fix(solana): confirm native SOL after a swap, and stop the circular USD check - #418
Merged
Merged
Conversation
…SD check
Two defects from one swap into SOL: the balance never updated, and a wildly
wrong received amount displayed a perfectly plausible dollar figure.
## 1. Swapping INTO native SOL had no direct confirmation
index.ts post-swap reconcile matched destinations with:
/^(solana:[^/]+)\/(?:token|spl):([1-9A-HJ-NP-Za-km-z]{32,44})$/
That is SPL-only. Native SOL is `solana:<net>/slip44:501` — no mint — so it hit
`continue` and got no direct read at all, falling back entirely to Pioneer's
portfolio indexer, which lags a completed swap. The dashboard kept showing the
pre-swap balance (0.00999 SOL after receiving ~0.23) across refreshes with
nothing to explain why. The comment right above that loop says a completed SPL
swap "can beat Pioneer's portfolio indexer by several seconds" — native SOL has
the same problem and was simply never covered.
Adds getSolanaNativeBalance() (getBalance RPC, 9 decimals — SOL is not a mint
and has no on-chain decimals field) and a native branch in the reconcile loop.
The entry match folds case deliberately: Pioneer returns Solana network ids
LOWERCASED (`solana:5eykt4usfv8...`) while the vault derives them mixed-case
(`solana:5eykt4UsFv8...`). A byte-exact compare finds nothing and silently drops
the fresh balance. Both spellings are in one getBalances log.
Following the file's own convention, an RPC that does not answer throws rather
than reporting 0 — a failed lookup is not an empty account.
## 2. The USD under "You received" could not disagree with the amount
toPriceUsd falls back to deriving the destination price from the quote ratio:
derived = (inAmt / outAmt) * fromPriceUsd
and the panel renders `outAmt * toPriceUsd`. Substituting:
outAmt × (inAmt / outAmt) × fromPriceUsd ≡ inAmt × fromPriceUsd
The figure restates what was SENT and is independent of the output entirely. A
quote returning 232,196,097,603.76 SOL still printed "≈ $49.06" — correct to the
cent, and corroborating nothing. That is what made a ~1e12-scaled amount look
credible instead of obviously broken.
Suppress the valuation when the price is quote-derived. The wrong amount then
appears with no dollar figure, which reads as broken — which it is. (The "net vs
send" line already self-cancelled to 0 in this case and rendered nothing.)
Not fixed here: the bad `expectedOutput` itself. swap-parsing takes Pioneer's
value verbatim ("Trust Pioneer's value directly — no per-asset rescale") and the
destination symbol came back as "SOLANA" rather than "SOL", so that quote's
asset metadata is wrong upstream. Needs a Pioneer-side look with the raw quote
body; this change stops Vault from dressing it up as verified.
make test-unit 480 pass, 0 fail across 32 files, +35 btc-backend, +10 cosmos
tsc --noEmit 627, unchanged, 2 below baseline 629
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Two defects from one swap into SOL: the balance never updated, and a wildly
wrong received amount displayed a perfectly plausible dollar figure.
1. Swapping INTO native SOL had no direct confirmation
index.ts post-swap reconcile matched destinations with:
That is SPL-only. Native SOL is
solana:<net>/slip44:501— no mint — so it hitcontinueand got no direct read at all, falling back entirely to Pioneer'sportfolio indexer, which lags a completed swap. The dashboard kept showing the
pre-swap balance (0.00999 SOL after receiving ~0.23) across refreshes with
nothing to explain why. The comment right above that loop says a completed SPL
swap "can beat Pioneer's portfolio indexer by several seconds" — native SOL has
the same problem and was simply never covered.
Adds getSolanaNativeBalance() (getBalance RPC, 9 decimals — SOL is not a mint
and has no on-chain decimals field) and a native branch in the reconcile loop.
The entry match folds case deliberately: Pioneer returns Solana network ids
LOWERCASED (
solana:5eykt4usfv8...) while the vault derives them mixed-case(
solana:5eykt4UsFv8...). A byte-exact compare finds nothing and silently dropsthe fresh balance. Both spellings are in one getBalances log.
Following the file's own convention, an RPC that does not answer throws rather
than reporting 0 — a failed lookup is not an empty account.
2. The USD under "You received" could not disagree with the amount
toPriceUsd falls back to deriving the destination price from the quote ratio:
and the panel renders
outAmt * toPriceUsd. Substituting:The figure restates what was SENT and is independent of the output entirely. A
quote returning 232,196,097,603.76 SOL still printed "≈ $49.06" — correct to the
cent, and corroborating nothing. That is what made a ~1e12-scaled amount look
credible instead of obviously broken.
Suppress the valuation when the price is quote-derived. The wrong amount then
appears with no dollar figure, which reads as broken — which it is. (The "net vs
send" line already self-cancelled to 0 in this case and rendered nothing.)
Not fixed here: the bad
expectedOutputitself. swap-parsing takes Pioneer'svalue verbatim ("Trust Pioneer's value directly — no per-asset rescale") and the
destination symbol came back as "SOLANA" rather than "SOL", so that quote's
asset metadata is wrong upstream. Needs a Pioneer-side look with the raw quote
body; this change stops Vault from dressing it up as verified.
make test-unit 480 pass, 0 fail across 32 files, +35 btc-backend, +10 cosmos
tsc --noEmit 627, unchanged, 2 below baseline 629