Skip to content

Commit 8b00d62

Browse files
committed
evm: separate manager execution cost
1 parent 3a3ed59 commit 8b00d62

17 files changed

+557
-314
lines changed

evm/src/NativeTransfers/NonFungibleNttManager.sol

+16-1
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,19 @@ contract NonFungibleNttManager is INonFungibleNttManager, ManagerBase {
110110

111111
// =============== External Interface ==================================================
112112

113+
function quoteDeliveryPrice(
114+
uint16 recipientChain,
115+
bytes memory transceiverInstructions
116+
) public view virtual returns (uint256[] memory, uint256) {
117+
address[] memory enabledTransceivers = _getEnabledTransceiversStorage();
118+
119+
TransceiverStructs.TransceiverInstruction[] memory instructions = TransceiverStructs
120+
.parseTransceiverInstructions(transceiverInstructions, enabledTransceivers.length);
121+
122+
// TODO: Compute execution cost here.
123+
return _quoteDeliveryPrice(recipientChain, instructions, enabledTransceivers, 0);
124+
}
125+
113126
function transfer(
114127
uint256[] memory tokenIds,
115128
uint16 recipientChain,
@@ -213,12 +226,13 @@ contract NonFungibleNttManager is INonFungibleNttManager, ManagerBase {
213226
}
214227

215228
// Fetch quotes and prepare for transfer.
229+
// TODO: compute execution cost here.
216230
(
217231
address[] memory enabledTransceivers,
218232
TransceiverStructs.TransceiverInstruction[] memory instructions,
219233
uint256[] memory priceQuotes,
220234
uint256 totalPriceQuote
221-
) = _prepareForTransfer(recipientChain, transceiverInstructions);
235+
) = _prepareForTransfer(recipientChain, transceiverInstructions, 0);
222236

223237
uint64 sequence = _useMessageSequence();
224238

@@ -242,6 +256,7 @@ contract NonFungibleNttManager is INonFungibleNttManager, ManagerBase {
242256
recipientChain,
243257
_getPeersStorage()[recipientChain].peerAddress,
244258
priceQuotes,
259+
0,
245260
instructions,
246261
enabledTransceivers,
247262
encodedNttManagerPayload

evm/src/NativeTransfers/NttManager.sol

+16-1
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,19 @@ contract NttManager is INttManager, RateLimiter, ManagerBase {
142142

143143
// ==================== External Interface ===============================================
144144

145+
/// @inheritdoc INttManager
146+
function quoteDeliveryPrice(
147+
uint16 recipientChain,
148+
bytes memory transceiverInstructions
149+
) public view virtual returns (uint256[] memory, uint256) {
150+
address[] memory enabledTransceivers = _getEnabledTransceiversStorage();
151+
152+
TransceiverStructs.TransceiverInstruction[] memory instructions = TransceiverStructs
153+
.parseTransceiverInstructions(transceiverInstructions, enabledTransceivers.length);
154+
155+
return _quoteDeliveryPrice(recipientChain, instructions, enabledTransceivers, 0);
156+
}
157+
145158
/// @inheritdoc INttManager
146159
function transfer(
147160
uint256 amount,
@@ -394,12 +407,13 @@ contract NttManager is INttManager, RateLimiter, ManagerBase {
394407
address sender,
395408
bytes memory transceiverInstructions
396409
) internal returns (uint64 msgSequence) {
410+
// TODO: compute execution cost here.
397411
(
398412
address[] memory enabledTransceivers,
399413
TransceiverStructs.TransceiverInstruction[] memory instructions,
400414
uint256[] memory priceQuotes,
401415
uint256 totalPriceQuote
402-
) = _prepareForTransfer(recipientChain, transceiverInstructions);
416+
) = _prepareForTransfer(recipientChain, transceiverInstructions, 0);
403417

404418
// push it on the stack again to avoid a stack too deep error
405419
uint64 seq = sequence;
@@ -422,6 +436,7 @@ contract NttManager is INttManager, RateLimiter, ManagerBase {
422436
recipientChain,
423437
_getPeersStorage()[recipientChain].peerAddress,
424438
priceQuotes,
439+
0,
425440
instructions,
426441
enabledTransceivers,
427442
encodedNttManagerPayload

evm/src/NativeTransfers/shared/ManagerBase.sol

+12-11
Original file line numberDiff line numberDiff line change
@@ -84,14 +84,14 @@ abstract contract ManagerBase is
8484
}
8585
}
8686

87-
// =============== External Logic =============================================================
87+
// =============== Internal Logic ===========================================================
8888

89-
/// @inheritdoc IManagerBase
90-
function quoteDeliveryPrice(
89+
function _quoteDeliveryPrice(
9190
uint16 recipientChain,
9291
TransceiverStructs.TransceiverInstruction[] memory transceiverInstructions,
93-
address[] memory enabledTransceivers
94-
) public view returns (uint256[] memory, uint256) {
92+
address[] memory enabledTransceivers,
93+
uint256 managerExecutionCost
94+
) internal view returns (uint256[] memory, uint256) {
9595
uint256 numEnabledTransceivers = enabledTransceivers.length;
9696
mapping(address => TransceiverInfo) storage transceiverInfos = _getTransceiverInfosStorage();
9797

@@ -101,16 +101,14 @@ abstract contract ManagerBase is
101101
address transceiverAddr = enabledTransceivers[i];
102102
uint8 registeredTransceiverIndex = transceiverInfos[transceiverAddr].index;
103103
uint256 transceiverPriceQuote = ITransceiver(transceiverAddr).quoteDeliveryPrice(
104-
recipientChain, transceiverInstructions[registeredTransceiverIndex]
104+
recipientChain, transceiverInstructions[registeredTransceiverIndex], managerExecutionCost
105105
);
106106
priceQuotes[i] = transceiverPriceQuote;
107107
totalPriceQuote += transceiverPriceQuote;
108108
}
109109
return (priceQuotes, totalPriceQuote);
110110
}
111111

112-
// =============== Internal Logic ===========================================================
113-
114112
function _recordTransceiverAttestation(
115113
uint16 sourceChainId,
116114
TransceiverStructs.ManagerMessage memory payload
@@ -160,6 +158,7 @@ abstract contract ManagerBase is
160158
uint16 recipientChain,
161159
bytes32 peerAddress,
162160
uint256[] memory priceQuotes,
161+
uint256 managerExecutionCost,
163162
TransceiverStructs.TransceiverInstruction[] memory transceiverInstructions,
164163
address[] memory enabledTransceivers,
165164
bytes memory ManagerMessage
@@ -179,14 +178,16 @@ abstract contract ManagerBase is
179178
recipientChain,
180179
transceiverInstructions[transceiverInfos[transceiverAddr].index],
181180
ManagerMessage,
182-
peerAddress
181+
peerAddress,
182+
managerExecutionCost
183183
);
184184
}
185185
}
186186

187187
function _prepareForTransfer(
188188
uint16 recipientChain,
189-
bytes memory transceiverInstructions
189+
bytes memory transceiverInstructions,
190+
uint256 managerExecutionCost
190191
)
191192
internal
192193
returns (
@@ -214,7 +215,7 @@ abstract contract ManagerBase is
214215
}
215216

216217
(uint256[] memory priceQuotes, uint256 totalPriceQuote) =
217-
quoteDeliveryPrice(recipientChain, instructions, enabledTransceivers);
218+
_quoteDeliveryPrice(recipientChain, instructions, enabledTransceivers, managerExecutionCost);
218219
{
219220
// check up front that msg.value will cover the delivery price
220221
if (msg.value < totalPriceQuote) {

evm/src/Transceiver/Transceiver.sol

+9-4
Original file line numberDiff line numberDiff line change
@@ -95,21 +95,24 @@ abstract contract Transceiver is
9595
/// @inheritdoc ITransceiver
9696
function quoteDeliveryPrice(
9797
uint16 targetChain,
98-
TransceiverStructs.TransceiverInstruction memory instruction
98+
TransceiverStructs.TransceiverInstruction memory instruction,
99+
uint256 managerExecutionCost
99100
) external view returns (uint256) {
100-
return _quoteDeliveryPrice(targetChain, instruction);
101+
return _quoteDeliveryPrice(targetChain, instruction, managerExecutionCost);
101102
}
102103

103104
/// @inheritdoc ITransceiver
104105
function sendMessage(
105106
uint16 recipientChain,
106107
TransceiverStructs.TransceiverInstruction memory instruction,
107108
bytes memory ManagerMessage,
108-
bytes32 recipientNttManagerAddress
109+
bytes32 recipientNttManagerAddress,
110+
uint256 managerExecutionCost
109111
) external payable nonReentrant onlyNttManager {
110112
_sendMessage(
111113
recipientChain,
112114
msg.value,
115+
managerExecutionCost,
113116
msg.sender,
114117
recipientNttManagerAddress,
115118
instruction,
@@ -122,6 +125,7 @@ abstract contract Transceiver is
122125
function _sendMessage(
123126
uint16 recipientChain,
124127
uint256 deliveryPayment,
128+
uint256 managerExecutionCost,
125129
address caller,
126130
bytes32 recipientNttManagerAddress,
127131
TransceiverStructs.TransceiverInstruction memory transceiverInstruction,
@@ -147,6 +151,7 @@ abstract contract Transceiver is
147151

148152
function _quoteDeliveryPrice(
149153
uint16 targetChain,
150-
TransceiverStructs.TransceiverInstruction memory transceiverInstruction
154+
TransceiverStructs.TransceiverInstruction memory transceiverInstruction,
155+
uint256 managerExecutionCost
151156
) internal view virtual returns (uint256);
152157
}

evm/src/Transceiver/WormholeTransceiver/WormholeTransceiver.sol

+9-5
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ contract WormholeTransceiver is
3939
address wormholeRelayerAddr,
4040
address specialRelayerAddr,
4141
uint8 _consistencyLevel,
42-
uint256 _gasLimit,
42+
uint256 _attestationGasLimit,
4343
IWormholeTransceiverState.ManagerType _managerType
4444
)
4545
WormholeTransceiverState(
@@ -48,7 +48,7 @@ contract WormholeTransceiver is
4848
wormholeRelayerAddr,
4949
specialRelayerAddr,
5050
_consistencyLevel,
51-
_gasLimit,
51+
_attestationGasLimit,
5252
_managerType
5353
)
5454
{}
@@ -148,7 +148,8 @@ contract WormholeTransceiver is
148148

149149
function _quoteDeliveryPrice(
150150
uint16 targetChain,
151-
TransceiverStructs.TransceiverInstruction memory instruction
151+
TransceiverStructs.TransceiverInstruction memory instruction,
152+
uint256 managerExecutionCost
152153
) internal view override returns (uint256 nativePriceQuote) {
153154
// Check the special instruction up front to see if we should skip sending via a relayer
154155
WormholeTransceiverInstruction memory weIns =
@@ -163,7 +164,9 @@ contract WormholeTransceiver is
163164
}
164165

165166
if (_shouldRelayViaStandardRelaying(targetChain)) {
166-
(uint256 cost,) = wormholeRelayer.quoteEVMDeliveryPrice(targetChain, 0, gasLimit);
167+
(uint256 cost,) = wormholeRelayer.quoteEVMDeliveryPrice(
168+
targetChain, 0, attestationGasLimit + managerExecutionCost
169+
);
167170
return cost;
168171
} else if (isSpecialRelayingEnabled(targetChain)) {
169172
uint256 cost = specialRelayer.quoteDeliveryPrice(getNttManagerToken(), targetChain, 0);
@@ -176,6 +179,7 @@ contract WormholeTransceiver is
176179
function _sendMessage(
177180
uint16 recipientChain,
178181
uint256 deliveryPayment,
182+
uint256 managerExecutionCost,
179183
address caller,
180184
bytes32 recipientNttManagerAddress,
181185
TransceiverStructs.TransceiverInstruction memory instruction,
@@ -206,7 +210,7 @@ contract WormholeTransceiver is
206210
fromWormholeFormat(getWormholePeer(recipientChain)),
207211
encodedTransceiverPayload,
208212
0,
209-
gasLimit
213+
attestationGasLimit + managerExecutionCost
210214
);
211215

212216
emit RelayingInfo(uint8(RelayingType.Standard), deliveryPayment);

evm/src/Transceiver/WormholeTransceiver/WormholeTransceiverState.sol

+3-3
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ abstract contract WormholeTransceiverState is IWormholeTransceiverState, Transce
3333
IWormholeRelayer public immutable wormholeRelayer;
3434
ISpecialRelayer public immutable specialRelayer;
3535
uint256 immutable wormholeTransceiver_evmChainId;
36-
uint256 public immutable gasLimit;
36+
uint256 public immutable attestationGasLimit;
3737
ManagerType public immutable managerType;
3838

3939
// ==================== Constants ================================================
@@ -58,15 +58,15 @@ abstract contract WormholeTransceiverState is IWormholeTransceiverState, Transce
5858
address wormholeRelayerAddr,
5959
address specialRelayerAddr,
6060
uint8 _consistencyLevel,
61-
uint256 _gasLimit,
61+
uint256 _attestationGasLimit,
6262
ManagerType _managerType
6363
) Transceiver(nttManager) {
6464
wormhole = IWormhole(wormholeCoreBridge);
6565
wormholeRelayer = IWormholeRelayer(wormholeRelayerAddr);
6666
specialRelayer = ISpecialRelayer(specialRelayerAddr);
6767
wormholeTransceiver_evmChainId = block.chainid;
6868
consistencyLevel = _consistencyLevel;
69-
gasLimit = _gasLimit;
69+
attestationGasLimit = _attestationGasLimit;
7070
managerType = _managerType;
7171
}
7272

evm/src/interfaces/IManagerBase.sol

-9
Original file line numberDiff line numberDiff line change
@@ -109,15 +109,6 @@ interface IManagerBase {
109109
/// @param chainId The target chain id
110110
error PeerNotRegistered(uint16 chainId);
111111

112-
/// @notice Fetch the delivery price for a given recipient chain transfer.
113-
/// @param recipientChain The chain ID of the transfer destination.
114-
/// @return - The delivery prices associated with each endpoint and the total price.
115-
function quoteDeliveryPrice(
116-
uint16 recipientChain,
117-
TransceiverStructs.TransceiverInstruction[] memory transceiverInstructions,
118-
address[] memory enabledTransceivers
119-
) external view returns (uint256[] memory, uint256);
120-
121112
/// @notice Sets the threshold for the number of attestations required for a message
122113
/// to be considered valid.
123114
/// @param threshold The new threshold.

evm/src/interfaces/INonFungibleNttManager.sol

+9
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,15 @@ interface INonFungibleNttManager is IManagerBase {
8080

8181
function getMaxBatchSize() external pure returns (uint8);
8282

83+
/// @notice Fetch the delivery price for a given recipient chain transfer.
84+
/// @param recipientChain The chain ID of the transfer destination.
85+
/// @param transceiverInstructions The transceiver specific instructions for quoting and sending
86+
/// @return - The delivery prices associated with each enabled endpoint and the total price.
87+
function quoteDeliveryPrice(
88+
uint16 recipientChain,
89+
bytes memory transceiverInstructions
90+
) external view returns (uint256[] memory, uint256);
91+
8392
function transfer(
8493
uint256[] memory tokenIds,
8594
uint16 recipientChain,

evm/src/interfaces/INttManager.sol

+9
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,15 @@ interface INttManager is IManagerBase {
9898
/// @notice Peer cannot have zero decimals.
9999
error InvalidPeerDecimals();
100100

101+
/// @notice Fetch the delivery price for a given recipient chain transfer.
102+
/// @param recipientChain The chain ID of the transfer destination.
103+
/// @param transceiverInstructions The transceiver specific instructions for quoting and sending
104+
/// @return - The delivery prices associated with each enabled endpoint and the total price.
105+
function quoteDeliveryPrice(
106+
uint16 recipientChain,
107+
bytes memory transceiverInstructions
108+
) external view returns (uint256[] memory, uint256);
109+
101110
/// @notice Transfer a given amount to a recipient on a given chain. This function is called
102111
/// by the user to send the token cross-chain. This function will either lock or burn the
103112
/// sender's tokens. Finally, this function will call into registered `Endpoint` contracts

evm/src/interfaces/ITransceiver.sol

+10-2
Original file line numberDiff line numberDiff line change
@@ -41,23 +41,31 @@ interface ITransceiver {
4141
/// @param recipientChain The Wormhole chain ID of the target chain.
4242
/// @param instruction An additional Instruction provided by the Transceiver to be
4343
/// executed on the recipient chain.
44+
/// @param managerExecutionCost The cost of executing the manager message on the recipient chain.
45+
/// Depending on the target chain, the units may vary. For example, on Ethereum, this is
46+
/// the additional gas cost (in excess of the attestation cost) for executing the manager message.
4447
/// @return deliveryPrice The cost of delivering a message to the recipient chain,
4548
/// in this chain's native token.
4649
function quoteDeliveryPrice(
4750
uint16 recipientChain,
48-
TransceiverStructs.TransceiverInstruction memory instruction
51+
TransceiverStructs.TransceiverInstruction memory instruction,
52+
uint256 managerExecutionCost
4953
) external view returns (uint256);
5054

5155
/// @dev Send a message to another chain.
5256
/// @param recipientChain The Wormhole chain ID of the recipient.
5357
/// @param instruction An additional Instruction provided by the Transceiver to be
5458
/// executed on the recipient chain.
5559
/// @param ManagerMessage A message to be sent to the nttManager on the recipient chain.
60+
/// @param managerExecutionCost The cost of executing the manager message on the recipient chain.
61+
/// Depending on the target chain, the units may vary. For example, on Ethereum, this is
62+
/// the additional gas cost (in excess of the attestation cost) for executing the manager message.
5663
function sendMessage(
5764
uint16 recipientChain,
5865
TransceiverStructs.TransceiverInstruction memory instruction,
5966
bytes memory ManagerMessage,
60-
bytes32 recipientNttManagerAddress
67+
bytes32 recipientNttManagerAddress,
68+
uint256 managerExecutionCost
6169
) external payable;
6270

6371
/// @notice Upgrades the transceiver to a new implementation.

0 commit comments

Comments
 (0)