-
Notifications
You must be signed in to change notification settings - Fork 3.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* feat: add contracts * fix: configure tsconfig and replace build => dist * chore: remove CI files * chore: use monorepo tslint / prettier
- Loading branch information
Showing
207 changed files
with
41,472 additions
and
29 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,14 @@ | ||
node_modules | ||
**/dist | ||
results | ||
temp | ||
.nyc_output | ||
*.tsbuildinfo | ||
|
||
build | ||
dist | ||
|
||
artifacts | ||
artifacts-ovm | ||
cache | ||
cache-ovm | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
*.sol linguist-language=Solidity |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
# Changelog | ||
|
||
## v0.1.11 | ||
- cleanup: ECDSAContractAccount | ||
- cleanup: Proxy_EOA | ||
- cleanup: StateManagerFactory | ||
- cleanup: Bytes32Utils | ||
- cleanup: Minor cleanup to state manager | ||
- cleanup: SafetyChecker | ||
- Remove gas estimators from gateway interface | ||
- Add ERC1820 Registry as a precompile | ||
- dev: Remove usage of custom concat function in Solidity | ||
- Fix revert string generated by EM wrapper | ||
- Update OVM_L1ERC20Gateway.sol | ||
- Move OVM_BondManager test into the right location | ||
|
||
## v0.1.10 | ||
Adds extensible ERC20Gateway and Improve CI. | ||
|
||
- dev: Apply linting to all test files | ||
- Test gas consumption of EM.run() | ||
- Extensible deposit withdraw | ||
- Update OVM_L2DepositedERC20.sol | ||
- Commit state dumps to regenesis repo for new tags | ||
- Update OVM_ChainStorageContainer.sol | ||
- Update OVM_ECDSAContractAccount.sol | ||
- Update OVM_CanonicalTransactionChain.sol | ||
- Reset Context on invalid gaslimit | ||
- [Fix] CI on merge | ||
- [Fix] Run integration tests in forked context | ||
|
||
## v0.1.9 | ||
|
||
Standardized ETH and ERC20 Gateways. | ||
|
||
- Add ETH deposit contract. | ||
- Add standard deposit/withdrawal interfaces. | ||
|
||
## v0.1.5 | ||
|
||
Various cleanup and maintenance tasks. | ||
|
||
- Improving comments and some names (#211) | ||
- Add descriptive comments above the contract declaration for all 'non-abstract contracts' (#200) | ||
- Add generic mock xdomain messenger (#209) | ||
- Move everything over to hardhat (#208) | ||
- Add comment to document v argument (#199) | ||
- Add security related comments (#191) | ||
|
||
## v0.1.4 | ||
|
||
Fix single contract redeployment & state dump script for | ||
mainnet. | ||
|
||
## v0.1.3 | ||
|
||
Add events to fraud proof initialization and finalization. | ||
|
||
## v0.1.2 | ||
|
||
Npm publish integrity. | ||
|
||
## v0.1.1 | ||
|
||
Audit fixes, deployment fixes & final parameterization. | ||
|
||
- Add build mainnet command to package.json (#186) | ||
- revert chain ID 422 -> 420 (#185) | ||
- add `AddressSet` event (#184) | ||
- Add mint & burn to L2 ETH (#178) | ||
- Wait for deploy transactions (#180) | ||
- Final Parameterization of Constants (#176) | ||
- re-enable monotonicity tests (#177) | ||
- make ovmSETNONCE notStatic (#179) | ||
- Add reentry protection to ExecutionManager.run() (#175) | ||
- Add nonReentrant to `relayMessage()` (#172) | ||
- ctc: public getters, remove dead variable (#174) | ||
- fix tainted memory bug in `Lib_BytesUtils.slice` (#171) | ||
|
||
## v0.1.0 | ||
|
||
Initial Release |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
(The MIT License) | ||
|
||
Copyright 2020 Optimism | ||
|
||
Permission is hereby granted, free of charge, to any person obtaining | ||
a copy of this software and associated documentation files (the | ||
"Software"), to deal in the Software without restriction, including | ||
without limitation the rights to use, copy, modify, merge, publish, | ||
distribute, sublicense, and/or sell copies of the Software, and to | ||
permit persons to whom the Software is furnished to do so, subject to | ||
the following conditions: | ||
|
||
The above copyright notice and this permission notice shall be | ||
included in all copies or substantial portions of the Software. | ||
|
||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. | ||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY | ||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, | ||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE | ||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
# Optimistic Ethereum Smart Contracts | ||
|
||
`@eth-optimism/contracts` contains the various Solidity smart contracts used within the Optimistic Ethereum system. | ||
Some of these contracts are deployed on Ethereum ("Layer 1"), while others are meant to be deployed to Optimistic Ethereum ("Layer 2"). | ||
|
||
Within each contract file you'll find a comment that lists: | ||
1. The compiler with which a contract is intended to be compiled, `solc` or `optimistic-solc`. | ||
2. The network upon to which the contract will be deployed, `OVM` or `EVM`. | ||
|
||
A more detailed overview of these contracts can be found on the [community hub](http://community.optimism.io/docs/protocol/protocol.html#system-overview). | ||
|
||
<!-- TODO: Add link to final contract docs here when finished. --> | ||
|
||
## Usage (npm) | ||
If your development stack is based on Node/npm: | ||
|
||
```shell | ||
npm install @eth-optimism/contracts | ||
``` | ||
|
||
Within your contracts: | ||
|
||
```solidity | ||
import { SomeContract } from "@eth-optimism/contracts/SomeContract.sol"; | ||
``` | ||
|
||
## Guide for Developers | ||
### Setup | ||
Install the following: | ||
- [`Node.js` (14+)](https://nodejs.org/en/) | ||
- [`npm`](https://www.npmjs.com/get-npm) | ||
- [`yarn`](https://classic.yarnpkg.com/en/docs/install/) | ||
|
||
Clone the repo: | ||
|
||
```shell | ||
git clone https://github.com/ethereum-optimism/contracts.git | ||
cd contracts | ||
``` | ||
|
||
Install `npm` packages: | ||
```shell | ||
yarn install | ||
``` | ||
|
||
### Running Tests | ||
Tests are executed via `yarn`: | ||
```shell | ||
yarn test | ||
``` | ||
|
||
Run specific tests by giving a path to the file you want to run: | ||
```shell | ||
yarn test ./test/path/to/my/test.spec.ts | ||
``` | ||
|
||
### Compiling and Building | ||
Easiest way is to run the primary build script: | ||
```shell | ||
yarn build | ||
``` | ||
|
||
Running the full build command will perform the following actions: | ||
1. `build:contracts` - Compile all Solidity contracts with both the EVM and OVM compilers. | ||
2. `build:typescript` - Builds the typescript files that are used to export utilities into js. | ||
3. `build:copy` - Copies various other files into the dist folder. | ||
4. `build:dump` - Generates a genesis state from the contracts that L2 geth will use. | ||
5. `build:typechain` - Generates [TypeChain](https://github.com/ethereum-ts/TypeChain) artifacts. | ||
|
||
You can also build specific components as follows: | ||
```shell | ||
yarn build:contracts | ||
``` | ||
|
||
## Security | ||
Please refer to our [Security Policy](https://github.com/ethereum-optimism/.github/security/policy) for information about how to disclose security issues with this code. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,120 @@ | ||
#!/usr/bin/env node | ||
|
||
const contracts = require('../dist/src/contract-deployment/deploy'); | ||
const { providers, Wallet, utils, ethers } = require('ethers'); | ||
const { LedgerSigner } = require('@ethersproject/hardware-wallets'); | ||
const { JsonRpcProvider } = providers; | ||
|
||
const env = process.env; | ||
const key = env.DEPLOYER_PRIVATE_KEY; | ||
const sequencerKey = env.SEQUENCER_PRIVATE_KEY; | ||
let SEQUENCER_ADDRESS = env.SEQUENCER_ADDRESS; | ||
const web3Url = env.L1_NODE_WEB3_URL || 'http://127.0.0.1:8545'; | ||
const DEPLOY_TX_GAS_LIMIT = env.DEPLOY_TX_GAS_LIMIT || 5000000; | ||
const MIN_TRANSACTION_GAS_LIMIT = env.MIN_TRANSACTION_GAS_LIMIT || 50000; | ||
const MAX_TRANSACTION_GAS_LIMIT = env.MAX_TRANSACTION_GAS_LIMIT || 9000000; | ||
const MAX_GAS_PER_QUEUE_PER_EPOCH = env.MAX_GAS_PER_QUEUE_PER_EPOCH || 250000000; | ||
const SECONDS_PER_EPOCH = env.SECONDS_PER_EPOCH || 0; | ||
const WAIT_FOR_RECEIPTS = env.WAIT_FOR_RECEIPTS === 'true'; | ||
let WHITELIST_OWNER = env.WHITELIST_OWNER; | ||
const WHITELIST_ALLOW_ARBITRARY_CONTRACT_DEPLOYMENT = env.WHITELIST_ALLOW_ARBITRARY_CONTRACT_DEPLOYMENT || true; | ||
const FORCE_INCLUSION_PERIOD_SECONDS = env.FORCE_INCLUSION_PERIOD_SECONDS || 2592000; // 30 days | ||
const FRAUD_PROOF_WINDOW_SECONDS = env.FRAUD_PROOF_WINDOW_SECONDS || (60 * 60 * 24 * 7); // 7 days | ||
const SEQUENCER_PUBLISH_WINDOW_SECONDS = env.SEQUENCER_PUBLISH_WINDOW_SECONDS || (60 * 30); // 30 min | ||
const CHAIN_ID = env.CHAIN_ID || 420; // layer 2 chainid | ||
const USE_LEDGER = env.USE_LEDGER || false; | ||
const ADDRESS_MANAGER_ADDRESS = env.ADDRESS_MANAGER_ADDRESS || undefined; | ||
const HD_PATH = env.HD_PATH || utils.defaultPath; | ||
const BLOCK_TIME_SECONDS = env.BLOCK_TIME_SECONDS || 15; | ||
const L2_CROSS_DOMAIN_MESSENGER_ADDRESS = | ||
env.L2_CROSS_DOMAIN_MESSENGER_ADDRESS || '0x4200000000000000000000000000000000000007'; | ||
let RELAYER_ADDRESS = env.RELAYER_ADDRESS || '0x0000000000000000000000000000000000000000'; | ||
const RELAYER_PRIVATE_KEY = env.RELAYER_PRIVATE_KEY; | ||
|
||
(async () => { | ||
const provider = new JsonRpcProvider(web3Url); | ||
let signer; | ||
|
||
// Use the ledger for the deployer | ||
if (USE_LEDGER) { | ||
signer = new LedgerSigner(provider, 'default', HD_PATH); | ||
} else { | ||
if (typeof key === 'undefined') | ||
throw new Error('Must pass deployer key as DEPLOYER_PRIVATE_KEY'); | ||
signer = new Wallet(key, provider); | ||
} | ||
|
||
if (SEQUENCER_ADDRESS) { | ||
if (!utils.isAddress(SEQUENCER_ADDRESS)) | ||
throw new Error(`Invalid Sequencer Address: ${SEQUENCER_ADDRESS}`); | ||
} else { | ||
if (!sequencerKey) | ||
throw new Error('Must pass sequencer key as SEQUENCER_PRIVATE_KEY'); | ||
const sequencer = new Wallet(sequencerKey, provider); | ||
SEQUENCER_ADDRESS = await sequencer.getAddress(); | ||
} | ||
|
||
if (typeof WHITELIST_OWNER === 'undefined') | ||
WHITELIST_OWNER = signer; | ||
|
||
// Use the address derived from RELAYER_PRIVATE_KEY if a private key | ||
// is passed. Using the zero address as the relayer address will mean | ||
// there is no relayer authentication. | ||
if (RELAYER_PRIVATE_KEY) { | ||
if (!utils.isAddress(RELAYER_ADDRESS)) | ||
throw new Error(`Invalid Relayer Address: ${RELAYER_ADDRESS}`); | ||
const relayer = new Wallet(RELAYER_PRIVATE_KEY, provider); | ||
RELAYER_ADDRESS = await relayer.getAddress(); | ||
} | ||
|
||
const result = await contracts.deploy({ | ||
deploymentSigner: signer, | ||
transactionChainConfig: { | ||
forceInclusionPeriodSeconds: FORCE_INCLUSION_PERIOD_SECONDS, | ||
sequencer: SEQUENCER_ADDRESS, | ||
forceInclusionPeriodBlocks: Math.ceil(FORCE_INCLUSION_PERIOD_SECONDS/BLOCK_TIME_SECONDS), | ||
}, | ||
stateChainConfig: { | ||
fraudProofWindowSeconds: FRAUD_PROOF_WINDOW_SECONDS, | ||
sequencerPublishWindowSeconds: SEQUENCER_PUBLISH_WINDOW_SECONDS, | ||
}, | ||
ovmGlobalContext: { | ||
ovmCHAINID: CHAIN_ID, | ||
L2CrossDomainMessengerAddress: L2_CROSS_DOMAIN_MESSENGER_ADDRESS | ||
}, | ||
l1CrossDomainMessengerConfig: { | ||
relayerAddress: RELAYER_ADDRESS, | ||
}, | ||
ovmGasMeteringConfig: { | ||
minTransactionGasLimit: MIN_TRANSACTION_GAS_LIMIT, | ||
maxTransactionGasLimit: MAX_TRANSACTION_GAS_LIMIT, | ||
maxGasPerQueuePerEpoch: MAX_GAS_PER_QUEUE_PER_EPOCH, | ||
secondsPerEpoch: SECONDS_PER_EPOCH | ||
}, | ||
whitelistConfig: { | ||
owner: WHITELIST_OWNER, | ||
allowArbitraryContractDeployment: WHITELIST_ALLOW_ARBITRARY_CONTRACT_DEPLOYMENT | ||
}, | ||
deployOverrides: { | ||
gasLimit: DEPLOY_TX_GAS_LIMIT | ||
}, | ||
waitForReceipts: WAIT_FOR_RECEIPTS, | ||
addressManager: ADDRESS_MANAGER_ADDRESS, | ||
}); | ||
|
||
const { failedDeployments, AddressManager } = result; | ||
if (failedDeployments.length !== 0) | ||
throw new Error(`Contract deployment failed: ${failedDeployments.join(',')}`); | ||
|
||
const out = {}; | ||
out.AddressManager = AddressManager.address; | ||
out.OVM_Sequencer = SEQUENCER_ADDRESS; | ||
out.Deployer = await signer.getAddress() | ||
for (const [name, contract] of Object.entries(result.contracts)) { | ||
out[name] = contract.address; | ||
} | ||
console.log(JSON.stringify(out, null, 2)); | ||
})().catch(err => { | ||
console.log(JSON.stringify({error: err.message, stack: err.stack}, null, 2)); | ||
process.exit(1); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
#!/usr/bin/env python3 | ||
# pip3 install pyevmasm | ||
from pyevmasm import instruction_tables | ||
|
||
#print(instruction_tables.keys()) | ||
|
||
def asm(x): | ||
return [instruction_tables['istanbul'][i].opcode for i in x] | ||
|
||
push_opcodes = asm(["PUSH%d" % i for i in range(1,33)]) | ||
stop_opcodes = asm(["STOP", "JUMP", "RETURN", "INVALID"]) | ||
caller_opcodes = asm(["CALLER"]) | ||
blacklist_ops = set([ | ||
"ADDRESS", "BALANCE", "BLOCKHASH", | ||
"CALL", "CALLCODE", "CHAINID", "COINBASE", | ||
"CREATE", "CREATE2", "DELEGATECALL", "DIFFICULTY", | ||
"EXTCODESIZE", "EXTCODECOPY", "EXTCODEHASH", | ||
"GASLIMIT", "GASPRICE", "NUMBER", | ||
"ORIGIN", "REVERT", "SELFBALANCE", "SELFDESTRUCT", | ||
"SLOAD", "SSTORE", "STATICCALL", "TIMESTAMP"]) | ||
whitelist_opcodes = [] | ||
for x in instruction_tables['istanbul']: | ||
if x.name not in blacklist_ops: | ||
whitelist_opcodes.append(x.opcode) | ||
|
||
pushmask = 0 | ||
for x in push_opcodes: | ||
pushmask |= 1 << x | ||
|
||
stopmask = 0 | ||
for x in stop_opcodes: | ||
stopmask |= 1 << x | ||
|
||
stoplist = [0]*256 | ||
procmask = 0 | ||
for i in range(256): | ||
if i in whitelist_opcodes and \ | ||
i not in push_opcodes and \ | ||
i not in stop_opcodes and \ | ||
i not in caller_opcodes: | ||
# can skip this opcode | ||
stoplist[i] = 1 | ||
else: | ||
procmask |= 1 << i | ||
|
||
# PUSH1 through PUSH4, can't skip in slow | ||
for i in range(0x60, 0x64): | ||
stoplist[i] = i-0x5e | ||
rr = "uint256[8] memory opcodeSkippableBytes = [\n" | ||
for i in range(0, 0x100, 0x20): | ||
ret = "uint256(0x" | ||
for j in range(i, i+0x20, 1): | ||
ret += ("%02X" % stoplist[j]) | ||
rr += ret+"),\n" | ||
|
||
rr = rr[:-2] + "];" | ||
|
||
print(rr) | ||
print("// Mask to gate opcode specific cases") | ||
print("uint256 opcodeGateMask = ~uint256(0x%x);" % procmask) | ||
print("// Halting opcodes") | ||
print("uint256 opcodeHaltingMask = ~uint256(0x%x);" % stopmask) | ||
print("// PUSH opcodes") | ||
print("uint256 opcodePushMask = ~uint256(0x%x);" % pushmask) | ||
|
Oops, something went wrong.