diff --git a/src/app/api/fee-compare/route.ts b/src/app/api/fee-compare/route.ts index b4f9e2e1..d6d53301 100644 --- a/src/app/api/fee-compare/route.ts +++ b/src/app/api/fee-compare/route.ts @@ -132,6 +132,7 @@ type GainsApiTrade = { realizedTradingFeesCollateral?: number; realizedFundingFeesCollateral?: number; realizedNewBorrowingFeesCollateral?: number; + realizedOldBorrowingFeesCollateral?: number; }; }; }; @@ -180,8 +181,7 @@ type HlWalletData = { type GainsWalletData = { events: number; - feesUsdc: number; // pure taker fee only (uiRealizedPnlData) - vaultFeesUsdc: number; // OI imbalance vault surcharge (tradeFeesData - uiRealizedPnlData) + feesUsdc: number; fundingFeesUsdc: number; fundingEstimated: boolean; borrowingFeesUsdc: number; @@ -193,8 +193,7 @@ type GainsWalletData = { pair: string; action: string; notional: number; - tradingFee: number; // taker fee only - vaultFee: number; // OI vault surcharge + tradingFee: number; fundingFee: number; borrowingFee: number; equivFee?: number; // equivalent fee on the other venue @@ -1525,23 +1524,20 @@ export async function GET(req: Request) { const otherSlug = slug === venueA ? venueB : venueA; const otherRate = slug === venueA ? rateB : rateA; let feesUsdc = 0; - let vaultFeesUsdc = 0; let fundingFeesUsdc = 0; let borrowingFeesUsdc = 0; let notionalUsd = 0; const recentTrades: GainsWalletData["recentTrades"] = []; for (const t of usdcTrades) { - // uiRealizedPnlData = pure taker fee; tradeFeesData = taker + OI vault surcharge + // Gains settles carry (funding + borrowing) on every action, not just closes. + // uiRealizedPnlData breaks down taker, funding, and borrowing separately — use it for all. const takerFee = t.meta?.uiRealizedPnlData?.realizedTradingFeesCollateral ?? t.meta?.tradeFeesData?.realizedTradingFeesCollateral ?? 0; - const totalTradingFee = t.meta?.tradeFeesData?.realizedTradingFeesCollateral ?? takerFee; - const vaultFee = Math.max(0, totalTradingFee - takerFee); - const isClose = CLOSE_ACTIONS.has(t.action); - const fundingFee = isClose ? (t.meta?.uiRealizedPnlData?.realizedFundingFeesCollateral ?? 0) : 0; - const borrowingFee = isClose ? (t.meta?.uiRealizedPnlData?.realizedNewBorrowingFeesCollateral ?? 0) : 0; + const fundingFee = t.meta?.uiRealizedPnlData?.realizedFundingFeesCollateral ?? 0; + const borrowingFee = (t.meta?.uiRealizedPnlData?.realizedNewBorrowingFeesCollateral ?? 0) + + (t.meta?.uiRealizedPnlData?.realizedOldBorrowingFeesCollateral ?? 0); feesUsdc += takerFee; - vaultFeesUsdc += vaultFee; fundingFeesUsdc += fundingFee; borrowingFeesUsdc += borrowingFee; const tradeNotional = t.size * t.leverage; @@ -1550,7 +1546,7 @@ export async function GET(req: Request) { const equivFee = otherSlug === "hyperliquid" ? tradeNotional * (gainsData.perSide[t.pair.split("/")[0]] ?? otherRate) : tradeNotional * otherRate; - recentTrades.push({ date: t.date, pair: t.pair, action: t.action, notional: tradeNotional, tradingFee: takerFee, vaultFee, fundingFee, borrowingFee, equivFee, pnl_net: t.pnl_net }); + recentTrades.push({ date: t.date, pair: t.pair, action: t.action, notional: tradeNotional, tradingFee: takerFee, fundingFee, borrowingFee, equivFee, pnl_net: t.pnl_net }); } } @@ -1566,17 +1562,16 @@ export async function GET(req: Request) { } } - const netCostUsdc = feesUsdc + vaultFeesUsdc + fundingFeesUsdc + borrowingFeesUsdc; + const netCostUsdc = feesUsdc + fundingFeesUsdc + borrowingFeesUsdc; walletData = { events: usdcTrades.length, feesUsdc, - vaultFeesUsdc, fundingFeesUsdc, fundingEstimated, borrowingFeesUsdc, netCostUsdc, positionSizeUsdc: notionalUsd, - avgFeeRateBps: notionalUsd > 0 ? (feesUsdc / notionalUsd) * 10000 : 0, + avgFeeRateBps: notionalUsd > 0 ? (netCostUsdc / notionalUsd) * 10000 : 0, recentTrades, } satisfies GainsWalletData; } else if (fetchEvmWallet && slug === "gmx-v2" && gmxWalletData) { diff --git a/src/components/fee-compare-client.tsx b/src/components/fee-compare-client.tsx index 59c816dd..736879dc 100644 --- a/src/components/fee-compare-client.tsx +++ b/src/components/fee-compare-client.tsx @@ -75,7 +75,6 @@ type HlWalletData = { type GainsWalletData = { events: number; feesUsdc: number; - vaultFeesUsdc: number; fundingFeesUsdc: number; fundingEstimated: boolean; borrowingFeesUsdc: number; @@ -88,7 +87,6 @@ type GainsWalletData = { action: string; notional: number; tradingFee: number; - vaultFee: number; fundingFee: number; borrowingFee: number; equivFee?: number; @@ -735,7 +733,6 @@ function WalletSide({ })()} {venue.slug === "gains" && (() => { const gW = w as GainsWalletData; - const hasVault = (gW.vaultFeesUsdc ?? 0) > 0.5; const hasFunding = Math.abs(gW.fundingFeesUsdc) > 0.5; const hasBorrowing = gW.borrowingFeesUsdc > 0.5; return ( @@ -752,19 +749,6 @@ function WalletSide({
Taker fees
{fmtUsd(gW.feesUsdc)}
- {hasVault && ( - <> -Vault fee
-- +{fmtUsd(gW.vaultFeesUsdc)} -
-- Gains charges an extra fee to LPs when your trade increases the long/short imbalance. Hyperliquid does not have this — it uses funding rates instead. -
- > - )} {hasFunding && (@@ -1202,8 +1186,7 @@ function GainsTradeTable({
{rows.map((t, i) => { - const hasVault = (t.vaultFee ?? 0) > 0.001; - const netCost = t.tradingFee + (t.vaultFee ?? 0) + t.fundingFee + t.borrowingFee; + const netCost = t.tradingFee + t.fundingFee + t.borrowingFee; const diff = hasEquiv && t.equivFee !== undefined ? t.equivFee - netCost : undefined; return ({fmtUsd(netCost)}
{fmtUsd(t.tradingFee)} taker - {hasVault ? ` +${fmtUsd(t.vaultFee)} vault LP` : ""} {t.borrowingFee > 0.001 ? ` +${fmtUsd(t.borrowingFee)} borrow` : ""} {Math.abs(t.fundingFee) > 0.001 ? ` ${t.fundingFee > 0 ? "+" : "−"}${fmtUsd(Math.abs(t.fundingFee))} fund`