@0xfps/pmamm-js 0.0.1

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.
@@ -0,0 +1,53 @@
1
+ type MarketTime = {
2
+ startTime: number;
3
+ currentTime: number;
4
+ endTime: number;
5
+ };
6
+
7
+ declare function getEffectiveLiquidity({ currentTime, endTime }: MarketTime): number;
8
+
9
+ type AfterTrade = {
10
+ oldXReserve: number;
11
+ oldYReserve: number;
12
+ oldPrice: number;
13
+ newXReserve: number;
14
+ newYReserve: number;
15
+ newPrice: number;
16
+ cost: number;
17
+ averageCost: number;
18
+ };
19
+
20
+ type Order = {
21
+ shares: number;
22
+ isBuy: boolean;
23
+ price: number;
24
+ marketTime: MarketTime;
25
+ };
26
+
27
+ declare function getNewReservesDataForXAfterYTrade(order: Order): AfterTrade;
28
+
29
+ declare function getNewReservesDataForYAfterXTrade(order: Order): AfterTrade;
30
+
31
+ type Reserves = {
32
+ x: number;
33
+ y: number;
34
+ };
35
+
36
+ declare function getPriceFromReseves({ x, y }: Reserves, marketTime: MarketTime): number;
37
+
38
+ declare function getReservesFromPrice(price: number, marketTime: MarketTime): Reserves;
39
+
40
+ type Limits = {
41
+ min: number;
42
+ max: number;
43
+ };
44
+
45
+ declare const pmAmm: {
46
+ getEffectiveLiquidity: typeof getEffectiveLiquidity;
47
+ getNewReservesDataForXAfterYTrade: typeof getNewReservesDataForXAfterYTrade;
48
+ getNewReservesDataForYAfterXTrade: typeof getNewReservesDataForYAfterXTrade;
49
+ getPriceFromReseves: typeof getPriceFromReseves;
50
+ getReservesFromPrice: typeof getReservesFromPrice;
51
+ };
52
+
53
+ export { type AfterTrade, type Limits, type MarketTime, type Order, type Reserves, pmAmm as default };
@@ -0,0 +1,53 @@
1
+ type MarketTime = {
2
+ startTime: number;
3
+ currentTime: number;
4
+ endTime: number;
5
+ };
6
+
7
+ declare function getEffectiveLiquidity({ currentTime, endTime }: MarketTime): number;
8
+
9
+ type AfterTrade = {
10
+ oldXReserve: number;
11
+ oldYReserve: number;
12
+ oldPrice: number;
13
+ newXReserve: number;
14
+ newYReserve: number;
15
+ newPrice: number;
16
+ cost: number;
17
+ averageCost: number;
18
+ };
19
+
20
+ type Order = {
21
+ shares: number;
22
+ isBuy: boolean;
23
+ price: number;
24
+ marketTime: MarketTime;
25
+ };
26
+
27
+ declare function getNewReservesDataForXAfterYTrade(order: Order): AfterTrade;
28
+
29
+ declare function getNewReservesDataForYAfterXTrade(order: Order): AfterTrade;
30
+
31
+ type Reserves = {
32
+ x: number;
33
+ y: number;
34
+ };
35
+
36
+ declare function getPriceFromReseves({ x, y }: Reserves, marketTime: MarketTime): number;
37
+
38
+ declare function getReservesFromPrice(price: number, marketTime: MarketTime): Reserves;
39
+
40
+ type Limits = {
41
+ min: number;
42
+ max: number;
43
+ };
44
+
45
+ declare const pmAmm: {
46
+ getEffectiveLiquidity: typeof getEffectiveLiquidity;
47
+ getNewReservesDataForXAfterYTrade: typeof getNewReservesDataForXAfterYTrade;
48
+ getNewReservesDataForYAfterXTrade: typeof getNewReservesDataForYAfterXTrade;
49
+ getPriceFromReseves: typeof getPriceFromReseves;
50
+ getReservesFromPrice: typeof getReservesFromPrice;
51
+ };
52
+
53
+ export { type AfterTrade, type Limits, type MarketTime, type Order, type Reserves, pmAmm as default };
package/dist/index.js ADDED
@@ -0,0 +1,219 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/index.ts
31
+ var index_exports = {};
32
+ __export(index_exports, {
33
+ default: () => index_default
34
+ });
35
+ module.exports = __toCommonJS(index_exports);
36
+
37
+ // src/constants.ts
38
+ var PRICE_DECIMALS = 6;
39
+ var LIQUIDITY_FACTOR = 100;
40
+
41
+ // src/amm-math/get-effective-liquidity.ts
42
+ function getEffectiveLiquidity({ currentTime, endTime }) {
43
+ return LIQUIDITY_FACTOR * Math.sqrt(endTime - currentTime);
44
+ }
45
+
46
+ // src/amm-math/gaussian.ts
47
+ var import_gaussian = __toESM(require("gaussian"));
48
+ var distribution = (0, import_gaussian.default)(0, 1);
49
+ function Phi(x) {
50
+ return distribution.cdf(x);
51
+ }
52
+ function phi(x) {
53
+ return distribution.pdf(x);
54
+ }
55
+ function Phi_inverse(x) {
56
+ return distribution.ppf(x);
57
+ }
58
+
59
+ // src/amm-math/get-price-from-reserves.ts
60
+ function getPriceFromReseves({ x, y }, marketTime) {
61
+ const effectiveL = getEffectiveLiquidity(marketTime);
62
+ const z = (y - x) / effectiveL;
63
+ const price = Phi(z);
64
+ return price;
65
+ }
66
+
67
+ // src/utils/get-new-price-data.ts
68
+ function getNewPriceCostAverageCost(newReserves, marketTime, oldPrice, shares) {
69
+ const newPrice = getPriceFromReseves(newReserves, marketTime);
70
+ const cost = parseFloat(((oldPrice + newPrice) / 2 * shares).toFixed(PRICE_DECIMALS));
71
+ const averageCost = parseFloat((cost / shares).toFixed(PRICE_DECIMALS));
72
+ const afterTrade = {
73
+ newPrice,
74
+ cost,
75
+ averageCost
76
+ };
77
+ return afterTrade;
78
+ }
79
+
80
+ // src/amm-math/invariant.ts
81
+ function invariant(x, y, Leff) {
82
+ const z = (y - x) / Leff;
83
+ return (y - x) * Phi(z) + Leff * phi(z) - y;
84
+ }
85
+
86
+ // src/amm-math/get-min-and-max-xy-reserves.ts
87
+ function getMinAndMaxYReservesForNewXReserve(currentYReserve, newXReserve, marketTime) {
88
+ let minYReserve, maxYReserve;
89
+ let minYEvaluation = false, maxYEvaluation = false;
90
+ let margin = 5e3;
91
+ const leff = getEffectiveLiquidity(marketTime);
92
+ while (!maxYEvaluation) {
93
+ maxYEvaluation = invariant(newXReserve, currentYReserve, leff) < 0;
94
+ currentYReserve += margin;
95
+ }
96
+ maxYReserve = currentYReserve;
97
+ while (!minYEvaluation) {
98
+ currentYReserve -= margin;
99
+ minYEvaluation = invariant(newXReserve, currentYReserve, leff) > 0;
100
+ }
101
+ minYReserve = currentYReserve;
102
+ return { min: minYReserve, max: maxYReserve };
103
+ }
104
+ function getMinAndMaxXReservesForNewYReserve(currentXReserve, newYReserve, marketTime) {
105
+ let minXReserve, maxXReserve;
106
+ let minXEvaluation = false, maxXEvaluation = false;
107
+ let margin = 5e3;
108
+ const leff = getEffectiveLiquidity(marketTime);
109
+ while (!maxXEvaluation) {
110
+ maxXEvaluation = invariant(currentXReserve, newYReserve, leff) < 0;
111
+ currentXReserve += margin;
112
+ }
113
+ maxXReserve = currentXReserve;
114
+ while (!minXEvaluation) {
115
+ currentXReserve -= margin;
116
+ minXEvaluation = invariant(currentXReserve, newYReserve, leff) > 0;
117
+ }
118
+ minXReserve = currentXReserve;
119
+ return { min: minXReserve, max: maxXReserve };
120
+ }
121
+
122
+ // src/amm-math/get-reserves-from-price.ts
123
+ function getReservesFromPrice(price, marketTime) {
124
+ const effectiveL = getEffectiveLiquidity(marketTime);
125
+ const z = Phi_inverse(price);
126
+ const diff = z * effectiveL;
127
+ const y = diff * price + effectiveL * phi(z);
128
+ const x = y - diff;
129
+ return { x, y };
130
+ }
131
+
132
+ // src/amm-math/get-new-reserves-for-x.ts
133
+ var import_bisect = __toESM(require("bisect"));
134
+ function getNewReservesDataForXAfterYTrade(order) {
135
+ const { shares, isBuy, price, marketTime } = order;
136
+ const { x: xReserve, y: yReserve } = getReservesFromPrice(price, marketTime);
137
+ if (isBuy && shares >= yReserve) throw new Error("Insufficient Y Liquidity.");
138
+ const leff = getEffectiveLiquidity(marketTime);
139
+ const newYReserve = isBuy ? yReserve - shares : yReserve + shares;
140
+ function evaluateX(x) {
141
+ return invariant(x, newYReserve, leff) < 0;
142
+ }
143
+ const currentXReserve = xReserve;
144
+ const { min, max } = getMinAndMaxXReservesForNewYReserve(
145
+ currentXReserve,
146
+ newYReserve,
147
+ marketTime
148
+ );
149
+ const newXReserve = (0, import_bisect.default)(evaluateX, min, max);
150
+ if (!isBuy && newXReserve <= 0) throw new Error("X Liquidity Depleted.");
151
+ const newReserves = { x: newXReserve, y: newYReserve };
152
+ const { newPrice, cost, averageCost } = getNewPriceCostAverageCost(
153
+ newReserves,
154
+ marketTime,
155
+ price,
156
+ shares
157
+ );
158
+ const afterTrade = {
159
+ oldXReserve: xReserve,
160
+ oldYReserve: yReserve,
161
+ oldPrice: price,
162
+ newXReserve,
163
+ newYReserve,
164
+ newPrice,
165
+ cost,
166
+ averageCost
167
+ };
168
+ return afterTrade;
169
+ }
170
+
171
+ // src/amm-math/get-new-reserves-for-y.ts
172
+ var import_bisect2 = __toESM(require("bisect"));
173
+ function getNewReservesDataForYAfterXTrade(order) {
174
+ const { shares, isBuy, price, marketTime } = order;
175
+ const { x: xReserve, y: yReserve } = getReservesFromPrice(price, marketTime);
176
+ if (isBuy && shares >= xReserve) throw new Error("Insufficient X Liquidity.");
177
+ const leff = getEffectiveLiquidity(marketTime);
178
+ const newXReserve = isBuy ? xReserve - shares : xReserve + shares;
179
+ function evaluateY(y) {
180
+ return invariant(newXReserve, y, leff) < 0;
181
+ }
182
+ const currentYReserve = yReserve;
183
+ const { min, max } = getMinAndMaxYReservesForNewXReserve(
184
+ currentYReserve,
185
+ newXReserve,
186
+ marketTime
187
+ );
188
+ const newYReserve = (0, import_bisect2.default)(evaluateY, min, max);
189
+ if (!isBuy && newYReserve <= 0) throw new Error("Y Liquidity Depleted.");
190
+ const newReserves = { x: newXReserve, y: newYReserve };
191
+ const { newPrice, cost, averageCost } = getNewPriceCostAverageCost(
192
+ newReserves,
193
+ marketTime,
194
+ price,
195
+ shares
196
+ );
197
+ const afterTrade = {
198
+ oldXReserve: xReserve,
199
+ oldYReserve: yReserve,
200
+ oldPrice: price,
201
+ newXReserve,
202
+ newYReserve,
203
+ newPrice,
204
+ cost,
205
+ averageCost
206
+ };
207
+ return afterTrade;
208
+ }
209
+
210
+ // src/index.ts
211
+ var pmAmm = {
212
+ getEffectiveLiquidity,
213
+ getNewReservesDataForXAfterYTrade,
214
+ getNewReservesDataForYAfterXTrade,
215
+ getPriceFromReseves,
216
+ getReservesFromPrice
217
+ };
218
+ var index_default = pmAmm;
219
+ //# sourceMappingURL=index.js.map
@@ -0,0 +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-for-x.ts","../src/amm-math/get-new-reserves-for-y.ts"],"sourcesContent":["import { getEffectiveLiquidity } from \"./amm-math/get-effective-liquidity\";\nimport { getNewReservesDataForXAfterYTrade } from \"./amm-math/get-new-reserves-for-x\";\nimport { getNewReservesDataForYAfterXTrade } from \"./amm-math/get-new-reserves-for-y\";\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\";\n\nexport {\n AfterTrade,\n Limits,\n MarketTime,\n Order,\n Reserves\n}\n\nconst pmAmm = {\n getEffectiveLiquidity,\n getNewReservesDataForXAfterYTrade,\n getNewReservesDataForYAfterXTrade,\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, 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 getNewReservesDataForXAfterYTrade(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 getNewReservesDataForYAfterXTrade(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 ADDED
@@ -0,0 +1,186 @@
1
+ // src/constants.ts
2
+ var PRICE_DECIMALS = 6;
3
+ var LIQUIDITY_FACTOR = 100;
4
+
5
+ // src/amm-math/get-effective-liquidity.ts
6
+ function getEffectiveLiquidity({ currentTime, endTime }) {
7
+ return LIQUIDITY_FACTOR * Math.sqrt(endTime - currentTime);
8
+ }
9
+
10
+ // src/amm-math/gaussian.ts
11
+ import gaussian from "gaussian";
12
+ var distribution = gaussian(0, 1);
13
+ function Phi(x) {
14
+ return distribution.cdf(x);
15
+ }
16
+ function phi(x) {
17
+ return distribution.pdf(x);
18
+ }
19
+ function Phi_inverse(x) {
20
+ return distribution.ppf(x);
21
+ }
22
+
23
+ // src/amm-math/get-price-from-reserves.ts
24
+ function getPriceFromReseves({ x, y }, marketTime) {
25
+ const effectiveL = getEffectiveLiquidity(marketTime);
26
+ const z = (y - x) / effectiveL;
27
+ const price = Phi(z);
28
+ return price;
29
+ }
30
+
31
+ // src/utils/get-new-price-data.ts
32
+ function getNewPriceCostAverageCost(newReserves, marketTime, oldPrice, shares) {
33
+ const newPrice = getPriceFromReseves(newReserves, marketTime);
34
+ const cost = parseFloat(((oldPrice + newPrice) / 2 * shares).toFixed(PRICE_DECIMALS));
35
+ const averageCost = parseFloat((cost / shares).toFixed(PRICE_DECIMALS));
36
+ const afterTrade = {
37
+ newPrice,
38
+ cost,
39
+ averageCost
40
+ };
41
+ return afterTrade;
42
+ }
43
+
44
+ // src/amm-math/invariant.ts
45
+ function invariant(x, y, Leff) {
46
+ const z = (y - x) / Leff;
47
+ return (y - x) * Phi(z) + Leff * phi(z) - y;
48
+ }
49
+
50
+ // src/amm-math/get-min-and-max-xy-reserves.ts
51
+ function getMinAndMaxYReservesForNewXReserve(currentYReserve, newXReserve, marketTime) {
52
+ let minYReserve, maxYReserve;
53
+ let minYEvaluation = false, maxYEvaluation = false;
54
+ let margin = 5e3;
55
+ const leff = getEffectiveLiquidity(marketTime);
56
+ while (!maxYEvaluation) {
57
+ maxYEvaluation = invariant(newXReserve, currentYReserve, leff) < 0;
58
+ currentYReserve += margin;
59
+ }
60
+ maxYReserve = currentYReserve;
61
+ while (!minYEvaluation) {
62
+ currentYReserve -= margin;
63
+ minYEvaluation = invariant(newXReserve, currentYReserve, leff) > 0;
64
+ }
65
+ minYReserve = currentYReserve;
66
+ return { min: minYReserve, max: maxYReserve };
67
+ }
68
+ function getMinAndMaxXReservesForNewYReserve(currentXReserve, newYReserve, marketTime) {
69
+ let minXReserve, maxXReserve;
70
+ let minXEvaluation = false, maxXEvaluation = false;
71
+ let margin = 5e3;
72
+ const leff = getEffectiveLiquidity(marketTime);
73
+ while (!maxXEvaluation) {
74
+ maxXEvaluation = invariant(currentXReserve, newYReserve, leff) < 0;
75
+ currentXReserve += margin;
76
+ }
77
+ maxXReserve = currentXReserve;
78
+ while (!minXEvaluation) {
79
+ currentXReserve -= margin;
80
+ minXEvaluation = invariant(currentXReserve, newYReserve, leff) > 0;
81
+ }
82
+ minXReserve = currentXReserve;
83
+ return { min: minXReserve, max: maxXReserve };
84
+ }
85
+
86
+ // src/amm-math/get-reserves-from-price.ts
87
+ function getReservesFromPrice(price, marketTime) {
88
+ const effectiveL = getEffectiveLiquidity(marketTime);
89
+ const z = Phi_inverse(price);
90
+ const diff = z * effectiveL;
91
+ const y = diff * price + effectiveL * phi(z);
92
+ const x = y - diff;
93
+ return { x, y };
94
+ }
95
+
96
+ // src/amm-math/get-new-reserves-for-x.ts
97
+ import bisect from "bisect";
98
+ function getNewReservesDataForXAfterYTrade(order) {
99
+ const { shares, isBuy, price, marketTime } = order;
100
+ const { x: xReserve, y: yReserve } = getReservesFromPrice(price, marketTime);
101
+ if (isBuy && shares >= yReserve) throw new Error("Insufficient Y Liquidity.");
102
+ const leff = getEffectiveLiquidity(marketTime);
103
+ const newYReserve = isBuy ? yReserve - shares : yReserve + shares;
104
+ function evaluateX(x) {
105
+ return invariant(x, newYReserve, leff) < 0;
106
+ }
107
+ const currentXReserve = xReserve;
108
+ const { min, max } = getMinAndMaxXReservesForNewYReserve(
109
+ currentXReserve,
110
+ newYReserve,
111
+ marketTime
112
+ );
113
+ const newXReserve = bisect(evaluateX, min, max);
114
+ if (!isBuy && newXReserve <= 0) throw new Error("X Liquidity Depleted.");
115
+ const newReserves = { x: newXReserve, y: newYReserve };
116
+ const { newPrice, cost, averageCost } = getNewPriceCostAverageCost(
117
+ newReserves,
118
+ marketTime,
119
+ price,
120
+ shares
121
+ );
122
+ const afterTrade = {
123
+ oldXReserve: xReserve,
124
+ oldYReserve: yReserve,
125
+ oldPrice: price,
126
+ newXReserve,
127
+ newYReserve,
128
+ newPrice,
129
+ cost,
130
+ averageCost
131
+ };
132
+ return afterTrade;
133
+ }
134
+
135
+ // src/amm-math/get-new-reserves-for-y.ts
136
+ import bisect2 from "bisect";
137
+ function getNewReservesDataForYAfterXTrade(order) {
138
+ const { shares, isBuy, price, marketTime } = order;
139
+ const { x: xReserve, y: yReserve } = getReservesFromPrice(price, marketTime);
140
+ if (isBuy && shares >= xReserve) throw new Error("Insufficient X Liquidity.");
141
+ const leff = getEffectiveLiquidity(marketTime);
142
+ const newXReserve = isBuy ? xReserve - shares : xReserve + shares;
143
+ function evaluateY(y) {
144
+ return invariant(newXReserve, y, leff) < 0;
145
+ }
146
+ const currentYReserve = yReserve;
147
+ const { min, max } = getMinAndMaxYReservesForNewXReserve(
148
+ currentYReserve,
149
+ newXReserve,
150
+ marketTime
151
+ );
152
+ const newYReserve = bisect2(evaluateY, min, max);
153
+ if (!isBuy && newYReserve <= 0) throw new Error("Y Liquidity Depleted.");
154
+ const newReserves = { x: newXReserve, y: newYReserve };
155
+ const { newPrice, cost, averageCost } = getNewPriceCostAverageCost(
156
+ newReserves,
157
+ marketTime,
158
+ price,
159
+ shares
160
+ );
161
+ const afterTrade = {
162
+ oldXReserve: xReserve,
163
+ oldYReserve: yReserve,
164
+ oldPrice: price,
165
+ newXReserve,
166
+ newYReserve,
167
+ newPrice,
168
+ cost,
169
+ averageCost
170
+ };
171
+ return afterTrade;
172
+ }
173
+
174
+ // src/index.ts
175
+ var pmAmm = {
176
+ getEffectiveLiquidity,
177
+ getNewReservesDataForXAfterYTrade,
178
+ getNewReservesDataForYAfterXTrade,
179
+ getPriceFromReseves,
180
+ getReservesFromPrice
181
+ };
182
+ var index_default = pmAmm;
183
+ export {
184
+ index_default as default
185
+ };
186
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +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-for-x.ts","../src/amm-math/get-new-reserves-for-y.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, 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 getNewReservesDataForXAfterYTrade(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 getNewReservesDataForYAfterXTrade(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 { getNewReservesDataForXAfterYTrade } from \"./amm-math/get-new-reserves-for-x\";\nimport { getNewReservesDataForYAfterXTrade } from \"./amm-math/get-new-reserves-for-y\";\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\";\n\nexport {\n AfterTrade,\n Limits,\n MarketTime,\n Order,\n Reserves\n}\n\nconst pmAmm = {\n getEffectiveLiquidity,\n getNewReservesDataForXAfterYTrade,\n getNewReservesDataForYAfterXTrade,\n getPriceFromReseves,\n getReservesFromPrice,\n}\n\nexport default pmAmm"],"mappings":"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","names":["bisect"]}
package/package.json ADDED
@@ -0,0 +1,43 @@
1
+ {
2
+ "name": "@0xfps/pmamm-js",
3
+ "version": "0.0.1",
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
+ "main": "./dist/index.js",
6
+ "module": "./dist/index.mjs",
7
+ "types": "./dist/index.d.ts",
8
+ "files": [
9
+ "dist"
10
+ ],
11
+ "scripts": {
12
+ "test": "echo \"Error: no test specified\" && exit 1",
13
+ "build": "rm -rf dist && tsup"
14
+ },
15
+ "repository": {
16
+ "type": "git",
17
+ "url": "git+https://github.com/0xfps/pmamm-js.git"
18
+ },
19
+ "keywords": [
20
+ "pm-amm",
21
+ "prediction-market",
22
+ "amm",
23
+ "pmamm",
24
+ "prediction-market-amm",
25
+ "automated-market-maker",
26
+ "prediction-market-automated-market-maker"
27
+ ],
28
+ "author": "0xfps",
29
+ "license": "MIT",
30
+ "bugs": {
31
+ "url": "https://github.com/0xfps/pmamm-js/issues"
32
+ },
33
+ "homepage": "https://github.com/0xfps/pmamm-js#readme",
34
+ "dependencies": {
35
+ "@types/gaussian": "^1.2.2",
36
+ "bisect": "^1.0.0",
37
+ "gaussian": "^1.3.0",
38
+ "tsup": "^8.5.1"
39
+ },
40
+ "devDependencies": {
41
+ "typescript": "^6.0.2"
42
+ }
43
+ }