import { Fraction } from '@uniswap/sdk-core'; import JSBI from 'jsbi'; export const X128 = BigInt(2) ** BigInt(128); export function ratioX128FromAmounts(t0: bigint, t1: bigint): bigint { if (t1 === 0n) return MAX_UINT256; return (t0 * X128) / t1; } export function ratioX128FromFraction(fr: Fraction): bigint { const denom = fr.denominator.toString(); if (denom === '0') return MAX_UINT256; const num = BigInt(fr.numerator.toString()); return (num * X128) / BigInt(denom); } export function absRatioDiffX128(aX128: bigint, bX128: bigint): bigint { return aX128 >= bX128 ? aX128 - bX128 : bX128 - aX128; } export function compareRatioX128(aX128: bigint, bX128: bigint): number { if (aX128 === bX128) return 0; return aX128 > bX128 ? 1 : -1; } export function withinToleranceByX128( heldT0: bigint, heldT1: bigint, desired: Fraction, tol: Fraction, ): boolean { const desiredDenom = desired.denominator.toString(); if (desiredDenom === '0') { return heldT1 === 0n; } const desiredX128 = ratioX128FromFraction(desired); const heldX128 = ratioX128FromAmounts(heldT0, heldT1); if (heldX128 === MAX_UINT256) return false; const diff = absRatioDiffX128(heldX128, desiredX128); const tolScaled = (desiredX128 * BigInt(tol.numerator.toString())) / BigInt(tol.denominator.toString()); return diff <= tolScaled; } export function fractionAbsoluteValue(fraction: Fraction): Fraction { const numeratorAbs = JSBI.lessThan(fraction.numerator, JSBI.BigInt(0)) ? JSBI.unaryMinus(fraction.numerator) : fraction.numerator; const denominatorAbs = JSBI.lessThan(fraction.denominator, JSBI.BigInt(0)) ? JSBI.unaryMinus(fraction.denominator) : fraction.denominator; return new Fraction(numeratorAbs, denominatorAbs); } export const MAX_UINT256 = BigInt( '0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff', );