LunaFI Hack
What happened
On May 22, 2023, an attacker exploited the reward logic of LunaFi, a betting platform on Polygon. Verichains put the loss at about $36,000. LunaFi's vLFI staking contract let claimRewards() pay out with no time lock on the staked balance. Rewards were not tied to how long a stake had been held, so the same vLFI could be moved to a new address and claim again.
The attack ran as a campaign of transactions rather than a single one. Between about 21:05 and 22:04 UTC the attacker's wallet sent dozens of run() calls to its attack contract, broken up by restake() and swap() calls. In one of them, 0xa0480d0f...6243, the contract created 50 new contracts and passed a single balance of about 5,740 vLFI from one to the next, pulling 30,137.5 LFI of rewards out of the vLFI contract at every hop (about 1.5 million LFI in that transaction alone). Minutes later the attacker re-staked 6,027,460 LFI and then 12,233,090 LFI into the vLFI contract, growing the balance that could claim, and at 21:47 UTC swapped 80,696,700 LFI for about 18.9 WETH on QuickSwap. The live figure of about 1,500,000 LFI matches only the first mapped transaction; the campaign's full LFI total was not tallied. According to Verichains' weekly digest, LunaFi acknowledged the hack, took full responsibility, and was working with Hacken on next steps.
Attacker: 0x11576cb3d8d6328cf319e85b10e09a228e84a8de
Attack contract: 0x43623b96936e854f8d85f893011f22ac91e58164
Example claim transaction: 0xa0480d0f7c8d8bf898cadde954e773ddc3740f1ffa31cdd98fe4c5f5d8266243
Re-stake transactions: 0xae1905de5eaa9603ca526d83d16f3397b90fe5b21990cff92d936106690f882a, 0x8e4b4be1c93071dd5c37f69ee5a285efc2abdbce779b8895413102c82b8ebf8a
Swap transaction: 0x76045837b25e3c5707b88f3df0660b91c31795c7b3f8dee8b67db26e7193a685
How it happened
- At 20:36 UTC the attacker bought LFI through QuickSwap, deployed attack contract
0x4362...8164, and called itsinitfunction at 21:03 UTC. - From 21:05 UTC the attacker called the contract's
run()function again and again. In0xa0480d0f...6243(21:40:17 UTC) the contract created 50 new contracts and moved one balance of 5,739.99 vLFI from each to the next. At every hop a reward claim ran against the vLFI contract and 30,137.5 LFI went to the attack contract, about 1,506,876 LFI in that transaction, because the contract never checked how long that balance had been staked. - The attacker then called
restake()to put the harvested LFI back into the vLFI contract: 6,027,460 LFI at 21:40:35 UTC (0xae1905de...882a) and 12,233,090 LFI at 21:43:27 UTC (0x8e4b4be1...bf8a). A larger vLFI balance meant larger claims in the followingrun()calls. - At 21:47:07 UTC (
0x76045837...a685) the attack contract sold 80,696,700 LFI into the QuickSwap LFI/WETH pair for about 18.9 WETH. Morerun(),swap()and token-withdrawal calls followed until 22:14 UTC, with two more withdrawals the next morning.
Protocol details
Security review history
- Hacken View report
Evidence
- report @AnciliaInc incident report twitter.com
- transaction Polygonscan transaction 0xa0480d0f...6243 polygonscan.com
- transaction Polygonscan transaction list for LunaFi Exploiter 0x11576cb3...a8de (pages 1-2) polygonscan.com
- transaction Polygonscan transaction 0xae1905de...882a (restake) polygonscan.com
- transaction Polygonscan transaction 0x8e4b4be1...bf8a (restake) polygonscan.com
- transaction Polygonscan transaction 0x76045837...a685 (swap) polygonscan.com
- address polygonscan.com address 0x1157…a8de polygonscan.com
- address polygonscan.com address 0x4362…8164 polygonscan.com
- analysis DeFiLlama defillama.com
- analysis Verichains Weekly Security Digest blog.verichains.io
Build your security review skills
Work through hands-on labs covering real exploit mechanics, review techniques, and defensive patterns.