From 64d7002fc74340c17821e695be13080f4f067447 Mon Sep 17 00:00:00 2001 From: Siddharth2207 Date: Mon, 26 Feb 2024 20:31:18 +0530 Subject: [PATCH] modeling tests --- .gitignore | 1 + lib/h20.pubstrats | 2 +- src/TrancheMirror.sol | 32 +++++---- test/TrancheMirrorTest.t.sol | 66 ++++++++++-------- test/util/TrancheMirrorUtils.sol | 95 ++++++++++++++++++++++++++ test/vg/tranche-space-amount.vg | 114 +++++++++++++++++++++++++++++++ 6 files changed, 269 insertions(+), 41 deletions(-) create mode 100644 test/vg/tranche-space-amount.vg diff --git a/.gitignore b/.gitignore index 995dbc2..ad302f5 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ out cache broadcast .env +test/csvs/* \ No newline at end of file diff --git a/lib/h20.pubstrats b/lib/h20.pubstrats index fbe6e56..b34a36a 160000 --- a/lib/h20.pubstrats +++ b/lib/h20.pubstrats @@ -1 +1 @@ -Subproject commit fbe6e56124b7b8d8e22e1cffd60ebe779f47456f +Subproject commit b34a36a504ecea0fc58e596fa72f7e469e702ac5 diff --git a/src/TrancheMirror.sol b/src/TrancheMirror.sol index ab8a89a..8538edd 100644 --- a/src/TrancheMirror.sol +++ b/src/TrancheMirror.sol @@ -68,15 +68,19 @@ function uint2str(uint256 _i) pure returns (string memory _uintAsString) { } return string(bstr); } - library LibTrancheSpreadOrders { - using Strings for address; - - function getTrancheSpreadBuyOrder(Vm vm, address orderBookSubparser) + using Strings for address;//100 000000000000000000 //909909909909909909 + + function getTrancheSpreadOrder( + Vm vm, + address orderBookSubparser, + uint256 testTrancheSpace, + uint256 spreadRatio + ) internal returns (bytes memory trancheRefill) { - string[] memory ffi = new string[](29); + string[] memory ffi = new string[](31); ffi[0] = "rain"; ffi[1] = "dotrain"; ffi[2] = "compose"; @@ -91,21 +95,23 @@ library LibTrancheSpreadOrders { ffi[11] = "--bind"; ffi[12] = "reserve-token=0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270"; ffi[13] = "--bind"; - ffi[14] = "get-tranche-space='get-real-tranche-space"; + ffi[14] = "get-tranche-space='get-test-tranche-space"; ffi[15] = "--bind"; - ffi[16] = "set-tranche-space='set-real-tranche-space"; + ffi[16] = "set-tranche-space='set-test-tranche-space"; ffi[17] = "--bind"; - ffi[18] = "tranche-reserve-amount-growth='tranche-reserve-amount-growth-constant"; + ffi[18] = string.concat("test-tranche-space=", uint2str(testTrancheSpace)); ffi[19] = "--bind"; - ffi[20] = string.concat("tranche-reserve-amount-base=", uint2str(1e18)); + ffi[20] = "tranche-reserve-amount-growth='tranche-reserve-amount-growth-constant"; ffi[21] = "--bind"; - ffi[22] = "tranche-reserve-io-ratio-growth='tranche-reserve-io-ratio-linear"; + ffi[22] = string.concat("tranche-reserve-amount-base=", uint2str(100e18)); ffi[23] = "--bind"; - ffi[24] = string.concat("tranche-reserve-io-ratio-base=", uint2str(111e16)); + ffi[24] = "tranche-reserve-io-ratio-growth='tranche-reserve-io-ratio-linear"; ffi[25] = "--bind"; - ffi[26] = string.concat("spread-ratio=", uint2str(101e16)); + ffi[26] = string.concat("tranche-reserve-io-ratio-base=", uint2str(111e16)); ffi[27] = "--bind"; - ffi[28] = string.concat("tranche-space-edge-guard-threshold=", uint2str(1e16)); + ffi[28] = string.concat("spread-ratio=", uint2str(spreadRatio)); + ffi[29] = "--bind"; + ffi[30] = string.concat("tranche-space-edge-guard-threshold=", uint2str(1e16)); trancheRefill = bytes.concat(getSubparserPrelude(orderBookSubparser), vm.ffi(ffi)); diff --git a/test/TrancheMirrorTest.t.sol b/test/TrancheMirrorTest.t.sol index 3a9ca13..d09bb16 100644 --- a/test/TrancheMirrorTest.t.sol +++ b/test/TrancheMirrorTest.t.sol @@ -7,34 +7,46 @@ import "test/util/TrancheMirrorUtils.sol"; import "src/TrancheMirror.sol"; contract TrancheMirrorTest is TrancheMirrorUtils { - - function testParseOrder() public { - console2.log("PARSER : ",address(PARSER)); - console2.log("INTERPRETER : ",address(INTERPRETER)); - console2.log("STORE : ",address(STORE)); - console2.log("EXPRESSION_DEPLOYER : ",address(EXPRESSION_DEPLOYER)); - console2.log("ORDERBOOK_SUPARSER : ",address(ORDERBOOK_SUPARSER)); - - - PARSER.parse( - LibTrancheSpreadOrders.getTrancheSpreadBuyOrder( - vm, - address(ORDERBOOK_SUPARSER) - ) - ); - } - function testParseOrderRainlang() public { - console2.log("PARSER : ",address(PARSER)); - console2.log("INTERPRETER : ",address(INTERPRETER)); - console2.log("STORE : ",address(STORE)); - console2.log("EXPRESSION_DEPLOYER : ",address(EXPRESSION_DEPLOYER)); - console2.log("ORDERBOOK_SUPARSER : ",address(ORDERBOOK_SUPARSER)); - - bytes memory rainlang = "_: decimal18-saturating-sub(2 2);"; - PARSER.parse( - rainlang - ); + function test_trancheModelling() public { + string memory file = "./test/csvs/tranche-space.csv"; + if (vm.exists(file)) vm.removeFile(file); + + FullyQualifiedNamespace namespace = + LibNamespace.qualifyNamespace(StateNamespace.wrap(uint256(uint160(ORDER_OWNER))), address(ORDERBOOK)); + + uint256[][] memory buyOrderContext = getBuyOrderContext(11223344); + + + for (uint256 i = 0; i < 200; i++) { + uint256 trancheSpace = uint256(1e17 * i); + + address expression; + { + (bytes memory bytecode, uint256[] memory constants) = PARSER.parse( + LibTrancheSpreadOrders.getTrancheSpreadOrder( + vm, + address(ORDERBOOK_SUPARSER), + trancheSpace, + 101e16 + ) + ); + (,, expression,) = EXPRESSION_DEPLOYER.deployExpression2(bytecode, constants); + } + + (uint256[] memory buyStack,) = IInterpreterV2(INTERPRETER).eval2( + IInterpreterStoreV1(address(STORE)), + namespace, + LibEncodedDispatch.encode2(expression, SourceIndexV2.wrap(0), type(uint32).max), + buyOrderContext, + new uint256[](0) + ); + + string memory line = string.concat(uint2str(trancheSpace), ",", uint2str(buyStack[1]), ",", uint2str(buyStack[0])); + + vm.writeLine(file, line); + + } } } diff --git a/test/util/TrancheMirrorUtils.sol b/test/util/TrancheMirrorUtils.sol index f57e5a1..14ea3dd 100644 --- a/test/util/TrancheMirrorUtils.sol +++ b/test/util/TrancheMirrorUtils.sol @@ -62,4 +62,99 @@ contract TrancheMirrorUtils is RainContracts, Test { CLONE_FACTORY = ICloneableFactoryV2(0x6d0c39093C21dA1230aCDD911420BBfA353A3FBA); } + function getSellOrderContext(uint256 orderHash) internal view returns (uint256[][] memory context) { + // Sell Order Context + context = new uint256[][](5); + { + { + uint256[] memory baseContext = new uint256[](2); + context[0] = baseContext; + } + { + uint256[] memory callingContext = new uint256[](3); + // order hash + callingContext[0] = orderHash; + // owner + callingContext[1] = uint256(uint160(address(ORDER_OWNER))); + // counterparty + callingContext[2] = uint256(uint160(address(ORDERBOOK))); + context[1] = callingContext; + } + { + uint256[] memory calculationsContext = new uint256[](0); + context[2] = calculationsContext; + } + { + uint256[] memory inputsContext = new uint256[](CONTEXT_VAULT_IO_ROWS); + inputsContext[0] = uint256(uint160(address(WETH_TOKEN))); + inputsContext[1] = 18; + context[3] = inputsContext; + } + { + uint256[] memory outputsContext = new uint256[](CONTEXT_VAULT_IO_ROWS); + outputsContext[0] = uint256(uint160(address(IEON_TOKEN))); + outputsContext[1] = 18; + context[4] = outputsContext; + } + } + } + + function getBuyOrderContext(uint256 orderHash) internal view returns (uint256[][] memory context) { + // Buy Order Context + context = new uint256[][](5); + { + { + uint256[] memory baseContext = new uint256[](2); + context[0] = baseContext; + } + { + uint256[] memory callingContext = new uint256[](3); + // order hash + callingContext[0] = orderHash; + // owner + callingContext[1] = uint256(uint160(address(ORDERBOOK))); + // counterparty + callingContext[2] = uint256(uint160(address(ARB_INSTANCE))); + context[1] = callingContext; + } + { + uint256[] memory calculationsContext = new uint256[](0); + context[2] = calculationsContext; + } + { + uint256[] memory inputsContext = new uint256[](CONTEXT_VAULT_IO_ROWS); + inputsContext[0] = uint256(uint160(address(IEON_TOKEN))); + inputsContext[1] = 18; + context[3] = inputsContext; + } + { + uint256[] memory outputsContext = new uint256[](CONTEXT_VAULT_IO_ROWS); + outputsContext[0] = uint256(uint160(address(WETH_TOKEN))); + outputsContext[1] = 18; + context[4] = outputsContext; + } + } + } + + function eval(bytes memory rainlang, uint256[][] memory context) public returns (uint256[] memory) { + (bytes memory bytecode, uint256[] memory constants) = PARSER.parse(rainlang); + (,, address expression,) = EXPRESSION_DEPLOYER.deployExpression2(bytecode, constants); + return evalDeployedExpression(expression, ORDER_HASH, context); + } + + function evalDeployedExpression(address expression, bytes32 orderHash, uint256[][] memory context) public view returns (uint256[] memory) { + + FullyQualifiedNamespace namespace = + LibNamespace.qualifyNamespace(StateNamespace.wrap(uint256(uint160(ORDER_OWNER))), address(ORDERBOOK)); + + (uint256[] memory stack,) = IInterpreterV2(INTERPRETER).eval2( + IInterpreterStoreV1(address(STORE)), + namespace, + LibEncodedDispatch.encode2(expression, SourceIndexV2.wrap(0), type(uint16).max), + context, + new uint256[](0) + ); + return stack; + } + } \ No newline at end of file diff --git a/test/vg/tranche-space-amount.vg b/test/vg/tranche-space-amount.vg new file mode 100644 index 0000000..8833cb9 --- /dev/null +++ b/test/vg/tranche-space-amount.vg @@ -0,0 +1,114 @@ +{ + "$schema": "https://vega.github.io/schema/vega/v5.json", + "title": { + "text": "IOEN Tranche Space Strategy: Buy Order", + "subtitle": [ + "", + "Distributor token : Polygon IOEN", + "Reserve token : Polygon WETH", + "Tranche reserve base amount : 100 ETH", + "Tranche reserve base io ratio : 1.11", + "Tranche space threshold : 0.01", + "Spread Ratio : 1.01" + ], + "encode":{ + "title": { + "update": { + "fontSize": {"value": 15} + } + }, + "subtitle": { + "interactive": true, + "hover": { + "fontStyle": {"value": "normal"} + } + } + } + }, + "width": 800, + "height": 500, + "padding": 15, + "autosize": "pad", + "data": [{ + "name": "tranche-space", + "transform": [ + { "type": "formula","as": "trancheSpaceScaled", "expr": "(datum.trancheSpace)/(1e+18)" }, + { "type": "formula","as": "amountScaled", "expr": "(datum.amount)/(1e+18)" }, + { "type": "formula","as": "ratioScaled", "expr": "(datum.ratio)/(1e+18)" } + + ], + "format": { + "type": "csv", + "parse": { + "trancheSpace": "number", + "amount": "number", + "ratio": "number" + }, + "header": ["trancheSpace","amount","ratio"] + }, + "url": "../csvs/tranche-space.csv" + }], + "scales": [{ + "name": "x", + "type": "linear", + "range": "width", + "domain": {"data": "tranche-space", "field": "trancheSpaceScaled"} + }, { + "name": "y", + "type": "linear", + "range": "height", + "domain": {"data": "tranche-space", "field": "amountScaled"} + }], + "axes": [ + { + "orient": "bottom", + "scale": "x", + "title": "Fixed point tranche space", + "encode": { + "labels": { + "update": { + "fontSize": {"value": 14} + } + }, + "title": { + "update": { + "fontSize": {"value": 14} + } + } + } + }, + { + "orient": "left", + "scale": "y", + "grid": true, + "title": "Fixed point amount", + "encode": { + "labels": { + "update": { + "fontSize": {"value": 14} + } + }, + "title": { + "update": { + "fontSize": {"value": 14} + } + } + } + } + + ], + "marks": [{ + "type": "symbol", + "from": {"data": "tranche-space"}, + "encode": { + "enter": { + "x": {"type": "quantitative","scale": "x", "field": "trancheSpaceScaled"}, + "y": {"type": "quantitative","scale": "y", "field": "amountScaled"}, + "fill": {"value": "steelblue"}, + "angle": {"value": 45}, + "shape": {"value": "cross"}, + "size": {"value": 30} + } + } + }] + } \ No newline at end of file