diff --git a/.github/workflows/node.yml b/.github/workflows/node.yml index 448a975e0..71287978c 100644 --- a/.github/workflows/node.yml +++ b/.github/workflows/node.yml @@ -106,5 +106,13 @@ jobs: path: ./* key: ${{ github.sha }} + - name: Install Foundry + uses: onbjerg/foundry-toolchain@v1 + with: + version: nightly + + - name: Install dependencies + run: cd solidity && forge install + - name: core run: yarn workspace @hyperlane-xyz/core run test diff --git a/solidity/contracts/HyperlaneConnectionClient.sol b/solidity/contracts/HyperlaneConnectionClient.sol index 6e9f17404..e0403eba1 100644 --- a/solidity/contracts/HyperlaneConnectionClient.sol +++ b/solidity/contracts/HyperlaneConnectionClient.sol @@ -18,7 +18,7 @@ abstract contract HyperlaneConnectionClient is IMailbox public mailbox; // Interchain Gas Paymaster contract. The relayer associated with this contract - // must be willing to relay messages dispatched from the current Outbox contract, + // must be willing to relay messages dispatched from the current Mailbox contract, // otherwise payments made to the paymaster will not result in relayed messages. IInterchainGasPaymaster public interchainGasPaymaster; @@ -136,7 +136,7 @@ abstract contract HyperlaneConnectionClient is } /** - * @notice Modify the contract the Application uses to validate Inbox contracts + * @notice Modify the contract the Application uses to validate Mailbox contracts * @param _mailbox The address of the mailbox contract */ function _setMailbox(address _mailbox) internal onlyContract(_mailbox) { diff --git a/solidity/contracts/Mailbox.sol b/solidity/contracts/Mailbox.sol index b3ed34026..2e2bd1851 100644 --- a/solidity/contracts/Mailbox.sol +++ b/solidity/contracts/Mailbox.sol @@ -211,7 +211,7 @@ contract Mailbox is /** * @notice Returns a checkpoint representing the current merkle tree. - * @return root The root of the Outbox's merkle tree. + * @return root The root of the Mailbox's merkle tree. * @return index The index of the last element in the tree. */ function latestCheckpoint() public view returns (bytes32, uint32) { diff --git a/solidity/contracts/middleware/InterchainAccountRouter.sol b/solidity/contracts/middleware/InterchainAccountRouter.sol index f99b3ab32..0b1d5a23c 100644 --- a/solidity/contracts/middleware/InterchainAccountRouter.sol +++ b/solidity/contracts/middleware/InterchainAccountRouter.sol @@ -26,16 +26,16 @@ contract InterchainAccountRouter is Router, IInterchainAccountRouter { ); function initialize( - address _owner, address _mailbox, - address _interchainGasPaymaster + address _interchainGasPaymaster, + address _interchainSecurityModule ) public initializer { - // Transfer ownership of the contract to deployer - _transferOwnership(_owner); - // Set the addresses for the Mailbox and IGP - // Alternatively, this could be done later in an initialize method - _setMailbox(_mailbox); - _setInterchainGasPaymaster(_interchainGasPaymaster); + // Transfer ownership of the contract to `msg.sender` + __HyperlaneConnectionClient_initialize( + _mailbox, + _interchainGasPaymaster, + _interchainSecurityModule + ); } function dispatch(uint32 _destinationDomain, Call[] calldata calls) diff --git a/solidity/contracts/middleware/InterchainQueryRouter.sol b/solidity/contracts/middleware/InterchainQueryRouter.sol index cbb010c08..7f7bb9e8d 100644 --- a/solidity/contracts/middleware/InterchainQueryRouter.sol +++ b/solidity/contracts/middleware/InterchainQueryRouter.sol @@ -32,16 +32,16 @@ contract InterchainQueryRouter is ); function initialize( - address _owner, address _mailbox, - address _interchainGasPaymaster + address _interchainGasPaymaster, + address _interchainSecurityModule ) public initializer { - // Transfer ownership of the contract to deployer - _transferOwnership(_owner); - // Set the addresses for the Mailbox and IGP - // Alternatively, this could be done later in an initialize method - _setMailbox(_mailbox); - _setInterchainGasPaymaster(_interchainGasPaymaster); + // Transfer ownership of the contract to `msg.sender` + __HyperlaneConnectionClient_initialize( + _mailbox, + _interchainGasPaymaster, + _interchainSecurityModule + ); } /** diff --git a/solidity/contracts/middleware/liquidity-layer/LiquidityLayerRouter.sol b/solidity/contracts/middleware/liquidity-layer/LiquidityLayerRouter.sol index e29ebcbdc..2b2155e9d 100644 --- a/solidity/contracts/middleware/liquidity-layer/LiquidityLayerRouter.sol +++ b/solidity/contracts/middleware/liquidity-layer/LiquidityLayerRouter.sol @@ -20,15 +20,15 @@ contract LiquidityLayerRouter is Router { event LiquidityLayerAdapterSet(string indexed bridge, address adapter); function initialize( - address _owner, address _mailbox, - address _interchainGasPaymaster + address _interchainGasPaymaster, + address _interchainSecurityModule ) public initializer { __HyperlaneConnectionClient_initialize( _mailbox, - _interchainGasPaymaster + _interchainGasPaymaster, + _interchainSecurityModule ); - _transferOwnership(_owner); } function dispatchWithTokens( diff --git a/solidity/contracts/mock/MockHyperlaneEnvironment.sol b/solidity/contracts/mock/MockHyperlaneEnvironment.sol index d8bc99ea5..651b0835c 100644 --- a/solidity/contracts/mock/MockHyperlaneEnvironment.sol +++ b/solidity/contracts/mock/MockHyperlaneEnvironment.sol @@ -3,6 +3,8 @@ pragma solidity ^0.8.13; import "./MockMailbox.sol"; import "../middleware/InterchainQueryRouter.sol"; +import "../InterchainGasPaymaster.sol"; +import "../test/TestIsm.sol"; import {TypeCasts} from "../libs/TypeCasts.sol"; @@ -11,6 +13,8 @@ contract MockHyperlaneEnvironment { uint32 destinationDomain; mapping(uint32 => MockMailbox) public mailboxes; + mapping(uint32 => InterchainGasPaymaster) public igps; + mapping(uint32 => IInterchainSecurityModule) public isms; mapping(uint32 => InterchainQueryRouter) public queryRouters; constructor(uint32 _originDomain, uint32 _destinationDomain) { @@ -20,6 +24,15 @@ contract MockHyperlaneEnvironment { MockMailbox originMailbox = new MockMailbox(_originDomain); MockMailbox destinationMailbox = new MockMailbox(_destinationDomain); + originMailbox.addRemoteMailbox(_destinationDomain, destinationMailbox); + destinationMailbox.addRemoteMailbox(_originDomain, originMailbox); + + igps[originDomain] = new InterchainGasPaymaster(); + igps[destinationDomain] = new InterchainGasPaymaster(); + + isms[originDomain] = new TestIsm(); + isms[destinationDomain] = new TestIsm(); + mailboxes[_originDomain] = originMailbox; mailboxes[_destinationDomain] = destinationMailbox; @@ -27,14 +40,14 @@ contract MockHyperlaneEnvironment { InterchainQueryRouter destinationQueryRouter = new InterchainQueryRouter(); originQueryRouter.initialize( - address(this), address(originMailbox), - address(0) + address(igps[originDomain]), + address(isms[originDomain]) ); destinationQueryRouter.initialize( - address(this), address(destinationMailbox), - address(0) + address(igps[destinationDomain]), + address(isms[destinationDomain]) ); originQueryRouter.enrollRemoteRouter( diff --git a/solidity/contracts/test/TestSendReceiver.sol b/solidity/contracts/test/TestSendReceiver.sol index 1f51cec0b..1271619b2 100644 --- a/solidity/contracts/test/TestSendReceiver.sol +++ b/solidity/contracts/test/TestSendReceiver.sol @@ -15,12 +15,12 @@ contract TestSendReceiver is IMessageRecipient { event Handled(bytes32 blockHash); function dispatchToSelf( - IMailbox _outbox, + IMailbox _mailbox, IInterchainGasPaymaster _paymaster, uint32 _destinationDomain, bytes calldata _messageBody ) external payable { - bytes32 _messageId = _outbox.dispatch( + bytes32 _messageId = _mailbox.dispatch( _destinationDomain, address(this).addressToBytes32(), _messageBody diff --git a/solidity/lib/forge-std/.github/workflows/tests.yml b/solidity/lib/forge-std/.github/workflows/tests.yml deleted file mode 100644 index 08ab66e94..000000000 --- a/solidity/lib/forge-std/.github/workflows/tests.yml +++ /dev/null @@ -1,26 +0,0 @@ -name: Tests -on: [push, pull_request] - -jobs: - check: - name: Foundry project - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - with: - submodules: recursive - - - name: Install Foundry - uses: onbjerg/foundry-toolchain@v1 - with: - version: nightly - - - name: Install dependencies - run: forge install - - name: Run tests - run: forge test -vvv - - name: Build Test with older solc versions - run: | - forge build --contracts src/Test.sol --use solc:0.8.0 - forge build --contracts src/Test.sol --use solc:0.7.0 - forge build --contracts src/Test.sol --use solc:0.6.0 diff --git a/solidity/package.json b/solidity/package.json index ad7aa9634..8cebada95 100644 --- a/solidity/package.json +++ b/solidity/package.json @@ -47,7 +47,7 @@ "clean": "hardhat clean && rm -rf ./dist ./cache", "coverage": "hardhat coverage", "prettier": "prettier --write ./contracts ./interfaces ./test", - "test": "hardhat test" + "test": "hardhat test && forge test -vvv" }, "types": "dist/index.d.ts" } diff --git a/solidity/test/InterchainAccountRouter.t.sol b/solidity/test/InterchainAccountRouter.t.sol index 811d19673..9b3834481 100644 --- a/solidity/test/InterchainAccountRouter.t.sol +++ b/solidity/test/InterchainAccountRouter.t.sol @@ -2,17 +2,16 @@ pragma solidity ^0.8.13; import "forge-std/Test.sol"; -import "../contracts/mock/MockOutbox.sol"; -import "../contracts/mock/MockInbox.sol"; -import "../contracts/AbacusConnectionManager.sol"; +import "../contracts/mock/MockMailbox.sol"; +import "../contracts/HyperlaneConnectionClient.sol"; +import "../contracts/mock/MockHyperlaneEnvironment.sol"; import {TypeCasts} from "../contracts/libs/TypeCasts.sol"; import "../contracts/test/TestRecipient.sol"; import "../contracts/middleware/InterchainAccountRouter.sol"; import {OwnableMulticall, Call} from "../contracts/OwnableMulticall.sol"; contract InterchainAccountRouterTest is Test { - MockOutbox outbox; - MockInbox inbox; + MockHyperlaneEnvironment environment; uint32 originDomain = 1; uint32 remoteDomain = 2; @@ -20,20 +19,10 @@ contract InterchainAccountRouterTest is Test { InterchainAccountRouter originRouter; InterchainAccountRouter remoteRouter; - AbacusConnectionManager originManager; - AbacusConnectionManager remoteManager; - TestRecipient recipient; function setUp() public { - inbox = new MockInbox(); - outbox = new MockOutbox(originDomain, address(inbox)); - - originManager = new AbacusConnectionManager(); - remoteManager = new AbacusConnectionManager(); - - originManager.setOutbox(address(outbox)); - remoteManager.enrollInbox(remoteDomain, address(inbox)); + environment = new MockHyperlaneEnvironment(originDomain, remoteDomain); recipient = new TestRecipient(); @@ -41,14 +30,14 @@ contract InterchainAccountRouterTest is Test { remoteRouter = new InterchainAccountRouter(); originRouter.initialize( - address(this), - address(originManager), - address(0) + address(environment.mailboxes(originDomain)), + address(environment.igps(originDomain)), + address(environment.isms(originDomain)) ); remoteRouter.initialize( - address(this), - address(remoteManager), - address(0) + address(environment.mailboxes(remoteDomain)), + address(environment.igps(remoteDomain)), + address(environment.isms(remoteDomain)) ); originRouter.enrollRemoteRouter( @@ -68,7 +57,7 @@ contract InterchainAccountRouterTest is Test { data: abi.encodeCall(recipient.fooBar, (1, "Test")) }); originRouter.dispatch(remoteDomain, calls); - inbox.processNextPendingMessage(); + environment.processNextPendingMessage(); assertEq(recipient.lastCallMessage(), "Test"); } } diff --git a/solidity/test/LiquidityLayerRouter.t.sol b/solidity/test/LiquidityLayerRouter.t.sol index 29a52d134..c503d53c2 100644 --- a/solidity/test/LiquidityLayerRouter.t.sol +++ b/solidity/test/LiquidityLayerRouter.t.sol @@ -53,16 +53,15 @@ contract LiquidityLayerRouterTest is Test { destinationDomain ); - // TODO: set IGP? originLiquidityLayerRouter.initialize( - address(this), - address(testEnvironment.connectionManager(originDomain)), - address(0) + address(testEnvironment.mailboxes(originDomain)), + address(testEnvironment.igps(originDomain)), + address(testEnvironment.isms(originDomain)) ); destinationLiquidityLayerRouter.initialize( - address(this), - address(testEnvironment.connectionManager(destinationDomain)), - address(0) + address(testEnvironment.mailboxes(destinationDomain)), + address(testEnvironment.igps(destinationDomain)), + address(testEnvironment.isms(destinationDomain)) ); originLiquidityLayerRouter.enrollRemoteRouter( diff --git a/solidity/test/Messaging.t.sol b/solidity/test/Messaging.t.sol index 98ba282b2..b05719fed 100644 --- a/solidity/test/Messaging.t.sol +++ b/solidity/test/Messaging.t.sol @@ -2,16 +2,16 @@ pragma solidity ^0.8.13; import "forge-std/Test.sol"; -import "../contracts/mock/MockOutbox.sol"; -import "../contracts/mock/MockInbox.sol"; +import "../contracts/mock/MockMailbox.sol"; +import "../contracts/mock/MockMailbox.sol"; import "../contracts/test/TestRecipient.sol"; -import "../interfaces/IInbox.sol"; -import "../interfaces/IOutbox.sol"; +import "../interfaces/IMailbox.sol"; +import "../interfaces/IMailbox.sol"; import {TypeCasts} from "../contracts/libs/TypeCasts.sol"; contract MessagingTest is Test { - MockOutbox outbox; - MockInbox inbox; + MockMailbox originMailbox; + MockMailbox remoteMailbox; TestRecipient receiver; @@ -19,19 +19,20 @@ contract MessagingTest is Test { uint32 remoteDomain = 2; function setUp() public { - inbox = new MockInbox(); - outbox = new MockOutbox(originDomain, address(inbox)); + originMailbox = new MockMailbox(originDomain); + remoteMailbox = new MockMailbox(remoteDomain); + originMailbox.addRemoteMailbox(remoteDomain, remoteMailbox); receiver = new TestRecipient(); } function testSendMessage(string calldata _message) public { - outbox.dispatch( + originMailbox.dispatch( remoteDomain, TypeCasts.addressToBytes32(address(receiver)), bytes(_message) ); - inbox.processNextPendingMessage(); + remoteMailbox.processNextInboundMessage(); assertEq(string(receiver.lastData()), _message); } } diff --git a/typescript/sdk/src/core/TestCoreDeployer.ts b/typescript/sdk/src/core/TestCoreDeployer.ts index 61b3936ea..205528895 100644 --- a/typescript/sdk/src/core/TestCoreDeployer.ts +++ b/typescript/sdk/src/core/TestCoreDeployer.ts @@ -1,10 +1,12 @@ import { ethers } from 'ethers'; import { + MultisigIsm, TestIsm__factory, TestMailbox, TestMailbox__factory, } from '@hyperlane-xyz/core'; +import { types } from '@hyperlane-xyz/utils'; import { chainMetadata } from '../consts/chainMetadata'; import { HyperlaneCoreDeployer } from '../deploy/core/HyperlaneCoreDeployer'; @@ -51,12 +53,10 @@ export class TestCoreDeployer< super(multiProvider, configs, testCoreFactories); } - // skip proxying - async deployMailbox( + // deploy a test ISM in place of a multisig ISM + async deployMultisigIsm( chain: LocalChain, - ): Promise> { - const localDomain = chainMetadata[chain].id; - + ): Promise { const testIsm = await this.deployContractFromFactory( chain, testCoreFactories.testIsm, @@ -64,9 +64,18 @@ export class TestCoreDeployer< [], ); await testIsm.setAccept(true); + return testIsm as unknown as MultisigIsm; + } + + // skip proxying + async deployMailbox( + chain: LocalChain, + defaultIsmAddress: types.Address, + ): Promise> { + const localDomain = chainMetadata[chain].id; const mailbox = await this.deployContract(chain, 'mailbox', [localDomain]); - await mailbox.initialize(testIsm.address); + await mailbox.initialize(defaultIsmAddress); return new ProxiedContract(mailbox, { kind: ProxyKind.UpgradeBeacon, proxy: mailbox.address, diff --git a/typescript/sdk/src/deploy/middleware/LiquidityLayerRouterDeployer.ts b/typescript/sdk/src/deploy/middleware/LiquidityLayerRouterDeployer.ts index 6ac780079..c4030460b 100644 --- a/typescript/sdk/src/deploy/middleware/LiquidityLayerRouterDeployer.ts +++ b/typescript/sdk/src/deploy/middleware/LiquidityLayerRouterDeployer.ts @@ -80,7 +80,11 @@ export class LiquidityLayerDeployer< const initCalldata = LiquidityLayerRouter__factory.createInterface().encodeFunctionData( 'initialize', - [config.owner, config.mailbox, config.interchainGasPaymaster], + [ + config.mailbox, + config.interchainGasPaymaster, + config.interchainSecurityModule, + ], ); const router = await this.deployContract(chain, 'router', [], { create2Salt: this.create2salt, diff --git a/typescript/sdk/src/deploy/middleware/deploy.ts b/typescript/sdk/src/deploy/middleware/deploy.ts index 12ef74337..508b57ec2 100644 --- a/typescript/sdk/src/deploy/middleware/deploy.ts +++ b/typescript/sdk/src/deploy/middleware/deploy.ts @@ -45,7 +45,11 @@ export class InterchainAccountDeployer< const initCalldata = InterchainAccountRouter__factory.createInterface().encodeFunctionData( 'initialize', - [config.owner, config.mailbox, config.interchainGasPaymaster], + [ + config.mailbox, + config.interchainGasPaymaster, + config.interchainSecurityModule, + ], ); const router = await this.deployContract(chain, 'router', [], { create2Salt: this.create2salt + 'router', @@ -86,7 +90,11 @@ export class InterchainQueryDeployer< const initCalldata = InterchainQueryRouter__factory.createInterface().encodeFunctionData( 'initialize', - [config.owner, config.mailbox, config.interchainGasPaymaster], + [ + config.mailbox, + config.interchainGasPaymaster, + config.interchainSecurityModule, + ], ); const router = await this.deployContract(chain, 'router', [], { create2Salt: this.create2salt + 'router', diff --git a/typescript/sdk/src/router.ts b/typescript/sdk/src/router.ts index 157a8b6e2..5e6f6ce7b 100644 --- a/typescript/sdk/src/router.ts +++ b/typescript/sdk/src/router.ts @@ -23,7 +23,7 @@ export type RouterFactories = export type ConnectionClientConfig = { mailbox: types.Address; interchainGasPaymaster: types.Address; - interchainSecurityModule?: types.Address; + interchainSecurityModule: types.Address; }; export { Router } from '@hyperlane-xyz/core';