mojito-testnet-sdk
Version:
🛠An SDK for building applications on top of mojitoswap in testnet.
77 lines (64 loc) • 3.05 kB
text/typescript
import { Token } from '../token'
import { TokenAmount } from './tokenAmount'
import { currencyEquals } from '../token'
import invariant from 'tiny-invariant'
import JSBI from 'jsbi'
import { BigintIsh, Rounding, TEN } from '../../constants'
import { Currency } from '../currency'
import { Route } from '../route'
import { Fraction } from './fraction'
import { CurrencyAmount } from './currencyAmount'
export class Price extends Fraction {
public readonly baseCurrency: Currency // input i.e. denominator
public readonly quoteCurrency: Currency // output i.e. numerator
public readonly scalar: Fraction // used to adjust the raw fraction w/r/t the decimals of the {base,quote}Token
public static fromRoute(route: Route): Price {
const prices: Price[] = []
for (const [i, pair] of route.pairs.entries()) {
prices.push(
route.path[i].equals(pair.token0)
? new Price(pair.reserve0.currency, pair.reserve1.currency, pair.reserve0.raw, pair.reserve1.raw)
: new Price(pair.reserve1.currency, pair.reserve0.currency, pair.reserve1.raw, pair.reserve0.raw)
)
}
return prices.slice(1).reduce((accumulator, currentValue) => accumulator.multiply(currentValue), prices[0])
}
// denominator and numerator _must_ be raw, i.e. in the native representation
public constructor(baseCurrency: Currency, quoteCurrency: Currency, denominator: BigintIsh, numerator: BigintIsh) {
super(numerator, denominator)
this.baseCurrency = baseCurrency
this.quoteCurrency = quoteCurrency
this.scalar = new Fraction(
JSBI.exponentiate(TEN, JSBI.BigInt(baseCurrency.decimals)),
JSBI.exponentiate(TEN, JSBI.BigInt(quoteCurrency.decimals))
)
}
public get raw(): Fraction {
return new Fraction(this.numerator, this.denominator)
}
public get adjusted(): Fraction {
return super.multiply(this.scalar)
}
public invert(): Price {
return new Price(this.quoteCurrency, this.baseCurrency, this.numerator, this.denominator)
}
public multiply(other: Price): Price {
invariant(currencyEquals(this.quoteCurrency, other.baseCurrency), 'TOKEN')
const fraction = super.multiply(other)
return new Price(this.baseCurrency, other.quoteCurrency, fraction.denominator, fraction.numerator)
}
// performs floor division on overflow
public quote(currencyAmount: CurrencyAmount): CurrencyAmount {
invariant(currencyEquals(currencyAmount.currency, this.baseCurrency), 'TOKEN')
if (this.quoteCurrency instanceof Token) {
return new TokenAmount(this.quoteCurrency, super.multiply(currencyAmount.raw).quotient)
}
return CurrencyAmount.ether(super.multiply(currencyAmount.raw).quotient)
}
public toSignificant(significantDigits: number = 6, format?: object, rounding?: Rounding): string {
return this.adjusted.toSignificant(significantDigits, format, rounding)
}
public toFixed(decimalPlaces: number = 4, format?: object, rounding?: Rounding): string {
return this.adjusted.toFixed(decimalPlaces, format, rounding)
}
}