Skip to content
This repository has been archived by the owner on May 23, 2023. It is now read-only.

Interface and Contract Changes for Step 1 of Permissionless Generic Relayer Plan #123

Draft
wants to merge 52 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
cb83fbb
Interface changes
derpy-duck Mar 22, 2023
fa50d9d
Permissionless version 1 implementation (#126)
derpy-duck Mar 24, 2023
737130d
New MessageInfo type with payload id when encoding
derpy-duck Mar 24, 2023
b9bef84
typescript and sdk hopefully build
derpy-duck Mar 24, 2023
6e0991e
typescript and sdk hopefully build
derpy-duck Mar 24, 2023
9f519ae
Fix redeliveryTest typescript error
derpy-duck Mar 24, 2023
cdaef45
Remove messages from redelivery instruction
derpy-duck Mar 24, 2023
0798e1a
Update specs/comments
derpy-duck Mar 24, 2023
b55f3d2
SDK updated - but not tested yet
derpy-duck Mar 24, 2023
6a89f7a
typo fix and sdk fix
derpy-duck Mar 27, 2023
7761ac6
Fix mock forge generic relayer to not use vaa hashes
derpy-duck Mar 27, 2023
d266e7c
sdk cleanup
derpy-duck Mar 28, 2023
00e49bb
Redeliveries removed
derpy-duck Mar 31, 2023
1bbf6b3
Feat: relayer engine v2 support + vaa fetching via manifest
JoeHowarth Mar 23, 2023
0675f91
cleanup
JoeHowarth Mar 24, 2023
306edbf
rebase on top of contract changes
JoeHowarth Mar 24, 2023
b165e49
save
JoeHowarth Apr 3, 2023
a2e2d37
Compiles w/o redelivery
JoeHowarth Apr 3, 2023
cf1fb8d
removing unused fields and checks
chase-45 Apr 3, 2023
2667a2d
added requesting sender to delivery container
chase-45 Apr 3, 2023
7b4d340
more redelivery code cleanup
chase-45 Apr 3, 2023
76553c3
null delivery address check
chase-45 Apr 3, 2023
7d30716
Forward wrapper (#129)
derpy-duck Apr 3, 2023
2316dd0
Relay provider is specified in the DeliveryInstructionsContainer, not…
derpy-duck Apr 4, 2023
d639d81
Move CoreRelayerStructs into its own interface file for organization
derpy-duck Apr 4, 2023
8746431
Remove outdated names
derpy-duck Apr 4, 2023
7e15094
Relay provider can set chains enabled and disabled
derpy-duck Apr 4, 2023
214736c
Typescript / relayer engine / sdk related changes; now blocked on a S…
derpy-duck Apr 4, 2023
42e6433
update relayer engine hash
JoeHowarth Apr 4, 2023
49103a0
messages -> messageInfos
derpy-duck Apr 5, 2023
9481113
Fix bug in 'rolloverChain' maximumRefund calculation
derpy-duck Apr 5, 2023
4313009
forge fmt
derpy-duck Apr 5, 2023
6012893
first cut at remote refunds
chase-45 Apr 5, 2023
aa90bc3
fixes
chase-45 Apr 5, 2023
b91b89c
asset conversion buffer is removed from refunds
chase-45 Apr 5, 2023
89d7251
Most tests pass
derpy-duck Apr 6, 2023
8737177
Add refundChain to encode/decode functions
derpy-duck Apr 6, 2023
58760cc
Logging in relayer engine processor
JoeHowarth Apr 6, 2023
9c6bf83
debugging (#130)
derpy-duck Apr 6, 2023
25f08b5
pkeys tilt
derpy-duck Apr 6, 2023
3886b7f
cross chain refunds, delivery data, payload additions
chase-45 Apr 6, 2023
65ecddf
Tests pass!
derpy-duck Apr 6, 2023
4df8b4d
return to old constants in test
derpy-duck Apr 6, 2023
b639509
Test for Cross chain refunds
derpy-duck Apr 6, 2023
44f35d1
Cross chain refund test works except the last assert
derpy-duck Apr 6, 2023
de7784b
same provider is now used for remote refunds
chase-45 Apr 7, 2023
c431650
delivery instructions contain the provider's target address rather th…
chase-45 Apr 8, 2023
b107a7d
IWormholeReceiver comments
chase-45 Apr 8, 2023
177e719
added IRelayProvider comments and others
chase-45 Apr 8, 2023
7e7594e
corrected outdated comments
chase-45 Apr 8, 2023
b9896fc
deliverydata test
chase-45 Apr 9, 2023
76adaed
remote refund does not revert test
chase-45 Apr 9, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
.idea
.vscode

**/pkeys.sh
**/pkeys_tilt.sh
**/pkeys.sh
277 changes: 133 additions & 144 deletions ethereum/contracts/coreRelayer/CoreRelayer.sol

Large diffs are not rendered by default.

523 changes: 233 additions & 290 deletions ethereum/contracts/coreRelayer/CoreRelayerDelivery.sol

Large diffs are not rendered by default.

9 changes: 6 additions & 3 deletions ethereum/contracts/coreRelayer/CoreRelayerGetters.sol
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
// contracts/Getters.sol
// SPDX-License-Identifier: Apache 2

pragma solidity ^0.8.0;

import "../interfaces/IWormhole.sol";
import "../interfaces/IRelayProvider.sol";
import "./CoreRelayerStructs.sol";
import "../interfaces/IWormholeRelayerInternalStructs.sol";

import "./CoreRelayerState.sol";
import "../libraries/external/BytesLib.sol";
Expand Down Expand Up @@ -53,10 +52,14 @@ contract CoreRelayerGetters is CoreRelayerState {
return _state.defaultRelayProvider;
}

function getForwardInstruction() internal view returns (CoreRelayerStructs.ForwardInstruction memory) {
function getForwardInstruction() public view returns (IWormholeRelayerInternalStructs.ForwardInstruction memory) {
return _state.forwardInstruction;
}

function getWormholeRelayerCallerAddress() public view returns (address) {
return _state.forwardWrapper;
}

function isContractLocked() internal view returns (bool) {
return _state.contractLock;
}
Expand Down
3 changes: 1 addition & 2 deletions ethereum/contracts/coreRelayer/CoreRelayerGovernance.sol
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
// contracts/Relayer.sol
// SPDX-License-Identifier: Apache 2

pragma solidity ^0.8.0;
Expand All @@ -9,7 +8,7 @@ import "../libraries/external/BytesLib.sol";

import "./CoreRelayerGetters.sol";
import "./CoreRelayerSetters.sol";
import "./CoreRelayerStructs.sol";
import "../interfaces/IWormholeRelayerInternalStructs.sol";
import "./CoreRelayerMessages.sol";

import "../interfaces/IWormhole.sol";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
// contracts/Implementation.sol
// SPDX-License-Identifier: Apache 2

pragma solidity ^0.8.0;
Expand Down
381 changes: 163 additions & 218 deletions ethereum/contracts/coreRelayer/CoreRelayerMessages.sol

Large diffs are not rendered by default.

1 change: 0 additions & 1 deletion ethereum/contracts/coreRelayer/CoreRelayerProxy.sol
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
// contracts/Wormhole.sol
// SPDX-License-Identifier: Apache 2

pragma solidity ^0.8.0;
Expand Down
9 changes: 6 additions & 3 deletions ethereum/contracts/coreRelayer/CoreRelayerSetters.sol
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
// contracts/Setters.sol
// SPDX-License-Identifier: Apache 2

pragma solidity ^0.8.0;

import "./CoreRelayerState.sol";
import "@openzeppelin/contracts/utils/Context.sol";
import "./CoreRelayerStructs.sol";
import "../interfaces/IWormholeRelayerInternalStructs.sol";
import {IWormhole} from "../interfaces/IWormhole.sol";

contract CoreRelayerSetters is CoreRelayerState, Context {
Expand Down Expand Up @@ -43,7 +42,7 @@ contract CoreRelayerSetters is CoreRelayerState, Context {
_state.registeredCoreRelayerContract[chainId] = relayerAddress;
}

function setForwardInstruction(CoreRelayerStructs.ForwardInstruction memory request) internal {
function setForwardInstruction(IWormholeRelayerInternalStructs.ForwardInstruction memory request) internal {
_state.forwardInstruction = request;
}

Expand All @@ -59,6 +58,10 @@ contract CoreRelayerSetters is CoreRelayerState, Context {
_state.targetAddress = targetAddress;
}

function setForwardWrapper(address newForwardWrapperAddress) internal {
_state.forwardWrapper = newForwardWrapperAddress;
}

function setEvmChainId(uint256 evmChainId) internal {
if (evmChainId != block.chainid) {
revert InvalidEvmChainId();
Expand Down
4 changes: 3 additions & 1 deletion ethereum/contracts/coreRelayer/CoreRelayerSetup.sol
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
// contracts/Setup.sol
// SPDX-License-Identifier: Apache 2

pragma solidity ^0.8.0;

import "./CoreRelayerGovernance.sol";
import "./ForwardWrapper.sol";

import "@openzeppelin/contracts/proxy/ERC1967/ERC1967Upgrade.sol";

Expand Down Expand Up @@ -43,6 +43,8 @@ contract CoreRelayerSetup is CoreRelayerSetters, ERC1967Upgrade {
setGovernanceContract(governanceContract);
setEvmChainId(evmChainId);

setForwardWrapper(address(new ForwardWrapper(address(this), wormhole)));

_upgradeTo(implementation);

// call initialize function of the new implementation
Expand Down
7 changes: 4 additions & 3 deletions ethereum/contracts/coreRelayer/CoreRelayerState.sol
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
// contracts/State.sol
// SPDX-License-Identifier: Apache 2

pragma solidity ^0.8.0;

import "./CoreRelayerStructs.sol";
import "../interfaces/IWormholeRelayerInternalStructs.sol";

contract CoreRelayerStorage {
struct Provider {
Expand All @@ -26,7 +25,9 @@ contract CoreRelayerStorage {
// address of the default relay provider on this chain
address defaultRelayProvider;
// Request which will be forwarded from the current delivery.
CoreRelayerStructs.ForwardInstruction forwardInstruction;
IWormholeRelayerInternalStructs.ForwardInstruction forwardInstruction;
// Wrapper contract to facilitate forwards
address forwardWrapper;
// mapping of initialized implementations
mapping(address => bool) initializedImplementations;
// mapping of relayer contracts on other chains
Expand Down
73 changes: 73 additions & 0 deletions ethereum/contracts/coreRelayer/ForwardWrapper.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
// SPDX-License-Identifier: Apache 2

pragma solidity ^0.8.0;

import "../interfaces/IWormholeReceiver.sol";
import "../interfaces/IWormhole.sol";
import "../interfaces/IRelayProvider.sol";
import "../interfaces/IForwardInstructionViewer.sol";
import "../interfaces/IWormholeRelayerInternalStructs.sol";
import "../interfaces/IForwardWrapper.sol";
import "../interfaces/IWormholeReceiver.sol";
import "../interfaces/IRelayProvider.sol";

contract ForwardWrapper {
IForwardInstructionViewer forwardInstructionViewer;
IWormhole wormhole;

error RequesterNotCoreRelayer();
error ForwardNotSufficientlyFunded(uint256 amountOfFunds, uint256 amountOfFundsNeeded);

constructor(address _wormholeRelayer, address _wormhole) {
forwardInstructionViewer = IForwardInstructionViewer(_wormholeRelayer);
wormhole = IWormhole(_wormhole);
}

function executeInstruction(
IWormholeRelayerInternalStructs.DeliveryInstruction memory instruction,
IWormholeReceiver.DeliveryData memory data,
bytes[] memory signedVaas
) public payable returns (bool callToTargetContractSucceeded, uint256 transactionFeeRefundAmount) {
if (msg.sender != address(forwardInstructionViewer)) {
revert RequesterNotCoreRelayer();
}

uint256 preGas = gasleft();

// Calls the 'receiveWormholeMessages' endpoint on the contract 'instruction.targetAddress'
// (with the gas limit and value specified in instruction, and 'encodedVMs' as the input)
(callToTargetContractSucceeded,) = forwardInstructionViewer.fromWormholeFormat(instruction.targetAddress).call{
gas: instruction.executionParameters.gasLimit,
value: instruction.receiverValueTarget
}(abi.encodeCall(IWormholeReceiver.receiveWormholeMessages, ((data), signedVaas)));

uint256 postGas = gasleft();

// Calculate the amount of gas used in the call (upperbounding at the gas limit, which shouldn't have been exceeded)
uint256 gasUsed = (preGas - postGas) > instruction.executionParameters.gasLimit
? instruction.executionParameters.gasLimit
: (preGas - postGas);

// Calculate the amount of maxTransactionFee to refund (multiply the maximum refund by the fraction of gas unused)
transactionFeeRefundAmount = (instruction.executionParameters.gasLimit - gasUsed)
* instruction.maximumRefundTarget / instruction.executionParameters.gasLimit;

IWormholeRelayerInternalStructs.ForwardInstruction memory forwardInstruction =
forwardInstructionViewer.getForwardInstruction();

if (forwardInstruction.isValid) {
uint256 feeForForward = transactionFeeRefundAmount + forwardInstruction.msgValue;
if (feeForForward < forwardInstruction.totalFee) {
revert ForwardNotSufficientlyFunded(feeForForward, forwardInstruction.totalFee);
}
}

if (!callToTargetContractSucceeded) {
msg.sender.call{value: msg.value}("");
}
}

function safeRelayProviderSupportsChain(IRelayProvider relayProvider, uint16 chainId) view external returns (bool isSupported){
return relayProvider.isChainSupported(chainId);
}
}
15 changes: 11 additions & 4 deletions ethereum/contracts/example_integrations/xMint/Hub.sol
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,11 @@ contract XmintHub is ERC20, IWormholeReceiver {
}

//This is the function which receives all messages from the remote contracts.
function receiveWormholeMessages(bytes[] memory vaas, bytes[] memory additionalData) public payable override {
function receiveWormholeMessages(IWormholeReceiver.DeliveryData memory deliveryData, bytes[] memory vaas)
public
payable
override
{
//The first message should be from the token bridge, so attempt to redeem it.
ITokenBridge.TransferWithPayload memory transferResult =
token_bridge.parseTransferWithPayload(token_bridge.completeTransferWithPayload(vaas[0]));
Expand Down Expand Up @@ -90,18 +94,21 @@ contract XmintHub is ERC20, IWormholeReceiver {
core_relayer.quoteGas(targetChain, SAFE_DELIVERY_GAS_CAPTURE, core_relayer.getDefaultRelayProvider());
uint256 receiverValue = 0;

bytes memory emptyArray;
IWormholeRelayer.Send memory request = IWormholeRelayer.Send({
targetChain: targetChain,
targetAddress: trustedContracts[targetChain],
refundChain: targetChain,
refundAddress: intendedRecipient, // All remaining funds will be returned to the user now
maxTransactionFee: maxTransactionFee,
receiverValue: receiverValue, // not needed in this case.
payload: emptyArray,
relayParameters: core_relayer.getDefaultRelayParams() //no overrides
});

core_relayer.send{value: maxTransactionFee + receiverValue}(
request, nonce, core_relayer.getDefaultRelayProvider()
);
// core_relayer.send{value: maxTransactionFee + receiverValue}(
// request, nonce, core_relayer.getDefaultRelayProvider()
//);
}

//This function calculates how many tokens should be minted to the end user based on how much
Expand Down
15 changes: 11 additions & 4 deletions ethereum/contracts/example_integrations/xMint/Spoke.sol
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,11 @@ contract XmintSpoke is IWormholeReceiver {
}

//This function receives messages back from the Hub contract and distributes the tokens to the user.
function receiveWormholeMessages(bytes[] memory vaas, bytes[] memory additionalData) public payable override {
function receiveWormholeMessages(IWormholeReceiver.DeliveryData memory deliveryData, bytes[] memory vaas)
public
payable
override
{
//Complete the token bridge transfer
ITokenBridge.TransferWithPayload memory transferResult =
token_bridge.parseTransferWithPayload(token_bridge.completeTransferWithPayload(vaas[0]));
Expand All @@ -88,18 +92,21 @@ contract XmintSpoke is IWormholeReceiver {
core_relayer.quoteGas(hub_contract_chain, SAFE_DELIVERY_GAS_CAPTURE, core_relayer.getDefaultRelayProvider());
uint256 receiverValue = 0;

bytes memory emptyArray;
IWormholeRelayer.Send memory request = IWormholeRelayer.Send({
targetChain: hub_contract_chain,
targetAddress: hub_contract_address,
refundChain: hub_contract_chain,
refundAddress: hub_contract_address, // This will be ignored on the target chain because the intent is to perform a forward
maxTransactionFee: maxTransactionFee,
receiverValue: receiverValue, // not needed in this case.
payload: emptyArray,
relayParameters: core_relayer.getDefaultRelayParams() //no overrides
});

core_relayer.send{value: maxTransactionFee + receiverValue}(
request, nonce, core_relayer.getDefaultRelayProvider()
);
//core_relayer.send{value: maxTransactionFee + receiverValue}(
// request, nonce, core_relayer.getDefaultRelayProvider()
//);
}

function bytesToBytes32(bytes memory b, uint256 offset) private pure returns (bytes32) {
Expand Down
Loading