Commit 7d72e069 authored by Kelvin Fichter's avatar Kelvin Fichter

Add Lib_SafeExecutionManagerWrapper

parent bb0b1814
...@@ -4,11 +4,11 @@ pragma experimental ABIEncoderV2; ...@@ -4,11 +4,11 @@ pragma experimental ABIEncoderV2;
/* Interface Imports */ /* Interface Imports */
import { iOVM_ECDSAContractAccount } from "../../iOVM/accounts/iOVM_ECDSAContractAccount.sol"; import { iOVM_ECDSAContractAccount } from "../../iOVM/accounts/iOVM_ECDSAContractAccount.sol";
import { iOVM_ExecutionManager } from "../../iOVM/execution/iOVM_ExecutionManager.sol";
/* Library Imports */ /* Library Imports */
import { Lib_OVMCodec } from "../../libraries/codec/Lib_OVMCodec.sol"; import { Lib_OVMCodec } from "../../libraries/codec/Lib_OVMCodec.sol";
import { Lib_ECDSAUtils } from "../../libraries/utils/Lib_ECDSAUtils.sol"; import { Lib_ECDSAUtils } from "../../libraries/utils/Lib_ECDSAUtils.sol";
import { Lib_SafeExecutionManagerWrapper } from "../../libraries/wrappers/Lib_SafeExecutionManagerWrapper.sol";
/** /**
* @title OVM_ECDSAContractAccount * @title OVM_ECDSAContractAccount
...@@ -43,7 +43,7 @@ contract OVM_ECDSAContractAccount is iOVM_ECDSAContractAccount { ...@@ -43,7 +43,7 @@ contract OVM_ECDSAContractAccount is iOVM_ECDSAContractAccount {
bytes memory _returndata bytes memory _returndata
) )
{ {
iOVM_ExecutionManager ovmExecutionManager = iOVM_ExecutionManager(msg.sender); address ovmExecutionManager = msg.sender;
// Address of this contract within the ovm (ovmADDRESS) should be the same as the // 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 // recovered address of the user who signed this message. This is how we manage to shim
...@@ -55,8 +55,8 @@ contract OVM_ECDSAContractAccount is iOVM_ECDSAContractAccount { ...@@ -55,8 +55,8 @@ contract OVM_ECDSAContractAccount is iOVM_ECDSAContractAccount {
_v, _v,
_r, _r,
_s, _s,
ovmExecutionManager.ovmCHAINID() Lib_SafeExecutionManagerWrapper.safeCHAINID(ovmExecutionManager)
) == ovmExecutionManager.ovmADDRESS(), ) == Lib_SafeExecutionManagerWrapper.safeADDRESS(ovmExecutionManager),
"Signature provided for EOA transaction execution is invalid." "Signature provided for EOA transaction execution is invalid."
); );
...@@ -64,14 +64,16 @@ contract OVM_ECDSAContractAccount is iOVM_ECDSAContractAccount { ...@@ -64,14 +64,16 @@ contract OVM_ECDSAContractAccount is iOVM_ECDSAContractAccount {
// Need to make sure that the transaction nonce is right and bump it if so. // Need to make sure that the transaction nonce is right and bump it if so.
require( require(
decodedTx.nonce == ovmExecutionManager.ovmGETNONCE() + 1, decodedTx.nonce == Lib_SafeExecutionManagerWrapper.safeGETNONCE(ovmExecutionManager) + 1,
"Transaction nonce does not match the expected nonce." "Transaction nonce does not match the expected nonce."
); );
ovmExecutionManager.ovmSETNONCE(decodedTx.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)) {
address created = ovmExecutionManager.ovmCREATE{gas: decodedTx.gasLimit}( address created = Lib_SafeExecutionManagerWrapper.safeCREATE(
ovmExecutionManager,
decodedTx.gasLimit,
decodedTx.data decodedTx.data
); );
...@@ -79,7 +81,8 @@ contract OVM_ECDSAContractAccount is iOVM_ECDSAContractAccount { ...@@ -79,7 +81,8 @@ 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 {
return ovmExecutionManager.ovmCALL( return Lib_SafeExecutionManagerWrapper.safeCALL(
ovmExecutionManager,
decodedTx.gasLimit, decodedTx.gasLimit,
decodedTx.target, decodedTx.target,
decodedTx.data decodedTx.data
......
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.7.0;
/**
* @title Lib_SafeExecutionManagerWrapper
*/
library Lib_SafeExecutionManagerWrapper {
/**********************
* Internal Functions *
**********************/
/**
* Makes an ovmCALL and performs all the necessary safety checks.
* @param _ovmExecutionManager Address of the OVM_ExecutionManager.
* @param _gasLimit Gas limit for the call.
* @param _target Address to call.
* @param _calldata Data to send to the call.
* @return _success Whether or not the call reverted.
* @return _returndata Data returned by the call.
*/
function safeCALL(
address _ovmExecutionManager,
uint256 _gasLimit,
address _target,
bytes memory _calldata
)
internal
returns (
bool _success,
bytes memory _returndata
)
{
bytes memory returndata = _safeExecutionManagerInteraction(
_ovmExecutionManager,
abi.encodeWithSignature(
"ovmCALL(uint256,address,bytes)",
_gasLimit,
_target,
_calldata
)
);
return abi.decode(returndata, (bool, bytes));
}
/**
* Performs an ovmCREATE and the necessary safety checks.
* @param _ovmExecutionManager Address of the OVM_ExecutionManager.
* @param _gasLimit Gas limit for the creation.
* @param _bytecode Code for the new contract.
* @return _contract Address of the created contract.
*/
function safeCREATE(
address _ovmExecutionManager,
uint256 _gasLimit,
bytes memory _bytecode
)
internal
returns (
address _contract
)
{
bytes memory returndata = _safeExecutionManagerInteraction(
_ovmExecutionManager,
_gasLimit,
abi.encodeWithSignature(
"ovmCREATE(bytes)",
_bytecode
)
);
return abi.decode(returndata, (address));
}
/**
* Performs a safe ovmCHAINID call.
* @param _ovmExecutionManager Address of the OVM_ExecutionManager.
* @return _CHAINID Result of calling ovmCHAINID.
*/
function safeCHAINID(
address _ovmExecutionManager
)
internal
returns (
uint256 _CHAINID
)
{
bytes memory returndata = _safeExecutionManagerInteraction(
_ovmExecutionManager,
abi.encodeWithSignature(
"ovmCHAINID()"
)
);
return abi.decode(returndata, (uint256));
}
/**
* Performs a safe ovmADDRESS call.
* @param _ovmExecutionManager Address of the OVM_ExecutionManager.
* @return _ADDRESS Result of calling ovmADDRESS.
*/
function safeADDRESS(
address _ovmExecutionManager
)
internal
returns (
address _ADDRESS
)
{
bytes memory returndata = _safeExecutionManagerInteraction(
_ovmExecutionManager,
abi.encodeWithSignature(
"ovmADDRESS()"
)
);
return abi.decode(returndata, (address));
}
/**
* Performs a safe ovmGETNONCE call.
* @param _ovmExecutionManager Address of the OVM_ExecutionManager.
* @return _nonce Result of calling ovmGETNONCE.
*/
function safeGETNONCE(
address _ovmExecutionManager
)
internal
returns (
uint256 _nonce
)
{
bytes memory returndata = _safeExecutionManagerInteraction(
_ovmExecutionManager,
abi.encodeWithSignature(
"ovmGETNONCE()"
)
);
return abi.decode(returndata, (uint256));
}
/**
* Performs a safe ovmSETNONCE call.
* @param _ovmExecutionManager Address of the OVM_ExecutionManager.
* @param _nonce New account nonce.
*/
function safeSETNONCE(
address _ovmExecutionManager,
uint256 _nonce
)
internal
{
_safeExecutionManagerInteraction(
_ovmExecutionManager,
abi.encodeWithSignature(
"ovmSETNONCE(uint256)",
_nonce
)
);
}
/*********************
* Private Functions *
*********************/
/**
* Performs an ovm interaction and the necessary safety checks.
* @param _ovmExecutionManager Address of the OVM_ExecutionManager.
* @param _gasLimit Gas limit for the interaction.
* @param _calldata Data to send to the OVM_ExecutionManager (encoded with sighash).
* @return _returndata Data sent back by the OVM_ExecutionManager.
*/
function _safeExecutionManagerInteraction(
address _ovmExecutionManager,
uint256 _gasLimit,
bytes memory _calldata
)
private
returns (
bytes memory _returndata
)
{
(
bool success,
bytes memory returndata
) = _ovmExecutionManager.call{gas: _gasLimit}(_calldata);
if (success == false) {
assembly {
revert(add(returndata, 0x20), mload(returndata))
}
} else if (returndata.length == 1) {
assembly {
return(0, 1)
}
} else {
return returndata;
}
}
function _safeExecutionManagerInteraction(
address _ovmExecutionManager,
bytes memory _calldata
)
private
returns (
bytes memory _returndata
)
{
return _safeExecutionManagerInteraction(
_ovmExecutionManager,
gasleft(),
_calldata
);
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment