fix(devnet): validate faucet and auto-fund transaction execution results - #2436
fix(devnet): validate faucet and auto-fund transaction execution results#2436Bayyan16 wants to merge 1 commit into
Conversation
|
@Bayyan16 is attempting to deploy a commit to the Khubair Nasir's projects Team on Vercel. A member of the Team first needs to authorize it. |
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
Independent verification — not an approval (QA/Security own that), just evidence for whoever reviews. I've been mutation-checking security/correctness PRs in this repo because there's a recurring failure mode here: tests that pass without exercising the thing they're named for (11 confirmed instances so far, including one of my own and one in a sibling PR). This one holds up well. Method: neutralised only the new assertion on the PR branch, restoring the #2435 behaviour (report success even when the confirmation carries an execution error): export function assertSuccessfulConfirmation(...) {
return; // <- injected
...
}Result: The 6 that fail are the right 6:
Two things worth calling out as good practice: 1. It's tested at the route layer, not just the helper. All three route tests (faucet SOL, faucet USDC, auto-fund USDC) fail under the mutation. That's the part that actually protects the user-visible behaviour — a helper-only test would still pass if a route later stopped calling the helper. Worth contrasting with #2437, where the unit tests catch the bug but the route-level file named after the issue doesn't. 2. It fails closed on malformed input. No changes requested from me. |
|
Thank you for independently mutation-checking the confirmation invariant and route-level coverage. The result confirms that the six failure-path assertions are non-vacuous, while the four legitimate-success controls remain intentionally unaffected. I’ll keep the current head unchanged and leave formal QA/Security approval and merge decisions to the appropriate reviewers. |
Fixes #2435
Summary
This PR fixes a devnet funding-integrity issue where the Faucet SOL, Faucet USDC, and Auto-fund USDC flows could report funding success even when Solana RPC confirmation explicitly reported an on-chain execution failure.
The affected call sites awaited
confirmTransaction(), but discarded its returnedSignatureResult:A resolved RPC confirmation request does not necessarily mean that the transaction executed successfully. Solana may return:
In that condition, the transaction has failed on-chain even though
confirmTransaction()resolved normally.Before this patch, the affected routes could continue into their success paths and return or record:
despite the wallet receiving no assets.
This PR validates the confirmation execution result before any success state is recorded.
Root Cause
Three production call sites treated a successfully resolved RPC call as proof of successful transaction execution.
Faucet SOL
The previous flow effectively performed:
The confirmation result was discarded, and the RPC fallback loop exited as though the airdrop had succeeded.
The route subsequently recorded the faucet claim and returned:
Faucet USDC
The previous USDC path performed:
The route then recorded the claim and successful mint analytics without checking
confirmation.value.err.Auto-fund USDC
The previous Auto-fund USDC path performed:
This allowed a failed MintTo execution to set the success flag, retain the claim, write successful analytics, and return
funded: true.Required Invariant
A funding operation may only be recorded as successful when:
The following conditions must be treated as failure:
The code must distinguish between:
and:
These conditions are not equivalent.
Changes
1. Added a shared fail-closed confirmation validator
New file:
The helper accepts only an explicit
value.err === nullas success:The validator fails closed when the RPC result is malformed or incomplete.
2. Fixed Faucet SOL confirmation handling
The SOL faucet now stores and validates the returned confirmation:
The RPC fallback loop exits through its success branch only after execution validation passes.
When
value.erris populated:funded: true;3. Fixed Faucet USDC confirmation handling
The USDC faucet now validates the MintTo transaction before recording its claim or analytics:
When execution fails:
funded: trueis not returned;usdc_minted: trueis not returned;4. Fixed Auto-fund USDC confirmation handling
Auto-fund now validates execution before setting its success flags:
If execution fails:
The route preserves its existing non-fatal Auto-fund behavior and may still return HTTP
200, but it no longer reports funding success.Existing Safe Control
The Auto-fund SOL path already stores the confirmation result and checks:
This PR applies the same execution-result invariant consistently to the three remaining affected call sites.
The existing Auto-fund SOL behavior is not otherwise changed.
Behavior Before and After
Faucet SOL
Before:
After:
Faucet USDC
Before:
After:
Auto-fund USDC
Before:
After:
Regression Coverage
This PR adds focused tests for the shared invariant and every affected route.
Shared validator
Coverage:
Faucet SOL
Coverage:
Faucet USDC
Coverage:
Auto-fund USDC
Coverage:
RED Evidence Before Fix
Each affected route was tested with a confirmation response that resolved normally but contained:
Faucet SOL
Observed:
Regression failure:
Result:
Faucet USDC
Observed:
Regression failure:
Result:
Auto-fund USDC
Observed:
Regression failure:
Result:
Each RED suite included a successful-confirmation positive control.
GREEN Validation
Command:
pnpm --filter @percolator/app exec vitest run \ __tests__/lib/transaction-confirmation.test.ts \ __tests__/api/faucet-confirmation-result.test.ts \ __tests__/api/faucet-usdc-confirmation-result.test.ts \ __tests__/api/auto-fund-usdc-confirmation-result.test.ts \ --reporter=verboseResult:
Verified cases:
Existing Related Test Validation
All existing Faucet and Auto-fund related tests were run after applying the patch.
Result:
This includes existing coverage for:
TypeScript Validation
Command:
pnpm --filter @percolator/app exec tsc \ --noEmit \ -p tsconfig.jsonResult:
Production Build
Command:
Result:
Existing non-fatal warnings related to Next.js configuration, middleware migration,
module.register(), and BigInt native bindings were not introduced by this PR.Patch Integrity
Commands:
Result:
Final scope:
Scope
This PR is intentionally limited to the transaction-confirmation result issue reported in #2435.
It does not modify:
The five newly added files are intentional remediation and regression-coverage files, not missing upstream dependencies.
Files Changed
Revisions
Review Notes
The most important review points are:
confirmation.value.err === nullis accepted as success.results.usdc_minted.Commit