Pool contract
The Pool
contract implements the state and logic of a single pool instance. Users' deposits and debt in a pool are managed in this specific Pool
instance. It allows users to retrieve and manage their positions and curators to change the pool configuration and claim fees.
On this page, we discuss the Pool
's main storage variables and external functions.
Data Types
Vesu V2 defines a number of data types, or struct
s, that are reused across the different components. We here discuss the main types related to the Pool
contract.
AssetConfig
The AssetConfig
struct contains all relevant state on a specific asset in a pool. It is stored in the asset_configs
mapping in the Pool
itself and can be fetched with the asset_config
function.
pub struct AssetConfig { // | slot | packed | notes
// | ---- | ------ | -----
pub total_collateral_shares: u256, // [SCALE] | 1 | u128 |
pub total_nominal_debt: u256, // [SCALE] | 1 | u123 |
pub reserve: u256, // [asset scale] | 2 | u128 |
pub max_utilization: u256, // [SCALE] | 2 | u8 | constant percentage
pub floor: u256, // [SCALE] | 2 | u8 | constant decimals
pub scale: u256, // [SCALE] | 2 | u8 | constant decimals
pub is_legacy: bool, // | 2 | u8 | constant
pub last_updated: u64, // [seconds] | 3 | u32 |
pub last_rate_accumulator: u256, // [SCALE] | 3 | u64 |
pub last_full_utilization_rate: u256, // [SCALE] | 3 | u64 |
pub fee_rate: u256, // [SCALE] | 3 | u8 | percentage
// tracks the number of unclaimed allocated shares (from each asset) that can be claimed by
// `fee_recipient`.
pub fee_shares: u256 // [SCALE] | 4 | u128 |
}
Position
The Position
struct contains the collateral_shares
and nominal_debt
of a user's position in the specific lending pair and pool. Note that collateral_shares
and nominal_debt
does not translate 1:1 to the underlying assets but a conversion has to be applied.
pub struct Position {
pub collateral_shares: u256, // packed as u128 [SCALE]
pub nominal_debt: u256 // packed as u123 [SCALE]
}
Amount & AmountDenomination
The Amount
struct is used to express a desired amount to deposit, withdraw, borrow, or repay in a user interaction and the respective ModifyPositionParam
parameter.
The AmountDenomination
enum
alows users to express a value in either Assets
denomination, that is in underlying asset units directly, or in Native
denomination which is the denomination that Vesu uses and is collateral_shares
for a collateral asset and nominal_debt
for a debt asset.
pub enum AmountDenomination {
#[default]
Native,
Assets,
}
The Amount
is then defined as the AmountDenomination
and the actual value.
pub struct Amount {
pub denomination: AmountDenomination,
pub value: i257,
}
Thereby, the value
is a signed integer and can express both an amount to deposit or withdraw:
- Collateral asset
- if
value >0
: deposit assets - if
value <0
: withdraw assets
- if
- Debt asset
- if
value >0
: borrow assets - if
value <0
: repay assets
- if
ModifyPositionParams
The ModifyPositionParams
struct is used to express the changes a user wants to make to a position in a specific Pool
. It includes the position's collateral_asset
and debt_asset
, the user
who should own the position, and the collateral
and debt
amounts, expressed in Amount
types, with which the position should be modified.
pub struct ModifyPositionParams {
pub collateral_asset: ContractAddress,
pub debt_asset: ContractAddress,
pub user: ContractAddress,
pub collateral: Amount,
pub debt: Amount,
}
The ModifyPositionParams
allows to express all sorts of position modifications including deposit, withdrawal, borrow, repay and is used for all position interactions with the modify_position
function. Read more on this in the Interact with Vesu section.
LiquidatePositionParams
The LiquidatePositionParams
struct is used to execute liquidations of insolvent position through the liquidate_position
function.
The liquidator defines which position to liquidate with the respective collateral_asset
, debt_asset
and user
fields. He indicates the amount of debt, in Assets
denomination, he wishes to repay with the debt_to_repay
field and defines the minimal amount of collateral, in Assets
denomination, he wants to receive in exchange with the min_collateral_to_receive
.
pub struct LiquidatePositionParams {
pub collateral_asset: ContractAddress,
pub debt_asset: ContractAddress,
pub user: ContractAddress,
pub min_collateral_to_receive: u256,
pub debt_to_repay: u256,
}
Storage
We here show the full storage of the Pool
contract with inline docs.
struct Storage {
// tracks the name
pool_name: felt252,
// tracks the state of each position
// (collateral_asset, debt_asset, user) -> position
positions: Map<(ContractAddress, ContractAddress, ContractAddress), Position>,
// tracks the delegation status for each delegator to a delegatee
// (delegator, delegatee) -> delegation
delegations: Map<(ContractAddress, ContractAddress), bool>,
// tracks the configuration / state of each asset
// asset -> asset configuration
asset_configs: Map<ContractAddress, AssetConfig>,
// Oracle contract address
oracle: ContractAddress,
// fee recipient
fee_recipient: ContractAddress,
// tracks the configuration / state of each pair
// (collateral_asset, debt_asset) -> pair configuration
pair_configs: Map<(ContractAddress, ContractAddress), PairConfig>,
// tracks the total collateral shares and the total nominal debt for each pair
// (collateral asset, debt asset) -> pair configuration
pairs: Map<(ContractAddress, ContractAddress), Pair>,
// tracks the address that can pause the contract
pausing_agent: ContractAddress,
// The owner of the pool
curator: ContractAddress,
// The pending curator
pending_curator: ContractAddress,
// Indicates whether the contract is paused
paused: bool,
#[substorage(v0)]
ownable: OwnableComponent::Storage,
// storage for the interest rate model component
#[substorage(v0)]
interest_rate_model: interest_rate_model_component::Storage,
}
User functions
Users interact with a Vesu pool primarily through the function position
, to retrieve a position, and modify_position
, to create or update an existing position.
Modify a position
Learn more on how to use this function here.
Use this function to create, modify and close positions. See section Modify Position Params above to learn more about the different configurations of the function arguments to achieve the different position updates.
/// Adjusts a positions collateral and debt balances
/// # Arguments
/// * `params` - see ModifyPositionParams
/// # Returns
/// * `response` - see UpdatePositionResponse
fn modify_position(ref self: ContractState, params: ModifyPositionParams) -> UpdatePositionResponse
Retrieve a position
Use this function to retrieve the current state of a user position including its collateral shares (Native
denomination), nominal debt (Native
denomination), collateral assets (Asset
denomination) and debt assets (Asset
denomination).
/// Returns the current state of a position
/// # Arguments
/// * `collateral_asset` - address of the collateral asset
/// * `debt_asset` - address of the debt asset
/// * `user` - address of the position's owner
/// # Returns
/// * `position` - position state
/// * `collateral` - amount of collateral (computed from position.collateral_shares) [asset scale]
/// * `debt` - amount of debt (computed from position.nominal_debt) [asset scale]
fn position(
self: @ContractState, collateral_asset: ContractAddress, debt_asset: ContractAddress, user: ContractAddress,
) -> (Position, u256, u256)
Liquidator functions
Use this function to liquidate an insolvent position.
/// Liquidates a position
/// # Arguments
/// * `params` - see LiquidatePositionParams
/// # Returns
/// * `response` - see UpdatePositionResponse
fn liquidate_position(ref self: ContractState, params: LiquidatePositionParams) -> UpdatePositionResponse
Curator functions
To create a new pool and add a new asset to an existing pool, curators should always use the create_pool
and add_asset
functions on the PoolFactory
contract.
Note that only the curator
role of the Pool
contract has permission to use the below functions.
Change Asset Parameter
To change a specific parameter for an asset, use the set_asset_parameter
function:
/// Sets a parameter of an asset
/// # Arguments
/// * `asset` - address of the asset
/// * `parameter` - parameter name
/// * `value` - value of the parameter
fn set_asset_parameter(ref self: ContractState, asset: ContractAddress, parameter: felt252, value: u256)
Note, the following parameters can be changed:
max_utilization
floor
fee_rate
Change Interest Rate Parameter
To change a specific parameter of an asset's interest rate model, use the set_interest_rate_parameter
function:
/// Sets a parameter for a given interest rate configuration for an asset
/// # Arguments
/// * `asset` - address of the asset
/// * `parameter` - parameter name
/// * `value` - value of the parameter
fn set_interest_rate_parameter(
ref self: ContractState, asset: ContractAddress, parameter: felt252, value: u256,
)
Change Pair Parameter
To change a specific parameter for a lending pair, use the set_pair_parameter
function:
/// Sets a parameter for a given pair configuration
/// # Arguments
/// * `collateral_asset` - address of the collateral asset
/// * `debt_asset` - address of the debt asset
/// * `parameter` - parameter name
/// * `value` - value of the parameter
fn set_pair_parameter(
ref self: ContractState,
collateral_asset: ContractAddress,
debt_asset: ContractAddress,
parameter: felt252,
value: u128,
)
Note, the following parameters can be changed:
max_ltv
liquidation_factor
debt_cap
Change Fee Recipient
To change the fee_recipient
for a pool, use the set_fee_recipient_parameter
function:
/// Sets the address to which fees are sent.
/// # Arguments
/// * `fee_recipient` - new fee address
fn set_fee_recipient(ref self: ContractState, fee_recipient: ContractAddress)
Nominate new Curator
To initiate the transfer of the curator role of a pool, use the nominate_curator
function. Note, transferring the curator role is a 2-step process and requires the new curator to accept the transfer.
/// Initiate transferring ownership of the pool.
/// The nominated curator should invoke `accept_curator_ownership` to complete the transfer.
/// At that point, the original curator will be removed and replaced with the nominated curator.
/// # Arguments
/// * `curator` - address of the new curator
fn nominate_curator(ref self: ContractState, pending_curator: ContractAddress)
Accept Curator Role
Note that without accepting a curator nomintation, you will not be able to use the curator permissions in a pool.
Use this function to accept the nomination of the curator role.
/// Accept the curator address.
/// At this point, the original curator will be removed and replaced with the nominated curator.
fn accept_curator_ownership(ref self: ContractState)
Change the Pauser Agent
The Pauser Agent role has the permission to pause deposits and withdrawals on a pool. Make sure you assign this role only to a trusted agent.
Use this function to assign the Pauser Agent role to a new account.
/// Sets the pausing agent
/// # Arguments
/// * `pausing_agent` - address of the pausing agent
fn set_pausing_agent(ref self: ContractState, pausing_agent: ContractAddress)
Pause pool
Pausing a pool should only be used in an emergency as it pauses all deposits and withdrawals in a pool. Pools can be paused by the Pauser Agent, Curator and Owner but only be unpaused by the curator or owner.
Use this function to pause deposits and withdrawals (including liquidations) in a pool.
/// Pauses the contract
/// Requirements: The contract is not paused
/// Emits a `Paused` event
fn pause(ref self: ContractState)
Unpause pool
Use this function to unpause a paused pool.
/// Lifts the pause on the contract
/// Requirements: The contract is paused
/// Emits an `Unpaused` event
fn unpause(ref self: ContractState)