Exactly DebtManager Fake-Market Exploit
Exploit Transactions
Victim Addresses
0x675d410dcf6f343219aae8d1dde0bfab46f52106Optimism0x81c9a7b55a4df39a9b7b5f781ec0e53539694873OptimismLoss Breakdown
Similar Incidents
Arcadia Self-Liquidation Bypass
30%Hundred hWBTC Donation Exploit
30%CivTrade Fake-Pool Callback Drain
24%Minto Fake-Token Purchase Exploit
24%GoodDollar Fake-Interest Mint
24%Metalend Empty-Market Donation Exploit
23%Root Cause Analysis
Exactly DebtManager Fake-Market Exploit
1. Incident Overview TL;DR
Exactly Protocol on Optimism was exploited in transaction 0x3d6367de5c191204b44b8a5cf975f257472087a9aadc59b5d744ffdef33a520e after the adversary prepared helper infrastructure in 0xeb330e1d745b4e3af3012f080a262704a3461b1620c809212d56da696c5baa22 and fake-market proxies in 0xace8c6bade64a00c9b5056691248fa1811dcb247c423589297ceec1f26ecbb85. The incident-block DebtManager proxy 0x675d410dcf6f343219aae8d1dde0bfab46f52106 was still pointing at implementation 0x16748cb753a68329ca2117a7647aa590317ebf41, a version that accepted arbitrary caller-supplied market and marketOut contracts in its leverage and cross-deleverage paths. The adversary supplied fake markets backed by malicious implementation 0x995a24c99ea2fd6c87421d516216d9bdc7fa72b4, forged victim context through DebtManager's permissive permit modifier, withdrew collateral from healthy borrowers who had previously approved DebtManager, and liquidated those borrowers inside the same batch.
The root cause is an access-control and trust-boundary failure in DebtManager, not a mere consequence of pre-existing user approvals. DebtManager let attacker-controlled contracts act as authorization roots and market interfaces, so approved victim collateral could be consumed under forged victim identity. The seed transaction reduced the exaUSDC market's USDC balance by 2643414024816 raw units and directly credited adversary EOA 0xe4f34a72d7c18b6f666d6ca53fbc3790bc9da042 with 2643414024790 raw USDC units according to the collected balance diff.
2. Key Background
Exactly's exaUSDC market lives at 0x81c9a7b55a4df39a9b7b5f781ec0e53539694873, with Auditor 0xaeb62e6f27bc103702e7bc879ae98bcea56f027e marking that market as listed at block 108375557. Borrowers in Exactly can approve DebtManager to operate on their market positions, and those delegated flows are expected to be safe because DebtManager is supposed to interact only with legitimate, auditor-listed markets. Healthy-vs-underwater status is determined by Auditor liquidity checks, and the sampled victim 0x87bf260aef0efd0ab046417ba290f69ae24c1642 was still healthy immediately before the exploit.
The critical internal mechanism is DebtManager's private _msgSender state. Its permit modifier calls safePermit on whatever token or market address the caller supplies, then sets _msgSender = p.account. In a trusted path that would let a legitimate market install the correct borrower identity for nested operations. In the incident path, the attacker supplied a fake market whose permit implementation accepted forged inputs and advanced victim nonces without a real signature.
The adversary's infrastructure consisted of helper 0x6dd61c69415c8ecab3fefd80d079435ead1a5b4d, two EIP-1167 minimal proxies 0x158a94b4219e76c86a52b8b41da535e927118267 and 0x9b88627ec60a7a45482c593e0f5d88da9bf66dbd, and shared malicious logic 0x995a24c99ea2fd6c87421d516216d9bdc7fa72b4. Those fake markets were shaped to look compatible enough with DebtManager and Market interfaces to pass through leverage and cross-deleverage code paths while redirecting callbacks into attacker-controlled logic and liquidity.
3. Vulnerability Analysis & Root Cause Summary
The vulnerability class is a protocol-level trust of unvalidated external contract inputs. Incident-block DebtManager accepted arbitrary Market interfaces in leverage, crossLeverage, and crossDeleverage, even though only auditor-listed Exactly markets were supposed to be trusted for delegated debt-management flows. At the same time, the permit modifier treated the supplied token or market contract as an authorization oracle and copied p.account into _msgSender immediately after the external safePermit call. A malicious fake market could therefore claim that a victim had permitted DebtManager, even when no real victim signature existed.
Once _msgSender was set to the victim, DebtManager continued execution as though the victim had intentionally initiated the operation. The attacker-controlled fake market then reentered DebtManager's vulnerable crossDeleverage path using a listed market as marketIn and the fake market as marketOut. Because no auditor-listing check guarded those inputs, DebtManager's Uniswap callback executed listed-market withdraw and related operations on behalf of the victim, consuming the victim's prior approval to DebtManager.
That unauthorized withdrawal depleted healthy collateral and created a shortfall that Exactly's own liquidation logic then treated as valid. The attacker helper immediately liquidated the now-underwater victim and routed seized value to adversary-controlled recipients. The protocol invariants that should have held are explicit: DebtManager should only trust auditor-listed markets, and logical user context in _msgSender should only arise from valid permits on trusted contracts. The code-level breakpoint is the combination of unchecked market parameters in leverage/deleverage entrypoints and the unguarded permit modifier.
4. Detailed Root Cause Analysis
The incident-block proxy wiring shows that DebtManager proxy 0x675d410dcf6f343219aae8d1dde0bfab46f52106 pointed to implementation 0x16748cb753a68329ca2117a7647aa590317ebf41 at block 108375558, while the proxy now points elsewhere. That matters because the collected incident-block source contains the vulnerable paths and the current implementation is not the one used during the exploit.
The relevant incident-block code is:
function crossDeleverage(
Market marketIn,
Market marketOut,
uint24 fee,
uint256 withdraw,
uint256 ratio,
uint160 sqrtPriceLimitX96
) public msgSender {
LeverageVars memory v;
v.assetIn = address(marketIn.asset());
v.assetOut = address(marketOut.asset());
v.sender = _msgSender;
...
}
modifier permit(
ERC20 token,
uint256 assets,
Permit calldata p
) {
IERC20PermitUpgradeable(address(token)).safePermit(p.account, address(this), assets, p.deadline, p.v, p.r, p.s);
{
address sender = _msgSender;
if (sender == address(0)) _msgSender = p.account;
else assert(p.account == sender);
}
_;
assert(_msgSender == address(0));
}
No auditor-listing check protects market, marketIn, or marketOut at these entrypoints. The same file only enforces auditor.markets(market).isListed inside approve, which is unrelated to exploit-time user input validation. That separation is the key defect.
The pre-state evidence confirms that exaUSDC market 0x81c9...4873 was listed and that borrower 0x87bf260aef0efd0ab046417ba290f69ae24c1642 was healthy immediately before the exploit. The borrower liquidity snapshot at block 108375557 shows collateral above debt:
2445683663052603671880000
2383671082644413329010990
The seed trace then shows the forged-permit and nested-withdraw sequence. Representative lines include a fake-market permit into the malicious implementation, followed by recursive DebtManager::crossDeleverage, a listed-market withdrawal on behalf of the victim, and liquidation:
0x995A24c99ea2fD6c87421d516216d9bDc7fa72b4::permit(0x87bF260aef0Efd0AB046417ba290f69aE24C1642, TransparentUpgradeableProxy: [0x675d410dcf6f343219AAe8d1DDE0BFAB46f52106], ...)
DebtManager::crossDeleverage(TransparentUpgradeableProxy: [0x81C9A7B55A4df39A9B7B5F781ec0e53539694873], 0x04C3fE749893cc9dDC6a6Bd08D1f3F4FD122374B, 500, 0, 0, 1461446703485210103287273052203988822378723970341)
Market::withdraw(222199043504, UniswapV3Pool: [0xe416e0Bc952569CfB07887B786E4d8a348354Ac3], 0x87bF260aef0Efd0AB046417ba290f69aE24C1642)
Market::liquidate(0x87bF260aef0Efd0AB046417ba290f69aE24C1642, 115792089237316195423570985008687907853269984665640564039457584007913129639935, TransparentUpgradeableProxy: [0x81C9A7B55A4df39A9B7B5F781ec0e53539694873])
The same trace pattern repeats for additional victims in the batch. This proves the exploit was not an isolated approval misuse by one borrower; it was a reusable attacker-controlled flow enabled by DebtManager's arbitrary-market trust.
Balance-diff evidence confirms the state impact. Victim 0x87bf...1642 lost 1779037477402 exaUSDC shares in the seed transaction, while the exaUSDC market contract lost 2643414024816 raw USDC units. The adversary cluster captured the extracted value: EOA 0xe4f34a72d7c18b6f666d6ca53fbc3790bc9da042 moved from 0 to 2643414024790 raw USDC units in the seed transaction.
5. Adversary Flow Analysis
The adversary lifecycle has three deterministic stages.
First, helper deployment: EOA 0xe4f34a72d7c18b6f666d6ca53fbc3790bc9da042 deployed helper 0x6dd61c69415c8ecab3fefd80d079435ead1a5b4d in transaction 0xeb330e1d745b4e3af3012f080a262704a3461b1620c809212d56da696c5baa22. Provenance artifacts tie this helper directly to the EOA and show it as the orchestrator for later exploit steps.
Second, fake-market deployment: transaction 0xace8c6bade64a00c9b5056691248fa1811dcb247c423589297ceec1f26ecbb85 created minimal proxies 0x158a94b4219e76c86a52b8b41da535e927118267 and 0x9b88627ec60a7a45482c593e0f5d88da9bf66dbd. Proxy reconstruction shows both are EIP-1167 clones of malicious implementation 0x995a24c99ea2fd6c87421d516216d9bdc7fa72b4, not legitimate Exactly markets.
Third, exploitation: sender 0x3747dbbcb5c07786a4c59883e473a2e38f571af9 submitted the exploit batches into helper 0x6dd6...5b4d, including seed transaction 0x3d6367de5c191204b44b8a5cf975f257472087a9aadc59b5d744ffdef33a520e and follow-on transactions 0x1526acf0d15dbf4356ff49dc76f2c6e98cf3fd2e8f5d292820ff8d4cb3388022 and 0xe8999f41e84c46d44c8ab4806a0ff4fcdffcfb2fc35aa6cfbc7078b7fbbef0ca. Inside the seed batch, the fake market accepted forged permits for multiple victims, DebtManager adopted those victims as _msgSender, listed-market withdrawals depleted collateral into attacker-controlled Uniswap paths, and the helper liquidated the resulting shortfalls. Seized market shares were routed to 0x23fd464e0b0ee21cedeb929b19cabf9bd5215019, while direct USDC reached adversary EOA 0xe4f34...a042.
This sequence satisfies the ACT model. No privileged keys, governance powers, or hidden state were required. An unprivileged attacker only needed public on-chain state, a deployable helper, fake-market contracts, and the ability to submit ordinary Optimism transactions.
6. Impact & Losses
The direct measured loss in the seed transaction is 2643414024816 raw USDC units, or 2,643,414.024816 USDC using 6 decimals. That amount appears as a USDC decrease on the exaUSDC market contract in the seed balance-diff artifact. The sample victim 0x87bf...1642 alone lost 1779037477402 exaUSDC shares in the same transaction, and multiple other healthy borrowers also lost exaUSDC shares before being liquidated.
The operational impact is broader than one transfer amount. Healthy borrowers who had previously delegated DebtManager access were forcibly moved into shortfall and liquidated through attacker-controlled fake markets. This breaks the intended approval boundary of the protocol: approvals to DebtManager were supposed to authorize Exactly's debt-management logic, not arbitrary attacker contracts posing as markets.
7. References
- Seed exploit transaction:
0x3d6367de5c191204b44b8a5cf975f257472087a9aadc59b5d744ffdef33a520e - Helper deployment transaction:
0xeb330e1d745b4e3af3012f080a262704a3461b1620c809212d56da696c5baa22 - Fake-market deployment transaction:
0xace8c6bade64a00c9b5056691248fa1811dcb247c423589297ceec1f26ecbb85 - DebtManager proxy wiring at incident block:
artifacts/collector/iter_2/address/10/0x675d410dcf6f343219aae8d1dde0bfab46f52106/proxy_wiring_summary.json - Incident-block DebtManager source:
artifacts/collector/iter_2/contract/10/0x16748cb753a68329ca2117a7647aa590317ebf41/source_clone/src/contracts/periphery/DebtManager.sol - Seed trace:
artifacts/collector/seed/10/0x3d6367de5c191204b44b8a5cf975f257472087a9aadc59b5d744ffdef33a520e/trace.cast.log - Seed balance diff:
artifacts/collector/iter_1/tx/10/0x3d6367de5c191204b44b8a5cf975f257472087a9aadc59b5d744ffdef33a520e/balance_diff.json - Exactly market and auditor source snapshot:
artifacts/collector/seed/10/0xcaa6136c4f85bca3b309b28e559fd3a27e0c40b3/src/contracts/Market.solandartifacts/collector/seed/10/0xcaa6136c4f85bca3b309b28e559fd3a27e0c40b3/src/contracts/Auditor.sol