Analysis of Hack of Feminist Metaverse
Feminist metaverse(@FM_Token) got hacked on 18 May 2022. This article provides an incident report by the SmartState team.
The attacker was able to gain a total of 1838 BNB(approx. 537k USD).
FM token contract: https://bscscan.com/address/0x843528746f073638c9e18253ee6078613c0df0f1
One of the attack transactions: https://bscscan.com/tx/0xfdc90e060004dd902204673831dce466dcf7e8519a79ccf76b90cd6c1c8b320d
The Feminist metaverse project is built around the FM token. The FM token is an ERC20 token with some extra features. One of the features is that it takes fees from swapping the token and accumulates them on the token’s contract balance. After enough tokens have been accumulated they are transferred to the token’s pair balance, a similar example is the SwapAndLiquify function in SafeMoon and other deflationary tokens. However, this functionality brings vulnerability to this project.
Above is a part of the code from the FM token internal _transfer method, which is called by transfer and transferFrom methods. As described above, when enough tokens have been accumulated on the contract’s balance they are added to the token’s pair address. However, it’s not safe to add tokens directly to the pair’s balance.
Uniswap V2 type pairs (in this case it was SakeSwap) have a skim function, which allows users to claim the difference between tokens pairs balances and actual reserves. In case tokens are added correctly via swap or liquidity methods, the reserves match the tokens balance, but in case they are simply transferred to the pair, the values are different. This functionality allowed the attacker to claim the difference from the pair contract, due to the vulnerable code in the FM token. However, the attack was something more than just claiming all accumulated funds from the pair.
The attacker calls the skim function on the pair address
Firstly, the attacker calls the skim function and claims the tokens difference from the pair address (https://bscscan.com/tx/0x755d18c9c954f3a9052c43a15db32ae31c2bf7adcee047f89f631b774a180111). This could have been the first and only step of the attack (at least until new tokens had accumulated), if it wasn’t for another interesting factor.
Some address had transferred 1.2 billion of tokens to the FM token address (https://bscscan.com/tx/0xe7755138e4bf3d3f5ef0eb24d03f164faaced099bbd50af6a428bc6567875f87). This address was mentioned in the token contract’s code:
Note, that the amount of tokens transferred to the pair’s address when enough tokens have accumulated is 150k.
So, the fact that this contract has now 1.2 billion of tokens means that each transfer of an FM token will send 150k tokens to the pair’s address.
The attacker created a smart contract that was calling a transfer function with the amount of 0.0000000000001 FM tokens to the attacker’s another address, because any amount of tokens in the transfer function is enough to invoke the pair’s balance increase, the only limitation is the minimal amount of 150k tokens on the contract’s address.
Each call to the attacker’s smart contract was transferring tokens about 500 times, which allowed them to gain about 75 millions of tokens on the pair’s address per one call. Then they just called the skim function again and transferred all the new tokens from the pair’s address to their own address
The attacker was repeating these steps until they drained all 1.2 billion tokens from the FM’s token contract address.