@reserve-protocol/dtf-rebalance-lib 0.2.4 → 0.2.6

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.
@@ -7,6 +7,7 @@ exports.getOpenAuction = exports.getTargetBasket = exports.AuctionRound = void 0
7
7
  const decimal_js_light_1 = __importDefault(require("decimal.js-light"));
8
8
  const numbers_1 = require("./numbers");
9
9
  const types_1 = require("./types");
10
+ decimal_js_light_1.default.set({ precision: 100 });
10
11
  // Call `getOpenAuction()` to get the current auction round
11
12
  var AuctionRound;
12
13
  (function (AuctionRound) {
@@ -33,7 +34,7 @@ const getTargetBasket = (_initialWeights, _prices, _decimals) => {
33
34
  const price = new decimal_js_light_1.default(_prices[i]);
34
35
  const decimalScale = new decimal_js_light_1.default(`1e${_decimals[i]}`);
35
36
  // {USD/wholeBU} = D27{tok/BU} * {BU/wholeBU} / {tok/wholeTok} / D27 * {USD/wholeTok}
36
- return new decimal_js_light_1.default(initialWeight.spot.toString()).mul(numbers_1.D18d).div(decimalScale).div(numbers_1.D27d).mul(price);
37
+ return new decimal_js_light_1.default(initialWeight.spot.toString()).div(decimalScale).mul(price).div(numbers_1.D9d);
37
38
  });
38
39
  const totalValue = vals.reduce((a, b) => a.add(b));
39
40
  // D18{1} = {USD/wholeBU} / {USD/wholeBU} * D18
@@ -95,9 +96,9 @@ const getOpenAuction = (rebalance, _supply, _initialFolio = [], _targetBasket =
95
96
  // {wholeTok/wholeBU} = D27{tok/BU} * {BU/wholeBU} / {tok/wholeTok} / D27
96
97
  let weightRanges = rebalance.weights.map((range, i) => {
97
98
  return {
98
- low: new decimal_js_light_1.default(range.low.toString()).mul(numbers_1.D18d).div(decimalScale[i]).div(numbers_1.D27d),
99
- spot: new decimal_js_light_1.default(range.spot.toString()).mul(numbers_1.D18d).div(decimalScale[i]).div(numbers_1.D27d),
100
- high: new decimal_js_light_1.default(range.high.toString()).mul(numbers_1.D18d).div(decimalScale[i]).div(numbers_1.D27d),
99
+ low: new decimal_js_light_1.default(range.low.toString()).div(decimalScale[i]).div(numbers_1.D9d),
100
+ spot: new decimal_js_light_1.default(range.spot.toString()).div(decimalScale[i]).div(numbers_1.D9d),
101
+ high: new decimal_js_light_1.default(range.high.toString()).div(decimalScale[i]).div(numbers_1.D9d),
101
102
  };
102
103
  });
103
104
  const finalStageAt = new decimal_js_light_1.default(_finalStageAt.toString());
@@ -121,7 +122,7 @@ const getOpenAuction = (rebalance, _supply, _initialFolio = [], _targetBasket =
121
122
  return weightRange.spot.mul(prices[i]);
122
123
  })
123
124
  .reduce((a, b) => a.add(b));
124
- const buPriceChange = buValue.sub(shareValue).abs().div(shareValue);
125
+ const buPriceChange = buValue.sub(shareValue).div(shareValue);
125
126
  console.log(` 🧺 ${buPriceChange.mul(100).toFixed(2)}% basket price difference`);
126
127
  if (debug) {
127
128
  console.log("shareValue", shareValue.toString());
@@ -131,7 +132,7 @@ const getOpenAuction = (rebalance, _supply, _initialFolio = [], _targetBasket =
131
132
  throw new Error("buValue and shareValue are too different, something probably went wrong");
132
133
  }
133
134
  // ================================================================
134
- // calculate rebalanceTarget
135
+ // calculate portionBeingEjected
135
136
  const ejectionIndices = [];
136
137
  for (let i = 0; i < rebalance.weights.length; i++) {
137
138
  if (rebalance.inRebalance[i] && rebalance.weights[i].spot == 0n) {
@@ -145,16 +146,20 @@ const getOpenAuction = (rebalance, _supply, _initialFolio = [], _targetBasket =
145
146
  })
146
147
  .reduce((a, b) => a.add(b), numbers_1.ZERO)
147
148
  .div(shareValue);
149
+ // ================================================================
150
+ // calculate progressions
151
+ // {wholeBU/wholeShare} = D18{BU/share} / D18
152
+ const prevSpotLimit = new decimal_js_light_1.default(rebalance.limits.spot.toString()).div(numbers_1.D18d);
153
+ // {wholeTok/wholeShare} = {wholeTok/wholeBU} * {wholeBU/wholeShare}
154
+ const expectedBalances = weightRanges.map((weightRange) => weightRange.spot.mul(prevSpotLimit));
148
155
  // {1} = {USD/wholeShare} / {USD/wholeShare}
149
156
  let progression = folio
150
157
  .map((actualBalance, i) => {
151
158
  if (!rebalance.inRebalance[i]) {
152
159
  return numbers_1.ZERO;
153
160
  }
154
- // {wholeTok/wholeShare} = {USD/wholeShare} * {1} / {USD/wholeTok}
155
- const balanceExpected = shareValue.mul(targetBasket[i]).div(prices[i]);
156
- // {wholeTok/wholeShare} = {wholeTok/wholeBU} * {wholeBU/wholeShare}
157
- const balanceInBasket = balanceExpected.gt(actualBalance) ? actualBalance : balanceExpected;
161
+ // {wholeTok/wholeShare}
162
+ const balanceInBasket = expectedBalances[i].gt(actualBalance) ? actualBalance : expectedBalances[i];
158
163
  // {USD/wholeShare} = {wholeTok/wholeShare} * {USD/wholeTok}
159
164
  return balanceInBasket.mul(prices[i]);
160
165
  })
@@ -167,10 +172,8 @@ const getOpenAuction = (rebalance, _supply, _initialFolio = [], _targetBasket =
167
172
  if (!rebalance.inRebalance[i] && rebalance.weights[i].spot > 0n) {
168
173
  return numbers_1.ZERO;
169
174
  }
170
- // {wholeTok/wholeShare} = {USD/wholeShare} * {1} / {USD/wholeTok}
171
- const balanceExpected = shareValue.mul(targetBasket[i]).div(prices[i]);
172
- // {wholeTok/wholeShare} = {wholeTok/wholeBU} * {wholeBU/wholeShare}
173
- const balanceInBasket = balanceExpected.gt(initialBalance) ? initialBalance : balanceExpected;
175
+ // {wholeTok/wholeShare}
176
+ const balanceInBasket = expectedBalances[i].gt(initialBalance) ? initialBalance : expectedBalances[i];
174
177
  // {USD/wholeShare} = {wholeTok/wholeShare} * {USD/wholeTok}
175
178
  return balanceInBasket.mul(prices[i]);
176
179
  })
@@ -209,7 +212,7 @@ const getOpenAuction = (rebalance, _supply, _initialFolio = [], _targetBasket =
209
212
  // if the ejections are everything that's left, keep the finalStageAt targeting from above
210
213
  if (progression.add(portionBeingEjected).lt(numbers_1.ONE)) {
211
214
  // else: get rid of all the dust
212
- let ejectionTarget = progression.add(portionBeingEjected.mul(1.02)); // buy 2% extra
215
+ let ejectionTarget = progression.add(portionBeingEjected.mul(1.05)); // buy 5% extra
213
216
  if (ejectionTarget.gt(numbers_1.ONE)) {
214
217
  ejectionTarget = numbers_1.ONE;
215
218
  }
@@ -241,11 +244,6 @@ const getOpenAuction = (rebalance, _supply, _initialFolio = [], _targetBasket =
241
244
  };
242
245
  // hold some surpluses aside if ejecting
243
246
  if (round == AuctionRound.EJECT) {
244
- // buy 0.1% more
245
- newLimits.low += newLimits.low / 1000n;
246
- // aim 1% higher in the future
247
- newLimits.spot += newLimits.spot / 100n;
248
- // leave 10% room to increase low in the future if ejection leaves dust behind
249
247
  newLimits.high += newLimits.high / 10n;
250
248
  }
251
249
  // low
@@ -288,23 +286,16 @@ const getOpenAuction = (rebalance, _supply, _initialFolio = [], _targetBasket =
288
286
  const newWeightsD27 = {
289
287
  low: (0, numbers_1.bn)(idealWeight
290
288
  .mul(rebalanceTarget.div(actualLimits.low.div(actualLimits.spot))) // add remaining delta into weight
291
- .mul(numbers_1.D27d)
292
- .mul(decimalScale[i])
293
- .div(numbers_1.D18d)),
294
- spot: (0, numbers_1.bn)(idealWeight.mul(numbers_1.D27d).mul(decimalScale[i]).div(numbers_1.D18d)),
289
+ .mul(numbers_1.D9d)
290
+ .mul(decimalScale[i])),
291
+ spot: (0, numbers_1.bn)(idealWeight.mul(numbers_1.D9d).mul(decimalScale[i])),
295
292
  high: (0, numbers_1.bn)(idealWeight
296
293
  .mul(numbers_1.ONE.add(delta).div(actualLimits.high.div(actualLimits.spot))) // add remaining delta into weight
297
- .mul(numbers_1.D27d)
298
- .mul(decimalScale[i])
299
- .div(numbers_1.D18d)),
294
+ .mul(numbers_1.D9d)
295
+ .mul(decimalScale[i])),
300
296
  };
301
297
  // hold some surpluses aside if ejecting
302
298
  if (round == AuctionRound.EJECT) {
303
- // buy 0.1% more
304
- newWeightsD27.low += newWeightsD27.low / 1000n;
305
- // aim 1% higher in the future
306
- newWeightsD27.spot += newWeightsD27.spot / 100n;
307
- // leave 10% room to increase low in the future if ejection leaves dust behind
308
299
  newWeightsD27.high += newWeightsD27.high / 10n;
309
300
  }
310
301
  if (newWeightsD27.low < weightRange.low) {
@@ -335,7 +326,7 @@ const getOpenAuction = (rebalance, _supply, _initialFolio = [], _targetBasket =
335
326
  // D27{USD/tok}
336
327
  const newPrices = rebalance.initialPrices.map((initialPrice, i) => {
337
328
  // revert if price out of bounds
338
- const spotPrice = (0, numbers_1.bn)(prices[i].mul(numbers_1.D27d).div(decimalScale[i]));
329
+ const spotPrice = (0, numbers_1.bn)(prices[i].div(decimalScale[i]).mul(numbers_1.D27d));
339
330
  if (spotPrice < initialPrice.low || spotPrice > initialPrice.high) {
340
331
  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!`);
341
332
  }
@@ -344,8 +335,8 @@ const getOpenAuction = (rebalance, _supply, _initialFolio = [], _targetBasket =
344
335
  }
345
336
  // D27{USD/tok} = {USD/wholeTok} * D27 / {tok/wholeTok}
346
337
  const pricesD27 = {
347
- low: (0, numbers_1.bn)(prices[i].mul(numbers_1.ONE.sub(priceError[i])).mul(numbers_1.D27d).div(decimalScale[i])),
348
- high: (0, numbers_1.bn)(prices[i].div(numbers_1.ONE.sub(priceError[i])).mul(numbers_1.D27d).div(decimalScale[i])),
338
+ low: (0, numbers_1.bn)(prices[i].mul(numbers_1.ONE.sub(priceError[i])).div(decimalScale[i]).mul(numbers_1.D27d)),
339
+ high: (0, numbers_1.bn)(prices[i].div(numbers_1.ONE.sub(priceError[i])).div(decimalScale[i]).mul(numbers_1.D27d)),
349
340
  };
350
341
  // low
351
342
  if (pricesD27.low < initialPrice.low) {
@@ -377,9 +368,9 @@ const getOpenAuction = (rebalance, _supply, _initialFolio = [], _targetBasket =
377
368
  // {wholeTok/wholeBU} = D27{tok/BU} * {BU/wholeBU} / {tok/wholeTok} / D27
378
369
  weightRanges = newWeights.map((range, i) => {
379
370
  return {
380
- low: new decimal_js_light_1.default(range.low.toString()).mul(numbers_1.D18d).div(decimalScale[i]).div(numbers_1.D27d),
381
- spot: new decimal_js_light_1.default(range.spot.toString()).mul(numbers_1.D18d).div(decimalScale[i]).div(numbers_1.D27d),
382
- high: new decimal_js_light_1.default(range.high.toString()).mul(numbers_1.D18d).div(decimalScale[i]).div(numbers_1.D27d),
371
+ low: new decimal_js_light_1.default(range.low.toString()).div(decimalScale[i]).div(numbers_1.D9d),
372
+ spot: new decimal_js_light_1.default(range.spot.toString()).div(decimalScale[i]).div(numbers_1.D9d),
373
+ high: new decimal_js_light_1.default(range.high.toString()).div(decimalScale[i]).div(numbers_1.D9d),
383
374
  };
384
375
  });
385
376
  // {USD}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@reserve-protocol/dtf-rebalance-lib",
3
- "version": "0.2.4",
3
+ "version": "0.2.6",
4
4
  "description": "Rebalancing library for DTFs in typescript",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.js",