Calculated from recorded token losses using historical USD prices at the incident time.
0xbb837d417b76dd237b4418e1695a50941a69259a1c4dee561ea57d982b9f10ec0x94dac4a3ce998143aa119c05460731da80ad90cfBase0xfcd3842f85ed87ba2889b4d35893403796e67ff1BaseOn Base block 2031747, transaction 0xbb837d417b76dd237b4418e1695a50941a69259a1c4dee561ea57d982b9f10ec drained the LeetSwap WETH/axlUSDC pair at 0x94dAC4a3Ce998143aa119c05460731dA80ad90cf. The attacker bought a small axlUSDC position, used a public helper on the pair to move almost all axlUSDC from the pair into the fee vault, called sync() to ratchet reserves down to the manipulated balance, and then swapped axlUSDC back into the pair to extract WETH.
The root cause is a contract bug in LeetSwapV2Pair: _transferFeesSupportingTaxTokens(address,uint256) is externally callable even though it is an invariant-critical fee-moving primitive. Because it transfers pair-held assets to the fees contract without access control and without updating reserves, any unprivileged caller can desynchronize balances from stored reserves and then make the manipulated balances authoritative via sync().
LeetSwap uses a Uniswap-V2-style pair design with separately stored reserves (reserve0, reserve1) and live ERC-20 balances. Pricing and invariant checks are performed against the stored reserves until _update() or sync() refreshes them.
The attacked pair is the verified LeetSwap WETH/axlUSDC pair at 0x94dAC4a3Ce998143aa119c05460731dA80ad90cf. In the verified source, the pair deploys a dedicated fee vault contract and stores its address in immutable .
feesaxlUSDC on Base is the verified token at 0xEB466342C4d449BC9f53A865D5Cb90586f405215. The pair held deep WETH liquidity and large axlUSDC reserves immediately before the exploit, which made reserve manipulation economically meaningful.
The vulnerability class is an access-control and reserve-accounting failure in the pair contract. The key bug is that the helper below is public, not internal, and it directly transfers pair-held tokens to the fee vault:
function _transferFeesSupportingTaxTokens(address token, uint256 amount)
public
returns (uint256)
{
uint256 balanceBefore = IERC20(token).balanceOf(fees);
_safeTransfer(token, fees, amount);
uint256 balanceAfter = IERC20(token).balanceOf(fees);
return balanceAfter - balanceBefore;
}
The contract's reserve model requires economically available balances and stored reserves to stay aligned. That invariant is broken here because _transferFeesSupportingTaxTokens moves assets out of the pair without calling _update(). The pair therefore keeps stale reserves until somebody later calls sync():
function sync() external lock {
_update(
IERC20Metadata(token0).balanceOf(address(this)),
IERC20Metadata(token1).balanceOf(address(this)),
reserve0,
reserve1
);
}
In effect, the attacker can first shrink the live balance of one side of the pool, then use sync() to overwrite the stored reserves with the manipulated balance, and then trade against a price curve that now vastly overprices the depleted asset. That is exactly what happened here on the axlUSDC side of the pair.
Immediately before the exploit, the pair held about 120.187521209079354818 WETH and 216584888040 raw axlUSDC units. The attacker-funded exploit contract first wrapped 0.001 ETH into WETH and swapped it into the pair for a starter axlUSDC position.
The crucial breakpoint was the direct call to the public helper:
LeetSwapV2Pair::_transferFeesSupportingTaxTokens(
0xEB466342C4d449BC9f53A865D5Cb90586f405215,
216583081404
)
The collected trace shows the pair transferring 216583081404 raw axlUSDC units to its fee vault 0xE659e3044B4720B4f107b12a45bcd9bc44A4AC02, and returning the same amount. The balance-diff artifact confirms the effect:
{
"token": "0xeb466342c4d449bc9f53a865d5cb90586f405215",
"holder": "0x94dac4a3ce998143aa119c05460731da80ad90cf",
"before": "216584888040",
"after": "1622117",
"delta": "-216583265923"
}
At that point the pair's live axlUSDC balance had been almost fully stripped, but the stored reserves were still stale. The attacker then called sync(). The trace shows the exact reserve update:
emit Sync(reserve0: 120188518209079354818, reserve1: 10000)
This is the invariant failure made authoritative: the pair still held roughly 120.1885 WETH, but reserve1 had been collapsed to only 10000 raw axlUSDC units. With reserves now reflecting the manipulated balance, the pair priced axlUSDC as if it were nearly absent.
The attacker then sold the axlUSDC accumulated from the seed swap back into the pair. The trace and balance diffs show a WETH transfer of 119446585023779038288 wei to the exploit contract, after which the contract unwrapped WETH to ETH and paid the profit recipient. The exploit did not require privileged keys, governance, or non-public data. Any unprivileged actor could have reproduced the same sequence on the public pair contract.
The adversary cluster consisted of:
0x705f736145bb9d4a4a186f4595907b60815085c3, which sent the exploit transaction.0xea8f89f47f3d4293897b4fe8cb69b5c233b9f560, which executed the calls.0x5b030f90db67190373dbf3422436df4c62f60a60, which received the final ETH payout.The on-chain sequence was:
0.001 ETH of seed capital and wrapped it into WETH._transferFeesSupportingTaxTokens(axlUSDC, 216583081404), pushing almost all pair-held axlUSDC into the pair's fee vault.sync(), causing the pair to emit Sync(reserve0=120188518209079354818,reserve1=10000).swap(...) to pull out WETH against the manipulated reserves.0x5b030f90db67190373dbf3422436df4c62f60a60.This is a single-transaction ACT exploit: all calls were made through public interfaces, and the profit condition was realized immediately in the same transaction.
The measurable loss was 119446585023779038288 wei of WETH-equivalent value, or 119.446585023779038288 WETH, drained from the LeetSwap WETH/axlUSDC pair.
The balance-diff artifact shows:
{
"token": "0x4200000000000000000000000000000000000006",
"holder": "0x94dac4a3ce998143aa119c05460731da80ad90cf",
"before": "120187521209079354818",
"after": "740936185300316530",
"delta": "-119446585023779038288"
}
The profit recipient 0x5b030f90db67190373dbf3422436df4c62f60a60 ended with 119447582023779038288 wei of native ETH-equivalent balance increase. After subtracting the exploit contract's 0.001 ETH seed capital and the sender EOA's 987419792502374 wei gas cost, the net profit was 119445594603986535914 wei.
0xbb837d417b76dd237b4418e1695a50941a69259a1c4dee561ea57d982b9f10ec metadata and trace.0x94dAC4a3Ce998143aa119c05460731dA80ad90cf, specifically _transferFeesSupportingTaxTokens, _update, and sync.0xEB466342C4d449BC9f53A865D5Cb90586f405215.