Uniswap / v3-sdk

🛠 An SDK for building applications on top of Uniswap V3
MIT License
547 stars 425 forks source link

getOutputAmount(), calculates 0 for a lot of pairs #125

Closed chikko80 closed 2 years ago

chikko80 commented 2 years ago

Hello guys,

I am new to the SDK and there are a few things I don't really understand. Maybe someone can help. I am facing a lot of pairs there the SDK just can't calculate the Output Amount. I always get an Output Amount of 0. What's the problem? From my understanding, the SDK implements the same logic as the smart contracts that are running life, so i the question rises why the SDK isn't able to calculate the amount.

Example code that gives 0: (Fill the imports, i removed them cause i work with the SDK locally)

` import { ethers } from "ethers"; import { Pool } from import { TickMath } from import { nearestUsableTick } from import { CurrencyAmount, Token } from import { abi as IUniswapV3PoolABI } from import JSBI from "jsbi";

const provider = new ethers.providers.JsonRpcProvider("https://mainnet.infura.io/v3/<infura-id>");
const poolAddress = "0x18d96b617a3e5c42a2ada4bc5d1b48e223f17d0d";

const poolContract = new ethers.Contract(poolAddress, IUniswapV3PoolABI, provider);

interface Immutables {
factory: string;
token0: string;
token1: string;
fee: number;
tickSpacing: number;
maxLiquidityPerTick: ethers.BigNumber;
}

interface State {
liquidity: ethers.BigNumber;
sqrtPriceX96: ethers.BigNumber;
tick: number;
observationIndex: number;
observationCardinality: number;
observationCardinalityNext: number;
feeProtocol: number;
unlocked: boolean;
}

async function getPoolImmutables() {
const [factory, token0, token1, fee, tickSpacing, maxLiquidityPerTick] = await Promise.all([
    poolContract.factory(),
    poolContract.token0(),
    poolContract.token1(),
    poolContract.fee(),
    poolContract.tickSpacing(),
    poolContract.maxLiquidityPerTick(),
]);

const immutables: Immutables = {
    factory,
    token0,
    token1,
    fee,
    tickSpacing,
    maxLiquidityPerTick,
};
return immutables;
}

async function getPoolState() {
const [liquidity, slot] = await Promise.all([poolContract.liquidity(), poolContract.slot0()]);

const PoolState: State = {
    liquidity,
    sqrtPriceX96: slot[0],
    tick: slot[1],
    observationIndex: slot[2],
    observationCardinality: slot[3],
    observationCardinalityNext: slot[4],
    feeProtocol: slot[5],
    unlocked: slot[6],
};

return PoolState;
}

async function main() {

// const poolAddress = "0x9e0905249ceefffb9605e034b534544684a58be6";
const [immutables, state] = await Promise.all([getPoolImmutables(), getPoolState()]);

const TokenA = new Token(3, immutables.token0, 6, "USDC", "USDC");

const TokenB = new Token(3, immutables.token1, 18, "UST", "UST");

const ticks = [
    {
    index: nearestUsableTick(TickMath.MIN_TICK, immutables.tickSpacing),
    liquidityNet: 1,
    liquidityGross: 0,
    },
    {
    index: nearestUsableTick(TickMath.MAX_TICK, immutables.tickSpacing),
    liquidityNet: -1,
    liquidityGross: 0,
    },
];

const poolExample = new Pool(TokenA, TokenB, immutables.fee, state.sqrtPriceX96.toString(), state.liquidity.toString(), state.tick, ticks);

try {
    const ONE_TOKEN_IN = JSBI.exponentiate(JSBI.BigInt(10), JSBI.BigInt(6));
    const inputAmount = JSBI.multiply(JSBI.BigInt(100), ONE_TOKEN_IN);
    const [outputAmount] = await poolExample.getOutputAmount(CurrencyAmount.fromRawAmount(TokenA, inputAmount));
    console.log(outputAmount.numerator.toString())
    let result = JSBI.BigInt(outputAmount.numerator.toString())
    result = JSBI.divide(result, JSBI.exponentiate(JSBI.BigInt(10), JSBI.BigInt(8)))
    console.log(result.toString())
} catch (e) {
    console.log(e);
}
}

main();

`