使用工厂模式的利与弊
智能合约可以部署其他智能合约,通常称为工厂模式,让你不是创建一个合约跟踪很多事情,而是创建多个智能合约,每个合约只跟踪各个的事情。 使用这种模式可以简化合约代码,减少某些类型的安全漏洞的影响。
在这篇文章中,我将带你了解一个例子,这个例子是基于最近的一次审计中发现的一个关键漏洞修改而来。 如果使用了工厂模式,这个漏洞就不会那么严重了。
下面是一个智能合约,通过一个相当简单的接口来出售 WETH。 如果你有WETH,你只需要 approve(授权)
这个智能合约来出售你的代币,它将确保你得到正确的金额。 只要批准了足够的代币,任何人都可以向你购买WETH 。
合约采用提现模式向卖家交付出售所得的ETH,但合约作者却犯了严重错误,代码如下:
// 技术上可以实现出售任何代币,但这个例子仅出售 WETH 。
// 因为这里不想关注价格. 1 WETH = 1 ETH.
contract WETHMarket {
IERC20 public weth;
mapping(address => uint256) public balanceOf;
constructor(IERC20 _weth) public {
weth = _weth;
}
// 从指定的seller购买 WETH . seller 需要先授权 WETH.
function buyFrom(address seller) external payable {
balanceOf[seller] += msg.value;
require(weth.transferFrom(seller, msg.sender, msg.value),
"WETH transfer failed.");
}
// 出售者调用,提取ETH
function withdraw(uint256 amount) external {
require(amount <= balanceOf[msg.sender], "Insufficient funds.");
// Whoops! Forgot this:
// balanceOf[msg.sender] -= amount;
(bool success, ) = msg.sender.call.value(amount)("");
require(success, "ETH transfer failed.");
}
}
如果你想知道为什么代码使用.call
而不是.transfer
,请阅读停止使用transfer())。
由于卖方的余额永远不会减少,所以,一...
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!