ERC4626 协议是一种用于代币化保险库的标准,它可以优化和统一收益保险库的技术参数。
ERC4626 协议是一种用于代币化保险库的标准,它可以优化和统一收益保险库的技术参数。收益保险库是指使用不同策略来为用户提供最佳收益的合约,例如借贷市场、聚合器或本身具有利息的代币。ERC4626 协议提供了一个标准的 API,用于表示单个底层 ERC-20 代币的收益保险库份额。
用户通过存入 ERC20 Token,从而获取一定比例的 vToken。在erc20 Token 存入的过程中,会在一定的时间内产生收益。在收益到期后,用户可以通过持有的vToken个数,获得一定比例的收益汇报。
此外ERC4626继承了ERC20,具有ERC20所具有的所有功能,而且还必须实现
IERC20Metadata
接口。举个例子来理解这个系统, ERC4626的基础代币可以比作是 黄金(_asset), 而通过存入 黄金来获取钞票(shares),既可以通过存入黄金来获取
shares
,也可以通过shares
兑换出黄金。例子不是很准确,但是可以初步了解这是一个什么东西。
源代码:链接。
接口中定义的函数如下:
主合约:
IERC20 private immutable _asset;
这是该金库 vault的基础代币,相当于黄金。
function _tryGetAssetDecimals(IERC20 asset_) private view returns (bool, uint8)
该函数的作用是获取 基础代币的精度值,通过 staticcall
来调用assert_
的 decimals()
函数获取该角度值,如果调用成功则返回(true, uint8(returnedDecimals))
,否则(false, 0)
。
function maxDeposit(address) public view virtual returns (uint256)
function maxMint(address) public view virtual returns (uint256)
查询指定地址可以存入/铸造最多的数目,二者都返回type(uint256).max
。
function maxRedeem(address owner) public view virtual returns (uint256)
查询可以赎回的最大资产,这里返回的是vToken
的数目。
function _convertToShares(uint256 assets, Math.Rounding rounding) internal view virtual returns (uint256) {
return assets.mulDiv(totalSupply() + 10 ** _decimalsOffset(), totalAssets() + 1, rounding);
}
将资产转化为shares
,可以理解为黄金兑换为钞票,这步计算可以抽象看作是
(assets * (totalSupply() + 10 ** _decimalsOffset())) / (totalAssets() + 1)
function _convertToAssets(uint256 shares, Math.Rounding rounding) internal view virtual returns (uint256) {
return shares.mulDiv(totalAssets() + 1, totalSupply() + 10 ** _decimalsOffset(), rounding);
}
将shares
转化为资产,可以理解为钞票兑换为黄金,这步计算可以抽象看作是:
(shares * ((totalAssets() + 1) / (totalSupply() + 10 ** _decimalsOffset())))
function previewDeposit(uint256 assets) public view virtual returns (uint256) {
return _convertToShares(assets, Math.Rounding.Floor);
}
该函数的功能是此时计算出指定的资产可以兑换多少shares
。
function previewMint(uint256 shares) public view virtual returns (uint256) {
return _convertToAssets(shares, Math.Rounding.Ceil);
}
该函数的功能是此时计算指定的shares
可以兑换成多少资产。
function previewWithdraw(uint256 assets) public view virtual returns (uint256) {
return _convertToShares(assets, Math.Rounding.Ceil);
}
该函数的功能是此时计算指定的shares
可以兑换成多少资产。和previewMint()
函数极其相似。
function _deposit(address caller, address receiver, uint256 assets, uint256 shares) internal virtual {
SafeERC20.safeTransferFrom(_asset, caller, address(this), assets);
_mint(receiver, shares);
emit Deposit(caller, receiver, assets, shares);
}
这是存入资产的内部函数,通过SafeERC20
的库函数,完成caller
向address(this)
转移_asset
代币操作。
function deposit(uint256 assets, address receiver) public virtual returns (uint256)
外部的存款函数,功能是msg.sender
往该 vault存入执行数额的资产,并将兑换出的vToken
发送到receiver
地址,通过mint()
函数,铸币数量是根据此时金库状态计算的uint256 assets = previewMint(shares)
。
function _withdraw(
address caller,
address receiver,
address owner,
uint256 assets,
uint256 shares
) internal virtual {
if (caller != owner) {
_spendAllowance(owner, caller, shares);
}
_burn(owner, shares);
SafeERC20.safeTransfer(_asset, receiver, assets);
emit Withdraw(caller, receiver, owner, assets, shares);
}
该功能是取出资产的内部函数,要求调用者msg.sender
必须是owner
,或者msg.sender
被owner
授权。销毁owner
数量为shares
的vToken,并从金库向receiver
转移_asset
代币。
function withdraw(uint256 assets, address receiver, address owner) public virtual returns (uint256) {
uint256 maxAssets = maxWithdraw(owner);
if (assets > maxAssets) {
revert ERC4626ExceededMaxWithdraw(owner, assets, maxAssets);
}
uint256 shares = previewWithdraw(assets);
_withdraw(_msgSender(), receiver, owner, assets, shares);
return shares;
}
外部的取款函数,实现逻辑是调用内部的_withdraw()
函数。参数是传入待取出的资产数量。
function redeem(uint256 shares, address receiver, address owner) public virtual returns (uint256) {
uint256 maxShares = maxRedeem(owner);
if (shares > maxShares) {
revert ERC4626ExceededMaxRedeem(owner, shares, maxShares);
}
uint256 assets = previewRedeem(shares);
_withdraw(_msgSender(), receiver, owner, assets, shares);
return assets;
}
这也是一个取款函数,内部调用的也是_withdraw()
函数,但是和withdraw()
函数不同的点在于,参数传入的是shares
。
ERC4626 协议是一种用于代币化保险库的标准,它可以优化和统一收益保险库的技术参数。它为单个底层 ERC-20 代币的收益保险库提供了一个标准的 API,并为存入、取出、铸造、赎回等操作提供了基本功能。它在 DeFi 领域有很多潜在的应用场景,可以为用户提供更多的选择和便利。它也有助于推动收益保险库的发展和创新,为 DeFi 生态系统增加更多的价值。
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!