UNPKG

@fleupold/dex-contracts

Version:

Contracts for dFusion multi-token batch auction exchange

87 lines (80 loc) 2.89 kB
import BN from "bn.js"; import assert from "assert"; import { Fraction } from "./fraction"; const MAX128 = new BN(2).pow(new BN(128)).subn(1); type SellAmount = BN; type BuyAmount = BN; /** * Modifies the price to work with ERC20 units * @param price - Amount of buy token in exchange for one sell token * @param sellTokenDecimals - Number of decimals of the sell token * @param buyTokenDecimals - Number of decimals of the buy token * Returns Fraction representing the number of buy tokens in exchange for one unit of sell token */ export function getUnitPrice( price: number, sellTokenDecimals: number, buyTokenDecimals: number, ): Fraction { assert(sellTokenDecimals >= 0, "sell token decimals must be non-negative"); assert(buyTokenDecimals >= 0, "buy token decimals must be non-negative"); return Fraction.fromNumber(price).mul( new Fraction( new BN(10).pow(new BN(buyTokenDecimals)), new BN(10).pow(new BN(sellTokenDecimals)), ), ); } /** * Computes the amount of output token units from their price and the amount of input token units * Note that the price is expressed in terms of tokens, while the amounts are in terms of token units * @param price - Amount of buy token in exchange for one sell token * @param sellAmount - Amount of sell token units that are exchanged at price * @param sellTokenDecimals - Number of decimals of the sell token * @param buyTokenDecimals - Number of decimals of the buy token * Returns amount of output token units obtained */ export function getBuyAmountFromPrice( price: number, sellAmount: SellAmount, sellTokenDecimals: number, buyTokenDecimals: number, ): BuyAmount { const unitPrice = getUnitPrice(price, sellTokenDecimals, buyTokenDecimals); const buyAmount = unitPrice.mul(new Fraction(sellAmount, 1)); return buyAmount.toBN(); } /** * Computes the buy and sell token amounts required for an unlimited order in the exchange * @param price - Price of the buyToken relative to one sell token * @param sellTokenDecimals - Number of decimals of the sell token * @param buyTokenDecimals - Number of decimals of the buy token * Returns amounts of sell-buy token for an unlimited order at the input price */ export function getUnlimitedOrderAmounts( price: number, sellTokenDecimals: number, buyTokenDecimals: number, ): { base: SellAmount; quote: BuyAmount } { let sellAmount = MAX128.clone(); let buyAmount = getBuyAmountFromPrice( price, sellAmount, sellTokenDecimals, buyTokenDecimals, ); if (buyAmount.gt(sellAmount)) { buyAmount = MAX128.clone(); sellAmount = getBuyAmountFromPrice( 1 / price, buyAmount, buyTokenDecimals, sellTokenDecimals, ); assert( buyAmount.gte(sellAmount), "Error: unable to create unlimited order", ); } return { base: sellAmount, quote: buyAmount }; }