Skip to content
This repository was archived by the owner on Apr 12, 2021. It is now read-only.
Draft
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,12 @@ pragma experimental ABIEncoderV2;
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_EIP155Tx } from "../../libraries/codec/Lib_EIP155Tx.sol";
import { Lib_SafeExecutionManagerWrapper } from "../../libraries/wrappers/Lib_SafeExecutionManagerWrapper.sol";
import { Lib_SafeMathWrapper } from "../../libraries/wrappers/Lib_SafeMathWrapper.sol";

import { console } from "hardhat/console.sol";
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know this is WIP, but just noting to remove this


/**
* @title OVM_ECDSAContractAccount
* @dev The ECDSA Contract Account can be used as the implementation for a ProxyEOA deployed by the
Expand All @@ -21,6 +22,8 @@ import { Lib_SafeMathWrapper } from "../../libraries/wrappers/Lib_SafeMathWrappe
* Runtime target: OVM
*/
contract OVM_ECDSAContractAccount is iOVM_ECDSAContractAccount {
using Lib_EIP155Tx for Lib_EIP155Tx.EIP155Tx;


/*************
* Constants *
Expand All @@ -38,20 +41,12 @@ contract OVM_ECDSAContractAccount is iOVM_ECDSAContractAccount {

/**
* 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.
* @param _encodedTransaction Signed EOA transaction.
* @return Whether or not the call returned (rather than reverted).
* @return Data returned by the call.
*/
function execute(
bytes memory _transaction,
Lib_OVMCodec.EOASignatureType _signatureType,
uint8 _v,
bytes32 _r,
bytes32 _s
bytes memory _encodedTransaction
)
override
public
Expand All @@ -60,34 +55,23 @@ contract OVM_ECDSAContractAccount is iOVM_ECDSAContractAccount {
bytes memory
)
{
bool isEthSign = _signatureType == Lib_OVMCodec.EOASignatureType.ETH_SIGNED_MESSAGE;
Lib_EIP155Tx.EIP155Tx memory transaction = Lib_EIP155Tx.decode(
_encodedTransaction,
Lib_SafeExecutionManagerWrapper.safeCHAINID()
);

// 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.
// Need to make sure that the transaction nonce is right and bump it if so.
Lib_SafeExecutionManagerWrapper.safeREQUIRE(
Lib_ECDSAUtils.recover(
_transaction,
isEthSign,
_v,
_r,
_s
) == Lib_SafeExecutionManagerWrapper.safeADDRESS(),
transaction.sender() == Lib_SafeExecutionManagerWrapper.safeADDRESS(),
"Signature provided for EOA transaction execution is invalid."
);

Lib_OVMCodec.EIP155Transaction memory decodedTx = Lib_OVMCodec.decodeEIP155Transaction(_transaction, isEthSign);

// Need to make sure that the transaction chainId is correct.
Lib_SafeExecutionManagerWrapper.safeREQUIRE(
decodedTx.chainId == Lib_SafeExecutionManagerWrapper.safeCHAINID(),
"Transaction chainId does not match expected OVM chainId."
);

// Need to make sure that the transaction nonce is right.
Lib_SafeExecutionManagerWrapper.safeREQUIRE(
decodedTx.nonce == Lib_SafeExecutionManagerWrapper.safeGETNONCE(),
transaction.nonce == Lib_SafeExecutionManagerWrapper.safeGETNONCE(),
"Transaction nonce does not match the expected nonce."
);

Expand All @@ -100,7 +84,7 @@ contract OVM_ECDSAContractAccount is iOVM_ECDSAContractAccount {

// Transfer fee to relayer.
address relayer = Lib_SafeExecutionManagerWrapper.safeCALLER();
uint256 fee = Lib_SafeMathWrapper.mul(decodedTx.gasLimit, decodedTx.gasPrice);
uint256 fee = Lib_SafeMathWrapper.mul(transaction.gasLimit, transaction.gasPrice);
(bool success, ) = Lib_SafeExecutionManagerWrapper.safeCALL(
gasleft(),
ETH_ERC20_ADDRESS,
Expand All @@ -111,11 +95,10 @@ contract OVM_ECDSAContractAccount is iOVM_ECDSAContractAccount {
"Fee was not transferred to relayer."
);

// Contract creations are signalled by sending a transaction to the zero address.
if (decodedTx.to == address(0)) {
if (transaction.isCreate) {
address created = Lib_SafeExecutionManagerWrapper.safeCREATE(
decodedTx.gasLimit,
decodedTx.data
transaction.gasLimit,
transaction.data
);

// EVM doesn't tell us whether a contract creation failed, even if it reverted during
Expand All @@ -125,12 +108,12 @@ contract OVM_ECDSAContractAccount is iOVM_ECDSAContractAccount {
// 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(decodedTx.nonce + 1);
Lib_SafeExecutionManagerWrapper.safeSETNONCE(transaction.nonce + 1);

return Lib_SafeExecutionManagerWrapper.safeCALL(
decodedTx.gasLimit,
decodedTx.to,
decodedTx.data
transaction.gasLimit,
transaction.to,
transaction.data
);
}
}
Expand Down
2 changes: 0 additions & 2 deletions contracts/optimistic-ethereum/OVM/accounts/OVM_ProxyEOA.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ pragma solidity >0.5.0 <0.8.0;

/* Library Imports */
import { Lib_Bytes32Utils } from "../../libraries/utils/Lib_Bytes32Utils.sol";
import { Lib_OVMCodec } from "../../libraries/codec/Lib_OVMCodec.sol";
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Files were unused, I removed them.

import { Lib_ECDSAUtils } from "../../libraries/utils/Lib_ECDSAUtils.sol";
import { Lib_SafeExecutionManagerWrapper } from "../../libraries/wrappers/Lib_SafeExecutionManagerWrapper.sol";

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@
pragma solidity >0.5.0 <0.8.0;

/* Library Imports */
import { Lib_BytesUtils } from "../../libraries/utils/Lib_BytesUtils.sol";
import { Lib_OVMCodec } from "../../libraries/codec/Lib_OVMCodec.sol";
import { Lib_ECDSAUtils } from "../../libraries/utils/Lib_ECDSAUtils.sol";
import { Lib_EIP155Tx } from "../../libraries/codec/Lib_EIP155Tx.sol";
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file gets way simpler.

import { Lib_SafeExecutionManagerWrapper } from "../../libraries/wrappers/Lib_SafeExecutionManagerWrapper.sol";

/**
Expand All @@ -19,109 +17,39 @@ import { Lib_SafeExecutionManagerWrapper } from "../../libraries/wrappers/Lib_Sa
* Runtime target: OVM
*/
contract OVM_SequencerEntrypoint {

/*********
* Enums *
*********/

enum TransactionType {
NATIVE_ETH_TRANSACTION,
ETH_SIGNED_MESSAGE
}
using Lib_EIP155Tx for Lib_EIP155Tx.EIP155Tx;


/*********************
* Fallback Function *
*********************/

/**
* Uses a custom "compressed" format to save on calldata gas:
* calldata[00:01]: transaction type (0 == EIP 155, 2 == Eth Sign Message)
* calldata[01:33]: signature "r" parameter
* calldata[33:65]: signature "s" parameter
* calldata[65:66]: signature "v" parameter
* calldata[66:69]: transaction gas limit
* calldata[69:72]: transaction gas price
* calldata[72:75]: transaction nonce
* calldata[75:95]: transaction target address
* calldata[95:XX]: transaction data
*/
fallback()
external
{
TransactionType transactionType = _getTransactionType(Lib_BytesUtils.toUint8(msg.data, 0));

bytes32 r = Lib_BytesUtils.toBytes32(Lib_BytesUtils.slice(msg.data, 1, 32));
bytes32 s = Lib_BytesUtils.toBytes32(Lib_BytesUtils.slice(msg.data, 33, 32));
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removes the calls to slice which is good

uint8 v = Lib_BytesUtils.toUint8(msg.data, 65);

// Remainder is the transaction to execute.
bytes memory compressedTx = Lib_BytesUtils.slice(msg.data, 66);
bool isEthSignedMessage = transactionType == TransactionType.ETH_SIGNED_MESSAGE;

// Need to decompress and then re-encode the transaction based on the original encoding.
bytes memory encodedTx = Lib_OVMCodec.encodeEIP155Transaction(
Lib_OVMCodec.decompressEIP155Transaction(compressedTx),
isEthSignedMessage
Lib_EIP155Tx.EIP155Tx memory transaction = Lib_EIP155Tx.decode(
msg.data,
Lib_SafeExecutionManagerWrapper.safeCHAINID()
);

address target = Lib_ECDSAUtils.recover(
encodedTx,
isEthSignedMessage,
uint8(v),
r,
s
);
address sender = transaction.sender();

if (Lib_SafeExecutionManagerWrapper.safeEXTCODESIZE(target) == 0) {
// ProxyEOA has not yet been deployed for this EOA.
bytes32 messageHash = Lib_ECDSAUtils.getMessageHash(encodedTx, isEthSignedMessage);
Lib_SafeExecutionManagerWrapper.safeCREATEEOA(messageHash, uint8(v), r, s);
if (Lib_SafeExecutionManagerWrapper.safeEXTCODESIZE(sender) == 0) {
Lib_SafeExecutionManagerWrapper.safeCREATEEOA(
transaction.hash(),
transaction.recoveryParam,
transaction.r,
transaction.s
);
}

// ProxyEOA has been deployed for this EOA, continue to CALL.
bytes memory callbytes = abi.encodeWithSignature(
"execute(bytes,uint8,uint8,bytes32,bytes32)",
encodedTx,
isEthSignedMessage,
uint8(v),
r,
s
);

Lib_SafeExecutionManagerWrapper.safeCALL(
gasleft(),
target,
callbytes
sender,
abi.encodeWithSignature(
"execute(bytes)",
msg.data
)
);
}


/**********************
* Internal Functions *
**********************/

/**
* Converts a uint256 into a TransactionType enum.
* @param _transactionType Transaction type index.
* @return Transaction type enum value.
*/
function _getTransactionType(
uint8 _transactionType
)
internal
returns (
TransactionType
)
{
if (_transactionType == 0) {
return TransactionType.NATIVE_ETH_TRANSACTION;
} if (_transactionType == 2) {
return TransactionType.ETH_SIGNED_MESSAGE;
} else {
Lib_SafeExecutionManagerWrapper.safeREVERT(
"Transaction type must be 0 or 2"
);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,6 @@
pragma solidity >0.5.0 <0.8.0;
pragma experimental ABIEncoderV2;

/* Library Imports */
import { Lib_OVMCodec } from "../../libraries/codec/Lib_OVMCodec.sol";

/**
* @title iOVM_ECDSAContractAccount
*/
Expand All @@ -15,10 +12,11 @@ interface iOVM_ECDSAContractAccount {
********************/

function execute(
bytes memory _transaction,
Lib_OVMCodec.EOASignatureType _signatureType,
uint8 _v,
bytes32 _r,
bytes32 _s
) external returns (bool _success, bytes memory _returndata);
bytes memory _encodedTransaction
)
external
returns (
bool,
bytes memory
);
}
Loading