Summary
Self-hosted Metis v7.0.17 ignores the appended PumpSwap
Pool::virtual_quote_reserves field when quoting an ExactIn SOL-to-token swap.
The self-hosted output is exactly reproduced by pricing against the raw quote
vault. The public Jupiter output is exactly reproduced by PumpSwap's required
effective reserve:
effective_quote_reserves =
pool_quote_token_account.amount + Pool::virtual_quote_reserves
This is a deterministic calculation issue rather than route selection or normal
quote staleness.
Environment
Architecture: x86_64
Metis: metis-binary 7.0.17 b1541702f205071fc532f269a4f4c4699a700406
Binary SHA-256: 3d01df17075d79cd6d5b3f1d333c30e906ada9999e2491545e15f24da55f60fb
The executable is byte-identical to the official v7.0.17 release asset.
Reproduction
QUERY='inputMint=So11111111111111111111111111111111111111112&outputMint=FsFVoqydZ8iHupxPz7VS6s5c9HJmsikyaQkdunCHpump&amount=100000000&swapMode=ExactIn&slippageBps=50&onlyDirectRoutes=true&restrictI
ntermediateTokens=true'
curl -s "http://127.0.0.1:8080/quote?${QUERY}" |
jq '{contextSlot,outAmount,otherAmountThreshold,routePlan}'
curl -s "https://lite-api.jup.ag/swap/v1/quote?${QUERY}" |
jq '{contextSlot,outAmount,otherAmountThreshold,routePlan}'
Both responses selected exactly one direct route through the same pool:
ammKey: 2eF6z1oJfr6WTHecH5QxHLEN4m3iQ6x3Dq6bQguxEyjM
label: Pump.fun Amm
Captured responses:
Self-hosted Metis v7.0.17:
contextSlot: 440268500
outAmount: 825974682488
otherAmountThreshold: 821844809076
Public Jupiter:
contextSlot: 440268500
outAmount: 589999391290
otherAmountThreshold: 587049394334
The live amounts will naturally change as the pool trades. The exact captured
state and deterministic reconstruction are provided below.
Exact on-chain reconstruction
Pool:
2eF6z1oJfr6WTHecH5QxHLEN4m3iQ6x3Dq6bQguxEyjM
The latest successful pool transaction before contextSlot=440268500 was at
slot 440268476:
https://explorer.solana.com/tx/2r67PrsGL3w2UgjADLCY7YTaGcWk3D4K4uFsqBV4VL7Rsh6wKnTP36gwhDJQHqfV9TzqhKCryokYQwJbR9eJjvND
Its post-transaction state was:
base reserve B: 367685895388406
raw quote-vault reserve Q: 43867055758
virtual_quote_reserves V: 17584505358
effective quote reserve Q+V: 61451561116
gross ExactIn amount: 100000000
fee-adjusted CPMM input x: 98765429
x=98765429 follows PumpSwap SDK v1.19.0 fee and conservative rounding logic.
Self-hosted result: raw vault only
floor(B * x / (Q + x))
= floor(
367685895388406 * 98765429
/ (43867055758 + 98765429)
)
= 825974682488
This exactly equals the self-hosted Metis outAmount.
Required PumpSwap result: effective reserve
floor(B * x / (Q + V + x))
= floor(
367685895388406 * 98765429
/ (43867055758 + 17584505358 + 98765429)
)
= 589999391290
This exactly equals the public Jupiter outAmount.
Therefore:
self_hosted / correct - 1
= 825974682488 / 589999391290 - 1
= 39.995853331654%
The exact integer equality shows that self-hosted v7.0.17 uses Q, while the
required calculation uses Q + V.
Expected behavior
Metis should decode the appended signed Pool::virtual_quote_reserves field and
use the effective quote reserve required by the current PumpSwap specification.
Expected output for the captured state:
Actual behavior
Self-hosted Metis prices against the raw quote vault and returns:
This is a deterministic 39.995853% overquote.
Impact
At slippageBps=50, Metis produces the following minimum output:
But the correct quote for the captured state is:
A transaction built from the self-hosted quote therefore has an unattainable
minimum output and can fail in the Jupiter JUP6... program with error 6001
(SlippageToleranceExceeded).
Retrying a fresh quote from the same binary does not resolve the issue because
the same reserve calculation is repeated. Increasing slippage enough to cover
this difference is not a safe workaround.
Relevant chronology
Official PumpSwap formula:
https://github.com/pump-fun/pump-public-docs/blob/main/docs/PUMP_SWAP_README.md#quoting-effective-quote-reserves
Official PumpSwap SDK v1.19.0 buy calculation:
https://unpkg.com/@pump-fun/pump-swap-sdk@1.19.0/src/sdk/buy.ts
Jupiter error reference:
https://developers.jup.ag/docs/swap/v1/common-errors
Requested fix
Please:
- Decode the appended signed
Pool::virtual_quote_reserves field.
- Use
raw_quote_vault + virtual_quote_reserves in PumpSwap quote calculations.
- Use checked signed arithmetic and reject invalid effective reserves.
- Audit both buy and sell quote paths.
- Add a regression test with a non-zero virtual reserve.
- Publish an updated self-hosted Metis binary containing the fix.
A useful regression test would compare quote and simulation results for the pool
above and verify that:
- a non-zero virtual reserve affects the quote;
- the result does not equal the legacy raw-vault-only calculation;
- pools with
virtual_quote_reserves == 0 remain unchanged.
Summary
Self-hosted Metis v7.0.17 ignores the appended PumpSwap
Pool::virtual_quote_reservesfield when quoting an ExactIn SOL-to-token swap.The self-hosted output is exactly reproduced by pricing against the raw quote
vault. The public Jupiter output is exactly reproduced by PumpSwap's required
effective reserve:
This is a deterministic calculation issue rather than route selection or normal
quote staleness.
Environment
The executable is byte-identical to the official v7.0.17 release asset.
Reproduction
Both responses selected exactly one direct route through the same pool:
Captured responses:
The live amounts will naturally change as the pool trades. The exact captured
state and deterministic reconstruction are provided below.
Exact on-chain reconstruction
Pool:
The latest successful pool transaction before
contextSlot=440268500was atslot
440268476:https://explorer.solana.com/tx/2r67PrsGL3w2UgjADLCY7YTaGcWk3D4K4uFsqBV4VL7Rsh6wKnTP36gwhDJQHqfV9TzqhKCryokYQwJbR9eJjvND
Its post-transaction state was:
x=98765429follows PumpSwap SDK v1.19.0 fee and conservative rounding logic.Self-hosted result: raw vault only
This exactly equals the self-hosted Metis
outAmount.Required PumpSwap result: effective reserve
This exactly equals the public Jupiter
outAmount.Therefore:
The exact integer equality shows that self-hosted v7.0.17 uses
Q, while therequired calculation uses
Q + V.Expected behavior
Metis should decode the appended signed
Pool::virtual_quote_reservesfield anduse the effective quote reserve required by the current PumpSwap specification.
Expected output for the captured state:
Actual behavior
Self-hosted Metis prices against the raw quote vault and returns:
This is a deterministic
39.995853%overquote.Impact
At
slippageBps=50, Metis produces the following minimum output:But the correct quote for the captured state is:
A transaction built from the self-hosted quote therefore has an unattainable
minimum output and can fail in the Jupiter
JUP6...program with error6001(
SlippageToleranceExceeded).Retrying a fresh quote from the same binary does not resolve the issue because
the same reserve calculation is repeated. Increasing slippage enough to cover
this difference is not a safe workaround.
Relevant chronology
https://github.com/jup-ag/metis-binary/releases/tag/v7.0.17
Pool::virtual_quote_reservesand the effective-reserve formulaon 2026-07-15:
pump-fun/pump-public-docs@2c22246
https://explorer.solana.com/tx/3ua1Qkxth2okpv8Sg8gGzNDobVhcuJC3Y78JTBvBaB2b2MhxP9unPESqrfZY5QeYoUHLWmWoyNJbUZ8ptiZoL9rv
Official PumpSwap formula:
https://github.com/pump-fun/pump-public-docs/blob/main/docs/PUMP_SWAP_README.md#quoting-effective-quote-reserves
Official PumpSwap SDK v1.19.0 buy calculation:
https://unpkg.com/@pump-fun/pump-swap-sdk@1.19.0/src/sdk/buy.ts
Jupiter error reference:
https://developers.jup.ag/docs/swap/v1/common-errors
Requested fix
Please:
Pool::virtual_quote_reservesfield.raw_quote_vault + virtual_quote_reservesin PumpSwap quote calculations.A useful regression test would compare quote and simulation results for the pool
above and verify that:
virtual_quote_reserves == 0remain unchanged.