本文档全面介绍了以太坊中 ERC-20 代币标准及其相关接口、合约和实用工具。
最好在 https://docs.openzeppelin.com/contracts/api/token/erc20 查看本文档 |
这组接口、合约和实用程序都与 ERC-20 代币标准 相关。
有关 ERC-20 代币的概述以及如何创建代币合约的演练,请阅读我们的 ERC-20 指南。 |
有一些核心合约实现了 ERC-20 标准中指定的行为:
IERC20
:所有 ERC-20 实现都应符合的接口。
IERC20Metadata
:扩展的 ERC-20 接口,包括 name
、symbol
和 decimals
函数。
此外,还有多个自定义扩展,包括:
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
花费的剩余代币数量。 默认情况下,此值为零。
当调用 approve
或 transferFrom
时,此值会发生变化。
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
设置 owner
的 spender
的 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这两个值都是不可变的:它们只能在构造期间设置一次。
name() → string
public返回代币的名称。
symbol() → string
public返回代币的符号,通常是名称的较短版本。
decimals() → uint8
public返回用于获取其用户表示形式的小数位数。 例如,如果 decimals
等于 2
,则应向用户显示 505
个代币的余额为 5.05
(505 / 10 ** 2
)。
代币通常选择值 18,模仿 Ether 和 Wei 之间的关系。 这是此函数返回的默认值,除非它被覆盖。
此信息仅用于显示目的:它绝不影响合同的任何算术,包括 IERC20.balanceOf 和 IERC20.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。 |
要求:
from
和 to
不能是零地址。
from
必须至少有 value
的余额。
调用者必须至少具有 value
的 from
的代币的 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`` 更新
owner对
spender`` 的 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
设置为 spender
在 owner
的代币上的 allowance,给定 owner
的签名 approval。
IERC20.approve 具有的与交易排序相关的相同问题也适用于此。 |
发出一个 Approval
事件。
要求:
spender
不能是零地址。
deadline
必须是未来的时间戳。
v
、r
和 s
必须是来自 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
设置为 spender
对 owner
的 token 的授权额度,
给定 owner
的签名批准。
与交易相关的 IERC20.approve 具有相同的问题<br>排序也适用于此处。 |
发出 Approval
事件。
要求:
spender
不能为零地址。
deadline
必须是未来的时间戳。
v
、r
和 s
必须是来自 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)
errorPermit 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._burn
和 ERC20.allowance
。
要求:
value
的 accounts
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._pause 和 Pausable._unpause 内部函数,具有适当的<br>访问控制,例如使用 AccessControl 或 Ownable 。不这样做会<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.getVotes
和 Votes.getPastVotes
查询投票权。
默认情况下,token 余额不考虑投票权。 这使得转移更便宜。 缺点是它 要求用户委托给自己以激活检查点并跟踪其投票权。
函数
Votes
Nonces
EIP712
ERC20
[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)
internaldecimals() → 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
来更改。
当此扩展与 ERC20Capped 或 ERC20Votes 扩展一起使用时,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 被铸造并发送给
receiver
,receiver
需要实现 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
publicallowance
覆盖,在查找当前授权时包括临时授权。如果
将持久授权和临时授权相加导致溢出,则返回 type(uint256).max。
_temporaryAllowance(address owner, address spender) → uint256
internalspender
对 owner
token 拥有的当前临时授权的内部 getter。
temporaryApprove(address spender, uint256 value) → bool
publicapprove
的替代方法,它将 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.transferAndCall
和
ERC1363.transferFromAndCall
方法启用调用,而使用 ERC1363.approveAndCall
可以进行批准后的调用
自 v5.1 版本可用。
函数
ERC20
事件
IERC20
错误
IERC20Errors
ERC20InsufficientBalance(sender, balance, needed)
](https://docs.openzeppelin.com/contracts/5.x/api/interfaces#IERC20实现了在
ERC-4626 中定义的 ERC-4626 “代币化金库标准”。这个扩展允许通过标准化的 deposit
, mint
, redeem
和 burn
工作流来铸造和销毁“份额”(使用 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 来表示底层资产的小数位数。
asset() → address
public参见 IERC4626.asset
。
totalAssets() → uint256
publicconvertToShares(uint256 assets) → uint256
publicconvertToAssets(uint256 shares) → uint256
publicmaxDeposit(address) → uint256
publicmaxMint(address) → uint256
public参见 IERC4626.maxMint
。
maxWithdraw(address owner) → uint256
publicmaxRedeem(address owner) → uint256
publicpreviewDeposit(uint256 assets) → uint256
publicpreviewMint(uint256 shares) → uint256
publicpreviewWithdraw(uint256 assets) → uint256
publicpreviewRedeem(uint256 shares) → uint256
publicdeposit(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
publicredeem(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
internalERC4626ExceededMaxDeposit(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
数量的 token
从 from
转移到 to
,花费 from
给予调用合约的授权。如果 token
不返回值,则非恢复调用被认为是成功的。
trySafeTransfer(contract IERC20 token, address to, uint256 value) → bool
internalsafeTransfer
的变体,如果操作不成功,则返回一个 bool 值,而不是恢复。
trySafeTransferFrom(contract IERC20 token, address from, address to, uint256 value) → bool
internalsafeTransferFrom
的变体,如果操作不成功,则返回一个 bool 值,而不是恢复。
safeIncreaseAllowance(contract IERC20 token, address spender, uint256 value)
internal将调用合约对 spender
的授权增加 value
。如果 token
不返回值,则非恢复调用被认为是成功的。
如果代币实现了 ERC-7674(具有临时授权的 ERC-20),并且如果“客户端”<br>智能合约使用 ERC-7674 来设置临时授权,那么“客户端”智能合约应避免使用<br>此函数。在具有非零临时授权(对于该特定所有者-支出者)的代币合约上执行 safeIncreaseAllowance 或 safeDecreaseAllowance 操作将导致意外行为。 |
safeDecreaseAllowance(contract IERC20 token, address spender, uint256 requestedDecrease)
internal将调用合约对 spender
的授权减少 requestedDecrease
。如果 token
不返回值,则非恢复调用被认为是成功的。
如果代币实现了 ERC-7674(具有临时授权的 ERC-20),并且如果“客户端”<br>智能合约使用 ERC-7674 来设置临时授权,那么“客户端”智能合约应避免使用<br>此函数。在具有非零临时授权(对于该特定所有者-支出者)的代币合约上执行 safeIncreaseAllowance 或 safeDecreaseAllowance 操作将导致意外行为。 |
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(operator, from, to, value, data)
checkOnERC1363ApprovalReceived(operator, spender, value, data)
错误
checkOnERC1363TransferReceived(address operator, address from, address to, uint256 value, bytes data)
internal对目标地址执行 IERC1363Receiver.onTransferReceived
的调用。
要求:
目标有代码(即是一个合约)。
目标 to
必须实现 IERC1363Receiver
接口。
目标必须返回 IERC1363Receiver.onTransferReceived
选择器以接受传输。
- 原文链接: docs.openzeppelin.com/co...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!