背景信息
2024 年 7 月 16日,Li.Fi 协议遭受黑客攻击,漏洞成因是钻石协议中 diamond 合约新添加的 facet 合约没有对参数进行检查,导致 call 函数任意执行。且 diamond 合约拥有用户的 approve,所以攻击者可以构造恶意参数对用户资金进行转移。
相关合约
- 钻石协议 LiFiDiamond:https://etherscan.io/address/0x1231deb6f5749ef6ce6943a275a1d3e7486f4eae#code
- 逻辑合约 GasZipFacet:https://etherscan.io/address/0xf28a352377663ca134bd27b582b1a9a4dad7e534#code
钻石协议
钻石协议的提案是 EIP-2535 :https://eips.ethereum.org/EIPS/eip-2535 ,想详细了解的读者可以阅读提案的具体内容。简单理解一下就是变种的 proxy 形式,根据不同的函数调用不同的 implement 合约。
Trace 分析
攻击者调用 LiFiDiamond.depositToGasZipERC20
函数,Diamond 合约 delegatecall Facet 合约
GasZipFacet.depositToGasZipERC20
LibSwap.swap 函数
在 _swap.callTo.call{value: nativeValue}(_swap.callData)
函数中,攻击者构造恶意参数,导致实际上调用的是 USDT.transferFrom()
函数。
ERC20 授权
由于在 LibAsset
中需要用到 transferFrom 函数转移用户的 ERC20 代币,所以需要用户对 LiFiDiamond
合约进行代币授权。这是攻击发生的第二个条件。