On 28th December 2020, the year that keeps on giving, A bug was exploited in the Cover protocol’s liquidity mining/farming contract called Blacksmith. Multiple hackers used the bug to mint practically infinite tokens. The hackers now owe trillions of dollars in taxes to their governments.
The biggest hacker burned most of the hacked tokens and returned 4350 ether but there still are around 70 thousand Cover tokens in circulation that were created using this exploit and shouldn’t exist. The original hacker has cashed out about 1400 ether, 1 million DAI, 3k LINK, and 90 WBTC, about $4.4 million in total already.
The bug that caused this attack is present on line 118 of the Blacksmith.sol smart contract. The contract caches the pool data in memory to save some gas, updates the pool data in storage but forgets to update the cached data. The outdated cached data is later used in calculations and that enables the hack.
There are only 3 hard problems in computer science:
1) cache invalidation
3) multithreading/asynchronous programming
2) naming things
4) off-by-1 errors
How it was executed
- A new pool was approved for liquidity mining, merely hours before the hack. This pool is perfectly normal but since it was new, the blacksmith contract didn’t have any LP token of this pool.
- The attacker deposited some tokens of this pool into the Blacksmith contract.
- The Blacksmith contract keeps track of rewards on a per token basis. If a lot of tokens are locked, the per token reward will be small. If very few tokens are locked, the per token reward will be large. The relevant variable is called
accRewardsPerTokenand is calculated as
totalPoolRewards / totalTokenBalance.
- The attacker then withdrew almost all of the LP tokens from the Blacksmith contract, reducing the
totalTokenBalanceamount to almost zero.
- The attacker then deposited some tokens of this pool again into the Blacksmith contract. This is where the bug showed its true colors. Since the
totalTokenBalancewas reduced a lot in the previous transaction, the newly calculated
accRewardsPerTokenshot up. The contract uses
rewardWriteoffto keep the affect of
accRewardsPerTokenin check. However, due to the bug, the old (small) value of
accRewardsPerTokenwas used when calculating the
rewardWriteoffvalue. Due to this, the large value of
- The attacker then withdrew their rewards. Since there was a large, unchecked value in
accRewardsPerToken, the total reward paid out of the system got inflated and the contract ended up minting 40,796,131,214,802,500,000 COVER tokens.
These were the steps followed by the biggest hackers. Others did very similar stuff.
The COVER protocol team was asleep while all of this was going on but they removed minting access from the Blacksmith contract as soon as they wake up to stop the attacks. They are now considering restoring a snapshot of the Tokens before the hack.
Restoring snapshots is definitely controversial but it seems like the best way forward. A similar thing was done with Bitcoin in 2013 when a hacker managed to mint infinite bitcoins. I’d advise the Cover team to fix the bug, get a fresh audit from a new team and then relaunch the new token.
H/T banteg, Sorawit Suriyakarn, and Valentin Mihov.