153 lines
5.4 KiB
Solidity
153 lines
5.4 KiB
Solidity
|
|
pragma solidity 0.8.26;
|
|
|
|
import "@forge-std/Test.sol";
|
|
import "@forge-std/console2.sol";
|
|
import {MockEnv, MockERC20} from "./MockEnv.sol";
|
|
import {VaultFactory} from "../src/core/VaultFactory.sol";
|
|
import {Dexorder} from "../src/more/Dexorder.sol";
|
|
import {IVault} from "../src/interface/IVault.sol";
|
|
import "../src/core/OrderSpec.sol";
|
|
import {float} from "../src/core/IEEE754.sol";
|
|
|
|
contract TestOrder is MockEnv, Test {
|
|
|
|
IVault public vault;
|
|
|
|
// vault gets 100,000 COIN and 100,000 USD
|
|
function setUp() public virtual {
|
|
initNoFees();
|
|
vault = IVault(factory.deployVault(address(this)));
|
|
uint256 coinAmount = 100_000 * 10 ** COIN.decimals();
|
|
COIN.mint(address(vault), coinAmount);
|
|
uint256 usdAmount = 100_000 * 10 ** USD.decimals();
|
|
USD.mint(address(vault), usdAmount);
|
|
}
|
|
|
|
|
|
function testPlaceOrder() public {
|
|
placeOrder();
|
|
}
|
|
|
|
|
|
function placeOrder() public {
|
|
Tranche[] memory tranches = new Tranche[](3);
|
|
tranches[0].fraction = 21845;
|
|
tranches[0].startTimeIsRelative = true;
|
|
tranches[0].startTime = 0;
|
|
tranches[1].fraction = 21845;
|
|
tranches[1].startTimeIsRelative = true;
|
|
tranches[1].startTime = 60;
|
|
tranches[2].fraction = 21845;
|
|
tranches[2].startTimeIsRelative = true;
|
|
tranches[2].startTime = 120;
|
|
uint256 amount = 100000000000000000000;
|
|
SwapOrder memory order = SwapOrder(
|
|
0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9, 0x82aF49447D8a07e3bd95BD0d56f35241523fBab1,
|
|
Route(Exchange.UniswapV3, 500), amount, amount/100, true, false, false,
|
|
NO_CONDITIONAL_ORDER, tranches
|
|
);
|
|
console2.logBytes(abi.encode(order));
|
|
console2.log("testPlaceOrder: calling vault.numSwapOrders");
|
|
console2.log(vault.numSwapOrders());
|
|
|
|
console2.log("testPlaceOrder: Placing order");
|
|
vault.placeDexorder(order);
|
|
}
|
|
}
|
|
|
|
contract TestExecute is TestOrder {
|
|
|
|
uint256 public coinInitialBalance;
|
|
uint256 public usdInitialBalance;
|
|
uint64 public exactOutputOrderIndex;
|
|
uint64 public exactInputOrderIndex;
|
|
uint64 public limitOrderIndex;
|
|
|
|
function setUp() public override {
|
|
TestOrder.setUp();
|
|
|
|
coinInitialBalance = 1_000_000 * 10**COIN.decimals();
|
|
usdInitialBalance = 1_000_000 * 10**USD.decimals();
|
|
COIN.mint(address(vault), coinInitialBalance);
|
|
USD.mint(address(vault), usdInitialBalance);
|
|
|
|
// #0: Exact Output Order
|
|
Tranche[] memory tranches = new Tranche[](1);
|
|
tranches[0].fraction = MAX_FRACTION;
|
|
tranches[0].endTime = DISTANT_FUTURE;
|
|
tranches[0].marketOrder = true;
|
|
uint256 amount = 3 * 10**USD.decimals() / 10; // 0.3 USD
|
|
SwapOrder memory order = SwapOrder(
|
|
address(COIN), address(USD), // sell COIN for USD
|
|
Route(Exchange.UniswapV3, 500), amount, amount/100, false, false,
|
|
false, NO_CONDITIONAL_ORDER, tranches
|
|
);
|
|
exactOutputOrderIndex = vault.numSwapOrders();
|
|
vault.placeDexorder(order);
|
|
|
|
// #1: Exact Input Order
|
|
tranches = new Tranche[](1);
|
|
tranches[0].fraction = MAX_FRACTION;
|
|
tranches[0].endTime = DISTANT_FUTURE;
|
|
tranches[0].marketOrder = true;
|
|
amount = 3 * 10**COIN.decimals() / 10; // 0.3 COIN
|
|
order = SwapOrder(
|
|
address(COIN), address(USD), // sell COIN for USD
|
|
Route(Exchange.UniswapV3, fee), amount, amount/100, true, false,
|
|
false, NO_CONDITIONAL_ORDER, tranches
|
|
);
|
|
exactInputOrderIndex = vault.numSwapOrders();
|
|
vault.placeDexorder(order);
|
|
|
|
buildLimitOrder();
|
|
|
|
}
|
|
|
|
function testExecuteOrderExactOutput() public {
|
|
vault.execute(exactOutputOrderIndex, 0, PriceProof(0));
|
|
}
|
|
|
|
|
|
function testExecuteOrderExactInput() public {
|
|
vault.execute(exactInputOrderIndex, 0, PriceProof(0));
|
|
}
|
|
|
|
|
|
function buildLimitOrder() private {
|
|
// #2: Limit Order
|
|
// test selling token0 above a certain price
|
|
Tranche[] memory tranches = new Tranche[](1);
|
|
tranches[0].fraction = MAX_FRACTION;
|
|
tranches[0].endTime = DISTANT_FUTURE;
|
|
tranches[0].minLine.intercept = inverted ? float.wrap(0x5368da9b) : float.wrap(0x2b8cc066); // float 1.0001e±12
|
|
MockERC20 token = MockERC20(token0);
|
|
uint256 amount = 3*10**token.decimals() / 10; // selling 0.3 token0
|
|
SwapOrder memory order = SwapOrder(
|
|
token0, token1, // sell
|
|
Route(Exchange.UniswapV3, fee), amount, amount/100, true, false,
|
|
false, NO_CONDITIONAL_ORDER, tranches
|
|
);
|
|
limitOrderIndex = vault.numSwapOrders();
|
|
vault.placeDexorder(order);
|
|
}
|
|
|
|
function testExecuteLimitOrder() public {
|
|
swapTo1();
|
|
vm.expectRevert(bytes('LL'));
|
|
// should revert with code 'LL' because the initial limit is above the current price
|
|
vault.execute(limitOrderIndex, 0, PriceProof(0));
|
|
console2.log('inverted');
|
|
console2.log(inverted);
|
|
console2.log('original price');
|
|
console2.log(price());
|
|
// better price for token0
|
|
uint160 newPrice = oneSqrtX96()*10002/10000;
|
|
swapToPrice(newPrice); // move price to be above our limit
|
|
console2.log('new price');
|
|
console2.log(newPrice);
|
|
vault.execute(limitOrderIndex, 0, PriceProof(0)); // should work now
|
|
}
|
|
|
|
}
|