diff --git a/abis/read/compound.json b/abis/read/compound.json new file mode 100644 index 0000000..3a67963 --- /dev/null +++ b/abis/read/compound.json @@ -0,0 +1,250 @@ +[{ + "inputs": [], + "name": "getCETHAddress", + "outputs": [{ + "internalType": "address", + "name": "", + "type": "address" + }], + "stateMutability": "pure", + "type": "function" +}, { + "inputs": [], + "name": "getCompReadAddress", + "outputs": [{ + "internalType": "address", + "name": "", + "type": "address" + }], + "stateMutability": "pure", + "type": "function" +}, { + "inputs": [], + "name": "getCompToken", + "outputs": [{ + "internalType": "contract TokenInterface", + "name": "", + "type": "address" + }], + "stateMutability": "pure", + "type": "function" +}, { + "inputs": [{ + "internalType": "address", + "name": "owner", + "type": "address" + }, { + "internalType": "address[]", + "name": "cAddress", + "type": "address[]" + }], + "name": "getCompoundData", + "outputs": [{ + "components": [{ + "internalType": "uint256", + "name": "tokenPriceInEth", + "type": "uint256" + }, { + "internalType": "uint256", + "name": "tokenPriceInUsd", + "type": "uint256" + }, { + "internalType": "uint256", + "name": "exchangeRateStored", + "type": "uint256" + }, { + "internalType": "uint256", + "name": "balanceOfUser", + "type": "uint256" + }, { + "internalType": "uint256", + "name": "borrowBalanceStoredUser", + "type": "uint256" + }, { + "internalType": "uint256", + "name": "totalBorrows", + "type": "uint256" + }, { + "internalType": "uint256", + "name": "totalSupplied", + "type": "uint256" + }, { + "internalType": "uint256", + "name": "borrowCap", + "type": "uint256" + }, { + "internalType": "uint256", + "name": "supplyRatePerBlock", + "type": "uint256" + }, { + "internalType": "uint256", + "name": "borrowRatePerBlock", + "type": "uint256" + }, { + "internalType": "uint256", + "name": "collateralFactor", + "type": "uint256" + }, { + "internalType": "uint256", + "name": "compSpeed", + "type": "uint256" + }, { + "internalType": "bool", + "name": "isComped", + "type": "bool" + }, { + "internalType": "bool", + "name": "isBorrowPaused", + "type": "bool" + }], + "internalType": "struct Helpers.CompData[]", + "name": "", + "type": "tuple[]" + }], + "stateMutability": "view", + "type": "function" +}, { + "inputs": [], + "name": "getComptroller", + "outputs": [{ + "internalType": "contract ComptrollerLensInterface", + "name": "", + "type": "address" + }], + "stateMutability": "pure", + "type": "function" +}, { + "inputs": [], + "name": "getOracleAddress", + "outputs": [{ + "internalType": "address", + "name": "", + "type": "address" + }], + "stateMutability": "view", + "type": "function" +}, { + "inputs": [{ + "internalType": "address", + "name": "owner", + "type": "address" + }, { + "internalType": "address[]", + "name": "cAddress", + "type": "address[]" + }], + "name": "getPosition", + "outputs": [{ + "components": [{ + "internalType": "uint256", + "name": "tokenPriceInEth", + "type": "uint256" + }, { + "internalType": "uint256", + "name": "tokenPriceInUsd", + "type": "uint256" + }, { + "internalType": "uint256", + "name": "exchangeRateStored", + "type": "uint256" + }, { + "internalType": "uint256", + "name": "balanceOfUser", + "type": "uint256" + }, { + "internalType": "uint256", + "name": "borrowBalanceStoredUser", + "type": "uint256" + }, { + "internalType": "uint256", + "name": "totalBorrows", + "type": "uint256" + }, { + "internalType": "uint256", + "name": "totalSupplied", + "type": "uint256" + }, { + "internalType": "uint256", + "name": "borrowCap", + "type": "uint256" + }, { + "internalType": "uint256", + "name": "supplyRatePerBlock", + "type": "uint256" + }, { + "internalType": "uint256", + "name": "borrowRatePerBlock", + "type": "uint256" + }, { + "internalType": "uint256", + "name": "collateralFactor", + "type": "uint256" + }, { + "internalType": "uint256", + "name": "compSpeed", + "type": "uint256" + }, { + "internalType": "bool", + "name": "isComped", + "type": "bool" + }, { + "internalType": "bool", + "name": "isBorrowPaused", + "type": "bool" + }], + "internalType": "struct Helpers.CompData[]", + "name": "", + "type": "tuple[]" + }, { + "components": [{ + "internalType": "uint256", + "name": "balance", + "type": "uint256" + }, { + "internalType": "uint256", + "name": "votes", + "type": "uint256" + }, { + "internalType": "address", + "name": "delegate", + "type": "address" + }, { + "internalType": "uint256", + "name": "allocated", + "type": "uint256" + }], + "internalType": "struct CompReadInterface.CompBalanceMetadataExt", + "name": "", + "type": "tuple" + }], + "stateMutability": "nonpayable", + "type": "function" +}, { + "inputs": [{ + "internalType": "contract CTokenInterface", + "name": "cToken", + "type": "address" + }], + "name": "getPriceInEth", + "outputs": [{ + "internalType": "uint256", + "name": "priceInETH", + "type": "uint256" + }, { + "internalType": "uint256", + "name": "priceInUSD", + "type": "uint256" + }], + "stateMutability": "view", + "type": "function" +}, { + "inputs": [], + "name": "name", + "outputs": [{ + "internalType": "string", + "name": "", + "type": "string" + }], + "stateMutability": "view", + "type": "function" +}] \ No newline at end of file diff --git a/abis/read/maker.json b/abis/read/maker.json new file mode 100644 index 0000000..f33369c --- /dev/null +++ b/abis/read/maker.json @@ -0,0 +1 @@ +[{"inputs":[{"internalType":"string[]","name":"name","type":"string[]"}],"name":"getColInfo","outputs":[{"components":[{"internalType":"uint256","name":"borrowRate","type":"uint256"},{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"uint256","name":"liquidationRatio","type":"uint256"},{"internalType":"uint256","name":"vaultDebtCelling","type":"uint256"},{"internalType":"uint256","name":"vaultDebtFloor","type":"uint256"},{"internalType":"uint256","name":"vaultTotalDebt","type":"uint256"},{"internalType":"uint256","name":"totalDebtCelling","type":"uint256"},{"internalType":"uint256","name":"TotalDebt","type":"uint256"}],"internalType":"struct Helpers.ColInfo[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"getDaiPosition","outputs":[{"internalType":"uint256","name":"amt","type":"uint256"},{"internalType":"uint256","name":"dsr","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getDsrRate","outputs":[{"internalType":"uint256","name":"dsr","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getMcdAddresses","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"getVaultById","outputs":[{"components":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"address","name":"owner","type":"address"},{"internalType":"string","name":"colType","type":"string"},{"internalType":"uint256","name":"collateral","type":"uint256"},{"internalType":"uint256","name":"art","type":"uint256"},{"internalType":"uint256","name":"debt","type":"uint256"},{"internalType":"uint256","name":"liquidatedCol","type":"uint256"},{"internalType":"uint256","name":"borrowRate","type":"uint256"},{"internalType":"uint256","name":"colPrice","type":"uint256"},{"internalType":"uint256","name":"liquidationRatio","type":"uint256"},{"internalType":"address","name":"vaultAddress","type":"address"}],"internalType":"struct Helpers.VaultData","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"getVaults","outputs":[{"components":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"address","name":"owner","type":"address"},{"internalType":"string","name":"colType","type":"string"},{"internalType":"uint256","name":"collateral","type":"uint256"},{"internalType":"uint256","name":"art","type":"uint256"},{"internalType":"uint256","name":"debt","type":"uint256"},{"internalType":"uint256","name":"liquidatedCol","type":"uint256"},{"internalType":"uint256","name":"borrowRate","type":"uint256"},{"internalType":"uint256","name":"colPrice","type":"uint256"},{"internalType":"uint256","name":"liquidationRatio","type":"uint256"},{"internalType":"address","name":"vaultAddress","type":"address"}],"internalType":"struct Helpers.VaultData[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"}] \ No newline at end of file diff --git a/components/CardAave.vue b/components/protocols/CardAave.vue similarity index 100% rename from components/CardAave.vue rename to components/protocols/CardAave.vue diff --git a/components/protocols/CardCompound.vue b/components/protocols/CardCompound.vue new file mode 100644 index 0000000..29e40da --- /dev/null +++ b/components/protocols/CardCompound.vue @@ -0,0 +1,224 @@ + + + + + + + + + + {{ formatUsd(supplyUsd) }} + + + {{ formatDecimal(supply) }} {{ symbol }} + + + + + + + {{ formatUsd(borrowUsd) }} + + + {{ formatDecimal(borrow) }} {{ symbol }} + + + + + + No Position + Supplied + Borrowed + C.F: {{ cf }} + + + + + + + + + + {{ formatPercent(supplyRate) }} + + + + Supply + + + + + + {{ formatPercent(borrowRate) }} + + + + Borrow + + + + + + + + Supply + + + Borrow + + + + + + Supply + + + Withdraw + + + + + + Borrow + + + Payback + + + + + + + diff --git a/composables/useCompoundPosition.ts b/composables/useCompoundPosition.ts new file mode 100644 index 0000000..2a11d20 --- /dev/null +++ b/composables/useCompoundPosition.ts @@ -0,0 +1,500 @@ +import { AbiItem } from "web3-utils"; + +import compoundABI from "~/abis/read/compound.json"; +import { computed, ref, watch } from "@nuxtjs/composition-api"; +import { useDSA } from "./useDSA"; +import { useWeb3 } from "./useWeb3"; +import BigNumber from "bignumber.js"; +import tokens from "~/constant/tokens"; +import { Network } from "./useNetwork"; +import { useBigNumber } from "./useBigNumber"; +import { usePosition } from "./usePosition"; +import { useToken } from "./useToken"; +import addresses from "~/constant/addresses"; +import ctokens from "~/constant/ctokens"; +import tokenIdMapping from "~/constant/tokenIdMapping"; + +const { + times, + isZero, + div, + max, + gt, + minus, + ensureValue, + plus +} = useBigNumber(); +const { getType } = usePosition(); + +const position = ref({ + totalSupplyInEth: new BigNumber(0), + totalBorrowInEth: new BigNumber(0), + totalBorrowStableInEth: new BigNumber(0), + totalBorrowVariableInEth: new BigNumber(0), + maxBorrowLimitInEth: new BigNumber(0), + maxBorrowLiquidityLimitInEth: new BigNumber(0), + ethPriceInUsd: "0", + data: [] +}); +const totalSupply = computed(() => + position.value + ? times( + position.value.totalSupplyInEth, + position.value.ethPriceInUsd + ).toFixed() + : 0 +); + +const totalBorrow = computed(() => + position.value + ? times( + position.value.totalBorrowInEth, + position.value.ethPriceInUsd + ).toFixed() + : 0 +); + +const ethPriceInUsd = computed(() => position.value?.ethPriceInUsd); + +const annualPercentageRateTypes = computed(() => [ + { label: "Variable", value: "variable", rateMode: 2 }, + { label: "Stable", value: "stable", rateMode: 1 } +]); + +export function useCompoundPosition( + { overridePosition } = { overridePosition: null } +) { + overridePosition = overridePosition || (pos => pos); + + const { web3, chainId, networkName } = useWeb3(); + const { activeAccount } = useDSA(); + const { getTokenByKey, allATokensV2 } = useToken(); + + const resolver = computed(() => addresses.mainnet.resolver.compound); + + const fetchPosition = async () => { + if (!web3.value) { + return; + } + + if (!activeAccount.value) { + return; + } + + const resolverInstance = new web3.value.eth.Contract( + compoundABI as AbiItem[], + resolver.value + ); + + const tokensArr = ctokens[networkName.value].allTokens.map(a => a.address); + + const compoundRawData = await resolverInstance.methods + .getPosition(activeAccount.value.address, tokensArr) + .call(); + + const newPos = calculateCompoundPosition( + compoundRawData, + networkName.value + ); + + return newPos; + }; + + const refreshPosition = async () => { + position.value = await fetchPosition(); + }; + + watch( + web3, + async val => { + if (val) { + refreshPosition(); + } + }, + { immediate: true } + ); + + watch( + activeAccount, + async val => { + if (val) { + refreshPosition(); + } + }, + { immediate: true } + ); + + const stats = computed(() => + displayPositions.value.reduce( + (stats, { key, supply, borrow, priceInEth, factor, liquidation }) => { + if (key === "eth") { + stats.ethSupplied = supply; + } + + stats.totalSupplyInEth = plus( + stats.totalSupplyInEth, + times(supply, priceInEth) + ).toFixed(); + stats.totalBorrowInEth = plus( + stats.totalBorrowInEth, + times(borrow, priceInEth) + ).toFixed(); + stats.totalMaxBorrowLimitInEth = plus( + stats.totalMaxBorrowLimitInEth, + times(supply, times(priceInEth, factor)) + ).toFixed(); + stats.totalMaxLiquidationLimitInEth = plus( + stats.totalMaxLiquidationLimitInEth, + times(supply, times(priceInEth, liquidation)) + ).toFixed(); + + return stats; + }, + { + totalSupplyInEth: "0", + totalBorrowInEth: "0", + totalMaxBorrowLimitInEth: "0", + totalMaxLiquidationLimitInEth: "0", + ethSupplied: "0" + } + ) + ); + + const rewardTokenPriceInUsd = computed(() => { + return ensureValue( + position.value.data.find(position => position.key === "comp")?.priceInUsd + ); + }); + + const displayPositions = computed(() => { + if (!position.value) { + return []; + } + + return ctokens[networkName.value].allTokens + .flatMap(ctoken => { + const token = getTokenByKey(ctoken.root); + if (!token) { + return []; + } + + const ctokenPosition = position.value.data.find( + x => x.cTokenId === ctoken.id + ); + + const p = getPositionOrDefaultPosition(token, ctokenPosition); + + if (gt(p.supply, "0") && gt(p.borrow, "0")) { + return [ + { ...p, type: "supply" }, + { ...p, type: "borrow" } + ]; + } else { + return [p]; + } + }) + .filter(p => { + if ( + tokenIdMapping.archived.compound.includes(p.tokenId) && + isZero(p.supply) && + isZero(p.borrow) + ) { + return false; + } + return true; + }) + .map(overridePosition); + }); + + function getPositionOrDefaultPosition(token, p) { + if (!p) { + const defaultPosition = { + key: token?.key, + tokenId: `${token?.symbol}-A`, + ctknBalance: "0", + cTokenDecimals: "0", + cf: "0", + supply: "0", + supplyUsd: "0", + supplyRate: "0", + supplyYield: "0", + borrow: "0", + borrowUsd: "0", + borrowRate: "0", + borrowYield: "0", + type: "no", + borrowEnabled: true, + supplyRewardRate: "0", + borrowRewardRate: "0", + priceInUsd: "0" + }; + + return defaultPosition; + } + + return { + key: token?.key, + tokenId: p.cTokenId, + ctknBalance: p.ctknBalance, + cTokenDecimals: p.cTokenDecimals, + cf: p.factor, + supply: p.supply, + supplyUsd: times(p.supply, p.priceInUsd).toFixed(), + supplyRate: p.supplyRate, + supplyYield: p.supplyYield, + borrow: p.borrow, + borrowUsd: times(p.borrow, p.priceInUsd).toFixed(), + borrowRate: p.borrowRate, + borrowYield: p.borrowYield, + borrowEnabled: p.borrowEnabled, + type: getType(p), + supplyRewardRate: times( + p.compSupplyApy, + rewardTokenPriceInUsd.value + ).toFixed(), + borrowRewardRate: times( + p.compBorrowApy, + rewardTokenPriceInUsd.value + ).toFixed(), + priceInUsd: p.priceInUsd + }; + } + + const maxLiquidation = computed(() => { + if (isZero(stats.value.totalSupplyInEth)) return "0"; + + return max( + div( + stats.value.totalMaxLiquidationLimitInEth, + stats.value.totalSupplyInEth + ), + "0" + ).toFixed(); + }); + + const liquidationPrice = computed(() => { + if (isZero(stats.value.ethSupplied)) return "0"; + + return max( + times( + div( + stats.value.totalBorrowInEth, + stats.value.totalMaxLiquidationLimitInEth + ), + ethPriceInUsd.value + ), + "0" + ).toFixed(); + }); + + const status = computed(() => { + if ( + isZero(stats.value.totalSupplyInEth) && + !isZero(stats.value.totalBorrowInEth) + ) + return "1.1"; + if (isZero(stats.value.totalSupplyInEth)) return "0"; + + return max( + div(stats.value.totalBorrowInEth, stats.value.totalSupplyInEth), + "0" + ).toFixed(); + }); + + const liquidation = computed(() => { + if (isZero(stats.value.totalSupplyInEth)) return "0"; + + return max( + div(stats.value.totalMaxBorrowLimitInEth, stats.value.totalSupplyInEth), + "0" + ).toFixed(); + }); + + return { + stats, + displayPositions, + position: position, + fetchPosition, + refreshPosition, + totalSupply, + totalBorrow, + status, + liquidation, + maxLiquidation, + liquidationPrice, + liquidationMaxPrice: ethPriceInUsd, + annualPercentageRateTypes + }; +} + +function calculateCompoundPosition( + res: any[], + network: Network = Network.Mainnet +) { + try { + const newPos = { + totalSupplyInEth: new BigNumber(0), + totalBorrowInEth: new BigNumber(0), + totalBorrowStableInEth: new BigNumber(0), + totalBorrowVariableInEth: new BigNumber(0), + maxBorrowLimitInEth: new BigNumber(0), + maxBorrowLiquidityLimitInEth: new BigNumber(0), + tokens: {}, + data: [] + }; + const dataPos = []; + let ethPrice = "0"; + ctokens[network].allTokens.forEach((ctoken, i) => { + const key = ctoken.address; + const [ + priceInEthInWei, + priceInUsdInWei, + exchangeRateInWei, + cBalanceInWei, + borrowInWei, + totalBorrowsInWei, + totalSuppliedInWei, + borrowCapInWei, + supplyRatePerBlock, + borrowRatePerBlock, + collateralFactorInWei, + compSpeed, + isComped, + isBorrowPaused + ] = res[0][i]; + + const decimals = tokens[network].getTokenByKey(ctoken.root).decimals; + const root = ctoken.root; + + const blocksInYear = 2398050; + + const priceInEth = new BigNumber(priceInEthInWei).dividedBy(1e18); + const priceInUsd = new BigNumber(priceInUsdInWei).dividedBy(1e18); + const exchangeRate = new BigNumber(exchangeRateInWei).dividedBy(1e18); + const supply = new BigNumber(cBalanceInWei) + .multipliedBy(exchangeRate) + .dividedBy(10 ** decimals); + const borrow = new BigNumber(borrowInWei).dividedBy(10 ** decimals); + const supplyRate = new BigNumber(supplyRatePerBlock) + .multipliedBy(blocksInYear) + .dividedBy(1e18); + const supplyYield = supplyRate + .dividedBy(365) + .plus(1) + .exponentiatedBy(365) + .minus(1) + .toFixed(18); + const borrowRate = new BigNumber(borrowRatePerBlock) + .multipliedBy(blocksInYear) + .dividedBy(1e18); + const borrowYield = borrowRate + .dividedBy(365) + .plus(1) + .exponentiatedBy(365) + .minus(1) + .toFixed(18); + const totalBorrow = new BigNumber(totalBorrowsInWei).dividedBy( + 10 ** decimals + ); + const borrowCap = new BigNumber(borrowCapInWei) + .dividedBy(10 ** decimals) + .multipliedBy(0.9999) + .toFixed(); + const collateralFactor = new BigNumber(collateralFactorInWei) + .dividedBy(1e18) + .toFixed(); + const totalSupplied = new BigNumber(totalSuppliedInWei) + .dividedBy(10 ** decimals) + .multipliedBy(priceInUsd); + const compSupplyApy = new BigNumber(compSpeed) + .multipliedBy(blocksInYear) + .dividedBy(1e18) + .dividedBy(totalSupplied) + .toFixed(); + const compBorrowApy = new BigNumber(compSpeed) + .multipliedBy(blocksInYear) + .dividedBy(1e18) + .dividedBy(totalBorrow.multipliedBy(priceInUsd)) + .toFixed(); + + newPos.totalSupplyInEth = newPos.totalSupplyInEth.plus( + supply.multipliedBy(priceInEth) + ); + newPos.maxBorrowLimitInEth = newPos.maxBorrowLimitInEth.plus( + supply.multipliedBy(priceInEth).multipliedBy(ctoken.factor) + ); + newPos.totalBorrowInEth = newPos.totalBorrowInEth.plus( + borrow.multipliedBy(priceInEth) + ); + + if (ctoken.root === "eth") ethPrice = priceInUsd.toFixed(); + dataPos.push({ + key: root, + cTokenAddr: key, + cTokenKey: ctoken.key, + cTokenDecimals: ctoken.decimals.toString(), + cTokenId: ctoken.id, + priceInEth: priceInEth.toFixed(), + priceInUsd: priceInUsd.toFixed(), + exchangeRate: exchangeRate.toFixed(), + ctknBalance: cBalanceInWei, + supply: supply.toFixed(), + borrow: borrow.toFixed(), + supplyRate: supplyRate.toFixed(), + supplyYield, + borrowRate: borrowRate.toFixed(), + borrowYield, + factor: collateralFactor, + totalBorrow: totalBorrow.toFixed(), + borrowCap, + isComped, + borrowEnabled: !isBorrowPaused, + compSupplyApy, + compBorrowApy + }); + }); + + const totalSupplyInEthIsZero = newPos.totalSupplyInEth.isZero(); + const status = totalSupplyInEthIsZero + ? 0 + : newPos.totalBorrowInEth.dividedBy(newPos.totalSupplyInEth).toFixed(); + const liquidation = totalSupplyInEthIsZero + ? 0 + : newPos.maxBorrowLimitInEth.dividedBy(newPos.totalSupplyInEth).toFixed(); + //@ts-ignore + newPos.totalSupplyInEth = newPos.totalSupplyInEth.toFixed(); + //@ts-ignore + newPos.totalBorrowInEth = newPos.totalBorrowInEth.toFixed(); + //@ts-ignore + newPos.maxBorrowLimitInEth = newPos.maxBorrowLimitInEth.toFixed(); + + //@ts-ignore + newPos.status = status; + + //@ts-ignore + newPos.liquidation = liquidation; + + //@ts-ignore + newPos.ethPriceInUsd = ethPrice; + + const comp = res[1]; + //@ts-ignore + newPos.compBalance = new BigNumber(comp.balance).dividedBy(1e18).toFixed(); + + //@ts-ignore + newPos.compAccrued = new BigNumber(comp.allocated) + .dividedBy(1e18) + .toFixed(); + //@ts-ignore + newPos.compDelegate = comp.delegate; + //@ts-ignore + newPos.compVotes = comp.votes; + + newPos.data = dataPos; + + return newPos; + } catch (error) { + console.error(error); + return Promise.reject(error); + } +} diff --git a/constant/tokenIdMapping.ts b/constant/tokenIdMapping.ts new file mode 100644 index 0000000..9ae4195 --- /dev/null +++ b/constant/tokenIdMapping.ts @@ -0,0 +1,38 @@ +const idToToken = { + 'ETH-A': 'eth', + 'BAT-A': 'bat', + 'COMP-A': 'comp', + 'DAI-A': 'dai', + 'REP-A': 'rep', + 'UNI-A': 'uni', + 'USDC-A': 'usdc', + 'USDT-A': 'usdt', + 'WBTC-A': 'wbtc', + 'WBTC-B': 'wbtc', + 'ZRX-A': 'zrx', + 'TUSD-A': 'tusd', + 'LINK-A': 'link', +} + +const tokenToId = { + compound: { + eth: 'ETH-A', + bat: 'BAT-A', + comp: 'COMP-A', + dai: 'DAI-A', + rep: 'REP-A', + uni: 'UNI-A', + usdc: 'USDC-A', + usdt: 'USDT-A', + wbtc: 'WBTC-B', + zrx: 'ZRX-A', + tusd: 'TUSD-A', + link: 'LINK-A', + }, +} + +const archived = { + compound: ['WBTC-A'], +} + +export default { idToToken, tokenToId, archived } diff --git a/pages/index.vue b/pages/index.vue index 040b325..df21656 100644 --- a/pages/index.vue +++ b/pages/index.vue @@ -44,6 +44,20 @@ const appsPerNetwork = { name: "Aave v2", url: "/mainnet/aave-v2", description: "Lend and borrow straight from your Gnosis Safe" + }, + { + id: "compound", + icon: AaveIcon, + name: "Compound", + url: "/mainnet/compound", + description: "Lend and borrow straight from your Gnosis Safe" + }, + { + id: "maker", + icon: AaveIcon, + name: "Maker", + url: "/mainnet/maker", + description: "Lend and borrow straight from your Gnosis Safe" } ], polygon: [ @@ -53,7 +67,7 @@ const appsPerNetwork = { name: "Aave v2", url: "/polygon/aave-v2", description: "Lend and borrow straight from your Gnosis Safe" - }, + } ] }; diff --git a/pages/mainnet/aave-v2.vue b/pages/mainnet/aave-v2.vue index 7a677d2..e77c20b 100644 --- a/pages/mainnet/aave-v2.vue +++ b/pages/mainnet/aave-v2.vue @@ -122,7 +122,7 @@ class="mt-3 grid w-full grid-cols-1 gap-4 sm:grid-cols-2 xxl:gap-6 min-w-max-content px-1" > - + + + + + Apps + + + + + Compound + + + + Overview + + + + + + {{ formatUsd(totalSupply) }} + + Lend + + + + + + + + + + + + + {{ formatUsd(totalBorrow) }} + + Borrowed + + + + + + + + + + + + + + + {{ formatPercent(status) }} + + {{ text }} + + + + D/C (%) + + + + Max - {{ formatPercent(position.maxLiquidation) }} + + + + + + + + + Your Positions + + + + + + + + + + + + + + + diff --git a/pages/polygon/aave-v2.vue b/pages/polygon/aave-v2.vue index 7a677d2..e77c20b 100644 --- a/pages/polygon/aave-v2.vue +++ b/pages/polygon/aave-v2.vue @@ -122,7 +122,7 @@ class="mt-3 grid w-full grid-cols-1 gap-4 sm:grid-cols-2 xxl:gap-6 min-w-max-content px-1" > -
Lend
Borrowed