From cefe8ddb40278a9942dc4c7843e356279a418f62 Mon Sep 17 00:00:00 2001 From: brightiron Date: Thu, 5 Oct 2023 11:31:01 -0500 Subject: [PATCH 01/17] remove zap. remove mention of rebases. --- src/components/TopBar/Wallet/Assets/index.tsx | 8 +- src/hooks/useWarmupInfo.ts | 28 --- src/hooks/useZapExecute.ts | 185 ------------------ .../components/ClaimsArea/ClaimsArea.tsx | 13 +- .../Stake/components/StakeArea/StakeArea.tsx | 21 +- .../components/RebaseTimer/RebaseTimer.scss | 4 - .../components/RebaseTimer/RebaseTimer.tsx | 24 --- .../__tests__/RebaseTimer.unit.test.tsx | 11 -- .../RebaseTimer/hooks/useNextRebaseDate.ts | 25 --- .../components/StakeFiveDayYield.tsx | 16 -- .../StakeInputArea/StakeInputArea.tsx | 138 ++----------- .../components/StakeConfirmationModal.tsx | 54 +---- .../StakeInputArea/components/TokenModal.tsx | 61 +----- .../components/StakeNextRebaseAmount.tsx | 61 ------ .../StakeArea/components/StakeRebaseYield.tsx | 14 -- .../TreasuryDashboard/TreasuryDashboard.tsx | 2 - .../components/Metric/Metric.tsx | 18 -- src/views/V1-Stake/V1-Stake.jsx | 7 +- 18 files changed, 39 insertions(+), 651 deletions(-) delete mode 100644 src/hooks/useZapExecute.ts delete mode 100644 src/views/Stake/components/StakeArea/components/RebaseTimer/RebaseTimer.scss delete mode 100644 src/views/Stake/components/StakeArea/components/RebaseTimer/RebaseTimer.tsx delete mode 100644 src/views/Stake/components/StakeArea/components/RebaseTimer/__tests__/RebaseTimer.unit.test.tsx delete mode 100644 src/views/Stake/components/StakeArea/components/RebaseTimer/hooks/useNextRebaseDate.ts delete mode 100644 src/views/Stake/components/StakeArea/components/StakeFiveDayYield.tsx delete mode 100644 src/views/Stake/components/StakeArea/components/StakeNextRebaseAmount.tsx delete mode 100644 src/views/Stake/components/StakeArea/components/StakeRebaseYield.tsx diff --git a/src/components/TopBar/Wallet/Assets/index.tsx b/src/components/TopBar/Wallet/Assets/index.tsx index 075a3e4dfb..90ff94c7bf 100644 --- a/src/components/TopBar/Wallet/Assets/index.tsx +++ b/src/components/TopBar/Wallet/Assets/index.tsx @@ -10,7 +10,7 @@ import { useFaucet } from "src/components/TopBar/Wallet/hooks/useFaucet"; import { GetTokenPrice } from "src/components/TopBar/Wallet/queries"; import { formatCurrency, formatNumber, isTestnet, trim } from "src/helpers"; import { DecimalBigNumber } from "src/helpers/DecimalBigNumber/DecimalBigNumber"; -import { prettifySeconds, prettifySecondsInDays } from "src/helpers/timeUtil"; +import { prettifySecondsInDays } from "src/helpers/timeUtil"; import { nonNullable } from "src/helpers/types/nonNullable"; import { useFuseBalance, @@ -28,7 +28,6 @@ import { useStakingRebaseRate } from "src/hooks/useStakingRebaseRate"; import { useTestableNetworks } from "src/hooks/useTestableNetworks"; import { NetworkId } from "src/networkDetails"; import { useBondNotes } from "src/views/Bond/components/ClaimBonds/hooks/useBondNotes"; -import { useNextRebaseDate } from "src/views/Stake/components/StakeArea/components/RebaseTimer/hooks/useNextRebaseDate"; import { useNetwork } from "wagmi"; const PREFIX = "AssetsIndex"; @@ -90,7 +89,6 @@ const AssetsIndex: FC = (props: { path?: string }) => { const { data: ohmPrice = 0 } = useOhmPrice(); const { data: priceFeed = { usd_24h_change: -0 } } = GetTokenPrice(); const { data: currentIndex = new DecimalBigNumber("0", 9) } = useCurrentIndex(); - const { data: nextRebaseDate } = useNextRebaseDate(); const { data: rebaseRate = 0 } = useStakingRebaseRate(); const { data: v1OhmBalance = new DecimalBigNumber("0", 9) } = useV1OhmBalance()[networks.MAINNET]; const { data: v1SohmBalance = new DecimalBigNumber("0", 9) } = useV1SohmBalance()[networks.MAINNET]; @@ -161,8 +159,6 @@ const AssetsIndex: FC = (props: { path?: string }) => { { symbol: ["sOHM"] as OHMTokenStackProps["tokens"], balance: formattedSOhmBalance, - timeRemaining: - nextRebaseDate && `Stakes in ${prettifySeconds((nextRebaseDate.getTime() - new Date().getTime()) / 1000)}`, assetValue: sOhmBalance.toApproxNumber() * ohmPrice, alwaysShow: true, lineThreeLabel: "Rebases per day", @@ -172,8 +168,6 @@ const AssetsIndex: FC = (props: { path?: string }) => { symbol: ["sOHM"] as OHMTokenStackProps["tokens"], balance: formattedV1SohmBalance, label: "(v1)", - timeRemaining: - nextRebaseDate && `Stakes in ${prettifySeconds((nextRebaseDate.getTime() - new Date().getTime()) / 1000)}`, assetValue: v1SohmBalance.toApproxNumber() * ohmPrice, }, { diff --git a/src/hooks/useWarmupInfo.ts b/src/hooks/useWarmupInfo.ts index f50a590014..e19f8978c7 100644 --- a/src/hooks/useWarmupInfo.ts +++ b/src/hooks/useWarmupInfo.ts @@ -2,9 +2,7 @@ import { useQuery } from "@tanstack/react-query"; import { BigNumber } from "ethers"; import { NetworkId } from "src/constants"; import { SOHM_CONTRACT, STAKING_CONTRACT } from "src/constants/contracts"; -import { parseBigNumber } from "src/helpers"; import { DecimalBigNumber } from "src/helpers/DecimalBigNumber/DecimalBigNumber"; -import { useNextRebase } from "src/views/Stake/components/StakeArea/components/RebaseTimer/hooks/useNextRebaseDate"; import { useAccount, useNetwork } from "wagmi"; export const warmupQueryKey = (address: string | `0x${string}`, chainId?: number) => [ @@ -53,32 +51,6 @@ export const useWarmupClaim = () => { ); }; -/** - * @returns JS Date for warmup completion for connected wallet - */ -export const useWarmupDate = () => { - const { data: warmupBalance, isSuccess: balanceSuccess } = useWarmupClaim(); - const { data: secondsToRebase, isSuccess: rebaseSuccess } = useNextRebase(); - const { data: epoch, isSuccess: epochSuccess } = useEpoch(); - const isSuccess = rebaseSuccess && balanceSuccess && epochSuccess; - - const parsedSeconds = parseBigNumber(secondsToRebase || BigNumber.from("0"), 0); - const epochLengthSeconds = parseBigNumber(epoch?.length.toBigNumber() || BigNumber.from("0"), 0); - - const warmupExpiry = warmupBalance?.expiry || BigNumber.from("0"); - const currentEpoch = epoch?.number.toBigNumber() || BigNumber.from("0"); - // how many fully length epochs are remaining? - const warmupLength = parseBigNumber(warmupExpiry, 0) - parseBigNumber(currentEpoch, 0) - 1; - - // secondsRemainingInThisEpoch + (epochLenghInSeconds * numberOfEpochsInWarmup) - const dateTime = new Date(Date.now() + (parsedSeconds + epochLengthSeconds * warmupLength) * 1000); - - return { - data: isSuccess ? dateTime : undefined, - isClaimable: isSuccess ? currentEpoch.gte(warmupExpiry) : undefined, - }; -}; - /** * warmupPeriod in # of epochs */ diff --git a/src/hooks/useZapExecute.ts b/src/hooks/useZapExecute.ts deleted file mode 100644 index 75d9eeaf19..0000000000 --- a/src/hooks/useZapExecute.ts +++ /dev/null @@ -1,185 +0,0 @@ -import { useMutation, useQueryClient } from "@tanstack/react-query"; -import { BigNumber, ContractReceipt, ethers } from "ethers"; -import toast from "react-hot-toast"; -import { NetworkId } from "src/constants"; -import { DAO_TREASURY_ADDRESSES, GOHM_ADDRESSES, ZAP_ADDRESSES } from "src/constants/addresses"; -import { SOHM_ADDRESSES } from "src/constants/addresses"; -import { trackGAEvent } from "src/helpers/analytics/trackGAEvent"; -import { DecimalBigNumber } from "src/helpers/DecimalBigNumber/DecimalBigNumber"; -import { isSupportedChain } from "src/helpers/ZapHelper"; -import { balanceQueryKey } from "src/hooks/useBalance"; -import { warmupQueryKey } from "src/hooks/useWarmupInfo"; -import { zapTokenBalancesKey } from "src/hooks/useZapTokenBalances"; -import { EthersError } from "src/lib/EthersTypes"; -import { Zap__factory } from "src/typechain/factories/Zap__factory"; -import { useAccount, useNetwork, useSigner } from "wagmi"; - -interface ZapTransactionResponse { - to: string; - data: string; - estimatedGas: string; - buyAmount: string; -} - -interface IUADataZap { - address: string; - value: string; - token: string; - type: string; - slippage: string; - approved: boolean; -} - -interface ZapExecuteOptions { - slippage: string; - sellAmount: BigNumber; - tokenAddress: string; - minimumAmount: string; - gOHM: boolean; -} - -export const useZapExecute = () => { - const client = useQueryClient(); - const { data: signer } = useSigner(); - const { address = "" } = useAccount(); - const { chain = { id: 1 } } = useNetwork(); - - return useMutation( - /** - * Ideally the parameters to this async function should be the slippage, etc. - * However the `mutationFn` parameter to `useMutation` accepts a function with - * one parameter only, and it wasn't working when passing an object with a defined interface. - * So the parameters are moved up a level. - */ - async ({ slippage, sellAmount, tokenAddress, minimumAmount, gOHM }) => { - if (!slippage || isNaN(Number(slippage))) throw new Error(`Slippage should be a number`); - - if (!tokenAddress) throw new Error(`The tokenAddress parameter must be set`); - if (!signer) throw new Error(`Signer is not set`); - - const minimumAmountNumber = new DecimalBigNumber(minimumAmount); - if (!minimumAmount || !minimumAmountNumber.gt("0")) throw new Error(`Minimum amount must be greater than 0`); - - if (!isSupportedChain(chain.id)) { - toast.error(`Zaps are only available on Ethereum Mainnet. Please switch networks.`); - throw new Error(`Zaps are only available on Ethereum Mainnet. Please switch networks.`); - } - - // We only operate on Ethereum mainnet for the moment, so we can use a static contract - const contract = Zap__factory.connect(ZAP_ADDRESSES[chain.id as keyof typeof ZAP_ADDRESSES], signer); - if (!contract) throw new Error(`Unable to access Zap contract on network ${chain.id}`); - - const toToken = gOHM - ? GOHM_ADDRESSES[chain.id as keyof typeof GOHM_ADDRESSES] - : SOHM_ADDRESSES[chain.id as keyof typeof SOHM_ADDRESSES]; - if (!toToken) - throw new Error(`Unable to fetch address for token (${gOHM ? "gOHM" : "sOHM"}) on network ${chain.id}`); - - const additionalOptions = { - ...(tokenAddress === ethers.constants.AddressZero && { value: sellAmount }), - }; - - console.debug("Fetching token swap data from Zapper"); - if (!address) throw new Error(`Account is not set`); - const swapData = await fetchSwapData(address, sellAmount, tokenAddress, +slippage / 100); - - console.debug("Commencing Zap"); - const transaction = await contract.ZapStake( - tokenAddress, - sellAmount, - toToken, - ethers.utils.parseUnits(minimumAmount, gOHM ? 18 : 9), - swapData.to, - swapData.data, - address, - additionalOptions, - ); - - console.debug("Awaiting transaction"); - return transaction.wait(); - }, - { - onError: (e, variables) => { - if (!address) throw new Error(`Account is not set`); - const uaData: IUADataZap = { - address, - value: variables.sellAmount.toString(), - token: variables.tokenAddress, - type: "Zap Swap Failure", - slippage: variables.slippage, - approved: false, - }; - trackGAEvent({ - category: "OlyZaps", - action: uaData.type, - metric1: parseFloat(uaData.value), - }); - - console.error(`Encountered error while executing Zap: ${e.message}`); - - if (e.message.indexOf("High Slippage") > 0) { - toast.error(`Transaction would fail due to slippage. Please use a higher slippage tolerance value.`); - } else if (e.message.indexOf("TRANSFER_AMOUNT_EXCEEDS_BALANCE") > 0) { - toast.error(`Insufficient balance.`); - } else { - toast.error("error" in e ? e.error.message : e.message); - } - - /** - * NOTE: Previously, ZapSlice would re-throw the error here. - * Re-throwing within react-query prevents the states (e.g. `isLoading`) - * from being set correctly, so we don't do that. - */ - }, - onSuccess: (_data, variables) => { - console.debug("Zap successful"); - if (!address) throw new Error(`Account is not set`); - const uaData: IUADataZap = { - address, - value: variables.sellAmount.toString(), - token: variables.tokenAddress, - type: "Zap Swap Success", - slippage: variables.slippage, - approved: true, - }; - trackGAEvent({ - category: "OlyZaps", - action: uaData.type, - metric1: parseFloat(uaData.value), - }); - toast.success("Successful Zap!"); - - // We force a refresh of balances, but don't wait on the result - const keysToRefetch = [ - balanceQueryKey(address, SOHM_ADDRESSES, NetworkId.MAINNET), - balanceQueryKey(address, GOHM_ADDRESSES, NetworkId.MAINNET), - warmupQueryKey(address, chain?.id), - zapTokenBalancesKey(address), - ]; - const promises = keysToRefetch.map(key => client.refetchQueries([key], { type: "active" })); - Promise.all(promises); - }, - }, - ); -}; - -const fetchSwapData = async ( - address: string, - sellAmount: BigNumber, - tokenAddress: string, - slippageDecimal: number, -): Promise => { - tokenAddress = tokenAddress.toLowerCase(); - const sellToken = tokenAddress === "0x0000000000000000000000000000000000000000" ? "ETH" : tokenAddress; - const response = await fetch( - `https://api.0x.org/swap/v1/quote?sellToken=${sellToken}&buyToken=0x64aa3364f17a4d01c6f1751fd97c2bd3d7e7f1d5&sellAmount=${sellAmount}&slippagePercentage=${slippageDecimal}&affiliateAddress=${ - DAO_TREASURY_ADDRESSES[NetworkId.MAINNET] - }`, - ); - const responseJson = await response.json(); - if (response.ok) { - return responseJson; - } else { - throw Error(JSON.stringify(responseJson)); - } -}; diff --git a/src/views/Stake/components/ClaimsArea/ClaimsArea.tsx b/src/views/Stake/components/ClaimsArea/ClaimsArea.tsx index 28dfc2c1de..d976fa12c6 100644 --- a/src/views/Stake/components/ClaimsArea/ClaimsArea.tsx +++ b/src/views/Stake/components/ClaimsArea/ClaimsArea.tsx @@ -4,7 +4,7 @@ import { styled } from "@mui/material/styles"; import useMediaQuery from "@mui/material/useMediaQuery"; import { DataRow, InfoTooltip, Paper, PrimaryButton, SecondaryButton, Token } from "@olympusdao/component-library"; import { prettifySeconds } from "src/helpers/timeUtil"; -import { IWarmupBalances, useWarmupClaim, useWarmupDate } from "src/hooks/useWarmupInfo"; +import { IWarmupBalances, useWarmupClaim } from "src/hooks/useWarmupInfo"; import { formatBalance } from "src/views/Stake/components/StakeArea/components/StakeBalances"; import { useClaimToken } from "src/views/Stake/components/StakeArea/components/StakeInputArea/hooks/useClaimToken"; import { useForfeitToken } from "src/views/Stake/components/StakeArea/components/StakeInputArea/hooks/useForfeitToken"; @@ -43,7 +43,7 @@ export const ClaimsArea = () => { const { isConnected } = useAccount(); const isSmallScreen = useMediaQuery("(max-width: 705px)"); const { data: claim } = useWarmupClaim(); - const { data: warmupDate, isClaimable } = useWarmupDate(); + // const { data: warmupDate, isClaimable } = useWarmupDate(); if (!isConnected || !claim || claim?.gohm.eq("0")) return <>; const warmupTooltip = `Your claim earns rebases during warmup. You can emergency withdraw, but this forfeits the rebases`; @@ -60,7 +60,7 @@ export const ClaimsArea = () => { - + ) : ( @@ -75,12 +75,7 @@ export const ClaimsArea = () => { - + )} diff --git a/src/views/Stake/components/StakeArea/StakeArea.tsx b/src/views/Stake/components/StakeArea/StakeArea.tsx index e77a7ecef8..eef8d1796c 100644 --- a/src/views/Stake/components/StakeArea/StakeArea.tsx +++ b/src/views/Stake/components/StakeArea/StakeArea.tsx @@ -1,14 +1,8 @@ import { Box, Divider } from "@mui/material"; -import { Metric, MetricCollection } from "@olympusdao/component-library"; import { useState } from "react"; import PageTitle from "src/components/PageTitle"; -import RebaseTimer from "src/views/Stake/components/StakeArea/components/RebaseTimer/RebaseTimer"; import { StakeBalances } from "src/views/Stake/components/StakeArea/components/StakeBalances"; -import { StakeFiveDayYield } from "src/views/Stake/components/StakeArea/components/StakeFiveDayYield"; import { StakeInputArea } from "src/views/Stake/components/StakeArea/components/StakeInputArea/StakeInputArea"; -import { StakeNextRebaseAmount } from "src/views/Stake/components/StakeArea/components/StakeNextRebaseAmount"; -import { StakeRebaseYield } from "src/views/Stake/components/StakeArea/components/StakeRebaseYield"; -import { CurrentIndex, StakingAPY } from "src/views/TreasuryDashboard/components/Metric/Metric"; import { useAccount } from "wagmi"; export const StakeArea: React.FC = () => { @@ -17,27 +11,14 @@ export const StakeArea: React.FC = () => { return ( <> - + - - - - - } /> - - - - - {isConnected && ( - - - )} diff --git a/src/views/Stake/components/StakeArea/components/RebaseTimer/RebaseTimer.scss b/src/views/Stake/components/StakeArea/components/RebaseTimer/RebaseTimer.scss deleted file mode 100644 index 2d38d25416..0000000000 --- a/src/views/Stake/components/StakeArea/components/RebaseTimer/RebaseTimer.scss +++ /dev/null @@ -1,4 +0,0 @@ -.rebase-timer { - position: relative; - width: max-content; -} diff --git a/src/views/Stake/components/StakeArea/components/RebaseTimer/RebaseTimer.tsx b/src/views/Stake/components/StakeArea/components/RebaseTimer/RebaseTimer.tsx deleted file mode 100644 index 8880fbf369..0000000000 --- a/src/views/Stake/components/StakeArea/components/RebaseTimer/RebaseTimer.tsx +++ /dev/null @@ -1,24 +0,0 @@ -import "src/views/Stake/components/StakeArea/components/RebaseTimer/RebaseTimer.scss"; - -import { Box, Skeleton } from "@mui/material"; -import React from "react"; -import { prettifySeconds } from "src/helpers/timeUtil"; -import { useNextRebaseDate } from "src/views/Stake/components/StakeArea/components/RebaseTimer/hooks/useNextRebaseDate"; - -const RebaseTimer: React.FC = () => { - const { data: nextRebaseDate } = useNextRebaseDate(); - - return ( - - {nextRebaseDate ? ( - <> - {prettifySeconds((nextRebaseDate.getTime() - new Date().getTime()) / 1000)}  - - ) : ( - - )} - - ); -}; - -export default RebaseTimer; diff --git a/src/views/Stake/components/StakeArea/components/RebaseTimer/__tests__/RebaseTimer.unit.test.tsx b/src/views/Stake/components/StakeArea/components/RebaseTimer/__tests__/RebaseTimer.unit.test.tsx deleted file mode 100644 index 5c2bf59012..0000000000 --- a/src/views/Stake/components/StakeArea/components/RebaseTimer/__tests__/RebaseTimer.unit.test.tsx +++ /dev/null @@ -1,11 +0,0 @@ -import RebaseTimer from "src/views/Stake/components/StakeArea/components/RebaseTimer/RebaseTimer"; -import { describe, expect, it, test } from "vitest"; - -describe("", () => { - test("should render component", () => { - it("should render component", () => { - const container = ; - expect(container).toMatchSnapshot(); - }); - }); -}); diff --git a/src/views/Stake/components/StakeArea/components/RebaseTimer/hooks/useNextRebaseDate.ts b/src/views/Stake/components/StakeArea/components/RebaseTimer/hooks/useNextRebaseDate.ts deleted file mode 100644 index f33d4a5800..0000000000 --- a/src/views/Stake/components/StakeArea/components/RebaseTimer/hooks/useNextRebaseDate.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { useQuery } from "@tanstack/react-query"; -import { BigNumber } from "ethers"; -import { NetworkId } from "src/constants"; -import { STAKING_ADDRESSES } from "src/constants/addresses"; -import { parseBigNumber } from "src/helpers"; -import { useStaticStakingContract } from "src/hooks/useContract"; - -export const useNextRebaseDate = () => { - const { data: secondsToRebase, isSuccess } = useNextRebase(); - const parsedSeconds = parseBigNumber(secondsToRebase || BigNumber.from("0"), 0); - const dateTime = new Date(Date.now() + parsedSeconds * 1000); - return { - data: isSuccess ? dateTime : undefined, - }; -}; - -export const useNextRebase = () => { - const contract = useStaticStakingContract(STAKING_ADDRESSES[NetworkId.MAINNET], NetworkId.MAINNET); - - return useQuery(["secondsToNextRebase"], async () => { - const secondsToRebase = await contract.secondsToNextEpoch(); - - return secondsToRebase; - }); -}; diff --git a/src/views/Stake/components/StakeArea/components/StakeFiveDayYield.tsx b/src/views/Stake/components/StakeArea/components/StakeFiveDayYield.tsx deleted file mode 100644 index c920798783..0000000000 --- a/src/views/Stake/components/StakeArea/components/StakeFiveDayYield.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import { DataRow } from "@olympusdao/component-library"; -import { formatNumber } from "src/helpers"; -import { useStakingRebaseRate } from "src/hooks/useStakingRebaseRate"; - -export const StakeFiveDayYield = () => { - const { data: rebaseRate } = useStakingRebaseRate(); - - const props: PropsOf = { title: `Rebases (5-Day Rate)` }; - - if (rebaseRate) { - const fiveDayRate = (Math.pow(1 + rebaseRate, 5 * 3) - 1) * 100; - props.balance = `${formatNumber(fiveDayRate, 4)}%`; - } else props.isLoading = true; - - return ; -}; diff --git a/src/views/Stake/components/StakeArea/components/StakeInputArea/StakeInputArea.tsx b/src/views/Stake/components/StakeArea/components/StakeInputArea/StakeInputArea.tsx index add336d2bc..95fae106c5 100644 --- a/src/views/Stake/components/StakeArea/components/StakeInputArea/StakeInputArea.tsx +++ b/src/views/Stake/components/StakeArea/components/StakeInputArea/StakeInputArea.tsx @@ -7,21 +7,13 @@ import { SwapCard, SwapCollection, } from "@olympusdao/component-library"; -import { parseUnits } from "ethers/lib/utils"; import React, { useEffect, useState } from "react"; import { WalletConnectedGuard } from "src/components/WalletConnectedGuard"; -import { - GOHM_ADDRESSES, - OHM_ADDRESSES, - SOHM_ADDRESSES, - STAKING_ADDRESSES, - ZAP_ADDRESSES, -} from "src/constants/addresses"; +import { GOHM_ADDRESSES, OHM_ADDRESSES, SOHM_ADDRESSES, STAKING_ADDRESSES } from "src/constants/addresses"; import { DecimalBigNumber } from "src/helpers/DecimalBigNumber/DecimalBigNumber"; import { useBalance } from "src/hooks/useBalance"; import { useCurrentIndex } from "src/hooks/useCurrentIndex"; import { useTestableNetworks } from "src/hooks/useTestableNetworks"; -import { useZapExecute } from "src/hooks/useZapExecute"; import { useLiveBonds } from "src/views/Bond/hooks/useLiveBonds"; import StakeConfirmationModal from "src/views/Stake/components/StakeArea/components/StakeInputArea/components/StakeConfirmationModal"; import TokenModal, { @@ -30,7 +22,6 @@ import TokenModal, { import { useStakeToken } from "src/views/Stake/components/StakeArea/components/StakeInputArea/hooks/useStakeToken"; import { useUnstakeToken } from "src/views/Stake/components/StakeArea/components/StakeInputArea/hooks/useUnstakeToken"; import { useWrapSohm } from "src/views/Wrap/components/WrapInputArea/hooks/useWrapSohm"; -import ZapTransactionDetails from "src/views/Zap/ZapTransactionDetails"; import { useNetwork } from "wagmi"; const PREFIX = "StakeInputArea"; @@ -78,14 +69,10 @@ export const StakeInputArea: React.FC<{ isZoomed: boolean }> = props => { const [stakedAssetType, setStakedAssetType] = useState({ name: "gOHM" }); const [swapAssetType, setSwapAssetType] = useState({ name: "OHM" }); const { chain = { id: 1 } } = useNetwork(); - const [currentAction, setCurrentAction] = useState<"STAKE" | "UNSTAKE">("STAKE"); const [tokenModalOpen, setTokenModalOpen] = useState(false); const [confirmationModalOpen, setConfirmationModalOpen] = useState(false); const [zapTokenModalOpen, setZapTokenModalOpen] = useState(false); - const [zapSlippageAmount, setZapSlippageAmount] = useState(""); - const [zapMinAmount, setZapMinAmount] = useState(""); - const zapExecute = useZapExecute(); const wrapMutation = useWrapSohm(); const fromToken = currentAction === "STAKE" ? swapAssetType.name : stakedAssetType.name; @@ -93,8 +80,6 @@ export const StakeInputArea: React.FC<{ isZoomed: boolean }> = props => { // Max balance stuff const [amount, setAmount] = useState(""); const [receiveAmount, setReceiveAmount] = useState(""); - const [zapExchangeRate, setZapExchangeRate] = useState(0); - const [zapOutputAmount, setZapOutputAmount] = useState(""); const addresses = fromToken === "OHM" ? OHM_ADDRESSES : fromToken === "sOHM" ? SOHM_ADDRESSES : GOHM_ADDRESSES; const balance = useBalance(addresses)[networks.MAINNET].data; @@ -103,12 +88,9 @@ export const StakeInputArea: React.FC<{ isZoomed: boolean }> = props => { const gOhmBalance = useBalance(GOHM_ADDRESSES)[networks.MAINNET].data; const { data: currentIndex } = useCurrentIndex(); - const contractRouting = ["OHM", "gOHM"].includes(swapAssetType.name) - ? "Stake" - : swapAssetType.name === "sOHM" - ? "Wrap" - : "Zap"; - const contractAddress = contractRouting === "Stake" || contractRouting === "Wrap" ? STAKING_ADDRESSES : ZAP_ADDRESSES; + const contractRouting = ["OHM", "gOHM"].includes(swapAssetType.name) ? "Stake" : "Wrap"; + + const contractAddress = STAKING_ADDRESSES; const humanReadableRouting = currentAction === "STAKE" @@ -117,16 +99,13 @@ export const StakeInputArea: React.FC<{ isZoomed: boolean }> = props => { ? "Unstake" : currentAction === "UNSTAKE" && contractRouting === "Wrap" ? "Unwrap" - : currentAction === "UNSTAKE" && contractRouting === "Zap" - ? "Zap out" : contractRouting; // Staking/unstaking mutation stuff const stakeMutation = useStakeToken(); const unstakeMutation = useUnstakeToken(stakedAssetType.name === "gOHM" ? "gOHM" : "sOHM"); const isMutating = (currentAction === "STAKE" ? stakeMutation : unstakeMutation).isLoading; - const isMutationSuccess = - stakeMutation.isSuccess || unstakeMutation.isSuccess || zapExecute.isSuccess || wrapMutation.isSuccess; + const isMutationSuccess = stakeMutation.isSuccess || unstakeMutation.isSuccess || wrapMutation.isSuccess; const bonds = useLiveBonds({ isInverseBond: true }).data; const amountExceedsBalance = balance && new DecimalBigNumber(amount).gt(balance) ? true : false; @@ -137,28 +116,20 @@ export const StakeInputArea: React.FC<{ isZoomed: boolean }> = props => { if (!currentIndex) return null; spendAsset ? setAmount(value) : setReceiveAmount(value); let oppositeAmount: string; - if (currentAction === "STAKE" && contractRouting === "Zap") { - if (zapExchangeRate === 0) return null; - if (spendAsset) { - oppositeAmount = new DecimalBigNumber(value).div(new DecimalBigNumber(zapExchangeRate.toString())).toString(); - } else { - oppositeAmount = new DecimalBigNumber(value).mul(new DecimalBigNumber(zapExchangeRate.toString())).toString(); - } + + if ((currentAction === "STAKE" && spendAsset) || (currentAction === "UNSTAKE" && !spendAsset)) { + oppositeAmount = + stakedAssetType.name === "gOHM" ? new DecimalBigNumber(value, 9).div(currentIndex, 18).toString() : value; } else { - if ((currentAction === "STAKE" && spendAsset) || (currentAction === "UNSTAKE" && !spendAsset)) { - oppositeAmount = - stakedAssetType.name === "gOHM" ? new DecimalBigNumber(value, 9).div(currentIndex, 18).toString() : value; - } else { - oppositeAmount = - stakedAssetType.name === "gOHM" ? new DecimalBigNumber(value, 18).mul(currentIndex).toString() : value; - } + oppositeAmount = + stakedAssetType.name === "gOHM" ? new DecimalBigNumber(value, 18).mul(currentIndex).toString() : value; } spendAsset ? setReceiveAmount(oppositeAmount) : setAmount(oppositeAmount); }; useEffect(() => { ohmOnChange(amount, true); - }, [stakedAssetType, swapAssetType, zapExchangeRate]); + }, [stakedAssetType, swapAssetType]); useEffect(() => { if (isMutationSuccess) setConfirmationModalOpen(false); @@ -175,18 +146,6 @@ export const StakeInputArea: React.FC<{ isZoomed: boolean }> = props => { } }, [currentAction]); - const onZap = async () => { - if (swapAssetType.balance && swapAssetType.address && swapAssetType.decimals) { - zapExecute.mutate({ - slippage: zapSlippageAmount, - sellAmount: parseUnits(amount, swapAssetType.decimals), - tokenAddress: swapAssetType.address, - minimumAmount: zapMinAmount, - gOHM: stakedAssetType.name === "gOHM", - }); - } - }; - const OhmSwapCard = () => { const balance = swapAssetType.name === "sOHM" @@ -210,7 +169,7 @@ export const StakeInputArea: React.FC<{ isZoomed: boolean }> = props => { ) } tokenName={swapAssetType.name} - tokenOnClick={currentAction === "STAKE" ? () => setZapTokenModalOpen(true) : undefined} + tokenOnClick={currentAction === "STAKE" ? () => setTokenModalOpen(true) : undefined} inputProps={{ "data-testid": "ohm-input", min: "0" }} value={currentAction === "STAKE" ? amount : receiveAmount} onChange={event => +event.target.value >= 0 && ohmOnChange(event.target.value, currentAction === "STAKE")} @@ -268,9 +227,9 @@ export const StakeInputArea: React.FC<{ isZoomed: boolean }> = props => { TabIndicatorProps={!props.isZoomed ? { style: { display: "none" } } : undefined} onChange={(_, view: number) => setCurrentAction(view === 0 ? "STAKE" : "UNSTAKE")} > - + - + @@ -287,32 +246,10 @@ export const StakeInputArea: React.FC<{ isZoomed: boolean }> = props => { open={tokenModalOpen} handleSelect={name => setStakedAssetType(name)} handleClose={() => setTokenModalOpen(false)} - sOhmBalance={sOhmBalance && sOhmBalance.toString({ decimals: 2 })} - gOhmBalance={gOhmBalance && gOhmBalance.toString({ decimals: 2 })} - /> - )} - {zapTokenModalOpen && ( - { - setSwapAssetType(name); - }} - handleClose={() => setZapTokenModalOpen(false)} ohmBalance={ohmBalance && ohmBalance.toString({ decimals: 2 })} sOhmBalance={sOhmBalance && sOhmBalance.toString({ decimals: 2 })} gOhmBalance={gOhmBalance && gOhmBalance.toString({ decimals: 2 })} - showZapAssets - /> - )} - {contractRouting === "Zap" && ( - setZapOutputAmount(amount)} - handleExchangeRate={rate => setZapExchangeRate(rate)} - handleSlippageAmount={slippage => setZapSlippageAmount(slippage)} - handleMinAmount={minAmount => setZapMinAmount(minAmount)} + currentAction={currentAction} /> )} {currentAction === "UNSTAKE" && liveInverseBonds && ( @@ -324,19 +261,7 @@ export const StakeInputArea: React.FC<{ isZoomed: boolean }> = props => { )} - {contractRouting === "Zap" && ( - - - You are about to Zap. Zaps allow you to stake OHM from any other currency, all in one - tx, saving you gas and headache. -
- {`Learn more`} -
-
- )} + {/* Stake / Wrap / Zap */} @@ -386,30 +311,6 @@ export const StakeInputArea: React.FC<{ isZoomed: boolean }> = props => { : "Unstake"} )} - {contractRouting === "Zap" && ( - <> - setConfirmationModalOpen(true)} - > - - {zapOutputAmount === "" - ? "Enter an amount" - : +zapOutputAmount >= 0.5 || stakedAssetType.name == "gOHM" - ? "Zap-Stake" - : "Minimum Output Amount: 0.5 sOHM"} - - - - )}
@@ -428,15 +329,10 @@ export const StakeInputArea: React.FC<{ isZoomed: boolean }> = props => { amount={amount} receiveAmount={receiveAmount} amountExceedsBalance={amountExceedsBalance} - zapOutputAmount={zapOutputAmount} - zapSlippageAmount={zapSlippageAmount} - zapMinAmount={zapMinAmount} stakeMutation={stakeMutation} unstakeMutation={unstakeMutation} isMutating={isMutating} - onZap={onZap} wrapMutation={wrapMutation} - zapExecuteIsLoading={zapExecute.isLoading} humanReadableRouting={humanReadableRouting} /> diff --git a/src/views/Stake/components/StakeArea/components/StakeInputArea/components/StakeConfirmationModal.tsx b/src/views/Stake/components/StakeArea/components/StakeInputArea/components/StakeConfirmationModal.tsx index db287b1c05..a19292b3ec 100644 --- a/src/views/Stake/components/StakeArea/components/StakeInputArea/components/StakeConfirmationModal.tsx +++ b/src/views/Stake/components/StakeArea/components/StakeInputArea/components/StakeConfirmationModal.tsx @@ -15,7 +15,7 @@ import { ModalHandleSelectProps } from "src/views/Stake/components/StakeArea/com const StakeConfirmationModal = (props: { open: boolean; onClose: () => void; - contractRouting: "Stake" | "Wrap" | "Zap"; + contractRouting: "Stake" | "Wrap"; addresses: any; chain: { id: number }; swapAssetType: ModalHandleSelectProps; @@ -25,16 +25,11 @@ const StakeConfirmationModal = (props: { amount: string; receiveAmount: string; amountExceedsBalance: boolean; - zapOutputAmount: string; - zapSlippageAmount: string; - zapMinAmount: string; stakeMutation: any; unstakeMutation: any; isMutating: boolean; - onZap: any; wrapMutation: any; - zapExecuteIsLoading: boolean; - humanReadableRouting: "Stake" | "Wrap" | "Zap" | "Unstake" | "Unwrap" | "Zap out"; + humanReadableRouting: "Stake" | "Wrap" | "Unstake" | "Unwrap"; }) => { const { data: warmupLength } = useWarmupPeriod(); const needsWarmup = warmupLength?.gt("0") || false; @@ -107,12 +102,11 @@ const StakeConfirmationModal = (props: { minHeight={"100px"} > - {props.isMutating || - (props.zapExecuteIsLoading && ( - - Please don't close this modal until all wallet transactions are confirmed. - - ))} + {props.isMutating && ( + + Please don't close this modal until all wallet transactions are confirmed. + + )} @@ -149,13 +143,7 @@ const StakeConfirmationModal = (props: { : { [props.chain.id]: props.swapAssetType.address } } spenderAddressMap={props.contractAddress} - approvalText={ - props.currentAction === "STAKE" - ? props.contractRouting === "Stake" || props.contractRouting === "Wrap" - ? "Approve Staking" - : `Approve Zap from ${props.swapAssetType.name}` - : "Approve Unstaking" - } + approvalText={props.currentAction === "STAKE" ? "Approve Wrapping" : "Approve Unwrapping"} approvalPendingText={"Confirming Approval in your wallet"} isVertical > @@ -217,32 +205,6 @@ const StakeConfirmationModal = (props: { : "Unstake"} )} - {props.contractRouting === "Zap" && ( - <> - - - - {props.zapOutputAmount === "" - ? "Enter an amount" - : +props.zapOutputAmount >= 0.5 || props.stakedAssetType.name == "gOHM" - ? "Zap-Stake" - : "Minimum Output Amount: 0.5 sOHM"} - - - - )} diff --git a/src/views/Stake/components/StakeArea/components/StakeInputArea/components/TokenModal.tsx b/src/views/Stake/components/StakeArea/components/StakeInputArea/components/TokenModal.tsx index 94fe8e7b15..1592d46d3d 100644 --- a/src/views/Stake/components/StakeArea/components/StakeInputArea/components/TokenModal.tsx +++ b/src/views/Stake/components/StakeArea/components/StakeInputArea/components/TokenModal.tsx @@ -1,9 +1,7 @@ -import { Avatar, Box, CircularProgress, Dialog, Link, List, ListItem, ListItemText, Typography } from "@mui/material"; +import { Avatar, Box, Dialog, Link, List, ListItem, ListItemText, Typography } from "@mui/material"; import { useTheme } from "@mui/material/styles"; import { Icon, OHMTokenProps, Token } from "@olympusdao/component-library"; import { FC } from "react"; -import { trim } from "src/helpers"; -import { useZapTokenBalances } from "src/hooks/useZapTokenBalances"; export interface ModalHandleSelectProps { name: string; @@ -30,8 +28,7 @@ type OHMTokenModalProps = { ohmBalance?: string; sOhmBalance?: string; gOhmBalance?: string; - showZapAssets?: boolean; - alwaysShowTokens?: { name: OHMTokenProps["name"]; balance: string; address: string; price: number }[]; + currentAction?: string; }; /** * Component for Displaying TokenModal @@ -43,14 +40,9 @@ const TokenModal: FC = ({ ohmBalance = "0.00", sOhmBalance = "0.00", gOhmBalance = "0.00", - showZapAssets = false, - alwaysShowTokens, + currentAction, }) => { const theme = useTheme(); - const { data: zapTokenBalances = { balances: {} }, isLoading } = useZapTokenBalances(); - const tokensBalance = zapTokenBalances.balances; - console.log(tokensBalance, "tokensBalance"); - const showZap = showZapAssets && tokensBalance; const TokenItem: FC = ({ name, balance = "0", icon, address = "", price, decimals, ...props }) => { return ( @@ -97,50 +89,9 @@ const TokenModal: FC = ({ - {showZap ? ( - isLoading ? ( - - - - ) : ( - <> - {alwaysShowTokens && ( - <> - {alwaysShowTokens.map(token => ( - - ))} - - )} - - {parseInt(sOhmBalance) > 0 && } - {Object.entries(tokensBalance) - .filter(token => !token[1].hide) - .sort((tokenA, tokenB) => tokenB[1].balanceUSD - tokenA[1].balanceUSD) - .map(token => ( - - ))} - - ) - ) : ( - <> - {parseInt(sOhmBalance) > 0 && } - - - )} + {currentAction === "STAKE" && } + {parseInt(sOhmBalance) > 0 && } + {currentAction === "UNSTAKE" && } diff --git a/src/views/Stake/components/StakeArea/components/StakeNextRebaseAmount.tsx b/src/views/Stake/components/StakeArea/components/StakeNextRebaseAmount.tsx deleted file mode 100644 index dd4404f0bb..0000000000 --- a/src/views/Stake/components/StakeArea/components/StakeNextRebaseAmount.tsx +++ /dev/null @@ -1,61 +0,0 @@ -import { DataRow } from "@olympusdao/component-library"; -import { formatNumber } from "src/helpers"; -import { DecimalBigNumber } from "src/helpers/DecimalBigNumber/DecimalBigNumber"; -import { nonNullable } from "src/helpers/types/nonNullable"; -import { - useFuseBalance, - useGohmBalance, - useGohmTokemakBalance, - useSohmBalance, - useV1SohmBalance, - useWsohmBalance, -} from "src/hooks/useBalance"; -import { useCurrentIndex } from "src/hooks/useCurrentIndex"; -import { useStakingRebaseRate } from "src/hooks/useStakingRebaseRate"; -import { useTestableNetworks } from "src/hooks/useTestableNetworks"; -import { NetworkId } from "src/networkDetails"; - -export const StakeNextRebaseAmount = () => { - const { data: rebaseRate } = useStakingRebaseRate(); - - const sohmBalances = useSohmBalance(); - const gohmBalances = useGohmBalance(); - const wsohmBalances = useWsohmBalance(); - const v1sohmBalances = useV1SohmBalance(); - const gohmFuseBalances = useFuseBalance(); - const gohmTokemakBalances = useGohmTokemakBalance(); - - const networks = useTestableNetworks(); - const { data: currentIndex } = useCurrentIndex(); - - const sohmTokens = [sohmBalances[networks.MAINNET].data, v1sohmBalances[networks.MAINNET].data]; - const totalSohmBalance = sohmTokens - .filter(nonNullable) - .reduce((res, bal) => res.add(bal), new DecimalBigNumber("0", 9)); - - const gohmTokens = [ - gohmBalances[networks.MAINNET].data, - gohmBalances[NetworkId.ARBITRUM].data, - gohmBalances[NetworkId.AVALANCHE].data, - gohmBalances[NetworkId.POLYGON].data, - gohmBalances[NetworkId.FANTOM].data, - gohmBalances[NetworkId.OPTIMISM].data, - wsohmBalances[NetworkId.MAINNET].data, - wsohmBalances[NetworkId.ARBITRUM].data, - wsohmBalances[NetworkId.AVALANCHE].data, - gohmFuseBalances[NetworkId.MAINNET].data, - gohmTokemakBalances[NetworkId.MAINNET].data, - ]; - const totalGohmBalance = gohmTokens - .filter(nonNullable) - .reduce((res, bal) => res.add(bal), new DecimalBigNumber("0", 18)); - - const props: PropsOf = { title: `Your Next Rebase` }; - - if (rebaseRate && sohmBalances && totalGohmBalance && currentIndex) { - const nextRewardAmount = rebaseRate * totalGohmBalance.mul(currentIndex).add(totalSohmBalance).toApproxNumber(); - props.balance = `${formatNumber(nextRewardAmount, 4)} OHM`; - } else props.isLoading = true; - - return ; -}; diff --git a/src/views/Stake/components/StakeArea/components/StakeRebaseYield.tsx b/src/views/Stake/components/StakeArea/components/StakeRebaseYield.tsx deleted file mode 100644 index 6a3d17826f..0000000000 --- a/src/views/Stake/components/StakeArea/components/StakeRebaseYield.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import { DataRow } from "@olympusdao/component-library"; -import { formatNumber } from "src/helpers"; -import { useStakingRebaseRate } from "src/hooks/useStakingRebaseRate"; - -export const StakeRebaseYield = () => { - const { data: rebaseRate } = useStakingRebaseRate(); - - const props: PropsOf = { title: `Next Rebase Yield` }; - - if (rebaseRate) props.balance = `${formatNumber(rebaseRate * 100, 4)}%`; - else props.isLoading = true; - - return ; -}; diff --git a/src/views/TreasuryDashboard/TreasuryDashboard.tsx b/src/views/TreasuryDashboard/TreasuryDashboard.tsx index 408052fe9b..09b37c18e8 100644 --- a/src/views/TreasuryDashboard/TreasuryDashboard.tsx +++ b/src/views/TreasuryDashboard/TreasuryDashboard.tsx @@ -24,7 +24,6 @@ import { AbstractedMetricProps, BackingPerGOHM, BackingPerOHM, - CurrentIndex, GOhmCirculatingSupply, GOHMPriceFromSubgraph, MarketCap, @@ -161,7 +160,6 @@ const MetricsDashboard = () => { )} {isTokenOHM() ? : } - diff --git a/src/views/TreasuryDashboard/components/Metric/Metric.tsx b/src/views/TreasuryDashboard/components/Metric/Metric.tsx index 2968ce1379..e3efcf83a2 100644 --- a/src/views/TreasuryDashboard/components/Metric/Metric.tsx +++ b/src/views/TreasuryDashboard/components/Metric/Metric.tsx @@ -7,7 +7,6 @@ import { useOhmPrice as useOhmPriceFromSubgraph, useTotalValueDeposited, } from "src/hooks/useProtocolMetrics"; -import { useStakingRebaseRate } from "src/hooks/useStakingRebaseRate"; import { useTreasuryMarketValueLatest } from "src/hooks/useTokenRecordsMetrics"; import { useOhmCirculatingSupply, useOhmTotalSupply } from "src/hooks/useTokenSupplyMetrics"; import { useLiquidBackingPerGOhm, useLiquidBackingPerOhmBacked, useMarketCap } from "src/hooks/useTreasuryMetrics"; @@ -217,23 +216,6 @@ export const TotalValueDeposited: React.FC; }; -export const StakingAPY: React.FC = props => { - const { data: rebaseRate } = useStakingRebaseRate(); - const _props: MetricProps = { - ...props, - label: `Annualized Rebases`, - }; - - if (rebaseRate) { - const apy = (Math.pow(1 + rebaseRate, 365 * 3) - 1) * 100; - const formatted = formatNumber(apy, 1); - - _props.metric = `${formatted}%`; - } else _props.isLoading = true; - - return ; -}; - export const TreasuryBalance: React.FC = props => { const marketValueQuery = useTreasuryMarketValueLatest(); diff --git a/src/views/V1-Stake/V1-Stake.jsx b/src/views/V1-Stake/V1-Stake.jsx index 952c2764bc..4a8d9b72cc 100644 --- a/src/views/V1-Stake/V1-Stake.jsx +++ b/src/views/V1-Stake/V1-Stake.jsx @@ -34,11 +34,10 @@ import { useTestableNetworks } from "src/hooks/useTestableNetworks"; import { isPendingTxn, txnButtonText } from "src/slices/PendingTxnsSlice"; import { changeApproval, changeStake } from "src/slices/StakeThunk"; import { ClaimsArea } from "src/views/Stake/components/ClaimsArea/ClaimsArea"; -import RebaseTimer from "src/views/Stake/components/StakeArea/components/RebaseTimer/RebaseTimer"; import { StakeFiveDayYield } from "src/views/Stake/components/StakeArea/components/StakeFiveDayYield"; import { StakeNextRebaseAmount } from "src/views/Stake/components/StakeArea/components/StakeNextRebaseAmount"; import { StakeRebaseYield } from "src/views/Stake/components/StakeArea/components/StakeRebaseYield"; -import { CurrentIndex, StakingAPY, TotalValueDeposited } from "src/views/TreasuryDashboard/components/Metric/Metric"; +import { TotalValueDeposited } from "src/views/TreasuryDashboard/components/Metric/Metric"; import { useAccount, useNetwork, useProvider } from "wagmi"; function V1Stake({ setMigrationModalOpen }) { @@ -165,13 +164,11 @@ function V1Stake({ setMigrationModalOpen }) { return (
- }> + - - From f06ad9abb2d54dbf53b421ac9d5a83aa1af295de Mon Sep 17 00:00:00 2001 From: brightiron Date: Fri, 6 Oct 2023 13:21:53 -0500 Subject: [PATCH 02/17] OLY-53 --- .../ConnectButton/ConnectButton.tsx | 144 +++--------- src/components/Sidebar/NavContent.tsx | 2 +- src/components/TopBar/TopBar.tsx | 8 +- .../TopBar/Wallet/Assets/Balances.tsx | 7 +- src/components/TopBar/Wallet/Assets/index.tsx | 76 +++--- .../Cooler/hooks/useGetCoolerBalance.tsx | 31 +++ .../components/ClaimsArea/ClaimsArea.tsx | 1 - .../Stake/components/StakeArea/StakeArea.tsx | 4 +- .../StakeArea/components/StakeBalances.tsx | 217 ------------------ src/views/V1-Stake/V1-Stake.jsx | 9 - 10 files changed, 118 insertions(+), 381 deletions(-) create mode 100644 src/views/Lending/Cooler/hooks/useGetCoolerBalance.tsx delete mode 100644 src/views/Stake/components/StakeArea/components/StakeBalances.tsx diff --git a/src/components/ConnectButton/ConnectButton.tsx b/src/components/ConnectButton/ConnectButton.tsx index 9beac2a45e..d622e74c13 100644 --- a/src/components/ConnectButton/ConnectButton.tsx +++ b/src/components/ConnectButton/ConnectButton.tsx @@ -1,7 +1,7 @@ -import { Box, Button, Link, SvgIcon, Typography, useMediaQuery, useTheme } from "@mui/material"; +import { Box, SvgIcon, Typography, useMediaQuery, useTheme } from "@mui/material"; import { Icon, OHMButtonProps, PrimaryButton } from "@olympusdao/component-library"; import { ConnectButton as RainbowConnectButton } from "@rainbow-me/rainbowkit"; -import { Link as RouterLink, useLocation } from "react-router-dom"; +import { useLocation } from "react-router-dom"; import { ReactComponent as WalletIcon } from "src/assets/icons/wallet.svg"; import { trackGAEvent } from "src/helpers/analytics/trackGAEvent"; @@ -61,9 +61,6 @@ export const ConnectButton = () => { const theme = useTheme(); const mobile = useMediaQuery(theme.breakpoints.down("sm")); - const walletDrawerOpen = - location.pathname === "/wallet" || location.pathname === "/utility" || location.pathname === "/info" ? true : false; - return ( {({ account, chain, openAccountModal, openChainModal, openConnectModal, mounted }) => { @@ -80,70 +77,29 @@ export const ConnectButton = () => { > {(() => { if (!mounted || !account || !chain) { - if (walletDrawerOpen) { - return ( - { - fireAnalyticsEvent(); - openConnectModal(); - }} - > - - {`Connect`} - - ); - } else { - return ( - - {!mobile ? ( - - - {`Connect Wallet`} - - ) : ( - - )} - - ); - } - } - return ( - - {walletDrawerOpen ? ( + { + fireAnalyticsEvent(); + openConnectModal(); + }} + > + + {`Connect`} + ; + } else { + return ( + <> { )} - ) : ( - - {mobile ? ( - - ) : ( - - )} - - )} - - ); + + ); + } })()}
); diff --git a/src/components/Sidebar/NavContent.tsx b/src/components/Sidebar/NavContent.tsx index 251da1cfee..0b00bc47f9 100644 --- a/src/components/Sidebar/NavContent.tsx +++ b/src/components/Sidebar/NavContent.tsx @@ -55,7 +55,7 @@ const NavContent: React.VFC = () => { - + } label={`Lend & Borrow`} to="/lending"> diff --git a/src/components/TopBar/TopBar.tsx b/src/components/TopBar/TopBar.tsx index aae925fed9..c17b729659 100644 --- a/src/components/TopBar/TopBar.tsx +++ b/src/components/TopBar/TopBar.tsx @@ -4,6 +4,7 @@ import { AppBar, Box, Button, SvgIcon, useMediaQuery, useTheme } from "@mui/mate import { styled } from "@mui/material/styles"; import { ReactComponent as MenuIcon } from "src/assets/icons/hamburger.svg"; import ConnectButton from "src/components/ConnectButton/ConnectButton"; +import ThemeSwitcher from "src/components/TopBar/ThemeSwitch"; const PREFIX = "TopBar"; @@ -43,9 +44,9 @@ interface TopBarProps { handleDrawerToggle: () => void; } -function TopBar({ handleDrawerToggle }: TopBarProps) { - const theme = useTheme(); - const desktop = useMediaQuery(theme.breakpoints.up(1048)); +function TopBar({ handleDrawerToggle, theme, toggleTheme }: TopBarProps) { + const themeColor = useTheme(); + const desktop = useMediaQuery(themeColor.breakpoints.up(1048)); return ( + {!desktop && ( + )} + + ); } else { return ( - - <> + + + ); } diff --git a/src/components/DevFaucet/index.tsx b/src/components/DevFaucet/index.tsx new file mode 100644 index 0000000000..c38fb4e57a --- /dev/null +++ b/src/components/DevFaucet/index.tsx @@ -0,0 +1,45 @@ +import { Box, FormControl, MenuItem, Select, Typography } from "@mui/material"; +import { SecondaryButton } from "@olympusdao/component-library"; +import { useState } from "react"; +import { useFaucet } from "src/components/TopBar/Wallet/hooks/useFaucet"; + +export const DevFaucet = () => { + const PREFIX = "AssetsIndex"; + const [faucetToken, setFaucetToken] = useState("OHM V2"); + const faucetMutation = useFaucet(); + + const classes = { + selector: `${PREFIX}-selector`, + forecast: `${PREFIX}-forecast`, + faucet: `${PREFIX}-faucet`, + }; + const isFaucetLoading = faucetMutation.isLoading; + + return ( + <> + Dev Faucet + + + + + faucetMutation.mutate(faucetToken)}> + {isFaucetLoading ? "Loading..." : "Get Tokens"} + + + + ); +}; diff --git a/src/components/Migration/MigrationModal.tsx b/src/components/Migration/MigrationModal.tsx index b2d5045078..19070f651e 100644 --- a/src/components/Migration/MigrationModal.tsx +++ b/src/components/Migration/MigrationModal.tsx @@ -3,10 +3,8 @@ import "src/components/Migration/MigrationModal.scss"; import { Box, Button, Table, TableBody, TableCell, TableHead, TableRow, Typography } from "@mui/material"; import useMediaQuery from "@mui/material/useMediaQuery"; import { InfoTooltip, Modal, Tab, Tabs } from "@olympusdao/component-library"; -import { useEffect } from "react"; -import toast from "react-hot-toast"; import { useDispatch } from "react-redux"; -import { isChainEthereum, trim } from "src/helpers"; +import { trim } from "src/helpers"; import { useMigrationData } from "src/helpers/Migration"; import { useAppSelector } from "src/hooks"; import { changeMigrationApproval, migrateAll } from "src/slices/MigrateThunk"; @@ -67,16 +65,6 @@ function MigrationModal({ open, handleClose }: { open: boolean; handleClose: any ); }; - useEffect(() => { - if ( - isChainEthereum({ chainId: chain.id, includeTestnets: true }) && - isAllApproved && - (currentOhmBalance || currentSOhmBalance || currentWSOhmBalance) - ) { - toast("All approvals complete. You may now migrate."); - } - }, [isAllApproved]); - const onMigrate = () => { if (!signer) throw new Error("No signer"); dispatch(migrateAll({ provider, signer, address, networkID: chain.id, gOHM: isGOHM })); diff --git a/src/components/Sidebar/NavContent.tsx b/src/components/Sidebar/NavContent.tsx index 0b00bc47f9..87a6d60835 100644 --- a/src/components/Sidebar/NavContent.tsx +++ b/src/components/Sidebar/NavContent.tsx @@ -1,4 +1,4 @@ -import { Box, Divider, Link, Paper, SvgIcon, Typography, useTheme } from "@mui/material"; +import { Box, Link, Paper, SvgIcon, Typography, useTheme } from "@mui/material"; import { styled } from "@mui/material/styles"; import { Icon } from "@olympusdao/component-library"; import React from "react"; @@ -49,22 +49,24 @@ const NavContent: React.VFC = () => {
diff --git a/src/components/TopBar/ThemeSwitch.tsx b/src/components/TopBar/ThemeSwitch.tsx index 6297a2f24b..0b7524f3ed 100644 --- a/src/components/TopBar/ThemeSwitch.tsx +++ b/src/components/TopBar/ThemeSwitch.tsx @@ -1,3 +1,4 @@ +import { Box } from "@mui/material"; import ToggleButton from "@mui/material/ToggleButton"; import { Icon } from "@olympusdao/component-library"; @@ -8,20 +9,22 @@ interface IThemeSwitcherProps { function ThemeSwitcher({ theme, toggleTheme }: IThemeSwitcherProps) { return ( - - {theme === "dark" ? ( - - ) : ( - - )} - + + + {theme === "dark" ? ( + + ) : ( + + )} + + ); } diff --git a/src/components/TopBar/TopBar.tsx b/src/components/TopBar/TopBar.tsx index c17b729659..4a51f1c88a 100644 --- a/src/components/TopBar/TopBar.tsx +++ b/src/components/TopBar/TopBar.tsx @@ -1,7 +1,6 @@ // import "src/components/TopBar/TopBar.scss"; -import { AppBar, Box, Button, SvgIcon, useMediaQuery, useTheme } from "@mui/material"; -import { styled } from "@mui/material/styles"; +import { Box, Button, SvgIcon, useMediaQuery, useTheme } from "@mui/material"; import { ReactComponent as MenuIcon } from "src/assets/icons/hamburger.svg"; import ConnectButton from "src/components/ConnectButton/ConnectButton"; import ThemeSwitcher from "src/components/TopBar/ThemeSwitch"; @@ -14,30 +13,6 @@ const classes = { pageTitle: `${PREFIX}-pageTitle`, }; -const StyledAppBar = styled(AppBar)(({ theme }) => ({ - [`&.${classes.appBar}`]: { - [theme.breakpoints.up("sm")]: { - width: "100%", - padding: "10px", - paddingTop: "22.5px", - }, - backdropFilter: "none", - }, - - [`& .${classes.menuButton}`]: { - [theme.breakpoints.up(1048)]: { - display: "none", - }, - }, - - [`& .${classes.pageTitle}`]: { - [theme.breakpoints.up(1048)]: { - marginLeft: "287px", - }, - marginLeft: "0px", - }, -})); - interface TopBarProps { theme: string; toggleTheme: (e: KeyboardEvent) => void; diff --git a/src/components/TopBar/Wallet/Assets/Balances.tsx b/src/components/TopBar/Wallet/Assets/Balances.tsx deleted file mode 100644 index 85ad3fc3bb..0000000000 --- a/src/components/TopBar/Wallet/Assets/Balances.tsx +++ /dev/null @@ -1,62 +0,0 @@ -import { AssetCard, OHMTokenStackProps } from "@olympusdao/component-library"; -import { GetTokenPrice } from "src/components/TopBar/Wallet/queries"; -import { formatCurrency } from "src/helpers"; - -interface TokenArray { - assetValue: number; - symbol?: OHMTokenStackProps["tokens"]; - balance?: string; - label?: string; - timeRemaining?: string; - underlyingSymbol?: string; - pnl?: string | number; - alwaysShow?: boolean; - ctaOnClick?: () => void; - ctaText?: string; - lineThreeValue?: string | number; - lineThreeLabel?: string; - geckoTicker?: string; -} -/** - * Component for Displaying Assets - */ -const Balances = (props: { token: TokenArray }) => { - const { data: priceFeed = { usd_24h_change: -0 } } = GetTokenPrice(props.token.geckoTicker); - const lineThree = props.token.lineThreeLabel - ? { lineThreeLabel: props.token.lineThreeLabel, lineThreeValue: props.token.lineThreeValue } - : {}; - const extraProps = - props.token.ctaText && props.token.ctaOnClick - ? { ctaText: props.token.ctaText, ctaOnClick: props.token.ctaOnClick } - : {}; - if (Number(props.token.balance) > 0 || props.token.alwaysShow) { - return ( - 0 - ? formatCurrency( - Number(props.token.balance) === 0 - ? 0 - : props.token.assetValue - Number(props.token.assetValue) / (1 + priceFeed.usd_24h_change / 100), - 2, - ) - : "" - } - timeRemaining={props.token.timeRemaining} - {...extraProps} - {...lineThree} - /> - ); - } - return <> ; -}; - -export default Balances; diff --git a/src/components/TopBar/Wallet/Assets/TransactionHistory.tsx b/src/components/TopBar/Wallet/Assets/TransactionHistory.tsx deleted file mode 100644 index 159fdea248..0000000000 --- a/src/components/TopBar/Wallet/Assets/TransactionHistory.tsx +++ /dev/null @@ -1,141 +0,0 @@ -import { Box, Button, Typography } from "@mui/material"; -import { styled } from "@mui/material/styles"; -import { TransactionRow } from "@olympusdao/component-library"; -import { FC, useMemo, useRef, useState } from "react"; -import useIntersectionObserver from "src/components/TopBar/Wallet/helpers"; -import { useTransactionHistory, useTransferHistory } from "src/components/TopBar/Wallet/queries"; -import { GOHM_TOKEN, OHM_TOKEN, SOHM_TOKEN, V1_OHM_TOKEN, V1_SOHM_TOKEN, WSOHM_TOKEN } from "src/constants/tokens"; -import { Transaction } from "src/helpers/covalent/interpretTransaction"; -import { nonNullable } from "src/helpers/types/nonNullable"; - -const PREFIX = "TransactionHistory"; - -const classes = { - tabNav: `${PREFIX}-tabNav`, -}; - -// TODO jss-to-styled codemod: The Fragment root was replaced by div. Change the tag if needed. -const Root = styled("div")(({ theme }) => ({ - "&.transaction-container": { - "&>*:nth-child(odd) .row-details": { - background: "transparent", - }, - }, - [`& .${classes.tabNav}`]: { - "& p": { - "&:first-child": { - paddingLeft: "0px", - }, - fontSize: "14px", - lineHeight: "20px", - color: theme.colors.gray[90], - padding: "8px 18px 10px 18px", - "&.active": { - color: theme.palette.mode === "light" ? theme.palette.primary.main : theme.colors.primary[300], - textDecoration: "underline", - textUnderlineOffset: ".23rem", - }, - cursor: "pointer", - }, - }, -})); - -const filters: Array<{ label: string; value: "all" | Transaction["type"] }> = [ - { label: "All", value: "all" }, - { label: "Staking", value: "staking" }, - { label: "Bond", value: "bond" }, - { label: "Zap", value: "zap" }, - { label: "Borrow", value: "borrow" }, -]; - -export const TransactionHistory: FC = () => { - const loadMoreButtonRef = useRef(null); - const [activeFilter, setActiveFilter] = useState<"all" | Transaction["type"]>("all"); - - const transactions = useTransactionHistory(); - const ohmTransfers = useTransferHistory(OHM_TOKEN); - const gohmTransfers = useTransferHistory(GOHM_TOKEN); - const sohmTransfers = useTransferHistory(SOHM_TOKEN); - const wsohmTransfers = useTransferHistory(WSOHM_TOKEN); - const v1ohmTransfers = useTransferHistory(V1_OHM_TOKEN); - const v1sohmTransfers = useTransferHistory(V1_SOHM_TOKEN); - - useIntersectionObserver({ - target: loadMoreButtonRef, - enabled: !!transactions.hasNextPage, - onIntersect: transactions.fetchNextPage, - }); - - const queries = [ - transactions, - gohmTransfers, - ohmTransfers, - sohmTransfers, - v1ohmTransfers, - v1sohmTransfers, - wsohmTransfers, - ]; - - const allLoaded = queries.every(query => query.isFetched); - - const history = queries - .map(query => query.data) - .filter(nonNullable) - .map(data => data.pages.flat()) - .flat() - .sort((a, b) => b.transaction.block_height - a.transaction.block_height); - - const filtered = useMemo(() => { - if (activeFilter === "all") return history; - return history.filter(transaction => transaction.type === activeFilter); - }, [activeFilter, history]); - - if (!allLoaded) return null; - - return ( - - - {filters.map(({ label, value }, index) => ( - setActiveFilter(value)} - className={activeFilter === value ? "active" : ""} - > - {label} - - ))} - - {filtered.map((transaction, index) => ( - - ))} - {filtered.length === 0 ? ( - - - No transactions - - - ) : ( - - - - )} - - ); -}; diff --git a/src/components/TopBar/Wallet/Assets/index.tsx b/src/components/TopBar/Wallet/Assets/index.tsx deleted file mode 100644 index 73790379be..0000000000 --- a/src/components/TopBar/Wallet/Assets/index.tsx +++ /dev/null @@ -1,295 +0,0 @@ -import { Box, Fade, FormControl, MenuItem, Select, Typography } from "@mui/material"; -import { styled } from "@mui/material/styles"; -import { OHMTokenStackProps, SecondaryButton, WalletBalance } from "@olympusdao/component-library"; -import { FC, useState } from "react"; -import { useNavigate } from "react-router-dom"; -import Balances from "src/components/TopBar/Wallet/Assets/Balances"; -import { useFaucet } from "src/components/TopBar/Wallet/hooks/useFaucet"; -import { GetTokenPrice } from "src/components/TopBar/Wallet/queries"; -import { formatCurrency, formatNumber, isTestnet, trim } from "src/helpers"; -import { DecimalBigNumber } from "src/helpers/DecimalBigNumber/DecimalBigNumber"; -import { prettifySecondsInDays } from "src/helpers/timeUtil"; -import { nonNullable } from "src/helpers/types/nonNullable"; -import { - useFuseBalance, - useGohmBalance, - useGohmTokemakBalance, - useOhmBalance, - useSohmBalance, - useV1OhmBalance, - useV1SohmBalance, - useWsohmBalance, -} from "src/hooks/useBalance"; -import { useCurrentIndex } from "src/hooks/useCurrentIndex"; -import { useOhmPrice } from "src/hooks/usePrices"; -import { useStakingRebaseRate } from "src/hooks/useStakingRebaseRate"; -import { useTestableNetworks } from "src/hooks/useTestableNetworks"; -import { NetworkId } from "src/networkDetails"; -import { useBondNotes } from "src/views/Bond/components/ClaimBonds/hooks/useBondNotes"; -import { useGetClearingHouse } from "src/views/Lending/Cooler/hooks/useGetClearingHouse"; -import { useGetCoolerBalance } from "src/views/Lending/Cooler/hooks/useGetCoolerBalance"; -import { useGetCoolerForWallet } from "src/views/Lending/Cooler/hooks/useGetCoolerForWallet"; -import { useAccount, useNetwork } from "wagmi"; - -const PREFIX = "AssetsIndex"; - -const classes = { - selector: `${PREFIX}-selector`, - forecast: `${PREFIX}-forecast`, - faucet: `${PREFIX}-faucet`, -}; - -const StyledFade = styled(Fade)(({ theme }) => ({ - [`& .${classes.selector}`]: { - "& p": { - fontSize: "16px", - fontWeight: 400, - lineHeight: "24px", - - cursor: "pointer", - }, - "& a": { - color: theme.colors.gray[90], - marginRight: "18px", - }, - "& a:last-child": { - marginRight: 0, - }, - "& .active": { - color: theme.palette.mode === "light" ? theme.palette.primary.main : theme.colors.primary[300], - textDecoration: "inherit", - }, - }, - - [`& .${classes.forecast}`]: { - textAlign: "right", - "& .number": { - fontWeight: 400, - }, - "& .numberSmall": { - justifyContent: "flex-end", - }, - }, - - [`& .${classes.faucet}`]: { - width: "30%", - }, -})); - -/** - * Component for Displaying Assets - */ - -export interface OHMAssetsProps { - path?: string; -} -const AssetsIndex: FC = (props: { path?: string }) => { - const { address } = useAccount(); - const navigate = useNavigate(); - const networks = useTestableNetworks(); - const { chain = { id: 1 } } = useNetwork(); - const { data: ohmPrice = 0 } = useOhmPrice(); - const { data: priceFeed = { usd_24h_change: -0 } } = GetTokenPrice(); - const { data: currentIndex = new DecimalBigNumber("0", 9) } = useCurrentIndex(); - const { data: rebaseRate = 0 } = useStakingRebaseRate(); - const { data: v1OhmBalance = new DecimalBigNumber("0", 9) } = useV1OhmBalance()[networks.MAINNET]; - const { data: v1SohmBalance = new DecimalBigNumber("0", 9) } = useV1SohmBalance()[networks.MAINNET]; - const { data: sOhmBalance = new DecimalBigNumber("0", 9) } = useSohmBalance()[networks.MAINNET]; - const wsohmBalances = useWsohmBalance(); - const gohmBalances = useGohmBalance(); - const ohmBalances = useOhmBalance(); - const { data: gohmFuseBalance = new DecimalBigNumber("0", 18) } = useFuseBalance()[NetworkId.MAINNET]; - const { data: gohmTokemakBalance = new DecimalBigNumber("0", 18) } = useGohmTokemakBalance()[NetworkId.MAINNET]; - const [faucetToken, setFaucetToken] = useState("OHM V2"); - const { data: clearingHouseV1 } = useGetClearingHouse({ clearingHouse: "clearingHouseV1" }); - const { data: clearingHouseV2 } = useGetClearingHouse({ clearingHouse: "clearingHouseV2" }); - const { data: coolerAddressV1 } = useGetCoolerForWallet({ - walletAddress: address, - factoryAddress: clearingHouseV1?.factory, - collateralAddress: clearingHouseV1?.collateralAddress, - debtAddress: clearingHouseV1?.debtAddress, - clearingHouseVersion: "clearingHouseV1", - }); - const { data: coolerAddressV2 } = useGetCoolerForWallet({ - walletAddress: address, - factoryAddress: clearingHouseV2?.factory, - collateralAddress: clearingHouseV2?.collateralAddress, - debtAddress: clearingHouseV2?.debtAddress, - clearingHouseVersion: "clearingHouseV2", - }); - - const { data: coolerV1Balance } = useGetCoolerBalance({ coolerAddress: coolerAddressV1 }); - const { data: coolerV2Balance } = useGetCoolerBalance({ coolerAddress: coolerAddressV2 }); - - const ohmTokens = isTestnet(chain.id) - ? [ohmBalances[NetworkId.TESTNET_GOERLI].data, ohmBalances[NetworkId.ARBITRUM_GOERLI].data] - : [ohmBalances[NetworkId.MAINNET].data, ohmBalances[NetworkId.ARBITRUM].data]; - - const gohmTokens = [ - gohmFuseBalance, - gohmTokemakBalance, - gohmBalances[networks.MAINNET].data, - gohmBalances[NetworkId.ARBITRUM].data, - gohmBalances[NetworkId.AVALANCHE].data, - gohmBalances[NetworkId.POLYGON].data, - gohmBalances[NetworkId.FANTOM].data, - gohmBalances[NetworkId.OPTIMISM].data, - ]; - const wsohmTokens = [ - wsohmBalances[NetworkId.MAINNET].data, - wsohmBalances[NetworkId.ARBITRUM].data, - wsohmBalances[NetworkId.AVALANCHE].data, - ]; - - const coolerTokens = [coolerV1Balance, coolerV2Balance]; - - const totalOhmBalance = ohmTokens - .filter(nonNullable) - .reduce((res, bal) => res.add(bal), new DecimalBigNumber("0", 18)); - - const totalGohmBalance = gohmTokens - .filter(nonNullable) - .reduce((res, bal) => res.add(bal), new DecimalBigNumber("0", 18)); - - const totalWsohmBalance = wsohmTokens - .filter(nonNullable) - .reduce((res, bal) => res.add(bal), new DecimalBigNumber("0", 18)); - - const totalCoolerBalance = coolerTokens - .filter(nonNullable) - .reduce((res, bal) => res.add(bal), new DecimalBigNumber("0", 18)); - - const notes = useBondNotes().data; - const formattedohmBalance = totalOhmBalance.toString({ decimals: 4, trim: false, format: true }); - const formattedV1OhmBalance = v1OhmBalance.toString({ decimals: 4, trim: false, format: true }); - const formattedV1SohmBalance = v1SohmBalance.toString({ decimals: 4, trim: false, format: true }); - const formattedWsOhmBalance = totalWsohmBalance.toString({ decimals: 4, trim: false, format: true }); - const formattedgOhmBalance = totalGohmBalance.toString({ decimals: 4, trim: false, format: true }); - const formattedSOhmBalance = sOhmBalance.toString({ decimals: 4, trim: false, format: true }); - const gOhmPriceChange = priceFeed.usd_24h_change * currentIndex.toApproxNumber(); - const gOhmPrice = ohmPrice * currentIndex.toApproxNumber(); - const rebaseAmountPerDay = rebaseRate * Number(formattedSOhmBalance) * 3; - const coolerBalance = totalCoolerBalance.toString({ decimals: 4, trim: false, format: true }); - - const tokenArray = [ - { - symbol: ["OHM"] as OHMTokenStackProps["tokens"], - balance: formattedohmBalance, - assetValue: totalOhmBalance.toApproxNumber() * ohmPrice, - alwaysShow: true, - }, - { - symbol: ["OHM"] as OHMTokenStackProps["tokens"], - balance: formattedV1OhmBalance, - label: "(v1)", - assetValue: v1OhmBalance.toApproxNumber() * ohmPrice, - }, - { - symbol: ["sOHM"] as OHMTokenStackProps["tokens"], - balance: formattedSOhmBalance, - assetValue: sOhmBalance.toApproxNumber() * ohmPrice, - lineThreeValue: Number(formattedSOhmBalance) > 0 ? `${trim(rebaseAmountPerDay, 3)} sOHM ` : undefined, - }, - { - symbol: ["sOHM"] as OHMTokenStackProps["tokens"], - balance: formattedV1SohmBalance, - label: "(v1)", - assetValue: v1SohmBalance.toApproxNumber() * ohmPrice, - }, - { - symbol: ["wsOHM"] as OHMTokenStackProps["tokens"], - balance: formattedWsOhmBalance, - assetValue: gOhmPrice * totalWsohmBalance.toApproxNumber(), - geckoTicker: "governance-ohm", - }, - { - symbol: ["gOHM"] as OHMTokenStackProps["tokens"], - balance: formattedgOhmBalance, - assetValue: gOhmPrice * totalGohmBalance.toApproxNumber(), - pnl: formattedgOhmBalance ? 0 : formatCurrency(totalGohmBalance.toApproxNumber() * gOhmPriceChange, 2), - alwaysShow: true, - geckoTicker: "governance-ohm", - }, - { - symbol: ["gOHM"] as OHMTokenStackProps["tokens"], - balance: coolerBalance, - assetValue: gOhmPrice * totalCoolerBalance.toApproxNumber(), - pnl: coolerBalance ? 0 : formatCurrency(totalCoolerBalance.toApproxNumber() * gOhmPriceChange, 2), - alwaysShow: true, - geckoTicker: "governance-ohm", - lineThreeLabel: "Cooler Loans Collateral", - }, - ]; - - const bondsArray = - notes?.map(note => ({ - key: note.id, - symbol: note.bond.quoteToken.icons, - balance: note.payout.toString({ decimals: 4, trim: false }), - label: "(Bond)", - timeRemaining: - Date.now() > note.matured ? "Fully Vested" : prettifySecondsInDays((note.matured - Date.now()) / 1000), - assetValue: note.payout.toApproxNumber() * gOhmPrice, - underlyingSymbol: "gOHM", - pnl: Number(note.payout) === 0 ? 0 : formatCurrency(note.payout.toApproxNumber() * gOhmPriceChange, 2), - ctaText: "Claim", - ctaOnClick: () => navigate("/bonds"), - geckoTicker: "governance-ohm", - })) || []; - - const assets = [...tokenArray, ...bondsArray]; - const walletTotalValueUSD = Object.values(assets).reduce((totalValue, token) => totalValue + token.assetValue, 0); - - const faucetMutation = useFaucet(); - const isFaucetLoading = faucetMutation.isLoading; - - return ( - - - - - - - <> - {assets.map((asset, index) => ( - - ))} - - - {chain.id === NetworkId.TESTNET_GOERLI && ( - <> - Dev Faucet - - - - - faucetMutation.mutate(faucetToken)}> - {isFaucetLoading ? "Loading..." : "Get Tokens"} - - - - )} - - - ); -}; - -export default AssetsIndex; diff --git a/src/components/TopBar/Wallet/GetOhm.tsx b/src/components/TopBar/Wallet/GetOhm.tsx deleted file mode 100644 index 1097bba26e..0000000000 --- a/src/components/TopBar/Wallet/GetOhm.tsx +++ /dev/null @@ -1,172 +0,0 @@ -import { Box, Fade, Grid, SvgIcon, Typography } from "@mui/material"; -import { styled } from "@mui/material/styles"; -import { GetOnButton, ItemCard, OHMTokenProps, OHMTokenStackProps } from "@olympusdao/component-library"; -import { FC } from "react"; -import { ReactComponent as balancerIcon } from "src/assets/balancer.svg"; -import sushiswapImg from "src/assets/sushiswap.png"; -import uniswapImg from "src/assets/uniswap.png"; -import { OHM_ADDRESSES } from "src/constants/addresses"; -import { formatCurrency, formatNumber, trim } from "src/helpers"; -import { sortByDiscount } from "src/helpers/bonds/sortByDiscount"; -import { DecimalBigNumber } from "src/helpers/DecimalBigNumber/DecimalBigNumber"; -import { defiLlamaChainToNetwork } from "src/helpers/defiLlamaChainToNetwork"; -import { normalizeSymbol } from "src/helpers/normalizeSymbol"; -import { prettifySecondsInDays } from "src/helpers/timeUtil"; -import { useGetLPStats } from "src/hooks/useGetLPStats"; -import { useStakingRebaseRate } from "src/hooks/useStakingRebaseRate"; -import { NetworkId } from "src/networkDetails"; -import { useLiveBonds } from "src/views/Bond/hooks/useLiveBonds"; -import { useNetwork } from "wagmi"; -const PREFIX = "GetOhm"; - -const classes = { - title: `${PREFIX}-title`, -}; - -const StyledBox = styled(Box)(() => ({ - [`& .${classes.title}`]: { - lineHeight: "24px", - fontWeight: 600, - marginBottom: "12px", - marginTop: "30px", - }, -})); - -/** - * Component for Displaying GetOhm - */ -const GetOhm: FC = () => { - const { chain = { id: 1 } } = useNetwork(); - const { data: rebaseRate = 0 } = useStakingRebaseRate(); - - const bonds = useLiveBonds().data; - const fiveDayRate = Math.pow(1 + rebaseRate, 5 * 3) - 1; - const { data: defiLlamaPools } = useGetLPStats(); - - return ( - - - - Exchanges - - - - } - exchangeName="Balancer" - /> - - - } - exchangeName="Sushiswap" - /> - - - } - exchangeName="Uniswap" - /> - - - {NetworkId.MAINNET === chain.id && ( - <> - - Zap - - - - Bonds - - {bonds && - sortByDiscount(bonds).map(bond => ( - - ))} - - Stake - - - - )} - - Farm Pool - - {defiLlamaPools && - defiLlamaPools.map(pool => ( - - ))} - - Vaults - - - - - Borrow - - - - - - ); -}; - -export default GetOhm; diff --git a/src/components/TopBar/Wallet/Info/Faq.tsx b/src/components/TopBar/Wallet/Info/Faq.tsx deleted file mode 100644 index ae85e41fe9..0000000000 --- a/src/components/TopBar/Wallet/Info/Faq.tsx +++ /dev/null @@ -1,47 +0,0 @@ -import { Box, Fade } from "@mui/material"; -import { InfoCard } from "@olympusdao/component-library"; - -/** - * Component for Displaying Faq - */ -const Faq = () => { - const faqContent = [ - { - title: "Why do we need OlympusDAO in the first place?", - content: - "Dollar-pegged stablecoins have become an essential part of crypto due to their lack of volatility as compared to tokens such as Bitcoin and Ether.", - }, - { - title: "Is OHM a stable coin?", - content: - "No, OHM is not a stable coin. Rather, OHM aspires to become an algorithmic reserve currency backed by other decentralized assets. ", - }, - { - title: "How does it work?", - content: - "At a high level, OlympusDAO consists of its protocol managed treasury, protocol owned liquidity (POL), bond mechanism, and staking rewards that are designed to control supply expansion.", - }, - { - title: "What is bonding?", - content: - "Bonding is the secondary value accrual strategy of Olympus. It allows Olympus to acquire its own liquidity and other reserve assets such as LUSD by selling OHM at a discount in exchange for these assets. ", - }, - { - title: "What is Staking?", - content: - "Staking is the primary value accrual strategy of Olympus. Stakers stake their OHM on the Olympus website to earn rebase rewards. The rebase rewards come from the proceed from bond sales, and can vary based on the number of OHM staked in the protocol and the reward rate set by monetary policy.", - }, - ]; - - return ( - - - {faqContent.map((faq: { title: string | undefined; content: string | undefined }, index) => ( - - ))} - - - ); -}; - -export default Faq; diff --git a/src/components/TopBar/Wallet/Info/News.tsx b/src/components/TopBar/Wallet/Info/News.tsx deleted file mode 100644 index f7153af538..0000000000 --- a/src/components/TopBar/Wallet/Info/News.tsx +++ /dev/null @@ -1,63 +0,0 @@ -import { Box, Fade } from "@mui/material"; -import { ArticleCard } from "@olympusdao/component-library"; -import { FC, Key } from "react"; -import { MediumArticles } from "src/components/TopBar/Wallet/queries"; - -export interface OHMNewsProps { - path?: string; -} - -/** - * Component for Displaying News - */ -const News: FC = () => { - const { data, isFetched } = MediumArticles(); - - /** - * Convert a template string into HTML DOM nodes - * @param {String} str The template string - * @return {Node.textContent} The template HTML - */ - const parseFeedContent = (str: string): string => { - const parser = new DOMParser(); - const doc = parser.parseFromString(str, "text/html"); - - return doc.body.textContent || ""; - }; - const truncate = (str: string) => { - return str.length > 400 ? str.substring(0, 397) + "..." : str; - }; - return ( - - - {isFetched && - data.items.map( - ( - article: { - title: string; - thumbnail: string; - content: string; - link: string | undefined; - pubDate: string | number | Date; - }, - index: Key | null | undefined, - ) => { - const dateNoTime = article.pubDate.toString().split(" ")[0]; - return ( - - ); - }, - )} - - - ); -}; - -export default News; diff --git a/src/components/TopBar/Wallet/Info/Proposals.tsx b/src/components/TopBar/Wallet/Info/Proposals.tsx deleted file mode 100644 index deebbcc8d4..0000000000 --- a/src/components/TopBar/Wallet/Info/Proposals.tsx +++ /dev/null @@ -1,52 +0,0 @@ -import { Box, Fade } from "@mui/material"; -import { InfoCard } from "@olympusdao/component-library"; -import { FC, Key } from "react"; -import { ActiveProposals } from "src/components/TopBar/Wallet/queries"; - -/** - * Component for displaying proposals - */ -export const Proposals: FC = () => { - const { data, isFetched } = ActiveProposals(); - - const truncate = (str: string) => { - return str.length > 200 ? str.substring(0, 197) + "..." : str; - }; - return ( - - - {isFetched && - data.proposals.map( - ( - proposal: { - title: string | undefined; - body: string; - state: string; - scores: number[]; - link: string | undefined; - end: number; - choices: { [x: string]: string | undefined }; - }, - index: Key | null | undefined, - ) => { - const max = Math.max(...proposal.scores); - const indexOf = proposal.scores.indexOf(max); - return ( - - ); - }, - )} - - - ); -}; diff --git a/src/components/TopBar/Wallet/Info/index.tsx b/src/components/TopBar/Wallet/Info/index.tsx deleted file mode 100644 index 0ee418ef30..0000000000 --- a/src/components/TopBar/Wallet/Info/index.tsx +++ /dev/null @@ -1,74 +0,0 @@ -import { Box, Fade, Link } from "@mui/material"; -import { styled } from "@mui/material/styles"; -import { FC } from "react"; -import { Navigate, NavLink, Outlet, Route, Routes, useLocation } from "react-router-dom"; -import Faq from "src/components/TopBar/Wallet/Info/Faq"; -import News from "src/components/TopBar/Wallet/Info/News"; -import { Proposals } from "src/components/TopBar/Wallet/Info/Proposals"; -import { Environment } from "src/helpers/environment/Environment/Environment"; - -/** - * Component for displaying info - */ -export const Info: FC = () => ( - <> - - }> - } /> - } /> - } /> - - - -); - -const PREFIX = "Info"; - -const classes = { - tabNav: `${PREFIX}-tabNav`, -}; - -// TODO jss-to-styled codemod: The Fragment root was replaced by div. Change the tag if needed. -const Root = styled("div")(({ theme }) => ({ - [`& .${classes.tabNav}`]: { - "& a": { - fontSize: "14px", - lineHeight: "20px", - color: theme.colors.gray[90], - padding: "8px 18px 10px 18px", - "&.active": { - color: theme.palette.mode === "light" ? theme.palette.primary.main : theme.colors.primary[300], - }, - }, - }, -})); - -const InfoContainer = () => { - const { pathname } = useLocation(); - - return ( - - - - {Environment.isWalletNewsEnabled() && ( - - News - - )} - - - Votes - - - - FAQ - - - - - {pathname === "/info" && } - - - - ); -}; diff --git a/src/components/TopBar/Wallet/__mocks__/mockFeedContent.tsx b/src/components/TopBar/Wallet/__mocks__/mockFeedContent.tsx deleted file mode 100644 index fefca768ca..0000000000 --- a/src/components/TopBar/Wallet/__mocks__/mockFeedContent.tsx +++ /dev/null @@ -1,30 +0,0 @@ -export const feedContent = [ - { - title: "Olympus Fundamentals: Encouraging Usability Through The Utility Pillar", - pubDate: "2022-03-31 22:05:22", - link: "https://olympusdao.medium.com/olympus-fundamentals-encouraging-usability-through-the-utility-pillar-68bcf11d5a85?source=rss-23e76a2f5695------2", - guid: "https://medium.com/p/68bcf11d5a85", - author: "OlympusDAO", - thumbnail: "https://cdn-images-1.medium.com/max/1024/0*ZTHo36X7c3PsAH5O", - description: - '\n

Ohmies,

\n

Welcome back to the final part of the Olympus Fundamental Series. If you’re new or need a refresher, you can read the first Olympus Foundations article, where we provide an overview of OlympusDAO and who we are, what we’re building, and why we’re doing it.

\n

Olympus is being built with three supporting structures:

\n
    \n
  1. \nReserve Pillar to establish Purchasing Power
  2. \n
  3. \nLiquidity Pillar to foster Universal Acceptance
  4. \n
  5. \nUtility Pillar to encourage High Usability
  6. \n
\n

In the last article, we dove deep into the Liquidity Pillar, which is responsible for OHM’s tradeability and universal acceptance as a deeply liquid asset. Prior to that, we explained the Reserve Pillar and its responsibility for OHM’s growth, stability, and positioning as a decentralized digital asset.

\n

With a solid reserve and robust liquidity pillar, the third and final supporting piece is the Utility Pillar.

\n

The Utility Pillar

\n

The Utility Pillar is responsible for how OHM is utilized throughout the digital economy. The ultimate purpose of having a trusted, backed, and deeply-liquid reserve asset is being able to use it with confidence. Whether that’s in the realm of decentralized finance, NFTs, or exploring the metaverse, we want to encourage anyone and everyone to use OHM across Web3. The concept of building utility can be categorized into two layers.

\n

The EconOHMy is the first layer of this pillar. For a thriving ecosystem, there must be protocols and DAOs who build products and services that utilize OHM. The work here is to find, develop, and support integrations and partnerships that promote OHM as a utility. We’ve already launched a way to kickstart this.

\n

Olympus Incubator & Grants:

\n

As mentioned in the last article, Olympus Incubator and Olympus Grants are our funding programs to bootstrap Olympus’ wider ecosystem. The incubator surpasses traditional “launchpads” by providing community support, mentorship, and effective strategies. Likewise, all of our grants will be directed to projects & contributors that directly advance Olympus in ways that synchronize with emergent priorities of the DAO. It will grow the econOHMy by finding ways to connect with markets and communities currently underserved by Web3. There are three key focuses to the Grants program:

\n
    \n
  1. \nEducation — projects that educate about Olympus
  2. \n
  3. \nInfrastructure — projects that improve/expand upon the infrastructure of Olympus
  4. \n
  5. \nUtility — projects that increase utility of OHM
  6. \n
\n

Partnerships:

\n

Olympus has welcomed over 40 partners and counting in the econOHMy. Below are some of the partners we’ve had the privilege of working with:

\n

Frax, Klima DAO, Redacted Cartel, Lobis, Rome, Alchemix, Dopex, Inverse, Tokemak, Umami Finance, Debt DAO, Vesta, Volt, Exodia, Liquity, Phantom DAO, Prime DAO, Spirit Swap & Fiat DAO.

\n

These aren’t just partnerships announcements for marketing’s sake. There are useful collaborations where Ohmies can use their OHM on many of these platforms. Here are some examples:

\n
    \n
  • \nBeethovenX — A leading DEX and Balancer fork on the Fantom network that allows for weighted investment pools with up to 8 Tokens, including gOHM.
  • \n
  • \nDopex — a decentralized options protocol which allows you to participate in Single Sided Options Vaults (SSOV). These vaults can earn you yield in USD or you can buy call & put options for a more in depth DeFi experience with your gOHM.
  • \n
  • \nJonesDAO — a managed yield, strategy, and liquidity protocol built atop of Dopex options.
  • \n
  • \nMarket — Lending and Borrowing Pools for gOHM on Avalanche & Polygon.
  • \n
  • \nRari Fuse- Lending and Borrowing Pools on Ethereum & Arbitrum.
  • \n
  • \nSynapse — a universal cross-chain liquidity network, use Synapse to bridge your gOHM to explore the multichain world!
  • \n
  • \nTokemak — an innovative multichain liquidity layer, deposit to their gOHM reactor to earn yield in the form of $TOKE.
  • \n
  • \nVesta — an Arbitrum-based collateralized debt platform to deposit and borrow with gOHM.
  • \n
\n

We’re excited to continue expanding utility in the econOHMy through these partners and many more to come. Just remember with any leverage products, please use your OHM responsibly.

\n

OlympusDAO will continue to explore this area and support solutions that utilize OHM for:

\n
    \n
  • \nCollateral — Protocols that accept gOHM as collateral to deposit and borrow against.
  • \n
  • \nMarketplaces — Apps and integrations that share our vision in furthering OHM as reserve currency.
  • \n
\n
A handy EconOHMy map by @yellah99

Mass-Adoption forms the second layer. The endgame has always been to bring mainstream audiences into Web3, DeFi, and the econOHMy. The DAO will incentivize initiatives that will bring OHM to the mainstream. These are things like:

\n
    \n
  • \nCEX listings — We aim to add OHM to Centralized Exchange (CEX) listings on market leaders such as Coinbase or Binance. Many new crypto users begin on CEXes because of they’re simplicity and availability to act as fiat on and off ramps. This brings OHM to 100s of millions of potential users, investors, and brand new Ohmies.
  • \n
  • \nReal-World Utility — Through partnerships like MoverDAO, we aim to make the use of gOHM as seamless as possible. Their platform makes it simple to top up a Visa debit card using gOHM, enabling you to buy groceries, pay your bills, and much more.
  • \n
  • \nMetaverse — As Web3 begins to explore and shape the metaverse, it’s our goal to ensure that Olympus has made its place in it. We are looking to integrate with GameFi and other metaverse initiatives that will onboard 100s of millions of users into crypto in innovative and interactive ways.
  • \n
\n

Olympus Odyssey:

\n

Odyssey is a sub-DAO of OlympusDAO aiming to build a liquid secondary market for NFTs as part of the Olympus ecosystem. An OHM-driven NFT marketplace started by and made for Ohmies. Soft launch and public launch dates will be announced in the spring of 2022.

\n
@Mushrohms by @OdysseyOlympus

We are also spearheading a new innovation in the crypto space that we believe will motivate anyone to join DeFi for beneficial causes.

\n

Olympus Give:

\n

Olympus Give is a revolutionary new way for Ohmies and the DeFi community at large to reverse any negative views the blockchain industry’s environmental impact or about DeFi being purely for profit. Olympus Give allows users to redirect their rebases to pre-selected Olympus Give causes or simply to any verified wallet of their choosing. This includes friends, family members, or community projects. Olympus does not take any fees whatsoever from this process because we are committed to empowering users to utilize the protocol as a seamless tool for public good. With every rebase, you are effortlessly donating to crypto ESG (environmental, social and governance) projects that are creating a real positive impact in the world.

\n

We launched Olympus GIve with 5 partners; Angel Protocol’s — Restore Earth, Gitcoin, ImpactMarket, Kolektivo and Popcorn. In V2 of Olympus Give, we added support for gOHM deposits and an option to redirect yield to any of our approved Olympus Grants recipients. Our plan for 2022 is to add many new partners and ways that the crypto community can utilize Olympus Give to support meaningful projects. Giving back to the global community is at the heart of what we do at Olympus and we couldn’t be more proud to lead the innovation in the field of DeFi for good.

\n

Welcome to Olympus

\n

That’s all the basics! You should now have a deep understanding of who we are at OlympusDAO, why our mission is important, what we’re doing about it, and how we’re delivering.

\n

If you made it this far, then you are a true Ohmie and we’d love for you to join us creating a better financial system. Head on over to our Discord and join our thriving community.

\n

Onward & upwards!

\n

About OlympusDAO

\n

Olympus is a decentralized financial reserve protocol that provides sustainable compounding interest through its community-owned and protected treasury.

\n

Twitter | Discord | Medium | Forum | Instagram

\n\n', - content: - '\n

Ohmies,

\n

Welcome back to the final part of the Olympus Fundamental Series. If you’re new or need a refresher, you can read the first Olympus Foundations article, where we provide an overview of OlympusDAO and who we are, what we’re building, and why we’re doing it.

\n

Olympus is being built with three supporting structures:

\n
    \n
  1. \nReserve Pillar to establish Purchasing Power
  2. \n
  3. \nLiquidity Pillar to foster Universal Acceptance
  4. \n
  5. \nUtility Pillar to encourage High Usability
  6. \n
\n

In the last article, we dove deep into the Liquidity Pillar, which is responsible for OHM’s tradeability and universal acceptance as a deeply liquid asset. Prior to that, we explained the Reserve Pillar and its responsibility for OHM’s growth, stability, and positioning as a decentralized digital asset.

\n

With a solid reserve and robust liquidity pillar, the third and final supporting piece is the Utility Pillar.

\n

The Utility Pillar

\n

The Utility Pillar is responsible for how OHM is utilized throughout the digital economy. The ultimate purpose of having a trusted, backed, and deeply-liquid reserve asset is being able to use it with confidence. Whether that’s in the realm of decentralized finance, NFTs, or exploring the metaverse, we want to encourage anyone and everyone to use OHM across Web3. The concept of building utility can be categorized into two layers.

\n

The EconOHMy is the first layer of this pillar. For a thriving ecosystem, there must be protocols and DAOs who build products and services that utilize OHM. The work here is to find, develop, and support integrations and partnerships that promote OHM as a utility. We’ve already launched a way to kickstart this.

\n

Olympus Incubator & Grants:

\n

As mentioned in the last article, Olympus Incubator and Olympus Grants are our funding programs to bootstrap Olympus’ wider ecosystem. The incubator surpasses traditional “launchpads” by providing community support, mentorship, and effective strategies. Likewise, all of our grants will be directed to projects & contributors that directly advance Olympus in ways that synchronize with emergent priorities of the DAO. It will grow the econOHMy by finding ways to connect with markets and communities currently underserved by Web3. There are three key focuses to the Grants program:

\n
    \n
  1. \nEducation — projects that educate about Olympus
  2. \n
  3. \nInfrastructure — projects that improve/expand upon the infrastructure of Olympus
  4. \n
  5. \nUtility — projects that increase utility of OHM
  6. \n
\n

Partnerships:

\n

Olympus has welcomed over 40 partners and counting in the econOHMy. Below are some of the partners we’ve had the privilege of working with:

\n

Frax, Klima DAO, Redacted Cartel, Lobis, Rome, Alchemix, Dopex, Inverse, Tokemak, Umami Finance, Debt DAO, Vesta, Volt, Exodia, Liquity, Phantom DAO, Prime DAO, Spirit Swap & Fiat DAO.

\n

These aren’t just partnerships announcements for marketing’s sake. There are useful collaborations where Ohmies can use their OHM on many of these platforms. Here are some examples:

\n
    \n
  • \nBeethovenX — A leading DEX and Balancer fork on the Fantom network that allows for weighted investment pools with up to 8 Tokens, including gOHM.
  • \n
  • \nDopex — a decentralized options protocol which allows you to participate in Single Sided Options Vaults (SSOV). These vaults can earn you yield in USD or you can buy call & put options for a more in depth DeFi experience with your gOHM.
  • \n
  • \nJonesDAO — a managed yield, strategy, and liquidity protocol built atop of Dopex options.
  • \n
  • \nMarket — Lending and Borrowing Pools for gOHM on Avalanche & Polygon.
  • \n
  • \nRari Fuse- Lending and Borrowing Pools on Ethereum & Arbitrum.
  • \n
  • \nSynapse — a universal cross-chain liquidity network, use Synapse to bridge your gOHM to explore the multichain world!
  • \n
  • \nTokemak — an innovative multichain liquidity layer, deposit to their gOHM reactor to earn yield in the form of $TOKE.
  • \n
  • \nVesta — an Arbitrum-based collateralized debt platform to deposit and borrow with gOHM.
  • \n
\n

We’re excited to continue expanding utility in the econOHMy through these partners and many more to come. Just remember with any leverage products, please use your OHM responsibly.

\n

OlympusDAO will continue to explore this area and support solutions that utilize OHM for:

\n
    \n
  • \nCollateral — Protocols that accept gOHM as collateral to deposit and borrow against.
  • \n
  • \nMarketplaces — Apps and integrations that share our vision in furthering OHM as reserve currency.
  • \n
\n
A handy EconOHMy map by @yellah99

Mass-Adoption forms the second layer. The endgame has always been to bring mainstream audiences into Web3, DeFi, and the econOHMy. The DAO will incentivize initiatives that will bring OHM to the mainstream. These are things like:

\n
    \n
  • \nCEX listings — We aim to add OHM to Centralized Exchange (CEX) listings on market leaders such as Coinbase or Binance. Many new crypto users begin on CEXes because of they’re simplicity and availability to act as fiat on and off ramps. This brings OHM to 100s of millions of potential users, investors, and brand new Ohmies.
  • \n
  • \nReal-World Utility — Through partnerships like MoverDAO, we aim to make the use of gOHM as seamless as possible. Their platform makes it simple to top up a Visa debit card using gOHM, enabling you to buy groceries, pay your bills, and much more.
  • \n
  • \nMetaverse — As Web3 begins to explore and shape the metaverse, it’s our goal to ensure that Olympus has made its place in it. We are looking to integrate with GameFi and other metaverse initiatives that will onboard 100s of millions of users into crypto in innovative and interactive ways.
  • \n
\n

Olympus Odyssey:

\n

Odyssey is a sub-DAO of OlympusDAO aiming to build a liquid secondary market for NFTs as part of the Olympus ecosystem. An OHM-driven NFT marketplace started by and made for Ohmies. Soft launch and public launch dates will be announced in the spring of 2022.

\n
@Mushrohms by @OdysseyOlympus

We are also spearheading a new innovation in the crypto space that we believe will motivate anyone to join DeFi for beneficial causes.

\n

Olympus Give:

\n

Olympus Give is a revolutionary new way for Ohmies and the DeFi community at large to reverse any negative views the blockchain industry’s environmental impact or about DeFi being purely for profit. Olympus Give allows users to redirect their rebases to pre-selected Olympus Give causes or simply to any verified wallet of their choosing. This includes friends, family members, or community projects. Olympus does not take any fees whatsoever from this process because we are committed to empowering users to utilize the protocol as a seamless tool for public good. With every rebase, you are effortlessly donating to crypto ESG (environmental, social and governance) projects that are creating a real positive impact in the world.

\n

We launched Olympus GIve with 5 partners; Angel Protocol’s — Restore Earth, Gitcoin, ImpactMarket, Kolektivo and Popcorn. In V2 of Olympus Give, we added support for gOHM deposits and an option to redirect yield to any of our approved Olympus Grants recipients. Our plan for 2022 is to add many new partners and ways that the crypto community can utilize Olympus Give to support meaningful projects. Giving back to the global community is at the heart of what we do at Olympus and we couldn’t be more proud to lead the innovation in the field of DeFi for good.

\n

Welcome to Olympus

\n

That’s all the basics! You should now have a deep understanding of who we are at OlympusDAO, why our mission is important, what we’re doing about it, and how we’re delivering.

\n

If you made it this far, then you are a true Ohmie and we’d love for you to join us creating a better financial system. Head on over to our Discord and join our thriving community.

\n

Onward & upwards!

\n

About OlympusDAO

\n

Olympus is a decentralized financial reserve protocol that provides sustainable compounding interest through its community-owned and protected treasury.

\n

Twitter | Discord | Medium | Forum | Instagram

\n\n', - enclosure: {}, - categories: ["ohm", "defi", "crypto-education", "olympus"], - }, - { - title: "The Olympus Treasury Dashboard", - pubDate: "2022-03-25 13:41:02", - link: "https://olympusdao.medium.com/the-olympus-treasury-dashboard-1e03b202ab4b?source=rss-23e76a2f5695------2", - guid: "https://medium.com/p/1e03b202ab4b", - author: "OlympusDAO", - thumbnail: "https://cdn-images-1.medium.com/max/1024/0*LZtL3zNL2J9G6ejx", - description: - '\n

One of the most incredible facets of DeFi organizations is the fact that most things on the balance sheet are transparent if you know where to look. It is commonplace for protocols to list all of their smart contracts, treasury addresses, and multi-sig wallets in their official documents so that DeFi participants can see, on the ledger of the blockchain, what those protocols are holding. However, this is a double-edged sword. That information is often quite tedious to sift through, and may take you across many different block explorers or through multiple chains just to figure out where everything is.

\n

Olympus disrupts all of this with the new Treasury Dashboard.

\n

In an effort to bring you the most transparency with the least amount of investigation as possible, we constructed a centralized location where all of our decentralized assets can be viewed. Partnering with Multifarm, we are creating a dashboard that includes every bit of information you would ever need or want to know about the Treasury; its strategies, its held positions, and more. Allow this document to act as a guide to using the Treasury Dashboard.

\n

Let’s dive into some of the components:

\n

Overview

\n

This is the same section you know and love, which greets you when you enter the Olympus app every day to check your balances and see how the market is shaping up. We haven’t changed this at all as it already does a great job of giving you a bird’s eye view of Olympus at any given moment. The way we see it — if it ain’t broke, don’t fix it!

\n

Treasury

\n

Here is where things will begin to diverge from what you know and start to expand transparency for the average Ohmie. The treasury tab is broken down into 5 parts: portfolio, category, farm, strategies, and OHM backing.

\n

The Portfolio section displays all assets that are held by the Treasury, what blockchain those assets live on, and in what amounts they are held in. There are tooltips throughout each selection explaining the differences in the effort of true transparency, one of our main goals is to have everything plainly understood.

\n
Treasury Portfolio

The Category section takes the portfolio a step further by breaking down all of the assets in each of their categorical groups. These being: reserve assets, protocol-owned liquidity, Olympus branch, Incubator, strategic assets, Olympus Pro, and an “other” section for assets that don’t quite fit into the previous categories.

\n
Treasury Categories

The next section, Farm, gives a serious analysis of all of Olympus Treasury’s farming positions, the amount of which those positions represent of the overall holdings, and the monthly revenue from our assets held on the behalf of our DAO partners.

\n
Treasury Farms

Following this is Strategies, arguably one of the most important pages on the entire dashboard. Strategies will give Ohmies insight into the methods and mechanisms of the Treasury, and present each minutia of detail that goes into the strategy decisions behind the Treasury’s interest in certain assets. In complete transparency, you can now see what actions are taken by the Treasury of Olympus and why.

\n
Treasury Strategies

The last section is $OHM Backing, which will be incredibly insightful for those who have been intrigued by our recent release of Inverse Bonds. Laid out for you in descending dollar denomination is each liquid piece of an $OHM token. Ohmies can see exactly what is backing their currency at any given time, giving them translucent optics into the best backed token in DeFi.

\n
Treasury $OHM Backing

Revenue

\n

Moving along from the Treasury tab, one can pan to the right and head to the Revenue tab. Inside of this branch of the dashboard, you get access to live numbers from each action of the Olympus Treasury that brings in revenue. That revenue in turn goes towards creating new OHM tokens and backing existing ones.

\n

Things are split up by section again here, with each section containing complete and detailed information, graphs, and analysis that seek to further expand our user’s scope of the revenue generated by the Olympus Treasury.

\n

The first section in Revenue is the Revenue Type. This is a simple and clear depiction of monthly revenue split into its different components. You’ll be able to see a line graph that tracks daily revenue over time for easy optics.

\n
Revenue Type

Next up is Farming Detailed, a section that shares a lot of common themes as the Farm section in the previous tab, but just adds more detail and color. Be sure to check out the daily earnings accumulated graph at the bottom to see the daily income from different productive assets that the DAO holds.

\n

Just a note: there will be more updates to this page in the coming weeks. We are currently in the process of deploying $66M+ more capital in productive assets to produce greater backing for OHM.

\n
Detailed Revenue Farming

Now shift your attention over to the Olympus Pro section. Since Olympus Pro is one of our most robust projects, it boasts one of the most robust revenue portions of the Treasury Dashboard. Contained in here is a complete list of OP revenue generated in the past 30 days or the past 24 hours; complemented by a visual of the daily earnings.

\n

Just take a quick look to check the recent earnings, or do a deep dive and see all your favorite protocol’s earnings from the last month, it’s up to you anon.

\n
Olympus Pro Revenue

After that is another one of the most important sections, especially for Olympus, that being the Bonding section. Here you will be able to see each bond purchased in the last day or throughout the last month, with daily earnings tracked graphically at the bottom. This is a powerful section of the dashboard if you are a bonder looking to see what the current bond purchasing market is like, but also for investors aiming to understand the influence bonds play upon the Olympus ecosystem.

\n
Bonding Revenue

We saved some of the best for last in the revenue tab. Revenue Agreements lay out a nice parcel of Olympus’ sphere of influence in the DeFi economy in opaque fashion. This section succinctly outlines revenues collected from three main partners in the ecOHMsystem: Redacted, Convex, and Toke. Our agreements to allocate treasury assets to these aligned SubDAOs is part of the protocol’s mission to increase revenue and expand the econOHMy defined in Olympus12.

\n
Revenue Agreements

Last, but not least, is Votium — which seems bare at the moment but will become more fleshed out as Olympus begins to allocate more treasury assets to some of these protocol services. There are some services being built by our direct partners that will influence the look of this part of the dashboard in the coming months.

\n

Olympus Pro

\n

As previously mentioned, Olympus Pro is an integral cog in the machine that is the Olympus Treasury. It creates value in revenue, but also in intangibles such as partnerships. Due to this, we simply could not resist giving Olympus Pro its time to shine. The tab adjacent to revenue is purely dedicated to Olympus Pro and the classification of everything the product encompasses in easy to digest formats.

\n

The Olympus Pro Treasury graph paints a picture of a thriving cornerstone of Olympus’ growth while the Olympus Pro Revenue graph picks up the pace by giving you a daily breakdown of the top bonded partners. You can also view all active Olympus Pro partners, see the value per chain, and the income per partner.

\n

With the release of permission less Olympus Pro right around the corner, there could not have been a better time for this dashboard to come about. When that unlock comes, the amount of data collected and shown on this area of the dashboard will be astronomical.

\n
Olympus Pro Overview

Proteus

\n

There is one last tab to the Treasury Dashboard that is intrinsically important to understanding the future evolution of Olympus as a reserve currency. Olympus plans to be everywhere on all chains, and Proteus is our means to do so and our metric to measure our performance. We kid you not when we say that the Proteus page contains the playbook for what you can be doing with your $gOHM, on what chain, and how that benefits Ohmies.

\n
Protocol $gOHM Reserves

We have all of the critical information located here; breakdown of chain liquidity, available DEX partners, and a leaderboard of protocol-owned $gOHM reserves. However, the most potent inclusion to this tab must be the ‘How to use $gOHM’ section at the very bottom. Scroll there and you will find all of the incredible projects that we have partnered with to bring you utility across the many chains that we support. This page will constantly be updated as we add new utility options — you’ll even see some of our upcoming features that haven’t even dropped yet!

\n
$gOHM Utility

Why Make This Upgrade?

\n

Well, the answer to this question is fairly simple, because we care deeply about two main principles:

\n
    \n
  1. Transparency towards our community
  2. \n
  3. Preserving the decentralized spirit of DeFi
  4. \n
\n

We cannot in good faith obfuscate the truth in a DeFi environment where many go to lengths to make information on Treasury holdings and allocations difficult or downright impossible to find. We welcome any and all interested in what we are doing here at Olympus to examine our Treasury with scrutiny and make an informed decision for them based on what they find. All of the data is there for you Ohmies, it is for you to interpret how you may.

\n

Through this endeavor, we preserve the decentralized spirit of DeFi and mark an example for other protocols to follow. We hope that our community resonates with this decision and uses the Treasury Dashboard to attain a greater understanding of the ways the protocol works for Ohmies.

\n

About OlympusDAO

\n

Olympus is a decentralized financial reserve protocol that provides sustainable compounding interest through its community-owned and protected treasury.

\n

Twitter | Discord | Medium | Forum | Instagram

\n\n', - content: - '\n

One of the most incredible facets of DeFi organizations is the fact that most things on the balance sheet are transparent if you know where to look. It is commonplace for protocols to list all of their smart contracts, treasury addresses, and multi-sig wallets in their official documents so that DeFi participants can see, on the ledger of the blockchain, what those protocols are holding. However, this is a double-edged sword. That information is often quite tedious to sift through, and may take you across many different block explorers or through multiple chains just to figure out where everything is.

\n

Olympus disrupts all of this with the new Treasury Dashboard.

\n

In an effort to bring you the most transparency with the least amount of investigation as possible, we constructed a centralized location where all of our decentralized assets can be viewed. Partnering with Multifarm, we are creating a dashboard that includes every bit of information you would ever need or want to know about the Treasury; its strategies, its held positions, and more. Allow this document to act as a guide to using the Treasury Dashboard.

\n

Let’s dive into some of the components:

\n

Overview

\n

This is the same section you know and love, which greets you when you enter the Olympus app every day to check your balances and see how the market is shaping up. We haven’t changed this at all as it already does a great job of giving you a bird’s eye view of Olympus at any given moment. The way we see it — if it ain’t broke, don’t fix it!

\n

Treasury

\n

Here is where things will begin to diverge from what you know and start to expand transparency for the average Ohmie. The treasury tab is broken down into 5 parts: portfolio, category, farm, strategies, and OHM backing.

\n

The Portfolio section displays all assets that are held by the Treasury, what blockchain those assets live on, and in what amounts they are held in. There are tooltips throughout each selection explaining the differences in the effort of true transparency, one of our main goals is to have everything plainly understood.

\n
Treasury Portfolio

The Category section takes the portfolio a step further by breaking down all of the assets in each of their categorical groups. These being: reserve assets, protocol-owned liquidity, Olympus branch, Incubator, strategic assets, Olympus Pro, and an “other” section for assets that don’t quite fit into the previous categories.

\n
Treasury Categories

The next section, Farm, gives a serious analysis of all of Olympus Treasury’s farming positions, the amount of which those positions represent of the overall holdings, and the monthly revenue from our assets held on the behalf of our DAO partners.

\n
Treasury Farms

Following this is Strategies, arguably one of the most important pages on the entire dashboard. Strategies will give Ohmies insight into the methods and mechanisms of the Treasury, and present each minutia of detail that goes into the strategy decisions behind the Treasury’s interest in certain assets. In complete transparency, you can now see what actions are taken by the Treasury of Olympus and why.

\n
Treasury Strategies

The last section is $OHM Backing, which will be incredibly insightful for those who have been intrigued by our recent release of Inverse Bonds. Laid out for you in descending dollar denomination is each liquid piece of an $OHM token. Ohmies can see exactly what is backing their currency at any given time, giving them translucent optics into the best backed token in DeFi.

\n
Treasury $OHM Backing

Revenue

\n

Moving along from the Treasury tab, one can pan to the right and head to the Revenue tab. Inside of this branch of the dashboard, you get access to live numbers from each action of the Olympus Treasury that brings in revenue. That revenue in turn goes towards creating new OHM tokens and backing existing ones.

\n

Things are split up by section again here, with each section containing complete and detailed information, graphs, and analysis that seek to further expand our user’s scope of the revenue generated by the Olympus Treasury.

\n

The first section in Revenue is the Revenue Type. This is a simple and clear depiction of monthly revenue split into its different components. You’ll be able to see a line graph that tracks daily revenue over time for easy optics.

\n
Revenue Type

Next up is Farming Detailed, a section that shares a lot of common themes as the Farm section in the previous tab, but just adds more detail and color. Be sure to check out the daily earnings accumulated graph at the bottom to see the daily income from different productive assets that the DAO holds.

\n

Just a note: there will be more updates to this page in the coming weeks. We are currently in the process of deploying $66M+ more capital in productive assets to produce greater backing for OHM.

\n
Detailed Revenue Farming

Now shift your attention over to the Olympus Pro section. Since Olympus Pro is one of our most robust projects, it boasts one of the most robust revenue portions of the Treasury Dashboard. Contained in here is a complete list of OP revenue generated in the past 30 days or the past 24 hours; complemented by a visual of the daily earnings.

\n

Just take a quick look to check the recent earnings, or do a deep dive and see all your favorite protocol’s earnings from the last month, it’s up to you anon.

\n
Olympus Pro Revenue

After that is another one of the most important sections, especially for Olympus, that being the Bonding section. Here you will be able to see each bond purchased in the last day or throughout the last month, with daily earnings tracked graphically at the bottom. This is a powerful section of the dashboard if you are a bonder looking to see what the current bond purchasing market is like, but also for investors aiming to understand the influence bonds play upon the Olympus ecosystem.

\n
Bonding Revenue

We saved some of the best for last in the revenue tab. Revenue Agreements lay out a nice parcel of Olympus’ sphere of influence in the DeFi economy in opaque fashion. This section succinctly outlines revenues collected from three main partners in the ecOHMsystem: Redacted, Convex, and Toke. Our agreements to allocate treasury assets to these aligned SubDAOs is part of the protocol’s mission to increase revenue and expand the econOHMy defined in Olympus12.

\n
Revenue Agreements

Last, but not least, is Votium — which seems bare at the moment but will become more fleshed out as Olympus begins to allocate more treasury assets to some of these protocol services. There are some services being built by our direct partners that will influence the look of this part of the dashboard in the coming months.

\n

Olympus Pro

\n

As previously mentioned, Olympus Pro is an integral cog in the machine that is the Olympus Treasury. It creates value in revenue, but also in intangibles such as partnerships. Due to this, we simply could not resist giving Olympus Pro its time to shine. The tab adjacent to revenue is purely dedicated to Olympus Pro and the classification of everything the product encompasses in easy to digest formats.

\n

The Olympus Pro Treasury graph paints a picture of a thriving cornerstone of Olympus’ growth while the Olympus Pro Revenue graph picks up the pace by giving you a daily breakdown of the top bonded partners. You can also view all active Olympus Pro partners, see the value per chain, and the income per partner.

\n

With the release of permission less Olympus Pro right around the corner, there could not have been a better time for this dashboard to come about. When that unlock comes, the amount of data collected and shown on this area of the dashboard will be astronomical.

\n
Olympus Pro Overview

Proteus

\n

There is one last tab to the Treasury Dashboard that is intrinsically important to understanding the future evolution of Olympus as a reserve currency. Olympus plans to be everywhere on all chains, and Proteus is our means to do so and our metric to measure our performance. We kid you not when we say that the Proteus page contains the playbook for what you can be doing with your $gOHM, on what chain, and how that benefits Ohmies.

\n
Protocol $gOHM Reserves

We have all of the critical information located here; breakdown of chain liquidity, available DEX partners, and a leaderboard of protocol-owned $gOHM reserves. However, the most potent inclusion to this tab must be the ‘How to use $gOHM’ section at the very bottom. Scroll there and you will find all of the incredible projects that we have partnered with to bring you utility across the many chains that we support. This page will constantly be updated as we add new utility options — you’ll even see some of our upcoming features that haven’t even dropped yet!

\n
$gOHM Utility

Why Make This Upgrade?

\n

Well, the answer to this question is fairly simple, because we care deeply about two main principles:

\n
    \n
  1. Transparency towards our community
  2. \n
  3. Preserving the decentralized spirit of DeFi
  4. \n
\n

We cannot in good faith obfuscate the truth in a DeFi environment where many go to lengths to make information on Treasury holdings and allocations difficult or downright impossible to find. We welcome any and all interested in what we are doing here at Olympus to examine our Treasury with scrutiny and make an informed decision for them based on what they find. All of the data is there for you Ohmies, it is for you to interpret how you may.

\n

Through this endeavor, we preserve the decentralized spirit of DeFi and mark an example for other protocols to follow. We hope that our community resonates with this decision and uses the Treasury Dashboard to attain a greater understanding of the ways the protocol works for Ohmies.

\n

About OlympusDAO

\n

Olympus is a decentralized financial reserve protocol that provides sustainable compounding interest through its community-owned and protected treasury.

\n

Twitter | Discord | Medium | Forum | Instagram

\n\n', - enclosure: {}, - categories: ["olympus", "dashboard", "ohm", "defi", "treasury"], - }, -]; diff --git a/src/components/TopBar/Wallet/__mocks__/mockProposalContent.tsx b/src/components/TopBar/Wallet/__mocks__/mockProposalContent.tsx deleted file mode 100644 index af39cfa08c..0000000000 --- a/src/components/TopBar/Wallet/__mocks__/mockProposalContent.tsx +++ /dev/null @@ -1,28 +0,0 @@ -export const proposalContent = [ - { - id: "0x807d75e51065c6d28651bf77627425cdac5835bd192c181a5186efe1d4042096", - title: "OIP-88: KlimaDAO Love Letter", - body: "**Summary:** KlimaDAO is about to launch a Love Letter to the Planet campaign, and we want to invite you to be a part of it. This campaign publicizes the launch of the Klima retirement aggregator which allows individuals and organizations to offset their carbon footprint on the Polygon network.\n\n**Proposal:** OlympusDAO to become an official partner of Klima Infinity and to offset 33,333.33 or 3,333.33 tonnes of carbon via the KlimaDAO retirement aggregator. Depending on the carbon asset (BCT vs MCO2) Olympus would need to retire 5186 or 509 respectively of KLIMA to offset based on BCT retirement. This would be 3.5% or 0.34% of the current staked amount in Olympus’ treasury which is approximately 147k KLIMA.\n\nMore context in the forum post.", - choices: ["In support, retire 33,333 tonnes", "In support, retire 3,333 tonnes", "Don't support"], - start: 1649011647, - end: 1649347200, - snapshot: "14514830", - state: "active", - author: "0x389b11C4fA4b95bCc252A2B20Bb62310Fbc36746", - link: "https://snapshot.org/#/olympusdao.eth/proposal/0x807d75e51065c6d28651bf77627425cdac5835bd192c181a5186efe1d4042096", - scores: [31781.74951970862, 5083.465548664648, 21334.0218350948], - }, - { - id: "0x70babccd32c31752f60275e0b2045b1bb73c7a98606fed54c0b54f6c2f7e1e62", - title: "TAP-9 Rocket Pool Whitelist", - body: "Summary: Seek authority from the community to whitelist Rocket Pool for staking of idle ETH reserve.\n\nBackground: Recently the DAO has been accumulating additional ETH reserves assets such via OIP-15: Add ETH to the Treasury. The DAO is now seeking the ability to stake idle reserve ETH in Rocket Pool to further increase the backing of OHM and to support the overall Ethereum Network.\n\nMotivation: Whitelisting Rocket Pool will allow Olympus to earn yield on idle ETH reserve and to help support the Ethereum network and grow the treasury. The DAO will adhere to the treasury framework of no more than 25% of excess reserve assets to a protocol. However, this is just a limit and the DAO will assess the optimal distribution on a per asset basis.\n\nDescription from https://rocketpool.net/: Rocket Pool is a first of its kind ETH2 Proof of Stake Protocol, designed to be community owned, decentralized, trustless and compatible with staking in Ethereum 2.0. It was first conceived in late 2016 and has since had over 5 successful public betas over the life span of ETH2 development. Rocket Pool strives to embody the core ethos of Ethereum and DeFi, specifically the non-custodial, trustless nature that allows self-sovereignty to truly thrive. The core premise behind a protocol is to ensure the network is not beholden to any one party. This is a principle directly linked to Ethereum and ETH2 itself, and a mindset used at every stage of the process as Rocket Pool has evolved.\n\nRisks: The protocol allocates the ETH to a decentralized node network for it to be staked. These nodes are operated in a trustless manner and the trust lies within the node operator to maintain adequate up-time. In the event of funds slashed due to inadequate presence for network validation, the node operator will forfeit RPL. Once funds are staked there is a finite number of ways to exit the staked position, Olympus can swap out of this particular position via DEXs but it can lead to potential slippage. The protocol operates in a trust minimized system that is controlled via smart contracts where there are assumption made on the behavior of node operators. A potential exploitation was brought to the team from a competitor but promptly acknowledged and fixed.\n\nProtocol Analysis: Using a risk analysis framework developed by the DAO, the Policy and Partnerships teams have attempted to score various protocols based on some subjective and non-subjective data. Rocket Pool scored a 5.2 out of 10. This is due to inherent risks associated with Ether staking for the Ethereum 2.0 upgrade.\n\nThe following risk analysis shows the outcome of the Treasury Team's holistic assessment of the proposed platform and intended strategies. Lastly, one final reminder that this score is an average that was derived from an generalized assessment of the platform which includes TVL, audits, protocol age/risk, targeted investment and strategy type.\nhttps://docs.google.com/spreadsheets/d/1p-FWa18Q-PD5V5WWadzSZcTMZSUM4QZBzMnmPloMFmk/edit?usp=sharing\n\nRequest for comment: https://forum.olympusdao.finance/d/1128-request-for-comment-rocket-pool-whitelist/8\n\nTAP-9 Forum post: https://forum.olympusdao.finance/d/1132-tap-9-rocket-pool-whitelist", - choices: ["Approve TAP-9", "Reject TAP-9"], - start: 1648434935, - end: 1648694135, - snapshot: "14472031", - state: "closed", - author: "0x389b11C4fA4b95bCc252A2B20Bb62310Fbc36746", - link: "https://snapshot.org/#/olympusdao.eth/proposal/0x70babccd32c31752f60275e0b2045b1bb73c7a98606fed54c0b54f6c2f7e1e62", - scores: [110846.11296222758, 66.66572722910414], - }, -]; diff --git a/src/components/TopBar/Wallet/__mocks__/mockTransactionHistory.tsx b/src/components/TopBar/Wallet/__mocks__/mockTransactionHistory.tsx deleted file mode 100644 index 13a250f591..0000000000 --- a/src/components/TopBar/Wallet/__mocks__/mockTransactionHistory.tsx +++ /dev/null @@ -1,909 +0,0 @@ -import { DecimalBigNumber } from "src/helpers/DecimalBigNumber/DecimalBigNumber"; - -export const bondPurchaseTransaction = { - token: { - name: "OHM", - addresses: { - "1": "0x64aa3364f17a4d01c6f1751fd97c2bd3d7e7f1d5", - "4": "0xd7B98050962ec7cC8D11a83446B3217257C754B7", - }, - _contractCache: {}, - icons: ["OHM"], - decimals: 9, - purchaseUrl: - "https://app.sushi.com/swap?inputCurrency=0x6b175474e89094c44da98b954eedeac495271d0f&outputCurrency=0x64aa3364f17a4d01c6f1751fd97c2bd3d7e7f1d5", - }, - transaction: { - block_signed_at: "2022-01-30T09:24:57Z", - block_height: 0, - tx_hash: "", - tx_offset: 267, - successful: true, - from_address: "0xDd1E5f42baA201050c4686FDF4e3FDE16A58BC6F", - from_address_label: null, - to_address: "0x9025046c6fb25fb39e720d97a8fd881ed69a1ef6", - to_address_label: null, - value: "0", - value_quote: 0, - gas_offered: 280570, - gas_spent: 255870, - gas_price: 58123484348, - gas_quote: 39.07767766744055, - gas_quote_rate: 2627.5908203125, - log_events: [ - { - block_signed_at: "2022-01-30T09:24:57Z", - block_height: 0, - tx_offset: 267, - log_offset: 339, - tx_hash: "", - raw_log_topics: [ - "0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925", - "0x0000000000000000000000008d7a5fedf55b68625b2e5953f8203b029cb9c44e", - "0x0000000000000000000000009025046c6fb25fb39e720d97a8fd881ed69a1ef6", - ], - sender_contract_decimals: 18, - sender_name: "Frax", - sender_contract_ticker_symbol: "FRAX", - sender_address: "0x853d955acef822db058eb8505911ed77f175b99e", - sender_address_label: "Frax (FRAX)", - sender_logo_url: "https://logos.covalenthq.com/tokens/0x853d955acef822db058eb8505911ed77f175b99e.png", - raw_log_data: "0x000000000000000000000000000000000000007e37bdffebf51e230431766906", - decoded: { - name: "Approval", - signature: "Approval(indexed address owner, indexed address spender, uint256 value)", - params: [ - { - name: "owner", - type: "address", - indexed: true, - decoded: true, - value: "0xDd1E5f42baA201050c4686FDF4e3FDE16A58BC6F", - }, - { - name: "spender", - type: "address", - indexed: true, - decoded: true, - value: "0x9025046c6fb25fb39e720d97a8fd881ed69a1ef6", - }, - { - name: "value", - type: "uint256", - indexed: false, - decoded: true, - value: "9999999847873488262851204638982", - }, - ], - }, - }, - { - block_signed_at: "2022-01-30T09:24:57Z", - block_height: 0, - tx_offset: 267, - log_offset: 338, - tx_hash: "", - raw_log_topics: [ - "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef", - "0x0000000000000000000000008d7a5fedf55b68625b2e5953f8203b029cb9c44e", - "0x0000000000000000000000009a315bdf513367c0377fb36545857d12e85813ef", - ], - sender_contract_decimals: 18, - sender_name: "Frax", - sender_contract_ticker_symbol: "FRAX", - sender_address: "0x853d955acef822db058eb8505911ed77f175b99e", - sender_address_label: "Frax (FRAX)", - sender_logo_url: "https://logos.covalenthq.com/tokens/0x853d955acef822db058eb8505911ed77f175b99e.png", - raw_log_data: "0x000000000000000000000000000000000000000000000eb79b080e27365a23a2", - decoded: { - name: "Transfer", - signature: "Transfer(indexed address from, indexed address to, uint256 value)", - params: [ - { - name: "from", - type: "address", - indexed: true, - decoded: true, - value: "0xDd1E5f42baA201050c4686FDF4e3FDE16A58BC6F", - }, - { - name: "to", - type: "address", - indexed: true, - decoded: true, - value: "0x9a315bdf513367c0377fb36545857d12e85813ef", - }, - { - name: "value", - type: "uint256", - indexed: false, - decoded: true, - value: "69500056120101151843234", - }, - ], - }, - }, - { - block_signed_at: "2022-01-30T09:24:57Z", - block_height: 0, - tx_offset: 267, - log_offset: 337, - tx_hash: "", - raw_log_topics: [ - "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef", - "0x0000000000000000000000000ab87046fbb341d058f17cbc4c1133f25a20a52f", - "0x0000000000000000000000009025046c6fb25fb39e720d97a8fd881ed69a1ef6", - ], - sender_contract_decimals: 18, - sender_name: "Governance OHM", - sender_contract_ticker_symbol: "gOHM", - sender_address: "0x0ab87046fbb341d058f17cbc4c1133f25a20a52f", - sender_address_label: null, - sender_logo_url: "https://logos.covalenthq.com/tokens/0x0ab87046fbb341d058f17cbc4c1133f25a20a52f.png", - raw_log_data: "0x000000000000000000000000000000000000000000000000d6eb39e73818731c", - decoded: { - name: "Transfer", - signature: "Transfer(indexed address from, indexed address to, uint256 value)", - params: [ - { - name: "from", - type: "address", - indexed: true, - decoded: true, - value: "0x0ab87046fbb341d058f17cbc4c1133f25a20a52f", - }, - { - name: "to", - type: "address", - indexed: true, - decoded: true, - value: "0x9025046c6fb25fb39e720d97a8fd881ed69a1ef6", - }, - { - name: "value", - type: "uint256", - indexed: false, - decoded: true, - value: "15486535408884937500", - }, - ], - }, - }, - { - block_signed_at: "2022-01-30T09:24:57Z", - block_height: 14106332, - tx_offset: 267, - log_offset: 336, - tx_hash: "", - raw_log_topics: [ - "0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925", - "0x0000000000000000000000009025046c6fb25fb39e720d97a8fd881ed69a1ef6", - "0x000000000000000000000000b63cac384247597756545b500253ff8e607a8020", - ], - sender_contract_decimals: 9, - sender_name: "Olympus", - sender_contract_ticker_symbol: "OHM", - sender_address: "0x64aa3364f17a4d01c6f1751fd97c2bd3d7e7f1d5", - sender_address_label: null, - sender_logo_url: "https://logos.covalenthq.com/tokens/0x64aa3364f17a4d01c6f1751fd97c2bd3d7e7f1d5.png", - raw_log_data: "0x000000000000000000000000002cd76fe086b93ce2f768a00b220fbd13143896", - decoded: { - name: "Approval", - signature: "Approval(indexed address owner, indexed address spender, uint256 value)", - params: [ - { - name: "owner", - type: "address", - indexed: true, - decoded: true, - value: "0x9025046c6fb25fb39e720d97a8fd881ed69a1ef6", - }, - { - name: "spender", - type: "address", - indexed: true, - decoded: true, - value: "0xb63cac384247597756545b500253ff8e607a8020", - }, - { - name: "value", - type: "uint256", - indexed: false, - decoded: true, - value: "999999999999999999999999999999841382882883734", - }, - ], - }, - }, - { - block_signed_at: "2022-01-30T09:24:57Z", - block_height: 14106332, - tx_offset: 267, - log_offset: 335, - tx_hash: "", - raw_log_topics: [ - "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef", - "0x0000000000000000000000009025046c6fb25fb39e720d97a8fd881ed69a1ef6", - "0x000000000000000000000000b63cac384247597756545b500253ff8e607a8020", - ], - sender_contract_decimals: 9, - sender_name: "Olympus", - sender_contract_ticker_symbol: "OHM", - sender_address: "0x64aa3364f17a4d01c6f1751fd97c2bd3d7e7f1d5", - sender_address_label: null, - sender_logo_url: "https://logos.covalenthq.com/tokens/0x64aa3364f17a4d01c6f1751fd97c2bd3d7e7f1d5.png", - raw_log_data: "0x0000000000000000000000000000000000000000000000000000010d7cef8424", - decoded: { - name: "Transfer", - signature: "Transfer(indexed address from, indexed address to, uint256 value)", - params: [ - { - name: "from", - type: "address", - indexed: true, - decoded: true, - value: "0x9025046c6fb25fb39e720d97a8fd881ed69a1ef6", - }, - { - name: "to", - type: "address", - indexed: true, - decoded: true, - value: "0xb63cac384247597756545b500253ff8e607a8020", - }, - { - name: "value", - type: "uint256", - indexed: false, - decoded: true, - value: "1157442274340", - }, - ], - }, - }, - { - block_signed_at: "2022-01-30T09:24:57Z", - block_height: 14106332, - tx_offset: 267, - log_offset: 334, - tx_hash: "", - raw_log_topics: [ - "0x9d228d69b5fdb8d273a2336f8fb8612d039631024ea9bf09c424a9503aa078f0", - "0x0000000000000000000000009025046c6fb25fb39e720d97a8fd881ed69a1ef6", - "0x0000000000000000000000009025046c6fb25fb39e720d97a8fd881ed69a1ef6", - ], - sender_contract_decimals: 0, - sender_name: null, - sender_contract_ticker_symbol: null, - sender_address: "0x9a315bdf513367c0377fb36545857d12e85813ef", - sender_address_label: null, - sender_logo_url: "https://logos.covalenthq.com/tokens/1/0x9a315bdf513367c0377fb36545857d12e85813ef.png", - raw_log_data: "0x0000000000000000000000000000000000000000000000000000010d7cef8424", - decoded: { - name: "Minted", - signature: "Minted(indexed address recipient, address gauge, uint256 minted)", - params: null, - }, - }, - { - block_signed_at: "2022-01-30T09:24:57Z", - block_height: 14106332, - tx_offset: 267, - log_offset: 333, - tx_hash: "", - raw_log_topics: [ - "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000009025046c6fb25fb39e720d97a8fd881ed69a1ef6", - ], - sender_contract_decimals: 9, - sender_name: "Olympus", - sender_contract_ticker_symbol: "OHM", - sender_address: "0x64aa3364f17a4d01c6f1751fd97c2bd3d7e7f1d5", - sender_address_label: null, - sender_logo_url: "https://logos.covalenthq.com/tokens/0x64aa3364f17a4d01c6f1751fd97c2bd3d7e7f1d5.png", - raw_log_data: "0x0000000000000000000000000000000000000000000000000000010d7cef8424", - decoded: { - name: "Transfer", - signature: "Transfer(indexed address from, indexed address to, uint256 value)", - params: [ - { - name: "from", - type: "address", - indexed: true, - decoded: true, - value: "0x0000000000000000000000000000000000000000", - }, - { - name: "to", - type: "address", - indexed: true, - decoded: true, - value: "0x9025046c6fb25fb39e720d97a8fd881ed69a1ef6", - }, - { - name: "value", - type: "uint256", - indexed: false, - decoded: true, - value: "1157442274340", - }, - ], - }, - }, - { - block_signed_at: "2022-01-30T09:24:57Z", - block_height: 14106332, - tx_offset: 267, - log_offset: 332, - tx_hash: "", - raw_log_topics: [ - "0x7880508a48fd3aee88f7e15917d85e39c3ad059e51ad4aca9bb46e7b4938b961", - "0x000000000000000000000000000000000000000000000000000000000000000d", - ], - sender_contract_decimals: 0, - sender_name: null, - sender_contract_ticker_symbol: null, - sender_address: "0x9025046c6fb25fb39e720d97a8fd881ed69a1ef6", - sender_address_label: null, - sender_logo_url: "https://logos.covalenthq.com/tokens/1/0x9025046c6fb25fb39e720d97a8fd881ed69a1ef6.png", - raw_log_data: - "0x000000000000000000000000000000000000000000000eb79b080e27365a23a20000000000000000000000000000000000000000000000000000000dfb08e769", - decoded: { - name: "Bond", - signature: "Bond(indexed uint256 id, uint256 amount, uint256 price)", - params: [ - { - name: "id", - type: "uint256", - indexed: true, - decoded: true, - value: "13", - }, - { - name: "amount", - type: "uint256", - indexed: false, - decoded: true, - value: "69500056120101151843234", - }, - { - name: "price", - type: "uint256", - indexed: false, - decoded: true, - value: "60046239593", - }, - ], - }, - }, - ], - }, - type: "bond", - details: "Bond Purchased", - value: new DecimalBigNumber("186075461403", 9), -}; - -export const bondClaimTransaction = { - token: { - name: "OHM", - addresses: { - "1": "0x64aa3364f17a4d01c6f1751fd97c2bd3d7e7f1d5", - "4": "0xd7B98050962ec7cC8D11a83446B3217257C754B7", - }, - _contractCache: {}, - icons: ["OHM"], - decimals: 9, - purchaseUrl: - "https://app.sushi.com/swap?inputCurrency=0x6b175474e89094c44da98b954eedeac495271d0f&outputCurrency=0x64aa3364f17a4d01c6f1751fd97c2bd3d7e7f1d5", - }, - transaction: { - block_signed_at: "2022-04-09T07:11:08Z", - block_height: 14550108, - tx_hash: "", - tx_offset: 248, - successful: true, - from_address: "0xDd1E5f42baA201050c4686FDF4e3FDE16A58BC6F", - from_address_label: null, - to_address: "0x9025046c6fb25fb39e720d97a8fd881ed69a1ef6", - to_address_label: null, - value: "0", - value_quote: 0, - gas_offered: 179338, - gas_spent: 179338, - gas_price: 27175202887, - gas_quote: 15.73186056865662, - gas_quote_rate: 3228.0107421875, - log_events: [ - { - block_signed_at: "2022-04-09T07:11:08Z", - block_height: 14550108, - tx_offset: 248, - log_offset: 671, - tx_hash: "", - raw_log_topics: [ - "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef", - "0x0000000000000000000000009025046c6fb25fb39e720d97a8fd881ed69a1ef6", - "0x0000000000000000000000008d7a5fedf55b68625b2e5953f8203b029cb9c44e", - ], - sender_contract_decimals: 18, - sender_name: "Governance OHM", - sender_contract_ticker_symbol: "gOHM", - sender_address: "0x0ab87046fbb341d058f17cbc4c1133f25a20a52f", - sender_address_label: null, - sender_logo_url: "https://logos.covalenthq.com/tokens/0x0ab87046fbb341d058f17cbc4c1133f25a20a52f.png", - raw_log_data: "0x000000000000000000000000000000000000000000000003ec3e9e8ef84f4e43", - decoded: { - name: "Transfer", - signature: "Transfer(indexed address from, indexed address to, uint256 value)", - params: [ - { - name: "from", - type: "address", - indexed: true, - decoded: true, - value: "0x9025046c6fb25fb39e720d97a8fd881ed69a1ef6", - }, - { - name: "to", - type: "address", - indexed: true, - decoded: true, - value: "0xDd1E5f42baA201050c4686FDF4e3FDE16A58BC6F", - }, - { - name: "value", - type: "uint256", - indexed: false, - decoded: true, - value: "72363450199524200003", - }, - ], - }, - }, - ], - }, - type: "bond", - details: "Bond Claimed", - value: new DecimalBigNumber("186075461403", 9), -}; - -export const supplyToFuseTransaction = { - token: { - name: "OHM", - addresses: { - "1": "0x64aa3364f17a4d01c6f1751fd97c2bd3d7e7f1d5", - "4": "0xd7B98050962ec7cC8D11a83446B3217257C754B7", - }, - _contractCache: {}, - icons: ["OHM"], - decimals: 9, - purchaseUrl: - "https://app.sushi.com/swap?inputCurrency=0x6b175474e89094c44da98b954eedeac495271d0f&outputCurrency=0x64aa3364f17a4d01c6f1751fd97c2bd3d7e7f1d5", - }, - transaction: { - block_signed_at: "2022-01-29T22:42:17Z", - block_height: 14103441, - tx_hash: "", - tx_offset: 57, - successful: true, - from_address: "0xDd1E5f42baA201050c4686FDF4e3FDE16A58BC6F", - from_address_label: null, - to_address: "0x252d447c54f33e033ad04048baeade7628cb1274", - to_address_label: null, - value: "0", - value_quote: 0, - gas_offered: 512706, - gas_spent: 498111, - gas_price: 70678247339, - gas_quote: 90.9073892833278, - gas_quote_rate: 2582.1845703125, - log_events: [ - { - block_signed_at: "2022-01-29T22:42:17Z", - block_height: 14103441, - tx_offset: 57, - log_offset: 126, - tx_hash: "", - raw_log_topics: ["0xe5b754fb1abb7f01b499791d0b820ae3b6af3424ac1c59768edb53f4ec31a929"], - sender_contract_decimals: 9, - sender_name: "Fraximalist Money Market Staked Olympus", - sender_contract_ticker_symbol: "fsOHM-36", - sender_address: "0x252d447c54f33e033ad04048baeade7628cb1274", - sender_address_label: null, - sender_logo_url: "https://logos.covalenthq.com/tokens/1/0x252d447c54f33e033ad04048baeade7628cb1274.png", - raw_log_data: - "0x0000000000000000000000008d7a5fedf55b68625b2e5953f8203b029cb9c44e000000000000000000000000000000000000000000000002cbad511038056fed000000000000000000000000000000000000000000000000000005507cd29e6b", - decoded: { - name: "Redeem", - signature: "Redeem(address redeemer, uint256 redeemAmount, uint256 redeemTokens)", - params: [ - { - name: "redeemer", - type: "address", - indexed: false, - decoded: true, - value: "0xDd1E5f42baA201050c4686FDF4e3FDE16A58BC6F", - }, - { - name: "redeemAmount", - type: "uint256", - indexed: false, - decoded: true, - value: "51569964038190624749", - }, - { - name: "redeemTokens", - type: "uint256", - indexed: false, - decoded: true, - value: "5843249700459", - }, - ], - }, - }, - { - block_signed_at: "2022-01-29T22:42:17Z", - block_height: 14103441, - tx_offset: 57, - log_offset: 125, - tx_hash: "", - raw_log_topics: [ - "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef", - "0x0000000000000000000000008d7a5fedf55b68625b2e5953f8203b029cb9c44e", - "0x000000000000000000000000252d447c54f33e033ad04048baeade7628cb1274", - ], - sender_contract_decimals: 9, - sender_name: "Fraximalist Money Market Staked Olympus", - sender_contract_ticker_symbol: "fsOHM-36", - sender_address: "0x252d447c54f33e033ad04048baeade7628cb1274", - sender_address_label: null, - sender_logo_url: "https://logos.covalenthq.com/tokens/1/0x252d447c54f33e033ad04048baeade7628cb1274.png", - raw_log_data: "0x000000000000000000000000000000000000000000000000000005507cd29e6b", - decoded: { - name: "Transfer", - signature: "Transfer(indexed address from, indexed address to, uint256 value)", - params: [ - { - name: "from", - type: "address", - indexed: true, - decoded: true, - value: "0xDd1E5f42baA201050c4686FDF4e3FDE16A58BC6F", - }, - { - name: "to", - type: "address", - indexed: true, - decoded: true, - value: "0x252d447c54f33e033ad04048baeade7628cb1274", - }, - { - name: "value", - type: "uint256", - indexed: false, - decoded: true, - value: "5843249700459", - }, - ], - }, - }, - { - block_signed_at: "2022-01-29T22:42:17Z", - block_height: 14103441, - tx_offset: 57, - log_offset: 124, - tx_hash: "", - raw_log_topics: [ - "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef", - "0x000000000000000000000000252d447c54f33e033ad04048baeade7628cb1274", - "0x0000000000000000000000008d7a5fedf55b68625b2e5953f8203b029cb9c44e", - ], - sender_contract_decimals: 18, - sender_name: "Governance OHM", - sender_contract_ticker_symbol: "gOHM", - sender_address: "0x0ab87046fbb341d058f17cbc4c1133f25a20a52f", - sender_address_label: null, - sender_logo_url: "https://logos.covalenthq.com/tokens/0x0ab87046fbb341d058f17cbc4c1133f25a20a52f.png", - raw_log_data: "0x000000000000000000000000000000000000000000000002cbad511038056fed", - decoded: { - name: "Transfer", - signature: "Transfer(indexed address from, indexed address to, uint256 value)", - params: [ - { - name: "from", - type: "address", - indexed: true, - decoded: true, - value: "0x252d447c54f33e033ad04048baeade7628cb1274", - }, - { - name: "to", - type: "address", - indexed: true, - decoded: true, - value: "0xDd1E5f42baA201050c4686FDF4e3FDE16A58BC6F", - }, - { - name: "value", - type: "uint256", - indexed: false, - decoded: true, - value: "51569964038190624749", - }, - ], - }, - }, - { - block_signed_at: "2022-01-29T22:42:17Z", - block_height: 14103441, - tx_offset: 57, - log_offset: 123, - tx_hash: "", - raw_log_topics: ["0x4dec04e750ca11537cabcd8a9eab06494de08da3735bc8871cd41250e190bc04"], - sender_contract_decimals: 9, - sender_name: "Fraximalist Money Market Staked Olympus", - sender_contract_ticker_symbol: "fsOHM-36", - sender_address: "0x252d447c54f33e033ad04048baeade7628cb1274", - sender_address_label: null, - sender_logo_url: "https://logos.covalenthq.com/tokens/1/0x252d447c54f33e033ad04048baeade7628cb1274.png", - raw_log_data: - "0x00000000000000000000000000000000000000000000002abdbd4bae014e7c8600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000dfa70e74f5781270000000000000000000000000000000000000000000000000000000000000000", - decoded: { - name: "AccrueInterest", - signature: - "AccrueInterest(uint256 cashPrior, uint256 interestAccumulated, uint256 borrowIndex, uint256 totalBorrows)", - params: [ - { - name: "cashPrior", - type: "uint256", - indexed: false, - decoded: true, - value: "788435418350286175366", - }, - { - name: "interestAccumulated", - type: "uint256", - indexed: false, - decoded: true, - value: "0", - }, - { - name: "borrowIndex", - type: "uint256", - indexed: false, - decoded: true, - value: "1007241605441618215", - }, - { - name: "totalBorrows", - type: "uint256", - indexed: false, - decoded: true, - value: "0", - }, - ], - }, - }, - ], - }, - type: "borrow", - details: "Supply to Fuse", - value: new DecimalBigNumber("186075461403", 9), -}; - -export const stakeTransaction = { - token: { - name: "OHM", - addresses: { - "1": "0x64aa3364f17a4d01c6f1751fd97c2bd3d7e7f1d5", - "4": "0xd7B98050962ec7cC8D11a83446B3217257C754B7", - }, - _contractCache: {}, - icons: ["OHM"], - decimals: 9, - purchaseUrl: - "https://app.sushi.com/swap?inputCurrency=0x6b175474e89094c44da98b954eedeac495271d0f&outputCurrency=0x64aa3364f17a4d01c6f1751fd97c2bd3d7e7f1d5", - }, - transaction: { - block_signed_at: "2022-02-23T03:41:38Z", - block_height: 0, - tx_hash: "", - tx_offset: 0, - successful: true, - from_address: "0xDd1E5f42baA201050c4686FDF4e3FDE16A58BC6F", - from_address_label: null, - to_address: "0xb63cac384247597756545b500253ff8e607a8020", - to_address_label: null, - value: "0", - value_quote: 0, - gas_offered: 0, - gas_spent: 0, - gas_price: 0, - fees_paid: "0", - gas_quote: 0, - gas_quote_rate: 0, - log_events: [ - { - block_signed_at: "2022-02-23T03:41:38Z", - block_height: 0, - tx_offset: 0, - log_offset: 0, - tx_hash: "", - raw_log_topics: [ - "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef", - "0x000000000000000000000000b63cac384247597756545b500253ff8e607a8020", - "0x00000000000000000000000039e606af0bd163cb87a33283e452a40829ab2297", - ], - sender_contract_decimals: 9, - sender_name: "Staked OHM", - sender_contract_ticker_symbol: "sOHM", - sender_address: "0x04906695d6d12cf5459975d7c3c03356e4ccd460", - sender_address_label: null, - sender_logo_url: "https://logos.covalenthq.com/tokens/1/0x04906695d6d12cf5459975d7c3c03356e4ccd460.png", - raw_log_data: "0x0000000000000000000000000000000000000000000000000000002b52f6371b", - decoded: { - name: "Transfer", - signature: "Transfer(indexed address from, indexed address to, uint256 value)", - params: [ - { - name: "from", - type: "address", - indexed: true, - decoded: true, - value: "0xb63cac384247597756545b500253ff8e607a8020", - }, - { - name: "to", - type: "address", - indexed: true, - decoded: true, - value: "0xDd1E5f42baA201050c4686FDF4e3FDE16A58BC6F", - }, - { - name: "value", - type: "uint256", - indexed: false, - decoded: true, - value: "186075461403", - }, - ], - }, - }, - { - block_signed_at: "2022-02-23T03:41:38Z", - block_height: 0, - tx_offset: 0, - log_offset: 0, - tx_hash: "", - raw_log_topics: [ - "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef", - "0x00000000000000000000000039e606af0bd163cb87a33283e452a40829ab2297", - "0x0000000000000000000000000000000000000000000000000000000000000000", - ], - sender_contract_decimals: 18, - sender_name: "Governance OHM", - sender_contract_ticker_symbol: "gOHM", - sender_address: "0x0ab87046fbb341d058f17cbc4c1133f25a20a52f", - sender_address_label: null, - sender_logo_url: "https://logos.covalenthq.com/tokens/1/0x0ab87046fbb341d058f17cbc4c1133f25a20a52f.png", - raw_log_data: "0x0000000000000000000000000000000000000000000000001dd6559bdb170000", - decoded: { - name: "Transfer", - signature: "Transfer(indexed address from, indexed address to, uint256 value)", - params: [ - { - name: "from", - type: "address", - indexed: true, - decoded: true, - value: "0xDd1E5f42baA201050c4686FDF4e3FDE16A58BC6F", - }, - { - name: "to", - type: "address", - indexed: true, - decoded: true, - value: "0x0000000000000000000000000000000000000000", - }, - { - name: "value", - type: "uint256", - indexed: false, - decoded: true, - value: "2150000000000000000", - }, - ], - }, - }, - ], - }, - type: "staking", - details: "Stake", - value: new DecimalBigNumber("186075461403", 9), -}; - -export const unstakeTransaction = { - token: { - name: "OHM", - addresses: { - "1": "0x64aa3364f17a4d01c6f1751fd97c2bd3d7e7f1d5", - "4": "0xd7B98050962ec7cC8D11a83446B3217257C754B7", - }, - _contractCache: {}, - icons: ["OHM"], - decimals: 9, - purchaseUrl: - "https://app.sushi.com/swap?inputCurrency=0x6b175474e89094c44da98b954eedeac495271d0f&outputCurrency=0x64aa3364f17a4d01c6f1751fd97c2bd3d7e7f1d5", - }, - transaction: { - block_signed_at: "2022-04-11T04:37:00Z", - block_height: 0, - tx_hash: "", - tx_offset: 78, - successful: true, - from_address: "0xDd1E5f42baA201050c4686FDF4e3FDE16A58BC6F", - from_address_label: null, - to_address: "0xb63cac384247597756545b500253ff8e607a8020", - to_address_label: null, - value: "0", - value_quote: 0, - gas_offered: 0, - gas_spent: 0, - gas_price: 0, - fees_paid: "3724488498243672", - gas_quote: 0, - gas_quote_rate: 0, - log_events: [ - { - block_signed_at: "2022-04-11T04:37:00Z", - block_height: 0, - tx_offset: 78, - log_offset: 73, - tx_hash: "", - raw_log_topics: [ - "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef", - "0x000000000000000000000000b63cac384247597756545b500253ff8e607a8020", - "0x00000000000000000000000039e606af0bd163cb87a33283e452a40829ab2297", - ], - sender_contract_decimals: 9, - sender_name: "Olympus", - sender_contract_ticker_symbol: "OHM", - sender_address: "0x64aa3364f17a4d01c6f1751fd97c2bd3d7e7f1d5", - sender_address_label: null, - sender_logo_url: "https://logos.covalenthq.com/tokens/1/0x64aa3364f17a4d01c6f1751fd97c2bd3d7e7f1d5.png", - raw_log_data: "0x0000000000000000000000000000000000000000000000000000004bf441aa30", - decoded: { - name: "Transfer", - signature: "Transfer(indexed address from, indexed address to, uint256 value)", - params: [ - { - name: "from", - type: "address", - indexed: true, - decoded: true, - value: "0xb63cac384247597756545b500253ff8e607a8020", - }, - { - name: "to", - type: "address", - indexed: true, - decoded: true, - value: "0xDd1E5f42baA201050c4686FDF4e3FDE16A58BC6F", - }, - { - name: "value", - type: "uint256", - indexed: false, - decoded: true, - value: "326220491312", - }, - ], - }, - }, - ], - }, - type: "staking", - details: "Unstake", - value: new DecimalBigNumber("186075461403", 9), -}; diff --git a/src/components/TopBar/Wallet/__tests__/Info.unit.test.tsx b/src/components/TopBar/Wallet/__tests__/Info.unit.test.tsx deleted file mode 100644 index f5991641ab..0000000000 --- a/src/components/TopBar/Wallet/__tests__/Info.unit.test.tsx +++ /dev/null @@ -1,20 +0,0 @@ -import React from "react"; -import Faq from "src/components/TopBar/Wallet/Info/Faq"; -import News from "src/components/TopBar/Wallet/Info/News"; -import { Proposals } from "src/components/TopBar/Wallet/Info/Proposals"; -import { render, screen } from "src/testUtils"; -import { describe, expect, it } from "vitest"; -describe("Info View", () => { - it("Should Display News for news Path", async () => { - render(); - expect(screen.getByTestId("news")); - }); - it("Should Display Proposals for proposal Path", async () => { - render(); - expect(screen.getByTestId("proposals")); - }); - it("Should Display Faq's for faq Path", async () => { - render(); - expect(screen.getByTestId("faq")); - }); -}); diff --git a/src/components/TopBar/Wallet/__tests__/News.unit.test.jsx b/src/components/TopBar/Wallet/__tests__/News.unit.test.jsx deleted file mode 100644 index 50a23db54a..0000000000 --- a/src/components/TopBar/Wallet/__tests__/News.unit.test.jsx +++ /dev/null @@ -1,16 +0,0 @@ -import axios from "axios"; -import { feedContent } from "src/components/TopBar/Wallet/__mocks__/mockFeedContent"; -import News from "src/components/TopBar/Wallet/Info/News"; -import { render, screen } from "src/testUtils"; -import { beforeEach, describe, expect, it, vi } from "vitest"; - -describe("News View", () => { - beforeEach(() => { - axios.get = vi.fn().mockResolvedValue({ data: { items: feedContent } }); - render(); - }); - it("Should Parse RSS Feed Correctly", async () => { - expect(screen.getByTestId("news")); - expect(await screen.findByText("The Olympus Treasury Dashboard")); - }); -}); diff --git a/src/components/TopBar/Wallet/__tests__/Proposals.unit.test.jsx b/src/components/TopBar/Wallet/__tests__/Proposals.unit.test.jsx deleted file mode 100644 index 7954f411bd..0000000000 --- a/src/components/TopBar/Wallet/__tests__/Proposals.unit.test.jsx +++ /dev/null @@ -1,19 +0,0 @@ -import { proposalContent } from "src/components/TopBar/Wallet/__mocks__/mockProposalContent"; -import { Proposals } from "src/components/TopBar/Wallet/Info/Proposals"; -import { render, screen } from "src/testUtils"; -import { beforeEach, describe, expect, it, vi } from "vitest"; - -describe("Proposal View", () => { - beforeEach(() => { - vi.mock("graphql-request", () => ({ - request: vi.fn().mockReturnValue({ proposals: proposalContent }), - gql: vi.fn(), - })); - render(); - }); - it("Should Load Proposals Correctly", async () => { - expect(screen.getByTestId("proposals")); - expect(await screen.findByText("OIP-88: KlimaDAO Love Letter")); - expect(await screen.findByText("TAP-9 Rocket Pool Whitelist")); - }); -}); diff --git a/src/components/TopBar/Wallet/__tests__/TransactionHistory.unit.test.jsx b/src/components/TopBar/Wallet/__tests__/TransactionHistory.unit.test.jsx deleted file mode 100644 index f5572f9eb1..0000000000 --- a/src/components/TopBar/Wallet/__tests__/TransactionHistory.unit.test.jsx +++ /dev/null @@ -1,81 +0,0 @@ -import { - bondClaimTransaction, - bondPurchaseTransaction, - stakeTransaction, - supplyToFuseTransaction, - unstakeTransaction, -} from "src/components/TopBar/Wallet/__mocks__/mockTransactionHistory"; -import Wallet from "src/components/TopBar/Wallet/index"; -import * as queries from "src/components/TopBar/Wallet/queries"; -import { fireEvent, render, screen } from "src/testUtils"; -import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; - -describe("", () => { - describe("Show no transactions", () => { - beforeEach(() => { - const useTransactionHistory = vi.spyOn(queries, "useTransactionHistory"); - useTransactionHistory.mockReturnValue({ data: { pages: [[]] }, isFetched: true }); - - const useTransferHistory = vi.spyOn(queries, "useTransferHistory"); - useTransferHistory.mockReturnValue({ data: { pages: [[]] }, isFetched: true }); - render(); - }); - - afterEach(() => { - vi.clearAllMocks(); - }); - it("Should show no transaction history", () => { - expect(screen.getByText("No transactions")); - }); - - it("Should filter the list when clicking on Staking", () => { - fireEvent.click(screen.getByText("Staking")); - expect(screen.getByText("No transactions")); - }); - }); - - describe("Show important transactions", () => { - beforeEach(() => { - const useTransactionHistory = vi.spyOn(queries, "useTransactionHistory"); - useTransactionHistory.mockReturnValue({ - data: { - pages: [ - [ - stakeTransaction, - unstakeTransaction, - supplyToFuseTransaction, - bondClaimTransaction, - bondPurchaseTransaction, - ], - ], - }, - isFetched: true, - }); - - const useTransferHistory = vi.spyOn(queries, "useTransferHistory"); - useTransferHistory.mockReturnValue({ data: { pages: [[]] }, isFetched: true }); - - render(); - }); - - it("Should display an unstake transaction", () => { - expect(screen.getByText("Unstake")); - }); - - it("Should display a stake transaction", () => { - expect(screen.getByText("Stake")); - }); - - it("Should display a bond purchased transaction", () => { - expect(screen.getByText("Bond Purchased")); - }); - - it("Should display a bond claimed transaction", () => { - expect(screen.getByText("Bond Claimed")); - }); - - it("Should display a fuse supply transaction", () => { - expect(screen.getByText("Supply to Fuse")); - }); - }); -}); diff --git a/src/components/TopBar/Wallet/__tests__/index.unit.test.tsx b/src/components/TopBar/Wallet/__tests__/index.unit.test.tsx deleted file mode 100644 index 4926dabc3d..0000000000 --- a/src/components/TopBar/Wallet/__tests__/index.unit.test.tsx +++ /dev/null @@ -1,66 +0,0 @@ -import React from "react"; -import Wallet from "src/components/TopBar/Wallet/index"; -import { render, screen } from "src/testUtils"; -import { beforeEach, describe, expect, it, vi } from "vitest"; - -// describe("Wallet Drawer Disconnected", () => { -// it("Default State Should Prompt to Connect Wallet", async () => { -// render(); -// expect(screen.getByText("Please Connect Your Wallet")); -// }); - -// it("Should Display Utility View", async () => { -// render(); -// expect(screen.getByText("Exchanges")); -// expect(screen.getByText("Farm Pool")); -// }); - -// it("Should Display Info View", async () => { -// render(); -// expect(screen.getByText("Votes")); -// }); -// }); - -describe("Wallet Drawer Connected", () => { - beforeEach(() => { - vi.mock("wagmi", async () => { - const wagmiImport: any = await vi.importActual("wagmi"); - return { - ...wagmiImport, - useAccount: vi.fn().mockReturnValue({ - address: "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", - isConnected: true, - error: null, - fetchStatus: "idle", - internal: { - dataUpdatedAt: 1654570110046, - errorUpdatedAt: 0, - failureCount: 0, - isFetchedAfterMount: true, - isLoadingError: false, - isPaused: false, - isPlaceholderData: false, - isPreviousData: false, - isRefetchError: false, - isStale: true, - }, - isError: false, - isFetched: true, - isFetching: false, - isIdle: false, - isLoading: false, - isRefetching: false, - isSuccess: true, - refetch: vi.fn(), - status: "success", - }), - }; - }); - }); - it("Default State Should Prompt to Connect Wallet", async () => { - // console.log(test, "test"); - render(); - expect(screen.getByText("My Wallet")); - expect(screen.getByText("Disconnect")); - }); -}); diff --git a/src/components/TopBar/Wallet/helpers.ts b/src/components/TopBar/Wallet/helpers.ts deleted file mode 100644 index 477fa11ccf..0000000000 --- a/src/components/TopBar/Wallet/helpers.ts +++ /dev/null @@ -1,37 +0,0 @@ -import React from "react"; - -export default function useIntersectionObserver({ - root, - target, - onIntersect, - threshold = 1.0, - rootMargin = "0px", - enabled = true, -}: any) { - React.useEffect(() => { - if (!enabled) { - return; - } - - const observer = new IntersectionObserver( - entries => entries.forEach(entry => entry.isIntersecting && onIntersect()), - { - root: root && root.current, - rootMargin, - threshold, - }, - ); - - const el = target && target.current; - - if (!el) { - return; - } - - observer.observe(el); - - return () => { - observer.unobserve(el); - }; - }, [target.current, enabled]); -} diff --git a/src/components/TopBar/Wallet/index.tsx b/src/components/TopBar/Wallet/index.tsx deleted file mode 100644 index 0d5f766e6c..0000000000 --- a/src/components/TopBar/Wallet/index.tsx +++ /dev/null @@ -1,174 +0,0 @@ -import { Box, SwipeableDrawer, Typography } from "@mui/material"; -import { styled } from "@mui/material/styles"; -import { Icon, SecondaryButton, TabBar } from "@olympusdao/component-library"; -import { useEffect, useState } from "react"; -import { useLocation, useNavigate } from "react-router-dom"; -import { ConnectButton, InPageConnectButton } from "src/components/ConnectButton/ConnectButton"; -import ThemeSwitcher from "src/components/TopBar/ThemeSwitch"; -import Assets from "src/components/TopBar/Wallet/Assets"; -import GetOhm from "src/components/TopBar/Wallet/GetOhm"; -import { Info } from "src/components/TopBar/Wallet/Info"; -import { useAccount, useDisconnect } from "wagmi"; - -const PREFIX = "Wallet"; - -const classes = { - root: `${PREFIX}-root`, - paper: `${PREFIX}-paper`, - networkSelector: `${PREFIX}-networkSelector`, - connectButton: `${PREFIX}-connectButton`, -}; - -// TODO jss-to-styled codemod: The Fragment root was replaced by div. Change the tag if needed. -const StyledSwipeableDrawer = styled(SwipeableDrawer)(({ theme }) => ({ - [`& .${classes.networkSelector}`]: { - background: theme.colors.gray[700], - minHeight: "39px", - borderRadius: "6px", - padding: "9px 18px", - alignItems: "center", - }, - - [`& .${classes.connectButton}`]: { - background: theme.colors.gray[600], - "&:hover": { - background: theme.colors.gray[600], - }, - }, - - [`&.${classes.root}`]: { - width: "460px", - maxWidth: "100%", - }, - - [`& .${classes.paper}`]: { - maxWidth: "100%", - background: theme.colors.gray[700], - }, -})); - -export function Wallet(props: { - open?: boolean; - component?: string; - theme: string; - toggleTheme: (e: KeyboardEvent) => void; -}) { - interface LocationState { - state: { prevPath: string }; - } - const { state: closeRedirect } = useLocation() as LocationState; - const [closeLocation, setCloseLocation] = useState("/"); - - //Watch for PrevPath passed in and set it as path to close. - useEffect(() => { - if (closeRedirect && closeRedirect.prevPath) { - setCloseLocation(closeRedirect.prevPath); - } - }, [closeRedirect]); - - const navigate = useNavigate(); - - const { isConnected } = useAccount(); - - // only enable backdrop transition on ios devices, - // because we can assume IOS is hosted on hight-end devices and will not drop frames - // also disable discovery on IOS, because of it's 'swipe to go back' feat - const isIOS = /iPad|iPhone|iPod/.test(navigator.userAgent); - - const DisconnectButton = () => { - const { disconnect } = useDisconnect(); - return Disconnect; - }; - - const ConnectMessage = () => ( - <> - - Please Connect Your Wallet - - - - - - ); - - return ( - null} - onClose={() => navigate(closeLocation)} - classes={{ - root: classes.root, - paper: classes.paper, - }} - > - - - - - - - - - { - navigate(closeLocation); - }} - style={{ cursor: "pointer" }} - name="x" - /> - - - - - - {(() => { - switch (props.component) { - case "info": - return ; - case "utility": - return ; - case "wallet": - return <>{!isConnected ? : }; - case "wallet/history": - return ; - default: - <>; - } - })()} - - - {(props.component !== "wallet" || isConnected) && ( - - {isConnected ? : } - - )} - - ); -} - -export default Wallet; diff --git a/src/components/TopBar/Wallet/queries.ts b/src/components/TopBar/Wallet/queries.ts deleted file mode 100644 index 26f7ad67c5..0000000000 --- a/src/components/TopBar/Wallet/queries.ts +++ /dev/null @@ -1,168 +0,0 @@ -import { useInfiniteQuery, useQuery } from "@tanstack/react-query"; -import axios from "axios"; -import { BigNumber } from "ethers"; -import { gql, request } from "graphql-request"; -const snapshotUrl = "https://hub.snapshot.org/graphql"; -const mediumUrl = "https://api.rss2json.com/v1/api.json?rss_url=https://olympusdao.medium.com/feed"; -import { FUSE_POOL_18_ADDRESSES } from "src/constants/addresses"; -import { shorten } from "src/helpers"; -import { Token } from "src/helpers/contracts/Token"; -import { interpretTransaction, Transaction } from "src/helpers/covalent/interpretTransaction"; -import { DecimalBigNumber } from "src/helpers/DecimalBigNumber/DecimalBigNumber"; -import { assert } from "src/helpers/types/assert"; -import { useStaticFuseContract } from "src/hooks/useContract"; -import { covalent } from "src/lib/covalent"; -import { CovalentResponse, CovalentTransaction, CovalentTransfer } from "src/lib/covalent.types"; -import { NetworkId } from "src/networkDetails"; -import { useAccount, useNetwork } from "wagmi"; -export const ActiveProposals = () => { - const { data, isFetched, isLoading } = useQuery(["ActiveProposals"], async () => { - const data = await request( - snapshotUrl, - gql` - query Proposals { - proposals( - first: 20 - skip: 0 - where: { space_in: ["olympusdao.eth"] } - orderBy: "created" - orderDirection: desc - ) { - id - title - body - choices - start - end - snapshot - state - author - link - scores - } - } - `, - ); - return data; - }); - return { data, isFetched, isLoading }; -}; - -export const MediumArticles = () => { - const { data, isFetched, isLoading } = useQuery(["MediumArticles"], async () => { - return await axios.get(mediumUrl).then(res => { - return res.data; - }); - }); - return { data, isFetched, isLoading }; -}; - -export const SupplyRatePerBlock = () => { - const fuse = useStaticFuseContract(FUSE_POOL_18_ADDRESSES[NetworkId.MAINNET], NetworkId.MAINNET); - const { data, isFetched, isLoading } = useQuery(["FuseSupply"], async () => { - return await fuse.supplyRatePerBlock(); - }); - return { data, isFetched, isLoading }; -}; - -export const GetTokenPrice = (tokenId = "olympus") => { - const { data, isFetched, isLoading } = useQuery(["TokenPrice", tokenId], async () => { - const cgResp = await axios.get( - `https://api.coingecko.com/api/v3/simple/price?ids=${tokenId}&vs_currencies=usd&include_24hr_change=true`, - ); - return cgResp.data[tokenId]; - }); - return { data, isFetched, isLoading }; -}; - -interface UseTransactionHistoryOptions { - address?: string; - networkId?: NetworkId; -} - -export const transactionHistoryQueryKey = (options: UseTransactionHistoryOptions) => - ["useTransactionHistory", options] as const; - -export const useTransactionHistory = () => { - const { address = "" } = useAccount(); - const { chain = { id: 1 } } = useNetwork(); - - return useInfiniteQuery, Error, Transaction[]>( - [transactionHistoryQueryKey({ address, networkId: chain.id })], - ({ pageParam = 0 }) => { - return covalent.transactions.listAll({ - address, - networkId: chain.id, - pageSize: 300, - pageNumber: pageParam, - }); - }, - { - enabled: !!address && !!chain.id, - select: ({ pages, pageParams }) => ({ - pageParams, - pages: pages.map(page => interpretTransaction(page.items, address)), - }), - getNextPageParam: lastPage => { - if (!lastPage.pagination.has_more) return; - return lastPage.pagination.page_number + 1; - }, - }, - ); -}; - -interface UseTransferHistoryOptions { - address?: string; - networkId?: NetworkId; - contractAddress?: string; -} - -export const transferHistoryQueryKey = (options: UseTransferHistoryOptions) => ["useTransferHistory", options] as const; - -export const useTransferHistory = (token: TToken) => { - const { address = "" } = useAccount(); - const { chain = { id: 1 } } = useNetwork(); - const contractAddress = token.getAddress(chain.id); - - return useInfiniteQuery, Error, Transaction[]>( - [transferHistoryQueryKey({ address, networkId: chain.id, contractAddress })], - async ({ pageParam = 0 }) => { - return covalent.transfers.listAll({ - address, - networkId: chain.id, - pageSize: 300, - contractAddress, - pageNumber: pageParam, - }); - }, - { - enabled: !!address && !!chain.id && !!contractAddress, - select: ({ pages, pageParams }) => ({ - pageParams, - pages: pages.map(page => - page.items.map(transaction => { - const [transfer] = transaction.transfers || []; - assert(transfer, "There should always be atleast 1 transfer"); - - const _transaction: Transaction = { - token, - transaction, - type: "transfer", - details: - transfer.transfer_type === "OUT" - ? `Transfer to ${shorten(transfer.to_address)}` - : `Deposit from ${shorten(transfer.to_address)}`, - value: new DecimalBigNumber(BigNumber.from(transfer.delta), token.decimals), - }; - - return _transaction; - }), - ), - }), - getNextPageParam: lastPage => { - if (!lastPage.pagination.has_more) return; - return lastPage.pagination.page_number + 1; - }, - }, - ); -}; diff --git a/src/constants/addresses.ts b/src/constants/addresses.ts index 346e875f70..ffc5cae355 100644 --- a/src/constants/addresses.ts +++ b/src/constants/addresses.ts @@ -60,7 +60,6 @@ export const GOHM_ADDRESSES = { [NetworkId.TESTNET_GOERLI]: "0xC1863141dc1861122d5410fB5973951c82871d98", [NetworkId.MAINNET]: "0x0ab87046fBb341D058F17CBC4c1133F25a20a52f", [NetworkId.ARBITRUM]: "0x8D9bA570D6cb60C7e3e0F31343Efe75AB8E65FB1", - [NetworkId.ARBITRUM_TESTNET]: "0x950c3626B9E9798aA1a4832cEee603ECfb7741a8", [NetworkId.AVALANCHE]: "0x321e7092a180bb43555132ec53aaa65a5bf84251", [NetworkId.AVALANCHE_TESTNET]: "0x115E5979435c89eF38fB87C2D7Fc3BCA09053c54", [NetworkId.POLYGON]: "0xd8cA34fd379d9ca3C6Ee3b3905678320F5b45195", @@ -73,7 +72,6 @@ export const WSOHM_ADDRESSES = { [NetworkId.TESTNET_GOERLI]: "0x98002335F094340BB8B21c8b7CC35F0792282651", [NetworkId.MAINNET]: "0xca76543cf381ebbb277be79574059e32108e3e65", [NetworkId.ARBITRUM]: "0x739ca6D71365a08f584c8FC4e1029045Fa8ABC4B", - [NetworkId.ARBITRUM_TESTNET]: "0x3DE0150338BDeE175a8EAc6fBbBF2c55279454d5", [NetworkId.AVALANCHE]: "0x8cd309e14575203535ef120b5b0ab4dded0c2073", [NetworkId.AVALANCHE_TESTNET]: "0x8e8ffc8d41Ee4A915A1FB3940b1beAB0c2Cd5bB0", }; @@ -104,7 +102,6 @@ export const MIGRATOR_ADDRESSES = { [NetworkId.TESTNET_GOERLI]: "0x33c7278a7C0Ea98d75B2CCb87506aC3fD494dC83", [NetworkId.MAINNET]: "0x184f3FAd8618a6F458C16bae63F70C426fE784B3", [NetworkId.ARBITRUM]: "0x1e7902a8b0adbf81042b5e30bdfa281f0b928d6d", - [NetworkId.ARBITRUM_TESTNET]: "0xde9518c8444Fa436704Fbd9db27B3910bca9F532", [NetworkId.AVALANCHE]: "0xB10209BFbb37d38EC1B5F0c964e489564e223ea7", [NetworkId.AVALANCHE_TESTNET]: "0x9050D25977F8A19CDD5599A28bC5f55d39fb6105", }; diff --git a/src/helpers/covalent/interpretTransaction.ts b/src/helpers/covalent/interpretTransaction.ts deleted file mode 100644 index 878812250d..0000000000 --- a/src/helpers/covalent/interpretTransaction.ts +++ /dev/null @@ -1,149 +0,0 @@ -import { BigNumber } from "ethers"; -import { NetworkId } from "src/constants"; -import { - BOND_DEPOSITORY_ADDRESSES, - FIATDAO_WSOHM_ADDRESSES, - FUSE_POOL_6_ADDRESSES, - FUSE_POOL_18_ADDRESSES, - FUSE_POOL_36_ADDRESSES, - MIGRATOR_ADDRESSES, - PT_PRIZE_POOL_ADDRESSES, - STAKING_ADDRESSES, - ZAP_ADDRESSES, -} from "src/constants/addresses"; -import { OHM_TOKEN } from "src/constants/tokens"; -import { Token } from "src/helpers/contracts/Token"; -import { DecimalBigNumber } from "src/helpers/DecimalBigNumber/DecimalBigNumber"; -import { assert } from "src/helpers/types/assert"; -import { CovalentTransaction } from "src/lib/covalent.types"; - -export interface Transaction { - type: "bond" | "zap" | "staking" | "zap" | "migration" | "33together" | "borrow" | "transfer"; - token: Token; - details: string; - value: DecimalBigNumber; - transaction: CovalentTransaction; -} - -const isContract = (contractAddresses: Partial> | Token, address: string) => - Object.values(contractAddresses) - .map(address => address.toLowerCase()) - .includes(address.toLowerCase()); - -export const interpretTransaction = (transactions: CovalentTransaction[], address: string) => { - const results: Transaction[] = []; - for (const transaction of transactions) { - if (!transaction.log_events || transaction.log_events.length === 0) continue; - - assert(transaction.log_events, "Transactions w/o logs are ignored"); - const [first, second] = transaction.log_events; - - if (isContract(BOND_DEPOSITORY_ADDRESSES, transaction.to_address)) { - if (first.decoded.params[1].value.toLowerCase() === address.toLowerCase()) - results.push({ - token: OHM_TOKEN, - transaction, - type: "bond", - details: "Bond Claimed", - value: new DecimalBigNumber(BigNumber.from(first.decoded.params[2].value), first.sender_contract_decimals), - }); - else - results.push({ - token: OHM_TOKEN, - transaction, - type: "bond", - details: "Bond Purchased", - value: new DecimalBigNumber(BigNumber.from(second.decoded.params[2].value), second.sender_contract_decimals), - }); - } - - if (isContract(STAKING_ADDRESSES, transaction.to_address)) { - if (isContract(STAKING_ADDRESSES, first.decoded.params[0].value) && isContract(OHM_TOKEN, first.sender_address)) - results.push({ - token: OHM_TOKEN, - transaction, - type: "staking", - details: "Unstake", - value: new DecimalBigNumber(BigNumber.from(first.decoded.params[2].value), first.sender_contract_decimals), - }); - else - results.push({ - token: OHM_TOKEN, - transaction, - type: "staking", - details: "Stake", - value: new DecimalBigNumber(BigNumber.from(first.decoded.params[2].value), first.sender_contract_decimals), - }); - } - - if (isContract(ZAP_ADDRESSES, transaction.to_address)) - results.push({ - token: OHM_TOKEN, - transaction, - type: "zap", - details: `Zap to ${second?.sender_contract_ticker_symbol}`, - value: new DecimalBigNumber(BigNumber.from(second.decoded.params[2].value), second.sender_contract_decimals), - }); - - if (isContract(MIGRATOR_ADDRESSES, transaction.to_address)) - results.push({ - token: OHM_TOKEN, - transaction, - type: "migration", - details: "Migration", - value: new DecimalBigNumber(BigNumber.from(first.decoded.params[2].value), first.sender_contract_decimals), - }); - - if (isContract(PT_PRIZE_POOL_ADDRESSES, transaction.to_address)) - results.push({ - token: OHM_TOKEN, - transaction, - type: "33together", - details: "33Together Claim", - value: new DecimalBigNumber(BigNumber.from(second.decoded.params[2].value), second.sender_contract_decimals), - }); - - if (isContract(FUSE_POOL_36_ADDRESSES, transaction.to_address)) { - const event = transaction.log_events.filter((event: { decoded: { name: string }; sender_address: string }) => { - return ( - event.decoded.name == "Transfer" && - isContract(FUSE_POOL_36_ADDRESSES, event.sender_address) && - isContract(FUSE_POOL_18_ADDRESSES, event.sender_address) && - isContract(FUSE_POOL_6_ADDRESSES, event.sender_address) - ); - }); - - results.push({ - token: OHM_TOKEN, - transaction, - type: "borrow", - details: "Supply to Fuse", - value: new DecimalBigNumber( - BigNumber.from(event[0]?.decoded.params[2].value), - event[0]?.sender_contract_decimals, - ), - }); - } - - if (isContract(FIATDAO_WSOHM_ADDRESSES, transaction.to_address)) { - if (isContract(FIATDAO_WSOHM_ADDRESSES, first.sender_address)) - results.push({ - token: OHM_TOKEN, - transaction, - type: "staking", - details: "FiatDAO Withdraw", - value: new DecimalBigNumber(BigNumber.from(first.decoded.params[2].value), second.sender_contract_decimals), - }); - else - results.push({ - token: OHM_TOKEN, - transaction, - type: "staking", - details: "FiatDAO Deposit", - value: new DecimalBigNumber(BigNumber.from(first.decoded.params[2].value), second.sender_contract_decimals), - }); - } - } - - return results; -}; diff --git a/src/helpers/environment/Environment/Environment.ts b/src/helpers/environment/Environment/Environment.ts index 08e078f3ae..50513666b6 100644 --- a/src/helpers/environment/Environment/Environment.ts +++ b/src/helpers/environment/Environment/Environment.ts @@ -111,11 +111,6 @@ export class Environment { key: `VITE_ARBITRUM_NODE_URL`, fallback: "https://rpc.ankr.com/arbitrum", }); - case NetworkId.ARBITRUM_TESTNET: - return this._get({ - key: `VITE_ARBITRUM_TESTNET_NODE_URL`, - fallback: "https://arb-rinkeby.g.alchemy.com/v2/_gg7wSSi0KMBsdKnGVfHDueq6xMB9EkC", - }); case NetworkId.ARBITRUM_GOERLI: return this._get({ key: `VITE_ARBITRUM_GOERLI_NODE_URL`, diff --git a/src/helpers/environment/Environment/Environment.unit.test.ts b/src/helpers/environment/Environment/Environment.unit.test.ts index 9d3d91e113..dcbd8b6e4c 100644 --- a/src/helpers/environment/Environment/Environment.unit.test.ts +++ b/src/helpers/environment/Environment/Environment.unit.test.ts @@ -93,7 +93,6 @@ describe("Environment", () => { expect(Environment.getNodeUrls(NetworkId.MAINNET)).not.toBeUndefined(); expect(Environment.getNodeUrls(NetworkId.TESTNET_GOERLI)).not.toBeUndefined(); expect(Environment.getNodeUrls(NetworkId.ARBITRUM)).not.toBeUndefined(); - expect(Environment.getNodeUrls(NetworkId.ARBITRUM_TESTNET)).not.toBeUndefined(); expect(Environment.getNodeUrls(NetworkId.AVALANCHE)).not.toBeUndefined(); expect(Environment.getNodeUrls(NetworkId.AVALANCHE_TESTNET)).not.toBeUndefined(); expect(Environment.getNodeUrls(NetworkId.POLYGON)).not.toBeUndefined(); diff --git a/src/helpers/index.tsx b/src/helpers/index.tsx index e163eadb70..525148ecae 100644 --- a/src/helpers/index.tsx +++ b/src/helpers/index.tsx @@ -119,7 +119,6 @@ export const formatNumber = (number: number, precision = 0) => { export const isTestnet = (networkId: NetworkId) => { const testnets = [ - NetworkId.ARBITRUM_TESTNET, NetworkId.ARBITRUM_GOERLI, NetworkId.AVALANCHE_TESTNET, NetworkId.FANTOM_TESTNET, diff --git a/src/hooks/useTestableNetworks.ts b/src/hooks/useTestableNetworks.ts index 97114b7938..41d9a1a8fe 100644 --- a/src/hooks/useTestableNetworks.ts +++ b/src/hooks/useTestableNetworks.ts @@ -16,7 +16,7 @@ export const useTestableNetworks = () => { return { MAINNET: getTestnet(NetworkId.MAINNET, NetworkId.TESTNET_GOERLI, chain.id), AVALANCHE: getTestnet(NetworkId.AVALANCHE, NetworkId.AVALANCHE_TESTNET, chain.id), - ARBITRUM_V0: getTestnet(NetworkId.ARBITRUM, NetworkId.ARBITRUM_TESTNET, chain.id), + ARBITRUM_V0: getTestnet(NetworkId.ARBITRUM, NetworkId.ARBITRUM_GOERLI, chain.id), ARBITRUM: getTestnet(NetworkId.ARBITRUM, NetworkId.ARBITRUM_GOERLI, chain.id), POLYGON: getTestnet(NetworkId.POLYGON, NetworkId.POLYGON_TESTNET, chain.id), FANTOM: getTestnet(NetworkId.FANTOM, NetworkId.FANTOM_TESTNET, chain.id), diff --git a/src/networkDetails.ts b/src/networkDetails.ts index 395b4e6e54..e4030acf03 100644 --- a/src/networkDetails.ts +++ b/src/networkDetails.ts @@ -3,7 +3,6 @@ export enum NetworkId { TESTNET_GOERLI = 5, ARBITRUM = 42161, - ARBITRUM_TESTNET = 421611, ARBITRUM_GOERLI = 421613, AVALANCHE = 43114, @@ -72,17 +71,6 @@ export const VIEWS_FOR_NETWORK: { [key: number]: IViewsForNetwork } = { bondsV2: false, range: false, }, - [NetworkId.ARBITRUM_TESTNET]: { - dashboard: true, - stake: false, - wrap: true, - zap: false, - threeTogether: false, - bonds: false, - network: true, - bondsV2: false, - range: false, - }, [NetworkId.ARBITRUM_GOERLI]: { dashboard: true, stake: false, diff --git a/src/testHelpers.ts b/src/testHelpers.ts index eb38cc5f0f..795fa173eb 100644 --- a/src/testHelpers.ts +++ b/src/testHelpers.ts @@ -271,7 +271,6 @@ export const mockGohmBalance = ( | NetworkId.MAINNET | NetworkId.TESTNET_GOERLI | NetworkId.ARBITRUM - | NetworkId.ARBITRUM_TESTNET | NetworkId.AVALANCHE | NetworkId.AVALANCHE_TESTNET | NetworkId.POLYGON @@ -283,7 +282,6 @@ export const mockGohmBalance = ( | NetworkId.MAINNET | NetworkId.TESTNET_GOERLI | NetworkId.ARBITRUM - | NetworkId.ARBITRUM_TESTNET | NetworkId.AVALANCHE | NetworkId.AVALANCHE_TESTNET | NetworkId.POLYGON @@ -391,39 +389,6 @@ export const mockGohmBalance = ( }); }, }, - [NetworkId.ARBITRUM_TESTNET]: { - data: data[NetworkId.ARBITRUM_TESTNET], - error: null, - isError: false, - isSuccess: true, - isLoading: false, - isLoadingError: false, - isPaused: false, - fetchStatus: "idle", - isRefetchError: false, - failureCount: 0, - isFetched: true, - isFetchedAfterMount: true, - isFetching: false, - isPlaceholderData: false, - isPreviousData: false, - isRefetching: false, - isStale: false, - status: "success", - dataUpdatedAt: 0, - errorUpdatedAt: 0, - errorUpdateCount: 0, - refetch: () => { - return new Promise(() => { - return true; - }); - }, - remove: () => { - return new Promise(() => { - return true; - }); - }, - }, [NetworkId.AVALANCHE]: { data: data[NetworkId.AVALANCHE], error: null, diff --git a/src/views/Bridge/components/BridgeFees.tsx b/src/views/Bridge/components/BridgeFees.tsx index 79cb061edf..d468d955a3 100644 --- a/src/views/Bridge/components/BridgeFees.tsx +++ b/src/views/Bridge/components/BridgeFees.tsx @@ -3,7 +3,7 @@ import { DataRow } from "@olympusdao/component-library"; import { BRIDGE_CHAINS } from "src/constants/addresses"; import { DecimalBigNumber } from "src/helpers/DecimalBigNumber/DecimalBigNumber"; import { useEstimateSendFee } from "src/hooks/useBridging"; -import { formatBalance } from "src/views/Stake/components/StakeArea/StakeBalances"; +import { formatBalance } from "src/views/Stake/components/StakeArea/components/StakeBalances"; import { useAccount, useNetwork } from "wagmi"; const StyledDataRow = styled(DataRow)({ diff --git a/src/views/MyBalances/LearnAboutGohm.tsx b/src/views/MyBalances/LearnAboutGohm.tsx new file mode 100644 index 0000000000..7e6e026d66 --- /dev/null +++ b/src/views/MyBalances/LearnAboutGohm.tsx @@ -0,0 +1,23 @@ +import { Box, Typography, useTheme } from "@mui/material"; +import { TertiaryButton } from "@olympusdao/component-library"; + +export const LearnAboutGohm = () => { + const theme = useTheme(); + return ( + <> + + What is OHM? + + gOHM is the governance token of the Olympus protocol. gOHM can be obtained by wrapping OHM. gOHM can be + unwrapped to OHM at any time. gOHM is used to vote in governance and can be used as collateral to take a + Cooler Loan. + + + + + Learn More + + + + ); +}; diff --git a/src/views/MyBalances/LearnAboutOhm.tsx b/src/views/MyBalances/LearnAboutOhm.tsx new file mode 100644 index 0000000000..f00dcb2ed4 --- /dev/null +++ b/src/views/MyBalances/LearnAboutOhm.tsx @@ -0,0 +1,27 @@ +import { Box, Typography, useTheme } from "@mui/material"; +import { PrimaryButton } from "@olympusdao/component-library"; + +export const LearnAboutOhm = () => { + const theme = useTheme(); + return ( + <> + + What is OHM? + + OHM is the native token of the Olympus protocol. OHM is used in liquid markets. OHM is fully-backed by the + Olympus treasury. + + + + + Get OHM + + + + ); +}; diff --git a/src/views/MyBalances/MyCoolerLoans.tsx b/src/views/MyBalances/MyCoolerLoans.tsx new file mode 100644 index 0000000000..3c42ee01c9 --- /dev/null +++ b/src/views/MyBalances/MyCoolerLoans.tsx @@ -0,0 +1,118 @@ +import { Box, Divider, LinearProgress, Link, SvgIcon, Typography, useTheme } from "@mui/material"; +import { Token } from "@olympusdao/component-library"; +import { ethers } from "ethers"; +import { Link as RouterLink } from "react-router-dom"; +import { ReactComponent as lendAndBorrowIcon } from "src/assets/icons/lendAndBorrow.svg"; +import { formatCurrency } from "src/helpers"; +import { DecimalBigNumber } from "src/helpers/DecimalBigNumber/DecimalBigNumber"; +import { useCurrentIndex } from "src/hooks/useCurrentIndex"; +import { useOhmPrice } from "src/hooks/usePrices"; +import { useGetClearingHouse } from "src/views/Lending/Cooler/hooks/useGetClearingHouse"; +import { useGetCoolerLoans } from "src/views/Lending/Cooler/hooks/useGetCoolerLoans"; +import { useAccount } from "wagmi"; + +export const MyCoolerLoans = ({ balance, balanceUSD }: { balance: string; balanceUSD: string }) => { + const theme = useTheme(); + const { address } = useAccount(); + const { data: ohmPrice = 0 } = useOhmPrice(); + const { data: currentIndex = new DecimalBigNumber("0", 9) } = useCurrentIndex(); + const gOhmPrice = ohmPrice * currentIndex.toApproxNumber(); + + const { data: clearingHouseV1 } = useGetClearingHouse({ clearingHouse: "clearingHouseV1" }); + const { data: clearingHouseV2 } = useGetClearingHouse({ clearingHouse: "clearingHouseV2" }); + + const { data: v1Loans, isFetched: isFetchedLoansV1 } = useGetCoolerLoans({ + walletAddress: address, + factoryAddress: clearingHouseV1?.factory, + collateralAddress: clearingHouseV1?.collateralAddress, + debtAddress: clearingHouseV1?.debtAddress, + }); + + const { data: v2Loans, isFetched: isFetchedLoansV2 } = useGetCoolerLoans({ + walletAddress: address, + factoryAddress: clearingHouseV2?.factory, + collateralAddress: clearingHouseV2?.collateralAddress, + debtAddress: clearingHouseV2?.debtAddress, + }); + + const loans = [...(v1Loans || []), ...(v2Loans || [])]; + + if (loans.length === 0) { + return <> ; + } + + return ( + + + + + + In Cooler Loans + + + + + {balance} gOHM + + + {balanceUSD} + + + + + + + + + + Collateral + + + Term + + + {loans.map(loan => { + const requestDays = Number(ethers.utils.formatUnits(loan.request.duration.toString(), 0)) / 86400; + const expiryDate = new Date(Number(loan.expiry.toString()) * 1000); + const currentDate = new Date(); + const daysLeft = Math.floor((expiryDate.getTime() - currentDate.getTime()) / (1000 * 3600 * 24)); + const percentComplete = ((requestDays - daysLeft) / requestDays) * 100; + return ( + + + + + + {Number(ethers.utils.formatUnits(loan.collateral.toString())).toFixed(4)} gOHM + + + + {formatCurrency(gOhmPrice * Number(ethers.utils.formatUnits(loan.collateral.toString())), 2)} + + + + + + + + + {expiryDate.toLocaleDateString([], { + month: "short", + day: "numeric", + year: "numeric", + }) || ""} + + + + + ); + })} + + + Manage Cooler Loans + + + + + ); +}; diff --git a/src/views/MyBalances/MyGohmBalances.tsx b/src/views/MyBalances/MyGohmBalances.tsx new file mode 100644 index 0000000000..6920df81ad --- /dev/null +++ b/src/views/MyBalances/MyGohmBalances.tsx @@ -0,0 +1,111 @@ +import { Box, Divider, Link, SvgIcon, Typography, useTheme } from "@mui/material"; +import { PrimaryButton, SecondaryButton, Token } from "@olympusdao/component-library"; +import { Link as RouterLink } from "react-router-dom"; +import { ReactComponent as WalletIcon } from "src/assets/icons/wallet.svg"; +import { formatCurrency } from "src/helpers"; +import { DecimalBigNumber } from "src/helpers/DecimalBigNumber/DecimalBigNumber"; +import { useGohmBalance } from "src/hooks/useBalance"; +import { useCurrentIndex } from "src/hooks/useCurrentIndex"; +import { useOhmPrice } from "src/hooks/usePrices"; +import { useTestableNetworks } from "src/hooks/useTestableNetworks"; +import { NetworkId } from "src/networkDetails"; + +export const MyGohmBalances = ({ walletBalance }: { walletBalance?: DecimalBigNumber }) => { + const gohmBalances = useGohmBalance(); + const { data: currentIndex = new DecimalBigNumber("0", 9) } = useCurrentIndex(); + const { data: ohmPrice = 0 } = useOhmPrice(); + const gOhmPrice = ohmPrice * currentIndex.toApproxNumber(); + + const networks = useTestableNetworks(); + + const crossChain = [ + { + network: "ARBITRUM", + balance: gohmBalances[NetworkId.ARBITRUM].data, + }, + { + network: "AVALANCHE", + balance: gohmBalances[NetworkId.AVALANCHE].data, + }, + { + network: "POLYGON", + balance: gohmBalances[NetworkId.POLYGON].data, + }, + { + network: "FANTOM", + balance: gohmBalances[NetworkId.FANTOM].data, + }, + { + network: "OPTIMISM", + balance: gohmBalances[NetworkId.OPTIMISM].data, + }, + { + network: "BOBA", + balance: gohmBalances[NetworkId.BOBA].data, + }, + ]; + const crossChainWithBalances = crossChain.filter(chain => chain.balance?.gt(new DecimalBigNumber("0"))); + const theme = useTheme(); + return ( + + + + + + In Wallet + + + + + {(walletBalance && Number(walletBalance.toString()).toFixed(4)) || "0.00 "} + gOHM + + + {walletBalance ? formatCurrency(gOhmPrice * Number(walletBalance.toString()), 2) : "$0.00"} + + + + + + + + + + + + + + {Number(gohmBalances[networks.MAINNET].data?.toString()).toFixed(4) || "0.00"} + + + + Unwrap + + + {crossChainWithBalances.map(chain => { + return ( + + + + + + + + {Number((chain.balance || new DecimalBigNumber("0")).toString()).toFixed(4) || "0.00"} + + + + Bridge + + + ); + })} + + ); +}; diff --git a/src/views/MyBalances/MyOhmBalances.tsx b/src/views/MyBalances/MyOhmBalances.tsx new file mode 100644 index 0000000000..007aa919d5 --- /dev/null +++ b/src/views/MyBalances/MyOhmBalances.tsx @@ -0,0 +1,165 @@ +import { Box, Divider, Link, SvgIcon, Typography } from "@mui/material"; +import { PrimaryButton, SecondaryButton, Token } from "@olympusdao/component-library"; +import { useState } from "react"; +import { Link as RouterLink } from "react-router-dom"; +import { ReactComponent as WalletIcon } from "src/assets/icons/wallet.svg"; +import { MigrationNotification } from "src/components/MigrationNotification"; +import { isTestnet } from "src/helpers"; +import { DecimalBigNumber } from "src/helpers/DecimalBigNumber/DecimalBigNumber"; +import { nonNullable } from "src/helpers/types/nonNullable"; +import { + useOhmBalance, + useSohmBalance, + useV1OhmBalance, + useV1SohmBalance, + useWsohmBalance, +} from "src/hooks/useBalance"; +import { useTestableNetworks } from "src/hooks/useTestableNetworks"; +import { NetworkId } from "src/networkDetails"; +import { useNetwork } from "wagmi"; + +export const MyOhmBalances = ({ walletBalance }: { walletBalance?: DecimalBigNumber }) => { + const { chain = { id: 1 } } = useNetwork(); + const networks = useTestableNetworks(); + const ohmBalances = useOhmBalance(); + const wsohmBalances = useWsohmBalance(); + const { data: v1OhmBalance = new DecimalBigNumber("0", 9) } = useV1OhmBalance()[networks.MAINNET]; + const { data: v1SohmBalance = new DecimalBigNumber("0", 9) } = useV1SohmBalance()[networks.MAINNET]; + const { data: sOhmBalance = new DecimalBigNumber("0", 9) } = useSohmBalance()[networks.MAINNET]; + const ohmTokens = isTestnet(chain.id) + ? [ohmBalances[NetworkId.TESTNET_GOERLI].data, ohmBalances[NetworkId.ARBITRUM_GOERLI].data] + : [ohmBalances[NetworkId.MAINNET].data, ohmBalances[NetworkId.ARBITRUM].data]; + + const wsohmTokens = [ + wsohmBalances[NetworkId.MAINNET].data, + wsohmBalances[NetworkId.ARBITRUM].data, + wsohmBalances[NetworkId.AVALANCHE].data, + ]; + + const totalOhmBalance = ohmTokens + .filter(nonNullable) + .reduce((res, bal) => res.add(bal), new DecimalBigNumber("0", 18)); + + const totalWsohmBalance = wsohmTokens + .filter(nonNullable) + .reduce((res, bal) => res.add(bal), new DecimalBigNumber("0", 18)); + + const [modalOpen, setModalOpen] = useState(false); + return ( + + + + + + In Wallet + + + + + + + + + + + + + + {Number(ohmBalances[networks.MAINNET].data?.toString()).toFixed(4) || "0.00"} OHM + + + + Wrap + + + {ohmBalances[networks.ARBITRUM].data?.gt(new DecimalBigNumber("0")) && ( + + + + + + + + {Number(ohmBalances[networks.ARBITRUM].data?.toString()).toFixed(4) || "0.00"} OHM + + + + Bridge + + + )} + {sOhmBalance.gt(new DecimalBigNumber("0")) && ( + + + + + + + + {Number(sOhmBalance.toString()).toFixed(4) || "0.00"} sOHM + + + + Wrap + + + )} + {v1OhmBalance.gt(new DecimalBigNumber("0")) && ( + + + + + + + + {Number(v1OhmBalance.toString()).toFixed(4) || "0.00"} OHM (v1) + + + { + setModalOpen(true); + }} + > + Migrate + + + )} + {v1SohmBalance.gt(new DecimalBigNumber("0")) && ( + + + + + + + + {Number(v1SohmBalance.toString()).toFixed(4) || "0.00"} sOHM (v1) + + + { + setModalOpen(true); + }} + > + Migrate + + + )} + setModalOpen(false)} /> + + ); +}; diff --git a/src/views/MyBalances/index.tsx b/src/views/MyBalances/index.tsx new file mode 100644 index 0000000000..71397b4d06 --- /dev/null +++ b/src/views/MyBalances/index.tsx @@ -0,0 +1,237 @@ +import { Box, Typography, useMediaQuery } from "@mui/material"; +import { useTheme } from "@mui/material/styles"; +import { Token, WalletBalance } from "@olympusdao/component-library"; +import { FC } from "react"; +import { DevFaucet } from "src/components/DevFaucet"; +import PageTitle from "src/components/PageTitle"; +import { formatCurrency, formatNumber, isTestnet } from "src/helpers"; +import { DecimalBigNumber } from "src/helpers/DecimalBigNumber/DecimalBigNumber"; +import { nonNullable } from "src/helpers/types/nonNullable"; +import { + useGohmBalance, + useOhmBalance, + useSohmBalance, + useV1OhmBalance, + useV1SohmBalance, + useWsohmBalance, +} from "src/hooks/useBalance"; +import { useCurrentIndex } from "src/hooks/useCurrentIndex"; +import { useOhmPrice } from "src/hooks/usePrices"; +import { useTestableNetworks } from "src/hooks/useTestableNetworks"; +import { NetworkId } from "src/networkDetails"; +import { useGetClearingHouse } from "src/views/Lending/Cooler/hooks/useGetClearingHouse"; +import { useGetCoolerBalance } from "src/views/Lending/Cooler/hooks/useGetCoolerBalance"; +import { useGetCoolerForWallet } from "src/views/Lending/Cooler/hooks/useGetCoolerForWallet"; +import { LearnAboutGohm } from "src/views/MyBalances/LearnAboutGohm"; +import { LearnAboutOhm } from "src/views/MyBalances/LearnAboutOhm"; +import { MyCoolerLoans } from "src/views/MyBalances/MyCoolerLoans"; +import { MyGohmBalances } from "src/views/MyBalances/MyGohmBalances"; +import { MyOhmBalances } from "src/views/MyBalances/MyOhmBalances"; +import { useAccount, useNetwork } from "wagmi"; + +/** + * Component for Displaying Assets + */ + +export interface OHMAssetsProps { + path?: string; +} +export const MyBalances: FC = () => { + const { address } = useAccount(); + const networks = useTestableNetworks(); + const { chain = { id: 1 } } = useNetwork(); + const { data: ohmPrice = 0 } = useOhmPrice(); + const { data: currentIndex = new DecimalBigNumber("0", 9) } = useCurrentIndex(); + const { data: v1OhmBalance = new DecimalBigNumber("0", 9) } = useV1OhmBalance()[networks.MAINNET]; + const { data: v1SohmBalance = new DecimalBigNumber("0", 9) } = useV1SohmBalance()[networks.MAINNET]; + const { data: sOhmBalance = new DecimalBigNumber("0", 9) } = useSohmBalance()[networks.MAINNET]; + const wsohmBalances = useWsohmBalance(); + const gohmBalances = useGohmBalance(); + const ohmBalances = useOhmBalance(); + const { data: clearingHouseV1 } = useGetClearingHouse({ clearingHouse: "clearingHouseV1" }); + const { data: clearingHouseV2 } = useGetClearingHouse({ clearingHouse: "clearingHouseV2" }); + const { data: coolerAddressV1 } = useGetCoolerForWallet({ + walletAddress: address, + factoryAddress: clearingHouseV1?.factory, + collateralAddress: clearingHouseV1?.collateralAddress, + debtAddress: clearingHouseV1?.debtAddress, + clearingHouseVersion: "clearingHouseV1", + }); + const { data: coolerAddressV2 } = useGetCoolerForWallet({ + walletAddress: address, + factoryAddress: clearingHouseV2?.factory, + collateralAddress: clearingHouseV2?.collateralAddress, + debtAddress: clearingHouseV2?.debtAddress, + clearingHouseVersion: "clearingHouseV2", + }); + + const { data: coolerV1Balance } = useGetCoolerBalance({ coolerAddress: coolerAddressV1 }); + const { data: coolerV2Balance } = useGetCoolerBalance({ coolerAddress: coolerAddressV2 }); + + const ohmTokens = isTestnet(chain.id) + ? [ohmBalances[NetworkId.TESTNET_GOERLI].data, ohmBalances[NetworkId.ARBITRUM_GOERLI].data] + : [ohmBalances[NetworkId.MAINNET].data, ohmBalances[NetworkId.ARBITRUM].data]; + + const coolerTokens = [coolerV1Balance, coolerV2Balance]; + + const gohmTokens = [ + gohmBalances[networks.MAINNET].data, + gohmBalances[NetworkId.ARBITRUM].data, + gohmBalances[NetworkId.AVALANCHE].data, + gohmBalances[NetworkId.POLYGON].data, + gohmBalances[NetworkId.FANTOM].data, + gohmBalances[NetworkId.OPTIMISM].data, + ]; + + const gOHMAndCoolerTokens = [...gohmTokens, ...coolerTokens]; + const wsohmTokens = [ + wsohmBalances[NetworkId.MAINNET].data, + wsohmBalances[NetworkId.ARBITRUM].data, + wsohmBalances[NetworkId.AVALANCHE].data, + ]; + + const totalOhmBalance = ohmTokens + .filter(nonNullable) + .reduce((res, bal) => res.add(bal), new DecimalBigNumber("0", 18)); + + const totalGohmBalance = gOHMAndCoolerTokens + .filter(nonNullable) + .reduce((res, bal) => res.add(bal), new DecimalBigNumber("0", 18)); + + const gOhmWalletBalance = gohmTokens + .filter(nonNullable) + .reduce((res, bal) => res.add(bal), new DecimalBigNumber("0", 18)); + + const totalWsohmBalance = wsohmTokens + .filter(nonNullable) + .reduce((res, bal) => res.add(bal), new DecimalBigNumber("0", 18)); + + const totalCoolerBalance = coolerTokens + .filter(nonNullable) + .reduce((res, bal) => res.add(bal), new DecimalBigNumber("0", 18)); + + const formattedohmBalance = totalOhmBalance.toString({ decimals: 4, trim: false, format: true }); + const formattedgOhmBalance = totalGohmBalance.toString({ decimals: 4, trim: false, format: true }); + const gOhmPrice = ohmPrice * currentIndex.toApproxNumber(); + const coolerBalance = totalCoolerBalance.toString({ decimals: 4, trim: false, format: true }); + + const tokenArray = [ + { + assetValue: totalOhmBalance.toApproxNumber() * ohmPrice, + }, + { + assetValue: v1OhmBalance.toApproxNumber() * ohmPrice, + }, + { + assetValue: sOhmBalance.toApproxNumber() * ohmPrice, + }, + { + assetValue: v1SohmBalance.toApproxNumber() * ohmPrice, + }, + { + assetValue: gOhmPrice * totalWsohmBalance.toApproxNumber(), + }, + { + assetValue: gOhmPrice * totalGohmBalance.toApproxNumber(), + }, + { + assetValue: gOhmPrice * totalCoolerBalance.toApproxNumber(), + }, + ]; + + const walletTotalValueUSD = Object.values(tokenArray).reduce((totalValue, token) => totalValue + token.assetValue, 0); + const isMobileScreen = useMediaQuery("(max-width: 513px)"); + const theme = useTheme(); + + return ( +
+ + + + + + + + + + + + + + + + + OHM + + + + + {formattedohmBalance} OHM + + + {formatCurrency(ohmPrice * Number(totalOhmBalance.toString()), 2)} + + + + {Number(totalOhmBalance.toString()) > 0 ? : } + + + + + + + + + gOHM + + + + + {formattedgOhmBalance} gOHM + + + {formatCurrency(gOhmPrice * Number(totalGohmBalance.toString()), 2)} + + + + {Number(totalGohmBalance.toString()) > 0 ? ( + <> + + + + ) : ( + + )} + + + + {chain.id === NetworkId.TESTNET_GOERLI && } + + + + + +
+ ); +}; diff --git a/src/views/Stake/components/StakeArea/StakeArea.tsx b/src/views/Stake/components/StakeArea/StakeArea.tsx index cb2902aa72..40328a66bb 100644 --- a/src/views/Stake/components/StakeArea/StakeArea.tsx +++ b/src/views/Stake/components/StakeArea/StakeArea.tsx @@ -1,7 +1,6 @@ -import { Box, Divider } from "@mui/material"; +import { Box } from "@mui/material"; import { useState } from "react"; import PageTitle from "src/components/PageTitle"; -import AssetsIndex from "src/components/TopBar/Wallet/Assets"; import { StakeInputArea } from "src/views/Stake/components/StakeArea/components/StakeInputArea/StakeInputArea"; import { useAccount } from "wagmi"; @@ -14,14 +13,6 @@ export const StakeArea: React.FC = () => { - {isConnected && ( - - - - - - - )} ); From c42b11587a9c8f168b6a9b5f8bee613017a5ecb1 Mon Sep 17 00:00:00 2001 From: brightiron Date: Mon, 6 Nov 2023 17:54:52 -0600 Subject: [PATCH 04/17] modal and cleanup --- .../ConnectButton/ConnectButton.tsx | 6 +- src/views/MyBalances/MyGohmBalances.tsx | 2 +- src/views/MyBalances/index.tsx | 44 +++++++--- src/views/Stake/Stake.tsx | 55 ++---------- .../Stake/components/StakeArea/StakeArea.tsx | 2 - .../StakeInputArea/StakeInputArea.tsx | 86 +++++++++---------- 6 files changed, 87 insertions(+), 108 deletions(-) diff --git a/src/components/ConnectButton/ConnectButton.tsx b/src/components/ConnectButton/ConnectButton.tsx index 90ee1453fb..758d211d5b 100644 --- a/src/components/ConnectButton/ConnectButton.tsx +++ b/src/components/ConnectButton/ConnectButton.tsx @@ -130,6 +130,10 @@ export const ConnectButton = () => { cursor: "pointer", fontWeight: 500, background: theme.palette.mode === "light" ? theme.colors.paper.card : theme.colors.gray[600], + "&:hover": { + background: + theme.palette.mode === "light" ? theme.colors.paper.cardHover : theme.colors.gray[500], + }, }} > @@ -138,7 +142,7 @@ export const ConnectButton = () => {