Vault
The Vault is the core module responsible for the storage, issuance, and redemption of cUSD, and for managing the underlying collateral assets. It plays a pivotal role as the protocol's liquidity backbone by enabling minting and burning of cUSD, facilitating liquidity for borrowers, and ensuring capital efficiency through the Fractional Reserves.
Overview of operations
Mint/Burn: cUSD can be minted/burned ~1:1 for any of the supported backing assets. Fees are dynamically calculated according to the allocation ratio of the asset.
Redeem: cUSD can be redeemed for a proportional amount of the basket of assets for a fixed fee.
Fractional Reserves: Idle capital in the Vault is deployed into yield-generating strategies (US T-bill yield, crypto lending markets) until borrowed or withdrawn.
Borrow/Repay: When operators borrow/repays assets, the Vault tracks utilization of the pool
Mechanics
Mint/Burn
The Vault is the main interface for liquidity providers to mint and burn cUSD. cUSD can be minted/burned at Oracle value for any of the assets. Fees are calculated in the Minter contract according to the allocation of the assets.
When a user mints/burns, the flow is as follows:
User Call: User calls
Vault.mint()
(or burn) with asset and amountFee Calculation: Vault calls
Minter.getMintAmount()
(or getBurnAmount) to calculate feesLogic Processing: MinterLogic calculates amount out and fees at current Oracle value
State Update: VaultLogic handles asset transfer and state updates
Token Minting: cUSD is minted/burned in exchange for underlying assets
Redeem
A depeg event of any of the underlying assets can result in a last man standing problem where the last to withdraw will be left with the depegged asset. When such events occur, the protocol incentivizes users to withdraw proportionally to the ratio of the assets, effectively socializing the losses. Redeem fees are charged at a fixed percentage, whereas burn fees are dynamic, making it economically infeasible to burn for USDT beyond the burn kink ratio. For instance, if the basket contains 50% of USDC valued at $0.9 and 50% of USDT valued at $1, then the redeem request for $100 cUSD should withdraw $45 worth of USDC and $50 worth of USDT minus fees.
When a user redeems, the flow is as follows:
User Call: User calls
Vault.redeem()
with cUSDFee Calculation: Vault calls
Minter.getRedeemAmount()
to calculate proportional amountsState Update: cUSD is burned from user, assets are divested from strategies
Asset Transfer: All underlying assets are transferred to user
Borrow Operations
Registered Operators can borrow assets from the Vault via the Lender, provided they are sufficiently collateralized by delegated assets from shared security networks. While assets are lent out from the Vault, the core borrow logic is implemented in the Lender contract. When the Operator requests to borrow via the Lender, the Lender calls Vault.borrow()
to transfer assets to the Lender, updating the utilization and reserve state of the Vault.
Similarly, Operators can repay via the Lender, which transfers borrowed assets back to the Vault.
Vault Management
Assets must first be whitelisted in order to be used in Cap. Only regulated dollar-denominated crypto assets are accepted as a backing assets.
Interest rates for borrowing each asset of the reserve is a function of the utilization rate of the asset. The current utilization rate of each asset can be queried in the Vault contract.
Configurations
Whitelist minters: Supports fee bypass for privileged users
Pause mechanisms:
Asset-Level Pause: Individual assets can be paused while others remain active
Protocol-Level Pause: Complete protocol shutdown capability
Key Vault Parameters
Total Supplies: Total amount of each asset deposited in the vault
Total Borrows: Total amount of each asset borrowed from the vault
Utilization Rate: Ratio of borrowed assets to total supplies, calculated as (Total Borrows / Total Supplies) * 100%
Available Balance: Amount of asset available for borrowing, calculated as Total Supplies - Total Borrows
Utilization Index: Cumulative utilization tracking for interest rate calculations
Insurance Fund: Address that receives fees from mint/burn operations
Pause States: Individual asset pause states and protocol-wide pause capability
Architecture
The Vault module inherits from the Fractional Reserve and Minter contracts
Vault - Manages asset storage, accounting, and cUSD minting/burning
Fractional Reserve - Manages idle capital deployment
Minter - Handles dynamic fee calculation for minting operations
Vault Contract
The Vault Contract is the main user-facing contract that enables minting and borrowing, as well as reserve asset management.
Core Functions
mint
: Allows users to deposit approved assets and receive cUSD in return
function mint(address _asset, uint256 _amountIn, uint256 _minAmountOut, address _receiver, uint256 _deadline)
external
returns (uint256 amountOut)
_asset
: Whitelisted asset to deposit_amountIn
: Amount of asset to use in the minting_minAmountOut
: Minimum amount to mint (slippage protection)_receiver
: Receiver of the minting_deadline
: Deadline of the transaction
Key features:
Slippage Protection:
_minAmountOut
parameterDeadline Protection: Transaction deadline validation
Dynamic Fees: Fees based on asset allocation ratios
burn
: Burns cUSD in exchange for one of the underlying assets.
function burn(address _asset, uint256 _amountIn, uint256 _minAmountOut, address _receiver, uint256 _deadline)
external
returns (uint256 amountOut)
_asset
: Asset to withdraw_amountIn
: Amount of cap token to burn_minAmountOut
: Minimum amount out to receive_receiver
: Receiver of the withdrawal_deadline
: Deadline of the transaction
redeem
: Allows users to burn cUSD in exchange for multi-collateral withdrawal, proportional to the ratio of the underlying assets.
function redeem(uint256 _amountIn, uint256[] calldata _minAmountsOut, address _receiver, uint256 _deadline)
external
returns (uint256[] memory amountsOut)
_amountIn
: Amount of Cap token to burn_minAmountsOut
: Minimum amounts of assets to withdraw_receiver
: Receiver of the withdrawal_deadline
: Deadline of the transaction
Key features:
Proportional Withdrawal: Withdraws assets proportional to current ratios
Fee Avoidance: Avoids dynamic fees by withdrawing proportionally
borrow
: Allows whitelisted agents to borrow assets from the vault
function borrow(address _asset, uint256 _amount, address _receiver) external
_asset
: Asset to borrow_amount
: Amount of asset to borrow_receiver
: Receiver of the borrow
repay
: Allows repayment of borrowed assets
function repay(address _asset, uint256 _amount) external
_asset
: Asset to repay_amount
: Amount of asset to repay
Admin Functions
addAsset
: Adds new assets to the vaultremoveAsset
: Removes assets from the vault (only if no supplies)pauseAsset
: Pauses operations for specific assetsunpauseAsset
: Resumes operations for specific assetspauseProtocol
: Pauses all protocol operationsunpauseProtocol
: Resumes all protocol operationssetInsuranceFund
: Sets the insurance fund addressrescueERC20
: Rescues unsupported tokens from the vault
View Functions
assets
: Get the list of assets supported by the vaulttotalSupplies
: Get the total supplies of an assettotalBorrows
: Get the total borrows of an assetutilization
: Get the utilization rate of an assetavailableBalance
: Get available balance to borrow an assetpaused
: Get the pause state of an assetcurrentUtilizationIndex
: Get up-to-date cumulative utilization indexinsuranceFund
: Get the insurance fund address
Data Structures
VaultStorage
The VaultStorage stores all vault configuration and state information.
struct VaultStorage {
EnumerableSet.AddressSet assets; // List of supported assets
mapping(address => uint256) totalSupplies; // Total supplies per asset
mapping(address => uint256) totalBorrows; // Total borrows per asset
mapping(address => uint256) utilizationIndex; // Utilization index per asset
mapping(address => uint256) lastUpdate; // Last update time per asset
mapping(address => bool) paused; // Pause state per asset
address insuranceFund; // Insurance fund address
}
MintBurnParams
Parameters for minting or burning operations.
struct MintBurnParams {
address asset; // Asset to mint or burn
uint256 amountIn; // Amount of asset to use
uint256 amountOut; // Amount of cap token to mint or burn
uint256 minAmountOut; // Minimum amount to mint or burn
address receiver; // Receiver of the operation
uint256 deadline; // Deadline of the transaction
uint256 fee; // Fee paid to insurance fund
}
RedeemParams
Parameters for redemption operations.
struct RedeemParams {
uint256 amountIn; // Amount of cap token to burn
uint256[] amountsOut; // Amounts of assets to withdraw
uint256[] minAmountsOut; // Minimum amounts of assets to withdraw
address receiver; // Receiver of the withdrawal
uint256 deadline; // Deadline of the transaction
uint256[] fees; // Fees paid to insurance fund
}
BorrowParams
Parameters for borrowing operations.
struct BorrowParams {
address asset; // Asset to borrow
uint256 amount; // Amount of asset to borrow
address receiver; // Receiver of the borrow
}
RepayParams
Parameters for repayment operations.
struct RepayParams {
address asset; // Asset to repay
uint256 amount; // Amount of asset to repay
}
Last updated