Skip to content

Commit 5c44b98

Browse files
authored
Merge pull request #331 from Gearbox-protocol/gearbox-campaigns
feat: gearbox campaigns
2 parents 45abac1 + 0c63579 commit 5c44b98

File tree

3 files changed

+148
-142
lines changed

3 files changed

+148
-142
lines changed

src/gearboxRewards/api.ts

Lines changed: 59 additions & 129 deletions
Original file line numberDiff line numberDiff line change
@@ -18,17 +18,13 @@ import {
1818
import { GearboxBackendApi } from "../core/endpoint";
1919
import { PoolData } from "../core/pool";
2020
import { TokenData } from "../tokens/tokenData";
21-
import {
22-
iAirdropDistributorAbi,
23-
iFarmingPoolAbi,
24-
iMulticall3Abi,
25-
} from "../types";
26-
import { toBN } from "../utils/formatter";
21+
import { iAirdropDistributorAbi, iFarmingPoolAbi } from "../types";
2722
import { BigIntMath } from "../utils/math";
23+
import { ExtraRewardApy } from "./apy";
2824
import {
2925
MerkleXYZApi,
30-
MerkleXYZRewardsCampaignsResponse,
3126
MerkleXYZUserRewardsResponse,
27+
MerkleXYZV4CampaignsResponse,
3228
} from "./merklAPI";
3329

3430
export interface GearboxExtraMerkleLmReward {
@@ -97,29 +93,17 @@ export interface FarmInfo {
9793
symbol: SupportedToken;
9894
}
9995

100-
type PoolsWithExtraRewardsList = Record<NetworkType, Array<Address>>;
101-
102-
const DEFAULT_POOLS_WITH_EXTRA_REWARDS: PoolsWithExtraRewardsList = {
103-
Mainnet: [
104-
"0x7354EC6E852108411e681D13E11185c3a2567981", // dtBTCV3
105-
],
106-
Arbitrum: [],
107-
Optimism: [],
108-
Base: [],
109-
};
110-
11196
type ReportHandler = (e: unknown, description?: string) => void;
11297

11398
export interface GetLmRewardsInfoProps {
11499
pools: Record<Address, PoolData>;
115100
tokensList: Record<Address, TokenData>;
116101
provider: PublicClient;
102+
}
117103

118-
multicallAddress: Address;
119-
120-
poolsWithExtraRewards?: PoolsWithExtraRewardsList;
121-
network: NetworkType;
122-
reportError?: ReportHandler;
104+
export interface GetExtraRewardsProps {
105+
chainId: number;
106+
tokensList: Record<Address, TokenData>;
123107
}
124108

125109
export interface GetLmRewardsProps {
@@ -150,15 +134,53 @@ export interface ClaimLmRewardsV3Props {
150134
}
151135

152136
export class GearboxRewardsApi {
137+
static async getExtraRewards({ chainId, tokensList }: GetExtraRewardsProps) {
138+
const res = await axios.get<MerkleXYZV4CampaignsResponse>(
139+
MerkleXYZApi.getGearboxCampaignsUrl(),
140+
);
141+
const currentActiveCampaigns = res.data.filter(
142+
c => c.status === "LIVE" && c.chainId === chainId,
143+
);
144+
145+
const r = currentActiveCampaigns.reduce<
146+
Record<Address, Array<ExtraRewardApy>>
147+
>((acc, campaign) => {
148+
const rewardSource = (
149+
campaign.tokens[0]?.address || campaign.identifier
150+
).toLowerCase() as Address;
151+
152+
const allRewards = campaign.rewardsRecord.breakdowns
153+
.map((r, i) => {
154+
const tokenLc = r.token.address.toLowerCase() as Address;
155+
const { symbol = r.token.symbol } = tokensList[tokenLc] || {};
156+
157+
const apy = campaign.aprRecord.breakdowns[i]?.value || 0;
158+
159+
const apyObject: ExtraRewardApy = {
160+
token: rewardSource,
161+
balance: null,
162+
163+
apy: apy,
164+
rewardToken: tokenLc,
165+
rewardTokenSymbol: symbol,
166+
};
167+
168+
return apyObject;
169+
})
170+
.filter(r => r.apy > 0);
171+
172+
acc[rewardSource] = [...(acc[rewardSource] || []), ...allRewards];
173+
174+
return acc;
175+
}, {});
176+
177+
return r;
178+
}
179+
153180
static async getLmRewardsInfo({
154181
pools,
155182
provider,
156-
multicallAddress,
157183
tokensList,
158-
159-
poolsWithExtraRewards = DEFAULT_POOLS_WITH_EXTRA_REWARDS,
160-
network,
161-
reportError,
162184
}: GetLmRewardsInfoProps) {
163185
const poolByStakedDiesel = Object.values(pools).reduce<
164186
Record<Address, Address>
@@ -187,19 +209,6 @@ export class GearboxRewardsApi {
187209
const poolStakedTokens = TypedObjectUtils.keys(poolByStakedDiesel);
188210
const allPoolTokens = TypedObjectUtils.keys(poolByItsToken);
189211

190-
const chainId = CHAINS[network];
191-
const poolTokensWithExtraReward = (
192-
poolsWithExtraRewards[network] || []
193-
).filter(p => {
194-
const token = tokensList[p.toLowerCase() as Address];
195-
196-
if (!token) {
197-
console.error(`Pool token not found ${p}`);
198-
return false;
199-
}
200-
return true;
201-
});
202-
203212
const farmInfoCalls = poolStakedTokens.map(address => ({
204213
address,
205214
abi: iFarmingPoolAbi,
@@ -221,40 +230,14 @@ export class GearboxRewardsApi {
221230
args: [],
222231
}));
223232

224-
const [mc, ...extra] = await Promise.allSettled([
225-
provider.multicall({
226-
allowFailure: false,
227-
multicallAddress: MULTICALL_ADDRESS,
228-
contracts: [
229-
{
230-
address: multicallAddress,
231-
abi: iMulticall3Abi as any,
232-
functionName: "getCurrentBlockTimestamp",
233-
args: [],
234-
},
235-
236-
...farmInfoCalls,
237-
...farmSupplyCalls,
238-
...rewardTokenCalls,
239-
],
240-
}),
241-
242-
...poolTokensWithExtraReward.map(t => {
243-
return axios.get<MerkleXYZRewardsCampaignsResponse>(
244-
MerkleXYZApi.getRewardsCampaignsUrl({
245-
params: {
246-
chainId,
247-
mainParameter: getAddress(t),
248-
},
249-
}),
250-
);
251-
}),
252-
]);
233+
const mc = await provider.multicall({
234+
allowFailure: false,
235+
multicallAddress: MULTICALL_ADDRESS,
236+
contracts: [...farmInfoCalls, ...farmSupplyCalls, ...rewardTokenCalls],
237+
});
253238

254-
const mcResponse =
255-
this.extractFulfilled(mc, reportError, "rewardsInfoMulticall") || [];
256-
const [ts = 0n, ...restMCResponse] = mcResponse;
257-
const blockTimestamp = (ts as bigint) || 0n;
239+
const mcResponse = mc;
240+
const [...restMCResponse] = mcResponse;
258241

259242
const farmInfoCallsEnd = farmInfoCalls.length;
260243
const farmInfo = restMCResponse.slice(
@@ -298,57 +281,8 @@ export class GearboxRewardsApi {
298281
{},
299282
);
300283

301-
const extraRewards = extra.reduce<Record<string, Array<FarmInfo>>>(
302-
(acc, r, index) => {
303-
const p = poolTokensWithExtraReward[index].toLowerCase() as Address;
304-
305-
const safeResp = this.extractFulfilled(
306-
r,
307-
reportError,
308-
`merkleCampaign: ${p}`,
309-
);
310-
311-
const l = safeResp?.data.reduce<Array<FarmInfo>>((infos, d) => {
312-
const started = toBigInt(d.startTimestamp || 0);
313-
const finished = toBigInt(d.endTimestamp || 0);
314-
315-
if (blockTimestamp >= started && blockTimestamp <= finished) {
316-
const rewardTokenLc = (
317-
d.rewardToken || ""
318-
).toLowerCase() as Address;
319-
const rewardTokenData = tokensList[rewardTokenLc];
320-
const reward = toBN(
321-
d.amountDecimal,
322-
rewardTokenData?.decimals || 18,
323-
);
324-
325-
if (rewardTokenData && reward > 0) {
326-
infos.push({
327-
pool: poolByItsToken[p],
328-
duration: toBigInt(d.endTimestamp - d.startTimestamp),
329-
finished,
330-
reward,
331-
balance: 0n,
332-
symbol: rewardTokenData.symbol,
333-
});
334-
}
335-
}
336-
337-
return infos;
338-
}, []);
339-
340-
if (l) {
341-
acc[p] = l;
342-
}
343-
344-
return acc;
345-
},
346-
{},
347-
);
348-
349284
const stakedTokenRewards = allPoolTokens.reduce<{
350285
base: Record<string, FarmInfo>;
351-
extra: Record<string, Array<FarmInfo>>;
352286
all: Record<string, Array<FarmInfo>>;
353287
}>(
354288
(acc, pool) => {
@@ -368,15 +302,12 @@ export class GearboxRewardsApi {
368302
}
369303
: undefined;
370304

371-
const extra = extraRewards[pool] || [];
372-
373305
if (baseReward) acc.base[pool] = baseReward;
374-
acc.extra[pool] = extra;
375-
acc.all[pool] = [...(baseReward ? [baseReward] : []), ...extra];
306+
acc.all[pool] = [...(baseReward ? [baseReward] : [])];
376307

377308
return acc;
378309
},
379-
{ base: {}, extra: {}, all: {} },
310+
{ base: {}, all: {} },
380311
);
381312

382313
const rewardPoolsSupply = allPoolTokens.reduce<Record<string, bigint>>(
@@ -391,7 +322,6 @@ export class GearboxRewardsApi {
391322
return {
392323
rewardPoolsInfo: stakedTokenRewards.all,
393324
baseRewardPoolsInfo: stakedTokenRewards.base,
394-
extraRewardPoolsInfo: stakedTokenRewards.extra,
395325
rewardPoolsSupply,
396326
};
397327
}

src/gearboxRewards/apy.ts

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,10 @@ const ONE = PERCENTAGE_FACTOR_1KK * 10n;
3737
export interface ExtraRewardApy {
3838
token: Address;
3939
balance: bigint | null;
40-
apy: number;
4140

42-
rewardInfo: FarmInfo;
41+
apy: number;
42+
rewardToken: Address;
43+
rewardTokenSymbol: string;
4344
}
4445

4546
interface GetPoolExtraAPY_V3Props {
@@ -150,8 +151,10 @@ export class GearboxRewardsApy {
150151
return {
151152
token: stakedDieselToken,
152153
balance: null,
154+
153155
apy: r,
154-
rewardInfo: rewardPoolsInfo,
156+
rewardToken: rewardAddress,
157+
rewardTokenSymbol: rewardPoolsInfo.symbol,
155158
};
156159
}
157160

@@ -252,6 +255,13 @@ export class GearboxRewardsApy {
252255
},
253256
}) / Number(PERCENTAGE_FACTOR);
254257

255-
return { token, balance, rewardInfo, apy: r };
258+
return {
259+
token,
260+
balance,
261+
262+
apy: r,
263+
rewardToken: rewardAddress,
264+
rewardTokenSymbol: rewardInfo.symbol,
265+
};
256266
}
257267
}

0 commit comments

Comments
 (0)