@suilend/sdk 1.0.7 → 1.0.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/core/api/events.d.ts +3 -0
- package/core/api/events.js +3 -0
- package/core/client.d.ts +1 -0
- package/core/client.js +10 -5
- package/core/constants.d.ts +4 -0
- package/core/constants.js +6 -1
- package/core/parsers/apiReserveAssetDataEvent.d.ts +10 -10
- package/core/parsers/apiReserveAssetDataEvent.js +23 -42
- package/core/parsers/deps.d.ts +3 -3
- package/core/parsers/obligation.d.ts +2 -0
- package/core/parsers/obligation.js +7 -4
- package/core/parsers/rateLimiter.js +2 -1
- package/core/parsers/reserve.js +3 -5
- package/core/types.d.ts +164 -0
- package/core/utils/events.d.ts +176 -0
- package/core/utils/events.js +104 -0
- package/core/utils/simulate.d.ts +56 -0
- package/core/utils/simulate.js +312 -0
- package/core/utils/utils.d.ts +61 -0
- package/core/utils/utils.js +157 -0
- package/core/utils.d.ts +4 -0
- package/core/utils.js +25 -1
- package/mainnet/_generated/suilend/index.d.ts +1 -1
- package/mainnet/_generated/suilend/index.js +1 -1
- package/mainnet/constants.d.ts +2 -0
- package/mainnet/constants.js +3 -0
- package/mainnet/utils/events.d.ts +1 -144
- package/mainnet/utils/events.js +14 -112
- package/mainnet/utils/obligation.d.ts +4 -4
- package/mainnet/utils/simulate.d.ts +30 -14
- package/mainnet/utils/simulate.js +53 -259
- package/mainnet/utils/utils.d.ts +1 -79
- package/mainnet/utils/utils.js +15 -155
- package/package.json +1 -1
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
import { SuiClient, SuiEvent } from "@mysten/sui.js/client";
|
|
2
|
+
type TypeName = {
|
|
3
|
+
name: string;
|
|
4
|
+
};
|
|
5
|
+
type Decimal = {
|
|
6
|
+
value: string;
|
|
7
|
+
};
|
|
8
|
+
type address = string;
|
|
9
|
+
type u64 = string;
|
|
10
|
+
export declare enum SuilendEventType {
|
|
11
|
+
InterestUpdateEvent = "InterestUpdateEvent",
|
|
12
|
+
ReserveAssetDataEvent = "ReserveAssetDataEvent",
|
|
13
|
+
MintEvent = "MintEvent",
|
|
14
|
+
RedeemEvent = "RedeemEvent",
|
|
15
|
+
DepositEvent = "DepositEvent",
|
|
16
|
+
WithdrawEvent = "WithdrawEvent",
|
|
17
|
+
BorrowEvent = "BorrowEvent",
|
|
18
|
+
RepayEvent = "RepayEvent",
|
|
19
|
+
LiquidateEvent = "LiquidateEvent",
|
|
20
|
+
ClaimRewardEvent = "ClaimRewardEvent",
|
|
21
|
+
ObligationDataEvent = "ObligationDataEvent"
|
|
22
|
+
}
|
|
23
|
+
export declare enum SuilendTransactionModule {
|
|
24
|
+
LendingMarket = "lending_market",
|
|
25
|
+
Reserve = "reserve"
|
|
26
|
+
}
|
|
27
|
+
declare class TypedParamsSuiEvent<T> {
|
|
28
|
+
event: SuiEvent;
|
|
29
|
+
constructor(event: SuiEvent);
|
|
30
|
+
params(): T;
|
|
31
|
+
isType(module: SuilendTransactionModule, eventType: SuilendEventType): boolean;
|
|
32
|
+
}
|
|
33
|
+
export declare class GenericSuilendEvent extends TypedParamsSuiEvent<{}> {
|
|
34
|
+
}
|
|
35
|
+
export declare class InterestUpdateEvent extends TypedParamsSuiEvent<{
|
|
36
|
+
lending_market_id: address;
|
|
37
|
+
coin_type: TypeName;
|
|
38
|
+
reserve_id: address;
|
|
39
|
+
cumulative_borrow_rate: Decimal;
|
|
40
|
+
available_amount: u64;
|
|
41
|
+
borrowed_amount: Decimal;
|
|
42
|
+
unclaimed_spread_fees: Decimal;
|
|
43
|
+
ctoken_supply: u64;
|
|
44
|
+
borrow_interest_paid: Decimal;
|
|
45
|
+
spread_fee: Decimal;
|
|
46
|
+
supply_interest_earned: Decimal;
|
|
47
|
+
borrow_interest_paid_usd_estimate: Decimal;
|
|
48
|
+
protocol_fee_usd_estimate: Decimal;
|
|
49
|
+
supply_interest_earned_usd_estimate: Decimal;
|
|
50
|
+
}> {
|
|
51
|
+
}
|
|
52
|
+
export declare class ReserveAssetDataEvent extends TypedParamsSuiEvent<{
|
|
53
|
+
lending_market_id: address;
|
|
54
|
+
coin_type: TypeName;
|
|
55
|
+
reserve_id: address;
|
|
56
|
+
available_amount: Decimal;
|
|
57
|
+
supply_amount: Decimal;
|
|
58
|
+
borrowed_amount: Decimal;
|
|
59
|
+
available_amount_usd_estimate: Decimal;
|
|
60
|
+
supply_amount_usd_estimate: Decimal;
|
|
61
|
+
borrowed_amount_usd_estimate: Decimal;
|
|
62
|
+
borrow_apr: Decimal;
|
|
63
|
+
supply_apr: Decimal;
|
|
64
|
+
ctoken_supply: u64;
|
|
65
|
+
cumulative_borrow_rate: Decimal;
|
|
66
|
+
price: Decimal;
|
|
67
|
+
smoothed_price: Decimal;
|
|
68
|
+
price_last_update_timestamp_s: u64;
|
|
69
|
+
}> {
|
|
70
|
+
}
|
|
71
|
+
export declare class MintEvent extends TypedParamsSuiEvent<{
|
|
72
|
+
lending_market_id: address;
|
|
73
|
+
coin_type: TypeName;
|
|
74
|
+
reserve_id: address;
|
|
75
|
+
liquidity_amount: u64;
|
|
76
|
+
ctoken_amount: u64;
|
|
77
|
+
}> {
|
|
78
|
+
}
|
|
79
|
+
export declare class RedeemEvent extends TypedParamsSuiEvent<{
|
|
80
|
+
lending_market_id: address;
|
|
81
|
+
coin_type: TypeName;
|
|
82
|
+
reserve_id: address;
|
|
83
|
+
ctoken_amount: u64;
|
|
84
|
+
liquidity_amount: u64;
|
|
85
|
+
}> {
|
|
86
|
+
}
|
|
87
|
+
export declare class DepositEvent extends TypedParamsSuiEvent<{
|
|
88
|
+
lending_market_id: address;
|
|
89
|
+
coin_type: TypeName;
|
|
90
|
+
reserve_id: address;
|
|
91
|
+
obligation_id: address;
|
|
92
|
+
ctoken_amount: u64;
|
|
93
|
+
}> {
|
|
94
|
+
}
|
|
95
|
+
export declare class WithdrawEvent extends TypedParamsSuiEvent<{
|
|
96
|
+
lending_market_id: address;
|
|
97
|
+
coin_type: TypeName;
|
|
98
|
+
reserve_id: address;
|
|
99
|
+
obligation_id: address;
|
|
100
|
+
ctoken_amount: u64;
|
|
101
|
+
}> {
|
|
102
|
+
}
|
|
103
|
+
export declare class BorrowEvent extends TypedParamsSuiEvent<{
|
|
104
|
+
lending_market_id: address;
|
|
105
|
+
coin_type: TypeName;
|
|
106
|
+
reserve_id: address;
|
|
107
|
+
obligation_id: address;
|
|
108
|
+
liquidity_amount: u64;
|
|
109
|
+
origination_fee_amount: u64;
|
|
110
|
+
}> {
|
|
111
|
+
}
|
|
112
|
+
export declare class RepayEvent extends TypedParamsSuiEvent<{
|
|
113
|
+
lending_market_id: address;
|
|
114
|
+
coin_type: TypeName;
|
|
115
|
+
reserve_id: address;
|
|
116
|
+
obligation_id: address;
|
|
117
|
+
liquidity_amount: u64;
|
|
118
|
+
}> {
|
|
119
|
+
}
|
|
120
|
+
export declare class LiquidateEvent extends TypedParamsSuiEvent<{
|
|
121
|
+
lending_market_id: address;
|
|
122
|
+
repay_reserve_id: address;
|
|
123
|
+
withdraw_reserve_id: address;
|
|
124
|
+
obligation_id: address;
|
|
125
|
+
repay_coin_type: TypeName;
|
|
126
|
+
withdraw_coin_type: TypeName;
|
|
127
|
+
repay_amount: u64;
|
|
128
|
+
withdraw_amount: u64;
|
|
129
|
+
protocol_fee_amount: u64;
|
|
130
|
+
liquidator_bonus_amount: u64;
|
|
131
|
+
}> {
|
|
132
|
+
}
|
|
133
|
+
export declare class ClaimRewardEvent extends TypedParamsSuiEvent<{
|
|
134
|
+
lending_market_id: address;
|
|
135
|
+
reserve_id: address;
|
|
136
|
+
obligation_id: address;
|
|
137
|
+
is_deposit_reward: boolean;
|
|
138
|
+
pool_reward_id: address;
|
|
139
|
+
coin_type: TypeName;
|
|
140
|
+
liquidity_amount: u64;
|
|
141
|
+
}> {
|
|
142
|
+
}
|
|
143
|
+
export declare class ObligationDataEvent extends TypedParamsSuiEvent<{
|
|
144
|
+
lending_market_id: address;
|
|
145
|
+
obligation_id: address;
|
|
146
|
+
deposits: {
|
|
147
|
+
coin_type: TypeName;
|
|
148
|
+
reserve_array_index: u64;
|
|
149
|
+
deposited_ctoken_amount: u64;
|
|
150
|
+
market_value: Decimal;
|
|
151
|
+
user_reward_manager_index: u64;
|
|
152
|
+
attributed_borrow_value: Decimal;
|
|
153
|
+
}[];
|
|
154
|
+
borrows: {
|
|
155
|
+
coin_type: TypeName;
|
|
156
|
+
reserve_array_index: u64;
|
|
157
|
+
borrowed_amount: Decimal;
|
|
158
|
+
cumulative_borrow_rate: Decimal;
|
|
159
|
+
market_value: Decimal;
|
|
160
|
+
user_reward_manager_index: u64;
|
|
161
|
+
}[];
|
|
162
|
+
deposited_value_usd: Decimal;
|
|
163
|
+
allowed_borrow_value_usd: Decimal;
|
|
164
|
+
unhealthy_borrow_value_usd: Decimal;
|
|
165
|
+
super_unhealthy_borrow_value_usd: Decimal;
|
|
166
|
+
unweighted_borrowed_value_usd: Decimal;
|
|
167
|
+
weighted_borrowed_value_usd: Decimal;
|
|
168
|
+
weighted_borrowed_value_upper_bound_usd: Decimal;
|
|
169
|
+
borrowing_isolated_asset: boolean;
|
|
170
|
+
bad_debt_usd: Decimal;
|
|
171
|
+
closable: boolean;
|
|
172
|
+
}> {
|
|
173
|
+
}
|
|
174
|
+
export declare function getEvents(client: SuiClient, digest: string): Promise<GenericSuilendEvent[]>;
|
|
175
|
+
export declare function getRedeemEvent(client: SuiClient, digest: string): Promise<RedeemEvent | null>;
|
|
176
|
+
export {};
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.getRedeemEvent = exports.getEvents = exports.ObligationDataEvent = exports.ClaimRewardEvent = exports.LiquidateEvent = exports.RepayEvent = exports.BorrowEvent = exports.WithdrawEvent = exports.DepositEvent = exports.RedeemEvent = exports.MintEvent = exports.ReserveAssetDataEvent = exports.InterestUpdateEvent = exports.GenericSuilendEvent = exports.SuilendTransactionModule = exports.SuilendEventType = void 0;
|
|
13
|
+
var SuilendEventType;
|
|
14
|
+
(function (SuilendEventType) {
|
|
15
|
+
SuilendEventType["InterestUpdateEvent"] = "InterestUpdateEvent";
|
|
16
|
+
SuilendEventType["ReserveAssetDataEvent"] = "ReserveAssetDataEvent";
|
|
17
|
+
SuilendEventType["MintEvent"] = "MintEvent";
|
|
18
|
+
SuilendEventType["RedeemEvent"] = "RedeemEvent";
|
|
19
|
+
SuilendEventType["DepositEvent"] = "DepositEvent";
|
|
20
|
+
SuilendEventType["WithdrawEvent"] = "WithdrawEvent";
|
|
21
|
+
SuilendEventType["BorrowEvent"] = "BorrowEvent";
|
|
22
|
+
SuilendEventType["RepayEvent"] = "RepayEvent";
|
|
23
|
+
SuilendEventType["LiquidateEvent"] = "LiquidateEvent";
|
|
24
|
+
SuilendEventType["ClaimRewardEvent"] = "ClaimRewardEvent";
|
|
25
|
+
SuilendEventType["ObligationDataEvent"] = "ObligationDataEvent";
|
|
26
|
+
})(SuilendEventType || (exports.SuilendEventType = SuilendEventType = {}));
|
|
27
|
+
var SuilendTransactionModule;
|
|
28
|
+
(function (SuilendTransactionModule) {
|
|
29
|
+
SuilendTransactionModule["LendingMarket"] = "lending_market";
|
|
30
|
+
SuilendTransactionModule["Reserve"] = "reserve";
|
|
31
|
+
})(SuilendTransactionModule || (exports.SuilendTransactionModule = SuilendTransactionModule = {}));
|
|
32
|
+
class TypedParamsSuiEvent {
|
|
33
|
+
constructor(event) {
|
|
34
|
+
this.event = event;
|
|
35
|
+
}
|
|
36
|
+
params() {
|
|
37
|
+
return this.event.parsedJson;
|
|
38
|
+
}
|
|
39
|
+
isType(module, eventType) {
|
|
40
|
+
return this.event.type.includes(`${module}::${eventType}`);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
class GenericSuilendEvent extends TypedParamsSuiEvent {
|
|
44
|
+
}
|
|
45
|
+
exports.GenericSuilendEvent = GenericSuilendEvent;
|
|
46
|
+
class InterestUpdateEvent extends TypedParamsSuiEvent {
|
|
47
|
+
}
|
|
48
|
+
exports.InterestUpdateEvent = InterestUpdateEvent;
|
|
49
|
+
class ReserveAssetDataEvent extends TypedParamsSuiEvent {
|
|
50
|
+
}
|
|
51
|
+
exports.ReserveAssetDataEvent = ReserveAssetDataEvent;
|
|
52
|
+
class MintEvent extends TypedParamsSuiEvent {
|
|
53
|
+
}
|
|
54
|
+
exports.MintEvent = MintEvent;
|
|
55
|
+
class RedeemEvent extends TypedParamsSuiEvent {
|
|
56
|
+
}
|
|
57
|
+
exports.RedeemEvent = RedeemEvent;
|
|
58
|
+
class DepositEvent extends TypedParamsSuiEvent {
|
|
59
|
+
}
|
|
60
|
+
exports.DepositEvent = DepositEvent;
|
|
61
|
+
class WithdrawEvent extends TypedParamsSuiEvent {
|
|
62
|
+
}
|
|
63
|
+
exports.WithdrawEvent = WithdrawEvent;
|
|
64
|
+
class BorrowEvent extends TypedParamsSuiEvent {
|
|
65
|
+
}
|
|
66
|
+
exports.BorrowEvent = BorrowEvent;
|
|
67
|
+
class RepayEvent extends TypedParamsSuiEvent {
|
|
68
|
+
}
|
|
69
|
+
exports.RepayEvent = RepayEvent;
|
|
70
|
+
class LiquidateEvent extends TypedParamsSuiEvent {
|
|
71
|
+
}
|
|
72
|
+
exports.LiquidateEvent = LiquidateEvent;
|
|
73
|
+
class ClaimRewardEvent extends TypedParamsSuiEvent {
|
|
74
|
+
}
|
|
75
|
+
exports.ClaimRewardEvent = ClaimRewardEvent;
|
|
76
|
+
class ObligationDataEvent extends TypedParamsSuiEvent {
|
|
77
|
+
}
|
|
78
|
+
exports.ObligationDataEvent = ObligationDataEvent;
|
|
79
|
+
function getEvents(client, digest) {
|
|
80
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
81
|
+
const tx = yield client.getTransactionBlock({
|
|
82
|
+
digest,
|
|
83
|
+
options: { showEvents: true },
|
|
84
|
+
});
|
|
85
|
+
const events = [];
|
|
86
|
+
for (const event of tx.events || []) {
|
|
87
|
+
events.push(new GenericSuilendEvent(event));
|
|
88
|
+
}
|
|
89
|
+
return events;
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
exports.getEvents = getEvents;
|
|
93
|
+
function getRedeemEvent(client, digest) {
|
|
94
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
95
|
+
const events = yield getEvents(client, digest);
|
|
96
|
+
for (const event of events) {
|
|
97
|
+
if (event.isType(SuilendTransactionModule.LendingMarket, SuilendEventType.RedeemEvent)) {
|
|
98
|
+
return event;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
return null;
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
exports.getRedeemEvent = getRedeemEvent;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import BigNumber from "bignumber.js";
|
|
2
|
+
import { SuiPriceServiceConnection } from "../../pyth-sdk";
|
|
3
|
+
interface Deps {
|
|
4
|
+
Decimal: any;
|
|
5
|
+
Obligation: any;
|
|
6
|
+
Deposit: any;
|
|
7
|
+
Borrow: any;
|
|
8
|
+
Reserve: any;
|
|
9
|
+
ReserveConfig: any;
|
|
10
|
+
PoolRewardManager: any;
|
|
11
|
+
PoolReward: any;
|
|
12
|
+
UserRewardManager: any;
|
|
13
|
+
UserReward: any;
|
|
14
|
+
}
|
|
15
|
+
export declare class Simulate {
|
|
16
|
+
Decimal: Deps["Decimal"];
|
|
17
|
+
Obligation: Deps["Obligation"];
|
|
18
|
+
Deposit: Deps["Deposit"];
|
|
19
|
+
Borrow: Deps["Borrow"];
|
|
20
|
+
Reserve: Deps["Reserve"];
|
|
21
|
+
ReserveConfig: Deps["ReserveConfig"];
|
|
22
|
+
PoolRewardManager: Deps["PoolRewardManager"];
|
|
23
|
+
PoolReward: Deps["PoolReward"];
|
|
24
|
+
UserRewardManager: Deps["UserRewardManager"];
|
|
25
|
+
UserReward: Deps["UserReward"];
|
|
26
|
+
constructor({ Decimal, Obligation, Deposit, Borrow, Reserve, ReserveConfig, PoolRewardManager, PoolReward, UserRewardManager, UserReward, }: Deps);
|
|
27
|
+
/**
|
|
28
|
+
* @deprecated since version 1.0.8. Use `calculateUtilizationPercent` instead.
|
|
29
|
+
*/
|
|
30
|
+
calculateUtilizationRate(reserve: typeof this.Reserve): BigNumber;
|
|
31
|
+
calculateUtilizationPercent(reserve: typeof this.Reserve): BigNumber;
|
|
32
|
+
/**
|
|
33
|
+
* @deprecated since version 1.0.8. Use `calculateBorrowAprPercent` instead.
|
|
34
|
+
*/
|
|
35
|
+
calculateBorrowApr(reserve: typeof this.Reserve): BigNumber;
|
|
36
|
+
calculateBorrowAprPercent(reserve: typeof this.Reserve): BigNumber;
|
|
37
|
+
/**
|
|
38
|
+
* @deprecated since version 1.0.8. Use `calculateDepositAprPercent` instead.
|
|
39
|
+
*/
|
|
40
|
+
calculateSupplyApr(reserve: typeof this.Reserve): BigNumber;
|
|
41
|
+
calculateDepositAprPercent(reserve: typeof this.Reserve): BigNumber;
|
|
42
|
+
compoundReserveInterest(reserve: typeof this.Reserve, now: number): typeof this.Reserve;
|
|
43
|
+
updatePoolRewardsManager(manager: typeof this.PoolRewardManager, nowMs: number): typeof this.PoolRewardManager;
|
|
44
|
+
refreshReservePrice(reserves: (typeof this.Reserve)[], pythConnection: SuiPriceServiceConnection): Promise<(typeof this.Reserve)[]>;
|
|
45
|
+
updateUserRewardManager(poolManager: typeof this.PoolRewardManager, userRewardManager: typeof this.UserRewardManager, now: number): typeof this.UserRewardManager;
|
|
46
|
+
refreshObligation(unrefreshedObligation: typeof this.Obligation, refreshedReserves: (typeof this.Reserve)[]): typeof this.Obligation;
|
|
47
|
+
numberToDecimal(value: number): any;
|
|
48
|
+
stringToDecimal(value: string): any;
|
|
49
|
+
decimalToBigNumber(value: typeof this.Decimal): BigNumber;
|
|
50
|
+
getCTokenMarketValue(reserve: typeof this.Reserve, depositedCTokenAmount: BigNumber): BigNumber;
|
|
51
|
+
getCTokenMarketValueLowerBound(reserve: typeof this.Reserve, depositedCTokenAmount: BigNumber): BigNumber;
|
|
52
|
+
cTokenRatio(reserve: typeof this.Reserve): BigNumber;
|
|
53
|
+
totalSupply(reserve: typeof this.Reserve): BigNumber;
|
|
54
|
+
compoundDebt(borrow: typeof this.Borrow, reserve: typeof this.Reserve): typeof this.Borrow;
|
|
55
|
+
}
|
|
56
|
+
export {};
|
|
@@ -0,0 +1,312 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.Simulate = void 0;
|
|
16
|
+
const bcs_1 = require("@mysten/sui.js/bcs");
|
|
17
|
+
const utils_1 = require("@mysten/sui.js/utils");
|
|
18
|
+
const bignumber_js_1 = __importDefault(require("bignumber.js"));
|
|
19
|
+
const uuid_1 = require("uuid");
|
|
20
|
+
const constants_1 = require("../constants");
|
|
21
|
+
const utils_2 = require("../utils");
|
|
22
|
+
class Simulate {
|
|
23
|
+
constructor({ Decimal, Obligation, Deposit, Borrow, Reserve, ReserveConfig, PoolRewardManager, PoolReward, UserRewardManager, UserReward, }) {
|
|
24
|
+
this.Decimal = Decimal;
|
|
25
|
+
this.Obligation = Obligation;
|
|
26
|
+
this.Deposit = Deposit;
|
|
27
|
+
this.Borrow = Borrow;
|
|
28
|
+
this.Reserve = Reserve;
|
|
29
|
+
this.ReserveConfig = ReserveConfig;
|
|
30
|
+
this.PoolRewardManager = PoolRewardManager;
|
|
31
|
+
this.PoolReward = PoolReward;
|
|
32
|
+
this.UserRewardManager = UserRewardManager;
|
|
33
|
+
this.UserReward = UserReward;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* @deprecated since version 1.0.8. Use `calculateUtilizationPercent` instead.
|
|
37
|
+
*/
|
|
38
|
+
calculateUtilizationRate(reserve) {
|
|
39
|
+
const { mintDecimals } = reserve;
|
|
40
|
+
// From core/parsers/reserve.ts > parseReserve
|
|
41
|
+
const availableAmount = new bignumber_js_1.default(reserve.availableAmount.toString()).div(10 ** mintDecimals);
|
|
42
|
+
const borrowedAmount = new bignumber_js_1.default(reserve.borrowedAmount.value.toString())
|
|
43
|
+
.div(constants_1.WAD)
|
|
44
|
+
.div(10 ** mintDecimals);
|
|
45
|
+
const unclaimedSpreadFees = new bignumber_js_1.default(reserve.unclaimedSpreadFees.value.toString())
|
|
46
|
+
.div(constants_1.WAD)
|
|
47
|
+
.div(10 ** mintDecimals);
|
|
48
|
+
const depositedAmount = borrowedAmount
|
|
49
|
+
.plus(availableAmount)
|
|
50
|
+
.minus(unclaimedSpreadFees);
|
|
51
|
+
return depositedAmount.eq(0)
|
|
52
|
+
? new bignumber_js_1.default(0)
|
|
53
|
+
: borrowedAmount.div(depositedAmount);
|
|
54
|
+
}
|
|
55
|
+
calculateUtilizationPercent(reserve) {
|
|
56
|
+
return this.calculateUtilizationRate(reserve).times(100);
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* @deprecated since version 1.0.8. Use `calculateBorrowAprPercent` instead.
|
|
60
|
+
*/
|
|
61
|
+
calculateBorrowApr(reserve) {
|
|
62
|
+
const config = reserve.config.element;
|
|
63
|
+
const utilizationPercent = this.calculateUtilizationPercent(reserve);
|
|
64
|
+
// From core/parsers/reserve.ts > parseReserveConfig
|
|
65
|
+
const interestRate = config.interestRateUtils.map((util, index) => ({
|
|
66
|
+
id: (0, uuid_1.v4)(),
|
|
67
|
+
utilPercent: new bignumber_js_1.default(util.toString()),
|
|
68
|
+
aprPercent: new bignumber_js_1.default(config.interestRateAprs[index].toString()).div(100),
|
|
69
|
+
}));
|
|
70
|
+
return (0, utils_2.linearlyInterpolate)(interestRate, "utilPercent", "aprPercent", utilizationPercent);
|
|
71
|
+
}
|
|
72
|
+
calculateBorrowAprPercent(reserve) {
|
|
73
|
+
return this.calculateBorrowApr(reserve);
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* @deprecated since version 1.0.8. Use `calculateDepositAprPercent` instead.
|
|
77
|
+
*/
|
|
78
|
+
calculateSupplyApr(reserve) {
|
|
79
|
+
const config = reserve.config.element;
|
|
80
|
+
const utilizationPercent = this.calculateUtilizationPercent(reserve);
|
|
81
|
+
const borrowAprPercent = this.calculateBorrowAprPercent(reserve);
|
|
82
|
+
// From core/parsers/reserve.ts > parseReserveConfig
|
|
83
|
+
const spreadFeeBps = Number(config.spreadFeeBps.toString());
|
|
84
|
+
return new bignumber_js_1.default(utilizationPercent.div(100))
|
|
85
|
+
.times(borrowAprPercent.div(100))
|
|
86
|
+
.times(1 - spreadFeeBps / 10000)
|
|
87
|
+
.times(100);
|
|
88
|
+
}
|
|
89
|
+
calculateDepositAprPercent(reserve) {
|
|
90
|
+
return this.calculateSupplyApr(reserve);
|
|
91
|
+
}
|
|
92
|
+
compoundReserveInterest(reserve, now) {
|
|
93
|
+
var _a, _b;
|
|
94
|
+
const timeElapsedSeconds = now - Number(reserve.interestLastUpdateTimestampS);
|
|
95
|
+
if (timeElapsedSeconds === 0) {
|
|
96
|
+
return reserve;
|
|
97
|
+
}
|
|
98
|
+
bignumber_js_1.default.config({ POW_PRECISION: 100 });
|
|
99
|
+
const compoundedBorrowRate = new bignumber_js_1.default(1)
|
|
100
|
+
.plus(this.calculateBorrowAprPercent(reserve)
|
|
101
|
+
.div(100)
|
|
102
|
+
.div(365 * 24 * 60 * 60))
|
|
103
|
+
.pow(new bignumber_js_1.default(timeElapsedSeconds).toNumber());
|
|
104
|
+
const updatedReserve = Object.assign({}, reserve);
|
|
105
|
+
const oldBorrowedAmount = this.decimalToBigNumber(reserve.borrowedAmount);
|
|
106
|
+
const oldCumulativeBorrowRate = this.decimalToBigNumber(reserve.cumulativeBorrowRate);
|
|
107
|
+
const oldUnclaimedSpreadFees = this.decimalToBigNumber(reserve.unclaimedSpreadFees);
|
|
108
|
+
updatedReserve.cumulativeBorrowRate = this.stringToDecimal(compoundedBorrowRate.multipliedBy(oldCumulativeBorrowRate).toString());
|
|
109
|
+
const netNewDebt = oldBorrowedAmount.multipliedBy(compoundedBorrowRate.minus(1));
|
|
110
|
+
const spreadFee = new bignumber_js_1.default(((_b = (_a = reserve.config.element) === null || _a === void 0 ? void 0 : _a.spreadFeeBps) === null || _b === void 0 ? void 0 : _b.toString()) || 0);
|
|
111
|
+
updatedReserve.unclaimedSpreadFees = this.stringToDecimal(oldUnclaimedSpreadFees
|
|
112
|
+
.plus(netNewDebt.multipliedBy(spreadFee.dividedBy(10000)))
|
|
113
|
+
.toString());
|
|
114
|
+
updatedReserve.borrowedAmount = this.stringToDecimal(oldBorrowedAmount.plus(netNewDebt).toString());
|
|
115
|
+
updatedReserve.interestLastUpdateTimestampS = BigInt(now);
|
|
116
|
+
updatedReserve.depositsPoolRewardManager = this.updatePoolRewardsManager(updatedReserve.depositsPoolRewardManager, now * 1000);
|
|
117
|
+
updatedReserve.borrowsPoolRewardManager = this.updatePoolRewardsManager(updatedReserve.borrowsPoolRewardManager, now * 1000);
|
|
118
|
+
return updatedReserve;
|
|
119
|
+
}
|
|
120
|
+
updatePoolRewardsManager(manager, nowMs) {
|
|
121
|
+
const updatedManager = Object.assign({}, manager);
|
|
122
|
+
const timeElapsedMs = nowMs - Number(manager.lastUpdateTimeMs);
|
|
123
|
+
if (manager.totalShares === BigInt(0) || timeElapsedMs === 0) {
|
|
124
|
+
return updatedManager;
|
|
125
|
+
}
|
|
126
|
+
updatedManager.poolRewards = updatedManager.poolRewards.map((poolReward) => {
|
|
127
|
+
if (poolReward === null) {
|
|
128
|
+
return poolReward;
|
|
129
|
+
}
|
|
130
|
+
if (nowMs < poolReward.startTimeMs ||
|
|
131
|
+
manager.lastUpdateTimeMs >= poolReward.endTimeMs) {
|
|
132
|
+
return poolReward;
|
|
133
|
+
}
|
|
134
|
+
const updatedPoolReward = Object.assign({}, poolReward);
|
|
135
|
+
const endTimeMs = Number(poolReward.endTimeMs);
|
|
136
|
+
const startTimeMs = Number(poolReward.startTimeMs);
|
|
137
|
+
const lastUpdateTimeMs = Number(manager.lastUpdateTimeMs);
|
|
138
|
+
const timePassedMs = Math.min(nowMs, endTimeMs) - Math.max(startTimeMs, lastUpdateTimeMs);
|
|
139
|
+
const unlockedRewards = new bignumber_js_1.default(poolReward.totalRewards.toString())
|
|
140
|
+
.multipliedBy(timePassedMs)
|
|
141
|
+
.dividedBy(Number(poolReward.endTimeMs - poolReward.startTimeMs));
|
|
142
|
+
updatedPoolReward.allocatedRewards = this.stringToDecimal(this.decimalToBigNumber(poolReward.allocatedRewards)
|
|
143
|
+
.plus(unlockedRewards)
|
|
144
|
+
.toString());
|
|
145
|
+
updatedPoolReward.cumulativeRewardsPerShare = this.stringToDecimal(this.decimalToBigNumber(poolReward.cumulativeRewardsPerShare)
|
|
146
|
+
.plus(unlockedRewards.dividedBy(Number(manager.totalShares)))
|
|
147
|
+
.toString());
|
|
148
|
+
return updatedPoolReward;
|
|
149
|
+
});
|
|
150
|
+
updatedManager.lastUpdateTimeMs = BigInt(nowMs);
|
|
151
|
+
return updatedManager;
|
|
152
|
+
}
|
|
153
|
+
refreshReservePrice(reserves, pythConnection) {
|
|
154
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
155
|
+
const priceIdentifiers = reserves.map((r) => (0, utils_1.toHEX)(new Uint8Array(r.priceIdentifier.bytes)));
|
|
156
|
+
const priceData = yield pythConnection.getLatestPriceFeeds(priceIdentifiers);
|
|
157
|
+
if (!priceData)
|
|
158
|
+
return reserves;
|
|
159
|
+
const updatedReserves = [];
|
|
160
|
+
for (let i = 0; i < reserves.length; i++) {
|
|
161
|
+
const newReserve = Object.assign({}, reserves[i]);
|
|
162
|
+
newReserve.price = this.stringToDecimal(priceData[i].getPriceUnchecked().getPriceAsNumberUnchecked().toString());
|
|
163
|
+
newReserve.smoothedPrice = this.stringToDecimal(priceData[i]
|
|
164
|
+
.getEmaPriceUnchecked()
|
|
165
|
+
.getPriceAsNumberUnchecked()
|
|
166
|
+
.toString());
|
|
167
|
+
newReserve.priceLastUpdateTimestampS = BigInt(priceData[i].getPriceUnchecked().publishTime);
|
|
168
|
+
updatedReserves.push(newReserve);
|
|
169
|
+
}
|
|
170
|
+
return updatedReserves;
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
updateUserRewardManager(poolManager, userRewardManager, now) {
|
|
174
|
+
const updatedUserRewardManager = Object.assign({}, userRewardManager);
|
|
175
|
+
for (let i = 0; i < poolManager.poolRewards.length; i++) {
|
|
176
|
+
const poolReward = poolManager.poolRewards[i];
|
|
177
|
+
if (poolReward == null) {
|
|
178
|
+
continue;
|
|
179
|
+
}
|
|
180
|
+
if (i >= userRewardManager.rewards.length) {
|
|
181
|
+
userRewardManager.rewards.push(null);
|
|
182
|
+
}
|
|
183
|
+
const oldReward = updatedUserRewardManager.rewards[i];
|
|
184
|
+
const reward = Object.assign({}, oldReward);
|
|
185
|
+
if (oldReward != null) {
|
|
186
|
+
const newRewards = this.decimalToBigNumber(poolReward.cumulativeRewardsPerShare)
|
|
187
|
+
.minus(this.decimalToBigNumber(oldReward.cumulativeRewardsPerShare))
|
|
188
|
+
.multipliedBy(new bignumber_js_1.default(Number(userRewardManager.share)));
|
|
189
|
+
reward.earnedRewards = this.stringToDecimal(this.decimalToBigNumber(oldReward.earnedRewards)
|
|
190
|
+
.plus(newRewards)
|
|
191
|
+
.toString());
|
|
192
|
+
reward.cumulativeRewardsPerShare = poolReward.cumulativeRewardsPerShare;
|
|
193
|
+
updatedUserRewardManager.rewards[i] = reward;
|
|
194
|
+
}
|
|
195
|
+
else {
|
|
196
|
+
if (userRewardManager.lastUpdateTimeMs <= poolReward.endTimeMs) {
|
|
197
|
+
updatedUserRewardManager.rewards[i] = this.UserReward.fromFields({
|
|
198
|
+
pool_reward_id: { bytes: poolReward.id.slice(2) },
|
|
199
|
+
earned_rewards: this.stringToDecimal((userRewardManager.lastUpdateTimeMs <= poolReward.startTimeMs
|
|
200
|
+
? this.decimalToBigNumber(poolReward.cumulativeRewardsPerShare).multipliedBy(new bignumber_js_1.default(Number(userRewardManager.share)))
|
|
201
|
+
: new bignumber_js_1.default(0)).toString()),
|
|
202
|
+
cumulative_rewards_per_share: poolReward.cumulativeRewardsPerShare,
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
updatedUserRewardManager.lastUpdateTimeMs = BigInt(now);
|
|
208
|
+
return updatedUserRewardManager;
|
|
209
|
+
}
|
|
210
|
+
refreshObligation(unrefreshedObligation, refreshedReserves) {
|
|
211
|
+
const obligation = Object.assign({}, unrefreshedObligation);
|
|
212
|
+
// Refresh Deposits
|
|
213
|
+
let depositValueUsd = new bignumber_js_1.default(0);
|
|
214
|
+
let allowedBorrowValueUsd = new bignumber_js_1.default(0);
|
|
215
|
+
let unhealthyBorrowValueUsd = new bignumber_js_1.default(0);
|
|
216
|
+
for (let i = 0; i < obligation.deposits.length; i++) {
|
|
217
|
+
const deposit = Object.assign({}, obligation.deposits[i]);
|
|
218
|
+
const reserve = refreshedReserves.find((r) => r.coinType.name === deposit.coinType.name);
|
|
219
|
+
if (!reserve) {
|
|
220
|
+
throw new Error(`Unable to find reserve for coin type ${deposit.coinType.name}`);
|
|
221
|
+
}
|
|
222
|
+
const config = reserve.config.element;
|
|
223
|
+
obligation.userRewardManagers[deposit.userRewardManagerIndex] = this.updateUserRewardManager(reserve.depositsPoolRewardManager, obligation.userRewardManagers[deposit.userRewardManagerIndex], Date.now());
|
|
224
|
+
const marketValue = this.getCTokenMarketValue(reserve, new bignumber_js_1.default(deposit.depositedCtokenAmount.toString()));
|
|
225
|
+
const marketValueLowerBound = this.getCTokenMarketValueLowerBound(reserve, new bignumber_js_1.default(deposit.depositedCtokenAmount.toString()));
|
|
226
|
+
deposit.marketValue = this.stringToDecimal(marketValue.toString());
|
|
227
|
+
depositValueUsd = depositValueUsd.plus(new bignumber_js_1.default(marketValue.toString()));
|
|
228
|
+
allowedBorrowValueUsd = allowedBorrowValueUsd.plus(marketValueLowerBound.multipliedBy(new bignumber_js_1.default(config.openLtvPct / 100)));
|
|
229
|
+
unhealthyBorrowValueUsd = unhealthyBorrowValueUsd.plus(marketValue.multipliedBy(new bignumber_js_1.default(config.closeLtvPct / 100)));
|
|
230
|
+
obligation.deposits[i] = deposit;
|
|
231
|
+
}
|
|
232
|
+
obligation.unhealthyBorrowValueUsd = this.stringToDecimal(unhealthyBorrowValueUsd.toString());
|
|
233
|
+
obligation.allowedBorrowValueUsd = this.stringToDecimal(allowedBorrowValueUsd.toString());
|
|
234
|
+
obligation.depositedValueUsd = this.stringToDecimal(depositValueUsd.toString());
|
|
235
|
+
// Refresh borrows
|
|
236
|
+
let unweightedBorrowedValueUsd = new bignumber_js_1.default(0);
|
|
237
|
+
let weightedBorrowedValueUsd = new bignumber_js_1.default(0);
|
|
238
|
+
let weightedBorrowedValueUpperBoundUsd = new bignumber_js_1.default(0);
|
|
239
|
+
for (let i = 0; i < obligation.borrows.length; i++) {
|
|
240
|
+
const unrefreshedBorrow = obligation.borrows[i];
|
|
241
|
+
const reserve = refreshedReserves.find((r) => r.coinType.name == unrefreshedBorrow.coinType.name);
|
|
242
|
+
if (!reserve) {
|
|
243
|
+
throw new Error(`Unable to find reserve for coin type ${unrefreshedBorrow.coinType.name}`);
|
|
244
|
+
}
|
|
245
|
+
const config = reserve.config.element;
|
|
246
|
+
const borrow = Object.assign({}, this.compoundDebt(unrefreshedBorrow, reserve));
|
|
247
|
+
obligation.userRewardManagers[borrow.userRewardManagerIndex] = this.updateUserRewardManager(reserve.borrowsPoolRewardManager, obligation.userRewardManagers[borrow.userRewardManagerIndex], Date.now());
|
|
248
|
+
const marketValue = this.decimalToBigNumber(borrow.borrowedAmount)
|
|
249
|
+
.multipliedBy(this.decimalToBigNumber(reserve.price))
|
|
250
|
+
.dividedBy(new bignumber_js_1.default(10 ** reserve.mintDecimals));
|
|
251
|
+
const upperBoundPrice = bignumber_js_1.default.max(this.decimalToBigNumber(reserve.price), this.decimalToBigNumber(reserve.smoothedPrice));
|
|
252
|
+
const marketValueUpperBound = this.decimalToBigNumber(reserve.borrowedAmount)
|
|
253
|
+
.multipliedBy(upperBoundPrice)
|
|
254
|
+
.dividedBy(new bignumber_js_1.default(10 ** reserve.mintDecimals));
|
|
255
|
+
borrow.marketValue = this.stringToDecimal(marketValue.toString());
|
|
256
|
+
unweightedBorrowedValueUsd = unweightedBorrowedValueUsd.plus(marketValue);
|
|
257
|
+
const borrowWeight = new bignumber_js_1.default((config.borrowWeightBps / BigInt(10000)).toString());
|
|
258
|
+
weightedBorrowedValueUsd = weightedBorrowedValueUsd.plus(marketValue.multipliedBy(borrowWeight));
|
|
259
|
+
weightedBorrowedValueUpperBoundUsd =
|
|
260
|
+
weightedBorrowedValueUpperBoundUsd.plus(marketValueUpperBound.multipliedBy(borrowWeight));
|
|
261
|
+
}
|
|
262
|
+
obligation.unweightedBorrowedValueUsd = this.stringToDecimal(unweightedBorrowedValueUsd.toString());
|
|
263
|
+
obligation.weightedBorrowedValueUpperBoundUsd = this.stringToDecimal(weightedBorrowedValueUpperBoundUsd.toString());
|
|
264
|
+
obligation.weightedBorrowedValueUsd = this.stringToDecimal(weightedBorrowedValueUsd.toString());
|
|
265
|
+
return obligation;
|
|
266
|
+
}
|
|
267
|
+
numberToDecimal(value) {
|
|
268
|
+
const adjustedValue = Math.round(value * +constants_1.WAD);
|
|
269
|
+
return this.Decimal.fromBcs(bcs_1.bcs.u256().serialize(adjustedValue).toBytes());
|
|
270
|
+
}
|
|
271
|
+
stringToDecimal(value) {
|
|
272
|
+
return this.numberToDecimal(new bignumber_js_1.default(value).toNumber());
|
|
273
|
+
}
|
|
274
|
+
decimalToBigNumber(value) {
|
|
275
|
+
return new bignumber_js_1.default(value.value.toString()).div(constants_1.WAD);
|
|
276
|
+
}
|
|
277
|
+
getCTokenMarketValue(reserve, depositedCTokenAmount) {
|
|
278
|
+
const liquidityAmount = depositedCTokenAmount.multipliedBy(this.cTokenRatio(reserve));
|
|
279
|
+
return this.decimalToBigNumber(reserve.price)
|
|
280
|
+
.multipliedBy(liquidityAmount)
|
|
281
|
+
.dividedBy(new bignumber_js_1.default(10 ** reserve.mintDecimals));
|
|
282
|
+
}
|
|
283
|
+
getCTokenMarketValueLowerBound(reserve, depositedCTokenAmount) {
|
|
284
|
+
const liquidityAmount = depositedCTokenAmount.multipliedBy(this.cTokenRatio(reserve));
|
|
285
|
+
const price = bignumber_js_1.default.min(this.decimalToBigNumber(reserve.price), this.decimalToBigNumber(reserve.smoothedPrice));
|
|
286
|
+
return price
|
|
287
|
+
.multipliedBy(liquidityAmount)
|
|
288
|
+
.dividedBy(new bignumber_js_1.default(10 ** reserve.mintDecimals));
|
|
289
|
+
}
|
|
290
|
+
cTokenRatio(reserve) {
|
|
291
|
+
if (reserve.ctokenSupply === BigInt(0)) {
|
|
292
|
+
return new bignumber_js_1.default(1);
|
|
293
|
+
}
|
|
294
|
+
return this.totalSupply(reserve).dividedBy(new bignumber_js_1.default(reserve.ctokenSupply.toString()));
|
|
295
|
+
}
|
|
296
|
+
totalSupply(reserve) {
|
|
297
|
+
return new bignumber_js_1.default(reserve.availableAmount.toString())
|
|
298
|
+
.plus(this.decimalToBigNumber(reserve.borrowedAmount))
|
|
299
|
+
.minus(this.decimalToBigNumber(reserve.unclaimedSpreadFees));
|
|
300
|
+
}
|
|
301
|
+
compoundDebt(borrow, reserve) {
|
|
302
|
+
const borrowCopy = Object.assign({}, borrow);
|
|
303
|
+
const newCumulativeBorrowRate = this.decimalToBigNumber(reserve.cumulativeBorrowRate);
|
|
304
|
+
const compoundedInterestRate = newCumulativeBorrowRate.dividedBy(this.decimalToBigNumber(borrow.cumulativeBorrowRate));
|
|
305
|
+
borrowCopy.borrowedAmount = this.stringToDecimal(this.decimalToBigNumber(borrow.borrowedAmount)
|
|
306
|
+
.multipliedBy(compoundedInterestRate)
|
|
307
|
+
.toString());
|
|
308
|
+
borrowCopy.cumulativeBorrowRate = this.stringToDecimal(newCumulativeBorrowRate.toString());
|
|
309
|
+
return borrowCopy;
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
exports.Simulate = Simulate;
|