EarnHub Hack

TOTAL LOST $245K
Low Other

What happened

The exploiter's address:

https://bscscan.com/address/0x3d98aee2…24dacc

Attacker contract A:

https://bscscan.com/address/0x89011932…4ad55f

Attacker contract B:

https://bscscan.com/address/0xf7acfa1c…9bdfe5

The root of the issue:

The makeHop() function allowed shareholders to shift their funds through different staking pools in a gas-efficient manner. This feature was intended to be implemented on the next dApp update, however, it’s been around for about 1 month on the contract side.

The issue is in the line below, which assumes that there can not be a malicious smart contract on the pool that is called on receiveHop(_pool):

tokenPool.stakingToken.approve(address(_newPool),

tokenPool.stakingToken.totalSupply());

By approving the totalSupply to the new pool, Contract B was able to have allowance to spend the staking contract tokens. This basically means they were able to withdraw them from the staking contract at a whim once that initial setup was made.

The attacker:

- created contract A

- created contract B

- the attacker contract then proceeded to buy some EarnHub, stake it, and make it hop to contract B (makeHop(contractBaddress))

- after receiving the hop, the contract was able to drain the funds from the staking contract by just using the transferFrom() function repeated times.

The example transaction:

https://bscscan.com/tx/0x40e69064…e01d3c

Stolen funds were deposited into Tornado Cash mixer:

https://explorer.bitquery.io/bsc/address/0x3d98aee2…24dacc/outflow

Case & protocol details

Classification Yield Aggregator
Protocol Type Exploit/Other
Affected asset / contract EHB
Official Website earnhub.fi/
Protocol Twitter/X @earnhubBSC

Evidence & learning

Sources and on-chain records

Practice this exploit pattern safely

Work through hands-on labs covering real exploit mechanics, review techniques, and defensive patterns.