The home for Hyperlane core contracts, sdk packages, and other infrastructure
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
hyperlane-monorepo/solidity/test/InterchainAccountRouter.t.sol

133 lines
4.1 KiB

// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.13;
import "forge-std/Test.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} from "../contracts/OwnableMulticall.sol";
contract InterchainAccountRouterTest is Test {
// TODO: dedupe
event InterchainAccountCreated(
uint32 indexed origin,
address sender,
address account
);
MockHyperlaneEnvironment environment;
uint32 originDomain = 1;
uint32 remoteDomain = 2;
InterchainAccountRouter originRouter;
InterchainAccountRouter remoteRouter;
TestRecipient recipient;
address ica;
OwnableMulticall ownable;
function setUp() public {
environment = new MockHyperlaneEnvironment(originDomain, remoteDomain);
recipient = new TestRecipient();
originRouter = new InterchainAccountRouter();
remoteRouter = new InterchainAccountRouter();
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))
);
ica = remoteRouter.getInterchainAccount(originDomain, address(this));
ownable = new OwnableMulticall();
}
function testCannotSetOwner(address newOwner) public {
vm.assume(newOwner != address(0x0));
originRouter.dispatch(
remoteDomain,
address(ownable),
abi.encodeWithSelector(ownable.transferOwnership.selector, newOwner)
);
vm.expectRevert(bytes("Ownable: caller is not the owner"));
environment.processNextPendingMessage();
}
function testSetOwner(address newOwner) public {
vm.assume(newOwner != address(0x0));
ownable.transferOwnership(ica);
originRouter.dispatch(
remoteDomain,
address(ownable),
abi.encodeWithSelector(ownable.transferOwnership.selector, newOwner)
);
vm.expectEmit(true, false, false, true, address(remoteRouter));
emit InterchainAccountCreated(originDomain, address(this), ica);
environment.processNextPendingMessage();
assertEq(ownable.owner(), newOwner);
}
function testCannotSetOwnerTwice(address newOwner) public {
vm.assume(newOwner != address(0x0) && newOwner != ica);
ownable.transferOwnership(ica);
CallLib.Call memory transferOwner = CallLib.Call({
to: address(ownable),
data: abi.encodeWithSelector(
ownable.transferOwnership.selector,
newOwner
)
});
CallLib.Call[] memory calls = new CallLib.Call[](2);
calls[0] = transferOwner;
calls[1] = transferOwner;
originRouter.dispatch(remoteDomain, calls);
vm.expectRevert(bytes("Ownable: caller is not the owner"));
environment.processNextPendingMessage();
}
function testOwner() public {
OwnableMulticall remoteIca = remoteRouter.getDeployedInterchainAccount(
originDomain,
address(this)
);
assertEq(remoteIca.owner(), address(remoteRouter));
OwnableMulticall localIca = originRouter.getDeployedInterchainAccount(
remoteDomain,
address(this)
);
assertEq(localIca.owner(), address(originRouter));
}
}