From ac2aed621f9b7d7c5f0bef4917957c961033511f Mon Sep 17 00:00:00 2001 From: Web3 Philosopher Date: Fri, 19 Jul 2024 13:32:47 +0100 Subject: [PATCH] Adds new networks (#21) * adds new networks * add quoteFee * remove sender from DispatchGet --- src/IDispatcher.sol | 14 ++++++------ src/IIsmpModule.sol | 51 ++++++++++++++++++++++++++++---------------- src/StateMachine.sol | 38 +++++++++++++++++++++++++-------- 3 files changed, 69 insertions(+), 34 deletions(-) diff --git a/src/IDispatcher.sol b/src/IDispatcher.sol index 5904ed5..647f59d 100644 --- a/src/IDispatcher.sol +++ b/src/IDispatcher.sol @@ -4,7 +4,7 @@ pragma solidity 0.8.17; import {StateMachineHeight} from "./IConsensusClient.sol"; import {PostRequest} from "./Message.sol"; -// An object for dispatching post requests to the IsmpDispatcher +// @notice An object for dispatching post requests to the Hyperbridge struct DispatchPost { // bytes representation of the destination state machine bytes dest; @@ -14,24 +14,23 @@ struct DispatchPost { bytes body; // timeout for this request in seconds uint64 timeout; - // the amount put up to be paid to the relayer, this is in $DAI and charged to tx.origin + // the amount put up to be paid to the relayer, + // this is charged in `IIsmpHost.feeToken` to `msg.sender` uint256 fee; // who pays for this request? address payer; } -// An object for dispatching get requests to the IsmpDispatcher +// @notice An object for dispatching get requests to the Hyperbridge struct DispatchGet { // bytes representation of the destination state machine bytes dest; // height at which to read the state machine uint64 height; - // Storage keys to read + // storage keys to read bytes[] keys; // timeout for this request in seconds uint64 timeout; - // The initiator of this request - address sender; // Hyperbridge protocol fees for processing this request. uint256 fee; } @@ -43,7 +42,8 @@ struct DispatchPostResponse { bytes response; // timeout for this response in seconds uint64 timeout; - // the amount put up to be paid to the relayer, this is in $DAI and charged to tx.origin + // the amount put up to be paid to the relayer, + // this is charged in `IIsmpHost.feeToken` to `msg.sender` uint256 fee; // who pays for this request? address payer; diff --git a/src/IIsmpModule.sol b/src/IIsmpModule.sol index e6eb5ce..1a8cc76 100644 --- a/src/IIsmpModule.sol +++ b/src/IIsmpModule.sol @@ -2,6 +2,8 @@ pragma solidity 0.8.17; import {PostRequest, PostResponse, GetResponse, GetRequest} from "./Message.sol"; +import {DispatchPost, DispatchPostResponse} from "./IDispatcher.sol"; +import {IIsmpHost} from "./IIsmpHost.sol"; struct IncomingPostRequest { // The Post request @@ -26,76 +28,89 @@ struct IncomingGetResponse { interface IIsmpModule { /** - * @dev Called by the IsmpHost to notify a module of a new request the module may choose to respond immediately, or in a later block + * @dev Called by the `IsmpHost` to notify a module of a new request the module may choose to respond immediately, or in a later block * @param incoming post request */ function onAccept(IncomingPostRequest memory incoming) external; /** - * @dev Called by the IsmpHost to notify a module of a post response to a previously sent out request + * @dev Called by the `IsmpHost` to notify a module of a post response to a previously sent out request * @param incoming post response */ function onPostResponse(IncomingPostResponse memory incoming) external; /** - * @dev Called by the IsmpHost to notify a module of a get response to a previously sent out request + * @dev Called by the `IsmpHost` to notify a module of a get response to a previously sent out request * @param incoming get response */ function onGetResponse(IncomingGetResponse memory incoming) external; /** - * @dev Called by the IsmpHost to notify a module of post requests that were previously sent but have now timed-out + * @dev Called by the `IsmpHost` to notify a module of post requests that were previously sent but have now timed-out * @param request post request */ function onPostRequestTimeout(PostRequest memory request) external; /** - * @dev Called by the IsmpHost to notify a module of post requests that were previously sent but have now timed-out + * @dev Called by the `IsmpHost` to notify a module of post requests that were previously sent but have now timed-out * @param request post request */ function onPostResponseTimeout(PostResponse memory request) external; /** - * @dev Called by the IsmpHost to notify a module of get requests that were previously sent but have now timed-out + * @dev Called by the `IsmpHost` to notify a module of get requests that were previously sent but have now timed-out * @param request get request */ function onGetTimeout(GetRequest memory request) external; } -/// Abstract contract to make implementing `IIsmpModule` easier. +// @notice Abstract contract to make implementing `IIsmpModule` easier. abstract contract BaseIsmpModule is IIsmpModule { - // Chain is not supported + // @notice Chain is not supported error UnsupportedChain(); - // Call was not expected + // @notice Call was not expected error UnexpectedCall(); - // Action is unauthorized - error UnauthorizedAction(); + // @notice Account is unauthorized + error UnauthorizedAccount(); + // @dev restricts caller to the local `IsmpHost` modifier onlyHost() { - if (msg.sender != host()) revert UnauthorizedAction(); + if (msg.sender != hostAddr()) revert UnauthorizedAccount(); _; } - function host() internal view returns (address h) { + // @dev Returns the `IsmpHost` address for the current chain. + // The `IsmpHost` is an immutable contract that will never change. + function hostAddr() internal view returns (address h) { assembly { switch chainid() // Ethereum Sepolia - case 11155111 { h := 0xbDFa473d7E483e088348e071480B624A248b2fC4 } + case 11155111 { h := 0x4175a96bd787a2C196e732a1244630650607fdC2 } // Arbitrum Sepolia - case 421614 { h := 0xC98976841a69Ce52d4D17B286A1698963E847982 } + case 421614 { h := 0xC8A9288BF705A238c3d96C76499F4A4E1d96c800 } // Optimism Sepolia - case 11155420 { h := 0x0D811D581D615AA44A36aa638825403F9b434E18 } + case 11155420 { h := 0xB9Ffd43C720A695d40C14896494c1461f3fBb8A7 } // Base Sepolia - case 84532 { h := 0x7FaBb96851517583eA7df7d6e9Dd28afc2fA38f5 } + case 84532 { h := 0xc76c16539877C0c38c18E815E449Ff4855DA11d4 } // Binance Smart Chain Testnet - case 97 { h := 0xE6bd95737DD35Fd0e5f134771A832405671f06e9 } + case 97 { h := 0x698Ea102d14dF1F9a4C3A76fE5DCEEeFcfd27f85 } } if (h == address(0)) revert UnsupportedChain(); } + // @dev returns the quoted fee for a dispatch + function quoteFee(DispatchPost memory post) internal view returns (uint256) { + return post.body.length * IIsmpHost(hostAddr()).perByteFee(); + } + + // @dev returns the quoted fee for a dispatch + function quoteFee(DispatchPostResponse memory res) internal view returns (uint256) { + return res.response.length * IIsmpHost(hostAddr()).perByteFee(); + } + function onAccept(IncomingPostRequest calldata) external virtual onlyHost { revert UnexpectedCall(); } diff --git a/src/StateMachine.sol b/src/StateMachine.sol index 487e295..9c37bc9 100644 --- a/src/StateMachine.sol +++ b/src/StateMachine.sol @@ -4,46 +4,66 @@ pragma solidity 0.8.17; import {Strings} from "openzeppelin/utils/Strings.sol"; library StateMachine { - /// The identifier for the relay chain. + /// @notice The identifier for the relay chain. uint256 public constant RELAY_CHAIN = 0; - // Address a state machine on the polkadot relay chain + // @notice Address a state machine on the polkadot relay chain function polkadot(uint256 id) internal pure returns (bytes memory) { return bytes(string.concat("POLKADOT-", Strings.toString(id))); } - // Address a state machine on the kusama relay chain + // @notice Address a state machine on the kusama relay chain function kusama(uint256 id) internal pure returns (bytes memory) { return bytes(string.concat("KUSAMA-", Strings.toString(id))); } - // Address the ethereum "execution layer" + // @notice Address the ethereum "execution layer" function ethereum() internal pure returns (bytes memory) { return bytes("ETHE"); } - // Address the Arbitrum state machine + // @notice Address the Arbitrum state machine function arbitrum() internal pure returns (bytes memory) { return bytes("ARBI"); } - // Address the Optimism state machine + // @notice Address the Optimism state machine function optimism() internal pure returns (bytes memory) { return bytes("OPTI"); } - // Address the Base state machine + // @notice Address the Base state machine function base() internal pure returns (bytes memory) { return bytes("BASE"); } - // Address the Polygon POS state machine + // @notice Address the Polygon POS state machine function polygon() internal pure returns (bytes memory) { return bytes("POLY"); } - // Address the Binance smart chain state machine + // @notice Address the Binance smart chain state machine function bsc() internal pure returns (bytes memory) { return bytes("BSC"); } + + // @notice Address the Blast state machine + function blast() internal pure returns (bytes memory) { + return bytes("BLST"); + } + + // @notice Address the Mantle machine + function mantle() internal pure returns (bytes memory) { + return bytes("MNTL"); + } + + // @notice Address the Manta machine + function manta() internal pure returns (bytes memory) { + return bytes("MNTA"); + } + + // @notice Address the Build on Bitcoin machine + function bob() internal pure returns (bytes memory) { + return bytes("BOB"); + } }