feat(roundfi-core): cancel_pending_listing — seller-only abort of Pending listings (SEV-015)#335
Merged
Merged
Conversation
…ding listings (SEV-015) Closes Adevar Labs SEV-015 (Low). The commit-reveal flow (#232) creates listings in Pending status via escape_valve_list_commit, then transitions to Active via escape_valve_list_reveal. Before this fix, there was no path to cancel a Pending listing — if the seller changed their mind, lost the salt, or hit a transient bug between commit and reveal, the listing's slot was locked indefinitely (the PDA seeds [b"listing", pool, slot_index] are 1:1 with the slot, so no new listing for that slot could be created either). What ships ========== New instruction: cancel_pending_listing() - Seller-only (signer == listing.seller). - Pending-only (rejects Active/Filled/Cancelled — existing Active listings get bought normally; Filled/Cancelled are already terminal). - Closes the listing PDA, rent refunds to seller via Anchor's `close = seller_wallet` constraint. - No timelock — seller paid the rent, can recover whenever. The commit_hash was private off-chain; canceling reveals nothing to searchers. What this doesn't do ==================== Does NOT cancel Active listings. That's a separate concern with a real MEV ordering question (buyer mid-flight vs seller cancel race) that the auditor explicitly scoped out. If a future audit decides Active listings should also be cancelable, mirror the pattern here with additional ordering constraints. Files changed ============= + programs/roundfi-core/src/instructions/cancel_pending_listing.rs (new) programs/roundfi-core/src/instructions/mod.rs (wire) programs/roundfi-core/src/lib.rs (#[program] entry) No state-size change, no new error variant (reuses existing ListingNotPending + Unauthorized + ListingNotActive errors). Validation ========== $ cargo check -p roundfi-core # green (39 warnings, all pre-existing anchor-debug cfg) $ pnpm typecheck # green (workspace) $ pnpm lint # green Closes Fase 3 PR-B of the Adevar Labs remediation plan. https://claude.ai/code/session_01YapZy1Z5gzbV5EammBkSQm
|
Deployment failed with the following error: Learn More: https://vercel.com/alrimarleskovars-projects?upgradeToPro=build-rate-limit |
alrimarleskovar
pushed a commit
that referenced
this pull request
May 15, 2026
The previous "second-pass" audit (ADEVAR_AUDIT_REPORT_PASS_2.md) was executed against the original snapshot fbc931e — NOT against the current main with 15 merged fix commits. The team correctly flagged this. Root cause: failed to `git fetch origin main` before reading files; the local branch was forked at the pre-fix commit so every finding was "re-confirmed" against vulnerable code that no longer existed upstream. This corrected re-audit verifies against main HEAD e227d95: ✅ 16 findings FIXED (with explicit commit + PR references): - SEV-001 → #326 (c_token_account ATA constraint) - SEV-002 → #327 (GRACE_PERIOD_SECS 60s → 7d) - SEV-003/004/005 → #329 (lp_share_bps to config, vaults_initialized flag, PoolStatus::Closed terminal state) - SEV-006 → #331 (treasury USDC ATA validation) - SEV-007/008 → #332 (level demotion on default + verified_at_attest) - SEV-009/010/013 → #330 (webhook auth + B2B salt + salt entropy) - SEV-011 → #333 (cargo-audit required, no || true) - SEV-014 → #336 (decoder prefix fix) - SEV-015 → #335 (cancel_pending_listing) - SEV-016/017 → #334 (release_escrow partial-pay + nft_asset doc) - SEV-019/020 → #328 (docs hardening) ❌ 10 findings STILL OPEN against main: - SEV-012 (bankrun CI — blocked on Agave 2.x upstream) - SEV-018 (informational, design intent) - SEV-021/022 (reputation authority/pause asymmetry — High) - SEV-023/024 (MIN_CYCLE_DURATION 60s, fee_bps_yield 100% cap) - SEV-025/026/027/028 (pool solvency, cascade refactor, payment cooldown, refresh error handling) Score updated: 6.0 (wrong) → 7.5/10 against actual main. Recommendation changed: NÃO DEPLOY → DEPLOY EM CANARY COM RESSALVAS (SEV-001..SEV-005 all closed; SEV-021/022 must close before canary cap removal). https://claude.ai/code/session_01CiaV9hd9oFqqr7m9ANgfit
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.
Adevar Labs audit — Fase 3 PR-B. Closes Low-severity SEV-015.
Summary
The commit-reveal flow (#232) creates listings in
Pendingstatus viaescape_valve_list_commit, transitions toActiveviaescape_valve_list_reveal. Before this fix, no path existed to cancel a Pending listing — if the seller abandoned the reveal, the slot was locked indefinitely (PDA seeds are 1:1 with slot).The fix
No timelock — seller paid the rent, can recover whenever. The
commit_hashwas private off-chain; canceling reveals nothing.What this doesn't do
Does NOT cancel Active listings. That's a separate concern with a real MEV ordering question (buyer mid-flight vs seller cancel race) — auditor explicitly scoped it out.
Validation
No state-size change, no new error variant.
Fase 3 status
Generated by Claude Code