@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 +7 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +11 -5
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +11 -5
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
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 =
|
|
40
|
-
var LIQUIDITY_FACTOR =
|
|
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-
|
|
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-
|
|
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 =
|
|
4
|
-
var LIQUIDITY_FACTOR =
|
|
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-
|
|
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-
|
|
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,
|
package/dist/index.mjs.map
CHANGED
|
@@ -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":";AACO,IAAM,iBAAiB;AAKvB,IAAM,iBAAiB;AAIvB,IAAM,mBAAmB;AAKzB,IAAM,cAAc;;;ACRpB,SAAS,sBAAsB,EAAE,aAAa,QAAQ,GAAuB;AAChF,SAAO,mBAAmB,KAAK,KAAK,UAAU,WAAW;AAC7D;;;ACTA,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;;;AChCA,IAAM,QAAQ;AAAA,EACV;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACJ;AAEA,IAAO,gBAAQ;","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":"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","names":["bisect"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@0xfps/pmamm-js",
|
|
3
|
-
"version": "0.0.
|
|
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",
|