于2025年2月12日,zkLend Finance协议遭到攻击,导致损失约950万美元。
zkLend是一个建立在Starknet区块链上的去中心化借贷协议。它允许用户借贷资产,类似于Aave或Compound等协议。
该攻击针对的是zkLend Market
合约(特别是wstETH市场),这是允许用户借贷资产的主要合约。
关键信息
攻击者地址: https://voyager.online/contract/0x04d7191dc8eac499bac710dd368706e3ce76c9945da52535de770d06ce7d3b26
漏洞合约(zkLend Market): https://voyager.online/contract/0x04c0a5193d58f74fbace4b74dcf65481e734ed1714121bdc571da345540efa05
示例攻击交易: https://voyager.online/tx/0x596bb905f74b545ca5a2af39c5724d952e43ef9887af3f6fd603eebfcc9c2a
漏洞分析
从攻击者地址来看,在攻击期间发生了多笔交易。
要理解这次攻击,我们需要首先检查调用runwithfirstdep
的交易,因为它似乎是最重要的一个。
在runwithfirstdep
交易中,我们可以看到对zkLend Market
合约进行了多次连续的deposit
和withdraw
调用。让我们先检查一个deposit
调用的细节。
很明显,deposit
和withdraw
调用中的金额不相同,这表明这不是一个简单的存取交易。这里我们看到,攻击者只存入了4.069
个wstETH,但提取了6.103
个wstETH。因此,我们需要检查deposit
和withdraw
函数的代码,以理解这次攻击。
通过检查deposit
函数的代码,我们可以看到它接受输入代币的amount
,并铸造相应数量的zToken
。withdraw
函数也是如此。但是,为什么攻击者能够销毁比他们应该的更多的zToken
呢?这让我们不得不检查zToken
合约中burn
函数的实现。
从burn
函数的实现中,我们可以看到实际销毁的金额是scaledDownAmount
。此外,通过检查safe_math::sub()
函数,我们可以确定计算scaledDownAmount
的公式是amount * SCALE / accumulator
。
所以,检查这个值最简单的方法是从攻击交易中检查这些值。我们有以下值:
amount:
6103946859077466029
(提取调用)accumulator:
4069297906051644020000000000000000000000000000
SCALE:
1000000000000000000000000000
从这些值中,我们可以计算出scaledDownAmount
如下:
scaledDownAmount = amount * SCALE / accumulator
= 6103946859077466029 * 1000000000000000000000000000 / 4069297906051644020000000000000000000000000000
= 1
所以现在很明显,这个值是攻击者精心选择的,以绕过scaled_down_amount.is_non_zero()
的检查。在runwithfirstdep
交易之前的deposit
交易用于操纵get_lending_accumulator()
函数的结果,使这个值大得多,从而使scaled_down_amount
变为1
。
事后分析
攻击后,被盗资金从Starknet桥接到以太坊区块链。攻击者随后试图通过将资金存入Railgun隐私池来洗钱,但被该协议的政策阻止。这次失败的洗钱尝试突出了在DeFi领域平衡隐私和透明度的重要性。
经验教训
这一事件突出了在处理复杂和敏感的金融操作时,仔细验证输入值的重要性。通过吸取这样的事件教训,DeFi社区可以构建更加稳健的系统,更好地保护用户资金。