EarnHub Hack
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
Evidence & learning
Sources and on-chain records
- report Report earnhub.medium.com
- report Report twitter.com
- report Report twitter.com
Practice this exploit pattern safely
Work through hands-on labs covering real exploit mechanics, review techniques, and defensive patterns.