This repository has been archived by the owner on May 23, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Improve forge test coverage + Seperate tests into individual tests (#119
) * fast tests * forge fmt * Remove parameter from forge test generic relayer * WIP * WIP * Move Forge Mock Generic Relayer to seperate file * Split revert redelivery tests into first few seperate tests * redelivery test changes * WIP * tests pass * Redelivery tests less D.R.Y and seperated into individual tests * Delivery tests less D.R.Y and seperated into individual tests * Resend checks in seperate tests * Forward test coverage! * 100% test coverage in CoreRelayer and CoreRelayerDelivery! * remove test coverage files * Governance tests * governance stack * forge fmt * removed console.sol
- Loading branch information
1 parent
48e2061
commit 9e28250
Showing
13 changed files
with
1,693 additions
and
641 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,3 @@ | ||
// contracts/Bridge.sol | ||
// SPDX-License-Identifier: Apache 2 | ||
|
||
pragma solidity ^0.8.0; | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,3 @@ | ||
// contracts/Messages.sol | ||
// SPDX-License-Identifier: Apache 2 | ||
|
||
pragma solidity ^0.8.0; | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,3 @@ | ||
// contracts/Messages.sol | ||
// SPDX-License-Identifier: Apache 2 | ||
|
||
pragma solidity ^0.8.0; | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,3 @@ | ||
// contracts/Messages.sol | ||
// SPDX-License-Identifier: Apache 2 | ||
|
||
pragma solidity ^0.8.0; | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,3 @@ | ||
// contracts/Messages.sol | ||
// SPDX-License-Identifier: Apache 2 | ||
|
||
pragma solidity ^0.8.0; | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
// SPDX-License-Identifier: UNLICENSED | ||
pragma solidity ^0.8.0; | ||
|
||
import "../contracts/interfaces/IWormhole.sol"; | ||
import "../contracts/interfaces/IWormholeReceiver.sol"; | ||
import "../contracts/interfaces/IWormholeRelayer.sol"; | ||
import "../contracts/interfaces/IRelayProvider.sol"; | ||
import "../contracts/libraries/external/BytesLib.sol"; | ||
import "./MockGenericRelayer.sol"; | ||
import "forge-std/console.sol"; | ||
import "forge-std/Vm.sol"; | ||
|
||
contract ForwardTester is IWormholeReceiver { | ||
using BytesLib for bytes; | ||
|
||
IWormhole wormhole; | ||
IWormholeRelayer wormholeRelayer; | ||
MockGenericRelayer genericRelayer; | ||
|
||
address private constant VM_ADDRESS = address(bytes20(uint160(uint256(keccak256("hevm cheat code"))))); | ||
|
||
Vm public constant vm = Vm(VM_ADDRESS); | ||
|
||
constructor(address _wormhole, address _wormholeRelayer, address _wormholeSimulator) { | ||
wormhole = IWormhole(_wormhole); | ||
wormholeRelayer = IWormholeRelayer(_wormholeRelayer); | ||
genericRelayer = new MockGenericRelayer(_wormhole, _wormholeSimulator, _wormholeRelayer); | ||
genericRelayer.setWormholeRelayerContract(wormhole.chainId(), address(wormholeRelayer)); | ||
genericRelayer.setProviderDeliveryAddress( | ||
wormhole.chainId(), | ||
wormholeRelayer.fromWormholeFormat( | ||
IRelayProvider(wormholeRelayer.getDefaultRelayProvider()).getDeliveryAddress(wormhole.chainId()) | ||
) | ||
); | ||
genericRelayer.setWormholeFee(wormhole.chainId(), wormhole.messageFee()); | ||
} | ||
|
||
enum Action { | ||
MultipleForwardsRequested, | ||
ForwardRequestFromWrongAddress, | ||
NonceIsZero, | ||
MultichainSendEmpty, | ||
MaxTransactionFeeNotEnough, | ||
FundsTooMuch, | ||
ReentrantCall, | ||
WorksCorrectly | ||
} | ||
|
||
function receiveWormholeMessages(bytes[] memory vaas, bytes[] memory additionalData) public payable override { | ||
(IWormhole.VM memory vaa, bool valid, string memory reason) = wormhole.parseAndVerifyVM(vaas[0]); | ||
require(valid, reason); | ||
|
||
bytes memory payload = vaa.payload; | ||
Action action = Action(payload.toUint8(0)); | ||
|
||
if (action == Action.MultipleForwardsRequested) { | ||
uint256 maxTransactionFee = | ||
wormholeRelayer.quoteGas(vaa.emitterChainId, 10000, wormholeRelayer.getDefaultRelayProvider()); | ||
wormholeRelayer.forward(vaa.emitterChainId, vaa.emitterAddress, vaa.emitterAddress, maxTransactionFee, 0, 1); | ||
wormholeRelayer.forward(vaa.emitterChainId, vaa.emitterAddress, vaa.emitterAddress, maxTransactionFee, 0, 1); | ||
} else if (action == Action.ForwardRequestFromWrongAddress) { | ||
// Emitter must be a wormhole relayer | ||
uint256 maxTransactionFee = | ||
wormholeRelayer.quoteGas(vaa.emitterChainId, 10000, wormholeRelayer.getDefaultRelayProvider()); | ||
DummyContract dc = new DummyContract(address(wormholeRelayer)); | ||
dc.forward(vaa.emitterChainId, vaa.emitterAddress, vaa.emitterAddress, maxTransactionFee, 0, 1); | ||
} else if (action == Action.NonceIsZero) { | ||
uint256 maxTransactionFee = | ||
wormholeRelayer.quoteGas(vaa.emitterChainId, 10000, wormholeRelayer.getDefaultRelayProvider()); | ||
wormholeRelayer.forward(vaa.emitterChainId, vaa.emitterAddress, vaa.emitterAddress, maxTransactionFee, 0, 0); | ||
} else if (action == Action.MultichainSendEmpty) { | ||
wormholeRelayer.multichainForward( | ||
IWormholeRelayer.MultichainSend( | ||
wormholeRelayer.getDefaultRelayProvider(), new IWormholeRelayer.Send[](0) | ||
), | ||
1 | ||
); | ||
} else if (action == Action.MaxTransactionFeeNotEnough) { | ||
uint256 maxTransactionFee = | ||
wormholeRelayer.quoteGas(vaa.emitterChainId, 1, wormholeRelayer.getDefaultRelayProvider()) - 1; | ||
wormholeRelayer.forward(vaa.emitterChainId, vaa.emitterAddress, vaa.emitterAddress, maxTransactionFee, 0, 1); | ||
} else if (action == Action.FundsTooMuch) { | ||
// set maximum budget to less than this | ||
uint256 maxTransactionFee = | ||
wormholeRelayer.quoteGas(vaa.emitterChainId, 10000, wormholeRelayer.getDefaultRelayProvider()); | ||
wormholeRelayer.forward(vaa.emitterChainId, vaa.emitterAddress, vaa.emitterAddress, maxTransactionFee, 0, 1); | ||
} else if (action == Action.ReentrantCall) { | ||
uint256 maxTransactionFee = | ||
wormholeRelayer.quoteGas(wormhole.chainId(), 10000, wormholeRelayer.getDefaultRelayProvider()); | ||
vm.recordLogs(); | ||
wormholeRelayer.send{value: maxTransactionFee + wormhole.messageFee()}( | ||
wormhole.chainId(), vaa.emitterAddress, vaa.emitterAddress, maxTransactionFee, 0, 1 | ||
); | ||
genericRelayer.relay(wormhole.chainId()); | ||
} else { | ||
uint256 maxTransactionFee = | ||
wormholeRelayer.quoteGas(vaa.emitterChainId, 10000, wormholeRelayer.getDefaultRelayProvider()); | ||
wormholeRelayer.forward(vaa.emitterChainId, vaa.emitterAddress, vaa.emitterAddress, maxTransactionFee, 0, 1); | ||
} | ||
} | ||
|
||
receive() external payable {} | ||
} | ||
|
||
contract DummyContract { | ||
IWormholeRelayer wormholeRelayer; | ||
|
||
constructor(address _wormholeRelayer) { | ||
wormholeRelayer = IWormholeRelayer(_wormholeRelayer); | ||
} | ||
|
||
function forward( | ||
uint16 chainId, | ||
bytes32 targetAddress, | ||
bytes32 refundAddress, | ||
uint256 maxTransactionFee, | ||
uint256 receiverValue, | ||
uint32 nonce | ||
) public { | ||
wormholeRelayer.forward(chainId, targetAddress, refundAddress, maxTransactionFee, receiverValue, nonce); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
// SPDX-License-Identifier: Apache 2 | ||
|
||
pragma solidity ^0.8.0; | ||
|
||
interface IWormholeRelayerInstructionParser { | ||
struct DeliveryInstructionsContainer { | ||
uint8 payloadId; //1 | ||
bool sufficientlyFunded; | ||
DeliveryInstruction[] instructions; | ||
} | ||
|
||
struct DeliveryInstruction { | ||
uint16 targetChain; | ||
bytes32 targetAddress; | ||
bytes32 refundAddress; | ||
uint256 maximumRefundTarget; | ||
uint256 receiverValueTarget; | ||
ExecutionParameters executionParameters; | ||
} | ||
|
||
struct ExecutionParameters { | ||
uint8 version; | ||
uint32 gasLimit; | ||
bytes32 providerDeliveryAddress; | ||
} | ||
|
||
struct RedeliveryByTxHashInstruction { | ||
uint8 payloadId; //2 | ||
uint16 sourceChain; | ||
bytes32 sourceTxHash; | ||
uint32 sourceNonce; | ||
uint16 targetChain; | ||
uint8 deliveryIndex; | ||
uint8 multisendIndex; | ||
uint256 newMaximumRefundTarget; | ||
uint256 newReceiverValueTarget; | ||
ExecutionParameters executionParameters; | ||
} | ||
|
||
function decodeDeliveryInstructionsContainer(bytes memory encoded) | ||
external | ||
pure | ||
returns (DeliveryInstructionsContainer memory); | ||
|
||
function decodeRedeliveryInstruction(bytes memory encoded) | ||
external | ||
pure | ||
returns (RedeliveryByTxHashInstruction memory instruction); | ||
|
||
function toWormholeFormat(address addr) external pure returns (bytes32 whFormat); | ||
|
||
function fromWormholeFormat(bytes32 whFormatAddress) external pure returns (address addr); | ||
} |
Oops, something went wrong.