Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Import changes from deprecated contracts repo #476

Closed
wants to merge 7 commits into from
Closed
Show file tree
Hide file tree
Changes from 5 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
8 changes: 8 additions & 0 deletions .changeset/ten-baboons-compete.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
"@eth-optimism/contracts": minor
gakonst marked this conversation as resolved.
Show resolved Hide resolved
---

- Remove ETH_SIGNED_MESSAGE and standardize on EIP-155 messages
- Reduce nonce size to uint64
- Ban ovmCALLER opcode when it would return ZERO
- Add value transfer in OVM_ECDSAContractAccount
maurelian marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,22 @@ 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";

/**
* @title OVM_ECDSAContractAccount
* @dev The ECDSA Contract Account can be used as the implementation for a ProxyEOA deployed by the
* ovmCREATEEOA operation. It enables backwards compatibility with Ethereum's Layer 1, by
* ovmCREATEEOA operation. It enables backwards compatibility with Ethereum's Layer 1, by
* providing eth_sign and EIP155 formatted transaction encodings.
*
* Compiler used: solc
* Runtime target: OVM
*/
contract OVM_ECDSAContractAccount is iOVM_ECDSAContractAccount {
using Lib_EIP155Tx for Lib_EIP155Tx.EIP155Tx;


/*************
* Constants *
Expand All @@ -38,20 +39,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 EIP155 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,31 +53,29 @@ contract OVM_ECDSAContractAccount is iOVM_ECDSAContractAccount {
bytes memory
)
{
bool isEthSign = _signatureType == Lib_OVMCodec.EOASignatureType.ETH_SIGNED_MESSAGE;
Lib_EIP155Tx.EIP155Tx memory decodedTx = Lib_EIP155Tx.decode(
_encodedTransaction,
Lib_SafeExecutionManagerWrapper.safeCHAINID()
);

// Recovery parameter being something other than 0 or 1 indicates that this transaction was
// signed using the wrong chain ID. We really should have this logic inside of Lib_EIP155Tx
// but I'd prefer not to add the "safeREQUIRE" logic into that library. So it'll live here
// for now.
Lib_SafeExecutionManagerWrapper.safeREQUIRE(
decodedTx.recoveryParam < 2,
"OVM_ECDSAContractAccount: Transaction was signed with the wrong chain ID."
);

// 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(),
decodedTx.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(),
Expand All @@ -98,16 +89,14 @@ contract OVM_ECDSAContractAccount is iOVM_ECDSAContractAccount {
// "Gas is not sufficient to execute the transaction."
// );

// Transfer fee to relayer.
// Transfer fee to relayer. We assume that whoever called this function is the relayer,
// hence the usage of CALLER. Fee is computed as gasLimit * gasPrice.
address relayer = Lib_SafeExecutionManagerWrapper.safeCALLER();
uint256 fee = Lib_SafeMathWrapper.mul(decodedTx.gasLimit, decodedTx.gasPrice);
(bool success, ) = Lib_SafeExecutionManagerWrapper.safeCALL(
gasleft(),
ETH_ERC20_ADDRESS,
abi.encodeWithSignature("transfer(address,uint256)", relayer, fee)
);
Lib_SafeExecutionManagerWrapper.safeREQUIRE(
success == true,
_attemptETHTransfer(
relayer, fee
),
"Fee was not transferred to relayer."
);

Expand All @@ -130,11 +119,50 @@ contract OVM_ECDSAContractAccount is iOVM_ECDSAContractAccount {
// cases, but since this is a contract we'd end up bumping the nonce twice.
Lib_SafeExecutionManagerWrapper.safeINCREMENTNONCE();

return Lib_SafeExecutionManagerWrapper.safeCALL(
gasleft(),
decodedTx.to,
decodedTx.data
);
if (decodedTx.value > 0) {
Lib_SafeExecutionManagerWrapper.safeREQUIRE(
Copy link
Contributor

Choose a reason for hiding this comment

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

Why is this needed? Was it the case before, was it a bug?

Also, it seems like integration tests are failing, did you run them locally?

decodedTx.data.length == 0,
"Sending ETH with data is currently unsupported."
);

return (
_attemptETHTransfer(decodedTx.to, decodedTx.value),
bytes('')
);
} else {
return Lib_SafeExecutionManagerWrapper.safeCALL(
gasleft(),
decodedTx.to,
decodedTx.data
);
}
}
}

/**
* Attempts to tansfer OVM_ETH.
* @param _to Address to send the L2 ETH to.
* @param _value Amount of L2 ETH to send.
* @return Whether the transfer was successful.
*/
function _attemptETHTransfer(
address _to,
uint256 _value
)
internal
returns(
bool
)
{
(bool success, ) = Lib_SafeExecutionManagerWrapper.safeCALL(
gasleft(),
ETH_ERC20_ADDRESS,
abi.encodeWithSignature(
"transfer(address,uint256)",
_to,
_value
)
);
return success;
}
}
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";
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 @@ -460,7 +460,7 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager, Lib_AddressResolver {
override
public
returns (
uint256 _nonce
uint64 _nonce
)
{
return _getAccountNonce(ovmADDRESS());
Expand All @@ -475,7 +475,7 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager, Lib_AddressResolver {
notStatic
{
address account = ovmADDRESS();
uint256 nonce = _getAccountNonce(account);
uint64 nonce = _getAccountNonce(account);

// Prevent overflow.
if (nonce + 1 > nonce) {
Expand Down Expand Up @@ -1050,15 +1050,15 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager, Lib_AddressResolver {
* This function sanitizes the return types for creation messages to match calls (bool, bytes),
* by being an external function which the EM can call, that mimics the success/fail case of the CREATE.
* This allows for consistent handling of both types of messages in _handleExternalMessage().
* Having this step occur as a separate call frame also allows us to easily revert the
* Having this step occur as a separate call frame also allows us to easily revert the
* contract deployment in the event that the code is unsafe.
*
* @param _gasLimit Amount of gas to be passed into this creation.
*
* param _gasLimit Amount of gas to be passed into this creation.
* @param _creationCode Code to pass into CREATE for deployment.
* @param _address OVM address being deployed to.
*/
function safeCREATE(
uint _gasLimit,
uint, // _gasLimit
Copy link
Collaborator

Choose a reason for hiding this comment

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

Hmmm, I think this was me, but I think Kelvin would want to remove this param internally to be more consistent with the EVM, so cc @smartcontracts

bytes memory _creationCode,
address _address
)
Expand Down Expand Up @@ -1097,7 +1097,7 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager, Lib_AddressResolver {
if (ethAddress == address(0)) {
// If the creation fails, the EVM lets us grab its revert data. This may contain a revert flag
// to be used above in _handleExternalMessage, so we pass the revert data back up unmodified.
assembly {
assembly {
returndatacopy(0,0,returndatasize())
revert(0, returndatasize())
}
Expand Down Expand Up @@ -1167,7 +1167,7 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager, Lib_AddressResolver {
*/
function _setAccountNonce(
address _address,
uint256 _nonce
uint64 _nonce
)
internal
{
Expand All @@ -1185,7 +1185,7 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager, Lib_AddressResolver {
)
internal
returns (
uint256 _nonce
uint64 _nonce
)
{
_checkAccountLoad(_address);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ contract OVM_StateManager is iOVM_StateManager {
*/
function setAccountNonce(
address _address,
uint256 _nonce
uint64 _nonce
)
override
public
Expand All @@ -228,7 +228,7 @@ contract OVM_StateManager is iOVM_StateManager {
public
view
returns (
uint256
uint64
)
{
return accounts[_address].nonce;
Expand Down
Loading