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
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
...
@@ -3,14 +3,17 @@ pragma solidity ^0.7.0;
...
@@ -3,14 +3,17 @@ pragma solidity ^0.7.0;
pragma experimental ABIEncoderV2;
pragma experimental ABIEncoderV2;
/* Library Imports */
/* Library Imports */
import { Lib_OVMCodec } from "../../libraries/codec/Lib_OVMCodec.sol";
import { Lib_EthUtils } from "../../libraries/utils/Lib_EthUtils.sol";
import { Lib_EthUtils } from "../../libraries/utils/Lib_EthUtils.sol";
/* Interface Imports */
/* Interface Imports */
import { iOVM_DataTypes } from "../../iOVM/codec/iOVM_DataTypes.sol";
import { iOVM_ExecutionManager } from "../../iOVM/execution/iOVM_ExecutionManager.sol";
import { iOVM_ExecutionManager } from "../../iOVM/execution/iOVM_ExecutionManager.sol";
import { iOVM_StateManager } from "../../iOVM/execution/iOVM_StateManager.sol";
import { iOVM_StateManager } from "../../iOVM/execution/iOVM_StateManager.sol";
import { iOVM_SafetyChecker } from "../../iOVM/execution/iOVM_SafetyChecker.sol";
import { iOVM_SafetyChecker } from "../../iOVM/execution/iOVM_SafetyChecker.sol";
/* Contract Imports */
import { OVM_ECDSAContractAccount } from "../accounts/OVM_ECDSAContractAccount.sol";
/**
/**
* @title OVM_ExecutionManager
* @title OVM_ExecutionManager
*/
*/
...
@@ -93,7 +96,7 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager {
...
@@ -93,7 +96,7 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager {
* @param _ovmStateManager iOVM_StateManager implementation providing account state.
* @param _ovmStateManager iOVM_StateManager implementation providing account state.
*/
*/
function run(
function run(
iOVM_DataTypes.OVMTransactionData
memory _transaction,
Lib_OVMCodec.Transaction
memory _transaction,
address _ovmStateManager
address _ovmStateManager
)
)
override
override
...
@@ -235,7 +238,7 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager {
...
@@ -235,7 +238,7 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager {
// Generate the correct CREATE address.
// Generate the correct CREATE address.
address contractAddress = Lib_EthUtils.getAddressForCREATE(
address contractAddress = Lib_EthUtils.getAddressForCREATE(
creator,
creator,
_getAccount
(creator).nonce
_getAccount
Nonce(creator)
);
);
_createContract(
_createContract(
...
@@ -282,6 +285,101 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager {
...
@@ -282,6 +285,101 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager {
}
}
/*******************************
* Account Abstraction Opcodes *
******************************/
/**
* Retrieves the nonce of the current ovmADDRESS.
* @return _nonce Nonce of the current contract.
*/
function ovmGETNONCE()
override
public
returns (
uint256 _nonce
)
{
return _getAccountNonce(ovmADDRESS());
}
/**
* Sets the nonce of the current ovmADDRESS.
* @param _nonce New nonce for the current contract.
*/
function ovmSETNONCE(
uint256 _nonce
)
override
public
{
if (_nonce <= ovmGETNONCE()) {
return;
}
_setAccountNonce(ovmADDRESS(), _nonce);
}
/**
* Creates a new EOA contract account, for account abstraction.
* @dev Essentially functions like ovmCREATE or ovmCREATE2, but we can bypass a lot of checks
* because the contract we're creating is trusted (no need to do safety checking or to
* handle unexpected reverts). Doesn't need to return an address because the address is
* assumed to be the user's actual address.
* @param _messageHash Hash of a message signed by some user, for verification.
* @param _v Signature `v` parameter.
* @param _r Signature `r` parameter.
* @param _s Signature `s` parameter.
*/
function ovmCREATEEOA(
bytes32 _messageHash,
uint8 _v,
bytes32 _r,
bytes32 _s
)
override
public
{
// Recover the EOA address from the message hash and signature parameters. Since we do the
// hashing in advance, we don't have handle different message hashing schemes. Even if this
// function were to return the wrong address (rather than explicitly returning the zero
// address), the rest of the transaction would simply fail (since there's no EOA account to
// actually execute the transaction).
address eoa = ecrecover(
_messageHash,
(_v - uint8(ovmCHAINID()) * 2) - 8,
_r,
_s
);
// Invalid signature is a case we proactively handle with a revert. We could alternatively
// have this function return a `success` boolean, but this is just easier.
if (eoa == address(0)) {
ovmREVERT(bytes("Signature provided for EOA contract creation is invalid."));
}
// If the user already has an EOA account, then there's no need to perform this operation.
if (_hasAccount(eoa) == true) {
return;
}
// We always need to initialize the contract with the default account values.
_initPendingAccount(eoa);
// Now actually create the account and get its bytecode. We're not worried about reverts
// (other than out of gas, which we can't capture anyway) because this contract is trusted.
OVM_ECDSAContractAccount eoaContractAccount = new OVM_ECDSAContractAccount();
bytes memory deployedCode = Lib_EthUtils.getCode(address(eoaContractAccount));
// Commit the account with its final values.
_commitPendingAccount(
eoa,
address(eoaContractAccount),
keccak256(deployedCode)
);
}
/*********************************
/*********************************
* Opcodes: Contract Interaction *
* Opcodes: Contract Interaction *
*********************************/
*********************************/
...
@@ -470,7 +568,7 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager {
...
@@ -470,7 +568,7 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager {
uint256 length = _length == 1 ? 2 : _length;
uint256 length = _length == 1 ? 2 : _length;
return Lib_EthUtils.getCode(
return Lib_EthUtils.getCode(
_getAccount
(_contract).ethAddress
,
_getAccount
EthAddress(_contract)
,
_offset,
_offset,
_length
_length
);
);
...
@@ -491,7 +589,7 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager {
...
@@ -491,7 +589,7 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager {
)
)
{
{
return Lib_EthUtils.getCodeSize(
return Lib_EthUtils.getCodeSize(
_getAccount
(_contract).ethAddress
_getAccount
EthAddress(_contract)
);
);
}
}
...
@@ -510,7 +608,7 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager {
...
@@ -510,7 +608,7 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager {
)
)
{
{
return Lib_EthUtils.getCodeHash(
return Lib_EthUtils.getCodeHash(
_getAccount
(_contract).ethAddress
_getAccount
EthAddress(_contract)
);
);
}
}
...
@@ -599,7 +697,7 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager {
...
@@ -599,7 +697,7 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager {
internal
internal
{
{
// 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.
_
incrementAccountNonce(ovmADDRESS()
);
_
setAccountNonce(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.
// to the contract's associated address.
...
@@ -648,7 +746,7 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager {
...
@@ -648,7 +746,7 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager {
return _handleExternalInteraction(
return _handleExternalInteraction(
_nextMessageContext,
_nextMessageContext,
_gasLimit,
_gasLimit,
_getAccount
(_contract).ethAddress
,
_getAccount
EthAddress(_contract)
,
_calldata
_calldata
);
);
}
}
...
@@ -749,54 +847,69 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager {
...
@@ -749,54 +847,69 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager {
******************************************/
******************************************/
/**
/**
*
Retrieves an account from
the OVM_StateManager.
*
Checks whether an account exists within
the OVM_StateManager.
* @param _address Address of the account to
retrieve
.
* @param _address Address of the account to
check
.
* @return _
account Retrieved account object
.
* @return _
exists Whether or not the account exists
.
*/
*/
function _
get
Account(
function _
has
Account(
address _address
address _address
)
)
internal
internal
returns (
returns (
iOVM_DataTypes.OVMAccount memory _account
bool _exists
)
)
{
{
// We need to make sure that the transaction isn't trying to access an account that hasn't
_checkAccountLoad(_address);
// been provided to the OVM_StateManager. We'll immediately abort if this is the case.
return ovmStateManager.hasAccount(_address);
_checkInvalidStateAccess(
}
ovmStateManager.hasAccount(_address)
);
// Check whether the account has been loaded before and mark it as loaded if not. We need
// this because "nuisance gas" only applies to the first time that an account is loaded.
(
bool _wasAccountAlreadyLoaded
) = ovmStateManager.testAndSetAccountLoaded(_address);
// Actually retrieve the account.
iOVM_DataTypes.OVMAccount memory account = ovmStateManager.getAccount(_address);
// If we hadn't already loaded the account, then we'll need to charge "nuisance gas" based
/**
// on the size of the contract code.
* Sets the nonce of an account.
if (_wasAccountAlreadyLoaded == false) {
* @param _address Address of the account to modify.
_useNuisanceGas(
* @param _nonce New account nonce.
Lib_EthUtils.getCodeSize(account.ethAddress) * NUISANCE_GAS_PER_CONTRACT_BYTE
*/
);
function _setAccountNonce(
}
address _address,
uint256 _nonce
)
internal
{
_checkAccountChange(_address);
ovmStateManager.setAccountNonce(_address, _nonce);
}
return account;
/**
* Gets the nonce of an account.
* @param _address Address of the account to access.
* @return _nonce Nonce of the account.
*/
function _getAccountNonce(
address _address
)
internal
returns (
uint256 _nonce
)
{
_checkAccountLoad(_address);
return ovmStateManager.getAccountNonce(_address);
}
}
/**
/**
* Increments the nonce of an account.
* Retrieves the Ethereum address of an account.
* @param _address Address of the account to bump.
* @param _address Address of the account to access.
* @return _ethAddress Corresponding Ethereum address.
*/
*/
function _
incrementAccountNonce
(
function _
getAccountEthAddress
(
address _address
address _address
)
)
internal
internal
returns (
address _ethAddress
)
{
{
ovmStateManager.incrementAccountNonce(_address);
_checkAccountLoad(_address);
ovmStateManager.getAccountEthAddress(_address);
}
}
/**
/**
...
@@ -808,6 +921,7 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager {
...
@@ -808,6 +921,7 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager {
)
)
internal
internal
{
{
_checkAccountChange(_address);
ovmStateManager.initPendingAccount(_address);
ovmStateManager.initPendingAccount(_address);
}
}
...
@@ -826,21 +940,7 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager {
...
@@ -826,21 +940,7 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager {
)
)
internal
internal
{
{
// Check whether the account has been changed before and mark it as changed if not. We need
_checkAccountChange(_address);
// this because "nuisance gas" only applies to the first time that an account is changed.
(
bool _wasAccountAlreadyChanged
) = ovmStateManager.testAndSetAccountChanged(_address);
// If we hadn't already changed the account, then we'll need to charge "nuisance gas" based
// on the size of the contract code.
if (_wasAccountAlreadyChanged == false) {
_useNuisanceGas(
Lib_EthUtils.getCodeSize(_ethAddress) * NUISANCE_GAS_PER_CONTRACT_BYTE
);
}
// Actually commit the contract.
ovmStateManager.commitPendingAccount(
ovmStateManager.commitPendingAccount(
_address,
_address,
_ethAddress,
_ethAddress,
...
@@ -862,6 +962,95 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager {
...
@@ -862,6 +962,95 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager {
returns (
returns (
bytes32 _value
bytes32 _value
)
)
{
_checkContractStorageLoad(_contract, _key);
return ovmStateManager.getContractStorage(_contract, _key);
}
/**
* Sets the value of a storage slot.
* @param _contract Address of the contract to modify.
* @param _key 32 byte key of the storage slot.
* @param _value 32 byte storage slot value.
*/
function _putContractStorage(
address _contract,
bytes32 _key,
bytes32 _value
)
internal
{
_checkContractStorageChange(_contract, _key);
ovmStateManager.putContractStorage(_contract, _key, _value);
}
/**
* Validation whenever a contract needs to be loaded. Checks that the account exists, charges
* nuisance gas if the account hasn't been loaded before.
* @param _address Address of the account to load.
*/
function _checkAccountLoad(
address _address
)
internal
{
// We need to make sure that the transaction isn't trying to access an account that hasn't
// been provided to the OVM_StateManager. We'll immediately abort if this is the case.
_checkInvalidStateAccess(
ovmStateManager.hasAccount(_address)
);
// Check whether the account has been loaded before and mark it as loaded if not. We need
// this because "nuisance gas" only applies to the first time that an account is loaded.
(
bool _wasAccountAlreadyLoaded
) = ovmStateManager.testAndSetAccountLoaded(_address);
// If we hadn't already loaded the account, then we'll need to charge "nuisance gas" based
// on the size of the contract code.
if (_wasAccountAlreadyLoaded == false) {
_useNuisanceGas(
Lib_EthUtils.getCodeSize(_getAccountEthAddress(_address)) * NUISANCE_GAS_PER_CONTRACT_BYTE
);
}
}
/**
* Validation whenever a contract needs to be changed. Checks that the account exists, charges
* nuisance gas if the account hasn't been changed before.
* @param _address Address of the account to change.
*/
function _checkAccountChange(
address _address
)
internal
{
// Check whether the account has been changed before and mark it as changed if not. We need
// this because "nuisance gas" only applies to the first time that an account is changed.
(
bool _wasAccountAlreadyChanged
) = ovmStateManager.testAndSetAccountChanged(_address);
// If we hadn't already changed the account, then we'll need to charge "nuisance gas" based
// on the size of the contract code.
if (_wasAccountAlreadyChanged == false) {
_useNuisanceGas(
Lib_EthUtils.getCodeSize(_getAccountEthAddress(_address)) * NUISANCE_GAS_PER_CONTRACT_BYTE
);
}
}
/**
* Validation whenever a slot needs to be loaded. Checks that the account exists, charges
* nuisance gas if the slot hasn't been loaded before.
* @param _contract Address of the account to load from.
* @param _key 32 byte key to load.
*/
function _checkContractStorageLoad(
address _contract,
bytes32 _key
)
internal
{
{
// We need to make sure that the transaction isn't trying to access storage that hasn't
// We need to make sure that the transaction isn't trying to access storage that hasn't
// been provided to the OVM_StateManager. We'll immediately abort if this is the case.
// been provided to the OVM_StateManager. We'll immediately abort if this is the case.
...
@@ -880,21 +1069,17 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager {
...
@@ -880,21 +1069,17 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager {
if (_wasContractStorageAlreadyLoaded == false) {
if (_wasContractStorageAlreadyLoaded == false) {
_useNuisanceGas(NUISANCE_GAS_SLOAD);
_useNuisanceGas(NUISANCE_GAS_SLOAD);
}
}
// Actually retrieve the storage slot.
return ovmStateManager.getContractStorage(_contract, _key);
}
}
/**
/**
*
Sets the value of a storage slot.
*
Validation whenever a slot needs to be changed. Checks that the account exists, charges
*
@param _contract Address of the contract to modify
.
*
nuisance gas if the slot hasn't been changed before
.
* @param _
key 32 byte key of the storage slot
.
* @param _
contract Address of the account to change
.
* @param _
value 32 byte storage slot valu
e.
* @param _
key 32 byte key to chang
e.
*/
*/
function _
putContractStora
ge(
function _
checkContractStorageChan
ge(
address _contract,
address _contract,
bytes32 _key,
bytes32 _key
bytes32 _value
)
)
internal
internal
{
{
...
@@ -909,9 +1094,6 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager {
...
@@ -909,9 +1094,6 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager {
if (_wasContractStorageAlreadyChanged == false) {
if (_wasContractStorageAlreadyChanged == false) {
_useNuisanceGas(NUISANCE_GAS_SSTORE);
_useNuisanceGas(NUISANCE_GAS_SSTORE);
}
}
// Actually modify the storage slot.
ovmStateManager.putContractStorage(_contract, _key, _value);
}
}
...
...
packages/contracts/contracts/optimistic-ethereum/OVM/execution/OVM_SafetyChecker.sol
View file @
9b464f1d
...
@@ -4,7 +4,20 @@ pragma solidity ^0.7.0;
...
@@ -4,7 +4,20 @@ pragma solidity ^0.7.0;
/* Interface Imports */
/* Interface Imports */
import { iOVM_SafetyChecker } from "../../iOVM/execution/iOVM_SafetyChecker.sol";
import { iOVM_SafetyChecker } from "../../iOVM/execution/iOVM_SafetyChecker.sol";
/**
* @title OVM_SafetyChecker
*/
contract OVM_SafetyChecker is iOVM_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(
function isBytecodeSafe(
bytes memory _bytecode
bytes memory _bytecode
)
)
...
...
packages/contracts/contracts/optimistic-ethereum/OVM/execution/OVM_StateManager.sol
View file @
9b464f1d
...
@@ -2,26 +2,39 @@
...
@@ -2,26 +2,39 @@
pragma solidity ^0.7.0;
pragma solidity ^0.7.0;
pragma experimental ABIEncoderV2;
pragma experimental ABIEncoderV2;
/* Library Imports */
import { Lib_OVMCodec } from "../../libraries/codec/Lib_OVMCodec.sol";
/* Interface Imports */
/* Interface Imports */
import { iOVM_StateManager } from "../../iOVM/execution/iOVM_StateManager.sol";
import { iOVM_StateManager } from "../../iOVM/execution/iOVM_StateManager.sol";
import { iOVM_DataTypes } from "../../iOVM/codec/iOVM_DataTypes.sol";
/**
* @title OVM_StateManager
*/
contract OVM_StateManager is iOVM_StateManager {
contract OVM_StateManager is iOVM_StateManager {
enum ItemState {
ITEM_UNTOUCHED,
ITEM_LOADED,
ITEM_CHANGED
}
mapping (address => iOVM_DataTypes.OVMAccount) public accounts;
/****************************************
mapping (address => iOVM_DataTypes.OVMAccount) public pendingAccounts;
* Contract Variables: Internal Storage *
mapping (address => mapping (bytes32 => bytes32)) public contractStorage;
****************************************/
mapping (address => mapping (bytes32 => bool)) public verifiedContractStorage;
mapping (bytes32 => ItemState) public itemStates;
mapping (address => Lib_OVMCodec.Account) internal accounts;
mapping (address => mapping (bytes32 => bytes32)) internal contractStorage;
mapping (address => mapping (bytes32 => bool)) internal verifiedContractStorage;
mapping (bytes32 => ItemState) internal itemStates;
/************************************
* Public Functions: Account Access *
************************************/
/**
* Inserts an account into the state.
* @param _address Address of the account to insert.
* @param _account Account to insert for the given address.
*/
function putAccount(
function putAccount(
address _address,
address _address,
iOVM_DataTypes.OVM
Account memory _account
Lib_OVMCodec.
Account memory _account
)
)
override
override
public
public
...
@@ -29,16 +42,26 @@ contract OVM_StateManager is iOVM_StateManager {
...
@@ -29,16 +42,26 @@ contract OVM_StateManager is iOVM_StateManager {
accounts[_address] = _account;
accounts[_address] = _account;
}
}
/**
* Retrieves an account from the state.
* @param _address Address of the account to retrieve.
* @return _account Account for the given address.
*/
function getAccount(address _address)
function getAccount(address _address)
override
override
public
public
returns (
returns (
iOVM_DataTypes.OVM
Account memory _account
Lib_OVMCodec.
Account memory _account
)
)
{
{
return accounts[_address];
return accounts[_address];
}
}
/**
* Checks whether the state has a given account.
* @param _address Address of the account to check.
* @return _exists Whether or not the state has the account.
*/
function hasAccount(
function hasAccount(
address _address
address _address
)
)
...
@@ -48,29 +71,79 @@ contract OVM_StateManager is iOVM_StateManager {
...
@@ -48,29 +71,79 @@ contract OVM_StateManager is iOVM_StateManager {
bool _exists
bool _exists
)
)
{
{
return getAccount(_address).codeHash != bytes32(0);
return accounts[_address].codeHash != bytes32(0);
}
/**
* Sets the nonce of an account.
* @param _address Address of the account to modify.
* @param _nonce New account nonce.
*/
function setAccountNonce(
address _address,
uint256 _nonce
)
override
public
{
accounts[_address].nonce = _nonce;
}
}
function incrementAccountNonce(
/**
* Gets the nonce of an account.
* @param _address Address of the account to access.
* @return _nonce Nonce of the account.
*/
function getAccountNonce(
address _address
address _address
)
)
override
override
public
public
returns (
uint256 _nonce
)
{
{
accounts[_address].nonce += 1
;
return accounts[_address].nonce
;
}
}
/**
* Retrieves the Ethereum address of an account.
* @param _address Address of the account to access.
* @return _ethAddress Corresponding Ethereum address.
*/
function getAccountEthAddress(
address _address
)
override
public
returns (
address _ethAddress
)
{
return accounts[_address].ethAddress;
}
/**
* Initializes a pending account (during CREATE or CREATE2) with the default values.
* @param _address Address of the account to initialize.
*/
function initPendingAccount(
function initPendingAccount(
address _address
address _address
)
)
override
override
public
public
{
{
iOVM_DataTypes.OVM
Account storage account = accounts[_address];
Lib_OVMCodec.
Account storage account = accounts[_address];
account.nonce = 1;
account.nonce = 1;
account.codeHash = keccak256(hex'80');
account.codeHash = keccak256(hex'80');
}
}
/**
* Finalizes the creation of a pending account (during CREATE or CREATE2).
* @param _address Address of the account to finalize.
* @param _ethAddress Address of the account's associated contract on Ethereum.
* @param _codeHash Hash of the account's code.
*/
function commitPendingAccount(
function commitPendingAccount(
address _address,
address _address,
address _ethAddress,
address _ethAddress,
...
@@ -79,11 +152,62 @@ contract OVM_StateManager is iOVM_StateManager {
...
@@ -79,11 +152,62 @@ contract OVM_StateManager is iOVM_StateManager {
override
override
public
public
{
{
iOVM_DataTypes.OVM
Account storage account = accounts[_address];
Lib_OVMCodec.
Account storage account = accounts[_address];
account.ethAddress = _ethAddress;
account.ethAddress = _ethAddress;
account.codeHash = _codeHash;
account.codeHash = _codeHash;
}
}
/**
* Checks whether an account has already been retrieved, and marks it as retrieved if not.
* @param _address Address of the account to check.
* @return _wasAccountAlreadyLoaded Whether or not the account was already loaded.
*/
function testAndSetAccountLoaded(
address _address
)
override
public
returns (
bool _wasAccountAlreadyLoaded
)
{
return _testItemState(
keccak256(abi.encodePacked(_address)),
ItemState.ITEM_LOADED
);
}
/**
* Checks whether an account has already been modified, and marks it as modified if not.
* @param _address Address of the account to check.
* @return _wasAccountAlreadyChanged Whether or not the account was already modified.
*/
function testAndSetAccountChanged(
address _address
)
override
public
returns (
bool _wasAccountAlreadyChanged
)
{
return _testItemState(
keccak256(abi.encodePacked(_address)),
ItemState.ITEM_CHANGED
);
}
/************************************
* Public Functions: Storage Access *
************************************/
/**
* Changes a contract storage slot value.
* @param _contract Address of the contract to modify.
* @param _key 32 byte storage slot key.
* @param _value 32 byte storage slot value.
*/
function putContractStorage(
function putContractStorage(
address _contract,
address _contract,
bytes32 _key,
bytes32 _key,
...
@@ -96,6 +220,12 @@ contract OVM_StateManager is iOVM_StateManager {
...
@@ -96,6 +220,12 @@ contract OVM_StateManager is iOVM_StateManager {
verifiedContractStorage[_contract][_key] = true;
verifiedContractStorage[_contract][_key] = true;
}
}
/**
* Retrieves a contract storage slot value.
* @param _contract Address of the contract to access.
* @param _key 32 byte storage slot key.
* @return _value 32 byte storage slot value.
*/
function getContractStorage(
function getContractStorage(
address _contract,
address _contract,
bytes32 _key
bytes32 _key
...
@@ -109,6 +239,12 @@ contract OVM_StateManager is iOVM_StateManager {
...
@@ -109,6 +239,12 @@ contract OVM_StateManager is iOVM_StateManager {
return contractStorage[_contract][_key];
return contractStorage[_contract][_key];
}
}
/**
* Checks whether a contract storage slot exists in the state.
* @param _contract Address of the contract to access.
* @param _key 32 byte storage slot key.
* @return _exists Whether or not the key was set in the state.
*/
function hasContractStorage(
function hasContractStorage(
address _contract,
address _contract,
bytes32 _key
bytes32 _key
...
@@ -121,37 +257,13 @@ contract OVM_StateManager is iOVM_StateManager {
...
@@ -121,37 +257,13 @@ contract OVM_StateManager is iOVM_StateManager {
{
{
return verifiedContractStorage[_contract][_key];
return verifiedContractStorage[_contract][_key];
}
}
function testAndSetAccountLoaded(
address _address
)
override
public
returns (
bool _wasAccountAlreadyLoaded
)
{
return _testItemState(
keccak256(abi.encodePacked(_address)),
ItemState.ITEM_LOADED
);
}
function testAndSetAccountChanged(
address _address
)
override
public
returns (
bool _wasAccountAlreadyChanged
)
{
return _testItemState(
keccak256(abi.encodePacked(_address)),
ItemState.ITEM_CHANGED
);
}
/**
* Checks whether a storage slot has already been retrieved, and marks it as retrieved if not.
* @param _contract Address of the contract to check.
* @param _key 32 byte storage slot key.
* @return _wasContractStorageAlreadyLoaded Whether or not the slot was already loaded.
*/
function testAndSetContractStorageLoaded(
function testAndSetContractStorageLoaded(
address _contract,
address _contract,
bytes32 _key
bytes32 _key
...
@@ -168,6 +280,12 @@ contract OVM_StateManager is iOVM_StateManager {
...
@@ -168,6 +280,12 @@ contract OVM_StateManager is iOVM_StateManager {
);
);
}
}
/**
* Checks whether a storage slot has already been modified, and marks it as modified if not.
* @param _contract Address of the contract to check.
* @param _key 32 byte storage slot key.
* @return _wasContractStorageAlreadyChanged Whether or not the slot was already modified.
*/
function testAndSetContractStorageChanged(
function testAndSetContractStorageChanged(
address _contract,
address _contract,
bytes32 _key
bytes32 _key
...
@@ -185,10 +303,17 @@ contract OVM_StateManager is iOVM_StateManager {
...
@@ -185,10 +303,17 @@ contract OVM_StateManager is iOVM_StateManager {
}
}
/*
/*
*********************
* Internal Functions
* Internal Functions
*
*/
*
*********************
/
/**
* Checks whether an item is in a particular state (ITEM_LOADED or ITEM_CHANGED) and sets the
* item to the provided state if not.
* @param _item 32 byte item ID to check.
* @param _minItemState Minumum state that must be satisfied by the item.
* @return _wasItemState Whether or not the item was already in the state.
*/
function _testItemState(
function _testItemState(
bytes32 _item,
bytes32 _item,
ItemState _minItemState
ItemState _minItemState
...
...
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 @@
...
@@ -2,10 +2,14 @@
pragma solidity ^0.7.0;
pragma solidity ^0.7.0;
pragma experimental ABIEncoderV2;
pragma experimental ABIEncoderV2;
/*
Interface
Imports */
/*
Library
Imports */
import {
iOVM_DataTypes } from "../codec/iOVM_DataTypes
.sol";
import {
Lib_OVMCodec } from "../../libraries/codec/Lib_OVMCodec
.sol";
interface iOVM_ExecutionManager {
interface iOVM_ExecutionManager {
/*******************
* Data Structures *
*******************/
enum RevertFlag {
enum RevertFlag {
DID_NOT_REVERT,
DID_NOT_REVERT,
OUT_OF_GAS,
OUT_OF_GAS,
...
@@ -42,8 +46,13 @@ interface iOVM_ExecutionManager {
...
@@ -42,8 +46,13 @@ interface iOVM_ExecutionManager {
RevertFlag revertFlag;
RevertFlag revertFlag;
}
}
/************************************
* Transaction Execution Entrypoint *
************************************/
function run(
function run(
iOVM_DataTypes.OVMTransactionData
calldata _transaction,
Lib_OVMCodec.Transaction
calldata _transaction,
address _txStateManager
address _txStateManager
) external;
) external;
...
@@ -73,7 +82,15 @@ interface iOVM_ExecutionManager {
...
@@ -73,7 +82,15 @@ interface iOVM_ExecutionManager {
function ovmCREATE(bytes memory _bytecode) external returns (address _contract);
function ovmCREATE(bytes memory _bytecode) external returns (address _contract);
function ovmCREATE2(bytes memory _bytecode, bytes32 _salt) 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 {
...
@@ -100,4 +117,11 @@ interface iOVM_ExecutionManager {
function ovmEXTCODECOPY(address _contract, uint256 _offset, uint256 _length) external returns (bytes memory _code);
function ovmEXTCODECOPY(address _contract, uint256 _offset, uint256 _length) external returns (bytes memory _code);
function ovmEXTCODESIZE(address _contract) external returns (uint256 _size);
function ovmEXTCODESIZE(address _contract) external returns (uint256 _size);
function ovmEXTCODEHASH(address _contract) external returns (bytes32 _hash);
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
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.7.0;
pragma solidity ^0.7.0;
/**
* @title iOVM_SafetyChecker
*/
interface iOVM_SafetyChecker {
interface iOVM_SafetyChecker {
/********************
* Public Functions *
********************/
function isBytecodeSafe(bytes memory _bytecode) external view returns (bool _safe);
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 @@
...
@@ -2,25 +2,48 @@
pragma solidity ^0.7.0;
pragma solidity ^0.7.0;
pragma experimental ABIEncoderV2;
pragma experimental ABIEncoderV2;
/*
Interface
Imports */
/*
Library
Imports */
import {
iOVM_DataTypes } from "../codec/iOVM_DataTypes
.sol";
import {
Lib_OVMCodec } from "../../libraries/codec/Lib_OVMCodec
.sol";
/**
* @title iOVM_StateManager
*/
interface 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 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 initPendingAccount(address _address) external;
function commitPendingAccount(address _address, address _ethAddress, bytes32 _codeHash) 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 putContractStorage(address _contract, bytes32 _key, bytes32 _value) external;
function getContractStorage(address _contract, bytes32 _key) external returns (bytes32 _value);
function getContractStorage(address _contract, bytes32 _key) external returns (bytes32 _value);
function hasContractStorage(address _contract, bytes32 _key) external returns (bool _exists);
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 testAndSetContractStorageLoaded(address _contract, bytes32 _key) external returns (bool _wasContractStorageAlreadyLoaded);
function testAndSetContractStorageChanged(address _contract, bytes32 _key) external returns (bool _wasContractStorageAlreadyChanged);
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
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.7.0;
pragma solidity ^0.7.0;
pragma experimental ABIEncoderV2;
interface iOVM_DataTypes {
/* Library Imports */
struct OVMAccount {
import { Lib_RLPReader } from "../rlp/Lib_RLPReader.sol";
uint256 nonce;
uint256 balance;
/**
bytes32 storageRoot;
* @title Lib_OVMCodec
bytes32 codeHash;
*/
address ethAddress;
library Lib_OVMCodec {
}
/*******************
* Data Structures *
*******************/
struct
EVM
Account {
struct Account {
uint256 nonce;
uint256 nonce;
uint256 balance;
uint256 balance;
bytes32 storageRoot;
bytes32 storageRoot;
bytes32 codeHash;
bytes32 codeHash;
address ethAddress;
}
}
struct
OVM
ChainBatchHeader {
struct ChainBatchHeader {
uint256 batchIndex;
uint256 batchIndex;
bytes32 batchRoot;
bytes32 batchRoot;
uint256 batchSize;
uint256 batchSize;
...
@@ -25,12 +30,12 @@ interface iOVM_DataTypes {
...
@@ -25,12 +30,12 @@ interface iOVM_DataTypes {
bytes extraData;
bytes extraData;
}
}
struct
OVM
ChainInclusionProof {
struct ChainInclusionProof {
uint256 index;
uint256 index;
bytes32[] siblings;
bytes32[] siblings;
}
}
struct
OVMTransactionData
{
struct
Transaction
{
uint256 timestamp;
uint256 timestamp;
uint256 queueOrigin;
uint256 queueOrigin;
address entrypoint;
address entrypoint;
...
@@ -40,16 +45,57 @@ interface iOVM_DataTypes {
...
@@ -40,16 +45,57 @@ interface iOVM_DataTypes {
bytes data;
bytes data;
}
}
struct
OVM
ProofMatrix {
struct ProofMatrix {
bool checkNonce;
bool checkNonce;
bool checkBalance;
bool checkBalance;
bool checkStorageRoot;
bool checkStorageRoot;
bool checkCodeHash;
bool checkCodeHash;
}
}
struct
OVM
QueueElement {
struct QueueElement {
uint256 timestamp;
uint256 timestamp;
bytes32 batchRoot;
bytes32 batchRoot;
bool isL1ToL2Batch;
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;
...
@@ -5,7 +5,22 @@ pragma experimental ABIEncoderV2;
/* Library Imports */
/* Library Imports */
import { Lib_RLPWriter } from "../rlp/Lib_RLPWriter.sol";
import { Lib_RLPWriter } from "../rlp/Lib_RLPWriter.sol";
/**
* @title Lib_EthUtils
*/
library 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(
function getCode(
address _address,
address _address,
uint256 _offset,
uint256 _offset,
...
@@ -27,6 +42,11 @@ library Lib_EthUtils {
...
@@ -27,6 +42,11 @@ library Lib_EthUtils {
return _code;
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(
function getCode(
address _address
address _address
)
)
...
@@ -43,6 +63,11 @@ library Lib_EthUtils {
...
@@ -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(
function getCodeSize(
address _address
address _address
)
)
...
@@ -59,6 +84,11 @@ library Lib_EthUtils {
...
@@ -59,6 +84,11 @@ library Lib_EthUtils {
return _codeSize;
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(
function getCodeHash(
address _address
address _address
)
)
...
@@ -75,6 +105,16 @@ library Lib_EthUtils {
...
@@ -75,6 +105,16 @@ library Lib_EthUtils {
return _codeHash;
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(
function createContract(
bytes memory _code
bytes memory _code
)
)
...
@@ -94,6 +134,12 @@ library Lib_EthUtils {
...
@@ -94,6 +134,12 @@ library Lib_EthUtils {
return _created;
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(
function getAddressForCREATE(
address _creator,
address _creator,
uint256 _nonce
uint256 _nonce
...
@@ -112,6 +158,13 @@ library Lib_EthUtils {
...
@@ -112,6 +158,13 @@ library Lib_EthUtils {
return getAddressFromHash(keccak256(encodedList));
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(
function getAddressForCREATE2(
address _creator,
address _creator,
bytes memory _bytecode,
bytes memory _bytecode,
...
@@ -131,19 +184,26 @@ library Lib_EthUtils {
...
@@ -131,19 +184,26 @@ library Lib_EthUtils {
return getAddressFromHash(hashedData);
return getAddressFromHash(hashedData);
}
}
/****************************************
* Private Functions: Contract Creation *
****************************************/
/**
/**
* Determines an address from a 32 byte hash. Since addresses are only
* 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
* 20 bytes, we need to retrieve the last 20 bytes from the original
* hash. Converting to uint256 and then uint160 gives us these bytes.
* hash. Converting to uint256 and then uint160 gives us these bytes.
* @param _hash Hash to convert to an address.
* @param _hash Hash to convert to an address.
* @return Hash converted to an address.
* @return
_address
Hash converted to an address.
*/
*/
function getAddressFromHash(
function getAddressFromHash(
bytes32 _hash
bytes32 _hash
)
)
private
private
pure
pure
returns (address)
returns (
address _address
)
{
{
return address(bytes20(uint160(uint256(_hash))));
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