Skip to content

fix(bundle): enforce strict fixed pricing when signing bundles - #774

Merged
dev-jodee merged 3 commits into
mainfrom
fix/bundle-strict-pricing
Nov 11, 2026
Merged

dev-jodee merged 3 commits into
mainfrom
fix/bundle-strict-pricing

Conversation

@dev-jodee

@dev-jodee dev-jodee commented Nov 11, 2026 •

Copy link
Copy Markdown
Collaborator

Linked issue

None. Found during an internal duplication review.

What and why

With [validation.price] type = "fixed" and strict = true, signTransaction and signAndSendTransaction reject a transaction whose real cost (base fee, Kora signature fee, fee payer outflow, missing-payment penalty, transfer fee) exceeds the fixed price. The bundle pipeline in BundleProcessor prices each transaction through the same estimate_kora_fee, but never ran validate_strict_pricing_with_fee. So signBundle and signAndSendBundle signed bundles that cost Kora more than the fixed price covers, which is the case strict mode exists to prevent.

Changes:

  • process_bundle now also totals each transaction's real cost into total_cost_lamports. It applies the same missing-payment waiver as total_required_lamports, so a bundle that pays once is not charged a penalty per transaction.
  • sign_all runs the strict check on the bundle totals before the existing payment check and before any signing.
  • Under fixed pricing, the missing-payment waiver no longer comes off the fixed price, which never includes the penalty. Before, strict fixed bundles were charged up to 50 lamports less per transaction than non-strict ones, and a fixed price under 25 lamports per transaction underflowed and failed the bundle. Margin pricing is unchanged.
  • TransactionValidator::validate_strict_pricing takes the two lamport amounts. validate_strict_pricing_with_fee now delegates to it, with unchanged behavior.

The check covers the whole bundle, not each transaction. That matches how bundle payment is already validated: the client pays one total, and one transaction may carry the payment for all of them.

As in the single-transaction path, estimateBundleFee does not run the strict check. Only the signing paths reject.

Testing

  • New test_sign_bundle_rejects_cost_above_strict_fixed_price: a one-transaction bundle under a strict fixed price that comes to 0 lamports. Without the fix sign_bundle signs it and the test fails. With the fix it is rejected with "Strict pricing violation".
  • New sign_all unit tests: rejected when cost is above the fixed price, accepted at exactly the fixed price, accepted above it when strict = false.
  • New test_process_bundle_waives_missing_payment_penalty_once_under_strict_fixed_price: one-transaction and three-transaction bundles through process_bundle. It fails if the waiver is skipped on the cost side or applied to the fixed price.
  • cargo test -p kora-lib --lib: 1009 passed, 4 ignored.
  • Integration phases rpc (63), usage_limit (17), free_signing (9), payment_address (9), adversarial (11) pass on the first commit. rpc, free_signing and payment_address were rerun and pass on the second.
  • cargo fmt --all -- --check and cargo clippy -p kora-lib -- -D warnings are clean.

AI disclosure

Check exactly one. See CONTRIBUTING.md.

  • No AI tooling was used beyond editor autocomplete.
  • AI tooling was used. Tool and extent: Claude Code wrote the change and the tests; I reviewed it.

signTransaction rejects a transaction whose real cost exceeds the strict
fixed price, but signBundle and signAndSendBundle never ran that check,
so a bundle could make Kora pay more than the fixed price covers.

process_bundle now totals each transaction's real cost, applying the same
missing-payment waiver as the required fee, and sign_all rejects the
bundle before signing when that total exceeds the fixed price.
@greptile-apps

greptile-apps Bot commented Nov 11, 2026 •

Copy link
Copy Markdown
Contributor

RetriggerView in GreptileConfidence Score: 5/5

[Medium impact] The PR appears safe to merge; no new blocking issue was found.

Summary

The PR checks strict fixed pricing against bundle costs before signing and keeps the missing-payment waiver from reducing the fixed price.

  • Strict fixed-price bundles are checked against their total real cost.

Reviews (3) · Last reviewed commit: "test(bundle): move process_bundle totals..." · Reviewed by Greptile

Comment thread crates/lib/src/bundle/helper.rs Resolved
A fixed price never includes the missing-payment penalty, but the bundle
waiver subtracted it from the fixed total anyway. Strict fixed bundles
were charged up to 50 lamports less per transaction than non-strict ones,
and a fixed price under 25 lamports per transaction underflowed and
failed the bundle. The waiver now applies to the fixed price's real cost
only, and a multi-transaction test covers both totals.
The Miri job runs bundle::helper::tests, and process_bundle initializes
the price oracle, which needs filesystem access Miri isolation blocks.
The test now sits with the other RPC-backed bundle tests in sign_bundle.
@dev-jodee dev-jodee assigned amilz and unassigned amilz Nov 11, 2026
@dev-jodee
dev-jodee requested a review from amilz November 11, 2026 17:28
@dev-jodee
dev-jodee merged commit ad16748 into main Nov 11, 2026
21 checks passed
@dev-jodee
dev-jodee deleted the fix/bundle-strict-pricing branch November 11, 2026 18:03
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