Skip to content
Open
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
75 changes: 69 additions & 6 deletions src/adaptors/metrom/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,9 @@ const CHAIN_TYPE_AND_NAMES: ByChainTypeAndId<string> = {
42_161: 'Arbitrum',
9_745: 'Plasma',
5_464: 'Saga',
56: 'BSC',
747_474: 'Katana',
4_326: 'MegaETH',
1: 'Ethereum',
},
aptos: {
1: 'Aptos',
Expand All @@ -50,6 +51,7 @@ interface BaseTarget {
interface AmmPoolLiquidityTarget extends BaseTarget {
type: 'amm-pool-liquidity';
id: string;
dex: string;
tokens: Token[];
usdTvl: number;
}
Expand Down Expand Up @@ -108,6 +110,16 @@ interface YieldSeekerTarget extends BaseTarget {
type: 'yield-seeker';
}

interface Erc4626Target extends BaseTarget {
type: 'erc4626-vault';
brand: string;
vault: {
name: string;
symbol: string;
asset: string;
};
}

interface Reward extends Token {
amount: string;
remaining: string;
Expand All @@ -130,7 +142,8 @@ interface Campaign {
| AaveV3BorrowTarget
| AaveV3NetSupplyTarget
| TurtleTarget
| YieldSeekerTarget;
| YieldSeekerTarget
| Erc4626Target;
rewards?: Rewards;
usdTvl?: number;
apr?: number;
Expand Down Expand Up @@ -218,6 +231,7 @@ interface ProcessedCampaign {
apyBase?: number;
apyReward?: number;
rewardTokens?: string[];
poolMeta: string;
}

async function processCampaign(
Expand All @@ -228,26 +242,50 @@ async function processCampaign(
return {
symbol: campaign.target.tokens.map((token) => token.symbol).join(' - '),
underlyingTokens: campaign.target.tokens.map((token) => token.address),
poolMeta: humanizeTargetProtocol('Pool on', campaign.target.dex),
};
}
case 'liquity-v2-debt': {
return {
symbol: campaign.target.collateral.symbol,
underlyingTokens: [campaign.target.collateral.address],
poolMeta: humanizeTargetProtocol('Borrow on', campaign.target.brand),
};
}
case 'liquity-v2-debt':
case 'liquity-v2-stability-pool': {
return {
symbol: campaign.target.collateral.symbol,
underlyingTokens: [campaign.target.collateral.address],
poolMeta: humanizeTargetProtocol(
'Stability pool on',
campaign.target.brand
),
};
}
case 'gmx-v1-liquidity': {
// FIXME: for now, with the current API, it's impossible to process GMX v1
// campaigns, address this later on
return null;
}
case 'aave-v3-supply':
case 'aave-v3-borrow':
case 'aave-v3-supply': {
return {
symbol: campaign.target.collateral.symbol,
underlyingTokens: [campaign.target.collateral.address],
poolMeta: humanizeTargetProtocol('Lend on', campaign.target.brand),
};
}
case 'aave-v3-borrow': {
return {
symbol: campaign.target.collateral.symbol,
underlyingTokens: [campaign.target.collateral.address],
poolMeta: humanizeTargetProtocol('Borrow on', campaign.target.brand),
};
}
case 'aave-v3-net-supply': {
return {
symbol: campaign.target.collateral.symbol,
underlyingTokens: [campaign.target.collateral.address],
poolMeta: humanizeTargetProtocol('Net lend on', campaign.target.brand),
};
}
case 'turtle': {
Expand All @@ -258,16 +296,31 @@ async function processCampaign(
opportunity?.incentives || campaign.target.incentives || [];

return {
symbol: (opportunity?.name || campaign.target.name).replace(/^Katana\s+/i, ''),
symbol: (opportunity?.name || campaign.target.name).replace(
/^Katana\s+/i,
''
),
underlyingTokens: getTurtleUnderlyingTokens(opportunity),
url: opportunity?.url,
...getTurtleApyFields(incentives, campaign.apr),
poolMeta: humanizeTargetProtocol('Deposit to', campaign.target.name),
};
}
case 'yield-seeker': {
return {
symbol: 'USDC',
underlyingTokens: [BASE_USDC],
poolMeta: 'Deposit',
};
}
case 'erc4626-vault': {
return {
symbol: campaign.target.vault.symbol,
underlyingTokens: [campaign.target.vault.asset],
poolMeta: humanizeTargetProtocol(
'Deposit to',
campaign.target.vault.name
),
};
}
default: {
Expand Down Expand Up @@ -362,3 +415,13 @@ function getCampaignApyFields(
}
: { apy: campaign.apr };
}

function humanizeTargetProtocol(action: string, protocolSlug?: string): string {
const normalizedSlug = protocolSlug?.trim();
if (!normalizedSlug) return action;

return `${action} ${normalizedSlug
.split(/[-_]/)
.map((word) => word.charAt(0).toUpperCase() + word.slice(1))
.join(' ')}`;
}
Loading