
Date: August 21 to 22, 2026
Chain: Base, with unbacked mints on BNB Smart Chain and the vault drained on Ethereum
Loss: 14,742,341.84 SAND, about $697,000
Class: legacy token function that lets any caller make the token contract call any target as itself
At 23:41 UTC on August 21, 2026, the first unbacked SAND mint landed on The Sandbox's bridge, SAND that no one had ever deposited on Ethereum. Thirty-nine blocks later the attacker minted 14,743,364.21 SAND more, exactly 100 tokens less than the Ethereum vault backing every bridged SAND held at that moment, and by 02:21 UTC on August 22 the vault had been drained.
The Sandbox's post-mortem drew a clear line under one fact: no private key was stolen. The attacker got control of the bridge's security settings through approveAndCall, a convenience function from an older generation of token design that let any caller make the SAND token contract call another contract with data the caller wrote, as itself.
The Sandbox is a blockchain gaming and creation platform, and SAND is its token, with a fixed maximum supply of 3 billion on Ethereum. To let SAND move to Base and BNB Smart Chain, The Sandbox used LayerZero's Omnichain Fungible Token standard, or OFT. On Ethereum, an OFT Adapter holds real SAND in a vault, and on the other chains an OFT contract mints SAND when a verified cross-chain message says an equal amount was locked or burned elsewhere. The whole system rests on that verification step, since a destination chain can't see Ethereum directly and has to trust whoever is configured to vouch for each message.
In LayerZero, the application decides who vouches. Each app chooses its verifiers and libraries, and it can appoint a delegate, an address allowed to change that configuration on the app's behalf. The SAND OFT contract on Base, at 0xac531Eb26Ca1d21b85126De8FB87E80E09002DcF, was itself the LayerZero app, so LayerZero's endpoint treated any call coming from the token contract as a call from the app. The Ethereum vault, a verified contract named OFTAdapterForSand, sits at the same address on Ethereum, which also meant a forged message claiming to come from that address passed the Base contract's check on who its trusted counterpart was, according to the DeFiHackLabs reproduction.
approveAndCall was designed to save users a step. A normal ERC-20 interaction takes one transaction to approve a spender and another for the spender to act, and approveAndCall bundles the two by approving and then calling the spender with extra data in the same transaction. In the SAND OFT on Base, according to The Sandbox's post-mortem and Blockaid, that outbound call went to a target and carried calldata that the caller chose, and it arrived at that target with the token contract as the sender.
The function did have one guard. Per the DeFiHackLabs proof of concept, it required the first parameter inside the caller's data to equal the caller's own address, a check meant to stop anyone spending someone else's approval. That check says nothing about which function the token is being asked to call. LayerZero's setDelegate takes a single address as its first parameter, so a caller who asks the endpoint to make them the delegate passes the guard by construction, and the endpoint sees the request coming from the SAND OFT itself and accepts it. Blockaid's summary was that the flaw sat in The Sandbox's SAND OFT on Base, in approveAndCall, while LayerZero's own contracts behaved as designed.
A function that forwards arbitrary calls lends the contract's identity to whoever calls it, so every permission that identity holds, in this contract or in any system that trusts it, becomes reachable by everyone. It works like a company stamp left on the front desk with a rule that visitors can only stamp letters bearing their own name, which stops nobody from writing their own name on a letter that appoints them to the board. A token that later becomes a bridge app, a governance member or a vault owner inherits that exposure without a single line of the old function changing.
With delegate rights, the attacker reconfigured bridge-message verification for the Base OFT so that its own contract was the only required verifier. DeFiHackLabs reproduced one of these transactions step by step. In Base block 50289412 at 03:09:31 UTC on August 22, SAND Exploiter 1, 0x638C...F296, deployed a contract that called approveAndCall to become the delegate, set itself as the sole verifier for messages from Ethereum, attested a forged deposit message, committed it, and delivered it to the OFT, which minted 10,000,000 SAND straight to the attacker.
Reports put the total at more than 329 trillion SAND across 703 mint events, which Crypto Times places between 23:42 UTC on August 21 and 04:45 UTC on August 22, with the freshly minted tokens spread across 173 wallets. The Sandbox's post-mortem puts the unbacked SAND left on Base and BNB Smart Chain at more than 339 trillion, against a real supply of 3 billion. PeckShield's early alert measured about 14.9 billion SAND in two wallets, and Blockaid put the face value of everything minted at about $49 billion, a number with no real liquidity behind it.
The value that mattered sat on Ethereum. The second mint, 14,743,364.21 SAND, was bridged back through the OFT and redeemed from the Ethereum vault in six withdrawals, the last of which, according to the post-mortem, was sized to leave exactly 100 SAND behind. About 48 minutes before the attacker's own messages cleared, an unrelated arbitrage bot redeemed 642,471.52 SAND of unbacked tokens it had bought on the open market, and two smaller withdrawals took another 5,409.03 SAND, which left the attacker with 14,095,483.66 SAND, 647,880.55 short of its target. In total, 14,742,341.84 SAND left the vault, about $697,000 and roughly 0.5% of SAND's maximum supply, and crypto.news reports the attacker converted it to about 80 ETH. The Sandbox estimated total economic impact at about $1.5 million, with about $760,000 of that falling on traders in a Base DEX pool.
At 05:26 UTC on August 22, The Sandbox shut the bridge at the contract level on all three chains, used governance to remove the LayerZero peer settings for Base and BNB Smart Chain, and retired the compromised contracts. SAND on Ethereum and Polygon wasn't affected, and Upbit and Bithumb paused SAND deposits and withdrawals while the incident was contained. The attacker's wallet was reported to TRM Labs and flagged by Chainalysis and SEAL, and no recovered funds have been reported since.
The post-mortem, published on August 27, set out a 1:1 reimbursement in SAND on Ethereum funded from the treasury, with no new SAND minted. Two exchanges hold more than 72% of the eligible balances and will reimburse their customers directly, and other holders claim from the wallet that held SAND at the snapshot. The claim window ran from September 8 to 4 PM UTC on September 22, with late claims reviewed individually through the end of October, and SAND left on the retired Base and BNB Smart Chain contracts can no longer be transferred or redeemed. Entitlements come from balances recorded immediately before the first unauthorized mint, which the post-mortem fixes at Base block 50,283,176 and BNB Smart Chain block 117,321,965.
Olympix reads a contract the way an attacker does, as states, transitions and entry points, and it takes in the context around the code, including the systems a contract is wired into, to infer the invariants the whole setup depends on. In the SAND OFT, one of the most important pieces of state lives outside the token itself: the LayerZero configuration that decides which messages count as real deposits. The engine maps every path that can change it, and uses signals to decide which ones to attack first.
Olympix's static analysis surfaces the signal here directly: a public function that takes a caller-chosen target and caller-chosen calldata and makes an external call from the contract, guarded only by a check on the shape of the data, in a contract whose address holds admin rights somewhere else. Olympix has flagged this class before in other codebases. From that signal the engine narrows from every path, to the feasible ones, to the paths that reach the invariant, which in plain words is that only The Sandbox's authorized owner can ever change who verifies SAND's bridge messages.
BugPoCer's job on this contract is to break that ownership rule. Running Counterexample-Guided Invariant Refutation, it treats the token, the LayerZero endpoint and the receive library as one system, takes the ownership rule as the thing to disprove, and executes paths through every entry point that can reach the endpoint's configuration. approveAndCall with the endpoint as its target and setDelegate as its data, with the caller's own address in the first slot, breaks the rule in a single call. Symbolic execution supports that search, and it's also used by BugScout, which can start from the forwarding call itself and try known hijack strategies against it.
The counterexample BugPoCer returns is the concrete sequence of state changes, the minimal conditions that trigger it and a generated Forge test that replays it: a fresh address calls approveAndCall, becomes the delegate, installs its own contract as the only verifier and mints SAND against no deposit. That's the August 21 attack, produced in development instead of on Base. Because Olympix runs automatically in development, at every merge and before release, the check also covers the moment that matters most for a case like this, when a token contract with a years-old convenience function becomes the owner of a bridge configuration. Audits cover the scope they're given in the time they have, and a bridge integration reviewed on its own can look sound while the token it's attached to quietly carries a way to speak for it.
The Sandbox's loss came from a function that worked exactly as written for years, until the contract that carried it was given a powerful new role. For builders adding cross-chain or admin capabilities to an existing token, the work starts with listing every path that lets an outsider make the contract act as itself. If you'd like to see how Olympix traces those paths across your contracts and the systems they're wired into, and returns a runnable counterexample for any that reach a permission they shouldn't, book a technical walkthrough.
Protocol: The Sandbox (SAND LayerZero OFT)
Chain: Base (also BNB Smart Chain; vault drained on Ethereum)
Date: August 21, 2026, 23:41 UTC (first unbacked mint) to August 22, 02:21 UTC (last vault withdrawal)
Loss: 14,742,341.84 SAND, about $697,000 (per The Sandbox)
Vulnerable SAND OFT (Base): 0xac53...2DcF
OFTAdapterForSand vault (Ethereum, same address): 0xac53...2DcF
Attacker EOA (SAND Exploiter 1, Base): 0x638C...F296
Example mint tx reproduced by DeFiHackLabs (Base block 50289412, 10,000,000 SAND): 0x76ed...a446
Attack contract deployed in that tx (delegate and sole verifier): 0xd7Cb...f6Ca
LayerZero EndpointV2 (Base): 0x1a44...728c
ReceiveUln302 (Base): 0xc70A...4bAf
Snapshot block (Base): 50,283,176
Snapshot block (BNB Smart Chain): 117,321,965
DeFiHackLabs: SandboxOFT_exp.sol proof of concept
eGamers: SAND Bridge Drained Via Legacy Token Function, The Sandbox Post-Mortem Finds
eGamers: SAND Holders Hit by August Bridge Exploit Can Now File Claims
crypto.news: Sandbox bridge exploit, 329T SAND minted, $675K stolen