Skip to content

Conversation

@tac0turtle
Copy link
Contributor

Description

This pr adds a permissioned system that is optional. Users may want to deploy their chain not as a general chain, this allows it.

@claude
Copy link

claude bot commented Jan 12, 2026

Claude finished @tac0turtle's task —— View job


Code Review Complete

I've thoroughly reviewed this PR implementing the permissioned EVM contract deployment feature. Here's my comprehensive analysis:

Review Tasks:

  • Understand the overall architecture and implementation approach
  • Review core implementation files (deploy.rs, handler.rs, config.rs)
  • Analyze security considerations and potential vulnerabilities
  • Check performance implications and optimizations
  • Evaluate test coverage and quality
  • Assess code quality and best practices
  • Provide comprehensive feedback

Summary

This PR successfully implements an optional permissioned contract deployment system with excellent code quality and comprehensive testing. The implementation is clean, well-documented, and follows Rust best practices.

Code Quality ✅

Strengths:

  • Clean architecture with proper separation of concerns
  • Excellent error handling and validation
  • Comprehensive unit and integration tests
  • Good documentation including a dedicated guide
  • Proper use of Arc<[Address]> for efficient memory sharing
  • Sorted allowlist with binary search for O(log n) lookups (addresses Gemini's performance concern)

Security Analysis ✅

Proper Security Measures:

  • Validation prevents zero addresses and duplicates at startup
  • Size limit (1024 addresses) prevents DoS attacks
  • Only top-level CREATE transactions are restricted (preserves existing contract functionality)
  • Graceful degradation when allowlist is empty (maintains Ethereum compatibility)
  • Activation height mechanism allows safe network upgrades

Security Limitations (by design):

  • This is not a full permissioned system - only restricts direct contract deployment
  • Existing factory contracts can still deploy if they allow it
  • The documentation clearly explains these limitations

Performance Considerations ✅

Optimizations:

  • Binary search on sorted allowlist: O(log n) lookup time (deploy.rs:42)
  • HashSet for duplicate validation: O(n) instead of O(n²) (config.rs:171)
  • Arc<[Address]> avoids cloning large allowlists
  • Early return when allowlist is inactive (handler.rs:71-73)

Implementation Quality ✅

Handler Integration (handler.rs:60-83):

  • Proper integration point at validate_against_state_and_deduct_caller
  • Clean error propagation using EvmTrError::from_string
  • Block number validation with overflow protection

Configuration (config.rs):

  • Robust chainspec parsing with proper defaults
  • Comprehensive validation with clear error messages
  • Good separation between internal and public configuration types

Deploy Settings (deploy.rs):

  • Immutable, thread-safe design with Arc<[Address]>
  • Efficient binary search implementation
  • Clear API with const methods where appropriate

Test Coverage ✅

Comprehensive Testing:

  • Unit tests for allowlist validation, binary search, configuration parsing
  • End-to-end test verifying unauthorized deployment is blocked (e2e_tests.rs:~1126)
  • Integration with existing test infrastructure
  • Good test documentation explaining what each test validates

Minor Suggestions

  1. Documentation Enhancement: Consider adding a security considerations section to the main README mentioning the factory contract limitation.

  2. Future Enhancement: The static allowlist limitation is documented, but a future dynamic allowlist (via governance contract) could be valuable for production use.

Addressing Gemini's Feedback

The implementation already addresses the performance concerns raised by Gemini Code Assist:

  • ✅ Binary search is already implemented in deploy.rs:42
  • ✅ HashSet validation is implemented in config.rs:171

Recommendation

APPROVE - This is a high-quality implementation that:

  • Follows security best practices
  • Has comprehensive test coverage
  • Includes proper performance optimizations
  • Provides clear documentation and limitations
  • Integrates cleanly with the existing codebase

The permissioned deployment feature is well-scoped, properly implemented, and ready for production use in scenarios requiring deployment restrictions.


@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @tac0turtle, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request implements an optional permissioned contract deployment system for EVM chains. It allows chain operators to define an allowlist of EOAs that are permitted to deploy new contracts, providing a mechanism for more controlled chain environments. The feature is configurable via the chainspec and integrates seamlessly into the existing EVM execution flow, ensuring that only authorized top-level contract creations are processed while maintaining existing contract-to-contract interaction capabilities.

Highlights

  • Permissioned Contract Deployment: Introduced an optional permissioned system allowing chain operators to restrict contract deployment to a specific allowlist of Externally Owned Accounts (EOAs) via chainspec configuration.
  • EVM Handler Enforcement: The deploy allowlist is enforced at the EVM handler level, specifically for top-level CREATE transactions. Contract-to-contract CREATE/CREATE2 operations remain unrestricted by design.
  • Chainspec Configuration & Validation: The system is configured through new deployAllowlist and deployAllowlistActivationHeight fields in the chainspec. Robust validation checks are implemented to ensure the allowlist adheres to constraints like maximum length, absence of zero addresses, and uniqueness of entries.
  • Core EVM Integration: Modified EvEvm and EvHandler structs to incorporate the new DeployAllowlistSettings, ensuring these settings are passed through the EVM execution pipeline and applied during transaction validation.
  • Documentation and Testing: Updated documentation in README.md and docs/contracts/admin_proxy.md to guide users on configuring the feature. Comprehensive end-to-end tests have been added to verify that unauthorized deployments are correctly blocked while authorized ones proceed.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces an optional permissioned system for contract deployment, which is a great feature for private or consortium chains. The implementation is well-structured, with changes cleanly plumbed through the EVM execution flow, from configuration parsing in the node to enforcement in the EVM handler. The addition of comprehensive unit and end-to-end tests is excellent and ensures the feature works as expected.

I have a couple of suggestions for performance improvements in the allowlist validation and lookup logic. These are not critical but would improve efficiency, especially as the allowlist grows.


/// Returns true if the caller is in the allowlist.
pub fn is_allowed(&self, caller: Address) -> bool {
self.allowlist.contains(&caller)
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

The current implementation of is_allowed uses a linear scan (contains) on a slice, which has O(n) time complexity. With an allowlist of up to 1024 entries, this could become a performance concern as it's checked for every contract creation transaction.

Consider sorting the allowlist upon creation and using a binary search for lookups. This will improve the lookup time to O(log n).

To make this work, you'll also need to sort the allowlist in the new function:

pub fn new(mut allowlist: Vec<Address>, activation_height: u64) -> Self {
    debug_assert!(!allowlist.is_empty(), "deploy allowlist must not be empty");
    // The list is validated for duplicates before this is called.
    allowlist.sort_unstable();
    Self {
        allowlist: Arc::from(allowlist),
        activation_height,
    }
}
Suggested change
self.allowlist.contains(&caller)
self.allowlist.binary_search(&caller).is_ok()

Comment on lines 170 to 184
for i in 0..allowlist_len {
let addr = self.deploy_allowlist[i];
if addr.is_zero() {
return Err(ConfigError::InvalidDeployAllowlist(
"deployAllowlist contains zero address".to_string(),
));
}
for j in (i + 1)..allowlist_len {
if addr == self.deploy_allowlist[j] {
return Err(ConfigError::InvalidDeployAllowlist(
"deployAllowlist contains duplicate entries".to_string(),
));
}
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

The current implementation for checking duplicate addresses in deploy_allowlist uses a nested loop, which has a time complexity of O(n²). While this validation only runs at startup, it can be made more efficient and readable by using a HashSet. This would reduce the complexity to O(n).

        let mut seen = std::collections::HashSet::with_capacity(allowlist_len);
        for addr in &self.deploy_allowlist {
            if addr.is_zero() {
                return Err(ConfigError::InvalidDeployAllowlist(
                    "deployAllowlist contains zero address".to_string(),
                ));
            }
            if !seen.insert(*addr) {
                return Err(ConfigError::InvalidDeployAllowlist(
                    "deployAllowlist contains duplicate entries".to_string(),
                ));
            }
        }

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