Abracadabra Money Hack Analysis
Abracadabra Money is a decentralized finance (DeFi) lending platform that lets users leverage their interest-earning crypto assets by using them as collateral to take out USD-pegged loans.
On October 4, the protocol experienced an exploit in its “cooking” functionality, resulting in a loss of around $1.7 million. The underlying cause appears to stem from shared mutable state across multiple cooking actions, which allowed an attacker to manipulate interactions that were not intended to interfere with each other.
Overview
Attacker: MIM_Spell Exploiter
Attack contract: 0xB8e0A4758Df2954063Ca4ba3d094f2d6EdA9B993
Vulnerable contacts:
Analysis
Since the attack was repeated across six contracts, we analyze only the first instance as outlined below:
The attack is straightforward: it involves calling the cook()
function of the target contract with actions = [5, 0]
. Based on the source code of cook()
, action 5
corresponds to ACTION_BORROW
, where the associated datas parameter includes the (amount, to)
values. Meanwhile, action 0
is undefined and therefore processed by the final else block in the loop.
So, what exactly is the issue in this case?
Let’s break it down step by step:
For
ACTION_BORROW
, the contract extracts the(amount, to)
parameters, calls_borrow()
, and then setsstatus.needsSolvencyCheck = true
to trigger a collateral verification at the end of the function.For
action = 0
, since it is undefined, execution falls to the final else block, where the contract calls_additionalCookAction()
- which itself is empty - and then updatesstatus
with the value ofreturnStatus
.
Since _additionalCookAction()
is empty, it returns all zero values - including returnStatus
. This effectively resets status.needsSolvencyCheck
to false
, causing the function to skip the collateral verification at the end. As a result, the attacker can borrow funds without providing the corresponding collateral.
The attacker repeated this process across 5 additional contracts, borrowing a total of approximately 1,724,494 MIM tokens. These tokens were then swapped sequentially from MIM → DAI → USDC → WETH → ETH. Finally, the attack contract executed a self-destruct operation, transferring around 395 ETH in profit to the attacker’s wallet.
Summary
The incident occurred due to a flaw that allowed normal security checks to be bypassed, enabling unauthorized borrowing and resulting in losses of around $1.7 million. This highlights the importance of careful design and validation in decentralized finance systems, where even small oversights can lead to major financial damage. To prevent similar issues, developers should prioritize robust testing, continuous monitoring, and most importantly, conduct thorough security audits before deploying any smart contract.