@reserve-protocol/dtf-rebalance-lib 0.2.17 → 0.3.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/dist/open-auction.d.ts +1 -1
- package/dist/open-auction.js +26 -15
- package/dist/start-rebalance.js +4 -7
- package/package.json +1 -1
package/dist/open-auction.d.ts
CHANGED
@@ -45,7 +45,7 @@ export interface OpenAuctionArgs {
|
|
45
45
|
* @param _prices {USD/wholeTok} either CURRENT or HISTORICAL prices
|
46
46
|
* @returns D18{1} The target basket
|
47
47
|
*/
|
48
|
-
export declare const getTargetBasket: (_initialWeights: WeightRange[], _prices: number[], _decimals: bigint[]) => bigint[];
|
48
|
+
export declare const getTargetBasket: (_initialWeights: WeightRange[], _prices: number[], _decimals: bigint[], debug?: boolean) => bigint[];
|
49
49
|
/**
|
50
50
|
* Get the values needed to call `folio.openAuction()` as the AUCTION_LAUNCHER
|
51
51
|
*
|
package/dist/open-auction.js
CHANGED
@@ -22,8 +22,13 @@ var AuctionRound;
|
|
22
22
|
* @param _prices {USD/wholeTok} either CURRENT or HISTORICAL prices
|
23
23
|
* @returns D18{1} The target basket
|
24
24
|
*/
|
25
|
-
const getTargetBasket = (_initialWeights, _prices, _decimals) => {
|
26
|
-
|
25
|
+
const getTargetBasket = (_initialWeights, _prices, _decimals, debug) => {
|
26
|
+
if (debug === undefined) {
|
27
|
+
debug = true;
|
28
|
+
}
|
29
|
+
if (debug) {
|
30
|
+
console.log("getTargetBasket", _initialWeights, _prices, _decimals);
|
31
|
+
}
|
27
32
|
if (_initialWeights.length != _prices.length) {
|
28
33
|
throw new Error("length mismatch");
|
29
34
|
}
|
@@ -79,7 +84,7 @@ const getOpenAuction = (rebalance, _supply, _initialFolio = [], _targetBasket =
|
|
79
84
|
// {1} = D18{1} / D18
|
80
85
|
const targetBasket = _targetBasket.map((a) => new utils_1.Decimal(a.toString()).div(numbers_1.D18d));
|
81
86
|
// {USD/wholeTok}
|
82
|
-
const prices = _prices.map((a) => new utils_1.Decimal(a));
|
87
|
+
const prices = _prices.map((a) => new utils_1.Decimal(a.toString()));
|
83
88
|
for (let i = 0; i < prices.length; i++) {
|
84
89
|
if (prices[i].lte(numbers_1.ZERO)) {
|
85
90
|
throw new Error(`missing price for token ${rebalance.tokens[i]}`);
|
@@ -148,10 +153,14 @@ const getOpenAuction = (rebalance, _supply, _initialFolio = [], _targetBasket =
|
|
148
153
|
.div(shareValue);
|
149
154
|
// ================================================================
|
150
155
|
// calculate progressions
|
156
|
+
// {wholeBU/wholeShare} = {USD/wholeShare} / {USD/wholeBU}
|
157
|
+
const spotLimit = shareValue.div(buValue);
|
151
158
|
// {wholeBU/wholeShare} = D18{BU/share} / D18
|
152
159
|
const prevSpotLimit = new utils_1.Decimal(rebalance.limits.spot.toString()).div(numbers_1.D18d);
|
160
|
+
const maxSpotLimit = spotLimit.gt(prevSpotLimit) ? spotLimit : prevSpotLimit;
|
153
161
|
// {wholeTok/wholeShare} = {wholeTok/wholeBU} * {wholeBU/wholeShare}
|
154
|
-
const expectedBalances = weightRanges.map((weightRange) => weightRange.spot.mul(
|
162
|
+
const expectedBalances = weightRanges.map((weightRange) => weightRange.spot.mul(maxSpotLimit));
|
163
|
+
// absolute scale
|
155
164
|
// {1} = {USD/wholeShare} / {USD/wholeShare}
|
156
165
|
let progression = folio
|
157
166
|
.map((actualBalance, i) => {
|
@@ -165,6 +174,7 @@ const getOpenAuction = (rebalance, _supply, _initialFolio = [], _targetBasket =
|
|
165
174
|
})
|
166
175
|
.reduce((a, b) => a.add(b))
|
167
176
|
.div(shareValue);
|
177
|
+
// absolute scale
|
168
178
|
// {1} = {USD/wholeShare} / {USD/wholeShare}
|
169
179
|
const initialProgression = initialFolio
|
170
180
|
.map((initialBalance, i) => {
|
@@ -188,7 +198,7 @@ const getOpenAuction = (rebalance, _supply, _initialFolio = [], _targetBasket =
|
|
188
198
|
let relativeProgression = initialProgression.eq(numbers_1.ONE)
|
189
199
|
? numbers_1.ONE
|
190
200
|
: progression.sub(initialProgression).div(numbers_1.ONE.sub(initialProgression));
|
191
|
-
let rebalanceTarget = numbers_1.ONE;
|
201
|
+
let rebalanceTarget = numbers_1.ONE; // absolute scale
|
192
202
|
let round = AuctionRound.FINAL;
|
193
203
|
if (debug) {
|
194
204
|
console.log("initialProgression", initialProgression.toString());
|
@@ -209,6 +219,8 @@ const getOpenAuction = (rebalance, _supply, _initialFolio = [], _targetBasket =
|
|
209
219
|
}
|
210
220
|
}
|
211
221
|
// EJECT
|
222
|
+
// TODO maybe increase threshold to nonzero value, taking into account price
|
223
|
+
// currently will get stuck trying to eject tiny dust over and over
|
212
224
|
if (portionBeingEjected.gt(0)) {
|
213
225
|
round = AuctionRound.EJECT;
|
214
226
|
// if the ejections are everything that's left, keep the finalStageAt targeting from above
|
@@ -236,8 +248,6 @@ const getOpenAuction = (rebalance, _supply, _initialFolio = [], _targetBasket =
|
|
236
248
|
const delta = numbers_1.ONE.sub(rebalanceTarget);
|
237
249
|
// ================================================================
|
238
250
|
// get new limits, constrained by extremes
|
239
|
-
// {wholeBU/wholeShare} = {USD/wholeShare} / {USD/wholeBU}
|
240
|
-
const spotLimit = shareValue.div(buValue);
|
241
251
|
// D18{BU/share} = {wholeBU/wholeShare} * D18 * {1}
|
242
252
|
const newLimits = {
|
243
253
|
low: (0, numbers_1.bn)(spotLimit.sub(spotLimit.mul(delta)).mul(numbers_1.D18d)),
|
@@ -287,7 +297,7 @@ const getOpenAuction = (rebalance, _supply, _initialFolio = [], _targetBasket =
|
|
287
297
|
// D27{tok/BU} = {wholeTok/wholeBU} * D27 * {tok/wholeTok} / {BU/wholeBU}
|
288
298
|
const newWeightsD27 = {
|
289
299
|
low: (0, numbers_1.bn)(idealWeight
|
290
|
-
.mul(
|
300
|
+
.mul(numbers_1.ONE.sub(delta).div(actualLimits.low.div(actualLimits.spot))) // add remaining delta into weight
|
291
301
|
.mul(numbers_1.D9d)
|
292
302
|
.mul(decimalScale[i])),
|
293
303
|
spot: (0, numbers_1.bn)(idealWeight.mul(numbers_1.D9d).mul(decimalScale[i])),
|
@@ -325,20 +335,20 @@ const getOpenAuction = (rebalance, _supply, _initialFolio = [], _targetBasket =
|
|
325
335
|
}
|
326
336
|
// ================================================================
|
327
337
|
// get new prices, constrained by extremes
|
328
|
-
// D27{
|
338
|
+
// D27{nanoUSD/tok}
|
329
339
|
const newPrices = rebalance.initialPrices.map((initialPrice, i) => {
|
330
|
-
//
|
331
|
-
const spotPrice = (0, numbers_1.bn)(prices[i].div(decimalScale[i]).mul(numbers_1.D27d));
|
340
|
+
// {nanoUSD/tok} = {USD/wholeTok} * {nanoUSD/USD} / {tok/wholeTok} * D27
|
341
|
+
const spotPrice = (0, numbers_1.bn)(prices[i].mul(numbers_1.D9d).div(decimalScale[i]).mul(numbers_1.D27d));
|
332
342
|
if (spotPrice < initialPrice.low || spotPrice > initialPrice.high) {
|
333
343
|
throw new Error(`spot price ${spotPrice.toString()} out of bounds relative to initial range [${initialPrice.low.toString()}, ${initialPrice.high.toString()}]! auction launcher MUST closeRebalance to prevent loss!`);
|
334
344
|
}
|
335
345
|
if (rebalance.priceControl == types_1.PriceControl.NONE) {
|
336
346
|
return initialPrice;
|
337
347
|
}
|
338
|
-
// D27{
|
348
|
+
// D27{nanoUSD/tok} = {USD/wholeTok} * {nanoUSD/USD} / {tok/wholeTok} * D27
|
339
349
|
const pricesD27 = {
|
340
|
-
low: (0, numbers_1.bn)(prices[i].mul(numbers_1.ONE.sub(priceError[i])).div(decimalScale[i]).mul(numbers_1.D27d)),
|
341
|
-
high: (0, numbers_1.bn)(prices[i].div(numbers_1.ONE.sub(priceError[i])).div(decimalScale[i]).mul(numbers_1.D27d)),
|
350
|
+
low: (0, numbers_1.bn)(prices[i].mul(numbers_1.ONE.sub(priceError[i])).mul(numbers_1.D9d).div(decimalScale[i]).mul(numbers_1.D27d)),
|
351
|
+
high: (0, numbers_1.bn)(prices[i].div(numbers_1.ONE.sub(priceError[i])).mul(numbers_1.D9d).div(decimalScale[i]).mul(numbers_1.D27d)),
|
342
352
|
};
|
343
353
|
// low
|
344
354
|
if (pricesD27.low < initialPrice.low) {
|
@@ -420,7 +430,8 @@ const getOpenAuction = (rebalance, _supply, _initialFolio = [], _targetBasket =
|
|
420
430
|
const returnWeights = [];
|
421
431
|
const returnPrices = [];
|
422
432
|
for (let i = 0; i < rebalance.tokens.length; i++) {
|
423
|
-
if (rebalance.inRebalance[i]
|
433
|
+
if (rebalance.inRebalance[i] &&
|
434
|
+
(surplusTokens.includes(rebalance.tokens[i]) || deficitTokens.includes(rebalance.tokens[i]))) {
|
424
435
|
returnTokens.push(rebalance.tokens[i]);
|
425
436
|
returnWeights.push(newWeights[i]);
|
426
437
|
returnPrices.push(newPrices[i]);
|
package/dist/start-rebalance.js
CHANGED
@@ -84,14 +84,11 @@ const getStartRebalance = (_supply, tokens, _folio, decimals, _targetBasket, _pr
|
|
84
84
|
// === newPrices ===
|
85
85
|
// D27{wholeTok/tok} = D27 / {tok/wholeTok}
|
86
86
|
const priceMultiplier = numbers_1.D27d.div(new utils_1.Decimal(`1e${decimals[i]}`));
|
87
|
-
// {USD/wholeTok} = {USD/wholeTok} * {1}
|
88
|
-
const lowPrice = prices[i].mul(numbers_1.ONE.sub(priceError[i]));
|
89
|
-
// {USD/wholeTok} = {USD/wholeTok} / {1}
|
90
|
-
const highPrice = prices[i].div(numbers_1.ONE.sub(priceError[i]));
|
91
|
-
// D27{USD/tok} = {USD/wholeTok} * D27{wholeTok/tok}
|
92
87
|
newPrices.push({
|
93
|
-
|
94
|
-
|
88
|
+
// D27{nanoUSD/tok} = {USD/wholeTok} * {1} * D27{wholeTok/tok} * {nanoUSD/USD}
|
89
|
+
low: (0, numbers_1.bn)(prices[i].mul(numbers_1.ONE.sub(priceError[i])).mul(priceMultiplier).mul(numbers_1.D9d)),
|
90
|
+
// D27{nanoUSD/tok} = {USD/wholeTok} / {1} * D27{wholeTok/tok} * {nanoUSD/USD}
|
91
|
+
high: (0, numbers_1.bn)(prices[i].div(numbers_1.ONE.sub(priceError[i])).mul(priceMultiplier).mul(numbers_1.D9d)),
|
95
92
|
});
|
96
93
|
}
|
97
94
|
// update low/high for tracking DTFs
|