Skip to content

Commit

Permalink
evm: Use executor
Browse files Browse the repository at this point in the history
  • Loading branch information
bruce-riley committed Dec 13, 2024
1 parent 9baf53b commit 42d28a7
Show file tree
Hide file tree
Showing 17 changed files with 359 additions and 164 deletions.
5 changes: 3 additions & 2 deletions evm/src/NttManager/ManagerBase.sol
Original file line number Diff line number Diff line change
Expand Up @@ -104,9 +104,10 @@ abstract contract ManagerBase is

/// @inheritdoc IManagerBase
function quoteDeliveryPrice(
uint16 recipientChain
uint16 recipientChain,
bytes memory transceiverInstructions
) public view returns (uint256) {
return endpoint.quoteDeliveryPrice(recipientChain); // TODO: Add in executor delivery price.
return endpoint.quoteDeliveryPrice(recipientChain, transceiverInstructions);
}

// =============== Internal Logic ===========================================================
Expand Down
164 changes: 102 additions & 62 deletions evm/src/NttManager/NttManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -185,10 +185,19 @@ contract NttManager is INttManager, RateLimiter, ManagerBase {
uint256 amount,
uint16 recipientChain,
bytes32 recipient,
bytes calldata executorQuote
bytes calldata executorQuote,
bytes calldata relayInstructions,
bytes calldata transceiverInstructions
) external payable nonReentrant whenNotPaused returns (uint64) {
return _transferEntryPoint(
amount, recipientChain, recipient, recipient, false, executorQuote, new bytes(0)
amount,
recipientChain,
recipient,
recipient,
false,
executorQuote,
relayInstructions,
transceiverInstructions
);
}

Expand All @@ -200,7 +209,8 @@ contract NttManager is INttManager, RateLimiter, ManagerBase {
bytes32 refundAddress,
bool shouldQueue,
bytes calldata executorQuote,
bytes memory relayInstructions
bytes calldata relayInstructions,
bytes calldata transceiverInstructions
) external payable nonReentrant whenNotPaused returns (uint64) {
return _transferEntryPoint(
amount,
Expand All @@ -209,7 +219,8 @@ contract NttManager is INttManager, RateLimiter, ManagerBase {
refundAddress,
shouldQueue,
executorQuote,
relayInstructions
relayInstructions,
transceiverInstructions
);
}

Expand Down Expand Up @@ -387,7 +398,8 @@ contract NttManager is INttManager, RateLimiter, ManagerBase {
queuedTransfer.refundAddress,
queuedTransfer.sender,
queuedTransfer.executorQuote,
queuedTransfer.relayInstructions
queuedTransfer.relayInstructions,
queuedTransfer.transceiverInstructions
);
}

Expand Down Expand Up @@ -424,7 +436,8 @@ contract NttManager is INttManager, RateLimiter, ManagerBase {
bytes32 refundAddress,
bool shouldQueue,
bytes memory executorQuote,
bytes memory relayInstructions
bytes memory relayInstructions,
bytes memory transceiverInstructions
) internal returns (uint64) {
if (amount == 0) {
revert ZeroAmount();
Expand Down Expand Up @@ -490,6 +503,7 @@ contract NttManager is INttManager, RateLimiter, ManagerBase {
shouldQueue,
executorQuote,
relayInstructions,
transceiverInstructions,
trimmedAmount,
sequence
);
Expand All @@ -506,7 +520,8 @@ contract NttManager is INttManager, RateLimiter, ManagerBase {
refundAddress,
msg.sender,
executorQuote,
relayInstructions
relayInstructions,
transceiverInstructions
);
}

Expand All @@ -518,6 +533,7 @@ contract NttManager is INttManager, RateLimiter, ManagerBase {
bool shouldQueue,
bytes memory executorQuote,
bytes memory relayInstructions,
bytes memory transceiverInstructions,
TrimmedAmount trimmedAmount,
uint64 sequence
) internal virtual returns (bool enqueued) {
Expand Down Expand Up @@ -546,13 +562,14 @@ contract NttManager is INttManager, RateLimiter, ManagerBase {
refundAddress,
msg.sender,
executorQuote,
relayInstructions
relayInstructions,
transceiverInstructions
);

// refund price quote back to sender
_refundToSender(msg.value);

// return that the transfer has been enqued
// return that the transfer has been enqueued
return true;
}

Expand All @@ -572,100 +589,123 @@ contract NttManager is INttManager, RateLimiter, ManagerBase {
bytes32 refundAddress,
address sender,
bytes memory executorQuote,
bytes memory relayInstructions
bytes memory relayInstructions,
bytes memory transceiverInstructions
) internal returns (uint64 msgSequence) {
// verify chain has not forked
checkFork(evmChainId);

// Compute the quote price and refund user excess value from msg.value
uint256 epTotalPriceQuote = quoteAndRefund(recipientChain);
uint256 epTotalPriceQuote = quoteAndRefund(recipientChain, transceiverInstructions);

// push it on the stack again to avoid a stack too deep error
uint64 seq = sequence;
TrimmedAmount amt = amount;
bytes32 recip = recipient;
bytes32 refundAddr = refundAddress;
return _transfer(
_TransferArgs({
sequence: sequence,
amount: amount,
recipientChain: recipientChain,
recipient: recipient,
refundAddress: refundAddress,
sender: sender,
executorQuote: executorQuote,
relayInstructions: relayInstructions,
transceiverInstructions: transceiverInstructions,
epTotalPriceQuote: epTotalPriceQuote
})
);
}

bytes memory encodedNttManagerPayload =
buildEncodedPayload(amt, recip, recipientChain, seq, sender, refundAddr);
/// @dev Used to get around "stack too deep.
struct _TransferArgs {
uint64 sequence;
TrimmedAmount amount;
uint16 recipientChain;
bytes32 recipient;
bytes32 refundAddress;
address sender;
bytes executorQuote;
bytes relayInstructions;
bytes transceiverInstructions;
uint256 epTotalPriceQuote;
}

// push onto the stack again to avoid stack too deep error
uint16 destinationChain = recipientChain;
function _transfer(
_TransferArgs memory args
) internal returns (uint64 msgSequence) {
bytes memory encodedNttManagerPayload = buildEncodedPayload(args);

// send the message
bytes32 payloadHash = keccak256(encodedNttManagerPayload);
endpoint.sendMessage{value: epTotalPriceQuote}(
destinationChain,
UniversalAddressLibrary.fromBytes32(_getPeersStorage()[destinationChain].peerAddress),
endpoint.sendMessage{value: args.epTotalPriceQuote}(
args.recipientChain,
UniversalAddressLibrary.fromBytes32(_getPeersStorage()[args.recipientChain].peerAddress),
payloadHash,
UniversalAddressLibrary.toAddress(UniversalAddressLibrary.fromBytes32(refundAddr))
UniversalAddressLibrary.toAddress(
UniversalAddressLibrary.fromBytes32(args.refundAddress)
),
args.transceiverInstructions
);

emit TransferSent(
recip,
refundAddr,
amt.untrim(tokenDecimals()),
epTotalPriceQuote,
destinationChain,
seq,
args.recipient,
args.refundAddress,
args.amount.untrim(tokenDecimals()),
args.epTotalPriceQuote,
args.recipientChain,
args.sequence,
payloadHash
);

bytes memory execQuote = executorQuote;

uint128 gasLimit = _getPeersStorage()[destinationChain].gasLimit;
uint128 gasLimit = _getPeersStorage()[args.recipientChain].gasLimit;
if (gasLimit == 0) {
revert InvalidGasLimitZero(destinationChain);
revert InvalidGasLimitZero(args.recipientChain);
}

bytes memory ri = RelayInstructions.encodeGas(gasLimit, 0);
if (relayInstructions.length != 0) {
ri = abi.encodePacked(ri, relayInstructions);
bytes memory relayInstructions = RelayInstructions.encodeGas(gasLimit, 0);
if (args.relayInstructions.length != 0) {
relayInstructions = abi.encodePacked(relayInstructions, args.relayInstructions);
}

executor.requestExecution(
destinationChain,
recip,
UniversalAddressLibrary.fromBytes32(refundAddr).toAddress(),
execQuote,
args.recipientChain,
args.recipient,
UniversalAddressLibrary.fromBytes32(args.refundAddress).toAddress(),
args.executorQuote,
encodedNttManagerPayload,
ri
relayInstructions
);

// return the sequence number
return seq;
return args.sequence;
}

function quoteAndRefund(
uint16 recipientChain
uint16 recipientChain,
bytes memory transceiverInstructions
) internal returns (uint256 epTotalPriceQuote) {
// refund user excess value from msg.value
epTotalPriceQuote = quoteDeliveryPrice(recipientChain);
// Check for negative value.
{
uint256 excessValue = msg.value - epTotalPriceQuote;
if (excessValue > 0) {
_refundToSender(excessValue);
}
epTotalPriceQuote = quoteDeliveryPrice(recipientChain, transceiverInstructions);
uint256 excessValue = msg.value - epTotalPriceQuote;
if (excessValue > 0) {
_refundToSender(excessValue);
}
}

function buildEncodedPayload(
TrimmedAmount amount,
bytes32 recipient,
uint16 recipientChain,
uint64 seq,
address sender,
bytes32 refundAddr
_TransferArgs memory args
) internal returns (bytes memory encodedNttManagerPayload) {
TransceiverStructs.NativeTokenTransfer memory ntt =
_prepareNativeTokenTransfer(amount, recipient, recipientChain, seq, sender, refundAddr);
TransceiverStructs.NativeTokenTransfer memory ntt = _prepareNativeTokenTransfer(
args.amount,
args.recipient,
args.recipientChain,
args.sequence,
args.sender,
args.refundAddress
);

// construct the NttManagerMessage payload
encodedNttManagerPayload = TransceiverStructs.encodeNttManagerMessage(
TransceiverStructs.NttManagerMessage(
bytes32(uint256(seq)),
toWormholeFormat(sender),
bytes32(uint256(args.sequence)),
toWormholeFormat(args.sender),
TransceiverStructs.encodeNativeTokenTransfer(ntt)
)
);
Expand Down
1 change: 1 addition & 0 deletions evm/src/NttManager/NttManagerNoRateLimiting.sol
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ contract NttManagerNoRateLimiting is NttManager {
bool, // shouldQueue
bytes memory, // executorQuote
bytes memory, // relayInstructions
bytes memory, // transceiverInstructions
TrimmedAmount, // trimmedAmount
uint64 // sequence
) internal pure override returns (bool) {
Expand Down
4 changes: 3 additions & 1 deletion evm/src/interfaces/IManagerBase.sol
Original file line number Diff line number Diff line change
Expand Up @@ -98,9 +98,11 @@ interface IManagerBase {

/// @notice Fetch the delivery price for a given recipient chain transfer.
/// @param recipientChain The Wormhole chain ID of the transfer destination.
/// @param transceiverInstructions The encoded adapter instructions to be passed to the endpoint.
/// @return - The delivery prices associated with each enabled endpoint and the total price.
function quoteDeliveryPrice(
uint16 recipientChain
uint16 recipientChain,
bytes memory transceiverInstructions
) external view returns (uint256);

/// @notice Sets the threshold for the number of attestations required for a message
Expand Down
16 changes: 12 additions & 4 deletions evm/src/interfaces/INttManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -166,12 +166,17 @@ interface INttManager is IManagerBase {
/// @param amount The amount to transfer.
/// @param recipientChain The Wormhole chain ID for the destination.
/// @param recipient The recipient address.
/// @param executorQuote The signed quote to be passed to the executor.
/// @param relayInstructions The relay instructions to be passed to the executor.
/// @param transceiverInstructions The adapter instructions to be passed to the endpoint.
/// @return msgId The resulting message ID of the transfer
function transfer(
uint256 amount,
uint16 recipientChain,
bytes32 recipient,
bytes calldata executorQuote
bytes calldata executorQuote,
bytes calldata relayInstructions,
bytes calldata transceiverInstructions
) external payable returns (uint64 msgId);

/// @notice Transfer a given amount to a recipient on a given chain. This function is called
Expand All @@ -182,9 +187,11 @@ interface INttManager is IManagerBase {
/// @param amount The amount to transfer.
/// @param recipientChain The Wormhole chain ID for the destination.
/// @param recipient The recipient address.
/// @param refundAddress The address to which a refund for unussed gas is issued on the recipient chain.
/// @param refundAddress The address to which a refund for unused gas is issued on the recipient chain.
/// @param shouldQueue Whether the transfer should be queued if the outbound limit is hit.
/// @param encodedInstructions Additional instructions to be forwarded to the recipient chain.
/// @param executorQuote The signed quote to be passed to the executor.
/// @param relayInstructions The relay instructions to be passed to the executor.
/// @param transceiverInstructions The adapter instructions to be passed to the endpoint.
/// @return msgId The resulting message ID of the transfer
function transfer(
uint256 amount,
Expand All @@ -193,7 +200,8 @@ interface INttManager is IManagerBase {
bytes32 refundAddress,
bool shouldQueue,
bytes calldata executorQuote,
bytes memory encodedInstructions
bytes calldata relayInstructions,
bytes calldata transceiverInstructions
) external payable returns (uint64 msgId);

/// @notice Complete an outbound transfer that's been queued.
Expand Down
2 changes: 2 additions & 0 deletions evm/src/interfaces/IRateLimiter.sol
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ interface IRateLimiter {
/// - recipientChain: the chain of the recipient.
/// - sender: the sender of the transfer.
/// - relayInstructions: additional instructions to be forwarded to the relayer.
/// - transceiverInstructions: instructions to be passed into the adapters.
struct OutboundQueuedTransfer {
bytes32 recipient;
bytes32 refundAddress;
Expand All @@ -72,6 +73,7 @@ interface IRateLimiter {
address sender;
bytes executorQuote;
bytes relayInstructions;
bytes transceiverInstructions;
}

/// @notice Parameters for an inbound queued transfer.
Expand Down
Loading

0 comments on commit 42d28a7

Please sign in to comment.