Skip to content

Commit

Permalink
Fix sor liq (#196)
Browse files Browse the repository at this point in the history
* fix in norm liquidity calcs

* priceimpact calc can revert, workaround

* add share if 2 paths

* possible undefined priceimpact
  • Loading branch information
franzns authored Mar 11, 2024
1 parent 159666f commit 454e405
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 14 deletions.
33 changes: 22 additions & 11 deletions modules/pool/lib/pool-on-chain-tokenpair-data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ export async function fetchTokenPairData(pools: PoolInput[], balancerQueriesAddr

// only inlcude pools with TVL >=$1000
// for each pool, get pairs
// for each pair per pool, create multicall to do a swap with $200 (min liq is $1k, so there should be at least $200 for each token) for effectivePrice calc and a swap with 1% TVL
// for each pair per pool, create multicall to do a swap with $100 (min liq is $1k, so there should be at least $100 for each token) for effectivePrice calc and a swap with 1% TVL
// then create multicall to do the second swap for each pair using the result of the first 1% swap as input, to calculate the spot price
// https://github.com/balancer/b-sdk/pull/204/files#diff-52e6d86a27aec03f59dd3daee140b625fd99bd9199936bbccc50ee550d0b0806

Expand Down Expand Up @@ -158,8 +158,8 @@ function generateTokenPairs(filteredPools: PoolInput[]): TokenPair[] {
// remove pools that have <$1000 TVL or a token without a balance or USD balance
valid:
(pool.dynamicData?.totalLiquidity || 0) >= 1000 &&
!pool.tokens.some((token) => token.dynamicData?.balance || '0' === '0') &&
!pool.tokens.some((token) => token.dynamicData?.balanceUSD || 0 === 0),
!pool.tokens.some((token) => (token.dynamicData?.balance || '0') === '0') &&
!pool.tokens.some((token) => (token.dynamicData?.balanceUSD || 0) === 0),

tokenA: {
address: pool.tokens[i].address,
Expand Down Expand Up @@ -262,20 +262,20 @@ function addBToAPriceCallsToMulticaller(
function getAmountOutAndEffectivePriceFromResult(tokenPair: TokenPair, onchainResults: { [id: string]: OnchainData }) {
const result = onchainResults[`${tokenPair.poolId}-${tokenPair.tokenA.address}-${tokenPair.tokenB.address}`];

if (result) {
if (result.effectivePriceAmountOut && result.aToBAmountOut) {
tokenPair.aToBAmountOut = BigInt(result.aToBAmountOut.toString());
// MathSol expects all values with 18 decimals, need to scale them
tokenPair.effectivePrice = MathSol.divDownFixed(
parseUnits(tokenPair.effectivePriceAmountIn.toString(), 18 - tokenPair.tokenA.decimals),
parseUnits(result.effectivePriceAmountOut.toString(), 18 - tokenPair.tokenB.decimals),
parseUnits(result.effectivePriceAmountOut?.toString(), 18 - tokenPair.tokenB.decimals),
);
}
}

function getBToAAmountFromResult(tokenPair: TokenPair, onchainResults: { [id: string]: OnchainData }) {
const result = onchainResults[`${tokenPair.poolId}-${tokenPair.tokenA.address}-${tokenPair.tokenB.address}`];

if (result) {
if (result.bToAAmountOut) {
tokenPair.bToAAmountOut = BigInt(result.bToAAmountOut.toString());
}
}
Expand All @@ -284,9 +284,14 @@ function calculateSpotPrice(tokenPair: TokenPair) {
const aToBAmountInScaled = parseUnits(tokenPair.aToBAmountIn.toString(), 18 - tokenPair.tokenA.decimals);
const aToBAmountOutScaled = parseUnits(tokenPair.aToBAmountOut.toString(), 18 - tokenPair.tokenB.decimals);
const bToAAmountOutScaled = parseUnits(tokenPair.bToAAmountOut.toString(), 18 - tokenPair.tokenA.decimals);
const priceAtoB = MathSol.divDownFixed(aToBAmountInScaled, aToBAmountOutScaled);
const priceBtoA = MathSol.divDownFixed(aToBAmountOutScaled, bToAAmountOutScaled);
tokenPair.spotPrice = MathSol.powDownFixed(MathSol.divDownFixed(priceAtoB, priceBtoA), WAD / 2n);
if (aToBAmountInScaled !== 0n && aToBAmountOutScaled !== 0n && bToAAmountOutScaled !== 0n) {
const priceAtoB = MathSol.divDownFixed(aToBAmountInScaled, aToBAmountOutScaled);
const priceBtoA = MathSol.divDownFixed(aToBAmountOutScaled, bToAAmountOutScaled);
tokenPair.spotPrice = MathSol.powDownFixed(MathSol.divDownFixed(priceAtoB, priceBtoA), WAD / 2n);
} else {
// this happens if any of the swaps reverted on-chain. Either the tokenBalance in the pool was <100 USD or RPC failed.
tokenPair.spotPrice = 0n;
}
}

function calculateNormalizedLiquidity(tokenPair: TokenPair) {
Expand All @@ -300,6 +305,12 @@ function calculateNormalizedLiquidity(tokenPair: TokenPair) {
);
priceRatio = parseEther('0.999999');
}
const priceImpact = WAD - priceRatio;
tokenPair.normalizedLiqudity = MathSol.divDownFixed(WAD, priceImpact);
if (priceRatio !== 0n) {
const priceImpact = WAD - priceRatio;
tokenPair.normalizedLiqudity = MathSol.divDownFixed(WAD, priceImpact);
} else {
// can happen if the pair could not be priced on-chain and everything is 0 (aToBAmount, effectivePrice, etc) and hence the spotPrice is 0.
// if that happens, normalizedLiquidity should be 0 as well.
tokenPair.normalizedLiqudity = 0n;
}
}
2 changes: 1 addition & 1 deletion modules/sor/sor.gql
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ type GqlSorGetSwapPaths {
"""
Price impact in percent. 0.01 -> 0.01%
"""
priceImpact: AmountHumanReadable!
priceImpact: AmountHumanReadable
}

"""
Expand Down
9 changes: 7 additions & 2 deletions modules/sor/sorV2/sorPathService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,12 @@ class SorPathService implements SwapService {
}

// price impact does not take the updatedAmount into account
const priceImpact = calculatePriceImpact(paths, swapKind).decimal.toFixed(4);
let priceImpact: string | undefined;
try {
priceImpact = calculatePriceImpact(paths, swapKind).decimal.toFixed(4);
} catch (error) {
priceImpact = undefined;
}

// get all affected pools
let poolIds: string[] = [];
Expand Down Expand Up @@ -386,7 +391,7 @@ class SorPathService implements SwapService {
tokenOut,
tokenInAmount,
tokenOutAmount,
share: 0, // TODO needed?
share: 0.5, // TODO needed?
hops: path.pools.map((pool, i) => {
return {
tokenIn: `${path.tokens[i].address}`,
Expand Down

0 comments on commit 454e405

Please sign in to comment.