@0xfps/pmamm-js 0.0.4 → 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.d.mts CHANGED
@@ -42,11 +42,18 @@ type Limits = {
42
42
  max: number;
43
43
  };
44
44
 
45
+ declare function Phi(x: number): number;
46
+ declare function phi(x: number): number;
47
+ declare function Phi_inverse(x: number): number;
48
+
45
49
  declare const pmAmm: {
46
50
  LIQUIDITY_FACTOR: number;
47
51
  PRICE_DECIMALS: number;
48
52
  STARTING_PRICE: number;
49
53
  TIME_FACTOR: number;
54
+ phi: typeof phi;
55
+ Phi: typeof Phi;
56
+ Phi_inverse: typeof Phi_inverse;
50
57
  getEffectiveLiquidity: typeof getEffectiveLiquidity;
51
58
  getNewReservesDataAfterYTrade: typeof getNewReservesDataAfterYTrade;
52
59
  getNewReservesDataAfterXTrade: typeof getNewReservesDataAfterXTrade;
package/dist/index.d.ts CHANGED
@@ -42,11 +42,18 @@ type Limits = {
42
42
  max: number;
43
43
  };
44
44
 
45
+ declare function Phi(x: number): number;
46
+ declare function phi(x: number): number;
47
+ declare function Phi_inverse(x: number): number;
48
+
45
49
  declare const pmAmm: {
46
50
  LIQUIDITY_FACTOR: number;
47
51
  PRICE_DECIMALS: number;
48
52
  STARTING_PRICE: number;
49
53
  TIME_FACTOR: number;
54
+ phi: typeof phi;
55
+ Phi: typeof Phi;
56
+ Phi_inverse: typeof Phi_inverse;
50
57
  getEffectiveLiquidity: typeof getEffectiveLiquidity;
51
58
  getNewReservesDataAfterYTrade: typeof getNewReservesDataAfterYTrade;
52
59
  getNewReservesDataAfterXTrade: typeof getNewReservesDataAfterXTrade;
package/dist/index.js CHANGED
@@ -36,13 +36,16 @@ 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
44
44
  function getEffectiveLiquidity({ currentTime, endTime }) {
45
- return LIQUIDITY_FACTOR * Math.sqrt(endTime - currentTime);
45
+ return LIQUIDITY_FACTOR * getWholeNumberFromDecimal(Math.sqrt(endTime - currentTime));
46
+ }
47
+ function getWholeNumberFromDecimal(decimal) {
48
+ return parseInt(decimal.toString().split(".")[0]);
46
49
  }
47
50
 
48
51
  // src/amm-math/gaussian.ts
@@ -131,7 +134,7 @@ function getReservesFromPrice(price, marketTime) {
131
134
  return { x, y };
132
135
  }
133
136
 
134
- // src/amm-math/get-new-reserves-after-x-trade.ts
137
+ // src/amm-math/get-new-reserves-after-y-trade.ts
135
138
  var import_bisect = __toESM(require("bisect"));
136
139
  function getNewReservesDataAfterYTrade(order) {
137
140
  const { shares, isBuy, price, marketTime } = order;
@@ -170,7 +173,7 @@ function getNewReservesDataAfterYTrade(order) {
170
173
  return afterTrade;
171
174
  }
172
175
 
173
- // src/amm-math/get-new-reserves-after-y-trade.ts
176
+ // src/amm-math/get-new-reserves-after-x-trade.ts
174
177
  var import_bisect2 = __toESM(require("bisect"));
175
178
  function getNewReservesDataAfterXTrade(order) {
176
179
  const { shares, isBuy, price, marketTime } = order;
@@ -215,6 +218,9 @@ var pmAmm = {
215
218
  PRICE_DECIMALS,
216
219
  STARTING_PRICE,
217
220
  TIME_FACTOR,
221
+ phi,
222
+ Phi,
223
+ Phi_inverse,
218
224
  getEffectiveLiquidity,
219
225
  getNewReservesDataAfterYTrade,
220
226
  getNewReservesDataAfterXTrade,
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\";\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 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.\nexport function getEffectiveLiquidity({ currentTime, endTime }: MarketTime): number {\n return LIQUIDITY_FACTOR * Math.sqrt(endTime - currentTime)\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,12 +1,15 @@
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
8
8
  function getEffectiveLiquidity({ currentTime, endTime }) {
9
- return LIQUIDITY_FACTOR * Math.sqrt(endTime - currentTime);
9
+ return LIQUIDITY_FACTOR * getWholeNumberFromDecimal(Math.sqrt(endTime - currentTime));
10
+ }
11
+ function getWholeNumberFromDecimal(decimal) {
12
+ return parseInt(decimal.toString().split(".")[0]);
10
13
  }
11
14
 
12
15
  // src/amm-math/gaussian.ts
@@ -95,7 +98,7 @@ function getReservesFromPrice(price, marketTime) {
95
98
  return { x, y };
96
99
  }
97
100
 
98
- // src/amm-math/get-new-reserves-after-x-trade.ts
101
+ // src/amm-math/get-new-reserves-after-y-trade.ts
99
102
  import bisect from "bisect";
100
103
  function getNewReservesDataAfterYTrade(order) {
101
104
  const { shares, isBuy, price, marketTime } = order;
@@ -134,7 +137,7 @@ function getNewReservesDataAfterYTrade(order) {
134
137
  return afterTrade;
135
138
  }
136
139
 
137
- // src/amm-math/get-new-reserves-after-y-trade.ts
140
+ // src/amm-math/get-new-reserves-after-x-trade.ts
138
141
  import bisect2 from "bisect";
139
142
  function getNewReservesDataAfterXTrade(order) {
140
143
  const { shares, isBuy, price, marketTime } = order;
@@ -179,6 +182,9 @@ var pmAmm = {
179
182
  PRICE_DECIMALS,
180
183
  STARTING_PRICE,
181
184
  TIME_FACTOR,
185
+ phi,
186
+ Phi,
187
+ Phi_inverse,
182
188
  getEffectiveLiquidity,
183
189
  getNewReservesDataAfterYTrade,
184
190
  getNewReservesDataAfterXTrade,
@@ -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.\nexport function getEffectiveLiquidity({ currentTime, endTime }: MarketTime): number {\n return LIQUIDITY_FACTOR * Math.sqrt(endTime - currentTime)\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\";\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 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.4",
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",