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
9b464f1d
Commit
9b464f1d
authored
Sep 17, 2020
by
Kelvin Fichter
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Added comments to more contracts, added account abstraction
parent
b439747a
Changes
14
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
876 additions
and
196 deletions
+876
-196
OVM_ECDSAContractAccount.sol
...mistic-ethereum/OVM/accounts/OVM_ECDSAContractAccount.sol
+89
-0
OVM_ExecutionManager.sol
...ptimistic-ethereum/OVM/execution/OVM_ExecutionManager.sol
+250
-68
OVM_SafetyChecker.sol
...s/optimistic-ethereum/OVM/execution/OVM_SafetyChecker.sol
+13
-0
OVM_StateManager.sol
...ts/optimistic-ethereum/OVM/execution/OVM_StateManager.sol
+176
-51
iOVM_ECDSAContractAccount.sol
...stic-ethereum/iOVM/accounts/iOVM_ECDSAContractAccount.sol
+24
-0
iOVM_ExecutionManager.sol
...imistic-ethereum/iOVM/execution/iOVM_ExecutionManager.sol
+28
-4
iOVM_SafetyChecker.sol
...optimistic-ethereum/iOVM/execution/iOVM_SafetyChecker.sol
+8
-0
iOVM_StateManager.sol
.../optimistic-ethereum/iOVM/execution/iOVM_StateManager.sol
+33
-10
Lib_OVMCodec.sol
...acts/optimistic-ethereum/libraries/codec/Lib_OVMCodec.sol
+101
-0
Lib_ECDSAUtils.sol
...ts/optimistic-ethereum/libraries/utils/Lib_ECDSAUtils.sol
+92
-0
Lib_EthUtils.sol
...acts/optimistic-ethereum/libraries/utils/Lib_EthUtils.sol
+62
-2
Proxy_Forwarder.spec.ts
...es/contracts/test/contracts/proxy/Proxy_Forwarder.spec.ts
+0
-11
Proxy_Manager.spec.ts
...ages/contracts/test/contracts/proxy/Proxy_Manager.spec.ts
+0
-39
Proxy_Resolver.spec.ts
...ges/contracts/test/contracts/proxy/Proxy_Resolver.spec.ts
+0
-11
No files found.
packages/contracts/contracts/optimistic-ethereum/OVM/accounts/OVM_ECDSAContractAccount.sol
0 → 100644
View file @
9b464f1d
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.7.0;
pragma experimental ABIEncoderV2;
/* Interface Imports */
import { iOVM_ECDSAContractAccount } from "../../iOVM/accounts/iOVM_ECDSAContractAccount.sol";
import { iOVM_ExecutionManager } from "../../iOVM/execution/iOVM_ExecutionManager.sol";
/* Library Imports */
import { Lib_OVMCodec } from "../../libraries/codec/Lib_OVMCodec.sol";
import { Lib_ECDSAUtils } from "../../libraries/utils/Lib_ECDSAUtils.sol";
/**
* @title OVM_ECDSAContractAccount
*/
contract OVM_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
)
{
iOVM_ExecutionManager ovmExecutionManager = iOVM_ExecutionManager(msg.sender);
// Address of this contract within the ovm (ovmADDRESS) should be the same as the
// recovered address of the user who signed this message. This is how we manage to shim
// account abstraction even though the user isn't a contract.
require(
Lib_ECDSAUtils.recover(
_transaction,
_signatureType == Lib_OVMCodec.EOASignatureType.ETH_SIGNED_MESSAGE,
_v,
_r,
_s,
ovmExecutionManager.ovmCHAINID()
) == ovmExecutionManager.ovmADDRESS(),
"Signature provided for EOA transaction execution is invalid."
);
Lib_OVMCodec.EOATransaction memory decodedTx = Lib_OVMCodec.decodeEOATransaction(_transaction);
// Need to make sure that the transaction nonce is right and bump it if so.
require(
decodedTx.nonce == ovmExecutionManager.ovmGETNONCE() + 1,
"Transaction nonce does not match the expected nonce."
);
ovmExecutionManager.ovmSETNONCE(decodedTx.nonce);
// Contract creations are signalled by sending a transaction to the zero address.
if (decodedTx.target == address(0)) {
address created = ovmExecutionManager.ovmCREATE{gas: 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 ovmExecutionManager.ovmCALL(
decodedTx.gasLimit,
decodedTx.target,
decodedTx.data
);
}
}
}
packages/contracts/contracts/optimistic-ethereum/OVM/execution/OVM_ExecutionManager.sol
View file @
9b464f1d
This diff is collapsed.
Click to expand it.
packages/contracts/contracts/optimistic-ethereum/OVM/execution/OVM_SafetyChecker.sol
View file @
9b464f1d
...
...
@@ -4,7 +4,20 @@ pragma solidity ^0.7.0;
/* Interface Imports */
import { iOVM_SafetyChecker } from "../../iOVM/execution/iOVM_SafetyChecker.sol";
/**
* @title OVM_SafetyChecker
*/
contract OVM_SafetyChecker is iOVM_SafetyChecker {
/********************
* Public Functions *
********************/
/**
* Checks that a given bytecode string is considered safe.
* @param _bytecode Bytecode string to check.
* @return _safe Whether or not the bytecode is safe.
*/
function isBytecodeSafe(
bytes memory _bytecode
)
...
...
packages/contracts/contracts/optimistic-ethereum/OVM/execution/OVM_StateManager.sol
View file @
9b464f1d
This diff is collapsed.
Click to expand it.
packages/contracts/contracts/optimistic-ethereum/iOVM/accounts/iOVM_ECDSAContractAccount.sol
0 → 100644
View file @
9b464f1d
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.7.0;
pragma experimental ABIEncoderV2;
/* Library Imports */
import { Lib_OVMCodec } from "../../libraries/codec/Lib_OVMCodec.sol";
/**
* @title iOVM_ECDSAContractAccount
*/
interface iOVM_ECDSAContractAccount {
/********************
* Public Functions *
********************/
function execute(
bytes memory _transaction,
Lib_OVMCodec.EOASignatureType _signatureType,
uint8 _v,
bytes32 _r,
bytes32 _s
) external returns (bool _success, bytes memory _returndata);
}
packages/contracts/contracts/optimistic-ethereum/iOVM/execution/iOVM_ExecutionManager.sol
View file @
9b464f1d
...
...
@@ -2,10 +2,14 @@
pragma solidity ^0.7.0;
pragma experimental ABIEncoderV2;
/*
Interface
Imports */
import {
iOVM_DataTypes } from "../codec/iOVM_DataTypes
.sol";
/*
Library
Imports */
import {
Lib_OVMCodec } from "../../libraries/codec/Lib_OVMCodec
.sol";
interface iOVM_ExecutionManager {
/*******************
* Data Structures *
*******************/
enum RevertFlag {
DID_NOT_REVERT,
OUT_OF_GAS,
...
...
@@ -42,8 +46,13 @@ interface iOVM_ExecutionManager {
RevertFlag revertFlag;
}
/************************************
* Transaction Execution Entrypoint *
************************************/
function run(
iOVM_DataTypes.OVMTransactionData
calldata _transaction,
Lib_OVMCodec.Transaction
calldata _transaction,
address _txStateManager
) external;
...
...
@@ -73,7 +82,15 @@ interface iOVM_ExecutionManager {
function ovmCREATE(bytes memory _bytecode) external returns (address _contract);
function ovmCREATE2(bytes memory _bytecode, bytes32 _salt) external returns (address _contract);
function safeCREATE(address _address, bytes memory _bytecode) external;
/*******************************
* Account Abstraction Opcodes *
******************************/
function ovmGETNONCE() external returns (uint256 _nonce);
function ovmSETNONCE(uint256 _nonce) external;
function ovmCREATEEOA(bytes32 _messageHash, uint8 _v, bytes32 _r, bytes32 _s) external;
/****************************
...
...
@@ -100,4 +117,11 @@ interface iOVM_ExecutionManager {
function ovmEXTCODECOPY(address _contract, uint256 _offset, uint256 _length) external returns (bytes memory _code);
function ovmEXTCODESIZE(address _contract) external returns (uint256 _size);
function ovmEXTCODEHASH(address _contract) external returns (bytes32 _hash);
/**************************************
* Public Functions: Execution Safety *
**************************************/
function safeCREATE(address _address, bytes memory _bytecode) external;
}
packages/contracts/contracts/optimistic-ethereum/iOVM/execution/iOVM_SafetyChecker.sol
View file @
9b464f1d
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.7.0;
/**
* @title iOVM_SafetyChecker
*/
interface iOVM_SafetyChecker {
/********************
* Public Functions *
********************/
function isBytecodeSafe(bytes memory _bytecode) external view returns (bool _safe);
}
packages/contracts/contracts/optimistic-ethereum/iOVM/execution/iOVM_StateManager.sol
View file @
9b464f1d
...
...
@@ -2,25 +2,48 @@
pragma solidity ^0.7.0;
pragma experimental ABIEncoderV2;
/*
Interface
Imports */
import {
iOVM_DataTypes } from "../codec/iOVM_DataTypes
.sol";
/*
Library
Imports */
import {
Lib_OVMCodec } from "../../libraries/codec/Lib_OVMCodec
.sol";
/**
* @title iOVM_StateManager
*/
interface iOVM_StateManager {
function putAccount(address _address, iOVM_DataTypes.OVMAccount memory _account) external;
function getAccount(address _address) external returns (iOVM_DataTypes.OVMAccount memory _account);
/*******************
* Data Structures *
*******************/
enum ItemState {
ITEM_UNTOUCHED,
ITEM_LOADED,
ITEM_CHANGED
}
/************************************
* Public Functions: Account Access *
************************************/
function putAccount(address _address, Lib_OVMCodec.Account memory _account) external;
function getAccount(address _address) external returns (Lib_OVMCodec.Account memory _account);
function hasAccount(address _address) external returns (bool _exists);
function incrementAccountNonce(address _address) external;
function setAccountNonce(address _address, uint256 _nonce) external;
function getAccountNonce(address _address) external returns (uint256 _nonce);
function getAccountEthAddress(address _address) external returns (address _ethAddress);
function initPendingAccount(address _address) external;
function commitPendingAccount(address _address, address _ethAddress, bytes32 _codeHash) external;
function testAndSetAccountLoaded(address _address) external returns (bool _wasAccountAlreadyLoaded);
function testAndSetAccountChanged(address _address) external returns (bool _wasAccountAlreadyChanged);
/************************************
* Public Functions: Storage Access *
************************************/
function putContractStorage(address _contract, bytes32 _key, bytes32 _value) external;
function getContractStorage(address _contract, bytes32 _key) external returns (bytes32 _value);
function hasContractStorage(address _contract, bytes32 _key) external returns (bool _exists);
function testAndSetAccountLoaded(address _address) external returns (bool _wasAccountAlreadyLoaded);
function testAndSetAccountChanged(address _address) external returns (bool _wasAccountAlreadyChanged);
function testAndSetContractStorageLoaded(address _contract, bytes32 _key) external returns (bool _wasContractStorageAlreadyLoaded);
function testAndSetContractStorageChanged(address _contract, bytes32 _key) external returns (bool _wasContractStorageAlreadyChanged);
}
packages/contracts/contracts/optimistic-ethereum/
iOVM/codec/iOVM_DataTypes
.sol
→
packages/contracts/contracts/optimistic-ethereum/
libraries/codec/Lib_OVMCodec
.sol
View file @
9b464f1d
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.7.0;
pragma experimental ABIEncoderV2;
interface iOVM_DataTypes {
struct OVMAccount {
uint256 nonce;
uint256 balance;
bytes32 storageRoot;
bytes32 codeHash;
address ethAddress;
}
/* Library Imports */
import { Lib_RLPReader } from "../rlp/Lib_RLPReader.sol";
/**
* @title Lib_OVMCodec
*/
library Lib_OVMCodec {
/*******************
* Data Structures *
*******************/
struct
EVM
Account {
struct Account {
uint256 nonce;
uint256 balance;
bytes32 storageRoot;
bytes32 codeHash;
address ethAddress;
}
struct
OVM
ChainBatchHeader {
struct ChainBatchHeader {
uint256 batchIndex;
bytes32 batchRoot;
uint256 batchSize;
...
...
@@ -25,12 +30,12 @@ interface iOVM_DataTypes {
bytes extraData;
}
struct
OVM
ChainInclusionProof {
struct ChainInclusionProof {
uint256 index;
bytes32[] siblings;
}
struct
OVMTransactionData
{
struct
Transaction
{
uint256 timestamp;
uint256 queueOrigin;
address entrypoint;
...
...
@@ -40,16 +45,57 @@ interface iOVM_DataTypes {
bytes data;
}
struct
OVM
ProofMatrix {
struct ProofMatrix {
bool checkNonce;
bool checkBalance;
bool checkStorageRoot;
bool checkCodeHash;
}
struct
OVM
QueueElement {
struct QueueElement {
uint256 timestamp;
bytes32 batchRoot;
bool isL1ToL2Batch;
}
struct EOATransaction {
address target;
uint256 nonce;
uint256 gasLimit;
bytes data;
}
enum EOASignatureType {
ETH_SIGNED_MESSAGE,
NATIVE_TRANSACTON
}
/*********************************************
* Internal Functions: Encoding and Decoding *
*********************************************/
/**
* Decodes an EOA transaction (i.e., native Ethereum RLP encoding).
* @param _transaction Encoded EOA transaction.
* @return _decoded Transaction decoded into a struct.
*/
function decodeEOATransaction(
bytes memory _transaction
)
internal
pure
returns (
EOATransaction memory _decoded
)
{
Lib_RLPReader.RLPItem[] memory decoded = Lib_RLPReader.toList(Lib_RLPReader.toRlpItem(_transaction));
return EOATransaction({
nonce: Lib_RLPReader.toUint(decoded[0]),
gasLimit: Lib_RLPReader.toUint(decoded[2]),
target: Lib_RLPReader.toAddress(decoded[3]),
data: Lib_RLPReader.toBytes(decoded[5])
});
}
}
packages/contracts/contracts/optimistic-ethereum/libraries/utils/Lib_ECDSAUtils.sol
0 → 100644
View file @
9b464f1d
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.7.0;
/**
* @title Lib_ECDSAUtils
*/
library Lib_ECDSAUtils {
/**************************************
* Internal Functions: ECDSA Recovery *
**************************************/
/**
* Recovers a signed address given a message and signature.
* @param _message Message that was originally signed.
* @param _isEthSignedMessage Whether or not the user used the `Ethereum Signed Message` prefix.
* @param _v Signature `v` parameter.
* @param _r Signature `r` parameter.
* @param _s Signature `s` parameter.
* @param _chainId Chain ID parameter.
* @return _sender Signer address.
*/
function recover(
bytes memory _message,
bool _isEthSignedMessage,
uint8 _v,
bytes32 _r,
bytes32 _s,
uint256 _chainId
)
internal
pure
returns (
address _sender
)
{
bytes32 messageHash;
if (_isEthSignedMessage) {
messageHash = getEthSignedMessageHash(_message);
} else {
messageHash = getNativeMessageHash(_message);
}
return ecrecover(
messageHash,
(_v - uint8(_chainId) * 2) - 8,
_r,
_s
);
}
/*************************************
* Private Functions: ECDSA Recovery *
*************************************/
/**
* Gets the native message hash (simple keccak256) for a message.
* @param _message Message to hash.
* @return _messageHash Native message hash.
*/
function getNativeMessageHash(
bytes memory _message
)
private
pure
returns (
bytes32 _messageHash
)
{
return keccak256(_message);
}
/**
* Gets the hash of a message with the `Ethereum Signed Message` prefix.
* @param _message Message to hash.
* @return _messageHash Prefixed message hash.
*/
function getEthSignedMessageHash(
bytes memory _message
)
private
pure
returns (
bytes32 _messageHash
)
{
bytes memory prefix = "\x19Ethereum Signed Message:\n32";
bytes32 messageHash = keccak256(_message);
return keccak256(abi.encodePacked(prefix, messageHash));
}
}
\ No newline at end of file
packages/contracts/contracts/optimistic-ethereum/libraries/utils/Lib_EthUtils.sol
View file @
9b464f1d
...
...
@@ -5,7 +5,22 @@ pragma experimental ABIEncoderV2;
/* Library Imports */
import { Lib_RLPWriter } from "../rlp/Lib_RLPWriter.sol";
/**
* @title Lib_EthUtils
*/
library Lib_EthUtils {
/***********************************
* Internal Functions: Code Access *
***********************************/
/**
* Gets the code for a given address.
* @param _address Address to get code for.
* @param _offset Offset to start reading from.
* @param _length Number of bytes to read.
* @return _code Code read from the contract.
*/
function getCode(
address _address,
uint256 _offset,
...
...
@@ -27,6 +42,11 @@ library Lib_EthUtils {
return _code;
}
/**
* Gets the full code for a given address.
* @param _address Address to get code for.
* @return _code Full code of the contract.
*/
function getCode(
address _address
)
...
...
@@ -43,6 +63,11 @@ library Lib_EthUtils {
);
}
/**
* Gets the size of a contract's code in bytes.
* @param _address Address to get code size for.
* @return _codeSize Size of the contract's code in bytes.
*/
function getCodeSize(
address _address
)
...
...
@@ -59,6 +84,11 @@ library Lib_EthUtils {
return _codeSize;
}
/**
* Gets the hash of a contract's code.
* @param _address Address to get a code hash for.
* @return _codeHash Hash of the contract's code.
*/
function getCodeHash(
address _address
)
...
...
@@ -75,6 +105,16 @@ library Lib_EthUtils {
return _codeHash;
}
/*****************************************
* Internal Functions: Contract Creation *
*****************************************/
/**
* Creates a contract with some given initialization code.
* @param _code Contract initialization code.
* @return _created Address of the created contract.
*/
function createContract(
bytes memory _code
)
...
...
@@ -94,6 +134,12 @@ library Lib_EthUtils {
return _created;
}
/**
* Computes the address that would be generated by CREATE.
* @param _creator Address creating the contract.
* @param _nonce Creator's nonce.
* @return _address Address to be generated by CREATE.
*/
function getAddressForCREATE(
address _creator,
uint256 _nonce
...
...
@@ -112,6 +158,13 @@ library Lib_EthUtils {
return getAddressFromHash(keccak256(encodedList));
}
/**
* Computes the address that would be generated by CREATE2.
* @param _creator Address creating the contract.
* @param _bytecode Bytecode of the contract to be created.
* @param _salt 32 byte salt value mixed into the hash.
* @return _address Address to be generated by CREATE2.
*/
function getAddressForCREATE2(
address _creator,
bytes memory _bytecode,
...
...
@@ -131,19 +184,26 @@ library Lib_EthUtils {
return getAddressFromHash(hashedData);
}
/****************************************
* Private Functions: Contract Creation *
****************************************/
/**
* Determines an address from a 32 byte hash. Since addresses are only
* 20 bytes, we need to retrieve the last 20 bytes from the original
* hash. Converting to uint256 and then uint160 gives us these bytes.
* @param _hash Hash to convert to an address.
* @return Hash converted to an address.
* @return
_address
Hash converted to an address.
*/
function getAddressFromHash(
bytes32 _hash
)
private
pure
returns (address)
returns (
address _address
)
{
return address(bytes20(uint160(uint256(_hash))));
}
...
...
packages/contracts/test/contracts/proxy/Proxy_Forwarder.spec.ts
deleted
100644 → 0
View file @
b439747a
import
{
expect
}
from
'
../../setup
'
/* External Imports */
import
{
ethers
}
from
'
@nomiclabs/buidler
'
import
{
Contract
,
ContractFactory
}
from
'
ethers
'
describe
(
'
Proxy_Forwarder
'
,
()
=>
{
describe
(
'
fallback
'
,
()
=>
{
})
})
packages/contracts/test/contracts/proxy/Proxy_Manager.spec.ts
deleted
100644 → 0
View file @
b439747a
import
{
expect
}
from
'
../../setup
'
/* External Imports */
import
{
ethers
}
from
'
@nomiclabs/buidler
'
import
{
Contract
,
ContractFactory
}
from
'
ethers
'
describe
(
'
Proxy_Manager
'
,
()
=>
{
describe
(
'
setProxy
'
,
()
=>
{
})
describe
(
'
getProxy
'
,
()
=>
{
})
describe
(
'
hasProxy
'
,
()
=>
{
})
describe
(
'
isProxy
'
,
()
=>
{
})
describe
(
'
setTarget
'
,
()
=>
{
})
describe
(
'
getTarget
'
,
()
=>
{
})
describe
(
'
hasTarget
'
,
()
=>
{
})
describe
(
'
isTarget
'
,
()
=>
{
})
})
packages/contracts/test/contracts/proxy/Proxy_Resolver.spec.ts
deleted
100644 → 0
View file @
b439747a
import
{
expect
}
from
'
../../setup
'
/* External Imports */
import
{
ethers
}
from
'
@nomiclabs/buidler
'
import
{
Contract
,
ContractFactory
}
from
'
ethers
'
describe
(
'
Proxy_Resolver
'
,
()
=>
{
describe
(
'
resolve
'
,
()
=>
{
})
})
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