ERC-20 - OpenZeppelin 文档

本文档全面介绍了以太坊中 ERC-20 代币标准及其相关接口、合约和实用工具。

ERC-20

最好在 https://docs.openzeppelin.com/contracts/api/token/erc20 查看本文档

这组接口、合约和实用程序都与 ERC-20 代币标准 相关。

有关 ERC-20 代币的概述以及如何创建代币合约的演练,请阅读我们的 ERC-20 指南

有一些核心合约实现了 ERC-20 标准中指定的行为:

此外,还有多个自定义扩展,包括:

  • ERC20Permit:代币的 gasless approval(标准化为 ERC-2612)。

  • ERC20Burnable:销毁自己的代币。

  • ERC20Capped:在铸造代币时强制执行总供应量的上限。

  • ERC20Pausable:暂停代币转账的能力。

  • ERC20FlashMint:通过临时代币的铸造和销毁对闪电贷的代币级别支持(标准化为 ERC-3156)。

  • ERC20Votes:对投票和投票委托的支持。

  • ERC20Wrapper:包装器,用于创建由另一个 ERC-20 支持的 ERC-20,具有存款和取款方法。 与 ERC20Votes 结合使用非常有用。

  • ERC20TemporaryApproval:支持仅持续一笔交易的 approval,如 ERC-7674 中定义。

  • ERC1363:支持调用转移或 approval 的目标,从而可以在单笔交易中在接收者上执行代码。

  • ERC4626:代币化金库,管理由资产(另一个 ERC-20)支持的股份(表示为 ERC-20)。

最后,有一些实用程序可以以各种方式与 ERC-20 合约交互:

  • SafeERC20:接口的包装器,无需处理布尔返回值。

可以在代码库中找到支持 ERC-20 资产的其他实用程序:

  • 可以使用 VestingWallet 对 ERC-20 代币进行时间锁定(为受益人持有到指定时间)或归属(按照给定的时间表发布)。
这组核心合约旨在保持公正,允许开发人员访问 ERC-20 中的内部函数(例如 _mint)并以他们喜欢的方式将其公开为外部函数。

核心

IERC20

import "@openzeppelin/contracts/token/ERC20/IERC20.sol";

ERC 中定义的 ERC-20 标准接口。

函数

事件

totalSupply() → uint256 external

返回存在的代币的值。

balanceOf(address account) → uint256 external

返回 account 拥有的代币的值。

transfer(address to, uint256 value) → bool external

value 数量的代币从调用者的帐户移动到 to

返回一个布尔值,指示操作是否成功。

发出一个 transfer 事件。

allowance(address owner, address spender) → uint256 external

返回 spender 将被允许代表 owner 通过 transferFrom 花费的剩余代币数量。 默认情况下,此值为零。

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

approve(address spender, uint256 value) → bool external

value 数量的代币设置为 spender 在调用者的代币上的 allowance。

返回一个布尔值,指示操作是否成功。

请注意,使用此方法更改 allowance 会带来风险,即有人可能会因不幸的事务排序而同时使用旧 allowance 和新 allowance。 缓解这种竞争状况的一种可能的解决方案是首先将 spender 的 allowance 减少到 0,然后再设置所需的值:https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729

发出一个 Approval 事件。

transferFrom(address from, address to, uint256 value) → bool external

使用 allowance 机制将 value 数量的代币从 from 移动到 to。 然后从调用者的 allowance 中扣除 value

返回一个布尔值,指示操作是否成功。

发出一个 transfer 事件。

Transfer(address indexed from, address indexed to, uint256 value) event

value 个代币从一个帐户(from)移动到另一个帐户(to)时发出。

请注意,value 可能为零。

Approval(address indexed owner, address indexed spender, uint256 value) event

当通过调用 approve 设置 ownerspender 的 allowance 时发出。 value 是新的 allowance。

IERC20Metadata

import "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol";

来自 ERC-20 标准的可选元数据函数的接口。

函数

IERC20

事件

IERC20

name() → string external

返回代币的名称。

symbol() → string external

返回代币的符号。

decimals() → uint8 external

返回代币的小数位数。

ERC20

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";

IERC20 接口的实现。

此实现与创建代币的方式无关。 这意味着必须在派生合约中使用 _mint 添加供应机制。

有关详细说明,请参阅我们的指南如何实现供应机制

decimals 的默认值为 18。 要更改此值,你应该覆盖此函数,使其返回不同的值。

我们遵循了一般的 OpenZeppelin Contracts 指南:函数在失败时恢复,而不是返回 false。 尽管如此,此行为是传统的,并且与 ERC-20 应用程序的期望不冲突。

函数

事件

IERC20

错误

IERC20Errors

constructor(string name_, string symbol_) internal

设置 namesymbol 的值。

这两个值都是不可变的:它们只能在构造期间设置一次。

name() → string public

返回代币的名称。

symbol() → string public

返回代币的符号,通常是名称的较短版本。

decimals() → uint8 public

返回用于获取其用户表示形式的小数位数。 例如,如果 decimals 等于 2,则应向用户显示 505 个代币的余额为 5.05505 / 10 ** 2)。

代币通常选择值 18,模仿 Ether 和 Wei 之间的关系。 这是此函数返回的默认值,除非它被覆盖。

此信息仅用于显示目的:它绝不影响合同的任何算术,包括 IERC20.balanceOfIERC20.transfer
totalSupply() → uint256 public

请参阅 IERC20.totalSupply

balanceOf(address account) → uint256 public

请参阅 IERC20.balanceOf

transfer(address to, uint256 value) → bool public

请参阅 IERC20.transfer

要求:

  • to 不能是零地址。

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

allowance(address owner, address spender) → uint256 public

请参阅 IERC20.allowance

approve(address spender, uint256 value) → bool public

请参阅 IERC20.approve

如果 value 是最大 uint256,则不会在 transferFrom 上更新 allowance。 这在语义上等同于无限 approval。

要求:

  • spender 不能是零地址。
transferFrom(address from, address to, uint256 value) → bool public

请参阅 IERC20.transferFrom

跳过发出指示 allowance 更新的 Approval 事件。 这不是 ERC 所要求的。 请参阅 _approve

如果当前 allowance 是最大 uint256,则不会更新 allowance。

要求:

  • fromto 不能是零地址。

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

  • 调用者必须至少具有 valuefrom 的代币的 allowance。

_transfer(address from, address to, uint256 value) internal

value 数量的代币从 from 移动到 to

此内部函数等效于 transfer,可用于例如实现自动代币费用、削减机制等。

发出一个 transfer 事件。

此函数不是虚拟函数,应覆盖 _update
_update(address from, address to, uint256 value) internal

value 数量的代币从 from 转移到 to,或者,如果 from(或 to)是零地址,则铸造(或销毁)。 对转移、铸造和销毁的所有自定义都应通过覆盖此函数来完成。

发出一个 transfer 事件。

_mint(address account, uint256 value) internal

通过从 address(0) 转移,创建 value 数量的代币并将其分配给 account。 依赖于 _update 机制

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

此函数不是虚拟函数,应覆盖 _update
_burn(address account, uint256 value) internal

account 中销毁 value 数量的代币,从而降低总供应量。 依赖于 _update 机制。

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

此函数不是虚拟函数,应覆盖 _update
_approve(address owner, address spender, uint256 value) internal

value 设置为 spender 在 \`owner 的代币上的 allowance。

此内部函数等效于 approve,可用于例如为某些子系统设置自动 allowance 等。

发出一个 Approval 事件。

要求:

  • owner 不能是零地址。

  • spender 不能是零地址。

对此逻辑的覆盖应该针对带有附加 bool emitEvent 参数的变体完成。

_approve(address owner, address spender, uint256 value, bool emitEvent) internal

_approve 的变体,带有可选标志以启用或禁用 Approval 事件。

默认情况下(当调用 _approve 时),该标志设置为 true。 另一方面,在 transferFrom 操作期间由 _spendAllowance 进行的 approval 更改会将该标志设置为 false。 这通过不在 transferFrom 操作期间发出任何 Approval 事件来节省 gas。

任何希望在 \transferFrom\\ 操作中继续发出 Approval 事件的人都可以使用以下覆盖强制将该标志设置为 true:

function _approve(address owner, address spender, uint256 value, bool) internal virtual override {
    super._approve(owner, spender, value, true);
}

要求与 _approve 相同。

_spendAllowance(address owner, address spender, uint256 value) internal

根据花费的 value`` 更新ownerspender`` 的 allowance。

如果 allowance 无限,则不会更新 allowance 值。 如果没有足够的 allowance 可用,则恢复。

不发出 Approval 事件。

扩展

IERC20Permit

import "@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol";

ERC-20 Permit 扩展的接口,允许通过签名进行 approval,如 ERC-2612 中定义。

添加 permit 方法,该方法可用于通过提供由帐户签名的消息来更改帐户的 ERC-20 allowance(请参阅 IERC20.allowance)。 通过不依赖 IERC20.approve,代币持有者帐户无需发送交易,因此根本不需要持有 Ether。

安全注意事项

关于 permit 的使用,有两个重要的考虑因素。 首先,有效的 permit 签名表示 allowance,不应假定其传达其他含义。 特别是,不应将其视为以任何特定方式花费 allowance 的意图。 第二个是,由于 permit 具有内置的重放保护并且可以由任何人提交,因此它们可以被抢先交易。 使用 permit 的协议应考虑这一点,并允许 permit 调用失败。 结合这两个方面,通常建议的模式是:

function doThingWithPermit(..., uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public {
    try token.permit(msg.sender, address(this), value, deadline, v, r, s) {} catch {}
    doThing(..., value);
}

function doThing(..., uint256 value) public {
    token.safeTransferFrom(msg.sender, address(this), value);
    ...
}

请注意:1) msg.sender 用作所有者,不会对签名者的意图产生歧义,并且 2) try/catch 的使用允许 permit 失败,并使代码能够容忍抢先交易。 (另请参见 SafeERC20.safeTransferFrom)。

此外,请注意,智能合约钱包(例如 Argent 或 Safe)无法生成 permit 签名,因此合约应具有不依赖 permit 的入口点。

函数

permit(address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) external

value 设置为 spenderowner 的代币上的 allowance,给定 owner 的签名 approval。

IERC20.approve 具有的与交易排序相关的相同问题也适用于此。

发出一个 Approval 事件。

要求:

  • spender 不能是零地址。

  • deadline 必须是未来的时间戳。

  • vrs 必须是来自 owner 的有效 secp256k1 签名,签名内容是 EIP712 格式的函数参数。

  • 签名必须使用 owner 的当前 nonce(请参阅 nonces)。

有关签名格式的更多信息,请参阅相关的 EIP 部分

请参阅上面的安全注意事项。
nonces(address owner) → uint256 external

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

每次成功调用 [permit](https://docs.openzeppelin.com/contracts/5.x/api/token/erc20#IERC20Permit-permit-address-address-uint25- _burn(account, value)

事件

IERC5267

IERC20

错误

Nonces

IERC20Errors

constructor(string name) internal

使用 name 参数初始化 EIP712 域分隔符,并将 version 设置为 "1"

使用与定义为 ERC-20 token 名称的相同 name 是一个好主意。

permit(address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public

value 设置为 spenderowner 的 token 的授权额度, 给定 owner 的签名批准。

与交易相关的 IERC20.approve 具有相同的问题<br>排序也适用于此处。

发出 Approval 事件。

要求:

  • spender 不能为零地址。

  • deadline 必须是未来的时间戳。

  • vrs 必须是来自 owner 的有效 secp256k1 签名 超过 EIP712 格式的函数参数。

  • 签名必须使用 owner 的当前 nonce(请参阅 nonces)。

有关签名格式的更多信息,请参阅 相关 EIP\ 部分

请参阅上面的安全注意事项。
nonces(address owner) → uint256 public

返回 owner 的当前 nonce。 每当为 permit 生成签名时,都必须包含此值。

每次成功调用 permit 都会使 owner 的 nonce 增加 1。 这 防止签名被多次使用。

DOMAIN_SEPARATOR() → bytes32 external

返回用于 permit 签名的编码中的域分隔符,如 EIP712 所定义。

ERC2612ExpiredSignature(uint256 deadline) error

Permit deadline 已过期。

ERC2612InvalidSigner(address signer, address owner) error

签名不匹配。

ERC20Burnable

import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol";

ERC20 的扩展,允许 token 持有者销毁他们自己的 token 以及他们有权使用的 token,这种方式可以 链下识别(通过事件分析)。

函数

ERC20

事件

IERC20

错误

IERC20Errors

burn(uint256 value) public

从调用者处销毁 value 数量的 token。

请参阅 ERC20._burn

burnFrom(address account, uint256 value) public

account 销毁 value 数量的 token,从 调用者的授权额度中扣除。

请参阅 ERC20._burnERC20.allowance

要求:

  • 调用者必须拥有至少 valueaccounts token 授权额度。

ERC20Capped

import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Capped.sol";

ERC20 的扩展,它为 token 的供应量增加了一个上限。

函数

ERC20

事件

IERC20

错误

IERC20Errors

constructor(uint256 cap_) internal

设置 cap 的值。此值是不可变的,只能在构造期间设置一次。

cap() → uint256 public

返回 token 总供应量的上限。

_update(address from, address to, uint256 value) internal

请参阅 ERC20._update

ERC20ExceededCap(uint256 increasedSupply, uint256 cap) error

已超过总供应量上限。

ERC20InvalidCap(uint256 cap) error

提供的 cap 不是有效的 cap。

ERC20Pausable

import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Pausable.sol";

ERC-20 token 具有可暂停的 token 转移、铸造和销毁功能。

适用于诸如阻止交易直到评估期结束,或者在发生重大错误时具有冻结所有 token 转移的紧急开关等场景。

此合约不包括公共的暂停和取消暂停功能。除了继承此合约之外,你还必须定义这两个函数,调用<br>Pausable._pausePausable._unpause 内部函数,具有适当的<br>访问控制,例如使用 AccessControlOwnable。不这样做会<br>使合约的暂停机制无法访问,因此无法使用。

函数

Pausable

ERC20

事件

Pausable

IERC20

错误

Pausable

IERC20Errors

_update(address from, address to, uint256 value) internal

请参阅 ERC20._update

要求:

  • 合约不得暂停。

ERC20Votes

import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Votes.sol";

ERC-20 的扩展,用于支持类似 Compound 的投票和委托。此版本比 Compound 的版本更通用, 并支持高达 2208 - 1 的 token 供应量,而 COMP 仅限于 296 - 1。

此合约不提供与 Compound 的 COMP token 的接口兼容性。

此扩展保留每个帐户投票权的记录(检查点)。 可以通过调用Votes.delegate函数直接委托投票权,或者通过签名与Votes.delegateBySig一起使用。 可以通过公共访问器Votes.getVotesVotes.getPastVotes 查询投票权。

默认情况下,token 余额不考虑投票权。 这使得转移更便宜。 缺点是它 要求用户委托给自己以激活检查点并跟踪其投票权。

函数

Votes

Nonces

EIP712

ERC20

  • name()

  • symbol()

  • [decimals()](https://docs.
    重写此函数可能会损害内部投票统计。<br>ERC20Votes 假设 token 以 1:1 的比例映射到投票单位,并且这不容易更改。
numCheckpoints(address account) → uint32 public

获取 account 的检查点数量。

checkpoints(address account, uint32 pos) → struct Checkpoints.Checkpoint208 public

获取 account 的第 pos 个检查点。

ERC20ExceededSafeSupply(uint256 increasedSupply, uint256 cap) error

总供应量上限已被超过,引入了投票溢出的风险。

ERC20Wrapper

import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Wrapper.sol";

ERC-20 token 合约的扩展,支持 token 包装。

用户可以存入和提取“底层 token”,并收到匹配数量的“包装 token”。这与其他模块结合使用时非常有用。例如,将此包装机制与 ERC20Votes 结合使用,可以将现有的“基本”ERC-20 包装成治理 token。

任何底层 token 在没有明确转账的情况下更改账户的 balanceOf 的机制<br>都可能导致此合约的供应量与其底层余额不同步。包装可能导致包装器抵押不足的 token 时请谨慎(即,包装器的总供应量高于其底层余额)。有关恢复累积到包装器的价值,请参阅 _recover

函数

ERC20

事件

IERC20

错误

IERC20Errors

constructor(contract IERC20 underlyingToken) internal
decimals() → uint8 public

参见 ERC20.decimals

underlying() → contract IERC20 public

返回正在包装的底层 ERC-20 token 的地址。

depositFor(address account, uint256 value) → bool public

允许用户存入底层 token 并铸造相应数量的包装 token。

withdrawTo(address account, uint256 value) → bool public

允许用户销毁一定数量的包装 token 并提取相应数量的底层 token。

_recover(address account) → uint256 internal

铸造包装 token 以覆盖任何可能因错误转移或从 重新抵押机制获得的 underlyingTokens。如果需要,可以使用访问控制公开的内部函数。

ERC20InvalidUnderlying(address token) error

底层 token 无法被包装。

ERC20FlashMint

import "@openzeppelin/contracts/token/ERC20/extensions/ERC20FlashMint.sol";

ERC-3156 闪电贷扩展的实现,如 ERC-3156 中定义。

添加了 flashLoan 方法,该方法在 token 级别提供闪电贷支持。默认情况下没有费用,但可以通过覆盖 flashFee 来更改。

当此扩展与 ERC20CappedERC20Votes 扩展一起使用时,maxFlashLoan 将无法正确反映可以闪电铸造的最大数量。我们建议覆盖 maxFlashLoan,以便它正确反映供应上限。

函数

ERC20

事件

IERC20

错误

IERC20Errors

maxFlashLoan(address token) → uint256 public

返回可用于贷款的最大 token 数量。

flashFee(address token, uint256 value) → uint256 public

返回执行闪电贷时应用的费用。此函数调用 _flashFee 函数,该函数返回执行闪电贷时应用的费用。

_flashFee(address token, uint256 value) → uint256 internal

返回进行闪电贷时收取的费用。默认情况下, 此实现不收取任何费用。可以重载此函数以使闪电贷机制具有通货紧缩性。

_flashFeeReceiver() → address internal

返回闪电贷费用的接收者地址。默认情况下, 此实现返回 address(0),这意味着费用金额将被销毁。可以重载此函数以更改费用接收者。

flashLoan(contract IERC3156FlashBorrower receiver, address token, uint256 value, bytes data) → bool public

执行闪电贷。新的 token 被铸造并发送给 receiverreceiver 需要实现 IERC3156FlashBorrower 接口。在闪电贷结束时,预期接收者拥有 value + fee 个 token,并将它们批准回 token 合约本身,以便 可以销毁它们。

ERC3156UnsupportedToken(address token) error

贷款 token 无效。

ERC3156ExceededMaxLoan(uint256 maxLoan) error

所请求的贷款超过了 token 的最大贷款价值。

ERC3156InvalidReceiver(address receiver) error

闪电贷的接收者不是有效的 IERC3156FlashBorrower.onFlashLoan 实现者。

ERC20TemporaryApproval

import "@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20TemporaryApproval.sol";

ERC20 的扩展,根据 ERC-7674 添加了对临时授权的支持。

这是一个草案合约。相应的 ERC 仍在修改中。

自 v5.1 版本可用。

函数

ERC20

事件

IERC20

错误

IERC20Errors

allowance(address owner, address spender) → uint256 public

allowance 覆盖,在查找当前授权时包括临时授权。如果 将持久授权和临时授权相加导致溢出,则返回 type(uint256).max。

_temporaryAllowance(address owner, address spender) → uint256 internal

spenderowner token 拥有的当前临时授权的内部 getter。

temporaryApprove(address spender, uint256 value) → bool public

approve 的替代方法,它将 value 数量的 token 设置为 spender 对 调用者 token 的临时授权。

返回一个布尔值,指示操作是否成功。

要求:

  • spender 不能是零地址。

不发出 Approval 事件。

_temporaryApprove(address owner, address spender, uint256 value) internal

value 设置为 spender 对 `owner 的 token 的临时授权。

此内部函数等效于 temporaryApprove,可用于例如为某些子系统设置自动授权等。

要求:

  • owner 不能是零地址。
  • spender 不能是零地址。

不发出 Approval 事件。

_spendAllowance(address owner, address spender, uint256 value) internal

_spendAllowance 覆盖,在最终回退之前消耗临时授权(如果有) 以消耗持久授权。 注意:如果临时授权足以支付消费,则此函数跳过调用 super._spendAllowance

ERC1363

import "@openzeppelin/contracts/token/ERC20/extensions/ERC1363.sol";

ERC20 token 的扩展,添加了对在接收者合约上进行转账和批准后执行代码的支持。在转账后通过 ERC1363.transferAndCallERC1363.transferFromAndCall 方法启用调用,而使用 ERC1363.approveAndCall 可以进行批准后的调用

自 v5.1 版本可用。

函数

ERC20

事件

IERC20

错误

IERC20Errors

这个扩展允许通过标准化的 depositmintredeemburn 工作流来铸造和销毁“份额”(使用 ERC-20 继承表示),以换取底层“资产”。此合约扩展了 ERC-20 标准。任何包含在其中的附加扩展都会影响此合约表示的“份额”代币,而不是作为独立合约的“资产”代币。

在空的(或几乎空的)ERC-4626 金库中,存款面临着通过抢先交易被盗的高风险,<br>通过向金库存入“捐款”来抬高份额的价格。这通常被称为捐赠或通胀攻击,本质上是滑点的问题。金库部署者可以通过进行初始<br>存款,存入大量资产来防止这种攻击,这样价格操纵就变得不可行。提款可能<br>同样受到滑点的影响。用户可以通过验证收到的金额是否符合预期来防止这种攻击以及普遍存在的意外滑点,使用一个执行这些检查的包装器,例如<br>ERC4626Router。<br>自 v4.9 以来,此实现引入了可配置的虚拟资产和份额,以帮助开发者减轻这种风险。<br>_decimalsOffset() 对应于底层资产的小数位数和金库的小数位数之间的十进制表示的偏移量。<br>此偏移量还决定了金库中虚拟份额与虚拟资产的比率,而虚拟份额与虚拟资产的比率本身决定了初始汇率。虽然不能完全防止攻击,但分析表明,即使攻击者能够从多个用户存款中获取价值,默认的<br>偏移量 (0) 也会使其无利可图,因为虚拟份额(从攻击者的捐款中)捕获的价值与攻击者的预期收益相匹配。<br>如果偏移量更大,攻击的成本将比其盈利性高出几个数量级。有关<br>底层数学的更多详细信息,请点击此处查看。<br>这种方法的缺点是虚拟份额确实捕获了(非常小的一部分)金库中累积的价值。<br>此外,如果金库遭受损失,用户试图退出金库,虚拟份额和资产<br>将导致第一个退出的用户遭受的损失减少,而不利于将遭受<br>更大损失的最后一个用户。希望恢复到 v4.9 之前行为的开发者只需覆盖<br>_convertToShares_convertToAssets 函数即可。<br>要了解更多信息,请查看我们的 ERC-4626 指南

函数

ERC20

事件

IERC4626

IERC20

错误

IERC20Errors

constructor(contract IERC20 asset_) internal

设置底层资产合约。这必须是 ERC20 兼容的合约(ERC-20 或 ERC-777)。

decimals() → uint8 public

小数位数是通过在底层资产的小数位数上加上小数位数偏移量来计算的。这个“原始”值在金库合约的构造过程中被缓存。如果这个读取操作失败(例如,资产尚未创建),则使用默认值 18 来表示底层资产的小数位数。

参见 IERC20Metadata.decimals

asset() → address public

参见 IERC4626.asset

totalAssets() → uint256 public

参见 IERC4626.totalAssets

convertToShares(uint256 assets) → uint256 public

参见 IERC4626.convertToShares

convertToAssets(uint256 shares) → uint256 public

参见 IERC4626.convertToAssets

maxDeposit(address) → uint256 public

参见 IERC4626.maxDeposit

maxMint(address) → uint256 public

参见 IERC4626.maxMint

maxWithdraw(address owner) → uint256 public

参见 IERC4626.maxWithdraw

maxRedeem(address owner) → uint256 public

参见 IERC4626.maxRedeem

previewDeposit(uint256 assets) → uint256 public

参见 IERC4626.previewDeposit

previewMint(uint256 shares) → uint256 public

参见 IERC4626.previewMint

previewWithdraw(uint256 assets) → uint256 public

参见 IERC4626.previewWithdraw

previewRedeem(uint256 shares) → uint256 public

参见 IERC4626.previewRedeem

deposit(uint256 assets, address receiver) → uint256 public

参见 IERC4626.deposit

mint(uint256 shares, address receiver) → uint256 public

参见 IERC4626.mint

withdraw(uint256 assets, address receiver, address owner) → uint256 public

参见 IERC4626.withdraw

redeem(uint256 shares, address receiver, address owner) → uint256 public

参见 IERC4626.redeem

_convertToShares(uint256 assets, enum Math.Rounding rounding) → uint256 internal

内部转换函数(从资产到份额),支持舍入方向。

_convertToAssets(uint256 shares, enum Math.Rounding rounding) → uint256 internal

内部转换函数(从份额到资产),支持舍入方向。

_deposit(address caller, address receiver, uint256 assets, uint256 shares) internal

存款/铸币的通用工作流程。

_withdraw(address caller, address receiver, address owner, uint256 assets, uint256 shares) internal

提取/赎回的通用工作流程。

_decimalsOffset() → uint8 internal
ERC4626ExceededMaxDeposit(address receiver, uint256 assets, uint256 max) error

尝试存入的资产超过了 receiver 的最大金额。

ERC4626ExceededMaxMint(address receiver, uint256 shares, uint256 max) error

尝试铸造的份额超过了 receiver 的最大金额。

ERC4626ExceededMaxWithdraw(address owner, uint256 assets, uint256 max) error

尝试提取的资产超过了 receiver 的最大金额。

ERC4626ExceededMaxRedeem(address owner, uint256 shares, uint256 max) error

尝试赎回的份额超过了 receiver 的最大金额。

实用工具

SafeERC20

import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";

ERC-20 操作的包装器,在失败时抛出异常(当代币合约返回 false 时)。还支持不返回值(而是在失败时恢复或抛出异常)的代币,非恢复调用被认为是成功的。要使用此库,你可以向你的合约添加 using SafeERC20 for IERC20; 语句,这允许你将安全操作称为 token.safeTransfer(…​) 等。

函数

错误

safeTransfer(contract IERC20 token, address to, uint256 value) internal

value 数量的 token 从调用合约转移到 to。如果 token 不返回值,则非恢复调用被认为是成功的。

safeTransferFrom(contract IERC20 token, address from, address to, uint256 value) internal

value 数量的 tokenfrom 转移到 to,花费 from 给予调用合约的授权。如果 token 不返回值,则非恢复调用被认为是成功的。

trySafeTransfer(contract IERC20 token, address to, uint256 value) → bool internal

safeTransfer 的变体,如果操作不成功,则返回一个 bool 值,而不是恢复。

trySafeTransferFrom(contract IERC20 token, address from, address to, uint256 value) → bool internal

safeTransferFrom 的变体,如果操作不成功,则返回一个 bool 值,而不是恢复。

safeIncreaseAllowance(contract IERC20 token, address spender, uint256 value) internal

将调用合约对 spender 的授权增加 value。如果 token 不返回值,则非恢复调用被认为是成功的。

如果代币实现了 ERC-7674(具有临时授权的 ERC-20),并且如果“客户端”<br>智能合约使用 ERC-7674 来设置临时授权,那么“客户端”智能合约应避免使用<br>此函数。在具有非零临时授权(对于该特定所有者-支出者)的代币合约上执行 safeIncreaseAllowancesafeDecreaseAllowance 操作将导致意外行为。
safeDecreaseAllowance(contract IERC20 token, address spender, uint256 requestedDecrease) internal

将调用合约对 spender 的授权减少 requestedDecrease。如果 token 不返回值,则非恢复调用被认为是成功的。

如果代币实现了 ERC-7674(具有临时授权的 ERC-20),并且如果“客户端”<br>智能合约使用 ERC-7674 来设置临时授权,那么“客户端”智能合约应避免使用<br>此函数。在具有非零临时授权(对于该特定所有者-支出者)的代币合约上执行 safeIncreaseAllowancesafeDecreaseAllowance 操作将导致意外行为。
forceApprove(contract IERC20 token, address spender, uint256 value) internal

将调用合约对 spender 的授权设置为 value。如果 token 不返回值,则非恢复调用被认为是成功的。用于需要先将授权设置为零,然后再将其设置为非零值的代币,例如 USDT。

如果代币实现了 ERC-7674,此函数不会修改任何临时授权。此函数<br>仅设置“标准”授权。任何临时授权都将保持活动状态,此外还将保留此处设置的值。
transferAndCallRelaxed(contract IERC1363 token, address to, uint256 value, bytes data) internal

执行一个 ERC1363 transferAndCall,如果目标没有代码,则回退到简单的 ERC20 transfer。这可以用于实现一个 ERC721 类型的安全传输,该传输依赖于在定位合约时进行 ERC1363 检查。

如果返回值不是 true,则恢复。

transferFromAndCallRelaxed(contract IERC1363 token, address from, address to, uint256 value, bytes data) internal

执行一个 ERC1363 transferFromAndCall,如果目标没有代码,则回退到简单的 ERC20 transferFrom。这可以用于实现一个 ERC721 类型的安全传输,该传输依赖于在定位合约时进行 ERC1363 检查。

如果返回值不是 true,则恢复。

approveAndCallRelaxed(contract IERC1363 token, address to, uint256 value, bytes data) internal

执行一个 ERC1363 approveAndCall,如果目标没有代码,则回退到简单的 ERC20 approve。这可以用于实现一个 ERC721 类型的安全传输,该传输依赖于在定位合约时进行 ERC1363 检查。

当接收者地址( to)没有代码(即是 EOA)时,此函数的作用类似于 forceApprove。<br>相反,当接收者地址( to)有代码时,此函数仅尝试调用 ERC1363.approveAndCall<br>一次而不重试,并依赖于返回值为 true。

如果返回值不是 true,则恢复。

SafeERC20FailedOperation(address token) error

与 ERC-20 代币的操作失败。

SafeERC20FailedDecreaseAllowance(address spender, uint256 currentAllowance, uint256 requestedDecrease) error

指示 decreaseAllowance 请求失败。

ERC1363Utils

import "@openzeppelin/contracts/token/ERC20/utils/ERC1363Utils.sol";

提供通用 ERC-1363 实用程序的库。

参见 ERC-1363

函数

错误

checkOnERC1363TransferReceived(address operator, address from, address to, uint256 value, bytes data) internal

对目标地址执行 IERC1363Receiver.onTransferReceived 的调用。

要求:

`checkOnERC13
  • 原文链接: docs.openzeppelin.com/co...
  • 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
OpenZeppelin
OpenZeppelin
江湖只有他的大名,没有他的介绍。