# Due to loss of precision, targetVotes may not reach

WardenPledge checks pledged amount against targetVotes, but Curve BoostV2 truncates slope so actual bias received is less, letting receiver fall short of targetVotes.

- Payout: Audit contest
- Severity: medium
- Program: Paladin
- Found by: cccz
- Disclosed: 2023-01-06
- Write-up quality: 6/10
- Original: https://code4rena.com/reports/2022-10-paladin#m-01
- Library page: https://bugbountylibrary.com/r/c4%3A2022-10-paladin%3AM-01
- Tags: area:web3 domain:web3 impact:integrity kind:contest platform:code4rena sev:medium tech:evm tech:solidity vuln:accounting-error vuln:precision-loss

**Target:** WardenPledge.sol pledge function interacting with Curve BoostV2
**Root cause:** The pledge check compares the raw pledged amount to targetVotes, but BoostV2 computes bias = (amount/boostDuration)*boostDuration, truncating the remainder so the receiver's actual delegated votes are less than amount.
**Steps:**
1. User calls pledge with an amount such that adjusted_balance_of(receiver) + amount <= targetVotes passes the check.
2. WardenPledge calls delegationBoost.boost(receiver, amount, endTimestamp, user).
3. BoostV2 computes `slope = amount / boostDuration` then `bias = slope * boostDuration`, losing the division remainder.
4. Receiver's adjusted_balance_of returns bias-based value, which is less than amount, so the balance never reaches targetVotes.
**How found:** Reading the pledge check against Curve BoostV2's slope/bias math and noticing integer division truncation makes bias < amount.
**Insight:** When a contract validates against a value computed by an external contract, replicate that contract's exact arithmetic (integer division truncation) in the check rather than using the nominal input amount.

