What exploit happened today for GoCerberus and Garuda, also for KetchupSwap, Lokum, YBear, Piggy, CaramelSwap and our rough compensation plan
Dear Garudians and Cerberions community,
Today, June 16th, multiple farms their native tokens were exploited all the way to $0.00. KetchupSwap, Lokum, YBear, Piggy, CaramelSwap. Sadly enough GoCerberus and Garuda were exploited as well.
Are the funds safe?
All non-native funds in our contracts are safe, and you are able to withdraw them without a problem. The exploit limits itself specifically to the native token only, and when executed it allowed the exploiter to amplify their rewards by a massive amount to effectively mint as many tokens as they want.
How did it start?
The exploit is not inherent to our contract. Most of the yield farms use a trusted contract called a MasterChef, which is used even by PancakeSwap themselves to distribute rewards. The problem is that the MasterChef was never designed for all these special tokens, it was designed specifically to receive rewards for LP tokens.
But, yield farms kept popping up and adding non-LP tokens and everything was fine. Until recently tokens with a transfer fee became more popular. Most of our tokens have a transfer fee as well, it’s how we can have our tokenomics. But the problem is that the MasterChef was not designed for this.
Due to the design of the masterchef if you stake 100 tokens (with a 5% transaction fee) in a MasterChef, you are still able to withdraw 100 tokens from the MasterChef. But due to the transfer fee, only 95 tokens actually arrived in the contract. We actually figured that this would happen with our native token GoCerberus, and we updated the masterchef to deduct the transaction fee from the balance, eliminating the issue.
But sadly enough we did not add this code to our non-native pools. This wasn’t such an issue, none of the non-native tokens have a transaction fee… Except for the Garuda token. Earlier today we noticed that the Garuda pool balance was getting smaller and some users reported that they could no longer withdraw. We had disabled depositing to this pool and started to think about a compensation plan. We understood that the issue had to do with the transaction fees at this time but did not know that this could be further exploited.
This is one of the exact reasons why we need to evolve to THOREUM masterchef.
In our THOREUM masterchef, every token with transaction fee will be checked and calculated exactly from the time they deposit so this will not happen ( Rugdoc.io have a scan on this and can confirm this). But in the near future we will double safe by not add pool for any deflationary token before we can confirm that their transaction fee is a fixed number that cannot be changed.
The initial drain
Due to the inner workings of the Masterchef, once user balances grow larger then the total token balance in the pool, they effectively get a multiplier on their rewards. Anyone that was still in the Garuda pool was getting way larger harvests then they should. Until the point came that so much Garuda was withdrawn from the Garuda pool, that this multiplier became so large that a single harvest harvested all GoCerberus in the masterchef, about 40 million tokens (worth $190k at the time).
So why is it that when the user balances are larger then the pool tokens, that users get a multiplier on their harvests? Again, it is because the masterchef developers never expected there to be a mismatch in these numbers:
In the masterchef, the rewards per staked token are actually calculated by dividing the pool emissions by the total tokens in the contract.
So, if there is 1 token remaining in the masterchef, the rewards per token are equal to the total emissions of that pool. So what happens in our previous case when there may only be 0.001 token in the pool and users still have a balance of thousands of tokens? Their harvests are thousands of times larger then what they should be
We believe that after KetchupSwap was exploited today, quickly some people realized this and got the balance in the pool so low that they could take all the tokens out of the masterchef in one go.
We are aware of this logic and completely eliminated it in our THOREUM masterchef. THOREUM already has more rigid logics to check for all possibility before transfer and make sure no one can transfer if supply is zero or less. (detail will be published in another article).
The second drain
So at this point all GoCerberus tokens were out of the masterchef, we quickly noticed this and took the actions we could. We started thinking of action plans to compensate the users. For some reason, after the initial drain, GoCerberus was still worth $0.005, so the damage was large but still limited.
Until 30 minutes later, the value of GoCerberus dropped to exactly $0. The token supply also increased to a number to large to write here. So somehow, exploiters were able to mint even more GoCerberus then the tokens available in the MasterChef. We believed that once the MasterChef was out of tokens, there were no more coins to steal. The issue lies with the referral systems of the MasterChef. When you do a simple harvest, the reward is transferred from the MasterChef to you, so you cannot take more tokens than the tokens present in the MasterChef, this is because we have a function safeCerberusTransfer that does not allow to return more.
But, the referral system of the MasterChef sadly enough does not use safeCerberusTransfer. Instead, it mints tokens directly to the referral:
We also eliminated this minting function in THOREUM, you can see no mint function in THOREUM contracts.
Thus, about 30 minutes later, we believe someone figured this out and was able to mint an unimaginable large amount of tokens to their referral, all because of the transaction fee on one single pool, the Garuda pool… The whole MasterChef was secure but it relied on the assumption that the total tokens in the contract would always be equal to the total sum of deposits. An assumption which many protocols did not know about. Today, many of these protocols, including ourselves, got exploited.
What we tried to do
After the initial drain, we realized what was happening and we noticed that there was still over $500k in value in the LPs. We quickly setup an emergency team to figure out a way to secure that money so it could be used for compensation. As we understood at this time that it was only a matter of time before these LPs would become worthless.
After discussing with our engineers, we thought about a method to ‘whitehat’ these funds and had actually started developing and deploying the contracts for this (essentially they would use the referral method above to mint a large amount of tokens). Although we believed we would have been able to secure these funds given a bit more time, we were not able to deploy and execute the whitehat contract our devs developed within time and at some point we were informed that it was ‘too late’. A very stressful call where everyone on the team was doing everything they could became silent. We did what we could. Sadly enough so many other projects today were vulnerable to the same exploit. It is a novel exploit and nobody was ready for it. We did our absolute best to salvage the remaining funds.
Our THOREUM contracts is completely safe from this attack
We designed Thoreum with safety in mind and we are the first Masterchef contract that take deflationary token , token with transaction fee, in consideration. This exploit cannot be happen in our Thoreum contracts as we have many safety check function. We will give details about Thorum contracts in another article when we have time.
Our compensation plans for the future
Because of BlockChain technology, our developers are able to make a snapshot of everybody’s balances right before the exploit. In the upcoming days, we will work out a detailed compensation plan for everybody that was holding Cerberus or Garuda either in an LP token, in their wallet or staking it to earn yield. But basically it will work like this
1. We will identify a block number before the first exploit and take a snapshot
2. We will identify the holder list of Cerberus, Garuda at that block ( either in LP pair, in LP pool, in single pool, in wallet)
3. We will use web3 technology to calculate the number of their holding
4. We will make a web tool so each user can enter a wallet and check this number
5. Make a new compensation tokens, for example GARUDAcomp and CERBERUScomp
6. Send the new token to the holders, number exactly match number of old token
7. Make a swap contract so holders of new token can swap their token for a valued token at that time, swap ratio will be based on the value of GARUDA and CERBERUS at the time of exploit and the value of the valued token at the time of swap.
8. This valued token will come from our dev fund, we do not mint new tokens to circulating supply, so it will not affect any current holders of this valued token.
This is roughly the plan, we will make more detailed one in the future. We know that this should happen soon so we are talking with a professional team to do this services for us. But this will take time, because it is complicated, so please be patience with us!
Thank you for your understanding and support