Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
24 changes: 10 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

## Objective

Provide an execution framework and proof-of-concept (PoC) service for [Wormhole](https://github.com/wormhole-foundation/wormhole), [Modular Messaging](https://github.com/wormholelabs-xyz/example-messaging-endpoint), and potentially other protocols that is permissionless, extensible, and low-overhead.
Provide an execution framework for [Wormhole](https://github.com/wormhole-foundation/wormhole) and potentially other protocols that is permissionless, extensible, and low-overhead.

## Runtime Support

Expand All @@ -11,6 +11,13 @@ Provide an execution framework and proof-of-concept (PoC) service for [Wormhole]
- [x] [Sui Move](./sui/)
- [x] [Aptos Move](./aptos/)

## Protocol Support

- [x] [CCTP v1](https://developers.circle.com/cctp)
- [x] [CCTP v2](https://developers.circle.com/cctp)
- [x] [NTT v1](https://github.com/wormhole-foundation/native-token-transfers)
- [x] [VAA v1](https://wormhole.com/docs/products/messaging/overview/)

## Background

Wormhole integrators rely on [various relayers](https://wormhole.com/docs/learn/infrastructure/relayer/) to complete cross-chain actions on behalf of users. The existing systems have some drawbacks however. [Wormhole Relayers](https://wormhole.com/docs/build/contract-integrations/wormhole-relayers/) introduce a significant cost overhead to achieve their goals while custom relayers introduce significant bespoke work for integrators aiming to avoid that overhead.
Expand Down Expand Up @@ -93,7 +100,7 @@ Executor Contract - The shared, on-chain contract/program used to make Execution

Execution Quote - A quote for execution for a given source and destination chain. Quotes are signed by the Quoter.

Execution Request - A request generated on-chain or off-chain for a given message (e.g. Modular Message, VAA v1, etc) to be executed on another chain.
Execution Request - A request generated on-chain or off-chain for a given message (e.g. NTT, VAA v1, etc) to be executed on another chain.

Quoter - An off-chain service which provides pricing for execution. A Relay Provider is uniquely identified by their Quoter’s EVM public key.

Expand Down Expand Up @@ -145,7 +152,7 @@ The Executor Contract MUST support the following methods

In order to minimize cost, this contract MUST NOT verify the signature on the Quote. The Quote SHOULD be verified by the submitting client code before being used in a transaction.

In order to be extensible, this contract MUST NOT construct or validate the message-specific request details (e.g. Modular Message, VAA v1, etc). It is up to the client to select an Executor which services the specific message types required.
In order to be extensible, this contract MUST NOT construct or validate the message-specific request details (e.g. NTT, VAA v1, etc). It is up to the client to select an Executor which services the specific message types required.

Similarly, this contract MUST NOT check the payment amount against the quote and relay instructions. It is up to the client to accurately estimate the required payment and the relayer to enforce it.

Expand Down Expand Up @@ -194,17 +201,6 @@ bytes32 emitterAddress
uint64 sequence
```

##### Modular Message Request [WIP]

```solidity
bytes4 prefix = b"ERM1" // 4-byte prefix for this struct
uint16 sourceChainId // Source chain
bytes32 sourceAddress // Source address
uint64 sequence // Sequence number returned by `endpoint.sendMessage`
uint32 payloadLen // Length of the payload
bytes payload // The full payload, the keccak of which was sent to `endpoint.sendMessage`
```

##### NTT v1 Request

```solidity
Expand Down
20 changes: 0 additions & 20 deletions evm/src/libraries/ExecutorMessages.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
pragma solidity ^0.8.19;

library ExecutorMessages {
bytes4 private constant REQ_MM = "ERM1";
bytes4 private constant REQ_VAA_V1 = "ERV1";
bytes4 private constant REQ_NTT_V1 = "ERN1";
bytes4 private constant REQ_CCTP_V1 = "ERC1";
Expand All @@ -12,25 +11,6 @@ library ExecutorMessages {
/// @dev Selector: 492f620d.
error PayloadTooLarge();

/// @notice Encodes a modular messaging request payload.
/// @param srcChain The source chain for the message (usually this chain).
/// @param srcAddr The source address for the message.
/// @param sequence The sequence number returned by `endpoint.sendMessage`.
/// @param payload The full payload, the keccak of which was sent to `endpoint.sendMessage`.
/// @return bytes The encoded request.
function makeMMRequest(uint16 srcChain, address srcAddr, uint64 sequence, bytes memory payload)
internal
pure
returns (bytes memory)
{
if (payload.length > type(uint32).max) {
revert PayloadTooLarge();
}
return abi.encodePacked(
REQ_MM, srcChain, bytes32(uint256(uint160(srcAddr))), sequence, uint32(payload.length), payload
);
}

/// @notice Encodes a version 1 VAA request payload.
/// @param emitterChain The emitter chain from the VAA.
/// @param emitterAddress The emitter address from the VAA.
Expand Down
17 changes: 0 additions & 17 deletions evm/test/ExecutorMessages.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,6 @@ import {Test, console} from "forge-std/Test.sol";
import {ExecutorMessages} from "../src/libraries/ExecutorMessages.sol";

contract ExecutorMessagesTest is Test {
function test_makeMMRequest() public pure {
address srcAddr = address(0xdeadbeef);
uint16 srcChain = 2;
uint64 sequence = 42;
bytes memory payload = "Hello, World";
bytes memory expected = abi.encodePacked(
"ERM1", // prefix
srcChain, // sourceChainId
bytes32(uint256(uint160(srcAddr))), // sourceAddress
sequence, // sequence
uint32(payload.length), // payloadLen
payload // payload
);
bytes memory buf = ExecutorMessages.makeMMRequest(srcChain, srcAddr, sequence, payload);
assertEq(keccak256(expected), keccak256(buf));
}

function test_makeVAAv1Request() public pure {
uint16 emitterChain = 7;
bytes32 emitterAddress = bytes32(uint256(uint160(0xdeadbeef)));
Expand Down
40 changes: 0 additions & 40 deletions svm/tests/executor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,46 +106,6 @@ describe("executor", () => {
).to.be.fulfilled;
});

it("Requests execution with real quote, MM request, and relay instruction!", async () => {
await expect(
program.methods
.requestForExecution({
amount: new BN(1),
dstChain: 2,
dstAddr: [
...Buffer.from(
"0000000000000000000000000000000000000000000000000000000000000000",
"hex",
),
],
refundAddr: program.provider.publicKey!,
signedQuoteBytes: Buffer.from(
encodeSignedQuoteHeader(
"EQ01",
"0x0000000000000000000000000000000000000000",
program.provider.publicKey!,
1,
2,
BigInt(Date.now() + 1_000_000) / BigInt(1000),
"0000000000002710000000003b9aca0700001d624add080000000625b3cb4600b69fffad8549dd87b875a85f6341283bc3cc61758e5b929cfa6913c8727af7a2776c66584cc260cb05d505c852187c0a29a7b774e1d05815020f774013b30fe11c",
),
),
requestBytes: Buffer.from(
"45524d310002000000000000000000000000157f9cd170058f373294addc32149f1f5c77a6410000000000000000000000910000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e11ba2b4d45eaed5996cd0823791e0c93114882d004f994e54540800000000000f42400000000000000000000000008738d8b87d770220aaf91239adc62a2ff3f88bbe000000000000000000000000e11ba2b4d45eaed5996cd0823791e0c93114882d0004",
"hex",
),
relayInstructions: Buffer.from(
"0100000000000000000000000000030d4000000000000000000000000000000000",
"hex",
),
})
.accounts({
payee: program.provider.publicKey!,
})
.rpc(),
).to.be.fulfilled;
});

it("Pays the payee!", async () => {
const payee = new anchor.web3.Keypair().publicKey;
// the payee must already exist to avoid making a requestor pay to instantiate new accounts
Expand Down
Loading