# Incorrect Spot Price

Notional's Leveraged Vaults _calcSpotPrice diverges from Balancer SDK math in five ways, so manipulated-pool detection can be bypassed and trades execute against a manipulated pool.

- Payout: Contest reward
- Severity: high
- Program: Notional
- Credited: xiaoming90
- Disclosed: 2023-10-09
- Write-up quality: 7/10
- Original: https://github.com/sherlock-audit/2023-10-notional-judging/issues/81
- Library page: https://bugbountylibrary.com/r/sherlock%3A2023-10-notional%3AH-3
- Tags: domain:web3 impact:funds-loss kind:contest platform:sherlock sev:high tech:evm tech:solidity technique:source-review vuln:accounting-error vuln:oracle-manipulation

**Target:** Balancer composable stable pool spot price oracle in Leveraged Vaults
**Root cause:** _calcSpotPrice mis-implements the Balancer SDK formula: subtracts b.y/b.x instead of adding, computes b wrong for S=0, ignores multi-token S, scales amp by A*2 instead of A*2^n, and omits the n^(n-1) amp downscale.
**Steps:**
1. Read BalancerSpotPrice._calculateStableMathSpotPrice calling StableMath._calcSpotPrice with scaledPrimary and secondary balances
2. Compare against Balancer SDK _poolDerivatives/stableMath spot price formula
3. Note numerator/denominator use `.sub(b.mulDown(balanceY))` and `.sub(b.mulDown(balanceX))` where SDK adds b.y and b.x
4. Note `b = Math.mul(invariant, a).sub(invariant)` assumes S=0, but composable pools have up to 5 tokens so S = sum of other balances
5. Note `a = (amplificationParameter * 2) / _AMP_PRECISION` vs SDK's A*2^n, and missing n^(n-1) downscale
6. Conclude spot price is wrong, so manipulation check in reinvest-rewards path can pass on a manipulated pool
**How found:** Code-reading comparison of the vault's StableMath._calcSpotPrice against the Balancer SDK's _poolDerivatives implementation, spotting five formula discrepancies (sign of b.y/b.x, b definition, S for multi-token pools, amp scaling by 2 vs 2^n, missing n^(n-1) downscale).
**Exploitation:** Not directly weaponized in the text; the flawed spot price is used as a manipulation guard before vault actions like reinvest rewards, so an attacker who manipulates the Balancer pool could pass the check and have the trade execute against the manipulated pool, causing asset loss.
**Insight:** When a protocol reimplements an external AMM's math (Balancer StableMath), diff it line-by-line against the SDK and check assumptions like token count n and amp scaling—two-token simplifications silently break on composable pools with up to 5 tokens.
