Skip to content

Commit

Permalink
Feature(v1.4.1): Zksync compatibility (#840)
Browse files Browse the repository at this point in the history
This PR "backmerges" the zksync compatibility from `main` to the `1.4.1`
release branch.

Backmerge is quoted because it turned out to be much more complicated
and led to more significant changes, such as:
- 1.4.1 was still using ethers v5, zksync plugins require ethers v6, so
I had to migrate the ethers version used in the project (I didn't
migrate it per se; I just used the `test` and `src` folders from the
`main` branch, minus the 1.5.0 changes)
- I migrated the project from `yarn` to `npm` because when I
cherry-picked from main, which uses npm, it was easier to do so rather
than sticking to `yarn`
- backmerging also led to discovering certain issues that were fixed in
`main`, such as broken benchmark on the CI when the compiler version
`0.8.2` is used and node version v16 being unsupported by hardhat
anymore

**TL:DR**
This PR is a 1.4.1 release with 1.5.0 tests, javascript utilities and
hardhat env, minus changes introduced in 1.5.0.

**How I tested the PR**:
- I made sure no changes were made to the contracts and checking that
they're still deployed to expected v1.4.1 addresses
- I ran zkSync test suite and deployed the contracts to zksync sepolia.
Proof of deployment:
```
> @safe-global/safe-smart-account@1.4.1-build.0 deploy-all
> hardhat deploy-contracts --network zkSyncSepolia

Yul codegen is only supported for solc >= 0.8. Flag forceEVMLA will automatically be set to true by default.
Yul codegen is only supported for solc >= 0.8. Flag forceEVMLA will automatically be set to true by default.
Nothing to compile
No need to generate any newer typings.
reusing "SimulateTxAccessor" at 0xdd35026932273768A3e31F4efF7313B5B7A7199d
reusing "SafeProxyFactory" at 0xc329D02fd8CB2fc13aa919005aF46320794a8629
reusing "TokenCallbackHandler" at 0xd508168Db968De1EBc6f288322e6C820137eeF79
reusing "CompatibilityFallbackHandler" at 0x9301E98DD367135f21bdF66f342A249c9D5F9069
reusing "CreateCall" at 0xAAA566Fe7978bB0fb0B5362B7ba23038f4428D8f
reusing "MultiSend" at 0x309D0B190FeCCa8e1D5D8309a16F7e3CB133E885
reusing "MultiSendCallOnly" at 0x0408EF011960d02349d50286D20531229BCef773
reusing "SignMessageLib" at 0xAca1ec0a1A575CDCCF1DC3d5d296202Eb6061888
reusing "SafeToL2Setup" at 0x199A9df0224031c20Cc27083A4164c9c8F1Bcb39
reusing "Safe" at 0xC35F063962328aC65cED5D4c3fC5dEf8dec68dFa
reusing "SafeL2" at 0x610fcA2e0279Fa1F8C00c8c2F71dF522AD469380
reusing "SafeToL2Migration" at 0xa26620d1f8f1a2433F0D25027F141aaCAFB3E590
reusing "SafeMigration" at 0x817756C6c555A94BCEE39eB5a102AbC1678b09A7
```

After the PR is merged and reviewed, I'll add the expected zkSync
addresses to the changelog.
  • Loading branch information
mmv08 authored Oct 1, 2024
1 parent aa14911 commit 0440046
Show file tree
Hide file tree
Showing 81 changed files with 15,333 additions and 13,132 deletions.
12 changes: 12 additions & 0 deletions .env.sample
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,17 @@ ERC4337_TEST_BUNDLER_URL=
ERC4337_TEST_NODE_URL=
ERC4337_TEST_SINGLETON_ADDRESS=
ERC4337_TEST_SAFE_FACTORY_ADDRESS=
# (Optional) Tells the test runner which Safe Singleton Contract to use for testing: Safe or SafeL2. Defaults to Safe.
SAFE_CONTRACT_UNDER_TEST="Safe"
# Used for compiling with different solidity testing
# Example: '0.8.19'
SOLIDITY_VERSION=
# For running coverage tests, `details` section of solidity settings are required, else could be removed.
# Example: '{"viaIR":true,"optimizer":{"enabled":true, "details": {"yul": true, "yulDetails": { "optimizerSteps": ""}}}}'
SOLIDITY_SETTINGS=
# Set to 1 to run hardhat in zksync mode. This will enable the ZK compiler and run the hardhat node in zksync mode.
HARDHAT_ENABLE_ZKSYNC=0
# Sets hardhat chain id. In general, you don't need this, it's only used for testing the SafeToL2Setup contract.
HARDHAT_CHAIN_ID=31337
# (Optional) Hardhat-deploy only supports zksync deployment if the private key for the account is provided. Specify the private key here.
ZKSYNC_DEPLOYER_PK="0x7726827caac94a7f9e1b160f7ea819f172f7b6f9d2a97f992c38edeab82d4110"
53 changes: 31 additions & 22 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,18 @@ on: [push, pull_request]

jobs:
tests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: "npm"
- run: npm ci
- run: npm run build
- run: npm run test

coverage:
runs-on: ubuntu-latest
strategy:
fail-fast: false
Expand All @@ -11,14 +23,14 @@ jobs:
env:
SAFE_CONTRACT_UNDER_TEST: ${{ matrix.contract-name }}
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: "yarn"
- run: yarn --frozen-lockfile
- run: yarn build
- run: yarn coverage
cache: "npm"
- run: npm ci
- run: npm run build
- run: npm run coverage
- name: Send coverage to Coveralls (parallel)
uses: coverallsapp/github-action@v2
with:
Expand All @@ -43,33 +55,30 @@ jobs:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
node-version: 16.7.0
- uses: actions/cache@v2
with:
path: "**/node_modules"
key: ${{ runner.os }}-modules-${{ hashFiles('**/yarn.lock') }}
- run: yarn --frozen-lockfile
- run: yarn lint:sol
node-version: 20.10.0
cache: "npm"
- run: npm ci
- run: npm run lint:sol

benchmarks:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
solidity: ["0.7.6", "0.8.2"]
solidity: ["0.7.6", "0.8.24"]
include:
- solidity: "0.8.2"
settings: '{"viaIR":true,"optimizer":{"enabled":true,"runs":10000}}'
- solidity: "0.8.24"
settings: '{"viaIR":false,"optimizer":{"enabled":true,"runs":1000000}}'
env:
SOLIDITY_VERSION: ${{ matrix.solidity }}
SOLIDITY_SETTINGS: ${{ matrix.settings }}
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
node-version: 16.7.0
- uses: actions/cache@v2
with:
path: "**/node_modules"
key: ${{ runner.os }}-modules-${{ hashFiles('**/yarn.lock') }}
- run: (yarn --frozen-lockfile && yarn build && yarn hardhat codesize --contractname Safe && yarn benchmark) || echo "Benchmark failed"
node-version: 20.10.0
cache: "npm"
- run: npm ci
- run: npm run build
- run: npm run codesize -- --contractname Safe
- run: npm run benchmark
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ coverage/
coverage.json
yarn-error.log
.vscode
typechain-types
era_test_node.log

# Certora Formal Verification related files
.certora_internal
Expand Down
3 changes: 0 additions & 3 deletions .husky/pre-commit
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"

# Redirect output to stderr.
exec 1>&2

Expand Down
2 changes: 1 addition & 1 deletion .nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v16.7.0
v20.10.0
1 change: 1 addition & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{
"plugins": ["prettier-plugin-solidity"],
"overrides": [
{
"files": "*.sol",
Expand Down
84 changes: 43 additions & 41 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,27 +1,26 @@
Safe Contracts
==============
# Safe Contracts

[![npm version](https://badge.fury.io/js/%40gnosis.pm%2Fsafe-contracts.svg)](https://badge.fury.io/js/%40gnosis.pm%2Fsafe-contracts)
[![Build Status](https://github.com/safe-global/safe-contracts/workflows/safe-contracts/badge.svg?branch=development)](https://github.com/safe-global/safe-contracts/actions)
[![Coverage Status](https://coveralls.io/repos/github/safe-global/safe-contracts/badge.svg?branch=development)](https://coveralls.io/github/safe-global/safe-contracts)

> :warning: **This branch contains changes that are under development** To use the latest audited version make sure to use the correct commit. The tagged versions that are used by the Safe team can be found in the [releases](https://github.com/safe-global/safe-contracts/releases).
Usage
-----
### Install requirements with yarn:
## Usage

### Install requirements with npm:

```bash
yarn
npm i
```

### Testing

To run the tests:

```bash
yarn build
yarn test
npm run build
npm run test
```

Optionally, if you want to run the ERC-4337 compatibility test, it uses a live bundler and node, so it contains some pre-requisites:
Expand All @@ -42,7 +41,7 @@ MNEMONIC=

A collection of the different Safe contract deployments and their addresses can be found in the [Safe deployments](https://github.com/safe-global/safe-deployments) repository.

To add support for a new network follow the steps of the ``Deploy`` section and create a PR in the [Safe deployments](https://github.com/safe-global/safe-deployments) repository.
To add support for a new network follow the steps of the `Deploy` section and create a PR in the [Safe deployments](https://github.com/safe-global/safe-deployments) repository.

### Deploy

Expand All @@ -53,72 +52,75 @@ To add support for a new network follow the steps of the ``Deploy`` section and
This will deploy the contracts deterministically and verify the contracts on etherscan using [Solidity 0.7.6](https://github.com/ethereum/solidity/releases/tag/v0.7.6) by default.

Preparation:
- Set `MNEMONIC` in `.env`
- Set `INFURA_KEY` in `.env`

- Set `MNEMONIC` in `.env`
- Set `INFURA_KEY` in `.env`

```bash
yarn deploy-all <network>
npm run deploy-all <network>
```

This will perform the following steps

```bash
yarn build
yarn hardhat --network <network> deploy
yarn hardhat --network <network> sourcify
yarn hardhat --network <network> etherscan-verify
yarn hardhat --network <network> local-verify
npm run build
npm run hardhat --network <network> deploy
npm run hardhat --network <network> sourcify
npm run hardhat --network <network> etherscan-verify
npm run hardhat --network <network> local-verify
```

#### Custom Networks

It is possible to use the `NODE_URL` env var to connect to any EVM based network via an RPC endpoint. This connection then can be used with the `custom` network.

E.g. to deploy the Safe contract suite on that network you would run `yarn deploy-all custom`.
E.g. to deploy the Safe contract suite on that network you would run `npm run deploy-all custom`.

The resulting addresses should be on all networks the same.

Note: Address will vary if contract code is changed or a different Solidity version is used.

#### Replay protection (EIP-155)

Some networks require replay protection, making it incompatible with the default deployment process as it relies on a presigned transaction without replay protection (see https://github.com/Arachnid/deterministic-deployment-proxy).
Some networks require replay protection, making it incompatible with the default deployment process as it relies on a presigned transaction without replay protection (see https://github.com/Arachnid/deterministic-deployment-proxy).

Safe Smart Account contracts use a different deterministic deployment proxy (https://github.com/safe-global/safe-singleton-factory). To make sure that the latest version of this package is installed, run `yarn add -D @safe-global/safe-singleton-factory` before deployment. For more information, including deploying the factory to a new network, please refer to the factory repo.
Safe Smart Account contracts use a different deterministic deployment proxy (https://github.com/safe-global/safe-singleton-factory). To make sure that the latest version of this package is installed, run `npm i -D @safe-global/safe-singleton-factory` before deployment. For more information, including deploying the factory to a new network, please refer to the factory repo.

Note: This will result in different addresses compared to hardhat's default deterministic deployment process.

### Verify contract

This command will use the deployment artifacts to compile the contracts and compare them to the onchain code

```bash
yarn hardhat --network <network> local-verify
npx hardhat --network <network> local-verify
```

This command will upload the contract source to Etherescan

```bash
yarn hardhat --network <network> etherscan-verify
npx hardhat --network <network> etherscan-verify
```

Documentation
-------------
- [Safe developer portal](http://docs.safe.global)
- [Error codes](docs/error_codes.md)
- [Coding guidelines](docs/guidelines.md)

Audits/ Formal Verification
---------
- [for Version 1.4.0/1.4.1 by Ackee Blockchain](docs/audit_1_4_0.md)
- [for Version 1.3.0 by G0 Group](docs/audit_1_3_0.md)
- [for Version 1.2.0 by G0 Group](docs/audit_1_2_0.md)
- [for Version 1.1.1 by G0 Group](docs/audit_1_1_1.md)
- [for Version 1.0.0 by Runtime Verification](docs/rv_1_0_0.md)
- [for Version 0.0.1 by Alexey Akhunov](docs/alexey_audit.md)

Security and Liability
----------------------
## Documentation

- [Safe developer portal](http://docs.safe.global)
- [Error codes](docs/error_codes.md)
- [Coding guidelines](docs/guidelines.md)

## Audits/ Formal Verification

- [for Version 1.4.0/1.4.1 by Ackee Blockchain](docs/audit_1_4_0.md)
- [for Version 1.3.0 by G0 Group](docs/audit_1_3_0.md)
- [for Version 1.2.0 by G0 Group](docs/audit_1_2_0.md)
- [for Version 1.1.1 by G0 Group](docs/audit_1_1_1.md)
- [for Version 1.0.0 by Runtime Verification](docs/rv_1_0_0.md)
- [for Version 0.0.1 by Alexey Akhunov](docs/alexey_audit.md)

## Security and Liability

All contracts are WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

License
-------
## License

All smart contracts are released under LGPL-3.0
13 changes: 6 additions & 7 deletions benchmark/Safe.Creation.spec.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import "@nomiclabs/hardhat-ethers";
import { setupBenchmarkContracts } from "./utils/setup"
import { setupBenchmarkContracts } from "./utils/setup";

const contractSetup = setupBenchmarkContracts(undefined, true)
describe("Safe", async () => {
const contractSetup = setupBenchmarkContracts(undefined, true);
describe("Safe", () => {
it("creation", async () => {
await contractSetup()
})
})
await contractSetup();
});
});
53 changes: 27 additions & 26 deletions benchmark/Safe.ERC1155.spec.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,30 @@
import { expect } from "chai";
import { waffle, ethers } from "hardhat";
import "@nomiclabs/hardhat-ethers";
import { ethers } from "hardhat";
import { BigNumberish } from "ethers";
import { buildSafeTransaction } from "../src/utils/execution";
import { BigNumber } from "ethers";
import { benchmark, Contracts } from "./utils/setup"
import { benchmark, Contracts } from "./utils/setup";

const [, , , , user5] = waffle.provider.getWallets();

benchmark("ERC1155", [{
name: "transfer",
prepare: async (contracts: Contracts, target: string, nonce: number) => {
const token = contracts.additions.token
await token.mint(target, 23, 1337, "0x")
const data = token.interface.encodeFunctionData("safeTransferFrom", [target, user5.address, 23, 500, "0x"])
return buildSafeTransaction({ to: token.address, data, safeTxGas: 1000000, nonce })
},
after: async (contracts: Contracts) => {
expect(
await contracts.additions.token.balanceOf(user5.address, 23)
).to.be.deep.eq(BigNumber.from(500))
},
fixture: async () => {
const tokenFactory = await ethers.getContractFactory("ERC1155Token")
return {
token: await tokenFactory.deploy()
}
}
}])
benchmark("ERC1155", async () => {
const [, , , , user5] = await ethers.getSigners();
return [
{
name: "transfer",
prepare: async (contracts: Contracts, target: string, nonce: BigNumberish) => {
const token = contracts.additions.token;
const tokenAddress = await token.getAddress();
await token.mint(target, 23, 1337, "0x");
const data = token.interface.encodeFunctionData("safeTransferFrom", [target, user5.address, 23, 500, "0x"]);
return buildSafeTransaction({ to: tokenAddress, data, safeTxGas: 1000000, nonce });
},
after: async (contracts: Contracts) => {
expect(await contracts.additions.token.balanceOf(user5.address, 23)).to.eq(500n);
},
fixture: async () => {
const tokenFactory = await ethers.getContractFactory("ERC1155Token");
return {
token: await tokenFactory.deploy(),
};
},
},
];
});
Loading

0 comments on commit 0440046

Please sign in to comment.