Skip to content

Commit

Permalink
AutoRelayer: cheap cross-chain refunds
Browse files Browse the repository at this point in the history
  • Loading branch information
JoeHowarth committed Aug 15, 2023
1 parent 5364ebb commit 9f185ad
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 62 deletions.
109 changes: 53 additions & 56 deletions ethereum/contracts/relayer/wormholeRelayer/WormholeRelayerDelivery.sol
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,17 @@ abstract contract WormholeRelayerDelivery is WormholeRelayerBase, IWormholeRelay
bytes memory deliveryOverrides
) public payable {

IWormhole.VM memory vm = getWormhole().parseVM(encodedDeliveryVAA);
DeliveryInstruction memory instruction = vm.payload.decodeDeliveryInstruction();

// Cross-chain refunds do not need to be verified
if (instruction.targetAddress == 0x0) {
handleCrossChainRefund(vm, instruction, relayerRefundAddress);
return;
}

// Parse and verify VAA containing delivery instructions, revert if invalid
(IWormhole.VM memory vm, bool valid, string memory reason) =
getWormhole().parseAndVerifyVM(encodedDeliveryVAA);
(bool valid, string memory reason) = getWormhole().verifyVM(vm);
if (!valid) {
revert InvalidDeliveryVaa(reason);
}
Expand All @@ -70,8 +78,6 @@ abstract contract WormholeRelayerDelivery is WormholeRelayerBase, IWormholeRelay
revert InvalidEmitter(vm.emitterAddress, registeredWormholeRelayer, vm.emitterChainId);
}

DeliveryInstruction memory instruction = vm.payload.decodeDeliveryInstruction();

DeliveryVAAInfo memory deliveryVaaInfo = DeliveryVAAInfo({
sourceChain: vm.emitterChainId,
sourceSequence: vm.sequence,
Expand Down Expand Up @@ -258,14 +264,6 @@ abstract contract WormholeRelayerDelivery is WormholeRelayerBase, IWormholeRelay
*/

function executeDelivery(DeliveryVAAInfo memory vaaInfo) private {

// If the targetAddress is the 0 address
// Then emit event and return
// (This is used for cross-chain refunds)
if (checkIfCrossChainRefund(vaaInfo)) {
return;
}

DeliveryResults memory results;

// Enforce replay protection
Expand Down Expand Up @@ -330,50 +328,6 @@ abstract contract WormholeRelayerDelivery is WormholeRelayerBase, IWormholeRelay
emitDeliveryEvent(vaaInfo, results);
}

function emitDeliveryEvent(DeliveryVAAInfo memory vaaInfo, DeliveryResults memory results) private {
emit Delivery(
fromWormholeFormat(vaaInfo.deliveryInstruction.targetAddress),
vaaInfo.sourceChain,
vaaInfo.sourceSequence,
vaaInfo.deliveryVaaHash,
results.status,
results.gasUsed,
payRefunds(
vaaInfo.deliveryInstruction,
vaaInfo.relayerRefundAddress,
(vaaInfo.gasLimit - results.gasUsed).toWei(vaaInfo.targetChainRefundPerGasUnused).asLocalNative(),
results.status
),
results.additionalStatusInfo,
(vaaInfo.redeliveryHash != 0) ? vaaInfo.encodedOverrides : new bytes(0)
);
}

function checkIfCrossChainRefund(DeliveryVAAInfo memory vaaInfo)
internal
returns (bool isCrossChainRefund)
{
if (vaaInfo.deliveryInstruction.targetAddress == 0x0) {
emit Delivery(
fromWormholeFormat(vaaInfo.deliveryInstruction.targetAddress),
vaaInfo.sourceChain,
vaaInfo.sourceSequence,
vaaInfo.deliveryVaaHash,
DeliveryStatus.SUCCESS,
Gas.wrap(0),
payRefunds(
vaaInfo.deliveryInstruction,
vaaInfo.relayerRefundAddress,
LocalNative.wrap(0),
DeliveryStatus.RECEIVER_FAILURE
),
bytes(""),
(vaaInfo.redeliveryHash != 0) ? vaaInfo.encodedOverrides : new bytes(0)
);
isCrossChainRefund = true;
}
}

function executeInstruction(EvmDeliveryInstruction memory evmInstruction)
external
returns (uint8 status, Gas gasUsed, bytes memory targetRevertDataTruncated)
Expand Down Expand Up @@ -427,6 +381,49 @@ abstract contract WormholeRelayerDelivery is WormholeRelayerBase, IWormholeRelay
}
}

function emitDeliveryEvent(DeliveryVAAInfo memory vaaInfo, DeliveryResults memory results) private {
emit Delivery(
fromWormholeFormat(vaaInfo.deliveryInstruction.targetAddress),
vaaInfo.sourceChain,
vaaInfo.sourceSequence,
vaaInfo.deliveryVaaHash,
results.status,
results.gasUsed,
payRefunds(
vaaInfo.deliveryInstruction,
vaaInfo.relayerRefundAddress,
(vaaInfo.gasLimit - results.gasUsed).toWei(vaaInfo.targetChainRefundPerGasUnused).asLocalNative(),
results.status
),
results.additionalStatusInfo,
(vaaInfo.redeliveryHash != 0) ? vaaInfo.encodedOverrides : new bytes(0)
);
}

function handleCrossChainRefund(
IWormhole.VM memory vm,
DeliveryInstruction memory deliveryInstruction,
address payable relayerRefundAddress
) internal {
RefundStatus refundStatus = payRefunds(
deliveryInstruction,
relayerRefundAddress,
LocalNative.wrap(0),
DeliveryStatus.RECEIVER_FAILURE
);
emit Delivery(
fromWormholeFormat(deliveryInstruction.targetAddress),
vm.emitterChainId,
vm.sequence,
vm.hash,
DeliveryStatus.SUCCESS,
Gas.wrap(0),
refundStatus,
bytes(""),
bytes("")
);
}

function payRefunds(
DeliveryInstruction memory deliveryInstruction,
address payable relayerRefundAddress,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,7 @@ abstract contract WormholeRelayerSend is WormholeRelayerBase, IWormholeRelayerSe
requestedReceiverValue: sendParams.receiverValue,
extraReceiverValue: provider.quoteAssetConversion(
sendParams.targetChain, sendParams.paymentForExtraReceiverValue
),
),
encodedExecutionInfo: encodedExecutionInfo,
refundChain: sendParams.refundChain,
refundAddress: sendParams.refundAddress,
Expand Down
10 changes: 6 additions & 4 deletions ethereum/forge-test/relayer/MockWormhole.sol
Original file line number Diff line number Diff line change
Expand Up @@ -207,12 +207,14 @@ contract MockWormhole is IWormhole {
return sequences[emitter];
}

function verifyVM(VM memory /*vm*/ )
function verifyVM(VM memory vm )
external
pure
returns (bool, /*valid*/ string memory /*reason*/ )
view
returns (bool valid, string memory reason )
{
revert("unsupported verifyVM in wormhole mock");
//behold the rigorous checking!
valid = !invalidVMs[vm.hash];
reason = "";
}

function verifySignatures(
Expand Down
1 change: 0 additions & 1 deletion ethereum/forge-test/relayer/WormholeRelayer.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -1312,7 +1312,6 @@ LocalNative forwardDeliveryCost;
*/

function invalidateVM(bytes memory message, WormholeSimulator simulator) internal {
change(message, message.length - 1);
simulator.invalidateVM(message);
}

Expand Down

0 comments on commit 9f185ad

Please sign in to comment.