Skip to content

Commit c162df7

Browse files
committed
gRelayer: make relayprovider calls safe (#2822)
* gRelayer-make-relay-provider-calls-safe * gRelayer-remove-unnecessary-code * gRelayer: attempt 1 at getting under contract size * gRelayer: uer contract size limit * forge fmt * gRelayer: Address nits in PR
1 parent 163af78 commit c162df7

8 files changed

+164
-108
lines changed

ethereum/contracts/interfaces/relayer/IForwardWrapper.sol

+6-4
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,10 @@ interface IForwardWrapper {
1313
bytes[] memory signedVaas
1414
) external payable returns (bool callToTargetContractSucceeded, uint256 transactionFeeRefundAmount);
1515

16-
function safeRelayProviderSupportsChain(IRelayProvider relayProvider, uint16 chainId)
17-
external
18-
view
19-
returns (bool isSupported);
16+
function getValuesFromRelayProvider(
17+
address providerAddress,
18+
uint16 sourceChain,
19+
uint16 targetChain,
20+
uint256 receiverValuePlusOverhead
21+
) external view returns (address rewardAddress, uint256 maximumBudget, uint256 receiverValueTarget);
2022
}

ethereum/contracts/interfaces/relayer/IWormholeRelayerInternalStructs.sol

+1-2
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ interface IWormholeRelayerInternalStructs {
5353

5454
struct DeliveryInternalVariables {
5555
uint256 preGas;
56-
uint256 postGas;
56+
uint256 postGas;
5757
bool callToInstructionExecutorSucceeded;
5858
bytes callToInstructionExecutorData;
5959
uint256 transactionFeeRefundAmount;
@@ -64,5 +64,4 @@ interface IWormholeRelayerInternalStructs {
6464
bytes additionalStatusInfo;
6565
bytes overridesInfo;
6666
}
67-
6867
}

ethereum/contracts/relayer/coreRelayer/CoreRelayer.sol

+1-1
Original file line numberDiff line numberDiff line change
@@ -390,7 +390,7 @@ abstract contract CoreRelayer is CoreRelayerDelivery {
390390
// and applies a multiplier of '1 + (buffer / denominator)'
391391
(uint16 buffer, uint16 denominator) = provider.getAssetConversionBuffer(targetChain);
392392
receiverValue = assetConversionHelper(
393-
targetChain, targetAmount, chainId(), uint256(0) + denominator + buffer, denominator, true, provider
393+
targetChain, targetAmount, chainId(), uint256(denominator) + buffer, denominator, true, provider
394394
);
395395
}
396396

ethereum/contracts/relayer/coreRelayer/CoreRelayerDelivery.sol

+122-82
Large diffs are not rendered by default.

ethereum/contracts/relayer/coreRelayer/CoreRelayerLibrary.sol

+1-1
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,7 @@ contract CoreRelayerLibrary is CoreRelayerState, ERC1967Upgrade {
262262
}
263263

264264
function truncateReturnData(bytes memory returnData) internal pure returns (bytes memory returnDataTruncated) {
265-
if(returnData.length <= 124) {
265+
if (returnData.length <= 124) {
266266
returnDataTruncated = returnData;
267267
} else {
268268
returnDataTruncated = returnData.slice(0, 124);

ethereum/contracts/relayer/coreRelayer/CoreRelayerMessages.sol

+1-1
Original file line numberDiff line numberDiff line change
@@ -515,7 +515,7 @@ abstract contract CoreRelayerMessages is CoreRelayerGetters {
515515
index += 32;
516516

517517
output.targetChain = encoded.toUint16(index);
518-
index+=2;
518+
index += 2;
519519

520520
output.executionParameters.version = 1;
521521
index += 1;

ethereum/contracts/relayer/coreRelayer/ForwardWrapper.sol

+30-16
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,9 @@ pragma solidity ^0.8.0;
44

55
import "../../interfaces/relayer/IWormholeReceiver.sol";
66
import "../../interfaces/IWormhole.sol";
7-
import "../../interfaces/relayer/IRelayProvider.sol";
87
import "../../interfaces/relayer/IForwardInstructionViewer.sol";
98
import "../../interfaces/relayer/IWormholeRelayerInternalStructs.sol";
109
import "../../interfaces/relayer/IForwardWrapper.sol";
11-
import "../../interfaces/relayer/IWormholeReceiver.sol";
12-
import "../../interfaces/relayer/IRelayProvider.sol";
1310
import {CoreRelayerLibrary} from "../coreRelayer/CoreRelayerLibrary.sol";
1411

1512
contract ForwardWrapper is CoreRelayerLibrary {
@@ -31,18 +28,21 @@ contract ForwardWrapper is CoreRelayerLibrary {
3128
// Calls the 'receiveWormholeMessages' endpoint on the contract 'instruction.targetAddress'
3229
// (with the gas limit and value specified in instruction, and 'encodedVMs' as the input)
3330
bytes memory returnData;
34-
(callToTargetContractSucceeded, returnData) = forwardInstructionViewer.fromWormholeFormat(instruction.targetAddress).call{
35-
gas: instruction.executionParameters.gasLimit,
36-
value: instruction.receiverValueTarget
37-
}(abi.encodeWithSelector(IWormholeReceiver.receiveWormholeMessages.selector, data, signedVaas));
31+
(callToTargetContractSucceeded, returnData) = forwardInstructionViewer.fromWormholeFormat(
32+
instruction.targetAddress
33+
).call{gas: instruction.executionParameters.gasLimit, value: instruction.receiverValueTarget}(
34+
abi.encodeWithSelector(IWormholeReceiver.receiveWormholeMessages.selector, data, signedVaas)
35+
);
3836

3937
uint256 postGas = gasleft();
4038

4139
returnDataTruncated = callToTargetContractSucceeded ? bytes("") : truncateReturnData(returnData);
4240
// Calculate the amount of gas used in the call (upperbounding at the gas limit, which shouldn't have been exceeded)
43-
gasUsed = uint32((preGas - postGas) > instruction.executionParameters.gasLimit
44-
? instruction.executionParameters.gasLimit
45-
: (preGas - postGas));
41+
gasUsed = uint32(
42+
(preGas - postGas) > instruction.executionParameters.gasLimit
43+
? instruction.executionParameters.gasLimit
44+
: (preGas - postGas)
45+
);
4646

4747
// Calculate the amount of maxTransactionFee to refund (multiply the maximum refund by the fraction of gas unused)
4848
uint256 transactionFeeRefundAmount = (instruction.executionParameters.gasLimit - gasUsed)
@@ -68,11 +68,25 @@ contract ForwardWrapper is CoreRelayerLibrary {
6868
}
6969
}
7070

71-
function safeRelayProviderSupportsChain(IRelayProvider relayProvider, uint16 chainId)
72-
external
73-
view
74-
returns (bool isSupported)
75-
{
76-
return relayProvider.isChainSupported(chainId);
71+
function getValuesFromRelayProvider(
72+
address providerAddress,
73+
uint16 sourceChain,
74+
uint16 targetChain,
75+
uint256 receiverValuePlusOverhead
76+
) public view returns (address rewardAddress, uint256 maximumBudget, uint256 receiverValueTarget) {
77+
IRelayProvider relayProvider = IRelayProvider(providerAddress);
78+
require(relayProvider.isChainSupported(targetChain));
79+
uint256 deliveryOverhead = relayProvider.quoteDeliveryOverhead(targetChain);
80+
rewardAddress = relayProvider.getRewardAddress();
81+
maximumBudget = relayProvider.quoteMaximumBudget(targetChain);
82+
uint256 srcNativeCurrencyPrice = relayProvider.quoteAssetPrice(sourceChain);
83+
uint256 dstNativeCurrencyPrice = relayProvider.quoteAssetPrice(targetChain);
84+
(uint16 buffer, uint16 denominator) = relayProvider.getAssetConversionBuffer(targetChain);
85+
receiverValueTarget = receiverValuePlusOverhead > deliveryOverhead
86+
? (
87+
(receiverValuePlusOverhead - deliveryOverhead) * srcNativeCurrencyPrice * denominator
88+
/ (dstNativeCurrencyPrice * (uint256(0) + denominator + buffer))
89+
)
90+
: 0;
7791
}
7892
}

ethereum/forge-test/relayer/WormholeRelayer.t.sol

+2-1
Original file line numberDiff line numberDiff line change
@@ -980,6 +980,7 @@ contract WormholeRelayerTests is Test {
980980
refundSource = (amountToGetInRefundTarget - target.relayProvider.quoteDeliveryOverhead(1))
981981
* feeParams.targetNativePrice * 100 / (uint256(1) * feeParams.sourceNativePrice * 105);
982982
}
983+
983984
assertTrue(
984985
refundSource == source.refundAddress.balance - refundAddressBalance, "Refund wasn't the correct amount"
985986
);
@@ -1054,12 +1055,12 @@ contract WormholeRelayerTests is Test {
10541055
- ((amountToGetInRefundTarget + feeParams.wormholeFeeOnTarget - receiverValueTargetActual)) * actualGasLimit
10551056
/ maximumRefund
10561057
);
1057-
10581058
uint256 refundSource = 0;
10591059
if (amountToGetInRefundTarget > target.relayProvider.quoteDeliveryOverhead(1)) {
10601060
refundSource = (amountToGetInRefundTarget - target.relayProvider.quoteDeliveryOverhead(1))
10611061
* feeParams.targetNativePrice * 100 / (uint256(1) * feeParams.sourceNativePrice * 105);
10621062
}
1063+
10631064
assertTrue(
10641065
refundSource == source.refundAddress.balance - refundAddressBalance, "Refund wasn't the correct amount"
10651066
);

0 commit comments

Comments
 (0)