# Division in Bonding.sol._openTradingOnUniswap() results in an incorrect lpSupply, higher vaultSupply, and dust AgentTokens getting locked in FPair

Bonding._openTradingOnUniswap divides tokenBalance by 10**decimals then AgentToken re-multiplies, truncating lpSupply and inflating vaultSupply, locking dust AgentTokens in FPair.

- Payout: Contest reward
- Severity: medium
- Program: Virtuals Protocol
- Credited: BowTiedOriole
- Disclosed: 2025-08-04
- Write-up quality: 6/10
- Original: https://code4rena.com/reports/2025-04-virtuals-protocol#m-05
- Library page: https://bugbountylibrary.com/r/c4%3A2025-04-virtuals-protocol%3AM-05
- Tags: domain:web3 impact:funds-loss kind:contest platform:code4rena sev:medium tech:evm tech:solidity technique:source-review vuln:accounting-error vuln:precision-loss

**Target:** Bonding.sol / AgentFactoryV3 / AgentToken graduation flow
**Root cause:** lpSupply is computed as tokenBalance / 10**decimals (truncating remainder) and later multiplied back by 10**decimals in AgentToken.initialize, yielding a smaller lpSupply; vaultSupply = totalSupply - lpSupply is correspondingly too large.
**Steps:**
1. Fork Base at block 29519750.
2. Alice calls `bonding.launch(...)` with 45000 ether to graduate the agent.
3. Bob calls `bonding.buy(0.5 ether, token)` to trigger graduation.
4. Read `tokenInfo(token)` to get agentToken address.
5. Compare `IERC20(agentToken).balanceOf(pair)` vs `IERC20(token).balanceOf(alice)+balanceOf(bob)`; they differ due to truncated lpSupply.
**How found:** Code reading of the graduation path: noticed the divide-by-10**decimals in Bonding followed by multiply-by-10**decimals in AgentToken.initialize, recognized the truncation/round-trip mismatch, and confirmed with a fork PoC.
**Exploitation:** Not an attack; the rounding error occurs naturally on graduation, leaving a small amount of AgentTokens permanently stuck in the FPair contract and over-crediting vaultSupply.
**Insight:** When a value is scaled down and later scaled back up across contract boundaries, check for truncation on the downscale that inflates any derived subtraction (here vaultSupply = totalSupply - lpSupply); pass raw wei instead of round-tripping through decimals.
