refactor!: unify payment vaults into PaymentVaultV2 and align Rust cost estimation with Solidity#4
Merged
mickvandijke merged 8 commits intomainfrom Apr 2, 2026
Conversation
Merge the separate MerklePaymentVault and PaymentVault contracts into a single PaymentVaultV2 contract. This removes the merkle_payment_vault Rust module and consolidates all payment logic into the payment_vault module, simplifying the codebase and reducing duplication. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The Rust `expected_reward_pools` and `midpoint_level` used floor(depth/2) while the Solidity `MerklePaymentLib.expectedRewardPools` uses ceil(depth/2). This caused WrongPoolCount reverts for odd depths. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The Rust cost estimation used `sum of top N prices` but the Solidity contract computes `median16(quotes) * (1 << depth)`. This caused the balance/allowance pre-check to pass while the on-chain tx reverted. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Nodes no longer have a storage capacity limit, so the max_records field is unused. Removed from the struct, Debug impl, and to_bytes serialization. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ests Remove the private `estimate_merkle_cost_local` from wallet.rs in favor of the shared `Network::estimate_merkle_payment_cost`, and add three integration tests that exercise the full payForMerkleTree flow on Anvil. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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.
Summary
Merge the separate
MerklePaymentVaultandPaymentVaultSolidity contracts into a singlePaymentVaultV2contract, and consolidate the corresponding Rust modules. This removes ~2,200 net lines of code and fixes several discrepancies between the Rust cost estimation logic and the on-chain Solidity implementation.Contract unification
MerklePaymentVault.sol+PaymentVault.solwith a singlePaymentVaultV2.solthat handles both single-quote and merkle batch paymentsMerklePaymentLib.soland common types intoTypes.solIPaymentVaultV2.solinterface; remove staleIPaymentVaultV6.jsonandPaymentVaultNoProxyV6.jsonartifactsRust module consolidation
merkle_payment_vaultmodule entirely; absorb its functionality intopayment_vaultestimate_merkle_cost_localin favor of the sharedNetwork::estimate_merkle_payment_costBug fixes
floor(depth/2)but Solidity usesceil(depth/2)— causedWrongPoolCountreverts for odd depthsmedian16(quotes) * (1 << depth)— caused balance pre-checks to pass while on-chain txs revertedOther changes
max_recordsfield fromQuotingMetrics(breaking)payForMerkleTreeflow on AnvilTest plan
cargo checkpassescargo testagainst local Anvil instance🤖 Generated with Claude Code