@nadohq/shared 0.65.0 → 0.67.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/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/{interest-BEsEmpAy.d.cts → interest-BN4bYdpY.d.cts} +3 -1
- package/dist/{interest-BEsEmpAy.d.cts.map → interest-BN4bYdpY.d.cts.map} +1 -1
- package/dist/{interest-DUfNVtPJ.d.ts → interest-CcDkLJnv.d.ts} +3 -1
- package/dist/{interest-DUfNVtPJ.d.ts.map → interest-CcDkLJnv.d.ts.map} +1 -1
- package/dist/{toIntegerString-CyhOUxbE.d.ts → toIntegerString-DfbD1c3k.d.ts} +3 -2
- package/dist/toIntegerString-DfbD1c3k.d.ts.map +1 -0
- package/dist/{toIntegerString-BUESqiY1.d.cts → toIntegerString-XmD3bQt-.d.cts} +3 -2
- package/dist/toIntegerString-XmD3bQt-.d.cts.map +1 -0
- package/dist/utils/index.d.cts +2 -2
- package/dist/utils/index.d.ts +2 -2
- package/dist/utils/interest.cjs +17 -3
- package/dist/utils/interest.cjs.map +1 -1
- package/dist/utils/interest.d.cts +1 -1
- package/dist/utils/interest.d.ts +1 -1
- package/dist/utils/interest.js +17 -3
- package/dist/utils/interest.js.map +1 -1
- package/dist/utils/math/index.d.cts +1 -1
- package/dist/utils/math/index.d.ts +1 -1
- package/dist/utils/math/toIntegerString.cjs +2 -1
- package/dist/utils/math/toIntegerString.cjs.map +1 -1
- package/dist/utils/math/toIntegerString.d.cts +1 -1
- package/dist/utils/math/toIntegerString.d.ts +1 -1
- package/dist/utils/math/toIntegerString.js +2 -1
- package/dist/utils/math/toIntegerString.js.map +1 -1
- package/package.json +2 -2
- package/src/utils/interest.test.ts +123 -0
- package/src/utils/interest.ts +43 -8
- package/src/utils/math/toIntegerString.ts +2 -1
- package/dist/toIntegerString-BUESqiY1.d.cts.map +0 -1
- package/dist/toIntegerString-CyhOUxbE.d.ts.map +0 -1
package/dist/index.d.cts
CHANGED
|
@@ -24,7 +24,7 @@ import { t as clampBigNumber } from "./clamp-D9lICt7X.cjs";
|
|
|
24
24
|
import { n as addDecimals, r as removeDecimals, t as NADO_PRODUCT_DECIMALS } from "./decimalAdjustment-DCwilVOA.cjs";
|
|
25
25
|
import { t as sumBigNumberBy } from "./sumBigNumberBy-BvDeov4-.cjs";
|
|
26
26
|
import { t as toBigInt } from "./toBigInt-BDiOjNl-.cjs";
|
|
27
|
-
import { t as toIntegerString } from "./toIntegerString-
|
|
27
|
+
import { t as toIntegerString } from "./toIntegerString-XmD3bQt-.cjs";
|
|
28
28
|
import { t as OrderExecutionType } from "./OrderExecutionType-5C8Yad5R.cjs";
|
|
29
29
|
import { a as OrderAppendixTwapFields, i as OrderAppendixTriggerType, n as OrderAppendixBuilderFields, r as OrderAppendixIsolatedFields, t as OrderAppendix } from "./orderAppendixTypes-BUU6xlgS.cjs";
|
|
30
30
|
import { t as SignatureParams } from "./signatureTypes-3nTqmq1y.cjs";
|
|
@@ -41,7 +41,7 @@ import { t as WalletNotProvidedError } from "./WalletNotProvidedError-Ba9SiWnP.c
|
|
|
41
41
|
import { t as getNadoClientTypeHeaders } from "./getNadoClientTypeHeaders-E-LLWL7-.cjs";
|
|
42
42
|
import { t as getValidatedAddress } from "./getValidatedAddress-CEK3POgJ.cjs";
|
|
43
43
|
import { t as getValidatedHex } from "./getValidatedHex-DIJn4BMz.cjs";
|
|
44
|
-
import { a as calcTotalDeposited, i as calcTotalBorrowed, n as calcBorrowRatePerSecond, o as calcUtilizationRatio, r as calcRealizedDepositRateForTimeRange, t as calcBorrowRateForTimeRange } from "./interest-
|
|
44
|
+
import { a as calcTotalDeposited, i as calcTotalBorrowed, n as calcBorrowRatePerSecond, o as calcUtilizationRatio, r as calcRealizedDepositRateForTimeRange, t as calcBorrowRateForTimeRange } from "./interest-BN4bYdpY.cjs";
|
|
45
45
|
import { t as isWriteableContract } from "./isWriteableContract-C9lzUJ7s.cjs";
|
|
46
46
|
import { t as mapValues } from "./mapValues-H9D_81GC.cjs";
|
|
47
47
|
import { n as unpackTwapOrderAppendixValue, t as packTwapOrderAppendixValue } from "./appendixTwapValue-DNudvbI5.cjs";
|
package/dist/index.d.ts
CHANGED
|
@@ -24,7 +24,7 @@ import { t as clampBigNumber } from "./clamp-D9lICt7X.js";
|
|
|
24
24
|
import { n as addDecimals, r as removeDecimals, t as NADO_PRODUCT_DECIMALS } from "./decimalAdjustment-pLqKqD8x.js";
|
|
25
25
|
import { t as sumBigNumberBy } from "./sumBigNumberBy-BvDeov4-.js";
|
|
26
26
|
import { t as toBigInt } from "./toBigInt-CBRk3mgz.js";
|
|
27
|
-
import { t as toIntegerString } from "./toIntegerString-
|
|
27
|
+
import { t as toIntegerString } from "./toIntegerString-DfbD1c3k.js";
|
|
28
28
|
import { t as OrderExecutionType } from "./OrderExecutionType-5C8Yad5R.js";
|
|
29
29
|
import { a as OrderAppendixTwapFields, i as OrderAppendixTriggerType, n as OrderAppendixBuilderFields, r as OrderAppendixIsolatedFields, t as OrderAppendix } from "./orderAppendixTypes-pxsI3qLs.js";
|
|
30
30
|
import { t as SignatureParams } from "./signatureTypes-3nTqmq1y.js";
|
|
@@ -41,7 +41,7 @@ import { t as WalletNotProvidedError } from "./WalletNotProvidedError-Ba9SiWnP.j
|
|
|
41
41
|
import { t as getNadoClientTypeHeaders } from "./getNadoClientTypeHeaders-E-LLWL7-.js";
|
|
42
42
|
import { t as getValidatedAddress } from "./getValidatedAddress-CEK3POgJ.js";
|
|
43
43
|
import { t as getValidatedHex } from "./getValidatedHex-DIJn4BMz.js";
|
|
44
|
-
import { a as calcTotalDeposited, i as calcTotalBorrowed, n as calcBorrowRatePerSecond, o as calcUtilizationRatio, r as calcRealizedDepositRateForTimeRange, t as calcBorrowRateForTimeRange } from "./interest-
|
|
44
|
+
import { a as calcTotalDeposited, i as calcTotalBorrowed, n as calcBorrowRatePerSecond, o as calcUtilizationRatio, r as calcRealizedDepositRateForTimeRange, t as calcBorrowRateForTimeRange } from "./interest-CcDkLJnv.js";
|
|
45
45
|
import { t as isWriteableContract } from "./isWriteableContract-X1rD5O8a.js";
|
|
46
46
|
import { t as mapValues } from "./mapValues-H9D_81GC.js";
|
|
47
47
|
import { n as unpackTwapOrderAppendixValue, t as packTwapOrderAppendixValue } from "./appendixTwapValue-Bb2ukj7A.js";
|
|
@@ -37,6 +37,7 @@ declare function calcBorrowRatePerSecond(product: SpotProduct): BigNumber;
|
|
|
37
37
|
*
|
|
38
38
|
* @param product Spot product
|
|
39
39
|
* @param seconds Number of seconds for the time period
|
|
40
|
+
* @param minDepositRate Annual min deposit rate, as stored in the product config
|
|
40
41
|
*/
|
|
41
42
|
declare function calcBorrowRateForTimeRange(product: SpotProduct, seconds: BigNumberish, minDepositRate: BigNumberish): BigNumber;
|
|
42
43
|
/**
|
|
@@ -45,8 +46,9 @@ declare function calcBorrowRateForTimeRange(product: SpotProduct, seconds: BigNu
|
|
|
45
46
|
* @param product Spot product
|
|
46
47
|
* @param seconds Number of seconds for the time period
|
|
47
48
|
* @param interestFeeFrac Fraction of paid borrower interest that is paid as a fee (0.2 = 20% fee)
|
|
49
|
+
* @param minDepositRate Annual min deposit rate, as stored in the product config
|
|
48
50
|
*/
|
|
49
51
|
declare function calcRealizedDepositRateForTimeRange(product: SpotProduct, seconds: BigNumberish, interestFeeFrac: BigNumberish, minDepositRate: BigNumberish): BigNumber;
|
|
50
52
|
//#endregion
|
|
51
53
|
export { calcTotalDeposited as a, calcTotalBorrowed as i, calcBorrowRatePerSecond as n, calcUtilizationRatio as o, calcRealizedDepositRateForTimeRange as r, calcBorrowRateForTimeRange as t };
|
|
52
|
-
//# sourceMappingURL=interest-
|
|
54
|
+
//# sourceMappingURL=interest-BN4bYdpY.d.cts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"interest-
|
|
1
|
+
{"version":3,"file":"interest-BN4bYdpY.d.cts","names":[],"sources":["../src/utils/src/utils/interest.ts"],"mappings":";;;;;;;;iBAQgB,iBAAA,CACd,sBAAA,EAAwB,YAAA,EACxB,8BAAA,EAAgC,YAAA,GAC/B,SAAA;;;;iBASa,kBAAA,CACd,uBAAA,EAAyB,YAAA,EACzB,+BAAA,EAAiC,YAAA,GAChC,SAAA;;;;;;iBAWa,oBAAA,CAAqB,OAAA,EAAS,WAAA,GAAW,SAAA;;;;AAvB7C;AASZ;;;;;;;;;;iBAmCgB,uBAAA,CAAwB,OAAA,EAAS,WAAA,GAAW,SAAA;;;;AAhChD;AAWZ;;;iBA6EgB,0BAAA,CACd,OAAA,EAAS,WAAA,EACT,OAAA,EAAS,YAAA,EACT,cAAA,EAAgB,YAAA,GAAY,SAAA;;;;;AAhF2B;AAqBzD;;;iBAoFgB,mCAAA,CACd,OAAA,EAAS,WAAA,EACT,OAAA,EAAS,YAAA,EACT,eAAA,EAAiB,YAAA,EACjB,cAAA,EAAgB,YAAA,GAAY,SAAA"}
|
|
@@ -37,6 +37,7 @@ declare function calcBorrowRatePerSecond(product: SpotProduct): BigNumber;
|
|
|
37
37
|
*
|
|
38
38
|
* @param product Spot product
|
|
39
39
|
* @param seconds Number of seconds for the time period
|
|
40
|
+
* @param minDepositRate Annual min deposit rate, as stored in the product config
|
|
40
41
|
*/
|
|
41
42
|
declare function calcBorrowRateForTimeRange(product: SpotProduct, seconds: BigNumberish, minDepositRate: BigNumberish): BigNumber;
|
|
42
43
|
/**
|
|
@@ -45,8 +46,9 @@ declare function calcBorrowRateForTimeRange(product: SpotProduct, seconds: BigNu
|
|
|
45
46
|
* @param product Spot product
|
|
46
47
|
* @param seconds Number of seconds for the time period
|
|
47
48
|
* @param interestFeeFrac Fraction of paid borrower interest that is paid as a fee (0.2 = 20% fee)
|
|
49
|
+
* @param minDepositRate Annual min deposit rate, as stored in the product config
|
|
48
50
|
*/
|
|
49
51
|
declare function calcRealizedDepositRateForTimeRange(product: SpotProduct, seconds: BigNumberish, interestFeeFrac: BigNumberish, minDepositRate: BigNumberish): BigNumber;
|
|
50
52
|
//#endregion
|
|
51
53
|
export { calcTotalDeposited as a, calcTotalBorrowed as i, calcBorrowRatePerSecond as n, calcUtilizationRatio as o, calcRealizedDepositRateForTimeRange as r, calcBorrowRateForTimeRange as t };
|
|
52
|
-
//# sourceMappingURL=interest-
|
|
54
|
+
//# sourceMappingURL=interest-CcDkLJnv.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"interest-
|
|
1
|
+
{"version":3,"file":"interest-CcDkLJnv.d.ts","names":[],"sources":["../src/utils/src/utils/interest.ts"],"mappings":";;;;;;;;iBAQgB,iBAAA,CACd,sBAAA,EAAwB,YAAA,EACxB,8BAAA,EAAgC,YAAA,GAC/B,SAAA;;;;iBASa,kBAAA,CACd,uBAAA,EAAyB,YAAA,EACzB,+BAAA,EAAiC,YAAA,GAChC,SAAA;;;;;;iBAWa,oBAAA,CAAqB,OAAA,EAAS,WAAA,GAAW,SAAA;;;;AAvB7C;AASZ;;;;;;;;;;iBAmCgB,uBAAA,CAAwB,OAAA,EAAS,WAAA,GAAW,SAAA;;;;AAhChD;AAWZ;;;iBA6EgB,0BAAA,CACd,OAAA,EAAS,WAAA,EACT,OAAA,EAAS,YAAA,EACT,cAAA,EAAgB,YAAA,GAAY,SAAA;;;;;AAhF2B;AAqBzD;;;iBAoFgB,mCAAA,CACd,OAAA,EAAS,WAAA,EACT,OAAA,EAAS,YAAA,EACT,eAAA,EAAiB,YAAA,EACjB,cAAA,EAAgB,YAAA,GAAY,SAAA"}
|
|
@@ -2,11 +2,12 @@ import { t as BigNumberish } from "./bigNumber-BqgJEjFs.js";
|
|
|
2
2
|
|
|
3
3
|
//#region src/utils/math/toIntegerString.d.ts
|
|
4
4
|
/**
|
|
5
|
-
* Converts a BigNumberish value to string
|
|
5
|
+
* Converts a BigNumberish value to an integer string, rounding any fractional
|
|
6
|
+
* part to the nearest integer (bignumber.js `.toFixed(0)` default rounding mode).
|
|
6
7
|
*
|
|
7
8
|
* @param val
|
|
8
9
|
*/
|
|
9
10
|
declare function toIntegerString(val: BigNumberish): string;
|
|
10
11
|
//#endregion
|
|
11
12
|
export { toIntegerString as t };
|
|
12
|
-
//# sourceMappingURL=toIntegerString-
|
|
13
|
+
//# sourceMappingURL=toIntegerString-DfbD1c3k.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"toIntegerString-DfbD1c3k.d.ts","names":[],"sources":["../src/utils/math/src/utils/math/toIntegerString.ts"],"mappings":";;;;;AAQA;;;;iBAAgB,eAAA,CAAgB,GAAiB,EAAZ,YAAY"}
|
|
@@ -2,11 +2,12 @@ import { t as BigNumberish } from "./bigNumber-BqgJEjFs.cjs";
|
|
|
2
2
|
|
|
3
3
|
//#region src/utils/math/toIntegerString.d.ts
|
|
4
4
|
/**
|
|
5
|
-
* Converts a BigNumberish value to string
|
|
5
|
+
* Converts a BigNumberish value to an integer string, rounding any fractional
|
|
6
|
+
* part to the nearest integer (bignumber.js `.toFixed(0)` default rounding mode).
|
|
6
7
|
*
|
|
7
8
|
* @param val
|
|
8
9
|
*/
|
|
9
10
|
declare function toIntegerString(val: BigNumberish): string;
|
|
10
11
|
//#endregion
|
|
11
12
|
export { toIntegerString as t };
|
|
12
|
-
//# sourceMappingURL=toIntegerString-
|
|
13
|
+
//# sourceMappingURL=toIntegerString-XmD3bQt-.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"toIntegerString-XmD3bQt-.d.cts","names":[],"sources":["../src/utils/math/src/utils/math/toIntegerString.ts"],"mappings":";;;;;AAQA;;;;iBAAgB,eAAA,CAAgB,GAAiB,EAAZ,YAAY"}
|
package/dist/utils/index.d.cts
CHANGED
|
@@ -4,7 +4,7 @@ import { t as clampBigNumber } from "../clamp-D9lICt7X.cjs";
|
|
|
4
4
|
import { n as addDecimals, r as removeDecimals, t as NADO_PRODUCT_DECIMALS } from "../decimalAdjustment-DCwilVOA.cjs";
|
|
5
5
|
import { t as sumBigNumberBy } from "../sumBigNumberBy-BvDeov4-.cjs";
|
|
6
6
|
import { t as toBigInt } from "../toBigInt-BDiOjNl-.cjs";
|
|
7
|
-
import { t as toIntegerString } from "../toIntegerString-
|
|
7
|
+
import { t as toIntegerString } from "../toIntegerString-XmD3bQt-.cjs";
|
|
8
8
|
import { n as asyncResult, t as AsyncResult } from "../asyncResult-BL5RY5sb.cjs";
|
|
9
9
|
import { n as calcPerpBalanceValue, r as calcSpotBalanceValue, t as calcPerpBalanceNotionalValue } from "../balanceValue-1rQfF7-m.cjs";
|
|
10
10
|
import { a as subaccountToBytes32, i as subaccountNameToBytes12, n as subaccountFromHex, o as subaccountToHex, r as subaccountNameBytesToStr, t as subaccountFromBytes32 } from "../bytes32-RGr1nYVD.cjs";
|
|
@@ -13,7 +13,7 @@ import { t as WalletNotProvidedError } from "../WalletNotProvidedError-Ba9SiWnP.
|
|
|
13
13
|
import { t as getNadoClientTypeHeaders } from "../getNadoClientTypeHeaders-E-LLWL7-.cjs";
|
|
14
14
|
import { t as getValidatedAddress } from "../getValidatedAddress-CEK3POgJ.cjs";
|
|
15
15
|
import { t as getValidatedHex } from "../getValidatedHex-DIJn4BMz.cjs";
|
|
16
|
-
import { a as calcTotalDeposited, i as calcTotalBorrowed, n as calcBorrowRatePerSecond, o as calcUtilizationRatio, r as calcRealizedDepositRateForTimeRange, t as calcBorrowRateForTimeRange } from "../interest-
|
|
16
|
+
import { a as calcTotalDeposited, i as calcTotalBorrowed, n as calcBorrowRatePerSecond, o as calcUtilizationRatio, r as calcRealizedDepositRateForTimeRange, t as calcBorrowRateForTimeRange } from "../interest-BN4bYdpY.cjs";
|
|
17
17
|
import { t as isWriteableContract } from "../isWriteableContract-C9lzUJ7s.cjs";
|
|
18
18
|
import { t as mapValues } from "../mapValues-H9D_81GC.cjs";
|
|
19
19
|
import { n as unpackTwapOrderAppendixValue, t as packTwapOrderAppendixValue } from "../appendixTwapValue-DNudvbI5.cjs";
|
package/dist/utils/index.d.ts
CHANGED
|
@@ -4,7 +4,7 @@ import { t as clampBigNumber } from "../clamp-D9lICt7X.js";
|
|
|
4
4
|
import { n as addDecimals, r as removeDecimals, t as NADO_PRODUCT_DECIMALS } from "../decimalAdjustment-pLqKqD8x.js";
|
|
5
5
|
import { t as sumBigNumberBy } from "../sumBigNumberBy-BvDeov4-.js";
|
|
6
6
|
import { t as toBigInt } from "../toBigInt-CBRk3mgz.js";
|
|
7
|
-
import { t as toIntegerString } from "../toIntegerString-
|
|
7
|
+
import { t as toIntegerString } from "../toIntegerString-DfbD1c3k.js";
|
|
8
8
|
import { n as asyncResult, t as AsyncResult } from "../asyncResult-BL5RY5sb.js";
|
|
9
9
|
import { n as calcPerpBalanceValue, r as calcSpotBalanceValue, t as calcPerpBalanceNotionalValue } from "../balanceValue-BYBNPNZD.js";
|
|
10
10
|
import { a as subaccountToBytes32, i as subaccountNameToBytes12, n as subaccountFromHex, o as subaccountToHex, r as subaccountNameBytesToStr, t as subaccountFromBytes32 } from "../bytes32-DsSNgVyG.js";
|
|
@@ -13,7 +13,7 @@ import { t as WalletNotProvidedError } from "../WalletNotProvidedError-Ba9SiWnP.
|
|
|
13
13
|
import { t as getNadoClientTypeHeaders } from "../getNadoClientTypeHeaders-E-LLWL7-.js";
|
|
14
14
|
import { t as getValidatedAddress } from "../getValidatedAddress-CEK3POgJ.js";
|
|
15
15
|
import { t as getValidatedHex } from "../getValidatedHex-DIJn4BMz.js";
|
|
16
|
-
import { a as calcTotalDeposited, i as calcTotalBorrowed, n as calcBorrowRatePerSecond, o as calcUtilizationRatio, r as calcRealizedDepositRateForTimeRange, t as calcBorrowRateForTimeRange } from "../interest-
|
|
16
|
+
import { a as calcTotalDeposited, i as calcTotalBorrowed, n as calcBorrowRatePerSecond, o as calcUtilizationRatio, r as calcRealizedDepositRateForTimeRange, t as calcBorrowRateForTimeRange } from "../interest-CcDkLJnv.js";
|
|
17
17
|
import { t as isWriteableContract } from "../isWriteableContract-X1rD5O8a.js";
|
|
18
18
|
import { t as mapValues } from "../mapValues-H9D_81GC.js";
|
|
19
19
|
import { n as unpackTwapOrderAppendixValue, t as packTwapOrderAppendixValue } from "../appendixTwapValue-Bb2ukj7A.js";
|
package/dist/utils/interest.cjs
CHANGED
|
@@ -55,13 +55,25 @@ function calcBorrowRatePerSecond(product) {
|
|
|
55
55
|
return annualRate.div(31536e3);
|
|
56
56
|
}
|
|
57
57
|
/**
|
|
58
|
+
* Compounds an annual min deposit rate over a period, giving the multiplier
|
|
59
|
+
* `SpotEngine._updateState` applies to both the borrow and the deposit
|
|
60
|
+
* multiplier: `(1 + minDepositRate / secondsPerYear) ** seconds`.
|
|
61
|
+
*
|
|
62
|
+
* @param minDepositRate Annual min deposit rate, as stored in the product config
|
|
63
|
+
* @param seconds Number of seconds for the time period
|
|
64
|
+
*/
|
|
65
|
+
function calcMinDepositRateMultiplier(minDepositRate, seconds) {
|
|
66
|
+
return (1 + require_utils_math_bigNumber.toBigNumber(minDepositRate).div(31536e3).toNumber()) ** require_utils_math_bigNumber.toBigNumber(seconds).toNumber();
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
58
69
|
* Calculates borrower interest rate compounded for a period of time.
|
|
59
70
|
*
|
|
60
71
|
* @param product Spot product
|
|
61
72
|
* @param seconds Number of seconds for the time period
|
|
73
|
+
* @param minDepositRate Annual min deposit rate, as stored in the product config
|
|
62
74
|
*/
|
|
63
75
|
function calcBorrowRateForTimeRange(product, seconds, minDepositRate) {
|
|
64
|
-
return require_utils_math_bigNumber.toBigNumber(calcBorrowRatePerSecond(product).plus(1).toNumber() ** require_utils_math_bigNumber.toBigNumber(seconds).toNumber()
|
|
76
|
+
return require_utils_math_bigNumber.toBigNumber(calcBorrowRatePerSecond(product).plus(1).toNumber() ** require_utils_math_bigNumber.toBigNumber(seconds).toNumber() * calcMinDepositRateMultiplier(minDepositRate, seconds) - 1);
|
|
65
77
|
}
|
|
66
78
|
/**
|
|
67
79
|
* Calculate depositor interest rate compounded for a period of time.
|
|
@@ -69,11 +81,13 @@ function calcBorrowRateForTimeRange(product, seconds, minDepositRate) {
|
|
|
69
81
|
* @param product Spot product
|
|
70
82
|
* @param seconds Number of seconds for the time period
|
|
71
83
|
* @param interestFeeFrac Fraction of paid borrower interest that is paid as a fee (0.2 = 20% fee)
|
|
84
|
+
* @param minDepositRate Annual min deposit rate, as stored in the product config
|
|
72
85
|
*/
|
|
73
86
|
function calcRealizedDepositRateForTimeRange(product, seconds, interestFeeFrac, minDepositRate) {
|
|
87
|
+
const minDepositRateMultiplier = calcMinDepositRateMultiplier(minDepositRate, seconds);
|
|
74
88
|
const utilization = calcUtilizationRatio(product);
|
|
75
|
-
if (utilization.eq(0)) return require_utils_math_bigNumber.toBigNumber(
|
|
76
|
-
return utilization.times(calcBorrowRateForTimeRange(product, seconds, require_utils_math_bigNumber.toBigNumber(0))).times(require_utils_math_BigNumbers.BigNumbers.ONE.minus(require_utils_math_bigNumber.toBigNumber(interestFeeFrac))).plus(
|
|
89
|
+
if (utilization.eq(0)) return require_utils_math_bigNumber.toBigNumber(minDepositRateMultiplier - 1);
|
|
90
|
+
return utilization.times(calcBorrowRateForTimeRange(product, seconds, require_utils_math_bigNumber.toBigNumber(0))).times(require_utils_math_BigNumbers.BigNumbers.ONE.minus(require_utils_math_bigNumber.toBigNumber(interestFeeFrac))).plus(require_utils_math_BigNumbers.BigNumbers.ONE).times(minDepositRateMultiplier).minus(require_utils_math_BigNumbers.BigNumbers.ONE);
|
|
77
91
|
}
|
|
78
92
|
//#endregion
|
|
79
93
|
exports.calcBorrowRateForTimeRange = calcBorrowRateForTimeRange;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"interest.cjs","names":["toBigNumber","removeDecimals","BigNumbers"],"sources":["../../src/utils/interest.ts"],"sourcesContent":["import BigNumber from 'bignumber.js';\nimport { SpotProduct } from '../types/productTypes';\nimport { BigNumberish, BigNumbers, removeDecimals, toBigNumber } from './math';\nimport { TimeInSeconds } from './time';\n\n/**\n * Calculate amount total borrowed for a product\n */\nexport function calcTotalBorrowed(\n totalBorrowsNormalized: BigNumberish,\n cumulativeBorrowsMultiplierX18: BigNumberish,\n): BigNumber {\n return toBigNumber(totalBorrowsNormalized).multipliedBy(\n removeDecimals(cumulativeBorrowsMultiplierX18),\n );\n}\n\n/**\n * Calculate amount total deposited for a product.\n */\nexport function calcTotalDeposited(\n totalDepositsNormalized: BigNumberish,\n cumulativeDepositsMultiplierX18: BigNumberish,\n): BigNumber {\n return toBigNumber(totalDepositsNormalized).multipliedBy(\n removeDecimals(cumulativeDepositsMultiplierX18),\n );\n}\n\n/**\n * Calculates utilization ratio = abs(total borrowed / total deposited)\n *\n * @param product Spot product\n */\nexport function calcUtilizationRatio(product: SpotProduct) {\n if (product.totalDeposited.eq(0) || product.totalBorrowed.eq(0)) {\n return toBigNumber(0);\n }\n return product.totalBorrowed.abs().div(product.totalDeposited);\n}\n\n/**\n * Calculates per-second borrow interest rate for a product. For example, a returned rate of 0.1 indicates 10% borrower\n * interest. The calculation for interest rate is as follows:\n *\n * If utilization ratio > inflection:\n * annual rate = (utilization ratio - inflection) / (1 - inflection) * interestLargeCap + interestFloor + interestSmallCap\n *\n * If utilization ratio <= inflection:\n * annual rate = utilization ratio * interestSmallCap / inflection + interestFloor\n *\n * The returned rate is annual rate / 31536000 seconds per year.\n *\n * @param product Spot product\n */\nexport function calcBorrowRatePerSecond(product: SpotProduct) {\n const {\n interestFloor,\n interestInflectionUtil,\n interestSmallCap,\n interestLargeCap,\n } = product;\n const utilization = calcUtilizationRatio(product);\n if (utilization.eq(0)) {\n return toBigNumber(0);\n }\n const pastInflection = utilization.gt(interestInflectionUtil);\n\n let annualRate: BigNumber;\n if (pastInflection) {\n const utilizationTerm = interestLargeCap.times(\n toBigNumber(utilization)\n .minus(interestInflectionUtil)\n .div(BigNumbers.ONE.minus(interestInflectionUtil)),\n );\n annualRate = interestFloor.plus(interestSmallCap).plus(utilizationTerm);\n } else {\n const utilizationTerm = utilization\n .div(interestInflectionUtil)\n .times(interestSmallCap);\n annualRate = interestFloor.plus(utilizationTerm);\n }\n\n return annualRate.div(TimeInSeconds.YEAR);\n}\n\n/**\n * Calculates borrower interest rate compounded for a period of time.\n *\n * @param product Spot product\n * @param seconds Number of seconds for the time period\n */\nexport function calcBorrowRateForTimeRange(\n product: SpotProduct,\n seconds: BigNumberish,\n minDepositRate: BigNumberish,\n) {\n const borrowRatePerSecond = calcBorrowRatePerSecond(product);\n\n // Convert to number for this, with some loss of precision, but using `.pow()` causes us to hit browser resource limits\n const
|
|
1
|
+
{"version":3,"file":"interest.cjs","names":["toBigNumber","removeDecimals","BigNumbers"],"sources":["../../src/utils/interest.ts"],"sourcesContent":["import BigNumber from 'bignumber.js';\nimport { SpotProduct } from '../types/productTypes';\nimport { BigNumberish, BigNumbers, removeDecimals, toBigNumber } from './math';\nimport { TimeInSeconds } from './time';\n\n/**\n * Calculate amount total borrowed for a product\n */\nexport function calcTotalBorrowed(\n totalBorrowsNormalized: BigNumberish,\n cumulativeBorrowsMultiplierX18: BigNumberish,\n): BigNumber {\n return toBigNumber(totalBorrowsNormalized).multipliedBy(\n removeDecimals(cumulativeBorrowsMultiplierX18),\n );\n}\n\n/**\n * Calculate amount total deposited for a product.\n */\nexport function calcTotalDeposited(\n totalDepositsNormalized: BigNumberish,\n cumulativeDepositsMultiplierX18: BigNumberish,\n): BigNumber {\n return toBigNumber(totalDepositsNormalized).multipliedBy(\n removeDecimals(cumulativeDepositsMultiplierX18),\n );\n}\n\n/**\n * Calculates utilization ratio = abs(total borrowed / total deposited)\n *\n * @param product Spot product\n */\nexport function calcUtilizationRatio(product: SpotProduct) {\n if (product.totalDeposited.eq(0) || product.totalBorrowed.eq(0)) {\n return toBigNumber(0);\n }\n return product.totalBorrowed.abs().div(product.totalDeposited);\n}\n\n/**\n * Calculates per-second borrow interest rate for a product. For example, a returned rate of 0.1 indicates 10% borrower\n * interest. The calculation for interest rate is as follows:\n *\n * If utilization ratio > inflection:\n * annual rate = (utilization ratio - inflection) / (1 - inflection) * interestLargeCap + interestFloor + interestSmallCap\n *\n * If utilization ratio <= inflection:\n * annual rate = utilization ratio * interestSmallCap / inflection + interestFloor\n *\n * The returned rate is annual rate / 31536000 seconds per year.\n *\n * @param product Spot product\n */\nexport function calcBorrowRatePerSecond(product: SpotProduct) {\n const {\n interestFloor,\n interestInflectionUtil,\n interestSmallCap,\n interestLargeCap,\n } = product;\n const utilization = calcUtilizationRatio(product);\n if (utilization.eq(0)) {\n return toBigNumber(0);\n }\n const pastInflection = utilization.gt(interestInflectionUtil);\n\n let annualRate: BigNumber;\n if (pastInflection) {\n const utilizationTerm = interestLargeCap.times(\n toBigNumber(utilization)\n .minus(interestInflectionUtil)\n .div(BigNumbers.ONE.minus(interestInflectionUtil)),\n );\n annualRate = interestFloor.plus(interestSmallCap).plus(utilizationTerm);\n } else {\n const utilizationTerm = utilization\n .div(interestInflectionUtil)\n .times(interestSmallCap);\n annualRate = interestFloor.plus(utilizationTerm);\n }\n\n return annualRate.div(TimeInSeconds.YEAR);\n}\n\n/**\n * Compounds an annual min deposit rate over a period, giving the multiplier\n * `SpotEngine._updateState` applies to both the borrow and the deposit\n * multiplier: `(1 + minDepositRate / secondsPerYear) ** seconds`.\n *\n * @param minDepositRate Annual min deposit rate, as stored in the product config\n * @param seconds Number of seconds for the time period\n */\nfunction calcMinDepositRateMultiplier(\n minDepositRate: BigNumberish,\n seconds: BigNumberish,\n): number {\n const perSecond = toBigNumber(minDepositRate)\n .div(TimeInSeconds.YEAR)\n .toNumber();\n return (1 + perSecond) ** toBigNumber(seconds).toNumber();\n}\n\n/**\n * Calculates borrower interest rate compounded for a period of time.\n *\n * @param product Spot product\n * @param seconds Number of seconds for the time period\n * @param minDepositRate Annual min deposit rate, as stored in the product config\n */\nexport function calcBorrowRateForTimeRange(\n product: SpotProduct,\n seconds: BigNumberish,\n minDepositRate: BigNumberish,\n) {\n const borrowRatePerSecond = calcBorrowRatePerSecond(product);\n\n // Convert to number for this, with some loss of precision, but using `.pow()` causes us to hit browser resource limits\n const borrowRateMultiplier =\n borrowRatePerSecond.plus(1).toNumber() ** toBigNumber(seconds).toNumber();\n // The engine multiplies the borrow multiplier by the min deposit multiplier,\n // so the min deposit rate has to be compounded over the same period rather\n // than added as an annual figure.\n return toBigNumber(\n borrowRateMultiplier *\n calcMinDepositRateMultiplier(minDepositRate, seconds) -\n 1,\n );\n}\n\n/**\n * Calculate depositor interest rate compounded for a period of time.\n *\n * @param product Spot product\n * @param seconds Number of seconds for the time period\n * @param interestFeeFrac Fraction of paid borrower interest that is paid as a fee (0.2 = 20% fee)\n * @param minDepositRate Annual min deposit rate, as stored in the product config\n */\nexport function calcRealizedDepositRateForTimeRange(\n product: SpotProduct,\n seconds: BigNumberish,\n interestFeeFrac: BigNumberish,\n minDepositRate: BigNumberish,\n) {\n const minDepositRateMultiplier = calcMinDepositRateMultiplier(\n minDepositRate,\n seconds,\n );\n const utilization = calcUtilizationRatio(product);\n // Nothing is borrowed, so no interest is paid — but the engine still applies\n // the min deposit multiplier, which is the whole point of a rate floor.\n if (utilization.eq(0)) {\n return toBigNumber(minDepositRateMultiplier - 1);\n }\n const realizedDepositRate = utilization\n .times(calcBorrowRateForTimeRange(product, seconds, toBigNumber(0)))\n .times(BigNumbers.ONE.minus(toBigNumber(interestFeeFrac)));\n return realizedDepositRate\n .plus(BigNumbers.ONE)\n .times(minDepositRateMultiplier)\n .minus(BigNumbers.ONE);\n}\n"],"mappings":";;;;;;;;;AAQA,SAAgB,kBACd,wBACA,gCACW;CACX,OAAOA,6BAAAA,YAAY,sBAAsB,EAAE,aACzCC,qCAAAA,eAAe,8BAA8B,CAC/C;AACF;;;;AAKA,SAAgB,mBACd,yBACA,iCACW;CACX,OAAOD,6BAAAA,YAAY,uBAAuB,EAAE,aAC1CC,qCAAAA,eAAe,+BAA+B,CAChD;AACF;;;;;;AAOA,SAAgB,qBAAqB,SAAsB;CACzD,IAAI,QAAQ,eAAe,GAAG,CAAC,KAAK,QAAQ,cAAc,GAAG,CAAC,GAC5D,OAAOD,6BAAAA,YAAY,CAAC;CAEtB,OAAO,QAAQ,cAAc,IAAI,EAAE,IAAI,QAAQ,cAAc;AAC/D;;;;;;;;;;;;;;;AAgBA,SAAgB,wBAAwB,SAAsB;CAC5D,MAAM,EACJ,eACA,wBACA,kBACA,qBACE;CACJ,MAAM,cAAc,qBAAqB,OAAO;CAChD,IAAI,YAAY,GAAG,CAAC,GAClB,OAAOA,6BAAAA,YAAY,CAAC;CAEtB,MAAM,iBAAiB,YAAY,GAAG,sBAAsB;CAE5D,IAAI;CACJ,IAAI,gBAAgB;EAClB,MAAM,kBAAkB,iBAAiB,MACvCA,6BAAAA,YAAY,WAAW,EACpB,MAAM,sBAAsB,EAC5B,IAAIE,8BAAAA,WAAW,IAAI,MAAM,sBAAsB,CAAC,CACrD;EACA,aAAa,cAAc,KAAK,gBAAgB,EAAE,KAAK,eAAe;CACxE,OAAO;EACL,MAAM,kBAAkB,YACrB,IAAI,sBAAsB,EAC1B,MAAM,gBAAgB;EACzB,aAAa,cAAc,KAAK,eAAe;CACjD;CAEA,OAAO,WAAW,IAAA,OAAsB;AAC1C;;;;;;;;;AAUA,SAAS,6BACP,gBACA,SACQ;CAIR,QAAQ,IAHUF,6BAAAA,YAAY,cAAc,EACzC,IAAA,OAAsB,EACtB,SACiB,MAAMA,6BAAAA,YAAY,OAAO,EAAE,SAAS;AAC1D;;;;;;;;AASA,SAAgB,2BACd,SACA,SACA,gBACA;CASA,OAAOA,6BAAAA,YARqB,wBAAwB,OAIhC,EAAE,KAAK,CAAC,EAAE,SAAS,KAAKA,6BAAAA,YAAY,OAAO,EAAE,SAAS,IAMtE,6BAA6B,gBAAgB,OAAO,IACpD,CACJ;AACF;;;;;;;;;AAUA,SAAgB,oCACd,SACA,SACA,iBACA,gBACA;CACA,MAAM,2BAA2B,6BAC/B,gBACA,OACF;CACA,MAAM,cAAc,qBAAqB,OAAO;CAGhD,IAAI,YAAY,GAAG,CAAC,GAClB,OAAOA,6BAAAA,YAAY,2BAA2B,CAAC;CAKjD,OAH4B,YACzB,MAAM,2BAA2B,SAAS,SAASA,6BAAAA,YAAY,CAAC,CAAC,CAAC,EAClE,MAAME,8BAAAA,WAAW,IAAI,MAAMF,6BAAAA,YAAY,eAAe,CAAC,CACjC,EACtB,KAAKE,8BAAAA,WAAW,GAAG,EACnB,MAAM,wBAAwB,EAC9B,MAAMA,8BAAAA,WAAW,GAAG;AACzB"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as calcTotalDeposited, i as calcTotalBorrowed, n as calcBorrowRatePerSecond, o as calcUtilizationRatio, r as calcRealizedDepositRateForTimeRange, t as calcBorrowRateForTimeRange } from "../interest-
|
|
1
|
+
import { a as calcTotalDeposited, i as calcTotalBorrowed, n as calcBorrowRatePerSecond, o as calcUtilizationRatio, r as calcRealizedDepositRateForTimeRange, t as calcBorrowRateForTimeRange } from "../interest-BN4bYdpY.cjs";
|
|
2
2
|
export { calcBorrowRateForTimeRange, calcBorrowRatePerSecond, calcRealizedDepositRateForTimeRange, calcTotalBorrowed, calcTotalDeposited, calcUtilizationRatio };
|
package/dist/utils/interest.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as calcTotalDeposited, i as calcTotalBorrowed, n as calcBorrowRatePerSecond, o as calcUtilizationRatio, r as calcRealizedDepositRateForTimeRange, t as calcBorrowRateForTimeRange } from "../interest-
|
|
1
|
+
import { a as calcTotalDeposited, i as calcTotalBorrowed, n as calcBorrowRatePerSecond, o as calcUtilizationRatio, r as calcRealizedDepositRateForTimeRange, t as calcBorrowRateForTimeRange } from "../interest-CcDkLJnv.js";
|
|
2
2
|
export { calcBorrowRateForTimeRange, calcBorrowRatePerSecond, calcRealizedDepositRateForTimeRange, calcTotalBorrowed, calcTotalDeposited, calcUtilizationRatio };
|
package/dist/utils/interest.js
CHANGED
|
@@ -54,13 +54,25 @@ function calcBorrowRatePerSecond(product) {
|
|
|
54
54
|
return annualRate.div(31536e3);
|
|
55
55
|
}
|
|
56
56
|
/**
|
|
57
|
+
* Compounds an annual min deposit rate over a period, giving the multiplier
|
|
58
|
+
* `SpotEngine._updateState` applies to both the borrow and the deposit
|
|
59
|
+
* multiplier: `(1 + minDepositRate / secondsPerYear) ** seconds`.
|
|
60
|
+
*
|
|
61
|
+
* @param minDepositRate Annual min deposit rate, as stored in the product config
|
|
62
|
+
* @param seconds Number of seconds for the time period
|
|
63
|
+
*/
|
|
64
|
+
function calcMinDepositRateMultiplier(minDepositRate, seconds) {
|
|
65
|
+
return (1 + toBigNumber(minDepositRate).div(31536e3).toNumber()) ** toBigNumber(seconds).toNumber();
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
57
68
|
* Calculates borrower interest rate compounded for a period of time.
|
|
58
69
|
*
|
|
59
70
|
* @param product Spot product
|
|
60
71
|
* @param seconds Number of seconds for the time period
|
|
72
|
+
* @param minDepositRate Annual min deposit rate, as stored in the product config
|
|
61
73
|
*/
|
|
62
74
|
function calcBorrowRateForTimeRange(product, seconds, minDepositRate) {
|
|
63
|
-
return toBigNumber(calcBorrowRatePerSecond(product).plus(1).toNumber() ** toBigNumber(seconds).toNumber()
|
|
75
|
+
return toBigNumber(calcBorrowRatePerSecond(product).plus(1).toNumber() ** toBigNumber(seconds).toNumber() * calcMinDepositRateMultiplier(minDepositRate, seconds) - 1);
|
|
64
76
|
}
|
|
65
77
|
/**
|
|
66
78
|
* Calculate depositor interest rate compounded for a period of time.
|
|
@@ -68,11 +80,13 @@ function calcBorrowRateForTimeRange(product, seconds, minDepositRate) {
|
|
|
68
80
|
* @param product Spot product
|
|
69
81
|
* @param seconds Number of seconds for the time period
|
|
70
82
|
* @param interestFeeFrac Fraction of paid borrower interest that is paid as a fee (0.2 = 20% fee)
|
|
83
|
+
* @param minDepositRate Annual min deposit rate, as stored in the product config
|
|
71
84
|
*/
|
|
72
85
|
function calcRealizedDepositRateForTimeRange(product, seconds, interestFeeFrac, minDepositRate) {
|
|
86
|
+
const minDepositRateMultiplier = calcMinDepositRateMultiplier(minDepositRate, seconds);
|
|
73
87
|
const utilization = calcUtilizationRatio(product);
|
|
74
|
-
if (utilization.eq(0)) return toBigNumber(
|
|
75
|
-
return utilization.times(calcBorrowRateForTimeRange(product, seconds, toBigNumber(0))).times(BigNumbers.ONE.minus(toBigNumber(interestFeeFrac))).plus(
|
|
88
|
+
if (utilization.eq(0)) return toBigNumber(minDepositRateMultiplier - 1);
|
|
89
|
+
return utilization.times(calcBorrowRateForTimeRange(product, seconds, toBigNumber(0))).times(BigNumbers.ONE.minus(toBigNumber(interestFeeFrac))).plus(BigNumbers.ONE).times(minDepositRateMultiplier).minus(BigNumbers.ONE);
|
|
76
90
|
}
|
|
77
91
|
//#endregion
|
|
78
92
|
export { calcBorrowRateForTimeRange, calcBorrowRatePerSecond, calcRealizedDepositRateForTimeRange, calcTotalBorrowed, calcTotalDeposited, calcUtilizationRatio };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"interest.js","names":[],"sources":["../../src/utils/interest.ts"],"sourcesContent":["import BigNumber from 'bignumber.js';\nimport { SpotProduct } from '../types/productTypes';\nimport { BigNumberish, BigNumbers, removeDecimals, toBigNumber } from './math';\nimport { TimeInSeconds } from './time';\n\n/**\n * Calculate amount total borrowed for a product\n */\nexport function calcTotalBorrowed(\n totalBorrowsNormalized: BigNumberish,\n cumulativeBorrowsMultiplierX18: BigNumberish,\n): BigNumber {\n return toBigNumber(totalBorrowsNormalized).multipliedBy(\n removeDecimals(cumulativeBorrowsMultiplierX18),\n );\n}\n\n/**\n * Calculate amount total deposited for a product.\n */\nexport function calcTotalDeposited(\n totalDepositsNormalized: BigNumberish,\n cumulativeDepositsMultiplierX18: BigNumberish,\n): BigNumber {\n return toBigNumber(totalDepositsNormalized).multipliedBy(\n removeDecimals(cumulativeDepositsMultiplierX18),\n );\n}\n\n/**\n * Calculates utilization ratio = abs(total borrowed / total deposited)\n *\n * @param product Spot product\n */\nexport function calcUtilizationRatio(product: SpotProduct) {\n if (product.totalDeposited.eq(0) || product.totalBorrowed.eq(0)) {\n return toBigNumber(0);\n }\n return product.totalBorrowed.abs().div(product.totalDeposited);\n}\n\n/**\n * Calculates per-second borrow interest rate for a product. For example, a returned rate of 0.1 indicates 10% borrower\n * interest. The calculation for interest rate is as follows:\n *\n * If utilization ratio > inflection:\n * annual rate = (utilization ratio - inflection) / (1 - inflection) * interestLargeCap + interestFloor + interestSmallCap\n *\n * If utilization ratio <= inflection:\n * annual rate = utilization ratio * interestSmallCap / inflection + interestFloor\n *\n * The returned rate is annual rate / 31536000 seconds per year.\n *\n * @param product Spot product\n */\nexport function calcBorrowRatePerSecond(product: SpotProduct) {\n const {\n interestFloor,\n interestInflectionUtil,\n interestSmallCap,\n interestLargeCap,\n } = product;\n const utilization = calcUtilizationRatio(product);\n if (utilization.eq(0)) {\n return toBigNumber(0);\n }\n const pastInflection = utilization.gt(interestInflectionUtil);\n\n let annualRate: BigNumber;\n if (pastInflection) {\n const utilizationTerm = interestLargeCap.times(\n toBigNumber(utilization)\n .minus(interestInflectionUtil)\n .div(BigNumbers.ONE.minus(interestInflectionUtil)),\n );\n annualRate = interestFloor.plus(interestSmallCap).plus(utilizationTerm);\n } else {\n const utilizationTerm = utilization\n .div(interestInflectionUtil)\n .times(interestSmallCap);\n annualRate = interestFloor.plus(utilizationTerm);\n }\n\n return annualRate.div(TimeInSeconds.YEAR);\n}\n\n/**\n * Calculates borrower interest rate compounded for a period of time.\n *\n * @param product Spot product\n * @param seconds Number of seconds for the time period\n */\nexport function calcBorrowRateForTimeRange(\n product: SpotProduct,\n seconds: BigNumberish,\n minDepositRate: BigNumberish,\n) {\n const borrowRatePerSecond = calcBorrowRatePerSecond(product);\n\n // Convert to number for this, with some loss of precision, but using `.pow()` causes us to hit browser resource limits\n const
|
|
1
|
+
{"version":3,"file":"interest.js","names":[],"sources":["../../src/utils/interest.ts"],"sourcesContent":["import BigNumber from 'bignumber.js';\nimport { SpotProduct } from '../types/productTypes';\nimport { BigNumberish, BigNumbers, removeDecimals, toBigNumber } from './math';\nimport { TimeInSeconds } from './time';\n\n/**\n * Calculate amount total borrowed for a product\n */\nexport function calcTotalBorrowed(\n totalBorrowsNormalized: BigNumberish,\n cumulativeBorrowsMultiplierX18: BigNumberish,\n): BigNumber {\n return toBigNumber(totalBorrowsNormalized).multipliedBy(\n removeDecimals(cumulativeBorrowsMultiplierX18),\n );\n}\n\n/**\n * Calculate amount total deposited for a product.\n */\nexport function calcTotalDeposited(\n totalDepositsNormalized: BigNumberish,\n cumulativeDepositsMultiplierX18: BigNumberish,\n): BigNumber {\n return toBigNumber(totalDepositsNormalized).multipliedBy(\n removeDecimals(cumulativeDepositsMultiplierX18),\n );\n}\n\n/**\n * Calculates utilization ratio = abs(total borrowed / total deposited)\n *\n * @param product Spot product\n */\nexport function calcUtilizationRatio(product: SpotProduct) {\n if (product.totalDeposited.eq(0) || product.totalBorrowed.eq(0)) {\n return toBigNumber(0);\n }\n return product.totalBorrowed.abs().div(product.totalDeposited);\n}\n\n/**\n * Calculates per-second borrow interest rate for a product. For example, a returned rate of 0.1 indicates 10% borrower\n * interest. The calculation for interest rate is as follows:\n *\n * If utilization ratio > inflection:\n * annual rate = (utilization ratio - inflection) / (1 - inflection) * interestLargeCap + interestFloor + interestSmallCap\n *\n * If utilization ratio <= inflection:\n * annual rate = utilization ratio * interestSmallCap / inflection + interestFloor\n *\n * The returned rate is annual rate / 31536000 seconds per year.\n *\n * @param product Spot product\n */\nexport function calcBorrowRatePerSecond(product: SpotProduct) {\n const {\n interestFloor,\n interestInflectionUtil,\n interestSmallCap,\n interestLargeCap,\n } = product;\n const utilization = calcUtilizationRatio(product);\n if (utilization.eq(0)) {\n return toBigNumber(0);\n }\n const pastInflection = utilization.gt(interestInflectionUtil);\n\n let annualRate: BigNumber;\n if (pastInflection) {\n const utilizationTerm = interestLargeCap.times(\n toBigNumber(utilization)\n .minus(interestInflectionUtil)\n .div(BigNumbers.ONE.minus(interestInflectionUtil)),\n );\n annualRate = interestFloor.plus(interestSmallCap).plus(utilizationTerm);\n } else {\n const utilizationTerm = utilization\n .div(interestInflectionUtil)\n .times(interestSmallCap);\n annualRate = interestFloor.plus(utilizationTerm);\n }\n\n return annualRate.div(TimeInSeconds.YEAR);\n}\n\n/**\n * Compounds an annual min deposit rate over a period, giving the multiplier\n * `SpotEngine._updateState` applies to both the borrow and the deposit\n * multiplier: `(1 + minDepositRate / secondsPerYear) ** seconds`.\n *\n * @param minDepositRate Annual min deposit rate, as stored in the product config\n * @param seconds Number of seconds for the time period\n */\nfunction calcMinDepositRateMultiplier(\n minDepositRate: BigNumberish,\n seconds: BigNumberish,\n): number {\n const perSecond = toBigNumber(minDepositRate)\n .div(TimeInSeconds.YEAR)\n .toNumber();\n return (1 + perSecond) ** toBigNumber(seconds).toNumber();\n}\n\n/**\n * Calculates borrower interest rate compounded for a period of time.\n *\n * @param product Spot product\n * @param seconds Number of seconds for the time period\n * @param minDepositRate Annual min deposit rate, as stored in the product config\n */\nexport function calcBorrowRateForTimeRange(\n product: SpotProduct,\n seconds: BigNumberish,\n minDepositRate: BigNumberish,\n) {\n const borrowRatePerSecond = calcBorrowRatePerSecond(product);\n\n // Convert to number for this, with some loss of precision, but using `.pow()` causes us to hit browser resource limits\n const borrowRateMultiplier =\n borrowRatePerSecond.plus(1).toNumber() ** toBigNumber(seconds).toNumber();\n // The engine multiplies the borrow multiplier by the min deposit multiplier,\n // so the min deposit rate has to be compounded over the same period rather\n // than added as an annual figure.\n return toBigNumber(\n borrowRateMultiplier *\n calcMinDepositRateMultiplier(minDepositRate, seconds) -\n 1,\n );\n}\n\n/**\n * Calculate depositor interest rate compounded for a period of time.\n *\n * @param product Spot product\n * @param seconds Number of seconds for the time period\n * @param interestFeeFrac Fraction of paid borrower interest that is paid as a fee (0.2 = 20% fee)\n * @param minDepositRate Annual min deposit rate, as stored in the product config\n */\nexport function calcRealizedDepositRateForTimeRange(\n product: SpotProduct,\n seconds: BigNumberish,\n interestFeeFrac: BigNumberish,\n minDepositRate: BigNumberish,\n) {\n const minDepositRateMultiplier = calcMinDepositRateMultiplier(\n minDepositRate,\n seconds,\n );\n const utilization = calcUtilizationRatio(product);\n // Nothing is borrowed, so no interest is paid — but the engine still applies\n // the min deposit multiplier, which is the whole point of a rate floor.\n if (utilization.eq(0)) {\n return toBigNumber(minDepositRateMultiplier - 1);\n }\n const realizedDepositRate = utilization\n .times(calcBorrowRateForTimeRange(product, seconds, toBigNumber(0)))\n .times(BigNumbers.ONE.minus(toBigNumber(interestFeeFrac)));\n return realizedDepositRate\n .plus(BigNumbers.ONE)\n .times(minDepositRateMultiplier)\n .minus(BigNumbers.ONE);\n}\n"],"mappings":";;;;;;;;AAQA,SAAgB,kBACd,wBACA,gCACW;CACX,OAAO,YAAY,sBAAsB,EAAE,aACzC,eAAe,8BAA8B,CAC/C;AACF;;;;AAKA,SAAgB,mBACd,yBACA,iCACW;CACX,OAAO,YAAY,uBAAuB,EAAE,aAC1C,eAAe,+BAA+B,CAChD;AACF;;;;;;AAOA,SAAgB,qBAAqB,SAAsB;CACzD,IAAI,QAAQ,eAAe,GAAG,CAAC,KAAK,QAAQ,cAAc,GAAG,CAAC,GAC5D,OAAO,YAAY,CAAC;CAEtB,OAAO,QAAQ,cAAc,IAAI,EAAE,IAAI,QAAQ,cAAc;AAC/D;;;;;;;;;;;;;;;AAgBA,SAAgB,wBAAwB,SAAsB;CAC5D,MAAM,EACJ,eACA,wBACA,kBACA,qBACE;CACJ,MAAM,cAAc,qBAAqB,OAAO;CAChD,IAAI,YAAY,GAAG,CAAC,GAClB,OAAO,YAAY,CAAC;CAEtB,MAAM,iBAAiB,YAAY,GAAG,sBAAsB;CAE5D,IAAI;CACJ,IAAI,gBAAgB;EAClB,MAAM,kBAAkB,iBAAiB,MACvC,YAAY,WAAW,EACpB,MAAM,sBAAsB,EAC5B,IAAI,WAAW,IAAI,MAAM,sBAAsB,CAAC,CACrD;EACA,aAAa,cAAc,KAAK,gBAAgB,EAAE,KAAK,eAAe;CACxE,OAAO;EACL,MAAM,kBAAkB,YACrB,IAAI,sBAAsB,EAC1B,MAAM,gBAAgB;EACzB,aAAa,cAAc,KAAK,eAAe;CACjD;CAEA,OAAO,WAAW,IAAA,OAAsB;AAC1C;;;;;;;;;AAUA,SAAS,6BACP,gBACA,SACQ;CAIR,QAAQ,IAHU,YAAY,cAAc,EACzC,IAAA,OAAsB,EACtB,SACiB,MAAM,YAAY,OAAO,EAAE,SAAS;AAC1D;;;;;;;;AASA,SAAgB,2BACd,SACA,SACA,gBACA;CASA,OAAO,YARqB,wBAAwB,OAIhC,EAAE,KAAK,CAAC,EAAE,SAAS,KAAK,YAAY,OAAO,EAAE,SAAS,IAMtE,6BAA6B,gBAAgB,OAAO,IACpD,CACJ;AACF;;;;;;;;;AAUA,SAAgB,oCACd,SACA,SACA,iBACA,gBACA;CACA,MAAM,2BAA2B,6BAC/B,gBACA,OACF;CACA,MAAM,cAAc,qBAAqB,OAAO;CAGhD,IAAI,YAAY,GAAG,CAAC,GAClB,OAAO,YAAY,2BAA2B,CAAC;CAKjD,OAH4B,YACzB,MAAM,2BAA2B,SAAS,SAAS,YAAY,CAAC,CAAC,CAAC,EAClE,MAAM,WAAW,IAAI,MAAM,YAAY,eAAe,CAAC,CACjC,EACtB,KAAK,WAAW,GAAG,EACnB,MAAM,wBAAwB,EAC9B,MAAM,WAAW,GAAG;AACzB"}
|
|
@@ -4,5 +4,5 @@ import { t as clampBigNumber } from "../../clamp-D9lICt7X.cjs";
|
|
|
4
4
|
import { n as addDecimals, r as removeDecimals, t as NADO_PRODUCT_DECIMALS } from "../../decimalAdjustment-DCwilVOA.cjs";
|
|
5
5
|
import { t as sumBigNumberBy } from "../../sumBigNumberBy-BvDeov4-.cjs";
|
|
6
6
|
import { t as toBigInt } from "../../toBigInt-BDiOjNl-.cjs";
|
|
7
|
-
import { t as toIntegerString } from "../../toIntegerString-
|
|
7
|
+
import { t as toIntegerString } from "../../toIntegerString-XmD3bQt-.cjs";
|
|
8
8
|
export { BigNumberish, BigNumbers, NADO_PRODUCT_DECIMALS, addDecimals, clampBigNumber, removeDecimals, sumBigNumberBy, toBigInt, toBigNumber, toIntegerString };
|
|
@@ -4,5 +4,5 @@ import { t as clampBigNumber } from "../../clamp-D9lICt7X.js";
|
|
|
4
4
|
import { n as addDecimals, r as removeDecimals, t as NADO_PRODUCT_DECIMALS } from "../../decimalAdjustment-pLqKqD8x.js";
|
|
5
5
|
import { t as sumBigNumberBy } from "../../sumBigNumberBy-BvDeov4-.js";
|
|
6
6
|
import { t as toBigInt } from "../../toBigInt-CBRk3mgz.js";
|
|
7
|
-
import { t as toIntegerString } from "../../toIntegerString-
|
|
7
|
+
import { t as toIntegerString } from "../../toIntegerString-DfbD1c3k.js";
|
|
8
8
|
export { BigNumberish, BigNumbers, NADO_PRODUCT_DECIMALS, addDecimals, clampBigNumber, removeDecimals, sumBigNumberBy, toBigInt, toBigNumber, toIntegerString };
|
|
@@ -2,7 +2,8 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
|
2
2
|
const require_utils_math_bigNumber = require("./bigNumber.cjs");
|
|
3
3
|
//#region src/utils/math/toIntegerString.ts
|
|
4
4
|
/**
|
|
5
|
-
* Converts a BigNumberish value to string
|
|
5
|
+
* Converts a BigNumberish value to an integer string, rounding any fractional
|
|
6
|
+
* part to the nearest integer (bignumber.js `.toFixed(0)` default rounding mode).
|
|
6
7
|
*
|
|
7
8
|
* @param val
|
|
8
9
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"toIntegerString.cjs","names":["toBigNumber"],"sources":["../../../src/utils/math/toIntegerString.ts"],"sourcesContent":["import { BigNumberish, toBigNumber } from './bigNumber';\n\n/**\n * Converts a BigNumberish value to string\n *\n * @param val\n */\nexport function toIntegerString(val: BigNumberish): string {\n // toFixed is required as toString gives values with `e`\n return toBigNumber(val).toFixed(0);\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"toIntegerString.cjs","names":["toBigNumber"],"sources":["../../../src/utils/math/toIntegerString.ts"],"sourcesContent":["import { BigNumberish, toBigNumber } from './bigNumber';\n\n/**\n * Converts a BigNumberish value to an integer string, rounding any fractional\n * part to the nearest integer (bignumber.js `.toFixed(0)` default rounding mode).\n *\n * @param val\n */\nexport function toIntegerString(val: BigNumberish): string {\n // toFixed is required as toString gives values with `e`\n return toBigNumber(val).toFixed(0);\n}\n"],"mappings":";;;;;;;;;AAQA,SAAgB,gBAAgB,KAA2B;CAEzD,OAAOA,6BAAAA,YAAY,GAAG,EAAE,QAAQ,CAAC;AACnC"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as toIntegerString } from "../../toIntegerString-
|
|
1
|
+
import { t as toIntegerString } from "../../toIntegerString-XmD3bQt-.cjs";
|
|
2
2
|
export { toIntegerString };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as toIntegerString } from "../../toIntegerString-
|
|
1
|
+
import { t as toIntegerString } from "../../toIntegerString-DfbD1c3k.js";
|
|
2
2
|
export { toIntegerString };
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { toBigNumber } from "./bigNumber.js";
|
|
2
2
|
//#region src/utils/math/toIntegerString.ts
|
|
3
3
|
/**
|
|
4
|
-
* Converts a BigNumberish value to string
|
|
4
|
+
* Converts a BigNumberish value to an integer string, rounding any fractional
|
|
5
|
+
* part to the nearest integer (bignumber.js `.toFixed(0)` default rounding mode).
|
|
5
6
|
*
|
|
6
7
|
* @param val
|
|
7
8
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"toIntegerString.js","names":[],"sources":["../../../src/utils/math/toIntegerString.ts"],"sourcesContent":["import { BigNumberish, toBigNumber } from './bigNumber';\n\n/**\n * Converts a BigNumberish value to string\n *\n * @param val\n */\nexport function toIntegerString(val: BigNumberish): string {\n // toFixed is required as toString gives values with `e`\n return toBigNumber(val).toFixed(0);\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"toIntegerString.js","names":[],"sources":["../../../src/utils/math/toIntegerString.ts"],"sourcesContent":["import { BigNumberish, toBigNumber } from './bigNumber';\n\n/**\n * Converts a BigNumberish value to an integer string, rounding any fractional\n * part to the nearest integer (bignumber.js `.toFixed(0)` default rounding mode).\n *\n * @param val\n */\nexport function toIntegerString(val: BigNumberish): string {\n // toFixed is required as toString gives values with `e`\n return toBigNumber(val).toFixed(0);\n}\n"],"mappings":";;;;;;;;AAQA,SAAgB,gBAAgB,KAA2B;CAEzD,OAAO,YAAY,GAAG,EAAE,QAAQ,CAAC;AACnC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nadohq/shared",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.67.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"description": "Shared utilities, types, and contract helpers for Nado SDK",
|
|
@@ -52,5 +52,5 @@
|
|
|
52
52
|
"bignumber.js": "11.1.1",
|
|
53
53
|
"viem": "2.52.0"
|
|
54
54
|
},
|
|
55
|
-
"gitHead": "
|
|
55
|
+
"gitHead": "58263d0bb5d08e10371a917e5c16d61cc81bb937"
|
|
56
56
|
}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import { describe, expect, it } from '@jest/globals';
|
|
2
|
+
import BigNumber from 'bignumber.js';
|
|
3
|
+
import { SpotProduct } from '../types/productTypes';
|
|
4
|
+
import {
|
|
5
|
+
calcBorrowRateForTimeRange,
|
|
6
|
+
calcBorrowRatePerSecond,
|
|
7
|
+
calcRealizedDepositRateForTimeRange,
|
|
8
|
+
} from './interest';
|
|
9
|
+
import { TimeInSeconds } from './time';
|
|
10
|
+
|
|
11
|
+
const MIN_DEPOSIT_RATE = 0.05;
|
|
12
|
+
|
|
13
|
+
function spotProduct(overrides: Partial<SpotProduct> = {}) {
|
|
14
|
+
return {
|
|
15
|
+
interestFloor: new BigNumber(0.01),
|
|
16
|
+
interestInflectionUtil: new BigNumber(0.8),
|
|
17
|
+
interestSmallCap: new BigNumber(0.04),
|
|
18
|
+
interestLargeCap: new BigNumber(0.4),
|
|
19
|
+
minDepositRate: new BigNumber(MIN_DEPOSIT_RATE),
|
|
20
|
+
totalDeposited: new BigNumber(1_000_000),
|
|
21
|
+
totalBorrowed: new BigNumber(-500_000),
|
|
22
|
+
...overrides,
|
|
23
|
+
} as SpotProduct;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* `SpotEngine._updateState` compounds the min deposit rate over the period and
|
|
28
|
+
* multiplies it into the borrow multiplier, rather than adding the annual rate.
|
|
29
|
+
*/
|
|
30
|
+
function onChainBorrowRate(product: SpotProduct, seconds: number) {
|
|
31
|
+
const borrowRatePerSecond = calcBorrowRatePerSecond(product).toNumber();
|
|
32
|
+
const minDepositRatePerSecond = MIN_DEPOSIT_RATE / TimeInSeconds.YEAR;
|
|
33
|
+
return (
|
|
34
|
+
(1 + borrowRatePerSecond) ** seconds *
|
|
35
|
+
(1 + minDepositRatePerSecond) ** seconds -
|
|
36
|
+
1
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
describe('interest', () => {
|
|
41
|
+
const periods: [string, number][] = [
|
|
42
|
+
['an hour', TimeInSeconds.HOUR],
|
|
43
|
+
['a day', TimeInSeconds.DAY],
|
|
44
|
+
['thirty days', TimeInSeconds.DAY * 30],
|
|
45
|
+
['a year', TimeInSeconds.YEAR],
|
|
46
|
+
];
|
|
47
|
+
|
|
48
|
+
describe('calcBorrowRateForTimeRange', () => {
|
|
49
|
+
it.each(periods)(
|
|
50
|
+
'compounds the min deposit rate over %s rather than adding it',
|
|
51
|
+
(_label, seconds) => {
|
|
52
|
+
const product = spotProduct();
|
|
53
|
+
expect(
|
|
54
|
+
calcBorrowRateForTimeRange(
|
|
55
|
+
product,
|
|
56
|
+
seconds,
|
|
57
|
+
product.minDepositRate,
|
|
58
|
+
).toNumber(),
|
|
59
|
+
).toBeCloseTo(onChainBorrowRate(product, seconds), 10);
|
|
60
|
+
},
|
|
61
|
+
);
|
|
62
|
+
|
|
63
|
+
it('stays below the annual min deposit rate for a short period', () => {
|
|
64
|
+
const product = spotProduct();
|
|
65
|
+
// Adding the annual rate unscaled put an hour of borrowing above 5%.
|
|
66
|
+
expect(
|
|
67
|
+
calcBorrowRateForTimeRange(
|
|
68
|
+
product,
|
|
69
|
+
TimeInSeconds.HOUR,
|
|
70
|
+
product.minDepositRate,
|
|
71
|
+
).toNumber(),
|
|
72
|
+
).toBeLessThan(MIN_DEPOSIT_RATE / 100);
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
it('returns only the borrow rate when there is no min deposit rate', () => {
|
|
76
|
+
const product = spotProduct();
|
|
77
|
+
const borrowRatePerSecond = calcBorrowRatePerSecond(product).toNumber();
|
|
78
|
+
expect(
|
|
79
|
+
calcBorrowRateForTimeRange(product, TimeInSeconds.DAY, 0).toNumber(),
|
|
80
|
+
).toBeCloseTo((1 + borrowRatePerSecond) ** TimeInSeconds.DAY - 1, 12);
|
|
81
|
+
});
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
describe('calcRealizedDepositRateForTimeRange', () => {
|
|
85
|
+
it('still pays the min deposit rate when nothing is borrowed', () => {
|
|
86
|
+
const product = spotProduct({ totalBorrowed: new BigNumber(0) });
|
|
87
|
+
const expected =
|
|
88
|
+
(1 + MIN_DEPOSIT_RATE / TimeInSeconds.YEAR) ** TimeInSeconds.DAY - 1;
|
|
89
|
+
expect(
|
|
90
|
+
calcRealizedDepositRateForTimeRange(
|
|
91
|
+
product,
|
|
92
|
+
TimeInSeconds.DAY,
|
|
93
|
+
0.2,
|
|
94
|
+
product.minDepositRate,
|
|
95
|
+
).toNumber(),
|
|
96
|
+
).toBeCloseTo(expected, 12);
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
it('compounds the min deposit rate on top of the realized rate', () => {
|
|
100
|
+
const product = spotProduct();
|
|
101
|
+
const seconds = TimeInSeconds.DAY;
|
|
102
|
+
const utilization = 0.5;
|
|
103
|
+
const borrowRate = calcBorrowRateForTimeRange(
|
|
104
|
+
product,
|
|
105
|
+
seconds,
|
|
106
|
+
0,
|
|
107
|
+
).toNumber();
|
|
108
|
+
const realized = utilization * borrowRate * (1 - 0.2);
|
|
109
|
+
const expected =
|
|
110
|
+
(1 + realized) *
|
|
111
|
+
(1 + MIN_DEPOSIT_RATE / TimeInSeconds.YEAR) ** seconds -
|
|
112
|
+
1;
|
|
113
|
+
expect(
|
|
114
|
+
calcRealizedDepositRateForTimeRange(
|
|
115
|
+
product,
|
|
116
|
+
seconds,
|
|
117
|
+
0.2,
|
|
118
|
+
product.minDepositRate,
|
|
119
|
+
).toNumber(),
|
|
120
|
+
).toBeCloseTo(expected, 12);
|
|
121
|
+
});
|
|
122
|
+
});
|
|
123
|
+
});
|
package/src/utils/interest.ts
CHANGED
|
@@ -84,11 +84,30 @@ export function calcBorrowRatePerSecond(product: SpotProduct) {
|
|
|
84
84
|
return annualRate.div(TimeInSeconds.YEAR);
|
|
85
85
|
}
|
|
86
86
|
|
|
87
|
+
/**
|
|
88
|
+
* Compounds an annual min deposit rate over a period, giving the multiplier
|
|
89
|
+
* `SpotEngine._updateState` applies to both the borrow and the deposit
|
|
90
|
+
* multiplier: `(1 + minDepositRate / secondsPerYear) ** seconds`.
|
|
91
|
+
*
|
|
92
|
+
* @param minDepositRate Annual min deposit rate, as stored in the product config
|
|
93
|
+
* @param seconds Number of seconds for the time period
|
|
94
|
+
*/
|
|
95
|
+
function calcMinDepositRateMultiplier(
|
|
96
|
+
minDepositRate: BigNumberish,
|
|
97
|
+
seconds: BigNumberish,
|
|
98
|
+
): number {
|
|
99
|
+
const perSecond = toBigNumber(minDepositRate)
|
|
100
|
+
.div(TimeInSeconds.YEAR)
|
|
101
|
+
.toNumber();
|
|
102
|
+
return (1 + perSecond) ** toBigNumber(seconds).toNumber();
|
|
103
|
+
}
|
|
104
|
+
|
|
87
105
|
/**
|
|
88
106
|
* Calculates borrower interest rate compounded for a period of time.
|
|
89
107
|
*
|
|
90
108
|
* @param product Spot product
|
|
91
109
|
* @param seconds Number of seconds for the time period
|
|
110
|
+
* @param minDepositRate Annual min deposit rate, as stored in the product config
|
|
92
111
|
*/
|
|
93
112
|
export function calcBorrowRateForTimeRange(
|
|
94
113
|
product: SpotProduct,
|
|
@@ -98,10 +117,16 @@ export function calcBorrowRateForTimeRange(
|
|
|
98
117
|
const borrowRatePerSecond = calcBorrowRatePerSecond(product);
|
|
99
118
|
|
|
100
119
|
// Convert to number for this, with some loss of precision, but using `.pow()` causes us to hit browser resource limits
|
|
101
|
-
const
|
|
102
|
-
borrowRatePerSecond.plus(1).toNumber() ** toBigNumber(seconds).toNumber()
|
|
103
|
-
|
|
104
|
-
|
|
120
|
+
const borrowRateMultiplier =
|
|
121
|
+
borrowRatePerSecond.plus(1).toNumber() ** toBigNumber(seconds).toNumber();
|
|
122
|
+
// The engine multiplies the borrow multiplier by the min deposit multiplier,
|
|
123
|
+
// so the min deposit rate has to be compounded over the same period rather
|
|
124
|
+
// than added as an annual figure.
|
|
125
|
+
return toBigNumber(
|
|
126
|
+
borrowRateMultiplier *
|
|
127
|
+
calcMinDepositRateMultiplier(minDepositRate, seconds) -
|
|
128
|
+
1,
|
|
129
|
+
);
|
|
105
130
|
}
|
|
106
131
|
|
|
107
132
|
/**
|
|
@@ -110,6 +135,7 @@ export function calcBorrowRateForTimeRange(
|
|
|
110
135
|
* @param product Spot product
|
|
111
136
|
* @param seconds Number of seconds for the time period
|
|
112
137
|
* @param interestFeeFrac Fraction of paid borrower interest that is paid as a fee (0.2 = 20% fee)
|
|
138
|
+
* @param minDepositRate Annual min deposit rate, as stored in the product config
|
|
113
139
|
*/
|
|
114
140
|
export function calcRealizedDepositRateForTimeRange(
|
|
115
141
|
product: SpotProduct,
|
|
@@ -117,12 +143,21 @@ export function calcRealizedDepositRateForTimeRange(
|
|
|
117
143
|
interestFeeFrac: BigNumberish,
|
|
118
144
|
minDepositRate: BigNumberish,
|
|
119
145
|
) {
|
|
146
|
+
const minDepositRateMultiplier = calcMinDepositRateMultiplier(
|
|
147
|
+
minDepositRate,
|
|
148
|
+
seconds,
|
|
149
|
+
);
|
|
120
150
|
const utilization = calcUtilizationRatio(product);
|
|
151
|
+
// Nothing is borrowed, so no interest is paid — but the engine still applies
|
|
152
|
+
// the min deposit multiplier, which is the whole point of a rate floor.
|
|
121
153
|
if (utilization.eq(0)) {
|
|
122
|
-
return toBigNumber(
|
|
154
|
+
return toBigNumber(minDepositRateMultiplier - 1);
|
|
123
155
|
}
|
|
124
|
-
|
|
156
|
+
const realizedDepositRate = utilization
|
|
125
157
|
.times(calcBorrowRateForTimeRange(product, seconds, toBigNumber(0)))
|
|
126
|
-
.times(BigNumbers.ONE.minus(toBigNumber(interestFeeFrac)))
|
|
127
|
-
|
|
158
|
+
.times(BigNumbers.ONE.minus(toBigNumber(interestFeeFrac)));
|
|
159
|
+
return realizedDepositRate
|
|
160
|
+
.plus(BigNumbers.ONE)
|
|
161
|
+
.times(minDepositRateMultiplier)
|
|
162
|
+
.minus(BigNumbers.ONE);
|
|
128
163
|
}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { BigNumberish, toBigNumber } from './bigNumber';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
* Converts a BigNumberish value to string
|
|
4
|
+
* Converts a BigNumberish value to an integer string, rounding any fractional
|
|
5
|
+
* part to the nearest integer (bignumber.js `.toFixed(0)` default rounding mode).
|
|
5
6
|
*
|
|
6
7
|
* @param val
|
|
7
8
|
*/
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"toIntegerString-BUESqiY1.d.cts","names":[],"sources":["../src/utils/math/src/utils/math/toIntegerString.ts"],"mappings":";;;;;AAOA;;;iBAAgB,eAAA,CAAgB,GAAiB,EAAZ,YAAY"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"toIntegerString-CyhOUxbE.d.ts","names":[],"sources":["../src/utils/math/src/utils/math/toIntegerString.ts"],"mappings":";;;;;AAOA;;;iBAAgB,eAAA,CAAgB,GAAiB,EAAZ,YAAY"}
|