合约实现中的事与愿违——实现与设计不符

针对区块链安全问题,成都链安科技团队每一周都将出智能合约安全漏洞解析连载,希望能帮助程序员写出更加安全牢固的合约,防患于未然。

引子:出尘花品爱池荷,零落秋风可奈何——《病中咏秋荷》清·蔡桓

本期话题

逻辑判断失误事与愿违,功能实现不周弄巧成拙

智能合约作为区块链技术革命的核心,乘着以太坊兴起的潮流,发展至今已经两年有余。智能合约的理念最早可以追溯到1995年,几乎与互联网同时出现。广受赞誉的密码学家尼克萨博最早提出了这个术语,他也是为比特币打下基础的学者之一。随着比特币的出现和应用,让智能合约的理念有了实现的机会。

从原理上来说,智能合约的执行依靠的是条件的触发,也就是类似于程序中的if-then语句。也就是说,智能合约对于其中合同条款的执行取决于预先编译好的逻辑判断,进而与真实世界的资产进行交互。本期,我们归纳总结了一些在从设计到实现的过程中出现安全漏洞。

zkSync联创提出新的治理解决方案L1 Fork,以应对智能合约实施过程中的风险:金色财经报道,Matter Labs联合创始人兼首席执行官Alex在社交媒体发文,提出“L1 Fork作为终审法院”概念拟解决智能合约实施风险问题,并且表示zkSync愿意资助相关研究。Alex指出,L2合约在紧急升级时存在中心化问题,相比之下L1是可分叉的,任何用户都可以选择加入他们主观认为正确且规范的分叉分支,但这种模式不适用于L2和DeFi协议,因为L2和DeFi协议无法分叉从L1桥接的底层原生资产(例如ETH)。

因此,Alex建议建立一个类似于现实世界司法机构的“链上法院”等级制度,每个协议都有自己的治理并定义正常和紧急升级机制且必须指定一份特殊合约作为上诉实例,这种模式可以解决紧急升级时的中心化问题。对于紧急升级,必须有一个上诉期,在此期间任何人都可以向上级“法院”提出质疑但必须缴纳预先确定的保释金,然后,该法院可以取消紧急升级(并且不执行任何其他操作),每个“法院”必须指定可以对任何决定提出上诉的更高一级“法院”,直到以太坊最高“法院”。[2023/9/3 13:14:42]

智能合约愈发复杂

Aku项目方价值3,400万美元ETH被永久锁定,系合约实现逻辑问题:4月23日消息,NFT项目方Akutar的11,539.5 ETH(约合3,400万美元)被永久锁定在拍卖合约。

Aku采用的是类似荷兰降价拍卖的形式,拍卖结束后会按照结束价格给用户退还超过最低价格的部分,因此这涉及refund以及total bids统计两个方面,而项目方在这两个方面均存在实现逻辑问题。

第一个漏洞,processRefunds() 会被恶意合约阻断,实现DoS攻击,也确有用户使用恶意合约阻断了processRefunds()执行,但该名用户表示只是让项目方确认问题存在,随即设置恶意合约变量,使得processRefunds()顺利执行完,因此该漏洞虽被利用,但已成功解决。

第二个漏洞,也就是真正导致项目方无法提款的关键所在,processRefunds()是按照msg.sender的数量记录在了refundProgress变量,拍卖结束项目方调用claimProjectFunds()取出合约内的ETH时,要求满足refundProgress >= totalBids,而totalBids记录的是NFT的数量,合约最终状态refundProgress数值为3669,totalBids数值为5495,从而导致项目方无法提取合约内的11539.5 ETH。

需要指出的是,在执行processRefunds()之前,参与拍卖的用户可以在三天后通过emergencyWithdraw()将个人投入的ETH取回,但由于processRefunds()的执行,导致用户的拍卖状态由未处理变为refund,从而不能再进行emergencyWithdraw()。[2022/4/23 14:43:41]

我们都知道,一个智能合约包含两部分:代码逻辑和数据。

火币合约将于12月11日18:00上线BTC等5大币种永续合约实时结算功能:火币官方刚刚发布公告称,火币合约平台将于2020年12月11日18:00上线BTC/USDT、ETH/USDT、LTC/USDT、LINK/USDT和XRP/USDT永续合约在全仓和逐仓模式下实时结算功能。暂定试行至新加坡时间2021年6月30日。[2020/12/11 14:56:12]

相比于比特币的脚本语言,智能合约发展的一个终极目标就是“图灵完备”,简单来说,就是无论怎样复杂的交易逻辑或功能都可以实现。

智能合约的开发经过一段时间的沉淀,已经由最初简单的转账、付款等功能需求,向越来越多的交易功能和逻辑进化,比如冻结、暂停、中止、授权。根据复杂性理论,越复杂的系统越容易有出错的可能。因此,越是功能强大的智能合约,其逻辑就越是复杂,也越容易出现逻辑上的漏洞。

Gate.io已上线BCHA/USDT永续合约实盘交易(USDT结算):据官方公告,Gate.io已上线BCHA/USDT永续合约实盘交易(USDT结算),支持1-20倍做多和做空操作,杠杆率可以在下单时自行选择。Gate.io永续合约是全球最活跃的区块链资产合约市场之一,日交易量高达8亿美金,结算类型分为“BTC结算永续合约”和“USDT结算永续合约”两种。Gate.io提示:请用户务必在完全了解风险并能承担风险的情况下参与,Gate.io平台不对投资行为承担担保、赔偿等责任。[2020/11/19 21:18:27]

开发合约也会言多必失?

打个比方来说,逻辑更加复杂的代码相当于更庞大的城池,在容纳更多人口的同时,需要防守的地方也更多。有些精心设计而又容易忽视防范的地方,比如错综复杂的下水道系统,正是容易让整个城池沦陷的重大隐患。

掌柜调查署丨兰建忠:火币合约实现“零分摊”关键在于“2+1”投资者保护基金:在今日的掌柜调查署上,火币集团副总裁兰建忠发言指出:火币合约实现全品种“零分摊”关键在于“2+1”的投资者保护基金先行赔付机制。

首先是安全备付金:火币合约和Huobi Global共用安全备付金。该保护基金总额20,000 BTC,专项用于应对火币平台可能出现的极端突发安全事故。

第二是风险准备金:风险准备金是用于应付因强平单未能平出而产生的穿仓损失。每一个合约品种,都有一个风险准备金。

第三是 零分摊保证金:零分摊保证金则是火币合约自2018年12月上线以来,就开启的一笔200万美元的“零分摊”保障资金。[2020/3/10]

同样,在智能合约中,开发者为自己的合约设计的特殊功能意在稳固代币的市值或者项目的寿命,而正是在这些逻辑和功能中,一个细微的失误,比如>、<、+、-这些符号的错误就可能导致整个逻辑与预想出现严重的偏差,留下致命的隐患。

代码实现失误漏洞总结

我们将代码实现过程中产生的失误分为两种:

1.逻辑判断错误

Solidity的if或者require等条件判断表达式对合约代码执行做出限制,开发者如果在编写合约时写出了错误的判断条件,将会造成比较大的逻辑错误,影响合约正常使用。

a)transferFlaw

在transferFrom()函数中,当对allowance值做校验的时,误将校验逻辑写反,从而使得合约代码的逻辑判断错误。有可能造成溢出或者任何人都能转出任何账户的余额。

我们来看一个案例

if(allowed>=value)returnfalse;此处校验逻辑写反了,导致只要授权值allowed小于转出额度,那么都能转账成功,利用这个漏洞,可以不经授权就可以转出他人账户中的代币。

l漏洞修复

推荐使用require(allowed>=value);语句对授权额度进行判断

b)pauseTransfer-anyone

以如下案例合约为例

onlyFromWallet中的判断条件将==写反了,写成了!=,使得除了walletAddress以外,所有账户都可以调用enableTokenTransfer()和disableTokenTransfer()函数,这两个函数可以开启或者关闭合约的转账、授权以及烧币功能,进而影响合约的正常使用。

l漏洞修复

使用正确的require判断语句:

c)allowAnyone

分析如下案例合约

在transferFrom函数中,转账前未对allowed进行校验,转账后对allow的计算也未使用SafeMath,使得任何账户都可可以不经授权就能够转出他人账户中的代币,并且,如果转账额度_value大于allowed,allowed-=_value将发生溢出。

l漏洞修复

i.在转账前增加对allowed的检查,require(allowed>=_value);;

ii.使用SafeMath对allow进行运算,

allowed=allowed.sub(_value);

d)approve-with-balance-verify

部分合约在函数approve()中,增加对被授权账户余额的校验,要求授权的_amount小于或等于当前余额。

一方面,对余额的校验并不能保证被授权账户一定可以转出这个数量的金额:

i.在approve之后,token的所有者自己通过transfer函数,把token转走,导致余额小于allowance。

ii.approve给多个人,其中一个人进行transferFrom操作后,可能导致余额小于之前给其他人approve过的值。

另一方面这个校验可能导致外部合约无法正常调用,必须由Token项目方提前转入一笔数额巨大的Token至中间账户才能继续执行。

例如下面这个合约

l漏洞修复

去掉balances的校验:

2.功能实现与设计不符

我们来详细分析如下案例合约:

上述两个函数重写了ERC20标准中的transfer和transferFrom函数,添加了对冻结账户的检查。

在transfer中,如果msg.sender被冻结,那么其不能进行代币交易。

但是,我们注意到,在transferFrom中,并没有对代币转出地址的检查。

如此一来,一个被冻结的地址可以通过授权第三方,然后通过第三方地址向目标地址发送代币,违背了设计中对冻结地址的限制。

l漏洞修复

在合约正式上链前,项目方应对合约进行充分的测试,确保其实现完全符合设计。

我本将心向明月,奈何明月照沟渠

以上的安全漏洞都是开发人员在实现某些功能需求时,出现低级错误或者只追求完成功能需求导致的。相信在漏洞被曝光或者被攻击者利用时,开发者的内心也是崩溃的,感觉枉费了一番苦功夫。在没有相关测试、审计团队的协助下,对于此类实现与设计不符的漏洞可能真的束手无策,尤其是关于合约逻辑的检测,可能需要用到形式化验证运用数学建模的方法对于合约进行描述之后才能查遗补漏。但是,汲取他人教训并且用于提高应该是每个先驱者在探索新领域时具备的素质,一个人可能会走的更快,而一群人,会走得更远。

郑重声明: 本文版权归原作者所有, 转载文章仅为传播更多信息之目的, 如作者信息标记有误, 请第一时间联系我们修改或删除, 多谢。

银河链

MEXC纪念币发的多了会引发通货膨胀么

前几天,佐罗的阿姨托佐罗找点关系,帮着兑换些纪念币,交谈的过程中,阿姨突然说:之前新闻老说什么货币超发引起通货膨胀什么的,国家发这么多纪念币,岂不是会引发通货膨胀么,不行,我得赶紧买东西去.

[0:15ms0-1:735ms