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 |
||||
pragma solidity >=0.8.0; |
||||
|
||||
import {CallLib} from "../Call.sol"; |
||||
import {TypeCasts} from "../TypeCasts.sol"; |
||||
import {CallLib} from "./Call.sol"; |
||||
import {TypeCasts} from "../../libs/TypeCasts.sol"; |
||||
|
||||
/** |
||||
* Format of message: |
@ -1,7 +1,7 @@ |
||||
// SPDX-License-Identifier: Apache-2.0 |
||||
pragma solidity ^0.8.13; |
||||
|
||||
import {CallLib} from "../Call.sol"; |
||||
import {CallLib} from "./Call.sol"; |
||||
|
||||
/** |
||||
* Format of message: |
@ -1,18 +1,18 @@ |
||||
// SPDX-License-Identifier: MIT OR Apache-2.0 |
||||
pragma solidity >=0.6.11; |
||||
|
||||
import "./TestRouter.sol"; |
||||
import "../GasRouter.sol"; |
||||
import "../client/GasRouter.sol"; |
||||
|
||||
contract TestGasRouter is TestRouter, GasRouter { |
||||
constructor(address _mailbox) TestRouter(_mailbox) {} |
||||
contract TestGasRouter is GasRouter { |
||||
constructor(address _mailbox) GasRouter(_mailbox) {} |
||||
|
||||
function _metadata(uint32 _destination) |
||||
internal |
||||
view |
||||
override(GasRouter, MailboxClient) |
||||
returns (bytes memory) |
||||
{ |
||||
return GasRouter._metadata(_destination); |
||||
function dispatch(uint32 _destination, bytes memory _msg) external payable { |
||||
_dispatch(_destination, _msg); |
||||
} |
||||
|
||||
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 |
||||
pragma solidity >=0.8.0; |
||||
|
||||
library Message { |
||||
library TokenMessage { |
||||
function format( |
||||
bytes32 _recipient, |
||||
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