问题描述
这是取自 OpenZeppelin 的 ERC20 transferFrom
实现:
function transferFrom(address sender,address recipient,uint256 amount) public virtual override returns (bool) {
_transfer(sender,recipient,amount);
uint256 currentAllowance = _allowances[sender][_msgSender()];
require(currentAllowance >= amount,"ERC20: transfer amount exceeds allowance");
_approve(sender,_msgSender(),currentAllowance - amount);
return true;
}
在检查取款机 (_transfer
) 限额之前调用 msg.sender
是否有原因?
如果先进行余量 transferFrom
检查,require
仍能正常工作吗?
解决方法
我在 OpenZeppelin GitHub Issues 上发现了关于同一主题的讨论,代码作者确认该顺序与 ERC-20 上下文无关。
在 ERC20 的情况下,订单无关紧要,因为 _transfer 和 _approve 是独立的,从不调用任何其他合约:它们是原子执行的。
此外,他指出,当有人想要覆盖功能时,保持顺序稳定很重要。
然而,这对于打算用自己的实现覆盖 _transfer 或 _approve 的用户来说非常重要:我们应该清楚这些事情发生的顺序。
来源:https://github.com/OpenZeppelin/openzeppelin-contracts/issues/2030#issuecomment-568487500
因此,假设您没有在覆盖的 _transfer()
和 _approve()
内部函数中使用自定义逻辑,如果您切换顺序,transferFrom()
仍然可以正常工作。