All incidents

ETN UMarket Drain

Share
Aug 04, 2022 13:50 UTCAttackLoss: 11,253.73 USDTPending manual check1 exploit txWindow: Atomic
Estimated Impact
11,253.73 USDT
Label
Attack
Exploit Tx
1
Addresses
2
Attack Window
Atomic
Aug 04, 2022 13:50 UTC → Aug 04, 2022 13:50 UTC

Exploit Transactions

TX 1BSC
0x72321a3b50bb68ac3b46b0ab973b0e87b6c48ab73d23c4ba2cb73527f978d995
Aug 04, 2022 13:50 UTCExplorer

Victim Addresses

0xc0e8d30d2ead2c324b3f1a8386992ba1be534cbfBSC
0x1292267f726e6f313972ec4e14578735473e1649BSC

Loss Breakdown

11,253.73USDT

Similar Incidents

Root Cause Analysis

ETN UMarket Drain

1. Incident Overview TL;DR

On BNB Chain block 20147975, transaction 0x72321a3b50bb68ac3b46b0ab973b0e87b6c48ab73d23c4ba2cb73527f978d995 used a flash-loan-backed helper contract to mint the rights needed to create an ETN product, force EtnProduct to seed a new Pancake pair with protocol-owned U, receive the LP position personally, burn that LP to recover U, sell enough U into UMarket to drain its USDT inventory, repay the flash loan, and forward 3,074.534856316884358000 USDT to the attacker EOA 0xde703797fe9219b0485fb31eda627aa182b1601e.

The root cause is a composable protocol design failure across two public code paths. EtnProduct.addLiquidity() spends protocol-held U and product tokens but mints the LP position to msg.sender, while UMarket.saleU() independently redeems U for USDT at a 1:1 rate when salePrice() is 1e18. Any unprivileged user who can mint the prerequisite NFT and shop rights can therefore convert protocol-controlled U into redeemable USDT.

2. Key Background

The exploit depends on four public ETN components. ETN_NFT at 0x48835a9065af7315916adfc1f952b7abebdbfd62 exposes a public mintETN(...) path and charges mintPrice; its source shows mintETN only requires payment and increments totalSupply(). EtnShop at 0xbcef2955c8955342e9cc92a090bdaecff8c562f8 lets the community-NFT owner call invite(address,uint) and then mint a shop NFT for the invited address. EtnProduct at 0x1292267f726e6f313972ec4e14578735473e1649 allows a shop owner to call newProduct(...), create a token through its factory, and immediately seed Pancake liquidity. UMarket at 0xc0e8d30d2ead2c324b3f1a8386992ba1be534cbf buys and sells U against USDT according to salePrice and buyPrice.

The relevant pre-state was publicly reconstructible before block 20147975: ETN_NFT.totalSupply() == 11, EtnProduct held 2,800,000 U, and UMarket held 11,253.734856316884358000 USDT. The balance diff confirms EtnProduct later lost exactly 700,000 U, while UMarket later lost its full USDT balance.

3. Vulnerability Analysis & Root Cause Summary

This is an ATTACK-class ACT exploit, not a privileged compromise. The violated invariant is straightforward: if protocol-owned U is supplied into liquidity, the resulting LP claim must remain protocol-controlled. Instead, EtnProduct delegated that claim to the external caller. BscScan-verified source for EtnProduct shows newProduct(...) gates only on etnShop.canUploadProduct(msg.sender, commId, shopId), records ownerMap[erc20Addr] = msg.sender, and calls addLiquidity(erc20Addr). The same source shows addLiquidity(address token) invokes Pancake router addLiquidity(..., msg.sender, ...), so the LP position is minted to the caller rather than to EtnProduct.

That custody failure alone externalizes protocol-owned U. The second half of the exploit is UMarket, whose verified source exposes saleU(uint256 amount) and getSaleCost(uint256 value). The root cause analysis is supported by the pre-state read that salePrice() == 1e18, meaning one U redeemed for one USDT. Because the attacker could permissionlessly acquire the shop authorization chain, the composition of EtnProduct and UMarket created a deterministic drain path from protocol inventory to liquid USDT.

4. Detailed Root Cause Analysis

The full sequence is visible in the seed trace for 0x72321a3b50bb68ac3b46b0ab973b0e87b6c48ab73d23c4ba2cb73527f978d995. The sender EOA is 0xde703797fe9219b0485fb31eda627aa182b1601e, and the transaction target is helper contract 0x178bf96e303fb31aef1b586271a63acd33e4eaf7. The helper first takes a DODO flash loan of 9,400 USDT, then swaps part of that USDT into BNB to fund the public NFT mint and shop mint fees.

The attacker then acquires the necessary ETN rights without privilege. ETN_NFT.mintETN(...) mints community token 11; EtnShop.invite(address(this), 11) invites the helper into that community; and EtnShop.mint(11, ...) mints shop token 1100. Those steps matter because EtnProduct.newProduct(11, 0, ...) trusts EtnShop.canUploadProduct(msg.sender, commId, shopId) as sufficient authorization for product creation.

The code-level breakpoint occurs when EtnProduct.addLiquidity() seeds the pair using protocol inventory but designates the external caller as the LP owner. The trace shows 0xaa33085e8Fa2CB903157324603E4601299E5dA06::transferFrom(EtnProduct, pair, 700000000000000000000000) and then the Pancake pair mints LP to the helper. The balance diff independently confirms:

{
  "token": "0xaa33085e8fa2cb903157324603e4601299e5da06",
  "holder": "0x1292267f726e6f313972ec4e14578735473e1649",
  "before": "2800000000000000000000000",
  "after": "2100000000000000000000000",
  "delta": "-700000000000000000000000"
}

Once the helper owns the LP tokens, the rest of the flow follows normal AMM mechanics. The helper transfers LP back to the new pair 0xc9053b00720eb661bbddc7bd6aba1d222aad5a71 and calls burn(address(this)). The trace records the pair returning 606091526731326449486438 U to the helper. That extracted U was not paid for by the attacker as treasury inventory; it was released because the LP claim had been wrongly externalized.

UMarket then monetizes the extracted U. The trace shows UMarket::saleU(11253734856316884358000), followed by a U transfer from the helper into UMarket and a USDT transfer of the same raw amount back to the helper:

0xc0e8D30D2ead2C324b3f1A8386992Ba1Be534CbF::saleU(11253734856316884358000)
0xaa33085e8Fa2CB903157324603E4601299E5dA06::transferFrom(helper, UMarket, 11253734856316884358000)
BEP20USDT::transfer(helper, 11253734856316884358000)
emit SaleU(helper, 11253734856316884358000, 11253734856316884358000)

The balance diff confirms the direct impact of that redemption:

{
  "token": "0x55d398326f99059ff775485246999027b3197955",
  "holder": "0xc0e8d30d2ead2c324b3f1a8386992ba1be534cbf",
  "before": "11253734856316884358000",
  "after": "0",
  "delta": "-11253734856316884358000"
}

Afterward the helper repays the 9,400 USDT flash loan and transfers the remaining 3,074.534856316884358000 USDT to the attacker EOA. The root cause is therefore fully deterministic: public mint rights plus LP recipient misassignment plus unconditional 1:1 redemption let any unprivileged actor convert protocol-held U into USDT.

5. Adversary Flow Analysis

The adversary cluster consists of EOA 0xde703797fe9219b0485fb31eda627aa182b1601e and helper contract 0x178bf96e303fb31aef1b586271a63acd33e4eaf7. The metadata shows the EOA sent the transaction to the helper, and the balance diff shows the final USDT profit landed on that EOA.

The on-chain flow is:

  1. Flash-borrow 9,400 USDT from DODO.
  2. Swap 7,380 USDT to BNB to fund ETN public mint costs.
  3. Mint community NFT 11, self-invite in EtnShop, and mint shop NFT 1100.
  4. Call EtnProduct.newProduct(11, 0, 10_000_000_000, ...).
  5. Receive LP minted from 700,000 U plus 700,000 product tokens.
  6. Burn the LP to recover 606,091.526731326449486438 U.
  7. Sell 11,253.734856316884358000 U into UMarket and drain all of its USDT.
  8. Repay the flash loan and forward 3,074.534856316884358000 USDT profit to the EOA.

This is ACT because every required step uses public code paths, public on-chain state, and temporary market liquidity. No protocol admin role, stolen key, or attacker-private artifact was required.

6. Impact & Losses

The immediate liquid loss was the full USDT inventory held by UMarket: 11,253.734856316884358000 USDT, encoded on-chain as 11253734856316884358000. The balance diff shows that UMarket ended the transaction with zero USDT. EtnProduct also lost custody of 700,000 U when it funded the new pool and let the attacker receive the LP position. The attacker’s net realized profit was 3,074.534856316884358000 USDT after repaying the flash loan, while still extracting a large residual U balance during the sequence.

The affected protocol components were EtnProduct and UMarket, with enabling authorization logic in ETN_NFT and EtnShop. The exploit therefore impacted both treasury-backed inventory custody and market-backed redemption liquidity.

7. References

  • Seed transaction: 0x72321a3b50bb68ac3b46b0ab973b0e87b6c48ab73d23c4ba2cb73527f978d995
  • Attacker EOA: 0xde703797fe9219b0485fb31eda627aa182b1601e
  • Helper contract: 0x178bf96e303fb31aef1b586271a63acd33e4eaf7
  • ETN_NFT: 0x48835a9065af7315916adfc1f952b7abebdbfd62
  • EtnShop: 0xbcef2955c8955342e9cc92a090bdaecff8c562f8
  • EtnProduct: 0x1292267f726e6f313972ec4e14578735473e1649
  • UMarket: 0xc0e8d30d2ead2c324b3f1a8386992ba1be534cbf
  • Seed metadata: /workspace/session/artifacts/collector/seed/56/0x72321a3b50bb68ac3b46b0ab973b0e87b6c48ab73d23c4ba2cb73527f978d995/metadata.json
  • Seed trace: /workspace/session/artifacts/collector/seed/56/0x72321a3b50bb68ac3b46b0ab973b0e87b6c48ab73d23c4ba2cb73527f978d995/trace.cast.log
  • Seed balance diff: /workspace/session/artifacts/collector/seed/56/0x72321a3b50bb68ac3b46b0ab973b0e87b6c48ab73d23c4ba2cb73527f978d995/balance_diff.json
  • Verified source references:
    • https://bscscan.com/address/0x48835a9065af7315916adfc1f952b7abebdbfd62#code
    • https://bscscan.com/address/0xbcef2955c8955342e9cc92a090bdaecff8c562f8#code
    • https://bscscan.com/address/0x1292267f726e6f313972ec4e14578735473e1649#code
    • https://bscscan.com/address/0xc0e8d30d2ead2c324b3f1a8386992ba1be534cbf#code