Skip to content
This repository has been archived by the owner on Apr 25, 2024. It is now read-only.

Commit

Permalink
update the reserve as well as getAmountIn amountInAfterTax calculatio…
Browse files Browse the repository at this point in the history
…n order
  • Loading branch information
Siyu Jiang authored and Siyu Jiang committed Sep 8, 2023
1 parent a74bc2e commit 8e16074
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 30 deletions.
25 changes: 13 additions & 12 deletions src/entities/pair.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -217,19 +217,20 @@ describe('Pair', () => {
// However in practice, we have round down of precisions in multiple steps
// hence the amount out will be slightly less than 91.48:
//
// inputAmountWithFee = 100 * 997 = 99700
// inputAmount = 100
// percentAfterSellFeesInDecimal = fraction(9650, 10000)
// inputAmountWithFeeAndTax = fraction(9650, 10000) * 99700 = 96210.5 = 96210 (rounded down)
// numerator = 96210 * 10000 = 962100000
// denominator = 10000 * 1000 + 96210 = 10096210
// outputAmount = 962100000 / 10096210 = 95 (rounded down)
// inputAmountAfterTax = 100 * fraction(9650, 10000) = 96.5 = 96 (rounded down)
// inputAmountWithFeeAndAfterTax = 96 * 997 = 95712
// numerator = 95712 * 10000 = 957120000
// denominator = 10000 * 1000 + 95712 = 10095712
// outputAmount = 957120000 / 10095712 = 94.8046061536 = 94 (rounded down)
// buyFeePercentInDecimal = fraction(400, 10000)
// percentAfterBuyFeesInDecimal = fraction(9600, 10000)
// outputAmountWithTax = 95 * fraction(9600, 10000)
// = 95 * 0.96
// = 91.2
// = 91 (rounded down)
const expectedOutputBlastAmount = JSBI.BigInt(91)
// outputAmountAfterTax = 94 * fraction(9600, 10000)
// = 94 * 0.96
// = 90.24
// = 90 (rounded down)
const expectedOutputBlastAmount = JSBI.BigInt(90)
expect(outputBlastAmount.quotient).toEqual(expectedOutputBlastAmount)
})

Expand All @@ -251,7 +252,7 @@ describe('Pair', () => {
//
// buyFeePercentInDecimal = fraction(400, 10000)
// percentAfterBuyFeesInDecimal = 1 - fraction(400, 10000) = fraction(9600, 10000)
// outputAmountWithTax = 91 / fraction(960000, 10000) + 1
// outputAmountBeforeTax = 91 / fraction(960000, 10000) + 1
// = 91 / 0.96 + 1
// = 94.7916666667 + 1
// = 94 (rounded down) + 1
Expand All @@ -264,7 +265,7 @@ describe('Pair', () => {
// = 97 (rounded up)
// sellFeePercentInDecimal = fraction(350, 10000)
// percentAfterSellFeesInDecimal = 1 - fraction(350, 10000) = fraction(9650, 10000)
// inputAmountWithTax = (97 / fraction(9650, 10000)) + 1
// inputAmountBeforeTax = (97 / fraction(9650, 10000)) + 1
// = (97 / 0.965) + 1
// = 100.518134715 + 1
// = 100 (rounded down) + 1
Expand Down
34 changes: 16 additions & 18 deletions src/entities/pair.ts
Original file line number Diff line number Diff line change
Expand Up @@ -185,17 +185,15 @@ export class Pair {
}
const inputReserve = this.reserveOf(inputAmount.currency)
const outputReserve = this.reserveOf(inputAmount.currency.equals(this.token0) ? this.token1 : this.token0)
const inputAmountWithFee = JSBI.multiply(inputAmount.quotient, _997)

const percentAfterSellFeesInDecimal = this.derivePercentAfterSellFeesInDecimal(
CurrencyAmount.fromRawAmount(inputAmount.currency, inputAmountWithFee)
)
const inputAmountWithFeeAndTax = percentAfterSellFeesInDecimal.greaterThan(ZERO)
? percentAfterSellFeesInDecimal.multiply(inputAmountWithFee).quotient // fraction.quotient will round down by itself, which is desired
: inputAmountWithFee
const percentAfterSellFeesInDecimal = this.derivePercentAfterSellFeesInDecimal(inputAmount)
const inputAmountAfterTax = percentAfterSellFeesInDecimal.greaterThan(ZERO)
? CurrencyAmount.fromRawAmount(inputAmount.currency, percentAfterSellFeesInDecimal.multiply(inputAmount).quotient) // fraction.quotient will round down by itself, which is desired
: inputAmount

const numerator = JSBI.multiply(inputAmountWithFeeAndTax, outputReserve.quotient)
const denominator = JSBI.add(JSBI.multiply(inputReserve.quotient, _1000), inputAmountWithFeeAndTax)
const inputAmountWithFeeAndAfterTax = JSBI.multiply(inputAmountAfterTax.quotient, _997)
const numerator = JSBI.multiply(inputAmountWithFeeAndAfterTax, outputReserve.quotient)
const denominator = JSBI.add(JSBI.multiply(inputReserve.quotient, _1000), inputAmountWithFeeAndAfterTax)
const outputAmount = CurrencyAmount.fromRawAmount(
inputAmount.currency.equals(this.token0) ? this.token1 : this.token0,
JSBI.divide(numerator, denominator) // JSBI.divide will round down by itself, which is desired
Expand All @@ -206,17 +204,17 @@ export class Pair {
}

const percentAfterBuyFeesInDecimal = this.derivePercentAfterBuyFeesInDecimal(outputAmount)
const outputAmountWithTax = percentAfterBuyFeesInDecimal.greaterThan(ZERO)
const outputAmountAfterTax = percentAfterBuyFeesInDecimal.greaterThan(ZERO)
? CurrencyAmount.fromRawAmount(
outputAmount.currency,
outputAmount.multiply(percentAfterBuyFeesInDecimal).quotient // fraction.quotient will round down by itself, which is desired
)
: outputAmount
if (JSBI.equal(outputAmountWithTax.quotient, ZERO)) {
if (JSBI.equal(outputAmountAfterTax.quotient, ZERO)) {
throw new InsufficientInputAmountError()
}

return [outputAmountWithTax, new Pair(inputReserve.add(inputAmount), outputReserve.subtract(outputAmount))]
return [outputAmountAfterTax, new Pair(inputReserve.add(inputAmountAfterTax), outputReserve.subtract(outputAmountAfterTax))]
}

/**
Expand Down Expand Up @@ -264,7 +262,7 @@ export class Pair {
public getInputAmount(outputAmount: CurrencyAmount<Token>): [CurrencyAmount<Token>, Pair] {
invariant(this.involvesToken(outputAmount.currency), 'TOKEN')
const percentAfterBuyFeesInDecimal = this.derivePercentAfterBuyFeesInDecimal(outputAmount)
const outputAmountWithTax = percentAfterBuyFeesInDecimal.greaterThan(ZERO)
const outputAmountBeforeTax = percentAfterBuyFeesInDecimal.greaterThan(ZERO)
? CurrencyAmount.fromRawAmount(
outputAmount.currency,
JSBI.add(outputAmount.divide(percentAfterBuyFeesInDecimal).quotient, ONE) // add 1 for rounding up
Expand All @@ -275,29 +273,29 @@ export class Pair {
JSBI.equal(this.reserve0.quotient, ZERO) ||
JSBI.equal(this.reserve1.quotient, ZERO) ||
JSBI.greaterThanOrEqual(outputAmount.quotient, this.reserveOf(outputAmount.currency).quotient) ||
JSBI.greaterThanOrEqual(outputAmountWithTax.quotient, this.reserveOf(outputAmount.currency).quotient)
JSBI.greaterThanOrEqual(outputAmountBeforeTax.quotient, this.reserveOf(outputAmount.currency).quotient)
) {
throw new InsufficientReservesError()
}

const outputReserve = this.reserveOf(outputAmount.currency)
const inputReserve = this.reserveOf(outputAmount.currency.equals(this.token0) ? this.token1 : this.token0)

const numerator = JSBI.multiply(JSBI.multiply(inputReserve.quotient, outputAmountWithTax.quotient), _1000)
const denominator = JSBI.multiply(JSBI.subtract(outputReserve.quotient, outputAmountWithTax.quotient), _997)
const numerator = JSBI.multiply(JSBI.multiply(inputReserve.quotient, outputAmountBeforeTax.quotient), _1000)
const denominator = JSBI.multiply(JSBI.subtract(outputReserve.quotient, outputAmountBeforeTax.quotient), _997)
const inputAmount = CurrencyAmount.fromRawAmount(
outputAmount.currency.equals(this.token0) ? this.token1 : this.token0,
JSBI.add(JSBI.divide(numerator, denominator), ONE) // add 1 here is part of the formula, no rounding needed here, since there will not be decimal at this point
)

const percentAfterSellFeesInDecimal = this.derivePercentAfterSellFeesInDecimal(inputAmount)
const inputAmountWithTax = percentAfterSellFeesInDecimal.greaterThan(ZERO)
const inputAmountBeforeTax = percentAfterSellFeesInDecimal.greaterThan(ZERO)
? CurrencyAmount.fromRawAmount(
inputAmount.currency,
JSBI.add(inputAmount.divide(percentAfterSellFeesInDecimal).quotient, ONE) // add 1 for rounding up
)
: inputAmount
return [inputAmountWithTax, new Pair(inputReserve.add(inputAmount), outputReserve.subtract(outputAmount))]
return [inputAmountBeforeTax, new Pair(inputReserve.add(inputAmount), outputReserve.subtract(outputAmount))]
}

public getLiquidityMinted(
Expand Down

0 comments on commit 8e16074

Please sign in to comment.