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/GasRouter.t.sol

120 lines
3.9 KiB

// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.13;
import "forge-std/Test.sol";
import "../contracts/mock/MockHyperlaneEnvironment.sol";
import "../contracts/test/TestGasRouter.sol";
contract GasRouterTest is Test {
event DestinationGasSet(uint32 indexed domain, uint256 gas);
MockHyperlaneEnvironment environment;
uint32 originDomain = 1;
uint32 remoteDomain = 2;
uint256 gasPrice; // The gas price used in IGP.quoteGasPayment
TestGasRouter originRouter;
TestGasRouter remoteRouter;
function setUp() public {
environment = new MockHyperlaneEnvironment(originDomain, remoteDomain);
// Same for origin and remote
gasPrice = environment.igps(originDomain).gasPrice();
originRouter = new TestGasRouter();
remoteRouter = new TestGasRouter();
originRouter.initialize(
address(environment.mailboxes(originDomain)),
address(environment.igps(originDomain))
);
remoteRouter.initialize(
address(environment.mailboxes(remoteDomain)),
address(environment.igps(remoteDomain))
);
originRouter.enrollRemoteRouter(
remoteDomain,
TypeCasts.addressToBytes32(address(remoteRouter))
);
remoteRouter.enrollRemoteRouter(
originDomain,
TypeCasts.addressToBytes32(address(originRouter))
);
}
function setDestinationGas(
GasRouter gasRouter,
uint32 domain,
uint256 gas
) public {
GasRouter.GasRouterConfig[]
memory gasConfigs = new GasRouter.GasRouterConfig[](1);
gasConfigs[0] = GasRouter.GasRouterConfig(domain, gas);
gasRouter.setDestinationGas(gasConfigs);
}
function testSetDestinationGas(uint256 gas) public {
vm.expectEmit(true, false, false, true, address(remoteRouter));
emit DestinationGasSet(originDomain, gas);
setDestinationGas(remoteRouter, originDomain, gas);
assertEq(remoteRouter.destinationGas(originDomain), gas);
vm.expectEmit(true, false, false, true, address(originRouter));
emit DestinationGasSet(remoteDomain, gas);
setDestinationGas(originRouter, remoteDomain, gas);
assertEq(originRouter.destinationGas(remoteDomain), gas);
}
function testQuoteGasPayment(uint256 gas) public {
vm.assume(gas > 0 && type(uint256).max / gas > gasPrice);
setDestinationGas(originRouter, remoteDomain, gas);
assertEq(originRouter.quoteGasPayment(remoteDomain), gas * gasPrice);
setDestinationGas(remoteRouter, originDomain, gas);
assertEq(remoteRouter.quoteGasPayment(originDomain), gas * gasPrice);
}
uint256 refund = 0;
bool passRefund = true;
receive() external payable {
refund = msg.value;
assert(passRefund);
}
function testDispatchWithGas(uint256 gas) public {
vm.assume(gas > 0 && type(uint256).max / gas > gasPrice);
vm.deal(address(this), gas * gasPrice);
setDestinationGas(originRouter, remoteDomain, gas);
uint256 requiredPayment = gas * gasPrice;
vm.expectRevert("insufficient interchain gas payment");
originRouter.dispatchWithGas{value: requiredPayment - 1}(
remoteDomain,
""
);
vm.deal(address(this), requiredPayment + 1);
originRouter.dispatchWithGas{value: requiredPayment + 1}(
remoteDomain,
""
);
assertEq(refund, 1);
// Reset the IGP balance to avoid a balance overflow
vm.deal(address(environment.igps(originDomain)), 0);
vm.deal(address(this), requiredPayment + 1);
passRefund = false;
vm.expectRevert("Interchain gas payment refund failed");
originRouter.dispatchWithGas{value: requiredPayment + 1}(
remoteDomain,
""
);
}
}