impermax-sdk 1.0.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/.idea/impermax-sdk.iml +12 -0
- package/.idea/misc.xml +6 -0
- package/.idea/modules.xml +8 -0
- package/.idea/workspace.xml +642 -0
- package/abis/ImpermaxABI.ts +3 -0
- package/abis/contracts/BAllowance.json +4735 -0
- package/abis/contracts/BDeployer.json +1195 -0
- package/abis/contracts/BInterestRateModel.json +10796 -0
- package/abis/contracts/BSetter.json +6219 -0
- package/abis/contracts/BStorage.json +2613 -0
- package/abis/contracts/Borrowable.json +19937 -0
- package/abis/contracts/CDeployer.json +1104 -0
- package/abis/contracts/CSetter.json +5094 -0
- package/abis/contracts/CStorage.json +516 -0
- package/abis/contracts/ClaimAggregator.json +2015 -0
- package/abis/contracts/Collateral.json +21615 -0
- package/abis/contracts/ERC20.json +819 -0
- package/abis/contracts/Factory.json +21986 -0
- package/abis/contracts/FarmingPool.json +8601 -0
- package/abis/contracts/IBDeployer.json +351 -0
- package/abis/contracts/IBorrowTracker.json +346 -0
- package/abis/contracts/IBorrowable.json +13207 -0
- package/abis/contracts/ICDeployer.json +294 -0
- package/abis/contracts/IClaimable.json +406 -0
- package/abis/contracts/ICollateral.json +8952 -0
- package/abis/contracts/IERC20.json +2376 -0
- package/abis/contracts/IFactory.json +3660 -0
- package/abis/contracts/IFarmingPool.json +3584 -0
- package/abis/contracts/IImpermaxCallee.json +679 -0
- package/abis/contracts/IMerkleDistributor.json +1134 -0
- package/abis/contracts/IPoolToken.json +5343 -0
- package/abis/contracts/IRouter01.json +6891 -0
- package/abis/contracts/IRouter02.json +7283 -0
- package/abis/contracts/ISimpleUniswapOracle.json +1469 -0
- package/abis/contracts/IStakedLPToken.json +7309 -0
- package/abis/contracts/IStakingRewards.json +1036 -0
- package/abis/contracts/IUniswapV2Callee.json +403 -0
- package/abis/contracts/IUniswapV2ERC20.json +3155 -0
- package/abis/contracts/IUniswapV2Factory.json +1690 -0
- package/abis/contracts/IUniswapV2Pair.json +6761 -0
- package/abis/contracts/IWETH.json +561 -0
- package/abis/contracts/ImpermaxChef.json +20945 -0
- package/abis/contracts/ImpermaxERC20.json +12095 -0
- package/abis/contracts/Math.json +1966 -0
- package/abis/contracts/MockERC20.json +8884 -0
- package/abis/contracts/PoolToken.json +10784 -0
- package/abis/contracts/Router01.json +43963 -0
- package/abis/contracts/SafeMath.json +6828 -0
- package/abis/contracts/SimpleUniswapOracle.json +9640 -0
- package/abis/contracts/TransferHelper.json +4875 -0
- package/abis/contracts/UQ112x112.json +1201 -0
- package/abis/contracts/UniswapV2ERC20.json +10969 -0
- package/abis/contracts/UniswapV2Factory.json +5521 -0
- package/abis/contracts/UniswapV2Library.json +13789 -0
- package/abis/contracts/UniswapV2Pair.json +30782 -0
- package/abis/contracts/WETH9.json +6613 -0
- package/config/amms.ts +199 -0
- package/config/contracts/claim-aggregators.ts +16 -0
- package/config/contracts/impermax-chef.ts +16 -0
- package/config/contracts/imxes.ts +16 -0
- package/config/contracts/merkle-distributors.ts +13 -0
- package/config/contracts/routers.ts +36 -0
- package/config/contracts/simple-uniswap-oracles.ts +33 -0
- package/config/contracts/weths.ts +18 -0
- package/config/debank-ids.ts +15 -0
- package/config/endpoints/merkle-distributors.ts +13 -0
- package/config/eth.ts +32 -0
- package/config/factories.ts +26 -0
- package/config/farms.ts +119 -0
- package/config/general.ts +8 -0
- package/config/subgraphs.ts +69 -0
- package/config/types.ts +81 -0
- package/impermax-router/Account.ts +123 -0
- package/impermax-router/AccountBorrowable.ts +110 -0
- package/impermax-router/AccountCollateral.ts +40 -0
- package/impermax-router/AccountLendingPool.ts +231 -0
- package/impermax-router/AccountPoolToken.ts +76 -0
- package/impermax-router/Borrowable.ts +86 -0
- package/impermax-router/Collateral.ts +26 -0
- package/impermax-router/ContractsHelper.ts +64 -0
- package/impermax-router/ImpermaxFactory.ts +47 -0
- package/impermax-router/Interactions.ts +94 -0
- package/impermax-router/InteractionsLendingPool.ts +129 -0
- package/impermax-router/InteractionsPoolToken.ts +187 -0
- package/impermax-router/LendingPool.ts +256 -0
- package/impermax-router/PoolToken.ts +112 -0
- package/impermax-router/index.ts +49 -0
- package/impermax-router/interfaces.ts +233 -0
- package/index.ts +5 -0
- package/package.json +23 -0
- package/subgraph/Account.ts +93 -0
- package/subgraph/AccountLendingPool.ts +60 -0
- package/subgraph/AccountPoolToken.ts +60 -0
- package/subgraph/LendingPool.ts +179 -0
- package/subgraph/PoolToken.ts +381 -0
- package/subgraph/PriceHelper.ts +150 -0
- package/subgraph/SolidexHelper.ts +54 -0
- package/subgraph/index.ts +166 -0
- package/subgraph/initializer.ts +509 -0
- package/subgraph/query.ts +224 -0
- package/tsconfig.json +16 -0
- package/utils/ether-utils.ts +22 -0
- package/utils/index.ts +12 -0
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
import { PendingRewardUI } from "./interfaces";
|
|
2
|
+
|
|
3
|
+
import PoolToken from "./PoolToken";
|
|
4
|
+
import ImpermaxFactory from "./ImpermaxFactory";
|
|
5
|
+
import { Contract } from "ethers";
|
|
6
|
+
import Collateral from "./Collateral";
|
|
7
|
+
import Borrowable from "./Borrowable";
|
|
8
|
+
import { Address, PoolTokenType } from '../config/types';
|
|
9
|
+
import { SOLIDEX_FACTORIES } from '../config/factories';
|
|
10
|
+
|
|
11
|
+
export default class LendingPool {
|
|
12
|
+
factory: ImpermaxFactory;
|
|
13
|
+
pairAddress: Address;
|
|
14
|
+
poolTokens: {
|
|
15
|
+
[PoolTokenType.Collateral]: Collateral,
|
|
16
|
+
[PoolTokenType.BorrowableA]: Borrowable,
|
|
17
|
+
[PoolTokenType.BorrowableB]: Borrowable,
|
|
18
|
+
};
|
|
19
|
+
cache: {
|
|
20
|
+
poolTokenAddresses?: Promise<{
|
|
21
|
+
[key in PoolTokenType]: Address
|
|
22
|
+
}>
|
|
23
|
+
isStakedLPToken?: Promise<boolean>,
|
|
24
|
+
uniswapV2Pair?: Promise<Contract>, // native uniswap pair
|
|
25
|
+
stakedLPToken?: Promise<Contract>, // collateral underlying
|
|
26
|
+
reserves?: Promise<[number, number]>,
|
|
27
|
+
LPTotalSupply?: Promise<number>,
|
|
28
|
+
marketPrice?: Promise<number>,
|
|
29
|
+
priceDenomLP?: Promise<[number, number]>,
|
|
30
|
+
TWAPPrice?: Promise<number>,
|
|
31
|
+
pendingReward?: Promise<PendingRewardUI>,
|
|
32
|
+
reinvestBountyFactor?: Promise<number>,
|
|
33
|
+
stakedLPExchangeRate?: Promise<number>,
|
|
34
|
+
} = {};
|
|
35
|
+
|
|
36
|
+
constructor(factory: ImpermaxFactory, pairAddress: Address) {
|
|
37
|
+
this.factory = factory;
|
|
38
|
+
this.pairAddress = pairAddress;
|
|
39
|
+
this.poolTokens = {
|
|
40
|
+
[PoolTokenType.Collateral]: new Collateral(this, PoolTokenType.Collateral),
|
|
41
|
+
[PoolTokenType.BorrowableA]: new Borrowable(this, PoolTokenType.BorrowableA),
|
|
42
|
+
[PoolTokenType.BorrowableB]: new Borrowable(this, PoolTokenType.BorrowableB),
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
cleanCache() {
|
|
47
|
+
this.cache = {};
|
|
48
|
+
this.pta().cleanCache();
|
|
49
|
+
this.ptb().cleanCache();
|
|
50
|
+
this.ptc().cleanCache();
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// Shortcuts
|
|
54
|
+
pta = () => this.poolTokens[PoolTokenType.BorrowableA];
|
|
55
|
+
ptb = () => this.poolTokens[PoolTokenType.BorrowableB];
|
|
56
|
+
ptc = () => this.poolTokens[PoolTokenType.Collateral];
|
|
57
|
+
|
|
58
|
+
getPoolToken(poolTokenType: PoolTokenType) : PoolToken {
|
|
59
|
+
return this.poolTokens[poolTokenType];
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
async getSubgraphLendingPool() {
|
|
63
|
+
return this.factory.router.subgraph.getLendingPool(this.factory.factory, this.pairAddress);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
private async initializePoolTokenAddresses() {
|
|
67
|
+
const lPool = await this.factory.getRouter().methods.getLendingPool(this.pairAddress).call();
|
|
68
|
+
return {
|
|
69
|
+
[PoolTokenType.Collateral]: lPool.collateral as Address,
|
|
70
|
+
[PoolTokenType.BorrowableA]: lPool.borrowableA as Address,
|
|
71
|
+
[PoolTokenType.BorrowableB]: lPool.borrowableB as Address,
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
async getPoolTokenAddresses() {
|
|
75
|
+
if (!this.cache.poolTokenAddresses) this.cache.poolTokenAddresses = this.initializePoolTokenAddresses();
|
|
76
|
+
return this.cache.poolTokenAddresses;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
private async initializeIsStakedLPToken() : Promise<boolean> {
|
|
80
|
+
try {
|
|
81
|
+
return await this.factory.getRouter().methods.isStakedLPToken(this.pairAddress).call();
|
|
82
|
+
} catch (e) {
|
|
83
|
+
return false;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
async getIsStakedLPToken() {
|
|
87
|
+
if (!this.cache.isStakedLPToken) this.cache.isStakedLPToken = this.initializeIsStakedLPToken();
|
|
88
|
+
return this.cache.isStakedLPToken;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
private async initializeStakedLPToken() : Promise<Contract> {
|
|
92
|
+
if (!await this.getIsStakedLPToken()) return null;
|
|
93
|
+
return this.factory.router.contractsHelper.newStakedLPToken(this.pairAddress);
|
|
94
|
+
}
|
|
95
|
+
async getStakedLPToken() {
|
|
96
|
+
if (!this.cache.stakedLPToken) this.cache.stakedLPToken = this.initializeStakedLPToken();
|
|
97
|
+
return this.cache.stakedLPToken;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
private async initializeUniswapV2Pair() : Promise<Contract> {
|
|
101
|
+
return this.factory.router.contractsHelper.newUniswapV2Pair(
|
|
102
|
+
await this.getIsStakedLPToken()
|
|
103
|
+
? await (await this.getStakedLPToken()).methods.underlying().call()
|
|
104
|
+
: this.pairAddress
|
|
105
|
+
);
|
|
106
|
+
}
|
|
107
|
+
async getUniswapV2Pair() {
|
|
108
|
+
if (!this.cache.uniswapV2Pair) this.cache.uniswapV2Pair = this.initializeUniswapV2Pair();
|
|
109
|
+
return this.cache.uniswapV2Pair;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// Reserves
|
|
113
|
+
private async initializeReserves() : Promise<[number, number]> {
|
|
114
|
+
const uniswapV2Pair = await this.getUniswapV2Pair();
|
|
115
|
+
const { reserve0, reserve1 } = await uniswapV2Pair.methods.getReserves().call();
|
|
116
|
+
return [
|
|
117
|
+
await this.pta().normalize(reserve0),
|
|
118
|
+
await this.ptb().normalize(reserve1),
|
|
119
|
+
];
|
|
120
|
+
}
|
|
121
|
+
async getReserves() {
|
|
122
|
+
if (!this.cache.reserves) this.cache.reserves = this.initializeReserves();
|
|
123
|
+
return this.cache.reserves;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// LP Total Supply
|
|
127
|
+
private async initializeLPTotalSupply() {
|
|
128
|
+
const uniswapV2Pair = await this.getUniswapV2Pair();
|
|
129
|
+
const totalSupply = await uniswapV2Pair.methods.totalSupply().call();
|
|
130
|
+
return this.ptc().normalize(totalSupply);
|
|
131
|
+
}
|
|
132
|
+
async getLPTotalSupply() : Promise<number> {
|
|
133
|
+
if (!this.cache.LPTotalSupply) this.cache.LPTotalSupply = this.initializeLPTotalSupply();
|
|
134
|
+
return this.cache.LPTotalSupply;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// Price Denom LP
|
|
138
|
+
private async initializePriceDenomLP() : Promise<[number, number]> {
|
|
139
|
+
const collateral = await this.ptc().getPoolToken();
|
|
140
|
+
const { price0, price1 } = await collateral.methods.getPrices().call();
|
|
141
|
+
const decimalsA = await this.pta().getDecimals();
|
|
142
|
+
const decimalsB = await this.ptb().getDecimals();
|
|
143
|
+
let stakedLPExchangeRate = await this.getStakedLPExchangeRate();
|
|
144
|
+
return [
|
|
145
|
+
price0 / 1e18 / 1e18 * Math.pow(10, decimalsA) * stakedLPExchangeRate,
|
|
146
|
+
price1 / 1e18 / 1e18 * Math.pow(10, decimalsB) * stakedLPExchangeRate
|
|
147
|
+
];
|
|
148
|
+
}
|
|
149
|
+
async getPriceDenomLP() {
|
|
150
|
+
if (!this.cache.priceDenomLP) this.cache.priceDenomLP = this.initializePriceDenomLP();
|
|
151
|
+
return this.cache.priceDenomLP;
|
|
152
|
+
}
|
|
153
|
+
async getMarketPriceDenomLP() : Promise<[number, number]> {
|
|
154
|
+
const [reserve0, reserve1] = await this.getReserves();
|
|
155
|
+
const totalSupply = await this.getLPTotalSupply();
|
|
156
|
+
return [
|
|
157
|
+
totalSupply / reserve0 / 2,
|
|
158
|
+
totalSupply / reserve1 / 2,
|
|
159
|
+
];
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// Market Price
|
|
163
|
+
async getMarketPrice() : Promise<number> {
|
|
164
|
+
const [reserve0, reserve1] = await this.getReserves();
|
|
165
|
+
return this.factory.router.priceInverted ? 1 * reserve0 / reserve1 : 1 * reserve1 / reserve0;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// TWAP Price
|
|
169
|
+
private async initializeTWAPPrice() : Promise<number> {
|
|
170
|
+
try {
|
|
171
|
+
let price;
|
|
172
|
+
if (SOLIDEX_FACTORIES.includes(this.factory.factory)) {
|
|
173
|
+
const collateral = await this.ptc().getPoolToken();
|
|
174
|
+
price = await collateral.methods.getTwapPrice112x112().call();
|
|
175
|
+
} else {
|
|
176
|
+
price = (await this.factory.getSimpleUniswapOracle().methods.getResult(this.pairAddress).call()).price;
|
|
177
|
+
}
|
|
178
|
+
const decimalsA = await this.pta().getDecimals();
|
|
179
|
+
const decimalsB = await this.ptb().getDecimals();
|
|
180
|
+
return price / 2**112 * Math.pow(10, decimalsA) / Math.pow(10, decimalsB);
|
|
181
|
+
}
|
|
182
|
+
catch (e) {
|
|
183
|
+
// Oracle is not initialized yet
|
|
184
|
+
return 0;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
async getTWAPPrice() : Promise<number> {
|
|
188
|
+
if (!this.cache.TWAPPrice) this.cache.TWAPPrice = this.initializeTWAPPrice();
|
|
189
|
+
return !this.factory.router.priceInverted ? (await this.cache.TWAPPrice) : 1 / (await this.cache.TWAPPrice);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// Exchange rate
|
|
193
|
+
private async initializeStakedLPExchangeRate() : Promise<number> {
|
|
194
|
+
if (!await this.getIsStakedLPToken()) return 1;
|
|
195
|
+
const stakedLPToken = await this.getStakedLPToken();
|
|
196
|
+
return await stakedLPToken.methods.exchangeRate().call() / 1e18;
|
|
197
|
+
}
|
|
198
|
+
async getStakedLPExchangeRate() : Promise<number> {
|
|
199
|
+
if (!this.cache.stakedLPExchangeRate) this.cache.stakedLPExchangeRate = this.initializeStakedLPExchangeRate();
|
|
200
|
+
return this.cache.stakedLPExchangeRate;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
// Pending Reward
|
|
204
|
+
private async initializePendingReward() : Promise<PendingRewardUI> {
|
|
205
|
+
const stakedLPToken = await this.getStakedLPToken();
|
|
206
|
+
const rewardTokenAddress = await stakedLPToken.methods.rewardsToken().call();
|
|
207
|
+
const rewardToken = this.factory.router.contractsHelper.newERC20(rewardTokenAddress);
|
|
208
|
+
const decimals = await rewardToken.methods.decimals().call();
|
|
209
|
+
let result = {
|
|
210
|
+
amount: 0,
|
|
211
|
+
symbol: await rewardToken.methods.symbol().call(),
|
|
212
|
+
}
|
|
213
|
+
try {
|
|
214
|
+
const pendingReward = await stakedLPToken.methods.getReward().call();
|
|
215
|
+
result.amount = pendingReward / Math.pow(10, decimals);
|
|
216
|
+
}
|
|
217
|
+
catch {
|
|
218
|
+
try {
|
|
219
|
+
const stakingRewardsAddress = await stakedLPToken.methods.stakingRewards().call();
|
|
220
|
+
const stakingRewards = this.factory.router.contractsHelper.newStakingRewards(stakingRewardsAddress);
|
|
221
|
+
const earned = await stakingRewards.methods.earned(stakedLPToken._address).call();
|
|
222
|
+
result.amount = earned / Math.pow(10, decimals);
|
|
223
|
+
}
|
|
224
|
+
catch {}
|
|
225
|
+
}
|
|
226
|
+
return result;
|
|
227
|
+
}
|
|
228
|
+
async getPendingReward() : Promise<PendingRewardUI> {
|
|
229
|
+
if (!this.cache.pendingReward) this.cache.pendingReward = this.initializePendingReward();
|
|
230
|
+
return this.cache.pendingReward;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
// Reinvest Bounty Factor
|
|
234
|
+
private async initializeReinvestBountyFactor() : Promise<number> {
|
|
235
|
+
if (!await this.getIsStakedLPToken()) return 0;
|
|
236
|
+
const stakedLPToken = await this.getStakedLPToken();
|
|
237
|
+
return (await stakedLPToken.methods.REINVEST_BOUNTY().call()) / 1e18;
|
|
238
|
+
}
|
|
239
|
+
async getReinvestBountyFactor() : Promise<number> {
|
|
240
|
+
if (!this.cache.reinvestBountyFactor) this.cache.reinvestBountyFactor = this.initializeReinvestBountyFactor();
|
|
241
|
+
return this.cache.reinvestBountyFactor;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
// Reinvest Bounty
|
|
245
|
+
async getReinvestBounty() : Promise<number> {
|
|
246
|
+
const pendingReward = await this.getPendingReward();
|
|
247
|
+
const reinvestBountyFactor = await this.getReinvestBountyFactor();
|
|
248
|
+
return pendingReward.amount * reinvestBountyFactor;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
// Has Farming
|
|
252
|
+
async hasFarming() : Promise<boolean> {
|
|
253
|
+
return await this.pta().hasFarming() || await this.ptb().hasFarming();
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { BigNumber } from "ethers";
|
|
2
|
+
import { Contract } from "./interfaces";
|
|
3
|
+
import { isValidNumber } from "../utils";
|
|
4
|
+
import { decimalToBalance } from "../utils/ether-utils";
|
|
5
|
+
import LendingPool from "./LendingPool";
|
|
6
|
+
import { Address, PoolTokenType } from '../config/types';
|
|
7
|
+
|
|
8
|
+
export default abstract class PoolToken {
|
|
9
|
+
lendingPool: LendingPool;
|
|
10
|
+
poolTokenType: PoolTokenType;
|
|
11
|
+
cache: {
|
|
12
|
+
token?: Promise<Contract>,
|
|
13
|
+
poolToken?: Promise<Contract>,
|
|
14
|
+
exchangeRate?: Promise<number>,
|
|
15
|
+
totalBalance?: Promise<number>,
|
|
16
|
+
} = {};
|
|
17
|
+
|
|
18
|
+
constructor(lendingPool: LendingPool, poolTokenType: PoolTokenType) {
|
|
19
|
+
this.lendingPool = lendingPool;
|
|
20
|
+
this.poolTokenType = poolTokenType;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
cleanCache() {
|
|
24
|
+
this.cache = {}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
getContractHelper = () => this.lendingPool.factory.router.contractsHelper;
|
|
28
|
+
|
|
29
|
+
async getSubgraphPoolToken() {
|
|
30
|
+
const lendingPool = await this.lendingPool.getSubgraphLendingPool();
|
|
31
|
+
return lendingPool.poolTokens[this.poolTokenType];
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
protected async getPoolTokenAddressFromLendingPool() {
|
|
35
|
+
return (await this.lendingPool.getPoolTokenAddresses())[this.poolTokenType];
|
|
36
|
+
}
|
|
37
|
+
abstract initializePoolToken() : Promise<Contract>;
|
|
38
|
+
async getPoolToken() {
|
|
39
|
+
if (!this.cache.poolToken) this.cache.poolToken = this.initializePoolToken();
|
|
40
|
+
return this.cache.poolToken;
|
|
41
|
+
}
|
|
42
|
+
async getPoolTokenAddress() : Promise<Address> {
|
|
43
|
+
return (await this.getPoolToken())._address;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
abstract initializeToken() : Promise<Contract>;
|
|
47
|
+
async getToken() {
|
|
48
|
+
if (!this.cache.token) this.cache.token = this.initializeToken();
|
|
49
|
+
return this.cache.token;
|
|
50
|
+
}
|
|
51
|
+
async getTokenAddress() {
|
|
52
|
+
return (await this.getToken())._address;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
async getDecimals() {
|
|
56
|
+
const subgraph = await this.getSubgraphPoolToken();
|
|
57
|
+
return await subgraph.getDecimals();
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Utilities
|
|
61
|
+
async normalize(amount: number) : Promise<number> {
|
|
62
|
+
return amount / Math.pow(10, await this.getDecimals());
|
|
63
|
+
}
|
|
64
|
+
async toBigNumber(amount: number) : Promise<BigNumber> {
|
|
65
|
+
if (!isValidNumber(amount)) return null;
|
|
66
|
+
return decimalToBalance(amount, await this.getDecimals());
|
|
67
|
+
}
|
|
68
|
+
async toNumber(amount: BigNumber) : Promise<number> {
|
|
69
|
+
if (!amount) return null;
|
|
70
|
+
return parseFloat(amount.toString()) / Math.pow(10, await this.getDecimals());
|
|
71
|
+
}
|
|
72
|
+
async toTokens(amount: number) : Promise<BigNumber> {
|
|
73
|
+
if (!isValidNumber(amount)) return null;
|
|
74
|
+
const exchangeRate = await this.getExchangeRate();
|
|
75
|
+
return decimalToBalance(amount / exchangeRate, await this.getDecimals());
|
|
76
|
+
}
|
|
77
|
+
async fromTokens(amount: BigNumber) : Promise<number> {
|
|
78
|
+
if (!amount) return null;
|
|
79
|
+
const exchangeRate = await this.getExchangeRate();
|
|
80
|
+
return parseFloat(amount.toString()) * exchangeRate / Math.pow(10, await this.getDecimals());
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// Total balance
|
|
84
|
+
private async initializeTotalBalance() {
|
|
85
|
+
const poolToken = await this.getPoolToken();
|
|
86
|
+
const amount = await poolToken.methods.totalBalance().call();
|
|
87
|
+
return this.normalize(amount);
|
|
88
|
+
}
|
|
89
|
+
async getTotalBalance() {
|
|
90
|
+
if (!this.cache.totalBalance) this.cache.totalBalance = this.initializeTotalBalance();
|
|
91
|
+
return this.cache.totalBalance;
|
|
92
|
+
}
|
|
93
|
+
async getTotalBalanceUSD() {
|
|
94
|
+
const totalBalance = await this.getTotalBalance();
|
|
95
|
+
const subgraph = await this.getSubgraphPoolToken();
|
|
96
|
+
const tokenPrice = await subgraph.getTokenPriceFast();
|
|
97
|
+
return totalBalance * tokenPrice;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// Exchange rate
|
|
101
|
+
protected async initializeExchangeRate() : Promise<number> {
|
|
102
|
+
const poolToken = await this.getPoolToken();
|
|
103
|
+
let exchangeRate = await poolToken.methods.exchangeRate().call() / 1e18;
|
|
104
|
+
return exchangeRate;
|
|
105
|
+
}
|
|
106
|
+
async getExchangeRate() : Promise<number> {
|
|
107
|
+
if (!this.cache.exchangeRate) this.cache.exchangeRate = this.initializeExchangeRate();
|
|
108
|
+
return this.cache.exchangeRate;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ImpermaxRouterCfg
|
|
3
|
+
} from "./interfaces";
|
|
4
|
+
import Subgraph from "../subgraph";
|
|
5
|
+
import ContractsHelper from "./ContractsHelper";
|
|
6
|
+
import ImpermaxFactory from "./ImpermaxFactory";
|
|
7
|
+
import { Factory, FactoryIndex, Networks } from '../config/types';
|
|
8
|
+
|
|
9
|
+
export default class ImpermaxRouter {
|
|
10
|
+
network: Networks;
|
|
11
|
+
subgraph: Subgraph;
|
|
12
|
+
web3: any;
|
|
13
|
+
chainId: number;
|
|
14
|
+
|
|
15
|
+
contractsHelper: ContractsHelper;
|
|
16
|
+
factories: FactoryIndex<ImpermaxFactory>;
|
|
17
|
+
|
|
18
|
+
uiMargin: number;
|
|
19
|
+
dust: number;
|
|
20
|
+
priceInverted: boolean;
|
|
21
|
+
|
|
22
|
+
constructor(cfg: ImpermaxRouterCfg) {
|
|
23
|
+
this.network = cfg.network;
|
|
24
|
+
this.subgraph = cfg.subgraph;
|
|
25
|
+
this.web3 = cfg.web3;
|
|
26
|
+
this.chainId = cfg.chainId;
|
|
27
|
+
this.uiMargin = 1.1;
|
|
28
|
+
this.dust = 1.000001;
|
|
29
|
+
this.priceInverted = cfg.priceInverted;
|
|
30
|
+
|
|
31
|
+
this.contractsHelper = new ContractsHelper(this);
|
|
32
|
+
this.factories = {};
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
cleanCache() {
|
|
36
|
+
for (const factory of Object.keys(this.factories) as Factory[]) {
|
|
37
|
+
this.factories[factory].cleanCache();
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
setPriceInverted(priceInverted: boolean) {
|
|
42
|
+
this.priceInverted = priceInverted;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
getFactory(factory: Factory) {
|
|
46
|
+
if (!this.factories[factory]) this.factories[factory] = new ImpermaxFactory(this, factory);
|
|
47
|
+
return this.factories[factory];
|
|
48
|
+
}
|
|
49
|
+
}
|
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
import { BigNumber } from "ethers";
|
|
2
|
+
import Subgraph from "../subgraph";
|
|
3
|
+
import { Address, Networks, PoolTokenType } from '../config/types';
|
|
4
|
+
|
|
5
|
+
export type Contract = any;
|
|
6
|
+
export type RouterContract = Contract;
|
|
7
|
+
export type FactoryContract = Contract;
|
|
8
|
+
export type SimpleUniswapOracleContract = Contract;
|
|
9
|
+
export type ERC20Contract = Contract;
|
|
10
|
+
export type UniswapV2PairContract = Contract;
|
|
11
|
+
export type UniswapV2FactoryContract = Contract;
|
|
12
|
+
export type BorrowableContract = Contract;
|
|
13
|
+
export type CollateralContract = Contract;
|
|
14
|
+
export type MerkleDistributorContract = Contract;
|
|
15
|
+
export type FarmingPoolContract = Contract;
|
|
16
|
+
export type ClaimAggregatorContract = Contract;
|
|
17
|
+
export type ClaimableContract = Contract;
|
|
18
|
+
export type StakedLPTokenContract = Contract;
|
|
19
|
+
export type ImpermaxChefContract = Contract;
|
|
20
|
+
|
|
21
|
+
export type LendingPool = {
|
|
22
|
+
uniswapV2Pair: UniswapV2PairContract,
|
|
23
|
+
tokenA: ERC20Contract,
|
|
24
|
+
tokenB: ERC20Contract,
|
|
25
|
+
collateral: CollateralContract,
|
|
26
|
+
borrowableA: BorrowableContract,
|
|
27
|
+
borrowableB: BorrowableContract,
|
|
28
|
+
farmingPoolA: FarmingPoolContract,
|
|
29
|
+
farmingPoolB: FarmingPoolContract,
|
|
30
|
+
stakedLPToken: StakedLPTokenContract,
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export enum ApprovalType {
|
|
34
|
+
POOL_TOKEN,
|
|
35
|
+
UNDERLYING,
|
|
36
|
+
BORROW,
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export interface PermitData {
|
|
40
|
+
permitData: string;
|
|
41
|
+
amount: BigNumber;
|
|
42
|
+
deadline: BigNumber;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export interface Changes {
|
|
46
|
+
changeBorrowedA: number;
|
|
47
|
+
changeBorrowedB: number;
|
|
48
|
+
changeCollateral: number;
|
|
49
|
+
}
|
|
50
|
+
export const NO_CHANGES = {
|
|
51
|
+
changeBorrowedA: 0,
|
|
52
|
+
changeBorrowedB: 0,
|
|
53
|
+
changeCollateral: 0,
|
|
54
|
+
}
|
|
55
|
+
export interface Values {
|
|
56
|
+
valueCollateral: number;
|
|
57
|
+
valueA: number;
|
|
58
|
+
valueB: number;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export interface ImpermaxRouterCfg {
|
|
62
|
+
network: Networks;
|
|
63
|
+
subgraph: Subgraph;
|
|
64
|
+
web3: any;
|
|
65
|
+
chainId: number;
|
|
66
|
+
priceInverted: boolean;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export interface PoolTokenData {
|
|
70
|
+
id: Address,
|
|
71
|
+
totalBalance: string,
|
|
72
|
+
exchangeRate: string,
|
|
73
|
+
totalBalanceUSD: string,
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export interface BorrowableData extends PoolTokenData {
|
|
77
|
+
underlying: TokenData,
|
|
78
|
+
totalBorrows: string,
|
|
79
|
+
borrowRate: string,
|
|
80
|
+
reserveFactor: string,
|
|
81
|
+
kinkBorrowRate: string,
|
|
82
|
+
kinkUtilizationRate: string,
|
|
83
|
+
borrowIndex: string,
|
|
84
|
+
accrualTimestamp: string,
|
|
85
|
+
farmingPool: FarmingPoolData,
|
|
86
|
+
rewards?: Array<{
|
|
87
|
+
rewardToken: Address,
|
|
88
|
+
rewardRate: number
|
|
89
|
+
}>,
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export interface CollateralData extends PoolTokenData {
|
|
93
|
+
safetyMargin: string,
|
|
94
|
+
liquidationIncentive: string,
|
|
95
|
+
liquidationFee: string,
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
export interface BorrowablePastData {
|
|
99
|
+
borrowIndex: string,
|
|
100
|
+
accrualTimestamp: string,
|
|
101
|
+
exchangeRate: string,
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
export interface TokenData {
|
|
105
|
+
id: Address,
|
|
106
|
+
symbol: string,
|
|
107
|
+
name: string,
|
|
108
|
+
decimals: string,
|
|
109
|
+
derivedUSD: string,
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export interface RewardData {
|
|
113
|
+
id: Address,
|
|
114
|
+
rewardRate: string,
|
|
115
|
+
rewardsToken: TokenData,
|
|
116
|
+
periodFinish: string,
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
export interface PairData {
|
|
120
|
+
id: Address,
|
|
121
|
+
factory: string,
|
|
122
|
+
reserve0: string,
|
|
123
|
+
reserve1: string,
|
|
124
|
+
totalSupply: string,
|
|
125
|
+
reserveUSD: string,
|
|
126
|
+
token0Price: string,
|
|
127
|
+
token1Price: string,
|
|
128
|
+
derivedUSD: string,
|
|
129
|
+
uniswapV2PairAddress: string,
|
|
130
|
+
uniswapV2Factory: string,
|
|
131
|
+
isStakedLPToken: boolean,
|
|
132
|
+
exchangeRate: string,
|
|
133
|
+
stakingRewards: string,
|
|
134
|
+
masterChef: string,
|
|
135
|
+
pid: string,
|
|
136
|
+
stakedTotalSupply: string,
|
|
137
|
+
rewards: Array<RewardData>,
|
|
138
|
+
uniswapAPR: number,
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
export interface FarmingPoolData {
|
|
142
|
+
epochAmount: string,
|
|
143
|
+
epochBegin: string,
|
|
144
|
+
segmentLength: string,
|
|
145
|
+
vestingBegin: string,
|
|
146
|
+
sharePercentage: string,
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
export interface LendingPoolPastData {
|
|
150
|
+
[PoolTokenType.Collateral]: undefined,
|
|
151
|
+
[PoolTokenType.BorrowableA]: BorrowablePastData,
|
|
152
|
+
[PoolTokenType.BorrowableB]: BorrowablePastData,
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
export interface LendingPoolData {
|
|
156
|
+
id: Address,
|
|
157
|
+
[PoolTokenType.Collateral]: CollateralData,
|
|
158
|
+
[PoolTokenType.BorrowableA]: BorrowableData,
|
|
159
|
+
[PoolTokenType.BorrowableB]: BorrowableData,
|
|
160
|
+
pair: PairData,
|
|
161
|
+
past24h?: LendingPoolPastData,
|
|
162
|
+
past7d?: LendingPoolPastData,
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
export interface CollateralPosition {
|
|
166
|
+
balance: string,
|
|
167
|
+
collateral: {
|
|
168
|
+
lendingPool: {
|
|
169
|
+
id: Address,
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
export interface SupplyPosition {
|
|
175
|
+
balance: string,
|
|
176
|
+
borrowable: {
|
|
177
|
+
underlying: {
|
|
178
|
+
id: Address
|
|
179
|
+
},
|
|
180
|
+
lendingPool: {
|
|
181
|
+
id: Address,
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
export interface BorrowPosition {
|
|
187
|
+
borrowBalance: string,
|
|
188
|
+
borrowIndex: string,
|
|
189
|
+
borrowable: {
|
|
190
|
+
underlying: {
|
|
191
|
+
id: Address
|
|
192
|
+
},
|
|
193
|
+
lendingPool: {
|
|
194
|
+
id: Address,
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
export interface UserData {
|
|
200
|
+
collateralPositions: { [key in Address]: CollateralPosition },
|
|
201
|
+
supplyPositions: { [key in Address]: { [key in PoolTokenType]?: SupplyPosition } },
|
|
202
|
+
borrowPositions: { [key in Address]: { [key in PoolTokenType]?: BorrowPosition } },
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
export interface TvlData {
|
|
206
|
+
crossChainTVLUSD: number;
|
|
207
|
+
totalBalanceUSD: number;
|
|
208
|
+
totalBorrowsUSD: number;
|
|
209
|
+
totalSupplyUSD: number;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
export interface AirdropData {
|
|
213
|
+
index: number;
|
|
214
|
+
amount: BigNumber;
|
|
215
|
+
proof: Array<string>;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
export interface ClaimEvent {
|
|
219
|
+
amount: number;
|
|
220
|
+
transactionHash: string;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
export interface XimxData {
|
|
224
|
+
totalSupply: string;
|
|
225
|
+
totalBalance: string;
|
|
226
|
+
exchangeRate: string;
|
|
227
|
+
dailyAPR: string;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
export interface PendingRewardUI {
|
|
231
|
+
symbol: string;
|
|
232
|
+
amount: number;
|
|
233
|
+
}
|
package/index.ts
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "impermax-sdk",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
|
8
|
+
},
|
|
9
|
+
"author": "",
|
|
10
|
+
"license": "ISC",
|
|
11
|
+
"devDependencies": {
|
|
12
|
+
"ts-loader": "^8.0.14",
|
|
13
|
+
"typescript": "^4.0.3"
|
|
14
|
+
},
|
|
15
|
+
"dependencies": {
|
|
16
|
+
"apollo-cache-inmemory": "^1.6.6",
|
|
17
|
+
"apollo-client": "^2.6.10",
|
|
18
|
+
"apollo-link-http": "^1.5.17",
|
|
19
|
+
"ethers": "^5.0.26",
|
|
20
|
+
"graphql": "^15.4.0",
|
|
21
|
+
"graphql-tag": "^2.11.0"
|
|
22
|
+
}
|
|
23
|
+
}
|