Foundry

Foundry is a blazing fast, portable and modular toolkit for Ethereum application development written in Rust.

Foundry consists of:

  • Forge: Ethereum testing framework (like Truffle, Hardhat and DappTools).
  • Cast: Swiss army knife for interacting with EVM smart contracts, sending transactions and getting chain data.
  • Anvil: Local Ethereum node, akin to Ganache, Hardhat Network.
  • Chisel: Fast, utilitarian, and verbose solidity REPL.

Documentation

https://book.getfoundry.sh/

Usage

Build

$ forge build

Test

$ forge test

Format

$ forge fmt

Gas Snapshots

$ forge snapshot

Anvil

$ anvil

Deploy

$ forge script script/Counter.s.sol:CounterScript --rpc-url <your_rpc_url> --private-key <your_private_key>

Cast

$ cast <subcommand>

Help

$ forge --help
$ anvil --help
$ cast --help

Contents

Constants

Git Source

Author: luoyhang003

Provides commonly used mathematical and configuration constants

Designed to be inherited by other contracts that require fixed values

State Variables

D18

Scaling factor for 18-decimal precision (commonly used in ERC20 tokens)

Equal to 10^18

uint256 internal constant D18 = 1e18;

D6

Scaling factor for 6-decimal precision

Equal to 10^6

uint256 internal constant D6 = 1e6;

BASE_DECIMALS

Default number of decimals used for calculations

Typically corresponds to 18-decimal precision

uint256 internal constant BASE_DECIMALS = 18;

FEE_DENOMINATOR

Denominator used for fee calculations

Basis point system: denominator = 10,000 (e.g., 100 = 1%)

uint256 internal constant FEE_DENOMINATOR = 1e4;

BPS_DENOMINATOR

Denominator for basis points calculations (10000 = 100%)

Basis point system: denominator = 10,000 (e.g., 100 = 1%)

uint256 internal constant BPS_DENOMINATOR = 1e4;

INIT_EXCHANGE_PRICE

Initial exchange price for tokenized vault lp

Set to 1 * 10^18 (represents a price of 1.0 in 18 decimals)

uint256 internal constant INIT_EXCHANGE_PRICE = 1e18;

STABLECOIN_BASE_PRICE

The base reference price for a stablecoin, normalized to 18 decimals.

Set to 1 * 10^18 (represents a price of 1.0 in 18 decimals)

uint256 internal constant STABLECOIN_BASE_PRICE = 1e18;

Contents

IAccessRegistry

Git Source

Author: luoyhang003

Interface for managing access control via whitelist and blacklist

Provides events and view functions to track and query account permissions

Functions

isWhitelisted

Checks whether a given address is whitelisted

function isWhitelisted(address _account) external view returns (bool);

Parameters

NameTypeDescription
_accountaddressThe address to check

Returns

NameTypeDescription
<none>boolTrue if the address is whitelisted, false otherwise

isBlacklisted

Checks whether a given address is blacklisted

function isBlacklisted(address _account) external view returns (bool);

Parameters

NameTypeDescription
_accountaddressThe address to check

Returns

NameTypeDescription
<none>boolTrue if the address is blacklisted, false otherwise

Events

WhitelistAdded

Emitted when an array of users is added to the whitelist.

event WhitelistAdded(address[] users);

Parameters

NameTypeDescription
usersaddress[]An array of addresses added to the whitelist.

BlacklistAdded

Emitted when an array of users is added to the blacklist.

event BlacklistAdded(address[] users);

Parameters

NameTypeDescription
usersaddress[]An array of addresses added to the blacklist.

WhitelistRemoved

Emitted when an array of users is removed from the whitelist.

event WhitelistRemoved(address[] users);

Parameters

NameTypeDescription
usersaddress[]An array of addresses removed from the whitelist.

BlacklistRemoved

Emitted when an array of users is removed from the blacklist.

event BlacklistRemoved(address[] users);

Parameters

NameTypeDescription
usersaddress[]An array of addresses removed from the blacklist.

IAssetsRouter

Git Source

Functions

route

Deposit tokens into the router and optionally forward them to the active recipient.

Pulls tokens from msg.sender into this contract. If auto-route is enabled, immediately forwards them to _activeRecipient.

function route(address _token, uint256 _amount) external;

Parameters

NameTypeDescription
_tokenaddressThe ERC20 token address being routed.
_amountuint256The amount of tokens to transfer.

getRouteRecipients

Returns the list of approved route recipients.

Returns the full list of route recipients currently registered in the router.

function getRouteRecipients() external view returns (address[] memory routeRecipients_);

Returns

NameTypeDescription
routeRecipients_address[]The array of all registered recipient addresses.

isRouteRecipient

Checks if an address is a valid route recipient.

Checks if a given address is a registered route recipient.

function isRouteRecipient(address _addr) external view returns (bool);

Parameters

NameTypeDescription
_addraddressThe address to check.

Returns

NameTypeDescription
<none>boolTrue if the address is a valid route recipient, otherwise false.

getActiveRecipient

Returns the currently active route recipient.

Returns the currently active route recipient where assets are routed automatically.

function getActiveRecipient() external view returns (address activeRecipient_);

Returns

NameTypeDescription
activeRecipient_addressThe address of the active route recipient.

isAutoRouteEnabled

Returns whether auto-routing is enabled.

Indicates whether automatic routing is currently enabled.

function isAutoRouteEnabled() external view returns (bool enabled_);

Returns

NameTypeDescription
enabled_boolBoolean flag, true if auto-routing is enabled, false otherwise.

Events

RouteRecipientAdded

Emitted when a new route recipient is added

event RouteRecipientAdded(address indexed recipient);

Parameters

NameTypeDescription
recipientaddressThe address of the recipient added

RouteRecipientRemoved

Emitted when a route recipient is removed

event RouteRecipientRemoved(address indexed recipient);

Parameters

NameTypeDescription
recipientaddressThe address of the recipient removed

SetAutoRouteEnabled

Emitted when auto-routing is enabled or disabled

event SetAutoRouteEnabled(bool enabled);

Parameters

NameTypeDescription
enabledboolTrue if auto-routing is enabled, false otherwise

SetActiveRecipient

Emitted when the active recipient is changed

event SetActiveRecipient(address indexed recipient);

Parameters

NameTypeDescription
recipientaddressThe new active recipient address

AssetsReceived

Emitted when assets are received by the contract

event AssetsReceived(address indexed token, address indexed recipient, uint256 amount);

Parameters

NameTypeDescription
tokenaddressThe ERC20 token address received
recipientaddressThe address sending the assets
amountuint256The amount of tokens received

AssetsRouted

Emitted when assets are routed to a recipient

event AssetsRouted(address indexed token, address indexed recipient, uint256 amount);

Parameters

NameTypeDescription
tokenaddressThe ERC20 token address routed
recipientaddressThe address receiving the routed assets
amountuint256The amount of tokens routed

IDepositVault

Git Source

Author: luoyhang003

Interface for a Deposit Vault contract that manages deposits of underlying assets and issues vault shares in return. Provides functionality to deposit, mint, preview conversions, and retrieve vault-related price information.

This interface defines the core vault operations and events to standardize how assets and shares are handled within the vault system.

Functions

deposit

Deposit an underlying asset and receive vault shares.

Equivalent to depositFor with msg.sender as receiver.

function deposit(address _asset, uint256 _amount) external returns (uint256 shares_);

Parameters

NameTypeDescription
_assetaddressAddress of the asset to deposit.
_amountuint256Amount of asset to deposit.

Returns

NameTypeDescription
shares_uint256Number of shares minted.

depositFor

Deposit an underlying asset on behalf of another account.

Reverts if receiver is zero address.

function depositFor(address _asset, uint256 _amount, address _receiver) external returns (uint256 shares_);

Parameters

NameTypeDescription
_assetaddressAddress of the asset to deposit.
_amountuint256Amount of asset to deposit.
_receiveraddressRecipient of the minted shares.

Returns

NameTypeDescription
shares_uint256Number of shares minted.

mint

Mint a specific number of shares by depositing assets.

Equivalent to mintFor with msg.sender as receiver.

function mint(address _asset, uint256 _shares) external returns (uint256 assets_);

Parameters

NameTypeDescription
_assetaddressAddress of the asset to deposit.
_sharesuint256Number of shares to mint.

Returns

NameTypeDescription
assets_uint256Amount of assets required.

mintFor

Mint a specific number of shares on behalf of another account.

Reverts if receiver is zero address.

function mintFor(address _asset, uint256 _shares, address _receiver) external returns (uint256 assets_);

Parameters

NameTypeDescription
_assetaddressAddress of the asset to deposit.
_sharesuint256Number of shares to mint.
_receiveraddressRecipient of the minted shares.

Returns

NameTypeDescription
assets_uint256Amount of assets required.

exchangePrice

Returns the cutoff vault token price (e.g. for settlement).

Fetches the cutoff price directly from the oracle register.

function exchangePrice() external view returns (uint256 price_);

Returns

NameTypeDescription
price_uint256Current vault token cutoff price.

convertToShares

Converts underlying assets to equivalent vault shares.

Normalizes _amount to 18 decimals before conversion. Uses floor rounding to avoid overestimating shares.

function convertToShares(address _asset, uint256 _amount)
    external
    view
    returns (uint256 shares_, uint256 underlyingPrice_, uint256 vaultTokenPrice_);

Parameters

NameTypeDescription
_assetaddressAddress of the underlying asset.
_amountuint256Amount of underlying asset.

Returns

NameTypeDescription
shares_uint256Equivalent vault shares.
underlyingPrice_uint256Price of the underlying asset.
vaultTokenPrice_uint256Price of the vault token.

convertToAssets

Converts vault shares to equivalent underlying assets.

Denormalizes values back from 18 decimals to asset decimals. Uses floor rounding to avoid overestimating asset returns.

function convertToAssets(address _asset, uint256 _shares)
    external
    view
    returns (uint256 assets_, uint256 underlyingPrice_, uint256 vaultTokenPrice_);

Parameters

NameTypeDescription
_assetaddressAddress of the underlying asset.
_sharesuint256Number of vault shares.

Returns

NameTypeDescription
assets_uint256Equivalent underlying asset amount.
underlyingPrice_uint256Price of the underlying asset.
vaultTokenPrice_uint256Price of the vault token.

previewDeposit

Previews deposit outcome including shares, fee, and prices.

Simulates deposit logic without state changes. Performs fee deduction, cap checks, and price fetches.

function previewDeposit(address _asset, uint256 _amount)
    external
    view
    returns (uint256 shares_, uint256 fee_, uint256 underlyingPrice_, uint256 vaultTokenPrice_);

Parameters

NameTypeDescription
_assetaddressAddress of the underlying asset.
_amountuint256Deposit amount.

Returns

NameTypeDescription
shares_uint256Number of shares minted.
fee_uint256Fee charged on deposit.
underlyingPrice_uint256Price of the underlying asset.
vaultTokenPrice_uint256Price of the vault token.

previewMint

Previews mint outcome including assets, fee, and prices.

Simulates mint logic without state changes. Performs fee addition, cap checks, and price fetches.

function previewMint(address _asset, uint256 _shares)
    external
    view
    returns (uint256 assets_, uint256 fee_, uint256 underlyingPrice_, uint256 vaultTokenPrice_);

Parameters

NameTypeDescription
_assetaddressAddress of the underlying asset.
_sharesuint256Number of shares to mint.

Returns

NameTypeDescription
assets_uint256Required underlying assets.
fee_uint256Fee charged on mint.
underlyingPrice_uint256Price of the underlying asset.
vaultTokenPrice_uint256Price of the vault token.

getUnderlyings

Returns list of all supported underlying assets.

Returns storage array directly; use cautiously in gas-sensitive contexts.

function getUnderlyings() external view returns (address[] memory underlyings);

Returns

NameTypeDescription
underlyingsaddress[]Array of supported assets.

Events

Deposit

Emitted when a deposit is made into the vault.

event Deposit(
    address indexed asset, uint256 amount, uint256 shares, uint256 fee, uint256 underlyingPrice, uint256 vaultTokenPrice
);

Parameters

NameTypeDescription
assetaddressThe address of the underlying asset being deposited.
amountuint256The amount of the underlying asset deposited.
sharesuint256The number of vault shares minted for the deposit.
feeuint256The fee charged during the deposit (if any).
underlyingPriceuint256The price of the underlying asset at the time of deposit.
vaultTokenPriceuint256The exchange rate of vault shares at the time of deposit.

UnderlyingAssetAdded

Emitted when a new underlying asset is added to the vault.

event UnderlyingAssetAdded(address asset);

Parameters

NameTypeDescription
assetaddressThe address of the underlying asset added.

UnderlyingAssetRemoved

Emitted when an underlying asset is removed from the vault.

event UnderlyingAssetRemoved(address asset);

Parameters

NameTypeDescription
assetaddressThe address of the underlying asset removed.

SetAssetsRouter

Emitted when the assets router is updated.

event SetAssetsRouter(address oldRouter, address newRouter);

Parameters

NameTypeDescription
oldRouteraddressThe address of the old assets router.
newRouteraddressThe address of the new assets router.

IOracleFeed

Git Source

Author: luoyhang003

Standardized interface for oracle price feeds.

Provides a unified method for fetching the latest asset price. Implementations may differ (e.g., Chainlink, Redstone, custom oracles), but must conform to this interface.

Functions

peek

Returns the latest price from the oracle.

The return value should be normalized to 18 decimals whenever possible to maintain consistency across different oracle implementations.

function peek() external view returns (uint256 price_);

Returns

NameTypeDescription
price_uint256The most recent valid price.

IOracleRegistry

Git Source

Author: luoyhang003

Interface for Oracle Registry contract to manage token oracles and price updates

Handles addition, removal, and updates of token oracles. Stores historical prices and cut-off prices. Includes role-based access control: PRICE_UPDATE_ROLE for price updates, ORACLE_MANAGE_ROLE for oracle management.

Functions

getOracle

Returns the oracle feed address for a given token

Returns zero address if token is not registered

function getOracle(address _token) external view returns (address oracle_);

Parameters

NameTypeDescription
_tokenaddressToken address to query

Returns

NameTypeDescription
oracle_addressAddress of the oracle feed

getTokens

Returns all registered token addresses

Useful for iterating over all tokens to fetch historical prices

function getTokens() external view returns (address[] memory tokens_);

Returns

NameTypeDescription
tokens_address[]Array of token addresses

latestPricesUpdatedAt

Returns the timestamp of the latest common price update

Reverts if no updates exist

function latestPricesUpdatedAt() external view returns (uint256 timestamp_);

Returns

NameTypeDescription
timestamp_uint256Timestamp of latest update

latestCutOffPriceUpdatedAt

Returns the timestamp of the latest cut-off price update

Reverts if no cut-off updates exist

function latestCutOffPriceUpdatedAt() external view returns (uint256 timestamp_);

Returns

NameTypeDescription
timestamp_uint256Timestamp of latest cut-off update

peek

Returns the latest price of a token from its oracle

Performs deviation check to prevent extreme values

function peek(address _token) external view returns (uint256 price_);

Parameters

NameTypeDescription
_tokenaddressToken address

Returns

NameTypeDescription
price_uint256Latest price from oracle

peekAt

Returns historical price for a token at a given index

Checks price validity (time not expired)

function peekAt(address _token, uint256 _index) external view returns (uint256 price_);

Parameters

NameTypeDescription
_tokenaddressToken address
_indexuint256Index (0 = latest)

Returns

NameTypeDescription
price_uint256Historical price

onlyPeekAt

Returns historical price without validity check

Useful for auditing or internal calculations

function onlyPeekAt(address _token, uint256 _index) external view returns (uint256 price_);

Parameters

NameTypeDescription
_tokenaddressToken address
_indexuint256Index (0 = latest)

Returns

NameTypeDescription
price_uint256Historical price

getVaultTokenPrice

Returns the historical price of the vault token at a given index

Checks price validity

function getVaultTokenPrice(uint256 _index) external view returns (uint256 price_);

Parameters

NameTypeDescription
_indexuint256Index (0 = latest)

Returns

NameTypeDescription
price_uint256Vault token price

onlyGetVaultTokenPrice

Returns the historical price of the vault token without validity check

Useful for internal calculations

function onlyGetVaultTokenPrice(uint256 _index) external view returns (uint256 price_);

Parameters

NameTypeDescription
_indexuint256Index (0 = latest)

Returns

NameTypeDescription
price_uint256Vault token price

getCutOffPrice

Returns token price at a cut-off update

Reverts if price is expired or index out of bounds

function getCutOffPrice(address _token, uint256 _index) external view returns (uint256 price_);

Parameters

NameTypeDescription
_tokenaddressToken address
_indexuint256Index of cut-off update (0 = latest)

Returns

NameTypeDescription
price_uint256The cut-off price for the token

getCutOffPrices

Returns token addresses and prices at a cut-off update

Reverts if price is expired or index out of bounds

function getCutOffPrices(uint256 _index) external view returns (address[] memory tokens_, uint256[] memory prices_);

Parameters

NameTypeDescription
_indexuint256Index of cut-off update (0 = latest)

Returns

NameTypeDescription
tokens_address[]Array of token addresses
prices_uint256[]Array of prices for each token

onlyGetCutOffPrices

Same as getCutOffPrices but does not check validity

Useful for internal auditing or calculation

function onlyGetCutOffPrices(uint256 _index)
    external
    view
    returns (address[] memory tokens_, uint256[] memory prices_);

Parameters

NameTypeDescription
_indexuint256Index of cut-off update (0 = latest)

Returns

NameTypeDescription
tokens_address[]Array of token addresses
prices_uint256[]Array of prices for each token

getVaultTokenCutOffPrice

Returns the vault token cut-off price at a given index

Checks validity

function getVaultTokenCutOffPrice(uint256 _index) external view returns (uint256 price_);

Parameters

NameTypeDescription
_indexuint256Index of cut-off update (0 = latest)

Returns

NameTypeDescription
price_uint256Vault token price

onlyGetVaultTokenCutOffPrice

Returns the vault token cut-off price without validity check

Useful for internal calculations

function onlyGetVaultTokenCutOffPrice(uint256 _index) external view returns (uint256 price_);

Parameters

NameTypeDescription
_indexuint256Index of cut-off update (0 = latest)

Returns

NameTypeDescription
price_uint256Vault token price

Events

OracleAdded

Emitted when a new token oracle is added

Only callable via OracleRegistry contract functions that manage oracles

event OracleAdded(address indexed token, address indexed oracle);

Parameters

NameTypeDescription
tokenaddressThe token address associated with the oracle
oracleaddressThe oracle address providing price feeds

OracleRemoved

Emitted when a token oracle is removed

Only callable via OracleRegistry contract functions that manage oracles

event OracleRemoved(address indexed token);

Parameters

NameTypeDescription
tokenaddressThe token address whose oracle is removed

OracleUpdated

Emitted when a token oracle is updated

Only callable via OracleRegistry contract functions that manage oracles

event OracleUpdated(address indexed token, address indexed oracle);

Parameters

NameTypeDescription
tokenaddressThe token address whose oracle is updated
oracleaddressThe new oracle address

PriceUpdated

Emitted when a token price is updated

Only callable by addresses with PRICE_UPDATE_ROLE

event PriceUpdated(address indexed token, uint256 price, uint256 updatedAt, bool isCutOffPrice);

Parameters

NameTypeDescription
tokenaddressThe token address
priceuint256The new price
updatedAtuint256Timestamp when the price is updated
isCutOffPriceboolWhether this price is a cut-off price

IParamRegistry

Git Source

Author: luoyhang003

Interface for the protocol parameter registry contract.

  • Defines key protocol configuration parameters such as fee rates, deposit caps, price tolerances, and critical role-restricted settings.
  • Provides events for tracking parameter updates to ensure transparency and auditability.
  • Exposes getter functions for external contracts to query configuration values, and (in the implementing contract) setter functions protected by timelock roles.
  • Used as the central source of truth for system-wide configuration and policy enforcement.*

Functions

getExchangeRateMaxUpperToleranceBps

Returns the current upper tolerance for exchange rate deviation.

function getExchangeRateMaxUpperToleranceBps() external view returns (uint256);

getExchangeRateMaxLowerToleranceBps

Returns the current lower tolerance for exchange rate deviation.

function getExchangeRateMaxLowerToleranceBps() external view returns (uint256);

getStablecoinPriceToleranceBps

Returns the current stablecoin price tolerance in bps.

function getStablecoinPriceToleranceBps() external view returns (uint256);

getVolatileAssetPriceToleranceBps

Returns the current volatile asset price tolerance in bps.

function getVolatileAssetPriceToleranceBps() external view returns (uint256);

getPriceUpdateInterval

Returns the minimum interval between price updates.

function getPriceUpdateInterval() external view returns (uint256);

getPriceValidityDuration

Returns the maximum validity duration of cached prices.

function getPriceValidityDuration() external view returns (uint256);

getMintFeeRate

Returns the configured mint fee rate for a given asset.

function getMintFeeRate(address _asset) external view returns (uint256);

Parameters

NameTypeDescription
_assetaddressThe address of the asset.

Returns

NameTypeDescription
<none>uint256The mint fee rate in basis points.

getRedeemFeeRate

Returns the configured redeem fee rate for a given asset.

function getRedeemFeeRate(address _asset) external view returns (uint256);

Parameters

NameTypeDescription
_assetaddressThe address of the asset.

Returns

NameTypeDescription
<none>uint256The redeem fee rate in basis points.

getDepositEnabled

Returns whether deposits are enabled for a given asset.

function getDepositEnabled(address _asset) external view returns (bool);

Parameters

NameTypeDescription
_assetaddressThe address of the asset.

Returns

NameTypeDescription
<none>boolTrue if deposits are enabled, false otherwise.

getRedeemEnabled

Returns whether redemptions are enabled for a given asset.

function getRedeemEnabled(address _asset) external view returns (bool);

Parameters

NameTypeDescription
_assetaddressThe address of the asset.

Returns

NameTypeDescription
<none>boolTrue if redemptions are enabled, false otherwise.

getTotalDepositCap

Returns the global deposit cap.

function getTotalDepositCap() external view returns (uint256);

getTokenDepositCap

Returns the deposit cap for a specific asset.

function getTokenDepositCap(address _asset) external view returns (uint256);

Parameters

NameTypeDescription
_assetaddressThe address of the asset.

getFeeRecipient

Returns the address of the fee recipient.

function getFeeRecipient() external view returns (address);

getForfeitTreasury

Returns the address of the forfeited assets treasury.

function getForfeitTreasury() external view returns (address);

Events

SetExchangeRateMaxUpperToleranceBps

Emitted when the maximum upper tolerance for exchange rate deviation is updated.

event SetExchangeRateMaxUpperToleranceBps(uint256 oldVal, uint256 newVal);

Parameters

NameTypeDescription
oldValuint256Previous tolerance value in basis points.
newValuint256New tolerance value in basis points.

SetExchangeRateMaxLowerToleranceBps

Emitted when the maximum lower tolerance for exchange rate deviation is updated.

event SetExchangeRateMaxLowerToleranceBps(uint256 oldVal, uint256 newVal);

Parameters

NameTypeDescription
oldValuint256Previous tolerance value in basis points.
newValuint256New tolerance value in basis points.

SetStablecoinPriceToleranceBps

Emitted when the stablecoin price tolerance is updated.

event SetStablecoinPriceToleranceBps(uint256 oldVal, uint256 newVal);

Parameters

NameTypeDescription
oldValuint256Previous tolerance value in basis points.
newValuint256New tolerance value in basis points.

SetVolatileAssetPriceToleranceBps

Emitted when the volatile asset price tolerance is updated.

event SetVolatileAssetPriceToleranceBps(uint256 oldVal, uint256 newVal);

Parameters

NameTypeDescription
oldValuint256Previous tolerance value in basis points.
newValuint256New tolerance value in basis points.

SetPriceUpdateInterval

Emitted when the minimum price update interval is updated.

event SetPriceUpdateInterval(uint256 oldVal, uint256 newVal);

Parameters

NameTypeDescription
oldValuint256Previous interval value in seconds.
newValuint256New interval value in seconds.

SetPriceValidityDuration

Emitted when the maximum price validity duration is updated.

event SetPriceValidityDuration(uint256 oldVal, uint256 newVal);

Parameters

NameTypeDescription
oldValuint256Previous duration value in seconds.
newValuint256New duration value in seconds.

SetMintFeeRate

Emitted when the mint fee rate for a specific asset is updated.

event SetMintFeeRate(address indexed asset, uint256 oldRate, uint256 newRate);

Parameters

NameTypeDescription
assetaddressThe address of the asset.
oldRateuint256Previous mint fee rate in basis points.
newRateuint256New mint fee rate in basis points.

SetRedeemFeeRate

Emitted when the redeem fee rate for a specific asset is updated.

event SetRedeemFeeRate(address indexed asset, uint256 oldRate, uint256 newRate);

Parameters

NameTypeDescription
assetaddressThe address of the asset.
oldRateuint256Previous redeem fee rate in basis points.
newRateuint256New redeem fee rate in basis points.

SetDepositEnabled

Emitted when deposit enablement is updated for a specific asset.

event SetDepositEnabled(address indexed asset, bool enabled);

Parameters

NameTypeDescription
assetaddressThe address of the asset.
enabledboolTrue if deposits are enabled, false otherwise.

SetRedeemEnabled

Emitted when redemption enablement is updated for a specific asset.

event SetRedeemEnabled(address indexed asset, bool enabled);

Parameters

NameTypeDescription
assetaddressThe address of the asset.
enabledboolTrue if redemptions are enabled, false otherwise.

SetTotalDepositCap

Emitted when the global deposit cap is updated.

event SetTotalDepositCap(uint256 oldVal, uint256 newVal);

Parameters

NameTypeDescription
oldValuint256Previous global deposit cap.
newValuint256New global deposit cap.

SetTokenDepositCap

Emitted when the deposit cap for a specific asset is updated.

event SetTokenDepositCap(address indexed asset, uint256 oldVal, uint256 newVal);

Parameters

NameTypeDescription
assetaddressThe address of the asset.
oldValuint256Previous cap value.
newValuint256New cap value.

SetFeeRecipient

Emitted when the fee recipient address is updated.

event SetFeeRecipient(address oldVal, address newVal);

Parameters

NameTypeDescription
oldValaddressPrevious fee recipient address.
newValaddressNew fee recipient address.

SetForfeitTreasury

Emitted when the forfeited assets treasury address is updated.

event SetForfeitTreasury(address oldVal, address newVal);

Parameters

NameTypeDescription
oldValaddressPrevious treasury address.
newValaddressNew treasury address.

IWithdrawController

Git Source

Author: luoyhang003

Interface for the WithdrawController contract, which manages withdrawal requests, processing, completion, and administration of supported withdrawal assets.

Defines core data structures, events, and status enums used by the WithdrawController implementation.

Functions

requestWithdrawal

Request withdrawal of a specific asset by burning shares.

User must be whitelisted. Generates a withdrawal receipt.

function requestWithdrawal(address _requestToken, uint256 _shares) external;

Parameters

NameTypeDescription
_requestTokenaddressAsset to withdraw into.
_sharesuint256Number of shares to redeem.

requestWithdrawals

Batch request withdrawals across multiple assets.

Lengths must match. Generates multiple withdrawal receipts.

function requestWithdrawals(address[] memory _requestTokens, uint256[] memory _shares) external;

Parameters

NameTypeDescription
_requestTokensaddress[]List of withdrawal asset addresses.
_sharesuint256[]Corresponding share amounts per asset.

cancelWithdrawal

Cancel a single pending withdrawal request.

Only the original requester can cancel. Shares are refunded.

function cancelWithdrawal(uint256 _id) external;

Parameters

NameTypeDescription
_iduint256Receipt ID of the withdrawal request.

cancelWithdrawals

Batch cancel withdrawal requests.

Only the original requester can cancel. Shares are refunded.

function cancelWithdrawals(uint256[] memory _ids) external;

Parameters

NameTypeDescription
_idsuint256[]An array of receipt IDs of the withdrawal requests.

completeWithdrawal

Complete a withdrawal once processed.

Burns shares, transfers asset to user, applies fees.

function completeWithdrawal(uint256 _id) external;

Parameters

NameTypeDescription
_iduint256Receipt ID of withdrawal.

completeWithdrawals

Batch complete withdrawals.

Burns shares, transfers asset to user, applies fees.

function completeWithdrawals(uint256[] memory _ids) external;

Parameters

NameTypeDescription
_idsuint256[]An array of receipt IDs of withdrawals.

getWithdrawalReceiptsLength

Returns total number of withdrawal receipts created.

function getWithdrawalReceiptsLength() external view returns (uint256 length_);

Returns

NameTypeDescription
length_uint256Total number of withdrawal receipts.

getWithdrawalReceipts

Paginates withdrawal receipts.

function getWithdrawalReceipts(uint256 _offset, uint256 _limit)
    external
    view
    returns (WithdrawalReceipt[] memory receipts_);

Parameters

NameTypeDescription
_offsetuint256Start index in array.
_limituint256Number of receipts to fetch.

Returns

NameTypeDescription
receipts_WithdrawalReceipt[]List of withdrawal receipts within range.

Events

WithdrawalRequested

Emitted when a user submits a withdrawal request.

event WithdrawalRequested(address indexed requester, address indexed requestAsset, uint256 requestShares, uint256 id);

Parameters

NameTypeDescription
requesteraddressThe address of the user requesting withdrawal.
requestAssetaddressThe asset requested for withdrawal.
requestSharesuint256The number of shares submitted for withdrawal.
iduint256The unique ID assigned to the withdrawal receipt.

WithdrawalCancelled

Emitted when a withdrawal request is cancelled by the user.

event WithdrawalCancelled(address indexed requester, uint256 requestShares, uint256 id);

Parameters

NameTypeDescription
requesteraddressThe address of the user who cancelled.
requestSharesuint256The number of shares refunded.
iduint256The ID of the cancelled withdrawal receipt.

WithdrawalCompleted

Emitted when a withdrawal is completed and assets are transferred.

event WithdrawalCompleted(
    address indexed requester, address indexed withdrawnAsset, uint256 withdrawnAmount, uint256 feeCharged, uint256 id
);

Parameters

NameTypeDescription
requesteraddressThe user receiving withdrawn assets.
withdrawnAssetaddressThe ERC20 asset withdrawn.
withdrawnAmountuint256The amount of asset received by the user.
feeChargeduint256The fee amount deducted from the withdrawal.
iduint256The ID of the completed withdrawal receipt.

WithdrawalProcessing

Emitted when a withdrawal request is marked as processing.

event WithdrawalProcessing(uint256 shareTokenPrice, uint256 requestAssetPrice, uint256 id);

Parameters

NameTypeDescription
shareTokenPriceuint256The price of the share token at processing.
requestAssetPriceuint256The price of the requested asset at processing.
iduint256The ID of the withdrawal receipt being processed.

AllMarkedAsProcessing

Emitted when all targeted withdrawal requests are marked as processing.

event AllMarkedAsProcessing();

WithdrawalProcessed

Emitted when a withdrawal receipt is marked as processed.

event WithdrawalProcessed(uint256 id);

Parameters

NameTypeDescription
iduint256The ID of the processed withdrawal receipt.

WithdrawalReviewing

Emitted when a withdrawal receipt is marked as under review.

event WithdrawalReviewing(uint256 id);

Parameters

NameTypeDescription
iduint256The ID of the withdrawal receipt.

WithdrawalRejected

Emitted when a withdrawal request is rejected.

event WithdrawalRejected(uint256 id);

Parameters

NameTypeDescription
iduint256The ID of the rejected withdrawal receipt.

WithdrawalForfeited

Emitted when a withdrawal request is forfeited.

event WithdrawalForfeited(uint256 id);

Parameters

NameTypeDescription
iduint256The ID of the forfeited withdrawal receipt.

WithdrawalAssetAdded

Emitted when a new withdrawal asset is added.

event WithdrawalAssetAdded(address indexed asset);

Parameters

NameTypeDescription
assetaddressThe address of the newly added ERC20 asset.

WithdrawalAssetRemoved

Emitted when a withdrawal asset is removed.

event WithdrawalAssetRemoved(address indexed asset);

Parameters

NameTypeDescription
assetaddressThe address of the removed ERC20 asset.

SetAssetsRouter

Emitted when the AssetsRouter address is updated.

event SetAssetsRouter(address oldRouter, address newRouter);

Parameters

NameTypeDescription
oldRouteraddressThe previous router address.
newRouteraddressThe new router address.

AssetRepaid

Emitted when an operator repays assets into the controller.

event AssetRepaid(address indexed asset, uint256 amount);

Parameters

NameTypeDescription
assetaddressThe ERC20 asset repaid.
amountuint256The amount of asset repaid.

Structs

WithdrawalReceipt

Record of a single withdrawal request.

Used to track user withdrawals, pricing context, fees, and status.

struct WithdrawalReceipt {
    address requester;
    address requestAsset;
    uint256 requestShares;
    uint256 shareTokenPrice;
    uint256 requestAssetPrice;
    uint256 feeRate;
    WITHDRAWAL_STATUS status;
}

Enums

WITHDRAWAL_STATUS

Lifecycle statuses of a withdrawal request.

Used in {WithdrawalReceipt.status} to track progress and outcomes.

enum WITHDRAWAL_STATUS {
    REQUESTED,
    CANCELLED,
    PROCESSING,
    REVIEWING,
    PROCESSED,
    COMPLETED,
    REJECTED,
    FORFEITED
}

Contents

Errors

Git Source

Author: luoyhang003

Centralized custom errors for all contracts in the protocol.

Each error saves gas compared to revert strings. The @dev comment also includes the corresponding 4-byte selector for debugging and off-chain tooling.

Errors

InvalidArrayLength

Thrown when array lengths do not match or are zero.

Selector: 0x9d89020a

error InvalidArrayLength();

ZeroAddress

Thrown when a provided address is zero.

Selector: 0xd92e233d

error ZeroAddress();

ZeroAmount

Thrown when a provided amount is zero.

Selector: 0x1f2a2005

error ZeroAmount();

IndexOutOfBounds

Thrown when an index is out of bounds.

Selector: 0x4e23d035

error IndexOutOfBounds();

UserNotWhitelisted

Thrown when a user is not whitelisted but tries to interact.

Selector: 0x2ba75b25

error UserNotWhitelisted();

InvalidDecimals

Thrown when a token has invalid decimals (e.g., >18).

Selector: 0xd25598a0

error InvalidDecimals();

UnsupportedAsset

Thrown when an asset is not supported.

Selector: 0x24a01144

error UnsupportedAsset();

AssetAlreadyAdded

Thrown when trying to add an already added asset.

Selector: 0x5ed26801

error AssetAlreadyAdded();

AssetAlreadyRemoved

Thrown when trying to remove an asset that was already removed.

Selector: 0x422afd8f

error AssetAlreadyRemoved();

TransferBlacklisted

Thrown when transfer is attempted by/for a blacklisted address.

Selector: 0x6554e8c5

error TransferBlacklisted();

DepositPaused

Thrown when deposits are paused.

Selector: 0x35edea30

error DepositPaused();

ExceedTokenDepositCap

Thrown when a deposit exceeds per-token deposit cap.

Selector: 0xcc60dc5b

error ExceedTokenDepositCap();

ExceedTotalDepositCap

Thrown when a deposit exceeds global deposit cap.

Selector: 0x5054f250

error ExceedTotalDepositCap();

MintZeroShare

Thrown when minting results in zero shares.

Selector: 0x1d31001e

error MintZeroShare();

DepositZeroAsset

Thrown when attempting to deposit zero assets.

Selector: 0xd69b89cc

error DepositZeroAsset();

InvalidOracle

Thrown when the oracle for an asset is invalid or missing.

Selector: 0x9589a27d

error InvalidOracle();

WithdrawPaused

Thrown when withdrawals are paused.

Selector: 0x8c3e1d33

error WithdrawPaused();

RequestZeroShare

Thrown when attempting to request withdrawal of zero shares.

Selector: 0x02db00e0

error RequestZeroShare();

InvalidReceiptStatus

Thrown when a withdrawal receipt has invalid status for the operation.

Selector: 0x9a3a286f

error InvalidReceiptStatus();

NotRequester

Thrown when a caller is not the original withdrawal requester.

Selector: 0x0e020b04

error NotRequester();

RecipientAlreadyAdded

Thrown when a recipient is already added.

Selector: 0x7f2a2d20

error RecipientAlreadyAdded();

RecipientAlreadyRemoved

Thrown when a recipient is already removed.

Selector: 0x7d78b4a2

error RecipientAlreadyRemoved();

InvalidRouteEnabledStatus

Thrown when attempting to set auto-route to its current state.

Selector: 0x618af2bf

error InvalidRouteEnabledStatus();

NotRouterRecipient

Thrown when a non-registered recipient is used.

Selector: 0xc31e8ebe

error NotRouterRecipient();

RemoveActiveRouter

Thrown when attempting to remove the currently active recipient.

Selector: 0x1d3ba5c9

error RemoveActiveRouter();

AutoRouteEnabled

Thrown when attempting to manual route the asstes when auto route is enabled.

Selector: 0x92d56bf7

error AutoRouteEnabled();

AlreadyBlacklisted

Thrown when trying to blacklist an already blacklisted user.

Selector: 0xf53de75f

error AlreadyBlacklisted();

AlreadyWhitelisted

Thrown when trying to whitelist an already whitelisted user.

Selector: 0xb73e95e1

error AlreadyWhitelisted();

OracleAlreadyAdded

Thrown when an oracle is already registered for an asset.

Selector: 0x652a449e

error OracleAlreadyAdded();

OracleNotExist

Thrown when an oracle does not exist for an asset.

Selector: 0x4dca4f7d

error OracleNotExist();

ExceedMaxDeviation

Thrown when price deviation exceeds maximum allowed.

Selector: 0x8774ad87

error ExceedMaxDeviation();

PriceUpdateTooFrequent

Thrown when price updates are attempted too frequently.

Selector: 0x8f46908a

error PriceUpdateTooFrequent();

PriceValidityExpired

Thrown when a price validity period has expired.

Selector: 0x7c9d063a

error PriceValidityExpired();

ExceedMaxDeviationBps

Thrown when tolerance basis points exceed maximum deviation.

Selector: 0xb8d855e2

error ExceedMaxDeviationBps();

InvalidPriceUpdateInterval

Thrown when price update interval is invalid.

Selector: 0xfff67f52

error InvalidPriceUpdateInterval();

PriceMaxValidityExceeded

Thrown when price validity duration exceeds allowed maximum.

Selector: 0x6eca7e24

error PriceMaxValidityExceeded();

ExceedMaxMintFeeRate

Thrown when mint fee rate exceeds maximum allowed.

Selector: 0x8f59faf8

error ExceedMaxMintFeeRate();

ExceedMaxRedeemFeeRate

Thrown when redeem fee rate exceeds maximum allowed.

Selector: 0x86871089

error ExceedMaxRedeemFeeRate();

InvalidPrice

Thrown when a reported price is invalid.

Selector: 0x00bfc921

error InvalidPrice();

StalePrice

Thrown when a reported price is stale.

Selector: 0x19abf40e

error StalePrice();

IncompleteRound

Thrown when a Chainlink round is incomplete.

Selector: 0x8ad52bdd

error IncompleteRound();

Contents

ChainlinkOracleFeed

Git Source

Inherits: OracleFeed

Author: luoyhang003

Oracle adapter that integrates with Chainlink price feeds.

Inherits from the abstract OracleFeed contract and implements the peek function by querying a Chainlink AggregatorV3Interface.

State Variables

priceFeed

Chainlink price feed contract (AggregatorV3Interface).

Immutable after deployment to ensure oracle integrity.

AggregatorV3Interface public immutable priceFeed;

Functions

constructor

Deploys the Chainlink oracle feed wrapper.

constructor(address _token, string memory _name, address _priceFeed) OracleFeed(_token, _name);

Parameters

NameTypeDescription
_tokenaddressThe address of the token this oracle is associated with.
_namestringA human-readable name for this oracle feed.
_priceFeedaddressThe address of the Chainlink AggregatorV3 price feed.

peek

Returns the latest price from the Chainlink feed, normalized to 18 decimals.

*Performs several safety checks:

  • Ensures the returned price is positive.
  • Ensures the round is not stale.
  • Ensures the round data is complete and not from the future.
  • Adjusts decimals from the Chainlink feed to a standard 18-decimal format.*
function peek() external view override returns (uint256 price_);

Returns

NameTypeDescription
price_uint256The latest valid price, scaled to 18 decimals.

OracleFeed

Git Source

Author: luoyhang003

Abstract contract for oracle price feeds. Provides a standard interface for retrieving asset prices.

This contract is meant to be inherited by specific oracle implementations that define the logic for fetching asset prices.

State Variables

token

The token address associated with this oracle feed.

Immutable after deployment to ensure the oracle is tied to a specific token.

address public immutable token;

name

The human-readable name of the oracle feed.

Can be used for UI or off-chain identification purposes.

string public name;

Functions

constructor

Sets the token address and feed name during deployment.

constructor(address _token, string memory _name);

Parameters

NameTypeDescription
_tokenaddressThe address of the token this oracle is associated with.
_namestringThe descriptive name for this oracle feed.

peek

Returns the current price of the specified asset.

Implementations must override this function to provide actual price logic.

function peek() external view virtual returns (uint256 price_);

Returns

NameTypeDescription
price_uint256The price of the asset with 18 decimals of precision.

OracleRegistry

Git Source

Inherits: AccessControl, Constants, IOracleRegistry

Author: luoyhang003

Manages prices for vaultToken and other registered tokens, including updates from oracles and cut-off prices.

Uses OpenZeppelin AccessControl for role-based permissioning

Stores historical prices and supports both common and cut-off price updates

Performs deviation checks to prevent extreme price manipulations

State Variables

PRICE_UPDATE_ROLE

Role allowed to update prices

Only addresses with this role can call updatePrices

Calculated as keccak256("PRICE_UPDATE_ROLE").

bytes32 public constant PRICE_UPDATE_ROLE = keccak256("PRICE_UPDATE_ROLE");

ORACLE_MANAGE_ROLE

Role allowed to manage oracles

Only addresses with this role can call addTokenOracle, removeTokenOracle, updateTokenOracle

Calculated as keccak256("ORACLE_MANAGE_ROLE").

bytes32 public constant ORACLE_MANAGE_ROLE = keccak256("ORACLE_MANAGE_ROLE");

paramRegister

Parameter registry contract

Used to fetch tolerances, price update intervals, and validity durations

IParamRegistry public paramRegister;

vaultToken

Vault token address

Core token whose price is specially managed and checked against exchange rate tolerances

address public immutable vaultToken;

tokens

List of all registered tokens

Used for iteration during price updates and retrieving historical prices

address[] public tokens;

commonPriceUpdatedAt

Timestamps of common price updates

Index corresponds to historical versions of price updates

uint256[] public commonPriceUpdatedAt;

cutOffPriceUpdateAt

Timestamps of cut-off price updates

Only updated when _isCutOffPrice is true during updatePrices

uint256[] public cutOffPriceUpdateAt;

prices

Token => Timestamp => Price mapping

Stores all historical prices for each token

mapping(address => mapping(uint256 => uint256)) public prices;

_oracles

Token => OracleFeed mapping

Internal mapping to track which oracle feed is used for each token

mapping(address => IOracleFeed) private _oracles;

Functions

constructor

Initializes OracleRegistry

Performs zero-address checks and ensures token/oracle arrays have the same length

Initializes initial prices and emits PriceUpdated events

constructor(
    address _vaultToken,
    address[] memory _tokens,
    address[] memory _oracleFeeds,
    address _paramRegister,
    address _defaultAdmin,
    address _priceUpdateRole,
    address _oracleManageRole
);

Parameters

NameTypeDescription
_vaultTokenaddressCore vault token
_tokensaddress[]Tokens to register initially
_oracleFeedsaddress[]Corresponding oracle feeds
_paramRegisteraddressParameter registry contract
_defaultAdminaddressAdmin address for DEFAULT_ADMIN_ROLE
_priceUpdateRoleaddressAddress granted the PRICE_UPDATE_ROLE.
_oracleManageRoleaddressAddress granted the ORACLE_MANAGE_ROLE.

updatePrices

Updates prices for vault token and other registered tokens

Reverts if price deviates beyond tolerances or updates are too frequent

Updates all registered tokens based on their oracle feeds

function updatePrices(uint256 _vaultTokenPrice, bool _isCutOffPrice) external onlyRole(PRICE_UPDATE_ROLE);

Parameters

NameTypeDescription
_vaultTokenPriceuint256New vault token price
_isCutOffPriceboolWhether the update is a cut-off price

addTokenOracle

Adds a new token and its oracle feed

Only callable by ORACLE_MANAGE_ROLE

Reverts if token already exists or any address is zero

function addTokenOracle(address _token, address _oracle) external onlyRole(ORACLE_MANAGE_ROLE);

Parameters

NameTypeDescription
_tokenaddressToken address
_oracleaddressOracle feed address

removeTokenOracle

Removes a token and its oracle feed

Uses swap-and-pop for efficient removal from array

Only callable by ORACLE_MANAGE_ROLE

function removeTokenOracle(address _token) external onlyRole(ORACLE_MANAGE_ROLE);

Parameters

NameTypeDescription
_tokenaddressToken address to remove

updateTokenOracle

Updates an existing token’s oracle feed

Only callable by ORACLE_MANAGE_ROLE

Reverts if token does not exist or any address is zero

function updateTokenOracle(address _token, address _oracle) external onlyRole(ORACLE_MANAGE_ROLE);

Parameters

NameTypeDescription
_tokenaddressToken address
_oracleaddressNew oracle feed address

getOracle

Returns the oracle feed address for a given token

Returns zero address if token is not registered

function getOracle(address _token) external view returns (address oracle_);

Parameters

NameTypeDescription
_tokenaddressToken address to query

Returns

NameTypeDescription
oracle_addressAddress of the oracle feed

getTokens

Returns all registered token addresses

Useful for iterating over all tokens to fetch historical prices

function getTokens() external view returns (address[] memory tokens_);

Returns

NameTypeDescription
tokens_address[]Array of token addresses

latestPricesUpdatedAt

Returns the timestamp of the latest common price update

Reverts if no updates exist

function latestPricesUpdatedAt() public view returns (uint256 timestamp_);

Returns

NameTypeDescription
timestamp_uint256Timestamp of latest update

latestCutOffPriceUpdatedAt

Returns the timestamp of the latest cut-off price update

Reverts if no cut-off updates exist

function latestCutOffPriceUpdatedAt() external view returns (uint256 timestamp_);

Returns

NameTypeDescription
timestamp_uint256Timestamp of latest cut-off update

peek

Returns the latest price of a token from its oracle

Performs deviation check to prevent extreme values

function peek(address _token) public view returns (uint256 price_);

Parameters

NameTypeDescription
_tokenaddressToken address

Returns

NameTypeDescription
price_uint256Latest price from oracle

peekAt

Returns historical price for a token at a given index

Checks price validity (time not expired)

function peekAt(address _token, uint256 _index) public view returns (uint256 price_);

Parameters

NameTypeDescription
_tokenaddressToken address
_indexuint256Index (0 = latest)

Returns

NameTypeDescription
price_uint256Historical price

onlyPeekAt

Returns historical price without validity check

Useful for auditing or internal calculations

function onlyPeekAt(address _token, uint256 _index) public view returns (uint256 price_);

Parameters

NameTypeDescription
_tokenaddressToken address
_indexuint256Index (0 = latest)

Returns

NameTypeDescription
price_uint256Historical price

getVaultTokenPrice

Returns the historical price of the vault token at a given index

Checks price validity

function getVaultTokenPrice(uint256 _index) public view returns (uint256 price_);

Parameters

NameTypeDescription
_indexuint256Index (0 = latest)

Returns

NameTypeDescription
price_uint256Vault token price

onlyGetVaultTokenPrice

Returns the historical price of the vault token without validity check

Useful for internal calculations

function onlyGetVaultTokenPrice(uint256 _index) public view returns (uint256 price_);

Parameters

NameTypeDescription
_indexuint256Index (0 = latest)

Returns

NameTypeDescription
price_uint256Vault token price

getCutOffPrice

Returns token price at a cut-off update

Reverts if price is expired or index out of bounds

function getCutOffPrice(address _token, uint256 _index) external view returns (uint256 price_);

Parameters

NameTypeDescription
_tokenaddressToken address
_indexuint256Index of cut-off update (0 = latest)

Returns

NameTypeDescription
price_uint256The cut-off price for the token

getCutOffPrices

Returns token addresses and prices at a cut-off update

Reverts if price is expired or index out of bounds

function getCutOffPrices(uint256 _index) external view returns (address[] memory tokens_, uint256[] memory prices_);

Parameters

NameTypeDescription
_indexuint256Index of cut-off update (0 = latest)

Returns

NameTypeDescription
tokens_address[]Array of token addresses
prices_uint256[]Array of prices for each token

onlyGetCutOffPrices

Same as getCutOffPrices but does not check validity

Useful for internal auditing or calculation

function onlyGetCutOffPrices(uint256 _index)
    external
    view
    returns (address[] memory tokens_, uint256[] memory prices_);

Parameters

NameTypeDescription
_indexuint256Index of cut-off update (0 = latest)

Returns

NameTypeDescription
tokens_address[]Array of token addresses
prices_uint256[]Array of prices for each token

getVaultTokenCutOffPrice

Returns the vault token cut-off price at a given index

Checks validity

function getVaultTokenCutOffPrice(uint256 _index) external view returns (uint256 price_);

Parameters

NameTypeDescription
_indexuint256Index of cut-off update (0 = latest)

Returns

NameTypeDescription
price_uint256Vault token price

onlyGetVaultTokenCutOffPrice

Returns the vault token cut-off price without validity check

Useful for internal calculations

function onlyGetVaultTokenCutOffPrice(uint256 _index) external view returns (uint256 price_);

Parameters

NameTypeDescription
_indexuint256Index of cut-off update (0 = latest)

Returns

NameTypeDescription
price_uint256Vault token price

_getPrice

Retrieves the historical price of a token at a given index

  • Uses commonPriceUpdatedAt array to find the timestamp of the requested price.
  • If _checkValidity is true, reverts if the price is older than paramRegister.getPriceValidityDuration().
  • Reverts if _index is out of bounds.
  • Returns the stored price from prices[token][updatedAt].*
function _getPrice(address _token, uint256 _index, bool _checkValidity) internal view returns (uint256);

Parameters

NameTypeDescription
_tokenaddressToken address to query
_indexuint256Index of the historical price (0 = latest)
_checkValidityboolWhether to check if the price is still valid

Returns

NameTypeDescription
<none>uint256price_ Price of the token at the given index

Contents

NoDeplayTimelockController

Git Source

Inherits: TimelockController

Author: luoyhang003

A specialized TimelockController with zero delay for operations

This contract extends OpenZeppelin's TimelockController and sets the execution delay to 0, allowing immediate execution of scheduled operations.

Functions

constructor

Deploys the NoDelayTimelockController

Calls the parent TimelockController constructor with delay = 0

constructor(address[] memory proposers, address[] memory executors, address admin)
    TimelockController(0, proposers, executors, admin);

Parameters

NameTypeDescription
proposersaddress[]The list of addresses allowed to propose operations
executorsaddress[]The list of addresses allowed to execute operations
adminaddressThe account that will be granted the DEFAULT_ADMIN_ROLE

OneDayDelayTimelockController

Git Source

Inherits: TimelockController

Author: luoyhang003

A TimelockController with a 1-day delay for executing operations

This contract extends OpenZeppelin's TimelockController and sets the execution delay to 1 day. Proposals must wait 1 day before they can be executed.

Functions

constructor

Deploys the OneDayDelayTimelockController

Calls the parent TimelockController constructor with delay = 1 days

constructor(address[] memory proposers, address[] memory executors, address admin)
    TimelockController(1 days, proposers, executors, admin);

Parameters

NameTypeDescription
proposersaddress[]The list of addresses allowed to propose operations
executorsaddress[]The list of addresses allowed to execute operations
adminaddressThe account that will be granted the DEFAULT_ADMIN_ROLE

ThreeDaysDelayTimelockController

Git Source

Inherits: TimelockController

Author: luoyhang003

A TimelockController with a 3-days delay for executing operations

This contract extends OpenZeppelin's TimelockController and sets the execution delay to 3 days. Proposals must wait 3 days before they can be executed.

Functions

constructor

Deploys the OneDayDelayTimelockController

Calls the parent TimelockController constructor with delay = 1 days

constructor(address[] memory proposers, address[] memory executors, address admin)
    TimelockController(3 days, proposers, executors, admin);

Parameters

NameTypeDescription
proposersaddress[]The list of addresses allowed to propose operations
executorsaddress[]The list of addresses allowed to execute operations
adminaddressThe account that will be granted the DEFAULT_ADMIN_ROLE

AccessRegistry

Git Source

Inherits: IAccessRegistry, AccessControl

Author: luoyhang003

Manages whitelist and blacklist for protocol access control.

Uses OpenZeppelin AccessControl for role-based permissions.

State Variables

OPERATOR_ROLE

Role identifier for operator accounts.

Calculated as keccak256("OPERATOR_ROLE").

bytes32 public constant OPERATOR_ROLE = keccak256("OPERATOR_ROLE");

_whitelist

Whitelist mapping to track approved users.

Address => true if whitelisted, false otherwise.

mapping(address => bool) private _whitelist;

_blacklist

Blacklist mapping to track blocked users.

Address => true if blacklisted, false otherwise.

mapping(address => bool) private _blacklist;

Functions

constructor

Deploys the contract and assigns initial admin and operator roles.

constructor(address _admin, address _operator);

Parameters

NameTypeDescription
_adminaddressAddress to receive the DEFAULT_ADMIN_ROLE.
_operatoraddressAddress to receive the OPERATOR_ROLE.

isWhitelisted

Checks whether a given address is whitelisted

function isWhitelisted(address _account) external view returns (bool);

Parameters

NameTypeDescription
_accountaddressThe address to check

Returns

NameTypeDescription
<none>boolTrue if the address is whitelisted, false otherwise

isBlacklisted

Checks whether a given address is blacklisted

function isBlacklisted(address _account) external view returns (bool);

Parameters

NameTypeDescription
_accountaddressThe address to check

Returns

NameTypeDescription
<none>boolTrue if the address is blacklisted, false otherwise

addWhitelist

Add multiple users to the whitelist.

Only callable by accounts with OPERATOR_ROLE.

function addWhitelist(address[] memory _users) external onlyRole(OPERATOR_ROLE);

Parameters

NameTypeDescription
_usersaddress[]Array of addresses to be whitelisted.

removeWhitelist

Remove multiple users from the whitelist.

Only callable by accounts with OPERATOR_ROLE.

function removeWhitelist(address[] memory _users) external onlyRole(OPERATOR_ROLE);

Parameters

NameTypeDescription
_usersaddress[]Array of addresses to be removed from whitelist.

addBlacklist

Add multiple users to the blacklist.

Only callable by accounts with OPERATOR_ROLE.

function addBlacklist(address[] memory _users) external onlyRole(OPERATOR_ROLE);

Parameters

NameTypeDescription
_usersaddress[]Array of addresses to be blacklisted.

removeBlacklist

Remove multiple users from the blacklist.

Only callable by accounts with OPERATOR_ROLE.

function removeBlacklist(address[] memory _users) external onlyRole(OPERATOR_ROLE);

Parameters

NameTypeDescription
_usersaddress[]Array of addresses to be removed from blacklist.

AssetsRouter

Git Source

Inherits: IAssetsRouter, AccessControl

Author: luoyhang003

Routes incoming ERC20 token transfers to a designated recipient address.

*Supports both automatic routing to the active recipient or manual routing by operators. Access is controlled via roles:

  • DEFAULT_ADMIN_ROLE: manages role assignments
  • ROUTER_ADMIN_ROLE: can add/remove route recipients
  • ROUTER_OPERATOR_ROLE: can change active recipient, enable/disable auto-route, or manually route assets*

State Variables

ROUTER_ADMIN_ROLE

Role identifier for router admins (manage recipients list).

Only addresses with this role can call addRouteRecipient and removeRouteRecipient

Calculated as keccak256("ROUTER_ADMIN_ROLE").

bytes32 public constant ROUTER_ADMIN_ROLE = keccak256("ROUTER_ADMIN_ROLE");

ROUTER_OPERATOR_ROLE

Role identifier for router operators (manage routing settings).

Only addresses with this role can call setActiveRecipient, setAutoRouteEnabled and manualRoute

Calculated as keccak256("ROUTER_OPERATOR_ROLE").

bytes32 public constant ROUTER_OPERATOR_ROLE = keccak256("ROUTER_OPERATOR_ROLE");

_routeRecipients

List of approved route recipients.

address[] private _routeRecipients;

_isRouteRecipient

Mapping for quick lookup of approved recipients.

mapping(address => bool) private _isRouteRecipient;

_activeRecipient

The currently active recipient address where tokens are routed automatically.

address private _activeRecipient;

_isAutoRouteEnabled

Flag indicating whether automatic routing is enabled.

bool private _isAutoRouteEnabled;

Functions

constructor

Deploys the AssetsRouter contract.

constructor(
    address _defaultAdmin,
    address _adminRole,
    address _operatorRole,
    address[] memory _recipients,
    address _active
);

Parameters

NameTypeDescription
_defaultAdminaddressAddress assigned as DEFAULT_ADMIN_ROLE.
_adminRoleaddressAddress granted the ROUTER_ADMIN_ROLE.
_operatorRoleaddressAddress granted the ROUTER_OPERATOR_ROLE.
_recipientsaddress[]Initial list of valid route recipients.
_activeaddressThe active recipient address for auto-routing.

route

Deposit tokens into the router and optionally forward them to the active recipient.

Pulls tokens from msg.sender into this contract. If auto-route is enabled, immediately forwards them to _activeRecipient.

function route(address _token, uint256 _amount) external;

Parameters

NameTypeDescription
_tokenaddressThe ERC20 token address being routed.
_amountuint256The amount of tokens to transfer.

getRouteRecipients

Returns the list of approved route recipients.

Returns the full list of route recipients currently registered in the router.

function getRouteRecipients() external view returns (address[] memory routeRecipients_);

Returns

NameTypeDescription
routeRecipients_address[]The array of all registered recipient addresses.

isRouteRecipient

Checks if an address is a valid route recipient.

Checks if a given address is a registered route recipient.

function isRouteRecipient(address _addr) external view returns (bool);

Parameters

NameTypeDescription
_addraddressThe address to check.

Returns

NameTypeDescription
<none>boolTrue if the address is a valid route recipient, otherwise false.

getActiveRecipient

Returns the currently active route recipient.

Returns the currently active route recipient where assets are routed automatically.

function getActiveRecipient() external view returns (address activeRecipient_);

Returns

NameTypeDescription
activeRecipient_addressThe address of the active route recipient.

isAutoRouteEnabled

Returns whether auto-routing is enabled.

Indicates whether automatic routing is currently enabled.

function isAutoRouteEnabled() external view returns (bool enabled_);

Returns

NameTypeDescription
enabled_boolBoolean flag, true if auto-routing is enabled, false otherwise.

addRouteRecipient

Add a new valid route recipient.

Callable only by ROUTER_ADMIN_ROLE.

function addRouteRecipient(address _recipient) external onlyRole(ROUTER_ADMIN_ROLE);

Parameters

NameTypeDescription
_recipientaddressThe address to add as a route recipient.

removeRouteRecipient

Remove an existing route recipient.

Cannot remove the currently active recipient.

function removeRouteRecipient(address _recipient) external onlyRole(ROUTER_ADMIN_ROLE);

Parameters

NameTypeDescription
_recipientaddressThe address to remove from the recipients list.

setActiveRecipient

Set the active recipient for auto-routing.

Callable only by ROUTER_OPERATOR_ROLE.

function setActiveRecipient(address _active) external onlyRole(ROUTER_OPERATOR_ROLE);

Parameters

NameTypeDescription
_activeaddressThe address to set as the active recipient.

setAutoRouteEnabled

Enable or disable automatic routing.

Callable only by ROUTER_OPERATOR_ROLE.

function setAutoRouteEnabled(bool _enabled) external onlyRole(ROUTER_OPERATOR_ROLE);

Parameters

NameTypeDescription
_enabledboolBoolean flag to set auto-routing state.

manualRoute

Manually route tokens to a specified recipient.

Callable only by ROUTER_OPERATOR_ROLE.

function manualRoute(address _token, address _recipient, uint256 _amount) external onlyRole(ROUTER_OPERATOR_ROLE);

Parameters

NameTypeDescription
_tokenaddressThe ERC20 token address to route.
_recipientaddressThe destination recipient address.
_amountuint256The amount of tokens to transfer.

DepositVault

Git Source

Inherits: IDepositVault, AccessControl, ReentrancyGuard, Constants

Author: luoyhang003

This contract manages deposits of underlying assets in exchange for vault tokens.

It mints vault tokens to whitelisted users based on the asset’s oracle price and applies fees and caps. Supports deposit/mint functions, preview simulations, and admin control over assets.

State Variables

VAULT_ADMIN_ROLE

Role allowed to set new AssetsRouter

Only addresses with this role can call setAssetsRouter

Calculated as keccak256("VAULT_ADMIN_ROLE").

bytes32 public constant VAULT_ADMIN_ROLE = keccak256("VAULT_ADMIN_ROLE");

VAULT_OPERATOR_ROLE

Role allowed to manage underlying assets

Only addresses with this role can call addUnderlyingAsset and removeUnderlyingAsset

Calculated as keccak256("VAULT_OPERATOR_ROLE").

bytes32 public constant VAULT_OPERATOR_ROLE = keccak256("VAULT_OPERATOR_ROLE");

vaultToken

ERC20 vault token.

Minted when users deposit assets or mint shares.

Token public immutable vaultToken;

accessRegistry

Access registry for fetching whitelist and blacklist.

IAccessRegistry public accessRegistry;

oracleRegistry

Oracle registry for fetching asset and vault token prices.

IOracleRegistry public oracleRegistry;

paramRegistry

Parameter registry for fee rates, deposit caps, etc.

IParamRegistry public paramRegistry;

assetsRouter

Router to forward deposited assets into underlying strategies.

IAssetsRouter public assetsRouter;

underlyingAssets

List of all supported underlying assets.

address[] public underlyingAssets;

isUnderlyingAsset

Mapping of supported assets.

mapping(address => bool) public isUnderlyingAsset;

tokenDecimals

Cached decimals for supported tokens.

mapping(address => uint8) public tokenDecimals;

tokenDeposited

Tracks deposited amount per underlying asset (net of fees).

mapping(address => uint256) public tokenDeposited;

Functions

constructor

Deploys the DepositVault contract.

Ensures addresses are valid and assets have valid oracles/decimals. Grants infinite approval of assets to the router.

constructor(
    address _defaultAdmin,
    address _adminRole,
    address _operatorRole,
    address _vaultToken,
    address _accessRegistry,
    address _oracleRegistry,
    address _paramRegistry,
    address _assetsRouter,
    address[] memory _underlyingAssets
);

Parameters

NameTypeDescription
_defaultAdminaddressAddress to receive the DEFAULT_ADMIN_ROLE.
_adminRoleaddressAddress granted the VAULT_ADMIN_ROLE.
_operatorRoleaddressAddress granted the VAULT_OPERATOR_ROLE.
_vaultTokenaddressAddress of the vault token contract.
_accessRegistryaddressAddress of the access registry contract.
_oracleRegistryaddressAddress of the oracle registry contract.
_paramRegistryaddressAddress of the parameter registry contract.
_assetsRouteraddressAddress of the assets router contract.
_underlyingAssetsaddress[]Initial list of supported assets.

deposit

Deposit an underlying asset and receive vault shares.

Equivalent to depositFor with msg.sender as receiver.

function deposit(address _asset, uint256 _amount) external returns (uint256 shares_);

Parameters

NameTypeDescription
_assetaddressAddress of the asset to deposit.
_amountuint256Amount of asset to deposit.

Returns

NameTypeDescription
shares_uint256Number of shares minted.

depositFor

Deposit an underlying asset on behalf of another account.

Reverts if receiver is zero address.

function depositFor(address _asset, uint256 _amount, address _receiver) external returns (uint256 shares_);

Parameters

NameTypeDescription
_assetaddressAddress of the asset to deposit.
_amountuint256Amount of asset to deposit.
_receiveraddressRecipient of the minted shares.

Returns

NameTypeDescription
shares_uint256Number of shares minted.

mint

Mint a specific number of shares by depositing assets.

Equivalent to mintFor with msg.sender as receiver.

function mint(address _asset, uint256 _shares) external returns (uint256 assets_);

Parameters

NameTypeDescription
_assetaddressAddress of the asset to deposit.
_sharesuint256Number of shares to mint.

Returns

NameTypeDescription
assets_uint256Amount of assets required.

mintFor

Mint a specific number of shares on behalf of another account.

Reverts if receiver is zero address.

function mintFor(address _asset, uint256 _shares, address _receiver) external returns (uint256 assets_);

Parameters

NameTypeDescription
_assetaddressAddress of the asset to deposit.
_sharesuint256Number of shares to mint.
_receiveraddressRecipient of the minted shares.

Returns

NameTypeDescription
assets_uint256Amount of assets required.

exchangePrice

Returns the cutoff vault token price (e.g. for settlement).

Fetches the cutoff price directly from the oracle registry.

function exchangePrice() external view returns (uint256 price_);

Returns

NameTypeDescription
price_uint256Current vault token cutoff price.

convertToShares

Converts underlying assets to equivalent vault shares.

Normalizes _amount to 18 decimals before conversion. Uses floor rounding to avoid overestimating shares.

function convertToShares(address _asset, uint256 _amount)
    public
    view
    returns (uint256 shares_, uint256 underlyingPrice_, uint256 vaultTokenPrice_);

Parameters

NameTypeDescription
_assetaddressAddress of the underlying asset.
_amountuint256Amount of underlying asset.

Returns

NameTypeDescription
shares_uint256Equivalent vault shares.
underlyingPrice_uint256Price of the underlying asset.
vaultTokenPrice_uint256Price of the vault token.

convertToAssets

Converts vault shares to equivalent underlying assets.

Denormalizes values back from 18 decimals to asset decimals. Uses floor rounding to avoid overestimating asset returns.

function convertToAssets(address _asset, uint256 _shares)
    public
    view
    returns (uint256 assets_, uint256 underlyingPrice_, uint256 vaultTokenPrice_);

Parameters

NameTypeDescription
_assetaddressAddress of the underlying asset.
_sharesuint256Number of vault shares.

Returns

NameTypeDescription
assets_uint256Equivalent underlying asset amount.
underlyingPrice_uint256Price of the underlying asset.
vaultTokenPrice_uint256Price of the vault token.

previewDeposit

Previews deposit outcome including shares, fee, and prices.

Simulates deposit logic without state changes. Performs fee deduction, cap checks, and price fetches.

function previewDeposit(address _asset, uint256 _amount)
    public
    view
    returns (uint256 shares_, uint256 fee_, uint256 underlyingPrice_, uint256 vaultTokenPrice_);

Parameters

NameTypeDescription
_assetaddressAddress of the underlying asset.
_amountuint256Deposit amount.

Returns

NameTypeDescription
shares_uint256Number of shares minted.
fee_uint256Fee charged on deposit.
underlyingPrice_uint256Price of the underlying asset.
vaultTokenPrice_uint256Price of the vault token.

previewMint

Previews mint outcome including assets, fee, and prices.

Simulates mint logic without state changes. Performs fee addition, cap checks, and price fetches.

function previewMint(address _asset, uint256 _shares)
    public
    view
    returns (uint256 assets_, uint256 fee_, uint256 underlyingPrice_, uint256 vaultTokenPrice_);

Parameters

NameTypeDescription
_assetaddressAddress of the underlying asset.
_sharesuint256Number of shares to mint.

Returns

NameTypeDescription
assets_uint256Required underlying assets.
fee_uint256Fee charged on mint.
underlyingPrice_uint256Price of the underlying asset.
vaultTokenPrice_uint256Price of the vault token.

getUnderlyings

Returns list of all supported underlying assets.

Returns storage array directly; use cautiously in gas-sensitive contexts.

function getUnderlyings() external view returns (address[] memory underlyings);

Returns

NameTypeDescription
underlyingsaddress[]Array of supported assets.

addUnderlyingAsset

Adds a new underlying asset to the vault.

Only callable by operator role. Requires valid oracle and decimals <= 18. Grants infinite approval to router.

function addUnderlyingAsset(address _asset) external onlyRole(VAULT_OPERATOR_ROLE);

Parameters

NameTypeDescription
_assetaddressAddress of the asset to add.

removeUnderlyingAsset

Removes an underlying asset from the vault.

Only callable by operator role. Resets approval to zero and updates storage.

function removeUnderlyingAsset(address _asset) external onlyRole(VAULT_OPERATOR_ROLE);

Parameters

NameTypeDescription
_assetaddressAddress of the asset to remove.

forceRouteAssets

Forcefully routes a specified amount of an asset through the assets router.

This function can only be called by an account with the {VAULT_OPERATOR_ROLE}. It is typically used in exceptional or administrative cases where assets must be manually routed to the designated destination, bypassing standard user-driven flows. Reverts if the asset address is zero or the amount is zero.

function forceRouteAssets(address _asset, uint256 _amount) external onlyRole(VAULT_OPERATOR_ROLE);

Parameters

NameTypeDescription
_assetaddressThe address of the underlying asset to be routed.
_amountuint256The amount of the underlying asset to be routed.

setAssetsRouter

Updates the asset router contract.

Only callable by admin role. Revokes approvals for old router and re-approves new one.

function setAssetsRouter(address _assetsRouter) external onlyRole(VAULT_ADMIN_ROLE);

Parameters

NameTypeDescription
_assetsRouteraddressNew router address.

_depositFor

Internal deposit logic used by deposit and depositFor.

Applies fee, checks caps, transfers funds, and mints shares.

function _depositFor(address _asset, uint256 _amount, address _receiver)
    internal
    nonReentrant
    returns (uint256 shares_);

Parameters

NameTypeDescription
_assetaddressAddress of asset to deposit.
_amountuint256Deposit amount.
_receiveraddressRecipient of vault shares.

Returns

NameTypeDescription
shares_uint256Number of shares minted.

_mintFor

Internal mint logic used by mint and mintFor.

Applies fee, checks caps, transfers funds, and mints shares.

function _mintFor(address _asset, uint256 _shares, address _receiver) internal nonReentrant returns (uint256 assets_);

Parameters

NameTypeDescription
_assetaddressAddress of asset to deposit.
_sharesuint256Number of shares to mint.
_receiveraddressRecipient of vault shares.

Returns

NameTypeDescription
assets_uint256Amount of assets transferred.

_normalize

Normalizes token amounts to base decimals (18).

Expands or compresses numbers depending on asset decimals.

function _normalize(uint256 _amount, uint256 _decimals) internal pure returns (uint256 normalized_);

Parameters

NameTypeDescription
_amountuint256Token amount in original decimals.
_decimalsuint256Decimals of the token.

Returns

NameTypeDescription
normalized_uint256Amount scaled to 18 decimals.

_denormalize

Denormalizes token amounts from base decimals (18) to asset decimals.

Reverses normalization logic.

function _denormalize(uint256 _amount, uint256 _decimals) internal pure returns (uint256 denormalized_);

Parameters

NameTypeDescription
_amountuint256Amount in 18 decimals.
_decimalsuint256Decimals of the asset.

Returns

NameTypeDescription
denormalized_uint256Amount scaled back to asset decimals.

ParamRegistry

Git Source

Inherits: IParamRegistry, AccessControl, Constants

Author: luoyhang003

Centralized registry for protocol parameters, including fee rates, deposit caps, tolerances, and operational flags.

Controlled via role-based access and timelocks (D0, D1, D3). Provides getter and setter functions for configuration parameters used across deposit, redemption, and pricing logic.

State Variables

D0_TIMELOCK_ROLE

Role controlling same-day (D0) parameter changes.

bytes32 public constant D0_TIMELOCK_ROLE = keccak256("D0_TIMELOCK_ROLE");

D1_TIMELOCK_ROLE

Role controlling 1-day delay (D1) parameter changes.

bytes32 public constant D1_TIMELOCK_ROLE = keccak256("D1_TIMELOCK_ROLE");

D3_TIMELOCK_ROLE

Role controlling 3-day delay (D3) parameter changes.

bytes32 public constant D3_TIMELOCK_ROLE = keccak256("D3_TIMELOCK_ROLE");

EXCHANGE_RATE_MAX_UPPER_DEVIATION_BPS

Maximum allowed upper deviation in exchange rate (bps).

uint256 public constant EXCHANGE_RATE_MAX_UPPER_DEVIATION_BPS = 200;

EXCHANGE_RATE_MAX_LOWER_DEVIATION_BPS

Maximum allowed lower deviation in exchange rate (bps).

uint256 public constant EXCHANGE_RATE_MAX_LOWER_DEVIATION_BPS = 200;

STABLECOIN_PRICE_MAX_DEVIATION_BPS

Maximum allowed deviation in stablecoin prices (bps).

uint256 public constant STABLECOIN_PRICE_MAX_DEVIATION_BPS = 500;

VOLATILE_ASSET_PRICE_MAX_DEVIATION_BPS

Maximum allowed deviation in volatile asset prices (bps).

uint256 public constant VOLATILE_ASSET_PRICE_MAX_DEVIATION_BPS = 5000;

PRICE_UPDATE_MIN_INTERVAL

Minimum interval allowed for price updates.

uint256 public constant PRICE_UPDATE_MIN_INTERVAL = 1 hours;

PRICE_MAX_VALIDITY_DURATION

Maximum validity period for price feeds.

uint256 public constant PRICE_MAX_VALIDITY_DURATION = 7 days;

MAX_MINT_FEE_RATE

Maximum allowed mint fee rate (bps).

uint256 public constant MAX_MINT_FEE_RATE = 100;

MAX_REDEEM_FEE_RATE

Maximum allowed redeem fee rate (bps).

uint256 public constant MAX_REDEEM_FEE_RATE = 100;

_exchangeRateMaxUpperToleranceBps

Current configured upper tolerance for exchange rate deviation.

uint256 private _exchangeRateMaxUpperToleranceBps = 100;

_exchangeRateMaxLowerToleranceBps

Current configured lower tolerance for exchange rate deviation.

uint256 private _exchangeRateMaxLowerToleranceBps = 50;

_stablecoinPriceToleranceBps

Current configured stablecoin price tolerance.

uint256 private _stablecoinPriceToleranceBps = 100;

_volatileAssetPriceToleranceBps

Current configured volatile asset price tolerance.

uint256 private _volatileAssetPriceToleranceBps = 500;

_priceUpdateInterval

Minimum interval between price updates.

uint256 private _priceUpdateInterval = 6 hours;

_price_validity_duration

Maximum validity period for cached price feeds.

uint256 private _price_validity_duration = 3 days;

_total_deposit_cap

Global cap on total deposits across all assets.

uint256 private _total_deposit_cap = type(uint256).max;

_fee_recipient

Address receiving collected fees.

address private _fee_recipient;

_forfeit_treasury

Address receiving forfeited assets (treasury).

address private _forfeit_treasury;

_mintFeeRate

Mapping of mint fee rates by asset.

mapping(address => uint256) private _mintFeeRate;

_redeemFeeRate

Mapping of redeem fee rates by asset.

mapping(address => uint256) private _redeemFeeRate;

_depositEnabled

Deposit enablement flags by asset.

mapping(address => bool) private _depositEnabled;

_redeemEnabled

Redeem enablement flags by asset.

mapping(address => bool) private _redeemEnabled;

_tokenDepositCap

Deposit caps for individual assets.

mapping(address => uint256) private _tokenDepositCap;

Functions

constructor

Deploys the ParamRegistry contract with initial roles and recipients.

Ensures none of the provided addresses are zero.

constructor(
    address _admin,
    address _d0Timelock,
    address _d1Timelock,
    address _d3Timelock,
    address _feeRecipient,
    address _forfeitTreasury
);

Parameters

NameTypeDescription
_adminaddressAddress to be assigned DEFAULT_ADMIN_ROLE.
_d0TimelockaddressAddress for D0 timelock role (immediate changes).
_d1TimelockaddressAddress for D1 timelock role (delayed changes).
_d3TimelockaddressAddress for D3 timelock role (longer delays).
_feeRecipientaddressAddress to receive protocol fees.
_forfeitTreasuryaddressAddress to receive forfeited assets.

getExchangeRateMaxUpperToleranceBps

Returns the current upper tolerance for exchange rate deviation.

function getExchangeRateMaxUpperToleranceBps() external view returns (uint256);

getExchangeRateMaxLowerToleranceBps

Returns the current lower tolerance for exchange rate deviation.

function getExchangeRateMaxLowerToleranceBps() external view returns (uint256);

getStablecoinPriceToleranceBps

Returns the current stablecoin price tolerance in bps.

function getStablecoinPriceToleranceBps() external view returns (uint256);

getVolatileAssetPriceToleranceBps

Returns the current volatile asset price tolerance in bps.

function getVolatileAssetPriceToleranceBps() external view returns (uint256);

getPriceUpdateInterval

Returns the minimum interval between price updates.

function getPriceUpdateInterval() external view returns (uint256);

getPriceValidityDuration

Returns the maximum validity duration of cached prices.

function getPriceValidityDuration() external view returns (uint256);

getMintFeeRate

Returns the configured mint fee rate for a given asset.

function getMintFeeRate(address _asset) external view returns (uint256);

Parameters

NameTypeDescription
_assetaddressThe address of the asset.

Returns

NameTypeDescription
<none>uint256The mint fee rate in basis points.

getRedeemFeeRate

Returns the configured redeem fee rate for a given asset.

function getRedeemFeeRate(address _asset) external view returns (uint256);

Parameters

NameTypeDescription
_assetaddressThe address of the asset.

Returns

NameTypeDescription
<none>uint256The redeem fee rate in basis points.

getDepositEnabled

Returns whether deposits are enabled for a given asset.

function getDepositEnabled(address _asset) external view returns (bool);

Parameters

NameTypeDescription
_assetaddressThe address of the asset.

Returns

NameTypeDescription
<none>boolTrue if deposits are enabled, false otherwise.

getRedeemEnabled

Returns whether redemptions are enabled for a given asset.

function getRedeemEnabled(address _asset) external view returns (bool);

Parameters

NameTypeDescription
_assetaddressThe address of the asset.

Returns

NameTypeDescription
<none>boolTrue if redemptions are enabled, false otherwise.

getTotalDepositCap

Returns the global deposit cap.

function getTotalDepositCap() external view returns (uint256);

getTokenDepositCap

Returns the deposit cap for a specific asset.

function getTokenDepositCap(address _asset) external view returns (uint256);

Parameters

NameTypeDescription
_assetaddressThe address of the asset.

getFeeRecipient

Returns the address of the fee recipient.

function getFeeRecipient() external view returns (address);

getForfeitTreasury

Returns the address of the forfeited assets treasury.

function getForfeitTreasury() external view returns (address);

setExchangeRateMaxUpperToleranceBps

Updates the maximum upper tolerance for exchange rate deviation.

Only callable by {D0_TIMELOCK_ROLE}.

function setExchangeRateMaxUpperToleranceBps(uint256 _bps) external onlyRole(D0_TIMELOCK_ROLE);

Parameters

NameTypeDescription
_bpsuint256New tolerance value in basis points.

setExchangeRateMaxLowerToleranceBps

Updates the maximum lower tolerance for exchange rate deviation.

Only callable by {D0_TIMELOCK_ROLE}.

function setExchangeRateMaxLowerToleranceBps(uint256 _bps) external onlyRole(D0_TIMELOCK_ROLE);

Parameters

NameTypeDescription
_bpsuint256New tolerance value in basis points.

setStablecoinPriceToleranceBps

Updates the stablecoin price tolerance.

Only callable by {D0_TIMELOCK_ROLE}.

function setStablecoinPriceToleranceBps(uint256 _bps) external onlyRole(D0_TIMELOCK_ROLE);

Parameters

NameTypeDescription
_bpsuint256New tolerance value in basis points.

setVolatileAssetPriceToleranceBps

Updates the volatile asset price tolerance.

Only callable by {D0_TIMELOCK_ROLE}.

function setVolatileAssetPriceToleranceBps(uint256 _bps) external onlyRole(D0_TIMELOCK_ROLE);

Parameters

NameTypeDescription
_bpsuint256New tolerance value in basis points.

setPriceUpdateInterval

Updates the minimum price update interval.

Only callable by {D0_TIMELOCK_ROLE}.

function setPriceUpdateInterval(uint256 _interval) external onlyRole(D0_TIMELOCK_ROLE);

Parameters

NameTypeDescription
_intervaluint256New interval in seconds.

setPriceValidityDuration

Updates the validity duration of price feeds.

Only callable by {D1_TIMELOCK_ROLE}.

function setPriceValidityDuration(uint256 _duration) external onlyRole(D1_TIMELOCK_ROLE);

Parameters

NameTypeDescription
_durationuint256New duration in seconds.

setMintFeeRate

Sets the mint fee rate for an asset.

Only callable by {D0_TIMELOCK_ROLE}.

function setMintFeeRate(address _asset, uint256 _rate) external onlyRole(D0_TIMELOCK_ROLE);

Parameters

NameTypeDescription
_assetaddressAddress of the asset.
_rateuint256New fee rate in bps.

setRedeemFeeRate

Sets the redeem fee rate for an asset.

Only callable by {D3_TIMELOCK_ROLE}.

function setRedeemFeeRate(address _asset, uint256 _rate) external onlyRole(D3_TIMELOCK_ROLE);

Parameters

NameTypeDescription
_assetaddressAddress of the asset.
_rateuint256New fee rate in bps.

setDepositEnabled

Enables or disables deposits for an asset.

Only callable by {D0_TIMELOCK_ROLE}.

function setDepositEnabled(address _asset, bool _enabled) external onlyRole(D0_TIMELOCK_ROLE);

Parameters

NameTypeDescription
_assetaddressAsset address.
_enabledboolTrue to enable, false to disable.

setRedeemEnabled

Enables or disables redemption for an asset.

Only callable by {D3_TIMELOCK_ROLE}.

function setRedeemEnabled(address _asset, bool _enabled) external onlyRole(D3_TIMELOCK_ROLE);

Parameters

NameTypeDescription
_assetaddressAsset address.
_enabledboolTrue to enable, false to disable.

setTotalDepositCap

Sets the global deposit cap.

Only callable by {D0_TIMELOCK_ROLE}.

function setTotalDepositCap(uint256 _cap) external onlyRole(D0_TIMELOCK_ROLE);

Parameters

NameTypeDescription
_capuint256New total deposit cap.

setTokenDepositCap

Sets the deposit cap for a specific asset.

Only callable by {D0_TIMELOCK_ROLE}.

function setTokenDepositCap(address _asset, uint256 _cap) external onlyRole(D0_TIMELOCK_ROLE);

Parameters

NameTypeDescription
_assetaddressAsset address.
_capuint256New cap value.

setFeeRecipient

Updates the fee recipient address.

Only callable by {D0_TIMELOCK_ROLE}.

function setFeeRecipient(address _feeRecipient) external onlyRole(D0_TIMELOCK_ROLE);

Parameters

NameTypeDescription
_feeRecipientaddressNew recipient address.

setForfeitTreasury

Updates the forfeited assets treasury address.

Only callable by {D0_TIMELOCK_ROLE}.

function setForfeitTreasury(address _forfeitTreasury) external onlyRole(D0_TIMELOCK_ROLE);

Parameters

NameTypeDescription
_forfeitTreasuryaddressNew treasury address.

Token

Git Source

Inherits: ERC20, AccessControl

Author: luoyhang003

ERC20 token with minting and blacklist transfer restrictions

Combines OpenZeppelin ERC20 and AccessControl

State Variables

MINTER_ROLE

Role identifier for minter accounts(contracts).

Calculated as keccak256("MINTER_ROLE").

bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");

OPERATOR_ROLE

Role identifier for operator accounts.

Calculated as keccak256("OPERATOR_ROLE").

bytes32 public constant OPERATOR_ROLE = keccak256("OPERATOR_ROLE");

accessRegistry

Reference to the access registry contract used for blacklist checks

Must implement the IAccessRegistry interface

IAccessRegistry public immutable accessRegistry;

Functions

constructor

Deploys the token and assigns DEFAULT_ADMIN_ROLE

constructor(address _admin, address _accessRegistry) ERC20("StakeStone USD", "SSUSD");

Parameters

NameTypeDescription
_adminaddressAddress that will receive the default admin role
_accessRegistryaddressAddress of the access registry contract used for blacklist validation

isBlacklisted

Checks whether a given address is blacklisted

function isBlacklisted(address _account) external view returns (bool);

Parameters

NameTypeDescription
_accountaddressThe address to check

Returns

NameTypeDescription
<none>boolTrue if the address is blacklisted, false otherwise

mint

Mint new tokens to a given address

Only callable by addresses with MINTER_ROLE

function mint(address _to, uint256 _amount) external onlyRole(MINTER_ROLE);

Parameters

NameTypeDescription
_toaddressThe address to receive the minted tokens
_amountuint256The amount of tokens to mint

burn

Burn tokens

function burn(uint256 _amount) external;

Parameters

NameTypeDescription
_amountuint256The amount of tokens to burn

_update

Overrides the _update function to enforce transfer restrictions

Prevents transfers if either sender or receiver is blacklisted

function _update(address _from, address _to, uint256 _amount) internal override;

Parameters

NameTypeDescription
_fromaddressthe address tokens are being transferred from
_toaddressthe address tokens are being transferred to
_amountuint256the amount of tokens being transferred

WithdrawController

Git Source

Inherits: IWithdrawController, AccessControl, ReentrancyGuard, Constants

Author: luoyhang003

Handles withdrawal requests, processing, reviewing, rejection, and completion.

Integrates with AccessRegistry for whitelisting, OracleRegistry for pricing, ParamRegistry for fee/limit parameters, and AssetsRouter for asset routing. Implements a multi-step withdrawal lifecycle controlled by admin/operator roles.

State Variables

WITHDRAWAL_ADMIN_ROLE

Role allowed to manage WithdrawController

Calculated as keccak256("WITHDRAWAL_ADMIN_ROLE").

bytes32 public constant WITHDRAWAL_ADMIN_ROLE = keccak256("WITHDRAWAL_ADMIN_ROLE");

WITHDRAWAL_OPERATOR_ROLE

Role allowed to operate WithdrawController

Calculated as keccak256("WITHDRAWAL_OPERATOR_ROLE").

bytes32 public constant WITHDRAWAL_OPERATOR_ROLE = keccak256("WITHDRAWAL_OPERATOR_ROLE");

shareToken

ERC20 share token representing ownership in the vault

Token public immutable shareToken;

accessRegistry

Registry managing whitelisted users for withdrawal access

IAccessRegistry public accessRegistry;

oracleRegistry

Registry providing oracle-based pricing for vault tokens and assets

IOracleRegistry public oracleRegistry;

paramRegistry

Registry holding fee rates, withdrawal caps, and forfeit/fee recipient

IParamRegistry public paramRegistry;

assetsRouter

Router responsible for routing assets to destinations

IAssetsRouter public assetsRouter;

withdrawalAssets

List of supported withdrawal assets

address[] public withdrawalAssets;

withdrawalReceipts

Stores all withdrawal receipts (requests + state tracking)

WithdrawalReceipt[] public withdrawalReceipts;

isWithdrawalAsset

Mapping of supported withdrawal asset status

mapping(address => bool) public isWithdrawalAsset;

tokenDecimals

Cached decimals for each withdrawal asset

mapping(address => uint8) public tokenDecimals;

Functions

constructor

Deploys WithdrawController with initial configs.

Validates input addresses, registers assets, and stores decimals.

constructor(
    address _defaultAdmin,
    address _adminRole,
    address _operatorRole,
    address _shareToken,
    address _accessRegistry,
    address _oracleRegistry,
    address _paramRegistry,
    address _assetsRouter,
    address[] memory _withdrawalAssets
);

Parameters

NameTypeDescription
_defaultAdminaddressAddress granted DEFAULT_ADMIN_ROLE.
_adminRoleaddressAddress granted WITHDRAWAL_ADMIN_ROLE.
_operatorRoleaddressAddress granted WITHDRAWAL_OPERATOR_ROLE.
_shareTokenaddressERC20 share token used for withdrawals.
_accessRegistryaddressRegistry of whitelisted users.
_oracleRegistryaddressRegistry for asset/oracle prices.
_paramRegistryaddressRegistry for fees and limits.
_assetsRouteraddressRouter contract for asset routing.
_withdrawalAssetsaddress[]Initial list of supported withdrawal assets.

requestWithdrawal

Request withdrawal of a specific asset by burning shares.

User must be whitelisted. Generates a withdrawal receipt.

function requestWithdrawal(address _requestToken, uint256 _shares) external;

Parameters

NameTypeDescription
_requestTokenaddressAsset to withdraw into.
_sharesuint256Number of shares to redeem.

requestWithdrawals

Batch request withdrawals across multiple assets.

Lengths must match. Generates multiple withdrawal receipts.

function requestWithdrawals(address[] memory _requestTokens, uint256[] memory _shares) external;

Parameters

NameTypeDescription
_requestTokensaddress[]List of withdrawal asset addresses.
_sharesuint256[]Corresponding share amounts per asset.

cancelWithdrawal

Cancel a single pending withdrawal request.

Only the original requester can cancel. Shares are refunded.

function cancelWithdrawal(uint256 _id) external;

Parameters

NameTypeDescription
_iduint256Receipt ID of the withdrawal request.

cancelWithdrawals

Batch cancel withdrawal requests.

Only the original requester can cancel. Shares are refunded.

function cancelWithdrawals(uint256[] memory _ids) external;

Parameters

NameTypeDescription
_idsuint256[]An array of receipt IDs of the withdrawal requests.

completeWithdrawal

Complete a withdrawal once processed.

Burns shares, transfers asset to user, applies fees.

function completeWithdrawal(uint256 _id) external;

Parameters

NameTypeDescription
_iduint256Receipt ID of withdrawal.

completeWithdrawals

Batch complete withdrawals.

Burns shares, transfers asset to user, applies fees.

function completeWithdrawals(uint256[] memory _ids) external;

Parameters

NameTypeDescription
_idsuint256[]An array of receipt IDs of withdrawals.

getWithdrawalReceiptsLength

Returns total number of withdrawal receipts created.

function getWithdrawalReceiptsLength() external view returns (uint256 length_);

Returns

NameTypeDescription
length_uint256Total number of withdrawal receipts.

getWithdrawalReceipts

Paginates withdrawal receipts.

function getWithdrawalReceipts(uint256 _offset, uint256 _limit)
    external
    view
    returns (WithdrawalReceipt[] memory receipts_);

Parameters

NameTypeDescription
_offsetuint256Start index in array.
_limituint256Number of receipts to fetch.

Returns

NameTypeDescription
receipts_WithdrawalReceipt[]List of withdrawal receipts within range.

markAsProcessing

Mark receipts as PROCESSING with reference prices.

Operator-only. Sets asset and share prices in receipt.

function markAsProcessing(uint256[] memory _ids, uint256 _priceIndex, bool _isCompleted)
    external
    onlyRole(WITHDRAWAL_OPERATOR_ROLE);

Parameters

NameTypeDescription
_idsuint256[]Array of receipt IDs.
_priceIndexuint256Oracle price index to use.
_isCompletedboolWhether all are finalized as processed.

markAsProcessed

Mark receipts as PROCESSED, ready for completion.

function markAsProcessed(uint256[] memory _ids) external onlyRole(WITHDRAWAL_OPERATOR_ROLE);

Parameters

NameTypeDescription
_idsuint256[]Array of receipt IDs.

markAsReviewing

Move receipts to REVIEWING state.

function markAsReviewing(uint256[] memory _ids) external onlyRole(WITHDRAWAL_OPERATOR_ROLE);

Parameters

NameTypeDescription
_idsuint256[]Array of receipt IDs.

markAsRejected

Reject withdrawal requests under review.

Returns original shares to user.

function markAsRejected(uint256[] memory _ids) external onlyRole(WITHDRAWAL_OPERATOR_ROLE);

Parameters

NameTypeDescription
_idsuint256[]Array of receipt IDs.

markAsForfeited

Forfeit withdrawals under review.

Redirects shares to treasury (penalty).

function markAsForfeited(uint256[] memory _ids) external onlyRole(WITHDRAWAL_OPERATOR_ROLE);

Parameters

NameTypeDescription
_idsuint256[]Array of receipt IDs.

repayAssets

Repays assets back into the controller (usually for liquidity replenishment).

Callable only by WITHDRAWAL_OPERATOR_ROLE. Lengths of _assets and _amounts must match and be > 0. Ensures asset is supported and amount is nonzero. Tokens are transferred from operator to this contract.

function repayAssets(address[] memory _assets, uint256[] memory _amounts) external onlyRole(WITHDRAWAL_OPERATOR_ROLE);

Parameters

NameTypeDescription
_assetsaddress[]Array of ERC20 token addresses to repay.
_amountsuint256[]Array of amounts to repay for each corresponding asset.

addWithdrawalAsset

Adds a new supported withdrawal asset.

Callable only by WITHDRAWAL_ADMIN_ROLE. Requires a valid oracle registered for _asset. Stores token decimals (must be ≤ 18). Emits {WithdrawalAssetAdded}.

function addWithdrawalAsset(address _asset) external onlyRole(WITHDRAWAL_ADMIN_ROLE);

Parameters

NameTypeDescription
_assetaddressERC20 token address to be added as a withdrawal option.

removeWithdrawalAsset

Removes an existing withdrawal asset from the supported list.

Callable only by WITHDRAWAL_ADMIN_ROLE. Reverts if _asset is not currently supported. Updates mapping and storage list. Emits {WithdrawalAssetRemoved}.

function removeWithdrawalAsset(address _asset) external onlyRole(WITHDRAWAL_ADMIN_ROLE);

Parameters

NameTypeDescription
_assetaddressERC20 token address to remove.

forceRouteAssets

Force routes a specific amount of an asset through the AssetsRouter.

Callable only by WITHDRAWAL_ADMIN_ROLE. Typically used in emergencies or manual corrections. Resets and re-approves allowance before routing.

function forceRouteAssets(address _asset, uint256 _amount) external onlyRole(WITHDRAWAL_ADMIN_ROLE);

Parameters

NameTypeDescription
_assetaddressERC20 token address to route.
_amountuint256Amount of _asset to route.

setAssetsRouter

Updates the AssetsRouter contract used for routing assets.

Callable only by WITHDRAWAL_ADMIN_ROLE. Emits {SetAssetsRouter}. Does not reset allowances for all assets (admin must manage separately if needed).

function setAssetsRouter(address _assetsRouter) external onlyRole(WITHDRAWAL_ADMIN_ROLE);

Parameters

NameTypeDescription
_assetsRouteraddressAddress of the new AssetsRouter contract.

_requestWithdrawal

Emits {WithdrawalRequested}.

Internal logic for handling withdrawal requests. Transfers shares from user, creates a withdrawal receipt, applies fee rate from ParamRegistry, and marks status as REQUESTED.

function _requestWithdrawal(address _requestToken, uint256 _shares) internal nonReentrant;

Parameters

NameTypeDescription
_requestTokenaddressAddress of the withdrawal asset requested.
_sharesuint256Amount of shares to redeem.

_cancelWithdrawal

Emits {WithdrawalCancelled}.

Internal logic for cancelling a withdrawal request. Refunds shares to requester and updates receipt status.

function _cancelWithdrawal(uint256 _id) internal;

Parameters

NameTypeDescription
_iduint256ID of the withdrawal receipt to cancel.

_completeWithdrawal

Emits {WithdrawalCompleted}.

Internal logic for completing withdrawals after being processed. Calculates withdrawn amount using oracle prices, applies fee, burns shares, and transfers assets to requester.

function _completeWithdrawal(uint256 _id) internal nonReentrant;

Parameters

NameTypeDescription
_iduint256ID of the withdrawal receipt to complete.

_normalize

Normalizes token amounts to base decimals (18).

Expands or compresses numbers depending on asset decimals.

function _normalize(uint256 _amount, uint256 _decimals) internal pure returns (uint256 normalized_);

Parameters

NameTypeDescription
_amountuint256Token amount in original decimals.
_decimalsuint256Decimals of the token.

Returns

NameTypeDescription
normalized_uint256Amount scaled to 18 decimals.

_denormalize

Denormalizes token amounts from base decimals (18) to asset decimals.

Reverses normalization logic.

function _denormalize(uint256 _amount, uint256 _decimals) internal pure returns (uint256 denormalized_);

Parameters

NameTypeDescription
_amountuint256Amount in 18 decimals.
_decimalsuint256Decimals of the asset.

Returns

NameTypeDescription
denormalized_uint256Amount scaled back to asset decimals.