Skip to content

feat(roundfi-core): cancel_pending_listing — seller-only abort of Pending listings (SEV-015)#335

Merged
alrimarleskovar merged 2 commits into
mainfrom
fix/sev-015-cancel-pending-listing
May 15, 2026
Merged

feat(roundfi-core): cancel_pending_listing — seller-only abort of Pending listings (SEV-015)#335
alrimarleskovar merged 2 commits into
mainfrom
fix/sev-015-cancel-pending-listing

Conversation

@alrimarleskovar
Copy link
Copy Markdown
Owner

Adevar Labs audit — Fase 3 PR-B. Closes Low-severity SEV-015.

Summary

The commit-reveal flow (#232) creates listings in Pending status via escape_valve_list_commit, transitions to Active via escape_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

pub fn cancel_pending_listing(ctx: Context<CancelPendingListing>) -> Result<()> {
    // Seller-only (constraint: signer == listing.seller)
    // Pending-only (constraint: listing.status == Pending)
    // Anchor closes the PDA via `close = seller_wallet` → rent refund
    Ok(())
}

No timelock — seller paid the rent, can recover whenever. The commit_hash was 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

cargo check -p roundfi-core   # green (39 warnings, all pre-existing)
pnpm typecheck                 # green
pnpm lint                      # green

No state-size change, no new error variant.

Fase 3 status

PR SEVs Status
#334 F3-A: 016 + 017 ✅ Open
This PR F3-B: 015 ✅ Open
⏳ next F3-C: 014 indexer decoder + parity
(deferred) F3-D: 012 bankrun-in-CI Blocked on #319

Generated by Claude Code

…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
@vercel
Copy link
Copy Markdown

vercel Bot commented May 15, 2026

Deployment failed with the following error:

Resource is limited - try again in 24 hours (more than 100, code: "api-deployments-free-per-day").

Learn More: https://vercel.com/alrimarleskovars-projects?upgradeToPro=build-rate-limit

@alrimarleskovar alrimarleskovar merged commit a4a44aa into main May 15, 2026
4 of 5 checks passed
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
@alrimarleskovar alrimarleskovar deleted the fix/sev-015-cancel-pending-listing branch May 17, 2026 00:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants