BasketManager
Inherits: ReentrancyGuardTransient, AccessControlEnumerable, Pausable, Rescuable
Contract responsible for managing baskets and their tokens. The accounting for assets per basket is done in the BasketManagerUtils contract.
State Variables
_MANAGER_ROLE
LIBRARIES /// CONSTANTS ///
Manager role. Managers can create new baskets.
bytes32 private constant _MANAGER_ROLE = keccak256("MANAGER_ROLE");
_PAUSER_ROLE
Pauser role.
bytes32 private constant _PAUSER_ROLE = keccak256("PAUSER_ROLE");
_REBALANCE_PROPOSER_ROLE
Rebalance Proposer role. Rebalance proposers can propose a new rebalance.
bytes32 private constant _REBALANCE_PROPOSER_ROLE = keccak256("REBALANCE_PROPOSER_ROLE");
_TOKENSWAP_PROPOSER_ROLE
TokenSwap Proposer role. Token swap proposers can propose a new token swap.
bytes32 private constant _TOKENSWAP_PROPOSER_ROLE = keccak256("TOKENSWAP_PROPOSER_ROLE");
_TOKENSWAP_EXECUTOR_ROLE
TokenSwap Executor role. Token swap executors can execute a token swap.
bytes32 private constant _TOKENSWAP_EXECUTOR_ROLE = keccak256("TOKENSWAP_EXECUTOR_ROLE");
_BASKET_TOKEN_ROLE
Basket token role. Given to the basket token contracts when they are created.
bytes32 private constant _BASKET_TOKEN_ROLE = keccak256("BASKET_TOKEN_ROLE");
_TIMELOCK_ROLE
Role given to a timelock contract that can set critical parameters.
bytes32 private constant _TIMELOCK_ROLE = keccak256("TIMELOCK_ROLE");
_MAX_MANAGEMENT_FEE
Maximum management fee (30%) in BPS denominated in 1e4.
uint16 private constant _MAX_MANAGEMENT_FEE = 3000;
_MAX_SWAP_FEE
Maximum swap fee (5%) in BPS denominated in 1e4.
uint16 private constant _MAX_SWAP_FEE = 500;
_MIN_STEP_DELAY
Minimum time between steps in a rebalance in seconds.
uint40 private constant _MIN_STEP_DELAY = 1 minutes;
_MAX_STEP_DELAY
Maximum time between steps in a rebalance in seconds.
uint40 private constant _MAX_STEP_DELAY = 60 minutes;
_MAX_RETRY_COUNT
Maximum bound of retry count.
uint8 private constant _MAX_RETRY_COUNT = 10;
_bmStorage
STATE VARIABLES ///
Struct containing the BasketManagerUtils contract and other necessary data.
BasketManagerStorage private _bmStorage;
isOrderValid
Mapping of order hashes to their validity status.
mapping(bytes32 => bool) public isOrderValid;
Functions
constructor
Initializes the contract with the given parameters.
constructor(
address basketTokenImplementation,
address eulerRouter_,
address strategyRegistry_,
address assetRegistry_,
address admin,
address feeCollector_
)
payable;
Parameters
Name | Type | Description |
---|---|---|
basketTokenImplementation | address | Address of the basket token implementation. |
eulerRouter_ | address | Address of the oracle registry. |
strategyRegistry_ | address | Address of the strategy registry. |
assetRegistry_ | address | Address of the asset registry. |
admin | address | Address of the admin. |
feeCollector_ | address | Address of the fee collector. |
basketTokenToIndex
PUBLIC FUNCTIONS ///
Returns the index of the basket token in the basketTokens array.
Reverts if the basket token does not exist.
function basketTokenToIndex(address basketToken) public view returns (uint256);
Parameters
Name | Type | Description |
---|---|---|
basketToken | address | Address of the basket token. |
Returns
Name | Type | Description |
---|---|---|
<none> | uint256 | Index of the basket token. |
getAssetIndexInBasket
Returns the index of the given asset in the basket.
Reverts if the basket asset does not exist.
function getAssetIndexInBasket(address basketToken, address asset) public view returns (uint256);
Parameters
Name | Type | Description |
---|---|---|
basketToken | address | Address of the basket token. |
asset | address | Address of the asset. |
Returns
Name | Type | Description |
---|---|---|
<none> | uint256 | Index of the asset in the basket. |
numOfBasketTokens
Returns the number of basket tokens.
function numOfBasketTokens() public view returns (uint256);
Returns
Name | Type | Description |
---|---|---|
<none> | uint256 | Number of basket tokens. |
basketTokens
Returns all basket token addresses.
function basketTokens() external view returns (address[] memory);
Returns
Name | Type | Description |
---|---|---|
<none> | address[] | Array of basket token addresses. |
basketIdToAddress
Returns the basket token address with the given basketId.
The basketId is the keccak256 hash of the bitFlag and strategy address.
function basketIdToAddress(bytes32 basketId) external view returns (address);
Parameters
Name | Type | Description |
---|---|---|
basketId | bytes32 | Basket ID. |
basketBalanceOf
Returns the balance of the given asset in the given basket.
function basketBalanceOf(address basketToken, address asset) external view returns (uint256);
Parameters
Name | Type | Description |
---|---|---|
basketToken | address | Address of the basket token. |
asset | address | Address of the asset. |
Returns
Name | Type | Description |
---|---|---|
<none> | uint256 | Balance of the asset in the basket. |
rebalanceStatus
Returns the current rebalance status.
function rebalanceStatus() external view returns (RebalanceStatus memory);
Returns
Name | Type | Description |
---|---|---|
<none> | RebalanceStatus | Rebalance status struct with the following fields: - basketHash: Hash of the baskets proposed for rebalance. - timestamp: Timestamp of the last action. - status: Status enum of the rebalance. |
externalTradesHash
Returns the hash of the external trades stored during proposeTokenSwap
function externalTradesHash() external view returns (bytes32);
Returns
Name | Type | Description |
---|---|---|
<none> | bytes32 | Hash of the external trades |
eulerRouter
Returns the address of the basket token implementation.
function eulerRouter() external view returns (address);
Returns
Name | Type | Description |
---|---|---|
<none> | address | Address of the basket token implementation. |
feeCollector
Returns the address of the feeCollector contract.
function feeCollector() external view returns (address);
Returns
Name | Type | Description |
---|---|---|
<none> | address | Address of the feeCollector. |
managementFee
Returns the management fee of a basket in BPS denominated in 1e4.
function managementFee(address basket) external view returns (uint16);
Parameters
Name | Type | Description |
---|---|---|
basket | address | Address of the basket. |
Returns
Name | Type | Description |
---|---|---|
<none> | uint16 | Management fee. |
swapFee
Returns the swap fee in BPS denominated in 1e4.
function swapFee() external view returns (uint16);
Returns
Name | Type | Description |
---|---|---|
<none> | uint16 | Swap fee. |
strategyRegistry
Returns the address of the strategy registry.
function strategyRegistry() external view returns (address);
Returns
Name | Type | Description |
---|---|---|
<none> | address | Address of the strategy registry. |
tokenSwapAdapter
Returns the address of the token swap adapter.
function tokenSwapAdapter() external view returns (address);
Returns
Name | Type | Description |
---|---|---|
<none> | address | Address of the token swap adapter. |
retryCount
Returns the retry count for the current rebalance epoch.
function retryCount() external view returns (uint8);
Returns
Name | Type | Description |
---|---|---|
<none> | uint8 | Retry count. |
retryLimit
Returns the maximum retry limit for the rebalance process.
function retryLimit() external view returns (uint8);
Returns
Name | Type | Description |
---|---|---|
<none> | uint8 | Retry limit. |
stepDelay
Returns the step delay for the rebalance process.
The step delay defines the minimum time interval, in seconds, required between consecutive steps in a rebalance. This ensures sufficient time for external trades or other operations to settle before proceeding.
function stepDelay() external view returns (uint40);
Returns
Name | Type | Description |
---|---|---|
<none> | uint40 | Step delay duration in seconds. |
basketAssets
Returns the addresses of all assets in the given basket.
function basketAssets(address basket) external view returns (address[] memory);
Parameters
Name | Type | Description |
---|---|---|
basket | address | Address of the basket. |
Returns
Name | Type | Description |
---|---|---|
<none> | address[] | Array of asset addresses. |
createNewBasket
Creates a new basket token with the given parameters.
function createNewBasket(
string calldata basketName,
string calldata symbol,
address baseAsset,
uint256 bitFlag,
address strategy
)
external
payable
whenNotPaused
onlyRole(_MANAGER_ROLE)
returns (address basket);
Parameters
Name | Type | Description |
---|---|---|
basketName | string | Name of the basket. |
symbol | string | Symbol of the basket. |
baseAsset | address | |
bitFlag | uint256 | Asset selection bitFlag for the basket. |
strategy | address | Address of the strategy contract for the basket. |
proposeRebalance
Proposes a rebalance for the given baskets. The rebalance is proposed if the difference between the target balance and the current balance of any asset in the basket is more than 500 USD.
function proposeRebalance(address[] calldata basketsToRebalance)
external
onlyRole(_REBALANCE_PROPOSER_ROLE)
nonReentrant
whenNotPaused;
Parameters
Name | Type | Description |
---|---|---|
basketsToRebalance | address[] | Array of basket addresses to rebalance. |
proposeTokenSwap
Proposes a set of internal trades and external trades to rebalance the given baskets. If the proposed token swap results are not close to the target balances, this function will revert.
This function can only be called after proposeRebalance.
function proposeTokenSwap(
InternalTrade[] calldata internalTrades,
ExternalTrade[] calldata externalTrades,
address[] calldata basketsToRebalance,
uint64[][] calldata targetWeights,
address[][] calldata basketAssets_
)
external
onlyRole(_TOKENSWAP_PROPOSER_ROLE)
nonReentrant
whenNotPaused;
Parameters
Name | Type | Description |
---|---|---|
internalTrades | InternalTrade[] | Array of internal trades to execute. |
externalTrades | ExternalTrade[] | Array of external trades to execute. |
basketsToRebalance | address[] | Array of basket addresses currently being rebalanced. |
targetWeights | uint64[][] | Array of target weights for the baskets. |
basketAssets_ | address[][] |
executeTokenSwap
Executes the token swaps proposed in proposeTokenSwap and updates the basket balances.
This function can only be called after proposeTokenSwap.
function executeTokenSwap(
ExternalTrade[] calldata externalTrades,
bytes calldata data
)
external
onlyRole(_TOKENSWAP_EXECUTOR_ROLE)
nonReentrant
whenNotPaused;
Parameters
Name | Type | Description |
---|---|---|
externalTrades | ExternalTrade[] | Array of external trades to execute. |
data | bytes | Encoded data for the token swap. |
setTokenSwapAdapter
Sets the address of the TokenSwapAdapter contract used to execute token swaps.
Only callable by the timelock.
function setTokenSwapAdapter(address tokenSwapAdapter_) external onlyRole(_TIMELOCK_ROLE);
Parameters
Name | Type | Description |
---|---|---|
tokenSwapAdapter_ | address | Address of the TokenSwapAdapter contract. |
completeRebalance
Completes the rebalance for the given baskets. The rebalance can be completed if it has been more than 15 minutes since the last action.
function completeRebalance(
ExternalTrade[] calldata externalTrades,
address[] calldata basketsToRebalance,
uint64[][] calldata targetWeights,
address[][] calldata basketAssets_
)
external
nonReentrant
whenNotPaused;
Parameters
Name | Type | Description |
---|---|---|
externalTrades | ExternalTrade[] | |
basketsToRebalance | address[] | Array of basket addresses proposed for rebalance. |
targetWeights | uint64[][] | Array of target weights for the baskets. |
basketAssets_ | address[][] |
proRataRedeem
FALLBACK REDEEM LOGIC ///
Fallback redeem function to redeem shares when the rebalance is not in progress. Redeems the shares for each underlying asset in the basket pro-rata to the amount of shares redeemed.
function proRataRedeem(
uint256 totalSupplyBefore,
uint256 burnedShares,
address to
)
public
nonReentrant
whenNotPaused
onlyRole(_BASKET_TOKEN_ROLE);
Parameters
Name | Type | Description |
---|---|---|
totalSupplyBefore | uint256 | Total supply of the basket token before the shares were burned. |
burnedShares | uint256 | Amount of shares burned. |
to | address | Address to send the redeemed assets to. |
setManagementFee
FEE FUNCTIONS ///
Set the management fee to be given to the treausry on rebalance.
Only callable by the timelock.
Setting the management fee of the 0 address will set the default management fee for newly created baskets.
function setManagementFee(address basket, uint16 managementFee_) external onlyRole(_TIMELOCK_ROLE);
Parameters
Name | Type | Description |
---|---|---|
basket | address | Address of the basket token. |
managementFee_ | uint16 | Management fee in BPS denominated in 1e4. |
setSwapFee
Set the swap fee to be given to the treasury on rebalance.
Only callable by the timelock.
function setSwapFee(uint16 swapFee_) external onlyRole(_TIMELOCK_ROLE);
Parameters
Name | Type | Description |
---|---|---|
swapFee_ | uint16 | Swap fee in BPS denominated in 1e4. |
setStepDelay
Updates the step delay for the rebalance process.
The step delay defines the minimum time interval, in seconds, required between consecutive steps in a rebalance. This ensures sufficient time for external trades or other operations to settle before proceeding.
function setStepDelay(uint40 stepDelay_) external onlyRole(_TIMELOCK_ROLE);
Parameters
Name | Type | Description |
---|---|---|
stepDelay_ | uint40 | The new step delay duration in seconds. |
setRetryLimit
Sets the retry limit for future rebalances.
function setRetryLimit(uint8 retryLimit_) external onlyRole(_TIMELOCK_ROLE);
Parameters
Name | Type | Description |
---|---|---|
retryLimit_ | uint8 | New retry limit. |
collectSwapFee
Claims the swap fee for the given asset and sends it to protocol treasury defined in the FeeCollector.
function collectSwapFee(address asset) external onlyRole(_MANAGER_ROLE) returns (uint256 collectedFees);
Parameters
Name | Type | Description |
---|---|---|
asset | address | Address of the asset to collect the swap fee for. |
updateBitFlag
Updates the bitFlag for the given basket.
function updateBitFlag(address basket, uint256 bitFlag) external onlyRole(_TIMELOCK_ROLE);
Parameters
Name | Type | Description |
---|---|---|
basket | address | Address of the basket. |
bitFlag | uint256 | New bitFlag. It must be inclusive of the current bitFlag. |
pause
PAUSING FUNCTIONS ///
Pauses the contract. Callable by DEFAULT_ADMIN_ROLE or PAUSER_ROLE.
function pause() external;
unpause
Unpauses the contract. Only callable by DEFAULT_ADMIN_ROLE.
function unpause() external onlyRole(DEFAULT_ADMIN_ROLE);
execute
Allows the timelock to execute an arbitrary function call on a target contract.
Can only be called by addresses with the timelock role. Reverts if the execution fails.
function execute(
address target,
bytes calldata data,
uint256 value
)
external
payable
onlyRole(_TIMELOCK_ROLE)
returns (bytes memory);
Parameters
Name | Type | Description |
---|---|---|
target | address | The address of the target contract. |
data | bytes | The calldata to send to the target contract. |
value | uint256 | The amount of Ether (in wei) to send with the call. |
Returns
Name | Type | Description |
---|---|---|
<none> | bytes | result The data returned from the function call. |
rescue
Allows the admin to rescue tokens mistakenly sent to the contract.
Can only be called by the admin. This function is intended for use in case of accidental token transfers into the contract. It will revert if the token is part of the enabled asset universe.
function rescue(IERC20 token, address to, uint256 balance) external onlyRole(DEFAULT_ADMIN_ROLE);
Parameters
Name | Type | Description |
---|---|---|
token | IERC20 | The ERC20 token to rescue, or address(0) for ETH. |
to | address | The recipient address of the rescued tokens. |
balance | uint256 | The amount of tokens to rescue. If set to 0, the entire balance will be rescued. |
Events
SwapFeeSet
EVENTS ///
Emitted when the swap fee is set.
event SwapFeeSet(uint16 oldFee, uint16 newFee);
ManagementFeeSet
Emitted when the management fee is set.
event ManagementFeeSet(address indexed basket, uint16 oldFee, uint16 newFee);
TokenSwapAdapterSet
Emitted when the TokenSwapAdapter contract is set.
event TokenSwapAdapterSet(address oldAdapter, address newAdapter);
BasketCreated
Emitted when a new basket is created.
event BasketCreated(
address indexed basket, string basketName, string symbol, address baseAsset, uint256 bitFlag, address strategy
);
BasketBitFlagUpdated
Emitted when the bitFlag of a basket is updated.
event BasketBitFlagUpdated(
address indexed basket, uint256 oldBitFlag, uint256 newBitFlag, bytes32 oldId, bytes32 newId
);
TokenSwapProposed
Emitted when a token swap is proposed during a rebalance.
event TokenSwapProposed(uint40 indexed epoch, InternalTrade[] internalTrades, ExternalTrade[] externalTrades);
TokenSwapExecuted
Emitted when a token swap is executed during a rebalance.
event TokenSwapExecuted(uint40 indexed epoch);
StepDelaySet
Emitted when the step delay is set.
event StepDelaySet(uint40 oldDelay, uint40 newDelay);
RetryLimitSet
Emitted when the retry limit is set.
event RetryLimitSet(uint8 oldLimit, uint8 newLimit);
Errors
TokenSwapNotProposed
ERRORS ///
Thrown when attempting to execute a token swap without first proposing it.
error TokenSwapNotProposed();
ExecuteTokenSwapFailed
Thrown when the call to TokenSwapAdapter.executeTokenSwap
fails.
error ExecuteTokenSwapFailed();
InvalidHash
Thrown when the provided hash does not match the expected hash.
This error is used to validate the integrity of data passed between functions.
error InvalidHash();
ExternalTradesHashMismatch
Thrown when the provided external trades do not match the hash stored during the token swap proposal.
This error prevents executing a token swap with different parameters than originally proposed.
error ExternalTradesHashMismatch();
MustWaitForRebalanceToComplete
Thrown when attempting to perform an action that requires no active rebalance.
Certain actions, like setting the token swap adapter, are disallowed during an active rebalance.
error MustWaitForRebalanceToComplete();
Unauthorized
Thrown when a caller attempts to access a function without proper authorization.
This error is thrown when a caller lacks the required role to perform an action.
error Unauthorized();
InvalidManagementFee
Thrown when attempting to set an invalid management fee.
The management fee must not exceed _MAX_MANAGEMENT_FEE
.
error InvalidManagementFee();
InvalidSwapFee
Thrown when attempting to set an invalid swap fee.
The swap fee must not exceed _MAX_SWAP_FEE
.
error InvalidSwapFee();
BasketTokenNotFound
Thrown when attempting to perform an action on a non-existent basket token.
This error is thrown when the provided basket token is not in the basketTokenToIndexPlusOne
mapping.
error BasketTokenNotFound();
BitFlagMustBeDifferent
Thrown when attempting to update the bitFlag to the same value.
error BitFlagMustBeDifferent();
BitFlagMustIncludeCurrent
Thrown when attempting to update the bitFlag without including the current bitFlag.
error BitFlagMustIncludeCurrent();
BitFlagUnsupportedByStrategy
Thrown when attempting to update the bitFlag to a value not supported by the strategy.
error BitFlagUnsupportedByStrategy();
BasketIdAlreadyExists
Thrown when attempting to create a basket with an ID that already exists.
error BasketIdAlreadyExists();
AssetExistsInUniverse
Thrown when attempting to rescue an asset to a basket that already exists in the asset universe.
error AssetExistsInUniverse();
ExecutionFailed
Thrown when the low-level call in the execute
function fails.
This error indicates that the target contract rejected the call or execution failed unexpectedly.
error ExecutionFailed();
InvalidStepDelay
Thrown when attempting to set an invalid step delay outside the bounds of _MIN_STEP_DELAY
and
_MAX_STEP_DELAY
.
error InvalidStepDelay();
InvalidRetryCount
Thrown when attempting to set an invalid retry limit outside the bounds of 0 and _MAX_RETRY_COUNT
.
error InvalidRetryCount();