incident 2026-04-18
FrontendsWhen the frontend was the exploit
For 47 minutes, from 14:06 UTC, tidewell.example served a copy of itself. The lending contracts behind it were audited and never touched. The domain's DNS pointed to another server, where the copied app asked users to approve a contract the protocol had never deployed. 61 wallets did, and 1.3M USDC left before the records were fixed.
timeline utc
47 minutes on the wrong server
- 14:06The registrar changes the nameservers for tidewell.example after a support request from someone posing as the team.
- 14:11A copied frontend goes live with a fresh certificate, and deposits now ask to approve a contract the team never deployed.
- 14:19A user approves 80,000 USDC for a deposit, and the attacker's contract pulls it within the same minute.
- 14:38The team sees deposits to the pool drop to zero while the site shows normal traffic, and posts a warning.
- 14:53The registrar restores the nameservers, after 61 wallets have approved the wrong contract and 1.3M USDC is gone.
Every check people had been taught passed. The address bar showed the right domain, and the certificate was valid, because the attacker requested a new one minutes after the switch.
The difference was in the request. The real app asks to approve the pool at 0x5c1d…e902, which has two years of history. The copy asked for 0xb7a4…3f10, deployed that morning with no published source.
what a check would have shown
The same request, read by Presign
- Not the spender of your last 9 deposits
- Spender deployed 6 hours earlier
- Source code not published
- Unlimited allowanceThe spender can move every USDC you hold, now or later.
- New contractThe spender was deployed 3 days ago.
- Unverified sourceIts code is not published, so nobody can read it.
An audit covers the contracts. It says nothing about the page that tells you which contract to call.
