Vault
The Vault is an ERC4626-compliant vault where lenders deposit the borrowed token (e.g., USDC, WETH) to earn yield from borrower interest. Each lending market has its own isolated vault instance deployed by the LendFactory.
The vault's pricePerShare increases over time as borrowers pay interest. It implements the full ERC20 and ERC4626 interfaces, with additional Curve-specific methods for APR reporting and supply limits.
The vault uses a dead shares mechanism (minting 1000 shares to the zero address on initialization) to protect against ERC4626 inflation attacks.
Vault.vyExamples use Ethers v6 with an ABI generated from the pinned source linked in each panel. Replace every zero address and amount placeholder. Read-only calls use the verified Ethereum v2 reference market; execute a write only on a fork first.
ERC4626 — Deposits and Withdrawals
deposit
Vault.deposit(_assets: uint256, _receiver: address) -> uint256Deposits the specified amount of borrowed tokens into the vault and mints shares to the receiver.
| Input | Type | Description |
|---|---|---|
_assets | uint256 | Amount of borrowed tokens to deposit |
_receiver | address | Address to receive the minted vault shares |
Returns: number of shares minted (uint256).
Emits: Deposit event.
<>Source code▼
Excerpt from lending/Vault.vy at 0d726b1:
@external
def deposit(_assets: uint256, _receiver: address = msg.sender) -> uint256:
"""
@notice Deposit assets in return for whatever number of shares corresponds to the current conditions
@param _assets Amount of assets to deposit
@param _receiver Receiver of the shares who is optional. If not specified - receiver is the sender
@return Amount of shares minted
"""
controller: IController = self._controller
total_assets: uint256 = self._total_assets()
assert total_assets + _assets >= MIN_ASSETS, "Need more assets"
assert total_assets + _assets <= self.maxSupply, "Supply limit"
to_mint: uint256 = self._convert_to_shares(_assets, True, total_assets)
assert to_mint > 0, "Can't mint 0 shares"
extcall ILendController(controller.address).on_borrowed_token_transfer_in(_assets)
tkn.transfer_from(self._borrowed_token, msg.sender, controller.address, _assets)
self._mint(_receiver, to_mint)
extcall controller.save_rate()
log IERC4626.Deposit(sender=msg.sender, owner=_receiver, assets=_assets, shares=to_mint)
return to_mint
▶Example▼
const contract = new Contract('0x2b5a321c3cb1f33e1abecd047c2649d0b4c47eba', VaultAbi, signer)
const tx = await contract.deposit(
/* _assets: uint256 */ 0n,
/* _receiver: address */ "0x0000000000000000000000000000000000000000",
)
await tx.wait()
mint
Vault.mint(_shares: uint256, _receiver: address) -> uint256Mints an exact number of vault shares by depositing the required amount of borrowed tokens.
| Input | Type | Description |
|---|---|---|
_shares | uint256 | Exact number of shares to mint |
_receiver | address | Address to receive the minted shares |
Returns: amount of assets deposited (uint256).
Emits: Deposit event.
<>Source code▼
Excerpt from lending/Vault.vy at 0d726b1:
@external
def mint(_shares: uint256, _receiver: address = msg.sender) -> uint256:
"""
@notice Mint given amount of shares taking whatever number of assets it requires
@param _shares Number of shares to mint
@param _receiver Optional receiver for the shares. If not specified - it's the sender
@return Amount of assets taken from the caller
"""
assert _shares > 0, "Can't mint 0 shares"
controller: IController = self._controller
total_assets: uint256 = self._total_assets()
assets: uint256 = self._convert_to_assets(_shares, False, total_assets)
assert total_assets + assets >= MIN_ASSETS, "Need more assets"
assert total_assets + assets <= self.maxSupply, "Supply limit"
extcall ILendController(controller.address).on_borrowed_token_transfer_in(assets)
tkn.transfer_from(self._borrowed_token, msg.sender, controller.address, assets)
self._mint(_receiver, _shares)
extcall controller.save_rate()
log IERC4626.Deposit(sender=msg.sender, owner=_receiver, assets=assets, shares=_shares)
return assets
@internal
@view
def _available_balance() -> uint256:
return crv_math.sub_or_zero(
staticcall self._controller.available_balance(),
staticcall self._controller.admin_fees(),
)
▶Example▼
const contract = new Contract('0x2b5a321c3cb1f33e1abecd047c2649d0b4c47eba', VaultAbi, provider)
const result = await contract.mint(
/* _shares: uint256 */ 0n,
/* _receiver: address */ "0x0000000000000000000000000000000000000000",
)
withdraw
Vault.withdraw(_assets: uint256, _receiver: address, _owner: address) -> uint256Withdraws an exact amount of borrowed tokens by burning the required vault shares.
| Input | Type | Description |
|---|---|---|
_assets | uint256 | Exact amount of borrowed tokens to withdraw |
_receiver | address | Address to receive the withdrawn tokens |
_owner | address | Address whose shares are burned |
Returns: number of shares burned (uint256).
Emits: Withdraw event.
<>Source code▼
Excerpt from lending/Vault.vy at 0d726b1:
@external
def withdraw(_assets: uint256, _receiver: address = msg.sender, _owner: address = msg.sender) -> uint256:
"""
@notice Withdraw given amount of asset and burn the corresponding amount of vault shares
@param _assets Amount of assets to withdraw
@param _receiver Receiver of the assets (optional, sender if not specified)
@param _owner Owner who's shares the caller takes. Only can take those if owner gave the approval to the sender. Optional
@return Number of shares burned
"""
total_assets: uint256 = self._total_assets()
assert total_assets - _assets >= MIN_ASSETS or total_assets == _assets, "Need more assets"
shares: uint256 = self._convert_to_shares(_assets, False, total_assets)
if _owner != msg.sender:
allowance: uint256 = self.allowance[_owner][msg.sender]
if allowance != max_value(uint256):
self._approve(_owner, msg.sender, allowance - shares)
controller: IController = self._controller
self._burn(_owner, shares)
extcall ILendController(controller.address).on_borrowed_token_transfer_out(_assets)
tkn.transfer_from(self._borrowed_token, controller.address, _receiver, _assets)
extcall controller.save_rate()
log IERC4626.Withdraw(sender=msg.sender, receiver=_receiver, owner=_owner, assets=_assets, shares=shares)
return shares
▶Example▼
const contract = new Contract('0x2b5a321c3cb1f33e1abecd047c2649d0b4c47eba', VaultAbi, signer)
const tx = await contract.withdraw(
/* _assets: uint256 */ 0n,
/* _receiver: address */ "0x0000000000000000000000000000000000000000",
/* _owner: address */ "0x0000000000000000000000000000000000000000",
)
await tx.wait()
redeem
Vault.redeem(_shares: uint256, _receiver: address, _owner: address) -> uint256Burns an exact number of vault shares and returns the corresponding borrowed tokens.
| Input | Type | Description |
|---|---|---|
_shares | uint256 | Exact number of shares to burn |
_receiver | address | Address to receive the withdrawn tokens |
_owner | address | Address whose shares are burned |
Returns: amount of assets withdrawn (uint256).
Emits: Withdraw event.
<>Source code▼
Excerpt from lending/Vault.vy at 0d726b1:
@external
def redeem(_shares: uint256, _receiver: address = msg.sender, _owner: address = msg.sender) -> uint256:
"""
@notice Burn given amount of shares and give corresponding assets to the user
@param _shares Amount of shares to burn
@param _receiver Optional receiver of the assets
@param _owner Optional owner of the shares. Can only redeem if owner gave approval to the sender
@return Amount of assets sent to the receiver
"""
if _owner != msg.sender:
allowance: uint256 = self.allowance[_owner][msg.sender]
if allowance != max_value(uint256):
self._approve(_owner, msg.sender, allowance - _shares)
total_assets: uint256 = self._total_assets()
assets_to_redeem: uint256 = self._convert_to_assets(_shares, True, total_assets)
assert total_assets - assets_to_redeem >= MIN_ASSETS or total_assets == assets_to_redeem, "Need more assets"
self._burn(_owner, _shares)
controller: IController = self._controller
extcall ILendController(controller.address).on_borrowed_token_transfer_out(assets_to_redeem)
tkn.transfer_from(self._borrowed_token, controller.address, _receiver, assets_to_redeem)
extcall controller.save_rate()
log IERC4626.Withdraw(sender=msg.sender, receiver=_receiver, owner=_owner, assets=assets_to_redeem, shares=_shares)
return assets_to_redeem
# ERC20 methods
@internal
def _approve(_owner: address, _spender: address, _value: uint256):
self.allowance[_owner][_spender] = _value
log IERC20.Approval(owner=_owner, spender=_spender, value=_value)
@internal
# … the remaining implementation is linked above.
▶Example▼
const contract = new Contract('0x2b5a321c3cb1f33e1abecd047c2649d0b4c47eba', VaultAbi, signer)
const tx = await contract.redeem(
/* _shares: uint256 */ 0n,
/* _receiver: address */ "0x0000000000000000000000000000000000000000",
/* _owner: address */ "0x0000000000000000000000000000000000000000",
)
await tx.wait()
ERC4626 — Preview and Limits
totalAssets
Vault.totalAssets() -> uint256: viewReturns the total amount of borrowed tokens managed by the vault, including tokens lent out to borrowers (tracked by the controller's debt accounting).
Returns: total assets (uint256).
<>Source code▼
Excerpt from lending/Vault.vy at 0d726b1:
@external
@view
def totalAssets() -> uint256:
"""
@notice Total assets which can be lent out or be in reserve
@return Total amount of underlying assets managed by the vault
"""
return self._total_assets()
@internal
@view
def _convert_to_shares(_assets: uint256, _is_floor: bool = True,
_total_assets: uint256 = max_value(uint256)) -> uint256:
"""
@param _assets Amount of assets to convert
@param _is_floor If True, round down; if False, round up
@param _total_assets Override for total assets; uses current value if max_value(uint256)
@return Amount of shares equivalent to `_assets`
"""
total_assets: uint256 = _total_assets
if total_assets == max_value(uint256):
total_assets = self._total_assets()
precision: uint256 = self.precision
numerator: uint256 = (self.totalSupply + DEAD_SHARES) * _assets * precision
denominator: uint256 = (total_assets * precision + 1)
if _is_floor:
return numerator // denominator
else:
return math._ceil_div(numerator, denominator)
@internal
@view
def _convert_to_assets(_shares: uint256, _is_floor: bool = True,
_total_assets: uint256 = max_value(uint256)) -> uint256:
"""
@param _shares Amount of shares to convert
# … the remaining implementation is linked above.
▶Example▼
const contract = new Contract('0x2b5a321c3cb1f33e1abecd047c2649d0b4c47eba', VaultAbi, provider)
const result = await contract.totalAssets()
convertToShares
Vault.convertToShares(_assets: uint256) -> uint256: viewReturns the number of vault shares that would be minted for a given amount of assets.
| Input | Type | Description |
|---|---|---|
_assets | uint256 | Amount of assets |
Returns: equivalent shares (uint256).
<>Source code▼
Excerpt from lending/Vault.vy at 0d726b1:
@external
@view
def convertToShares(_assets: uint256) -> uint256:
"""
@notice Returns the amount of shares which the Vault would exchange for the given amount of assets provided
@param _assets Amount of assets to convert
@return Amount of shares equivalent to _assets
"""
return self._convert_to_shares(_assets)
▶Example▼
const contract = new Contract('0x2b5a321c3cb1f33e1abecd047c2649d0b4c47eba', VaultAbi, provider)
const result = await contract.convertToShares(
/* _assets: uint256 */ 0n,
)
convertToAssets
Vault.convertToAssets(_shares: uint256) -> uint256: viewReturns the amount of assets that a given number of shares is worth.
| Input | Type | Description |
|---|---|---|
_shares | uint256 | Amount of shares |
Returns: equivalent assets (uint256).
<>Source code▼
Excerpt from lending/Vault.vy at 0d726b1:
@external
@view
def convertToAssets(_shares: uint256) -> uint256:
"""
@notice Returns the amount of assets that the Vault would exchange for the amount of shares provided
@param _shares Amount of shares to convert
@return Amount of assets equivalent to _shares
"""
return self._convert_to_assets(_shares)
▶Example▼
const contract = new Contract('0x2b5a321c3cb1f33e1abecd047c2649d0b4c47eba', VaultAbi, provider)
const result = await contract.convertToAssets(
/* _shares: uint256 */ 0n,
)
previewDeposit
Vault.previewDeposit(_assets: uint256) -> uint256: viewSimulates a deposit and returns the number of shares that would be minted. Rounds down.
| Input | Type | Description |
|---|---|---|
_assets | uint256 | Amount of assets to deposit |
Returns: shares that would be minted (uint256).
<>Source code▼
Excerpt from lending/Vault.vy at 0d726b1:
@external
@view
def previewDeposit(_assets: uint256) -> uint256:
"""
@notice Returns the amount of shares which can be obtained upon depositing assets
@param _assets Amount of assets to deposit
@return Amount of shares that would be minted for _assets
"""
return self._convert_to_shares(_assets)
▶Example▼
const contract = new Contract('0x2b5a321c3cb1f33e1abecd047c2649d0b4c47eba', VaultAbi, provider)
const result = await contract.previewDeposit(
/* _assets: uint256 */ 0n,
)
previewMint
Vault.previewMint(_shares: uint256) -> uint256: viewSimulates a mint and returns the amount of assets required. Rounds up.
| Input | Type | Description |
|---|---|---|
_shares | uint256 | Number of shares to mint |
Returns: assets required (uint256).
<>Source code▼
Excerpt from lending/Vault.vy at 0d726b1:
@external
@view
def previewMint(_shares: uint256) -> uint256:
"""
@notice Calculate the amount of assets which is needed to exactly mint the given amount of shares
@param _shares Number of shares to mint
@return Amount of assets required to mint exactly _shares
"""
return self._convert_to_assets(_shares, False)
▶Example▼
const contract = new Contract('0x2b5a321c3cb1f33e1abecd047c2649d0b4c47eba', VaultAbi, provider)
const result = await contract.previewMint(
/* _shares: uint256 */ 0n,
)
previewWithdraw
Vault.previewWithdraw(_assets: uint256) -> uint256: viewSimulates a withdrawal and returns the number of shares that would be burned. Rounds up.
| Input | Type | Description |
|---|---|---|
_assets | uint256 | Amount of assets to withdraw |
Returns: shares that would be burned (uint256).
<>Source code▼
Excerpt from lending/Vault.vy at 0d726b1:
@external
@view
def previewWithdraw(_assets: uint256) -> uint256:
"""
@notice Calculate number of shares which gets burned when withdrawing given amount of asset
@param _assets Amount of assets to withdraw
@return Number of shares that would be burned for _assets
"""
return self._convert_to_shares(_assets, False)
▶Example▼
const contract = new Contract('0x2b5a321c3cb1f33e1abecd047c2649d0b4c47eba', VaultAbi, provider)
const result = await contract.previewWithdraw(
/* _assets: uint256 */ 0n,
)
previewRedeem
Vault.previewRedeem(_shares: uint256) -> uint256: viewSimulates a redemption and returns the amount of assets that would be returned. Rounds down.
| Input | Type | Description |
|---|---|---|
_shares | uint256 | Number of shares to redeem |
Returns: assets that would be returned (uint256).
<>Source code▼
Excerpt from lending/Vault.vy at 0d726b1:
@external
@view
def previewRedeem(_shares: uint256) -> uint256:
"""
@notice Calculate the amount of assets which can be obtained by redeeming the given amount of shares
@param _shares Amount of shares to redeem
@return Amount of assets that would be received for _shares
"""
return self._convert_to_assets(_shares)
▶Example▼
const contract = new Contract('0x2b5a321c3cb1f33e1abecd047c2649d0b4c47eba', VaultAbi, provider)
const result = await contract.previewRedeem(
/* _shares: uint256 */ 0n,
)
maxDeposit
Vault.maxDeposit(_receiver: address) -> uint256: viewReturns the maximum amount of assets that can be deposited for a given receiver, considering the supply limit.
| Input | Type | Description |
|---|---|---|
_receiver | address | Receiver address |
Returns: max depositable assets (uint256).
<>Source code▼
Excerpt from lending/Vault.vy at 0d726b1:
@external
@view
def maxDeposit(_receiver: address) -> uint256:
"""
@notice Maximum amount of assets which a given user can deposit
@param _receiver Address of the prospective depositor
@return Maximum depositable asset amount given the current supply cap
"""
max_supply: uint256 = self.maxSupply
if max_supply == max_value(uint256):
return max_supply
else:
assets: uint256 = self._total_assets()
return max(max_supply, assets) - assets
▶Example▼
const contract = new Contract('0x2b5a321c3cb1f33e1abecd047c2649d0b4c47eba', VaultAbi, provider)
const result = await contract.maxDeposit(
/* _receiver: address */ "0x0000000000000000000000000000000000000000",
)
maxMint
Vault.maxMint(_receiver: address) -> uint256: viewReturns the maximum number of shares that can be minted for a given receiver.
| Input | Type | Description |
|---|---|---|
_receiver | address | Receiver address |
Returns: max mintable shares (uint256).
<>Source code▼
Excerpt from lending/Vault.vy at 0d726b1:
@external
@view
def maxMint(_receiver: address) -> uint256:
"""
@notice Return maximum amount of shares which a given user can mint
@param _receiver Address of the prospective minter
@return Maximum mintable share amount given the current supply cap
"""
max_supply: uint256 = self.maxSupply
if max_supply == max_value(uint256):
return max_supply
else:
assets: uint256 = self._total_assets()
return self._convert_to_shares(max(max_supply, assets) - assets)
▶Example▼
const contract = new Contract('0x2b5a321c3cb1f33e1abecd047c2649d0b4c47eba', VaultAbi, provider)
const result = await contract.maxMint(
/* _receiver: address */ "0x0000000000000000000000000000000000000000",
)
maxWithdraw
Vault.maxWithdraw(_owner: address) -> uint256: viewReturns the maximum amount of assets that can be withdrawn by a given owner, limited by available liquidity.
| Input | Type | Description |
|---|---|---|
_owner | address | Owner of the shares |
Returns: max withdrawable assets (uint256).
<>Source code▼
Excerpt from lending/Vault.vy at 0d726b1:
@external
@view
def maxWithdraw(_owner: address) -> uint256:
"""
@notice Maximum amount of assets which a given user can withdraw. Aware of both user's balance and available liquidity
@param _owner Address of the share owner
@return Maximum withdrawable asset amount
"""
return min(
self._convert_to_assets(self.balanceOf[_owner]),
self._available_balance(),
)
▶Example▼
const contract = new Contract('0x2b5a321c3cb1f33e1abecd047c2649d0b4c47eba', VaultAbi, provider)
const result = await contract.maxWithdraw(
/* _owner: address */ "0x0000000000000000000000000000000000000000",
)
maxRedeem
Vault.maxRedeem(_owner: address) -> uint256: viewReturns the maximum number of shares that can be redeemed by a given owner.
| Input | Type | Description |
|---|---|---|
_owner | address | Owner of the shares |
Returns: max redeemable shares (uint256).
<>Source code▼
Excerpt from lending/Vault.vy at 0d726b1:
@external
@view
def maxRedeem(_owner: address) -> uint256:
"""
@notice Calculate maximum amount of shares which a given user can redeem
@param _owner Address of the share owner
@return Maximum redeemable share amount given the owner's balance and available liquidity
"""
return min(
self._convert_to_shares(self._available_balance(), False),
self.balanceOf[_owner],
)
▶Example▼
const contract = new Contract('0x2b5a321c3cb1f33e1abecd047c2649d0b4c47eba', VaultAbi, provider)
const result = await contract.maxRedeem(
/* _owner: address */ "0x0000000000000000000000000000000000000000",
)
pricePerShare
Vault.pricePerShare() -> uint256: viewReturns the current price per share, scaled to 1e18. Increases over time as interest accrues.
Returns: price per share (uint256).
<>Source code▼
Excerpt from lending/Vault.vy at 0d726b1:
@external
@view
def pricePerShare(_is_floor: bool = True) -> uint256:
"""
@notice Method which shows how much one pool share costs in asset tokens if they are normalized to 18 decimals
@dev pricePerShare can decrease if totalSupply reaches zero (e.g., when all shares are burned).
In this case, it resets to the initial value.
@param _is_floor If True, round down; if False, round up
@return Price of one share in asset tokens, normalized to 1e18
"""
supply: uint256 = self.totalSupply
if supply == 0:
return 10**18 // DEAD_SHARES
else:
precision: uint256 = self.precision
numerator: uint256 = 10**18 * (self._total_assets() * precision + 1)
denominator: uint256 = (supply + DEAD_SHARES)
pps: uint256 = 0
if _is_floor:
pps = numerator // denominator
else:
pps = math._ceil_div(numerator, denominator)
assert pps > 0
return pps
▶Example▼
const contract = new Contract('0x2b5a321c3cb1f33e1abecd047c2649d0b4c47eba', VaultAbi, provider)
const result = await contract.pricePerShare()
APR
borrow_apr
Vault.borrow_apr() -> uint256: viewReturns the current annualized borrow rate as reported by the monetary policy, scaled to 1e18.
Returns: borrow APR (uint256).
<>Source code▼
Excerpt from lending/Vault.vy at 0d726b1:
@external
@view
def borrow_apr() -> uint256:
"""
@notice Borrow APR (annualized and 1e18-based)
@return Current annualized borrow rate scaled by 1e18
"""
return staticcall self._amm.rate() * (365 * 86400)
▶Example▼
const contract = new Contract('0x2b5a321c3cb1f33e1abecd047c2649d0b4c47eba', VaultAbi, provider)
const result = await contract.borrow_apr()
lend_apr
Vault.lend_apr() -> uint256: viewReturns the current annualized lending rate — the effective yield lenders earn after accounting for utilization and admin fees, scaled to 1e18.
Returns: lend APR (uint256).
<>Source code▼
Excerpt from lending/Vault.vy at 0d726b1:
@external
@view
def lend_apr() -> uint256:
"""
@notice Lending APR (annualized and 1e18-based), net of admin fees
@return Current annualized lending rate scaled by 1e18, after admin fee deduction
"""
debt: uint256 = staticcall self._controller.total_debt()
if debt == 0:
return 0
gross_apr: uint256 = staticcall self._amm.rate() * (365 * 86400) * debt // self._total_assets()
admin_pct: uint256 = staticcall ILendController(self._controller.address).admin_percentage()
return gross_apr * (c.WAD - admin_pct) // c.WAD
▶Example▼
const contract = new Contract('0x2b5a321c3cb1f33e1abecd047c2649d0b4c47eba', VaultAbi, provider)
const result = await contract.lend_apr()
Vault Info
asset
Vault.asset() -> address: viewReturns the address of the underlying borrowed token (the ERC4626 asset).
Returns: asset address (address).
<>Source code▼
Excerpt from lending/Vault.vy at 0d726b1:
@external
@view
def asset() -> IERC20:
"""
@notice Asset which is the same as borrowed_token
@return Address of the underlying asset token
"""
return self._borrowed_token
@internal
@view
def _total_assets() -> uint256:
return (
staticcall self._controller.available_balance()
+ staticcall self._controller.total_debt()
- staticcall self._controller.admin_fees()
)
▶Example▼
const contract = new Contract('0x2b5a321c3cb1f33e1abecd047c2649d0b4c47eba', VaultAbi, provider)
const result = await contract.asset()
borrowed_token
Vault.borrowed_token() -> address: viewReturns the borrowed token address.
Returns: token address (address).
<>Source code▼
Excerpt from lending/Vault.vy at 0d726b1:
@external
@view
@reentrant
def borrowed_token() -> IERC20:
return self._borrowed_token
_collateral_token: IERC20
# https://github.com/vyperlang/vyper/issues/4721
▶Example▼
const contract = new Contract('0x2b5a321c3cb1f33e1abecd047c2649d0b4c47eba', VaultAbi, provider)
const result = await contract.borrowed_token()
collateral_token
Vault.collateral_token() -> address: viewReturns the collateral token address for this market.
Returns: token address (address).
<>Source code▼
Excerpt from lending/Vault.vy at 0d726b1:
@external
@view
@reentrant
def collateral_token() -> IERC20:
return self._collateral_token
_amm: IAMM
# https://github.com/vyperlang/vyper/issues/4721
▶Example▼
const contract = new Contract('0x2b5a321c3cb1f33e1abecd047c2649d0b4c47eba', VaultAbi, provider)
const result = await contract.collateral_token()
controller
Vault.controller() -> address: viewReturns the LendController address associated with this vault.
Returns: controller address (address).
<>Source code▼
Excerpt from lending/Vault.vy at 0d726b1:
@external
@view
@reentrant
def controller() -> IController:
return self._controller
_factory: IFactory
# https://github.com/vyperlang/vyper/issues/4721
▶Example▼
const contract = new Contract('0x2b5a321c3cb1f33e1abecd047c2649d0b4c47eba', VaultAbi, provider)
const result = await contract.controller()
amm
Vault.amm() -> address: viewReturns the AMM (LLAMMA) address associated with this vault.
Returns: AMM address (address).
<>Source code▼
Excerpt from lending/Vault.vy at 0d726b1:
@external
@view
@reentrant
def amm() -> IAMM:
return self._amm
_controller: IController
# https://github.com/vyperlang/vyper/issues/4721
▶Example▼
const contract = new Contract('0x2b5a321c3cb1f33e1abecd047c2649d0b4c47eba', VaultAbi, provider)
const result = await contract.amm()
factory
Vault.factory() -> address: viewReturns the factory that deployed this vault.
Returns: factory address (address).
<>Source code▼
Excerpt from lending/Vault.vy at 0d726b1:
@external
@view
@reentrant
def factory() -> IFactory:
return self._factory
maxSupply: public(reentrant(uint256))
# ERC20 publics
decimals: public(constant(uint8)) = 18
name: public(reentrant(String[64]))
symbol: public(reentrant(String[34]))
NAME_PREFIX: constant(String[16]) = 'Curve Vault for '
SYMBOL_PREFIX: constant(String[2]) = 'cv'
allowance: public(reentrant(HashMap[address, HashMap[address, uint256]]))
balanceOf: public(reentrant(HashMap[address, uint256]))
totalSupply: public(reentrant(uint256))
precision: uint256
▶Example▼
const contract = new Contract('0x2b5a321c3cb1f33e1abecd047c2649d0b4c47eba', VaultAbi, provider)
const result = await contract.factory()
Admin
set_max_supply
Vault.set_max_supply(_max_supply: uint256)This function is only callable by the admin, which is the factory owner.
Sets the maximum supply cap for the vault. When set, deposits that would push totalSupply above this limit are rejected.
| Input | Type | Description |
|---|---|---|
_max_supply | uint256 | New maximum supply cap (0 = unlimited) |
Emits: SetMaxSupply event.
<>Source code▼
Excerpt from lending/Vault.vy at 0d726b1:
@external
def set_max_supply(_max_supply: uint256):
"""
@notice Set maximum depositable supply
@param _max_supply New maximum supply cap in asset tokens
"""
assert msg.sender == staticcall self._factory.admin() or msg.sender == self._factory.address
self.maxSupply = _max_supply
log IVault.SetMaxSupply(max_supply=_max_supply)
▶Example▼
const contract = new Contract('0x2b5a321c3cb1f33e1abecd047c2649d0b4c47eba', VaultAbi, signer)
const tx = await contract.set_max_supply(
/* _max_supply: uint256 */ 0n,
)
await tx.wait()
admin
Vault.admin() -> address: viewReturns the admin of the vault, which is the owner of the factory contract.
Returns: admin address (address).
<>Source code▼
Excerpt from lending/Vault.vy at 0d726b1:
@external
@view
def admin() -> address:
return staticcall self._factory.admin()
▶Example▼
const contract = new Contract('0x2b5a321c3cb1f33e1abecd047c2649d0b4c47eba', VaultAbi, provider)
const result = await contract.admin()
ERC20
The vault implements the full ERC20 interface for vault share tokens.
transfer
Vault.transfer(_to: address, _value: uint256) -> boolTransfers vault shares to another address.
| Input | Type | Description |
|---|---|---|
_to | address | Recipient address |
_value | uint256 | Amount of shares to transfer |
Returns: success (bool).
Emits: Transfer event.
<>Source code▼
Excerpt from lending/Vault.vy at 0d726b1:
@external
def transfer(_to: address, _value: uint256) -> bool:
"""
@notice Transfer tokens to `_to`.
@param _to The account to transfer tokens to.
@param _value The amount of tokens to transfer.
@return True on success
"""
self._transfer(msg.sender, _to, _value)
return True
▶Example▼
const contract = new Contract('0x2b5a321c3cb1f33e1abecd047c2649d0b4c47eba', VaultAbi, signer)
const tx = await contract.transfer(
/* _to: address */ "0x0000000000000000000000000000000000000000",
/* _value: uint256 */ 0n,
)
await tx.wait()
transferFrom
Vault.transferFrom(_from: address, _to: address, _value: uint256) -> boolTransfers vault shares from one address to another, using the caller's allowance.
| Input | Type | Description |
|---|---|---|
_from | address | Sender address |
_to | address | Recipient address |
_value | uint256 | Amount of shares to transfer |
Returns: success (bool).
Emits: Transfer event.
<>Source code▼
Excerpt from lending/Vault.vy at 0d726b1:
@external
def transferFrom(_from: address, _to: address, _value: uint256) -> bool:
"""
@notice Transfer tokens from one account to another.
@dev The caller needs to have an allowance from account `_from` greater than or
equal to the value being transferred. An allowance equal to the uint256 type's
maximum, is considered infinite and does not decrease.
@param _from The account which tokens will be spent from.
@param _to The account which tokens will be sent to.
@param _value The amount of tokens to be transferred.
@return True on success
"""
allowance: uint256 = self.allowance[_from][msg.sender]
if allowance != max_value(uint256):
self._approve(_from, msg.sender, allowance - _value)
self._transfer(_from, _to, _value)
return True
▶Example▼
const contract = new Contract('0x2b5a321c3cb1f33e1abecd047c2649d0b4c47eba', VaultAbi, signer)
const tx = await contract.transferFrom(
/* _from: address */ "0x0000000000000000000000000000000000000000",
/* _to: address */ "0x0000000000000000000000000000000000000000",
/* _value: uint256 */ 0n,
)
await tx.wait()
approve
Vault.approve(_spender: address, _value: uint256) -> boolApproves an address to spend vault shares on behalf of the caller.
| Input | Type | Description |
|---|---|---|
_spender | address | Address to approve |
_value | uint256 | Allowance amount |
Returns: success (bool).
Emits: Approval event.
<>Source code▼
Excerpt from lending/Vault.vy at 0d726b1:
@external
def approve(_spender: address, _value: uint256) -> bool:
"""
@notice Allow `_spender` to transfer up to `_value` amount of tokens from the caller's account.
@dev Non-zero to non-zero approvals are allowed, but should be used cautiously. The methods
increaseAllowance + decreaseAllowance are available to prevent any front-running that
may occur.
@param _spender The account permitted to spend up to `_value` amount of caller's funds.
@param _value The amount of tokens `_spender` is allowed to spend.
@return True on success
"""
self._approve(msg.sender, _spender, _value)
return True
▶Example▼
const contract = new Contract('0x2b5a321c3cb1f33e1abecd047c2649d0b4c47eba', VaultAbi, signer)
const tx = await contract.approve(
/* _spender: address */ "0x0000000000000000000000000000000000000000",
/* _value: uint256 */ 0n,
)
await tx.wait()
increaseAllowance
Vault.increaseAllowance(_spender: address, _add_value: uint256) -> boolIncreases the allowance for a spender by a given amount.
| Input | Type | Description |
|---|---|---|
_spender | address | Address whose allowance to increase |
_add_value | uint256 | Amount to add to the current allowance |
Returns: success (bool).
Emits: Approval event.
<>Source code▼
Excerpt from lending/Vault.vy at 0d726b1:
@external
def increaseAllowance(_spender: address, _add_value: uint256) -> bool:
"""
@notice Increase the allowance granted to `_spender`.
@dev This function will never overflow, and instead will bound
allowance to MAX_UINT256. This has the potential to grant an
infinite approval.
@param _spender The account to increase the allowance of.
@param _add_value The amount to increase the allowance by.
@return True on success
"""
cached_allowance: uint256 = self.allowance[msg.sender][_spender]
allowance: uint256 = unsafe_add(cached_allowance, _add_value)
# check for an overflow
if allowance < cached_allowance:
allowance = max_value(uint256)
if allowance != cached_allowance:
self._approve(msg.sender, _spender, allowance)
return True
▶Example▼
const contract = new Contract('0x2b5a321c3cb1f33e1abecd047c2649d0b4c47eba', VaultAbi, signer)
const tx = await contract.increaseAllowance(
/* _spender: address */ "0x0000000000000000000000000000000000000000",
/* _add_value: uint256 */ 0n,
)
await tx.wait()
decreaseAllowance
Vault.decreaseAllowance(_spender: address, _sub_value: uint256) -> boolDecreases the allowance for a spender by a given amount.
| Input | Type | Description |
|---|---|---|
_spender | address | Address whose allowance to decrease |
_sub_value | uint256 | Amount to subtract from the current allowance |
Returns: success (bool).
Emits: Approval event.
<>Source code▼
Excerpt from lending/Vault.vy at 0d726b1:
@external
def decreaseAllowance(_spender: address, _sub_value: uint256) -> bool:
"""
@notice Decrease the allowance granted to `_spender`.
@dev This function will never underflow, and instead will bound
allowance to 0.
@param _spender The account to decrease the allowance of.
@param _sub_value The amount to decrease the allowance by.
@return True on success
"""
cached_allowance: uint256 = self.allowance[msg.sender][_spender]
allowance: uint256 = unsafe_sub(cached_allowance, _sub_value)
# check for an underflow
if cached_allowance < allowance:
allowance = 0
if allowance != cached_allowance:
self._approve(msg.sender, _spender, allowance)
return True
▶Example▼
const contract = new Contract('0x2b5a321c3cb1f33e1abecd047c2649d0b4c47eba', VaultAbi, signer)
const tx = await contract.decreaseAllowance(
/* _spender: address */ "0x0000000000000000000000000000000000000000",
/* _sub_value: uint256 */ 0n,
)
await tx.wait()