# Division difference can result in a revert when claiming treasury yield and excess rewards to some users

Inconsistent rounding order in ysTotal computation makes balanceOfYsCvgAt exceed totalSuppliesTracking, letting some users over-claim treasury yield and causing last claimers' withdrawals to revert.

- Payout: Contest reward
- Severity: medium
- Program: Convergence
- Credited: cergyk
- Disclosed: 2023-11-06
- Write-up quality: 6/10
- Original: https://github.com/sherlock-audit/2023-11-convergence-judging/issues/190
- Library page: https://bugbountylibrary.com/r/sherlock%3A2023-11-convergence%3AM-6
- Tags: domain:web3 impact:dos impact:funds-loss kind:contest platform:sherlock sev:medium tech:solidity technique:source-review vuln:accounting-error vuln:precision-loss vuln:reward-distribution

**Target:** LockingPositionService.sol (ysTotal / balanceOfYsCvgAt share accounting)
**Root cause:** ysTotal is computed as (lockDuration * ((amount*ysPercentage)/MAX_PERCENTAGE))/MAX_LOCK when tracking totalSupplies, but as (((endCycle-startCycle)*amount*ysPercentage)/MAX_PERCENTAGE)/MAX_LOCK in balanceOfYsCvgAt; the different division ordering rounds differently, so per-user balance can exceed the tracked total.
**Steps:**
1. Note mintPosition/increaseLockAmount/increaseLockTimeAndAmount compute `cvgLockAmount=(amount*ysPercentage)/MAX_PERCENTAGE` then `ysTotal=(lockDuration*cvgLockAmount)/MAX_LOCK` and add to totalSuppliesTracking.
2. Note balanceOfYsCvgAt computes `ysTotal=(((endCycle-startCycle)*amount*ysPercentage)/MAX_PERCENTAGE)/MAX_LOCK`.
3. Pick values e.g. startCycle=357,endCycle=420,amount=2,ysPercentage=80: tracking gives (2*80)/100=1 then (63*1)/96=0; balanceOfYsCvgAt gives (63*2*80)/100/96=1.
4. Repeat with increaseLockAmount using small amounts to accumulate the per-user delta above the tracked total.
5. At reward cycle end, earlier claimers withdraw the over-credited shares; the last claimer's claim reverts for insufficient reward balance.
**How found:** Code reading comparing the two ysTotal formulas across mintPosition/increaseLockAmount/_ysCvgCheckpoint versus balanceOfYsCvgAt, spotting the different division ordering and testing small values to show rounding divergence.
**Exploitation:** Attacker locks small non-100-divisible amounts repeatedly via increaseLockAmount to inflate their balanceOfYsCvgAt relative to totalSuppliesTracking, then claims treasury yield/excess rewards before other users, leaving insufficient funds so the final claimers revert.
**Escalation:** Accumulating many small increaseLockAmount calls widens the tracked-vs-balance delta; related report #132 shows arbitrary reward theft when attacker is sole YS allocator.
**Insight:** When the same derived quantity is computed in multiple places, diff the exact order of multiply/divide operations—Solidity truncation makes reordered divisions disagree, and any per-user view that can exceed an aggregate counter enables over-claim/drain of a shared pool.
