This report was made possible by the @RektHQ Opsec Team
Average Joe Executive Summary
TOTAL VALUE LOST: $9.4m, $3.2m recovered and $6.2m lost
Actors involved
- **Grap Finance: Deployer (Externally owned account)** minted 40,796,131,214,802,500,000 $COVER tokens
- List of addresses and how much cover they've minted over the last 10k blocks, a few ones are probably the exploiters (by banteg)
Addresses who minted COVER in last 10k blocks (NOT all exploiters)
Step By Step Guide to COVER Exploit
- A new balancer pool was added via a transaction.
- Grap Finance Deployer deposited 15,255.552810089260015362 BPT (DAI/Basis cover) on Cover
- Grap Finance Deployer withdrew 15,255.552810089260015361 BPT (DAI/Basis Cover) on Cover Leaving just 1 Wei in his balance on Cover
- A user (0xdf1aefb979d180b4d67cca9abb4c5108c89dc8a4) withdrawn his full balance (1,007.599009946121991627 BPT) from Cover. Now only Grab Finance has liquidity on Cover, exactly 1 wei.
This lead to an unfortunate mathematical issue in the updatePool
function which inflated the pool.accRewardsPerToken
- At Dec-28-2020 12:00:21 PM +UTC, the Grap Finance Deployer account deposited the new balancer pool tokens in the Blacksmith contract.
- The second issue that made this exploit possible was the incorrect usage of
memory
and storage
keywords. Note the memory
and storage
keywords allowed the exploit to happen, but the maths issue inflated the exploit amount to the insane amount.
Short Guide on memory
and storage
The memory
keyword makes a copy of a variable so that you can use the copy of the variable to do something without changing the original variable. Whereas the storage
keyword can do operations on the original variable (does not make a copy).
Here is a nice guide if you are interested to know more about memory
and storage
variables.