关于协议:EIP4626-Tokenized-Vault-Standard-金库标准化

29次阅读

共计 4269 个字符,预计需要花费 11 分钟才能阅读完成。

https://eips.ethereum.org/EIP…

Abstract

以下规范容许为代表单个底层 ERC-20 份额的保险库施行规范 API。该规范是 ERC-20 代币的扩大,它提供了存取代币和读取余额的基本功能。

Motivation

代币化保险库不足标准化,导致施行细节多样化。一些不同的例子包含借贷市场、聚合器和具备外在利息的代币。这使得须要合乎许多规范的协定在聚合器或插件层难以集成,并迫使每个协定实现本人的适配器,这些适配器容易出错并节约开发资源。代币化保险库的规范将升高收益保险库的集成工作量,同时创立更加统一和弱小的施行模式。

Code

Events

Deposit 事件:

event Deposit(address indexed caller, address indexed owner, uint256 assets, uint256 shares);

Withdraw 事件:

event Withdraw(
        address indexed caller,
        address indexed receiver,
        address indexed owner,
        uint256 assets,
        uint256 shares
);

IMMUTABLES

ERC20 public immutable asset;

constructor(
    ERC20 _asset,
    string memory _name,
    string memory _symbol
) ERC20(_name, _symbol, _asset.decimals()) {asset = _asset;}

Main Logic

Deposit 函数:function deposit(uint256 assets, address receiver) public virtual returns (uint256 shares) {
    // Check for rounding error since we round down in previewDeposit.
    require((shares = previewDeposit(assets)) != 0, "ZERO_SHARES");

    // Need to transfer before minting or ERC777s could reenter.
    asset.safeTransferFrom(msg.sender, address(this), assets);

    _mint(receiver, shares);

    emit Deposit(msg.sender, receiver, assets, shares);

    afterDeposit(assets, shares);
}

Mint 函数:

function mint(uint256 shares, address receiver) public virtual returns (uint256 assets) {assets = previewMint(shares); // No need to check for rounding error, previewMint rounds up.

    // Need to transfer before minting or ERC777s could reenter.
    asset.safeTransferFrom(msg.sender, address(this), assets);

    _mint(receiver, shares);

    emit Deposit(msg.sender, receiver, assets, shares);

    afterDeposit(assets, shares);
}

Withdraw 函数:

function withdraw(
    uint256 assets,
    address receiver,
    address owner
) public virtual returns (uint256 shares) {shares = previewWithdraw(assets); // No need to check for rounding error, previewWithdraw rounds up.

    if (msg.sender != owner) {uint256 allowed = allowance[owner][msg.sender]; // Saves gas for limited approvals.

        if (allowed != type(uint256).max) allowance[owner][msg.sender] = allowed - shares;
    }

    beforeWithdraw(assets, shares);

    _burn(owner, shares);

    emit Withdraw(msg.sender, receiver, owner, assets, shares);

    asset.safeTransfer(receiver, assets);
}

Redeem 函数:

function redeem(
    uint256 shares,
    address receiver,
    address owner
) public virtual returns (uint256 assets) {if (msg.sender != owner) {uint256 allowed = allowance[owner][msg.sender]; // Saves gas for limited approvals.

        if (allowed != type(uint256).max) allowance[owner][msg.sender] = allowed - shares;
    }

    // Check for rounding error since we round down in previewRedeem.
    require((assets = previewRedeem(shares)) != 0, "ZERO_ASSETS");

    beforeWithdraw(assets, shares);

    _burn(owner, shares);

    emit Withdraw(msg.sender, receiver, owner, assets, shares);

    asset.safeTransfer(receiver, assets);
}

Account Logic

function totalAssets() public view virtual returns (uint256);

function convertToShares(uint256 assets) public view returns (uint256) {
    uint256 supply = totalSupply; // Saves an extra SLOAD if totalSupply is non-zero.

    return supply == 0 ? assets : assets.mulDivDown(supply, totalAssets());
}

function convertToAssets(uint256 shares) public view returns (uint256) {
    uint256 supply = totalSupply; // Saves an extra SLOAD if totalSupply is non-zero.

    return supply == 0 ? shares : shares.mulDivDown(totalAssets(), supply);
}

function previewDeposit(uint256 assets) public view virtual returns (uint256) {return convertToShares(assets);
}

function previewMint(uint256 shares) public view virtual returns (uint256) {
    uint256 supply = totalSupply; // Saves an extra SLOAD if totalSupply is non-zero.

    return supply == 0 ? shares : shares.mulDivUp(totalAssets(), supply);
}

function previewWithdraw(uint256 assets) public view virtual returns (uint256) {
    uint256 supply = totalSupply; // Saves an extra SLOAD if totalSupply is non-zero.

    return supply == 0 ? assets : assets.mulDivUp(supply, totalAssets());
}

function previewRedeem(uint256 shares) public view virtual returns (uint256) {return convertToAssets(shares);
}

/*///////////////////////////////////////////////////////////////
                 DEPOSIT/WITHDRAWAL LIMIT LOGIC
//////////////////////////////////////////////////////////////*/

function maxDeposit(address) public view virtual returns (uint256) {return type(uint256).max;
}

function maxMint(address) public view virtual returns (uint256) {return type(uint256).max;
}

function maxWithdraw(address owner) public view virtual returns (uint256) {return convertToAssets(balanceOf[owner]);
}

function maxRedeem(address owner) public view virtual returns (uint256) {return balanceOf[owner];
}

Hooks Logic

function beforeWithdraw(uint256 assets, uint256 shares) internal virtual {}

function afterDeposit(uint256 assets, uint256 shares) internal virtual {}

参考文章

https://ethereum-magicians.or…
https://github.com/Rari-Capit…

正文完
 0