diff --git a/test/concrete/ob/OrderBookV6.quote.fork.t.sol b/test/concrete/ob/OrderBookV6.quote.fork.t.sol new file mode 100644 index 0000000000..d127acf501 --- /dev/null +++ b/test/concrete/ob/OrderBookV6.quote.fork.t.sol @@ -0,0 +1,78 @@ +// SPDX-License-Identifier: LicenseRef-DCL-1.0 +// SPDX-FileCopyrightText: Copyright (c) 2020 Rain Open Source Software Ltd +pragma solidity =0.8.25; + +import {Test, console2} from "forge-std/Test.sol"; +import { + IRaindexV6, + QuoteV2, + OrderV4, + SignedContextV1 +} from "rain.raindex.interface/interface/IRaindexV6.sol"; +import {LibOrder} from "../../../src/lib/LibOrder.sol"; +import {Float, LibDecimalFloat} from "rain.math.float/lib/LibDecimalFloat.sol"; + +/// @title OrderBookV6QuoteForkTest +/// @notice Fork Base mainnet to quote a live ST0x order via `quote2`. +/// Run with: +/// `BASE_MAINNET_RPC_URL= forge test --match-contract OrderBookV6QuoteForkTest -vvv` +contract OrderBookV6QuoteForkTest is Test { + using LibDecimalFloat for Float; + + address internal constant ORDERBOOK = 0xe522cB4a5fCb2eb31a52Ff41a4653d85A4fd7C9D; + bytes32 internal constant EXPECTED_ORDER_HASH = + 0x4a051ad4567935a5a0570b3e2e77714c44405bb58e5b83e3cc484de1cee0747e; + uint256 internal constant FORK_BLOCK = 46_815_818; + + bytes internal constant ORDER_BYTES = + hex"0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000a9c16673f65ae808688cb18952afe3d9658c808f00000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000046050abe09afac859678a220a1b0971e0cf2c310c53072f6455bcb2da776effb2b30000000000000000000000003bf9bd9da4784f75c92317e61c68493ecc9aabdc0000000000000000000000001aa775533e28b1d843e1a589034984e3a62005dc000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000002c7000000000000000000000000000000000000000000000000000000000000000efffffffc000000000000000000000000000000000000000000000000000027120000000000000000000000008ff1ca8ed2e98f693a3ea16b3ebe44fe90500a430000000000000000556e74727573746564206f7261636c65207369676e6572f70000000000000000000000000000000000000000000000000000000000000001004f7261636c6520736368656d612076657273696f6e206d69736d61746368fe0000000000000000005075626c6973682074696d6520696e20667574757265f6000000000000000000000000000000000000000000000000000000000000012c00000000000000000000000000004f7261636c652064617461207374616c65f1000000000000000000000000000000000000000000000000000000000000000000000000000000000000004f7261636c65207072696365206973207a65726ff4fffffffe0000000000000000000000000000000000000000000000000000000100000000000050726963652062656c6f77206d696e696d756d20626f756e64f900000000000000000000000000000000000000000000000000000000000186a000000000000050726963652061626f7665206d6178696d756d20626f756e64f900000000000000000000000000000000000000000000000000000000000000c7030000001400180403000236100000011000000b1000023a12000000000000290700040110000201100001031000051f1200001e020000031000060110000401100003001000001f1200001e0200000310010603100206011000051910000000100002261200001e020000011000070110000600100002191000003d120000261200001e020000011000090110000800100001211200001e0200000110000b0110000a00100001211200001e0200000110000d0110000c00100001251200001e02000000100001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000833589fcd6edb6e08f4c7c32d4f71b54bda02913000000000000000000000000000000000000000000000000000000000000fab4000000000000000000000000000000000000000000000000000000000000000100000000000000000000000031c2c14134e6e3b7ef9478297f199331133fc2d80000000000000000000000000000000000000000000000000000000000000fab"; + + function setUp() public { + string memory rpc = vm.envOr("BASE_MAINNET_RPC_URL", string("https://mainnet.base.org")); + vm.createSelectFork(rpc); + vm.rollFork(FORK_BLOCK); + } + + function testQuoteSt0xSplgUsdcOrder() external view { + OrderV4 memory order = abi.decode(ORDER_BYTES, (OrderV4)); + assertEq(LibOrder.hash(order), EXPECTED_ORDER_HASH, "order hash"); + + SignedContextV1[] memory signedContext = new SignedContextV1[](1); + signedContext[0] = SignedContextV1({ + signer: 0x8Ff1CA8ED2e98f693A3eA16b3EBE44FE90500A43, + context: new bytes32[](3), + signature: hex"093ed36a10387f443cdec9a4825402c7af0575c00962ba0925dac7780a91d2f83158d88e848f5b2ac6be704cbd5bfb4e659a4133567a01233fe9824ac2dd12f61c" + }); + signedContext[0].context[0] = 0x0000000000000000000000000000000000000000000000000000000000000001; + signedContext[0].context[1] = 0xfffffffd00000000000000000000000000000000000000000000000000015d33; + signedContext[0].context[2] = 0x000000000000000000000000000000000000000000000000000000006a1f117e; + + uint256 oracleVersion = uint256(signedContext[0].context[0]); + (uint256 oraclePrice,) = Float.wrap(signedContext[0].context[1]).toFixedDecimalLossy(18); + uint256 oraclePublishTime = uint256(signedContext[0].context[2]); + + console2.log("oracleVersion", oracleVersion); + console2.log("oraclePrice", oraclePrice); + console2.log("oraclePublishTime", oraclePublishTime); + + QuoteV2 memory quoteConfig = QuoteV2({ + order: order, + inputIOIndex: 0, + outputIOIndex: 0, + signedContext: signedContext + }); + + (bool success, Float maxOutput, Float ioRatio) = IRaindexV6(ORDERBOOK).quote2(quoteConfig); + + (uint256 maxOutputFixed,) = maxOutput.toFixedDecimalLossy(18); + (uint256 ioRatioFixed,) = ioRatio.toFixedDecimalLossy(18); + + console2.log("quote success", success); + console2.log("maxOutput", maxOutputFixed); + console2.log("ioRatio", ioRatioFixed); + + assertTrue(success, "quote2"); + // assertFalse(maxOutput.isZero(), "max output"); + // assertFalse(ioRatio.isZero(), "io ratio"); + } +}