From 9418b9fabf1f09aabd8692dbcb8bf10d25508b66 Mon Sep 17 00:00:00 2001 From: 0xng Date: Fri, 10 May 2024 13:39:18 -0300 Subject: [PATCH 1/7] chore: adding bridge spec --- specs/protocol/bridges.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/specs/protocol/bridges.md b/specs/protocol/bridges.md index 319b7b0a5..e8d1cadc4 100644 --- a/specs/protocol/bridges.md +++ b/specs/protocol/bridges.md @@ -6,6 +6,7 @@ - [Overview](#overview) - [Token Depositing](#token-depositing) +- [ERC20 Unlocking](#erc20-unlocking) - [Upgradability](#upgradability) @@ -29,15 +30,19 @@ interface StandardBridge { event ERC20BridgeInitiated(address indexed localToken, address indexed remoteToken, address indexed from, address to, uint256 amount, bytes extraData); event ETHBridgeFinalized(address indexed from, address indexed to, uint256 amount, bytes extraData); event ETHBridgeInitiated(address indexed from, address indexed to, uint256 amount, bytes extraData); + event ERC20Unlocked(address indexed localToken, address indexed remotetoken, address indexed from, uint256 amount, bytes32 messageHash); function bridgeERC20(address _localToken, address _remoteToken, uint256 _amount, uint32 _minGasLimit, bytes memory _extraData) external; function bridgeERC20To(address _localToken, address _remoteToken, address _to, uint256 _amount, uint32 _minGasLimit, bytes memory _extraData) external; function bridgeETH(uint32 _minGasLimit, bytes memory _extraData) payable external; function bridgeETHTo(address _to, uint32 _minGasLimit, bytes memory _extraData) payable external; function deposits(address, address) view external returns (uint256); + function processedMessages(bytes32 _messageHashes) view external returns (uint256); + function unlockERC20s(address _localToken, address _remoteToken, address _from, address _to, uint256 _amount, bytes calldata _extraData, uint240 _nonce, uint32 _minGasLimit) external; function finalizeBridgeERC20(address _localToken, address _remoteToken, address _from, address _to, uint256 _amount, bytes memory _extraData) external; function finalizeBridgeETH(address _from, address _to, uint256 _amount, bytes memory _extraData) payable external; function messenger() view external returns (address); + function ROLLBACK_INBOX() view external returns (address); function OTHER_BRIDGE() view external returns (address); } ``` @@ -49,6 +54,9 @@ domain. An `OptimismMintableERC20` token contract must exist on the remote domain to be able to deposit tokens to that domain. One of these tokens can be deployed using the `OptimismMintableERC20Factory` contract. +## ERC20 Unlocking +The `ERC20Unlocked` function is used to unlock tokens stuck due to failure in relaying prior ERC20 bridging actions. A `messageHash` must exist in the `ROLLBACK_INBOX` contract to certify the message hash corresponding to an ERC20 bridging action started from the standard bridged failed on the other domain. + ## Upgradability Both the L1 and L2 standard bridges should be behind upgradable proxies. From db55924bb3cd7d1dbe36a8a53ef31223651e2ceb Mon Sep 17 00:00:00 2001 From: 0xng Date: Fri, 10 May 2024 13:58:19 -0300 Subject: [PATCH 2/7] chore: adding messengers spec --- specs/protocol/messengers.md | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/specs/protocol/messengers.md b/specs/protocol/messengers.md index 142a4e2dd..d2a393b33 100644 --- a/specs/protocol/messengers.md +++ b/specs/protocol/messengers.md @@ -38,6 +38,7 @@ interface CrossDomainMessenger { event RelayedMessage(bytes32 indexed msgHash); event SentMessage(address indexed target, address sender, bytes message, uint256 messageNonce, uint256 gasLimit); event SentMessageExtension1(address indexed sender, uint256 value); + event MessageSentToRollbackInbox(bytes32 indexed messageHash, address indexed target, address sender, bytes message, uint256 messageNonce, uint256 gasLimit); function MESSAGE_VERSION() external view returns (uint16); function MIN_GAS_CALLDATA_OVERHEAD() external view returns (uint64); @@ -45,8 +46,10 @@ interface CrossDomainMessenger { function MIN_GAS_DYNAMIC_OVERHEAD_DENOMINATOR() external view returns (uint64); function MIN_GAS_DYNAMIC_OVERHEAD_NUMERATOR() external view returns (uint64); function OTHER_MESSENGER() external view returns (address); + function ROLLBACK_INBOX() external view returns (address); + function ROLLBACK_INBOX_DELAY() external view returns (uint256); function baseGas(bytes memory _message, uint32 _minGasLimit) external pure returns (uint64); - function failedMessages(bytes32) external view returns (bool); + function failedMessages(bytes32) external view returns (uint256); function messageNonce() external view returns (uint256); function relayMessage( uint256 _nonce, @@ -57,7 +60,8 @@ interface CrossDomainMessenger { bytes memory _message ) external payable; function sendMessage(address _target, bytes memory _message, uint32 _minGasLimit) external payable; - function successfulMessages(bytes32) external view returns (bool); + function sendHashToRollbackInbox(bytes32 _versionedHash, bytes32 _minGasLimit) external; + function successfulMessages(bytes32) external view returns (uint256); function xDomainMessageSender() external view returns (address); } ``` @@ -79,6 +83,9 @@ then waits for the finalization window to pass, and then finalizes the withdrawa on the OptimismPortal, which calls `relayMessage` on the `L1CrossDomainMessenger` to finalize the withdrawal. +## Rolling a Message Back +The `sendHashToRollbackInbox` function is used to send the hashes of failed and unsuccesful messages to the `ROLLBACK_INBOX` contract on the other domain after a given delay, ensuring the message corresponding to the rolled back hash is never processed in the current domain. The main purpose of this function is to inform the other domain of failed messages so contracts living in this other domain can handle the message failure. This allows functionalities such as unlocking stuck ERC20s. + ## Upgradability The L1 and L2 cross domain messengers should be deployed behind upgradable From 25f0fdb4322672ae312ac4db346388ee087dd0fb Mon Sep 17 00:00:00 2001 From: 0xng Date: Fri, 10 May 2024 14:00:48 -0300 Subject: [PATCH 3/7] fix: table of contents missing link --- specs/protocol/messengers.md | 1 + 1 file changed, 1 insertion(+) diff --git a/specs/protocol/messengers.md b/specs/protocol/messengers.md index d2a393b33..ce6742945 100644 --- a/specs/protocol/messengers.md +++ b/specs/protocol/messengers.md @@ -6,6 +6,7 @@ - [Overview](#overview) - [Message Passing](#message-passing) +- [Rolling a Message Back](#rolling-a-message-back) - [Upgradability](#upgradability) - [Message Versioning](#message-versioning) - [Message Version 0](#message-version-0) From e9d672997eef967b0e3ff31b4d4d280ba7be992a Mon Sep 17 00:00:00 2001 From: 0xng Date: Fri, 10 May 2024 14:10:32 -0300 Subject: [PATCH 4/7] chore: adding roleback inboxes spec --- specs/protocol/rollback-inboxes.md | 34 ++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 specs/protocol/rollback-inboxes.md diff --git a/specs/protocol/rollback-inboxes.md b/specs/protocol/rollback-inboxes.md new file mode 100644 index 000000000..af309e653 --- /dev/null +++ b/specs/protocol/rollback-inboxes.md @@ -0,0 +1,34 @@ +# Rollback Inboxes + + + +**Table of Contents** + +- [Overview](#overview) +- [Message Hash Reception](#message-hash-reception) +- [Upgradability](#upgradability) + + + +## Overview + +The rollback inbox contracts are responsible for storing the hashes of messages that failed on the other domain. They are built with the purpose of allowing contracts on the same domain to have the capability of handling what actions to perform when one of the messages they sent failed on the other domain. + +```solidity +interface RollbackInbox { + event MessageHashReceived(bytes32 indexed messageHash, uint256 indexed timestamp); + + function receiveMessageHash(bytes32 _messageHash, address _sender) external; + function messenger() view external returns (address); + function otherMessenger() view external returns (address); + function messageHashes(bytes32 _messageHash) view external returns (uint256); +} +``` + +## Message Hash Reception + +The `receiveMessageHash` function is used to receive message hashes from the other domain. It must ensure the caller is the `CrossDomainMessenger` from this domain, and that the sender is the `CrossDomainMessenger` from the other domain. + +## Upgradability + +Both the L1 and L2 rollback inboxes should be behind upgradable proxies. From 0d964c469dda929ba6b78f1761bff698e748183c Mon Sep 17 00:00:00 2001 From: Skeletor Spaceman <92943766+skeletor-spaceman@users.noreply.github.com> Date: Fri, 10 May 2024 16:10:54 -0300 Subject: [PATCH 5/7] fix: rollback inbox can be used by non-senders too --- specs/protocol/rollback-inboxes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specs/protocol/rollback-inboxes.md b/specs/protocol/rollback-inboxes.md index af309e653..dab91a002 100644 --- a/specs/protocol/rollback-inboxes.md +++ b/specs/protocol/rollback-inboxes.md @@ -12,7 +12,7 @@ ## Overview -The rollback inbox contracts are responsible for storing the hashes of messages that failed on the other domain. They are built with the purpose of allowing contracts on the same domain to have the capability of handling what actions to perform when one of the messages they sent failed on the other domain. +The rollback inbox contracts are responsible for storing the hashes of messages that failed on the other domain. They are built with the purpose of allowing contracts on the same domain to have the capability of handling what actions to perform when a message failed on the other domain and was rolled-back to it's origin domain. ```solidity interface RollbackInbox { From f77fe6facea7d27129ad5b37b2f0a619e168cef7 Mon Sep 17 00:00:00 2001 From: 0xng Date: Fri, 10 May 2024 16:16:48 -0300 Subject: [PATCH 6/7] chore: adding predeployed address to be defined --- specs/protocol/rollback-inboxes.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/specs/protocol/rollback-inboxes.md b/specs/protocol/rollback-inboxes.md index dab91a002..93f387bdc 100644 --- a/specs/protocol/rollback-inboxes.md +++ b/specs/protocol/rollback-inboxes.md @@ -14,6 +14,8 @@ The rollback inbox contracts are responsible for storing the hashes of messages that failed on the other domain. They are built with the purpose of allowing contracts on the same domain to have the capability of handling what actions to perform when a message failed on the other domain and was rolled-back to it's origin domain. +The `L2RollbackInbox` is a predeploy contract located at TO BE DEFINED. + ```solidity interface RollbackInbox { event MessageHashReceived(bytes32 indexed messageHash, uint256 indexed timestamp); From 1939fd5bf4e779d1a926d587056f746ae29937a8 Mon Sep 17 00:00:00 2001 From: 0xng Date: Fri, 10 May 2024 17:58:01 -0300 Subject: [PATCH 7/7] fix: md linter --- specs/protocol/bridges.md | 6 +++++- specs/protocol/messengers.md | 9 ++++++++- specs/protocol/rollback-inboxes.md | 9 +++++++-- 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/specs/protocol/bridges.md b/specs/protocol/bridges.md index e8d1cadc4..0a8f2284d 100644 --- a/specs/protocol/bridges.md +++ b/specs/protocol/bridges.md @@ -55,7 +55,11 @@ domain to be able to deposit tokens to that domain. One of these tokens can be deployed using the `OptimismMintableERC20Factory` contract. ## ERC20 Unlocking -The `ERC20Unlocked` function is used to unlock tokens stuck due to failure in relaying prior ERC20 bridging actions. A `messageHash` must exist in the `ROLLBACK_INBOX` contract to certify the message hash corresponding to an ERC20 bridging action started from the standard bridged failed on the other domain. + +The `ERC20Unlocked` function is used to unlock tokens stuck due to failure in +relaying prior ERC20 bridging actions. A `messageHash` must exist in the `ROLLBACK_INBOX` +contract to certify the message hash corresponding to an ERC20 bridging action started +from the standard bridged failed on the other domain. ## Upgradability diff --git a/specs/protocol/messengers.md b/specs/protocol/messengers.md index ce6742945..66f9433e0 100644 --- a/specs/protocol/messengers.md +++ b/specs/protocol/messengers.md @@ -85,7 +85,14 @@ on the OptimismPortal, which calls `relayMessage` on the `L1CrossDomainMessenger` to finalize the withdrawal. ## Rolling a Message Back -The `sendHashToRollbackInbox` function is used to send the hashes of failed and unsuccesful messages to the `ROLLBACK_INBOX` contract on the other domain after a given delay, ensuring the message corresponding to the rolled back hash is never processed in the current domain. The main purpose of this function is to inform the other domain of failed messages so contracts living in this other domain can handle the message failure. This allows functionalities such as unlocking stuck ERC20s. + +The `sendHashToRollbackInbox` function is used to send the hashes of failed +and unsuccesful messages to the `ROLLBACK_INBOX` contract on the other domain +after a given delay, ensuring the message corresponding to the rolled back hash +is never processed in the current domain. The main purpose of this function +is to inform the other domain of failed messages so contracts living in +this other domain can handle the message failure. This allows functionalities +such as unlocking stuck ERC20s. ## Upgradability diff --git a/specs/protocol/rollback-inboxes.md b/specs/protocol/rollback-inboxes.md index 93f387bdc..7c5118037 100644 --- a/specs/protocol/rollback-inboxes.md +++ b/specs/protocol/rollback-inboxes.md @@ -12,7 +12,10 @@ ## Overview -The rollback inbox contracts are responsible for storing the hashes of messages that failed on the other domain. They are built with the purpose of allowing contracts on the same domain to have the capability of handling what actions to perform when a message failed on the other domain and was rolled-back to it's origin domain. +The rollback inbox contracts are responsible for storing the hashes of messages +that failed on the other domain. They are built with the purpose of allowing contracts +on the same domain to have the capability of handling what actions to perform when a +message failed on the other domain and was rolled-back to it's origin domain. The `L2RollbackInbox` is a predeploy contract located at TO BE DEFINED. @@ -29,7 +32,9 @@ interface RollbackInbox { ## Message Hash Reception -The `receiveMessageHash` function is used to receive message hashes from the other domain. It must ensure the caller is the `CrossDomainMessenger` from this domain, and that the sender is the `CrossDomainMessenger` from the other domain. +The `receiveMessageHash` function is used to receive message hashes from the other domain. +It must ensure the caller is the `CrossDomainMessenger` from this domain, and that the +sender is the `CrossDomainMessenger` from the other domain. ## Upgradability