@reserve-protocol/dtf-rebalance-lib 0.2.16 → 0.2.18

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.
@@ -51,13 +51,13 @@ export declare const getTargetBasket: (_initialWeights: WeightRange[], _prices:
51
51
  *
52
52
  * Non-AUCTION_LAUNCHERs should use `folio.openAuctionUnrestricted()`
53
53
  *
54
- * @param rebalance The result of calling folio.getRebalance()
54
+ * @param rebalance The result of calling folio.getRebalance(), today
55
55
  * @param _supply {share} The totalSupply() of the basket, today
56
56
  * @param _initialFolio D18{tok/share} Initial balances per share, e.g result of folio.toAssets(1e18, 0) at time rebalance was first proposed
57
57
  * @param _targetBasket D18{1} Result of calling `getTargetBasket()`
58
- * @param _folio D18{tok/share} Current ratio of token per share, e.g result of folio.toAssets(1e18, 0)
58
+ * @param _folio D18{tok/share} Current ratio of token per share, e.g result of folio.toAssets(1e18, 0), today
59
59
  * @param _decimals Decimals of each token
60
- * @param _prices {USD/wholeTok} USD prices for each *whole* token
60
+ * @param _prices {USD/wholeTok} USD prices for each *whole* token, today
61
61
  * @param _priceError {1} Price error to use for each token during auction pricing; should be smaller than price error during startRebalance
62
62
  * @param _finalStageAt {1} The % rebalanced from the initial Folio to determine when is the final stage of the rebalance
63
63
  */
@@ -46,13 +46,13 @@ exports.getTargetBasket = getTargetBasket;
46
46
  *
47
47
  * Non-AUCTION_LAUNCHERs should use `folio.openAuctionUnrestricted()`
48
48
  *
49
- * @param rebalance The result of calling folio.getRebalance()
49
+ * @param rebalance The result of calling folio.getRebalance(), today
50
50
  * @param _supply {share} The totalSupply() of the basket, today
51
51
  * @param _initialFolio D18{tok/share} Initial balances per share, e.g result of folio.toAssets(1e18, 0) at time rebalance was first proposed
52
52
  * @param _targetBasket D18{1} Result of calling `getTargetBasket()`
53
- * @param _folio D18{tok/share} Current ratio of token per share, e.g result of folio.toAssets(1e18, 0)
53
+ * @param _folio D18{tok/share} Current ratio of token per share, e.g result of folio.toAssets(1e18, 0), today
54
54
  * @param _decimals Decimals of each token
55
- * @param _prices {USD/wholeTok} USD prices for each *whole* token
55
+ * @param _prices {USD/wholeTok} USD prices for each *whole* token, today
56
56
  * @param _priceError {1} Price error to use for each token during auction pricing; should be smaller than price error during startRebalance
57
57
  * @param _finalStageAt {1} The % rebalanced from the initial Folio to determine when is the final stage of the rebalance
58
58
  */
@@ -148,10 +148,14 @@ const getOpenAuction = (rebalance, _supply, _initialFolio = [], _targetBasket =
148
148
  .div(shareValue);
149
149
  // ================================================================
150
150
  // calculate progressions
151
+ // {wholeBU/wholeShare} = {USD/wholeShare} / {USD/wholeBU}
152
+ const spotLimit = shareValue.div(buValue);
151
153
  // {wholeBU/wholeShare} = D18{BU/share} / D18
152
154
  const prevSpotLimit = new utils_1.Decimal(rebalance.limits.spot.toString()).div(numbers_1.D18d);
155
+ const maxSpotLimit = spotLimit.gt(prevSpotLimit) ? spotLimit : prevSpotLimit;
153
156
  // {wholeTok/wholeShare} = {wholeTok/wholeBU} * {wholeBU/wholeShare}
154
- const expectedBalances = weightRanges.map((weightRange) => weightRange.spot.mul(prevSpotLimit));
157
+ const expectedBalances = weightRanges.map((weightRange) => weightRange.spot.mul(maxSpotLimit));
158
+ // absolute scale
155
159
  // {1} = {USD/wholeShare} / {USD/wholeShare}
156
160
  let progression = folio
157
161
  .map((actualBalance, i) => {
@@ -165,11 +169,11 @@ const getOpenAuction = (rebalance, _supply, _initialFolio = [], _targetBasket =
165
169
  })
166
170
  .reduce((a, b) => a.add(b))
167
171
  .div(shareValue);
172
+ // absolute scale
168
173
  // {1} = {USD/wholeShare} / {USD/wholeShare}
169
174
  const initialProgression = initialFolio
170
175
  .map((initialBalance, i) => {
171
- // make sure to include tokens that were already ejected
172
- if (!rebalance.inRebalance[i] && rebalance.weights[i].spot > 0n) {
176
+ if (!rebalance.inRebalance[i]) {
173
177
  return numbers_1.ZERO;
174
178
  }
175
179
  // {wholeTok/wholeShare}
@@ -183,13 +187,13 @@ const getOpenAuction = (rebalance, _supply, _initialFolio = [], _targetBasket =
183
187
  if (debug) {
184
188
  console.log("progression < initialProgression", progression.toString(), initialProgression.toString());
185
189
  }
186
- progression = initialProgression; // don't go backwards
190
+ progression = initialProgression; // don't go backwards, should only happen due to negligible rounding errors
187
191
  }
188
192
  // {1} = {1} / {1}
189
193
  let relativeProgression = initialProgression.eq(numbers_1.ONE)
190
194
  ? numbers_1.ONE
191
195
  : progression.sub(initialProgression).div(numbers_1.ONE.sub(initialProgression));
192
- let rebalanceTarget = numbers_1.ONE;
196
+ let rebalanceTarget = numbers_1.ONE; // absolute scale
193
197
  let round = AuctionRound.FINAL;
194
198
  if (debug) {
195
199
  console.log("initialProgression", initialProgression.toString());
@@ -210,6 +214,8 @@ const getOpenAuction = (rebalance, _supply, _initialFolio = [], _targetBasket =
210
214
  }
211
215
  }
212
216
  // EJECT
217
+ // TODO maybe increase threshold to nonzero value, taking into account price
218
+ // currently will get stuck trying to eject tiny dust over and over
213
219
  if (portionBeingEjected.gt(0)) {
214
220
  round = AuctionRound.EJECT;
215
221
  // if the ejections are everything that's left, keep the finalStageAt targeting from above
@@ -237,8 +243,6 @@ const getOpenAuction = (rebalance, _supply, _initialFolio = [], _targetBasket =
237
243
  const delta = numbers_1.ONE.sub(rebalanceTarget);
238
244
  // ================================================================
239
245
  // get new limits, constrained by extremes
240
- // {wholeBU/wholeShare} = {USD/wholeShare} / {USD/wholeBU}
241
- const spotLimit = shareValue.div(buValue);
242
246
  // D18{BU/share} = {wholeBU/wholeShare} * D18 * {1}
243
247
  const newLimits = {
244
248
  low: (0, numbers_1.bn)(spotLimit.sub(spotLimit.mul(delta)).mul(numbers_1.D18d)),
@@ -288,7 +292,7 @@ const getOpenAuction = (rebalance, _supply, _initialFolio = [], _targetBasket =
288
292
  // D27{tok/BU} = {wholeTok/wholeBU} * D27 * {tok/wholeTok} / {BU/wholeBU}
289
293
  const newWeightsD27 = {
290
294
  low: (0, numbers_1.bn)(idealWeight
291
- .mul(rebalanceTarget.div(actualLimits.low.div(actualLimits.spot))) // add remaining delta into weight
295
+ .mul(numbers_1.ONE.sub(delta).div(actualLimits.low.div(actualLimits.spot))) // add remaining delta into weight
292
296
  .mul(numbers_1.D9d)
293
297
  .mul(decimalScale[i])),
294
298
  spot: (0, numbers_1.bn)(idealWeight.mul(numbers_1.D9d).mul(decimalScale[i])),
@@ -421,7 +425,8 @@ const getOpenAuction = (rebalance, _supply, _initialFolio = [], _targetBasket =
421
425
  const returnWeights = [];
422
426
  const returnPrices = [];
423
427
  for (let i = 0; i < rebalance.tokens.length; i++) {
424
- if (rebalance.inRebalance[i]) {
428
+ if (rebalance.inRebalance[i] &&
429
+ (surplusTokens.includes(rebalance.tokens[i]) || deficitTokens.includes(rebalance.tokens[i]))) {
425
430
  returnTokens.push(rebalance.tokens[i]);
426
431
  returnWeights.push(newWeights[i]);
427
432
  returnPrices.push(newPrices[i]);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@reserve-protocol/dtf-rebalance-lib",
3
- "version": "0.2.16",
3
+ "version": "0.2.18",
4
4
  "description": "Rebalancing library for DTFs in typescript",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.js",