BasketManagerUtils

Git Source

Library containing utility functions for managing storage related to baskets, including creating new baskets, proposing and executing rebalances, and settling internal and external token trades.

State Variables

_USD_ISO_4217_CODE

CONSTANTS ///

ISO 4217 numeric code for USD, used as a constant address representation

address private constant _USD_ISO_4217_CODE = address(840);

_MAX_NUM_OF_BASKET_TOKENS

Maximum number of basket tokens allowed to be created.

uint256 private constant _MAX_NUM_OF_BASKET_TOKENS = 256;

_MAX_SLIPPAGE

Maximum slippage multiplier for token swaps, expressed in 1e18.

uint256 private constant _MAX_SLIPPAGE = 0.05e18;

_MAX_WEIGHT_DEVIATION

Maximum deviation multiplier to determine if a set of balances has reached the desired target weights.

uint256 private constant _MAX_WEIGHT_DEVIATION = 0.05e18;

_WEIGHT_PRECISION

Precision used for weight calculations and slippage calculations.

uint256 private constant _WEIGHT_PRECISION = 1e18;

_MAX_RETRIES

Maximum number of retries for a rebalance.

uint8 private constant _MAX_RETRIES = 3;

_REBALANCE_COOLDOWN_SEC

Minimum time between rebalances in seconds.

uint40 private constant _REBALANCE_COOLDOWN_SEC = 1 hours;

Functions

createNewBasket

Creates a new basket token with the given parameters.

function createNewBasket(
    BasketManagerStorage storage self,
    string calldata basketName,
    string calldata symbol,
    address baseAsset,
    uint256 bitFlag,
    address strategy
)
    external
    returns (address basket);

Parameters

NameTypeDescription
selfBasketManagerStorageBasketManagerStorage struct containing strategy data.
basketNamestringName of the basket.
symbolstringSymbol of the basket.
baseAssetaddress
bitFlaguint256Asset selection bitFlag for the basket.
strategyaddressAddress of the strategy contract for the basket.

Returns

NameTypeDescription
basketaddressAddress of the newly created basket token.

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(BasketManagerStorage storage self, address[] calldata baskets) external;

Parameters

NameTypeDescription
selfBasketManagerStorage
basketsaddress[]Array of basket addresses to rebalance.

proposeTokenSwap

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(
    BasketManagerStorage storage self,
    InternalTrade[] calldata internalTrades,
    ExternalTrade[] calldata externalTrades,
    address[] calldata baskets,
    uint64[][] calldata basketTargetWeights
)
    external;

Parameters

NameTypeDescription
selfBasketManagerStorageBasketManagerStorage struct containing strategy data.
internalTradesInternalTrade[]Array of internal trades to execute.
externalTradesExternalTrade[]Array of external trades to execute.
basketsaddress[]Array of basket addresses currently being rebalanced.
basketTargetWeightsuint64[][]Array of target weights for each basket.

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(
    BasketManagerStorage storage self,
    ExternalTrade[] calldata externalTrades,
    address[] calldata baskets,
    uint64[][] calldata basketTargetWeights
)
    external;

Parameters

NameTypeDescription
selfBasketManagerStorageBasketManagerStorage struct containing strategy data.
externalTradesExternalTrade[]Array of external trades matching those proposed for rebalance.
basketsaddress[]Array of basket addresses proposed for rebalance.
basketTargetWeightsuint64[][]Array of target weights for each basket.

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(
    BasketManagerStorage storage self,
    uint256 totalSupplyBefore,
    uint256 burnedShares,
    address to
)
    external;

Parameters

NameTypeDescription
selfBasketManagerStorage
totalSupplyBeforeuint256Total supply of the basket token before the shares were burned.
burnedSharesuint256Amount of shares burned.
toaddressAddress to send the redeemed assets to.

basketTokenToRebalanceAssetToIndex

Returns the index of the asset in a given basket

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

Parameters

NameTypeDescription
selfBasketManagerStorageBasketManagerStorage struct containing strategy data.
basketTokenaddressBasket token address.
assetaddressAsset address.

Returns

NameTypeDescription
indexuint256Index of the asset in the basket.

basketTokenToIndex

Returns the index of the basket token.

function basketTokenToIndex(
    BasketManagerStorage storage self,
    address basketToken
)
    public
    view
    returns (uint256 index);

Parameters

NameTypeDescription
selfBasketManagerStorageBasketManagerStorage struct containing strategy data.
basketTokenaddressBasket token address.

Returns

NameTypeDescription
indexuint256Index of the basket token.

_indexOf

INTERNAL FUNCTIONS ///

Returns the index of the element in the array.

Reverts if the element does not exist in the array.

function _indexOf(address[] memory array, address element) internal pure returns (uint256 index);

Parameters

NameTypeDescription
arrayaddress[]Array to find the element in.
elementaddressElement to find in the array.

Returns

NameTypeDescription
indexuint256Index of the element in the array.

_finalizeRebalance

PRIVATE FUNCTIONS ///

Internal function to finalize the state changes for the current rebalance. Resets rebalance status and attempts to process pending redeems. If all pending redeems cannot be fulfilled notifies basket token of a failed rebalance.

function _finalizeRebalance(BasketManagerStorage storage self, address[] calldata baskets) private;

Parameters

NameTypeDescription
selfBasketManagerStorageBasketManagerStorage struct containing strategy data.
basketsaddress[]Array of basket addresses currently being rebalanced.

_completeTokenSwap

Internal function to complete proposed token swaps.

function _completeTokenSwap(
    BasketManagerStorage storage self,
    ExternalTrade[] calldata externalTrades
)
    private
    returns (uint256[2][] memory claimedAmounts);

Parameters

NameTypeDescription
selfBasketManagerStorageBasketManagerStorage struct containing strategy data.
externalTradesExternalTrade[]Array of external trades to be completed.

Returns

NameTypeDescription
claimedAmountsuint256[2][]amounts claimed from the completed token swaps

_processExternalTrades

Internal function to update internal accounting with result of completed token swaps.

function _processExternalTrades(BasketManagerStorage storage self, ExternalTrade[] calldata externalTrades) private;

Parameters

NameTypeDescription
selfBasketManagerStorageBasketManagerStorage struct containing strategy data.
externalTradesExternalTrade[]Array of external trades to be completed.

_initializeBasketData

Internal function to initialize basket data.

function _initializeBasketData(
    BasketManagerStorage storage self,
    address[] calldata baskets,
    uint256[][] memory basketBalances,
    uint256[] memory totalValue_
)
    private
    view;

Parameters

NameTypeDescription
selfBasketManagerStorageBasketManagerStorage struct containing strategy data.
basketsaddress[]Array of basket addresses currently being rebalanced.
basketBalancesuint256[][]An empty array used for asset balances for each basket being rebalanced. Updated with current balances at the end of the function.
totalValue_uint256[]An initialized array of total basket values for each basket being rebalanced.

_processInternalTrades

Internal function to settle internal trades.

If the result of an internal trade is not within the provided minAmount or maxAmount, this function will revert.

function _processInternalTrades(
    BasketManagerStorage storage self,
    InternalTrade[] calldata internalTrades,
    address[] calldata baskets,
    uint256[][] memory basketBalances
)
    private;

Parameters

NameTypeDescription
selfBasketManagerStorageBasketManagerStorage struct containing strategy data.
internalTradesInternalTrade[]Array of internal trades to execute.
basketsaddress[]Array of basket addresses currently being rebalanced.
basketBalancesuint256[][]An initialized array of asset amounts for each basket being rebalanced. Updated with settled internal trades at the end of the function.

_validateExternalTrades

Internal function to validate the results of external trades.

If the result of an external trade is not within the _MAX_SLIPPAGE threshold of the minAmount, this function will revert.

function _validateExternalTrades(
    BasketManagerStorage storage self,
    ExternalTrade[] calldata externalTrades,
    address[] calldata baskets,
    uint256[] memory totalValue_,
    uint256[][] memory afterTradeAmounts_
)
    private
    view;

Parameters

NameTypeDescription
selfBasketManagerStorageBasketManagerStorage struct containing strategy data.
externalTradesExternalTrade[]Array of external trades to be validated.
basketsaddress[]Array of basket addresses currently being rebalanced.
totalValue_uint256[]Array of total basket values in USD.
afterTradeAmounts_uint256[][]An initialized array of asset amounts for each basket being rebalanced.

_validateBasketHash

Validate the basket hash based on the given baskets and target weights.

function _validateBasketHash(
    BasketManagerStorage storage self,
    address[] calldata baskets,
    uint64[][] calldata basketsTargetWeights
)
    private
    view;

_isTargetWeightMet

Checks if weight deviations after trades are within the acceptable _MAX_WEIGHT_DEVIATION threshold. Returns true if all deviations are within bounds for each asset in every basket.

function _isTargetWeightMet(
    BasketManagerStorage storage self,
    address[] calldata baskets,
    uint256[][] memory basketBalances,
    uint256[] memory totalValues,
    uint64[][] calldata basketsTargetWeights
)
    private
    view
    returns (bool);

Parameters

NameTypeDescription
selfBasketManagerStorageBasketManagerStorage struct containing strategy data.
basketsaddress[]Array of basket addresses currently being rebalanced.
basketBalancesuint256[][]2D array of asset balances for each basket. Rows are baskets, columns are assets.
totalValuesuint256[]Array of total basket values in USD.
basketsTargetWeightsuint64[][]Array of target weights for each basket.

_processPendingDeposits

Internal function to process pending deposits and fulfill them.

function _processPendingDeposits(
    BasketManagerStorage storage self,
    address basket,
    uint256 basketValue,
    uint256 baseAssetBalance,
    uint256 pendingDeposit,
    uint256 baseAssetIndex
)
    private
    returns (uint256 totalSupply, uint256 pendingDepositValue);

Parameters

NameTypeDescription
selfBasketManagerStorageBasketManagerStorage struct containing strategy data.
basketaddressBasket token address.
basketValueuint256Current value of the basket in USD.
baseAssetBalanceuint256Current balance of the base asset in the basket.
pendingDeposituint256Current assets pending deposit in the given basket.
baseAssetIndexuint256

Returns

NameTypeDescription
totalSupplyuint256Total supply of the basket token after processing pending deposits.
pendingDepositValueuint256Value of the pending deposits in USD.

_calculateTargetBalances

Internal function to calculate the target balances for each asset in a given basket.

function _calculateTargetBalances(
    BasketManagerStorage storage self,
    address basket,
    uint256 basketValue,
    uint256 requiredWithdrawValue,
    address[] memory assets,
    uint64[] memory proposedTargetWeights
)
    private
    view
    returns (uint256[] memory targetBalances);

Parameters

NameTypeDescription
selfBasketManagerStorageBasketManagerStorage struct containing strategy data.
basketaddressBasket token address.
basketValueuint256Current value of the basket in USD.
requiredWithdrawValueuint256Value of the assets to be withdrawn from the basket.
assetsaddress[]Array of asset addresses in the basket.
proposedTargetWeightsuint64[]

Returns

NameTypeDescription
targetBalancesuint256[]Array of target balances for each asset in the basket.

_calculateBasketValue

Internal function to calculate the current value of all assets in a given basket.

function _calculateBasketValue(
    BasketManagerStorage storage self,
    address basket,
    address[] memory assets
)
    private
    view
    returns (uint256[] memory balances, uint256 basketValue);

Parameters

NameTypeDescription
selfBasketManagerStorageBasketManagerStorage struct containing strategy data.
basketaddressBasket token address.
assetsaddress[]Array of asset addresses in the basket.

Returns

NameTypeDescription
balancesuint256[]Array of balances of each asset in the basket.
basketValueuint256Current value of the basket in USD.

_isRebalanceRequired

Internal function to check if a rebalance is required for the given basket.

A rebalance is required if the difference between the current asset balances and the target balances is greater than 0. We assume the permissioned caller has already validated the condition to call this function optimally.

function _isRebalanceRequired(
    address[] memory assets,
    uint256[] memory balances,
    uint256[] memory targetBalances
)
    private
    view
    returns (bool shouldRebalance);

Parameters

NameTypeDescription
assetsaddress[]Array of asset addresses in the basket.
balancesuint256[]Array of balances of each asset in the basket.
targetBalancesuint256[]Array of target balances for each asset in the basket.

Returns

NameTypeDescription
shouldRebalanceboolBoolean indicating if a rebalance is required.

_setBaseAssetIndex

Internal function to store the index of the base asset for a given basket. Reverts if the base asset is not present in the basket's assets.

If the base asset is not present in the basket, this function will revert.

function _setBaseAssetIndex(
    BasketManagerStorage storage self,
    address basket,
    address[] memory assets,
    address baseAsset
)
    private;

Parameters

NameTypeDescription
selfBasketManagerStorageBasketManagerStorage struct containing strategy data.
basketaddressBasket token address.
assetsaddress[]Array of asset addresses in the basket.
baseAssetaddressBase asset address.

_createRebalanceBitMask

Internal function to create a bitmask for baskets being rebalanced.

A bitmask like 00000011 indicates that the first two baskets are being rebalanced.

function _createRebalanceBitMask(
    BasketManagerStorage storage self,
    address[] memory baskets
)
    private
    view
    returns (uint256 basketMask);

Parameters

NameTypeDescription
selfBasketManagerStorageBasketManagerStorage struct containing strategy data.
basketsaddress[]Array of basket addresses currently being rebalanced.

Returns

NameTypeDescription
basketMaskuint256Bitmask for baskets being rebalanced.

Events

InternalTradeSettled

EVENTS ///

Emitted when an internal trade is settled.

event InternalTradeSettled(InternalTrade internalTrade, uint256 buyAmount);

Parameters

NameTypeDescription
internalTradeInternalTradeInternal trade that was settled.
buyAmountuint256Amount of the the from token that is traded.

SwapFeeCharged

Emitted when swap fees are charged on an internal trade.

event SwapFeeCharged(address indexed asset, uint256 amount);

Parameters

NameTypeDescription
assetaddressAsset that the swap fee was charged in.
amountuint256Amount of the asset that was charged.

RebalanceProposed

Emitted when a rebalance is proposed for a set of baskets

event RebalanceProposed(uint40 indexed epoch, address[] baskets, uint64[][] proposedTargetWeights, bytes32 basketHash);

Parameters

NameTypeDescription
epochuint40Unique identifier for the rebalance, incremented each time a rebalance is proposed
basketsaddress[]Array of basket addresses to rebalance
proposedTargetWeightsuint64[][]Array of target weights for each basket
basketHashbytes32Hash of the basket addresses and target weights for the rebalance

RebalanceCompleted

Emitted when a rebalance is completed.

event RebalanceCompleted(uint40 indexed epoch);

Errors

ZeroTotalSupply

ERRORS ///

Reverts when the total supply of a basket token is zero.

error ZeroTotalSupply();

ZeroBurnedShares

Reverts when the amount of burned shares is zero.

error ZeroBurnedShares();

CannotBurnMoreSharesThanTotalSupply

Reverts when trying to burn more shares than the total supply.

error CannotBurnMoreSharesThanTotalSupply();

BasketTokenNotFound

Reverts when the requested basket token is not found.

error BasketTokenNotFound();

AssetNotFoundInBasket

Reverts when the requested asset is not found in the basket.

error AssetNotFoundInBasket();

BasketTokenAlreadyExists

Reverts when trying to create a basket token that already exists.

error BasketTokenAlreadyExists();

BasketTokenMaxExceeded

Reverts when the maximum number of basket tokens has been reached.

error BasketTokenMaxExceeded();

ElementIndexNotFound

Reverts when the requested element index is not found.

error ElementIndexNotFound();

StrategyRegistryDoesNotSupportStrategy

Reverts when the strategy registry does not support the given strategy.

error StrategyRegistryDoesNotSupportStrategy();

BasketsMismatch

Reverts when the baskets or target weights do not match the proposed rebalance.

error BasketsMismatch();

BaseAssetMismatch

Reverts when the base asset does not match the given asset.

error BaseAssetMismatch();

AssetListEmpty

Reverts when the asset is not found in the asset registry.

error AssetListEmpty();

MustWaitForRebalanceToComplete

Reverts when a rebalance is in progress and the caller must wait for it to complete.

error MustWaitForRebalanceToComplete();

NoRebalanceInProgress

Reverts when there is no rebalance in progress.

error NoRebalanceInProgress();

TooEarlyToCompleteRebalance

Reverts when it is too early to complete the rebalance.

error TooEarlyToCompleteRebalance();

TooEarlyToProposeRebalance

Reverts when it is too early to propose a rebalance.

error TooEarlyToProposeRebalance();

RebalanceNotRequired

Reverts when a rebalance is not required.

error RebalanceNotRequired();

ExternalTradeSlippage

Reverts when the external trade slippage exceeds the allowed limit.

error ExternalTradeSlippage();

TargetWeightsNotMet

Reverts when the target weights are not met.

error TargetWeightsNotMet();

InternalTradeMinMaxAmountNotReached

Reverts when the minimum or maximum amount is not reached for an internal trade.

error InternalTradeMinMaxAmountNotReached();

IncorrectTradeTokenAmount

Reverts when the trade token amount is incorrect.

error IncorrectTradeTokenAmount();

ExternalTradeMismatch

Reverts when given external trades do not match.

error ExternalTradeMismatch();

CompleteTokenSwapFailed

Reverts when the delegatecall to the tokenswap adapter fails.

error CompleteTokenSwapFailed();

AssetNotEnabled

Reverts when an asset included in a bit flag is not enabled in the asset registry.

error AssetNotEnabled();

Structs

InternalTradeInfo

STRUCTS ///

Struct containing data for an internal trade.

struct InternalTradeInfo {
    uint256 fromBasketIndex;
    uint256 toBasketIndex;
    uint256 sellTokenAssetIndex;
    uint256 buyTokenAssetIndex;
    uint256 toBasketBuyTokenIndex;
    uint256 toBasketSellTokenIndex;
    uint256 netBuyAmount;
    uint256 netSellAmount;
    uint256 feeOnBuy;
    uint256 feeOnSell;
}

ExternalTradeInfo

Struct containing data for an external trade.

struct ExternalTradeInfo {
    uint256 sellTokenPrice;
    uint256 buyTokenPrice;
    uint256 sellValue;
    uint256 internalMinAmount;
    uint256 diff;
}

BasketOwnershipInfo

Struct containing data for basket ownership of an external trade.

struct BasketOwnershipInfo {
    uint256 basketIndex;
    uint256 buyTokenAssetIndex;
    uint256 sellTokenAssetIndex;
}