@reyaxyz/common 0.332.0 → 0.333.2
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 +1 -1
- package/dist/commands/exposure/command.js +6 -0
- package/dist/commands/exposure/command.js.map +1 -1
- package/dist/trading-api-types.js.map +1 -1
- package/dist/types/commands/exposure/command.d.ts +6 -0
- package/dist/types/commands/exposure/command.d.ts.map +1 -1
- package/dist/types/trading-api-types.d.ts +6 -0
- package/dist/types/trading-api-types.d.ts.map +1 -1
- package/dist/types/utils/calculate.d.ts +39 -6
- package/dist/types/utils/calculate.d.ts.map +1 -1
- package/dist/types/utils/token/token-info.d.ts.map +1 -1
- package/dist/utils/calculate.js +85 -8
- package/dist/utils/calculate.js.map +1 -1
- package/dist/utils/token/token-info.js +9 -1
- package/dist/utils/token/token-info.js.map +1 -1
- package/package.json +2 -2
- package/src/commands/exposure/command.ts +6 -0
- package/src/trading-api-types.ts +6 -0
- package/src/utils/calculate.ts +122 -17
- package/src/utils/token/token-info.ts +3 -1
package/src/utils/calculate.ts
CHANGED
|
@@ -63,31 +63,136 @@ export const calculateMaxExposure = ({
|
|
|
63
63
|
riskFactor: number;
|
|
64
64
|
}) => poolBalance / (poolIMR * Math.sqrt(riskFactor));
|
|
65
65
|
|
|
66
|
+
/**
|
|
67
|
+
* Splits a trade exposure into rebalancing and unbalancing portions relative to pool net exposure.
|
|
68
|
+
* Rebalancing reduces pool's absolute exposure; unbalancing increases it.
|
|
69
|
+
*/
|
|
70
|
+
export const splitTradeExposure = (
|
|
71
|
+
tradeExposure: number,
|
|
72
|
+
poolNetExposure: number,
|
|
73
|
+
): { rebalancing: number; unbalancing: number } => {
|
|
74
|
+
if (tradeExposure === 0) {
|
|
75
|
+
return { rebalancing: 0, unbalancing: 0 };
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// If pool has no exposure, entire trade is unbalancing
|
|
79
|
+
if (poolNetExposure === 0) {
|
|
80
|
+
return { rebalancing: 0, unbalancing: tradeExposure };
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// Opposite sign means trade increases pool exposure → pure unbalancing
|
|
84
|
+
const sameSign =
|
|
85
|
+
(poolNetExposure > 0 && tradeExposure > 0) ||
|
|
86
|
+
(poolNetExposure < 0 && tradeExposure < 0);
|
|
87
|
+
if (!sameSign) {
|
|
88
|
+
return { rebalancing: 0, unbalancing: tradeExposure };
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// Same sign: trade reduces pool exposure (pool takes opposite side)
|
|
92
|
+
const absPool = Math.abs(poolNetExposure);
|
|
93
|
+
const absTrade = Math.abs(tradeExposure);
|
|
94
|
+
|
|
95
|
+
if (absTrade <= absPool) {
|
|
96
|
+
// Pure rebalancing — trade doesn't cross zero
|
|
97
|
+
return { rebalancing: tradeExposure, unbalancing: 0 };
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// Mixed: rebalance up to pool exposure, then unbalance the rest
|
|
101
|
+
const rebalancing = poolNetExposure;
|
|
102
|
+
const unbalancing = tradeExposure - rebalancing;
|
|
103
|
+
return { rebalancing, unbalancing };
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Computes the new log price multiplier (logF) after a trade, handling both
|
|
108
|
+
* rebalancing and unbalancing portions.
|
|
109
|
+
*
|
|
110
|
+
* Mirrors on-chain logic in PriceMultiplier.sol:computeNewLogPriceMultiplier.
|
|
111
|
+
*/
|
|
112
|
+
export const computeNewLogF = ({
|
|
113
|
+
currentLogF,
|
|
114
|
+
tradeExposure,
|
|
115
|
+
poolNetExposure,
|
|
116
|
+
depthFactor,
|
|
117
|
+
maxExposure,
|
|
118
|
+
}: {
|
|
119
|
+
currentLogF: number;
|
|
120
|
+
tradeExposure: number;
|
|
121
|
+
poolNetExposure: number;
|
|
122
|
+
depthFactor: number;
|
|
123
|
+
maxExposure: number;
|
|
124
|
+
}): number => {
|
|
125
|
+
if (tradeExposure === 0) return currentLogF;
|
|
126
|
+
|
|
127
|
+
const { rebalancing, unbalancing } = splitTradeExposure(
|
|
128
|
+
tradeExposure,
|
|
129
|
+
poolNetExposure,
|
|
130
|
+
);
|
|
131
|
+
|
|
132
|
+
// Case 1: Has unbalancing portion (includes mixed trades)
|
|
133
|
+
if (unbalancing !== 0) {
|
|
134
|
+
// If also rebalancing, it brings logF to 0 by definition (trade crosses zero)
|
|
135
|
+
const startLogF = rebalancing === 0 ? currentLogF : 0;
|
|
136
|
+
return startLogF + unbalancing / (depthFactor * maxExposure);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// Case 2: Only rebalancing
|
|
140
|
+
// Both rebalancing and poolNetExposure have the same sign, so ratio is in [0, 1]
|
|
141
|
+
if (rebalancing !== 0 && poolNetExposure !== 0) {
|
|
142
|
+
const ratio = rebalancing / poolNetExposure;
|
|
143
|
+
return currentLogF * (1 - ratio);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
return currentLogF;
|
|
147
|
+
};
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Estimates the execution price for a trade using the exponential logPriceMultiplier formula.
|
|
151
|
+
*
|
|
152
|
+
* Mirrors on-chain logic:
|
|
153
|
+
* 1. computeNewLogPriceMultiplier (PriceMultiplier.sol)
|
|
154
|
+
* 2. computeAmmPrice: ammPrice = oraclePrice * exp(logF)
|
|
155
|
+
* 3. computeSignedSpread: executionPrice = ammPrice * (1 + signedSpread)
|
|
156
|
+
*
|
|
157
|
+
* @audit spreadDiscount not applied — known limitation, to be addressed later
|
|
158
|
+
* @audit priceSpacing rounding not applied
|
|
159
|
+
*/
|
|
66
160
|
export const calculateEstimatedExecutionPrice = ({
|
|
67
|
-
poolPrice,
|
|
68
161
|
oraclePrice,
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
162
|
+
currentLogF,
|
|
163
|
+
tradeExposure,
|
|
164
|
+
poolNetExposure,
|
|
165
|
+
depthFactor,
|
|
166
|
+
maxExposure,
|
|
167
|
+
priceSpread,
|
|
73
168
|
}: {
|
|
74
|
-
poolPrice: number;
|
|
75
169
|
oraclePrice: number;
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
170
|
+
currentLogF: number;
|
|
171
|
+
tradeExposure: number;
|
|
172
|
+
poolNetExposure: number;
|
|
173
|
+
depthFactor: number;
|
|
174
|
+
maxExposure: number;
|
|
175
|
+
priceSpread: number;
|
|
80
176
|
}): number => {
|
|
81
|
-
if (
|
|
82
|
-
return
|
|
177
|
+
if (tradeExposure === 0) {
|
|
178
|
+
return oraclePrice * Math.exp(currentLogF);
|
|
83
179
|
}
|
|
84
180
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
181
|
+
// 1. Compute new logF after trade impact
|
|
182
|
+
const newLogF = computeNewLogF({
|
|
183
|
+
currentLogF,
|
|
184
|
+
tradeExposure,
|
|
185
|
+
poolNetExposure,
|
|
186
|
+
depthFactor,
|
|
187
|
+
maxExposure,
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
// 2. Compute AMM price: oraclePrice * exp(newLogF)
|
|
191
|
+
const ammPrice = oraclePrice * Math.exp(newLogF);
|
|
89
192
|
|
|
90
|
-
|
|
193
|
+
// 3. Apply signed spread
|
|
194
|
+
const signedSpread = tradeExposure > 0 ? priceSpread : -priceSpread;
|
|
195
|
+
return Math.max(0, ammPrice * (1 + signedSpread));
|
|
91
196
|
};
|
|
92
197
|
|
|
93
198
|
export const calculateTradeFee = ({
|
|
@@ -122,7 +122,9 @@ export const TOKEN_INFO: Record<ReyaChainId | MoneyInOutChainId, TokenInfo[]> =
|
|
|
122
122
|
address: '0xa6cf523f856f4a0aab78848e251c1b042e6406d5',
|
|
123
123
|
decimals: 8,
|
|
124
124
|
isRUSDUnderlying: false,
|
|
125
|
-
|
|
125
|
+
minDepositAmount: 0.0001,
|
|
126
|
+
minWithdrawAmount: 0.0001,
|
|
127
|
+
minTransferAmount: 0.0001,
|
|
126
128
|
},
|
|
127
129
|
],
|
|
128
130
|
[MoneyInOutChainId.ethereumMainnet]: [
|