175 lines
5.7 KiB
TypeScript
175 lines
5.7 KiB
TypeScript
/**
|
|
* Yield protocol constants — contract addresses, function selectors, and types
|
|
* for Aave V3 and Morpho Blue vault integrations.
|
|
*/
|
|
|
|
// ── Supported chains for yield ──
|
|
export type SupportedYieldChain = "1" | "8453";
|
|
export type YieldProtocol = "aave-v3" | "morpho-blue";
|
|
export type StablecoinSymbol = "USDC" | "USDT" | "DAI";
|
|
|
|
export interface YieldOpportunity {
|
|
protocol: YieldProtocol;
|
|
chainId: SupportedYieldChain;
|
|
asset: StablecoinSymbol;
|
|
assetAddress: string;
|
|
vaultAddress: string; // aToken for Aave, vault for Morpho
|
|
apy: number;
|
|
apy7d?: number;
|
|
tvl?: number;
|
|
poolId?: string; // DeFi Llama pool ID
|
|
vaultName?: string;
|
|
}
|
|
|
|
export interface YieldPosition {
|
|
protocol: YieldProtocol;
|
|
chainId: SupportedYieldChain;
|
|
asset: StablecoinSymbol;
|
|
assetAddress: string;
|
|
vaultAddress: string;
|
|
shares: string; // raw shares/aToken balance
|
|
underlying: string; // underlying asset value
|
|
decimals: number;
|
|
apy: number;
|
|
dailyEarnings: number;
|
|
annualEarnings: number;
|
|
}
|
|
|
|
export interface YieldSuggestion {
|
|
type: "deposit" | "rebalance";
|
|
priority: "high" | "medium" | "low";
|
|
from?: { protocol: YieldProtocol; chainId: SupportedYieldChain; vaultAddress: string; apy: number };
|
|
to: YieldOpportunity;
|
|
amount: string;
|
|
amountUSD: number;
|
|
reason: string;
|
|
estimatedGasCostUSD: number;
|
|
}
|
|
|
|
// ── Stablecoin addresses per chain ──
|
|
export const STABLECOIN_ADDRESSES: Record<SupportedYieldChain, Record<StablecoinSymbol, string>> = {
|
|
"1": {
|
|
USDC: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
|
|
USDT: "0xdAC17F958D2ee523a2206206994597C13D831ec7",
|
|
DAI: "0x6B175474E89094C44Da98b954EedeAC495271d0F",
|
|
},
|
|
"8453": {
|
|
USDC: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
|
|
USDT: "0x0000000000000000000000000000000000000000", // not on Base
|
|
DAI: "0x50c5725949A6F0c72E6C4a641F24049A917DB0Cb",
|
|
},
|
|
};
|
|
|
|
export const STABLECOIN_DECIMALS: Record<StablecoinSymbol, number> = {
|
|
USDC: 6,
|
|
USDT: 6,
|
|
DAI: 18,
|
|
};
|
|
|
|
// ── Aave V3 ──
|
|
export const AAVE_V3_POOL: Record<SupportedYieldChain, string> = {
|
|
"1": "0x87870Bca3F3fD6335C3F4ce8392D69350B4fA4E2",
|
|
"8453": "0xA238Dd80C259a72e81d7e4664a9801593F98d1c5",
|
|
};
|
|
|
|
// aToken addresses (receipt tokens for deposits)
|
|
export const AAVE_ATOKENS: Record<SupportedYieldChain, Partial<Record<StablecoinSymbol, string>>> = {
|
|
"1": {
|
|
USDC: "0x98C23E9d8f34FEFb1B7BD6a91B7FF122F4e16F5c",
|
|
USDT: "0x23878914EFE38d27C4D67Ab83ed1b93A74D4086a",
|
|
DAI: "0x018008bfb33d285247A21d44E50697654f754e63",
|
|
},
|
|
"8453": {
|
|
USDC: "0x4e65fE4DbA92790696d040ac24Aa414708F5c0AB",
|
|
DAI: "0x0a1d576f3eFeF75b330424287a95A366e8281D54",
|
|
},
|
|
};
|
|
|
|
// ── Morpho Blue Vaults ──
|
|
export interface MorphoVaultInfo {
|
|
address: string;
|
|
name: string;
|
|
asset: StablecoinSymbol;
|
|
}
|
|
|
|
export const MORPHO_VAULTS: Record<SupportedYieldChain, MorphoVaultInfo[]> = {
|
|
"1": [
|
|
{ address: "0xBEEF01735c132Ada46AA9aA4c54623cAA92A64CB", name: "Steakhouse USDC", asset: "USDC" },
|
|
{ address: "0x2371e134e3455e0593363cBF89d3b6cf53740618", name: "Steakhouse USDT", asset: "USDT" },
|
|
],
|
|
"8453": [
|
|
{ address: "0xc1256Ae5FF1cf2719D4937adb3bbCCab2E00A2Ca", name: "Moonwell Flagship USDC", asset: "USDC" },
|
|
],
|
|
};
|
|
|
|
// ── MultiSend (for batched approve+deposit) ──
|
|
export const MULTISEND_CALL_ONLY: Record<SupportedYieldChain, string> = {
|
|
"1": "0x40A2aCCbd92BCA938b02010E17A5b8929b49130D",
|
|
"8453": "0x40A2aCCbd92BCA938b02010E17A5b8929b49130D",
|
|
};
|
|
|
|
// ── Function selectors ──
|
|
export const SELECTORS = {
|
|
// ERC-20
|
|
approve: "0x095ea7b3", // approve(address,uint256)
|
|
balanceOf: "0x70a08231", // balanceOf(address)
|
|
// Aave V3 Pool
|
|
supply: "0x617ba037", // supply(address,uint256,address,uint16)
|
|
withdraw: "0x69328dec", // withdraw(address,uint256,address)
|
|
getReserveData: "0x35ea6a75", // getReserveData(address)
|
|
// ERC-4626 (Morpho vaults)
|
|
deposit: "0x6e553f65", // deposit(uint256,address)
|
|
redeem: "0xba087652", // redeem(uint256,address,address)
|
|
convertToAssets: "0x07a2d13a", // convertToAssets(uint256)
|
|
maxDeposit: "0x402d267d", // maxDeposit(address)
|
|
// MultiSend
|
|
multiSend: "0x8d80ff0a", // multiSend(bytes)
|
|
} as const;
|
|
|
|
// ── ABI encoding helpers ──
|
|
export function padAddress(addr: string): string {
|
|
return addr.slice(2).toLowerCase().padStart(64, "0");
|
|
}
|
|
|
|
export function padUint256(value: bigint): string {
|
|
return value.toString(16).padStart(64, "0");
|
|
}
|
|
|
|
export function encodeApprove(spender: string, amount: bigint): string {
|
|
return `${SELECTORS.approve}${padAddress(spender)}${padUint256(amount)}`;
|
|
}
|
|
|
|
export function encodeAaveSupply(asset: string, amount: bigint, onBehalfOf: string): string {
|
|
return `${SELECTORS.supply}${padAddress(asset)}${padUint256(amount)}${padAddress(onBehalfOf)}${padUint256(0n)}`;
|
|
}
|
|
|
|
export function encodeAaveWithdraw(asset: string, amount: bigint, to: string): string {
|
|
return `${SELECTORS.withdraw}${padAddress(asset)}${padUint256(amount)}${padAddress(to)}`;
|
|
}
|
|
|
|
export function encodeMorphoDeposit(amount: bigint, receiver: string): string {
|
|
return `${SELECTORS.deposit}${padUint256(amount)}${padAddress(receiver)}`;
|
|
}
|
|
|
|
export function encodeMorphoRedeem(shares: bigint, receiver: string, owner: string): string {
|
|
return `${SELECTORS.redeem}${padUint256(shares)}${padAddress(receiver)}${padAddress(owner)}`;
|
|
}
|
|
|
|
export function encodeBalanceOf(address: string): string {
|
|
return `${SELECTORS.balanceOf}${padAddress(address)}`;
|
|
}
|
|
|
|
export function encodeConvertToAssets(shares: bigint): string {
|
|
return `${SELECTORS.convertToAssets}${padUint256(shares)}`;
|
|
}
|
|
|
|
export function encodeMaxDeposit(receiver: string): string {
|
|
return `${SELECTORS.maxDeposit}${padAddress(receiver)}`;
|
|
}
|
|
|
|
// ── Chain display names ──
|
|
export const YIELD_CHAIN_NAMES: Record<SupportedYieldChain, string> = {
|
|
"1": "Ethereum",
|
|
"8453": "Base",
|
|
};
|