Commit 886a1507 authored by Elena Gesheva's avatar Elena Gesheva Committed by GitHub

Merge pull request #1033 from...

Merge pull request #1033 from ethereum-optimism/elena/op-790-add-linting-andor-formatting-to-solidity

Add contracts linting
parents db4611a7 e67551c3
...@@ -134,5 +134,9 @@ jobs: ...@@ -134,5 +134,9 @@ jobs:
# if: steps.yarn-cache.outputs.cache-hit != 'true' # if: steps.yarn-cache.outputs.cache-hit != 'true'
run: yarn install run: yarn install
- name: Lint - name: Lint JS and TS
run: yarn lint:check run: yarn lint:check
- name: Lint Solidity
working-directory: ./packages/contracts
run: yarn lint:contracts
...@@ -6,7 +6,7 @@ export const FORCE_INCLUSION_PERIOD_SECONDS = 600 ...@@ -6,7 +6,7 @@ export const FORCE_INCLUSION_PERIOD_SECONDS = 600
export const DEFAULT_ACCOUNTS = defaultAccounts export const DEFAULT_ACCOUNTS = defaultAccounts
export const DEFAULT_ACCOUNTS_HARDHAT = defaultAccounts.map((account) => { export const DEFAULT_ACCOUNTS_HARDHAT = defaultAccounts.map((account) => {
return { return {
balance: ethers.BigNumber.from(account.balance).toHexString(), balance: account.balance,
privateKey: account.secretKey, privateKey: account.secretKey,
} }
}) })
......
{
"extends": "solhint:recommended",
"plugins": [],
"rules": {
"compiler-version": "off",
"code-complexity": ["warn", 5],
"max-line-length": ["error", 100],
"func-param-name-mixedcase": "error",
"modifier-name-mixedcase": "error",
"ordering": "warn",
"not-rely-on-time": "off",
"no-complex-fallback": "off",
"not-rely-on-block-hash": "off",
"reentrancy": "off",
"contract-name-camelcase": "off"
}
}
...@@ -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,12 @@ contract OVM_L1CrossDomainMessenger is ...@@ -204,7 +210,12 @@ 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 +309,8 @@ contract OVM_L1CrossDomainMessenger is ...@@ -298,7 +309,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 +335,12 @@ contract OVM_L1CrossDomainMessenger is ...@@ -323,7 +335,12 @@ 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,6 +44,7 @@ contract OVM_L1MultiMessageRelayer is iOVM_L1MultiMessageRelayer, Lib_AddressRes ...@@ -42,6 +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"),
// solhint-disable-next-line max-line-length
"OVM_L1MultiMessageRelayer: Function can only be called by the OVM_L2BatchMessageRelayer" "OVM_L1MultiMessageRelayer: Function can only be called by the OVM_L2BatchMessageRelayer"
); );
_; _;
...@@ -58,7 +61,7 @@ contract OVM_L1MultiMessageRelayer is iOVM_L1MultiMessageRelayer, Lib_AddressRes ...@@ -58,7 +61,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,9 @@ contract OVM_L1StandardBridge is iOVM_L1StandardBridge, OVM_CrossDomainEnabled { ...@@ -69,7 +70,9 @@ 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 +139,8 @@ contract OVM_L1StandardBridge is iOVM_L1StandardBridge, OVM_CrossDomainEnabled { ...@@ -136,7 +139,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 +239,9 @@ contract OVM_L1StandardBridge is iOVM_L1StandardBridge, OVM_CrossDomainEnabled { ...@@ -235,8 +239,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),
...@@ -284,7 +289,7 @@ contract OVM_L1StandardBridge is iOVM_L1StandardBridge, OVM_CrossDomainEnabled { ...@@ -284,7 +289,7 @@ contract OVM_L1StandardBridge is iOVM_L1StandardBridge, OVM_CrossDomainEnabled {
onlyFromCrossDomainAccount(l2TokenBridge) onlyFromCrossDomainAccount(l2TokenBridge)
{ {
(bool success, ) = _to.call{value: _amount}(new bytes(0)); (bool success, ) = _to.call{value: _amount}(new bytes(0));
require(success, 'TransferHelper::safeTransferETH: ETH transfer failed'); require(success, "TransferHelper::safeTransferETH: ETH transfer failed");
emit ETHWithdrawalFinalized(_from, _to, _amount, _data); emit ETHWithdrawalFinalized(_from, _to, _amount, _data);
} }
...@@ -306,7 +311,7 @@ contract OVM_L1StandardBridge is iOVM_L1StandardBridge, OVM_CrossDomainEnabled { ...@@ -306,7 +311,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 +324,8 @@ contract OVM_L1StandardBridge is iOVM_L1StandardBridge, OVM_CrossDomainEnabled { ...@@ -319,7 +324,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 {
......
...@@ -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,12 +10,13 @@ import { Lib_MerkleTree } from "../../libraries/utils/Lib_MerkleTree.sol"; ...@@ -10,12 +10,13 @@ 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";
/* External Imports */ /* External Imports */
import '@openzeppelin/contracts/math/SafeMath.sol'; import "@openzeppelin/contracts/math/SafeMath.sol";
/** /**
* @title OVM_StateCommitmentChain * @title OVM_StateCommitmentChain
...@@ -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,
......
...@@ -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-enable 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)]
...@@ -96,11 +100,12 @@ contract OVM_SafetyChecker is iOVM_SafetyChecker { ...@@ -96,11 +100,12 @@ contract OVM_SafetyChecker is iOVM_SafetyChecker {
if (opBit & opcodePushMask == 0) { if (opBit & opcodePushMask == 0) {
// all pushes are valid opcodes // all pushes are valid opcodes
// subsequent bytes are not opcodes. Skip them. // subsequent bytes are not opcodes. Skip them.
_pc += (opNum - 0x5e); // PUSH1 is 0x60, so opNum-0x5f = PUSHed bytes and we +1 to _pc += (opNum - 0x5e); // PUSH1 is 0x60, so opNum-0x5f = PUSHed bytes and we
// skip the _pc++; line below in order to save gas ((-0x5f + 1) = -0x5e) // +1 to skip the _pc++; line below in order to save gas ((-0x5f + 1) = -0x5e)
continue; continue;
} else if (opBit & opcodeHaltingMask == 0) { } else if (opBit & opcodeHaltingMask == 0) {
// STOP or JUMP or RETURN or INVALID (Note: REVERT is blacklisted, so not included here) // STOP or JUMP or RETURN or INVALID (Note: REVERT is blacklisted, so not
// included here)
// We are now inside unreachable code until we hit a JUMPDEST! // We are now inside unreachable code until we hit a JUMPDEST!
do { do {
_pc++; _pc++;
...@@ -110,7 +115,8 @@ contract OVM_SafetyChecker is iOVM_SafetyChecker { ...@@ -110,7 +115,8 @@ contract OVM_SafetyChecker is iOVM_SafetyChecker {
// encountered a JUMPDEST // encountered a JUMPDEST
if (opNum == 0x5b) break; if (opNum == 0x5b) break;
// skip PUSHed bytes // skip PUSHed bytes
if ((1 << opNum) & opcodePushMask == 0) _pc += (opNum - 0x5f); // opNum-0x5f = PUSHed bytes (PUSH1 is 0x60) // opNum-0x5f = PUSHed bytes (PUSH1 is 0x60)
if ((1 << opNum) & opcodePushMask == 0) _pc += (opNum - 0x5f);
} while (_pc < codeLength); } while (_pc < codeLength);
// opNum is 0x5b, so we don't continue here since the pc++ is fine // opNum is 0x5b, so we don't continue here since the pc++ is fine
} else if (opNum == 0x33) { // Caller opcode } else if (opNum == 0x33) { // Caller opcode
...@@ -129,7 +135,11 @@ contract OVM_SafetyChecker is iOVM_SafetyChecker { ...@@ -129,7 +135,11 @@ contract OVM_SafetyChecker is iOVM_SafetyChecker {
if ((firstOps >> 192) == 0x3350600060045af1) { if ((firstOps >> 192) == 0x3350600060045af1) {
_pc += 8; _pc += 8;
// Call EM and abort execution if instructed // Call EM and abort execution if instructed
// CALLER PUSH1 0x00 SWAP1 GAS CALL PC PUSH1 0x0E ADD JUMPI RETURNDATASIZE PUSH1 0x00 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x00 REVERT JUMPDEST RETURNDATASIZE PUSH1 0x01 EQ ISZERO PC PUSH1 0x0a ADD JUMPI PUSH1 0x01 PUSH1 0x00 RETURN JUMPDEST // CALLER PUSH1 0x00 SWAP1 GAS CALL PC PUSH1 0x0E ADD JUMPI RETURNDATASIZE
// PUSH1 0x00 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x00 REVERT JUMPDEST
// RETURNDATASIZE PUSH1 0x01 EQ ISZERO PC PUSH1 0x0a ADD JUMPI PUSH1 0x01 PUSH1
// 0x00 RETURN JUMPDEST
// solhint-disable-next-line max-line-length
} else if (firstOps == 0x336000905af158600e01573d6000803e3d6000fd5b3d6001141558600a015760 && secondOps == 0x016000f35b) { } else if (firstOps == 0x336000905af158600e01573d6000803e3d6000fd5b3d6001141558600a015760 && secondOps == 0x016000f35b) {
_pc += 37; _pc += 37;
} else { } else {
......
...@@ -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() {
......
...@@ -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 {
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
pragma solidity >0.5.0; pragma solidity >0.5.0;
pragma experimental ABIEncoderV2; pragma experimental ABIEncoderV2;
import './iOVM_L1ERC20Bridge.sol'; import "./iOVM_L1ERC20Bridge.sol";
/** /**
* @title iOVM_L1StandardBridge * @title iOVM_L1StandardBridge
...@@ -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
......
...@@ -138,7 +138,7 @@ library Lib_EIP155Tx { ...@@ -138,7 +138,7 @@ library Lib_EIP155Tx {
// We write the encoding of empty bytes when the transaction is a creation, *not* the zero // We write the encoding of empty bytes when the transaction is a creation, *not* the zero
// address as one might assume. // address as one might assume.
if (_transaction.isCreate) { if (_transaction.isCreate) {
raw[3] = Lib_RLPWriter.writeBytes(''); raw[3] = Lib_RLPWriter.writeBytes("");
} else { } else {
raw[3] = Lib_RLPWriter.writeAddress(_transaction.to); raw[3] = Lib_RLPWriter.writeAddress(_transaction.to);
} }
...@@ -153,8 +153,8 @@ library Lib_EIP155Tx { ...@@ -153,8 +153,8 @@ library Lib_EIP155Tx {
} else { } else {
// Chain ID *is* included in the unsigned transaction. // Chain ID *is* included in the unsigned transaction.
raw[6] = Lib_RLPWriter.writeUint(_transaction.chainId); raw[6] = Lib_RLPWriter.writeUint(_transaction.chainId);
raw[7] = Lib_RLPWriter.writeBytes(''); raw[7] = Lib_RLPWriter.writeBytes("");
raw[8] = Lib_RLPWriter.writeBytes(''); raw[8] = Lib_RLPWriter.writeBytes("");
} }
return Lib_RLPWriter.writeList(raw); return Lib_RLPWriter.writeList(raw);
......
...@@ -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;
......
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
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);
......
...@@ -3,7 +3,7 @@ pragma solidity >=0.5.16 <0.8.0; ...@@ -3,7 +3,7 @@ pragma solidity >=0.5.16 <0.8.0;
import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import './IL2StandardERC20.sol'; import "./IL2StandardERC20.sol";
contract L2StandardERC20 is IL2StandardERC20, ERC20 { contract L2StandardERC20 is IL2StandardERC20, ERC20 {
address public override l1Token; address public override l1Token;
......
...@@ -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;
...@@ -157,7 +158,7 @@ library Lib_MerkleTrie { ...@@ -157,7 +158,7 @@ library Lib_MerkleTrie {
"Provided proof is invalid." "Provided proof is invalid."
); );
bytes memory value = exists ? _getNodeValue(proof[pathLength - 1]) : bytes(''); bytes memory value = exists ? _getNodeValue(proof[pathLength - 1]) : bytes("");
return ( return (
exists, exists,
...@@ -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)
} }
......
...@@ -94,7 +94,7 @@ library Lib_BytesUtils { ...@@ -94,7 +94,7 @@ library Lib_BytesUtils {
) )
{ {
if (_start >= _bytes.length) { if (_start >= _bytes.length) {
return bytes(''); return bytes("");
} }
return slice(_bytes, _start, _bytes.length - _start); return slice(_bytes, _start, _bytes.length - _start);
......
...@@ -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;
......
...@@ -45,6 +45,9 @@ const config: HardhatUserConfig = { ...@@ -45,6 +45,9 @@ const config: HardhatUserConfig = {
version: '0.7.6', version: '0.7.6',
settings: { settings: {
optimizer: { enabled: true, runs: 200 }, optimizer: { enabled: true, runs: 200 },
metadata: {
bytecodeHash: 'none',
},
outputSelection: { outputSelection: {
'*': { '*': {
'*': ['storageLayout'], '*': ['storageLayout'],
......
...@@ -37,6 +37,7 @@ ...@@ -37,6 +37,7 @@
"posttest:slither": "rm -f @openzeppelin && rm -f @ens && rm -f hardhat", "posttest:slither": "rm -f @openzeppelin && rm -f @ens && rm -f hardhat",
"lint:check": "eslint .", "lint:check": "eslint .",
"lint:fix": "yarn lint:check --fix", "lint:fix": "yarn lint:check --fix",
"lint:contracts": "yarn solhint -f table contracts/optimistic-ethereum/**/*.sol",
"clean": "rm -rf ./dist ./artifacts ./artifacts-ovm ./cache ./cache-ovm ./tsconfig.build.tsbuildinfo", "clean": "rm -rf ./dist ./artifacts ./artifacts-ovm ./cache ./cache-ovm ./tsconfig.build.tsbuildinfo",
"deploy": "ts-node \"./bin/deploy.ts\" && yarn generate-markdown", "deploy": "ts-node \"./bin/deploy.ts\" && yarn generate-markdown",
"serve": "./bin/serve_dump.sh", "serve": "./bin/serve_dump.sh",
...@@ -105,6 +106,7 @@ ...@@ -105,6 +106,7 @@
"lint-staged": "11.0.0", "lint-staged": "11.0.0",
"random-bytes-seed": "^1.0.3", "random-bytes-seed": "^1.0.3",
"rlp": "^2.2.6", "rlp": "^2.2.6",
"solhint": "^3.3.6",
"solidity-coverage": "^0.7.16", "solidity-coverage": "^0.7.16",
"ts-generator": "0.0.8", "ts-generator": "0.0.8",
"ts-node": "^9.1.1", "ts-node": "^9.1.1",
......
...@@ -10,7 +10,7 @@ import { getContractDefinition } from '../../src/contract-defs' ...@@ -10,7 +10,7 @@ import { getContractDefinition } from '../../src/contract-defs'
export const DEFAULT_ACCOUNTS = defaultAccounts export const DEFAULT_ACCOUNTS = defaultAccounts
export const DEFAULT_ACCOUNTS_HARDHAT = defaultAccounts.map((account) => { export const DEFAULT_ACCOUNTS_HARDHAT = defaultAccounts.map((account) => {
return { return {
balance: ethers.BigNumber.from(account.balance).toHexString(), balance: account.balance,
privateKey: account.secretKey, privateKey: account.secretKey,
} }
}) })
......
...@@ -14,7 +14,12 @@ try { ...@@ -14,7 +14,12 @@ try {
ReturnData, ReturnData,
} = require('hardhat/internal/hardhat-network/provider/return-data') } = require('hardhat/internal/hardhat-network/provider/return-data')
decodeRevertReason = (value: Buffer) => { decodeRevertReason = (value: Buffer) => {
return new ReturnData(value).decodeError() const returnData = new ReturnData(value)
if (returnData.isErrorReturnData()) {
return returnData.decodeError()
} else {
return ''
}
} }
} }
// Handle hardhat ^2.2.0 // Handle hardhat ^2.2.0
......
This diff is collapsed.
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