From b8af70bd5f419bc8f4e77e6209a0a031e138fc9c Mon Sep 17 00:00:00 2001 From: echo Date: Tue, 12 Mar 2024 11:58:16 +0800 Subject: [PATCH 01/39] upgrade ormp lib --- lib/ORMP | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/ORMP b/lib/ORMP index 8c63613..3b94699 160000 --- a/lib/ORMP +++ b/lib/ORMP @@ -1 +1 @@ -Subproject commit 8c6361392856bf5704c45e6be664f58a50221ac9 +Subproject commit 3b9469971551aecda8e1ceaae79d0657a205dc48 From c7da7375d7e60e015be7e67ad726f19f9bb3eb9a Mon Sep 17 00:00:00 2001 From: echo Date: Tue, 12 Mar 2024 13:51:05 +0800 Subject: [PATCH 02/39] fix #204 --- script/test/ORMPPort.t.sol | 4 ++-- src/ports/ORMPPort.sol | 26 +++++++++++++++++++------- 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/script/test/ORMPPort.t.sol b/script/test/ORMPPort.t.sol index e7ce656..5b5eeaa 100644 --- a/script/test/ORMPPort.t.sol +++ b/script/test/ORMPPort.t.sol @@ -38,14 +38,14 @@ contract ORMPPortTest is Test { function testSetAppConfig() public { vm.prank(dao); - ormpPort.setAppConfig(address(0x2), address(0x3)); + ormpPort.setSenderConfig(address(0x2), address(0x3)); UC memory uc = IORMP(vm.envOr("ORMP_ADDRESS", address(ormpProtocol))).getAppConfig(address(ormpPort)); assertEq(uc.oracle, address(0x2)); assertEq(uc.relayer, address(0x3)); // Cannot vm.expectRevert(bytes("Ownable: caller is not the owner")); vm.prank(address(0)); - ormpPort.setAppConfig(address(0x2), address(0x3)); + ormpPort.setSenderConfig(address(0x2), address(0x3)); } function testSetPort() public { diff --git a/src/ports/ORMPPort.sol b/src/ports/ORMPPort.sol index 7d580df..9ba25f4 100644 --- a/src/ports/ORMPPort.sol +++ b/src/ports/ORMPPort.sol @@ -20,11 +20,11 @@ pragma solidity ^0.8.17; import "./base/BaseMessagePort.sol"; import "./base/PortLookup.sol"; import "ORMP/src/interfaces/IORMP.sol"; -import "ORMP/src/user/Application.sol"; +import "ORMP/src/user/UpgradeableApplication.sol"; import "@openzeppelin/contracts/access/Ownable2Step.sol"; -contract ORMPPort is Ownable2Step, Application, BaseMessagePort, PortLookup { - constructor(address dao, address ormp, string memory name) Application(ormp) BaseMessagePort(name) { +contract ORMPPort is Ownable2Step, UpgradeableApplication, BaseMessagePort, PortLookup { + constructor(address dao, address ormp, string memory name) UpgradeableApplication(ormp) BaseMessagePort(name) { _transferOwnership(dao); } @@ -32,8 +32,20 @@ contract ORMPPort is Ownable2Step, Application, BaseMessagePort, PortLookup { _setURI(uri); } - function setAppConfig(address oracle, address relayer) external onlyOwner { - _setAppConfig(oracle, relayer); + function setSender(address ormp) external onlyOwner { + _setSender(ormp); + } + + function setRecver(address ormp) external onlyOwner { + _setRecver(ormp); + } + + function setSenderConfig(address oracle, address relayer) external onlyOwner { + _setSenderConfig(oracle, relayer); + } + + function setRecverConfig(address oracle, address relayer) external onlyOwner { + _setRecverConfig(oracle, relayer); } function setToPort(uint256 _toChainId, address _toPortAddress) external onlyOwner { @@ -50,7 +62,7 @@ contract ORMPPort is Ownable2Step, Application, BaseMessagePort, PortLookup { { (uint256 gasLimit, address refund, bytes memory ormpParams) = abi.decode(params, (uint256, address, bytes)); bytes memory encoded = abi.encodeWithSelector(ORMPPort.recv.selector, fromDapp, toDapp, message); - IORMP(TRUSTED_ORMP).send{value: msg.value}( + IORMP(sender).send{value: msg.value}( toChainId, _checkedToPort(toChainId), gasLimit, encoded, refund, ormpParams ); } @@ -69,6 +81,6 @@ contract ORMPPort is Ownable2Step, Application, BaseMessagePort, PortLookup { { (uint256 gasLimit,, bytes memory ormpParams) = abi.decode(params, (uint256, address, bytes)); bytes memory encoded = abi.encodeWithSelector(ORMPPort.recv.selector, msg.sender, toDapp, message); - return IORMP(TRUSTED_ORMP).fee(toChainId, address(this), gasLimit, encoded, ormpParams); + return IORMP(sender).fee(toChainId, address(this), gasLimit, encoded, ormpParams); } } From 121b90ca7192c821a55a00227510778aafb0b653 Mon Sep 17 00:00:00 2001 From: echo Date: Tue, 12 Mar 2024 16:29:33 +0800 Subject: [PATCH 03/39] fix #215 --- script/test/ORMPPort.t.sol | 12 -- src/ports/ORMPPort.sol | 16 -- src/ports/ORMPUpgradeableAndRetryablePort.sol | 153 ++++++++++++++++++ src/ports/base/BaseMessagePort.sol | 9 +- 4 files changed, 155 insertions(+), 35 deletions(-) create mode 100644 src/ports/ORMPUpgradeableAndRetryablePort.sol diff --git a/script/test/ORMPPort.t.sol b/script/test/ORMPPort.t.sol index 5b5eeaa..a28a394 100644 --- a/script/test/ORMPPort.t.sol +++ b/script/test/ORMPPort.t.sol @@ -36,18 +36,6 @@ contract ORMPPortTest is Test { ormpPort.setURI("https://test.uri"); } - function testSetAppConfig() public { - vm.prank(dao); - ormpPort.setSenderConfig(address(0x2), address(0x3)); - UC memory uc = IORMP(vm.envOr("ORMP_ADDRESS", address(ormpProtocol))).getAppConfig(address(ormpPort)); - assertEq(uc.oracle, address(0x2)); - assertEq(uc.relayer, address(0x3)); - // Cannot - vm.expectRevert(bytes("Ownable: caller is not the owner")); - vm.prank(address(0)); - ormpPort.setSenderConfig(address(0x2), address(0x3)); - } - function testSetPort() public { // From port vm.prank(dao); diff --git a/src/ports/ORMPPort.sol b/src/ports/ORMPPort.sol index 9ba25f4..6b8a20d 100644 --- a/src/ports/ORMPPort.sol +++ b/src/ports/ORMPPort.sol @@ -32,22 +32,6 @@ contract ORMPPort is Ownable2Step, UpgradeableApplication, BaseMessagePort, Port _setURI(uri); } - function setSender(address ormp) external onlyOwner { - _setSender(ormp); - } - - function setRecver(address ormp) external onlyOwner { - _setRecver(ormp); - } - - function setSenderConfig(address oracle, address relayer) external onlyOwner { - _setSenderConfig(oracle, relayer); - } - - function setRecverConfig(address oracle, address relayer) external onlyOwner { - _setRecverConfig(oracle, relayer); - } - function setToPort(uint256 _toChainId, address _toPortAddress) external onlyOwner { _setToPort(_toChainId, _toPortAddress); } diff --git a/src/ports/ORMPUpgradeableAndRetryablePort.sol b/src/ports/ORMPUpgradeableAndRetryablePort.sol new file mode 100644 index 0000000..74d5241 --- /dev/null +++ b/src/ports/ORMPUpgradeableAndRetryablePort.sol @@ -0,0 +1,153 @@ +// This file is part of Darwinia. +// Copyright (C) 2018-2023 Darwinia Network +// SPDX-License-Identifier: GPL-3.0 +// +// Darwinia is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Darwinia is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Darwinia. If not, see . + +pragma solidity ^0.8.17; + +import "./base/BaseMessagePort.sol"; +import "./base/PortLookup.sol"; +import "ORMP/src/interfaces/IORMP.sol"; +import "ORMP/src/user/UpgradeableApplication.sol"; +import "@openzeppelin/contracts/access/Ownable2Step.sol"; +import "@openzeppelin/contracts/security/ReentrancyGuard.sol"; + +contract ORMPUpgradeableAndRetryablePort is + Ownable2Step, + UpgradeableApplication, + BaseMessagePort, + PortLookup, + ReentrancyGuard +{ + /// msgHash => isFailed + mapping(bytes32 => bool) public fails; + + event MessageDispatchedFailure( + bytes32 indexed msgHash, bytes32 msgId, uint256 fromChainId, address fromDapp, address toDapp, bytes message + ); + event RetryFailedMessage(bytes32 indexed msgHash, bool result); + event ClearFailedMessage(bytes32 indexed msgHash); + + constructor(address dao, address ormp, string memory name) UpgradeableApplication(ormp) BaseMessagePort(name) { + _transferOwnership(dao); + } + + function setURI(string calldata uri) external onlyOwner { + _setURI(uri); + } + + function setSender(address ormp) external onlyOwner { + _setSender(ormp); + } + + function setRecver(address ormp) external onlyOwner { + _setRecver(ormp); + } + + function setSenderConfig(address oracle, address relayer) external onlyOwner { + _setSenderConfig(oracle, relayer); + } + + function setRecverConfig(address oracle, address relayer) external onlyOwner { + _setRecverConfig(oracle, relayer); + } + + function setToPort(uint256 _toChainId, address _toPortAddress) external onlyOwner { + _setToPort(_toChainId, _toPortAddress); + } + + function setFromPort(uint256 _fromChainId, address _fromPortAddress) external onlyOwner { + _setFromPort(_fromChainId, _fromPortAddress); + } + + function _send(address fromDapp, uint256 toChainId, address toDapp, bytes calldata message, bytes calldata params) + internal + override + { + (uint256 gasLimit, address refund, bytes memory ormpParams) = abi.decode(params, (uint256, address, bytes)); + bytes memory encoded = + abi.encodeWithSelector(ORMPUpgradeableAndRetryablePort.recv.selector, fromDapp, toDapp, message); + IORMP(sender).send{value: msg.value}( + toChainId, _checkedToPort(toChainId), gasLimit, encoded, refund, ormpParams + ); + } + + function recv(address fromDapp, address toDapp, bytes calldata message) external payable onlyORMP { + uint256 fromChainId = _fromChainId(); + require(_xmsgSender() == _checkedFromPort(fromChainId), "!auth"); + _recv(fromChainId, fromDapp, toDapp, message); + } + + function retryFailedMessage( + bytes32 msgId, + uint256 fromChainId, + address fromDapp, + address toDapp, + bytes calldata message + ) external payable nonReentrant returns (bool success) { + bytes32 msgHash = hashInfo(msgId, fromChainId, fromDapp, toDapp, message); + require(fails[msgHash] == true, "!failed"); + (success,) = toDapp.call{value: msg.value}(abi.encodePacked(message, fromChainId, fromDapp)); + if (success) { + delete fails[msgHash]; + } + emit RetryFailedMessage(msgHash, success); + } + + function clearFailedMessage( + bytes32 msgId, + uint256 fromChainId, + address fromDapp, + address toDapp, + bytes calldata message + ) external { + bytes32 msgHash = hashInfo(msgId, fromChainId, fromDapp, toDapp, message); + require(fails[msgHash] == true, "!failed"); + require(toDapp == msg.sender, "!auth"); + delete fails[msgHash]; + emit ClearFailedMessage(msgHash); + } + + /// NOTE: Due to gas-related issues, it is not guaranteed that failed messages will always be stored. + function _recv(uint256 fromChainId, address fromDapp, address toDapp, bytes memory message) internal override { + (bool success,) = toDapp.call{value: msg.value}(abi.encodePacked(message, fromChainId, fromDapp)); + if (!success) { + bytes32 msgId = _messageId(); + bytes32 msgHash = hashInfo(msgId, fromChainId, fromDapp, toDapp, message); + fails[msgHash] = true; + emit MessageDispatchedFailure(msgHash, msgId, fromChainId, fromDapp, toDapp, message); + } + } + + function hashInfo(bytes32 msgId, uint256 fromChainId, address fromDapp, address toDapp, bytes memory message) + internal + pure + returns (bytes32) + { + return keccak256(abi.encode(msgId, fromChainId, fromDapp, toDapp, message)); + } + + function fee(uint256 toChainId, address toDapp, bytes calldata message, bytes calldata params) + external + view + override + returns (uint256) + { + (uint256 gasLimit,, bytes memory ormpParams) = abi.decode(params, (uint256, address, bytes)); + bytes memory encoded = + abi.encodeWithSelector(ORMPUpgradeableAndRetryablePort.recv.selector, msg.sender, toDapp, message); + return IORMP(sender).fee(toChainId, address(this), gasLimit, encoded, ormpParams); + } +} diff --git a/src/ports/base/BaseMessagePort.sol b/src/ports/base/BaseMessagePort.sol index c678b06..7873210 100644 --- a/src/ports/base/BaseMessagePort.sol +++ b/src/ports/base/BaseMessagePort.sol @@ -48,15 +48,10 @@ abstract contract BaseMessagePort is IMessagePort, PortMetadata { /// @param fromDapp The message sender in source chain. /// @param toDapp The message receiver in dest chain. /// @param message The message body. - function _recv(uint256 fromChainId, address fromDapp, address toDapp, bytes memory message) - internal - returns (bytes memory) - { + function _recv(uint256 fromChainId, address fromDapp, address toDapp, bytes memory message) internal virtual { (bool success, bytes memory returndata) = toDapp.call{value: msg.value}(abi.encodePacked(message, fromChainId, fromDapp)); - if (success) { - return returndata; - } else { + if (!success) { revert MessageFailure(returndata); } } From 38183da629cd2690dc6ef72ad2763e621e9ffcc1 Mon Sep 17 00:00:00 2001 From: echo Date: Tue, 12 Mar 2024 16:32:43 +0800 Subject: [PATCH 04/39] revert --- script/test/ORMPPort.t.sol | 12 ++++++++++++ src/ports/ORMPPort.sol | 14 +++++++++----- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/script/test/ORMPPort.t.sol b/script/test/ORMPPort.t.sol index a28a394..723ff3a 100644 --- a/script/test/ORMPPort.t.sol +++ b/script/test/ORMPPort.t.sol @@ -36,6 +36,18 @@ contract ORMPPortTest is Test { ormpPort.setURI("https://test.uri"); } + function testSetAppConfig() public { + vm.prank(dao); + ormpPort.setAppConfig(address(0x2), address(0x3)); + UC memory uc = IORMP(vm.envOr("ORMP_ADDRESS", address(ormpProtocol))).getAppConfig(address(ormpPort)); + assertEq(uc.oracle, address(0x2)); + assertEq(uc.relayer, address(0x3)); + // Cannot + vm.expectRevert(bytes("Ownable: caller is not the owner")); + vm.prank(address(0)); + ormpPort.setSenderConfig(address(0x2), address(0x3)); + } + function testSetPort() public { // From port vm.prank(dao); diff --git a/src/ports/ORMPPort.sol b/src/ports/ORMPPort.sol index 6b8a20d..7d580df 100644 --- a/src/ports/ORMPPort.sol +++ b/src/ports/ORMPPort.sol @@ -20,11 +20,11 @@ pragma solidity ^0.8.17; import "./base/BaseMessagePort.sol"; import "./base/PortLookup.sol"; import "ORMP/src/interfaces/IORMP.sol"; -import "ORMP/src/user/UpgradeableApplication.sol"; +import "ORMP/src/user/Application.sol"; import "@openzeppelin/contracts/access/Ownable2Step.sol"; -contract ORMPPort is Ownable2Step, UpgradeableApplication, BaseMessagePort, PortLookup { - constructor(address dao, address ormp, string memory name) UpgradeableApplication(ormp) BaseMessagePort(name) { +contract ORMPPort is Ownable2Step, Application, BaseMessagePort, PortLookup { + constructor(address dao, address ormp, string memory name) Application(ormp) BaseMessagePort(name) { _transferOwnership(dao); } @@ -32,6 +32,10 @@ contract ORMPPort is Ownable2Step, UpgradeableApplication, BaseMessagePort, Port _setURI(uri); } + function setAppConfig(address oracle, address relayer) external onlyOwner { + _setAppConfig(oracle, relayer); + } + function setToPort(uint256 _toChainId, address _toPortAddress) external onlyOwner { _setToPort(_toChainId, _toPortAddress); } @@ -46,7 +50,7 @@ contract ORMPPort is Ownable2Step, UpgradeableApplication, BaseMessagePort, Port { (uint256 gasLimit, address refund, bytes memory ormpParams) = abi.decode(params, (uint256, address, bytes)); bytes memory encoded = abi.encodeWithSelector(ORMPPort.recv.selector, fromDapp, toDapp, message); - IORMP(sender).send{value: msg.value}( + IORMP(TRUSTED_ORMP).send{value: msg.value}( toChainId, _checkedToPort(toChainId), gasLimit, encoded, refund, ormpParams ); } @@ -65,6 +69,6 @@ contract ORMPPort is Ownable2Step, UpgradeableApplication, BaseMessagePort, Port { (uint256 gasLimit,, bytes memory ormpParams) = abi.decode(params, (uint256, address, bytes)); bytes memory encoded = abi.encodeWithSelector(ORMPPort.recv.selector, msg.sender, toDapp, message); - return IORMP(sender).fee(toChainId, address(this), gasLimit, encoded, ormpParams); + return IORMP(TRUSTED_ORMP).fee(toChainId, address(this), gasLimit, encoded, ormpParams); } } From 2b3703e162869d3b8327e6338a350f98a2761150 Mon Sep 17 00:00:00 2001 From: echo Date: Tue, 12 Mar 2024 16:33:28 +0800 Subject: [PATCH 05/39] revert --- script/test/ORMPPort.t.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/script/test/ORMPPort.t.sol b/script/test/ORMPPort.t.sol index 723ff3a..e7ce656 100644 --- a/script/test/ORMPPort.t.sol +++ b/script/test/ORMPPort.t.sol @@ -45,7 +45,7 @@ contract ORMPPortTest is Test { // Cannot vm.expectRevert(bytes("Ownable: caller is not the owner")); vm.prank(address(0)); - ormpPort.setSenderConfig(address(0x2), address(0x3)); + ormpPort.setAppConfig(address(0x2), address(0x3)); } function testSetPort() public { From 07697243cc5036867921e8e41d7a12ffefbd8418 Mon Sep 17 00:00:00 2001 From: echo Date: Tue, 12 Mar 2024 17:23:31 +0800 Subject: [PATCH 06/39] refactor --- lib/ORMP | 2 +- src/ports/ORMPPort.sol | 15 ++-- src/ports/ORMPUpgradeableAndRetryablePort.sol | 72 +++++-------------- 3 files changed, 25 insertions(+), 64 deletions(-) diff --git a/lib/ORMP b/lib/ORMP index 3b94699..cdc9d5c 160000 --- a/lib/ORMP +++ b/lib/ORMP @@ -1 +1 @@ -Subproject commit 3b9469971551aecda8e1ceaae79d0657a205dc48 +Subproject commit cdc9d5c810112beac23c3b8729a9743c99acf19b diff --git a/src/ports/ORMPPort.sol b/src/ports/ORMPPort.sol index 7d580df..867587a 100644 --- a/src/ports/ORMPPort.sol +++ b/src/ports/ORMPPort.sol @@ -28,19 +28,19 @@ contract ORMPPort is Ownable2Step, Application, BaseMessagePort, PortLookup { _transferOwnership(dao); } - function setURI(string calldata uri) external onlyOwner { + function setURI(string calldata uri) external virtual onlyOwner { _setURI(uri); } - function setAppConfig(address oracle, address relayer) external onlyOwner { + function setAppConfig(address oracle, address relayer) external virtual onlyOwner { _setAppConfig(oracle, relayer); } - function setToPort(uint256 _toChainId, address _toPortAddress) external onlyOwner { + function setToPort(uint256 _toChainId, address _toPortAddress) external virtual onlyOwner { _setToPort(_toChainId, _toPortAddress); } - function setFromPort(uint256 _fromChainId, address _fromPortAddress) external onlyOwner { + function setFromPort(uint256 _fromChainId, address _fromPortAddress) external virtual onlyOwner { _setFromPort(_fromChainId, _fromPortAddress); } @@ -50,12 +50,12 @@ contract ORMPPort is Ownable2Step, Application, BaseMessagePort, PortLookup { { (uint256 gasLimit, address refund, bytes memory ormpParams) = abi.decode(params, (uint256, address, bytes)); bytes memory encoded = abi.encodeWithSelector(ORMPPort.recv.selector, fromDapp, toDapp, message); - IORMP(TRUSTED_ORMP).send{value: msg.value}( + IORMP(ormpSender()).send{value: msg.value}( toChainId, _checkedToPort(toChainId), gasLimit, encoded, refund, ormpParams ); } - function recv(address fromDapp, address toDapp, bytes calldata message) external payable onlyORMP { + function recv(address fromDapp, address toDapp, bytes calldata message) external payable onlyORMPRecver { uint256 fromChainId = _fromChainId(); require(_xmsgSender() == _checkedFromPort(fromChainId), "!auth"); _recv(fromChainId, fromDapp, toDapp, message); @@ -64,11 +64,12 @@ contract ORMPPort is Ownable2Step, Application, BaseMessagePort, PortLookup { function fee(uint256 toChainId, address toDapp, bytes calldata message, bytes calldata params) external view + virtual override returns (uint256) { (uint256 gasLimit,, bytes memory ormpParams) = abi.decode(params, (uint256, address, bytes)); bytes memory encoded = abi.encodeWithSelector(ORMPPort.recv.selector, msg.sender, toDapp, message); - return IORMP(TRUSTED_ORMP).fee(toChainId, address(this), gasLimit, encoded, ormpParams); + return IORMP(ormpSender()).fee(toChainId, address(this), gasLimit, encoded, ormpParams); } } diff --git a/src/ports/ORMPUpgradeableAndRetryablePort.sol b/src/ports/ORMPUpgradeableAndRetryablePort.sol index 74d5241..699a8a2 100644 --- a/src/ports/ORMPUpgradeableAndRetryablePort.sol +++ b/src/ports/ORMPUpgradeableAndRetryablePort.sol @@ -17,20 +17,11 @@ pragma solidity ^0.8.17; -import "./base/BaseMessagePort.sol"; -import "./base/PortLookup.sol"; -import "ORMP/src/interfaces/IORMP.sol"; -import "ORMP/src/user/UpgradeableApplication.sol"; -import "@openzeppelin/contracts/access/Ownable2Step.sol"; import "@openzeppelin/contracts/security/ReentrancyGuard.sol"; +import "ORMP/src/user/UpgradeableApplication.sol"; +import "./ORMPPort.sol"; -contract ORMPUpgradeableAndRetryablePort is - Ownable2Step, - UpgradeableApplication, - BaseMessagePort, - PortLookup, - ReentrancyGuard -{ +contract ORMPUpgradeableAndRetryablePort is ORMPPort, UpgradeableApplication, ReentrancyGuard { /// msgHash => isFailed mapping(bytes32 => bool) public fails; @@ -40,12 +31,19 @@ contract ORMPUpgradeableAndRetryablePort is event RetryFailedMessage(bytes32 indexed msgHash, bool result); event ClearFailedMessage(bytes32 indexed msgHash); - constructor(address dao, address ormp, string memory name) UpgradeableApplication(ormp) BaseMessagePort(name) { - _transferOwnership(dao); + constructor(address dao, address ormp, string memory name) ORMPPort(dao, ormp, name) UpgradeableApplication(ormp) {} + + function ormpSender() public view override(Application, UpgradeableApplication) returns (address) { + return super.ormpSender(); + } + + function ormpRecver() public view override(Application, UpgradeableApplication) returns (address) { + return super.ormpRecver(); } - function setURI(string calldata uri) external onlyOwner { - _setURI(uri); + function setAppConfig(address oracle, address relayer) external override onlyOwner { + setSenderConfig(oracle, relayer); + setRecverConfig(oracle, relayer); } function setSender(address ormp) external onlyOwner { @@ -56,40 +54,14 @@ contract ORMPUpgradeableAndRetryablePort is _setRecver(ormp); } - function setSenderConfig(address oracle, address relayer) external onlyOwner { + function setSenderConfig(address oracle, address relayer) public onlyOwner { _setSenderConfig(oracle, relayer); } - function setRecverConfig(address oracle, address relayer) external onlyOwner { + function setRecverConfig(address oracle, address relayer) public onlyOwner { _setRecverConfig(oracle, relayer); } - function setToPort(uint256 _toChainId, address _toPortAddress) external onlyOwner { - _setToPort(_toChainId, _toPortAddress); - } - - function setFromPort(uint256 _fromChainId, address _fromPortAddress) external onlyOwner { - _setFromPort(_fromChainId, _fromPortAddress); - } - - function _send(address fromDapp, uint256 toChainId, address toDapp, bytes calldata message, bytes calldata params) - internal - override - { - (uint256 gasLimit, address refund, bytes memory ormpParams) = abi.decode(params, (uint256, address, bytes)); - bytes memory encoded = - abi.encodeWithSelector(ORMPUpgradeableAndRetryablePort.recv.selector, fromDapp, toDapp, message); - IORMP(sender).send{value: msg.value}( - toChainId, _checkedToPort(toChainId), gasLimit, encoded, refund, ormpParams - ); - } - - function recv(address fromDapp, address toDapp, bytes calldata message) external payable onlyORMP { - uint256 fromChainId = _fromChainId(); - require(_xmsgSender() == _checkedFromPort(fromChainId), "!auth"); - _recv(fromChainId, fromDapp, toDapp, message); - } - function retryFailedMessage( bytes32 msgId, uint256 fromChainId, @@ -138,16 +110,4 @@ contract ORMPUpgradeableAndRetryablePort is { return keccak256(abi.encode(msgId, fromChainId, fromDapp, toDapp, message)); } - - function fee(uint256 toChainId, address toDapp, bytes calldata message, bytes calldata params) - external - view - override - returns (uint256) - { - (uint256 gasLimit,, bytes memory ormpParams) = abi.decode(params, (uint256, address, bytes)); - bytes memory encoded = - abi.encodeWithSelector(ORMPUpgradeableAndRetryablePort.recv.selector, msg.sender, toDapp, message); - return IORMP(sender).fee(toChainId, address(this), gasLimit, encoded, ormpParams); - } } From 5124b02d11a5737111dd4f5abde299494ce03c76 Mon Sep 17 00:00:00 2001 From: echo Date: Tue, 12 Mar 2024 17:24:47 +0800 Subject: [PATCH 07/39] doc --- src/ports/ORMPUpgradeableAndRetryablePort.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ports/ORMPUpgradeableAndRetryablePort.sol b/src/ports/ORMPUpgradeableAndRetryablePort.sol index 699a8a2..a888782 100644 --- a/src/ports/ORMPUpgradeableAndRetryablePort.sol +++ b/src/ports/ORMPUpgradeableAndRetryablePort.sol @@ -92,7 +92,7 @@ contract ORMPUpgradeableAndRetryablePort is ORMPPort, UpgradeableApplication, Re emit ClearFailedMessage(msgHash); } - /// NOTE: Due to gas-related issues, it is not guaranteed that failed messages will always be stored. + /// NOTE: Due to gas-related issues on arbitrum, it is not guaranteed that failed messages will always be stored. function _recv(uint256 fromChainId, address fromDapp, address toDapp, bytes memory message) internal override { (bool success,) = toDapp.call{value: msg.value}(abi.encodePacked(message, fromChainId, fromDapp)); if (!success) { From bfc644c5d8d88a6b2bf64cd7f439c69b64e8eb8f Mon Sep 17 00:00:00 2001 From: echo Date: Wed, 13 Mar 2024 11:37:57 +0800 Subject: [PATCH 08/39] retryable ormp port --- lib/ORMP | 2 +- src/ports/ORMPPort.sol | 6 +- src/ports/ORMPUpgradeableAndRetryablePort.sol | 80 ++++++++----------- 3 files changed, 37 insertions(+), 51 deletions(-) diff --git a/lib/ORMP b/lib/ORMP index cdc9d5c..86a3aea 160000 --- a/lib/ORMP +++ b/lib/ORMP @@ -1 +1 @@ -Subproject commit cdc9d5c810112beac23c3b8729a9743c99acf19b +Subproject commit 86a3aead36d0da2397b185b9b4be02f45f335232 diff --git a/src/ports/ORMPPort.sol b/src/ports/ORMPPort.sol index 867587a..1c640df 100644 --- a/src/ports/ORMPPort.sol +++ b/src/ports/ORMPPort.sol @@ -49,13 +49,13 @@ contract ORMPPort is Ownable2Step, Application, BaseMessagePort, PortLookup { override { (uint256 gasLimit, address refund, bytes memory ormpParams) = abi.decode(params, (uint256, address, bytes)); - bytes memory encoded = abi.encodeWithSelector(ORMPPort.recv.selector, fromDapp, toDapp, message); + bytes memory encoded = abi.encodeWithSelector(this.recv.selector, fromDapp, toDapp, message); IORMP(ormpSender()).send{value: msg.value}( toChainId, _checkedToPort(toChainId), gasLimit, encoded, refund, ormpParams ); } - function recv(address fromDapp, address toDapp, bytes calldata message) external payable onlyORMPRecver { + function recv(address fromDapp, address toDapp, bytes memory message) public payable virtual onlyORMPRecver { uint256 fromChainId = _fromChainId(); require(_xmsgSender() == _checkedFromPort(fromChainId), "!auth"); _recv(fromChainId, fromDapp, toDapp, message); @@ -69,7 +69,7 @@ contract ORMPPort is Ownable2Step, Application, BaseMessagePort, PortLookup { returns (uint256) { (uint256 gasLimit,, bytes memory ormpParams) = abi.decode(params, (uint256, address, bytes)); - bytes memory encoded = abi.encodeWithSelector(ORMPPort.recv.selector, msg.sender, toDapp, message); + bytes memory encoded = abi.encodeWithSelector(this.recv.selector, msg.sender, toDapp, message); return IORMP(ormpSender()).fee(toChainId, address(this), gasLimit, encoded, ormpParams); } } diff --git a/src/ports/ORMPUpgradeableAndRetryablePort.sol b/src/ports/ORMPUpgradeableAndRetryablePort.sol index a888782..aa5b786 100644 --- a/src/ports/ORMPUpgradeableAndRetryablePort.sol +++ b/src/ports/ORMPUpgradeableAndRetryablePort.sol @@ -22,13 +22,10 @@ import "ORMP/src/user/UpgradeableApplication.sol"; import "./ORMPPort.sol"; contract ORMPUpgradeableAndRetryablePort is ORMPPort, UpgradeableApplication, ReentrancyGuard { - /// msgHash => isFailed - mapping(bytes32 => bool) public fails; + /// @dev msgHash => isDispathedInPort. + mapping(bytes32 => bool) public dones; - event MessageDispatchedFailure( - bytes32 indexed msgHash, bytes32 msgId, uint256 fromChainId, address fromDapp, address toDapp, bytes message - ); - event RetryFailedMessage(bytes32 indexed msgHash, bool result); + event MessageDispatchedInPort(bytes32 indexed msgHash); event ClearFailedMessage(bytes32 indexed msgHash); constructor(address dao, address ormp, string memory name) ORMPPort(dao, ormp, name) UpgradeableApplication(ormp) {} @@ -62,52 +59,41 @@ contract ORMPUpgradeableAndRetryablePort is ORMPPort, UpgradeableApplication, Re _setRecverConfig(oracle, relayer); } - function retryFailedMessage( - bytes32 msgId, - uint256 fromChainId, - address fromDapp, - address toDapp, - bytes calldata message - ) external payable nonReentrant returns (bool success) { - bytes32 msgHash = hashInfo(msgId, fromChainId, fromDapp, toDapp, message); - require(fails[msgHash] == true, "!failed"); - (success,) = toDapp.call{value: msg.value}(abi.encodePacked(message, fromChainId, fromDapp)); - if (success) { - delete fails[msgHash]; - } - emit RetryFailedMessage(msgHash, success); + function retryFailedMessage(Message calldata message) external payable nonReentrant { + bytes32 msgHash = _checkMessage(message); + (, address fromDapp, address toDapp, bytes memory payload) = + abi.decode(message.encoded, (bytes4, address, address, bytes)); + _recv(message.fromChainId, fromDapp, toDapp, payload); + _markDone(msgHash); } - function clearFailedMessage( - bytes32 msgId, - uint256 fromChainId, - address fromDapp, - address toDapp, - bytes calldata message - ) external { - bytes32 msgHash = hashInfo(msgId, fromChainId, fromDapp, toDapp, message); - require(fails[msgHash] == true, "!failed"); - require(toDapp == msg.sender, "!auth"); - delete fails[msgHash]; - emit ClearFailedMessage(msgHash); + function _checkMessage(Message calldata message) internal view returns (bytes32 msgHash) { + msgHash = hash(message); + require(IORMP(ormpRecver()).dones(msgHash) == true, "!done"); + require(LOCAL_CHAINID() == message.toChainId, "!toChainId"); + require(address(this) == message.to, "!to"); + uint256 fromChainId = message.fromChainId; + require(message.from == _checkedFromPort(fromChainId), "!auth"); + } + + function _markDone(bytes32 msgHash) internal { + dones[msgHash] = true; + emit MessageDispatchedInPort(msgHash); } - /// NOTE: Due to gas-related issues on arbitrum, it is not guaranteed that failed messages will always be stored. - function _recv(uint256 fromChainId, address fromDapp, address toDapp, bytes memory message) internal override { - (bool success,) = toDapp.call{value: msg.value}(abi.encodePacked(message, fromChainId, fromDapp)); - if (!success) { - bytes32 msgId = _messageId(); - bytes32 msgHash = hashInfo(msgId, fromChainId, fromDapp, toDapp, message); - fails[msgHash] = true; - emit MessageDispatchedFailure(msgHash, msgId, fromChainId, fromDapp, toDapp, message); - } + function recv(address fromDapp, address toDapp, bytes memory message) public payable override { + super.recv(fromDapp, toDapp, message); + bytes32 msgHash = _messageId(); + _markDone(msgHash); } - function hashInfo(bytes32 msgId, uint256 fromChainId, address fromDapp, address toDapp, bytes memory message) - internal - pure - returns (bytes32) - { - return keccak256(abi.encode(msgId, fromChainId, fromDapp, toDapp, message)); + function clearFailedMessage(Message calldata message) external { + bytes32 msgHash = _checkMessage(message); + _clear(msgHash); + } + + function _clear(bytes32 msgHash) internal { + dones[msgHash] = true; + emit ClearFailedMessage(msgHash); } } From 610ec2c7b3475530d58549323ae615ef53e52b97 Mon Sep 17 00:00:00 2001 From: echo Date: Wed, 13 Mar 2024 11:41:29 +0800 Subject: [PATCH 09/39] retryable ormp port --- src/ports/ORMPUpgradeableAndRetryablePort.sol | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ports/ORMPUpgradeableAndRetryablePort.sol b/src/ports/ORMPUpgradeableAndRetryablePort.sol index aa5b786..f6dff4c 100644 --- a/src/ports/ORMPUpgradeableAndRetryablePort.sol +++ b/src/ports/ORMPUpgradeableAndRetryablePort.sol @@ -70,6 +70,7 @@ contract ORMPUpgradeableAndRetryablePort is ORMPPort, UpgradeableApplication, Re function _checkMessage(Message calldata message) internal view returns (bytes32 msgHash) { msgHash = hash(message); require(IORMP(ormpRecver()).dones(msgHash) == true, "!done"); + require(dones[msgHash] == false, "done"); require(LOCAL_CHAINID() == message.toChainId, "!toChainId"); require(address(this) == message.to, "!to"); uint256 fromChainId = message.fromChainId; From 5f3f38c8553fc4d68cea19671f13a677d2f90c72 Mon Sep 17 00:00:00 2001 From: echo Date: Wed, 13 Mar 2024 11:43:21 +0800 Subject: [PATCH 10/39] revert base changes --- src/ports/base/BaseMessagePort.sol | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/ports/base/BaseMessagePort.sol b/src/ports/base/BaseMessagePort.sol index 7873210..c678b06 100644 --- a/src/ports/base/BaseMessagePort.sol +++ b/src/ports/base/BaseMessagePort.sol @@ -48,10 +48,15 @@ abstract contract BaseMessagePort is IMessagePort, PortMetadata { /// @param fromDapp The message sender in source chain. /// @param toDapp The message receiver in dest chain. /// @param message The message body. - function _recv(uint256 fromChainId, address fromDapp, address toDapp, bytes memory message) internal virtual { + function _recv(uint256 fromChainId, address fromDapp, address toDapp, bytes memory message) + internal + returns (bytes memory) + { (bool success, bytes memory returndata) = toDapp.call{value: msg.value}(abi.encodePacked(message, fromChainId, fromDapp)); - if (!success) { + if (success) { + return returndata; + } else { revert MessageFailure(returndata); } } From b9e50a64f678ac042f42543efd2516ca28f8a1f5 Mon Sep 17 00:00:00 2001 From: echo Date: Wed, 13 Mar 2024 11:48:33 +0800 Subject: [PATCH 11/39] check auth when clear --- src/ports/ORMPUpgradeableAndRetryablePort.sol | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/ports/ORMPUpgradeableAndRetryablePort.sol b/src/ports/ORMPUpgradeableAndRetryablePort.sol index f6dff4c..986d077 100644 --- a/src/ports/ORMPUpgradeableAndRetryablePort.sol +++ b/src/ports/ORMPUpgradeableAndRetryablePort.sol @@ -74,7 +74,7 @@ contract ORMPUpgradeableAndRetryablePort is ORMPPort, UpgradeableApplication, Re require(LOCAL_CHAINID() == message.toChainId, "!toChainId"); require(address(this) == message.to, "!to"); uint256 fromChainId = message.fromChainId; - require(message.from == _checkedFromPort(fromChainId), "!auth"); + require(message.from == _checkedFromPort(fromChainId), "!xAuth"); } function _markDone(bytes32 msgHash) internal { @@ -89,6 +89,7 @@ contract ORMPUpgradeableAndRetryablePort is ORMPPort, UpgradeableApplication, Re } function clearFailedMessage(Message calldata message) external { + require(message.to == msg.sender, "!auth"); bytes32 msgHash = _checkMessage(message); _clear(msgHash); } From b7ea269dff11645e71703d7b7b0758045f613c0a Mon Sep 17 00:00:00 2001 From: echo Date: Wed, 13 Mar 2024 11:51:02 +0800 Subject: [PATCH 12/39] check auth when clear --- src/ports/ORMPUpgradeableAndRetryablePort.sol | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/ports/ORMPUpgradeableAndRetryablePort.sol b/src/ports/ORMPUpgradeableAndRetryablePort.sol index 986d077..e8a53db 100644 --- a/src/ports/ORMPUpgradeableAndRetryablePort.sol +++ b/src/ports/ORMPUpgradeableAndRetryablePort.sol @@ -89,8 +89,9 @@ contract ORMPUpgradeableAndRetryablePort is ORMPPort, UpgradeableApplication, Re } function clearFailedMessage(Message calldata message) external { - require(message.to == msg.sender, "!auth"); bytes32 msgHash = _checkMessage(message); + (,, address toDapp,) = abi.decode(message.encoded, (bytes4, address, address, bytes)); + require(toDapp == msg.sender, "!auth"); _clear(msgHash); } From 8ceb33ef0299a568461087469466f12cdddee4b9 Mon Sep 17 00:00:00 2001 From: echo Date: Wed, 13 Mar 2024 12:07:21 +0800 Subject: [PATCH 13/39] prevent replay --- src/ports/ORMPUpgradeableAndRetryablePort.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ports/ORMPUpgradeableAndRetryablePort.sol b/src/ports/ORMPUpgradeableAndRetryablePort.sol index e8a53db..38d5c7d 100644 --- a/src/ports/ORMPUpgradeableAndRetryablePort.sol +++ b/src/ports/ORMPUpgradeableAndRetryablePort.sol @@ -70,7 +70,6 @@ contract ORMPUpgradeableAndRetryablePort is ORMPPort, UpgradeableApplication, Re function _checkMessage(Message calldata message) internal view returns (bytes32 msgHash) { msgHash = hash(message); require(IORMP(ormpRecver()).dones(msgHash) == true, "!done"); - require(dones[msgHash] == false, "done"); require(LOCAL_CHAINID() == message.toChainId, "!toChainId"); require(address(this) == message.to, "!to"); uint256 fromChainId = message.fromChainId; @@ -78,6 +77,7 @@ contract ORMPUpgradeableAndRetryablePort is ORMPPort, UpgradeableApplication, Re } function _markDone(bytes32 msgHash) internal { + require(dones[msgHash] == false, "done"); dones[msgHash] = true; emit MessageDispatchedInPort(msgHash); } From 7e96fd9e9abea9dfb8bd8a8091bb760760081653 Mon Sep 17 00:00:00 2001 From: echo Date: Wed, 13 Mar 2024 12:07:44 +0800 Subject: [PATCH 14/39] prevent replay --- src/ports/ORMPUpgradeableAndRetryablePort.sol | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ports/ORMPUpgradeableAndRetryablePort.sol b/src/ports/ORMPUpgradeableAndRetryablePort.sol index 38d5c7d..e95d39a 100644 --- a/src/ports/ORMPUpgradeableAndRetryablePort.sol +++ b/src/ports/ORMPUpgradeableAndRetryablePort.sol @@ -96,6 +96,7 @@ contract ORMPUpgradeableAndRetryablePort is ORMPPort, UpgradeableApplication, Re } function _clear(bytes32 msgHash) internal { + require(dones[msgHash] == false, "done"); dones[msgHash] = true; emit ClearFailedMessage(msgHash); } From db5b55f6a42a785a3f0ff6d270b45f20bdef1dda Mon Sep 17 00:00:00 2001 From: echo Date: Wed, 13 Mar 2024 12:16:45 +0800 Subject: [PATCH 15/39] simply --- lib/ORMP | 2 +- src/ports/ORMPPort.sol | 2 +- src/ports/ORMPUpgradeableAndRetryablePort.sol | 29 +++---------------- 3 files changed, 6 insertions(+), 27 deletions(-) diff --git a/lib/ORMP b/lib/ORMP index 86a3aea..c5f0ff0 160000 --- a/lib/ORMP +++ b/lib/ORMP @@ -1 +1 @@ -Subproject commit 86a3aead36d0da2397b185b9b4be02f45f335232 +Subproject commit c5f0ff0eef0c6a5d393e6ae91cf4a4ebe0b27da6 diff --git a/src/ports/ORMPPort.sol b/src/ports/ORMPPort.sol index 1c640df..1d7938c 100644 --- a/src/ports/ORMPPort.sol +++ b/src/ports/ORMPPort.sol @@ -55,7 +55,7 @@ contract ORMPPort is Ownable2Step, Application, BaseMessagePort, PortLookup { ); } - function recv(address fromDapp, address toDapp, bytes memory message) public payable virtual onlyORMPRecver { + function recv(address fromDapp, address toDapp, bytes memory message) public payable virtual onlyORMP { uint256 fromChainId = _fromChainId(); require(_xmsgSender() == _checkedFromPort(fromChainId), "!auth"); _recv(fromChainId, fromDapp, toDapp, message); diff --git a/src/ports/ORMPUpgradeableAndRetryablePort.sol b/src/ports/ORMPUpgradeableAndRetryablePort.sol index e95d39a..6bee478 100644 --- a/src/ports/ORMPUpgradeableAndRetryablePort.sol +++ b/src/ports/ORMPUpgradeableAndRetryablePort.sol @@ -30,33 +30,12 @@ contract ORMPUpgradeableAndRetryablePort is ORMPPort, UpgradeableApplication, Re constructor(address dao, address ormp, string memory name) ORMPPort(dao, ormp, name) UpgradeableApplication(ormp) {} - function ormpSender() public view override(Application, UpgradeableApplication) returns (address) { - return super.ormpSender(); + function protocol() public view override(Application, UpgradeableApplication) returns (address) { + return super.protocol(); } - function ormpRecver() public view override(Application, UpgradeableApplication) returns (address) { - return super.ormpRecver(); - } - - function setAppConfig(address oracle, address relayer) external override onlyOwner { - setSenderConfig(oracle, relayer); - setRecverConfig(oracle, relayer); - } - - function setSender(address ormp) external onlyOwner { - _setSender(ormp); - } - - function setRecver(address ormp) external onlyOwner { - _setRecver(ormp); - } - - function setSenderConfig(address oracle, address relayer) public onlyOwner { - _setSenderConfig(oracle, relayer); - } - - function setRecverConfig(address oracle, address relayer) public onlyOwner { - _setRecverConfig(oracle, relayer); + function setORMP(address ormp) external onlyOwner { + _setORMP(ormp); } function retryFailedMessage(Message calldata message) external payable nonReentrant { From b1779dc142ab1166759c8d9ef566ef6ebda92acd Mon Sep 17 00:00:00 2001 From: echo Date: Wed, 13 Mar 2024 12:18:21 +0800 Subject: [PATCH 16/39] simply --- src/ports/ORMPPort.sol | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/ports/ORMPPort.sol b/src/ports/ORMPPort.sol index 1d7938c..3ac1728 100644 --- a/src/ports/ORMPPort.sol +++ b/src/ports/ORMPPort.sol @@ -28,19 +28,19 @@ contract ORMPPort is Ownable2Step, Application, BaseMessagePort, PortLookup { _transferOwnership(dao); } - function setURI(string calldata uri) external virtual onlyOwner { + function setURI(string calldata uri) external onlyOwner { _setURI(uri); } - function setAppConfig(address oracle, address relayer) external virtual onlyOwner { + function setAppConfig(address oracle, address relayer) external onlyOwner { _setAppConfig(oracle, relayer); } - function setToPort(uint256 _toChainId, address _toPortAddress) external virtual onlyOwner { + function setToPort(uint256 _toChainId, address _toPortAddress) external onlyOwner { _setToPort(_toChainId, _toPortAddress); } - function setFromPort(uint256 _fromChainId, address _fromPortAddress) external virtual onlyOwner { + function setFromPort(uint256 _fromChainId, address _fromPortAddress) external onlyOwner { _setFromPort(_fromChainId, _fromPortAddress); } @@ -50,7 +50,7 @@ contract ORMPPort is Ownable2Step, Application, BaseMessagePort, PortLookup { { (uint256 gasLimit, address refund, bytes memory ormpParams) = abi.decode(params, (uint256, address, bytes)); bytes memory encoded = abi.encodeWithSelector(this.recv.selector, fromDapp, toDapp, message); - IORMP(ormpSender()).send{value: msg.value}( + IORMP(protocol()).send{value: msg.value}( toChainId, _checkedToPort(toChainId), gasLimit, encoded, refund, ormpParams ); } @@ -64,12 +64,11 @@ contract ORMPPort is Ownable2Step, Application, BaseMessagePort, PortLookup { function fee(uint256 toChainId, address toDapp, bytes calldata message, bytes calldata params) external view - virtual override returns (uint256) { (uint256 gasLimit,, bytes memory ormpParams) = abi.decode(params, (uint256, address, bytes)); bytes memory encoded = abi.encodeWithSelector(this.recv.selector, msg.sender, toDapp, message); - return IORMP(ormpSender()).fee(toChainId, address(this), gasLimit, encoded, ormpParams); + return IORMP(protocol()).fee(toChainId, address(this), gasLimit, encoded, ormpParams); } } From 417b07c10c9a683fa65f400a438c5a0b3067cf39 Mon Sep 17 00:00:00 2001 From: echo Date: Wed, 13 Mar 2024 12:24:11 +0800 Subject: [PATCH 17/39] simply --- lib/ORMP | 2 +- src/ports/ORMPPort.sol | 2 +- src/ports/ORMPUpgradeableAndRetryablePort.sol | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/ORMP b/lib/ORMP index c5f0ff0..e0aeb25 160000 --- a/lib/ORMP +++ b/lib/ORMP @@ -1 +1 @@ -Subproject commit c5f0ff0eef0c6a5d393e6ae91cf4a4ebe0b27da6 +Subproject commit e0aeb254ea24a1a9d79368e1cbebe9f3de5d98a8 diff --git a/src/ports/ORMPPort.sol b/src/ports/ORMPPort.sol index 3ac1728..6129a64 100644 --- a/src/ports/ORMPPort.sol +++ b/src/ports/ORMPPort.sol @@ -55,7 +55,7 @@ contract ORMPPort is Ownable2Step, Application, BaseMessagePort, PortLookup { ); } - function recv(address fromDapp, address toDapp, bytes memory message) public payable virtual onlyORMP { + function recv(address fromDapp, address toDapp, bytes calldata message) public payable virtual onlyORMP { uint256 fromChainId = _fromChainId(); require(_xmsgSender() == _checkedFromPort(fromChainId), "!auth"); _recv(fromChainId, fromDapp, toDapp, message); diff --git a/src/ports/ORMPUpgradeableAndRetryablePort.sol b/src/ports/ORMPUpgradeableAndRetryablePort.sol index 6bee478..a45dfc9 100644 --- a/src/ports/ORMPUpgradeableAndRetryablePort.sol +++ b/src/ports/ORMPUpgradeableAndRetryablePort.sol @@ -48,7 +48,7 @@ contract ORMPUpgradeableAndRetryablePort is ORMPPort, UpgradeableApplication, Re function _checkMessage(Message calldata message) internal view returns (bytes32 msgHash) { msgHash = hash(message); - require(IORMP(ormpRecver()).dones(msgHash) == true, "!done"); + require(IORMP(protocol()).dones(msgHash) == true, "!done"); require(LOCAL_CHAINID() == message.toChainId, "!toChainId"); require(address(this) == message.to, "!to"); uint256 fromChainId = message.fromChainId; @@ -61,7 +61,7 @@ contract ORMPUpgradeableAndRetryablePort is ORMPPort, UpgradeableApplication, Re emit MessageDispatchedInPort(msgHash); } - function recv(address fromDapp, address toDapp, bytes memory message) public payable override { + function recv(address fromDapp, address toDapp, bytes calldata message) public payable override { super.recv(fromDapp, toDapp, message); bytes32 msgHash = _messageId(); _markDone(msgHash); From 5e16b3452cc1054d4e5a9e3bd608ace6bb95fe02 Mon Sep 17 00:00:00 2001 From: echo Date: Wed, 13 Mar 2024 23:12:31 +0800 Subject: [PATCH 18/39] deploy ormp ur --- SUPPORTED.md | 7 +- bin/config.sh | 20 +++-- bin/deploy.sh | 6 ++ script/deploy/DeployORMPURPort.s.sol | 78 +++++++++++++++++++ .../input/11155111/deploy_ormp_ur_port.c.json | 7 ++ .../input/421614/deploy_ormp_ur_port.c.json | 7 ++ script/input/43/deploy_ormp_ur_port.c.json | 7 ++ script/input/c3.json | 2 + .../deploy_ormp_ur_port.a-latest.json | 4 + .../421614/deploy_ormp_ur_port.a-latest.json | 4 + .../43/deploy_ormp_ur_port.a-latest.json | 4 + 11 files changed, 136 insertions(+), 10 deletions(-) create mode 100644 script/deploy/DeployORMPURPort.s.sol create mode 100644 script/input/11155111/deploy_ormp_ur_port.c.json create mode 100644 script/input/421614/deploy_ormp_ur_port.c.json create mode 100644 script/input/43/deploy_ormp_ur_port.c.json create mode 100644 script/output/11155111/deploy_ormp_ur_port.a-latest.json create mode 100644 script/output/421614/deploy_ormp_ur_port.a-latest.json create mode 100644 script/output/43/deploy_ormp_ur_port.a-latest.json diff --git a/SUPPORTED.md b/SUPPORTED.md index 0b5c2f2..97afe43 100644 --- a/SUPPORTED.md +++ b/SUPPORTED.md @@ -1,7 +1,8 @@ ## Canonical Cross-chain Deployment Addresses -| Port | Name | Canonical Cross-chain Deployment Address | -|----------|---------|--------------------------------------------| -| ORMPPort | ORMP | 0x0000000005d961F950adA391C1511c92bbc64D9F | +| Port | Name | Canonical Cross-chain Deployment Address | +|---------------------------------|------------|--------------------------------------------| +| ORMPPort | ORMP | 0x0000000005d961F950adA391C1511c92bbc64D9F | +| ORMPUpgradeableAndRetryablePort | ORMP-UR | 0x000000000EA450D971d3A68c754Fb5C212d3101b | ## Supported Chains ### Mainnet diff --git a/bin/config.sh b/bin/config.sh index b9866fb..eeeca7f 100755 --- a/bin/config.sh +++ b/bin/config.sh @@ -15,15 +15,21 @@ get_uri() { # forge script script/config/PortConfig.s.sol:PortConfig --sig "run(uint256[],string)" "[11155111,44]" $uri --chain-id 421614 --broadcast --skip-simulation --legacy # forge script script/config/PortConfig.s.sol:PortConfig --sig "run(uint256[],string)" "[44,421614]" $uri --chain-id 11155111 --broadcast -export PORT_KEY="MULTIPORT_ADDR" -uri=$(get_uri "QmQsKZG4SSbqZ12a1VpZRsURrHbRe5mVbZZQ7GmLs42ZRN") -forge script script/config/PortConfig.s.sol:PortConfig --sig "run(uint256[],string)" "[421614,11155111]" $uri --chain-id 43 --broadcast -g 200 -forge script script/config/PortConfig.s.sol:PortConfig --sig "run(uint256[],string)" "[11155111,44]" $uri --chain-id 421614 --broadcast --skip-simulation --legacy +export PORT_KEY="ORMPURPORT_ADDR" +uri=$(get_uri "QmX8rYZP1u5paFfJdaEe75DLdZXmjs8FSkC7mrN6vefc32") +# forge script script/config/PortConfig.s.sol:PortConfig --sig "run(uint256[],string)" "[421614,11155111]" $uri --chain-id 43 --broadcast -g 200 +forge script script/config/PortConfig.s.sol:PortConfig --sig "run(uint256[],string)" "[11155111,44]" $uri --chain-id 421614 --broadcast --skip-simulation forge script script/config/PortConfig.s.sol:PortConfig --sig "run(uint256[],string)" "[44,421614]" $uri --chain-id 11155111 --broadcast -forge script script/config/MultiPortConfig.s.sol:MultiPortConfig --chain-id 43 --broadcast -g 200 -forge script script/config/MultiPortConfig.s.sol:MultiPortConfig --chain-id 421614 --broadcast --skip-simulation --legacy -forge script script/config/MultiPortConfig.s.sol:MultiPortConfig --chain-id 11155111 --broadcast +# export PORT_KEY="MULTIPORT_ADDR" +# uri=$(get_uri "QmQsKZG4SSbqZ12a1VpZRsURrHbRe5mVbZZQ7GmLs42ZRN") +# forge script script/config/PortConfig.s.sol:PortConfig --sig "run(uint256[],string)" "[421614,11155111]" $uri --chain-id 43 --broadcast -g 200 +# forge script script/config/PortConfig.s.sol:PortConfig --sig "run(uint256[],string)" "[11155111,44]" $uri --chain-id 421614 --broadcast --skip-simulation --legacy +# forge script script/config/PortConfig.s.sol:PortConfig --sig "run(uint256[],string)" "[44,421614]" $uri --chain-id 11155111 --broadcast +# +# forge script script/config/MultiPortConfig.s.sol:MultiPortConfig --chain-id 43 --broadcast -g 200 +# forge script script/config/MultiPortConfig.s.sol:MultiPortConfig --chain-id 421614 --broadcast --skip-simulation --legacy +# forge script script/config/MultiPortConfig.s.sol:MultiPortConfig --chain-id 11155111 --broadcast # export PORT_KEY="XACCOUNTFACTORY_ADDR" # uri=$(get_uri "QmahfNo9m9TqHUxARhug93Ubzn3HVutfQ9bDAxWq9ksJhy") diff --git a/bin/deploy.sh b/bin/deploy.sh index 5f29c4d..7142e20 100755 --- a/bin/deploy.sh +++ b/bin/deploy.sh @@ -22,10 +22,16 @@ set -eo pipefail # forge script script/deploy/DeployXAccountFactory.s.sol:DeployXAccountFactory --chain-id 11155111 --broadcast --verify --legacy # forge script script/deploy/DeployXAccountFactory.s.sol:DeployXAccountFactory --chain-id 43 --broadcast --verify +# Deploy ormp port on testnet # forge script script/deploy/DeployORMPPort.s.sol:DeployORMPPort --chain-id 43 --broadcast --verify --legacy --skip-simulation # forge script script/deploy/DeployORMPPort.s.sol:DeployORMPPort --chain-id 421614 --broadcast --verify --legacy --skip-simulation # forge script script/deploy/DeployORMPPort.s.sol:DeployORMPPort --chain-id 11155111 --broadcast --verify --legacy +# Deploy ormp-ur port on testnet +# forge script script/deploy/DeployORMPURPort.s.sol:DeployORMPURPort --chain-id 43 --broadcast --verify --legacy +# forge script script/deploy/DeployORMPURPort.s.sol:DeployORMPURPort --chain-id 421614 --broadcast --verify --legacy --skip-simulation +# forge script script/deploy/DeployORMPURPort.s.sol:DeployORMPURPort --chain-id 11155111 --broadcast --verify --legacy + # forge script script/deploy/DeployORMPPort.s.sol:DeployORMPPort --chain-id 1 --broadcast --verify --slow # forge script script/deploy/DeployORMPPort.s.sol:DeployORMPPort --chain-id 44 --broadcast --verify --slow # forge script script/deploy/DeployORMPPort.s.sol:DeployORMPPort --chain-id 46 --broadcast --verify --slow diff --git a/script/deploy/DeployORMPURPort.s.sol b/script/deploy/DeployORMPURPort.s.sol new file mode 100644 index 0000000..ee160ca --- /dev/null +++ b/script/deploy/DeployORMPURPort.s.sol @@ -0,0 +1,78 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.17; + +import {stdJson} from "forge-std/StdJson.sol"; +import {Script} from "forge-std/Script.sol"; +import {console2 as console} from "forge-std/console2.sol"; +import {Common} from "create3-deploy/script/Common.s.sol"; +import {ScriptTools} from "create3-deploy/script/ScriptTools.sol"; + +import "../../src/ports/ORMPUpgradeableAndRetryablePort.sol"; + +interface III { + function owner() external view returns (address); + function transferOwnership(address newOwner) external; + function pendingOwner() external view returns (address); +} + +contract DeployORMPURPort is Common { + using stdJson for string; + using ScriptTools for string; + + address ORMP; + address ADDR; + bytes32 SALT; + + string c3; + string config; + string instanceId; + string outputName; + address deployer; + address dao; + + function name() public pure override returns (string memory) { + return "DeployORMPURPort"; + } + + function setUp() public override { + super.setUp(); + + instanceId = vm.envOr("INSTANCE_ID", string("deploy_ormp_ur_port.c")); + outputName = "deploy_ormp_ur_port.a"; + config = ScriptTools.readInput(instanceId); + c3 = ScriptTools.readInput("../c3"); + ORMP = c3.readAddress(".ORMP_ADDR"); + ADDR = c3.readAddress(".ORMPURPORT_ADDR"); + SALT = c3.readBytes32(".ORMPURPORT_SALT"); + + deployer = config.readAddress(".DEPLOYER"); + dao = config.readAddress(".DAO"); + } + + function run() public { + require(deployer == msg.sender, "!deployer"); + + deploy(); + // setConfig(); + + ScriptTools.exportContract(outputName, "DAO", dao); + ScriptTools.exportContract(outputName, "ORMPUR_PORT", ADDR); + } + + function deploy() public broadcast returns (address) { + string memory name_ = config.readString(".metadata.name"); + bytes memory byteCode = type(ORMPPort).creationCode; + bytes memory initCode = bytes.concat(byteCode, abi.encode(deployer, ORMP, name_)); + address port = _deploy3(SALT, initCode); + require(port == ADDR, "!addr"); + require(III(ADDR).owner() == deployer); + console.log("ORMPPort deployed: %s", port); + return port; + } + + function setConfig() public broadcast { + III(ADDR).transferOwnership(dao); + require(III(ADDR).pendingOwner() == dao, "!dao"); + // TODO:: dao.acceptOwnership() + } +} diff --git a/script/input/11155111/deploy_ormp_ur_port.c.json b/script/input/11155111/deploy_ormp_ur_port.c.json new file mode 100644 index 0000000..3723665 --- /dev/null +++ b/script/input/11155111/deploy_ormp_ur_port.c.json @@ -0,0 +1,7 @@ +{ + "DAO": "0x0f14341A7f464320319025540E8Fe48Ad0fe5aec", + "DEPLOYER": "0x0f14341A7f464320319025540E8Fe48Ad0fe5aec", + "metadata": { + "name": "ORMP-UR" + } +} diff --git a/script/input/421614/deploy_ormp_ur_port.c.json b/script/input/421614/deploy_ormp_ur_port.c.json new file mode 100644 index 0000000..3723665 --- /dev/null +++ b/script/input/421614/deploy_ormp_ur_port.c.json @@ -0,0 +1,7 @@ +{ + "DAO": "0x0f14341A7f464320319025540E8Fe48Ad0fe5aec", + "DEPLOYER": "0x0f14341A7f464320319025540E8Fe48Ad0fe5aec", + "metadata": { + "name": "ORMP-UR" + } +} diff --git a/script/input/43/deploy_ormp_ur_port.c.json b/script/input/43/deploy_ormp_ur_port.c.json new file mode 100644 index 0000000..3723665 --- /dev/null +++ b/script/input/43/deploy_ormp_ur_port.c.json @@ -0,0 +1,7 @@ +{ + "DAO": "0x0f14341A7f464320319025540E8Fe48Ad0fe5aec", + "DEPLOYER": "0x0f14341A7f464320319025540E8Fe48Ad0fe5aec", + "metadata": { + "name": "ORMP-UR" + } +} diff --git a/script/input/c3.json b/script/input/c3.json index edaa472..f037336 100644 --- a/script/input/c3.json +++ b/script/input/c3.json @@ -6,6 +6,8 @@ "PORTREGISTRY_SALT": "0xa9578bb3432e82a6797cc7ff405700ed7f45aee1737bf2b9c04a6f4054723395", "ORMPPORT_ADDR": "0x0000000005d961F950adA391C1511c92bbc64D9F", "ORMPPORT_SALT": "0xe9cab07c7534f6d34500c7fc83b0d4205012e3e7cc3c1cf1d74f67858d413740", + "ORMPURPORT_ADDR": "0x000000000EA450D971d3A68c754Fb5C212d3101b", + "ORMPURPORT_SALT": "0x6da6ca9d7ad25e6d11f456555cdb5b4bc167bbe4788d32b39d547daccdaf24b8", "MULTIPORT_ADDR": "0x00005e5FCC932F3a5B7A3665bC99Bab0d1Ff0477", "MULTIPORT_SALT": "0x55dd52ed08c902216c638e6c8768264718084b250c674379327aa7e2800a9ce2", "SAFEMSGPORTMODULE_ADDR": "0x0000BB6920aA050733b7e368FA7DF6d7FAA88142", diff --git a/script/output/11155111/deploy_ormp_ur_port.a-latest.json b/script/output/11155111/deploy_ormp_ur_port.a-latest.json new file mode 100644 index 0000000..8546379 --- /dev/null +++ b/script/output/11155111/deploy_ormp_ur_port.a-latest.json @@ -0,0 +1,4 @@ +{ + "DAO": "0x0f14341A7f464320319025540E8Fe48Ad0fe5aec", + "ORMPUR_PORT": "0x000000000EA450D971d3A68c754Fb5C212d3101b" +} \ No newline at end of file diff --git a/script/output/421614/deploy_ormp_ur_port.a-latest.json b/script/output/421614/deploy_ormp_ur_port.a-latest.json new file mode 100644 index 0000000..8546379 --- /dev/null +++ b/script/output/421614/deploy_ormp_ur_port.a-latest.json @@ -0,0 +1,4 @@ +{ + "DAO": "0x0f14341A7f464320319025540E8Fe48Ad0fe5aec", + "ORMPUR_PORT": "0x000000000EA450D971d3A68c754Fb5C212d3101b" +} \ No newline at end of file diff --git a/script/output/43/deploy_ormp_ur_port.a-latest.json b/script/output/43/deploy_ormp_ur_port.a-latest.json new file mode 100644 index 0000000..8546379 --- /dev/null +++ b/script/output/43/deploy_ormp_ur_port.a-latest.json @@ -0,0 +1,4 @@ +{ + "DAO": "0x0f14341A7f464320319025540E8Fe48Ad0fe5aec", + "ORMPUR_PORT": "0x000000000EA450D971d3A68c754Fb5C212d3101b" +} \ No newline at end of file From 4d2b8c8702caa3ff9e5713ae7a85ff4b869adcaa Mon Sep 17 00:00:00 2001 From: echo Date: Fri, 15 Mar 2024 23:04:17 +0800 Subject: [PATCH 19/39] upgrade lib ormp --- lib/ORMP | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/ORMP b/lib/ORMP index 8c63613..e0aeb25 160000 --- a/lib/ORMP +++ b/lib/ORMP @@ -1 +1 @@ -Subproject commit 8c6361392856bf5704c45e6be664f58a50221ac9 +Subproject commit e0aeb254ea24a1a9d79368e1cbebe9f3de5d98a8 From ce0a1f054e5e1791df994bc52a3163cf23b34d57 Mon Sep 17 00:00:00 2001 From: echo Date: Mon, 18 Mar 2024 14:25:31 +0800 Subject: [PATCH 20/39] fix --- script/input/c3.json | 1 - 1 file changed, 1 deletion(-) diff --git a/script/input/c3.json b/script/input/c3.json index 15f0ba5..4607028 100644 --- a/script/input/c3.json +++ b/script/input/c3.json @@ -14,5 +14,4 @@ "SAFEMSGPORTMODULE_SALT": "0xc565cc72ab6d4ee29f4513c7c1327c12daee2436d316ba1337e108528a17c186", "XACCOUNTFACTORY_ADDR": "0x0000FcFa1F8e3768e5ea55D60A02340dbCcB9dd1", "XACCOUNTFACTORY_SALT": "0xc0dbbd749dc02a6c33d0ae2d9df2206a2313d5a1b7a1356c56bbe8739514a6a0" ->>>>>>> main } From c040b11923735f59d5eee68549a50b4f589e2306 Mon Sep 17 00:00:00 2001 From: echo Date: Thu, 21 Mar 2024 22:14:30 +0800 Subject: [PATCH 21/39] upgradeable and retryable ormp port --- ...oyORMPPort.s.sol => DeployORMPUPort.s.sol} | 14 ++-- script/deploy/DeployORMPURPort.s.sol | 4 +- script/test/ORMPPort.t.sol | 10 +-- src/examples/ExampleRetryableDapp.sol | 49 +++++++++++++ src/interfaces/IMessagePortExt.sol | 25 +++++++ src/ports/ORMPUpgradeableAndRetryablePort.sol | 57 ++++++++------- .../{ORMPPort.sol => ORMPUpgradeablePort.sol} | 73 +++++++++++++++++-- 7 files changed, 182 insertions(+), 50 deletions(-) rename script/deploy/{DeployORMPPort.s.sol => DeployORMPUPort.s.sol} (85%) create mode 100644 src/examples/ExampleRetryableDapp.sol create mode 100644 src/interfaces/IMessagePortExt.sol rename src/ports/{ORMPPort.sol => ORMPUpgradeablePort.sol} (54%) diff --git a/script/deploy/DeployORMPPort.s.sol b/script/deploy/DeployORMPUPort.s.sol similarity index 85% rename from script/deploy/DeployORMPPort.s.sol rename to script/deploy/DeployORMPUPort.s.sol index c310c76..8d7d0bc 100644 --- a/script/deploy/DeployORMPPort.s.sol +++ b/script/deploy/DeployORMPUPort.s.sol @@ -7,7 +7,7 @@ import {console2 as console} from "forge-std/console2.sol"; import {Common} from "create3-deploy/script/Common.s.sol"; import {ScriptTools} from "create3-deploy/script/ScriptTools.sol"; -import "../../src/ports/ORMPPort.sol"; +import "../../src/ports/ORMPUpgradeablePort.sol"; interface III { function owner() external view returns (address); @@ -15,7 +15,7 @@ interface III { function pendingOwner() external view returns (address); } -contract DeployORMPPort is Common { +contract DeployORMPUPort is Common { using stdJson for string; using ScriptTools for string; @@ -31,7 +31,7 @@ contract DeployORMPPort is Common { address dao; function name() public pure override returns (string memory) { - return "DeployORMPPort"; + return "DeployORMPUPort"; } function setUp() public override { @@ -42,8 +42,8 @@ contract DeployORMPPort is Common { config = ScriptTools.readInput(instanceId); c3 = ScriptTools.readInput("../c3"); ORMP = c3.readAddress(".ORMP_ADDR"); - ADDR = c3.readAddress(".ORMPPORT_ADDR"); - SALT = c3.readBytes32(".ORMPPORT_SALT"); + ADDR = c3.readAddress(".ORMPUPORT_ADDR"); + SALT = c3.readBytes32(".ORMPUPORT_SALT"); deployer = config.readAddress(".DEPLOYER"); dao = config.readAddress(".DAO"); @@ -61,12 +61,12 @@ contract DeployORMPPort is Common { function deploy() public broadcast returns (address) { string memory name_ = config.readString(".metadata.name"); - bytes memory byteCode = type(ORMPPort).creationCode; + bytes memory byteCode = type(ORMPUpgradeablePort).creationCode; bytes memory initCode = bytes.concat(byteCode, abi.encode(deployer, ORMP, name_)); address port = _deploy3(SALT, initCode); require(port == ADDR, "!addr"); require(III(ADDR).owner() == deployer); - console.log("ORMPPort deployed: %s", port); + console.log("ORMPUpgradeablePort deployed: %s", port); return port; } diff --git a/script/deploy/DeployORMPURPort.s.sol b/script/deploy/DeployORMPURPort.s.sol index ee160ca..20744aa 100644 --- a/script/deploy/DeployORMPURPort.s.sol +++ b/script/deploy/DeployORMPURPort.s.sol @@ -61,12 +61,12 @@ contract DeployORMPURPort is Common { function deploy() public broadcast returns (address) { string memory name_ = config.readString(".metadata.name"); - bytes memory byteCode = type(ORMPPort).creationCode; + bytes memory byteCode = type(ORMPUpgradeableAndRetryablePort).creationCode; bytes memory initCode = bytes.concat(byteCode, abi.encode(deployer, ORMP, name_)); address port = _deploy3(SALT, initCode); require(port == ADDR, "!addr"); require(III(ADDR).owner() == deployer); - console.log("ORMPPort deployed: %s", port); + console.log("ORMPUpgradeableAndRetryablePort deployed: %s", port); return port; } diff --git a/script/test/ORMPPort.t.sol b/script/test/ORMPPort.t.sol index e7ce656..e7722cf 100644 --- a/script/test/ORMPPort.t.sol +++ b/script/test/ORMPPort.t.sol @@ -7,13 +7,13 @@ import "ORMP/src/ORMP.sol"; import "ORMP/src/interfaces/IORMP.sol"; import "ORMP/src/UserConfig.sol"; -import "../../src/ports/ORMPPort.sol"; +import "../../src/ports/ORMPUpgradeablePort.sol"; import "../../src/ports/base/FromPortLookup.sol"; contract ORMPPortTest is Test { using Chains for uint256; - ORMPPort ormpPort; + ORMPUpgradeablePort ormpPort; address dao; address ormpProtocol; @@ -22,7 +22,7 @@ contract ORMPPortTest is Test { vm.createSelectFork(chainId.toChainName()); dao = address(0x1); ormpProtocol = address(0x00000000001523057a05d6293C1e5171eE33eE0A); - ormpPort = new ORMPPort(dao, vm.envOr("ORMP_ADDRESS", address(ormpProtocol)), "ORMP"); + ormpPort = new ORMPUpgradeablePort(dao, vm.envOr("ORMP_ADDRESS", address(ormpProtocol)), "ORMP"); } function testSetUri() public { @@ -38,14 +38,14 @@ contract ORMPPortTest is Test { function testSetAppConfig() public { vm.prank(dao); - ormpPort.setAppConfig(address(0x2), address(0x3)); + ormpPort.setAppConfig(address(ormpPort), address(0x2), address(0x3)); UC memory uc = IORMP(vm.envOr("ORMP_ADDRESS", address(ormpProtocol))).getAppConfig(address(ormpPort)); assertEq(uc.oracle, address(0x2)); assertEq(uc.relayer, address(0x3)); // Cannot vm.expectRevert(bytes("Ownable: caller is not the owner")); vm.prank(address(0)); - ormpPort.setAppConfig(address(0x2), address(0x3)); + ormpPort.setAppConfig(address(ormpPort), address(0x2), address(0x3)); } function testSetPort() public { diff --git a/src/examples/ExampleRetryableDapp.sol b/src/examples/ExampleRetryableDapp.sol new file mode 100644 index 0000000..07a7237 --- /dev/null +++ b/src/examples/ExampleRetryableDapp.sol @@ -0,0 +1,49 @@ +// This file is part of Darwinia. +// Copyright (C) 2018-2023 Darwinia Network +// SPDX-License-Identifier: GPL-3.0 +// +// Darwinia is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Darwinia is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Darwinia. If not, see . + +pragma solidity ^0.8.17; + +import "@openzeppelin/contracts/security/ReentrancyGuard.sol"; +import "ORMP/src/Common.sol"; +import "../interfaces/IMessagePortExt.sol"; +import "./ExampleReceiverDapp.sol"; + +contract ExampleRetryableDapp is ExampleReceiverDapp, ReentrancyGuard { + uint256 public immutable FROM_CHAINID; + + constructor(address port, address dapp, uint256 fromChainId) ExampleReceiverDapp(port, dapp) { + FROM_CHAINID = fromChainId; + } + + // function retryFailedMessage(Message calldata message) external payable nonReentrant { + // msgHash = hash(message); + // require(IMessagePortExt(PORT).checkDeliveried(msgHash), "!delivery"); + // require(IMessagePortExt(PORT).checkCompleted(msgHash) == false, "completed"); + // require(message.toChainId == block.chainid, "!toChainId"); + // require(message.to == PORT, "!to"); + // require(message.fromChainId == FROM_CHAINID, "!fromChainId"); + // require(message.from == IMessagePortExt(PORT).fromPortLookup(FROM_CHAINID), "!port"); + // (bytes4, address fromDapp, address toDapp, bytes memory payload) = + // abi.decode(message.encoded, (bytes4, address, address, bytes)); + // require(fromDapp == DAPP, "!fromDapp"); + // require(toDapp == address(this), "!toDapp"); + // (bytes4 sig, bytes memory params) = abi.decode(payload, (bytes4, bytes)); + // require(sig == ExampleReceiverDapp.xxx.selector, "!sig"); + // // redo xxx. + // emit DappMessageRecv(FROM_CHAINID, DAPP, PORT, params); + // } +} diff --git a/src/interfaces/IMessagePortExt.sol b/src/interfaces/IMessagePortExt.sol new file mode 100644 index 0000000..5d986b2 --- /dev/null +++ b/src/interfaces/IMessagePortExt.sol @@ -0,0 +1,25 @@ +// This file is part of Darwinia. +// Copyright (C) 2018-2023 Darwinia Network +// SPDX-License-Identifier: GPL-3.0 +// +// Darwinia is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Darwinia is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Darwinia. If not, see . + +pragma solidity ^0.8.0; + +interface IMessagePortExt { + function checkDeliveried(bytes32 msgHash) external view returns (bool); + function checkCompleted(bytes32 msgHash) external view returns (bool); + function fromPortLookup(uint256 fromChainId) external view returns (address); + function toPortLookup(uint256 toChainId) external view returns (address); +} diff --git a/src/ports/ORMPUpgradeableAndRetryablePort.sol b/src/ports/ORMPUpgradeableAndRetryablePort.sol index a45dfc9..63b6885 100644 --- a/src/ports/ORMPUpgradeableAndRetryablePort.sol +++ b/src/ports/ORMPUpgradeableAndRetryablePort.sol @@ -18,27 +18,20 @@ pragma solidity ^0.8.17; import "@openzeppelin/contracts/security/ReentrancyGuard.sol"; -import "ORMP/src/user/UpgradeableApplication.sol"; -import "./ORMPPort.sol"; +import "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; +import "./ORMPUpgradeablePort.sol"; + +contract ORMPUpgradeableAndRetryablePort is ORMPUpgradeablePort, ReentrancyGuard { + using EnumerableSet for EnumerableSet.AddressSet; -contract ORMPUpgradeableAndRetryablePort is ORMPPort, UpgradeableApplication, ReentrancyGuard { /// @dev msgHash => isDispathedInPort. mapping(bytes32 => bool) public dones; event MessageDispatchedInPort(bytes32 indexed msgHash); - event ClearFailedMessage(bytes32 indexed msgHash); - - constructor(address dao, address ormp, string memory name) ORMPPort(dao, ormp, name) UpgradeableApplication(ormp) {} - - function protocol() public view override(Application, UpgradeableApplication) returns (address) { - return super.protocol(); - } - function setORMP(address ormp) external onlyOwner { - _setORMP(ormp); - } + constructor(address dao, address ormp, string memory name) ORMPUpgradeablePort(dao, ormp, name) {} - function retryFailedMessage(Message calldata message) external payable nonReentrant { + function retry(Message calldata message) external payable nonReentrant { bytes32 msgHash = _checkMessage(message); (, address fromDapp, address toDapp, bytes memory payload) = abi.decode(message.encoded, (bytes4, address, address, bytes)); @@ -46,9 +39,30 @@ contract ORMPUpgradeableAndRetryablePort is ORMPPort, UpgradeableApplication, Re _markDone(msgHash); } + function clear(Message calldata message) external { + bytes32 msgHash = _checkMessage(message); + (,, address toDapp,) = abi.decode(message.encoded, (bytes4, address, address, bytes)); + require(toDapp == msg.sender, "!auth"); + _clear(msgHash); + } + + function _clear(bytes32 msgHash) internal { + require(dones[msgHash] == false, "done"); + dones[msgHash] = true; + emit MessageDispatchedInPort(msgHash); + } + + function _checkDispathed(bytes32 msgHash) internal view { + uint256 len = historyORMPSet.length(); + for (uint256 i = 0; i < len; i++) { + address o = historyORMPSet.at(i); + require(IORMP(o).dones(msgHash), "!done"); + } + } + function _checkMessage(Message calldata message) internal view returns (bytes32 msgHash) { msgHash = hash(message); - require(IORMP(protocol()).dones(msgHash) == true, "!done"); + _checkDispathed(msgHash); require(LOCAL_CHAINID() == message.toChainId, "!toChainId"); require(address(this) == message.to, "!to"); uint256 fromChainId = message.fromChainId; @@ -66,17 +80,4 @@ contract ORMPUpgradeableAndRetryablePort is ORMPPort, UpgradeableApplication, Re bytes32 msgHash = _messageId(); _markDone(msgHash); } - - function clearFailedMessage(Message calldata message) external { - bytes32 msgHash = _checkMessage(message); - (,, address toDapp,) = abi.decode(message.encoded, (bytes4, address, address, bytes)); - require(toDapp == msg.sender, "!auth"); - _clear(msgHash); - } - - function _clear(bytes32 msgHash) internal { - require(dones[msgHash] == false, "done"); - dones[msgHash] = true; - emit ClearFailedMessage(msgHash); - } } diff --git a/src/ports/ORMPPort.sol b/src/ports/ORMPUpgradeablePort.sol similarity index 54% rename from src/ports/ORMPPort.sol rename to src/ports/ORMPUpgradeablePort.sol index 6129a64..01e9631 100644 --- a/src/ports/ORMPPort.sol +++ b/src/ports/ORMPUpgradeablePort.sol @@ -20,20 +20,61 @@ pragma solidity ^0.8.17; import "./base/BaseMessagePort.sol"; import "./base/PortLookup.sol"; import "ORMP/src/interfaces/IORMP.sol"; -import "ORMP/src/user/Application.sol"; +import "ORMP/src/user/UpgradeableApplication.sol"; import "@openzeppelin/contracts/access/Ownable2Step.sol"; +import "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; -contract ORMPPort is Ownable2Step, Application, BaseMessagePort, PortLookup { - constructor(address dao, address ormp, string memory name) Application(ormp) BaseMessagePort(name) { +contract ORMPUpgradeablePort is Ownable2Step, AppBase, BaseMessagePort, PortLookup { + using EnumerableSet for EnumerableSet.AddressSet; + + address public ormp; + + EnumerableSet.AddressSet internal historyORMPSet; + + event SetORMP(address previousORMP, address currentORMP); + + modifier onlyORMPs() { + require(historyORMPSet.contains(msg.sender), "!ormps"); + _; + } + + modifier onlyOnce() { + bytes32 msgHash = _messageId(); + uint256 len = historyORMPSet.length(); + for (uint256 i = 0; i < len; i++) { + address o = historyORMPSet.at(i); + require(IORMP(o).dones(msgHash) == false, "done"); + } + _; + } + + constructor(address dao, address ormp_, string memory name) BaseMessagePort(name) { _transferOwnership(dao); + ormp = ormp_; + historyORMPSet.add(ormp_); } - function setURI(string calldata uri) external onlyOwner { - _setURI(uri); + function protocol() public view override returns (address) { + return ormp; + } + + /// @notice How to migrate to new ORMP contract. + /// 1. setORMP to new ORMP contract. + /// 2. previousORMP.setAppConfig to null after relay on-flight message. + function setORMP(address ormp_) external onlyOwner { + address previousORMP = ormp; + require(historyORMPSet.add(previousORMP), "!add"); + ormp = ormp_; + emit SetORMP(previousORMP, ormp_); } - function setAppConfig(address oracle, address relayer) external onlyOwner { - _setAppConfig(oracle, relayer); + function setAppConfig(address ormp_, address oracle, address relayer) external onlyOwner { + require(historyORMPSet.contains(ormp_), "!exist"); + IORMP(ormp_).setAppConfig(oracle, relayer); + } + + function setURI(string calldata uri) external onlyOwner { + _setURI(uri); } function setToPort(uint256 _toChainId, address _toPortAddress) external onlyOwner { @@ -44,6 +85,22 @@ contract ORMPPort is Ownable2Step, Application, BaseMessagePort, PortLookup { _setFromPort(_fromChainId, _fromPortAddress); } + function historyORMPLength() public view returns (uint256) { + return historyORMPSet.length(); + } + + function historyORMPs() public view returns (address[] memory) { + return historyORMPSet.values(); + } + + function historyORMPAt(uint256 index) public view returns (address) { + return historyORMPSet.at(index); + } + + function historyORMPContains(address ormp_) public view returns (bool) { + return historyORMPSet.contains(ormp_); + } + function _send(address fromDapp, uint256 toChainId, address toDapp, bytes calldata message, bytes calldata params) internal override @@ -55,7 +112,7 @@ contract ORMPPort is Ownable2Step, Application, BaseMessagePort, PortLookup { ); } - function recv(address fromDapp, address toDapp, bytes calldata message) public payable virtual onlyORMP { + function recv(address fromDapp, address toDapp, bytes calldata message) public payable virtual onlyORMPs onlyOnce { uint256 fromChainId = _fromChainId(); require(_xmsgSender() == _checkedFromPort(fromChainId), "!auth"); _recv(fromChainId, fromDapp, toDapp, message); From 74435bee414dbf0a13c8ddd57c442930f7c3fb04 Mon Sep 17 00:00:00 2001 From: echo Date: Thu, 21 Mar 2024 22:23:01 +0800 Subject: [PATCH 22/39] retryable dapp demo --- src/examples/ExampleRetryableDapp.sol | 28 +++++-------------- ...ePortExt.sol => IMessageRetryablePort.sol} | 8 ++---- src/ports/ORMPUpgradeableAndRetryablePort.sol | 20 +++++++------ 3 files changed, 21 insertions(+), 35 deletions(-) rename src/interfaces/{IMessagePortExt.sol => IMessageRetryablePort.sol} (69%) diff --git a/src/examples/ExampleRetryableDapp.sol b/src/examples/ExampleRetryableDapp.sol index 07a7237..be7530f 100644 --- a/src/examples/ExampleRetryableDapp.sol +++ b/src/examples/ExampleRetryableDapp.sol @@ -19,31 +19,17 @@ pragma solidity ^0.8.17; import "@openzeppelin/contracts/security/ReentrancyGuard.sol"; import "ORMP/src/Common.sol"; -import "../interfaces/IMessagePortExt.sol"; +import "../interfaces/IMessageRetryablePort.sol"; import "./ExampleReceiverDapp.sol"; contract ExampleRetryableDapp is ExampleReceiverDapp, ReentrancyGuard { - uint256 public immutable FROM_CHAINID; + constructor(address port, address dapp) ExampleReceiverDapp(port, dapp) {} - constructor(address port, address dapp, uint256 fromChainId) ExampleReceiverDapp(port, dapp) { - FROM_CHAINID = fromChainId; + function retry(bytes calldata messageData) external payable { + IMessageRetryablePort(PORT).retry(messageData); } - // function retryFailedMessage(Message calldata message) external payable nonReentrant { - // msgHash = hash(message); - // require(IMessagePortExt(PORT).checkDeliveried(msgHash), "!delivery"); - // require(IMessagePortExt(PORT).checkCompleted(msgHash) == false, "completed"); - // require(message.toChainId == block.chainid, "!toChainId"); - // require(message.to == PORT, "!to"); - // require(message.fromChainId == FROM_CHAINID, "!fromChainId"); - // require(message.from == IMessagePortExt(PORT).fromPortLookup(FROM_CHAINID), "!port"); - // (bytes4, address fromDapp, address toDapp, bytes memory payload) = - // abi.decode(message.encoded, (bytes4, address, address, bytes)); - // require(fromDapp == DAPP, "!fromDapp"); - // require(toDapp == address(this), "!toDapp"); - // (bytes4 sig, bytes memory params) = abi.decode(payload, (bytes4, bytes)); - // require(sig == ExampleReceiverDapp.xxx.selector, "!sig"); - // // redo xxx. - // emit DappMessageRecv(FROM_CHAINID, DAPP, PORT, params); - // } + function clear(bytes calldata messageData) external { + IMessageRetryablePort(PORT).clear(messageData); + } } diff --git a/src/interfaces/IMessagePortExt.sol b/src/interfaces/IMessageRetryablePort.sol similarity index 69% rename from src/interfaces/IMessagePortExt.sol rename to src/interfaces/IMessageRetryablePort.sol index 5d986b2..076e483 100644 --- a/src/interfaces/IMessagePortExt.sol +++ b/src/interfaces/IMessageRetryablePort.sol @@ -17,9 +17,7 @@ pragma solidity ^0.8.0; -interface IMessagePortExt { - function checkDeliveried(bytes32 msgHash) external view returns (bool); - function checkCompleted(bytes32 msgHash) external view returns (bool); - function fromPortLookup(uint256 fromChainId) external view returns (address); - function toPortLookup(uint256 toChainId) external view returns (address); +interface IMessageRetryablePort { + function retry(bytes calldata messageData) external payable; + function clear(bytes calldata messageData) external; } diff --git a/src/ports/ORMPUpgradeableAndRetryablePort.sol b/src/ports/ORMPUpgradeableAndRetryablePort.sol index 63b6885..7946b1a 100644 --- a/src/ports/ORMPUpgradeableAndRetryablePort.sol +++ b/src/ports/ORMPUpgradeableAndRetryablePort.sol @@ -31,7 +31,8 @@ contract ORMPUpgradeableAndRetryablePort is ORMPUpgradeablePort, ReentrancyGuard constructor(address dao, address ormp, string memory name) ORMPUpgradeablePort(dao, ormp, name) {} - function retry(Message calldata message) external payable nonReentrant { + function retry(bytes calldata messageData) external payable nonReentrant { + Message memory message = abi.decode(messageData, (Message)); bytes32 msgHash = _checkMessage(message); (, address fromDapp, address toDapp, bytes memory payload) = abi.decode(message.encoded, (bytes4, address, address, bytes)); @@ -39,19 +40,14 @@ contract ORMPUpgradeableAndRetryablePort is ORMPUpgradeablePort, ReentrancyGuard _markDone(msgHash); } - function clear(Message calldata message) external { + function clear(bytes calldata messageData) external { + Message memory message = abi.decode(messageData, (Message)); bytes32 msgHash = _checkMessage(message); (,, address toDapp,) = abi.decode(message.encoded, (bytes4, address, address, bytes)); require(toDapp == msg.sender, "!auth"); _clear(msgHash); } - function _clear(bytes32 msgHash) internal { - require(dones[msgHash] == false, "done"); - dones[msgHash] = true; - emit MessageDispatchedInPort(msgHash); - } - function _checkDispathed(bytes32 msgHash) internal view { uint256 len = historyORMPSet.length(); for (uint256 i = 0; i < len; i++) { @@ -60,7 +56,7 @@ contract ORMPUpgradeableAndRetryablePort is ORMPUpgradeablePort, ReentrancyGuard } } - function _checkMessage(Message calldata message) internal view returns (bytes32 msgHash) { + function _checkMessage(Message memory message) internal view returns (bytes32 msgHash) { msgHash = hash(message); _checkDispathed(msgHash); require(LOCAL_CHAINID() == message.toChainId, "!toChainId"); @@ -75,6 +71,12 @@ contract ORMPUpgradeableAndRetryablePort is ORMPUpgradeablePort, ReentrancyGuard emit MessageDispatchedInPort(msgHash); } + function _clear(bytes32 msgHash) internal { + require(dones[msgHash] == false, "done"); + dones[msgHash] = true; + emit MessageDispatchedInPort(msgHash); + } + function recv(address fromDapp, address toDapp, bytes calldata message) public payable override { super.recv(fromDapp, toDapp, message); bytes32 msgHash = _messageId(); From 33da2426581a17e418abac6d903f58d61352a393 Mon Sep 17 00:00:00 2001 From: echo Date: Thu, 21 Mar 2024 22:39:17 +0800 Subject: [PATCH 23/39] upgrade lib ormp --- lib/ORMP | 2 +- src/ports/ORMPUpgradeablePort.sol | 16 +++++----------- 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/lib/ORMP b/lib/ORMP index e0aeb25..485fdb4 160000 --- a/lib/ORMP +++ b/lib/ORMP @@ -1 +1 @@ -Subproject commit e0aeb254ea24a1a9d79368e1cbebe9f3de5d98a8 +Subproject commit 485fdb48b444ba2c3ae555ef78eb17c71e76186e diff --git a/src/ports/ORMPUpgradeablePort.sol b/src/ports/ORMPUpgradeablePort.sol index 01e9631..ec1e18e 100644 --- a/src/ports/ORMPUpgradeablePort.sol +++ b/src/ports/ORMPUpgradeablePort.sol @@ -20,7 +20,7 @@ pragma solidity ^0.8.17; import "./base/BaseMessagePort.sol"; import "./base/PortLookup.sol"; import "ORMP/src/interfaces/IORMP.sol"; -import "ORMP/src/user/UpgradeableApplication.sol"; +import "ORMP/src/user/AppBase.sol"; import "@openzeppelin/contracts/access/Ownable2Step.sol"; import "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; @@ -33,7 +33,7 @@ contract ORMPUpgradeablePort is Ownable2Step, AppBase, BaseMessagePort, PortLook event SetORMP(address previousORMP, address currentORMP); - modifier onlyORMPs() { + modifier onlyORMP() override { require(historyORMPSet.contains(msg.sender), "!ormps"); _; } @@ -54,10 +54,6 @@ contract ORMPUpgradeablePort is Ownable2Step, AppBase, BaseMessagePort, PortLook historyORMPSet.add(ormp_); } - function protocol() public view override returns (address) { - return ormp; - } - /// @notice How to migrate to new ORMP contract. /// 1. setORMP to new ORMP contract. /// 2. previousORMP.setAppConfig to null after relay on-flight message. @@ -107,12 +103,10 @@ contract ORMPUpgradeablePort is Ownable2Step, AppBase, BaseMessagePort, PortLook { (uint256 gasLimit, address refund, bytes memory ormpParams) = abi.decode(params, (uint256, address, bytes)); bytes memory encoded = abi.encodeWithSelector(this.recv.selector, fromDapp, toDapp, message); - IORMP(protocol()).send{value: msg.value}( - toChainId, _checkedToPort(toChainId), gasLimit, encoded, refund, ormpParams - ); + IORMP(ormp).send{value: msg.value}(toChainId, _checkedToPort(toChainId), gasLimit, encoded, refund, ormpParams); } - function recv(address fromDapp, address toDapp, bytes calldata message) public payable virtual onlyORMPs onlyOnce { + function recv(address fromDapp, address toDapp, bytes calldata message) public payable virtual onlyORMP onlyOnce { uint256 fromChainId = _fromChainId(); require(_xmsgSender() == _checkedFromPort(fromChainId), "!auth"); _recv(fromChainId, fromDapp, toDapp, message); @@ -126,6 +120,6 @@ contract ORMPUpgradeablePort is Ownable2Step, AppBase, BaseMessagePort, PortLook { (uint256 gasLimit,, bytes memory ormpParams) = abi.decode(params, (uint256, address, bytes)); bytes memory encoded = abi.encodeWithSelector(this.recv.selector, msg.sender, toDapp, message); - return IORMP(protocol()).fee(toChainId, address(this), gasLimit, encoded, ormpParams); + return IORMP(ormp).fee(toChainId, address(this), gasLimit, encoded, ormpParams); } } From 3277af976ea3aed65333e53d4e9d395dd4c1e16d Mon Sep 17 00:00:00 2001 From: echo Date: Thu, 21 Mar 2024 22:44:30 +0800 Subject: [PATCH 24/39] fix test --- script/test/ORMPPort.t.sol | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/script/test/ORMPPort.t.sol b/script/test/ORMPPort.t.sol index e7722cf..4224504 100644 --- a/script/test/ORMPPort.t.sol +++ b/script/test/ORMPPort.t.sol @@ -21,8 +21,8 @@ contract ORMPPortTest is Test { uint256 chainId = Chains.Darwinia; vm.createSelectFork(chainId.toChainName()); dao = address(0x1); - ormpProtocol = address(0x00000000001523057a05d6293C1e5171eE33eE0A); - ormpPort = new ORMPUpgradeablePort(dao, vm.envOr("ORMP_ADDRESS", address(ormpProtocol)), "ORMP"); + ormpProtocol = vm.envOr("ORMP_ADDRESS", 0x00000000001523057a05d6293C1e5171eE33eE0A); + ormpPort = new ORMPUpgradeablePort(dao, vm.envOr("ORMP_ADDRESS", ormpProtocol), "ORMP"); } function testSetUri() public { @@ -38,14 +38,14 @@ contract ORMPPortTest is Test { function testSetAppConfig() public { vm.prank(dao); - ormpPort.setAppConfig(address(ormpPort), address(0x2), address(0x3)); + ormpPort.setAppConfig(ormpProtocol, address(0x2), address(0x3)); UC memory uc = IORMP(vm.envOr("ORMP_ADDRESS", address(ormpProtocol))).getAppConfig(address(ormpPort)); assertEq(uc.oracle, address(0x2)); assertEq(uc.relayer, address(0x3)); // Cannot vm.expectRevert(bytes("Ownable: caller is not the owner")); vm.prank(address(0)); - ormpPort.setAppConfig(address(ormpPort), address(0x2), address(0x3)); + ormpPort.setAppConfig(ormpProtocol, address(0x2), address(0x3)); } function testSetPort() public { From 798c15703f9af10592010c482f808fd4f8a02529 Mon Sep 17 00:00:00 2001 From: echo Date: Thu, 21 Mar 2024 22:49:15 +0800 Subject: [PATCH 25/39] doc --- src/ports/ORMPUpgradeableAndRetryablePort.sol | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/ports/ORMPUpgradeableAndRetryablePort.sol b/src/ports/ORMPUpgradeableAndRetryablePort.sol index 7946b1a..42bc13b 100644 --- a/src/ports/ORMPUpgradeableAndRetryablePort.sol +++ b/src/ports/ORMPUpgradeableAndRetryablePort.sol @@ -24,7 +24,8 @@ import "./ORMPUpgradeablePort.sol"; contract ORMPUpgradeableAndRetryablePort is ORMPUpgradeablePort, ReentrancyGuard { using EnumerableSet for EnumerableSet.AddressSet; - /// @dev msgHash => isDispathedInPort. + /// @dev msgHash => isDispatchedInPort. + /// The dispatched result means dapp executed successful. mapping(bytes32 => bool) public dones; event MessageDispatchedInPort(bytes32 indexed msgHash); From 6829d4f3cdeed712fe9704ce8a94ba5f93b2b46d Mon Sep 17 00:00:00 2001 From: echo Date: Thu, 21 Mar 2024 22:50:40 +0800 Subject: [PATCH 26/39] doc --- src/ports/ORMPUpgradeableAndRetryablePort.sol | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/ports/ORMPUpgradeableAndRetryablePort.sol b/src/ports/ORMPUpgradeableAndRetryablePort.sol index 42bc13b..0015dd8 100644 --- a/src/ports/ORMPUpgradeableAndRetryablePort.sol +++ b/src/ports/ORMPUpgradeableAndRetryablePort.sol @@ -32,8 +32,8 @@ contract ORMPUpgradeableAndRetryablePort is ORMPUpgradeablePort, ReentrancyGuard constructor(address dao, address ormp, string memory name) ORMPUpgradeablePort(dao, ormp, name) {} - function retry(bytes calldata messageData) external payable nonReentrant { - Message memory message = abi.decode(messageData, (Message)); + function retry(bytes calldata failedMessage) external payable nonReentrant { + Message memory message = abi.decode(failedMessage, (Message)); bytes32 msgHash = _checkMessage(message); (, address fromDapp, address toDapp, bytes memory payload) = abi.decode(message.encoded, (bytes4, address, address, bytes)); @@ -41,8 +41,8 @@ contract ORMPUpgradeableAndRetryablePort is ORMPUpgradeablePort, ReentrancyGuard _markDone(msgHash); } - function clear(bytes calldata messageData) external { - Message memory message = abi.decode(messageData, (Message)); + function clear(bytes calldata failedMessage) external { + Message memory message = abi.decode(failedMessage, (Message)); bytes32 msgHash = _checkMessage(message); (,, address toDapp,) = abi.decode(message.encoded, (bytes4, address, address, bytes)); require(toDapp == msg.sender, "!auth"); From 8da96ec39afd2a4d3af0a1a0be2f3cea2531f8b3 Mon Sep 17 00:00:00 2001 From: echo Date: Thu, 21 Mar 2024 22:52:34 +0800 Subject: [PATCH 27/39] doc --- src/examples/ExampleRetryableDapp.sol | 8 ++++---- src/interfaces/IMessageRetryablePort.sol | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/examples/ExampleRetryableDapp.sol b/src/examples/ExampleRetryableDapp.sol index be7530f..b4dac5a 100644 --- a/src/examples/ExampleRetryableDapp.sol +++ b/src/examples/ExampleRetryableDapp.sol @@ -25,11 +25,11 @@ import "./ExampleReceiverDapp.sol"; contract ExampleRetryableDapp is ExampleReceiverDapp, ReentrancyGuard { constructor(address port, address dapp) ExampleReceiverDapp(port, dapp) {} - function retry(bytes calldata messageData) external payable { - IMessageRetryablePort(PORT).retry(messageData); + function retry(bytes calldata failedMessage) external payable { + IMessageRetryablePort(PORT).retry(failedMessage); } - function clear(bytes calldata messageData) external { - IMessageRetryablePort(PORT).clear(messageData); + function clear(bytes calldata failedMessage) external { + IMessageRetryablePort(PORT).clear(failedMessage); } } diff --git a/src/interfaces/IMessageRetryablePort.sol b/src/interfaces/IMessageRetryablePort.sol index 076e483..448a06d 100644 --- a/src/interfaces/IMessageRetryablePort.sol +++ b/src/interfaces/IMessageRetryablePort.sol @@ -18,6 +18,6 @@ pragma solidity ^0.8.0; interface IMessageRetryablePort { - function retry(bytes calldata messageData) external payable; - function clear(bytes calldata messageData) external; + function retry(bytes calldata failedMessage) external payable; + function clear(bytes calldata failedMessage) external; } From abf0b131f7dfb55972a0f30690dbbaa6c6c3bb2d Mon Sep 17 00:00:00 2001 From: echo Date: Thu, 21 Mar 2024 22:58:09 +0800 Subject: [PATCH 28/39] doc --- src/ports/ORMPUpgradeablePort.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ports/ORMPUpgradeablePort.sol b/src/ports/ORMPUpgradeablePort.sol index ec1e18e..0e88252 100644 --- a/src/ports/ORMPUpgradeablePort.sol +++ b/src/ports/ORMPUpgradeablePort.sol @@ -56,7 +56,7 @@ contract ORMPUpgradeablePort is Ownable2Step, AppBase, BaseMessagePort, PortLook /// @notice How to migrate to new ORMP contract. /// 1. setORMP to new ORMP contract. - /// 2. previousORMP.setAppConfig to null after relay on-flight message. + /// 2. previousORMP.setAppConfig to null. function setORMP(address ormp_) external onlyOwner { address previousORMP = ormp; require(historyORMPSet.add(previousORMP), "!add"); From 96aec62f054de388dd3f87a7400101cbeedd4964 Mon Sep 17 00:00:00 2001 From: echo Date: Thu, 21 Mar 2024 23:02:18 +0800 Subject: [PATCH 29/39] doc --- src/ports/ORMPUpgradeablePort.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ports/ORMPUpgradeablePort.sol b/src/ports/ORMPUpgradeablePort.sol index 0e88252..ec1e18e 100644 --- a/src/ports/ORMPUpgradeablePort.sol +++ b/src/ports/ORMPUpgradeablePort.sol @@ -56,7 +56,7 @@ contract ORMPUpgradeablePort is Ownable2Step, AppBase, BaseMessagePort, PortLook /// @notice How to migrate to new ORMP contract. /// 1. setORMP to new ORMP contract. - /// 2. previousORMP.setAppConfig to null. + /// 2. previousORMP.setAppConfig to null after relay on-flight message. function setORMP(address ormp_) external onlyOwner { address previousORMP = ormp; require(historyORMPSet.add(previousORMP), "!add"); From e18e2737757e0129fc4fd05f82f0462cdd6e372f Mon Sep 17 00:00:00 2001 From: echo Date: Fri, 22 Mar 2024 16:16:13 +0800 Subject: [PATCH 30/39] fix --- src/ports/ORMPUpgradeablePort.sol | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/ports/ORMPUpgradeablePort.sol b/src/ports/ORMPUpgradeablePort.sol index ec1e18e..fa2012a 100644 --- a/src/ports/ORMPUpgradeablePort.sol +++ b/src/ports/ORMPUpgradeablePort.sol @@ -29,6 +29,8 @@ contract ORMPUpgradeablePort is Ownable2Step, AppBase, BaseMessagePort, PortLook address public ormp; + mapping(bytes32 => bool) public dones; + EnumerableSet.AddressSet internal historyORMPSet; event SetORMP(address previousORMP, address currentORMP); @@ -38,16 +40,6 @@ contract ORMPUpgradeablePort is Ownable2Step, AppBase, BaseMessagePort, PortLook _; } - modifier onlyOnce() { - bytes32 msgHash = _messageId(); - uint256 len = historyORMPSet.length(); - for (uint256 i = 0; i < len; i++) { - address o = historyORMPSet.at(i); - require(IORMP(o).dones(msgHash) == false, "done"); - } - _; - } - constructor(address dao, address ormp_, string memory name) BaseMessagePort(name) { _transferOwnership(dao); ormp = ormp_; @@ -56,7 +48,7 @@ contract ORMPUpgradeablePort is Ownable2Step, AppBase, BaseMessagePort, PortLook /// @notice How to migrate to new ORMP contract. /// 1. setORMP to new ORMP contract. - /// 2. previousORMP.setAppConfig to null after relay on-flight message. + /// 2. delete previousORMP after relay on-flight message. function setORMP(address ormp_) external onlyOwner { address previousORMP = ormp; require(historyORMPSet.add(previousORMP), "!add"); @@ -64,6 +56,11 @@ contract ORMPUpgradeablePort is Ownable2Step, AppBase, BaseMessagePort, PortLook emit SetORMP(previousORMP, ormp_); } + function delORMP(address ormp_) external onlyOwner { + require(ormp != ormp_, "sender"); + require(historyORMPSet.remove(ormp_), "!del"); + } + function setAppConfig(address ormp_, address oracle, address relayer) external onlyOwner { require(historyORMPSet.contains(ormp_), "!exist"); IORMP(ormp_).setAppConfig(oracle, relayer); @@ -106,10 +103,13 @@ contract ORMPUpgradeablePort is Ownable2Step, AppBase, BaseMessagePort, PortLook IORMP(ormp).send{value: msg.value}(toChainId, _checkedToPort(toChainId), gasLimit, encoded, refund, ormpParams); } - function recv(address fromDapp, address toDapp, bytes calldata message) public payable virtual onlyORMP onlyOnce { + function recv(address fromDapp, address toDapp, bytes calldata message) public payable virtual onlyORMP { uint256 fromChainId = _fromChainId(); require(_xmsgSender() == _checkedFromPort(fromChainId), "!auth"); _recv(fromChainId, fromDapp, toDapp, message); + bytes32 msgHash = _messageId(); + require(dones(msgHash) == false, "done"); + dones[msgHash] = true; } function fee(uint256 toChainId, address toDapp, bytes calldata message, bytes calldata params) From 58212522c99b47deb75a5679a74d345cd3f1f4bb Mon Sep 17 00:00:00 2001 From: echo Date: Fri, 22 Mar 2024 18:46:51 +0800 Subject: [PATCH 31/39] rm dones --- src/ports/ORMPUpgradeablePort.sol | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/ports/ORMPUpgradeablePort.sol b/src/ports/ORMPUpgradeablePort.sol index fa2012a..5f320e6 100644 --- a/src/ports/ORMPUpgradeablePort.sol +++ b/src/ports/ORMPUpgradeablePort.sol @@ -29,8 +29,6 @@ contract ORMPUpgradeablePort is Ownable2Step, AppBase, BaseMessagePort, PortLook address public ormp; - mapping(bytes32 => bool) public dones; - EnumerableSet.AddressSet internal historyORMPSet; event SetORMP(address previousORMP, address currentORMP); @@ -107,9 +105,6 @@ contract ORMPUpgradeablePort is Ownable2Step, AppBase, BaseMessagePort, PortLook uint256 fromChainId = _fromChainId(); require(_xmsgSender() == _checkedFromPort(fromChainId), "!auth"); _recv(fromChainId, fromDapp, toDapp, message); - bytes32 msgHash = _messageId(); - require(dones(msgHash) == false, "done"); - dones[msgHash] = true; } function fee(uint256 toChainId, address toDapp, bytes calldata message, bytes calldata params) From 6c7a33d3522baa012ef536bc284c4cb5f808741c Mon Sep 17 00:00:00 2001 From: echo Date: Fri, 22 Mar 2024 18:48:38 +0800 Subject: [PATCH 32/39] clean --- script/deploy/DeployORMPURPort.s.sol | 78 ----------------- script/input/c3.json | 2 - src/examples/ExampleRetryableDapp.sol | 35 -------- src/interfaces/IMessageRetryablePort.sol | 23 ----- src/ports/ORMPUpgradeableAndRetryablePort.sol | 86 ------------------- 5 files changed, 224 deletions(-) delete mode 100644 script/deploy/DeployORMPURPort.s.sol delete mode 100644 src/examples/ExampleRetryableDapp.sol delete mode 100644 src/interfaces/IMessageRetryablePort.sol delete mode 100644 src/ports/ORMPUpgradeableAndRetryablePort.sol diff --git a/script/deploy/DeployORMPURPort.s.sol b/script/deploy/DeployORMPURPort.s.sol deleted file mode 100644 index 20744aa..0000000 --- a/script/deploy/DeployORMPURPort.s.sol +++ /dev/null @@ -1,78 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.17; - -import {stdJson} from "forge-std/StdJson.sol"; -import {Script} from "forge-std/Script.sol"; -import {console2 as console} from "forge-std/console2.sol"; -import {Common} from "create3-deploy/script/Common.s.sol"; -import {ScriptTools} from "create3-deploy/script/ScriptTools.sol"; - -import "../../src/ports/ORMPUpgradeableAndRetryablePort.sol"; - -interface III { - function owner() external view returns (address); - function transferOwnership(address newOwner) external; - function pendingOwner() external view returns (address); -} - -contract DeployORMPURPort is Common { - using stdJson for string; - using ScriptTools for string; - - address ORMP; - address ADDR; - bytes32 SALT; - - string c3; - string config; - string instanceId; - string outputName; - address deployer; - address dao; - - function name() public pure override returns (string memory) { - return "DeployORMPURPort"; - } - - function setUp() public override { - super.setUp(); - - instanceId = vm.envOr("INSTANCE_ID", string("deploy_ormp_ur_port.c")); - outputName = "deploy_ormp_ur_port.a"; - config = ScriptTools.readInput(instanceId); - c3 = ScriptTools.readInput("../c3"); - ORMP = c3.readAddress(".ORMP_ADDR"); - ADDR = c3.readAddress(".ORMPURPORT_ADDR"); - SALT = c3.readBytes32(".ORMPURPORT_SALT"); - - deployer = config.readAddress(".DEPLOYER"); - dao = config.readAddress(".DAO"); - } - - function run() public { - require(deployer == msg.sender, "!deployer"); - - deploy(); - // setConfig(); - - ScriptTools.exportContract(outputName, "DAO", dao); - ScriptTools.exportContract(outputName, "ORMPUR_PORT", ADDR); - } - - function deploy() public broadcast returns (address) { - string memory name_ = config.readString(".metadata.name"); - bytes memory byteCode = type(ORMPUpgradeableAndRetryablePort).creationCode; - bytes memory initCode = bytes.concat(byteCode, abi.encode(deployer, ORMP, name_)); - address port = _deploy3(SALT, initCode); - require(port == ADDR, "!addr"); - require(III(ADDR).owner() == deployer); - console.log("ORMPUpgradeableAndRetryablePort deployed: %s", port); - return port; - } - - function setConfig() public broadcast { - III(ADDR).transferOwnership(dao); - require(III(ADDR).pendingOwner() == dao, "!dao"); - // TODO:: dao.acceptOwnership() - } -} diff --git a/script/input/c3.json b/script/input/c3.json index 4607028..ada2828 100644 --- a/script/input/c3.json +++ b/script/input/c3.json @@ -6,8 +6,6 @@ "PORTREGISTRY_SALT": "0x09b30e96d39e3a44a10fb03ee7f325b13af3b681afd2bbe4c87e23cbbeabd26f", "ORMPPORT_ADDR": "0x0000000005d961F950adA391C1511c92bbc64D9F", "ORMPPORT_SALT": "0xe9cab07c7534f6d34500c7fc83b0d4205012e3e7cc3c1cf1d74f67858d413740", - "ORMPURPORT_ADDR": "0x000000000EA450D971d3A68c754Fb5C212d3101b", - "ORMPURPORT_SALT": "0x6da6ca9d7ad25e6d11f456555cdb5b4bc167bbe4788d32b39d547daccdaf24b8", "MULTIPORT_ADDR": "0x000002C33f83AE045d5EBB8972F09674379e6A31", "MULTIPORT_SALT": "0xc6935a1d5d0b9a995e68ffe1151c3c05162d221283fbd8083888e169b43792f2", "SAFEMSGPORTMODULE_ADDR": "0x000080fc9c29c366DC8c1C656846E277BA7b6cB9", diff --git a/src/examples/ExampleRetryableDapp.sol b/src/examples/ExampleRetryableDapp.sol deleted file mode 100644 index b4dac5a..0000000 --- a/src/examples/ExampleRetryableDapp.sol +++ /dev/null @@ -1,35 +0,0 @@ -// This file is part of Darwinia. -// Copyright (C) 2018-2023 Darwinia Network -// SPDX-License-Identifier: GPL-3.0 -// -// Darwinia is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// Darwinia is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with Darwinia. If not, see . - -pragma solidity ^0.8.17; - -import "@openzeppelin/contracts/security/ReentrancyGuard.sol"; -import "ORMP/src/Common.sol"; -import "../interfaces/IMessageRetryablePort.sol"; -import "./ExampleReceiverDapp.sol"; - -contract ExampleRetryableDapp is ExampleReceiverDapp, ReentrancyGuard { - constructor(address port, address dapp) ExampleReceiverDapp(port, dapp) {} - - function retry(bytes calldata failedMessage) external payable { - IMessageRetryablePort(PORT).retry(failedMessage); - } - - function clear(bytes calldata failedMessage) external { - IMessageRetryablePort(PORT).clear(failedMessage); - } -} diff --git a/src/interfaces/IMessageRetryablePort.sol b/src/interfaces/IMessageRetryablePort.sol deleted file mode 100644 index 448a06d..0000000 --- a/src/interfaces/IMessageRetryablePort.sol +++ /dev/null @@ -1,23 +0,0 @@ -// This file is part of Darwinia. -// Copyright (C) 2018-2023 Darwinia Network -// SPDX-License-Identifier: GPL-3.0 -// -// Darwinia is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// Darwinia is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with Darwinia. If not, see . - -pragma solidity ^0.8.0; - -interface IMessageRetryablePort { - function retry(bytes calldata failedMessage) external payable; - function clear(bytes calldata failedMessage) external; -} diff --git a/src/ports/ORMPUpgradeableAndRetryablePort.sol b/src/ports/ORMPUpgradeableAndRetryablePort.sol deleted file mode 100644 index 0015dd8..0000000 --- a/src/ports/ORMPUpgradeableAndRetryablePort.sol +++ /dev/null @@ -1,86 +0,0 @@ -// This file is part of Darwinia. -// Copyright (C) 2018-2023 Darwinia Network -// SPDX-License-Identifier: GPL-3.0 -// -// Darwinia is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// Darwinia is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with Darwinia. If not, see . - -pragma solidity ^0.8.17; - -import "@openzeppelin/contracts/security/ReentrancyGuard.sol"; -import "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; -import "./ORMPUpgradeablePort.sol"; - -contract ORMPUpgradeableAndRetryablePort is ORMPUpgradeablePort, ReentrancyGuard { - using EnumerableSet for EnumerableSet.AddressSet; - - /// @dev msgHash => isDispatchedInPort. - /// The dispatched result means dapp executed successful. - mapping(bytes32 => bool) public dones; - - event MessageDispatchedInPort(bytes32 indexed msgHash); - - constructor(address dao, address ormp, string memory name) ORMPUpgradeablePort(dao, ormp, name) {} - - function retry(bytes calldata failedMessage) external payable nonReentrant { - Message memory message = abi.decode(failedMessage, (Message)); - bytes32 msgHash = _checkMessage(message); - (, address fromDapp, address toDapp, bytes memory payload) = - abi.decode(message.encoded, (bytes4, address, address, bytes)); - _recv(message.fromChainId, fromDapp, toDapp, payload); - _markDone(msgHash); - } - - function clear(bytes calldata failedMessage) external { - Message memory message = abi.decode(failedMessage, (Message)); - bytes32 msgHash = _checkMessage(message); - (,, address toDapp,) = abi.decode(message.encoded, (bytes4, address, address, bytes)); - require(toDapp == msg.sender, "!auth"); - _clear(msgHash); - } - - function _checkDispathed(bytes32 msgHash) internal view { - uint256 len = historyORMPSet.length(); - for (uint256 i = 0; i < len; i++) { - address o = historyORMPSet.at(i); - require(IORMP(o).dones(msgHash), "!done"); - } - } - - function _checkMessage(Message memory message) internal view returns (bytes32 msgHash) { - msgHash = hash(message); - _checkDispathed(msgHash); - require(LOCAL_CHAINID() == message.toChainId, "!toChainId"); - require(address(this) == message.to, "!to"); - uint256 fromChainId = message.fromChainId; - require(message.from == _checkedFromPort(fromChainId), "!xAuth"); - } - - function _markDone(bytes32 msgHash) internal { - require(dones[msgHash] == false, "done"); - dones[msgHash] = true; - emit MessageDispatchedInPort(msgHash); - } - - function _clear(bytes32 msgHash) internal { - require(dones[msgHash] == false, "done"); - dones[msgHash] = true; - emit MessageDispatchedInPort(msgHash); - } - - function recv(address fromDapp, address toDapp, bytes calldata message) public payable override { - super.recv(fromDapp, toDapp, message); - bytes32 msgHash = _messageId(); - _markDone(msgHash); - } -} From 11ddef354c6967bd29269f3352a96d9bc6f5e47c Mon Sep 17 00:00:00 2001 From: echo Date: Fri, 22 Mar 2024 21:26:05 +0800 Subject: [PATCH 33/39] clean --- SUPPORTED.md | 1 - script/input/11155111/deploy_ormp_ur_port.c.json | 7 ------- script/input/421614/deploy_ormp_ur_port.c.json | 7 ------- script/input/43/deploy_ormp_ur_port.c.json | 7 ------- script/output/11155111/deploy_ormp_ur_port.a-latest.json | 4 ---- script/output/421614/deploy_ormp_ur_port.a-latest.json | 4 ---- script/output/43/deploy_ormp_ur_port.a-latest.json | 4 ---- 7 files changed, 34 deletions(-) delete mode 100644 script/input/11155111/deploy_ormp_ur_port.c.json delete mode 100644 script/input/421614/deploy_ormp_ur_port.c.json delete mode 100644 script/input/43/deploy_ormp_ur_port.c.json delete mode 100644 script/output/11155111/deploy_ormp_ur_port.a-latest.json delete mode 100644 script/output/421614/deploy_ormp_ur_port.a-latest.json delete mode 100644 script/output/43/deploy_ormp_ur_port.a-latest.json diff --git a/SUPPORTED.md b/SUPPORTED.md index 97afe43..e76427a 100644 --- a/SUPPORTED.md +++ b/SUPPORTED.md @@ -2,7 +2,6 @@ | Port | Name | Canonical Cross-chain Deployment Address | |---------------------------------|------------|--------------------------------------------| | ORMPPort | ORMP | 0x0000000005d961F950adA391C1511c92bbc64D9F | -| ORMPUpgradeableAndRetryablePort | ORMP-UR | 0x000000000EA450D971d3A68c754Fb5C212d3101b | ## Supported Chains ### Mainnet diff --git a/script/input/11155111/deploy_ormp_ur_port.c.json b/script/input/11155111/deploy_ormp_ur_port.c.json deleted file mode 100644 index 3723665..0000000 --- a/script/input/11155111/deploy_ormp_ur_port.c.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "DAO": "0x0f14341A7f464320319025540E8Fe48Ad0fe5aec", - "DEPLOYER": "0x0f14341A7f464320319025540E8Fe48Ad0fe5aec", - "metadata": { - "name": "ORMP-UR" - } -} diff --git a/script/input/421614/deploy_ormp_ur_port.c.json b/script/input/421614/deploy_ormp_ur_port.c.json deleted file mode 100644 index 3723665..0000000 --- a/script/input/421614/deploy_ormp_ur_port.c.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "DAO": "0x0f14341A7f464320319025540E8Fe48Ad0fe5aec", - "DEPLOYER": "0x0f14341A7f464320319025540E8Fe48Ad0fe5aec", - "metadata": { - "name": "ORMP-UR" - } -} diff --git a/script/input/43/deploy_ormp_ur_port.c.json b/script/input/43/deploy_ormp_ur_port.c.json deleted file mode 100644 index 3723665..0000000 --- a/script/input/43/deploy_ormp_ur_port.c.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "DAO": "0x0f14341A7f464320319025540E8Fe48Ad0fe5aec", - "DEPLOYER": "0x0f14341A7f464320319025540E8Fe48Ad0fe5aec", - "metadata": { - "name": "ORMP-UR" - } -} diff --git a/script/output/11155111/deploy_ormp_ur_port.a-latest.json b/script/output/11155111/deploy_ormp_ur_port.a-latest.json deleted file mode 100644 index 8546379..0000000 --- a/script/output/11155111/deploy_ormp_ur_port.a-latest.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "DAO": "0x0f14341A7f464320319025540E8Fe48Ad0fe5aec", - "ORMPUR_PORT": "0x000000000EA450D971d3A68c754Fb5C212d3101b" -} \ No newline at end of file diff --git a/script/output/421614/deploy_ormp_ur_port.a-latest.json b/script/output/421614/deploy_ormp_ur_port.a-latest.json deleted file mode 100644 index 8546379..0000000 --- a/script/output/421614/deploy_ormp_ur_port.a-latest.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "DAO": "0x0f14341A7f464320319025540E8Fe48Ad0fe5aec", - "ORMPUR_PORT": "0x000000000EA450D971d3A68c754Fb5C212d3101b" -} \ No newline at end of file diff --git a/script/output/43/deploy_ormp_ur_port.a-latest.json b/script/output/43/deploy_ormp_ur_port.a-latest.json deleted file mode 100644 index 8546379..0000000 --- a/script/output/43/deploy_ormp_ur_port.a-latest.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "DAO": "0x0f14341A7f464320319025540E8Fe48Ad0fe5aec", - "ORMPUR_PORT": "0x000000000EA450D971d3A68c754Fb5C212d3101b" -} \ No newline at end of file From 89b337ef0cfc02cad00eb29a397e5e9ca5bbc3a0 Mon Sep 17 00:00:00 2001 From: echo Date: Fri, 22 Mar 2024 21:29:25 +0800 Subject: [PATCH 34/39] clean --- bin/config.sh | 18 +++++++++--------- bin/deploy.sh | 32 ++++++++++++++++---------------- ipfs/ormp_u.json | 6 ++++++ 3 files changed, 31 insertions(+), 25 deletions(-) create mode 100644 ipfs/ormp_u.json diff --git a/bin/config.sh b/bin/config.sh index c4c0429..d00f6dc 100755 --- a/bin/config.sh +++ b/bin/config.sh @@ -15,11 +15,11 @@ get_uri() { # forge script script/config/PortConfig.s.sol:PortConfig --sig "run(uint256[],string)" "[11155111,44]" $uri --chain-id 421614 --broadcast --skip-simulation --legacy # forge script script/config/PortConfig.s.sol:PortConfig --sig "run(uint256[],string)" "[44,421614]" $uri --chain-id 11155111 --broadcast -export PORT_KEY="ORMPURPORT_ADDR" -uri=$(get_uri "QmX8rYZP1u5paFfJdaEe75DLdZXmjs8FSkC7mrN6vefc32") +export PORT_KEY="ORMPUPORT_ADDR" +uri=$(get_uri "QmZB2RQ6nfWPq4a42FuPQAasSRFgqHFGgPqRNxEWAi7HEd") # forge script script/config/PortConfig.s.sol:PortConfig --sig "run(uint256[],string)" "[421614,11155111]" $uri --chain-id 43 --broadcast -g 200 -forge script script/config/PortConfig.s.sol:PortConfig --sig "run(uint256[],string)" "[11155111,44]" $uri --chain-id 421614 --broadcast --skip-simulation -forge script script/config/PortConfig.s.sol:PortConfig --sig "run(uint256[],string)" "[44,421614]" $uri --chain-id 11155111 --broadcast +# forge script script/config/PortConfig.s.sol:PortConfig --sig "run(uint256[],string)" "[11155111,44]" $uri --chain-id 421614 --broadcast --skip-simulation +# forge script script/config/PortConfig.s.sol:PortConfig --sig "run(uint256[],string)" "[44,421614]" $uri --chain-id 11155111 --broadcast # export PORT_KEY="MULTIPORT_ADDR" # uri=$(get_uri "QmQsKZG4SSbqZ12a1VpZRsURrHbRe5mVbZZQ7GmLs42ZRN") @@ -31,11 +31,11 @@ forge script script/config/PortConfig.s.sol:PortConfig --sig "run(uint256[],stri # forge script script/config/MultiPortConfig.s.sol:MultiPortConfig --chain-id 421614 --broadcast --skip-simulation --legacy # forge script script/config/MultiPortConfig.s.sol:MultiPortConfig --chain-id 11155111 --broadcast -export PORT_KEY="XACCOUNTFACTORY_ADDR" -uri=$(get_uri "QmahfNo9m9TqHUxARhug93Ubzn3HVutfQ9bDAxWq9ksJhy") -forge script script/config/PortConfig.s.sol:PortConfig --sig "run(uint256[],string)" "[]" $uri --chain-id 43 --broadcast -g 200 -forge script script/config/PortConfig.s.sol:PortConfig --sig "run(uint256[],string)" "[]" $uri --chain-id 421614 --broadcast --skip-simulation --legacy -forge script script/config/PortConfig.s.sol:PortConfig --sig "run(uint256[],string)" "[]" $uri --chain-id 11155111 --broadcast +# export PORT_KEY="XACCOUNTFACTORY_ADDR" +# uri=$(get_uri "QmahfNo9m9TqHUxARhug93Ubzn3HVutfQ9bDAxWq9ksJhy") +# forge script script/config/PortConfig.s.sol:PortConfig --sig "run(uint256[],string)" "[]" $uri --chain-id 43 --broadcast -g 200 +# forge script script/config/PortConfig.s.sol:PortConfig --sig "run(uint256[],string)" "[]" $uri --chain-id 421614 --broadcast --skip-simulation --legacy +# forge script script/config/PortConfig.s.sol:PortConfig --sig "run(uint256[],string)" "[]" $uri --chain-id 11155111 --broadcast # forge script script/config/PortConfig.s.sol:PortConfig --sig "run(uint256[],string)" "[42161,1,44]" $uri --chain-id 46 --broadcast diff --git a/bin/deploy.sh b/bin/deploy.sh index 066ee63..005edfd 100755 --- a/bin/deploy.sh +++ b/bin/deploy.sh @@ -3,34 +3,34 @@ set -eo pipefail # Deploy port registry on testnet -forge script script/deploy/DeployPortRegistry.s.sol:DeployPortRegistry --chain-id 421614 --slow --broadcast --verify --legacy --skip-simulation -forge script script/deploy/DeployPortRegistry.s.sol:DeployPortRegistry --chain-id 11155111 --broadcast --verify --legacy -forge script script/deploy/DeployPortRegistry.s.sol:DeployPortRegistry --chain-id 43 --broadcast --verify +# forge script script/deploy/DeployPortRegistry.s.sol:DeployPortRegistry --chain-id 421614 --slow --broadcast --verify --legacy --skip-simulation +# forge script script/deploy/DeployPortRegistry.s.sol:DeployPortRegistry --chain-id 11155111 --broadcast --verify --legacy +# forge script script/deploy/DeployPortRegistry.s.sol:DeployPortRegistry --chain-id 43 --broadcast --verify # Deploy multi port on testnet -forge script script/deploy/DeployMultiPort.s.sol:DeployMultiPort --chain-id 421614 --slow --broadcast --verify --legacy --skip-simulation -forge script script/deploy/DeployMultiPort.s.sol:DeployMultiPort --chain-id 11155111 --broadcast --verify --legacy -forge script script/deploy/DeployMultiPort.s.sol:DeployMultiPort --chain-id 43 --broadcast --verify +# forge script script/deploy/DeployMultiPort.s.sol:DeployMultiPort --chain-id 421614 --slow --broadcast --verify --legacy --skip-simulation +# forge script script/deploy/DeployMultiPort.s.sol:DeployMultiPort --chain-id 11155111 --broadcast --verify --legacy +# forge script script/deploy/DeployMultiPort.s.sol:DeployMultiPort --chain-id 43 --broadcast --verify # Deploy safe msgport module on testnet -forge script script/deploy/DeploySafeMsgportModule.s.sol:DeploySafeMsgportModule --chain-id 421614 --slow --broadcast --verify --legacy --skip-simulation -forge script script/deploy/DeploySafeMsgportModule.s.sol:DeploySafeMsgportModule --chain-id 11155111 --broadcast --verify --legacy -forge script script/deploy/DeploySafeMsgportModule.s.sol:DeploySafeMsgportModule --chain-id 43 --broadcast --verify +# forge script script/deploy/DeploySafeMsgportModule.s.sol:DeploySafeMsgportModule --chain-id 421614 --slow --broadcast --verify --legacy --skip-simulation +# forge script script/deploy/DeploySafeMsgportModule.s.sol:DeploySafeMsgportModule --chain-id 11155111 --broadcast --verify --legacy +# forge script script/deploy/DeploySafeMsgportModule.s.sol:DeploySafeMsgportModule --chain-id 43 --broadcast --verify # Deploy xaccount factory on testnet -forge script script/deploy/DeployXAccountFactory.s.sol:DeployXAccountFactory --chain-id 421614 --slow --broadcast --verify --legacy --skip-simulation -forge script script/deploy/DeployXAccountFactory.s.sol:DeployXAccountFactory --chain-id 11155111 --broadcast --verify --legacy -forge script script/deploy/DeployXAccountFactory.s.sol:DeployXAccountFactory --chain-id 43 --broadcast --verify +# forge script script/deploy/DeployXAccountFactory.s.sol:DeployXAccountFactory --chain-id 421614 --slow --broadcast --verify --legacy --skip-simulation +# forge script script/deploy/DeployXAccountFactory.s.sol:DeployXAccountFactory --chain-id 11155111 --broadcast --verify --legacy +# forge script script/deploy/DeployXAccountFactory.s.sol:DeployXAccountFactory --chain-id 43 --broadcast --verify # Deploy ormp port on testnet # forge script script/deploy/DeployORMPPort.s.sol:DeployORMPPort --chain-id 43 --broadcast --verify --legacy --skip-simulation # forge script script/deploy/DeployORMPPort.s.sol:DeployORMPPort --chain-id 421614 --broadcast --verify --legacy --skip-simulation # forge script script/deploy/DeployORMPPort.s.sol:DeployORMPPort --chain-id 11155111 --broadcast --verify --legacy -# Deploy ormp-ur port on testnet -# forge script script/deploy/DeployORMPURPort.s.sol:DeployORMPURPort --chain-id 43 --broadcast --verify --legacy -# forge script script/deploy/DeployORMPURPort.s.sol:DeployORMPURPort --chain-id 421614 --broadcast --verify --legacy --skip-simulation -# forge script script/deploy/DeployORMPURPort.s.sol:DeployORMPURPort --chain-id 11155111 --broadcast --verify --legacy +# Deploy ormp-u port on testnet +forge script script/deploy/DeployORMPUPort.s.sol:DeployORMPUPort --chain-id 43 --broadcast --verify --legacy +forge script script/deploy/DeployORMPUPort.s.sol:DeployORMPUPort --chain-id 421614 --broadcast --verify --legacy --skip-simulation +forge script script/deploy/DeployORMPUPort.s.sol:DeployORMPUPort --chain-id 11155111 --broadcast --verify --legacy # forge script script/deploy/DeployORMPPort.s.sol:DeployORMPPort --chain-id 1 --broadcast --verify --slow # forge script script/deploy/DeployORMPPort.s.sol:DeployORMPPort --chain-id 44 --broadcast --verify --slow diff --git a/ipfs/ormp_u.json b/ipfs/ormp_u.json new file mode 100644 index 0000000..90e36ee --- /dev/null +++ b/ipfs/ormp_u.json @@ -0,0 +1,6 @@ +{ + "name": "ORMP-U", + "provider": "Msgport", + "description": "ORMPUpgradeablePort by Msgport", + "api": "https://github.com/darwinia-network/darwinia-msgport-api/blob/main/README.md" +} From e870bcb45ac59f3781bfa6d64702d44fad23b548 Mon Sep 17 00:00:00 2001 From: echo Date: Fri, 22 Mar 2024 21:30:54 +0800 Subject: [PATCH 35/39] clean --- script/test/{ORMPPort.t.sol => ORMPUpgradeablePort.t.sol} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename script/test/{ORMPPort.t.sol => ORMPUpgradeablePort.t.sol} (98%) diff --git a/script/test/ORMPPort.t.sol b/script/test/ORMPUpgradeablePort.t.sol similarity index 98% rename from script/test/ORMPPort.t.sol rename to script/test/ORMPUpgradeablePort.t.sol index 4224504..0f6d422 100644 --- a/script/test/ORMPPort.t.sol +++ b/script/test/ORMPUpgradeablePort.t.sol @@ -10,7 +10,7 @@ import "ORMP/src/UserConfig.sol"; import "../../src/ports/ORMPUpgradeablePort.sol"; import "../../src/ports/base/FromPortLookup.sol"; -contract ORMPPortTest is Test { +contract ORMPUpgradeablePortTest is Test { using Chains for uint256; ORMPUpgradeablePort ormpPort; From 7899fda1e41a0c4a41bbe7fa5ccfb3e310a9eb30 Mon Sep 17 00:00:00 2001 From: echo Date: Fri, 22 Mar 2024 21:31:36 +0800 Subject: [PATCH 36/39] pin solc version to 0.8.17 --- script/test/ORMPUpgradeablePort.t.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/script/test/ORMPUpgradeablePort.t.sol b/script/test/ORMPUpgradeablePort.t.sol index 0f6d422..366dfc3 100644 --- a/script/test/ORMPUpgradeablePort.t.sol +++ b/script/test/ORMPUpgradeablePort.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.17; +pragma solidity 0.8.17; import "forge-std/Test.sol"; import {Chains} from "create3-deploy/script/Chains.sol"; From 1a1a23a74a9069b7b84f8ed802b8e396f27da7ff Mon Sep 17 00:00:00 2001 From: echo Date: Fri, 22 Mar 2024 21:33:20 +0800 Subject: [PATCH 37/39] pin solc version to 0.8.17 --- script/test/ORMPUpgradeablePort.t.sol | 2 +- src/ports/ORMPUpgradeablePort.sol | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/script/test/ORMPUpgradeablePort.t.sol b/script/test/ORMPUpgradeablePort.t.sol index 366dfc3..0f6d422 100644 --- a/script/test/ORMPUpgradeablePort.t.sol +++ b/script/test/ORMPUpgradeablePort.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.17; +pragma solidity ^0.8.17; import "forge-std/Test.sol"; import {Chains} from "create3-deploy/script/Chains.sol"; diff --git a/src/ports/ORMPUpgradeablePort.sol b/src/ports/ORMPUpgradeablePort.sol index 5f320e6..1f220b3 100644 --- a/src/ports/ORMPUpgradeablePort.sol +++ b/src/ports/ORMPUpgradeablePort.sol @@ -15,7 +15,7 @@ // You should have received a copy of the GNU General Public License // along with Darwinia. If not, see . -pragma solidity ^0.8.17; +pragma solidity 0.8.17; import "./base/BaseMessagePort.sol"; import "./base/PortLookup.sol"; From 1ab078de5f062a9ab4a3603ed38cb6f73c444c1c Mon Sep 17 00:00:00 2001 From: echo Date: Mon, 25 Mar 2024 09:44:42 +0800 Subject: [PATCH 38/39] fix --- src/ports/ORMPUpgradeablePort.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ports/ORMPUpgradeablePort.sol b/src/ports/ORMPUpgradeablePort.sol index 1f220b3..8cc7114 100644 --- a/src/ports/ORMPUpgradeablePort.sol +++ b/src/ports/ORMPUpgradeablePort.sol @@ -49,8 +49,8 @@ contract ORMPUpgradeablePort is Ownable2Step, AppBase, BaseMessagePort, PortLook /// 2. delete previousORMP after relay on-flight message. function setORMP(address ormp_) external onlyOwner { address previousORMP = ormp; - require(historyORMPSet.add(previousORMP), "!add"); ormp = ormp_; + require(historyORMPSet.add(ormp_), "!add"); emit SetORMP(previousORMP, ormp_); } From cd25955c4d968559922e3005ff2221f572c57768 Mon Sep 17 00:00:00 2001 From: echo Date: Mon, 25 Mar 2024 17:18:05 +0800 Subject: [PATCH 39/39] add event --- src/ports/ORMPUpgradeablePort.sol | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/ports/ORMPUpgradeablePort.sol b/src/ports/ORMPUpgradeablePort.sol index 8cc7114..e3bb389 100644 --- a/src/ports/ORMPUpgradeablePort.sol +++ b/src/ports/ORMPUpgradeablePort.sol @@ -32,6 +32,8 @@ contract ORMPUpgradeablePort is Ownable2Step, AppBase, BaseMessagePort, PortLook EnumerableSet.AddressSet internal historyORMPSet; event SetORMP(address previousORMP, address currentORMP); + event HistoryORMPAdded(address ormp); + event HistoryORMPDeleted(address ormp); modifier onlyORMP() override { require(historyORMPSet.contains(msg.sender), "!ormps"); @@ -52,11 +54,13 @@ contract ORMPUpgradeablePort is Ownable2Step, AppBase, BaseMessagePort, PortLook ormp = ormp_; require(historyORMPSet.add(ormp_), "!add"); emit SetORMP(previousORMP, ormp_); + emit HistoryORMPAdded(ormp_); } function delORMP(address ormp_) external onlyOwner { require(ormp != ormp_, "sender"); require(historyORMPSet.remove(ormp_), "!del"); + emit HistoryORMPDeleted(ormp_); } function setAppConfig(address ormp_, address oracle, address relayer) external onlyOwner {