Abracadabra integrated Hexagate for automated incident response, configuring it to halt borrowing in cauldrons across supported chains when detecting high or critical issues in monitored contracts. This was achieved through a single permissioned call to the Cauldron Owner contract. The monitors were systematically set up for all cauldron deployments listed in the abracadabra-money-contracts GitHub repository as of 07/02.
Hexagate runs a proprietary ML process to classify transactions and suspicious contracts targeting monitored contracts.Hexagate did detect the incident on the DegenBox vault contract which held the ERC20 tokens exploited during the attack. Unfortunately, no monitor had been set on the vault contract but on the affected cauldrons.In hindsight, DegenBox should have been included in the monitoring set of contracts as it would have raised an alarm due to the attacker withdrawing the funds from the contract and thus triggering an automated response that could have prevented the hack.The effectiveness of our usage of the Hexagate platform would have been increased for every contract added to the platform, with the best state being different monitors configured for the different components of the Abracadabra DAO ecosystem. This stems from a lack of understanding of the intricacies of the platform.
The affected GMXCauldronV2 contract was reviewed by Guardian, as documented in their audit report dated November 14, 2023 (audit PDF). Abracadabra DAO selected Guardian as its primary audit partner due to their deep expertise with GMX, having previously audited GMX V2 and its associated contracts. An update to the OrderAgent implementation to support compatibility with GMX V2.1 was also reviewed by Guardian on November 28, 2024, with corresponding test updates completed concurrently (see PR #233).
gmETH - 0x2b02bBeAb8eCAb792d3F4DDA7a76f63Aa21934FA
gmBTC - 0xD7659D913430945600dfe875434B6d80646d552A
gmSOL - 0x7962ACFcfc2ccEBC810045391D60040F635404fb
gmBTC/BTC - 0x9fF8b4C842e4a95dAB5089781427c836DAE94831
gmETH/ETH - 0x625Fe79547828b1B54467E5Ed822a9A8a074bD61
Attacker Wallets
1: 0xe9A4034E89608Df1731835A3Fd997fd3a82F2f39 (mainnet+arbitrum)
2: 0xa47359F87509D783EBB3daA0b75F24ED07888306 (arbitrum)
3: 0x08606858ee5941af37e46f47012689cf83052b56 (arbitrum)
4: 0x4Ade855c2240099c20e361796c8f697d1Bdb6938 (arbitrum)
5: 0x51c9d0264d829a4F6d525dF2357Cd20Ea79b5049 (arbitrum)
6: 0xAF9e33Aa03CAaa613c3Ba4221f7EA3eE2AC38649 (mainnet+arbitrum, laundering wallet)
Mar 25th, 6 am UTC
Wallet 1 gets funded through Tornado Cash 1 ETH
Wallet 6 gets funded through Tornado Cash 10 ETH (10 x 1ETH)
uses Stargate to bridge ETH to Arbitrum
Wallet 1
Wallet 6
Wallet 1 Acquires 3.31700399 gmETH/ETH Token thru GMX
Wallet 1 interacts with gmETH/ETH Cauldron (used to set approval on the master contract only)
Wallet 1 distributes 0.5 gmETH/ETH to Attacker Wallets 2,3,4,5
Wallet 1 transfers 0.1 ETH to each of the attacker wallets 2,3,4,5
Wallet 2,3,4,5 approve master contract and deposit 0.5 with gmETH/ETH Cauldron (used to set approval on the master contract only)
Wallet 1 creates Exploit Contract 0xf29120acd274a0c60a181a37b1ae9119fe0f1c9c
Wallet 6 sends 9.93 ETH to exploit contract
Following the exploit, the attacker utilized EOA 0xaf9e33aa03caaa613c3ba4221f7ea3ee2ac38649 to bridge ETH via Stargate, subsequently laundering the funds through Tornado Cash on Ethereum mainnet.
The AbracadabraDAO team was made aware of the incident by ZeroShadow at 9.31 am UTC, at a point in time when the attacker was concluding his attack.
The attack was neutralized through immediate protocol adjustments:
Borrow Pause: Borrowing was disabled across all GM cauldrons, preventing further liquidations or undercollateralized MIM issuance.
OrderAgent Nullification: The orderAgent address was set to 0x0000000000000000000000000000000000000000, halting new deposit creation.
In the aftermath of the exploit, Abracadabra undertook efforts to recover funds trapped within multiple GmxV2CauldronRouterOrder contracts. These efforts successfully reclaimed approximately $260,000 USD in assets that remained vulnerable to theft by the attacker post-exploit.
The attack was a multi-vector assault targeting five distinct GM cauldrons within the Abracadabra ecosystem. It unfolded across 56 transactions, systematically exploiting each cauldron multiple times. The attack methodology relied on a two-phase transaction structure: an initial setup transaction to establish exploitable conditions, followed by an execution transaction to mint undercollateralized MIM.
The campaign commenced on March 25, 2025, at 07:57:52 AM UTC with the first setup transaction. The inaugural exploit transaction followed swiftly at 07:58:06 AM UTC, minting $44,390 of undercollateralized MIM. The attacker sustained this effort over approximately one hour and forty minutes, with exploit transactions continuing until 09:37:36 AM UTC. The assault was halted when the borrow limit across all GM cauldrons was reduced to zero at 09:46:22 AM UTC.
The total amount of undercollateralized MIM borrowed is roughly 13.4 Million, no user collateral is affected.
The Abracadabra GMX V2 cauldrons integrate with GMX to facilitate collateral deposits via a two-step process. Each deposit initiates an action request to GMX, managed by a dedicated GmxV2CauldronRouterOrder contract instantiated to track the deposit’s lifecycle.
Successful Deposit: Upon completion, the GmxV2CauldronRouterOrder contract receives GM LP tokens, credits them to the cauldron via the DegenBox, and updates the user’s collateral balance in the GmxV2CauldronV4 contract.
Failed Deposit: If the deposit fails, GMX returns the input tokens to the GmxV2CauldronRouterOrder contract. The collateral value is then reported as orderValueInCollateral, calculated as the lesser of the market token’s minOutputAmount or the inputAmount of input tokens.
The exploit originated from an issue in the GmxV2CauldronV4 contract’s collateral accounting mechanism, specifically within its custom liquidate function. When a position is liquidated and its DegenBox collateral shares are insufficient to cover outstanding debts, the function draws additional collateral from the GmxV2CauldronRouterOrder contract (via the OrderAgent) to settle the debt.
However the order is not tracked as being closed for the user in the Cauldron and the reported orderValueInCollateral is not updated.
This discrepancy allowed the attacker to borrow against “phantom collateral”, a reported value that no longer existed, resulting in undercollateralized loans.
The attacker exploited this vulnerability in two distinct phases, utilizing the cook action, a feature enabling the composition of multiple operations within a single transaction, incorporating flash loan logic for borrowing, with solvency checks deferred until all actions are complete. In both phases, every call action (Action 30) within the cook transactions invoked an attacker-controlled exploit contract at 0xf29120acd274a0c60a181a37b1ae9119fe0f1c9c, orchestrating the operation.
This attack is only possible in the case where the deposit to GMX fails and input tokens are returned to the GmxV2CauldronRouterOrder contract. The attacker achieved this by assigning a minimum GM token output amount that was unachievable based on the input token amount, GMX then reverts the deposit and returns the input tokens,
The deposit request to GMX was created through the cauldron cook action along with a borrow to seed the initial deposit in the first step of the attack.
An example transaction for this first step can be seen here.
For the second step, this exploit transaction is a companion to the first transaction referenced above.
The subsequent cook transaction executed the exploit through a precise sequence of actions:
Borrow (Action 5): The GmxV2CauldronRouterOrder contract must have enough collateral to cover the outstanding debts during a liquidation, and to achieve a complete liquidation the attacker will borrow an amount that could be greater than the value of collateral that is available in the GmxV2CauldronRouterOrder. Therefore to ensure the liquidation is able to succeed, the actor provides additional tokens to be able to withdraw from the GmxV2CauldronRouterOrder contract during liquidation. This first borrow is used to fund these additional tokens.
Call (Action 30): The attacker makes an external call to their own deployed attack contract to invoke the get_before_liquidate_amount function. This function computes the amount that the attacker will borrow to not only become liquidatable but also retrieve as much input tokens from the GmxV2CauldronRouterOrder during the liquidation as possible. As mentioned in the previous step, the attacker will specify an amount even greater than the amount coverable and so, in this step, a portion of the borrowed funds, 3640 USDC in our example transaction, from the first step are withdrawn, swapped, and sent to the GmxV2CauldronRouterOrder contract to ensure that the liquidation can pass.
Borrow (Action 5): Executed the calculated borrow, driving the position’s loan-to-value (LTV) ratio beyond the 75% threshold for the GM Sol-USDC cauldron. For example, at address 0x2ca694563cf89dd1e0e712f5ac0fa791e6865a02, the orderValueInCollateral reported 15,074 GM Sol-USDC tokens (valued at ~$60,000, with a $4 token price). Prior borrowing included 42,000 MIM from the setup phase, followed by 10,000 MIM and 7,880 MIM in this phase, triggering liquidation eligibility.
Liquidate (Action 31): Executed the liquidation of the position, the liquidation removes the backing USDC collateral from the GmxV2CauldronRouterOrder contract and sends it to the attacker. The attacker then uses this value to pay down the position’s debt to carry out the liquidation. The exploit has not been realized yet, but the root cause has occurred. The GmxV2CauldronRouterOrder is still credited to the user and still reports an orderValueInCollateral of 15,074 GM Sol-USDC tokens, meanwhile the collateral in the GmxV2CauldronRouterOrder contract has been removed
Call (Action 30): The order should have been removed from the user’s collateral tracking at this point, however since it is still credited to the user the attacker can borrow against it. The fifth action in the cook transaction is an external call to the attacker’s contract to determine the maximum amount that they can borrow against the phantom collateral.
Borrow (Action 5): With the returned value from the get_after_liquidate_amount function the attacker borrows the maximum amount that they can.
Call (Action 30): With these unbacked borrowed funds the attacker performs a final step to make an external call to their external contract to withdraw and swap all of the borrowed MIM through MIMSwap to realize the exploit.
Chainalysis, ZeroShadow and members of Seal 911 are tracking the hacked funds, and tracing back the attackers steps.
Because of the way the attack was uniquely executed, a strong lead has been identified.
We are awaiting to communicate with the hacker on-chain, as well as through reward@abracadabra.money.
On-chain messages have been sent to the addresses holding the stolen funds: