0x8fcdfcded45100437ff94801090355f2f689941dca75de9a702e01670f361c040x6A0b87D6b74F7D5C92722F6a11714DBeDa9F3895BaseOn Base block 23514451, transaction 0x8fcdfcded45100437ff94801090355f2f689941dca75de9a702e01670f361c04 exploited Clober Rebalancer at 0x6A0b87D6b74F7D5C92722F6a11714DBeDa9F3895. The attacker EOA 0x012fc6377f1c5ccf6e29967bce52e3629aaa6025 called attacker contract 0x32fb1bedd95bf78ca2c6943ae5aeaeaafc0d97c1, which flash-borrowed WETH from Morpho, opened a fresh pool with itself as strategy, minted LP, and then reentered Rebalancer.burn from burnHook. That reentrancy let two burns settle against stale reserves and extracted 133700000000000000000 wei of WETH, which was unwrapped and forwarded as ETH profit in the same transaction.
The root cause is a reentrancy bug in Rebalancer._burn: it computes withdrawals and burns LP, then calls the untrusted strategy hook before reducing pool.reserveA and pool.reserveB. A malicious strategy can therefore recursively call burn while the contract still prices withdrawals from the old reserves.
Clober Rebalancer allows any caller to open a pool for a valid book pair and to choose an arbitrary strategy address. That strategy receives privileged callbacks through mintHook, burnHook, and rebalanceHook. The exploit does not require privileged governance, stolen keys, or private orderflow.
Morpho is relevant only as a permissionless capital source. The flash loan supplies the temporary WETH used to mint LP, but the flash loan itself behaves correctly and is not the root cause. The victim-side condition that matters is that the Rebalancer already held a publicly visible WETH balance before the attack; the pre-state balance diff shows 133707875556674808577 wei of WETH at the victim contract immediately before exploitation.
This incident is an ATTACK-class ACT exploit caused by unsafe external interaction in a stateful withdrawal path. The violated invariant is straightforward: across burns, a user must not withdraw more than its pro-rata share of pool reserves plus settled claimable amounts. Clober breaks that invariant because _burn calculates withdrawalA and withdrawalB from the current reserves, burns the LP, and then immediately invokes pool.strategy.burnHook(...) before reserve accounting is finalized.
The verified victim code shows the dangerous ordering:
withdrawalA = (reserveA + claimedAmountA) * burnAmount / supply + canceledAmountA;
withdrawalB = (reserveB + claimedAmountB) * burnAmount / supply + canceledAmountB;
_burn(user, uint256(key), burnAmount);
pool.strategy.burnHook(msg.sender, key, burnAmount, supply);
pool.reserveA = _settleCurrency(bookKeyA.quote, reserveA) - withdrawalA;
pool.reserveB = _settleCurrency(bookKeyA.base, reserveB) - withdrawalB;
Because the hook is attacker-controlled and runs before pool.reserveA and pool.reserveB are decreased, a reentrant second burn is quoted against stale reserves. The analysis in root_cause.json correctly identifies both the invariant and the exact breakpoint.
The exploit uses a freshly created pool whose strategy is the attacker contract itself. The attacker first determines a rounded stealable amount from the victim's observable WETH balance, flash-borrows twice that amount from Morpho, and opens a Clober pool pairing WETH with an attacker-controlled fake token. The attacker then mints LP using the borrowed WETH and the fake token.
The on-chain trace captures the critical sequence:
Morpho::flashLoan(WETH, 267400000000000000000, ...)
Rebalancer::open(..., strategy = 0x32Fb1BedD95BF78ca2c6943aE5AEaEAAFc0d97C1)
Rebalancer::burn(..., 133700000000000000000, 0, 0)
0x32Fb1BedD95BF78ca2c6943aE5AEaEAAFc0d97C1::burnHook(...)
Rebalancer::burn(..., 133700000000000000000, 0, 0)
WETH9::withdraw(133700000000000000000)
In the incident transaction, the attacker minted 267.4 LP and started by burning 133.7 LP. The outer _burn computed the withdrawal using reserves of 267.4 WETH and 267.4 fake-token units, then reduced total supply but had not yet reduced the pool reserves. During burnHook, the malicious strategy reentered burn with the remaining 133.7 LP. Since pool.reserveA and pool.reserveB were still unchanged, the inner burn also priced itself against the full pre-burn reserve state and withdrew 267.4 WETH and matching fake-token units. After control returned, the outer frame still completed its own 133.7 WETH payout.
That double counting is visible in the balance diff. The victim Rebalancer's WETH ERC-20 balance fell from 133707875556674808577 to 7875556674808577, a delta of exactly -133700000000000000000. The attacker EOA's native balance rose by 133540501283062363385 wei net of gas, and the difference to the full 133.7 ETH is explained by Base fee-vault deltas recorded in the native balance section.
The adversary flow is fully permissionless and single-transaction:
0x012fc6377f1c5ccf6e29967bce52e3629aaa6025 calls attacker contract 0x32fb1bedd95bf78ca2c6943ae5aeaeaafc0d97c1.attackAmount = 133700000000000000000.267400000000000000000 wei of WETH from Morpho via flashLoan.267.4 LP, burns half, and reenters burn from burnHook with the remaining LP.The trace and metadata support the identified adversary cluster:
0x012fc6377f1c5ccf6e29967bce52e3629aaa6025 is the transaction sender and final ETH recipient.0x32fb1bedd95bf78ca2c6943ae5aeaeaafc0d97c1 is the malicious strategy and execution contract.The exploit conditions listed in root_cause.json are correct: the adversary must be able to set an attacker-controlled strategy, source temporary WETH liquidity, and target a Rebalancer instance already holding WETH.
The measurable loss is 133.7 WETH from Clober Rebalancer, represented in smallest units as 133700000000000000000 with 18 decimals. The fake quote token did not carry economic value; it was only a vehicle for satisfying the pool interface while the WETH leg was over-withdrawn.
The profit predicate is also satisfied. The attacker EOA's ETH balance increased from 1.153475443767715212 ETH to 134.693976726830078597 ETH, for a net delta of 133.540501283062363385 ETH after gas and fee-vault payments. This is consistent with the contract unwrapping 133.7 WETH and forwarding the proceeds.
0x8fcdfcded45100437ff94801090355f2f689941dca75de9a702e01670f361c040x6A0b87D6b74F7D5C92722F6a11714DBeDa9F38950xBBBBBbbBBb9cC5e90e3b3Af64bdAF62C37EEFFCb0x4200000000000000000000000000000000000006src/Rebalancer.sol