Skip to content

Commit bdbab4c

Browse files
feat: add contracts (#22)
1 parent da8ebf8 commit bdbab4c

File tree

148 files changed

+29773
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

148 files changed

+29773
-0
lines changed

.env.example

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
### NOTE: DO NOT USE THIS FILE IF USING TESTNET'S .ENV
2+
ETHERSCAN_API_KEY=ABC123ABC123ABC123ABC123ABC123ABC1
3+
4+
RINKEBY_RPC=https://eth-rinkeby.alchemyapi.io/v2/<YOUR ALCHEMY KEY>
5+
SCROLL_L1_RPC=https://prealpha.scroll.io/l1
6+
SCROLL_L2_RPC=https://prealpha.scroll.io/l2
7+
8+
RINKEBY_PRIVATE_KEY=0xabc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc1
9+
L1_DEPLOYER_PRIVATE_KEY=0xabc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc1
10+
L2_DEPLOYER_PRIVATE_KEY=0xabc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc1
11+
12+
CHAIN_ID_L2="5343541"

.eslintignore

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
node_modules
2+
artifacts
3+
cache
4+
coverage

.eslintrc.js

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
module.exports = {
2+
env: {
3+
browser: false,
4+
es2021: true,
5+
mocha: true,
6+
node: true,
7+
},
8+
plugins: ["@typescript-eslint"],
9+
extends: [
10+
"standard",
11+
"plugin:prettier/recommended",
12+
"plugin:node/recommended",
13+
],
14+
parser: "@typescript-eslint/parser",
15+
parserOptions: {
16+
ecmaVersion: 12,
17+
},
18+
rules: {
19+
"node/no-unsupported-features/es-syntax": [
20+
"error",
21+
{ ignores: ["modules"] },
22+
],
23+
},
24+
};

.gitignore

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
node_modules
2+
.env
3+
coverage
4+
coverage.json
5+
typechain
6+
7+
# Hardhat/Foundry files
8+
cache
9+
cache-hardhat
10+
artifacts
11+
12+
# logs
13+
*.log
14+
15+
# eslint
16+
.eslintcache

.husky/pre-commit

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
#!/usr/bin/env sh
2+
. "$(dirname -- "$0")/_/husky.sh"
3+
4+
yarn lint-staged && forge build && npx hardhat compile

.npmignore

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
hardhat.config.ts
2+
scripts
3+
test

.prettierignore

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
node_modules
2+
artifacts
3+
cache
4+
coverage*
5+
gasReporterOutput.json

.prettierrc

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"printWidth": 120,
3+
"singleQuote": false,
4+
"tabWidth": 2,
5+
"bracketSpacing": true
6+
}

.solhint.json

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"extends": "solhint:recommended",
3+
"rules": {
4+
"compiler-version": ["error", "^0.8.0"],
5+
"func-visibility": ["warn", { "ignoreConstructors": true }]
6+
}
7+
}

.solhintignore

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
node_modules

README.md

+74
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
# Scroll Contracts
2+
3+
## Directory Structure
4+
5+
```
6+
integration-test
7+
|- xxx.test.ts - "Hardhat integration tests"
8+
lib
9+
|- forge-std - "foundry dependency"
10+
scripts
11+
|- deploy.ts - "hardhat deploy script"
12+
src
13+
|- test
14+
| `- xxx.t.sol - "Unit testi in solidity"
15+
`- xxx.sol - "solidity contract"
16+
.gitmodules - "foundry dependecy modules"
17+
foundry.toml - "configure foundry"
18+
hardhat.config.ts - "configure hardhat"
19+
remappings.txt - "foundry dependency mappings"
20+
...
21+
```
22+
23+
## Dependency
24+
25+
### Foundry
26+
27+
First run the command below to get foundryup, the Foundry toolchain installer:
28+
29+
```bash
30+
curl -L https://foundry.paradigm.xyz | bash
31+
```
32+
33+
If you do not want to use the redirect, feel free to manually download the foundryup installation script from [here](https://raw.githubusercontent.com/foundry-rs/foundry/master/foundryup/foundryup).
34+
35+
Then, run `foundryup` in a new terminal session or after reloading your `PATH`.
36+
37+
Other ways to install Foundry can be found [here](https://github.com/foundry-rs/foundry#installation).
38+
39+
### Hardhat
40+
41+
```
42+
yarn install
43+
```
44+
45+
## Build
46+
47+
+ Run `git submodule update --init --recursive` to initialise git submodules.
48+
+ Run `yarn prettier:solidity` to run linting in fix mode, will auto-format all solidity codes.
49+
+ Run `yarn prettier` to run linting in fix mode, will auto-format all typescript codes.
50+
+ Run `forge build` to compile contracts with foundry.
51+
+ Run `npx hardhat compile` to compile with hardhat.
52+
+ Run `forge test -vvv` to run foundry units tests. It will compile all contracts before running the unit tests.
53+
+ Run `npx hardhat test` to run integration tests. It may not compile all contracts before running, it's better to run `npx hardhat compile` first.
54+
55+
## TODO
56+
57+
- [ ] unit tests
58+
- [ ] L1 Messenger
59+
- [x] L1 Gateways
60+
- [x] L1 Gateway Router
61+
- [ ] L2 Messenger
62+
- [x] L2 Gateways
63+
- [x] L2 Gateway Router
64+
- [x] ScrollStandardERC20Factory
65+
- [x] Whitelist
66+
- [ ] SimpleGasOracle
67+
- [ ] integration tests
68+
- [x] ERC20Gateway
69+
- [x] GatewayRouter
70+
- [ ] ZKRollup contracts
71+
- [x] Gas Oracle contracts for cross chain message call
72+
- [ ] ERC721/ERC115 interface design
73+
- [ ] add proof verification codes
74+
- [ ] security analysis

deployments/README.md

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# Deployments
2+
3+
## local testnet
4+
5+
```bash
6+
# start local hardhat node
7+
npx hardhat node
8+
```
9+
10+
### layer 1
11+
12+
Contract addresses can be found in [deployments](./l1geth.json).
13+
14+
### layer 2
15+
16+
Contract addresses can be found in [deployments](./l2geth.json).

deployments/l1geth.json

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
{
2+
"ProxyAdmin": null,
3+
"ZKRollup": {
4+
"implementation": null,
5+
"proxy": null
6+
},
7+
"L1ScrollMessenger": {
8+
"implementation": null,
9+
"proxy": null
10+
},
11+
"L1GatewayRouter": {
12+
"implementation": null,
13+
"proxy": null
14+
},
15+
"L1StandardERC20Gateway": {
16+
"implementation": null,
17+
"proxy": null
18+
},
19+
"L1WETHGateway": {
20+
"implementation": null,
21+
"proxy": null
22+
}
23+
}

deployments/l2geth.json

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
"ProxyAdmin": null,
3+
"WETH": null,
4+
"Whitelist": null,
5+
"ScrollStandardERC20": null,
6+
"ScrollStandardERC20Factory": null,
7+
"L2ScrollMessenger": null,
8+
"L2GatewayRouter": {
9+
"implementation": null,
10+
"proxy": null
11+
},
12+
"L2StandardERC20Gateway": {
13+
"implementation": null,
14+
"proxy": null
15+
},
16+
"L2WETHGateway": {
17+
"implementation": null,
18+
"proxy": null
19+
}
20+
}

docs/CrossDomainMessaging.md

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# Cross Domain Messaging
2+
3+
Like other layer 2 protocol, Scroll allow dapps to communicate between layer 1 and layer 2. More specifically, dapps on layer 1 can trigger contract functions in layer 2, and vice versa.
4+
5+
## Message Between L1 and L2
6+
7+
The Scroll protocol implements two core contracts `L1ScrollMessenger` and `L2ScrollMessenger` to enable cross domain messaging. The only entry to send cross domain message is to call the following function:
8+
9+
```solidity
10+
function sendMessage(
11+
address _to,
12+
bytes memory _message,
13+
uint256 _gasLimit
14+
) external payable
15+
```
16+
17+
The function is attached in both messenger in layer 1 and layer 2. After that, the Sequencer will handle the rest part for you. We will explain the detailed workflow in the following docs.
18+
19+
### Send Message from L1 to L2
20+
21+
As described above, the first step is to call `L1ScrollMessenger.sendMessage` in layer 1. The `L1ScrollMessenger` contract will emit a `SentMessage` event, which will be notified by the Sequencer. The Sequencer will for the confirmation of the function call in layer 1. Normally, the Sequencer will wait for 10-20 blocks. After that, the Sequencer will initiate a transaction in layer 2, calling function `L2ScrollMessenger.relayMessage` and finally, the message is executed in layer 2.
22+
23+
The execution in layer 2 may be failed due to out of gas problem. In such case, one can call `L1ScrollMessenger.replayMessage` to replace the message with a larger gas limit. And the Sequencer will follow the steps and execute the message again in layer 2.
24+
25+
### Send Message from L2 to L1
26+
27+
Similar to sending message from L1 to L2, you should call `L2ScrollMessenger.sendMessage` first in layer 2. The `L2ScrollMessenger` contract will emit a `SentMessage` event, which will be notified by the Sequencer. Unlike above, the Sequencer will first batch submit layer 2 transactions (or block) to `ZKRollup` contract in layer 1. Then the Sequencer will wait the proof generated by roller and submit the proof to `ZKRollup` contract in layer 1 again. Finally, anyone can call `L1ScrollMessenger.relayMessageWithProof` with correct proof to execute the message in layer 1.
28+
29+
Currently, for the safety reason, we only allow privileged contracts to send cross domain messages. And only privileged accounts can call `L2ScrollMessenger.relayMessage`.
30+
31+
## Fee For Sending Message
32+
33+
to be discussed.

docs/Overview.md

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# Overview
2+
3+
![](./assets/overview.png)
4+
5+
The above picture is the overview of the contract design. There are several components both in layer 1 and layer 2: L1/L2 Scroll Messenger, various L1/L2 Gateways and L1/L2 Gateway Router. Besides these, there is a Rollup component only in layer 1.
6+
7+
The followings are the detailed docs for each component (docs are generated automatically by `@primitivefi/hardhat-dodoc` plugin):
8+
9+
- [L1 Scroll Messenger](./apis/L1ScrollMessenger.md) and [L2 Scroll Messenger](./apis/L2ScrollMessenger.md): Main entry for sending and relaying cross domain message.
10+
- [Rollup](./apis/ZKRollup.md)
11+
- [L1 Gateway Router](./apis/L1GatewayRouter.md) and [L2 Gateway Router](./apis/L2GatewayRouter.md): Router contract for depositing/withdrawing Ethers and ERC20 tokens.
12+
- L1/L2 Gateways:
13+
- [L1 Standard ERC20 Gateway](./apis/L1StandardERC20Gateway.md) and [L2 Standard ERC20 Gateway](./apis/L2StandardERC20Gateway.md)
14+
- [L1 WETH Gateway](./apis/L1WETHGateway.md) and [L2 WETH Gateway](./apis/L2WETHGateway.md)
15+
- [L1 ERC721 Gateway](./apis/L1ERC721Gateway.md) and [L2 ERC721 Gateway](./apis/L2ERC721Gateway.md)
16+
- [L1 ERC1155 Gateway](./apis/L1ERC1155Gateway.md) and [L2 ERC1155 Gateway](./apis/L2ERC1155Gateway.md)
17+
- [ScrollStandardERC20Factory](./apis/ScrollStandardERC20Factory.md): The `ScrollStandardERC20` token factory used by `L2StandardERC20Gateway`.
18+
19+
There are two main applications: Token Bridge and Cross Domain Messaging. You can find the documentations in the links below:
20+
21+
- [Token Bridge](./TokenBridge.md): moving token from layer 1 to layer 2, or from layer 2 to layer 1.
22+
- [Cross Domain Messaging](./CrossDomainMessaging.md): sending data to layer 2 from layer 1, or sending data to layer 2 from layer 1. Basically, it will help to trigger function call cross layer. The token bridge also use cross domain messaging to achieve its functionality.

0 commit comments

Comments
 (0)