diff --git a/.gitmodules b/.gitmodules index 7a15136..83c3e9f 100644 --- a/.gitmodules +++ b/.gitmodules @@ -13,3 +13,6 @@ [submodule "lib/h20.pubstrats"] path = lib/h20.pubstrats url = https://github.com/h20liquidity/h20.pubstrats.git +[submodule "lib/view-quoter-v3"] + path = lib/view-quoter-v3 + url = https://github.com/Uniswap/view-quoter-v3 diff --git a/lib/h20.pubstrats b/lib/h20.pubstrats index 668ae9d..0c11382 160000 --- a/lib/h20.pubstrats +++ b/lib/h20.pubstrats @@ -1 +1 @@ -Subproject commit 668ae9d2e2ab4d4549212ef6e6faacb12e5dbd0c +Subproject commit 0c11382c885eb75493eb506344b3a0299b9a5990 diff --git a/lib/view-quoter-v3 b/lib/view-quoter-v3 new file mode 160000 index 0000000..0649670 --- /dev/null +++ b/lib/view-quoter-v3 @@ -0,0 +1 @@ +Subproject commit 064967017bd1a0df11e9d71ff024b29584aafaa5 diff --git a/src/TrancheMirror.sol b/src/TrancheMirror.sol index bf25e98..82a4ec9 100644 --- a/src/TrancheMirror.sol +++ b/src/TrancheMirror.sol @@ -24,9 +24,8 @@ address constant POLYGON_IEON_HOLDER = 0xd6756f5aF54486Abda6bd9b1eee4aB0dBa7C3ef // USDT token holder. address constant POLYGON_USDT_HOLDER = 0xF977814e90dA44bFA03b6295A0616a897441aceC; -/// @dev https://docs.sushi.com/docs/Products/Classic%20AMM/Deployment%20Addresses -/// @dev https://polygonscan.com/address/0xc35DADB65012eC5796536bD9864eD8773aBc74C4 -address constant POLYGON_SUSHI_V2_FACTORY = 0xc35DADB65012eC5796536bD9864eD8773aBc74C4; +/// @dev https://polygonscan.com/address/0x5757371414417b8C6CAad45bAeF941aBc7d3Ab32 +address constant UNI_V2_FACTORY = 0x5757371414417b8C6CAad45bAeF941aBc7d3Ab32; /// @dev https://polygonscan.com/address/0xd0e9c8f5Fae381459cf07Ec506C1d2896E8b5df6 IERC20 constant IEON_TOKEN = IERC20(0xd0e9c8f5Fae381459cf07Ec506C1d2896E8b5df6); @@ -34,6 +33,9 @@ IERC20 constant IEON_TOKEN = IERC20(0xd0e9c8f5Fae381459cf07Ec506C1d2896E8b5df6); /// @dev https://polygonscan.com/address/0xc2132D05D31c914a87C6611C10748AEb04B58e8F IERC20 constant USDT_TOKEN = IERC20(0xc2132D05D31c914a87C6611C10748AEb04B58e8F); +/// @dev https://polygonscan.com/address/0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270 +IERC20 constant WETH_TOKEN = IERC20(0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270); + /// @dev https://docs.sushi.com/docs/Products/Classic%20AMM/Deployment%20Addresses address constant POLYGON_SUSHI_V2_ROUTER = 0x1b02dA8Cb0d097eB8D57A175b88c7D8b47997506; @@ -41,7 +43,76 @@ function polygonIeonIo() pure returns (IO memory) { return IO(address(IEON_TOKEN), 18, VAULT_ID); } -function polygonUsdtIo() pure returns (IO memory) { - return IO(address(USDT_TOKEN), 6, VAULT_ID); +function polygonWethIo() pure returns (IO memory) { + return IO(address(WETH_TOKEN), 18, VAULT_ID); +} + +function uint2str(uint256 _i) pure returns (string memory _uintAsString) { + if (_i == 0) { + return "0"; + } + uint256 j = _i; + uint256 len; + while (j != 0) { + len++; + j /= 10; + } + bytes memory bstr = new bytes(len); + uint256 k = len; + while (_i != 0) { + k = k - 1; + uint8 temp = (48 + uint8(_i - _i / 10 * 10)); + bytes1 b1 = bytes1(temp); + bstr[k] = b1; + _i /= 10; + } + return string(bstr); +} + +library LibTrancheSpreadOrders { + using Strings for address; + + function getTrancheSpreadBuyOrder(Vm vm, address orderBookSubparser, address uniswapWords) + internal + returns (bytes memory trancheRefill) + { + string[] memory ffi = new string[](29); + ffi[0] = "rain"; + ffi[1] = "dotrain"; + ffi[2] = "compose"; + ffi[3] = "-i"; + ffi[4] = "lib/h20.pubstrats/src/tranche-spread.rain"; + ffi[5] = "--entrypoint"; + ffi[6] = "calculate-io"; + ffi[7] = "--entrypoint"; + ffi[8] = "handle-io"; + ffi[9] = "--bind"; + ffi[10] = "distribution-token=0xd0e9c8f5Fae381459cf07Ec506C1d2896E8b5df6"; + ffi[11] = "--bind"; + ffi[12] = "reserve-token=0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270"; + ffi[13] = "--bind"; + ffi[14] = string.concat("tranche-reserve-amount-base=", uint2str(1e18)); + ffi[15] = "--bind"; + ffi[16] = string.concat("tranche-reserve-io-ratio-base=", uint2str(111e16)); + ffi[17] = "--bind"; + ffi[18] = string.concat("spread-ratio=", uint2str(101e16)); + ffi[19] = "--bind"; + ffi[20] = string.concat("tranche-space-edge-guard-threshold=", uint2str(1e16)); + ffi[21] = "--bind"; + ffi[22] = "get-tranche-space='get-real-tranche-space"; + ffi[23] = "--bind"; + ffi[24] = "set-tranche-space='set-real-tranche-space"; + ffi[25] = "--bind"; + ffi[26] = "tranche-reserve-amount-growth='tranche-reserve-amount-growth-constant"; + ffi[27] = "--bind"; + ffi[28] = "tranche-reserve-io-ratio-growth='tranche-reserve-io-ratio-linear"; + trancheRefill = bytes.concat(getSubparserPrelude(orderBookSubparser, uniswapWords), vm.ffi(ffi)); + } + + function getSubparserPrelude(address obSubparser, address uniswapWords) internal pure returns (bytes memory) { + bytes memory RAINSTRING_OB_SUBPARSER = + bytes(string.concat("using-words-from ", obSubparser.toHexString(), " ", uniswapWords.toHexString(), " ")); + return RAINSTRING_OB_SUBPARSER; + } } diff --git a/test/TrancheMirrorTest.t.sol b/test/TrancheMirrorTest.t.sol index 65f7e88..21ebadc 100644 --- a/test/TrancheMirrorTest.t.sol +++ b/test/TrancheMirrorTest.t.sol @@ -4,8 +4,18 @@ pragma solidity =0.8.19; import {Vm} from "forge-std/Vm.sol"; import {console2, Test} from "forge-std/Test.sol"; import "test/util/TrancheMirrorUtils.sol"; +import "src/TrancheMirror.sol"; contract TrancheMirrorTest is TrancheMirrorUtils { + function testParseOrder() public { + PARSER.parse( + LibTrancheSpreadOrders.getTrancheSpreadBuyOrder( + vm, + address(ORDERBOOK_SUPARSER), + address(UNISWAP_WORDS) + ) + ); + } } diff --git a/test/util/TrancheMirrorUtils.sol b/test/util/TrancheMirrorUtils.sol index 4eb5018..e78952b 100644 --- a/test/util/TrancheMirrorUtils.sol +++ b/test/util/TrancheMirrorUtils.sol @@ -40,13 +40,23 @@ contract TrancheMirrorUtils is RainContracts, Test { function setUp() public { selectPolygonFork(); - PARSER = IParserV1(0xc2D7890077F3EA75c2798D8624E1E0E6ef8C41e6); - INTERPRETER = IInterpreterV2(0xB7d691B7E3676cb70dB0cDae95797F24Eab6980D); - STORE = IInterpreterStoreV2(0x0b5a2b0aCFc5B52bf341FAD638B63C9A6f82dcb9); - EXPRESSION_DEPLOYER = IExpressionDeployerV3(0xE1E250a234aF6F343062873bf89c9D1a0a659c0b); + + deployParser(); + deployStore(); + deployInterpreter(); + + deployExpressionDeployer(vm, address(INTERPRETER), address(STORE), address(PARSER)); + deployOrderBookSubparser(); + deployUniswapWords(vm); + + // PARSER = IParserV1(0xc2D7890077F3EA75c2798D8624E1E0E6ef8C41e6); + // INTERPRETER = IInterpreterV2(0xB7d691B7E3676cb70dB0cDae95797F24Eab6980D); + // STORE = IInterpreterStoreV2(0x0b5a2b0aCFc5B52bf341FAD638B63C9A6f82dcb9); + // EXPRESSION_DEPLOYER = IExpressionDeployerV3(0xE1E250a234aF6F343062873bf89c9D1a0a659c0b); + // ORDERBOOK_SUPARSER = ISubParserV2(0x8A99456dD0E1CaA187CF6B779cA42EFE94E9C42b); + // UNISWAP_WORDS = ISubParserV2(0xd97e8e581393055521F813D6889CfcCEDF7847C6); + ORDERBOOK = IOrderBookV3(0xDE5aBE2837bc042397D80E37fb7b2C850a8d5a6C); - ORDERBOOK_SUPARSER = ISubParserV2(0x8A99456dD0E1CaA187CF6B779cA42EFE94E9C42b); - UNISWAP_WORDS = ISubParserV2(0xd97e8e581393055521F813D6889CfcCEDF7847C6); ARB_IMPLEMENTATION = IOrderBookV3ArbOrderTaker(0x8F29083140559bd1771eDBfB73656A9f676c00Fd); ARB_INSTANCE = IOrderBookV3ArbOrderTaker(0x0D7896d70FE84e88CC8e8BaDcB14D612Eee4Bbe0); CLONE_FACTORY = ICloneableFactoryV2(0x6d0c39093C21dA1230aCDD911420BBfA353A3FBA);