price constraints working
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
# this script requires the jq command $(sudo apt install jq)
|
||||
|
||||
# first-pass build
|
||||
forge build "$@" || exit 1
|
||||
forge build --force "$@" || exit 1
|
||||
|
||||
# calculate the Vault init code hash using the bytecode generated for Vault
|
||||
# shellcheck disable=SC2046
|
||||
|
||||
@@ -220,11 +220,14 @@ library OrderLib {
|
||||
// c.valueSqrtX96 = uint160(price * c.valueSqrtX96 / 2**96);
|
||||
int256 limit256 = int256(uint256(lc.valueSqrtX96));
|
||||
if( lc.slopeSqrtX96 != 0 ) {
|
||||
// todo cannot add square roots.
|
||||
limit256 += int256(block.timestamp - lc.time) * lc.slopeSqrtX96 / 2**96;
|
||||
if( limit256 < 0 )
|
||||
limit256 = 0;
|
||||
}
|
||||
console2.log(limit256);
|
||||
console2.log(price);
|
||||
console2.log(lc.isAbove);
|
||||
uint160 limit = uint160(uint256(limit256));
|
||||
// use <= and >= here because trading AT the limit results in 0 volume. price must exceed the limit.
|
||||
if( lc.isAbove && price <= limit || !lc.isAbove && price >= limit )
|
||||
@@ -254,6 +257,10 @@ library OrderLib {
|
||||
- (status.order.amountIsInput ? status.trancheFilledIn[trancheIndex] : status.trancheFilledOut[trancheIndex]); // minus tranche fills
|
||||
console2.log('amount');
|
||||
console2.log(amount);
|
||||
console2.log('limit');
|
||||
console2.log(sqrtPriceLimitX96);
|
||||
console2.log('price');
|
||||
console2.log(sqrtPriceX96);
|
||||
// order amount remaining
|
||||
require( (status.order.amountIsInput ? status.filledIn : status.filledOut) <= status.order.amount, 'OVERFILL' );
|
||||
uint256 remaining = status.order.amount - (status.order.amountIsInput ? status.filledIn : status.filledOut);
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
// SPDX-License-Identifier: UNLICENSED
|
||||
//pragma solidity =0.7.6;
|
||||
pragma solidity >=0.8.0;
|
||||
pragma abicoder v2;
|
||||
|
||||
@@ -9,6 +8,8 @@ import "./OrderLib.sol";
|
||||
import "./Vault.sol";
|
||||
import "./VaultDeployer.sol";
|
||||
import "./Factory.sol";
|
||||
import "forge-std/console2.sol";
|
||||
|
||||
|
||||
contract QueryHelper {
|
||||
uint8 constant public version = 1;
|
||||
@@ -47,28 +48,40 @@ contract QueryHelper {
|
||||
function getRoutes( address tokenA, address tokenB ) public view
|
||||
returns(RoutesResult[] memory routes) {
|
||||
// todo discover all supported pools
|
||||
console2.log('getRoutes');
|
||||
console2.log(tokenA);
|
||||
console2.log(tokenB);
|
||||
// here we find the highest liquidity pool for v2 and for v3
|
||||
uint24[4] memory fees = [uint24(100),500,3000,10000];
|
||||
uint24 uniswapV2Fee = 0;
|
||||
// uint128 uniswapV2Liquidity = 0;
|
||||
// address uniswapV2Pool = address(0);
|
||||
uint24 uniswapV3Fee = 0;
|
||||
uint128 uniswapV3Liquidity = 0;
|
||||
uint256 uniswapV3Liquidity = 0;
|
||||
address uniswapV3Pool = address(0);
|
||||
IERC20 ercA = IERC20(tokenA);
|
||||
for( uint8 f=0; f<4; f++ ) {
|
||||
IUniswapV3Pool pool = IUniswapV3Pool(Constants.uniswapV3Factory.getPool(tokenA, tokenB, fees[f]));
|
||||
try pool.liquidity() returns (uint128 liquidity) {
|
||||
// todo v2
|
||||
if( liquidity > uniswapV3Liquidity ) {
|
||||
uniswapV3Fee = fees[f];
|
||||
uniswapV3Liquidity = liquidity;
|
||||
uniswapV3Pool = address(pool);
|
||||
}
|
||||
console2.log('getPool..');
|
||||
uint24 fee = fees[f];
|
||||
IUniswapV3Pool pool = IUniswapV3Pool(Constants.uniswapV3Factory.getPool(tokenA, tokenB, fee));
|
||||
if( address(pool) == address(0) ) {
|
||||
console2.log('no pool');
|
||||
continue;
|
||||
}
|
||||
catch {
|
||||
console2.log('gotPool.');
|
||||
console2.log(address(pool));
|
||||
// NOTE: pool.liquidity() is only the current tick's liquidity, so we look at the pool's balance
|
||||
// of one of the tokens as a measure of liquidity
|
||||
uint256 liquidity = ercA.balanceOf(address(pool));
|
||||
if( liquidity > uniswapV3Liquidity ) {
|
||||
uniswapV3Fee = fee;
|
||||
uniswapV3Liquidity = liquidity;
|
||||
uniswapV3Pool = address(pool);
|
||||
}
|
||||
}
|
||||
uint8 routesCount = uniswapV3Fee > 0 ? 1 : 0 + uniswapV2Fee > 0 ? 1 : 0;
|
||||
console2.log(uniswapV3Pool);
|
||||
console2.log(uint(routesCount));
|
||||
routes = new QueryHelper.RoutesResult[](routesCount);
|
||||
uint8 i = 0;
|
||||
// todo v2
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
// SPDX-License-Identifier: UNLICENSED
|
||||
//pragma solidity =0.7.6;
|
||||
pragma solidity >=0.8.0;
|
||||
pragma abicoder v2;
|
||||
|
||||
@@ -15,7 +14,7 @@ library UniswapSwapper {
|
||||
address pool;
|
||||
address tokenIn;
|
||||
address tokenOut;
|
||||
address recipient;
|
||||
address recipient; // todo refactor back into bool outputToOwner to save space and constrain the money path
|
||||
uint24 fee;
|
||||
uint256 amount;
|
||||
uint160 sqrtPriceLimitX96;
|
||||
@@ -135,4 +134,19 @@ library UniswapSwapper {
|
||||
TransferHelper.safeApprove(params.tokenIn, address(Constants.uniswapV3SwapRouter), 0);
|
||||
}
|
||||
|
||||
// from https://github.com/ethereum/dapp-bin/pull/50/files
|
||||
// the same logic as UniswapV2's version of sqrt
|
||||
function sqrt(uint x) internal pure returns (uint y) {
|
||||
// todo overflow is not possible in this algorithm, correct? we map wrap it in unchecked {}
|
||||
if (x == 0) return 0;
|
||||
else if (x <= 3) return 1;
|
||||
uint z = (x + 1) / 2;
|
||||
y = x;
|
||||
while (z < y)
|
||||
{
|
||||
y = z;
|
||||
z = (x / z + z) / 2;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -41,7 +41,8 @@ contract MockEnv {
|
||||
inverted = address(COIN) > address(USD);
|
||||
token0 = inverted ? address(USD) : address(COIN);
|
||||
token1 = inverted ? address(COIN) : address(USD);
|
||||
uint160 initialPrice = uint160(79228162514264337593543); // price 1e-12 = sqrt price 1e-6 = 2**96 / 10**6
|
||||
// uint160 initialPrice = uint160(79228162514264337593543); // price 1e-12 = sqrt price 1e-6 = 2**96 / 10**6
|
||||
uint160 initialPrice = uint160(79228162514264337593543950336000000); // $1.00
|
||||
console2.log('if this is the last line before a revert then make sure to run forge with --rpc-url');
|
||||
// if this reverts here make sure Anvil is started and you are running forge with --rpc-url
|
||||
pool = IUniswapV3Pool(nfpm.createAndInitializePoolIfNecessary(token0, token1, fee, initialPrice));
|
||||
@@ -138,8 +139,8 @@ contract MockEnv {
|
||||
return swapper.exactInputSingle(params);
|
||||
}
|
||||
|
||||
function price() public view returns (uint160 sqrtPrice) {
|
||||
(sqrtPrice,,,,,,) = pool.slot0();
|
||||
function price() public view returns (uint160 sqrtPriceX96) {
|
||||
(sqrtPriceX96,,,,,,) = pool.slot0();
|
||||
}
|
||||
|
||||
function swapToPrice(uint160 sqrtPriceLimitX96) public {
|
||||
|
||||
Reference in New Issue
Block a user