Abracadabra xSUSHI stale-rate exploit
Exploit Transactions
0x3d163bfbec5686d428a6d43e45e2626a220cc4fcfac7620c620b82c1f2537c78Victim Addresses
0xbb02a884621fb8f5bfd263a67f58b65df5b090f3Ethereum0xf5bce5077908a1b7370b9ae04adc565ebd643966EthereumLoss Breakdown
Similar Incidents
Balancer bb-a-USD stale-rate exploit
42%CauldronV4 solvency-check bypass enables uncollateralized MIM borrowing
33%TheNFTV2 Stale Burn Approval
32%Stranded Swapper Sweep
32%Floor DAO Stale Epoch Harvesting
32%OxODex Stale Withdrawal Drain
32%Root Cause Analysis
Abracadabra xSUSHI stale-rate exploit
1. Incident Overview TL;DR
Abracadabra's xSUSHI Cauldron was exploited in transaction 0x3d163bfbec5686d428a6d43e45e2626a220cc4fcfac7620c620b82c1f2537c78 on Ethereum block 15928290. The attacker flash-loaned xSUSHI, posted it as collateral, borrowed MIM against a stale cached collateral exchange rate, refreshed the oracle to the higher current rate, and then self-liquidated the now-insolvent position. The end result was a transfer of 110911161654715069023439 MIM to the attacker EOA.
The root cause is that CauldronMediumRiskV1.borrow() accepted credit using the stored exchangeRate without first refreshing it from the oracle. When that cached rate lagged materially below the current oracle rate, the borrow admission check overstated the collateral value and let the attacker open debt that was already insolvent under current pricing.
2. Key Background
Abracadabra cauldrons are isolated lending markets built on BentoBox. Users deposit collateral as BentoBox shares and borrow MIM subject to a collateralization constraint. This market used xSUSHI as collateral through ChainlinkOracleV2 at 0x00632cfe43d8f9f8e6cd0d39ffa3d4fa7ec73cfb, with oracleData pointing to xSUSHIOracleUSD at 0xe4e58df3956bc6423a62e87ddd99ca3120f1dd4b.
The xSUSHI oracle path is fully public and deterministic. ChainlinkOracleV2.get() decodes the configured oracle addresses and decimals, then computes the rate through _get(). xSUSHIOracleUSD.latestAnswer() derives xSUSHI value from public Chainlink price feeds and the on-chain SushiBar backing ratio sushi.balanceOf(bar) / bar.totalSupply(). The cauldron caches the resulting value in storage as exchangeRate, and any user can refresh it by calling updateExchangeRate().
3. Vulnerability Analysis & Root Cause Summary
The vulnerability is inconsistent oracle freshness across borrow admission and liquidation. In the verified CauldronMediumRiskV1 source, _isSolvent(address user, uint256 _exchangeRate) evaluates solvency using the _exchangeRate argument. The solvent modifier executes require(_isSolvent(msg.sender, exchangeRate), "Cauldron: user insolvent");, so it uses the stored exchangeRate variable after the function body runs. borrow(address to, uint256 amount) is declared public solvent, calls accrue(), and then _borrow(to, amount); it does not call updateExchangeRate() before issuing credit.
That design is safe only if the cached exchangeRate is sufficiently fresh. Here it was not. At the pre-state before block 15928290, the cauldron stored exchangeRate = 387970202315884682, while the current oracle output was already 533537989524363604. Because a higher exchange rate means more collateral is required per unit of MIM debt, the stale lower rate made the attacker appear solvent for a borrow that should have been disallowed. Once the attacker refreshed the oracle in the same transaction, the position became liquidatable immediately. Liquidation then returned the xSUSHI collateral, allowing flash-loan repayment while the excess borrowed MIM remained as profit.
4. Detailed Root Cause Analysis
The exploitable precondition was a large gap between the stored and current xSUSHI exchange rates. The analysis records the pre-state as block 15928289, with the cached value 387970202315884682 and the fresh oracle value 533537989524363604. That delta was enough to let 418303133561411935643097 xSUSHI amount support a stale-rate debt ceiling of 808637746657725724709524 MIM units, while the fresh-rate ceiling was only 588013143076727120979650.
The attacker borrowed 808233600000000000000000 MIM before the opening fee, which fits under the stale-rate ceiling but exceeds the fresh-rate ceiling by 220624603580998603729874 units. The trace confirms the sequence: deposit xSUSHI into BentoBox, add that collateral to the cauldron, and borrow MIM while the cached rate is still active. The relevant borrow leg emitted LogBorrow and transferred 808233598391674532913372 MIM shares from the cauldron to the attacker helper.
Immediately after borrowing, the attacker invoked updateExchangeRate(). The trace shows ChainlinkOracleV2::get(...) returning true, 533537989524363604, followed by LogExchangeRate(: 533537989524363604) and a storage write updating slot 10 from the stale value to the fresh one. With the correct rate in place, the position no longer satisfied the solvency inequality.
The attacker then called liquidate(...) against its own position. The trace shows LogRemoveCollateral returning essentially the full xSUSHI collateral and LogRepay covering 696904465868713624864768 MIM amount, with the BentoBox MIM transfer back to the cauldron recorded as 696904464481924953145286. After liquidation, the helper withdrew the recovered xSUSHI and residual MIM from BentoBox, swapped 417972476571306111792 MIM for 225000000000000000003 xSUSHI to cover the flash-loan fee, repaid BentoBox 450225000000000000000000 xSUSHI, and finally transferred 110911161654715069023439 MIM to the attacker EOA.
The balance diff independently confirms the outcome. BentoBox lost 111329134131286375135231 MIM, the Sushi route consumed 417972476571306111792 MIM to buy fee coverage, and the attacker EOA gained exactly 110911161654715069023439 MIM.
5. Adversary Flow Analysis
The adversary EOA was 0xb7ea0f0f8c6df7a61bf024db21bbe85ac5688005, and the helper contract executing the exploit path was 0x8c761066bc6c20e9c65ece9972a9eb6ed511fd4d. The transaction was a single atomic ACT sequence; no privileged role, private key compromise, or private orderflow was required.
The execution flow was:
1. Flash-loan 450000 xSUSHI from BentoBox.
2. Deposit 418285898000000000000000 xSUSHI shares into BentoBox.
3. Add those shares as cauldron collateral.
4. Borrow 808233600000000000000000 MIM using the stale cached exchange rate.
5. Refresh the oracle so the cauldron stores the higher current rate.
6. Liquidate the now-insolvent position and recover the xSUSHI collateral.
7. Withdraw recovered xSUSHI and residual MIM from BentoBox.
8. Swap 417972476571306111792 MIM for 225000000000000000003 xSUSHI to cover the flash-loan fee.
9. Repay 450225000000000000000000 xSUSHI to BentoBox.
10. Transfer 110911161654715069023439 MIM profit to the attacker EOA.
This is ACT because every required step is public: batchFlashLoan, addCollateral, borrow, updateExchangeRate, and liquidate are permissionless, the oracle inputs are on-chain/public, and the attacker-side helper is a generic contract any user could deploy.
6. Impact & Losses
The realized loss was protocol inventory depletion in MIM. The attacker extracted 110911161654715069023439 MIM from the BentoBox-backed cauldron system after covering the flash-loan fee. The directly affected victim component was the Abracadabra xSUSHI Cauldron at 0xbb02a884621fb8f5bfd263a67f58b65df5b090f3, with BentoBox at 0xf5bce5077908a1b7370b9ae04adc565ebd643966 serving as the custody layer that ultimately bore the inventory decrease recorded in the balance diff.
This loss was not caused by price manipulation, privileged access, or an external dependency outage. It was caused by the protocol using different pricing states for borrow admission and liquidation inside an attacker-controlled transaction sequence.
7. References
- Seed transaction:
0x3d163bfbec5686d428a6d43e45e2626a220cc4fcfac7620c620b82c1f2537c78 - Victim cauldron:
0xbb02a884621fb8f5bfd263a67f58b65df5b090f3 - Oracle wrapper:
0x00632cfe43d8f9f8e6cd0d39ffa3d4fa7ec73cfb - xSUSHI oracle:
0xe4e58df3956bc6423a62e87ddd99ca3120f1dd4b - Trace evidence: the collected verbose trace for the seed transaction showing the borrow,
updateExchangeRate(), liquidation, swap, repayment, and profit transfer - Balance evidence: the collected balance diff showing the attacker EOA's
110911161654715069023439MIM gain and BentoBox's corresponding MIM decrease - Verified source evidence: Etherscan verified source for
CauldronMediumRiskV1,ChainlinkOracleV2, andxSUSHIOracleUSD