Calculated from recorded token losses using historical USD prices at the incident time.
0x199c4b88cab6b4b495b9d91af98e746811dd8f82f43117c48205e6332db9f0e00x80121da952a74c06adc1d7f85a237089b57af347BSC0x7a3adf2f6b239e64dab1738c695cf48155b6e152BSCOn BSC block 30113118, transaction 0x199c4b88cab6b4b495b9d91af98e746811dd8f82f43117c48205e6332db9f0e0 drained the FFIST/USDT PancakeSwap pool by corrupting the token-side reserve before a sell. The attacker first bought FFIST, then sent a zero-value FFIST transfer that overwrote the pair's FFIST balance to 1, called public sync(), and finally sold 24 raw FFIST units into the now-desynchronized pool. The exploit was possible because GoldCoin's _airdrop logic lets any non-whitelisted transfer write _balances[airdropAddress] = 1 for attacker-controlled addresses, including the LP pair. The seed transaction produced a deterministic adversary portfolio gain of 219.154800816693701658 BNB-equivalent and left the pair short 53198433607272063480945 raw USDT units.
This incident depends on the interaction between a broken token and a standard constant-product pair. PancakeSwap V2 pairs trust token balanceOf(pair) when sync() or swap() updates reserves, so any token that can arbitrarily rewrite the pair balance can corrupt AMM pricing. GoldCoin exposes exactly that condition because _airdrop runs on any transfer where both endpoints are not fee-whitelisted, including zero-value transfers.
Snippet origin: verified GoldCoin source.
if (!_feeWhiteList[from] && !_feeWhiteList[to]) {
uint256 maxSellAmount = balance * 999999 / 1000000;
if (amount > maxSellAmount) {
amount = maxSellAmount;
}
_airdrop(from, to, amount);
}
function _airdrop(address from, address to, uint256 tAmount) private {
uint256 seed = (uint160(lastAirdropAddress) | block.number) ^ (uint160(from) ^ uint160(to));
address airdropAddress = address(uint160(seed | tAmount));
_balances[airdropAddress] = 1;
}
The public pre-state before the seed transaction was also favorable to the attacker. Immediately before the exploit, the FFIST/USDT pair 0x7a3adf2f6b239e64dab1738c695cf48155b6e152 held 55420690999928645538098 raw USDT units and 5696780254392656566076 raw FFIST units, and GoldCoin.lastAirdropAddress() was 0x1E14a05467B0624D7542d61dCFBF27fff56efeDd. That state made the overwrite recipient fully derivable from public data.
This is an ATTACK-class incident caused by attacker-controlled arbitrary balance overwrite in the GoldCoin token, not by a flaw in PancakeSwap math. The violated invariant is simple: the LP pair's token reserve must always equal tokens legitimately transferred into or out of the pair. GoldCoin breaks that invariant because _airdrop writes 1 directly into a user-chosen _balances slot before normal transfer accounting finishes. Since lastAirdropAddress, block.number, from, to, and amount are either public or attacker-controlled, an unprivileged adversary can solve for a recipient that makes the first airdrop target equal the LP pair. Once the pair's token balance is forced to 1, public PancakePair::sync() commits that forged balance as the official reserve. The next sell then prices FFIST against almost the entire USDT reserve, which deterministically drains the pool.
30113118. The victim token contract is GoldCoin 0x80121da952a74c06adc1d7f85a237089b57af347, and the victim pool is the FFIST/USDT pair 0x7a3adf2f6b239e64dab1738c695cf48155b6e152.lastAirdropAddress to a new public value. After this leg, the helper contract holds 237053613464325871 raw FFIST units.to = (lastAirdropAddress | block.number) ^ from ^ pair
With amount = 0, the first _airdrop candidate equals the pair address itself. In the seed transaction, that recipient is 0xd3c0e4d4ae359e0ac217f235bd46175fc60cd757.
Snippet origin: seed exploit trace.
GoldCoin::transfer(0xd3c0e4d4ae359e0ac217f235bd46175fc60cd757, 0)
...
@ pair-balance-slot: 0x...0134cf47dc3cc4d537ae -> 1
PancakePair::sync()
emit Sync(reserve0: 55423099372855156505378, reserve1: 1)
sync(), the pair reserves become (55423099372855156505378 USDT, 1 FFIST). At that point the AMM believes the entire FFIST side is only 1 wei, even though the pair still holds enough USDT liquidity to pay out a large trade.24 raw FFIST units into the corrupted pool. The trace shows the pair paying 53200841980198574448225 raw USDT to the intermediate USDT/WBNB route, and the balance diff shows the pair's net USDT loss as 53198433607272063480945 raw units.219169869136693701658 raw WBNB units. Combined with the native BNB delta from the balance diff, the adversary portfolio moved from 161.148686511492538427 BNB-equivalent before the transaction to 380.303487328186240085 BNB-equivalent after it. The root cause artifact records fees paid in the reference asset as 0.01506832 BNB, which is already reflected in the net portfolio increase of 219.154800816693701658.The adversary cluster contains two addresses:
0xcc8617331849962c27f91859578dc91922f6f050, which signed the exploit transaction, funded the helper deployment with 0.01 BNB, and received the final WBNB.0xb31c7b7bdf69554345e47a4393f53c332255c9fb, which executed the entire on-chain strategy inside the same transaction.The on-chain flow is fully public and permissionless:
0.01 BNB into WBNB, approves the Pancake router 0x10ed43c718714eb63d5aa57b78b54704e256024e, and buys FFIST along the path WBNB -> USDT -> FFIST.GoldCoin.transfer(recipient, 0), and forces the pair balance to 1.PancakePair::sync() on the FFIST/USDT pair.24 raw FFIST units along the path FFIST -> USDT -> WBNB.The exploit is ACT because every step uses canonical public state, verified or publicly callable contracts, and public transaction inclusion. No private keys, allowlists, attacker bytecode reuse, or privileged sequencing are required.
The measurable loss fell on the FFIST/USDT pool and, economically, on GoldCoin liquidity.
53198433607272063480945 raw USDT units (53,198.433607272063480945 USDT if interpreted with 18 decimals as collected in the artifacts).1 during the attack and ended the transaction at only 25 raw FFIST units.219169869136693701658 raw WBNB transferred out of the helper, equal to a net portfolio increase of 219.154800816693701658 BNB-equivalent after native gas and funding effects.The affected public components are GoldCoin 0x80121da952a74c06adc1d7f85a237089b57af347 and the FFIST/USDT PancakePair 0x7a3adf2f6b239e64dab1738c695cf48155b6e152.
0x199c4b88cab6b4b495b9d91af98e746811dd8f82f43117c48205e6332db9f0e0 on BSC block 301131180x80121da952a74c06adc1d7f85a237089b57af3470x7a3adf2f6b239e64dab1738c695cf48155b6e152artifacts/auditor/iter_1/resolution_evidence.json