diff --git a/lib/abis/EulerSwap.json b/lib/abis/EulerSwap.json new file mode 100644 index 0000000000..7020fb3342 --- /dev/null +++ b/lib/abis/EulerSwap.json @@ -0,0 +1,1382 @@ +[ + { + "type": "constructor", + "inputs": [ + { + "name": "evc_", + "type": "address", + "internalType": "address" + }, + { + "name": "poolManager_", + "type": "address", + "internalType": "address" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "EVC", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "address" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "activate", + "inputs": [ + { + "name": "initialState", + "type": "tuple", + "internalType": "struct IEulerSwap.InitialState", + "components": [ + { + "name": "currReserve0", + "type": "uint112", + "internalType": "uint112" + }, + { + "name": "currReserve1", + "type": "uint112", + "internalType": "uint112" + } + ] + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "afterAddLiquidity", + "inputs": [ + { + "name": "sender", + "type": "address", + "internalType": "address" + }, + { + "name": "key", + "type": "tuple", + "internalType": "struct PoolKey", + "components": [ + { + "name": "currency0", + "type": "address", + "internalType": "Currency" + }, + { + "name": "currency1", + "type": "address", + "internalType": "Currency" + }, + { + "name": "fee", + "type": "uint24", + "internalType": "uint24" + }, + { + "name": "tickSpacing", + "type": "int24", + "internalType": "int24" + }, + { + "name": "hooks", + "type": "address", + "internalType": "contract IHooks" + } + ] + }, + { + "name": "params", + "type": "tuple", + "internalType": "struct IPoolManager.ModifyLiquidityParams", + "components": [ + { + "name": "tickLower", + "type": "int24", + "internalType": "int24" + }, + { + "name": "tickUpper", + "type": "int24", + "internalType": "int24" + }, + { + "name": "liquidityDelta", + "type": "int256", + "internalType": "int256" + }, + { + "name": "salt", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "delta", + "type": "int256", + "internalType": "BalanceDelta" + }, + { + "name": "feesAccrued", + "type": "int256", + "internalType": "BalanceDelta" + }, + { + "name": "hookData", + "type": "bytes", + "internalType": "bytes" + } + ], + "outputs": [ + { + "name": "", + "type": "bytes4", + "internalType": "bytes4" + }, + { + "name": "", + "type": "int256", + "internalType": "BalanceDelta" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "afterDonate", + "inputs": [ + { + "name": "sender", + "type": "address", + "internalType": "address" + }, + { + "name": "key", + "type": "tuple", + "internalType": "struct PoolKey", + "components": [ + { + "name": "currency0", + "type": "address", + "internalType": "Currency" + }, + { + "name": "currency1", + "type": "address", + "internalType": "Currency" + }, + { + "name": "fee", + "type": "uint24", + "internalType": "uint24" + }, + { + "name": "tickSpacing", + "type": "int24", + "internalType": "int24" + }, + { + "name": "hooks", + "type": "address", + "internalType": "contract IHooks" + } + ] + }, + { + "name": "amount0", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "amount1", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "hookData", + "type": "bytes", + "internalType": "bytes" + } + ], + "outputs": [ + { + "name": "", + "type": "bytes4", + "internalType": "bytes4" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "afterInitialize", + "inputs": [ + { + "name": "sender", + "type": "address", + "internalType": "address" + }, + { + "name": "key", + "type": "tuple", + "internalType": "struct PoolKey", + "components": [ + { + "name": "currency0", + "type": "address", + "internalType": "Currency" + }, + { + "name": "currency1", + "type": "address", + "internalType": "Currency" + }, + { + "name": "fee", + "type": "uint24", + "internalType": "uint24" + }, + { + "name": "tickSpacing", + "type": "int24", + "internalType": "int24" + }, + { + "name": "hooks", + "type": "address", + "internalType": "contract IHooks" + } + ] + }, + { + "name": "sqrtPriceX96", + "type": "uint160", + "internalType": "uint160" + }, + { + "name": "tick", + "type": "int24", + "internalType": "int24" + } + ], + "outputs": [ + { + "name": "", + "type": "bytes4", + "internalType": "bytes4" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "afterRemoveLiquidity", + "inputs": [ + { + "name": "sender", + "type": "address", + "internalType": "address" + }, + { + "name": "key", + "type": "tuple", + "internalType": "struct PoolKey", + "components": [ + { + "name": "currency0", + "type": "address", + "internalType": "Currency" + }, + { + "name": "currency1", + "type": "address", + "internalType": "Currency" + }, + { + "name": "fee", + "type": "uint24", + "internalType": "uint24" + }, + { + "name": "tickSpacing", + "type": "int24", + "internalType": "int24" + }, + { + "name": "hooks", + "type": "address", + "internalType": "contract IHooks" + } + ] + }, + { + "name": "params", + "type": "tuple", + "internalType": "struct IPoolManager.ModifyLiquidityParams", + "components": [ + { + "name": "tickLower", + "type": "int24", + "internalType": "int24" + }, + { + "name": "tickUpper", + "type": "int24", + "internalType": "int24" + }, + { + "name": "liquidityDelta", + "type": "int256", + "internalType": "int256" + }, + { + "name": "salt", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "delta", + "type": "int256", + "internalType": "BalanceDelta" + }, + { + "name": "feesAccrued", + "type": "int256", + "internalType": "BalanceDelta" + }, + { + "name": "hookData", + "type": "bytes", + "internalType": "bytes" + } + ], + "outputs": [ + { + "name": "", + "type": "bytes4", + "internalType": "bytes4" + }, + { + "name": "", + "type": "int256", + "internalType": "BalanceDelta" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "afterSwap", + "inputs": [ + { + "name": "sender", + "type": "address", + "internalType": "address" + }, + { + "name": "key", + "type": "tuple", + "internalType": "struct PoolKey", + "components": [ + { + "name": "currency0", + "type": "address", + "internalType": "Currency" + }, + { + "name": "currency1", + "type": "address", + "internalType": "Currency" + }, + { + "name": "fee", + "type": "uint24", + "internalType": "uint24" + }, + { + "name": "tickSpacing", + "type": "int24", + "internalType": "int24" + }, + { + "name": "hooks", + "type": "address", + "internalType": "contract IHooks" + } + ] + }, + { + "name": "params", + "type": "tuple", + "internalType": "struct IPoolManager.SwapParams", + "components": [ + { + "name": "zeroForOne", + "type": "bool", + "internalType": "bool" + }, + { + "name": "amountSpecified", + "type": "int256", + "internalType": "int256" + }, + { + "name": "sqrtPriceLimitX96", + "type": "uint160", + "internalType": "uint160" + } + ] + }, + { + "name": "delta", + "type": "int256", + "internalType": "BalanceDelta" + }, + { + "name": "hookData", + "type": "bytes", + "internalType": "bytes" + } + ], + "outputs": [ + { + "name": "", + "type": "bytes4", + "internalType": "bytes4" + }, + { + "name": "", + "type": "int128", + "internalType": "int128" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "beforeAddLiquidity", + "inputs": [ + { + "name": "sender", + "type": "address", + "internalType": "address" + }, + { + "name": "key", + "type": "tuple", + "internalType": "struct PoolKey", + "components": [ + { + "name": "currency0", + "type": "address", + "internalType": "Currency" + }, + { + "name": "currency1", + "type": "address", + "internalType": "Currency" + }, + { + "name": "fee", + "type": "uint24", + "internalType": "uint24" + }, + { + "name": "tickSpacing", + "type": "int24", + "internalType": "int24" + }, + { + "name": "hooks", + "type": "address", + "internalType": "contract IHooks" + } + ] + }, + { + "name": "params", + "type": "tuple", + "internalType": "struct IPoolManager.ModifyLiquidityParams", + "components": [ + { + "name": "tickLower", + "type": "int24", + "internalType": "int24" + }, + { + "name": "tickUpper", + "type": "int24", + "internalType": "int24" + }, + { + "name": "liquidityDelta", + "type": "int256", + "internalType": "int256" + }, + { + "name": "salt", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "hookData", + "type": "bytes", + "internalType": "bytes" + } + ], + "outputs": [ + { + "name": "", + "type": "bytes4", + "internalType": "bytes4" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "beforeDonate", + "inputs": [ + { + "name": "sender", + "type": "address", + "internalType": "address" + }, + { + "name": "key", + "type": "tuple", + "internalType": "struct PoolKey", + "components": [ + { + "name": "currency0", + "type": "address", + "internalType": "Currency" + }, + { + "name": "currency1", + "type": "address", + "internalType": "Currency" + }, + { + "name": "fee", + "type": "uint24", + "internalType": "uint24" + }, + { + "name": "tickSpacing", + "type": "int24", + "internalType": "int24" + }, + { + "name": "hooks", + "type": "address", + "internalType": "contract IHooks" + } + ] + }, + { + "name": "amount0", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "amount1", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "hookData", + "type": "bytes", + "internalType": "bytes" + } + ], + "outputs": [ + { + "name": "", + "type": "bytes4", + "internalType": "bytes4" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "beforeInitialize", + "inputs": [ + { + "name": "sender", + "type": "address", + "internalType": "address" + }, + { + "name": "key", + "type": "tuple", + "internalType": "struct PoolKey", + "components": [ + { + "name": "currency0", + "type": "address", + "internalType": "Currency" + }, + { + "name": "currency1", + "type": "address", + "internalType": "Currency" + }, + { + "name": "fee", + "type": "uint24", + "internalType": "uint24" + }, + { + "name": "tickSpacing", + "type": "int24", + "internalType": "int24" + }, + { + "name": "hooks", + "type": "address", + "internalType": "contract IHooks" + } + ] + }, + { + "name": "sqrtPriceX96", + "type": "uint160", + "internalType": "uint160" + } + ], + "outputs": [ + { + "name": "", + "type": "bytes4", + "internalType": "bytes4" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "beforeRemoveLiquidity", + "inputs": [ + { + "name": "sender", + "type": "address", + "internalType": "address" + }, + { + "name": "key", + "type": "tuple", + "internalType": "struct PoolKey", + "components": [ + { + "name": "currency0", + "type": "address", + "internalType": "Currency" + }, + { + "name": "currency1", + "type": "address", + "internalType": "Currency" + }, + { + "name": "fee", + "type": "uint24", + "internalType": "uint24" + }, + { + "name": "tickSpacing", + "type": "int24", + "internalType": "int24" + }, + { + "name": "hooks", + "type": "address", + "internalType": "contract IHooks" + } + ] + }, + { + "name": "params", + "type": "tuple", + "internalType": "struct IPoolManager.ModifyLiquidityParams", + "components": [ + { + "name": "tickLower", + "type": "int24", + "internalType": "int24" + }, + { + "name": "tickUpper", + "type": "int24", + "internalType": "int24" + }, + { + "name": "liquidityDelta", + "type": "int256", + "internalType": "int256" + }, + { + "name": "salt", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "hookData", + "type": "bytes", + "internalType": "bytes" + } + ], + "outputs": [ + { + "name": "", + "type": "bytes4", + "internalType": "bytes4" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "beforeSwap", + "inputs": [ + { + "name": "sender", + "type": "address", + "internalType": "address" + }, + { + "name": "key", + "type": "tuple", + "internalType": "struct PoolKey", + "components": [ + { + "name": "currency0", + "type": "address", + "internalType": "Currency" + }, + { + "name": "currency1", + "type": "address", + "internalType": "Currency" + }, + { + "name": "fee", + "type": "uint24", + "internalType": "uint24" + }, + { + "name": "tickSpacing", + "type": "int24", + "internalType": "int24" + }, + { + "name": "hooks", + "type": "address", + "internalType": "contract IHooks" + } + ] + }, + { + "name": "params", + "type": "tuple", + "internalType": "struct IPoolManager.SwapParams", + "components": [ + { + "name": "zeroForOne", + "type": "bool", + "internalType": "bool" + }, + { + "name": "amountSpecified", + "type": "int256", + "internalType": "int256" + }, + { + "name": "sqrtPriceLimitX96", + "type": "uint160", + "internalType": "uint160" + } + ] + }, + { + "name": "hookData", + "type": "bytes", + "internalType": "bytes" + } + ], + "outputs": [ + { + "name": "", + "type": "bytes4", + "internalType": "bytes4" + }, + { + "name": "", + "type": "int256", + "internalType": "BeforeSwapDelta" + }, + { + "name": "", + "type": "uint24", + "internalType": "uint24" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "computeQuote", + "inputs": [ + { + "name": "tokenIn", + "type": "address", + "internalType": "address" + }, + { + "name": "tokenOut", + "type": "address", + "internalType": "address" + }, + { + "name": "amount", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "exactIn", + "type": "bool", + "internalType": "bool" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "curve", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getAssets", + "inputs": [], + "outputs": [ + { + "name": "asset0", + "type": "address", + "internalType": "address" + }, + { + "name": "asset1", + "type": "address", + "internalType": "address" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getHookPermissions", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "tuple", + "internalType": "struct Hooks.Permissions", + "components": [ + { + "name": "beforeInitialize", + "type": "bool", + "internalType": "bool" + }, + { + "name": "afterInitialize", + "type": "bool", + "internalType": "bool" + }, + { + "name": "beforeAddLiquidity", + "type": "bool", + "internalType": "bool" + }, + { + "name": "afterAddLiquidity", + "type": "bool", + "internalType": "bool" + }, + { + "name": "beforeRemoveLiquidity", + "type": "bool", + "internalType": "bool" + }, + { + "name": "afterRemoveLiquidity", + "type": "bool", + "internalType": "bool" + }, + { + "name": "beforeSwap", + "type": "bool", + "internalType": "bool" + }, + { + "name": "afterSwap", + "type": "bool", + "internalType": "bool" + }, + { + "name": "beforeDonate", + "type": "bool", + "internalType": "bool" + }, + { + "name": "afterDonate", + "type": "bool", + "internalType": "bool" + }, + { + "name": "beforeSwapReturnDelta", + "type": "bool", + "internalType": "bool" + }, + { + "name": "afterSwapReturnDelta", + "type": "bool", + "internalType": "bool" + }, + { + "name": "afterAddLiquidityReturnDelta", + "type": "bool", + "internalType": "bool" + }, + { + "name": "afterRemoveLiquidityReturnDelta", + "type": "bool", + "internalType": "bool" + } + ] + } + ], + "stateMutability": "pure" + }, + { + "type": "function", + "name": "getLimits", + "inputs": [ + { + "name": "tokenIn", + "type": "address", + "internalType": "address" + }, + { + "name": "tokenOut", + "type": "address", + "internalType": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getParams", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "tuple", + "internalType": "struct IEulerSwap.Params", + "components": [ + { + "name": "vault0", + "type": "address", + "internalType": "address" + }, + { + "name": "vault1", + "type": "address", + "internalType": "address" + }, + { + "name": "eulerAccount", + "type": "address", + "internalType": "address" + }, + { + "name": "equilibriumReserve0", + "type": "uint112", + "internalType": "uint112" + }, + { + "name": "equilibriumReserve1", + "type": "uint112", + "internalType": "uint112" + }, + { + "name": "priceX", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "priceY", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "concentrationX", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "concentrationY", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "fee", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "protocolFee", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "protocolFeeRecipient", + "type": "address", + "internalType": "address" + } + ] + } + ], + "stateMutability": "pure" + }, + { + "type": "function", + "name": "getReserves", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint112", + "internalType": "uint112" + }, + { + "name": "", + "type": "uint112", + "internalType": "uint112" + }, + { + "name": "", + "type": "uint32", + "internalType": "uint32" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "poolKey", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "tuple", + "internalType": "struct PoolKey", + "components": [ + { + "name": "currency0", + "type": "address", + "internalType": "Currency" + }, + { + "name": "currency1", + "type": "address", + "internalType": "Currency" + }, + { + "name": "fee", + "type": "uint24", + "internalType": "uint24" + }, + { + "name": "tickSpacing", + "type": "int24", + "internalType": "int24" + }, + { + "name": "hooks", + "type": "address", + "internalType": "contract IHooks" + } + ] + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "poolManager", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "contract IPoolManager" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "swap", + "inputs": [ + { + "name": "amount0Out", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "amount1Out", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "to", + "type": "address", + "internalType": "address" + }, + { + "name": "data", + "type": "bytes", + "internalType": "bytes" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "event", + "name": "EulerSwapActivated", + "inputs": [ + { + "name": "asset0", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "asset1", + "type": "address", + "indexed": true, + "internalType": "address" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "Swap", + "inputs": [ + { + "name": "sender", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "amount0In", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + }, + { + "name": "amount1In", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + }, + { + "name": "amount0Out", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + }, + { + "name": "amount1Out", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + }, + { + "name": "reserve0", + "type": "uint112", + "indexed": false, + "internalType": "uint112" + }, + { + "name": "reserve1", + "type": "uint112", + "indexed": false, + "internalType": "uint112" + }, + { + "name": "to", + "type": "address", + "indexed": true, + "internalType": "address" + } + ], + "anonymous": false + }, + { + "type": "error", + "name": "AlreadyActivated", + "inputs": [] + }, + { + "type": "error", + "name": "AmountTooBig", + "inputs": [] + }, + { + "type": "error", + "name": "AssetsOutOfOrderOrEqual", + "inputs": [] + }, + { + "type": "error", + "name": "BadParam", + "inputs": [] + }, + { + "type": "error", + "name": "ControllerDisabled", + "inputs": [] + }, + { + "type": "error", + "name": "CurveViolation", + "inputs": [] + }, + { + "type": "error", + "name": "DepositFailure", + "inputs": [ + { + "name": "reason", + "type": "bytes", + "internalType": "bytes" + } + ] + }, + { + "type": "error", + "name": "EVC_InvalidAddress", + "inputs": [] + }, + { + "type": "error", + "name": "HookNotImplemented", + "inputs": [] + }, + { + "type": "error", + "name": "InsufficientCalldata", + "inputs": [] + }, + { + "type": "error", + "name": "Locked", + "inputs": [] + }, + { + "type": "error", + "name": "LockedHook", + "inputs": [] + }, + { + "type": "error", + "name": "NotAuthorized", + "inputs": [] + }, + { + "type": "error", + "name": "NotPoolManager", + "inputs": [] + }, + { + "type": "error", + "name": "OperatorNotInstalled", + "inputs": [] + }, + { + "type": "error", + "name": "Overflow", + "inputs": [] + }, + { + "type": "error", + "name": "SafeERC20FailedOperation", + "inputs": [ + { + "name": "token", + "type": "address", + "internalType": "address" + } + ] + }, + { + "type": "error", + "name": "SwapLimitExceeded", + "inputs": [] + }, + { + "type": "error", + "name": "UnsupportedPair", + "inputs": [] + } +] diff --git a/lib/cron/cache-pools.ts b/lib/cron/cache-pools.ts index 60ef9bd98f..381da59849 100644 --- a/lib/cron/cache-pools.ts +++ b/lib/cron/cache-pools.ts @@ -26,12 +26,38 @@ import * as zlib from 'zlib' import dotenv from 'dotenv' import { v4HooksPoolsFiltering } from '../util/v4HooksPoolsFiltering' import { BUNNI_POOLS_CONFIG } from '../util/bunni-pools' +import { EulerSwap } from '../types/ext/EulerSwap' +import { EulerSwap__factory } from '../types/ext/factories/EulerSwap__factory' +import { GlobalRpcProviders } from '../rpc/GlobalRpcProviders' // Needed for local stack dev, not needed for staging or prod // But it still doesn't work on the local cdk stack update, // so we will manually populate ALCHEMY_QUERY_KEY env var in the cron job lambda in cache-config.ts dotenv.config() +function getEthToUsdRate(pools: V4SubgraphPool[]): number { + const top3TvlPools = pools + .slice() + .sort((a, b) => b.tvlUSD - a.tvlUSD) + .slice(0, 3) + const averageRate = top3TvlPools.reduce((acc, pool) => acc + pool.tvlUSD / pool.tvlETH, 0) / top3TvlPools.length + return averageRate +} + +function isUsdEquivalent(symbol: string | undefined): boolean { + if (!symbol) { + return false + } + return ['USDC', 'USDT', 'USDe'].includes(symbol) +} + +function isEthEquivalent(symbol: string | undefined): boolean { + if (!symbol) { + return false + } + return ['WETH', 'stETH', 'ETH'].includes(symbol) +} + const handler: ScheduledHandler = metricScope((metrics) => async (event: EventBridgeEvent) => { const beforeAll = Date.now() metrics.setNamespace('Uniswap') @@ -297,6 +323,9 @@ const handler: ScheduledHandler = metricScope((metrics) => async (event: EventBr ] if (eulerHooksProvider) { + const ethToUsdRate = getEthToUsdRate(pools as V4SubgraphPool[]) + log.info(`Eth to USD rate: ${ethToUsdRate}`) + const eulerHooks = await eulerHooksProvider?.getHooks() if (eulerHooks) { metric.putMetric('eulerHooks.length', eulerHooks.length) @@ -304,11 +333,51 @@ const handler: ScheduledHandler = metricScope((metrics) => async (event: EventBr const eulerPools = await Promise.all( eulerHooks.map(async (eulerHook) => { const pool = await eulerHooksProvider?.getPoolByHook(eulerHook.hook) - log.info(`eulerHooks pool ${JSON.stringify(pool)}`) - // we need to inflate euler pool TVL from 0 to significant TVL, so that they have a chance to be picked up - ;(pool as V4SubgraphPool).tvlUSD = 1000 - ;(pool as V4SubgraphPool).tvlETH = 5500000 + if (!pool) { + log.info(`No pool found for euler hook ${eulerHook.hook}`) + return null + } + + const contract: EulerSwap = EulerSwap__factory.connect( + pool.hooks, + GlobalRpcProviders.getGlobalUniRpcProviders(log).get(ChainId.MAINNET)! + ) + + log.info(`Pool: ${JSON.stringify(pool)}`) + // Get the TVL from the EulerSwap contract + const limits = await contract.getLimits(pool.token0.id, pool.token1.id) + log.info(`Limits: ${JSON.stringify(limits)}`) + + const token0Symbol = pool.token0.symbol + const token1Symbol = pool.token1.symbol + if (isUsdEquivalent(token0Symbol)) { + pool.tvlUSD = limits[0].toNumber() + pool.tvlETH = limits[0].toNumber() / ethToUsdRate + } else if (isUsdEquivalent(token1Symbol)) { + pool.tvlUSD = limits[1].toNumber() + pool.tvlETH = limits[1].toNumber() / ethToUsdRate + } else if (isEthEquivalent(token0Symbol)) { + pool.tvlETH = limits[0].toNumber() + pool.tvlUSD = limits[0].toNumber() * ethToUsdRate + } else if (isEthEquivalent(token1Symbol)) { + pool.tvlETH = limits[1].toNumber() + pool.tvlUSD = limits[1].toNumber() * ethToUsdRate + } else { + log.info( + `Unknown token symbol: pool ${pool.id} with token0 symbol ${token0Symbol} and token1 symbol ${token1Symbol} is not usd or eth equivalent` + ) + log.info(`Setting TVL to 1000 USD and 5500000 ETH`) + } + + if ((pool.tvlUSD === 0 && pool.tvlETH === 0) || !pool.tvlUSD || !pool.tvlETH) { + log.info(`Pool ${pool.id} has 0 TVL`) + // we need to inflate euler pool TVL from 0 to significant TVL, so that they have a chance to be picked up + ;(pool as V4SubgraphPool).tvlUSD = 1000 + ;(pool as V4SubgraphPool).tvlETH = 5500000 + } + + log.info(`Pool TVL USD: ${pool.tvlUSD}, Pool TVL ETH: ${pool.tvlETH}`) return pool })