@reserve-protocol/dtf-rebalance-lib 0.0.17 → 0.1.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.
@@ -223,10 +223,10 @@ const getOpenAuction = (rebalance, _supply, _initialFolio = [], _targetBasket =
223
223
  high: (0, numbers_1.bn)(spotLimit.add(spotLimit.mul(delta)).mul(numbers_1.D18d)),
224
224
  };
225
225
  if (round == AuctionRound.EJECT && rebalanceTarget.eq(numbers_1.ONE)) {
226
- // if ejecting to completion, aim 10% higher (if possible)
227
- newLimits.low = (0, numbers_1.bn)(spotLimit.mul(1.1).mul(numbers_1.D18d));
228
- newLimits.spot = (0, numbers_1.bn)(spotLimit.mul(1.1).mul(numbers_1.D18d));
229
- newLimits.high = (0, numbers_1.bn)(spotLimit.mul(1.1).mul(numbers_1.D18d));
226
+ // aim 1% higher if executed permissonlessly
227
+ newLimits.spot += newLimits.spot * 1n / 100n;
228
+ // leave 10% room to increase low in the future if ejection leaves dust behind
229
+ newLimits.high += newLimits.high * 10n / 100n;
230
230
  }
231
231
  // low
232
232
  if (newLimits.low < rebalance.limits.low) {
@@ -282,10 +282,10 @@ const getOpenAuction = (rebalance, _supply, _initialFolio = [], _targetBasket =
282
282
  .div(numbers_1.D18d)),
283
283
  };
284
284
  if (round == AuctionRound.EJECT && rebalanceTarget.eq(numbers_1.ONE)) {
285
- // if ejecting to completion, aim 10% higher
286
- newWeightsD27.low = newWeightsD27.low * 11n / 10n;
287
- newWeightsD27.spot = newWeightsD27.spot * 11n / 10n;
288
- newWeightsD27.high = newWeightsD27.high * 11n / 10n;
285
+ // aim 1% higher if executed permissonlessly
286
+ newWeightsD27.spot += newWeightsD27.spot * 1n / 100n;
287
+ // leave 10% room to increase low in the future if ejection leaves dust behind
288
+ newWeightsD27.high += newWeightsD27.high * 10n / 100n;
289
289
  }
290
290
  if (newWeightsD27.low < weightRange.low) {
291
291
  newWeightsD27.low = weightRange.low;
@@ -11,6 +11,7 @@ export interface StartRebalanceArgsPartial {
11
11
  *
12
12
  * @param _supply {share}
13
13
  * @param tokens Addresses of tokens in the basket
14
+ * @param _folio D18{tok/share} Folio of the basket
14
15
  * @param decimals Decimals of each token
15
16
  * @param _targetBasket D18{1} Ideal basket
16
17
  * @param _prices {USD/wholeTok} USD prices for each *whole* token
@@ -18,4 +19,4 @@ export interface StartRebalanceArgsPartial {
18
19
  * @param _dtfPrice {USD/wholeShare} DTF price
19
20
  * @param weightControl TRACKING=false, NATIVE=true
20
21
  */
21
- export declare const getStartRebalance: (_supply: bigint, tokens: string[], decimals: bigint[], _targetBasket: bigint[], _prices: number[], _priceError: number[], _dtfPrice: number, weightControl: boolean, logging?: boolean) => StartRebalanceArgsPartial;
22
+ export declare const getStartRebalance: (_supply: bigint, tokens: string[], _folio: bigint[], decimals: bigint[], _targetBasket: bigint[], _prices: number[], _priceError: number[], weightControl: boolean, logging?: boolean) => StartRebalanceArgsPartial;
@@ -13,6 +13,7 @@ const numbers_1 = require("./numbers");
13
13
  *
14
14
  * @param _supply {share}
15
15
  * @param tokens Addresses of tokens in the basket
16
+ * @param _folio D18{tok/share} Folio of the basket
16
17
  * @param decimals Decimals of each token
17
18
  * @param _targetBasket D18{1} Ideal basket
18
19
  * @param _prices {USD/wholeTok} USD prices for each *whole* token
@@ -20,10 +21,12 @@ const numbers_1 = require("./numbers");
20
21
  * @param _dtfPrice {USD/wholeShare} DTF price
21
22
  * @param weightControl TRACKING=false, NATIVE=true
22
23
  */
23
- const getStartRebalance = (_supply, tokens, decimals, _targetBasket, _prices, _priceError, _dtfPrice, weightControl, logging) => {
24
+ const getStartRebalance = (_supply, tokens, _folio, decimals, _targetBasket, _prices, _priceError, weightControl, logging) => {
24
25
  if (logging) {
25
- console.log('getStartRebalance', _supply, tokens, decimals, _targetBasket, _prices, _priceError, _dtfPrice, weightControl);
26
+ console.log('getStartRebalance', _supply, tokens, _folio, decimals, _targetBasket, _prices, _priceError, weightControl);
26
27
  }
28
+ // {wholeTok/wholeShare} = D18{tok/share} * {share/wholeShare} / {tok/wholeTok} / D18
29
+ const folio = _folio.map((c, i) => new decimal_js_light_1.default(c.toString()).div(new decimal_js_light_1.default(`1e${decimals[i]}`)));
27
30
  // convert price number inputs to bigints
28
31
  // {USD/wholeTok}
29
32
  const prices = _prices.map((a) => new decimal_js_light_1.default(a.toString()));
@@ -32,8 +35,6 @@ const getStartRebalance = (_supply, tokens, decimals, _targetBasket, _prices, _p
32
35
  throw new Error(`missing price for token ${tokens[i]}`);
33
36
  }
34
37
  }
35
- // {USD/wholeShare}
36
- const dtfPrice = new decimal_js_light_1.default(_dtfPrice);
37
38
  // {1} = D18{1} / D18
38
39
  const targetBasket = _targetBasket.map((a) => new decimal_js_light_1.default(a.toString()).div(numbers_1.D18d));
39
40
  // {1}
@@ -52,6 +53,8 @@ const getStartRebalance = (_supply, tokens, decimals, _targetBasket, _prices, _p
52
53
  throw new Error('cannot defer prices');
53
54
  }
54
55
  // === newWeights ===
56
+ // {USD/wholeShare} = {wholeTok/wholeShare} * {USD/wholeTok}
57
+ const dtfPrice = folio.map((f, i) => f.mul(prices[i])).reduce((a, b) => a.add(b));
55
58
  // {wholeTok/wholeShare} = {1} * {USD/wholeShare} / {USD/wholeTok}
56
59
  const spotWeight = targetBasket[i].mul(dtfPrice).div(prices[i]);
57
60
  // D27{tok/share}{wholeShare/wholeTok} = D27 * {tok/wholeTok} / {share/wholeShare}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@reserve-protocol/dtf-rebalance-lib",
3
- "version": "0.0.17",
3
+ "version": "0.1.0",
4
4
  "description": "Rebalancing library for DTFs in typescript",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.js",
@@ -330,10 +330,11 @@ export const getOpenAuction = (
330
330
  }
331
331
 
332
332
  if (round == AuctionRound.EJECT && rebalanceTarget.eq(ONE)) {
333
- // if ejecting to completion, aim 10% higher (if possible)
334
- newLimits.low = bn(spotLimit.mul(1.1).mul(D18d))
335
- newLimits.spot = bn(spotLimit.mul(1.1).mul(D18d))
336
- newLimits.high = bn(spotLimit.mul(1.1).mul(D18d))
333
+ // aim 1% higher if executed permissonlessly
334
+ newLimits.spot += newLimits.spot * 1n / 100n
335
+
336
+ // leave 10% room to increase low in the future if ejection leaves dust behind
337
+ newLimits.high += newLimits.high * 10n / 100n
337
338
  }
338
339
 
339
340
  // low
@@ -403,10 +404,11 @@ export const getOpenAuction = (
403
404
  }
404
405
 
405
406
  if (round == AuctionRound.EJECT && rebalanceTarget.eq(ONE)) {
406
- // if ejecting to completion, aim 10% higher
407
- newWeightsD27.low = newWeightsD27.low * 11n / 10n
408
- newWeightsD27.spot = newWeightsD27.spot * 11n / 10n
409
- newWeightsD27.high = newWeightsD27.high * 11n / 10n
407
+ // aim 1% higher if executed permissonlessly
408
+ newWeightsD27.spot += newWeightsD27.spot * 1n / 100n
409
+
410
+ // leave 10% room to increase low in the future if ejection leaves dust behind
411
+ newWeightsD27.high += newWeightsD27.high * 10n / 100n
410
412
  }
411
413
 
412
414
  if (newWeightsD27.low < weightRange.low) {
@@ -21,6 +21,7 @@ export interface StartRebalanceArgsPartial {
21
21
  *
22
22
  * @param _supply {share}
23
23
  * @param tokens Addresses of tokens in the basket
24
+ * @param _folio D18{tok/share} Folio of the basket
24
25
  * @param decimals Decimals of each token
25
26
  * @param _targetBasket D18{1} Ideal basket
26
27
  * @param _prices {USD/wholeTok} USD prices for each *whole* token
@@ -31,18 +32,23 @@ export interface StartRebalanceArgsPartial {
31
32
  export const getStartRebalance = (
32
33
  _supply: bigint,
33
34
  tokens: string[],
35
+ _folio: bigint[],
34
36
  decimals: bigint[],
35
37
  _targetBasket: bigint[],
36
38
  _prices: number[],
37
39
  _priceError: number[],
38
- _dtfPrice: number,
39
40
  weightControl: boolean,
40
41
  logging?: boolean
41
42
  ): StartRebalanceArgsPartial => {
42
43
  if (logging) {
43
- console.log('getStartRebalance', _supply, tokens, decimals, _targetBasket, _prices, _priceError, _dtfPrice, weightControl)
44
+ console.log('getStartRebalance', _supply, tokens, _folio, decimals, _targetBasket, _prices, _priceError, weightControl)
44
45
  }
45
46
 
47
+ // {wholeTok/wholeShare} = D18{tok/share} * {share/wholeShare} / {tok/wholeTok} / D18
48
+ const folio = _folio.map((c: bigint, i: number) =>
49
+ new Decimal(c.toString()).div(new Decimal(`1e${decimals[i]}`))
50
+ )
51
+
46
52
  // convert price number inputs to bigints
47
53
 
48
54
  // {USD/wholeTok}
@@ -53,9 +59,6 @@ export const getStartRebalance = (
53
59
  }
54
60
  }
55
61
 
56
- // {USD/wholeShare}
57
- const dtfPrice = new Decimal(_dtfPrice)
58
-
59
62
  // {1} = D18{1} / D18
60
63
  const targetBasket = _targetBasket.map((a) =>
61
64
  new Decimal(a.toString()).div(D18d)
@@ -83,6 +86,8 @@ export const getStartRebalance = (
83
86
 
84
87
  // === newWeights ===
85
88
 
89
+ // {USD/wholeShare} = {wholeTok/wholeShare} * {USD/wholeTok}
90
+ const dtfPrice = folio.map((f: Decimal, i: number) => f.mul(prices[i])).reduce((a: Decimal, b: Decimal) => a.add(b))
86
91
 
87
92
  // {wholeTok/wholeShare} = {1} * {USD/wholeShare} / {USD/wholeTok}
88
93
  const spotWeight = targetBasket[i].mul(dtfPrice).div(prices[i])