Skip to content

Commit 6be4d83

Browse files
committed
add Merkl rewards to existing pools
1 parent da2cdfa commit 6be4d83

File tree

7 files changed

+110
-24
lines changed

7 files changed

+110
-24
lines changed

src/adaptors/euler-v2/index.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ const lensAbi = require('./lens.abi.json');
55
const factoryAbi = require('./factory.abi.json');
66
const axios = require('axios');
77
const { url } = require('inspector');
8+
const { addMerklRewardApy } = require('../merkl/merkl-additional-reward');
89

910
const chains = {
1011
ethereum: {
@@ -131,7 +132,7 @@ const getApys = async () => {
131132
}
132133
}
133134
}
134-
return result;
135+
return addMerklRewardApy(result, 'euler');
135136
};
136137

137138
module.exports = {

src/adaptors/gamma/index.js

+4-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ const { request, gql } = require('graphql-request');
33
const sdk = require('@defillama/sdk');
44
const utils = require('../utils');
55
const { print } = require('graphql');
6+
const { addMerklRewardApy } = require('../merkl/merkl-additional-reward');
67

78
const EXCHANGES_API = {
89
uniswapv3: '',
@@ -388,11 +389,13 @@ const getApy = async () => {
388389
'0x431f6e577a431d9ee87a535fde2db830e352e33c',
389390
'0xed17209ab7f9224e29cc9894fa14a011f37b6115',
390391
];
391-
return pools.flat().map((i) => ({
392+
const data = pools.flat().map((i) => ({
392393
...i,
393394
apyReward: x.includes(i.pool) || i.chain === 'Manta' ? null : i.apyReward,
394395
rewardTokens: x.includes(i.pool) || i.chain === 'Manta' ? null : i.rewardTokens,
395396
})).filter(p => p.chain != 'Binance');
397+
398+
return addMerklRewardApy(data, 'gamma', (p) => p.pool.split('-')[0]);
396399
};
397400

398401
module.exports = {

src/adaptors/merkl/config.js

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
exports.networks = {
2+
1: 'ethereum',
3+
137: 'polygon',
4+
10: 'optimism',
5+
42161: 'arbitrum',
6+
1101: 'polygon_zkevm',
7+
8453: 'base',
8+
60808: 'bob',
9+
146: 'sonic',
10+
43114: 'avax',
11+
80094: 'berachain',
12+
56: 'bsc',
13+
};
14+
15+
// Protocols that should not be listed under Merkl
16+
// as they already have their own adapters.
17+
exports.protocolsBlacklist = [
18+
'euler',
19+
'crosscurve',
20+
'aerodrome',
21+
'gamma',
22+
'uniswap',
23+
];

src/adaptors/merkl/index.js

+2-19
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,6 @@
11
const sdk = require('@defillama/sdk');
22
const utils = require('../utils');
3-
4-
const networks = {
5-
1: 'ethereum',
6-
137: 'polygon',
7-
10: 'optimism',
8-
42161: 'arbitrum',
9-
1101: 'polygon_zkevm',
10-
8453: 'base',
11-
60808: 'bob',
12-
};
13-
14-
// Protocols that should not be listed under Merkl
15-
// as they already have their own adapters.
16-
const protocolsBlacklist = [
17-
'euler',
18-
'crosscurve',
19-
'aerodrome',
20-
'gamma',
21-
];
3+
const { networks } = require('./config');
224

235
// Allow specific pools from blacklisted protocols
246
const poolsWhitelist = [
@@ -50,6 +32,7 @@ const main = async () => {
5032
data = await utils.getData(`https://api.merkl.xyz/v4/opportunities?chainId=${chainId}&status=LIVE&items=100&page=${pageI}`);
5133
} catch (err) {
5234
console.log('failed to fetch Merkl data on chain ' + chain);
35+
break;
5336
}
5437

5538
if (data.length === 0) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
const { networks } = require('../../constants');
2+
const { getData } = require('../utils');
3+
4+
exports.addMerklRewardApy = async (
5+
pools,
6+
protocolId,
7+
poolAddressGetter,
8+
) => {
9+
try {
10+
let merklPools = [];
11+
let pageI = 0;
12+
13+
while(true) {
14+
let data;
15+
try {
16+
data = await getData(`https://api.merkl.xyz/v4/opportunities?mainProtocolId=${protocolId}&status=LIVE&items=100&page=${pageI}`);
17+
} catch (err) {
18+
console.log(`failed to fetch Merkl data for ${protocolId}: ${err}`);
19+
break;
20+
}
21+
22+
if (data.length === 0) {
23+
break;
24+
}
25+
26+
merklPools.push(...data);
27+
pageI++;
28+
}
29+
30+
31+
const merklPoolsMap = Object.fromEntries(Object.keys(networks).map(id => [networks[id], {}]));
32+
merklPools.forEach(pool => {
33+
if (!networks[pool.chainId]) {
34+
return;
35+
}
36+
37+
merklPoolsMap[networks[pool.chainId]][pool.identifier.toLowerCase()] = {
38+
apyReward: pool.apr,
39+
rewardTokens: [...new Set(pool.rewardsRecord?.breakdowns.map(x => x.token.address) || [])]
40+
}
41+
});
42+
43+
return pools.map(pool => {
44+
const poolAddress = poolAddressGetter ? poolAddressGetter(pool) : pool.pool;
45+
const merklRewards = merklPoolsMap[pool.chain.toLowerCase()][poolAddress.toLowerCase()];
46+
47+
if (!merklRewards) {
48+
return pool;
49+
}
50+
51+
// if the data is already present, don't overwrite it
52+
if (pool.apyReward || (pool.rewardTokens && pool.rewardTokens.length !== 0)) {
53+
console.log('pool already has apyReward or rewardTokens', pool.pool);
54+
return pool;
55+
}
56+
57+
return {
58+
...pool,
59+
...merklRewards,
60+
}
61+
});
62+
} catch (err) {
63+
console.log(`Failed to add Merkl reward apy to ${protocolId}: ${err}`);
64+
65+
// If we fail to fetch Merkl data, just return the original pools
66+
return pools;
67+
}
68+
};

src/adaptors/uniswap-v2/index.js

+5-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ const sdk = require('@defillama/sdk');
22
const { request, gql } = require('graphql-request');
33

44
const utils = require('../utils');
5+
const { addMerklRewardApy } = require('../merkl/merkl-additional-reward');
56

67
const chains = {
78
ethereum: sdk.graph.modifyEndpoint(
@@ -126,7 +127,10 @@ const main = async (timestamp = null) => {
126127
}
127128
}
128129

129-
return data.filter((p) => utils.keepFinite(p));
130+
return addMerklRewardApy(
131+
data.filter((p) => utils.keepFinite(p)),
132+
'uniswap'
133+
);
130134
};
131135

132136
module.exports = {

src/adaptors/uniswap-v3/index.js

+6-2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ const { EstimatedFees } = require('./estimateFee.ts');
77
const { checkStablecoin } = require('../../handlers/triggerEnrichment');
88
const { boundaries } = require('../../utils/exclude');
99
const getOnchainPools = require('./onchain');
10+
const { addMerklRewardApy } = require('../merkl/merkl-additional-reward');
1011

1112
const chains = {
1213
ethereum: sdk.graph.modifyEndpoint(
@@ -352,7 +353,8 @@ const main = async (timestamp = null) => {
352353
);
353354
}
354355
data.push(...(await getOnchainPools()))
355-
return data
356+
return addMerklRewardApy(
357+
data
356358
.flat()
357359
.filter(
358360
(p) =>
@@ -361,7 +363,9 @@ const main = async (timestamp = null) => {
361363
'0x0c6d9d0f82ed2e0b86c4d3e9a9febf95415d1b76',
362364
'0xc809d13e9ea08f296d3b32d4c69d46ff90f73fd8',
363365
].includes(p.pool)
364-
);
366+
),
367+
'uniswap'
368+
);
365369
};
366370

367371
module.exports = {

0 commit comments

Comments
 (0)