Skip to content

Instantly share code, notes, and snippets.

@ruvaleev
Last active October 18, 2023 15:17
Show Gist options
  • Save ruvaleev/6122e967d96a6e92287a6cf44ece3b32 to your computer and use it in GitHub Desktop.
Save ruvaleev/6122e967d96a6e92287a6cf44ece3b32 to your computer and use it in GitHub Desktop.
WTF is going on?
export const PRICE_PRECISION = 18;
export const Q96 = BigNumber(Math.pow(2, 96));
export const Q128 = BigNumber(Math.pow(2, 128));
export const Q256 = BigNumber(Math.pow(2, 256));
export const ZERO = BigNumber(0);
import BigNumber from 'bignumber.js';
import { Q128, Q256, ZERO } from '__constants';
function subIn256(x, y) {
const difference = x.minus(y);
if (difference.lt(ZERO)) {
return Q256.plus(difference)
} else {
return difference;
}
}
function toBigNumber(num) {
return new BigNumber(num);
}
function getFees(
feeGrowthGlobal0, feeGrowthGlobal1, feeGrowth0Low, feeGrowth0Hi, feeGrowthInside0,
feeGrowth1Low, feeGrowth1Hi, feeGrowthInside1, liquidity, decimals0, decimals1, tickLower, tickUpper, tickCurrent
) {
let feeGrowthGlobal_0 = toBigNumber(feeGrowthGlobal0);
let feeGrowthGlobal_1 = toBigNumber(feeGrowthGlobal1);
let feeGrowthInsideLast_0 = toBigNumber(feeGrowthInside0);
let feeGrowthInsideLast_1 = toBigNumber(feeGrowthInside1);
let tickLowerFeeGrowthOutside_0 = toBigNumber(feeGrowth0Low);
let tickLowerFeeGrowthOutside_1 = toBigNumber(feeGrowth1Low);
let tickUpperFeeGrowthOutside_0 = toBigNumber(feeGrowth0Hi);
let tickUpperFeeGrowthOutside_1 = toBigNumber(feeGrowth1Hi);
let tickLowerFeeGrowthBelow_0 = ZERO;
let tickLowerFeeGrowthBelow_1 = ZERO;
let tickUpperFeeGrowthAbove_0 = ZERO;
let tickUpperFeeGrowthAbove_1 = ZERO;
if (tickCurrent >= tickUpper){
tickUpperFeeGrowthAbove_0 = subIn256(feeGrowthGlobal_0, tickUpperFeeGrowthOutside_0);
tickUpperFeeGrowthAbove_1 = subIn256(feeGrowthGlobal_1, tickUpperFeeGrowthOutside_1);
} else {
tickUpperFeeGrowthAbove_0 = tickUpperFeeGrowthOutside_0
tickUpperFeeGrowthAbove_1 = tickUpperFeeGrowthOutside_1
}
if (tickCurrent >= tickLower){
tickLowerFeeGrowthBelow_0 = tickLowerFeeGrowthOutside_0
tickLowerFeeGrowthBelow_1 = tickLowerFeeGrowthOutside_1
} else{
tickLowerFeeGrowthBelow_0 = subIn256(feeGrowthGlobal_0, tickLowerFeeGrowthOutside_0);
tickLowerFeeGrowthBelow_1 = subIn256(feeGrowthGlobal_1, tickLowerFeeGrowthOutside_1);
}
let fr_t1_0 = subIn256(subIn256(feeGrowthGlobal_0, tickLowerFeeGrowthBelow_0), tickUpperFeeGrowthAbove_0);
let fr_t1_1 = subIn256(subIn256(feeGrowthGlobal_1, tickLowerFeeGrowthBelow_1), tickUpperFeeGrowthAbove_1);
const resGrowthFees0 = subIn256(fr_t1_0, feeGrowthInsideLast_0)
const resGrowthFees1 = subIn256(fr_t1_1, feeGrowthInsideLast_1)
const uncollectedFees_0 = liquidity.multipliedBy(resGrowthFees0).dividedBy(Q128);
const uncollectedFees_1 = liquidity.multipliedBy(resGrowthFees1).dividedBy(Q128);
const precision0 = toBigNumber(10**decimals0);
const precision1 = toBigNumber(10**decimals1);
let uncollectedFeesAdjusted_0 = (uncollectedFees_0.dividedBy(precision0)).toFixed(decimals0);
let uncollectedFeesAdjusted_1 = (uncollectedFees_1.dividedBy(precision1)).toFixed(decimals1);
return {fees0: uncollectedFeesAdjusted_0, fees1: uncollectedFeesAdjusted_1}
}
export default getFees;
import BigNumber from 'bignumber.js';
import getFees from '__services/getFees';
describe('getFees', () => {
describe('when same decimals', () => {
const liquidity = BigNumber('7108218528222899361894')
const feeGrowthGlobal0X128 = BigNumber('208835107267699315514338644992581187')
const feeGrowthGlobal1X128 = BigNumber('313653298461314658420682448261369158520')
const tickUpper = 76050
const tickLower = 73430
const feeGrowthOutside0X128Upper = BigNumber('6870750798044025148227866664355024') // of the upper tick of position
const feeGrowthOutside1X128Upper = BigNumber('14013529065654888970332476500856001847') // of the upper tick of position
const feeGrowthOutside0X128Lower = BigNumber('129362448994648287540025458230935296') // of the lower tick of position
const feeGrowthOutside1X128Lower = BigNumber('175943338775698876993679593052051410691') // of the lower tick of position
const feeGrowthInside0LastX128 = BigNumber('69152337145849472040338377168383236')
const feeGrowthInside1LastX128 = BigNumber('117001692319817971649209116374655145049')
const tick = 75677
const decimals0 = 18
const decimals1 = 18
it('returns properly calculated fees', () => {
expect(
getFees(
feeGrowthGlobal0X128,
feeGrowthGlobal1X128,
feeGrowthOutside0X128Lower,
feeGrowthOutside0X128Upper,
feeGrowthInside0LastX128,
feeGrowthOutside1X128Lower,
feeGrowthOutside1X128Upper,
feeGrowthInside1LastX128,
liquidity,
decimals0,
decimals1,
tickLower,
tickUpper,
tick
)
).toEqual({fees0: '0.072058684527202062', fees1: '139.847572053993460216'})
});
})
describe('when different decimals', () => {
const liquidity = BigNumber('477550033551699')
const feeGrowthGlobal0X128 = BigNumber('38801535727909269532917328293691613330053')
const feeGrowthGlobal1X128 = BigNumber('66815283213268741772954215092612')
const tickUpper = -200310
const tickLower = -203190
const feeGrowthOutside0X128Upper = BigNumber('302262195143298415259619494746838407729') // of the upper tick of position
const feeGrowthOutside1X128Upper = BigNumber('612076910341715108280663452272') // of the upper tick of position
const feeGrowthOutside0X128Lower = BigNumber('1389446086837536329373633889581184202797') // of the lower tick of position
const feeGrowthOutside1X128Lower = BigNumber('2477092305229384387505363697019') // of the lower tick of position
const feeGrowthInside0LastX128 = BigNumber('33819274971982470552721340282569211455911')
const feeGrowthInside1LastX128 = BigNumber('58577573406703228483069725719999')
const tick = -202779
const decimals0 = 18
const decimals1 = 6
it('returns properly calculated fees', () => {
expect(
getFees(
feeGrowthGlobal0X128,
feeGrowthGlobal1X128,
feeGrowthOutside0X128Lower,
feeGrowthOutside0X128Upper,
feeGrowthInside0LastX128,
feeGrowthOutside1X128Lower,
feeGrowthOutside1X128Upper,
feeGrowthInside1LastX128,
liquidity,
decimals0,
decimals1,
tickLower,
tickUpper,
tick
)
).toEqual({fees0: '0.004617939679200664', fees1: '7.225428'})
});
})
describe('when current tick is out of range', () => {
const liquidity = BigNumber('16649031368038418')
const feeGrowthGlobal0X128 = BigNumber('41587826366351661761787568234919597257287')
const feeGrowthGlobal1X128 = BigNumber('71207135789803872127732583284281')
const tickUpper = -202740
const tickLower = -202950
const feeGrowthOutside0X128Upper = BigNumber('23623927678635026405525201674516592214499') // of the upper tick of position
const feeGrowthOutside1X128Upper = BigNumber('41889215130226370061098949950347') // of the upper tick of position
const feeGrowthOutside0X128Lower = BigNumber('28138940083802386376225608139418141010216') // of the lower tick of position
const feeGrowthOutside1X128Lower = BigNumber('49574638000242573396812064032056') // of the lower tick of position
const feeGrowthInside0LastX128 = BigNumber('115792089237316195423570985008687907848111843853796435050067843230047949334441')
const feeGrowthInside1LastX128 = BigNumber('115792089237316195423570985008687907853269984656885367027568119608456871195988')
const tick = -202710
const decimals0 = 18
const decimals1 = 6
it('returns properly calculated fees', () => {
expect(
getFees(
feeGrowthGlobal0X128,
feeGrowthGlobal1X128,
feeGrowthOutside0X128Lower,
feeGrowthOutside0X128Upper,
feeGrowthInside0LastX128,
feeGrowthOutside1X128Lower,
feeGrowthOutside1X128Upper,
feeGrowthInside1LastX128,
liquidity,
decimals0,
decimals1,
tickLower,
tickUpper,
tick
)
).toEqual({fees0: '0.02962279', fees1: '49.0998560'})
});
})
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment