# 📚 Allocator Interaction Instructions --- This doc will serve as an instruction manual for working with the [`TreasuryExtender`](https://github.com/OlympusDAO/olympus-contracts/blob/main/contracts/TreasuryExtender.sol) and related allocators. --- ### Contents | 📚📚📚📚📚📚📚📚📚📚📚📚📚📚📚📚📚📚📚📚📚📚📚📚📚📚📚📚📚📚📚📚📚 | |:----------------------------------------------------------------------------------------------------------------------------------:| | 1. Contract deployments and info | | 2. General instructions | | 3. Function reference for [`BaseAllocator`](https://github.com/OlympusDAO/olympus-contracts/blob/main/contracts/types/BaseAllocator.sol#L376) | | 4. Function reference for [`TreasuryExtender`](https://github.com/OlympusDAO/olympus-contracts/blob/main/contracts/TreasuryExtender.sol) | --- ## Contract Deployments and Info | Contract | Etherscan link | Source code | | --- | --- | --- | | TreasuryExtender.sol | [link](https://etherscan.io/address/0xb32ad041f23eafd682f57fce31d3ea4fd92d17af) | [link](https://github.com/OlympusDAO/olympus-contracts/blob/main/contracts/TreasuryExtender.sol) | | AaveAllocatorV2.sol | [link](https://etherscan.io/address/0x0D33c811D0fcC711BcB388DFB3a152DE445bE66F) | [link](https://github.com/OlympusDAO/olympus-contracts/blob/allocators/contracts/allocators/AaveAllocatorV2.sol) | | AlchemixAllocatorV2.sol | [link](https://etherscan.io/address/0x51563d61f8a5869b24eddfb2705308bae539bf56) | [link](https://github.com/OlympusDAO/olympus-contracts/blob/allocators/contracts/allocators/AlchemixAllocatorV2.sol) | | FxsAllocatorV2.sol | [link](https://etherscan.io/address/0x0f953D861347414698F34B75dbFd6e7dF1A73493) | [link](https://github.com/OlympusDAO/olympus-contracts/blob/allocators/contracts/allocators/FxsAllocatorV2.sol) | BtrflyAllocator.sol | [link](https://etherscan.io/address/0xC8431fEb345B46c30A4576c1b5faF080fdc54e2f) | [link](https://github.com/OlympusDAO/olympus-contracts/blob/allocators/contracts/allocators/BtrflyAllocator.sol) | LUSDAllocatorV2.sol | [link](https://etherscan.io/address/0x2C1700F38C38C32595CFeF3D6B0B275bC2D2a578) | [link](https://github.com/OlympusDAO/olympus-contracts/blob/allocators/contracts/allocators/LUSDAllocatorV2.sol) | | BaseAllocator.sol | N/A - is Base Class | [link](https://github.com/OlympusDAO/olympus-contracts/blob/main/contracts/types/BaseAllocator.sol) | ## General Instructions The account interacting with the `TreasuryExtender` will here be called `GUARDIAN` because only it has access to modify `TreasuryExtender` state. This is the address obtained from `OlympusAuthority` `guardian`. In the next topics the general guidelines for interacting with the common interface will be specified. Function call order is specific if protocol specific implementations require it. It is recommended for `GUARDIAN` to communicate protol specific mechanisms to contributors. Contributors should in return then specify function call order and functionality in general. Function descriptions in this doc will be exactly enough to allow `GUARDIAN` to interact fully with the contracts, complete descriptions can be found in the NatSpec of each of the contracts above. ### Activation process Before activating an allocator first set up all necessary parameters inside the contract, this is contract specific and requires knowledge about the allocator / protocol. After this is done, - call `TreasuryExtender::registerDeposit(address)` -> this is to register the token deposit and the allocator inside the `TreasuryExtender` contract. This is necessary for the next step. `NOTE:` this is for one token only. This entire procedure will be repeated for each token individually _except_ for the last step. - call `TreasuryExtender::setAllocatorLimits(uint256 id, AllocatorLimits limits)` to set the upper amount which may be allocated and the amount which may be lost by the allocator during normal operation. Note, that there are essentially two types of allocators in regards to `loss`: * allocators without a `loss` threshold: Every single loss will be reported and registered. This includes tiny losses. Good for 1:1 allocators (as most allocators are). * allocators with a `loss` threshold: Only loss above a threshold will be reported in full, otherwise if it is below, an `AllocatorRegisteredLoss` event will be fired, but only 1 will be deducted. This is for allocations with impermanent loss. * This is also repeated as the above for each token. - call `Allocator::activate()` to finally activate the allocator. This is to only be called once and not repeatedly as the above functions for multiple token deposits. This engulfs the entire Allocator runtime and thus is singular. You may now transfer tokens to the allocator. ### Token transfers and depositing In order to transfer tokens from the treasury _to_ to allocators, first the `TreasuryExtender` contract needs to proper permissions. In the tests the permissions with ids **0** and **3** were necessary. - In order to transfer a token _to_ the Allocator, take the deposit id and call `TreasuryExtender::requestFundsFromTreasury(uint256 id, uint256 amount)`, this will transfer the tokens into the allocator. - Now call `Allocator::update(uint256 id)` with the same deposit id, which should deposit the tokens into the protocol. This will also handle harvest operations. ### Token withdrawal #### Underlying tokens: - call `Allocator::deallocate(uint256[])` with the amounts wanted on the allocator and _if necessary_ wait for the tokens to be withdrawn. * the uint256[] holds the amounts of underlying tokens to withdraw based on the index of the tokens inside the contracts. Please be aware what the ordering of the tokens within the contracts is. You may call `tokens()` on the allocator to find this out. - call `TreasuryExtender::returnFundsToTreasury(uint256 id, uint256 amount)` to return exactly `amount` of token registered under `id` to the treasury. #### Utility / reward tokens - call `Allocator::returnRewardsToTreasury(uint256 id / address allocatorAddress, address token, uint256 amount)` to return `amount` of `token` to the treasury. Explicit deallocations are not necessary because it is expected for all reward tokens to stay idle in the contract. ### Deactivation WIP ## Function reference for [`BaseAllocator`](https://github.com/OlympusDAO/olympus-contracts/blob/main/contracts/types/BaseAllocator.sol#L376) Please familiarize yourself with the functions. This interface is implemented by every allocator. ### Functions | function | signature (bytes4) | source code | description | | --- | --- | --- | --- | | update(uint256) | 82ab890a | [link](https://github.com/OlympusDAO/olympus-contracts/blob/c9561e7faff39a6ddd77cd7e06a4af5d4ed2a0e2/contracts/types/BaseAllocator.sol#L235) | `GUARDIAN` should call this as a regular routine to handle re/investing, `gain`/`loss` reporting on the Allocator. It is the job of the developer to make a system which given any state will report the proper `gain`/`loss`, the developer should also report to `GUARDIAN` if there are special circumstances under which the function should or should not be called. | | deallocate(uint256[]) | 013e1b98 | [link](https://github.com/OlympusDAO/olympus-contracts/blob/c9561e7faff39a6ddd77cd7e06a4af5d4ed2a0e2/contracts/types/BaseAllocator.sol#L156) | If `GUARDIAN` wants to withdraw underlying tokens from the Allocator, tokens must first be withdrawn **_to_** the Allocator, this function must be called with the amounts to withdraw in order to initiate the process. Special care is to be taken by developers to specify whether the input amount is in LP or underlying tokens, and if there is any delay between withdrawal and token availability. | | prepareMigration() | 19300234 | [link](https://github.com/OlympusDAO/olympus-contracts/blob/c9561e7faff39a6ddd77cd7e06a4af5d4ed2a0e2/contracts/types/BaseAllocator.sol#L263) | Before initiating a migration, this function must be called by `GUARDIAN` to initiate any necessary withdrawals and state changes to the allocator. | | migrate() | 8fd3ab80 | [link](https://github.com/OlympusDAO/olympus-contracts/blob/c9561e7faff39a6ddd77cd7e06a4af5d4ed2a0e2/contracts/types/BaseAllocator.sol#L292) | `GUARDIAN` should call this function once `prepareMigration()` has executed and all withdrawals have been processed, as indicated by the developer. **This function will transfer all funds except `rewards` to the last allocator registered, meaning that care is to be taken to follow the proper migration procedure which will described below.** | | activate() | 0f15f4c0 | [link](https://github.com/OlympusDAO/olympus-contracts/blob/c9561e7faff39a6ddd77cd7e06a4af5d4ed2a0e2/contracts/types/BaseAllocator.sol#L327) | Part of the initialization procedure, `GUARDIAN` must call this function to enable token transfers to the allocator. The call order will be described below similarly to `migrate` as both are part of procedures. | | deactivate(bool) | e6eb0045 | [link](https://github.com/OlympusDAO/olympus-contracts/blob/c9561e7faff39a6ddd77cd7e06a4af5d4ed2a0e2/contracts/types/BaseAllocator.sol#L376) | Part of the deactivation procedure, `GUARDIAN` may call this function to manually deactivate the Allocator in case of suspicious activity, if it's being paused etc. This function is also called internally. The call order for this functino will be described below. | | amountAllocated(uint256) | cc008f31 | [link](https://github.com/OlympusDAO/olympus-contracts/blob/c9561e7faff39a6ddd77cd7e06a4af5d4ed2a0e2/contracts/types/BaseAllocator.sol#L183) | Getter. Call this to get the amount of allocated (underlying) tokens owned (deposited into protocols) by the allocator. | | ids() | e7657e15 | [link](https://github.com/OlympusDAO/olympus-contracts/blob/c9561e7faff39a6ddd77cd7e06a4af5d4ed2a0e2/contracts/types/BaseAllocator.sol#L352) | Getter. Gets all deposit ids which are registered with this allocator. These are the exact ids memorized in the TreasuryExtender. | | tokens() | 680989b8 | [link](https://github.com/OlympusDAO/olympus-contracts/blob/c9561e7faff39a6ddd77cd7e06a4af5d4ed2a0e2/contracts/types/BaseAllocator.sol#L361) | Getter. Gets array of allocated (underlying tokens.) | | utilityTokens() | ab9201cc | [link](https://github.com/OlympusDAO/olympus-contracts/blob/c9561e7faff39a6ddd77cd7e06a4af5d4ed2a0e2/contracts/types/BaseAllocator.sol#L195) | Getter. Gets array of utility tokens. | | rewardTokens() | c2b18aa0 | [link](https://github.com/OlympusDAO/olympus-contracts/blob/c9561e7faff39a6ddd77cd7e06a4af5d4ed2a0e2/contracts/types/BaseAllocator.sol#L189) | Getter. Gets array of reward tokens. | All other functions not mentioned are either not for `GUARDIAN` or self-explanatory. ## Function reference for [`TreasuryExtender`](https://github.com/OlympusDAO/olympus-contracts/blob/main/contracts/TreasuryExtender.sol) Please familiarize yourself with the functions. ### Functions | function | signature (bytes4) | source code | description | | --- | --- | --- | --- | | registerDeposit(address) | e8a19fdc | [link](https://github.com/OlympusDAO/olympus-contracts/blob/c9561e7faff39a6ddd77cd7e06a4af5d4ed2a0e2/contracts/TreasuryExtender.sol#L97) | This function is used to register a new deposit with an allocator contract. This means, to register an underlying token being deposited in an allocator, since the same token can be deposited in multiple ones. This assigns a unique, immutable id of the deposit in the `TreasuryExtender` and also a set of ids for internal usage in the respective allocator. Only `GUARDIAN` may call this. | | setAllocatorLimits(uint256 id, AllocatorLimits limits) | N/A need to calculate | [link](https://github.com/OlympusDAO/olympus-contracts/blob/c9561e7faff39a6ddd77cd7e06a4af5d4ed2a0e2/contracts/TreasuryExtender.sol#L124) | This function sets an upper bound on the maximum amount which can be allocated to this allocator (in relation to the deposit) and also the maximum loss amount for the deposit. `limits` is a struct which contains `allocated` and `loss` which represent these limits. This is in actuality a `(uint128,uint128)` tuple used for efficient packing. |