// SPDX-License-Identifier: Apache-2.0 pragma solidity ^0.8.13; import "forge-std/Test.sol"; import {InterchainQueryRouter} from "../contracts/middleware/InterchainQueryRouter.sol"; import {IInterchainQueryRouter} from "../interfaces/IInterchainQueryRouter.sol"; import {MockHyperlaneEnvironment} from "../contracts/mock/MockHyperlaneEnvironment.sol"; import {MockToken} from "../contracts/mock/MockToken.sol"; import {TypeCasts} from "../contracts/libs/TypeCasts.sol"; import "../contracts/test/TestRecipient.sol"; import {OwnableMulticall, Call} from "../contracts/OwnableMulticall.sol"; contract InterchainQueryRouterTest is Test { // TODO: dedupe event QueryDispatched( uint32 indexed destinationDomain, address indexed sender ); event QueryReturned(uint32 indexed originDomain, address indexed sender); event QueryResolved( uint32 indexed destinationDomain, address indexed sender ); MockHyperlaneEnvironment environment; InterchainQueryRouter originRouter; InterchainQueryRouter remoteRouter; TestRecipient recipient; uint32 originDomain; uint32 remoteDomain; address addressResult; uint256 uint256Result; function setUp() public { originDomain = 123; remoteDomain = 321; environment = new MockHyperlaneEnvironment(originDomain, remoteDomain); recipient = new TestRecipient(); originRouter = new InterchainQueryRouter(); remoteRouter = new InterchainQueryRouter(); address owner = address(this); originRouter.initialize( address(environment.mailboxes(originDomain)), address(environment.igps(originDomain)), address(environment.isms(originDomain)), owner ); remoteRouter.initialize( address(environment.mailboxes(remoteDomain)), address(environment.igps(remoteDomain)), address(environment.isms(remoteDomain)), owner ); originRouter.enrollRemoteRouter( remoteDomain, TypeCasts.addressToBytes32(address(remoteRouter)) ); remoteRouter.enrollRemoteRouter( originDomain, TypeCasts.addressToBytes32(address(originRouter)) ); } function queryHelper( address target, bytes memory call, bytes memory callback ) public { vm.expectEmit(true, true, false, true, address(originRouter)); emit QueryDispatched(remoteDomain, address(this)); originRouter.query(remoteDomain, address(target), call, callback); vm.expectEmit(true, true, false, true, address(remoteRouter)); emit QueryReturned(originDomain, address(this)); environment.processNextPendingMessage(); vm.expectEmit(true, true, false, true, address(originRouter)); emit QueryResolved(remoteDomain, address(this)); environment.processNextPendingMessageFromDestination(); } function receiveAddress(address _result) external { addressResult = _result; } function testQueryAddress(address owner) public { vm.assume(owner != address(0x0)); // Deploy a random ownable contract OwnableMulticall ownable = new OwnableMulticall(); // Set the routers owner ownable.transferOwnership(owner); queryHelper( address(ownable), abi.encodePacked(ownable.owner.selector), abi.encodePacked(this.receiveAddress.selector) ); assertEq(addressResult, owner); } function receiveUint256(uint256 _result) external { uint256Result = _result; } function testQueryUint256(uint256 balance) public { vm.assume(balance > 0); MockToken token = new MockToken(); token.mint(address(this), balance); queryHelper( address(token), abi.encodeWithSelector(token.balanceOf.selector, address(this)), abi.encodePacked(this.receiveUint256.selector) ); assertEq(uint256Result, balance); } }