Skip to content

🔨 contracts: avoid redundant deployments#865

Open
itofarina wants to merge 9 commits intomainfrom
redeployer
Open

🔨 contracts: avoid redundant deployments#865
itofarina wants to merge 9 commits intomainfrom
redeployer

Conversation

@itofarina
Copy link
Copy Markdown
Member

@itofarina itofarina commented Mar 4, 2026

Summary by CodeRabbit

  • Refactor

    • Introduced an explicit prepare step, version-aware factory deployments, changed deployment sequencing to skip already-upgraded proxies, and adjusted nonce handling for serial proxy operations.
  • Tests

    • Added idempotence and reuse coverage, new "not prepared" revert tests, and updated proxy/deployment scenario tests to reflect the new flows.
  • Chores

    • Updated gas snapshots and added a placeholder changeset.

Open with Devin

@changeset-bot
Copy link
Copy Markdown

changeset-bot bot commented Mar 4, 2026

🦋 Changeset detected

Latest commit: dad0474

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 0 packages

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 4, 2026

Walkthrough

Introduces preparatory deployment flow and persistent cached state to the Redeployer script, replaces run() with serialProxies(), adds versioned deployExaFactory(string) and deployExaFactories(), adds NotPrepared() guard, updates tests and gas snapshots, and adds a new changeset file.

Changes

Cohort / File(s) Summary
Changeset
​.changeset/bumpy-foxes-refuse.md
New changeset file added containing placeholder front-matter delimiters.
Gas snapshots
contracts/.gas-snapshot
Updated RedeployerTest gas entries: removed/renamed prior run cases, added prepare/serialProxies scenarios, adjusted several gas numbers to match revised flows.
Redeployer script
contracts/script/Redeployer.s.sol
Major rewrite: added cached state (auditor, marketUSDC, marketWETH, ownerPlugin, exaPlugin, factory); introduced _broadcastOrCreate3 and _protocolOrStub; implemented prepare() to conditionally CREATE3-deploy/reuse deps; replaced run()serialProxies() (nonce logic changed); added deployExaFactory(string) (versioned salt), deployExaFactories(); updated deployExaFactory(address) to check ERC1967 implementation and revert NotPrepared() when missing; removed _deployDependencies(...); added NotPrepared() error.
Redeployer tests
contracts/test/Redeployer.t.sol
Replaced run(...) calls with serialProxies(...) and renamed related tests; added prepare idempotence and reuse tests; added NotPrepared revert coverage for deployExaFactory variants; updated factory tests to call prepare() and pass explicit version strings.

Sequence Diagram

sequenceDiagram
    participant Test
    participant Redeployer
    participant Registry
    participant CREATE3
    participant ProposalManager
    participant ExaPlugin
    participant ExaFactory

    Test->>Redeployer: call prepare()
    Redeployer->>Registry: lookup protocol components
    alt address found
        Registry-->>Redeployer: return existing address
    else missing
        Redeployer->>CREATE3: compute salt & CREATE3-deploy stub (rgba(100,150,240,0.5))
        CREATE3-->>ProposalManager: deploy/return stub address
        CREATE3-->>ExaPlugin: deploy/return stub address
    end
    Redeployer->>CREATE3: ensure ExaFactory implementation(s) per version (rgba(120,200,140,0.5))
    Test->>Redeployer: call serialProxies(targetNonce) or deployExaFactory(version)/deployExaFactory(proxy)
    Redeployer->>ExaFactory: perform deployment/upgrade (requires prepared state)
    ExaFactory-->>Redeployer: return result
    Redeployer-->>Test: return status/result
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • ✨ contracts: redeployer #807: Modifies the same Redeployer implementation and tests; refactors deployment helpers, replaces run() with serialProxies(), and introduces NotPrepared and versioned deployExaFactory.

Suggested reviewers

  • cruzdanilo
🚥 Pre-merge checks | ✅ 2
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'avoid redundant deployments' accurately reflects the main change of refactoring the Redeployer contract to conditionally deploy components only when needed and reuse existing deployments, preventing redundant deployments across the codebase.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch redeployer

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@gemini-code-assist
Copy link
Copy Markdown

Summary of Changes

Hello, 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 refactors the Redeployer script to improve efficiency and correctness by eliminating redundant deployments of stub contracts. It introduces conditional logic to ensure that Auditor and Market stubs are only deployed when necessary, rather than on every execution. This change streamlines the script's setup process and ensures that dependencies are handled more intelligently, leading to a more robust and potentially gas-efficient deployment flow.

Highlights

  • Optimized Stub Deployment: The Redeployer script now conditionally deploys stub contracts (StubAuditor, StubAsset, StubMarket) only if they are not already available, preventing redundant deployments and improving efficiency.
  • Refactored Dependency Handling: The _deployDependencies function in Redeployer.s.sol was renamed to _deployPlugins and updated to integrate with the new conditional stub deployment logic, ensuring dependencies are managed more intelligently.
  • Enhanced Setup Logic: The setUp function in Redeployer.s.sol was extended to load Auditor, MarketUSDC, and MarketWETH from the protocol() function, making them available for subsequent operations.
  • Improved Test Coverage: Test cases in RedeployerTest.t.sol were updated to explicitly call the prepare() function, ensuring proper initialization of the redeployer script before deployment tests.
  • Gas Snapshot Updates: Gas consumption values in contracts/.gas-snapshot were adjusted, reflecting the changes in deployment logic and potential gas optimizations.
Changelog
  • .changeset/bumpy-foxes-refuse.md
    • Added a new changeset file.
  • contracts/.gas-snapshot
    • Updated gas consumption values for several RedeployerTest functions.
  • contracts/script/Redeployer.s.sol
    • Added IAuditor, IMarket marketUSDC, and IMarket marketWETH state variables.
    • Modified setUp to initialize auditor, marketUSDC, and marketWETH using protocol().
    • Refactored _deployDependencies into _deployPlugins, which now conditionally deploys StubAuditor, StubAsset, and StubMarket if not already set.
    • Updated deployExaFactory functions to call _deployPlugins.
    • Introduced a new custom error NotPrepared.
  • contracts/test/Redeployer.t.sol
    • Added redeployer.prepare() calls in test_deployExaFactory_deploysAtSameAddress_onPolygon() and test_deployExaFactory_deploysViaCreate3AtSameAddress_onPolygon().
Activity
  • No human activity has been recorded on this pull request yet.
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.

gemini-code-assist[bot]

This comment was marked as resolved.

@sentry
Copy link
Copy Markdown

sentry bot commented Mar 4, 2026

Codecov Report

❌ Patch coverage is 90.00000% with 9 lines in your changes missing coverage. Please review.
✅ Project coverage is 72.41%. Comparing base (8f7fa82) to head (dad0474).
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
contracts/script/Redeployer.s.sol 90.00% 9 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #865      +/-   ##
==========================================
+ Coverage   71.59%   72.41%   +0.81%     
==========================================
  Files         227      227              
  Lines        8217     8472     +255     
  Branches     2626     2740     +114     
==========================================
+ Hits         5883     6135     +252     
- Misses       2106     2115       +9     
+ Partials      228      222       -6     
Flag Coverage Δ
e2e 70.62% <90.00%> (+18.26%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

coderabbitai[bot]

This comment was marked as resolved.

@itofarina itofarina changed the title ⚡ contracts: avoid redundant stub deployments in redeployer 🔨 contracts: avoid redundant stub deployments Mar 4, 2026
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

♻️ Duplicate comments (1)
contracts/script/Redeployer.s.sol (1)

68-86: ⚠️ Potential issue | 🟠 Major

Guard and backfill all plugin dependencies, not just auditor.

Line 68 only backfills when auditor is zero, and Line 180 only validates auditor. If auditor is set but marketUSDC/marketWETH are zero, plugin deployment can fail at constructor-time with invalid markets.

🔧 Suggested fix
-    if (address(auditor) == address(0)) {
+    if (address(auditor) == address(0)) {
       auditor = IAuditor(
         CREATE3_FACTORY.deploy(keccak256(abi.encode("StubAuditor")), vm.getCode("Redeployer.s.sol:StubAuditor"))
       );
-      address stubAsset =
-        CREATE3_FACTORY.deploy(keccak256(abi.encode("StubAsset")), vm.getCode("Redeployer.s.sol:StubAsset"));
+    }
+
+    if (address(marketUSDC) == address(0) || address(marketWETH) == address(0)) {
+      address stubAsset = CREATE3_FACTORY.getDeployed(admin, keccak256(abi.encode("StubAsset")));
+      if (stubAsset.code.length == 0) {
+        stubAsset =
+          CREATE3_FACTORY.deploy(keccak256(abi.encode("StubAsset")), vm.getCode("Redeployer.s.sol:StubAsset"));
+      }
+
+      if (address(marketUSDC) == address(0)) {
+        address stubUSDC = CREATE3_FACTORY.getDeployed(admin, keccak256(abi.encode("StubMarketUSDC")));
+        marketUSDC = IMarket(
+          stubUSDC.code.length == 0
+            ? CREATE3_FACTORY.deploy(
+              keccak256(abi.encode("StubMarketUSDC")),
+              abi.encodePacked(vm.getCode("Redeployer.s.sol:StubMarket"), abi.encode(stubAsset))
+            )
+            : stubUSDC
+        );
+      }
+
+      if (address(marketWETH) == address(0)) {
+        address stubWETH = CREATE3_FACTORY.getDeployed(admin, keccak256(abi.encode("StubMarketWETH")));
+        marketWETH = IMarket(
+          stubWETH.code.length == 0
+            ? CREATE3_FACTORY.deploy(
+              keccak256(abi.encode("StubMarketWETH")),
+              abi.encodePacked(vm.getCode("Redeployer.s.sol:StubMarket"), abi.encode(stubAsset))
+            )
+            : stubWETH
+        );
+      }
-      marketUSDC = IMarket(
-        CREATE3_FACTORY.deploy(
-          keccak256(abi.encode("StubMarketUSDC")),
-          abi.encodePacked(vm.getCode("Redeployer.s.sol:StubMarket"), abi.encode(stubAsset))
-        )
-      );
-      marketWETH = IMarket(
-        CREATE3_FACTORY.deploy(
-          keccak256(abi.encode("StubMarketWETH")),
-          abi.encodePacked(vm.getCode("Redeployer.s.sol:StubMarket"), abi.encode(stubAsset))
-        )
-      );
     }
@@
-    if (address(auditor) == address(0)) revert NotPrepared();
+    if (address(auditor) == address(0) || address(marketUSDC) == address(0) || address(marketWETH) == address(0)) {
+      revert NotPrepared();
+    }

Also applies to: 179-180


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 6b9ddd18-4e44-47bb-b692-023871716822

📥 Commits

Reviewing files that changed from the base of the PR and between 6b4ddc7 and 31a5a09.

📒 Files selected for processing (4)
  • .changeset/bumpy-foxes-refuse.md
  • contracts/.gas-snapshot
  • contracts/script/Redeployer.s.sol
  • contracts/test/Redeployer.t.sol

@itofarina itofarina force-pushed the redeployer branch 2 times, most recently from 681ea16 to 478caf9 Compare March 4, 2026 21:06
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

♻️ Duplicate comments (1)
contracts/script/Redeployer.s.sol (1)

68-86: ⚠️ Potential issue | 🟠 Major

Harden readiness checks for partially resolved dependencies.

prepare() and _deployPlugins() gate on auditor only. If auditor is present but marketUSDC/marketWETH are not, deployment can fail later in ExaPlugin construction instead of reverting with NotPrepared().

🔧 Suggested fix
-    if (address(auditor).code.length == 0) {
+    if (address(auditor).code.length == 0) {
       auditor = IAuditor(
         CREATE3_FACTORY.deploy(keccak256(abi.encode("StubAuditor")), vm.getCode("Redeployer.s.sol:StubAuditor"))
       );
+    }
+    if (address(marketUSDC).code.length == 0 || address(marketWETH).code.length == 0) {
       address stubAsset =
         CREATE3_FACTORY.deploy(keccak256(abi.encode("StubAsset")), vm.getCode("Redeployer.s.sol:StubAsset"));
-      marketUSDC = IMarket(
-        CREATE3_FACTORY.deploy(
-          keccak256(abi.encode("StubMarketUSDC")),
-          abi.encodePacked(vm.getCode("Redeployer.s.sol:StubMarket"), abi.encode(stubAsset))
-        )
-      );
-      marketWETH = IMarket(
-        CREATE3_FACTORY.deploy(
-          keccak256(abi.encode("StubMarketWETH")),
-          abi.encodePacked(vm.getCode("Redeployer.s.sol:StubMarket"), abi.encode(stubAsset))
-        )
-      );
+      if (address(marketUSDC).code.length == 0) {
+        marketUSDC = IMarket(
+          CREATE3_FACTORY.deploy(
+            keccak256(abi.encode("StubMarketUSDC")),
+            abi.encodePacked(vm.getCode("Redeployer.s.sol:StubMarket"), abi.encode(stubAsset))
+          )
+        );
+      }
+      if (address(marketWETH).code.length == 0) {
+        marketWETH = IMarket(
+          CREATE3_FACTORY.deploy(
+            keccak256(abi.encode("StubMarketWETH")),
+            abi.encodePacked(vm.getCode("Redeployer.s.sol:StubMarket"), abi.encode(stubAsset))
+          )
+        );
+      }
     }
@@
-    if (address(auditor).code.length == 0) revert NotPrepared();
+    if (
+      address(auditor).code.length == 0
+        || address(marketUSDC).code.length == 0
+        || address(marketWETH).code.length == 0
+    ) revert NotPrepared();

Also applies to: 179-193


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 27201171-afe2-4d37-9f59-68bbbe95d8e4

📥 Commits

Reviewing files that changed from the base of the PR and between 31a5a09 and 478caf9.

📒 Files selected for processing (4)
  • .changeset/bumpy-foxes-refuse.md
  • contracts/.gas-snapshot
  • contracts/script/Redeployer.s.sol
  • contracts/test/Redeployer.t.sol

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

♻️ Duplicate comments (1)
contracts/script/Redeployer.s.sol (1)

179-193: ⚠️ Potential issue | 🟠 Major

Expand readiness guard to cover both markets.

_deployPlugins() currently guards only auditor, but it immediately consumes marketUSDC and marketWETH as constructor inputs. Missing market code can surface as an opaque low-level revert instead of NotPrepared.

🔧 Proposed fix
   function _deployPlugins(address admin) internal returns (IPlugin, IPlugin) {
-    if (address(auditor).code.length == 0) revert NotPrepared();
+    if (
+      address(auditor).code.length == 0 || address(marketUSDC).code.length == 0 || address(marketWETH).code.length == 0
+    ) revert NotPrepared();

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 7b34488d-6631-4754-8b0f-08ec0d9f6758

📥 Commits

Reviewing files that changed from the base of the PR and between 478caf9 and 88934db.

📒 Files selected for processing (4)
  • .changeset/bumpy-foxes-refuse.md
  • contracts/.gas-snapshot
  • contracts/script/Redeployer.s.sol
  • contracts/test/Redeployer.t.sol

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
contracts/script/Redeployer.s.sol (1)

90-103: ⚠️ Potential issue | 🟡 Minor

run() NatSpec says exclusive nonce, but implementation is inclusive.

The parameter docs and loop behavior diverge (<= targetNonce). Please make these consistent to prevent incorrect caller assumptions.

📝 Minimal fix (doc alignment)
-  /// `@param` targetNonce The nonce to stop at (exclusive)
+  /// `@param` targetNonce The nonce to stop at (inclusive)
♻️ Duplicate comments (1)
contracts/script/Redeployer.s.sol (1)

68-86: ⚠️ Potential issue | 🟠 Major

NotPrepared can be skipped while markets are still unresolved.

prepare() backfills stubs only when auditor is missing, and _deployPlugins() only validates auditor. If auditor resolves but marketUSDC/marketWETH do not, plugin deployment can fail with a low-level revert instead of NotPrepared, and prepare() won’t repair that state.

🔧 Suggested fix
-    if (address(auditor).code.length == 0) {
+    if (address(auditor).code.length == 0) {
       auditor = IAuditor(
         CREATE3_FACTORY.deploy(keccak256(abi.encode("StubAuditor")), vm.getCode("Redeployer.s.sol:StubAuditor"))
       );
-      address stubAsset =
-        CREATE3_FACTORY.deploy(keccak256(abi.encode("StubAsset")), vm.getCode("Redeployer.s.sol:StubAsset"));
+    }
+
+    if (address(marketUSDC).code.length == 0 || address(marketWETH).code.length == 0) {
+      address stubAsset = CREATE3_FACTORY.getDeployed(admin, keccak256(abi.encode("StubAsset")));
+      if (stubAsset.code.length == 0) {
+        stubAsset = CREATE3_FACTORY.deploy(keccak256(abi.encode("StubAsset")), vm.getCode("Redeployer.s.sol:StubAsset"));
+      }
+      if (address(marketUSDC).code.length == 0) {
       marketUSDC = IMarket(
         CREATE3_FACTORY.deploy(
           keccak256(abi.encode("StubMarketUSDC")),
           abi.encodePacked(vm.getCode("Redeployer.s.sol:StubMarket"), abi.encode(stubAsset))
         )
       );
+      }
+      if (address(marketWETH).code.length == 0) {
       marketWETH = IMarket(
         CREATE3_FACTORY.deploy(
           keccak256(abi.encode("StubMarketWETH")),
           abi.encodePacked(vm.getCode("Redeployer.s.sol:StubMarket"), abi.encode(stubAsset))
         )
       );
+      }
     }
@@
-    if (address(auditor).code.length == 0) revert NotPrepared();
+    if (address(auditor).code.length == 0 || address(marketUSDC).code.length == 0 || address(marketWETH).code.length == 0) {
+      revert NotPrepared();
+    }

Also applies to: 179-193


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: ad9fb905-5aa6-418a-9507-a42a5b07c847

📥 Commits

Reviewing files that changed from the base of the PR and between 88934db and c3afa7e.

📒 Files selected for processing (3)
  • contracts/.gas-snapshot
  • contracts/script/Redeployer.s.sol
  • contracts/test/Redeployer.t.sol

@itofarina itofarina changed the title 🔨 contracts: avoid redundant stub deployments 🔨 contracts: avoid redundant deployments Mar 5, 2026
@itofarina itofarina force-pushed the redeployer branch 5 times, most recently from 76965b3 to 7789af5 Compare March 11, 2026 20:55
@itofarina itofarina force-pushed the redeployer branch 2 times, most recently from 9345b59 to 13997b4 Compare March 12, 2026 20:24
@itofarina itofarina marked this pull request as ready for review March 12, 2026 20:25
@itofarina itofarina requested a review from cruzdanilo as a code owner March 12, 2026 20:25
devin-ai-integration[bot]

This comment was marked as resolved.

chatgpt-codex-connector[bot]

This comment was marked as resolved.

coderabbitai[bot]

This comment was marked as resolved.

coderabbitai[bot]

This comment was marked as resolved.

chatgpt-codex-connector[bot]

This comment was marked as resolved.

chatgpt-codex-connector[bot]

This comment was marked as resolved.

devin-ai-integration[bot]

This comment was marked as resolved.

coderabbitai[bot]

This comment was marked as resolved.

@itofarina itofarina force-pushed the redeployer branch 2 times, most recently from 78d7b91 to 449ada9 Compare March 27, 2026 17:03
chatgpt-codex-connector[bot]

This comment was marked as resolved.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
contracts/script/Redeployer.s.sol (1)

205-224: 🧹 Nitpick | 🔵 Trivial

Consider adding ownerPlugin to the NotPrepared check.

Line 210 only verifies exaPlugin.code.length, but line 219 also uses ownerPlugin in the factory constructor. While the intended flow (prepare() deploys ownerPlugin before exaPlugin) should guarantee both are available, an explicit check would make the invariant clearer and prevent misuse.

🔧 Suggested improvement
   function deployExaFactory(string calldata version) external returns (ExaAccountFactory f) {
     bytes32 salt = keccak256(abi.encode("Exa Plugin", version));
     f = ExaAccountFactory(payable(CREATE3_FACTORY.getDeployed(acct("admin"), salt)));
     if (address(f).code.length != 0) return f;
-    if (address(exaPlugin).code.length == 0) revert NotPrepared();
+    if (address(ownerPlugin).code.length == 0 || address(exaPlugin).code.length == 0) revert NotPrepared();

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: ac128abc-2a58-4311-946b-ef16e079f4d3

📥 Commits

Reviewing files that changed from the base of the PR and between 78d7b91 and 449ada9.

📒 Files selected for processing (4)
  • .changeset/bumpy-foxes-refuse.md
  • contracts/.gas-snapshot
  • contracts/script/Redeployer.s.sol
  • contracts/test/Redeployer.t.sol

coderabbitai[bot]

This comment was marked as resolved.

chatgpt-codex-connector[bot]

This comment was marked as resolved.

coderabbitai[bot]

This comment was marked as resolved.

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: dad0474b7c

ℹ️ About Codex in GitHub

Codex has been enabled to automatically 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 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

♻️ Duplicate comments (1)
contracts/script/Redeployer.s.sol (1)

148-150: 🧹 Nitpick | 🔵 Trivial

Consider using ProposalManager.PROPOSER_ROLE constant.

The inline keccak256("PROPOSER_ROLE") works but is less maintainable. ProposalManager already exposes this as a public constant.

♻️ Suggested improvement
-    if (!ProposalManager(proposalManagerAddr).hasRole(keccak256("PROPOSER_ROLE"), address(exaPlugin))) {
-      ProposalManager(proposalManagerAddr).grantRole(keccak256("PROPOSER_ROLE"), address(exaPlugin));
+    ProposalManager pm = ProposalManager(proposalManagerAddr);
+    if (!pm.hasRole(pm.PROPOSER_ROLE(), address(exaPlugin))) {
+      pm.grantRole(pm.PROPOSER_ROLE(), address(exaPlugin));
     }

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: e21e6346-9d52-44dc-b3b4-6ec268b11725

📥 Commits

Reviewing files that changed from the base of the PR and between 26eefc4 and dad0474.

📒 Files selected for processing (4)
  • .changeset/bumpy-foxes-refuse.md
  • contracts/.gas-snapshot
  • contracts/script/Redeployer.s.sol
  • contracts/test/Redeployer.t.sol

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