当前位置:首页 > 物联网 > 区块链
[导读] 智能合约可以部署其他智能合约。这使工厂模式成为可能,在工厂模式中,您可以创建多个智能合同,每个智能合同只跟踪一件事,而不是一个跟踪许多事情的智能合同。使用此模式可以简化代码并减少某些类型的安全漏

智能合约可以部署其他智能合约。这使工厂模式成为可能,在工厂模式中,您可以创建多个智能合同,每个智能合同只跟踪一件事,而不是一个跟踪许多事情的智能合同。使用此模式可以简化代码并减少某些类型的安全漏洞的影响。

在这篇文章中,我将向您介绍一个基于我们在最近的审计中发现的一个关键漏洞的示例。如果使用了工厂模式,那么漏洞就就减少了很多。

越野车智能合约

下面是一个智能合约,通过一个相当简单的界面销售WETH。如果您有WETH,你只需要批准这个智能合约出售你的代币,它将确保你得到正确的金额支付。只要批准充足的代币,任何人都可以任意购买WETH。

合约使用提款模式将付款交付给卖方,但合约的作者犯了一个严重的错误:

1// Technically this could sell any token, but we‘re selling WETH in this

2// example because then I don’t have to think about prices. 1 WETH costs 1 ETH.

3contract WETHMarket {

4 IERC20 public weth;

5 mapping(address =》 uint256) public balanceOf;

6

7 constructor(IERC20 _weth) public {

8 weth = _weth;

9 }

10

11 // Buy WETH from a specified seller. Seller must first approve WETH.

12 function buyFrom(address seller) external payable {

13 balanceOf[seller] += msg.value;

14 require(weth.transferFrom(seller, msg.sender, msg.value),

15 “WETH transfer failed.”);

16 }

17

18 // Used by a seller to get their ETH.

19 funcTIon withdraw(uint256 amount) external {

20 require(amount 《= balanceOf[msg.sender], “Insufficient funds.”);

21

22 // Whoops! Forgot this:

23 // balanceOf[msg.sender] -= amount;

24

25 (bool success, ) = msg.sender.call.value(amount)(“”);

26 require(success, “ETH transfer failed.”);

27 }

28}

(如果您想知道为什么代码使用.call而不是.transfer,请阅读“立即停止使用Solidity的传输()”)。

因为卖方的余额从未减少,所以欠任何以太的卖方都可以反复调用withdraw()来消耗每个人的合约。这是一个严重的漏洞。

修复这个bug,就像大多数bug一样,一旦你发现了它,就变得微不足道了。但在这篇文章中,我想谈谈如何通过使用工厂模式来减轻这个bug,即使我们不知道这个特定的问题。

现在让我们看一下更简单的WETHMarket合约版本。在这个版本中,合约只负责销售一个卖家的WETH。此合约与先前版本具有相同的bug:

1contract WETHSale {

2 IERC20 public weth;

3 address seller; // only a single seller

4 uint256 public balance; // no need for a mapping anymore

5

6 constructor(IERC20 _weth, address _seller) public {

7 weth = _weth;

8 seller = _seller;

9 }

10

11 // No need to specify the seller.

12 funcTIon buy() external payable {

13 balance += msg.value;

14 require(weth.transferFrom(seller, msg.sender, msg.value));

15 }

16

17 funcTIon withdraw(uint256 amount) external {

18 require(msg.sender == seller, “Only the seller can withdraw.”);

19 require(amount 《= balance, “Insufficient funds.”);

20

21 uint256 amount = balance;

22

23 // Whoops! Forgot this:

24 // balance -= amount;

25

26 (bool success, ) = msg.sender.call.value(amount)(“”);

27 require(success, “ETH transfer failed.”);

28 }

29}

尽管存在完全相同的逻辑错误,但此漏洞并不是那么严重。只允许一个帐户调用withdraw(),并且合约中存储的所有以太网都属于该帐户。这个错误的影响只是余额并不能反映合约中的真实余额。

这个bug是手工挑选来显示其优点的,但是这个bug代表了托管协议中的一大类bug。根据我审计智能合约的经验,这是发现关键漏洞最常见的地方之一。

托管背后的想法是,不同的资金必须分开存放,以确保合同始终可以涵盖所有欠款。获得托管权最简单的方法之一是将资金完全分成不同的智能合约。

您可以将工厂模式看作是一种深入防御的托管方法。

简单代码

单卖方版本的合约不仅有更强大的代管,而且更简单。我们去掉了一个函数参数和一个映射。在生产代码中,我们可能会更进一步,完全删除balance,而代之以address(this).balance。

因为我写合约是为了方便阅读,原来的代码已经很简单了。在现实世界的例子中,这种差异可能更为显著。从安全的角度来看,任何降低复杂性的机会都是一种胜利。

工厂模式

每个卖家都可以部署自己的Wethsale合约并从简单的合约中获益,但是这种方法有一个主要的缺点,恶意卖家可能会部署稍微修改过的代码版本,但实际上并没有传输weth。

即使像ConsenSys Diligence这样有信誉的公司审核了WETHSale代码,每个买家也必须验证他们购买的具体合约是否使用了那些确切的代码。

使用工厂可以解决这个问题。工厂确保每个部署的合约都使用相同的代码,并且它提供了一个简单的查找机制来查找给定卖方的单一合约:

contract WETHSaleFactory {

IERC20 public weth;

mapping(address =》 WETHSale) public sales;

constructor(IERC20 _weth) public {

weth = _weth;

}

funcTIon deploy() external {

require(sales[msg.sender] == WETHSale(0), “Only one sale per seller.”);

sales[msg.sender] = new WETHSale(weth, msg.sender);

}

}

潜在缺陷

使用工厂模式的一个主要缺点是价格昂贵。CREATE操作码目前的燃气成本为32,000。我们的特殊合约还需要另外两个SSTORE来跟踪WETH和卖方地址,每个地址需要20,000燃气。这比代码的原始多卖家版本至少多72,000气体。

另一个潜在的缺点是复杂性。在大多数实际情况下,工厂模式简化了现有的合同,但请记住,它还添加了一个新的合同:工厂本身。根据代码的不同,这可能会导致复杂性的增加。

在决定工厂模式之前,请仔细考虑变更的总体影响。

总结

1. 托管方面的错误是导致关键漏洞的一个重要原因。

2. 使用单独的智能合约可以降低这些错误的严重性。

3. 工厂模式以一种不可信任的方式实现了这一点。

4. 在采用工厂模式之前还要考虑潜在的缺点。

来源: 区块链研究实验室

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

北京2024年5月16日 /美通社/ -- 5月10日晚,2024中国品牌日晚会在新华社全媒体矩阵播出,50个入选品牌在当晚揭晓,极氪名列其中,成为首度上榜的中国造车新势力代表。 图为北京时间5月10日 21:30 ,...

关键字: 吉利 COM HTML 代码

上海2024年4月16日 /美通社/ -- 根据研究和经验, 设备和系统50%的故障或失效可直接或间接地是由转子不平衡引起的。在先前申克现场动平衡仪的基础上, 申克又创新了一套更成熟的移动式平衡设备:SmartBalan...

关键字: BALANCE SMART FFT 振动分析

2023年10月18日,中国在第三届“一带一路”国际合作高峰论坛期间发布《全球人工智能治理倡议》,围绕人工智能发展、安全、治理三方面系统阐述了人工智能治理中国方案。

关键字: 人工智能 大模型 代码

我们看到这么多的安全问题,部分原因在于我们对待安全的方式:安全性通常被认为是事后考虑的问题,是在开发结束时才添加到设备上的东西。然而,复杂的系统,尤其是嵌入式系统,有一个很大的攻击面,这让攻击者有机可乘,能够在“盔甲”上...

关键字: 代码 嵌入式系统 软件漏洞

新富人群财务需求多元发展,投顾服务迎来新机遇 上海2023年9月20日 /美通社/ -- 2023年9月19日,上海交通大学上海高级金融学院(高金)与全球领先的金融服务机构嘉信理财(Charles Schwab)联合发...

关键字: BSP ADVANCED INA 代码

北京2023年9月14日 /美通社/ -- 生物医药高科技公司诺诚健华(港交所代码:09969;上交所代码:688428)今日宣布,新型蛋白酪氨酸磷酸酶SHP2变构抑制剂ICP-189联用针对表皮生长因子受体(EGFR)...

关键字: IC HP 代码 ARMA

上海2023年9月1日 /美通社/ -- 2023上半年,安集科技(股票代码:688019)市场拓展规划成效显现,营业收入稳健增长。 全球半导体产业挑战持续存在的情形下,安集科技秉承发扬"克难攻坚,敢打硬...

关键字: 安集科技 BSP 代码 半导体材料

广州2023年8月29日 /美通社/ --  8月28日,保健食品行业迎来新规,国家市场监管总局正式发布《保健食品新功能及产品技术评价实施细则(试行)》(简称《实施...

关键字: UI BSP JOURNAL 检测方法

国际酒店运营商升级其在线支付功能 上海2023年8月28日 /美通社/ -- 加拿大金融科技公司Nuvei Corporation(以下简称“Nuvei”或“公司”)(纳斯达克代码:NVEI)(多伦多证券交易所代码:N...

关键字: 代码 IP SE 纳斯达克

2023年上半年收入7.459亿元 同比增长5.1% 毛利率水平上升 海外收入同比增长65.4% 香港2023年8月22日 /美通社/ -- 金邦达宝嘉控股有限公司及其附属公司(以下合称「金邦达」、「...

关键字: 数字化 代码 嵌入式软件 COM
关闭
关闭