Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 86 additions & 0 deletions src/adaptors/shapeswap-v3/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
const { request, gql } = require('graphql-request');

const utils = require('../utils');

const SUBGRAPH = 'https://graph.swap.w3us.site/subgraphs/name/shape/uniswap-v3';
const CHAIN = 'shape';
const PROJECT = 'shapeswap-v3';

const poolsQuery = gql`
query ($block: Int!) {
pools(
first: 1000
orderBy: totalValueLockedUSD
orderDirection: desc
block: { number: $block }
where: { totalValueLockedUSD_gt: "100" }
) {
id
feeTier
totalValueLockedToken0
totalValueLockedToken1
totalValueLockedUSD
volumeUSD
token0 { id symbol decimals }
token1 { id symbol decimals }
}
}
`;

const priorVolumeQuery = gql`
query ($block: Int!) {
pools(
first: 1000
orderBy: totalValueLockedUSD
orderDirection: desc
block: { number: $block }
) {
id
volumeUSD
}
}
`;

const apy = async (timestamp = null) => {
const [block, blockPrior] = await utils.getBlocks(CHAIN, timestamp, [SUBGRAPH]);

const { pools } = await request(SUBGRAPH, poolsQuery, { block });

let priorPools = [];
try {
priorPools = (await request(SUBGRAPH, priorVolumeQuery, { block: blockPrior })).pools;
} catch (e) {
console.log('shapeswap-v3 prior block query failed, falling back to zero prior volume', e.message);
}
const priorVolumeById = Object.fromEntries(priorPools.map((p) => [p.id, Number(p.volumeUSD)]));

return pools
.map((p) => {
const tvlUsd = Number(p.totalValueLockedUSD);
const volumeUsdAll = Number(p.volumeUSD);
const volumeUsd1d = Math.max(volumeUsdAll - (priorVolumeById[p.id] ?? volumeUsdAll), 0);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Incorrect fallback for missing prior volume data.

When priorVolumeById[p.id] is undefined (pool missing from prior data or prior query failed), the fallback volumeUsdAll causes the calculation to become volumeUsdAll - volumeUsdAll = 0, resulting in zero 1-day volume and zero APY for affected pools.

The error message on line 53 states "falling back to zero prior volume", which suggests the intent is to treat prior volume as 0 (not 1-day volume as 0). This would make 1-day volume equal to current cumulative volume for new pools or when prior data is unavailable.

🐛 Proposed fix to use zero prior volume as fallback
-      const volumeUsd1d = Math.max(volumeUsdAll - (priorVolumeById[p.id] ?? volumeUsdAll), 0);
+      const volumeUsd1d = Math.max(volumeUsdAll - (priorVolumeById[p.id] ?? 0), 0);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const volumeUsd1d = Math.max(volumeUsdAll - (priorVolumeById[p.id] ?? volumeUsdAll), 0);
const volumeUsd1d = Math.max(volumeUsdAll - (priorVolumeById[p.id] ?? 0), 0);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/adaptors/shapeswap-v3/index.js` at line 61, The calculation for 1-day USD
volume uses a wrong fallback: replace the fallback that uses volumeUsdAll with
zero so missing prior data is treated as priorVolume = 0. Update the expression
that computes volumeUsd1d (which references priorVolumeById, p.id and
volumeUsdAll) to use priorVolumeById[p.id] ?? 0 instead of priorVolumeById[p.id]
?? volumeUsdAll so volumeUsd1d = Math.max(volumeUsdAll - (priorVolumeById[p.id]
?? 0), 0); also review the related log message about "falling back to zero prior
volume" to ensure it matches the new behavior.

const feeRate = Number(p.feeTier) / 1e6;
const fees1d = volumeUsd1d * feeRate;
const apyBase = tvlUsd > 0 ? (fees1d * 365 * 100) / tvlUsd : 0;

return {
pool: `${p.id}-${CHAIN}`.toLowerCase(),
chain: utils.formatChain(CHAIN),
project: PROJECT,
symbol: utils.formatSymbol(`${p.token0.symbol}-${p.token1.symbol}`),
tvlUsd,
apyBase,
underlyingTokens: [p.token0.id, p.token1.id],
poolMeta: `${Number(p.feeTier) / 1e4}%`,
url: `https://info.shapeswap.xyz/home#/pools/${p.id}`,
volumeUsd1d,
};
})
.filter(utils.keepFinite);
};

module.exports = {
timetravel: false,
apy,
url: 'https://shapeswap.xyz/',
};
3 changes: 2 additions & 1 deletion src/adaptors/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,8 @@ const getLatestBlockSubgraph = async (url) => {
url.includes('exchange-v3-zksync/version/latest') ||
url.includes('balancer-base-v2/version/latest') ||
url.includes('horizondex') ||
url.includes('swopfi-units')
url.includes('swopfi-units') ||
url.includes('swap.w3us.site')
? await request(url, queryGraph)
: url.includes('aperture/uniswap-v3')
? await request(
Expand Down
Loading