Skip to content

Fix: Resolve Deployment Issues #751

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 4 commits into
base: dev
Choose a base branch
from
Draft

Conversation

marvinkruse
Copy link
Member

@marvinkruse marvinkruse commented May 20, 2025

This PR aims to address the following issues:

  • Consistent Module Deployment Addresses (not just for the Orchestrator) that can't be disturbed by others deploying workflows
    • This new variant bases the module's address on the address of the caller (which is the orchestrator factory, so even if someone just calls the module factory directly, it won't matter), the address of the orchestrator attached to it, and a nonce
    • This way it's unique to the actual user doing the deployment and can't be sniped/disturbed
    • There was an earlier PR that tried to fix this, too, but this solution should be way better.
  • Allows users to deploy and initialize/configure external contracts via the orchestrator factory
    • Main reason and idea: multicalls are only possible if you interact with our contracts, so deploying the issuance token is a problem. This fixes it, as you can deploy it and set it up all within the same call, but still keeps the factory's contract size low.

⚠️ Current issues: The external contract deployment function opens the contract up to a potential vulnerability in its current form, allowing you to facilitate contract calls on behalf of the orchestrator factory. We are just using this to test the frontend multicall capabilities for now and unblock them, but this needs a fix/solution before we release it to any "real" network


Below is the GitHub AI summary of the changes, be wary

This pull request introduces changes to enhance the deployment logic for CREATE2-based flows, improve nonce handling, and add support for deploying external contracts. It also includes a new test to validate the external contract deployment functionality. Below is a breakdown of the most important changes:

Enhancements to CREATE2-based deployment logic:

  • Updated _deploymentNonces mapping in ModuleFactory_v1 to use a hash of the caller's address and orchestrator address as the key, improving nonce uniqueness. (src/factories/ModuleFactory_v1.sol, src/factories/ModuleFactory_v1.solL115-R118)
  • Modified _createSalt function to generate a salt using the hash of the caller's address and orchestrator, ensuring better handling of orchestrator-specific deployments. (src/factories/ModuleFactory_v1.sol, src/factories/ModuleFactory_v1.solL289-R302)
  • Updated proxy creation logic to pass the orchestrator address to _createSalt, aligning with the new salt generation approach. (src/factories/ModuleFactory_v1.sol, src/factories/ModuleFactory_v1.solL212-R226)

Support for external contract deployment:

New test for external contract deployment:

@marvinkruse marvinkruse self-assigned this May 20, 2025
Copy link

@Copilot 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 refines the deployment logic to ensure module addresses remain unique and secure while also enabling external contract deployment with initialization calls in a single transaction.

  • Updated CREATE2-based deployment logic in ModuleFactory_v1 with improved salt generation.
  • Introduced external contract deployment in OrchestratorFactory_v1 with support for subsequent initialization calls.
  • Added a new unit test in OrchestratorFactoryV1Test to validate external contract deployment and post-deployment behavior.

Reviewed Changes

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

File Description
test/unit/factories/OrchestratorFactory_v1.t.sol Added a unit test for external contract deployment and event expectations.
src/factories/OrchestratorFactory_v1.sol Introduced deployExternalContract using CREATE2 and post-deployment calls.
src/factories/ModuleFactory_v1.sol Modified salt generation to improve nonce uniqueness using orchestrator address.

{
deploymentAddress = Create2.deploy(0, _createSalt(), code);
for (uint i; i < calls.length; ++i) {
(bool success,) = deploymentAddress.call(calls[i]);
Copy link
Preview

Copilot AI May 20, 2025

Choose a reason for hiding this comment

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

Consider adding reentrancy protection or employing a checks-effects-interactions pattern for the external calls to mitigate potential security vulnerabilities, especially in production scenarios.

Copilot uses AI. Check for mistakes.

Copy link
Member Author

@marvinkruse marvinkruse May 20, 2025

Choose a reason for hiding this comment

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

Yeah, that's exactly what I mentioned above. Will add something for this once we verified whether this works at all and is a good solution.

Copy link
Member Author

@marvinkruse marvinkruse May 20, 2025

Choose a reason for hiding this comment

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

@fabianschu and @FHieser: have some ideas to prevent abuse here? I just have one idea atm which is to have a list of allowed bytecode hashes that can be deployed via this (i.e. the 4 issuance token versions we have), so no one can build an exploiter contract (which would be annoying, as we'd need to whitelist them each every time there is something new, but doable).
Any other cool ideas? Or would a regular reentrancy-protection work already. I'm a bit concerned that users may be able to call other contracts "as the orchestrator factory" but not sure if it's being too careful atm.

Copy link
Contributor

Choose a reason for hiding this comment

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

Not directly abuse, but we had some assumptions in the past regarding "What users will expect when they see a contract that was deployed via our factories". We never defined this properly, but one might argue that if contracts can be freely deployed via our factories it might give the feeling of "Yes this is a Inverter contract" which might be misleading.
Correct me but the purpose of this function is to salt deploy Token contracts or Singletons that are needed for a workflow correct?
As they are technically not modules I would be against just slapping this function in here.
Instead I would propose to do it in a library style deployment similar to the modulefactory but for singletons. That way we can restrict what users can deploy and ensure the quality of deployments in the first place. The deployments also can happen via Clones then too making them way cheaper.

@marvinkruse
Copy link
Member Author

@FHieser @fabianschu just tagging you for a review, this isn't "done" yet, as you can see in the warning, but the idea would be to get some feedback in general before I continue on this. Please reach out to me if you need any information.

Copy link
Contributor

@FHieser FHieser left a comment

Choose a reason for hiding this comment

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

I would like to see a proper E2E test on this.

{
deploymentAddress = Create2.deploy(0, _createSalt(), code);
for (uint i; i < calls.length; ++i) {
(bool success,) = deploymentAddress.call(calls[i]);
Copy link
Contributor

Choose a reason for hiding this comment

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

Not directly abuse, but we had some assumptions in the past regarding "What users will expect when they see a contract that was deployed via our factories". We never defined this properly, but one might argue that if contracts can be freely deployed via our factories it might give the feeling of "Yes this is a Inverter contract" which might be misleading.
Correct me but the purpose of this function is to salt deploy Token contracts or Singletons that are needed for a workflow correct?
As they are technically not modules I would be against just slapping this function in here.
Instead I would propose to do it in a library style deployment similar to the modulefactory but for singletons. That way we can restrict what users can deploy and ensure the quality of deployments in the first place. The deployments also can happen via Clones then too making them way cheaper.

/// @dev Maps the hash of the callers address and the corresponding
/// orchestrator address to a nonce used for the create2-based
/// deployment.
mapping(bytes32 => uint) private _deploymentNonces;
Copy link
Contributor

Choose a reason for hiding this comment

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

Does this change the storage layout in any way?

Copy link
Member Author

Choose a reason for hiding this comment

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

So, mapping storage works in the sense that the slot/address where this mapping is and the key(s) of the mapping are used to determine the storage address of the value stored. So, in general, this is just one storage slot in terms of the order that we have. As I changed the key from address to bytes32, it's basically generating totally new storage locations, and there won't be any overlap.

So short form: This is fine and doesn't change the layout in any way. There are also no "old" values in there.

@marvinkruse
Copy link
Member Author

I would like to see a proper E2E test on this.

Yeah, I know! Will be done after we confirmed that the solution works 🤝

@FHieser
Copy link
Contributor

FHieser commented May 20, 2025

Damn just saw Mehmets solution.
My first expectation was that the frontend integration has to calculate all the salts and end addresses,
but with the simulation he just skips everything on that which is so clean. <3

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