safe-global / safe-smart-account

Safe allows secure management of blockchain assets.
https://safe.global
GNU Lesser General Public License v3.0
1.84k stars 907 forks source link

Add Safe to L2 Setup Contract #759

Closed nlordell closed 2 months ago

nlordell commented 4 months ago

This PR introduces a setup contract that can be called from the Safe setup function in order to automatically promote a Safe at setup time if the code is executing on an L2. Namely, this allows the Safe Proxy factory to use a single singleton and initializer for all chains, but end up with different singletons depending on the chain ID.

The expected use of this contract is to use the standard proxy factory:

Safe l1Singleton;
SafeL2 l2Singleton;
SafeToL2Setup l2Setup;

proxyFactory.createProxyWithNonce(
    address(l1Singleton),
    abi.encodeCall(
        l1Singleton.setup,
        (
            owners,
            threshold,
            address(l2Setup),
            abi.encodeCall(l2Setup.setupToL2, address(l2Singleton)),
            fallbackHandler,
            paymentToken,
            payment,
            paymentReceiver
        )
    ),
    saltNonce
)

On L1 (i.e. Ethereum Mainnet where chainId == 1), you would end up with a Safe where safe.singleton == l1Singleton and on any other chains, you would end up with safe.singleton == l2Singleton. This would happen before the first transaction.

coveralls commented 4 months ago

Pull Request Test Coverage Report for Build 9780086819

Details


Totals Coverage Status
Change from base Build 9710052157: 0.1%
Covered Lines: 400
Relevant Lines: 412

💛 - Coveralls
Sulthanmh commented 2 months ago

Yes

On Tue, 2 Jul 2024 at 7:36 PM Nicholas Rodrigues Lordello < @.***> wrote:

@.**** commented on this pull request.

In test/libraries/SafeToL2Setup.spec.ts https://github.com/safe-global/safe-smart-account/pull/759#discussion_r1662761551 :

  • ethers.ZeroAddress,
  • 0,
  • ethers.ZeroAddress,
  • ]);
  • const safeAddress = await proxyFactory.createProxyWithNonce.staticCall(safeSingleton.target, setupData, 0);
  • await expect(proxyFactory.createProxyWithNonce(safeSingleton.target, setupData, 0))
  • .to.emit(safeToL2SetupLib.attach(safeAddress), "ChangedSingleton")
  • .withArgs(safeL2SingletonAddress);
  • });
  • it("can be used only via DELEGATECALL opcode", async () => {
  • const { safeToL2SetupLib } = await setupTests();
  • const randomAddress = ethers.hexlify(ethers.randomBytes(20));
  • await expect(safeToL2SetupLib.setupToL2(randomAddress)).to.be.rejectedWith("GS900");

We should document this new error code somewhere.

— Reply to this email directly, view it on GitHub https://github.com/safe-global/safe-smart-account/pull/759#pullrequestreview-2154212132, or unsubscribe https://github.com/notifications/unsubscribe-auth/BJI7R6NXRKJJDZHB3YDXLH3ZKLCGLAVCNFSM6AAAAABHLCGTV2VHI2DSMVQWIX3LMV43YUDVNRWFEZLROVSXG5CSMV3GSZLXHMZDCNJUGIYTEMJTGI . You are receiving this because you commented.Message ID: @.***>