Carson Pair Reserve Siphon
Exploit Transactions
0x37d921a6bb0ecdd8f1ec918d795f9c354727a3ff6b0dba98a512fceb9662a3acVictim Addresses
0xe0a3e0f7e4c789747eb29a212ea915a7a1e1ac69BSCLoss Breakdown
Similar Incidents
CS Pair Balance Burn Drain
40%GoldCoin Pair Reserve Overwrite
39%StarlinkCoin Pair Drain
37%APE2 Pair Burn Exploit
37%CFC Reserve Collapse
36%Sheep Burn Reserve Drain
36%Root Cause Analysis
Carson Pair Reserve Siphon
1. Incident Overview TL;DR
On BSC block 30306325, transaction 0x37d921a6bb0ecdd8f1ec918d795f9c354727a3ff6b0dba98a512fceb9662a3ac exploited the Carson/USDT pair at 0xe0a3e0f7e4c789747eb29a212ea915a7a1e1ac69. An unprivileged EOA, 0x25bcbbb92c2ae9d0c6f4db814e46fd5c632e2bd3, called attacker contract 0x9cffc95e742d22c1446a3d22e656bb23835a38ac, sourced public USDT liquidity through DODO flash loans, bought Carson, and then sold Carson back into the pair in 51 chunks.
The root cause is a broken swap path in Carson's custom pair design. The pair prices Carson-to-USDT sells using the full Carson balance increase, but before it syncs reserves it calls helper 0xD092A69Dd806bd0f49E69739770784CDa896c07b and transfers 60% of that Carson from the pair balance itself to the dead address and the marketing address. That reserve shrink is not reflected in the quoted USDT output, so repeated sells become artificially profitable. The transaction drained 100677.049295746860016399 USDT net from LP-held liquidity and cost the sender exactly 56095692000000000 wei-BNB in gas.
2. Key Background
Carson does not use a vanilla PancakeSwap pair. Its pair contract is an unverified but bytecode-identifiable Uniswap-V2-style contract whose selector table includes swap(uint256,uint256,address,bytes), token0(), token1(), and factory(). On-chain reads tie the pair to Carson token 0x0acd5019edc8ff765517e2e691c5eef6f9c08830, USDT 0x55d398326f99059ff775485246999027b3197955, and helper/factory 0xD092A69Dd806bd0f49E69739770784CDa896c07b.
Carson itself is fee-on-transfer. Normal buys and sells already route portions of Carson to reward trackers, the dead address, and a marketing address. The exploitable behavior here is different: the pair itself pays extra Carson out of its own reserves after pricing a swap. That means the pair's internal accounting path matters more than the token's transfer tax alone.
The helper contract is also unverified, but its selector table exposes 0x64a115b4(address) and 0x918b6c8d(address,address) alongside factory-like methods such as createPair(address,address) and getPair(address,address). Direct calls against (pair, Carson) return:
Origin: helper fee configuration call
recipient0 = 0x000000000000000000000000000000000000dEaD
fee0 = 300000000000000000
recipient1 = 0x4D9bD49b7383B88477724428556c7fe36d7e6bc4
fee1 = 300000000000000000
The same helper call against (pair, USDT) returns zeros, so only the Carson side is siphoned from reserves.
3. Vulnerability Analysis & Root Cause Summary
This incident is an ATTACK, not MEV arbitrage and not privileged abuse. The protocol bug is a reserve-accounting error inside the pair's swap path. For a Carson-to-USDT sell, once the pair has measured the Carson input and computed amount1Out, the pair should only sync reserves consistent with that priced input, less the AMM fee already embedded in the invariant formula. Instead, the pair calls the helper, decodes two Carson fee recipients plus two 0.3e18 fee rates, divides those fee rates by 1e18, and then executes two ERC-20 transfer(address,uint256) calls from the pair balance itself before Sync. This creates a mismatch between the reserves used for pricing and the reserves that remain after the swap finishes.
The vulnerable components are:
- Pair
0xe0a3e0f7e4c789747eb29a212ea915a7a1e1ac69, specifically the Carson-side swap logic around bytecode offsets0x1c25-0x1f53. - Helper
0xd092a69dd806bd0f49e69739770784cda896c07b, specifically0x918b6c8d(address,address)at bytecode offset0x0475, which returns the fee recipients and rates used by the pair.
The explicit invariant is: after pricing a Carson sell from amount0In, the pair's Carson reserve must not be reduced by extra pair-funded transfers before reserves are synced. The concrete breakpoint is the helper lookup followed by Carson.transfer(dead, fee) and Carson.transfer(marketing, fee) from the pair balance.
4. Detailed Root Cause Analysis
4.1 Pair-Side Code Path
The pair disassembly shows the Carson-side swap path building a call to helper selector 0x918b6c8d, performing a STATICCALL, decoding four returned words, dividing the two fee rates by 1e18, and then preparing ERC-20 transfer calls:
Origin: Carson pair disassembly
00001c25: PUSH4 0x918b6c8d
...
00001c7d: STATICCALL
...
00001ca6: DUP1
00001ca7: MLOAD
...
00001cc2: PUSH8 0x0de0b6b3a7640000
...
00001d05: DIV
00001d0e: PUSH1 0x06
00001d10: SLOAD
00001d15: PUSH4 0xa9059cbb
...
00001d3d: PUSH4 0xa9059cbb
The helper side confirms that 0x918b6c8d reads four contiguous words from a nested mapping rooted at slot 5:
Origin: helper disassembly
00000475: JUMPDEST
00000476: PUSH1 0x05
...
00000486: KECCAK256
0000048e: KECCAK256
00000490: SLOAD
00000495: SLOAD
0000049a: SLOAD
000004a0: SLOAD
That bytecode-level evidence matches the direct helper call output for (pair, Carson): dead address, 0.3e18, marketing address, 0.3e18. It also matches the pair behavior seen in the trace.
4.2 Economic Effect on the First Sell
After the initial Carson buy, the pair held 36785.567997789766543734 Carson and 1643796.192676695188781042 USDT. The attacker then started the sell loop with a 5000 Carson sell. Carson's transfer tax meant only 4650 Carson reached the pair. The pair nevertheless priced the USDT output from that full effective input and paid 183979.325468778887158891 USDT.
Immediately afterward, the pair used the helper-derived Carson fee configuration to transfer 1395 Carson to the dead address and another 1395 Carson to marketing from the pair balance itself. The pair therefore synced to a Carson reserve that was 2790 Carson lower than the reserve level implied by the priced input.
The traced sell path shows the relevant sequence:
Origin: seed transaction trace, sell-loop excerpt
0xD092A69Dd806bd0f49E69739770784CDa896c07b::918b6c8d(pair, Carson) [staticcall]
0x0aCD5019EdC8ff765517e2e691C5EeF6f9c08830::transfer(0x000000000000000000000000000000000000dEaD, 1395000000000000000000)
0x0aCD5019EdC8ff765517e2e691C5EeF6f9c08830::transfer(0x4D9bD49b7383B88477724428556c7fe36d7e6bc4, 1395000000000000000000)
emit Sync(: 124205567997789766543734, : 84374052691489810528083)
The reportable invariant violation is now deterministic:
- Pricing step: the pair behaves as though it keeps the full Carson input, net of AMM fee.
- Reserve step: the pair then removes 60% of that Carson from reserves before
Sync. - Outcome: the price is ratcheted upward for the next sell, but the already-paid USDT output is not clawed back.
4.3 Why Split Sells Become Profitable
Because only 40% of each effective Carson sell remains in reserves, the pair's Carson side grows much more slowly than the pricing math assumes. That makes the quote side appear scarcer on each iteration than it should be under a correct invariant. The attacker exploited that by repeating the sell path 50 times with 5000 Carson sells and once with a final 105794675801160498373731 Carson sell. A sequential simulation using the traced reserve updates and the helper fee configuration reproduces the exact gross extraction of 1600677049295746860016399 wei-USDT.
This exploit is ACT because every required input is public:
- Carson/USDT liquidity is on-chain and public.
- DODO flash-loan pools are public and permissionless.
- Pair/helper behavior is publicly observable via trace, bytecode, and direct
eth_call.
5. Adversary Flow Analysis
The adversary cluster consists of:
- EOA
0x25bcbbb92c2ae9d0c6f4db814e46fd5c632e2bd3, which submitted the transaction and received the final profit. - Exploit contract
0x9cffc95e742d22c1446a3d22e656bb23835a38ac, which executed the buy and sell loop. - Flash-loan helper
0x55e741bace7d48ce29c514e5688eabb02493c8f2, which nested public DODO flash loans.
The end-to-end execution flow is:
- Flash-loan funding. Helper
0x55e741...borrowed USDT from five public DODO pools in the same transaction:641735356277648165889865,190522893034905101776323,676888608756592594683579,81511918330743653235156, and149185234339130108353560wei-USDT. - Price pump. The exploit contract spent
1500000000000000000000000wei-USDT to buy382574920216301611154550Carson, moving reserves to36785567997789766543734Carson and1643796192676695188781042USDT. - Broken sell loop. The attacker sold Carson back to the pair in 51 chunks. Every sell was followed by helper lookup
0x918b6c8d(pair, Carson)and pair-funded transfers to the dead and marketing addresses beforeSync. - Repayment and profit. Contract
0x9cff...repaid1739844010739019623938483wei-USDT to0x55e741..., then transferred100677049295746860016399wei-USDT to the sender EOA.
The attacker-side bytecode is consistent with that flow. Selector extraction from 0x55e741... includes DPPFlashLoanCall(address,uint256,uint256,bytes), matching the trace, while selector extraction from 0x9cff... shows a generic exploit entrypoint rather than any privileged protocol-only interface.
6. Impact & Losses
The measurable loss is:
- Token:
USDT - Raw amount:
100677049295746860016399 - Decimals:
18 - Human-readable amount:
100677.049295746860016399USDT
The victim is the Carson/USDT pair and, economically, its liquidity providers. The pair's USDT balance fell by exactly the amount that the adversary EOA gained. The sender also paid exactly 56095692000000000 wei-BNB in gas, derived from receipt gasUsed = 18698564 and effectiveGasPrice = 3000000000.
7. References
- Seed exploit transaction:
0x37d921a6bb0ecdd8f1ec918d795f9c354727a3ff6b0dba98a512fceb9662a3ac - Carson token:
0x0acd5019edc8ff765517e2e691c5eef6f9c08830 - Carson/USDT pair:
0xe0a3e0f7e4c789747eb29a212ea915a7a1e1ac69 - Helper/factory:
0xD092A69Dd806bd0f49E69739770784CDa896c07b - Public trace evidence: seed trace and balance diff under the collector seed artifacts
- Bytecode evidence: pair disassembly, helper disassembly, selector extraction, helper fee-configuration note, and receipt under the auditor
iter_1artifacts - External explorer reference: BscScan transaction page for the exploit transaction