Skip to content

Commit

Permalink
feat(rewards): fixing morpho rewards on vault positions (DefiLlama#1699)
Browse files Browse the repository at this point in the history
  • Loading branch information
tomrpl authored and Silverwingsw committed Feb 13, 2025
1 parent 846eecc commit 372ac0c
Showing 1 changed file with 76 additions and 37 deletions.
113 changes: 76 additions & 37 deletions src/adaptors/morpho-blue/index.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
const { request, gql } = require('graphql-request');

const GRAPH_URL = 'https://blue-api.morpho.org/graphql';
const MORPHO_TOKEN_ADDRESS = '0x9994E35Db50125E0DF82e4c2dde62496CE330999';
const CHAINS = {
ethereum: 1,
base: 8453,
};

const gqlQueries = {
marketsData: gql`
query GetYieldsData($chainId: Int!) {
query GetYieldsData($chainId: Int!, $skip: Int!) {
markets(
first: 800
first: 100
skip: $skip
orderBy: SupplyAssetsUsd
orderDirection: Desc
where: { chainId_in: [$chainId] }
Expand Down Expand Up @@ -43,6 +43,7 @@ const gqlQueries = {
supplyAssetsUsd
borrowAssetsUsd
rewards {
borrowApr
asset {
address
}
Expand All @@ -53,9 +54,10 @@ const gqlQueries = {
}
`,
metaMorphoVaults: gql`
query GetVaultsData($chainId: Int!) {
query GetVaultsData($chainId: Int!, $skip: Int!) {
vaults(
first: 100
skip: $skip
orderBy: TotalAssetsUsd
orderDirection: Desc
where: { chainId_in: [$chainId] }
Expand All @@ -78,10 +80,18 @@ const gqlQueries = {
fee
totalSupply
allocation {
supplyAssetsUsd
market {
uniqueKey
state {
rewards {
asset {
address
}
supplyApr
}
}
}
supplyAssetsUsd
}
}
}
Expand All @@ -98,42 +108,59 @@ const apy = async () => {
let pools = [];

for (const [chain, chainId] of Object.entries(CHAINS)) {
const data = await Promise.all([
request(GRAPH_URL, gqlQueries.metaMorphoVaults, { chainId }),
request(GRAPH_URL, gqlQueries.marketsData, { chainId }),
]);
// Fetch vaults data with pagination
let allVaults = [];
let skip = 0;
while (true) {
const { vaults } = await request(GRAPH_URL, gqlQueries.metaMorphoVaults, {
chainId,
skip,
});

if (!vaults.items.length) break;

allVaults = [...allVaults, ...vaults.items];
skip += 100;
}

// Fetch markets data with pagination
let allMarkets = [];
skip = 0;
while (true) {
const { markets } = await request(GRAPH_URL, gqlQueries.marketsData, {
chainId,
skip,
});

const earn = data[0].vaults.items;
const borrow = data[1].markets.items;
if (!markets.items.length) break;

allMarkets = [...allMarkets, ...markets.items];
skip += 100;
}

const earn = allVaults;
const borrow = allMarkets;

const earnPools = earn.map((vault) => {
// fetch reward token addresses from borrow data
let additionalRewardTokens = [];
// fetch reward token addresses from allocation data
let additionalRewardTokens = new Set();
vault.state.allocation.forEach((allocatedMarket) => {
if (allocatedMarket.supplyAssetsUsd !== 0) {
const marketRewards = borrow.find(
(market) =>
market.pool === `morpho-blue-${allocatedMarket.market.uniqueKey}`
);
if (marketRewards) {
additionalRewardTokens = additionalRewardTokens.concat(
marketRewards.rewardTokens
);
}
const allocationUsd = allocatedMarket.supplyAssetsUsd;
if (allocationUsd > 0) {
// For each reward from the allocated market
allocatedMarket.market.state.rewards?.forEach((rw) => {
if (rw.supplyApr > 0) {
additionalRewardTokens.add(rw.asset.address.toLowerCase());
}
});
}
});

// net = including rewards, apy = baseApy
const rewardsApy = vault.state.netApy - vault.state.apy;
const isNegligibleApy = isNegligible(rewardsApy, vault.state.apy);
const apyReward =
isNegligibleApy || additionalRewardTokens.length === 0
? 0
: rewardsApy * 100;
const rewardTokens =
isNegligibleApy || additionalRewardTokens.length === 0
? []
: [...new Set(additionalRewardTokens)];
const rewardsApy = Math.max(vault.state.netApy - vault.state.apy, 0);
const isNegligibleApy = isNegligible(rewardsApy, vault.state.netApy);
const rewardTokens = isNegligibleApy ? [] : [...additionalRewardTokens];
const apyReward = rewardTokens.length === 0 ? 0 : rewardsApy * 100;

return {
pool: `morpho-blue-${vault.address}-${chain}`,
Expand All @@ -153,10 +180,9 @@ const apy = async () => {

const borrowPools = borrow.map((market) => {
if (!market.collateralAsset?.symbol) return null;

const rewardTokens = market.state.rewards
.map((reward) => reward.asset.address)
.filter((address) => address !== MORPHO_TOKEN_ADDRESS);
.filter((reward) => reward.borrowApr > 0)
.map((reward) => reward.asset.address);

const apyRewardBorrow =
Math.max(
Expand Down Expand Up @@ -190,7 +216,20 @@ const apy = async () => {
pools = [...pools, ...earnPools, ...borrowPools];
}

return pools.filter(Boolean);
const uniquePools = Array.from(
pools
.reduce((map, pool) => {
if (!pool) return map;
const key = `morpho-blue-${pool.pool}-${pool.chain}`;
if (!map.has(key) || pool.tvlUsd > map.get(key).tvlUsd) {
map.set(key, pool);
}
return map;
}, new Map())
.values()
);

return uniquePools.filter(Boolean);
};

module.exports = {
Expand Down

0 comments on commit 372ac0c

Please sign in to comment.