VaultManagercontract is the main contract of Angle Borrowing Module. It is one of the only user-facing contracts. This contract allows people to deposit collateral and open up loans of a given AgToken. It handles all the loan logic (fees and interest rate) as well as the liquidation logic.
VaultManagercontract per collateral type for a given stablecoin. You may have for instance two different
VaultManagercontract for ETH as a collateral, with for instance two different set of parameters.
ERC721MetadataUpgradeablestandard. Vaults (name of the tokens in this contract) are non fungible, but they can be transferred from one address to another, you can also approve another address to interact with you vault or simply check the number of vaults you own.
Initializable. This contract is upgradeable. This contract implements a version of
ERC721Permitwhich allows to grant allowance to an address for an ensemble of vautlts through a permit signature.
treasury: Reference to the
Treasurycontract associated to this
collateral: Reference to the collateral handled by this
stablecoin: Stablecoin handled by this contract. Another
VaultManagercontract could have the same rights as this
VaultManageron the stablecoin contract
oracle: Oracle contract to get access to the price of the collateral with respect to the stablecoin
veBoostProxy: Reference to the contract which computes adjusted veANGLE balances for liquidators boosts
dust: Minimum amount of debt a vault can have
_dustCollateral: Minimum amount of collateral (in stablecoin value) that can be left in a vault during a liquidation where the health factor function is decreasing
debtCeiling: Maximum amount of stablecoins that can be issued with this contract
yLiquidationBoost: Threshold veANGLE balance values and value of the boost for liquidators at these threshold values: the length of these arrays should be 2
collateralFactor: Encodes the maximum ratio stablecoin/collateral a vault can have before being liquidated. It's what determines the minimum collateral ratio of a position
targetHealthFactor: Maximum Health factor at which a vault can end up after a liquidation (unless it's fully liquidated)
borrowFee: Upfront fee taken when borrowing stablecoins
repayFee: Fee taken when repaying a stablecoin debt
interestRate: Per second interest taken to borrowers taking agToken loans
liquidationSurcharge: Fee taken by the protocol during a liquidation. Technically, this value is not the fee per se, it's 1 - fee. For instance for a 2% fee,
liquidationSurchargeshould be 98%.
maxLiquidationDiscount: Maximum discount given to liquidators
whitelistingActivated: Whether whitelisting is required to own a vault or not
paused: Whether the contract is paused or not
lastInterestAccumulatorUpdated: Timestamp at which the
interestAccumulator: Keeps track of the interest that should accrue to the protocol. The stored value is not necessarily the true value: this one is recomputed every time an action takes place within the protocol.
totalNormalizedDebt: Total normalized amount of stablecoins borrowed
surplus: Surplus accumulated by the contract: surplus is always in stablecoins, and is then reset when the value is communicated to the treasury contract
badDebt: Bad debt made from liquidated vaults which ended up having no collateral and a positive amount of stablecoins
vaultData: Maps a
vaultIDto its data (namely collateral amount and normalized debt)
isWhitelisted: Maps an address to whether it's whitelisted and can open or own a vault
_operatorApprovals). The only publicly available is the
vaultIDCountwhich is a counter to generate a unique
vaultIDfor each vault:
tokenIDin basic ERC721 contracts.
_noncesmapping to used to check permit signatures to the contract.
Treasurycontract which then calls its associated
getControlledVaultsfunction was also added. It allows to check all the vaults controlled by an address. This is an expensive function that should never be called on-chain as it iterates over all vaultIDs. It is here to reduce dependency on an external graph to link a vaultID ID to its owner.
owner: Address which signed the message
spender: Address to grant or revoke allowance to
approved: Whether to grant or revoke allowance
deadline: Timestamp till which the signature is valid
v, r, s: Signature data
VaultManagercontract was designed to be composable in a single transaction: this can be done with the
oracleValue) are done only once
actions: Set of actions to perform. Each action corresponds to a different integer.
datas: Array of data to be decoded for each action. Each item in this array is the abi-encoded version of different parameters for each version: parameters can include like the
stablecoinAmountto borrow for instance. Each action expects particular data to be given (more detail below). The
datasarray should have the same length as the
from: Address from which stablecoins will be taken if one action includes burning stablecoins. This address should either be the
msg.senderor be approved by the latter
to: Address to which stablecoins and/or collateral will be sent in case of
who: Address of the contract to handle in case of repayment of stablecoins from received collateral
repayData: Data to pass to the repayment contract in case of
paymentData: Struct containing the final transfers executed. This struct contains four different fields (named from the protocol's perspective):
stablecoinAmountToGive: Stablecoin amount the contract has given to the
stablecoinAmountToReceive: Stablecoin amount taken from the
fromaddress to be burnt by the contract
collateralAmountToGive: Collateral amount the contract has given to the
collateralAmountToReceive: Collateral amount taken from the
msg.senderaddress Any contract interfacing with the
vaultID, specifiying a
vaultID = 0will automatically process the last vault created.
borrowaction to get stablecoins).
address: address for which the vault should be created
uint256: ID of the vault to close
uint256: ID of the vault to add collateral to
uint256: Amount of collateral to add
uint256: ID of the vault to remove collateral from
uint256: Amount of collateral to remove
uint256: ID of the vault for which stablecoins should be borrowed
uint256: Amount of stablecoins to borrow. If there are borrowing fees, the amount of stablecoins actually going to the
uint256: ID of the vault for which debt should be repaid
uint256: Amount of stablecoins to repay. Setting an amount higher than the debt of the vault will simply reimburse all the outstanding debt in the vault. In this case, stablecoin transfer from the
fromaddress will just be equal to the value of the debt, meaning if you use
type(uint256).max, you will just be charged the value of the debt
VaultManagercontract. Only approved addresses by the source vault owner can perform this action, however any vault from any
VaultManagercontract of the same stablecoin can see its debt reduced by this means. A solvency check is performed after the debt increase in the source
uint256: ID of the vault in this contract for which debt should be increased
address: Address of the
VaultManagercontract where the vault from which debt should be taken is: it can well be the same
VaultManagercontract. If a wrong
VaultManageraddress is specified (like a contract with specifically the right interface), then this function may just increase the debt in a vault without reducing the debt in another one.
uint256: ID of the vault from which debt should be taken. This operation will technically just reduce the debt of this vault. If there are different minting fees in both contracts, then this action will make sure that everything is as if for the borrowers they had been the same
uint256: Amount of stablecoins to increase the debt of
VaultManagerfor the collateral (if the specific collateral used supports this).
address: Owner address which has signed the permit and wants to approve the `VaultManager``
uint256: Amount of collateral to approve
uint256: Deadline parameter for the permit
vparameter for the permit. This
uint256is casted to
uint8in the contract
toVaultand returns the ID of this vault.
VaultManagercontracts if these contracts were requested a
getDebtInaction with debt from a vault in the contract. Hence only
VaultManagerof the same treasury contracts can call it. This function ultimately reduces the debt of
senderBorrowFeeto make sure that if the
senderBorrowFeeis greater than the borrow fee in the contract, then borrow fees are still paid on the debt transferred.
VaultManagercontract are handled directly in the same contract. There are two external access functions for liquidators to liquidate.
checkLiquidationfunction for each vault to liquidate before calling for a liquidation.
vaultIDs: List of the vaults to liquidate
amounts: Array of amount of stablecoins to bring for the liquidation of each vault. If an amount is too big, it is going to be rounded down by the contract to the max possible amount to repay for an unhealthy vault
from: Address from which stablecoins for the liquidations will be takne
to: Address to which collateral will be sent
who: This is an optional argument (could be the zero address), and can be used in case a specific contract should handle the repayment
data: Optional again, it can help the
whocontract to know which swap to proceed
liqOpp: This is a struct with several info on the liquidations that were made by this function. Note that these returned values are denominated from a protocol perspective.
stablecoinAmountToReceive: This is the amount of stablecoins the liquidator has given for the liquidation
collateralAmountToGive: Current amount of collateral obtained from the protocol from the contract
badDebtFromLiquidation: Bad debt accrued across the liquidation process in the
oracleValue: Oracle value at which the liquidation took place
newInterestAccumulator: Value of the
interestAccumulatorat the time of the call (this is a value used to track vaults outstanding debt)
liquidatoris optional here: it is here to compute the boost on the discount a liquidator could get.
liqOpp. It contains data about how much stablecoins can be repaid from the liquidation, what discount the liquidator would get, what collateral amount the liquidator could at most get. For more details on the output of this function, you can check the guide here.
VaultManagerlevel. These functions are:
Treasurycontract to pull surplus and bad debt from the contract. The role of the
Treasurycontract is then to pool all the surplus and bad debt it got from all
VaultManagerto handle governance distribution.
VaultManagercontract, calling this contract resets the
badDebtvalue in storage to zero.
Treasurycontract, the contract has several restricted functions used by governance (or the guardian) to set parameters:
setUint64: to change parameters stored as
setDebtCeiling: to change the debt ceiling of the `VaultManager``
setLiquidationBoostParameters: sets the parameters for the liquidation booster which encodes the slope of the discount for liquidators
toggleWhitelist: to toggle permission for vault ownership by any account or to allow/disallow an address in case whitelisting is activated. If this is activated, vaults that existed prior to that will not be transferrable to addresses which are not whitelisted, and new vaults will only be openable by whitelisted addresses
setOracle: to set the oracle contract
setTreasury: to change the reference to the
Treasurycontract (this function should never be used in practice)
togglePause: to pause the contract
setBaseURI: to change the ERC721 Metadata URI