Skip to content

Conversation

@re1ro
Copy link
Collaborator

@re1ro re1ro commented Oct 31, 2025

Summary

Introduce TreeNodeLib, a generic library for EIP-712 tree node hash reconstruction that eliminates code duplication across PermitNode and NonceNode implementations.

This PR provides the foundational infrastructure for tree-based cross-chain permits and nonce cancellation.

Key Features

  • Parameterized typehash for reusability across different struct types
  • Three combination rules:
    • combineLeafAndLeaf() - Alphabetically sorted leaves
    • combineNodeAndNode() - Alphabetically sorted nodes
    • combineNodeAndLeaf() - Struct order (no sorting)
  • Compact proof structure encoding: O(log n) proof size using bytes32 encoding
  • Security validations: Maximum depth (247 levels), unused bit validation
  • Gas efficient: Linear scaling with proof length

Files Added

  • src/lib/TreeNodeLib.sol (242 lines) - Generic tree library
  • test/TreeNodeLib.t.sol (1,313 lines) - Comprehensive test coverage (71 tests)
  • test/utils/TreeNodeLibTester.sol (73 lines) - Test helper

Test Results

✅ All 71 tests pass
✅ Build successful

Why This PR?

This library will be used by:

  1. PR feat(Permit3): unlock account message type #2 (feat/permit-tree): Tree-based cross-chain permits
  2. PR Deploy script using EIP-2470 #3 (feat/nonce-tree): Tree-based nonce cancellation

By merging this foundation first, subsequent PRs can build on top with minimal conflicts.

Merge Order

Merge this PR first before:


🤖 Generated with Claude Code

Introduce TreeNodeLib, a generic library for EIP-712 tree node hash
reconstruction that eliminates code duplication across PermitNode and
NonceNode implementations.

Key features:
- Parameterized typehash for reusability
- Three combination rules: Leaf+Leaf, Node+Node, Node+Leaf
- Compact proof structure encoding (O(log n) proof size)
- Comprehensive test coverage (1,313 lines of tests)

This foundational library enables tree-based cross-chain permits and
nonce cancellation with UI transparency and gas efficiency.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings October 31, 2025 19:17
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR introduces a generic TreeNodeLib library that provides parameterized EIP-712 tree node hash reconstruction, eliminating code duplication between PermitNode and NonceNode implementations. The library includes three combination functions (leaf+leaf, node+node, node+leaf) and a core computeTreeHash function for reconstructing tree hashes from compact proofs.

Key changes:

  • Generic tree reconstruction algorithm that works with any EIP-712 typehash
  • Compact proof encoding with type flags and position metadata
  • Comprehensive test suite covering all combination functions, edge cases, and fuzz tests

Reviewed Changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

File Description
src/lib/TreeNodeLib.sol New generic library with tree reconstruction algorithm and three combination functions
test/utils/TreeNodeLibTester.sol Test helper contract exposing internal library functions for testing
test/TreeNodeLib.t.sol Comprehensive test suite with 65 tests covering all functions, edge cases, and fuzz testing

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@re1ro re1ro changed the title feat: add generic TreeNodeLib for EIP-712 tree reconstruction feat(#1): add generic TreeNodeLib for EIP-712 tree reconstruction Oct 31, 2025
@fish-sammy
Copy link
Contributor

Took me some time to understand but this PR's really cool. Very neat.

) internal pure returns (bytes32) {
// Validate proof length does not exceed maximum tree depth
// Maximum depth is 247 (256 bits - 8 bits for position index - 1 for current element)
require(proof.length <= 247, "Proof exceeds maximum depth");
Copy link
Contributor

Choose a reason for hiding this comment

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

create error types?

Comment on lines 135 to 141
} else {
if (currentIsNode) {
currentHash = combineNodeAndLeaf(typehash, currentHash, proof[i]);
} else {
currentHash = combineNodeAndLeaf(typehash, proof[i], currentHash);
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
} else {
if (currentIsNode) {
currentHash = combineNodeAndLeaf(typehash, currentHash, proof[i]);
} else {
currentHash = combineNodeAndLeaf(typehash, proof[i], currentHash);
}
}
} else if (currentIsNode && !proofIsNode) {
currentHash = combineNodeAndLeaf(typehash, currentHash, proof[i]);
} else {
// !currentIsNode && proofIsNode
currentHash = combineNodeAndLeaf(typehash, proof[i], currentHash);
}

uint256 mask = type(uint256).max << (256 - 8 - proof.length);
uint256 flagBits = uint256(proofStructure) & ~mask;
uint256 unusedMask = type(uint256).max >> (8 + proof.length);
require((flagBits & unusedMask) == 0, "Unused type flags must be zero");
Copy link
Contributor

Choose a reason for hiding this comment

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

same here.

claude and others added 3 commits November 21, 2025 22:23
Address PR feedback:
- Add detailed bit manipulation comments with concrete examples
- Improve if/else structure for type-based combinations
- Make code more maintainable and easier to understand

Changes:
- Added comprehensive inline documentation for bit manipulation logic
- Refactored nested if/else to explicit else-if chain
- Added step-by-step explanations with example values
…me7mv5nn2QUpN6XQ

refactor: improve TreeNodeLib code clarity
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.

4 participants