diff --git a/README.md b/README.md index 3b92a18..8234192 100644 --- a/README.md +++ b/README.md @@ -222,6 +222,13 @@ uint32 sourceDomain uint64 nonce ``` +##### CCTP v2 Request + +```solidity +bytes4 prefix = "ERC2" // 4-byte prefix for this struct +uint8 autoDiscover // Currently, must be one. +``` + #### Relay Instructions ##### Gas Instruction diff --git a/evm/README.md b/evm/README.md index c172d3f..e0d4b3b 100644 --- a/evm/README.md +++ b/evm/README.md @@ -94,6 +94,31 @@ executor.requestExecution{value: executorArgs.value}( +#### Example v2 CCTP Request + +The `depositForBurn` function in CCTP v2 doesn't return anything, so we don't have a unique identifier for a transfer. +The off-chain executor will detect all Circle V2 transfers in the transaction and relay them. + + + +```solidity +import "example-messaging-executor/evm/src/interfaces/IExecutor.sol"; +import "example-messaging-executor/evm/src/libraries/ExecutorMessages.sol"; +... +circleTokenMessenger.depositForBurn(amount, destinationDomain, mintRecipient, burnToken, destinationCaller, maxFee, minFinalityThreshold); + +executor.requestExecution{value: executorArgs.value}( + 0, + bytes32(0), + executorArgs.refundAddress, + executorArgs.signedQuote, + ExecutorMessages.makeCCTPv2Request(), + executorArgs.instructions +); +``` + + + ### Execution Support #### v1 VAA Execution @@ -117,7 +142,15 @@ function receiveMessage(bytes memory encodedMessage) external The Circle Message Transmitter contract implements the following function. ```solidity -function receiveMessage(bytes calldata message,bytes calldata attestation) external override whenNotPaused returns (bool success) +function receiveMessage(bytes calldata message, bytes calldata attestation) external override whenNotPaused returns (bool success) +``` + +#### v2 CCTP Execution + +The Circle Message Transmitter contract implements the following function. + +```solidity +function receiveMessage(bytes calldata message, bytes calldata attestation) external override whenNotPaused returns (bool success) ``` ## Executor Development diff --git a/evm/src/libraries/ExecutorMessages.sol b/evm/src/libraries/ExecutorMessages.sol index 9784d2d..428887f 100644 --- a/evm/src/libraries/ExecutorMessages.sol +++ b/evm/src/libraries/ExecutorMessages.sol @@ -6,6 +6,7 @@ library ExecutorMessages { bytes4 private constant REQ_VAA_V1 = "ERV1"; bytes4 private constant REQ_NTT_V1 = "ERN1"; bytes4 private constant REQ_CCTP_V1 = "ERC1"; + bytes4 private constant REQ_CCTP_V2 = "ERC2"; /// @notice Payload length will not fit in a uint32. /// @dev Selector: 492f620d. @@ -63,4 +64,12 @@ library ExecutorMessages { function makeCCTPv1Request(uint32 sourceDomain, uint64 nonce) internal pure returns (bytes memory) { return abi.encodePacked(REQ_CCTP_V1, sourceDomain, nonce); } + + /// @notice Encodes a version 2 CCTP request payload. + /// This request currently assumes the Executor will auto detect the event off chain. + /// That may change in the future, in which case this interface would change. + /// @return bytes The encoded request. + function makeCCTPv2Request() internal pure returns (bytes memory) { + return abi.encodePacked(REQ_CCTP_V2, uint8(1)); + } } diff --git a/evm/test/ExecutorMessages.t.sol b/evm/test/ExecutorMessages.t.sol index b0d59df..2006ef7 100644 --- a/evm/test/ExecutorMessages.t.sol +++ b/evm/test/ExecutorMessages.t.sol @@ -46,4 +46,10 @@ contract ExecutorMessagesTest is Test { bytes memory buf = ExecutorMessages.makeCCTPv1Request(srcDomain, nonce); assertEq(keccak256(expected), keccak256(buf)); } + + function test_makeCCTPv2Request() public pure { + bytes memory expected = abi.encodePacked("ERC2", uint8(1)); + bytes memory buf = ExecutorMessages.makeCCTPv2Request(); + assertEq(keccak256(expected), keccak256(buf)); + } }