# veCVXStrategy.manualRebalance has wrong logic

veCVXStrategy.manualRebalance compares a percentage ratio against an absolute CVX token amount, breaking rebalancing and locking nearly all funds.

- Payout: Audit contest
- Severity: high
- Program: BadgerDAO
- Found by: cmichel
- Disclosed: 2021-11-05
- Write-up quality: 6/10
- Original: https://github.com/code-423n4/2021-09-bvecvx-findings/issues/47
- Library page: https://bugbountylibrary.com/r/c4%3A2021-09-bvecvx%3AH-01
- Tags: area:web3 domain:web3 impact:funds-loss kind:contest platform:code4rena sev:high tech:solidity technique:source-review vuln:accounting-error vuln:business-logic

**Target:** veCVXStrategy Solidity contract (manualRebalance)
**Root cause:** currentLockRatio is an 18-decimal percentage (max 1e18) while newLockRatio is an unbounded absolute CVX token amount, so the comparison and subtraction mix incompatible units.
**Steps:**
1. Read manualRebalance: currentLockRatio = balanceInLock.mul(10**18).div(totalCVXBalance) (percentage, max 1e18)
2. newLockRatio = totalCVXBalance.mul(toLock).div(MAX_BPS) (absolute CVX amount, unbounded)
3. Observe `if (newLockRatio <= currentLockRatio)` compares percentage vs token amount
4. With high totalCVXBalance, newLockRatio dwarfs currentLockRatio, so cvxToLock = newLockRatio.sub(currentLockRatio) locks nearly everything
**How found:** Code review of the rebalance math: noticed the two 'ratios' are computed with different scaling (10**18 percentage vs MAX_BPS-scaled token amount) and are therefore not comparable.
**Insight:** When two variables are both named 'ratio', verify their scaling and units independently; a percentage scaled by 1e18 and an amount scaled by MAX_BPS will silently diverge as balances grow.

