0xfab5912f858b3768b7b7d312abcc02b64af7b1e1b62c4f29a2c1a2d1568e9fa20xA31d98b1aA71a99565EC2564b81f834E90B1097bEthereumA victim approved MainnetSettler for the full balance of the EVERYBODY token, and the protocol allowed any caller to execute a BASIC action without user-authenticated intent binding. The attacker drained the victim’s full token balance in one call.
Attack details:
Victim: 0xA31d98b1aA71a99565EC2564b81f834E90B1097b
Token: 0x68b36248477277865C64dFc78884ef80577078f3 (EVERYBODY)
Protocol: 0x70BF6634Ee8Cb27D04478F184b9b8bB13E5f4710 (MainnetSettler)
Exploit tx: 0xfab5912f858b3768b7b7d312abcc02b64af7b1e1b62c4f29a2c1a2d1568e9fa2
Block: 0x143f4b0
Drained amount: 308453642481581939556432141 (18 decimals)
MainnetSettler exposes execute(AllowedSlippage, bytes[] actions, bytes32) and dispatches encoded actions such as ISettlerActions.BASIC. The BASIC action path forwards arbitrary callback data to a target pool address when sellToken == address(0) and computes no owner-specific execution constraint.
In this incident, the victim had an unlimited allowance set for the settler, which is a common pattern for spenders but expected to be used under caller-authorized flows.
The core flaw is an authorization bypass in the spender path: BASIC actions can carry raw ABI payloads that are executed against an arbitrary pool contract without tying the call to user intent. The dispatch entrypoint does not authenticate the caller or constrain calldata beyond the token transfer semantics.
poolAn attacker can encode transferFrom(victim, attacker, full_balance) into BASIC when sellToken is zero and trigger MainnetSettler.execute from an unprivileged EOA. Because EVERYBODY was already approved, the call pulls all tokens to the attacker.
The incident is therefore an authorization and confused-deputy class defect, not pure MEV: the protocol state transition directly moves custody under existing approval without any user transaction constraint in the exploited path.
The seed attack transaction both deploys a helper contract and executes the exploit in its constructor. Observed execution state changes from trace:
MainnetSettler fallback executes -> fallback decodes action -> calls BASIC
BASIC pool call -> token.transferFrom(victim, attacker, victim_balance)
From on-chain state checks, the pre-state had:
allowance(victim, settler) = type(uint256).maxbalance(victim) = 308453642481581939556432141balance(attacker) = 0Post-state after the seed tx:
balance(victim) = 0balance(attacker) = 308453642481581939556432141allowance(victim, settler) reduced by exactly the drained amountThe token transferFrom event and storage delta in trace directly confirms the exploit and that the spender call was arbitrary, not derived from authenticated user instruction in this flow.
A single seed transaction is sufficient for full theft:
BASIC call data with:
sellToken = 0x0pool = token addressdata = abi.encodeWithSelector(IERC20.transferFrom, victim, attacker, victimBalance)MainnetSettler.execute.transferFrom, draining victim balance.From execution evidence: the transferFrom event in the seed tx logs transfers all victim funds to attacker address.
The incident moved the victim-controlled EVERYBODY balance entirely to the attacker-held address. This is a direct custodial theft under standard approval semantics and does not require privileged roles or private state.
308453642481581939556432141 smallest units (18 decimals)EVERYBODY0xfab5912f858b3768b7b7d312abcc02b64af7b1e1b62c4f29a2c1a2d1568e9fa2/workspace/session/artifacts/collector/seed/1/0xfab5912f858b3768b7b7d312abcc02b64af7b1e1b62c4f29a2c1a2d1568e9fa2/trace.cast.log/workspace/session/artifacts/collector/seed/1/0xfab5912f858b3768b7b7d312abcc02b64af7b1e1b62c4f29a2c1a2d1568e9fa2/metadata.json/workspace/session/artifacts/auditor/iter_0/onchain_state_checks.json/workspace/session/root_cause.json