Level Finance Referral Double-Claim
Level Finance on BNB Chain lost $1.1M because LevelReferralControllerV2 paid out referral rewards without marking the epoch claimed, allowing repeated claims.
- Date
- Victim
- Level Finance
- Chain(s)
- Status
- Funds Stolen
On May 1, 2023, the BNB Chain perpetuals protocol Level Finance lost approximately $1.1 million (214,000 LVL tokens) through a double-claim bug in its LevelReferralControllerV2 contract. The referral-reward claim function paid out before marking the epoch as claimed, letting an attacker claim the same epoch's rewards repeatedly in a loop.
What happened
Level Finance ran a referral program: users earned LVL token rewards based on referred trading volume, claimable per epoch. The claimMultiple function in LevelReferralControllerV2 processed these claims.
The bug was a textbook checks-effects-interactions violation specific to claim accounting:
- The claim function calculated the user's owed rewards for an epoch.
- Transferred the LVL tokens to the user.
- Then updated the bookkeeping to mark that epoch as claimed.
Because the "mark as claimed" step happened after the payout — and because the function could be called repeatedly within the same transaction context before state settled — the attacker could claim the same epoch's rewards many times before the contract recorded any of them as claimed.
The attacker looped the claim, extracting 214,000 LVL (~$1.1M) against a single epoch's legitimate entitlement, then dumped the LVL into liquidity.
Aftermath
- Level Finance confirmed the exploit and identified the buggy claim ordering as the sole root cause.
- The team paused the referral contract and shipped a fixed version with claim-state updated before payout.
- LVL token took a price hit from the dump; the protocol continued operating with the patched contract.
Why it matters
Level Finance is a small-dollar but pedagogically perfect instance of the single oldest rule in smart-contract security: checks-effects-interactions — update your state before you make the external call / payout, never after.
The DAO taught this in 2016. It is the first rule in every Solidity security guide. And yet it keeps shipping — here in a reward-claim function rather than a withdrawal function, which is exactly why it slipped through: developers internalise "apply CEI to withdrawals" but don't always recognise that a referral-reward claim is structurally a withdrawal and needs the same discipline.
The catalogue is full of this generalisation failure — the core bug class is well-known, but it reappears every time it's wearing slightly different clothes:
- Reentrancy in deposits (Grim), not just withdrawals.
- Solvency checks missing in emergency functions (Platypus), not just normal-path functions.
- CEI violated in reward claims (Level Finance), not just token transfers.
The lesson Level Finance crystallises: a vulnerability class is not "handled" because the obvious instances of it are handled. Every function that moves value is subject to the same rules, and the bugs cluster precisely in the functions developers don't think of as value-moving — periphery, rewards, migration, emergency, claim. Those are the functions written fastest and reviewed least, and the catalogue shows, over and over, that they are where the next instance of the oldest bugs will appear.
Sources & on-chain evidence
- [01]halborn.comhttps://www.halborn.com/blog/post/explained-the-level-finance-hack-may-2023
- [02]beincrypto.comhttps://beincrypto.com/decentralized-perpetual-market-level-finance-hacked-1-1m/
- [03]rekt.newshttps://rekt.news/level-finance-rekt