Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
N
nebula
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
exchain
nebula
Commits
b02010d1
Commit
b02010d1
authored
Oct 13, 2020
by
Kelvin Fichter
Browse files
Options
Browse Files
Download
Plain Diff
Added basic tests for message passing contracts
parents
dcfd3df9
669ed02c
Changes
37
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
37 changed files
with
1520 additions
and
3072 deletions
+1520
-3072
gen_safety_checker_constants.py
packages/contracts/bin/gen_safety_checker_constants.py
+65
-0
take-dump.ts
packages/contracts/bin/take-dump.ts
+2
-2
OVM_ECDSAContractAccount.sol
...mistic-ethereum/OVM/accounts/OVM_ECDSAContractAccount.sol
+5
-1
OVM_BaseCrossDomainMessenger.sol
...stic-ethereum/OVM/bridge/OVM_BaseCrossDomainMessenger.sol
+2
-19
OVM_L1CrossDomainMessenger.sol
...mistic-ethereum/OVM/bridge/OVM_L1CrossDomainMessenger.sol
+12
-11
OVM_L2CrossDomainMessenger.sol
...mistic-ethereum/OVM/bridge/OVM_L2CrossDomainMessenger.sol
+4
-1
OVM_StateCommitmentChain.sol
...ptimistic-ethereum/OVM/chain/OVM_StateCommitmentChain.sol
+43
-1
OVM_ExecutionManager.sol
...ptimistic-ethereum/OVM/execution/OVM_ExecutionManager.sol
+30
-23
OVM_SafetyChecker.sol
...s/optimistic-ethereum/OVM/execution/OVM_SafetyChecker.sol
+110
-8
OVM_StateManager.sol
...ts/optimistic-ethereum/OVM/execution/OVM_StateManager.sol
+2
-2
OVM_StateTransitioner.sol
...istic-ethereum/OVM/verification/OVM_StateTransitioner.sol
+1
-0
iOVM_BaseCrossDomainMessenger.sol
...ic-ethereum/iOVM/bridge/iOVM_BaseCrossDomainMessenger.sol
+0
-8
iOVM_StateCommitmentChain.sol
...imistic-ethereum/iOVM/chain/iOVM_StateCommitmentChain.sol
+6
-0
iOVM_ExecutionManager.sol
...imistic-ethereum/iOVM/execution/iOVM_ExecutionManager.sol
+0
-1
iOVM_SafetyChecker.sol
...optimistic-ethereum/iOVM/execution/iOVM_SafetyChecker.sol
+1
-1
iOVM_StateManager.sol
.../optimistic-ethereum/iOVM/execution/iOVM_StateManager.sol
+3
-1
Lib_AddressManager.sol
...mistic-ethereum/libraries/resolver/Lib_AddressManager.sol
+5
-1
Lib_Ownable.sol
...ts/optimistic-ethereum/libraries/resolver/Lib_Ownable.sol
+78
-0
Lib_RLPReader.sol
...racts/optimistic-ethereum/libraries/rlp/Lib_RLPReader.sol
+4
-0
Lib_MerkleTrie.sol
...cts/optimistic-ethereum/libraries/trie/Lib_MerkleTrie.sol
+0
-2
mockOVM_ECDSAContractAccount.sol
...thereum/mockOVM/accounts/mockOVM_ECDSAContractAccount.sol
+71
-0
mockOVM_CrossDomainMessenger.sol
...-ethereum/mockOVM/bridge/mockOVM_CrossDomainMessenger.sol
+16
-0
package.json
packages/contracts/package.json
+14
-6
config.ts
packages/contracts/src/contract-deployment/config.ts
+31
-1
deploy.ts
packages/contracts/src/contract-deployment/deploy.ts
+14
-2
contract-dumps.ts
packages/contracts/src/contract-dumps.ts
+76
-111
index.ts
packages/contracts/src/index.ts
+1
-1
test.json
packages/contracts/test.json
+0
-1217
OVM_L1CrossDomainMessenger.spec.ts
...t/contracts/OVM/bridge/OVM_L1CrossDomainMessenger.spec.ts
+316
-0
OVM_L2CrossDomainMessenger.spec.ts
...t/contracts/OVM/bridge/OVM_L2CrossDomainMessenger.spec.ts
+163
-0
OVM_StateCommitmentChain.spec.ts
...test/contracts/OVM/chain/OVM_StateCommitmentChain.spec.ts
+8
-4
ovmCREATE.spec.ts
...acts/OVM/execution/OVM_ExecutionManager/ovmCREATE.spec.ts
+75
-0
OVM_SafetyChecker.spec.ts
...ts/test/contracts/OVM/execution/OVM_SafetyChecker.spec.ts
+1
-1
safety-checker.test.json
packages/contracts/test/data/json/safety-checker.test.json
+28
-1344
test-runner.ts
packages/contracts/test/helpers/test-runner/test-runner.ts
+23
-4
tsconfig.json
packages/contracts/tsconfig.json
+1
-2
yarn.lock
packages/contracts/yarn.lock
+309
-297
No files found.
packages/contracts/bin/gen_safety_checker_constants.py
0 → 100755
View file @
b02010d1
#!/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
+=
(
"
%02
X"
%
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
)
packages/contracts/bin/take-dump.ts
View file @
b02010d1
...
@@ -4,12 +4,12 @@ import * as path from 'path'
...
@@ -4,12 +4,12 @@ import * as path from 'path'
import
*
as
mkdirp
from
'
mkdirp
'
import
*
as
mkdirp
from
'
mkdirp
'
/* Internal Imports */
/* Internal Imports */
import
{
makeStateDump
}
from
'
../src
'
import
{
makeStateDump
}
from
'
../src
/contract-dumps
'
;(
async
()
=>
{
;(
async
()
=>
{
const
outdir
=
path
.
resolve
(
__dirname
,
'
../build/dumps
'
)
const
outdir
=
path
.
resolve
(
__dirname
,
'
../build/dumps
'
)
const
outfile
=
path
.
join
(
outdir
,
'
state-dump.latest.json
'
)
const
outfile
=
path
.
join
(
outdir
,
'
state-dump.latest.json
'
)
mkdirp
.
sync
(
outdir
)
mkdirp
.
sync
(
outdir
)
const
dump
=
await
makeStateDump
()
const
dump
=
await
makeStateDump
()
fs
.
writeFileSync
(
outfile
,
JSON
.
stringify
(
dump
))
fs
.
writeFileSync
(
outfile
,
JSON
.
stringify
(
dump
,
null
,
4
))
})()
})()
packages/contracts/contracts/optimistic-ethereum/OVM/accounts/OVM_ECDSAContractAccount.sol
View file @
b02010d1
...
@@ -67,7 +67,6 @@ contract OVM_ECDSAContractAccount is iOVM_ECDSAContractAccount {
...
@@ -67,7 +67,6 @@ contract OVM_ECDSAContractAccount is iOVM_ECDSAContractAccount {
decodedTx.nonce == Lib_SafeExecutionManagerWrapper.safeGETNONCE(ovmExecutionManager) + 1,
decodedTx.nonce == Lib_SafeExecutionManagerWrapper.safeGETNONCE(ovmExecutionManager) + 1,
"Transaction nonce does not match the expected nonce."
"Transaction nonce does not match the expected nonce."
);
);
Lib_SafeExecutionManagerWrapper.safeSETNONCE(ovmExecutionManager, decodedTx.nonce);
// Contract creations are signalled by sending a transaction to the zero address.
// Contract creations are signalled by sending a transaction to the zero address.
if (decodedTx.target == address(0)) {
if (decodedTx.target == address(0)) {
...
@@ -81,6 +80,11 @@ contract OVM_ECDSAContractAccount is iOVM_ECDSAContractAccount {
...
@@ -81,6 +80,11 @@ contract OVM_ECDSAContractAccount is iOVM_ECDSAContractAccount {
// initialization. Always return `true` for our success value here.
// initialization. Always return `true` for our success value here.
return (true, abi.encode(created));
return (true, abi.encode(created));
} else {
} else {
// We only want to bump the nonce for `ovmCALL` because `ovmCREATE` automatically bumps
// the nonce of the calling account. Normally an EOA would bump the nonce for both
// cases, but since this is a contract we'd end up bumping the nonce twice.
Lib_SafeExecutionManagerWrapper.safeSETNONCE(ovmExecutionManager, decodedTx.nonce);
return Lib_SafeExecutionManagerWrapper.safeCALL(
return Lib_SafeExecutionManagerWrapper.safeCALL(
ovmExecutionManager,
ovmExecutionManager,
decodedTx.gasLimit,
decodedTx.gasLimit,
...
...
packages/contracts/contracts/optimistic-ethereum/OVM/bridge/OVM_BaseCrossDomainMessenger.sol
View file @
b02010d1
...
@@ -16,7 +16,6 @@ contract OVM_BaseCrossDomainMessenger is iOVM_BaseCrossDomainMessenger {
...
@@ -16,7 +16,6 @@ contract OVM_BaseCrossDomainMessenger is iOVM_BaseCrossDomainMessenger {
mapping (bytes32 => bool) public receivedMessages;
mapping (bytes32 => bool) public receivedMessages;
mapping (bytes32 => bool) public sentMessages;
mapping (bytes32 => bool) public sentMessages;
address public targetMessengerAddress;
uint256 public messageNonce;
uint256 public messageNonce;
address public xDomainMessageSender;
address public xDomainMessageSender;
...
@@ -25,22 +24,6 @@ contract OVM_BaseCrossDomainMessenger is iOVM_BaseCrossDomainMessenger {
...
@@ -25,22 +24,6 @@ contract OVM_BaseCrossDomainMessenger is iOVM_BaseCrossDomainMessenger {
* Public Functions *
* Public Functions *
********************/
********************/
/**
* Sets the target messenger address.
* @dev Currently, this function is public and therefore allows anyone to modify the target
* messenger for a given xdomain messenger contract. Obviously this shouldn't be allowed,
* but we still need to determine an adequate mechanism for updating this address.
* @param _targetMessengerAddress New messenger address.
*/
function setTargetMessengerAddress(
address _targetMessengerAddress
)
override
public
{
targetMessengerAddress = _targetMessengerAddress;
}
/**
/**
* Sends a cross domain message to the target messenger.
* Sends a cross domain message to the target messenger.
* @param _target Target contract address.
* @param _target Target contract address.
...
@@ -92,8 +75,8 @@ contract OVM_BaseCrossDomainMessenger is iOVM_BaseCrossDomainMessenger {
...
@@ -92,8 +75,8 @@ contract OVM_BaseCrossDomainMessenger is iOVM_BaseCrossDomainMessenger {
bytes memory
bytes memory
)
)
{
{
return abi.encodeWithS
elector
(
return abi.encodeWithS
ignature
(
bytes4(keccak256(bytes("relayMessage(address,address,bytes,uint256)")))
,
"relayMessage(address,address,bytes,uint256)"
,
_target,
_target,
_sender,
_sender,
_message,
_message,
...
...
packages/contracts/contracts/optimistic-ethereum/OVM/bridge/OVM_L1CrossDomainMessenger.sol
View file @
b02010d1
...
@@ -16,6 +16,9 @@ import { iOVM_StateCommitmentChain } from "../../iOVM/chain/iOVM_StateCommitment
...
@@ -16,6 +16,9 @@ import { iOVM_StateCommitmentChain } from "../../iOVM/chain/iOVM_StateCommitment
/* Contract Imports */
/* Contract Imports */
import { OVM_BaseCrossDomainMessenger } from "./OVM_BaseCrossDomainMessenger.sol";
import { OVM_BaseCrossDomainMessenger } from "./OVM_BaseCrossDomainMessenger.sol";
/* Logging Imports */
import { console } from "@nomiclabs/buidler/console.sol";
/**
/**
* @title OVM_L1CrossDomainMessenger
* @title OVM_L1CrossDomainMessenger
*/
*/
...
@@ -163,15 +166,13 @@ contract OVM_L1CrossDomainMessenger is iOVM_L1CrossDomainMessenger, OVM_BaseCros
...
@@ -163,15 +166,13 @@ contract OVM_L1CrossDomainMessenger is iOVM_L1CrossDomainMessenger, OVM_BaseCros
bool
bool
)
)
{
{
// TODO: We *must* verify that the batch timestamp is sufficiently old.
return (
// However, this requires that we first add timestamps to state batches
ovmStateCommitmentChain.insideFraudProofWindow(_proof.stateRootBatchHeader) == false
// and account for that change in various tests. Change of that size is
&& ovmStateCommitmentChain.verifyElement(
// out of scope for this ticket, so "TODO" for now.
abi.encodePacked(_proof.stateRoot),
_proof.stateRootBatchHeader,
return ovmStateCommitmentChain.verifyElement(
_proof.stateRootProof
abi.encodePacked(_proof.stateRoot),
)
_proof.stateRootBatchHeader,
_proof.stateRootProof
);
);
}
}
...
@@ -219,7 +220,7 @@ contract OVM_L1CrossDomainMessenger is iOVM_L1CrossDomainMessenger, OVM_BaseCros
...
@@ -219,7 +220,7 @@ contract OVM_L1CrossDomainMessenger is iOVM_L1CrossDomainMessenger, OVM_BaseCros
abi.encodePacked(storageKey),
abi.encodePacked(storageKey),
abi.encodePacked(uint256(1)),
abi.encodePacked(uint256(1)),
_proof.storageTrieWitness,
_proof.storageTrieWitness,
_proof.stat
eRoot
account.storag
eRoot
);
);
}
}
...
@@ -236,7 +237,7 @@ contract OVM_L1CrossDomainMessenger is iOVM_L1CrossDomainMessenger, OVM_BaseCros
...
@@ -236,7 +237,7 @@ contract OVM_L1CrossDomainMessenger is iOVM_L1CrossDomainMessenger, OVM_BaseCros
internal
internal
{
{
ovmCanonicalTransactionChain.enqueue(
ovmCanonicalTransactionChain.enqueue(
targetMessengerAddress
,
resolve("OVM_L2CrossDomainMessenger")
,
_gasLimit,
_gasLimit,
_message
_message
);
);
...
...
packages/contracts/contracts/optimistic-ethereum/OVM/bridge/OVM_L2CrossDomainMessenger.sol
View file @
b02010d1
...
@@ -13,6 +13,9 @@ import { iOVM_L2ToL1MessagePasser } from "../../iOVM/precompiles/iOVM_L2ToL1Mess
...
@@ -13,6 +13,9 @@ import { iOVM_L2ToL1MessagePasser } from "../../iOVM/precompiles/iOVM_L2ToL1Mess
/* Contract Imports */
/* Contract Imports */
import { OVM_BaseCrossDomainMessenger } from "./OVM_BaseCrossDomainMessenger.sol";
import { OVM_BaseCrossDomainMessenger } from "./OVM_BaseCrossDomainMessenger.sol";
/* Logging Imports */
import { console } from "@nomiclabs/buidler/console.sol";
/**
/**
* @title OVM_L2CrossDomainMessenger
* @title OVM_L2CrossDomainMessenger
*/
*/
...
@@ -104,7 +107,7 @@ contract OVM_L2CrossDomainMessenger is iOVM_L2CrossDomainMessenger, OVM_BaseCros
...
@@ -104,7 +107,7 @@ contract OVM_L2CrossDomainMessenger is iOVM_L2CrossDomainMessenger, OVM_BaseCros
)
)
{
{
return (
return (
ovmL1MessageSender.getL1MessageSender() ==
targetMessengerAddress
ovmL1MessageSender.getL1MessageSender() ==
resolve("OVM_L1CrossDomainMessenger")
);
);
}
}
...
...
packages/contracts/contracts/optimistic-ethereum/OVM/chain/OVM_StateCommitmentChain.sol
View file @
b02010d1
...
@@ -18,6 +18,13 @@ import { OVM_BaseChain } from "./OVM_BaseChain.sol";
...
@@ -18,6 +18,13 @@ import { OVM_BaseChain } from "./OVM_BaseChain.sol";
* @title OVM_StateCommitmentChain
* @title OVM_StateCommitmentChain
*/
*/
contract OVM_StateCommitmentChain is iOVM_StateCommitmentChain, OVM_BaseChain, Lib_AddressResolver {
contract OVM_StateCommitmentChain is iOVM_StateCommitmentChain, OVM_BaseChain, Lib_AddressResolver {
/*************
* Constants *
*************/
uint256 constant public FRAUD_PROOF_WINDOW = 7 days;
/*******************************************
/*******************************************
* Contract Variables: Contract References *
* Contract Variables: Contract References *
...
@@ -75,7 +82,9 @@ contract OVM_StateCommitmentChain is iOVM_StateCommitmentChain, OVM_BaseChain, L
...
@@ -75,7 +82,9 @@ contract OVM_StateCommitmentChain is iOVM_StateCommitmentChain, OVM_BaseChain, L
_appendBatch(
_appendBatch(
elements,
elements,
abi.encodePacked(block.timestamp)
abi.encode(
block.timestamp
)
);
);
}
}
...
@@ -94,6 +103,39 @@ contract OVM_StateCommitmentChain is iOVM_StateCommitmentChain, OVM_BaseChain, L
...
@@ -94,6 +103,39 @@ contract OVM_StateCommitmentChain is iOVM_StateCommitmentChain, OVM_BaseChain, L
"State batches can only be deleted by the OVM_FraudVerifier."
"State batches can only be deleted by the OVM_FraudVerifier."
);
);
require(
insideFraudProofWindow(_batchHeader),
"State batches can only be deleted within the fraud proof window."
);
_deleteBatch(_batchHeader);
_deleteBatch(_batchHeader);
}
}
/**********************************
* Public Functions: Batch Status *
**********************************/
function insideFraudProofWindow(
Lib_OVMCodec.ChainBatchHeader memory _batchHeader
)
override
public
view
returns (
bool _inside
)
{
uint256 timestamp = abi.decode(
_batchHeader.extraData,
(uint256)
);
require(
timestamp != 0,
"Batch header timestamp cannot be zero"
);
return timestamp + FRAUD_PROOF_WINDOW > block.timestamp;
}
}
}
packages/contracts/contracts/optimistic-ethereum/OVM/execution/OVM_ExecutionManager.sol
View file @
b02010d1
...
@@ -27,8 +27,8 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager, Lib_AddressResolver {
...
@@ -27,8 +27,8 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager, Lib_AddressResolver {
* External Contract References *
* External Contract References *
********************************/
********************************/
iOVM_SafetyChecker
public
ovmSafetyChecker;
iOVM_SafetyChecker
internal
ovmSafetyChecker;
iOVM_StateManager
public
ovmStateManager;
iOVM_StateManager
internal
ovmStateManager;
/*******************************
/*******************************
...
@@ -63,11 +63,15 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager, Lib_AddressResolver {
...
@@ -63,11 +63,15 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager, Lib_AddressResolver {
* @param _libAddressManager Address of the Address Manager.
* @param _libAddressManager Address of the Address Manager.
*/
*/
constructor(
constructor(
address _libAddressManager
address _libAddressManager,
GasMeterConfig memory _gasMeterConfig,
GlobalContext memory _globalContext
)
)
Lib_AddressResolver(_libAddressManager)
Lib_AddressResolver(_libAddressManager)
{
{
ovmSafetyChecker = iOVM_SafetyChecker(resolve("OVM_SafetyChecker"));
ovmSafetyChecker = iOVM_SafetyChecker(resolve("OVM_SafetyChecker"));
gasMeterConfig = _gasMeterConfig;
globalContext = _globalContext;
}
}
...
@@ -120,10 +124,18 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager, Lib_AddressResolver {
...
@@ -120,10 +124,18 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager, Lib_AddressResolver {
override
override
public
public
{
{
// Store our OVM_StateManager instance (significantly easier than attempting to pass the
address
// Store our OVM_StateManager instance (significantly easier than attempting to pass the
// around in calldata).
// a
ddress a
round in calldata).
ovmStateManager = iOVM_StateManager(_ovmStateManager);
ovmStateManager = iOVM_StateManager(_ovmStateManager);
// Make sure this function can't be called by anyone except the owner of the
// OVM_StateManager (expected to be an OVM_StateTransitioner). We can revert here because
// this would make the `run` itself invalid.
require(
msg.sender == ovmStateManager.owner(),
"Only the owner of the ovmStateManager can call this function"
);
// Check whether we need to start a new epoch, do so if necessary.
// Check whether we need to start a new epoch, do so if necessary.
_checkNeedsNewEpoch(_transaction.timestamp);
_checkNeedsNewEpoch(_transaction.timestamp);
...
@@ -150,6 +162,9 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager, Lib_AddressResolver {
...
@@ -150,6 +162,9 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager, Lib_AddressResolver {
// Wipe the execution context.
// Wipe the execution context.
_resetContext();
_resetContext();
// Reset the ovmStateManager.
ovmStateManager = iOVM_StateManager(address(0));
}
}
...
@@ -494,7 +509,6 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager, Lib_AddressResolver {
...
@@ -494,7 +509,6 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager, Lib_AddressResolver {
MessageContext memory nextMessageContext = messageContext;
MessageContext memory nextMessageContext = messageContext;
nextMessageContext.ovmCALLER = nextMessageContext.ovmADDRESS;
nextMessageContext.ovmCALLER = nextMessageContext.ovmADDRESS;
nextMessageContext.ovmADDRESS = _address;
nextMessageContext.ovmADDRESS = _address;
nextMessageContext.isCreation = false;
bool isStaticEntrypoint = false;
bool isStaticEntrypoint = false;
return _callContract(
return _callContract(
...
@@ -532,7 +546,6 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager, Lib_AddressResolver {
...
@@ -532,7 +546,6 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager, Lib_AddressResolver {
nextMessageContext.ovmCALLER = nextMessageContext.ovmADDRESS;
nextMessageContext.ovmCALLER = nextMessageContext.ovmADDRESS;
nextMessageContext.ovmADDRESS = _address;
nextMessageContext.ovmADDRESS = _address;
nextMessageContext.isStatic = true;
nextMessageContext.isStatic = true;
nextMessageContext.isCreation = false;
bool isStaticEntrypoint = true;
bool isStaticEntrypoint = true;
return _callContract(
return _callContract(
...
@@ -567,7 +580,6 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager, Lib_AddressResolver {
...
@@ -567,7 +580,6 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager, Lib_AddressResolver {
{
{
// DELEGATECALL does not change anything about the message context.
// DELEGATECALL does not change anything about the message context.
MessageContext memory nextMessageContext = messageContext;
MessageContext memory nextMessageContext = messageContext;
nextMessageContext.isCreation = false;
bool isStaticEntrypoint = false;
bool isStaticEntrypoint = false;
return _callContract(
return _callContract(
...
@@ -753,19 +765,12 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager, Lib_AddressResolver {
...
@@ -753,19 +765,12 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager, Lib_AddressResolver {
// We always need to initialize the contract with the default account values.
// We always need to initialize the contract with the default account values.
_initPendingAccount(_address);
_initPendingAccount(_address);
// We're going into a contract creation, so we need to set this flag to get the correct
// revert behavior.
messageContext.isCreation = true;
// Actually deploy the contract and retrieve its address. This step is hiding a lot of
// Actually deploy the contract and retrieve its address. This step is hiding a lot of
// complexity because we need to ensure that contract creation *never* reverts by itself.
// complexity because we need to ensure that contract creation *never* reverts by itself.
// We cover this partially by storing a revert flag and returning (instead of reverting)
// We cover this partially by storing a revert flag and returning (instead of reverting)
// when we know that we're inside a contract's creation code.
// when we know that we're inside a contract's creation code.
address ethAddress = Lib_EthUtils.createContract(_bytecode);
address ethAddress = Lib_EthUtils.createContract(_bytecode);
// Now reset this flag so we go back to normal revert behavior.
messageContext.isCreation = false;
// Contract creation returns the zero address when it fails, which should only be possible
// Contract creation returns the zero address when it fails, which should only be possible
// if the user intentionally runs out of gas. However, we might still have a bit of gas
// if the user intentionally runs out of gas. However, we might still have a bit of gas
// left over since contract calls can only be passed 63/64ths of total gas, so we need to
// left over since contract calls can only be passed 63/64ths of total gas, so we need to
...
@@ -818,7 +823,7 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager, Lib_AddressResolver {
...
@@ -818,7 +823,7 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager, Lib_AddressResolver {
)
)
{
{
// We always update the nonce of the creating account, even if the creation fails.
// We always update the nonce of the creating account, even if the creation fails.
_setAccountNonce(ovmADDRESS(), 1);
_setAccountNonce(ovmADDRESS(),
_getAccountNonce(ovmADDRESS()) +
1);
// We're stepping into a CREATE or CREATE2, so we need to update ADDRESS to point
// We're stepping into a CREATE or CREATE2, so we need to update ADDRESS to point
// to the contract's associated address and CALLER to point to the previous ADDRESS.
// to the contract's associated address and CALLER to point to the previous ADDRESS.
...
@@ -1394,7 +1399,12 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager, Lib_AddressResolver {
...
@@ -1394,7 +1399,12 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager, Lib_AddressResolver {
// *single* byte, something the OVM_ExecutionManager will not return in any other case.
// *single* byte, something the OVM_ExecutionManager will not return in any other case.
// We're thereby allowed to communicate failure without allowing contracts to trick us into
// We're thereby allowed to communicate failure without allowing contracts to trick us into
// thinking there was a failure.
// thinking there was a failure.
if (messageContext.isCreation) {
bool isCreation;
assembly {
isCreation := eq(extcodesize(caller()), 0)
}
if (isCreation) {
messageRecord.revertFlag = _flag;
messageRecord.revertFlag = _flag;
assembly {
assembly {
...
@@ -1550,7 +1560,7 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager, Lib_AddressResolver {
...
@@ -1550,7 +1560,7 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager, Lib_AddressResolver {
_getGasMetadata(cumulativeGasKey)
_getGasMetadata(cumulativeGasKey)
- _getGasMetadata(prevEpochGasKey)
- _getGasMetadata(prevEpochGasKey)
+ _gasLimit
+ _gasLimit
)
>
gasMeterConfig.maxGasPerQueuePerEpoch
)
<
gasMeterConfig.maxGasPerQueuePerEpoch
);
);
}
}
...
@@ -1650,11 +1660,6 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager, Lib_AddressResolver {
...
@@ -1650,11 +1660,6 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager, Lib_AddressResolver {
if (_prevMessageContext.isStatic != _nextMessageContext.isStatic) {
if (_prevMessageContext.isStatic != _nextMessageContext.isStatic) {
messageContext.isStatic = _nextMessageContext.isStatic;
messageContext.isStatic = _nextMessageContext.isStatic;
}
}
// Avoid unnecessary the SSTORE.
if (_prevMessageContext.isCreation != _nextMessageContext.isCreation) {
messageContext.isCreation = _nextMessageContext.isCreation;
}
}
}
/**
/**
...
@@ -1672,6 +1677,8 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager, Lib_AddressResolver {
...
@@ -1672,6 +1677,8 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager, Lib_AddressResolver {
transactionContext.ovmL1QUEUEORIGIN = _transaction.l1QueueOrigin;
transactionContext.ovmL1QUEUEORIGIN = _transaction.l1QueueOrigin;
transactionContext.ovmL1TXORIGIN = _transaction.l1Txorigin;
transactionContext.ovmL1TXORIGIN = _transaction.l1Txorigin;
transactionContext.ovmGASLIMIT = gasMeterConfig.maxGasPerQueuePerEpoch;
transactionContext.ovmGASLIMIT = gasMeterConfig.maxGasPerQueuePerEpoch;
messageRecord.nuisanceGasLeft = _getNuisanceGasLimit(_transaction.gasLimit);
}
}
/**
/**
...
...
packages/contracts/contracts/optimistic-ethereum/OVM/execution/OVM_SafetyChecker.sol
View file @
b02010d1
...
@@ -12,22 +12,124 @@ contract OVM_SafetyChecker is iOVM_SafetyChecker {
...
@@ -12,22 +12,124 @@ contract OVM_SafetyChecker is iOVM_SafetyChecker {
/********************
/********************
* Public Functions *
* Public Functions *
********************/
********************/
/**
/**
*
Checks that a given bytecode string is considered
safe.
*
Returns whether or not all of the provided bytecode is
safe.
* @param _bytecode
Bytecode string to
check.
* @param _bytecode
The bytecode to safety
check.
* @return
_safe Whether or not the bytecode is saf
e.
* @return
`true` if the bytecode is safe, `false` otherwis
e.
*/
*/
function isBytecodeSafe(
function isBytecodeSafe(
bytes memory _bytecode
bytes memory _bytecode
)
)
override
override
public
external
view
view
returns (
returns (bool)
bool _safe
)
{
{
// autogenerated by gen_safety_checker_constants.py
// number of bytes to skip for each opcode
uint256[8] memory opcodeSkippableBytes = [
uint256(0x0001010101010101010101010000000001010101010101010101010101010000),
uint256(0x0100000000000000000000000000000000000000010101010101000000010100),
uint256(0x0000000000000000000000000000000001010101000000010101010100000000),
uint256(0x0203040500000000000000000000000000000000000000000000000000000000),
uint256(0x0101010101010101010101010101010101010101010101010101010101010101),
uint256(0x0101010101000000000000000000000000000000000000000000000000000000),
uint256(0x0000000000000000000000000000000000000000000000000000000000000000),
uint256(0x0000000000000000000000000000000000000000000000000000000000000000)
];
// Mask to gate opcode specific cases
uint256 opcodeGateMask = ~uint256(0xffffffffffffffffffffffe000000000fffffffff070ffff9c0ffffec000f001);
// Halting opcodes
uint256 opcodeHaltingMask = ~uint256(0x4008000000000000000000000000000000000000004000000000000000000001);
// PUSH opcodes
uint256 opcodePushMask = ~uint256(0xffffffff000000000000000000000000);
uint256 codeLength;
uint256 _pc;
assembly {
_pc := add(_bytecode, 0x20)
}
codeLength = _pc + _bytecode.length;
do {
// current opcode: 0x00...0xff
uint256 opNum;
// inline assembly removes the extra add + bounds check
assembly {
let word := mload(_pc) //load the next 32 bytes at pc into word
// Look up number of bytes to skip from opcodeSkippableBytes and then update indexInWord
// E.g. the 02030405 in opcodeSkippableBytes is the number of bytes to skip for PUSH1->4
// We repeat this 6 times, thus we can only skip bytes for up to PUSH4 ((1+4) * 6 = 30 < 32).
// If we see an opcode that is listed as 0 skippable bytes e.g. PUSH5,
// then we will get stuck on that indexInWord and then opNum will be set to the PUSH5 opcode.
let indexInWord := byte(0, mload(add(opcodeSkippableBytes, byte(0, word))))
indexInWord := add(indexInWord, byte(0, mload(add(opcodeSkippableBytes, byte(indexInWord, word)))))
indexInWord := add(indexInWord, byte(0, mload(add(opcodeSkippableBytes, byte(indexInWord, word)))))
indexInWord := add(indexInWord, byte(0, mload(add(opcodeSkippableBytes, byte(indexInWord, word)))))
indexInWord := add(indexInWord, byte(0, mload(add(opcodeSkippableBytes, byte(indexInWord, word)))))
indexInWord := add(indexInWord, byte(0, mload(add(opcodeSkippableBytes, byte(indexInWord, word)))))
_pc := add(_pc, indexInWord)
opNum := byte(indexInWord, word)
}
// + push opcodes
// + stop opcodes [STOP(0x00),JUMP(0x56),RETURN(0xf3),INVALID(0xfe)]
// + caller opcode CALLER(0x33)
// + blacklisted opcodes
uint256 opBit = 1 << opNum;
if (opBit & opcodeGateMask == 0) {
if (opBit & opcodePushMask == 0) {
// all pushes are valid opcodes
// subsequent bytes are not opcodes. Skip them.
_pc += (opNum - 0x5e); // PUSH1 is 0x60, so opNum-0x5f = PUSHed bytes and we +1 to
// skip the _pc++; line below in order to save gas ((-0x5f + 1) = -0x5e)
continue;
} else if (opBit & opcodeHaltingMask == 0) {
// STOP or JUMP or RETURN or INVALID (Note: REVERT is blacklisted, so not included here)
// We are now inside unreachable code until we hit a JUMPDEST!
do {
_pc++;
assembly {
opNum := byte(0, mload(_pc))
}
// encountered a JUMPDEST
if (opNum == 0x5b) break;
// skip PUSHed bytes
if ((1 << opNum) & opcodePushMask == 0) _pc += (opNum - 0x5f); // opNum-0x5f = PUSHed bytes (PUSH1 is 0x60)
} while (_pc < codeLength);
// opNum is 0x5b, so we don't continue here since the pc++ is fine
} else if (opNum == 0x33) { // Caller opcode
uint256 firstOps; // next 32 bytes of bytecode
uint256 secondOps; // following 32 bytes of bytecode
assembly {
firstOps := mload(_pc)
// 32 - 4 bytes = 28 bytes = 224 bits
secondOps := shr(224, mload(add(_pc, 0x20)))
}
// Call identity precompile
// CALLER POP PUSH1 0x00 PUSH1 0x04 GAS CALL
// 32 - 8 bytes = 24 bytes = 192
if ((firstOps >> 192) == 0x3350600060045af1) {
_pc += 8;
// Call EM and abort execution if instructed
// CALLER PUSH1 0x00 SWAP1 GAS CALL PC PUSH1 0x1d ADD EQ JUMPI RETURNDATASIZE PUSH1 0x00 DUP1 RETURNDATACOPY PUSH1 0x00 REVERT JUMPDEST PUSH1 0x01 PUSH1 0x00 RETURN JUMPDEST
} else if (firstOps == 0x336000905af158601d0157586012013d600114573d6000803e3d6000fd5b6001 && secondOps == 0x6000f35b) {
_pc += 36;
} else {
return false;
}
continue;
} else {
// encountered a non-whitelisted opcode!
return false;
}
}
_pc++;
} while (_pc < codeLength);
return true;
return true;
}
}
}
}
packages/contracts/contracts/optimistic-ethereum/OVM/execution/OVM_StateManager.sol
View file @
b02010d1
...
@@ -25,8 +25,8 @@ contract OVM_StateManager is iOVM_StateManager {
...
@@ -25,8 +25,8 @@ contract OVM_StateManager is iOVM_StateManager {
* Contract Variables: Contract References *
* Contract Variables: Contract References *
*******************************************/
*******************************************/
address public owner;
address
override
public owner;
address public ovmExecutionManager;
address
override
public ovmExecutionManager;
/****************************************
/****************************************
...
...
packages/contracts/contracts/optimistic-ethereum/OVM/verification/OVM_StateTransitioner.sol
View file @
b02010d1
...
@@ -304,6 +304,7 @@ contract OVM_StateTransitioner is iOVM_StateTransitioner, Lib_AddressResolver {
...
@@ -304,6 +304,7 @@ contract OVM_StateTransitioner is iOVM_StateTransitioner, Lib_AddressResolver {
)
)
override
override
public
public
onlyDuringPhase(TransitionPhase.PRE_EXECUTION)
{
{
require(
require(
Lib_OVMCodec.hashTransaction(_transaction) == transactionHash,
Lib_OVMCodec.hashTransaction(_transaction) == transactionHash,
...
...
packages/contracts/contracts/optimistic-ethereum/iOVM/bridge/iOVM_BaseCrossDomainMessenger.sol
View file @
b02010d1
...
@@ -11,14 +11,6 @@ interface iOVM_BaseCrossDomainMessenger {
...
@@ -11,14 +11,6 @@ interface iOVM_BaseCrossDomainMessenger {
* Public Functions *
* Public Functions *
********************/
********************/
/**
* Sets the target messenger address.
* @param _targetMessengerAddress New messenger address.
*/
function setTargetMessengerAddress(
address _targetMessengerAddress
) external;
/**
/**
* Sends a cross domain message to the target messenger.
* Sends a cross domain message to the target messenger.
* @param _target Target contract address.
* @param _target Target contract address.
...
...
packages/contracts/contracts/optimistic-ethereum/iOVM/chain/iOVM_StateCommitmentChain.sol
View file @
b02010d1
...
@@ -19,4 +19,10 @@ interface iOVM_StateCommitmentChain is iOVM_BaseChain {
...
@@ -19,4 +19,10 @@ interface iOVM_StateCommitmentChain is iOVM_BaseChain {
function appendStateBatch(bytes32[] calldata _batch) external;
function appendStateBatch(bytes32[] calldata _batch) external;
function deleteStateBatch(Lib_OVMCodec.ChainBatchHeader memory _batchHeader) external;
function deleteStateBatch(Lib_OVMCodec.ChainBatchHeader memory _batchHeader) external;
/**********************************
* Public Functions: Batch Status *
**********************************/
function insideFraudProofWindow(Lib_OVMCodec.ChainBatchHeader memory _batchHeader) external view returns (bool _inside);
}
}
packages/contracts/contracts/optimistic-ethereum/iOVM/execution/iOVM_ExecutionManager.sol
View file @
b02010d1
...
@@ -62,7 +62,6 @@ interface iOVM_ExecutionManager {
...
@@ -62,7 +62,6 @@ interface iOVM_ExecutionManager {
address ovmCALLER;
address ovmCALLER;
address ovmADDRESS;
address ovmADDRESS;
bool isStatic;
bool isStatic;
bool isCreation;
}
}
struct MessageRecord {
struct MessageRecord {
...
...
packages/contracts/contracts/optimistic-ethereum/iOVM/execution/iOVM_SafetyChecker.sol
View file @
b02010d1
...
@@ -10,5 +10,5 @@ interface iOVM_SafetyChecker {
...
@@ -10,5 +10,5 @@ interface iOVM_SafetyChecker {
* Public Functions *
* Public Functions *
********************/
********************/
function isBytecodeSafe(bytes memory _bytecode) external view returns (bool
_safe
);
function isBytecodeSafe(bytes memory _bytecode) external view returns (bool);
}
}
packages/contracts/contracts/optimistic-ethereum/iOVM/execution/iOVM_StateManager.sol
View file @
b02010d1
...
@@ -25,7 +25,9 @@ interface iOVM_StateManager {
...
@@ -25,7 +25,9 @@ interface iOVM_StateManager {
/***************************
/***************************
* Public Functions: Setup *
* Public Functions: Setup *
***************************/
***************************/
function owner() external view returns (address _owner);
function ovmExecutionManager() external view returns (address _ovmExecutionManager);
function setExecutionManager(address _ovmExecutionManager) external;
function setExecutionManager(address _ovmExecutionManager) external;
...
...
packages/contracts/contracts/optimistic-ethereum/libraries/resolver/Lib_AddressManager.sol
View file @
b02010d1
// SPDX-License-Identifier: UNLICENSED
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.7.0;
pragma solidity ^0.7.0;
/* Contract Imports */
import { Ownable } from "./Lib_Ownable.sol";
/**
/**
* @title Lib_AddressManager
* @title Lib_AddressManager
*/
*/
contract Lib_AddressManager {
contract Lib_AddressManager
is Ownable
{
/*******************************************
/*******************************************
* Contract Variables: Internal Accounting *
* Contract Variables: Internal Accounting *
...
@@ -22,6 +25,7 @@ contract Lib_AddressManager {
...
@@ -22,6 +25,7 @@ contract Lib_AddressManager {
address _address
address _address
)
)
public
public
onlyOwner
{
{
addresses[_getNameHash(_name)] = _address;
addresses[_getNameHash(_name)] = _address;
}
}
...
...
packages/contracts/contracts/optimistic-ethereum/libraries/resolver/Lib_Ownable.sol
0 → 100644
View file @
b02010d1
// SPDX-License-Identifier: MIT
pragma solidity ^0.7.0;
/**
* @title Ownable
* @dev Adapted from https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/Ownable.sol
*/
abstract contract Ownable {
/*************
* Variables *
*************/
address public owner;
/**********
* Events *
**********/
event OwnershipTransferred(
address indexed previousOwner,
address indexed newOwner
);
/***************
* Constructor *
***************/
constructor()
internal
{
owner = msg.sender;
emit OwnershipTransferred(address(0), owner);
}
/**********************
* Function Modifiers *
**********************/
modifier onlyOwner() {
require(
owner == msg.sender,
"Ownable: caller is not the owner"
);
_;
}
/********************
* Public Functions *
********************/
function renounceOwnership()
public
virtual
onlyOwner
{
emit OwnershipTransferred(owner, address(0));
owner = address(0);
}
function transferOwnership(address _newOwner)
public
virtual
onlyOwner
{
require(
_newOwner != address(0),
"Ownable: new owner cannot be the zero address"
);
emit OwnershipTransferred(owner, _newOwner);
owner = _newOwner;
}
}
packages/contracts/contracts/optimistic-ethereum/libraries/rlp/Lib_RLPReader.sol
View file @
b02010d1
...
@@ -389,6 +389,10 @@ library Lib_RLPReader {
...
@@ -389,6 +389,10 @@ library Lib_RLPReader {
address
address
)
)
{
{
if (_in.length == 1) {
return address(0);
}
require(
require(
_in.length == 21,
_in.length == 21,
"Invalid RLP address value."
"Invalid RLP address value."
...
...
packages/contracts/contracts/optimistic-ethereum/libraries/trie/Lib_MerkleTrie.sol
View file @
b02010d1
...
@@ -6,8 +6,6 @@ import { Lib_BytesUtils } from "../utils/Lib_BytesUtils.sol";
...
@@ -6,8 +6,6 @@ import { Lib_BytesUtils } from "../utils/Lib_BytesUtils.sol";
import { Lib_RLPReader } from "../rlp/Lib_RLPReader.sol";
import { Lib_RLPReader } from "../rlp/Lib_RLPReader.sol";
import { Lib_RLPWriter } from "../rlp/Lib_RLPWriter.sol";
import { Lib_RLPWriter } from "../rlp/Lib_RLPWriter.sol";
import { console } from "@nomiclabs/buidler/console.sol";
/**
/**
* @title Lib_MerkleTrie
* @title Lib_MerkleTrie
*/
*/
...
...
packages/contracts/contracts/optimistic-ethereum/mockOVM/accounts/mockOVM_ECDSAContractAccount.sol
0 → 100644
View file @
b02010d1
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.7.0;
pragma experimental ABIEncoderV2;
/* Interface Imports */
import { iOVM_ECDSAContractAccount } from "../../iOVM/accounts/iOVM_ECDSAContractAccount.sol";
/* Library Imports */
import { Lib_OVMCodec } from "../../libraries/codec/Lib_OVMCodec.sol";
import { Lib_ECDSAUtils } from "../../libraries/utils/Lib_ECDSAUtils.sol";
import { Lib_SafeExecutionManagerWrapper } from "../../libraries/wrappers/Lib_SafeExecutionManagerWrapper.sol";
/**
* @title mockOVM_ECDSAContractAccount
*/
contract mockOVM_ECDSAContractAccount is iOVM_ECDSAContractAccount {
/********************
* Public Functions *
********************/
/**
* Executes a signed transaction.
* @param _transaction Signed EOA transaction.
* @param _signatureType Hashing scheme used for the transaction (e.g., ETH signed message).
* @param _v Signature `v` parameter.
* @param _r Signature `r` parameter.
* @param _s Signature `s` parameter.
* @return _success Whether or not the call returned (rather than reverted).
* @return _returndata Data returned by the call.
*/
function execute(
bytes memory _transaction,
Lib_OVMCodec.EOASignatureType _signatureType,
uint8 _v,
bytes32 _r,
bytes32 _s
)
override
public
returns (
bool _success,
bytes memory _returndata
)
{
address ovmExecutionManager = msg.sender;
// Skip signature validation in this mock.
Lib_OVMCodec.EOATransaction memory decodedTx = Lib_OVMCodec.decodeEOATransaction(_transaction);
// Contract creations are signalled by sending a transaction to the zero address.
if (decodedTx.target == address(0)) {
address created = Lib_SafeExecutionManagerWrapper.safeCREATE(
ovmExecutionManager,
decodedTx.gasLimit,
decodedTx.data
);
// EVM doesn't tell us whether a contract creation failed, even if it reverted during
// initialization. Always return `true` for our success value here.
return (true, abi.encode(created));
} else {
return Lib_SafeExecutionManagerWrapper.safeCALL(
ovmExecutionManager,
decodedTx.gasLimit,
decodedTx.target,
decodedTx.data
);
}
}
}
packages/contracts/contracts/optimistic-ethereum/mockOVM/bridge/mockOVM_CrossDomainMessenger.sol
View file @
b02010d1
...
@@ -29,6 +29,7 @@ contract mockOVM_CrossDomainMessenger is OVM_BaseCrossDomainMessenger {
...
@@ -29,6 +29,7 @@ contract mockOVM_CrossDomainMessenger is OVM_BaseCrossDomainMessenger {
**********************/
**********************/
ReceivedMessage[] internal fullReceivedMessages;
ReceivedMessage[] internal fullReceivedMessages;
address internal targetMessengerAddress;
uint256 internal lastRelayedMessage;
uint256 internal lastRelayedMessage;
uint256 internal delay;
uint256 internal delay;
...
@@ -51,6 +52,21 @@ contract mockOVM_CrossDomainMessenger is OVM_BaseCrossDomainMessenger {
...
@@ -51,6 +52,21 @@ contract mockOVM_CrossDomainMessenger is OVM_BaseCrossDomainMessenger {
* Public Functions *
* Public Functions *
********************/
********************/
/**
* Sets the target messenger address.
* @dev Currently, this function is public and therefore allows anyone to modify the target
* messenger for a given xdomain messenger contract. Obviously this shouldn't be allowed,
* but we still need to determine an adequate mechanism for updating this address.
* @param _targetMessengerAddress New messenger address.
*/
function setTargetMessengerAddress(
address _targetMessengerAddress
)
public
{
targetMessengerAddress = _targetMessengerAddress;
}
/**
/**
* Sends a message to another mock xdomain messenger.
* Sends a message to another mock xdomain messenger.
* @param _target Target for the message.
* @param _target Target for the message.
...
...
packages/contracts/package.json
View file @
b02010d1
{
{
"name"
:
"optimism"
,
"name"
:
"@eth-optimism/contracts"
,
"version"
:
"1.0.0"
,
"version"
:
"0.0.2-alpha.1"
,
"main"
:
"index.js"
,
"main"
:
"build/src/index.js"
,
"files"
:
[
"build/**/*.js"
,
"build/contracts/*"
,
"build/dumps/*json"
,
"build/artifacts/*json"
],
"license"
:
"MIT"
,
"license"
:
"MIT"
,
"scripts"
:
{
"scripts"
:
{
"build"
:
"yarn run build:contracts && yarn run build:typescript && yarn run build:copy"
,
"build"
:
"yarn run build:contracts && yarn run build:typescript && yarn run build:copy
&& yarn run build:dump
"
,
"build:typescript"
:
"tsc -p ."
,
"build:typescript"
:
"tsc -p ."
,
"build:contracts"
:
"buidler compile"
,
"build:contracts"
:
"buidler compile"
,
"build:dump"
:
"ts-node
\"
bin/take-dump.ts
\"
"
,
"build:dump"
:
"ts-node
\"
bin/take-dump.ts
\"
"
,
...
@@ -17,6 +23,9 @@
...
@@ -17,6 +23,9 @@
"lint:fix:typescript"
:
"prettier --config prettier-config.json --write
\"
buidler.config.ts
\"
\"
{src,test}/**/*.ts
\"
"
,
"lint:fix:typescript"
:
"prettier --config prettier-config.json --write
\"
buidler.config.ts
\"
\"
{src,test}/**/*.ts
\"
"
,
"clean"
:
"rm -rf ./artifacts ./build ./cache"
"clean"
:
"rm -rf ./artifacts ./build ./cache"
},
},
"dependencies"
:
{
"ethers"
:
"5.0.0"
},
"devDependencies"
:
{
"devDependencies"
:
{
"@eth-optimism/smock"
:
"^0.0.2"
,
"@eth-optimism/smock"
:
"^0.0.2"
,
"@nomiclabs/buidler"
:
"^1.4.4"
,
"@nomiclabs/buidler"
:
"^1.4.4"
,
...
@@ -31,11 +40,10 @@
...
@@ -31,11 +40,10 @@
"chai"
:
"^4.2.0"
,
"chai"
:
"^4.2.0"
,
"copyfiles"
:
"^2.3.0"
,
"copyfiles"
:
"^2.3.0"
,
"ethereum-waffle"
:
"3.0.0"
,
"ethereum-waffle"
:
"3.0.0"
,
"ethers"
:
"5.0.0"
,
"fs-extra"
:
"^9.0.1"
,
"fs-extra"
:
"^9.0.1"
,
"ganache-core"
:
"^2.12.1"
,
"ganache-core"
:
"^2.12.1"
,
"lodash"
:
"^4.17.20"
,
"lodash"
:
"^4.17.20"
,
"merkle-patricia-tree"
:
"
git+https://github.com/kfichter/merkle-patricia-tree
"
,
"merkle-patricia-tree"
:
"
^4.0.0
"
,
"mkdirp"
:
"^1.0.4"
,
"mkdirp"
:
"^1.0.4"
,
"mocha"
:
"^8.1.1"
,
"mocha"
:
"^8.1.1"
,
"prettier"
:
"^2.1.2"
,
"prettier"
:
"^2.1.2"
,
...
...
packages/contracts/src/contract-deployment/config.ts
View file @
b02010d1
...
@@ -12,6 +12,9 @@ export interface RollupDeployConfig {
...
@@ -12,6 +12,9 @@ export interface RollupDeployConfig {
maxGasPerQueuePerEpoch
:
number
maxGasPerQueuePerEpoch
:
number
secondsPerEpoch
:
number
secondsPerEpoch
:
number
}
}
ovmGlobalContext
:
{
ovmCHAINID
:
number
}
transactionChainConfig
:
{
transactionChainConfig
:
{
sequencer
:
string
|
Signer
sequencer
:
string
|
Signer
forceInclusionPeriodSeconds
:
number
forceInclusionPeriodSeconds
:
number
...
@@ -20,6 +23,7 @@ export interface RollupDeployConfig {
...
@@ -20,6 +23,7 @@ export interface RollupDeployConfig {
owner
:
string
|
Signer
owner
:
string
|
Signer
allowArbitraryContractDeployment
:
boolean
allowArbitraryContractDeployment
:
boolean
}
}
dependencies
?:
string
[]
}
}
export
interface
ContractDeployParameters
{
export
interface
ContractDeployParameters
{
...
@@ -64,9 +68,29 @@ export const makeContractDeployConfig = async (
...
@@ -64,9 +68,29 @@ export const makeContractDeployConfig = async (
factory
:
getContractFactory
(
'
OVM_StateCommitmentChain
'
),
factory
:
getContractFactory
(
'
OVM_StateCommitmentChain
'
),
params
:
[
AddressManager
.
address
],
params
:
[
AddressManager
.
address
],
},
},
OVM_DeployerWhitelist
:
{
factory
:
getContractFactory
(
'
OVM_DeployerWhitelist
'
),
params
:
[],
},
OVM_L1MessageSender
:
{
factory
:
getContractFactory
(
'
OVM_L1MessageSender
'
),
params
:
[],
},
OVM_L2ToL1MessagePasser
:
{
factory
:
getContractFactory
(
'
OVM_L2ToL1MessagePasser
'
),
params
:
[],
},
OVM_SafetyChecker
:
{
factory
:
getContractFactory
(
'
OVM_SafetyChecker
'
),
params
:
[],
},
OVM_ExecutionManager
:
{
OVM_ExecutionManager
:
{
factory
:
getContractFactory
(
'
OVM_ExecutionManager
'
),
factory
:
getContractFactory
(
'
OVM_ExecutionManager
'
),
params
:
[
AddressManager
.
address
],
params
:
[
AddressManager
.
address
,
config
.
ovmGasMeteringConfig
,
config
.
ovmGlobalContext
,
],
},
},
OVM_StateManager
:
{
OVM_StateManager
:
{
factory
:
getContractFactory
(
'
OVM_StateManager
'
),
factory
:
getContractFactory
(
'
OVM_StateManager
'
),
...
@@ -91,5 +115,11 @@ export const makeContractDeployConfig = async (
...
@@ -91,5 +115,11 @@ export const makeContractDeployConfig = async (
OVM_StateTransitionerFactory
:
{
OVM_StateTransitionerFactory
:
{
factory
:
getContractFactory
(
'
OVM_StateTransitionerFactory
'
),
factory
:
getContractFactory
(
'
OVM_StateTransitionerFactory
'
),
},
},
OVM_ECDSAContractAccount
:
{
factory
:
getContractFactory
(
'
OVM_ECDSAContractAccount
'
),
},
mockOVM_ECDSAContractAccount
:
{
factory
:
getContractFactory
(
'
mockOVM_ECDSAContractAccount
'
),
},
}
}
}
}
packages/contracts/src/contract-deployment/deploy.ts
View file @
b02010d1
...
@@ -38,20 +38,32 @@ export const deploy = async (
...
@@ -38,20 +38,32 @@ export const deploy = async (
for
(
const
[
name
,
contractDeployParameters
]
of
Object
.
entries
(
for
(
const
[
name
,
contractDeployParameters
]
of
Object
.
entries
(
contractDeployConfig
contractDeployConfig
))
{
))
{
if
(
config
.
dependencies
&&
!
config
.
dependencies
.
includes
(
name
))
{
continue
}
const
SimpleProxy
=
await
Factory__SimpleProxy
.
deploy
()
const
SimpleProxy
=
await
Factory__SimpleProxy
.
deploy
()
await
AddressManager
.
setAddress
(
name
,
SimpleProxy
.
address
)
await
AddressManager
.
setAddress
(
name
,
SimpleProxy
.
address
)
contracts
[
`Proxy__
${
name
}
`
]
=
SimpleProxy
try
{
try
{
contracts
[
name
]
=
await
contractDeployParameters
.
factory
contracts
[
name
]
=
await
contractDeployParameters
.
factory
.
connect
(
config
.
deploymentSigner
)
.
connect
(
config
.
deploymentSigner
)
.
deploy
(...
contractDeployParameters
.
params
)
.
deploy
(...
(
contractDeployParameters
.
params
||
[])
)
await
SimpleProxy
.
setTarget
(
contracts
[
name
].
address
)
await
SimpleProxy
.
setTarget
(
contracts
[
name
].
address
)
}
catch
(
err
)
{
}
catch
(
err
)
{
failedDeployments
.
push
(
name
)
failedDeployments
.
push
(
name
)
}
}
}
}
for
(
const
contractDeployParameters
of
Object
.
values
(
contractDeployConfig
))
{
for
(
const
[
name
,
contractDeployParameters
]
of
Object
.
entries
(
contractDeployConfig
))
{
if
(
config
.
dependencies
&&
!
config
.
dependencies
.
includes
(
name
))
{
continue
}
if
(
contractDeployParameters
.
afterDeploy
)
{
if
(
contractDeployParameters
.
afterDeploy
)
{
await
contractDeployParameters
.
afterDeploy
(
contracts
)
await
contractDeployParameters
.
afterDeploy
(
contracts
)
}
}
...
...
packages/contracts/src/contract-dumps.ts
View file @
b02010d1
...
@@ -2,57 +2,29 @@
...
@@ -2,57 +2,29 @@
import
*
as
path
from
'
path
'
import
*
as
path
from
'
path
'
import
{
ethers
}
from
'
ethers
'
import
{
ethers
}
from
'
ethers
'
import
*
as
Ganache
from
'
ganache-core
'
import
*
as
Ganache
from
'
ganache-core
'
import
{
keccak256
}
from
'
ethers/lib/utils
'
/* Internal Imports */
/* Internal Imports */
import
{
deploy
,
RollupDeployConfig
}
from
'
./contract-deployment
'
import
{
deploy
,
RollupDeployConfig
}
from
'
./contract-deployment
'
import
{
fromHexString
,
toHexString
,
remove0x
}
from
'
../test/helpers/utils
'
import
{
getContractDefinition
}
from
'
./contract-defs
'
import
{
getContractDefinition
}
from
'
./contract-defs
'
import
{
keccak256
}
from
'
ethers/lib/utils
'
type
Accounts
=
Array
<
{
originalAddress
:
string
address
:
string
code
:
string
}
>
interface
StorageDump
{
interface
StorageDump
{
[
key
:
string
]:
string
[
key
:
string
]:
string
}
}
export
interface
StateDump
{
export
interface
StateDump
{
contracts
:
{
ovmExecutionManager
:
string
ovmStateManager
:
string
}
accounts
:
{
accounts
:
{
[
address
:
string
]:
{
[
name
:
string
]:
{
balance
:
number
address
:
string
nonce
:
number
code
:
string
code
:
string
codeHash
:
string
storage
:
StorageDump
storage
:
StorageDump
abi
:
any
}
}
}
}
}
}
/**
* Finds the addresses of all accounts changed in the state.
* @param cStateManager Instance of the callback-based internal vm StateManager.
* @returns Array of changed addresses.
*/
const
getChangedAccounts
=
async
(
cStateManager
:
any
):
Promise
<
string
[]
>
=>
{
return
new
Promise
<
string
[]
>
((
resolve
,
reject
)
=>
{
const
accounts
:
string
[]
=
[]
const
stream
=
cStateManager
.
_trie
.
createReadStream
()
stream
.
on
(
'
data
'
,
(
val
:
any
)
=>
{
accounts
.
push
(
val
.
key
.
toString
(
'
hex
'
))
})
stream
.
on
(
'
end
'
,
()
=>
{
resolve
(
accounts
)
})
})
}
/**
/**
* Generates a storage dump for a given address.
* Generates a storage dump for a given address.
* @param cStateManager Instance of the callback-based internal vm StateManager.
* @param cStateManager Instance of the callback-based internal vm StateManager.
...
@@ -90,15 +62,23 @@ const getStorageDump = async (
...
@@ -90,15 +62,23 @@ const getStorageDump = async (
*/
*/
const
sanitizeStorageDump
=
(
const
sanitizeStorageDump
=
(
storageDump
:
StorageDump
,
storageDump
:
StorageDump
,
accounts
:
Accounts
accounts
:
Array
<
{
originalAddress
:
string
deadAddress
:
string
}
>
):
StorageDump
=>
{
):
StorageDump
=>
{
for
(
const
account
of
accounts
)
{
account
.
originalAddress
=
remove0x
(
account
.
originalAddress
).
toLowerCase
()
account
.
deadAddress
=
remove0x
(
account
.
deadAddress
).
toLowerCase
()
}
for
(
const
[
key
,
value
]
of
Object
.
entries
(
storageDump
))
{
for
(
const
[
key
,
value
]
of
Object
.
entries
(
storageDump
))
{
let
parsedKey
=
key
let
parsedKey
=
key
let
parsedValue
=
value
let
parsedValue
=
value
for
(
const
account
of
accounts
)
{
for
(
const
account
of
accounts
)
{
const
re
=
new
RegExp
(
`
${
account
.
originalAddress
}
`
,
'
g
'
)
const
re
=
new
RegExp
(
`
${
account
.
originalAddress
}
`
,
'
g
'
)
parsedValue
=
parsedValue
.
replace
(
re
,
account
.
a
ddress
)
parsedValue
=
parsedValue
.
replace
(
re
,
account
.
deadA
ddress
)
parsedKey
=
parsedKey
.
replace
(
re
,
account
.
a
ddress
)
parsedKey
=
parsedKey
.
replace
(
re
,
account
.
deadA
ddress
)
}
}
if
(
parsedKey
!==
key
)
{
if
(
parsedKey
!==
key
)
{
...
@@ -135,6 +115,9 @@ export const makeStateDump = async (): Promise<any> => {
...
@@ -135,6 +115,9 @@ export const makeStateDump = async (): Promise<any> => {
maxGasPerQueuePerEpoch
:
1
_000_000_000_000
,
maxGasPerQueuePerEpoch
:
1
_000_000_000_000
,
secondsPerEpoch
:
600
,
secondsPerEpoch
:
600
,
},
},
ovmGlobalContext
:
{
ovmCHAINID
:
420
,
},
transactionChainConfig
:
{
transactionChainConfig
:
{
sequencer
:
signer
,
sequencer
:
signer
,
forceInclusionPeriodSeconds
:
600
,
forceInclusionPeriodSeconds
:
600
,
...
@@ -143,96 +126,78 @@ export const makeStateDump = async (): Promise<any> => {
...
@@ -143,96 +126,78 @@ export const makeStateDump = async (): Promise<any> => {
owner
:
signer
,
owner
:
signer
,
allowArbitraryContractDeployment
:
true
,
allowArbitraryContractDeployment
:
true
,
},
},
dependencies
:
[
'
Lib_AddressManager
'
,
'
OVM_DeployerWhitelist
'
,
'
OVM_L1MessageSender
'
,
'
OVM_L2ToL1MessagePasser
'
,
'
OVM_L2CrossDomainMessenger
'
,
'
OVM_SafetyChecker
'
,
'
OVM_ExecutionManager
'
,
'
OVM_StateManager
'
,
'
mockOVM_ECDSAContractAccount
'
,
],
}
const
precompiles
=
{
OVM_L2ToL1MessagePasser
:
'
0x4200000000000000000000000000000000000000
'
,
OVM_L1MessageSender
:
'
0x4200000000000000000000000000000000000001
'
,
OVM_DeployerWhitelist
:
'
0x4200000000000000000000000000000000000002
'
,
}
}
const
deploymentResult
=
await
deploy
(
config
)
const
deploymentResult
=
await
deploy
(
config
)
deploymentResult
.
contracts
[
'
Lib_AddressManager
'
]
=
deploymentResult
.
AddressManager
if
(
deploymentResult
.
failedDeployments
.
length
>
0
)
{
throw
new
Error
(
`Could not generate state dump, deploy failed for:
${
deploymentResult
.
failedDeployments
}
`
)
}
const
pStateManager
=
ganache
.
engine
.
manager
.
state
.
blockchain
.
vm
.
pStateManager
const
pStateManager
=
ganache
.
engine
.
manager
.
state
.
blockchain
.
vm
.
pStateManager
const
cStateManager
=
pStateManager
.
_wrapped
const
cStateManager
=
pStateManager
.
_wrapped
const
ovmExecutionManagerOriginalAddress
=
deploymentResult
.
contracts
.
OVM_ExecutionManager
.
address
.
slice
(
2
)
.
toLowerCase
()
const
ovmExecutionManagerAddress
=
'
c0dec0dec0dec0dec0dec0dec0dec0dec0de0000
'
const
ovmStateManagerOriginalAddress
=
deploymentResult
.
contracts
.
OVM_StateManager
.
address
.
slice
(
2
)
.
toLowerCase
()
const
ovmStateManagerAddress
=
'
c0dec0dec0dec0dec0dec0dec0dec0dec0de0001
'
const
l2ToL1MessagePasserDef
=
getContractDefinition
(
'
OVM_L2ToL1MessagePasser
'
)
const
l2ToL1MessagePasserHash
=
keccak256
(
l2ToL1MessagePasserDef
.
deployedBytecode
)
const
l2ToL1MessagePasserAddress
=
'
4200000000000000000000000000000000000000
'
const
l1MessageSenderDef
=
getContractDefinition
(
'
OVM_L1MessageSender
'
)
const
l1MessageSenderHash
=
keccak256
(
l1MessageSenderDef
.
deployedBytecode
)
const
l1MessageSenderAddress
=
'
4200000000000000000000000000000000000001
'
const
changedAccounts
=
await
getChangedAccounts
(
cStateManager
)
let
deadAddressIndex
=
0
const
accounts
:
Accounts
=
[]
for
(
const
originalAddress
of
changedAccounts
)
{
const
code
=
(
await
pStateManager
.
getContractCode
(
originalAddress
)
).
toString
(
'
hex
'
)
const
codeHash
=
keccak256
(
'
0x
'
+
code
)
if
(
code
.
length
===
0
)
{
continue
}
// Sorry for this one!
let
address
=
originalAddress
if
(
codeHash
===
l2ToL1MessagePasserHash
)
{
address
=
l2ToL1MessagePasserAddress
}
else
if
(
codeHash
===
l1MessageSenderHash
)
{
address
=
l1MessageSenderAddress
}
else
if
(
originalAddress
===
ovmExecutionManagerOriginalAddress
)
{
address
=
ovmExecutionManagerAddress
}
else
if
(
originalAddress
===
ovmStateManagerOriginalAddress
)
{
address
=
ovmStateManagerAddress
}
else
{
address
=
`deaddeaddeaddeaddeaddeaddeaddeaddead
${
deadAddressIndex
.
toString
(
16
)
.
padStart
(
4
,
'
0
'
)}
`
deadAddressIndex
++
}
accounts
.
push
({
originalAddress
,
address
,
code
,
})
}
const
dump
:
StateDump
=
{
const
dump
:
StateDump
=
{
contracts
:
{
ovmExecutionManager
:
'
0x
'
+
ovmExecutionManagerAddress
,
ovmStateManager
:
'
0x
'
+
ovmStateManagerAddress
,
},
accounts
:
{},
accounts
:
{},
}
}
for
(
const
account
of
accounts
)
{
for
(
let
i
=
0
;
i
<
Object
.
keys
(
deploymentResult
.
contracts
).
length
;
i
++
)
{
const
storageDump
=
sanitizeStorageDump
(
const
name
=
Object
.
keys
(
deploymentResult
.
contracts
)[
i
]
await
getStorageDump
(
cStateManager
,
account
.
originalAddress
),
const
contract
=
deploymentResult
.
contracts
[
name
]
accounts
const
codeBuf
=
await
pStateManager
.
getContractCode
(
fromHexString
(
contract
.
address
)
)
)
const
code
=
toHexString
(
codeBuf
)
dump
.
accounts
[
account
.
address
]
=
{
const
deadAddress
=
balance
:
0
,
precompiles
[
name
]
||
nonce
:
0
,
`0xdeaddeaddeaddeaddeaddeaddeaddeaddead
${
i
.
toString
(
16
).
padStart
(
4
,
'
0
'
)}
`
code
:
account
.
code
,
storage
:
storageDump
,
dump
.
accounts
[
name
]
=
{
address
:
deadAddress
,
code
,
codeHash
:
keccak256
(
code
),
storage
:
await
getStorageDump
(
cStateManager
,
contract
.
address
),
abi
:
getContractDefinition
(
name
.
replace
(
'
Proxy__
'
,
''
)).
abi
,
}
}
}
}
const
addressMap
=
Object
.
keys
(
dump
.
accounts
).
map
((
name
)
=>
{
return
{
originalAddress
:
deploymentResult
.
contracts
[
name
].
address
,
deadAddress
:
dump
.
accounts
[
name
].
address
,
}
})
for
(
const
name
of
Object
.
keys
(
dump
.
accounts
))
{
dump
.
accounts
[
name
].
storage
=
sanitizeStorageDump
(
dump
.
accounts
[
name
].
storage
,
addressMap
)
}
return
dump
return
dump
}
}
...
...
packages/contracts/src/index.ts
View file @
b02010d1
export
*
from
'
./contract-defs
'
export
*
from
'
./contract-defs
'
export
*
from
'
./contract-dumps
'
export
{
getLatestStateDump
,
StateDump
}
from
'
./contract-dumps
'
export
*
from
'
./contract-deployment
'
export
*
from
'
./contract-deployment
'
packages/contracts/test.json
deleted
100644 → 0
View file @
dcfd3df9
This diff is collapsed.
Click to expand it.
packages/contracts/test/contracts/OVM/bridge/OVM_L1CrossDomainMessenger.spec.ts
0 → 100644
View file @
b02010d1
import
{
expect
}
from
'
../../../setup
'
/* External Imports */
import
{
ethers
}
from
'
@nomiclabs/buidler
'
import
{
Signer
,
ContractFactory
,
Contract
,
BigNumber
}
from
'
ethers
'
import
{
smockit
,
MockContract
}
from
'
@eth-optimism/smock
'
/* Internal Imports */
import
{
makeAddressManager
,
setProxyTarget
,
NON_NULL_BYTES32
,
ZERO_ADDRESS
,
NON_ZERO_ADDRESS
,
NULL_BYTES32
,
DUMMY_BATCH_HEADERS
,
DUMMY_BATCH_PROOFS
,
TrieTestGenerator
,
toHexString
,
}
from
'
../../../helpers
'
import
{
getContractInterface
}
from
'
../../../../src
'
import
{
keccak256
}
from
'
ethers/lib/utils
'
const
getXDomainCalldata
=
(
sender
:
string
,
target
:
string
,
message
:
string
,
messageNonce
:
number
):
string
=>
{
return
getContractInterface
(
'
OVM_L2CrossDomainMessenger
'
).
encodeFunctionData
(
'
relayMessage
'
,
[
target
,
sender
,
message
,
messageNonce
])
}
describe
(
'
OVM_L1CrossDomainMessenger
'
,
()
=>
{
let
signer
:
Signer
before
(
async
()
=>
{
;[
signer
]
=
await
ethers
.
getSigners
()
})
let
AddressManager
:
Contract
before
(
async
()
=>
{
AddressManager
=
await
makeAddressManager
()
})
let
Mock__TargetContract
:
MockContract
let
Mock__OVM_L2CrossDomainMessenger
:
MockContract
let
Mock__OVM_CanonicalTransactionChain
:
MockContract
let
Mock__OVM_StateCommitmentChain
:
MockContract
before
(
async
()
=>
{
Mock__TargetContract
=
smockit
(
await
ethers
.
getContractFactory
(
'
Helper_SimpleProxy
'
)
)
Mock__OVM_L2CrossDomainMessenger
=
smockit
(
await
ethers
.
getContractFactory
(
'
OVM_L2CrossDomainMessenger
'
)
)
Mock__OVM_CanonicalTransactionChain
=
smockit
(
await
ethers
.
getContractFactory
(
'
OVM_CanonicalTransactionChain
'
)
)
Mock__OVM_StateCommitmentChain
=
smockit
(
await
ethers
.
getContractFactory
(
'
OVM_StateCommitmentChain
'
)
)
await
AddressManager
.
setAddress
(
'
OVM_L2CrossDomainMessenger
'
,
Mock__OVM_L2CrossDomainMessenger
.
address
)
await
setProxyTarget
(
AddressManager
,
'
OVM_CanonicalTransactionChain
'
,
Mock__OVM_CanonicalTransactionChain
)
await
setProxyTarget
(
AddressManager
,
'
OVM_StateCommitmentChain
'
,
Mock__OVM_StateCommitmentChain
)
})
let
Factory__OVM_L1CrossDomainMessenger
:
ContractFactory
before
(
async
()
=>
{
Factory__OVM_L1CrossDomainMessenger
=
await
ethers
.
getContractFactory
(
'
OVM_L1CrossDomainMessenger
'
)
})
let
OVM_L1CrossDomainMessenger
:
Contract
beforeEach
(
async
()
=>
{
OVM_L1CrossDomainMessenger
=
await
Factory__OVM_L1CrossDomainMessenger
.
deploy
(
AddressManager
.
address
)
})
describe
(
'
sendMessage
'
,
()
=>
{
const
target
=
NON_ZERO_ADDRESS
const
message
=
NON_NULL_BYTES32
const
gasLimit
=
100
_000
it
(
'
should be able to send a single message
'
,
async
()
=>
{
await
expect
(
OVM_L1CrossDomainMessenger
.
sendMessage
(
target
,
message
,
gasLimit
)
).
to
.
not
.
be
.
reverted
expect
(
Mock__OVM_CanonicalTransactionChain
.
smocked
.
enqueue
.
calls
[
0
]
).
to
.
deep
.
equal
([
Mock__OVM_L2CrossDomainMessenger
.
address
,
BigNumber
.
from
(
gasLimit
),
getXDomainCalldata
(
await
signer
.
getAddress
(),
target
,
message
,
0
),
])
})
it
(
'
should be able to send the same message twice
'
,
async
()
=>
{
await
OVM_L1CrossDomainMessenger
.
sendMessage
(
target
,
message
,
gasLimit
)
await
expect
(
OVM_L1CrossDomainMessenger
.
sendMessage
(
target
,
message
,
gasLimit
)
).
to
.
not
.
be
.
reverted
})
})
describe
(
'
replayMessage
'
,
()
=>
{
const
target
=
NON_ZERO_ADDRESS
const
message
=
NON_NULL_BYTES32
const
gasLimit
=
100
_000
it
(
'
should revert if the message does not exist
'
,
async
()
=>
{
await
expect
(
OVM_L1CrossDomainMessenger
.
replayMessage
(
target
,
await
signer
.
getAddress
(),
message
,
0
,
gasLimit
)
).
to
.
be
.
revertedWith
(
'
Provided message has not already been sent.
'
)
})
it
(
'
should succeed if the message exists
'
,
async
()
=>
{
await
OVM_L1CrossDomainMessenger
.
sendMessage
(
target
,
message
,
gasLimit
)
await
expect
(
OVM_L1CrossDomainMessenger
.
replayMessage
(
target
,
await
signer
.
getAddress
(),
message
,
0
,
gasLimit
)
).
to
.
not
.
be
.
reverted
})
})
describe
(
'
relayMessage
'
,
()
=>
{
let
target
:
string
let
message
:
string
let
sender
:
string
let
proof
:
any
before
(
async
()
=>
{
target
=
Mock__TargetContract
.
address
message
=
Mock__TargetContract
.
interface
.
encodeFunctionData
(
'
setTarget
'
,
[
NON_ZERO_ADDRESS
,
])
sender
=
await
signer
.
getAddress
()
const
calldata
=
getXDomainCalldata
(
sender
,
target
,
message
,
0
)
const
precompile
=
'
0x4200000000000000000000000000000000000000
'
const
storageKey
=
keccak256
(
keccak256
(
calldata
)
+
'
00
'
.
repeat
(
32
))
const
storageGenerator
=
await
TrieTestGenerator
.
fromNodes
({
nodes
:
[
{
key
:
storageKey
,
val
:
'
0x
'
+
'
01
'
.
padStart
(
64
,
'
0
'
),
},
],
secure
:
true
,
})
const
generator
=
await
TrieTestGenerator
.
fromAccounts
({
accounts
:
[
{
address
:
precompile
,
nonce
:
0
,
balance
:
0
,
codeHash
:
keccak256
(
'
0x1234
'
),
storageRoot
:
toHexString
(
storageGenerator
.
_trie
.
root
),
},
],
secure
:
true
,
})
proof
=
{
stateRoot
:
toHexString
(
generator
.
_trie
.
root
),
stateRootBatchHeader
:
DUMMY_BATCH_HEADERS
[
0
],
stateRootProof
:
DUMMY_BATCH_PROOFS
[
0
],
stateTrieWitness
:
(
await
generator
.
makeAccountProofTest
(
precompile
))
.
accountTrieWitness
,
storageTrieWitness
:
(
await
storageGenerator
.
makeInclusionProofTest
(
storageKey
)
).
proof
,
}
})
beforeEach
(
async
()
=>
{
Mock__OVM_StateCommitmentChain
.
smocked
.
verifyElement
.
will
.
return
.
with
(
true
)
Mock__OVM_StateCommitmentChain
.
smocked
.
insideFraudProofWindow
.
will
.
return
.
with
(
false
)
})
it
(
'
should revert if still inside the fraud proof window
'
,
async
()
=>
{
Mock__OVM_StateCommitmentChain
.
smocked
.
insideFraudProofWindow
.
will
.
return
.
with
(
true
)
const
proof
=
{
stateRoot
:
NULL_BYTES32
,
stateRootBatchHeader
:
DUMMY_BATCH_HEADERS
[
0
],
stateRootProof
:
DUMMY_BATCH_PROOFS
[
0
],
stateTrieWitness
:
'
0x
'
,
storageTrieWitness
:
'
0x
'
,
}
await
expect
(
OVM_L1CrossDomainMessenger
.
relayMessage
(
target
,
sender
,
message
,
0
,
proof
)
).
to
.
be
.
revertedWith
(
'
Provided message could not be verified.
'
)
})
it
(
'
should revert if provided an invalid state root proof
'
,
async
()
=>
{
Mock__OVM_StateCommitmentChain
.
smocked
.
verifyElement
.
will
.
return
.
with
(
false
)
const
proof
=
{
stateRoot
:
NULL_BYTES32
,
stateRootBatchHeader
:
DUMMY_BATCH_HEADERS
[
0
],
stateRootProof
:
DUMMY_BATCH_PROOFS
[
0
],
stateTrieWitness
:
'
0x
'
,
storageTrieWitness
:
'
0x
'
,
}
await
expect
(
OVM_L1CrossDomainMessenger
.
relayMessage
(
target
,
sender
,
message
,
0
,
proof
)
).
to
.
be
.
revertedWith
(
'
Provided message could not be verified.
'
)
})
it
(
'
should revert if provided an invalid storage trie witness
'
,
async
()
=>
{
await
expect
(
OVM_L1CrossDomainMessenger
.
relayMessage
(
target
,
sender
,
message
,
0
,
{
...
proof
,
storageTrieWitness
:
'
0x
'
,
})
).
to
.
be
.
reverted
})
it
(
'
should revert if provided an invalid state trie witness
'
,
async
()
=>
{
await
expect
(
OVM_L1CrossDomainMessenger
.
relayMessage
(
target
,
sender
,
message
,
0
,
{
...
proof
,
stateTrieWitness
:
'
0x
'
,
})
).
to
.
be
.
reverted
})
it
(
'
should send a call to the target contract
'
,
async
()
=>
{
await
OVM_L1CrossDomainMessenger
.
relayMessage
(
target
,
sender
,
message
,
0
,
proof
)
expect
(
Mock__TargetContract
.
smocked
.
setTarget
.
calls
[
0
]).
to
.
deep
.
equal
([
NON_ZERO_ADDRESS
,
])
})
it
(
'
should revert if trying to send the same message twice
'
,
async
()
=>
{
await
OVM_L1CrossDomainMessenger
.
relayMessage
(
target
,
sender
,
message
,
0
,
proof
)
await
expect
(
OVM_L1CrossDomainMessenger
.
relayMessage
(
target
,
sender
,
message
,
0
,
proof
)
).
to
.
be
.
revertedWith
(
'
Provided message has already been received.
'
)
})
})
})
packages/contracts/test/contracts/OVM/bridge/OVM_L2CrossDomainMessenger.spec.ts
0 → 100644
View file @
b02010d1
import
{
expect
}
from
'
../../../setup
'
/* External Imports */
import
{
ethers
}
from
'
@nomiclabs/buidler
'
import
{
Signer
,
ContractFactory
,
Contract
}
from
'
ethers
'
import
{
smockit
,
MockContract
}
from
'
@eth-optimism/smock
'
/* Internal Imports */
import
{
makeAddressManager
,
setProxyTarget
,
NON_NULL_BYTES32
,
ZERO_ADDRESS
,
NON_ZERO_ADDRESS
,
}
from
'
../../../helpers
'
import
{
getContractInterface
}
from
'
../../../../src
'
const
getXDomainCalldata
=
(
sender
:
string
,
target
:
string
,
message
:
string
,
messageNonce
:
number
):
string
=>
{
return
getContractInterface
(
'
OVM_L2CrossDomainMessenger
'
).
encodeFunctionData
(
'
relayMessage
'
,
[
target
,
sender
,
message
,
messageNonce
])
}
describe
(
'
OVM_L2CrossDomainMessenger
'
,
()
=>
{
let
signer
:
Signer
before
(
async
()
=>
{
;[
signer
]
=
await
ethers
.
getSigners
()
})
let
AddressManager
:
Contract
before
(
async
()
=>
{
AddressManager
=
await
makeAddressManager
()
})
let
Mock__TargetContract
:
MockContract
let
Mock__OVM_L1CrossDomainMessenger
:
MockContract
let
Mock__OVM_L1MessageSender
:
MockContract
let
Mock__OVM_L2ToL1MessagePasser
:
MockContract
before
(
async
()
=>
{
Mock__TargetContract
=
smockit
(
await
ethers
.
getContractFactory
(
'
Helper_SimpleProxy
'
)
)
Mock__OVM_L1CrossDomainMessenger
=
smockit
(
await
ethers
.
getContractFactory
(
'
OVM_L1CrossDomainMessenger
'
)
)
Mock__OVM_L1MessageSender
=
smockit
(
await
ethers
.
getContractFactory
(
'
OVM_L1MessageSender
'
)
)
Mock__OVM_L2ToL1MessagePasser
=
smockit
(
await
ethers
.
getContractFactory
(
'
OVM_L2ToL1MessagePasser
'
)
)
await
AddressManager
.
setAddress
(
'
OVM_L1CrossDomainMessenger
'
,
Mock__OVM_L1CrossDomainMessenger
.
address
)
await
setProxyTarget
(
AddressManager
,
'
OVM_L1MessageSender
'
,
Mock__OVM_L1MessageSender
)
await
setProxyTarget
(
AddressManager
,
'
OVM_L2ToL1MessagePasser
'
,
Mock__OVM_L2ToL1MessagePasser
)
})
let
Factory__OVM_L2CrossDomainMessenger
:
ContractFactory
before
(
async
()
=>
{
Factory__OVM_L2CrossDomainMessenger
=
await
ethers
.
getContractFactory
(
'
OVM_L2CrossDomainMessenger
'
)
})
let
OVM_L2CrossDomainMessenger
:
Contract
beforeEach
(
async
()
=>
{
OVM_L2CrossDomainMessenger
=
await
Factory__OVM_L2CrossDomainMessenger
.
deploy
(
AddressManager
.
address
)
})
describe
(
'
sendMessage
'
,
()
=>
{
const
target
=
NON_ZERO_ADDRESS
const
message
=
NON_NULL_BYTES32
const
gasLimit
=
100
_000
it
(
'
should be able to send a single message
'
,
async
()
=>
{
await
expect
(
OVM_L2CrossDomainMessenger
.
sendMessage
(
target
,
message
,
gasLimit
)
).
to
.
not
.
be
.
reverted
expect
(
Mock__OVM_L2ToL1MessagePasser
.
smocked
.
passMessageToL1
.
calls
[
0
]
).
to
.
deep
.
equal
([
getXDomainCalldata
(
await
signer
.
getAddress
(),
target
,
message
,
0
),
])
})
it
(
'
should be able to send the same message twice
'
,
async
()
=>
{
await
OVM_L2CrossDomainMessenger
.
sendMessage
(
target
,
message
,
gasLimit
)
await
expect
(
OVM_L2CrossDomainMessenger
.
sendMessage
(
target
,
message
,
gasLimit
)
).
to
.
not
.
be
.
reverted
})
})
describe
(
'
relayMessage
'
,
()
=>
{
let
target
:
string
let
message
:
string
let
sender
:
string
before
(
async
()
=>
{
target
=
Mock__TargetContract
.
address
message
=
Mock__TargetContract
.
interface
.
encodeFunctionData
(
'
setTarget
'
,
[
NON_ZERO_ADDRESS
,
])
sender
=
await
signer
.
getAddress
()
})
beforeEach
(
async
()
=>
{
Mock__OVM_L1MessageSender
.
smocked
.
getL1MessageSender
.
will
.
return
.
with
(
Mock__OVM_L1CrossDomainMessenger
.
address
)
})
it
(
'
should revert if the L1 message sender is not the OVM_L1CrossDomainMessenger
'
,
async
()
=>
{
Mock__OVM_L1MessageSender
.
smocked
.
getL1MessageSender
.
will
.
return
.
with
(
ZERO_ADDRESS
)
await
expect
(
OVM_L2CrossDomainMessenger
.
relayMessage
(
target
,
sender
,
message
,
0
)
).
to
.
be
.
revertedWith
(
'
Provided message could not be verified.
'
)
})
it
(
'
should send a call to the target contract
'
,
async
()
=>
{
await
OVM_L2CrossDomainMessenger
.
relayMessage
(
target
,
sender
,
message
,
0
)
expect
(
Mock__TargetContract
.
smocked
.
setTarget
.
calls
[
0
]).
to
.
deep
.
equal
([
NON_ZERO_ADDRESS
,
])
})
it
(
'
should revert if trying to send the same message twice
'
,
async
()
=>
{
Mock__OVM_L1MessageSender
.
smocked
.
getL1MessageSender
.
will
.
return
.
with
(
Mock__OVM_L1CrossDomainMessenger
.
address
)
await
OVM_L2CrossDomainMessenger
.
relayMessage
(
target
,
sender
,
message
,
0
)
await
expect
(
OVM_L2CrossDomainMessenger
.
relayMessage
(
target
,
sender
,
message
,
0
)
).
to
.
be
.
revertedWith
(
'
Provided message has already been received.
'
)
})
})
})
packages/contracts/test/contracts/OVM/chain/OVM_StateCommitmentChain.spec.ts
View file @
b02010d1
...
@@ -13,8 +13,9 @@ import {
...
@@ -13,8 +13,9 @@ import {
ZERO_ADDRESS
,
ZERO_ADDRESS
,
toHexString32
,
toHexString32
,
getEthTime
,
getEthTime
,
NULL_BYTES32
,
}
from
'
../../../helpers
'
}
from
'
../../../helpers
'
import
{
keccak256
}
from
'
ethers/lib/utils
'
import
{
keccak256
,
defaultAbiCoder
}
from
'
ethers/lib/utils
'
describe
(
'
OVM_StateCommitmentChain
'
,
()
=>
{
describe
(
'
OVM_StateCommitmentChain
'
,
()
=>
{
let
signer
:
Signer
let
signer
:
Signer
...
@@ -106,7 +107,7 @@ describe('OVM_StateCommitmentChain', () => {
...
@@ -106,7 +107,7 @@ describe('OVM_StateCommitmentChain', () => {
batchRoot
:
keccak256
(
NON_NULL_BYTES32
),
batchRoot
:
keccak256
(
NON_NULL_BYTES32
),
batchSize
:
1
,
batchSize
:
1
,
prevTotalElements
:
0
,
prevTotalElements
:
0
,
extraData
:
'
0x
'
,
extraData
:
NULL_BYTES32
,
}
}
beforeEach
(
async
()
=>
{
beforeEach
(
async
()
=>
{
...
@@ -114,7 +115,10 @@ describe('OVM_StateCommitmentChain', () => {
...
@@ -114,7 +115,10 @@ describe('OVM_StateCommitmentChain', () => {
batch
.
length
batch
.
length
)
)
await
OVM_StateCommitmentChain
.
appendStateBatch
(
batch
)
await
OVM_StateCommitmentChain
.
appendStateBatch
(
batch
)
batchHeader
.
extraData
=
toHexString32
(
await
getEthTime
(
ethers
.
provider
))
batchHeader
.
extraData
=
defaultAbiCoder
.
encode
(
[
'
uint256
'
],
[
await
getEthTime
(
ethers
.
provider
)]
)
})
})
describe
(
'
when the sender is not the OVM_FraudVerifier
'
,
()
=>
{
describe
(
'
when the sender is not the OVM_FraudVerifier
'
,
()
=>
{
...
@@ -156,7 +160,7 @@ describe('OVM_StateCommitmentChain', () => {
...
@@ -156,7 +160,7 @@ describe('OVM_StateCommitmentChain', () => {
await
expect
(
await
expect
(
OVM_StateCommitmentChain
.
deleteStateBatch
({
OVM_StateCommitmentChain
.
deleteStateBatch
({
...
batchHeader
,
...
batchHeader
,
extraData
:
'
0x
1234
'
,
extraData
:
'
0x
'
+
'
22
'
.
repeat
(
32
)
,
})
})
).
to
.
be
.
revertedWith
(
'
Invalid batch header.
'
)
).
to
.
be
.
revertedWith
(
'
Invalid batch header.
'
)
})
})
...
...
packages/contracts/test/contracts/OVM/execution/OVM_ExecutionManager/ovmCREATE.spec.ts
View file @
b02010d1
...
@@ -16,6 +16,8 @@ import {
...
@@ -16,6 +16,8 @@ import {
const
CREATED_CONTRACT_1
=
'
0x2bda4a99d5be88609d23b1e4ab5d1d34fb1c2feb
'
const
CREATED_CONTRACT_1
=
'
0x2bda4a99d5be88609d23b1e4ab5d1d34fb1c2feb
'
const
CREATED_CONTRACT_2
=
'
0x2bda4a99d5be88609d23b1e4ab5d1d34fb1c2feb
'
const
CREATED_CONTRACT_2
=
'
0x2bda4a99d5be88609d23b1e4ab5d1d34fb1c2feb
'
const
CREATED_CONTRACT_BY_2_1
=
'
0xe0d8be8101f36ebe6b01abacec884422c39a1f62
'
const
CREATED_CONTRACT_BY_2_2
=
'
0x15ac629e1a3866b17179ee4ae86de5cbda744335
'
const
NESTED_CREATED_CONTRACT
=
'
0xcb964b3f4162a0d4f5c997b40e19da5a546bc36f
'
const
NESTED_CREATED_CONTRACT
=
'
0xcb964b3f4162a0d4f5c997b40e19da5a546bc36f
'
const
DUMMY_REVERT_DATA
=
const
DUMMY_REVERT_DATA
=
'
0xdeadbeef1e5420deadbeef1e5420deadbeef1e5420deadbeef1e5420deadbeef1e5420
'
'
0xdeadbeef1e5420deadbeef1e5420deadbeef1e5420deadbeef1e5420deadbeef1e5420
'
...
@@ -49,6 +51,14 @@ const test_ovmCREATE: TestDefinition = {
...
@@ -49,6 +51,14 @@ const test_ovmCREATE: TestDefinition = {
codeHash
:
VERIFIED_EMPTY_CONTRACT_HASH
,
codeHash
:
VERIFIED_EMPTY_CONTRACT_HASH
,
ethAddress
:
'
0x
'
+
'
00
'
.
repeat
(
20
),
ethAddress
:
'
0x
'
+
'
00
'
.
repeat
(
20
),
},
},
[
CREATED_CONTRACT_BY_2_1
]:
{
codeHash
:
VERIFIED_EMPTY_CONTRACT_HASH
,
ethAddress
:
'
0x
'
+
'
00
'
.
repeat
(
20
),
},
[
CREATED_CONTRACT_BY_2_2
]:
{
codeHash
:
'
0x
'
+
'
01
'
.
repeat
(
32
),
ethAddress
:
'
0x
'
+
'
00
'
.
repeat
(
20
),
},
[
NESTED_CREATED_CONTRACT
]:
{
[
NESTED_CREATED_CONTRACT
]:
{
codeHash
:
VERIFIED_EMPTY_CONTRACT_HASH
,
codeHash
:
VERIFIED_EMPTY_CONTRACT_HASH
,
ethAddress
:
'
0x
'
+
'
00
'
.
repeat
(
20
),
ethAddress
:
'
0x
'
+
'
00
'
.
repeat
(
20
),
...
@@ -527,6 +537,38 @@ const test_ovmCREATE: TestDefinition = {
...
@@ -527,6 +537,38 @@ const test_ovmCREATE: TestDefinition = {
},
},
],
],
},
},
{
name
:
'
ovmCREATE => ovmCREATE => ovmCALL(ADDRESS_NONEXIST)
'
,
steps
:
[
{
functionName
:
'
ovmCALL
'
,
functionParams
:
{
gasLimit
:
OVM_TX_GAS_LIMIT
,
target
:
'
$DUMMY_OVM_ADDRESS_2
'
,
subSteps
:
[
{
functionName
:
'
ovmCREATE
'
,
functionParams
:
{
subSteps
:
[
{
functionName
:
'
ovmCREATE
'
,
functionParams
:
{
bytecode
:
'
0x
'
,
},
expectedReturnStatus
:
true
,
expectedReturnValue
:
ZERO_ADDRESS
,
},
],
},
expectedReturnStatus
:
true
,
expectedReturnValue
:
CREATED_CONTRACT_BY_2_1
,
},
],
},
expectedReturnStatus
:
true
,
},
],
},
{
{
name
:
'
ovmCREATE => ovmCREATE => ovmCALL(ADDRESS_NONEXIST)
'
,
name
:
'
ovmCREATE => ovmCREATE => ovmCALL(ADDRESS_NONEXIST)
'
,
expectInvalidStateAccess
:
true
,
expectInvalidStateAccess
:
true
,
...
@@ -563,6 +605,39 @@ const test_ovmCREATE: TestDefinition = {
...
@@ -563,6 +605,39 @@ const test_ovmCREATE: TestDefinition = {
},
},
],
],
},
},
{
name
:
'
OZ-AUDIT: ovmCREATE => ((ovmCREATE => ovmADDRESS), ovmREVERT)
'
,
steps
:
[
{
functionName
:
'
ovmCREATE
'
,
functionParams
:
{
subSteps
:
[
{
functionName
:
'
ovmCREATE
'
,
functionParams
:
{
subSteps
:
[
{
functionName
:
'
ovmADDRESS
'
,
expectedReturnValue
:
NESTED_CREATED_CONTRACT
,
},
],
},
expectedReturnStatus
:
true
,
expectedReturnValue
:
NESTED_CREATED_CONTRACT
,
},
{
functionName
:
'
ovmREVERT
'
,
revertData
:
DUMMY_REVERT_DATA
,
expectedReturnStatus
:
true
,
expectedReturnValue
:
'
0x00
'
,
},
],
},
expectedReturnStatus
:
true
,
expectedReturnValue
:
ZERO_ADDRESS
,
},
],
},
{
{
name
:
'
ovmCREATE => OUT_OF_GAS
'
,
name
:
'
ovmCREATE => OUT_OF_GAS
'
,
steps
:
[
steps
:
[
...
...
packages/contracts/test/contracts/OVM/execution/OVM_SafetyChecker.spec.ts
View file @
b02010d1
...
@@ -17,7 +17,7 @@ describe('OVM_SafetyChecker', () => {
...
@@ -17,7 +17,7 @@ describe('OVM_SafetyChecker', () => {
OVM_SafetyChecker
=
await
Factory__OVM_SafetyChecker
.
deploy
()
OVM_SafetyChecker
=
await
Factory__OVM_SafetyChecker
.
deploy
()
})
})
describe
.
skip
(
'
isBytecodeSafe()
'
,
()
=>
{
describe
(
'
isBytecodeSafe()
'
,
()
=>
{
for
(
const
testName
of
Object
.
keys
(
SAFETY_CHECKER_TEST_JSON
))
{
for
(
const
testName
of
Object
.
keys
(
SAFETY_CHECKER_TEST_JSON
))
{
const
test
=
SAFETY_CHECKER_TEST_JSON
[
testName
]
const
test
=
SAFETY_CHECKER_TEST_JSON
[
testName
]
it
(
`should correctly classify:
${
testName
}
`
,
async
()
=>
{
it
(
`should correctly classify:
${
testName
}
`
,
async
()
=>
{
...
...
packages/contracts/test/data/json/safety-checker.test.json
View file @
b02010d1
This diff is collapsed.
Click to expand it.
packages/contracts/test/helpers/test-runner/test-runner.ts
View file @
b02010d1
...
@@ -4,7 +4,7 @@ import { expect } from '../../setup'
...
@@ -4,7 +4,7 @@ import { expect } from '../../setup'
import
{
ethers
}
from
'
@nomiclabs/buidler
'
import
{
ethers
}
from
'
@nomiclabs/buidler
'
import
{
Contract
,
BigNumber
,
ContractFactory
}
from
'
ethers
'
import
{
Contract
,
BigNumber
,
ContractFactory
}
from
'
ethers
'
import
{
cloneDeep
,
merge
}
from
'
lodash
'
import
{
cloneDeep
,
merge
}
from
'
lodash
'
import
{
smoddit
,
ModifiableContract
}
from
'
@eth-optimism/smock
'
import
{
smoddit
,
smockit
,
ModifiableContract
}
from
'
@eth-optimism/smock
'
/* Internal Imports */
/* Internal Imports */
import
{
import
{
...
@@ -148,10 +148,15 @@ export class ExecutionManagerTestRunner {
...
@@ -148,10 +148,15 @@ export class ExecutionManagerTestRunner {
await
ethers
.
getContractFactory
(
'
Lib_AddressManager
'
)
await
ethers
.
getContractFactory
(
'
Lib_AddressManager
'
)
).
deploy
()
).
deploy
()
this
.
contracts
.
OVM_
SafetyChecker
=
await
(
const
SafetyChecker
=
await
(
await
ethers
.
getContractFactory
(
'
OVM_SafetyChecker
'
)
await
ethers
.
getContractFactory
(
'
OVM_SafetyChecker
'
)
).
deploy
()
).
deploy
()
const
MockSafetyChecker
=
smockit
(
SafetyChecker
)
MockSafetyChecker
.
smocked
.
isBytecodeSafe
.
will
.
return
.
with
(
true
)
this
.
contracts
.
OVM_SafetyChecker
=
MockSafetyChecker
await
AddressManager
.
setAddress
(
await
AddressManager
.
setAddress
(
'
OVM_SafetyChecker
'
,
'
OVM_SafetyChecker
'
,
this
.
contracts
.
OVM_SafetyChecker
.
address
this
.
contracts
.
OVM_SafetyChecker
.
address
...
@@ -159,11 +164,25 @@ export class ExecutionManagerTestRunner {
...
@@ -159,11 +164,25 @@ export class ExecutionManagerTestRunner {
this
.
contracts
.
OVM_ExecutionManager
=
await
(
this
.
contracts
.
OVM_ExecutionManager
=
await
(
await
smoddit
(
'
OVM_ExecutionManager
'
)
await
smoddit
(
'
OVM_ExecutionManager
'
)
).
deploy
(
AddressManager
.
address
)
).
deploy
(
AddressManager
.
address
,
{
minTransactionGasLimit
:
0
,
maxTransactionGasLimit
:
1
_000_000_000
,
maxGasPerQueuePerEpoch
:
1
_000_000_000_000
,
secondsPerEpoch
:
600
,
},
{
ovmCHAINID
:
420
,
}
)
this
.
contracts
.
OVM_StateManager
=
await
(
this
.
contracts
.
OVM_StateManager
=
await
(
await
smoddit
(
'
OVM_StateManager
'
)
await
smoddit
(
'
OVM_StateManager
'
)
).
deploy
(
this
.
contracts
.
OVM_ExecutionManager
.
address
)
).
deploy
(
await
this
.
contracts
.
OVM_ExecutionManager
.
signer
.
getAddress
())
await
this
.
contracts
.
OVM_StateManager
.
setExecutionManager
(
this
.
contracts
.
OVM_ExecutionManager
.
address
)
this
.
contracts
.
Helper_TestRunner
=
await
(
this
.
contracts
.
Helper_TestRunner
=
await
(
await
ethers
.
getContractFactory
(
'
Helper_TestRunner
'
)
await
ethers
.
getContractFactory
(
'
Helper_TestRunner
'
)
...
...
packages/contracts/tsconfig.json
View file @
b02010d1
...
@@ -20,8 +20,7 @@
...
@@ -20,8 +20,7 @@
"node_modules/@types"
"node_modules/@types"
]
]
},
},
"include"
:
[
"*.ts"
,
"**/*.ts"
,
"artifacts/*.json"
],
"include"
:
[
"src/**/*.ts"
,
"artifacts/*.json"
],
"exclude"
:
[
"./build"
,
"node_modules"
,
"test"
],
"files"
:
[
"files"
:
[
"./buidler.config.ts"
,
"./buidler.config.ts"
,
"./buidler-env.d.ts"
,
"./buidler-env.d.ts"
,
...
...
packages/contracts/yarn.lock
View file @
b02010d1
This diff is collapsed.
Click to expand it.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment