# NFTs can be transferred even if StakeAtRisk remains, so the user's win cannot be recorded on the chain due to underflow, and can recover past losses that can't be recovered (steal protocol's token)

AI Arena Fighter NFTs with residual StakeAtRisk can be unstaked and sold; new owner's win reclaims stake against wrong amountLost, underflowing or stealing protocol NRN.

- Payout: Contest reward
- Severity: medium
- Program: AI Arena
- Credited: klau5
- Disclosed: 2024-05-14
- Write-up quality: 7/10
- Original: https://github.com/code-423n4/2024-02-ai-arena-findings/issues/137
- Library page: https://bugbountylibrary.com/r/c4%3A2024-02-ai-arena%3AM-06
- Tags: domain:web3 impact:funds-loss impact:integrity kind:contest platform:code4rena sev:medium tech:evm tech:solidity technique:chained technique:source-review vuln:access-control vuln:accounting-error vuln:business-logic

**Target:** RankedBattle / StakeAtRisk staking contracts
**Root cause:** unstakeNRN unlocks the Fighter NFT when amountStaked hits 0 without checking remaining StakeAtRisk, and reclaimNRN debits amountLost[fighterOwner] keyed to the current owner rather than the NFT's original loser.
**Steps:**
1. Seller stakes NRN on tokenId, loses a battle so StakeAtRisk[round][tokenId] > 0.
2. Seller calls `unstakeNRN(amountStaked[tokenId], tokenId)`; amountStaked becomes 0 and `updateFighterStaking(tokenId,false)` unlocks NFT despite StakeAtRisk.
3. Seller transfers NFT to buyer via `transferFrom`.
4. Buyer (game server) calls `updateBattleRecord(tokenId,50,0,1500,true)` for a win; `_addResultPoints` calls `reclaimNRN(curStakeAtRisk, tokenId, buyer)` which executes `amountLost[buyer] -= nrnToReclaim` and reverts with Panic(0x11) underflow.
5. Variant: buyer with prior round losses (amountLost>0) buys NFT with StakeAtRisk, wins, and reclaims past-round losses that should be unrecoverable.
**How found:** Code reading of unstakeNRN's unlock condition (amountStaked==0) versus StakeAtRisk bookkeeping, noticing amountLost is keyed by owner address not tokenId, then reasoning about NFT transfer changing the owner mid-round.
**Exploitation:** Attacker accumulates amountLost in a past round (unrecoverable loss), then buys a cheap Fighter NFT carrying StakeAtRisk in the current round from the secondary market, wins battles with it to trigger reclaimNRN, which decrements the attacker's stale amountLost and transfers NRN out of StakeAtRisk, recovering losses that should be permanently lost.
**Escalation:** Chaining across rounds: past-round amountLost persists globally and is offset by current-round StakeAtRisk of a purchased NFT, converting unrecoverable losses into recovered protocol tokens.
**Insight:** When loss/risk accounting is keyed by owner address but the asset (NFT) is transferable, check whether transferring the asset lets a new owner's balance absorb another token's risk; also check unlock conditions that ignore residual risk state.
