Skip to content

Commit fd62a9d

Browse files
committed
Adds L2 token deployment script via factory
1 parent c86ac26 commit fd62a9d

4 files changed

Lines changed: 673 additions & 32 deletions

File tree

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
"withdrawals-dump": "node ./scripts/pre-regen-withdrawals-dump"
1414
},
1515
"dependencies": {
16-
"@eth-optimism/contracts": "0.3.5",
16+
"@eth-optimism/contracts": "^0.4.6",
1717
"@eth-optimism/core-utils": "^0.4.5",
1818
"@eth-optimism/data-transport-layer": "^0.1.0",
1919
"@eth-optimism/provider": "^0.0.1-alpha.14",

scripts/deploy-l2-token/ERC20.json

Lines changed: 222 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,222 @@
1+
[
2+
{
3+
"constant": true,
4+
"inputs": [],
5+
"name": "name",
6+
"outputs": [
7+
{
8+
"name": "",
9+
"type": "string"
10+
}
11+
],
12+
"payable": false,
13+
"stateMutability": "view",
14+
"type": "function"
15+
},
16+
{
17+
"constant": false,
18+
"inputs": [
19+
{
20+
"name": "_spender",
21+
"type": "address"
22+
},
23+
{
24+
"name": "_value",
25+
"type": "uint256"
26+
}
27+
],
28+
"name": "approve",
29+
"outputs": [
30+
{
31+
"name": "",
32+
"type": "bool"
33+
}
34+
],
35+
"payable": false,
36+
"stateMutability": "nonpayable",
37+
"type": "function"
38+
},
39+
{
40+
"constant": true,
41+
"inputs": [],
42+
"name": "totalSupply",
43+
"outputs": [
44+
{
45+
"name": "",
46+
"type": "uint256"
47+
}
48+
],
49+
"payable": false,
50+
"stateMutability": "view",
51+
"type": "function"
52+
},
53+
{
54+
"constant": false,
55+
"inputs": [
56+
{
57+
"name": "_from",
58+
"type": "address"
59+
},
60+
{
61+
"name": "_to",
62+
"type": "address"
63+
},
64+
{
65+
"name": "_value",
66+
"type": "uint256"
67+
}
68+
],
69+
"name": "transferFrom",
70+
"outputs": [
71+
{
72+
"name": "",
73+
"type": "bool"
74+
}
75+
],
76+
"payable": false,
77+
"stateMutability": "nonpayable",
78+
"type": "function"
79+
},
80+
{
81+
"constant": true,
82+
"inputs": [],
83+
"name": "decimals",
84+
"outputs": [
85+
{
86+
"name": "",
87+
"type": "uint8"
88+
}
89+
],
90+
"payable": false,
91+
"stateMutability": "view",
92+
"type": "function"
93+
},
94+
{
95+
"constant": true,
96+
"inputs": [
97+
{
98+
"name": "_owner",
99+
"type": "address"
100+
}
101+
],
102+
"name": "balanceOf",
103+
"outputs": [
104+
{
105+
"name": "balance",
106+
"type": "uint256"
107+
}
108+
],
109+
"payable": false,
110+
"stateMutability": "view",
111+
"type": "function"
112+
},
113+
{
114+
"constant": true,
115+
"inputs": [],
116+
"name": "symbol",
117+
"outputs": [
118+
{
119+
"name": "",
120+
"type": "string"
121+
}
122+
],
123+
"payable": false,
124+
"stateMutability": "view",
125+
"type": "function"
126+
},
127+
{
128+
"constant": false,
129+
"inputs": [
130+
{
131+
"name": "_to",
132+
"type": "address"
133+
},
134+
{
135+
"name": "_value",
136+
"type": "uint256"
137+
}
138+
],
139+
"name": "transfer",
140+
"outputs": [
141+
{
142+
"name": "",
143+
"type": "bool"
144+
}
145+
],
146+
"payable": false,
147+
"stateMutability": "nonpayable",
148+
"type": "function"
149+
},
150+
{
151+
"constant": true,
152+
"inputs": [
153+
{
154+
"name": "_owner",
155+
"type": "address"
156+
},
157+
{
158+
"name": "_spender",
159+
"type": "address"
160+
}
161+
],
162+
"name": "allowance",
163+
"outputs": [
164+
{
165+
"name": "",
166+
"type": "uint256"
167+
}
168+
],
169+
"payable": false,
170+
"stateMutability": "view",
171+
"type": "function"
172+
},
173+
{
174+
"payable": true,
175+
"stateMutability": "payable",
176+
"type": "fallback"
177+
},
178+
{
179+
"anonymous": false,
180+
"inputs": [
181+
{
182+
"indexed": true,
183+
"name": "owner",
184+
"type": "address"
185+
},
186+
{
187+
"indexed": true,
188+
"name": "spender",
189+
"type": "address"
190+
},
191+
{
192+
"indexed": false,
193+
"name": "value",
194+
"type": "uint256"
195+
}
196+
],
197+
"name": "Approval",
198+
"type": "event"
199+
},
200+
{
201+
"anonymous": false,
202+
"inputs": [
203+
{
204+
"indexed": true,
205+
"name": "from",
206+
"type": "address"
207+
},
208+
{
209+
"indexed": true,
210+
"name": "to",
211+
"type": "address"
212+
},
213+
{
214+
"indexed": false,
215+
"name": "value",
216+
"type": "uint256"
217+
}
218+
],
219+
"name": "Transfer",
220+
"type": "event"
221+
}
222+
]

scripts/deploy-l2-token/index.ts

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
#!/usr/bin/env -S node --require ts-node/register
2+
3+
import { providers, Wallet, utils, Contract } from "ethers";
4+
import { getContractInterface, predeploys } from "@eth-optimism/contracts";
5+
import erc20Abi from "./ERC20.json";
6+
import dotenv from "dotenv";
7+
dotenv.config();
8+
9+
function config() {
10+
if (!process.env.PRIVATE_KEY) throw new Error("Must pass PRIVATE_KEY");
11+
if (!process.env.NETWORK) throw new Error("Must pass NETWORK");
12+
if (!process.env.NAME) throw new Error("Must pass NAME");
13+
if (!process.env.SYMBOL) throw new Error("Must pass SYMBOL");
14+
if (!process.env.L1_TOKEN_ADDRESS) throw new Error("Must pass L1_TOKEN_ADDRESS");
15+
return {
16+
privateKey: process.env.PRIVATE_KEY,
17+
network: process.env.NETWORK,
18+
name: process.env.NAME,
19+
symbol: process.env.SYMBOL,
20+
l1TokenAddress: process.env.L1_TOKEN_ADDRESS,
21+
};
22+
}
23+
24+
(async () => {
25+
console.log("booting up fam\n");
26+
const cfg = config();
27+
28+
const l2FactoryAddress =
29+
cfg.network === "kovan"
30+
? "0x50EB44e3a68f1963278b4c74c6c343508d31704C"
31+
: "0x2e985AcD6C8Fa033A4c5209b0140940E24da7C5C";
32+
33+
const l2Provider = new providers.JsonRpcProvider(`https://${cfg.network}.optimism.io`);
34+
const wallet = new Wallet(cfg.privateKey).connect(l2Provider);
35+
const l2TokenFactory = new Contract(l2FactoryAddress, getContractInterface("OVM_L2StandardTokenFactory"), wallet);
36+
const address = await wallet.getAddress();
37+
console.log(`Deploying ${cfg.name} ($${cfg.symbol}) from ${address}...`);
38+
const tx = await l2TokenFactory.createStandardL2Token(cfg.l1TokenAddress, cfg.name, cfg.symbol);
39+
const receipt = await tx.wait();
40+
const [, tokenCreatedEvent] = receipt.events;
41+
const l2TokenAddress = tokenCreatedEvent.args._l2Token;
42+
console.log(`Deployed to ${l2TokenAddress} on Optimistic ${cfg.network}`);
43+
})().catch((err) => {
44+
console.log(err);
45+
process.exit(1);
46+
});

0 commit comments

Comments
 (0)