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
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
accRewardsPerToken
and is calculated astotalPoolRewards / totalTokenBalance
. - The attacker then withdrew almost all of the LP tokens from the Blacksmith contract, reducing the
totalTokenBalance
amount 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
totalTokenBalance
was reduced a lot in the previous transaction, the newly calculatedaccRewardsPerToken
shot up. The contract usesrewardWriteoff
to keep the affect ofaccRewardsPerToken
in check. However, due to the bug, the old (small) value ofaccRewardsPerToken
was used when calculating therewardWriteoff
value. Due to this, the large value ofaccRewardsPerToken
remained unchecked. - 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.
Final thoughts
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.