From e7bdde921ba6087f82ddb0407b42bd084d481c44 Mon Sep 17 00:00:00 2001 From: Andreas <41449730+nonergodic@users.noreply.github.com> Date: Thu, 22 Aug 2024 09:05:45 -0700 Subject: [PATCH] Restructure and update repo (#31) * restructure repo in line with new, expanded purpose * fix typo * bump solc version to 8.19 (last version before shanghai) * move remappings into foundry.toml * fix foundry.toml syntax mishap * Update README.md Co-authored-by: Csongor Kiss * Update README.md Co-authored-by: Csongor Kiss * updated README * fix failing tests * fix vm.assume rejected too many inputs error in query tests --------- Co-authored-by: Csongor Kiss --- README.md | 42 +++++++++---- foundry.toml | 10 +++- remappings.txt | 2 - src/Chains.sol | 2 +- src/Utils.sol | 18 +++--- src/{ => WormholeRelayer}/Base.sol | 10 ++-- .../CCTPAndTokenBase.sol | 24 ++++---- src/{ => WormholeRelayer}/CCTPBase.sol | 14 ++--- src/{ => WormholeRelayer}/TokenBase.sol | 22 +++---- src/WormholeRelayerSDK.sol | 31 +++++++--- src/interfaces/ITokenBridge.sol | 2 +- src/interfaces/IWormholeRelayer.sol | 6 +- .../IMessageTransmitter.sol | 0 .../{CCTPInterfaces => cctp}/IReceiver.sol | 0 .../{CCTPInterfaces => cctp}/IRelayer.sol | 0 .../ITokenMessenger.sol | 21 ++++++- src/interfaces/{ => token}/IERC20.sol | 0 src/interfaces/token/IUSDC.sol | 17 ++++++ src/interfaces/{ => token}/IWETH.sol | 1 - src/libraries/BytesParsing.sol | 2 +- src/testing/ERC20Mock.sol | 4 +- .../DeliveryInstructionDecoder.sol | 20 +++---- .../ExecutionParameters.sol | 5 +- .../MockOffchainRelayer.sol | 20 +++---- src/testing/WormholeRelayerTest.sol | 50 +++++----------- src/testing/helpers/CircleCCTPSimulator.sol | 11 ++-- src/testing/helpers/WormholeSimulator.sol | 10 ++-- test/QueryResponse.t.sol | 60 ++++++++++++------- .../CCTPAndTokenBridgeBase.t.sol | 30 ++++------ test/{ => WormholeRelayer}/CCTPBase.t.sol | 26 ++++---- test/{ => WormholeRelayer}/ChooseChains.t.sol | 24 +++----- test/{ => WormholeRelayer}/ExtraChains.t.sol | 37 +++++------- test/{ => WormholeRelayer}/Fork.t.sol | 32 ++++------ 33 files changed, 292 insertions(+), 261 deletions(-) delete mode 100644 remappings.txt rename src/{ => WormholeRelayer}/Base.sol (87%) rename src/{ => WormholeRelayer}/CCTPAndTokenBase.sol (96%) rename src/{ => WormholeRelayer}/CCTPBase.sol (95%) rename src/{ => WormholeRelayer}/TokenBase.sol (93%) rename src/interfaces/{CCTPInterfaces => cctp}/IMessageTransmitter.sol (100%) rename src/interfaces/{CCTPInterfaces => cctp}/IReceiver.sol (100%) rename src/interfaces/{CCTPInterfaces => cctp}/IRelayer.sol (100%) rename src/interfaces/{CCTPInterfaces => cctp}/ITokenMessenger.sol (68%) rename src/interfaces/{ => token}/IERC20.sol (100%) create mode 100644 src/interfaces/token/IUSDC.sol rename src/interfaces/{ => token}/IWETH.sol (89%) rename src/testing/{helpers => WormholeRelayer}/DeliveryInstructionDecoder.sol (94%) rename src/testing/{helpers => WormholeRelayer}/ExecutionParameters.sol (95%) rename src/testing/{helpers => WormholeRelayer}/MockOffchainRelayer.sol (94%) rename test/{ => WormholeRelayer}/CCTPAndTokenBridgeBase.t.sol (88%) rename test/{ => WormholeRelayer}/CCTPBase.t.sol (86%) rename test/{ => WormholeRelayer}/ChooseChains.t.sol (68%) rename test/{ => WormholeRelayer}/ExtraChains.t.sol (50%) rename test/{ => WormholeRelayer}/Fork.t.sol (90%) diff --git a/README.md b/README.md index ebc9230..19b9658 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,12 @@ # Wormhole Solidity SDK -The purpose of this SDK is to provide helpers to take your existing single-chain solidity application cross-chain using Wormhole's automatic relayers +The purpose of this SDK is to make on-chain integrations with Wormhole on EVM compatible chains as smooth as possible by providing all necessary Solidity interfaces along with useful libraries and tools for testing. -### Installation +For off-chain code, please refer to the [TypeScript SDK](https://github.com/wormhole-foundation/wormhole-sdk-ts) and in particular the [EVM platform implementation](https://github.com/wormhole-foundation/wormhole-sdk-ts/tree/main/platforms/evm). + +This SDK was originally created for integrations with the WormholeRelayer and then expanded to cover all integration. + +## Installation **Foundry and Forge** @@ -10,11 +14,27 @@ The purpose of this SDK is to provide helpers to take your existing single-chain forge install wormhole-foundation/wormhole-solidity-sdk ``` -### Example Usage + Introduction to Automatic Relayers +**Solc Version** + +Currently the SDK uses solc version 0.8.19 to avoid issues with PUSH0 which was introduced in 0.8.20 but which is not supported on many EVM chains. + +## WormholeRelayer + +### Introduction + +The WormholeRelayer (also sometimes referred to as the automatic or generic relayer) allows integrators to leverage external parties known as delivery providers, to relay messages emitted on a given source chain to the intended target chain. + +This frees integrators, who are building a cross-chain app, from the cumbersome and painful task of having to run relaying infrastructure themselves (and thus e.g. dealing with the headache of having to acquire gas tokens for the target chain). + +Messages include, but aren't limited to: Wormhole attestations (VAAs), Circle attestations (CCTP) + +Delivery providers provide a quote for the cost of a delivery on the source chain and also take payment there. This means the process is not fully trustless (delivery providers can take payment and then fail to perform the delivery), however the state of the respective chains always makes it clear whether a delivery provider has done their duty for a given delivery and delivery providers can't maliciously manipulate the content of a delivery. + +### Example Usage [HelloWormhole - Simple cross-chain message sending application](https://github.com/wormhole-foundation/hello-wormhole) -[HelloToken - Simple cross-chain token sending application](https://github.com/wormhole-foundation/hello-tokens) +[HelloToken - Simple cross-chain token sending application](https://github.com/wormhole-foundation/hello-token) [HelloUSDC - Simple cross-chain USDC sending application using CCTP](https://github.com/wormhole-foundation/hello-usdc) @@ -22,16 +42,14 @@ forge install wormhole-foundation/wormhole-solidity-sdk - Includes interfaces to interact with contracts in the Wormhole ecosystem ([src/interfaces](https://github.com/wormhole-foundation/wormhole-solidity-sdk/tree/main/src/interfaces)) - Includes the base class ‘Base’ with helpers for common actions that will typically need to be done within ‘receiveWormholeMessages’: - - [`onlyWormholeRelayer()`](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/main/src/Base.sol#L24): Checking that msg.sender is the wormhole relayer contract - Sometimes, Cross-chain applications may be set up such that there is one ‘spoke’ contract on every chain, which sends messages to the ‘hub’ contract. If so, we’d ideally only want to allow messages to be sent from these spoke contracts. Included are helpers for this: - - - [`setRegisteredSender(uint16 sourceChain, bytes32 sourceAddress)`](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/main/src/Base.sol#L47): Setting the specified sender for ‘sourceChain’ to be ‘sourceAddress’ - - [`isRegisteredSender(uint16 sourceChain, bytes32 sourceAddress)`](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/main/src/Base.sol#L35): Checking that the sender who requested the delivery is the registered address for that chain + - [`onlyWormholeRelayer()`](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/main/src/WormholeRelayer/Base.sol#L24): Checking that msg.sender is the wormhole relayer contract + Sometimes, cross-chain applications may be set up such that there is one ‘spoke’ contract on every chain, which sends messages to the ‘hub’ contract. If so, we’d ideally only want to allow messages to be sent from these spoke contracts. Included are helpers for this: - Look at test/Counter.t.sol for an example usage of Base + - [`setRegisteredSender(uint16 sourceChain, bytes32 sourceAddress)`](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/main/src/WormholeRelayer/Base.sol#L45): Setting the specified sender for ‘sourceChain’ to be ‘sourceAddress’ + - [`isRegisteredSender(uint16 sourceChain, bytes32 sourceAddress)`](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/main/src/WormholeRelayer/Base.sol#L30): Checking that the sender who requested the delivery is the registered address for that chain -- Included are also the ‘[TokenSender](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/main/src/TokenBase#L36)’ and ‘[TokenReceiver](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/main/src/TokenBase.sol#L126)’ base classes with helpers for smart contracts that wish to send and receive tokens using Wormhole’s TokenBridge. See ‘[HelloToken](https://github.com/wormhole-foundation/hello-token)’ for example usage. -- Included are also the ‘[CCTPSender](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/main/src/CCTPBase#L70)’ and ‘[CCTPReceiver](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/main/src/CCTPBase.sol#L134)’ base classes with helpers for smart contracts that wish to send and receive both tokens using Wormhole’s TokenBridge as well as USDC using CCTP. See ‘[HelloUSDC](https://github.com/wormhole-foundation/hello-usdc)’ for example usage. +- Included are also the ‘[TokenSender](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/main/src/WormholeRelayer/TokenBase#L36)’ and ‘[TokenReceiver](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/main/src/WormholeRelayer/TokenBase.sol#L126)’ base classes with helpers for smart contracts that wish to send and receive tokens using Wormhole’s TokenBridge. See ‘[HelloToken](https://github.com/wormhole-foundation/hello-token)’ for example usage. +- Included are also the ‘[CCTPSender](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/main/src/WormholeRelayer/CCTPBase#L59)’ and ‘[CCTPReceiver](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/main/src/WormholeRelayer/CCTPBase.sol#L177)’ base classes with helpers for smart contracts that wish to send and receive both tokens using Wormhole’s TokenBridge as well as USDC using CCTP. See ‘[HelloUSDC](https://github.com/wormhole-foundation/hello-usdc)’ for example usage. - Included are helpers that help set up a local forge testing environment. See ‘[HelloWormhole](https://github.com/wormhole-foundation/hello-wormhole)’ for example usage. **Note: This code is meant to be used as starter / reference code. Feel free to modify for use in your contracts, and also make sure to audit any code used from here as part of your contracts before deploying to mainnet.** \ No newline at end of file diff --git a/foundry.toml b/foundry.toml index dd87c33..52ad6f3 100644 --- a/foundry.toml +++ b/foundry.toml @@ -1,8 +1,14 @@ [profile.default] -solc_version = "0.8.13" +solc_version = "0.8.19" src = "src" out = "out" libs = ["lib"] via_ir = true -# See more config options https://github.com/foundry-rs/foundry/tree/master/config \ No newline at end of file +remappings = [ + "ds-test/=lib/forge-std/lib/ds-test/src/", + "forge-std/=lib/forge-std/src/", + "wormhole-sdk/=src/", +] + +# See more config options https://github.com/foundry-rs/foundry/tree/master/config diff --git a/remappings.txt b/remappings.txt deleted file mode 100644 index 845bd0a..0000000 --- a/remappings.txt +++ /dev/null @@ -1,2 +0,0 @@ -ds-test/=lib/forge-std/lib/ds-test/src/ -forge-std/=lib/forge-std/src/ diff --git a/src/Chains.sol b/src/Chains.sol index 6347711..960454d 100644 --- a/src/Chains.sol +++ b/src/Chains.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: Apache 2 -pragma solidity ^0.8.13; +pragma solidity ^0.8.19; // In the wormhole wire format, 0 indicates that a message is for any destination chain uint16 constant CHAIN_ID_UNSET = 0; diff --git a/src/Utils.sol b/src/Utils.sol index 1f93441..36eb112 100644 --- a/src/Utils.sol +++ b/src/Utils.sol @@ -1,16 +1,18 @@ // SPDX-License-Identifier: Apache 2 -pragma solidity ^0.8.13; +pragma solidity ^0.8.19; -import "./interfaces/IWormholeRelayer.sol"; +error NotAnEvmAddress(bytes32); -function toWormholeFormat(address addr) pure returns (bytes32) { - return bytes32(uint256(uint160(addr))); +function toUniversalAddress(address addr) pure returns (bytes32 universalAddr) { + universalAddr = bytes32(uint256(uint160(addr))); } -function fromWormholeFormat(bytes32 whFormatAddress) pure returns (address) { - if (uint256(whFormatAddress) >> 160 != 0) { - revert NotAnEvmAddress(whFormatAddress); +function fromUniversalAddress(bytes32 universalAddr) pure returns (address addr) { + if (bytes12(universalAddr) != 0) + revert NotAnEvmAddress(universalAddr); + + assembly ("memory-safe") { + addr := universalAddr } - return address(uint160(uint256(whFormatAddress))); } diff --git a/src/Base.sol b/src/WormholeRelayer/Base.sol similarity index 87% rename from src/Base.sol rename to src/WormholeRelayer/Base.sol index 1815f9b..7c54b6b 100644 --- a/src/Base.sol +++ b/src/WormholeRelayer/Base.sol @@ -1,10 +1,10 @@ // SPDX-License-Identifier: Apache 2 -pragma solidity ^0.8.13; +pragma solidity ^0.8.19; -import "./interfaces/IWormholeReceiver.sol"; -import "./interfaces/IWormholeRelayer.sol"; -import "./interfaces/IWormhole.sol"; -import "./Utils.sol"; +import "wormhole-sdk/interfaces/IWormholeReceiver.sol"; +import "wormhole-sdk/interfaces/IWormholeRelayer.sol"; +import "wormhole-sdk/interfaces/IWormhole.sol"; +import "wormhole-sdk/Utils.sol"; abstract contract Base { IWormholeRelayer public immutable wormholeRelayer; diff --git a/src/CCTPAndTokenBase.sol b/src/WormholeRelayer/CCTPAndTokenBase.sol similarity index 96% rename from src/CCTPAndTokenBase.sol rename to src/WormholeRelayer/CCTPAndTokenBase.sol index 989ad38..92a7920 100644 --- a/src/CCTPAndTokenBase.sol +++ b/src/WormholeRelayer/CCTPAndTokenBase.sol @@ -1,14 +1,14 @@ // SPDX-License-Identifier: Apache 2 -pragma solidity ^0.8.13; +pragma solidity ^0.8.19; -import "./interfaces/IWormholeReceiver.sol"; -import "./interfaces/IWormholeRelayer.sol"; -import "./interfaces/ITokenBridge.sol"; -import {IERC20} from "./interfaces/IERC20.sol"; -import "./interfaces/CCTPInterfaces/ITokenMessenger.sol"; -import "./interfaces/CCTPInterfaces/IMessageTransmitter.sol"; +import "wormhole-sdk/interfaces/IWormholeReceiver.sol"; +import "wormhole-sdk/interfaces/IWormholeRelayer.sol"; +import "wormhole-sdk/interfaces/ITokenBridge.sol"; +import "wormhole-sdk/interfaces/token/IERC20.sol"; +import "wormhole-sdk/interfaces/cctp/ITokenMessenger.sol"; +import "wormhole-sdk/interfaces/cctp/IMessageTransmitter.sol"; +import "wormhole-sdk/Utils.sol"; -import "./Utils.sol"; import "./TokenBase.sol"; import "./CCTPBase.sol"; @@ -216,13 +216,13 @@ abstract contract CCTPAndTokenSender is CCTPAndTokenBase { token, amount, targetChain, - toWormholeFormat(targetAddress), + toUniversalAddress(targetAddress), 0, payload ); return VaaKey({ - emitterAddress: toWormholeFormat(address(tokenBridge)), + emitterAddress: toUniversalAddress(address(tokenBridge)), chainId: wormhole.chainId(), sequence: sequence }); @@ -333,7 +333,7 @@ abstract contract CCTPAndTokenReceiver is CCTPAndTokenBase { ) internal view returns (address tokenAddressOnThisChain) { return tokenHomeChain == wormhole.chainId() - ? fromWormholeFormat(tokenHomeAddress) + ? fromUniversalAddress(tokenHomeAddress) : tokenBridge.wrappedAsset(tokenHomeChain, tokenHomeAddress); } @@ -362,7 +362,7 @@ abstract contract CCTPAndTokenReceiver is CCTPAndTokenBase { ITokenBridge.TransferWithPayload memory transfer = tokenBridge .parseTransferWithPayload(parsed.payload); require( - transfer.to == toWormholeFormat(address(this)) && + transfer.to == toUniversalAddress(address(this)) && transfer.toChain == wormhole.chainId(), "Token was not sent to this address" ); diff --git a/src/CCTPBase.sol b/src/WormholeRelayer/CCTPBase.sol similarity index 95% rename from src/CCTPBase.sol rename to src/WormholeRelayer/CCTPBase.sol index 4fe7271..856e7c8 100644 --- a/src/CCTPBase.sol +++ b/src/WormholeRelayer/CCTPBase.sol @@ -1,13 +1,13 @@ // SPDX-License-Identifier: Apache 2 -pragma solidity ^0.8.13; +pragma solidity ^0.8.19; -import "./interfaces/IWormholeReceiver.sol"; -import "./interfaces/IWormholeRelayer.sol"; -import {IERC20} from "./interfaces/IERC20.sol"; -import "./interfaces/CCTPInterfaces/ITokenMessenger.sol"; -import "./interfaces/CCTPInterfaces/IMessageTransmitter.sol"; +import "wormhole-sdk/interfaces/IWormholeReceiver.sol"; +import "wormhole-sdk/interfaces/IWormholeRelayer.sol"; +import "wormhole-sdk/interfaces/token/IERC20.sol"; +import "wormhole-sdk/interfaces/cctp/ITokenMessenger.sol"; +import "wormhole-sdk/interfaces/cctp/IMessageTransmitter.sol"; +import "wormhole-sdk/Utils.sol"; -import "./Utils.sol"; import "./Base.sol"; library CCTPMessageLib { diff --git a/src/TokenBase.sol b/src/WormholeRelayer/TokenBase.sol similarity index 93% rename from src/TokenBase.sol rename to src/WormholeRelayer/TokenBase.sol index 6e96c49..ac90738 100644 --- a/src/TokenBase.sol +++ b/src/WormholeRelayer/TokenBase.sol @@ -1,13 +1,13 @@ // SPDX-License-Identifier: Apache 2 -pragma solidity ^0.8.13; +pragma solidity ^0.8.19; -import "./interfaces/IWormholeReceiver.sol"; -import "./interfaces/IWormholeRelayer.sol"; -import "./interfaces/ITokenBridge.sol"; -import {IERC20} from "./interfaces/IERC20.sol"; -import {Base} from "./WormholeRelayerSDK.sol"; +import "wormhole-sdk/interfaces/IWormholeReceiver.sol"; +import "wormhole-sdk/interfaces/IWormholeRelayer.sol"; +import "wormhole-sdk/interfaces/ITokenBridge.sol"; +import "wormhole-sdk/interfaces/token/IERC20.sol"; +import "wormhole-sdk/Utils.sol"; -import "./Utils.sol"; +import {Base} from "./Base.sol"; abstract contract TokenBase is Base { ITokenBridge public immutable tokenBridge; @@ -76,13 +76,13 @@ abstract contract TokenSender is TokenBase { token, amount, targetChain, - toWormholeFormat(targetAddress), + toUniversalAddress(targetAddress), 0, payload ); return VaaKey({ - emitterAddress: toWormholeFormat(address(tokenBridge)), + emitterAddress: toUniversalAddress(address(tokenBridge)), chainId: wormhole.chainId(), sequence: sequence }); @@ -180,7 +180,7 @@ abstract contract TokenReceiver is TokenBase { ) internal view returns (address tokenAddressOnThisChain) { return tokenHomeChain == wormhole.chainId() - ? fromWormholeFormat(tokenHomeAddress) + ? fromUniversalAddress(tokenHomeAddress) : tokenBridge.wrappedAsset(tokenHomeChain, tokenHomeAddress); } @@ -205,7 +205,7 @@ abstract contract TokenReceiver is TokenBase { ITokenBridge.TransferWithPayload memory transfer = tokenBridge .parseTransferWithPayload(parsed.payload); require( - transfer.to == toWormholeFormat(address(this)) && + transfer.to == toUniversalAddress(address(this)) && transfer.toChain == wormhole.chainId(), "Token was not sent to this address" ); diff --git a/src/WormholeRelayerSDK.sol b/src/WormholeRelayerSDK.sol index 78d4ccd..32681e5 100644 --- a/src/WormholeRelayerSDK.sol +++ b/src/WormholeRelayerSDK.sol @@ -1,11 +1,24 @@ // SPDX-License-Identifier: Apache 2 -pragma solidity ^0.8.13; +pragma solidity ^0.8.19; -import "./interfaces/IWormholeReceiver.sol"; -import "./interfaces/IWormholeRelayer.sol"; -import "./Chains.sol"; -import "./Utils.sol"; -import {Base} from "./Base.sol"; -import {TokenBase, TokenReceiver, TokenSender} from "./TokenBase.sol"; -import {CCTPBase, CCTPReceiver, CCTPSender} from "./CCTPBase.sol"; -import {CCTPAndTokenBase, CCTPAndTokenReceiver, CCTPAndTokenSender} from "./CCTPAndTokenBase.sol"; +import "wormhole-sdk/interfaces/IWormholeReceiver.sol"; +import "wormhole-sdk/interfaces/IWormholeRelayer.sol"; +import "wormhole-sdk/Chains.sol"; +import "wormhole-sdk/Utils.sol"; + +import {Base} from "wormhole-sdk/WormholeRelayer/Base.sol"; +import { + TokenBase, + TokenReceiver, + TokenSender +} from "wormhole-sdk/WormholeRelayer/TokenBase.sol"; +import { + CCTPBase, + CCTPReceiver, + CCTPSender +} from "wormhole-sdk/WormholeRelayer/CCTPBase.sol"; +import { + CCTPAndTokenBase, + CCTPAndTokenReceiver, + CCTPAndTokenSender +} from "wormhole-sdk/WormholeRelayer/CCTPAndTokenBase.sol"; diff --git a/src/interfaces/ITokenBridge.sol b/src/interfaces/ITokenBridge.sol index eb9f05a..281d4d6 100644 --- a/src/interfaces/ITokenBridge.sol +++ b/src/interfaces/ITokenBridge.sol @@ -3,7 +3,7 @@ pragma solidity ^0.8.0; -import "./IWETH.sol"; +import "./token/IWETH.sol"; import "./IWormhole.sol"; interface ITokenBridge { diff --git a/src/interfaces/IWormholeRelayer.sol b/src/interfaces/IWormholeRelayer.sol index 520a1cc..c41dcba 100644 --- a/src/interfaces/IWormholeRelayer.sol +++ b/src/interfaces/IWormholeRelayer.sol @@ -2,6 +2,8 @@ pragma solidity ^0.8.0; +import {NotAnEvmAddress} from "wormhole-sdk/Utils.sol"; + /** * @title WormholeRelayer * @author @@ -668,5 +670,5 @@ error InvalidOverrideRefundPerGasUnused(); error InsufficientRelayerFunds(uint256 msgValue, uint256 minimum); //When a bytes32 field can't be converted into a 20 byte EVM address, because the 12 padding bytes -// are non-zero (duplicated from Utils.sol) -error NotAnEvmAddress(bytes32); +// are non-zero (see Utils.sol) +//error NotAnEvmAddress(bytes32); diff --git a/src/interfaces/CCTPInterfaces/IMessageTransmitter.sol b/src/interfaces/cctp/IMessageTransmitter.sol similarity index 100% rename from src/interfaces/CCTPInterfaces/IMessageTransmitter.sol rename to src/interfaces/cctp/IMessageTransmitter.sol diff --git a/src/interfaces/CCTPInterfaces/IReceiver.sol b/src/interfaces/cctp/IReceiver.sol similarity index 100% rename from src/interfaces/CCTPInterfaces/IReceiver.sol rename to src/interfaces/cctp/IReceiver.sol diff --git a/src/interfaces/CCTPInterfaces/IRelayer.sol b/src/interfaces/cctp/IRelayer.sol similarity index 100% rename from src/interfaces/CCTPInterfaces/IRelayer.sol rename to src/interfaces/cctp/IRelayer.sol diff --git a/src/interfaces/CCTPInterfaces/ITokenMessenger.sol b/src/interfaces/cctp/ITokenMessenger.sol similarity index 68% rename from src/interfaces/CCTPInterfaces/ITokenMessenger.sol rename to src/interfaces/cctp/ITokenMessenger.sol index 29e700e..832e4f8 100644 --- a/src/interfaces/CCTPInterfaces/ITokenMessenger.sol +++ b/src/interfaces/cctp/ITokenMessenger.sol @@ -1,6 +1,25 @@ - +/* + * Copyright (c) 2022, Circle Internet Financial Limited. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ pragma solidity ^0.8.0; +/** + * @title TokenMessenger + * @notice Sends messages and receives messages to/from MessageTransmitters + * and to/from TokenMinters + */ interface ITokenMessenger { /** * @notice Deposits and burns tokens from sender to be minted on destination domain. The mint diff --git a/src/interfaces/IERC20.sol b/src/interfaces/token/IERC20.sol similarity index 100% rename from src/interfaces/IERC20.sol rename to src/interfaces/token/IERC20.sol diff --git a/src/interfaces/token/IUSDC.sol b/src/interfaces/token/IUSDC.sol new file mode 100644 index 0000000..f94debe --- /dev/null +++ b/src/interfaces/token/IUSDC.sol @@ -0,0 +1,17 @@ +// SPDX-License-Identifier: Apache 2 + +pragma solidity ^0.8.0; + +import "./IERC20.sol"; + +interface IUSDC is IERC20 { + function mint(address to, uint256 amount) external; + + function configureMinter(address minter, uint256 minterAllowedAmount) external; + + function masterMinter() external view returns (address); + + function owner() external view returns (address); + + function blacklister() external view returns (address); +} diff --git a/src/interfaces/IWETH.sol b/src/interfaces/token/IWETH.sol similarity index 89% rename from src/interfaces/IWETH.sol rename to src/interfaces/token/IWETH.sol index e09013c..e3c9c8d 100644 --- a/src/interfaces/IWETH.sol +++ b/src/interfaces/token/IWETH.sol @@ -1,4 +1,3 @@ -// contracts/Bridge.sol // SPDX-License-Identifier: Apache 2 pragma solidity ^0.8.0; diff --git a/src/libraries/BytesParsing.sol b/src/libraries/BytesParsing.sol index 765c8c7..7f27a63 100644 --- a/src/libraries/BytesParsing.sol +++ b/src/libraries/BytesParsing.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: Apache 2 -pragma solidity ^0.8.13; +pragma solidity ^0.8.19; library BytesParsing { uint256 private constant freeMemoryPtr = 0x40; diff --git a/src/testing/ERC20Mock.sol b/src/testing/ERC20Mock.sol index 848ec99..a3d54a2 100644 --- a/src/testing/ERC20Mock.sol +++ b/src/testing/ERC20Mock.sol @@ -1,7 +1,7 @@ -pragma solidity ^0.8.13; +pragma solidity ^0.8.19; -import "../interfaces/IERC20.sol"; +import "wormhole-sdk/interfaces/token/IERC20.sol"; /* * ERC20 impl from solmate diff --git a/src/testing/helpers/DeliveryInstructionDecoder.sol b/src/testing/WormholeRelayer/DeliveryInstructionDecoder.sol similarity index 94% rename from src/testing/helpers/DeliveryInstructionDecoder.sol rename to src/testing/WormholeRelayer/DeliveryInstructionDecoder.sol index 7add44a..956b896 100644 --- a/src/testing/helpers/DeliveryInstructionDecoder.sol +++ b/src/testing/WormholeRelayer/DeliveryInstructionDecoder.sol @@ -1,9 +1,9 @@ -pragma solidity ^0.8.13; +pragma solidity ^0.8.19; -import "../../interfaces/IWormholeRelayer.sol"; -import "../../libraries/BytesParsing.sol"; -import {CCTPMessageLib} from "../../CCTPBase.sol"; +import "wormhole-sdk/interfaces/IWormholeRelayer.sol"; +import "wormhole-sdk/libraries/BytesParsing.sol"; +import {CCTPMessageLib} from "wormhole-sdk/WormholeRelayer/CCTPBase.sol"; uint8 constant VERSION_VAAKEY = 1; uint8 constant VERSION_DELIVERY_OVERRIDE = 1; @@ -66,7 +66,7 @@ function decodeDeliveryInstruction( strct.requestedReceiverValue = requestedReceiverValue; strct.extraReceiverValue = extraReceiverValue; - checkLength(encoded, offset); + encoded.checkLength(offset); } function decodeRedeliveryInstruction( @@ -87,7 +87,7 @@ function decodeRedeliveryInstruction( strct.newRequestedReceiverValue = newRequestedReceiverValue; - checkLength(encoded, offset); + encoded.checkLength(offset); } function vaaKeyArrayToMessageKeyArray( @@ -223,12 +223,6 @@ function checkUint8( } } -function checkLength(bytes memory encoded, uint256 expected) pure { - if (encoded.length != expected) { - revert InvalidPayloadLength(encoded.length, expected); - } -} - function encode( DeliveryOverride memory strct ) pure returns (bytes memory encoded) { @@ -253,5 +247,5 @@ function decodeDeliveryOverride( strct.newReceiverValue = receiverValue; - checkLength(encoded, offset); + encoded.checkLength(offset); } diff --git a/src/testing/helpers/ExecutionParameters.sol b/src/testing/WormholeRelayer/ExecutionParameters.sol similarity index 95% rename from src/testing/helpers/ExecutionParameters.sol rename to src/testing/WormholeRelayer/ExecutionParameters.sol index fedad1c..f61c393 100644 --- a/src/testing/helpers/ExecutionParameters.sol +++ b/src/testing/WormholeRelayer/ExecutionParameters.sol @@ -1,9 +1,8 @@ // SPDX-License-Identifier: Apache 2 -pragma solidity ^0.8.13; +pragma solidity ^0.8.19; -// import "../../interfaces/relayer/TypedUnits.sol"; -import "../../libraries/BytesParsing.sol"; +import "wormhole-sdk/libraries/BytesParsing.sol"; error UnexpectedExecutionParamsVersion(uint8 version, uint8 expectedVersion); error UnsupportedExecutionParamsVersion(uint8 version); diff --git a/src/testing/helpers/MockOffchainRelayer.sol b/src/testing/WormholeRelayer/MockOffchainRelayer.sol similarity index 94% rename from src/testing/helpers/MockOffchainRelayer.sol rename to src/testing/WormholeRelayer/MockOffchainRelayer.sol index ca4d9c4..6b55a3d 100644 --- a/src/testing/helpers/MockOffchainRelayer.sol +++ b/src/testing/WormholeRelayer/MockOffchainRelayer.sol @@ -5,14 +5,14 @@ pragma solidity ^0.8.0; import "forge-std/Vm.sol"; import "forge-std/console.sol"; -import {toWormholeFormat, fromWormholeFormat} from "../../Utils.sol"; -import {CCTPMessageLib} from "../../CCTPBase.sol"; -import "../../interfaces/IWormholeRelayer.sol"; -import "../../interfaces/IWormhole.sol"; -import "../../libraries/BytesParsing.sol"; - -import {WormholeSimulator} from "./WormholeSimulator.sol"; -import {CircleMessageTransmitterSimulator} from "./CircleCCTPSimulator.sol"; +import "wormhole-sdk/interfaces/IWormhole.sol"; +import "wormhole-sdk/interfaces/IWormholeRelayer.sol"; +import {toUniversalAddress, fromUniversalAddress} from "wormhole-sdk/Utils.sol"; +import "wormhole-sdk/libraries/BytesParsing.sol"; +import {CCTPMessageLib} from "wormhole-sdk/WormholeRelayer/CCTPBase.sol"; + +import {WormholeSimulator} from "../helpers/WormholeSimulator.sol"; +import {CircleMessageTransmitterSimulator} from "../helpers/CircleCCTPSimulator.sol"; import "./DeliveryInstructionDecoder.sol"; import "./ExecutionParameters.sol"; @@ -166,13 +166,13 @@ contract MockOffchainRelayer { console.log( "Found VAA from chain %s emitted from %s", parsed[i].emitterChainId, - fromWormholeFormat(parsed[i].emitterAddress) + fromUniversalAddress(parsed[i].emitterAddress) ); } if ( parsed[i].emitterAddress == - toWormholeFormat(wormholeRelayerContracts[chainId]) && + toUniversalAddress(wormholeRelayerContracts[chainId]) && (parsed[i].emitterChainId == chainId) ) { if (debugLogging) { diff --git a/src/testing/WormholeRelayerTest.sol b/src/testing/WormholeRelayerTest.sol index 88e5e15..5ee5701 100644 --- a/src/testing/WormholeRelayerTest.sol +++ b/src/testing/WormholeRelayerTest.sol @@ -1,21 +1,21 @@ -pragma solidity ^0.8.13; +pragma solidity ^0.8.19; -import "../../src/interfaces/IWormholeRelayer.sol"; -import "../../src/interfaces/IWormhole.sol"; -import "../../src/interfaces/ITokenBridge.sol"; -import "../../src/interfaces/CCTPInterfaces/IMessageTransmitter.sol"; -import "../../src/interfaces/CCTPInterfaces/ITokenMessenger.sol"; -import "../../src/Utils.sol"; +import "forge-std/Test.sol"; +import "forge-std/console.sol"; + +import "wormhole-sdk/interfaces/IWormholeRelayer.sol"; +import "wormhole-sdk/interfaces/IWormhole.sol"; +import "wormhole-sdk/interfaces/ITokenBridge.sol"; +import "wormhole-sdk/interfaces/cctp/IMessageTransmitter.sol"; +import "wormhole-sdk/interfaces/cctp/ITokenMessenger.sol"; +import "wormhole-sdk/Utils.sol"; import "./helpers/WormholeSimulator.sol"; import "./helpers/CircleCCTPSimulator.sol"; import "./ERC20Mock.sol"; -import "./helpers/DeliveryInstructionDecoder.sol"; -import "./helpers/ExecutionParameters.sol"; -import "./helpers/MockOffchainRelayer.sol"; - -import "forge-std/Test.sol"; -import "forge-std/console.sol"; +import "./WormholeRelayer/DeliveryInstructionDecoder.sol"; +import "./WormholeRelayer/ExecutionParameters.sol"; +import "./WormholeRelayer/MockOffchainRelayer.sol"; struct ChainInfo { uint16 chainId; @@ -311,28 +311,6 @@ abstract contract WormholeRelayerTest is Test { circleTokenMessenger: ITokenMessenger(address(0)), USDC: IERC20(address(0)) }); - chainInfosTestnet[5] = ChainInfo({ - chainId: 5, - name: "polygon mumbai", - url: vm.envOr( - "POLYGON_MUMBAI_RPC_URL", - string("https://rpc.ankr.com/polygon_mumbai") - ), - relayer: IWormholeRelayer( - 0x0591C25ebd0580E0d4F27A82Fc2e24E7489CB5e0 - ), - tokenBridge: ITokenBridge( - 0x377D55a7928c046E18eEbb61977e714d2a76472a - ), - wormhole: IWormhole(0x0CBE91CF822c73C2315FB05100C2F714765d5c20), - circleMessageTransmitter: IMessageTransmitter( - 0xe09A679F56207EF33F5b9d8fb4499Ec00792eA73 - ), - circleTokenMessenger: ITokenMessenger( - 0x9f3B8679c73C2Fef8b59B4f3444d4e156fb70AA5 - ), - USDC: IERC20(0x9999f7Fea5938fD3b1E26A12c3f2fb024e194f97) - }); chainInfosTestnet[16] = ChainInfo({ chainId: 16, name: "moonbase alpha - moonbeam", @@ -523,7 +501,7 @@ abstract contract WormholeRelayerTest is Test { name: "arbitrum", url: vm.envOr( "ARBITRUM_RPC_URL", - string("https://rpc.ankr.com/arbitrum") + string("https://arb1.arbitrum.io/rpc") ), relayer: IWormholeRelayer( 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 diff --git a/src/testing/helpers/CircleCCTPSimulator.sol b/src/testing/helpers/CircleCCTPSimulator.sol index df5669c..9b54ff4 100644 --- a/src/testing/helpers/CircleCCTPSimulator.sol +++ b/src/testing/helpers/CircleCCTPSimulator.sol @@ -1,13 +1,12 @@ // SPDX-License-Identifier: Apache 2 -pragma solidity ^0.8.13; - -import {IMessageTransmitter} from "../../../src/interfaces/CCTPInterfaces/IMessageTransmitter.sol"; -import "./BytesLib.sol"; +pragma solidity ^0.8.19; import "forge-std/Vm.sol"; -import "forge-std/console.sol"; -import {CCTPMessageLib} from "../../CCTPBase.sol"; +import {IMessageTransmitter} from "wormhole-sdk/interfaces/cctp/IMessageTransmitter.sol"; +import {CCTPMessageLib} from "wormhole-sdk/WormholeRelayer/CCTPBase.sol"; + +import "./BytesLib.sol"; interface MessageTransmitterViewAttesterManager { function attesterManager() external view returns (address); diff --git a/src/testing/helpers/WormholeSimulator.sol b/src/testing/helpers/WormholeSimulator.sol index a73f6ca..fafcdb4 100644 --- a/src/testing/helpers/WormholeSimulator.sol +++ b/src/testing/helpers/WormholeSimulator.sol @@ -1,11 +1,11 @@ // SPDX-License-Identifier: Apache 2 -pragma solidity ^0.8.13; - -import {IWormhole} from "../../../src/interfaces/IWormhole.sol"; -import "./BytesLib.sol"; +pragma solidity ^0.8.19; import "forge-std/Vm.sol"; -import "forge-std/console.sol"; + +import "wormhole-sdk/interfaces/IWormhole.sol"; + +import "./BytesLib.sol"; /** * @title A Wormhole Guardian Simulator diff --git a/test/QueryResponse.t.sol b/test/QueryResponse.t.sol index 89f6200..9a09adb 100644 --- a/test/QueryResponse.t.sol +++ b/test/QueryResponse.t.sol @@ -664,36 +664,46 @@ contract TestQueryResponse is Test { queryResponse.verifyQueryResponseSignatures(resp, signatures); } - function testFuzz_validateBlockTime_success(uint256 _blockTime, uint256 _minBlockTime) public view { - _blockTime = bound(_blockTime, 0, type(uint64).max/1_000_000); - vm.assume(_blockTime >= _minBlockTime); + function testFuzz_validateBlockTime_success(uint64 _blockTime, uint64 _minBlockTime) public view { + _blockTime %= type(uint64).max/1_000_000 + 1; + _minBlockTime %= type(uint64).max/1_000_000 + 1; + if (_minBlockTime > type(uint64).max/1_000_000 - _blockTime) + _blockTime %= type(uint64).max/1_000_000 - _minBlockTime + 1; + + _blockTime += _minBlockTime; queryResponse.validateBlockTime(uint64(_blockTime * 1_000_000), _minBlockTime); } - function testFuzz_validateBlockTime_fail(uint256 _blockTime, uint256 _minBlockTime) public { - _blockTime = bound(_blockTime, 0, type(uint64).max/1_000_000); - vm.assume(_blockTime < _minBlockTime); + function testFuzz_validateBlockTime_fail(uint64 _blockTime, uint64 _minBlockTime) public { + _minBlockTime %= type(uint64).max/1_000_000 + 1; + vm.assume(_minBlockTime > 0); + _blockTime %= _minBlockTime; vm.expectRevert(StaleBlockTime.selector); queryResponse.validateBlockTime(uint64(_blockTime * 1_000_000), _minBlockTime); } - function testFuzz_validateBlockNum_success(uint64 _blockNum, uint256 _minBlockNum) public view { - vm.assume(_blockNum >= _minBlockNum); + function testFuzz_validateBlockNum_success(uint64 _blockNum, uint64 _minBlockNum) public view { + if (_minBlockNum > type(uint64).max - _blockNum) //can't safely add _minBlockNum + _blockNum %= type(uint64).max - _minBlockNum + 1; //prevent overflow + + _blockNum += _minBlockNum; queryResponse.validateBlockNum(_blockNum, _minBlockNum); } - function testFuzz_validateBlockNum_fail(uint64 _blockNum, uint256 _minBlockNum) public { - vm.assume(_blockNum < _minBlockNum); + function testFuzz_validateBlockNum_fail(uint256 _blockNum, uint256 _minBlockNum) public { + vm.assume(_minBlockNum > 0); + _blockNum %= _minBlockNum; vm.expectRevert(StaleBlockNum.selector); - queryResponse.validateBlockNum(_blockNum, _minBlockNum); + queryResponse.validateBlockNum(uint64(_blockNum), _minBlockNum); } - function testFuzz_validateChainId_success(uint16 _validChainIndex, uint16[] memory _validChainIds) public view { - vm.assume(_validChainIndex < _validChainIds.length); + function testFuzz_validateChainId_success(uint256 _validChainIndex, uint16[] memory _validChainIds) public view { + vm.assume(_validChainIds.length > 0); + _validChainIndex %= _validChainIds.length; queryResponse.validateChainId(_validChainIds[_validChainIndex], _validChainIds); } @@ -708,8 +718,10 @@ contract TestQueryResponse is Test { } function testFuzz_validateEthCallData_success(bytes memory randomBytes, uint256 _contractAddressIndex, uint256 _functionSignatureIndex, address[] memory _expectedContractAddresses, bytes4[] memory _expectedFunctionSignatures) public view { - vm.assume(_contractAddressIndex < _expectedContractAddresses.length); - vm.assume(_functionSignatureIndex < _expectedFunctionSignatures.length); + vm.assume(_expectedContractAddresses.length > 0); + _contractAddressIndex %= _expectedContractAddresses.length; + vm.assume(_expectedFunctionSignatures.length > 0); + _functionSignatureIndex %= _expectedFunctionSignatures.length; EthCallData memory callData = EthCallData({ contractAddress: _expectedContractAddresses[_contractAddressIndex], @@ -721,7 +733,8 @@ contract TestQueryResponse is Test { } function testFuzz_validateEthCallData_successZeroSignatures(bytes4 randomSignature, bytes memory randomBytes, uint256 _contractAddressIndex, address[] memory _expectedContractAddresses) public view { - vm.assume(_contractAddressIndex < _expectedContractAddresses.length); + vm.assume(_expectedContractAddresses.length > 0); + _contractAddressIndex %= _expectedContractAddresses.length; EthCallData memory callData = EthCallData({ contractAddress: _expectedContractAddresses[_contractAddressIndex], @@ -735,7 +748,8 @@ contract TestQueryResponse is Test { } function testFuzz_validateEthCallData_successZeroAddresses(address randomAddress, bytes memory randomBytes, uint256 _functionSignatureIndex, bytes4[] memory _expectedFunctionSignatures) public view { - vm.assume(_functionSignatureIndex < _expectedFunctionSignatures.length); + vm.assume(_expectedFunctionSignatures.length > 0); + _functionSignatureIndex %= _expectedFunctionSignatures.length; EthCallData memory callData = EthCallData({ contractAddress: randomAddress, @@ -749,7 +763,8 @@ contract TestQueryResponse is Test { } function testFuzz_validateEthCallData_failSignature(bytes memory randomBytes, uint256 _contractAddressIndex, address[] memory _expectedContractAddresses, bytes4[] memory _expectedFunctionSignatures) public { - vm.assume(_contractAddressIndex < _expectedContractAddresses.length); + vm.assume(_expectedContractAddresses.length > 0); + _contractAddressIndex %= _expectedContractAddresses.length; vm.assume(_expectedFunctionSignatures.length > 0); for (uint256 i = 0; i < _expectedFunctionSignatures.length; ++i) { @@ -767,7 +782,8 @@ contract TestQueryResponse is Test { } function testFuzz_validateEthCallData_failAddress(bytes memory randomBytes, address randomAddress, uint256 _functionSignatureIndex, address[] memory _expectedContractAddresses, bytes4[] memory _expectedFunctionSignatures) public { - vm.assume(_functionSignatureIndex < _expectedFunctionSignatures.length); + vm.assume(_expectedFunctionSignatures.length > 0); + _functionSignatureIndex %= _expectedFunctionSignatures.length; vm.assume(_expectedContractAddresses.length > 0); for (uint256 i = 0; i < _expectedContractAddresses.length; ++i) { @@ -785,8 +801,10 @@ contract TestQueryResponse is Test { } function testFuzz_validateMultipleEthCallData_success(uint8 numInputs, bytes memory randomBytes, uint256 _contractAddressIndex, uint256 _functionSignatureIndex, address[] memory _expectedContractAddresses, bytes4[] memory _expectedFunctionSignatures) public view { - vm.assume(_contractAddressIndex < _expectedContractAddresses.length); - vm.assume(_functionSignatureIndex < _expectedFunctionSignatures.length); + vm.assume(_expectedContractAddresses.length > 0); + _contractAddressIndex %= _expectedContractAddresses.length; + vm.assume(_expectedFunctionSignatures.length > 0); + _functionSignatureIndex %= _expectedFunctionSignatures.length; EthCallData[] memory callDatas = new EthCallData[](numInputs); diff --git a/test/CCTPAndTokenBridgeBase.t.sol b/test/WormholeRelayer/CCTPAndTokenBridgeBase.t.sol similarity index 88% rename from test/CCTPAndTokenBridgeBase.t.sol rename to test/WormholeRelayer/CCTPAndTokenBridgeBase.t.sol index b26fa08..1c6ff90 100644 --- a/test/CCTPAndTokenBridgeBase.t.sol +++ b/test/WormholeRelayer/CCTPAndTokenBridgeBase.t.sol @@ -1,14 +1,8 @@ -pragma solidity ^0.8.13; +pragma solidity ^0.8.19; -import "../src/WormholeRelayerSDK.sol"; -import "../src/interfaces/IWormholeReceiver.sol"; -import "../src/interfaces/IWormholeRelayer.sol"; -import "../src/interfaces/IERC20.sol"; - -import "../src/testing/WormholeRelayerTest.sol"; - -import "../src/WormholeRelayerSDK.sol"; -import "../src/Utils.sol"; +import "wormhole-sdk/WormholeRelayerSDK.sol"; +import "wormhole-sdk/interfaces/token/IERC20.sol"; +import "wormhole-sdk/testing/WormholeRelayerTest.sol"; contract CCTPAndTokenBridgeToy is CCTPAndTokenSender, CCTPAndTokenReceiver { uint256 constant GAS_LIMIT = 250_000; @@ -30,8 +24,8 @@ contract CCTPAndTokenBridgeToy is CCTPAndTokenSender, CCTPAndTokenReceiver { _USDC ) { - setCCTPDomain(5, 7); - setCCTPDomain(6, 1); + setCCTPDomain(23, 3); + setCCTPDomain(2, 0); } function quoteCrossChainDeposit( @@ -62,7 +56,7 @@ contract CCTPAndTokenBridgeToy is CCTPAndTokenSender, CCTPAndTokenReceiver { bytes memory payload = abi.encode(recipient, amount); sendTokenWithPayloadToEvm( targetChain, - fromWormholeFormat(registeredSenders[targetChain]), // address (on targetChain) to send token and payload to + fromUniversalAddress(registeredSenders[targetChain]), // address (on targetChain) to send token and payload to payload, 0, // receiver value GAS_LIMIT, @@ -87,7 +81,7 @@ contract CCTPAndTokenBridgeToy is CCTPAndTokenSender, CCTPAndTokenReceiver { bytes memory payload = abi.encode(recipient, amount); sendUSDCWithPayloadToEvm( targetChain, - fromWormholeFormat(registeredSenders[targetChain]), // address (on targetChain) to send token and payload to + fromUniversalAddress(registeredSenders[targetChain]), // address (on targetChain) to send token and payload to payload, 0, // receiver value GAS_LIMIT, @@ -144,7 +138,7 @@ contract WormholeSDKTest is WormholeRelayerBasicTest { ERC20Mock public token; constructor() { - setTestnetForkChains(5, 6); + setMainnetForkChains(23, 2); } function setUpSource() public override { @@ -178,13 +172,13 @@ contract WormholeSDKTest is WormholeRelayerBasicTest { vm.selectFork(sourceFork); CCTPAndTokenBridgeToySource.setRegisteredSender( targetChain, - toWormholeFormat(address(CCTPAndTokenBridgeToyTarget)) + toUniversalAddress(address(CCTPAndTokenBridgeToyTarget)) ); vm.selectFork(targetFork); CCTPAndTokenBridgeToyTarget.setRegisteredSender( sourceChain, - toWormholeFormat(address(CCTPAndTokenBridgeToySource)) + toUniversalAddress(address(CCTPAndTokenBridgeToySource)) ); } @@ -240,7 +234,7 @@ contract WormholeSDKTest is WormholeRelayerBasicTest { vm.selectFork(targetFork); address wormholeWrappedToken = tokenBridgeTarget.wrappedAsset( sourceChain, - toWormholeFormat(address(token)) + toUniversalAddress(address(token)) ); assertEq(IERC20(wormholeWrappedToken).balanceOf(recipient), amount); } diff --git a/test/CCTPBase.t.sol b/test/WormholeRelayer/CCTPBase.t.sol similarity index 86% rename from test/CCTPBase.t.sol rename to test/WormholeRelayer/CCTPBase.t.sol index 0940b2e..e0375d6 100644 --- a/test/CCTPBase.t.sol +++ b/test/WormholeRelayer/CCTPBase.t.sol @@ -1,14 +1,8 @@ -pragma solidity ^0.8.13; +pragma solidity ^0.8.19; -import "../src/WormholeRelayerSDK.sol"; -import "../src/interfaces/IWormholeReceiver.sol"; -import "../src/interfaces/IWormholeRelayer.sol"; -import "../src/interfaces/IERC20.sol"; - -import "../src/testing/WormholeRelayerTest.sol"; - -import "../src/WormholeRelayerSDK.sol"; -import "../src/Utils.sol"; +import "wormhole-sdk/WormholeRelayerSDK.sol"; +import "wormhole-sdk/interfaces/token/IERC20.sol"; +import "wormhole-sdk/testing/WormholeRelayerTest.sol"; contract CCTPToy is CCTPSender, CCTPReceiver { uint256 constant GAS_LIMIT = 250_000; @@ -28,8 +22,8 @@ contract CCTPToy is CCTPSender, CCTPReceiver { _USDC ) { - setCCTPDomain(5, 7); - setCCTPDomain(6, 1); + setCCTPDomain(23, 3); + setCCTPDomain(2, 0); } function quoteCrossChainDeposit( @@ -59,7 +53,7 @@ contract CCTPToy is CCTPSender, CCTPReceiver { bytes memory payload = abi.encode(recipient, amount); sendUSDCWithPayloadToEvm( targetChain, - fromWormholeFormat(registeredSenders[targetChain]), // address (on targetChain) to send token and payload to + fromUniversalAddress(registeredSenders[targetChain]), // address (on targetChain) to send token and payload to payload, 0, // receiver value GAS_LIMIT, @@ -95,7 +89,7 @@ contract WormholeSDKTest is WormholeRelayerBasicTest { ERC20Mock USDCTarget; constructor() { - setTestnetForkChains(5, 6); + setMainnetForkChains(23, 2); } function setUpSource() public override { @@ -126,13 +120,13 @@ contract WormholeSDKTest is WormholeRelayerBasicTest { vm.selectFork(sourceFork); CCTPToySource.setRegisteredSender( targetChain, - toWormholeFormat(address(CCTPToyTarget)) + toUniversalAddress(address(CCTPToyTarget)) ); vm.selectFork(targetFork); CCTPToyTarget.setRegisteredSender( sourceChain, - toWormholeFormat(address(CCTPToySource)) + toUniversalAddress(address(CCTPToySource)) ); } diff --git a/test/ChooseChains.t.sol b/test/WormholeRelayer/ChooseChains.t.sol similarity index 68% rename from test/ChooseChains.t.sol rename to test/WormholeRelayer/ChooseChains.t.sol index 6ea50c3..13220b9 100644 --- a/test/ChooseChains.t.sol +++ b/test/WormholeRelayer/ChooseChains.t.sol @@ -1,17 +1,9 @@ -pragma solidity ^0.8.13; +pragma solidity ^0.8.19; -import "../src/WormholeRelayerSDK.sol"; -import "../src/interfaces/IWormholeReceiver.sol"; -import "../src/interfaces/IWormholeRelayer.sol"; -import "../src/interfaces/IERC20.sol"; - -import "../src/testing/WormholeRelayerTest.sol"; - -import "../src/WormholeRelayerSDK.sol"; -import "../src/Utils.sol"; - -import "forge-std/console.sol"; +import "wormhole-sdk/WormholeRelayerSDK.sol"; +import "wormhole-sdk/interfaces/token/IERC20.sol"; +import "wormhole-sdk/testing/WormholeRelayerTest.sol"; import {Toy} from "./Fork.t.sol"; contract ChooseChainsTest is WormholeRelayerBasicTest { @@ -19,19 +11,19 @@ contract ChooseChainsTest is WormholeRelayerBasicTest { Toy toyTarget; constructor() { - setTestnetForkChains(4, 5); + setTestnetForkChains(4, 6); } function setUpSource() public override { require(wormholeSource.chainId() == 4); toySource = new Toy(address(relayerSource), address(wormholeSource)); - toySource.setRegisteredSender(targetChain, toWormholeFormat(address(this))); + toySource.setRegisteredSender(targetChain, toUniversalAddress(address(this))); } function setUpTarget() public override { - require(wormholeTarget.chainId() == 5); + require(wormholeTarget.chainId() == 6); toyTarget = new Toy(address(relayerTarget), address(wormholeTarget)); - toyTarget.setRegisteredSender(sourceChain, toWormholeFormat(address(this))); + toyTarget.setRegisteredSender(sourceChain, toUniversalAddress(address(this))); } function testSendMessage() public { diff --git a/test/ExtraChains.t.sol b/test/WormholeRelayer/ExtraChains.t.sol similarity index 50% rename from test/ExtraChains.t.sol rename to test/WormholeRelayer/ExtraChains.t.sol index e38066a..94db0cf 100644 --- a/test/ExtraChains.t.sol +++ b/test/WormholeRelayer/ExtraChains.t.sol @@ -1,46 +1,41 @@ -pragma solidity ^0.8.13; +pragma solidity ^0.8.19; -import "../src/WormholeRelayerSDK.sol"; -import "../src/interfaces/IWormholeReceiver.sol"; -import "../src/interfaces/IWormholeRelayer.sol"; -import "../src/interfaces/IERC20.sol"; +import "wormhole-sdk/WormholeRelayerSDK.sol"; +import "wormhole-sdk/interfaces/token/IERC20.sol"; +import "wormhole-sdk/testing/WormholeRelayerTest.sol"; -import "../src/testing/WormholeRelayerTest.sol"; - -import "../src/WormholeRelayerSDK.sol"; -import "../src/Utils.sol"; - -import "forge-std/console.sol"; import {Toy} from "./Fork.t.sol"; contract ExtraChainsTest is WormholeRelayerTest { mapping(uint16 => Toy) toys; constructor() WormholeRelayerTest() { - ChainInfo[] memory chains = new ChainInfo[](4); + ChainInfo[] memory chains = new ChainInfo[](3); chains[0] = chainInfosTestnet[4]; - chains[1] = chainInfosTestnet[5]; - chains[2] = chainInfosTestnet[6]; - chains[3] = chainInfosTestnet[14]; + chains[1] = chainInfosTestnet[6]; + chains[2] = chainInfosTestnet[14]; setActiveForks(chains); } function setUpFork(ActiveFork memory fork) public override { toys[fork.chainId] = new Toy(address(fork.relayer), address(fork.wormhole)); - toys[fork.chainId].setRegisteredSender(4, toWormholeFormat(address(this))); - toys[fork.chainId].setRegisteredSender(5, toWormholeFormat(address(this))); - toys[fork.chainId].setRegisteredSender(6, toWormholeFormat(address(this))); - toys[fork.chainId].setRegisteredSender(14, toWormholeFormat(address(this))); + toys[fork.chainId].setRegisteredSender(4, toUniversalAddress(address(this))); + toys[fork.chainId].setRegisteredSender(6, toUniversalAddress(address(this))); + toys[fork.chainId].setRegisteredSender(14, toUniversalAddress(address(this))); } function testSendFromCelo() public { ActiveFork memory celo = activeForks[14]; - for (uint16 i = 4; i < 7; ++i) { + uint16[] memory chains = new uint16[](2); + chains[0] = 4; + chains[1] = 6; + for (uint16 i = 0; i < chains.length; ++i) { + uint16 chainId = chains[i]; vm.selectFork(celo.fork); vm.recordLogs(); - ActiveFork memory target = activeForks[i]; + ActiveFork memory target = activeForks[chainId]; (uint256 cost,) = celo.relayer.quoteEVMDeliveryPrice(target.chainId, 1e17, 100_000); diff --git a/test/Fork.t.sol b/test/WormholeRelayer/Fork.t.sol similarity index 90% rename from test/Fork.t.sol rename to test/WormholeRelayer/Fork.t.sol index c20b56e..de0b298 100644 --- a/test/Fork.t.sol +++ b/test/WormholeRelayer/Fork.t.sol @@ -1,17 +1,11 @@ -pragma solidity ^0.8.13; - -import "../src/WormholeRelayerSDK.sol"; -import "../src/interfaces/IWormholeReceiver.sol"; -import "../src/interfaces/IWormholeRelayer.sol"; -import "../src/interfaces/IERC20.sol"; - -import "../src/testing/WormholeRelayerTest.sol"; - -import "../src/WormholeRelayerSDK.sol"; -import "../src/Utils.sol"; +pragma solidity ^0.8.19; import "forge-std/console.sol"; +import "wormhole-sdk/WormholeRelayerSDK.sol"; +import "wormhole-sdk/interfaces/token/IERC20.sol"; +import "wormhole-sdk/testing/WormholeRelayerTest.sol"; + contract Toy is Base { IWormholeRelayer relayer; @@ -83,7 +77,7 @@ contract TokenToy is TokenSender, TokenReceiver { bytes memory payload = abi.encode(recipient); sendTokenWithPayloadToEvm( targetChain, - fromWormholeFormat(registeredSenders[targetChain]), // address (on targetChain) to send token and payload to + fromUniversalAddress(registeredSenders[targetChain]), // address (on targetChain) to send token and payload to payload, 0, // receiver value GAS_LIMIT, @@ -111,7 +105,7 @@ contract TokenToy is TokenSender, TokenReceiver { bytes memory payload = abi.encode(recipient); sendTokenWithPayloadToEvm( targetChain, - fromWormholeFormat(registeredSenders[targetChain]), // address (on targetChain) to send token and payload to + fromUniversalAddress(registeredSenders[targetChain]), // address (on targetChain) to send token and payload to payload, 0, // receiver value GAS_LIMIT, @@ -154,7 +148,7 @@ contract WormholeSDKTest is WormholeRelayerBasicTest { toySource = new Toy(address(relayerSource), address(wormholeSource)); toySource.setRegisteredSender( targetChain, - toWormholeFormat(address(this)) + toUniversalAddress(address(this)) ); tokenToySource = new TokenToy( @@ -170,7 +164,7 @@ contract WormholeSDKTest is WormholeRelayerBasicTest { toyTarget = new Toy(address(relayerTarget), address(wormholeTarget)); toyTarget.setRegisteredSender( sourceChain, - toWormholeFormat(address(this)) + toUniversalAddress(address(this)) ); tokenToyTarget = new TokenToy( @@ -184,13 +178,13 @@ contract WormholeSDKTest is WormholeRelayerBasicTest { vm.selectFork(sourceFork); tokenToySource.setRegisteredSender( targetChain, - toWormholeFormat(address(tokenToyTarget)) + toUniversalAddress(address(tokenToyTarget)) ); vm.selectFork(targetFork); tokenToyTarget.setRegisteredSender( sourceChain, - toWormholeFormat(address(tokenToySource)) + toUniversalAddress(address(tokenToySource)) ); } @@ -260,7 +254,7 @@ contract WormholeSDKTest is WormholeRelayerBasicTest { vm.selectFork(targetFork); address wormholeWrappedToken = tokenBridgeTarget.wrappedAsset( sourceChain, - toWormholeFormat(address(token)) + toUniversalAddress(address(token)) ); assertEq(IERC20(wormholeWrappedToken).balanceOf(recipient), amount); } @@ -291,7 +285,7 @@ contract WormholeSDKTest is WormholeRelayerBasicTest { vm.selectFork(targetFork); address wormholeWrappedToken = tokenBridgeTarget.wrappedAsset( sourceChain, - toWormholeFormat(address(token)) + toUniversalAddress(address(token)) ); assertEq(IERC20(wormholeWrappedToken).balanceOf(recipient), amount); assertTrue(refundAddress.balance > 0);