BasketManager

Git Source

Inherits: ReentrancyGuardTransient, AccessControlEnumerable, Pausable

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;

_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

NameTypeDescription
basketTokenImplementationaddressAddress of the basket token implementation.
eulerRouter_addressAddress of the oracle registry.
strategyRegistry_addressAddress of the strategy registry.
assetRegistry_addressAddress of the asset registry.
adminaddressAddress of the admin.
feeCollector_addressAddress 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 index);

Parameters

NameTypeDescription
basketTokenaddressAddress of the basket token.

Returns

NameTypeDescription
indexuint256Index of the basket token.

basketTokenToRebalanceAssetToIndex

Returns the index of the basket asset in the basketAssets array.

Reverts if the basket asset does not exist.

function basketTokenToRebalanceAssetToIndex(address basketToken, address asset) public view returns (uint256 index);

Parameters

NameTypeDescription
basketTokenaddressAddress of the basket token.
assetaddressAddress of the asset.

Returns

NameTypeDescription
indexuint256Index of the basket asset.

numOfBasketTokens

Returns the number of basket tokens.

function numOfBasketTokens() public view returns (uint256);

Returns

NameTypeDescription
<none>uint256Number of basket tokens.

basketTokens

Returns all basket token addresses.

function basketTokens() external view returns (address[] memory);

Returns

NameTypeDescription
<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

NameTypeDescription
basketIdbytes32Basket ID.

basketBalanceOf

Returns the balance of the given asset in the given basket.

function basketBalanceOf(address basketToken, address asset) external view returns (uint256);

Parameters

NameTypeDescription
basketTokenaddressAddress of the basket token.
assetaddressAddress of the asset.

Returns

NameTypeDescription
<none>uint256Balance of the asset in the basket.

rebalanceStatus

Returns the current rebalance status.

function rebalanceStatus() external view returns (RebalanceStatus memory);

Returns

NameTypeDescription
<none>RebalanceStatusRebalance 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

NameTypeDescription
<none>bytes32Hash of the external trades

eulerRouter

Returns the address of the basket token implementation.

function eulerRouter() external view returns (address);

Returns

NameTypeDescription
<none>addressAddress of the basket token implementation.

feeCollector

Returns the address of the feeCollector contract.

function feeCollector() external view returns (address);

Returns

NameTypeDescription
<none>addressAddress 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

NameTypeDescription
basketaddressAddress of the basket.

Returns

NameTypeDescription
<none>uint16Management fee.

swapFee

Returns the swap fee in BPS denominated in 1e4.

function swapFee() external view returns (uint16);

Returns

NameTypeDescription
<none>uint16Swap fee.

strategyRegistry

Returns the address of the strategy registry.

function strategyRegistry() external view returns (address);

Returns

NameTypeDescription
<none>addressAddress of the strategy registry.

tokenSwapAdapter

Returns the address of the token swap adapter.

function tokenSwapAdapter() external view returns (address);

Returns

NameTypeDescription
<none>addressAddress of the token swap adapter.

retryCount

Returns the retry count for the current rebalance epoch.

function retryCount() external view returns (uint8);

Returns

NameTypeDescription
<none>uint8Retry count.

basketAssets

Returns the addresses of all assets in the given basket.

function basketAssets(address basket) external view returns (address[] memory);

Parameters

NameTypeDescription
basketaddressAddress of the basket.

Returns

NameTypeDescription
<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

NameTypeDescription
basketNamestringName of the basket.
symbolstringSymbol of the basket.
baseAssetaddress
bitFlaguint256Asset selection bitFlag for the basket.
strategyaddressAddress 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

NameTypeDescription
basketsToRebalanceaddress[]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
)
    external
    onlyRole(_TOKENSWAP_PROPOSER_ROLE)
    nonReentrant
    whenNotPaused;

Parameters

NameTypeDescription
internalTradesInternalTrade[]Array of internal trades to execute.
externalTradesExternalTrade[]Array of external trades to execute.
basketsToRebalanceaddress[]Array of basket addresses currently being rebalanced.
targetWeightsuint64[][]Array of target weights for the baskets.

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

NameTypeDescription
externalTradesExternalTrade[]Array of external trades to execute.
databytesEncoded 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

NameTypeDescription
tokenSwapAdapter_addressAddress 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
)
    external
    nonReentrant
    whenNotPaused;

Parameters

NameTypeDescription
externalTradesExternalTrade[]
basketsToRebalanceaddress[]Array of basket addresses proposed for rebalance.
targetWeightsuint64[][]Array of target weights for the baskets.

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

NameTypeDescription
totalSupplyBeforeuint256Total supply of the basket token before the shares were burned.
burnedSharesuint256Amount of shares burned.
toaddressAddress 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

NameTypeDescription
basketaddressAddress of the basket token.
managementFee_uint16Management 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

NameTypeDescription
swapFee_uint16Swap fee in BPS denominated in 1e4.

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

NameTypeDescription
assetaddressAddress 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

NameTypeDescription
basketaddressAddress of the basket.
bitFlaguint256New 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);

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);

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

error BitFlagMustBeDifferent();

BitFlagMustIncludeCurrent

error BitFlagMustIncludeCurrent();

BitFlagUnsupportedByStrategy

error BitFlagUnsupportedByStrategy();

BasketIdAlreadyExists

error BasketIdAlreadyExists();