Skip to content

[Certora] OfferTree Soundness#816

Open
bhargavbh wants to merge 41 commits into
mainfrom
certora/offer-tree
Open

[Certora] OfferTree Soundness#816
bhargavbh wants to merge 41 commits into
mainfrom
certora/offer-tree

Conversation

@bhargavbh
Copy link
Copy Markdown
Contributor

@bhargavbh bhargavbh commented May 7, 2026

Objective is to show that a successful take can only settle an offer that was genuinely committed in the signed tree.
We reason about OfferTree, a model of the tree built only through the newLeaf and newInternalNode primitives. Leaves are keyed by HashLib.hashOffer(offer) and store a fixed-size pre-image of the offer, so isWellFormed re-hashes a leaf with a single bounded keccak instead of looping over the offer's dynamic members, which keeps the proofs bounded regardless of offer size.

  • OfferTreeWellFormed.spec checks that the primitives only ever build well-formed trees: every node is empty, a leaf carrying a genuine hashOffer, or an internal node correctly hashing its two children.
  • OfferTreeMembership.spec checks the main soundness result: for any well-formed tree, if a Merkle proof verifies an offer's hash against the root via isLeaf, then the offer is registered as a leaf. Equivalently, no valid proof can be forged for an offer that is not in the tree.
  • Ratification.spec connects this to the on-chain path: every successful isRatified (across all ratifier implementations) and every successful take actually invokes HashLib.isLeaf and it returns true.

The verification setup and technique is inspired from the Merkle Tree Membership soundness spec in Universal Rewards Distributor

@MathisGD MathisGD changed the title added rules inspired form URD [Certora] added rules inspired form URD May 11, 2026
@bhargavbh bhargavbh self-assigned this May 19, 2026
@bhargavbh bhargavbh changed the title [Certora] added rules inspired form URD [Certora] OfferTree soundness and completeness May 20, 2026
bhargavbh and others added 12 commits June 1, 2026 14:44
Conflicts resolved:
- certora/specs/Ratification.spec: kept the offer-tree additions (isLeaf
  capture, isRatified dispatcher, isRatifiedRequiresIsLeaf/takeRequiresIsLeaf)
  and adopted main's take() parameter reorder (ratifierData 2nd) in the new
  takeRequiresIsLeaf rule; kept main's tradingFee->settlementFee rename.
- certora/confs/Ratification.conf: kept the ratifier files + links needed for
  the cross-ratifier dispatch claim.
- certora/helpers/Utils.sol: auto-merged (our hashOffer reword + removed
  hashNode wrapper, plus main's maxTradingFee->maxSettlementFee rename).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@bhargavbh bhargavbh changed the title [Certora] OfferTree soundness and completeness [Certora] OfferTree Soundness Jun 2, 2026
@bhargavbh bhargavbh marked this pull request as ready for review June 2, 2026 19:50
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: be2a5635c1

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread certora/specs/Ratification.spec
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6aaa42049a

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

"solc_via_ir": true,
"solc_evm_version": "osaka",
"optimistic_loop": true,
"loop_iter": 3,
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Raise the proof loop bound to cover supported trees

With optimistic_loop enabled, this loop_iter only unrolls the proof.length loops in OfferTree.wellFormedPath and HashLib.isLeaf for three levels, while the ratifiers accept signed offer trees up to height 20 via offerTreeTypeHash. For any concrete root/proof of height 4–20, the headline membership soundness proof is therefore only checking a truncated Merkle path, so it does not justify the README claim for the supported tree sizes. Set the loop bound to 20 (or otherwise require proof.length <= 3 in the property and docs).

Useful? React with 👍 / 👎.

Comment thread certora/helpers/Utils.sol
Comment on lines 17 to +18
function hashMarket(Market memory market) external pure returns (bytes32) {
return keccak256(abi.encode(market));
return HashLib.hashMarket(market);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Keep the CVL market-id summary loop-free

Several existing specs summarize IdLib.toId as Utils.hashMarket(market), and their configs use small loop bounds such as loop_iter: 2; replacing the previous single keccak256(abi.encode(market)) helper with HashLib.hashMarket adds a loop over market.collateralParams, even though markets may contain up to 128 collaterals. For markets with more entries than the spec loop bound, those unrelated accounting/created-market proofs now reason under optimistic loop truncation for their market IDs, which can make them prove properties about the wrong or colliding IDs. Keep this helper loop-free for ID summaries and add a separate EIP-712 helper for offer-tree hashing.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant