Blacksmith,漏洞就在其中被发现。如果您知道受影响协议或易受攻击合约的确切名称,也可以直接搜索它。



Blacksmith: pool does not exist。
Pool memory pool = pools[_lpToken];,数据在此被缓存,然后在第 125 行更新,我们看到 _claimCoverRewards(pool, miner);
合约使用了缓存数据,因为数据本身留在内存中;这就是为什么后来合约使用这些数据计算函数。缓存没有更新导致了这次黑客攻击:
example.sol
example.sol
example.sol
- 在攻击发生前几个小时,一个新池被批准用于流动性挖矿。这个池完全正常,但由于它是新的,Blacksmith 合约中没有此池的任何 LP 代币。
- 攻击者将此池的一些代币存入了 Blacksmith 合约。
- Blacksmith 合约按每代币基础跟踪奖励。如果锁定了大量代币,每代币的奖励将很小。如果锁定的代币很少,每代币的奖励将很大。相关变量称为
accRewardsPerToken,计算为totalPoolRewards / totalTokenBalance。 - 然后攻击者从 Blacksmith 合约中提取了几乎所有的 LP 代币,将
totalTokenBalance数量减少到几乎为零。 - 然后攻击者再次将此池的一些代币存入 Blacksmith 合约。这就是漏洞暴露出真面目的地方。由于
totalTokenBalance在前一交易中被大幅减少,新计算的accRewardsPerToken飙升。合约使用rewardWriteoff来控制accRewardsPerToken的影响。然而,由于漏洞,在计算rewardWriteoff值时使用了accRewardsPerToken的旧(小)值。因此,accRewardsPerToken的大值没有被控制。 - 然后攻击者提取了他们的奖励。由于
accRewardsPerToken中存在一个大的、未被控制的值,从系统支付的总奖励被抬高,合约最终铸造了 40,796,131,214,802,500,000 枚 COVER 代币。
感谢 Mudit Gupta 对此次黑客攻击最后部分的分析——在他的博客上阅读更多信息 :)