All incidents

9419 Migration Arbitrage

Share
Nov 16, 2023 14:12 UTCAttackLoss: 26,362.09 USDTPending manual check1 exploit txWindow: Atomic
Estimated Impact
26,362.09 USDT
Label
Attack
Exploit Tx
1
Addresses
3
Attack Window
Atomic
Nov 16, 2023 14:12 UTC → Nov 16, 2023 14:12 UTC

Exploit Transactions

TX 1BSC
0xf6ec3c22b718c3da17746416992bac7b65a4ef42ccf5b43cf0716c82bffc2844
Nov 16, 2023 14:12 UTCExplorer

Victim Addresses

0x86335cb69e4e28fad231dae3e206ce90849a5477BSC
0x0cca1055f3827b6d2f530d52c514e3699c98f3b9BSC
0x5a522c949f3dcbc30f511e20d72fb44b770f28e6BSC

Loss Breakdown

26,362.09USDT

Similar Incidents

Root Cause Analysis

9419 Migration Arbitrage

1. Incident Overview TL;DR

At BNB Chain block 33545075, transaction 0xf6ec3c22b718c3da17746416992bac7b65a4ef42ccf5b43cf0716c82bffc2844 let an unprivileged adversary turn legacy 9419V2 into fee-free 9419V3, force protocol buybacks, dump into the induced 9419V3/USDT demand, repay a Pancake V3 flash loan, and forward 26,362.09291137296841279 USDT to 0xba0bcb1d0a2166d26a4bfd9fabb825369ab36209.

The root cause is the combination of two public, attacker-timed surfaces:

  • The migrator 0x5a522c949f3dcbc30f511e20d72fb44b770f28e6 redeemed 9419V2 for 9419V3 at a fixed nominal rate with no price check, cap, or expiry.
  • Coin9419V3 at 0x86335cb69e4e28fad231dae3e206ce90849a5477 exposed buyback side effects that could be triggered before the attacker’s exit completed.

This is an ACT incident. The exploit used only public liquidity, public swaps, a public migrator, and publicly callable protocol contracts.

2. Key Background

9419V2 and 9419V3 were trading in separate Pancake markets, so their prices had diverged. That divergence mattered because the protocol kept a live migration path from the old token to the new token even after both assets had their own market prices.

Coin9419V3 stored a protocol-set migrantAddress and restricted importRelation to that address. The same contract also ran repurchase and marketing side effects inside _transfer for fee-bearing trades. Those design choices meant the protocol trusted a single migrator to mint live 9419V3 claims and also allowed trading activity to spend protocol inventory at attacker-chosen timing.

From the verified Coin9419V3 source:

modifier onlyMigrant{
    require(msg.sender == migrantAddress, "Err migrant contract address");
    _;
}

function importRelation(address recommer, address user) external onlyMigrant{
    addRelation(recommer, user);
}

function _transfer(address from,address to,uint256 amount) private {
    ...
    if( takeFee && msg.sender != marketingAddress && msg.sender != repurchaseAddress ){
        _repurchase6827Pool();
        _marketingAutoAddLp();
    }
    ...
}

Origin: Coin9419V3 verified source.

The unverified migrator was reconstructed from storage and trace evidence. Its key behavior was:

slot_1_old_token      = 0x0cca1055f3827b6d2f530d52c514e3699c98f3b9
slot_2_new_token      = 0x86335cb69e4e28fad231dae3e206ce90849a5477
slot_3_residual_amount= 1000000000000000000

entrypoint:
  amount = oldToken.balanceOf(msg.sender)
  oldToken.transferFrom(msg.sender, address(this), amount)
  newToken.transfer(msg.sender, amount - 1e18)
  Coin9419V3.importRelation(slot_4_referrer, msg.sender)

Origin: migrator storage and behavior reconstruction.

3. Vulnerability Analysis & Root Cause Summary

The vulnerability class is an economic attack enabled by unsafe migration design and attacker-triggerable buyback execution. The protocol left a public bridge from 9419V2 to 9419V3 active even though the two tokens no longer had parity in the market. Because the migrator exchanged tokens at a fixed nominal rate, an attacker could buy cheap 9419V2 and redeem it for more valuable 9419V3. The same setup became more dangerous because 9419V3 trading could trigger protocol repurchase and marketing flows before the attacker’s sell finished settling. That let the attacker time protocol-owned inventory consumption immediately before exiting into the 9419V3/USDT pool. The broken invariant is straightforward: a migration path must not let public users convert cheaper legacy inventory into more expensive replacement inventory at a fixed rate, and protocol buyback inventory must not be spendable at attacker-chosen prices.

The exploit required four concrete live conditions, all of which were satisfied in the seed state:

  • The attacker could buy 9419V2 from the public legacy market.
  • The public migrator still accepted 9419V2 and released 9419V3 at the stale fixed nominal rate.
  • Coin9419V3 still routed fee-bearing transfers through the repurchase path.
  • The repurchase contract still held enough 6827 inventory to create material buy pressure.

The violated design principles were equally concrete:

  • A legacy-to-new-token migration must be disabled or repriced once the two assets trade independently.
  • Fee exemptions must not be reachable through a public migration path.
  • Protocol buyback logic must not be triggerable at attacker-selected timing without slippage and execution controls.

4. Detailed Root Cause Analysis

The first breakpoint was the public migrator. The trace shows the exploit contract calling the migrator’s no-argument entrypoint, and the reconstructed behavior matches the root cause exactly:

0x5a522C949F3DcBc30f511E20D72fb44B770f28e6::004b2cc0()
  Coin9419V2::balanceOf(attacker) -> 12757806796945991578214185129315
  Coin9419V3::balanceOf(migrator) -> 12757806796946991578214185129315
  Coin9419V2::transferFrom(attacker, migrator, 12757806796945991578214185129315)

Origin: seed transaction trace.

That behavior is reinforced by the post-transaction balance deltas:

{
  "token": "0x0cca1055f3827b6d2f530d52c514e3699c98f3b9",
  "holder": "0x5a522c949f3dcbc30f511e20d72fb44b770f28e6",
  "delta": "12757806796945991578214185129315"
}

Origin: seed transaction balance diff.

The attacker did not need privileged access to exploit this. The migrator was public, and Coin9419V3 already trusted it via migrantAddress. The attacker first bought cheap 9419V2 from the public 9419V2 market, then bought 9419V3 into the fee-exempt migrator address, and finally surrendered the cheap 9419V2 to withdraw untaxed 9419V3. That converted legacy-market value into new-market value at a stale 1:1 nominal rate.

The second breakpoint was the buyback path. Coin9419V3 explicitly routed fee-bearing transfers through _repurchase6827Pool() and _marketingAutoAddLp(), and the exploit transaction repeatedly spent protocol-owned 6827 immediately before the dump. The resulting balance diff shows protocol buyback inventory leaving the repurchase contract:

{
  "token": "0xea8db921475764f7fb8e2548d77f5a6425605b45",
  "holder": "0x11cd2168fc420ae1375626655ab8f355f0075bd6",
  "delta": "-2923089256979974330695203983"
}

Origin: seed transaction balance diff.

At that point the economic invariant was already broken. The attacker had acquired fee-free 9419V3 inventory that should not have been obtainable at that price, and the protocol then spent its own 6827 reserves to support 9419V3 demand into the attacker’s exit.

5. Adversary Flow Analysis

The attacker cluster was:

  • EOA 0xe9fac789c947f364f53c3bc28bb6e9e099526468, which submitted the transaction.
  • Exploit contract 0x87c75f8a69732bad999ce1fab464526856215c77, which executed the entire strategy.
  • Profit recipient 0xba0bcb1d0a2166d26a4bfd9fabb825369ab36209, which received the final USDT transfer.

The on-chain execution flow was:

  1. The exploit contract flash-borrowed 1,100,000 USDT from Pancake V3 pool 0x92b7807bf19b7dddf89b706143896d05228f3121.
  2. It seeded the marketing contract so repeated LP-side effects could execute.
  3. It bought 9419V2 from the old public market.
  4. It bought 9419V3 with the migrator as recipient, using the migrator’s fee exemption to position untaxed 9419V3.
  5. It sold excess 9419V2, then called the public migrator and converted the remaining cheap 9419V2 into 9419V3.
  6. It repeatedly forced the repurchase path so protocol-owned 6827 was spent buying 9419V3.
  7. It sold the migrated 9419V3 into the now-supported 9419V3/USDT pool.
  8. It repaid 1,100,110 USDT to the flash pool and forwarded the residual profit.

The seed trace and balance diff jointly show the flash-loan funding, the public migration call, the repurchase inventory depletion, and the final profit transfer, so the adversary flow is fully deterministic rather than inferred.

6. Impact & Losses

The measurable realized profit was 26,362.09291137296841279 USDT, represented on-chain as 26362092911372968412790 smallest units. The balance diff shows that amount arriving at the immediate profit-recipient EOA:

{
  "token": "0x55d398326f99059ff775485246999027b3197955",
  "holder": "0xba0bcb1d0a2166d26a4bfd9fabb825369ab36209",
  "delta": "26362092911372968412790"
}

Origin: seed transaction balance diff.

The protocol also lost control over 6827 repurchase inventory during the attack and suffered attacker-favorable repricing in the 9419V3/USDT market. The practical victim was the 9419 DAO token system spanning Coin9419V2, Coin9419V3, and the live migrator.

7. References

  • Seed exploit transaction metadata for 0xf6ec3c22b718c3da17746416992bac7b65a4ef42ccf5b43cf0716c82bffc2844, including sender 0xe9fac789c947f364f53c3bc28bb6e9e099526468, target 0x87c75f8a69732bad999ce1fab464526856215c77, and block 33545075
  • Seed opcode-level trace for the same transaction, which shows the flash loan, migrator call, repurchase execution, and repayment flow
  • Seed balance-diff artifact for the same transaction, which confirms the final USDT profit and the repurchase / migrator token deltas
  • Verified Coin9419V3 source at 0x86335cb69e4e28fad231dae3e206ce90849a5477
  • Verified Coin9419V2 source at 0x0cca1055f3827b6d2f530d52c514e3699c98f3b9
  • Migrator storage and behavior reconstruction for 0x5a522c949f3dcbc30f511e20d72fb44b770f28e6
  • BscScan transaction page: https://bscscan.com/tx/0xf6ec3c22b718c3da17746416992bac7b65a4ef42ccf5b43cf0716c82bffc2844