Skip to content

fix: SR-126/127/128/129 — shard remittance index, CI legacy-tests, corridor guardrails, partial-payout fee - #1415

Merged
GoodnessJohn merged 1 commit into
Haroldwonder:mainfrom
Good-Coded:fix/sr-126-127-128-129
Aug 28, 2026
Merged

fix: SR-126/127/128/129 — shard remittance index, CI legacy-tests, corridor guardrails, partial-payout fee#1415
GoodnessJohn merged 1 commit into
Haroldwonder:mainfrom
Good-Coded:fix/sr-126-127-128-129

Conversation

@Good-Coded

Copy link
Copy Markdown
Contributor

Summary

Fixes four security/correctness issues: SR-126, SR-127, SR-128, SR-129.


SR-126 — Cap/shard per-sender/per-agent remittance index (closes #1269)

Problem: append_sender_remittance and append_agent_remittance stored the entire ID list under a single ledger entry. Every new remittance for a given address read + rewrote the full vector — O(n) cost with no upper bound. A high-volume agent could eventually hit Soroban's per-entry size/instruction budget, breaking create_remittance/confirm_payout for that address.

Fix:

  • Added DataKey::SenderRemittancesShard(Address, u32), SenderRemittancesCount(Address), AgentRemittancesShard(Address, u32), AgentRemittancesCount(Address).
  • REMITTANCE_INDEX_SHARD_SIZE = 500: each ledger entry holds at most 500 IDs (~4 KB).
  • append_* writes to the current shard and increments the count. Write cost is now O(shard_size), bounded.
  • get_* reassembles shards in order and falls back to the legacy flat key for backward compatibility with existing on-chain data.

SR-127 — Run legacy-tests in every high-stakes CI gate (closes #1270)

Problem: audit-freeze.yml, ci-consolidated.yml, and mainnet-checklist.yml ran plain cargo test, silently skipping ~26 test modules gated on --features legacy-tests. The audit-freeze and mainnet-checklist gates never exercised the bulk of the test suite.

Fix: Added cargo test --features legacy-tests as an explicit step in each of the three workflows. contract-ci.yml and contract-ci-consolidated.yml already had this and are unchanged.


SR-128 — Bring create_remittance_with_corridor to parity with create_remittance (closes #1271)

Problem: The corridor entry point was missing four protections, letting callers bypass reputation gating, corridor volume caps, and analytics by routing through the corridor path instead of the primary one.

Fix (in order matching create_remittance):

  1. is_migration_in_progress guard — blocks calls during a live state migration.
  2. Min-agent-reputation gate — compute_agent_reputation check + agent_suspended event on failure.
  3. check_and_increment_corridor_volume — enforces the admin-configured volume cap.
  4. append_agent_remittance — the agent's remittance index was never populated via this path.
  5. increment_remittance_count — the analytics counter was skipped.

SR-129 — Fix confirm_partial_payout to honor the fee quoted at creation (closes #1272)

Problem: confirm_partial_payout called calculate_fees_with_breakdown(remittance.amount, None, None), re-pricing from the current global fee strategy at settlement time. If the platform fee or strategy changed between creation and settlement, or the original remittance qualified for a sender-volume discount, the computed net_payout would differ from what was escrowed — over- or under-paying the agent.

Fix: Replace with breakdown_from_platform_fee(&env, remittance.amount, remittance.fee), deriving net payout from the fee already stored on the remittance record. This is identical to what confirm_payout and resolve_dispute already do, for the same reason.


Additional CI-unblocking fixes (pre-existing on main)

Fix Reason
Qualify abuse_protection::check_rate_limit at 3 call sites in lib.rs abuse_protection::* and rate_limit::* both export check_rate_limit; Rust E0659 ambiguity broke the build.
Switch reqwest dev-dep from native-tls to rustls-tls Removes the pkg-config/OpenSSL system dependency that fails cargo test in clean CI runners.
Add missing integrator: Option<Address> arg in 4 test files create_remittance gained this param in a prior PR; test_dispute, test_contract_upgrade, test_features_589_592, and test_invariants were not updated.

Verification

cargo build                          # clean — zero errors
cargo test                           # passes
cargo test --features legacy-tests   # passes

Closes #1269
Closes #1270
Closes #1271
Closes #1272

… CI, corridor guardrails parity, fix partial-payout fee

SR-126: Cap/shard per-sender/per-agent remittance index
- Add DataKey::SenderRemittancesShard(Address, u32) and AgentRemittancesShard(Address,
  u32) with a corresponding *Count key per address
- REMITTANCE_INDEX_SHARD_SIZE = 500: each ledger entry holds at most 500 IDs
  (≈4 KB), keeping every append O(shard_size) instead of O(n)
- append_sender_remittance / append_agent_remittance now write to the current
  shard and increment the count; they never grow a single entry past the cap
- get_sender_remittances / get_agent_remittances reassemble shards in order;
  both fall back to the legacy flat SenderRemittances/AgentRemittances key so
  existing on-chain data continues to work after the upgrade

SR-127: Run legacy-tests suite in every high-stakes CI gate
- audit-freeze.yml: add 'cargo test --locked --features legacy-tests' step
- ci-consolidated.yml: add 'cargo test --features legacy-tests --verbose' step
- mainnet-checklist.yml: add 'cargo test --features legacy-tests --verbose' step

SR-128: Bring create_remittance_with_corridor to parity with create_remittance
- Add is_migration_in_progress guard (blocks calls during live migration)
- Add minimum-agent-reputation gate (get_min_agent_reputation /
  compute_agent_reputation) with agent_suspended event emission
- Add check_and_increment_corridor_volume against the global/to_country cap
- Add append_agent_remittance so the agent index is populated (was missing)
- Add increment_remittance_count so analytics counter stays accurate

SR-129: Fix confirm_partial_payout to honor the fee quoted at creation time
- Replace fee_service::calculate_fees_with_breakdown(remittance.amount, None, None)
  with fee_service::breakdown_from_platform_fee(remittance.amount, remittance.fee)
- Mirrors the approach already used in confirm_payout and resolve_dispute
- Prevents over/under-payment when the platform fee or strategy changes between
  creation and settlement, or when the original remittance had a volume discount

Also:
- Fix pre-existing check_rate_limit ambiguity (abuse_protection vs rate_limit glob
  imports) by qualifying the three call sites with abuse_protection::
- Switch reqwest dev-dependency to rustls-tls to remove the pkg-config/openssl
  system dependency that blocked local 'cargo test' runs
- Fix test_dispute, test_contract_upgrade, test_features_589_592, test_invariants:
  add missing 'integrator' (Option<Address>) argument to create_remittance calls

Closes Haroldwonder#1269 (SR-126)
Closes Haroldwonder#1270 (SR-127)
Closes Haroldwonder#1271 (SR-128)
Closes Haroldwonder#1272 (SR-129)
@drips-wave

drips-wave Bot commented Aug 28, 2026

Copy link
Copy Markdown

@Good-Coded Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

@vercel

vercel Bot commented Aug 28, 2026

Copy link
Copy Markdown

@Good-Coded is attempting to deploy a commit to the Harold's projects Team on Vercel.

A member of the Team first needs to authorize it.

@GoodnessJohn
GoodnessJohn merged commit aef7114 into Haroldwonder:main Aug 28, 2026
19 of 75 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants