# maxSellPercent will be broken when a vesting is delisted after a seller has claimed additional steps

Unlisting a vesting after claiming steps refunds full sold amount, resetting sold counter and letting seller exceed maxSellPercent sell limit.

- Payout: Contest reward
- Severity: medium
- Program: SecondSwap
- Credited: BenRai
- Disclosed: 2025-02-18
- Write-up quality: 6/10
- Original: https://code4rena.com/reports/2024-12-secondswap#m-20
- Library page: https://bugbountylibrary.com/r/c4%3A2024-12-secondswap%3AM-20
- Tags: domain:web3 impact:integrity kind:contest platform:code4rena sev:medium tech:solidity vuln:accounting-error vuln:business-logic

**Target:** SecondSwap_VestingManager unlistVesting / listVesting accounting
**Root cause:** unlistVesting subtracts the full refunded amount from allocations[seller][plan].sold without accounting for steps the seller claimed while the listing was active, so the sold counter no longer reflects tokens already unlocked/claimed.
**Steps:**
1. Alice has 100-token allocation, 10 steps, releaseRate 10/step, maxSellPercent 50%.
2. She lists 50 tokens: sold=50, releaseRate drops to 5/step, tokens moved to VestingManager.
3. After 5 steps she claims 5*5=25 tokens; remaining allocation 25.
4. No buyer; she calls unlistVesting(seller, plan, 50): `allocations[seller][plan].sold -= 50` → sold=0, 50 tokens refunded.
5. Now sellLimit computed from current allocation (100) * 50% = 50, but only ~25 should be sellable given 5 steps unlocked; she can list/sell all locked tokens.
**How found:** Code review of unlistVesting vs listVesting accounting: noticed sold is decremented by full refunded amount while releaseRate/claimed steps changed during listing lifetime, breaking the maxSellPercent invariant.
**Exploitation:** Seller lists, waits for steps to unlock and claims, then unlists to reset the sold counter, then re-lists up to maxSellPercent of the full allocation, exceeding the intended locked-token sell cap.
**Insight:** When a protocol tracks a 'sold/used' counter that is decremented on refund/cancel, check whether state (claimed steps, accrued yield, release rate) mutated during the listing's lifetime makes the symmetric decrement incorrect.
