All incidents

AURUM NodePool Parameter Abuse

Share
Nov 22, 2022 18:22 UTCAttackLoss: 49.92 WBNBPending manual check2 exploit txWindow: 1m 51s
Estimated Impact
49.92 WBNB
Label
Attack
Exploit Tx
2
Addresses
2
Attack Window
1m 51s
Nov 22, 2022 18:22 UTC → Nov 22, 2022 18:24 UTC

Exploit Transactions

TX 1BSC
0xb3bc6ca257387eae1cea3b997eb489c1a9c208d09ec4d117198029277468e25d
Nov 22, 2022 18:22 UTCExplorer
TX 2BSC
0x7f031e8543e75bd5c85168558be89d2e08b7c02a32d07d76517cdbb10e279782
Nov 22, 2022 18:24 UTCExplorer

Victim Addresses

0x70678291bddfd95498d1214be368e19e882f7614BSC
0x73a1163ea930a0a67dfefb9c3713ef0923755b78BSC

Loss Breakdown

49.92WBNB

Similar Incidents

Root Cause Analysis

AURUM NodePool Parameter Abuse

1. Incident Overview TL;DR

On BNB Smart Chain, the attacker executed a two-transaction permissionless exploit against AURUM Finance by abusing public configuration functions in AurumNodePool. The attacker first bought a small amount of AURUM, lowered the node purchase price to 1000 ether, created one node, then raised rewardPerDay to an attacker-chosen value, claimed an outsized AURUM reward, and sold the reward into the public AURUM/WBNB PancakeSwap pool. The root cause was missing access control on the economic parameters that govern node creation cost and reward emission.

2. Key Background

AURUM Finance used an auxiliary AurumNodePool contract at 0x70678291bddfd95498d1214be368e19e882f7614 to sell nodes for AURUM and to pay node rewards in AURUM. A node owner's reward is linear in elapsed time and the global rewardPerDay parameter. AURUM is fee-on-transfer, so a large reward claim and immediate sale materially changes the AURUM/WBNB PancakeSwap pair at 0xe6b2a82ff7f3414edc7ef95c42a6014913f8fd61. The exploit only required ordinary public BSC transactions and enough AURUM to satisfy the attacker-lowered node price.

3. Vulnerability Analysis & Root Cause Summary

The vulnerability class is unrestricted mutation of critical economic configuration. AurumNodePool exposed both changeNodePrice(uint256) and changeRewardPerNode(uint256) as unrestricted external functions. Those values directly gate createNode and claimNodeReward, so any unprivileged caller could rewrite the cost to acquire a node and the emission rate used to compute rewards. The node reward formula was rewardPerDay * (block.timestamp - node.lastClaimTime) / 86400, which made rewardPerDay the direct multiplier on the token transfer performed during reward claim. Once the attacker held a node, the attacker could set an extreme rewardPerDay, claim the inflated reward from the protocol's AURUM balance, and dump the tokens into existing AMM liquidity for WBNB. The violated invariant is that only protocol governance should be able to mutate node pricing and reward parameters.

4. Detailed Root Cause Analysis

The relevant victim code from the verified AurumNodePool source is:

function getNodeReward(NodeEntity memory node) internal view returns (uint256) {
    return rewardPerDay * (block.timestamp - node.lastClaimTime) / 86400;
}

function claimNodeReward(uint256 _creationTime) external {
    ...
    uint256 rewardNode = getNodeReward(node);
    node.lastClaimTime = block.timestamp;
    AURUM.transfer(account, rewardNode);
}

function changeNodePrice(uint256 newNodePrice) external {
    nodePrice = newNodePrice;
}

function changeRewardPerNode(uint256 _rewardPerDay) external {
    rewardPerDay = _rewardPerDay;
}

The first seed transaction, 0xb3bc6ca257387eae1cea3b997eb489c1a9c208d09ec4d117198029277468e25d, shows the attacker helper buying AURUM, then invoking the unrestricted price setter and node creation path:

0x70678291...::changeNodePrice(1000000000000000000000)
0x70678291...::createNode(1)

The second seed transaction, 0x7f031e8543e75bd5c85168558be89d2e08b7c02a32d07d76517cdbb10e279782, shows the unrestricted reward-rate mutation, reward claim, and resulting transfer from the node pool:

0x70678291...::changeRewardPerNode(434159898144856792986061626032)
0x70678291...::claimNodeReward(1669141375)
AURUMFinance::transfer(0x3d743b2f760a431cc20047cb5c7758c9a8860d6b, 557774869144434074322370838)

After the claim, the helper contract held 557798557556828860854456306 AURUM because of the reward transfer and token-side accounting visible in trace storage changes. The helper then sold the balance through PancakeRouter into the AURUM/WBNB pool. The exploit therefore did not require privileged credentials, private state, or attacker-only infrastructure; it was entirely realizable through public on-chain calls against live protocol contracts and public liquidity.

5. Adversary Flow Analysis

The adversary cluster consisted of EOA 0x6903499751f973052155df339116b6c6b24ac24b and helper contract 0x3d743b2f760a431cc20047cb5c7758c9a8860d6b. The flow was:

  1. In block 23282134, the EOA sent 0.01 BNB to the helper via 0xb3bc6ca257387eae1cea3b997eb489c1a9c208d09ec4d117198029277468e25d.
  2. The helper bought AURUM on PancakeSwap, called changeNodePrice(1000 ether), and created one node. The node creation timestamp used later for reward claim was 1669141375.
  3. In block 23282171, the EOA triggered the helper again via 0x7f031e8543e75bd5c85168558be89d2e08b7c02a32d07d76517cdbb10e279782.
  4. The helper called changeRewardPerNode(434159898144856792986061626032), then claimNodeReward(1669141375), pulling 557774869144434074322370838 AURUM out of the node-pool-funded token balance.
  5. The helper sold 557798557556828860854456306 AURUM through PancakeRouter. The trace shows the pair paying out 49822328340023151336 wei of WBNB before unwrap, and the helper returned 49.847793631535049573 BNB to the EOA.

6. Impact & Losses

The measurable loss was extraction of WBNB value from the public AURUM/WBNB liquidity pool plus corruption of the protocol's reward economics. Collector balance deltas show WBNB at 0xbb4cdb9cbd36b01bd1cbaebf2de08d9173bc095c lost 49925429504468031091 wei in the realization transaction, while the attacker EOA gained 49813416591535049573 wei in that same transaction. Across both seed transactions, the attacker EOA moved from 0.19318891 BNB to 49.953966401535049573 BNB, for net profit of 49.760777491535049573 BNB. The recorded loss artifact is 49915454107092780868 raw WBNB units.

7. References

  • Seed transaction 0xb3bc6ca257387eae1cea3b997eb489c1a9c208d09ec4d117198029277468e25d on BSC, including trace and balance diff.
  • Seed transaction 0x7f031e8543e75bd5c85168558be89d2e08b7c02a32d07d76517cdbb10e279782 on BSC, including trace and balance diff.
  • Verified AURUM token source at 0x73a1163ea930a0a67dfefb9c3713ef0923755b78.
  • Verified AurumNodePool source extracted by the auditor at 0x70678291bddfd95498d1214be368e19e882f7614.
  • Public liquidity venue: PancakeSwap AURUM/WBNB pair 0xe6b2a82ff7f3414edc7ef95c42a6014913f8fd61.