Skip to content

Commit 57363f4

Browse files
feat: ui incentives data provider v3
1 parent 5931580 commit 57363f4

File tree

12 files changed

+3762
-0
lines changed

12 files changed

+3762
-0
lines changed
Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
import { BigNumber } from 'ethers';
2+
import { ReservesIncentiveData, UserReservesIncentivesData } from './types';
3+
4+
export const getReservesIncentivesDataMock: ReservesIncentiveData[] = [
5+
{
6+
underlyingAsset: '0xb04Aaa2A73ff3D88950BdF19Eb4AC029630a2367',
7+
aIncentiveData: {
8+
tokenAddress: '0x6d0eeb7b37BF26E182EB9a8631DCF79e4EF43DDd',
9+
incentiveControllerAddress: '0x5465485D7b15CaBc9196E73A0b1cc457262079e3',
10+
rewardsTokenInformation: [
11+
{
12+
rewardTokenSymbol: 'REW',
13+
rewardTokenAddress: '0x1f689325CBdF44B24DBE2ecC2b1fFD4130861b4E',
14+
rewardOracleAddress: '0xca8e9B5F9e36EbF74096223fc48810861b4FA642',
15+
emissionPerSecond: BigNumber.from({
16+
_hex: '0x04464ecbc45ffe',
17+
_isBigNumber: true,
18+
}),
19+
incentivesLastUpdateTimestamp: BigNumber.from({
20+
_hex: '0x61a5167a',
21+
_isBigNumber: true,
22+
}),
23+
tokenIncentivesIndex: BigNumber.from({
24+
_hex: '0x00',
25+
_isBigNumber: true,
26+
}),
27+
emissionEndTimestamp: BigNumber.from({
28+
_hex: '0x638649fa',
29+
_isBigNumber: true,
30+
}),
31+
rewardPriceFeed: BigNumber.from({
32+
_hex: '0x05f5e100',
33+
_isBigNumber: true,
34+
}),
35+
rewardTokenDecimals: 18,
36+
precision: 18,
37+
priceFeedDecimals: 0,
38+
},
39+
],
40+
},
41+
vIncentiveData: {
42+
tokenAddress: '0xaD99ef885623E8520f631625b2675d6dAd3aaDC1',
43+
incentiveControllerAddress: '0x5465485D7b15CaBc9196E73A0b1cc457262079e3',
44+
rewardsTokenInformation: [
45+
{
46+
rewardTokenSymbol: 'REW',
47+
rewardTokenAddress: '0x1f689325CBdF44B24DBE2ecC2b1fFD4130861b4E',
48+
rewardOracleAddress: '0xca8e9B5F9e36EbF74096223fc48810861b4FA642',
49+
emissionPerSecond: BigNumber.from({
50+
_hex: '0x04464ecbc45ffe',
51+
_isBigNumber: true,
52+
}),
53+
incentivesLastUpdateTimestamp: BigNumber.from({
54+
_hex: '0x61a5167a',
55+
_isBigNumber: true,
56+
}),
57+
tokenIncentivesIndex: BigNumber.from({
58+
_hex: '0x00',
59+
_isBigNumber: true,
60+
}),
61+
emissionEndTimestamp: BigNumber.from({
62+
_hex: '0x638649fa',
63+
_isBigNumber: true,
64+
}),
65+
rewardPriceFeed: BigNumber.from({
66+
_hex: '0x05f5e100',
67+
_isBigNumber: true,
68+
}),
69+
rewardTokenDecimals: 18,
70+
precision: 18,
71+
priceFeedDecimals: 0,
72+
},
73+
],
74+
},
75+
},
76+
];
77+
78+
export const getUserIncentivesDataMock: UserReservesIncentivesData[] = [
79+
{
80+
underlyingAsset: '0xb04Aaa2A73ff3D88950BdF19Eb4AC029630a2367',
81+
aTokenIncentivesUserData: {
82+
tokenAddress: '0x6d0eeb7b37BF26E182EB9a8631DCF79e4EF43DDd',
83+
incentiveControllerAddress: '0x5465485D7b15CaBc9196E73A0b1cc457262079e3',
84+
userRewardsInformation: [
85+
{
86+
rewardTokenSymbol: 'REW',
87+
rewardOracleAddress: '0xca8e9B5F9e36EbF74096223fc48810861b4FA642',
88+
rewardTokenAddress: '0x1f689325CBdF44B24DBE2ecC2b1fFD4130861b4E',
89+
userUnclaimedRewards: BigNumber.from({
90+
_hex: '0x00',
91+
_isBigNumber: true,
92+
}),
93+
tokenIncentivesUserIndex: BigNumber.from({
94+
_hex: '0x00',
95+
_isBigNumber: true,
96+
}),
97+
rewardPriceFeed: BigNumber.from({
98+
_hex: '0x05f5e100',
99+
_isBigNumber: true,
100+
}),
101+
priceFeedDecimals: 0,
102+
rewardTokenDecimals: 18,
103+
},
104+
],
105+
},
106+
vTokenIncentivesUserData: {
107+
tokenAddress: '0xaD99ef885623E8520f631625b2675d6dAd3aaDC1',
108+
incentiveControllerAddress: '0x5465485D7b15CaBc9196E73A0b1cc457262079e3',
109+
userRewardsInformation: [
110+
{
111+
rewardTokenSymbol: 'REW',
112+
rewardOracleAddress: '0xca8e9B5F9e36EbF74096223fc48810861b4FA642',
113+
rewardTokenAddress: '0x1f689325CBdF44B24DBE2ecC2b1fFD4130861b4E',
114+
userUnclaimedRewards: BigNumber.from({
115+
_hex: '0x00',
116+
_isBigNumber: true,
117+
}),
118+
tokenIncentivesUserIndex: BigNumber.from({
119+
_hex: '0x00',
120+
_isBigNumber: true,
121+
}),
122+
rewardPriceFeed: BigNumber.from({
123+
_hex: '0x05f5e100',
124+
_isBigNumber: true,
125+
}),
126+
priceFeedDecimals: 0,
127+
rewardTokenDecimals: 18,
128+
},
129+
],
130+
},
131+
},
132+
];
Lines changed: 217 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,217 @@
1+
import { providers } from 'ethers';
2+
import BaseService from '../commons/BaseService';
3+
import { UiIncentiveDataProviderValidator } from '../commons/validators/methodValidators';
4+
import { isEthAddress } from '../commons/validators/paramValidators';
5+
import { ReservesHelperInput, UserReservesHelperInput } from '../index';
6+
import { UiIncentiveDataProviderV3 } from './typechain/UiIncentiveDataProviderV3';
7+
import { UiIncentiveDataProviderV3__factory } from './typechain/UiIncentiveDataProviderV3__factory';
8+
import {
9+
FullReservesIncentiveDataResponse,
10+
IncentiveData,
11+
IncentiveDataHumanized,
12+
ReservesIncentiveData,
13+
ReservesIncentiveDataHumanized,
14+
RewardInfo,
15+
UserIncentiveData,
16+
UserIncentiveDataHumanized,
17+
UserReservesIncentivesData,
18+
UserReservesIncentivesDataHumanized,
19+
UserRewardInfo,
20+
} from './types';
21+
export * from './types';
22+
23+
export interface UiIncentiveDataProviderInterface {
24+
getFullReservesIncentiveData: (
25+
args: UserReservesHelperInput,
26+
) => Promise<FullReservesIncentiveDataResponse>;
27+
getReservesIncentivesData: (
28+
args: ReservesHelperInput,
29+
) => Promise<ReservesIncentiveData[]>;
30+
getUserReservesIncentivesData: (
31+
args: UserReservesHelperInput,
32+
) => Promise<UserReservesIncentivesData[]>;
33+
getReservesIncentivesDataHumanized: (
34+
args: ReservesHelperInput,
35+
) => Promise<ReservesIncentiveDataHumanized[]>;
36+
getUserReservesIncentivesDataHumanized: (
37+
args: UserReservesHelperInput,
38+
) => Promise<UserReservesIncentivesDataHumanized[]>;
39+
}
40+
export interface FeedResultSuccessful {
41+
rewardTokenAddress: string;
42+
answer: string;
43+
updatedAt: number;
44+
decimals: number;
45+
}
46+
47+
export interface UiIncentiveDataProviderContext {
48+
uiIncentiveDataProviderAddress: string;
49+
provider: providers.Provider;
50+
chainId: number;
51+
}
52+
53+
export class UiIncentiveDataProvider
54+
extends BaseService<UiIncentiveDataProviderV3>
55+
implements UiIncentiveDataProviderInterface
56+
{
57+
readonly uiIncentiveDataProviderAddress: string;
58+
59+
readonly chainId: number;
60+
61+
/**
62+
* Constructor
63+
* @param context The ui incentive data provider context
64+
*/
65+
public constructor({
66+
provider,
67+
uiIncentiveDataProviderAddress,
68+
chainId,
69+
}: UiIncentiveDataProviderContext) {
70+
super(provider, UiIncentiveDataProviderV3__factory);
71+
this.uiIncentiveDataProviderAddress = uiIncentiveDataProviderAddress;
72+
this.chainId = chainId;
73+
}
74+
75+
/**
76+
* Get the full reserve incentive data for the lending pool and the user
77+
* @param user The user address
78+
*/
79+
@UiIncentiveDataProviderValidator
80+
public async getFullReservesIncentiveData(
81+
@isEthAddress('user')
82+
@isEthAddress('lendingPoolAddressProvider')
83+
{ user, lendingPoolAddressProvider }: UserReservesHelperInput,
84+
): Promise<FullReservesIncentiveDataResponse> {
85+
const uiIncentiveContract = this.getContractInstance(
86+
this.uiIncentiveDataProviderAddress,
87+
);
88+
89+
return uiIncentiveContract.getFullReservesIncentiveData(
90+
lendingPoolAddressProvider,
91+
user,
92+
);
93+
}
94+
95+
/**
96+
* Get the reserve incentive data for the lending pool
97+
*/
98+
@UiIncentiveDataProviderValidator
99+
public async getReservesIncentivesData(
100+
@isEthAddress('lendingPoolAddressProvider')
101+
{ lendingPoolAddressProvider }: ReservesHelperInput,
102+
): Promise<ReservesIncentiveData[]> {
103+
const uiIncentiveContract = this.getContractInstance(
104+
this.uiIncentiveDataProviderAddress,
105+
);
106+
107+
return uiIncentiveContract.getReservesIncentivesData(
108+
lendingPoolAddressProvider,
109+
);
110+
}
111+
112+
/**
113+
* Get the reserve incentive data for the user
114+
* @param user The user address
115+
*/
116+
@UiIncentiveDataProviderValidator
117+
public async getUserReservesIncentivesData(
118+
@isEthAddress('user')
119+
@isEthAddress('lendingPoolAddressProvider')
120+
{ user, lendingPoolAddressProvider }: UserReservesHelperInput,
121+
): Promise<UserReservesIncentivesData[]> {
122+
const uiIncentiveContract = this.getContractInstance(
123+
this.uiIncentiveDataProviderAddress,
124+
);
125+
126+
return uiIncentiveContract.getUserReservesIncentivesData(
127+
lendingPoolAddressProvider,
128+
user,
129+
);
130+
}
131+
132+
@UiIncentiveDataProviderValidator
133+
public async getReservesIncentivesDataHumanized(
134+
@isEthAddress('lendingPoolAddressProvider')
135+
{ lendingPoolAddressProvider }: ReservesHelperInput,
136+
): Promise<ReservesIncentiveDataHumanized[]> {
137+
const response: ReservesIncentiveData[] =
138+
await this.getReservesIncentivesData({ lendingPoolAddressProvider });
139+
140+
return response.map(r => ({
141+
id: `${this.chainId}-${r.underlyingAsset}-${lendingPoolAddressProvider}`.toLowerCase(),
142+
underlyingAsset: r.underlyingAsset.toLowerCase(),
143+
aIncentiveData: this._formatIncentiveData(r.aIncentiveData),
144+
vIncentiveData: this._formatIncentiveData(r.vIncentiveData),
145+
}));
146+
}
147+
148+
@UiIncentiveDataProviderValidator
149+
public async getUserReservesIncentivesDataHumanized(
150+
@isEthAddress('user')
151+
@isEthAddress('lendingPoolAddressProvider')
152+
{ user, lendingPoolAddressProvider }: UserReservesHelperInput,
153+
): Promise<UserReservesIncentivesDataHumanized[]> {
154+
const response: UserReservesIncentivesData[] =
155+
await this.getUserReservesIncentivesData({
156+
user,
157+
lendingPoolAddressProvider,
158+
});
159+
160+
return response.map(r => ({
161+
id: `${this.chainId}-${user}-${r.underlyingAsset}-${lendingPoolAddressProvider}`.toLowerCase(),
162+
underlyingAsset: r.underlyingAsset.toLowerCase(),
163+
aTokenIncentivesUserData: this._formatUserIncentiveData(
164+
r.aTokenIncentivesUserData,
165+
),
166+
vTokenIncentivesUserData: this._formatUserIncentiveData(
167+
r.vTokenIncentivesUserData,
168+
),
169+
}));
170+
}
171+
172+
private _formatIncentiveData(data: IncentiveData): IncentiveDataHumanized {
173+
return {
174+
tokenAddress: data.tokenAddress,
175+
incentiveControllerAddress: data.incentiveControllerAddress,
176+
rewardsTokenInformation: data.rewardsTokenInformation.map(
177+
(rawRewardInfo: RewardInfo) => ({
178+
precision: rawRewardInfo.precision,
179+
rewardTokenAddress: rawRewardInfo.rewardTokenAddress,
180+
rewardTokenDecimals: rawRewardInfo.rewardTokenDecimals,
181+
emissionPerSecond: rawRewardInfo.emissionPerSecond.toString(),
182+
incentivesLastUpdateTimestamp:
183+
rawRewardInfo.incentivesLastUpdateTimestamp.toNumber(),
184+
tokenIncentivesIndex: rawRewardInfo.tokenIncentivesIndex.toString(),
185+
emissionEndTimestamp: rawRewardInfo.emissionEndTimestamp.toNumber(),
186+
rewardTokenSymbol: rawRewardInfo.rewardTokenSymbol,
187+
rewardOracleAddress: rawRewardInfo.rewardOracleAddress,
188+
rewardPriceFeed: rawRewardInfo.rewardPriceFeed.toString(),
189+
priceFeedDecimals: rawRewardInfo.priceFeedDecimals,
190+
}),
191+
),
192+
};
193+
}
194+
195+
private _formatUserIncentiveData(
196+
data: UserIncentiveData,
197+
): UserIncentiveDataHumanized {
198+
return {
199+
tokenAddress: data.tokenAddress,
200+
incentiveControllerAddress: data.incentiveControllerAddress,
201+
userRewardsInformation: data.userRewardsInformation.map(
202+
(userRewardInformation: UserRewardInfo) => ({
203+
rewardTokenAddress: userRewardInformation.rewardTokenAddress,
204+
rewardTokenDecimals: userRewardInformation.rewardTokenDecimals,
205+
tokenIncentivesUserIndex:
206+
userRewardInformation.tokenIncentivesUserIndex.toString(),
207+
userUnclaimedRewards:
208+
userRewardInformation.userUnclaimedRewards.toString(),
209+
rewardTokenSymbol: userRewardInformation.rewardTokenSymbol,
210+
rewardOracleAddress: userRewardInformation.rewardOracleAddress,
211+
rewardPriceFeed: userRewardInformation.rewardPriceFeed.toString(),
212+
priceFeedDecimals: userRewardInformation.priceFeedDecimals,
213+
}),
214+
),
215+
};
216+
}
217+
}

0 commit comments

Comments
 (0)