Breaking Down the $6.5M Abracadabra Money Hack: A Detailed Analysis of the Cauldron V4 Exploit
Intro
Welcome to ‘Block Forensics,’ our new series where we analyze some of the most interesting hacks in blockchain. Our opening feature dives into the $6.5M Abracadabra Money Hack, providing a detailed examination of the Cauldron V4 exploit and its implications for DeFi security.
Background
Abracadabra Money is a pioneering DeFi lending protocol that empowers users to borrow its omnistablecoin MIM token using various types of collateral. Recently, the protocol faced a significant challenge when an attack exploited its V3 and V4 Cauldrons, leading to the unauthorized borrowing of MIM tokens. The attack not only resulted in a substantial $6.5 million loss but also caused the MIM stablecoin to depeg.
Deep dive
For those keen to delve into the technical details, you can explore the CauldronV4 vault contract here. Let’s break down the core components of this exploit.
Cauldrons, which are Abracadabra’s vaults, track borrowed funds in two ways:
1. Elastic: represents the total token amount to be repaid by borrowers, which can fluctuate due to interest rates.
2. Base: represents the total parts of the debt that all borrowers hold, offering a more stable representation of the debt for internal calculations.
The attacker exploited the precision loss by repeatedly calling userBorrowPart()
and repay()
from within V4 Cauldron.
In the snippet below, part
represents the borrowed amount of the user's share in the total debt e.g. totalBorrow.base
.
Before we continue, let’s look at the Rebase Library’s add
and sub
functions:
Steps taken in the attack
- The attacker took a flashloan of MIM tokens from
Abracadabra.Money: Degenbox
and donated the tokens to theBentoBox
contract.
2. The attacker then called the repayForAll()
function in CauldronV4
, which repaid the debt for all borrows and set the elastic to 0.
3. When totalBorrow.elastic
was set to 0, totalBorrow.base
was supposed to also drop to 0. However, the logic to drop the base to 0 wasn’t included, resulting in the base staying at 6.
4. This discrepancy between the values of totalBorrow.elastic
and totalBorrow.base
wasn’t accounted for by the Rebase library. As a result, the attacker was able to borrow and repay a single token repeatedly, which meant that the value of part
rose to an exponentially large number. This was because the base stayed at 6 in Step 3.
5. BecausetotalBorrow.base
was not being updated as intended, the final debt or the solvency checks implemented by the protocol were redundant. The borrowed part
value was extremely negligible in comparison to the total debt parts fed using _totalBorrow.base
, allowing the attacker to drain all the liquidity from the pool.
6. The library’s add
and sub
functions were affected, which get called in the borrow and repay functions.
A solution for Remediation
The library is not storing the new base value in CauldronV4. Therefore, we could have a function that updates the Rebase
struct in CauldronV4.
This function should be called within repayForAll()
and any other function where the elastic changes in value.
Conclusion
We hope you’ve gained some insights into the complexities of the $6.5M Abracadabra Money Hack and the broader implications for DeFi security. Stay tuned for more articles of ‘Block Forensics’, where we’ll continue to dissect the mechanics behind the most intriguing and impactful breaches in blockchain. Together, let’s learn from these incidents to develop stronger, more resilient systems.