@kasufinance/kasu-sdk 1.0.1
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/.eslintignore +3 -0
- package/.eslintrc.json +90 -0
- package/.github/workflows/ci.yml +0 -0
- package/.github/workflows/main.yml +43 -0
- package/.prettierignore +3 -0
- package/.prettierrc +28 -0
- package/abis/IClearingCoordinator.abi.json +410 -0
- package/abis/IERC20Metadata.abi.json +224 -0
- package/abis/IFeeManager.abi.json +66 -0
- package/abis/IKSULocking.abi.json +754 -0
- package/abis/IKasuAllowList.abi.json +455 -0
- package/abis/IKasuController.abi.json +423 -0
- package/abis/IKasuNFTs.abi.json +1523 -0
- package/abis/IKsuPrice.abi.json +15 -0
- package/abis/ILendingPool.abi.json +1431 -0
- package/abis/ILendingPoolFactory.abi.json +97 -0
- package/abis/ILendingPoolManager.abi.json +1347 -0
- package/abis/ILendingPoolTranche.abi.json +1317 -0
- package/abis/IPriceFeed.abi.json +1 -0
- package/abis/ISystemVariables.abi.json +431 -0
- package/abis/IUserLoyaltyRewards.abi.json +288 -0
- package/abis/IUserManager.abi.json +321 -0
- package/abis/KSULockBonus.abi.json +91 -0
- package/abis/KasuPoolExternalTVL.abi.json +812 -0
- package/abis/Swapper.abi.json +146 -0
- package/copy-abi.ps1 +15 -0
- package/dist/bundle.cjs.js +21646 -0
- package/dist/bundle.esm.js +21644 -0
- package/dist/contracts/IClearingCoordinatorAbi.d.ts +169 -0
- package/dist/contracts/IClearingCoordinatorAbi.js +1 -0
- package/dist/contracts/IERC20MetadataAbi.d.ts +162 -0
- package/dist/contracts/IERC20MetadataAbi.js +1 -0
- package/dist/contracts/IFeeManagerAbi.d.ts +96 -0
- package/dist/contracts/IFeeManagerAbi.js +1 -0
- package/dist/contracts/IKSULockingAbi.d.ts +466 -0
- package/dist/contracts/IKSULockingAbi.js +1 -0
- package/dist/contracts/IKasuAllowListAbi.d.ts +304 -0
- package/dist/contracts/IKasuAllowListAbi.js +1 -0
- package/dist/contracts/IKasuControllerAbi.d.ts +309 -0
- package/dist/contracts/IKasuControllerAbi.js +1 -0
- package/dist/contracts/IKasuNFTsAbi.d.ts +1121 -0
- package/dist/contracts/IKasuNFTsAbi.js +1 -0
- package/dist/contracts/IKsuPriceAbi.d.ts +42 -0
- package/dist/contracts/IKsuPriceAbi.js +1 -0
- package/dist/contracts/ILendingPoolAbi.d.ts +968 -0
- package/dist/contracts/ILendingPoolAbi.js +1 -0
- package/dist/contracts/ILendingPoolFactoryAbi.d.ts +103 -0
- package/dist/contracts/ILendingPoolFactoryAbi.js +1 -0
- package/dist/contracts/ILendingPoolManagerAbi.d.ts +779 -0
- package/dist/contracts/ILendingPoolManagerAbi.js +1 -0
- package/dist/contracts/ILendingPoolTrancheAbi.d.ts +752 -0
- package/dist/contracts/ILendingPoolTrancheAbi.js +1 -0
- package/dist/contracts/ISystemVariablesAbi.d.ts +378 -0
- package/dist/contracts/ISystemVariablesAbi.js +1 -0
- package/dist/contracts/IUserLoyaltyRewardsAbi.d.ts +248 -0
- package/dist/contracts/IUserLoyaltyRewardsAbi.js +1 -0
- package/dist/contracts/IUserManagerAbi.d.ts +270 -0
- package/dist/contracts/IUserManagerAbi.js +1 -0
- package/dist/contracts/KSULockBonusAbi.d.ts +61 -0
- package/dist/contracts/KSULockBonusAbi.js +1 -0
- package/dist/contracts/KasuPoolExternalTVLAbi.d.ts +411 -0
- package/dist/contracts/KasuPoolExternalTVLAbi.js +1 -0
- package/dist/contracts/SwapperAbi.d.ts +120 -0
- package/dist/contracts/SwapperAbi.js +1 -0
- package/dist/contracts/common.d.ts +21 -0
- package/dist/contracts/common.js +1 -0
- package/dist/contracts/factories/IClearingCoordinatorAbi__factory.d.ts +320 -0
- package/dist/contracts/factories/IClearingCoordinatorAbi__factory.js +423 -0
- package/dist/contracts/factories/IERC20MetadataAbi__factory.d.ts +178 -0
- package/dist/contracts/factories/IERC20MetadataAbi__factory.js +237 -0
- package/dist/contracts/factories/IFeeManagerAbi__factory.d.ts +59 -0
- package/dist/contracts/factories/IFeeManagerAbi__factory.js +79 -0
- package/dist/contracts/factories/IKSULockingAbi__factory.d.ts +588 -0
- package/dist/contracts/factories/IKSULockingAbi__factory.js +767 -0
- package/dist/contracts/factories/IKasuAllowListAbi__factory.d.ts +354 -0
- package/dist/contracts/factories/IKasuAllowListAbi__factory.js +468 -0
- package/dist/contracts/factories/IKasuControllerAbi__factory.d.ts +339 -0
- package/dist/contracts/factories/IKasuControllerAbi__factory.js +436 -0
- package/dist/contracts/factories/IKasuNFTsAbi__factory.d.ts +1629 -0
- package/dist/contracts/factories/IKasuNFTsAbi__factory.js +2108 -0
- package/dist/contracts/factories/IKsuPriceAbi__factory.d.ts +18 -0
- package/dist/contracts/factories/IKsuPriceAbi__factory.js +28 -0
- package/dist/contracts/factories/ILendingPoolAbi__factory.d.ts +1109 -0
- package/dist/contracts/factories/ILendingPoolAbi__factory.js +1444 -0
- package/dist/contracts/factories/ILendingPoolFactoryAbi__factory.d.ts +81 -0
- package/dist/contracts/factories/ILendingPoolFactoryAbi__factory.js +110 -0
- package/dist/contracts/factories/ILendingPoolManagerAbi__factory.d.ts +1045 -0
- package/dist/contracts/factories/ILendingPoolManagerAbi__factory.js +1360 -0
- package/dist/contracts/factories/ILendingPoolTrancheAbi__factory.d.ts +1015 -0
- package/dist/contracts/factories/ILendingPoolTrancheAbi__factory.js +1330 -0
- package/dist/contracts/factories/ISystemVariablesAbi__factory.d.ts +338 -0
- package/dist/contracts/factories/ISystemVariablesAbi__factory.js +444 -0
- package/dist/contracts/factories/IUserLoyaltyRewardsAbi__factory.d.ts +230 -0
- package/dist/contracts/factories/IUserLoyaltyRewardsAbi__factory.js +301 -0
- package/dist/contracts/factories/IUserManagerAbi__factory.d.ts +250 -0
- package/dist/contracts/factories/IUserManagerAbi__factory.js +334 -0
- package/dist/contracts/factories/KSULockBonusAbi__factory.d.ts +76 -0
- package/dist/contracts/factories/KSULockBonusAbi__factory.js +104 -0
- package/dist/contracts/factories/KasuPoolExternalTVLAbi__factory.d.ts +631 -0
- package/dist/contracts/factories/KasuPoolExternalTVLAbi__factory.js +825 -0
- package/dist/contracts/factories/SwapperAbi__factory.d.ts +120 -0
- package/dist/contracts/factories/SwapperAbi__factory.js +159 -0
- package/dist/contracts/factories/index.d.ts +18 -0
- package/dist/contracts/factories/index.js +21 -0
- package/dist/contracts/index.d.ts +37 -0
- package/dist/contracts/index.js +19 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.js +16 -0
- package/dist/sdk-config.d.ts +22 -0
- package/dist/sdk-config.js +9 -0
- package/dist/services/DataService/data-service.d.ts +37 -0
- package/dist/services/DataService/data-service.js +586 -0
- package/dist/services/DataService/directus-types.d.ts +187 -0
- package/dist/services/DataService/directus-types.js +1 -0
- package/dist/services/DataService/queries.d.ts +7 -0
- package/dist/services/DataService/queries.js +158 -0
- package/dist/services/DataService/subgraph-types.d.ts +95 -0
- package/dist/services/DataService/subgraph-types.js +1 -0
- package/dist/services/DataService/types.d.ts +169 -0
- package/dist/services/DataService/types.js +1 -0
- package/dist/services/Locking/locking.d.ts +61 -0
- package/dist/services/Locking/locking.js +344 -0
- package/dist/services/Locking/queries.d.ts +10 -0
- package/dist/services/Locking/queries.js +108 -0
- package/dist/services/Locking/types.d.ts +117 -0
- package/dist/services/Locking/types.js +1 -0
- package/dist/services/Portfolio/portfolio.d.ts +22 -0
- package/dist/services/Portfolio/portfolio.js +325 -0
- package/dist/services/Portfolio/queries.d.ts +2 -0
- package/dist/services/Portfolio/queries.js +164 -0
- package/dist/services/Portfolio/types.d.ts +206 -0
- package/dist/services/Portfolio/types.js +1 -0
- package/dist/services/Swapper/swapper.d.ts +11 -0
- package/dist/services/Swapper/swapper.js +97 -0
- package/dist/services/Swapper/types.d.ts +51 -0
- package/dist/services/Swapper/types.js +1 -0
- package/dist/services/UserLending/helper.d.ts +2 -0
- package/dist/services/UserLending/helper.js +16 -0
- package/dist/services/UserLending/queries.d.ts +8 -0
- package/dist/services/UserLending/queries.js +188 -0
- package/dist/services/UserLending/subgraph-types.d.ts +147 -0
- package/dist/services/UserLending/subgraph-types.js +6 -0
- package/dist/services/UserLending/types.d.ts +102 -0
- package/dist/services/UserLending/types.js +13 -0
- package/dist/services/UserLending/user-lending.d.ts +55 -0
- package/dist/services/UserLending/user-lending.js +490 -0
- package/dist/services/shared.d.ts +1 -0
- package/dist/services/shared.js +11 -0
- package/dist/tests/sample.test.d.ts +1 -0
- package/dist/tests/sample.test.js +32 -0
- package/index.ts +2 -0
- package/jest-config.ts +9 -0
- package/jest.config.js +8 -0
- package/package.json +49 -0
- package/rollup.config.js +45 -0
- package/src/contracts/IClearingCoordinatorAbi.ts +406 -0
- package/src/contracts/IERC20MetadataAbi.ts +364 -0
- package/src/contracts/IFeeManagerAbi.ts +182 -0
- package/src/contracts/IKSULockingAbi.ts +965 -0
- package/src/contracts/IKasuAllowListAbi.ts +605 -0
- package/src/contracts/IKasuControllerAbi.ts +703 -0
- package/src/contracts/IKasuNFTsAbi.ts +2744 -0
- package/src/contracts/IKsuPriceAbi.ts +87 -0
- package/src/contracts/ILendingPoolAbi.ts +2081 -0
- package/src/contracts/ILendingPoolFactoryAbi.ts +161 -0
- package/src/contracts/ILendingPoolManagerAbi.ts +1917 -0
- package/src/contracts/ILendingPoolTrancheAbi.ts +1911 -0
- package/src/contracts/ISystemVariablesAbi.ts +908 -0
- package/src/contracts/IUserLoyaltyRewardsAbi.ts +544 -0
- package/src/contracts/IUserManagerAbi.ts +612 -0
- package/src/contracts/KSULockBonusAbi.ts +124 -0
- package/src/contracts/KasuPoolExternalTVLAbi.ts +1071 -0
- package/src/contracts/SwapperAbi.ts +266 -0
- package/src/contracts/common.ts +44 -0
- package/src/contracts/factories/IClearingCoordinatorAbi__factory.ts +438 -0
- package/src/contracts/factories/IERC20MetadataAbi__factory.ts +248 -0
- package/src/contracts/factories/IFeeManagerAbi__factory.ts +90 -0
- package/src/contracts/factories/IKSULockingAbi__factory.ts +778 -0
- package/src/contracts/factories/IKasuAllowListAbi__factory.ts +479 -0
- package/src/contracts/factories/IKasuControllerAbi__factory.ts +447 -0
- package/src/contracts/factories/IKasuNFTsAbi__factory.ts +2116 -0
- package/src/contracts/factories/IKsuPriceAbi__factory.ts +36 -0
- package/src/contracts/factories/ILendingPoolAbi__factory.ts +1455 -0
- package/src/contracts/factories/ILendingPoolFactoryAbi__factory.ts +125 -0
- package/src/contracts/factories/ILendingPoolManagerAbi__factory.ts +1375 -0
- package/src/contracts/factories/ILendingPoolTrancheAbi__factory.ts +1345 -0
- package/src/contracts/factories/ISystemVariablesAbi__factory.ts +455 -0
- package/src/contracts/factories/IUserLoyaltyRewardsAbi__factory.ts +316 -0
- package/src/contracts/factories/IUserManagerAbi__factory.ts +345 -0
- package/src/contracts/factories/KSULockBonusAbi__factory.ts +115 -0
- package/src/contracts/factories/KasuPoolExternalTVLAbi__factory.ts +840 -0
- package/src/contracts/factories/SwapperAbi__factory.ts +167 -0
- package/src/contracts/factories/index.ts +21 -0
- package/src/contracts/index.ts +40 -0
- package/src/index.ts +27 -0
- package/src/sdk-config.ts +35 -0
- package/src/services/DataService/data-service.ts +1017 -0
- package/src/services/DataService/directus-types.ts +199 -0
- package/src/services/DataService/queries.ts +165 -0
- package/src/services/DataService/subgraph-types.ts +104 -0
- package/src/services/DataService/types.ts +184 -0
- package/src/services/Locking/locking.ts +541 -0
- package/src/services/Locking/queries.ts +118 -0
- package/src/services/Locking/types.ts +141 -0
- package/src/services/Portfolio/portfolio.ts +593 -0
- package/src/services/Portfolio/queries.ts +166 -0
- package/src/services/Portfolio/types.ts +220 -0
- package/src/services/Swapper/swapper.ts +158 -0
- package/src/services/Swapper/types.ts +54 -0
- package/src/services/UserLending/helper.ts +28 -0
- package/src/services/UserLending/queries.ts +196 -0
- package/src/services/UserLending/subgraph-types.ts +173 -0
- package/src/services/UserLending/types.ts +123 -0
- package/src/services/UserLending/user-lending.ts +933 -0
- package/src/services/shared.ts +11 -0
- package/src/tests/sample.test.ts +44 -0
- package/tsconfig.json +27 -0
- package/tsconfig.tsbuildinfo +1 -0
- package/versioner.sh +6 -0
|
@@ -0,0 +1,541 @@
|
|
|
1
|
+
import { Provider } from '@ethersproject/providers';
|
|
2
|
+
import { BigNumber, ContractTransaction, ethers, Signer } from 'ethers';
|
|
3
|
+
import { formatEther, formatUnits, parseUnits } from 'ethers/lib/utils';
|
|
4
|
+
import { GraphQLClient } from 'graphql-request';
|
|
5
|
+
|
|
6
|
+
import {
|
|
7
|
+
IERC20MetadataAbi,
|
|
8
|
+
IERC20MetadataAbi__factory,
|
|
9
|
+
IKSULockingAbi,
|
|
10
|
+
IKSULockingAbi__factory,
|
|
11
|
+
IKsuPriceAbi,
|
|
12
|
+
IKsuPriceAbi__factory,
|
|
13
|
+
ISystemVariablesAbi,
|
|
14
|
+
ISystemVariablesAbi__factory,
|
|
15
|
+
IUserLoyaltyRewardsAbi,
|
|
16
|
+
IUserLoyaltyRewardsAbi__factory,
|
|
17
|
+
IUserManagerAbi,
|
|
18
|
+
IUserManagerAbi__factory,
|
|
19
|
+
} from '../../contracts';
|
|
20
|
+
import { SdkConfig } from '../../sdk-config';
|
|
21
|
+
import {
|
|
22
|
+
getAllTrancheConfigurationsQuery,
|
|
23
|
+
getAllTranchesQuery,
|
|
24
|
+
} from '../DataService/queries';
|
|
25
|
+
import {
|
|
26
|
+
TrancheConfigurationSubgraphResult,
|
|
27
|
+
TrancheSubgraphResult,
|
|
28
|
+
} from '../DataService/subgraph-types';
|
|
29
|
+
|
|
30
|
+
import {
|
|
31
|
+
claimedFeesQuery,
|
|
32
|
+
getSystemVariablesQuery,
|
|
33
|
+
getTotalUserLoyaltsRewardsQuery,
|
|
34
|
+
lockingPeriodsQuery,
|
|
35
|
+
lockingSummariesQuery,
|
|
36
|
+
userEarnedrKsuQuery,
|
|
37
|
+
userLocksQuery,
|
|
38
|
+
userStakedKsuQuery,
|
|
39
|
+
userTotalBonusAmountQuery,
|
|
40
|
+
} from './queries';
|
|
41
|
+
import {
|
|
42
|
+
GQLClaimedFeesForAddress,
|
|
43
|
+
GQLEarnedRKsuForAddress,
|
|
44
|
+
GQLGetLockingPeriods,
|
|
45
|
+
GQLStakedAmountForAddress,
|
|
46
|
+
GQLTotalBonusAmountForAddress,
|
|
47
|
+
GQLUserLocks,
|
|
48
|
+
LockingSummarySubgraphResult,
|
|
49
|
+
LockPeriod,
|
|
50
|
+
LockPeriodInterface,
|
|
51
|
+
RSVDeadlineValue,
|
|
52
|
+
SystemVariables,
|
|
53
|
+
totalUserLoyaltyRewards,
|
|
54
|
+
UserBonusData,
|
|
55
|
+
UserLock,
|
|
56
|
+
} from './types';
|
|
57
|
+
|
|
58
|
+
export class KSULocking {
|
|
59
|
+
private readonly _contractAbi: IKSULockingAbi;
|
|
60
|
+
private readonly _kasuToken: IERC20MetadataAbi;
|
|
61
|
+
private readonly _kasuBonusAddress: string;
|
|
62
|
+
private readonly _graph: GraphQLClient;
|
|
63
|
+
private readonly _userManagerAbi: IUserManagerAbi;
|
|
64
|
+
private readonly _systemVariablesAbi: ISystemVariablesAbi;
|
|
65
|
+
private readonly _ksuPriceAbi: IKsuPriceAbi;
|
|
66
|
+
private readonly _userLoyaltyRewardsAbi: IUserLoyaltyRewardsAbi;
|
|
67
|
+
private readonly apyBonuses: number[] = [0, 0.001, 0.002];
|
|
68
|
+
/**
|
|
69
|
+
*
|
|
70
|
+
*/
|
|
71
|
+
constructor(
|
|
72
|
+
private _kasuConfig: SdkConfig,
|
|
73
|
+
signerOrProvider: Signer | Provider,
|
|
74
|
+
) {
|
|
75
|
+
this._contractAbi = IKSULockingAbi__factory.connect(
|
|
76
|
+
_kasuConfig.contracts.IKSULocking,
|
|
77
|
+
signerOrProvider,
|
|
78
|
+
);
|
|
79
|
+
this._kasuToken = IERC20MetadataAbi__factory.connect(
|
|
80
|
+
_kasuConfig.contracts.KSUToken,
|
|
81
|
+
signerOrProvider,
|
|
82
|
+
);
|
|
83
|
+
this._userManagerAbi = IUserManagerAbi__factory.connect(
|
|
84
|
+
_kasuConfig.contracts.UserManager,
|
|
85
|
+
signerOrProvider,
|
|
86
|
+
);
|
|
87
|
+
this._systemVariablesAbi = ISystemVariablesAbi__factory.connect(
|
|
88
|
+
_kasuConfig.contracts.SystemVariables,
|
|
89
|
+
signerOrProvider,
|
|
90
|
+
);
|
|
91
|
+
this._ksuPriceAbi = IKsuPriceAbi__factory.connect(
|
|
92
|
+
_kasuConfig.contracts.KsuPrice,
|
|
93
|
+
signerOrProvider,
|
|
94
|
+
);
|
|
95
|
+
this._kasuBonusAddress = _kasuConfig.contracts.IKSULockBonus;
|
|
96
|
+
this._graph = new GraphQLClient(_kasuConfig.subgraphUrl);
|
|
97
|
+
this._userLoyaltyRewardsAbi = IUserLoyaltyRewardsAbi__factory.connect(
|
|
98
|
+
_kasuConfig.contracts.UserLoyaltyRewards,
|
|
99
|
+
signerOrProvider,
|
|
100
|
+
);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
async lockKSUTokens(
|
|
104
|
+
amount: BigNumber,
|
|
105
|
+
lockPeriod: BigNumber,
|
|
106
|
+
): Promise<ContractTransaction> {
|
|
107
|
+
return this._contractAbi.lock(amount, lockPeriod);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
async lockKSUWithPermit(
|
|
111
|
+
amount: number,
|
|
112
|
+
lockPeriod: number,
|
|
113
|
+
permit: RSVDeadlineValue,
|
|
114
|
+
): Promise<ContractTransaction> {
|
|
115
|
+
const amountBN = BigNumber.from(amount);
|
|
116
|
+
const lockPeriodBN = BigNumber.from(lockPeriod);
|
|
117
|
+
|
|
118
|
+
const ksuPermit = {
|
|
119
|
+
value: BigNumber.from(permit.value),
|
|
120
|
+
deadline: BigNumber.from(permit.deadline),
|
|
121
|
+
v: BigNumber.from(permit.v),
|
|
122
|
+
r: permit.r,
|
|
123
|
+
s: permit.s,
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
return this._contractAbi.lockWithPermit(
|
|
127
|
+
amountBN,
|
|
128
|
+
lockPeriodBN,
|
|
129
|
+
ksuPermit,
|
|
130
|
+
);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
async unlockKSU(
|
|
134
|
+
amount: BigNumber,
|
|
135
|
+
userLockId: BigNumber,
|
|
136
|
+
): Promise<ContractTransaction> {
|
|
137
|
+
return this._contractAbi.unlock(amount, userLockId);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
async claimFees(): Promise<ContractTransaction> {
|
|
141
|
+
return await this._contractAbi.claimFees();
|
|
142
|
+
}
|
|
143
|
+
async lockDetails(lockPeriod: BigNumber): Promise<LockPeriodInterface> {
|
|
144
|
+
const result = await this._contractAbi.lockDetails(lockPeriod);
|
|
145
|
+
return {
|
|
146
|
+
rKsuMultiplier: result[0].toNumber(),
|
|
147
|
+
ksuBonusMultiplier: result[1].toNumber(),
|
|
148
|
+
isActive: result[2],
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
async userTotalDeposits(userAddress: string): Promise<BigNumber> {
|
|
153
|
+
return await this._contractAbi.userTotalDeposits(userAddress);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
async calculateUserLockProjectedProtocolFeeRewards(
|
|
157
|
+
epochId: string,
|
|
158
|
+
KSULocked: number,
|
|
159
|
+
lockPeriod: BigNumber,
|
|
160
|
+
): Promise<number> {
|
|
161
|
+
if (KSULocked === 0) {
|
|
162
|
+
return 0;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
const lockingSummarySubgraph: LockingSummarySubgraphResult =
|
|
166
|
+
await this._graph.request(lockingSummariesQuery);
|
|
167
|
+
const lockingSummary = lockingSummarySubgraph.lockingSummaries[0];
|
|
168
|
+
const totalRKSU = lockingSummary.totalRKsuAmount;
|
|
169
|
+
|
|
170
|
+
const lockDetails = await this.lockDetails(lockPeriod);
|
|
171
|
+
|
|
172
|
+
const newUserRKSU =
|
|
173
|
+
(KSULocked + KSULocked * lockDetails.ksuBonusMultiplier) *
|
|
174
|
+
lockDetails.rKsuMultiplier;
|
|
175
|
+
const totalRKSUAfterLock = totalRKSU + newUserRKSU;
|
|
176
|
+
|
|
177
|
+
const systemVariables: SystemVariables = await this._graph.request(
|
|
178
|
+
getSystemVariablesQuery,
|
|
179
|
+
);
|
|
180
|
+
const performanceFee =
|
|
181
|
+
parseFloat(systemVariables.systemVariables.performanceFee) / 100;
|
|
182
|
+
const ecosystemFee =
|
|
183
|
+
parseFloat(systemVariables.systemVariables.ecosystemFeeRate) / 100;
|
|
184
|
+
|
|
185
|
+
let projectedYearlyPlatformInterest = 0;
|
|
186
|
+
const subgraphResults: TrancheSubgraphResult =
|
|
187
|
+
await this._graph.request(getAllTranchesQuery, {
|
|
188
|
+
unusedPools: this._kasuConfig.UNUSED_LENDING_POOL_IDS,
|
|
189
|
+
});
|
|
190
|
+
const subgraphConfigurationResults: TrancheConfigurationSubgraphResult =
|
|
191
|
+
await this._graph.request(getAllTrancheConfigurationsQuery, {
|
|
192
|
+
unusedPools: this._kasuConfig.UNUSED_LENDING_POOL_IDS,
|
|
193
|
+
epochId,
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
for (const tranche of subgraphResults.lendingPoolTranches) {
|
|
197
|
+
const trancheConfig =
|
|
198
|
+
subgraphConfigurationResults.lendingPoolTrancheConfigurations.find(
|
|
199
|
+
(r) => r.id == tranche.id,
|
|
200
|
+
);
|
|
201
|
+
if (!trancheConfig) {
|
|
202
|
+
console.warn(
|
|
203
|
+
"Couldn't find tranche configuration for id: ",
|
|
204
|
+
tranche.id,
|
|
205
|
+
);
|
|
206
|
+
continue;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
const interestUpdates =
|
|
210
|
+
trancheConfig.lendingPoolTrancheInterestRateUpdates;
|
|
211
|
+
|
|
212
|
+
const interestRate = interestUpdates.length
|
|
213
|
+
? interestUpdates[0].epochInterestRate
|
|
214
|
+
: trancheConfig.interestRate;
|
|
215
|
+
|
|
216
|
+
projectedYearlyPlatformInterest +=
|
|
217
|
+
parseFloat(tranche.balance) *
|
|
218
|
+
this.calculateApy(parseFloat(interestRate));
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
const totalExpectedEcosystemFees =
|
|
222
|
+
projectedYearlyPlatformInterest * performanceFee * ecosystemFee;
|
|
223
|
+
return (
|
|
224
|
+
(totalExpectedEcosystemFees * newUserRKSU) /
|
|
225
|
+
parseFloat(totalRKSUAfterLock)
|
|
226
|
+
);
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
calculateApy(epochInterestRate: number): number {
|
|
230
|
+
const EPOCHS_IN_YEAR = 52.17857;
|
|
231
|
+
return (1 + epochInterestRate) ^ (EPOCHS_IN_YEAR - 1);
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
async getUserLocks(userAddress: string): Promise<UserLock[]> {
|
|
235
|
+
const result: GQLUserLocks = await this._graph.request(userLocksQuery, {
|
|
236
|
+
userAddress: userAddress.toLowerCase(),
|
|
237
|
+
});
|
|
238
|
+
const resultPromises = result.userLocks.map(async (userLock) => {
|
|
239
|
+
const [, id] = userLock.id.split('-');
|
|
240
|
+
const rKSUtoUSDCRatio = await this.getRKSUvsUSDCRatio(
|
|
241
|
+
userLock.rKSUAmount,
|
|
242
|
+
userAddress,
|
|
243
|
+
);
|
|
244
|
+
const loyaltyStatus =
|
|
245
|
+
this.getLoyaltyLevelAndApyBonusFromRatio(rKSUtoUSDCRatio);
|
|
246
|
+
return {
|
|
247
|
+
id: BigNumber.from(id),
|
|
248
|
+
lockedAmount: userLock.ksuAmount,
|
|
249
|
+
rKSUAmount: userLock.rKSUAmount,
|
|
250
|
+
rKSUtoUSDCRatio: rKSUtoUSDCRatio,
|
|
251
|
+
apyBonus: loyaltyStatus.apyBonus,
|
|
252
|
+
loyaltyLevel: loyaltyStatus.loyaltyLevel,
|
|
253
|
+
startTime: parseFloat(userLock.startTimestamp),
|
|
254
|
+
endTime: parseFloat(userLock.endTimestamp),
|
|
255
|
+
lockPeriod: userLock.lockPeriod,
|
|
256
|
+
};
|
|
257
|
+
});
|
|
258
|
+
|
|
259
|
+
const results = await Promise.all(resultPromises);
|
|
260
|
+
return results.sort((a, b) => a.endTime - b.endTime);
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
async getUserBonusData(userAddress: string): Promise<UserBonusData> {
|
|
264
|
+
// TODO this userLocks query is kinda bad -> change to userLocksDepositInfo as u never need user locks by themselves
|
|
265
|
+
// whole function takes between 500 - 800ms
|
|
266
|
+
|
|
267
|
+
const DECIMALS = 18;
|
|
268
|
+
|
|
269
|
+
// Normalized user address
|
|
270
|
+
const normalizedAddress = userAddress.toLowerCase();
|
|
271
|
+
|
|
272
|
+
// Fetch data concurrently
|
|
273
|
+
const [
|
|
274
|
+
userLocksData,
|
|
275
|
+
resultLoyaltyRewards,
|
|
276
|
+
protocolFeesEarned,
|
|
277
|
+
userRewards,
|
|
278
|
+
] = await Promise.all([
|
|
279
|
+
this._graph.request<GQLUserLocks>(userLocksQuery, {
|
|
280
|
+
userAddress: normalizedAddress,
|
|
281
|
+
}),
|
|
282
|
+
this._graph.request<totalUserLoyaltyRewards>(
|
|
283
|
+
getTotalUserLoyaltsRewardsQuery,
|
|
284
|
+
{ userAddress: normalizedAddress },
|
|
285
|
+
),
|
|
286
|
+
this._contractAbi.rewards(userAddress),
|
|
287
|
+
this._userLoyaltyRewardsAbi.userRewards(userAddress),
|
|
288
|
+
]);
|
|
289
|
+
|
|
290
|
+
// Extract data and format with fallback
|
|
291
|
+
const { userLocks } = userLocksData;
|
|
292
|
+
|
|
293
|
+
const formattedKsuBonusAndRewards = ethers.utils.formatUnits(
|
|
294
|
+
userRewards,
|
|
295
|
+
DECIMALS,
|
|
296
|
+
);
|
|
297
|
+
const formattedProtocolFeesEarned = ethers.utils.formatUnits(
|
|
298
|
+
protocolFeesEarned,
|
|
299
|
+
DECIMALS,
|
|
300
|
+
);
|
|
301
|
+
|
|
302
|
+
const ksuBonusAndRewardsLifetime =
|
|
303
|
+
resultLoyaltyRewards.user === null
|
|
304
|
+
? '0.0'
|
|
305
|
+
: resultLoyaltyRewards.user.totalUserLoyaltyRewards;
|
|
306
|
+
|
|
307
|
+
const totalLockedAmount =
|
|
308
|
+
userLocks.length === 0
|
|
309
|
+
? '0.0'
|
|
310
|
+
: userLocks[0].userLockDepositsInfo.ksuLockedAmount;
|
|
311
|
+
|
|
312
|
+
// Construct response data
|
|
313
|
+
return {
|
|
314
|
+
ksuBonusAndRewards: formattedKsuBonusAndRewards,
|
|
315
|
+
ksuBonusAndRewardsLifetime: ksuBonusAndRewardsLifetime,
|
|
316
|
+
protocolFeesEarned: formattedProtocolFeesEarned,
|
|
317
|
+
totalLockedAmount: totalLockedAmount,
|
|
318
|
+
};
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
getLoyaltyLevelAndApyBonusFromRatio(rKSUtoUSDCRatio: number): {
|
|
322
|
+
loyaltyLevel: number;
|
|
323
|
+
apyBonus: number;
|
|
324
|
+
} {
|
|
325
|
+
if (rKSUtoUSDCRatio < 0.01) {
|
|
326
|
+
return { loyaltyLevel: 0, apyBonus: this.apyBonuses[0] };
|
|
327
|
+
} else if (rKSUtoUSDCRatio < 0.05) {
|
|
328
|
+
return { loyaltyLevel: 1, apyBonus: this.apyBonuses[1] };
|
|
329
|
+
}
|
|
330
|
+
return { loyaltyLevel: 2, apyBonus: this.apyBonuses[2] };
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
async getRKSUvsUSDCRatio(
|
|
334
|
+
rKSUAmount: string,
|
|
335
|
+
userAddress: string,
|
|
336
|
+
): Promise<number> {
|
|
337
|
+
const [depositedAmount, pendingAmount]: [BigNumber, BigNumber] =
|
|
338
|
+
await this._userManagerAbi.userTotalPendingAndActiveDepositedAmountForCurrentEpoch(
|
|
339
|
+
userAddress,
|
|
340
|
+
);
|
|
341
|
+
const ksuPrice: BigNumber =
|
|
342
|
+
await this._systemVariablesAbi.ksuEpochTokenPrice();
|
|
343
|
+
const rKSUAmountBignumber: BigNumber = ethers.utils.parseUnits(
|
|
344
|
+
rKSUAmount,
|
|
345
|
+
18,
|
|
346
|
+
);
|
|
347
|
+
|
|
348
|
+
const totalUserUsdcAmount =
|
|
349
|
+
depositedAmount.toNumber() + pendingAmount.toNumber();
|
|
350
|
+
|
|
351
|
+
const rKSUInUSDC = rKSUAmountBignumber
|
|
352
|
+
.mul(ksuPrice)
|
|
353
|
+
.div(ethers.utils.parseUnits('1', 18))
|
|
354
|
+
.div(ethers.utils.parseUnits('1', 12));
|
|
355
|
+
|
|
356
|
+
return rKSUInUSDC.toNumber() / totalUserUsdcAmount;
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
async getClaimableRewards(userAddress: string): Promise<BigNumber> {
|
|
360
|
+
const result = await this._contractAbi.rewards(userAddress);
|
|
361
|
+
return result;
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
async getKasuTokenPrice(): Promise<{ price: BigNumber; decimals: number }> {
|
|
365
|
+
const decimals = 18;
|
|
366
|
+
|
|
367
|
+
return Promise.resolve({
|
|
368
|
+
price: await this._ksuPriceAbi.ksuTokenPrice(),
|
|
369
|
+
decimals,
|
|
370
|
+
});
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
async getKasuEpochTokenPrice(): Promise<{
|
|
374
|
+
price: BigNumber;
|
|
375
|
+
decimals: number;
|
|
376
|
+
}> {
|
|
377
|
+
const decimals = 18;
|
|
378
|
+
|
|
379
|
+
return Promise.resolve({
|
|
380
|
+
price: await this._systemVariablesAbi.ksuEpochTokenPrice(),
|
|
381
|
+
decimals,
|
|
382
|
+
});
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
async getLifetimeRewards(
|
|
386
|
+
userAddress: string,
|
|
387
|
+
rewardDecimals: number,
|
|
388
|
+
claimableRewards?: BigNumber,
|
|
389
|
+
): Promise<BigNumber> {
|
|
390
|
+
const result: GQLClaimedFeesForAddress = await this._graph.request(
|
|
391
|
+
claimedFeesQuery,
|
|
392
|
+
{
|
|
393
|
+
userAddress: userAddress.toLowerCase(),
|
|
394
|
+
},
|
|
395
|
+
);
|
|
396
|
+
|
|
397
|
+
const claimedRewards = result.userLockDepositsInfo?.feesClaimed ?? '0';
|
|
398
|
+
|
|
399
|
+
if (!claimableRewards) {
|
|
400
|
+
claimableRewards = await this.getClaimableRewards(userAddress);
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
return claimableRewards.add(parseUnits(claimedRewards, rewardDecimals));
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
getLaunchBonusAmount(
|
|
407
|
+
lockAmount: BigNumber,
|
|
408
|
+
bonusMultiplier: number,
|
|
409
|
+
bonusTokensLeft: BigNumber,
|
|
410
|
+
): BigNumber {
|
|
411
|
+
const bonusMultiplierBN = ethers.utils.parseUnits(
|
|
412
|
+
bonusMultiplier.toFixed(2),
|
|
413
|
+
2,
|
|
414
|
+
);
|
|
415
|
+
const projectedBonus = lockAmount.mul(bonusMultiplierBN).div(100);
|
|
416
|
+
|
|
417
|
+
if (bonusTokensLeft.gt(projectedBonus)) {
|
|
418
|
+
return projectedBonus;
|
|
419
|
+
} else {
|
|
420
|
+
return bonusTokensLeft;
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
async getUserStakedKsu(userAddress: string): Promise<string> {
|
|
425
|
+
const result: GQLStakedAmountForAddress = await this._graph.request(
|
|
426
|
+
userStakedKsuQuery,
|
|
427
|
+
{
|
|
428
|
+
userAddress: userAddress.toLowerCase(),
|
|
429
|
+
},
|
|
430
|
+
);
|
|
431
|
+
if (result.userLockDepositsInfo == null) {
|
|
432
|
+
return '0';
|
|
433
|
+
}
|
|
434
|
+
return result.userLockDepositsInfo.ksuLockedAmount;
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
async getUserEarnedrKsu(userAddress: string): Promise<string> {
|
|
438
|
+
const result: GQLEarnedRKsuForAddress = await this._graph.request(
|
|
439
|
+
userEarnedrKsuQuery,
|
|
440
|
+
{
|
|
441
|
+
userAddress: userAddress.toLowerCase(),
|
|
442
|
+
},
|
|
443
|
+
);
|
|
444
|
+
if (result.userLockDepositsInfo == null) {
|
|
445
|
+
return '0';
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
return result.userLockDepositsInfo.rKSUAmount;
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
async getUserTotalBonusAmount(userAddress: string): Promise<string> {
|
|
452
|
+
const result: GQLTotalBonusAmountForAddress = await this._graph.request(
|
|
453
|
+
userTotalBonusAmountQuery,
|
|
454
|
+
{
|
|
455
|
+
userAddress: userAddress.toLowerCase(),
|
|
456
|
+
},
|
|
457
|
+
);
|
|
458
|
+
if (result.userLockDepositsInfo == null) {
|
|
459
|
+
return '0';
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
return result.userLockDepositsInfo.totalKsuBonusAmount;
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
async getLockingRewards(
|
|
466
|
+
userAddress: string,
|
|
467
|
+
): Promise<{ claimableRewards: string; lifeTimeRewards: string }> {
|
|
468
|
+
const rewardDecimals = 6;
|
|
469
|
+
|
|
470
|
+
const claimableRewards = await this.getClaimableRewards(userAddress);
|
|
471
|
+
|
|
472
|
+
const lifeTimeRewards = await this.getLifetimeRewards(
|
|
473
|
+
userAddress,
|
|
474
|
+
rewardDecimals,
|
|
475
|
+
claimableRewards,
|
|
476
|
+
);
|
|
477
|
+
|
|
478
|
+
return {
|
|
479
|
+
claimableRewards: formatUnits(claimableRewards, rewardDecimals),
|
|
480
|
+
lifeTimeRewards: formatUnits(lifeTimeRewards, rewardDecimals),
|
|
481
|
+
};
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
async getTotalKsuStaked(): Promise<string> {
|
|
485
|
+
return Promise.resolve(ethers.constants.Zero.toString());
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
async getAvailableKsuBonus(): Promise<string> {
|
|
489
|
+
const amount = await this._kasuToken.balanceOf(this._kasuBonusAddress);
|
|
490
|
+
|
|
491
|
+
return formatEther(amount);
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
async getUserKsuBalance(userAddress: string): Promise<string> {
|
|
495
|
+
const balance = await this._kasuToken.balanceOf(
|
|
496
|
+
userAddress.toLowerCase(),
|
|
497
|
+
);
|
|
498
|
+
|
|
499
|
+
return formatEther(balance);
|
|
500
|
+
}
|
|
501
|
+
async getNextEpochDate(): Promise<EpochTimeStamp> {
|
|
502
|
+
return (
|
|
503
|
+
await this._systemVariablesAbi.nextEpochStartTimestamp()
|
|
504
|
+
).toNumber();
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
async getNextClearingPeriodDate(): Promise<EpochTimeStamp> {
|
|
508
|
+
const nextEpochDate = await this.getNextEpochDate();
|
|
509
|
+
|
|
510
|
+
const clearingPeriodLength =
|
|
511
|
+
await this._systemVariablesAbi.clearingPeriodLength();
|
|
512
|
+
|
|
513
|
+
const nextClearingPeriod = BigNumber.from(nextEpochDate)
|
|
514
|
+
.sub(clearingPeriodLength)
|
|
515
|
+
.toNumber();
|
|
516
|
+
|
|
517
|
+
const nowUnix = Date.now() / 1000;
|
|
518
|
+
|
|
519
|
+
if (nowUnix >= nextClearingPeriod) {
|
|
520
|
+
const oneWeek = 604800; // in seconds
|
|
521
|
+
|
|
522
|
+
return nextClearingPeriod + oneWeek;
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
return nextClearingPeriod;
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
async getActiveLockPeriods(): Promise<LockPeriod[]> {
|
|
529
|
+
const data: GQLGetLockingPeriods =
|
|
530
|
+
await this._graph.request(lockingPeriodsQuery);
|
|
531
|
+
return data.lockPeriods;
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
getProjectedApy(): string {
|
|
535
|
+
return '10.00';
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
getProjectedUSDC(): string {
|
|
539
|
+
return '20.00';
|
|
540
|
+
}
|
|
541
|
+
}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { gql } from 'graphql-request';
|
|
2
|
+
|
|
3
|
+
export const claimedFeesQuery = gql`
|
|
4
|
+
query GetClaimedFeesForAddress($userAddress: String!) {
|
|
5
|
+
userLockDepositsInfo(id: $userAddress) {
|
|
6
|
+
feesClaimed
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
`;
|
|
10
|
+
|
|
11
|
+
export const userEarnedrKsuQuery = gql`
|
|
12
|
+
query GetClaimedFeesForAddress($userAddress: String!) {
|
|
13
|
+
userLockDepositsInfo(id: $userAddress) {
|
|
14
|
+
rKSUAmount
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
`;
|
|
18
|
+
|
|
19
|
+
export const userTotalBonusAmountQuery = gql`
|
|
20
|
+
query GetClaimedFeesForAddress($userAddress: String!) {
|
|
21
|
+
userLockDepositsInfo(id: $userAddress) {
|
|
22
|
+
totalKsuBonusAmount
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
`;
|
|
26
|
+
|
|
27
|
+
export const userStakedKsuQuery = gql`
|
|
28
|
+
query GetUserLockDepositsInfo($userAddress: String!) {
|
|
29
|
+
userLockDepositsInfo(id: $userAddress) {
|
|
30
|
+
ksuLockedAmount
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
`;
|
|
34
|
+
|
|
35
|
+
export const userLocksQuery = gql`
|
|
36
|
+
query GetUserLocks($userAddress: String!) {
|
|
37
|
+
userLocks(
|
|
38
|
+
where: { userLockDepositsInfo: $userAddress, ksuAmount_gt: 0 }
|
|
39
|
+
) {
|
|
40
|
+
id
|
|
41
|
+
ksuAmount
|
|
42
|
+
endTimestamp
|
|
43
|
+
startTimestamp
|
|
44
|
+
lockPeriod {
|
|
45
|
+
rKSUMultiplier
|
|
46
|
+
lockPeriod
|
|
47
|
+
ksuBonusMultiplier
|
|
48
|
+
id
|
|
49
|
+
}
|
|
50
|
+
rKSUAmount
|
|
51
|
+
userLockDepositsInfo {
|
|
52
|
+
totalKsuBonusAmount
|
|
53
|
+
rKSUAmount
|
|
54
|
+
ksuLockedAmount
|
|
55
|
+
id
|
|
56
|
+
feesClaimed
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
`;
|
|
61
|
+
|
|
62
|
+
export const lockingPeriodsQuery = gql`
|
|
63
|
+
query LockingPeriodsQuery {
|
|
64
|
+
lockPeriods(orderBy: lockPeriod, where: { isActive: true }) {
|
|
65
|
+
rKSUMultiplier
|
|
66
|
+
lockPeriod
|
|
67
|
+
ksuBonusMultiplier
|
|
68
|
+
isActive
|
|
69
|
+
id
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
`;
|
|
73
|
+
|
|
74
|
+
export const lockingSummariesQuery = gql`
|
|
75
|
+
query LockingSummariesQuery {
|
|
76
|
+
lockingSummaries {
|
|
77
|
+
id
|
|
78
|
+
totalRKsuAmount
|
|
79
|
+
totalKsuLockedAmount
|
|
80
|
+
totalFeesEmitted
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
`;
|
|
84
|
+
|
|
85
|
+
export const getAllTranchesQuery = gql`
|
|
86
|
+
query getAllTranches($unusedPools: [String]!) {
|
|
87
|
+
lendingPoolTranches(where: { lendingPool_not_in: $unusedPools }) {
|
|
88
|
+
id
|
|
89
|
+
balance
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
`;
|
|
93
|
+
|
|
94
|
+
export const getTotalUserLoyaltsRewardsQuery = gql`
|
|
95
|
+
query getAllUserLoyaltsRewards($userAddress: String!) {
|
|
96
|
+
user(id: $userAddress) {
|
|
97
|
+
id
|
|
98
|
+
totalUserLoyaltyRewards
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
`;
|
|
102
|
+
|
|
103
|
+
export const getSystemVariablesQuery = gql`
|
|
104
|
+
query getSystemVariablesQuery {
|
|
105
|
+
systemVariables(id: "SYSTEM_VARIABLES") {
|
|
106
|
+
id
|
|
107
|
+
protocolFeeRate
|
|
108
|
+
priceUpdateEpoch
|
|
109
|
+
performanceFee
|
|
110
|
+
loyaltyThresholds
|
|
111
|
+
ksuEpochTokenPrice
|
|
112
|
+
epochDuration
|
|
113
|
+
ecosystemFeeRate
|
|
114
|
+
clearingPeriodLength
|
|
115
|
+
canOnlyDepositJuniorWhenUserHasRKSU
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
`;
|