Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Update Arbitrum's vendored contracts to Nitro #3692

Merged
merged 6 commits into from Sep 28, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -32,6 +32,7 @@
* `Ownable2Step`: extension of `Ownable` that makes the ownership transfers a two step process. ([#3620](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3620))
* `Math` and `SignedMath`: optimize function `max` by using `>` instead of `>=`. ([#3679](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3679))
* `Math`: Add `log2`, `log10` and `log256`. ([#3670](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3670))
* Arbitrum: Update the vendored arbitrum contracts to match the nitro upgrade. ([#3692](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3692))

### Breaking changes

Expand Down
1 change: 0 additions & 1 deletion contracts/crosschain/arbitrum/LibArbitrumL1.sol
Expand Up @@ -4,7 +4,6 @@
pragma solidity ^0.8.4;

import {IBridge as ArbitrumL1_Bridge} from "../../vendor/arbitrum/IBridge.sol";
import {IInbox as ArbitrumL1_Inbox} from "../../vendor/arbitrum/IInbox.sol";
import {IOutbox as ArbitrumL1_Outbox} from "../../vendor/arbitrum/IOutbox.sol";
import "../errors.sol";

Expand Down
123 changes: 82 additions & 41 deletions contracts/vendor/arbitrum/IArbSys.sol
@@ -1,63 +1,60 @@
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (vendor/arbitrum/IArbSys.sol)
// Copyright 2021-2022, Offchain Labs, Inc.
// For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE
// SPDX-License-Identifier: BUSL-1.1

pragma solidity >=0.4.21 <0.9.0;

/**
* @title Precompiled contract that exists in every Arbitrum chain at address(100), 0x0000000000000000000000000000000000000064. Exposes a variety of system-level functionality.
* @title System level functionality
* @notice For use by contracts to interact with core L2-specific functionality.
* Precompiled contract that exists in every Arbitrum chain at address(100), 0x0000000000000000000000000000000000000064.
*/
interface IArbSys {
/**
* @notice Get internal version number identifying an ArbOS build
* @return version number as int
*/
function arbOSVersion() external pure returns (uint256);

function arbChainID() external view returns (uint256);

/**
* @notice Get Arbitrum block number (distinct from L1 block number; Arbitrum genesis block has block number 0)
* @return block number as int
*/
function arbBlockNumber() external view returns (uint256);

/**
* @notice Send given amount of Eth to dest from sender.
* This is a convenience function, which is equivalent to calling sendTxToL1 with empty calldataForL1.
* @param destination recipient address on L1
* @return unique identifier for this L2-to-L1 transaction.
* @notice Get Arbitrum block hash (reverts unless currentBlockNum-256 <= arbBlockNum < currentBlockNum)
* @return block hash
*/
function withdrawEth(address destination) external payable returns (uint256);
function arbBlockHash(uint256 arbBlockNum) external view returns (bytes32);

/**
* @notice Send a transaction to L1
* @param destination recipient address on L1
* @param calldataForL1 (optional) calldata for L1 contract call
* @return a unique identifier for this L2-to-L1 transaction.
* @notice Gets the rollup's unique chain identifier
* @return Chain identifier as int
*/
function sendTxToL1(address destination, bytes calldata calldataForL1) external payable returns (uint256);
function arbChainID() external view returns (uint256);

/**
* @notice get the number of transactions issued by the given external account or the account sequence number of the given contract
* @param account target account
* @return the number of transactions issued by the given external account or the account sequence number of the given contract
* @notice Get internal version number identifying an ArbOS build
* @return version number as int
*/
function getTransactionCount(address account) external view returns (uint256);
function arbOSVersion() external view returns (uint256);

/**
* @notice get the value of target L2 storage slot
* This function is only callable from address 0 to prevent contracts from being able to call it
* @param account target account
* @param index target index of storage slot
* @return stotage value for the given account at the given index
* @notice Returns 0 since Nitro has no concept of storage gas
* @return uint 0
*/
function getStorageAt(address account, uint256 index) external view returns (uint256);
function getStorageGasAvailable() external view returns (uint256);

/**
* @notice check if current call is coming from l1
* @return true if the caller of this was called directly from L1
* @notice (deprecated) check if current call is top level (meaning it was triggered by an EoA or a L1 contract)
* @dev this call has been deprecated and may be removed in a future release
* @return true if current execution frame is not a call by another L2 contract
*/
function isTopLevelCall() external view returns (bool);

/**
* @notice map L1 sender contract address to its L2 alias
* @param sender sender address
* @param unused argument no longer used
* @return aliased sender address
*/
function mapL1SenderContractAddressToL2Alias(address sender, address unused) external pure returns (address);

/**
* @notice check if the caller (of this caller of this) is an aliased L1 contract address
* @return true iff the caller's address is an alias for an L1 contract address
Expand All @@ -71,19 +68,55 @@ interface IArbSys {
function myCallersAddressWithoutAliasing() external view returns (address);

/**
* @notice map L1 sender contract address to its L2 alias
* @param sender sender address
* @param dest destination address
* @return aliased sender address
* @notice Send given amount of Eth to dest from sender.
* This is a convenience function, which is equivalent to calling sendTxToL1 with empty data.
* @param destination recipient address on L1
* @return unique identifier for this L2-to-L1 transaction.
*/
function mapL1SenderContractAddressToL2Alias(address sender, address dest) external pure returns (address);
function withdrawEth(address destination) external payable returns (uint256);

/**
* @notice get the caller's amount of available storage gas
* @return amount of storage gas available to the caller
* @notice Send a transaction to L1
* @dev it is not possible to execute on the L1 any L2-to-L1 transaction which contains data
* to a contract address without any code (as enforced by the Bridge contract).
* @param destination recipient address on L1
* @param data (optional) calldata for L1 contract call
* @return a unique identifier for this L2-to-L1 transaction.
*/
function getStorageGasAvailable() external view returns (uint256);
function sendTxToL1(address destination, bytes calldata data) external payable returns (uint256);

/**
* @notice Get send Merkle tree state
* @return size number of sends in the history
* @return root root hash of the send history
* @return partials hashes of partial subtrees in the send history tree
*/
function sendMerkleTreeState()
external
view
returns (
uint256 size,
bytes32 root,
bytes32[] memory partials
);

/**
* @notice creates a send txn from L2 to L1
* @param position = (level << 192) + leaf = (0 << 192) + leaf = leaf
*/
event L2ToL1Tx(
address caller,
address indexed destination,
uint256 indexed hash,
uint256 indexed position,
uint256 arbBlockNum,
uint256 ethBlockNum,
uint256 timestamp,
uint256 callvalue,
bytes data
);

/// @dev DEPRECATED in favour of the new L2ToL1Tx event above after the nitro upgrade
event L2ToL1Transaction(
address caller,
address indexed destination,
Expand All @@ -96,4 +129,12 @@ interface IArbSys {
uint256 callvalue,
bytes data
);

/**
* @notice logs a merkle branch for proof synthesis
* @param reserved an index meant only to align the 4th index with L2ToL1Transaction's 4th event
* @param hash the merkle hash
* @param position = (level << 192) + leaf
*/
event SendMerkleUpdate(uint256 indexed reserved, bytes32 indexed hash, uint256 indexed position);
}
110 changes: 76 additions & 34 deletions contracts/vendor/arbitrum/IBridge.sol
@@ -1,23 +1,9 @@
// SPDX-License-Identifier: Apache-2.0
// OpenZeppelin Contracts (last updated v4.6.0) (vendor/arbitrum/IBridge.sol)

/*
* Copyright 2021, Offchain Labs, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

pragma solidity ^0.8.0;
// Copyright 2021-2022, Offchain Labs, Inc.
// For license information, see https://github.com/nitro/blob/master/LICENSE
// SPDX-License-Identifier: BUSL-1.1

// solhint-disable-next-line compiler-version
pragma solidity >=0.6.9 <0.9.0;

interface IBridge {
event MessageDelivered(
Expand All @@ -26,41 +12,97 @@ interface IBridge {
address inbox,
uint8 kind,
address sender,
bytes32 messageDataHash
bytes32 messageDataHash,
uint256 baseFeeL1,
uint64 timestamp
);

event BridgeCallTriggered(address indexed outbox, address indexed destAddr, uint256 amount, bytes data);
event BridgeCallTriggered(address indexed outbox, address indexed to, uint256 value, bytes data);

event InboxToggle(address indexed inbox, bool enabled);

event OutboxToggle(address indexed outbox, bool enabled);

function deliverMessageToInbox(
event SequencerInboxUpdated(address newSequencerInbox);

function allowedDelayedInboxList(uint256) external returns (address);

function allowedOutboxList(uint256) external returns (address);

/// @dev Accumulator for delayed inbox messages; tail represents hash of the current state; each element represents the inclusion of a new message.
function delayedInboxAccs(uint256) external view returns (bytes32);

/// @dev Accumulator for sequencer inbox messages; tail represents hash of the current state; each element represents the inclusion of a new message.
function sequencerInboxAccs(uint256) external view returns (bytes32);

// OpenZeppelin: changed return type from IOwnable
function rollup() external view returns (address);

function sequencerInbox() external view returns (address);

function activeOutbox() external view returns (address);

function allowedDelayedInboxes(address inbox) external view returns (bool);

function allowedOutboxes(address outbox) external view returns (bool);

function sequencerReportedSubMessageCount() external view returns (uint256);

/**
* @dev Enqueue a message in the delayed inbox accumulator.
* These messages are later sequenced in the SequencerInbox, either
* by the sequencer as part of a normal batch, or by force inclusion.
*/
function enqueueDelayedMessage(
uint8 kind,
address sender,
bytes32 messageDataHash
) external payable returns (uint256);

function executeCall(
address destAddr,
uint256 amount,
address to,
uint256 value,
bytes calldata data
) external returns (bool success, bytes memory returnData);

// These are only callable by the admin
function setInbox(address inbox, bool enabled) external;
function delayedMessageCount() external view returns (uint256);

function setOutbox(address inbox, bool enabled) external;
function sequencerMessageCount() external view returns (uint256);

// View functions
// ---------- onlySequencerInbox functions ----------

function activeOutbox() external view returns (address);
function enqueueSequencerMessage(
bytes32 dataHash,
uint256 afterDelayedMessagesRead,
uint256 prevMessageCount,
uint256 newMessageCount
)
external
returns (
uint256 seqMessageIndex,
bytes32 beforeAcc,
bytes32 delayedAcc,
bytes32 acc
);

function allowedInboxes(address inbox) external view returns (bool);
/**
* @dev Allows the sequencer inbox to submit a delayed message of the batchPostingReport type
* This is done through a separate function entrypoint instead of allowing the sequencer inbox
* to call `enqueueDelayedMessage` to avoid the gas overhead of an extra SLOAD in either
* every delayed inbox or every sequencer inbox call.
*/
function submitBatchSpendingReport(address batchPoster, bytes32 dataHash) external returns (uint256 msgNum);

function allowedOutboxes(address outbox) external view returns (bool);
// ---------- onlyRollupOrOwner functions ----------

function setSequencerInbox(address _sequencerInbox) external;

function setDelayedInbox(address inbox, bool enabled) external;

function setOutbox(address inbox, bool enabled) external;

function inboxAccs(uint256 index) external view returns (bytes32);
// ---------- initializer ----------

function messageCount() external view returns (uint256);
// OpenZeppelin: changed rollup_ type from IOwnable
function initialize(address rollup_) external;
}
15 changes: 15 additions & 0 deletions contracts/vendor/arbitrum/IDelayedMessageProvider.sol
@@ -0,0 +1,15 @@
// Copyright 2021-2022, Offchain Labs, Inc.
// For license information, see https://github.com/nitro/blob/master/LICENSE
// SPDX-License-Identifier: BUSL-1.1

// solhint-disable-next-line compiler-version
pragma solidity >=0.6.9 <0.9.0;

interface IDelayedMessageProvider {
/// @dev event emitted when a inbox message is added to the Bridge's delayed accumulator
event InboxMessageDelivered(uint256 indexed messageNum, bytes data);

/// @dev event emitted when a inbox message is added to the Bridge's delayed accumulator
/// same as InboxMessageDelivered but the batch data is available in tx.input
event InboxMessageDeliveredFromOrigin(uint256 indexed messageNum);
}