Commit 86a13dcb authored by elenadimitrova's avatar elenadimitrova

Fix max-line-length linting issues in contracts

parent 563de90d
...@@ -11,14 +11,19 @@ import { Lib_PredeployAddresses } from "../../../libraries/constants/Lib_Predepl ...@@ -11,14 +11,19 @@ import { Lib_PredeployAddresses } from "../../../libraries/constants/Lib_Predepl
import { Lib_CrossDomainUtils } from "../../../libraries/bridge/Lib_CrossDomainUtils.sol"; import { Lib_CrossDomainUtils } from "../../../libraries/bridge/Lib_CrossDomainUtils.sol";
/* Interface Imports */ /* Interface Imports */
import { iOVM_L1CrossDomainMessenger } from "../../../iOVM/bridge/messaging/iOVM_L1CrossDomainMessenger.sol"; import { iOVM_L1CrossDomainMessenger } from
import { iOVM_CanonicalTransactionChain } from "../../../iOVM/chain/iOVM_CanonicalTransactionChain.sol"; "../../../iOVM/bridge/messaging/iOVM_L1CrossDomainMessenger.sol";
import { iOVM_CanonicalTransactionChain } from
"../../../iOVM/chain/iOVM_CanonicalTransactionChain.sol";
import { iOVM_StateCommitmentChain } from "../../../iOVM/chain/iOVM_StateCommitmentChain.sol"; import { iOVM_StateCommitmentChain } from "../../../iOVM/chain/iOVM_StateCommitmentChain.sol";
/* External Imports */ /* External Imports */
import { OwnableUpgradeable } from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; import { OwnableUpgradeable } from
import { PausableUpgradeable } from "@openzeppelin/contracts-upgradeable/utils/PausableUpgradeable.sol"; "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
import { ReentrancyGuardUpgradeable } from "@openzeppelin/contracts-upgradeable/utils/ReentrancyGuardUpgradeable.sol"; import { PausableUpgradeable } from
"@openzeppelin/contracts-upgradeable/utils/PausableUpgradeable.sol";
import { ReentrancyGuardUpgradeable } from
"@openzeppelin/contracts-upgradeable/utils/ReentrancyGuardUpgradeable.sol";
/** /**
* @title OVM_L1CrossDomainMessenger * @title OVM_L1CrossDomainMessenger
...@@ -194,7 +199,8 @@ contract OVM_L1CrossDomainMessenger is ...@@ -194,7 +199,8 @@ contract OVM_L1CrossDomainMessenger is
{ {
address ovmCanonicalTransactionChain = resolve("OVM_CanonicalTransactionChain"); address ovmCanonicalTransactionChain = resolve("OVM_CanonicalTransactionChain");
// Use the CTC queue length as nonce // Use the CTC queue length as nonce
uint40 nonce = iOVM_CanonicalTransactionChain(ovmCanonicalTransactionChain).getQueueLength(); uint40 nonce =
iOVM_CanonicalTransactionChain(ovmCanonicalTransactionChain).getQueueLength();
bytes memory xDomainCalldata = Lib_CrossDomainUtils.encodeXDomainCalldata( bytes memory xDomainCalldata = Lib_CrossDomainUtils.encodeXDomainCalldata(
_target, _target,
...@@ -204,7 +210,11 @@ contract OVM_L1CrossDomainMessenger is ...@@ -204,7 +210,11 @@ contract OVM_L1CrossDomainMessenger is
); );
address l2CrossDomainMessenger = resolve("OVM_L2CrossDomainMessenger"); address l2CrossDomainMessenger = resolve("OVM_L2CrossDomainMessenger");
_sendXDomainMessage(ovmCanonicalTransactionChain, l2CrossDomainMessenger, xDomainCalldata, _gasLimit); _sendXDomainMessage(
ovmCanonicalTransactionChain,
l2CrossDomainMessenger,
xDomainCalldata,
_gasLimit);
emit SentMessage(xDomainCalldata); emit SentMessage(xDomainCalldata);
} }
...@@ -298,7 +308,8 @@ contract OVM_L1CrossDomainMessenger is ...@@ -298,7 +308,8 @@ contract OVM_L1CrossDomainMessenger is
{ {
// Verify that the message is in the queue: // Verify that the message is in the queue:
address canonicalTransactionChain = resolve("OVM_CanonicalTransactionChain"); address canonicalTransactionChain = resolve("OVM_CanonicalTransactionChain");
Lib_OVMCodec.QueueElement memory element = iOVM_CanonicalTransactionChain(canonicalTransactionChain).getQueueElement(_queueIndex); Lib_OVMCodec.QueueElement memory element =
iOVM_CanonicalTransactionChain(canonicalTransactionChain).getQueueElement(_queueIndex);
address l2CrossDomainMessenger = resolve("OVM_L2CrossDomainMessenger"); address l2CrossDomainMessenger = resolve("OVM_L2CrossDomainMessenger");
// Compute the transactionHash // Compute the transactionHash
...@@ -323,7 +334,11 @@ contract OVM_L1CrossDomainMessenger is ...@@ -323,7 +334,11 @@ contract OVM_L1CrossDomainMessenger is
_queueIndex _queueIndex
); );
_sendXDomainMessage(canonicalTransactionChain, l2CrossDomainMessenger, xDomainCalldata, _gasLimit); _sendXDomainMessage(
canonicalTransactionChain,
l2CrossDomainMessenger,
xDomainCalldata,
_gasLimit);
} }
......
...@@ -4,8 +4,10 @@ pragma solidity >0.5.0 <0.8.0; ...@@ -4,8 +4,10 @@ pragma solidity >0.5.0 <0.8.0;
pragma experimental ABIEncoderV2; pragma experimental ABIEncoderV2;
/* Interface Imports */ /* Interface Imports */
import { iOVM_L1CrossDomainMessenger } from "../../../iOVM/bridge/messaging/iOVM_L1CrossDomainMessenger.sol"; import { iOVM_L1CrossDomainMessenger } from
import { iOVM_L1MultiMessageRelayer } from "../../../iOVM/bridge/messaging/iOVM_L1MultiMessageRelayer.sol"; "../../../iOVM/bridge/messaging/iOVM_L1CrossDomainMessenger.sol";
import { iOVM_L1MultiMessageRelayer } from
"../../../iOVM/bridge/messaging/iOVM_L1MultiMessageRelayer.sol";
/* Library Imports */ /* Library Imports */
import { Lib_AddressResolver } from "../../../libraries/resolver/Lib_AddressResolver.sol"; import { Lib_AddressResolver } from "../../../libraries/resolver/Lib_AddressResolver.sol";
...@@ -42,7 +44,7 @@ contract OVM_L1MultiMessageRelayer is iOVM_L1MultiMessageRelayer, Lib_AddressRes ...@@ -42,7 +44,7 @@ contract OVM_L1MultiMessageRelayer is iOVM_L1MultiMessageRelayer, Lib_AddressRes
modifier onlyBatchRelayer() { modifier onlyBatchRelayer() {
require( require(
msg.sender == resolve("OVM_L2BatchMessageRelayer"), msg.sender == resolve("OVM_L2BatchMessageRelayer"),
"OVM_L1MultiMessageRelayer: Function can only be called by the OVM_L2BatchMessageRelayer" "OVM_L1MultiMessageRelayer: Function can only be called by the OVM_L2BatchMessageRelayer" // solhint-disable-line max-line-length
); );
_; _;
} }
...@@ -58,7 +60,7 @@ contract OVM_L1MultiMessageRelayer is iOVM_L1MultiMessageRelayer, Lib_AddressRes ...@@ -58,7 +60,7 @@ contract OVM_L1MultiMessageRelayer is iOVM_L1MultiMessageRelayer, Lib_AddressRes
*/ */
function batchRelayMessages( function batchRelayMessages(
L2ToL1Message[] calldata _messages L2ToL1Message[] calldata _messages
) )
override override
external external
onlyBatchRelayer onlyBatchRelayer
......
...@@ -7,7 +7,8 @@ import { Lib_AddressResolver } from "../../../libraries/resolver/Lib_AddressReso ...@@ -7,7 +7,8 @@ import { Lib_AddressResolver } from "../../../libraries/resolver/Lib_AddressReso
import { Lib_CrossDomainUtils } from "../../../libraries/bridge/Lib_CrossDomainUtils.sol"; import { Lib_CrossDomainUtils } from "../../../libraries/bridge/Lib_CrossDomainUtils.sol";
/* Interface Imports */ /* Interface Imports */
import { iOVM_L2CrossDomainMessenger } from "../../../iOVM/bridge/messaging/iOVM_L2CrossDomainMessenger.sol"; import { iOVM_L2CrossDomainMessenger } from
"../../../iOVM/bridge/messaging/iOVM_L2CrossDomainMessenger.sol";
import { iOVM_L1MessageSender } from "../../../iOVM/predeploys/iOVM_L1MessageSender.sol"; import { iOVM_L1MessageSender } from "../../../iOVM/predeploys/iOVM_L1MessageSender.sol";
import { iOVM_L2ToL1MessagePasser } from "../../../iOVM/predeploys/iOVM_L2ToL1MessagePasser.sol"; import { iOVM_L2ToL1MessagePasser } from "../../../iOVM/predeploys/iOVM_L2ToL1MessagePasser.sol";
...@@ -57,8 +58,10 @@ contract OVM_L2CrossDomainMessenger is ...@@ -57,8 +58,10 @@ contract OVM_L2CrossDomainMessenger is
/** /**
* @param _libAddressManager Address of the Address Manager. * @param _libAddressManager Address of the Address Manager.
*/ */
constructor(address _libAddressManager) Lib_AddressResolver(_libAddressManager) ReentrancyGuard() {} constructor(address _libAddressManager)
Lib_AddressResolver(_libAddressManager)
ReentrancyGuard()
{}
/******************** /********************
* Public Functions * * Public Functions *
......
...@@ -18,8 +18,9 @@ import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/SafeERC20.sol"; ...@@ -18,8 +18,9 @@ import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/SafeERC20.sol";
/** /**
* @title OVM_L1StandardBridge * @title OVM_L1StandardBridge
* @dev The L1 ETH and ERC20 Bridge is a contract which stores deposited L1 funds and standard tokens that are in use on L2. * @dev The L1 ETH and ERC20 Bridge is a contract which stores deposited L1 funds and standard
* It synchronizes a corresponding L2 Bridge, informing it of deposits, and listening to it for newly finalized withdrawals. * tokens that are in use on L2. It synchronizes a corresponding L2 Bridge, informing it of deposits
* and listening to it for newly finalized withdrawals.
* *
* Compiler used: solc * Compiler used: solc
* Runtime target: EVM * Runtime target: EVM
...@@ -69,7 +70,8 @@ contract OVM_L1StandardBridge is iOVM_L1StandardBridge, OVM_CrossDomainEnabled { ...@@ -69,7 +70,8 @@ contract OVM_L1StandardBridge is iOVM_L1StandardBridge, OVM_CrossDomainEnabled {
* Depositing * * Depositing *
**************/ **************/
/// @dev Modifier requiring sender to be EOA. This check could be bypassed by a malicious contract via initcode, but it takes care of the user error we want to avoid. /// @dev Modifier requiring sender to be EOA. This check could be bypassed by a malicious
// contract via initcode, but it takes care of the user error we want to avoid.
modifier onlyEOA() { modifier onlyEOA() {
// Used to stop deposits from contracts (avoid accidentally lost tokens) // Used to stop deposits from contracts (avoid accidentally lost tokens)
require(!Address.isContract(msg.sender), "Account not EOA"); require(!Address.isContract(msg.sender), "Account not EOA");
...@@ -136,7 +138,8 @@ contract OVM_L1StandardBridge is iOVM_L1StandardBridge, OVM_CrossDomainEnabled { ...@@ -136,7 +138,8 @@ contract OVM_L1StandardBridge is iOVM_L1StandardBridge, OVM_CrossDomainEnabled {
} }
/** /**
* @dev Performs the logic for deposits by storing the ETH and informing the L2 ETH Gateway of the deposit. * @dev Performs the logic for deposits by storing the ETH and informing the L2 ETH Gateway of
* the deposit.
* @param _from Account to pull the deposit from on L1. * @param _from Account to pull the deposit from on L1.
* @param _to Account to give the deposit to on L2. * @param _to Account to give the deposit to on L2.
* @param _l2Gas Gas limit required to complete the deposit on L2. * @param _l2Gas Gas limit required to complete the deposit on L2.
...@@ -235,8 +238,9 @@ contract OVM_L1StandardBridge is iOVM_L1StandardBridge, OVM_CrossDomainEnabled { ...@@ -235,8 +238,9 @@ contract OVM_L1StandardBridge is iOVM_L1StandardBridge, OVM_CrossDomainEnabled {
) )
internal internal
{ {
// When a deposit is initiated on L1, the L1 Bridge transfers the funds to itself for future withdrawals. // When a deposit is initiated on L1, the L1 Bridge transfers the funds to itself for future
// safeTransferFrom also checks if the contract has code, so this will fail if _from is an EOA or address(0). // withdrawals. safeTransferFrom also checks if the contract has code, so this will fail if
// _from is an EOA or address(0).
IERC20(_l1Token).safeTransferFrom( IERC20(_l1Token).safeTransferFrom(
_from, _from,
address(this), address(this),
...@@ -306,7 +310,7 @@ contract OVM_L1StandardBridge is iOVM_L1StandardBridge, OVM_CrossDomainEnabled { ...@@ -306,7 +310,7 @@ contract OVM_L1StandardBridge is iOVM_L1StandardBridge, OVM_CrossDomainEnabled {
{ {
deposits[_l1Token][_l2Token] = deposits[_l1Token][_l2Token].sub(_amount); deposits[_l1Token][_l2Token] = deposits[_l1Token][_l2Token].sub(_amount);
// When a withdrawal is finalized on L1, the L1 Bridge transfers the funds to the withdrawer. // When a withdrawal is finalized on L1, the L1 Bridge transfers the funds to the withdrawer
IERC20(_l1Token).safeTransfer(_to, _amount); IERC20(_l1Token).safeTransfer(_to, _amount);
emit ERC20WithdrawalFinalized(_l1Token, _l2Token, _from, _to, _amount, _data); emit ERC20WithdrawalFinalized(_l1Token, _l2Token, _from, _to, _amount, _data);
...@@ -319,7 +323,8 @@ contract OVM_L1StandardBridge is iOVM_L1StandardBridge, OVM_CrossDomainEnabled { ...@@ -319,7 +323,8 @@ contract OVM_L1StandardBridge is iOVM_L1StandardBridge, OVM_CrossDomainEnabled {
/** /**
* @dev Adds ETH balance to the account. This is meant to allow for ETH * @dev Adds ETH balance to the account. This is meant to allow for ETH
* to be migrated from an old gateway to a new gateway. * to be migrated from an old gateway to a new gateway.
* NOTE: This is left for one upgrade only so we are able to receive the migrated ETH from the old contract * NOTE: This is left for one upgrade only so we are able to receive the migrated ETH from the
* old contract
*/ */
function donateETH() external payable {} function donateETH() external payable {}
} }
...@@ -17,10 +17,12 @@ import { IL2StandardERC20 } from "../../../libraries/standards/IL2StandardERC20. ...@@ -17,10 +17,12 @@ import { IL2StandardERC20 } from "../../../libraries/standards/IL2StandardERC20.
/** /**
* @title OVM_L2StandardBridge * @title OVM_L2StandardBridge
* @dev The L2 Standard bridge is a contract which works together with the L1 Standard bridge to enable * @dev The L2 Standard bridge is a contract which works together with the L1 Standard bridge to
* ETH and ERC20 transitions between L1 and L2. * enable ETH and ERC20 transitions between L1 and L2.
* This contract acts as a minter for new tokens when it hears about deposits into the L1 Standard bridge. * This contract acts as a minter for new tokens when it hears about deposits into the L1 Standard
* This contract also acts as a burner of the tokens intended for withdrawal, informing the L1 bridge to release L1 funds. * bridge.
* This contract also acts as a burner of the tokens intended for withdrawal, informing the L1
* bridge to release L1 funds.
* *
* Compiler used: optimistic-solc * Compiler used: optimistic-solc
* Runtime target: OVM * Runtime target: OVM
...@@ -102,7 +104,8 @@ contract OVM_L2StandardBridge is iOVM_L2ERC20Bridge, OVM_CrossDomainEnabled { ...@@ -102,7 +104,8 @@ contract OVM_L2StandardBridge is iOVM_L2ERC20Bridge, OVM_CrossDomainEnabled {
} }
/** /**
* @dev Performs the logic for deposits by storing the token and informing the L2 token Gateway of the deposit. * @dev Performs the logic for deposits by storing the token and informing the L2 token Gateway
* of the deposit.
* @param _l2Token Address of L2 token where withdrawal was initiated. * @param _l2Token Address of L2 token where withdrawal was initiated.
* @param _from Account to pull the deposit from on L2. * @param _from Account to pull the deposit from on L2.
* @param _to Account to give the withdrawal to on L1. * @param _to Account to give the withdrawal to on L1.
...@@ -122,7 +125,8 @@ contract OVM_L2StandardBridge is iOVM_L2ERC20Bridge, OVM_CrossDomainEnabled { ...@@ -122,7 +125,8 @@ contract OVM_L2StandardBridge is iOVM_L2ERC20Bridge, OVM_CrossDomainEnabled {
) )
internal internal
{ {
// When a withdrawal is initiated, we burn the withdrawer's funds to prevent subsequent L2 usage // When a withdrawal is initiated, we burn the withdrawer's funds to prevent subsequent L2
// usage
IL2StandardERC20(_l2Token).burn(msg.sender, _amount); IL2StandardERC20(_l2Token).burn(msg.sender, _amount);
// Construct calldata for l1TokenBridge.finalizeERC20Withdrawal(_to, _amount) // Construct calldata for l1TokenBridge.finalizeERC20Withdrawal(_to, _amount)
...@@ -185,7 +189,8 @@ contract OVM_L2StandardBridge is iOVM_L2ERC20Bridge, OVM_CrossDomainEnabled { ...@@ -185,7 +189,8 @@ contract OVM_L2StandardBridge is iOVM_L2ERC20Bridge, OVM_CrossDomainEnabled {
ERC165Checker.supportsInterface(_l2Token, 0x1d1d8b63) && ERC165Checker.supportsInterface(_l2Token, 0x1d1d8b63) &&
_l1Token == IL2StandardERC20(_l2Token).l1Token() _l1Token == IL2StandardERC20(_l2Token).l1Token()
) { ) {
// When a deposit is finalized, we credit the account on L2 with the same amount of tokens. // When a deposit is finalized, we credit the account on L2 with the same amount of
// tokens.
IL2StandardERC20(_l2Token).mint(_to, _amount); IL2StandardERC20(_l2Token).mint(_to, _amount);
emit DepositFinalized(_l1Token, _l2Token, _from, _to, _amount, _data); emit DepositFinalized(_l1Token, _l2Token, _from, _to, _amount, _data);
} else { } else {
......
...@@ -9,7 +9,8 @@ import { Lib_AddressResolver } from "../../libraries/resolver/Lib_AddressResolve ...@@ -9,7 +9,8 @@ import { Lib_AddressResolver } from "../../libraries/resolver/Lib_AddressResolve
import { Lib_MerkleTree } from "../../libraries/utils/Lib_MerkleTree.sol"; import { Lib_MerkleTree } from "../../libraries/utils/Lib_MerkleTree.sol";
/* Interface Imports */ /* Interface Imports */
import { iOVM_CanonicalTransactionChain } from "../../iOVM/chain/iOVM_CanonicalTransactionChain.sol"; import { iOVM_CanonicalTransactionChain } from
"../../iOVM/chain/iOVM_CanonicalTransactionChain.sol";
import { iOVM_ChainStorageContainer } from "../../iOVM/chain/iOVM_ChainStorageContainer.sol"; import { iOVM_ChainStorageContainer } from "../../iOVM/chain/iOVM_ChainStorageContainer.sol";
/* Contract Imports */ /* Contract Imports */
...@@ -23,8 +24,8 @@ import { Math } from "@openzeppelin/contracts/math/Math.sol"; ...@@ -23,8 +24,8 @@ import { Math } from "@openzeppelin/contracts/math/Math.sol";
* @dev The Canonical Transaction Chain (CTC) contract is an append-only log of transactions * @dev The Canonical Transaction Chain (CTC) contract is an append-only log of transactions
* which must be applied to the rollup state. It defines the ordering of rollup transactions by * which must be applied to the rollup state. It defines the ordering of rollup transactions by
* writing them to the 'CTC:batches' instance of the Chain Storage Container. * writing them to the 'CTC:batches' instance of the Chain Storage Container.
* The CTC also allows any account to 'enqueue' an L2 transaction, which will require that the Sequencer * The CTC also allows any account to 'enqueue' an L2 transaction, which will require that the
* will eventually append it to the rollup state. * Sequencer will eventually append it to the rollup state.
* If the Sequencer does not include an enqueued transaction within the 'force inclusion period', * If the Sequencer does not include an enqueued transaction within the 'force inclusion period',
* then any account may force it to be included by calling appendQueueBatch(). * then any account may force it to be included by calling appendQueueBatch().
* *
...@@ -359,7 +360,7 @@ contract OVM_CanonicalTransactionChain is iOVM_CanonicalTransactionChain, Lib_Ad ...@@ -359,7 +360,7 @@ contract OVM_CanonicalTransactionChain is iOVM_CanonicalTransactionChain, Lib_Ad
// Lib_OVMCodec.QueueElement memory el = getQueueElement(nextQueueIndex); // Lib_OVMCodec.QueueElement memory el = getQueueElement(nextQueueIndex);
// require( // require(
// el.timestamp + forceInclusionPeriodSeconds < block.timestamp, // el.timestamp + forceInclusionPeriodSeconds < block.timestamp,
// "Queue transactions cannot be submitted during the sequencer inclusion period." // "Queue transactions cannot be submitted during the sequencer inclusion period."
// ); // );
// } // }
// leaves[i] = _getQueueLeafHash(nextQueueIndex); // leaves[i] = _getQueueLeafHash(nextQueueIndex);
...@@ -424,7 +425,8 @@ contract OVM_CanonicalTransactionChain is iOVM_CanonicalTransactionChain, Lib_Ad ...@@ -424,7 +425,8 @@ contract OVM_CanonicalTransactionChain is iOVM_CanonicalTransactionChain, Lib_Ad
"Must append at least one element." "Must append at least one element."
); );
uint40 nextTransactionPtr = uint40(BATCH_CONTEXT_START_POS + BATCH_CONTEXT_SIZE * numContexts); uint40 nextTransactionPtr = uint40(BATCH_CONTEXT_START_POS +
BATCH_CONTEXT_SIZE * numContexts);
require( require(
msg.data.length >= nextTransactionPtr, msg.data.length >= nextTransactionPtr,
...@@ -533,14 +535,16 @@ contract OVM_CanonicalTransactionChain is iOVM_CanonicalTransactionChain, Lib_Ad ...@@ -533,14 +535,16 @@ contract OVM_CanonicalTransactionChain is iOVM_CanonicalTransactionChain, Lib_Ad
uint40 blockTimestamp; uint40 blockTimestamp;
uint40 blockNumber; uint40 blockNumber;
if (curContext.numSubsequentQueueTransactions == 0) { if (curContext.numSubsequentQueueTransactions == 0) {
// The last element is a sequencer tx, therefore pull timestamp and block number from the last context. // The last element is a sequencer tx, therefore pull timestamp and block number from
// the last context.
blockTimestamp = uint40(curContext.timestamp); blockTimestamp = uint40(curContext.timestamp);
blockNumber = uint40(curContext.blockNumber); blockNumber = uint40(curContext.blockNumber);
} else { } else {
// The last element is a queue tx, therefore pull timestamp and block number from the queue element. // The last element is a queue tx, therefore pull timestamp and block number from the
// curContext.numSubsequentQueueTransactions > 0 which means that we've processed at least one queue element. // queue element.
// We increment nextQueueIndex after processing each queue element, // curContext.numSubsequentQueueTransactions > 0 which means that we've processed at
// so the index of the last element we processed is nextQueueIndex - 1. // least one queue element. We increment nextQueueIndex after processing each queue
// element, so the index of the last element we processed is nextQueueIndex - 1.
Lib_OVMCodec.QueueElement memory lastElement = _getQueueElement( Lib_OVMCodec.QueueElement memory lastElement = _getQueueElement(
nextQueueIndex - 1, nextQueueIndex - 1,
queueRef queueRef
...@@ -667,6 +671,8 @@ contract OVM_CanonicalTransactionChain is iOVM_CanonicalTransactionChain, Lib_Ad ...@@ -667,6 +671,8 @@ contract OVM_CanonicalTransactionChain is iOVM_CanonicalTransactionChain, Lib_Ad
uint40 nextQueueIndex; uint40 nextQueueIndex;
uint40 lastTimestamp; uint40 lastTimestamp;
uint40 lastBlockNumber; uint40 lastBlockNumber;
// solhint-disable max-line-length
assembly { assembly {
extraData := shr(40, extraData) extraData := shr(40, extraData)
totalElements := and(extraData, 0x000000000000000000000000000000000000000000000000000000FFFFFFFFFF) totalElements := and(extraData, 0x000000000000000000000000000000000000000000000000000000FFFFFFFFFF)
...@@ -674,6 +680,7 @@ contract OVM_CanonicalTransactionChain is iOVM_CanonicalTransactionChain, Lib_Ad ...@@ -674,6 +680,7 @@ contract OVM_CanonicalTransactionChain is iOVM_CanonicalTransactionChain, Lib_Ad
lastTimestamp := shr(80, and(extraData, 0x0000000000000000000000000000000000FFFFFFFFFF00000000000000000000)) lastTimestamp := shr(80, and(extraData, 0x0000000000000000000000000000000000FFFFFFFFFF00000000000000000000))
lastBlockNumber := shr(120, and(extraData, 0x000000000000000000000000FFFFFFFFFF000000000000000000000000000000)) lastBlockNumber := shr(120, and(extraData, 0x000000000000000000000000FFFFFFFFFF000000000000000000000000000000))
} }
// solhint-enable max-line-length
return ( return (
totalElements, totalElements,
...@@ -764,10 +771,12 @@ contract OVM_CanonicalTransactionChain is iOVM_CanonicalTransactionChain, Lib_Ad ...@@ -764,10 +771,12 @@ contract OVM_CanonicalTransactionChain is iOVM_CanonicalTransactionChain, Lib_Ad
uint40 elementTimestamp; uint40 elementTimestamp;
uint40 elementBlockNumber; uint40 elementBlockNumber;
// solhint-disable max-line-length
assembly { assembly {
elementTimestamp := and(timestampAndBlockNumber, 0x000000000000000000000000000000000000000000000000000000FFFFFFFFFF) elementTimestamp := and(timestampAndBlockNumber, 0x000000000000000000000000000000000000000000000000000000FFFFFFFFFF)
elementBlockNumber := shr(40, and(timestampAndBlockNumber, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000000000)) elementBlockNumber := shr(40, and(timestampAndBlockNumber, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000000000))
} }
// solhint-enable max-line-length
return Lib_OVMCodec.QueueElement({ return Lib_OVMCodec.QueueElement({
transactionHash: transactionHash, transactionHash: transactionHash,
...@@ -835,7 +844,7 @@ contract OVM_CanonicalTransactionChain is iOVM_CanonicalTransactionChain, Lib_Ad ...@@ -835,7 +844,7 @@ contract OVM_CanonicalTransactionChain is iOVM_CanonicalTransactionChain, Lib_Ad
mstore(add(chainElementStart, 1), ctxTimestamp) mstore(add(chainElementStart, 1), ctxTimestamp)
mstore(add(chainElementStart, 33), ctxBlockNumber) mstore(add(chainElementStart, 33), ctxBlockNumber)
calldatacopy(add(chainElementStart, BYTES_TILL_TX_DATA), add(_nextTransactionPtr, 3), _txDataLength) calldatacopy(add(chainElementStart, BYTES_TILL_TX_DATA), add(_nextTransactionPtr, 3), _txDataLength) // solhint-disable-line max-line-length
leafHash := keccak256(chainElementStart, add(BYTES_TILL_TX_DATA, _txDataLength)) leafHash := keccak256(chainElementStart, add(BYTES_TILL_TX_DATA, _txDataLength))
} }
...@@ -877,7 +886,7 @@ contract OVM_CanonicalTransactionChain is iOVM_CanonicalTransactionChain, Lib_Ad ...@@ -877,7 +886,7 @@ contract OVM_CanonicalTransactionChain is iOVM_CanonicalTransactionChain, Lib_Ad
mstore(add(chainElementStart, 1), ctxTimestamp) mstore(add(chainElementStart, 1), ctxTimestamp)
mstore(add(chainElementStart, 33), ctxBlockNumber) mstore(add(chainElementStart, 33), ctxBlockNumber)
pop(staticcall(gas(), 0x04, add(txData, 0x20), txDataLength, add(chainElementStart, BYTES_TILL_TX_DATA), txDataLength)) pop(staticcall(gas(), 0x04, add(txData, 0x20), txDataLength, add(chainElementStart, BYTES_TILL_TX_DATA), txDataLength)) // solhint-disable-line max-line-length
leafHash := keccak256(chainElementStart, add(BYTES_TILL_TX_DATA, txDataLength)) leafHash := keccak256(chainElementStart, add(BYTES_TILL_TX_DATA, txDataLength))
} }
...@@ -989,10 +998,11 @@ contract OVM_CanonicalTransactionChain is iOVM_CanonicalTransactionChain, Lib_Ad ...@@ -989,10 +998,11 @@ contract OVM_CanonicalTransactionChain is iOVM_CanonicalTransactionChain, Lib_Ad
_queueRef _queueRef
); );
// If the force inclusion period has passed for an enqueued transaction, it MUST be the next chain element. // If the force inclusion period has passed for an enqueued transaction, it MUST be the
// next chain element.
require( require(
block.timestamp < nextQueueElement.timestamp + forceInclusionPeriodSeconds, block.timestamp < nextQueueElement.timestamp + forceInclusionPeriodSeconds,
"Previously enqueued batches have expired and must be appended before a new sequencer batch." "Previously enqueued batches have expired and must be appended before a new sequencer batch." // solhint-disable-line max-line-length
); );
// Just like sequencer transaction times must be increasing relative to each other, // Just like sequencer transaction times must be increasing relative to each other,
...@@ -1009,10 +1019,12 @@ contract OVM_CanonicalTransactionChain is iOVM_CanonicalTransactionChain, Lib_Ad ...@@ -1009,10 +1019,12 @@ contract OVM_CanonicalTransactionChain is iOVM_CanonicalTransactionChain, Lib_Ad
} }
/** /**
* Checks that a given batch context is valid based on its previous context, and the next queue elemtent. * Checks that a given batch context is valid based on its previous context, and the next queue
* elemtent.
* @param _prevContext The previously validated batch context. * @param _prevContext The previously validated batch context.
* @param _nextContext The batch context to validate with this call. * @param _nextContext The batch context to validate with this call.
* @param _nextQueueIndex Index of the next queue element to process for the _nextContext's subsequentQueueElements. * @param _nextQueueIndex Index of the next queue element to process for the _nextContext's
* subsequentQueueElements.
* @param _queueRef The storage container for the queue. * @param _queueRef The storage container for the queue.
*/ */
function _validateNextBatchContext( function _validateNextBatchContext(
...@@ -1061,17 +1073,22 @@ contract OVM_CanonicalTransactionChain is iOVM_CanonicalTransactionChain, Lib_Ad ...@@ -1061,17 +1073,22 @@ contract OVM_CanonicalTransactionChain is iOVM_CanonicalTransactionChain, Lib_Ad
internal internal
view view
{ {
// If the queue is not now empty, check the mononoticity of whatever the next batch that will come in is. // If the queue is not now empty, check the mononoticity of whatever the next batch that
if (_queueLength - _nextQueueIndex > 0 && _finalContext.numSubsequentQueueTransactions == 0) { // will come in is.
if (_queueLength - _nextQueueIndex > 0 && _finalContext.numSubsequentQueueTransactions == 0)
{
_validateContextBeforeEnqueue( _validateContextBeforeEnqueue(
_finalContext, _finalContext,
_nextQueueIndex, _nextQueueIndex,
_queueRef _queueRef
); );
} }
// Batches cannot be added from the future, or subsequent enqueue() contexts would violate monotonicity. // Batches cannot be added from the future, or subsequent enqueue() contexts would violate
require(_finalContext.timestamp <= block.timestamp, "Context timestamp is from the future."); // monotonicity.
require(_finalContext.blockNumber <= block.number, "Context block number is from the future."); require(_finalContext.timestamp <= block.timestamp,
"Context timestamp is from the future.");
require(_finalContext.blockNumber <= block.number,
"Context block number is from the future.");
} }
/** /**
...@@ -1119,7 +1136,8 @@ contract OVM_CanonicalTransactionChain is iOVM_CanonicalTransactionChain, Lib_Ad ...@@ -1119,7 +1136,8 @@ contract OVM_CanonicalTransactionChain is iOVM_CanonicalTransactionChain, Lib_Ad
bool bool
) )
{ {
OVM_ExecutionManager ovmExecutionManager = OVM_ExecutionManager(resolve("OVM_ExecutionManager")); OVM_ExecutionManager ovmExecutionManager =
OVM_ExecutionManager(resolve("OVM_ExecutionManager"));
uint256 gasLimit = ovmExecutionManager.getMaxTransactionGasLimit(); uint256 gasLimit = ovmExecutionManager.getMaxTransactionGasLimit();
bytes32 leafHash = _getSequencerLeafHash(_txChainElement); bytes32 leafHash = _getSequencerLeafHash(_txChainElement);
...@@ -1151,7 +1169,8 @@ contract OVM_CanonicalTransactionChain is iOVM_CanonicalTransactionChain, Lib_Ad ...@@ -1151,7 +1169,8 @@ contract OVM_CanonicalTransactionChain is iOVM_CanonicalTransactionChain, Lib_Ad
* @param _transaction The transaction we are verifying inclusion of. * @param _transaction The transaction we are verifying inclusion of.
* @param _queueIndex The queueIndex of the queued transaction. * @param _queueIndex The queueIndex of the queued transaction.
* @param _batchHeader Header of the batch the transaction was included in. * @param _batchHeader Header of the batch the transaction was included in.
* @param _inclusionProof An inclusion proof into the CTC at a particular index (should point to queue tx). * @param _inclusionProof An inclusion proof into the CTC at a particular index (should point to
* queue tx).
* @return True if the transaction was included in the specified location, else false. * @return True if the transaction was included in the specified location, else false.
*/ */
function _verifyQueueTransaction( function _verifyQueueTransaction(
...@@ -1215,7 +1234,8 @@ contract OVM_CanonicalTransactionChain is iOVM_CanonicalTransactionChain, Lib_Ad ...@@ -1215,7 +1234,8 @@ contract OVM_CanonicalTransactionChain is iOVM_CanonicalTransactionChain, Lib_Ad
) )
{ {
require( require(
Lib_OVMCodec.hashBatchHeader(_batchHeader) == batches().get(uint32(_batchHeader.batchIndex)), Lib_OVMCodec.hashBatchHeader(_batchHeader) ==
batches().get(uint32(_batchHeader.batchIndex)),
"Invalid batch header." "Invalid batch header."
); );
......
...@@ -10,10 +10,10 @@ import { iOVM_ChainStorageContainer } from "../../iOVM/chain/iOVM_ChainStorageCo ...@@ -10,10 +10,10 @@ import { iOVM_ChainStorageContainer } from "../../iOVM/chain/iOVM_ChainStorageCo
/** /**
* @title OVM_ChainStorageContainer * @title OVM_ChainStorageContainer
* @dev The Chain Storage Container provides its owner contract with read, write and delete functionality. * @dev The Chain Storage Container provides its owner contract with read, write and delete
* This provides gas efficiency gains by enabling it to overwrite storage slots which can no longer be used * functionality. This provides gas efficiency gains by enabling it to overwrite storage slots which
* in a fraud proof due to the fraud window having passed, and the associated chain state or * can no longer be used in a fraud proof due to the fraud window having passed, and the associated
* transactions being finalized. * chain state or transactions being finalized.
* Three distinct Chain Storage Containers will be deployed on Layer 1: * Three distinct Chain Storage Containers will be deployed on Layer 1:
* 1. Stores transaction batches for the Canonical Transaction Chain * 1. Stores transaction batches for the Canonical Transaction Chain
* 2. Stores queued transactions for the Canonical Transaction Chain * 2. Stores queued transactions for the Canonical Transaction Chain
......
...@@ -10,7 +10,8 @@ import { Lib_MerkleTree } from "../../libraries/utils/Lib_MerkleTree.sol"; ...@@ -10,7 +10,8 @@ import { Lib_MerkleTree } from "../../libraries/utils/Lib_MerkleTree.sol";
/* Interface Imports */ /* Interface Imports */
import { iOVM_FraudVerifier } from "../../iOVM/verification/iOVM_FraudVerifier.sol"; import { iOVM_FraudVerifier } from "../../iOVM/verification/iOVM_FraudVerifier.sol";
import { iOVM_StateCommitmentChain } from "../../iOVM/chain/iOVM_StateCommitmentChain.sol"; import { iOVM_StateCommitmentChain } from "../../iOVM/chain/iOVM_StateCommitmentChain.sol";
import { iOVM_CanonicalTransactionChain } from "../../iOVM/chain/iOVM_CanonicalTransactionChain.sol"; import { iOVM_CanonicalTransactionChain } from
"../../iOVM/chain/iOVM_CanonicalTransactionChain.sol";
import { iOVM_BondManager } from "../../iOVM/verification/iOVM_BondManager.sol"; import { iOVM_BondManager } from "../../iOVM/verification/iOVM_BondManager.sol";
import { iOVM_ChainStorageContainer } from "../../iOVM/chain/iOVM_ChainStorageContainer.sol"; import { iOVM_ChainStorageContainer } from "../../iOVM/chain/iOVM_ChainStorageContainer.sol";
...@@ -149,7 +150,9 @@ contract OVM_StateCommitmentChain is iOVM_StateCommitmentChain, Lib_AddressResol ...@@ -149,7 +150,9 @@ contract OVM_StateCommitmentChain is iOVM_StateCommitmentChain, Lib_AddressResol
); );
require( require(
getTotalElements() + _batch.length <= iOVM_CanonicalTransactionChain(resolve("OVM_CanonicalTransactionChain")).getTotalElements(), getTotalElements() + _batch.length <=
iOVM_CanonicalTransactionChain(resolve("OVM_CanonicalTransactionChain"))
.getTotalElements(),
"Number of state roots cannot exceed the number of canonical transactions." "Number of state roots cannot exceed the number of canonical transactions."
); );
...@@ -267,6 +270,7 @@ contract OVM_StateCommitmentChain is iOVM_StateCommitmentChain, Lib_AddressResol ...@@ -267,6 +270,7 @@ contract OVM_StateCommitmentChain is iOVM_StateCommitmentChain, Lib_AddressResol
{ {
bytes27 extraData = batches().getGlobalMetadata(); bytes27 extraData = batches().getGlobalMetadata();
// solhint-disable max-line-length
uint40 totalElements; uint40 totalElements;
uint40 lastSequencerTimestamp; uint40 lastSequencerTimestamp;
assembly { assembly {
...@@ -274,6 +278,7 @@ contract OVM_StateCommitmentChain is iOVM_StateCommitmentChain, Lib_AddressResol ...@@ -274,6 +278,7 @@ contract OVM_StateCommitmentChain is iOVM_StateCommitmentChain, Lib_AddressResol
totalElements := and(extraData, 0x000000000000000000000000000000000000000000000000000000FFFFFFFFFF) totalElements := and(extraData, 0x000000000000000000000000000000000000000000000000000000FFFFFFFFFF)
lastSequencerTimestamp := shr(40, and(extraData, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000000000)) lastSequencerTimestamp := shr(40, and(extraData, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000000000))
} }
// solhint-enable max-line-length
return ( return (
totalElements, totalElements,
......
...@@ -83,7 +83,8 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager, Lib_AddressResolver { ...@@ -83,7 +83,8 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager, Lib_AddressResolver {
* Default Context Values * * Default Context Values *
**************************/ **************************/
uint256 constant DEFAULT_UINT256 = 0xdefa017defa017defa017defa017defa017defa017defa017defa017defa017d; uint256 constant DEFAULT_UINT256 =
0xdefa017defa017defa017defa017defa017defa017defa017defa017defa017d;
address constant DEFAULT_ADDRESS = 0xdEfa017defA017DeFA017DEfa017DeFA017DeFa0; address constant DEFAULT_ADDRESS = 0xdEfa017defA017DeFA017DEfa017DeFA017DeFa0;
...@@ -92,7 +93,8 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager, Lib_AddressResolver { ...@@ -92,7 +93,8 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager, Lib_AddressResolver {
*************************************/ *************************************/
/** /**
* @dev The Execution Manager and State Manager each have this 30 byte prefix, and are uncallable. * @dev The Execution Manager and State Manager each have this 30 byte prefix,
* and are uncallable.
*/ */
address constant CONTAINER_CONTRACT_PREFIX = 0xDeadDeAddeAddEAddeadDEaDDEAdDeaDDeAD0000; address constant CONTAINER_CONTRACT_PREFIX = 0xDeadDeAddeAddEAddeadDEaDDEAdDeaDDeAD0000;
...@@ -205,7 +207,8 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager, Lib_AddressResolver { ...@@ -205,7 +207,8 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager, Lib_AddressResolver {
// OVM_StateManager (expected to be an OVM_StateTransitioner). We can revert here because // OVM_StateManager (expected to be an OVM_StateTransitioner). We can revert here because
// this would make the `run` itself invalid. // this would make the `run` itself invalid.
require( require(
// This method may return false during fraud proofs, but always returns true in L2 nodes' State Manager precompile. // This method may return false during fraud proofs, but always returns true in
// L2 nodes' State Manager precompile.
ovmStateManager.isAuthenticated(msg.sender), ovmStateManager.isAuthenticated(msg.sender),
"Only authenticated addresses in ovmStateManager can call this function" "Only authenticated addresses in ovmStateManager can call this function"
); );
...@@ -677,7 +680,8 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager, Lib_AddressResolver { ...@@ -677,7 +680,8 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager, Lib_AddressResolver {
bytes memory _returndata bytes memory _returndata
) )
{ {
// STATICCALL updates the CALLER, updates the ADDRESS, and runs in a static, valueless context. // STATICCALL updates the CALLER, updates the ADDRESS, and runs in a static,
// valueless context.
MessageContext memory nextMessageContext = messageContext; MessageContext memory nextMessageContext = messageContext;
nextMessageContext.ovmCALLER = nextMessageContext.ovmADDRESS; nextMessageContext.ovmCALLER = nextMessageContext.ovmADDRESS;
nextMessageContext.ovmADDRESS = _address; nextMessageContext.ovmADDRESS = _address;
...@@ -727,7 +731,8 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager, Lib_AddressResolver { ...@@ -727,7 +731,8 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager, Lib_AddressResolver {
} }
/** /**
* @notice Legacy ovmCALL function which did not support ETH value; this maintains backwards compatibility. * @notice Legacy ovmCALL function which did not support ETH value; this maintains backwards
* compatibility.
* @param _gasLimit Amount of gas to be passed into this call. * @param _gasLimit Amount of gas to be passed into this call.
* @param _address Address of the contract to call. * @param _address Address of the contract to call.
* @param _calldata Data to send along with the call. * @param _calldata Data to send along with the call.
...@@ -953,7 +958,8 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager, Lib_AddressResolver { ...@@ -953,7 +958,8 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager, Lib_AddressResolver {
********************************************/ ********************************************/
/** /**
* Checks whether the given address is on the whitelist to ovmCREATE/ovmCREATE2, and reverts if not. * Checks whether the given address is on the whitelist to ovmCREATE/ovmCREATE2,
* and reverts if not.
* @param _deployerAddress Address attempting to deploy a contract. * @param _deployerAddress Address attempting to deploy a contract.
*/ */
function _checkDeployerAllowed( function _checkDeployerAllowed(
...@@ -1048,17 +1054,21 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager, Lib_AddressResolver { ...@@ -1048,17 +1054,21 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager, Lib_AddressResolver {
bytes memory _returndata bytes memory _returndata
) )
{ {
// We reserve addresses of the form 0xdeaddeaddead...NNNN for the container contracts in L2 geth. // We reserve addresses of the form 0xdeaddeaddead...NNNN for the container contracts in L2
// So, we block calls to these addresses since they are not safe to run as an OVM contract itself. // geth. So, we block calls to these addresses since they are not safe to run as an OVM
// contract itself.
if ( if (
(uint256(_contract) & uint256(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000)) (uint256(_contract) &
uint256(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000))
== uint256(CONTAINER_CONTRACT_PREFIX) == uint256(CONTAINER_CONTRACT_PREFIX)
) { ) {
// solhint-disable-next-line max-line-length
// EVM does not return data in the success case, see: https://github.com/ethereum/go-ethereum/blob/aae7660410f0ef90279e14afaaf2f429fdc2a186/core/vm/instructions.go#L600-L604 // EVM does not return data in the success case, see: https://github.com/ethereum/go-ethereum/blob/aae7660410f0ef90279e14afaaf2f429fdc2a186/core/vm/instructions.go#L600-L604
return (true, hex''); return (true, hex'');
} }
// Both 0x0000... and the EVM precompiles have the same address on L1 and L2 --> no trie lookup needed. // Both 0x0000... and the EVM precompiles have the same address on L1 and L2 -->
// no trie lookup needed.
address codeContractAddress = address codeContractAddress =
uint(_contract) < 100 uint(_contract) < 100
? _contract ? _contract
...@@ -1074,11 +1084,13 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager, Lib_AddressResolver { ...@@ -1074,11 +1084,13 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager, Lib_AddressResolver {
} }
/** /**
* Handles all interactions which involve the execution manager calling out to untrusted code (both calls and creates). * Handles all interactions which involve the execution manager calling out to untrusted code
* Ensures that OVM-related measures are enforced, including L2 gas refunds, nuisance gas, and flagged reversions. * (both calls and creates). Ensures that OVM-related measures are enforced, including L2 gas
* refunds, nuisance gas, and flagged reversions.
* *
* @param _nextMessageContext Message context to be used for the external message. * @param _nextMessageContext Message context to be used for the external message.
* @param _gasLimit Amount of gas to be passed into this message. NOTE: this argument is overwritten in some cases to avoid stack-too-deep. * @param _gasLimit Amount of gas to be passed into this message. NOTE: this argument is
* overwritten in some cases to avoid stack-too-deep.
* @param _contract OVM address being called or deployed to * @param _contract OVM address being called or deployed to
* @param _data Data for the message (either calldata or creation code) * @param _data Data for the message (either calldata or creation code)
* @param _messageType What type of ovmOPCODE this message corresponds to. * @param _messageType What type of ovmOPCODE this message corresponds to.
...@@ -1100,23 +1112,28 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager, Lib_AddressResolver { ...@@ -1100,23 +1112,28 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager, Lib_AddressResolver {
) )
{ {
uint256 messageValue = _nextMessageContext.ovmCALLVALUE; uint256 messageValue = _nextMessageContext.ovmCALLVALUE;
// If there is value in this message, we need to transfer the ETH over before switching contexts. // If there is value in this message, we need to transfer the ETH over before switching
// contexts.
if ( if (
messageValue > 0 messageValue > 0
&& _isValueType(_messageType) && _isValueType(_messageType)
) { ) {
// Handle out-of-intrinsic gas consistent with EVM behavior -- the subcall "appears to revert" if we don't have enough gas to transfer the ETH. // Handle out-of-intrinsic gas consistent with EVM behavior -- the subcall "appears to
// revert" if we don't have enough gas to transfer the ETH.
// Similar to dynamic gas cost of value exceeding gas here: // Similar to dynamic gas cost of value exceeding gas here:
// solhint-disable-next-line max-line-length
// https://github.com/ethereum/go-ethereum/blob/c503f98f6d5e80e079c1d8a3601d188af2a899da/core/vm/interpreter.go#L268-L273 // https://github.com/ethereum/go-ethereum/blob/c503f98f6d5e80e079c1d8a3601d188af2a899da/core/vm/interpreter.go#L268-L273
if (gasleft() < CALL_WITH_VALUE_INTRINSIC_GAS) { if (gasleft() < CALL_WITH_VALUE_INTRINSIC_GAS) {
return (false, hex""); return (false, hex"");
} }
// If there *is* enough gas to transfer ETH, then we need to make sure this amount of gas is reserved (i.e. not // If there *is* enough gas to transfer ETH, then we need to make sure this amount of
// given to the _contract.call below) to guarantee that _handleExternalMessage can't run out of gas. // gas is reserved (i.e. not given to the _contract.call below) to guarantee that
// In particular, in the event that the call fails, we will need to transfer the ETH back to the sender. // _handleExternalMessage can't run out of gas. In particular, in the event that
// Taking the lesser of _gasLimit and gasleft() - CALL_WITH_VALUE_INTRINSIC_GAS guarantees that the second // the call fails, we will need to transfer the ETH back to the sender.
// _attemptForcedEthTransfer below, if needed, always has enough gas to succeed. // Taking the lesser of _gasLimit and gasleft() - CALL_WITH_VALUE_INTRINSIC_GAS
// guarantees that the second _attemptForcedEthTransfer below, if needed, always has
// enough gas to succeed.
_gasLimit = Math.min( _gasLimit = Math.min(
_gasLimit, _gasLimit,
gasleft() - CALL_WITH_VALUE_INTRINSIC_GAS // Cannot overflow due to the above check. gasleft() - CALL_WITH_VALUE_INTRINSIC_GAS // Cannot overflow due to the above check.
...@@ -1129,8 +1146,10 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager, Lib_AddressResolver { ...@@ -1129,8 +1146,10 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager, Lib_AddressResolver {
messageValue messageValue
); );
// If the ETH transfer fails (should only be possible in the case of insufficient balance), then treat this as a revert. // If the ETH transfer fails (should only be possible in the case of insufficient
// This mirrors EVM behavior, see https://github.com/ethereum/go-ethereum/blob/2dee31930c9977af2a9fcb518fb9838aa609a7cf/core/vm/evm.go#L298 // balance), then treat this as a revert. This mirrors EVM behavior, see
// solhint-disable-next-line max-line-length
// https://github.com/ethereum/go-ethereum/blob/2dee31930c9977af2a9fcb518fb9838aa609a7cf/core/vm/evm.go#L298
if (!transferredOvmEth) { if (!transferredOvmEth) {
return (false, hex""); return (false, hex"");
} }
...@@ -1184,16 +1203,18 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager, Lib_AddressResolver { ...@@ -1184,16 +1203,18 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager, Lib_AddressResolver {
messageValue messageValue
); );
// Since we transferred it in above and the call reverted, the transfer back should always pass. // Since we transferred it in above and the call reverted, the transfer back should
// This code path should NEVER be triggered since we sent `messageValue` worth of OVM_ETH into the target // always pass. This code path should NEVER be triggered since we sent `messageValue`
// and reserved sufficient gas to execute the transfer, but in case there is some edge case which has // worth of OVM_ETH into the target and reserved sufficient gas to execute the transfer,
// been missed, we revert the entire frame (and its parent) to make sure the ETH gets sent back. // but in case there is some edge case which has been missed, we revert the entire frame
// (and its parent) to make sure the ETH gets sent back.
if (!transferredOvmEth) { if (!transferredOvmEth) {
_revertWithFlag(RevertFlag.OUT_OF_GAS); _revertWithFlag(RevertFlag.OUT_OF_GAS);
} }
} }
// Switch back to the original message context now that we're out of the call and all OVM_ETH is in the right place. // Switch back to the original message context now that we're out of the call and all
// OVM_ETH is in the right place.
_switchMessageContext(_nextMessageContext, prevMessageContext); _switchMessageContext(_nextMessageContext, prevMessageContext);
// Assuming there were no reverts, the message record should be accurate here. We'll update // Assuming there were no reverts, the message record should be accurate here. We'll update
...@@ -1218,8 +1239,9 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager, Lib_AddressResolver { ...@@ -1218,8 +1239,9 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager, Lib_AddressResolver {
} }
// INTENTIONAL_REVERT, UNSAFE_BYTECODE, STATIC_VIOLATION, and CREATOR_NOT_ALLOWED aren't // INTENTIONAL_REVERT, UNSAFE_BYTECODE, STATIC_VIOLATION, and CREATOR_NOT_ALLOWED aren't
// dependent on the input state, so we can just handle them like standard reverts. Our only change here // dependent on the input state, so we can just handle them like standard reverts.
// is to record the gas refund reported by the call (enforced by safety checking). // Our only change here is to record the gas refund reported by the call (enforced by
// safety checking).
if ( if (
flag == RevertFlag.INTENTIONAL_REVERT flag == RevertFlag.INTENTIONAL_REVERT
|| flag == RevertFlag.UNSAFE_BYTECODE || flag == RevertFlag.UNSAFE_BYTECODE
...@@ -1262,7 +1284,8 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager, Lib_AddressResolver { ...@@ -1262,7 +1284,8 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager, Lib_AddressResolver {
/** /**
* Handles the creation-specific safety measures required for OVM contract deployment. * Handles the creation-specific safety measures required for OVM contract deployment.
* This function sanitizes the return types for creation messages to match calls (bool, bytes), * 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. * 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(). * 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. * contract deployment in the event that the code is unsafe.
...@@ -1296,7 +1319,7 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager, Lib_AddressResolver { ...@@ -1296,7 +1319,7 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager, Lib_AddressResolver {
// developer experience, we do return the remaining gas. // developer experience, we do return the remaining gas.
_revertWithFlag( _revertWithFlag(
RevertFlag.UNSAFE_BYTECODE, RevertFlag.UNSAFE_BYTECODE,
Lib_ErrorUtils.encodeRevertString("Contract creation code contains unsafe opcodes. Did you use the right compiler or pass an unsafe constructor argument?") Lib_ErrorUtils.encodeRevertString("Contract creation code contains unsafe opcodes. Did you use the right compiler or pass an unsafe constructor argument?") // solhint-disable-line max-line-length
); );
} }
...@@ -1304,12 +1327,13 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager, Lib_AddressResolver { ...@@ -1304,12 +1327,13 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager, Lib_AddressResolver {
_initPendingAccount(_address); _initPendingAccount(_address);
// Actually execute the EVM create message. // Actually execute the EVM create message.
// NOTE: The inline assembly below means we can NOT make any evm calls between here and then. // NOTE: The inline assembly below means we can NOT make any evm calls between here and then
address ethAddress = Lib_EthUtils.createContract(_creationCode); address ethAddress = Lib_EthUtils.createContract(_creationCode);
if (ethAddress == address(0)) { if (ethAddress == address(0)) {
// If the creation fails, the EVM lets us grab its revert data. This may contain a revert flag // If the creation fails, the EVM lets us grab its revert data. This may contain a
// to be used above in _handleExternalMessage, so we pass the revert data back up unmodified. // revert flag to be used above in _handleExternalMessage, so we pass the revert data
// back up unmodified.
assembly { assembly {
returndatacopy(0,0,returndatasize()) returndatacopy(0,0,returndatasize())
revert(0, returndatasize()) revert(0, returndatasize())
...@@ -1322,7 +1346,7 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager, Lib_AddressResolver { ...@@ -1322,7 +1346,7 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager, Lib_AddressResolver {
if (ovmSafetyChecker.isBytecodeSafe(deployedCode) == false) { if (ovmSafetyChecker.isBytecodeSafe(deployedCode) == false) {
_revertWithFlag( _revertWithFlag(
RevertFlag.UNSAFE_BYTECODE, RevertFlag.UNSAFE_BYTECODE,
Lib_ErrorUtils.encodeRevertString("Constructor attempted to deploy unsafe bytecode.") Lib_ErrorUtils.encodeRevertString("Constructor attempted to deploy unsafe bytecode.") // solhint-disable-line max-line-length
); );
} }
...@@ -1340,8 +1364,10 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager, Lib_AddressResolver { ...@@ -1340,8 +1364,10 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager, Lib_AddressResolver {
******************************************/ ******************************************/
/** /**
* Invokes an ovmCALL to OVM_ETH.transfer on behalf of the current ovmADDRESS, allowing us to force movement of OVM_ETH in correspondence with ETH's native value functionality. * Invokes an ovmCALL to OVM_ETH.transfer on behalf of the current ovmADDRESS, allowing us to
* WARNING: this will send on behalf of whatever the messageContext.ovmADDRESS is in storage at the time of the call. * force movement of OVM_ETH in correspondence with ETH's native value functionality.
* WARNING: this will send on behalf of whatever the messageContext.ovmADDRESS is in storage
* at the time of the call.
* NOTE: In the future, this could be optimized to directly invoke EM._setContractStorage(...). * NOTE: In the future, this could be optimized to directly invoke EM._setContractStorage(...).
* @param _to Amount of OVM_ETH to be sent. * @param _to Amount of OVM_ETH to be sent.
* @param _value Amount of OVM_ETH to send. * @param _value Amount of OVM_ETH to send.
...@@ -1362,8 +1388,8 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager, Lib_AddressResolver { ...@@ -1362,8 +1388,8 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager, Lib_AddressResolver {
_value _value
); );
// OVM_ETH inherits from the UniswapV2ERC20 standard. In this implementation, its return type // OVM_ETH inherits from the UniswapV2ERC20 standard. In this implementation, its return
// is a boolean. However, the implementation always returns true if it does not revert. // type is a boolean. However, the implementation always returns true if it does not revert
// Thus, success of the call frame is sufficient to infer success of the transfer itself. // Thus, success of the call frame is sufficient to infer success of the transfer itself.
(bool success, ) = ovmCALL( (bool success, ) = ovmCALL(
gasleft(), gasleft(),
...@@ -1576,7 +1602,8 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager, Lib_AddressResolver { ...@@ -1576,7 +1602,8 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager, Lib_AddressResolver {
// on the size of the contract code. // on the size of the contract code.
if (_wasAccountAlreadyLoaded == false) { if (_wasAccountAlreadyLoaded == false) {
_useNuisanceGas( _useNuisanceGas(
(Lib_EthUtils.getCodeSize(_getAccountEthAddress(_address)) * NUISANCE_GAS_PER_CONTRACT_BYTE) + MIN_NUISANCE_GAS_PER_CONTRACT (Lib_EthUtils.getCodeSize(_getAccountEthAddress(_address))
* NUISANCE_GAS_PER_CONTRACT_BYTE) + MIN_NUISANCE_GAS_PER_CONTRACT
); );
} }
} }
...@@ -1606,7 +1633,8 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager, Lib_AddressResolver { ...@@ -1606,7 +1633,8 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager, Lib_AddressResolver {
if (_wasAccountAlreadyChanged == false) { if (_wasAccountAlreadyChanged == false) {
ovmStateManager.incrementTotalUncommittedAccounts(); ovmStateManager.incrementTotalUncommittedAccounts();
_useNuisanceGas( _useNuisanceGas(
(Lib_EthUtils.getCodeSize(_getAccountEthAddress(_address)) * NUISANCE_GAS_PER_CONTRACT_BYTE) + MIN_NUISANCE_GAS_PER_CONTRACT (Lib_EthUtils.getCodeSize(_getAccountEthAddress(_address))
* NUISANCE_GAS_PER_CONTRACT_BYTE) + MIN_NUISANCE_GAS_PER_CONTRACT
); );
} }
} }
...@@ -1708,7 +1736,8 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager, Lib_AddressResolver { ...@@ -1708,7 +1736,8 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager, Lib_AddressResolver {
bytes memory _revertdata bytes memory _revertdata
) )
{ {
// Out of gas and create exceptions will fundamentally return no data, so simulating it shouldn't either. // Out of gas and create exceptions will fundamentally return no data, so simulating it
// shouldn't either.
if ( if (
_flag == RevertFlag.OUT_OF_GAS _flag == RevertFlag.OUT_OF_GAS
) { ) {
...@@ -1903,9 +1932,9 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager, Lib_AddressResolver { ...@@ -1903,9 +1932,9 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager, Lib_AddressResolver {
// This check prevents calling run with the default ovmNumber. // This check prevents calling run with the default ovmNumber.
// Combined with the first check in run(): // Combined with the first check in run():
// if (transactionContext.ovmNUMBER != DEFAULT_UINT256) { return; } // if (transactionContext.ovmNUMBER != DEFAULT_UINT256) { return; }
// It should be impossible to re-enter since run() returns before any other call frames are created. // It should be impossible to re-enter since run() returns before any other call frames are
// Since this value is already being written to storage, we save much gas compared to // created. Since this value is already being written to storage, we save much gas compared
// using the standard nonReentrant pattern. // to using the standard nonReentrant pattern.
if (_transaction.blockNumber == DEFAULT_UINT256) { if (_transaction.blockNumber == DEFAULT_UINT256) {
return false; return false;
} }
...@@ -2046,8 +2075,9 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager, Lib_AddressResolver { ...@@ -2046,8 +2075,9 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager, Lib_AddressResolver {
) )
internal internal
{ {
// These conditionals allow us to avoid unneccessary SSTOREs. However, they do mean that the current storage // These conditionals allow us to avoid unneccessary SSTOREs. However, they do mean that
// value for the messageContext MUST equal the _prevMessageContext argument, or an SSTORE might be erroneously skipped. // the current storage value for the messageContext MUST equal the _prevMessageContext
// argument, or an SSTORE might be erroneously skipped.
if (_prevMessageContext.ovmCALLER != _nextMessageContext.ovmCALLER) { if (_prevMessageContext.ovmCALLER != _nextMessageContext.ovmCALLER) {
messageContext.ovmCALLER = _nextMessageContext.ovmCALLER; messageContext.ovmCALLER = _nextMessageContext.ovmCALLER;
} }
...@@ -2134,7 +2164,8 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager, Lib_AddressResolver { ...@@ -2134,7 +2164,8 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager, Lib_AddressResolver {
} }
/** /**
* Returns whether or not the given message type (potentially) requires the transfer of ETH value along with the message. * Returns whether or not the given message type (potentially) requires the transfer of ETH
* value along with the message.
* @param _messageType the message type in question. * @param _messageType the message type in question.
*/ */
function _isValueType( function _isValueType(
...@@ -2161,7 +2192,8 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager, Lib_AddressResolver { ...@@ -2161,7 +2192,8 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager, Lib_AddressResolver {
/** /**
* Unreachable helper function for simulating eth_calls with an OVM message context. * Unreachable helper function for simulating eth_calls with an OVM message context.
* This function will throw an exception in all cases other than when used as a custom entrypoint in L2 Geth to simulate eth_call. * This function will throw an exception in all cases other than when used as a custom
* entrypoint in L2 Geth to simulate eth_call.
* @param _transaction the message transaction to simulate. * @param _transaction the message transaction to simulate.
* @param _from the OVM account the simulated call should be from. * @param _from the OVM account the simulated call should be from.
* @param _value the amount of ETH value to send. * @param _value the amount of ETH value to send.
......
...@@ -51,8 +51,10 @@ contract OVM_SafetyChecker is iOVM_SafetyChecker { ...@@ -51,8 +51,10 @@ contract OVM_SafetyChecker is iOVM_SafetyChecker {
uint256(0x0000000000000000000000000000000000000000000000000000000000000000) uint256(0x0000000000000000000000000000000000000000000000000000000000000000)
]; ];
// Mask to gate opcode specific cases // Mask to gate opcode specific cases
// solhint-disable-next-line max-line-length
uint256 opcodeGateMask = ~uint256(0xffffffffffffffffffffffe000000000fffffffff070ffff9c0ffffec000f001); uint256 opcodeGateMask = ~uint256(0xffffffffffffffffffffffe000000000fffffffff070ffff9c0ffffec000f001);
// Halting opcodes // Halting opcodes
// solhint-disable-next-line max-line-length
uint256 opcodeHaltingMask = ~uint256(0x4008000000000000000000000000000000000000004000000000000000000001); uint256 opcodeHaltingMask = ~uint256(0x4008000000000000000000000000000000000000004000000000000000000001);
// PUSH opcodes // PUSH opcodes
uint256 opcodePushMask = ~uint256(0xffffffff000000000000000000000000); uint256 opcodePushMask = ~uint256(0xffffffff000000000000000000000000);
...@@ -67,6 +69,7 @@ contract OVM_SafetyChecker is iOVM_SafetyChecker { ...@@ -67,6 +69,7 @@ contract OVM_SafetyChecker is iOVM_SafetyChecker {
// current opcode: 0x00...0xff // current opcode: 0x00...0xff
uint256 opNum; uint256 opNum;
/* solhint-disable max-line-length */
// inline assembly removes the extra add + bounds check // inline assembly removes the extra add + bounds check
assembly { assembly {
let word := mload(_pc) //load the next 32 bytes at pc into word let word := mload(_pc) //load the next 32 bytes at pc into word
...@@ -86,6 +89,7 @@ contract OVM_SafetyChecker is iOVM_SafetyChecker { ...@@ -86,6 +89,7 @@ contract OVM_SafetyChecker is iOVM_SafetyChecker {
opNum := byte(indexInWord, word) opNum := byte(indexInWord, word)
} }
/* solhint-disable max-line-length */
// + push opcodes // + push opcodes
// + stop opcodes [STOP(0x00),JUMP(0x56),RETURN(0xf3),INVALID(0xfe)] // + stop opcodes [STOP(0x00),JUMP(0x56),RETURN(0xf3),INVALID(0xfe)]
......
...@@ -10,8 +10,9 @@ import { iOVM_StateManager } from "../../iOVM/execution/iOVM_StateManager.sol"; ...@@ -10,8 +10,9 @@ import { iOVM_StateManager } from "../../iOVM/execution/iOVM_StateManager.sol";
/** /**
* @title OVM_StateManager * @title OVM_StateManager
* @dev The State Manager contract holds all storage values for contracts in the OVM. It can only be written to by the * @dev The State Manager contract holds all storage values for contracts in the OVM. It can only be
* the Execution Manager and State Transitioner. It runs on L1 during the setup and execution of a fraud proof. * written to by the Execution Manager and State Transitioner. It runs on L1 during the setup and
* execution of a fraud proof.
* The same logic runs on L2, but has been implemented as a precompile in the L2 go-ethereum client * The same logic runs on L2, but has been implemented as a precompile in the L2 go-ethereum client
* (see https://github.com/ethereum-optimism/go-ethereum/blob/master/core/vm/ovm_state_manager.go). * (see https://github.com/ethereum-optimism/go-ethereum/blob/master/core/vm/ovm_state_manager.go).
* *
...@@ -24,10 +25,12 @@ contract OVM_StateManager is iOVM_StateManager { ...@@ -24,10 +25,12 @@ contract OVM_StateManager is iOVM_StateManager {
* Constants * * Constants *
*************/ *************/
bytes32 constant internal EMPTY_ACCOUNT_STORAGE_ROOT = 0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421; bytes32 constant internal EMPTY_ACCOUNT_STORAGE_ROOT =
bytes32 constant internal EMPTY_ACCOUNT_CODE_HASH = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470; 0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421;
bytes32 constant internal STORAGE_XOR_VALUE = 0xFEEDFACECAFEBEEFFEEDFACECAFEBEEFFEEDFACECAFEBEEFFEEDFACECAFEBEEF; bytes32 constant internal EMPTY_ACCOUNT_CODE_HASH =
0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;
bytes32 constant internal STORAGE_XOR_VALUE =
0xFEEDFACECAFEBEEFFEEDFACECAFEBEEFFEEDFACECAFEBEEFFEEDFACECAFEBEEF;
/************* /*************
* Variables * * Variables *
...@@ -42,7 +45,6 @@ contract OVM_StateManager is iOVM_StateManager { ...@@ -42,7 +45,6 @@ contract OVM_StateManager is iOVM_StateManager {
uint256 internal totalUncommittedAccounts; uint256 internal totalUncommittedAccounts;
uint256 internal totalUncommittedContractStorage; uint256 internal totalUncommittedContractStorage;
/*************** /***************
* Constructor * * Constructor *
***************/ ***************/
...@@ -57,13 +59,13 @@ contract OVM_StateManager is iOVM_StateManager { ...@@ -57,13 +59,13 @@ contract OVM_StateManager is iOVM_StateManager {
owner = _owner; owner = _owner;
} }
/********************** /**********************
* Function Modifiers * * Function Modifiers *
**********************/ **********************/
/** /**
* Simple authentication, this contract should only be accessible to the owner (which is expected to be the State Transitioner during `PRE_EXECUTION` * Simple authentication, this contract should only be accessible to the owner
* (which is expected to be the State Transitioner during `PRE_EXECUTION`
* or the OVM_ExecutionManager during transaction execution. * or the OVM_ExecutionManager during transaction execution.
*/ */
modifier authenticated() { modifier authenticated() {
......
// SPDX-License-Identifier: CC0-1.0 // SPDX-License-Identifier: CC0-1.0
/* ERC1820 Pseudo-introspection Registry Contract /* ERC1820 Pseudo-introspection Registry Contract
* This standard defines a universal registry smart contract where any address (contract or regular account) can * This standard defines a universal registry smart contract where any address (contract or regular
* register which interface it supports and which smart contract is responsible for its implementation. * account) can register which interface it supports and which smart contract is responsible for its
* implementation.
* *
* Written in 2019 by Jordi Baylina and Jacques Dafflon * Written in 2019 by Jordi Baylina and Jacques Dafflon
* *
* To the extent possible under law, the author(s) have dedicated all copyright and related and neighboring rights to * To the extent possible under law, the author(s) have dedicated all copyright and related and
* this software to the public domain worldwide. This software is distributed without any warranty. * neighboring rights to this software to the public domain worldwide. This software is distributed
* without any warranty.
* *
* You should have received a copy of the CC0 Public Domain Dedication along with this software. If not, see * You should have received a copy of the CC0 Public Domain Dedication along with this software.
* <http://creativecommons.org/publicdomain/zero/1.0/>. * If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
*/ */
pragma solidity >0.5.0 <0.8.0; pragma solidity >0.5.0 <0.8.0;
/// @dev The interface a contract MUST implement if it is the implementer of /// @dev The interface a contract MUST implement if it is the implementer of
/// some (other) interface for any address other than itself. /// some (other) interface for any address other than itself.
interface ERC1820ImplementerInterface { interface ERC1820ImplementerInterface {
/// @notice Indicates whether the contract implements the interface 'interfaceHash' for the address 'addr' or not. /// @notice Indicates whether the contract implements the interface 'interfaceHash' for the
/// address 'addr' or not.
/// @param interfaceHash keccak256 hash of the name of the interface /// @param interfaceHash keccak256 hash of the name of the interface
/// @param addr Address for which the contract will implement the interface /// @param addr Address for which the contract will implement the interface
/// @return ERC1820_ACCEPT_MAGIC only if the contract implements 'interfaceHash' for the address 'addr'. /// @return ERC1820_ACCEPT_MAGIC only if the contract implements 'interfaceHash' for the address
function canImplementInterfaceForAddress(bytes32 interfaceHash, address addr) external view returns(bytes32); /// 'addr'.
function canImplementInterfaceForAddress(bytes32 interfaceHash, address addr) external view
returns(bytes32);
} }
/** /**
...@@ -35,25 +40,31 @@ interface ERC1820ImplementerInterface { ...@@ -35,25 +40,31 @@ interface ERC1820ImplementerInterface {
contract ERC1820Registry { contract ERC1820Registry {
bytes4 constant internal INVALID_ID = 0xffffffff; bytes4 constant internal INVALID_ID = 0xffffffff;
bytes4 constant internal ERC165ID = 0x01ffc9a7; bytes4 constant internal ERC165ID = 0x01ffc9a7;
bytes32 constant internal ERC1820_ACCEPT_MAGIC = keccak256(abi.encodePacked("ERC1820_ACCEPT_MAGIC")); bytes32 constant internal ERC1820_ACCEPT_MAGIC =
keccak256(abi.encodePacked("ERC1820_ACCEPT_MAGIC"));
mapping(address => mapping(bytes32 => address)) internal interfaces; mapping(address => mapping(bytes32 => address)) internal interfaces;
mapping(address => address) internal managers; mapping(address => address) internal managers;
mapping(address => mapping(bytes4 => bool)) internal erc165Cached; mapping(address => mapping(bytes4 => bool)) internal erc165Cached;
/// @notice Indicates a contract is the 'implementer' of 'interfaceHash' for 'addr'. /// @notice Indicates a contract is the 'implementer' of 'interfaceHash' for 'addr'.
event InterfaceImplementerSet(address indexed addr, bytes32 indexed interfaceHash, address indexed implementer); event InterfaceImplementerSet(
address indexed addr,
bytes32 indexed interfaceHash,
address indexed implementer);
/// @notice Indicates 'newManager' is the address of the new manager for 'addr'. /// @notice Indicates 'newManager' is the address of the new manager for 'addr'.
event ManagerChanged(address indexed addr, address indexed newManager); event ManagerChanged(address indexed addr, address indexed newManager);
/// @notice Query if an address implements an interface and through which contract. /// @notice Query if an address implements an interface and through which contract.
/// @param _addr Address being queried for the implementer of an interface. /// @param _addr Address being queried for the implementer of an interface.
/// (If '_addr' is the zero address then 'msg.sender' is assumed.) // (If '_addr' is the zero address then 'msg.sender' is assumed.)
/// @param _interfaceHash Keccak256 hash of the name of the interface as a string. /// @param _interfaceHash Keccak256 hash of the name of the interface as a string.
/// E.g., 'web3.utils.keccak256("ERC777TokensRecipient")' for the 'ERC777TokensRecipient' interface. // E.g., 'web3.utils.keccak256("ERC777TokensRecipient")' for the 'ERC777TokensRecipient'
/// @return The address of the contract which implements the interface '_interfaceHash' for '_addr' // interface.
/// or '0' if '_addr' did not register an implementer for this interface. /// @return The address of the contract which implements the interface '_interfaceHash' for
function getInterfaceImplementer(address _addr, bytes32 _interfaceHash) external view returns (address) { // '_addr' or '0' if '_addr' did not register an implementer for this interface.
function getInterfaceImplementer(address _addr, bytes32 _interfaceHash) external view
returns (address) {
address addr = _addr == address(0) ? msg.sender : _addr; address addr = _addr == address(0) ? msg.sender : _addr;
if (isERC165Interface(_interfaceHash)) { if (isERC165Interface(_interfaceHash)) {
bytes4 erc165InterfaceHash = bytes4(_interfaceHash); bytes4 erc165InterfaceHash = bytes4(_interfaceHash);
...@@ -63,14 +74,16 @@ contract ERC1820Registry { ...@@ -63,14 +74,16 @@ contract ERC1820Registry {
} }
/// @notice Sets the contract which implements a specific interface for an address. /// @notice Sets the contract which implements a specific interface for an address.
/// Only the manager defined for that address can set it. // Only the manager defined for that address can set it.
/// (Each address is the manager for itself until it sets a new manager.) // (Each address is the manager for itself until it sets a new manager.)
/// @param _addr Address for which to set the interface. /// @param _addr Address for which to set the interface.
/// (If '_addr' is the zero address then 'msg.sender' is assumed.) // (If '_addr' is the zero address then 'msg.sender' is assumed.)
/// @param _interfaceHash Keccak256 hash of the name of the interface as a string. /// @param _interfaceHash Keccak256 hash of the name of the interface as a string.
/// E.g., 'web3.utils.keccak256("ERC777TokensRecipient")' for the 'ERC777TokensRecipient' interface. // e.g. 'web3.utils.keccak256("ERC777TokensRecipient")' for the 'ERC777TokensRecipient'
// interface.
/// @param _implementer Contract address implementing '_interfaceHash' for '_addr'. /// @param _implementer Contract address implementing '_interfaceHash' for '_addr'.
function setInterfaceImplementer(address _addr, bytes32 _interfaceHash, address _implementer) external { function setInterfaceImplementer(address _addr, bytes32 _interfaceHash, address _implementer)
external {
address addr = _addr == address(0) ? msg.sender : _addr; address addr = _addr == address(0) ? msg.sender : _addr;
require(getManager(addr) == msg.sender, "Not the manager"); require(getManager(addr) == msg.sender, "Not the manager");
...@@ -87,9 +100,10 @@ contract ERC1820Registry { ...@@ -87,9 +100,10 @@ contract ERC1820Registry {
} }
/// @notice Sets '_newManager' as manager for '_addr'. /// @notice Sets '_newManager' as manager for '_addr'.
/// The new manager will be able to call 'setInterfaceImplementer' for '_addr'. // The new manager will be able to call 'setInterfaceImplementer' for '_addr'.
/// @param _addr Address for which to set the new manager. /// @param _addr Address for which to set the new manager.
/// @param _newManager Address of the new manager for 'addr'. (Pass '0x0' to reset the manager to '_addr'.) /// @param _newManager Address of the new manager for 'addr'.
// (Pass '0x0' to reset the manager to '_addr'.)
function setManager(address _addr, address _newManager) external { function setManager(address _addr, address _newManager) external {
require(getManager(_addr) == msg.sender, "Not the manager"); require(getManager(_addr) == msg.sender, "Not the manager");
managers[_addr] = _newManager == _addr ? address(0) : _newManager; managers[_addr] = _newManager == _addr ? address(0) : _newManager;
...@@ -129,23 +143,27 @@ contract ERC1820Registry { ...@@ -129,23 +143,27 @@ contract ERC1820Registry {
/// @notice Checks whether a contract implements an ERC165 interface or not. /// @notice Checks whether a contract implements an ERC165 interface or not.
// If the result is not cached a direct lookup on the contract address is performed. // If the result is not cached a direct lookup on the contract address is performed.
// If the result is not cached or the cached value is out-of-date, the cache MUST be updated manually by calling // If the result is not cached or the cached value is out-of-date, the cache MUST be updated
// manually by calling
// 'updateERC165Cache' with the contract address. // 'updateERC165Cache' with the contract address.
/// @param _contract Address of the contract to check. /// @param _contract Address of the contract to check.
/// @param _interfaceId ERC165 interface to check. /// @param _interfaceId ERC165 interface to check.
/// @return True if '_contract' implements '_interfaceId', false otherwise. /// @return True if '_contract' implements '_interfaceId', false otherwise.
function implementsERC165Interface(address _contract, bytes4 _interfaceId) public view returns (bool) { function implementsERC165Interface(address _contract, bytes4 _interfaceId) public view
returns (bool) {
if (!erc165Cached[_contract][_interfaceId]) { if (!erc165Cached[_contract][_interfaceId]) {
return implementsERC165InterfaceNoCache(_contract, _interfaceId); return implementsERC165InterfaceNoCache(_contract, _interfaceId);
} }
return interfaces[_contract][_interfaceId] == _contract; return interfaces[_contract][_interfaceId] == _contract;
} }
/// @notice Checks whether a contract implements an ERC165 interface or not without using nor updating the cache. /// @notice Checks whether a contract implements an ERC165 interface or not without using nor
// updating the cache.
/// @param _contract Address of the contract to check. /// @param _contract Address of the contract to check.
/// @param _interfaceId ERC165 interface to check. /// @param _interfaceId ERC165 interface to check.
/// @return True if '_contract' implements '_interfaceId', false otherwise. /// @return True if '_contract' implements '_interfaceId', false otherwise.
function implementsERC165InterfaceNoCache(address _contract, bytes4 _interfaceId) public view returns (bool) { function implementsERC165InterfaceNoCache(address _contract, bytes4 _interfaceId) public view
returns (bool) {
uint256 success; uint256 success;
uint256 result; uint256 result;
...@@ -168,8 +186,10 @@ contract ERC1820Registry { ...@@ -168,8 +186,10 @@ contract ERC1820Registry {
/// @notice Checks whether the hash is a ERC165 interface (ending with 28 zeroes) or not. /// @notice Checks whether the hash is a ERC165 interface (ending with 28 zeroes) or not.
/// @param _interfaceHash The hash to check. /// @param _interfaceHash The hash to check.
/// @return True if '_interfaceHash' is an ERC165 interface (ending with 28 zeroes), false otherwise. /// @return True if '_interfaceHash' is an ERC165 interface (ending with 28 zeroes),
// false otherwise.
function isERC165Interface(bytes32 _interfaceHash) internal pure returns (bool) { function isERC165Interface(bytes32 _interfaceHash) internal pure returns (bool) {
// solhint-disable-next-line max-line-length
return _interfaceHash & 0x00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF == 0; return _interfaceHash & 0x00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF == 0;
} }
...@@ -180,7 +200,7 @@ contract ERC1820Registry { ...@@ -180,7 +200,7 @@ contract ERC1820Registry {
bytes4 erc165ID = ERC165ID; bytes4 erc165ID = ERC165ID;
assembly { assembly {
let x := mload(0x40) // Find empty storage location using "free memory pointer" let x := mload(0x40) // Find empty storage location using "free memory pointer"
mstore(x, erc165ID) // Place signature at beginning of empty storage mstore(x, erc165ID) // Place signature at beginning of empty storage
mstore(add(x, 0x04), _interfaceId) // Place first argument directly next to signature mstore(add(x, 0x04), _interfaceId) // Place first argument directly next to signature
......
...@@ -7,7 +7,8 @@ import { iOVM_ECDSAContractAccount } from "../../iOVM/predeploys/iOVM_ECDSAContr ...@@ -7,7 +7,8 @@ import { iOVM_ECDSAContractAccount } from "../../iOVM/predeploys/iOVM_ECDSAContr
/* Library Imports */ /* Library Imports */
import { Lib_EIP155Tx } from "../../libraries/codec/Lib_EIP155Tx.sol"; import { Lib_EIP155Tx } from "../../libraries/codec/Lib_EIP155Tx.sol";
import { Lib_ExecutionManagerWrapper } from "../../libraries/wrappers/Lib_ExecutionManagerWrapper.sol"; import { Lib_ExecutionManagerWrapper } from
"../../libraries/wrappers/Lib_ExecutionManagerWrapper.sol";
import { Lib_PredeployAddresses } from "../../libraries/constants/Lib_PredeployAddresses.sol"; import { Lib_PredeployAddresses } from "../../libraries/constants/Lib_PredeployAddresses.sol";
/* Contract Imports */ /* Contract Imports */
...@@ -152,9 +153,9 @@ contract OVM_ECDSAContractAccount is iOVM_ECDSAContractAccount { ...@@ -152,9 +153,9 @@ contract OVM_ECDSAContractAccount is iOVM_ECDSAContractAccount {
// cases, but since this is a contract we'd end up bumping the nonce twice. // cases, but since this is a contract we'd end up bumping the nonce twice.
Lib_ExecutionManagerWrapper.ovmINCREMENTNONCE(); Lib_ExecutionManagerWrapper.ovmINCREMENTNONCE();
// NOTE: Upgrades are temporarily disabled because users can, in theory, modify their EOA // NOTE: Upgrades are temporarily disabled because users can, in theory, modify their
// so that they don't have to pay any fees to the sequencer. Function will remain disabled // EOA so that they don't have to pay any fees to the sequencer. Function will remain
// until a robust solution is in place. // disabled until a robust solution is in place.
require( require(
_transaction.to != Lib_ExecutionManagerWrapper.ovmADDRESS(), _transaction.to != Lib_ExecutionManagerWrapper.ovmADDRESS(),
"Calls to self are disabled until upgradability is re-enabled." "Calls to self are disabled until upgradability is re-enabled."
......
...@@ -41,17 +41,18 @@ contract OVM_ETH is L2StandardERC20, IWETH9 { ...@@ -41,17 +41,18 @@ contract OVM_ETH is L2StandardERC20, IWETH9 {
/** /**
* Implements the WETH9 deposit() function as a no-op. * Implements the WETH9 deposit() function as a no-op.
* WARNING: this function does NOT have to do with cross-chain asset bridging. The * WARNING: this function does NOT have to do with cross-chain asset bridging. The relevant
* relevant deposit and withdraw functions for that use case can be found at L2StandardBridge.sol. * deposit and withdraw functions for that use case can be found at L2StandardBridge.sol.
* This function allows developers to treat OVM_ETH as WETH without any modifications to their code. * This function allows developers to treat OVM_ETH as WETH without any modifications to their
* code.
*/ */
function deposit() function deposit()
public public
payable payable
override override
{ {
// Calling deposit() with nonzero value will send the ETH to this contract address. Once recieved here, // Calling deposit() with nonzero value will send the ETH to this contract address.
// We transfer it back by sending to the msg.sender. // Once received here, we transfer it back by sending to the msg.sender.
_transfer(address(this), msg.sender, msg.value); _transfer(address(this), msg.sender, msg.value);
emit Deposit(msg.sender, msg.value); emit Deposit(msg.sender, msg.value);
...@@ -59,9 +60,10 @@ contract OVM_ETH is L2StandardERC20, IWETH9 { ...@@ -59,9 +60,10 @@ contract OVM_ETH is L2StandardERC20, IWETH9 {
/** /**
* Implements the WETH9 withdraw() function as a no-op. * Implements the WETH9 withdraw() function as a no-op.
* WARNING: this function does NOT have to do with cross-chain asset bridging. The * WARNING: this function does NOT have to do with cross-chain asset bridging. The relevant
* relevant deposit and withdraw functions for that use case can be found at L2StandardBridge.sol. * deposit and withdraw functions for that use case can be found at L2StandardBridge.sol.
* This function allows developers to treat OVM_ETH as WETH without any modifications to their code. * This function allows developers to treat OVM_ETH as WETH without any modifications to their
* code.
* @param _wad Amount being withdrawn * @param _wad Amount being withdrawn
*/ */
function withdraw( function withdraw(
...@@ -70,10 +72,12 @@ contract OVM_ETH is L2StandardERC20, IWETH9 { ...@@ -70,10 +72,12 @@ contract OVM_ETH is L2StandardERC20, IWETH9 {
external external
override override
{ {
// Calling withdraw() with value exceeding the withdrawer's ovmBALANCE should revert, as in WETH9. // Calling withdraw() with value exceeding the withdrawer's ovmBALANCE should revert,
// as in WETH9.
require(balanceOf(msg.sender) >= _wad); require(balanceOf(msg.sender) >= _wad);
// Other than emitting an event, OVM_ETH already is native ETH, so we don't need to do anything else. // Other than emitting an event, OVM_ETH already is native ETH, so we don't need to do
// anything else.
emit Withdrawal(msg.sender, _wad); emit Withdrawal(msg.sender, _wad);
} }
} }
...@@ -36,9 +36,9 @@ contract OVM_L2ToL1MessagePasser is iOVM_L2ToL1MessagePasser { ...@@ -36,9 +36,9 @@ contract OVM_L2ToL1MessagePasser is iOVM_L2ToL1MessagePasser {
override override
public public
{ {
// Note: although this function is public, only messages sent from the OVM_L2CrossDomainMessenger // Note: although this function is public, only messages sent from the
// will be relayed by the OVM_L1CrossDomainMessenger. This is enforced by a check in // OVM_L2CrossDomainMessenger will be relayed by the OVM_L1CrossDomainMessenger.
// OVM_L1CrossDomainMessenger._verifyStorageProof(). // This is enforced by a check in OVM_L1CrossDomainMessenger._verifyStorageProof().
sentMessages[keccak256( sentMessages[keccak256(
abi.encodePacked( abi.encodePacked(
_message, _message,
......
...@@ -4,13 +4,14 @@ pragma solidity >0.5.0 <0.8.0; ...@@ -4,13 +4,14 @@ pragma solidity >0.5.0 <0.8.0;
/* Library Imports */ /* Library Imports */
import { Lib_Bytes32Utils } from "../../libraries/utils/Lib_Bytes32Utils.sol"; import { Lib_Bytes32Utils } from "../../libraries/utils/Lib_Bytes32Utils.sol";
import { Lib_PredeployAddresses } from "../../libraries/constants/Lib_PredeployAddresses.sol"; import { Lib_PredeployAddresses } from "../../libraries/constants/Lib_PredeployAddresses.sol";
import { Lib_ExecutionManagerWrapper } from "../../libraries/wrappers/Lib_ExecutionManagerWrapper.sol"; import { Lib_ExecutionManagerWrapper } from
"../../libraries/wrappers/Lib_ExecutionManagerWrapper.sol";
/** /**
* @title OVM_ProxyEOA * @title OVM_ProxyEOA
* @dev The Proxy EOA contract uses a delegate call to execute the logic in an implementation contract. * @dev The Proxy EOA contract uses a delegate call to execute the logic in an implementation
* In combination with the logic implemented in the ECDSA Contract Account, this enables a form of upgradable * contract. In combination with the logic implemented in the ECDSA Contract Account, this enables
* 'account abstraction' on layer 2. * a form of upgradable 'account abstraction' on layer 2.
* *
* Compiler used: optimistic-solc * Compiler used: optimistic-solc
* Runtime target: OVM * Runtime target: OVM
...@@ -29,10 +30,9 @@ contract OVM_ProxyEOA { ...@@ -29,10 +30,9 @@ contract OVM_ProxyEOA {
/************* /*************
* Constants * * Constants *
*************/ *************/
// solhint-disable-next-line max-line-length
bytes32 constant IMPLEMENTATION_KEY = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; //bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1); bytes32 constant IMPLEMENTATION_KEY = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; //bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1);
/********************* /*********************
* Fallback Function * * Fallback Function *
*********************/ *********************/
......
...@@ -4,7 +4,8 @@ pragma experimental ABIEncoderV2; ...@@ -4,7 +4,8 @@ pragma experimental ABIEncoderV2;
/* Library Imports */ /* Library Imports */
import { Lib_EIP155Tx } from "../../libraries/codec/Lib_EIP155Tx.sol"; import { Lib_EIP155Tx } from "../../libraries/codec/Lib_EIP155Tx.sol";
import { Lib_ExecutionManagerWrapper } from "../../libraries/wrappers/Lib_ExecutionManagerWrapper.sol"; import { Lib_ExecutionManagerWrapper } from
"../../libraries/wrappers/Lib_ExecutionManagerWrapper.sol";
import { iOVM_ECDSAContractAccount } from "../../iOVM/predeploys/iOVM_ECDSAContractAccount.sol"; import { iOVM_ECDSAContractAccount } from "../../iOVM/predeploys/iOVM_ECDSAContractAccount.sol";
/** /**
......
...@@ -61,6 +61,7 @@ contract OVM_SequencerFeeVault { ...@@ -61,6 +61,7 @@ contract OVM_SequencerFeeVault {
require( require(
balance >= MIN_WITHDRAWAL_AMOUNT, balance >= MIN_WITHDRAWAL_AMOUNT,
// solhint-disable-next-line max-line-length
"OVM_SequencerFeeVault: withdrawal amount must be greater than minimum withdrawal amount" "OVM_SequencerFeeVault: withdrawal amount must be greater than minimum withdrawal amount"
); );
......
...@@ -13,6 +13,7 @@ abstract contract Abs_FraudContributor is Lib_AddressResolver { ...@@ -13,6 +13,7 @@ abstract contract Abs_FraudContributor is Lib_AddressResolver {
uint256 startGas = gasleft(); uint256 startGas = gasleft();
_; _;
uint256 gasSpent = startGas - gasleft(); uint256 gasSpent = startGas - gasleft();
iOVM_BondManager(resolve('OVM_BondManager')).recordGasSpent(preStateRoot, txHash, msg.sender, gasSpent); iOVM_BondManager(resolve('OVM_BondManager'))
.recordGasSpent(preStateRoot, txHash, msg.sender, gasSpent);
} }
} }
...@@ -75,9 +75,12 @@ contract OVM_BondManager is iOVM_BondManager, Lib_AddressResolver { ...@@ -75,9 +75,12 @@ contract OVM_BondManager is iOVM_BondManager, Lib_AddressResolver {
********************/ ********************/
/// Adds `who` to the list of witnessProviders for the provided `preStateRoot`. /// Adds `who` to the list of witnessProviders for the provided `preStateRoot`.
function recordGasSpent(bytes32 _preStateRoot, bytes32 _txHash, address who, uint256 gasSpent) override public { function recordGasSpent(bytes32 _preStateRoot, bytes32 _txHash, address who, uint256 gasSpent)
override public {
// The sender must be the transitioner that corresponds to the claimed pre-state root // The sender must be the transitioner that corresponds to the claimed pre-state root
address transitioner = address(iOVM_FraudVerifier(resolve("OVM_FraudVerifier")).getStateTransitioner(_preStateRoot, _txHash)); address transitioner =
address(iOVM_FraudVerifier(resolve("OVM_FraudVerifier"))
.getStateTransitioner(_preStateRoot, _txHash));
require(transitioner == msg.sender, Errors.ONLY_TRANSITIONER); require(transitioner == msg.sender, Errors.ONLY_TRANSITIONER);
witnessProviders[_preStateRoot].total += gasSpent; witnessProviders[_preStateRoot].total += gasSpent;
......
...@@ -9,10 +9,12 @@ import { Lib_AddressResolver } from "../../libraries/resolver/Lib_AddressResolve ...@@ -9,10 +9,12 @@ import { Lib_AddressResolver } from "../../libraries/resolver/Lib_AddressResolve
/* Interface Imports */ /* Interface Imports */
import { iOVM_FraudVerifier } from "../../iOVM/verification/iOVM_FraudVerifier.sol"; import { iOVM_FraudVerifier } from "../../iOVM/verification/iOVM_FraudVerifier.sol";
import { iOVM_StateTransitioner } from "../../iOVM/verification/iOVM_StateTransitioner.sol"; import { iOVM_StateTransitioner } from "../../iOVM/verification/iOVM_StateTransitioner.sol";
import { iOVM_StateTransitionerFactory } from "../../iOVM/verification/iOVM_StateTransitionerFactory.sol"; import { iOVM_StateTransitionerFactory } from
"../../iOVM/verification/iOVM_StateTransitionerFactory.sol";
import { iOVM_BondManager } from "../../iOVM/verification/iOVM_BondManager.sol"; import { iOVM_BondManager } from "../../iOVM/verification/iOVM_BondManager.sol";
import { iOVM_StateCommitmentChain } from "../../iOVM/chain/iOVM_StateCommitmentChain.sol"; import { iOVM_StateCommitmentChain } from "../../iOVM/chain/iOVM_StateCommitmentChain.sol";
import { iOVM_CanonicalTransactionChain } from "../../iOVM/chain/iOVM_CanonicalTransactionChain.sol"; import { iOVM_CanonicalTransactionChain } from
"../../iOVM/chain/iOVM_CanonicalTransactionChain.sol";
/* Contract Imports */ /* Contract Imports */
import { Abs_FraudContributor } from "./Abs_FraudContributor.sol"; import { Abs_FraudContributor } from "./Abs_FraudContributor.sol";
...@@ -108,8 +110,10 @@ contract OVM_FraudVerifier is Lib_AddressResolver, Abs_FraudContributor, iOVM_Fr ...@@ -108,8 +110,10 @@ contract OVM_FraudVerifier is Lib_AddressResolver, Abs_FraudContributor, iOVM_Fr
return; return;
} }
iOVM_StateCommitmentChain ovmStateCommitmentChain = iOVM_StateCommitmentChain(resolve("OVM_StateCommitmentChain")); iOVM_StateCommitmentChain ovmStateCommitmentChain =
iOVM_CanonicalTransactionChain ovmCanonicalTransactionChain = iOVM_CanonicalTransactionChain(resolve("OVM_CanonicalTransactionChain")); iOVM_StateCommitmentChain(resolve("OVM_StateCommitmentChain"));
iOVM_CanonicalTransactionChain ovmCanonicalTransactionChain =
iOVM_CanonicalTransactionChain(resolve("OVM_CanonicalTransactionChain"));
require( require(
ovmStateCommitmentChain.verifyStateCommitment( ovmStateCommitmentChain.verifyStateCommitment(
...@@ -131,6 +135,7 @@ contract OVM_FraudVerifier is Lib_AddressResolver, Abs_FraudContributor, iOVM_Fr ...@@ -131,6 +135,7 @@ contract OVM_FraudVerifier is Lib_AddressResolver, Abs_FraudContributor, iOVM_Fr
); );
require ( require (
// solhint-disable-next-line max-line-length
_preStateRootBatchHeader.prevTotalElements + _preStateRootProof.index + 1 == _transactionBatchHeader.prevTotalElements + _transactionProof.index, _preStateRootBatchHeader.prevTotalElements + _preStateRootProof.index + 1 == _transactionBatchHeader.prevTotalElements + _transactionProof.index,
"Pre-state root global index must equal to the transaction root global index." "Pre-state root global index must equal to the transaction root global index."
); );
...@@ -169,7 +174,8 @@ contract OVM_FraudVerifier is Lib_AddressResolver, Abs_FraudContributor, iOVM_Fr ...@@ -169,7 +174,8 @@ contract OVM_FraudVerifier is Lib_AddressResolver, Abs_FraudContributor, iOVM_Fr
contributesToFraudProof(_preStateRoot, _txHash) contributesToFraudProof(_preStateRoot, _txHash)
{ {
iOVM_StateTransitioner transitioner = getStateTransitioner(_preStateRoot, _txHash); iOVM_StateTransitioner transitioner = getStateTransitioner(_preStateRoot, _txHash);
iOVM_StateCommitmentChain ovmStateCommitmentChain = iOVM_StateCommitmentChain(resolve("OVM_StateCommitmentChain")); iOVM_StateCommitmentChain ovmStateCommitmentChain =
iOVM_StateCommitmentChain(resolve("OVM_StateCommitmentChain"));
require( require(
transitioner.isComplete() == true, transitioner.isComplete() == true,
...@@ -177,6 +183,7 @@ contract OVM_FraudVerifier is Lib_AddressResolver, Abs_FraudContributor, iOVM_Fr ...@@ -177,6 +183,7 @@ contract OVM_FraudVerifier is Lib_AddressResolver, Abs_FraudContributor, iOVM_Fr
); );
require ( require (
// solhint-disable-next-line max-line-length
_postStateRootBatchHeader.prevTotalElements + _postStateRootProof.index == _preStateRootBatchHeader.prevTotalElements + _preStateRootProof.index + 1, _postStateRootBatchHeader.prevTotalElements + _postStateRootProof.index == _preStateRootBatchHeader.prevTotalElements + _preStateRootProof.index + 1,
"Post-state root global index must equal to the pre state root global index plus one." "Post-state root global index must equal to the pre state root global index plus one."
); );
...@@ -208,7 +215,8 @@ contract OVM_FraudVerifier is Lib_AddressResolver, Abs_FraudContributor, iOVM_Fr ...@@ -208,7 +215,8 @@ contract OVM_FraudVerifier is Lib_AddressResolver, Abs_FraudContributor, iOVM_Fr
_cancelStateTransition(_postStateRootBatchHeader, _preStateRoot); _cancelStateTransition(_postStateRootBatchHeader, _preStateRoot);
// TEMPORARY: Remove the transitioner; for minnet. // TEMPORARY: Remove the transitioner; for minnet.
transitioners[keccak256(abi.encodePacked(_preStateRoot, _txHash))] = iOVM_StateTransitioner(0x0000000000000000000000000000000000000000); transitioners[keccak256(abi.encodePacked(_preStateRoot, _txHash))] =
iOVM_StateTransitioner(0x0000000000000000000000000000000000000000);
emit FraudProofFinalized( emit FraudProofFinalized(
_preStateRoot, _preStateRoot,
...@@ -254,14 +262,15 @@ contract OVM_FraudVerifier is Lib_AddressResolver, Abs_FraudContributor, iOVM_Fr ...@@ -254,14 +262,15 @@ contract OVM_FraudVerifier is Lib_AddressResolver, Abs_FraudContributor, iOVM_Fr
) )
internal internal
{ {
transitioners[keccak256(abi.encodePacked(_preStateRoot, _txHash))] = iOVM_StateTransitionerFactory( transitioners[keccak256(abi.encodePacked(_preStateRoot, _txHash))] =
resolve("OVM_StateTransitionerFactory") iOVM_StateTransitionerFactory(
).create( resolve("OVM_StateTransitionerFactory")
address(libAddressManager), ).create(
_stateTransitionIndex, address(libAddressManager),
_preStateRoot, _stateTransitionIndex,
_txHash _preStateRoot,
); _txHash
);
} }
/** /**
...@@ -275,7 +284,8 @@ contract OVM_FraudVerifier is Lib_AddressResolver, Abs_FraudContributor, iOVM_Fr ...@@ -275,7 +284,8 @@ contract OVM_FraudVerifier is Lib_AddressResolver, Abs_FraudContributor, iOVM_Fr
) )
internal internal
{ {
iOVM_StateCommitmentChain ovmStateCommitmentChain = iOVM_StateCommitmentChain(resolve("OVM_StateCommitmentChain")); iOVM_StateCommitmentChain ovmStateCommitmentChain =
iOVM_StateCommitmentChain(resolve("OVM_StateCommitmentChain"));
iOVM_BondManager ovmBondManager = iOVM_BondManager(resolve("OVM_BondManager")); iOVM_BondManager ovmBondManager = iOVM_BondManager(resolve("OVM_BondManager"));
// Delete the state batch. // Delete the state batch.
...@@ -284,7 +294,8 @@ contract OVM_FraudVerifier is Lib_AddressResolver, Abs_FraudContributor, iOVM_Fr ...@@ -284,7 +294,8 @@ contract OVM_FraudVerifier is Lib_AddressResolver, Abs_FraudContributor, iOVM_Fr
); );
// Get the timestamp and publisher for that block. // Get the timestamp and publisher for that block.
(uint256 timestamp, address publisher) = abi.decode(_postStateRootBatchHeader.extraData, (uint256, address)); (uint256 timestamp, address publisher) =
abi.decode(_postStateRootBatchHeader.extraData, (uint256, address));
// Slash the bonds at the bond manager. // Slash the bonds at the bond manager.
ovmBondManager.finalize( ovmBondManager.finalize(
......
...@@ -25,19 +25,20 @@ import { Abs_FraudContributor } from "./Abs_FraudContributor.sol"; ...@@ -25,19 +25,20 @@ import { Abs_FraudContributor } from "./Abs_FraudContributor.sol";
/** /**
* @title OVM_StateTransitioner * @title OVM_StateTransitioner
* @dev The State Transitioner coordinates the execution of a state transition during the evaluation of a * @dev The State Transitioner coordinates the execution of a state transition during the evaluation
* fraud proof. It feeds verified input to the Execution Manager's run(), and controls a State Manager (which is * of a fraud proof. It feeds verified input to the Execution Manager's run(), and controls a
* uniquely created for each fraud proof). * State Manager (which is uniquely created for each fraud proof).
* Once a fraud proof has been initialized, this contract is provided with the pre-state root and verifies * Once a fraud proof has been initialized, this contract is provided with the pre-state root and
* that the OVM storage slots committed to the State Mangager are contained in that state * verifies that the OVM storage slots committed to the State Mangager are contained in that state
* This contract controls the State Manager and Execution Manager, and uses them to calculate the * This contract controls the State Manager and Execution Manager, and uses them to calculate the
* post-state root by applying the transaction. The Fraud Verifier can then check for fraud by comparing * post-state root by applying the transaction. The Fraud Verifier can then check for fraud by
* the calculated post-state root with the proposed post-state root. * comparing the calculated post-state root with the proposed post-state root.
* *
* Compiler used: solc * Compiler used: solc
* Runtime target: EVM * Runtime target: EVM
*/ */
contract OVM_StateTransitioner is Lib_AddressResolver, Abs_FraudContributor, iOVM_StateTransitioner { contract OVM_StateTransitioner is Lib_AddressResolver, Abs_FraudContributor, iOVM_StateTransitioner
{
/******************* /*******************
* Data Structures * * Data Structures *
...@@ -72,7 +73,9 @@ contract OVM_StateTransitioner is Lib_AddressResolver, Abs_FraudContributor, iOV ...@@ -72,7 +73,9 @@ contract OVM_StateTransitioner is Lib_AddressResolver, Abs_FraudContributor, iOV
* Constants * * Constants *
*************/ *************/
// solhint-disable-next-line max-line-length
bytes32 internal constant EMPTY_ACCOUNT_CODE_HASH = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470; bytes32 internal constant EMPTY_ACCOUNT_CODE_HASH = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;
// solhint-disable-next-line max-line-length
bytes32 internal constant EMPTY_ACCOUNT_STORAGE_ROOT = 0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421; bytes32 internal constant EMPTY_ACCOUNT_STORAGE_ROOT = 0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421;
...@@ -99,7 +102,8 @@ contract OVM_StateTransitioner is Lib_AddressResolver, Abs_FraudContributor, iOV ...@@ -99,7 +102,8 @@ contract OVM_StateTransitioner is Lib_AddressResolver, Abs_FraudContributor, iOV
postStateRoot = _preStateRoot; postStateRoot = _preStateRoot;
transactionHash = _transactionHash; transactionHash = _transactionHash;
ovmStateManager = iOVM_StateManagerFactory(resolve("OVM_StateManagerFactory")).create(address(this)); ovmStateManager = iOVM_StateManagerFactory(resolve("OVM_StateManagerFactory"))
.create(address(this));
} }
...@@ -227,6 +231,7 @@ contract OVM_StateTransitioner is Lib_AddressResolver, Abs_FraudContributor, iOV ...@@ -227,6 +231,7 @@ contract OVM_StateTransitioner is Lib_AddressResolver, Abs_FraudContributor, iOV
// of the code stored on L2. // of the code stored on L2.
require( require(
Lib_EthUtils.getCodeHash(ethContractAddress) == account.codeHash, Lib_EthUtils.getCodeHash(ethContractAddress) == account.codeHash,
// solhint-disable-next-line max-line-length
"OVM_StateTransitioner: Provided L1 contract code hash does not match L2 contract code hash." "OVM_StateTransitioner: Provided L1 contract code hash does not match L2 contract code hash."
); );
} }
...@@ -338,11 +343,13 @@ contract OVM_StateTransitioner is Lib_AddressResolver, Abs_FraudContributor, iOV ...@@ -338,11 +343,13 @@ contract OVM_StateTransitioner is Lib_AddressResolver, Abs_FraudContributor, iOV
// This includes 1/64 of the gas getting lost because of EIP-150 (lost twice--first // This includes 1/64 of the gas getting lost because of EIP-150 (lost twice--first
// going into EM, then going into the code contract). // going into EM, then going into the code contract).
require( require(
gasleft() >= 100000 + _transaction.gasLimit * 1032 / 1000, // 1032/1000 = 1.032 = (64/63)^2 rounded up // 1032/1000 = 1.032 = (64/63)^2 rounded up
gasleft() >= 100000 + _transaction.gasLimit * 1032 / 1000,
"Not enough gas to execute transaction deterministically." "Not enough gas to execute transaction deterministically."
); );
iOVM_ExecutionManager ovmExecutionManager = iOVM_ExecutionManager(resolve("OVM_ExecutionManager")); iOVM_ExecutionManager ovmExecutionManager =
iOVM_ExecutionManager(resolve("OVM_ExecutionManager"));
// We call `setExecutionManager` right before `run` (and not earlier) just in case the // We call `setExecutionManager` right before `run` (and not earlier) just in case the
// OVM_ExecutionManager address was updated between the time when this contract was created // OVM_ExecutionManager address was updated between the time when this contract was created
......
...@@ -7,7 +7,8 @@ import { Lib_AddressResolver } from "../../libraries/resolver/Lib_AddressResolve ...@@ -7,7 +7,8 @@ import { Lib_AddressResolver } from "../../libraries/resolver/Lib_AddressResolve
/* Interface Imports */ /* Interface Imports */
import { iOVM_StateTransitioner } from "../../iOVM/verification/iOVM_StateTransitioner.sol"; import { iOVM_StateTransitioner } from "../../iOVM/verification/iOVM_StateTransitioner.sol";
import { iOVM_StateTransitionerFactory } from "../../iOVM/verification/iOVM_StateTransitionerFactory.sol"; import { iOVM_StateTransitionerFactory } from
"../../iOVM/verification/iOVM_StateTransitionerFactory.sol";
import { iOVM_FraudVerifier } from "../../iOVM/verification/iOVM_FraudVerifier.sol"; import { iOVM_FraudVerifier } from "../../iOVM/verification/iOVM_FraudVerifier.sol";
/* Contract Imports */ /* Contract Imports */
......
...@@ -3,7 +3,9 @@ pragma solidity >0.5.0 <0.8.0; ...@@ -3,7 +3,9 @@ pragma solidity >0.5.0 <0.8.0;
pragma experimental ABIEncoderV2; pragma experimental ABIEncoderV2;
/* Interface Imports */ /* Interface Imports */
import { iOVM_L1CrossDomainMessenger } from "../../../iOVM/bridge/messaging/iOVM_L1CrossDomainMessenger.sol"; import { iOVM_L1CrossDomainMessenger } from
"../../../iOVM/bridge/messaging/iOVM_L1CrossDomainMessenger.sol";
interface iOVM_L1MultiMessageRelayer { interface iOVM_L1MultiMessageRelayer {
struct L2ToL1Message { struct L2ToL1Message {
......
...@@ -29,7 +29,7 @@ interface iOVM_L1StandardBridge is iOVM_L1ERC20Bridge { ...@@ -29,7 +29,7 @@ interface iOVM_L1StandardBridge is iOVM_L1ERC20Bridge {
/******************** /********************
* Public Functions * * Public Functions *
********************/ ********************/
/** /**
* @dev Deposit an amount of the ETH to the caller's balance on L2. * @dev Deposit an amount of the ETH to the caller's balance on L2.
* @param _l2Gas Gas limit required to complete the deposit on L2. * @param _l2Gas Gas limit required to complete the deposit on L2.
...@@ -66,8 +66,8 @@ interface iOVM_L1StandardBridge is iOVM_L1ERC20Bridge { ...@@ -66,8 +66,8 @@ interface iOVM_L1StandardBridge is iOVM_L1ERC20Bridge {
/** /**
* @dev Complete a withdrawal from L2 to L1, and credit funds to the recipient's balance of the * @dev Complete a withdrawal from L2 to L1, and credit funds to the recipient's balance of the
* L1 ETH token. * L1 ETH token. Since only the xDomainMessenger can call this function, it will never be called
* Since only the xDomainMessenger can call this function, it will never be called before the withdrawal is finalized. * before the withdrawal is finalized.
* @param _from L2 address initiating the transfer. * @param _from L2 address initiating the transfer.
* @param _to L1 address to credit the withdrawal to. * @param _to L1 address to credit the withdrawal to.
* @param _amount Amount of the ERC20 to deposit. * @param _amount Amount of the ERC20 to deposit.
......
...@@ -85,8 +85,8 @@ interface iOVM_L2ERC20Bridge { ...@@ -85,8 +85,8 @@ interface iOVM_L2ERC20Bridge {
/** /**
* @dev Complete a deposit from L1 to L2, and credits funds to the recipient's balance of this * @dev Complete a deposit from L1 to L2, and credits funds to the recipient's balance of this
* L2 token. * L2 token. This call will fail if it did not originate from a corresponding deposit in
* This call will fail if it did not originate from a corresponding deposit in OVM_l1TokenGateway. * OVM_l1TokenGateway.
* @param _l1Token Address for the l1 token this is called with * @param _l1Token Address for the l1 token this is called with
* @param _l2Token Address for the l2 token this is called with * @param _l2Token Address for the l2 token this is called with
* @param _from Account to pull the deposit from on L2. * @param _from Account to pull the deposit from on L2.
......
...@@ -119,8 +119,10 @@ interface iOVM_ExecutionManager { ...@@ -119,8 +119,10 @@ interface iOVM_ExecutionManager {
* Contract Creation Opcodes * * Contract Creation Opcodes *
*****************************/ *****************************/
function ovmCREATE(bytes memory _bytecode) external returns (address _contract, bytes memory _revertdata); function ovmCREATE(bytes memory _bytecode) external
function ovmCREATE2(bytes memory _bytecode, bytes32 _salt) external returns (address _contract, bytes memory _revertdata); returns (address _contract, bytes memory _revertdata);
function ovmCREATE2(bytes memory _bytecode, bytes32 _salt) external
returns (address _contract, bytes memory _revertdata);
/******************************* /*******************************
...@@ -137,10 +139,14 @@ interface iOVM_ExecutionManager { ...@@ -137,10 +139,14 @@ interface iOVM_ExecutionManager {
****************************/ ****************************/
// Valueless ovmCALL for maintaining backwards compatibility with legacy OVM bytecode. // Valueless ovmCALL for maintaining backwards compatibility with legacy OVM bytecode.
function ovmCALL(uint256 _gasLimit, address _address, bytes memory _calldata) external returns (bool _success, bytes memory _returndata); function ovmCALL(uint256 _gasLimit, address _address, bytes memory _calldata) external
function ovmCALL(uint256 _gasLimit, address _address, uint256 _value, bytes memory _calldata) external returns (bool _success, bytes memory _returndata); returns (bool _success, bytes memory _returndata);
function ovmSTATICCALL(uint256 _gasLimit, address _address, bytes memory _calldata) external returns (bool _success, bytes memory _returndata); function ovmCALL(uint256 _gasLimit, address _address, uint256 _value, bytes memory _calldata)
function ovmDELEGATECALL(uint256 _gasLimit, address _address, bytes memory _calldata) external returns (bool _success, bytes memory _returndata); external returns (bool _success, bytes memory _returndata);
function ovmSTATICCALL(uint256 _gasLimit, address _address, bytes memory _calldata) external
returns (bool _success, bytes memory _returndata);
function ovmDELEGATECALL(uint256 _gasLimit, address _address, bytes memory _calldata) external
returns (bool _success, bytes memory _returndata);
/**************************** /****************************
...@@ -155,7 +161,8 @@ interface iOVM_ExecutionManager { ...@@ -155,7 +161,8 @@ interface iOVM_ExecutionManager {
* Contract Code Opcodes * * Contract Code Opcodes *
*************************/ *************************/
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);
......
...@@ -42,7 +42,8 @@ interface iOVM_StateManager { ...@@ -42,7 +42,8 @@ interface iOVM_StateManager {
function putAccount(address _address, Lib_OVMCodec.Account memory _account) external; function putAccount(address _address, Lib_OVMCodec.Account memory _account) external;
function putEmptyAccount(address _address) external; function putEmptyAccount(address _address) external;
function getAccount(address _address) external view returns (Lib_OVMCodec.Account memory _account); function getAccount(address _address) external view
returns (Lib_OVMCodec.Account memory _account);
function hasAccount(address _address) external view returns (bool _exists); function hasAccount(address _address) external view returns (bool _exists);
function hasEmptyAccount(address _address) external view returns (bool _exists); function hasEmptyAccount(address _address) external view returns (bool _exists);
function setAccountNonce(address _address, uint256 _nonce) external; function setAccountNonce(address _address, uint256 _nonce) external;
...@@ -50,9 +51,12 @@ interface iOVM_StateManager { ...@@ -50,9 +51,12 @@ interface iOVM_StateManager {
function getAccountEthAddress(address _address) external view returns (address _ethAddress); function getAccountEthAddress(address _address) external view returns (address _ethAddress);
function getAccountStorageRoot(address _address) external view returns (bytes32 _storageRoot); function getAccountStorageRoot(address _address) external view returns (bytes32 _storageRoot);
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)
function testAndSetAccountLoaded(address _address) external returns (bool _wasAccountAlreadyLoaded); external;
function testAndSetAccountChanged(address _address) external returns (bool _wasAccountAlreadyChanged); function testAndSetAccountLoaded(address _address) external
returns (bool _wasAccountAlreadyLoaded);
function testAndSetAccountChanged(address _address) external
returns (bool _wasAccountAlreadyChanged);
function commitAccount(address _address) external returns (bool _wasAccountCommitted); function commitAccount(address _address) external returns (bool _wasAccountCommitted);
function incrementTotalUncommittedAccounts() external; function incrementTotalUncommittedAccounts() external;
function getTotalUncommittedAccounts() external view returns (uint256 _total); function getTotalUncommittedAccounts() external view returns (uint256 _total);
...@@ -65,13 +69,20 @@ interface iOVM_StateManager { ...@@ -65,13 +69,20 @@ interface iOVM_StateManager {
************************************/ ************************************/
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 view returns (bytes32 _value); function getContractStorage(address _contract, bytes32 _key) external view
function hasContractStorage(address _contract, bytes32 _key) external view returns (bool _exists); returns (bytes32 _value);
function testAndSetContractStorageLoaded(address _contract, bytes32 _key) external returns (bool _wasContractStorageAlreadyLoaded); function hasContractStorage(address _contract, bytes32 _key) external view
function testAndSetContractStorageChanged(address _contract, bytes32 _key) external returns (bool _wasContractStorageAlreadyChanged); returns (bool _exists);
function commitContractStorage(address _contract, bytes32 _key) external returns (bool _wasContractStorageCommitted); function testAndSetContractStorageLoaded(address _contract, bytes32 _key) external
returns (bool _wasContractStorageAlreadyLoaded);
function testAndSetContractStorageChanged(address _contract, bytes32 _key) external
returns (bool _wasContractStorageAlreadyChanged);
function commitContractStorage(address _contract, bytes32 _key) external
returns (bool _wasContractStorageCommitted);
function incrementTotalUncommittedContractStorage() external; function incrementTotalUncommittedContractStorage() external;
function getTotalUncommittedContractStorage() external view returns (uint256 _total); function getTotalUncommittedContractStorage() external view returns (uint256 _total);
function wasContractStorageChanged(address _contract, bytes32 _key) external view returns (bool); function wasContractStorageChanged(address _contract, bytes32 _key) external view
function wasContractStorageCommitted(address _contract, bytes32 _key) external view returns (bool); returns (bool);
function wasContractStorageCommitted(address _contract, bytes32 _key) external view
returns (bool);
} }
...@@ -9,6 +9,7 @@ interface ERC20 { ...@@ -9,6 +9,7 @@ interface ERC20 {
/// All the errors which may be encountered on the bond manager /// All the errors which may be encountered on the bond manager
library Errors { library Errors {
string constant ERC20_ERR = "BondManager: Could not post bond"; string constant ERC20_ERR = "BondManager: Could not post bond";
// solhint-disable-next-line max-line-length
string constant ALREADY_FINALIZED = "BondManager: Fraud proof for this pre-state root has already been finalized"; string constant ALREADY_FINALIZED = "BondManager: Fraud proof for this pre-state root has already been finalized";
string constant SLASHED = "BondManager: Cannot finalize withdrawal, you probably got slashed"; string constant SLASHED = "BondManager: Cannot finalize withdrawal, you probably got slashed";
string constant WRONG_STATE = "BondManager: Wrong bond state for proposer"; string constant WRONG_STATE = "BondManager: Wrong bond state for proposer";
...@@ -16,9 +17,11 @@ library Errors { ...@@ -16,9 +17,11 @@ library Errors {
string constant WITHDRAWAL_PENDING = "BondManager: Withdrawal already pending"; string constant WITHDRAWAL_PENDING = "BondManager: Withdrawal already pending";
string constant TOO_EARLY = "BondManager: Too early to finalize your withdrawal"; string constant TOO_EARLY = "BondManager: Too early to finalize your withdrawal";
// solhint-disable-next-line max-line-length
string constant ONLY_TRANSITIONER = "BondManager: Only the transitioner for this pre-state root may call this function"; string constant ONLY_TRANSITIONER = "BondManager: Only the transitioner for this pre-state root may call this function";
// solhint-disable-next-line max-line-length
string constant ONLY_FRAUD_VERIFIER = "BondManager: Only the fraud verifier may call this function"; string constant ONLY_FRAUD_VERIFIER = "BondManager: Only the fraud verifier may call this function";
// solhint-disable-next-line max-line-length
string constant ONLY_STATE_COMMITMENT_CHAIN = "BondManager: Only the state commitment chain may call this function"; string constant ONLY_STATE_COMMITMENT_CHAIN = "BondManager: Only the state commitment chain may call this function";
string constant WAIT_FOR_DISPUTES = "BondManager: Wait for other potential disputes"; string constant WAIT_FOR_DISPUTES = "BondManager: Wait for other potential disputes";
} }
......
...@@ -36,7 +36,8 @@ interface iOVM_FraudVerifier { ...@@ -36,7 +36,8 @@ interface iOVM_FraudVerifier {
* Public Functions: Transition Status * * Public Functions: Transition Status *
***************************************/ ***************************************/
function getStateTransitioner(bytes32 _preStateRoot, bytes32 _txHash) external view returns (iOVM_StateTransitioner _transitioner); function getStateTransitioner(bytes32 _preStateRoot, bytes32 _txHash) external view
returns (iOVM_StateTransitioner _transitioner);
/**************************************** /****************************************
......
...@@ -2,7 +2,8 @@ ...@@ -2,7 +2,8 @@
pragma solidity >0.5.0 <0.8.0; pragma solidity >0.5.0 <0.8.0;
/* Interface Imports */ /* Interface Imports */
import { iOVM_CrossDomainMessenger } from "../../iOVM/bridge/messaging/iOVM_CrossDomainMessenger.sol"; import { iOVM_CrossDomainMessenger } from
"../../iOVM/bridge/messaging/iOVM_CrossDomainMessenger.sol";
/** /**
* @title OVM_CrossDomainEnabled * @title OVM_CrossDomainEnabled
......
...@@ -11,9 +11,11 @@ library Lib_PredeployAddresses { ...@@ -11,9 +11,11 @@ library Lib_PredeployAddresses {
address internal constant ECDSA_CONTRACT_ACCOUNT = 0x4200000000000000000000000000000000000003; address internal constant ECDSA_CONTRACT_ACCOUNT = 0x4200000000000000000000000000000000000003;
address internal constant SEQUENCER_ENTRYPOINT = 0x4200000000000000000000000000000000000005; address internal constant SEQUENCER_ENTRYPOINT = 0x4200000000000000000000000000000000000005;
address payable internal constant OVM_ETH = 0x4200000000000000000000000000000000000006; address payable internal constant OVM_ETH = 0x4200000000000000000000000000000000000006;
// solhint-disable-next-line max-line-length
address internal constant L2_CROSS_DOMAIN_MESSENGER = 0x4200000000000000000000000000000000000007; address internal constant L2_CROSS_DOMAIN_MESSENGER = 0x4200000000000000000000000000000000000007;
address internal constant LIB_ADDRESS_MANAGER = 0x4200000000000000000000000000000000000008; address internal constant LIB_ADDRESS_MANAGER = 0x4200000000000000000000000000000000000008;
address internal constant PROXY_EOA = 0x4200000000000000000000000000000000000009; address internal constant PROXY_EOA = 0x4200000000000000000000000000000000000009;
// solhint-disable-next-line max-line-length
address internal constant EXECUTION_MANAGER_WRAPPER = 0x420000000000000000000000000000000000000B; address internal constant EXECUTION_MANAGER_WRAPPER = 0x420000000000000000000000000000000000000B;
address internal constant SEQUENCER_FEE_WALLET = 0x4200000000000000000000000000000000000011; address internal constant SEQUENCER_FEE_WALLET = 0x4200000000000000000000000000000000000011;
address internal constant ERC1820_REGISTRY = 0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24; address internal constant ERC1820_REGISTRY = 0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24;
......
...@@ -2,7 +2,8 @@ ...@@ -2,7 +2,8 @@
pragma solidity =0.7.6; pragma solidity =0.7.6;
import '@openzeppelin/contracts/token/ERC20/IERC20.sol'; import '@openzeppelin/contracts/token/ERC20/IERC20.sol';
/// @title Interface for WETH9. Also contains the non-ERC20 events normally present in the WETH9 implementation. /// @title Interface for WETH9. Also contains the non-ERC20 events
/// normally present in the WETH9 implementation.
interface IWETH9 is IERC20 { interface IWETH9 is IERC20 {
event Deposit(address indexed dst, uint256 wad); event Deposit(address indexed dst, uint256 wad);
event Withdrawal(address indexed src, uint256 wad); event Withdrawal(address indexed src, uint256 wad);
......
...@@ -148,7 +148,8 @@ library Lib_MerkleTrie { ...@@ -148,7 +148,8 @@ library Lib_MerkleTrie {
) )
{ {
TrieNode[] memory proof = _parseProof(_proof); TrieNode[] memory proof = _parseProof(_proof);
(uint256 pathLength, bytes memory keyRemainder, bool isFinalNode) = _walkNodePath(proof, _key, _root); (uint256 pathLength, bytes memory keyRemainder, bool isFinalNode) =
_walkNodePath(proof, _key, _root);
bool exists = keyRemainder.length == 0; bool exists = keyRemainder.length == 0;
...@@ -253,7 +254,8 @@ library Lib_MerkleTrie { ...@@ -253,7 +254,8 @@ library Lib_MerkleTrie {
if (currentNode.decoded.length == BRANCH_NODE_LENGTH) { if (currentNode.decoded.length == BRANCH_NODE_LENGTH) {
if (currentKeyIndex == key.length) { if (currentKeyIndex == key.length) {
// We've hit the end of the key, meaning the value should be within this branch node. // We've hit the end of the key
// meaning the value should be within this branch node.
break; break;
} else { } else {
// We're not at the end of the key yet. // We're not at the end of the key yet.
...@@ -288,7 +290,8 @@ library Lib_MerkleTrie { ...@@ -288,7 +290,8 @@ library Lib_MerkleTrie {
} else if (prefix == PREFIX_EXTENSION_EVEN || prefix == PREFIX_EXTENSION_ODD) { } else if (prefix == PREFIX_EXTENSION_EVEN || prefix == PREFIX_EXTENSION_ODD) {
if (sharedNibbleLength != pathRemainder.length) { if (sharedNibbleLength != pathRemainder.length) {
// Our extension node is not identical to the remainder. // Our extension node is not identical to the remainder.
// We've hit the end of this path, updates will need to modify this extension. // We've hit the end of this path
// updates will need to modify this extension.
currentNodeID = bytes32(RLP_NULL); currentNodeID = bytes32(RLP_NULL);
break; break;
} else { } else {
...@@ -348,6 +351,7 @@ library Lib_MerkleTrie { ...@@ -348,6 +351,7 @@ library Lib_MerkleTrie {
TrieNode[] memory newNodes = new TrieNode[](3); TrieNode[] memory newNodes = new TrieNode[](3);
uint256 totalNewNodes = 0; uint256 totalNewNodes = 0;
// solhint-disable-next-line max-line-length
// Reference: https://github.com/ethereumjs/merkle-patricia-tree/blob/c0a10395aab37d42c175a47114ebfcbd7efcf059/src/baseTrie.ts#L294-L313 // Reference: https://github.com/ethereumjs/merkle-patricia-tree/blob/c0a10395aab37d42c175a47114ebfcbd7efcf059/src/baseTrie.ts#L294-L313
bool matchLeaf = false; bool matchLeaf = false;
if (lastNodeType == NodeType.LeafNode) { if (lastNodeType == NodeType.LeafNode) {
...@@ -391,7 +395,8 @@ library Lib_MerkleTrie { ...@@ -391,7 +395,8 @@ library Lib_MerkleTrie {
totalNewNodes += 1; totalNewNodes += 1;
// Create a new leaf node, slicing our remainder since the first byte points // Create a new leaf node, slicing our remainder since the first byte points
// to our branch node. // to our branch node.
newNodes[totalNewNodes] = _makeLeafNode(Lib_BytesUtils.slice(keyRemainder, 1), _value); newNodes[totalNewNodes] =
_makeLeafNode(Lib_BytesUtils.slice(keyRemainder, 1), _value);
totalNewNodes += 1; totalNewNodes += 1;
} }
} else { } else {
...@@ -429,13 +434,23 @@ library Lib_MerkleTrie { ...@@ -429,13 +434,23 @@ library Lib_MerkleTrie {
if (lastNodeType == NodeType.LeafNode) { if (lastNodeType == NodeType.LeafNode) {
// We're dealing with a leaf node. // We're dealing with a leaf node.
// We'll modify the key and insert the old leaf node into the branch index. // We'll modify the key and insert the old leaf node into the branch index.
TrieNode memory modifiedLastNode = _makeLeafNode(lastNodeKey, _getNodeValue(lastNode)); TrieNode memory modifiedLastNode =
newBranch = _editBranchIndex(newBranch, branchKey, _getNodeHash(modifiedLastNode.encoded)); _makeLeafNode(lastNodeKey, _getNodeValue(lastNode));
newBranch =
_editBranchIndex(
newBranch,
branchKey,
_getNodeHash(modifiedLastNode.encoded));
} else if (lastNodeKey.length != 0) { } else if (lastNodeKey.length != 0) {
// We're dealing with a shrinking extension node. // We're dealing with a shrinking extension node.
// We need to modify the node to decrease the size of the key. // We need to modify the node to decrease the size of the key.
TrieNode memory modifiedLastNode = _makeExtensionNode(lastNodeKey, _getNodeValue(lastNode)); TrieNode memory modifiedLastNode =
newBranch = _editBranchIndex(newBranch, branchKey, _getNodeHash(modifiedLastNode.encoded)); _makeExtensionNode(lastNodeKey, _getNodeValue(lastNode));
newBranch =
_editBranchIndex(
newBranch,
branchKey,
_getNodeHash(modifiedLastNode.encoded));
} else { } else {
// We're dealing with an unnecessary extension node. // We're dealing with an unnecessary extension node.
// We're going to delete the node entirely. // We're going to delete the node entirely.
......
...@@ -246,7 +246,9 @@ library Lib_Buffer { ...@@ -246,7 +246,9 @@ library Lib_Buffer {
uint40 length; uint40 length;
bytes27 extraData; bytes27 extraData;
assembly { assembly {
// solhint-disable-next-line max-line-length
length := and(context, 0x000000000000000000000000000000000000000000000000000000FFFFFFFFFF) length := and(context, 0x000000000000000000000000000000000000000000000000000000FFFFFFFFFF)
// solhint-disable-next-line max-line-length
extraData := and(context, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000000000) extraData := and(context, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000000000)
} }
......
...@@ -14,7 +14,8 @@ library Lib_ErrorUtils { ...@@ -14,7 +14,8 @@ library Lib_ErrorUtils {
/** /**
* Encodes an error string into raw solidity-style revert data. * Encodes an error string into raw solidity-style revert data.
* (i.e. ascii bytes, prefixed with bytes4(keccak("Error(string))")) * (i.e. ascii bytes, prefixed with bytes4(keccak("Error(string))"))
* Ref: https://docs.soliditylang.org/en/v0.8.2/control-structures.html?highlight=Error(string)#panic-via-assert-and-error-via-require * Ref: https://docs.soliditylang.org/en/v0.8.2/control-structures.html?highlight=Error(string)
* #panic-via-assert-and-error-via-require
* @param _reason Reason for the reversion. * @param _reason Reason for the reversion.
* @return Standard solidity revert data for the given reason. * @return Standard solidity revert data for the given reason.
*/ */
......
...@@ -14,8 +14,8 @@ library Lib_MerkleTree { ...@@ -14,8 +14,8 @@ library Lib_MerkleTree {
/** /**
* Calculates a merkle root for a list of 32-byte leaf hashes. WARNING: If the number * Calculates a merkle root for a list of 32-byte leaf hashes. WARNING: If the number
* of leaves passed in is not a power of two, it pads out the tree with zero hashes. * of leaves passed in is not a power of two, it pads out the tree with zero hashes.
* If you do not know the original length of elements for the tree you are verifying, * If you do not know the original length of elements for the tree you are verifying, then
* then this may allow empty leaves past _elements.length to pass a verification check down the line. * this may allow empty leaves past _elements.length to pass a verification check down the line.
* Note that the _elements argument is modified, therefore it must not be used again afterwards * Note that the _elements argument is modified, therefore it must not be used again afterwards
* @param _elements Array of hashes from which to generate a merkle root. * @param _elements Array of hashes from which to generate a merkle root.
* @return Merkle root of the leaves, with zero hashes for non-powers-of-two (see above). * @return Merkle root of the leaves, with zero hashes for non-powers-of-two (see above).
...@@ -114,7 +114,8 @@ library Lib_MerkleTree { ...@@ -114,7 +114,8 @@ library Lib_MerkleTree {
* @param _root The Merkle root to verify against. * @param _root The Merkle root to verify against.
* @param _leaf The leaf hash to verify inclusion of. * @param _leaf The leaf hash to verify inclusion of.
* @param _index The index in the tree of this leaf. * @param _index The index in the tree of this leaf.
* @param _siblings Array of sibline nodes in the inclusion proof, starting from depth 0 (bottom of the tree). * @param _siblings Array of sibline nodes in the inclusion proof, starting from depth 0
* (bottom of the tree).
* @param _totalLeaves The total number of leaves originally passed into. * @param _totalLeaves The total number of leaves originally passed into.
* @return Whether or not the merkle branch and leaf passes verification. * @return Whether or not the merkle branch and leaf passes verification.
*/ */
......
...@@ -253,7 +253,8 @@ library Lib_ExecutionManagerWrapper { ...@@ -253,7 +253,8 @@ library Lib_ExecutionManagerWrapper {
bytes memory bytes memory
) )
{ {
(bool success, bytes memory returndata) = Lib_PredeployAddresses.EXECUTION_MANAGER_WRAPPER.delegatecall(_calldata); (bool success, bytes memory returndata) =
Lib_PredeployAddresses.EXECUTION_MANAGER_WRAPPER.delegatecall(_calldata);
if (success == true) { if (success == true) {
return returndata; return returndata;
......
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