From f78a84ffe256c83bb9791963db1e44da5c4956af Mon Sep 17 00:00:00 2001 From: William Liu Date: Sun, 24 Dec 2023 05:28:15 +0000 Subject: [PATCH] feat: add trading apy --- data/constants.js | 1 + data/mainnet/pools.js | 24 + src/lib/constants.js | 3 + src/lib/third-party/wombat.js | 47 +- src/lib/web3/contracts/index.js | 14 + .../web3/contracts/wombat-asset/contract.json | 697 +++++++++ .../web3/contracts/wombat-asset/methods.js | 5 + .../contracts/wombat-fee-pool/contract.json | 1338 +++++++++++++++++ .../web3/contracts/wombat-fee-pool/methods.js | 6 + .../trading-apys/implementations/magpie.js | 46 + 10 files changed, 2169 insertions(+), 12 deletions(-) create mode 100644 src/lib/web3/contracts/wombat-asset/contract.json create mode 100644 src/lib/web3/contracts/wombat-asset/methods.js create mode 100644 src/lib/web3/contracts/wombat-fee-pool/contract.json create mode 100644 src/lib/web3/contracts/wombat-fee-pool/methods.js create mode 100644 src/vaults/trading-apys/implementations/magpie.js diff --git a/data/constants.js b/data/constants.js index 692ab8a..8735ce5 100644 --- a/data/constants.js +++ b/data/constants.js @@ -126,6 +126,7 @@ const TRADING_APY_TYPES = { CAMELOT: 'CAMELOT', BASESWAP: 'BASESWAP', CURVE_BASE: 'CURVE_BASE', + MAGPIE: 'MAGPIE', } const POOL_TYPES = { diff --git a/data/mainnet/pools.js b/data/mainnet/pools.js index b8b15c4..c33104e 100644 --- a/data/mainnet/pools.js +++ b/data/mainnet/pools.js @@ -52,6 +52,10 @@ module.exports = [ chain: CHAIN_IDS.ARBITRUM_ONE, id: 'magpie_DAI_main', type: POOL_TYPES.INCENTIVE, + tradingApyFunction: { + type: TRADING_APY_TYPES.MAGPIE, + params: [addresses.ARBITRUM_ONE.V2.magpie_DAI_main.Underlying], + }, contractAddress: addresses.ARBITRUM_ONE.V2.magpie_DAI_main.NewPool, collateralAddress: addresses.ARBITRUM_ONE.V2.magpie_DAI_main.NewVault, rewardAPY: [], @@ -74,6 +78,10 @@ module.exports = [ chain: CHAIN_IDS.ARBITRUM_ONE, id: 'magpie_ETH_frxeth', type: POOL_TYPES.INCENTIVE, + tradingApyFunction: { + type: TRADING_APY_TYPES.MAGPIE, + params: [addresses.ARBITRUM_ONE.V2.magpie_ETH_frxeth.Underlying], + }, contractAddress: addresses.ARBITRUM_ONE.V2.magpie_ETH_frxeth.NewPool, collateralAddress: addresses.ARBITRUM_ONE.V2.magpie_ETH_frxeth.NewVault, rewardAPY: [], @@ -96,6 +104,10 @@ module.exports = [ chain: CHAIN_IDS.ARBITRUM_ONE, id: 'magpie_USDCe_main', type: POOL_TYPES.INCENTIVE, + tradingApyFunction: { + type: TRADING_APY_TYPES.MAGPIE, + params: [addresses.ARBITRUM_ONE.V2.magpie_USDCe_main.Underlying], + }, contractAddress: addresses.ARBITRUM_ONE.V2.magpie_USDCe_main.NewPool, collateralAddress: addresses.ARBITRUM_ONE.V2.magpie_USDCe_main.NewVault, rewardAPY: [], @@ -118,6 +130,10 @@ module.exports = [ chain: CHAIN_IDS.ARBITRUM_ONE, id: 'magpie_USDC_main', type: POOL_TYPES.INCENTIVE, + tradingApyFunction: { + type: TRADING_APY_TYPES.MAGPIE, + params: [addresses.ARBITRUM_ONE.V2.magpie_USDC_main.Underlying], + }, contractAddress: addresses.ARBITRUM_ONE.V2.magpie_USDC_main.NewPool, collateralAddress: addresses.ARBITRUM_ONE.V2.magpie_USDC_main.NewVault, rewardAPY: [], @@ -140,6 +156,10 @@ module.exports = [ chain: CHAIN_IDS.ARBITRUM_ONE, id: 'magpie_USDT_main', type: POOL_TYPES.INCENTIVE, + tradingApyFunction: { + type: TRADING_APY_TYPES.MAGPIE, + params: [addresses.ARBITRUM_ONE.V2.magpie_USDT_main.Underlying], + }, contractAddress: addresses.ARBITRUM_ONE.V2.magpie_USDT_main.NewPool, collateralAddress: addresses.ARBITRUM_ONE.V2.magpie_USDT_main.NewVault, rewardAPY: [], @@ -162,6 +182,10 @@ module.exports = [ chain: CHAIN_IDS.ARBITRUM_ONE, id: 'magpie_WOM_mwom', type: POOL_TYPES.INCENTIVE, + tradingApyFunction: { + type: TRADING_APY_TYPES.MAGPIE, + params: [addresses.ARBITRUM_ONE.V2.magpie_WOM_mwom.Underlying], + }, contractAddress: addresses.ARBITRUM_ONE.V2.magpie_WOM_mwom.NewPool, collateralAddress: addresses.ARBITRUM_ONE.V2.magpie_WOM_mwom.NewVault, rewardAPY: [], diff --git a/src/lib/constants.js b/src/lib/constants.js index f7a5627..1ac578f 100644 --- a/src/lib/constants.js +++ b/src/lib/constants.js @@ -193,6 +193,8 @@ const APE_API_URL = 'https://ape-swap-api.herokuapp.com' const WOMBAT_ARB_SUBGRAPH_URL = 'https://api.thegraph.com/subgraphs/name/wombat-exchange/wombat-exchange-arbone' +const WOMBAT_ARB_ONE_BLOCK_URL = + 'https://api.thegraph.com/subgraphs/name/wombat-exchange/arbitrum-one-block' const BALANCER_SUBGRAPH_URLS = { ETH: 'https://api.thegraph.com/subgraphs/name/balancer-labs/balancer-v2', @@ -302,4 +304,5 @@ module.exports = { DEXSCREENER_API_URL, CURVE_FINANCE_API_URL, WOMBAT_ARB_SUBGRAPH_URL, + WOMBAT_ARB_ONE_BLOCK_URL, } diff --git a/src/lib/third-party/wombat.js b/src/lib/third-party/wombat.js index 2ed5990..a22824b 100644 --- a/src/lib/third-party/wombat.js +++ b/src/lib/third-party/wombat.js @@ -1,12 +1,17 @@ const { get } = require('lodash') const { cachedAxios } = require('../db/models/cache') -const { WOMBAT_ARB_SUBGRAPH_URL } = require('../constants') +const { WOMBAT_ARB_SUBGRAPH_URL, WOMBAT_ARB_ONE_BLOCK_URL } = require('../constants') -const executeWombatCall = (type, query) => { +const executeWombatCall = (url, type, query) => { return cachedAxios - .post(WOMBAT_ARB_SUBGRAPH_URL, JSON.stringify({ query })) + .post(url, JSON.stringify({ query })) .then(response => { - const data = get(response, `data.data.${type}`) + let data + if (type) { + data = get(response, `data.data.${type}`) + } else { + data = get(response, `data.data`) + } if (data) { return data } else { @@ -20,17 +25,35 @@ const executeWombatCall = (type, query) => { }) } -const getWomAprSubgraph = async underlyingAddr => { - const womAPRQuery = `query { - assets (where: {id: "${underlyingAddr.toLowerCase()}"}) { - avgBoostedApr, - coverageRatio +const getBlockNumArb = async timestamp => { + const blockQuery = `query { + blocks (first: 1, orderBy: timestamp, orderDirection:desc where:{timestamp_lte:${timestamp}}) { + number }}` - const aprInfo = await executeWombatCall('assets[0]', womAPRQuery) - return { apr: aprInfo.avgBoostedApr, ratio: aprInfo.coverageRatio } + const blockInfo = await executeWombatCall(WOMBAT_ARB_ONE_BLOCK_URL, 'blocks[0]', blockQuery) + return blockInfo.number +} + +const getTradingVolumeDaily = async (underlyingAddr, blockNum) => { + const tradingVolQuery = `query { + assetsNow:assets (where: {id: "${underlyingAddr.toLowerCase()}"}) { + totalTradeVolumeUSD, + tvlUSD + } + assets24hAgo: assets(where: {id: "${underlyingAddr.toLowerCase()}"} block:{number:${blockNum}}){ + totalTradeVolumeUSD + } + }` + + const tradingVolInfo = await executeWombatCall(WOMBAT_ARB_SUBGRAPH_URL, null, tradingVolQuery) + const dailyTradingVol = + parseFloat(tradingVolInfo.assetsNow[0].totalTradeVolumeUSD) - + parseFloat(tradingVolInfo.assets24hAgo[0].totalTradeVolumeUSD) + return { dailyTradingVol, tvlUSD: parseFloat(tradingVolInfo.assetsNow[0].tvlUSD) } } module.exports = { - getWomAprSubgraph, + getTradingVolumeDaily, + getBlockNumArb, } diff --git a/src/lib/web3/contracts/index.js b/src/lib/web3/contracts/index.js index e2aa533..7e077c4 100644 --- a/src/lib/web3/contracts/index.js +++ b/src/lib/web3/contracts/index.js @@ -115,6 +115,12 @@ const wombatStakingContract = require('../contracts/wombat-staking/contract.json const wombatMasterMethods = require('../contracts/wom-master/methods') const wombatMasterContract = require('../contracts/wom-master/contract.json') +const wombatAssetMethods = require('../contracts/wombat-asset/methods') +const wombatAssetContract = require('../contracts/wombat-asset/contract.json') + +const wombatFeePoolMethods = require('../contracts/wombat-fee-pool/methods') +const wombatFeePoolContract = require('../contracts/wombat-fee-pool/contract.json') + const lodestarCTokenMethods = require('../contracts/lodestar-ctoken/methods') const lodestarCTokenContract = require('../contracts/lodestar-ctoken/contract.json') @@ -286,4 +292,12 @@ module.exports = { contract: wombatMasterContract, methods: wombatMasterMethods, }, + wombatAsset: { + contract: wombatAssetContract, + methods: wombatAssetMethods, + }, + wombatFeePool: { + contract: wombatFeePoolContract, + methods: wombatFeePoolMethods, + }, } diff --git a/src/lib/web3/contracts/wombat-asset/contract.json b/src/lib/web3/contracts/wombat-asset/contract.json new file mode 100644 index 0000000..cf232bc --- /dev/null +++ b/src/lib/web3/contracts/wombat-asset/contract.json @@ -0,0 +1,697 @@ +{ + "address": { + "ropsten": "", + "mainnet": "" + }, + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "underlyingToken_", + "type": "address" + }, + { + "internalType": "string", + "name": "name_", + "type": "string" + }, + { + "internalType": "string", + "name": "symbol_", + "type": "string" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "ASSET_OVERFLOW", + "type": "error" + }, + { + "inputs": [], + "name": "WOMBAT_FORBIDDEN", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "previousMaxSupply", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newMaxSupply", + "type": "uint256" + } + ], + "name": "SetMaxSupply", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousPoolAddr", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newPoolAddr", + "type": "address" + } + ], + "name": "SetPool", + "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": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "inputs": [], + "name": "DOMAIN_SEPARATOR", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "addCash", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "addLiability", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "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": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "burn", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "cash", + "outputs": [ + { + "internalType": "uint120", + "name": "", + "type": "uint120" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "subtractedValue", + "type": "uint256" + } + ], + "name": "decreaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "addedValue", + "type": "uint256" + } + ], + "name": "increaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "liability", + "outputs": [ + { + "internalType": "uint120", + "name": "", + "type": "uint120" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "maxSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "mint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "nonces", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "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": "pool", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "removeCash", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "removeLiability", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "maxSupply_", + "type": "uint256" + } + ], + "name": "setMaxSupply", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "pool_", + "type": "address" + } + ], + "name": "setPool", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "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": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transferUnderlyingToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "underlyingToken", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "underlyingTokenBalance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "underlyingTokenDecimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + } + ] +} \ No newline at end of file diff --git a/src/lib/web3/contracts/wombat-asset/methods.js b/src/lib/web3/contracts/wombat-asset/methods.js new file mode 100644 index 0000000..f6634a8 --- /dev/null +++ b/src/lib/web3/contracts/wombat-asset/methods.js @@ -0,0 +1,5 @@ +const { countFunctionCall } = require('../..') + +const getPool = instance => countFunctionCall(instance.methods.pool().call()) + +module.exports = { getPool } diff --git a/src/lib/web3/contracts/wombat-fee-pool/contract.json b/src/lib/web3/contracts/wombat-fee-pool/contract.json new file mode 100644 index 0000000..778caa6 --- /dev/null +++ b/src/lib/web3/contracts/wombat-fee-pool/contract.json @@ -0,0 +1,1338 @@ +{ + "address": { + "ropsten": "", + "mainnet": "" + }, + "abi": [ + { + "inputs": [], + "name": "CORE_UNDERFLOW", + "type": "error" + }, + { + "inputs": [], + "name": "WOMBAT_AMOUNT_TOO_LOW", + "type": "error" + }, + { + "inputs": [], + "name": "WOMBAT_ASSET_ALREADY_EXIST", + "type": "error" + }, + { + "inputs": [], + "name": "WOMBAT_ASSET_ALREADY_PAUSED", + "type": "error" + }, + { + "inputs": [], + "name": "WOMBAT_ASSET_NOT_EXISTS", + "type": "error" + }, + { + "inputs": [], + "name": "WOMBAT_ASSET_NOT_PAUSED", + "type": "error" + }, + { + "inputs": [], + "name": "WOMBAT_CASH_NOT_ENOUGH", + "type": "error" + }, + { + "inputs": [], + "name": "WOMBAT_COV_RATIO_LIMIT_EXCEEDED", + "type": "error" + }, + { + "inputs": [], + "name": "WOMBAT_EXPIRED", + "type": "error" + }, + { + "inputs": [], + "name": "WOMBAT_FORBIDDEN", + "type": "error" + }, + { + "inputs": [], + "name": "WOMBAT_INVALID_VALUE", + "type": "error" + }, + { + "inputs": [], + "name": "WOMBAT_SAME_ADDRESS", + "type": "error" + }, + { + "inputs": [], + "name": "WOMBAT_ZERO_ADDRESS", + "type": "error" + }, + { + "inputs": [], + "name": "WOMBAT_ZERO_AMOUNT", + "type": "error" + }, + { + "inputs": [], + "name": "WOMBAT_ZERO_LIQUIDITY", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "asset", + "type": "address" + } + ], + "name": "AssetAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "asset", + "type": "address" + } + ], + "name": "AssetRemoved", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "liquidity", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "Deposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "FillPool", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "Paused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "PausedAsset", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "SetAmpFactor", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "addr", + "type": "address" + } + ], + "name": "SetDev", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "lpDividendRatio", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "retentionRatio", + "type": "uint256" + } + ], + "name": "SetFee", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "addr", + "type": "address" + } + ], + "name": "SetFeeTo", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "SetHaircutRate", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "addr", + "type": "address" + } + ], + "name": "SetMasterWombat", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "SetMintFeeThreshold", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "fromToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "toToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "fromAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "toAmount", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "Swap", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "TransferTipBucket", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "Unpaused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "UnpausedAsset", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "liquidity", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "Withdraw", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "address", + "name": "asset", + "type": "address" + } + ], + "name": "addAsset", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "addressOfAsset", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "ampFactor", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "minimumLiquidity", + "type": "uint256" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "shouldStake", + "type": "bool" + } + ], + "name": "deposit", + "outputs": [ + { + "internalType": "uint256", + "name": "liquidity", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "dev", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "endCovRatio", + "outputs": [ + { + "internalType": "uint128", + "name": "", + "type": "uint128" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "exchangeRate", + "outputs": [ + { + "internalType": "uint256", + "name": "xr", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "feeTo", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "fillPool", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "getTokens", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "globalEquilCovRatio", + "outputs": [ + { + "internalType": "uint256", + "name": "equilCovRatio", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "invariantInUint", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "haircutRate", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "ampFactor_", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "haircutRate_", + "type": "uint256" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "lpDividendRatio", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "masterWombat", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "mintFee", + "outputs": [ + { + "internalType": "uint256", + "name": "feeCollected", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "mintFeeThreshold", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "pauseAsset", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "paused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "fromToken", + "type": "address" + }, + { + "internalType": "address", + "name": "toToken", + "type": "address" + }, + { + "internalType": "int256", + "name": "toAmount", + "type": "int256" + } + ], + "name": "quoteAmountIn", + "outputs": [ + { + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "haircut", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "quotePotentialDeposit", + "outputs": [ + { + "internalType": "uint256", + "name": "liquidity", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reward", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "fromToken", + "type": "address" + }, + { + "internalType": "address", + "name": "toToken", + "type": "address" + }, + { + "internalType": "int256", + "name": "fromAmount", + "type": "int256" + } + ], + "name": "quotePotentialSwap", + "outputs": [ + { + "internalType": "uint256", + "name": "potentialOutcome", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "haircut", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "liquidity", + "type": "uint256" + } + ], + "name": "quotePotentialWithdraw", + "outputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "fee", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "fromToken", + "type": "address" + }, + { + "internalType": "address", + "name": "toToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "liquidity", + "type": "uint256" + } + ], + "name": "quotePotentialWithdrawFromOtherAsset", + "outputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "withdrewAmount", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "removeAsset", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "retentionRatio", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "ampFactor_", + "type": "uint256" + } + ], + "name": "setAmpFactor", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint128", + "name": "startCovRatio_", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "endCovRatio_", + "type": "uint128" + } + ], + "name": "setCovRatioFeeParam", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "dev_", + "type": "address" + } + ], + "name": "setDev", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "lpDividendRatio_", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "retentionRatio_", + "type": "uint256" + } + ], + "name": "setFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "feeTo_", + "type": "address" + } + ], + "name": "setFeeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "haircutRate_", + "type": "uint256" + } + ], + "name": "setHaircutRate", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "masterWombat_", + "type": "address" + } + ], + "name": "setMasterWombat", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "mintFeeThreshold_", + "type": "uint256" + } + ], + "name": "setMintFeeThreshold", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "startCovRatio", + "outputs": [ + { + "internalType": "uint128", + "name": "", + "type": "uint128" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "fromToken", + "type": "address" + }, + { + "internalType": "address", + "name": "toToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "fromAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "minimumToAmount", + "type": "uint256" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "name": "swap", + "outputs": [ + { + "internalType": "uint256", + "name": "actualToAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "haircut", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "tipBucketBalance", + "outputs": [ + { + "internalType": "uint256", + "name": "balance", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "transferTipBucket", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "unpause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "unpauseAsset", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "liquidity", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "minimumAmount", + "type": "uint256" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "name": "withdraw", + "outputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "fromToken", + "type": "address" + }, + { + "internalType": "address", + "name": "toToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "liquidity", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "minimumAmount", + "type": "uint256" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "name": "withdrawFromOtherAsset", + "outputs": [ + { + "internalType": "uint256", + "name": "toAmount", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } + ] +} \ No newline at end of file diff --git a/src/lib/web3/contracts/wombat-fee-pool/methods.js b/src/lib/web3/contracts/wombat-fee-pool/methods.js new file mode 100644 index 0000000..06ac82b --- /dev/null +++ b/src/lib/web3/contracts/wombat-fee-pool/methods.js @@ -0,0 +1,6 @@ +const { countFunctionCall } = require('../..') + +const getHaircutRate = instance => countFunctionCall(instance.methods.haircutRate().call()) + +const getLpDividendRatio = instance => countFunctionCall(instance.methods.lpDividendRatio().call()) +module.exports = { getHaircutRate, getLpDividendRatio } diff --git a/src/vaults/trading-apys/implementations/magpie.js b/src/vaults/trading-apys/implementations/magpie.js new file mode 100644 index 0000000..5dafd7e --- /dev/null +++ b/src/vaults/trading-apys/implementations/magpie.js @@ -0,0 +1,46 @@ +const BigNumber = require('bignumber.js') +const { wombatAsset, wombatFeePool } = require('../../../lib/web3/contracts') +const { web3ARBITRUM } = require('../../../lib/web3') +const { getTradingVolumeDaily, getBlockNumArb } = require('../../../lib/third-party/wombat') + +const getTradingApy = async lpAddress => { + let apy = 0 + const web3 = web3ARBITRUM + const { + contract: { abi: wombatAssetAbi }, + methods: wombatAssetgMethods, + } = wombatAsset + + const { + contract: { abi: wombatFeePoolAbi }, + methods: wombatFeePoolMethods, + } = wombatFeePool + + const currentDate = new Date() + const timestamp = currentDate.getTime() + + const timestamp24hAgo = Math.floor(timestamp / 1000) - 86400 + const blockNum = await getBlockNumArb(timestamp24hAgo) + const womTradeData = await getTradingVolumeDaily(lpAddress.toLowerCase(), blockNum) + + const wombatAssetInstance = new web3.eth.Contract(wombatAssetAbi, lpAddress.toLowerCase()) + const feePoolAddr = await wombatAssetgMethods.getPool(wombatAssetInstance) + + const wombatFeePoolInstance = new web3.eth.Contract(wombatFeePoolAbi, feePoolAddr) + const haircut = new BigNumber( + await wombatFeePoolMethods.getHaircutRate(wombatFeePoolInstance), + ).div(1e18) + const lpDividendRatio = new BigNumber( + await wombatFeePoolMethods.getLpDividendRatio(wombatFeePoolInstance), + ).div(1e18) + + apy = + (womTradeData.dailyTradingVol * parseFloat(haircut) * parseFloat(lpDividendRatio) * 365 * 100) / + (womTradeData.tvlUSD * 2) + + return apy.toFixed(2, 1) +} + +module.exports = { + getTradingApy, +}