-
Notifications
You must be signed in to change notification settings - Fork 50
Add the native arbitrum bridge #6
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
Merged
Changes from 3 commits
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
b412772
feat: add arbitrum L1 bridge and dependencies
shalzz 457b060
feat: add arbitrum L2 bridge
shalzz 61bc2f3
refactor(bridge): use ArbRetryableTx#getSubmissionPrice
shalzz a6cfdd0
chore: .gitignore and removal of unnecessary yarn cache as we are usi…
jaybuidl 0ed4d74
chore: .gitignore
jaybuidl File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2,6 +2,10 @@ | |
| cache | ||
| artifacts | ||
|
|
||
| ## Hardhat typechain bindings/types | ||
| typechain | ||
| typechain/** | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. that should go before or after the autogenerated section |
||
|
|
||
| # Hardhat deploy files | ||
| deployments/localhost | ||
| deployments/hardhat | ||
|
|
@@ -170,4 +174,4 @@ tags | |
| # .yarn/cache | ||
| # .pnp.* | ||
|
|
||
| # End of https://www.toptal.com/developers/gitignore/api/vim,node,visualstudiocode,yarn | ||
| # End of https://www.toptal.com/developers/gitignore/api/vim,node,visualstudiocode,yarn | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,58 @@ | ||
| // SPDX-License-Identifier: MIT | ||
|
|
||
| pragma solidity ^0.8.0; | ||
|
|
||
| import "./interfaces/IInbox.sol"; | ||
| import "./interfaces/IArbRetryableTx.sol"; | ||
|
|
||
| contract L1Bridge { | ||
| address public l2Target; | ||
| IInbox public inbox; | ||
| IArbRetryableTx constant arbRetryableTx = IArbRetryableTx(address(110)); | ||
|
|
||
| event RetryableTicketCreated(uint256 indexed ticketId); | ||
|
|
||
| constructor(address _l2Target, address _inbox) { | ||
| l2Target = _l2Target; | ||
| inbox = IInbox(_inbox); | ||
| } | ||
|
|
||
| /** | ||
| * Sends an arbitrary message from one domain to another. | ||
| * | ||
| * @dev The caller needs to pay some ETH to cover the gas costs | ||
| * of the call on L2. Excess ETH that is not used by gas costs will | ||
| * be refunded to the `msg.sender` address on L2. | ||
| * | ||
| * @notice if a user does not desire immediate redemption, they should | ||
| * provide a DepositValue of at least CallValue + MaxSubmissionCost. | ||
| * If they do desire immediate execution, they should provide a DepositValue | ||
| * of at least CallValue + MaxSubmissionCost + (GasPrice x MaxGas). | ||
| * | ||
| * @param _calldata The L2 encoded message data. | ||
| * @param _maxGas Gas limit for immediate L2 execution attempt. | ||
| * @param _gasPriceBid L2 Gas price bid for immediate L2 execution attempt. | ||
| * @return Unique id to track the message request/transaction. | ||
| */ | ||
| function sendCrossDomainMessage( | ||
| bytes memory _calldata, | ||
| uint256 _maxGas, | ||
| uint256 _gasPriceBid | ||
| ) external payable returns (uint256) { | ||
| (uint256 baseSubmissionCost, ) = arbRetryableTx.getSubmissionPrice(_calldata.length); | ||
|
|
||
| uint256 ticketID = inbox.createRetryableTicket{value: msg.value}( | ||
| l2Target, | ||
| 0, | ||
| baseSubmissionCost, | ||
| msg.sender, | ||
| msg.sender, | ||
| _maxGas, | ||
| _gasPriceBid, | ||
| _calldata | ||
| ); | ||
|
|
||
| emit RetryableTicketCreated(ticketID); | ||
| return ticketID; | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| // SPDX-License-Identifier: MIT | ||
|
|
||
| pragma solidity ^0.8.0; | ||
|
|
||
| import "./interfaces/IArbSys.sol"; | ||
|
|
||
| contract L2Bridge { | ||
| address public l1Target; | ||
| IArbSys constant arbsys = IArbSys(address(100)); | ||
|
|
||
| event L2ToL1TxCreated(uint256 indexed withdrawalId); | ||
|
|
||
| constructor(address _l1Target) { | ||
| l1Target = _l1Target; | ||
| } | ||
|
|
||
| /** | ||
| * Sends an arbitrary message from one domain to another. | ||
| * | ||
| * @param _calldata The L1 encoded message data. | ||
| * @return Unique id to track the message request/transaction. | ||
| */ | ||
| function sendCrossDomainMessage(bytes memory _calldata) external payable returns (uint256) { | ||
| uint256 withdrawalId = arbsys.sendTxToL1(l1Target, _calldata); | ||
|
|
||
| emit L2ToL1TxCreated(withdrawalId); | ||
| return withdrawalId; | ||
| } | ||
| } |
72 changes: 72 additions & 0 deletions
72
contracts/src/bridge/arbitrum/interfaces/IArbRetryableTx.sol
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,72 @@ | ||
| pragma solidity >=0.7.0; | ||
|
|
||
| /** | ||
| * @title precompiled contract in every Arbitrum chain for retryable transaction related data retrieval and interactions. Exists at 0x000000000000000000000000000000000000006E | ||
| */ | ||
| interface IArbRetryableTx { | ||
| /** | ||
| * @notice Redeem a redeemable tx. | ||
| * Revert if called by an L2 contract, or if txId does not exist, or if txId reverts. | ||
| * If this returns, txId has been completed and is no longer available for redemption. | ||
| * If this reverts, txId is still available for redemption (until it times out or is canceled). | ||
| @param txId unique identifier of retryable message: keccak256(keccak256(ArbchainId, inbox-sequence-number), uint(0) ) | ||
| */ | ||
| function redeem(bytes32 txId) external; | ||
|
|
||
| /** | ||
| * @notice Return the minimum lifetime of redeemable txn. | ||
| * @return lifetime in seconds | ||
| */ | ||
| function getLifetime() external view returns (uint256); | ||
|
|
||
| /** | ||
| * @notice Return the timestamp when ticketId will age out, or zero if ticketId does not exist. | ||
| * The timestamp could be in the past, because aged-out tickets might not be discarded immediately. | ||
| * @param ticketId unique ticket identifier | ||
| * @return timestamp for ticket's deadline | ||
| */ | ||
| function getTimeout(bytes32 ticketId) external view returns (uint256); | ||
|
|
||
| /** | ||
| * @notice Return the price, in wei, of submitting a new retryable tx with a given calldata size. | ||
| * @param calldataSize call data size to get price of (in wei) | ||
| * @return (price, nextUpdateTimestamp). Price is guaranteed not to change until nextUpdateTimestamp. | ||
| */ | ||
| function getSubmissionPrice(uint256 calldataSize) external view returns (uint256, uint256); | ||
|
|
||
| /** | ||
| * @notice Return the price, in wei, of extending the lifetime of ticketId by an additional lifetime period. Revert if ticketId doesn't exist. | ||
| * @param ticketId unique ticket identifier | ||
| * @return (price, nextUpdateTimestamp). Price is guaranteed not to change until nextUpdateTimestamp. | ||
| */ | ||
| function getKeepalivePrice(bytes32 ticketId) external view returns (uint256, uint256); | ||
|
|
||
| /** | ||
| @notice Deposits callvalue into the sender's L2 account, then adds one lifetime period to the life of ticketId. | ||
| * If successful, emits LifetimeExtended event. | ||
| * Revert if ticketId does not exist, or if the timeout of ticketId is already at least one lifetime period in the future, or if the sender has insufficient funds (after the deposit). | ||
| * @param ticketId unique ticket identifier | ||
| * @return New timeout of ticketId. | ||
| */ | ||
| function keepalive(bytes32 ticketId) external payable returns (uint256); | ||
|
|
||
| /** | ||
| * @notice Return the beneficiary of ticketId. | ||
| * Revert if ticketId doesn't exist. | ||
| * @param ticketId unique ticket identifier | ||
| * @return address of beneficiary for ticket | ||
| */ | ||
| function getBeneficiary(bytes32 ticketId) external view returns (address); | ||
|
|
||
| /** | ||
| * @notice Cancel ticketId and refund its callvalue to its beneficiary. | ||
| * Revert if ticketId doesn't exist, or if called by anyone other than ticketId's beneficiary. | ||
| * @param ticketId unique ticket identifier | ||
| */ | ||
| function cancel(bytes32 ticketId) external; | ||
|
|
||
| event TicketCreated(bytes32 indexed ticketId); | ||
| event LifetimeExtended(bytes32 indexed ticketId, uint256 newTimeout); | ||
| event Redeemed(bytes32 indexed ticketId); | ||
| event Canceled(bytes32 indexed ticketId); | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,71 @@ | ||
| pragma solidity >=0.7.0; | ||
|
|
||
| /** | ||
| * @title Precompiled contract that exists in every Arbitrum chain at address(100), 0x0000000000000000000000000000000000000064. Exposes a variety of system-level functionality. | ||
| */ | ||
| interface IArbSys { | ||
| /** | ||
| * @notice Get internal version number identifying an ArbOS build | ||
| * @return version number as int | ||
| */ | ||
| function arbOSVersion() external pure 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. | ||
| */ | ||
| function withdrawEth(address destination) external payable returns (uint256); | ||
|
|
||
| /** | ||
| * @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. | ||
| */ | ||
| function sendTxToL1(address destination, bytes calldata calldataForL1) external payable 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 | ||
| */ | ||
| function getTransactionCount(address account) 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 | ||
| */ | ||
| function getStorageAt(address account, uint256 index) 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 | ||
| */ | ||
| function isTopLevelCall() external view returns (bool); | ||
|
|
||
| event EthWithdrawal(address indexed destAddr, uint256 amount); | ||
|
|
||
| event L2ToL1Transaction( | ||
| address caller, | ||
| address indexed destination, | ||
| uint256 indexed uniqueId, | ||
| uint256 indexed batchNumber, | ||
| uint256 indexInBatch, | ||
| uint256 arbBlockNum, | ||
| uint256 ethBlockNum, | ||
| uint256 timestamp, | ||
| uint256 callvalue, | ||
| bytes data | ||
| ); | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,65 @@ | ||
| // SPDX-License-Identifier: Apache-2.0 | ||
|
|
||
| /* | ||
| * 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; | ||
|
|
||
| interface IBridge { | ||
| event MessageDelivered( | ||
| uint256 indexed messageIndex, | ||
| bytes32 indexed beforeInboxAcc, | ||
| address inbox, | ||
| uint8 kind, | ||
| address sender, | ||
| bytes32 messageDataHash | ||
| ); | ||
|
|
||
| event BridgeCallTriggered(address indexed outbox, address indexed destAddr, uint256 amount, bytes data); | ||
|
|
||
| event InboxToggle(address indexed inbox, bool enabled); | ||
|
|
||
| event OutboxToggle(address indexed outbox, bool enabled); | ||
|
|
||
| function deliverMessageToInbox( | ||
| uint8 kind, | ||
| address sender, | ||
| bytes32 messageDataHash | ||
| ) external payable returns (uint256); | ||
|
|
||
| function executeCall( | ||
| address destAddr, | ||
| uint256 amount, | ||
| 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 setOutbox(address inbox, bool enabled) external; | ||
|
|
||
| // View functions | ||
|
|
||
| function activeOutbox() external view returns (address); | ||
|
|
||
| function allowedInboxes(address inbox) external view returns (bool); | ||
|
|
||
| function allowedOutboxes(address outbox) external view returns (bool); | ||
|
|
||
| function inboxAccs(uint256 index) external view returns (bytes32); | ||
|
|
||
| function messageCount() external view returns (uint256); | ||
| } |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.