本教程适用于所有希望向主网推出user-ready应用程序的人员
如果你想要将构建的DeFi协议或是其他智能合约应用发布到区块链主网上,安全因素一定是你要首先去考虑的。
许多团队在审查代码时只关注Solidity方面的问题,但要确保一个DApp的安全性并使其适配主网,还有很多其他问题需要关注。
了解近期高发的DeFi安全威胁——比如价格预言机攻击、暴力破解攻击以及其他攻击手段,将保护你以及你的用户数十亿美元的资产。
因此启动项目前做好尽职调查必不可少。
本文由CertiK及Chainlink联合出品,将为你分享DeFi安全的10个最佳实践,这将有助于防止你的应用程序成为攻击的受害者。
?超长干货,建议先收藏再看哦!
1.意识到重入攻击的危害
以智能合约为中介进行的攻击并不总是来自于外部。
重入攻击作为臭名昭著DAO攻击的一种形式,是DeFi安全中常见的攻击类型。
当合约调用另一个恶意合约的外部函数时,该恶意合约可以通过fallback(回调函数)进行重入攻击回调到原合约。
这是DeFi安全攻击的一种常见类型——恶意合约可以在第一个函数完成前回调到调用合约之中。
引用Solidity文档中对于重入攻击的描述:"一个合约与另一个合约的任何互动,以及任何以太币的转移都会将控制权交给该合约。这使得合约有可能在这个互动完成之前回调到合约"。
我们来看一个例子?
Let’slookatanexample:```solidity//SPDX-License-Identifier:GPL-3
functionwithdrawBalance()public{??uintamountToWithdraw=userBalances;??msg
```
在一个函数执行完成之前调用其他函数
对开发者而言这是一个明显的提醒——在ETH转账之前一定要先更新内部状态。
一些协议甚至在其函数上添加互斥锁,这样如果函数尚未返回,该函数就不能被再次调用。
除了常见的重入漏洞,还有一些重入攻击可以由特定的EIP机制触发,如ERC777。
ERC-777是建立在ERC-20之上的以太坊代币标准。
它向后兼容ERC-20,并增加了一个功能,使"操作员"能够代表代币所有者发送代币。
关键是,该协议还允许为代币所有者添加"send/receivehooks",以便在发送或接收交易时自动采取进一步行动。从UniswapimBTC黑客事件中可以看出,该漏洞实际上是由Uniswap交易所在余额更改之前发送ETH造成的。
Hut 8已就此前在公司北湾基地通电的约6400台ASIC矿机达成托管协议:金色财经报道,Hut 8已就此前在公司北湾基地通电的约6400台ASIC矿机达成托管协议。Hut8首席执行官Jaime Leverton表示,重新安置的矿机将为提供大约600PH/s的额外安装运行能力。一旦机器通电,总安装算力将增加到大约3.2EH/s。该协议包括3个月的初始期限,除非任何一方提前30天通知终止,否则将连续续签一个月。这些机器正在立即发货,预计将在7月下旬通电。[2023/6/22 21:54:44]
在该攻击中,Uniswap的功能设计没有遵循已被广泛采用的??"ChecksEffectInteractive"模式,该模式是为了保护智能合约免受重入攻击而发明的,按照该模式,代币转移应该在任何价值转移之前进行。
2.使用DEX或AMM中的代币余额储备作为代币价格参考会产生漏洞
这既是用于攻击协议的最常见方法之一,也是最容易防御的DeFi攻击类型。
使用`getReserves()`来决定代币价格是十分危险的。
当用户通过使用闪电贷攻击基于订单簿或自动做市商(AMM)的去中心化交易所(DEX)中的代币价格,这种中心化的价格预言机就有可能会被攻击。
在被闪电贷攻击时,因为项目使用了DEX中的价格作为他们的价格预言机的数据,导致智能合约的执行出现异常,其形式包括触发虚假清算、发放过大的贷款或触发不公平交易。
由于这个漏洞,即使是市面上主流的DEX——例如Uniswap,?也不建议单独使用代币对(swappair)中两种代币的相对比率作为价格预言机的定价。
在基于DEX或AMM的价格预言机中,预言机的数据源是DEX上一次成功交易,代币对调整之后的代币余额,即代币对中两种代币的相对比率。
该价格可能与代币的实际市场价格不同步。
例如,如果进行了大额交易时代币对中没有足够的流动性来支持,将会导致代币价格与交易所的平均市场价格相比发生较大波动,当用户大量买入时代币价格会飙升,当大量卖出时代币价格会狂跌。
闪电贷加剧了这一问题,因为它允许所有用户在没有任何抵押的情况下获得大量临时资金,以执行大额交易。用户经常将问题归咎于闪电贷,称之为“闪电贷攻击”。
然而,根本问题是——他们自己的DEX使用的是不安全的价格预言机,代币价格很容易被操纵,导致依赖预言机的协议引用了不准确的价格。
这些攻击应被更准确地描述为“预言机操纵攻击”,这一攻击形式在DeFi生态系统中造成了大量的攻击事件。因此所有开发人员都应该在智能合约中删除可能导致价格预言机被操纵的相关代码。
这里以最近一次攻击的代码举例,此次攻击造成了3000万美元的损失,并使该协议的奖励代币的价格暴跌?。
币安P2P平台越南市场增加对TUSD的支持:4月20日消息,币安宣布其 P2P 平台在越南市场增加了对 TUSD 的支持,符合条件的用户现在可以在币安 P2P 平台上直接使用越南盾买卖 TUSD。[2023/4/20 14:15:56]
```javascriptfunctionvalueOfAsset(addressasset,uintamount)publicviewoverridereturns(uintvalueInBNB,uintvalueInDAI){??if(keccak256(abi.encodePacked(IProtocolPair(asset).symbol()))==keccak256("Protocol-LP")){????(uintreserve0,uintreserve1,)=IPancakePair(asset).getReserves();??????valueInWETH=amount.mul(reserve0).mul(2).div(IProtocolPair(asset).totalSupply());??????valueInDAI=valueInWETH.mul(priceOfETH()).div(1e18);??}}```
该项目有一个预言机机制,可以从DEX中获取代币价格。
在DEX中,用户可以将一对代币存入流动性池合同,允许用户根据汇率在这些代币之间进行交换,汇率根据池中每一方的流动性数量计算。
现在有一个假设,如果一个项目大部分代码是从热门项目Uniswap中拷贝而来,我们可以认为这个项目是安全的。?
然而如果项目方在此基础之上添加了一个奖励代币项目,当用户向LP权益池中存储流动性时,他们不仅可以获得流动性代币LPtoken,还可以获取流动性挖矿的奖励代币。
这种情况下,黑客可以通过闪电贷将大量资金存入流动性池,从而操纵这个奖励代币的铸造功能,这使得他们能够以错误的比率兑换奖励代币。
在下方这个函数中,我们可以看到,攻击者做的第一件事就是根据流动性池中两种资产的储备量,获得流动性池中资产之间的汇率。
下面这行代码的目的是获得流动性池中的代币储备?
```javascript(uintreserve0,uintreserve1,)=IProtocolPair(asset).getReserves();```
如果一个流动性池中有5个WETH和10个DAI,那么它的reserve0为5,reserve1为10。
当你获得了流动性池中每种代币的储备量之后,将两个储备量相除,得到的汇率就可以定义代币对中任意一种资产的价格。
根据上面的例子,如果流动性池中有5个WETH和10个DAI,那么兑换率是1个WETH兑换2个DAI——用10除以5。
报告:亚洲游戏玩家占据80%的Web3游戏市场:金色财经报道,根据DappRadar与日本加密货币公司Pacific Meta联合进行的一项研究,预计亚洲游戏玩家将占据Web3游戏市场的绝大部分。该研究发现,亚洲已经拥有17亿玩家,占全球游戏人口的55%,并且可能占所有Web3游戏玩家的80%。
报告还显示,总计1000名受访者中有40%的人了解区块链游戏;在了解此类游戏的人中,近57%的人表示Web3游戏“看起来很有趣”,而只有大约10%的人表示它们看起来很无聊。[2023/4/14 14:02:25]
虽然使用去中心化交易所可以很好地交换具有即时流动性的资产,但这并不能保证DEX提供的价格比率是正确的,因为DEX中的价格很容易被闪电贷操纵,并且单个DEX中的交易数据往往只代表资产的总交易量的一小部分。
所以当其被用于计算奖励代币数量时,智能合约的执行很容易变得不准确。
以下面的代码为例?
Slightlymodifiedforcomprehension```javascript//ProtocolMinterV2.sol0x819eea71d3f93bb604816f1797d4828c90219b5dfunctionmintReward(addressasset/*LPtoken*/,uint_withdrawalFee/*0*/,uint_performanceFee/*0.00015...*/,addressto/*attacker*/,uint)externalpayableoverrideonlyMinter{??uintfeeSum=_performanceFee.add(_withdrawalFee);??_transferAsset(asset,feeSum);//transfersLPtokensfromVaultFlipToFliptothis??uintprotocolETHAmount=_zapAssetsToProtoclETH(asset,feeSum,true);??if(protocolETHAmount==0)return;??IEIP20(PROTOCOL_ETH).safeTransfer(PROTOCOL_POOL,protocolETHAmount);??IStakingRewards(PROTOCOL_POOL).notifyRewardAmount(protocolETHAmount);??(uintvalueInETH,)=priceCalculator.valueOfAsset(PROTOCOL_ETH,protocolETHAmount);//returnsinflatedvalue??uintcontribution=valueInETH.mul(_performanceFee).div(feeSum);??uintmintReward=amountRewardToMint(contribution);??_mint(mintReward,to);//mintstherewardtotheliquidityprovidersandattacks}```
9000万枚USDC在Binance被销毁:11月12日消息,Whale Alert数据显示,9000万枚USDC在Binance被销毁。
交易哈希:0x0409a4a4f4920e95515dc45251ebfaeaf41b9108bd81f53385f90d85444919ab,交易地址:0x55fe002aeff02f77364de339a1292923a15844b8。[2022/11/12 12:55:04]
在这个例子中,向用户进行奖励代币发放的主要函数是_mint(mintReward,to);。
我们可以看到,该函数根据用户在流动性池上锁定的资产价值来铸造奖励代币。
因此,如果一个用户突然在流动性池中拥有大量的资产,那么该用户可以轻易地为自己铸造大量奖励代币,这部分代币是从其他用户的奖励中窃取的。
然而,目前的利润水平依旧没有达到攻击者的期望。
因此,操纵DEX中代币的价格可以大大提升他们窃取的代币价值。
在这个例子中,合约认为他们给用户发放了价值5美元的奖励代币,但实际上发放了5000美元。
通过这种设置,恶意用户可以很容易地进行闪电贷攻击,将获取的临时资金存入流动性池,铸造大量的奖励,然后偿还闪电贷款,获得的利润由其他流动性提供者承担,从中获利。
为了防止基于闪电贷攻击的价格操纵问题,通常的解决方案是采取DEX市场的时间加权平均价格。
虽然这可以防止闪电贷歪曲预言机价格,因为闪电贷只存在于一个交易或区块中,而TWAP是多个区块的平均值,但这并不是一个完整的解决方案,因为TWAP有其自身的妥协。
在价格剧烈波动时期,TWAP预言会变得不准确,这可能会导致下游事件——如无法在期限内清偿抵押不足的贷款。
此外,TWAP预言没有提供足够的市场覆盖率,因为它只追踪一个DEX中的数据,使其它容易受到不同交易所的流动性或交易量变化的影响,从而影响TWAP预言给出的价格。
解决方案:使用去中心化的预言机网络
与其使用中心化预言机来确定汇率,保证DeFi安全的最佳做法是使用去中心化的多个预言机组成的网络来确定代币的实际市场价格。
一个DEX作为一个交易所是去中心化的,但把它作为定价信息参考时它是中心化的。
正确的做法是:你需要收集所有流动性中心化和去中心化交易所的价格,按交易量加权,并去除偏差值/清洗交易,以获得相关资产全球汇率的去中心化准确视图,确保能反映市场的实际价格。
如果你能获取基于所有交易环境的成交量加权的全球平均值的资产价格,那么闪电贷在单一交易所中操纵资产价格就不是问题。
此外,由于闪电贷款只存在于单个交易中,它们对去中心化的价格源并没有影响,这些价格源在单独的交易中产生具有能代表全球市场的实际价格更新。
箭牌已为绿箭等品牌提交NFT、加密货币及元宇宙相关商标申请:6月28日消息,据美国律师Mike Kondoudis的推文,美国糖果公司箭牌已为其旗下绿箭(Doublemint)、ORBIT、彩虹糖(SKITTLES)、Starburst四个品牌提交NFT、加密货币及元宇宙相关商标申请。范围涵盖NFT及数字代币、虚拟糖果及零食、用于验证/传输/共享的NFT及数字货币和加密收藏品的软件。[2022/6/28 1:35:58]
Chainlink预言机网络的去中心化结构及其实现的广泛市场覆盖,保护了DeFi协议免受闪电贷攻击导致的价格操纵,这就是为什么越来越多的DeFi项目正在集成Chainlink价格反馈机制,以防止价格预言机被攻击,并确保在突发的交易量变化中准确定价。
你不需要再使用`getReserves`来计算价格,而是从Chainlink数据源中获得代币交换比率,Chainlink数据源是去中心化的预言机节点网络,在链上提供能反映所有相关CEX和DEX的资产加权平均价格。
```soliditypragmasolidity^0.6.7;import"??/**??*Returnsthelatestprice??*/??functiongetThePrice()publicviewreturns(int){????(??????uint80roundID,??????intprice,??????uintstartedAt,??????uinttimeStamp,??????uint80answeredInRound????)=priceFeed.latestRoundData();????returnprice;??}}```
上面的代码是实现Chainlink价格预言机的全部内容,你可以通过阅读文档尝试在应用程序中进行实现。
如果你刚开始接触智能合约或预言机,我们有一个初学者教程,帮助你入门,并保护你的协议及用户免受闪电贷和预言机操纵攻击。
如果你想了解更多详情,可以试试查看OpenZeppelin的DEX??Ethernaut,它显示了操纵DEX的代币价格有多么容易。
3.不要使用Keccak256或Blockhash生成随机数
使用?"block.difficulty"、"block.timestamp"、"blockhash"或任何与区块相关的参数来生成随机数,都会使你的代码被恶意攻击。
智能合约中的随机性在许多用例中都很有用,例如无偏见地确定奖品的获得者,或者公平地将稀有NFT分配给用户。
然而,区块链是确定的系统,不提供随机数的防篡改来源,所以在不查看区块链外部的情况下获取随机数是具备一定风险的,并有可能导致被恶意攻击。
随机数生成漏洞并不像预言机操纵攻击或重入攻击那样普遍,但它们在Solidity教育材料中可是“常客”。
许多教育内容误导区块链开发人员使用如下代码获取随机数:
```javascriptuintrandomNumber=uint(keccak256(abi.encodePacked(nonce,msg.sender,block.difficulty,block.timestamp)))%totalSize;```
这里的想法是使用nonce、块难度和时间戳的某种组合来创建一个"随机"数字。
然而,这有几个明显的缺点——你可以很轻易的用取消交易的方式重复生成多次,直到得到一个你想要的随机数。
1.使用像block.difficity这样的哈希对象作为源来生产随机数时,矿工有能力改变这个源。与"重滚"策略类似,如果结果对他们不利,矿工可以利用他们订购交易的能力,将某些交易排除在区块之外。
如果该交易是用于链上生成随机数的源,矿工也可以选择扣留对他们不利的哈希值所在的区块。
2.使用block.timestamp无法提供任何随机性,因为时间戳是任何人都可以预测的。以这种方式使用链上随机数生成器,会让用户以及矿工对"随机"数字产生影响和控制。
如果你希望实现一个公平系统,以这种方式生成随机性将非常有利于攻击者,并且这个问题只会随着随机函数所保护的价值量的增加而变得更糟,因为攻击它的动机也增加了。
解决方案:使用ChainlinkVRF作为可验证的随机数生成器
为了防止被恶意攻击,开发者需要一种方法来生成可验证的随机数,并防止其被矿工和用户篡改。
实现这一目标需要来自于预言机的链下随机数源。
然而,许多提供随机性来源的预言机没有办法真正证明他们提供的数字确实是随机产生的。
因此开发者需要能够从链外获取随机性,同时也需要一种密码学算法来证明随机性没有被操纵过。
Chainlink的可验证随机函数正好实现了这一点。它使用预言机节点在链外生成一个随机数,并对该数字的完整性进行加密证明。然后由VRF协调器在链上检查加密证明,以验证VRF的确定性和防篡改性。
它的工作原理是这样的:
1.一个用户从Chainlink上节点请求一个随机数,并提供一个种子值,随后Chainlink将会发出一个链上事件日志。
2.链外的Chainlink预言机读取该日志,并使用可验证的随机函数基于节点的密钥哈希、用户给定的种子和发送请求时未知的块数据创建一个随机数和加密证明。然后,它在第二笔交易中把随机数返回链上,这时在链上通过VRF协调器合约使用加密证明进行验证。
ChainlinkVRF是如何解决上述问题的?
1.无法进行回滚攻击
由于这个过程需要两笔交易,第二笔交易是创建随机数的地方,所以你无法看到随机数或取消你的交易。
2.矿工无法改变这个值
由于ChainlinkVRF不使用矿工可以控制的参数,比如block.difficulty或block.timestamp等可预测的值,所以他们无法控制随机数。
用户、预言机节点或DApp开发者无法操纵ChainlinkVRF提供的随机性数据,这使得它成为智能合约应用所使用的链上随机性来源的安全得到了保证。
大家可以按照文档的要求试试在代码中实施ChainlinkVRF,或者根据我们的初学者指南来使用ChainlinkVRF。
在本系列接下来的内容中,将会为大家逐一讲解剩余的7大DeFi安全最佳实践方式,欢迎持续关注!
关注CertiK官方公众号,底部对话框发送消息“图谱”,可获取《区块链知识图谱》高清大图哦!
参考链接:
1.?https://www.researchgate.net/publication/235301171_The_Adoption_of_Electronic_Banking_Technologies_by_US_Consumers
2.https://www.gemini.com/cryptopedia/the-dao-hack-makerdao
3.https://docs.soliditylang.org/en/v0.8.9/contracts.html?highlight=receive#special-functions
4.?https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/
5.?https://eips.ethereum.org/EIPS/eip-1884#motivation
6.?https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/ReentrancyGuard.sol
7.?https://fravoll.github.io/solidity-patterns/checks_effects_interactions.html
8、https://blog.chain.link/flash-loans-and-the-importance-of-tamper-proof-oracles/
9.https://www.coindesk.com/flash-loans-centralized-price-oracles
10.https://github.com/Uniswap/uniswap-v2-core/tree/4dd59067c76dea4a0e8e4bfdda41877a6b16dedc
11.https://chain.link/data-feeds
12.https://docs.chain.link/docs/using-chainlink-reference-contracts/
13.https://docs.chain.link/docs/get-the-latest-price/
14.https://docs.chain.link/docs/beginners-tutorial/
15.https://ethernaut.openzeppelin.com/level/0x0b0276F85EF92432fBd6529E169D9dE4aD337b1F
16.https://docs.chain.link/docs/get-a-random-number/
17.https://docs.chain.link/docs/get-a-random-number/
18.https://docs.chain.link/docs/intermediates-tutorial/
来源:金色财经
标签:INTAINCHAHAIMyPoints E-Commerceblockchain是什么意思中文翻译chad币合约HairDAO
中国人民银行数字货币研究所副所长狄刚12月5日在国际金融论坛第18届全球年会上表示,区块链技术在数字金融领域应用成果初现.
1900/1/1 0:00:00近日,舵手云获得“国家信息系统安全等级保护”非银行机构最高等级等保三级备案认证并顺利复测。代表舵手云在安全与系统规范化管理方面得到了监管和认可,标志着舵手云的系统安全性已经达到行业内最高标准,可.
1900/1/1 0:00:00区块链有哪些缺点区块链的优势很多,劣势也很明显。区块链上的信息公开透明,可以有效地防止黑箱操作等现象。但也意味着如果知道某个人的账户,我就能知道他的所有财富和每一笔交易,没有隐私可言.
1900/1/1 0:00:00美国证券交易委员会面临越来越大的压力,不仅仅是金融科技的利益相关方,参议员也在呼吁国会尽快制定美国Crypto法律和指导方针.
1900/1/1 0:00:00原标题|7个DApp的Optimism生态,这个头部layer2是否乐观?作者:简苏尔Optimism是一种以太坊layer2扩展解决方案,与单独的以太坊第1层相比.
1900/1/1 0:00:00原文标题:《Welcometo『Web3.』What''sThat?》原文编译:0x137、0x76,律动BlockBeats加密爱好者们已经成功的预见到.
1900/1/1 0:00:00