diff --git a/src/user/Application.sol b/src/user/Application.sol
index d4dc137..91c45f7 100644
--- a/src/user/Application.sol
+++ b/src/user/Application.sol
@@ -15,9 +15,8 @@
// 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 "../Common.sol";
import "../interfaces/IORMP.sol";
// https://eips.ethereum.org/EIPS/eip-5164
diff --git a/src/user/UpgradeableApplication.sol b/src/user/UpgradeableApplication.sol
new file mode 100644
index 0000000..e685caf
--- /dev/null
+++ b/src/user/UpgradeableApplication.sol
@@ -0,0 +1,78 @@
+// 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 "../interfaces/IORMP.sol";
+
+// https://eips.ethereum.org/EIPS/eip-5164
+abstract contract UpgradeableApplication {
+ address public sender;
+ address public recver;
+
+ event SetSender(address ormp);
+ event SetRecver(address ormp);
+
+ constructor(address ormp) {
+ sender = ormp;
+ recver = ormp;
+ }
+
+ function _setSender(address ormp) internal virtual {
+ sender = ormp;
+ emit SetSender(ormp);
+ }
+
+ function _setRecver(address ormp) internal virtual {
+ recver = ormp;
+ emit SetRecver(ormp);
+ }
+
+ function _setSenderConfig(address oracle, address relayer) internal virtual {
+ IORMP(sender).setAppConfig(oracle, relayer);
+ }
+
+ function _setRecverConfig(address oracle, address relayer) internal virtual {
+ IORMP(recver).setAppConfig(oracle, relayer);
+ }
+
+ modifier onlyORMP() {
+ require(recver == msg.sender, "!ormp");
+ _;
+ }
+
+ function _messageId() internal pure returns (bytes32 _msgDataMessageId) {
+ require(msg.data.length >= 84, "!messageId");
+ assembly {
+ _msgDataMessageId := calldataload(sub(calldatasize(), 84))
+ }
+ }
+
+ function _fromChainId() internal pure returns (uint256 _msgDataFromChainId) {
+ require(msg.data.length >= 52, "!fromChainId");
+ assembly {
+ _msgDataFromChainId := calldataload(sub(calldatasize(), 52))
+ }
+ }
+
+ function _xmsgSender() internal pure returns (address payable _from) {
+ require(msg.data.length >= 20, "!xmsgSender");
+ assembly {
+ _from := shr(96, calldataload(sub(calldatasize(), 20)))
+ }
+ }
+}
diff --git a/test/ORMP.t.sol b/test/ORMP.t.sol
index 981bf00..4074a78 100644
--- a/test/ORMP.t.sol
+++ b/test/ORMP.t.sol
@@ -56,14 +56,14 @@ contract ORMPTest is Test, Verifier {
function test_Refunds() public {
uint256 f = ormp.fee(2, self, 0, "", "");
- ormp.send{value: f+5}(2, self, 0, "", address(5), "");
+ ormp.send{value: f + 5}(2, self, 0, "", address(5), "");
assertEq(address(5).balance, 5);
}
function testFail_sendSameMsg() public {
uint256 f1 = ormp.fee(2, self, 0, "", "");
bytes32 msgHash1 = ormp.send{value: f1}(2, self, 0, "", self, "");
-
+
uint256 f2 = ormp.fee(2, self, 0, "", "");
bytes32 msgHash2 = ormp.send{value: f2}(2, self, 0, "", self, "");
vm.chainId(2);
@@ -94,12 +94,14 @@ contract ORMPTest is Test, Verifier {
uint256 f = ormp.fee(2, self, 0, "", "");
ormp.send{value: f}(2, self, 0, "", self, "");
proof = Proof({blockNumber: block.number, messageIndex: ormp.messageCount() - 1, messageProof: ormp.prove()});
-
+
vm.chainId(2);
bool returnValue = ormp.recv(message, abi.encode(proof));
- assertEq(returnValue, false); /// msg delivery failed
- assertEq(ormp.dones(hash(message)), true); /// but marked dispatched
+ /// msg delivery failed
+ assertEq(returnValue, false);
+ /// but marked dispatched
+ assertEq(ormp.dones(hash(message)), true);
}
function fee(uint256, address) external pure returns (uint256) {