Skip to content

Commit

Permalink
tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Siddharth2207 committed Feb 27, 2024
1 parent 64d7002 commit 16e0ba4
Show file tree
Hide file tree
Showing 5 changed files with 245 additions and 37 deletions.
99 changes: 97 additions & 2 deletions src/TrancheMirror.sol
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ uint256 constant VAULT_ID = uint256(keccak256("vault"));
address constant POLYGON_IEON_HOLDER = 0xd6756f5aF54486Abda6bd9b1eee4aB0dBa7C3ef2;
// USDT token holder.
address constant POLYGON_USDT_HOLDER = 0xF977814e90dA44bFA03b6295A0616a897441aceC;
// Wrapped native token holder.
address constant POLYGON_WETH_HOLDER = 0x8C81A2c64Bf001b03AfB3c513a7be223Ba23de1B;


/// @dev https://polygonscan.com/address/0x5757371414417b8C6CAad45bAeF941aBc7d3Ab32
address constant UNI_V2_FACTORY = 0x5757371414417b8C6CAad45bAeF941aBc7d3Ab32;
Expand All @@ -39,6 +42,56 @@ IERC20 constant WETH_TOKEN = IERC20(0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270);
/// @dev https://docs.sushi.com/docs/Products/Classic%20AMM/Deployment%20Addresses
address constant POLYGON_SUSHI_V2_ROUTER = 0x1b02dA8Cb0d097eB8D57A175b88c7D8b47997506;

bytes constant SELL_ROUTE =
//offset
hex"0000000000000000000000000000000000000000000000000000000000000020"
//stream length
hex"0000000000000000000000000000000000000000000000000000000000000042"
//command 2 = processUserERC20
hex"02"
//token address
hex"d0e9c8f5fae381459cf07ec506c1d2896e8b5df6"
//number of pools
hex"01"
// pool share
hex"ffff"
// pool type
hex"00"
// pool address
hex"316bc12871c807020ef8c1bc7771061c4e7a04ed"
// direction 1
hex"00"
// to
hex"0D7896d70FE84e88CC8e8BaDcB14D612Eee4Bbe0"
// padding
hex"000000000000000000000000000000000000000000000000000000000000";

bytes constant BUY_ROUTE =
//offset
hex"0000000000000000000000000000000000000000000000000000000000000020"
//stream length
hex"0000000000000000000000000000000000000000000000000000000000000042"
//command 2 = processUserERC20
hex"02"
//token address
hex"0d500b1d8e8ef31e21c99d1db9a6444d3adf1270"
//number of pools
hex"01"
// pool share
hex"ffff"
// pool type
hex"00"
// pool address
hex"316bc12871c807020ef8c1bc7771061c4e7a04ed"
// direction 1
hex"01"
// to
hex"0D7896d70FE84e88CC8e8BaDcB14D612Eee4Bbe0"
// padding
hex"000000000000000000000000000000000000000000000000000000000000";



function polygonIeonIo() pure returns (IO memory) {
return IO(address(IEON_TOKEN), 18, VAULT_ID);
}
Expand Down Expand Up @@ -69,9 +122,9 @@ function uint2str(uint256 _i) pure returns (string memory _uintAsString) {
return string(bstr);
}
library LibTrancheSpreadOrders {
using Strings for address;//100 000000000000000000 //909909909909909909
using Strings for address;

function getTrancheSpreadOrder(
function getTrancheTestSpreadOrder(
Vm vm,
address orderBookSubparser,
uint256 testTrancheSpace,
Expand Down Expand Up @@ -117,6 +170,48 @@ library LibTrancheSpreadOrders {
trancheRefill = bytes.concat(getSubparserPrelude(orderBookSubparser), vm.ffi(ffi));
}

function getTrancheSpreadOrder(
Vm vm,
address orderBookSubparser
)
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] = "get-tranche-space='get-real-tranche-space";
ffi[15] = "--bind";
ffi[16] = "set-tranche-space='set-real-tranche-space";
ffi[17] = "--bind";
ffi[18] = "tranche-reserve-amount-growth='tranche-reserve-amount-growth-constant";
ffi[19] = "--bind";
ffi[20] = string.concat("tranche-reserve-amount-base=", uint2str(100e18));
ffi[21] = "--bind";
ffi[22] = "tranche-reserve-io-ratio-growth='tranche-reserve-io-ratio-linear";
ffi[23] = "--bind";
ffi[24] = string.concat("tranche-reserve-io-ratio-base=", uint2str(111e16));
ffi[25] = "--bind";
ffi[26] = string.concat("spread-ratio=", uint2str(101e16));
ffi[27] = "--bind";
ffi[28] = string.concat("tranche-space-edge-guard-threshold=", uint2str(1e16));


trancheRefill = bytes.concat(getSubparserPrelude(orderBookSubparser), vm.ffi(ffi));
}

function getSubparserPrelude(address obSubparser) internal pure returns (bytes memory) {
bytes memory RAINSTRING_OB_SUBPARSER =
bytes(string.concat("using-words-from ", obSubparser.toHexString(), " "));
Expand Down
52 changes: 52 additions & 0 deletions test/TrancheMirrorModeling.t.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// SPDX-License-Identifier: CAL
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 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.getTrancheTestSpreadOrder(
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);

}
}
}

123 changes: 92 additions & 31 deletions test/TrancheMirrorTest.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,47 +6,108 @@ import {console2, Test} from "forge-std/Test.sol";
import "test/util/TrancheMirrorUtils.sol";
import "src/TrancheMirror.sol";

contract TrancheMirrorTest is TrancheMirrorUtils {
contract TrancheMirrorTest is TrancheMirrorUtils {

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);
using SafeERC20 for IERC20;

function testBuyOrderHappyFork() public {
{
uint256 depositAmount = 1e10;
giveTestAccountsTokens(WETH_TOKEN, POLYGON_WETH_HOLDER, ORDER_OWNER, depositAmount);
depositTokens(ORDER_OWNER, WETH_TOKEN, VAULT_ID, depositAmount);
}
OrderV2 memory buyOrder;
{
(bytes memory bytecode, uint256[] memory constants) = PARSER.parse(
LibTrancheSpreadOrders.getTrancheSpreadOrder(
vm,
address(ORDERBOOK_SUPARSER)
)
);
buyOrder = placeOrder(ORDER_OWNER, bytecode, constants, polygonIeonIo(), polygonWethIo());
}
takeOrder(buyOrder, BUY_ROUTE);
}

for (uint256 i = 0; i < 200; i++) {
uint256 trancheSpace = uint256(1e17 * i);

address expression;
{
(bytes memory bytecode, uint256[] memory constants) = PARSER.parse(
function testSellOrderHappyFork() public {
{
uint256 depositAmount = 100e18;
giveTestAccountsTokens(IEON_TOKEN, POLYGON_IEON_HOLDER, ORDER_OWNER, depositAmount);
depositTokens(ORDER_OWNER, IEON_TOKEN, VAULT_ID, depositAmount);
}
OrderV2 memory sellOrder;
{
(bytes memory bytecode, uint256[] memory constants) = PARSER.parse(
LibTrancheSpreadOrders.getTrancheSpreadOrder(
vm,
address(ORDERBOOK_SUPARSER),
trancheSpace,
101e16
address(ORDERBOOK_SUPARSER)
)
);
(,, expression,) = EXPRESSION_DEPLOYER.deployExpression2(bytecode, constants);
}
);
sellOrder = placeOrder(ORDER_OWNER, bytecode, constants, polygonWethIo(), polygonIeonIo());
}
takeOrder(sellOrder, SELL_ROUTE);
}

(uint256[] memory buyStack,) = IInterpreterV2(INTERPRETER).eval2(
IInterpreterStoreV1(address(STORE)),
namespace,
LibEncodedDispatch.encode2(expression, SourceIndexV2.wrap(0), type(uint32).max),
buyOrderContext,
new uint256[](0)
);
function giveTestAccountsTokens(IERC20 token, address from, address to, uint256 amount) internal {
vm.startPrank(from);
token.safeTransfer(to, amount);
assertEq(token.balanceOf(to), amount);
vm.stopPrank();
}

string memory line = string.concat(uint2str(trancheSpace), ",", uint2str(buyStack[1]), ",", uint2str(buyStack[0]));
function depositTokens(address depositor, IERC20 token, uint256 vaultId, uint256 amount) internal {
vm.startPrank(depositor);
token.safeApprove(address(ORDERBOOK), amount);
ORDERBOOK.deposit(address(token), vaultId, amount);
vm.stopPrank();
}

vm.writeLine(file, line);
function placeOrder(
address orderOwner,
bytes memory bytecode,
uint256[] memory constants,
IO memory input,
IO memory output
) internal returns (OrderV2 memory order) {
IO[] memory inputs = new IO[](1);
inputs[0] = input;

}
IO[] memory outputs = new IO[](1);
outputs[0] = output;

EvaluableConfigV3 memory evaluableConfig = EvaluableConfigV3(EXPRESSION_DEPLOYER, bytecode, constants);

OrderConfigV2 memory orderConfig = OrderConfigV2(inputs, outputs, evaluableConfig, "");

vm.startPrank(orderOwner);
vm.recordLogs();

(bool stateChanged) = ORDERBOOK.addOrder(orderConfig);

Vm.Log[] memory entries = vm.getRecordedLogs();

assertEq(entries.length, 3);
(,, order,) = abi.decode(entries[2].data, (address, address, OrderV2, bytes32));
assertEq(order.owner, orderOwner);
assertEq(order.handleIO, true);
assertEq(address(order.evaluable.interpreter), address(INTERPRETER));
assertEq(address(order.evaluable.store), address(STORE));
assertEq(stateChanged, true);
}

function takeOrder(OrderV2 memory order, bytes memory route) internal {
vm.startPrank(APPROVED_EOA);

uint256 inputIOIndex = 0;
uint256 outputIOIndex = 0;

TakeOrderConfigV2[] memory innerConfigs = new TakeOrderConfigV2[](1);

innerConfigs[0] = TakeOrderConfigV2(order, inputIOIndex, outputIOIndex, new SignedContextV1[](0));
TakeOrdersConfigV2 memory takeOrdersConfig =
TakeOrdersConfigV2(0, type(uint256).max, type(uint256).max, innerConfigs, route);
ARB_INSTANCE.arb(takeOrdersConfig, 0);
vm.stopPrank();
}
}

4 changes: 2 additions & 2 deletions test/util/TrancheMirrorUtils.sol
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ contract TrancheMirrorUtils is RainContracts, Test {
using LibFixedPointDecimalArithmeticOpenZeppelin for uint256;
using LibFixedPointDecimalScale for uint256;

uint256 constant FORK_BLOCK_NUMBER = 53784754;
uint256 constant FORK_BLOCK_NUMBER = 54005438;
uint256 constant CONTEXT_VAULT_IO_ROWS = 5;

function selectPolygonFork() internal {
Expand Down Expand Up @@ -49,7 +49,7 @@ contract TrancheMirrorUtils is RainContracts, Test {
deployOrderBookSubparser();
deployUniswapWords(vm);

// PARSER = IParserV1(0xc2D7890077F3EA75c2798D8624E1E0E6ef8C41e6);
// PARSER = IParserV1(0xc2D7890077F3EA75c2798D8624E1E0E6ef8C41e6);
// INTERPRETER = IInterpreterV2(0xB7d691B7E3676cb70dB0cDae95797F24Eab6980D);
// STORE = IInterpreterStoreV2(0x0b5a2b0aCFc5B52bf341FAD638B63C9A6f82dcb9);
// EXPRESSION_DEPLOYER = IExpressionDeployerV3(0xE1E250a234aF6F343062873bf89c9D1a0a659c0b);
Expand Down
4 changes: 2 additions & 2 deletions test/vg/tranche-space-amount.vg
Original file line number Diff line number Diff line change
Expand Up @@ -98,13 +98,13 @@

],
"marks": [{
"type": "symbol",
"type": "line",
"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}
Expand Down

0 comments on commit 16e0ba4

Please sign in to comment.