v3 Router SDK changes (#2752)
### Description - Reorganize solidity directory structure for clarity - Updates router apps (token and helloworld) with changes from https://github.com/hyperlane-xyz/hyperlane-monorepo/pull/2749 ### Drive-by changes - Merges the hyperlane-token package to solidity and sdk ### Backward compatibility No (removed token package) ### Testing - Unit Tests - Instrumented coveragemerkle-vs-mapping
parent
fcfecdf250
commit
1ecfc46ce2
@ -0,0 +1,31 @@ |
|||||||
|
comment: |
||||||
|
layout: "header, diff, flags, components" # show component info in the PR comment |
||||||
|
|
||||||
|
component_management: |
||||||
|
default_rules: # default rules that will be inherited by all components |
||||||
|
statuses: |
||||||
|
- type: project # in this case every component that doens't have a status defined will have a project type one |
||||||
|
target: auto |
||||||
|
branches: |
||||||
|
- "!main" |
||||||
|
individual_components: |
||||||
|
- component_id: module_core |
||||||
|
name: core |
||||||
|
paths: |
||||||
|
- solidity/contracts/Mailbox.sol |
||||||
|
- component_id: module_hooks |
||||||
|
name: hooks |
||||||
|
paths: |
||||||
|
- solidity/contracts/hooks/** |
||||||
|
- component_id: module_isms |
||||||
|
name: isms |
||||||
|
paths: |
||||||
|
- solidity/contracts/isms/** |
||||||
|
- component_id: module_token |
||||||
|
name: token |
||||||
|
paths: |
||||||
|
- solidity/contracts/token/** |
||||||
|
- component_id: module_middlewares |
||||||
|
name: middlewares |
||||||
|
paths: |
||||||
|
- solidity/contracts/middleware/** |
@ -1,50 +0,0 @@ |
|||||||
// SPDX-License-Identifier: MIT OR Apache-2.0 |
|
||||||
pragma solidity >=0.6.11; |
|
||||||
|
|
||||||
import {OwnableMulticall} from "../../OwnableMulticall.sol"; |
|
||||||
import {CallLib} from "../../libs/Call.sol"; |
|
||||||
|
|
||||||
interface IInterchainAccountRouter { |
|
||||||
function callRemote( |
|
||||||
uint32 _destination, |
|
||||||
address _to, |
|
||||||
uint256 _value, |
|
||||||
bytes calldata _data |
|
||||||
) external returns (bytes32); |
|
||||||
|
|
||||||
function callRemote(uint32 _destination, CallLib.Call[] calldata calls) |
|
||||||
external |
|
||||||
returns (bytes32); |
|
||||||
|
|
||||||
function callRemoteWithOverrides( |
|
||||||
uint32 _destination, |
|
||||||
bytes32 _router, |
|
||||||
bytes32 _ism, |
|
||||||
CallLib.Call[] calldata calls |
|
||||||
) external returns (bytes32); |
|
||||||
|
|
||||||
function getLocalInterchainAccount( |
|
||||||
uint32 _origin, |
|
||||||
bytes32 _router, |
|
||||||
bytes32 _owner, |
|
||||||
address _ism |
|
||||||
) external view returns (OwnableMulticall); |
|
||||||
|
|
||||||
function getLocalInterchainAccount( |
|
||||||
uint32 _origin, |
|
||||||
address _router, |
|
||||||
address _owner, |
|
||||||
address _ism |
|
||||||
) external view returns (OwnableMulticall); |
|
||||||
|
|
||||||
function getRemoteInterchainAccount( |
|
||||||
address _router, |
|
||||||
address _owner, |
|
||||||
address _ism |
|
||||||
) external view returns (address); |
|
||||||
|
|
||||||
function getRemoteInterchainAccount(uint32 _destination, address _owner) |
|
||||||
external |
|
||||||
view |
|
||||||
returns (address); |
|
||||||
} |
|
@ -1,18 +0,0 @@ |
|||||||
// SPDX-License-Identifier: MIT OR Apache-2.0 |
|
||||||
pragma solidity >=0.6.11; |
|
||||||
|
|
||||||
import {CallLib} from "../../libs/Call.sol"; |
|
||||||
|
|
||||||
interface IInterchainQueryRouter { |
|
||||||
function query( |
|
||||||
uint32 _destination, |
|
||||||
address _to, |
|
||||||
bytes memory _data, |
|
||||||
bytes memory _callback |
|
||||||
) external returns (bytes32); |
|
||||||
|
|
||||||
function query( |
|
||||||
uint32 _destination, |
|
||||||
CallLib.StaticCallWithCallback[] calldata calls |
|
||||||
) external returns (bytes32); |
|
||||||
} |
|
@ -1,57 +0,0 @@ |
|||||||
// SPDX-License-Identifier: MIT |
|
||||||
// OpenZeppelin Contracts (last updated v4.6.0) (crosschain/CrossChainEnabled.sol) |
|
||||||
|
|
||||||
pragma solidity ^0.8.4; |
|
||||||
|
|
||||||
import "./errors.sol"; |
|
||||||
|
|
||||||
/** |
|
||||||
* @author OpenZeppelin |
|
||||||
* @dev LibOptimism was removed from the OpenZeppelin Contracts library as of v4.7.0 |
|
||||||
* @dev Provides information for building cross-chain aware contracts. This |
|
||||||
* abstract contract provides accessors and modifiers to control the execution |
|
||||||
* flow when receiving cross-chain messages. |
|
||||||
* |
|
||||||
* Actual implementations of cross-chain aware contracts, which are based on |
|
||||||
* this abstraction, will have to inherit from a bridge-specific |
|
||||||
* specialization. Such specializations are provided under |
|
||||||
* `crosschain/<chain>/CrossChainEnabled<chain>.sol`. |
|
||||||
* |
|
||||||
* _Available since v4.6._ |
|
||||||
*/ |
|
||||||
abstract contract CrossChainEnabled { |
|
||||||
/** |
|
||||||
* @dev Throws if the current function call is not the result of a |
|
||||||
* cross-chain execution. |
|
||||||
*/ |
|
||||||
modifier onlyCrossChain() { |
|
||||||
if (!_isCrossChain()) revert NotCrossChainCall(); |
|
||||||
_; |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* @dev Throws if the current function call is not the result of a |
|
||||||
* cross-chain execution initiated by `account`. |
|
||||||
*/ |
|
||||||
modifier onlyCrossChainSender(address expected) { |
|
||||||
address actual = _crossChainSender(); |
|
||||||
if (expected != actual) |
|
||||||
revert InvalidCrossChainSender(actual, expected); |
|
||||||
_; |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* @dev Returns whether the current function call is the result of a |
|
||||||
* cross-chain message. |
|
||||||
*/ |
|
||||||
function _isCrossChain() internal view virtual returns (bool); |
|
||||||
|
|
||||||
/** |
|
||||||
* @dev Returns the address of the sender of the cross-chain message that |
|
||||||
* triggered the current function call. |
|
||||||
* |
|
||||||
* IMPORTANT: Should revert with `NotCrossChainCall` if the current function |
|
||||||
* call is not the result of a cross-chain message. |
|
||||||
*/ |
|
||||||
function _crossChainSender() internal view virtual returns (address); |
|
||||||
} |
|
@ -1,7 +0,0 @@ |
|||||||
// SPDX-License-Identifier: MIT |
|
||||||
// OpenZeppelin Contracts (last updated v4.6.0) (crosschain/errors.sol) |
|
||||||
|
|
||||||
pragma solidity ^0.8.4; |
|
||||||
|
|
||||||
error NotCrossChainCall(); |
|
||||||
error InvalidCrossChainSender(address actual, address expected); |
|
@ -1,50 +0,0 @@ |
|||||||
// SPDX-License-Identifier: MIT |
|
||||||
// OpenZeppelin Contracts (last updated v4.7.0) (crosschain/optimism/CrossChainEnabledOptimism.sol) |
|
||||||
|
|
||||||
pragma solidity ^0.8.4; |
|
||||||
|
|
||||||
import {CrossChainEnabled} from "../CrossChainEnabled.sol"; |
|
||||||
import {LibOptimism} from "./LibOptimism.sol"; |
|
||||||
|
|
||||||
/** |
|
||||||
* @author OpenZeppelin |
|
||||||
* @dev CrossChainEnabledOptimism was removed from the OpenZeppelin Contracts library as of v4.7.0 |
|
||||||
* @dev https://www.optimism.io/[Optimism] specialization or the |
|
||||||
* {CrossChainEnabled} abstraction. |
|
||||||
* |
|
||||||
* The messenger (`CrossDomainMessenger`) contract is provided and maintained by |
|
||||||
* the optimism team. You can find the address of this contract on mainnet and |
|
||||||
* kovan in the https://github.com/ethereum-optimism/optimism/tree/develop/packages/contracts/deployments[deployments section of Optimism monorepo]. |
|
||||||
* |
|
||||||
* _Available since v4.6._ |
|
||||||
*/ |
|
||||||
abstract contract CrossChainEnabledOptimism is CrossChainEnabled { |
|
||||||
/// @custom:oz-upgrades-unsafe-allow state-variable-immutable |
|
||||||
address private immutable _messenger; |
|
||||||
|
|
||||||
/// @custom:oz-upgrades-unsafe-allow constructor |
|
||||||
constructor(address messenger) { |
|
||||||
_messenger = messenger; |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* @dev see {CrossChainEnabled-_isCrossChain} |
|
||||||
*/ |
|
||||||
function _isCrossChain() internal view virtual override returns (bool) { |
|
||||||
return LibOptimism.isCrossChain(_messenger); |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* @dev see {CrossChainEnabled-_crossChainSender} |
|
||||||
*/ |
|
||||||
function _crossChainSender() |
|
||||||
internal |
|
||||||
view |
|
||||||
virtual |
|
||||||
override |
|
||||||
onlyCrossChain |
|
||||||
returns (address) |
|
||||||
{ |
|
||||||
return LibOptimism.crossChainSender(_messenger); |
|
||||||
} |
|
||||||
} |
|
@ -1,40 +0,0 @@ |
|||||||
// SPDX-License-Identifier: MIT |
|
||||||
// OpenZeppelin Contracts (last updated v4.7.0) (crosschain/optimism/LibOptimism.sol) |
|
||||||
|
|
||||||
pragma solidity ^0.8.4; |
|
||||||
|
|
||||||
import {ICrossDomainMessenger} from "../../../../interfaces/optimism/ICrossDomainMessenger.sol"; |
|
||||||
import {NotCrossChainCall} from "../errors.sol"; |
|
||||||
|
|
||||||
/** |
|
||||||
* @dev Primitives for cross-chain aware contracts for https://www.optimism.io/[Optimism]. |
|
||||||
* See the https://community.optimism.io/docs/developers/bridge/messaging/#accessing-msg-sender[documentation] |
|
||||||
* for the functionality used here. |
|
||||||
*/ |
|
||||||
library LibOptimism { |
|
||||||
/** |
|
||||||
* @dev Returns whether the current function call is the result of a |
|
||||||
* cross-chain message relayed by `messenger`. |
|
||||||
*/ |
|
||||||
function isCrossChain(address messenger) internal view returns (bool) { |
|
||||||
return msg.sender == messenger; |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* @dev Returns the address of the sender that triggered the current |
|
||||||
* cross-chain message through `messenger`. |
|
||||||
* |
|
||||||
* NOTE: {isCrossChain} should be checked before trying to recover the |
|
||||||
* sender, as it will revert with `NotCrossChainCall` if the current |
|
||||||
* function call is not the result of a cross-chain message. |
|
||||||
*/ |
|
||||||
function crossChainSender(address messenger) |
|
||||||
internal |
|
||||||
view |
|
||||||
returns (address) |
|
||||||
{ |
|
||||||
if (!isCrossChain(messenger)) revert NotCrossChainCall(); |
|
||||||
|
|
||||||
return ICrossDomainMessenger(messenger).xDomainMessageSender(); |
|
||||||
} |
|
||||||
} |
|
@ -1,35 +0,0 @@ |
|||||||
// SPDX-License-Identifier: MIT OR Apache-2.0 |
|
||||||
pragma solidity >=0.8.0; |
|
||||||
// ============ Internal Imports ============ |
|
||||||
import {TypeCasts} from "./TypeCasts.sol"; |
|
||||||
// ============ External Imports ============ |
|
||||||
import {ECDSA} from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; |
|
||||||
|
|
||||||
library ValidatorAnnouncements { |
|
||||||
using TypeCasts for address; |
|
||||||
|
|
||||||
/** |
|
||||||
* @notice Returns the digest validators are expected to sign when signing announcements. |
|
||||||
* @param _mailbox Address of the mailbox being validated |
|
||||||
* @param _localDomain Domain of chain on which the contract is deployed |
|
||||||
* @param _storageLocation Storage location string. |
|
||||||
* @return The digest of the announcement. |
|
||||||
*/ |
|
||||||
function getAnnouncementDigest( |
|
||||||
address _mailbox, |
|
||||||
uint32 _localDomain, |
|
||||||
string memory _storageLocation |
|
||||||
) internal pure returns (bytes32) { |
|
||||||
bytes32 _domainHash = keccak256( |
|
||||||
abi.encodePacked( |
|
||||||
_localDomain, |
|
||||||
_mailbox.addressToBytes32(), |
|
||||||
"HYPERLANE_ANNOUNCEMENT" |
|
||||||
) |
|
||||||
); |
|
||||||
return |
|
||||||
ECDSA.toEthSignedMessageHash( |
|
||||||
keccak256(abi.encodePacked(_domainHash, _storageLocation)) |
|
||||||
); |
|
||||||
} |
|
||||||
} |
|
@ -1,8 +1,8 @@ |
|||||||
// SPDX-License-Identifier: MIT OR Apache-2.0 |
// SPDX-License-Identifier: MIT OR Apache-2.0 |
||||||
pragma solidity >=0.8.0; |
pragma solidity >=0.8.0; |
||||||
|
|
||||||
import {CallLib} from "../Call.sol"; |
import {CallLib} from "./Call.sol"; |
||||||
import {TypeCasts} from "../TypeCasts.sol"; |
import {TypeCasts} from "../../libs/TypeCasts.sol"; |
||||||
|
|
||||||
/** |
/** |
||||||
* Format of message: |
* Format of message: |
@ -1,7 +1,7 @@ |
|||||||
// SPDX-License-Identifier: Apache-2.0 |
// SPDX-License-Identifier: Apache-2.0 |
||||||
pragma solidity ^0.8.13; |
pragma solidity ^0.8.13; |
||||||
|
|
||||||
import {CallLib} from "../Call.sol"; |
import {CallLib} from "./Call.sol"; |
||||||
|
|
||||||
/** |
/** |
||||||
* Format of message: |
* Format of message: |
@ -1,18 +1,18 @@ |
|||||||
// SPDX-License-Identifier: MIT OR Apache-2.0 |
// SPDX-License-Identifier: MIT OR Apache-2.0 |
||||||
pragma solidity >=0.6.11; |
pragma solidity >=0.6.11; |
||||||
|
|
||||||
import "./TestRouter.sol"; |
import "../client/GasRouter.sol"; |
||||||
import "../GasRouter.sol"; |
|
||||||
|
|
||||||
contract TestGasRouter is TestRouter, GasRouter { |
contract TestGasRouter is GasRouter { |
||||||
constructor(address _mailbox) TestRouter(_mailbox) {} |
constructor(address _mailbox) GasRouter(_mailbox) {} |
||||||
|
|
||||||
function _metadata(uint32 _destination) |
function dispatch(uint32 _destination, bytes memory _msg) external payable { |
||||||
internal |
_dispatch(_destination, _msg); |
||||||
view |
|
||||||
override(GasRouter, MailboxClient) |
|
||||||
returns (bytes memory) |
|
||||||
{ |
|
||||||
return GasRouter._metadata(_destination); |
|
||||||
} |
} |
||||||
|
|
||||||
|
function _handle( |
||||||
|
uint32, |
||||||
|
bytes32, |
||||||
|
bytes calldata |
||||||
|
) internal pure override {} |
||||||
} |
} |
||||||
|
@ -1,16 +0,0 @@ |
|||||||
// SPDX-License-Identifier: MIT OR Apache-2.0 |
|
||||||
pragma solidity >=0.8.0; |
|
||||||
|
|
||||||
import {IMessageRecipient} from "../../interfaces/IMessageRecipient.sol"; |
|
||||||
|
|
||||||
contract BadRecipient1 is IMessageRecipient { |
|
||||||
function handle( |
|
||||||
uint32, |
|
||||||
bytes32, |
|
||||||
bytes calldata |
|
||||||
) external payable override { |
|
||||||
assembly { |
|
||||||
revert(0, 0) |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
@ -1,6 +0,0 @@ |
|||||||
// SPDX-License-Identifier: MIT OR Apache-2.0 |
|
||||||
pragma solidity >=0.8.0; |
|
||||||
|
|
||||||
contract BadRecipient2 { |
|
||||||
function handle(uint32, bytes32) external pure {} // solhint-disable-line no-empty-blocks |
|
||||||
} |
|
@ -1,17 +0,0 @@ |
|||||||
// SPDX-License-Identifier: MIT OR Apache-2.0 |
|
||||||
pragma solidity >=0.8.0; |
|
||||||
|
|
||||||
import {IMessageRecipient} from "../../interfaces/IMessageRecipient.sol"; |
|
||||||
|
|
||||||
contract BadRecipient3 is IMessageRecipient { |
|
||||||
function handle( |
|
||||||
uint32, |
|
||||||
bytes32, |
|
||||||
bytes calldata |
|
||||||
) external payable override { |
|
||||||
assembly { |
|
||||||
mstore(0, 0xabcdef) |
|
||||||
revert(0, 32) |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
@ -1,14 +0,0 @@ |
|||||||
// SPDX-License-Identifier: MIT OR Apache-2.0 |
|
||||||
pragma solidity >=0.8.0; |
|
||||||
|
|
||||||
import {IMessageRecipient} from "../../interfaces/IMessageRecipient.sol"; |
|
||||||
|
|
||||||
contract BadRecipient5 is IMessageRecipient { |
|
||||||
function handle( |
|
||||||
uint32, |
|
||||||
bytes32, |
|
||||||
bytes calldata |
|
||||||
) external payable override { |
|
||||||
require(false, "no can do"); |
|
||||||
} |
|
||||||
} |
|
@ -1,14 +0,0 @@ |
|||||||
// SPDX-License-Identifier: MIT OR Apache-2.0 |
|
||||||
pragma solidity >=0.8.0; |
|
||||||
|
|
||||||
import {IMessageRecipient} from "../../interfaces/IMessageRecipient.sol"; |
|
||||||
|
|
||||||
contract BadRecipient6 is IMessageRecipient { |
|
||||||
function handle( |
|
||||||
uint32, |
|
||||||
bytes32, |
|
||||||
bytes calldata |
|
||||||
) external payable override { |
|
||||||
require(false); // solhint-disable-line reason-string |
|
||||||
} |
|
||||||
} |
|
@ -1,7 +1,7 @@ |
|||||||
// SPDX-License-Identifier: MIT OR Apache-2.0 |
// SPDX-License-Identifier: MIT OR Apache-2.0 |
||||||
pragma solidity >=0.8.0; |
pragma solidity >=0.8.0; |
||||||
|
|
||||||
library Message { |
library TokenMessage { |
||||||
function format( |
function format( |
||||||
bytes32 _recipient, |
bytes32 _recipient, |
||||||
uint256 _amount, |
uint256 _amount, |
@ -0,0 +1,21 @@ |
|||||||
|
# generates lcov.info |
||||||
|
forge coverage --report lcov |
||||||
|
|
||||||
|
if ! command -v lcov &>/dev/null; then |
||||||
|
echo "lcov is not installed. Installing..." |
||||||
|
sudo apt-get install lcov |
||||||
|
fi |
||||||
|
|
||||||
|
lcov --version |
||||||
|
|
||||||
|
# forge does not instrument libraries https://github.com/foundry-rs/foundry/issues/4854 |
||||||
|
EXCLUDE="*test* *mock* *node_modules* $(grep -r 'library' contracts -l)" |
||||||
|
lcov --rc lcov_branch_coverage=1 \ |
||||||
|
--output-file forge-pruned-lcov.info \ |
||||||
|
--remove lcov.info $EXCLUDE |
||||||
|
|
||||||
|
if [ "$CI" != "true" ]; then |
||||||
|
genhtml --rc lcov_branch_coverage=1 \ |
||||||
|
--output-directory coverage forge-pruned-lcov.info \ |
||||||
|
&& open coverage/index.html |
||||||
|
fi |
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue