Unify overheardIgp and igp (#2766)
### Description - v3 uses the OverheadIgp as the default igp and removing an "inner" igp makes it simpler to deploy and interact with - `InterchainGasPaymaster` has a `setDestinationGasConfigs` which sets it the overhead and the oracle. - the gas overhead gets added it directly to the specified gasAmount. - Downstream changes to the `typescript/*` module in the igpConfig, checke, deployer, etc ### Drive-by changes None ### Related issues - precursor to https://github.com/hyperlane-xyz/issues/issues/623 - related to https://github.com/hyperlane-xyz/issues/issues/637 - missing changes to governor https://github.com/hyperlane-xyz/issues/issues/641 ### Backward compatibility Yes ### Testing Fuzzpull/2774/head
parent
f0a45bd6b1
commit
a60ec18237
@ -1,134 +0,0 @@ |
||||
// SPDX-License-Identifier: MIT OR Apache-2.0 |
||||
pragma solidity >=0.8.0; |
||||
|
||||
// ============ Internal Imports ============ |
||||
import {IInterchainGasPaymaster} from "../../interfaces/IInterchainGasPaymaster.sol"; |
||||
|
||||
// ============ External Imports ============ |
||||
import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol"; |
||||
|
||||
/** |
||||
* @notice An IGP that adds configured gas overheads to gas amounts and forwards |
||||
* calls to an "inner" IGP. |
||||
* @dev The intended use of this contract is to store overhead gas amounts for destination |
||||
* domains, e.g. Mailbox and/or ISM gas usage, such that users of this IGP are only required |
||||
* to specify the gas amount used by their own applications. |
||||
*/ |
||||
contract OverheadIgp is IInterchainGasPaymaster, Ownable { |
||||
// ============ Constants ============ |
||||
|
||||
/// @notice The IGP that is called when paying for or quoting gas |
||||
/// after applying overhead gas amounts. |
||||
IInterchainGasPaymaster public immutable innerIgp; |
||||
|
||||
// ============ Public Storage ============ |
||||
|
||||
/// @notice Destination domain => overhead gas amount on that domain. |
||||
mapping(uint32 => uint256) public destinationGasOverhead; |
||||
|
||||
// ============ Events ============ |
||||
|
||||
/** |
||||
* @notice Emitted when an entry in the destinationGasOverhead mapping is set. |
||||
* @param domain The destination domain. |
||||
* @param gasOverhead The gas overhead amount on that domain. |
||||
*/ |
||||
event DestinationGasOverheadSet(uint32 indexed domain, uint256 gasOverhead); |
||||
|
||||
struct DomainConfig { |
||||
uint32 domain; |
||||
uint256 gasOverhead; |
||||
} |
||||
|
||||
// ============ Constructor ============ |
||||
|
||||
constructor(address _innerIgp) { |
||||
innerIgp = IInterchainGasPaymaster(_innerIgp); |
||||
} |
||||
|
||||
// ============ External Functions ============ |
||||
|
||||
/** |
||||
* @notice Adds the stored destinationGasOverhead to the _gasAmount and forwards the |
||||
* call to the innerIgp's `payForGas` function. |
||||
* @param _messageId The ID of the message to pay for. |
||||
* @param _destinationDomain The domain of the message's destination chain. |
||||
* @param _gasAmount The amount of destination gas to pay for. This should not |
||||
* consider any gas that is accounted for in the stored destinationGasOverhead. |
||||
* @param _refundAddress The address to refund any overpayment to. |
||||
*/ |
||||
function payForGas( |
||||
bytes32 _messageId, |
||||
uint32 _destinationDomain, |
||||
uint256 _gasAmount, |
||||
address _refundAddress |
||||
) external payable { |
||||
innerIgp.payForGas{value: msg.value}( |
||||
_messageId, |
||||
_destinationDomain, |
||||
destinationGasAmount(_destinationDomain, _gasAmount), |
||||
_refundAddress |
||||
); |
||||
} |
||||
|
||||
/** |
||||
* @notice Sets destination gas overheads for multiple domains. |
||||
* @dev Only callable by the owner. |
||||
* @param configs A list of destination domains and gas overheads. |
||||
*/ |
||||
function setDestinationGasOverheads(DomainConfig[] calldata configs) |
||||
external |
||||
onlyOwner |
||||
{ |
||||
for (uint256 i; i < configs.length; i++) { |
||||
_setDestinationGasOverhead(configs[i]); |
||||
} |
||||
} |
||||
|
||||
// ============ Public Functions ============ |
||||
|
||||
/** |
||||
* @notice Adds the stored destinationGasOverhead to the _gasAmount and forwards the |
||||
* call to the innerIgp's `quoteGasPayment` function. |
||||
* @param _destinationDomain The domain of the message's destination chain. |
||||
* @param _gasAmount The amount of destination gas to pay for. This should not |
||||
* consider any gas that is accounted for in the stored destinationGasOverhead. |
||||
* @return The amount of native tokens required to pay for interchain gas. |
||||
*/ |
||||
function quoteGasPayment(uint32 _destinationDomain, uint256 _gasAmount) |
||||
public |
||||
view |
||||
returns (uint256) |
||||
{ |
||||
return |
||||
innerIgp.quoteGasPayment( |
||||
_destinationDomain, |
||||
destinationGasAmount(_destinationDomain, _gasAmount) |
||||
); |
||||
} |
||||
|
||||
/** |
||||
* @notice Returns the stored destinationGasOverhead added to the _gasAmount. |
||||
* @dev If there is no stored destinationGasOverhead, 0 is used. |
||||
* @param _destinationDomain The domain of the message's destination chain. |
||||
* @param _gasAmount The amount of destination gas to pay for. This should not |
||||
* consider any gas that is accounted for in the stored destinationGasOverhead. |
||||
* @return The stored destinationGasOverhead added to the _gasAmount. |
||||
*/ |
||||
function destinationGasAmount(uint32 _destinationDomain, uint256 _gasAmount) |
||||
public |
||||
view |
||||
returns (uint256) |
||||
{ |
||||
return destinationGasOverhead[_destinationDomain] + _gasAmount; |
||||
} |
||||
|
||||
/** |
||||
* @notice Sets the destination gas overhead for a single domain. |
||||
* @param config The destination domain and gas overhead. |
||||
*/ |
||||
function _setDestinationGasOverhead(DomainConfig calldata config) internal { |
||||
destinationGasOverhead[config.domain] = config.gasOverhead; |
||||
emit DestinationGasOverheadSet(config.domain, config.gasOverhead); |
||||
} |
||||
} |
@ -1,146 +0,0 @@ |
||||
// SPDX-License-Identifier: Apache-2.0 |
||||
pragma solidity ^0.8.13; |
||||
|
||||
import {Test} from "forge-std/Test.sol"; |
||||
import {OverheadIgp} from "../../contracts/hooks/igp/OverheadIgp.sol"; |
||||
import {TestInterchainGasPaymaster} from "../../contracts/test/TestInterchainGasPaymaster.sol"; |
||||
|
||||
contract OverheadIgpTest is Test { |
||||
OverheadIgp igp; |
||||
|
||||
TestInterchainGasPaymaster innerIgp; |
||||
|
||||
bytes32 constant testMessageId = |
||||
bytes32( |
||||
0xf00000000000000000000000000000000000000000000000000000000000000f |
||||
); |
||||
uint32 constant testDestinationDomain = 1234; |
||||
uint256 constant testGasOverhead = 123000; |
||||
uint256 constant testGasAmount = 50000; |
||||
|
||||
address constant nonOwner = 0xCAfEcAfeCAfECaFeCaFecaFecaFECafECafeCaFe; |
||||
|
||||
event InnerIgpSet(address innerIgp); |
||||
event DestinationGasOverheadSet(uint32 indexed domain, uint256 gasOverhead); |
||||
|
||||
function setUp() public { |
||||
innerIgp = new TestInterchainGasPaymaster(); |
||||
igp = new OverheadIgp(address(innerIgp)); |
||||
} |
||||
|
||||
function testInnerIgpSet() public { |
||||
assertEq(address(igp.innerIgp()), address(innerIgp)); |
||||
} |
||||
|
||||
function testPayForGas() public { |
||||
setTestDestinationGasOverhead(); |
||||
|
||||
uint256 testPayment = 123456789; |
||||
|
||||
vm.expectCall( |
||||
address(innerIgp), |
||||
testPayment, |
||||
abi.encodeCall( |
||||
innerIgp.payForGas, |
||||
( |
||||
testMessageId, |
||||
testDestinationDomain, |
||||
testGasOverhead + testGasAmount, |
||||
msg.sender |
||||
) |
||||
) |
||||
); |
||||
|
||||
igp.payForGas{value: testPayment}( |
||||
testMessageId, |
||||
testDestinationDomain, |
||||
testGasAmount, |
||||
msg.sender |
||||
); |
||||
} |
||||
|
||||
function testQuoteGasPayment() public { |
||||
setTestDestinationGasOverhead(); |
||||
|
||||
vm.expectCall( |
||||
address(innerIgp), |
||||
abi.encodeCall( |
||||
innerIgp.quoteGasPayment, |
||||
(testDestinationDomain, testGasOverhead + testGasAmount) |
||||
) |
||||
); |
||||
|
||||
igp.quoteGasPayment(testDestinationDomain, testGasAmount); |
||||
} |
||||
|
||||
function testDestinationGasAmount() public { |
||||
setTestDestinationGasOverhead(); |
||||
|
||||
assertEq( |
||||
igp.destinationGasAmount(testDestinationDomain, testGasAmount), |
||||
testGasOverhead + testGasAmount |
||||
); |
||||
} |
||||
|
||||
// Test that it doesn't revert, and just doesn't add any value to the |
||||
// provided gas amount |
||||
function testDestinationGasAmountWhenOverheadNotSet() public { |
||||
assertEq( |
||||
igp.destinationGasAmount(testDestinationDomain, testGasAmount), |
||||
testGasAmount |
||||
); |
||||
} |
||||
|
||||
function testSetDestinationGasAmounts() public { |
||||
OverheadIgp.DomainConfig[] |
||||
memory configs = new OverheadIgp.DomainConfig[](2); |
||||
configs[0] = OverheadIgp.DomainConfig( |
||||
testDestinationDomain, |
||||
testGasOverhead |
||||
); |
||||
configs[1] = OverheadIgp.DomainConfig(4321, 432100); |
||||
|
||||
// Topic 0 = event signature |
||||
// Topic 1 = indexed domain |
||||
// Topic 2 = not set |
||||
// Data = gas amount |
||||
vm.expectEmit(true, true, false, true); |
||||
emit DestinationGasOverheadSet( |
||||
configs[0].domain, |
||||
configs[0].gasOverhead |
||||
); |
||||
vm.expectEmit(true, true, false, true); |
||||
emit DestinationGasOverheadSet( |
||||
configs[1].domain, |
||||
configs[1].gasOverhead |
||||
); |
||||
|
||||
igp.setDestinationGasOverheads(configs); |
||||
} |
||||
|
||||
function testSetDestinationGasAmountsNotOwner() public { |
||||
OverheadIgp.DomainConfig[] |
||||
memory configs = new OverheadIgp.DomainConfig[](2); |
||||
configs[0] = OverheadIgp.DomainConfig( |
||||
testDestinationDomain, |
||||
testGasOverhead |
||||
); |
||||
configs[1] = OverheadIgp.DomainConfig(4321, 432100); |
||||
|
||||
vm.expectRevert("Ownable: caller is not the owner"); |
||||
vm.prank(nonOwner); |
||||
igp.setDestinationGasOverheads(configs); |
||||
} |
||||
|
||||
// ============ Helper Functions ============ |
||||
|
||||
function setTestDestinationGasOverhead() internal { |
||||
OverheadIgp.DomainConfig[] |
||||
memory configs = new OverheadIgp.DomainConfig[](1); |
||||
configs[0] = OverheadIgp.DomainConfig( |
||||
testDestinationDomain, |
||||
testGasOverhead |
||||
); |
||||
igp.setDestinationGasOverheads(configs); |
||||
} |
||||
} |
Loading…
Reference in new issue