Skip to content
Draft
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
2 changes: 2 additions & 0 deletions src/oracles/wormhole/WormholeOracle.sol
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,8 @@ contract WormholeOracle is BaseOracle, WormholeVerifier, Ownable {

// Map remoteMessagingProtocolChainIdentifier to canonical chain id. This ensures we use canonical ids.
uint256 remoteChainId = _chainIdentifierToBlockChainId[remoteMessagingProtocolChainIdentifier];
if (remoteChainId == 0) revert ZeroValue();

uint256 numPayloads = payloadHashes.length;

for (uint256 i; i < numPayloads; ++i) {
Expand Down
61 changes: 61 additions & 0 deletions test/TestCatalyst.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,67 @@ contract TestCatalyst is Test {
vm.snapshotGasLastCall("finaliseSelf");
}

function test_receive_and_settle_with_real_order() external {
uint256 initialSwapperBalance = token.balanceOf(swapper);
vm.prank(swapper);
uint256 amount = 1e18 / 10;
uint256 tokenId = theCompact.deposit(address(token), alwaysOKAllocator, amount);

address localOracle = address(wormholeOracle);
// These are the real addresses of fill_and_submit_output.move
bytes32 remoteOracle = 0x7c8361d4493d8b4de5a6c57a35458f238cf987f59dde1ea190656b122f77bef9; // Emitter cap address
bytes32 remoteFiller = 0x1611edd9a9d42dbcd9ae773ffa22be0f6017b00590959dd5c767e4efcd34cd0b;
bytes32 recipient = 0x000000000000000000000000006217c47ffa5eb3f3c92247fffe22ad998242c5;
bytes32 outputToken = 0x5ef2fcf809fb9535ea0aeaea421f683026f06c34569aafc42bcde652ef6dd270;
uint256 remoteChainId = 100;
bytes32 solverBytes = 0x000000000000000000000000ea22232eee6365d797fec0f804da81f3e3f18c2d;
address solverAddress = address(uint160(uint256(solverBytes)));

uint256[2][] memory inputs = new uint256[2][](1);
inputs[0] = [tokenId, amount];
OutputDescription[] memory outputs = new OutputDescription[](1);
outputs[0] = OutputDescription({
remoteFiller: remoteFiller,
remoteOracle: remoteOracle,
chainId: remoteChainId,
token: outputToken,
amount: amount,
recipient: recipient,
remoteCall: hex"",
fulfillmentContext: hex""
});
CatalystCompactOrder memory order =
CatalystCompactOrder({ user: address(swapper), nonce: 0, originChainId: block.chainid, fillDeadline: type(uint32).max, localOracle: localOracle, inputs: inputs, outputs: outputs });

// Make Compact
bytes32 typeHash = TheCompactOrderType.BATCH_COMPACT_TYPE_HASH;
uint256[2][] memory idsAndAmounts = new uint256[2][](1);
idsAndAmounts[0] = [tokenId, amount];

bytes memory sponsorSig = getCompactBatchWitnessSignature(swapperPrivateKey, typeHash, address(compactSettler), swapper, 0, type(uint32).max, idsAndAmounts, this.orderHash(order));
bytes memory allocatorSig = hex"";

bytes memory signature = abi.encode(sponsorSig, allocatorSig);
bytes32 orderId = compactSettler.orderIdentifier(order);

bytes[] memory payloads = new bytes[](1);
payloads[0] = OutputEncodingLib.encodeFillDescriptionM(solverBytes, orderId, uint32(block.timestamp), outputs[0]);

bytes memory expectedMessageEmitted = this.encodeMessage(outputs[0].remoteFiller, payloads);

bytes memory vaa = makeValidVAA(uint16(remoteChainId), remoteOracle, expectedMessageEmitted);
wormholeOracle.setChainMap(uint16(remoteChainId), remoteChainId);
wormholeOracle.receiveMessage(vaa);

uint32[] memory timestamps = new uint32[](1);
timestamps[0] = uint32(block.timestamp);

vm.prank(solverAddress);
compactSettler.finaliseSelf(order, signature, timestamps, solverBytes);
assertEq(token.balanceOf(solverAddress), amount);
assertEq(token.balanceOf(swapper), initialSwapperBalance - amount);
}

function test_entire_flow_different_solvers(bytes32 solverIdentifier2) external {
vm.prank(swapper);
uint256 amount = 1e18 / 10;
Expand Down
1 change: 1 addition & 0 deletions test/oracle/wormhole/callworm.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ pragma solidity ^0.8.22;

import "forge-std/Test.sol";
import { WormholeVerifier } from "src/oracles/wormhole/external/callworm/WormholeVerifier.sol";
import { WormholeOracle } from "src/oracles/wormhole/WormholeOracle.sol";
import "src/oracles/wormhole/external/wormhole/Messages.sol";
import "src/oracles/wormhole/external/wormhole/Setters.sol";
import "src/oracles/wormhole/external/wormhole/Structs.sol";
Expand Down
38 changes: 38 additions & 0 deletions test/oracle/wormhole/receive.t.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// SPDX-License-Identifier: Apache 2

pragma solidity ^0.8.22;

import { WormholeOracle } from "src/oracles/wormhole/WormholeOracle.sol";
import { TestWormholeCallWorm } from "./callworm.t.sol";

contract TestReceiveWormholeOracleProofs is TestWormholeCallWorm {
event OutputProven(uint256 chainid, bytes32 remoteIdentifier, bytes32 application, bytes32 payloadHash);

WormholeOracle oracle;

function test_receive_proof() external {
oracle = new WormholeOracle(address(this), address(messages));
bytes memory stripped_message = hex"1611edd9a9d42dbcd9ae773ffa22be0f6017b00590959dd5c767e4efcd34cd0b000100b400000000000000000000000000000000000000000000000000000000000000ac82f523c28a9556fdc958116e496b8ce488969b8ffbb8998620c5e890c6156cf5000000005ef2fcf809fb9535ea0aeaea421f683026f06c34569aafc42bcde652ef6dd270640000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ec191e4700000000000000000000000000000000";
bytes memory validVM = makeValidVM(stripped_message);
bytes32 payloadHash = keccak256(hex"00000000000000000000000000000000000000000000000000000000000000ac82f523c28a9556fdc958116e496b8ce488969b8ffbb8998620c5e890c6156cf5000000005ef2fcf809fb9535ea0aeaea421f683026f06c34569aafc42bcde652ef6dd270640000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ec191e4700000000000000000000000000000000");

vm.prank(address(this));
oracle.setChainMap(13, 13);
/**
chainId: 13(00x000d)
remoteIdentifier: 0xdeadbeefbeefdead
application: 0x1611edd9a9d42dbcd9ae773ffa22be0f6017b00590959dd5c767e4efcd34cd0b
payload: 00000000000000000000000000000000000000000000000000000000000000ac82f523c28a9556fdc958116e496b8ce488969b8ffbb8998620c5e890c6156cf5000000005ef2fcf809fb9535ea0aeaea421f683026f06c34569aafc42bcde652ef6dd270640000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ec191e4700000000000000000000000000000000

The chainId and remoteIdentifier are from the oracle with dummy guardian set.
The application is the coin_filler id from fill_and_submit test in SUI.
The payload is the fill description from the fill_and_submit test in SUI.
*/

vm.expectEmit();
emit OutputProven(13, bytes32(uint256(0xdeadbeefbeefdead)), 0x1611edd9a9d42dbcd9ae773ffa22be0f6017b00590959dd5c767e4efcd34cd0b, payloadHash);

oracle.receiveMessage(validVM);
assert(oracle.isProven(13, bytes32(uint256(0xdeadbeefbeefdead)), 0x1611edd9a9d42dbcd9ae773ffa22be0f6017b00590959dd5c767e4efcd34cd0b, payloadHash));
}
}
41 changes: 41 additions & 0 deletions test/oracle/wormhole/submit.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -82,4 +82,45 @@ contract TestSubmitWormholeOracleProofs is Test {
emit PackagePublished(0, expectedPayload, 15);
oracle.submit(address(filler), payloads);
}

/**
* @dev This is used to test receive against SUI chain
*/
function test_fill_no_fuzz_output() public {
uint256 amount = 100;
bytes32 solverIdentifier = bytes32(uint256(uint160(makeAddr("solver"))));
bytes32 recipient = bytes32(uint256(uint160(makeAddr("recipient"))));
address sender = makeAddr("sender");

token.mint(sender, amount);
vm.prank(sender);
token.approve(address(filler), amount);

OutputDescription memory output = OutputDescription({
remoteOracle: bytes32(uint256(uint160(address(oracle)))),
remoteFiller: bytes32(uint256(uint160(address(filler)))),
token: bytes32(abi.encode(address(token))),
amount: amount,
recipient: bytes32(abi.encode(recipient)),
chainId: uint32(block.chainid),
remoteCall: hex"",
fulfillmentContext: hex""
});

bytes32 orderId = hex"e58f15295d1c9e383c8d4dad01ee03cfa4448f0d4f52925fa957d6e76612bff9";
vm.expectCall(address(token), abi.encodeWithSignature("transferFrom(address,address,uint256)", address(sender), recipient, amount));

vm.prank(sender);
filler.fill(orderId, output, solverIdentifier);

bytes memory payload = OutputEncodingLib.encodeFillDescriptionM(solverIdentifier, orderId, uint32(block.timestamp), output);
bytes[] memory payloads = new bytes[](1);
payloads[0] = payload;

bytes memory expectedPayload = this.encodeMessageCalldata(output.remoteFiller, payloads);

vm.expectEmit();
emit PackagePublished(0, expectedPayload, 15);
oracle.submit(address(filler), payloads);
}
}
Loading