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...