We ran Guardix on Euler Finance's code from before the $197M hack

October 20, 2026

On March 13, 2023, an attacker took $197 million from Euler Finance (Chainalysis write-up, Rekt write-up). The bug sat in one function: donateToReserves in EToken.sol.

We pointed Guardix at the public Euler code as it stood before the attack, at commit dfaa778. Guardix flagged that function, at those lines, as a high-severity issue.

01Bug

The bug

donateToReserves lets an account give its eTokens to the protocol reserves. It lowers the account's balance and raises the reserve balance. It never calls checkLiquidity, so nothing stops an account from donating away the collateral that keeps its loan healthy.

assetStorage.users[account].balance = encodeAmount(newBalance);
assetStorage.reserveBalance = assetCache.reserveBalance = encodeSmallAmount(assetCache.reserveBalance + amount);

The attacker used this to push their own account underwater on purpose, then liquidated it from a second account at a discount.

02Reported

What Guardix reported

Guardix's finding, in its own words: "donateToReserves moves seize-able eToken collateral into reserveBalance without checkLiquidity, capping liquidation yield at zero." It pointed to contracts/modules/EToken.sol, lines 359-386, the body of the function, and suggested high severity.

03Limits

What this run does not show

  • The finding is a hypothesis. Guardix's validation stage, which tries to confirm a finding, did not run.
  • Guardix found the missing check, but its scenario is different from the real attack. It describes donating collateral so that liquidators get nothing. It does not describe the self-liquidation path the attacker took.
  • The run was partial. The stage that walks through each entry point covered 15 of 72 units. The unit for donateToReserves was one of the 15 it finished.
  • Guardix produced 75 hypotheses in total on this code. This one is the match.
04Your code

Try it on your code

Guardix runs the same audit agents on your contracts. Contact: guardix@dome.net.