All incidents

UEarnPool Reward Drain

Share
Nov 17, 2022 01:22 UTCAttackLoss: 22,330.57 USDTPending manual check2 exploit txWindow: 1m 12s
Estimated Impact
22,330.57 USDT
Label
Attack
Exploit Tx
2
Addresses
1
Attack Window
1m 12s
Nov 17, 2022 01:22 UTC → Nov 17, 2022 01:24 UTC

Exploit Transactions

TX 1BSC
0x824de0989f2ce3230866cb61d588153e5312151aebb1e905ad775864885cd418
Nov 17, 2022 01:22 UTCExplorer
TX 2BSC
0xb83f9165952697f27b1c7f932bcece5dfa6f0d2f9f3c3be2bb325815bfd834ec
Nov 17, 2022 01:24 UTCExplorer

Victim Addresses

0x02d841b976298dcd37ed6cc59f75d9dd39a3690cBSC

Loss Breakdown

22,330.57USDT

Similar Incidents

Root Cause Analysis

UEarnPool Reward Drain

1. Incident Overview TL;DR

UEarnPool on BNB Chain was drained through a permissionless referral-reward design flaw. In transaction 0x824de0989f2ce3230866cb61d588153e5312151aebb1e905ad775864885cd418, the attacker prepared a deep inviter tree of attacker-controlled helper contracts. In transaction 0xb83f9165952697f27b1c7f932bcece5dfa6f0d2f9f3c3be2bb325815bfd834ec, the attacker flash-swapped 2.42 million USDT, used that capital to manufacture team volume inside the self-controlled tree, claimed fixed team rewards from UEarnPool, repaid the flash swap, and extracted protocol funds.

The root cause is that UEarnPool treats attacker-manufactured referral volume as legitimate team volume. bindInvitor lets any fresh account join an arbitrary inviter tree, _addTeamAmount credits the full stake amount to every upstream inviter, and claimTeamReward converts those attacker-controlled teamAmount balances into fixed USDT payouts without any sybil resistance or economic-backing check.

2. Key Background

UEarnPool is deployed at 0x02d841b976298dcd37ed6cc59f75d9dd39a3690c on BNB Chain and uses USDT at 0x55d398326f99059ff775485246999027b3197955 with 18 decimals. The exploit used PancakePair 0x7efaef62fddcca950418312c6c91aef321375a00 as a permissionless flash-swap source.

The relevant reward model has two moving parts. First, users can bind an inviter through a permissionless referral tree. Second, once a user’s teamAmount and personal stake satisfy level thresholds, claimTeamReward pays fixed milestone rewards. The level-3 path relevant here sums 3,000 USDT, 9,000 USDT, 30,000 USDT, and 120,000 USDT for a total of 162,000 USDT per qualified account.

The attacker did not need privileged access. The only prerequisites were fresh accounts or contracts, enough temporary capital for the large qualifying stake, and enough pool liquidity to pay the milestone rewards.

3. Vulnerability Analysis & Root Cause Summary

This is an ATTACK-category ACT opportunity caused by unsafe referral accounting. The invariant that should have held is: team rewards must be backed by economically real, non-self-manufactured team volume, and one unit of capital must not unlock repeated fixed payouts across attacker-controlled accounts.

The verified UEarnPool source exposes the exact code paths that break that invariant:

function bindInvitor(address invitor) external {
    address account = msg.sender;
    require(invitor != account, "self");
    ...
}

function _addTeamAmount(address account, uint256 amount) private {
    uint256 teamLength = _teamLength;
    ...
}

function claimTeamReward(address account) external {
    uint256 level = getUserLevel(account);
    ...
}

bindInvitor allows arbitrary tree construction by any new account. _addTeamAmount then propagates the full staked amount to each upstream inviter for up to the configured team depth. claimTeamReward finally turns those threshold crossings into fixed USDT transfers, while levelClaimed only prevents re-claiming the same level and does not remove or economically net the underlying team volume. That combination makes the system sybil-amplifiable and drainable with recycled capital.

4. Detailed Root Cause Analysis

The exploit starts with attacker-controlled topology creation. The setup trace for tx 0x824de0989f2ce3230866cb61d588153e5312151aebb1e905ad775864885cd418 shows the EOA 0x645516882d8d1b2bc69f85c58164a290c92c0365 calling attacker contract 0x14cab4bb0d3bff14cc104d53c812bb1cc882ab3d, which repeatedly deploys helper contracts and has each helper call UEarnPool::bindInvitor(...) to point at the next attacker-controlled account in the chain.

0x7D66F070...::aa21133c(0x645516882d8d1b2bc69f85c58164a290c92c0365)
  └─ UEarnPool::bindInvitor(0x645516882D8d1b2bc69F85C58164a290c92c0365)
...
0x21C473f9...::aa21133c(0x4C1eF1e394d6a81613b9319dc9CE6F4a17C6a9E0)
  └─ UEarnPool::bindInvitor(0x4C1eF1e394d6a81613b9319dc9CE6F4a17C6a9E0)

With the referral chain in place, the attacker uses flash liquidity to seed teamAmount. The exploit trace for tx 0xb83f9165952697f27b1c7f932bcece5dfa6f0d2f9f3c3be2bb325815bfd834ec shows PancakePair::swap sending 2.42 million USDT to the attacker contract, which forwards 2.4 million USDT to the leaf helper and calls UEarnPool::stake(0, 2400000000000000000000000). Because _addTeamAmount credits the full amount to each upstream inviter, that one leaf stake immediately pushes all attacker-controlled ancestors toward the level thresholds.

The attacker then walks back up the tree with 20,000 USDT stakes to satisfy each helper’s personal-amount requirement and calls claimTeamReward account by account. The on-chain trace records repeated 162,000 USDT reward transfers from UEarnPool to helper addresses:

UEarnPool::claimTeamReward(0xFF05d42441380bA69cd923299aBf2feC7e46d85A)
  └─ BEP20USDT::transfer(0xFF05d42441380bA69cd923299aBf2feC7e46d85A, 162000000000000000000000)
...
UEarnPool::claimTeamReward(0xbF4d6F5485dC2B9bCe55487D02DDf493670C689C)
  └─ BEP20USDT::transfer(0xbF4d6F5485dC2B9bCe55487D02DDf493670C689C, 162000000000000000000000)

Those fixed transfers are the concrete breakpoint: protocol liquidity is paid out solely because attacker-controlled accounts crossed thresholds produced by attacker-controlled referral volume. No check enforces that the volume came from distinct users, from net new value, or from rewards that the pool had sustainably earned.

The loss is confirmed by the balance diff for the exploit transaction. UEarnPool’s USDT balance fell from 22331065000000000000000 to 500000000000000000, a net delta of -22330565000000000000000, while the Pancake pair received 6292000000000000000000 USDT back and the attacker-controlled payout address 0x9709dff20a1a3bf57e504eacf30808bc2d21222d received 15938565000000000000000 USDT.

5. Adversary Flow Analysis

The attack has two on-chain stages.

First, the attacker prepares the sybil tree in tx 0x824de0989f2ce3230866cb61d588153e5312151aebb1e905ad775864885cd418. The sender EOA is 0x645516882d8d1b2bc69f85c58164a290c92c0365, and the direct callee is the attacker orchestrator 0x14cab4bb0d3bff14cc104d53c812bb1cc882ab3d. The trace shows repeated helper deployments and bindInvitor calls that produce a deep chain rooted in attacker-controlled accounts.

Second, the attacker realizes the drain in tx 0xb83f9165952697f27b1c7f932bcece5dfa6f0d2f9f3c3be2bb325815bfd834ec. The same EOA again calls the orchestrator, which flash-swaps 2.42 million USDT from PancakePair, funds the leaf helper, stakes 2.4 million USDT into UEarnPool, iterates 20,000 USDT stakes and claimTeamReward calls across the upstream helpers, sweeps helper balances back to the orchestrator, repays 2426292000000000000000000 USDT to PancakePair, and distributes profit.

The trace and balance diff jointly support the full adversary cluster:

  • 0x645516882d8d1b2bc69f85c58164a290c92c0365: sender of both transactions and recipient of 100 USDT in the exploit transaction.
  • 0x14cab4bb0d3bff14cc104d53c812bb1cc882ab3d: attacker orchestrator that deploys helpers, executes the flash swap, and routes funds.
  • 0x9709dff20a1a3bf57e504eacf30808bc2d21222d: profit receiver of 15,938.565 USDT.

6. Impact & Losses

UEarnPool lost 22330565000000000000000 raw USDT units, which is 22,330.565 USDT at 18 decimals. The exploit left the pool with only 500000000000000000 raw units, or 0.5 USDT, confirming near-total depletion of the pool balance available to this reward path.

The realized attacker-side monetary outcomes visible in the exploit transaction are:

  • 0x9709dff20a1a3bf57e504eacf30808bc2d21222d gained 15938565000000000000000 raw USDT units.
  • 0x645516882d8d1b2bc69f85c58164a290c92c0365 gained 100000000000000000000 raw USDT units.
  • PancakePair gained 6292000000000000000000 raw USDT units as principal plus fee repayment.

7. References

  • Verified victim contract: UEarnPool 0x02d841b976298dcd37ed6cc59f75d9dd39a3690c on BscScan.
  • Setup transaction metadata and trace: 0x824de0989f2ce3230866cb61d588153e5312151aebb1e905ad775864885cd418.
  • Exploit transaction metadata, trace, and balance diff: 0xb83f9165952697f27b1c7f932bcece5dfa6f0d2f9f3c3be2bb325815bfd834ec.
  • Key public contracts: USDT 0x55d398326f99059ff775485246999027b3197955, PancakePair 0x7efaef62fddcca950418312c6c91aef321375a00, UEarnPool 0x02d841b976298dcd37ed6cc59f75d9dd39a3690c.