@reserve-protocol/dtf-rebalance-lib 0.2.7 → 0.2.9

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/numbers.d.ts CHANGED
@@ -1,11 +1,12 @@
1
- import Decimal from 'decimal.js-light';
1
+ import DecimalLight from 'decimal.js-light';
2
+ import type { Decimal as DecimalType } from 'decimal.js-light';
2
3
  export declare const D27n: bigint;
3
4
  export declare const D18n: bigint;
4
5
  export declare const D9n: bigint;
5
- export declare const D27d: Decimal;
6
- export declare const D18d: Decimal;
7
- export declare const D9d: Decimal;
8
- export declare const ZERO: Decimal;
9
- export declare const ONE: Decimal;
10
- export declare const TWO: Decimal;
11
- export declare const bn: (str: string | Decimal) => bigint;
6
+ export declare const D27d: DecimalType;
7
+ export declare const D18d: DecimalType;
8
+ export declare const D9d: DecimalType;
9
+ export declare const ZERO: DecimalLight;
10
+ export declare const ONE: DecimalLight;
11
+ export declare const TWO: DecimalLight;
12
+ export declare const bn: (str: string | DecimalType) => bigint;
package/dist/numbers.js CHANGED
@@ -5,16 +5,18 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.bn = exports.TWO = exports.ONE = exports.ZERO = exports.D9d = exports.D18d = exports.D27d = exports.D9n = exports.D18n = exports.D27n = void 0;
7
7
  const decimal_js_light_1 = __importDefault(require("decimal.js-light"));
8
+ // Create a local Decimal constructor with custom precision
9
+ const Decimal = decimal_js_light_1.default.clone({ precision: 100 });
8
10
  exports.D27n = 10n ** 27n;
9
11
  exports.D18n = 10n ** 18n;
10
12
  exports.D9n = 10n ** 9n;
11
- exports.D27d = new decimal_js_light_1.default('1e27');
12
- exports.D18d = new decimal_js_light_1.default('1e18');
13
- exports.D9d = new decimal_js_light_1.default('1e9');
14
- exports.ZERO = new decimal_js_light_1.default('0');
15
- exports.ONE = new decimal_js_light_1.default('1');
16
- exports.TWO = new decimal_js_light_1.default('2');
13
+ exports.D27d = new Decimal('1e27');
14
+ exports.D18d = new Decimal('1e18');
15
+ exports.D9d = new Decimal('1e9');
16
+ exports.ZERO = new Decimal('0');
17
+ exports.ONE = new Decimal('1');
18
+ exports.TWO = new Decimal('2');
17
19
  const bn = (str) => {
18
- return BigInt(new decimal_js_light_1.default(str).toFixed(0));
20
+ return BigInt(new Decimal(str).toFixed(0));
19
21
  };
20
22
  exports.bn = bn;
@@ -7,7 +7,8 @@ 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
+ // Create a local Decimal constructor with custom precision
11
+ const Decimal = decimal_js_light_1.default.clone({ precision: 100 });
11
12
  // Call `getOpenAuction()` to get the current auction round
12
13
  var AuctionRound;
13
14
  (function (AuctionRound) {
@@ -31,10 +32,10 @@ const getTargetBasket = (_initialWeights, _prices, _decimals) => {
31
32
  throw new Error("length mismatch");
32
33
  }
33
34
  const vals = _initialWeights.map((initialWeight, i) => {
34
- const price = new decimal_js_light_1.default(_prices[i]);
35
- const decimalScale = new decimal_js_light_1.default(`1e${_decimals[i]}`);
35
+ const price = new Decimal(_prices[i]);
36
+ const decimalScale = new Decimal(`1e${_decimals[i]}`);
36
37
  // {USD/wholeBU} = D27{tok/BU} * {BU/wholeBU} / {tok/wholeTok} / D27 * {USD/wholeTok}
37
- return new decimal_js_light_1.default(initialWeight.spot.toString()).div(decimalScale).mul(price).div(numbers_1.D9d);
38
+ return new Decimal(initialWeight.spot.toString()).div(decimalScale).mul(price).div(numbers_1.D9d);
38
39
  });
39
40
  const totalValue = vals.reduce((a, b) => a.add(b));
40
41
  // D18{1} = {USD/wholeBU} / {USD/wholeBU} * D18
@@ -75,33 +76,33 @@ const getOpenAuction = (rebalance, _supply, _initialFolio = [], _targetBasket =
75
76
  }
76
77
  // ================================================================
77
78
  // {wholeShare} = {share} / {share/wholeShare}
78
- const supply = new decimal_js_light_1.default(_supply.toString()).div(numbers_1.D18d);
79
+ const supply = new Decimal(_supply.toString()).div(numbers_1.D18d);
79
80
  // {1} = D18{1} / D18
80
- const targetBasket = _targetBasket.map((a) => new decimal_js_light_1.default(a.toString()).div(numbers_1.D18d));
81
+ const targetBasket = _targetBasket.map((a) => new Decimal(a.toString()).div(numbers_1.D18d));
81
82
  // {USD/wholeTok}
82
- const prices = _prices.map((a) => new decimal_js_light_1.default(a));
83
+ const prices = _prices.map((a) => new Decimal(a));
83
84
  for (let i = 0; i < prices.length; i++) {
84
85
  if (prices[i].eq(numbers_1.ZERO)) {
85
86
  throw new Error(`missing price for token ${rebalance.tokens[i]}`);
86
87
  }
87
88
  }
88
89
  // {1}
89
- const priceError = _priceError.map((a) => new decimal_js_light_1.default(a.toString()));
90
+ const priceError = _priceError.map((a) => new Decimal(a.toString()));
90
91
  // {tok/wholeTok}
91
- const decimalScale = _decimals.map((a) => new decimal_js_light_1.default(`1e${a}`));
92
+ const decimalScale = _decimals.map((a) => new Decimal(`1e${a}`));
92
93
  // {wholeTok/wholeShare} = D18{tok/share} * {share/wholeShare} / {tok/wholeTok} / D18
93
- const initialFolio = _initialFolio.map((c, i) => new decimal_js_light_1.default(c.toString()).div(decimalScale[i]));
94
+ const initialFolio = _initialFolio.map((c, i) => new Decimal(c.toString()).div(decimalScale[i]));
94
95
  // {wholeTok/wholeShare} = D18{tok/share} * {share/wholeShare} / {tok/wholeTok} / D18
95
- const folio = _folio.map((c, i) => new decimal_js_light_1.default(c.toString()).div(decimalScale[i]));
96
+ const folio = _folio.map((c, i) => new Decimal(c.toString()).div(decimalScale[i]));
96
97
  // {wholeTok/wholeBU} = D27{tok/BU} * {BU/wholeBU} / {tok/wholeTok} / D27
97
98
  let weightRanges = rebalance.weights.map((range, i) => {
98
99
  return {
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),
100
+ low: new Decimal(range.low.toString()).div(decimalScale[i]).div(numbers_1.D9d),
101
+ spot: new Decimal(range.spot.toString()).div(decimalScale[i]).div(numbers_1.D9d),
102
+ high: new Decimal(range.high.toString()).div(decimalScale[i]).div(numbers_1.D9d),
102
103
  };
103
104
  });
104
- const finalStageAt = new decimal_js_light_1.default(_finalStageAt.toString());
105
+ const finalStageAt = new Decimal(_finalStageAt.toString());
105
106
  // ================================================================
106
107
  // calculate ideal spot limit, the actual BU<->share ratio
107
108
  // {USD/wholeShare} = {wholeTok/wholeShare} * {USD/wholeTok}
@@ -147,40 +148,38 @@ const getOpenAuction = (rebalance, _supply, _initialFolio = [], _targetBasket =
147
148
  .reduce((a, b) => a.add(b), numbers_1.ZERO)
148
149
  .div(shareValue);
149
150
  // ================================================================
150
- // {wholeBU/wholeShare} = D18{BU/share} / D18
151
- const prevSpotLimit = new decimal_js_light_1.default(rebalance.limits.spot.toString()).div(numbers_1.D18d);
152
151
  // calculate progressions
153
- // {1} = {USD/wholeBU} / {USD/wholeBU}
152
+ // {wholeBU/wholeShare} = D18{BU/share} / D18
153
+ const prevSpotLimit = new Decimal(rebalance.limits.spot.toString()).div(numbers_1.D18d);
154
+ // {wholeTok/wholeBU} = {wholeTok/wholeBU} * {wholeBU/wholeShare}
155
+ const expectedBalances = weightRanges.map((weightRange) => weightRange.spot.mul(prevSpotLimit));
156
+ // {1} = {USD/wholeShare} / {USD/wholeShare}
154
157
  let progression = folio
155
158
  .map((actualBalance, i) => {
156
159
  if (!rebalance.inRebalance[i]) {
157
160
  return numbers_1.ZERO;
158
161
  }
159
- // {wholeTok/wholeBU} = {wholeTok/wholeShare} / {wholeBU/wholeShare}
160
- const actualInBU = actualBalance.div(prevSpotLimit);
161
- // {wholeTok/wholeBU}
162
- const balanceInBasket = weightRanges[i].spot.gt(actualInBU) ? actualInBU : weightRanges[i].spot;
163
- // {USD/wholeBU} = {wholeTok/wholeBU} * {USD/wholeTok}
162
+ // {wholeTok/wholeShare}
163
+ const balanceInBasket = expectedBalances[i].gt(actualBalance) ? actualBalance : expectedBalances[i];
164
+ // {USD/wholeShare} = {wholeTok/wholeShare} * {USD/wholeTok}
164
165
  return balanceInBasket.mul(prices[i]);
165
166
  })
166
167
  .reduce((a, b) => a.add(b))
167
- .div(buValue);
168
- // {1} = {USD/wholeBU} / {USD/wholeBU}
168
+ .div(shareValue);
169
+ // {1} = {USD/wholeShare} / {USD/wholeShare}
169
170
  const initialProgression = initialFolio
170
171
  .map((initialBalance, i) => {
171
172
  // make sure to include tokens that were already ejected
172
173
  if (!rebalance.inRebalance[i] && rebalance.weights[i].spot > 0n) {
173
174
  return numbers_1.ZERO;
174
175
  }
175
- // {wholeTok/wholeBU} = {wholeTok/wholeShare} / {wholeBU/wholeShare}
176
- const initialInBU = initialBalance.div(prevSpotLimit);
177
- // {wholeTok/wholeBU}
178
- const balanceInBasket = weightRanges[i].spot.gt(initialInBU) ? initialInBU : weightRanges[i].spot;
179
- // {USD/wholeBU} = {wholeTok/wholeBU} * {USD/wholeTok}
176
+ // {wholeTok/wholeShare}
177
+ const balanceInBasket = expectedBalances[i].gt(initialBalance) ? initialBalance : expectedBalances[i];
178
+ // {USD/wholeShare} = {wholeTok/wholeShare} * {USD/wholeTok}
180
179
  return balanceInBasket.mul(prices[i]);
181
180
  })
182
181
  .reduce((a, b) => a.add(b))
183
- .div(buValue);
182
+ .div(shareValue);
184
183
  if (progression < initialProgression) {
185
184
  progression = initialProgression; // don't go backwards
186
185
  }
@@ -276,9 +275,9 @@ const getOpenAuction = (rebalance, _supply, _initialFolio = [], _targetBasket =
276
275
  // get new weights, constrained by extremes
277
276
  // {wholeBU/wholeShare} = D18{BU/share} / D18
278
277
  const actualLimits = {
279
- low: new decimal_js_light_1.default(newLimits.low.toString()).div(numbers_1.D18d),
280
- spot: new decimal_js_light_1.default(newLimits.spot.toString()).div(numbers_1.D18d),
281
- high: new decimal_js_light_1.default(newLimits.high.toString()).div(numbers_1.D18d),
278
+ low: new Decimal(newLimits.low.toString()).div(numbers_1.D18d),
279
+ spot: new Decimal(newLimits.spot.toString()).div(numbers_1.D18d),
280
+ high: new Decimal(newLimits.high.toString()).div(numbers_1.D18d),
282
281
  };
283
282
  // D27{tok/BU}
284
283
  const newWeights = rebalance.weights.map((weightRange, i) => {
@@ -370,9 +369,9 @@ const getOpenAuction = (rebalance, _supply, _initialFolio = [], _targetBasket =
370
369
  // {wholeTok/wholeBU} = D27{tok/BU} * {BU/wholeBU} / {tok/wholeTok} / D27
371
370
  weightRanges = newWeights.map((range, i) => {
372
371
  return {
373
- low: new decimal_js_light_1.default(range.low.toString()).div(decimalScale[i]).div(numbers_1.D9d),
374
- spot: new decimal_js_light_1.default(range.spot.toString()).div(decimalScale[i]).div(numbers_1.D9d),
375
- high: new decimal_js_light_1.default(range.high.toString()).div(decimalScale[i]).div(numbers_1.D9d),
372
+ low: new Decimal(range.low.toString()).div(decimalScale[i]).div(numbers_1.D9d),
373
+ spot: new Decimal(range.spot.toString()).div(decimalScale[i]).div(numbers_1.D9d),
374
+ high: new Decimal(range.high.toString()).div(decimalScale[i]).div(numbers_1.D9d),
376
375
  };
377
376
  });
378
377
  // {USD}
@@ -6,6 +6,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.getStartRebalance = void 0;
7
7
  const decimal_js_light_1 = __importDefault(require("decimal.js-light"));
8
8
  const numbers_1 = require("./numbers");
9
+ // Create a local Decimal constructor with custom precision
10
+ const Decimal = decimal_js_light_1.default.clone({ precision: 100 });
9
11
  /**
10
12
  * Get the arguments needed to call startRebalance
11
13
  *
@@ -26,19 +28,19 @@ const getStartRebalance = (_supply, tokens, _folio, decimals, _targetBasket, _pr
26
28
  console.log("getStartRebalance", _supply, tokens, _folio, decimals, _targetBasket, _prices, _priceError, weightControl);
27
29
  }
28
30
  // {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]}`)));
31
+ const folio = _folio.map((c, i) => new Decimal(c.toString()).div(new Decimal(`1e${decimals[i]}`)));
30
32
  // convert price number inputs to bigints
31
33
  // {USD/wholeTok}
32
- const prices = _prices.map((a) => new decimal_js_light_1.default(a.toString()));
34
+ const prices = _prices.map((a) => new Decimal(a.toString()));
33
35
  for (let i = 0; i < prices.length; i++) {
34
36
  if (prices[i].eq(numbers_1.ZERO)) {
35
37
  throw new Error(`missing price for token ${tokens[i]}`);
36
38
  }
37
39
  }
38
40
  // {1} = D18{1} / D18
39
- const targetBasket = _targetBasket.map((a) => new decimal_js_light_1.default(a.toString()).div(numbers_1.D18d));
41
+ const targetBasket = _targetBasket.map((a) => new Decimal(a.toString()).div(numbers_1.D18d));
40
42
  // {1}
41
- const priceError = _priceError.map((a) => new decimal_js_light_1.default(a.toString()));
43
+ const priceError = _priceError.map((a) => new Decimal(a.toString()));
42
44
  // ================================================================
43
45
  const newWeights = [];
44
46
  const newPrices = [];
@@ -60,7 +62,7 @@ const getStartRebalance = (_supply, tokens, _folio, decimals, _targetBasket, _pr
60
62
  // {wholeTok/wholeShare} = {1} * {USD/wholeShare} / {USD/wholeTok}
61
63
  const spotWeight = targetBasket[i].mul(dtfPrice).div(prices[i]);
62
64
  // D27{tok/share}{wholeShare/wholeTok} = D27 * {tok/wholeTok} / {share/wholeShare}
63
- const limitMultiplier = numbers_1.D27d.mul(new decimal_js_light_1.default(`1e${decimals[i]}`)).div(numbers_1.D18d);
65
+ const limitMultiplier = numbers_1.D27d.mul(new Decimal(`1e${decimals[i]}`)).div(numbers_1.D18d);
64
66
  if (debug) {
65
67
  console.log("limitMultiplier", limitMultiplier.toString());
66
68
  }
@@ -86,7 +88,7 @@ const getStartRebalance = (_supply, tokens, _folio, decimals, _targetBasket, _pr
86
88
  }
87
89
  // === newPrices ===
88
90
  // D27{wholeTok/tok} = D27 / {tok/wholeTok}
89
- const priceMultiplier = numbers_1.D27d.div(new decimal_js_light_1.default(`1e${decimals[i]}`));
91
+ const priceMultiplier = numbers_1.D27d.div(new Decimal(`1e${decimals[i]}`));
90
92
  // {USD/wholeTok} = {USD/wholeTok} * {1}
91
93
  const lowPrice = prices[i].mul(numbers_1.ONE.sub(priceError[i]));
92
94
  const highPrice = prices[i].mul(numbers_1.ONE.add(priceError[i]));
package/dist/utils.js CHANGED
@@ -6,6 +6,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.getBasketDistribution = void 0;
7
7
  const decimal_js_light_1 = __importDefault(require("decimal.js-light"));
8
8
  const numbers_1 = require("./numbers");
9
+ // Create a local Decimal constructor with custom precision
10
+ const Decimal = decimal_js_light_1.default.clone({ precision: 100 });
9
11
  /**
10
12
  * This function can be used to get a basket distribution EITHER from a set of historical basket weights
11
13
  * or from a set of current balances. Make sure to use prices from the right time.
@@ -16,11 +18,11 @@ const numbers_1 = require("./numbers");
16
18
  * @returns D18{1} Current basket, total will be around 1e18 but not exactly
17
19
  */
18
20
  const getBasketDistribution = (_bals, _prices, decimals) => {
19
- const decimalScale = decimals.map((d) => new decimal_js_light_1.default(`1e${d}`));
21
+ const decimalScale = decimals.map((d) => new Decimal(`1e${d}`));
20
22
  // {wholeTok} = {tok} / {tok/wholeTok}
21
- const bals = _bals.map((bal, i) => new decimal_js_light_1.default(bal.toString()).div(decimalScale[i]));
23
+ const bals = _bals.map((bal, i) => new Decimal(bal.toString()).div(decimalScale[i]));
22
24
  // {USD/wholeTok} = {USD/wholeTok}
23
- const prices = _prices.map((a) => new decimal_js_light_1.default(a.toString()));
25
+ const prices = _prices.map((a) => new Decimal(a.toString()));
24
26
  // {USD} = {wholeTok} * {USD/wholeTok}
25
27
  const totalValue = bals
26
28
  .map((bal, i) => bal.mul(prices[i]))
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@reserve-protocol/dtf-rebalance-lib",
3
- "version": "0.2.7",
3
+ "version": "0.2.9",
4
4
  "description": "Rebalancing library for DTFs in typescript",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.js",