diff --git a/src/adaptors/umami-finance/abis/glpVault.json b/src/adaptors/umami-finance/abis/glpVault.json new file mode 100644 index 0000000000..afcac17311 --- /dev/null +++ b/src/adaptors/umami-finance/abis/glpVault.json @@ -0,0 +1,931 @@ +[ + { + "inputs": [ + { + "internalType": "contract ERC20", + "name": "_asset", + "type": "address" + }, + { + "internalType": "string", + "name": "_name", + "type": "string" + }, + { + "internalType": "string", + "name": "_symbol", + "type": "string" + }, + { + "internalType": "address", + "name": "_aggregateVault", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "caller", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "Deposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "Paused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "Unpaused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "caller", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "Withdraw", + "type": "event" + }, + { + "inputs": [], + "name": "AUTH", + "outputs": [ + { + "internalType": "contract Auth", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "DOMAIN_SEPARATOR", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "aggregateVault", + "outputs": [ + { + "internalType": "contract AggregateVault", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "asset", + "outputs": [ + { + "internalType": "contract ERC20", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "convertToAssets", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + } + ], + "name": "convertToShares", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "internalType": "address", + "name": "receiver", + "type": "address" + } + ], + "name": "deposit", + "outputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "maxDeposit", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "maxMint", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "maxRedeem", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "maxWithdraw", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + }, + { + "internalType": "address", + "name": "receiver", + "type": "address" + } + ], + "name": "mint", + "outputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_mintAmount", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_timelockContract", + "type": "address" + } + ], + "name": "mintTimelockBoost", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "nonces", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pauseDepositWithdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "paused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "permit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "pps", + "outputs": [ + { + "internalType": "uint256", + "name": "pricePerShare", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + } + ], + "name": "previewDeposit", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "size", + "type": "uint256" + } + ], + "name": "previewDepositFee", + "outputs": [ + { + "internalType": "uint256", + "name": "totalDepositFee", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "previewMint", + "outputs": [ + { + "internalType": "uint256", + "name": "_mintAmount", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "previewRedeem", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "previewVaultCap", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + } + ], + "name": "previewWithdraw", + "outputs": [ + { + "internalType": "uint256", + "name": "_withdrawAmount", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "size", + "type": "uint256" + } + ], + "name": "previewWithdrawalFee", + "outputs": [ + { + "internalType": "uint256", + "name": "totalWithdrawalFee", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + }, + { + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "redeem", + "outputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalAssets", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "tvl", + "outputs": [ + { + "internalType": "uint256", + "name": "totalValueLocked", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "unpauseDepositWithdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract AggregateVault", + "name": "_newAggregateVault", + "type": "address" + } + ], + "name": "updateAggregateVault", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "internalType": "bytes32[]", + "name": "merkleProof", + "type": "bytes32[]" + } + ], + "name": "whitelistDeposit", + "outputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "withdraw", + "outputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/src/adaptors/umami-finance/index.js b/src/adaptors/umami-finance/index.js index 917390d702..7ffe53679e 100644 --- a/src/adaptors/umami-finance/index.js +++ b/src/adaptors/umami-finance/index.js @@ -1,13 +1,16 @@ const superagent = require('superagent'); const axios = require('axios'); const { request, gql } = require('graphql-request'); - -const UMAMI_GRAPH_URL = - 'https://api.thegraph.com/subgraphs/name/umamidao/protocol-metrics'; -const UMAMI_API_URL = 'https://api.umami.finance/api/v2'; -const UMAMI_ADDRESS = '0x1622bf67e6e5747b81866fe0b85178a93c7f86e3'; -const mUMAMI_ADDRESS = '0x2adabd6e8ce3e82f52d9998a7f64a90d294a92a4'; -const cmUMAMI_ADDRESS = '0x1922c36f3bc762ca300b4a46bb2102f84b1684ab'; +const { + UMAMI_ADDRESS, + mUMAMI_ADDRESS, + cmUMAMI_ADDRESS, + UMAMI_GRAPH_URL, + UMAMI_API_URL, + wETH_ADDRESS, +} = require('./umamiConstants'); +const { getUmamiGlpVaultsYield } = require('./umamiVaults'); +const { WETH } = require('../unsheth/contract_addresses'); const tokenSupplyQuery = gql` { @@ -36,18 +39,26 @@ const main = async () => { const mUMAMI = { pool: mUMAMI_ADDRESS, tvlUsd: +(parseFloat(marinating) * umamiPriceUSD), - apy: +metrics[0].value, - symbol: 'UMAMI', + apyBase: +metrics[0].value, + symbol: 'mUMAMI', + rewardTokens: [wETH_ADDRESS], + underlyingTokens: [UMAMI_ADDRESS], + url: 'https://umami.finance/marinate', }; const cmUMAMI = { pool: cmUMAMI_ADDRESS, tvlUsd: +(parseFloat(compounding) * umamiPriceUSD), - apy: +metrics[1].value, - symbol: 'mUMAMI', + apyBase: +metrics[1].value, + symbol: 'cmUMAMI', + rewardTokens: [UMAMI_ADDRESS], + underlyingTokens: [UMAMI_ADDRESS], + url: 'https://umami.finance/marinate', }; - return [mUMAMI, cmUMAMI].map((strat) => ({ + const vaults = await getUmamiGlpVaultsYield(); + + return [mUMAMI, cmUMAMI, ...vaults].map((strat) => ({ ...strat, chain: 'Arbitrum', project: 'umami-finance', diff --git a/src/adaptors/umami-finance/umamiConstants.js b/src/adaptors/umami-finance/umamiConstants.js new file mode 100644 index 0000000000..2610775714 --- /dev/null +++ b/src/adaptors/umami-finance/umamiConstants.js @@ -0,0 +1,56 @@ +const UMAMI_GRAPH_URL = + 'https://api.thegraph.com/subgraphs/name/umamidao/protocol-metrics'; +const UMAMI_API_URL = 'https://api.umami.finance/api/v2'; + +const UMAMI_ADDRESS = '0x1622bf67e6e5747b81866fe0b85178a93c7f86e3'; +const mUMAMI_ADDRESS = '0x2adabd6e8ce3e82f52d9998a7f64a90d294a92a4'; +const cmUMAMI_ADDRESS = '0x1922c36f3bc762ca300b4a46bb2102f84b1684ab'; +const wETH_ADDRESS = '0x82aF49447D8a07e3bd95BD0d56f35241523fBab1'; + +const UMAMI_ALL_VAULTS = [ + { + id: 'glpusdc', + symbol: 'glpUSDC', + decimals: 6, + underlyingAsset: '0xff970a61a04b1ca14834a43f5de4533ebddb5cc8', + address: '0x727ed4ef04bb2a96ec77e44c1a91dbb01b605e42', + }, + { + id: 'glpweth', + symbol: 'glpWETH', + decimals: 18, + underlyingAsset: '0x82af49447d8a07e3bd95bd0d56f35241523fbab1', + address: '0xbb84d79159d6bbe1de148dc82640caa677e06126', + }, + { + id: 'glpwbtc', + symbol: 'glpWBTC', + decimals: 8, + underlyingAsset: '0x2f2a2543b76a4166549f7aab2e75bef0aefc5b0f', + address: '0x6a89faf99587a12e6bb0351f2fa9006c6cd12257', + }, + { + id: 'glplink', + symbol: 'glpLINK', + decimals: 18, + underlyingAsset: '0xf97f4df75117a78c1a5a0dbb814af92458539fb4', + address: '0xe0a21a475f8da0ee7fa5af8c1809d8ac5257607d', + }, + { + id: 'glpuni', + symbol: 'glpUNI', + decimals: 18, + underlyingAsset: '0xfa7f8980b0f1e64a2062791cc3b0871572f1f7f0', + address: '0x37c0705a65948ea5e0ae1add13552bcad7711a23', + }, +]; + +module.exports = { + wETH_ADDRESS, + UMAMI_GRAPH_URL, + UMAMI_API_URL, + UMAMI_ADDRESS, + mUMAMI_ADDRESS, + cmUMAMI_ADDRESS, + UMAMI_ALL_VAULTS, +}; diff --git a/src/adaptors/umami-finance/umamiVaults.js b/src/adaptors/umami-finance/umamiVaults.js new file mode 100644 index 0000000000..4a36ccae7f --- /dev/null +++ b/src/adaptors/umami-finance/umamiVaults.js @@ -0,0 +1,54 @@ +const axios = require('axios'); +const superagent = require('superagent'); +const sdk = require('@defillama/sdk'); +const Web3 = require('web3'); + +const { UMAMI_ALL_VAULTS, UMAMI_API_URL } = require('./umamiConstants'); +const vaultAbi = require('./abis/glpVault.json'); +const utils = require('../utils'); + +const RPC_URL = 'https://arb-mainnet-public.unifra.io'; + +const web3 = new Web3(RPC_URL); + +const getUmamiGlpVaultsYield = async () => { + const vaults = []; + await Promise.all( + UMAMI_ALL_VAULTS.map(async (vault) => { + const vaultContract = new web3.eth.Contract(vaultAbi, vault.address); + + const tvl = await vaultContract.methods.tvl().call(); + + const vaultFromApi = ( + await superagent.get(`${UMAMI_API_URL}/vaults/${vault.id}`) + ).body; + + const underlyingTokenPriceKey = + `arbitrum:${vault.underlyingAsset}`.toLowerCase(); + + const underlyingTokenPrice = ( + await superagent.get( + `https://coins.llama.fi/prices/current/${underlyingTokenPriceKey}` + ) + ).body.coins[underlyingTokenPriceKey].price; + + vaults.push({ + pool: vault.address, + tvlUsd: +( + parseFloat(tvl / 10 ** vault.decimals) * underlyingTokenPrice + ), + apyBase: +(vaultFromApi.liquidApr * 100).toFixed(2), + symbol: vault.symbol, + rewardTokens: [vault.underlyingAsset], + underlyingTokens: [vault.underlyingAsset], + url: `https://umami.finance/vaults/${vault.id}`, + }); + }) + ); + + return vaults; +}; + +module.exports = { + getUmamiGlpVaultsYield, +};