@signals-protocol/v1-sdk 1.0.0
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 +99 -0
- package/dist/clmsr-sdk.d.ts +110 -0
- package/dist/clmsr-sdk.js +980 -0
- package/dist/fees.d.ts +69 -0
- package/dist/fees.js +229 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.js +65 -0
- package/dist/types.d.ts +161 -0
- package/dist/types.js +83 -0
- package/dist/utils/math.d.ts +185 -0
- package/dist/utils/math.js +427 -0
- package/dist/utils/prb-math.d.ts +6 -0
- package/dist/utils/prb-math.js +309 -0
- package/package.json +62 -0
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
import Big from "big.js";
|
|
2
|
+
import { WADAmount, USDCAmount } from "../types";
|
|
3
|
+
/** WAD format constant: 1e18 */
|
|
4
|
+
export declare const WAD: Big.Big;
|
|
5
|
+
/** Scale difference between USDC (6 decimals) and WAD (18 decimals): 1e12 */
|
|
6
|
+
export declare const SCALE_DIFF: Big.Big;
|
|
7
|
+
export declare const HALF_SCALE_DIFF: Big.Big;
|
|
8
|
+
/** USDC precision constant: 1e6 */
|
|
9
|
+
export declare const USDC_PRECISION: Big.Big;
|
|
10
|
+
/** Maximum safe input for exp() function: 133.084... * 1e18 (PRBMath limit) */
|
|
11
|
+
export declare const MAX_EXP_INPUT_WAD: Big.Big;
|
|
12
|
+
/** Maximum number of chunks per transaction */
|
|
13
|
+
export declare const MAX_CHUNKS_PER_TX = 100;
|
|
14
|
+
/** Minimum and maximum factor bounds for segment tree operations */
|
|
15
|
+
export declare const MIN_FACTOR: Big.Big;
|
|
16
|
+
export declare const MAX_FACTOR: Big.Big;
|
|
17
|
+
export declare const HALF_WAD: Big.Big;
|
|
18
|
+
export declare const LN_MAX_FACTOR_WAD: Big.Big;
|
|
19
|
+
export declare const MAX_UINT256: bigint;
|
|
20
|
+
export declare function toBigInt(value: Big, label?: string): bigint;
|
|
21
|
+
export declare function fromBigInt(value: bigint): Big;
|
|
22
|
+
/**
|
|
23
|
+
* Convert 6-decimal USDC amount to 18-decimal WAD format
|
|
24
|
+
* @param amt6 Amount in 6-decimal format
|
|
25
|
+
* @returns Amount in WAD format
|
|
26
|
+
*/
|
|
27
|
+
export declare function toWad(amt6: USDCAmount): WADAmount;
|
|
28
|
+
/**
|
|
29
|
+
* Convert 18-decimal WAD format to 6-decimal USDC amount (truncates)
|
|
30
|
+
* @param amtWad Amount in WAD format
|
|
31
|
+
* @returns Amount in 6-decimal format
|
|
32
|
+
*/
|
|
33
|
+
export declare function fromWad(amtWad: WADAmount): USDCAmount;
|
|
34
|
+
/**
|
|
35
|
+
* Convert 18-decimal WAD format to 6-decimal USDC amount with round-up
|
|
36
|
+
* Always rounds up to ensure minimum 1 micro unit cost
|
|
37
|
+
* @param amtWad Amount in WAD format
|
|
38
|
+
* @returns Amount in 6-decimal format (rounded up)
|
|
39
|
+
*/
|
|
40
|
+
export declare function fromWadRoundUp(amtWad: WADAmount): USDCAmount;
|
|
41
|
+
/**
|
|
42
|
+
* Convert 18-decimal WAD format to 6-decimal USDC amount with nearest rounding (ties up)
|
|
43
|
+
* @param amtWad Amount in WAD format
|
|
44
|
+
* @returns Amount in 6-decimal format (rounded to nearest)
|
|
45
|
+
*/
|
|
46
|
+
export declare function fromWadNearest(amtWad: WADAmount): USDCAmount;
|
|
47
|
+
/**
|
|
48
|
+
* Convert 18-decimal WAD format to 6-decimal USDC amount with nearest rounding
|
|
49
|
+
* but enforce minimum 1 micro unit when the input is non-zero.
|
|
50
|
+
* @param amtWad Amount in WAD format
|
|
51
|
+
* @returns Amount in 6-decimal format (rounded to nearest, minimum 1 if non-zero)
|
|
52
|
+
*/
|
|
53
|
+
export declare function fromWadNearestMin1(amtWad: WADAmount): USDCAmount;
|
|
54
|
+
/**
|
|
55
|
+
* Convert WAD format to regular number (divide by 1e18)
|
|
56
|
+
* @param amtWad Amount in WAD format
|
|
57
|
+
* @returns Regular number
|
|
58
|
+
*/
|
|
59
|
+
export declare function wadToNumber(amtWad: WADAmount): Big;
|
|
60
|
+
/**
|
|
61
|
+
* Format USDC amount to 6 decimal places maximum
|
|
62
|
+
* @param amount USDC amount (in micro USDC)
|
|
63
|
+
* @returns Formatted amount with max 6 decimals
|
|
64
|
+
*/
|
|
65
|
+
export declare function formatUSDC(amount: USDCAmount): USDCAmount;
|
|
66
|
+
/**
|
|
67
|
+
* WAD multiplication: (a * b) / WAD
|
|
68
|
+
* @param a First operand
|
|
69
|
+
* @param b Second operand
|
|
70
|
+
* @returns Product in WAD format
|
|
71
|
+
*/
|
|
72
|
+
export declare function wMul(a: WADAmount, b: WADAmount): WADAmount;
|
|
73
|
+
/**
|
|
74
|
+
* WAD multiplication with nearest rounding (ties up)
|
|
75
|
+
* Mirrors on-chain wMulNearest helper.
|
|
76
|
+
* @param a First operand
|
|
77
|
+
* @param b Second operand
|
|
78
|
+
* @returns Product in WAD format rounded to nearest
|
|
79
|
+
*/
|
|
80
|
+
export declare function wMulNearest(a: WADAmount, b: WADAmount): WADAmount;
|
|
81
|
+
/**
|
|
82
|
+
* WAD division: (a * WAD) / b
|
|
83
|
+
* @param a Dividend
|
|
84
|
+
* @param b Divisor
|
|
85
|
+
* @returns Quotient in WAD format
|
|
86
|
+
*/
|
|
87
|
+
export declare function wDiv(a: WADAmount, b: WADAmount): WADAmount;
|
|
88
|
+
/**
|
|
89
|
+
* WAD division with rounding up: ceil((a * WAD) / b)
|
|
90
|
+
* @param a Dividend
|
|
91
|
+
* @param b Divisor
|
|
92
|
+
* @returns Quotient in WAD format rounded up
|
|
93
|
+
*/
|
|
94
|
+
export declare function wDivUp(a: WADAmount, b: WADAmount): WADAmount;
|
|
95
|
+
/**
|
|
96
|
+
* WAD exponentiation: e^x
|
|
97
|
+
* Uses Taylor series expansion for accurate results
|
|
98
|
+
* @param x Exponent in WAD format
|
|
99
|
+
* @returns e^x in WAD format
|
|
100
|
+
*/
|
|
101
|
+
export declare function wExp(x: WADAmount): WADAmount;
|
|
102
|
+
/**
|
|
103
|
+
* WAD natural logarithm: ln(x)
|
|
104
|
+
* @param x Input in WAD format (must be >= 1.0)
|
|
105
|
+
* @returns ln(x) in WAD format
|
|
106
|
+
*/
|
|
107
|
+
export declare function wLn(x: WADAmount): WADAmount;
|
|
108
|
+
/**
|
|
109
|
+
* WAD square root: √x
|
|
110
|
+
* @param x Input in WAD format
|
|
111
|
+
* @returns √x in WAD format
|
|
112
|
+
*/
|
|
113
|
+
export declare function wSqrt(x: WADAmount): WADAmount;
|
|
114
|
+
/**
|
|
115
|
+
* Sum of exponentials: Σ exp(v_i)
|
|
116
|
+
* @param values Array of values in WAD format
|
|
117
|
+
* @returns Sum of exponentials in WAD format
|
|
118
|
+
*/
|
|
119
|
+
export declare function sumExp(values: WADAmount[]): WADAmount;
|
|
120
|
+
/**
|
|
121
|
+
* Logarithm of sum of exponentials: ln(Σ exp(v_i))
|
|
122
|
+
* Uses numerical stability techniques (subtract max value)
|
|
123
|
+
* @param values Array of values in WAD format
|
|
124
|
+
* @returns ln(Σ exp(v_i)) in WAD format
|
|
125
|
+
*/
|
|
126
|
+
export declare function logSumExp(values: WADAmount[]): WADAmount;
|
|
127
|
+
/**
|
|
128
|
+
* Calculate CLMSR price from exponential values
|
|
129
|
+
* Price = exp(q/α) / Σ exp(q_i/α)
|
|
130
|
+
* @param expValue Pre-computed exp(q/α) value for this tick
|
|
131
|
+
* @param totalSumExp Sum of all exponentials Σ exp(q/α)
|
|
132
|
+
* @returns Normalized price in WAD format
|
|
133
|
+
*/
|
|
134
|
+
export declare function clmsrPrice(expValue: WADAmount, totalSumExp: WADAmount): WADAmount;
|
|
135
|
+
/**
|
|
136
|
+
* Calculate CLMSR cost: α * ln(Σ_after / Σ_before)
|
|
137
|
+
* @param alpha Liquidity parameter α in WAD format
|
|
138
|
+
* @param sumBefore Sum of exponentials before trade
|
|
139
|
+
* @param sumAfter Sum of exponentials after trade
|
|
140
|
+
* @returns Trade cost in WAD format (always positive)
|
|
141
|
+
*/
|
|
142
|
+
export declare function clmsrCost(alpha: WADAmount, sumBefore: WADAmount, sumAfter: WADAmount): WADAmount;
|
|
143
|
+
/**
|
|
144
|
+
* Calculate CLMSR proceeds (for selling): α * ln(Σ_before / Σ_after)
|
|
145
|
+
* @param alpha Liquidity parameter α in WAD format
|
|
146
|
+
* @param sumBefore Sum of exponentials before sell
|
|
147
|
+
* @param sumAfter Sum of exponentials after sell
|
|
148
|
+
* @returns Trade proceeds in WAD format
|
|
149
|
+
*/
|
|
150
|
+
export declare function clmsrProceeds(alpha: WADAmount, sumBefore: WADAmount, sumAfter: WADAmount): WADAmount;
|
|
151
|
+
/**
|
|
152
|
+
* Calculate exp(q/α) with contract-equivalent overflow guard
|
|
153
|
+
* Equivalent to contract's _safeExp function
|
|
154
|
+
* @param q Quantity in WAD format
|
|
155
|
+
* @param alpha Liquidity parameter in WAD format
|
|
156
|
+
* @returns Result of exp(q/α) in WAD format
|
|
157
|
+
*/
|
|
158
|
+
export declare function safeExp(q: WADAmount, alpha: WADAmount): WADAmount;
|
|
159
|
+
export declare function maxSafeChunkQuantity(alpha: WADAmount): WADAmount;
|
|
160
|
+
/**
|
|
161
|
+
* Check if a factor is within safe bounds for segment tree operations
|
|
162
|
+
* @param factor Factor to check
|
|
163
|
+
* @returns true if factor is within bounds
|
|
164
|
+
*/
|
|
165
|
+
export declare function isFactorSafe(factor: WADAmount): boolean;
|
|
166
|
+
/**
|
|
167
|
+
* Create a new Big number from string, number, or Big
|
|
168
|
+
* @param value Input value
|
|
169
|
+
* @returns Big number
|
|
170
|
+
*/
|
|
171
|
+
export declare function toBig(value: string | number | Big): Big;
|
|
172
|
+
/**
|
|
173
|
+
* Create WAD amount from numeric value (multiply by 1e18)
|
|
174
|
+
* Use this for converting regular numbers to WAD format
|
|
175
|
+
* @param value Input value in regular units (e.g., 1.5 USDC)
|
|
176
|
+
* @returns WAD amount (18 decimals)
|
|
177
|
+
*/
|
|
178
|
+
export declare function toWAD(value: string | number): WADAmount;
|
|
179
|
+
/**
|
|
180
|
+
* Create micro-USDC amount from USDC value (multiply by 1e6)
|
|
181
|
+
* Use this for converting user input USDC amounts to SDK format
|
|
182
|
+
* @param value Input value in USDC (e.g., "100" = 100 USDC)
|
|
183
|
+
* @returns USDC amount in 6-decimal format (micro-USDC)
|
|
184
|
+
*/
|
|
185
|
+
export declare function toMicroUSDC(value: string | number): USDCAmount;
|
|
@@ -0,0 +1,427 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.MAX_UINT256 = exports.LN_MAX_FACTOR_WAD = exports.HALF_WAD = exports.MAX_FACTOR = exports.MIN_FACTOR = exports.MAX_CHUNKS_PER_TX = exports.MAX_EXP_INPUT_WAD = exports.USDC_PRECISION = exports.HALF_SCALE_DIFF = exports.SCALE_DIFF = exports.WAD = void 0;
|
|
7
|
+
exports.toBigInt = toBigInt;
|
|
8
|
+
exports.fromBigInt = fromBigInt;
|
|
9
|
+
exports.toWad = toWad;
|
|
10
|
+
exports.fromWad = fromWad;
|
|
11
|
+
exports.fromWadRoundUp = fromWadRoundUp;
|
|
12
|
+
exports.fromWadNearest = fromWadNearest;
|
|
13
|
+
exports.fromWadNearestMin1 = fromWadNearestMin1;
|
|
14
|
+
exports.wadToNumber = wadToNumber;
|
|
15
|
+
exports.formatUSDC = formatUSDC;
|
|
16
|
+
exports.wMul = wMul;
|
|
17
|
+
exports.wMulNearest = wMulNearest;
|
|
18
|
+
exports.wDiv = wDiv;
|
|
19
|
+
exports.wDivUp = wDivUp;
|
|
20
|
+
exports.wExp = wExp;
|
|
21
|
+
exports.wLn = wLn;
|
|
22
|
+
exports.wSqrt = wSqrt;
|
|
23
|
+
exports.sumExp = sumExp;
|
|
24
|
+
exports.logSumExp = logSumExp;
|
|
25
|
+
exports.clmsrPrice = clmsrPrice;
|
|
26
|
+
exports.clmsrCost = clmsrCost;
|
|
27
|
+
exports.clmsrProceeds = clmsrProceeds;
|
|
28
|
+
exports.safeExp = safeExp;
|
|
29
|
+
exports.maxSafeChunkQuantity = maxSafeChunkQuantity;
|
|
30
|
+
exports.isFactorSafe = isFactorSafe;
|
|
31
|
+
exports.toBig = toBig;
|
|
32
|
+
exports.toWAD = toWAD;
|
|
33
|
+
exports.toMicroUSDC = toMicroUSDC;
|
|
34
|
+
const big_js_1 = __importDefault(require("big.js"));
|
|
35
|
+
const types_1 = require("../types");
|
|
36
|
+
const prb_math_1 = require("./prb-math");
|
|
37
|
+
// ============================================================================
|
|
38
|
+
// CONSTANTS
|
|
39
|
+
// ============================================================================
|
|
40
|
+
/** WAD format constant: 1e18 */
|
|
41
|
+
exports.WAD = new big_js_1.default("1e18");
|
|
42
|
+
const WAD_BI = prb_math_1.UUNIT;
|
|
43
|
+
/** Scale difference between USDC (6 decimals) and WAD (18 decimals): 1e12 */
|
|
44
|
+
exports.SCALE_DIFF = new big_js_1.default("1e12");
|
|
45
|
+
exports.HALF_SCALE_DIFF = exports.SCALE_DIFF.div(2);
|
|
46
|
+
const SCALE_DIFF_BI = 1000000000000n;
|
|
47
|
+
const HALF_SCALE_DIFF_BI = SCALE_DIFF_BI / 2n;
|
|
48
|
+
/** USDC precision constant: 1e6 */
|
|
49
|
+
exports.USDC_PRECISION = new big_js_1.default("1000000");
|
|
50
|
+
/** Maximum safe input for exp() function: 133.084... * 1e18 (PRBMath limit) */
|
|
51
|
+
exports.MAX_EXP_INPUT_WAD = new big_js_1.default(prb_math_1.UEXP_MAX_INPUT.toString());
|
|
52
|
+
/** Maximum number of chunks per transaction */
|
|
53
|
+
exports.MAX_CHUNKS_PER_TX = 100;
|
|
54
|
+
/** Minimum and maximum factor bounds for segment tree operations */
|
|
55
|
+
exports.MIN_FACTOR = new big_js_1.default("0.01e18"); // 1%
|
|
56
|
+
exports.MAX_FACTOR = new big_js_1.default("100e18"); // 100x
|
|
57
|
+
exports.HALF_WAD = exports.WAD.div(2);
|
|
58
|
+
const HALF_WAD_BI = WAD_BI / 2n;
|
|
59
|
+
exports.LN_MAX_FACTOR_WAD = new big_js_1.default("4605170185988091368"); // ln(100) * 1e18
|
|
60
|
+
exports.MAX_UINT256 = prb_math_1.MAX_UINT256;
|
|
61
|
+
// Big.js configuration for precision (optimized for performance)
|
|
62
|
+
big_js_1.default.DP = 30; // 30 decimal places for internal calculations (sufficient for CLMSR precision)
|
|
63
|
+
big_js_1.default.RM = big_js_1.default.roundHalfUp; // Round half up
|
|
64
|
+
function toBigIntStrict(value, label) {
|
|
65
|
+
const rounded = value.round(0, big_js_1.default.roundDown);
|
|
66
|
+
if (!rounded.eq(value)) {
|
|
67
|
+
throw new types_1.CalculationError(`${label} must be an integer`);
|
|
68
|
+
}
|
|
69
|
+
return BigInt(rounded.toFixed(0, big_js_1.default.roundDown));
|
|
70
|
+
}
|
|
71
|
+
function toBigInt(value, label = "value") {
|
|
72
|
+
return toBigIntStrict(value, label);
|
|
73
|
+
}
|
|
74
|
+
function fromBigInt(value) {
|
|
75
|
+
return new big_js_1.default(value.toString());
|
|
76
|
+
}
|
|
77
|
+
// ============================================================================
|
|
78
|
+
// SCALING FUNCTIONS
|
|
79
|
+
// ============================================================================
|
|
80
|
+
/**
|
|
81
|
+
* Convert 6-decimal USDC amount to 18-decimal WAD format
|
|
82
|
+
* @param amt6 Amount in 6-decimal format
|
|
83
|
+
* @returns Amount in WAD format
|
|
84
|
+
*/
|
|
85
|
+
function toWad(amt6) {
|
|
86
|
+
return amt6.mul(exports.SCALE_DIFF);
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Convert 18-decimal WAD format to 6-decimal USDC amount (truncates)
|
|
90
|
+
* @param amtWad Amount in WAD format
|
|
91
|
+
* @returns Amount in 6-decimal format
|
|
92
|
+
*/
|
|
93
|
+
function fromWad(amtWad) {
|
|
94
|
+
if (amtWad.eq(0)) {
|
|
95
|
+
return new big_js_1.default(0);
|
|
96
|
+
}
|
|
97
|
+
const amtBI = toBigIntStrict(amtWad, "amtWad");
|
|
98
|
+
return fromBigInt(amtBI / SCALE_DIFF_BI);
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Convert 18-decimal WAD format to 6-decimal USDC amount with round-up
|
|
102
|
+
* Always rounds up to ensure minimum 1 micro unit cost
|
|
103
|
+
* @param amtWad Amount in WAD format
|
|
104
|
+
* @returns Amount in 6-decimal format (rounded up)
|
|
105
|
+
*/
|
|
106
|
+
function fromWadRoundUp(amtWad) {
|
|
107
|
+
if (amtWad.eq(0)) {
|
|
108
|
+
return new big_js_1.default(0);
|
|
109
|
+
}
|
|
110
|
+
const amtBI = toBigIntStrict(amtWad, "amtWad");
|
|
111
|
+
const numerator = amtBI + SCALE_DIFF_BI - 1n;
|
|
112
|
+
return fromBigInt(numerator / SCALE_DIFF_BI);
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Convert 18-decimal WAD format to 6-decimal USDC amount with nearest rounding (ties up)
|
|
116
|
+
* @param amtWad Amount in WAD format
|
|
117
|
+
* @returns Amount in 6-decimal format (rounded to nearest)
|
|
118
|
+
*/
|
|
119
|
+
function fromWadNearest(amtWad) {
|
|
120
|
+
if (amtWad.eq(0)) {
|
|
121
|
+
return new big_js_1.default(0);
|
|
122
|
+
}
|
|
123
|
+
const amtBI = toBigIntStrict(amtWad, "amtWad");
|
|
124
|
+
const shifted = amtBI + HALF_SCALE_DIFF_BI;
|
|
125
|
+
return fromBigInt(shifted / SCALE_DIFF_BI);
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Convert 18-decimal WAD format to 6-decimal USDC amount with nearest rounding
|
|
129
|
+
* but enforce minimum 1 micro unit when the input is non-zero.
|
|
130
|
+
* @param amtWad Amount in WAD format
|
|
131
|
+
* @returns Amount in 6-decimal format (rounded to nearest, minimum 1 if non-zero)
|
|
132
|
+
*/
|
|
133
|
+
function fromWadNearestMin1(amtWad) {
|
|
134
|
+
if (amtWad.eq(0)) {
|
|
135
|
+
return new big_js_1.default(0);
|
|
136
|
+
}
|
|
137
|
+
const rounded = fromWadNearest(amtWad);
|
|
138
|
+
return rounded.eq(0) ? new big_js_1.default(1) : rounded;
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Convert WAD format to regular number (divide by 1e18)
|
|
142
|
+
* @param amtWad Amount in WAD format
|
|
143
|
+
* @returns Regular number
|
|
144
|
+
*/
|
|
145
|
+
function wadToNumber(amtWad) {
|
|
146
|
+
return amtWad.div(exports.WAD);
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Format USDC amount to 6 decimal places maximum
|
|
150
|
+
* @param amount USDC amount (in micro USDC)
|
|
151
|
+
* @returns Formatted amount with max 6 decimals
|
|
152
|
+
*/
|
|
153
|
+
function formatUSDC(amount) {
|
|
154
|
+
// amount는 이미 micro USDC 단위이므로 정수여야 함
|
|
155
|
+
return new big_js_1.default(amount.toFixed(0, big_js_1.default.roundDown));
|
|
156
|
+
}
|
|
157
|
+
// ============================================================================
|
|
158
|
+
// BASIC MATH OPERATIONS
|
|
159
|
+
// ============================================================================
|
|
160
|
+
/**
|
|
161
|
+
* WAD multiplication: (a * b) / WAD
|
|
162
|
+
* @param a First operand
|
|
163
|
+
* @param b Second operand
|
|
164
|
+
* @returns Product in WAD format
|
|
165
|
+
*/
|
|
166
|
+
function wMul(a, b) {
|
|
167
|
+
const aBI = toBigIntStrict(a, "a");
|
|
168
|
+
const bBI = toBigIntStrict(b, "b");
|
|
169
|
+
return fromBigInt((aBI * bBI) / WAD_BI);
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* WAD multiplication with nearest rounding (ties up)
|
|
173
|
+
* Mirrors on-chain wMulNearest helper.
|
|
174
|
+
* @param a First operand
|
|
175
|
+
* @param b Second operand
|
|
176
|
+
* @returns Product in WAD format rounded to nearest
|
|
177
|
+
*/
|
|
178
|
+
function wMulNearest(a, b) {
|
|
179
|
+
if (a.eq(0) || b.eq(0)) {
|
|
180
|
+
return new big_js_1.default(0);
|
|
181
|
+
}
|
|
182
|
+
const aBI = toBigIntStrict(a, "a");
|
|
183
|
+
const bBI = toBigIntStrict(b, "b");
|
|
184
|
+
const product = aBI * bBI;
|
|
185
|
+
return fromBigInt((product + HALF_WAD_BI) / WAD_BI);
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* WAD division: (a * WAD) / b
|
|
189
|
+
* @param a Dividend
|
|
190
|
+
* @param b Divisor
|
|
191
|
+
* @returns Quotient in WAD format
|
|
192
|
+
*/
|
|
193
|
+
function wDiv(a, b) {
|
|
194
|
+
if (b.eq(0)) {
|
|
195
|
+
throw new types_1.ValidationError("Division by zero");
|
|
196
|
+
}
|
|
197
|
+
const aBI = toBigIntStrict(a, "a");
|
|
198
|
+
const bBI = toBigIntStrict(b, "b");
|
|
199
|
+
return fromBigInt((aBI * WAD_BI) / bBI);
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* WAD division with rounding up: ceil((a * WAD) / b)
|
|
203
|
+
* @param a Dividend
|
|
204
|
+
* @param b Divisor
|
|
205
|
+
* @returns Quotient in WAD format rounded up
|
|
206
|
+
*/
|
|
207
|
+
function wDivUp(a, b) {
|
|
208
|
+
if (b.eq(0)) {
|
|
209
|
+
throw new types_1.ValidationError("Division by zero");
|
|
210
|
+
}
|
|
211
|
+
const aBI = toBigIntStrict(a, "a");
|
|
212
|
+
const bBI = toBigIntStrict(b, "b");
|
|
213
|
+
const numerator = aBI * WAD_BI;
|
|
214
|
+
const quotient = numerator / bBI;
|
|
215
|
+
if (numerator % bBI === 0n) {
|
|
216
|
+
return fromBigInt(quotient);
|
|
217
|
+
}
|
|
218
|
+
return fromBigInt(quotient + 1n);
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* WAD exponentiation: e^x
|
|
222
|
+
* Uses Taylor series expansion for accurate results
|
|
223
|
+
* @param x Exponent in WAD format
|
|
224
|
+
* @returns e^x in WAD format
|
|
225
|
+
*/
|
|
226
|
+
function wExp(x) {
|
|
227
|
+
if (x.lt(0)) {
|
|
228
|
+
throw new types_1.ValidationError("Exponent must be non-negative");
|
|
229
|
+
}
|
|
230
|
+
const xBI = toBigIntStrict(x, "x");
|
|
231
|
+
if (xBI > prb_math_1.UEXP_MAX_INPUT) {
|
|
232
|
+
throw new types_1.ValidationError(`Exponent too large: ${x.toString()}, max: ${exports.MAX_EXP_INPUT_WAD.toString()}`);
|
|
233
|
+
}
|
|
234
|
+
return fromBigInt((0, prb_math_1.expWad)(xBI));
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* WAD natural logarithm: ln(x)
|
|
238
|
+
* @param x Input in WAD format (must be >= 1.0)
|
|
239
|
+
* @returns ln(x) in WAD format
|
|
240
|
+
*/
|
|
241
|
+
function wLn(x) {
|
|
242
|
+
const xBI = toBigIntStrict(x, "x");
|
|
243
|
+
if (xBI < WAD_BI) {
|
|
244
|
+
throw new types_1.ValidationError("Logarithm input must be >= 1.0 (WAD)");
|
|
245
|
+
}
|
|
246
|
+
return fromBigInt((0, prb_math_1.lnWad)(xBI));
|
|
247
|
+
}
|
|
248
|
+
/**
|
|
249
|
+
* WAD square root: √x
|
|
250
|
+
* @param x Input in WAD format
|
|
251
|
+
* @returns √x in WAD format
|
|
252
|
+
*/
|
|
253
|
+
function wSqrt(x) {
|
|
254
|
+
if (x.lt(0)) {
|
|
255
|
+
throw new types_1.ValidationError("Square root input must be non-negative");
|
|
256
|
+
}
|
|
257
|
+
// Use Big.js sqrt method
|
|
258
|
+
const xScaled = x.div(exports.WAD);
|
|
259
|
+
const result = xScaled.sqrt();
|
|
260
|
+
return result.mul(exports.WAD);
|
|
261
|
+
}
|
|
262
|
+
// ============================================================================
|
|
263
|
+
// AGGREGATION FUNCTIONS
|
|
264
|
+
// ============================================================================
|
|
265
|
+
/**
|
|
266
|
+
* Sum of exponentials: Σ exp(v_i)
|
|
267
|
+
* @param values Array of values in WAD format
|
|
268
|
+
* @returns Sum of exponentials in WAD format
|
|
269
|
+
*/
|
|
270
|
+
function sumExp(values) {
|
|
271
|
+
if (values.length === 0) {
|
|
272
|
+
throw new types_1.ValidationError("Empty array provided to sumExp");
|
|
273
|
+
}
|
|
274
|
+
let sum = new big_js_1.default(0);
|
|
275
|
+
for (const v of values) {
|
|
276
|
+
const expV = wExp(v);
|
|
277
|
+
sum = sum.plus(expV);
|
|
278
|
+
}
|
|
279
|
+
return sum;
|
|
280
|
+
}
|
|
281
|
+
/**
|
|
282
|
+
* Logarithm of sum of exponentials: ln(Σ exp(v_i))
|
|
283
|
+
* Uses numerical stability techniques (subtract max value)
|
|
284
|
+
* @param values Array of values in WAD format
|
|
285
|
+
* @returns ln(Σ exp(v_i)) in WAD format
|
|
286
|
+
*/
|
|
287
|
+
function logSumExp(values) {
|
|
288
|
+
if (values.length === 0) {
|
|
289
|
+
throw new types_1.ValidationError("Empty array provided to logSumExp");
|
|
290
|
+
}
|
|
291
|
+
// Find maximum value for numerical stability
|
|
292
|
+
let maxVal = values[0];
|
|
293
|
+
for (let i = 1; i < values.length; i++) {
|
|
294
|
+
if (values[i].gt(maxVal)) {
|
|
295
|
+
maxVal = values[i];
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
// Calculate sum of exp(x - max) with proper scaling
|
|
299
|
+
let sumScaled = new big_js_1.default(0);
|
|
300
|
+
for (const v of values) {
|
|
301
|
+
// Safe subtraction to avoid underflow
|
|
302
|
+
const diff = v.gte(maxVal) ? v.minus(maxVal) : new big_js_1.default(0);
|
|
303
|
+
const eScaled = wExp(diff);
|
|
304
|
+
sumScaled = sumScaled.plus(eScaled);
|
|
305
|
+
}
|
|
306
|
+
if (sumScaled.eq(0)) {
|
|
307
|
+
throw new types_1.CalculationError("Sum scaled to zero in logSumExp");
|
|
308
|
+
}
|
|
309
|
+
return maxVal.plus(wLn(sumScaled));
|
|
310
|
+
}
|
|
311
|
+
// ============================================================================
|
|
312
|
+
// CLMSR-SPECIFIC FUNCTIONS
|
|
313
|
+
// ============================================================================
|
|
314
|
+
/**
|
|
315
|
+
* Calculate CLMSR price from exponential values
|
|
316
|
+
* Price = exp(q/α) / Σ exp(q_i/α)
|
|
317
|
+
* @param expValue Pre-computed exp(q/α) value for this tick
|
|
318
|
+
* @param totalSumExp Sum of all exponentials Σ exp(q/α)
|
|
319
|
+
* @returns Normalized price in WAD format
|
|
320
|
+
*/
|
|
321
|
+
function clmsrPrice(expValue, totalSumExp) {
|
|
322
|
+
if (totalSumExp.eq(0)) {
|
|
323
|
+
throw new types_1.ValidationError("Total sum of exponentials is zero");
|
|
324
|
+
}
|
|
325
|
+
return wDiv(expValue, totalSumExp);
|
|
326
|
+
}
|
|
327
|
+
/**
|
|
328
|
+
* Calculate CLMSR cost: α * ln(Σ_after / Σ_before)
|
|
329
|
+
* @param alpha Liquidity parameter α in WAD format
|
|
330
|
+
* @param sumBefore Sum of exponentials before trade
|
|
331
|
+
* @param sumAfter Sum of exponentials after trade
|
|
332
|
+
* @returns Trade cost in WAD format (always positive)
|
|
333
|
+
*/
|
|
334
|
+
function clmsrCost(alpha, sumBefore, sumAfter) {
|
|
335
|
+
if (sumBefore.eq(0)) {
|
|
336
|
+
throw new types_1.ValidationError("Sum before trade is zero");
|
|
337
|
+
}
|
|
338
|
+
const ratio = wDiv(sumAfter, sumBefore);
|
|
339
|
+
if (ratio.lt(exports.WAD)) {
|
|
340
|
+
throw new types_1.ValidationError("Ratio < 1 not supported in unsigned version");
|
|
341
|
+
}
|
|
342
|
+
const lnRatio = wLn(ratio);
|
|
343
|
+
return wMul(alpha, lnRatio);
|
|
344
|
+
}
|
|
345
|
+
/**
|
|
346
|
+
* Calculate CLMSR proceeds (for selling): α * ln(Σ_before / Σ_after)
|
|
347
|
+
* @param alpha Liquidity parameter α in WAD format
|
|
348
|
+
* @param sumBefore Sum of exponentials before sell
|
|
349
|
+
* @param sumAfter Sum of exponentials after sell
|
|
350
|
+
* @returns Trade proceeds in WAD format
|
|
351
|
+
*/
|
|
352
|
+
function clmsrProceeds(alpha, sumBefore, sumAfter) {
|
|
353
|
+
if (sumBefore.eq(0) || sumAfter.eq(0)) {
|
|
354
|
+
throw new types_1.ValidationError("Sum before or after trade is zero");
|
|
355
|
+
}
|
|
356
|
+
if (sumBefore.lte(sumAfter)) {
|
|
357
|
+
return new big_js_1.default(0); // No proceeds if sum doesn't decrease
|
|
358
|
+
}
|
|
359
|
+
const ratio = wDiv(sumBefore, sumAfter);
|
|
360
|
+
const lnRatio = wLn(ratio);
|
|
361
|
+
return wMul(alpha, lnRatio);
|
|
362
|
+
}
|
|
363
|
+
// ============================================================================
|
|
364
|
+
// SAFE EXPONENTIAL WITH CHUNKING
|
|
365
|
+
// ============================================================================
|
|
366
|
+
/**
|
|
367
|
+
* Calculate exp(q/α) with contract-equivalent overflow guard
|
|
368
|
+
* Equivalent to contract's _safeExp function
|
|
369
|
+
* @param q Quantity in WAD format
|
|
370
|
+
* @param alpha Liquidity parameter in WAD format
|
|
371
|
+
* @returns Result of exp(q/α) in WAD format
|
|
372
|
+
*/
|
|
373
|
+
function safeExp(q, alpha) {
|
|
374
|
+
if (alpha.eq(0)) {
|
|
375
|
+
throw new types_1.ValidationError("Alpha cannot be zero");
|
|
376
|
+
}
|
|
377
|
+
const input = wDiv(q, alpha);
|
|
378
|
+
if (input.gt(exports.MAX_EXP_INPUT_WAD)) {
|
|
379
|
+
throw new types_1.ValidationError(`Exponent too large: ${input.toString()}, max: ${exports.MAX_EXP_INPUT_WAD.toString()}`);
|
|
380
|
+
}
|
|
381
|
+
return wExp(input);
|
|
382
|
+
}
|
|
383
|
+
function maxSafeChunkQuantity(alpha) {
|
|
384
|
+
if (alpha.eq(0)) {
|
|
385
|
+
return new big_js_1.default(0);
|
|
386
|
+
}
|
|
387
|
+
const treeLimit = wMul(alpha, exports.LN_MAX_FACTOR_WAD);
|
|
388
|
+
const expLimit = wMul(alpha, exports.MAX_EXP_INPUT_WAD);
|
|
389
|
+
return treeLimit.lt(expLimit) ? treeLimit : expLimit;
|
|
390
|
+
}
|
|
391
|
+
// ============================================================================
|
|
392
|
+
// UTILITY FUNCTIONS
|
|
393
|
+
// ============================================================================
|
|
394
|
+
/**
|
|
395
|
+
* Check if a factor is within safe bounds for segment tree operations
|
|
396
|
+
* @param factor Factor to check
|
|
397
|
+
* @returns true if factor is within bounds
|
|
398
|
+
*/
|
|
399
|
+
function isFactorSafe(factor) {
|
|
400
|
+
return factor.gte(exports.MIN_FACTOR) && factor.lte(exports.MAX_FACTOR);
|
|
401
|
+
}
|
|
402
|
+
/**
|
|
403
|
+
* Create a new Big number from string, number, or Big
|
|
404
|
+
* @param value Input value
|
|
405
|
+
* @returns Big number
|
|
406
|
+
*/
|
|
407
|
+
function toBig(value) {
|
|
408
|
+
return new big_js_1.default(value);
|
|
409
|
+
}
|
|
410
|
+
/**
|
|
411
|
+
* Create WAD amount from numeric value (multiply by 1e18)
|
|
412
|
+
* Use this for converting regular numbers to WAD format
|
|
413
|
+
* @param value Input value in regular units (e.g., 1.5 USDC)
|
|
414
|
+
* @returns WAD amount (18 decimals)
|
|
415
|
+
*/
|
|
416
|
+
function toWAD(value) {
|
|
417
|
+
return new big_js_1.default(value).mul(exports.WAD);
|
|
418
|
+
}
|
|
419
|
+
/**
|
|
420
|
+
* Create micro-USDC amount from USDC value (multiply by 1e6)
|
|
421
|
+
* Use this for converting user input USDC amounts to SDK format
|
|
422
|
+
* @param value Input value in USDC (e.g., "100" = 100 USDC)
|
|
423
|
+
* @returns USDC amount in 6-decimal format (micro-USDC)
|
|
424
|
+
*/
|
|
425
|
+
function toMicroUSDC(value) {
|
|
426
|
+
return new big_js_1.default(value).mul(exports.USDC_PRECISION);
|
|
427
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
declare const UUNIT = 1000000000000000000n;
|
|
2
|
+
declare const UEXP_MAX_INPUT = 133084258667509499440n;
|
|
3
|
+
declare const MAX_UINT256: bigint;
|
|
4
|
+
declare function ln(x: bigint): bigint;
|
|
5
|
+
declare function exp(x: bigint): bigint;
|
|
6
|
+
export { exp as expWad, ln as lnWad, UEXP_MAX_INPUT, UUNIT, MAX_UINT256 };
|