ERC20

此模块提供了与 ERC20 合约相关的接口、预设和实用程序。

有关 ERC20 的概述,请阅读我们的 ERC20 指南

核心

IERC20

use openzeppelin_token::erc20::interface::IERC20;

EIP-20 中定义的 IERC20 标准的接口。

函数

total_supply() → u256 external

返回存在的 Token 总量。

balance_of(account: ContractAddress) → u256 external

返回 account 拥有的 Token 数量。

allowance(owner: ContractAddress, spender: ContractAddress) → u256 external

返回通过 transfer_from 允许 spender 代表 owner 消费的剩余 Token 数量。 默认为零。

当调用 approvetransfer_from 时,此值会发生变化。

transfer(recipient: ContractAddress, amount: u256) → bool external

amount 数量的 Token 从调用者的 Token 余额转移到 to。 成功时返回 true,否则回退。

发出 Transfer 事件。

transfer_from(sender: ContractAddress, recipient: ContractAddress, amount: u256) → bool external

使用授权机制将 amount 数量的 Token 从 sender 转移到 recipient。 然后从调用者的授权中扣除 amount。 成功时返回 true,否则回退。

发出 Transfer 事件。

approve(spender: ContractAddress, amount: u256) → bool external

设置 amount 作为 spender 对调用者的 Token 的授权。 成功时返回 true,否则回退。

发出 Approval 事件。

事件

Transfer(from: ContractAddress, to: ContractAddress, value: u256) event

value 数量的 Token 从一个地址 (from) 移动到另一个地址 (to) 时触发。

请注意,value 可能为零。

Approval(owner: ContractAddress, spender: ContractAddress, value: u256) event

当设置 spenderowner 的授权时触发。 value 是新的授权。

IERC20Metadata

use openzeppelin_token::erc20::interface::IERC20Metadata;

EIP-20 中可选元数据函数的接口。

函数

name() → ByteArray external

返回 Token 的名称。

symbol() → ByteArray external

返回 Token 的交易代码。

decimals() → u8 external

返回 Token 使用的小数位数 - 例如,8 表示将 Token 金额除以 100000000 以获得其用户可读的表示形式。

例如,如果 decimals 等于 2,则 505 个 Token 的余额应向用户显示为 5.05 (505 / 10 ** 2)。

Token 通常选择 18 的值,模仿 Ether 和 Wei 之间的关系。 这是此函数返回的默认值。 要创建自定义的小数位实现,请参阅 自定义小数位数

此信息仅用于_显示_目的:它不会以任何方式影响合约的任何算术。

ERC20Component

use openzeppelin_token::erc20::ERC20Component;

扩展 IERC20IERC20Metadata 的 ERC20 组件。

请参阅 Hooks 以了解如何使用 hook。

钩子

钩子是一些函数,它们的实现可以扩展组件源代码的功能。每个 使用 ERC20Component 的合约都应提供 ERC20HooksTrait 的实现。 对于基本的 Token 合约,一个 必须提供没有逻辑的空实现。

您可以使用 openzeppelin_token::erc20::ERC20HooksEmptyImpl,它已经作为库的一部分提供 为此目的。

before_update(ref self: ContractState, from: ContractAddress, recipient: ContractAddress, amount: u256) hook

update 函数的开头,在任何其他逻辑之前执行的函数。

after_update(ref self: ContractState, from: ContractAddress, recipient: ContractAddress, amount: u256) hook

update 函数末尾执行的函数。

可嵌入的函数

total_supply(@self: ContractState) → u256 external

请参阅 IERC20::total_supply

balance_of(@self: ContractState, account: ContractAddress) → u256 external

请参阅 IERC20::balance_of

allowance(@self: ContractState, owner: ContractAddress, spender: ContractAddress) → u256 external

请参阅 IERC20::allowance

transfer(ref self: ContractState, recipient: ContractAddress, amount: u256) → bool external

请参阅 IERC20::transfer

要求:

  • recipient 不能是零地址。

  • 调用者必须至少有 amount 的余额。

transfer_from(ref self: ContractState, sender: ContractAddress, recipient: ContractAddress, amount: u256) → bool external

请参阅 IERC20::transfer_from

要求:

  • sender 不能是零地址。

  • sender 必须至少有 amount 的余额。

  • recipient 不能是零地址。

  • 调用者必须至少具有 amountsender Token 的授权。

approve(ref self: ContractState, spender: ContractAddress, amount: u256) → bool external

请参阅 IERC20::approve

要求:

  • spender 不能是零地址。

name() → ByteArray external

请参阅 IERC20Metadata::name

symbol() → ByteArray external

请参阅 IERC20Metadata::symbol

decimals() → u8 external

totalSupply(self: @ContractState) → u256 external

支持 Cairo v0 约定,即以 camelCase 编写外部方法,如 这里 中所述。

balanceOf(self: @ContractState, account: ContractAddress) → u256 external

请参阅 IERC20::balance_of.

支持 Cairo v0 约定,即以 camelCase 编写外部方法,如 这里 中所述。

transferFrom(ref self: ContractState, sender: ContractAddress, recipient: ContractAddress) → bool external

请参阅 IERC20::transfer_from

支持 Cairo v0 约定,即以 camelCase 编写外部方法,如 这里 中所述。

permit(ref self: ContractState, owner: ContractAddress, spender: ContractAddress, amount: u256, deadline: u64, signature: Span<felt252>) → bool external

在验证签名后,设置 amount 作为 spenderownerToken 的授权。

要求:

  • owner 是已部署的帐户合约。

  • spender 不是零地址。

  • deadline 不是过去的 UNIX 时间戳。

  • signature 是可以使用对 owner 帐户的调用来验证的有效签名。

  • signature 必须使用 owner 的当前 nonce。

发出 Approval 事件。 每次成功调用都会使 owner 的 nonce 增加 1。

nonces(self: @ContractState, owner: ContractAddress) → felt252 external

返回 owner 的当前 nonce。 只要为 permit 调用生成签名,就必须包含 nonce 值。

DOMAIN_SEPARATOR(self: @ContractState) → felt252 external

返回用于生成 permit 签名的消息哈希的域分隔符。 域哈希逻辑遵循 SNIP12 标准。

snip12_metadata(self: @ContractState) → (felt252, felt252) external

返回用于生成许可签名的消息哈希的域名和版本。

返回的元组包含:

内部函数

initializer(ref self: ContractState, name: ByteArray, symbol: ByteArray) internal

通过设置 Token 名称和符号来初始化合约。 这应在合约的构造函数中使用。

mint(ref self: ContractState, recipient: ContractAddress, amount: u256) internal

创建 amount 数量的 Token 并将其分配给 recipient

发出一个 Transfer 事件,其中 from 为零地址。

要求:

  • recipient 不能是零地址。

burn(ref self: ContractState, account: ContractAddress, amount: u256) internal

销毁 account 中的 amount 数量的 Token。

发出一个 Transfer 事件,其中 to 设置为零地址。

要求:

  • account 不能是零地址。

update(ref self: ContractState, from: ContractAddress, to: ContractAddress, amount: u256) internal

amount 数量的 Token 从 from 转移到 to,或者在 from (或 to) 是零地址的情况下,可以选择铸造 (或销毁)。

注意:可以使用 ERC20HooksTrait 扩展此函数,以添加 在转移、铸造或销毁之前和/或之后的功能。

发出 Transfer 事件。

_transfer(ref self: ContractState, sender: ContractAddress, recipient: ContractAddress, amount: u256) internal

amount 数量的 Token 从 from 移动到 to

此内部函数不检查访问权限,但可以用作构建块,例如,实现自动 Token 费用、削减机制等。

发出 Transfer 事件。

要求:

  • from 不能是零地址。

  • to 不能是零地址。

  • from 必须至少有 amount 的余额。

_approve(ref self: ContractState, owner: ContractAddress, spender: ContractAddress, amount: u256) internal

设置 amount 作为 spenderownerToken 的授权。

此内部函数不检查访问权限,但可以用作构建块,例如,代表其他地址实施自动授权。

发出 Approval 事件。

要求:

  • owner 不能是零地址。

  • spender 不能是零地址。

_spend_allowance(ref self: ContractState, owner: ContractAddress, spender: ContractAddress, amount: u256) internal

根据花费的 amount 更新 ownerspender 的授权。

如果授权无限,此内部函数不会更新授权值。

可能会发出 Approval 事件。

事件

Transfer(from: ContractAddress, to: ContractAddress, value: u256) event

请参阅 IERC20::Transfer

Approval(owner: ContractAddress, spender: ContractAddress, value: u256) event

请参阅 IERC20::Approval

扩展

IERC20Permit

use openzeppelin_token::erc20::interface::IERC20Permit;

ERC20Permit 标准的接口,支持如 EIP-2612 中定义的无 Gas Token 授权。

函数

permit(owner: ContractAddress, spender: ContractAddress, amount: u256, deadline: u64, signature: Span<felt252>) external

在验证签名后,设置 amount 作为 spenderownerToken 的授权。

nonces(owner: ContractAddress) → felt252 external

返回 owner 的当前 nonce。 只要为 permit 调用生成签名,就必须包含 nonce 值。

DOMAIN_SEPARATOR() → felt252 external

返回用于生成 permit 签名的消息哈希的域分隔符。 域哈希逻辑遵循 SNIP12 标准。

IERC4626

use openzeppelin_token::erc20::extensions::erc4626::interface::IERC4626;

EIP-4626 中定义的 IERC4626 标准的接口。

函数

asset() → ContractAddress external

返回用于保险库进行核算、存款和取款的基础 Token 的地址。

要求:

  • 必须是 ERC20 Token 合约。

  • 绝对不能发生 panic。

total_assets() → u256 external

返回由金库“管理”的基础资产的总量。

要求:

  • 应该包括收益产生的任何复利。

  • 必须包括对金库资产收取的任何费用。

  • 绝对不能发生 panic。

convert_to_shares(assets: u256) → u256 external

返回无论滑点或费用如何,金库将交换所提供的 assets 金额的份额数量。

要求:

  • 不得包括对金库资产收取的任何费用。

  • 不得显示任何取决于调用者的变化。

  • 在执行实际交换时,不得反映滑点或其他链上条件。

  • 除非由于输入非常大导致整数溢出,否则不能发生 panic。

  • 必须向下舍入到 0。

注意:此计算可能不反映“每个用户”的每股价格,而应 反映“平均用户”的每股价格,这意味着平均用户应该期望 在交易到和从交易时看到。

convert_to_assets(shares: u256) → u256 external

返回无论滑点或费用如何,金库将交换所提供的 shares 金额的资产金额。

要求:

  • 不得包括对金库资产收取的任何费用。

  • 不得显示任何取决于调用者的变化。

  • 在执行实际交换时,不得反映滑点或其他链上条件。

  • 除非由于输入非常大导致整数溢出,否则不能发生 panic。

  • 必须向下舍入到 0。

注意:此计算可能不反映“每个用户”的每股价格,而应 反映“平均用户”的每股价格,这意味着平均用户 应该期望在交易到和从交易时看到。

max_deposit(receiver: ContractAddress) → u256 external

返回可以通过存款调用存入金库的 receiver 的基础资产最大金额。

要求:

  • 如果接收者受到某些存款限制,则必须返回一个有限的值。

  • 如果可以存入的最大资产金额没有限制,则必须返回 2 ** 256 - 1。

  • 绝对不能发生 panic。

preview_deposit(assets: u256) → u256 external

允许链上或链下用户模拟其在当前链上存款的影响 区块,鉴于当前的链上条件。

要求:

  • 必须返回与金库份额的精确数量尽可能接近且不超过此数量 在同一次交易中进行存款调用时铸造,即如果同一次交易中调用 IERC4626::deposit,则 IERC4626::deposit 应该返回与 preview_deposit 相同或更多的份额。

  • 不得考虑像 IERC4626::max_deposit 返回的那些存款限制,并且应始终 就像存款会被接受一样,无论用户是否有足够的 Token 已批准等。

  • 必须包括存款费用。 集成商应了解存款的存在 费用。

  • 绝对不能发生 panic。

注意:IERC4626::convert_to_sharespreview_deposit 之间的任何不利差异 应被视为份额价格的滑点或其他类型的条件,这意味着 存款人将因存款而损失资产。

[[IERC4626-要求:

  • 必须发送 IERC4626::Deposit 事件。

  • 可以支持一个额外的流程,其中底层 token 在铸造执行之前由 Vault 合约拥有,并在铸造期间被计算在内。

  • 如果无法铸造所有份额(由于达到存款限制、滑点、用户未向 Vault 合约批准足够的底层 token 等),则必须 panic。

大多数实现都需要预先批准 Vault 的底层资产 token。

max_withdraw(owner: ContractAddress) → u256 external

返回可以通过 withdraw 调用从 Vault 中的 owner 余额中提取的底层资产的最大数量。

要求:

  • 如果 owner 受到某些提款限制或时间锁定的约束,则必须返回一个有限的值。

  • 禁止 panic。

preview_withdraw(assets: u256) → u256 external

允许链上或链下用户模拟他们在当前区块提款的效果,给定当前的链上条件。

要求:

  • 必须返回尽可能接近且不少于在同一交易中 withdraw 调用中将被销毁的确切 Vault 份额数量,即如果 IERC4626::withdraw 在同一交易中被调用,则应返回与 preview_withdraw 相同或更少的份额。

  • 不得考虑像 IERC4626::max_withdraw 返回的提款限制,并且应始终表现得好像提款将被接受,无论用户是否有足够的份额等。

  • 必须包括提款费用。集成商应注意提款费用的存在。

  • 禁止 panic。

IERC4626::convert_to_sharespreview_withdraw 之间的任何不利差异都应被视为份额价格的滑点或某种其他类型的条件,这意味着存款人将因存款而损失资产。

withdraw(assets: u256, receiver: ContractAddress, owner: ContractAddress) → u256 external

从 owner 处销毁份额,并将精确数量的底层 token assets 发送到 receiver。

要求:

  • 必须发送 IERC4626::Withdraw 事件。

  • 可以支持一个额外的流程,其中底层 token 在 withdraw 执行之前由 Vault 合约拥有,并在 withdraw 期间被计算在内。

  • 如果无法提取所有 assets (由于达到提款限制、滑点、owner 没有足够的份额等),则必须 revert。

某些实现将需要在执行提款之前预先向 Vault 发出请求。 这些方法应单独执行。

max_redeem(owner: ContractAddress) → u256 external

返回可以通过 redeem 调用从 Vault 中的 owner 余额中赎回的最大 Vault 份额数量。

要求:

  • 如果 owner 受到某些提款限制或时间锁定的约束,则必须返回一个有限的值。

  • 如果 owner 不受任何提款限制或时间锁定的约束,则必须返回 ERC20::balance_of(owner)

  • 禁止 panic。

preview_redeem(shares: u256) → u256 external

允许链上或链下用户模拟他们在当前区块赎回的效果,给定当前的链上条件。

要求:

  • 必须返回尽可能接近且不多于在同一交易中 redeem 调用中将被提取的确切资产数量,即如果 IERC4626::redeem 在同一交易中被调用,则应返回与 preview_redeem 相同或更多的资产。

  • 不得考虑像 IERC4626::max_redeem 返回的赎回限制,并且应始终表现得好像赎回将被接受,无论用户是否有足够的份额等。

  • 必须包括提款费用。集成商应注意提款费用的存在。

  • 禁止 panic。

IERC4626::convert_to_assetspreview_redeem 之间的任何不利差异都应被视为份额价格的滑点或某种其他类型的条件,这意味着存款人将因赎回而损失资产。

redeem(shares: u256, receiver: ContractAddress, owner: ContractAddress) → u256 external

从 owner 处销毁精确数量的份额 shares,并将底层 token assets 发送到 receiver。

要求:

  • 必须发送 IERC4626::Withdraw 事件。

  • 可以支持一个额外的流程,其中底层 token 在 redeem 执行之前由 Vault 合约拥有,并在 redeem 期间被计算在内。

  • 如果无法赎回所有 shares (由于达到提款限制、滑点、owner 没有足够的份额等),则必须 revert。

某些实现将需要在执行提款之前预先向 Vault 发出请求。 这些方法应单独执行。

事件

Deposit(sender: ContractAddress, owner: ContractAddress, assets: u256, shares: u256) event

senderassets 交换 shares 并将这些 shares 转移到 owner 时发出。

Withdraw(sender: ContractAddress, receiver: ContractAddress, owner: ContractAddress, assets: u256, shares: u256) event

senderowner 拥有的 shares 交换 assets 并将这些 assets 转移到 receiver 时发出。

ERC4626Component

use openzeppelin_token::erc20::extensions::erc4626::ERC4626Component;

ERC20 的扩展,实现了 IERC4626 接口,该接口允许铸造和销毁 "shares",以换取底层的 "asset"。 该组件利用 traits 来配置费用、限制和小数位数。

注意钩子。从钩子调用外部合约时必须特别小心。在这种情况下,请考虑实施重入保护。例如,在 withdraw 流程中,withdraw_limit 在调用 before_withdraw 钩子*之前*进行检查。如果此钩子执行重新进入调用,再次调用 withdraw,则对 withdraw_limit 的后续检查将在第一次提款的核心逻辑(例如,销毁份额和转移资产)执行之前完成。这可能导致绕过提款约束或耗尽资金。

不可变配置

UNDERLYING_DECIMALS: u128 constant

应与底层资产的小数位数匹配。 默认值为 18

DECIMALS_OFFSET: u128 constant

对应于 UNDERLYING_DECIMALS 和 vault 小数位数之间的表示偏移量。 偏移量越大,攻击者执行通货膨胀攻击的成本就越高。

validate() internal

验证合约配置的给定实现。

要求:

  • UNDERLYING_DECIMALS + DECIMALS_OFFSET 不能超过 255 (max u8)。

此函数由合约的 initializer 调用。

钩子

钩子是实现可以扩展组件源代码功能的函数。 每个使用 ERC4626Component 的合约都应提供 ERC4626HooksTrait 的实现。 对于基本 token 合约,必须提供没有逻辑的空实现。

您可以使用 openzeppelin_token::erc20::extensions::erc4626::ERC4626HooksEmptyImpl,它已经作为库的一部分提供用于此目的。

FeeConfigTrait

预计在合约级别定义的费用的调整。 默认为无进入或退出费用。

FeeConfigTrait 钩子直接进入 ERC4626 组件的 preview 方法。 如果实际(预览)操作发生在同一交易中(根据 EIP-4626 规范),则 preview 方法必须返回尽可能接近精确数量的份额或资产。 所有操作都使用其相应的 preview 方法作为正在移动的资产或份额的值。 因此,在 FeeConfigTrait 中调整操作的资产会相应地调整 preview 操作和实际操作中的资产(或要转换为份额的资产)。
要转移费用,此 trait 需要与 ERC4626Component::ERC4626Hooks 协调。 请参阅 ERC4626FeesMock example

adjust_deposit(ref self: ContractState, assets: u256, shares: u256) hook

调整 preview_deposit 中的存款以考虑入场费。 入场费应在 after_deposit 钩子中转移。

adjust_mint(ref self: ContractState, assets: u256, shares: u256) hook

调整 preview_mint 中的存款以考虑入场费。 入场费应在 after_deposit 钩子中转移。

adjust_withdraw(ref self: ContractState, assets: u256, shares: u256) hook

调整 preview_withdraw 中的提款以考虑退场费。 退场费应在 before_withdraw 钩子中转移。

adjust_redeem(ref self: ContractState, assets: u256, shares: u256) hook

调整 preview_redeem 中的提款以考虑退场费。 退场费应在 before_withdraw 钩子中转移。

LimitConfigTrait

设置目标交换类型的限制,并且预计在合约级别定义。这些限制直接对应于 max_<OPERATION>,即 deposit_limitmax_deposit

EIP-4626 规范指出,max_<OPERATION> 方法必须考虑所有全局和用户特定的限制。如果操作被禁用(即使是暂时的),则相应的限制必须为 0,并且不得 panic。

deposit_limit(ref self: ContractState, receiver: ContractAddress) -> Option<u256> hook

允许的最大存款额。

默认为 (Option::None) 2 ** 256 - 1。

mint_limit(ref self: ContractState, receiver: ContractAddress) -> Option<u256> hook

允许的最大铸币额。

默认为 (Option::None) 2 ** 256 - 1。

withdraw_limit(ref self: ContractState, owner: ContractAddress) -> Option<u256> hook

允许的最大提款额。

默认为 (Option::None) 从份额转换的 owner 的全部资产余额。

redeem_limit(ref self: ContractState, owner: ContractAddress) -> Option<u256> hook

允许的最大赎回额。

默认为 (Option::None) owner 的全部资产余额。

ERC4626HooksTrait

允许合约将逻辑挂钩到存款和提款交易中。 这是合约可以转移费用的地方。

ERC4626 preview 方法必须包含任何入场费或退场费。 AdjustFeesTrait 将相应地调整这些值;因此,如果使用合约强制执行入场费或退场费,则必须在 AdjustFeesTrait 中设置费用。 请参阅 ERC4626FeesMock example

before_withdraw(ref self: ContractState, assets: u256, shares: u256) hook

挂钩到 _withdraw

在销毁份额和转移资产之前执行逻辑。

after_withdraw(ref self: ContractState, assets: u256, shares: u256) hook

挂钩到 _withdraw

在销毁份额和转移资产之后执行逻辑。

before_deposit(ref self: ContractState, assets: u256, shares: u256) hook

挂钩到 _deposit

在转移资产和铸造份额之前执行逻辑。

after_deposit(ref self: ContractState, assets: u256, shares: u256) hook

挂钩到 _deposit

在转移资产和铸造份额之后执行逻辑。

可嵌入的函数

asset(self: @ContractState) → ContractAddress external

返回用于 Vault 进行核算、存款和取款的底层 token 的地址。

total_assets(self: @ContractState) → u256 external

返回由 Vault "管理" 的底层资产的总量。

convert_to_shares(self: @ContractState, assets: u256) → u256 external

返回 Vault 将为所提供的资产数量交换的份额数量,而无需考虑滑点或费用。

按照 EIP-4626 规范,只有在输入过大导致溢出时,才可能 panic。

convert_to_assets(self: @ContractState, shares: u256) → u256 external

返回 Vault 将为所提供的份额数量交换的资产数量,而无需考虑滑点或费用。

按照 EIP-4626 规范,只有在输入过大导致溢出时,才可能 panic。

max_deposit(self: @ContractState, receiver: ContractAddress) → u256 external

返回可以通过 deposit 调用存入 Vault 以供 receiver 使用的底层资产的最大数量。

默认的最大存款值为 2 ** 256 - 1。

可以通过在 LimitConfigTrait::deposit_limit 中定义自定义逻辑来更改此值。

preview_deposit(self: @ContractState, assets: u256) → u256 external

允许链上或链下用户模拟他们在当前区块的存款效果,给定当前的链上条件。

默认的存款预览值是全部份额。 例如,可以通过在 LimitConfigTrait::adjust_deposit 中定义自定义逻辑来更改此值,以考虑费用。

此方法必须包含入场费才能符合 EIP-4626 规范。

deposit(ref self: ContractState, assets: u256, receiver: ContractAddress) → u256 external

通过存入精确数量的底层 token assets,向 receiver 铸造 Vault 份额。 返回新铸造的份额数量。

要求:

  • assets 小于或等于 receiver 的最大存款额。

发送 Deposit 事件。

max_mint(self: @ContractState, receiver: ContractAddress) → u256 external

返回可以通过 mint 调用为 receiver 铸造的最大 Vault 份额数量。

默认的最大铸币值为 2 ** 256 - 1。

可以通过在 LimitConfigTrait::mint_limit 中定义自定义逻辑来更改此值。

preview_mint(self: @ContractState, shares: u256) → u256 external

允许链上或链下用户模拟他们在当前区块的铸币效果,给定当前的链上条件。

默认的铸币预览值是全部资产。 例如,可以通过在 LimitConfigTrait::adjust_mint 中定义自定义逻辑来更改此值,以考虑费用。

此方法必须包含入场费才能符合 EIP-4626 规范。

mint(self: @ContractState, shares: u256, receiver: ContractAddress) → u256 external

通过存入底层 token 的数量,向 receiver 铸造精确数量的 Vault shares。 返回存入的资产数量。

要求:

  • shares 小于或等于 receiver 的最大份额数量。

发送 Deposit 事件。

max_withdraw(self: @ContractState, owner: ContractAddress) → u256 external

返回可以通过 withdraw 调用从 Vault 中的 owner 余额中提取的底层资产的最大数量。

默认的最大提款值是 owner 的全部资产余额(从份额转换而来)。 可以通过在 LimitConfigTrait::withdraw_limit 中定义自定义逻辑来更改此值。

使用自定义限制时,最大提款额将是自定义限制本身或 owner 的全部资产余额,以较小者为准。

preview_withdraw(self: @ContractState, assets: u256) → u256 external

允许链上或链下用户模拟他们在当前区块的提款效果,给定当前的链上条件。

默认的提款预览值是全部份额。 例如,可以通过在 LimitConfigTrait::adjust_withdraw 中定义自定义逻辑来更改此值,以考虑费用。

此方法必须包含退场费才能符合 EIP-4626 规范。

withdraw(self: @ContractState, assets: u256, receiver: ContractAddress, owner: ContractAddress) → u256 external

owner 处销毁份额,并将精确数量的底层 token assets 发送到 receiver

要求:

  • assets 小于或等于 owner 的最大提款额。

发送 Withdraw 事件。

max_redeem(self: @ContractState, owner: ContractAddress) → u256 external

返回可以通过 redeem 调用从 Vault 中的 owner 余额中赎回的最大 Vault 份额数量。

默认的最大赎回值是 owner 的全部资产余额。 可以通过在 LimitConfigTrait::redeem_limit 中定义自定义逻辑来更改此值。

使用自定义限制时,最大赎回额将是自定义限制本身或 owner 的全部资产余额,以较小者为准。

preview_redeem(self: @ContractState, shares: u256) → u256 external

允许链上或链下用户模拟他们在当前区块的赎回效果,给定当前的链上条件。

默认的赎回预览值是全部资产。 例如,可以通过在 LimitConfigTrait::adjust_redeem 中定义自定义逻辑来更改此值,以考虑费用。

此方法必须包含退场费才能符合 EIP-4626 规范。

redeem(self: @ContractState, shares: u256, receiver: ContractAddress, owner: ContractAddress) → u256 external

owner 处销毁精确数量的 shares,并将底层 token 的资产发送到 receiver

要求:

  • shares 小于或等于 owner 的最大赎回额。

发送 Withdraw 事件。

name(self: @ContractState) → ByteArray external

返回 token 的名称。

symbol(self: @ContractState) → ByteArray external

返回 token 的交易代码,通常是名称的缩写版本。

decimals(self: @ContractState) → u8 external

返回累积的小数位数,其中包括 UNDERLYING_DECIMALSOFFSET_DECIMALS。 两者都必须在实现合约的 ImmutableConfig 中定义。

内部函数

initializer(ref self: ContractState, asset_address: ContractAddress) internal

验证 ImmutableConfig 常量并将 asset_address 设置为 vault。 这应在合约的构造函数中设置。

要求:

  • asset_address 不能为零地址。

_deposit(ref self: ContractState, caller: ContractAddress, receiver: ContractAddress, assets: u256, shares: u256) internal

depositmint 的内部逻辑。

assetscaller 转移到 Vault 合约,然后将 shares 铸造到 receiver。 费用可以在 ERC4626Hooks::after_deposit 钩子中转移,该钩子在资产转移和份额铸造后执行。

要求:

发送两个 ERC20::Transfer 事件(ERC20::mintERC20::transfer_from)。

发送 Deposit 事件。

_withdraw(ref self: ContractState, caller: ContractAddress, receiver: ContractAddress, owner: ContractAddress, assets: u256, shares: u256) internal

withdrawredeem 的内部逻辑。

owner 处销毁 shares,然后将 assets 转移到 receiver。 费用可以在 ERC4626Hooks::before_withdraw 钩子中转移,该钩:page-title: ERC20Upgradeable

==== 构造函数

==== constructor(ref self: ContractState, name: ByteArray, symbol: ByteArray, fixed_supply: u256, recipient: ContractAddress, owner: ContractAddress) constructor

设置 namesymbol,并将 fixed_supply 数量的 tokens 铸造给 recipient。 将 owner 指定为合约所有者,并赋予升级权限。

==== 外部函数

==== upgrade(ref self: ContractState, new_class_hash: ClassHash) external

将合约升级到由 new_class_hash 给出的新实现。

要求:

  • 调用者是合约所有者。

  • new_class_hash 不能为零。