Skip to main content

DepositManager

Git Source

Inherits: Policy, PolicyEnabler, IDepositManager, BaseAssetManager

Title: Deposit Manager

This policy manages deposits and withdrawals for Olympus protocol contracts

Key Features:

  • ERC6909 receipt tokens with optional ERC20 wrapping, using ReceiptTokenManager
  • Operator isolation preventing cross-operator fund access
  • Borrowing functionality
  • Configurable reclaim rates for risk management

Constants​

ROLE_DEPOSIT_OPERATOR​

The role that is allowed to deposit and withdraw funds

bytes32 public constant ROLE_DEPOSIT_OPERATOR = "deposit_operator";

_RECEIPT_TOKEN_MANAGER​

The receipt token manager for creating receipt tokens

ReceiptTokenManager internal immutable _RECEIPT_TOKEN_MANAGER;

ONE_HUNDRED_PERCENT​

Constant equivalent to 100%

uint16 public constant ONE_HUNDRED_PERCENT = 100e2;

State Variables​

_assetLiabilities​

Maps asset liabilities key to the number of receipt tokens that have been minted

This is used to ensure that the receipt tokens are solvent As with the BaseAssetManager, deposited asset tokens with different deposit periods are co-mingled.

mapping(bytes32 key => uint256 receiptTokenSupply) internal _assetLiabilities;

_assetPeriods​

Maps token ID to the asset period

mapping(uint256 tokenId => AssetPeriod) internal _assetPeriods;

_ownedTokenIds​

Set of token IDs that this DepositManager owns

EnumerableSet.UintSet internal _ownedTokenIds;

_operatorToName​

Maps operator address to its name

mapping(address operator => bytes3 name) internal _operatorToName;

_operatorNames​

A set of operator names

This contains unique values

mapping(bytes3 name => bool isRegistered) internal _operatorNames;

_borrowedAmounts​

Maps asset-operator key to current borrowed amounts

The key is the keccak256 of the asset address and the operator address

mapping(bytes32 key => uint256 borrowedAmount) internal _borrowedAmounts;

Functions​

_onlyAssetPeriodExists​

function _onlyAssetPeriodExists(
IERC20 asset_,
uint8 depositPeriod_,
address operator_
) internal view;

Parameters

NameTypeDescription
asset_IERC20
depositPeriod_uint8
operator_address

onlyAssetPeriodExists​

Reverts if the asset period is not configured

modifier onlyAssetPeriodExists(
IERC20 asset_,
uint8 depositPeriod_,
address operator_
);

Parameters

NameTypeDescription
asset_IERC20
depositPeriod_uint8
operator_address

_onlyAssetPeriodEnabled​

function _onlyAssetPeriodEnabled(
IERC20 asset_,
uint8 depositPeriod_,
address operator_
) internal view;

Parameters

NameTypeDescription
asset_IERC20
depositPeriod_uint8
operator_address

onlyAssetPeriodEnabled​

Reverts if the asset period is not enabled

modifier onlyAssetPeriodEnabled(
IERC20 asset_,
uint8 depositPeriod_,
address operator_
);

Parameters

NameTypeDescription
asset_IERC20
depositPeriod_uint8
operator_address

constructor​

constructor(address kernel_, address tokenManager_) Policy(Kernel(kernel_));

Parameters

NameTypeDescription
kernel_address
tokenManager_address

configureDependencies​

Define module dependencies for this policy.

function configureDependencies() external override returns (Keycode[] memory dependencies);

Returns

NameTypeDescription
dependenciesKeycode[]- Keycode array of module dependencies.

requestPermissions​

Function called by kernel to set module function permissions.

function requestPermissions()
external
view
override
returns (Permissions[] memory permissions);

Returns

NameTypeDescription
permissionsPermissions[]- Array of keycodes and function selectors for requested permissions.

VERSION​

function VERSION() external pure returns (uint8 major, uint8 minor);

Returns

NameTypeDescription
majoruint8
minoruint8

deposit​

This function is only callable by addresses with the deposit operator role

The actions of the calling deposit operator are restricted to its own namespace, preventing the operator from accessing funds of other operators.

This function reverts if:

  • The contract is not enabled
  • The caller does not have the deposit operator role
  • The asset/deposit period/operator combination is not enabled
  • The deposit amount is below the minimum deposit requirement
  • The deposit would exceed the asset's deposit cap for the operator
  • The depositor has not approved the DepositManager to spend the asset tokens
  • The depositor has insufficient asset token balance
  • The asset is a fee-on-transfer token
  • Zero shares would be received from the vault
function deposit(
DepositParams calldata params_
)
external
onlyEnabled
onlyRole(ROLE_DEPOSIT_OPERATOR)
onlyAssetPeriodEnabled(params_.asset, params_.depositPeriod, msg.sender)
returns (uint256 receiptTokenId, uint256 actualAmount);

Parameters

NameTypeDescription
params_DepositParamsThe parameters for the deposit

Returns

NameTypeDescription
receiptTokenIduint256The ID of the receipt token
actualAmountuint256The quantity of receipt tokens minted to the depositor

maxClaimYield​

The actions of the calling deposit operator are restricted to its own namespace, preventing the operator from accessing funds of other operators.

Note that the returned value is a theoretical maximum. The theoretical value may not be accurate or possible due to rounding and other behaviours in an ERC4626 vault.

function maxClaimYield(IERC20 asset_, address operator_) external view returns (uint256);

Parameters

NameTypeDescription
asset_IERC20The address of the underlying asset
operator_addressThe address of the operator

Returns

NameTypeDescription
<none>uint256The amount of yield that can be claimed

claimYield​

Notes:

  • This function is only callable by addresses with the deposit operator role
  • The actions of the calling deposit operator are restricted to its own namespace, preventing the operator from accessing funds of other operators.
  • Given a low enough amount, the actual amount withdrawn may be 0. This function will not revert in such a case.

This function reverts if:

  • The contract is not enabled
  • The caller does not have the deposit operator role
  • The asset is not configured in BaseAssetManager
  • The operator becomes insolvent after the withdrawal (assets + borrowed < liabilities)
function claimYield(
IERC20 asset_,
address recipient_,
uint256 amount_
)
external
onlyEnabled
onlyRole(ROLE_DEPOSIT_OPERATOR)
onlyConfiguredAsset(asset_)
returns (uint256 actualAmount);

Parameters

NameTypeDescription
asset_IERC20The address of the underlying asset
recipient_addressThe recipient of the claimed yield
amount_uint256The amount to claim yield for

Returns

NameTypeDescription
actualAmountuint256The quantity of underlying assets transferred to the recipient

withdraw​

Notes:

  • This function is only callable by addresses with the deposit operator role
  • The actions of the calling deposit operator are restricted to its own namespace, preventing the operator from accessing funds of other operators.
  • Given a low enough amount, the actual amount withdrawn may be 0. This function will not revert in such a case.

This function will revert if:

  • The contract is not enabled
  • The caller does not have the deposit operator role
  • The recipient is the zero address
  • The asset/deposit period/operator combination is not configured
  • The depositor has insufficient receipt token balance
  • For wrapped tokens: depositor has not approved ReceiptTokenManager to spend the wrapped ERC20 token
  • For unwrapped tokens: depositor has not approved the caller to spend ERC6909 tokens
  • The operator becomes insolvent after the withdrawal (assets + borrowed < liabilities)
function withdraw(
WithdrawParams calldata params_
) external onlyEnabled onlyRole(ROLE_DEPOSIT_OPERATOR) returns (uint256 actualAmount);

Parameters

NameTypeDescription
params_WithdrawParamsThe parameters for the withdrawal

Returns

NameTypeDescription
actualAmountuint256The quantity of underlying assets transferred to the recipient

getOperatorLiabilities​

Returns the liabilities for an asset and operator pair

function getOperatorLiabilities(
IERC20 asset_,
address operator_
) external view returns (uint256);

Parameters

NameTypeDescription
asset_IERC20The address of the underlying asset
operator_addressThe address of the operator

Returns

NameTypeDescription
<none>uint256The quantity of assets that the contract is custodying for the operator's depositors

_getAssetLiabilitiesKey​

Get the key for the asset liabilities mapping

The key is the keccak256 of the asset address and the operator address

function _getAssetLiabilitiesKey(
IERC20 asset_,
address operator_
) internal pure returns (bytes32);

Parameters

NameTypeDescription
asset_IERC20
operator_address

Returns

NameTypeDescription
<none>bytes32

_validateOperatorSolvency​

Validates that an operator remains solvent after a withdrawal

This function ensures that operator assets + borrowed amount >= operator liabilities This is the core solvency constraint for the DepositManager

Notes:

  • The solvency checks assume that the value of each vault share is increasing, and will not reduce.
  • In a situation where the assets per share reduces below 1 (at the appropriate decimal scale), the solvency check will fail.
function _validateOperatorSolvency(IERC20 asset_, address operator_) internal view;

Parameters

NameTypeDescription
asset_IERC20The asset to validate solvency for
operator_addressThe operator to validate solvency for

setOperatorName​

Note that once set, an operator name cannot be changed.

This function reverts if:

  • The contract is not enabled
  • The caller does not have the admin or manager role
  • The operator's name is already set
  • The name is already in use by another operator
  • The operator name is empty
  • The operator name is not exactly 3 characters long
  • The operator name contains characters that are not a-z or 0-9
function setOperatorName(
address operator_,
string calldata name_
) external onlyEnabled onlyManagerOrAdminRole;

Parameters

NameTypeDescription
operator_address
name_string

getOperatorName​

Returns the name of an operator

function getOperatorName(address operator_) public view returns (string memory);

Parameters

NameTypeDescription
operator_addressThe address of the operator

Returns

NameTypeDescription
<none>stringThe name of the operator or an empty string

isAssetPeriod​

Returns whether a deposit asset, period and operator combination are configured

A asset period that is disabled will not accept further deposits

function isAssetPeriod(
IERC20 asset_,
uint8 depositPeriod_,
address operator_
) public view override returns (AssetPeriodStatus memory status);

Parameters

NameTypeDescription
asset_IERC20The address of the underlying asset
depositPeriod_uint8The deposit period, in months
operator_addressThe address of the operator

Returns

NameTypeDescription
statusAssetPeriodStatusThe status of the asset period

addAsset​

This function reverts if:

  • The contract is not enabled
  • The caller does not have the admin or manager role
  • asset_ is the zero address
  • minimumDeposit > depositCap

Notes:

  • A limitation of the current implementation is that the vault is assumed to be monotonically-increasing in value.
  • The pairing of the asset and vault is immutable, to prevent a governance attack on user deposits.
function addAsset(
IERC20 asset_,
IERC4626 vault_,
uint256 depositCap_,
uint256 minimumDeposit_
) external onlyEnabled onlyManagerOrAdminRole;

Parameters

NameTypeDescription
asset_IERC20The address of the underlying asset
vault_IERC4626The address of the ERC4626 vault to deposit the asset into (or the zero address)
depositCap_uint256The deposit cap of the asset
minimumDeposit_uint256The minimum deposit amount for the asset

setAssetDepositCap​

Sets the deposit cap for an asset

This function reverts if:

  • The contract is not enabled
  • The caller does not have the admin or manager role
  • asset_ is not configured
  • The existing minimum deposit > depositCap_
function setAssetDepositCap(
IERC20 asset_,
uint256 depositCap_
) external onlyEnabled onlyManagerOrAdminRole;

Parameters

NameTypeDescription
asset_IERC20The address of the underlying asset
depositCap_uint256The deposit cap to set for the asset

setAssetMinimumDeposit​

Sets the minimum deposit for an asset

This function reverts if:

  • The contract is not enabled
  • The caller does not have the admin or manager role
  • asset_ is not configured
  • minimumDeposit_ > the existing deposit cap
function setAssetMinimumDeposit(
IERC20 asset_,
uint256 minimumDeposit_
) external onlyEnabled onlyManagerOrAdminRole;

Parameters

NameTypeDescription
asset_IERC20The address of the underlying asset
minimumDeposit_uint256The minimum deposit to set for the asset

addAssetPeriod​

This function is only callable by the manager or admin role

This function reverts if:

  • The contract is not enabled
  • The caller does not have the manager or admin role
  • The asset has not been added via addAsset()
  • The operator is the zero address
  • The deposit period is 0
  • The asset/deposit period/operator combination is already configured
  • The operator name has not been set
  • Receipt token creation fails (invalid parameters in ReceiptTokenManager)
function addAssetPeriod(
IERC20 asset_,
uint8 depositPeriod_,
address operator_
)
external
onlyEnabled
onlyManagerOrAdminRole
onlyConfiguredAsset(asset_)
returns (uint256 receiptTokenId);

Parameters

NameTypeDescription
asset_IERC20The address of the underlying asset
depositPeriod_uint8The deposit period, in months
operator_addressThe address of the operator

Returns

NameTypeDescription
receiptTokenIduint256The ID of the new receipt token

enableAssetPeriod​

This function is only callable by the manager or admin role

This function reverts if:

  • The contract is not enabled
  • The caller does not have the manager or admin role
  • The asset/deposit period/operator combination does not exist
  • The asset period is already enabled
function enableAssetPeriod(
IERC20 asset_,
uint8 depositPeriod_,
address operator_
)
external
onlyEnabled
onlyManagerOrAdminRole
onlyAssetPeriodExists(asset_, depositPeriod_, operator_);

Parameters

NameTypeDescription
asset_IERC20The address of the underlying asset
depositPeriod_uint8The deposit period, in months
operator_addressThe address of the operator

disableAssetPeriod​

This function is only callable by the manager or admin role

This function reverts if:

  • The contract is not enabled
  • The caller does not have the manager or admin role
  • The asset/deposit period/operator combination does not exist
  • The asset period is already disabled
function disableAssetPeriod(
IERC20 asset_,
uint8 depositPeriod_,
address operator_
)
external
onlyEnabled
onlyManagerOrAdminRole
onlyAssetPeriodExists(asset_, depositPeriod_, operator_);

Parameters

NameTypeDescription
asset_IERC20The address of the underlying asset
depositPeriod_uint8The deposit period, in months
operator_addressThe address of the operator

getAssetPeriods​

Gets all configured asset periods

function getAssetPeriods() external view override returns (AssetPeriod[] memory assetPeriods);

Returns

NameTypeDescription
assetPeriodsAssetPeriod[]Array of configured asset periods

getAssetPeriod​

Returns the asset period from a receipt token ID

function getAssetPeriod(uint256 tokenId_) public view override returns (AssetPeriod memory);

Parameters

NameTypeDescription
tokenId_uint256The ID of the receipt token

Returns

NameTypeDescription
<none>AssetPeriodThe asset period

getAssetPeriod​

Returns the asset period for an asset, period and operator

function getAssetPeriod(
IERC20 asset_,
uint8 depositPeriod_,
address operator_
) public view override returns (AssetPeriod memory);

Parameters

NameTypeDescription
asset_IERC20The address of the underlying asset
depositPeriod_uint8The deposit period, in months
operator_addressThe address of the operator

Returns

NameTypeDescription
<none>AssetPeriodThe asset period

borrowingWithdraw​

Notes:

  • This function is only callable by addresses with the deposit operator role
  • Given a low enough amount, the actual amount withdrawn may be 0. This function will not revert in such a case.

This function reverts if:

  • The contract is not enabled
  • The caller does not have the deposit operator role
  • The recipient is the zero address
  • The asset has not been added via addAsset()
  • The amount exceeds the operator's available borrowing capacity
  • The operator becomes insolvent after the withdrawal (assets + borrowed < liabilities)
function borrowingWithdraw(
BorrowingWithdrawParams calldata params_
) external onlyEnabled onlyRole(ROLE_DEPOSIT_OPERATOR) returns (uint256 actualAmount);

Parameters

NameTypeDescription
params_BorrowingWithdrawParamsThe parameters for the borrowing withdrawal

Returns

NameTypeDescription
actualAmountuint256The quantity of underlying assets transferred to the recipient

borrowingRepay​

Notes:

  • This function is only callable by addresses with the deposit operator role
  • This function does not check for over-payment. It is expected to be handled by the calling contract.
  • If the actual amount repaid is greater than the maximum amount provided, updates to the state variables are capped at the maximum amount.

This function reverts if:

  • The contract is not enabled
  • The caller does not have the deposit operator role
  • The asset has not been added via addAsset()
  • The payer has not approved DepositManager to spend the asset tokens
  • The payer has insufficient asset token balance
  • The asset is a fee-on-transfer token
  • Zero shares would be deposited into the vault
  • The operator becomes insolvent after the repayment (assets + borrowed < liabilities)
function borrowingRepay(
BorrowingRepayParams calldata params_
) external onlyEnabled onlyRole(ROLE_DEPOSIT_OPERATOR) returns (uint256 actualAmount);

Parameters

NameTypeDescription
params_BorrowingRepayParamsThe parameters for the borrowing repayment

Returns

NameTypeDescription
actualAmountuint256The quantity of underlying assets received from the payer

borrowingDefault​

This function is only callable by addresses with the deposit operator role

This function reverts if:

  • The contract is not enabled
  • The caller does not have the deposit operator role
  • The asset has not been added via addAsset()
  • The amount exceeds the current borrowed amount for the operator
  • The payer has insufficient receipt token balance
  • The payer has not approved the caller to spend ERC6909 tokens
  • The operator becomes insolvent after the default (assets + borrowed < liabilities)
function borrowingDefault(
BorrowingDefaultParams calldata params_
) external onlyEnabled onlyRole(ROLE_DEPOSIT_OPERATOR);

Parameters

NameTypeDescription
params_BorrowingDefaultParams

getBorrowedAmount​

Gets the current borrowed amount for an operator

function getBorrowedAmount(
IERC20 asset_,
address operator_
) public view returns (uint256 borrowed);

Parameters

NameTypeDescription
asset_IERC20The address of the underlying asset
operator_addressThe address of the operator

Returns

NameTypeDescription
borroweduint256The current borrowed amount for the operator

getBorrowingCapacity​

Gets the available borrowing capacity for an operator

function getBorrowingCapacity(
IERC20 asset_,
address operator_
) public view returns (uint256 capacity);

Parameters

NameTypeDescription
asset_IERC20The address of the underlying asset
operator_addressThe address of the operator

Returns

NameTypeDescription
capacityuint256The available borrowing capacity for the operator

_setReceiptTokenData​

function _setReceiptTokenData(
IERC20 asset_,
uint8 depositPeriod_,
address operator_
) internal returns (uint256 tokenId);

Parameters

NameTypeDescription
asset_IERC20
depositPeriod_uint8
operator_address

Returns

NameTypeDescription
tokenIduint256

getReceiptTokenId​

Returns the ID of the receipt token for an asset period and operator

The ID returned is not a guarantee that the asset period is configured or enabled. isAssetPeriod should be used for that purpose.

function getReceiptTokenId(
IERC20 asset_,
uint8 depositPeriod_,
address operator_
) public view override returns (uint256);

Parameters

NameTypeDescription
asset_IERC20The address of the underlying asset
depositPeriod_uint8The deposit period, in months
operator_addressThe address of the operator

Returns

NameTypeDescription
<none>uint256The ID of the receipt token

getReceiptTokenManager​

Gets the receipt token manager

function getReceiptTokenManager() external view override returns (IReceiptTokenManager);

Returns

NameTypeDescription
<none>IReceiptTokenManagerThe receipt token manager contract

getReceiptTokenIds​

Gets all receipt token IDs owned by this contract

function getReceiptTokenIds() external view override returns (uint256[] memory);

Returns

NameTypeDescription
<none>uint256[]Array of receipt token IDs

getReceiptToken​

Convenience function that returns both receipt token ID and wrapped token address

function getReceiptToken(
IERC20 asset_,
uint8 depositPeriod_,
address operator_
) external view override returns (uint256 tokenId, address wrappedToken);

Parameters

NameTypeDescription
asset_IERC20The asset contract
depositPeriod_uint8The deposit period in months
operator_addressThe operator address

Returns

NameTypeDescription
tokenIduint256The receipt token ID
wrappedTokenaddressThe address of the wrapped ERC20 token (0x0 if not created yet)

supportsInterface​

function supportsInterface(
bytes4 interfaceId
) public view virtual override(BaseAssetManager, PolicyEnabler) returns (bool);

Parameters

NameTypeDescription
interfaceIdbytes4

Returns

NameTypeDescription
<none>bool

rescue​

Rescue any ERC20 token sent to this contract and send it to the TRSRY

This function reverts if:

  • The caller does not have the admin role
  • token_ is a managed asset or vault
  • token_ is the zero address
function rescue(address token_) external onlyEnabled onlyAdminRole;

Parameters

NameTypeDescription
token_addressThe address of the ERC20 token to rescue