@0xfps/pmamm-js 0.0.1 → 0.0.3
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/README.md +109 -0
- package/dist/index.d.mts +8 -4
- package/dist/index.d.ts +8 -4
- package/dist/index.js +12 -6
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +12 -6
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/README.md
ADDED
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
# PM-AMM (Prediction Market Automated Market Maker)
|
|
2
|
+
#### `pmamm.js`
|
|
3
|
+
|
|
4
|
+
This package provides a practical implementation of the prediction market automated market maker introduced by Paradigm, commonly referred to as the [pm-AMM](https://www.paradigm.xyz/2024/11/pm-amm). The pm-AMM is designed specifically for outcome tokens; assets that resolve to fixed payoffs (e.g., $1 or $0), and is derived from a probabilistic model known as Gaussian Score Dynamics. Unlike traditional AMMs such as constant product or LMSR, this design enforces a uniform loss-vs-rebalancing (LVR) profile, meaning liquidity providers incur losses at a rate proportional to pool value regardless of price, while concentrating liquidity around the most informative probability region (near 50%).
|
|
5
|
+
|
|
6
|
+
Beyond the core invariant, the package covers the full set of mechanics required to work with a pm-AMM in practice. It includes utilities for modeling price dynamics over time, computing price from reserves and inversely deriving reserves from a target price, and simulating trades to determine resulting costs and updated pool states. Users can simulate buying or selling either `YES` or `NO` tokens, with accurate computation of post-trade reserves and average execution cost. Additionally, the package incorporates a port of the reference Python simulator, enabling numerical experimentation and validation, along with a small set of helper utilities to streamline integration and testing workflows.
|
|
7
|
+
|
|
8
|
+
Note that the `X` token represents the `YES` outcome, while the `Y` token represents the `NO` outcome.
|
|
9
|
+
|
|
10
|
+
## How To Install
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
npm install @0xfps/pmamm-js
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
## Important Types
|
|
18
|
+
|
|
19
|
+
### `Reserves`
|
|
20
|
+
```typescript
|
|
21
|
+
type Reserves = {
|
|
22
|
+
x: number, // $YES.
|
|
23
|
+
y: number // $NO.
|
|
24
|
+
}
|
|
25
|
+
```
|
|
26
|
+
Shows the number of shares available for the `YES` and `NO` tokens.
|
|
27
|
+
|
|
28
|
+
### `AfterTrade`
|
|
29
|
+
```typescript
|
|
30
|
+
type AfterTrade = {
|
|
31
|
+
oldXReserve: number,
|
|
32
|
+
oldYReserve: number,
|
|
33
|
+
oldPrice: number,
|
|
34
|
+
newXReserve: number,
|
|
35
|
+
newYReserve: number,
|
|
36
|
+
newPrice: number
|
|
37
|
+
cost: number,
|
|
38
|
+
averageCost: number,
|
|
39
|
+
}
|
|
40
|
+
```
|
|
41
|
+
Shows the metadata of a the result of the purchase or sale of a certain number of shares.
|
|
42
|
+
|
|
43
|
+
### `MarketTime`
|
|
44
|
+
```typescript
|
|
45
|
+
type type MarketTime = {
|
|
46
|
+
startTime: number,
|
|
47
|
+
currentTime: number,
|
|
48
|
+
endTime: number
|
|
49
|
+
}
|
|
50
|
+
```
|
|
51
|
+
Every market runs within a certain time. This shows the time data, the start time of the market, the end time of the market and the current time, ideally, when the trade is to be done.
|
|
52
|
+
|
|
53
|
+
### `Order`
|
|
54
|
+
```typescript
|
|
55
|
+
type Order = {
|
|
56
|
+
shares: number,
|
|
57
|
+
isBuy: boolean,
|
|
58
|
+
price: number,
|
|
59
|
+
marketTime: MarketTime
|
|
60
|
+
}
|
|
61
|
+
```
|
|
62
|
+
Contains the details of the purchase or sale of a certain number of shares. It's token agnostic. There are separate functions for the purchase and sale of the `YES` and `NO` tokens.
|
|
63
|
+
|
|
64
|
+
## Usage
|
|
65
|
+
|
|
66
|
+
### `getNewReservesDataAfterXTrade`
|
|
67
|
+
```typescript
|
|
68
|
+
function getNewReservesDataAfterXTrade(order: Order): AfterTrade
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Returns the market data that would be in place after a successful execution of the purchase or sale of `X` shares (`YES` shares).
|
|
72
|
+
|
|
73
|
+
### `getNewReservesDataAfterYTrade`
|
|
74
|
+
```typescript
|
|
75
|
+
function getNewReservesDataAfterYTrade(order: Order): AfterTrade
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Returns the market data that would be in place after a successful execution of the purchase or sale of the `Y` shares (`NO` shares).
|
|
79
|
+
|
|
80
|
+
### `getPriceFromReseves`
|
|
81
|
+
```typescript
|
|
82
|
+
function getPriceFromReseves(reserves: Reserves, marketTime: MarketTime): number
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Returns the price of the `X` token from the reserves of `X` and `Y` using the market time. To get the price of `Y`, simply do:
|
|
86
|
+
```typescript
|
|
87
|
+
const yPrice = 1 - getPriceFromReseves(reserves, marketTime)
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### `getReservesFromPrice`
|
|
91
|
+
```typescript
|
|
92
|
+
function getReservesFromPrice(price: number, marketTime: MarketTime): Reserves
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
Returns the quantity of `X` and `Y` shares available using the price and the market time.
|
|
96
|
+
|
|
97
|
+
### `getEffectiveLiquidity`
|
|
98
|
+
```typescript
|
|
99
|
+
function getEffectiveLiquidity(marketTime: MarketTime): number
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
Returns effective liquidity from liquidity factor. Leff = L(√(T - t)). Where T = End time, market closing time and t = current time.
|
|
103
|
+
|
|
104
|
+
### `invariant`
|
|
105
|
+
```typescript
|
|
106
|
+
function invariant(x: number, y: number, Leff: number): number
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
Given a particular number of `X` and `Y` shares and an effective liquidity, `Leff`, this function should return `0` or a number infinitesimally close to `0`. This validates that the `X` and `Y` share amounts are valid reserves for the PM-AMM. It's the `XY = K` of PM-AMMs.
|
package/dist/index.d.mts
CHANGED
|
@@ -24,9 +24,9 @@ type Order = {
|
|
|
24
24
|
marketTime: MarketTime;
|
|
25
25
|
};
|
|
26
26
|
|
|
27
|
-
declare function
|
|
27
|
+
declare function getNewReservesDataAfterYTrade(order: Order): AfterTrade;
|
|
28
28
|
|
|
29
|
-
declare function
|
|
29
|
+
declare function getNewReservesDataAfterXTrade(order: Order): AfterTrade;
|
|
30
30
|
|
|
31
31
|
type Reserves = {
|
|
32
32
|
x: number;
|
|
@@ -43,9 +43,13 @@ type Limits = {
|
|
|
43
43
|
};
|
|
44
44
|
|
|
45
45
|
declare const pmAmm: {
|
|
46
|
+
LIQUIDITY_FACTOR: number;
|
|
47
|
+
PRICE_DECIMALS: number;
|
|
48
|
+
STARTING_PRICE: number;
|
|
49
|
+
TIME_FACTOR: number;
|
|
46
50
|
getEffectiveLiquidity: typeof getEffectiveLiquidity;
|
|
47
|
-
|
|
48
|
-
|
|
51
|
+
getNewReservesDataAfterYTrade: typeof getNewReservesDataAfterYTrade;
|
|
52
|
+
getNewReservesDataAfterXTrade: typeof getNewReservesDataAfterXTrade;
|
|
49
53
|
getPriceFromReseves: typeof getPriceFromReseves;
|
|
50
54
|
getReservesFromPrice: typeof getReservesFromPrice;
|
|
51
55
|
};
|
package/dist/index.d.ts
CHANGED
|
@@ -24,9 +24,9 @@ type Order = {
|
|
|
24
24
|
marketTime: MarketTime;
|
|
25
25
|
};
|
|
26
26
|
|
|
27
|
-
declare function
|
|
27
|
+
declare function getNewReservesDataAfterYTrade(order: Order): AfterTrade;
|
|
28
28
|
|
|
29
|
-
declare function
|
|
29
|
+
declare function getNewReservesDataAfterXTrade(order: Order): AfterTrade;
|
|
30
30
|
|
|
31
31
|
type Reserves = {
|
|
32
32
|
x: number;
|
|
@@ -43,9 +43,13 @@ type Limits = {
|
|
|
43
43
|
};
|
|
44
44
|
|
|
45
45
|
declare const pmAmm: {
|
|
46
|
+
LIQUIDITY_FACTOR: number;
|
|
47
|
+
PRICE_DECIMALS: number;
|
|
48
|
+
STARTING_PRICE: number;
|
|
49
|
+
TIME_FACTOR: number;
|
|
46
50
|
getEffectiveLiquidity: typeof getEffectiveLiquidity;
|
|
47
|
-
|
|
48
|
-
|
|
51
|
+
getNewReservesDataAfterYTrade: typeof getNewReservesDataAfterYTrade;
|
|
52
|
+
getNewReservesDataAfterXTrade: typeof getNewReservesDataAfterXTrade;
|
|
49
53
|
getPriceFromReseves: typeof getPriceFromReseves;
|
|
50
54
|
getReservesFromPrice: typeof getReservesFromPrice;
|
|
51
55
|
};
|
package/dist/index.js
CHANGED
|
@@ -35,8 +35,10 @@ __export(index_exports, {
|
|
|
35
35
|
module.exports = __toCommonJS(index_exports);
|
|
36
36
|
|
|
37
37
|
// src/constants.ts
|
|
38
|
+
var STARTING_PRICE = 0.5;
|
|
38
39
|
var PRICE_DECIMALS = 6;
|
|
39
40
|
var LIQUIDITY_FACTOR = 100;
|
|
41
|
+
var TIME_FACTOR = 1e3;
|
|
40
42
|
|
|
41
43
|
// src/amm-math/get-effective-liquidity.ts
|
|
42
44
|
function getEffectiveLiquidity({ currentTime, endTime }) {
|
|
@@ -129,9 +131,9 @@ function getReservesFromPrice(price, marketTime) {
|
|
|
129
131
|
return { x, y };
|
|
130
132
|
}
|
|
131
133
|
|
|
132
|
-
// src/amm-math/get-new-reserves-
|
|
134
|
+
// src/amm-math/get-new-reserves-after-x-trade.ts
|
|
133
135
|
var import_bisect = __toESM(require("bisect"));
|
|
134
|
-
function
|
|
136
|
+
function getNewReservesDataAfterYTrade(order) {
|
|
135
137
|
const { shares, isBuy, price, marketTime } = order;
|
|
136
138
|
const { x: xReserve, y: yReserve } = getReservesFromPrice(price, marketTime);
|
|
137
139
|
if (isBuy && shares >= yReserve) throw new Error("Insufficient Y Liquidity.");
|
|
@@ -168,9 +170,9 @@ function getNewReservesDataForXAfterYTrade(order) {
|
|
|
168
170
|
return afterTrade;
|
|
169
171
|
}
|
|
170
172
|
|
|
171
|
-
// src/amm-math/get-new-reserves-
|
|
173
|
+
// src/amm-math/get-new-reserves-after-y-trade.ts
|
|
172
174
|
var import_bisect2 = __toESM(require("bisect"));
|
|
173
|
-
function
|
|
175
|
+
function getNewReservesDataAfterXTrade(order) {
|
|
174
176
|
const { shares, isBuy, price, marketTime } = order;
|
|
175
177
|
const { x: xReserve, y: yReserve } = getReservesFromPrice(price, marketTime);
|
|
176
178
|
if (isBuy && shares >= xReserve) throw new Error("Insufficient X Liquidity.");
|
|
@@ -209,9 +211,13 @@ function getNewReservesDataForYAfterXTrade(order) {
|
|
|
209
211
|
|
|
210
212
|
// src/index.ts
|
|
211
213
|
var pmAmm = {
|
|
214
|
+
LIQUIDITY_FACTOR,
|
|
215
|
+
PRICE_DECIMALS,
|
|
216
|
+
STARTING_PRICE,
|
|
217
|
+
TIME_FACTOR,
|
|
212
218
|
getEffectiveLiquidity,
|
|
213
|
-
|
|
214
|
-
|
|
219
|
+
getNewReservesDataAfterYTrade,
|
|
220
|
+
getNewReservesDataAfterXTrade,
|
|
215
221
|
getPriceFromReseves,
|
|
216
222
|
getReservesFromPrice
|
|
217
223
|
};
|
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-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"]}
|
|
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"]}
|
package/dist/index.mjs
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
// src/constants.ts
|
|
2
|
+
var STARTING_PRICE = 0.5;
|
|
2
3
|
var PRICE_DECIMALS = 6;
|
|
3
4
|
var LIQUIDITY_FACTOR = 100;
|
|
5
|
+
var TIME_FACTOR = 1e3;
|
|
4
6
|
|
|
5
7
|
// src/amm-math/get-effective-liquidity.ts
|
|
6
8
|
function getEffectiveLiquidity({ currentTime, endTime }) {
|
|
@@ -93,9 +95,9 @@ function getReservesFromPrice(price, marketTime) {
|
|
|
93
95
|
return { x, y };
|
|
94
96
|
}
|
|
95
97
|
|
|
96
|
-
// src/amm-math/get-new-reserves-
|
|
98
|
+
// src/amm-math/get-new-reserves-after-x-trade.ts
|
|
97
99
|
import bisect from "bisect";
|
|
98
|
-
function
|
|
100
|
+
function getNewReservesDataAfterYTrade(order) {
|
|
99
101
|
const { shares, isBuy, price, marketTime } = order;
|
|
100
102
|
const { x: xReserve, y: yReserve } = getReservesFromPrice(price, marketTime);
|
|
101
103
|
if (isBuy && shares >= yReserve) throw new Error("Insufficient Y Liquidity.");
|
|
@@ -132,9 +134,9 @@ function getNewReservesDataForXAfterYTrade(order) {
|
|
|
132
134
|
return afterTrade;
|
|
133
135
|
}
|
|
134
136
|
|
|
135
|
-
// src/amm-math/get-new-reserves-
|
|
137
|
+
// src/amm-math/get-new-reserves-after-y-trade.ts
|
|
136
138
|
import bisect2 from "bisect";
|
|
137
|
-
function
|
|
139
|
+
function getNewReservesDataAfterXTrade(order) {
|
|
138
140
|
const { shares, isBuy, price, marketTime } = order;
|
|
139
141
|
const { x: xReserve, y: yReserve } = getReservesFromPrice(price, marketTime);
|
|
140
142
|
if (isBuy && shares >= xReserve) throw new Error("Insufficient X Liquidity.");
|
|
@@ -173,9 +175,13 @@ function getNewReservesDataForYAfterXTrade(order) {
|
|
|
173
175
|
|
|
174
176
|
// src/index.ts
|
|
175
177
|
var pmAmm = {
|
|
178
|
+
LIQUIDITY_FACTOR,
|
|
179
|
+
PRICE_DECIMALS,
|
|
180
|
+
STARTING_PRICE,
|
|
181
|
+
TIME_FACTOR,
|
|
176
182
|
getEffectiveLiquidity,
|
|
177
|
-
|
|
178
|
-
|
|
183
|
+
getNewReservesDataAfterYTrade,
|
|
184
|
+
getNewReservesDataAfterXTrade,
|
|
179
185
|
getPriceFromReseves,
|
|
180
186
|
getReservesFromPrice
|
|
181
187
|
};
|
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-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"]}
|
|
1
|
+
{"version":3,"sources":["../src/constants.ts","../src/amm-math/get-effective-liquidity.ts","../src/amm-math/gaussian.ts","../src/amm-math/get-price-from-reserves.ts","../src/utils/get-new-price-data.ts","../src/amm-math/invariant.ts","../src/amm-math/get-min-and-max-xy-reserves.ts","../src/amm-math/get-reserves-from-price.ts","../src/amm-math/get-new-reserves-after-x-trade.ts","../src/amm-math/get-new-reserves-after-y-trade.ts","../src/index.ts"],"sourcesContent":["// Staring price of both sides of the market.\nexport const STARTING_PRICE = 0.5\n// This, while not needed for this package, because JS operates\n// with floating point numbers, is needed to establish the point\n// of the current price of either sides of the market as having\n// 6 decimals on the contract interface.\nexport const PRICE_DECIMALS = 6\n// This is tentative, anyone can use any liquidity factor. This,\n// just like `PRICE_DECIMALS` establish the fact that we're using\n// a 100 point liquidity factor on the contract interface.\nexport const LIQUIDITY_FACTOR = 100\n// JS deals with time in milliseconds, when recreating with Solidity,\n// multiply LF with 1,000 too even though time will not need milliseconds.\n// Concurrency.\n// Solidity computes regarding times will be operated on the normal seconds level.\nexport const TIME_FACTOR = 1000","import { LIQUIDITY_FACTOR } from \"../constants\";\nimport { MarketTime } from \"../types/market-time\";\n\n// Returns effective liquidity from liquidity factor.\n//\n// Leff = L(√(T - t))\n// Where T = End time, market closing time and t = current time.\nexport function getEffectiveLiquidity({ currentTime, endTime }: MarketTime): number {\n return LIQUIDITY_FACTOR * Math.sqrt(endTime - currentTime)\n}","import gaussian from \"gaussian\"\n\nconst distribution = gaussian(0, 1)\n\n// CDF, Cumulative Distribution Function.\nexport function Phi(x: number): number {\n return distribution.cdf(x)\n}\n\n// PDF, Probability Density Function.\nexport function phi(x: number): number {\n return distribution.pdf(x)\n}\n\n// PPF or 1/CDF.\nexport function Phi_inverse(x: number): number {\n return distribution.ppf(x)\n}","import { Reserves } from \"../types/ reserves\"\nimport { MarketTime } from \"../types/market-time\"\nimport { Phi } from \"./gaussian\"\nimport { getEffectiveLiquidity } from \"./get-effective-liquidity\"\n\nexport function getPriceFromReseves({ x, y }: Reserves, marketTime: MarketTime): number {\n const effectiveL = getEffectiveLiquidity(marketTime)\n\n const z = (y - x) / effectiveL\n const price = Phi(z)\n\n return price\n}","import { getPriceFromReseves } from \"../amm-math/get-price-from-reserves\";\nimport { PRICE_DECIMALS } from \"../constants\";\nimport { Reserves } from \"../types/ reserves\";\nimport { AfterTrade } from \"../types/after-trade\";\nimport { MarketTime } from \"../types/market-time\";\n\nexport function getNewPriceCostAverageCost(\n newReserves: Reserves,\n marketTime: MarketTime,\n oldPrice: number,\n shares: number\n): Omit<AfterTrade, \"oldXReserve\" | \"oldYReserve\" | \"oldPrice\" | \"newXReserve\" | \"newYReserve\"> {\n const newPrice = getPriceFromReseves(newReserves, marketTime)\n const cost = parseFloat((((oldPrice + newPrice) / 2) * shares).toFixed(PRICE_DECIMALS))\n const averageCost = parseFloat((cost / shares).toFixed(PRICE_DECIMALS))\n\n const afterTrade = {\n newPrice,\n cost,\n averageCost\n }\n\n return afterTrade\n}","import { phi, Phi } from \"./gaussian\";\n\n// For a given x, y and Leff, this invariant must be equal or infinitesimally\n// close to 0.\n// Refer to https://www.paradigm.xyz/2024/11/pm-amm#90ef7fa55727.\nexport function invariant(x: number, y: number, Leff: number): number {\n const z = (y - x) / Leff\n\n return ((y - x) * Phi(z)) + (Leff * phi(z)) - y\n}","import { Limits } from \"../types/limits\"\nimport { MarketTime } from \"../types/market-time\"\nimport { getEffectiveLiquidity } from \"./get-effective-liquidity\"\nimport { invariant } from \"./invariant\"\n\n// Each of these two functions solve to determine the range of values\n// for y and x (yLimit and xLimit) respectively that needs to be approached\n// so that the function given at `invariant` will be equal or close to 0.\n// The whole point of these functions is that it narrows down two limits\n// `min` and `max` for both x and y. `min` is always lesser than `max`, by\n// inference, and applying `min` in the invariant yields a positive number \n// close to 0, say +0.04. `max` when applied to the invariant yields a \n// negative number close to 0, say -0.02. By establishing and using these\n// limits, it's easier for the Bisection function to find a middle ground\n// to pick which number between `min` an `max` yields the closest to 0 (on the\n// negative). That is the number we're looking for.\n//\n// As the limits of either go down, the inviariant positively expands, and it\n// negatively expands as the limits go up.\nexport function getMinAndMaxYReservesForNewXReserve(\n currentYReserve: number,\n newXReserve: number,\n marketTime: MarketTime\n): Limits {\n let minYReserve, maxYReserve\n let minYEvaluation = false, maxYEvaluation = false\n let margin = 5000\n const leff = getEffectiveLiquidity(marketTime)\n\n // Finding the upper limits.\n // We keep adding 10,000 until the invariant\n // results in below 0.\n while (!maxYEvaluation) {\n maxYEvaluation = invariant(newXReserve, currentYReserve, leff) < 0\n currentYReserve += margin\n }\n\n maxYReserve = currentYReserve\n\n // Finding the lower limits.\n // We keep adding 10,000 until the invariant\n // results in above 0.\n while (!minYEvaluation) {\n currentYReserve -= margin\n minYEvaluation = invariant(newXReserve, currentYReserve, leff) > 0\n }\n\n minYReserve = currentYReserve\n\n return { min: minYReserve, max: maxYReserve }\n}\n\nexport function getMinAndMaxXReservesForNewYReserve(\n currentXReserve: number,\n newYReserve: number,\n marketTime: MarketTime\n): Limits {\n let minXReserve, maxXReserve\n let minXEvaluation = false, maxXEvaluation = false\n let margin = 5000\n const leff = getEffectiveLiquidity(marketTime)\n\n // Finding the upper limits.\n // We keep adding 10,000 until the invariant\n // results in below 0.\n while (!maxXEvaluation) {\n maxXEvaluation = invariant(currentXReserve, newYReserve, leff) < 0\n currentXReserve += margin\n }\n\n maxXReserve = currentXReserve\n\n // Finding the lower limits.\n // We keep adding 10,000 until the invariant\n // results in above 0.\n while (!minXEvaluation) {\n currentXReserve -= margin\n minXEvaluation = invariant(currentXReserve, newYReserve, leff) > 0\n }\n\n minXReserve = currentXReserve\n\n return { min: minXReserve, max: maxXReserve }\n}","import { Reserves } from \"../types/ reserves\"\nimport { MarketTime } from \"../types/market-time\"\nimport { phi, Phi_inverse } from \"./gaussian\"\nimport { getEffectiveLiquidity } from \"./get-effective-liquidity\"\n\nexport function getReservesFromPrice(price: number, marketTime: MarketTime): Reserves {\n const effectiveL = getEffectiveLiquidity(marketTime)\n const z = Phi_inverse(price)\n const diff = (z) * effectiveL\n\n const y = (diff * price) + (effectiveL * phi(z))\n const x = y - diff\n\n return { x, y }\n}","import { AfterTrade } from \"../types/after-trade\"\nimport { Order } from \"../types/order\"\nimport { getNewPriceCostAverageCost } from \"../utils/get-new-price-data\"\nimport { getEffectiveLiquidity } from \"./get-effective-liquidity\"\nimport { getMinAndMaxXReservesForNewYReserve } from \"./get-min-and-max-xy-reserves\"\nimport { getReservesFromPrice } from \"./get-reserves-from-price\"\nimport { invariant } from \"./invariant\"\nimport bisect from \"bisect\"\n\nexport function getNewReservesDataAfterYTrade(order: Order): AfterTrade {\n const { shares, isBuy, price, marketTime } = order\n const { x: xReserve, y: yReserve } = getReservesFromPrice(price, marketTime)\n\n if (isBuy && shares >= yReserve) throw new Error(\"Insufficient Y Liquidity.\")\n\n const leff = getEffectiveLiquidity(marketTime)\n const newYReserve = isBuy ? yReserve - shares : yReserve + shares\n\n function evaluateX(x: number) {\n return invariant(x, newYReserve, leff) < 0\n }\n\n const currentXReserve = xReserve\n const { min, max } = getMinAndMaxXReservesForNewYReserve(\n currentXReserve,\n newYReserve,\n marketTime\n )\n const newXReserve = bisect(evaluateX, min, max)\n\n if (!isBuy && newXReserve <= 0) throw new Error(\"X Liquidity Depleted.\")\n\n const newReserves = { x: newXReserve, y: newYReserve }\n const { newPrice, cost, averageCost } = getNewPriceCostAverageCost(\n newReserves,\n marketTime,\n price,\n shares\n )\n\n const afterTrade = {\n oldXReserve: xReserve,\n oldYReserve: yReserve,\n oldPrice: price,\n newXReserve,\n newYReserve,\n newPrice,\n cost,\n averageCost\n }\n\n return afterTrade\n}","import { AfterTrade } from \"../types/after-trade\"\nimport { Order } from \"../types/order\"\nimport { getNewPriceCostAverageCost } from \"../utils/get-new-price-data\"\nimport { getEffectiveLiquidity } from \"./get-effective-liquidity\"\nimport { getMinAndMaxYReservesForNewXReserve } from \"./get-min-and-max-xy-reserves\"\nimport { getReservesFromPrice } from \"./get-reserves-from-price\"\nimport { invariant } from \"./invariant\"\nimport bisect from \"bisect\"\n\nexport function getNewReservesDataAfterXTrade(order: Order): AfterTrade {\n const { shares, isBuy, price, marketTime } = order\n const { x: xReserve, y: yReserve } = getReservesFromPrice(price, marketTime)\n\n if (isBuy && shares >= xReserve) throw new Error(\"Insufficient X Liquidity.\")\n\n const leff = getEffectiveLiquidity(marketTime)\n const newXReserve = isBuy ? xReserve - shares : xReserve + shares\n\n function evaluateY(y: number) {\n return invariant(newXReserve, y, leff) < 0\n }\n\n const currentYReserve = yReserve\n const { min, max } = getMinAndMaxYReservesForNewXReserve(\n currentYReserve,\n newXReserve,\n marketTime\n )\n const newYReserve = bisect(evaluateY, min, max)\n\n if (!isBuy && newYReserve <= 0) throw new Error(\"Y Liquidity Depleted.\")\n\n const newReserves = { x: newXReserve, y: newYReserve }\n const { newPrice, cost, averageCost } = getNewPriceCostAverageCost(\n newReserves,\n marketTime,\n price,\n shares\n )\n\n const afterTrade = {\n oldXReserve: xReserve,\n oldYReserve: yReserve,\n oldPrice: price,\n newXReserve,\n newYReserve,\n newPrice,\n cost,\n averageCost\n }\n\n return afterTrade\n}","import { getEffectiveLiquidity } from \"./amm-math/get-effective-liquidity\";\nimport { getNewReservesDataAfterYTrade } from \"./amm-math/get-new-reserves-after-x-trade\";\nimport { getNewReservesDataAfterXTrade } from \"./amm-math/get-new-reserves-after-y-trade\";\nimport { getPriceFromReseves } from \"./amm-math/get-price-from-reserves\";\nimport { getReservesFromPrice } from \"./amm-math/get-reserves-from-price\";\nimport { AfterTrade } from \"./types/after-trade\";\nimport { Limits } from \"./types/limits\";\nimport { MarketTime } from \"./types/market-time\";\nimport { Order } from \"./types/order\";\nimport { Reserves } from \"./types/ reserves\";\nimport { LIQUIDITY_FACTOR, PRICE_DECIMALS, STARTING_PRICE, TIME_FACTOR } from \"./constants\";\n\nexport {\n AfterTrade,\n Limits,\n MarketTime,\n Order,\n Reserves\n}\n\nconst pmAmm = {\n LIQUIDITY_FACTOR,\n PRICE_DECIMALS,\n STARTING_PRICE,\n TIME_FACTOR,\n getEffectiveLiquidity,\n getNewReservesDataAfterYTrade,\n getNewReservesDataAfterXTrade,\n getPriceFromReseves,\n getReservesFromPrice,\n}\n\nexport default pmAmm"],"mappings":"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","names":["bisect"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@0xfps/pmamm-js",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.3",
|
|
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",
|