# Transmuter::queryGraph incorrectly rounds up which will lead to broken accounting and locked funds in an alchemist

Transmuter.queryGraph rounds up earmarked amounts by 1, breaking WeightIncrement's increment<=total invariant and reverting all AlchemistV3 transactions, locking funds.

- Payout: Contest reward
- Severity: medium
- Program: Alchemix
- Credited: gesha17
- Disclosed: 2025-07-15
- Write-up quality: 7/10
- Original: https://cdn.cantina.xyz/reports/cantina_competition_alchemix_may2025.pdf#3.2.17
- Library page: https://bugbountylibrary.com/r/cantina%3Aalchemix_may2025%3A3.2.17
- Tags: domain:web3 impact:dos impact:funds-loss kind:contest platform:cantina sev:medium tech:evm tech:solidity technique:source-review vuln:accounting-error vuln:dos

**Target:** AlchemistV3 / Transmuter queryGraph earmark accounting
**Root cause:** queryGraph returns (queried/BLOCK_SCALING_FACTOR)+1, always rounding up instead of down, so cumulativeEarmarked can exceed totalDebt over time.
**Steps:**
1. Deposit 100e18 collateral, mint 50e18 debt via `alchemist.mint(tokenId, 50e18, ...)`
2. Create redemption of 50e18 via `transmuterLogic.createRedemption(50e18)`
3. `vm.roll(block.number+1)` then call `alchemist.poke(tokenId)` — queryGraph returns 9512937595130 instead of 9512937595129
4. `vm.roll(block.number+5_256_000)` then call `alchemist.repay(25e18, tokenId)`
5. WeightIncrement require(increment <= totalDebt - cumulativeEarmarked) fails: 49999990487062404871 <= 49999990487062404870 is false, revert
**How found:** Code review of queryGraph's `+1` rounding combined with WeightIncrement's `require(increment <= total)` invariant; traced that cumulativeEarmarked accumulates rounded-up values until it exceeds totalDebt.
**Insight:** When a view function feeds an accounting invariant, check rounding direction against the invariant's boundary: a `+1` ceil in a graph query can push a cumulative counter past its cap and brick every state-changing call that touches _earmark.
