@0xfps/pmamm-js 0.0.5 → 0.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -36,8 +36,8 @@ module.exports = __toCommonJS(index_exports);
36
36
 
37
37
  // src/constants.ts
38
38
  var STARTING_PRICE = 0.5;
39
- var PRICE_DECIMALS = 6;
40
- var LIQUIDITY_FACTOR = 100;
39
+ var PRICE_DECIMALS = 18;
40
+ var LIQUIDITY_FACTOR = 1e4;
41
41
  var TIME_FACTOR = 1e3;
42
42
 
43
43
  // src/amm-math/get-effective-liquidity.ts
@@ -134,7 +134,7 @@ function getReservesFromPrice(price, marketTime) {
134
134
  return { x, y };
135
135
  }
136
136
 
137
- // src/amm-math/get-new-reserves-after-x-trade.ts
137
+ // src/amm-math/get-new-reserves-after-y-trade.ts
138
138
  var import_bisect = __toESM(require("bisect"));
139
139
  function getNewReservesDataAfterYTrade(order) {
140
140
  const { shares, isBuy, price, marketTime } = order;
@@ -173,7 +173,7 @@ function getNewReservesDataAfterYTrade(order) {
173
173
  return afterTrade;
174
174
  }
175
175
 
176
- // src/amm-math/get-new-reserves-after-y-trade.ts
176
+ // src/amm-math/get-new-reserves-after-x-trade.ts
177
177
  var import_bisect2 = __toESM(require("bisect"));
178
178
  function getNewReservesDataAfterXTrade(order) {
179
179
  const { shares, isBuy, price, marketTime } = order;
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/constants.ts","../src/amm-math/get-effective-liquidity.ts","../src/amm-math/gaussian.ts","../src/amm-math/get-price-from-reserves.ts","../src/utils/get-new-price-data.ts","../src/amm-math/invariant.ts","../src/amm-math/get-min-and-max-xy-reserves.ts","../src/amm-math/get-reserves-from-price.ts","../src/amm-math/get-new-reserves-after-x-trade.ts","../src/amm-math/get-new-reserves-after-y-trade.ts"],"sourcesContent":["import { getEffectiveLiquidity } from \"./amm-math/get-effective-liquidity\";\nimport { getNewReservesDataAfterYTrade } from \"./amm-math/get-new-reserves-after-x-trade\";\nimport { getNewReservesDataAfterXTrade } from \"./amm-math/get-new-reserves-after-y-trade\";\nimport { getPriceFromReseves } from \"./amm-math/get-price-from-reserves\";\nimport { getReservesFromPrice } from \"./amm-math/get-reserves-from-price\";\nimport { AfterTrade } from \"./types/after-trade\";\nimport { Limits } from \"./types/limits\";\nimport { MarketTime } from \"./types/market-time\";\nimport { Order } from \"./types/order\";\nimport { Reserves } from \"./types/ reserves\";\nimport { LIQUIDITY_FACTOR, PRICE_DECIMALS, STARTING_PRICE, TIME_FACTOR } from \"./constants\";\nimport { Phi, phi, Phi_inverse } from \"./amm-math/gaussian\";\n\nexport {\n AfterTrade,\n Limits,\n MarketTime,\n Order,\n Reserves\n}\n\nconst pmAmm = {\n LIQUIDITY_FACTOR,\n PRICE_DECIMALS,\n STARTING_PRICE,\n TIME_FACTOR,\n phi,\n Phi,\n Phi_inverse,\n getEffectiveLiquidity,\n getNewReservesDataAfterYTrade,\n getNewReservesDataAfterXTrade,\n getPriceFromReseves,\n getReservesFromPrice,\n}\n\nexport default pmAmm","// Staring price of both sides of the market.\nexport const STARTING_PRICE = 0.5\n// This, while not needed for this package, because JS operates\n// with floating point numbers, is needed to establish the point\n// of the current price of either sides of the market as having\n// 6 decimals on the contract interface.\nexport const PRICE_DECIMALS = 6\n// This is tentative, anyone can use any liquidity factor. This,\n// just like `PRICE_DECIMALS` establish the fact that we're using\n// a 100 point liquidity factor on the contract interface.\nexport const LIQUIDITY_FACTOR = 100\n// JS deals with time in milliseconds, when recreating with Solidity,\n// multiply LF with 1,000 too even though time will not need milliseconds.\n// Concurrency.\n// Solidity computes regarding times will be operated on the normal seconds level.\nexport const TIME_FACTOR = 1000","import { LIQUIDITY_FACTOR } from \"../constants\";\nimport { MarketTime } from \"../types/market-time\";\n\n// Returns effective liquidity from liquidity factor.\n//\n// Leff = L(√(T - t))\n// Where T = End time, market closing time and t = current time.\n// To keep in line with Solidity, remove decimal part and keep whole number.\nexport function getEffectiveLiquidity({ currentTime, endTime }: MarketTime): number {\n return LIQUIDITY_FACTOR * getWholeNumberFromDecimal(Math.sqrt(endTime - currentTime))\n}\n\nfunction getWholeNumberFromDecimal(decimal: number): number {\n return parseInt(decimal.toString().split(\".\")[0])\n}","import gaussian from \"gaussian\"\n\nconst distribution = gaussian(0, 1)\n\n// CDF, Cumulative Distribution Function.\nexport function Phi(x: number): number {\n return distribution.cdf(x)\n}\n\n// PDF, Probability Density Function.\nexport function phi(x: number): number {\n return distribution.pdf(x)\n}\n\n// PPF or 1/CDF.\nexport function Phi_inverse(x: number): number {\n return distribution.ppf(x)\n}","import { Reserves } from \"../types/ reserves\"\nimport { MarketTime } from \"../types/market-time\"\nimport { Phi } from \"./gaussian\"\nimport { getEffectiveLiquidity } from \"./get-effective-liquidity\"\n\nexport function getPriceFromReseves({ x, y }: Reserves, marketTime: MarketTime): number {\n const effectiveL = getEffectiveLiquidity(marketTime)\n\n const z = (y - x) / effectiveL\n const price = Phi(z)\n\n return price\n}","import { getPriceFromReseves } from \"../amm-math/get-price-from-reserves\";\nimport { PRICE_DECIMALS } from \"../constants\";\nimport { Reserves } from \"../types/ reserves\";\nimport { AfterTrade } from \"../types/after-trade\";\nimport { MarketTime } from \"../types/market-time\";\n\nexport function getNewPriceCostAverageCost(\n newReserves: Reserves,\n marketTime: MarketTime,\n oldPrice: number,\n shares: number\n): Omit<AfterTrade, \"oldXReserve\" | \"oldYReserve\" | \"oldPrice\" | \"newXReserve\" | \"newYReserve\"> {\n const newPrice = getPriceFromReseves(newReserves, marketTime)\n const cost = parseFloat((((oldPrice + newPrice) / 2) * shares).toFixed(PRICE_DECIMALS))\n const averageCost = parseFloat((cost / shares).toFixed(PRICE_DECIMALS))\n\n const afterTrade = {\n newPrice,\n cost,\n averageCost\n }\n\n return afterTrade\n}","import { phi, Phi } from \"./gaussian\";\n\n// For a given x, y and Leff, this invariant must be equal or infinitesimally\n// close to 0.\n// Refer to https://www.paradigm.xyz/2024/11/pm-amm#90ef7fa55727.\nexport function invariant(x: number, y: number, Leff: number): number {\n const z = (y - x) / Leff\n\n return ((y - x) * Phi(z)) + (Leff * phi(z)) - y\n}","import { Limits } from \"../types/limits\"\nimport { MarketTime } from \"../types/market-time\"\nimport { getEffectiveLiquidity } from \"./get-effective-liquidity\"\nimport { invariant } from \"./invariant\"\n\n// Each of these two functions solve to determine the range of values\n// for y and x (yLimit and xLimit) respectively that needs to be approached\n// so that the function given at `invariant` will be equal or close to 0.\n// The whole point of these functions is that it narrows down two limits\n// `min` and `max` for both x and y. `min` is always lesser than `max`, by\n// inference, and applying `min` in the invariant yields a positive number \n// close to 0, say +0.04. `max` when applied to the invariant yields a \n// negative number close to 0, say -0.02. By establishing and using these\n// limits, it's easier for the Bisection function to find a middle ground\n// to pick which number between `min` an `max` yields the closest to 0 (on the\n// negative). That is the number we're looking for.\n//\n// As the limits of either go down, the inviariant positively expands, and it\n// negatively expands as the limits go up.\nexport function getMinAndMaxYReservesForNewXReserve(\n currentYReserve: number,\n newXReserve: number,\n marketTime: MarketTime\n): Limits {\n let minYReserve, maxYReserve\n let minYEvaluation = false, maxYEvaluation = false\n let margin = 5000\n const leff = getEffectiveLiquidity(marketTime)\n\n // Finding the upper limits.\n // We keep adding 10,000 until the invariant\n // results in below 0.\n while (!maxYEvaluation) {\n maxYEvaluation = invariant(newXReserve, currentYReserve, leff) < 0\n currentYReserve += margin\n }\n\n maxYReserve = currentYReserve\n\n // Finding the lower limits.\n // We keep adding 10,000 until the invariant\n // results in above 0.\n while (!minYEvaluation) {\n currentYReserve -= margin\n minYEvaluation = invariant(newXReserve, currentYReserve, leff) > 0\n }\n\n minYReserve = currentYReserve\n\n return { min: minYReserve, max: maxYReserve }\n}\n\nexport function getMinAndMaxXReservesForNewYReserve(\n currentXReserve: number,\n newYReserve: number,\n marketTime: MarketTime\n): Limits {\n let minXReserve, maxXReserve\n let minXEvaluation = false, maxXEvaluation = false\n let margin = 5000\n const leff = getEffectiveLiquidity(marketTime)\n\n // Finding the upper limits.\n // We keep adding 10,000 until the invariant\n // results in below 0.\n while (!maxXEvaluation) {\n maxXEvaluation = invariant(currentXReserve, newYReserve, leff) < 0\n currentXReserve += margin\n }\n\n maxXReserve = currentXReserve\n\n // Finding the lower limits.\n // We keep adding 10,000 until the invariant\n // results in above 0.\n while (!minXEvaluation) {\n currentXReserve -= margin\n minXEvaluation = invariant(currentXReserve, newYReserve, leff) > 0\n }\n\n minXReserve = currentXReserve\n\n return { min: minXReserve, max: maxXReserve }\n}","import { Reserves } from \"../types/ reserves\"\nimport { MarketTime } from \"../types/market-time\"\nimport { phi, Phi_inverse } from \"./gaussian\"\nimport { getEffectiveLiquidity } from \"./get-effective-liquidity\"\n\nexport function getReservesFromPrice(price: number, marketTime: MarketTime): Reserves {\n const effectiveL = getEffectiveLiquidity(marketTime)\n const z = Phi_inverse(price)\n const diff = (z) * effectiveL\n\n const y = (diff * price) + (effectiveL * phi(z))\n const x = y - diff\n\n return { x, y }\n}","import { AfterTrade } from \"../types/after-trade\"\nimport { Order } from \"../types/order\"\nimport { getNewPriceCostAverageCost } from \"../utils/get-new-price-data\"\nimport { getEffectiveLiquidity } from \"./get-effective-liquidity\"\nimport { getMinAndMaxXReservesForNewYReserve } from \"./get-min-and-max-xy-reserves\"\nimport { getReservesFromPrice } from \"./get-reserves-from-price\"\nimport { invariant } from \"./invariant\"\nimport bisect from \"bisect\"\n\nexport function getNewReservesDataAfterYTrade(order: Order): AfterTrade {\n const { shares, isBuy, price, marketTime } = order\n const { x: xReserve, y: yReserve } = getReservesFromPrice(price, marketTime)\n\n if (isBuy && shares >= yReserve) throw new Error(\"Insufficient Y Liquidity.\")\n\n const leff = getEffectiveLiquidity(marketTime)\n const newYReserve = isBuy ? yReserve - shares : yReserve + shares\n\n function evaluateX(x: number) {\n return invariant(x, newYReserve, leff) < 0\n }\n\n const currentXReserve = xReserve\n const { min, max } = getMinAndMaxXReservesForNewYReserve(\n currentXReserve,\n newYReserve,\n marketTime\n )\n const newXReserve = bisect(evaluateX, min, max)\n\n if (!isBuy && newXReserve <= 0) throw new Error(\"X Liquidity Depleted.\")\n\n const newReserves = { x: newXReserve, y: newYReserve }\n const { newPrice, cost, averageCost } = getNewPriceCostAverageCost(\n newReserves,\n marketTime,\n price,\n shares\n )\n\n const afterTrade = {\n oldXReserve: xReserve,\n oldYReserve: yReserve,\n oldPrice: price,\n newXReserve,\n newYReserve,\n newPrice,\n cost,\n averageCost\n }\n\n return afterTrade\n}","import { AfterTrade } from \"../types/after-trade\"\nimport { Order } from \"../types/order\"\nimport { getNewPriceCostAverageCost } from \"../utils/get-new-price-data\"\nimport { getEffectiveLiquidity } from \"./get-effective-liquidity\"\nimport { getMinAndMaxYReservesForNewXReserve } from \"./get-min-and-max-xy-reserves\"\nimport { getReservesFromPrice } from \"./get-reserves-from-price\"\nimport { invariant } from \"./invariant\"\nimport bisect from \"bisect\"\n\nexport function getNewReservesDataAfterXTrade(order: Order): AfterTrade {\n const { shares, isBuy, price, marketTime } = order\n const { x: xReserve, y: yReserve } = getReservesFromPrice(price, marketTime)\n\n if (isBuy && shares >= xReserve) throw new Error(\"Insufficient X Liquidity.\")\n\n const leff = getEffectiveLiquidity(marketTime)\n const newXReserve = isBuy ? xReserve - shares : xReserve + shares\n\n function evaluateY(y: number) {\n return invariant(newXReserve, y, leff) < 0\n }\n\n const currentYReserve = yReserve\n const { min, max } = getMinAndMaxYReservesForNewXReserve(\n currentYReserve,\n newXReserve,\n marketTime\n )\n const newYReserve = bisect(evaluateY, min, max)\n\n if (!isBuy && newYReserve <= 0) throw new Error(\"Y Liquidity Depleted.\")\n\n const newReserves = { x: newXReserve, y: newYReserve }\n const { newPrice, cost, averageCost } = getNewPriceCostAverageCost(\n newReserves,\n marketTime,\n price,\n shares\n )\n\n const afterTrade = {\n oldXReserve: xReserve,\n oldYReserve: yReserve,\n oldPrice: price,\n newXReserve,\n newYReserve,\n newPrice,\n cost,\n averageCost\n }\n\n return afterTrade\n}"],"mappings":"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","names":["gaussian","bisect","import_bisect","bisect"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/constants.ts","../src/amm-math/get-effective-liquidity.ts","../src/amm-math/gaussian.ts","../src/amm-math/get-price-from-reserves.ts","../src/utils/get-new-price-data.ts","../src/amm-math/invariant.ts","../src/amm-math/get-min-and-max-xy-reserves.ts","../src/amm-math/get-reserves-from-price.ts","../src/amm-math/get-new-reserves-after-y-trade.ts","../src/amm-math/get-new-reserves-after-x-trade.ts"],"sourcesContent":["import { getEffectiveLiquidity } from \"./amm-math/get-effective-liquidity\";\nimport { getNewReservesDataAfterYTrade } from \"./amm-math/get-new-reserves-after-y-trade\";\nimport { getNewReservesDataAfterXTrade } from \"./amm-math/get-new-reserves-after-x-trade\";\nimport { getPriceFromReseves } from \"./amm-math/get-price-from-reserves\";\nimport { getReservesFromPrice } from \"./amm-math/get-reserves-from-price\";\nimport { AfterTrade } from \"./types/after-trade\";\nimport { Limits } from \"./types/limits\";\nimport { MarketTime } from \"./types/market-time\";\nimport { Order } from \"./types/order\";\nimport { Reserves } from \"./types/ reserves\";\nimport { LIQUIDITY_FACTOR, PRICE_DECIMALS, STARTING_PRICE, TIME_FACTOR } from \"./constants\";\nimport { Phi, phi, Phi_inverse } from \"./amm-math/gaussian\";\n\nexport {\n AfterTrade,\n Limits,\n MarketTime,\n Order,\n Reserves\n}\n\nconst pmAmm = {\n LIQUIDITY_FACTOR,\n PRICE_DECIMALS,\n STARTING_PRICE,\n TIME_FACTOR,\n phi,\n Phi,\n Phi_inverse,\n getEffectiveLiquidity,\n getNewReservesDataAfterYTrade,\n getNewReservesDataAfterXTrade,\n getPriceFromReseves,\n getReservesFromPrice,\n}\n\nexport default pmAmm","// Staring price of both sides of the market.\nexport const STARTING_PRICE = 0.5\n// This, while not needed for this package, because JS operates\n// with floating point numbers, is needed to establish the point\n// of the current price of either sides of the market as having\n// 18 decimals on the contract interface.\nexport const PRICE_DECIMALS = 18\n// This is tentative, anyone can use any liquidity factor. This,\n// just like `PRICE_DECIMALS` establish the fact that we're using\n// a 10000 point liquidity factor on the contract interface.\nexport const LIQUIDITY_FACTOR = 10000\n// JS deals with time in milliseconds, when recreating with Solidity,\n// multiply LF with 1,000 too even though time will not need milliseconds.\n// Concurrency.\n// Solidity computes regarding times will be operated on the normal seconds level.\nexport const TIME_FACTOR = 1000","import { LIQUIDITY_FACTOR } from \"../constants\";\nimport { MarketTime } from \"../types/market-time\";\n\n// Returns effective liquidity from liquidity factor.\n//\n// Leff = L(√(T - t))\n// Where T = End time, market closing time and t = current time.\n// To keep in line with Solidity, remove decimal part and keep whole number.\nexport function getEffectiveLiquidity({ currentTime, endTime }: MarketTime): number {\n return LIQUIDITY_FACTOR * getWholeNumberFromDecimal(Math.sqrt(endTime - currentTime))\n}\n\nfunction getWholeNumberFromDecimal(decimal: number): number {\n return parseInt(decimal.toString().split(\".\")[0])\n}","import gaussian from \"gaussian\"\n\nconst distribution = gaussian(0, 1)\n\n// CDF, Cumulative Distribution Function.\nexport function Phi(x: number): number {\n return distribution.cdf(x)\n}\n\n// PDF, Probability Density Function.\nexport function phi(x: number): number {\n return distribution.pdf(x)\n}\n\n// PPF or 1/CDF.\nexport function Phi_inverse(x: number): number {\n return distribution.ppf(x)\n}","import { Reserves } from \"../types/ reserves\"\nimport { MarketTime } from \"../types/market-time\"\nimport { Phi } from \"./gaussian\"\nimport { getEffectiveLiquidity } from \"./get-effective-liquidity\"\n\nexport function getPriceFromReseves({ x, y }: Reserves, marketTime: MarketTime): number {\n const effectiveL = getEffectiveLiquidity(marketTime)\n\n const z = (y - x) / effectiveL\n const price = Phi(z)\n\n return price\n}","import { getPriceFromReseves } from \"../amm-math/get-price-from-reserves\";\nimport { PRICE_DECIMALS } from \"../constants\";\nimport { Reserves } from \"../types/ reserves\";\nimport { AfterTrade } from \"../types/after-trade\";\nimport { MarketTime } from \"../types/market-time\";\n\nexport function getNewPriceCostAverageCost(\n newReserves: Reserves,\n marketTime: MarketTime,\n oldPrice: number,\n shares: number\n): Omit<AfterTrade, \"oldXReserve\" | \"oldYReserve\" | \"oldPrice\" | \"newXReserve\" | \"newYReserve\"> {\n const newPrice = getPriceFromReseves(newReserves, marketTime)\n const cost = parseFloat((((oldPrice + newPrice) / 2) * shares).toFixed(PRICE_DECIMALS))\n const averageCost = parseFloat((cost / shares).toFixed(PRICE_DECIMALS))\n\n const afterTrade = {\n newPrice,\n cost,\n averageCost\n }\n\n return afterTrade\n}","import { phi, Phi } from \"./gaussian\";\n\n// For a given x, y and Leff, this invariant must be equal or infinitesimally\n// close to 0.\n// Refer to https://www.paradigm.xyz/2024/11/pm-amm#90ef7fa55727.\nexport function invariant(x: number, y: number, Leff: number): number {\n const z = (y - x) / Leff\n\n return ((y - x) * Phi(z)) + (Leff * phi(z)) - y\n}","import { Limits } from \"../types/limits\"\nimport { MarketTime } from \"../types/market-time\"\nimport { getEffectiveLiquidity } from \"./get-effective-liquidity\"\nimport { invariant } from \"./invariant\"\n\n// Each of these two functions solve to determine the range of values\n// for y and x (yLimit and xLimit) respectively that needs to be approached\n// so that the function given at `invariant` will be equal or close to 0.\n// The whole point of these functions is that it narrows down two limits\n// `min` and `max` for both x and y. `min` is always lesser than `max`, by\n// inference, and applying `min` in the invariant yields a positive number \n// close to 0, say +0.04. `max` when applied to the invariant yields a \n// negative number close to 0, say -0.02. By establishing and using these\n// limits, it's easier for the Bisection function to find a middle ground\n// to pick which number between `min` an `max` yields the closest to 0 (on the\n// negative). That is the number we're looking for.\n//\n// As the limits of either go down, the inviariant positively expands, and it\n// negatively expands as the limits go up.\nexport function getMinAndMaxYReservesForNewXReserve(\n currentYReserve: number,\n newXReserve: number,\n marketTime: MarketTime\n): Limits {\n let minYReserve, maxYReserve\n let minYEvaluation = false, maxYEvaluation = false\n let margin = 5000\n const leff = getEffectiveLiquidity(marketTime)\n\n // Finding the upper limits.\n // We keep adding 10,000 until the invariant\n // results in below 0.\n while (!maxYEvaluation) {\n maxYEvaluation = invariant(newXReserve, currentYReserve, leff) < 0\n currentYReserve += margin\n }\n\n maxYReserve = currentYReserve\n\n // Finding the lower limits.\n // We keep adding 10,000 until the invariant\n // results in above 0.\n while (!minYEvaluation) {\n currentYReserve -= margin\n minYEvaluation = invariant(newXReserve, currentYReserve, leff) > 0\n }\n\n minYReserve = currentYReserve\n\n return { min: minYReserve, max: maxYReserve }\n}\n\nexport function getMinAndMaxXReservesForNewYReserve(\n currentXReserve: number,\n newYReserve: number,\n marketTime: MarketTime\n): Limits {\n let minXReserve, maxXReserve\n let minXEvaluation = false, maxXEvaluation = false\n let margin = 5000\n const leff = getEffectiveLiquidity(marketTime)\n\n // Finding the upper limits.\n // We keep adding 10,000 until the invariant\n // results in below 0.\n while (!maxXEvaluation) {\n maxXEvaluation = invariant(currentXReserve, newYReserve, leff) < 0\n currentXReserve += margin\n }\n\n maxXReserve = currentXReserve\n\n // Finding the lower limits.\n // We keep adding 10,000 until the invariant\n // results in above 0.\n while (!minXEvaluation) {\n currentXReserve -= margin\n minXEvaluation = invariant(currentXReserve, newYReserve, leff) > 0\n }\n\n minXReserve = currentXReserve\n\n return { min: minXReserve, max: maxXReserve }\n}","import { Reserves } from \"../types/ reserves\"\nimport { MarketTime } from \"../types/market-time\"\nimport { phi, Phi_inverse } from \"./gaussian\"\nimport { getEffectiveLiquidity } from \"./get-effective-liquidity\"\n\nexport function getReservesFromPrice(price: number, marketTime: MarketTime): Reserves {\n const effectiveL = getEffectiveLiquidity(marketTime)\n const z = Phi_inverse(price)\n const diff = (z) * effectiveL\n\n const y = (diff * price) + (effectiveL * phi(z))\n const x = y - diff\n\n return { x, y }\n}","import { AfterTrade } from \"../types/after-trade\"\nimport { Order } from \"../types/order\"\nimport { getNewPriceCostAverageCost } from \"../utils/get-new-price-data\"\nimport { getEffectiveLiquidity } from \"./get-effective-liquidity\"\nimport { getMinAndMaxXReservesForNewYReserve } from \"./get-min-and-max-xy-reserves\"\nimport { getReservesFromPrice } from \"./get-reserves-from-price\"\nimport { invariant } from \"./invariant\"\nimport bisect from \"bisect\"\n\nexport function getNewReservesDataAfterYTrade(order: Order): AfterTrade {\n const { shares, isBuy, price, marketTime } = order\n const { x: xReserve, y: yReserve } = getReservesFromPrice(price, marketTime)\n\n if (isBuy && shares >= yReserve) throw new Error(\"Insufficient Y Liquidity.\")\n\n const leff = getEffectiveLiquidity(marketTime)\n const newYReserve = isBuy ? yReserve - shares : yReserve + shares\n\n function evaluateX(x: number) {\n return invariant(x, newYReserve, leff) < 0\n }\n\n const currentXReserve = xReserve\n const { min, max } = getMinAndMaxXReservesForNewYReserve(\n currentXReserve,\n newYReserve,\n marketTime\n )\n const newXReserve = bisect(evaluateX, min, max)\n\n if (!isBuy && newXReserve <= 0) throw new Error(\"X Liquidity Depleted.\")\n\n const newReserves = { x: newXReserve, y: newYReserve }\n const { newPrice, cost, averageCost } = getNewPriceCostAverageCost(\n newReserves,\n marketTime,\n price,\n shares\n )\n\n const afterTrade = {\n oldXReserve: xReserve,\n oldYReserve: yReserve,\n oldPrice: price,\n newXReserve,\n newYReserve,\n newPrice,\n cost,\n averageCost\n }\n\n return afterTrade\n}","import { AfterTrade } from \"../types/after-trade\"\nimport { Order } from \"../types/order\"\nimport { getNewPriceCostAverageCost } from \"../utils/get-new-price-data\"\nimport { getEffectiveLiquidity } from \"./get-effective-liquidity\"\nimport { getMinAndMaxYReservesForNewXReserve } from \"./get-min-and-max-xy-reserves\"\nimport { getReservesFromPrice } from \"./get-reserves-from-price\"\nimport { invariant } from \"./invariant\"\nimport bisect from \"bisect\"\n\nexport function getNewReservesDataAfterXTrade(order: Order): AfterTrade {\n const { shares, isBuy, price, marketTime } = order\n const { x: xReserve, y: yReserve } = getReservesFromPrice(price, marketTime)\n\n if (isBuy && shares >= xReserve) throw new Error(\"Insufficient X Liquidity.\")\n\n const leff = getEffectiveLiquidity(marketTime)\n const newXReserve = isBuy ? xReserve - shares : xReserve + shares\n\n function evaluateY(y: number) {\n return invariant(newXReserve, y, leff) < 0\n }\n\n const currentYReserve = yReserve\n const { min, max } = getMinAndMaxYReservesForNewXReserve(\n currentYReserve,\n newXReserve,\n marketTime\n )\n const newYReserve = bisect(evaluateY, min, max)\n\n if (!isBuy && newYReserve <= 0) throw new Error(\"Y Liquidity Depleted.\")\n\n const newReserves = { x: newXReserve, y: newYReserve }\n const { newPrice, cost, averageCost } = getNewPriceCostAverageCost(\n newReserves,\n marketTime,\n price,\n shares\n )\n\n const afterTrade = {\n oldXReserve: xReserve,\n oldYReserve: yReserve,\n oldPrice: price,\n newXReserve,\n newYReserve,\n newPrice,\n cost,\n averageCost\n }\n\n return afterTrade\n}"],"mappings":"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","names":["gaussian","bisect","import_bisect","bisect"]}
package/dist/index.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  // src/constants.ts
2
2
  var STARTING_PRICE = 0.5;
3
- var PRICE_DECIMALS = 6;
4
- var LIQUIDITY_FACTOR = 100;
3
+ var PRICE_DECIMALS = 18;
4
+ var LIQUIDITY_FACTOR = 1e4;
5
5
  var TIME_FACTOR = 1e3;
6
6
 
7
7
  // src/amm-math/get-effective-liquidity.ts
@@ -98,7 +98,7 @@ function getReservesFromPrice(price, marketTime) {
98
98
  return { x, y };
99
99
  }
100
100
 
101
- // src/amm-math/get-new-reserves-after-x-trade.ts
101
+ // src/amm-math/get-new-reserves-after-y-trade.ts
102
102
  import bisect from "bisect";
103
103
  function getNewReservesDataAfterYTrade(order) {
104
104
  const { shares, isBuy, price, marketTime } = order;
@@ -137,7 +137,7 @@ function getNewReservesDataAfterYTrade(order) {
137
137
  return afterTrade;
138
138
  }
139
139
 
140
- // src/amm-math/get-new-reserves-after-y-trade.ts
140
+ // src/amm-math/get-new-reserves-after-x-trade.ts
141
141
  import bisect2 from "bisect";
142
142
  function getNewReservesDataAfterXTrade(order) {
143
143
  const { shares, isBuy, price, marketTime } = order;
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/constants.ts","../src/amm-math/get-effective-liquidity.ts","../src/amm-math/gaussian.ts","../src/amm-math/get-price-from-reserves.ts","../src/utils/get-new-price-data.ts","../src/amm-math/invariant.ts","../src/amm-math/get-min-and-max-xy-reserves.ts","../src/amm-math/get-reserves-from-price.ts","../src/amm-math/get-new-reserves-after-x-trade.ts","../src/amm-math/get-new-reserves-after-y-trade.ts","../src/index.ts"],"sourcesContent":["// Staring price of both sides of the market.\nexport const STARTING_PRICE = 0.5\n// This, while not needed for this package, because JS operates\n// with floating point numbers, is needed to establish the point\n// of the current price of either sides of the market as having\n// 6 decimals on the contract interface.\nexport const PRICE_DECIMALS = 6\n// This is tentative, anyone can use any liquidity factor. This,\n// just like `PRICE_DECIMALS` establish the fact that we're using\n// a 100 point liquidity factor on the contract interface.\nexport const LIQUIDITY_FACTOR = 100\n// JS deals with time in milliseconds, when recreating with Solidity,\n// multiply LF with 1,000 too even though time will not need milliseconds.\n// Concurrency.\n// Solidity computes regarding times will be operated on the normal seconds level.\nexport const TIME_FACTOR = 1000","import { LIQUIDITY_FACTOR } from \"../constants\";\nimport { MarketTime } from \"../types/market-time\";\n\n// Returns effective liquidity from liquidity factor.\n//\n// Leff = L(√(T - t))\n// Where T = End time, market closing time and t = current time.\n// To keep in line with Solidity, remove decimal part and keep whole number.\nexport function getEffectiveLiquidity({ currentTime, endTime }: MarketTime): number {\n return LIQUIDITY_FACTOR * getWholeNumberFromDecimal(Math.sqrt(endTime - currentTime))\n}\n\nfunction getWholeNumberFromDecimal(decimal: number): number {\n return parseInt(decimal.toString().split(\".\")[0])\n}","import gaussian from \"gaussian\"\n\nconst distribution = gaussian(0, 1)\n\n// CDF, Cumulative Distribution Function.\nexport function Phi(x: number): number {\n return distribution.cdf(x)\n}\n\n// PDF, Probability Density Function.\nexport function phi(x: number): number {\n return distribution.pdf(x)\n}\n\n// PPF or 1/CDF.\nexport function Phi_inverse(x: number): number {\n return distribution.ppf(x)\n}","import { Reserves } from \"../types/ reserves\"\nimport { MarketTime } from \"../types/market-time\"\nimport { Phi } from \"./gaussian\"\nimport { getEffectiveLiquidity } from \"./get-effective-liquidity\"\n\nexport function getPriceFromReseves({ x, y }: Reserves, marketTime: MarketTime): number {\n const effectiveL = getEffectiveLiquidity(marketTime)\n\n const z = (y - x) / effectiveL\n const price = Phi(z)\n\n return price\n}","import { getPriceFromReseves } from \"../amm-math/get-price-from-reserves\";\nimport { PRICE_DECIMALS } from \"../constants\";\nimport { Reserves } from \"../types/ reserves\";\nimport { AfterTrade } from \"../types/after-trade\";\nimport { MarketTime } from \"../types/market-time\";\n\nexport function getNewPriceCostAverageCost(\n newReserves: Reserves,\n marketTime: MarketTime,\n oldPrice: number,\n shares: number\n): Omit<AfterTrade, \"oldXReserve\" | \"oldYReserve\" | \"oldPrice\" | \"newXReserve\" | \"newYReserve\"> {\n const newPrice = getPriceFromReseves(newReserves, marketTime)\n const cost = parseFloat((((oldPrice + newPrice) / 2) * shares).toFixed(PRICE_DECIMALS))\n const averageCost = parseFloat((cost / shares).toFixed(PRICE_DECIMALS))\n\n const afterTrade = {\n newPrice,\n cost,\n averageCost\n }\n\n return afterTrade\n}","import { phi, Phi } from \"./gaussian\";\n\n// For a given x, y and Leff, this invariant must be equal or infinitesimally\n// close to 0.\n// Refer to https://www.paradigm.xyz/2024/11/pm-amm#90ef7fa55727.\nexport function invariant(x: number, y: number, Leff: number): number {\n const z = (y - x) / Leff\n\n return ((y - x) * Phi(z)) + (Leff * phi(z)) - y\n}","import { Limits } from \"../types/limits\"\nimport { MarketTime } from \"../types/market-time\"\nimport { getEffectiveLiquidity } from \"./get-effective-liquidity\"\nimport { invariant } from \"./invariant\"\n\n// Each of these two functions solve to determine the range of values\n// for y and x (yLimit and xLimit) respectively that needs to be approached\n// so that the function given at `invariant` will be equal or close to 0.\n// The whole point of these functions is that it narrows down two limits\n// `min` and `max` for both x and y. `min` is always lesser than `max`, by\n// inference, and applying `min` in the invariant yields a positive number \n// close to 0, say +0.04. `max` when applied to the invariant yields a \n// negative number close to 0, say -0.02. By establishing and using these\n// limits, it's easier for the Bisection function to find a middle ground\n// to pick which number between `min` an `max` yields the closest to 0 (on the\n// negative). That is the number we're looking for.\n//\n// As the limits of either go down, the inviariant positively expands, and it\n// negatively expands as the limits go up.\nexport function getMinAndMaxYReservesForNewXReserve(\n currentYReserve: number,\n newXReserve: number,\n marketTime: MarketTime\n): Limits {\n let minYReserve, maxYReserve\n let minYEvaluation = false, maxYEvaluation = false\n let margin = 5000\n const leff = getEffectiveLiquidity(marketTime)\n\n // Finding the upper limits.\n // We keep adding 10,000 until the invariant\n // results in below 0.\n while (!maxYEvaluation) {\n maxYEvaluation = invariant(newXReserve, currentYReserve, leff) < 0\n currentYReserve += margin\n }\n\n maxYReserve = currentYReserve\n\n // Finding the lower limits.\n // We keep adding 10,000 until the invariant\n // results in above 0.\n while (!minYEvaluation) {\n currentYReserve -= margin\n minYEvaluation = invariant(newXReserve, currentYReserve, leff) > 0\n }\n\n minYReserve = currentYReserve\n\n return { min: minYReserve, max: maxYReserve }\n}\n\nexport function getMinAndMaxXReservesForNewYReserve(\n currentXReserve: number,\n newYReserve: number,\n marketTime: MarketTime\n): Limits {\n let minXReserve, maxXReserve\n let minXEvaluation = false, maxXEvaluation = false\n let margin = 5000\n const leff = getEffectiveLiquidity(marketTime)\n\n // Finding the upper limits.\n // We keep adding 10,000 until the invariant\n // results in below 0.\n while (!maxXEvaluation) {\n maxXEvaluation = invariant(currentXReserve, newYReserve, leff) < 0\n currentXReserve += margin\n }\n\n maxXReserve = currentXReserve\n\n // Finding the lower limits.\n // We keep adding 10,000 until the invariant\n // results in above 0.\n while (!minXEvaluation) {\n currentXReserve -= margin\n minXEvaluation = invariant(currentXReserve, newYReserve, leff) > 0\n }\n\n minXReserve = currentXReserve\n\n return { min: minXReserve, max: maxXReserve }\n}","import { Reserves } from \"../types/ reserves\"\nimport { MarketTime } from \"../types/market-time\"\nimport { phi, Phi_inverse } from \"./gaussian\"\nimport { getEffectiveLiquidity } from \"./get-effective-liquidity\"\n\nexport function getReservesFromPrice(price: number, marketTime: MarketTime): Reserves {\n const effectiveL = getEffectiveLiquidity(marketTime)\n const z = Phi_inverse(price)\n const diff = (z) * effectiveL\n\n const y = (diff * price) + (effectiveL * phi(z))\n const x = y - diff\n\n return { x, y }\n}","import { AfterTrade } from \"../types/after-trade\"\nimport { Order } from \"../types/order\"\nimport { getNewPriceCostAverageCost } from \"../utils/get-new-price-data\"\nimport { getEffectiveLiquidity } from \"./get-effective-liquidity\"\nimport { getMinAndMaxXReservesForNewYReserve } from \"./get-min-and-max-xy-reserves\"\nimport { getReservesFromPrice } from \"./get-reserves-from-price\"\nimport { invariant } from \"./invariant\"\nimport bisect from \"bisect\"\n\nexport function getNewReservesDataAfterYTrade(order: Order): AfterTrade {\n const { shares, isBuy, price, marketTime } = order\n const { x: xReserve, y: yReserve } = getReservesFromPrice(price, marketTime)\n\n if (isBuy && shares >= yReserve) throw new Error(\"Insufficient Y Liquidity.\")\n\n const leff = getEffectiveLiquidity(marketTime)\n const newYReserve = isBuy ? yReserve - shares : yReserve + shares\n\n function evaluateX(x: number) {\n return invariant(x, newYReserve, leff) < 0\n }\n\n const currentXReserve = xReserve\n const { min, max } = getMinAndMaxXReservesForNewYReserve(\n currentXReserve,\n newYReserve,\n marketTime\n )\n const newXReserve = bisect(evaluateX, min, max)\n\n if (!isBuy && newXReserve <= 0) throw new Error(\"X Liquidity Depleted.\")\n\n const newReserves = { x: newXReserve, y: newYReserve }\n const { newPrice, cost, averageCost } = getNewPriceCostAverageCost(\n newReserves,\n marketTime,\n price,\n shares\n )\n\n const afterTrade = {\n oldXReserve: xReserve,\n oldYReserve: yReserve,\n oldPrice: price,\n newXReserve,\n newYReserve,\n newPrice,\n cost,\n averageCost\n }\n\n return afterTrade\n}","import { AfterTrade } from \"../types/after-trade\"\nimport { Order } from \"../types/order\"\nimport { getNewPriceCostAverageCost } from \"../utils/get-new-price-data\"\nimport { getEffectiveLiquidity } from \"./get-effective-liquidity\"\nimport { getMinAndMaxYReservesForNewXReserve } from \"./get-min-and-max-xy-reserves\"\nimport { getReservesFromPrice } from \"./get-reserves-from-price\"\nimport { invariant } from \"./invariant\"\nimport bisect from \"bisect\"\n\nexport function getNewReservesDataAfterXTrade(order: Order): AfterTrade {\n const { shares, isBuy, price, marketTime } = order\n const { x: xReserve, y: yReserve } = getReservesFromPrice(price, marketTime)\n\n if (isBuy && shares >= xReserve) throw new Error(\"Insufficient X Liquidity.\")\n\n const leff = getEffectiveLiquidity(marketTime)\n const newXReserve = isBuy ? xReserve - shares : xReserve + shares\n\n function evaluateY(y: number) {\n return invariant(newXReserve, y, leff) < 0\n }\n\n const currentYReserve = yReserve\n const { min, max } = getMinAndMaxYReservesForNewXReserve(\n currentYReserve,\n newXReserve,\n marketTime\n )\n const newYReserve = bisect(evaluateY, min, max)\n\n if (!isBuy && newYReserve <= 0) throw new Error(\"Y Liquidity Depleted.\")\n\n const newReserves = { x: newXReserve, y: newYReserve }\n const { newPrice, cost, averageCost } = getNewPriceCostAverageCost(\n newReserves,\n marketTime,\n price,\n shares\n )\n\n const afterTrade = {\n oldXReserve: xReserve,\n oldYReserve: yReserve,\n oldPrice: price,\n newXReserve,\n newYReserve,\n newPrice,\n cost,\n averageCost\n }\n\n return afterTrade\n}","import { getEffectiveLiquidity } from \"./amm-math/get-effective-liquidity\";\nimport { getNewReservesDataAfterYTrade } from \"./amm-math/get-new-reserves-after-x-trade\";\nimport { getNewReservesDataAfterXTrade } from \"./amm-math/get-new-reserves-after-y-trade\";\nimport { getPriceFromReseves } from \"./amm-math/get-price-from-reserves\";\nimport { getReservesFromPrice } from \"./amm-math/get-reserves-from-price\";\nimport { AfterTrade } from \"./types/after-trade\";\nimport { Limits } from \"./types/limits\";\nimport { MarketTime } from \"./types/market-time\";\nimport { Order } from \"./types/order\";\nimport { Reserves } from \"./types/ reserves\";\nimport { LIQUIDITY_FACTOR, PRICE_DECIMALS, STARTING_PRICE, TIME_FACTOR } from \"./constants\";\nimport { Phi, phi, Phi_inverse } from \"./amm-math/gaussian\";\n\nexport {\n AfterTrade,\n Limits,\n MarketTime,\n Order,\n Reserves\n}\n\nconst pmAmm = {\n LIQUIDITY_FACTOR,\n PRICE_DECIMALS,\n STARTING_PRICE,\n TIME_FACTOR,\n phi,\n Phi,\n Phi_inverse,\n getEffectiveLiquidity,\n getNewReservesDataAfterYTrade,\n getNewReservesDataAfterXTrade,\n getPriceFromReseves,\n getReservesFromPrice,\n}\n\nexport default pmAmm"],"mappings":"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","names":["bisect"]}
1
+ {"version":3,"sources":["../src/constants.ts","../src/amm-math/get-effective-liquidity.ts","../src/amm-math/gaussian.ts","../src/amm-math/get-price-from-reserves.ts","../src/utils/get-new-price-data.ts","../src/amm-math/invariant.ts","../src/amm-math/get-min-and-max-xy-reserves.ts","../src/amm-math/get-reserves-from-price.ts","../src/amm-math/get-new-reserves-after-y-trade.ts","../src/amm-math/get-new-reserves-after-x-trade.ts","../src/index.ts"],"sourcesContent":["// Staring price of both sides of the market.\nexport const STARTING_PRICE = 0.5\n// This, while not needed for this package, because JS operates\n// with floating point numbers, is needed to establish the point\n// of the current price of either sides of the market as having\n// 18 decimals on the contract interface.\nexport const PRICE_DECIMALS = 18\n// This is tentative, anyone can use any liquidity factor. This,\n// just like `PRICE_DECIMALS` establish the fact that we're using\n// a 10000 point liquidity factor on the contract interface.\nexport const LIQUIDITY_FACTOR = 10000\n// JS deals with time in milliseconds, when recreating with Solidity,\n// multiply LF with 1,000 too even though time will not need milliseconds.\n// Concurrency.\n// Solidity computes regarding times will be operated on the normal seconds level.\nexport const TIME_FACTOR = 1000","import { LIQUIDITY_FACTOR } from \"../constants\";\nimport { MarketTime } from \"../types/market-time\";\n\n// Returns effective liquidity from liquidity factor.\n//\n// Leff = L(√(T - t))\n// Where T = End time, market closing time and t = current time.\n// To keep in line with Solidity, remove decimal part and keep whole number.\nexport function getEffectiveLiquidity({ currentTime, endTime }: MarketTime): number {\n return LIQUIDITY_FACTOR * getWholeNumberFromDecimal(Math.sqrt(endTime - currentTime))\n}\n\nfunction getWholeNumberFromDecimal(decimal: number): number {\n return parseInt(decimal.toString().split(\".\")[0])\n}","import gaussian from \"gaussian\"\n\nconst distribution = gaussian(0, 1)\n\n// CDF, Cumulative Distribution Function.\nexport function Phi(x: number): number {\n return distribution.cdf(x)\n}\n\n// PDF, Probability Density Function.\nexport function phi(x: number): number {\n return distribution.pdf(x)\n}\n\n// PPF or 1/CDF.\nexport function Phi_inverse(x: number): number {\n return distribution.ppf(x)\n}","import { Reserves } from \"../types/ reserves\"\nimport { MarketTime } from \"../types/market-time\"\nimport { Phi } from \"./gaussian\"\nimport { getEffectiveLiquidity } from \"./get-effective-liquidity\"\n\nexport function getPriceFromReseves({ x, y }: Reserves, marketTime: MarketTime): number {\n const effectiveL = getEffectiveLiquidity(marketTime)\n\n const z = (y - x) / effectiveL\n const price = Phi(z)\n\n return price\n}","import { getPriceFromReseves } from \"../amm-math/get-price-from-reserves\";\nimport { PRICE_DECIMALS } from \"../constants\";\nimport { Reserves } from \"../types/ reserves\";\nimport { AfterTrade } from \"../types/after-trade\";\nimport { MarketTime } from \"../types/market-time\";\n\nexport function getNewPriceCostAverageCost(\n newReserves: Reserves,\n marketTime: MarketTime,\n oldPrice: number,\n shares: number\n): Omit<AfterTrade, \"oldXReserve\" | \"oldYReserve\" | \"oldPrice\" | \"newXReserve\" | \"newYReserve\"> {\n const newPrice = getPriceFromReseves(newReserves, marketTime)\n const cost = parseFloat((((oldPrice + newPrice) / 2) * shares).toFixed(PRICE_DECIMALS))\n const averageCost = parseFloat((cost / shares).toFixed(PRICE_DECIMALS))\n\n const afterTrade = {\n newPrice,\n cost,\n averageCost\n }\n\n return afterTrade\n}","import { phi, Phi } from \"./gaussian\";\n\n// For a given x, y and Leff, this invariant must be equal or infinitesimally\n// close to 0.\n// Refer to https://www.paradigm.xyz/2024/11/pm-amm#90ef7fa55727.\nexport function invariant(x: number, y: number, Leff: number): number {\n const z = (y - x) / Leff\n\n return ((y - x) * Phi(z)) + (Leff * phi(z)) - y\n}","import { Limits } from \"../types/limits\"\nimport { MarketTime } from \"../types/market-time\"\nimport { getEffectiveLiquidity } from \"./get-effective-liquidity\"\nimport { invariant } from \"./invariant\"\n\n// Each of these two functions solve to determine the range of values\n// for y and x (yLimit and xLimit) respectively that needs to be approached\n// so that the function given at `invariant` will be equal or close to 0.\n// The whole point of these functions is that it narrows down two limits\n// `min` and `max` for both x and y. `min` is always lesser than `max`, by\n// inference, and applying `min` in the invariant yields a positive number \n// close to 0, say +0.04. `max` when applied to the invariant yields a \n// negative number close to 0, say -0.02. By establishing and using these\n// limits, it's easier for the Bisection function to find a middle ground\n// to pick which number between `min` an `max` yields the closest to 0 (on the\n// negative). That is the number we're looking for.\n//\n// As the limits of either go down, the inviariant positively expands, and it\n// negatively expands as the limits go up.\nexport function getMinAndMaxYReservesForNewXReserve(\n currentYReserve: number,\n newXReserve: number,\n marketTime: MarketTime\n): Limits {\n let minYReserve, maxYReserve\n let minYEvaluation = false, maxYEvaluation = false\n let margin = 5000\n const leff = getEffectiveLiquidity(marketTime)\n\n // Finding the upper limits.\n // We keep adding 10,000 until the invariant\n // results in below 0.\n while (!maxYEvaluation) {\n maxYEvaluation = invariant(newXReserve, currentYReserve, leff) < 0\n currentYReserve += margin\n }\n\n maxYReserve = currentYReserve\n\n // Finding the lower limits.\n // We keep adding 10,000 until the invariant\n // results in above 0.\n while (!minYEvaluation) {\n currentYReserve -= margin\n minYEvaluation = invariant(newXReserve, currentYReserve, leff) > 0\n }\n\n minYReserve = currentYReserve\n\n return { min: minYReserve, max: maxYReserve }\n}\n\nexport function getMinAndMaxXReservesForNewYReserve(\n currentXReserve: number,\n newYReserve: number,\n marketTime: MarketTime\n): Limits {\n let minXReserve, maxXReserve\n let minXEvaluation = false, maxXEvaluation = false\n let margin = 5000\n const leff = getEffectiveLiquidity(marketTime)\n\n // Finding the upper limits.\n // We keep adding 10,000 until the invariant\n // results in below 0.\n while (!maxXEvaluation) {\n maxXEvaluation = invariant(currentXReserve, newYReserve, leff) < 0\n currentXReserve += margin\n }\n\n maxXReserve = currentXReserve\n\n // Finding the lower limits.\n // We keep adding 10,000 until the invariant\n // results in above 0.\n while (!minXEvaluation) {\n currentXReserve -= margin\n minXEvaluation = invariant(currentXReserve, newYReserve, leff) > 0\n }\n\n minXReserve = currentXReserve\n\n return { min: minXReserve, max: maxXReserve }\n}","import { Reserves } from \"../types/ reserves\"\nimport { MarketTime } from \"../types/market-time\"\nimport { phi, Phi_inverse } from \"./gaussian\"\nimport { getEffectiveLiquidity } from \"./get-effective-liquidity\"\n\nexport function getReservesFromPrice(price: number, marketTime: MarketTime): Reserves {\n const effectiveL = getEffectiveLiquidity(marketTime)\n const z = Phi_inverse(price)\n const diff = (z) * effectiveL\n\n const y = (diff * price) + (effectiveL * phi(z))\n const x = y - diff\n\n return { x, y }\n}","import { AfterTrade } from \"../types/after-trade\"\nimport { Order } from \"../types/order\"\nimport { getNewPriceCostAverageCost } from \"../utils/get-new-price-data\"\nimport { getEffectiveLiquidity } from \"./get-effective-liquidity\"\nimport { getMinAndMaxXReservesForNewYReserve } from \"./get-min-and-max-xy-reserves\"\nimport { getReservesFromPrice } from \"./get-reserves-from-price\"\nimport { invariant } from \"./invariant\"\nimport bisect from \"bisect\"\n\nexport function getNewReservesDataAfterYTrade(order: Order): AfterTrade {\n const { shares, isBuy, price, marketTime } = order\n const { x: xReserve, y: yReserve } = getReservesFromPrice(price, marketTime)\n\n if (isBuy && shares >= yReserve) throw new Error(\"Insufficient Y Liquidity.\")\n\n const leff = getEffectiveLiquidity(marketTime)\n const newYReserve = isBuy ? yReserve - shares : yReserve + shares\n\n function evaluateX(x: number) {\n return invariant(x, newYReserve, leff) < 0\n }\n\n const currentXReserve = xReserve\n const { min, max } = getMinAndMaxXReservesForNewYReserve(\n currentXReserve,\n newYReserve,\n marketTime\n )\n const newXReserve = bisect(evaluateX, min, max)\n\n if (!isBuy && newXReserve <= 0) throw new Error(\"X Liquidity Depleted.\")\n\n const newReserves = { x: newXReserve, y: newYReserve }\n const { newPrice, cost, averageCost } = getNewPriceCostAverageCost(\n newReserves,\n marketTime,\n price,\n shares\n )\n\n const afterTrade = {\n oldXReserve: xReserve,\n oldYReserve: yReserve,\n oldPrice: price,\n newXReserve,\n newYReserve,\n newPrice,\n cost,\n averageCost\n }\n\n return afterTrade\n}","import { AfterTrade } from \"../types/after-trade\"\nimport { Order } from \"../types/order\"\nimport { getNewPriceCostAverageCost } from \"../utils/get-new-price-data\"\nimport { getEffectiveLiquidity } from \"./get-effective-liquidity\"\nimport { getMinAndMaxYReservesForNewXReserve } from \"./get-min-and-max-xy-reserves\"\nimport { getReservesFromPrice } from \"./get-reserves-from-price\"\nimport { invariant } from \"./invariant\"\nimport bisect from \"bisect\"\n\nexport function getNewReservesDataAfterXTrade(order: Order): AfterTrade {\n const { shares, isBuy, price, marketTime } = order\n const { x: xReserve, y: yReserve } = getReservesFromPrice(price, marketTime)\n\n if (isBuy && shares >= xReserve) throw new Error(\"Insufficient X Liquidity.\")\n\n const leff = getEffectiveLiquidity(marketTime)\n const newXReserve = isBuy ? xReserve - shares : xReserve + shares\n\n function evaluateY(y: number) {\n return invariant(newXReserve, y, leff) < 0\n }\n\n const currentYReserve = yReserve\n const { min, max } = getMinAndMaxYReservesForNewXReserve(\n currentYReserve,\n newXReserve,\n marketTime\n )\n const newYReserve = bisect(evaluateY, min, max)\n\n if (!isBuy && newYReserve <= 0) throw new Error(\"Y Liquidity Depleted.\")\n\n const newReserves = { x: newXReserve, y: newYReserve }\n const { newPrice, cost, averageCost } = getNewPriceCostAverageCost(\n newReserves,\n marketTime,\n price,\n shares\n )\n\n const afterTrade = {\n oldXReserve: xReserve,\n oldYReserve: yReserve,\n oldPrice: price,\n newXReserve,\n newYReserve,\n newPrice,\n cost,\n averageCost\n }\n\n return afterTrade\n}","import { getEffectiveLiquidity } from \"./amm-math/get-effective-liquidity\";\nimport { getNewReservesDataAfterYTrade } from \"./amm-math/get-new-reserves-after-y-trade\";\nimport { getNewReservesDataAfterXTrade } from \"./amm-math/get-new-reserves-after-x-trade\";\nimport { getPriceFromReseves } from \"./amm-math/get-price-from-reserves\";\nimport { getReservesFromPrice } from \"./amm-math/get-reserves-from-price\";\nimport { AfterTrade } from \"./types/after-trade\";\nimport { Limits } from \"./types/limits\";\nimport { MarketTime } from \"./types/market-time\";\nimport { Order } from \"./types/order\";\nimport { Reserves } from \"./types/ reserves\";\nimport { LIQUIDITY_FACTOR, PRICE_DECIMALS, STARTING_PRICE, TIME_FACTOR } from \"./constants\";\nimport { Phi, phi, Phi_inverse } from \"./amm-math/gaussian\";\n\nexport {\n AfterTrade,\n Limits,\n MarketTime,\n Order,\n Reserves\n}\n\nconst pmAmm = {\n LIQUIDITY_FACTOR,\n PRICE_DECIMALS,\n STARTING_PRICE,\n TIME_FACTOR,\n phi,\n Phi,\n Phi_inverse,\n getEffectiveLiquidity,\n getNewReservesDataAfterYTrade,\n getNewReservesDataAfterXTrade,\n getPriceFromReseves,\n getReservesFromPrice,\n}\n\nexport default pmAmm"],"mappings":";AACO,IAAM,iBAAiB;AAKvB,IAAM,iBAAiB;AAIvB,IAAM,mBAAmB;AAKzB,IAAM,cAAc;;;ACPpB,SAAS,sBAAsB,EAAE,aAAa,QAAQ,GAAuB;AAChF,SAAO,mBAAmB,0BAA0B,KAAK,KAAK,UAAU,WAAW,CAAC;AACxF;AAEA,SAAS,0BAA0B,SAAyB;AACxD,SAAO,SAAS,QAAQ,SAAS,EAAE,MAAM,GAAG,EAAE,CAAC,CAAC;AACpD;;;ACdA,OAAO,cAAc;AAErB,IAAM,eAAe,SAAS,GAAG,CAAC;AAG3B,SAAS,IAAI,GAAmB;AACnC,SAAO,aAAa,IAAI,CAAC;AAC7B;AAGO,SAAS,IAAI,GAAmB;AACnC,SAAO,aAAa,IAAI,CAAC;AAC7B;AAGO,SAAS,YAAY,GAAmB;AAC3C,SAAO,aAAa,IAAI,CAAC;AAC7B;;;ACZO,SAAS,oBAAoB,EAAE,GAAG,EAAE,GAAa,YAAgC;AACpF,QAAM,aAAa,sBAAsB,UAAU;AAEnD,QAAM,KAAK,IAAI,KAAK;AACpB,QAAM,QAAQ,IAAI,CAAC;AAEnB,SAAO;AACX;;;ACNO,SAAS,2BACZ,aACA,YACA,UACA,QAC4F;AAC5F,QAAM,WAAW,oBAAoB,aAAa,UAAU;AAC5D,QAAM,OAAO,aAAc,WAAW,YAAY,IAAK,QAAQ,QAAQ,cAAc,CAAC;AACtF,QAAM,cAAc,YAAY,OAAO,QAAQ,QAAQ,cAAc,CAAC;AAEtE,QAAM,aAAa;AAAA,IACf;AAAA,IACA;AAAA,IACA;AAAA,EACJ;AAEA,SAAO;AACX;;;AClBO,SAAS,UAAU,GAAW,GAAW,MAAsB;AAClE,QAAM,KAAK,IAAI,KAAK;AAEpB,UAAS,IAAI,KAAK,IAAI,CAAC,IAAM,OAAO,IAAI,CAAC,IAAK;AAClD;;;ACUO,SAAS,oCACZ,iBACA,aACA,YACM;AACN,MAAI,aAAa;AACjB,MAAI,iBAAiB,OAAO,iBAAiB;AAC7C,MAAI,SAAS;AACb,QAAM,OAAO,sBAAsB,UAAU;AAK7C,SAAO,CAAC,gBAAgB;AACpB,qBAAiB,UAAU,aAAa,iBAAiB,IAAI,IAAI;AACjE,uBAAmB;AAAA,EACvB;AAEA,gBAAc;AAKd,SAAO,CAAC,gBAAgB;AACpB,uBAAmB;AACnB,qBAAiB,UAAU,aAAa,iBAAiB,IAAI,IAAI;AAAA,EACrE;AAEA,gBAAc;AAEd,SAAO,EAAE,KAAK,aAAa,KAAK,YAAY;AAChD;AAEO,SAAS,oCACZ,iBACA,aACA,YACM;AACN,MAAI,aAAa;AACjB,MAAI,iBAAiB,OAAO,iBAAiB;AAC7C,MAAI,SAAS;AACb,QAAM,OAAO,sBAAsB,UAAU;AAK7C,SAAO,CAAC,gBAAgB;AACpB,qBAAiB,UAAU,iBAAiB,aAAa,IAAI,IAAI;AACjE,uBAAmB;AAAA,EACvB;AAEA,gBAAc;AAKd,SAAO,CAAC,gBAAgB;AACpB,uBAAmB;AACnB,qBAAiB,UAAU,iBAAiB,aAAa,IAAI,IAAI;AAAA,EACrE;AAEA,gBAAc;AAEd,SAAO,EAAE,KAAK,aAAa,KAAK,YAAY;AAChD;;;AC9EO,SAAS,qBAAqB,OAAe,YAAkC;AAClF,QAAM,aAAa,sBAAsB,UAAU;AACnD,QAAM,IAAI,YAAY,KAAK;AAC3B,QAAM,OAAQ,IAAK;AAEnB,QAAM,IAAK,OAAO,QAAU,aAAa,IAAI,CAAC;AAC9C,QAAM,IAAI,IAAI;AAEd,SAAO,EAAE,GAAG,EAAE;AAClB;;;ACPA,OAAO,YAAY;AAEZ,SAAS,8BAA8B,OAA0B;AACpE,QAAM,EAAE,QAAQ,OAAO,OAAO,WAAW,IAAI;AAC7C,QAAM,EAAE,GAAG,UAAU,GAAG,SAAS,IAAI,qBAAqB,OAAO,UAAU;AAE3E,MAAI,SAAS,UAAU,SAAU,OAAM,IAAI,MAAM,2BAA2B;AAE5E,QAAM,OAAO,sBAAsB,UAAU;AAC7C,QAAM,cAAc,QAAQ,WAAW,SAAS,WAAW;AAE3D,WAAS,UAAU,GAAW;AAC1B,WAAO,UAAU,GAAG,aAAa,IAAI,IAAI;AAAA,EAC7C;AAEA,QAAM,kBAAkB;AACxB,QAAM,EAAE,KAAK,IAAI,IAAI;AAAA,IACjB;AAAA,IACA;AAAA,IACA;AAAA,EACJ;AACA,QAAM,cAAc,OAAO,WAAW,KAAK,GAAG;AAE9C,MAAI,CAAC,SAAS,eAAe,EAAG,OAAM,IAAI,MAAM,uBAAuB;AAEvE,QAAM,cAAc,EAAE,GAAG,aAAa,GAAG,YAAY;AACrD,QAAM,EAAE,UAAU,MAAM,YAAY,IAAI;AAAA,IACpC;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACJ;AAEA,QAAM,aAAa;AAAA,IACf,aAAa;AAAA,IACb,aAAa;AAAA,IACb,UAAU;AAAA,IACV;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACJ;AAEA,SAAO;AACX;;;AC7CA,OAAOA,aAAY;AAEZ,SAAS,8BAA8B,OAA0B;AACpE,QAAM,EAAE,QAAQ,OAAO,OAAO,WAAW,IAAI;AAC7C,QAAM,EAAE,GAAG,UAAU,GAAG,SAAS,IAAI,qBAAqB,OAAO,UAAU;AAE3E,MAAI,SAAS,UAAU,SAAU,OAAM,IAAI,MAAM,2BAA2B;AAE5E,QAAM,OAAO,sBAAsB,UAAU;AAC7C,QAAM,cAAc,QAAQ,WAAW,SAAS,WAAW;AAE3D,WAAS,UAAU,GAAW;AAC1B,WAAO,UAAU,aAAa,GAAG,IAAI,IAAI;AAAA,EAC7C;AAEA,QAAM,kBAAkB;AACxB,QAAM,EAAE,KAAK,IAAI,IAAI;AAAA,IACjB;AAAA,IACA;AAAA,IACA;AAAA,EACJ;AACA,QAAM,cAAcA,QAAO,WAAW,KAAK,GAAG;AAE9C,MAAI,CAAC,SAAS,eAAe,EAAG,OAAM,IAAI,MAAM,uBAAuB;AAEvE,QAAM,cAAc,EAAE,GAAG,aAAa,GAAG,YAAY;AACrD,QAAM,EAAE,UAAU,MAAM,YAAY,IAAI;AAAA,IACpC;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACJ;AAEA,QAAM,aAAa;AAAA,IACf,aAAa;AAAA,IACb,aAAa;AAAA,IACb,UAAU;AAAA,IACV;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACJ;AAEA,SAAO;AACX;;;AC/BA,IAAM,QAAQ;AAAA,EACV;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACJ;AAEA,IAAO,gBAAQ;","names":["bisect"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@0xfps/pmamm-js",
3
- "version": "0.0.5",
3
+ "version": "0.0.6",
4
4
  "description": "A TypeScript implementation of the core functionalities of the PM-AMM Model by Paradigm @ https://www.paradigm.xyz/2024/11/pm-amm.",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",