From b405b6b0e21a47d8327717feffeb7b3bbe976274 Mon Sep 17 00:00:00 2001 From: Borja Aranda Date: Mon, 16 Dec 2024 18:54:17 +0100 Subject: [PATCH 1/9] feat: XMTP messages contracts are upgradeable and pausable --- contracts/script/DeployerGroupMessages.s.sol | 28 ++++++++++++++++++++ contracts/script/DeployerNodeRegistry.s.sol | 16 +++++++++++ 2 files changed, 44 insertions(+) create mode 100644 contracts/script/DeployerGroupMessages.s.sol create mode 100644 contracts/script/DeployerNodeRegistry.s.sol diff --git a/contracts/script/DeployerGroupMessages.s.sol b/contracts/script/DeployerGroupMessages.s.sol new file mode 100644 index 00000000..8799afaa --- /dev/null +++ b/contracts/script/DeployerGroupMessages.s.sol @@ -0,0 +1,28 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.28; + +import "forge-std/src/Script.sol"; +import "src/GroupMessages.sol"; +import { ERC1967Proxy } from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol"; + +contract DeployProxiedGroupMessages is Script { + function run() external { + uint256 privateKey = vm.envUint("PRIVATE_KEY"); + vm.startBroadcast(privateKey); + + // Step 1: Deploy the implementation contract + GroupMessages groupMessagesImpl = new GroupMessages(); + + // Step 2: Deploy the proxy contract + ERC1967Proxy proxy = new ERC1967Proxy( + address(groupMessagesImpl), + abi.encodeWithSelector(GroupMessages.initialize.selector) + ); + + // Log the deployed contract addresses + console.log("Implementation Address:", address(groupMessagesImpl)); + console.log("Proxy Address:", address(proxy)); + + vm.stopBroadcast(); + } +} diff --git a/contracts/script/DeployerNodeRegistry.s.sol b/contracts/script/DeployerNodeRegistry.s.sol new file mode 100644 index 00000000..84690866 --- /dev/null +++ b/contracts/script/DeployerNodeRegistry.s.sol @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.28; + +import {Script, console} from "forge-std/src/Script.sol"; +import "src/Nodes.sol"; + +contract Deployer is Script { + function setUp() public {} + + function run() public { + vm.startBroadcast(); + new Nodes(); + + vm.broadcast(); + } +} From d2a93dd696ed3e72c4bc3a50aa1ddbb19639ab95 Mon Sep 17 00:00:00 2001 From: Borja Aranda Date: Wed, 18 Dec 2024 19:19:26 +0100 Subject: [PATCH 2/9] feat: add tests and scripts --- contracts/script/DeployerGroupMessages.s.sol | 28 ------ contracts/script/DeployerNodeRegistry.s.sol | 16 ---- contracts/test/GroupMessage.t.sol | 95 +++++++++++++++++++- 3 files changed, 94 insertions(+), 45 deletions(-) delete mode 100644 contracts/script/DeployerGroupMessages.s.sol delete mode 100644 contracts/script/DeployerNodeRegistry.s.sol diff --git a/contracts/script/DeployerGroupMessages.s.sol b/contracts/script/DeployerGroupMessages.s.sol deleted file mode 100644 index 8799afaa..00000000 --- a/contracts/script/DeployerGroupMessages.s.sol +++ /dev/null @@ -1,28 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity 0.8.28; - -import "forge-std/src/Script.sol"; -import "src/GroupMessages.sol"; -import { ERC1967Proxy } from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol"; - -contract DeployProxiedGroupMessages is Script { - function run() external { - uint256 privateKey = vm.envUint("PRIVATE_KEY"); - vm.startBroadcast(privateKey); - - // Step 1: Deploy the implementation contract - GroupMessages groupMessagesImpl = new GroupMessages(); - - // Step 2: Deploy the proxy contract - ERC1967Proxy proxy = new ERC1967Proxy( - address(groupMessagesImpl), - abi.encodeWithSelector(GroupMessages.initialize.selector) - ); - - // Log the deployed contract addresses - console.log("Implementation Address:", address(groupMessagesImpl)); - console.log("Proxy Address:", address(proxy)); - - vm.stopBroadcast(); - } -} diff --git a/contracts/script/DeployerNodeRegistry.s.sol b/contracts/script/DeployerNodeRegistry.s.sol deleted file mode 100644 index 84690866..00000000 --- a/contracts/script/DeployerNodeRegistry.s.sol +++ /dev/null @@ -1,16 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity 0.8.28; - -import {Script, console} from "forge-std/src/Script.sol"; -import "src/Nodes.sol"; - -contract Deployer is Script { - function setUp() public {} - - function run() public { - vm.startBroadcast(); - new Nodes(); - - vm.broadcast(); - } -} diff --git a/contracts/test/GroupMessage.t.sol b/contracts/test/GroupMessage.t.sol index 9becc55f..83662376 100644 --- a/contracts/test/GroupMessage.t.sol +++ b/contracts/test/GroupMessage.t.sol @@ -192,4 +192,97 @@ contract GroupMessagesTest is Test, GroupMessages, Utils { emit GroupMessages.MessageSent(ID, message, 2); groupMessages.addMessage(ID, message); } -} + + function testAddMessageInvalid() public { + bytes memory message = new bytes(77); + for (uint256 i = 0; i < message.length; i++) { + message[i] = bytes1(uint8(i % 256)); + } + + vm.expectRevert(GroupMessages.InvalidMessage.selector); + groupMessages.addMessage(GROUP_ID, message); + } + + function testInvalidReinitialization() public { + vm.expectRevert(Initializable.InvalidInitialization.selector); + groupMessages.initialize(admin); + } + + function testPauseUnpause() public { + groupMessages.pause(); + + vm.prank(unauthorized); + vm.expectRevert(); + groupMessages.unpause(); + + groupMessages.unpause(); + + vm.prank(unauthorized); + vm.expectRevert(); + groupMessages.pause(); + } + + function testRoles() public { + groupMessages.grantRole(DEFAULT_ADMIN_ROLE, unauthorized); + + vm.startPrank(unauthorized); + groupMessages.pause(); + groupMessages.unpause(); + vm.stopPrank(); + + groupMessages.revokeRole(DEFAULT_ADMIN_ROLE, unauthorized); + + vm.prank(unauthorized); + vm.expectRevert(revertRoleData(unauthorized)); + groupMessages.pause(); + + groupMessages.renounceRole(DEFAULT_ADMIN_ROLE, admin); + vm.expectRevert(revertRoleData(admin)); + groupMessages.pause(); + } + + function testUpgradeImplementation() public { + GroupMessages newGroupMessagesImpl = new GroupMessages(); + address newImplAddress = address(newGroupMessagesImpl); + address oldImplAddress = address(groupMessagesImpl); + + bytes memory message = new bytes(78); + for (uint256 i = 0; i < message.length; i++) { + message[i] = bytes1(uint8(i % 256)); + } + + // Retrieve the implementation address directly from the proxy storage. + bytes32 rawImplAddress = vm.load(address(groupMessages), EIP1967_IMPL_SLOT); + address implementationAddress = address(uint160(uint256(rawImplAddress))); + assertEq(implementationAddress, oldImplAddress); + + // Initialize sequenceId to 1. The state should be preserved between upgrades. + vm.expectEmit(address(groupMessages)); + emit GroupMessages.MessageSent(GROUP_ID, message, 1); + groupMessages.addMessage(GROUP_ID, message); + + // Unauthorized upgrade attempts should revert. + vm.prank(unauthorized); + vm.expectRevert(revertRoleData(unauthorized)); + groupMessages.upgradeToAndCall(address(newGroupMessagesImpl), ""); + + // Authorized upgrade should succeed and emit UpgradeAuthorized event. + vm.expectEmit(address(groupMessages)); + emit GroupMessages.UpgradeAuthorized(address(this), address(newGroupMessagesImpl)); + groupMessages.upgradeToAndCall(address(newGroupMessagesImpl), ""); + + // Retrieve the new implementation address directly from the proxy storage. + rawImplAddress = vm.load(address(groupMessages), EIP1967_IMPL_SLOT); + implementationAddress = address(uint160(uint256(rawImplAddress))); + assertEq(implementationAddress, newImplAddress); + + // Next sequenceId should be 2. + vm.expectEmit(address(groupMessages)); + emit GroupMessages.MessageSent(GROUP_ID, message, 2); + groupMessages.addMessage(GROUP_ID, message); + } + + function revertRoleData(address _user) public pure returns (bytes memory) { + return abi.encodeWithSelector(IAccessControl.AccessControlUnauthorizedAccount.selector, _user, DEFAULT_ADMIN_ROLE); + } +} \ No newline at end of file From 3fc2edbf0de0e5ad1971e3241143d62137b4901a Mon Sep 17 00:00:00 2001 From: Borja Aranda Date: Thu, 19 Dec 2024 11:34:52 +0100 Subject: [PATCH 3/9] add finished scripts --- .../script/output/31337/group_messages_deployment.json | 10 ++++++++++ .../output/31337/identity_updates_deployment.json | 10 ++++++++++ contracts/test/GroupMessage.t.sol | 4 +++- 3 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 contracts/script/output/31337/group_messages_deployment.json create mode 100644 contracts/script/output/31337/identity_updates_deployment.json diff --git a/contracts/script/output/31337/group_messages_deployment.json b/contracts/script/output/31337/group_messages_deployment.json new file mode 100644 index 00000000..25f1f10b --- /dev/null +++ b/contracts/script/output/31337/group_messages_deployment.json @@ -0,0 +1,10 @@ +{ + "addresses": { + "groupMessagesDeployer": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "groupMessagesImpl": "0xD0141E899a65C95a556fE2B27e5982A6DE7fDD7A", + "groupMessagesProxy": "0xD5ac451B0c50B9476107823Af206eD814a2e2580", + "groupMessagesProxyAdmin": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266" + }, + "deploymentBlock": 104, + "latestUpgradeBlock": 110 +} \ No newline at end of file diff --git a/contracts/script/output/31337/identity_updates_deployment.json b/contracts/script/output/31337/identity_updates_deployment.json new file mode 100644 index 00000000..5e6af9b5 --- /dev/null +++ b/contracts/script/output/31337/identity_updates_deployment.json @@ -0,0 +1,10 @@ +{ + "addresses": { + "identityUpdatesDeployer": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "identityUpdatesImpl": "0x18E317A7D70d8fBf8e6E893616b52390EbBdb629", + "identityUpdatesProxy": "0x5067457698Fd6Fa1C6964e416b3f42713513B3dD", + "identityUpdatesProxyAdmin": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266" + }, + "deploymentBlock": 100, + "latestUpgradeBlock": 108 +} \ No newline at end of file diff --git a/contracts/test/GroupMessage.t.sol b/contracts/test/GroupMessage.t.sol index 83662376..c266f757 100644 --- a/contracts/test/GroupMessage.t.sol +++ b/contracts/test/GroupMessage.t.sol @@ -197,7 +197,7 @@ contract GroupMessagesTest is Test, GroupMessages, Utils { bytes memory message = new bytes(77); for (uint256 i = 0; i < message.length; i++) { message[i] = bytes1(uint8(i % 256)); - } + } vm.expectRevert(GroupMessages.InvalidMessage.selector); groupMessages.addMessage(GROUP_ID, message); @@ -210,12 +210,14 @@ contract GroupMessagesTest is Test, GroupMessages, Utils { function testPauseUnpause() public { groupMessages.pause(); + assertTrue(groupMessages.paused()); vm.prank(unauthorized); vm.expectRevert(); groupMessages.unpause(); groupMessages.unpause(); + assertFalse(groupMessages.paused()); vm.prank(unauthorized); vm.expectRevert(); From ce4214082a30e4798b89425036084028367894b0 Mon Sep 17 00:00:00 2001 From: Borja Aranda Date: Thu, 19 Dec 2024 14:25:38 +0100 Subject: [PATCH 4/9] include finished contracts, ci and readme --- .../31337/group_messages_deployment.json | 8 +- .../31337/identity_updates_deployment.json | 6 +- contracts/test/GroupMessage.t.sol | 115 ++++++++++++++---- 3 files changed, 95 insertions(+), 34 deletions(-) diff --git a/contracts/script/output/31337/group_messages_deployment.json b/contracts/script/output/31337/group_messages_deployment.json index 25f1f10b..d22c1632 100644 --- a/contracts/script/output/31337/group_messages_deployment.json +++ b/contracts/script/output/31337/group_messages_deployment.json @@ -1,10 +1,10 @@ { "addresses": { "groupMessagesDeployer": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", - "groupMessagesImpl": "0xD0141E899a65C95a556fE2B27e5982A6DE7fDD7A", - "groupMessagesProxy": "0xD5ac451B0c50B9476107823Af206eD814a2e2580", + "groupMessagesImpl": "0xe8D2A1E88c91DCd5433208d4152Cc4F399a7e91d", + "groupMessagesProxy": "0x5067457698Fd6Fa1C6964e416b3f42713513B3dD", "groupMessagesProxyAdmin": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266" }, - "deploymentBlock": 104, - "latestUpgradeBlock": 110 + "deploymentBlock": 100, + "latestUpgradeBlock": 100 } \ No newline at end of file diff --git a/contracts/script/output/31337/identity_updates_deployment.json b/contracts/script/output/31337/identity_updates_deployment.json index 5e6af9b5..1ec61bc4 100644 --- a/contracts/script/output/31337/identity_updates_deployment.json +++ b/contracts/script/output/31337/identity_updates_deployment.json @@ -2,9 +2,9 @@ "addresses": { "identityUpdatesDeployer": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", "identityUpdatesImpl": "0x18E317A7D70d8fBf8e6E893616b52390EbBdb629", - "identityUpdatesProxy": "0x5067457698Fd6Fa1C6964e416b3f42713513B3dD", + "identityUpdatesProxy": "0x4b6aB5F819A515382B0dEB6935D793817bB4af28", "identityUpdatesProxyAdmin": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266" }, - "deploymentBlock": 100, - "latestUpgradeBlock": 108 + "deploymentBlock": 102, + "latestUpgradeBlock": 102 } \ No newline at end of file diff --git a/contracts/test/GroupMessage.t.sol b/contracts/test/GroupMessage.t.sol index c266f757..72bcb3a9 100644 --- a/contracts/test/GroupMessage.t.sol +++ b/contracts/test/GroupMessage.t.sol @@ -193,14 +193,64 @@ contract GroupMessagesTest is Test, GroupMessages, Utils { groupMessages.addMessage(ID, message); } - function testAddMessageInvalid() public { - bytes memory message = new bytes(77); - for (uint256 i = 0; i < message.length; i++) { - message[i] = bytes1(uint8(i % 256)); - } - - vm.expectRevert(GroupMessages.InvalidMessage.selector); - groupMessages.addMessage(GROUP_ID, message); + function testAddMessageWithMaxPayload() public { + bytes memory message = _generatePayload(MAX_PAYLOAD_SIZE); + + vm.expectEmit(address(groupMessages)); + emit GroupMessages.MessageSent(ID, message, 1); + + groupMessages.addMessage(ID, message); + } + + function testAddMessageTooSmall() public { + bytes memory message = _generatePayload(MIN_PAYLOAD_SIZE - 1); + + vm.expectRevert( + abi.encodeWithSelector( + GroupMessages.InvalidPayloadSize.selector, message.length, MIN_PAYLOAD_SIZE, MAX_PAYLOAD_SIZE + ) + ); + + groupMessages.addMessage(ID, message); + } + + function testAddMessageTooBig() public { + bytes memory message = _generatePayload(MAX_PAYLOAD_SIZE + 1); + + vm.expectRevert( + abi.encodeWithSelector( + GroupMessages.InvalidPayloadSize.selector, message.length, MIN_PAYLOAD_SIZE, MAX_PAYLOAD_SIZE + ) + ); + + groupMessages.addMessage(ID, message); + } + + function testAddMessageWhenPaused() public { + bytes memory message = _generatePayload(MIN_PAYLOAD_SIZE); + + groupMessages.pause(); + assertTrue(groupMessages.paused()); + + vm.expectRevert(abi.encodeWithSelector(PausableUpgradeable.EnforcedPause.selector)); + + groupMessages.addMessage(ID, message); + } + + function testSequenceIdIncrement() public { + bytes memory message = _generatePayload(MIN_PAYLOAD_SIZE); + + vm.expectEmit(address(groupMessages)); + emit GroupMessages.MessageSent(ID, message, 1); + groupMessages.addMessage(ID, message); + + vm.expectEmit(address(groupMessages)); + emit GroupMessages.MessageSent(ID, message, 2); + groupMessages.addMessage(ID, message); + + vm.expectEmit(address(groupMessages)); + emit GroupMessages.MessageSent(ID, message, 3); + groupMessages.addMessage(ID, message); } function testInvalidReinitialization() public { @@ -213,14 +263,22 @@ contract GroupMessagesTest is Test, GroupMessages, Utils { assertTrue(groupMessages.paused()); vm.prank(unauthorized); - vm.expectRevert(); + vm.expectRevert( + abi.encodeWithSelector( + IAccessControl.AccessControlUnauthorizedAccount.selector, unauthorized, DEFAULT_ADMIN_ROLE + ) + ); groupMessages.unpause(); groupMessages.unpause(); assertFalse(groupMessages.paused()); vm.prank(unauthorized); - vm.expectRevert(); + vm.expectRevert( + abi.encodeWithSelector( + IAccessControl.AccessControlUnauthorizedAccount.selector, unauthorized, DEFAULT_ADMIN_ROLE + ) + ); groupMessages.pause(); } @@ -235,11 +293,17 @@ contract GroupMessagesTest is Test, GroupMessages, Utils { groupMessages.revokeRole(DEFAULT_ADMIN_ROLE, unauthorized); vm.prank(unauthorized); - vm.expectRevert(revertRoleData(unauthorized)); + vm.expectRevert( + abi.encodeWithSelector( + IAccessControl.AccessControlUnauthorizedAccount.selector, unauthorized, DEFAULT_ADMIN_ROLE + ) + ); groupMessages.pause(); groupMessages.renounceRole(DEFAULT_ADMIN_ROLE, admin); - vm.expectRevert(revertRoleData(admin)); + vm.expectRevert( + abi.encodeWithSelector(IAccessControl.AccessControlUnauthorizedAccount.selector, admin, DEFAULT_ADMIN_ROLE) + ); groupMessages.pause(); } @@ -247,11 +311,8 @@ contract GroupMessagesTest is Test, GroupMessages, Utils { GroupMessages newGroupMessagesImpl = new GroupMessages(); address newImplAddress = address(newGroupMessagesImpl); address oldImplAddress = address(groupMessagesImpl); - - bytes memory message = new bytes(78); - for (uint256 i = 0; i < message.length; i++) { - message[i] = bytes1(uint8(i % 256)); - } + + bytes memory message = _generatePayload(MIN_PAYLOAD_SIZE); // Retrieve the implementation address directly from the proxy storage. bytes32 rawImplAddress = vm.load(address(groupMessages), EIP1967_IMPL_SLOT); @@ -260,12 +321,16 @@ contract GroupMessagesTest is Test, GroupMessages, Utils { // Initialize sequenceId to 1. The state should be preserved between upgrades. vm.expectEmit(address(groupMessages)); - emit GroupMessages.MessageSent(GROUP_ID, message, 1); - groupMessages.addMessage(GROUP_ID, message); + emit GroupMessages.MessageSent(ID, message, 1); + groupMessages.addMessage(ID, message); // Unauthorized upgrade attempts should revert. vm.prank(unauthorized); - vm.expectRevert(revertRoleData(unauthorized)); + vm.expectRevert( + abi.encodeWithSelector( + IAccessControl.AccessControlUnauthorizedAccount.selector, unauthorized, DEFAULT_ADMIN_ROLE + ) + ); groupMessages.upgradeToAndCall(address(newGroupMessagesImpl), ""); // Authorized upgrade should succeed and emit UpgradeAuthorized event. @@ -280,11 +345,7 @@ contract GroupMessagesTest is Test, GroupMessages, Utils { // Next sequenceId should be 2. vm.expectEmit(address(groupMessages)); - emit GroupMessages.MessageSent(GROUP_ID, message, 2); - groupMessages.addMessage(GROUP_ID, message); - } - - function revertRoleData(address _user) public pure returns (bytes memory) { - return abi.encodeWithSelector(IAccessControl.AccessControlUnauthorizedAccount.selector, _user, DEFAULT_ADMIN_ROLE); + emit GroupMessages.MessageSent(ID, message, 2); + groupMessages.addMessage(ID, message); } -} \ No newline at end of file +} From bc37841727bbf1f8bb3802fee89704e74478c297 Mon Sep 17 00:00:00 2001 From: Borja Aranda Date: Fri, 20 Dec 2024 13:47:15 +0100 Subject: [PATCH 5/9] make CI happy --- contracts/script/output/31337/GroupMessages.json | 10 ++++++++++ contracts/script/output/31337/IdentityUpdates.json | 10 ++++++++++ .../script/output/31337/group_messages_deployment.json | 10 ---------- .../output/31337/identity_updates_deployment.json | 10 ---------- 4 files changed, 20 insertions(+), 20 deletions(-) create mode 100644 contracts/script/output/31337/GroupMessages.json create mode 100644 contracts/script/output/31337/IdentityUpdates.json delete mode 100644 contracts/script/output/31337/group_messages_deployment.json delete mode 100644 contracts/script/output/31337/identity_updates_deployment.json diff --git a/contracts/script/output/31337/GroupMessages.json b/contracts/script/output/31337/GroupMessages.json new file mode 100644 index 00000000..0a15425f --- /dev/null +++ b/contracts/script/output/31337/GroupMessages.json @@ -0,0 +1,10 @@ +{ + "addresses": { + "groupMessagesDeployer": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "groupMessagesImpl": "0xc0F115A19107322cFBf1cDBC7ea011C19EbDB4F8", + "groupMessagesProxy": "0xc96304e3c037f81dA488ed9dEa1D8F2a48278a75", + "groupMessagesProxyAdmin": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266" + }, + "deploymentBlock": 107, + "latestUpgradeBlock": 107 +} \ No newline at end of file diff --git a/contracts/script/output/31337/IdentityUpdates.json b/contracts/script/output/31337/IdentityUpdates.json new file mode 100644 index 00000000..ca52f0e1 --- /dev/null +++ b/contracts/script/output/31337/IdentityUpdates.json @@ -0,0 +1,10 @@ +{ + "addresses": { + "identityUpdatesDeployer": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "identityUpdatesImpl": "0x34B40BA116d5Dec75548a9e9A8f15411461E8c70", + "identityUpdatesProxy": "0xD0141E899a65C95a556fE2B27e5982A6DE7fDD7A", + "identityUpdatesProxyAdmin": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266" + }, + "deploymentBlock": 109, + "latestUpgradeBlock": 109 +} \ No newline at end of file diff --git a/contracts/script/output/31337/group_messages_deployment.json b/contracts/script/output/31337/group_messages_deployment.json deleted file mode 100644 index d22c1632..00000000 --- a/contracts/script/output/31337/group_messages_deployment.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "addresses": { - "groupMessagesDeployer": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", - "groupMessagesImpl": "0xe8D2A1E88c91DCd5433208d4152Cc4F399a7e91d", - "groupMessagesProxy": "0x5067457698Fd6Fa1C6964e416b3f42713513B3dD", - "groupMessagesProxyAdmin": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266" - }, - "deploymentBlock": 100, - "latestUpgradeBlock": 100 -} \ No newline at end of file diff --git a/contracts/script/output/31337/identity_updates_deployment.json b/contracts/script/output/31337/identity_updates_deployment.json deleted file mode 100644 index 1ec61bc4..00000000 --- a/contracts/script/output/31337/identity_updates_deployment.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "addresses": { - "identityUpdatesDeployer": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", - "identityUpdatesImpl": "0x18E317A7D70d8fBf8e6E893616b52390EbBdb629", - "identityUpdatesProxy": "0x4b6aB5F819A515382B0dEB6935D793817bB4af28", - "identityUpdatesProxyAdmin": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266" - }, - "deploymentBlock": 102, - "latestUpgradeBlock": 102 -} \ No newline at end of file From e07716d8c9637c1bbe324a0d978caa284508b7ce Mon Sep 17 00:00:00 2001 From: Borja Aranda Date: Fri, 20 Dec 2024 14:57:44 +0100 Subject: [PATCH 6/9] move contract dev scripts to dev/contracts --- contracts/script/output/31337/GroupMessages.json | 8 ++++---- contracts/script/output/31337/IdentityUpdates.json | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/contracts/script/output/31337/GroupMessages.json b/contracts/script/output/31337/GroupMessages.json index 0a15425f..d20f6cc2 100644 --- a/contracts/script/output/31337/GroupMessages.json +++ b/contracts/script/output/31337/GroupMessages.json @@ -1,10 +1,10 @@ { "addresses": { "groupMessagesDeployer": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", - "groupMessagesImpl": "0xc0F115A19107322cFBf1cDBC7ea011C19EbDB4F8", - "groupMessagesProxy": "0xc96304e3c037f81dA488ed9dEa1D8F2a48278a75", + "groupMessagesImpl": "0xB0f05d25e41FbC2b52013099ED9616f1206Ae21B", + "groupMessagesProxy": "0x5FeaeBfB4439F3516c74939A9D04e95AFE82C4ae", "groupMessagesProxyAdmin": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266" }, - "deploymentBlock": 107, - "latestUpgradeBlock": 107 + "deploymentBlock": 43, + "latestUpgradeBlock": 43 } \ No newline at end of file diff --git a/contracts/script/output/31337/IdentityUpdates.json b/contracts/script/output/31337/IdentityUpdates.json index ca52f0e1..cd8f4b2a 100644 --- a/contracts/script/output/31337/IdentityUpdates.json +++ b/contracts/script/output/31337/IdentityUpdates.json @@ -1,10 +1,10 @@ { "addresses": { "identityUpdatesDeployer": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", - "identityUpdatesImpl": "0x34B40BA116d5Dec75548a9e9A8f15411461E8c70", - "identityUpdatesProxy": "0xD0141E899a65C95a556fE2B27e5982A6DE7fDD7A", + "identityUpdatesImpl": "0x976fcd02f7C4773dd89C309fBF55D5923B4c98a1", + "identityUpdatesProxy": "0x19cEcCd6942ad38562Ee10bAfd44776ceB67e923", "identityUpdatesProxyAdmin": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266" }, - "deploymentBlock": 109, - "latestUpgradeBlock": 109 + "deploymentBlock": 45, + "latestUpgradeBlock": 45 } \ No newline at end of file From cc661e25e838cc19f8ba25b5693ad9b82162aa18 Mon Sep 17 00:00:00 2001 From: Borja Aranda Date: Sun, 22 Dec 2024 14:36:37 +0100 Subject: [PATCH 7/9] generate config in human readable names --- contracts/script/output/31337/GroupMessages.json | 10 ---------- contracts/script/output/31337/IdentityUpdates.json | 10 ---------- 2 files changed, 20 deletions(-) delete mode 100644 contracts/script/output/31337/GroupMessages.json delete mode 100644 contracts/script/output/31337/IdentityUpdates.json diff --git a/contracts/script/output/31337/GroupMessages.json b/contracts/script/output/31337/GroupMessages.json deleted file mode 100644 index d20f6cc2..00000000 --- a/contracts/script/output/31337/GroupMessages.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "addresses": { - "groupMessagesDeployer": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", - "groupMessagesImpl": "0xB0f05d25e41FbC2b52013099ED9616f1206Ae21B", - "groupMessagesProxy": "0x5FeaeBfB4439F3516c74939A9D04e95AFE82C4ae", - "groupMessagesProxyAdmin": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266" - }, - "deploymentBlock": 43, - "latestUpgradeBlock": 43 -} \ No newline at end of file diff --git a/contracts/script/output/31337/IdentityUpdates.json b/contracts/script/output/31337/IdentityUpdates.json deleted file mode 100644 index cd8f4b2a..00000000 --- a/contracts/script/output/31337/IdentityUpdates.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "addresses": { - "identityUpdatesDeployer": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", - "identityUpdatesImpl": "0x976fcd02f7C4773dd89C309fBF55D5923B4c98a1", - "identityUpdatesProxy": "0x19cEcCd6942ad38562Ee10bAfd44776ceB67e923", - "identityUpdatesProxyAdmin": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266" - }, - "deploymentBlock": 45, - "latestUpgradeBlock": 45 -} \ No newline at end of file From 0f862bf58e58b87809901f047837ab6660827be8 Mon Sep 17 00:00:00 2001 From: Borja Aranda Date: Mon, 23 Dec 2024 16:00:25 +0100 Subject: [PATCH 8/9] chore: move contract logic to contracts folder --- .github/workflows/solidity.yml | 10 +-- .github/workflows/test.yml | 2 +- .vscode/settings.json | 3 +- .../config/anvil_localnet/GroupMessages.json | 8 +- .../anvil_localnet/IdentityUpdates.json | 8 +- {dev/contracts => contracts/dev}/deploy-local | 15 ++-- .../dev}/deploy-testnet | 0 contracts/dev/generate | 70 ++++++++++++++++++ {dev/contracts => contracts/dev/lib}/common | 14 ++-- dev/contracts/.env => contracts/dev/lib/env | 0 .../pkg/groupmessages/GroupMessages.go | 2 +- .../pkg/identityupdates/IdentityUpdates.go | 2 +- .../nodes.go => contracts/pkg/nodes/Nodes.go | 2 +- contracts/src/GroupMessages.sol | 2 + contracts/src/IdentityUpdates.sol | 2 + dev/baked/Dockerfile | 2 +- dev/contracts/deploy-ephemeral | 11 --- dev/contracts/generate | 25 ------- dev/generate | 2 +- dev/local.env | 2 +- dev/up | 4 +- doc/deploy.md | 52 ++++++------- pkg/api/payer/publish_test.go | 4 +- pkg/api/payer/service.go | 7 +- pkg/blockchain/blockchainPublisher.go | 15 ++-- pkg/blockchain/interface.go | 7 +- pkg/blockchain/registryAdmin.go | 12 +-- pkg/indexer/indexer.go | 15 ++-- pkg/indexer/storer/groupMessage.go | 6 +- pkg/indexer/storer/groupMessage_test.go | 6 +- pkg/indexer/storer/identityUpdate.go | 6 +- pkg/indexer/storer/identityUpdate_test.go | 4 +- .../blockchain/mock_IBlockchainPublisher.go | 33 +++++---- pkg/mocks/registry/mock_NodesContract.go | 17 +++-- pkg/registry/contractRegistry.go | 9 ++- pkg/registry/contractRegistry_test.go | 20 ++--- pkg/registry/interface.go | 4 +- pkg/testutils/contracts.go | 73 ++++++++++++------- pkg/utils/chainEvent_test.go | 6 +- 39 files changed, 277 insertions(+), 205 deletions(-) rename {dev/contracts => contracts/dev}/deploy-local (60%) rename {dev/contracts => contracts/dev}/deploy-testnet (100%) create mode 100755 contracts/dev/generate rename {dev/contracts => contracts/dev/lib}/common (77%) rename dev/contracts/.env => contracts/dev/lib/env (100%) rename pkg/abis/groupMessages.go => contracts/pkg/groupmessages/GroupMessages.go (99%) rename pkg/abis/identityUpdates.go => contracts/pkg/identityupdates/IdentityUpdates.go (99%) rename pkg/abis/nodes.go => contracts/pkg/nodes/Nodes.go (99%) delete mode 100755 dev/contracts/deploy-ephemeral delete mode 100755 dev/contracts/generate diff --git a/.github/workflows/solidity.yml b/.github/workflows/solidity.yml index a1482f09..d47dbcb8 100644 --- a/.github/workflows/solidity.yml +++ b/.github/workflows/solidity.yml @@ -1,4 +1,4 @@ -name: CI Solidity +name: Solidity on: push: @@ -37,7 +37,7 @@ jobs: run: forge build - name: Cache data - uses: actions/cache@v4 + uses: actions/cache/save@v4 with: path: contracts key: ci-solidity-${{ github.ref }} @@ -56,7 +56,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Restore cache - uses: actions/cache@v4 + uses: actions/cache/restore@v4 with: path: contracts key: ci-solidity-${{ github.ref }} @@ -77,7 +77,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Restore cache - uses: actions/cache@v4 + uses: actions/cache/restore@v4 with: path: contracts key: ci-solidity-${{ github.ref }} @@ -98,7 +98,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Restore cache - uses: actions/cache@v4 + uses: actions/cache/restore@v4 with: path: contracts key: ci-solidity-${{ github.ref }} diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 8544c06d..352c3d39 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -28,7 +28,7 @@ jobs: uses: foundry-rs/foundry-toolchain@v1 with: version: "nightly-ac81a53d1d5823919ffbadd3c65f081927aa11f2" - - run: dev/contracts/deploy-local + - run: contracts/dev/deploy-local - name: Run Tests run: | export GOPATH="${HOME}/go/" diff --git a/.vscode/settings.json b/.vscode/settings.json index 8918121c..684be825 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -17,5 +17,6 @@ ] }, "solidity.compileUsingRemoteVersion": "v0.8.28", - "solidity.formatter": "forge" + "solidity.formatter": "forge", + "wake.compiler.solc.remappings": [] } diff --git a/contracts/config/anvil_localnet/GroupMessages.json b/contracts/config/anvil_localnet/GroupMessages.json index 7ade0abb..1c217d30 100644 --- a/contracts/config/anvil_localnet/GroupMessages.json +++ b/contracts/config/anvil_localnet/GroupMessages.json @@ -1,10 +1,10 @@ { "addresses": { "groupMessagesDeployer": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", - "groupMessagesImpl": "0x0a17FabeA4633ce714F1Fa4a2dcA62C3bAc4758d", - "groupMessagesProxy": "0x3C1Cb427D20F15563aDa8C249E71db76d7183B6c", + "groupMessagesImpl": "0x5f246ADDCF057E0f778CD422e20e413be70f9a0c", + "groupMessagesProxy": "0xaD82Ecf79e232B0391C5479C7f632aA1EA701Ed1", "groupMessagesProxyAdmin": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266" }, - "deploymentBlock": 65, - "latestUpgradeBlock": 71 + "deploymentBlock": 160, + "latestUpgradeBlock": 160 } \ No newline at end of file diff --git a/contracts/config/anvil_localnet/IdentityUpdates.json b/contracts/config/anvil_localnet/IdentityUpdates.json index bcdaf689..bd96842c 100644 --- a/contracts/config/anvil_localnet/IdentityUpdates.json +++ b/contracts/config/anvil_localnet/IdentityUpdates.json @@ -1,10 +1,10 @@ { "addresses": { "identityUpdatesDeployer": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", - "identityUpdatesImpl": "0x1343248Cbd4e291C6979e70a138f4c774e902561", - "identityUpdatesProxy": "0x22a9B82A6c3D2BFB68F324B2e8367f346Dd6f32a", + "identityUpdatesImpl": "0x4Dd5336F3C0D70893A7a86c6aEBe9B953E87c891", + "identityUpdatesProxy": "0x91A1EeE63f300B8f41AE6AF67eDEa2e2ed8c3f79", "identityUpdatesProxyAdmin": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266" }, - "deploymentBlock": 67, - "latestUpgradeBlock": 67 + "deploymentBlock": 162, + "latestUpgradeBlock": 162 } \ No newline at end of file diff --git a/dev/contracts/deploy-local b/contracts/dev/deploy-local similarity index 60% rename from dev/contracts/deploy-local rename to contracts/dev/deploy-local index 6249f2c2..b6d0c656 100755 --- a/dev/contracts/deploy-local +++ b/contracts/dev/deploy-local @@ -1,14 +1,17 @@ #!/bin/bash # Deploy the smart contracts to the local anvil node set -euo pipefail -source dev/contracts/.env -source dev/contracts/common # Make sure the build directory exists mkdir -p ./build -# Move to working directory -cd ./contracts +# Always work from the contracts directory +script_dir=$(dirname "$(realpath "$0")") +repo_root=$(realpath "${script_dir}/../") +cd "${repo_root}" + +source dev/lib/env +source dev/lib/common # Update depencencies forge soldeer update &> /dev/null @@ -19,6 +22,4 @@ fi forge_deploy_script group_messages forge_deploy_script identity_updates - -# TODO: This should be a function in the forge CLI -deploy_contract src/Nodes.sol Nodes +forge_deploy_script nodes src/Nodes.sol Nodes diff --git a/dev/contracts/deploy-testnet b/contracts/dev/deploy-testnet similarity index 100% rename from dev/contracts/deploy-testnet rename to contracts/dev/deploy-testnet diff --git a/contracts/dev/generate b/contracts/dev/generate new file mode 100755 index 00000000..e97b3677 --- /dev/null +++ b/contracts/dev/generate @@ -0,0 +1,70 @@ +#!/bin/bash + +set -euo pipefail + +# Default directories (can be overridden with environment variables) +source_dir="${SOURCE_DIR:-src}" +build_dir="${BUILD_DIR:-build}" +output_dir="${OUTPUT_DIR:-pkg}" + +# Ensure required directories exist and clean up old artifacts +function setup_directories() { + mkdir -p "${build_dir}" "${output_dir}" +} + +# Generate bindings for a given contract +function generate_bindings() { + local filename="$1" + local package="$(echo "${filename}" | tr '[:upper:]' '[:lower:]')" + local source_artifact="${source_dir}/${filename}.sol" + local build_artifact="${build_dir}/${filename}" + local output_artifact="${output_dir}/${package}/${filename}.go" + + rm -f "${build_artifact}".*.json + mkdir -p "${output_dir}/${package}" + rm -f "${output_dir}/${package}"/*.go + + # Generate ABI and bytecode + if ! forge inspect "${source_artifact}:${filename}" abi > "${build_artifact}.abi.json"; then + echo "ERROR: Failed to generate ABI for ${filename}" >&2 + exit 1 + fi + + if ! forge inspect "${source_artifact}:${filename}" bytecode > "${build_artifact}.bin.json"; then + echo "ERROR: Failed to generate bytecode for ${filename}" >&2 + exit 1 + fi + + # Generate Go bindings + if ! abigen --abi "${build_artifact}.abi.json" \ + --bin "${build_artifact}.bin.json" \ + --pkg "${package}" \ + --type "${filename}" \ + --out "${output_artifact}" > /dev/null 2>&1; then + echo "ERROR: Failed to generate bindings for ${filename}" >&2 + exit 1 + fi +} + +function main() { + # Always work from the contracts directory + script_dir=$(dirname "$(realpath "$0")") + repo_root=$(realpath "${script_dir}/../") + cd "${repo_root}" + + setup_directories + + # Define contracts (pass as arguments or use a default list) + local contracts=("$@") + if [ "${#contracts[@]}" -eq 0 ]; then + contracts=("Nodes" "GroupMessages" "IdentityUpdates") + fi + + # Generate bindings for each contract + for contract in "${contracts[@]}"; do + echo "Processing contract: ${contract}" + generate_bindings "${contract}" + done +} + +main "$@" diff --git a/dev/contracts/common b/contracts/dev/lib/common similarity index 77% rename from dev/contracts/common rename to contracts/dev/lib/common index 4ab899ea..f5585254 100644 --- a/dev/contracts/common +++ b/contracts/dev/lib/common @@ -27,15 +27,17 @@ function forge_deploy_script() { echo -e "\n" ;; + nodes) + # TODO: Migrate to forge script + forge create --broadcast --legacy --json --rpc-url $DOCKER_RPC_URL --private-key $PRIVATE_KEY "$2:$3" > ../build/$3.json + echo -e "✅ Nodes contract deployed.\n" + cat ../build/$3.json + echo -e "\n" + ;; + *) echo "Invalid option. Use 'group_messages' or 'identity_updates'." exit 1 ;; esac } - -# Deploy a contract and save the output (which includes the contract address) to a JSON file to be used in tests -# TODO: This should be a function in the forge CLI -function deploy_contract() { - forge create --broadcast --legacy --json --rpc-url $DOCKER_RPC_URL --private-key $PRIVATE_KEY "$1:$2" > ../build/$2.json -} diff --git a/dev/contracts/.env b/contracts/dev/lib/env similarity index 100% rename from dev/contracts/.env rename to contracts/dev/lib/env diff --git a/pkg/abis/groupMessages.go b/contracts/pkg/groupmessages/GroupMessages.go similarity index 99% rename from pkg/abis/groupMessages.go rename to contracts/pkg/groupmessages/GroupMessages.go index 47355324..7f226ee9 100644 --- a/pkg/abis/groupMessages.go +++ b/contracts/pkg/groupmessages/GroupMessages.go @@ -1,7 +1,7 @@ // Code generated - DO NOT EDIT. // This file is a generated binding and any manual changes will be lost. -package abis +package groupmessages import ( "errors" diff --git a/pkg/abis/identityUpdates.go b/contracts/pkg/identityupdates/IdentityUpdates.go similarity index 99% rename from pkg/abis/identityUpdates.go rename to contracts/pkg/identityupdates/IdentityUpdates.go index 1a1b5af4..c4a2d5d2 100644 --- a/pkg/abis/identityUpdates.go +++ b/contracts/pkg/identityupdates/IdentityUpdates.go @@ -1,7 +1,7 @@ // Code generated - DO NOT EDIT. // This file is a generated binding and any manual changes will be lost. -package abis +package identityupdates import ( "errors" diff --git a/pkg/abis/nodes.go b/contracts/pkg/nodes/Nodes.go similarity index 99% rename from pkg/abis/nodes.go rename to contracts/pkg/nodes/Nodes.go index 68343855..69ea8657 100644 --- a/pkg/abis/nodes.go +++ b/contracts/pkg/nodes/Nodes.go @@ -1,7 +1,7 @@ // Code generated - DO NOT EDIT. // This file is a generated binding and any manual changes will be lost. -package abis +package nodes import ( "errors" diff --git a/contracts/src/GroupMessages.sol b/contracts/src/GroupMessages.sol index 912fbdb3..e2acbcdc 100644 --- a/contracts/src/GroupMessages.sol +++ b/contracts/src/GroupMessages.sol @@ -30,9 +30,11 @@ contract GroupMessages is Initializable, AccessControlUpgradeable, UUPSUpgradeab uint256 public constant MAX_PAYLOAD_SIZE = 4_194_304; // State variables + // slither-disable-next-line unused-state,constable-states uint64 private sequenceId; /// @dev Reserved storage gap for future upgrades + // slither-disable-next-line unused-state,naming-convention uint256[50] private __gap; // Initialization diff --git a/contracts/src/IdentityUpdates.sol b/contracts/src/IdentityUpdates.sol index 7e6eaeca..6d46d438 100644 --- a/contracts/src/IdentityUpdates.sol +++ b/contracts/src/IdentityUpdates.sol @@ -30,9 +30,11 @@ contract IdentityUpdates is Initializable, AccessControlUpgradeable, UUPSUpgrade uint256 public constant MAX_PAYLOAD_SIZE = 4_194_304; // State variables + // slither-disable-next-line unused-state,constable-states uint64 private sequenceId; /// @dev Reserved storage gap for future upgrades + // slither-disable-next-line unused-state,naming-convention uint256[50] private __gap; // Initialization diff --git a/dev/baked/Dockerfile b/dev/baked/Dockerfile index dd09529c..b6e8a579 100644 --- a/dev/baked/Dockerfile +++ b/dev/baked/Dockerfile @@ -22,7 +22,7 @@ COPY . . # It seems that anvil flushes the file to disk on shutdown and it takes a few ms to be persisted # That gives us the pkill+sleep requirement RUN dev/docker/anvil-background && \ - dev/contracts/deploy-local && \ + contracts/dev/deploy-local && \ dev/register-local-node && \ dev/register-local-node-2 && \ pkill -f anvil && \ diff --git a/dev/contracts/deploy-ephemeral b/dev/contracts/deploy-ephemeral deleted file mode 100755 index 5bef356e..00000000 --- a/dev/contracts/deploy-ephemeral +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/bash -# Deploy the smart contracts to the local anvil node and log the resulting JSON - -source dev/contracts/.env - -cd ./contracts - -# Update depencencies -forge soldeer install - -forge create --legacy --json --broadcast --rpc-url $DOCKER_RPC_URL --private-key $PRIVATE_KEY "$1:$2" \ No newline at end of file diff --git a/dev/contracts/generate b/dev/contracts/generate deleted file mode 100755 index 9031c821..00000000 --- a/dev/contracts/generate +++ /dev/null @@ -1,25 +0,0 @@ -#!/bin/bash - -set -e - -PACKAGE_NAME="abis" -BUILD_DIR="build" -OUTPUT_DIR="pkg/abis" - -mkdir -p ./build -rm -f ./build/*.abi.json -rm -f ./pkg/abis/*.go - -function generate_bindings() { - cd contracts - forge inspect ./src/${1}.sol:${1} abi > ../${BUILD_DIR}/${1}.abi.json - forge inspect ./src/${1}.sol:${1} bytecode > ../${BUILD_DIR}/${1}.bin.json - - cd .. - abigen --abi ./${BUILD_DIR}/${1}.abi.json --bin ./${BUILD_DIR}/${1}.bin.json --pkg "${PACKAGE_NAME}" --type "${1}" --out "./${OUTPUT_DIR}/${1}.go" > /dev/null 2>&1 - -} - -for contract in Nodes GroupMessages IdentityUpdates; do - generate_bindings $contract -done diff --git a/dev/generate b/dev/generate index 8de689de..751f6cb6 100755 --- a/dev/generate +++ b/dev/generate @@ -6,5 +6,5 @@ set -euo pipefail sqlc generate go generate ./... rm -rf pkg/mocks/* -./dev/contracts/generate +./contracts/dev/generate mockery diff --git a/dev/local.env b/dev/local.env index f07ecaf4..38521690 100755 --- a/dev/local.env +++ b/dev/local.env @@ -1,6 +1,6 @@ #!/bin/bash -source dev/contracts/.env +source contracts/dev/lib/env # Anvil scripts output folder ANVIL_SCRIPTS_OUTPUT=contracts/config/anvil_localnet diff --git a/dev/up b/dev/up index a3f3da74..5edd05c5 100755 --- a/dev/up +++ b/dev/up @@ -28,8 +28,8 @@ fi dev/docker/up # Make sure the abis are updated -dev/contracts/generate -dev/contracts/deploy-local +contracts/dev/generate +contracts/dev/deploy-local echo "Registering local node-1" dev/register-local-node diff --git a/doc/deploy.md b/doc/deploy.md index 048995af..ca1a60fb 100644 --- a/doc/deploy.md +++ b/doc/deploy.md @@ -5,8 +5,9 @@ ## Deploy a new Contract The current environment lives in [Conduit Testnet Staging](https://explorer-testnet-staging-88dqtxdinc.t.conduit.xyz/). -To deploy a new contract you need to run `./dev/contracts/deploy-testnet` +To deploy a new contract you need to run `./contracts/dev/deploy-testnet` You will need: + - $PRIVATE_KEY which is accessible to all members of @ephemerahq/backend - $VERIFIER_URL: https://explorer-testnet-staging-88dqtxdinc.t.conduit.xyz/api - $RPC_URL: https://rpc-testnet-staging-88dqtxdinc.t.conduit.xyz/ @@ -18,6 +19,7 @@ We definitely need the node contract address (for example `0x7c9A7c92e21E9aC25Ce Before nodes can start or peer, they need to be registered with the contract. To do so, run: + ```shell export XMTPD_CONTRACTS_RPC_URL="https://rpc-testnet-staging-88dqtxdinc.t.conduit.xyz/" export XMTPD_CONTRACTS_CHAIN_ID=34498 @@ -36,6 +38,7 @@ You need to register all (both) nodes with their correct DNS entries and public ### Verify Registration To verify registration, use: + ```shell export XMTPD_CONTRACTS_RPC_URL="https://rpc-testnet-staging-88dqtxdinc.t.conduit.xyz/" export XMTPD_CONTRACTS_CHAIN_ID=34498 @@ -47,29 +50,29 @@ dev/cli get-all-nodes \ ``` And you should get something along these lines: + ```json { - "size": 2, - "nodes": [ - { - "NodeId": 100, - "Node": { - "SigningKeyPub": "BOVELF0f4vAra5oaOGODp3ZoYLQKYHmgIjmU/6LOEFEsToqIY97q2FnD1lQKsgJsgvi4k8HFvvbGP0fZ3zOiB9s=", - "HttpAddress": "https://grpc.testnet.xmtp.network", - "IsHealthy": true - } - }, - { - "NodeId": 200, - "Node": { - "SigningKeyPub": "BPwmHUOgFTU5pMZMKXY8sOfjd8DqwpEMPUvtsiNaxwNxz+fKU3SsqOdYJQDVjLfRL5XsA5XVZIge2WDZ7S0zpx4=", - "HttpAddress": "https://grpc2.testnet.xmtp.network", - "IsHealthy": true - } - } - ] + "size": 2, + "nodes": [ + { + "NodeId": 100, + "Node": { + "SigningKeyPub": "BOVELF0f4vAra5oaOGODp3ZoYLQKYHmgIjmU/6LOEFEsToqIY97q2FnD1lQKsgJsgvi4k8HFvvbGP0fZ3zOiB9s=", + "HttpAddress": "https://grpc.testnet.xmtp.network", + "IsHealthy": true + } + }, + { + "NodeId": 200, + "Node": { + "SigningKeyPub": "BPwmHUOgFTU5pMZMKXY8sOfjd8DqwpEMPUvtsiNaxwNxz+fKU3SsqOdYJQDVjLfRL5XsA5XVZIge2WDZ7S0zpx4=", + "HttpAddress": "https://grpc2.testnet.xmtp.network", + "IsHealthy": true + } + } + ] } - ``` ## Deploy XMTPD nodes @@ -78,9 +81,9 @@ Node deployment is currently fully handled by [Ephemera](https://github.com/ephe There are currently two nodes running: -| DNS Name | Location | Public Key | -| --- | ---| -- | -| https://grpc.testnet.xmtp.network | US-EAST-2 | 0x03e5442c5d1fe2f02b6b9a1a386383a7766860b40a6079a0223994ffa2ce10512c | +| DNS Name | Location | Public Key | +| ---------------------------------- | ---------- | -------------------------------------------------------------------- | +| https://grpc.testnet.xmtp.network | US-EAST-2 | 0x03e5442c5d1fe2f02b6b9a1a386383a7766860b40a6079a0223994ffa2ce10512c | | https://grpc2.testnet.xmtp.network | EU-NORTH-1 | 0x02fc261d43a0153539a4c64c29763cb0e7e377c0eac2910c3d4bedb2235ac70371 | For more info, refer to the infrastructure README. @@ -89,7 +92,6 @@ For more info, refer to the infrastructure README. The easiest way is to use [GRPC Health Probe](https://github.com/grpc-ecosystem/grpc-health-probe) - ```shell grpc-health-probe -tls -addr grpc.testnet.xmtp.network:443 status: SERVING diff --git a/pkg/api/payer/publish_test.go b/pkg/api/payer/publish_test.go index 9ec51244..46864834 100644 --- a/pkg/api/payer/publish_test.go +++ b/pkg/api/payer/publish_test.go @@ -9,7 +9,7 @@ import ( "github.com/ethereum/go-ethereum/crypto" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" - "github.com/xmtp/xmtpd/pkg/abis" + "github.com/xmtp/xmtpd/contracts/pkg/identityupdates" "github.com/xmtp/xmtpd/pkg/api/payer" "github.com/xmtp/xmtpd/pkg/envelopes" blockchainMocks "github.com/xmtp/xmtpd/pkg/mocks/blockchain" @@ -73,7 +73,7 @@ func TestPublishIdentityUpdate(t *testing.T) { mockMessagePublisher.EXPECT(). PublishIdentityUpdate(mock.Anything, mock.Anything, mock.Anything). - Return(&abis.IdentityUpdatesIdentityUpdateCreated{ + Return(&identityupdates.IdentityUpdatesIdentityUpdateCreated{ Raw: types.Log{ TxHash: txnHash, }, diff --git a/pkg/api/payer/service.go b/pkg/api/payer/service.go index 3a8d918a..8819d6ae 100644 --- a/pkg/api/payer/service.go +++ b/pkg/api/payer/service.go @@ -6,7 +6,8 @@ import ( "time" "github.com/ethereum/go-ethereum/common" - "github.com/xmtp/xmtpd/pkg/abis" + "github.com/xmtp/xmtpd/contracts/pkg/groupmessages" + "github.com/xmtp/xmtpd/contracts/pkg/identityupdates" "github.com/xmtp/xmtpd/pkg/blockchain" "github.com/xmtp/xmtpd/pkg/constants" "github.com/xmtp/xmtpd/pkg/envelopes" @@ -199,7 +200,7 @@ func (s *Service) publishToBlockchain( var hash common.Hash switch kind { case topic.TOPIC_KIND_GROUP_MESSAGES_V1: - var logMessage *abis.GroupMessagesMessageSent + var logMessage *groupmessages.GroupMessagesMessageSent if logMessage, err = s.blockchainPublisher.PublishGroupMessage(ctx, idBytes, payload); err != nil { return nil, status.Errorf(codes.Internal, "error publishing group message: %v", err) } @@ -215,7 +216,7 @@ func (s *Service) publishToBlockchain( ) case topic.TOPIC_KIND_IDENTITY_UPDATES_V1: - var logMessage *abis.IdentityUpdatesIdentityUpdateCreated + var logMessage *identityupdates.IdentityUpdatesIdentityUpdateCreated if logMessage, err = s.blockchainPublisher.PublishIdentityUpdate(ctx, idBytes, payload); err != nil { return nil, status.Errorf(codes.Internal, "error publishing identity update: %v", err) } diff --git a/pkg/blockchain/blockchainPublisher.go b/pkg/blockchain/blockchainPublisher.go index d648a2f8..0350dec9 100644 --- a/pkg/blockchain/blockchainPublisher.go +++ b/pkg/blockchain/blockchainPublisher.go @@ -13,7 +13,8 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/ethclient" - "github.com/xmtp/xmtpd/pkg/abis" + "github.com/xmtp/xmtpd/contracts/pkg/groupmessages" + "github.com/xmtp/xmtpd/contracts/pkg/identityupdates" "github.com/xmtp/xmtpd/pkg/config" "go.uber.org/zap" ) @@ -24,8 +25,8 @@ Can publish to the blockchain, signing messages using the provided signer type BlockchainPublisher struct { signer TransactionSigner client *ethclient.Client - messagesContract *abis.GroupMessages - identityUpdateContract *abis.IdentityUpdates + messagesContract *groupmessages.GroupMessages + identityUpdateContract *identityupdates.IdentityUpdates logger *zap.Logger mutexNonce sync.Mutex nonce uint64 @@ -41,7 +42,7 @@ func NewBlockchainPublisher( if client == nil { return nil, errors.New("client is nil") } - messagesContract, err := abis.NewGroupMessages( + messagesContract, err := groupmessages.NewGroupMessages( common.HexToAddress(contractOptions.MessagesContractAddress), client, ) @@ -49,7 +50,7 @@ func NewBlockchainPublisher( if err != nil { return nil, err } - identityUpdateContract, err := abis.NewIdentityUpdates( + identityUpdateContract, err := identityupdates.NewIdentityUpdates( common.HexToAddress(contractOptions.IdentityUpdatesContractAddress), client, ) @@ -83,7 +84,7 @@ func (m *BlockchainPublisher) PublishGroupMessage( ctx context.Context, groupID [32]byte, message []byte, -) (*abis.GroupMessagesMessageSent, error) { +) (*groupmessages.GroupMessagesMessageSent, error) { if len(message) == 0 { return nil, errors.New("message is empty") } @@ -126,7 +127,7 @@ func (m *BlockchainPublisher) PublishIdentityUpdate( ctx context.Context, inboxId [32]byte, identityUpdate []byte, -) (*abis.IdentityUpdatesIdentityUpdateCreated, error) { +) (*identityupdates.IdentityUpdatesIdentityUpdateCreated, error) { if len(identityUpdate) == 0 { return nil, errors.New("identity update is empty") } diff --git a/pkg/blockchain/interface.go b/pkg/blockchain/interface.go index 78031b96..904e4f41 100644 --- a/pkg/blockchain/interface.go +++ b/pkg/blockchain/interface.go @@ -8,7 +8,8 @@ import ( "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" - "github.com/xmtp/xmtpd/pkg/abis" + "github.com/xmtp/xmtpd/contracts/pkg/groupmessages" + "github.com/xmtp/xmtpd/contracts/pkg/identityupdates" ) // Construct a raw blockchain listener that can be used to listen for events across many contract event types @@ -50,10 +51,10 @@ type IBlockchainPublisher interface { ctx context.Context, inboxId [32]byte, identityUpdate []byte, - ) (*abis.IdentityUpdatesIdentityUpdateCreated, error) + ) (*identityupdates.IdentityUpdatesIdentityUpdateCreated, error) PublishGroupMessage( ctx context.Context, groupdId [32]byte, message []byte, - ) (*abis.GroupMessagesMessageSent, error) + ) (*groupmessages.GroupMessagesMessageSent, error) } diff --git a/pkg/blockchain/registryAdmin.go b/pkg/blockchain/registryAdmin.go index 2a009813..d99b1f51 100644 --- a/pkg/blockchain/registryAdmin.go +++ b/pkg/blockchain/registryAdmin.go @@ -11,7 +11,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/ethclient" - "github.com/xmtp/xmtpd/pkg/abis" + "github.com/xmtp/xmtpd/contracts/pkg/nodes" "github.com/xmtp/xmtpd/pkg/config" "go.uber.org/zap" ) @@ -24,7 +24,7 @@ A NodeRegistryAdmin is a struct responsible for calling admin functions on the n type NodeRegistryAdmin struct { client *ethclient.Client signer TransactionSigner - contract *abis.Nodes + contract *nodes.Nodes logger *zap.Logger } @@ -34,7 +34,7 @@ func NewNodeRegistryAdmin( signer TransactionSigner, contractsOptions config.ContractsOptions, ) (*NodeRegistryAdmin, error) { - contract, err := abis.NewNodes( + contract, err := nodes.NewNodes( common.HexToAddress(contractsOptions.NodesContractAddress), client, ) @@ -95,7 +95,7 @@ A NodeRegistryCaller is a struct responsible for calling public functions on the */ type NodeRegistryCaller struct { client *ethclient.Client - contract *abis.NodesCaller + contract *nodes.NodesCaller logger *zap.Logger } @@ -104,7 +104,7 @@ func NewNodeRegistryCaller( client *ethclient.Client, contractsOptions config.ContractsOptions, ) (*NodeRegistryCaller, error) { - contract, err := abis.NewNodesCaller( + contract, err := nodes.NewNodesCaller( common.HexToAddress(contractsOptions.NodesContractAddress), client, ) @@ -121,7 +121,7 @@ func NewNodeRegistryCaller( func (n *NodeRegistryCaller) GetAllNodes( ctx context.Context, -) ([]abis.NodesNodeWithId, error) { +) ([]nodes.NodesNodeWithId, error) { return n.contract.AllNodes(&bind.CallOpts{ Context: ctx, diff --git a/pkg/indexer/indexer.go b/pkg/indexer/indexer.go index 4034244c..c98e2859 100644 --- a/pkg/indexer/indexer.go +++ b/pkg/indexer/indexer.go @@ -11,7 +11,8 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/ethclient" - "github.com/xmtp/xmtpd/pkg/abis" + "github.com/xmtp/xmtpd/contracts/pkg/groupmessages" + "github.com/xmtp/xmtpd/contracts/pkg/identityupdates" "github.com/xmtp/xmtpd/pkg/blockchain" "github.com/xmtp/xmtpd/pkg/config" "github.com/xmtp/xmtpd/pkg/db/queries" @@ -223,7 +224,7 @@ func indexLogs( } func buildMessagesTopic() (common.Hash, error) { - abi, err := abis.GroupMessagesMetaData.GetAbi() + abi, err := groupmessages.GroupMessagesMetaData.GetAbi() if err != nil { return common.Hash{}, err } @@ -231,7 +232,7 @@ func buildMessagesTopic() (common.Hash, error) { } func buildIdentityUpdatesTopic() (common.Hash, error) { - abi, err := abis.IdentityUpdatesMetaData.GetAbi() + abi, err := identityupdates.IdentityUpdatesMetaData.GetAbi() if err != nil { return common.Hash{}, err } @@ -241,8 +242,8 @@ func buildIdentityUpdatesTopic() (common.Hash, error) { func messagesContract( cfg config.ContractsOptions, client *ethclient.Client, -) (*abis.GroupMessages, error) { - return abis.NewGroupMessages( +) (*groupmessages.GroupMessages, error) { + return groupmessages.NewGroupMessages( common.HexToAddress(cfg.MessagesContractAddress), client, ) @@ -251,8 +252,8 @@ func messagesContract( func identityUpdatesContract( cfg config.ContractsOptions, client *ethclient.Client, -) (*abis.IdentityUpdates, error) { - return abis.NewIdentityUpdates( +) (*identityupdates.IdentityUpdates, error) { + return identityupdates.NewIdentityUpdates( common.HexToAddress(cfg.IdentityUpdatesContractAddress), client, ) diff --git a/pkg/indexer/storer/groupMessage.go b/pkg/indexer/storer/groupMessage.go index 472bb226..9c65a63b 100644 --- a/pkg/indexer/storer/groupMessage.go +++ b/pkg/indexer/storer/groupMessage.go @@ -5,7 +5,7 @@ import ( "errors" "github.com/ethereum/go-ethereum/core/types" - "github.com/xmtp/xmtpd/pkg/abis" + "github.com/xmtp/xmtpd/contracts/pkg/groupmessages" "github.com/xmtp/xmtpd/pkg/db/queries" "github.com/xmtp/xmtpd/pkg/envelopes" "github.com/xmtp/xmtpd/pkg/topic" @@ -14,7 +14,7 @@ import ( ) type GroupMessageStorer struct { - contract *abis.GroupMessages + contract *groupmessages.GroupMessages queries *queries.Queries logger *zap.Logger } @@ -22,7 +22,7 @@ type GroupMessageStorer struct { func NewGroupMessageStorer( queries *queries.Queries, logger *zap.Logger, - contract *abis.GroupMessages, + contract *groupmessages.GroupMessages, ) *GroupMessageStorer { return &GroupMessageStorer{ queries: queries, diff --git a/pkg/indexer/storer/groupMessage_test.go b/pkg/indexer/storer/groupMessage_test.go index 3499486c..6e82ef6a 100644 --- a/pkg/indexer/storer/groupMessage_test.go +++ b/pkg/indexer/storer/groupMessage_test.go @@ -7,7 +7,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" "github.com/stretchr/testify/require" - "github.com/xmtp/xmtpd/pkg/abis" + "github.com/xmtp/xmtpd/contracts/pkg/groupmessages" "github.com/xmtp/xmtpd/pkg/blockchain" "github.com/xmtp/xmtpd/pkg/db/queries" "github.com/xmtp/xmtpd/pkg/envelopes" @@ -26,7 +26,7 @@ func buildGroupMessageStorer(t *testing.T) (*GroupMessageStorer, func()) { client, err := blockchain.NewClient(ctx, config.RpcUrl) require.NoError(t, err) - contract, err := abis.NewGroupMessages( + contract, err := groupmessages.NewGroupMessages( common.HexToAddress(contractAddress), client, ) @@ -122,7 +122,7 @@ func TestStoreGroupMessageMalformed(t *testing.T) { storer, cleanup := buildGroupMessageStorer(t) defer cleanup() - abi, err := abis.GroupMessagesMetaData.GetAbi() + abi, err := groupmessages.GroupMessagesMetaData.GetAbi() require.NoError(t, err) topic, err := utils.GetEventTopic(abi, "MessageSent") diff --git a/pkg/indexer/storer/identityUpdate.go b/pkg/indexer/storer/identityUpdate.go index b9719373..737923fc 100644 --- a/pkg/indexer/storer/identityUpdate.go +++ b/pkg/indexer/storer/identityUpdate.go @@ -9,7 +9,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" "github.com/pingcap/log" - "github.com/xmtp/xmtpd/pkg/abis" + "github.com/xmtp/xmtpd/contracts/pkg/identityupdates" "github.com/xmtp/xmtpd/pkg/db" "github.com/xmtp/xmtpd/pkg/db/queries" "github.com/xmtp/xmtpd/pkg/envelopes" @@ -27,7 +27,7 @@ const ( ) type IdentityUpdateStorer struct { - contract *abis.IdentityUpdates + contract *identityupdates.IdentityUpdates db *sql.DB logger *zap.Logger validationService mlsvalidate.MLSValidationService @@ -36,7 +36,7 @@ type IdentityUpdateStorer struct { func NewIdentityUpdateStorer( db *sql.DB, logger *zap.Logger, - contract *abis.IdentityUpdates, + contract *identityupdates.IdentityUpdates, validationService mlsvalidate.MLSValidationService, ) *IdentityUpdateStorer { return &IdentityUpdateStorer{ diff --git a/pkg/indexer/storer/identityUpdate_test.go b/pkg/indexer/storer/identityUpdate_test.go index c06fddb2..5426912c 100644 --- a/pkg/indexer/storer/identityUpdate_test.go +++ b/pkg/indexer/storer/identityUpdate_test.go @@ -7,7 +7,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" - "github.com/xmtp/xmtpd/pkg/abis" + "github.com/xmtp/xmtpd/contracts/pkg/identityupdates" "github.com/xmtp/xmtpd/pkg/blockchain" "github.com/xmtp/xmtpd/pkg/db/queries" "github.com/xmtp/xmtpd/pkg/mlsvalidate" @@ -30,7 +30,7 @@ func buildIdentityUpdateStorer( client, err := blockchain.NewClient(ctx, config.RpcUrl) require.NoError(t, err) - contract, err := abis.NewIdentityUpdates( + contract, err := identityupdates.NewIdentityUpdates( common.HexToAddress(contractAddress), client, ) diff --git a/pkg/mocks/blockchain/mock_IBlockchainPublisher.go b/pkg/mocks/blockchain/mock_IBlockchainPublisher.go index dba74b98..37c1c50f 100644 --- a/pkg/mocks/blockchain/mock_IBlockchainPublisher.go +++ b/pkg/mocks/blockchain/mock_IBlockchainPublisher.go @@ -3,10 +3,11 @@ package blockchain import ( - abis "github.com/xmtp/xmtpd/pkg/abis" - context "context" + groupmessages "github.com/xmtp/xmtpd/contracts/pkg/groupmessages" + identityupdates "github.com/xmtp/xmtpd/contracts/pkg/identityupdates" + mock "github.com/stretchr/testify/mock" ) @@ -24,23 +25,23 @@ func (_m *MockIBlockchainPublisher) EXPECT() *MockIBlockchainPublisher_Expecter } // PublishGroupMessage provides a mock function with given fields: ctx, groupdId, message -func (_m *MockIBlockchainPublisher) PublishGroupMessage(ctx context.Context, groupdId [32]byte, message []byte) (*abis.GroupMessagesMessageSent, error) { +func (_m *MockIBlockchainPublisher) PublishGroupMessage(ctx context.Context, groupdId [32]byte, message []byte) (*groupmessages.GroupMessagesMessageSent, error) { ret := _m.Called(ctx, groupdId, message) if len(ret) == 0 { panic("no return value specified for PublishGroupMessage") } - var r0 *abis.GroupMessagesMessageSent + var r0 *groupmessages.GroupMessagesMessageSent var r1 error - if rf, ok := ret.Get(0).(func(context.Context, [32]byte, []byte) (*abis.GroupMessagesMessageSent, error)); ok { + if rf, ok := ret.Get(0).(func(context.Context, [32]byte, []byte) (*groupmessages.GroupMessagesMessageSent, error)); ok { return rf(ctx, groupdId, message) } - if rf, ok := ret.Get(0).(func(context.Context, [32]byte, []byte) *abis.GroupMessagesMessageSent); ok { + if rf, ok := ret.Get(0).(func(context.Context, [32]byte, []byte) *groupmessages.GroupMessagesMessageSent); ok { r0 = rf(ctx, groupdId, message) } else { if ret.Get(0) != nil { - r0 = ret.Get(0).(*abis.GroupMessagesMessageSent) + r0 = ret.Get(0).(*groupmessages.GroupMessagesMessageSent) } } @@ -73,34 +74,34 @@ func (_c *MockIBlockchainPublisher_PublishGroupMessage_Call) Run(run func(ctx co return _c } -func (_c *MockIBlockchainPublisher_PublishGroupMessage_Call) Return(_a0 *abis.GroupMessagesMessageSent, _a1 error) *MockIBlockchainPublisher_PublishGroupMessage_Call { +func (_c *MockIBlockchainPublisher_PublishGroupMessage_Call) Return(_a0 *groupmessages.GroupMessagesMessageSent, _a1 error) *MockIBlockchainPublisher_PublishGroupMessage_Call { _c.Call.Return(_a0, _a1) return _c } -func (_c *MockIBlockchainPublisher_PublishGroupMessage_Call) RunAndReturn(run func(context.Context, [32]byte, []byte) (*abis.GroupMessagesMessageSent, error)) *MockIBlockchainPublisher_PublishGroupMessage_Call { +func (_c *MockIBlockchainPublisher_PublishGroupMessage_Call) RunAndReturn(run func(context.Context, [32]byte, []byte) (*groupmessages.GroupMessagesMessageSent, error)) *MockIBlockchainPublisher_PublishGroupMessage_Call { _c.Call.Return(run) return _c } // PublishIdentityUpdate provides a mock function with given fields: ctx, inboxId, identityUpdate -func (_m *MockIBlockchainPublisher) PublishIdentityUpdate(ctx context.Context, inboxId [32]byte, identityUpdate []byte) (*abis.IdentityUpdatesIdentityUpdateCreated, error) { +func (_m *MockIBlockchainPublisher) PublishIdentityUpdate(ctx context.Context, inboxId [32]byte, identityUpdate []byte) (*identityupdates.IdentityUpdatesIdentityUpdateCreated, error) { ret := _m.Called(ctx, inboxId, identityUpdate) if len(ret) == 0 { panic("no return value specified for PublishIdentityUpdate") } - var r0 *abis.IdentityUpdatesIdentityUpdateCreated + var r0 *identityupdates.IdentityUpdatesIdentityUpdateCreated var r1 error - if rf, ok := ret.Get(0).(func(context.Context, [32]byte, []byte) (*abis.IdentityUpdatesIdentityUpdateCreated, error)); ok { + if rf, ok := ret.Get(0).(func(context.Context, [32]byte, []byte) (*identityupdates.IdentityUpdatesIdentityUpdateCreated, error)); ok { return rf(ctx, inboxId, identityUpdate) } - if rf, ok := ret.Get(0).(func(context.Context, [32]byte, []byte) *abis.IdentityUpdatesIdentityUpdateCreated); ok { + if rf, ok := ret.Get(0).(func(context.Context, [32]byte, []byte) *identityupdates.IdentityUpdatesIdentityUpdateCreated); ok { r0 = rf(ctx, inboxId, identityUpdate) } else { if ret.Get(0) != nil { - r0 = ret.Get(0).(*abis.IdentityUpdatesIdentityUpdateCreated) + r0 = ret.Get(0).(*identityupdates.IdentityUpdatesIdentityUpdateCreated) } } @@ -133,12 +134,12 @@ func (_c *MockIBlockchainPublisher_PublishIdentityUpdate_Call) Run(run func(ctx return _c } -func (_c *MockIBlockchainPublisher_PublishIdentityUpdate_Call) Return(_a0 *abis.IdentityUpdatesIdentityUpdateCreated, _a1 error) *MockIBlockchainPublisher_PublishIdentityUpdate_Call { +func (_c *MockIBlockchainPublisher_PublishIdentityUpdate_Call) Return(_a0 *identityupdates.IdentityUpdatesIdentityUpdateCreated, _a1 error) *MockIBlockchainPublisher_PublishIdentityUpdate_Call { _c.Call.Return(_a0, _a1) return _c } -func (_c *MockIBlockchainPublisher_PublishIdentityUpdate_Call) RunAndReturn(run func(context.Context, [32]byte, []byte) (*abis.IdentityUpdatesIdentityUpdateCreated, error)) *MockIBlockchainPublisher_PublishIdentityUpdate_Call { +func (_c *MockIBlockchainPublisher_PublishIdentityUpdate_Call) RunAndReturn(run func(context.Context, [32]byte, []byte) (*identityupdates.IdentityUpdatesIdentityUpdateCreated, error)) *MockIBlockchainPublisher_PublishIdentityUpdate_Call { _c.Call.Return(run) return _c } diff --git a/pkg/mocks/registry/mock_NodesContract.go b/pkg/mocks/registry/mock_NodesContract.go index 423d4495..1027ee3f 100644 --- a/pkg/mocks/registry/mock_NodesContract.go +++ b/pkg/mocks/registry/mock_NodesContract.go @@ -5,7 +5,8 @@ package registry import ( bind "github.com/ethereum/go-ethereum/accounts/abi/bind" mock "github.com/stretchr/testify/mock" - abis "github.com/xmtp/xmtpd/pkg/abis" + + nodes "github.com/xmtp/xmtpd/contracts/pkg/nodes" ) // MockNodesContract is an autogenerated mock type for the NodesContract type @@ -22,23 +23,23 @@ func (_m *MockNodesContract) EXPECT() *MockNodesContract_Expecter { } // AllNodes provides a mock function with given fields: opts -func (_m *MockNodesContract) AllNodes(opts *bind.CallOpts) ([]abis.NodesNodeWithId, error) { +func (_m *MockNodesContract) AllNodes(opts *bind.CallOpts) ([]nodes.NodesNodeWithId, error) { ret := _m.Called(opts) if len(ret) == 0 { panic("no return value specified for AllNodes") } - var r0 []abis.NodesNodeWithId + var r0 []nodes.NodesNodeWithId var r1 error - if rf, ok := ret.Get(0).(func(*bind.CallOpts) ([]abis.NodesNodeWithId, error)); ok { + if rf, ok := ret.Get(0).(func(*bind.CallOpts) ([]nodes.NodesNodeWithId, error)); ok { return rf(opts) } - if rf, ok := ret.Get(0).(func(*bind.CallOpts) []abis.NodesNodeWithId); ok { + if rf, ok := ret.Get(0).(func(*bind.CallOpts) []nodes.NodesNodeWithId); ok { r0 = rf(opts) } else { if ret.Get(0) != nil { - r0 = ret.Get(0).([]abis.NodesNodeWithId) + r0 = ret.Get(0).([]nodes.NodesNodeWithId) } } @@ -69,12 +70,12 @@ func (_c *MockNodesContract_AllNodes_Call) Run(run func(opts *bind.CallOpts)) *M return _c } -func (_c *MockNodesContract_AllNodes_Call) Return(_a0 []abis.NodesNodeWithId, _a1 error) *MockNodesContract_AllNodes_Call { +func (_c *MockNodesContract_AllNodes_Call) Return(_a0 []nodes.NodesNodeWithId, _a1 error) *MockNodesContract_AllNodes_Call { _c.Call.Return(_a0, _a1) return _c } -func (_c *MockNodesContract_AllNodes_Call) RunAndReturn(run func(*bind.CallOpts) ([]abis.NodesNodeWithId, error)) *MockNodesContract_AllNodes_Call { +func (_c *MockNodesContract_AllNodes_Call) RunAndReturn(run func(*bind.CallOpts) ([]nodes.NodesNodeWithId, error)) *MockNodesContract_AllNodes_Call { _c.Call.Return(run) return _c } diff --git a/pkg/registry/contractRegistry.go b/pkg/registry/contractRegistry.go index 56997b2c..c4215526 100644 --- a/pkg/registry/contractRegistry.go +++ b/pkg/registry/contractRegistry.go @@ -3,15 +3,16 @@ package registry import ( "context" "errors" - "github.com/xmtp/xmtpd/pkg/tracing" "strings" "sync" "time" + "github.com/xmtp/xmtpd/pkg/tracing" + "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/crypto" - "github.com/xmtp/xmtpd/pkg/abis" + "github.com/xmtp/xmtpd/contracts/pkg/nodes" "github.com/xmtp/xmtpd/pkg/config" "go.uber.org/zap" ) @@ -53,7 +54,7 @@ func NewSmartContractRegistry( options config.ContractsOptions, ) (*SmartContractRegistry, error) { - contract, err := abis.NewNodesCaller( + contract, err := nodes.NewNodesCaller( common.HexToAddress(options.NodesContractAddress), ethclient, ) @@ -228,7 +229,7 @@ func (s *SmartContractRegistry) SetContractForTest(contract NodesContract) { s.contract = contract } -func convertNode(rawNode abis.NodesNodeWithId) Node { +func convertNode(rawNode nodes.NodesNodeWithId) Node { // Unmarshal the signing key. // If invalid, mark the config as being invalid as well. Clients should treat the // node as unhealthy in this case diff --git a/pkg/registry/contractRegistry_test.go b/pkg/registry/contractRegistry_test.go index 997b9caf..cb780ac4 100644 --- a/pkg/registry/contractRegistry_test.go +++ b/pkg/registry/contractRegistry_test.go @@ -10,7 +10,7 @@ import ( "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" - "github.com/xmtp/xmtpd/pkg/abis" + "github.com/xmtp/xmtpd/contracts/pkg/nodes" "github.com/xmtp/xmtpd/pkg/config" mocks "github.com/xmtp/xmtpd/pkg/mocks/registry" r "github.com/xmtp/xmtpd/pkg/registry" @@ -45,15 +45,15 @@ func TestContractRegistryNewNodes(t *testing.T) { mockContract := mocks.NewMockNodesContract(t) mockContract.EXPECT(). AllNodes(mock.Anything). - Return([]abis.NodesNodeWithId{ + Return([]nodes.NodesNodeWithId{ { NodeId: 1, - Node: abis.NodesNode{ + Node: nodes.NodesNode{ HttpAddress: "http://foo.com", SigningKeyPub: enc, }, }, - {NodeId: 2, Node: abis.NodesNode{HttpAddress: "https://bar.com", + {NodeId: 2, Node: nodes.NodesNode{HttpAddress: "https://bar.com", SigningKeyPub: enc}}, }, nil) @@ -88,15 +88,15 @@ func TestContractRegistryChangedNodes(t *testing.T) { // The first call, we'll set the address to foo.com. // Subsequent calls will set the address to bar.com mockContract.EXPECT(). - AllNodes(mock.Anything).RunAndReturn(func(*bind.CallOpts) ([]abis.NodesNodeWithId, error) { + AllNodes(mock.Anything).RunAndReturn(func(*bind.CallOpts) ([]nodes.NodesNodeWithId, error) { httpAddress := "http://foo.com" if !hasSentInitialValues { hasSentInitialValues = true } else { httpAddress = "http://bar.com" } - return []abis.NodesNodeWithId{ - {NodeId: 1, Node: abis.NodesNode{HttpAddress: httpAddress, SigningKeyPub: enc}}, + return []nodes.NodesNodeWithId{ + {NodeId: 1, Node: nodes.NodesNode{HttpAddress: httpAddress, SigningKeyPub: enc}}, }, nil }) @@ -134,11 +134,11 @@ func TestStopOnContextCancel(t *testing.T) { mockContract := mocks.NewMockNodesContract(t) mockContract.EXPECT(). AllNodes(mock.Anything). - RunAndReturn(func(*bind.CallOpts) ([]abis.NodesNodeWithId, error) { - return []abis.NodesNodeWithId{ + RunAndReturn(func(*bind.CallOpts) ([]nodes.NodesNodeWithId, error) { + return []nodes.NodesNodeWithId{ { NodeId: uint32(rand.Intn(1000)), - Node: abis.NodesNode{HttpAddress: "http://foo.com", SigningKeyPub: enc}, + Node: nodes.NodesNode{HttpAddress: "http://foo.com", SigningKeyPub: enc}, }, }, nil }) diff --git a/pkg/registry/interface.go b/pkg/registry/interface.go index 2aca4738..9d32c385 100644 --- a/pkg/registry/interface.go +++ b/pkg/registry/interface.go @@ -2,7 +2,7 @@ package registry import ( "github.com/ethereum/go-ethereum/accounts/abi/bind" - "github.com/xmtp/xmtpd/pkg/abis" + "github.com/xmtp/xmtpd/contracts/pkg/nodes" ) /* @@ -10,7 +10,7 @@ import ( A dumbed down interface of abis.NodesCaller for generating mocks */ type NodesContract interface { - AllNodes(opts *bind.CallOpts) ([]abis.NodesNodeWithId, error) + AllNodes(opts *bind.CallOpts) ([]nodes.NodesNodeWithId, error) } // Unregister the callback diff --git a/pkg/testutils/contracts.go b/pkg/testutils/contracts.go index 1282eb3d..1f128585 100644 --- a/pkg/testutils/contracts.go +++ b/pkg/testutils/contracts.go @@ -1,27 +1,39 @@ package testutils import ( - "bytes" - "encoding/json" - "os/exec" + "math/big" "testing" + "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/ethclient" "github.com/stretchr/testify/require" - "github.com/xmtp/xmtpd/pkg/abis" + "github.com/xmtp/xmtpd/contracts/pkg/groupmessages" + "github.com/xmtp/xmtpd/contracts/pkg/identityupdates" + "github.com/xmtp/xmtpd/contracts/pkg/nodes" envelopesProto "github.com/xmtp/xmtpd/pkg/proto/xmtpv4/envelopes" "github.com/xmtp/xmtpd/pkg/utils" "google.golang.org/protobuf/proto" ) +const ( + ANVIL_LOCALNET_HOST = "http://localhost:7545" + ANVIL_LOCALNET_CHAIN_ID = 31337 + LOCAL_PRIVATE_KEY = "ac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80" + NODES_CONTRACT_NAME = "Nodes" + GROUP_MESSAGES_CONTRACT_NAME = "GroupMessages" + IDENTITY_UPDATES_CONTRACT_NAME = "IdentityUpdates" +) + // Build an abi encoded MessageSent event struct func BuildMessageSentEvent( groupID [32]byte, message []byte, sequenceID uint64, ) ([]byte, error) { - abi, err := abis.GroupMessagesMetaData.GetAbi() + abi, err := groupmessages.GroupMessagesMetaData.GetAbi() if err != nil { return nil, err } @@ -40,7 +52,7 @@ func BuildMessageSentLog( eventData, err := BuildMessageSentEvent(groupID, messageBytes, sequenceID) require.NoError(t, err) - abi, err := abis.GroupMessagesMetaData.GetAbi() + abi, err := groupmessages.GroupMessagesMetaData.GetAbi() require.NoError(t, err) topic, err := utils.GetEventTopic(abi, "MessageSent") @@ -53,7 +65,7 @@ func BuildMessageSentLog( } func BuildIdentityUpdateEvent(inboxId [32]byte, update []byte, sequenceID uint64) ([]byte, error) { - abi, err := abis.IdentityUpdatesMetaData.GetAbi() + abi, err := identityupdates.IdentityUpdatesMetaData.GetAbi() if err != nil { return nil, err } @@ -72,7 +84,7 @@ func BuildIdentityUpdateLog( eventData, err := BuildIdentityUpdateEvent(inboxId, messageBytes, sequenceID) require.NoError(t, err) - abi, err := abis.IdentityUpdatesMetaData.GetAbi() + abi, err := identityupdates.IdentityUpdatesMetaData.GetAbi() require.NoError(t, err) topic, err := utils.GetEventTopic(abi, "IdentityUpdateCreated") @@ -89,36 +101,45 @@ func BuildIdentityUpdateLog( Deploy a contract and return the contract's address. Will return a different address for each run, making it suitable for testing * */ -func deployContract(t *testing.T, filePath string, contractName string) string { - packageRoot := rootPath(t) - cmd := exec.Command("./dev/contracts/deploy-ephemeral", filePath, contractName) - cmd.Dir = packageRoot +func deployContract(t *testing.T, contractName string) string { + client, err := ethclient.Dial(ANVIL_LOCALNET_HOST) + require.NoError(t, err) - var out bytes.Buffer - var errors bytes.Buffer - cmd.Stdout = &out - cmd.Stderr = &errors + privateKey, err := crypto.HexToECDSA(LOCAL_PRIVATE_KEY) + require.NoError(t, err) - err := cmd.Run() - require.NoError(t, err, "Failed to execute deploy-ephemeral script", errors.String()) + auth, err := bind.NewKeyedTransactorWithChainID( + privateKey, + big.NewInt(ANVIL_LOCALNET_CHAIN_ID), + ) + require.NoError(t, err) - output := out.String() - t.Logf("deploy-ephemeral output: %s", output) + var addr common.Address + + switch contractName { + case NODES_CONTRACT_NAME: + addr, _, _, err = nodes.DeployNodes(auth, client) + case GROUP_MESSAGES_CONTRACT_NAME: + addr, _, _, err = groupmessages.DeployGroupMessages(auth, client) + case IDENTITY_UPDATES_CONTRACT_NAME: + addr, _, _, err = identityupdates.DeployIdentityUpdates(auth, client) + default: + t.Fatalf("Unknown contract name: %s", contractName) + } - var parsed contractInfo - require.NoError(t, json.Unmarshal([]byte(output), &parsed)) + require.NoError(t, err) - return parsed.DeployedTo + return addr.String() } func DeployNodesContract(t *testing.T) string { - return deployContract(t, "./src/Nodes.sol", "Nodes") + return deployContract(t, NODES_CONTRACT_NAME) } func DeployGroupMessagesContract(t *testing.T) string { - return deployContract(t, "./src/GroupMessages.sol", "GroupMessages") + return deployContract(t, GROUP_MESSAGES_CONTRACT_NAME) } func DeployIdentityUpdatesContract(t *testing.T) string { - return deployContract(t, "./src/IdentityUpdates.sol", "IdentityUpdates") + return deployContract(t, IDENTITY_UPDATES_CONTRACT_NAME) } diff --git a/pkg/utils/chainEvent_test.go b/pkg/utils/chainEvent_test.go index bb3d2eff..c0bb84e3 100644 --- a/pkg/utils/chainEvent_test.go +++ b/pkg/utils/chainEvent_test.go @@ -5,7 +5,7 @@ import ( "github.com/ethereum/go-ethereum/crypto" "github.com/stretchr/testify/require" - "github.com/xmtp/xmtpd/pkg/abis" + "github.com/xmtp/xmtpd/contracts/pkg/groupmessages" ) const ( @@ -14,7 +14,7 @@ const ( ) func TestGetEventSignature(t *testing.T) { - abi, _ := abis.GroupMessagesMetaData.GetAbi() + abi, _ := groupmessages.GroupMessagesMetaData.GetAbi() signature, err := GetEventSig(abi, "MessageSent") require.NoError(t, err) @@ -22,7 +22,7 @@ func TestGetEventSignature(t *testing.T) { } func TestGetEventTopic(t *testing.T) { - abi, _ := abis.GroupMessagesMetaData.GetAbi() + abi, _ := groupmessages.GroupMessagesMetaData.GetAbi() topic, err := GetEventTopic(abi, "MessageSent") require.NoError(t, err) From 6797e30c0e021a66fa47343568984ebe692ccf15 Mon Sep 17 00:00:00 2001 From: Borja Aranda Date: Tue, 7 Jan 2025 21:56:17 +0100 Subject: [PATCH 9/9] rebase --- .../config/anvil_localnet/GroupMessages.json | 8 +- .../anvil_localnet/IdentityUpdates.json | 8 +- contracts/pkg/groupmessages/GroupMessages.go | 2 +- .../pkg/identityupdates/IdentityUpdates.go | 2 +- contracts/test/GroupMessage.t.sol | 156 ------------------ 5 files changed, 10 insertions(+), 166 deletions(-) diff --git a/contracts/config/anvil_localnet/GroupMessages.json b/contracts/config/anvil_localnet/GroupMessages.json index 1c217d30..5b9760fa 100644 --- a/contracts/config/anvil_localnet/GroupMessages.json +++ b/contracts/config/anvil_localnet/GroupMessages.json @@ -1,10 +1,10 @@ { "addresses": { "groupMessagesDeployer": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", - "groupMessagesImpl": "0x5f246ADDCF057E0f778CD422e20e413be70f9a0c", - "groupMessagesProxy": "0xaD82Ecf79e232B0391C5479C7f632aA1EA701Ed1", + "groupMessagesImpl": "0xc5a5C42992dECbae36851359345FE25997F5C42d", + "groupMessagesProxy": "0x67d269191c92Caf3cD7723F116c85e6E9bf55933", "groupMessagesProxyAdmin": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266" }, - "deploymentBlock": 160, - "latestUpgradeBlock": 160 + "deploymentBlock": 28, + "latestUpgradeBlock": 28 } \ No newline at end of file diff --git a/contracts/config/anvil_localnet/IdentityUpdates.json b/contracts/config/anvil_localnet/IdentityUpdates.json index bd96842c..79d70dbb 100644 --- a/contracts/config/anvil_localnet/IdentityUpdates.json +++ b/contracts/config/anvil_localnet/IdentityUpdates.json @@ -1,10 +1,10 @@ { "addresses": { "identityUpdatesDeployer": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", - "identityUpdatesImpl": "0x4Dd5336F3C0D70893A7a86c6aEBe9B953E87c891", - "identityUpdatesProxy": "0x91A1EeE63f300B8f41AE6AF67eDEa2e2ed8c3f79", + "identityUpdatesImpl": "0xE6E340D132b5f46d1e472DebcD681B2aBc16e57E", + "identityUpdatesProxy": "0xc3e53F4d16Ae77Db1c982e75a937B9f60FE63690", "identityUpdatesProxyAdmin": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266" }, - "deploymentBlock": 162, - "latestUpgradeBlock": 162 + "deploymentBlock": 30, + "latestUpgradeBlock": 30 } \ No newline at end of file diff --git a/contracts/pkg/groupmessages/GroupMessages.go b/contracts/pkg/groupmessages/GroupMessages.go index 7f226ee9..50b429d5 100644 --- a/contracts/pkg/groupmessages/GroupMessages.go +++ b/contracts/pkg/groupmessages/GroupMessages.go @@ -32,7 +32,7 @@ var ( // GroupMessagesMetaData contains all meta data concerning the GroupMessages contract. var GroupMessagesMetaData = &bind.MetaData{ ABI: "[{\"type\":\"function\",\"name\":\"DEFAULT_ADMIN_ROLE\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"MAX_PAYLOAD_SIZE\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"MIN_PAYLOAD_SIZE\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"UPGRADE_INTERFACE_VERSION\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"addMessage\",\"inputs\":[{\"name\":\"groupId\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"message\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"getRoleAdmin\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"grantRole\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"hasRole\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"initialize\",\"inputs\":[{\"name\":\"_admin\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"pause\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"paused\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"proxiableUUID\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"renounceRole\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"callerConfirmation\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"revokeRole\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"supportsInterface\",\"inputs\":[{\"name\":\"interfaceId\",\"type\":\"bytes4\",\"internalType\":\"bytes4\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"unpause\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"upgradeToAndCall\",\"inputs\":[{\"name\":\"newImplementation\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"data\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"event\",\"name\":\"Initialized\",\"inputs\":[{\"name\":\"version\",\"type\":\"uint64\",\"indexed\":false,\"internalType\":\"uint64\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"MessageSent\",\"inputs\":[{\"name\":\"groupId\",\"type\":\"bytes32\",\"indexed\":false,\"internalType\":\"bytes32\"},{\"name\":\"message\",\"type\":\"bytes\",\"indexed\":false,\"internalType\":\"bytes\"},{\"name\":\"sequenceId\",\"type\":\"uint64\",\"indexed\":false,\"internalType\":\"uint64\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Paused\",\"inputs\":[{\"name\":\"account\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"RoleAdminChanged\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"previousAdminRole\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"newAdminRole\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"RoleGranted\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"account\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"sender\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"RoleRevoked\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"account\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"sender\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Unpaused\",\"inputs\":[{\"name\":\"account\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"UpgradeAuthorized\",\"inputs\":[{\"name\":\"upgrader\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"},{\"name\":\"newImplementation\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Upgraded\",\"inputs\":[{\"name\":\"implementation\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"error\",\"name\":\"AccessControlBadConfirmation\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"AccessControlUnauthorizedAccount\",\"inputs\":[{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"neededRole\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}]},{\"type\":\"error\",\"name\":\"AddressEmptyCode\",\"inputs\":[{\"name\":\"target\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"type\":\"error\",\"name\":\"ERC1967InvalidImplementation\",\"inputs\":[{\"name\":\"implementation\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"type\":\"error\",\"name\":\"ERC1967NonPayable\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"EnforcedPause\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"ExpectedPause\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"FailedCall\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidInitialization\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidPayloadSize\",\"inputs\":[{\"name\":\"actualSize\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"minSize\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"maxSize\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]},{\"type\":\"error\",\"name\":\"NotInitializing\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"UUPSUnauthorizedCallContext\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"UUPSUnsupportedProxiableUUID\",\"inputs\":[{\"name\":\"slot\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}]},{\"type\":\"error\",\"name\":\"ZeroAdminAddress\",\"inputs\":[]}]", - Bin: "0x60a0604052306080523480156012575f5ffd5b506080516117be6100395f395f8181610ba401528181610bcd0152610ee001526117be5ff3fe608060405260043610610109575f3560e01c80635c975abb116100a1578063a2ba193411610071578063c4d66de811610057578063c4d66de81461036e578063d547741f1461038d578063f5368506146103ac575f5ffd5b8063a2ba193414610303578063ad3cb1cc14610319575f5ffd5b80635c975abb146102365780638456cb591461026c57806391d1485414610280578063a217fddf146102f0575f5ffd5b80633f4ba83a116100dc5780633f4ba83a146101dc5780634dff26b5146101f05780634f1ef2861461020f57806352d1902d14610222575f5ffd5b806301ffc9a71461010d578063248a9ca3146101415780632f2ff15d1461019c57806336568abe146101bd575b5f5ffd5b348015610118575f5ffd5b5061012c61012736600461143c565b6103c0565b60405190151581526020015b60405180910390f35b34801561014c575f5ffd5b5061018e61015b36600461147b565b5f9081527f02dd7bc7dec4dceedda775e58dd541e08a116c6c53815c0bd028192f7b626800602052604090206001015490565b604051908152602001610138565b3480156101a7575f5ffd5b506101bb6101b63660046114ba565b610458565b005b3480156101c8575f5ffd5b506101bb6101d73660046114ba565b6104a1565b3480156101e7575f5ffd5b506101bb6104ff565b3480156101fb575f5ffd5b506101bb61020a3660046114e4565b610514565b6101bb61021d366004611588565b610606565b34801561022d575f5ffd5b5061018e610625565b348015610241575f5ffd5b507fcd5ed15c6e187e77e9aee88184c21f4f2182ab5827cb3b7e07fbedcd63f033005460ff1661012c565b348015610277575f5ffd5b506101bb610653565b34801561028b575f5ffd5b5061012c61029a3660046114ba565b5f9182527f02dd7bc7dec4dceedda775e58dd541e08a116c6c53815c0bd028192f7b6268006020908152604080842073ffffffffffffffffffffffffffffffffffffffff93909316845291905290205460ff1690565b3480156102fb575f5ffd5b5061018e5f81565b34801561030e575f5ffd5b5061018e6240000081565b348015610324575f5ffd5b506103616040518060400160405280600581526020017f352e302e3000000000000000000000000000000000000000000000000000000081525081565b6040516101389190611689565b348015610379575f5ffd5b506101bb6103883660046116dc565b610665565b348015610398575f5ffd5b506101bb6103a73660046114ba565b61084a565b3480156103b7575f5ffd5b5061018e604e81565b5f7fffffffff0000000000000000000000000000000000000000000000000000000082167f7965db0b00000000000000000000000000000000000000000000000000000000148061045257507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b92915050565b5f8281527f02dd7bc7dec4dceedda775e58dd541e08a116c6c53815c0bd028192f7b62680060205260409020600101546104918161088d565b61049b8383610897565b50505050565b73ffffffffffffffffffffffffffffffffffffffff811633146104f0576040517f6697b23200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6104fa82826109b5565b505050565b5f6105098161088d565b610511610a91565b50565b61051c610b2e565b604e81108015906105305750624000008111155b8190604e906240000090610586576040517f93b7abe60000000000000000000000000000000000000000000000000000000081526004810193909352602483019190915260448201526064015b60405180910390fd5b50505f805467ffffffffffffffff808216600101167fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000090911681179091556040517f91f47151424884a46811ed593aa8a02ee5012e9332a4dcf1e9236a8ed4443c3e92506105f9918691869186916116f5565b60405180910390a1505050565b61060e610b8c565b61061782610c90565b6106218282610d8f565b5050565b5f61062e610ec8565b507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc90565b5f61065d8161088d565b610511610f37565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00805468010000000000000000810460ff16159067ffffffffffffffff165f811580156106af5750825b90505f8267ffffffffffffffff1660011480156106cb5750303b155b9050811580156106d9575080155b15610710576040517ff92ee8a900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b84547fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000016600117855583156107715784547fffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff16680100000000000000001785555b73ffffffffffffffffffffffffffffffffffffffff86166107be576040517f3ef39b8100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6107c6610fb0565b6107ce610fb0565b6107d6610fb8565b6107e05f87610897565b5083156108425784547fffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b505050505050565b5f8281527f02dd7bc7dec4dceedda775e58dd541e08a116c6c53815c0bd028192f7b62680060205260409020600101546108838161088d565b61049b83836109b5565b6105118133610fc8565b5f8281527f02dd7bc7dec4dceedda775e58dd541e08a116c6c53815c0bd028192f7b6268006020818152604080842073ffffffffffffffffffffffffffffffffffffffff8616855290915282205460ff166109ac575f8481526020828152604080832073ffffffffffffffffffffffffffffffffffffffff87168452909152902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790556109483390565b73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16857f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a46001915050610452565b5f915050610452565b5f8281527f02dd7bc7dec4dceedda775e58dd541e08a116c6c53815c0bd028192f7b6268006020818152604080842073ffffffffffffffffffffffffffffffffffffffff8616855290915282205460ff16156109ac575f8481526020828152604080832073ffffffffffffffffffffffffffffffffffffffff8716808552925280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905551339287917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a46001915050610452565b610a9961106e565b7fcd5ed15c6e187e77e9aee88184c21f4f2182ab5827cb3b7e07fbedcd63f0330080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001681557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390a150565b7fcd5ed15c6e187e77e9aee88184c21f4f2182ab5827cb3b7e07fbedcd63f033005460ff1615610b8a576040517fd93c066500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b3073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000161480610c5957507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16610c407f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5473ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff1614155b15610b8a576040517fe07c8dba00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f610c9a8161088d565b73ffffffffffffffffffffffffffffffffffffffff8216610d3d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f4e657720696d706c656d656e746174696f6e2063616e6e6f74206265207a657260448201527f6f20616464726573730000000000000000000000000000000000000000000000606482015260840161057d565b6040805133815273ffffffffffffffffffffffffffffffffffffffff841660208201527fd30e1d298bf814ea43d22b4ce8298062b08609cd67496483769d836157dd52fa910160405180910390a15050565b8173ffffffffffffffffffffffffffffffffffffffff166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015610e14575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201909252610e119181019061175b565b60015b610e62576040517f4c9c8ce300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8316600482015260240161057d565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc8114610ebe576040517faa1d49a40000000000000000000000000000000000000000000000000000000081526004810182905260240161057d565b6104fa83836110c9565b3073ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610b8a576040517fe07c8dba00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610f3f610b2e565b7fcd5ed15c6e187e77e9aee88184c21f4f2182ab5827cb3b7e07fbedcd63f0330080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011781557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25833610b03565b610b8a61112b565b610fc061112b565b610b8a611192565b5f8281527f02dd7bc7dec4dceedda775e58dd541e08a116c6c53815c0bd028192f7b6268006020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff16610621576040517fe2517d3f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821660048201526024810183905260440161057d565b7fcd5ed15c6e187e77e9aee88184c21f4f2182ab5827cb3b7e07fbedcd63f033005460ff16610b8a576040517f8dfc202b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6110d2826111e3565b60405173ffffffffffffffffffffffffffffffffffffffff8316907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b905f90a2805115611123576104fa82826112b1565b610621611330565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a005468010000000000000000900460ff16610b8a576040517fd7e6bcf800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61119a61112b565b7fcd5ed15c6e187e77e9aee88184c21f4f2182ab5827cb3b7e07fbedcd63f0330080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b8073ffffffffffffffffffffffffffffffffffffffff163b5f0361124b576040517f4c9c8ce300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8216600482015260240161057d565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60605f5f8473ffffffffffffffffffffffffffffffffffffffff16846040516112da9190611772565b5f60405180830381855af49150503d805f8114611312576040519150601f19603f3d011682016040523d82523d5f602084013e611317565b606091505b5091509150611327858383611368565b95945050505050565b3415610b8a576040517fb398979f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60608261137d57611378826113fa565b6113f3565b81511580156113a1575073ffffffffffffffffffffffffffffffffffffffff84163b155b156113f0576040517f9996b31500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8516600482015260240161057d565b50805b9392505050565b80511561140a5780518082602001fd5b6040517fd6bda27500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f6020828403121561144c575f5ffd5b81357fffffffff00000000000000000000000000000000000000000000000000000000811681146113f3575f5ffd5b5f6020828403121561148b575f5ffd5b5035919050565b803573ffffffffffffffffffffffffffffffffffffffff811681146114b5575f5ffd5b919050565b5f5f604083850312156114cb575f5ffd5b823591506114db60208401611492565b90509250929050565b5f5f5f604084860312156114f6575f5ffd5b83359250602084013567ffffffffffffffff811115611513575f5ffd5b8401601f81018613611523575f5ffd5b803567ffffffffffffffff811115611539575f5ffd5b86602082840101111561154a575f5ffd5b939660209190910195509293505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b5f5f60408385031215611599575f5ffd5b6115a283611492565b9150602083013567ffffffffffffffff8111156115bd575f5ffd5b8301601f810185136115cd575f5ffd5b803567ffffffffffffffff8111156115e7576115e761155b565b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8501160116810181811067ffffffffffffffff821117156116535761165361155b565b60405281815282820160200187101561166a575f5ffd5b816020840160208301375f602083830101528093505050509250929050565b602081525f82518060208401528060208501604085015e5f6040828501015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011684010191505092915050565b5f602082840312156116ec575f5ffd5b6113f382611492565b84815260606020820152826060820152828460808301375f608084830101525f60807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f860116830101905067ffffffffffffffff8316604083015295945050505050565b5f6020828403121561176b575f5ffd5b5051919050565b5f82518060208501845e5f92019182525091905056fea264697066735822122072d7566503253678adc66fd27920aaabe0ac779b70ca5ff95eb4b05309ab3a9064736f6c634300081c0033", + Bin: "0x60a0604052306080523480156012575f5ffd5b506080516117be6100395f395f8181610ba401528181610bcd0152610ee001526117be5ff3fe608060405260043610610109575f3560e01c80635c975abb116100a1578063a2ba193411610071578063c4d66de811610057578063c4d66de81461036e578063d547741f1461038d578063f5368506146103ac575f5ffd5b8063a2ba193414610303578063ad3cb1cc14610319575f5ffd5b80635c975abb146102365780638456cb591461026c57806391d1485414610280578063a217fddf146102f0575f5ffd5b80633f4ba83a116100dc5780633f4ba83a146101dc5780634dff26b5146101f05780634f1ef2861461020f57806352d1902d14610222575f5ffd5b806301ffc9a71461010d578063248a9ca3146101415780632f2ff15d1461019c57806336568abe146101bd575b5f5ffd5b348015610118575f5ffd5b5061012c61012736600461143c565b6103c0565b60405190151581526020015b60405180910390f35b34801561014c575f5ffd5b5061018e61015b36600461147b565b5f9081527f02dd7bc7dec4dceedda775e58dd541e08a116c6c53815c0bd028192f7b626800602052604090206001015490565b604051908152602001610138565b3480156101a7575f5ffd5b506101bb6101b63660046114ba565b610458565b005b3480156101c8575f5ffd5b506101bb6101d73660046114ba565b6104a1565b3480156101e7575f5ffd5b506101bb6104ff565b3480156101fb575f5ffd5b506101bb61020a3660046114e4565b610514565b6101bb61021d366004611588565b610606565b34801561022d575f5ffd5b5061018e610625565b348015610241575f5ffd5b507fcd5ed15c6e187e77e9aee88184c21f4f2182ab5827cb3b7e07fbedcd63f033005460ff1661012c565b348015610277575f5ffd5b506101bb610653565b34801561028b575f5ffd5b5061012c61029a3660046114ba565b5f9182527f02dd7bc7dec4dceedda775e58dd541e08a116c6c53815c0bd028192f7b6268006020908152604080842073ffffffffffffffffffffffffffffffffffffffff93909316845291905290205460ff1690565b3480156102fb575f5ffd5b5061018e5f81565b34801561030e575f5ffd5b5061018e6240000081565b348015610324575f5ffd5b506103616040518060400160405280600581526020017f352e302e3000000000000000000000000000000000000000000000000000000081525081565b6040516101389190611689565b348015610379575f5ffd5b506101bb6103883660046116dc565b610665565b348015610398575f5ffd5b506101bb6103a73660046114ba565b61084a565b3480156103b7575f5ffd5b5061018e604e81565b5f7fffffffff0000000000000000000000000000000000000000000000000000000082167f7965db0b00000000000000000000000000000000000000000000000000000000148061045257507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b92915050565b5f8281527f02dd7bc7dec4dceedda775e58dd541e08a116c6c53815c0bd028192f7b62680060205260409020600101546104918161088d565b61049b8383610897565b50505050565b73ffffffffffffffffffffffffffffffffffffffff811633146104f0576040517f6697b23200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6104fa82826109b5565b505050565b5f6105098161088d565b610511610a91565b50565b61051c610b2e565b604e81108015906105305750624000008111155b8190604e906240000090610586576040517f93b7abe60000000000000000000000000000000000000000000000000000000081526004810193909352602483019190915260448201526064015b60405180910390fd5b50505f805467ffffffffffffffff808216600101167fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000090911681179091556040517f91f47151424884a46811ed593aa8a02ee5012e9332a4dcf1e9236a8ed4443c3e92506105f9918691869186916116f5565b60405180910390a1505050565b61060e610b8c565b61061782610c90565b6106218282610d8f565b5050565b5f61062e610ec8565b507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc90565b5f61065d8161088d565b610511610f37565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00805468010000000000000000810460ff16159067ffffffffffffffff165f811580156106af5750825b90505f8267ffffffffffffffff1660011480156106cb5750303b155b9050811580156106d9575080155b15610710576040517ff92ee8a900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b84547fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000016600117855583156107715784547fffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff16680100000000000000001785555b73ffffffffffffffffffffffffffffffffffffffff86166107be576040517f3ef39b8100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6107c6610fb0565b6107ce610fb0565b6107d6610fb8565b6107e05f87610897565b5083156108425784547fffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b505050505050565b5f8281527f02dd7bc7dec4dceedda775e58dd541e08a116c6c53815c0bd028192f7b62680060205260409020600101546108838161088d565b61049b83836109b5565b6105118133610fc8565b5f8281527f02dd7bc7dec4dceedda775e58dd541e08a116c6c53815c0bd028192f7b6268006020818152604080842073ffffffffffffffffffffffffffffffffffffffff8616855290915282205460ff166109ac575f8481526020828152604080832073ffffffffffffffffffffffffffffffffffffffff87168452909152902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790556109483390565b73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16857f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a46001915050610452565b5f915050610452565b5f8281527f02dd7bc7dec4dceedda775e58dd541e08a116c6c53815c0bd028192f7b6268006020818152604080842073ffffffffffffffffffffffffffffffffffffffff8616855290915282205460ff16156109ac575f8481526020828152604080832073ffffffffffffffffffffffffffffffffffffffff8716808552925280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905551339287917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a46001915050610452565b610a9961106e565b7fcd5ed15c6e187e77e9aee88184c21f4f2182ab5827cb3b7e07fbedcd63f0330080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001681557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390a150565b7fcd5ed15c6e187e77e9aee88184c21f4f2182ab5827cb3b7e07fbedcd63f033005460ff1615610b8a576040517fd93c066500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b3073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000161480610c5957507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16610c407f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5473ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff1614155b15610b8a576040517fe07c8dba00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f610c9a8161088d565b73ffffffffffffffffffffffffffffffffffffffff8216610d3d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f4e657720696d706c656d656e746174696f6e2063616e6e6f74206265207a657260448201527f6f20616464726573730000000000000000000000000000000000000000000000606482015260840161057d565b6040805133815273ffffffffffffffffffffffffffffffffffffffff841660208201527fd30e1d298bf814ea43d22b4ce8298062b08609cd67496483769d836157dd52fa910160405180910390a15050565b8173ffffffffffffffffffffffffffffffffffffffff166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015610e14575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201909252610e119181019061175b565b60015b610e62576040517f4c9c8ce300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8316600482015260240161057d565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc8114610ebe576040517faa1d49a40000000000000000000000000000000000000000000000000000000081526004810182905260240161057d565b6104fa83836110c9565b3073ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610b8a576040517fe07c8dba00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610f3f610b2e565b7fcd5ed15c6e187e77e9aee88184c21f4f2182ab5827cb3b7e07fbedcd63f0330080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011781557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25833610b03565b610b8a61112b565b610fc061112b565b610b8a611192565b5f8281527f02dd7bc7dec4dceedda775e58dd541e08a116c6c53815c0bd028192f7b6268006020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff16610621576040517fe2517d3f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821660048201526024810183905260440161057d565b7fcd5ed15c6e187e77e9aee88184c21f4f2182ab5827cb3b7e07fbedcd63f033005460ff16610b8a576040517f8dfc202b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6110d2826111e3565b60405173ffffffffffffffffffffffffffffffffffffffff8316907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b905f90a2805115611123576104fa82826112b1565b610621611330565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a005468010000000000000000900460ff16610b8a576040517fd7e6bcf800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61119a61112b565b7fcd5ed15c6e187e77e9aee88184c21f4f2182ab5827cb3b7e07fbedcd63f0330080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b8073ffffffffffffffffffffffffffffffffffffffff163b5f0361124b576040517f4c9c8ce300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8216600482015260240161057d565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60605f5f8473ffffffffffffffffffffffffffffffffffffffff16846040516112da9190611772565b5f60405180830381855af49150503d805f8114611312576040519150601f19603f3d011682016040523d82523d5f602084013e611317565b606091505b5091509150611327858383611368565b95945050505050565b3415610b8a576040517fb398979f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60608261137d57611378826113fa565b6113f3565b81511580156113a1575073ffffffffffffffffffffffffffffffffffffffff84163b155b156113f0576040517f9996b31500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8516600482015260240161057d565b50805b9392505050565b80511561140a5780518082602001fd5b6040517fd6bda27500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f6020828403121561144c575f5ffd5b81357fffffffff00000000000000000000000000000000000000000000000000000000811681146113f3575f5ffd5b5f6020828403121561148b575f5ffd5b5035919050565b803573ffffffffffffffffffffffffffffffffffffffff811681146114b5575f5ffd5b919050565b5f5f604083850312156114cb575f5ffd5b823591506114db60208401611492565b90509250929050565b5f5f5f604084860312156114f6575f5ffd5b83359250602084013567ffffffffffffffff811115611513575f5ffd5b8401601f81018613611523575f5ffd5b803567ffffffffffffffff811115611539575f5ffd5b86602082840101111561154a575f5ffd5b939660209190910195509293505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b5f5f60408385031215611599575f5ffd5b6115a283611492565b9150602083013567ffffffffffffffff8111156115bd575f5ffd5b8301601f810185136115cd575f5ffd5b803567ffffffffffffffff8111156115e7576115e761155b565b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8501160116810181811067ffffffffffffffff821117156116535761165361155b565b60405281815282820160200187101561166a575f5ffd5b816020840160208301375f602083830101528093505050509250929050565b602081525f82518060208401528060208501604085015e5f6040828501015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011684010191505092915050565b5f602082840312156116ec575f5ffd5b6113f382611492565b84815260606020820152826060820152828460808301375f608084830101525f60807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f860116830101905067ffffffffffffffff8316604083015295945050505050565b5f6020828403121561176b575f5ffd5b5051919050565b5f82518060208501845e5f92019182525091905056fea2646970667358221220c75e50afed7163b3cd75fd1432b108e7bcf294c0e2cacb4037b4b04401d4361864736f6c634300081c0033", } // GroupMessagesABI is the input ABI used to generate the binding from. diff --git a/contracts/pkg/identityupdates/IdentityUpdates.go b/contracts/pkg/identityupdates/IdentityUpdates.go index c4a2d5d2..0f437ad6 100644 --- a/contracts/pkg/identityupdates/IdentityUpdates.go +++ b/contracts/pkg/identityupdates/IdentityUpdates.go @@ -32,7 +32,7 @@ var ( // IdentityUpdatesMetaData contains all meta data concerning the IdentityUpdates contract. var IdentityUpdatesMetaData = &bind.MetaData{ ABI: "[{\"type\":\"function\",\"name\":\"DEFAULT_ADMIN_ROLE\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"MAX_PAYLOAD_SIZE\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"MIN_PAYLOAD_SIZE\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"UPGRADE_INTERFACE_VERSION\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"addIdentityUpdate\",\"inputs\":[{\"name\":\"inboxId\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"update\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"getRoleAdmin\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"grantRole\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"hasRole\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"initialize\",\"inputs\":[{\"name\":\"_admin\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"pause\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"paused\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"proxiableUUID\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"renounceRole\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"callerConfirmation\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"revokeRole\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"supportsInterface\",\"inputs\":[{\"name\":\"interfaceId\",\"type\":\"bytes4\",\"internalType\":\"bytes4\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"unpause\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"upgradeToAndCall\",\"inputs\":[{\"name\":\"newImplementation\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"data\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"event\",\"name\":\"IdentityUpdateCreated\",\"inputs\":[{\"name\":\"inboxId\",\"type\":\"bytes32\",\"indexed\":false,\"internalType\":\"bytes32\"},{\"name\":\"update\",\"type\":\"bytes\",\"indexed\":false,\"internalType\":\"bytes\"},{\"name\":\"sequenceId\",\"type\":\"uint64\",\"indexed\":false,\"internalType\":\"uint64\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Initialized\",\"inputs\":[{\"name\":\"version\",\"type\":\"uint64\",\"indexed\":false,\"internalType\":\"uint64\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Paused\",\"inputs\":[{\"name\":\"account\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"RoleAdminChanged\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"previousAdminRole\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"newAdminRole\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"RoleGranted\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"account\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"sender\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"RoleRevoked\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"account\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"sender\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Unpaused\",\"inputs\":[{\"name\":\"account\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"UpgradeAuthorized\",\"inputs\":[{\"name\":\"upgrader\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"},{\"name\":\"newImplementation\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Upgraded\",\"inputs\":[{\"name\":\"implementation\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"error\",\"name\":\"AccessControlBadConfirmation\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"AccessControlUnauthorizedAccount\",\"inputs\":[{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"neededRole\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}]},{\"type\":\"error\",\"name\":\"AddressEmptyCode\",\"inputs\":[{\"name\":\"target\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"type\":\"error\",\"name\":\"ERC1967InvalidImplementation\",\"inputs\":[{\"name\":\"implementation\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"type\":\"error\",\"name\":\"ERC1967NonPayable\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"EnforcedPause\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"ExpectedPause\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"FailedCall\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidInitialization\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidPayloadSize\",\"inputs\":[{\"name\":\"actualSize\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"minSize\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"maxSize\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]},{\"type\":\"error\",\"name\":\"NotInitializing\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"UUPSUnauthorizedCallContext\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"UUPSUnsupportedProxiableUUID\",\"inputs\":[{\"name\":\"slot\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}]},{\"type\":\"error\",\"name\":\"ZeroAdminAddress\",\"inputs\":[]}]", - Bin: "0x60a0604052306080523480156012575f5ffd5b506080516117be6100395f395f8181610b4601528181610b6f0152610e8401526117be5ff3fe608060405260043610610109575f3560e01c80638456cb59116100a1578063ad3cb1cc11610071578063c4d66de811610057578063c4d66de81461036e578063d547741f1461038d578063f5368506146103ac575f5ffd5b8063ad3cb1cc146102fa578063ba74fc7c1461034f575f5ffd5b80638456cb591461024d57806391d1485414610261578063a217fddf146102d1578063a2ba1934146102e4575f5ffd5b80633f4ba83a116100dc5780633f4ba83a146101dc5780634f1ef286146101f057806352d1902d146102035780635c975abb14610217575f5ffd5b806301ffc9a71461010d578063248a9ca3146101415780632f2ff15d1461019c57806336568abe146101bd575b5f5ffd5b348015610118575f5ffd5b5061012c61012736600461143c565b6103c0565b60405190151581526020015b60405180910390f35b34801561014c575f5ffd5b5061018e61015b36600461147b565b5f9081527f02dd7bc7dec4dceedda775e58dd541e08a116c6c53815c0bd028192f7b626800602052604090206001015490565b604051908152602001610138565b3480156101a7575f5ffd5b506101bb6101b63660046114ba565b610458565b005b3480156101c8575f5ffd5b506101bb6101d73660046114ba565b6104a1565b3480156101e7575f5ffd5b506101bb6104ff565b6101bb6101fe366004611511565b610514565b34801561020e575f5ffd5b5061018e610533565b348015610222575f5ffd5b507fcd5ed15c6e187e77e9aee88184c21f4f2182ab5827cb3b7e07fbedcd63f033005460ff1661012c565b348015610258575f5ffd5b506101bb610561565b34801561026c575f5ffd5b5061012c61027b3660046114ba565b5f9182527f02dd7bc7dec4dceedda775e58dd541e08a116c6c53815c0bd028192f7b6268006020908152604080842073ffffffffffffffffffffffffffffffffffffffff93909316845291905290205460ff1690565b3480156102dc575f5ffd5b5061018e5f81565b3480156102ef575f5ffd5b5061018e6240000081565b348015610305575f5ffd5b506103426040518060400160405280600581526020017f352e302e3000000000000000000000000000000000000000000000000000000081525081565b6040516101389190611612565b34801561035a575f5ffd5b506101bb610369366004611665565b610573565b348015610379575f5ffd5b506101bb6103883660046116dc565b610665565b348015610398575f5ffd5b506101bb6103a73660046114ba565b61084a565b3480156103b7575f5ffd5b5061018e606881565b5f7fffffffff0000000000000000000000000000000000000000000000000000000082167f7965db0b00000000000000000000000000000000000000000000000000000000148061045257507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b92915050565b5f8281527f02dd7bc7dec4dceedda775e58dd541e08a116c6c53815c0bd028192f7b62680060205260409020600101546104918161088d565b61049b8383610897565b50505050565b73ffffffffffffffffffffffffffffffffffffffff811633146104f0576040517f6697b23200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6104fa82826109b5565b505050565b5f6105098161088d565b610511610a91565b50565b61051c610b2e565b61052582610c34565b61052f8282610d33565b5050565b5f61053c610e6c565b507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc90565b5f61056b8161088d565b610511610edb565b61057b610f54565b6068811080159061058f5750624000008111155b819060689062400000906105e5576040517f93b7abe60000000000000000000000000000000000000000000000000000000081526004810193909352602483019190915260448201526064015b60405180910390fd5b50505f805467ffffffffffffffff808216600101167fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000090911681179091556040517fc1a40f292090ec0435e939cdfe248e0322a88566679a90a50c4e9e5ef762dbd59250610658918691869186916116f5565b60405180910390a1505050565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00805468010000000000000000810460ff16159067ffffffffffffffff165f811580156106af5750825b90505f8267ffffffffffffffff1660011480156106cb5750303b155b9050811580156106d9575080155b15610710576040517ff92ee8a900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b84547fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000016600117855583156107715784547fffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff16680100000000000000001785555b73ffffffffffffffffffffffffffffffffffffffff86166107be576040517f3ef39b8100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6107c6610fb0565b6107ce610fb0565b6107d6610fb8565b6107e05f87610897565b5083156108425784547fffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b505050505050565b5f8281527f02dd7bc7dec4dceedda775e58dd541e08a116c6c53815c0bd028192f7b62680060205260409020600101546108838161088d565b61049b83836109b5565b6105118133610fc8565b5f8281527f02dd7bc7dec4dceedda775e58dd541e08a116c6c53815c0bd028192f7b6268006020818152604080842073ffffffffffffffffffffffffffffffffffffffff8616855290915282205460ff166109ac575f8481526020828152604080832073ffffffffffffffffffffffffffffffffffffffff87168452909152902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790556109483390565b73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16857f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a46001915050610452565b5f915050610452565b5f8281527f02dd7bc7dec4dceedda775e58dd541e08a116c6c53815c0bd028192f7b6268006020818152604080842073ffffffffffffffffffffffffffffffffffffffff8616855290915282205460ff16156109ac575f8481526020828152604080832073ffffffffffffffffffffffffffffffffffffffff8716808552925280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905551339287917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a46001915050610452565b610a9961106e565b7fcd5ed15c6e187e77e9aee88184c21f4f2182ab5827cb3b7e07fbedcd63f0330080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001681557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390a150565b3073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000161480610bfb57507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16610be27f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5473ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff1614155b15610c32576040517fe07c8dba00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b5f610c3e8161088d565b73ffffffffffffffffffffffffffffffffffffffff8216610ce1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f4e657720696d706c656d656e746174696f6e2063616e6e6f74206265207a657260448201527f6f2061646472657373000000000000000000000000000000000000000000000060648201526084016105dc565b6040805133815273ffffffffffffffffffffffffffffffffffffffff841660208201527fd30e1d298bf814ea43d22b4ce8298062b08609cd67496483769d836157dd52fa910160405180910390a15050565b8173ffffffffffffffffffffffffffffffffffffffff166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015610db8575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201909252610db59181019061175b565b60015b610e06576040517f4c9c8ce300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff831660048201526024016105dc565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc8114610e62576040517faa1d49a4000000000000000000000000000000000000000000000000000000008152600481018290526024016105dc565b6104fa83836110c9565b3073ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610c32576040517fe07c8dba00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610ee3610f54565b7fcd5ed15c6e187e77e9aee88184c21f4f2182ab5827cb3b7e07fbedcd63f0330080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011781557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25833610b03565b7fcd5ed15c6e187e77e9aee88184c21f4f2182ab5827cb3b7e07fbedcd63f033005460ff1615610c32576040517fd93c066500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610c3261112b565b610fc061112b565b610c32611192565b5f8281527f02dd7bc7dec4dceedda775e58dd541e08a116c6c53815c0bd028192f7b6268006020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff1661052f576040517fe2517d3f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82166004820152602481018390526044016105dc565b7fcd5ed15c6e187e77e9aee88184c21f4f2182ab5827cb3b7e07fbedcd63f033005460ff16610c32576040517f8dfc202b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6110d2826111e3565b60405173ffffffffffffffffffffffffffffffffffffffff8316907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b905f90a2805115611123576104fa82826112b1565b61052f611330565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a005468010000000000000000900460ff16610c32576040517fd7e6bcf800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61119a61112b565b7fcd5ed15c6e187e77e9aee88184c21f4f2182ab5827cb3b7e07fbedcd63f0330080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b8073ffffffffffffffffffffffffffffffffffffffff163b5f0361124b576040517f4c9c8ce300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821660048201526024016105dc565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60605f5f8473ffffffffffffffffffffffffffffffffffffffff16846040516112da9190611772565b5f60405180830381855af49150503d805f8114611312576040519150601f19603f3d011682016040523d82523d5f602084013e611317565b606091505b5091509150611327858383611368565b95945050505050565b3415610c32576040517fb398979f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60608261137d57611378826113fa565b6113f3565b81511580156113a1575073ffffffffffffffffffffffffffffffffffffffff84163b155b156113f0576040517f9996b31500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff851660048201526024016105dc565b50805b9392505050565b80511561140a5780518082602001fd5b6040517fd6bda27500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f6020828403121561144c575f5ffd5b81357fffffffff00000000000000000000000000000000000000000000000000000000811681146113f3575f5ffd5b5f6020828403121561148b575f5ffd5b5035919050565b803573ffffffffffffffffffffffffffffffffffffffff811681146114b5575f5ffd5b919050565b5f5f604083850312156114cb575f5ffd5b823591506114db60208401611492565b90509250929050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b5f5f60408385031215611522575f5ffd5b61152b83611492565b9150602083013567ffffffffffffffff811115611546575f5ffd5b8301601f81018513611556575f5ffd5b803567ffffffffffffffff811115611570576115706114e4565b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8501160116810181811067ffffffffffffffff821117156115dc576115dc6114e4565b6040528181528282016020018710156115f3575f5ffd5b816020840160208301375f602083830101528093505050509250929050565b602081525f82518060208401528060208501604085015e5f6040828501015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011684010191505092915050565b5f5f5f60408486031215611677575f5ffd5b83359250602084013567ffffffffffffffff811115611694575f5ffd5b8401601f810186136116a4575f5ffd5b803567ffffffffffffffff8111156116ba575f5ffd5b8660208284010111156116cb575f5ffd5b939660209190910195509293505050565b5f602082840312156116ec575f5ffd5b6113f382611492565b84815260606020820152826060820152828460808301375f608084830101525f60807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f860116830101905067ffffffffffffffff8316604083015295945050505050565b5f6020828403121561176b575f5ffd5b5051919050565b5f82518060208501845e5f92019182525091905056fea26469706673582212202d65f062d705cb761a34070256e7c4f8eab20ae6669f6158830cb02fcd42c16164736f6c634300081c0033", + Bin: "0x60a0604052306080523480156012575f5ffd5b506080516117be6100395f395f8181610b4601528181610b6f0152610e8401526117be5ff3fe608060405260043610610109575f3560e01c80638456cb59116100a1578063ad3cb1cc11610071578063c4d66de811610057578063c4d66de81461036e578063d547741f1461038d578063f5368506146103ac575f5ffd5b8063ad3cb1cc146102fa578063ba74fc7c1461034f575f5ffd5b80638456cb591461024d57806391d1485414610261578063a217fddf146102d1578063a2ba1934146102e4575f5ffd5b80633f4ba83a116100dc5780633f4ba83a146101dc5780634f1ef286146101f057806352d1902d146102035780635c975abb14610217575f5ffd5b806301ffc9a71461010d578063248a9ca3146101415780632f2ff15d1461019c57806336568abe146101bd575b5f5ffd5b348015610118575f5ffd5b5061012c61012736600461143c565b6103c0565b60405190151581526020015b60405180910390f35b34801561014c575f5ffd5b5061018e61015b36600461147b565b5f9081527f02dd7bc7dec4dceedda775e58dd541e08a116c6c53815c0bd028192f7b626800602052604090206001015490565b604051908152602001610138565b3480156101a7575f5ffd5b506101bb6101b63660046114ba565b610458565b005b3480156101c8575f5ffd5b506101bb6101d73660046114ba565b6104a1565b3480156101e7575f5ffd5b506101bb6104ff565b6101bb6101fe366004611511565b610514565b34801561020e575f5ffd5b5061018e610533565b348015610222575f5ffd5b507fcd5ed15c6e187e77e9aee88184c21f4f2182ab5827cb3b7e07fbedcd63f033005460ff1661012c565b348015610258575f5ffd5b506101bb610561565b34801561026c575f5ffd5b5061012c61027b3660046114ba565b5f9182527f02dd7bc7dec4dceedda775e58dd541e08a116c6c53815c0bd028192f7b6268006020908152604080842073ffffffffffffffffffffffffffffffffffffffff93909316845291905290205460ff1690565b3480156102dc575f5ffd5b5061018e5f81565b3480156102ef575f5ffd5b5061018e6240000081565b348015610305575f5ffd5b506103426040518060400160405280600581526020017f352e302e3000000000000000000000000000000000000000000000000000000081525081565b6040516101389190611612565b34801561035a575f5ffd5b506101bb610369366004611665565b610573565b348015610379575f5ffd5b506101bb6103883660046116dc565b610665565b348015610398575f5ffd5b506101bb6103a73660046114ba565b61084a565b3480156103b7575f5ffd5b5061018e606881565b5f7fffffffff0000000000000000000000000000000000000000000000000000000082167f7965db0b00000000000000000000000000000000000000000000000000000000148061045257507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b92915050565b5f8281527f02dd7bc7dec4dceedda775e58dd541e08a116c6c53815c0bd028192f7b62680060205260409020600101546104918161088d565b61049b8383610897565b50505050565b73ffffffffffffffffffffffffffffffffffffffff811633146104f0576040517f6697b23200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6104fa82826109b5565b505050565b5f6105098161088d565b610511610a91565b50565b61051c610b2e565b61052582610c34565b61052f8282610d33565b5050565b5f61053c610e6c565b507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc90565b5f61056b8161088d565b610511610edb565b61057b610f54565b6068811080159061058f5750624000008111155b819060689062400000906105e5576040517f93b7abe60000000000000000000000000000000000000000000000000000000081526004810193909352602483019190915260448201526064015b60405180910390fd5b50505f805467ffffffffffffffff808216600101167fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000090911681179091556040517fc1a40f292090ec0435e939cdfe248e0322a88566679a90a50c4e9e5ef762dbd59250610658918691869186916116f5565b60405180910390a1505050565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00805468010000000000000000810460ff16159067ffffffffffffffff165f811580156106af5750825b90505f8267ffffffffffffffff1660011480156106cb5750303b155b9050811580156106d9575080155b15610710576040517ff92ee8a900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b84547fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000016600117855583156107715784547fffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff16680100000000000000001785555b73ffffffffffffffffffffffffffffffffffffffff86166107be576040517f3ef39b8100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6107c6610fb0565b6107ce610fb0565b6107d6610fb8565b6107e05f87610897565b5083156108425784547fffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b505050505050565b5f8281527f02dd7bc7dec4dceedda775e58dd541e08a116c6c53815c0bd028192f7b62680060205260409020600101546108838161088d565b61049b83836109b5565b6105118133610fc8565b5f8281527f02dd7bc7dec4dceedda775e58dd541e08a116c6c53815c0bd028192f7b6268006020818152604080842073ffffffffffffffffffffffffffffffffffffffff8616855290915282205460ff166109ac575f8481526020828152604080832073ffffffffffffffffffffffffffffffffffffffff87168452909152902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790556109483390565b73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16857f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a46001915050610452565b5f915050610452565b5f8281527f02dd7bc7dec4dceedda775e58dd541e08a116c6c53815c0bd028192f7b6268006020818152604080842073ffffffffffffffffffffffffffffffffffffffff8616855290915282205460ff16156109ac575f8481526020828152604080832073ffffffffffffffffffffffffffffffffffffffff8716808552925280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905551339287917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a46001915050610452565b610a9961106e565b7fcd5ed15c6e187e77e9aee88184c21f4f2182ab5827cb3b7e07fbedcd63f0330080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001681557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390a150565b3073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000161480610bfb57507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16610be27f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5473ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff1614155b15610c32576040517fe07c8dba00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b5f610c3e8161088d565b73ffffffffffffffffffffffffffffffffffffffff8216610ce1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f4e657720696d706c656d656e746174696f6e2063616e6e6f74206265207a657260448201527f6f2061646472657373000000000000000000000000000000000000000000000060648201526084016105dc565b6040805133815273ffffffffffffffffffffffffffffffffffffffff841660208201527fd30e1d298bf814ea43d22b4ce8298062b08609cd67496483769d836157dd52fa910160405180910390a15050565b8173ffffffffffffffffffffffffffffffffffffffff166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015610db8575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201909252610db59181019061175b565b60015b610e06576040517f4c9c8ce300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff831660048201526024016105dc565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc8114610e62576040517faa1d49a4000000000000000000000000000000000000000000000000000000008152600481018290526024016105dc565b6104fa83836110c9565b3073ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610c32576040517fe07c8dba00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610ee3610f54565b7fcd5ed15c6e187e77e9aee88184c21f4f2182ab5827cb3b7e07fbedcd63f0330080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011781557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25833610b03565b7fcd5ed15c6e187e77e9aee88184c21f4f2182ab5827cb3b7e07fbedcd63f033005460ff1615610c32576040517fd93c066500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610c3261112b565b610fc061112b565b610c32611192565b5f8281527f02dd7bc7dec4dceedda775e58dd541e08a116c6c53815c0bd028192f7b6268006020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff1661052f576040517fe2517d3f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82166004820152602481018390526044016105dc565b7fcd5ed15c6e187e77e9aee88184c21f4f2182ab5827cb3b7e07fbedcd63f033005460ff16610c32576040517f8dfc202b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6110d2826111e3565b60405173ffffffffffffffffffffffffffffffffffffffff8316907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b905f90a2805115611123576104fa82826112b1565b61052f611330565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a005468010000000000000000900460ff16610c32576040517fd7e6bcf800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61119a61112b565b7fcd5ed15c6e187e77e9aee88184c21f4f2182ab5827cb3b7e07fbedcd63f0330080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b8073ffffffffffffffffffffffffffffffffffffffff163b5f0361124b576040517f4c9c8ce300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821660048201526024016105dc565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60605f5f8473ffffffffffffffffffffffffffffffffffffffff16846040516112da9190611772565b5f60405180830381855af49150503d805f8114611312576040519150601f19603f3d011682016040523d82523d5f602084013e611317565b606091505b5091509150611327858383611368565b95945050505050565b3415610c32576040517fb398979f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60608261137d57611378826113fa565b6113f3565b81511580156113a1575073ffffffffffffffffffffffffffffffffffffffff84163b155b156113f0576040517f9996b31500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff851660048201526024016105dc565b50805b9392505050565b80511561140a5780518082602001fd5b6040517fd6bda27500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f6020828403121561144c575f5ffd5b81357fffffffff00000000000000000000000000000000000000000000000000000000811681146113f3575f5ffd5b5f6020828403121561148b575f5ffd5b5035919050565b803573ffffffffffffffffffffffffffffffffffffffff811681146114b5575f5ffd5b919050565b5f5f604083850312156114cb575f5ffd5b823591506114db60208401611492565b90509250929050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b5f5f60408385031215611522575f5ffd5b61152b83611492565b9150602083013567ffffffffffffffff811115611546575f5ffd5b8301601f81018513611556575f5ffd5b803567ffffffffffffffff811115611570576115706114e4565b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8501160116810181811067ffffffffffffffff821117156115dc576115dc6114e4565b6040528181528282016020018710156115f3575f5ffd5b816020840160208301375f602083830101528093505050509250929050565b602081525f82518060208401528060208501604085015e5f6040828501015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011684010191505092915050565b5f5f5f60408486031215611677575f5ffd5b83359250602084013567ffffffffffffffff811115611694575f5ffd5b8401601f810186136116a4575f5ffd5b803567ffffffffffffffff8111156116ba575f5ffd5b8660208284010111156116cb575f5ffd5b939660209190910195509293505050565b5f602082840312156116ec575f5ffd5b6113f382611492565b84815260606020820152826060820152828460808301375f608084830101525f60807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f860116830101905067ffffffffffffffff8316604083015295945050505050565b5f6020828403121561176b575f5ffd5b5051919050565b5f82518060208501845e5f92019182525091905056fea2646970667358221220d2f35b6d0d2224e9743fc5f7cc5c75db625a1d12d506a9e162239033e938c86364736f6c634300081c0033", } // IdentityUpdatesABI is the input ABI used to generate the binding from. diff --git a/contracts/test/GroupMessage.t.sol b/contracts/test/GroupMessage.t.sol index 72bcb3a9..9becc55f 100644 --- a/contracts/test/GroupMessage.t.sol +++ b/contracts/test/GroupMessage.t.sol @@ -192,160 +192,4 @@ contract GroupMessagesTest is Test, GroupMessages, Utils { emit GroupMessages.MessageSent(ID, message, 2); groupMessages.addMessage(ID, message); } - - function testAddMessageWithMaxPayload() public { - bytes memory message = _generatePayload(MAX_PAYLOAD_SIZE); - - vm.expectEmit(address(groupMessages)); - emit GroupMessages.MessageSent(ID, message, 1); - - groupMessages.addMessage(ID, message); - } - - function testAddMessageTooSmall() public { - bytes memory message = _generatePayload(MIN_PAYLOAD_SIZE - 1); - - vm.expectRevert( - abi.encodeWithSelector( - GroupMessages.InvalidPayloadSize.selector, message.length, MIN_PAYLOAD_SIZE, MAX_PAYLOAD_SIZE - ) - ); - - groupMessages.addMessage(ID, message); - } - - function testAddMessageTooBig() public { - bytes memory message = _generatePayload(MAX_PAYLOAD_SIZE + 1); - - vm.expectRevert( - abi.encodeWithSelector( - GroupMessages.InvalidPayloadSize.selector, message.length, MIN_PAYLOAD_SIZE, MAX_PAYLOAD_SIZE - ) - ); - - groupMessages.addMessage(ID, message); - } - - function testAddMessageWhenPaused() public { - bytes memory message = _generatePayload(MIN_PAYLOAD_SIZE); - - groupMessages.pause(); - assertTrue(groupMessages.paused()); - - vm.expectRevert(abi.encodeWithSelector(PausableUpgradeable.EnforcedPause.selector)); - - groupMessages.addMessage(ID, message); - } - - function testSequenceIdIncrement() public { - bytes memory message = _generatePayload(MIN_PAYLOAD_SIZE); - - vm.expectEmit(address(groupMessages)); - emit GroupMessages.MessageSent(ID, message, 1); - groupMessages.addMessage(ID, message); - - vm.expectEmit(address(groupMessages)); - emit GroupMessages.MessageSent(ID, message, 2); - groupMessages.addMessage(ID, message); - - vm.expectEmit(address(groupMessages)); - emit GroupMessages.MessageSent(ID, message, 3); - groupMessages.addMessage(ID, message); - } - - function testInvalidReinitialization() public { - vm.expectRevert(Initializable.InvalidInitialization.selector); - groupMessages.initialize(admin); - } - - function testPauseUnpause() public { - groupMessages.pause(); - assertTrue(groupMessages.paused()); - - vm.prank(unauthorized); - vm.expectRevert( - abi.encodeWithSelector( - IAccessControl.AccessControlUnauthorizedAccount.selector, unauthorized, DEFAULT_ADMIN_ROLE - ) - ); - groupMessages.unpause(); - - groupMessages.unpause(); - assertFalse(groupMessages.paused()); - - vm.prank(unauthorized); - vm.expectRevert( - abi.encodeWithSelector( - IAccessControl.AccessControlUnauthorizedAccount.selector, unauthorized, DEFAULT_ADMIN_ROLE - ) - ); - groupMessages.pause(); - } - - function testRoles() public { - groupMessages.grantRole(DEFAULT_ADMIN_ROLE, unauthorized); - - vm.startPrank(unauthorized); - groupMessages.pause(); - groupMessages.unpause(); - vm.stopPrank(); - - groupMessages.revokeRole(DEFAULT_ADMIN_ROLE, unauthorized); - - vm.prank(unauthorized); - vm.expectRevert( - abi.encodeWithSelector( - IAccessControl.AccessControlUnauthorizedAccount.selector, unauthorized, DEFAULT_ADMIN_ROLE - ) - ); - groupMessages.pause(); - - groupMessages.renounceRole(DEFAULT_ADMIN_ROLE, admin); - vm.expectRevert( - abi.encodeWithSelector(IAccessControl.AccessControlUnauthorizedAccount.selector, admin, DEFAULT_ADMIN_ROLE) - ); - groupMessages.pause(); - } - - function testUpgradeImplementation() public { - GroupMessages newGroupMessagesImpl = new GroupMessages(); - address newImplAddress = address(newGroupMessagesImpl); - address oldImplAddress = address(groupMessagesImpl); - - bytes memory message = _generatePayload(MIN_PAYLOAD_SIZE); - - // Retrieve the implementation address directly from the proxy storage. - bytes32 rawImplAddress = vm.load(address(groupMessages), EIP1967_IMPL_SLOT); - address implementationAddress = address(uint160(uint256(rawImplAddress))); - assertEq(implementationAddress, oldImplAddress); - - // Initialize sequenceId to 1. The state should be preserved between upgrades. - vm.expectEmit(address(groupMessages)); - emit GroupMessages.MessageSent(ID, message, 1); - groupMessages.addMessage(ID, message); - - // Unauthorized upgrade attempts should revert. - vm.prank(unauthorized); - vm.expectRevert( - abi.encodeWithSelector( - IAccessControl.AccessControlUnauthorizedAccount.selector, unauthorized, DEFAULT_ADMIN_ROLE - ) - ); - groupMessages.upgradeToAndCall(address(newGroupMessagesImpl), ""); - - // Authorized upgrade should succeed and emit UpgradeAuthorized event. - vm.expectEmit(address(groupMessages)); - emit GroupMessages.UpgradeAuthorized(address(this), address(newGroupMessagesImpl)); - groupMessages.upgradeToAndCall(address(newGroupMessagesImpl), ""); - - // Retrieve the new implementation address directly from the proxy storage. - rawImplAddress = vm.load(address(groupMessages), EIP1967_IMPL_SLOT); - implementationAddress = address(uint160(uint256(rawImplAddress))); - assertEq(implementationAddress, newImplAddress); - - // Next sequenceId should be 2. - vm.expectEmit(address(groupMessages)); - emit GroupMessages.MessageSent(ID, message, 2); - groupMessages.addMessage(ID, message); - } }