Root Cause
AlpsCon's newer reward hub contracts use a MasterChef-style accRewardPerShare accounting model. When a staking position was migrated from an older hub, the new contract set the user's rewardDebt to zero instead of initialising it to amount × accRewardPerShare / PRECISION. This meant every migrated position was immediately owed all rewards that had accumulated since the hub's inception — a classic checkpoint-on-deposit bug.
Separately, the contract's EIP-7702 whitelist (used to gate certain privileged calls) still contained the Hardhat default account address (0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266) — a well-known key distributed in every Hardhat installation — which had been on the whitelist for approximately 14 months.
// Vulnerable MasterChef-style migration (reconstructed from Verichains analysis)
function migrateFromOldHub(address user, uint256 amount) external onlyOldHub {
UserInfo storage info = userInfo[user];
info.amount += amount;
// BUG: should be: info.rewardDebt += amount * accRewardPerShare / PRECISION;
// info.rewardDebt is left at 0 (or unchanged from prior deposits)
}
function harvest() external {
UserInfo storage info = userInfo[msg.sender];
uint256 pending =
info.amount * accRewardPerShare / PRECISION - info.rewardDebt;
// 'pending' is inflated for migrated positions
_safeReward(msg.sender, pending);
info.rewardDebt = info.amount * accRewardPerShare / PRECISION;
}
Attack Steps
| # | Action |
|---|---|
| 1 | Attacker derives Hardhat default private key (publicly known) |
| 2 | Signs EIP-7702 authorization to pass the whitelist gate |
| 3 | Flash-borrows tokens; triggers migration from old hub → new hub |
| 4 | New position's rewardDebt initialised to 0 |
| 5 | Calls harvest() → claims all rewards accumulated since hub deployment |
| 6 | Repays flash loan; nets ~$152,295 USDC |
Impact
- ~$152,295 USDC drained from AlpsCon AI Trade Hub reward pool on BNB Chain
- Two separate, independently exploitable vulnerabilities (whitelist + accounting)
- Incident dated October 18, 2026 (SlowMist / Verichains)
Lessons for Auditors
- Always set rewardDebt on every state change that affects amount. In MasterChef forks,
rewardDebtmust be updated atomically with every deposit, withdrawal, and migration:rewardDebt = amount * accRewardPerShare / PRECISION. Missing this on migration paths is one of the most common DeFi yield-farming bugs. - Purge test keys from production whitelists before deployment. The Hardhat default accounts (
0xf39F...,0x7099..., etc.) have publicly known private keys. Their presence in any production access-control list is a critical vulnerability. Run a pre-deployment check:grep -r '0xf39Fd6e51' contracts/should return zero results in production builds. - EIP-7702 whitelists require periodic rotation audits. EIP-7702 authorization lists can accumulate stale entries. Implement an expiry mechanism or a regular (quarterly) review to prune addresses that no longer need privileged access.
- Two low-severity findings can combine into a high-severity exploit. Neither bug alone may be rated critical, but the whitelist bypass enabling the accounting exploit produced a significant loss. Auditors should model compound exploit paths.