June 18, 2026
|
Exploit Postmortem

ATM Token's $243.5K Loss and How Olympix Would Have Prevented It

Date: June 4, 2026

Chain: BNB Chain (BSC)

Loss: approximately $243.5K (BSC-USD)Class: unbounded swap embedded in the token transfer path, a cross-contract interaction flaw

Status: in scope for pre-deployment analysis, preventable

Summary

On June 4, 2026, the ATM token was drained of roughly $243.5K in BSC-USD. The token's transfer logic was not a plain transfer. On every move of tokens, the contract reached into a decentralized exchange and automatically converted a portion of the transferred ATM into BSC-USD through a router. That behavior was not bounded, so the attacker turned an ordinary transfer into a lever. By triggering transfers repeatedly, they invoked the embedded swap over and over and pulled far more BSC-USD out of the contract than any transfer justified, draining about $243,500. The flaw did not live inside a single function read on its own. It lived in what the token did across the boundary to the exchange every time it was called.

Background

Some tokens add behavior to their transfer path beyond moving a balance. A common version is a token that takes a portion of every transfer and automatically swaps it into a stablecoin or the native asset, usually to fund a treasury or maintain liquidity. ATM did this. Its custom transferFrom() converted 20% of the transferred ATM into BSC-USD through a router on each transfer.

The convenience of that design carries a hidden cost. A transfer is supposed to be a simple, self-contained balance change. Once it also performs a swap on an external market, the transfer stops being self-contained. It now moves value through another contract on every call, and its safety depends not only on the token's own code but on how that code interacts with the exchange it calls into.

Root Cause

The flaw was in the token's custom transferFrom(), which embedded a DEX swap directly in the transfer path. On every transfer, the function automatically converted 20% of the transferred ATM into BSC-USD through a router.

The implementation did not properly bound this behavior. There was no effective limit on how the embedded swap could be invoked, so each transfer became a way to push value out of the contract through the router, and nothing stopped an attacker from doing it again and again. Repeating the transfer repeated the swap, and repeating the swap drained the contract's BSC-USD.

What makes this defect different from a single bad line is where it lives. The token's transfer code on its own looks like a tax-and-swap feature. The router on its own behaves correctly. The drain only exists in the round trip between them, in the fact that ATM calls the router on every transfer and places no bound on the result. The vulnerability spans the boundary between the token and the exchange, which is exactly the kind of behavior that is invisible when either contract is read alone.

Attack Flow

  1. The attacker arranged to call the token's transfer path repeatedly, exercising the branch that performs the embedded swap.
  2. Each call automatically converted 20% of the transferred ATM into BSC-USD through the router, moving value out of the contract on every transfer.
  3. Because the swap was not bounded against repeated invocation, the attacker triggered it over and over, compounding the extraction far beyond what any single transfer warranted.
  4. The accumulated BSC-USD drained roughly $243.5K from the contract.

Impact

The contract's BSC-USD was extracted to the attacker through its own transfer mechanism, leaving holders with a token whose central function could be operated as a withdrawal pump. The loss was approximately $243.5K. Because the value left through a swap that the token was designed to perform, each individual transfer looked like normal token behavior rather than an exploit, even as the contract emptied.

The Problem With Audit-Only Security

Most token and protocol security still rests on a one-time audit before launch, and most reviews are scoped to a single contract. That scoping is where a failure like this slips through, because the flaw was never contained in one contract.

A reviewer reading ATM's transfer code in isolation sees a swap call to a router. If the router and the pool are treated as trusted externals, stubbed out, or marked out of scope, which is common practice when a review is bounded to the contract under examination, the reviewer never models the full round trip. The swap reads as a tokenomics feature, the kind of tax-and-convert behavior many tokens ship deliberately, rather than as an unbounded path that pumps value out of the contract on every call. The danger does not appear in any single function. It appears in the interaction between two contracts, and a review that examines one of them at a time will not see it.

A point-in-time audit compounds this. It captures the contract as it stood on review day, under a fixed budget that rarely extends to simulating the contract against every external it touches under adversarial repetition. Newer analysis tooling has made these cross-contract edge cases far easier to find than they were when many tokens were first audited, which means a clean report from the time of deployment is not evidence that the interaction is safe today.

How Olympix Would Have Prevented It

Olympix analyzes a contract together with the contracts it interacts with, not in isolation. Its cluster-stage analysis takes the token's implementation and the contracts it calls, the router and the pool here, and evaluates them as the connected system they actually form on-chain. That is the level at which this vulnerability exists, so it is the level at which it becomes visible.

Applied to ATM, that cross-contract analysis sees the embedded swap in transferFrom(), follows the call into the router, and tests what happens when the transfer is invoked repeatedly rather than once. The unbounded extraction that drained the contract is not an obscure consequence at that level. It is the direct result of a transfer that swaps without a bound, and BugPocer can demonstrate it with a proof-of-concept that loops the transfer and shows BSC-USD leaving the contract.

This kind of detection depends on analyzing the full cluster. The implementation contract on its own is not enough, because the flaw is in the interaction, so the analysis needs the token and the contracts it depends on available together, which is straightforward when those live alongside the code. Given the cluster, the interaction is testable before deployment rather than discovered after the drain.

This is not an argument against audits. A skilled human review remains valuable. It is an argument that an audit scoped to a single contract, however thorough, can pass a token whose risk only emerges in its interaction with the market it trades into. Cross-contract analysis with automated proof-of-concept generation is what closes that gap, because it tests the system the contract actually runs in rather than the contract by itself.

Takeaway

A transfer that quietly performs a swap turns every transfer into a withdrawal, and without a bound on that behavior an attacker simply calls it until the contract is empty. ATM lost roughly $243.5K not to an exotic trick but to a design that coupled its transfer path to an external exchange and never limited the result. The flaw could not be seen in the token alone or the router alone. It lived in the interaction between them, which is precisely what single-contract review and point-in-time audits are least equipped to catch and what cross-contract analysis with proof-of-concept generation is built for. Verifying a contract against the system it actually runs in, before it ships, is the difference between a token that looks like it has a feature and one that has a drain. You can see Olympix analyze your contracts alongside the ones they interact with, with a working proof-of-concept for every finding, in a free demo.

On-Chain References

Vulnerable Contract: 0x4fd0878ee1bbf7b1019138e8eec746e5a5d5a205
Transaction: 0x37b90a337075cd2feea93b12780abe9f953dad476e1c1418a02447aaa6dcfd86

What’s a Rich Text element?

The rich text element allows you to create and format headings, paragraphs, blockquotes, images, and video all in one place instead of having to add and format them individually. Just double-click and easily create content.

A rich text element can be used with static or dynamic content. For static content, just drop it into any page and begin editing. For dynamic content, add a rich text field to any collection and then connect a rich text element to that field in the settings panel. Voila!

Headings, paragraphs, blockquotes, figures, images, and figure captions can all be styled after a class is added to the rich text element using the "When inside of" nested selector system.

  1. Follow-up: Conduct a follow-up review to ensure that the remediation steps were effective and that the smart contract is now secure.
  2. Follow-up: Conduct a follow-up review to ensure that the remediation steps were effective and that the smart contract is now secure.

In Brief

  • Remitano suffered a $2.7M loss due to a private key compromise.
  • GAMBL’s recommendation system was exploited.
  • DAppSocial lost $530K due to a logic vulnerability.
  • Rocketswap’s private keys were inadvertently deployed on the server.

Hacks

Hacks Analysis

Huobi  |  Amount Lost: $8M

On September 24th, the Huobi Global exploit on the Ethereum Mainnet resulted in a $8 million loss due to the compromise of private keys. The attacker executed the attack in a single transaction by sending 4,999 ETH to a malicious contract. The attacker then created a second malicious contract and transferred 1,001 ETH to this new contract. Huobi has since confirmed that they have identified the attacker and has extended an offer of a 5% white hat bounty reward if the funds are returned to the exchange.

Exploit Contract: 0x2abc22eb9a09ebbe7b41737ccde147f586efeb6a

More from Olympix:

No items found.

Ready to Shift Security Assurance In-House? Talk to Our Security Experts Today.