From 46e5eb61836827413b0747e4c817cc5183cbb4fb Mon Sep 17 00:00:00 2001 From: Joaquin Battilana Date: Wed, 9 Aug 2023 00:10:25 +0100 Subject: [PATCH 01/46] feat: basic repay --- .../transactions/Repay/RepayActions.tsx | 250 +++++++++++++++--- 1 file changed, 215 insertions(+), 35 deletions(-) diff --git a/src/components/transactions/Repay/RepayActions.tsx b/src/components/transactions/Repay/RepayActions.tsx index 3b432f0ced..5be8263a99 100644 --- a/src/components/transactions/Repay/RepayActions.tsx +++ b/src/components/transactions/Repay/RepayActions.tsx @@ -1,11 +1,32 @@ -import { InterestRate, ProtocolAction } from '@aave/contract-helpers'; +import { + ApproveType, + gasLimitRecommendations, + InterestRate, + MAX_UINT_AMOUNT, + ProtocolAction, +} from '@aave/contract-helpers'; +import { SignatureLike } from '@ethersproject/bytes'; +import { TransactionResponse } from '@ethersproject/providers'; import { Trans } from '@lingui/macro'; import { BoxProps } from '@mui/material'; -import { useTransactionHandler } from 'src/helpers/useTransactionHandler'; +import { parseUnits } from 'ethers/lib/utils'; +import { useCallback, useEffect, useState } from 'react'; +import { MOCK_SIGNED_HASH } from 'src/helpers/useTransactionHandler'; import { ComputedReserveData } from 'src/hooks/app-data-provider/useAppDataProvider'; +import { useModalContext } from 'src/hooks/useModal'; +import { useWeb3Context } from 'src/libs/hooks/useWeb3Context'; import { useRootStore } from 'src/store/root'; +import { ApprovalMethod } from 'src/store/walletSlice'; +import { getErrorTextFromError, TxAction } from 'src/ui-config/errorMapping'; import { TxActionsWrapper } from '../TxActionsWrapper'; +import { APPROVAL_GAS_LIMIT, checkRequiresApproval } from '../utils'; + +interface SignedParams { + signature: SignatureLike; + deadline: string; + amount: string; +} export interface RepayActionProps extends BoxProps { amountToRepay: string; @@ -31,46 +52,205 @@ export const RepayActions = ({ blocked, ...props }: RepayActionProps) => { - const { repay, repayWithPermit, tryPermit } = useRootStore(); - - const usingPermit = tryPermit(poolAddress); - const { approval, action, requiresApproval, loadingTxns, approvalTxState, mainTxState } = - useTransactionHandler({ - tryPermit: usingPermit, - permitAction: ProtocolAction.repayWithPermit, - protocolAction: ProtocolAction.repay, - eventTxInfo: { - amount: amountToRepay, - assetName: poolReserve.name, - asset: poolReserve.underlyingAsset, - }, - handleGetTxns: async () => { - return repay({ - amountToRepay, - poolAddress, - repayWithATokens, - debtType, - poolReserve, - isWrongNetwork, - symbol, + const { + repay, + repayWithPermit, + tryPermit, + getApprovedAmount, + walletApprovalMethodPreference, + generateSignatureRequest, + generateApproval, + estimateGasLimit, + addTransaction, + } = useRootStore(); + const { signTxData, sendTx } = useWeb3Context(); + const [approvedAmount, setApprovedAmount] = useState(); + const [signatureParams, setSignatureParams] = useState(); + + const { + approvalTxState, + mainTxState, + loadingTxns, + setMainTxState, + setTxError, + setGasLimit, + setLoadingTxns, + setApprovalTxState, + } = useModalContext(); + + const [requiresApproval, setRequiresApproval] = useState(false); + const permitAvailable = tryPermit(poolAddress); + const usePermit = permitAvailable && walletApprovalMethodPreference === ApprovalMethod.PERMIT; + + const fetchApprovedAmount = useCallback( + async (forceApprovalCheck?: boolean) => { + // Check approved amount on-chain on first load or if an action triggers a re-check such as an approval being confirmed + if (!approvedAmount || forceApprovalCheck) { + setLoadingTxns(true); + const approvedAmount = await getApprovedAmount({ token: poolAddress }); + setApprovedAmount(approvedAmount); + } + + if (approvedAmount) { + const fetchedRequiresApproval = checkRequiresApproval({ + approvedAmount: approvedAmount.amount, + amount: amountToRepay, + signedAmount: signatureParams ? signatureParams.amount : '0', }); - }, - handleGetPermitTxns: async (signatures, deadline) => { - return repayWithPermit({ - amountToRepay, + setRequiresApproval(fetchedRequiresApproval); + if (fetchedRequiresApproval) setApprovalTxState({}); + } + + setLoadingTxns(false); + }, + [ + approvedAmount, + setLoadingTxns, + getApprovedAmount, + poolAddress, + amountToRepay, + signatureParams, + setApprovalTxState, + ] + ); + + const approval = async () => { + try { + if (requiresApproval && approvedAmount) { + if (usePermit) { + const deadline = Math.floor(Date.now() / 1000 + 3600).toString(); + const signatureRequest = await generateSignatureRequest({ + ...approvedAmount, + deadline, + amount: parseUnits(amountToRepay, poolReserve.decimals).toString(), + }); + + const response = await signTxData(signatureRequest); + setSignatureParams({ signature: response, deadline, amount: amountToRepay }); + setApprovalTxState({ + txHash: MOCK_SIGNED_HASH, + loading: false, + success: true, + }); + } else { + let approveTxData = generateApproval(approvedAmount); + setApprovalTxState({ ...approvalTxState, loading: true }); + approveTxData = await estimateGasLimit(approveTxData); + const response = await sendTx(approveTxData); + await response.wait(1); + setApprovalTxState({ + txHash: response.hash, + loading: false, + success: true, + }); + addTransaction(response.hash, { + action: ProtocolAction.approval, + txState: 'success', + asset: poolAddress, + amount: MAX_UINT_AMOUNT, + assetName: symbol, + }); + fetchApprovedAmount(true); + } + } + } catch (error) { + const parsedError = getErrorTextFromError(error, TxAction.GAS_ESTIMATION, false); + setTxError(parsedError); + setApprovalTxState({ + txHash: undefined, + loading: false, + }); + } + }; + + const action = async () => { + try { + setMainTxState({ ...mainTxState, loading: true }); + + let response: TransactionResponse; + let action = ProtocolAction.default; + + // determine if approval is signature or transaction + // checking user preference is not sufficient because permit may be available but the user has an existing approval + if (usePermit && signatureParams) { + action = ProtocolAction.supplyWithPermit; + let signedSupplyWithPermitTxData = repayWithPermit({ + amountToRepay: parseUnits(amountToRepay, poolReserve.decimals).toString(), poolReserve, isWrongNetwork, poolAddress, symbol, debtType, repayWithATokens, - signature: signatures[0], - deadline, + signature: signatureParams.signature, + deadline: signatureParams.deadline, + }); + + signedSupplyWithPermitTxData = await estimateGasLimit(signedSupplyWithPermitTxData); + response = await sendTx(signedSupplyWithPermitTxData); + + await response.wait(1); + } else { + action = ProtocolAction.supply; + let supplyTxData = repay({ + amountToRepay: parseUnits(amountToRepay, poolReserve.decimals).toString(), + poolAddress, + repayWithATokens, + debtType, + poolReserve, + isWrongNetwork, + symbol, }); - }, - skip: !amountToRepay || parseFloat(amountToRepay) === 0 || blocked, - deps: [amountToRepay, poolAddress, repayWithATokens], - }); + supplyTxData = await estimateGasLimit(supplyTxData); + response = await sendTx(supplyTxData); + + await response.wait(1); + } + + setMainTxState({ + txHash: response.hash, + loading: false, + success: true, + }); + + addTransaction(response.hash, { + action, + txState: 'success', + asset: poolAddress, + amount: amountToRepay, + assetName: symbol, + }); + + queryClient.invalidateQueries({ queryKey: [QueryKeys.POOL_TOKENS] }); + refetchPoolData && refetchPoolData(); + refetchIncentiveData && refetchIncentiveData(); + refetchGhoData && refetchGhoData(); + } catch (error) { + const parsedError = getErrorTextFromError(error, TxAction.GAS_ESTIMATION, false); + setTxError(parsedError); + setMainTxState({ + txHash: undefined, + loading: false, + }); + } + }; + + useEffect(() => { + fetchApprovedAmount(); + }, [fetchApprovedAmount, poolAddress]); + + useEffect(() => { + let supplyGasLimit = 0; + if (usePermit) { + supplyGasLimit = Number(gasLimitRecommendations[ProtocolAction.supplyWithPermit].recommended); + } else { + supplyGasLimit = Number(gasLimitRecommendations[ProtocolAction.supply].recommended); + if (requiresApproval && !approvalTxState.success) { + supplyGasLimit += Number(APPROVAL_GAS_LIMIT); + } + } + setGasLimit(supplyGasLimit.toString()); + }, [requiresApproval, approvalTxState, usePermit, setGasLimit]); return ( approval([{ amount: amountToRepay, underlyingAsset: poolAddress }])} actionText={Repay {symbol}} actionInProgressText={Repaying {symbol}} - tryPermit={usingPermit} + tryPermit={permitAvailable} /> ); }; From 448260cea4d3dcd5f0baf1b8630d47bf56107eb8 Mon Sep 17 00:00:00 2001 From: Joaquin Battilana Date: Thu, 24 Aug 2023 02:26:25 +0100 Subject: [PATCH 02/46] feat: repay bundle --- package.json | 2 +- .../transactions/Repay/RepayActions.tsx | 71 +++++++------------ src/store/poolSlice.ts | 48 +++++++------ yarn.lock | 8 +-- 4 files changed, 58 insertions(+), 71 deletions(-) diff --git a/package.json b/package.json index 53e3199680..5ce404a911 100644 --- a/package.json +++ b/package.json @@ -32,7 +32,7 @@ "test:coverage": "jest --coverage" }, "dependencies": { - "@aave/contract-helpers": "1.18.2", + "@aave/contract-helpers": "1.19.1-45458494b8e59c90f88fae315d34749099213262.0", "@aave/math-utils": "1.18.2", "@bgd-labs/aave-address-book": "^1.30.0", "@emotion/cache": "11.10.3", diff --git a/src/components/transactions/Repay/RepayActions.tsx b/src/components/transactions/Repay/RepayActions.tsx index 5be8263a99..87b5be475e 100644 --- a/src/components/transactions/Repay/RepayActions.tsx +++ b/src/components/transactions/Repay/RepayActions.tsx @@ -10,14 +10,17 @@ import { TransactionResponse } from '@ethersproject/providers'; import { Trans } from '@lingui/macro'; import { BoxProps } from '@mui/material'; import { parseUnits } from 'ethers/lib/utils'; -import { useCallback, useEffect, useState } from 'react'; +import { queryClient } from 'pages/_app.page'; +import { useCallback, useEffect, useMemo, useState } from 'react'; import { MOCK_SIGNED_HASH } from 'src/helpers/useTransactionHandler'; +import { useBackgroundDataProvider } from 'src/hooks/app-data-provider/BackgroundDataProvider'; import { ComputedReserveData } from 'src/hooks/app-data-provider/useAppDataProvider'; import { useModalContext } from 'src/hooks/useModal'; import { useWeb3Context } from 'src/libs/hooks/useWeb3Context'; import { useRootStore } from 'src/store/root'; import { ApprovalMethod } from 'src/store/walletSlice'; import { getErrorTextFromError, TxAction } from 'src/ui-config/errorMapping'; +import { QueryKeys } from 'src/ui-config/queries'; import { TxActionsWrapper } from '../TxActionsWrapper'; import { APPROVAL_GAS_LIMIT, checkRequiresApproval } from '../utils'; @@ -64,9 +67,9 @@ export const RepayActions = ({ addTransaction, } = useRootStore(); const { signTxData, sendTx } = useWeb3Context(); + const { refetchGhoData, refetchIncentiveData, refetchPoolData } = useBackgroundDataProvider(); const [approvedAmount, setApprovedAmount] = useState(); const [signatureParams, setSignatureParams] = useState(); - const { approvalTxState, mainTxState, @@ -78,45 +81,28 @@ export const RepayActions = ({ setApprovalTxState, } = useModalContext(); - const [requiresApproval, setRequiresApproval] = useState(false); const permitAvailable = tryPermit(poolAddress); + console.log(permitAvailable); const usePermit = permitAvailable && walletApprovalMethodPreference === ApprovalMethod.PERMIT; - const fetchApprovedAmount = useCallback( - async (forceApprovalCheck?: boolean) => { - // Check approved amount on-chain on first load or if an action triggers a re-check such as an approval being confirmed - if (!approvedAmount || forceApprovalCheck) { - setLoadingTxns(true); - const approvedAmount = await getApprovedAmount({ token: poolAddress }); - setApprovedAmount(approvedAmount); - } - - if (approvedAmount) { - const fetchedRequiresApproval = checkRequiresApproval({ - approvedAmount: approvedAmount.amount, - amount: amountToRepay, - signedAmount: signatureParams ? signatureParams.amount : '0', - }); - setRequiresApproval(fetchedRequiresApproval); - if (fetchedRequiresApproval) setApprovalTxState({}); - } - - setLoadingTxns(false); - }, - [ - approvedAmount, - setLoadingTxns, - getApprovedAmount, - poolAddress, - amountToRepay, - signatureParams, - setApprovalTxState, - ] - ); + const requiresApproval = useMemo(() => { + return checkRequiresApproval({ + approvedAmount: approvedAmount?.amount || '0', + amount: amountToRepay, + signedAmount: signatureParams ? signatureParams.amount : '0', + }); + }, [amountToRepay, signatureParams, approvedAmount]); + + const fetchApprovedAmount = useCallback(async () => { + setLoadingTxns(true); + const approvedAmountPool = await getApprovedAmount({ token: poolAddress }); + setApprovedAmount(approvedAmountPool); + setLoadingTxns(false); + }, [setLoadingTxns, getApprovedAmount, poolAddress]); const approval = async () => { try { - if (requiresApproval && approvedAmount) { + if (approvedAmount) { if (usePermit) { const deadline = Math.floor(Date.now() / 1000 + 3600).toString(); const signatureRequest = await generateSignatureRequest({ @@ -150,7 +136,6 @@ export const RepayActions = ({ amount: MAX_UINT_AMOUNT, assetName: symbol, }); - fetchApprovedAmount(true); } } } catch (error) { @@ -170,10 +155,8 @@ export const RepayActions = ({ let response: TransactionResponse; let action = ProtocolAction.default; - // determine if approval is signature or transaction - // checking user preference is not sufficient because permit may be available but the user has an existing approval if (usePermit && signatureParams) { - action = ProtocolAction.supplyWithPermit; + action = ProtocolAction.repayWithPermit; let signedSupplyWithPermitTxData = repayWithPermit({ amountToRepay: parseUnits(amountToRepay, poolReserve.decimals).toString(), poolReserve, @@ -188,10 +171,9 @@ export const RepayActions = ({ signedSupplyWithPermitTxData = await estimateGasLimit(signedSupplyWithPermitTxData); response = await sendTx(signedSupplyWithPermitTxData); - await response.wait(1); } else { - action = ProtocolAction.supply; + action = ProtocolAction.repay; let supplyTxData = repay({ amountToRepay: parseUnits(amountToRepay, poolReserve.decimals).toString(), poolAddress, @@ -203,16 +185,13 @@ export const RepayActions = ({ }); supplyTxData = await estimateGasLimit(supplyTxData); response = await sendTx(supplyTxData); - await response.wait(1); } - setMainTxState({ txHash: response.hash, loading: false, success: true, }); - addTransaction(response.hash, { action, txState: 'success', @@ -237,7 +216,7 @@ export const RepayActions = ({ useEffect(() => { fetchApprovedAmount(); - }, [fetchApprovedAmount, poolAddress]); + }, [fetchApprovedAmount]); useEffect(() => { let supplyGasLimit = 0; @@ -266,7 +245,7 @@ export const RepayActions = ({ sx={sx} {...props} handleAction={action} - handleApproval={() => approval([{ amount: amountToRepay, underlyingAsset: poolAddress }])} + handleApproval={approval} actionText={Repay {symbol}} actionInProgressText={Repaying {symbol}} tryPermit={permitAvailable} diff --git a/src/store/poolSlice.ts b/src/store/poolSlice.ts index e26b6527ad..f838bcdf80 100644 --- a/src/store/poolSlice.ts +++ b/src/store/poolSlice.ts @@ -11,7 +11,6 @@ import { IncentivesController, IncentivesControllerV2, IncentivesControllerV2Interface, - InterestRate, LendingPool, LendingPoolBundle, MAX_UINT_AMOUNT, @@ -92,13 +91,13 @@ export interface PoolSlice { claimRewards: (args: ClaimRewardsActionsProps) => Promise; // TODO: optimize types to use only neccessary properties swapCollateral: (args: SwapActionProps) => Promise; - repay: (args: RepayActionProps) => Promise; + repay: (args: RepayActionProps) => PopulatedTransaction; repayWithPermit: ( args: RepayActionProps & { signature: SignatureLike; deadline: string; } - ) => Promise; + ) => PopulatedTransaction; poolComputed: { minRemainingBaseTokenBalance: string; }; @@ -551,38 +550,47 @@ export const createPoolSlice: StateCreator< }); }, repay: ({ repayWithATokens, amountToRepay, poolAddress, debtType }) => { - const pool = getCorrectPool(); + const poolBundle = getCorrectPoolBundle(); const currentAccount = get().account; - if (pool instanceof Pool && repayWithATokens) { - return pool.repayWithATokens({ - user: currentAccount, - reserve: poolAddress, - amount: amountToRepay, - rateMode: debtType as InterestRate, - useOptimizedPath: get().useOptimizedPath(), - }); + if (poolBundle instanceof PoolBundle) { + if (repayWithATokens) { + return poolBundle.repayWithATokensTxBuilder.generateTxData({ + user: currentAccount, + reserve: poolAddress, + amount: amountToRepay, + useOptimizedPath: get().useOptimizedPath(), + rateMode: debtType, + }); + } else { + return poolBundle.repayTxBuilder.generateTxData({ + user: currentAccount, + reserve: poolAddress, + amount: amountToRepay, + useOptimizedPath: get().useOptimizedPath(), + interestRateMode: debtType, + }); + } } else { - return pool.repay({ + const lendingPool = poolBundle as LendingPoolBundle; + return lendingPool.repayTxBuilder.generateTxData({ user: currentAccount, reserve: poolAddress, amount: amountToRepay, interestRateMode: debtType, - useOptimizedPath: get().useOptimizedPath(), }); } }, repayWithPermit: ({ poolAddress, amountToRepay, debtType, deadline, signature }) => { - // Better to get rid of direct assert - const pool = getCorrectPool() as Pool; + const poolBundle = getCorrectPoolBundle() as PoolBundle; const currentAccount = get().account; - return pool.repayWithPermit({ + return poolBundle.repayTxBuilder.generateSignedTxData({ user: currentAccount, reserve: poolAddress, - amount: amountToRepay, // amountToRepay.toString(), - interestRateMode: debtType, - signature, + amount: amountToRepay, useOptimizedPath: get().useOptimizedPath(), + interestRateMode: debtType, deadline, + signature, }); }, swapCollateral: async ({ diff --git a/yarn.lock b/yarn.lock index 6b197fa330..e78fc0d21f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,10 +2,10 @@ # yarn lockfile v1 -"@aave/contract-helpers@1.18.2": - version "1.18.2" - resolved "https://registry.yarnpkg.com/@aave/contract-helpers/-/contract-helpers-1.18.2.tgz#1c614ae9498f2bb30fa09932d364dbf3548f7e39" - integrity sha512-xzVUkOEyLJl/UmztJyGoHVtjnkc3+0eZc3fvpncvfl6QLK+JLFGFNCPaXdLCaBzh1FXZX8m/pSprMZteCIWs4g== +"@aave/contract-helpers@1.19.1-45458494b8e59c90f88fae315d34749099213262.0": + version "1.19.1-45458494b8e59c90f88fae315d34749099213262.0" + resolved "https://registry.yarnpkg.com/@aave/contract-helpers/-/contract-helpers-1.19.1-45458494b8e59c90f88fae315d34749099213262.0.tgz#35666cb54cfd952c41d077d1a1d243edcb30956a" + integrity sha512-Vcoe8NOcRPbnlGf/Oik42KFP19jcfz1X6hNL4StKrYRKQYhSuSn9wsro5e6Wz4o40flXrHyNDCpB0Mns6EmtTA== dependencies: isomorphic-unfetch "^3.1.0" From 2aafd9f91d3330374b806ba2ee990b590cb0d489 Mon Sep 17 00:00:00 2001 From: Mark Grothe Date: Wed, 6 Sep 2023 16:15:26 -0500 Subject: [PATCH 03/46] fix: temp package --- yarn.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/yarn.lock b/yarn.lock index b99a881a0f..6e9d122938 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,10 +2,10 @@ # yarn lockfile v1 -"@aave/contract-helpers@^1.20.0": - version "1.20.0" - resolved "https://registry.yarnpkg.com/@aave/contract-helpers/-/contract-helpers-1.20.0.tgz#4ff6afb540402ff2ffef3b08cbcc80a688b627d1" - integrity sha512-LrHswh/g1fyTpZ4fKHO2jdGjDe/2ligz47xZp/b23IS+b2eXxvTqOtPvDyyAXyYvcmK6Ce3zYYAUk2jaMOGoNg== +"@aave/contract-helpers@1.20.1-9a9b6935eb38067043d6773ef5b53be01fc9b667.0+641b8a1": + version "1.20.1-9a9b6935eb38067043d6773ef5b53be01fc9b667.0" + resolved "https://registry.yarnpkg.com/@aave/contract-helpers/-/contract-helpers-1.20.1-9a9b6935eb38067043d6773ef5b53be01fc9b667.0.tgz#7d3e370d0751c36cee25f915d94f701bde67645e" + integrity sha512-SrgfUaLs+95r39kFCBdSvYoy6pe1K2MiRLWFW5lhIyw/+Rl/dqtaLAGNQJzT9ms2aJPa5Xhb2YOypQ4o/EzoJg== dependencies: isomorphic-unfetch "^3.1.0" From 94b1ebdd6ca4a1126d1fee0da2e48e696f438f26 Mon Sep 17 00:00:00 2001 From: Mark Grothe Date: Thu, 7 Sep 2023 15:04:34 -0500 Subject: [PATCH 04/46] feat: approved amount fetching (#1777) * feat: consolidating shared approval logic * feat: useApprovalTx hook * fix: refetch on mount always to fetch on modal open * fix: apply refetch on mount * fix: check for amount before requiring approval * fix: removed duplicate file * fix: cleanup * fix: clean up loading states, remove uneeded useEffects * fix: don't automatically refetch approval amounts * fix: don't automatically refetch approved amounts --- .../transactions/Repay/RepayActions.tsx | 119 ++++--------- .../transactions/Supply/SupplyActions.tsx | 162 +++++------------- .../transactions/TxActionsWrapper.tsx | 2 +- src/hooks/useApprovalTx.tsx | 108 ++++++++++++ src/hooks/useApprovedAmount.tsx | 37 ++++ src/services/ApprovedAmountService.ts | 52 ++++++ src/store/poolSlice.ts | 10 -- src/ui-config/SharedDependenciesProvider.tsx | 4 + src/ui-config/queries.ts | 6 +- src/ui-config/queries.tsx | 12 -- 10 files changed, 290 insertions(+), 222 deletions(-) create mode 100644 src/hooks/useApprovalTx.tsx create mode 100644 src/hooks/useApprovedAmount.tsx create mode 100644 src/services/ApprovedAmountService.ts delete mode 100644 src/ui-config/queries.tsx diff --git a/src/components/transactions/Repay/RepayActions.tsx b/src/components/transactions/Repay/RepayActions.tsx index 87b5be475e..881851a4a1 100644 --- a/src/components/transactions/Repay/RepayActions.tsx +++ b/src/components/transactions/Repay/RepayActions.tsx @@ -1,20 +1,14 @@ -import { - ApproveType, - gasLimitRecommendations, - InterestRate, - MAX_UINT_AMOUNT, - ProtocolAction, -} from '@aave/contract-helpers'; -import { SignatureLike } from '@ethersproject/bytes'; +import { gasLimitRecommendations, InterestRate, ProtocolAction } from '@aave/contract-helpers'; import { TransactionResponse } from '@ethersproject/providers'; import { Trans } from '@lingui/macro'; import { BoxProps } from '@mui/material'; import { parseUnits } from 'ethers/lib/utils'; import { queryClient } from 'pages/_app.page'; -import { useCallback, useEffect, useMemo, useState } from 'react'; -import { MOCK_SIGNED_HASH } from 'src/helpers/useTransactionHandler'; +import { useEffect, useState } from 'react'; import { useBackgroundDataProvider } from 'src/hooks/app-data-provider/BackgroundDataProvider'; import { ComputedReserveData } from 'src/hooks/app-data-provider/useAppDataProvider'; +import { SignedParams, useApprovalTx } from 'src/hooks/useApprovalTx'; +import { usePoolApprovedAmount } from 'src/hooks/useApprovedAmount'; import { useModalContext } from 'src/hooks/useModal'; import { useWeb3Context } from 'src/libs/hooks/useWeb3Context'; import { useRootStore } from 'src/store/root'; @@ -25,12 +19,6 @@ import { QueryKeys } from 'src/ui-config/queries'; import { TxActionsWrapper } from '../TxActionsWrapper'; import { APPROVAL_GAS_LIMIT, checkRequiresApproval } from '../utils'; -interface SignedParams { - signature: SignatureLike; - deadline: string; - amount: string; -} - export interface RepayActionProps extends BoxProps { amountToRepay: string; poolReserve: ComputedReserveData; @@ -59,16 +47,12 @@ export const RepayActions = ({ repay, repayWithPermit, tryPermit, - getApprovedAmount, walletApprovalMethodPreference, - generateSignatureRequest, - generateApproval, estimateGasLimit, addTransaction, } = useRootStore(); - const { signTxData, sendTx } = useWeb3Context(); + const { sendTx } = useWeb3Context(); const { refetchGhoData, refetchIncentiveData, refetchPoolData } = useBackgroundDataProvider(); - const [approvedAmount, setApprovedAmount] = useState(); const [signatureParams, setSignatureParams] = useState(); const { approvalTxState, @@ -81,72 +65,49 @@ export const RepayActions = ({ setApprovalTxState, } = useModalContext(); + const { + data: approvedAmount, + refetch: fetchApprovedAmount, + isFetching: fetchingApprovedAmount, + isFetchedAfterMount, + } = usePoolApprovedAmount(poolAddress); + const permitAvailable = tryPermit(poolAddress); - console.log(permitAvailable); const usePermit = permitAvailable && walletApprovalMethodPreference === ApprovalMethod.PERMIT; - const requiresApproval = useMemo(() => { - return checkRequiresApproval({ + setLoadingTxns(fetchingApprovedAmount); + + const requiresApproval = + Number(amountToRepay) !== 0 && + checkRequiresApproval({ approvedAmount: approvedAmount?.amount || '0', amount: amountToRepay, signedAmount: signatureParams ? signatureParams.amount : '0', }); - }, [amountToRepay, signatureParams, approvedAmount]); - const fetchApprovedAmount = useCallback(async () => { - setLoadingTxns(true); - const approvedAmountPool = await getApprovedAmount({ token: poolAddress }); - setApprovedAmount(approvedAmountPool); - setLoadingTxns(false); - }, [setLoadingTxns, getApprovedAmount, poolAddress]); + if (requiresApproval && approvalTxState?.success) { + // There was a successful approval tx, but the approval amount is not enough. + // Clear the state to prompt for another approval. + setApprovalTxState({}); + } + + const { approval } = useApprovalTx({ + usePermit, + approvedAmount, + requiresApproval, + assetAddress: poolAddress, + symbol, + decimals: poolReserve.decimals, + signatureAmount: amountToRepay, + onApprovalTxConfirmed: fetchApprovedAmount, + onSignTxCompleted: (signedParams) => setSignatureParams(signedParams), + }); - const approval = async () => { - try { - if (approvedAmount) { - if (usePermit) { - const deadline = Math.floor(Date.now() / 1000 + 3600).toString(); - const signatureRequest = await generateSignatureRequest({ - ...approvedAmount, - deadline, - amount: parseUnits(amountToRepay, poolReserve.decimals).toString(), - }); - - const response = await signTxData(signatureRequest); - setSignatureParams({ signature: response, deadline, amount: amountToRepay }); - setApprovalTxState({ - txHash: MOCK_SIGNED_HASH, - loading: false, - success: true, - }); - } else { - let approveTxData = generateApproval(approvedAmount); - setApprovalTxState({ ...approvalTxState, loading: true }); - approveTxData = await estimateGasLimit(approveTxData); - const response = await sendTx(approveTxData); - await response.wait(1); - setApprovalTxState({ - txHash: response.hash, - loading: false, - success: true, - }); - addTransaction(response.hash, { - action: ProtocolAction.approval, - txState: 'success', - asset: poolAddress, - amount: MAX_UINT_AMOUNT, - assetName: symbol, - }); - } - } - } catch (error) { - const parsedError = getErrorTextFromError(error, TxAction.GAS_ESTIMATION, false); - setTxError(parsedError); - setApprovalTxState({ - txHash: undefined, - loading: false, - }); + useEffect(() => { + if (!isFetchedAfterMount) { + fetchApprovedAmount(); } - }; + }, [fetchApprovedAmount, isFetchedAfterMount]); const action = async () => { try { @@ -214,10 +175,6 @@ export const RepayActions = ({ } }; - useEffect(() => { - fetchApprovedAmount(); - }, [fetchApprovedAmount]); - useEffect(() => { let supplyGasLimit = 0; if (usePermit) { diff --git a/src/components/transactions/Supply/SupplyActions.tsx b/src/components/transactions/Supply/SupplyActions.tsx index e1d01d83bc..bb8a1e0b82 100644 --- a/src/components/transactions/Supply/SupplyActions.tsx +++ b/src/components/transactions/Supply/SupplyActions.tsx @@ -1,18 +1,13 @@ -import { - ApproveType, - gasLimitRecommendations, - MAX_UINT_AMOUNT, - ProtocolAction, -} from '@aave/contract-helpers'; -import { SignatureLike } from '@ethersproject/bytes'; +import { gasLimitRecommendations, ProtocolAction } from '@aave/contract-helpers'; import { TransactionResponse } from '@ethersproject/providers'; import { Trans } from '@lingui/macro'; import { BoxProps } from '@mui/material'; import { parseUnits } from 'ethers/lib/utils'; import { queryClient } from 'pages/_app.page'; -import React, { useCallback, useEffect, useState } from 'react'; -import { MOCK_SIGNED_HASH } from 'src/helpers/useTransactionHandler'; +import React, { useEffect, useState } from 'react'; import { useBackgroundDataProvider } from 'src/hooks/app-data-provider/BackgroundDataProvider'; +import { SignedParams, useApprovalTx } from 'src/hooks/useApprovalTx'; +import { usePoolApprovedAmount } from 'src/hooks/useApprovedAmount'; import { useModalContext } from 'src/hooks/useModal'; import { useWeb3Context } from 'src/libs/hooks/useWeb3Context'; import { useRootStore } from 'src/store/root'; @@ -33,12 +28,6 @@ export interface SupplyActionProps extends BoxProps { decimals: number; } -interface SignedParams { - signature: SignatureLike; - deadline: string; - amount: string; -} - export const SupplyActions = React.memo( ({ amountToSupply, @@ -54,9 +43,6 @@ export const SupplyActions = React.memo( tryPermit, supply, supplyWithPermit, - getApprovedAmount, - generateSignatureRequest, - generateApproval, walletApprovalMethodPreference, estimateGasLimit, addTransaction, @@ -64,9 +50,6 @@ export const SupplyActions = React.memo( state.tryPermit, state.supply, state.supplyWithPermit, - state.getApprovedAmount, - state.generateSignatureRequest, - state.generateApproval, state.walletApprovalMethodPreference, state.estimateGasLimit, state.addTransaction, @@ -83,50 +66,52 @@ export const SupplyActions = React.memo( } = useModalContext(); const { refetchPoolData, refetchIncentiveData, refetchGhoData } = useBackgroundDataProvider(); const permitAvailable = tryPermit(poolAddress); - const { signTxData, sendTx } = useWeb3Context(); + const { sendTx } = useWeb3Context(); - const [usePermit, setUsePermit] = useState(false); - const [approvedAmount, setApprovedAmount] = useState(); - const [requiresApproval, setRequiresApproval] = useState(false); const [signatureParams, setSignatureParams] = useState(); - // callback to fetch approved amount and determine execution path on dependency updates - const fetchApprovedAmount = useCallback( - async (forceApprovalCheck?: boolean) => { - // Check approved amount on-chain on first load or if an action triggers a re-check such as an approval being confirmed - if (!approvedAmount || forceApprovalCheck) { - setLoadingTxns(true); - const approvedAmount = await getApprovedAmount({ token: poolAddress }); - setApprovedAmount(approvedAmount); - } - - if (approvedAmount) { - const fetchedRequiresApproval = checkRequiresApproval({ - approvedAmount: approvedAmount.amount, - amount: amountToSupply, - signedAmount: signatureParams ? signatureParams.amount : '0', - }); - setRequiresApproval(fetchedRequiresApproval); - if (fetchedRequiresApproval) setApprovalTxState({}); - } - - setLoadingTxns(false); - }, - [ - approvedAmount, - setLoadingTxns, - getApprovedAmount, - poolAddress, - amountToSupply, - signatureParams, - setApprovalTxState, - ] - ); + const { + data: approvedAmount, + refetch: fetchApprovedAmount, + isRefetching: fetchingApprovedAmount, + isFetchedAfterMount, + } = usePoolApprovedAmount(poolAddress); + + setLoadingTxns(fetchingApprovedAmount); + + const requiresApproval = + Number(amountToSupply) !== 0 && + checkRequiresApproval({ + approvedAmount: approvedAmount?.amount || '0', + amount: amountToSupply, + signedAmount: signatureParams ? signatureParams.amount : '0', + }); + + if (requiresApproval && approvalTxState?.success) { + // There was a successful approval tx, but the approval amount is not enough. + // Clear the state to prompt for another approval. + setApprovalTxState({}); + } + + const usePermit = permitAvailable && walletApprovalMethodPreference === ApprovalMethod.PERMIT; + + const { approval } = useApprovalTx({ + usePermit, + approvedAmount, + requiresApproval, + assetAddress: poolAddress, + symbol, + decimals, + signatureAmount: amountToSupply, + onApprovalTxConfirmed: fetchApprovedAmount, + onSignTxCompleted: (signedParams) => setSignatureParams(signedParams), + }); - // Run on first load to decide execution path useEffect(() => { - fetchApprovedAmount(); - }, [fetchApprovedAmount]); + if (!isFetchedAfterMount) { + fetchApprovedAmount(); + } + }, [fetchApprovedAmount, isFetchedAfterMount]); // Update gas estimation useEffect(() => { @@ -144,61 +129,6 @@ export const SupplyActions = React.memo( setGasLimit(supplyGasLimit.toString()); }, [requiresApproval, approvalTxState, usePermit, setGasLimit]); - useEffect(() => { - const preferPermit = - permitAvailable && walletApprovalMethodPreference === ApprovalMethod.PERMIT; - setUsePermit(preferPermit); - }, [permitAvailable, walletApprovalMethodPreference]); - - const approval = async () => { - try { - if (requiresApproval && approvedAmount) { - if (usePermit) { - const deadline = Math.floor(Date.now() / 1000 + 3600).toString(); - const signatureRequest = await generateSignatureRequest({ - ...approvedAmount, - deadline, - amount: parseUnits(amountToSupply, decimals).toString(), - }); - - const response = await signTxData(signatureRequest); - setSignatureParams({ signature: response, deadline, amount: amountToSupply }); - setApprovalTxState({ - txHash: MOCK_SIGNED_HASH, - loading: false, - success: true, - }); - } else { - let approveTxData = generateApproval(approvedAmount); - setApprovalTxState({ ...approvalTxState, loading: true }); - approveTxData = await estimateGasLimit(approveTxData); - const response = await sendTx(approveTxData); - await response.wait(1); - setApprovalTxState({ - txHash: response.hash, - loading: false, - success: true, - }); - addTransaction(response.hash, { - action: ProtocolAction.approval, - txState: 'success', - asset: poolAddress, - amount: MAX_UINT_AMOUNT, - assetName: symbol, - }); - fetchApprovedAmount(true); - } - } - } catch (error) { - const parsedError = getErrorTextFromError(error, TxAction.GAS_ESTIMATION, false); - setTxError(parsedError); - setApprovalTxState({ - txHash: undefined, - loading: false, - }); - } - }; - const action = async () => { try { setMainTxState({ ...mainTxState, loading: true }); @@ -273,7 +203,7 @@ export const SupplyActions = React.memo( preparingTransactions={loadingTxns} actionText={Supply {symbol}} actionInProgressText={Supplying {symbol}} - handleApproval={() => approval()} + handleApproval={approval} handleAction={action} requiresApproval={requiresApproval} tryPermit={permitAvailable} diff --git a/src/components/transactions/TxActionsWrapper.tsx b/src/components/transactions/TxActionsWrapper.tsx index 587a554aad..af16ded1bd 100644 --- a/src/components/transactions/TxActionsWrapper.tsx +++ b/src/components/transactions/TxActionsWrapper.tsx @@ -127,7 +127,7 @@ export const TxActionsWrapper = ({ const approvalParams = getApprovalParams(); return ( - {requiresApproval && !readOnlyModeAddress && ( + {approvalParams && !readOnlyModeAddress && ( diff --git a/src/hooks/useApprovalTx.tsx b/src/hooks/useApprovalTx.tsx new file mode 100644 index 0000000000..26f0c90558 --- /dev/null +++ b/src/hooks/useApprovalTx.tsx @@ -0,0 +1,108 @@ +import { ApproveType, MAX_UINT_AMOUNT, ProtocolAction } from '@aave/contract-helpers'; +import { SignatureLike } from '@ethersproject/bytes'; +import { parseUnits } from 'ethers/lib/utils'; +import { MOCK_SIGNED_HASH } from 'src/helpers/useTransactionHandler'; +import { useWeb3Context } from 'src/libs/hooks/useWeb3Context'; +import { useRootStore } from 'src/store/root'; +import { getErrorTextFromError, TxAction } from 'src/ui-config/errorMapping'; + +import { useModalContext } from './useModal'; + +export interface SignedParams { + signature: SignatureLike; + deadline: string; + amount: string; +} + +export const useApprovalTx = ({ + usePermit, + approvedAmount, + requiresApproval, + assetAddress, + symbol, + decimals, + signatureAmount, + onApprovalTxConfirmed, + onSignTxCompleted, +}: { + usePermit: boolean; + approvedAmount: ApproveType | undefined; + requiresApproval: boolean; + assetAddress: string; + symbol: string; + decimals: number; + signatureAmount: string; + onApprovalTxConfirmed?: () => void; + onSignTxCompleted?: (signedParams: SignedParams) => void; +}) => { + const [generateApproval, generateSignatureRequest, estimateGasLimit, addTransaction] = + useRootStore((store) => [ + store.generateApproval, + store.generateSignatureRequest, + store.estimateGasLimit, + store.addTransaction, + ]); + + const { signTxData, sendTx } = useWeb3Context(); + + const { approvalTxState, setApprovalTxState, setTxError } = useModalContext(); + + const approval = async () => { + try { + if (requiresApproval && approvedAmount) { + if (usePermit) { + const deadline = Math.floor(Date.now() / 1000 + 3600).toString(); + const signatureRequest = await generateSignatureRequest({ + ...approvedAmount, + deadline, + amount: parseUnits(signatureAmount, decimals).toString(), + }); + + const response = await signTxData(signatureRequest); + if (onSignTxCompleted) { + onSignTxCompleted({ signature: response, deadline, amount: signatureAmount }); + } + + setApprovalTxState({ + txHash: MOCK_SIGNED_HASH, + loading: false, + success: true, + }); + } else { + let approveTxData = generateApproval(approvedAmount); + setApprovalTxState({ ...approvalTxState, loading: true }); + approveTxData = await estimateGasLimit(approveTxData); + const response = await sendTx(approveTxData); + await response.wait(1); + setApprovalTxState({ + txHash: response.hash, + loading: false, + success: true, + }); + addTransaction(response.hash, { + action: ProtocolAction.approval, + txState: 'success', + asset: assetAddress, + amount: MAX_UINT_AMOUNT, + assetName: symbol, + }); + + if (onApprovalTxConfirmed) { + onApprovalTxConfirmed(); + } + } + } + } catch (error) { + const parsedError = getErrorTextFromError(error, TxAction.GAS_ESTIMATION, false); + setTxError(parsedError); + setApprovalTxState({ + txHash: undefined, + loading: false, + }); + } + }; + + return { + approval, + }; +}; diff --git a/src/hooks/useApprovedAmount.tsx b/src/hooks/useApprovedAmount.tsx new file mode 100644 index 0000000000..6f8cb46366 --- /dev/null +++ b/src/hooks/useApprovedAmount.tsx @@ -0,0 +1,37 @@ +import { useQuery } from '@tanstack/react-query'; +import { useRootStore } from 'src/store/root'; +import { QueryKeys } from 'src/ui-config/queries'; +import { useSharedDependencies } from 'src/ui-config/SharedDependenciesProvider'; + +export const useApprovedAmount = ({ + token, + spender, +}: { + user: string; + token: string; + spender: string; +}) => { + const { approvedAmountService } = useSharedDependencies(); + const user = useRootStore((store) => store.account); + return useQuery({ + queryFn: () => approvedAmountService.getApprovedAmount(user, token, spender), + queryKey: [QueryKeys.APPROVED_AMOUNT, user, token, spender], + enabled: !!user, + refetchOnMount: false, + refetchOnWindowFocus: false, + refetchOnReconnect: false, + }); +}; + +export const usePoolApprovedAmount = (token: string) => { + const { approvedAmountService } = useSharedDependencies(); + const user = useRootStore((store) => store.account); + return useQuery({ + queryFn: () => approvedAmountService.getPoolApprovedAmount(user, token), + queryKey: [QueryKeys.POOL_APPROVED_AMOUNT, user, token], + enabled: !!user, + refetchOnMount: false, + refetchOnWindowFocus: false, + refetchOnReconnect: false, + }); +}; diff --git a/src/services/ApprovedAmountService.ts b/src/services/ApprovedAmountService.ts new file mode 100644 index 0000000000..a49b4d99e4 --- /dev/null +++ b/src/services/ApprovedAmountService.ts @@ -0,0 +1,52 @@ +import { ApproveType, ERC20Service, LendingPoolBundle, PoolBundle } from '@aave/contract-helpers'; +import { Provider } from '@ethersproject/providers'; +import { MarketDataType } from 'src/ui-config/marketsConfig'; +import { Hashable } from 'src/utils/types'; + +export class ApprovedAmountService implements Hashable { + private readonly ERC20Service: ERC20Service; + private readonly PoolBundleService: PoolBundle | LendingPoolBundle; + + constructor(provider: Provider, public readonly currentMarketData: MarketDataType) { + this.ERC20Service = new ERC20Service(provider); + + if (currentMarketData.v3) { + this.PoolBundleService = new PoolBundle(provider, { + POOL: currentMarketData.addresses.LENDING_POOL, + WETH_GATEWAY: currentMarketData.addresses.WETH_GATEWAY, + L2_ENCODER: currentMarketData.addresses.L2_ENCODER, + }); + } else { + this.PoolBundleService = new LendingPoolBundle(provider, { + LENDING_POOL: currentMarketData.addresses.LENDING_POOL, + WETH_GATEWAY: currentMarketData.addresses.WETH_GATEWAY, + }); + } + } + + async getPoolApprovedAmount(user: string, token: string): Promise { + if (this.PoolBundleService instanceof PoolBundle) { + return this.PoolBundleService.supplyTxBuilder.getApprovedAmount({ + user, + token, + }); + } else { + return this.PoolBundleService.depositTxBuilder.getApprovedAmount({ + user, + token, + }); + } + } + + async getApprovedAmount(user: string, token: string, spender: string): Promise { + return this.ERC20Service.approvedAmount({ + user, + token, + spender, + }); + } + + public toHash() { + return this.currentMarketData.chainId.toString(); + } +} diff --git a/src/store/poolSlice.ts b/src/store/poolSlice.ts index db6a39ab5b..2882ce2841 100644 --- a/src/store/poolSlice.ts +++ b/src/store/poolSlice.ts @@ -112,7 +112,6 @@ export interface PoolSlice { generateApproval: (args: ApproveType) => PopulatedTransaction; supply: (args: Omit) => PopulatedTransaction; supplyWithPermit: (args: Omit) => PopulatedTransaction; - getApprovedAmount: (args: { token: string }) => Promise; borrow: (args: Omit) => PopulatedTransaction; getCreditDelegationApprovedAmount: ( args: Omit @@ -315,15 +314,6 @@ export const createPoolSlice: StateCreator< signature, }); }, - getApprovedAmount: async (args: { token: string }) => { - const poolBundle = getCorrectPoolBundle(); - const user = get().account; - if (poolBundle instanceof PoolBundle) { - return poolBundle.supplyTxBuilder.getApprovedAmount({ user, token: args.token }); - } else { - return poolBundle.depositTxBuilder.getApprovedAmount({ user, token: args.token }); - } - }, borrow: (args: Omit) => { const poolBundle = getCorrectPoolBundle(); const currentAccount = get().account; diff --git a/src/ui-config/SharedDependenciesProvider.tsx b/src/ui-config/SharedDependenciesProvider.tsx index d68c1b9c92..998eec26ba 100644 --- a/src/ui-config/SharedDependenciesProvider.tsx +++ b/src/ui-config/SharedDependenciesProvider.tsx @@ -1,4 +1,5 @@ import { createContext, useContext } from 'react'; +import { ApprovedAmountService } from 'src/services/ApprovedAmountService'; import { GovernanceService } from 'src/services/GovernanceService'; import { UiStakeDataService } from 'src/services/UiStakeDataService'; import { WalletBalanceService } from 'src/services/WalletBalanceService'; @@ -14,6 +15,7 @@ interface SharedDependenciesContext { governanceWalletBalanceService: WalletBalanceService; poolTokensBalanceService: WalletBalanceService; uiStakeDataService: UiStakeDataService; + approvedAmountService: ApprovedAmountService; } const SharedDependenciesContext = createContext(null); @@ -54,6 +56,7 @@ export const SharedDependenciesProvider: React.FC = ({ children }) => { stakeConfig.stakeDataProvider, stakingChainId ); + const approvedAmountService = new ApprovedAmountService(currentProvider, currentMarketData); return ( { governanceWalletBalanceService, poolTokensBalanceService, uiStakeDataService, + approvedAmountService, }} > {children} diff --git a/src/ui-config/queries.ts b/src/ui-config/queries.ts index a8472c8aec..0014e5e5a8 100644 --- a/src/ui-config/queries.ts +++ b/src/ui-config/queries.ts @@ -1,5 +1,5 @@ -export enum QueryKeys { - POWERS = 'POWERS', +export const enum QueryKeys { + USE_POWERS = 'USE_POWERS', VOTE_ON_PROPOSAL = 'VOTE_ON_PROPOSAL', VOTING_POWER_AT = 'VOTING_POWER_AT', GOVERNANCE_TOKENS = 'GOVERNANCE_TOKENS', @@ -7,6 +7,8 @@ export enum QueryKeys { POOL_TOKENS = 'POOL_TOKENS', GENERAL_STAKE_UI_DATA = 'GENERAL_STAKE_UI_DATA', USER_STAKE_UI_DATA = 'USER_STAKE_UI_DATA', + APPROVED_AMOUNT = 'APPROVED_AMOUNT', + POOL_APPROVED_AMOUNT = 'POOL_APPROVED_AMOUNT', } export const POLLING_INTERVAL = 60000; diff --git a/src/ui-config/queries.tsx b/src/ui-config/queries.tsx deleted file mode 100644 index 83288bf272..0000000000 --- a/src/ui-config/queries.tsx +++ /dev/null @@ -1,12 +0,0 @@ -export enum QueryKeys { - USE_POWERS = 'USE_POWERS', - VOTE_ON_PROPOSAL = 'VOTE_ON_PROPOSAL', - VOTING_POWER_AT = 'VOTING_POWER_AT', - GOVERNANCE_TOKENS = 'GOVERNANCE_TOKENS', - POOL_TOKENS = 'POOL_TOKENS', - GENERAL_STAKE_UI_DATA = 'GENERAL_STAKE_UI_DATA', - USER_STAKE_UI_DATA = 'USER_STAKE_UI_DATA', - TRANSACTION_HISTORY = 'TRANSACTION_HISTORY', -} - -export const POOLING_INTERVAL = 60000; From 97c2445744ac30771a2e4fa0c91fbe3645ea8375 Mon Sep 17 00:00:00 2001 From: Mark Grothe Date: Thu, 7 Sep 2023 15:15:33 -0500 Subject: [PATCH 05/46] fix: query key name --- src/ui-config/queries.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ui-config/queries.ts b/src/ui-config/queries.ts index 0014e5e5a8..ea6fe136a6 100644 --- a/src/ui-config/queries.ts +++ b/src/ui-config/queries.ts @@ -1,5 +1,5 @@ export const enum QueryKeys { - USE_POWERS = 'USE_POWERS', + POWERS = 'POWERS', VOTE_ON_PROPOSAL = 'VOTE_ON_PROPOSAL', VOTING_POWER_AT = 'VOTING_POWER_AT', GOVERNANCE_TOKENS = 'GOVERNANCE_TOKENS', From 13d516cba420b6832e0bf7f181a05832ac7dc636 Mon Sep 17 00:00:00 2001 From: Mark Grothe Date: Thu, 7 Sep 2023 22:25:12 -0500 Subject: [PATCH 06/46] fix: disable approval until first load --- src/components/transactions/Repay/RepayActions.tsx | 2 +- src/components/transactions/Supply/SupplyActions.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/transactions/Repay/RepayActions.tsx b/src/components/transactions/Repay/RepayActions.tsx index 881851a4a1..cfa476f050 100644 --- a/src/components/transactions/Repay/RepayActions.tsx +++ b/src/components/transactions/Repay/RepayActions.tsx @@ -191,7 +191,7 @@ export const RepayActions = ({ return ( Supply {symbol}} actionInProgressText={Supplying {symbol}} handleApproval={approval} From a284a0eb570e91d8a3abd1e553ce5a9e2319920c Mon Sep 17 00:00:00 2001 From: Mark Grothe Date: Thu, 7 Sep 2023 22:52:14 -0500 Subject: [PATCH 07/46] fix: don't subscribe to entire store --- src/components/transactions/Repay/RepayActions.tsx | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/components/transactions/Repay/RepayActions.tsx b/src/components/transactions/Repay/RepayActions.tsx index cfa476f050..9fc69e45f7 100644 --- a/src/components/transactions/Repay/RepayActions.tsx +++ b/src/components/transactions/Repay/RepayActions.tsx @@ -43,14 +43,21 @@ export const RepayActions = ({ blocked, ...props }: RepayActionProps) => { - const { + const [ repay, repayWithPermit, tryPermit, walletApprovalMethodPreference, estimateGasLimit, addTransaction, - } = useRootStore(); + ] = useRootStore((store) => [ + store.repay, + store.repayWithPermit, + store.tryPermit, + store.walletApprovalMethodPreference, + store.estimateGasLimit, + store.addTransaction, + ]); const { sendTx } = useWeb3Context(); const { refetchGhoData, refetchIncentiveData, refetchPoolData } = useBackgroundDataProvider(); const [signatureParams, setSignatureParams] = useState(); From 9b016a3e029bb9c1018d301ad64686f1c61d4e53 Mon Sep 17 00:00:00 2001 From: Mark Grothe Date: Fri, 8 Sep 2023 12:22:54 -0500 Subject: [PATCH 08/46] fix: bundle size --- src/services/ApprovedAmountService.ts | 33 ++++++-------- src/store/poolSlice.ts | 45 +++++++++++--------- src/ui-config/SharedDependenciesProvider.tsx | 7 ++- 3 files changed, 44 insertions(+), 41 deletions(-) diff --git a/src/services/ApprovedAmountService.ts b/src/services/ApprovedAmountService.ts index a49b4d99e4..56e13529fc 100644 --- a/src/services/ApprovedAmountService.ts +++ b/src/services/ApprovedAmountService.ts @@ -1,37 +1,32 @@ -import { ApproveType, ERC20Service, LendingPoolBundle, PoolBundle } from '@aave/contract-helpers'; +import { + ApproveType, + ERC20Service, + LendingPoolBundleInterface, + PoolBundleInterface, +} from '@aave/contract-helpers'; import { Provider } from '@ethersproject/providers'; import { MarketDataType } from 'src/ui-config/marketsConfig'; import { Hashable } from 'src/utils/types'; export class ApprovedAmountService implements Hashable { private readonly ERC20Service: ERC20Service; - private readonly PoolBundleService: PoolBundle | LendingPoolBundle; - constructor(provider: Provider, public readonly currentMarketData: MarketDataType) { + constructor( + private bundle: PoolBundleInterface | LendingPoolBundleInterface, + private currentMarketData: MarketDataType, + provider: Provider + ) { this.ERC20Service = new ERC20Service(provider); - - if (currentMarketData.v3) { - this.PoolBundleService = new PoolBundle(provider, { - POOL: currentMarketData.addresses.LENDING_POOL, - WETH_GATEWAY: currentMarketData.addresses.WETH_GATEWAY, - L2_ENCODER: currentMarketData.addresses.L2_ENCODER, - }); - } else { - this.PoolBundleService = new LendingPoolBundle(provider, { - LENDING_POOL: currentMarketData.addresses.LENDING_POOL, - WETH_GATEWAY: currentMarketData.addresses.WETH_GATEWAY, - }); - } } async getPoolApprovedAmount(user: string, token: string): Promise { - if (this.PoolBundleService instanceof PoolBundle) { - return this.PoolBundleService.supplyTxBuilder.getApprovedAmount({ + if ('supplyTxBuilder' in this.bundle) { + return this.bundle.supplyTxBuilder.getApprovedAmount({ user, token, }); } else { - return this.PoolBundleService.depositTxBuilder.getApprovedAmount({ + return this.bundle.depositTxBuilder.getApprovedAmount({ user, token, }); diff --git a/src/store/poolSlice.ts b/src/store/poolSlice.ts index 2882ce2841..5c521bc76b 100644 --- a/src/store/poolSlice.ts +++ b/src/store/poolSlice.ts @@ -13,11 +13,13 @@ import { IncentivesControllerV2Interface, LendingPool, LendingPoolBundle, + LendingPoolBundleInterface, MAX_UINT_AMOUNT, PermitSignature, Pool, PoolBaseCurrencyHumanized, PoolBundle, + PoolBundleInterface, ReserveDataHumanized, ReservesIncentiveDataHumanized, UiIncentiveDataProvider, @@ -124,6 +126,7 @@ export interface PoolSlice { ) => Promise; generateApproveDelegation: (args: Omit) => PopulatedTransaction; estimateGasLimit: (tx: PopulatedTransaction) => Promise; + getCorrectPoolBundle: () => PoolBundleInterface | LendingPoolBundleInterface; } export const createPoolSlice: StateCreator< @@ -152,24 +155,24 @@ export const createPoolSlice: StateCreator< }); } } - function getCorrectPoolBundle() { - const currentMarketData = get().currentMarketData; - const provider = get().jsonRpcProvider(); - if (currentMarketData.v3) { - return new PoolBundle(provider, { - POOL: currentMarketData.addresses.LENDING_POOL, - WETH_GATEWAY: currentMarketData.addresses.WETH_GATEWAY, - L2_ENCODER: currentMarketData.addresses.L2_ENCODER, - }); - } else { - return new LendingPoolBundle(provider, { - LENDING_POOL: currentMarketData.addresses.LENDING_POOL, - WETH_GATEWAY: currentMarketData.addresses.WETH_GATEWAY, - }); - } - } return { data: new Map(), + getCorrectPoolBundle() { + const currentMarketData = get().currentMarketData; + const provider = get().jsonRpcProvider(); + if (currentMarketData.v3) { + return new PoolBundle(provider, { + POOL: currentMarketData.addresses.LENDING_POOL, + WETH_GATEWAY: currentMarketData.addresses.WETH_GATEWAY, + L2_ENCODER: currentMarketData.addresses.L2_ENCODER, + }); + } else { + return new LendingPoolBundle(provider, { + LENDING_POOL: currentMarketData.addresses.LENDING_POOL, + WETH_GATEWAY: currentMarketData.addresses.WETH_GATEWAY, + }); + } + }, refreshPoolData: async (marketData?: MarketDataType) => { const account = get().account; const currentChainId = get().currentChainId; @@ -283,7 +286,7 @@ export const createPoolSlice: StateCreator< return tokenERC20Service.approveTxData({ ...args, amount: MAX_UINT_AMOUNT }); }, supply: (args: Omit) => { - const poolBundle = getCorrectPoolBundle(); + const poolBundle = get().getCorrectPoolBundle(); const currentAccount = get().account; if (poolBundle instanceof PoolBundle) { return poolBundle.supplyTxBuilder.generateTxData({ @@ -302,7 +305,7 @@ export const createPoolSlice: StateCreator< } }, supplyWithPermit: (args: Omit) => { - const poolBundle = getCorrectPoolBundle() as PoolBundle; + const poolBundle = get().getCorrectPoolBundle() as PoolBundle; const user = get().account; const signature = utils.joinSignature(args.signature); return poolBundle.supplyTxBuilder.generateSignedTxData({ @@ -315,7 +318,7 @@ export const createPoolSlice: StateCreator< }); }, borrow: (args: Omit) => { - const poolBundle = getCorrectPoolBundle(); + const poolBundle = get().getCorrectPoolBundle(); const currentAccount = get().account; if (poolBundle instanceof PoolBundle) { return poolBundle.borrowTxBuilder.generateTxData({ @@ -539,7 +542,7 @@ export const createPoolSlice: StateCreator< }); }, repay: ({ repayWithATokens, amountToRepay, poolAddress, debtType }) => { - const poolBundle = getCorrectPoolBundle(); + const poolBundle = get().getCorrectPoolBundle(); const currentAccount = get().account; if (poolBundle instanceof PoolBundle) { if (repayWithATokens) { @@ -570,7 +573,7 @@ export const createPoolSlice: StateCreator< } }, repayWithPermit: ({ poolAddress, amountToRepay, debtType, deadline, signature }) => { - const poolBundle = getCorrectPoolBundle() as PoolBundle; + const poolBundle = get().getCorrectPoolBundle() as PoolBundle; const currentAccount = get().account; return poolBundle.repayTxBuilder.generateSignedTxData({ user: currentAccount, diff --git a/src/ui-config/SharedDependenciesProvider.tsx b/src/ui-config/SharedDependenciesProvider.tsx index 998eec26ba..88299e5723 100644 --- a/src/ui-config/SharedDependenciesProvider.tsx +++ b/src/ui-config/SharedDependenciesProvider.tsx @@ -23,6 +23,7 @@ const SharedDependenciesContext = createContext { const currentNetworkConfig = useRootStore((state) => state.currentNetworkConfig); const currentMarketData = useRootStore((state) => state.currentMarketData); + const bundle = useRootStore((state) => state.getCorrectPoolBundle()); const isGovernanceFork = currentNetworkConfig.isFork && currentNetworkConfig.underlyingChainId === governanceConfig.chainId; @@ -56,7 +57,11 @@ export const SharedDependenciesProvider: React.FC = ({ children }) => { stakeConfig.stakeDataProvider, stakingChainId ); - const approvedAmountService = new ApprovedAmountService(currentProvider, currentMarketData); + const approvedAmountService = new ApprovedAmountService( + bundle, + currentMarketData, + currentProvider + ); return ( Date: Mon, 11 Sep 2023 13:12:24 -0500 Subject: [PATCH 09/46] fix: don't require approval if repaying with aTokens --- src/components/transactions/Repay/RepayActions.tsx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/components/transactions/Repay/RepayActions.tsx b/src/components/transactions/Repay/RepayActions.tsx index 9fc69e45f7..3ff07000d5 100644 --- a/src/components/transactions/Repay/RepayActions.tsx +++ b/src/components/transactions/Repay/RepayActions.tsx @@ -85,6 +85,7 @@ export const RepayActions = ({ setLoadingTxns(fetchingApprovedAmount); const requiresApproval = + !repayWithATokens && Number(amountToRepay) !== 0 && checkRequiresApproval({ approvedAmount: approvedAmount?.amount || '0', @@ -111,10 +112,10 @@ export const RepayActions = ({ }); useEffect(() => { - if (!isFetchedAfterMount) { + if (!isFetchedAfterMount && !repayWithATokens) { fetchApprovedAmount(); } - }, [fetchApprovedAmount, isFetchedAfterMount]); + }, [fetchApprovedAmount, isFetchedAfterMount, repayWithATokens]); const action = async () => { try { From 423ce22d60f43355872e3b62b39bd79345af018b Mon Sep 17 00:00:00 2001 From: Mark Grothe Date: Wed, 4 Oct 2023 13:03:22 -0500 Subject: [PATCH 10/46] fix: lazy load services --- src/services/ApprovedAmountService.ts | 62 +++++++++++++++----- src/ui-config/SharedDependenciesProvider.tsx | 7 +-- 2 files changed, 47 insertions(+), 22 deletions(-) diff --git a/src/services/ApprovedAmountService.ts b/src/services/ApprovedAmountService.ts index 56e13529fc..5dfea7512c 100644 --- a/src/services/ApprovedAmountService.ts +++ b/src/services/ApprovedAmountService.ts @@ -1,6 +1,6 @@ import { ApproveType, - ERC20Service, + IERC20ServiceInterface, LendingPoolBundleInterface, PoolBundleInterface, } from '@aave/contract-helpers'; @@ -9,32 +9,62 @@ import { MarketDataType } from 'src/ui-config/marketsConfig'; import { Hashable } from 'src/utils/types'; export class ApprovedAmountService implements Hashable { - private readonly ERC20Service: ERC20Service; - - constructor( - private bundle: PoolBundleInterface | LendingPoolBundleInterface, - private currentMarketData: MarketDataType, - provider: Provider - ) { - this.ERC20Service = new ERC20Service(provider); + private ERC20Service: IERC20ServiceInterface | undefined; + private PoolService: PoolBundleInterface | undefined; + private LendingPoolService: LendingPoolBundleInterface | undefined; + + constructor(private currentMarketData: MarketDataType, private provider: Provider) {} + + private async getERC20Service() { + if (!this.ERC20Service) { + this.ERC20Service = new (await import('@aave/contract-helpers')).ERC20Service(this.provider); + } + + return this.ERC20Service; + } + + private async getPoolService() { + if (!this.PoolService) { + this.PoolService = new (await import('@aave/contract-helpers')).PoolBundle(this.provider, { + POOL: this.currentMarketData.addresses.LENDING_POOL, + WETH_GATEWAY: this.currentMarketData.addresses.WETH_GATEWAY, + L2_ENCODER: this.currentMarketData.addresses.L2_ENCODER, + }); + } + + return this.PoolService; + } + + private async getLendingPoolService() { + if (!this.LendingPoolService) { + this.LendingPoolService = new (await import('@aave/contract-helpers')).LendingPoolBundle( + this.provider, + { + LENDING_POOL: this.currentMarketData.addresses.LENDING_POOL, + WETH_GATEWAY: this.currentMarketData.addresses.WETH_GATEWAY, + } + ); + } + + return this.LendingPoolService; } async getPoolApprovedAmount(user: string, token: string): Promise { - if ('supplyTxBuilder' in this.bundle) { - return this.bundle.supplyTxBuilder.getApprovedAmount({ + if (this.currentMarketData.v3) { + const pool = await this.getPoolService(); + return pool.supplyTxBuilder.getApprovedAmount({ user, token, }); } else { - return this.bundle.depositTxBuilder.getApprovedAmount({ - user, - token, - }); + const lendingPool = await this.getLendingPoolService(); + return lendingPool.depositTxBuilder.getApprovedAmount({ user, token }); } } async getApprovedAmount(user: string, token: string, spender: string): Promise { - return this.ERC20Service.approvedAmount({ + const service = await this.getERC20Service(); + return service.approvedAmount({ user, token, spender, diff --git a/src/ui-config/SharedDependenciesProvider.tsx b/src/ui-config/SharedDependenciesProvider.tsx index 88299e5723..43151b473f 100644 --- a/src/ui-config/SharedDependenciesProvider.tsx +++ b/src/ui-config/SharedDependenciesProvider.tsx @@ -23,7 +23,6 @@ const SharedDependenciesContext = createContext { const currentNetworkConfig = useRootStore((state) => state.currentNetworkConfig); const currentMarketData = useRootStore((state) => state.currentMarketData); - const bundle = useRootStore((state) => state.getCorrectPoolBundle()); const isGovernanceFork = currentNetworkConfig.isFork && currentNetworkConfig.underlyingChainId === governanceConfig.chainId; @@ -57,11 +56,7 @@ export const SharedDependenciesProvider: React.FC = ({ children }) => { stakeConfig.stakeDataProvider, stakingChainId ); - const approvedAmountService = new ApprovedAmountService( - bundle, - currentMarketData, - currentProvider - ); + const approvedAmountService = new ApprovedAmountService(currentMarketData, currentProvider); return ( Date: Thu, 5 Oct 2023 13:28:03 -0500 Subject: [PATCH 11/46] fix: use latest temp utils --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 7807de4306..57a8ac3254 100644 --- a/package.json +++ b/package.json @@ -32,7 +32,7 @@ "test:coverage": "jest --coverage" }, "dependencies": { - "@aave/contract-helpers": "1.20.1-9a9b6935eb38067043d6773ef5b53be01fc9b667.0+641b8a1", + "@aave/contract-helpers": "1.20.1-8d191bf193b4e5f74af4086481eb6f23a17f39e5.0+3d83c37", "@aave/math-utils": "^1.20.0", "@bgd-labs/aave-address-book": "^2.0.0", "@emotion/cache": "11.10.3", diff --git a/yarn.lock b/yarn.lock index 6e9d122938..744642e971 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,10 +2,10 @@ # yarn lockfile v1 -"@aave/contract-helpers@1.20.1-9a9b6935eb38067043d6773ef5b53be01fc9b667.0+641b8a1": - version "1.20.1-9a9b6935eb38067043d6773ef5b53be01fc9b667.0" - resolved "https://registry.yarnpkg.com/@aave/contract-helpers/-/contract-helpers-1.20.1-9a9b6935eb38067043d6773ef5b53be01fc9b667.0.tgz#7d3e370d0751c36cee25f915d94f701bde67645e" - integrity sha512-SrgfUaLs+95r39kFCBdSvYoy6pe1K2MiRLWFW5lhIyw/+Rl/dqtaLAGNQJzT9ms2aJPa5Xhb2YOypQ4o/EzoJg== +"@aave/contract-helpers@1.20.1-8d191bf193b4e5f74af4086481eb6f23a17f39e5.0+3d83c37": + version "1.20.1-8d191bf193b4e5f74af4086481eb6f23a17f39e5.0" + resolved "https://registry.yarnpkg.com/@aave/contract-helpers/-/contract-helpers-1.20.1-8d191bf193b4e5f74af4086481eb6f23a17f39e5.0.tgz#2ef2357f91d13808737d8bdf7250f25c92624961" + integrity sha512-lLvX/nZ+JwiHWRURb2LifcqX4EW1utdu8STHXqs1LskTbnsoFUpytRXCpMj1EbdnJ6p1aNHpVJrTRQhxNysnLw== dependencies: isomorphic-unfetch "^3.1.0" From 83fe81cb930730b162857b18a1860674236841dc Mon Sep 17 00:00:00 2001 From: Joaquin Battilana Date: Tue, 10 Oct 2023 12:50:38 +0100 Subject: [PATCH 12/46] chore: bump aave utilities --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 7807de4306..761e66b5f9 100644 --- a/package.json +++ b/package.json @@ -32,7 +32,7 @@ "test:coverage": "jest --coverage" }, "dependencies": { - "@aave/contract-helpers": "1.20.1-9a9b6935eb38067043d6773ef5b53be01fc9b667.0+641b8a1", + "@aave/contract-helpers": "1.20.1-8d191bf193b4e5f74af4086481eb6f23a17f39e5.0", "@aave/math-utils": "^1.20.0", "@bgd-labs/aave-address-book": "^2.0.0", "@emotion/cache": "11.10.3", diff --git a/yarn.lock b/yarn.lock index 6e9d122938..06ab9e859d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,10 +2,10 @@ # yarn lockfile v1 -"@aave/contract-helpers@1.20.1-9a9b6935eb38067043d6773ef5b53be01fc9b667.0+641b8a1": - version "1.20.1-9a9b6935eb38067043d6773ef5b53be01fc9b667.0" - resolved "https://registry.yarnpkg.com/@aave/contract-helpers/-/contract-helpers-1.20.1-9a9b6935eb38067043d6773ef5b53be01fc9b667.0.tgz#7d3e370d0751c36cee25f915d94f701bde67645e" - integrity sha512-SrgfUaLs+95r39kFCBdSvYoy6pe1K2MiRLWFW5lhIyw/+Rl/dqtaLAGNQJzT9ms2aJPa5Xhb2YOypQ4o/EzoJg== +"@aave/contract-helpers@1.20.1-8d191bf193b4e5f74af4086481eb6f23a17f39e5.0": + version "1.20.1-8d191bf193b4e5f74af4086481eb6f23a17f39e5.0" + resolved "https://registry.yarnpkg.com/@aave/contract-helpers/-/contract-helpers-1.20.1-8d191bf193b4e5f74af4086481eb6f23a17f39e5.0.tgz#2ef2357f91d13808737d8bdf7250f25c92624961" + integrity sha512-lLvX/nZ+JwiHWRURb2LifcqX4EW1utdu8STHXqs1LskTbnsoFUpytRXCpMj1EbdnJ6p1aNHpVJrTRQhxNysnLw== dependencies: isomorphic-unfetch "^3.1.0" From 0ec4bdf7976ea71bd5141c69f31bb688a803b9ec Mon Sep 17 00:00:00 2001 From: Joaquin Battilana Date: Wed, 11 Oct 2023 23:50:53 +0100 Subject: [PATCH 13/46] chore: upgraded package utilities --- package.json | 4 ++-- yarn.lock | 16 ++++++++-------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/package.json b/package.json index a068223d1f..24d7711ee2 100644 --- a/package.json +++ b/package.json @@ -32,8 +32,8 @@ "test:coverage": "jest --coverage" }, "dependencies": { - "@aave/contract-helpers": "1.21.0", - "@aave/math-utils": "^1.21.0", + "@aave/contract-helpers": "1.20.1-8d191bf193b4e5f74af4086481eb6f23a17f39e5.0", + "@aave/math-utils": "1.20.1-8d191bf193b4e5f74af4086481eb6f23a17f39e5.0", "@bgd-labs/aave-address-book": "^2.7.0", "@emotion/cache": "11.10.3", "@emotion/react": "11.10.4", diff --git a/yarn.lock b/yarn.lock index a472b2610c..1f7e17ae1d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,17 +2,17 @@ # yarn lockfile v1 -"@aave/contract-helpers@1.21.0": - version "1.21.0" - resolved "https://registry.yarnpkg.com/@aave/contract-helpers/-/contract-helpers-1.21.0.tgz#9081a7aab4bc84818584494c344e99ef3e1dffec" - integrity sha512-vlTZyX5yDHli4u4zXNcI74JRcWToPSL3ARdax80Kauu+9L8SxjWNcbIfPrCvvQ7j0HY8tYDg4O4FYRjwu62N3Q== +"@aave/contract-helpers@1.20.1-8d191bf193b4e5f74af4086481eb6f23a17f39e5.0": + version "1.20.1-8d191bf193b4e5f74af4086481eb6f23a17f39e5.0" + resolved "https://registry.yarnpkg.com/@aave/contract-helpers/-/contract-helpers-1.20.1-8d191bf193b4e5f74af4086481eb6f23a17f39e5.0.tgz#2ef2357f91d13808737d8bdf7250f25c92624961" + integrity sha512-lLvX/nZ+JwiHWRURb2LifcqX4EW1utdu8STHXqs1LskTbnsoFUpytRXCpMj1EbdnJ6p1aNHpVJrTRQhxNysnLw== dependencies: isomorphic-unfetch "^3.1.0" -"@aave/math-utils@^1.21.0": - version "1.21.0" - resolved "https://registry.yarnpkg.com/@aave/math-utils/-/math-utils-1.21.0.tgz#420e36de179c27637be1c544afaf2f7b6c92b4d1" - integrity sha512-phO9BogmnpMPaK0/rl2QxdiTfHLHb+YmTCwvLC3e/IhDyRcc4QKLb/NFaPfC65aRZBjEEsS4QI1crPz3WKHHXA== +"@aave/math-utils@1.20.1-8d191bf193b4e5f74af4086481eb6f23a17f39e5.0": + version "1.20.1-8d191bf193b4e5f74af4086481eb6f23a17f39e5.0" + resolved "https://registry.yarnpkg.com/@aave/math-utils/-/math-utils-1.20.1-8d191bf193b4e5f74af4086481eb6f23a17f39e5.0.tgz#fb516c9ab3388da3c4935b72cf64c4bc752d5a3a" + integrity sha512-aEgIvluZRiJQsELDpGCaKUvGx7BaJB3mqKJAI42NQ+UH4oUsQuiNlG6sZQMVBOQiGpq8vn7qcnXZ7A1LRGZreg== "@adobe/css-tools@^4.0.1": version "4.0.1" From 6e588fbb5ea88f306440466d40a018c44ececc1d Mon Sep 17 00:00:00 2001 From: Joaquin Battilana Date: Fri, 13 Oct 2023 13:08:44 +0100 Subject: [PATCH 14/46] feat: handle -1 in approve methods --- .../transactions/Repay/RepayActions.tsx | 15 ++++------ .../transactions/Repay/RepayModalContent.tsx | 1 + src/store/poolSlice.ts | 29 +++++++++++++------ 3 files changed, 27 insertions(+), 18 deletions(-) diff --git a/src/components/transactions/Repay/RepayActions.tsx b/src/components/transactions/Repay/RepayActions.tsx index 3ff07000d5..24214cc93d 100644 --- a/src/components/transactions/Repay/RepayActions.tsx +++ b/src/components/transactions/Repay/RepayActions.tsx @@ -29,6 +29,7 @@ export interface RepayActionProps extends BoxProps { debtType: InterestRate; repayWithATokens: boolean; blocked?: boolean; + maxApproveNeeded: string; } export const RepayActions = ({ @@ -41,6 +42,7 @@ export const RepayActions = ({ debtType, repayWithATokens, blocked, + maxApproveNeeded, ...props }: RepayActionProps) => { const [ @@ -89,7 +91,7 @@ export const RepayActions = ({ Number(amountToRepay) !== 0 && checkRequiresApproval({ approvedAmount: approvedAmount?.amount || '0', - amount: amountToRepay, + amount: Number(amountToRepay) === -1 ? maxApproveNeeded : amountToRepay, signedAmount: signatureParams ? signatureParams.amount : '0', }); @@ -106,7 +108,7 @@ export const RepayActions = ({ assetAddress: poolAddress, symbol, decimals: poolReserve.decimals, - signatureAmount: amountToRepay, + signatureAmount: Number(amountToRepay) === -1 ? maxApproveNeeded : amountToRepay, onApprovalTxConfirmed: fetchApprovedAmount, onSignTxCompleted: (signedParams) => setSignatureParams(signedParams), }); @@ -117,6 +119,8 @@ export const RepayActions = ({ } }, [fetchApprovedAmount, isFetchedAfterMount, repayWithATokens]); + console.log(approvedAmount); + const action = async () => { try { setMainTxState({ ...mainTxState, loading: true }); @@ -128,12 +132,8 @@ export const RepayActions = ({ action = ProtocolAction.repayWithPermit; let signedSupplyWithPermitTxData = repayWithPermit({ amountToRepay: parseUnits(amountToRepay, poolReserve.decimals).toString(), - poolReserve, - isWrongNetwork, poolAddress, - symbol, debtType, - repayWithATokens, signature: signatureParams.signature, deadline: signatureParams.deadline, }); @@ -148,9 +148,6 @@ export const RepayActions = ({ poolAddress, repayWithATokens, debtType, - poolReserve, - isWrongNetwork, - symbol, }); supplyTxData = await estimateGasLimit(supplyTxData); response = await sendTx(supplyTxData); diff --git a/src/components/transactions/Repay/RepayModalContent.tsx b/src/components/transactions/Repay/RepayModalContent.tsx index a80d089030..9dea57d9cc 100644 --- a/src/components/transactions/Repay/RepayModalContent.tsx +++ b/src/components/transactions/Repay/RepayModalContent.tsx @@ -274,6 +274,7 @@ export const RepayModalContent = ({ {txError && } >; @@ -93,14 +108,9 @@ export interface PoolSlice { claimRewards: (args: ClaimRewardsActionsProps) => Promise; // TODO: optimize types to use only neccessary properties swapCollateral: (args: SwapActionProps) => Promise; - repay: (args: RepayActionProps) => PopulatedTransaction; + repay: (args: RepayArgs) => PopulatedTransaction; withdrawAndSwitch: (args: WithdrawAndSwitchActionProps) => PopulatedTransaction; - repayWithPermit: ( - args: RepayActionProps & { - signature: SignatureLike; - deadline: string; - } - ) => PopulatedTransaction; + repayWithPermit: (args: RepayWithPermitArgs) => PopulatedTransaction; poolComputed: { minRemainingBaseTokenBalance: string; }; @@ -586,6 +596,7 @@ export const createPoolSlice: StateCreator< repayWithPermit: ({ poolAddress, amountToRepay, debtType, deadline, signature }) => { const poolBundle = get().getCorrectPoolBundle() as PoolBundle; const currentAccount = get().account; + const stringSignature = utils.joinSignature(signature); return poolBundle.repayTxBuilder.generateSignedTxData({ user: currentAccount, reserve: poolAddress, @@ -593,7 +604,7 @@ export const createPoolSlice: StateCreator< useOptimizedPath: get().useOptimizedPath(), interestRateMode: debtType, deadline, - signature, + signature: stringSignature, }); }, swapCollateral: async ({ From bb4ff51eaa654a4d049bdc8143e8a2c5c84f8d5e Mon Sep 17 00:00:00 2001 From: Joaquin Battilana Date: Tue, 17 Oct 2023 13:45:57 +0100 Subject: [PATCH 15/46] feat: fixed approval error --- src/components/transactions/Repay/RepayActions.tsx | 14 ++++++++++---- .../transactions/Repay/RepayModalContent.tsx | 6 ++++-- src/hooks/useApprovalTx.tsx | 5 +++-- 3 files changed, 17 insertions(+), 8 deletions(-) diff --git a/src/components/transactions/Repay/RepayActions.tsx b/src/components/transactions/Repay/RepayActions.tsx index 7543e0a704..0b14fc54ad 100644 --- a/src/components/transactions/Repay/RepayActions.tsx +++ b/src/components/transactions/Repay/RepayActions.tsx @@ -1,7 +1,9 @@ import { gasLimitRecommendations, InterestRate, ProtocolAction } from '@aave/contract-helpers'; +import { valueToBigNumber } from '@aave/math-utils'; import { TransactionResponse } from '@ethersproject/providers'; import { Trans } from '@lingui/macro'; import { BoxProps } from '@mui/material'; +import BigNumber from 'bignumber.js'; import { parseUnits } from 'ethers/lib/utils'; import { queryClient } from 'pages/_app.page'; import { useEffect, useState } from 'react'; @@ -111,7 +113,13 @@ export const RepayActions = ({ assetAddress: poolAddress, symbol, decimals: poolReserve.decimals, - signatureAmount: Number(amountToRepay) === -1 ? maxApproveNeeded : amountToRepay, + signatureAmount: + Number(amountToRepay) === -1 + ? valueToBigNumber(maxApproveNeeded) + .multipliedBy('1.0025') + .decimalPlaces(18, BigNumber.ROUND_UP) + .toString() + : amountToRepay, onApprovalTxConfirmed: fetchApprovedAmount, onSignTxCompleted: (signedParams) => setSignatureParams(signedParams), }); @@ -122,8 +130,6 @@ export const RepayActions = ({ } }, [fetchApprovedAmount, isFetchedAfterMount, repayWithATokens]); - console.log(approvedAmount); - const action = async () => { try { setMainTxState({ ...mainTxState, loading: true }); @@ -133,6 +139,7 @@ export const RepayActions = ({ if (usePermit && signatureParams) { action = ProtocolAction.repayWithPermit; + console.log(1); let signedSupplyWithPermitTxData = repayWithPermit({ amountToRepay: parseUnits(amountToRepay, poolReserve.decimals).toString(), poolAddress, @@ -140,7 +147,6 @@ export const RepayActions = ({ signature: signatureParams.signature, deadline: signatureParams.deadline, }); - signedSupplyWithPermitTxData = await estimateGasLimit(signedSupplyWithPermitTxData); response = await sendTx(signedSupplyWithPermitTxData); await response.wait(1); diff --git a/src/components/transactions/Repay/RepayModalContent.tsx b/src/components/transactions/Repay/RepayModalContent.tsx index 9dea57d9cc..789049e8c5 100644 --- a/src/components/transactions/Repay/RepayModalContent.tsx +++ b/src/components/transactions/Repay/RepayModalContent.tsx @@ -79,7 +79,9 @@ export const RepayModalContent = ({ .multipliedBy(marketReferencePriceInUsd) .shiftedBy(-USD_DECIMALS); - const safeAmountToRepayAll = valueToBigNumber(debt).multipliedBy('1.0025'); + const safeAmountToRepayAll = valueToBigNumber(debt) + .multipliedBy('1.0025') + .decimalPlaces(poolReserve.decimals, BigNumber.ROUND_UP); // calculate max amount abailable to repay let maxAmountToRepay: BigNumber; @@ -274,7 +276,7 @@ export const RepayModalContent = ({ {txError && } Date: Tue, 17 Oct 2023 17:05:38 +0100 Subject: [PATCH 16/46] feat: added -1 to options --- .../transactions/Repay/RepayActions.tsx | 22 ++++++++++++------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/src/components/transactions/Repay/RepayActions.tsx b/src/components/transactions/Repay/RepayActions.tsx index 0b14fc54ad..de129d02e4 100644 --- a/src/components/transactions/Repay/RepayActions.tsx +++ b/src/components/transactions/Repay/RepayActions.tsx @@ -140,26 +140,32 @@ export const RepayActions = ({ if (usePermit && signatureParams) { action = ProtocolAction.repayWithPermit; console.log(1); - let signedSupplyWithPermitTxData = repayWithPermit({ - amountToRepay: parseUnits(amountToRepay, poolReserve.decimals).toString(), + const signedRepayWithPermitTxData = repayWithPermit({ + amountToRepay: + amountToRepay === '-1' + ? amountToRepay + : parseUnits(amountToRepay, poolReserve.decimals).toString(), poolAddress, debtType, signature: signatureParams.signature, deadline: signatureParams.deadline, }); - signedSupplyWithPermitTxData = await estimateGasLimit(signedSupplyWithPermitTxData); - response = await sendTx(signedSupplyWithPermitTxData); + // signedRepayWithPermitTxData = await estimateGasLimit(signedRepayWithPermitTxData); + response = await sendTx(signedRepayWithPermitTxData); await response.wait(1); } else { action = ProtocolAction.repay; - let supplyTxData = repay({ - amountToRepay: parseUnits(amountToRepay, poolReserve.decimals).toString(), + let repayTxData = repay({ + amountToRepay: + amountToRepay === '-1' + ? amountToRepay + : parseUnits(amountToRepay, poolReserve.decimals).toString(), poolAddress, repayWithATokens, debtType, }); - supplyTxData = await estimateGasLimit(supplyTxData); - response = await sendTx(supplyTxData); + repayTxData = await estimateGasLimit(repayTxData); + response = await sendTx(repayTxData); await response.wait(1); } setMainTxState({ From 650eda9f962d310e7cb535107c2545de2ce367a5 Mon Sep 17 00:00:00 2001 From: Joaquin Battilana Date: Tue, 17 Oct 2023 17:33:14 +0100 Subject: [PATCH 17/46] feat: added max uint to approve --- src/components/transactions/Repay/RepayActions.tsx | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/src/components/transactions/Repay/RepayActions.tsx b/src/components/transactions/Repay/RepayActions.tsx index de129d02e4..32047523f4 100644 --- a/src/components/transactions/Repay/RepayActions.tsx +++ b/src/components/transactions/Repay/RepayActions.tsx @@ -1,9 +1,8 @@ import { gasLimitRecommendations, InterestRate, ProtocolAction } from '@aave/contract-helpers'; -import { valueToBigNumber } from '@aave/math-utils'; import { TransactionResponse } from '@ethersproject/providers'; import { Trans } from '@lingui/macro'; import { BoxProps } from '@mui/material'; -import BigNumber from 'bignumber.js'; +import { constants } from 'ethers'; import { parseUnits } from 'ethers/lib/utils'; import { queryClient } from 'pages/_app.page'; import { useEffect, useState } from 'react'; @@ -113,13 +112,7 @@ export const RepayActions = ({ assetAddress: poolAddress, symbol, decimals: poolReserve.decimals, - signatureAmount: - Number(amountToRepay) === -1 - ? valueToBigNumber(maxApproveNeeded) - .multipliedBy('1.0025') - .decimalPlaces(18, BigNumber.ROUND_UP) - .toString() - : amountToRepay, + signatureAmount: Number(amountToRepay) === -1 ? constants.MaxUint256.toString() : amountToRepay, onApprovalTxConfirmed: fetchApprovedAmount, onSignTxCompleted: (signedParams) => setSignatureParams(signedParams), }); From ba54f02059b69abb9d44a0933f9aae0efcadf08e Mon Sep 17 00:00:00 2001 From: Joaquin Battilana Date: Tue, 17 Oct 2023 17:42:11 +0100 Subject: [PATCH 18/46] feat: fixed approve --- src/components/transactions/Repay/RepayActions.tsx | 3 +-- src/components/transactions/utils.ts | 1 + src/hooks/useApprovalTx.tsx | 6 +++++- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/components/transactions/Repay/RepayActions.tsx b/src/components/transactions/Repay/RepayActions.tsx index 32047523f4..2b3daf2535 100644 --- a/src/components/transactions/Repay/RepayActions.tsx +++ b/src/components/transactions/Repay/RepayActions.tsx @@ -2,7 +2,6 @@ import { gasLimitRecommendations, InterestRate, ProtocolAction } from '@aave/con import { TransactionResponse } from '@ethersproject/providers'; import { Trans } from '@lingui/macro'; import { BoxProps } from '@mui/material'; -import { constants } from 'ethers'; import { parseUnits } from 'ethers/lib/utils'; import { queryClient } from 'pages/_app.page'; import { useEffect, useState } from 'react'; @@ -112,7 +111,7 @@ export const RepayActions = ({ assetAddress: poolAddress, symbol, decimals: poolReserve.decimals, - signatureAmount: Number(amountToRepay) === -1 ? constants.MaxUint256.toString() : amountToRepay, + signatureAmount: amountToRepay, onApprovalTxConfirmed: fetchApprovedAmount, onSignTxCompleted: (signedParams) => setSignatureParams(signedParams), }); diff --git a/src/components/transactions/utils.ts b/src/components/transactions/utils.ts index c0273206fd..e7a3ea70d4 100644 --- a/src/components/transactions/utils.ts +++ b/src/components/transactions/utils.ts @@ -34,6 +34,7 @@ export const checkRequiresApproval = ({ // Returns false if the user has a max approval, an approval > amountToSupply, or a valid signature for amountToSupply if ( approvedAmount === '-1' || + signedAmount === '-1' || (approvedAmount !== '0' && Number(approvedAmount) >= Number(amount)) || Number(signedAmount) >= Number(amount) ) { diff --git a/src/hooks/useApprovalTx.tsx b/src/hooks/useApprovalTx.tsx index c0fd2a1f40..40d172a11a 100644 --- a/src/hooks/useApprovalTx.tsx +++ b/src/hooks/useApprovalTx.tsx @@ -1,5 +1,6 @@ import { ApproveType, MAX_UINT_AMOUNT, ProtocolAction } from '@aave/contract-helpers'; import { SignatureLike } from '@ethersproject/bytes'; +import { constants } from 'ethers'; import { parseUnits } from 'ethers/lib/utils'; import { MOCK_SIGNED_HASH } from 'src/helpers/useTransactionHandler'; import { useWeb3Context } from 'src/libs/hooks/useWeb3Context'; @@ -56,7 +57,10 @@ export const useApprovalTx = ({ const signatureRequest = await generateSignatureRequest({ ...approvedAmount, deadline, - amount: parseUnits(signatureAmount, decimals).toString(), + amount: + signatureAmount === '-1' + ? constants.MaxUint256.toString() + : parseUnits(signatureAmount, decimals).toString(), }); const response = await signTxData(signatureRequest); From 951f83c9c63f57644cb9e97964cd7679f0887514 Mon Sep 17 00:00:00 2001 From: Joaquin Battilana Date: Tue, 17 Oct 2023 17:52:49 +0100 Subject: [PATCH 19/46] feat: updated utilitiers version --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index d9175360e9..6398eade1e 100644 --- a/package.json +++ b/package.json @@ -32,7 +32,7 @@ "test:coverage": "jest --coverage" }, "dependencies": { - "@aave/contract-helpers": "1.20.1-8d191bf193b4e5f74af4086481eb6f23a17f39e5.0", + "@aave/contract-helpers": "1.21.1-2e2295889aa7b15bb4e9c6d5065432703f7c1542.0", "@aave/math-utils": "1.20.1-8d191bf193b4e5f74af4086481eb6f23a17f39e5.0", "@bgd-labs/aave-address-book": "^2.7.0", "@emotion/cache": "11.10.3", diff --git a/yarn.lock b/yarn.lock index 452a6dbc3e..bfd5b7d8a0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,10 +2,10 @@ # yarn lockfile v1 -"@aave/contract-helpers@1.20.1-8d191bf193b4e5f74af4086481eb6f23a17f39e5.0": - version "1.20.1-8d191bf193b4e5f74af4086481eb6f23a17f39e5.0" - resolved "https://registry.yarnpkg.com/@aave/contract-helpers/-/contract-helpers-1.20.1-8d191bf193b4e5f74af4086481eb6f23a17f39e5.0.tgz#2ef2357f91d13808737d8bdf7250f25c92624961" - integrity sha512-lLvX/nZ+JwiHWRURb2LifcqX4EW1utdu8STHXqs1LskTbnsoFUpytRXCpMj1EbdnJ6p1aNHpVJrTRQhxNysnLw== +"@aave/contract-helpers@1.21.1-2e2295889aa7b15bb4e9c6d5065432703f7c1542.0": + version "1.21.1-2e2295889aa7b15bb4e9c6d5065432703f7c1542.0" + resolved "https://registry.yarnpkg.com/@aave/contract-helpers/-/contract-helpers-1.21.1-2e2295889aa7b15bb4e9c6d5065432703f7c1542.0.tgz#875d199308e37ad5c4850800ceabf09b473bb425" + integrity sha512-ogZbmm4g/w5KqiFk50nKT7IVqCAwptN4hEAW0BIkYnUI9FdTaSY3SNN4TsejSfz7jKtS+Tz5OTo4F68cbmSCeA== dependencies: isomorphic-unfetch "^3.1.0" From 3f27df4d2ddbe4821f328ab60e3ef649c4662bc9 Mon Sep 17 00:00:00 2001 From: Mark Grothe Date: Thu, 5 Oct 2023 14:37:16 -0500 Subject: [PATCH 20/46] fix: symbol in success modal --- src/components/transactions/Repay/RepayModalContent.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/transactions/Repay/RepayModalContent.tsx b/src/components/transactions/Repay/RepayModalContent.tsx index 789049e8c5..81f942b0c9 100644 --- a/src/components/transactions/Repay/RepayModalContent.tsx +++ b/src/components/transactions/Repay/RepayModalContent.tsx @@ -225,7 +225,7 @@ export const RepayModalContent = ({ repaid} amount={amountRef.current} - symbol={tokenToRepayWith.symbol} + symbol={repayWithATokens ? poolReserve.symbol : tokenToRepayWith.symbol} /> ); From 999c851703e1643f61ae580892bc46e5db0a58d9 Mon Sep 17 00:00:00 2001 From: Mark Grothe Date: Tue, 24 Oct 2023 21:01:33 -0500 Subject: [PATCH 21/46] feat: use optimized path --- package.json | 2 +- .../transactions/Repay/RepayActions.tsx | 44 ++++++++++--- src/store/poolSlice.ts | 66 ++++++++++++++----- yarn.lock | 8 +-- 4 files changed, 90 insertions(+), 30 deletions(-) diff --git a/package.json b/package.json index 6398eade1e..aac028ba0e 100644 --- a/package.json +++ b/package.json @@ -32,7 +32,7 @@ "test:coverage": "jest --coverage" }, "dependencies": { - "@aave/contract-helpers": "1.21.1-2e2295889aa7b15bb4e9c6d5065432703f7c1542.0", + "@aave/contract-helpers": "1.21.1-0efe71955bfd19d178a3edef77416ca0612598b9.0", "@aave/math-utils": "1.20.1-8d191bf193b4e5f74af4086481eb6f23a17f39e5.0", "@bgd-labs/aave-address-book": "^2.7.0", "@emotion/cache": "11.10.3", diff --git a/src/components/transactions/Repay/RepayActions.tsx b/src/components/transactions/Repay/RepayActions.tsx index 2b3daf2535..9a23efc709 100644 --- a/src/components/transactions/Repay/RepayActions.tsx +++ b/src/components/transactions/Repay/RepayActions.tsx @@ -48,17 +48,23 @@ export const RepayActions = ({ const [ repay, repayWithPermit, + encodeRepayParams, + encodeRepayWithPermit, tryPermit, walletApprovalMethodPreference, estimateGasLimit, addTransaction, + optimizedPath, ] = useRootStore((store) => [ store.repay, store.repayWithPermit, + store.encodeRepayParams, + store.encodeRepayWithPermitParams, store.tryPermit, store.walletApprovalMethodPreference, store.estimateGasLimit, store.addTransaction, + store.useOptimizedPath, ]); const { sendTx } = useWeb3Context(); const { refetchGhoData, refetchIncentiveData, refetchPoolData } = useBackgroundDataProvider(); @@ -130,24 +136,33 @@ export const RepayActions = ({ let action = ProtocolAction.default; if (usePermit && signatureParams) { - action = ProtocolAction.repayWithPermit; - console.log(1); - const signedRepayWithPermitTxData = repayWithPermit({ - amountToRepay: + const repayWithPermitParams = { + amount: amountToRepay === '-1' ? amountToRepay : parseUnits(amountToRepay, poolReserve.decimals).toString(), - poolAddress, - debtType, + reserve: poolAddress, + interestRateMode: debtType, signature: signatureParams.signature, deadline: signatureParams.deadline, + }; + + let encodedParams: [string, string, string] | undefined; + if (optimizedPath()) { + encodedParams = await encodeRepayWithPermit(repayWithPermitParams); + } + + action = ProtocolAction.repayWithPermit; + let signedRepayWithPermitTxData = repayWithPermit({ + ...repayWithPermitParams, + encodedTxData: encodedParams ? encodedParams[0] : undefined, }); - // signedRepayWithPermitTxData = await estimateGasLimit(signedRepayWithPermitTxData); + + signedRepayWithPermitTxData = await estimateGasLimit(signedRepayWithPermitTxData); response = await sendTx(signedRepayWithPermitTxData); await response.wait(1); } else { - action = ProtocolAction.repay; - let repayTxData = repay({ + const repayParams = { amountToRepay: amountToRepay === '-1' ? amountToRepay @@ -155,6 +170,17 @@ export const RepayActions = ({ poolAddress, repayWithATokens, debtType, + }; + + let encodedParams: string | undefined; + if (optimizedPath()) { + encodedParams = await encodeRepayParams(repayParams); + } + + action = ProtocolAction.repay; + let repayTxData = repay({ + ...repayParams, + encodedTxData: encodedParams, }); repayTxData = await estimateGasLimit(repayTxData); response = await sendTx(repayTxData); diff --git a/src/store/poolSlice.ts b/src/store/poolSlice.ts index 6af8f6029e..6e984510e7 100644 --- a/src/store/poolSlice.ts +++ b/src/store/poolSlice.ts @@ -36,11 +36,11 @@ import { LPWithdrawParamsType, } from '@aave/contract-helpers/dist/esm/lendingPool-contract/lendingPoolTypes'; import { + LPRepayWithPermitParamsType, LPSignERC20ApprovalType, LPSupplyParamsType, LPSupplyWithPermitType, } from '@aave/contract-helpers/dist/esm/v3-pool-contract/lendingPoolTypes'; -import { SignatureLike } from '@ethersproject/bytes'; import dayjs from 'dayjs'; import { BigNumber, PopulatedTransaction, Signature, utils } from 'ethers'; import { splitSignature } from 'ethers/lib/utils'; @@ -67,19 +67,12 @@ export type PoolReserve = { userReserves?: UserReserveDataHumanized[]; }; -type RepayWithPermitArgs = { - amountToRepay: string; - poolAddress: string; - debtType: InterestRate; - signature: SignatureLike; - deadline: string; -}; - type RepayArgs = { amountToRepay: string; poolAddress: string; debtType: InterestRate; repayWithATokens: boolean; + encodedTxData?: string; }; // TODO: add chain/provider/account mapping @@ -108,9 +101,13 @@ export interface PoolSlice { claimRewards: (args: ClaimRewardsActionsProps) => Promise; // TODO: optimize types to use only neccessary properties swapCollateral: (args: SwapActionProps) => Promise; - repay: (args: RepayArgs) => PopulatedTransaction; withdrawAndSwitch: (args: WithdrawAndSwitchActionProps) => PopulatedTransaction; - repayWithPermit: (args: RepayWithPermitArgs) => PopulatedTransaction; + repay: (args: RepayArgs) => PopulatedTransaction; + encodeRepayParams: (args: RepayArgs) => Promise; + repayWithPermit: (args: Omit) => PopulatedTransaction; + encodeRepayWithPermitParams: ( + args: Omit + ) => Promise<[string, string, string]>; poolComputed: { minRemainingBaseTokenBalance: string; }; @@ -562,7 +559,7 @@ export const createPoolSlice: StateCreator< }, }); }, - repay: ({ repayWithATokens, amountToRepay, poolAddress, debtType }) => { + repay: ({ repayWithATokens, amountToRepay, poolAddress, debtType, encodedTxData }) => { const poolBundle = get().getCorrectPoolBundle(); const currentAccount = get().account; if (poolBundle instanceof PoolBundle) { @@ -573,6 +570,7 @@ export const createPoolSlice: StateCreator< amount: amountToRepay, useOptimizedPath: get().useOptimizedPath(), rateMode: debtType, + encodedTxData, }); } else { return poolBundle.repayTxBuilder.generateTxData({ @@ -581,6 +579,7 @@ export const createPoolSlice: StateCreator< amount: amountToRepay, useOptimizedPath: get().useOptimizedPath(), interestRateMode: debtType, + encodedTxData, }); } } else { @@ -593,20 +592,55 @@ export const createPoolSlice: StateCreator< }); } }, - repayWithPermit: ({ poolAddress, amountToRepay, debtType, deadline, signature }) => { + repayWithPermit: ({ + reserve, + amount, + interestRateMode, + deadline, + signature, + encodedTxData, + }) => { const poolBundle = get().getCorrectPoolBundle() as PoolBundle; const currentAccount = get().account; const stringSignature = utils.joinSignature(signature); return poolBundle.repayTxBuilder.generateSignedTxData({ user: currentAccount, - reserve: poolAddress, - amount: amountToRepay, + reserve, + amount, useOptimizedPath: get().useOptimizedPath(), - interestRateMode: debtType, + interestRateMode, + deadline, + signature: stringSignature, + encodedTxData, + }); + }, + encodeRepayWithPermitParams: ({ reserve, amount, interestRateMode, deadline, signature }) => { + const poolBundle = get().getCorrectPoolBundle() as PoolBundle; + const stringSignature = utils.joinSignature(signature); + return poolBundle.repayTxBuilder.encodeRepayWithPermitParams({ + reserve, + amount, + interestRateMode, deadline, signature: stringSignature, }); }, + encodeRepayParams: ({ amountToRepay, poolAddress, debtType, repayWithATokens }) => { + const poolBundle = get().getCorrectPoolBundle() as PoolBundle; + if (repayWithATokens) { + return poolBundle.repayWithATokensTxBuilder.encodeRepayWithATokensParams({ + reserve: poolAddress, + amount: amountToRepay, + rateMode: debtType, + }); + } else { + return poolBundle.repayTxBuilder.encodeRepayParams({ + reserve: poolAddress, + amount: amountToRepay, + interestRateMode: debtType, + }); + } + }, swapCollateral: async ({ poolReserve, targetReserve, diff --git a/yarn.lock b/yarn.lock index bfd5b7d8a0..b1e95417b5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,10 +2,10 @@ # yarn lockfile v1 -"@aave/contract-helpers@1.21.1-2e2295889aa7b15bb4e9c6d5065432703f7c1542.0": - version "1.21.1-2e2295889aa7b15bb4e9c6d5065432703f7c1542.0" - resolved "https://registry.yarnpkg.com/@aave/contract-helpers/-/contract-helpers-1.21.1-2e2295889aa7b15bb4e9c6d5065432703f7c1542.0.tgz#875d199308e37ad5c4850800ceabf09b473bb425" - integrity sha512-ogZbmm4g/w5KqiFk50nKT7IVqCAwptN4hEAW0BIkYnUI9FdTaSY3SNN4TsejSfz7jKtS+Tz5OTo4F68cbmSCeA== +"@aave/contract-helpers@1.21.1-0efe71955bfd19d178a3edef77416ca0612598b9.0": + version "1.21.1-0efe71955bfd19d178a3edef77416ca0612598b9.0" + resolved "https://registry.yarnpkg.com/@aave/contract-helpers/-/contract-helpers-1.21.1-0efe71955bfd19d178a3edef77416ca0612598b9.0.tgz#ff068c6b1cc84c989a8566ae5cb0de8674fabdb2" + integrity sha512-04FPIti7B2U4KXKUTzXAXbL+NOP1Q+KtDFZR1mo5OWJZoW6Ky8xCTqSpFNMQbxMoejiJaYYqkeEQnOgVOuwEDQ== dependencies: isomorphic-unfetch "^3.1.0" From 9447207132927fda4f31e8638cef1295529a1434 Mon Sep 17 00:00:00 2001 From: Nikita Boakrev Date: Wed, 25 Oct 2023 12:10:11 +0100 Subject: [PATCH 22/46] fix: remove abpt from staking test coverage --- cypress/e2e/3-stake-governance/stake.cy.ts | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/cypress/e2e/3-stake-governance/stake.cy.ts b/cypress/e2e/3-stake-governance/stake.cy.ts index a721c049ea..1690ee9e1b 100644 --- a/cypress/e2e/3-stake-governance/stake.cy.ts +++ b/cypress/e2e/3-stake-governance/stake.cy.ts @@ -18,14 +18,14 @@ const testCases = [ tabValue: 'aave', changeApproval: true, }, - { - asset: assets.staking.ABPT, - amount: 5, - checkAmount: '5.00', - checkAmountFinal: '10.00', - tabValue: 'bpt', - changeApproval: false, - }, + // { + // asset: assets.staking.ABPT, + // amount: 5, + // checkAmount: '5.00', + // checkAmountFinal: '10.00', + // tabValue: 'bpt', + // changeApproval: false, + // }, ]; testCases.forEach( From 09f485cde067ec203da93502d47f64ed069fa074 Mon Sep 17 00:00:00 2001 From: Nikita Boakrev Date: Wed, 25 Oct 2023 12:12:31 +0100 Subject: [PATCH 23/46] fix: import --- cypress/e2e/3-stake-governance/stake.cy.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cypress/e2e/3-stake-governance/stake.cy.ts b/cypress/e2e/3-stake-governance/stake.cy.ts index 1690ee9e1b..dc1dbe4677 100644 --- a/cypress/e2e/3-stake-governance/stake.cy.ts +++ b/cypress/e2e/3-stake-governance/stake.cy.ts @@ -3,10 +3,10 @@ import { skipState } from '../../support/steps/common'; import { configEnvWithTenderlyMainnetFork } from '../../support/steps/configuration.steps'; import { activateCooldown, - stake, - reCallCooldown, claimReward, + reCallCooldown, reStake, + stake, } from '../../support/steps/stake.steps'; const testCases = [ From e0ee8c9387ca6e4b330d2b7dcfc74a3e83588659 Mon Sep 17 00:00:00 2001 From: Mark Grothe Date: Tue, 5 Sep 2023 16:36:25 -0500 Subject: [PATCH 24/46] feat: wip --- package.json | 2 +- src/components/transactions/AssetInput.tsx | 21 +- .../Supply/SupplyModalContent.tsx | 112 ++++++++- .../Supply/SupplyWrappedTokenActions.tsx | 236 ++++++++++++++++++ .../transactions/Supply/useApprovedAmount.tsx | 46 ++++ .../Supply/useSavingsDaiWrapper.ts | 46 ++++ .../WithdrawAndSwitchModalContent.tsx | 7 +- .../Withdraw/WithdrawModalContent.tsx | 170 ++++++++++++- src/locales/en/messages.js | 2 +- src/locales/en/messages.po | 9 + src/store/poolSlice.ts | 70 ++++++ src/ui-config/marketsConfig.tsx | 2 + src/ui-config/wrappedTokenConfig.ts | 7 + yarn.lock | 8 +- 14 files changed, 702 insertions(+), 36 deletions(-) create mode 100644 src/components/transactions/Supply/SupplyWrappedTokenActions.tsx create mode 100644 src/components/transactions/Supply/useApprovedAmount.tsx create mode 100644 src/components/transactions/Supply/useSavingsDaiWrapper.ts create mode 100644 src/ui-config/wrappedTokenConfig.ts diff --git a/package.json b/package.json index c0f48cf2e1..8e37e03cea 100644 --- a/package.json +++ b/package.json @@ -32,7 +32,7 @@ "test:coverage": "jest --coverage" }, "dependencies": { - "@aave/contract-helpers": "1.21.1-0efe71955bfd19d178a3edef77416ca0612598b9.0", + "@aave/contract-helpers": "1.21.1-3c5fc7ba506d4aceaf433900344ace2f391e397b.0", "@aave/math-utils": "1.20.1-8d191bf193b4e5f74af4086481eb6f23a17f39e5.0", "@bgd-labs/aave-address-book": "^2.7.0", "@emotion/cache": "11.10.3", diff --git a/src/components/transactions/AssetInput.tsx b/src/components/transactions/AssetInput.tsx index 74e1c2bac1..58094a2216 100644 --- a/src/components/transactions/AssetInput.tsx +++ b/src/components/transactions/AssetInput.tsx @@ -85,6 +85,7 @@ export interface AssetInputProps { selectOptionHeader?: ReactNode; selectOption?: (asset: T) => ReactNode; sx?: BoxProps; + exchangeRateComponent?: ReactNode; } export const AssetInput = ({ @@ -106,6 +107,7 @@ export const AssetInput = ({ selectOptionHeader, selectOption, sx = {}, + exchangeRateComponent, }: AssetInputProps) => { const theme = useTheme(); const trackEvent = useRootStore((store) => store.trackEvent); @@ -131,13 +133,12 @@ export const AssetInput = ({ ({ - p: '8px 12px', border: `1px solid ${theme.palette.divider}`, borderRadius: '6px', - mb: 1, + overflow: 'hidden', })} > - + {loading ? ( @@ -284,7 +285,7 @@ export const AssetInput = ({ )} - + {loading ? ( ) : ( @@ -330,6 +331,18 @@ export const AssetInput = ({ )} + {exchangeRateComponent && ( + + {exchangeRateComponent} + + )} ); diff --git a/src/components/transactions/Supply/SupplyModalContent.tsx b/src/components/transactions/Supply/SupplyModalContent.tsx index ecadcb62d3..04dcaa2da9 100644 --- a/src/components/transactions/Supply/SupplyModalContent.tsx +++ b/src/components/transactions/Supply/SupplyModalContent.tsx @@ -5,8 +5,13 @@ import { valueToBigNumber, } from '@aave/math-utils'; import { Trans } from '@lingui/macro'; +import { Skeleton, Stack, Typography } from '@mui/material'; import BigNumber from 'bignumber.js'; import React, { useMemo, useState } from 'react'; +import { ContentWithTooltip } from 'src/components/ContentWithTooltip'; +import { FormattedNumber } from 'src/components/primitives/FormattedNumber'; +import { Link } from 'src/components/primitives/Link'; +import { TokenIcon } from 'src/components/primitives/TokenIcon'; import { Warning } from 'src/components/primitives/Warning'; import { AMPLWarning } from 'src/components/Warnings/AMPLWarning'; import { useAssetCaps } from 'src/hooks/useAssetCaps'; @@ -14,6 +19,7 @@ import { useModalContext } from 'src/hooks/useModal'; import { useProtocolDataContext } from 'src/hooks/useProtocolDataContext'; import { ERC20TokenType } from 'src/libs/web3-data-provider/Web3Provider'; import { useRootStore } from 'src/store/root'; +import { wrappedTokenConfig } from 'src/ui-config/wrappedTokenConfig'; import { getMaxAmountAvailableToSupply } from 'src/utils/getMaxAmountAvailableToSupply'; import { isFeatureEnabled } from 'src/utils/marketsAndNetworksConfig'; import { GENERAL } from 'src/utils/mixPanelEvents'; @@ -21,7 +27,7 @@ import { roundToTokenDecimals } from 'src/utils/utils'; import { useAppDataContext } from '../../../hooks/app-data-provider/useAppDataProvider'; import { CapType } from '../../caps/helper'; -import { AssetInput } from '../AssetInput'; +import { Asset, AssetInput } from '../AssetInput'; import { GasEstimationError } from '../FlowCommons/GasEstimationError'; import { ModalWrapperProps } from '../FlowCommons/ModalWrapper'; import { TxSuccessView } from '../FlowCommons/Success'; @@ -37,6 +43,12 @@ import { AAVEWarning } from '../Warnings/AAVEWarning'; import { IsolationModeWarning } from '../Warnings/IsolationModeWarning'; import { SNXWarning } from '../Warnings/SNXWarning'; import { SupplyActions } from './SupplyActions'; +import { SupplyWrappedTokenActions } from './SupplyWrappedTokenActions'; +import { useSavingsDaiWrapper } from './useSavingsDaiWrapper'; + +interface SupplyAsset extends Asset { + balance: string; +} export enum ErrorType { CAP_REACHED, @@ -60,6 +72,12 @@ export const SupplyModalContent = React.memo( ); // states + const [tokenToSupply, setTokenToSupply] = useState({ + address: poolReserve.underlyingAsset, + symbol: poolReserve.symbol, + iconSymbol: poolReserve.iconSymbol, + balance: tokenBalance, + }); const [amount, setAmount] = useState(''); const supplyUnWrapped = underlyingAsset.toLowerCase() === API_ETH_MOCK_ADDRESS.toLowerCase(); @@ -187,6 +205,26 @@ export const SupplyModalContent = React.memo( /> ); + const assets = [ + { + balance: maxAmountToSupply, + symbol: supplyUnWrapped ? currentNetworkConfig.baseAssetSymbol : poolReserve.symbol, + iconSymbol: supplyUnWrapped ? currentNetworkConfig.baseAssetSymbol : poolReserve.iconSymbol, + }, + ]; + + const wrappedTokenInConfig = + wrappedTokenConfig[currentMarketData.chainId][poolReserve.underlyingAsset]; + if (wrappedTokenInConfig) { + assets.push({ + balance: maxAmountToSupply, + symbol: 'DAI', // TODO + iconSymbol: 'DAI', // TODO + }); + } + + const supplyingWrappedToken = tokenToSupply.address === wrappedTokenInConfig; + return ( <> {showIsolationWarning && } @@ -206,16 +244,9 @@ export const SupplyModalContent = React.memo( value={amount} onChange={handleChange} usdValue={amountInUsd.toString(10)} - symbol={supplyUnWrapped ? currentNetworkConfig.baseAssetSymbol : poolReserve.symbol} - assets={[ - { - balance: maxAmountToSupply, - symbol: supplyUnWrapped ? currentNetworkConfig.baseAssetSymbol : poolReserve.symbol, - iconSymbol: supplyUnWrapped - ? currentNetworkConfig.baseAssetSymbol - : poolReserve.iconSymbol, - }, - ]} + symbol={tokenToSupply.symbol} + assets={assets} + onSelect={setTokenToSupply} capType={CapType.supplyCap} isMaxSelected={isMaxSelected} disabled={supplyTxState.loading} @@ -228,6 +259,10 @@ export const SupplyModalContent = React.memo( assetName: poolReserve.name, }, }} + exchangeRateComponent={ + poolReserve.symbol === 'sDAI' && + tokenToSupply.symbol === 'DAI' && + } /> @@ -246,8 +281,61 @@ export const SupplyModalContent = React.memo( {txError && } - + {supplyingWrappedToken ? ( + + ) : ( + + )} ); } ); + +const ExchangeRate = ({ supplyAmount }: { supplyAmount: string }) => { + const { loading, tokenOutAmount } = useSavingsDaiWrapper({ supplyAmount, decimals: 18 }); + + console.log('tokenOutAmount', tokenOutAmount); + + return ( + + + Supply amount + + {loading ? ( + + ) : ( + <> + + + sDAI + + + )} + + + ); +}; +const ExchangeRateTooltip = ( + <> + + DAI balance will be converted via DSR contracts and then supplied as sDAI to Aave reserve. + Switching incurs no additional costs and no slippage. + {' '} + + Learn more + + +); diff --git a/src/components/transactions/Supply/SupplyWrappedTokenActions.tsx b/src/components/transactions/Supply/SupplyWrappedTokenActions.tsx new file mode 100644 index 0000000000..e7a77d4760 --- /dev/null +++ b/src/components/transactions/Supply/SupplyWrappedTokenActions.tsx @@ -0,0 +1,236 @@ +import { gasLimitRecommendations, MAX_UINT_AMOUNT, ProtocolAction } from '@aave/contract-helpers'; +import { SignatureLike } from '@ethersproject/bytes'; +import { TransactionResponse } from '@ethersproject/providers'; +import { Trans } from '@lingui/macro'; +import { BoxProps } from '@mui/material'; +import { parseUnits } from 'ethers/lib/utils'; +import { useState } from 'react'; +import { MOCK_SIGNED_HASH } from 'src/helpers/useTransactionHandler'; +import { useModalContext } from 'src/hooks/useModal'; +import { useWeb3Context } from 'src/libs/hooks/useWeb3Context'; +import { useRootStore } from 'src/store/root'; +import { ApprovalMethod } from 'src/store/walletSlice'; +import { getErrorTextFromError, TxAction } from 'src/ui-config/errorMapping'; + +import { TxActionsWrapper } from '../TxActionsWrapper'; +import { APPROVAL_GAS_LIMIT, checkRequiresApproval } from '../utils'; +import { useApprovedAmount } from './useApprovedAmount'; + +interface SignedParams { + signature: SignatureLike; + deadline: string; + amount: string; +} + +interface SupplyWrappedTokenActionProps extends BoxProps { + tokenIn: string; + amountToSupply: string; + decimals: number; + symbol: string; +} +export const SupplyWrappedTokenActions = ({ + tokenIn, + amountToSupply, + decimals, + symbol, + sx, + ...props +}: SupplyWrappedTokenActionProps) => { + const [ + currentMarketData, + tryPermit, + walletApprovalMethodPreference, + generateSignatureRequest, + generateApproval, + estimateGasLimit, + addTransaction, + supplyDaiAsSavingsDaiWithPermit, + supplyDaiAsSavingsDai, + ] = useRootStore((state) => [ + state.currentMarketData, + state.tryPermit, + state.walletApprovalMethodPreference, + state.generateSignatureRequest, + state.generateApproval, + state.estimateGasLimit, + state.addTransaction, + state.supplyDaiAsSavingsDaiWithPermit, + state.supplyDaiAsSavingsDai, + ]); + + const [signatureParams, setSignatureParams] = useState(); + + const { + approvalTxState, + mainTxState, + loadingTxns, + setApprovalTxState, + setMainTxState, + setTxError, + setGasLimit, + } = useModalContext(); + + const { signTxData, sendTx } = useWeb3Context(); + + const { loading: loadingApprovedAmount, approval } = useApprovedAmount({ + spender: currentMarketData.addresses.SDAI_TOKEN_WRAPPER || '', + tokenAddress: tokenIn, + }); + + let requiresApproval = false; + if (approval) { + requiresApproval = checkRequiresApproval({ + approvedAmount: approval.amount, + amount: amountToSupply, + signedAmount: signatureParams ? signatureParams.amount : '0', + }); + } + + const permitAvailable = tryPermit(tokenIn); + + const usePermit = permitAvailable && walletApprovalMethodPreference === ApprovalMethod.PERMIT; + + // Update gas estimation + let supplyGasLimit = 0; + if (usePermit) { + supplyGasLimit = Number(gasLimitRecommendations[ProtocolAction.supplyWithPermit].recommended); + } else { + supplyGasLimit = Number(gasLimitRecommendations[ProtocolAction.supply].recommended); + if (requiresApproval && !approvalTxState.success) { + supplyGasLimit += Number(APPROVAL_GAS_LIMIT); + } + } + + setGasLimit(supplyGasLimit.toString()); + + console.log('loading approved amount', loadingApprovedAmount); + console.log('approval', approval); + + const approvalAction = async () => { + try { + if (requiresApproval && approval) { + if (usePermit) { + const deadline = Math.floor(Date.now() / 1000 + 3600).toString(); + const signatureRequest = await generateSignatureRequest({ + ...approval, + deadline, + amount: parseUnits(amountToSupply, decimals).toString(), + }); + + const response = await signTxData(signatureRequest); + setSignatureParams({ signature: response, deadline, amount: amountToSupply }); + setApprovalTxState({ + txHash: MOCK_SIGNED_HASH, + loading: false, + success: true, + }); + } else { + let approveTxData = generateApproval(approval); + setApprovalTxState({ ...approvalTxState, loading: true }); + approveTxData = await estimateGasLimit(approveTxData); + const response = await sendTx(approveTxData); + await response.wait(1); + setApprovalTxState({ + txHash: response.hash, + loading: false, + success: true, + }); + addTransaction(response.hash, { + action: ProtocolAction.approval, + txState: 'success', + asset: tokenIn, + amount: MAX_UINT_AMOUNT, + assetName: symbol, + }); + // fetchApprovedAmount(true); + } + } + } catch (error) { + const parsedError = getErrorTextFromError(error, TxAction.GAS_ESTIMATION, false); + setTxError(parsedError); + setApprovalTxState({ + txHash: undefined, + loading: false, + }); + } + }; + + const action = async () => { + try { + setMainTxState({ ...mainTxState, loading: true }); + + let response: TransactionResponse; + let action = ProtocolAction.default; + + // determine if approval is signature or transaction + // checking user preference is not sufficient because permit may be available but the user has an existing approval + if (usePermit && signatureParams) { + action = ProtocolAction.supplyWithPermit; + let signedSupplyWithPermitTxData = supplyDaiAsSavingsDaiWithPermit( + parseUnits(amountToSupply, decimals).toString(), + signatureParams.deadline, + signatureParams.signature + ); + + signedSupplyWithPermitTxData = await estimateGasLimit(signedSupplyWithPermitTxData); + response = await sendTx(signedSupplyWithPermitTxData); + + await response.wait(1); + } else { + action = ProtocolAction.supply; + let supplyTxData = supplyDaiAsSavingsDai(parseUnits(amountToSupply, decimals).toString()); + supplyTxData = await estimateGasLimit(supplyTxData); + response = await sendTx(supplyTxData); + + await response.wait(1); + } + + setMainTxState({ + txHash: response.hash, + loading: false, + success: true, + }); + + addTransaction(response.hash, { + action, + txState: 'success', + asset: tokenIn, + amount: amountToSupply, + assetName: symbol, + }); + + // queryClient.invalidateQueries({ queryKey: [QueryKeys.POOL_TOKENS] }); + // refetchPoolData && refetchPoolData(); + // refetchIncentiveData && refetchIncentiveData(); + // refetchGhoData && refetchGhoData(); + } catch (error) { + const parsedError = getErrorTextFromError(error, TxAction.GAS_ESTIMATION, false); + setTxError(parsedError); + setMainTxState({ + txHash: undefined, + loading: false, + }); + } + }; + + return ( + Supply {symbol}} + actionInProgressText={Supplying {symbol}} + handleApproval={() => approvalAction()} + handleAction={action} + requiresApproval={requiresApproval} + tryPermit={permitAvailable} + sx={sx} + {...props} + /> + ); +}; diff --git a/src/components/transactions/Supply/useApprovedAmount.tsx b/src/components/transactions/Supply/useApprovedAmount.tsx new file mode 100644 index 0000000000..d3c6dfe5a4 --- /dev/null +++ b/src/components/transactions/Supply/useApprovedAmount.tsx @@ -0,0 +1,46 @@ +import { ApproveType, ERC20Service } from '@aave/contract-helpers'; +import { useCallback, useEffect, useState } from 'react'; +import { useRootStore } from 'src/store/root'; + +export const useApprovedAmount = ({ + spender, + tokenAddress, +}: { + spender: string; + tokenAddress: string; +}) => { + const [provider, account] = useRootStore((state) => [state.jsonRpcProvider, state.account]); + const [loading, setLoading] = useState(false); + const [approval, setApproval] = useState(); + + const fetchApprovedAmount = useCallback( + async (spender: string, tokenAddress: string) => { + setLoading(true); + console.log('fetching approved amount'); + const erc20Service = new ERC20Service(provider()); + const approvedTargetAmount = await erc20Service.approvedAmount({ + user: account, + token: tokenAddress, + spender, + }); + setApproval({ + amount: approvedTargetAmount.toString(), + spender, + token: tokenAddress, + user: account, + }); + setLoading(false); + }, + [provider, account] + ); + + useEffect(() => { + if (!spender || !tokenAddress) return; + fetchApprovedAmount(spender, tokenAddress); + }, [spender, tokenAddress, fetchApprovedAmount]); + + return { + loading, + approval, + }; +}; diff --git a/src/components/transactions/Supply/useSavingsDaiWrapper.ts b/src/components/transactions/Supply/useSavingsDaiWrapper.ts new file mode 100644 index 0000000000..86103df0ab --- /dev/null +++ b/src/components/transactions/Supply/useSavingsDaiWrapper.ts @@ -0,0 +1,46 @@ +import { formatUnits, parseUnits } from 'ethers/lib/utils'; +import { useEffect, useState } from 'react'; +import { useRootStore } from 'src/store/root'; + +export const useSavingsDaiWrapper = ({ + supplyAmount, + decimals, +}: { + supplyAmount: string; + decimals: number; +}) => { + const getSavingsDaiForDai = useRootStore((state) => state.getSavingsDaiForDai); + const [loading, setLoading] = useState(false); + const [tokenOutAmount, setTokenOutAmount] = useState('0'); + + useEffect(() => { + if (!supplyAmount || supplyAmount === '0') { + setTokenOutAmount('0'); + return; + } + + const getTokenInForTokenOut = async () => { + const amount = parseUnits(supplyAmount, decimals).toString(); + const tokenOut = await getSavingsDaiForDai(amount); + const outAmount = formatUnits(tokenOut.toString(), decimals); + // console.log('out amount', outAmount); + setTokenOutAmount(outAmount); + setLoading(false); + }; + + setLoading(true); + const timeout = setTimeout(() => { + getTokenInForTokenOut(); + }, 2000); + + return () => { + clearTimeout(timeout); + // setLoading(false); + }; + }, [decimals, getSavingsDaiForDai, supplyAmount]); + + return { + loading, + tokenOutAmount, + }; +}; diff --git a/src/components/transactions/Withdraw/WithdrawAndSwitchModalContent.tsx b/src/components/transactions/Withdraw/WithdrawAndSwitchModalContent.tsx index e5f98b180e..2f9ffff466 100644 --- a/src/components/transactions/Withdraw/WithdrawAndSwitchModalContent.tsx +++ b/src/components/transactions/Withdraw/WithdrawAndSwitchModalContent.tsx @@ -15,6 +15,7 @@ import { useProtocolDataContext } from 'src/hooks/useProtocolDataContext'; import { useWeb3Context } from 'src/libs/hooks/useWeb3Context'; import { ListSlippageButton } from 'src/modules/dashboard/lists/SlippageList'; import { useRootStore } from 'src/store/root'; +import { wrappedTokenConfig } from 'src/ui-config/wrappedTokenConfig'; import { calculateHFAfterWithdraw } from 'src/utils/hfUtils'; import { GENERAL } from 'src/utils/mixPanelEvents'; @@ -51,6 +52,9 @@ export const WithdrawAndSwitchModalContent = ({ const trackEvent = useRootStore((store) => store.trackEvent); const [maxSlippage, setMaxSlippage] = useState('0.1'); + // if the asset can be unwrapped (e.g. sDAI -> DAI) we don't need to use paraswap + const wrappedTokenOutConfig = wrappedTokenConfig[currentChainId][poolReserve.underlyingAsset]; + let swapTargets = reserves .filter((r) => r.underlyingAsset !== poolReserve.underlyingAsset) .map((reserve) => ({ @@ -59,6 +63,7 @@ export const WithdrawAndSwitchModalContent = ({ iconSymbol: reserve.iconSymbol, })); + // TODO: if withdrawing and unwrapping, should we show that asset at the top of the list? swapTargets = [ ...swapTargets.filter((r) => r.symbol === 'GHO'), ...swapTargets.filter((r) => r.symbol !== 'GHO'), @@ -89,7 +94,7 @@ export const WithdrawAndSwitchModalContent = ({ swapIn: { ...poolReserve, amount: amountRef.current }, swapOut: { ...swapTarget.reserve, amount: '0' }, max: isMaxSelected && maxAmountToWithdraw.eq(underlyingBalance), - skip: withdrawTxState.loading || false, + skip: wrappedTokenOutConfig !== '' || withdrawTxState.loading || false, maxSlippage: Number(maxSlippage), }); diff --git a/src/components/transactions/Withdraw/WithdrawModalContent.tsx b/src/components/transactions/Withdraw/WithdrawModalContent.tsx index c582190115..1969e9d95c 100644 --- a/src/components/transactions/Withdraw/WithdrawModalContent.tsx +++ b/src/components/transactions/Withdraw/WithdrawModalContent.tsx @@ -1,8 +1,12 @@ import { API_ETH_MOCK_ADDRESS } from '@aave/contract-helpers'; import { valueToBigNumber } from '@aave/math-utils'; +import { ArrowNarrowRightIcon } from '@heroicons/react/solid'; import { Trans } from '@lingui/macro'; -import { Box, Checkbox, Typography } from '@mui/material'; +import { Box, Checkbox, Stack, SvgIcon, Typography } from '@mui/material'; import { useRef, useState } from 'react'; +import { ContentWithTooltip } from 'src/components/ContentWithTooltip'; +import { FormattedNumber } from 'src/components/primitives/FormattedNumber'; +import { Link } from 'src/components/primitives/Link'; import { Warning } from 'src/components/primitives/Warning'; import { useAppDataContext } from 'src/hooks/app-data-provider/useAppDataProvider'; import { useModalContext } from 'src/hooks/useModal'; @@ -11,7 +15,7 @@ import { useRootStore } from 'src/store/root'; import { calculateHFAfterWithdraw } from 'src/utils/hfUtils'; import { GENERAL } from 'src/utils/mixPanelEvents'; -import { AssetInput } from '../AssetInput'; +import { Asset, AssetInput } from '../AssetInput'; import { GasEstimationError } from '../FlowCommons/GasEstimationError'; import { ModalWrapperProps } from '../FlowCommons/ModalWrapper'; import { TxSuccessView } from '../FlowCommons/Success'; @@ -26,6 +30,16 @@ import { calculateMaxWithdrawAmount } from './utils'; import { WithdrawActions } from './WithdrawActions'; import { useWithdrawError } from './WithdrawError'; +interface WithdrawAsset extends Asset { + balance: string; +} + +// does this naming make sense? +// probably need to key on the underlying asset addresses +const wrappedTokenConfig: { [symbol: string]: string } = { + sDAI: 'DAI', +}; + export enum ErrorType { CAN_NOT_WITHDRAW_THIS_AMOUNT, POOL_DOES_NOT_HAVE_ENOUGH_LIQUIDITY, @@ -47,6 +61,12 @@ export const WithdrawModalContent = ({ const { user } = useAppDataContext(); const { currentNetworkConfig } = useProtocolDataContext(); + const [tokenToWithdraw, setTokenToWithdraw] = useState({ + address: poolReserve.underlyingAsset, + symbol: poolReserve.symbol, + iconSymbol: poolReserve.iconSymbol, + balance: '100', + }); const [_amount, setAmount] = useState(''); const [withdrawMax, setWithdrawMax] = useState(''); const [riskCheckboxAccepted, setRiskCheckboxAccepted] = useState(false); @@ -110,22 +130,30 @@ export const WithdrawModalContent = ({ /> ); + const assets: WithdrawAsset[] = [ + { + balance: maxAmountToWithdraw.toString(), + symbol: poolReserve.symbol, + iconSymbol: poolReserve.iconSymbol, + }, + ]; + + if (wrappedTokenConfig[poolReserve.symbol]) { + assets.push({ + balance: maxAmountToWithdraw.toString(), + symbol: wrappedTokenConfig[poolReserve.symbol], + iconSymbol: wrappedTokenConfig[poolReserve.symbol], + }); + } + return ( <> Supply balance ) } + exchangeRateComponent={ + poolReserve.symbol === 'sDAI' && tokenToWithdraw.symbol === 'DAI' && + } /> {blockingError !== undefined && ( @@ -227,3 +258,116 @@ export const WithdrawModalContent = ({ ); }; + +const ExchangeRate = () => { + return ( + + + + + + sDAI + + + + + + + DAI + + + + ); +}; +const ExchangeRateTooltip = ( + <> + + DAI balance will be converted via DSR contracts and then supplied as sDAI to Aave reserve. + Switching incurs no additional costs and no slippage. + {' '} + + Learn more + + +); + +const ExchangeIcon = () => { + return ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ); +}; diff --git a/src/locales/en/messages.js b/src/locales/en/messages.js index ded666b4d0..adaa452475 100644 --- a/src/locales/en/messages.js +++ b/src/locales/en/messages.js @@ -1 +1 @@ -/*eslint-disable*/module.exports={messages:{"...":"...",".CSV":".CSV",".JSON":".JSON","<0><1><2/>Add <3/> stkAAVE to borrow at <4/> (max discount)":"<0><1><2/>Add <3/> stkAAVE to borrow at <4/> (max discount)","<0><1><2/>Add stkAAVE to see borrow rate with discount":"<0><1><2/>Add stkAAVE to see borrow rate with discount","<0>Ampleforth is a rebasing asset. Visit the <1>documentation to learn more.":"<0>Ampleforth is a rebasing asset. Visit the <1>documentation to learn more.","<0>Attention: Parameter changes via governance can alter your account health factor and risk of liquidation. Follow the <1>Aave governance forum for updates.":"<0>Attention: Parameter changes via governance can alter your account health factor and risk of liquidation. Follow the <1>Aave governance forum for updates.","<0>Slippage tolerance <1>{selectedSlippage}% <2>{0}":["<0>Slippage tolerance <1>",["selectedSlippage"],"% <2>",["0"],""],"AAVE holders (Ethereum network only) can stake their AAVE in the Safety Module to add more security to the protocol and earn Safety Incentives. In the case of a shortfall event, up to 30% of your stake can be slashed to cover the deficit, providing an additional layer of protection for the protocol.":"AAVE holders (Ethereum network only) can stake their AAVE in the Safety Module to add more security to the protocol and earn Safety Incentives. In the case of a shortfall event, up to 30% of your stake can be slashed to cover the deficit, providing an additional layer of protection for the protocol.","APR":"APR","APY":"APY","APY change":"APY change","APY type":"APY type","APY type change":"APY type change","APY with discount applied":"APY with discount applied","APY, fixed rate":"APY, fixed rate","APY, stable":"APY, stable","APY, variable":"APY, variable","AToken supply is not zero":"AToken supply is not zero","Aave Governance":"Aave Governance","Aave aToken":"Aave aToken","Aave debt token":"Aave debt token","Aave is a fully decentralized, community governed protocol by the AAVE token-holders. AAVE token-holders collectively discuss, propose, and vote on upgrades to the protocol. AAVE token-holders (Ethereum network only) can either vote themselves on new proposals or delagate to an address of choice. To learn more check out the Governance":"Aave is a fully decentralized, community governed protocol by the AAVE token-holders. AAVE token-holders collectively discuss, propose, and vote on upgrades to the protocol. AAVE token-holders (Ethereum network only) can either vote themselves on new proposals or delagate to an address of choice. To learn more check out the Governance","Aave per month":"Aave per month","About GHO":"About GHO","Account":"Account","Action cannot be performed because the reserve is frozen":"Action cannot be performed because the reserve is frozen","Action cannot be performed because the reserve is paused":"Action cannot be performed because the reserve is paused","Action requires an active reserve":"Action requires an active reserve","Activate Cooldown":"Activate Cooldown","Add stkAAVE to see borrow APY with the discount":"Add stkAAVE to see borrow APY with the discount","Add to wallet":"Add to wallet","Add {0} to wallet to track your balance.":["Add ",["0"]," to wallet to track your balance."],"Address is not a contract":"Address is not a contract","Addresses":"Addresses","Addresses ({0})":["Addresses (",["0"],")"],"All Assets":"All Assets","All done!":"All done!","All proposals":"All proposals","All transactions":"All transactions","Allowance required action":"Allowance required action","Allows you to decide whether to use a supplied asset as collateral. An asset used as collateral will affect your borrowing power and health factor.":"Allows you to decide whether to use a supplied asset as collateral. An asset used as collateral will affect your borrowing power and health factor.","Allows you to switch between <0>variable and <1>stable interest rates, where variable rate can increase and decrease depending on the amount of liquidity in the reserve, and stable rate will stay the same for the duration of your loan.":"Allows you to switch between <0>variable and <1>stable interest rates, where variable rate can increase and decrease depending on the amount of liquidity in the reserve, and stable rate will stay the same for the duration of your loan.","Amount":"Amount","Amount claimable":"Amount claimable","Amount in cooldown":"Amount in cooldown","Amount must be greater than 0":"Amount must be greater than 0","Amount to unstake":"Amount to unstake","An error has occurred fetching the proposal metadata from IPFS.":"An error has occurred fetching the proposal metadata from IPFS.","Approve Confirmed":"Approve Confirmed","Approve with":"Approve with","Approve {symbol} to continue":["Approve ",["symbol"]," to continue"],"Approving {symbol}...":["Approving ",["symbol"],"..."],"Array parameters that should be equal length are not":"Array parameters that should be equal length are not","Asset":"Asset","Asset can be only used as collateral in isolation mode with limited borrowing power. To enter isolation mode, disable all other collateral.":"Asset can be only used as collateral in isolation mode with limited borrowing power. To enter isolation mode, disable all other collateral.","Asset can only be used as collateral in isolation mode only.":"Asset can only be used as collateral in isolation mode only.","Asset cannot be migrated because you have isolated collateral in {marketName} v3 Market which limits borrowable assets. You can manage your collateral in <0>{marketName} V3 Dashboard":["Asset cannot be migrated because you have isolated collateral in ",["marketName"]," v3 Market which limits borrowable assets. You can manage your collateral in <0>",["marketName"]," V3 Dashboard"],"Asset cannot be migrated due to insufficient liquidity or borrow cap limitation in {marketName} v3 market.":["Asset cannot be migrated due to insufficient liquidity or borrow cap limitation in ",["marketName"]," v3 market."],"Asset cannot be migrated due to supply cap restriction in {marketName} v3 market.":["Asset cannot be migrated due to supply cap restriction in ",["marketName"]," v3 market."],"Asset cannot be migrated to {marketName} V3 Market due to E-mode restrictions. You can disable or manage E-mode categories in your <0>V3 Dashboard":["Asset cannot be migrated to ",["marketName"]," V3 Market due to E-mode restrictions. You can disable or manage E-mode categories in your <0>V3 Dashboard"],"Asset cannot be migrated to {marketName} v3 Market since collateral asset will enable isolation mode.":["Asset cannot be migrated to ",["marketName"]," v3 Market since collateral asset will enable isolation mode."],"Asset cannot be used as collateral.":"Asset cannot be used as collateral.","Asset category":"Asset category","Asset is frozen in {marketName} v3 market, hence this position cannot be migrated.":["Asset is frozen in ",["marketName"]," v3 market, hence this position cannot be migrated."],"Asset is not borrowable in isolation mode":"Asset is not borrowable in isolation mode","Asset is not listed":"Asset is not listed","Asset supply is limited to a certain amount to reduce protocol exposure to the asset and to help manage risks involved.":"Asset supply is limited to a certain amount to reduce protocol exposure to the asset and to help manage risks involved.","Assets":"Assets","Assets to borrow":"Assets to borrow","Assets to supply":"Assets to supply","Assets with zero LTV ({assetsBlockingWithdraw}) must be withdrawn or disabled as collateral to perform this action":["Assets with zero LTV (",["assetsBlockingWithdraw"],") must be withdrawn or disabled as collateral to perform this action"],"At a discount":"At a discount","Author":"Author","Available":"Available","Available assets":"Available assets","Available liquidity":"Available liquidity","Available on":"Available on","Available rewards":"Available rewards","Available to borrow":"Available to borrow","Available to supply":"Available to supply","Back to Dashboard":"Back to Dashboard","Balance":"Balance","Balance to revoke":"Balance to revoke","Be careful - You are very close to liquidation. Consider depositing more collateral or paying down some of your borrowed positions":"Be careful - You are very close to liquidation. Consider depositing more collateral or paying down some of your borrowed positions","Be mindful of the network congestion and gas prices.":"Be mindful of the network congestion and gas prices.","Because this asset is paused, no actions can be taken until further notice":"Because this asset is paused, no actions can be taken until further notice","Before supplying":"Before supplying","Blocked Address":"Blocked Address","Borrow":"Borrow","Borrow APY":"Borrow APY","Borrow APY rate":"Borrow APY rate","Borrow APY, fixed rate":"Borrow APY, fixed rate","Borrow APY, stable":"Borrow APY, stable","Borrow APY, variable":"Borrow APY, variable","Borrow amount to reach {0}% utilization":["Borrow amount to reach ",["0"],"% utilization"],"Borrow and repay in same block is not allowed":"Borrow and repay in same block is not allowed","Borrow apy":"Borrow apy","Borrow balance":"Borrow balance","Borrow balance after repay":"Borrow balance after repay","Borrow balance after switch":"Borrow balance after switch","Borrow cap":"Borrow cap","Borrow cap is exceeded":"Borrow cap is exceeded","Borrow info":"Borrow info","Borrow power used":"Borrow power used","Borrow rate change":"Borrow rate change","Borrow {symbol}":["Borrow ",["symbol"]],"Borrowed":"Borrowed","Borrowed asset amount":"Borrowed asset amount","Borrowing is currently unavailable for {0}.":["Borrowing is currently unavailable for ",["0"],"."],"Borrowing is disabled due to an Aave community decision. <0>More details":"Borrowing is disabled due to an Aave community decision. <0>More details","Borrowing is not enabled":"Borrowing is not enabled","Borrowing is unavailable because you’re using Isolation mode. To manage Isolation mode visit your <0>Dashboard.":"Borrowing is unavailable because you’re using Isolation mode. To manage Isolation mode visit your <0>Dashboard.","Borrowing is unavailable because you’ve enabled Efficiency Mode (E-Mode) and Isolation mode. To manage E-Mode and Isolation mode visit your <0>Dashboard.":"Borrowing is unavailable because you’ve enabled Efficiency Mode (E-Mode) and Isolation mode. To manage E-Mode and Isolation mode visit your <0>Dashboard.","Borrowing is unavailable because you’ve enabled Efficiency Mode (E-Mode) for {0} category. To manage E-Mode categories visit your <0>Dashboard.":["Borrowing is unavailable because you’ve enabled Efficiency Mode (E-Mode) for ",["0"]," category. To manage E-Mode categories visit your <0>Dashboard."],"Borrowing of this asset is limited to a certain amount to minimize liquidity pool insolvency.":"Borrowing of this asset is limited to a certain amount to minimize liquidity pool insolvency.","Borrowing power and assets are limited due to Isolation mode.":"Borrowing power and assets are limited due to Isolation mode.","Borrowing this amount will reduce your health factor and increase risk of liquidation.":"Borrowing this amount will reduce your health factor and increase risk of liquidation.","Borrowing {symbol}":["Borrowing ",["symbol"]],"Both":"Both","Buy Crypto With Fiat":"Buy Crypto With Fiat","Buy Crypto with Fiat":"Buy Crypto with Fiat","Buy {cryptoSymbol} with Fiat":["Buy ",["cryptoSymbol"]," with Fiat"],"COPIED!":"COPIED!","COPY IMAGE":"COPY IMAGE","Can be collateral":"Can be collateral","Can be executed":"Can be executed","Cancel":"Cancel","Cannot disable E-Mode":"Cannot disable E-Mode","Choose how much voting/proposition power to give to someone else by delegating some of your AAVE or stkAAVE balance. Your tokens will remain in your account, but your delegate will be able to vote or propose on your behalf. If your AAVE or stkAAVE balance changes, your delegate's voting/proposition power will be automatically adjusted.":"Choose how much voting/proposition power to give to someone else by delegating some of your AAVE or stkAAVE balance. Your tokens will remain in your account, but your delegate will be able to vote or propose on your behalf. If your AAVE or stkAAVE balance changes, your delegate's voting/proposition power will be automatically adjusted.","Choose one of the on-ramp services":"Choose one of the on-ramp services","Claim":"Claim","Claim all":"Claim all","Claim all rewards":"Claim all rewards","Claim {0}":["Claim ",["0"]],"Claim {symbol}":["Claim ",["symbol"]],"Claimable AAVE":"Claimable AAVE","Claimed":"Claimed","Claiming":"Claiming","Claiming {symbol}":["Claiming ",["symbol"]],"Close":"Close","Collateral":"Collateral","Collateral balance after repay":"Collateral balance after repay","Collateral change":"Collateral change","Collateral is (mostly) the same currency that is being borrowed":"Collateral is (mostly) the same currency that is being borrowed","Collateral to repay with":"Collateral to repay with","Collateral usage":"Collateral usage","Collateral usage is limited because of Isolation mode.":"Collateral usage is limited because of Isolation mode.","Collateral usage is limited because of isolation mode.":"Collateral usage is limited because of isolation mode.","Collateral usage is limited because of isolation mode. <0>Learn More":"Collateral usage is limited because of isolation mode. <0>Learn More","Collateralization":"Collateralization","Collector Contract":"Collector Contract","Collector Info":"Collector Info","Connect wallet":"Connect wallet","Cooldown period":"Cooldown period","Cooldown period warning":"Cooldown period warning","Cooldown time left":"Cooldown time left","Cooldown to unstake":"Cooldown to unstake","Cooling down...":"Cooling down...","Copy address":"Copy address","Copy error message":"Copy error message","Copy error text":"Copy error text","Covered debt":"Covered debt","Created":"Created","Current LTV":"Current LTV","Current differential":"Current differential","Current v2 Balance":"Current v2 Balance","Current v2 balance":"Current v2 balance","Current votes":"Current votes","Dark mode":"Dark mode","Dashboard":"Dashboard","Data couldn't be fetched, please reload graph.":"Data couldn't be fetched, please reload graph.","Debt":"Debt","Debt ceiling is exceeded":"Debt ceiling is exceeded","Debt ceiling is not zero":"Debt ceiling is not zero","Debt ceiling limits the amount possible to borrow against this asset by protocol users. Debt ceiling is specific to assets in isolation mode and is denoted in USD.":"Debt ceiling limits the amount possible to borrow against this asset by protocol users. Debt ceiling is specific to assets in isolation mode and is denoted in USD.","Delegated power":"Delegated power","Details":"Details","Developers":"Developers","Differential":"Differential","Disable E-Mode":"Disable E-Mode","Disable testnet":"Disable testnet","Disable {symbol} as collateral":["Disable ",["symbol"]," as collateral"],"Disabled":"Disabled","Disabling E-Mode":"Disabling E-Mode","Disabling this asset as collateral affects your borrowing power and Health Factor.":"Disabling this asset as collateral affects your borrowing power and Health Factor.","Disconnect Wallet":"Disconnect Wallet","Discord channel":"Discord channel","Discount":"Discount","Discount applied for <0/> staking AAVE":"Discount applied for <0/> staking AAVE","Discount model parameters":"Discount model parameters","Discount parameters are decided by the Aave community and may be changed over time. Check Governance for updates and vote to participate. <0>Learn more":"Discount parameters are decided by the Aave community and may be changed over time. Check Governance for updates and vote to participate. <0>Learn more","Discountable amount":"Discountable amount","Docs":"Docs","Download":"Download","Due to internal stETH mechanics required for rebasing support, it is not possible to perform a collateral switch where stETH is the source token.":"Due to internal stETH mechanics required for rebasing support, it is not possible to perform a collateral switch where stETH is the source token.","Due to the Horizon bridge exploit, certain assets on the Harmony network are not at parity with Ethereum, which affects the Aave V3 Harmony market.":"Due to the Horizon bridge exploit, certain assets on the Harmony network are not at parity with Ethereum, which affects the Aave V3 Harmony market.","E-Mode":"E-Mode","E-Mode Category":"E-Mode Category","E-Mode category":"E-Mode category","E-Mode increases your LTV for a selected category of assets up to 97%. <0>Learn more":"E-Mode increases your LTV for a selected category of assets up to 97%. <0>Learn more","E-Mode increases your LTV for a selected category of assets up to<0/>. <1>Learn more":"E-Mode increases your LTV for a selected category of assets up to<0/>. <1>Learn more","E-Mode increases your LTV for a selected category of assets, meaning that when E-mode is enabled, you will have higher borrowing power over assets of the same E-mode category which are defined by Aave Governance. You can enter E-Mode from your <0>Dashboard. To learn more about E-Mode and applied restrictions in <1>FAQ or <2>Aave V3 Technical Paper.":"E-Mode increases your LTV for a selected category of assets, meaning that when E-mode is enabled, you will have higher borrowing power over assets of the same E-mode category which are defined by Aave Governance. You can enter E-Mode from your <0>Dashboard. To learn more about E-Mode and applied restrictions in <1>FAQ or <2>Aave V3 Technical Paper.","Effective interest rate":"Effective interest rate","Efficiency mode (E-Mode)":"Efficiency mode (E-Mode)","Emode":"Emode","Enable E-Mode":"Enable E-Mode","Enable {symbol} as collateral":["Enable ",["symbol"]," as collateral"],"Enabled":"Enabled","Enabling E-Mode":"Enabling E-Mode","Enabling E-Mode only allows you to borrow assets belonging to the selected category. Please visit our <0>FAQ guide to learn more about how it works and the applied restrictions.":"Enabling E-Mode only allows you to borrow assets belonging to the selected category. Please visit our <0>FAQ guide to learn more about how it works and the applied restrictions.","Enabling this asset as collateral increases your borrowing power and Health Factor. However, it can get liquidated if your health factor drops below 1.":"Enabling this asset as collateral increases your borrowing power and Health Factor. However, it can get liquidated if your health factor drops below 1.","Ended":"Ended","Ends":"Ends","English":"English","Enter ETH address":"Enter ETH address","Enter an amount":"Enter an amount","Error connecting. Try refreshing the page.":"Error connecting. Try refreshing the page.","Estimated compounding interest, including discount for Staking {0}AAVE in Safety Module.":["Estimated compounding interest, including discount for Staking ",["0"],"AAVE in Safety Module."],"Exceeds the discount":"Exceeds the discount","Executed":"Executed","Expected amount to repay":"Expected amount to repay","Expires":"Expires","Export data to":"Export data to","FAQ":"FAQ","FAQS":"FAQS","Failed to load proposal voters. Please refresh the page.":"Failed to load proposal voters. Please refresh the page.","Faucet":"Faucet","Faucet {0}":["Faucet ",["0"]],"Fetching data...":"Fetching data...","Filter":"Filter","Fixed":"Fixed","Fixed rate":"Fixed rate","Flashloan is disabled for this asset, hence this position cannot be migrated.":"Flashloan is disabled for this asset, hence this position cannot be migrated.","For repayment of a specific type of debt, the user needs to have debt that type":"For repayment of a specific type of debt, the user needs to have debt that type","Forum discussion":"Forum discussion","French":"French","Funds in the Safety Module":"Funds in the Safety Module","GHO is a native decentralized, collateral-backed digital asset pegged to USD. It is created by users via borrowing against multiple collateral. When user repays their GHO borrow position, the protocol burns that user's GHO. All the interest payments accrued by minters of GHO would be directly transferred to the AaveDAO treasury.":"GHO is a native decentralized, collateral-backed digital asset pegged to USD. It is created by users via borrowing against multiple collateral. When user repays their GHO borrow position, the protocol burns that user's GHO. All the interest payments accrued by minters of GHO would be directly transferred to the AaveDAO treasury.","Get ABP Token":"Get ABP Token","Global settings":"Global settings","Go Back":"Go Back","Go to Balancer Pool":"Go to Balancer Pool","Go to V3 Dashboard":"Go to V3 Dashboard","Governance":"Governance","Greek":"Greek","Health Factor ({0} v2)":["Health Factor (",["0"]," v2)"],"Health Factor ({0} v3)":["Health Factor (",["0"]," v3)"],"Health factor":"Health factor","Health factor is lesser than the liquidation threshold":"Health factor is lesser than the liquidation threshold","Health factor is not below the threshold":"Health factor is not below the threshold","Hide":"Hide","Holders of stkAAVE receive a discount on the GHO borrowing rate":"Holders of stkAAVE receive a discount on the GHO borrowing rate","I acknowledge the risks involved.":"I acknowledge the risks involved.","I fully understand the risks of migrating.":"I fully understand the risks of migrating.","I understand how cooldown ({0}) and unstaking ({1}) work":["I understand how cooldown (",["0"],") and unstaking (",["1"],") work"],"If the error continues to happen,<0/> you may report it to this":"If the error continues to happen,<0/> you may report it to this","If the health factor goes below 1, the liquidation of your collateral might be triggered.":"If the health factor goes below 1, the liquidation of your collateral might be triggered.","If you DO NOT unstake within {0} of unstake window, you will need to activate cooldown process again.":["If you DO NOT unstake within ",["0"]," of unstake window, you will need to activate cooldown process again."],"If your loan to value goes above the liquidation threshold your collateral supplied may be liquidated.":"If your loan to value goes above the liquidation threshold your collateral supplied may be liquidated.","In E-Mode some assets are not borrowable. Exit E-Mode to get access to all assets":"In E-Mode some assets are not borrowable. Exit E-Mode to get access to all assets","In Isolation mode, you cannot supply other assets as collateral. A global debt ceiling limits the borrowing power of the isolated asset. To exit isolation mode disable {0} as collateral before borrowing another asset. Read more in our <0>FAQ":["In Isolation mode, you cannot supply other assets as collateral. A global debt ceiling limits the borrowing power of the isolated asset. To exit isolation mode disable ",["0"]," as collateral before borrowing another asset. Read more in our <0>FAQ"],"Inconsistent flashloan parameters":"Inconsistent flashloan parameters","Insufficient collateral to cover new borrow position. Wallet must have borrowing power remaining to perform debt switch.":"Insufficient collateral to cover new borrow position. Wallet must have borrowing power remaining to perform debt switch.","Interest accrued":"Interest accrued","Interest rate rebalance conditions were not met":"Interest rate rebalance conditions were not met","Interest rate strategy":"Interest rate strategy","Invalid amount to burn":"Invalid amount to burn","Invalid amount to mint":"Invalid amount to mint","Invalid bridge protocol fee":"Invalid bridge protocol fee","Invalid expiration":"Invalid expiration","Invalid flashloan premium":"Invalid flashloan premium","Invalid return value of the flashloan executor function":"Invalid return value of the flashloan executor function","Invalid signature":"Invalid signature","Isolated":"Isolated","Isolated Debt Ceiling":"Isolated Debt Ceiling","Isolated assets have limited borrowing power and other assets cannot be used as collateral.":"Isolated assets have limited borrowing power and other assets cannot be used as collateral.","Join the community discussion":"Join the community discussion","LEARN MORE":"LEARN MORE","Language":"Language","Learn more":"Learn more","Learn more about risks involved":"Learn more about risks involved","Learn more in our <0>FAQ guide":"Learn more in our <0>FAQ guide","Learn more.":"Learn more.","Links":"Links","Liqudation":"Liqudation","Liquidated collateral":"Liquidated collateral","Liquidation":"Liquidation","Liquidation <0/> threshold":"Liquidation <0/> threshold","Liquidation Threshold":"Liquidation Threshold","Liquidation at":"Liquidation at","Liquidation penalty":"Liquidation penalty","Liquidation risk":"Liquidation risk","Liquidation risk parameters":"Liquidation risk parameters","Liquidation threshold":"Liquidation threshold","Liquidation value":"Liquidation value","Loading data...":"Loading data...","Ltv validation failed":"Ltv validation failed","MAI has been paused due to a community decision. Supply, borrows and repays are impacted. <0>More details":"MAI has been paused due to a community decision. Supply, borrows and repays are impacted. <0>More details","MAX":"MAX","Manage analytics":"Manage analytics","Market":"Market","Markets":"Markets","Max":"Max","Max LTV":"Max LTV","Max slashing":"Max slashing","Max slippage":"Max slippage","Maximum amount available to borrow against this asset is limited because debt ceiling is at {0}%.":["Maximum amount available to borrow against this asset is limited because debt ceiling is at ",["0"],"%."],"Maximum amount available to borrow is <0/> {0} (<1/>).":["Maximum amount available to borrow is <0/> ",["0"]," (<1/>)."],"Maximum amount available to borrow is limited because protocol borrow cap is nearly reached.":"Maximum amount available to borrow is limited because protocol borrow cap is nearly reached.","Maximum amount available to supply is <0/> {0} (<1/>).":["Maximum amount available to supply is <0/> ",["0"]," (<1/>)."],"Maximum amount available to supply is limited because protocol supply cap is at {0}%.":["Maximum amount available to supply is limited because protocol supply cap is at ",["0"],"%."],"Maximum loan to value":"Maximum loan to value","Meet GHO":"Meet GHO","Menu":"Menu","Migrate":"Migrate","Migrate to V3":"Migrate to V3","Migrate to v3":"Migrate to v3","Migrate to {0} v3 Market":["Migrate to ",["0"]," v3 Market"],"Migrated":"Migrated","Migrating":"Migrating","Migrating multiple collaterals and borrowed assets at the same time can be an expensive operation and might fail in certain situations.<0>Therefore it’s not recommended to migrate positions with more than 5 assets (deposited + borrowed) at the same time.":"Migrating multiple collaterals and borrowed assets at the same time can be an expensive operation and might fail in certain situations.<0>Therefore it’s not recommended to migrate positions with more than 5 assets (deposited + borrowed) at the same time.","Migration risks":"Migration risks","Minimum GHO borrow amount":"Minimum GHO borrow amount","Minimum USD value received":"Minimum USD value received","Minimum staked Aave amount":"Minimum staked Aave amount","Minimum {0} received":["Minimum ",["0"]," received"],"More":"More","NAY":"NAY","Need help connecting a wallet? <0>Read our FAQ":"Need help connecting a wallet? <0>Read our FAQ","Net APR":"Net APR","Net APY":"Net APY","Net APY is the combined effect of all supply and borrow positions on net worth, including incentives. It is possible to have a negative net APY if debt APY is higher than supply APY.":"Net APY is the combined effect of all supply and borrow positions on net worth, including incentives. It is possible to have a negative net APY if debt APY is higher than supply APY.","Net worth":"Net worth","Network":"Network","Network not supported for this wallet":"Network not supported for this wallet","New APY":"New APY","No assets selected to migrate.":"No assets selected to migrate.","No rewards to claim":"No rewards to claim","No search results{0}":["No search results",["0"]],"No transactions yet.":"No transactions yet.","No voting power":"No voting power","None":"None","Not a valid address":"Not a valid address","Not enough balance on your wallet":"Not enough balance on your wallet","Not enough collateral to repay this amount of debt with":"Not enough collateral to repay this amount of debt with","Not enough staked balance":"Not enough staked balance","Not enough voting power to participate in this proposal":"Not enough voting power to participate in this proposal","Not reached":"Not reached","Nothing borrowed yet":"Nothing borrowed yet","Nothing found":"Nothing found","Nothing staked":"Nothing staked","Nothing supplied yet":"Nothing supplied yet","Notify":"Notify","Ok, Close":"Ok, Close","Ok, I got it":"Ok, I got it","Operation not supported":"Operation not supported","Oracle price":"Oracle price","Overview":"Overview","Page not found":"Page not found","Participating in this {symbol} reserve gives annualized rewards.":["Participating in this ",["symbol"]," reserve gives annualized rewards."],"Pending...":"Pending...","Per the community, the Fantom market has been frozen.":"Per the community, the Fantom market has been frozen.","Per the community, the V2 AMM market has been deprecated.":"Per the community, the V2 AMM market has been deprecated.","Please always be aware of your <0>Health Factor (HF) when partially migrating a position and that your rates will be updated to V3 rates.":"Please always be aware of your <0>Health Factor (HF) when partially migrating a position and that your rates will be updated to V3 rates.","Please connect a wallet to view your personal information here.":"Please connect a wallet to view your personal information here.","Please connect your wallet to be able to switch your tokens.":"Please connect your wallet to be able to switch your tokens.","Please connect your wallet to get free testnet assets.":"Please connect your wallet to get free testnet assets.","Please connect your wallet to see migration tool.":"Please connect your wallet to see migration tool.","Please connect your wallet to see your supplies, borrowings, and open positions.":"Please connect your wallet to see your supplies, borrowings, and open positions.","Please connect your wallet to view transaction history.":"Please connect your wallet to view transaction history.","Please enter a valid wallet address.":"Please enter a valid wallet address.","Please switch to {networkName}.":["Please switch to ",["networkName"],"."],"Please, connect your wallet":"Please, connect your wallet","Pool addresses provider is not registered":"Pool addresses provider is not registered","Powered by":"Powered by","Preview tx and migrate":"Preview tx and migrate","Price":"Price","Price data is not currently available for this reserve on the protocol subgraph":"Price data is not currently available for this reserve on the protocol subgraph","Price impact":"Price impact","Price impact is the spread between the total value of the entry tokens switched and the destination tokens obtained (in USD), which results from the limited liquidity of the trading pair.":"Price impact is the spread between the total value of the entry tokens switched and the destination tokens obtained (in USD), which results from the limited liquidity of the trading pair.","Price impact {0}%":["Price impact ",["0"],"%"],"Privacy":"Privacy","Proposal details":"Proposal details","Proposal overview":"Proposal overview","Proposals":"Proposals","Proposition":"Proposition","Protocol borrow cap at 100% for this asset. Further borrowing unavailable.":"Protocol borrow cap at 100% for this asset. Further borrowing unavailable.","Protocol borrow cap is at 100% for this asset. Further borrowing unavailable.":"Protocol borrow cap is at 100% for this asset. Further borrowing unavailable.","Protocol debt ceiling is at 100% for this asset. Further borrowing against this asset is unavailable.":"Protocol debt ceiling is at 100% for this asset. Further borrowing against this asset is unavailable.","Protocol debt ceiling is at 100% for this asset. Futher borrowing against this asset is unavailable.":"Protocol debt ceiling is at 100% for this asset. Futher borrowing against this asset is unavailable.","Protocol supply cap at 100% for this asset. Further supply unavailable.":"Protocol supply cap at 100% for this asset. Further supply unavailable.","Protocol supply cap is at 100% for this asset. Further supply unavailable.":"Protocol supply cap is at 100% for this asset. Further supply unavailable.","Quorum":"Quorum","Rate change":"Rate change","Raw-Ipfs":"Raw-Ipfs","Reached":"Reached","Reactivate cooldown period to unstake {0} {stakedToken}":["Reactivate cooldown period to unstake ",["0"]," ",["stakedToken"]],"Read more here.":"Read more here.","Read-only mode allows to see address positions in Aave, but you won't be able to perform transactions.":"Read-only mode allows to see address positions in Aave, but you won't be able to perform transactions.","Read-only mode.":"Read-only mode.","Read-only mode. Connect to a wallet to perform transactions.":"Read-only mode. Connect to a wallet to perform transactions.","Receive (est.)":"Receive (est.)","Received":"Received","Recipient address":"Recipient address","Rejected connection request":"Rejected connection request","Reload":"Reload","Reload the page":"Reload the page","Remaining debt":"Remaining debt","Remaining supply":"Remaining supply","Repaid":"Repaid","Repay":"Repay","Repay with":"Repay with","Repay {symbol}":["Repay ",["symbol"]],"Repaying {symbol}":["Repaying ",["symbol"]],"Repayment amount to reach {0}% utilization":["Repayment amount to reach ",["0"],"% utilization"],"Reserve Size":"Reserve Size","Reserve factor":"Reserve factor","Reserve factor is a percentage of interest which goes to a {0} that is controlled by Aave governance to promote ecosystem growth.":["Reserve factor is a percentage of interest which goes to a ",["0"]," that is controlled by Aave governance to promote ecosystem growth."],"Reserve status & configuration":"Reserve status & configuration","Reset":"Reset","Restake":"Restake","Restake {symbol}":["Restake ",["symbol"]],"Restaked":"Restaked","Restaking {symbol}":["Restaking ",["symbol"]],"Review approval tx details":"Review approval tx details","Review changes to continue":"Review changes to continue","Review tx":"Review tx","Review tx details":"Review tx details","Revoke power":"Revoke power","Reward(s) to claim":"Reward(s) to claim","Rewards APR":"Rewards APR","Risk details":"Risk details","SEE CHARTS":"SEE CHARTS","Safety of your deposited collateral against the borrowed assets and its underlying value.":"Safety of your deposited collateral against the borrowed assets and its underlying value.","Save and share":"Save and share","Seatbelt report":"Seatbelt report","Seems like we can't switch the network automatically. Please check if you can change it from the wallet.":"Seems like we can't switch the network automatically. Please check if you can change it from the wallet.","Select":"Select","Select APY type to switch":"Select APY type to switch","Select an asset":"Select an asset","Select language":"Select language","Select slippage tolerance":"Select slippage tolerance","Select v2 borrows to migrate":"Select v2 borrows to migrate","Select v2 supplies to migrate":"Select v2 supplies to migrate","Selected assets have successfully migrated. Visit the Market Dashboard to see them.":"Selected assets have successfully migrated. Visit the Market Dashboard to see them.","Selected borrow assets":"Selected borrow assets","Selected supply assets":"Selected supply assets","Send feedback":"Send feedback","Set up delegation":"Set up delegation","Setup notifications about your Health Factor using the Hal app.":"Setup notifications about your Health Factor using the Hal app.","Share on Lens":"Share on Lens","Share on twitter":"Share on twitter","Show":"Show","Show Frozen or paused assets":"Show Frozen or paused assets","Show assets with 0 balance":"Show assets with 0 balance","Sign to continue":"Sign to continue","Signatures ready":"Signatures ready","Signing":"Signing","Since this asset is frozen, the only available actions are withdraw and repay which can be accessed from the <0>Dashboard":"Since this asset is frozen, the only available actions are withdraw and repay which can be accessed from the <0>Dashboard","Since this is a test network, you can get any of the assets if you have ETH on your wallet":"Since this is a test network, you can get any of the assets if you have ETH on your wallet","Slippage":"Slippage","Slippage is the difference between the quoted and received amounts from changing market conditions between the moment the transaction is submitted and its verification.":"Slippage is the difference between the quoted and received amounts from changing market conditions between the moment the transaction is submitted and its verification.","Some migrated assets will not be used as collateral due to enabled isolation mode in {marketName} V3 Market. Visit <0>{marketName} V3 Dashboard to manage isolation mode.":["Some migrated assets will not be used as collateral due to enabled isolation mode in ",["marketName"]," V3 Market. Visit <0>",["marketName"]," V3 Dashboard to manage isolation mode."],"Something went wrong":"Something went wrong","Sorry, an unexpected error happened. In the meantime you may try reloading the page, or come back later.":"Sorry, an unexpected error happened. In the meantime you may try reloading the page, or come back later.","Sorry, we couldn't find the page you were looking for.":"Sorry, we couldn't find the page you were looking for.","Spanish":"Spanish","Stable":"Stable","Stable Interest Type is disabled for this currency":"Stable Interest Type is disabled for this currency","Stable borrowing is enabled":"Stable borrowing is enabled","Stable borrowing is not enabled":"Stable borrowing is not enabled","Stable debt supply is not zero":"Stable debt supply is not zero","Stable interest rate will <0>stay the same for the duration of your loan. Recommended for long-term loan periods and for users who prefer predictability.":"Stable interest rate will <0>stay the same for the duration of your loan. Recommended for long-term loan periods and for users who prefer predictability.","Stablecoin":"Stablecoin","Stake":"Stake","Stake AAVE":"Stake AAVE","Stake ABPT":"Stake ABPT","Stake cooldown activated":"Stake cooldown activated","Staked":"Staked","Staking":"Staking","Staking APR":"Staking APR","Staking Rewards":"Staking Rewards","Staking balance":"Staking balance","Staking discount":"Staking discount","Started":"Started","State":"State","Static interest rate that is determined by Aave Governance. This rate may be changed over time depending on the need for the GHO supply to contract/expand. <0>Learn more":"Static interest rate that is determined by Aave Governance. This rate may be changed over time depending on the need for the GHO supply to contract/expand. <0>Learn more","Supplied":"Supplied","Supplied asset amount":"Supplied asset amount","Supply":"Supply","Supply APY":"Supply APY","Supply apy":"Supply apy","Supply balance":"Supply balance","Supply balance after switch":"Supply balance after switch","Supply cap is exceeded":"Supply cap is exceeded","Supply cap on target reserve reached. Try lowering the amount.":"Supply cap on target reserve reached. Try lowering the amount.","Supply {symbol}":["Supply ",["symbol"]],"Supplying your":"Supplying your","Supplying {symbol}":["Supplying ",["symbol"]],"Switch":"Switch","Switch APY type":"Switch APY type","Switch E-Mode":"Switch E-Mode","Switch E-Mode category":"Switch E-Mode category","Switch Network":"Switch Network","Switch borrow position":"Switch borrow position","Switch rate":"Switch rate","Switch to":"Switch to","Switched":"Switched","Switching":"Switching","Switching E-Mode":"Switching E-Mode","Switching rate":"Switching rate","Techpaper":"Techpaper","Terms":"Terms","Test Assets":"Test Assets","Testnet mode":"Testnet mode","Testnet mode is ON":"Testnet mode is ON","Thank you for voting!!":"Thank you for voting!!","The % of your total borrowing power used. This is based on the amount of your collateral supplied and the total amount that you can borrow.":"The % of your total borrowing power used. This is based on the amount of your collateral supplied and the total amount that you can borrow.","The Aave Balancer Pool Token (ABPT) is a liquidity pool token. You can receive ABPT by depositing a combination of AAVE + ETH in the Balancer liquidity pool. You can then stake your BPT in the Safety Module to secure the protocol and earn Safety Incentives.":"The Aave Balancer Pool Token (ABPT) is a liquidity pool token. You can receive ABPT by depositing a combination of AAVE + ETH in the Balancer liquidity pool. You can then stake your BPT in the Safety Module to secure the protocol and earn Safety Incentives.","The Aave Protocol is programmed to always use the price of 1 GHO = $1. This is different from using market pricing via oracles for other crypto assets. This creates stabilizing arbitrage opportunities when the price of GHO fluctuates.":"The Aave Protocol is programmed to always use the price of 1 GHO = $1. This is different from using market pricing via oracles for other crypto assets. This creates stabilizing arbitrage opportunities when the price of GHO fluctuates.","The Maximum LTV ratio represents the maximum borrowing power of a specific collateral. For example, if a collateral has an LTV of 75%, the user can borrow up to 0.75 worth of ETH in the principal currency for every 1 ETH worth of collateral.":"The Maximum LTV ratio represents the maximum borrowing power of a specific collateral. For example, if a collateral has an LTV of 75%, the user can borrow up to 0.75 worth of ETH in the principal currency for every 1 ETH worth of collateral.","The Stable Rate is not enabled for this currency":"The Stable Rate is not enabled for this currency","The address of the pool addresses provider is invalid":"The address of the pool addresses provider is invalid","The app is running in testnet mode. Learn how it works in":"The app is running in testnet mode. Learn how it works in","The caller of the function is not an AToken":"The caller of the function is not an AToken","The caller of this function must be a pool":"The caller of this function must be a pool","The collateral balance is 0":"The collateral balance is 0","The collateral chosen cannot be liquidated":"The collateral chosen cannot be liquidated","The cooldown period is the time required prior to unstaking your tokens (20 days). You can only withdraw your assets from the Security Module after the cooldown period and within the unstake window.<0>Learn more":"The cooldown period is the time required prior to unstaking your tokens (20 days). You can only withdraw your assets from the Security Module after the cooldown period and within the unstake window.<0>Learn more","The cooldown period is {0}. After {1} of cooldown, you will enter unstake window of {2}. You will continue receiving rewards during cooldown and unstake window.":["The cooldown period is ",["0"],". After ",["1"]," of cooldown, you will enter unstake window of ",["2"],". You will continue receiving rewards during cooldown and unstake window."],"The effects on the health factor would cause liquidation. Try lowering the amount.":"The effects on the health factor would cause liquidation. Try lowering the amount.","The loan to value of the migrated positions would cause liquidation. Increase migrated collateral or reduce migrated borrow to continue.":"The loan to value of the migrated positions would cause liquidation. Increase migrated collateral or reduce migrated borrow to continue.","The requested amount is greater than the max loan size in stable rate mode":"The requested amount is greater than the max loan size in stable rate mode","The total amount of your assets denominated in USD that can be used as collateral for borrowing assets.":"The total amount of your assets denominated in USD that can be used as collateral for borrowing assets.","The underlying asset cannot be rescued":"The underlying asset cannot be rescued","The underlying balance needs to be greater than 0":"The underlying balance needs to be greater than 0","The weighted average of APY for all borrowed assets, including incentives.":"The weighted average of APY for all borrowed assets, including incentives.","The weighted average of APY for all supplied assets, including incentives.":"The weighted average of APY for all supplied assets, including incentives.","There are not enough funds in the{0}reserve to borrow":["There are not enough funds in the",["0"],"reserve to borrow"],"There is not enough collateral to cover a new borrow":"There is not enough collateral to cover a new borrow","There is not enough liquidity for the target asset to perform the switch. Try lowering the amount.":"There is not enough liquidity for the target asset to perform the switch. Try lowering the amount.","There was some error. Please try changing the parameters or <0><1>copy the error":"There was some error. Please try changing the parameters or <0><1>copy the error","These assets are temporarily frozen or paused by Aave community decisions, meaning that further supply / borrow, or rate swap of these assets are unavailable. Withdrawals and debt repayments are allowed. Follow the <0>Aave governance forum for further updates.":"These assets are temporarily frozen or paused by Aave community decisions, meaning that further supply / borrow, or rate swap of these assets are unavailable. Withdrawals and debt repayments are allowed. Follow the <0>Aave governance forum for further updates.","These funds have been borrowed and are not available for withdrawal at this time.":"These funds have been borrowed and are not available for withdrawal at this time.","This action will reduce V2 health factor below liquidation threshold. retain collateral or migrate borrow position to continue.":"This action will reduce V2 health factor below liquidation threshold. retain collateral or migrate borrow position to continue.","This action will reduce health factor of V3 below liquidation threshold. Increase migrated collateral or reduce migrated borrow to continue.":"This action will reduce health factor of V3 below liquidation threshold. Increase migrated collateral or reduce migrated borrow to continue.","This action will reduce your health factor. Please be mindful of the increased risk of collateral liquidation.":"This action will reduce your health factor. Please be mindful of the increased risk of collateral liquidation.","This address is blocked on app.aave.com because it is associated with one or more":"This address is blocked on app.aave.com because it is associated with one or more","This asset has almost reached its borrow cap. There is only {messageValue} available to be borrowed from this market.":["This asset has almost reached its borrow cap. There is only ",["messageValue"]," available to be borrowed from this market."],"This asset has almost reached its supply cap. There can only be {messageValue} supplied to this market.":["This asset has almost reached its supply cap. There can only be ",["messageValue"]," supplied to this market."],"This asset has reached its borrow cap. Nothing is available to be borrowed from this market.":"This asset has reached its borrow cap. Nothing is available to be borrowed from this market.","This asset has reached its supply cap. Nothing is available to be supplied from this market.":"This asset has reached its supply cap. Nothing is available to be supplied from this market.","This asset is frozen due to an Aave Protocol Governance decision. <0>More details":"This asset is frozen due to an Aave Protocol Governance decision. <0>More details","This asset is frozen due to an Aave Protocol Governance decision. On the 20th of December 2022, renFIL will no longer be supported and cannot be bridged back to its native network. It is recommended to withdraw supply positions and repay borrow positions so that renFIL can be bridged back to FIL before the deadline. After this date, it will no longer be possible to convert renFIL to FIL. <0>More details":"This asset is frozen due to an Aave Protocol Governance decision. On the 20th of December 2022, renFIL will no longer be supported and cannot be bridged back to its native network. It is recommended to withdraw supply positions and repay borrow positions so that renFIL can be bridged back to FIL before the deadline. After this date, it will no longer be possible to convert renFIL to FIL. <0>More details","This asset is frozen due to an Aave community decision. <0>More details":"This asset is frozen due to an Aave community decision. <0>More details","This asset is planned to be offboarded due to an Aave Protocol Governance decision. <0>More details":"This asset is planned to be offboarded due to an Aave Protocol Governance decision. <0>More details","This gas calculation is only an estimation. Your wallet will set the price of the transaction. You can modify the gas settings directly from your wallet provider.":"This gas calculation is only an estimation. Your wallet will set the price of the transaction. You can modify the gas settings directly from your wallet provider.","This integration was<0>proposed and approvedby the community.":"This integration was<0>proposed and approvedby the community.","This is the total amount available for you to borrow. You can borrow based on your collateral and until the borrow cap is reached.":"This is the total amount available for you to borrow. You can borrow based on your collateral and until the borrow cap is reached.","This is the total amount that you are able to supply to in this reserve. You are able to supply your wallet balance up until the supply cap is reached.":"This is the total amount that you are able to supply to in this reserve. You are able to supply your wallet balance up until the supply cap is reached.","This represents the threshold at which a borrow position will be considered undercollateralized and subject to liquidation for each collateral. For example, if a collateral has a liquidation threshold of 80%, it means that the position will be liquidated when the debt value is worth 80% of the collateral value.":"This represents the threshold at which a borrow position will be considered undercollateralized and subject to liquidation for each collateral. For example, if a collateral has a liquidation threshold of 80%, it means that the position will be liquidated when the debt value is worth 80% of the collateral value.","Time left to be able to withdraw your staked asset.":"Time left to be able to withdraw your staked asset.","Time left to unstake":"Time left to unstake","Time left until the withdrawal window closes.":"Time left until the withdrawal window closes.","Tip: Try increasing slippage or reduce input amount":"Tip: Try increasing slippage or reduce input amount","To borrow you need to supply any asset to be used as collateral.":"To borrow you need to supply any asset to be used as collateral.","To continue, you need to grant Aave smart contracts permission to move your funds from your wallet. Depending on the asset and wallet you use, it is done by signing the permission message (gas free), or by submitting an approval transaction (requires gas). <0>Learn more":"To continue, you need to grant Aave smart contracts permission to move your funds from your wallet. Depending on the asset and wallet you use, it is done by signing the permission message (gas free), or by submitting an approval transaction (requires gas). <0>Learn more","To enable E-mode for the {0} category, all borrow positions outside of this category must be closed.":["To enable E-mode for the ",["0"]," category, all borrow positions outside of this category must be closed."],"To repay on behalf of a user an explicit amount to repay is needed":"To repay on behalf of a user an explicit amount to repay is needed","To request access for this permissioned market, please visit: <0>Acces Provider Name":"To request access for this permissioned market, please visit: <0>Acces Provider Name","To submit a proposal for minor changes to the protocol, you'll need at least 80.00K power. If you want to change the core code base, you'll need 320k power.<0>Learn more.":"To submit a proposal for minor changes to the protocol, you'll need at least 80.00K power. If you want to change the core code base, you'll need 320k power.<0>Learn more.","Top 10 addresses":"Top 10 addresses","Total available":"Total available","Total borrowed":"Total borrowed","Total borrows":"Total borrows","Total emission per day":"Total emission per day","Total interest accrued":"Total interest accrued","Total market size":"Total market size","Total supplied":"Total supplied","Total voting power":"Total voting power","Total worth":"Total worth","Track wallet":"Track wallet","Track wallet balance in read-only mode":"Track wallet balance in read-only mode","Transaction failed":"Transaction failed","Transaction history":"Transaction history","Transaction history is not currently available for this market":"Transaction history is not currently available for this market","Transaction overview":"Transaction overview","Transactions":"Transactions","UNSTAKE {symbol}":["UNSTAKE ",["symbol"]],"Unavailable":"Unavailable","Unbacked":"Unbacked","Unbacked mint cap is exceeded":"Unbacked mint cap is exceeded","Underlying asset does not exist in {marketName} v3 Market, hence this position cannot be migrated.":["Underlying asset does not exist in ",["marketName"]," v3 Market, hence this position cannot be migrated."],"Underlying token":"Underlying token","Unstake now":"Unstake now","Unstake window":"Unstake window","Unstaked":"Unstaked","Unstaking {symbol}":["Unstaking ",["symbol"]],"Update: Disruptions reported for WETH, WBTC, WMATIC, and USDT. AIP 230 will resolve the disruptions and the market will be operating as normal on ~26th May 13h00 UTC.":"Update: Disruptions reported for WETH, WBTC, WMATIC, and USDT. AIP 230 will resolve the disruptions and the market will be operating as normal on ~26th May 13h00 UTC.","Use it to vote for or against active proposals.":"Use it to vote for or against active proposals.","Use your AAVE and stkAAVE balance to delegate your voting and proposition powers. You will not be sending any tokens, only the rights to vote and propose changes to the protocol. You can re-delegate or revoke power to self at any time.":"Use your AAVE and stkAAVE balance to delegate your voting and proposition powers. You will not be sending any tokens, only the rights to vote and propose changes to the protocol. You can re-delegate or revoke power to self at any time.","Used as collateral":"Used as collateral","User cannot withdraw more than the available balance":"User cannot withdraw more than the available balance","User did not borrow the specified currency":"User did not borrow the specified currency","User does not have outstanding stable rate debt on this reserve":"User does not have outstanding stable rate debt on this reserve","User does not have outstanding variable rate debt on this reserve":"User does not have outstanding variable rate debt on this reserve","User is in isolation mode":"User is in isolation mode","User is trying to borrow multiple assets including a siloed one":"User is trying to borrow multiple assets including a siloed one","Users who stake AAVE in Safety Module (i.e. stkAAVE holders) receive a discount on GHO borrow interest rate. The discount applies to 100 GHO for every 1 stkAAVE held. Use the calculator below to see GHO borrow rate with the discount applied.":"Users who stake AAVE in Safety Module (i.e. stkAAVE holders) receive a discount on GHO borrow interest rate. The discount applies to 100 GHO for every 1 stkAAVE held. Use the calculator below to see GHO borrow rate with the discount applied.","Utilization Rate":"Utilization Rate","VIEW TX":"VIEW TX","VOTE NAY":"VOTE NAY","VOTE YAE":"VOTE YAE","Variable":"Variable","Variable debt supply is not zero":"Variable debt supply is not zero","Variable interest rate will <0>fluctuate based on the market conditions. Recommended for short-term positions.":"Variable interest rate will <0>fluctuate based on the market conditions. Recommended for short-term positions.","Variable rate":"Variable rate","Version 2":"Version 2","Version 3":"Version 3","View":"View","View Transactions":"View Transactions","View all votes":"View all votes","View contract":"View contract","View details":"View details","View on Explorer":"View on Explorer","Vote NAY":"Vote NAY","Vote YAE":"Vote YAE","Voted NAY":"Voted NAY","Voted YAE":"Voted YAE","Votes":"Votes","Voting":"Voting","Voting power":"Voting power","Voting results":"Voting results","Wallet Balance":"Wallet Balance","Wallet balance":"Wallet balance","Wallet not detected. Connect or install wallet and retry":"Wallet not detected. Connect or install wallet and retry","Wallets are provided by External Providers and by selecting you agree to Terms of those Providers. Your access to the wallet might be reliant on the External Provider being operational.":"Wallets are provided by External Providers and by selecting you agree to Terms of those Providers. Your access to the wallet might be reliant on the External Provider being operational.","We couldn't find any assets related to your search. Try again with a different asset name, symbol, or address.":"We couldn't find any assets related to your search. Try again with a different asset name, symbol, or address.","We couldn't find any transactions related to your search. Try again with a different asset name, or reset filters.":"We couldn't find any transactions related to your search. Try again with a different asset name, or reset filters.","We couldn’t detect a wallet. Connect a wallet to stake and view your balance.":"We couldn’t detect a wallet. Connect a wallet to stake and view your balance.","We suggest you go back to the Dashboard.":"We suggest you go back to the Dashboard.","Website":"Website","When a liquidation occurs, liquidators repay up to 50% of the outstanding borrowed amount on behalf of the borrower. In return, they can buy the collateral at a discount and keep the difference (liquidation penalty) as a bonus.":"When a liquidation occurs, liquidators repay up to 50% of the outstanding borrowed amount on behalf of the borrower. In return, they can buy the collateral at a discount and keep the difference (liquidation penalty) as a bonus.","With a voting power of <0/>":"With a voting power of <0/>","With testnet Faucet you can get free assets to test the Aave Protocol. Make sure to switch your wallet provider to the appropriate testnet network, select desired asset, and click ‘Faucet’ to get tokens transferred to your wallet. The assets on a testnet are not “real,” meaning they have no monetary value. <0>Learn more":"With testnet Faucet you can get free assets to test the Aave Protocol. Make sure to switch your wallet provider to the appropriate testnet network, select desired asset, and click ‘Faucet’ to get tokens transferred to your wallet. The assets on a testnet are not “real,” meaning they have no monetary value. <0>Learn more","Withdraw":"Withdraw","Withdraw & Switch":"Withdraw & Switch","Withdraw and Switch":"Withdraw and Switch","Withdraw {symbol}":["Withdraw ",["symbol"]],"Withdrawing and Switching":"Withdrawing and Switching","Withdrawing this amount will reduce your health factor and increase risk of liquidation.":"Withdrawing this amount will reduce your health factor and increase risk of liquidation.","Withdrawing {symbol}":["Withdrawing ",["symbol"]],"Wrong Network":"Wrong Network","YAE":"YAE","You are entering Isolation mode":"You are entering Isolation mode","You can borrow this asset with a stable rate only if you borrow more than the amount you are supplying as collateral.":"You can borrow this asset with a stable rate only if you borrow more than the amount you are supplying as collateral.","You can not change Interest Type to stable as your borrowings are higher than your collateral":"You can not change Interest Type to stable as your borrowings are higher than your collateral","You can not disable E-Mode as your current collateralization level is above 80%, disabling E-Mode can cause liquidation. To exit E-Mode supply or repay borrowed positions.":"You can not disable E-Mode as your current collateralization level is above 80%, disabling E-Mode can cause liquidation. To exit E-Mode supply or repay borrowed positions.","You can not switch usage as collateral mode for this currency, because it will cause collateral call":"You can not switch usage as collateral mode for this currency, because it will cause collateral call","You can not use this currency as collateral":"You can not use this currency as collateral","You can not withdraw this amount because it will cause collateral call":"You can not withdraw this amount because it will cause collateral call","You can only switch to tokens with variable APY types. After this transaction, you may change the variable rate to a stable one if available.":"You can only switch to tokens with variable APY types. After this transaction, you may change the variable rate to a stable one if available.","You can only withdraw your assets from the Security Module after the cooldown period ends and the unstake window is active.":"You can only withdraw your assets from the Security Module after the cooldown period ends and the unstake window is active.","You can report incident to our <0>Discord or<1>Github.":"You can report incident to our <0>Discord or<1>Github.","You cancelled the transaction.":"You cancelled the transaction.","You did not participate in this proposal":"You did not participate in this proposal","You do not have supplies in this currency":"You do not have supplies in this currency","You don’t have enough funds in your wallet to repay the full amount. If you proceed to repay with your current amount of funds, you will still have a small borrowing position in your dashboard.":"You don’t have enough funds in your wallet to repay the full amount. If you proceed to repay with your current amount of funds, you will still have a small borrowing position in your dashboard.","You have no AAVE/stkAAVE balance to delegate.":"You have no AAVE/stkAAVE balance to delegate.","You have not borrow yet using this currency":"You have not borrow yet using this currency","You may borrow up to <0/> GHO at <1/> (max discount)":"You may borrow up to <0/> GHO at <1/> (max discount)","You may enter a custom amount in the field.":"You may enter a custom amount in the field.","You switched to {0} rate":["You switched to ",["0"]," rate"],"You unstake here":"You unstake here","You voted {0}":["You voted ",["0"]],"You will exit isolation mode and other tokens can now be used as collateral":"You will exit isolation mode and other tokens can now be used as collateral","You {action} <0/> {symbol}":["You ",["action"]," <0/> ",["symbol"]],"You've successfully switched borrow position.":"You've successfully switched borrow position.","You've successfully switched tokens.":"You've successfully switched tokens.","You've successfully withdrew & switched tokens.":"You've successfully withdrew & switched tokens.","Your balance is lower than the selected amount.":"Your balance is lower than the selected amount.","Your borrows":"Your borrows","Your current loan to value based on your collateral supplied.":"Your current loan to value based on your collateral supplied.","Your health factor and loan to value determine the assurance of your collateral. To avoid liquidations you can supply more collateral or repay borrow positions.":"Your health factor and loan to value determine the assurance of your collateral. To avoid liquidations you can supply more collateral or repay borrow positions.","Your info":"Your info","Your proposition power is based on your AAVE/stkAAVE balance and received delegations.":"Your proposition power is based on your AAVE/stkAAVE balance and received delegations.","Your reward balance is 0":"Your reward balance is 0","Your supplies":"Your supplies","Your voting info":"Your voting info","Your voting power is based on your AAVE/stkAAVE balance and received delegations.":"Your voting power is based on your AAVE/stkAAVE balance and received delegations.","Your {name} wallet is empty. Purchase or transfer assets or use <0>{0} to transfer your {network} assets.":["Your ",["name"]," wallet is empty. Purchase or transfer assets or use <0>",["0"]," to transfer your ",["network"]," assets."],"Your {name} wallet is empty. Purchase or transfer assets.":["Your ",["name"]," wallet is empty. Purchase or transfer assets."],"Your {networkName} wallet is empty. Get free test assets at":["Your ",["networkName"]," wallet is empty. Get free test assets at"],"Your {networkName} wallet is empty. Get free test {0} at":["Your ",["networkName"]," wallet is empty. Get free test ",["0"]," at"],"Zero address not valid":"Zero address not valid","assets":"assets","blocked activities":"blocked activities","copy the error":"copy the error","disabled":"disabled","documentation":"documentation","enabled":"enabled","ends":"ends","for":"for","of":"of","on":"on","please check that the amount you want to supply is not currently being used for staking. If it is being used for staking, your transaction might fail.":"please check that the amount you want to supply is not currently being used for staking. If it is being used for staking, your transaction might fail.","repaid":"repaid","stETH supplied as collateral will continue to accrue staking rewards provided by daily rebases.":"stETH supplied as collateral will continue to accrue staking rewards provided by daily rebases.","stETH tokens will be migrated to Wrapped stETH using Lido Protocol wrapper which leads to supply balance change after migration: {0}":["stETH tokens will be migrated to Wrapped stETH using Lido Protocol wrapper which leads to supply balance change after migration: ",["0"]],"staking view":"staking view","starts":"starts","stkAAVE holders get a discount on GHO borrow rate":"stkAAVE holders get a discount on GHO borrow rate","to":"to","tokens is not the same as staking them. If you wish to stake your":"tokens is not the same as staking them. If you wish to stake your","tokens, please go to the":"tokens, please go to the","withdrew":"withdrew","{0}":[["0"]],"{0} Balance":[["0"]," Balance"],"{0} Faucet":[["0"]," Faucet"],"{0} on-ramp service is provided by External Provider and by selecting you agree to Terms of the Provider. Your access to the service might be reliant on the External Provider being operational.":[["0"]," on-ramp service is provided by External Provider and by selecting you agree to Terms of the Provider. Your access to the service might be reliant on the External Provider being operational."],"{0}{name}":[["0"],["name"]],"{currentMethod}":[["currentMethod"]],"{d}d":[["d"],"d"],"{h}h":[["h"],"h"],"{m}m":[["m"],"m"],"{networkName} Faucet":[["networkName"]," Faucet"],"{notifyText}":[["notifyText"]],"{numSelected}/{numAvailable} assets selected":[["numSelected"],"/",["numAvailable"]," assets selected"],"{s}s":[["s"],"s"],"{title}":[["title"]],"{tooltipText}":[["tooltipText"]]}}; \ No newline at end of file +/*eslint-disable*/module.exports={messages:{"...":"...",".CSV":".CSV",".JSON":".JSON","<0><1><2/>Add <3/> stkAAVE to borrow at <4/> (max discount)":"<0><1><2/>Add <3/> stkAAVE to borrow at <4/> (max discount)","<0><1><2/>Add stkAAVE to see borrow rate with discount":"<0><1><2/>Add stkAAVE to see borrow rate with discount","<0>Ampleforth is a rebasing asset. Visit the <1>documentation to learn more.":"<0>Ampleforth is a rebasing asset. Visit the <1>documentation to learn more.","<0>Attention: Parameter changes via governance can alter your account health factor and risk of liquidation. Follow the <1>Aave governance forum for updates.":"<0>Attention: Parameter changes via governance can alter your account health factor and risk of liquidation. Follow the <1>Aave governance forum for updates.","<0>Slippage tolerance <1>{selectedSlippage}% <2>{0}":["<0>Slippage tolerance <1>",["selectedSlippage"],"% <2>",["0"],""],"AAVE holders (Ethereum network only) can stake their AAVE in the Safety Module to add more security to the protocol and earn Safety Incentives. In the case of a shortfall event, up to 30% of your stake can be slashed to cover the deficit, providing an additional layer of protection for the protocol.":"AAVE holders (Ethereum network only) can stake their AAVE in the Safety Module to add more security to the protocol and earn Safety Incentives. In the case of a shortfall event, up to 30% of your stake can be slashed to cover the deficit, providing an additional layer of protection for the protocol.","APR":"APR","APY":"APY","APY change":"APY change","APY type":"APY type","APY type change":"APY type change","APY with discount applied":"APY with discount applied","APY, fixed rate":"APY, fixed rate","APY, stable":"APY, stable","APY, variable":"APY, variable","AToken supply is not zero":"AToken supply is not zero","Aave Governance":"Aave Governance","Aave aToken":"Aave aToken","Aave debt token":"Aave debt token","Aave is a fully decentralized, community governed protocol by the AAVE token-holders. AAVE token-holders collectively discuss, propose, and vote on upgrades to the protocol. AAVE token-holders (Ethereum network only) can either vote themselves on new proposals or delagate to an address of choice. To learn more check out the Governance":"Aave is a fully decentralized, community governed protocol by the AAVE token-holders. AAVE token-holders collectively discuss, propose, and vote on upgrades to the protocol. AAVE token-holders (Ethereum network only) can either vote themselves on new proposals or delagate to an address of choice. To learn more check out the Governance","Aave per month":"Aave per month","About GHO":"About GHO","Account":"Account","Action cannot be performed because the reserve is frozen":"Action cannot be performed because the reserve is frozen","Action cannot be performed because the reserve is paused":"Action cannot be performed because the reserve is paused","Action requires an active reserve":"Action requires an active reserve","Activate Cooldown":"Activate Cooldown","Add stkAAVE to see borrow APY with the discount":"Add stkAAVE to see borrow APY with the discount","Add to wallet":"Add to wallet","Add {0} to wallet to track your balance.":["Add ",["0"]," to wallet to track your balance."],"Address is not a contract":"Address is not a contract","Addresses":"Addresses","Addresses ({0})":["Addresses (",["0"],")"],"All Assets":"All Assets","All done!":"All done!","All proposals":"All proposals","All transactions":"All transactions","Allowance required action":"Allowance required action","Allows you to decide whether to use a supplied asset as collateral. An asset used as collateral will affect your borrowing power and health factor.":"Allows you to decide whether to use a supplied asset as collateral. An asset used as collateral will affect your borrowing power and health factor.","Allows you to switch between <0>variable and <1>stable interest rates, where variable rate can increase and decrease depending on the amount of liquidity in the reserve, and stable rate will stay the same for the duration of your loan.":"Allows you to switch between <0>variable and <1>stable interest rates, where variable rate can increase and decrease depending on the amount of liquidity in the reserve, and stable rate will stay the same for the duration of your loan.","Amount":"Amount","Amount claimable":"Amount claimable","Amount in cooldown":"Amount in cooldown","Amount must be greater than 0":"Amount must be greater than 0","Amount to unstake":"Amount to unstake","An error has occurred fetching the proposal metadata from IPFS.":"An error has occurred fetching the proposal metadata from IPFS.","Approve Confirmed":"Approve Confirmed","Approve with":"Approve with","Approve {symbol} to continue":["Approve ",["symbol"]," to continue"],"Approving {symbol}...":["Approving ",["symbol"],"..."],"Array parameters that should be equal length are not":"Array parameters that should be equal length are not","Asset":"Asset","Asset can be only used as collateral in isolation mode with limited borrowing power. To enter isolation mode, disable all other collateral.":"Asset can be only used as collateral in isolation mode with limited borrowing power. To enter isolation mode, disable all other collateral.","Asset can only be used as collateral in isolation mode only.":"Asset can only be used as collateral in isolation mode only.","Asset cannot be migrated because you have isolated collateral in {marketName} v3 Market which limits borrowable assets. You can manage your collateral in <0>{marketName} V3 Dashboard":["Asset cannot be migrated because you have isolated collateral in ",["marketName"]," v3 Market which limits borrowable assets. You can manage your collateral in <0>",["marketName"]," V3 Dashboard"],"Asset cannot be migrated due to insufficient liquidity or borrow cap limitation in {marketName} v3 market.":["Asset cannot be migrated due to insufficient liquidity or borrow cap limitation in ",["marketName"]," v3 market."],"Asset cannot be migrated due to supply cap restriction in {marketName} v3 market.":["Asset cannot be migrated due to supply cap restriction in ",["marketName"]," v3 market."],"Asset cannot be migrated to {marketName} V3 Market due to E-mode restrictions. You can disable or manage E-mode categories in your <0>V3 Dashboard":["Asset cannot be migrated to ",["marketName"]," V3 Market due to E-mode restrictions. You can disable or manage E-mode categories in your <0>V3 Dashboard"],"Asset cannot be migrated to {marketName} v3 Market since collateral asset will enable isolation mode.":["Asset cannot be migrated to ",["marketName"]," v3 Market since collateral asset will enable isolation mode."],"Asset cannot be used as collateral.":"Asset cannot be used as collateral.","Asset category":"Asset category","Asset is frozen in {marketName} v3 market, hence this position cannot be migrated.":["Asset is frozen in ",["marketName"]," v3 market, hence this position cannot be migrated."],"Asset is not borrowable in isolation mode":"Asset is not borrowable in isolation mode","Asset is not listed":"Asset is not listed","Asset supply is limited to a certain amount to reduce protocol exposure to the asset and to help manage risks involved.":"Asset supply is limited to a certain amount to reduce protocol exposure to the asset and to help manage risks involved.","Assets":"Assets","Assets to borrow":"Assets to borrow","Assets to supply":"Assets to supply","Assets with zero LTV ({assetsBlockingWithdraw}) must be withdrawn or disabled as collateral to perform this action":["Assets with zero LTV (",["assetsBlockingWithdraw"],") must be withdrawn or disabled as collateral to perform this action"],"At a discount":"At a discount","Author":"Author","Available":"Available","Available assets":"Available assets","Available liquidity":"Available liquidity","Available on":"Available on","Available rewards":"Available rewards","Available to borrow":"Available to borrow","Available to supply":"Available to supply","Back to Dashboard":"Back to Dashboard","Balance":"Balance","Balance to revoke":"Balance to revoke","Be careful - You are very close to liquidation. Consider depositing more collateral or paying down some of your borrowed positions":"Be careful - You are very close to liquidation. Consider depositing more collateral or paying down some of your borrowed positions","Be mindful of the network congestion and gas prices.":"Be mindful of the network congestion and gas prices.","Because this asset is paused, no actions can be taken until further notice":"Because this asset is paused, no actions can be taken until further notice","Before supplying":"Before supplying","Blocked Address":"Blocked Address","Borrow":"Borrow","Borrow APY":"Borrow APY","Borrow APY rate":"Borrow APY rate","Borrow APY, fixed rate":"Borrow APY, fixed rate","Borrow APY, stable":"Borrow APY, stable","Borrow APY, variable":"Borrow APY, variable","Borrow amount to reach {0}% utilization":["Borrow amount to reach ",["0"],"% utilization"],"Borrow and repay in same block is not allowed":"Borrow and repay in same block is not allowed","Borrow apy":"Borrow apy","Borrow balance":"Borrow balance","Borrow balance after repay":"Borrow balance after repay","Borrow balance after switch":"Borrow balance after switch","Borrow cap":"Borrow cap","Borrow cap is exceeded":"Borrow cap is exceeded","Borrow info":"Borrow info","Borrow power used":"Borrow power used","Borrow rate change":"Borrow rate change","Borrow {symbol}":["Borrow ",["symbol"]],"Borrowed":"Borrowed","Borrowed asset amount":"Borrowed asset amount","Borrowing is currently unavailable for {0}.":["Borrowing is currently unavailable for ",["0"],"."],"Borrowing is disabled due to an Aave community decision. <0>More details":"Borrowing is disabled due to an Aave community decision. <0>More details","Borrowing is not enabled":"Borrowing is not enabled","Borrowing is unavailable because you’re using Isolation mode. To manage Isolation mode visit your <0>Dashboard.":"Borrowing is unavailable because you’re using Isolation mode. To manage Isolation mode visit your <0>Dashboard.","Borrowing is unavailable because you’ve enabled Efficiency Mode (E-Mode) and Isolation mode. To manage E-Mode and Isolation mode visit your <0>Dashboard.":"Borrowing is unavailable because you’ve enabled Efficiency Mode (E-Mode) and Isolation mode. To manage E-Mode and Isolation mode visit your <0>Dashboard.","Borrowing is unavailable because you’ve enabled Efficiency Mode (E-Mode) for {0} category. To manage E-Mode categories visit your <0>Dashboard.":["Borrowing is unavailable because you’ve enabled Efficiency Mode (E-Mode) for ",["0"]," category. To manage E-Mode categories visit your <0>Dashboard."],"Borrowing of this asset is limited to a certain amount to minimize liquidity pool insolvency.":"Borrowing of this asset is limited to a certain amount to minimize liquidity pool insolvency.","Borrowing power and assets are limited due to Isolation mode.":"Borrowing power and assets are limited due to Isolation mode.","Borrowing this amount will reduce your health factor and increase risk of liquidation.":"Borrowing this amount will reduce your health factor and increase risk of liquidation.","Borrowing {symbol}":["Borrowing ",["symbol"]],"Both":"Both","Buy Crypto With Fiat":"Buy Crypto With Fiat","Buy Crypto with Fiat":"Buy Crypto with Fiat","Buy {cryptoSymbol} with Fiat":["Buy ",["cryptoSymbol"]," with Fiat"],"COPIED!":"COPIED!","COPY IMAGE":"COPY IMAGE","Can be collateral":"Can be collateral","Can be executed":"Can be executed","Cancel":"Cancel","Cannot disable E-Mode":"Cannot disable E-Mode","Choose how much voting/proposition power to give to someone else by delegating some of your AAVE or stkAAVE balance. Your tokens will remain in your account, but your delegate will be able to vote or propose on your behalf. If your AAVE or stkAAVE balance changes, your delegate's voting/proposition power will be automatically adjusted.":"Choose how much voting/proposition power to give to someone else by delegating some of your AAVE or stkAAVE balance. Your tokens will remain in your account, but your delegate will be able to vote or propose on your behalf. If your AAVE or stkAAVE balance changes, your delegate's voting/proposition power will be automatically adjusted.","Choose one of the on-ramp services":"Choose one of the on-ramp services","Claim":"Claim","Claim all":"Claim all","Claim all rewards":"Claim all rewards","Claim {0}":["Claim ",["0"]],"Claim {symbol}":["Claim ",["symbol"]],"Claimable AAVE":"Claimable AAVE","Claimed":"Claimed","Claiming":"Claiming","Claiming {symbol}":["Claiming ",["symbol"]],"Close":"Close","Collateral":"Collateral","Collateral balance after repay":"Collateral balance after repay","Collateral change":"Collateral change","Collateral is (mostly) the same currency that is being borrowed":"Collateral is (mostly) the same currency that is being borrowed","Collateral to repay with":"Collateral to repay with","Collateral usage":"Collateral usage","Collateral usage is limited because of Isolation mode.":"Collateral usage is limited because of Isolation mode.","Collateral usage is limited because of isolation mode.":"Collateral usage is limited because of isolation mode.","Collateral usage is limited because of isolation mode. <0>Learn More":"Collateral usage is limited because of isolation mode. <0>Learn More","Collateralization":"Collateralization","Collector Contract":"Collector Contract","Collector Info":"Collector Info","Connect wallet":"Connect wallet","Cooldown period":"Cooldown period","Cooldown period warning":"Cooldown period warning","Cooldown time left":"Cooldown time left","Cooldown to unstake":"Cooldown to unstake","Cooling down...":"Cooling down...","Copy address":"Copy address","Copy error message":"Copy error message","Copy error text":"Copy error text","Covered debt":"Covered debt","Created":"Created","Current LTV":"Current LTV","Current differential":"Current differential","Current v2 Balance":"Current v2 Balance","Current v2 balance":"Current v2 balance","Current votes":"Current votes","Dark mode":"Dark mode","Dashboard":"Dashboard","Data couldn't be fetched, please reload graph.":"Data couldn't be fetched, please reload graph.","Debt":"Debt","Debt ceiling is exceeded":"Debt ceiling is exceeded","Debt ceiling is not zero":"Debt ceiling is not zero","Debt ceiling limits the amount possible to borrow against this asset by protocol users. Debt ceiling is specific to assets in isolation mode and is denoted in USD.":"Debt ceiling limits the amount possible to borrow against this asset by protocol users. Debt ceiling is specific to assets in isolation mode and is denoted in USD.","Delegated power":"Delegated power","Details":"Details","Developers":"Developers","Differential":"Differential","Disable E-Mode":"Disable E-Mode","Disable testnet":"Disable testnet","Disable {symbol} as collateral":["Disable ",["symbol"]," as collateral"],"Disabled":"Disabled","Disabling E-Mode":"Disabling E-Mode","Disabling this asset as collateral affects your borrowing power and Health Factor.":"Disabling this asset as collateral affects your borrowing power and Health Factor.","Disconnect Wallet":"Disconnect Wallet","Discord channel":"Discord channel","Discount":"Discount","Discount applied for <0/> staking AAVE":"Discount applied for <0/> staking AAVE","Discount model parameters":"Discount model parameters","Discount parameters are decided by the Aave community and may be changed over time. Check Governance for updates and vote to participate. <0>Learn more":"Discount parameters are decided by the Aave community and may be changed over time. Check Governance for updates and vote to participate. <0>Learn more","Discountable amount":"Discountable amount","Docs":"Docs","Download":"Download","Due to internal stETH mechanics required for rebasing support, it is not possible to perform a collateral switch where stETH is the source token.":"Due to internal stETH mechanics required for rebasing support, it is not possible to perform a collateral switch where stETH is the source token.","Due to the Horizon bridge exploit, certain assets on the Harmony network are not at parity with Ethereum, which affects the Aave V3 Harmony market.":"Due to the Horizon bridge exploit, certain assets on the Harmony network are not at parity with Ethereum, which affects the Aave V3 Harmony market.","E-Mode":"E-Mode","E-Mode Category":"E-Mode Category","E-Mode category":"E-Mode category","E-Mode increases your LTV for a selected category of assets up to 97%. <0>Learn more":"E-Mode increases your LTV for a selected category of assets up to 97%. <0>Learn more","E-Mode increases your LTV for a selected category of assets up to<0/>. <1>Learn more":"E-Mode increases your LTV for a selected category of assets up to<0/>. <1>Learn more","E-Mode increases your LTV for a selected category of assets, meaning that when E-mode is enabled, you will have higher borrowing power over assets of the same E-mode category which are defined by Aave Governance. You can enter E-Mode from your <0>Dashboard. To learn more about E-Mode and applied restrictions in <1>FAQ or <2>Aave V3 Technical Paper.":"E-Mode increases your LTV for a selected category of assets, meaning that when E-mode is enabled, you will have higher borrowing power over assets of the same E-mode category which are defined by Aave Governance. You can enter E-Mode from your <0>Dashboard. To learn more about E-Mode and applied restrictions in <1>FAQ or <2>Aave V3 Technical Paper.","Effective interest rate":"Effective interest rate","Efficiency mode (E-Mode)":"Efficiency mode (E-Mode)","Emode":"Emode","Enable E-Mode":"Enable E-Mode","Enable {symbol} as collateral":["Enable ",["symbol"]," as collateral"],"Enabled":"Enabled","Enabling E-Mode":"Enabling E-Mode","Enabling E-Mode only allows you to borrow assets belonging to the selected category. Please visit our <0>FAQ guide to learn more about how it works and the applied restrictions.":"Enabling E-Mode only allows you to borrow assets belonging to the selected category. Please visit our <0>FAQ guide to learn more about how it works and the applied restrictions.","Enabling this asset as collateral increases your borrowing power and Health Factor. However, it can get liquidated if your health factor drops below 1.":"Enabling this asset as collateral increases your borrowing power and Health Factor. However, it can get liquidated if your health factor drops below 1.","Ended":"Ended","Ends":"Ends","English":"English","Enter ETH address":"Enter ETH address","Enter an amount":"Enter an amount","Error connecting. Try refreshing the page.":"Error connecting. Try refreshing the page.","Estimated compounding interest, including discount for Staking {0}AAVE in Safety Module.":["Estimated compounding interest, including discount for Staking ",["0"],"AAVE in Safety Module."],"Exceeds the discount":"Exceeds the discount","Executed":"Executed","Expected amount to repay":"Expected amount to repay","Expires":"Expires","Export data to":"Export data to","FAQ":"FAQ","FAQS":"FAQS","Failed to load proposal voters. Please refresh the page.":"Failed to load proposal voters. Please refresh the page.","Faucet":"Faucet","Faucet {0}":["Faucet ",["0"]],"Fetching data...":"Fetching data...","Filter":"Filter","Fixed":"Fixed","Fixed rate":"Fixed rate","Flashloan is disabled for this asset, hence this position cannot be migrated.":"Flashloan is disabled for this asset, hence this position cannot be migrated.","For repayment of a specific type of debt, the user needs to have debt that type":"For repayment of a specific type of debt, the user needs to have debt that type","Forum discussion":"Forum discussion","French":"French","Funds in the Safety Module":"Funds in the Safety Module","GHO is a native decentralized, collateral-backed digital asset pegged to USD. It is created by users via borrowing against multiple collateral. When user repays their GHO borrow position, the protocol burns that user's GHO. All the interest payments accrued by minters of GHO would be directly transferred to the AaveDAO treasury.":"GHO is a native decentralized, collateral-backed digital asset pegged to USD. It is created by users via borrowing against multiple collateral. When user repays their GHO borrow position, the protocol burns that user's GHO. All the interest payments accrued by minters of GHO would be directly transferred to the AaveDAO treasury.","Get ABP Token":"Get ABP Token","Global settings":"Global settings","Go Back":"Go Back","Go to Balancer Pool":"Go to Balancer Pool","Go to V3 Dashboard":"Go to V3 Dashboard","Governance":"Governance","Greek":"Greek","Health Factor ({0} v2)":["Health Factor (",["0"]," v2)"],"Health Factor ({0} v3)":["Health Factor (",["0"]," v3)"],"Health factor":"Health factor","Health factor is lesser than the liquidation threshold":"Health factor is lesser than the liquidation threshold","Health factor is not below the threshold":"Health factor is not below the threshold","Hide":"Hide","Holders of stkAAVE receive a discount on the GHO borrowing rate":"Holders of stkAAVE receive a discount on the GHO borrowing rate","I acknowledge the risks involved.":"I acknowledge the risks involved.","I fully understand the risks of migrating.":"I fully understand the risks of migrating.","I understand how cooldown ({0}) and unstaking ({1}) work":["I understand how cooldown (",["0"],") and unstaking (",["1"],") work"],"If the error continues to happen,<0/> you may report it to this":"If the error continues to happen,<0/> you may report it to this","If the health factor goes below 1, the liquidation of your collateral might be triggered.":"If the health factor goes below 1, the liquidation of your collateral might be triggered.","If you DO NOT unstake within {0} of unstake window, you will need to activate cooldown process again.":["If you DO NOT unstake within ",["0"]," of unstake window, you will need to activate cooldown process again."],"If your loan to value goes above the liquidation threshold your collateral supplied may be liquidated.":"If your loan to value goes above the liquidation threshold your collateral supplied may be liquidated.","In E-Mode some assets are not borrowable. Exit E-Mode to get access to all assets":"In E-Mode some assets are not borrowable. Exit E-Mode to get access to all assets","In Isolation mode, you cannot supply other assets as collateral. A global debt ceiling limits the borrowing power of the isolated asset. To exit isolation mode disable {0} as collateral before borrowing another asset. Read more in our <0>FAQ":["In Isolation mode, you cannot supply other assets as collateral. A global debt ceiling limits the borrowing power of the isolated asset. To exit isolation mode disable ",["0"]," as collateral before borrowing another asset. Read more in our <0>FAQ"],"Inconsistent flashloan parameters":"Inconsistent flashloan parameters","Insufficient collateral to cover new borrow position. Wallet must have borrowing power remaining to perform debt switch.":"Insufficient collateral to cover new borrow position. Wallet must have borrowing power remaining to perform debt switch.","Interest accrued":"Interest accrued","Interest rate rebalance conditions were not met":"Interest rate rebalance conditions were not met","Interest rate strategy":"Interest rate strategy","Invalid amount to burn":"Invalid amount to burn","Invalid amount to mint":"Invalid amount to mint","Invalid bridge protocol fee":"Invalid bridge protocol fee","Invalid expiration":"Invalid expiration","Invalid flashloan premium":"Invalid flashloan premium","Invalid return value of the flashloan executor function":"Invalid return value of the flashloan executor function","Invalid signature":"Invalid signature","Isolated":"Isolated","Isolated Debt Ceiling":"Isolated Debt Ceiling","Isolated assets have limited borrowing power and other assets cannot be used as collateral.":"Isolated assets have limited borrowing power and other assets cannot be used as collateral.","Join the community discussion":"Join the community discussion","LEARN MORE":"LEARN MORE","Language":"Language","Learn more":"Learn more","Learn more about risks involved":"Learn more about risks involved","Learn more in our <0>FAQ guide":"Learn more in our <0>FAQ guide","Learn more.":"Learn more.","Links":"Links","Liqudation":"Liqudation","Liquidated collateral":"Liquidated collateral","Liquidation":"Liquidation","Liquidation <0/> threshold":"Liquidation <0/> threshold","Liquidation Threshold":"Liquidation Threshold","Liquidation at":"Liquidation at","Liquidation penalty":"Liquidation penalty","Liquidation risk":"Liquidation risk","Liquidation risk parameters":"Liquidation risk parameters","Liquidation threshold":"Liquidation threshold","Liquidation value":"Liquidation value","Loading data...":"Loading data...","Ltv validation failed":"Ltv validation failed","MAI has been paused due to a community decision. Supply, borrows and repays are impacted. <0>More details":"MAI has been paused due to a community decision. Supply, borrows and repays are impacted. <0>More details","MAX":"MAX","Manage analytics":"Manage analytics","Market":"Market","Markets":"Markets","Max":"Max","Max LTV":"Max LTV","Max slashing":"Max slashing","Max slippage":"Max slippage","Maximum amount available to borrow against this asset is limited because debt ceiling is at {0}%.":["Maximum amount available to borrow against this asset is limited because debt ceiling is at ",["0"],"%."],"Maximum amount available to borrow is <0/> {0} (<1/>).":["Maximum amount available to borrow is <0/> ",["0"]," (<1/>)."],"Maximum amount available to borrow is limited because protocol borrow cap is nearly reached.":"Maximum amount available to borrow is limited because protocol borrow cap is nearly reached.","Maximum amount available to supply is <0/> {0} (<1/>).":["Maximum amount available to supply is <0/> ",["0"]," (<1/>)."],"Maximum amount available to supply is limited because protocol supply cap is at {0}%.":["Maximum amount available to supply is limited because protocol supply cap is at ",["0"],"%."],"Maximum loan to value":"Maximum loan to value","Meet GHO":"Meet GHO","Menu":"Menu","Migrate":"Migrate","Migrate to V3":"Migrate to V3","Migrate to v3":"Migrate to v3","Migrate to {0} v3 Market":["Migrate to ",["0"]," v3 Market"],"Migrated":"Migrated","Migrating":"Migrating","Migrating multiple collaterals and borrowed assets at the same time can be an expensive operation and might fail in certain situations.<0>Therefore it’s not recommended to migrate positions with more than 5 assets (deposited + borrowed) at the same time.":"Migrating multiple collaterals and borrowed assets at the same time can be an expensive operation and might fail in certain situations.<0>Therefore it’s not recommended to migrate positions with more than 5 assets (deposited + borrowed) at the same time.","Migration risks":"Migration risks","Minimum GHO borrow amount":"Minimum GHO borrow amount","Minimum USD value received":"Minimum USD value received","Minimum staked Aave amount":"Minimum staked Aave amount","Minimum {0} received":["Minimum ",["0"]," received"],"More":"More","NAY":"NAY","Need help connecting a wallet? <0>Read our FAQ":"Need help connecting a wallet? <0>Read our FAQ","Net APR":"Net APR","Net APY":"Net APY","Net APY is the combined effect of all supply and borrow positions on net worth, including incentives. It is possible to have a negative net APY if debt APY is higher than supply APY.":"Net APY is the combined effect of all supply and borrow positions on net worth, including incentives. It is possible to have a negative net APY if debt APY is higher than supply APY.","Net worth":"Net worth","Network":"Network","Network not supported for this wallet":"Network not supported for this wallet","New APY":"New APY","No assets selected to migrate.":"No assets selected to migrate.","No rewards to claim":"No rewards to claim","No search results{0}":["No search results",["0"]],"No transactions yet.":"No transactions yet.","No voting power":"No voting power","None":"None","Not a valid address":"Not a valid address","Not enough balance on your wallet":"Not enough balance on your wallet","Not enough collateral to repay this amount of debt with":"Not enough collateral to repay this amount of debt with","Not enough staked balance":"Not enough staked balance","Not enough voting power to participate in this proposal":"Not enough voting power to participate in this proposal","Not reached":"Not reached","Nothing borrowed yet":"Nothing borrowed yet","Nothing found":"Nothing found","Nothing staked":"Nothing staked","Nothing supplied yet":"Nothing supplied yet","Notify":"Notify","Ok, Close":"Ok, Close","Ok, I got it":"Ok, I got it","Operation not supported":"Operation not supported","Oracle price":"Oracle price","Overview":"Overview","Page not found":"Page not found","Participating in this {symbol} reserve gives annualized rewards.":["Participating in this ",["symbol"]," reserve gives annualized rewards."],"Pending...":"Pending...","Per the community, the Fantom market has been frozen.":"Per the community, the Fantom market has been frozen.","Per the community, the V2 AMM market has been deprecated.":"Per the community, the V2 AMM market has been deprecated.","Please always be aware of your <0>Health Factor (HF) when partially migrating a position and that your rates will be updated to V3 rates.":"Please always be aware of your <0>Health Factor (HF) when partially migrating a position and that your rates will be updated to V3 rates.","Please connect a wallet to view your personal information here.":"Please connect a wallet to view your personal information here.","Please connect your wallet to be able to switch your tokens.":"Please connect your wallet to be able to switch your tokens.","Please connect your wallet to get free testnet assets.":"Please connect your wallet to get free testnet assets.","Please connect your wallet to see migration tool.":"Please connect your wallet to see migration tool.","Please connect your wallet to see your supplies, borrowings, and open positions.":"Please connect your wallet to see your supplies, borrowings, and open positions.","Please connect your wallet to view transaction history.":"Please connect your wallet to view transaction history.","Please enter a valid wallet address.":"Please enter a valid wallet address.","Please switch to {networkName}.":["Please switch to ",["networkName"],"."],"Please, connect your wallet":"Please, connect your wallet","Pool addresses provider is not registered":"Pool addresses provider is not registered","Powered by":"Powered by","Preview tx and migrate":"Preview tx and migrate","Price":"Price","Price data is not currently available for this reserve on the protocol subgraph":"Price data is not currently available for this reserve on the protocol subgraph","Price impact":"Price impact","Price impact is the spread between the total value of the entry tokens switched and the destination tokens obtained (in USD), which results from the limited liquidity of the trading pair.":"Price impact is the spread between the total value of the entry tokens switched and the destination tokens obtained (in USD), which results from the limited liquidity of the trading pair.","Price impact {0}%":["Price impact ",["0"],"%"],"Privacy":"Privacy","Proposal details":"Proposal details","Proposal overview":"Proposal overview","Proposals":"Proposals","Proposition":"Proposition","Protocol borrow cap at 100% for this asset. Further borrowing unavailable.":"Protocol borrow cap at 100% for this asset. Further borrowing unavailable.","Protocol borrow cap is at 100% for this asset. Further borrowing unavailable.":"Protocol borrow cap is at 100% for this asset. Further borrowing unavailable.","Protocol debt ceiling is at 100% for this asset. Further borrowing against this asset is unavailable.":"Protocol debt ceiling is at 100% for this asset. Further borrowing against this asset is unavailable.","Protocol debt ceiling is at 100% for this asset. Futher borrowing against this asset is unavailable.":"Protocol debt ceiling is at 100% for this asset. Futher borrowing against this asset is unavailable.","Protocol supply cap at 100% for this asset. Further supply unavailable.":"Protocol supply cap at 100% for this asset. Further supply unavailable.","Protocol supply cap is at 100% for this asset. Further supply unavailable.":"Protocol supply cap is at 100% for this asset. Further supply unavailable.","Quorum":"Quorum","Rate change":"Rate change","Raw-Ipfs":"Raw-Ipfs","Reached":"Reached","Reactivate cooldown period to unstake {0} {stakedToken}":["Reactivate cooldown period to unstake ",["0"]," ",["stakedToken"]],"Read more here.":"Read more here.","Read-only mode allows to see address positions in Aave, but you won't be able to perform transactions.":"Read-only mode allows to see address positions in Aave, but you won't be able to perform transactions.","Read-only mode.":"Read-only mode.","Read-only mode. Connect to a wallet to perform transactions.":"Read-only mode. Connect to a wallet to perform transactions.","Receive (est.)":"Receive (est.)","Received":"Received","Recipient address":"Recipient address","Rejected connection request":"Rejected connection request","Reload":"Reload","Reload the page":"Reload the page","Remaining debt":"Remaining debt","Remaining supply":"Remaining supply","Repaid":"Repaid","Repay":"Repay","Repay with":"Repay with","Repay {symbol}":["Repay ",["symbol"]],"Repaying {symbol}":["Repaying ",["symbol"]],"Repayment amount to reach {0}% utilization":["Repayment amount to reach ",["0"],"% utilization"],"Reserve Size":"Reserve Size","Reserve factor":"Reserve factor","Reserve factor is a percentage of interest which goes to a {0} that is controlled by Aave governance to promote ecosystem growth.":["Reserve factor is a percentage of interest which goes to a ",["0"]," that is controlled by Aave governance to promote ecosystem growth."],"Reserve status & configuration":"Reserve status & configuration","Reset":"Reset","Restake":"Restake","Restake {symbol}":["Restake ",["symbol"]],"Restaked":"Restaked","Restaking {symbol}":["Restaking ",["symbol"]],"Review approval tx details":"Review approval tx details","Review changes to continue":"Review changes to continue","Review tx":"Review tx","Review tx details":"Review tx details","Revoke power":"Revoke power","Reward(s) to claim":"Reward(s) to claim","Rewards APR":"Rewards APR","Risk details":"Risk details","SEE CHARTS":"SEE CHARTS","Safety of your deposited collateral against the borrowed assets and its underlying value.":"Safety of your deposited collateral against the borrowed assets and its underlying value.","Save and share":"Save and share","Seatbelt report":"Seatbelt report","Seems like we can't switch the network automatically. Please check if you can change it from the wallet.":"Seems like we can't switch the network automatically. Please check if you can change it from the wallet.","Select":"Select","Select APY type to switch":"Select APY type to switch","Select an asset":"Select an asset","Select language":"Select language","Select slippage tolerance":"Select slippage tolerance","Select v2 borrows to migrate":"Select v2 borrows to migrate","Select v2 supplies to migrate":"Select v2 supplies to migrate","Selected assets have successfully migrated. Visit the Market Dashboard to see them.":"Selected assets have successfully migrated. Visit the Market Dashboard to see them.","Selected borrow assets":"Selected borrow assets","Selected supply assets":"Selected supply assets","Send feedback":"Send feedback","Set up delegation":"Set up delegation","Setup notifications about your Health Factor using the Hal app.":"Setup notifications about your Health Factor using the Hal app.","Share on Lens":"Share on Lens","Share on twitter":"Share on twitter","Show":"Show","Show Frozen or paused assets":"Show Frozen or paused assets","Show assets with 0 balance":"Show assets with 0 balance","Sign to continue":"Sign to continue","Signatures ready":"Signatures ready","Signing":"Signing","Since this asset is frozen, the only available actions are withdraw and repay which can be accessed from the <0>Dashboard":"Since this asset is frozen, the only available actions are withdraw and repay which can be accessed from the <0>Dashboard","Since this is a test network, you can get any of the assets if you have ETH on your wallet":"Since this is a test network, you can get any of the assets if you have ETH on your wallet","Slippage":"Slippage","Slippage is the difference between the quoted and received amounts from changing market conditions between the moment the transaction is submitted and its verification.":"Slippage is the difference between the quoted and received amounts from changing market conditions between the moment the transaction is submitted and its verification.","Some migrated assets will not be used as collateral due to enabled isolation mode in {marketName} V3 Market. Visit <0>{marketName} V3 Dashboard to manage isolation mode.":["Some migrated assets will not be used as collateral due to enabled isolation mode in ",["marketName"]," V3 Market. Visit <0>",["marketName"]," V3 Dashboard to manage isolation mode."],"Something went wrong":"Something went wrong","Sorry, an unexpected error happened. In the meantime you may try reloading the page, or come back later.":"Sorry, an unexpected error happened. In the meantime you may try reloading the page, or come back later.","Sorry, we couldn't find the page you were looking for.":"Sorry, we couldn't find the page you were looking for.","Spanish":"Spanish","Stable":"Stable","Stable Interest Type is disabled for this currency":"Stable Interest Type is disabled for this currency","Stable borrowing is enabled":"Stable borrowing is enabled","Stable borrowing is not enabled":"Stable borrowing is not enabled","Stable debt supply is not zero":"Stable debt supply is not zero","Stable interest rate will <0>stay the same for the duration of your loan. Recommended for long-term loan periods and for users who prefer predictability.":"Stable interest rate will <0>stay the same for the duration of your loan. Recommended for long-term loan periods and for users who prefer predictability.","Stablecoin":"Stablecoin","Stake":"Stake","Stake AAVE":"Stake AAVE","Stake ABPT":"Stake ABPT","Stake cooldown activated":"Stake cooldown activated","Staked":"Staked","Staking":"Staking","Staking APR":"Staking APR","Staking Rewards":"Staking Rewards","Staking balance":"Staking balance","Staking discount":"Staking discount","Started":"Started","State":"State","Static interest rate that is determined by Aave Governance. This rate may be changed over time depending on the need for the GHO supply to contract/expand. <0>Learn more":"Static interest rate that is determined by Aave Governance. This rate may be changed over time depending on the need for the GHO supply to contract/expand. <0>Learn more","Supplied":"Supplied","Supplied asset amount":"Supplied asset amount","Supply":"Supply","Supply APY":"Supply APY","Supply apy":"Supply apy","Supply balance":"Supply balance","Supply balance after switch":"Supply balance after switch","Supply cap is exceeded":"Supply cap is exceeded","Supply cap on target reserve reached. Try lowering the amount.":"Supply cap on target reserve reached. Try lowering the amount.","Supply {symbol}":["Supply ",["symbol"]],"Supplying your":"Supplying your","Supplying {symbol}":["Supplying ",["symbol"]],"Switch":"Switch","Switch APY type":"Switch APY type","Switch E-Mode":"Switch E-Mode","Switch E-Mode category":"Switch E-Mode category","Switch Network":"Switch Network","Switch borrow position":"Switch borrow position","Switch rate":"Switch rate","Switch to":"Switch to","Switched":"Switched","Switching":"Switching","Switching E-Mode":"Switching E-Mode","Switching rate":"Switching rate","Techpaper":"Techpaper","Terms":"Terms","Test Assets":"Test Assets","Testnet mode":"Testnet mode","Testnet mode is ON":"Testnet mode is ON","Thank you for voting!!":"Thank you for voting!!","The % of your total borrowing power used. This is based on the amount of your collateral supplied and the total amount that you can borrow.":"The % of your total borrowing power used. This is based on the amount of your collateral supplied and the total amount that you can borrow.","The Aave Balancer Pool Token (ABPT) is a liquidity pool token. You can receive ABPT by depositing a combination of AAVE + ETH in the Balancer liquidity pool. You can then stake your BPT in the Safety Module to secure the protocol and earn Safety Incentives.":"The Aave Balancer Pool Token (ABPT) is a liquidity pool token. You can receive ABPT by depositing a combination of AAVE + ETH in the Balancer liquidity pool. You can then stake your BPT in the Safety Module to secure the protocol and earn Safety Incentives.","The Aave Protocol is programmed to always use the price of 1 GHO = $1. This is different from using market pricing via oracles for other crypto assets. This creates stabilizing arbitrage opportunities when the price of GHO fluctuates.":"The Aave Protocol is programmed to always use the price of 1 GHO = $1. This is different from using market pricing via oracles for other crypto assets. This creates stabilizing arbitrage opportunities when the price of GHO fluctuates.","The Maximum LTV ratio represents the maximum borrowing power of a specific collateral. For example, if a collateral has an LTV of 75%, the user can borrow up to 0.75 worth of ETH in the principal currency for every 1 ETH worth of collateral.":"The Maximum LTV ratio represents the maximum borrowing power of a specific collateral. For example, if a collateral has an LTV of 75%, the user can borrow up to 0.75 worth of ETH in the principal currency for every 1 ETH worth of collateral.","The Stable Rate is not enabled for this currency":"The Stable Rate is not enabled for this currency","The address of the pool addresses provider is invalid":"The address of the pool addresses provider is invalid","The app is running in testnet mode. Learn how it works in":"The app is running in testnet mode. Learn how it works in","The caller of the function is not an AToken":"The caller of the function is not an AToken","The caller of this function must be a pool":"The caller of this function must be a pool","The collateral balance is 0":"The collateral balance is 0","The collateral chosen cannot be liquidated":"The collateral chosen cannot be liquidated","The cooldown period is the time required prior to unstaking your tokens (20 days). You can only withdraw your assets from the Security Module after the cooldown period and within the unstake window.<0>Learn more":"The cooldown period is the time required prior to unstaking your tokens (20 days). You can only withdraw your assets from the Security Module after the cooldown period and within the unstake window.<0>Learn more","The cooldown period is {0}. After {1} of cooldown, you will enter unstake window of {2}. You will continue receiving rewards during cooldown and unstake window.":["The cooldown period is ",["0"],". After ",["1"]," of cooldown, you will enter unstake window of ",["2"],". You will continue receiving rewards during cooldown and unstake window."],"The effects on the health factor would cause liquidation. Try lowering the amount.":"The effects on the health factor would cause liquidation. Try lowering the amount.","The loan to value of the migrated positions would cause liquidation. Increase migrated collateral or reduce migrated borrow to continue.":"The loan to value of the migrated positions would cause liquidation. Increase migrated collateral or reduce migrated borrow to continue.","The requested amount is greater than the max loan size in stable rate mode":"The requested amount is greater than the max loan size in stable rate mode","The total amount of your assets denominated in USD that can be used as collateral for borrowing assets.":"The total amount of your assets denominated in USD that can be used as collateral for borrowing assets.","The underlying asset cannot be rescued":"The underlying asset cannot be rescued","The underlying balance needs to be greater than 0":"The underlying balance needs to be greater than 0","The weighted average of APY for all borrowed assets, including incentives.":"The weighted average of APY for all borrowed assets, including incentives.","The weighted average of APY for all supplied assets, including incentives.":"The weighted average of APY for all supplied assets, including incentives.","There are not enough funds in the{0}reserve to borrow":["There are not enough funds in the",["0"],"reserve to borrow"],"There is not enough collateral to cover a new borrow":"There is not enough collateral to cover a new borrow","There is not enough liquidity for the target asset to perform the switch. Try lowering the amount.":"There is not enough liquidity for the target asset to perform the switch. Try lowering the amount.","There was some error. Please try changing the parameters or <0><1>copy the error":"There was some error. Please try changing the parameters or <0><1>copy the error","These assets are temporarily frozen or paused by Aave community decisions, meaning that further supply / borrow, or rate swap of these assets are unavailable. Withdrawals and debt repayments are allowed. Follow the <0>Aave governance forum for further updates.":"These assets are temporarily frozen or paused by Aave community decisions, meaning that further supply / borrow, or rate swap of these assets are unavailable. Withdrawals and debt repayments are allowed. Follow the <0>Aave governance forum for further updates.","These funds have been borrowed and are not available for withdrawal at this time.":"These funds have been borrowed and are not available for withdrawal at this time.","This action will reduce V2 health factor below liquidation threshold. retain collateral or migrate borrow position to continue.":"This action will reduce V2 health factor below liquidation threshold. retain collateral or migrate borrow position to continue.","This action will reduce health factor of V3 below liquidation threshold. Increase migrated collateral or reduce migrated borrow to continue.":"This action will reduce health factor of V3 below liquidation threshold. Increase migrated collateral or reduce migrated borrow to continue.","This action will reduce your health factor. Please be mindful of the increased risk of collateral liquidation.":"This action will reduce your health factor. Please be mindful of the increased risk of collateral liquidation.","This address is blocked on app.aave.com because it is associated with one or more":"This address is blocked on app.aave.com because it is associated with one or more","This asset has almost reached its borrow cap. There is only {messageValue} available to be borrowed from this market.":["This asset has almost reached its borrow cap. There is only ",["messageValue"]," available to be borrowed from this market."],"This asset has almost reached its supply cap. There can only be {messageValue} supplied to this market.":["This asset has almost reached its supply cap. There can only be ",["messageValue"]," supplied to this market."],"This asset has reached its borrow cap. Nothing is available to be borrowed from this market.":"This asset has reached its borrow cap. Nothing is available to be borrowed from this market.","This asset has reached its supply cap. Nothing is available to be supplied from this market.":"This asset has reached its supply cap. Nothing is available to be supplied from this market.","This asset is frozen due to an Aave Protocol Governance decision. <0>More details":"This asset is frozen due to an Aave Protocol Governance decision. <0>More details","This asset is frozen due to an Aave Protocol Governance decision. On the 20th of December 2022, renFIL will no longer be supported and cannot be bridged back to its native network. It is recommended to withdraw supply positions and repay borrow positions so that renFIL can be bridged back to FIL before the deadline. After this date, it will no longer be possible to convert renFIL to FIL. <0>More details":"This asset is frozen due to an Aave Protocol Governance decision. On the 20th of December 2022, renFIL will no longer be supported and cannot be bridged back to its native network. It is recommended to withdraw supply positions and repay borrow positions so that renFIL can be bridged back to FIL before the deadline. After this date, it will no longer be possible to convert renFIL to FIL. <0>More details","This asset is frozen due to an Aave community decision. <0>More details":"This asset is frozen due to an Aave community decision. <0>More details","This asset is planned to be offboarded due to an Aave Protocol Governance decision. <0>More details":"This asset is planned to be offboarded due to an Aave Protocol Governance decision. <0>More details","This gas calculation is only an estimation. Your wallet will set the price of the transaction. You can modify the gas settings directly from your wallet provider.":"This gas calculation is only an estimation. Your wallet will set the price of the transaction. You can modify the gas settings directly from your wallet provider.","This integration was<0>proposed and approvedby the community.":"This integration was<0>proposed and approvedby the community.","This is the total amount available for you to borrow. You can borrow based on your collateral and until the borrow cap is reached.":"This is the total amount available for you to borrow. You can borrow based on your collateral and until the borrow cap is reached.","This is the total amount that you are able to supply to in this reserve. You are able to supply your wallet balance up until the supply cap is reached.":"This is the total amount that you are able to supply to in this reserve. You are able to supply your wallet balance up until the supply cap is reached.","This represents the threshold at which a borrow position will be considered undercollateralized and subject to liquidation for each collateral. For example, if a collateral has a liquidation threshold of 80%, it means that the position will be liquidated when the debt value is worth 80% of the collateral value.":"This represents the threshold at which a borrow position will be considered undercollateralized and subject to liquidation for each collateral. For example, if a collateral has a liquidation threshold of 80%, it means that the position will be liquidated when the debt value is worth 80% of the collateral value.","Time left to be able to withdraw your staked asset.":"Time left to be able to withdraw your staked asset.","Time left to unstake":"Time left to unstake","Time left until the withdrawal window closes.":"Time left until the withdrawal window closes.","Tip: Try increasing slippage or reduce input amount":"Tip: Try increasing slippage or reduce input amount","To borrow you need to supply any asset to be used as collateral.":"To borrow you need to supply any asset to be used as collateral.","To continue, you need to grant Aave smart contracts permission to move your funds from your wallet. Depending on the asset and wallet you use, it is done by signing the permission message (gas free), or by submitting an approval transaction (requires gas). <0>Learn more":"To continue, you need to grant Aave smart contracts permission to move your funds from your wallet. Depending on the asset and wallet you use, it is done by signing the permission message (gas free), or by submitting an approval transaction (requires gas). <0>Learn more","To enable E-mode for the {0} category, all borrow positions outside of this category must be closed.":["To enable E-mode for the ",["0"]," category, all borrow positions outside of this category must be closed."],"To repay on behalf of a user an explicit amount to repay is needed":"To repay on behalf of a user an explicit amount to repay is needed","To request access for this permissioned market, please visit: <0>Acces Provider Name":"To request access for this permissioned market, please visit: <0>Acces Provider Name","To submit a proposal for minor changes to the protocol, you'll need at least 80.00K power. If you want to change the core code base, you'll need 320k power.<0>Learn more.":"To submit a proposal for minor changes to the protocol, you'll need at least 80.00K power. If you want to change the core code base, you'll need 320k power.<0>Learn more.","Top 10 addresses":"Top 10 addresses","Total available":"Total available","Total borrowed":"Total borrowed","Total borrows":"Total borrows","Total emission per day":"Total emission per day","Total interest accrued":"Total interest accrued","Total market size":"Total market size","Total supplied":"Total supplied","Total voting power":"Total voting power","Total worth":"Total worth","Track wallet":"Track wallet","Track wallet balance in read-only mode":"Track wallet balance in read-only mode","Transaction failed":"Transaction failed","Transaction history":"Transaction history","Transaction history is not currently available for this market":"Transaction history is not currently available for this market","Transaction overview":"Transaction overview","Transactions":"Transactions","UNSTAKE {symbol}":["UNSTAKE ",["symbol"]],"Unavailable":"Unavailable","Unbacked":"Unbacked","Unbacked mint cap is exceeded":"Unbacked mint cap is exceeded","Underlying asset does not exist in {marketName} v3 Market, hence this position cannot be migrated.":["Underlying asset does not exist in ",["marketName"]," v3 Market, hence this position cannot be migrated."],"Underlying token":"Underlying token","Unstake now":"Unstake now","Unstake window":"Unstake window","Unstaked":"Unstaked","Unstaking {symbol}":["Unstaking ",["symbol"]],"Update: Disruptions reported for WETH, WBTC, WMATIC, and USDT. AIP 230 will resolve the disruptions and the market will be operating as normal on ~26th May 13h00 UTC.":"Update: Disruptions reported for WETH, WBTC, WMATIC, and USDT. AIP 230 will resolve the disruptions and the market will be operating as normal on ~26th May 13h00 UTC.","Use it to vote for or against active proposals.":"Use it to vote for or against active proposals.","Use your AAVE and stkAAVE balance to delegate your voting and proposition powers. You will not be sending any tokens, only the rights to vote and propose changes to the protocol. You can re-delegate or revoke power to self at any time.":"Use your AAVE and stkAAVE balance to delegate your voting and proposition powers. You will not be sending any tokens, only the rights to vote and propose changes to the protocol. You can re-delegate or revoke power to self at any time.","Used as collateral":"Used as collateral","User cannot withdraw more than the available balance":"User cannot withdraw more than the available balance","User did not borrow the specified currency":"User did not borrow the specified currency","User does not have outstanding stable rate debt on this reserve":"User does not have outstanding stable rate debt on this reserve","User does not have outstanding variable rate debt on this reserve":"User does not have outstanding variable rate debt on this reserve","User is in isolation mode":"User is in isolation mode","User is trying to borrow multiple assets including a siloed one":"User is trying to borrow multiple assets including a siloed one","Users who stake AAVE in Safety Module (i.e. stkAAVE holders) receive a discount on GHO borrow interest rate. The discount applies to 100 GHO for every 1 stkAAVE held. Use the calculator below to see GHO borrow rate with the discount applied.":"Users who stake AAVE in Safety Module (i.e. stkAAVE holders) receive a discount on GHO borrow interest rate. The discount applies to 100 GHO for every 1 stkAAVE held. Use the calculator below to see GHO borrow rate with the discount applied.","Utilization Rate":"Utilization Rate","VIEW TX":"VIEW TX","VOTE NAY":"VOTE NAY","VOTE YAE":"VOTE YAE","Variable":"Variable","Variable debt supply is not zero":"Variable debt supply is not zero","Variable interest rate will <0>fluctuate based on the market conditions. Recommended for short-term positions.":"Variable interest rate will <0>fluctuate based on the market conditions. Recommended for short-term positions.","Variable rate":"Variable rate","Version 2":"Version 2","Version 3":"Version 3","View":"View","View Transactions":"View Transactions","View all votes":"View all votes","View contract":"View contract","View details":"View details","View on Explorer":"View on Explorer","Vote NAY":"Vote NAY","Vote YAE":"Vote YAE","Voted NAY":"Voted NAY","Voted YAE":"Voted YAE","Votes":"Votes","Voting":"Voting","Voting power":"Voting power","Voting results":"Voting results","Wallet Balance":"Wallet Balance","Wallet balance":"Wallet balance","Wallet not detected. Connect or install wallet and retry":"Wallet not detected. Connect or install wallet and retry","Wallets are provided by External Providers and by selecting you agree to Terms of those Providers. Your access to the wallet might be reliant on the External Provider being operational.":"Wallets are provided by External Providers and by selecting you agree to Terms of those Providers. Your access to the wallet might be reliant on the External Provider being operational.","We couldn't find any assets related to your search. Try again with a different asset name, symbol, or address.":"We couldn't find any assets related to your search. Try again with a different asset name, symbol, or address.","We couldn't find any transactions related to your search. Try again with a different asset name, or reset filters.":"We couldn't find any transactions related to your search. Try again with a different asset name, or reset filters.","We couldn’t detect a wallet. Connect a wallet to stake and view your balance.":"We couldn’t detect a wallet. Connect a wallet to stake and view your balance.","We suggest you go back to the Dashboard.":"We suggest you go back to the Dashboard.","Website":"Website","When a liquidation occurs, liquidators repay up to 50% of the outstanding borrowed amount on behalf of the borrower. In return, they can buy the collateral at a discount and keep the difference (liquidation penalty) as a bonus.":"When a liquidation occurs, liquidators repay up to 50% of the outstanding borrowed amount on behalf of the borrower. In return, they can buy the collateral at a discount and keep the difference (liquidation penalty) as a bonus.","With a voting power of <0/>":"With a voting power of <0/>","With testnet Faucet you can get free assets to test the Aave Protocol. Make sure to switch your wallet provider to the appropriate testnet network, select desired asset, and click ‘Faucet’ to get tokens transferred to your wallet. The assets on a testnet are not “real,” meaning they have no monetary value. <0>Learn more":"With testnet Faucet you can get free assets to test the Aave Protocol. Make sure to switch your wallet provider to the appropriate testnet network, select desired asset, and click ‘Faucet’ to get tokens transferred to your wallet. The assets on a testnet are not “real,” meaning they have no monetary value. <0>Learn more","Withdraw":"Withdraw","Withdraw & Switch":"Withdraw & Switch","Withdraw and Switch":"Withdraw and Switch","Withdraw {symbol}":["Withdraw ",["symbol"]],"Withdrawing and Switching":"Withdrawing and Switching","Withdrawing this amount will reduce your health factor and increase risk of liquidation.":"Withdrawing this amount will reduce your health factor and increase risk of liquidation.","Withdrawing {symbol}":["Withdrawing ",["symbol"]],"Wrong Network":"Wrong Network","YAE":"YAE","You are entering Isolation mode":"You are entering Isolation mode","You can borrow this asset with a stable rate only if you borrow more than the amount you are supplying as collateral.":"You can borrow this asset with a stable rate only if you borrow more than the amount you are supplying as collateral.","You can not change Interest Type to stable as your borrowings are higher than your collateral":"You can not change Interest Type to stable as your borrowings are higher than your collateral","You can not disable E-Mode as your current collateralization level is above 80%, disabling E-Mode can cause liquidation. To exit E-Mode supply or repay borrowed positions.":"You can not disable E-Mode as your current collateralization level is above 80%, disabling E-Mode can cause liquidation. To exit E-Mode supply or repay borrowed positions.","You can not switch usage as collateral mode for this currency, because it will cause collateral call":"You can not switch usage as collateral mode for this currency, because it will cause collateral call","You can not use this currency as collateral":"You can not use this currency as collateral","You can not withdraw this amount because it will cause collateral call":"You can not withdraw this amount because it will cause collateral call","You can only switch to tokens with variable APY types. After this transaction, you may change the variable rate to a stable one if available.":"You can only switch to tokens with variable APY types. After this transaction, you may change the variable rate to a stable one if available.","You can only withdraw your assets from the Security Module after the cooldown period ends and the unstake window is active.":"You can only withdraw your assets from the Security Module after the cooldown period ends and the unstake window is active.","You can report incident to our <0>Discord or<1>Github.":"You can report incident to our <0>Discord or<1>Github.","You cancelled the transaction.":"You cancelled the transaction.","You did not participate in this proposal":"You did not participate in this proposal","You do not have supplies in this currency":"You do not have supplies in this currency","You don’t have enough funds in your wallet to repay the full amount. If you proceed to repay with your current amount of funds, you will still have a small borrowing position in your dashboard.":"You don’t have enough funds in your wallet to repay the full amount. If you proceed to repay with your current amount of funds, you will still have a small borrowing position in your dashboard.","You have no AAVE/stkAAVE balance to delegate.":"You have no AAVE/stkAAVE balance to delegate.","You have not borrow yet using this currency":"You have not borrow yet using this currency","You may borrow up to <0/> GHO at <1/> (max discount)":"You may borrow up to <0/> GHO at <1/> (max discount)","You may enter a custom amount in the field.":"You may enter a custom amount in the field.","You switched to {0} rate":["You switched to ",["0"]," rate"],"You unstake here":"You unstake here","You voted {0}":["You voted ",["0"]],"You will exit isolation mode and other tokens can now be used as collateral":"You will exit isolation mode and other tokens can now be used as collateral","You {action} <0/> {symbol}":["You ",["action"]," <0/> ",["symbol"]],"You've successfully switched borrow position.":"You've successfully switched borrow position.","You've successfully switched tokens.":"You've successfully switched tokens.","You've successfully withdrew & switched tokens.":"You've successfully withdrew & switched tokens.","Your balance is lower than the selected amount.":"Your balance is lower than the selected amount.","Your borrows":"Your borrows","Your current loan to value based on your collateral supplied.":"Your current loan to value based on your collateral supplied.","Your health factor and loan to value determine the assurance of your collateral. To avoid liquidations you can supply more collateral or repay borrow positions.":"Your health factor and loan to value determine the assurance of your collateral. To avoid liquidations you can supply more collateral or repay borrow positions.","Your info":"Your info","Your proposition power is based on your AAVE/stkAAVE balance and received delegations.":"Your proposition power is based on your AAVE/stkAAVE balance and received delegations.","Your reward balance is 0":"Your reward balance is 0","Your supplies":"Your supplies","Your voting info":"Your voting info","Your voting power is based on your AAVE/stkAAVE balance and received delegations.":"Your voting power is based on your AAVE/stkAAVE balance and received delegations.","Your {name} wallet is empty. Purchase or transfer assets or use <0>{0} to transfer your {network} assets.":["Your ",["name"]," wallet is empty. Purchase or transfer assets or use <0>",["0"]," to transfer your ",["network"]," assets."],"Your {name} wallet is empty. Purchase or transfer assets.":["Your ",["name"]," wallet is empty. Purchase or transfer assets."],"Your {networkName} wallet is empty. Get free test assets at":["Your ",["networkName"]," wallet is empty. Get free test assets at"],"Your {networkName} wallet is empty. Get free test {0} at":["Your ",["networkName"]," wallet is empty. Get free test ",["0"]," at"],"Zero address not valid":"Zero address not valid","assets":"assets","blocked activities":"blocked activities","copy the error":"copy the error","disabled":"disabled","documentation":"documentation","enabled":"enabled","ends":"ends","for":"for","of":"of","on":"on","please check that the amount you want to supply is not currently being used for staking. If it is being used for staking, your transaction might fail.":"please check that the amount you want to supply is not currently being used for staking. If it is being used for staking, your transaction might fail.","repaid":"repaid","stETH supplied as collateral will continue to accrue staking rewards provided by daily rebases.":"stETH supplied as collateral will continue to accrue staking rewards provided by daily rebases.","stETH tokens will be migrated to Wrapped stETH using Lido Protocol wrapper which leads to supply balance change after migration: {0}":["stETH tokens will be migrated to Wrapped stETH using Lido Protocol wrapper which leads to supply balance change after migration: ",["0"]],"staking view":"staking view","starts":"starts","stkAAVE holders get a discount on GHO borrow rate":"stkAAVE holders get a discount on GHO borrow rate","to":"to","tokens is not the same as staking them. If you wish to stake your":"tokens is not the same as staking them. If you wish to stake your","tokens, please go to the":"tokens, please go to the","withdrew":"withdrew","{0}":[["0"]],"{0} Balance":[["0"]," Balance"],"{0} Faucet":[["0"]," Faucet"],"{0} on-ramp service is provided by External Provider and by selecting you agree to Terms of the Provider. Your access to the service might be reliant on the External Provider being operational.":[["0"]," on-ramp service is provided by External Provider and by selecting you agree to Terms of the Provider. Your access to the service might be reliant on the External Provider being operational."],"{0}{name}":[["0"],["name"]],"{currentMethod}":[["currentMethod"]],"{d}d":[["d"],"d"],"{h}h":[["h"],"h"],"{m}m":[["m"],"m"],"{networkName} Faucet":[["networkName"]," Faucet"],"{notifyText}":[["notifyText"]],"{numSelected}/{numAvailable} assets selected":[["numSelected"],"/",["numAvailable"]," assets selected"],"{s}s":[["s"],"s"],"{title}":[["title"]],"{tooltipText}":[["tooltipText"]]}}; diff --git a/src/locales/en/messages.po b/src/locales/en/messages.po index be6f63b573..e31ddd777d 100644 --- a/src/locales/en/messages.po +++ b/src/locales/en/messages.po @@ -791,6 +791,11 @@ msgstr "Current v2 balance" msgid "Current votes" msgstr "Current votes" +#: src/components/transactions/Supply/SupplyModalContent.tsx +#: src/components/transactions/Withdraw/WithdrawModalContent.tsx +msgid "DAI balance will be converted via DSR contracts and then supplied as sDAI to Aave reserve. Switching incurs no additional costs and no slippage." +msgstr "DAI balance will be converted via DSR contracts and then supplied as sDAI to Aave reserve. Switching incurs no additional costs and no slippage." + #: src/layouts/components/DarkModeSwitcher.tsx msgid "Dark mode" msgstr "Dark mode" @@ -1270,10 +1275,12 @@ msgstr "Language" #: src/components/infoTooltips/DebtCeilingMaxedTooltip.tsx #: src/components/infoTooltips/SupplyCapMaxedTooltip.tsx #: src/components/transactions/StakeCooldown/StakeCooldownModalContent.tsx +#: src/components/transactions/Supply/SupplyModalContent.tsx #: src/components/transactions/Warnings/BorrowCapWarning.tsx #: src/components/transactions/Warnings/DebtCeilingWarning.tsx #: src/components/transactions/Warnings/MarketWarning.tsx #: src/components/transactions/Warnings/SupplyCapWarning.tsx +#: src/components/transactions/Withdraw/WithdrawModalContent.tsx #: src/layouts/TopBarNotify.tsx #: src/modules/dashboard/LiquidationRiskParametresModal/LiquidationRiskParametresModal.tsx #: src/modules/reserve-overview/BorrowInfo.tsx @@ -2224,6 +2231,7 @@ msgid "Supply cap on target reserve reached. Try lowering the amount." msgstr "Supply cap on target reserve reached. Try lowering the amount." #: src/components/transactions/Supply/SupplyActions.tsx +#: src/components/transactions/Supply/SupplyWrappedTokenActions.tsx msgid "Supply {symbol}" msgstr "Supply {symbol}" @@ -2232,6 +2240,7 @@ msgid "Supplying your" msgstr "Supplying your" #: src/components/transactions/Supply/SupplyActions.tsx +#: src/components/transactions/Supply/SupplyWrappedTokenActions.tsx msgid "Supplying {symbol}" msgstr "Supplying {symbol}" diff --git a/src/store/poolSlice.ts b/src/store/poolSlice.ts index 67c31e4316..c0a8abf184 100644 --- a/src/store/poolSlice.ts +++ b/src/store/poolSlice.ts @@ -23,6 +23,7 @@ import { PoolBundleInterface, ReserveDataHumanized, ReservesIncentiveDataHumanized, + SavingsDaiTokenWrapperService, UiIncentiveDataProvider, UiPoolDataProvider, UserReserveDataHumanized, @@ -41,6 +42,7 @@ import { LPSupplyParamsType, LPSupplyWithPermitType, } from '@aave/contract-helpers/dist/esm/v3-pool-contract/lendingPoolTypes'; +import { SignatureLike } from '@ethersproject/bytes'; import dayjs from 'dayjs'; import { BigNumber, PopulatedTransaction, Signature, utils } from 'ethers'; import { splitSignature } from 'ethers/lib/utils'; @@ -132,6 +134,15 @@ export interface PoolSlice { generateApproval: (args: ApproveType, opts?: GenerateApprovalOpts) => PopulatedTransaction; supply: (args: Omit) => PopulatedTransaction; supplyWithPermit: (args: Omit) => PopulatedTransaction; + getDaiForSavingsDai: (amount: string) => Promise; + getSavingsDaiForDai: (amount: string) => Promise; + supplyDaiAsSavingsDai: (amount: string) => PopulatedTransaction; + supplyDaiAsSavingsDaiWithPermit: ( + amount: string, + deadline: string, + signature: SignatureLike + ) => PopulatedTransaction; + getApprovedAmount: (args: { token: string }) => Promise; borrow: (args: Omit) => PopulatedTransaction; getCreditDelegationApprovedAmount: ( args: Omit @@ -335,6 +346,65 @@ export const createPoolSlice: StateCreator< signature, }); }, + getDaiForSavingsDai: (amount: string) => { + const provider = get().jsonRpcProvider(); + const wrapperAddress = get().currentMarketData.addresses.SDAI_TOKEN_WRAPPER; + if (!wrapperAddress) { + throw Error('sDAI wrapper is not configured'); + } + + const service = new SavingsDaiTokenWrapperService(provider, wrapperAddress); + return service.getTokenInForTokenOut(amount); + }, + getSavingsDaiForDai: (amount: string) => { + const provider = get().jsonRpcProvider(); + const wrapperAddress = get().currentMarketData.addresses.SDAI_TOKEN_WRAPPER; + if (!wrapperAddress) { + throw Error('sDAI wrapper is not configured'); + } + + const service = new SavingsDaiTokenWrapperService(provider, wrapperAddress); + return service.getTokenOutForTokenIn(amount); + }, + supplyDaiAsSavingsDai: (amount: string) => { + const provider = get().jsonRpcProvider(); + const wrapperAddress = get().currentMarketData.addresses.SDAI_TOKEN_WRAPPER; + if (!wrapperAddress) { + throw Error('sDAI wrapper is not configured'); + } + + const service = new SavingsDaiTokenWrapperService(provider, wrapperAddress); + return service.supplyToken(amount, get().account, '0'); + }, + supplyDaiAsSavingsDaiWithPermit: ( + amount: string, + deadline: string, + signature: SignatureLike + ) => { + const provider = get().jsonRpcProvider(); + const wrapperAddress = get().currentMarketData.addresses.SDAI_TOKEN_WRAPPER; + if (!wrapperAddress) { + throw Error('sDAI wrapper is not configured'); + } + + const service = new SavingsDaiTokenWrapperService(provider, wrapperAddress); + return service.supplyTokenWithPermit({ + amount, + onBehalfOf: get().account, + deadline, + signature, + referralCode: '0', + }); + }, + getApprovedAmount: async (args: { token: string }) => { + const poolBundle = getCorrectPoolBundle(); + const user = get().account; + if (poolBundle instanceof PoolBundle) { + return poolBundle.supplyTxBuilder.getApprovedAmount({ user, token: args.token }); + } else { + return poolBundle.depositTxBuilder.getApprovedAmount({ user, token: args.token }); + } + }, borrow: (args: Omit) => { const poolBundle = get().getCorrectPoolBundle(); const currentAccount = get().account; diff --git a/src/ui-config/marketsConfig.tsx b/src/ui-config/marketsConfig.tsx index 0fd779afe8..ffa553a14b 100644 --- a/src/ui-config/marketsConfig.tsx +++ b/src/ui-config/marketsConfig.tsx @@ -67,6 +67,7 @@ export type MarketDataType = { V3_MIGRATOR?: string; GHO_TOKEN_ADDRESS?: string; GHO_UI_DATA_PROVIDER?: string; + SDAI_TOKEN_WRAPPER?: string; }; /** * https://www.hal.xyz/ has integrated aave for healtfactor warning notification @@ -142,6 +143,7 @@ export const marketsData: { GHO_UI_DATA_PROVIDER: AaveV3Ethereum.UI_GHO_DATA_PROVIDER, WITHDRAW_SWITCH_ADAPTER: AaveV3Ethereum.WITHDRAW_SWAP_ADAPTER, DEBT_SWITCH_ADAPTER: AaveV3Ethereum.DEBT_SWAP_ADAPTER, + SDAI_TOKEN_WRAPPER: '0x437f428930669cd06adab2df4a8d4b203ac729c6', }, halIntegration: { URL: 'https://app.hal.xyz/recipes/aave-v3-track-health-factor', diff --git a/src/ui-config/wrappedTokenConfig.ts b/src/ui-config/wrappedTokenConfig.ts new file mode 100644 index 0000000000..e5fdd170b9 --- /dev/null +++ b/src/ui-config/wrappedTokenConfig.ts @@ -0,0 +1,7 @@ +import { ChainId } from '@aave/contract-helpers'; + +export const wrappedTokenConfig: { [chainId: number]: { [tokenOut: string]: string } } = { + [ChainId.mainnet]: { + '0x83f20f44975d03b1b09e64809b757c47f942beea': '0x6b175474e89094c44da98b954eedeac495271d0f', // sDAI -> DAI + }, +}; diff --git a/yarn.lock b/yarn.lock index 274554b1b3..3ed3130065 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,10 +2,10 @@ # yarn lockfile v1 -"@aave/contract-helpers@1.21.1-0efe71955bfd19d178a3edef77416ca0612598b9.0": - version "1.21.1-0efe71955bfd19d178a3edef77416ca0612598b9.0" - resolved "https://registry.yarnpkg.com/@aave/contract-helpers/-/contract-helpers-1.21.1-0efe71955bfd19d178a3edef77416ca0612598b9.0.tgz#ff068c6b1cc84c989a8566ae5cb0de8674fabdb2" - integrity sha512-04FPIti7B2U4KXKUTzXAXbL+NOP1Q+KtDFZR1mo5OWJZoW6Ky8xCTqSpFNMQbxMoejiJaYYqkeEQnOgVOuwEDQ== +"@aave/contract-helpers@1.21.1-3c5fc7ba506d4aceaf433900344ace2f391e397b.0": + version "1.21.1-3c5fc7ba506d4aceaf433900344ace2f391e397b.0" + resolved "https://registry.yarnpkg.com/@aave/contract-helpers/-/contract-helpers-1.21.1-3c5fc7ba506d4aceaf433900344ace2f391e397b.0.tgz#680026aed17cc839c9b6fa56b56cece2da095096" + integrity sha512-zR1LC9dgoquNop55o74GCkGYT1xaTH7JGiOgNshFb1gQaci+KEwqNTIDlCtSBFIg3mTc4NJXHu75Qz3n8HxyBA== dependencies: isomorphic-unfetch "^3.1.0" From b6f8fa263eed6ce4ba06d40badf0264cd4bf8750 Mon Sep 17 00:00:00 2001 From: Mark Grothe Date: Wed, 6 Sep 2023 10:43:51 -0500 Subject: [PATCH 25/46] feat: wip --- .../Supply/useSavingsDaiWrapper.ts | 47 ++++++++++++++++++- .../WithdrawAndSwitchModalContent.tsx | 12 ++++- 2 files changed, 56 insertions(+), 3 deletions(-) diff --git a/src/components/transactions/Supply/useSavingsDaiWrapper.ts b/src/components/transactions/Supply/useSavingsDaiWrapper.ts index 86103df0ab..37b21992e3 100644 --- a/src/components/transactions/Supply/useSavingsDaiWrapper.ts +++ b/src/components/transactions/Supply/useSavingsDaiWrapper.ts @@ -19,7 +19,7 @@ export const useSavingsDaiWrapper = ({ return; } - const getTokenInForTokenOut = async () => { + const getTokenOutForTokenIn = async () => { const amount = parseUnits(supplyAmount, decimals).toString(); const tokenOut = await getSavingsDaiForDai(amount); const outAmount = formatUnits(tokenOut.toString(), decimals); @@ -30,7 +30,7 @@ export const useSavingsDaiWrapper = ({ setLoading(true); const timeout = setTimeout(() => { - getTokenInForTokenOut(); + getTokenOutForTokenIn(); }, 2000); return () => { @@ -44,3 +44,46 @@ export const useSavingsDaiWrapper = ({ tokenOutAmount, }; }; + +export const useDaiForSavingsDaiWrapper = ({ + withdrawAmount, + decimals, +}: { + withdrawAmount: string; + decimals: number; +}) => { + const getDaiForSavingsDai = useRootStore((state) => state.getDaiForSavingsDai); + const [loading, setLoading] = useState(false); + const [tokenInAmount, setTokenInAmount] = useState('0'); + + useEffect(() => { + if (!withdrawAmount || withdrawAmount === '0') { + setTokenInAmount('0'); + return; + } + + const getTokenInForTokenOut = async () => { + const amount = parseUnits(withdrawAmount, decimals).toString(); + const tokenOut = await getDaiForSavingsDai(amount); + const outAmount = formatUnits(tokenOut.toString(), decimals); + // console.log('out amount', outAmount); + setTokenInAmount(outAmount); + setLoading(false); + }; + + setLoading(true); + const timeout = setTimeout(() => { + getTokenInForTokenOut(); + }, 2000); + + return () => { + clearTimeout(timeout); + // setLoading(false); + }; + }, [decimals, getDaiForSavingsDai, withdrawAmount]); + + return { + loading, + tokenInAmount, + }; +}; diff --git a/src/components/transactions/Withdraw/WithdrawAndSwitchModalContent.tsx b/src/components/transactions/Withdraw/WithdrawAndSwitchModalContent.tsx index 2f9ffff466..6b44658963 100644 --- a/src/components/transactions/Withdraw/WithdrawAndSwitchModalContent.tsx +++ b/src/components/transactions/Withdraw/WithdrawAndSwitchModalContent.tsx @@ -23,6 +23,7 @@ import { Asset, AssetInput } from '../AssetInput'; import { GasEstimationError } from '../FlowCommons/GasEstimationError'; import { ModalWrapperProps } from '../FlowCommons/ModalWrapper'; import { DetailsHFLine, DetailsNumberLine, TxModalDetails } from '../FlowCommons/TxModalDetails'; +import { useDaiForSavingsDaiWrapper } from '../Supply/useSavingsDaiWrapper'; import { zeroLTVBlockingWithdraw } from '../utils'; import { calculateMaxWithdrawAmount } from './utils'; import { WithdrawAndSwitchActions } from './WithdrawAndSwitchActions'; @@ -55,6 +56,8 @@ export const WithdrawAndSwitchModalContent = ({ // if the asset can be unwrapped (e.g. sDAI -> DAI) we don't need to use paraswap const wrappedTokenOutConfig = wrappedTokenConfig[currentChainId][poolReserve.underlyingAsset]; + console.log(wrappedTokenOutConfig); + let swapTargets = reserves .filter((r) => r.underlyingAsset !== poolReserve.underlyingAsset) .map((reserve) => ({ @@ -80,6 +83,13 @@ export const WithdrawAndSwitchModalContent = ({ const maxAmountToWithdraw = calculateMaxWithdrawAmount(user, userReserve, poolReserve); const underlyingBalance = valueToBigNumber(userReserve?.underlyingBalance || '0'); + const { loading: loadingDaiForSavingsDai, tokenInAmount } = useDaiForSavingsDaiWrapper({ + withdrawAmount: amountRef.current, + decimals: 18, + }); + + console.log(loadingDaiForSavingsDai, tokenInAmount); + const { inputAmountUSD, inputAmount, @@ -94,7 +104,7 @@ export const WithdrawAndSwitchModalContent = ({ swapIn: { ...poolReserve, amount: amountRef.current }, swapOut: { ...swapTarget.reserve, amount: '0' }, max: isMaxSelected && maxAmountToWithdraw.eq(underlyingBalance), - skip: wrappedTokenOutConfig !== '' || withdrawTxState.loading || false, + skip: wrappedTokenOutConfig !== undefined || withdrawTxState.loading || false, maxSlippage: Number(maxSlippage), }); From 8d47eb8720065de9d4f71d613f8bbf34d07cb820 Mon Sep 17 00:00:00 2001 From: Mark Grothe Date: Thu, 26 Oct 2023 08:29:17 -0500 Subject: [PATCH 26/46] feat: wip --- .../Withdraw/WithdrawAndUnwrapActions.tsx | 181 ++++++++++++++++++ src/ui-config/wrappedTokenConfig.ts | 15 ++ 2 files changed, 196 insertions(+) create mode 100644 src/components/transactions/Withdraw/WithdrawAndUnwrapActions.tsx diff --git a/src/components/transactions/Withdraw/WithdrawAndUnwrapActions.tsx b/src/components/transactions/Withdraw/WithdrawAndUnwrapActions.tsx new file mode 100644 index 0000000000..2937503738 --- /dev/null +++ b/src/components/transactions/Withdraw/WithdrawAndUnwrapActions.tsx @@ -0,0 +1,181 @@ +import { MAX_UINT_AMOUNT, ProtocolAction, TokenWrapperService } from '@aave/contract-helpers'; +import { SignatureLike } from '@ethersproject/bytes'; +import { Trans } from '@lingui/macro'; +import { parseUnits } from 'ethers/lib/utils'; +import { useState } from 'react'; +import { MOCK_SIGNED_HASH } from 'src/helpers/useTransactionHandler'; +import { useModalContext } from 'src/hooks/useModal'; +import { useWeb3Context } from 'src/libs/hooks/useWeb3Context'; +import { useRootStore } from 'src/store/root'; +import { ApprovalMethod } from 'src/store/walletSlice'; +import { getErrorTextFromError, TxAction } from 'src/ui-config/errorMapping'; + +import { useApprovedAmount } from '../Supply/useApprovedAmount'; +import { TxActionsWrapper } from '../TxActionsWrapper'; +import { checkRequiresApproval } from '../utils'; + +interface SignedParams { + signature: SignatureLike; + deadline: string; + amount: string; +} + +interface WithdrawAndUnwrapActionProps { + reserve: string; + amountToWithdraw: string; + isWrongNetwork: boolean; + tokenIn: string; + tokenOut: string; + tokenWrapperAddress: string; + decimals: number; + symbol: string; +} + +export const WithdrawAndUnwrapAction = ({ + reserve, + amountToWithdraw, + isWrongNetwork, + tokenIn, + tokenOut, + tokenWrapperAddress, + decimals, + symbol, +}: WithdrawAndUnwrapActionProps) => { + const [ + provider, + wrapperAddress, + account, + estimateGasLimit, + walletApprovalMethodPreference, + tryPermit, + generateSignatureRequest, + generateApproval, + addTransaction, + ] = useRootStore((state) => [ + state.jsonRpcProvider, + state.currentMarketData.addresses.SDAI_TOKEN_WRAPPER, + state.account, + state.estimateGasLimit, + state.walletApprovalMethodPreference, + state.tryPermit, + state.generateSignatureRequest, + state.generateApproval, + state.addTransaction, + ]); + + const { signTxData, sendTx } = useWeb3Context(); + + const [signatureParams, setSignatureParams] = useState(); + + const { + approvalTxState, + mainTxState, + loadingTxns, + setLoadingTxns, + setApprovalTxState, + setMainTxState, + setGasLimit, + setTxError, + } = useModalContext(); + + const { loading: loadingApprovedAmount, approval } = useApprovedAmount({ + spender: tokenWrapperAddress, + tokenAddress: tokenIn, + }); + + let requiresApproval = false; + if (approval) { + requiresApproval = checkRequiresApproval({ + approvedAmount: approval.amount, + amount: amountToWithdraw, + signedAmount: signatureParams ? signatureParams.amount : '0', + }); + } + + const permitAvailable = tryPermit(tokenIn); + + const usePermit = permitAvailable && walletApprovalMethodPreference === ApprovalMethod.PERMIT; + + const approvalAction = async () => { + try { + if (requiresApproval && approval) { + if (usePermit) { + const deadline = Math.floor(Date.now() / 1000 + 3600).toString(); + const signatureRequest = await generateSignatureRequest({ + ...approval, + deadline, + amount: parseUnits(amountToWithdraw, decimals).toString(), + }); + + const response = await signTxData(signatureRequest); + setSignatureParams({ signature: response, deadline, amount: amountToWithdraw }); + setApprovalTxState({ + txHash: MOCK_SIGNED_HASH, + loading: false, + success: true, + }); + } else { + let approveTxData = generateApproval(approval); + setApprovalTxState({ ...approvalTxState, loading: true }); + approveTxData = await estimateGasLimit(approveTxData); + const response = await sendTx(approveTxData); + await response.wait(1); + setApprovalTxState({ + txHash: response.hash, + loading: false, + success: true, + }); + addTransaction(response.hash, { + action: ProtocolAction.approval, + txState: 'success', + asset: tokenIn, + amount: MAX_UINT_AMOUNT, + assetName: symbol, + }); + // fetchApprovedAmount(true); + } + } + } catch (error) { + const parsedError = getErrorTextFromError(error, TxAction.GAS_ESTIMATION, false); + setTxError(parsedError); + setApprovalTxState({ + txHash: undefined, + loading: false, + }); + } + }; + + const action = async () => { + try { + const service = new TokenWrapperService(provider(), wrapperAddress || ''); + let txData = service.withdrawToken(amountToWithdraw, account); + txData = await estimateGasLimit(txData); + const response = await sendTx(txData); + + await response.wait(1); + } catch (error) { + const parsedError = getErrorTextFromError(error, TxAction.GAS_ESTIMATION, false); + setTxError(parsedError); + setApprovalTxState({ + txHash: undefined, + loading: false, + }); + } + }; + + return ( + Withdrawing} + actionText={Withdraw} + handleAction={action} + requiresApproval={false} + /> + ); +}; diff --git a/src/ui-config/wrappedTokenConfig.ts b/src/ui-config/wrappedTokenConfig.ts index e5fdd170b9..d1a498654f 100644 --- a/src/ui-config/wrappedTokenConfig.ts +++ b/src/ui-config/wrappedTokenConfig.ts @@ -1,7 +1,22 @@ import { ChainId } from '@aave/contract-helpers'; +interface WrappedTokenConfig { + tokenIn: string; + tokenOut: string; + tokenWrapperContractAddress: string; +} + export const wrappedTokenConfig: { [chainId: number]: { [tokenOut: string]: string } } = { [ChainId.mainnet]: { '0x83f20f44975d03b1b09e64809b757c47f942beea': '0x6b175474e89094c44da98b954eedeac495271d0f', // sDAI -> DAI }, }; + +// TODO: need to consider v2/v3 markets +export const foo: { [chainId: number]: WrappedTokenConfig } = { + [ChainId.mainnet]: { + tokenIn: '0x6B175474E89094C44Da98b954EedeAC495271d0F', //DAI + tokenOut: '0x83f20f44975d03b1b09e64809b757c47f942beea', //sDAI + tokenWrapperContractAddress: '0x437f428930669cd06adab2df4a8d4b203ac729c6', + }, +}; From d20282e2e42d6e8b50889c236fa23b05811b94a7 Mon Sep 17 00:00:00 2001 From: Mark Grothe Date: Thu, 26 Oct 2023 08:45:37 -0500 Subject: [PATCH 27/46] fix: bad merge --- src/store/poolSlice.ts | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/store/poolSlice.ts b/src/store/poolSlice.ts index c0a8abf184..9f470b5899 100644 --- a/src/store/poolSlice.ts +++ b/src/store/poolSlice.ts @@ -142,7 +142,6 @@ export interface PoolSlice { deadline: string, signature: SignatureLike ) => PopulatedTransaction; - getApprovedAmount: (args: { token: string }) => Promise; borrow: (args: Omit) => PopulatedTransaction; getCreditDelegationApprovedAmount: ( args: Omit @@ -396,15 +395,6 @@ export const createPoolSlice: StateCreator< referralCode: '0', }); }, - getApprovedAmount: async (args: { token: string }) => { - const poolBundle = getCorrectPoolBundle(); - const user = get().account; - if (poolBundle instanceof PoolBundle) { - return poolBundle.supplyTxBuilder.getApprovedAmount({ user, token: args.token }); - } else { - return poolBundle.depositTxBuilder.getApprovedAmount({ user, token: args.token }); - } - }, borrow: (args: Omit) => { const poolBundle = get().getCorrectPoolBundle(); const currentAccount = get().account; From 6e57858a9f607374b8b02aa9263b7c3601aea743 Mon Sep 17 00:00:00 2001 From: Mark Grothe Date: Thu, 26 Oct 2023 17:12:05 -0500 Subject: [PATCH 28/46] feat: token wrapping wip --- .../Supply/SupplyModalContent.tsx | 113 +++++----- .../Supply/SupplyWrappedTokenActions.tsx | 154 ++++++------- .../Supply/useSavingsDaiWrapper.ts | 89 -------- .../WithdrawAndSwitchModalContent.tsx | 67 ++++-- .../Withdraw/WithdrawAndUnwrapActions.tsx | 205 +++++++++--------- .../Withdraw/WithdrawModalContent.tsx | 170 ++------------- src/hooks/token-wrapper/useTokenWrapper.ts | 45 ++++ src/hooks/useApprovedAmount.tsx | 9 +- src/locales/en/messages.js | 2 +- src/locales/en/messages.po | 7 +- src/services/TokenWrapperService.ts | 80 +++++++ src/store/poolSlice.ts | 60 ----- src/ui-config/SharedDependenciesProvider.tsx | 4 + src/ui-config/wrappedTokenConfig.ts | 33 +-- 14 files changed, 444 insertions(+), 594 deletions(-) delete mode 100644 src/components/transactions/Supply/useSavingsDaiWrapper.ts create mode 100644 src/hooks/token-wrapper/useTokenWrapper.ts create mode 100644 src/services/TokenWrapperService.ts diff --git a/src/components/transactions/Supply/SupplyModalContent.tsx b/src/components/transactions/Supply/SupplyModalContent.tsx index 04dcaa2da9..3d1077a279 100644 --- a/src/components/transactions/Supply/SupplyModalContent.tsx +++ b/src/components/transactions/Supply/SupplyModalContent.tsx @@ -7,13 +7,15 @@ import { import { Trans } from '@lingui/macro'; import { Skeleton, Stack, Typography } from '@mui/material'; import BigNumber from 'bignumber.js'; -import React, { useMemo, useState } from 'react'; +import React, { useState } from 'react'; import { ContentWithTooltip } from 'src/components/ContentWithTooltip'; import { FormattedNumber } from 'src/components/primitives/FormattedNumber'; import { Link } from 'src/components/primitives/Link'; import { TokenIcon } from 'src/components/primitives/TokenIcon'; import { Warning } from 'src/components/primitives/Warning'; import { AMPLWarning } from 'src/components/Warnings/AMPLWarning'; +import { useWalletBalances } from 'src/hooks/app-data-provider/useWalletBalances'; +import { useTokenOutForTokenIn } from 'src/hooks/token-wrapper/useTokenWrapper'; import { useAssetCaps } from 'src/hooks/useAssetCaps'; import { useModalContext } from 'src/hooks/useModal'; import { useProtocolDataContext } from 'src/hooks/useProtocolDataContext'; @@ -44,7 +46,6 @@ import { IsolationModeWarning } from '../Warnings/IsolationModeWarning'; import { SNXWarning } from '../Warnings/SNXWarning'; import { SupplyActions } from './SupplyActions'; import { SupplyWrappedTokenActions } from './SupplyWrappedTokenActions'; -import { useSavingsDaiWrapper } from './useSavingsDaiWrapper'; interface SupplyAsset extends Asset { balance: string; @@ -66,6 +67,7 @@ export const SupplyModalContent = React.memo( const { marketReferencePriceInUsd, user } = useAppDataContext(); const { currentMarketData, currentNetworkConfig } = useProtocolDataContext(); const { mainTxState: supplyTxState, gasLimit, txError } = useModalContext(); + const { walletBalances } = useWalletBalances(currentMarketData); const { supplyCap: supplyCapUsage, debtCeiling: debtCeilingUsage } = useAssetCaps(); const minRemainingBaseTokenBalance = useRootStore( (state) => state.poolComputed.minRemainingBaseTokenBalance @@ -79,36 +81,53 @@ export const SupplyModalContent = React.memo( balance: tokenBalance, }); const [amount, setAmount] = useState(''); + const supplyUnWrapped = underlyingAsset.toLowerCase() === API_ETH_MOCK_ADDRESS.toLowerCase(); const walletBalance = supplyUnWrapped ? nativeBalance : tokenBalance; + const wrappedTokenInConfig = wrappedTokenConfig[currentMarketData.chainId].find( + (c) => c.tokenOut.underlyingAsset === poolReserve.underlyingAsset + ); + const supplyApy = poolReserve.supplyAPY; const { supplyCap, totalLiquidity, isFrozen, decimals, debtCeiling, isolationModeTotalDebt } = poolReserve; - // Calculate max amount to supply - const maxAmountToSupply = useMemo( - () => - getMaxAmountAvailableToSupply( - walletBalance, - { supplyCap, totalLiquidity, isFrozen, decimals, debtCeiling, isolationModeTotalDebt }, - underlyingAsset, - minRemainingBaseTokenBalance - ), - [ - walletBalance, - supplyCap, - totalLiquidity, - isFrozen, - decimals, - debtCeiling, - isolationModeTotalDebt, - underlyingAsset, - minRemainingBaseTokenBalance, - ] + const maxAmountToSupply = getMaxAmountAvailableToSupply( + walletBalance, + { supplyCap, totalLiquidity, isFrozen, decimals, debtCeiling, isolationModeTotalDebt }, + underlyingAsset, + minRemainingBaseTokenBalance ); + const assets = [ + { + balance: maxAmountToSupply, + symbol: supplyUnWrapped ? currentNetworkConfig.baseAssetSymbol : poolReserve.symbol, + iconSymbol: supplyUnWrapped ? currentNetworkConfig.baseAssetSymbol : poolReserve.iconSymbol, + address: poolReserve.underlyingAsset, + }, + ]; + + let supplyingWrappedToken = false; + if (wrappedTokenInConfig) { + const tokenToWrapBalance = + walletBalances[wrappedTokenInConfig.tokenIn.underlyingAsset]?.amount || '0'; + + if (tokenToWrapBalance !== '0') { + assets.push({ + balance: tokenToWrapBalance, + symbol: wrappedTokenInConfig.tokenIn.symbol, + iconSymbol: wrappedTokenInConfig.tokenIn.symbol, + address: wrappedTokenInConfig.tokenIn.underlyingAsset, + }); + } + + supplyingWrappedToken = + tokenToSupply.address === wrappedTokenInConfig.tokenIn.underlyingAsset; + } + const handleChange = (value: string) => { if (value === '-1') { setAmount(maxAmountToSupply); @@ -205,26 +224,6 @@ export const SupplyModalContent = React.memo( /> ); - const assets = [ - { - balance: maxAmountToSupply, - symbol: supplyUnWrapped ? currentNetworkConfig.baseAssetSymbol : poolReserve.symbol, - iconSymbol: supplyUnWrapped ? currentNetworkConfig.baseAssetSymbol : poolReserve.iconSymbol, - }, - ]; - - const wrappedTokenInConfig = - wrappedTokenConfig[currentMarketData.chainId][poolReserve.underlyingAsset]; - if (wrappedTokenInConfig) { - assets.push({ - balance: maxAmountToSupply, - symbol: 'DAI', // TODO - iconSymbol: 'DAI', // TODO - }); - } - - const supplyingWrappedToken = tokenToSupply.address === wrappedTokenInConfig; - return ( <> {showIsolationWarning && } @@ -260,8 +259,13 @@ export const SupplyModalContent = React.memo( }, }} exchangeRateComponent={ - poolReserve.symbol === 'sDAI' && - tokenToSupply.symbol === 'DAI' && + supplyingWrappedToken && + wrappedTokenInConfig && ( + + ) } /> @@ -281,9 +285,10 @@ export const SupplyModalContent = React.memo( {txError && } - {supplyingWrappedToken ? ( + {supplyingWrappedToken && wrappedTokenInConfig ? ( { - const { loading, tokenOutAmount } = useSavingsDaiWrapper({ supplyAmount, decimals: 18 }); +const ExchangeRate = ({ + supplyAmount, + tokenWrapperAddress, +}: { + supplyAmount: string; + tokenWrapperAddress: string; +}) => { + const { isFetching: loading, data: tokenOutAmount } = useTokenOutForTokenIn( + supplyAmount, + 18, + tokenWrapperAddress + ); console.log('tokenOutAmount', tokenOutAmount); @@ -311,7 +326,7 @@ const ExchangeRate = ({ supplyAmount }: { supplyAmount: string }) => { ) : ( <> { - const [ - currentMarketData, - tryPermit, - walletApprovalMethodPreference, - generateSignatureRequest, - generateApproval, - estimateGasLimit, - addTransaction, - supplyDaiAsSavingsDaiWithPermit, - supplyDaiAsSavingsDai, - ] = useRootStore((state) => [ - state.currentMarketData, - state.tryPermit, - state.walletApprovalMethodPreference, - state.generateSignatureRequest, - state.generateApproval, - state.estimateGasLimit, - state.addTransaction, - state.supplyDaiAsSavingsDaiWithPermit, - state.supplyDaiAsSavingsDai, - ]); + const [user, walletApprovalMethodPreference, estimateGasLimit, addTransaction] = useRootStore( + (state) => [ + state.account, + state.walletApprovalMethodPreference, + state.estimateGasLimit, + state.addTransaction, + ] + ); + const { refetchPoolData } = useBackgroundDataProvider(); + const { tokenWrapperService } = useSharedDependencies(); const [signatureParams, setSignatureParams] = useState(); const { @@ -70,25 +65,24 @@ export const SupplyWrappedTokenActions = ({ setGasLimit, } = useModalContext(); - const { signTxData, sendTx } = useWeb3Context(); + const { sendTx } = useWeb3Context(); - const { loading: loadingApprovedAmount, approval } = useApprovedAmount({ - spender: currentMarketData.addresses.SDAI_TOKEN_WRAPPER || '', - tokenAddress: tokenIn, - }); + const { + data: approvedAmount, + isFetching, + refetch: fetchApprovedAmount, + } = useApprovedAmount(tokenIn, tokenWrapperAddress); let requiresApproval = false; - if (approval) { + if (approvedAmount !== undefined) { requiresApproval = checkRequiresApproval({ - approvedAmount: approval.amount, + approvedAmount: approvedAmount.toString(), amount: amountToSupply, signedAmount: signatureParams ? signatureParams.amount : '0', }); } - const permitAvailable = tryPermit(tokenIn); - - const usePermit = permitAvailable && walletApprovalMethodPreference === ApprovalMethod.PERMIT; + const usePermit = walletApprovalMethodPreference === ApprovalMethod.PERMIT; // Update gas estimation let supplyGasLimit = 0; @@ -103,57 +97,31 @@ export const SupplyWrappedTokenActions = ({ setGasLimit(supplyGasLimit.toString()); - console.log('loading approved amount', loadingApprovedAmount); - console.log('approval', approval); + console.log('loading approved amount', isFetching); + console.log('approved amount', approvedAmount); - const approvalAction = async () => { - try { - if (requiresApproval && approval) { - if (usePermit) { - const deadline = Math.floor(Date.now() / 1000 + 3600).toString(); - const signatureRequest = await generateSignatureRequest({ - ...approval, - deadline, - amount: parseUnits(amountToSupply, decimals).toString(), - }); - - const response = await signTxData(signatureRequest); - setSignatureParams({ signature: response, deadline, amount: amountToSupply }); - setApprovalTxState({ - txHash: MOCK_SIGNED_HASH, - loading: false, - success: true, - }); - } else { - let approveTxData = generateApproval(approval); - setApprovalTxState({ ...approvalTxState, loading: true }); - approveTxData = await estimateGasLimit(approveTxData); - const response = await sendTx(approveTxData); - await response.wait(1); - setApprovalTxState({ - txHash: response.hash, - loading: false, - success: true, - }); - addTransaction(response.hash, { - action: ProtocolAction.approval, - txState: 'success', - asset: tokenIn, - amount: MAX_UINT_AMOUNT, - assetName: symbol, - }); - // fetchApprovedAmount(true); - } - } - } catch (error) { - const parsedError = getErrorTextFromError(error, TxAction.GAS_ESTIMATION, false); - setTxError(parsedError); - setApprovalTxState({ - txHash: undefined, - loading: false, - }); - } - }; + if (requiresApproval && approvalTxState?.success) { + // There was a successful approval tx, but the approval amount is not enough. + // Clear the state to prompt for another approval. + setApprovalTxState({}); + } + + const { approval: approvalAction } = useApprovalTx({ + usePermit, + approvedAmount: { + amount: approvedAmount?.toString() || '0', + spender: tokenWrapperAddress, + token: tokenIn, + user, + }, + requiresApproval, + assetAddress: tokenIn, + symbol, + decimals: decimals, + signatureAmount: amountToSupply, + onApprovalTxConfirmed: fetchApprovedAmount, + onSignTxCompleted: (signedParams) => setSignatureParams(signedParams), + }); const action = async () => { try { @@ -166,8 +134,10 @@ export const SupplyWrappedTokenActions = ({ // checking user preference is not sufficient because permit may be available but the user has an existing approval if (usePermit && signatureParams) { action = ProtocolAction.supplyWithPermit; - let signedSupplyWithPermitTxData = supplyDaiAsSavingsDaiWithPermit( + let signedSupplyWithPermitTxData = await tokenWrapperService.supplyWrappedTokenWithPermit( parseUnits(amountToSupply, decimals).toString(), + tokenWrapperAddress, + user, signatureParams.deadline, signatureParams.signature ); @@ -178,7 +148,11 @@ export const SupplyWrappedTokenActions = ({ await response.wait(1); } else { action = ProtocolAction.supply; - let supplyTxData = supplyDaiAsSavingsDai(parseUnits(amountToSupply, decimals).toString()); + let supplyTxData = await tokenWrapperService.supplyWrappedToken( + parseUnits(amountToSupply, decimals).toString(), + tokenWrapperAddress, + user + ); supplyTxData = await estimateGasLimit(supplyTxData); response = await sendTx(supplyTxData); @@ -199,10 +173,8 @@ export const SupplyWrappedTokenActions = ({ assetName: symbol, }); - // queryClient.invalidateQueries({ queryKey: [QueryKeys.POOL_TOKENS] }); - // refetchPoolData && refetchPoolData(); - // refetchIncentiveData && refetchIncentiveData(); - // refetchGhoData && refetchGhoData(); + queryClient.invalidateQueries({ queryKey: [QueryKeys.POOL_TOKENS] }); + refetchPoolData && refetchPoolData(); } catch (error) { const parsedError = getErrorTextFromError(error, TxAction.GAS_ESTIMATION, false); setTxError(parsedError); @@ -228,7 +200,7 @@ export const SupplyWrappedTokenActions = ({ handleApproval={() => approvalAction()} handleAction={action} requiresApproval={requiresApproval} - tryPermit={permitAvailable} + tryPermit={usePermit} sx={sx} {...props} /> diff --git a/src/components/transactions/Supply/useSavingsDaiWrapper.ts b/src/components/transactions/Supply/useSavingsDaiWrapper.ts deleted file mode 100644 index 37b21992e3..0000000000 --- a/src/components/transactions/Supply/useSavingsDaiWrapper.ts +++ /dev/null @@ -1,89 +0,0 @@ -import { formatUnits, parseUnits } from 'ethers/lib/utils'; -import { useEffect, useState } from 'react'; -import { useRootStore } from 'src/store/root'; - -export const useSavingsDaiWrapper = ({ - supplyAmount, - decimals, -}: { - supplyAmount: string; - decimals: number; -}) => { - const getSavingsDaiForDai = useRootStore((state) => state.getSavingsDaiForDai); - const [loading, setLoading] = useState(false); - const [tokenOutAmount, setTokenOutAmount] = useState('0'); - - useEffect(() => { - if (!supplyAmount || supplyAmount === '0') { - setTokenOutAmount('0'); - return; - } - - const getTokenOutForTokenIn = async () => { - const amount = parseUnits(supplyAmount, decimals).toString(); - const tokenOut = await getSavingsDaiForDai(amount); - const outAmount = formatUnits(tokenOut.toString(), decimals); - // console.log('out amount', outAmount); - setTokenOutAmount(outAmount); - setLoading(false); - }; - - setLoading(true); - const timeout = setTimeout(() => { - getTokenOutForTokenIn(); - }, 2000); - - return () => { - clearTimeout(timeout); - // setLoading(false); - }; - }, [decimals, getSavingsDaiForDai, supplyAmount]); - - return { - loading, - tokenOutAmount, - }; -}; - -export const useDaiForSavingsDaiWrapper = ({ - withdrawAmount, - decimals, -}: { - withdrawAmount: string; - decimals: number; -}) => { - const getDaiForSavingsDai = useRootStore((state) => state.getDaiForSavingsDai); - const [loading, setLoading] = useState(false); - const [tokenInAmount, setTokenInAmount] = useState('0'); - - useEffect(() => { - if (!withdrawAmount || withdrawAmount === '0') { - setTokenInAmount('0'); - return; - } - - const getTokenInForTokenOut = async () => { - const amount = parseUnits(withdrawAmount, decimals).toString(); - const tokenOut = await getDaiForSavingsDai(amount); - const outAmount = formatUnits(tokenOut.toString(), decimals); - // console.log('out amount', outAmount); - setTokenInAmount(outAmount); - setLoading(false); - }; - - setLoading(true); - const timeout = setTimeout(() => { - getTokenInForTokenOut(); - }, 2000); - - return () => { - clearTimeout(timeout); - // setLoading(false); - }; - }, [decimals, getDaiForSavingsDai, withdrawAmount]); - - return { - loading, - tokenInAmount, - }; -}; diff --git a/src/components/transactions/Withdraw/WithdrawAndSwitchModalContent.tsx b/src/components/transactions/Withdraw/WithdrawAndSwitchModalContent.tsx index 6b44658963..9d993566bf 100644 --- a/src/components/transactions/Withdraw/WithdrawAndSwitchModalContent.tsx +++ b/src/components/transactions/Withdraw/WithdrawAndSwitchModalContent.tsx @@ -10,6 +10,7 @@ import { useAppDataContext, } from 'src/hooks/app-data-provider/useAppDataProvider'; import { useCollateralSwap } from 'src/hooks/paraswap/useCollateralSwap'; +import { useTokenInForTokenOut } from 'src/hooks/token-wrapper/useTokenWrapper'; import { useModalContext } from 'src/hooks/useModal'; import { useProtocolDataContext } from 'src/hooks/useProtocolDataContext'; import { useWeb3Context } from 'src/libs/hooks/useWeb3Context'; @@ -23,11 +24,11 @@ import { Asset, AssetInput } from '../AssetInput'; import { GasEstimationError } from '../FlowCommons/GasEstimationError'; import { ModalWrapperProps } from '../FlowCommons/ModalWrapper'; import { DetailsHFLine, DetailsNumberLine, TxModalDetails } from '../FlowCommons/TxModalDetails'; -import { useDaiForSavingsDaiWrapper } from '../Supply/useSavingsDaiWrapper'; import { zeroLTVBlockingWithdraw } from '../utils'; import { calculateMaxWithdrawAmount } from './utils'; import { WithdrawAndSwitchActions } from './WithdrawAndSwitchActions'; import { WithdrawAndSwitchTxSuccessView } from './WithdrawAndSwitchSuccess'; +import { WithdrawAndUnwrapAction } from './WithdrawAndUnwrapActions'; import { useWithdrawError } from './WithdrawError'; export enum ErrorType { @@ -54,9 +55,9 @@ export const WithdrawAndSwitchModalContent = ({ const [maxSlippage, setMaxSlippage] = useState('0.1'); // if the asset can be unwrapped (e.g. sDAI -> DAI) we don't need to use paraswap - const wrappedTokenOutConfig = wrappedTokenConfig[currentChainId][poolReserve.underlyingAsset]; - - console.log(wrappedTokenOutConfig); + const wrappedTokenOutConfig = wrappedTokenConfig[currentChainId].find( + (c) => c.tokenOut.underlyingAsset === poolReserve.underlyingAsset + ); let swapTargets = reserves .filter((r) => r.underlyingAsset !== poolReserve.underlyingAsset) @@ -83,12 +84,25 @@ export const WithdrawAndSwitchModalContent = ({ const maxAmountToWithdraw = calculateMaxWithdrawAmount(user, userReserve, poolReserve); const underlyingBalance = valueToBigNumber(userReserve?.underlyingBalance || '0'); - const { loading: loadingDaiForSavingsDai, tokenInAmount } = useDaiForSavingsDaiWrapper({ - withdrawAmount: amountRef.current, - decimals: 18, - }); + // const { loading: loadingDaiForSavingsDai, tokenInAmount } = useDaiForSavingsDaiWrapper({ + // withdrawAmount: amountRef.current, + // decimals: 18, + // }); - console.log(loadingDaiForSavingsDai, tokenInAmount); + // console.log(loadingDaiForSavingsDai, tokenInAmount); + + let withdrawAndUnwrap = false; + if (wrappedTokenOutConfig) { + withdrawAndUnwrap = targetReserve.address === wrappedTokenOutConfig.tokenIn.underlyingAsset; + } + + const { data: unwrappedAmount } = useTokenInForTokenOut( + amountRef.current, + poolReserve.decimals, + wrappedTokenOutConfig?.tokenWrapperContractAddress || '' + ); + + console.log('unwrappedAmount', unwrappedAmount); const { inputAmountUSD, @@ -104,7 +118,7 @@ export const WithdrawAndSwitchModalContent = ({ swapIn: { ...poolReserve, amount: amountRef.current }, swapOut: { ...swapTarget.reserve, amount: '0' }, max: isMaxSelected && maxAmountToWithdraw.eq(underlyingBalance), - skip: wrappedTokenOutConfig !== undefined || withdrawTxState.loading || false, + skip: withdrawAndUnwrap || withdrawTxState.loading || false, maxSlippage: Number(maxSlippage), }); @@ -203,7 +217,7 @@ export const WithdrawAndSwitchModalContent = ({ )} - + {withdrawAndUnwrap && wrappedTokenOutConfig ? ( + + ) : ( + + )} ); }; diff --git a/src/components/transactions/Withdraw/WithdrawAndUnwrapActions.tsx b/src/components/transactions/Withdraw/WithdrawAndUnwrapActions.tsx index 2937503738..d88675aef0 100644 --- a/src/components/transactions/Withdraw/WithdrawAndUnwrapActions.tsx +++ b/src/components/transactions/Withdraw/WithdrawAndUnwrapActions.tsx @@ -1,18 +1,24 @@ -import { MAX_UINT_AMOUNT, ProtocolAction, TokenWrapperService } from '@aave/contract-helpers'; +import { gasLimitRecommendations, ProtocolAction, valueToWei } from '@aave/contract-helpers'; import { SignatureLike } from '@ethersproject/bytes'; +import { TransactionResponse } from '@ethersproject/providers'; import { Trans } from '@lingui/macro'; -import { parseUnits } from 'ethers/lib/utils'; -import { useState } from 'react'; -import { MOCK_SIGNED_HASH } from 'src/helpers/useTransactionHandler'; +import { constants } from 'ethers'; +import { queryClient } from 'pages/_app.page'; +import { useEffect, useState } from 'react'; +import { useBackgroundDataProvider } from 'src/hooks/app-data-provider/BackgroundDataProvider'; +import { ComputedReserveData } from 'src/hooks/app-data-provider/useAppDataProvider'; +import { useApprovalTx } from 'src/hooks/useApprovalTx'; +import { useApprovedAmount } from 'src/hooks/useApprovedAmount'; import { useModalContext } from 'src/hooks/useModal'; import { useWeb3Context } from 'src/libs/hooks/useWeb3Context'; import { useRootStore } from 'src/store/root'; import { ApprovalMethod } from 'src/store/walletSlice'; import { getErrorTextFromError, TxAction } from 'src/ui-config/errorMapping'; +import { QueryKeys } from 'src/ui-config/queries'; +import { useSharedDependencies } from 'src/ui-config/SharedDependenciesProvider'; -import { useApprovedAmount } from '../Supply/useApprovedAmount'; import { TxActionsWrapper } from '../TxActionsWrapper'; -import { checkRequiresApproval } from '../utils'; +import { APPROVAL_GAS_LIMIT, checkRequiresApproval } from '../utils'; interface SignedParams { signature: SignatureLike; @@ -21,52 +27,31 @@ interface SignedParams { } interface WithdrawAndUnwrapActionProps { - reserve: string; + poolReserve: ComputedReserveData; amountToWithdraw: string; isWrongNetwork: boolean; - tokenIn: string; - tokenOut: string; tokenWrapperAddress: string; - decimals: number; - symbol: string; } export const WithdrawAndUnwrapAction = ({ - reserve, + poolReserve, amountToWithdraw, isWrongNetwork, - tokenIn, - tokenOut, tokenWrapperAddress, - decimals, - symbol, }: WithdrawAndUnwrapActionProps) => { - const [ - provider, - wrapperAddress, - account, - estimateGasLimit, - walletApprovalMethodPreference, - tryPermit, - generateSignatureRequest, - generateApproval, - addTransaction, - ] = useRootStore((state) => [ - state.jsonRpcProvider, - state.currentMarketData.addresses.SDAI_TOKEN_WRAPPER, - state.account, - state.estimateGasLimit, - state.walletApprovalMethodPreference, - state.tryPermit, - state.generateSignatureRequest, - state.generateApproval, - state.addTransaction, - ]); - - const { signTxData, sendTx } = useWeb3Context(); + const [account, estimateGasLimit, walletApprovalMethodPreference, user] = useRootStore( + (state) => [ + state.account, + state.estimateGasLimit, + state.walletApprovalMethodPreference, + state.account, + ] + ); - const [signatureParams, setSignatureParams] = useState(); + const { sendTx } = useWeb3Context(); + const [signatureParams, setSignatureParams] = useState(); + const { refetchPoolData } = useBackgroundDataProvider(); const { approvalTxState, mainTxState, @@ -78,81 +63,86 @@ export const WithdrawAndUnwrapAction = ({ setTxError, } = useModalContext(); - const { loading: loadingApprovedAmount, approval } = useApprovedAmount({ - spender: tokenWrapperAddress, - tokenAddress: tokenIn, - }); + const { tokenWrapperService } = useSharedDependencies(); + + const { + data: approvedAmount, + isFetching: fetchingApprovedAmount, + refetch: fetchApprovedAmount, + } = useApprovedAmount(poolReserve.aTokenAddress, tokenWrapperAddress); + + setLoadingTxns(fetchingApprovedAmount); let requiresApproval = false; - if (approval) { + if (approvedAmount !== undefined) { requiresApproval = checkRequiresApproval({ - approvedAmount: approval.amount, + approvedAmount: approvedAmount.toString(), amount: amountToWithdraw, signedAmount: signatureParams ? signatureParams.amount : '0', }); } - const permitAvailable = tryPermit(tokenIn); - - const usePermit = permitAvailable && walletApprovalMethodPreference === ApprovalMethod.PERMIT; + // const permitAvailable = tryPermit(tokenIn); + + const usePermit = walletApprovalMethodPreference === ApprovalMethod.PERMIT; + + const { approval: approvalAction } = useApprovalTx({ + usePermit, + approvedAmount: { + amount: approvedAmount?.toString() || '0', + spender: tokenWrapperAddress, + token: poolReserve.aTokenAddress, + user, + }, + requiresApproval, + assetAddress: poolReserve.aTokenAddress, + symbol: poolReserve.symbol, + decimals: poolReserve.decimals, + signatureAmount: amountToWithdraw, + onApprovalTxConfirmed: fetchApprovedAmount, + onSignTxCompleted: (signedParams) => setSignatureParams(signedParams), + }); - const approvalAction = async () => { + const action = async () => { try { - if (requiresApproval && approval) { - if (usePermit) { - const deadline = Math.floor(Date.now() / 1000 + 3600).toString(); - const signatureRequest = await generateSignatureRequest({ - ...approval, - deadline, - amount: parseUnits(amountToWithdraw, decimals).toString(), - }); - - const response = await signTxData(signatureRequest); - setSignatureParams({ signature: response, deadline, amount: amountToWithdraw }); - setApprovalTxState({ - txHash: MOCK_SIGNED_HASH, - loading: false, - success: true, - }); - } else { - let approveTxData = generateApproval(approval); - setApprovalTxState({ ...approvalTxState, loading: true }); - approveTxData = await estimateGasLimit(approveTxData); - const response = await sendTx(approveTxData); - await response.wait(1); - setApprovalTxState({ - txHash: response.hash, - loading: false, - success: true, - }); - addTransaction(response.hash, { - action: ProtocolAction.approval, - txState: 'success', - asset: tokenIn, - amount: MAX_UINT_AMOUNT, - assetName: symbol, - }); - // fetchApprovedAmount(true); - } + setMainTxState({ ...mainTxState, loading: true }); + + let response: TransactionResponse; + + const convertedAmount: string = + amountToWithdraw === '-1' + ? constants.MaxUint256.toString() + : valueToWei(amountToWithdraw, poolReserve.decimals); + + if (usePermit && signatureParams) { + let signedTxData = await tokenWrapperService.withdrawWrappedTokenWithPermit( + convertedAmount, + tokenWrapperAddress, + user, + signatureParams.deadline, + signatureParams.signature + ); + signedTxData = await estimateGasLimit(signedTxData); + response = await sendTx(signedTxData); + await response.wait(1); + } else { + let txData = await tokenWrapperService.withdrawWrappedToken( + convertedAmount, + tokenWrapperAddress, + account + ); + txData = await estimateGasLimit(txData); + response = await sendTx(txData); + await response.wait(1); } - } catch (error) { - const parsedError = getErrorTextFromError(error, TxAction.GAS_ESTIMATION, false); - setTxError(parsedError); - setApprovalTxState({ - txHash: undefined, + setMainTxState({ + txHash: response.hash, loading: false, + success: true, }); - } - }; - const action = async () => { - try { - const service = new TokenWrapperService(provider(), wrapperAddress || ''); - let txData = service.withdrawToken(amountToWithdraw, account); - txData = await estimateGasLimit(txData); - const response = await sendTx(txData); - - await response.wait(1); + queryClient.invalidateQueries({ queryKey: [QueryKeys.POOL_TOKENS] }); + refetchPoolData && refetchPoolData(); } catch (error) { const parsedError = getErrorTextFromError(error, TxAction.GAS_ESTIMATION, false); setTxError(parsedError); @@ -163,6 +153,16 @@ export const WithdrawAndUnwrapAction = ({ } }; + useEffect(() => { + let supplyGasLimit = 0; + supplyGasLimit = Number(gasLimitRecommendations[ProtocolAction.withdraw].recommended); + if (requiresApproval && !approvalTxState.success) { + supplyGasLimit += Number(APPROVAL_GAS_LIMIT); + } + + setGasLimit(supplyGasLimit.toString()); + }, [requiresApproval, approvalTxState, usePermit, setGasLimit]); + return ( Withdrawing} actionText={Withdraw} handleAction={action} - requiresApproval={false} + requiresApproval={requiresApproval} + handleApproval={approvalAction} /> ); }; diff --git a/src/components/transactions/Withdraw/WithdrawModalContent.tsx b/src/components/transactions/Withdraw/WithdrawModalContent.tsx index 1969e9d95c..c582190115 100644 --- a/src/components/transactions/Withdraw/WithdrawModalContent.tsx +++ b/src/components/transactions/Withdraw/WithdrawModalContent.tsx @@ -1,12 +1,8 @@ import { API_ETH_MOCK_ADDRESS } from '@aave/contract-helpers'; import { valueToBigNumber } from '@aave/math-utils'; -import { ArrowNarrowRightIcon } from '@heroicons/react/solid'; import { Trans } from '@lingui/macro'; -import { Box, Checkbox, Stack, SvgIcon, Typography } from '@mui/material'; +import { Box, Checkbox, Typography } from '@mui/material'; import { useRef, useState } from 'react'; -import { ContentWithTooltip } from 'src/components/ContentWithTooltip'; -import { FormattedNumber } from 'src/components/primitives/FormattedNumber'; -import { Link } from 'src/components/primitives/Link'; import { Warning } from 'src/components/primitives/Warning'; import { useAppDataContext } from 'src/hooks/app-data-provider/useAppDataProvider'; import { useModalContext } from 'src/hooks/useModal'; @@ -15,7 +11,7 @@ import { useRootStore } from 'src/store/root'; import { calculateHFAfterWithdraw } from 'src/utils/hfUtils'; import { GENERAL } from 'src/utils/mixPanelEvents'; -import { Asset, AssetInput } from '../AssetInput'; +import { AssetInput } from '../AssetInput'; import { GasEstimationError } from '../FlowCommons/GasEstimationError'; import { ModalWrapperProps } from '../FlowCommons/ModalWrapper'; import { TxSuccessView } from '../FlowCommons/Success'; @@ -30,16 +26,6 @@ import { calculateMaxWithdrawAmount } from './utils'; import { WithdrawActions } from './WithdrawActions'; import { useWithdrawError } from './WithdrawError'; -interface WithdrawAsset extends Asset { - balance: string; -} - -// does this naming make sense? -// probably need to key on the underlying asset addresses -const wrappedTokenConfig: { [symbol: string]: string } = { - sDAI: 'DAI', -}; - export enum ErrorType { CAN_NOT_WITHDRAW_THIS_AMOUNT, POOL_DOES_NOT_HAVE_ENOUGH_LIQUIDITY, @@ -61,12 +47,6 @@ export const WithdrawModalContent = ({ const { user } = useAppDataContext(); const { currentNetworkConfig } = useProtocolDataContext(); - const [tokenToWithdraw, setTokenToWithdraw] = useState({ - address: poolReserve.underlyingAsset, - symbol: poolReserve.symbol, - iconSymbol: poolReserve.iconSymbol, - balance: '100', - }); const [_amount, setAmount] = useState(''); const [withdrawMax, setWithdrawMax] = useState(''); const [riskCheckboxAccepted, setRiskCheckboxAccepted] = useState(false); @@ -130,30 +110,22 @@ export const WithdrawModalContent = ({ /> ); - const assets: WithdrawAsset[] = [ - { - balance: maxAmountToWithdraw.toString(), - symbol: poolReserve.symbol, - iconSymbol: poolReserve.iconSymbol, - }, - ]; - - if (wrappedTokenConfig[poolReserve.symbol]) { - assets.push({ - balance: maxAmountToWithdraw.toString(), - symbol: wrappedTokenConfig[poolReserve.symbol], - iconSymbol: wrappedTokenConfig[poolReserve.symbol], - }); - } - return ( <> Supply balance ) } - exchangeRateComponent={ - poolReserve.symbol === 'sDAI' && tokenToWithdraw.symbol === 'DAI' && - } /> {blockingError !== undefined && ( @@ -258,116 +227,3 @@ export const WithdrawModalContent = ({ ); }; - -const ExchangeRate = () => { - return ( - - - - - - sDAI - - - - - - - DAI - - - - ); -}; -const ExchangeRateTooltip = ( - <> - - DAI balance will be converted via DSR contracts and then supplied as sDAI to Aave reserve. - Switching incurs no additional costs and no slippage. - {' '} - - Learn more - - -); - -const ExchangeIcon = () => { - return ( - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ); -}; diff --git a/src/hooks/token-wrapper/useTokenWrapper.ts b/src/hooks/token-wrapper/useTokenWrapper.ts new file mode 100644 index 0000000000..3e146c7406 --- /dev/null +++ b/src/hooks/token-wrapper/useTokenWrapper.ts @@ -0,0 +1,45 @@ +import { useQuery } from '@tanstack/react-query'; +import { BigNumber } from 'ethers'; +import { formatUnits, parseUnits } from 'ethers/lib/utils'; +import { useSharedDependencies } from 'src/ui-config/SharedDependenciesProvider'; + +export const useTokenInForTokenOut = ( + amount: string, + decimals: number, + tokenWrapperAddress: string +) => { + const { tokenWrapperService } = useSharedDependencies(); + return useQuery({ + queryFn: () => { + if (amount === '' || amount === '0') return Promise.resolve(BigNumber.from(0)); + + return tokenWrapperService.getTokenInForTokenOut( + parseUnits(amount, decimals).toString(), + tokenWrapperAddress + ); + }, + queryKey: [tokenWrapperAddress, amount], + select: (data) => formatUnits(data.toString(), decimals), + }); +}; + +export const useTokenOutForTokenIn = ( + amount: string, + decimals: number, + tokenWrapperAddress: string +) => { + const { tokenWrapperService } = useSharedDependencies(); + return useQuery({ + queryFn: () => { + if (amount === '' || amount === '0') return Promise.resolve(BigNumber.from(0)); + + return tokenWrapperService.getTokenOutForTokenIn( + parseUnits(amount, decimals).toString(), + tokenWrapperAddress + ); + }, + queryKey: [tokenWrapperAddress, amount], + select: (data) => formatUnits(data.toString(), decimals), + enabled: tokenWrapperAddress !== '', + }); +}; diff --git a/src/hooks/useApprovedAmount.tsx b/src/hooks/useApprovedAmount.tsx index 6f8cb46366..9fee0b1649 100644 --- a/src/hooks/useApprovedAmount.tsx +++ b/src/hooks/useApprovedAmount.tsx @@ -3,14 +3,7 @@ import { useRootStore } from 'src/store/root'; import { QueryKeys } from 'src/ui-config/queries'; import { useSharedDependencies } from 'src/ui-config/SharedDependenciesProvider'; -export const useApprovedAmount = ({ - token, - spender, -}: { - user: string; - token: string; - spender: string; -}) => { +export const useApprovedAmount = (token: string, spender: string) => { const { approvedAmountService } = useSharedDependencies(); const user = useRootStore((store) => store.account); return useQuery({ diff --git a/src/locales/en/messages.js b/src/locales/en/messages.js index adaa452475..6a5d8f0abb 100644 --- a/src/locales/en/messages.js +++ b/src/locales/en/messages.js @@ -1 +1 @@ -/*eslint-disable*/module.exports={messages:{"...":"...",".CSV":".CSV",".JSON":".JSON","<0><1><2/>Add <3/> stkAAVE to borrow at <4/> (max discount)":"<0><1><2/>Add <3/> stkAAVE to borrow at <4/> (max discount)","<0><1><2/>Add stkAAVE to see borrow rate with discount":"<0><1><2/>Add stkAAVE to see borrow rate with discount","<0>Ampleforth is a rebasing asset. Visit the <1>documentation to learn more.":"<0>Ampleforth is a rebasing asset. Visit the <1>documentation to learn more.","<0>Attention: Parameter changes via governance can alter your account health factor and risk of liquidation. Follow the <1>Aave governance forum for updates.":"<0>Attention: Parameter changes via governance can alter your account health factor and risk of liquidation. Follow the <1>Aave governance forum for updates.","<0>Slippage tolerance <1>{selectedSlippage}% <2>{0}":["<0>Slippage tolerance <1>",["selectedSlippage"],"% <2>",["0"],""],"AAVE holders (Ethereum network only) can stake their AAVE in the Safety Module to add more security to the protocol and earn Safety Incentives. In the case of a shortfall event, up to 30% of your stake can be slashed to cover the deficit, providing an additional layer of protection for the protocol.":"AAVE holders (Ethereum network only) can stake their AAVE in the Safety Module to add more security to the protocol and earn Safety Incentives. In the case of a shortfall event, up to 30% of your stake can be slashed to cover the deficit, providing an additional layer of protection for the protocol.","APR":"APR","APY":"APY","APY change":"APY change","APY type":"APY type","APY type change":"APY type change","APY with discount applied":"APY with discount applied","APY, fixed rate":"APY, fixed rate","APY, stable":"APY, stable","APY, variable":"APY, variable","AToken supply is not zero":"AToken supply is not zero","Aave Governance":"Aave Governance","Aave aToken":"Aave aToken","Aave debt token":"Aave debt token","Aave is a fully decentralized, community governed protocol by the AAVE token-holders. AAVE token-holders collectively discuss, propose, and vote on upgrades to the protocol. AAVE token-holders (Ethereum network only) can either vote themselves on new proposals or delagate to an address of choice. To learn more check out the Governance":"Aave is a fully decentralized, community governed protocol by the AAVE token-holders. AAVE token-holders collectively discuss, propose, and vote on upgrades to the protocol. AAVE token-holders (Ethereum network only) can either vote themselves on new proposals or delagate to an address of choice. To learn more check out the Governance","Aave per month":"Aave per month","About GHO":"About GHO","Account":"Account","Action cannot be performed because the reserve is frozen":"Action cannot be performed because the reserve is frozen","Action cannot be performed because the reserve is paused":"Action cannot be performed because the reserve is paused","Action requires an active reserve":"Action requires an active reserve","Activate Cooldown":"Activate Cooldown","Add stkAAVE to see borrow APY with the discount":"Add stkAAVE to see borrow APY with the discount","Add to wallet":"Add to wallet","Add {0} to wallet to track your balance.":["Add ",["0"]," to wallet to track your balance."],"Address is not a contract":"Address is not a contract","Addresses":"Addresses","Addresses ({0})":["Addresses (",["0"],")"],"All Assets":"All Assets","All done!":"All done!","All proposals":"All proposals","All transactions":"All transactions","Allowance required action":"Allowance required action","Allows you to decide whether to use a supplied asset as collateral. An asset used as collateral will affect your borrowing power and health factor.":"Allows you to decide whether to use a supplied asset as collateral. An asset used as collateral will affect your borrowing power and health factor.","Allows you to switch between <0>variable and <1>stable interest rates, where variable rate can increase and decrease depending on the amount of liquidity in the reserve, and stable rate will stay the same for the duration of your loan.":"Allows you to switch between <0>variable and <1>stable interest rates, where variable rate can increase and decrease depending on the amount of liquidity in the reserve, and stable rate will stay the same for the duration of your loan.","Amount":"Amount","Amount claimable":"Amount claimable","Amount in cooldown":"Amount in cooldown","Amount must be greater than 0":"Amount must be greater than 0","Amount to unstake":"Amount to unstake","An error has occurred fetching the proposal metadata from IPFS.":"An error has occurred fetching the proposal metadata from IPFS.","Approve Confirmed":"Approve Confirmed","Approve with":"Approve with","Approve {symbol} to continue":["Approve ",["symbol"]," to continue"],"Approving {symbol}...":["Approving ",["symbol"],"..."],"Array parameters that should be equal length are not":"Array parameters that should be equal length are not","Asset":"Asset","Asset can be only used as collateral in isolation mode with limited borrowing power. To enter isolation mode, disable all other collateral.":"Asset can be only used as collateral in isolation mode with limited borrowing power. To enter isolation mode, disable all other collateral.","Asset can only be used as collateral in isolation mode only.":"Asset can only be used as collateral in isolation mode only.","Asset cannot be migrated because you have isolated collateral in {marketName} v3 Market which limits borrowable assets. You can manage your collateral in <0>{marketName} V3 Dashboard":["Asset cannot be migrated because you have isolated collateral in ",["marketName"]," v3 Market which limits borrowable assets. You can manage your collateral in <0>",["marketName"]," V3 Dashboard"],"Asset cannot be migrated due to insufficient liquidity or borrow cap limitation in {marketName} v3 market.":["Asset cannot be migrated due to insufficient liquidity or borrow cap limitation in ",["marketName"]," v3 market."],"Asset cannot be migrated due to supply cap restriction in {marketName} v3 market.":["Asset cannot be migrated due to supply cap restriction in ",["marketName"]," v3 market."],"Asset cannot be migrated to {marketName} V3 Market due to E-mode restrictions. You can disable or manage E-mode categories in your <0>V3 Dashboard":["Asset cannot be migrated to ",["marketName"]," V3 Market due to E-mode restrictions. You can disable or manage E-mode categories in your <0>V3 Dashboard"],"Asset cannot be migrated to {marketName} v3 Market since collateral asset will enable isolation mode.":["Asset cannot be migrated to ",["marketName"]," v3 Market since collateral asset will enable isolation mode."],"Asset cannot be used as collateral.":"Asset cannot be used as collateral.","Asset category":"Asset category","Asset is frozen in {marketName} v3 market, hence this position cannot be migrated.":["Asset is frozen in ",["marketName"]," v3 market, hence this position cannot be migrated."],"Asset is not borrowable in isolation mode":"Asset is not borrowable in isolation mode","Asset is not listed":"Asset is not listed","Asset supply is limited to a certain amount to reduce protocol exposure to the asset and to help manage risks involved.":"Asset supply is limited to a certain amount to reduce protocol exposure to the asset and to help manage risks involved.","Assets":"Assets","Assets to borrow":"Assets to borrow","Assets to supply":"Assets to supply","Assets with zero LTV ({assetsBlockingWithdraw}) must be withdrawn or disabled as collateral to perform this action":["Assets with zero LTV (",["assetsBlockingWithdraw"],") must be withdrawn or disabled as collateral to perform this action"],"At a discount":"At a discount","Author":"Author","Available":"Available","Available assets":"Available assets","Available liquidity":"Available liquidity","Available on":"Available on","Available rewards":"Available rewards","Available to borrow":"Available to borrow","Available to supply":"Available to supply","Back to Dashboard":"Back to Dashboard","Balance":"Balance","Balance to revoke":"Balance to revoke","Be careful - You are very close to liquidation. Consider depositing more collateral or paying down some of your borrowed positions":"Be careful - You are very close to liquidation. Consider depositing more collateral or paying down some of your borrowed positions","Be mindful of the network congestion and gas prices.":"Be mindful of the network congestion and gas prices.","Because this asset is paused, no actions can be taken until further notice":"Because this asset is paused, no actions can be taken until further notice","Before supplying":"Before supplying","Blocked Address":"Blocked Address","Borrow":"Borrow","Borrow APY":"Borrow APY","Borrow APY rate":"Borrow APY rate","Borrow APY, fixed rate":"Borrow APY, fixed rate","Borrow APY, stable":"Borrow APY, stable","Borrow APY, variable":"Borrow APY, variable","Borrow amount to reach {0}% utilization":["Borrow amount to reach ",["0"],"% utilization"],"Borrow and repay in same block is not allowed":"Borrow and repay in same block is not allowed","Borrow apy":"Borrow apy","Borrow balance":"Borrow balance","Borrow balance after repay":"Borrow balance after repay","Borrow balance after switch":"Borrow balance after switch","Borrow cap":"Borrow cap","Borrow cap is exceeded":"Borrow cap is exceeded","Borrow info":"Borrow info","Borrow power used":"Borrow power used","Borrow rate change":"Borrow rate change","Borrow {symbol}":["Borrow ",["symbol"]],"Borrowed":"Borrowed","Borrowed asset amount":"Borrowed asset amount","Borrowing is currently unavailable for {0}.":["Borrowing is currently unavailable for ",["0"],"."],"Borrowing is disabled due to an Aave community decision. <0>More details":"Borrowing is disabled due to an Aave community decision. <0>More details","Borrowing is not enabled":"Borrowing is not enabled","Borrowing is unavailable because you’re using Isolation mode. To manage Isolation mode visit your <0>Dashboard.":"Borrowing is unavailable because you’re using Isolation mode. To manage Isolation mode visit your <0>Dashboard.","Borrowing is unavailable because you’ve enabled Efficiency Mode (E-Mode) and Isolation mode. To manage E-Mode and Isolation mode visit your <0>Dashboard.":"Borrowing is unavailable because you’ve enabled Efficiency Mode (E-Mode) and Isolation mode. To manage E-Mode and Isolation mode visit your <0>Dashboard.","Borrowing is unavailable because you’ve enabled Efficiency Mode (E-Mode) for {0} category. To manage E-Mode categories visit your <0>Dashboard.":["Borrowing is unavailable because you’ve enabled Efficiency Mode (E-Mode) for ",["0"]," category. To manage E-Mode categories visit your <0>Dashboard."],"Borrowing of this asset is limited to a certain amount to minimize liquidity pool insolvency.":"Borrowing of this asset is limited to a certain amount to minimize liquidity pool insolvency.","Borrowing power and assets are limited due to Isolation mode.":"Borrowing power and assets are limited due to Isolation mode.","Borrowing this amount will reduce your health factor and increase risk of liquidation.":"Borrowing this amount will reduce your health factor and increase risk of liquidation.","Borrowing {symbol}":["Borrowing ",["symbol"]],"Both":"Both","Buy Crypto With Fiat":"Buy Crypto With Fiat","Buy Crypto with Fiat":"Buy Crypto with Fiat","Buy {cryptoSymbol} with Fiat":["Buy ",["cryptoSymbol"]," with Fiat"],"COPIED!":"COPIED!","COPY IMAGE":"COPY IMAGE","Can be collateral":"Can be collateral","Can be executed":"Can be executed","Cancel":"Cancel","Cannot disable E-Mode":"Cannot disable E-Mode","Choose how much voting/proposition power to give to someone else by delegating some of your AAVE or stkAAVE balance. Your tokens will remain in your account, but your delegate will be able to vote or propose on your behalf. If your AAVE or stkAAVE balance changes, your delegate's voting/proposition power will be automatically adjusted.":"Choose how much voting/proposition power to give to someone else by delegating some of your AAVE or stkAAVE balance. Your tokens will remain in your account, but your delegate will be able to vote or propose on your behalf. If your AAVE or stkAAVE balance changes, your delegate's voting/proposition power will be automatically adjusted.","Choose one of the on-ramp services":"Choose one of the on-ramp services","Claim":"Claim","Claim all":"Claim all","Claim all rewards":"Claim all rewards","Claim {0}":["Claim ",["0"]],"Claim {symbol}":["Claim ",["symbol"]],"Claimable AAVE":"Claimable AAVE","Claimed":"Claimed","Claiming":"Claiming","Claiming {symbol}":["Claiming ",["symbol"]],"Close":"Close","Collateral":"Collateral","Collateral balance after repay":"Collateral balance after repay","Collateral change":"Collateral change","Collateral is (mostly) the same currency that is being borrowed":"Collateral is (mostly) the same currency that is being borrowed","Collateral to repay with":"Collateral to repay with","Collateral usage":"Collateral usage","Collateral usage is limited because of Isolation mode.":"Collateral usage is limited because of Isolation mode.","Collateral usage is limited because of isolation mode.":"Collateral usage is limited because of isolation mode.","Collateral usage is limited because of isolation mode. <0>Learn More":"Collateral usage is limited because of isolation mode. <0>Learn More","Collateralization":"Collateralization","Collector Contract":"Collector Contract","Collector Info":"Collector Info","Connect wallet":"Connect wallet","Cooldown period":"Cooldown period","Cooldown period warning":"Cooldown period warning","Cooldown time left":"Cooldown time left","Cooldown to unstake":"Cooldown to unstake","Cooling down...":"Cooling down...","Copy address":"Copy address","Copy error message":"Copy error message","Copy error text":"Copy error text","Covered debt":"Covered debt","Created":"Created","Current LTV":"Current LTV","Current differential":"Current differential","Current v2 Balance":"Current v2 Balance","Current v2 balance":"Current v2 balance","Current votes":"Current votes","Dark mode":"Dark mode","Dashboard":"Dashboard","Data couldn't be fetched, please reload graph.":"Data couldn't be fetched, please reload graph.","Debt":"Debt","Debt ceiling is exceeded":"Debt ceiling is exceeded","Debt ceiling is not zero":"Debt ceiling is not zero","Debt ceiling limits the amount possible to borrow against this asset by protocol users. Debt ceiling is specific to assets in isolation mode and is denoted in USD.":"Debt ceiling limits the amount possible to borrow against this asset by protocol users. Debt ceiling is specific to assets in isolation mode and is denoted in USD.","Delegated power":"Delegated power","Details":"Details","Developers":"Developers","Differential":"Differential","Disable E-Mode":"Disable E-Mode","Disable testnet":"Disable testnet","Disable {symbol} as collateral":["Disable ",["symbol"]," as collateral"],"Disabled":"Disabled","Disabling E-Mode":"Disabling E-Mode","Disabling this asset as collateral affects your borrowing power and Health Factor.":"Disabling this asset as collateral affects your borrowing power and Health Factor.","Disconnect Wallet":"Disconnect Wallet","Discord channel":"Discord channel","Discount":"Discount","Discount applied for <0/> staking AAVE":"Discount applied for <0/> staking AAVE","Discount model parameters":"Discount model parameters","Discount parameters are decided by the Aave community and may be changed over time. Check Governance for updates and vote to participate. <0>Learn more":"Discount parameters are decided by the Aave community and may be changed over time. Check Governance for updates and vote to participate. <0>Learn more","Discountable amount":"Discountable amount","Docs":"Docs","Download":"Download","Due to internal stETH mechanics required for rebasing support, it is not possible to perform a collateral switch where stETH is the source token.":"Due to internal stETH mechanics required for rebasing support, it is not possible to perform a collateral switch where stETH is the source token.","Due to the Horizon bridge exploit, certain assets on the Harmony network are not at parity with Ethereum, which affects the Aave V3 Harmony market.":"Due to the Horizon bridge exploit, certain assets on the Harmony network are not at parity with Ethereum, which affects the Aave V3 Harmony market.","E-Mode":"E-Mode","E-Mode Category":"E-Mode Category","E-Mode category":"E-Mode category","E-Mode increases your LTV for a selected category of assets up to 97%. <0>Learn more":"E-Mode increases your LTV for a selected category of assets up to 97%. <0>Learn more","E-Mode increases your LTV for a selected category of assets up to<0/>. <1>Learn more":"E-Mode increases your LTV for a selected category of assets up to<0/>. <1>Learn more","E-Mode increases your LTV for a selected category of assets, meaning that when E-mode is enabled, you will have higher borrowing power over assets of the same E-mode category which are defined by Aave Governance. You can enter E-Mode from your <0>Dashboard. To learn more about E-Mode and applied restrictions in <1>FAQ or <2>Aave V3 Technical Paper.":"E-Mode increases your LTV for a selected category of assets, meaning that when E-mode is enabled, you will have higher borrowing power over assets of the same E-mode category which are defined by Aave Governance. You can enter E-Mode from your <0>Dashboard. To learn more about E-Mode and applied restrictions in <1>FAQ or <2>Aave V3 Technical Paper.","Effective interest rate":"Effective interest rate","Efficiency mode (E-Mode)":"Efficiency mode (E-Mode)","Emode":"Emode","Enable E-Mode":"Enable E-Mode","Enable {symbol} as collateral":["Enable ",["symbol"]," as collateral"],"Enabled":"Enabled","Enabling E-Mode":"Enabling E-Mode","Enabling E-Mode only allows you to borrow assets belonging to the selected category. Please visit our <0>FAQ guide to learn more about how it works and the applied restrictions.":"Enabling E-Mode only allows you to borrow assets belonging to the selected category. Please visit our <0>FAQ guide to learn more about how it works and the applied restrictions.","Enabling this asset as collateral increases your borrowing power and Health Factor. However, it can get liquidated if your health factor drops below 1.":"Enabling this asset as collateral increases your borrowing power and Health Factor. However, it can get liquidated if your health factor drops below 1.","Ended":"Ended","Ends":"Ends","English":"English","Enter ETH address":"Enter ETH address","Enter an amount":"Enter an amount","Error connecting. Try refreshing the page.":"Error connecting. Try refreshing the page.","Estimated compounding interest, including discount for Staking {0}AAVE in Safety Module.":["Estimated compounding interest, including discount for Staking ",["0"],"AAVE in Safety Module."],"Exceeds the discount":"Exceeds the discount","Executed":"Executed","Expected amount to repay":"Expected amount to repay","Expires":"Expires","Export data to":"Export data to","FAQ":"FAQ","FAQS":"FAQS","Failed to load proposal voters. Please refresh the page.":"Failed to load proposal voters. Please refresh the page.","Faucet":"Faucet","Faucet {0}":["Faucet ",["0"]],"Fetching data...":"Fetching data...","Filter":"Filter","Fixed":"Fixed","Fixed rate":"Fixed rate","Flashloan is disabled for this asset, hence this position cannot be migrated.":"Flashloan is disabled for this asset, hence this position cannot be migrated.","For repayment of a specific type of debt, the user needs to have debt that type":"For repayment of a specific type of debt, the user needs to have debt that type","Forum discussion":"Forum discussion","French":"French","Funds in the Safety Module":"Funds in the Safety Module","GHO is a native decentralized, collateral-backed digital asset pegged to USD. It is created by users via borrowing against multiple collateral. When user repays their GHO borrow position, the protocol burns that user's GHO. All the interest payments accrued by minters of GHO would be directly transferred to the AaveDAO treasury.":"GHO is a native decentralized, collateral-backed digital asset pegged to USD. It is created by users via borrowing against multiple collateral. When user repays their GHO borrow position, the protocol burns that user's GHO. All the interest payments accrued by minters of GHO would be directly transferred to the AaveDAO treasury.","Get ABP Token":"Get ABP Token","Global settings":"Global settings","Go Back":"Go Back","Go to Balancer Pool":"Go to Balancer Pool","Go to V3 Dashboard":"Go to V3 Dashboard","Governance":"Governance","Greek":"Greek","Health Factor ({0} v2)":["Health Factor (",["0"]," v2)"],"Health Factor ({0} v3)":["Health Factor (",["0"]," v3)"],"Health factor":"Health factor","Health factor is lesser than the liquidation threshold":"Health factor is lesser than the liquidation threshold","Health factor is not below the threshold":"Health factor is not below the threshold","Hide":"Hide","Holders of stkAAVE receive a discount on the GHO borrowing rate":"Holders of stkAAVE receive a discount on the GHO borrowing rate","I acknowledge the risks involved.":"I acknowledge the risks involved.","I fully understand the risks of migrating.":"I fully understand the risks of migrating.","I understand how cooldown ({0}) and unstaking ({1}) work":["I understand how cooldown (",["0"],") and unstaking (",["1"],") work"],"If the error continues to happen,<0/> you may report it to this":"If the error continues to happen,<0/> you may report it to this","If the health factor goes below 1, the liquidation of your collateral might be triggered.":"If the health factor goes below 1, the liquidation of your collateral might be triggered.","If you DO NOT unstake within {0} of unstake window, you will need to activate cooldown process again.":["If you DO NOT unstake within ",["0"]," of unstake window, you will need to activate cooldown process again."],"If your loan to value goes above the liquidation threshold your collateral supplied may be liquidated.":"If your loan to value goes above the liquidation threshold your collateral supplied may be liquidated.","In E-Mode some assets are not borrowable. Exit E-Mode to get access to all assets":"In E-Mode some assets are not borrowable. Exit E-Mode to get access to all assets","In Isolation mode, you cannot supply other assets as collateral. A global debt ceiling limits the borrowing power of the isolated asset. To exit isolation mode disable {0} as collateral before borrowing another asset. Read more in our <0>FAQ":["In Isolation mode, you cannot supply other assets as collateral. A global debt ceiling limits the borrowing power of the isolated asset. To exit isolation mode disable ",["0"]," as collateral before borrowing another asset. Read more in our <0>FAQ"],"Inconsistent flashloan parameters":"Inconsistent flashloan parameters","Insufficient collateral to cover new borrow position. Wallet must have borrowing power remaining to perform debt switch.":"Insufficient collateral to cover new borrow position. Wallet must have borrowing power remaining to perform debt switch.","Interest accrued":"Interest accrued","Interest rate rebalance conditions were not met":"Interest rate rebalance conditions were not met","Interest rate strategy":"Interest rate strategy","Invalid amount to burn":"Invalid amount to burn","Invalid amount to mint":"Invalid amount to mint","Invalid bridge protocol fee":"Invalid bridge protocol fee","Invalid expiration":"Invalid expiration","Invalid flashloan premium":"Invalid flashloan premium","Invalid return value of the flashloan executor function":"Invalid return value of the flashloan executor function","Invalid signature":"Invalid signature","Isolated":"Isolated","Isolated Debt Ceiling":"Isolated Debt Ceiling","Isolated assets have limited borrowing power and other assets cannot be used as collateral.":"Isolated assets have limited borrowing power and other assets cannot be used as collateral.","Join the community discussion":"Join the community discussion","LEARN MORE":"LEARN MORE","Language":"Language","Learn more":"Learn more","Learn more about risks involved":"Learn more about risks involved","Learn more in our <0>FAQ guide":"Learn more in our <0>FAQ guide","Learn more.":"Learn more.","Links":"Links","Liqudation":"Liqudation","Liquidated collateral":"Liquidated collateral","Liquidation":"Liquidation","Liquidation <0/> threshold":"Liquidation <0/> threshold","Liquidation Threshold":"Liquidation Threshold","Liquidation at":"Liquidation at","Liquidation penalty":"Liquidation penalty","Liquidation risk":"Liquidation risk","Liquidation risk parameters":"Liquidation risk parameters","Liquidation threshold":"Liquidation threshold","Liquidation value":"Liquidation value","Loading data...":"Loading data...","Ltv validation failed":"Ltv validation failed","MAI has been paused due to a community decision. Supply, borrows and repays are impacted. <0>More details":"MAI has been paused due to a community decision. Supply, borrows and repays are impacted. <0>More details","MAX":"MAX","Manage analytics":"Manage analytics","Market":"Market","Markets":"Markets","Max":"Max","Max LTV":"Max LTV","Max slashing":"Max slashing","Max slippage":"Max slippage","Maximum amount available to borrow against this asset is limited because debt ceiling is at {0}%.":["Maximum amount available to borrow against this asset is limited because debt ceiling is at ",["0"],"%."],"Maximum amount available to borrow is <0/> {0} (<1/>).":["Maximum amount available to borrow is <0/> ",["0"]," (<1/>)."],"Maximum amount available to borrow is limited because protocol borrow cap is nearly reached.":"Maximum amount available to borrow is limited because protocol borrow cap is nearly reached.","Maximum amount available to supply is <0/> {0} (<1/>).":["Maximum amount available to supply is <0/> ",["0"]," (<1/>)."],"Maximum amount available to supply is limited because protocol supply cap is at {0}%.":["Maximum amount available to supply is limited because protocol supply cap is at ",["0"],"%."],"Maximum loan to value":"Maximum loan to value","Meet GHO":"Meet GHO","Menu":"Menu","Migrate":"Migrate","Migrate to V3":"Migrate to V3","Migrate to v3":"Migrate to v3","Migrate to {0} v3 Market":["Migrate to ",["0"]," v3 Market"],"Migrated":"Migrated","Migrating":"Migrating","Migrating multiple collaterals and borrowed assets at the same time can be an expensive operation and might fail in certain situations.<0>Therefore it’s not recommended to migrate positions with more than 5 assets (deposited + borrowed) at the same time.":"Migrating multiple collaterals and borrowed assets at the same time can be an expensive operation and might fail in certain situations.<0>Therefore it’s not recommended to migrate positions with more than 5 assets (deposited + borrowed) at the same time.","Migration risks":"Migration risks","Minimum GHO borrow amount":"Minimum GHO borrow amount","Minimum USD value received":"Minimum USD value received","Minimum staked Aave amount":"Minimum staked Aave amount","Minimum {0} received":["Minimum ",["0"]," received"],"More":"More","NAY":"NAY","Need help connecting a wallet? <0>Read our FAQ":"Need help connecting a wallet? <0>Read our FAQ","Net APR":"Net APR","Net APY":"Net APY","Net APY is the combined effect of all supply and borrow positions on net worth, including incentives. It is possible to have a negative net APY if debt APY is higher than supply APY.":"Net APY is the combined effect of all supply and borrow positions on net worth, including incentives. It is possible to have a negative net APY if debt APY is higher than supply APY.","Net worth":"Net worth","Network":"Network","Network not supported for this wallet":"Network not supported for this wallet","New APY":"New APY","No assets selected to migrate.":"No assets selected to migrate.","No rewards to claim":"No rewards to claim","No search results{0}":["No search results",["0"]],"No transactions yet.":"No transactions yet.","No voting power":"No voting power","None":"None","Not a valid address":"Not a valid address","Not enough balance on your wallet":"Not enough balance on your wallet","Not enough collateral to repay this amount of debt with":"Not enough collateral to repay this amount of debt with","Not enough staked balance":"Not enough staked balance","Not enough voting power to participate in this proposal":"Not enough voting power to participate in this proposal","Not reached":"Not reached","Nothing borrowed yet":"Nothing borrowed yet","Nothing found":"Nothing found","Nothing staked":"Nothing staked","Nothing supplied yet":"Nothing supplied yet","Notify":"Notify","Ok, Close":"Ok, Close","Ok, I got it":"Ok, I got it","Operation not supported":"Operation not supported","Oracle price":"Oracle price","Overview":"Overview","Page not found":"Page not found","Participating in this {symbol} reserve gives annualized rewards.":["Participating in this ",["symbol"]," reserve gives annualized rewards."],"Pending...":"Pending...","Per the community, the Fantom market has been frozen.":"Per the community, the Fantom market has been frozen.","Per the community, the V2 AMM market has been deprecated.":"Per the community, the V2 AMM market has been deprecated.","Please always be aware of your <0>Health Factor (HF) when partially migrating a position and that your rates will be updated to V3 rates.":"Please always be aware of your <0>Health Factor (HF) when partially migrating a position and that your rates will be updated to V3 rates.","Please connect a wallet to view your personal information here.":"Please connect a wallet to view your personal information here.","Please connect your wallet to be able to switch your tokens.":"Please connect your wallet to be able to switch your tokens.","Please connect your wallet to get free testnet assets.":"Please connect your wallet to get free testnet assets.","Please connect your wallet to see migration tool.":"Please connect your wallet to see migration tool.","Please connect your wallet to see your supplies, borrowings, and open positions.":"Please connect your wallet to see your supplies, borrowings, and open positions.","Please connect your wallet to view transaction history.":"Please connect your wallet to view transaction history.","Please enter a valid wallet address.":"Please enter a valid wallet address.","Please switch to {networkName}.":["Please switch to ",["networkName"],"."],"Please, connect your wallet":"Please, connect your wallet","Pool addresses provider is not registered":"Pool addresses provider is not registered","Powered by":"Powered by","Preview tx and migrate":"Preview tx and migrate","Price":"Price","Price data is not currently available for this reserve on the protocol subgraph":"Price data is not currently available for this reserve on the protocol subgraph","Price impact":"Price impact","Price impact is the spread between the total value of the entry tokens switched and the destination tokens obtained (in USD), which results from the limited liquidity of the trading pair.":"Price impact is the spread between the total value of the entry tokens switched and the destination tokens obtained (in USD), which results from the limited liquidity of the trading pair.","Price impact {0}%":["Price impact ",["0"],"%"],"Privacy":"Privacy","Proposal details":"Proposal details","Proposal overview":"Proposal overview","Proposals":"Proposals","Proposition":"Proposition","Protocol borrow cap at 100% for this asset. Further borrowing unavailable.":"Protocol borrow cap at 100% for this asset. Further borrowing unavailable.","Protocol borrow cap is at 100% for this asset. Further borrowing unavailable.":"Protocol borrow cap is at 100% for this asset. Further borrowing unavailable.","Protocol debt ceiling is at 100% for this asset. Further borrowing against this asset is unavailable.":"Protocol debt ceiling is at 100% for this asset. Further borrowing against this asset is unavailable.","Protocol debt ceiling is at 100% for this asset. Futher borrowing against this asset is unavailable.":"Protocol debt ceiling is at 100% for this asset. Futher borrowing against this asset is unavailable.","Protocol supply cap at 100% for this asset. Further supply unavailable.":"Protocol supply cap at 100% for this asset. Further supply unavailable.","Protocol supply cap is at 100% for this asset. Further supply unavailable.":"Protocol supply cap is at 100% for this asset. Further supply unavailable.","Quorum":"Quorum","Rate change":"Rate change","Raw-Ipfs":"Raw-Ipfs","Reached":"Reached","Reactivate cooldown period to unstake {0} {stakedToken}":["Reactivate cooldown period to unstake ",["0"]," ",["stakedToken"]],"Read more here.":"Read more here.","Read-only mode allows to see address positions in Aave, but you won't be able to perform transactions.":"Read-only mode allows to see address positions in Aave, but you won't be able to perform transactions.","Read-only mode.":"Read-only mode.","Read-only mode. Connect to a wallet to perform transactions.":"Read-only mode. Connect to a wallet to perform transactions.","Receive (est.)":"Receive (est.)","Received":"Received","Recipient address":"Recipient address","Rejected connection request":"Rejected connection request","Reload":"Reload","Reload the page":"Reload the page","Remaining debt":"Remaining debt","Remaining supply":"Remaining supply","Repaid":"Repaid","Repay":"Repay","Repay with":"Repay with","Repay {symbol}":["Repay ",["symbol"]],"Repaying {symbol}":["Repaying ",["symbol"]],"Repayment amount to reach {0}% utilization":["Repayment amount to reach ",["0"],"% utilization"],"Reserve Size":"Reserve Size","Reserve factor":"Reserve factor","Reserve factor is a percentage of interest which goes to a {0} that is controlled by Aave governance to promote ecosystem growth.":["Reserve factor is a percentage of interest which goes to a ",["0"]," that is controlled by Aave governance to promote ecosystem growth."],"Reserve status & configuration":"Reserve status & configuration","Reset":"Reset","Restake":"Restake","Restake {symbol}":["Restake ",["symbol"]],"Restaked":"Restaked","Restaking {symbol}":["Restaking ",["symbol"]],"Review approval tx details":"Review approval tx details","Review changes to continue":"Review changes to continue","Review tx":"Review tx","Review tx details":"Review tx details","Revoke power":"Revoke power","Reward(s) to claim":"Reward(s) to claim","Rewards APR":"Rewards APR","Risk details":"Risk details","SEE CHARTS":"SEE CHARTS","Safety of your deposited collateral against the borrowed assets and its underlying value.":"Safety of your deposited collateral against the borrowed assets and its underlying value.","Save and share":"Save and share","Seatbelt report":"Seatbelt report","Seems like we can't switch the network automatically. Please check if you can change it from the wallet.":"Seems like we can't switch the network automatically. Please check if you can change it from the wallet.","Select":"Select","Select APY type to switch":"Select APY type to switch","Select an asset":"Select an asset","Select language":"Select language","Select slippage tolerance":"Select slippage tolerance","Select v2 borrows to migrate":"Select v2 borrows to migrate","Select v2 supplies to migrate":"Select v2 supplies to migrate","Selected assets have successfully migrated. Visit the Market Dashboard to see them.":"Selected assets have successfully migrated. Visit the Market Dashboard to see them.","Selected borrow assets":"Selected borrow assets","Selected supply assets":"Selected supply assets","Send feedback":"Send feedback","Set up delegation":"Set up delegation","Setup notifications about your Health Factor using the Hal app.":"Setup notifications about your Health Factor using the Hal app.","Share on Lens":"Share on Lens","Share on twitter":"Share on twitter","Show":"Show","Show Frozen or paused assets":"Show Frozen or paused assets","Show assets with 0 balance":"Show assets with 0 balance","Sign to continue":"Sign to continue","Signatures ready":"Signatures ready","Signing":"Signing","Since this asset is frozen, the only available actions are withdraw and repay which can be accessed from the <0>Dashboard":"Since this asset is frozen, the only available actions are withdraw and repay which can be accessed from the <0>Dashboard","Since this is a test network, you can get any of the assets if you have ETH on your wallet":"Since this is a test network, you can get any of the assets if you have ETH on your wallet","Slippage":"Slippage","Slippage is the difference between the quoted and received amounts from changing market conditions between the moment the transaction is submitted and its verification.":"Slippage is the difference between the quoted and received amounts from changing market conditions between the moment the transaction is submitted and its verification.","Some migrated assets will not be used as collateral due to enabled isolation mode in {marketName} V3 Market. Visit <0>{marketName} V3 Dashboard to manage isolation mode.":["Some migrated assets will not be used as collateral due to enabled isolation mode in ",["marketName"]," V3 Market. Visit <0>",["marketName"]," V3 Dashboard to manage isolation mode."],"Something went wrong":"Something went wrong","Sorry, an unexpected error happened. In the meantime you may try reloading the page, or come back later.":"Sorry, an unexpected error happened. In the meantime you may try reloading the page, or come back later.","Sorry, we couldn't find the page you were looking for.":"Sorry, we couldn't find the page you were looking for.","Spanish":"Spanish","Stable":"Stable","Stable Interest Type is disabled for this currency":"Stable Interest Type is disabled for this currency","Stable borrowing is enabled":"Stable borrowing is enabled","Stable borrowing is not enabled":"Stable borrowing is not enabled","Stable debt supply is not zero":"Stable debt supply is not zero","Stable interest rate will <0>stay the same for the duration of your loan. Recommended for long-term loan periods and for users who prefer predictability.":"Stable interest rate will <0>stay the same for the duration of your loan. Recommended for long-term loan periods and for users who prefer predictability.","Stablecoin":"Stablecoin","Stake":"Stake","Stake AAVE":"Stake AAVE","Stake ABPT":"Stake ABPT","Stake cooldown activated":"Stake cooldown activated","Staked":"Staked","Staking":"Staking","Staking APR":"Staking APR","Staking Rewards":"Staking Rewards","Staking balance":"Staking balance","Staking discount":"Staking discount","Started":"Started","State":"State","Static interest rate that is determined by Aave Governance. This rate may be changed over time depending on the need for the GHO supply to contract/expand. <0>Learn more":"Static interest rate that is determined by Aave Governance. This rate may be changed over time depending on the need for the GHO supply to contract/expand. <0>Learn more","Supplied":"Supplied","Supplied asset amount":"Supplied asset amount","Supply":"Supply","Supply APY":"Supply APY","Supply apy":"Supply apy","Supply balance":"Supply balance","Supply balance after switch":"Supply balance after switch","Supply cap is exceeded":"Supply cap is exceeded","Supply cap on target reserve reached. Try lowering the amount.":"Supply cap on target reserve reached. Try lowering the amount.","Supply {symbol}":["Supply ",["symbol"]],"Supplying your":"Supplying your","Supplying {symbol}":["Supplying ",["symbol"]],"Switch":"Switch","Switch APY type":"Switch APY type","Switch E-Mode":"Switch E-Mode","Switch E-Mode category":"Switch E-Mode category","Switch Network":"Switch Network","Switch borrow position":"Switch borrow position","Switch rate":"Switch rate","Switch to":"Switch to","Switched":"Switched","Switching":"Switching","Switching E-Mode":"Switching E-Mode","Switching rate":"Switching rate","Techpaper":"Techpaper","Terms":"Terms","Test Assets":"Test Assets","Testnet mode":"Testnet mode","Testnet mode is ON":"Testnet mode is ON","Thank you for voting!!":"Thank you for voting!!","The % of your total borrowing power used. This is based on the amount of your collateral supplied and the total amount that you can borrow.":"The % of your total borrowing power used. This is based on the amount of your collateral supplied and the total amount that you can borrow.","The Aave Balancer Pool Token (ABPT) is a liquidity pool token. You can receive ABPT by depositing a combination of AAVE + ETH in the Balancer liquidity pool. You can then stake your BPT in the Safety Module to secure the protocol and earn Safety Incentives.":"The Aave Balancer Pool Token (ABPT) is a liquidity pool token. You can receive ABPT by depositing a combination of AAVE + ETH in the Balancer liquidity pool. You can then stake your BPT in the Safety Module to secure the protocol and earn Safety Incentives.","The Aave Protocol is programmed to always use the price of 1 GHO = $1. This is different from using market pricing via oracles for other crypto assets. This creates stabilizing arbitrage opportunities when the price of GHO fluctuates.":"The Aave Protocol is programmed to always use the price of 1 GHO = $1. This is different from using market pricing via oracles for other crypto assets. This creates stabilizing arbitrage opportunities when the price of GHO fluctuates.","The Maximum LTV ratio represents the maximum borrowing power of a specific collateral. For example, if a collateral has an LTV of 75%, the user can borrow up to 0.75 worth of ETH in the principal currency for every 1 ETH worth of collateral.":"The Maximum LTV ratio represents the maximum borrowing power of a specific collateral. For example, if a collateral has an LTV of 75%, the user can borrow up to 0.75 worth of ETH in the principal currency for every 1 ETH worth of collateral.","The Stable Rate is not enabled for this currency":"The Stable Rate is not enabled for this currency","The address of the pool addresses provider is invalid":"The address of the pool addresses provider is invalid","The app is running in testnet mode. Learn how it works in":"The app is running in testnet mode. Learn how it works in","The caller of the function is not an AToken":"The caller of the function is not an AToken","The caller of this function must be a pool":"The caller of this function must be a pool","The collateral balance is 0":"The collateral balance is 0","The collateral chosen cannot be liquidated":"The collateral chosen cannot be liquidated","The cooldown period is the time required prior to unstaking your tokens (20 days). You can only withdraw your assets from the Security Module after the cooldown period and within the unstake window.<0>Learn more":"The cooldown period is the time required prior to unstaking your tokens (20 days). You can only withdraw your assets from the Security Module after the cooldown period and within the unstake window.<0>Learn more","The cooldown period is {0}. After {1} of cooldown, you will enter unstake window of {2}. You will continue receiving rewards during cooldown and unstake window.":["The cooldown period is ",["0"],". After ",["1"]," of cooldown, you will enter unstake window of ",["2"],". You will continue receiving rewards during cooldown and unstake window."],"The effects on the health factor would cause liquidation. Try lowering the amount.":"The effects on the health factor would cause liquidation. Try lowering the amount.","The loan to value of the migrated positions would cause liquidation. Increase migrated collateral or reduce migrated borrow to continue.":"The loan to value of the migrated positions would cause liquidation. Increase migrated collateral or reduce migrated borrow to continue.","The requested amount is greater than the max loan size in stable rate mode":"The requested amount is greater than the max loan size in stable rate mode","The total amount of your assets denominated in USD that can be used as collateral for borrowing assets.":"The total amount of your assets denominated in USD that can be used as collateral for borrowing assets.","The underlying asset cannot be rescued":"The underlying asset cannot be rescued","The underlying balance needs to be greater than 0":"The underlying balance needs to be greater than 0","The weighted average of APY for all borrowed assets, including incentives.":"The weighted average of APY for all borrowed assets, including incentives.","The weighted average of APY for all supplied assets, including incentives.":"The weighted average of APY for all supplied assets, including incentives.","There are not enough funds in the{0}reserve to borrow":["There are not enough funds in the",["0"],"reserve to borrow"],"There is not enough collateral to cover a new borrow":"There is not enough collateral to cover a new borrow","There is not enough liquidity for the target asset to perform the switch. Try lowering the amount.":"There is not enough liquidity for the target asset to perform the switch. Try lowering the amount.","There was some error. Please try changing the parameters or <0><1>copy the error":"There was some error. Please try changing the parameters or <0><1>copy the error","These assets are temporarily frozen or paused by Aave community decisions, meaning that further supply / borrow, or rate swap of these assets are unavailable. Withdrawals and debt repayments are allowed. Follow the <0>Aave governance forum for further updates.":"These assets are temporarily frozen or paused by Aave community decisions, meaning that further supply / borrow, or rate swap of these assets are unavailable. Withdrawals and debt repayments are allowed. Follow the <0>Aave governance forum for further updates.","These funds have been borrowed and are not available for withdrawal at this time.":"These funds have been borrowed and are not available for withdrawal at this time.","This action will reduce V2 health factor below liquidation threshold. retain collateral or migrate borrow position to continue.":"This action will reduce V2 health factor below liquidation threshold. retain collateral or migrate borrow position to continue.","This action will reduce health factor of V3 below liquidation threshold. Increase migrated collateral or reduce migrated borrow to continue.":"This action will reduce health factor of V3 below liquidation threshold. Increase migrated collateral or reduce migrated borrow to continue.","This action will reduce your health factor. Please be mindful of the increased risk of collateral liquidation.":"This action will reduce your health factor. Please be mindful of the increased risk of collateral liquidation.","This address is blocked on app.aave.com because it is associated with one or more":"This address is blocked on app.aave.com because it is associated with one or more","This asset has almost reached its borrow cap. There is only {messageValue} available to be borrowed from this market.":["This asset has almost reached its borrow cap. There is only ",["messageValue"]," available to be borrowed from this market."],"This asset has almost reached its supply cap. There can only be {messageValue} supplied to this market.":["This asset has almost reached its supply cap. There can only be ",["messageValue"]," supplied to this market."],"This asset has reached its borrow cap. Nothing is available to be borrowed from this market.":"This asset has reached its borrow cap. Nothing is available to be borrowed from this market.","This asset has reached its supply cap. Nothing is available to be supplied from this market.":"This asset has reached its supply cap. Nothing is available to be supplied from this market.","This asset is frozen due to an Aave Protocol Governance decision. <0>More details":"This asset is frozen due to an Aave Protocol Governance decision. <0>More details","This asset is frozen due to an Aave Protocol Governance decision. On the 20th of December 2022, renFIL will no longer be supported and cannot be bridged back to its native network. It is recommended to withdraw supply positions and repay borrow positions so that renFIL can be bridged back to FIL before the deadline. After this date, it will no longer be possible to convert renFIL to FIL. <0>More details":"This asset is frozen due to an Aave Protocol Governance decision. On the 20th of December 2022, renFIL will no longer be supported and cannot be bridged back to its native network. It is recommended to withdraw supply positions and repay borrow positions so that renFIL can be bridged back to FIL before the deadline. After this date, it will no longer be possible to convert renFIL to FIL. <0>More details","This asset is frozen due to an Aave community decision. <0>More details":"This asset is frozen due to an Aave community decision. <0>More details","This asset is planned to be offboarded due to an Aave Protocol Governance decision. <0>More details":"This asset is planned to be offboarded due to an Aave Protocol Governance decision. <0>More details","This gas calculation is only an estimation. Your wallet will set the price of the transaction. You can modify the gas settings directly from your wallet provider.":"This gas calculation is only an estimation. Your wallet will set the price of the transaction. You can modify the gas settings directly from your wallet provider.","This integration was<0>proposed and approvedby the community.":"This integration was<0>proposed and approvedby the community.","This is the total amount available for you to borrow. You can borrow based on your collateral and until the borrow cap is reached.":"This is the total amount available for you to borrow. You can borrow based on your collateral and until the borrow cap is reached.","This is the total amount that you are able to supply to in this reserve. You are able to supply your wallet balance up until the supply cap is reached.":"This is the total amount that you are able to supply to in this reserve. You are able to supply your wallet balance up until the supply cap is reached.","This represents the threshold at which a borrow position will be considered undercollateralized and subject to liquidation for each collateral. For example, if a collateral has a liquidation threshold of 80%, it means that the position will be liquidated when the debt value is worth 80% of the collateral value.":"This represents the threshold at which a borrow position will be considered undercollateralized and subject to liquidation for each collateral. For example, if a collateral has a liquidation threshold of 80%, it means that the position will be liquidated when the debt value is worth 80% of the collateral value.","Time left to be able to withdraw your staked asset.":"Time left to be able to withdraw your staked asset.","Time left to unstake":"Time left to unstake","Time left until the withdrawal window closes.":"Time left until the withdrawal window closes.","Tip: Try increasing slippage or reduce input amount":"Tip: Try increasing slippage or reduce input amount","To borrow you need to supply any asset to be used as collateral.":"To borrow you need to supply any asset to be used as collateral.","To continue, you need to grant Aave smart contracts permission to move your funds from your wallet. Depending on the asset and wallet you use, it is done by signing the permission message (gas free), or by submitting an approval transaction (requires gas). <0>Learn more":"To continue, you need to grant Aave smart contracts permission to move your funds from your wallet. Depending on the asset and wallet you use, it is done by signing the permission message (gas free), or by submitting an approval transaction (requires gas). <0>Learn more","To enable E-mode for the {0} category, all borrow positions outside of this category must be closed.":["To enable E-mode for the ",["0"]," category, all borrow positions outside of this category must be closed."],"To repay on behalf of a user an explicit amount to repay is needed":"To repay on behalf of a user an explicit amount to repay is needed","To request access for this permissioned market, please visit: <0>Acces Provider Name":"To request access for this permissioned market, please visit: <0>Acces Provider Name","To submit a proposal for minor changes to the protocol, you'll need at least 80.00K power. If you want to change the core code base, you'll need 320k power.<0>Learn more.":"To submit a proposal for minor changes to the protocol, you'll need at least 80.00K power. If you want to change the core code base, you'll need 320k power.<0>Learn more.","Top 10 addresses":"Top 10 addresses","Total available":"Total available","Total borrowed":"Total borrowed","Total borrows":"Total borrows","Total emission per day":"Total emission per day","Total interest accrued":"Total interest accrued","Total market size":"Total market size","Total supplied":"Total supplied","Total voting power":"Total voting power","Total worth":"Total worth","Track wallet":"Track wallet","Track wallet balance in read-only mode":"Track wallet balance in read-only mode","Transaction failed":"Transaction failed","Transaction history":"Transaction history","Transaction history is not currently available for this market":"Transaction history is not currently available for this market","Transaction overview":"Transaction overview","Transactions":"Transactions","UNSTAKE {symbol}":["UNSTAKE ",["symbol"]],"Unavailable":"Unavailable","Unbacked":"Unbacked","Unbacked mint cap is exceeded":"Unbacked mint cap is exceeded","Underlying asset does not exist in {marketName} v3 Market, hence this position cannot be migrated.":["Underlying asset does not exist in ",["marketName"]," v3 Market, hence this position cannot be migrated."],"Underlying token":"Underlying token","Unstake now":"Unstake now","Unstake window":"Unstake window","Unstaked":"Unstaked","Unstaking {symbol}":["Unstaking ",["symbol"]],"Update: Disruptions reported for WETH, WBTC, WMATIC, and USDT. AIP 230 will resolve the disruptions and the market will be operating as normal on ~26th May 13h00 UTC.":"Update: Disruptions reported for WETH, WBTC, WMATIC, and USDT. AIP 230 will resolve the disruptions and the market will be operating as normal on ~26th May 13h00 UTC.","Use it to vote for or against active proposals.":"Use it to vote for or against active proposals.","Use your AAVE and stkAAVE balance to delegate your voting and proposition powers. You will not be sending any tokens, only the rights to vote and propose changes to the protocol. You can re-delegate or revoke power to self at any time.":"Use your AAVE and stkAAVE balance to delegate your voting and proposition powers. You will not be sending any tokens, only the rights to vote and propose changes to the protocol. You can re-delegate or revoke power to self at any time.","Used as collateral":"Used as collateral","User cannot withdraw more than the available balance":"User cannot withdraw more than the available balance","User did not borrow the specified currency":"User did not borrow the specified currency","User does not have outstanding stable rate debt on this reserve":"User does not have outstanding stable rate debt on this reserve","User does not have outstanding variable rate debt on this reserve":"User does not have outstanding variable rate debt on this reserve","User is in isolation mode":"User is in isolation mode","User is trying to borrow multiple assets including a siloed one":"User is trying to borrow multiple assets including a siloed one","Users who stake AAVE in Safety Module (i.e. stkAAVE holders) receive a discount on GHO borrow interest rate. The discount applies to 100 GHO for every 1 stkAAVE held. Use the calculator below to see GHO borrow rate with the discount applied.":"Users who stake AAVE in Safety Module (i.e. stkAAVE holders) receive a discount on GHO borrow interest rate. The discount applies to 100 GHO for every 1 stkAAVE held. Use the calculator below to see GHO borrow rate with the discount applied.","Utilization Rate":"Utilization Rate","VIEW TX":"VIEW TX","VOTE NAY":"VOTE NAY","VOTE YAE":"VOTE YAE","Variable":"Variable","Variable debt supply is not zero":"Variable debt supply is not zero","Variable interest rate will <0>fluctuate based on the market conditions. Recommended for short-term positions.":"Variable interest rate will <0>fluctuate based on the market conditions. Recommended for short-term positions.","Variable rate":"Variable rate","Version 2":"Version 2","Version 3":"Version 3","View":"View","View Transactions":"View Transactions","View all votes":"View all votes","View contract":"View contract","View details":"View details","View on Explorer":"View on Explorer","Vote NAY":"Vote NAY","Vote YAE":"Vote YAE","Voted NAY":"Voted NAY","Voted YAE":"Voted YAE","Votes":"Votes","Voting":"Voting","Voting power":"Voting power","Voting results":"Voting results","Wallet Balance":"Wallet Balance","Wallet balance":"Wallet balance","Wallet not detected. Connect or install wallet and retry":"Wallet not detected. Connect or install wallet and retry","Wallets are provided by External Providers and by selecting you agree to Terms of those Providers. Your access to the wallet might be reliant on the External Provider being operational.":"Wallets are provided by External Providers and by selecting you agree to Terms of those Providers. Your access to the wallet might be reliant on the External Provider being operational.","We couldn't find any assets related to your search. Try again with a different asset name, symbol, or address.":"We couldn't find any assets related to your search. Try again with a different asset name, symbol, or address.","We couldn't find any transactions related to your search. Try again with a different asset name, or reset filters.":"We couldn't find any transactions related to your search. Try again with a different asset name, or reset filters.","We couldn’t detect a wallet. Connect a wallet to stake and view your balance.":"We couldn’t detect a wallet. Connect a wallet to stake and view your balance.","We suggest you go back to the Dashboard.":"We suggest you go back to the Dashboard.","Website":"Website","When a liquidation occurs, liquidators repay up to 50% of the outstanding borrowed amount on behalf of the borrower. In return, they can buy the collateral at a discount and keep the difference (liquidation penalty) as a bonus.":"When a liquidation occurs, liquidators repay up to 50% of the outstanding borrowed amount on behalf of the borrower. In return, they can buy the collateral at a discount and keep the difference (liquidation penalty) as a bonus.","With a voting power of <0/>":"With a voting power of <0/>","With testnet Faucet you can get free assets to test the Aave Protocol. Make sure to switch your wallet provider to the appropriate testnet network, select desired asset, and click ‘Faucet’ to get tokens transferred to your wallet. The assets on a testnet are not “real,” meaning they have no monetary value. <0>Learn more":"With testnet Faucet you can get free assets to test the Aave Protocol. Make sure to switch your wallet provider to the appropriate testnet network, select desired asset, and click ‘Faucet’ to get tokens transferred to your wallet. The assets on a testnet are not “real,” meaning they have no monetary value. <0>Learn more","Withdraw":"Withdraw","Withdraw & Switch":"Withdraw & Switch","Withdraw and Switch":"Withdraw and Switch","Withdraw {symbol}":["Withdraw ",["symbol"]],"Withdrawing and Switching":"Withdrawing and Switching","Withdrawing this amount will reduce your health factor and increase risk of liquidation.":"Withdrawing this amount will reduce your health factor and increase risk of liquidation.","Withdrawing {symbol}":["Withdrawing ",["symbol"]],"Wrong Network":"Wrong Network","YAE":"YAE","You are entering Isolation mode":"You are entering Isolation mode","You can borrow this asset with a stable rate only if you borrow more than the amount you are supplying as collateral.":"You can borrow this asset with a stable rate only if you borrow more than the amount you are supplying as collateral.","You can not change Interest Type to stable as your borrowings are higher than your collateral":"You can not change Interest Type to stable as your borrowings are higher than your collateral","You can not disable E-Mode as your current collateralization level is above 80%, disabling E-Mode can cause liquidation. To exit E-Mode supply or repay borrowed positions.":"You can not disable E-Mode as your current collateralization level is above 80%, disabling E-Mode can cause liquidation. To exit E-Mode supply or repay borrowed positions.","You can not switch usage as collateral mode for this currency, because it will cause collateral call":"You can not switch usage as collateral mode for this currency, because it will cause collateral call","You can not use this currency as collateral":"You can not use this currency as collateral","You can not withdraw this amount because it will cause collateral call":"You can not withdraw this amount because it will cause collateral call","You can only switch to tokens with variable APY types. After this transaction, you may change the variable rate to a stable one if available.":"You can only switch to tokens with variable APY types. After this transaction, you may change the variable rate to a stable one if available.","You can only withdraw your assets from the Security Module after the cooldown period ends and the unstake window is active.":"You can only withdraw your assets from the Security Module after the cooldown period ends and the unstake window is active.","You can report incident to our <0>Discord or<1>Github.":"You can report incident to our <0>Discord or<1>Github.","You cancelled the transaction.":"You cancelled the transaction.","You did not participate in this proposal":"You did not participate in this proposal","You do not have supplies in this currency":"You do not have supplies in this currency","You don’t have enough funds in your wallet to repay the full amount. If you proceed to repay with your current amount of funds, you will still have a small borrowing position in your dashboard.":"You don’t have enough funds in your wallet to repay the full amount. If you proceed to repay with your current amount of funds, you will still have a small borrowing position in your dashboard.","You have no AAVE/stkAAVE balance to delegate.":"You have no AAVE/stkAAVE balance to delegate.","You have not borrow yet using this currency":"You have not borrow yet using this currency","You may borrow up to <0/> GHO at <1/> (max discount)":"You may borrow up to <0/> GHO at <1/> (max discount)","You may enter a custom amount in the field.":"You may enter a custom amount in the field.","You switched to {0} rate":["You switched to ",["0"]," rate"],"You unstake here":"You unstake here","You voted {0}":["You voted ",["0"]],"You will exit isolation mode and other tokens can now be used as collateral":"You will exit isolation mode and other tokens can now be used as collateral","You {action} <0/> {symbol}":["You ",["action"]," <0/> ",["symbol"]],"You've successfully switched borrow position.":"You've successfully switched borrow position.","You've successfully switched tokens.":"You've successfully switched tokens.","You've successfully withdrew & switched tokens.":"You've successfully withdrew & switched tokens.","Your balance is lower than the selected amount.":"Your balance is lower than the selected amount.","Your borrows":"Your borrows","Your current loan to value based on your collateral supplied.":"Your current loan to value based on your collateral supplied.","Your health factor and loan to value determine the assurance of your collateral. To avoid liquidations you can supply more collateral or repay borrow positions.":"Your health factor and loan to value determine the assurance of your collateral. To avoid liquidations you can supply more collateral or repay borrow positions.","Your info":"Your info","Your proposition power is based on your AAVE/stkAAVE balance and received delegations.":"Your proposition power is based on your AAVE/stkAAVE balance and received delegations.","Your reward balance is 0":"Your reward balance is 0","Your supplies":"Your supplies","Your voting info":"Your voting info","Your voting power is based on your AAVE/stkAAVE balance and received delegations.":"Your voting power is based on your AAVE/stkAAVE balance and received delegations.","Your {name} wallet is empty. Purchase or transfer assets or use <0>{0} to transfer your {network} assets.":["Your ",["name"]," wallet is empty. Purchase or transfer assets or use <0>",["0"]," to transfer your ",["network"]," assets."],"Your {name} wallet is empty. Purchase or transfer assets.":["Your ",["name"]," wallet is empty. Purchase or transfer assets."],"Your {networkName} wallet is empty. Get free test assets at":["Your ",["networkName"]," wallet is empty. Get free test assets at"],"Your {networkName} wallet is empty. Get free test {0} at":["Your ",["networkName"]," wallet is empty. Get free test ",["0"]," at"],"Zero address not valid":"Zero address not valid","assets":"assets","blocked activities":"blocked activities","copy the error":"copy the error","disabled":"disabled","documentation":"documentation","enabled":"enabled","ends":"ends","for":"for","of":"of","on":"on","please check that the amount you want to supply is not currently being used for staking. If it is being used for staking, your transaction might fail.":"please check that the amount you want to supply is not currently being used for staking. If it is being used for staking, your transaction might fail.","repaid":"repaid","stETH supplied as collateral will continue to accrue staking rewards provided by daily rebases.":"stETH supplied as collateral will continue to accrue staking rewards provided by daily rebases.","stETH tokens will be migrated to Wrapped stETH using Lido Protocol wrapper which leads to supply balance change after migration: {0}":["stETH tokens will be migrated to Wrapped stETH using Lido Protocol wrapper which leads to supply balance change after migration: ",["0"]],"staking view":"staking view","starts":"starts","stkAAVE holders get a discount on GHO borrow rate":"stkAAVE holders get a discount on GHO borrow rate","to":"to","tokens is not the same as staking them. If you wish to stake your":"tokens is not the same as staking them. If you wish to stake your","tokens, please go to the":"tokens, please go to the","withdrew":"withdrew","{0}":[["0"]],"{0} Balance":[["0"]," Balance"],"{0} Faucet":[["0"]," Faucet"],"{0} on-ramp service is provided by External Provider and by selecting you agree to Terms of the Provider. Your access to the service might be reliant on the External Provider being operational.":[["0"]," on-ramp service is provided by External Provider and by selecting you agree to Terms of the Provider. Your access to the service might be reliant on the External Provider being operational."],"{0}{name}":[["0"],["name"]],"{currentMethod}":[["currentMethod"]],"{d}d":[["d"],"d"],"{h}h":[["h"],"h"],"{m}m":[["m"],"m"],"{networkName} Faucet":[["networkName"]," Faucet"],"{notifyText}":[["notifyText"]],"{numSelected}/{numAvailable} assets selected":[["numSelected"],"/",["numAvailable"]," assets selected"],"{s}s":[["s"],"s"],"{title}":[["title"]],"{tooltipText}":[["tooltipText"]]}}; +/*eslint-disable*/module.exports={messages:{"...":"...",".CSV":".CSV",".JSON":".JSON","<0><1><2/>Add <3/> stkAAVE to borrow at <4/> (max discount)":"<0><1><2/>Add <3/> stkAAVE to borrow at <4/> (max discount)","<0><1><2/>Add stkAAVE to see borrow rate with discount":"<0><1><2/>Add stkAAVE to see borrow rate with discount","<0>Ampleforth is a rebasing asset. Visit the <1>documentation to learn more.":"<0>Ampleforth is a rebasing asset. Visit the <1>documentation to learn more.","<0>Attention: Parameter changes via governance can alter your account health factor and risk of liquidation. Follow the <1>Aave governance forum for updates.":"<0>Attention: Parameter changes via governance can alter your account health factor and risk of liquidation. Follow the <1>Aave governance forum for updates.","<0>Slippage tolerance <1>{selectedSlippage}% <2>{0}":["<0>Slippage tolerance <1>",["selectedSlippage"],"% <2>",["0"],""],"AAVE holders (Ethereum network only) can stake their AAVE in the Safety Module to add more security to the protocol and earn Safety Incentives. In the case of a shortfall event, up to 30% of your stake can be slashed to cover the deficit, providing an additional layer of protection for the protocol.":"AAVE holders (Ethereum network only) can stake their AAVE in the Safety Module to add more security to the protocol and earn Safety Incentives. In the case of a shortfall event, up to 30% of your stake can be slashed to cover the deficit, providing an additional layer of protection for the protocol.","APR":"APR","APY":"APY","APY change":"APY change","APY type":"APY type","APY type change":"APY type change","APY with discount applied":"APY with discount applied","APY, fixed rate":"APY, fixed rate","APY, stable":"APY, stable","APY, variable":"APY, variable","AToken supply is not zero":"AToken supply is not zero","Aave Governance":"Aave Governance","Aave aToken":"Aave aToken","Aave debt token":"Aave debt token","Aave is a fully decentralized, community governed protocol by the AAVE token-holders. AAVE token-holders collectively discuss, propose, and vote on upgrades to the protocol. AAVE token-holders (Ethereum network only) can either vote themselves on new proposals or delagate to an address of choice. To learn more check out the Governance":"Aave is a fully decentralized, community governed protocol by the AAVE token-holders. AAVE token-holders collectively discuss, propose, and vote on upgrades to the protocol. AAVE token-holders (Ethereum network only) can either vote themselves on new proposals or delagate to an address of choice. To learn more check out the Governance","Aave per month":"Aave per month","About GHO":"About GHO","Account":"Account","Action cannot be performed because the reserve is frozen":"Action cannot be performed because the reserve is frozen","Action cannot be performed because the reserve is paused":"Action cannot be performed because the reserve is paused","Action requires an active reserve":"Action requires an active reserve","Activate Cooldown":"Activate Cooldown","Add stkAAVE to see borrow APY with the discount":"Add stkAAVE to see borrow APY with the discount","Add to wallet":"Add to wallet","Add {0} to wallet to track your balance.":["Add ",["0"]," to wallet to track your balance."],"Address is not a contract":"Address is not a contract","Addresses":"Addresses","Addresses ({0})":["Addresses (",["0"],")"],"All Assets":"All Assets","All done!":"All done!","All proposals":"All proposals","All transactions":"All transactions","Allowance required action":"Allowance required action","Allows you to decide whether to use a supplied asset as collateral. An asset used as collateral will affect your borrowing power and health factor.":"Allows you to decide whether to use a supplied asset as collateral. An asset used as collateral will affect your borrowing power and health factor.","Allows you to switch between <0>variable and <1>stable interest rates, where variable rate can increase and decrease depending on the amount of liquidity in the reserve, and stable rate will stay the same for the duration of your loan.":"Allows you to switch between <0>variable and <1>stable interest rates, where variable rate can increase and decrease depending on the amount of liquidity in the reserve, and stable rate will stay the same for the duration of your loan.","Amount":"Amount","Amount claimable":"Amount claimable","Amount in cooldown":"Amount in cooldown","Amount must be greater than 0":"Amount must be greater than 0","Amount to unstake":"Amount to unstake","An error has occurred fetching the proposal metadata from IPFS.":"An error has occurred fetching the proposal metadata from IPFS.","Approve Confirmed":"Approve Confirmed","Approve with":"Approve with","Approve {symbol} to continue":["Approve ",["symbol"]," to continue"],"Approving {symbol}...":["Approving ",["symbol"],"..."],"Array parameters that should be equal length are not":"Array parameters that should be equal length are not","Asset":"Asset","Asset can be only used as collateral in isolation mode with limited borrowing power. To enter isolation mode, disable all other collateral.":"Asset can be only used as collateral in isolation mode with limited borrowing power. To enter isolation mode, disable all other collateral.","Asset can only be used as collateral in isolation mode only.":"Asset can only be used as collateral in isolation mode only.","Asset cannot be migrated because you have isolated collateral in {marketName} v3 Market which limits borrowable assets. You can manage your collateral in <0>{marketName} V3 Dashboard":["Asset cannot be migrated because you have isolated collateral in ",["marketName"]," v3 Market which limits borrowable assets. You can manage your collateral in <0>",["marketName"]," V3 Dashboard"],"Asset cannot be migrated due to insufficient liquidity or borrow cap limitation in {marketName} v3 market.":["Asset cannot be migrated due to insufficient liquidity or borrow cap limitation in ",["marketName"]," v3 market."],"Asset cannot be migrated due to supply cap restriction in {marketName} v3 market.":["Asset cannot be migrated due to supply cap restriction in ",["marketName"]," v3 market."],"Asset cannot be migrated to {marketName} V3 Market due to E-mode restrictions. You can disable or manage E-mode categories in your <0>V3 Dashboard":["Asset cannot be migrated to ",["marketName"]," V3 Market due to E-mode restrictions. You can disable or manage E-mode categories in your <0>V3 Dashboard"],"Asset cannot be migrated to {marketName} v3 Market since collateral asset will enable isolation mode.":["Asset cannot be migrated to ",["marketName"]," v3 Market since collateral asset will enable isolation mode."],"Asset cannot be used as collateral.":"Asset cannot be used as collateral.","Asset category":"Asset category","Asset is frozen in {marketName} v3 market, hence this position cannot be migrated.":["Asset is frozen in ",["marketName"]," v3 market, hence this position cannot be migrated."],"Asset is not borrowable in isolation mode":"Asset is not borrowable in isolation mode","Asset is not listed":"Asset is not listed","Asset supply is limited to a certain amount to reduce protocol exposure to the asset and to help manage risks involved.":"Asset supply is limited to a certain amount to reduce protocol exposure to the asset and to help manage risks involved.","Assets":"Assets","Assets to borrow":"Assets to borrow","Assets to supply":"Assets to supply","Assets with zero LTV ({assetsBlockingWithdraw}) must be withdrawn or disabled as collateral to perform this action":["Assets with zero LTV (",["assetsBlockingWithdraw"],") must be withdrawn or disabled as collateral to perform this action"],"At a discount":"At a discount","Author":"Author","Available":"Available","Available assets":"Available assets","Available liquidity":"Available liquidity","Available on":"Available on","Available rewards":"Available rewards","Available to borrow":"Available to borrow","Available to supply":"Available to supply","Back to Dashboard":"Back to Dashboard","Balance":"Balance","Balance to revoke":"Balance to revoke","Be careful - You are very close to liquidation. Consider depositing more collateral or paying down some of your borrowed positions":"Be careful - You are very close to liquidation. Consider depositing more collateral or paying down some of your borrowed positions","Be mindful of the network congestion and gas prices.":"Be mindful of the network congestion and gas prices.","Because this asset is paused, no actions can be taken until further notice":"Because this asset is paused, no actions can be taken until further notice","Before supplying":"Before supplying","Blocked Address":"Blocked Address","Borrow":"Borrow","Borrow APY":"Borrow APY","Borrow APY rate":"Borrow APY rate","Borrow APY, fixed rate":"Borrow APY, fixed rate","Borrow APY, stable":"Borrow APY, stable","Borrow APY, variable":"Borrow APY, variable","Borrow amount to reach {0}% utilization":["Borrow amount to reach ",["0"],"% utilization"],"Borrow and repay in same block is not allowed":"Borrow and repay in same block is not allowed","Borrow apy":"Borrow apy","Borrow balance":"Borrow balance","Borrow balance after repay":"Borrow balance after repay","Borrow balance after switch":"Borrow balance after switch","Borrow cap":"Borrow cap","Borrow cap is exceeded":"Borrow cap is exceeded","Borrow info":"Borrow info","Borrow power used":"Borrow power used","Borrow rate change":"Borrow rate change","Borrow {symbol}":["Borrow ",["symbol"]],"Borrowed":"Borrowed","Borrowed asset amount":"Borrowed asset amount","Borrowing is currently unavailable for {0}.":["Borrowing is currently unavailable for ",["0"],"."],"Borrowing is disabled due to an Aave community decision. <0>More details":"Borrowing is disabled due to an Aave community decision. <0>More details","Borrowing is not enabled":"Borrowing is not enabled","Borrowing is unavailable because you’re using Isolation mode. To manage Isolation mode visit your <0>Dashboard.":"Borrowing is unavailable because you’re using Isolation mode. To manage Isolation mode visit your <0>Dashboard.","Borrowing is unavailable because you’ve enabled Efficiency Mode (E-Mode) and Isolation mode. To manage E-Mode and Isolation mode visit your <0>Dashboard.":"Borrowing is unavailable because you’ve enabled Efficiency Mode (E-Mode) and Isolation mode. To manage E-Mode and Isolation mode visit your <0>Dashboard.","Borrowing is unavailable because you’ve enabled Efficiency Mode (E-Mode) for {0} category. To manage E-Mode categories visit your <0>Dashboard.":["Borrowing is unavailable because you’ve enabled Efficiency Mode (E-Mode) for ",["0"]," category. To manage E-Mode categories visit your <0>Dashboard."],"Borrowing of this asset is limited to a certain amount to minimize liquidity pool insolvency.":"Borrowing of this asset is limited to a certain amount to minimize liquidity pool insolvency.","Borrowing power and assets are limited due to Isolation mode.":"Borrowing power and assets are limited due to Isolation mode.","Borrowing this amount will reduce your health factor and increase risk of liquidation.":"Borrowing this amount will reduce your health factor and increase risk of liquidation.","Borrowing {symbol}":["Borrowing ",["symbol"]],"Both":"Both","Buy Crypto With Fiat":"Buy Crypto With Fiat","Buy Crypto with Fiat":"Buy Crypto with Fiat","Buy {cryptoSymbol} with Fiat":["Buy ",["cryptoSymbol"]," with Fiat"],"COPIED!":"COPIED!","COPY IMAGE":"COPY IMAGE","Can be collateral":"Can be collateral","Can be executed":"Can be executed","Cancel":"Cancel","Cannot disable E-Mode":"Cannot disable E-Mode","Choose how much voting/proposition power to give to someone else by delegating some of your AAVE or stkAAVE balance. Your tokens will remain in your account, but your delegate will be able to vote or propose on your behalf. If your AAVE or stkAAVE balance changes, your delegate's voting/proposition power will be automatically adjusted.":"Choose how much voting/proposition power to give to someone else by delegating some of your AAVE or stkAAVE balance. Your tokens will remain in your account, but your delegate will be able to vote or propose on your behalf. If your AAVE or stkAAVE balance changes, your delegate's voting/proposition power will be automatically adjusted.","Choose one of the on-ramp services":"Choose one of the on-ramp services","Claim":"Claim","Claim all":"Claim all","Claim all rewards":"Claim all rewards","Claim {0}":["Claim ",["0"]],"Claim {symbol}":["Claim ",["symbol"]],"Claimable AAVE":"Claimable AAVE","Claimed":"Claimed","Claiming":"Claiming","Claiming {symbol}":["Claiming ",["symbol"]],"Close":"Close","Collateral":"Collateral","Collateral balance after repay":"Collateral balance after repay","Collateral change":"Collateral change","Collateral is (mostly) the same currency that is being borrowed":"Collateral is (mostly) the same currency that is being borrowed","Collateral to repay with":"Collateral to repay with","Collateral usage":"Collateral usage","Collateral usage is limited because of Isolation mode.":"Collateral usage is limited because of Isolation mode.","Collateral usage is limited because of isolation mode.":"Collateral usage is limited because of isolation mode.","Collateral usage is limited because of isolation mode. <0>Learn More":"Collateral usage is limited because of isolation mode. <0>Learn More","Collateralization":"Collateralization","Collector Contract":"Collector Contract","Collector Info":"Collector Info","Connect wallet":"Connect wallet","Cooldown period":"Cooldown period","Cooldown period warning":"Cooldown period warning","Cooldown time left":"Cooldown time left","Cooldown to unstake":"Cooldown to unstake","Cooling down...":"Cooling down...","Copy address":"Copy address","Copy error message":"Copy error message","Copy error text":"Copy error text","Covered debt":"Covered debt","Created":"Created","Current LTV":"Current LTV","Current differential":"Current differential","Current v2 Balance":"Current v2 Balance","Current v2 balance":"Current v2 balance","Current votes":"Current votes","DAI balance will be converted via DSR contracts and then supplied as sDAI to Aave reserve. Switching incurs no additional costs and no slippage.":"DAI balance will be converted via DSR contracts and then supplied as sDAI to Aave reserve. Switching incurs no additional costs and no slippage.","Dark mode":"Dark mode","Dashboard":"Dashboard","Data couldn't be fetched, please reload graph.":"Data couldn't be fetched, please reload graph.","Debt":"Debt","Debt ceiling is exceeded":"Debt ceiling is exceeded","Debt ceiling is not zero":"Debt ceiling is not zero","Debt ceiling limits the amount possible to borrow against this asset by protocol users. Debt ceiling is specific to assets in isolation mode and is denoted in USD.":"Debt ceiling limits the amount possible to borrow against this asset by protocol users. Debt ceiling is specific to assets in isolation mode and is denoted in USD.","Delegated power":"Delegated power","Details":"Details","Developers":"Developers","Differential":"Differential","Disable E-Mode":"Disable E-Mode","Disable testnet":"Disable testnet","Disable {symbol} as collateral":["Disable ",["symbol"]," as collateral"],"Disabled":"Disabled","Disabling E-Mode":"Disabling E-Mode","Disabling this asset as collateral affects your borrowing power and Health Factor.":"Disabling this asset as collateral affects your borrowing power and Health Factor.","Disconnect Wallet":"Disconnect Wallet","Discord channel":"Discord channel","Discount":"Discount","Discount applied for <0/> staking AAVE":"Discount applied for <0/> staking AAVE","Discount model parameters":"Discount model parameters","Discount parameters are decided by the Aave community and may be changed over time. Check Governance for updates and vote to participate. <0>Learn more":"Discount parameters are decided by the Aave community and may be changed over time. Check Governance for updates and vote to participate. <0>Learn more","Discountable amount":"Discountable amount","Docs":"Docs","Download":"Download","Due to internal stETH mechanics required for rebasing support, it is not possible to perform a collateral switch where stETH is the source token.":"Due to internal stETH mechanics required for rebasing support, it is not possible to perform a collateral switch where stETH is the source token.","Due to the Horizon bridge exploit, certain assets on the Harmony network are not at parity with Ethereum, which affects the Aave V3 Harmony market.":"Due to the Horizon bridge exploit, certain assets on the Harmony network are not at parity with Ethereum, which affects the Aave V3 Harmony market.","E-Mode":"E-Mode","E-Mode Category":"E-Mode Category","E-Mode category":"E-Mode category","E-Mode increases your LTV for a selected category of assets up to 97%. <0>Learn more":"E-Mode increases your LTV for a selected category of assets up to 97%. <0>Learn more","E-Mode increases your LTV for a selected category of assets up to<0/>. <1>Learn more":"E-Mode increases your LTV for a selected category of assets up to<0/>. <1>Learn more","E-Mode increases your LTV for a selected category of assets, meaning that when E-mode is enabled, you will have higher borrowing power over assets of the same E-mode category which are defined by Aave Governance. You can enter E-Mode from your <0>Dashboard. To learn more about E-Mode and applied restrictions in <1>FAQ or <2>Aave V3 Technical Paper.":"E-Mode increases your LTV for a selected category of assets, meaning that when E-mode is enabled, you will have higher borrowing power over assets of the same E-mode category which are defined by Aave Governance. You can enter E-Mode from your <0>Dashboard. To learn more about E-Mode and applied restrictions in <1>FAQ or <2>Aave V3 Technical Paper.","Effective interest rate":"Effective interest rate","Efficiency mode (E-Mode)":"Efficiency mode (E-Mode)","Emode":"Emode","Enable E-Mode":"Enable E-Mode","Enable {symbol} as collateral":["Enable ",["symbol"]," as collateral"],"Enabled":"Enabled","Enabling E-Mode":"Enabling E-Mode","Enabling E-Mode only allows you to borrow assets belonging to the selected category. Please visit our <0>FAQ guide to learn more about how it works and the applied restrictions.":"Enabling E-Mode only allows you to borrow assets belonging to the selected category. Please visit our <0>FAQ guide to learn more about how it works and the applied restrictions.","Enabling this asset as collateral increases your borrowing power and Health Factor. However, it can get liquidated if your health factor drops below 1.":"Enabling this asset as collateral increases your borrowing power and Health Factor. However, it can get liquidated if your health factor drops below 1.","Ended":"Ended","Ends":"Ends","English":"English","Enter ETH address":"Enter ETH address","Enter an amount":"Enter an amount","Error connecting. Try refreshing the page.":"Error connecting. Try refreshing the page.","Estimated compounding interest, including discount for Staking {0}AAVE in Safety Module.":["Estimated compounding interest, including discount for Staking ",["0"],"AAVE in Safety Module."],"Exceeds the discount":"Exceeds the discount","Executed":"Executed","Expected amount to repay":"Expected amount to repay","Expires":"Expires","Export data to":"Export data to","FAQ":"FAQ","FAQS":"FAQS","Failed to load proposal voters. Please refresh the page.":"Failed to load proposal voters. Please refresh the page.","Faucet":"Faucet","Faucet {0}":["Faucet ",["0"]],"Fetching data...":"Fetching data...","Filter":"Filter","Fixed":"Fixed","Fixed rate":"Fixed rate","Flashloan is disabled for this asset, hence this position cannot be migrated.":"Flashloan is disabled for this asset, hence this position cannot be migrated.","For repayment of a specific type of debt, the user needs to have debt that type":"For repayment of a specific type of debt, the user needs to have debt that type","Forum discussion":"Forum discussion","French":"French","Funds in the Safety Module":"Funds in the Safety Module","GHO is a native decentralized, collateral-backed digital asset pegged to USD. It is created by users via borrowing against multiple collateral. When user repays their GHO borrow position, the protocol burns that user's GHO. All the interest payments accrued by minters of GHO would be directly transferred to the AaveDAO treasury.":"GHO is a native decentralized, collateral-backed digital asset pegged to USD. It is created by users via borrowing against multiple collateral. When user repays their GHO borrow position, the protocol burns that user's GHO. All the interest payments accrued by minters of GHO would be directly transferred to the AaveDAO treasury.","Get ABP Token":"Get ABP Token","Global settings":"Global settings","Go Back":"Go Back","Go to Balancer Pool":"Go to Balancer Pool","Go to V3 Dashboard":"Go to V3 Dashboard","Governance":"Governance","Greek":"Greek","Health Factor ({0} v2)":["Health Factor (",["0"]," v2)"],"Health Factor ({0} v3)":["Health Factor (",["0"]," v3)"],"Health factor":"Health factor","Health factor is lesser than the liquidation threshold":"Health factor is lesser than the liquidation threshold","Health factor is not below the threshold":"Health factor is not below the threshold","Hide":"Hide","Holders of stkAAVE receive a discount on the GHO borrowing rate":"Holders of stkAAVE receive a discount on the GHO borrowing rate","I acknowledge the risks involved.":"I acknowledge the risks involved.","I fully understand the risks of migrating.":"I fully understand the risks of migrating.","I understand how cooldown ({0}) and unstaking ({1}) work":["I understand how cooldown (",["0"],") and unstaking (",["1"],") work"],"If the error continues to happen,<0/> you may report it to this":"If the error continues to happen,<0/> you may report it to this","If the health factor goes below 1, the liquidation of your collateral might be triggered.":"If the health factor goes below 1, the liquidation of your collateral might be triggered.","If you DO NOT unstake within {0} of unstake window, you will need to activate cooldown process again.":["If you DO NOT unstake within ",["0"]," of unstake window, you will need to activate cooldown process again."],"If your loan to value goes above the liquidation threshold your collateral supplied may be liquidated.":"If your loan to value goes above the liquidation threshold your collateral supplied may be liquidated.","In E-Mode some assets are not borrowable. Exit E-Mode to get access to all assets":"In E-Mode some assets are not borrowable. Exit E-Mode to get access to all assets","In Isolation mode, you cannot supply other assets as collateral. A global debt ceiling limits the borrowing power of the isolated asset. To exit isolation mode disable {0} as collateral before borrowing another asset. Read more in our <0>FAQ":["In Isolation mode, you cannot supply other assets as collateral. A global debt ceiling limits the borrowing power of the isolated asset. To exit isolation mode disable ",["0"]," as collateral before borrowing another asset. Read more in our <0>FAQ"],"Inconsistent flashloan parameters":"Inconsistent flashloan parameters","Insufficient collateral to cover new borrow position. Wallet must have borrowing power remaining to perform debt switch.":"Insufficient collateral to cover new borrow position. Wallet must have borrowing power remaining to perform debt switch.","Interest accrued":"Interest accrued","Interest rate rebalance conditions were not met":"Interest rate rebalance conditions were not met","Interest rate strategy":"Interest rate strategy","Invalid amount to burn":"Invalid amount to burn","Invalid amount to mint":"Invalid amount to mint","Invalid bridge protocol fee":"Invalid bridge protocol fee","Invalid expiration":"Invalid expiration","Invalid flashloan premium":"Invalid flashloan premium","Invalid return value of the flashloan executor function":"Invalid return value of the flashloan executor function","Invalid signature":"Invalid signature","Isolated":"Isolated","Isolated Debt Ceiling":"Isolated Debt Ceiling","Isolated assets have limited borrowing power and other assets cannot be used as collateral.":"Isolated assets have limited borrowing power and other assets cannot be used as collateral.","Join the community discussion":"Join the community discussion","LEARN MORE":"LEARN MORE","Language":"Language","Learn more":"Learn more","Learn more about risks involved":"Learn more about risks involved","Learn more in our <0>FAQ guide":"Learn more in our <0>FAQ guide","Learn more.":"Learn more.","Links":"Links","Liqudation":"Liqudation","Liquidated collateral":"Liquidated collateral","Liquidation":"Liquidation","Liquidation <0/> threshold":"Liquidation <0/> threshold","Liquidation Threshold":"Liquidation Threshold","Liquidation at":"Liquidation at","Liquidation penalty":"Liquidation penalty","Liquidation risk":"Liquidation risk","Liquidation risk parameters":"Liquidation risk parameters","Liquidation threshold":"Liquidation threshold","Liquidation value":"Liquidation value","Loading data...":"Loading data...","Ltv validation failed":"Ltv validation failed","MAI has been paused due to a community decision. Supply, borrows and repays are impacted. <0>More details":"MAI has been paused due to a community decision. Supply, borrows and repays are impacted. <0>More details","MAX":"MAX","Manage analytics":"Manage analytics","Market":"Market","Markets":"Markets","Max":"Max","Max LTV":"Max LTV","Max slashing":"Max slashing","Max slippage":"Max slippage","Maximum amount available to borrow against this asset is limited because debt ceiling is at {0}%.":["Maximum amount available to borrow against this asset is limited because debt ceiling is at ",["0"],"%."],"Maximum amount available to borrow is <0/> {0} (<1/>).":["Maximum amount available to borrow is <0/> ",["0"]," (<1/>)."],"Maximum amount available to borrow is limited because protocol borrow cap is nearly reached.":"Maximum amount available to borrow is limited because protocol borrow cap is nearly reached.","Maximum amount available to supply is <0/> {0} (<1/>).":["Maximum amount available to supply is <0/> ",["0"]," (<1/>)."],"Maximum amount available to supply is limited because protocol supply cap is at {0}%.":["Maximum amount available to supply is limited because protocol supply cap is at ",["0"],"%."],"Maximum loan to value":"Maximum loan to value","Meet GHO":"Meet GHO","Menu":"Menu","Migrate":"Migrate","Migrate to V3":"Migrate to V3","Migrate to v3":"Migrate to v3","Migrate to {0} v3 Market":["Migrate to ",["0"]," v3 Market"],"Migrated":"Migrated","Migrating":"Migrating","Migrating multiple collaterals and borrowed assets at the same time can be an expensive operation and might fail in certain situations.<0>Therefore it’s not recommended to migrate positions with more than 5 assets (deposited + borrowed) at the same time.":"Migrating multiple collaterals and borrowed assets at the same time can be an expensive operation and might fail in certain situations.<0>Therefore it’s not recommended to migrate positions with more than 5 assets (deposited + borrowed) at the same time.","Migration risks":"Migration risks","Minimum GHO borrow amount":"Minimum GHO borrow amount","Minimum USD value received":"Minimum USD value received","Minimum staked Aave amount":"Minimum staked Aave amount","Minimum {0} received":["Minimum ",["0"]," received"],"More":"More","NAY":"NAY","Need help connecting a wallet? <0>Read our FAQ":"Need help connecting a wallet? <0>Read our FAQ","Net APR":"Net APR","Net APY":"Net APY","Net APY is the combined effect of all supply and borrow positions on net worth, including incentives. It is possible to have a negative net APY if debt APY is higher than supply APY.":"Net APY is the combined effect of all supply and borrow positions on net worth, including incentives. It is possible to have a negative net APY if debt APY is higher than supply APY.","Net worth":"Net worth","Network":"Network","Network not supported for this wallet":"Network not supported for this wallet","New APY":"New APY","No assets selected to migrate.":"No assets selected to migrate.","No rewards to claim":"No rewards to claim","No search results{0}":["No search results",["0"]],"No transactions yet.":"No transactions yet.","No voting power":"No voting power","None":"None","Not a valid address":"Not a valid address","Not enough balance on your wallet":"Not enough balance on your wallet","Not enough collateral to repay this amount of debt with":"Not enough collateral to repay this amount of debt with","Not enough staked balance":"Not enough staked balance","Not enough voting power to participate in this proposal":"Not enough voting power to participate in this proposal","Not reached":"Not reached","Nothing borrowed yet":"Nothing borrowed yet","Nothing found":"Nothing found","Nothing staked":"Nothing staked","Nothing supplied yet":"Nothing supplied yet","Notify":"Notify","Ok, Close":"Ok, Close","Ok, I got it":"Ok, I got it","Operation not supported":"Operation not supported","Oracle price":"Oracle price","Overview":"Overview","Page not found":"Page not found","Participating in this {symbol} reserve gives annualized rewards.":["Participating in this ",["symbol"]," reserve gives annualized rewards."],"Pending...":"Pending...","Per the community, the Fantom market has been frozen.":"Per the community, the Fantom market has been frozen.","Per the community, the V2 AMM market has been deprecated.":"Per the community, the V2 AMM market has been deprecated.","Please always be aware of your <0>Health Factor (HF) when partially migrating a position and that your rates will be updated to V3 rates.":"Please always be aware of your <0>Health Factor (HF) when partially migrating a position and that your rates will be updated to V3 rates.","Please connect a wallet to view your personal information here.":"Please connect a wallet to view your personal information here.","Please connect your wallet to be able to switch your tokens.":"Please connect your wallet to be able to switch your tokens.","Please connect your wallet to get free testnet assets.":"Please connect your wallet to get free testnet assets.","Please connect your wallet to see migration tool.":"Please connect your wallet to see migration tool.","Please connect your wallet to see your supplies, borrowings, and open positions.":"Please connect your wallet to see your supplies, borrowings, and open positions.","Please connect your wallet to view transaction history.":"Please connect your wallet to view transaction history.","Please enter a valid wallet address.":"Please enter a valid wallet address.","Please switch to {networkName}.":["Please switch to ",["networkName"],"."],"Please, connect your wallet":"Please, connect your wallet","Pool addresses provider is not registered":"Pool addresses provider is not registered","Powered by":"Powered by","Preview tx and migrate":"Preview tx and migrate","Price":"Price","Price data is not currently available for this reserve on the protocol subgraph":"Price data is not currently available for this reserve on the protocol subgraph","Price impact":"Price impact","Price impact is the spread between the total value of the entry tokens switched and the destination tokens obtained (in USD), which results from the limited liquidity of the trading pair.":"Price impact is the spread between the total value of the entry tokens switched and the destination tokens obtained (in USD), which results from the limited liquidity of the trading pair.","Price impact {0}%":["Price impact ",["0"],"%"],"Privacy":"Privacy","Proposal details":"Proposal details","Proposal overview":"Proposal overview","Proposals":"Proposals","Proposition":"Proposition","Protocol borrow cap at 100% for this asset. Further borrowing unavailable.":"Protocol borrow cap at 100% for this asset. Further borrowing unavailable.","Protocol borrow cap is at 100% for this asset. Further borrowing unavailable.":"Protocol borrow cap is at 100% for this asset. Further borrowing unavailable.","Protocol debt ceiling is at 100% for this asset. Further borrowing against this asset is unavailable.":"Protocol debt ceiling is at 100% for this asset. Further borrowing against this asset is unavailable.","Protocol debt ceiling is at 100% for this asset. Futher borrowing against this asset is unavailable.":"Protocol debt ceiling is at 100% for this asset. Futher borrowing against this asset is unavailable.","Protocol supply cap at 100% for this asset. Further supply unavailable.":"Protocol supply cap at 100% for this asset. Further supply unavailable.","Protocol supply cap is at 100% for this asset. Further supply unavailable.":"Protocol supply cap is at 100% for this asset. Further supply unavailable.","Quorum":"Quorum","Rate change":"Rate change","Raw-Ipfs":"Raw-Ipfs","Reached":"Reached","Reactivate cooldown period to unstake {0} {stakedToken}":["Reactivate cooldown period to unstake ",["0"]," ",["stakedToken"]],"Read more here.":"Read more here.","Read-only mode allows to see address positions in Aave, but you won't be able to perform transactions.":"Read-only mode allows to see address positions in Aave, but you won't be able to perform transactions.","Read-only mode.":"Read-only mode.","Read-only mode. Connect to a wallet to perform transactions.":"Read-only mode. Connect to a wallet to perform transactions.","Receive (est.)":"Receive (est.)","Received":"Received","Recipient address":"Recipient address","Rejected connection request":"Rejected connection request","Reload":"Reload","Reload the page":"Reload the page","Remaining debt":"Remaining debt","Remaining supply":"Remaining supply","Repaid":"Repaid","Repay":"Repay","Repay with":"Repay with","Repay {symbol}":["Repay ",["symbol"]],"Repaying {symbol}":["Repaying ",["symbol"]],"Repayment amount to reach {0}% utilization":["Repayment amount to reach ",["0"],"% utilization"],"Reserve Size":"Reserve Size","Reserve factor":"Reserve factor","Reserve factor is a percentage of interest which goes to a {0} that is controlled by Aave governance to promote ecosystem growth.":["Reserve factor is a percentage of interest which goes to a ",["0"]," that is controlled by Aave governance to promote ecosystem growth."],"Reserve status & configuration":"Reserve status & configuration","Reset":"Reset","Restake":"Restake","Restake {symbol}":["Restake ",["symbol"]],"Restaked":"Restaked","Restaking {symbol}":["Restaking ",["symbol"]],"Review approval tx details":"Review approval tx details","Review changes to continue":"Review changes to continue","Review tx":"Review tx","Review tx details":"Review tx details","Revoke power":"Revoke power","Reward(s) to claim":"Reward(s) to claim","Rewards APR":"Rewards APR","Risk details":"Risk details","SEE CHARTS":"SEE CHARTS","Safety of your deposited collateral against the borrowed assets and its underlying value.":"Safety of your deposited collateral against the borrowed assets and its underlying value.","Save and share":"Save and share","Seatbelt report":"Seatbelt report","Seems like we can't switch the network automatically. Please check if you can change it from the wallet.":"Seems like we can't switch the network automatically. Please check if you can change it from the wallet.","Select":"Select","Select APY type to switch":"Select APY type to switch","Select an asset":"Select an asset","Select language":"Select language","Select slippage tolerance":"Select slippage tolerance","Select v2 borrows to migrate":"Select v2 borrows to migrate","Select v2 supplies to migrate":"Select v2 supplies to migrate","Selected assets have successfully migrated. Visit the Market Dashboard to see them.":"Selected assets have successfully migrated. Visit the Market Dashboard to see them.","Selected borrow assets":"Selected borrow assets","Selected supply assets":"Selected supply assets","Send feedback":"Send feedback","Set up delegation":"Set up delegation","Setup notifications about your Health Factor using the Hal app.":"Setup notifications about your Health Factor using the Hal app.","Share on Lens":"Share on Lens","Share on twitter":"Share on twitter","Show":"Show","Show Frozen or paused assets":"Show Frozen or paused assets","Show assets with 0 balance":"Show assets with 0 balance","Sign to continue":"Sign to continue","Signatures ready":"Signatures ready","Signing":"Signing","Since this asset is frozen, the only available actions are withdraw and repay which can be accessed from the <0>Dashboard":"Since this asset is frozen, the only available actions are withdraw and repay which can be accessed from the <0>Dashboard","Since this is a test network, you can get any of the assets if you have ETH on your wallet":"Since this is a test network, you can get any of the assets if you have ETH on your wallet","Slippage":"Slippage","Slippage is the difference between the quoted and received amounts from changing market conditions between the moment the transaction is submitted and its verification.":"Slippage is the difference between the quoted and received amounts from changing market conditions between the moment the transaction is submitted and its verification.","Some migrated assets will not be used as collateral due to enabled isolation mode in {marketName} V3 Market. Visit <0>{marketName} V3 Dashboard to manage isolation mode.":["Some migrated assets will not be used as collateral due to enabled isolation mode in ",["marketName"]," V3 Market. Visit <0>",["marketName"]," V3 Dashboard to manage isolation mode."],"Something went wrong":"Something went wrong","Sorry, an unexpected error happened. In the meantime you may try reloading the page, or come back later.":"Sorry, an unexpected error happened. In the meantime you may try reloading the page, or come back later.","Sorry, we couldn't find the page you were looking for.":"Sorry, we couldn't find the page you were looking for.","Spanish":"Spanish","Stable":"Stable","Stable Interest Type is disabled for this currency":"Stable Interest Type is disabled for this currency","Stable borrowing is enabled":"Stable borrowing is enabled","Stable borrowing is not enabled":"Stable borrowing is not enabled","Stable debt supply is not zero":"Stable debt supply is not zero","Stable interest rate will <0>stay the same for the duration of your loan. Recommended for long-term loan periods and for users who prefer predictability.":"Stable interest rate will <0>stay the same for the duration of your loan. Recommended for long-term loan periods and for users who prefer predictability.","Stablecoin":"Stablecoin","Stake":"Stake","Stake AAVE":"Stake AAVE","Stake ABPT":"Stake ABPT","Stake cooldown activated":"Stake cooldown activated","Staked":"Staked","Staking":"Staking","Staking APR":"Staking APR","Staking Rewards":"Staking Rewards","Staking balance":"Staking balance","Staking discount":"Staking discount","Started":"Started","State":"State","Static interest rate that is determined by Aave Governance. This rate may be changed over time depending on the need for the GHO supply to contract/expand. <0>Learn more":"Static interest rate that is determined by Aave Governance. This rate may be changed over time depending on the need for the GHO supply to contract/expand. <0>Learn more","Supplied":"Supplied","Supplied asset amount":"Supplied asset amount","Supply":"Supply","Supply APY":"Supply APY","Supply apy":"Supply apy","Supply balance":"Supply balance","Supply balance after switch":"Supply balance after switch","Supply cap is exceeded":"Supply cap is exceeded","Supply cap on target reserve reached. Try lowering the amount.":"Supply cap on target reserve reached. Try lowering the amount.","Supply {symbol}":["Supply ",["symbol"]],"Supplying your":"Supplying your","Supplying {symbol}":["Supplying ",["symbol"]],"Switch":"Switch","Switch APY type":"Switch APY type","Switch E-Mode":"Switch E-Mode","Switch E-Mode category":"Switch E-Mode category","Switch Network":"Switch Network","Switch borrow position":"Switch borrow position","Switch rate":"Switch rate","Switch to":"Switch to","Switched":"Switched","Switching":"Switching","Switching E-Mode":"Switching E-Mode","Switching rate":"Switching rate","Techpaper":"Techpaper","Terms":"Terms","Test Assets":"Test Assets","Testnet mode":"Testnet mode","Testnet mode is ON":"Testnet mode is ON","Thank you for voting!!":"Thank you for voting!!","The % of your total borrowing power used. This is based on the amount of your collateral supplied and the total amount that you can borrow.":"The % of your total borrowing power used. This is based on the amount of your collateral supplied and the total amount that you can borrow.","The Aave Balancer Pool Token (ABPT) is a liquidity pool token. You can receive ABPT by depositing a combination of AAVE + ETH in the Balancer liquidity pool. You can then stake your BPT in the Safety Module to secure the protocol and earn Safety Incentives.":"The Aave Balancer Pool Token (ABPT) is a liquidity pool token. You can receive ABPT by depositing a combination of AAVE + ETH in the Balancer liquidity pool. You can then stake your BPT in the Safety Module to secure the protocol and earn Safety Incentives.","The Aave Protocol is programmed to always use the price of 1 GHO = $1. This is different from using market pricing via oracles for other crypto assets. This creates stabilizing arbitrage opportunities when the price of GHO fluctuates.":"The Aave Protocol is programmed to always use the price of 1 GHO = $1. This is different from using market pricing via oracles for other crypto assets. This creates stabilizing arbitrage opportunities when the price of GHO fluctuates.","The Maximum LTV ratio represents the maximum borrowing power of a specific collateral. For example, if a collateral has an LTV of 75%, the user can borrow up to 0.75 worth of ETH in the principal currency for every 1 ETH worth of collateral.":"The Maximum LTV ratio represents the maximum borrowing power of a specific collateral. For example, if a collateral has an LTV of 75%, the user can borrow up to 0.75 worth of ETH in the principal currency for every 1 ETH worth of collateral.","The Stable Rate is not enabled for this currency":"The Stable Rate is not enabled for this currency","The address of the pool addresses provider is invalid":"The address of the pool addresses provider is invalid","The app is running in testnet mode. Learn how it works in":"The app is running in testnet mode. Learn how it works in","The caller of the function is not an AToken":"The caller of the function is not an AToken","The caller of this function must be a pool":"The caller of this function must be a pool","The collateral balance is 0":"The collateral balance is 0","The collateral chosen cannot be liquidated":"The collateral chosen cannot be liquidated","The cooldown period is the time required prior to unstaking your tokens (20 days). You can only withdraw your assets from the Security Module after the cooldown period and within the unstake window.<0>Learn more":"The cooldown period is the time required prior to unstaking your tokens (20 days). You can only withdraw your assets from the Security Module after the cooldown period and within the unstake window.<0>Learn more","The cooldown period is {0}. After {1} of cooldown, you will enter unstake window of {2}. You will continue receiving rewards during cooldown and unstake window.":["The cooldown period is ",["0"],". After ",["1"]," of cooldown, you will enter unstake window of ",["2"],". You will continue receiving rewards during cooldown and unstake window."],"The effects on the health factor would cause liquidation. Try lowering the amount.":"The effects on the health factor would cause liquidation. Try lowering the amount.","The loan to value of the migrated positions would cause liquidation. Increase migrated collateral or reduce migrated borrow to continue.":"The loan to value of the migrated positions would cause liquidation. Increase migrated collateral or reduce migrated borrow to continue.","The requested amount is greater than the max loan size in stable rate mode":"The requested amount is greater than the max loan size in stable rate mode","The total amount of your assets denominated in USD that can be used as collateral for borrowing assets.":"The total amount of your assets denominated in USD that can be used as collateral for borrowing assets.","The underlying asset cannot be rescued":"The underlying asset cannot be rescued","The underlying balance needs to be greater than 0":"The underlying balance needs to be greater than 0","The weighted average of APY for all borrowed assets, including incentives.":"The weighted average of APY for all borrowed assets, including incentives.","The weighted average of APY for all supplied assets, including incentives.":"The weighted average of APY for all supplied assets, including incentives.","There are not enough funds in the{0}reserve to borrow":["There are not enough funds in the",["0"],"reserve to borrow"],"There is not enough collateral to cover a new borrow":"There is not enough collateral to cover a new borrow","There is not enough liquidity for the target asset to perform the switch. Try lowering the amount.":"There is not enough liquidity for the target asset to perform the switch. Try lowering the amount.","There was some error. Please try changing the parameters or <0><1>copy the error":"There was some error. Please try changing the parameters or <0><1>copy the error","These assets are temporarily frozen or paused by Aave community decisions, meaning that further supply / borrow, or rate swap of these assets are unavailable. Withdrawals and debt repayments are allowed. Follow the <0>Aave governance forum for further updates.":"These assets are temporarily frozen or paused by Aave community decisions, meaning that further supply / borrow, or rate swap of these assets are unavailable. Withdrawals and debt repayments are allowed. Follow the <0>Aave governance forum for further updates.","These funds have been borrowed and are not available for withdrawal at this time.":"These funds have been borrowed and are not available for withdrawal at this time.","This action will reduce V2 health factor below liquidation threshold. retain collateral or migrate borrow position to continue.":"This action will reduce V2 health factor below liquidation threshold. retain collateral or migrate borrow position to continue.","This action will reduce health factor of V3 below liquidation threshold. Increase migrated collateral or reduce migrated borrow to continue.":"This action will reduce health factor of V3 below liquidation threshold. Increase migrated collateral or reduce migrated borrow to continue.","This action will reduce your health factor. Please be mindful of the increased risk of collateral liquidation.":"This action will reduce your health factor. Please be mindful of the increased risk of collateral liquidation.","This address is blocked on app.aave.com because it is associated with one or more":"This address is blocked on app.aave.com because it is associated with one or more","This asset has almost reached its borrow cap. There is only {messageValue} available to be borrowed from this market.":["This asset has almost reached its borrow cap. There is only ",["messageValue"]," available to be borrowed from this market."],"This asset has almost reached its supply cap. There can only be {messageValue} supplied to this market.":["This asset has almost reached its supply cap. There can only be ",["messageValue"]," supplied to this market."],"This asset has reached its borrow cap. Nothing is available to be borrowed from this market.":"This asset has reached its borrow cap. Nothing is available to be borrowed from this market.","This asset has reached its supply cap. Nothing is available to be supplied from this market.":"This asset has reached its supply cap. Nothing is available to be supplied from this market.","This asset is frozen due to an Aave Protocol Governance decision. <0>More details":"This asset is frozen due to an Aave Protocol Governance decision. <0>More details","This asset is frozen due to an Aave Protocol Governance decision. On the 20th of December 2022, renFIL will no longer be supported and cannot be bridged back to its native network. It is recommended to withdraw supply positions and repay borrow positions so that renFIL can be bridged back to FIL before the deadline. After this date, it will no longer be possible to convert renFIL to FIL. <0>More details":"This asset is frozen due to an Aave Protocol Governance decision. On the 20th of December 2022, renFIL will no longer be supported and cannot be bridged back to its native network. It is recommended to withdraw supply positions and repay borrow positions so that renFIL can be bridged back to FIL before the deadline. After this date, it will no longer be possible to convert renFIL to FIL. <0>More details","This asset is frozen due to an Aave community decision. <0>More details":"This asset is frozen due to an Aave community decision. <0>More details","This asset is planned to be offboarded due to an Aave Protocol Governance decision. <0>More details":"This asset is planned to be offboarded due to an Aave Protocol Governance decision. <0>More details","This gas calculation is only an estimation. Your wallet will set the price of the transaction. You can modify the gas settings directly from your wallet provider.":"This gas calculation is only an estimation. Your wallet will set the price of the transaction. You can modify the gas settings directly from your wallet provider.","This integration was<0>proposed and approvedby the community.":"This integration was<0>proposed and approvedby the community.","This is the total amount available for you to borrow. You can borrow based on your collateral and until the borrow cap is reached.":"This is the total amount available for you to borrow. You can borrow based on your collateral and until the borrow cap is reached.","This is the total amount that you are able to supply to in this reserve. You are able to supply your wallet balance up until the supply cap is reached.":"This is the total amount that you are able to supply to in this reserve. You are able to supply your wallet balance up until the supply cap is reached.","This represents the threshold at which a borrow position will be considered undercollateralized and subject to liquidation for each collateral. For example, if a collateral has a liquidation threshold of 80%, it means that the position will be liquidated when the debt value is worth 80% of the collateral value.":"This represents the threshold at which a borrow position will be considered undercollateralized and subject to liquidation for each collateral. For example, if a collateral has a liquidation threshold of 80%, it means that the position will be liquidated when the debt value is worth 80% of the collateral value.","Time left to be able to withdraw your staked asset.":"Time left to be able to withdraw your staked asset.","Time left to unstake":"Time left to unstake","Time left until the withdrawal window closes.":"Time left until the withdrawal window closes.","Tip: Try increasing slippage or reduce input amount":"Tip: Try increasing slippage or reduce input amount","To borrow you need to supply any asset to be used as collateral.":"To borrow you need to supply any asset to be used as collateral.","To continue, you need to grant Aave smart contracts permission to move your funds from your wallet. Depending on the asset and wallet you use, it is done by signing the permission message (gas free), or by submitting an approval transaction (requires gas). <0>Learn more":"To continue, you need to grant Aave smart contracts permission to move your funds from your wallet. Depending on the asset and wallet you use, it is done by signing the permission message (gas free), or by submitting an approval transaction (requires gas). <0>Learn more","To enable E-mode for the {0} category, all borrow positions outside of this category must be closed.":["To enable E-mode for the ",["0"]," category, all borrow positions outside of this category must be closed."],"To repay on behalf of a user an explicit amount to repay is needed":"To repay on behalf of a user an explicit amount to repay is needed","To request access for this permissioned market, please visit: <0>Acces Provider Name":"To request access for this permissioned market, please visit: <0>Acces Provider Name","To submit a proposal for minor changes to the protocol, you'll need at least 80.00K power. If you want to change the core code base, you'll need 320k power.<0>Learn more.":"To submit a proposal for minor changes to the protocol, you'll need at least 80.00K power. If you want to change the core code base, you'll need 320k power.<0>Learn more.","Top 10 addresses":"Top 10 addresses","Total available":"Total available","Total borrowed":"Total borrowed","Total borrows":"Total borrows","Total emission per day":"Total emission per day","Total interest accrued":"Total interest accrued","Total market size":"Total market size","Total supplied":"Total supplied","Total voting power":"Total voting power","Total worth":"Total worth","Track wallet":"Track wallet","Track wallet balance in read-only mode":"Track wallet balance in read-only mode","Transaction failed":"Transaction failed","Transaction history":"Transaction history","Transaction history is not currently available for this market":"Transaction history is not currently available for this market","Transaction overview":"Transaction overview","Transactions":"Transactions","UNSTAKE {symbol}":["UNSTAKE ",["symbol"]],"Unavailable":"Unavailable","Unbacked":"Unbacked","Unbacked mint cap is exceeded":"Unbacked mint cap is exceeded","Underlying asset does not exist in {marketName} v3 Market, hence this position cannot be migrated.":["Underlying asset does not exist in ",["marketName"]," v3 Market, hence this position cannot be migrated."],"Underlying token":"Underlying token","Unstake now":"Unstake now","Unstake window":"Unstake window","Unstaked":"Unstaked","Unstaking {symbol}":["Unstaking ",["symbol"]],"Update: Disruptions reported for WETH, WBTC, WMATIC, and USDT. AIP 230 will resolve the disruptions and the market will be operating as normal on ~26th May 13h00 UTC.":"Update: Disruptions reported for WETH, WBTC, WMATIC, and USDT. AIP 230 will resolve the disruptions and the market will be operating as normal on ~26th May 13h00 UTC.","Use it to vote for or against active proposals.":"Use it to vote for or against active proposals.","Use your AAVE and stkAAVE balance to delegate your voting and proposition powers. You will not be sending any tokens, only the rights to vote and propose changes to the protocol. You can re-delegate or revoke power to self at any time.":"Use your AAVE and stkAAVE balance to delegate your voting and proposition powers. You will not be sending any tokens, only the rights to vote and propose changes to the protocol. You can re-delegate or revoke power to self at any time.","Used as collateral":"Used as collateral","User cannot withdraw more than the available balance":"User cannot withdraw more than the available balance","User did not borrow the specified currency":"User did not borrow the specified currency","User does not have outstanding stable rate debt on this reserve":"User does not have outstanding stable rate debt on this reserve","User does not have outstanding variable rate debt on this reserve":"User does not have outstanding variable rate debt on this reserve","User is in isolation mode":"User is in isolation mode","User is trying to borrow multiple assets including a siloed one":"User is trying to borrow multiple assets including a siloed one","Users who stake AAVE in Safety Module (i.e. stkAAVE holders) receive a discount on GHO borrow interest rate. The discount applies to 100 GHO for every 1 stkAAVE held. Use the calculator below to see GHO borrow rate with the discount applied.":"Users who stake AAVE in Safety Module (i.e. stkAAVE holders) receive a discount on GHO borrow interest rate. The discount applies to 100 GHO for every 1 stkAAVE held. Use the calculator below to see GHO borrow rate with the discount applied.","Utilization Rate":"Utilization Rate","VIEW TX":"VIEW TX","VOTE NAY":"VOTE NAY","VOTE YAE":"VOTE YAE","Variable":"Variable","Variable debt supply is not zero":"Variable debt supply is not zero","Variable interest rate will <0>fluctuate based on the market conditions. Recommended for short-term positions.":"Variable interest rate will <0>fluctuate based on the market conditions. Recommended for short-term positions.","Variable rate":"Variable rate","Version 2":"Version 2","Version 3":"Version 3","View":"View","View Transactions":"View Transactions","View all votes":"View all votes","View contract":"View contract","View details":"View details","View on Explorer":"View on Explorer","Vote NAY":"Vote NAY","Vote YAE":"Vote YAE","Voted NAY":"Voted NAY","Voted YAE":"Voted YAE","Votes":"Votes","Voting":"Voting","Voting power":"Voting power","Voting results":"Voting results","Wallet Balance":"Wallet Balance","Wallet balance":"Wallet balance","Wallet not detected. Connect or install wallet and retry":"Wallet not detected. Connect or install wallet and retry","Wallets are provided by External Providers and by selecting you agree to Terms of those Providers. Your access to the wallet might be reliant on the External Provider being operational.":"Wallets are provided by External Providers and by selecting you agree to Terms of those Providers. Your access to the wallet might be reliant on the External Provider being operational.","We couldn't find any assets related to your search. Try again with a different asset name, symbol, or address.":"We couldn't find any assets related to your search. Try again with a different asset name, symbol, or address.","We couldn't find any transactions related to your search. Try again with a different asset name, or reset filters.":"We couldn't find any transactions related to your search. Try again with a different asset name, or reset filters.","We couldn’t detect a wallet. Connect a wallet to stake and view your balance.":"We couldn’t detect a wallet. Connect a wallet to stake and view your balance.","We suggest you go back to the Dashboard.":"We suggest you go back to the Dashboard.","Website":"Website","When a liquidation occurs, liquidators repay up to 50% of the outstanding borrowed amount on behalf of the borrower. In return, they can buy the collateral at a discount and keep the difference (liquidation penalty) as a bonus.":"When a liquidation occurs, liquidators repay up to 50% of the outstanding borrowed amount on behalf of the borrower. In return, they can buy the collateral at a discount and keep the difference (liquidation penalty) as a bonus.","With a voting power of <0/>":"With a voting power of <0/>","With testnet Faucet you can get free assets to test the Aave Protocol. Make sure to switch your wallet provider to the appropriate testnet network, select desired asset, and click ‘Faucet’ to get tokens transferred to your wallet. The assets on a testnet are not “real,” meaning they have no monetary value. <0>Learn more":"With testnet Faucet you can get free assets to test the Aave Protocol. Make sure to switch your wallet provider to the appropriate testnet network, select desired asset, and click ‘Faucet’ to get tokens transferred to your wallet. The assets on a testnet are not “real,” meaning they have no monetary value. <0>Learn more","Withdraw":"Withdraw","Withdraw & Switch":"Withdraw & Switch","Withdraw and Switch":"Withdraw and Switch","Withdraw {symbol}":["Withdraw ",["symbol"]],"Withdrawing":"Withdrawing","Withdrawing and Switching":"Withdrawing and Switching","Withdrawing this amount will reduce your health factor and increase risk of liquidation.":"Withdrawing this amount will reduce your health factor and increase risk of liquidation.","Withdrawing {symbol}":["Withdrawing ",["symbol"]],"Wrong Network":"Wrong Network","YAE":"YAE","You are entering Isolation mode":"You are entering Isolation mode","You can borrow this asset with a stable rate only if you borrow more than the amount you are supplying as collateral.":"You can borrow this asset with a stable rate only if you borrow more than the amount you are supplying as collateral.","You can not change Interest Type to stable as your borrowings are higher than your collateral":"You can not change Interest Type to stable as your borrowings are higher than your collateral","You can not disable E-Mode as your current collateralization level is above 80%, disabling E-Mode can cause liquidation. To exit E-Mode supply or repay borrowed positions.":"You can not disable E-Mode as your current collateralization level is above 80%, disabling E-Mode can cause liquidation. To exit E-Mode supply or repay borrowed positions.","You can not switch usage as collateral mode for this currency, because it will cause collateral call":"You can not switch usage as collateral mode for this currency, because it will cause collateral call","You can not use this currency as collateral":"You can not use this currency as collateral","You can not withdraw this amount because it will cause collateral call":"You can not withdraw this amount because it will cause collateral call","You can only switch to tokens with variable APY types. After this transaction, you may change the variable rate to a stable one if available.":"You can only switch to tokens with variable APY types. After this transaction, you may change the variable rate to a stable one if available.","You can only withdraw your assets from the Security Module after the cooldown period ends and the unstake window is active.":"You can only withdraw your assets from the Security Module after the cooldown period ends and the unstake window is active.","You can report incident to our <0>Discord or<1>Github.":"You can report incident to our <0>Discord or<1>Github.","You cancelled the transaction.":"You cancelled the transaction.","You did not participate in this proposal":"You did not participate in this proposal","You do not have supplies in this currency":"You do not have supplies in this currency","You don’t have enough funds in your wallet to repay the full amount. If you proceed to repay with your current amount of funds, you will still have a small borrowing position in your dashboard.":"You don’t have enough funds in your wallet to repay the full amount. If you proceed to repay with your current amount of funds, you will still have a small borrowing position in your dashboard.","You have no AAVE/stkAAVE balance to delegate.":"You have no AAVE/stkAAVE balance to delegate.","You have not borrow yet using this currency":"You have not borrow yet using this currency","You may borrow up to <0/> GHO at <1/> (max discount)":"You may borrow up to <0/> GHO at <1/> (max discount)","You may enter a custom amount in the field.":"You may enter a custom amount in the field.","You switched to {0} rate":["You switched to ",["0"]," rate"],"You unstake here":"You unstake here","You voted {0}":["You voted ",["0"]],"You will exit isolation mode and other tokens can now be used as collateral":"You will exit isolation mode and other tokens can now be used as collateral","You {action} <0/> {symbol}":["You ",["action"]," <0/> ",["symbol"]],"You've successfully switched borrow position.":"You've successfully switched borrow position.","You've successfully switched tokens.":"You've successfully switched tokens.","You've successfully withdrew & switched tokens.":"You've successfully withdrew & switched tokens.","Your balance is lower than the selected amount.":"Your balance is lower than the selected amount.","Your borrows":"Your borrows","Your current loan to value based on your collateral supplied.":"Your current loan to value based on your collateral supplied.","Your health factor and loan to value determine the assurance of your collateral. To avoid liquidations you can supply more collateral or repay borrow positions.":"Your health factor and loan to value determine the assurance of your collateral. To avoid liquidations you can supply more collateral or repay borrow positions.","Your info":"Your info","Your proposition power is based on your AAVE/stkAAVE balance and received delegations.":"Your proposition power is based on your AAVE/stkAAVE balance and received delegations.","Your reward balance is 0":"Your reward balance is 0","Your supplies":"Your supplies","Your voting info":"Your voting info","Your voting power is based on your AAVE/stkAAVE balance and received delegations.":"Your voting power is based on your AAVE/stkAAVE balance and received delegations.","Your {name} wallet is empty. Purchase or transfer assets or use <0>{0} to transfer your {network} assets.":["Your ",["name"]," wallet is empty. Purchase or transfer assets or use <0>",["0"]," to transfer your ",["network"]," assets."],"Your {name} wallet is empty. Purchase or transfer assets.":["Your ",["name"]," wallet is empty. Purchase or transfer assets."],"Your {networkName} wallet is empty. Get free test assets at":["Your ",["networkName"]," wallet is empty. Get free test assets at"],"Your {networkName} wallet is empty. Get free test {0} at":["Your ",["networkName"]," wallet is empty. Get free test ",["0"]," at"],"Zero address not valid":"Zero address not valid","assets":"assets","blocked activities":"blocked activities","copy the error":"copy the error","disabled":"disabled","documentation":"documentation","enabled":"enabled","ends":"ends","for":"for","of":"of","on":"on","please check that the amount you want to supply is not currently being used for staking. If it is being used for staking, your transaction might fail.":"please check that the amount you want to supply is not currently being used for staking. If it is being used for staking, your transaction might fail.","repaid":"repaid","stETH supplied as collateral will continue to accrue staking rewards provided by daily rebases.":"stETH supplied as collateral will continue to accrue staking rewards provided by daily rebases.","stETH tokens will be migrated to Wrapped stETH using Lido Protocol wrapper which leads to supply balance change after migration: {0}":["stETH tokens will be migrated to Wrapped stETH using Lido Protocol wrapper which leads to supply balance change after migration: ",["0"]],"staking view":"staking view","starts":"starts","stkAAVE holders get a discount on GHO borrow rate":"stkAAVE holders get a discount on GHO borrow rate","to":"to","tokens is not the same as staking them. If you wish to stake your":"tokens is not the same as staking them. If you wish to stake your","tokens, please go to the":"tokens, please go to the","withdrew":"withdrew","{0}":[["0"]],"{0} Balance":[["0"]," Balance"],"{0} Faucet":[["0"]," Faucet"],"{0} on-ramp service is provided by External Provider and by selecting you agree to Terms of the Provider. Your access to the service might be reliant on the External Provider being operational.":[["0"]," on-ramp service is provided by External Provider and by selecting you agree to Terms of the Provider. Your access to the service might be reliant on the External Provider being operational."],"{0}{name}":[["0"],["name"]],"{currentMethod}":[["currentMethod"]],"{d}d":[["d"],"d"],"{h}h":[["h"],"h"],"{m}m":[["m"],"m"],"{networkName} Faucet":[["networkName"]," Faucet"],"{notifyText}":[["notifyText"]],"{numSelected}/{numAvailable} assets selected":[["numSelected"],"/",["numAvailable"]," assets selected"],"{s}s":[["s"],"s"],"{title}":[["title"]],"{tooltipText}":[["tooltipText"]]}}; \ No newline at end of file diff --git a/src/locales/en/messages.po b/src/locales/en/messages.po index e31ddd777d..94027ce110 100644 --- a/src/locales/en/messages.po +++ b/src/locales/en/messages.po @@ -792,7 +792,6 @@ msgid "Current votes" msgstr "Current votes" #: src/components/transactions/Supply/SupplyModalContent.tsx -#: src/components/transactions/Withdraw/WithdrawModalContent.tsx msgid "DAI balance will be converted via DSR contracts and then supplied as sDAI to Aave reserve. Switching incurs no additional costs and no slippage." msgstr "DAI balance will be converted via DSR contracts and then supplied as sDAI to Aave reserve. Switching incurs no additional costs and no slippage." @@ -1280,7 +1279,6 @@ msgstr "Language" #: src/components/transactions/Warnings/DebtCeilingWarning.tsx #: src/components/transactions/Warnings/MarketWarning.tsx #: src/components/transactions/Warnings/SupplyCapWarning.tsx -#: src/components/transactions/Withdraw/WithdrawModalContent.tsx #: src/layouts/TopBarNotify.tsx #: src/modules/dashboard/LiquidationRiskParametresModal/LiquidationRiskParametresModal.tsx #: src/modules/reserve-overview/BorrowInfo.tsx @@ -2882,6 +2880,7 @@ msgid "With testnet Faucet you can get free assets to test the Aave Protocol. Ma msgstr "With testnet Faucet you can get free assets to test the Aave Protocol. Make sure to switch your wallet provider to the appropriate testnet network, select desired asset, and click ‘Faucet’ to get tokens transferred to your wallet. The assets on a testnet are not “real,” meaning they have no monetary value. <0>Learn more" #: src/components/transactions/Withdraw/WithdrawAndSwitchModalContent.tsx +#: src/components/transactions/Withdraw/WithdrawAndUnwrapActions.tsx #: src/components/transactions/Withdraw/WithdrawModal.tsx #: src/components/transactions/Withdraw/WithdrawTypeSelector.tsx #: src/modules/dashboard/lists/SuppliedPositionsList/SuppliedPositionsListItem.tsx @@ -2904,6 +2903,10 @@ msgstr "Withdraw and Switch" msgid "Withdraw {symbol}" msgstr "Withdraw {symbol}" +#: src/components/transactions/Withdraw/WithdrawAndUnwrapActions.tsx +msgid "Withdrawing" +msgstr "Withdrawing" + #: src/components/transactions/Withdraw/WithdrawAndSwitchActions.tsx msgid "Withdrawing and Switching" msgstr "Withdrawing and Switching" diff --git a/src/services/TokenWrapperService.ts b/src/services/TokenWrapperService.ts new file mode 100644 index 0000000000..763f0bc15a --- /dev/null +++ b/src/services/TokenWrapperService.ts @@ -0,0 +1,80 @@ +import { TokenWrapperServiceInterface } from '@aave/contract-helpers'; +import { SignatureLike } from '@ethersproject/bytes'; +import { Provider } from '@ethersproject/providers'; +import { BigNumber } from 'ethers'; + +export class TokenWrapperService { + private tokenWrapperService: { + [chainId: number]: { [tokenWrapperAddress: string]: TokenWrapperServiceInterface }; + } = {}; + + constructor(private chainId: number, private provider: Provider) {} + + private async getService(tokenWrapperAddress: string) { + if (!this.tokenWrapperService[this.chainId]) { + this.tokenWrapperService[this.chainId] = {}; + } + + if (!this.tokenWrapperService[this.chainId][tokenWrapperAddress]) { + this.tokenWrapperService[this.chainId][tokenWrapperAddress] = new ( + await import('@aave/contract-helpers') + ).TokenWrapperService(this.provider, tokenWrapperAddress); + } + + return this.tokenWrapperService[this.chainId][tokenWrapperAddress]; + } + + public async getTokenInForTokenOut( + amount: string, + tokenWrapperAddress: string + ): Promise { + const service = await this.getService(tokenWrapperAddress); + return service.getTokenInForTokenOut(amount); + } + + public async getTokenOutForTokenIn( + amount: string, + tokenWrapperAddress: string + ): Promise { + const service = await this.getService(tokenWrapperAddress); + return service.getTokenOutForTokenIn(amount); + } + + public async supplyWrappedToken(amount: string, tokenWrapperAddress: string, user: string) { + const service = await this.getService(tokenWrapperAddress); + return service.supplyToken(amount, user, '0'); + } + + public async supplyWrappedTokenWithPermit( + amount: string, + tokenWrapperAddress: string, + user: string, + deadline: string, + signature: SignatureLike + ) { + const service = await this.getService(tokenWrapperAddress); + return service.supplyTokenWithPermit({ + amount, + onBehalfOf: user, + referralCode: '0', + deadline, + signature, + }); + } + + public async withdrawWrappedToken(amount: string, tokenWrapperAddress: string, user: string) { + const service = await this.getService(tokenWrapperAddress); + return service.withdrawToken(amount, user); + } + + public async withdrawWrappedTokenWithPermit( + amount: string, + tokenWrapperAddress: string, + user: string, + deadline: string, + signature: SignatureLike + ) { + const service = await this.getService(tokenWrapperAddress); + return service.withdrawTokenWithPermit(amount, user, deadline, signature); + } +} diff --git a/src/store/poolSlice.ts b/src/store/poolSlice.ts index 9f470b5899..67c31e4316 100644 --- a/src/store/poolSlice.ts +++ b/src/store/poolSlice.ts @@ -23,7 +23,6 @@ import { PoolBundleInterface, ReserveDataHumanized, ReservesIncentiveDataHumanized, - SavingsDaiTokenWrapperService, UiIncentiveDataProvider, UiPoolDataProvider, UserReserveDataHumanized, @@ -42,7 +41,6 @@ import { LPSupplyParamsType, LPSupplyWithPermitType, } from '@aave/contract-helpers/dist/esm/v3-pool-contract/lendingPoolTypes'; -import { SignatureLike } from '@ethersproject/bytes'; import dayjs from 'dayjs'; import { BigNumber, PopulatedTransaction, Signature, utils } from 'ethers'; import { splitSignature } from 'ethers/lib/utils'; @@ -134,14 +132,6 @@ export interface PoolSlice { generateApproval: (args: ApproveType, opts?: GenerateApprovalOpts) => PopulatedTransaction; supply: (args: Omit) => PopulatedTransaction; supplyWithPermit: (args: Omit) => PopulatedTransaction; - getDaiForSavingsDai: (amount: string) => Promise; - getSavingsDaiForDai: (amount: string) => Promise; - supplyDaiAsSavingsDai: (amount: string) => PopulatedTransaction; - supplyDaiAsSavingsDaiWithPermit: ( - amount: string, - deadline: string, - signature: SignatureLike - ) => PopulatedTransaction; borrow: (args: Omit) => PopulatedTransaction; getCreditDelegationApprovedAmount: ( args: Omit @@ -345,56 +335,6 @@ export const createPoolSlice: StateCreator< signature, }); }, - getDaiForSavingsDai: (amount: string) => { - const provider = get().jsonRpcProvider(); - const wrapperAddress = get().currentMarketData.addresses.SDAI_TOKEN_WRAPPER; - if (!wrapperAddress) { - throw Error('sDAI wrapper is not configured'); - } - - const service = new SavingsDaiTokenWrapperService(provider, wrapperAddress); - return service.getTokenInForTokenOut(amount); - }, - getSavingsDaiForDai: (amount: string) => { - const provider = get().jsonRpcProvider(); - const wrapperAddress = get().currentMarketData.addresses.SDAI_TOKEN_WRAPPER; - if (!wrapperAddress) { - throw Error('sDAI wrapper is not configured'); - } - - const service = new SavingsDaiTokenWrapperService(provider, wrapperAddress); - return service.getTokenOutForTokenIn(amount); - }, - supplyDaiAsSavingsDai: (amount: string) => { - const provider = get().jsonRpcProvider(); - const wrapperAddress = get().currentMarketData.addresses.SDAI_TOKEN_WRAPPER; - if (!wrapperAddress) { - throw Error('sDAI wrapper is not configured'); - } - - const service = new SavingsDaiTokenWrapperService(provider, wrapperAddress); - return service.supplyToken(amount, get().account, '0'); - }, - supplyDaiAsSavingsDaiWithPermit: ( - amount: string, - deadline: string, - signature: SignatureLike - ) => { - const provider = get().jsonRpcProvider(); - const wrapperAddress = get().currentMarketData.addresses.SDAI_TOKEN_WRAPPER; - if (!wrapperAddress) { - throw Error('sDAI wrapper is not configured'); - } - - const service = new SavingsDaiTokenWrapperService(provider, wrapperAddress); - return service.supplyTokenWithPermit({ - amount, - onBehalfOf: get().account, - deadline, - signature, - referralCode: '0', - }); - }, borrow: (args: Omit) => { const poolBundle = get().getCorrectPoolBundle(); const currentAccount = get().account; diff --git a/src/ui-config/SharedDependenciesProvider.tsx b/src/ui-config/SharedDependenciesProvider.tsx index 8f1b4ec84b..9cd2f3a148 100644 --- a/src/ui-config/SharedDependenciesProvider.tsx +++ b/src/ui-config/SharedDependenciesProvider.tsx @@ -1,6 +1,7 @@ import { createContext, useContext } from 'react'; import { ApprovedAmountService } from 'src/services/ApprovedAmountService'; import { GovernanceService } from 'src/services/GovernanceService'; +import { TokenWrapperService } from 'src/services/TokenWrapperService'; import { UiIncentivesService } from 'src/services/UIIncentivesService'; import { UiPoolService } from 'src/services/UIPoolService'; import { UiStakeDataService } from 'src/services/UiStakeDataService'; @@ -20,6 +21,7 @@ interface SharedDependenciesContext { approvedAmountService: ApprovedAmountService; uiIncentivesService: UiIncentivesService; uiPoolService: UiPoolService; + tokenWrapperService: TokenWrapperService; } const SharedDependenciesContext = createContext(null); @@ -61,6 +63,7 @@ export const SharedDependenciesProvider: React.FC = ({ children }) => { const uiPoolService = new UiPoolService(getProvider); const uiIncentivesService = new UiIncentivesService(getProvider); + const tokenWrapperService = new TokenWrapperService(currentMarketData.chainId, currentProvider); return ( { approvedAmountService, uiPoolService, uiIncentivesService, + tokenWrapperService, }} > {children} diff --git a/src/ui-config/wrappedTokenConfig.ts b/src/ui-config/wrappedTokenConfig.ts index d1a498654f..65afc9cd1f 100644 --- a/src/ui-config/wrappedTokenConfig.ts +++ b/src/ui-config/wrappedTokenConfig.ts @@ -1,22 +1,29 @@ import { ChainId } from '@aave/contract-helpers'; interface WrappedTokenConfig { - tokenIn: string; - tokenOut: string; + tokenIn: Token; + tokenOut: Token; tokenWrapperContractAddress: string; } -export const wrappedTokenConfig: { [chainId: number]: { [tokenOut: string]: string } } = { - [ChainId.mainnet]: { - '0x83f20f44975d03b1b09e64809b757c47f942beea': '0x6b175474e89094c44da98b954eedeac495271d0f', // sDAI -> DAI - }, -}; +interface Token { + underlyingAsset: string; + symbol: string; +} // TODO: need to consider v2/v3 markets -export const foo: { [chainId: number]: WrappedTokenConfig } = { - [ChainId.mainnet]: { - tokenIn: '0x6B175474E89094C44Da98b954EedeAC495271d0F', //DAI - tokenOut: '0x83f20f44975d03b1b09e64809b757c47f942beea', //sDAI - tokenWrapperContractAddress: '0x437f428930669cd06adab2df4a8d4b203ac729c6', - }, +export const wrappedTokenConfig: { [chainId: number]: WrappedTokenConfig[] } = { + [ChainId.mainnet]: [ + { + tokenIn: { + underlyingAsset: '0x6B175474E89094C44Da98b954EedeAC495271d0F'.toLowerCase(), + symbol: 'DAI', + }, + tokenOut: { + underlyingAsset: '0x83f20f44975d03b1b09e64809b757c47f942beea'.toLowerCase(), + symbol: 'sDAI', + }, + tokenWrapperContractAddress: '0x437f428930669cd06adab2df4a8d4b203ac729c6', + }, + ], }; From 882e7c40db1051ba26e4b7215c1c1cd20b27283c Mon Sep 17 00:00:00 2001 From: Mark Grothe Date: Wed, 1 Nov 2023 15:17:57 -0500 Subject: [PATCH 29/46] feat: wrapped tokens refactoring --- .../WrappedTokenToolTipContent.tsx | 65 ++ .../transactions/FlowCommons/ModalWrapper.tsx | 7 +- .../transactions/Supply/SupplyModal.tsx | 4 +- .../Supply/SupplyModalContent.tsx | 556 ++++++++++++------ .../WithdrawAndSwitchModalContent.tsx | 64 +- .../app-data-provider/useAppDataProvider.tsx | 52 ++ src/hooks/token-wrapper/useTokenWrapper.ts | 5 + src/locales/en/messages.js | 2 +- src/locales/en/messages.po | 10 +- .../SupplyAssetsList/SupplyAssetsList.tsx | 21 +- .../SupplyAssetsList/SupplyAssetsListItem.tsx | 96 ++- src/utils/hfUtils.ts | 36 ++ 12 files changed, 688 insertions(+), 230 deletions(-) create mode 100644 src/components/infoTooltips/WrappedTokenToolTipContent.tsx diff --git a/src/components/infoTooltips/WrappedTokenToolTipContent.tsx b/src/components/infoTooltips/WrappedTokenToolTipContent.tsx new file mode 100644 index 0000000000..b703d6e869 --- /dev/null +++ b/src/components/infoTooltips/WrappedTokenToolTipContent.tsx @@ -0,0 +1,65 @@ +import { ArrowNarrowRightIcon } from '@heroicons/react/solid'; +import { Trans } from '@lingui/macro'; +import { Box, Skeleton, Stack, SvgIcon, Typography } from '@mui/material'; +import { useTokenInForTokenOut } from 'src/hooks/token-wrapper/useTokenWrapper'; + +import { FormattedNumber } from '../primitives/FormattedNumber'; + +export const WrappedTokenTooltipContent = ({ + decimals, + tokenWrapperAddress, + tokenInSymbol, + tokenOutSymbol, +}: { + decimals: number; + tokenWrapperAddress: string; + tokenInSymbol: string; + tokenOutSymbol: string; +}) => { + const { isFetching: loadingExchangeRate, data: exchangeRate } = useTokenInForTokenOut( + '1', + decimals, + tokenWrapperAddress + ); + + return ( + + + + DAI balance will be converted via DSR contracts and then supplied as sDAI to Aave reserve. + Switching incurs no additional costs and no slippage. + + + + + + Exchange rate + + + {loadingExchangeRate ? ( + + ) : ( + + + {tokenOutSymbol} + + + + + {tokenInSymbol} + + )} + + + ); +}; diff --git a/src/components/transactions/FlowCommons/ModalWrapper.tsx b/src/components/transactions/FlowCommons/ModalWrapper.tsx index fe2608d2a2..40e32f26c1 100644 --- a/src/components/transactions/FlowCommons/ModalWrapper.tsx +++ b/src/components/transactions/FlowCommons/ModalWrapper.tsx @@ -5,6 +5,7 @@ import { ComputedReserveData, ComputedUserReserveData, useAppDataContext, + WrappedTokenConfig, } from 'src/hooks/app-data-provider/useAppDataProvider'; import { useWalletBalances } from 'src/hooks/app-data-provider/useWalletBalances'; import { AssetCapsProvider } from 'src/hooks/useAssetCaps'; @@ -29,6 +30,7 @@ export interface ModalWrapperProps { nativeBalance: string; isWrongNetwork: boolean; action?: string; + wrappedTokenConfig?: WrappedTokenConfig; } export const ModalWrapper: React.FC<{ @@ -54,7 +56,7 @@ export const ModalWrapper: React.FC<{ const currentMarketData = useRootStore((store) => store.currentMarketData); const currentNetworkConfig = useRootStore((store) => store.currentNetworkConfig); const { walletBalances } = useWalletBalances(currentMarketData); - const { user, reserves } = useAppDataContext(); + const { user, reserves, wrappedTokenReserves } = useAppDataContext(); const { txError, mainTxState } = useModalContext(); const { permissions } = usePermissions(); @@ -115,6 +117,9 @@ export const ModalWrapper: React.FC<{ symbol, underlyingAsset, userReserve, + wrappedTokenConfig: wrappedTokenReserves.find( + (r) => r.tokenOut.underlyingAsset === underlyingAsset + ), })} ); diff --git a/src/components/transactions/Supply/SupplyModal.tsx b/src/components/transactions/Supply/SupplyModal.tsx index d6b7c25051..9d89a4b72b 100644 --- a/src/components/transactions/Supply/SupplyModal.tsx +++ b/src/components/transactions/Supply/SupplyModal.tsx @@ -5,7 +5,7 @@ import { ModalContextType, ModalType, useModalContext } from 'src/hooks/useModal import { BasicModal } from '../../primitives/BasicModal'; import { ModalWrapper } from '../FlowCommons/ModalWrapper'; -import { SupplyModalContent } from './SupplyModalContent'; +import { SupplyModalContentWrapper } from './SupplyModalContent'; export const SupplyModal = () => { const { type, close, args } = useModalContext() as ModalContextType<{ @@ -20,7 +20,7 @@ export const SupplyModal = () => { underlyingAsset={args.underlyingAsset} requiredPermission={PERMISSION.DEPOSITOR} > - {(params) => } + {(params) => } ); diff --git a/src/components/transactions/Supply/SupplyModalContent.tsx b/src/components/transactions/Supply/SupplyModalContent.tsx index 3d1077a279..0bc0cd9752 100644 --- a/src/components/transactions/Supply/SupplyModalContent.tsx +++ b/src/components/transactions/Supply/SupplyModalContent.tsx @@ -1,28 +1,31 @@ import { API_ETH_MOCK_ADDRESS } from '@aave/contract-helpers'; -import { - calculateHealthFactorFromBalancesBigUnits, - USD_DECIMALS, - valueToBigNumber, -} from '@aave/math-utils'; +import { USD_DECIMALS, valueToBigNumber } from '@aave/math-utils'; +import { ArrowNarrowRightIcon } from '@heroicons/react/solid'; import { Trans } from '@lingui/macro'; -import { Skeleton, Stack, Typography } from '@mui/material'; +import { Box, Skeleton, Stack, SvgIcon, Typography } from '@mui/material'; import BigNumber from 'bignumber.js'; -import React, { useState } from 'react'; -import { ContentWithTooltip } from 'src/components/ContentWithTooltip'; +import React, { useEffect, useState } from 'react'; import { FormattedNumber } from 'src/components/primitives/FormattedNumber'; -import { Link } from 'src/components/primitives/Link'; import { TokenIcon } from 'src/components/primitives/TokenIcon'; import { Warning } from 'src/components/primitives/Warning'; +import { TextWithTooltip } from 'src/components/TextWithTooltip'; import { AMPLWarning } from 'src/components/Warnings/AMPLWarning'; +import { CollateralType } from 'src/helpers/types'; import { useWalletBalances } from 'src/hooks/app-data-provider/useWalletBalances'; -import { useTokenOutForTokenIn } from 'src/hooks/token-wrapper/useTokenWrapper'; +import { + useTokenInForTokenOut, + useTokenOutForTokenIn, +} from 'src/hooks/token-wrapper/useTokenWrapper'; import { useAssetCaps } from 'src/hooks/useAssetCaps'; import { useModalContext } from 'src/hooks/useModal'; import { useProtocolDataContext } from 'src/hooks/useProtocolDataContext'; import { ERC20TokenType } from 'src/libs/web3-data-provider/Web3Provider'; import { useRootStore } from 'src/store/root'; -import { wrappedTokenConfig } from 'src/ui-config/wrappedTokenConfig'; -import { getMaxAmountAvailableToSupply } from 'src/utils/getMaxAmountAvailableToSupply'; +import { + getMaxAmountAvailableToSupply, + remainingCap, +} from 'src/utils/getMaxAmountAvailableToSupply'; +import { calculateHFAfterSupply } from 'src/utils/hfUtils'; import { isFeatureEnabled } from 'src/utils/marketsAndNetworksConfig'; import { GENERAL } from 'src/utils/mixPanelEvents'; import { roundToTokenDecimals } from 'src/utils/utils'; @@ -55,45 +58,101 @@ export enum ErrorType { CAP_REACHED, } +export const SupplyModalContentWrapper = (params: ModalWrapperProps) => { + const { user, wrappedTokenReserves } = useAppDataContext(); + const { currentMarketData } = useProtocolDataContext(); + const { walletBalances } = useWalletBalances(currentMarketData); + const { supplyCap: supplyCapUsage, debtCeiling: debtCeilingUsage } = useAssetCaps(); + + const { poolReserve, userReserve } = params; + + const wrappedToken = wrappedTokenReserves.find( + (r) => r.tokenOut.underlyingAsset === params.underlyingAsset + ); + + const canSupplyAsWrappedToken = + wrappedToken && + walletBalances[wrappedToken.tokenIn.underlyingAsset.toLowerCase()].amount !== '0'; + + const hasDifferentCollateral = user.userReservesData.find( + (reserve) => reserve.usageAsCollateralEnabledOnUser && reserve.reserve.id !== poolReserve.id + ); + + const showIsolationWarning: boolean = + !user.isInIsolationMode && + poolReserve.isIsolated && + !hasDifferentCollateral && + (userReserve && userReserve.underlyingBalance !== '0' + ? userReserve.usageAsCollateralEnabledOnUser + : true); + + const props: SupplyModalContentProps = { + ...params, + isolationModeWarning: showIsolationWarning ? ( + + ) : null, + addTokenProps: { + address: poolReserve.aTokenAddress, + symbol: poolReserve.iconSymbol, + decimals: poolReserve.decimals, + aToken: true, + }, + collateralType: getAssetCollateralType( + userReserve, + user.totalCollateralUSD, + user.isInIsolationMode, + debtCeilingUsage.isMaxed + ), + supplyCapWarning: supplyCapUsage.determineWarningDisplay({ supplyCap: supplyCapUsage }), + debtCeilingWarning: debtCeilingUsage.determineWarningDisplay({ debtCeiling: debtCeilingUsage }), + }; + + return canSupplyAsWrappedToken ? ( + + ) : ( + + ); +}; + +interface SupplyModalContentProps extends ModalWrapperProps { + addTokenProps: ERC20TokenType; + collateralType: CollateralType; + isolationModeWarning: React.ReactNode; + supplyCapWarning: React.ReactNode; + debtCeilingWarning: React.ReactNode; +} + export const SupplyModalContent = React.memo( ({ underlyingAsset, poolReserve, - userReserve, isWrongNetwork, nativeBalance, tokenBalance, - }: ModalWrapperProps) => { + isolationModeWarning, + addTokenProps, + collateralType, + supplyCapWarning, + debtCeilingWarning, + }: SupplyModalContentProps) => { const { marketReferencePriceInUsd, user } = useAppDataContext(); const { currentMarketData, currentNetworkConfig } = useProtocolDataContext(); const { mainTxState: supplyTxState, gasLimit, txError } = useModalContext(); - const { walletBalances } = useWalletBalances(currentMarketData); - const { supplyCap: supplyCapUsage, debtCeiling: debtCeilingUsage } = useAssetCaps(); const minRemainingBaseTokenBalance = useRootStore( (state) => state.poolComputed.minRemainingBaseTokenBalance ); // states - const [tokenToSupply, setTokenToSupply] = useState({ - address: poolReserve.underlyingAsset, - symbol: poolReserve.symbol, - iconSymbol: poolReserve.iconSymbol, - balance: tokenBalance, - }); const [amount, setAmount] = useState(''); - const supplyUnWrapped = underlyingAsset.toLowerCase() === API_ETH_MOCK_ADDRESS.toLowerCase(); const walletBalance = supplyUnWrapped ? nativeBalance : tokenBalance; - const wrappedTokenInConfig = wrappedTokenConfig[currentMarketData.chainId].find( - (c) => c.tokenOut.underlyingAsset === poolReserve.underlyingAsset - ); - const supplyApy = poolReserve.supplyAPY; const { supplyCap, totalLiquidity, isFrozen, decimals, debtCeiling, isolationModeTotalDebt } = poolReserve; + // Calculate max amount to supply const maxAmountToSupply = getMaxAmountAvailableToSupply( walletBalance, { supplyCap, totalLiquidity, isFrozen, decimals, debtCeiling, isolationModeTotalDebt }, @@ -101,33 +160,6 @@ export const SupplyModalContent = React.memo( minRemainingBaseTokenBalance ); - const assets = [ - { - balance: maxAmountToSupply, - symbol: supplyUnWrapped ? currentNetworkConfig.baseAssetSymbol : poolReserve.symbol, - iconSymbol: supplyUnWrapped ? currentNetworkConfig.baseAssetSymbol : poolReserve.iconSymbol, - address: poolReserve.underlyingAsset, - }, - ]; - - let supplyingWrappedToken = false; - if (wrappedTokenInConfig) { - const tokenToWrapBalance = - walletBalances[wrappedTokenInConfig.tokenIn.underlyingAsset]?.amount || '0'; - - if (tokenToWrapBalance !== '0') { - assets.push({ - balance: tokenToWrapBalance, - symbol: wrappedTokenInConfig.tokenIn.symbol, - iconSymbol: wrappedTokenInConfig.tokenIn.symbol, - address: wrappedTokenInConfig.tokenIn.underlyingAsset, - }); - } - - supplyingWrappedToken = - tokenToSupply.address === wrappedTokenInConfig.tokenIn.underlyingAsset; - } - const handleChange = (value: string) => { if (value === '-1') { setAmount(maxAmountToSupply); @@ -137,72 +169,17 @@ export const SupplyModalContent = React.memo( } }; - // Calculation of future HF - const amountIntEth = new BigNumber(amount).multipliedBy( + const amountInEth = new BigNumber(amount).multipliedBy( poolReserve.formattedPriceInMarketReferenceCurrency ); - // TODO: is it correct to ut to -1 if user doesnt exist? - const amountInUsd = amountIntEth + + const amountInUsd = amountInEth .multipliedBy(marketReferencePriceInUsd) .shiftedBy(-USD_DECIMALS); - const totalCollateralMarketReferenceCurrencyAfter = user - ? valueToBigNumber(user.totalCollateralMarketReferenceCurrency).plus(amountIntEth) - : '-1'; - - const liquidationThresholdAfter = user - ? valueToBigNumber(user.totalCollateralMarketReferenceCurrency) - .multipliedBy(user.currentLiquidationThreshold) - .plus(amountIntEth.multipliedBy(poolReserve.formattedReserveLiquidationThreshold)) - .dividedBy(totalCollateralMarketReferenceCurrencyAfter) - : '-1'; const isMaxSelected = amount === maxAmountToSupply; - let healthFactorAfterDeposit = user ? valueToBigNumber(user.healthFactor) : '-1'; - - if ( - user && - ((!user.isInIsolationMode && !poolReserve.isIsolated) || - (user.isInIsolationMode && - user.isolatedReserve?.underlyingAsset === poolReserve.underlyingAsset)) - ) { - healthFactorAfterDeposit = calculateHealthFactorFromBalancesBigUnits({ - collateralBalanceMarketReferenceCurrency: totalCollateralMarketReferenceCurrencyAfter, - borrowBalanceMarketReferenceCurrency: valueToBigNumber( - user.totalBorrowsMarketReferenceCurrency - ), - currentLiquidationThreshold: liquidationThresholdAfter, - }); - } - - // ************** Warnings ********** - // isolation warning - const hasDifferentCollateral = user.userReservesData.find( - (reserve) => reserve.usageAsCollateralEnabledOnUser && reserve.reserve.id !== poolReserve.id - ); - const showIsolationWarning: boolean = - !user.isInIsolationMode && - poolReserve.isIsolated && - !hasDifferentCollateral && - (userReserve && userReserve.underlyingBalance !== '0' - ? userReserve.usageAsCollateralEnabledOnUser - : true); - - // token info to add to wallet - const addToken: ERC20TokenType = { - address: poolReserve.aTokenAddress, - symbol: poolReserve.iconSymbol, - decimals: poolReserve.decimals, - aToken: true, - }; - - // collateralization state - const collateralType = getAssetCollateralType( - userReserve, - user.totalCollateralUSD, - user.isInIsolationMode, - debtCeilingUsage.isMaxed - ); + const healfthFactorAfterSupply = calculateHFAfterSupply(user, poolReserve, amountInEth); const supplyActionsProps = { amountToSupply: amount, @@ -220,15 +197,15 @@ export const SupplyModalContent = React.memo( action={Supplied} amount={amount} symbol={supplyUnWrapped ? currentNetworkConfig.baseAssetSymbol : poolReserve.symbol} - addToken={addToken} + addToken={addTokenProps} /> ); return ( <> - {showIsolationWarning && } - {supplyCapUsage.determineWarningDisplay({ supplyCap: supplyCapUsage })} - {debtCeilingUsage.determineWarningDisplay({ debtCeiling: debtCeilingUsage })} + {isolationModeWarning} + {supplyCapWarning} + {debtCeilingWarning} {poolReserve.symbol === 'AMPL' && ( @@ -243,9 +220,16 @@ export const SupplyModalContent = React.memo( value={amount} onChange={handleChange} usdValue={amountInUsd.toString(10)} - symbol={tokenToSupply.symbol} - assets={assets} - onSelect={setTokenToSupply} + symbol={supplyUnWrapped ? currentNetworkConfig.baseAssetSymbol : poolReserve.symbol} + assets={[ + { + balance: maxAmountToSupply, + symbol: supplyUnWrapped ? currentNetworkConfig.baseAssetSymbol : poolReserve.symbol, + iconSymbol: supplyUnWrapped + ? currentNetworkConfig.baseAssetSymbol + : poolReserve.iconSymbol, + }, + ]} capType={CapType.supplyCap} isMaxSelected={isMaxSelected} disabled={supplyTxState.loading} @@ -258,15 +242,6 @@ export const SupplyModalContent = React.memo( assetName: poolReserve.name, }, }} - exchangeRateComponent={ - supplyingWrappedToken && - wrappedTokenInConfig && ( - - ) - } /> @@ -279,78 +254,305 @@ export const SupplyModalContent = React.memo( {txError && } - {supplyingWrappedToken && wrappedTokenInConfig ? ( - - ) : ( - - )} + ); } ); +export const SupplyWrappedTokenModalContent = ({ + poolReserve, + wrappedTokenConfig, + isolationModeWarning, + supplyCapWarning, + debtCeilingWarning, + addTokenProps, + collateralType, +}: SupplyModalContentProps) => { + const { marketReferencePriceInUsd, user } = useAppDataContext(); + const { currentMarketData } = useProtocolDataContext(); + const { mainTxState: supplyTxState, gasLimit, txError } = useModalContext(); + const { walletBalances } = useWalletBalances(currentMarketData); + const minRemainingBaseTokenBalance = useRootStore( + (state) => state.poolComputed.minRemainingBaseTokenBalance + ); + + if (!wrappedTokenConfig) { + throw new Error('Wrapped token config is not defined'); + } + + const tokenInBalance = walletBalances[wrappedTokenConfig.tokenIn.underlyingAsset].amount; + const tokenOutBalance = walletBalances[wrappedTokenConfig.tokenOut.underlyingAsset].amount; + + const assets = [ + { + balance: tokenInBalance, + symbol: wrappedTokenConfig.tokenIn.symbol, + iconSymbol: wrappedTokenConfig.tokenIn.symbol, + address: wrappedTokenConfig.tokenIn.underlyingAsset, + }, + ]; + + if (tokenOutBalance !== '0') { + assets.unshift({ + balance: tokenOutBalance, + symbol: wrappedTokenConfig.tokenOut.symbol, + iconSymbol: wrappedTokenConfig.tokenOut.symbol, + address: wrappedTokenConfig.tokenOut.underlyingAsset, + }); + } + + const [tokenToSupply, setTokenToSupply] = useState(assets[0]); + const [amount, setAmount] = useState(''); + const [convertedTokenInAmount, setConvertedTokenInAmount] = useState('0'); + const { isFetching: loadingExchangeRate, data: exchangeRate } = useTokenInForTokenOut( + '1', + poolReserve.decimals, + wrappedTokenConfig.tokenWrapperAddress + ); + + console.log('loadingExchangeRate', loadingExchangeRate); + + useEffect(() => { + if (!exchangeRate) return; + const convertedAmount = valueToBigNumber(tokenInBalance).multipliedBy(exchangeRate).toString(); + setConvertedTokenInAmount(convertedAmount); + console.log('convertedAmount', convertedAmount); + }, [exchangeRate, tokenInBalance]); + + const { supplyCap, totalLiquidity, isFrozen, decimals, debtCeiling, isolationModeTotalDebt } = + poolReserve; + + const maxAmountToSupply = getMaxAmountAvailableToSupply( + tokenOutBalance, + { supplyCap, totalLiquidity, isFrozen, decimals, debtCeiling, isolationModeTotalDebt }, + poolReserve.underlyingAsset, + minRemainingBaseTokenBalance + ); + + const tokenOutRemainingSupplyCap = remainingCap( + poolReserve.supplyCap, + poolReserve.totalLiquidity + ); + + let maxAmountOfTokenInToSupply = tokenInBalance; + if (BigNumber(convertedTokenInAmount).isGreaterThan(tokenOutRemainingSupplyCap)) { + maxAmountOfTokenInToSupply = BigNumber(tokenOutRemainingSupplyCap) + .dividedBy(exchangeRate || '0') + .toString(); + } + + console.log(maxAmountOfTokenInToSupply); + + let supplyingWrappedToken = false; + if (wrappedTokenConfig) { + supplyingWrappedToken = tokenToSupply.address === wrappedTokenConfig.tokenIn.underlyingAsset; + } + + const handleChange = (value: string) => { + if (value === '-1') { + if (supplyingWrappedToken) { + setAmount(maxAmountOfTokenInToSupply); + } else { + setAmount(maxAmountToSupply); + } + } else { + const decimalTruncatedValue = roundToTokenDecimals(value, poolReserve.decimals); + setAmount(decimalTruncatedValue); + } + }; + + const amountInEth = new BigNumber(amount).multipliedBy( + poolReserve.formattedPriceInMarketReferenceCurrency + ); + + const amountInUsd = amountInEth.multipliedBy(marketReferencePriceInUsd).shiftedBy(-USD_DECIMALS); + + const isMaxSelected = amount === maxAmountToSupply; + + const healfthFactorAfterSupply = calculateHFAfterSupply(user, poolReserve, amountInEth); + + if (supplyTxState.success) + return ( + Supplied} + amount={amount} + symbol={poolReserve.symbol} + addToken={addTokenProps} + /> + ); + + return ( + <> + {isolationModeWarning} + {supplyCapWarning} + {debtCeilingWarning} + Wallet balance} + event={{ + eventName: GENERAL.MAX_INPUT_SELECTION, + eventParams: { + asset: poolReserve.underlyingAsset, + assetName: poolReserve.name, + }, + }} + exchangeRateComponent={ + supplyingWrappedToken && ( + + ) + } + /> + + + Supply APY} + value={poolReserve.supplyAPY} + percent + /> + + + + + + {txError && } + + {supplyingWrappedToken ? ( + + ) : ( + + )} + + ); +}; + const ExchangeRate = ({ supplyAmount, + decimals, + tokenInSymbol, + tokenOutSymbol, tokenWrapperAddress, }: { supplyAmount: string; + decimals: number; + tokenInSymbol: string; + tokenOutSymbol: string; tokenWrapperAddress: string; }) => { + const { isFetching: loadingExchangeRate, data: exchangeRate } = useTokenInForTokenOut( + '1', + decimals, + tokenWrapperAddress + ); + const { isFetching: loading, data: tokenOutAmount } = useTokenOutForTokenIn( supplyAmount, - 18, + decimals, tokenWrapperAddress ); console.log('tokenOutAmount', tokenOutAmount); return ( - - - Supply amount - - {loading ? ( - - ) : ( - <> - - - sDAI - - - )} - - + + Supply amount + + {loading ? ( + + ) : ( + <> + + + sDAI + + + )} + + + + + DAI balance will be converted via DSR contracts and then supplied as sDAI to Aave + reserve. Switching incurs no additional costs and no slippage. + + + + + + Exchange rate + + + {loadingExchangeRate ? ( + + ) : ( + + + {tokenOutSymbol} + + + + + {tokenInSymbol} + + )} + + + + ); }; -const ExchangeRateTooltip = ( - <> - - DAI balance will be converted via DSR contracts and then supplied as sDAI to Aave reserve. - Switching incurs no additional costs and no slippage. - {' '} - - Learn more - - -); diff --git a/src/components/transactions/Withdraw/WithdrawAndSwitchModalContent.tsx b/src/components/transactions/Withdraw/WithdrawAndSwitchModalContent.tsx index 9d993566bf..e068fcd5b8 100644 --- a/src/components/transactions/Withdraw/WithdrawAndSwitchModalContent.tsx +++ b/src/components/transactions/Withdraw/WithdrawAndSwitchModalContent.tsx @@ -16,9 +16,9 @@ import { useProtocolDataContext } from 'src/hooks/useProtocolDataContext'; import { useWeb3Context } from 'src/libs/hooks/useWeb3Context'; import { ListSlippageButton } from 'src/modules/dashboard/lists/SlippageList'; import { useRootStore } from 'src/store/root'; -import { wrappedTokenConfig } from 'src/ui-config/wrappedTokenConfig'; import { calculateHFAfterWithdraw } from 'src/utils/hfUtils'; import { GENERAL } from 'src/utils/mixPanelEvents'; +import { roundToTokenDecimals } from 'src/utils/utils'; import { Asset, AssetInput } from '../AssetInput'; import { GasEstimationError } from '../FlowCommons/GasEstimationError'; @@ -42,6 +42,7 @@ export const WithdrawAndSwitchModalContent = ({ userReserve, symbol, isWrongNetwork, + wrappedTokenConfig, }: ModalWrapperProps) => { const { gasLimit, mainTxState: withdrawTxState, txError } = useModalContext(); const { currentAccount } = useWeb3Context(); @@ -54,11 +55,6 @@ export const WithdrawAndSwitchModalContent = ({ const trackEvent = useRootStore((store) => store.trackEvent); const [maxSlippage, setMaxSlippage] = useState('0.1'); - // if the asset can be unwrapped (e.g. sDAI -> DAI) we don't need to use paraswap - const wrappedTokenOutConfig = wrappedTokenConfig[currentChainId].find( - (c) => c.tokenOut.underlyingAsset === poolReserve.underlyingAsset - ); - let swapTargets = reserves .filter((r) => r.underlyingAsset !== poolReserve.underlyingAsset) .map((reserve) => ({ @@ -84,22 +80,15 @@ export const WithdrawAndSwitchModalContent = ({ const maxAmountToWithdraw = calculateMaxWithdrawAmount(user, userReserve, poolReserve); const underlyingBalance = valueToBigNumber(userReserve?.underlyingBalance || '0'); - // const { loading: loadingDaiForSavingsDai, tokenInAmount } = useDaiForSavingsDaiWrapper({ - // withdrawAmount: amountRef.current, - // decimals: 18, - // }); - - // console.log(loadingDaiForSavingsDai, tokenInAmount); - let withdrawAndUnwrap = false; - if (wrappedTokenOutConfig) { - withdrawAndUnwrap = targetReserve.address === wrappedTokenOutConfig.tokenIn.underlyingAsset; + if (wrappedTokenConfig) { + withdrawAndUnwrap = targetReserve.address === wrappedTokenConfig.tokenIn.underlyingAsset; } - const { data: unwrappedAmount } = useTokenInForTokenOut( + const { data: unwrappedAmount, isFetching: loadingTokenInForTokenOut } = useTokenInForTokenOut( amountRef.current, poolReserve.decimals, - wrappedTokenOutConfig?.tokenWrapperContractAddress || '' + wrappedTokenConfig?.tokenWrapperAddress || '' ); console.log('unwrappedAmount', unwrappedAmount); @@ -122,7 +111,16 @@ export const WithdrawAndSwitchModalContent = ({ maxSlippage: Number(maxSlippage), }); - const loadingSkeleton = routeLoading && outputAmountUSD === '0'; + let outputUSD = outputAmountUSD; + if (withdrawAndUnwrap) { + outputUSD = valueToBigNumber(unwrappedAmount || '0') + .multipliedBy(wrappedTokenConfig?.tokenIn.priceInUSD || 0) + .toString(); + } + + const loadingSkeleton = + (routeLoading && outputAmountUSD === '0') || (withdrawAndUnwrap && loadingTokenInForTokenOut); + const unborrowedLiquidity = valueToBigNumber(poolReserve.unborrowedLiquidity); const assetsBlockingWithdraw: string[] = zeroLTVBlockingWithdraw(user); @@ -145,8 +143,9 @@ export const WithdrawAndSwitchModalContent = ({ const handleChange = (value: string) => { const maxSelected = value === '-1'; - amountRef.current = maxSelected ? maxAmountToWithdraw.toString(10) : value; - setAmount(value); + const truncatedValue = roundToTokenDecimals(value, poolReserve.decimals); + amountRef.current = maxSelected ? maxAmountToWithdraw.toString(10) : truncatedValue; + setAmount(truncatedValue); if (maxSelected && maxAmountToWithdraw.eq(underlyingBalance)) { trackEvent(GENERAL.MAX_INPUT_SELECTION, { type: 'withdraw' }); } @@ -162,18 +161,25 @@ export const WithdrawAndSwitchModalContent = ({ userReserve?.reserve.priceInUSD || 0 ); - if (withdrawTxState.success) + if (withdrawTxState.success) { + let amount = inputAmount; + let outAmount = outputAmount; + if (withdrawAndUnwrap) { + amount = amountRef.current; + outAmount = unwrappedAmount || '0'; + } return ( ); + } return ( <> @@ -219,7 +225,7 @@ export const WithdrawAndSwitchModalContent = ({ Receive (est.)} @@ -228,7 +234,7 @@ export const WithdrawAndSwitchModalContent = ({ loading={loadingSkeleton} /> - {error && !loadingSkeleton && ( + {error && !loadingSkeleton && !withdrawAndUnwrap && ( {error} @@ -243,7 +249,9 @@ export const WithdrawAndSwitchModalContent = ({ + withdrawAndUnwrap ? null : ( + + ) } > )} - {withdrawAndUnwrap && wrappedTokenOutConfig ? ( + {withdrawAndUnwrap ? ( ) : ( Promise; isUserHasDeposits: boolean; user: ExtendedFormattedUser; + wrappedTokenReserves: WrappedTokenConfig[]; // refreshIncentives?: () => Promise; // loading: boolean; @@ -98,6 +113,7 @@ export const AppDataProvider: React.FC = ({ children }) => { formattedPoolReserves, userSummary, displayGho, + currentChainId, ] = useRootStore((state) => [ selectCurrentReserves(state), selectCurrentBaseCurrencyData(state), @@ -110,6 +126,7 @@ export const AppDataProvider: React.FC = ({ children }) => { selectFormattedReserves(state, currentTimestamp), selectUserSummaryAndIncentives(state, currentTimestamp), state.displayGho, + state.currentChainId, ]); const formattedGhoReserveData: FormattedGhoReserveData = formatGhoReserveData({ @@ -241,6 +258,40 @@ export const AppDataProvider: React.FC = ({ children }) => { (debtAPY || 0) * (Number(user.totalBorrowsUSD) / Number(user.netWorthUSD !== '0' ? user.netWorthUSD : '1')); + const wrappedTokens = wrappedTokenConfig[currentChainId] ?? []; + let wrappedTokenReserves: WrappedTokenConfig[] = []; + if (user.userReservesData.length > 0) { + wrappedTokenReserves = wrappedTokens.map((config) => { + const tokenInReserve = user.userReservesData.find( + (userReserve) => userReserve.underlyingAsset === config.tokenIn.underlyingAsset + ); + + const tokenOutReserve = user.userReservesData.find( + (userReserve) => userReserve.underlyingAsset === config.tokenOut.underlyingAsset + ); + + if (!tokenInReserve || !tokenOutReserve) { + throw new Error('no wrapped token reserves'); + } + + return { + tokenIn: { + symbol: tokenInReserve.reserve.symbol, + underlyingAsset: tokenInReserve.reserve.underlyingAsset, + decimals: tokenInReserve.reserve.decimals, + priceInUSD: tokenInReserve.reserve.priceInUSD, + }, + tokenOut: { + symbol: tokenOutReserve.reserve.symbol, + underlyingAsset: tokenOutReserve.reserve.underlyingAsset, + decimals: tokenOutReserve.reserve.decimals, + priceInUSD: tokenOutReserve.reserve.priceInUSD, + }, + tokenWrapperAddress: config.tokenWrapperContractAddress, + }; + }); + } + return ( { }, ghoUserData: formattedGhoUserData, ghoLoadingData: !ghoReserveDataFetched, + wrappedTokenReserves, }} > {children} diff --git a/src/hooks/token-wrapper/useTokenWrapper.ts b/src/hooks/token-wrapper/useTokenWrapper.ts index 3e146c7406..4b32b3f5ec 100644 --- a/src/hooks/token-wrapper/useTokenWrapper.ts +++ b/src/hooks/token-wrapper/useTokenWrapper.ts @@ -20,6 +20,9 @@ export const useTokenInForTokenOut = ( }, queryKey: [tokenWrapperAddress, amount], select: (data) => formatUnits(data.toString(), decimals), + enabled: tokenWrapperAddress !== '', + refetchOnWindowFocus: false, + refetchOnMount: false, }); }; @@ -41,5 +44,7 @@ export const useTokenOutForTokenIn = ( queryKey: [tokenWrapperAddress, amount], select: (data) => formatUnits(data.toString(), decimals), enabled: tokenWrapperAddress !== '', + refetchOnWindowFocus: false, + refetchOnMount: false, }); }; diff --git a/src/locales/en/messages.js b/src/locales/en/messages.js index 6a5d8f0abb..f079d88ffc 100644 --- a/src/locales/en/messages.js +++ b/src/locales/en/messages.js @@ -1 +1 @@ -/*eslint-disable*/module.exports={messages:{"...":"...",".CSV":".CSV",".JSON":".JSON","<0><1><2/>Add <3/> stkAAVE to borrow at <4/> (max discount)":"<0><1><2/>Add <3/> stkAAVE to borrow at <4/> (max discount)","<0><1><2/>Add stkAAVE to see borrow rate with discount":"<0><1><2/>Add stkAAVE to see borrow rate with discount","<0>Ampleforth is a rebasing asset. Visit the <1>documentation to learn more.":"<0>Ampleforth is a rebasing asset. Visit the <1>documentation to learn more.","<0>Attention: Parameter changes via governance can alter your account health factor and risk of liquidation. Follow the <1>Aave governance forum for updates.":"<0>Attention: Parameter changes via governance can alter your account health factor and risk of liquidation. Follow the <1>Aave governance forum for updates.","<0>Slippage tolerance <1>{selectedSlippage}% <2>{0}":["<0>Slippage tolerance <1>",["selectedSlippage"],"% <2>",["0"],""],"AAVE holders (Ethereum network only) can stake their AAVE in the Safety Module to add more security to the protocol and earn Safety Incentives. In the case of a shortfall event, up to 30% of your stake can be slashed to cover the deficit, providing an additional layer of protection for the protocol.":"AAVE holders (Ethereum network only) can stake their AAVE in the Safety Module to add more security to the protocol and earn Safety Incentives. In the case of a shortfall event, up to 30% of your stake can be slashed to cover the deficit, providing an additional layer of protection for the protocol.","APR":"APR","APY":"APY","APY change":"APY change","APY type":"APY type","APY type change":"APY type change","APY with discount applied":"APY with discount applied","APY, fixed rate":"APY, fixed rate","APY, stable":"APY, stable","APY, variable":"APY, variable","AToken supply is not zero":"AToken supply is not zero","Aave Governance":"Aave Governance","Aave aToken":"Aave aToken","Aave debt token":"Aave debt token","Aave is a fully decentralized, community governed protocol by the AAVE token-holders. AAVE token-holders collectively discuss, propose, and vote on upgrades to the protocol. AAVE token-holders (Ethereum network only) can either vote themselves on new proposals or delagate to an address of choice. To learn more check out the Governance":"Aave is a fully decentralized, community governed protocol by the AAVE token-holders. AAVE token-holders collectively discuss, propose, and vote on upgrades to the protocol. AAVE token-holders (Ethereum network only) can either vote themselves on new proposals or delagate to an address of choice. To learn more check out the Governance","Aave per month":"Aave per month","About GHO":"About GHO","Account":"Account","Action cannot be performed because the reserve is frozen":"Action cannot be performed because the reserve is frozen","Action cannot be performed because the reserve is paused":"Action cannot be performed because the reserve is paused","Action requires an active reserve":"Action requires an active reserve","Activate Cooldown":"Activate Cooldown","Add stkAAVE to see borrow APY with the discount":"Add stkAAVE to see borrow APY with the discount","Add to wallet":"Add to wallet","Add {0} to wallet to track your balance.":["Add ",["0"]," to wallet to track your balance."],"Address is not a contract":"Address is not a contract","Addresses":"Addresses","Addresses ({0})":["Addresses (",["0"],")"],"All Assets":"All Assets","All done!":"All done!","All proposals":"All proposals","All transactions":"All transactions","Allowance required action":"Allowance required action","Allows you to decide whether to use a supplied asset as collateral. An asset used as collateral will affect your borrowing power and health factor.":"Allows you to decide whether to use a supplied asset as collateral. An asset used as collateral will affect your borrowing power and health factor.","Allows you to switch between <0>variable and <1>stable interest rates, where variable rate can increase and decrease depending on the amount of liquidity in the reserve, and stable rate will stay the same for the duration of your loan.":"Allows you to switch between <0>variable and <1>stable interest rates, where variable rate can increase and decrease depending on the amount of liquidity in the reserve, and stable rate will stay the same for the duration of your loan.","Amount":"Amount","Amount claimable":"Amount claimable","Amount in cooldown":"Amount in cooldown","Amount must be greater than 0":"Amount must be greater than 0","Amount to unstake":"Amount to unstake","An error has occurred fetching the proposal metadata from IPFS.":"An error has occurred fetching the proposal metadata from IPFS.","Approve Confirmed":"Approve Confirmed","Approve with":"Approve with","Approve {symbol} to continue":["Approve ",["symbol"]," to continue"],"Approving {symbol}...":["Approving ",["symbol"],"..."],"Array parameters that should be equal length are not":"Array parameters that should be equal length are not","Asset":"Asset","Asset can be only used as collateral in isolation mode with limited borrowing power. To enter isolation mode, disable all other collateral.":"Asset can be only used as collateral in isolation mode with limited borrowing power. To enter isolation mode, disable all other collateral.","Asset can only be used as collateral in isolation mode only.":"Asset can only be used as collateral in isolation mode only.","Asset cannot be migrated because you have isolated collateral in {marketName} v3 Market which limits borrowable assets. You can manage your collateral in <0>{marketName} V3 Dashboard":["Asset cannot be migrated because you have isolated collateral in ",["marketName"]," v3 Market which limits borrowable assets. You can manage your collateral in <0>",["marketName"]," V3 Dashboard"],"Asset cannot be migrated due to insufficient liquidity or borrow cap limitation in {marketName} v3 market.":["Asset cannot be migrated due to insufficient liquidity or borrow cap limitation in ",["marketName"]," v3 market."],"Asset cannot be migrated due to supply cap restriction in {marketName} v3 market.":["Asset cannot be migrated due to supply cap restriction in ",["marketName"]," v3 market."],"Asset cannot be migrated to {marketName} V3 Market due to E-mode restrictions. You can disable or manage E-mode categories in your <0>V3 Dashboard":["Asset cannot be migrated to ",["marketName"]," V3 Market due to E-mode restrictions. You can disable or manage E-mode categories in your <0>V3 Dashboard"],"Asset cannot be migrated to {marketName} v3 Market since collateral asset will enable isolation mode.":["Asset cannot be migrated to ",["marketName"]," v3 Market since collateral asset will enable isolation mode."],"Asset cannot be used as collateral.":"Asset cannot be used as collateral.","Asset category":"Asset category","Asset is frozen in {marketName} v3 market, hence this position cannot be migrated.":["Asset is frozen in ",["marketName"]," v3 market, hence this position cannot be migrated."],"Asset is not borrowable in isolation mode":"Asset is not borrowable in isolation mode","Asset is not listed":"Asset is not listed","Asset supply is limited to a certain amount to reduce protocol exposure to the asset and to help manage risks involved.":"Asset supply is limited to a certain amount to reduce protocol exposure to the asset and to help manage risks involved.","Assets":"Assets","Assets to borrow":"Assets to borrow","Assets to supply":"Assets to supply","Assets with zero LTV ({assetsBlockingWithdraw}) must be withdrawn or disabled as collateral to perform this action":["Assets with zero LTV (",["assetsBlockingWithdraw"],") must be withdrawn or disabled as collateral to perform this action"],"At a discount":"At a discount","Author":"Author","Available":"Available","Available assets":"Available assets","Available liquidity":"Available liquidity","Available on":"Available on","Available rewards":"Available rewards","Available to borrow":"Available to borrow","Available to supply":"Available to supply","Back to Dashboard":"Back to Dashboard","Balance":"Balance","Balance to revoke":"Balance to revoke","Be careful - You are very close to liquidation. Consider depositing more collateral or paying down some of your borrowed positions":"Be careful - You are very close to liquidation. Consider depositing more collateral or paying down some of your borrowed positions","Be mindful of the network congestion and gas prices.":"Be mindful of the network congestion and gas prices.","Because this asset is paused, no actions can be taken until further notice":"Because this asset is paused, no actions can be taken until further notice","Before supplying":"Before supplying","Blocked Address":"Blocked Address","Borrow":"Borrow","Borrow APY":"Borrow APY","Borrow APY rate":"Borrow APY rate","Borrow APY, fixed rate":"Borrow APY, fixed rate","Borrow APY, stable":"Borrow APY, stable","Borrow APY, variable":"Borrow APY, variable","Borrow amount to reach {0}% utilization":["Borrow amount to reach ",["0"],"% utilization"],"Borrow and repay in same block is not allowed":"Borrow and repay in same block is not allowed","Borrow apy":"Borrow apy","Borrow balance":"Borrow balance","Borrow balance after repay":"Borrow balance after repay","Borrow balance after switch":"Borrow balance after switch","Borrow cap":"Borrow cap","Borrow cap is exceeded":"Borrow cap is exceeded","Borrow info":"Borrow info","Borrow power used":"Borrow power used","Borrow rate change":"Borrow rate change","Borrow {symbol}":["Borrow ",["symbol"]],"Borrowed":"Borrowed","Borrowed asset amount":"Borrowed asset amount","Borrowing is currently unavailable for {0}.":["Borrowing is currently unavailable for ",["0"],"."],"Borrowing is disabled due to an Aave community decision. <0>More details":"Borrowing is disabled due to an Aave community decision. <0>More details","Borrowing is not enabled":"Borrowing is not enabled","Borrowing is unavailable because you’re using Isolation mode. To manage Isolation mode visit your <0>Dashboard.":"Borrowing is unavailable because you’re using Isolation mode. To manage Isolation mode visit your <0>Dashboard.","Borrowing is unavailable because you’ve enabled Efficiency Mode (E-Mode) and Isolation mode. To manage E-Mode and Isolation mode visit your <0>Dashboard.":"Borrowing is unavailable because you’ve enabled Efficiency Mode (E-Mode) and Isolation mode. To manage E-Mode and Isolation mode visit your <0>Dashboard.","Borrowing is unavailable because you’ve enabled Efficiency Mode (E-Mode) for {0} category. To manage E-Mode categories visit your <0>Dashboard.":["Borrowing is unavailable because you’ve enabled Efficiency Mode (E-Mode) for ",["0"]," category. To manage E-Mode categories visit your <0>Dashboard."],"Borrowing of this asset is limited to a certain amount to minimize liquidity pool insolvency.":"Borrowing of this asset is limited to a certain amount to minimize liquidity pool insolvency.","Borrowing power and assets are limited due to Isolation mode.":"Borrowing power and assets are limited due to Isolation mode.","Borrowing this amount will reduce your health factor and increase risk of liquidation.":"Borrowing this amount will reduce your health factor and increase risk of liquidation.","Borrowing {symbol}":["Borrowing ",["symbol"]],"Both":"Both","Buy Crypto With Fiat":"Buy Crypto With Fiat","Buy Crypto with Fiat":"Buy Crypto with Fiat","Buy {cryptoSymbol} with Fiat":["Buy ",["cryptoSymbol"]," with Fiat"],"COPIED!":"COPIED!","COPY IMAGE":"COPY IMAGE","Can be collateral":"Can be collateral","Can be executed":"Can be executed","Cancel":"Cancel","Cannot disable E-Mode":"Cannot disable E-Mode","Choose how much voting/proposition power to give to someone else by delegating some of your AAVE or stkAAVE balance. Your tokens will remain in your account, but your delegate will be able to vote or propose on your behalf. If your AAVE or stkAAVE balance changes, your delegate's voting/proposition power will be automatically adjusted.":"Choose how much voting/proposition power to give to someone else by delegating some of your AAVE or stkAAVE balance. Your tokens will remain in your account, but your delegate will be able to vote or propose on your behalf. If your AAVE or stkAAVE balance changes, your delegate's voting/proposition power will be automatically adjusted.","Choose one of the on-ramp services":"Choose one of the on-ramp services","Claim":"Claim","Claim all":"Claim all","Claim all rewards":"Claim all rewards","Claim {0}":["Claim ",["0"]],"Claim {symbol}":["Claim ",["symbol"]],"Claimable AAVE":"Claimable AAVE","Claimed":"Claimed","Claiming":"Claiming","Claiming {symbol}":["Claiming ",["symbol"]],"Close":"Close","Collateral":"Collateral","Collateral balance after repay":"Collateral balance after repay","Collateral change":"Collateral change","Collateral is (mostly) the same currency that is being borrowed":"Collateral is (mostly) the same currency that is being borrowed","Collateral to repay with":"Collateral to repay with","Collateral usage":"Collateral usage","Collateral usage is limited because of Isolation mode.":"Collateral usage is limited because of Isolation mode.","Collateral usage is limited because of isolation mode.":"Collateral usage is limited because of isolation mode.","Collateral usage is limited because of isolation mode. <0>Learn More":"Collateral usage is limited because of isolation mode. <0>Learn More","Collateralization":"Collateralization","Collector Contract":"Collector Contract","Collector Info":"Collector Info","Connect wallet":"Connect wallet","Cooldown period":"Cooldown period","Cooldown period warning":"Cooldown period warning","Cooldown time left":"Cooldown time left","Cooldown to unstake":"Cooldown to unstake","Cooling down...":"Cooling down...","Copy address":"Copy address","Copy error message":"Copy error message","Copy error text":"Copy error text","Covered debt":"Covered debt","Created":"Created","Current LTV":"Current LTV","Current differential":"Current differential","Current v2 Balance":"Current v2 Balance","Current v2 balance":"Current v2 balance","Current votes":"Current votes","DAI balance will be converted via DSR contracts and then supplied as sDAI to Aave reserve. Switching incurs no additional costs and no slippage.":"DAI balance will be converted via DSR contracts and then supplied as sDAI to Aave reserve. Switching incurs no additional costs and no slippage.","Dark mode":"Dark mode","Dashboard":"Dashboard","Data couldn't be fetched, please reload graph.":"Data couldn't be fetched, please reload graph.","Debt":"Debt","Debt ceiling is exceeded":"Debt ceiling is exceeded","Debt ceiling is not zero":"Debt ceiling is not zero","Debt ceiling limits the amount possible to borrow against this asset by protocol users. Debt ceiling is specific to assets in isolation mode and is denoted in USD.":"Debt ceiling limits the amount possible to borrow against this asset by protocol users. Debt ceiling is specific to assets in isolation mode and is denoted in USD.","Delegated power":"Delegated power","Details":"Details","Developers":"Developers","Differential":"Differential","Disable E-Mode":"Disable E-Mode","Disable testnet":"Disable testnet","Disable {symbol} as collateral":["Disable ",["symbol"]," as collateral"],"Disabled":"Disabled","Disabling E-Mode":"Disabling E-Mode","Disabling this asset as collateral affects your borrowing power and Health Factor.":"Disabling this asset as collateral affects your borrowing power and Health Factor.","Disconnect Wallet":"Disconnect Wallet","Discord channel":"Discord channel","Discount":"Discount","Discount applied for <0/> staking AAVE":"Discount applied for <0/> staking AAVE","Discount model parameters":"Discount model parameters","Discount parameters are decided by the Aave community and may be changed over time. Check Governance for updates and vote to participate. <0>Learn more":"Discount parameters are decided by the Aave community and may be changed over time. Check Governance for updates and vote to participate. <0>Learn more","Discountable amount":"Discountable amount","Docs":"Docs","Download":"Download","Due to internal stETH mechanics required for rebasing support, it is not possible to perform a collateral switch where stETH is the source token.":"Due to internal stETH mechanics required for rebasing support, it is not possible to perform a collateral switch where stETH is the source token.","Due to the Horizon bridge exploit, certain assets on the Harmony network are not at parity with Ethereum, which affects the Aave V3 Harmony market.":"Due to the Horizon bridge exploit, certain assets on the Harmony network are not at parity with Ethereum, which affects the Aave V3 Harmony market.","E-Mode":"E-Mode","E-Mode Category":"E-Mode Category","E-Mode category":"E-Mode category","E-Mode increases your LTV for a selected category of assets up to 97%. <0>Learn more":"E-Mode increases your LTV for a selected category of assets up to 97%. <0>Learn more","E-Mode increases your LTV for a selected category of assets up to<0/>. <1>Learn more":"E-Mode increases your LTV for a selected category of assets up to<0/>. <1>Learn more","E-Mode increases your LTV for a selected category of assets, meaning that when E-mode is enabled, you will have higher borrowing power over assets of the same E-mode category which are defined by Aave Governance. You can enter E-Mode from your <0>Dashboard. To learn more about E-Mode and applied restrictions in <1>FAQ or <2>Aave V3 Technical Paper.":"E-Mode increases your LTV for a selected category of assets, meaning that when E-mode is enabled, you will have higher borrowing power over assets of the same E-mode category which are defined by Aave Governance. You can enter E-Mode from your <0>Dashboard. To learn more about E-Mode and applied restrictions in <1>FAQ or <2>Aave V3 Technical Paper.","Effective interest rate":"Effective interest rate","Efficiency mode (E-Mode)":"Efficiency mode (E-Mode)","Emode":"Emode","Enable E-Mode":"Enable E-Mode","Enable {symbol} as collateral":["Enable ",["symbol"]," as collateral"],"Enabled":"Enabled","Enabling E-Mode":"Enabling E-Mode","Enabling E-Mode only allows you to borrow assets belonging to the selected category. Please visit our <0>FAQ guide to learn more about how it works and the applied restrictions.":"Enabling E-Mode only allows you to borrow assets belonging to the selected category. Please visit our <0>FAQ guide to learn more about how it works and the applied restrictions.","Enabling this asset as collateral increases your borrowing power and Health Factor. However, it can get liquidated if your health factor drops below 1.":"Enabling this asset as collateral increases your borrowing power and Health Factor. However, it can get liquidated if your health factor drops below 1.","Ended":"Ended","Ends":"Ends","English":"English","Enter ETH address":"Enter ETH address","Enter an amount":"Enter an amount","Error connecting. Try refreshing the page.":"Error connecting. Try refreshing the page.","Estimated compounding interest, including discount for Staking {0}AAVE in Safety Module.":["Estimated compounding interest, including discount for Staking ",["0"],"AAVE in Safety Module."],"Exceeds the discount":"Exceeds the discount","Executed":"Executed","Expected amount to repay":"Expected amount to repay","Expires":"Expires","Export data to":"Export data to","FAQ":"FAQ","FAQS":"FAQS","Failed to load proposal voters. Please refresh the page.":"Failed to load proposal voters. Please refresh the page.","Faucet":"Faucet","Faucet {0}":["Faucet ",["0"]],"Fetching data...":"Fetching data...","Filter":"Filter","Fixed":"Fixed","Fixed rate":"Fixed rate","Flashloan is disabled for this asset, hence this position cannot be migrated.":"Flashloan is disabled for this asset, hence this position cannot be migrated.","For repayment of a specific type of debt, the user needs to have debt that type":"For repayment of a specific type of debt, the user needs to have debt that type","Forum discussion":"Forum discussion","French":"French","Funds in the Safety Module":"Funds in the Safety Module","GHO is a native decentralized, collateral-backed digital asset pegged to USD. It is created by users via borrowing against multiple collateral. When user repays their GHO borrow position, the protocol burns that user's GHO. All the interest payments accrued by minters of GHO would be directly transferred to the AaveDAO treasury.":"GHO is a native decentralized, collateral-backed digital asset pegged to USD. It is created by users via borrowing against multiple collateral. When user repays their GHO borrow position, the protocol burns that user's GHO. All the interest payments accrued by minters of GHO would be directly transferred to the AaveDAO treasury.","Get ABP Token":"Get ABP Token","Global settings":"Global settings","Go Back":"Go Back","Go to Balancer Pool":"Go to Balancer Pool","Go to V3 Dashboard":"Go to V3 Dashboard","Governance":"Governance","Greek":"Greek","Health Factor ({0} v2)":["Health Factor (",["0"]," v2)"],"Health Factor ({0} v3)":["Health Factor (",["0"]," v3)"],"Health factor":"Health factor","Health factor is lesser than the liquidation threshold":"Health factor is lesser than the liquidation threshold","Health factor is not below the threshold":"Health factor is not below the threshold","Hide":"Hide","Holders of stkAAVE receive a discount on the GHO borrowing rate":"Holders of stkAAVE receive a discount on the GHO borrowing rate","I acknowledge the risks involved.":"I acknowledge the risks involved.","I fully understand the risks of migrating.":"I fully understand the risks of migrating.","I understand how cooldown ({0}) and unstaking ({1}) work":["I understand how cooldown (",["0"],") and unstaking (",["1"],") work"],"If the error continues to happen,<0/> you may report it to this":"If the error continues to happen,<0/> you may report it to this","If the health factor goes below 1, the liquidation of your collateral might be triggered.":"If the health factor goes below 1, the liquidation of your collateral might be triggered.","If you DO NOT unstake within {0} of unstake window, you will need to activate cooldown process again.":["If you DO NOT unstake within ",["0"]," of unstake window, you will need to activate cooldown process again."],"If your loan to value goes above the liquidation threshold your collateral supplied may be liquidated.":"If your loan to value goes above the liquidation threshold your collateral supplied may be liquidated.","In E-Mode some assets are not borrowable. Exit E-Mode to get access to all assets":"In E-Mode some assets are not borrowable. Exit E-Mode to get access to all assets","In Isolation mode, you cannot supply other assets as collateral. A global debt ceiling limits the borrowing power of the isolated asset. To exit isolation mode disable {0} as collateral before borrowing another asset. Read more in our <0>FAQ":["In Isolation mode, you cannot supply other assets as collateral. A global debt ceiling limits the borrowing power of the isolated asset. To exit isolation mode disable ",["0"]," as collateral before borrowing another asset. Read more in our <0>FAQ"],"Inconsistent flashloan parameters":"Inconsistent flashloan parameters","Insufficient collateral to cover new borrow position. Wallet must have borrowing power remaining to perform debt switch.":"Insufficient collateral to cover new borrow position. Wallet must have borrowing power remaining to perform debt switch.","Interest accrued":"Interest accrued","Interest rate rebalance conditions were not met":"Interest rate rebalance conditions were not met","Interest rate strategy":"Interest rate strategy","Invalid amount to burn":"Invalid amount to burn","Invalid amount to mint":"Invalid amount to mint","Invalid bridge protocol fee":"Invalid bridge protocol fee","Invalid expiration":"Invalid expiration","Invalid flashloan premium":"Invalid flashloan premium","Invalid return value of the flashloan executor function":"Invalid return value of the flashloan executor function","Invalid signature":"Invalid signature","Isolated":"Isolated","Isolated Debt Ceiling":"Isolated Debt Ceiling","Isolated assets have limited borrowing power and other assets cannot be used as collateral.":"Isolated assets have limited borrowing power and other assets cannot be used as collateral.","Join the community discussion":"Join the community discussion","LEARN MORE":"LEARN MORE","Language":"Language","Learn more":"Learn more","Learn more about risks involved":"Learn more about risks involved","Learn more in our <0>FAQ guide":"Learn more in our <0>FAQ guide","Learn more.":"Learn more.","Links":"Links","Liqudation":"Liqudation","Liquidated collateral":"Liquidated collateral","Liquidation":"Liquidation","Liquidation <0/> threshold":"Liquidation <0/> threshold","Liquidation Threshold":"Liquidation Threshold","Liquidation at":"Liquidation at","Liquidation penalty":"Liquidation penalty","Liquidation risk":"Liquidation risk","Liquidation risk parameters":"Liquidation risk parameters","Liquidation threshold":"Liquidation threshold","Liquidation value":"Liquidation value","Loading data...":"Loading data...","Ltv validation failed":"Ltv validation failed","MAI has been paused due to a community decision. Supply, borrows and repays are impacted. <0>More details":"MAI has been paused due to a community decision. Supply, borrows and repays are impacted. <0>More details","MAX":"MAX","Manage analytics":"Manage analytics","Market":"Market","Markets":"Markets","Max":"Max","Max LTV":"Max LTV","Max slashing":"Max slashing","Max slippage":"Max slippage","Maximum amount available to borrow against this asset is limited because debt ceiling is at {0}%.":["Maximum amount available to borrow against this asset is limited because debt ceiling is at ",["0"],"%."],"Maximum amount available to borrow is <0/> {0} (<1/>).":["Maximum amount available to borrow is <0/> ",["0"]," (<1/>)."],"Maximum amount available to borrow is limited because protocol borrow cap is nearly reached.":"Maximum amount available to borrow is limited because protocol borrow cap is nearly reached.","Maximum amount available to supply is <0/> {0} (<1/>).":["Maximum amount available to supply is <0/> ",["0"]," (<1/>)."],"Maximum amount available to supply is limited because protocol supply cap is at {0}%.":["Maximum amount available to supply is limited because protocol supply cap is at ",["0"],"%."],"Maximum loan to value":"Maximum loan to value","Meet GHO":"Meet GHO","Menu":"Menu","Migrate":"Migrate","Migrate to V3":"Migrate to V3","Migrate to v3":"Migrate to v3","Migrate to {0} v3 Market":["Migrate to ",["0"]," v3 Market"],"Migrated":"Migrated","Migrating":"Migrating","Migrating multiple collaterals and borrowed assets at the same time can be an expensive operation and might fail in certain situations.<0>Therefore it’s not recommended to migrate positions with more than 5 assets (deposited + borrowed) at the same time.":"Migrating multiple collaterals and borrowed assets at the same time can be an expensive operation and might fail in certain situations.<0>Therefore it’s not recommended to migrate positions with more than 5 assets (deposited + borrowed) at the same time.","Migration risks":"Migration risks","Minimum GHO borrow amount":"Minimum GHO borrow amount","Minimum USD value received":"Minimum USD value received","Minimum staked Aave amount":"Minimum staked Aave amount","Minimum {0} received":["Minimum ",["0"]," received"],"More":"More","NAY":"NAY","Need help connecting a wallet? <0>Read our FAQ":"Need help connecting a wallet? <0>Read our FAQ","Net APR":"Net APR","Net APY":"Net APY","Net APY is the combined effect of all supply and borrow positions on net worth, including incentives. It is possible to have a negative net APY if debt APY is higher than supply APY.":"Net APY is the combined effect of all supply and borrow positions on net worth, including incentives. It is possible to have a negative net APY if debt APY is higher than supply APY.","Net worth":"Net worth","Network":"Network","Network not supported for this wallet":"Network not supported for this wallet","New APY":"New APY","No assets selected to migrate.":"No assets selected to migrate.","No rewards to claim":"No rewards to claim","No search results{0}":["No search results",["0"]],"No transactions yet.":"No transactions yet.","No voting power":"No voting power","None":"None","Not a valid address":"Not a valid address","Not enough balance on your wallet":"Not enough balance on your wallet","Not enough collateral to repay this amount of debt with":"Not enough collateral to repay this amount of debt with","Not enough staked balance":"Not enough staked balance","Not enough voting power to participate in this proposal":"Not enough voting power to participate in this proposal","Not reached":"Not reached","Nothing borrowed yet":"Nothing borrowed yet","Nothing found":"Nothing found","Nothing staked":"Nothing staked","Nothing supplied yet":"Nothing supplied yet","Notify":"Notify","Ok, Close":"Ok, Close","Ok, I got it":"Ok, I got it","Operation not supported":"Operation not supported","Oracle price":"Oracle price","Overview":"Overview","Page not found":"Page not found","Participating in this {symbol} reserve gives annualized rewards.":["Participating in this ",["symbol"]," reserve gives annualized rewards."],"Pending...":"Pending...","Per the community, the Fantom market has been frozen.":"Per the community, the Fantom market has been frozen.","Per the community, the V2 AMM market has been deprecated.":"Per the community, the V2 AMM market has been deprecated.","Please always be aware of your <0>Health Factor (HF) when partially migrating a position and that your rates will be updated to V3 rates.":"Please always be aware of your <0>Health Factor (HF) when partially migrating a position and that your rates will be updated to V3 rates.","Please connect a wallet to view your personal information here.":"Please connect a wallet to view your personal information here.","Please connect your wallet to be able to switch your tokens.":"Please connect your wallet to be able to switch your tokens.","Please connect your wallet to get free testnet assets.":"Please connect your wallet to get free testnet assets.","Please connect your wallet to see migration tool.":"Please connect your wallet to see migration tool.","Please connect your wallet to see your supplies, borrowings, and open positions.":"Please connect your wallet to see your supplies, borrowings, and open positions.","Please connect your wallet to view transaction history.":"Please connect your wallet to view transaction history.","Please enter a valid wallet address.":"Please enter a valid wallet address.","Please switch to {networkName}.":["Please switch to ",["networkName"],"."],"Please, connect your wallet":"Please, connect your wallet","Pool addresses provider is not registered":"Pool addresses provider is not registered","Powered by":"Powered by","Preview tx and migrate":"Preview tx and migrate","Price":"Price","Price data is not currently available for this reserve on the protocol subgraph":"Price data is not currently available for this reserve on the protocol subgraph","Price impact":"Price impact","Price impact is the spread between the total value of the entry tokens switched and the destination tokens obtained (in USD), which results from the limited liquidity of the trading pair.":"Price impact is the spread between the total value of the entry tokens switched and the destination tokens obtained (in USD), which results from the limited liquidity of the trading pair.","Price impact {0}%":["Price impact ",["0"],"%"],"Privacy":"Privacy","Proposal details":"Proposal details","Proposal overview":"Proposal overview","Proposals":"Proposals","Proposition":"Proposition","Protocol borrow cap at 100% for this asset. Further borrowing unavailable.":"Protocol borrow cap at 100% for this asset. Further borrowing unavailable.","Protocol borrow cap is at 100% for this asset. Further borrowing unavailable.":"Protocol borrow cap is at 100% for this asset. Further borrowing unavailable.","Protocol debt ceiling is at 100% for this asset. Further borrowing against this asset is unavailable.":"Protocol debt ceiling is at 100% for this asset. Further borrowing against this asset is unavailable.","Protocol debt ceiling is at 100% for this asset. Futher borrowing against this asset is unavailable.":"Protocol debt ceiling is at 100% for this asset. Futher borrowing against this asset is unavailable.","Protocol supply cap at 100% for this asset. Further supply unavailable.":"Protocol supply cap at 100% for this asset. Further supply unavailable.","Protocol supply cap is at 100% for this asset. Further supply unavailable.":"Protocol supply cap is at 100% for this asset. Further supply unavailable.","Quorum":"Quorum","Rate change":"Rate change","Raw-Ipfs":"Raw-Ipfs","Reached":"Reached","Reactivate cooldown period to unstake {0} {stakedToken}":["Reactivate cooldown period to unstake ",["0"]," ",["stakedToken"]],"Read more here.":"Read more here.","Read-only mode allows to see address positions in Aave, but you won't be able to perform transactions.":"Read-only mode allows to see address positions in Aave, but you won't be able to perform transactions.","Read-only mode.":"Read-only mode.","Read-only mode. Connect to a wallet to perform transactions.":"Read-only mode. Connect to a wallet to perform transactions.","Receive (est.)":"Receive (est.)","Received":"Received","Recipient address":"Recipient address","Rejected connection request":"Rejected connection request","Reload":"Reload","Reload the page":"Reload the page","Remaining debt":"Remaining debt","Remaining supply":"Remaining supply","Repaid":"Repaid","Repay":"Repay","Repay with":"Repay with","Repay {symbol}":["Repay ",["symbol"]],"Repaying {symbol}":["Repaying ",["symbol"]],"Repayment amount to reach {0}% utilization":["Repayment amount to reach ",["0"],"% utilization"],"Reserve Size":"Reserve Size","Reserve factor":"Reserve factor","Reserve factor is a percentage of interest which goes to a {0} that is controlled by Aave governance to promote ecosystem growth.":["Reserve factor is a percentage of interest which goes to a ",["0"]," that is controlled by Aave governance to promote ecosystem growth."],"Reserve status & configuration":"Reserve status & configuration","Reset":"Reset","Restake":"Restake","Restake {symbol}":["Restake ",["symbol"]],"Restaked":"Restaked","Restaking {symbol}":["Restaking ",["symbol"]],"Review approval tx details":"Review approval tx details","Review changes to continue":"Review changes to continue","Review tx":"Review tx","Review tx details":"Review tx details","Revoke power":"Revoke power","Reward(s) to claim":"Reward(s) to claim","Rewards APR":"Rewards APR","Risk details":"Risk details","SEE CHARTS":"SEE CHARTS","Safety of your deposited collateral against the borrowed assets and its underlying value.":"Safety of your deposited collateral against the borrowed assets and its underlying value.","Save and share":"Save and share","Seatbelt report":"Seatbelt report","Seems like we can't switch the network automatically. Please check if you can change it from the wallet.":"Seems like we can't switch the network automatically. Please check if you can change it from the wallet.","Select":"Select","Select APY type to switch":"Select APY type to switch","Select an asset":"Select an asset","Select language":"Select language","Select slippage tolerance":"Select slippage tolerance","Select v2 borrows to migrate":"Select v2 borrows to migrate","Select v2 supplies to migrate":"Select v2 supplies to migrate","Selected assets have successfully migrated. Visit the Market Dashboard to see them.":"Selected assets have successfully migrated. Visit the Market Dashboard to see them.","Selected borrow assets":"Selected borrow assets","Selected supply assets":"Selected supply assets","Send feedback":"Send feedback","Set up delegation":"Set up delegation","Setup notifications about your Health Factor using the Hal app.":"Setup notifications about your Health Factor using the Hal app.","Share on Lens":"Share on Lens","Share on twitter":"Share on twitter","Show":"Show","Show Frozen or paused assets":"Show Frozen or paused assets","Show assets with 0 balance":"Show assets with 0 balance","Sign to continue":"Sign to continue","Signatures ready":"Signatures ready","Signing":"Signing","Since this asset is frozen, the only available actions are withdraw and repay which can be accessed from the <0>Dashboard":"Since this asset is frozen, the only available actions are withdraw and repay which can be accessed from the <0>Dashboard","Since this is a test network, you can get any of the assets if you have ETH on your wallet":"Since this is a test network, you can get any of the assets if you have ETH on your wallet","Slippage":"Slippage","Slippage is the difference between the quoted and received amounts from changing market conditions between the moment the transaction is submitted and its verification.":"Slippage is the difference between the quoted and received amounts from changing market conditions between the moment the transaction is submitted and its verification.","Some migrated assets will not be used as collateral due to enabled isolation mode in {marketName} V3 Market. Visit <0>{marketName} V3 Dashboard to manage isolation mode.":["Some migrated assets will not be used as collateral due to enabled isolation mode in ",["marketName"]," V3 Market. Visit <0>",["marketName"]," V3 Dashboard to manage isolation mode."],"Something went wrong":"Something went wrong","Sorry, an unexpected error happened. In the meantime you may try reloading the page, or come back later.":"Sorry, an unexpected error happened. In the meantime you may try reloading the page, or come back later.","Sorry, we couldn't find the page you were looking for.":"Sorry, we couldn't find the page you were looking for.","Spanish":"Spanish","Stable":"Stable","Stable Interest Type is disabled for this currency":"Stable Interest Type is disabled for this currency","Stable borrowing is enabled":"Stable borrowing is enabled","Stable borrowing is not enabled":"Stable borrowing is not enabled","Stable debt supply is not zero":"Stable debt supply is not zero","Stable interest rate will <0>stay the same for the duration of your loan. Recommended for long-term loan periods and for users who prefer predictability.":"Stable interest rate will <0>stay the same for the duration of your loan. Recommended for long-term loan periods and for users who prefer predictability.","Stablecoin":"Stablecoin","Stake":"Stake","Stake AAVE":"Stake AAVE","Stake ABPT":"Stake ABPT","Stake cooldown activated":"Stake cooldown activated","Staked":"Staked","Staking":"Staking","Staking APR":"Staking APR","Staking Rewards":"Staking Rewards","Staking balance":"Staking balance","Staking discount":"Staking discount","Started":"Started","State":"State","Static interest rate that is determined by Aave Governance. This rate may be changed over time depending on the need for the GHO supply to contract/expand. <0>Learn more":"Static interest rate that is determined by Aave Governance. This rate may be changed over time depending on the need for the GHO supply to contract/expand. <0>Learn more","Supplied":"Supplied","Supplied asset amount":"Supplied asset amount","Supply":"Supply","Supply APY":"Supply APY","Supply apy":"Supply apy","Supply balance":"Supply balance","Supply balance after switch":"Supply balance after switch","Supply cap is exceeded":"Supply cap is exceeded","Supply cap on target reserve reached. Try lowering the amount.":"Supply cap on target reserve reached. Try lowering the amount.","Supply {symbol}":["Supply ",["symbol"]],"Supplying your":"Supplying your","Supplying {symbol}":["Supplying ",["symbol"]],"Switch":"Switch","Switch APY type":"Switch APY type","Switch E-Mode":"Switch E-Mode","Switch E-Mode category":"Switch E-Mode category","Switch Network":"Switch Network","Switch borrow position":"Switch borrow position","Switch rate":"Switch rate","Switch to":"Switch to","Switched":"Switched","Switching":"Switching","Switching E-Mode":"Switching E-Mode","Switching rate":"Switching rate","Techpaper":"Techpaper","Terms":"Terms","Test Assets":"Test Assets","Testnet mode":"Testnet mode","Testnet mode is ON":"Testnet mode is ON","Thank you for voting!!":"Thank you for voting!!","The % of your total borrowing power used. This is based on the amount of your collateral supplied and the total amount that you can borrow.":"The % of your total borrowing power used. This is based on the amount of your collateral supplied and the total amount that you can borrow.","The Aave Balancer Pool Token (ABPT) is a liquidity pool token. You can receive ABPT by depositing a combination of AAVE + ETH in the Balancer liquidity pool. You can then stake your BPT in the Safety Module to secure the protocol and earn Safety Incentives.":"The Aave Balancer Pool Token (ABPT) is a liquidity pool token. You can receive ABPT by depositing a combination of AAVE + ETH in the Balancer liquidity pool. You can then stake your BPT in the Safety Module to secure the protocol and earn Safety Incentives.","The Aave Protocol is programmed to always use the price of 1 GHO = $1. This is different from using market pricing via oracles for other crypto assets. This creates stabilizing arbitrage opportunities when the price of GHO fluctuates.":"The Aave Protocol is programmed to always use the price of 1 GHO = $1. This is different from using market pricing via oracles for other crypto assets. This creates stabilizing arbitrage opportunities when the price of GHO fluctuates.","The Maximum LTV ratio represents the maximum borrowing power of a specific collateral. For example, if a collateral has an LTV of 75%, the user can borrow up to 0.75 worth of ETH in the principal currency for every 1 ETH worth of collateral.":"The Maximum LTV ratio represents the maximum borrowing power of a specific collateral. For example, if a collateral has an LTV of 75%, the user can borrow up to 0.75 worth of ETH in the principal currency for every 1 ETH worth of collateral.","The Stable Rate is not enabled for this currency":"The Stable Rate is not enabled for this currency","The address of the pool addresses provider is invalid":"The address of the pool addresses provider is invalid","The app is running in testnet mode. Learn how it works in":"The app is running in testnet mode. Learn how it works in","The caller of the function is not an AToken":"The caller of the function is not an AToken","The caller of this function must be a pool":"The caller of this function must be a pool","The collateral balance is 0":"The collateral balance is 0","The collateral chosen cannot be liquidated":"The collateral chosen cannot be liquidated","The cooldown period is the time required prior to unstaking your tokens (20 days). You can only withdraw your assets from the Security Module after the cooldown period and within the unstake window.<0>Learn more":"The cooldown period is the time required prior to unstaking your tokens (20 days). You can only withdraw your assets from the Security Module after the cooldown period and within the unstake window.<0>Learn more","The cooldown period is {0}. After {1} of cooldown, you will enter unstake window of {2}. You will continue receiving rewards during cooldown and unstake window.":["The cooldown period is ",["0"],". After ",["1"]," of cooldown, you will enter unstake window of ",["2"],". You will continue receiving rewards during cooldown and unstake window."],"The effects on the health factor would cause liquidation. Try lowering the amount.":"The effects on the health factor would cause liquidation. Try lowering the amount.","The loan to value of the migrated positions would cause liquidation. Increase migrated collateral or reduce migrated borrow to continue.":"The loan to value of the migrated positions would cause liquidation. Increase migrated collateral or reduce migrated borrow to continue.","The requested amount is greater than the max loan size in stable rate mode":"The requested amount is greater than the max loan size in stable rate mode","The total amount of your assets denominated in USD that can be used as collateral for borrowing assets.":"The total amount of your assets denominated in USD that can be used as collateral for borrowing assets.","The underlying asset cannot be rescued":"The underlying asset cannot be rescued","The underlying balance needs to be greater than 0":"The underlying balance needs to be greater than 0","The weighted average of APY for all borrowed assets, including incentives.":"The weighted average of APY for all borrowed assets, including incentives.","The weighted average of APY for all supplied assets, including incentives.":"The weighted average of APY for all supplied assets, including incentives.","There are not enough funds in the{0}reserve to borrow":["There are not enough funds in the",["0"],"reserve to borrow"],"There is not enough collateral to cover a new borrow":"There is not enough collateral to cover a new borrow","There is not enough liquidity for the target asset to perform the switch. Try lowering the amount.":"There is not enough liquidity for the target asset to perform the switch. Try lowering the amount.","There was some error. Please try changing the parameters or <0><1>copy the error":"There was some error. Please try changing the parameters or <0><1>copy the error","These assets are temporarily frozen or paused by Aave community decisions, meaning that further supply / borrow, or rate swap of these assets are unavailable. Withdrawals and debt repayments are allowed. Follow the <0>Aave governance forum for further updates.":"These assets are temporarily frozen or paused by Aave community decisions, meaning that further supply / borrow, or rate swap of these assets are unavailable. Withdrawals and debt repayments are allowed. Follow the <0>Aave governance forum for further updates.","These funds have been borrowed and are not available for withdrawal at this time.":"These funds have been borrowed and are not available for withdrawal at this time.","This action will reduce V2 health factor below liquidation threshold. retain collateral or migrate borrow position to continue.":"This action will reduce V2 health factor below liquidation threshold. retain collateral or migrate borrow position to continue.","This action will reduce health factor of V3 below liquidation threshold. Increase migrated collateral or reduce migrated borrow to continue.":"This action will reduce health factor of V3 below liquidation threshold. Increase migrated collateral or reduce migrated borrow to continue.","This action will reduce your health factor. Please be mindful of the increased risk of collateral liquidation.":"This action will reduce your health factor. Please be mindful of the increased risk of collateral liquidation.","This address is blocked on app.aave.com because it is associated with one or more":"This address is blocked on app.aave.com because it is associated with one or more","This asset has almost reached its borrow cap. There is only {messageValue} available to be borrowed from this market.":["This asset has almost reached its borrow cap. There is only ",["messageValue"]," available to be borrowed from this market."],"This asset has almost reached its supply cap. There can only be {messageValue} supplied to this market.":["This asset has almost reached its supply cap. There can only be ",["messageValue"]," supplied to this market."],"This asset has reached its borrow cap. Nothing is available to be borrowed from this market.":"This asset has reached its borrow cap. Nothing is available to be borrowed from this market.","This asset has reached its supply cap. Nothing is available to be supplied from this market.":"This asset has reached its supply cap. Nothing is available to be supplied from this market.","This asset is frozen due to an Aave Protocol Governance decision. <0>More details":"This asset is frozen due to an Aave Protocol Governance decision. <0>More details","This asset is frozen due to an Aave Protocol Governance decision. On the 20th of December 2022, renFIL will no longer be supported and cannot be bridged back to its native network. It is recommended to withdraw supply positions and repay borrow positions so that renFIL can be bridged back to FIL before the deadline. After this date, it will no longer be possible to convert renFIL to FIL. <0>More details":"This asset is frozen due to an Aave Protocol Governance decision. On the 20th of December 2022, renFIL will no longer be supported and cannot be bridged back to its native network. It is recommended to withdraw supply positions and repay borrow positions so that renFIL can be bridged back to FIL before the deadline. After this date, it will no longer be possible to convert renFIL to FIL. <0>More details","This asset is frozen due to an Aave community decision. <0>More details":"This asset is frozen due to an Aave community decision. <0>More details","This asset is planned to be offboarded due to an Aave Protocol Governance decision. <0>More details":"This asset is planned to be offboarded due to an Aave Protocol Governance decision. <0>More details","This gas calculation is only an estimation. Your wallet will set the price of the transaction. You can modify the gas settings directly from your wallet provider.":"This gas calculation is only an estimation. Your wallet will set the price of the transaction. You can modify the gas settings directly from your wallet provider.","This integration was<0>proposed and approvedby the community.":"This integration was<0>proposed and approvedby the community.","This is the total amount available for you to borrow. You can borrow based on your collateral and until the borrow cap is reached.":"This is the total amount available for you to borrow. You can borrow based on your collateral and until the borrow cap is reached.","This is the total amount that you are able to supply to in this reserve. You are able to supply your wallet balance up until the supply cap is reached.":"This is the total amount that you are able to supply to in this reserve. You are able to supply your wallet balance up until the supply cap is reached.","This represents the threshold at which a borrow position will be considered undercollateralized and subject to liquidation for each collateral. For example, if a collateral has a liquidation threshold of 80%, it means that the position will be liquidated when the debt value is worth 80% of the collateral value.":"This represents the threshold at which a borrow position will be considered undercollateralized and subject to liquidation for each collateral. For example, if a collateral has a liquidation threshold of 80%, it means that the position will be liquidated when the debt value is worth 80% of the collateral value.","Time left to be able to withdraw your staked asset.":"Time left to be able to withdraw your staked asset.","Time left to unstake":"Time left to unstake","Time left until the withdrawal window closes.":"Time left until the withdrawal window closes.","Tip: Try increasing slippage or reduce input amount":"Tip: Try increasing slippage or reduce input amount","To borrow you need to supply any asset to be used as collateral.":"To borrow you need to supply any asset to be used as collateral.","To continue, you need to grant Aave smart contracts permission to move your funds from your wallet. Depending on the asset and wallet you use, it is done by signing the permission message (gas free), or by submitting an approval transaction (requires gas). <0>Learn more":"To continue, you need to grant Aave smart contracts permission to move your funds from your wallet. Depending on the asset and wallet you use, it is done by signing the permission message (gas free), or by submitting an approval transaction (requires gas). <0>Learn more","To enable E-mode for the {0} category, all borrow positions outside of this category must be closed.":["To enable E-mode for the ",["0"]," category, all borrow positions outside of this category must be closed."],"To repay on behalf of a user an explicit amount to repay is needed":"To repay on behalf of a user an explicit amount to repay is needed","To request access for this permissioned market, please visit: <0>Acces Provider Name":"To request access for this permissioned market, please visit: <0>Acces Provider Name","To submit a proposal for minor changes to the protocol, you'll need at least 80.00K power. If you want to change the core code base, you'll need 320k power.<0>Learn more.":"To submit a proposal for minor changes to the protocol, you'll need at least 80.00K power. If you want to change the core code base, you'll need 320k power.<0>Learn more.","Top 10 addresses":"Top 10 addresses","Total available":"Total available","Total borrowed":"Total borrowed","Total borrows":"Total borrows","Total emission per day":"Total emission per day","Total interest accrued":"Total interest accrued","Total market size":"Total market size","Total supplied":"Total supplied","Total voting power":"Total voting power","Total worth":"Total worth","Track wallet":"Track wallet","Track wallet balance in read-only mode":"Track wallet balance in read-only mode","Transaction failed":"Transaction failed","Transaction history":"Transaction history","Transaction history is not currently available for this market":"Transaction history is not currently available for this market","Transaction overview":"Transaction overview","Transactions":"Transactions","UNSTAKE {symbol}":["UNSTAKE ",["symbol"]],"Unavailable":"Unavailable","Unbacked":"Unbacked","Unbacked mint cap is exceeded":"Unbacked mint cap is exceeded","Underlying asset does not exist in {marketName} v3 Market, hence this position cannot be migrated.":["Underlying asset does not exist in ",["marketName"]," v3 Market, hence this position cannot be migrated."],"Underlying token":"Underlying token","Unstake now":"Unstake now","Unstake window":"Unstake window","Unstaked":"Unstaked","Unstaking {symbol}":["Unstaking ",["symbol"]],"Update: Disruptions reported for WETH, WBTC, WMATIC, and USDT. AIP 230 will resolve the disruptions and the market will be operating as normal on ~26th May 13h00 UTC.":"Update: Disruptions reported for WETH, WBTC, WMATIC, and USDT. AIP 230 will resolve the disruptions and the market will be operating as normal on ~26th May 13h00 UTC.","Use it to vote for or against active proposals.":"Use it to vote for or against active proposals.","Use your AAVE and stkAAVE balance to delegate your voting and proposition powers. You will not be sending any tokens, only the rights to vote and propose changes to the protocol. You can re-delegate or revoke power to self at any time.":"Use your AAVE and stkAAVE balance to delegate your voting and proposition powers. You will not be sending any tokens, only the rights to vote and propose changes to the protocol. You can re-delegate or revoke power to self at any time.","Used as collateral":"Used as collateral","User cannot withdraw more than the available balance":"User cannot withdraw more than the available balance","User did not borrow the specified currency":"User did not borrow the specified currency","User does not have outstanding stable rate debt on this reserve":"User does not have outstanding stable rate debt on this reserve","User does not have outstanding variable rate debt on this reserve":"User does not have outstanding variable rate debt on this reserve","User is in isolation mode":"User is in isolation mode","User is trying to borrow multiple assets including a siloed one":"User is trying to borrow multiple assets including a siloed one","Users who stake AAVE in Safety Module (i.e. stkAAVE holders) receive a discount on GHO borrow interest rate. The discount applies to 100 GHO for every 1 stkAAVE held. Use the calculator below to see GHO borrow rate with the discount applied.":"Users who stake AAVE in Safety Module (i.e. stkAAVE holders) receive a discount on GHO borrow interest rate. The discount applies to 100 GHO for every 1 stkAAVE held. Use the calculator below to see GHO borrow rate with the discount applied.","Utilization Rate":"Utilization Rate","VIEW TX":"VIEW TX","VOTE NAY":"VOTE NAY","VOTE YAE":"VOTE YAE","Variable":"Variable","Variable debt supply is not zero":"Variable debt supply is not zero","Variable interest rate will <0>fluctuate based on the market conditions. Recommended for short-term positions.":"Variable interest rate will <0>fluctuate based on the market conditions. Recommended for short-term positions.","Variable rate":"Variable rate","Version 2":"Version 2","Version 3":"Version 3","View":"View","View Transactions":"View Transactions","View all votes":"View all votes","View contract":"View contract","View details":"View details","View on Explorer":"View on Explorer","Vote NAY":"Vote NAY","Vote YAE":"Vote YAE","Voted NAY":"Voted NAY","Voted YAE":"Voted YAE","Votes":"Votes","Voting":"Voting","Voting power":"Voting power","Voting results":"Voting results","Wallet Balance":"Wallet Balance","Wallet balance":"Wallet balance","Wallet not detected. Connect or install wallet and retry":"Wallet not detected. Connect or install wallet and retry","Wallets are provided by External Providers and by selecting you agree to Terms of those Providers. Your access to the wallet might be reliant on the External Provider being operational.":"Wallets are provided by External Providers and by selecting you agree to Terms of those Providers. Your access to the wallet might be reliant on the External Provider being operational.","We couldn't find any assets related to your search. Try again with a different asset name, symbol, or address.":"We couldn't find any assets related to your search. Try again with a different asset name, symbol, or address.","We couldn't find any transactions related to your search. Try again with a different asset name, or reset filters.":"We couldn't find any transactions related to your search. Try again with a different asset name, or reset filters.","We couldn’t detect a wallet. Connect a wallet to stake and view your balance.":"We couldn’t detect a wallet. Connect a wallet to stake and view your balance.","We suggest you go back to the Dashboard.":"We suggest you go back to the Dashboard.","Website":"Website","When a liquidation occurs, liquidators repay up to 50% of the outstanding borrowed amount on behalf of the borrower. In return, they can buy the collateral at a discount and keep the difference (liquidation penalty) as a bonus.":"When a liquidation occurs, liquidators repay up to 50% of the outstanding borrowed amount on behalf of the borrower. In return, they can buy the collateral at a discount and keep the difference (liquidation penalty) as a bonus.","With a voting power of <0/>":"With a voting power of <0/>","With testnet Faucet you can get free assets to test the Aave Protocol. Make sure to switch your wallet provider to the appropriate testnet network, select desired asset, and click ‘Faucet’ to get tokens transferred to your wallet. The assets on a testnet are not “real,” meaning they have no monetary value. <0>Learn more":"With testnet Faucet you can get free assets to test the Aave Protocol. Make sure to switch your wallet provider to the appropriate testnet network, select desired asset, and click ‘Faucet’ to get tokens transferred to your wallet. The assets on a testnet are not “real,” meaning they have no monetary value. <0>Learn more","Withdraw":"Withdraw","Withdraw & Switch":"Withdraw & Switch","Withdraw and Switch":"Withdraw and Switch","Withdraw {symbol}":["Withdraw ",["symbol"]],"Withdrawing":"Withdrawing","Withdrawing and Switching":"Withdrawing and Switching","Withdrawing this amount will reduce your health factor and increase risk of liquidation.":"Withdrawing this amount will reduce your health factor and increase risk of liquidation.","Withdrawing {symbol}":["Withdrawing ",["symbol"]],"Wrong Network":"Wrong Network","YAE":"YAE","You are entering Isolation mode":"You are entering Isolation mode","You can borrow this asset with a stable rate only if you borrow more than the amount you are supplying as collateral.":"You can borrow this asset with a stable rate only if you borrow more than the amount you are supplying as collateral.","You can not change Interest Type to stable as your borrowings are higher than your collateral":"You can not change Interest Type to stable as your borrowings are higher than your collateral","You can not disable E-Mode as your current collateralization level is above 80%, disabling E-Mode can cause liquidation. To exit E-Mode supply or repay borrowed positions.":"You can not disable E-Mode as your current collateralization level is above 80%, disabling E-Mode can cause liquidation. To exit E-Mode supply or repay borrowed positions.","You can not switch usage as collateral mode for this currency, because it will cause collateral call":"You can not switch usage as collateral mode for this currency, because it will cause collateral call","You can not use this currency as collateral":"You can not use this currency as collateral","You can not withdraw this amount because it will cause collateral call":"You can not withdraw this amount because it will cause collateral call","You can only switch to tokens with variable APY types. After this transaction, you may change the variable rate to a stable one if available.":"You can only switch to tokens with variable APY types. After this transaction, you may change the variable rate to a stable one if available.","You can only withdraw your assets from the Security Module after the cooldown period ends and the unstake window is active.":"You can only withdraw your assets from the Security Module after the cooldown period ends and the unstake window is active.","You can report incident to our <0>Discord or<1>Github.":"You can report incident to our <0>Discord or<1>Github.","You cancelled the transaction.":"You cancelled the transaction.","You did not participate in this proposal":"You did not participate in this proposal","You do not have supplies in this currency":"You do not have supplies in this currency","You don’t have enough funds in your wallet to repay the full amount. If you proceed to repay with your current amount of funds, you will still have a small borrowing position in your dashboard.":"You don’t have enough funds in your wallet to repay the full amount. If you proceed to repay with your current amount of funds, you will still have a small borrowing position in your dashboard.","You have no AAVE/stkAAVE balance to delegate.":"You have no AAVE/stkAAVE balance to delegate.","You have not borrow yet using this currency":"You have not borrow yet using this currency","You may borrow up to <0/> GHO at <1/> (max discount)":"You may borrow up to <0/> GHO at <1/> (max discount)","You may enter a custom amount in the field.":"You may enter a custom amount in the field.","You switched to {0} rate":["You switched to ",["0"]," rate"],"You unstake here":"You unstake here","You voted {0}":["You voted ",["0"]],"You will exit isolation mode and other tokens can now be used as collateral":"You will exit isolation mode and other tokens can now be used as collateral","You {action} <0/> {symbol}":["You ",["action"]," <0/> ",["symbol"]],"You've successfully switched borrow position.":"You've successfully switched borrow position.","You've successfully switched tokens.":"You've successfully switched tokens.","You've successfully withdrew & switched tokens.":"You've successfully withdrew & switched tokens.","Your balance is lower than the selected amount.":"Your balance is lower than the selected amount.","Your borrows":"Your borrows","Your current loan to value based on your collateral supplied.":"Your current loan to value based on your collateral supplied.","Your health factor and loan to value determine the assurance of your collateral. To avoid liquidations you can supply more collateral or repay borrow positions.":"Your health factor and loan to value determine the assurance of your collateral. To avoid liquidations you can supply more collateral or repay borrow positions.","Your info":"Your info","Your proposition power is based on your AAVE/stkAAVE balance and received delegations.":"Your proposition power is based on your AAVE/stkAAVE balance and received delegations.","Your reward balance is 0":"Your reward balance is 0","Your supplies":"Your supplies","Your voting info":"Your voting info","Your voting power is based on your AAVE/stkAAVE balance and received delegations.":"Your voting power is based on your AAVE/stkAAVE balance and received delegations.","Your {name} wallet is empty. Purchase or transfer assets or use <0>{0} to transfer your {network} assets.":["Your ",["name"]," wallet is empty. Purchase or transfer assets or use <0>",["0"]," to transfer your ",["network"]," assets."],"Your {name} wallet is empty. Purchase or transfer assets.":["Your ",["name"]," wallet is empty. Purchase or transfer assets."],"Your {networkName} wallet is empty. Get free test assets at":["Your ",["networkName"]," wallet is empty. Get free test assets at"],"Your {networkName} wallet is empty. Get free test {0} at":["Your ",["networkName"]," wallet is empty. Get free test ",["0"]," at"],"Zero address not valid":"Zero address not valid","assets":"assets","blocked activities":"blocked activities","copy the error":"copy the error","disabled":"disabled","documentation":"documentation","enabled":"enabled","ends":"ends","for":"for","of":"of","on":"on","please check that the amount you want to supply is not currently being used for staking. If it is being used for staking, your transaction might fail.":"please check that the amount you want to supply is not currently being used for staking. If it is being used for staking, your transaction might fail.","repaid":"repaid","stETH supplied as collateral will continue to accrue staking rewards provided by daily rebases.":"stETH supplied as collateral will continue to accrue staking rewards provided by daily rebases.","stETH tokens will be migrated to Wrapped stETH using Lido Protocol wrapper which leads to supply balance change after migration: {0}":["stETH tokens will be migrated to Wrapped stETH using Lido Protocol wrapper which leads to supply balance change after migration: ",["0"]],"staking view":"staking view","starts":"starts","stkAAVE holders get a discount on GHO borrow rate":"stkAAVE holders get a discount on GHO borrow rate","to":"to","tokens is not the same as staking them. If you wish to stake your":"tokens is not the same as staking them. If you wish to stake your","tokens, please go to the":"tokens, please go to the","withdrew":"withdrew","{0}":[["0"]],"{0} Balance":[["0"]," Balance"],"{0} Faucet":[["0"]," Faucet"],"{0} on-ramp service is provided by External Provider and by selecting you agree to Terms of the Provider. Your access to the service might be reliant on the External Provider being operational.":[["0"]," on-ramp service is provided by External Provider and by selecting you agree to Terms of the Provider. Your access to the service might be reliant on the External Provider being operational."],"{0}{name}":[["0"],["name"]],"{currentMethod}":[["currentMethod"]],"{d}d":[["d"],"d"],"{h}h":[["h"],"h"],"{m}m":[["m"],"m"],"{networkName} Faucet":[["networkName"]," Faucet"],"{notifyText}":[["notifyText"]],"{numSelected}/{numAvailable} assets selected":[["numSelected"],"/",["numAvailable"]," assets selected"],"{s}s":[["s"],"s"],"{title}":[["title"]],"{tooltipText}":[["tooltipText"]]}}; \ No newline at end of file +/*eslint-disable*/module.exports={messages:{"...":"...",".CSV":".CSV",".JSON":".JSON","<0><1><2/>Add <3/> stkAAVE to borrow at <4/> (max discount)":"<0><1><2/>Add <3/> stkAAVE to borrow at <4/> (max discount)","<0><1><2/>Add stkAAVE to see borrow rate with discount":"<0><1><2/>Add stkAAVE to see borrow rate with discount","<0>Ampleforth is a rebasing asset. Visit the <1>documentation to learn more.":"<0>Ampleforth is a rebasing asset. Visit the <1>documentation to learn more.","<0>Attention: Parameter changes via governance can alter your account health factor and risk of liquidation. Follow the <1>Aave governance forum for updates.":"<0>Attention: Parameter changes via governance can alter your account health factor and risk of liquidation. Follow the <1>Aave governance forum for updates.","<0>Slippage tolerance <1>{selectedSlippage}% <2>{0}":["<0>Slippage tolerance <1>",["selectedSlippage"],"% <2>",["0"],""],"AAVE holders (Ethereum network only) can stake their AAVE in the Safety Module to add more security to the protocol and earn Safety Incentives. In the case of a shortfall event, up to 30% of your stake can be slashed to cover the deficit, providing an additional layer of protection for the protocol.":"AAVE holders (Ethereum network only) can stake their AAVE in the Safety Module to add more security to the protocol and earn Safety Incentives. In the case of a shortfall event, up to 30% of your stake can be slashed to cover the deficit, providing an additional layer of protection for the protocol.","APR":"APR","APY":"APY","APY change":"APY change","APY type":"APY type","APY type change":"APY type change","APY with discount applied":"APY with discount applied","APY, fixed rate":"APY, fixed rate","APY, stable":"APY, stable","APY, variable":"APY, variable","AToken supply is not zero":"AToken supply is not zero","Aave Governance":"Aave Governance","Aave aToken":"Aave aToken","Aave debt token":"Aave debt token","Aave is a fully decentralized, community governed protocol by the AAVE token-holders. AAVE token-holders collectively discuss, propose, and vote on upgrades to the protocol. AAVE token-holders (Ethereum network only) can either vote themselves on new proposals or delagate to an address of choice. To learn more check out the Governance":"Aave is a fully decentralized, community governed protocol by the AAVE token-holders. AAVE token-holders collectively discuss, propose, and vote on upgrades to the protocol. AAVE token-holders (Ethereum network only) can either vote themselves on new proposals or delagate to an address of choice. To learn more check out the Governance","Aave per month":"Aave per month","About GHO":"About GHO","Account":"Account","Action cannot be performed because the reserve is frozen":"Action cannot be performed because the reserve is frozen","Action cannot be performed because the reserve is paused":"Action cannot be performed because the reserve is paused","Action requires an active reserve":"Action requires an active reserve","Activate Cooldown":"Activate Cooldown","Add stkAAVE to see borrow APY with the discount":"Add stkAAVE to see borrow APY with the discount","Add to wallet":"Add to wallet","Add {0} to wallet to track your balance.":["Add ",["0"]," to wallet to track your balance."],"Address is not a contract":"Address is not a contract","Addresses":"Addresses","Addresses ({0})":["Addresses (",["0"],")"],"All Assets":"All Assets","All done!":"All done!","All proposals":"All proposals","All transactions":"All transactions","Allowance required action":"Allowance required action","Allows you to decide whether to use a supplied asset as collateral. An asset used as collateral will affect your borrowing power and health factor.":"Allows you to decide whether to use a supplied asset as collateral. An asset used as collateral will affect your borrowing power and health factor.","Allows you to switch between <0>variable and <1>stable interest rates, where variable rate can increase and decrease depending on the amount of liquidity in the reserve, and stable rate will stay the same for the duration of your loan.":"Allows you to switch between <0>variable and <1>stable interest rates, where variable rate can increase and decrease depending on the amount of liquidity in the reserve, and stable rate will stay the same for the duration of your loan.","Amount":"Amount","Amount claimable":"Amount claimable","Amount in cooldown":"Amount in cooldown","Amount must be greater than 0":"Amount must be greater than 0","Amount to unstake":"Amount to unstake","An error has occurred fetching the proposal metadata from IPFS.":"An error has occurred fetching the proposal metadata from IPFS.","Approve Confirmed":"Approve Confirmed","Approve with":"Approve with","Approve {symbol} to continue":["Approve ",["symbol"]," to continue"],"Approving {symbol}...":["Approving ",["symbol"],"..."],"Array parameters that should be equal length are not":"Array parameters that should be equal length are not","Asset":"Asset","Asset can be only used as collateral in isolation mode with limited borrowing power. To enter isolation mode, disable all other collateral.":"Asset can be only used as collateral in isolation mode with limited borrowing power. To enter isolation mode, disable all other collateral.","Asset can only be used as collateral in isolation mode only.":"Asset can only be used as collateral in isolation mode only.","Asset cannot be migrated because you have isolated collateral in {marketName} v3 Market which limits borrowable assets. You can manage your collateral in <0>{marketName} V3 Dashboard":["Asset cannot be migrated because you have isolated collateral in ",["marketName"]," v3 Market which limits borrowable assets. You can manage your collateral in <0>",["marketName"]," V3 Dashboard"],"Asset cannot be migrated due to insufficient liquidity or borrow cap limitation in {marketName} v3 market.":["Asset cannot be migrated due to insufficient liquidity or borrow cap limitation in ",["marketName"]," v3 market."],"Asset cannot be migrated due to supply cap restriction in {marketName} v3 market.":["Asset cannot be migrated due to supply cap restriction in ",["marketName"]," v3 market."],"Asset cannot be migrated to {marketName} V3 Market due to E-mode restrictions. You can disable or manage E-mode categories in your <0>V3 Dashboard":["Asset cannot be migrated to ",["marketName"]," V3 Market due to E-mode restrictions. You can disable or manage E-mode categories in your <0>V3 Dashboard"],"Asset cannot be migrated to {marketName} v3 Market since collateral asset will enable isolation mode.":["Asset cannot be migrated to ",["marketName"]," v3 Market since collateral asset will enable isolation mode."],"Asset cannot be used as collateral.":"Asset cannot be used as collateral.","Asset category":"Asset category","Asset is frozen in {marketName} v3 market, hence this position cannot be migrated.":["Asset is frozen in ",["marketName"]," v3 market, hence this position cannot be migrated."],"Asset is not borrowable in isolation mode":"Asset is not borrowable in isolation mode","Asset is not listed":"Asset is not listed","Asset supply is limited to a certain amount to reduce protocol exposure to the asset and to help manage risks involved.":"Asset supply is limited to a certain amount to reduce protocol exposure to the asset and to help manage risks involved.","Assets":"Assets","Assets to borrow":"Assets to borrow","Assets to supply":"Assets to supply","Assets with zero LTV ({assetsBlockingWithdraw}) must be withdrawn or disabled as collateral to perform this action":["Assets with zero LTV (",["assetsBlockingWithdraw"],") must be withdrawn or disabled as collateral to perform this action"],"At a discount":"At a discount","Author":"Author","Available":"Available","Available assets":"Available assets","Available liquidity":"Available liquidity","Available on":"Available on","Available rewards":"Available rewards","Available to borrow":"Available to borrow","Available to supply":"Available to supply","Back to Dashboard":"Back to Dashboard","Balance":"Balance","Balance to revoke":"Balance to revoke","Be careful - You are very close to liquidation. Consider depositing more collateral or paying down some of your borrowed positions":"Be careful - You are very close to liquidation. Consider depositing more collateral or paying down some of your borrowed positions","Be mindful of the network congestion and gas prices.":"Be mindful of the network congestion and gas prices.","Because this asset is paused, no actions can be taken until further notice":"Because this asset is paused, no actions can be taken until further notice","Before supplying":"Before supplying","Blocked Address":"Blocked Address","Borrow":"Borrow","Borrow APY":"Borrow APY","Borrow APY rate":"Borrow APY rate","Borrow APY, fixed rate":"Borrow APY, fixed rate","Borrow APY, stable":"Borrow APY, stable","Borrow APY, variable":"Borrow APY, variable","Borrow amount to reach {0}% utilization":["Borrow amount to reach ",["0"],"% utilization"],"Borrow and repay in same block is not allowed":"Borrow and repay in same block is not allowed","Borrow apy":"Borrow apy","Borrow balance":"Borrow balance","Borrow balance after repay":"Borrow balance after repay","Borrow balance after switch":"Borrow balance after switch","Borrow cap":"Borrow cap","Borrow cap is exceeded":"Borrow cap is exceeded","Borrow info":"Borrow info","Borrow power used":"Borrow power used","Borrow rate change":"Borrow rate change","Borrow {symbol}":["Borrow ",["symbol"]],"Borrowed":"Borrowed","Borrowed asset amount":"Borrowed asset amount","Borrowing is currently unavailable for {0}.":["Borrowing is currently unavailable for ",["0"],"."],"Borrowing is disabled due to an Aave community decision. <0>More details":"Borrowing is disabled due to an Aave community decision. <0>More details","Borrowing is not enabled":"Borrowing is not enabled","Borrowing is unavailable because you’re using Isolation mode. To manage Isolation mode visit your <0>Dashboard.":"Borrowing is unavailable because you’re using Isolation mode. To manage Isolation mode visit your <0>Dashboard.","Borrowing is unavailable because you’ve enabled Efficiency Mode (E-Mode) and Isolation mode. To manage E-Mode and Isolation mode visit your <0>Dashboard.":"Borrowing is unavailable because you’ve enabled Efficiency Mode (E-Mode) and Isolation mode. To manage E-Mode and Isolation mode visit your <0>Dashboard.","Borrowing is unavailable because you’ve enabled Efficiency Mode (E-Mode) for {0} category. To manage E-Mode categories visit your <0>Dashboard.":["Borrowing is unavailable because you’ve enabled Efficiency Mode (E-Mode) for ",["0"]," category. To manage E-Mode categories visit your <0>Dashboard."],"Borrowing of this asset is limited to a certain amount to minimize liquidity pool insolvency.":"Borrowing of this asset is limited to a certain amount to minimize liquidity pool insolvency.","Borrowing power and assets are limited due to Isolation mode.":"Borrowing power and assets are limited due to Isolation mode.","Borrowing this amount will reduce your health factor and increase risk of liquidation.":"Borrowing this amount will reduce your health factor and increase risk of liquidation.","Borrowing {symbol}":["Borrowing ",["symbol"]],"Both":"Both","Buy Crypto With Fiat":"Buy Crypto With Fiat","Buy Crypto with Fiat":"Buy Crypto with Fiat","Buy {cryptoSymbol} with Fiat":["Buy ",["cryptoSymbol"]," with Fiat"],"COPIED!":"COPIED!","COPY IMAGE":"COPY IMAGE","Can be collateral":"Can be collateral","Can be executed":"Can be executed","Cancel":"Cancel","Cannot disable E-Mode":"Cannot disable E-Mode","Choose how much voting/proposition power to give to someone else by delegating some of your AAVE or stkAAVE balance. Your tokens will remain in your account, but your delegate will be able to vote or propose on your behalf. If your AAVE or stkAAVE balance changes, your delegate's voting/proposition power will be automatically adjusted.":"Choose how much voting/proposition power to give to someone else by delegating some of your AAVE or stkAAVE balance. Your tokens will remain in your account, but your delegate will be able to vote or propose on your behalf. If your AAVE or stkAAVE balance changes, your delegate's voting/proposition power will be automatically adjusted.","Choose one of the on-ramp services":"Choose one of the on-ramp services","Claim":"Claim","Claim all":"Claim all","Claim all rewards":"Claim all rewards","Claim {0}":["Claim ",["0"]],"Claim {symbol}":["Claim ",["symbol"]],"Claimable AAVE":"Claimable AAVE","Claimed":"Claimed","Claiming":"Claiming","Claiming {symbol}":["Claiming ",["symbol"]],"Close":"Close","Collateral":"Collateral","Collateral balance after repay":"Collateral balance after repay","Collateral change":"Collateral change","Collateral is (mostly) the same currency that is being borrowed":"Collateral is (mostly) the same currency that is being borrowed","Collateral to repay with":"Collateral to repay with","Collateral usage":"Collateral usage","Collateral usage is limited because of Isolation mode.":"Collateral usage is limited because of Isolation mode.","Collateral usage is limited because of isolation mode.":"Collateral usage is limited because of isolation mode.","Collateral usage is limited because of isolation mode. <0>Learn More":"Collateral usage is limited because of isolation mode. <0>Learn More","Collateralization":"Collateralization","Collector Contract":"Collector Contract","Collector Info":"Collector Info","Connect wallet":"Connect wallet","Cooldown period":"Cooldown period","Cooldown period warning":"Cooldown period warning","Cooldown time left":"Cooldown time left","Cooldown to unstake":"Cooldown to unstake","Cooling down...":"Cooling down...","Copy address":"Copy address","Copy error message":"Copy error message","Copy error text":"Copy error text","Covered debt":"Covered debt","Created":"Created","Current LTV":"Current LTV","Current differential":"Current differential","Current v2 Balance":"Current v2 Balance","Current v2 balance":"Current v2 balance","Current votes":"Current votes","DAI balance will be converted via DSR contracts and then supplied as sDAI to Aave reserve. Switching incurs no additional costs and no slippage.":"DAI balance will be converted via DSR contracts and then supplied as sDAI to Aave reserve. Switching incurs no additional costs and no slippage.","Dark mode":"Dark mode","Dashboard":"Dashboard","Data couldn't be fetched, please reload graph.":"Data couldn't be fetched, please reload graph.","Debt":"Debt","Debt ceiling is exceeded":"Debt ceiling is exceeded","Debt ceiling is not zero":"Debt ceiling is not zero","Debt ceiling limits the amount possible to borrow against this asset by protocol users. Debt ceiling is specific to assets in isolation mode and is denoted in USD.":"Debt ceiling limits the amount possible to borrow against this asset by protocol users. Debt ceiling is specific to assets in isolation mode and is denoted in USD.","Delegated power":"Delegated power","Details":"Details","Developers":"Developers","Differential":"Differential","Disable E-Mode":"Disable E-Mode","Disable testnet":"Disable testnet","Disable {symbol} as collateral":["Disable ",["symbol"]," as collateral"],"Disabled":"Disabled","Disabling E-Mode":"Disabling E-Mode","Disabling this asset as collateral affects your borrowing power and Health Factor.":"Disabling this asset as collateral affects your borrowing power and Health Factor.","Disconnect Wallet":"Disconnect Wallet","Discord channel":"Discord channel","Discount":"Discount","Discount applied for <0/> staking AAVE":"Discount applied for <0/> staking AAVE","Discount model parameters":"Discount model parameters","Discount parameters are decided by the Aave community and may be changed over time. Check Governance for updates and vote to participate. <0>Learn more":"Discount parameters are decided by the Aave community and may be changed over time. Check Governance for updates and vote to participate. <0>Learn more","Discountable amount":"Discountable amount","Docs":"Docs","Download":"Download","Due to internal stETH mechanics required for rebasing support, it is not possible to perform a collateral switch where stETH is the source token.":"Due to internal stETH mechanics required for rebasing support, it is not possible to perform a collateral switch where stETH is the source token.","Due to the Horizon bridge exploit, certain assets on the Harmony network are not at parity with Ethereum, which affects the Aave V3 Harmony market.":"Due to the Horizon bridge exploit, certain assets on the Harmony network are not at parity with Ethereum, which affects the Aave V3 Harmony market.","E-Mode":"E-Mode","E-Mode Category":"E-Mode Category","E-Mode category":"E-Mode category","E-Mode increases your LTV for a selected category of assets up to 97%. <0>Learn more":"E-Mode increases your LTV for a selected category of assets up to 97%. <0>Learn more","E-Mode increases your LTV for a selected category of assets up to<0/>. <1>Learn more":"E-Mode increases your LTV for a selected category of assets up to<0/>. <1>Learn more","E-Mode increases your LTV for a selected category of assets, meaning that when E-mode is enabled, you will have higher borrowing power over assets of the same E-mode category which are defined by Aave Governance. You can enter E-Mode from your <0>Dashboard. To learn more about E-Mode and applied restrictions in <1>FAQ or <2>Aave V3 Technical Paper.":"E-Mode increases your LTV for a selected category of assets, meaning that when E-mode is enabled, you will have higher borrowing power over assets of the same E-mode category which are defined by Aave Governance. You can enter E-Mode from your <0>Dashboard. To learn more about E-Mode and applied restrictions in <1>FAQ or <2>Aave V3 Technical Paper.","Effective interest rate":"Effective interest rate","Efficiency mode (E-Mode)":"Efficiency mode (E-Mode)","Emode":"Emode","Enable E-Mode":"Enable E-Mode","Enable {symbol} as collateral":["Enable ",["symbol"]," as collateral"],"Enabled":"Enabled","Enabling E-Mode":"Enabling E-Mode","Enabling E-Mode only allows you to borrow assets belonging to the selected category. Please visit our <0>FAQ guide to learn more about how it works and the applied restrictions.":"Enabling E-Mode only allows you to borrow assets belonging to the selected category. Please visit our <0>FAQ guide to learn more about how it works and the applied restrictions.","Enabling this asset as collateral increases your borrowing power and Health Factor. However, it can get liquidated if your health factor drops below 1.":"Enabling this asset as collateral increases your borrowing power and Health Factor. However, it can get liquidated if your health factor drops below 1.","Ended":"Ended","Ends":"Ends","English":"English","Enter ETH address":"Enter ETH address","Enter an amount":"Enter an amount","Error connecting. Try refreshing the page.":"Error connecting. Try refreshing the page.","Estimated compounding interest, including discount for Staking {0}AAVE in Safety Module.":["Estimated compounding interest, including discount for Staking ",["0"],"AAVE in Safety Module."],"Exceeds the discount":"Exceeds the discount","Exchange rate":"Exchange rate","Executed":"Executed","Expected amount to repay":"Expected amount to repay","Expires":"Expires","Export data to":"Export data to","FAQ":"FAQ","FAQS":"FAQS","Failed to load proposal voters. Please refresh the page.":"Failed to load proposal voters. Please refresh the page.","Faucet":"Faucet","Faucet {0}":["Faucet ",["0"]],"Fetching data...":"Fetching data...","Filter":"Filter","Fixed":"Fixed","Fixed rate":"Fixed rate","Flashloan is disabled for this asset, hence this position cannot be migrated.":"Flashloan is disabled for this asset, hence this position cannot be migrated.","For repayment of a specific type of debt, the user needs to have debt that type":"For repayment of a specific type of debt, the user needs to have debt that type","Forum discussion":"Forum discussion","French":"French","Funds in the Safety Module":"Funds in the Safety Module","GHO is a native decentralized, collateral-backed digital asset pegged to USD. It is created by users via borrowing against multiple collateral. When user repays their GHO borrow position, the protocol burns that user's GHO. All the interest payments accrued by minters of GHO would be directly transferred to the AaveDAO treasury.":"GHO is a native decentralized, collateral-backed digital asset pegged to USD. It is created by users via borrowing against multiple collateral. When user repays their GHO borrow position, the protocol burns that user's GHO. All the interest payments accrued by minters of GHO would be directly transferred to the AaveDAO treasury.","Get ABP Token":"Get ABP Token","Global settings":"Global settings","Go Back":"Go Back","Go to Balancer Pool":"Go to Balancer Pool","Go to V3 Dashboard":"Go to V3 Dashboard","Governance":"Governance","Greek":"Greek","Health Factor ({0} v2)":["Health Factor (",["0"]," v2)"],"Health Factor ({0} v3)":["Health Factor (",["0"]," v3)"],"Health factor":"Health factor","Health factor is lesser than the liquidation threshold":"Health factor is lesser than the liquidation threshold","Health factor is not below the threshold":"Health factor is not below the threshold","Hide":"Hide","Holders of stkAAVE receive a discount on the GHO borrowing rate":"Holders of stkAAVE receive a discount on the GHO borrowing rate","I acknowledge the risks involved.":"I acknowledge the risks involved.","I fully understand the risks of migrating.":"I fully understand the risks of migrating.","I understand how cooldown ({0}) and unstaking ({1}) work":["I understand how cooldown (",["0"],") and unstaking (",["1"],") work"],"If the error continues to happen,<0/> you may report it to this":"If the error continues to happen,<0/> you may report it to this","If the health factor goes below 1, the liquidation of your collateral might be triggered.":"If the health factor goes below 1, the liquidation of your collateral might be triggered.","If you DO NOT unstake within {0} of unstake window, you will need to activate cooldown process again.":["If you DO NOT unstake within ",["0"]," of unstake window, you will need to activate cooldown process again."],"If your loan to value goes above the liquidation threshold your collateral supplied may be liquidated.":"If your loan to value goes above the liquidation threshold your collateral supplied may be liquidated.","In E-Mode some assets are not borrowable. Exit E-Mode to get access to all assets":"In E-Mode some assets are not borrowable. Exit E-Mode to get access to all assets","In Isolation mode, you cannot supply other assets as collateral. A global debt ceiling limits the borrowing power of the isolated asset. To exit isolation mode disable {0} as collateral before borrowing another asset. Read more in our <0>FAQ":["In Isolation mode, you cannot supply other assets as collateral. A global debt ceiling limits the borrowing power of the isolated asset. To exit isolation mode disable ",["0"]," as collateral before borrowing another asset. Read more in our <0>FAQ"],"Inconsistent flashloan parameters":"Inconsistent flashloan parameters","Insufficient collateral to cover new borrow position. Wallet must have borrowing power remaining to perform debt switch.":"Insufficient collateral to cover new borrow position. Wallet must have borrowing power remaining to perform debt switch.","Interest accrued":"Interest accrued","Interest rate rebalance conditions were not met":"Interest rate rebalance conditions were not met","Interest rate strategy":"Interest rate strategy","Invalid amount to burn":"Invalid amount to burn","Invalid amount to mint":"Invalid amount to mint","Invalid bridge protocol fee":"Invalid bridge protocol fee","Invalid expiration":"Invalid expiration","Invalid flashloan premium":"Invalid flashloan premium","Invalid return value of the flashloan executor function":"Invalid return value of the flashloan executor function","Invalid signature":"Invalid signature","Isolated":"Isolated","Isolated Debt Ceiling":"Isolated Debt Ceiling","Isolated assets have limited borrowing power and other assets cannot be used as collateral.":"Isolated assets have limited borrowing power and other assets cannot be used as collateral.","Join the community discussion":"Join the community discussion","LEARN MORE":"LEARN MORE","Language":"Language","Learn more":"Learn more","Learn more about risks involved":"Learn more about risks involved","Learn more in our <0>FAQ guide":"Learn more in our <0>FAQ guide","Learn more.":"Learn more.","Links":"Links","Liqudation":"Liqudation","Liquidated collateral":"Liquidated collateral","Liquidation":"Liquidation","Liquidation <0/> threshold":"Liquidation <0/> threshold","Liquidation Threshold":"Liquidation Threshold","Liquidation at":"Liquidation at","Liquidation penalty":"Liquidation penalty","Liquidation risk":"Liquidation risk","Liquidation risk parameters":"Liquidation risk parameters","Liquidation threshold":"Liquidation threshold","Liquidation value":"Liquidation value","Loading data...":"Loading data...","Ltv validation failed":"Ltv validation failed","MAI has been paused due to a community decision. Supply, borrows and repays are impacted. <0>More details":"MAI has been paused due to a community decision. Supply, borrows and repays are impacted. <0>More details","MAX":"MAX","Manage analytics":"Manage analytics","Market":"Market","Markets":"Markets","Max":"Max","Max LTV":"Max LTV","Max slashing":"Max slashing","Max slippage":"Max slippage","Maximum amount available to borrow against this asset is limited because debt ceiling is at {0}%.":["Maximum amount available to borrow against this asset is limited because debt ceiling is at ",["0"],"%."],"Maximum amount available to borrow is <0/> {0} (<1/>).":["Maximum amount available to borrow is <0/> ",["0"]," (<1/>)."],"Maximum amount available to borrow is limited because protocol borrow cap is nearly reached.":"Maximum amount available to borrow is limited because protocol borrow cap is nearly reached.","Maximum amount available to supply is <0/> {0} (<1/>).":["Maximum amount available to supply is <0/> ",["0"]," (<1/>)."],"Maximum amount available to supply is limited because protocol supply cap is at {0}%.":["Maximum amount available to supply is limited because protocol supply cap is at ",["0"],"%."],"Maximum loan to value":"Maximum loan to value","Meet GHO":"Meet GHO","Menu":"Menu","Migrate":"Migrate","Migrate to V3":"Migrate to V3","Migrate to v3":"Migrate to v3","Migrate to {0} v3 Market":["Migrate to ",["0"]," v3 Market"],"Migrated":"Migrated","Migrating":"Migrating","Migrating multiple collaterals and borrowed assets at the same time can be an expensive operation and might fail in certain situations.<0>Therefore it’s not recommended to migrate positions with more than 5 assets (deposited + borrowed) at the same time.":"Migrating multiple collaterals and borrowed assets at the same time can be an expensive operation and might fail in certain situations.<0>Therefore it’s not recommended to migrate positions with more than 5 assets (deposited + borrowed) at the same time.","Migration risks":"Migration risks","Minimum GHO borrow amount":"Minimum GHO borrow amount","Minimum USD value received":"Minimum USD value received","Minimum staked Aave amount":"Minimum staked Aave amount","Minimum {0} received":["Minimum ",["0"]," received"],"More":"More","NAY":"NAY","Need help connecting a wallet? <0>Read our FAQ":"Need help connecting a wallet? <0>Read our FAQ","Net APR":"Net APR","Net APY":"Net APY","Net APY is the combined effect of all supply and borrow positions on net worth, including incentives. It is possible to have a negative net APY if debt APY is higher than supply APY.":"Net APY is the combined effect of all supply and borrow positions on net worth, including incentives. It is possible to have a negative net APY if debt APY is higher than supply APY.","Net worth":"Net worth","Network":"Network","Network not supported for this wallet":"Network not supported for this wallet","New APY":"New APY","No assets selected to migrate.":"No assets selected to migrate.","No rewards to claim":"No rewards to claim","No search results{0}":["No search results",["0"]],"No transactions yet.":"No transactions yet.","No voting power":"No voting power","None":"None","Not a valid address":"Not a valid address","Not enough balance on your wallet":"Not enough balance on your wallet","Not enough collateral to repay this amount of debt with":"Not enough collateral to repay this amount of debt with","Not enough staked balance":"Not enough staked balance","Not enough voting power to participate in this proposal":"Not enough voting power to participate in this proposal","Not reached":"Not reached","Nothing borrowed yet":"Nothing borrowed yet","Nothing found":"Nothing found","Nothing staked":"Nothing staked","Nothing supplied yet":"Nothing supplied yet","Notify":"Notify","Ok, Close":"Ok, Close","Ok, I got it":"Ok, I got it","Operation not supported":"Operation not supported","Oracle price":"Oracle price","Overview":"Overview","Page not found":"Page not found","Participating in this {symbol} reserve gives annualized rewards.":["Participating in this ",["symbol"]," reserve gives annualized rewards."],"Pending...":"Pending...","Per the community, the Fantom market has been frozen.":"Per the community, the Fantom market has been frozen.","Per the community, the V2 AMM market has been deprecated.":"Per the community, the V2 AMM market has been deprecated.","Please always be aware of your <0>Health Factor (HF) when partially migrating a position and that your rates will be updated to V3 rates.":"Please always be aware of your <0>Health Factor (HF) when partially migrating a position and that your rates will be updated to V3 rates.","Please connect a wallet to view your personal information here.":"Please connect a wallet to view your personal information here.","Please connect your wallet to be able to switch your tokens.":"Please connect your wallet to be able to switch your tokens.","Please connect your wallet to get free testnet assets.":"Please connect your wallet to get free testnet assets.","Please connect your wallet to see migration tool.":"Please connect your wallet to see migration tool.","Please connect your wallet to see your supplies, borrowings, and open positions.":"Please connect your wallet to see your supplies, borrowings, and open positions.","Please connect your wallet to view transaction history.":"Please connect your wallet to view transaction history.","Please enter a valid wallet address.":"Please enter a valid wallet address.","Please switch to {networkName}.":["Please switch to ",["networkName"],"."],"Please, connect your wallet":"Please, connect your wallet","Pool addresses provider is not registered":"Pool addresses provider is not registered","Powered by":"Powered by","Preview tx and migrate":"Preview tx and migrate","Price":"Price","Price data is not currently available for this reserve on the protocol subgraph":"Price data is not currently available for this reserve on the protocol subgraph","Price impact":"Price impact","Price impact is the spread between the total value of the entry tokens switched and the destination tokens obtained (in USD), which results from the limited liquidity of the trading pair.":"Price impact is the spread between the total value of the entry tokens switched and the destination tokens obtained (in USD), which results from the limited liquidity of the trading pair.","Price impact {0}%":["Price impact ",["0"],"%"],"Privacy":"Privacy","Proposal details":"Proposal details","Proposal overview":"Proposal overview","Proposals":"Proposals","Proposition":"Proposition","Protocol borrow cap at 100% for this asset. Further borrowing unavailable.":"Protocol borrow cap at 100% for this asset. Further borrowing unavailable.","Protocol borrow cap is at 100% for this asset. Further borrowing unavailable.":"Protocol borrow cap is at 100% for this asset. Further borrowing unavailable.","Protocol debt ceiling is at 100% for this asset. Further borrowing against this asset is unavailable.":"Protocol debt ceiling is at 100% for this asset. Further borrowing against this asset is unavailable.","Protocol debt ceiling is at 100% for this asset. Futher borrowing against this asset is unavailable.":"Protocol debt ceiling is at 100% for this asset. Futher borrowing against this asset is unavailable.","Protocol supply cap at 100% for this asset. Further supply unavailable.":"Protocol supply cap at 100% for this asset. Further supply unavailable.","Protocol supply cap is at 100% for this asset. Further supply unavailable.":"Protocol supply cap is at 100% for this asset. Further supply unavailable.","Quorum":"Quorum","Rate change":"Rate change","Raw-Ipfs":"Raw-Ipfs","Reached":"Reached","Reactivate cooldown period to unstake {0} {stakedToken}":["Reactivate cooldown period to unstake ",["0"]," ",["stakedToken"]],"Read more here.":"Read more here.","Read-only mode allows to see address positions in Aave, but you won't be able to perform transactions.":"Read-only mode allows to see address positions in Aave, but you won't be able to perform transactions.","Read-only mode.":"Read-only mode.","Read-only mode. Connect to a wallet to perform transactions.":"Read-only mode. Connect to a wallet to perform transactions.","Receive (est.)":"Receive (est.)","Received":"Received","Recipient address":"Recipient address","Rejected connection request":"Rejected connection request","Reload":"Reload","Reload the page":"Reload the page","Remaining debt":"Remaining debt","Remaining supply":"Remaining supply","Repaid":"Repaid","Repay":"Repay","Repay with":"Repay with","Repay {symbol}":["Repay ",["symbol"]],"Repaying {symbol}":["Repaying ",["symbol"]],"Repayment amount to reach {0}% utilization":["Repayment amount to reach ",["0"],"% utilization"],"Reserve Size":"Reserve Size","Reserve factor":"Reserve factor","Reserve factor is a percentage of interest which goes to a {0} that is controlled by Aave governance to promote ecosystem growth.":["Reserve factor is a percentage of interest which goes to a ",["0"]," that is controlled by Aave governance to promote ecosystem growth."],"Reserve status & configuration":"Reserve status & configuration","Reset":"Reset","Restake":"Restake","Restake {symbol}":["Restake ",["symbol"]],"Restaked":"Restaked","Restaking {symbol}":["Restaking ",["symbol"]],"Review approval tx details":"Review approval tx details","Review changes to continue":"Review changes to continue","Review tx":"Review tx","Review tx details":"Review tx details","Revoke power":"Revoke power","Reward(s) to claim":"Reward(s) to claim","Rewards APR":"Rewards APR","Risk details":"Risk details","SEE CHARTS":"SEE CHARTS","Safety of your deposited collateral against the borrowed assets and its underlying value.":"Safety of your deposited collateral against the borrowed assets and its underlying value.","Save and share":"Save and share","Seatbelt report":"Seatbelt report","Seems like we can't switch the network automatically. Please check if you can change it from the wallet.":"Seems like we can't switch the network automatically. Please check if you can change it from the wallet.","Select":"Select","Select APY type to switch":"Select APY type to switch","Select an asset":"Select an asset","Select language":"Select language","Select slippage tolerance":"Select slippage tolerance","Select v2 borrows to migrate":"Select v2 borrows to migrate","Select v2 supplies to migrate":"Select v2 supplies to migrate","Selected assets have successfully migrated. Visit the Market Dashboard to see them.":"Selected assets have successfully migrated. Visit the Market Dashboard to see them.","Selected borrow assets":"Selected borrow assets","Selected supply assets":"Selected supply assets","Send feedback":"Send feedback","Set up delegation":"Set up delegation","Setup notifications about your Health Factor using the Hal app.":"Setup notifications about your Health Factor using the Hal app.","Share on Lens":"Share on Lens","Share on twitter":"Share on twitter","Show":"Show","Show Frozen or paused assets":"Show Frozen or paused assets","Show assets with 0 balance":"Show assets with 0 balance","Sign to continue":"Sign to continue","Signatures ready":"Signatures ready","Signing":"Signing","Since this asset is frozen, the only available actions are withdraw and repay which can be accessed from the <0>Dashboard":"Since this asset is frozen, the only available actions are withdraw and repay which can be accessed from the <0>Dashboard","Since this is a test network, you can get any of the assets if you have ETH on your wallet":"Since this is a test network, you can get any of the assets if you have ETH on your wallet","Slippage":"Slippage","Slippage is the difference between the quoted and received amounts from changing market conditions between the moment the transaction is submitted and its verification.":"Slippage is the difference between the quoted and received amounts from changing market conditions between the moment the transaction is submitted and its verification.","Some migrated assets will not be used as collateral due to enabled isolation mode in {marketName} V3 Market. Visit <0>{marketName} V3 Dashboard to manage isolation mode.":["Some migrated assets will not be used as collateral due to enabled isolation mode in ",["marketName"]," V3 Market. Visit <0>",["marketName"]," V3 Dashboard to manage isolation mode."],"Something went wrong":"Something went wrong","Sorry, an unexpected error happened. In the meantime you may try reloading the page, or come back later.":"Sorry, an unexpected error happened. In the meantime you may try reloading the page, or come back later.","Sorry, we couldn't find the page you were looking for.":"Sorry, we couldn't find the page you were looking for.","Spanish":"Spanish","Stable":"Stable","Stable Interest Type is disabled for this currency":"Stable Interest Type is disabled for this currency","Stable borrowing is enabled":"Stable borrowing is enabled","Stable borrowing is not enabled":"Stable borrowing is not enabled","Stable debt supply is not zero":"Stable debt supply is not zero","Stable interest rate will <0>stay the same for the duration of your loan. Recommended for long-term loan periods and for users who prefer predictability.":"Stable interest rate will <0>stay the same for the duration of your loan. Recommended for long-term loan periods and for users who prefer predictability.","Stablecoin":"Stablecoin","Stake":"Stake","Stake AAVE":"Stake AAVE","Stake ABPT":"Stake ABPT","Stake cooldown activated":"Stake cooldown activated","Staked":"Staked","Staking":"Staking","Staking APR":"Staking APR","Staking Rewards":"Staking Rewards","Staking balance":"Staking balance","Staking discount":"Staking discount","Started":"Started","State":"State","Static interest rate that is determined by Aave Governance. This rate may be changed over time depending on the need for the GHO supply to contract/expand. <0>Learn more":"Static interest rate that is determined by Aave Governance. This rate may be changed over time depending on the need for the GHO supply to contract/expand. <0>Learn more","Supplied":"Supplied","Supplied asset amount":"Supplied asset amount","Supply":"Supply","Supply APY":"Supply APY","Supply apy":"Supply apy","Supply balance":"Supply balance","Supply balance after switch":"Supply balance after switch","Supply cap is exceeded":"Supply cap is exceeded","Supply cap on target reserve reached. Try lowering the amount.":"Supply cap on target reserve reached. Try lowering the amount.","Supply {symbol}":["Supply ",["symbol"]],"Supplying your":"Supplying your","Supplying {symbol}":["Supplying ",["symbol"]],"Switch":"Switch","Switch APY type":"Switch APY type","Switch E-Mode":"Switch E-Mode","Switch E-Mode category":"Switch E-Mode category","Switch Network":"Switch Network","Switch borrow position":"Switch borrow position","Switch rate":"Switch rate","Switch to":"Switch to","Switched":"Switched","Switching":"Switching","Switching E-Mode":"Switching E-Mode","Switching rate":"Switching rate","Techpaper":"Techpaper","Terms":"Terms","Test Assets":"Test Assets","Testnet mode":"Testnet mode","Testnet mode is ON":"Testnet mode is ON","Thank you for voting!!":"Thank you for voting!!","The % of your total borrowing power used. This is based on the amount of your collateral supplied and the total amount that you can borrow.":"The % of your total borrowing power used. This is based on the amount of your collateral supplied and the total amount that you can borrow.","The Aave Balancer Pool Token (ABPT) is a liquidity pool token. You can receive ABPT by depositing a combination of AAVE + ETH in the Balancer liquidity pool. You can then stake your BPT in the Safety Module to secure the protocol and earn Safety Incentives.":"The Aave Balancer Pool Token (ABPT) is a liquidity pool token. You can receive ABPT by depositing a combination of AAVE + ETH in the Balancer liquidity pool. You can then stake your BPT in the Safety Module to secure the protocol and earn Safety Incentives.","The Aave Protocol is programmed to always use the price of 1 GHO = $1. This is different from using market pricing via oracles for other crypto assets. This creates stabilizing arbitrage opportunities when the price of GHO fluctuates.":"The Aave Protocol is programmed to always use the price of 1 GHO = $1. This is different from using market pricing via oracles for other crypto assets. This creates stabilizing arbitrage opportunities when the price of GHO fluctuates.","The Maximum LTV ratio represents the maximum borrowing power of a specific collateral. For example, if a collateral has an LTV of 75%, the user can borrow up to 0.75 worth of ETH in the principal currency for every 1 ETH worth of collateral.":"The Maximum LTV ratio represents the maximum borrowing power of a specific collateral. For example, if a collateral has an LTV of 75%, the user can borrow up to 0.75 worth of ETH in the principal currency for every 1 ETH worth of collateral.","The Stable Rate is not enabled for this currency":"The Stable Rate is not enabled for this currency","The address of the pool addresses provider is invalid":"The address of the pool addresses provider is invalid","The app is running in testnet mode. Learn how it works in":"The app is running in testnet mode. Learn how it works in","The caller of the function is not an AToken":"The caller of the function is not an AToken","The caller of this function must be a pool":"The caller of this function must be a pool","The collateral balance is 0":"The collateral balance is 0","The collateral chosen cannot be liquidated":"The collateral chosen cannot be liquidated","The cooldown period is the time required prior to unstaking your tokens (20 days). You can only withdraw your assets from the Security Module after the cooldown period and within the unstake window.<0>Learn more":"The cooldown period is the time required prior to unstaking your tokens (20 days). You can only withdraw your assets from the Security Module after the cooldown period and within the unstake window.<0>Learn more","The cooldown period is {0}. After {1} of cooldown, you will enter unstake window of {2}. You will continue receiving rewards during cooldown and unstake window.":["The cooldown period is ",["0"],". After ",["1"]," of cooldown, you will enter unstake window of ",["2"],". You will continue receiving rewards during cooldown and unstake window."],"The effects on the health factor would cause liquidation. Try lowering the amount.":"The effects on the health factor would cause liquidation. Try lowering the amount.","The loan to value of the migrated positions would cause liquidation. Increase migrated collateral or reduce migrated borrow to continue.":"The loan to value of the migrated positions would cause liquidation. Increase migrated collateral or reduce migrated borrow to continue.","The requested amount is greater than the max loan size in stable rate mode":"The requested amount is greater than the max loan size in stable rate mode","The total amount of your assets denominated in USD that can be used as collateral for borrowing assets.":"The total amount of your assets denominated in USD that can be used as collateral for borrowing assets.","The underlying asset cannot be rescued":"The underlying asset cannot be rescued","The underlying balance needs to be greater than 0":"The underlying balance needs to be greater than 0","The weighted average of APY for all borrowed assets, including incentives.":"The weighted average of APY for all borrowed assets, including incentives.","The weighted average of APY for all supplied assets, including incentives.":"The weighted average of APY for all supplied assets, including incentives.","There are not enough funds in the{0}reserve to borrow":["There are not enough funds in the",["0"],"reserve to borrow"],"There is not enough collateral to cover a new borrow":"There is not enough collateral to cover a new borrow","There is not enough liquidity for the target asset to perform the switch. Try lowering the amount.":"There is not enough liquidity for the target asset to perform the switch. Try lowering the amount.","There was some error. Please try changing the parameters or <0><1>copy the error":"There was some error. Please try changing the parameters or <0><1>copy the error","These assets are temporarily frozen or paused by Aave community decisions, meaning that further supply / borrow, or rate swap of these assets are unavailable. Withdrawals and debt repayments are allowed. Follow the <0>Aave governance forum for further updates.":"These assets are temporarily frozen or paused by Aave community decisions, meaning that further supply / borrow, or rate swap of these assets are unavailable. Withdrawals and debt repayments are allowed. Follow the <0>Aave governance forum for further updates.","These funds have been borrowed and are not available for withdrawal at this time.":"These funds have been borrowed and are not available for withdrawal at this time.","This action will reduce V2 health factor below liquidation threshold. retain collateral or migrate borrow position to continue.":"This action will reduce V2 health factor below liquidation threshold. retain collateral or migrate borrow position to continue.","This action will reduce health factor of V3 below liquidation threshold. Increase migrated collateral or reduce migrated borrow to continue.":"This action will reduce health factor of V3 below liquidation threshold. Increase migrated collateral or reduce migrated borrow to continue.","This action will reduce your health factor. Please be mindful of the increased risk of collateral liquidation.":"This action will reduce your health factor. Please be mindful of the increased risk of collateral liquidation.","This address is blocked on app.aave.com because it is associated with one or more":"This address is blocked on app.aave.com because it is associated with one or more","This asset has almost reached its borrow cap. There is only {messageValue} available to be borrowed from this market.":["This asset has almost reached its borrow cap. There is only ",["messageValue"]," available to be borrowed from this market."],"This asset has almost reached its supply cap. There can only be {messageValue} supplied to this market.":["This asset has almost reached its supply cap. There can only be ",["messageValue"]," supplied to this market."],"This asset has reached its borrow cap. Nothing is available to be borrowed from this market.":"This asset has reached its borrow cap. Nothing is available to be borrowed from this market.","This asset has reached its supply cap. Nothing is available to be supplied from this market.":"This asset has reached its supply cap. Nothing is available to be supplied from this market.","This asset is frozen due to an Aave Protocol Governance decision. <0>More details":"This asset is frozen due to an Aave Protocol Governance decision. <0>More details","This asset is frozen due to an Aave Protocol Governance decision. On the 20th of December 2022, renFIL will no longer be supported and cannot be bridged back to its native network. It is recommended to withdraw supply positions and repay borrow positions so that renFIL can be bridged back to FIL before the deadline. After this date, it will no longer be possible to convert renFIL to FIL. <0>More details":"This asset is frozen due to an Aave Protocol Governance decision. On the 20th of December 2022, renFIL will no longer be supported and cannot be bridged back to its native network. It is recommended to withdraw supply positions and repay borrow positions so that renFIL can be bridged back to FIL before the deadline. After this date, it will no longer be possible to convert renFIL to FIL. <0>More details","This asset is frozen due to an Aave community decision. <0>More details":"This asset is frozen due to an Aave community decision. <0>More details","This asset is planned to be offboarded due to an Aave Protocol Governance decision. <0>More details":"This asset is planned to be offboarded due to an Aave Protocol Governance decision. <0>More details","This gas calculation is only an estimation. Your wallet will set the price of the transaction. You can modify the gas settings directly from your wallet provider.":"This gas calculation is only an estimation. Your wallet will set the price of the transaction. You can modify the gas settings directly from your wallet provider.","This integration was<0>proposed and approvedby the community.":"This integration was<0>proposed and approvedby the community.","This is the total amount available for you to borrow. You can borrow based on your collateral and until the borrow cap is reached.":"This is the total amount available for you to borrow. You can borrow based on your collateral and until the borrow cap is reached.","This is the total amount that you are able to supply to in this reserve. You are able to supply your wallet balance up until the supply cap is reached.":"This is the total amount that you are able to supply to in this reserve. You are able to supply your wallet balance up until the supply cap is reached.","This represents the threshold at which a borrow position will be considered undercollateralized and subject to liquidation for each collateral. For example, if a collateral has a liquidation threshold of 80%, it means that the position will be liquidated when the debt value is worth 80% of the collateral value.":"This represents the threshold at which a borrow position will be considered undercollateralized and subject to liquidation for each collateral. For example, if a collateral has a liquidation threshold of 80%, it means that the position will be liquidated when the debt value is worth 80% of the collateral value.","Time left to be able to withdraw your staked asset.":"Time left to be able to withdraw your staked asset.","Time left to unstake":"Time left to unstake","Time left until the withdrawal window closes.":"Time left until the withdrawal window closes.","Tip: Try increasing slippage or reduce input amount":"Tip: Try increasing slippage or reduce input amount","To borrow you need to supply any asset to be used as collateral.":"To borrow you need to supply any asset to be used as collateral.","To continue, you need to grant Aave smart contracts permission to move your funds from your wallet. Depending on the asset and wallet you use, it is done by signing the permission message (gas free), or by submitting an approval transaction (requires gas). <0>Learn more":"To continue, you need to grant Aave smart contracts permission to move your funds from your wallet. Depending on the asset and wallet you use, it is done by signing the permission message (gas free), or by submitting an approval transaction (requires gas). <0>Learn more","To enable E-mode for the {0} category, all borrow positions outside of this category must be closed.":["To enable E-mode for the ",["0"]," category, all borrow positions outside of this category must be closed."],"To repay on behalf of a user an explicit amount to repay is needed":"To repay on behalf of a user an explicit amount to repay is needed","To request access for this permissioned market, please visit: <0>Acces Provider Name":"To request access for this permissioned market, please visit: <0>Acces Provider Name","To submit a proposal for minor changes to the protocol, you'll need at least 80.00K power. If you want to change the core code base, you'll need 320k power.<0>Learn more.":"To submit a proposal for minor changes to the protocol, you'll need at least 80.00K power. If you want to change the core code base, you'll need 320k power.<0>Learn more.","Top 10 addresses":"Top 10 addresses","Total available":"Total available","Total borrowed":"Total borrowed","Total borrows":"Total borrows","Total emission per day":"Total emission per day","Total interest accrued":"Total interest accrued","Total market size":"Total market size","Total supplied":"Total supplied","Total voting power":"Total voting power","Total worth":"Total worth","Track wallet":"Track wallet","Track wallet balance in read-only mode":"Track wallet balance in read-only mode","Transaction failed":"Transaction failed","Transaction history":"Transaction history","Transaction history is not currently available for this market":"Transaction history is not currently available for this market","Transaction overview":"Transaction overview","Transactions":"Transactions","UNSTAKE {symbol}":["UNSTAKE ",["symbol"]],"Unavailable":"Unavailable","Unbacked":"Unbacked","Unbacked mint cap is exceeded":"Unbacked mint cap is exceeded","Underlying asset does not exist in {marketName} v3 Market, hence this position cannot be migrated.":["Underlying asset does not exist in ",["marketName"]," v3 Market, hence this position cannot be migrated."],"Underlying token":"Underlying token","Unstake now":"Unstake now","Unstake window":"Unstake window","Unstaked":"Unstaked","Unstaking {symbol}":["Unstaking ",["symbol"]],"Update: Disruptions reported for WETH, WBTC, WMATIC, and USDT. AIP 230 will resolve the disruptions and the market will be operating as normal on ~26th May 13h00 UTC.":"Update: Disruptions reported for WETH, WBTC, WMATIC, and USDT. AIP 230 will resolve the disruptions and the market will be operating as normal on ~26th May 13h00 UTC.","Use it to vote for or against active proposals.":"Use it to vote for or against active proposals.","Use your AAVE and stkAAVE balance to delegate your voting and proposition powers. You will not be sending any tokens, only the rights to vote and propose changes to the protocol. You can re-delegate or revoke power to self at any time.":"Use your AAVE and stkAAVE balance to delegate your voting and proposition powers. You will not be sending any tokens, only the rights to vote and propose changes to the protocol. You can re-delegate or revoke power to self at any time.","Used as collateral":"Used as collateral","User cannot withdraw more than the available balance":"User cannot withdraw more than the available balance","User did not borrow the specified currency":"User did not borrow the specified currency","User does not have outstanding stable rate debt on this reserve":"User does not have outstanding stable rate debt on this reserve","User does not have outstanding variable rate debt on this reserve":"User does not have outstanding variable rate debt on this reserve","User is in isolation mode":"User is in isolation mode","User is trying to borrow multiple assets including a siloed one":"User is trying to borrow multiple assets including a siloed one","Users who stake AAVE in Safety Module (i.e. stkAAVE holders) receive a discount on GHO borrow interest rate. The discount applies to 100 GHO for every 1 stkAAVE held. Use the calculator below to see GHO borrow rate with the discount applied.":"Users who stake AAVE in Safety Module (i.e. stkAAVE holders) receive a discount on GHO borrow interest rate. The discount applies to 100 GHO for every 1 stkAAVE held. Use the calculator below to see GHO borrow rate with the discount applied.","Utilization Rate":"Utilization Rate","VIEW TX":"VIEW TX","VOTE NAY":"VOTE NAY","VOTE YAE":"VOTE YAE","Variable":"Variable","Variable debt supply is not zero":"Variable debt supply is not zero","Variable interest rate will <0>fluctuate based on the market conditions. Recommended for short-term positions.":"Variable interest rate will <0>fluctuate based on the market conditions. Recommended for short-term positions.","Variable rate":"Variable rate","Version 2":"Version 2","Version 3":"Version 3","View":"View","View Transactions":"View Transactions","View all votes":"View all votes","View contract":"View contract","View details":"View details","View on Explorer":"View on Explorer","Vote NAY":"Vote NAY","Vote YAE":"Vote YAE","Voted NAY":"Voted NAY","Voted YAE":"Voted YAE","Votes":"Votes","Voting":"Voting","Voting power":"Voting power","Voting results":"Voting results","Wallet Balance":"Wallet Balance","Wallet balance":"Wallet balance","Wallet not detected. Connect or install wallet and retry":"Wallet not detected. Connect or install wallet and retry","Wallets are provided by External Providers and by selecting you agree to Terms of those Providers. Your access to the wallet might be reliant on the External Provider being operational.":"Wallets are provided by External Providers and by selecting you agree to Terms of those Providers. Your access to the wallet might be reliant on the External Provider being operational.","We couldn't find any assets related to your search. Try again with a different asset name, symbol, or address.":"We couldn't find any assets related to your search. Try again with a different asset name, symbol, or address.","We couldn't find any transactions related to your search. Try again with a different asset name, or reset filters.":"We couldn't find any transactions related to your search. Try again with a different asset name, or reset filters.","We couldn’t detect a wallet. Connect a wallet to stake and view your balance.":"We couldn’t detect a wallet. Connect a wallet to stake and view your balance.","We suggest you go back to the Dashboard.":"We suggest you go back to the Dashboard.","Website":"Website","When a liquidation occurs, liquidators repay up to 50% of the outstanding borrowed amount on behalf of the borrower. In return, they can buy the collateral at a discount and keep the difference (liquidation penalty) as a bonus.":"When a liquidation occurs, liquidators repay up to 50% of the outstanding borrowed amount on behalf of the borrower. In return, they can buy the collateral at a discount and keep the difference (liquidation penalty) as a bonus.","With a voting power of <0/>":"With a voting power of <0/>","With testnet Faucet you can get free assets to test the Aave Protocol. Make sure to switch your wallet provider to the appropriate testnet network, select desired asset, and click ‘Faucet’ to get tokens transferred to your wallet. The assets on a testnet are not “real,” meaning they have no monetary value. <0>Learn more":"With testnet Faucet you can get free assets to test the Aave Protocol. Make sure to switch your wallet provider to the appropriate testnet network, select desired asset, and click ‘Faucet’ to get tokens transferred to your wallet. The assets on a testnet are not “real,” meaning they have no monetary value. <0>Learn more","Withdraw":"Withdraw","Withdraw & Switch":"Withdraw & Switch","Withdraw and Switch":"Withdraw and Switch","Withdraw {symbol}":["Withdraw ",["symbol"]],"Withdrawing":"Withdrawing","Withdrawing and Switching":"Withdrawing and Switching","Withdrawing this amount will reduce your health factor and increase risk of liquidation.":"Withdrawing this amount will reduce your health factor and increase risk of liquidation.","Withdrawing {symbol}":["Withdrawing ",["symbol"]],"Wrong Network":"Wrong Network","YAE":"YAE","You are entering Isolation mode":"You are entering Isolation mode","You can borrow this asset with a stable rate only if you borrow more than the amount you are supplying as collateral.":"You can borrow this asset with a stable rate only if you borrow more than the amount you are supplying as collateral.","You can not change Interest Type to stable as your borrowings are higher than your collateral":"You can not change Interest Type to stable as your borrowings are higher than your collateral","You can not disable E-Mode as your current collateralization level is above 80%, disabling E-Mode can cause liquidation. To exit E-Mode supply or repay borrowed positions.":"You can not disable E-Mode as your current collateralization level is above 80%, disabling E-Mode can cause liquidation. To exit E-Mode supply or repay borrowed positions.","You can not switch usage as collateral mode for this currency, because it will cause collateral call":"You can not switch usage as collateral mode for this currency, because it will cause collateral call","You can not use this currency as collateral":"You can not use this currency as collateral","You can not withdraw this amount because it will cause collateral call":"You can not withdraw this amount because it will cause collateral call","You can only switch to tokens with variable APY types. After this transaction, you may change the variable rate to a stable one if available.":"You can only switch to tokens with variable APY types. After this transaction, you may change the variable rate to a stable one if available.","You can only withdraw your assets from the Security Module after the cooldown period ends and the unstake window is active.":"You can only withdraw your assets from the Security Module after the cooldown period ends and the unstake window is active.","You can report incident to our <0>Discord or<1>Github.":"You can report incident to our <0>Discord or<1>Github.","You cancelled the transaction.":"You cancelled the transaction.","You did not participate in this proposal":"You did not participate in this proposal","You do not have supplies in this currency":"You do not have supplies in this currency","You don’t have enough funds in your wallet to repay the full amount. If you proceed to repay with your current amount of funds, you will still have a small borrowing position in your dashboard.":"You don’t have enough funds in your wallet to repay the full amount. If you proceed to repay with your current amount of funds, you will still have a small borrowing position in your dashboard.","You have no AAVE/stkAAVE balance to delegate.":"You have no AAVE/stkAAVE balance to delegate.","You have not borrow yet using this currency":"You have not borrow yet using this currency","You may borrow up to <0/> GHO at <1/> (max discount)":"You may borrow up to <0/> GHO at <1/> (max discount)","You may enter a custom amount in the field.":"You may enter a custom amount in the field.","You switched to {0} rate":["You switched to ",["0"]," rate"],"You unstake here":"You unstake here","You voted {0}":["You voted ",["0"]],"You will exit isolation mode and other tokens can now be used as collateral":"You will exit isolation mode and other tokens can now be used as collateral","You {action} <0/> {symbol}":["You ",["action"]," <0/> ",["symbol"]],"You've successfully switched borrow position.":"You've successfully switched borrow position.","You've successfully switched tokens.":"You've successfully switched tokens.","You've successfully withdrew & switched tokens.":"You've successfully withdrew & switched tokens.","Your balance is lower than the selected amount.":"Your balance is lower than the selected amount.","Your borrows":"Your borrows","Your current loan to value based on your collateral supplied.":"Your current loan to value based on your collateral supplied.","Your health factor and loan to value determine the assurance of your collateral. To avoid liquidations you can supply more collateral or repay borrow positions.":"Your health factor and loan to value determine the assurance of your collateral. To avoid liquidations you can supply more collateral or repay borrow positions.","Your info":"Your info","Your proposition power is based on your AAVE/stkAAVE balance and received delegations.":"Your proposition power is based on your AAVE/stkAAVE balance and received delegations.","Your reward balance is 0":"Your reward balance is 0","Your supplies":"Your supplies","Your voting info":"Your voting info","Your voting power is based on your AAVE/stkAAVE balance and received delegations.":"Your voting power is based on your AAVE/stkAAVE balance and received delegations.","Your {name} wallet is empty. Purchase or transfer assets or use <0>{0} to transfer your {network} assets.":["Your ",["name"]," wallet is empty. Purchase or transfer assets or use <0>",["0"]," to transfer your ",["network"]," assets."],"Your {name} wallet is empty. Purchase or transfer assets.":["Your ",["name"]," wallet is empty. Purchase or transfer assets."],"Your {networkName} wallet is empty. Get free test assets at":["Your ",["networkName"]," wallet is empty. Get free test assets at"],"Your {networkName} wallet is empty. Get free test {0} at":["Your ",["networkName"]," wallet is empty. Get free test ",["0"]," at"],"Zero address not valid":"Zero address not valid","assets":"assets","blocked activities":"blocked activities","copy the error":"copy the error","disabled":"disabled","documentation":"documentation","enabled":"enabled","ends":"ends","for":"for","of":"of","on":"on","please check that the amount you want to supply is not currently being used for staking. If it is being used for staking, your transaction might fail.":"please check that the amount you want to supply is not currently being used for staking. If it is being used for staking, your transaction might fail.","repaid":"repaid","stETH supplied as collateral will continue to accrue staking rewards provided by daily rebases.":"stETH supplied as collateral will continue to accrue staking rewards provided by daily rebases.","stETH tokens will be migrated to Wrapped stETH using Lido Protocol wrapper which leads to supply balance change after migration: {0}":["stETH tokens will be migrated to Wrapped stETH using Lido Protocol wrapper which leads to supply balance change after migration: ",["0"]],"staking view":"staking view","starts":"starts","stkAAVE holders get a discount on GHO borrow rate":"stkAAVE holders get a discount on GHO borrow rate","to":"to","tokens is not the same as staking them. If you wish to stake your":"tokens is not the same as staking them. If you wish to stake your","tokens, please go to the":"tokens, please go to the","withdrew":"withdrew","{0}":[["0"]],"{0} Balance":[["0"]," Balance"],"{0} Faucet":[["0"]," Faucet"],"{0} on-ramp service is provided by External Provider and by selecting you agree to Terms of the Provider. Your access to the service might be reliant on the External Provider being operational.":[["0"]," on-ramp service is provided by External Provider and by selecting you agree to Terms of the Provider. Your access to the service might be reliant on the External Provider being operational."],"{0}{name}":[["0"],["name"]],"{currentMethod}":[["currentMethod"]],"{d}d":[["d"],"d"],"{h}h":[["h"],"h"],"{m}m":[["m"],"m"],"{networkName} Faucet":[["networkName"]," Faucet"],"{notifyText}":[["notifyText"]],"{numSelected}/{numAvailable} assets selected":[["numSelected"],"/",["numAvailable"]," assets selected"],"{s}s":[["s"],"s"],"{title}":[["title"]],"{tooltipText}":[["tooltipText"]]}}; \ No newline at end of file diff --git a/src/locales/en/messages.po b/src/locales/en/messages.po index 94027ce110..a138c5dfeb 100644 --- a/src/locales/en/messages.po +++ b/src/locales/en/messages.po @@ -791,6 +791,7 @@ msgstr "Current v2 balance" msgid "Current votes" msgstr "Current votes" +#: src/components/infoTooltips/WrappedTokenToolTipContent.tsx #: src/components/transactions/Supply/SupplyModalContent.tsx msgid "DAI balance will be converted via DSR contracts and then supplied as sDAI to Aave reserve. Switching incurs no additional costs and no slippage." msgstr "DAI balance will be converted via DSR contracts and then supplied as sDAI to Aave reserve. Switching incurs no additional costs and no slippage." @@ -1012,6 +1013,11 @@ msgstr "Estimated compounding interest, including discount for Staking {0}AAVE i msgid "Exceeds the discount" msgstr "Exceeds the discount" +#: src/components/infoTooltips/WrappedTokenToolTipContent.tsx +#: src/components/transactions/Supply/SupplyModalContent.tsx +msgid "Exchange rate" +msgstr "Exchange rate" + #: pages/governance/proposal/[proposalId].governance.tsx msgid "Executed" msgstr "Executed" @@ -1274,7 +1280,6 @@ msgstr "Language" #: src/components/infoTooltips/DebtCeilingMaxedTooltip.tsx #: src/components/infoTooltips/SupplyCapMaxedTooltip.tsx #: src/components/transactions/StakeCooldown/StakeCooldownModalContent.tsx -#: src/components/transactions/Supply/SupplyModalContent.tsx #: src/components/transactions/Warnings/BorrowCapWarning.tsx #: src/components/transactions/Warnings/DebtCeilingWarning.tsx #: src/components/transactions/Warnings/MarketWarning.tsx @@ -2172,6 +2177,7 @@ msgstr "State" msgid "Static interest rate that is determined by Aave Governance. This rate may be changed over time depending on the need for the GHO supply to contract/expand. <0>Learn more" msgstr "Static interest rate that is determined by Aave Governance. This rate may be changed over time depending on the need for the GHO supply to contract/expand. <0>Learn more" +#: src/components/transactions/Supply/SupplyModalContent.tsx #: src/components/transactions/Supply/SupplyModalContent.tsx msgid "Supplied" msgstr "Supplied" @@ -2192,6 +2198,7 @@ msgstr "Supplied asset amount" msgid "Supply" msgstr "Supply" +#: src/components/transactions/Supply/SupplyModalContent.tsx #: src/components/transactions/Supply/SupplyModalContent.tsx #: src/modules/dashboard/lists/SuppliedPositionsList/SuppliedPositionsListMobileItem.tsx #: src/modules/dashboard/lists/SupplyAssetsList/SupplyAssetsListMobileItem.tsx @@ -2833,6 +2840,7 @@ msgstr "Wallet Balance" #: src/components/transactions/Repay/RepayTypeSelector.tsx #: src/components/transactions/Stake/StakeModalContent.tsx #: src/components/transactions/Supply/SupplyModalContent.tsx +#: src/components/transactions/Supply/SupplyModalContent.tsx #: src/modules/dashboard/lists/SupplyAssetsList/SupplyAssetsList.tsx #: src/modules/faucet/FaucetAssetsList.tsx msgid "Wallet balance" diff --git a/src/modules/dashboard/lists/SupplyAssetsList/SupplyAssetsList.tsx b/src/modules/dashboard/lists/SupplyAssetsList/SupplyAssetsList.tsx index 5cf330f60b..ba8d4c2bbc 100644 --- a/src/modules/dashboard/lists/SupplyAssetsList/SupplyAssetsList.tsx +++ b/src/modules/dashboard/lists/SupplyAssetsList/SupplyAssetsList.tsx @@ -52,6 +52,7 @@ export const SupplyAssetsList = () => { reserves, marketReferencePriceInUsd, loading: loadingReserves, + wrappedTokenReserves, } = useAppDataContext(); const { walletBalances, loading } = useWalletBalances(currentMarketData); const [displayGho] = useRootStore((store) => [store.displayGho]); @@ -167,9 +168,23 @@ export const SupplyAssetsList = () => { const sortedSupplyReserves = tokensToSupply.sort((a, b) => +a.walletBalanceUSD > +b.walletBalanceUSD ? -1 : 1 ); - const filteredSupplyReserves = sortedSupplyReserves.filter( - (reserve) => reserve.availableToDepositUSD !== '0' - ); + + const filteredSupplyReserves = sortedSupplyReserves.filter((reserve) => { + if (reserve.availableToDepositUSD !== '0') { + return true; + } + + const wrappedTokenConfig = wrappedTokenReserves.find( + (r) => r.tokenOut.underlyingAsset === reserve.underlyingAsset + ); + + if (!wrappedTokenConfig) { + return false; + } + + // The asset can be supplied if the user has a 'token in' balance, (DAI as sDAI for example) + return walletBalances[wrappedTokenConfig.tokenIn.underlyingAsset]?.amount !== '0'; + }); // Filter out reserves const supplyReserves: unknown = isShowZeroAssets diff --git a/src/modules/dashboard/lists/SupplyAssetsList/SupplyAssetsListItem.tsx b/src/modules/dashboard/lists/SupplyAssetsList/SupplyAssetsListItem.tsx index 710295040f..d6d9fbf145 100644 --- a/src/modules/dashboard/lists/SupplyAssetsList/SupplyAssetsListItem.tsx +++ b/src/modules/dashboard/lists/SupplyAssetsList/SupplyAssetsListItem.tsx @@ -1,9 +1,15 @@ import { SwitchHorizontalIcon } from '@heroicons/react/outline'; import { EyeIcon } from '@heroicons/react/solid'; import { Trans } from '@lingui/macro'; -import { Button, ListItemText, Menu, MenuItem, SvgIcon } from '@mui/material'; +import { Box, Button, ListItemText, Menu, MenuItem, Stack, SvgIcon } from '@mui/material'; import { useState } from 'react'; +import { ContentWithTooltip } from 'src/components/ContentWithTooltip'; +import { WrappedTokenTooltipContent } from 'src/components/infoTooltips/WrappedTokenToolTipContent'; +import { FormattedNumber } from 'src/components/primitives/FormattedNumber'; import { NoData } from 'src/components/primitives/NoData'; +import { TokenIcon } from 'src/components/primitives/TokenIcon'; +import { useAppDataContext } from 'src/hooks/app-data-provider/useAppDataProvider'; +import { useWalletBalances } from 'src/hooks/app-data-provider/useWalletBalances'; import { useAssetCaps } from 'src/hooks/useAssetCaps'; import { useModalContext } from 'src/hooks/useModal'; import { useRootStore } from 'src/store/root'; @@ -40,6 +46,9 @@ export const SupplyAssetsListItem = ({ }: DashboardReserve) => { const currentMarketData = useRootStore((store) => store.currentMarketData); const currentMarket = useRootStore((store) => store.currentMarket); + const { wrappedTokenReserves } = useAppDataContext(); + const { walletBalances } = useWalletBalances(currentMarketData); + const { openSupply, openSwitch } = useModalContext(); // Disable the asset to prevent it from being supplied if supply cap has been reached @@ -55,7 +64,20 @@ export const SupplyAssetsListItem = ({ const handleClose = () => { setAnchorEl(null); }; - const disableSupply = !isActive || isFreezed || Number(walletBalance) <= 0 || isMaxCapReached; + + const wrappedToken = wrappedTokenReserves.find( + (r) => r.tokenOut.underlyingAsset === underlyingAsset + ); + + const canSupplyAsWrappedToken = + wrappedToken && + walletBalances[wrappedToken.tokenIn.underlyingAsset.toLowerCase()].amount !== '0'; + + const disableSupply = + !isActive || + isFreezed || + (Number(walletBalance) <= 0 && !canSupplyAsWrappedToken) || + isMaxCapReached; const onDetailsClick = () => { trackEvent(DASHBOARD.DETAILS_NAVIGATION, { @@ -82,21 +104,61 @@ export const SupplyAssetsListItem = ({ currentMarket={currentMarket} showDebtCeilingTooltips > - - } - /> + {canSupplyAsWrappedToken && walletBalance === '0' ? ( + + + } + > + + + + + + + + + + ) : ( + + } + /> + )} diff --git a/src/utils/hfUtils.ts b/src/utils/hfUtils.ts index b2a5852b71..780d828ae2 100644 --- a/src/utils/hfUtils.ts +++ b/src/utils/hfUtils.ts @@ -214,3 +214,39 @@ export const calculateHFAfterWithdraw = ({ return healthFactorAfterWithdraw; }; + +export const calculateHFAfterSupply = ( + user: ExtendedFormattedUser, + poolReserve: ComputedReserveData, + supplyAmountInEth: BigNumber +) => { + let healthFactorAfterDeposit = user ? valueToBigNumber(user.healthFactor) : '-1'; + + const totalCollateralMarketReferenceCurrencyAfter = user + ? valueToBigNumber(user.totalCollateralMarketReferenceCurrency).plus(supplyAmountInEth) + : '-1'; + + const liquidationThresholdAfter = user + ? valueToBigNumber(user.totalCollateralMarketReferenceCurrency) + .multipliedBy(user.currentLiquidationThreshold) + .plus(supplyAmountInEth.multipliedBy(poolReserve.formattedReserveLiquidationThreshold)) + .dividedBy(totalCollateralMarketReferenceCurrencyAfter) + : '-1'; + + if ( + user && + ((!user.isInIsolationMode && !poolReserve.isIsolated) || + (user.isInIsolationMode && + user.isolatedReserve?.underlyingAsset === poolReserve.underlyingAsset)) + ) { + healthFactorAfterDeposit = calculateHealthFactorFromBalancesBigUnits({ + collateralBalanceMarketReferenceCurrency: totalCollateralMarketReferenceCurrencyAfter, + borrowBalanceMarketReferenceCurrency: valueToBigNumber( + user.totalBorrowsMarketReferenceCurrency + ), + currentLiquidationThreshold: liquidationThresholdAfter, + }); + } + + return healthFactorAfterDeposit; +}; From 872550e5e06eb17c92b4c5bdcc8ea33a6809486b Mon Sep 17 00:00:00 2001 From: Mark Grothe Date: Wed, 1 Nov 2023 16:07:19 -0500 Subject: [PATCH 30/46] feat: misc fixes --- src/components/infoTooltips/WrappedTokenToolTipContent.tsx | 4 ++-- .../transactions/Supply/SupplyWrappedTokenActions.tsx | 5 +---- src/locales/en/messages.js | 2 +- src/locales/en/messages.po | 5 ++++- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/components/infoTooltips/WrappedTokenToolTipContent.tsx b/src/components/infoTooltips/WrappedTokenToolTipContent.tsx index b703d6e869..1a9ac28c86 100644 --- a/src/components/infoTooltips/WrappedTokenToolTipContent.tsx +++ b/src/components/infoTooltips/WrappedTokenToolTipContent.tsx @@ -26,8 +26,8 @@ export const WrappedTokenTooltipContent = ({ - DAI balance will be converted via DSR contracts and then supplied as sDAI to Aave reserve. - Switching incurs no additional costs and no slippage. + DAI balance will be converted via DSR contracts and then supplied as sDAI. Switching + incurs no additional costs and no slippage. diff --git a/src/components/transactions/Supply/SupplyWrappedTokenActions.tsx b/src/components/transactions/Supply/SupplyWrappedTokenActions.tsx index 2585c73641..0a62f2e2e1 100644 --- a/src/components/transactions/Supply/SupplyWrappedTokenActions.tsx +++ b/src/components/transactions/Supply/SupplyWrappedTokenActions.tsx @@ -97,9 +97,6 @@ export const SupplyWrappedTokenActions = ({ setGasLimit(supplyGasLimit.toString()); - console.log('loading approved amount', isFetching); - console.log('approved amount', approvedAmount); - if (requiresApproval && approvalTxState?.success) { // There was a successful approval tx, but the approval amount is not enough. // Clear the state to prompt for another approval. @@ -194,7 +191,7 @@ export const SupplyWrappedTokenActions = ({ requiresAmount amount={amountToSupply} symbol={symbol} - preparingTransactions={loadingTxns} + preparingTransactions={loadingTxns || isFetching} actionText={Supply {symbol}} actionInProgressText={Supplying {symbol}} handleApproval={() => approvalAction()} diff --git a/src/locales/en/messages.js b/src/locales/en/messages.js index f079d88ffc..19d820bbcd 100644 --- a/src/locales/en/messages.js +++ b/src/locales/en/messages.js @@ -1 +1 @@ -/*eslint-disable*/module.exports={messages:{"...":"...",".CSV":".CSV",".JSON":".JSON","<0><1><2/>Add <3/> stkAAVE to borrow at <4/> (max discount)":"<0><1><2/>Add <3/> stkAAVE to borrow at <4/> (max discount)","<0><1><2/>Add stkAAVE to see borrow rate with discount":"<0><1><2/>Add stkAAVE to see borrow rate with discount","<0>Ampleforth is a rebasing asset. Visit the <1>documentation to learn more.":"<0>Ampleforth is a rebasing asset. Visit the <1>documentation to learn more.","<0>Attention: Parameter changes via governance can alter your account health factor and risk of liquidation. Follow the <1>Aave governance forum for updates.":"<0>Attention: Parameter changes via governance can alter your account health factor and risk of liquidation. Follow the <1>Aave governance forum for updates.","<0>Slippage tolerance <1>{selectedSlippage}% <2>{0}":["<0>Slippage tolerance <1>",["selectedSlippage"],"% <2>",["0"],""],"AAVE holders (Ethereum network only) can stake their AAVE in the Safety Module to add more security to the protocol and earn Safety Incentives. In the case of a shortfall event, up to 30% of your stake can be slashed to cover the deficit, providing an additional layer of protection for the protocol.":"AAVE holders (Ethereum network only) can stake their AAVE in the Safety Module to add more security to the protocol and earn Safety Incentives. In the case of a shortfall event, up to 30% of your stake can be slashed to cover the deficit, providing an additional layer of protection for the protocol.","APR":"APR","APY":"APY","APY change":"APY change","APY type":"APY type","APY type change":"APY type change","APY with discount applied":"APY with discount applied","APY, fixed rate":"APY, fixed rate","APY, stable":"APY, stable","APY, variable":"APY, variable","AToken supply is not zero":"AToken supply is not zero","Aave Governance":"Aave Governance","Aave aToken":"Aave aToken","Aave debt token":"Aave debt token","Aave is a fully decentralized, community governed protocol by the AAVE token-holders. AAVE token-holders collectively discuss, propose, and vote on upgrades to the protocol. AAVE token-holders (Ethereum network only) can either vote themselves on new proposals or delagate to an address of choice. To learn more check out the Governance":"Aave is a fully decentralized, community governed protocol by the AAVE token-holders. AAVE token-holders collectively discuss, propose, and vote on upgrades to the protocol. AAVE token-holders (Ethereum network only) can either vote themselves on new proposals or delagate to an address of choice. To learn more check out the Governance","Aave per month":"Aave per month","About GHO":"About GHO","Account":"Account","Action cannot be performed because the reserve is frozen":"Action cannot be performed because the reserve is frozen","Action cannot be performed because the reserve is paused":"Action cannot be performed because the reserve is paused","Action requires an active reserve":"Action requires an active reserve","Activate Cooldown":"Activate Cooldown","Add stkAAVE to see borrow APY with the discount":"Add stkAAVE to see borrow APY with the discount","Add to wallet":"Add to wallet","Add {0} to wallet to track your balance.":["Add ",["0"]," to wallet to track your balance."],"Address is not a contract":"Address is not a contract","Addresses":"Addresses","Addresses ({0})":["Addresses (",["0"],")"],"All Assets":"All Assets","All done!":"All done!","All proposals":"All proposals","All transactions":"All transactions","Allowance required action":"Allowance required action","Allows you to decide whether to use a supplied asset as collateral. An asset used as collateral will affect your borrowing power and health factor.":"Allows you to decide whether to use a supplied asset as collateral. An asset used as collateral will affect your borrowing power and health factor.","Allows you to switch between <0>variable and <1>stable interest rates, where variable rate can increase and decrease depending on the amount of liquidity in the reserve, and stable rate will stay the same for the duration of your loan.":"Allows you to switch between <0>variable and <1>stable interest rates, where variable rate can increase and decrease depending on the amount of liquidity in the reserve, and stable rate will stay the same for the duration of your loan.","Amount":"Amount","Amount claimable":"Amount claimable","Amount in cooldown":"Amount in cooldown","Amount must be greater than 0":"Amount must be greater than 0","Amount to unstake":"Amount to unstake","An error has occurred fetching the proposal metadata from IPFS.":"An error has occurred fetching the proposal metadata from IPFS.","Approve Confirmed":"Approve Confirmed","Approve with":"Approve with","Approve {symbol} to continue":["Approve ",["symbol"]," to continue"],"Approving {symbol}...":["Approving ",["symbol"],"..."],"Array parameters that should be equal length are not":"Array parameters that should be equal length are not","Asset":"Asset","Asset can be only used as collateral in isolation mode with limited borrowing power. To enter isolation mode, disable all other collateral.":"Asset can be only used as collateral in isolation mode with limited borrowing power. To enter isolation mode, disable all other collateral.","Asset can only be used as collateral in isolation mode only.":"Asset can only be used as collateral in isolation mode only.","Asset cannot be migrated because you have isolated collateral in {marketName} v3 Market which limits borrowable assets. You can manage your collateral in <0>{marketName} V3 Dashboard":["Asset cannot be migrated because you have isolated collateral in ",["marketName"]," v3 Market which limits borrowable assets. You can manage your collateral in <0>",["marketName"]," V3 Dashboard"],"Asset cannot be migrated due to insufficient liquidity or borrow cap limitation in {marketName} v3 market.":["Asset cannot be migrated due to insufficient liquidity or borrow cap limitation in ",["marketName"]," v3 market."],"Asset cannot be migrated due to supply cap restriction in {marketName} v3 market.":["Asset cannot be migrated due to supply cap restriction in ",["marketName"]," v3 market."],"Asset cannot be migrated to {marketName} V3 Market due to E-mode restrictions. You can disable or manage E-mode categories in your <0>V3 Dashboard":["Asset cannot be migrated to ",["marketName"]," V3 Market due to E-mode restrictions. You can disable or manage E-mode categories in your <0>V3 Dashboard"],"Asset cannot be migrated to {marketName} v3 Market since collateral asset will enable isolation mode.":["Asset cannot be migrated to ",["marketName"]," v3 Market since collateral asset will enable isolation mode."],"Asset cannot be used as collateral.":"Asset cannot be used as collateral.","Asset category":"Asset category","Asset is frozen in {marketName} v3 market, hence this position cannot be migrated.":["Asset is frozen in ",["marketName"]," v3 market, hence this position cannot be migrated."],"Asset is not borrowable in isolation mode":"Asset is not borrowable in isolation mode","Asset is not listed":"Asset is not listed","Asset supply is limited to a certain amount to reduce protocol exposure to the asset and to help manage risks involved.":"Asset supply is limited to a certain amount to reduce protocol exposure to the asset and to help manage risks involved.","Assets":"Assets","Assets to borrow":"Assets to borrow","Assets to supply":"Assets to supply","Assets with zero LTV ({assetsBlockingWithdraw}) must be withdrawn or disabled as collateral to perform this action":["Assets with zero LTV (",["assetsBlockingWithdraw"],") must be withdrawn or disabled as collateral to perform this action"],"At a discount":"At a discount","Author":"Author","Available":"Available","Available assets":"Available assets","Available liquidity":"Available liquidity","Available on":"Available on","Available rewards":"Available rewards","Available to borrow":"Available to borrow","Available to supply":"Available to supply","Back to Dashboard":"Back to Dashboard","Balance":"Balance","Balance to revoke":"Balance to revoke","Be careful - You are very close to liquidation. Consider depositing more collateral or paying down some of your borrowed positions":"Be careful - You are very close to liquidation. Consider depositing more collateral or paying down some of your borrowed positions","Be mindful of the network congestion and gas prices.":"Be mindful of the network congestion and gas prices.","Because this asset is paused, no actions can be taken until further notice":"Because this asset is paused, no actions can be taken until further notice","Before supplying":"Before supplying","Blocked Address":"Blocked Address","Borrow":"Borrow","Borrow APY":"Borrow APY","Borrow APY rate":"Borrow APY rate","Borrow APY, fixed rate":"Borrow APY, fixed rate","Borrow APY, stable":"Borrow APY, stable","Borrow APY, variable":"Borrow APY, variable","Borrow amount to reach {0}% utilization":["Borrow amount to reach ",["0"],"% utilization"],"Borrow and repay in same block is not allowed":"Borrow and repay in same block is not allowed","Borrow apy":"Borrow apy","Borrow balance":"Borrow balance","Borrow balance after repay":"Borrow balance after repay","Borrow balance after switch":"Borrow balance after switch","Borrow cap":"Borrow cap","Borrow cap is exceeded":"Borrow cap is exceeded","Borrow info":"Borrow info","Borrow power used":"Borrow power used","Borrow rate change":"Borrow rate change","Borrow {symbol}":["Borrow ",["symbol"]],"Borrowed":"Borrowed","Borrowed asset amount":"Borrowed asset amount","Borrowing is currently unavailable for {0}.":["Borrowing is currently unavailable for ",["0"],"."],"Borrowing is disabled due to an Aave community decision. <0>More details":"Borrowing is disabled due to an Aave community decision. <0>More details","Borrowing is not enabled":"Borrowing is not enabled","Borrowing is unavailable because you’re using Isolation mode. To manage Isolation mode visit your <0>Dashboard.":"Borrowing is unavailable because you’re using Isolation mode. To manage Isolation mode visit your <0>Dashboard.","Borrowing is unavailable because you’ve enabled Efficiency Mode (E-Mode) and Isolation mode. To manage E-Mode and Isolation mode visit your <0>Dashboard.":"Borrowing is unavailable because you’ve enabled Efficiency Mode (E-Mode) and Isolation mode. To manage E-Mode and Isolation mode visit your <0>Dashboard.","Borrowing is unavailable because you’ve enabled Efficiency Mode (E-Mode) for {0} category. To manage E-Mode categories visit your <0>Dashboard.":["Borrowing is unavailable because you’ve enabled Efficiency Mode (E-Mode) for ",["0"]," category. To manage E-Mode categories visit your <0>Dashboard."],"Borrowing of this asset is limited to a certain amount to minimize liquidity pool insolvency.":"Borrowing of this asset is limited to a certain amount to minimize liquidity pool insolvency.","Borrowing power and assets are limited due to Isolation mode.":"Borrowing power and assets are limited due to Isolation mode.","Borrowing this amount will reduce your health factor and increase risk of liquidation.":"Borrowing this amount will reduce your health factor and increase risk of liquidation.","Borrowing {symbol}":["Borrowing ",["symbol"]],"Both":"Both","Buy Crypto With Fiat":"Buy Crypto With Fiat","Buy Crypto with Fiat":"Buy Crypto with Fiat","Buy {cryptoSymbol} with Fiat":["Buy ",["cryptoSymbol"]," with Fiat"],"COPIED!":"COPIED!","COPY IMAGE":"COPY IMAGE","Can be collateral":"Can be collateral","Can be executed":"Can be executed","Cancel":"Cancel","Cannot disable E-Mode":"Cannot disable E-Mode","Choose how much voting/proposition power to give to someone else by delegating some of your AAVE or stkAAVE balance. Your tokens will remain in your account, but your delegate will be able to vote or propose on your behalf. If your AAVE or stkAAVE balance changes, your delegate's voting/proposition power will be automatically adjusted.":"Choose how much voting/proposition power to give to someone else by delegating some of your AAVE or stkAAVE balance. Your tokens will remain in your account, but your delegate will be able to vote or propose on your behalf. If your AAVE or stkAAVE balance changes, your delegate's voting/proposition power will be automatically adjusted.","Choose one of the on-ramp services":"Choose one of the on-ramp services","Claim":"Claim","Claim all":"Claim all","Claim all rewards":"Claim all rewards","Claim {0}":["Claim ",["0"]],"Claim {symbol}":["Claim ",["symbol"]],"Claimable AAVE":"Claimable AAVE","Claimed":"Claimed","Claiming":"Claiming","Claiming {symbol}":["Claiming ",["symbol"]],"Close":"Close","Collateral":"Collateral","Collateral balance after repay":"Collateral balance after repay","Collateral change":"Collateral change","Collateral is (mostly) the same currency that is being borrowed":"Collateral is (mostly) the same currency that is being borrowed","Collateral to repay with":"Collateral to repay with","Collateral usage":"Collateral usage","Collateral usage is limited because of Isolation mode.":"Collateral usage is limited because of Isolation mode.","Collateral usage is limited because of isolation mode.":"Collateral usage is limited because of isolation mode.","Collateral usage is limited because of isolation mode. <0>Learn More":"Collateral usage is limited because of isolation mode. <0>Learn More","Collateralization":"Collateralization","Collector Contract":"Collector Contract","Collector Info":"Collector Info","Connect wallet":"Connect wallet","Cooldown period":"Cooldown period","Cooldown period warning":"Cooldown period warning","Cooldown time left":"Cooldown time left","Cooldown to unstake":"Cooldown to unstake","Cooling down...":"Cooling down...","Copy address":"Copy address","Copy error message":"Copy error message","Copy error text":"Copy error text","Covered debt":"Covered debt","Created":"Created","Current LTV":"Current LTV","Current differential":"Current differential","Current v2 Balance":"Current v2 Balance","Current v2 balance":"Current v2 balance","Current votes":"Current votes","DAI balance will be converted via DSR contracts and then supplied as sDAI to Aave reserve. Switching incurs no additional costs and no slippage.":"DAI balance will be converted via DSR contracts and then supplied as sDAI to Aave reserve. Switching incurs no additional costs and no slippage.","Dark mode":"Dark mode","Dashboard":"Dashboard","Data couldn't be fetched, please reload graph.":"Data couldn't be fetched, please reload graph.","Debt":"Debt","Debt ceiling is exceeded":"Debt ceiling is exceeded","Debt ceiling is not zero":"Debt ceiling is not zero","Debt ceiling limits the amount possible to borrow against this asset by protocol users. Debt ceiling is specific to assets in isolation mode and is denoted in USD.":"Debt ceiling limits the amount possible to borrow against this asset by protocol users. Debt ceiling is specific to assets in isolation mode and is denoted in USD.","Delegated power":"Delegated power","Details":"Details","Developers":"Developers","Differential":"Differential","Disable E-Mode":"Disable E-Mode","Disable testnet":"Disable testnet","Disable {symbol} as collateral":["Disable ",["symbol"]," as collateral"],"Disabled":"Disabled","Disabling E-Mode":"Disabling E-Mode","Disabling this asset as collateral affects your borrowing power and Health Factor.":"Disabling this asset as collateral affects your borrowing power and Health Factor.","Disconnect Wallet":"Disconnect Wallet","Discord channel":"Discord channel","Discount":"Discount","Discount applied for <0/> staking AAVE":"Discount applied for <0/> staking AAVE","Discount model parameters":"Discount model parameters","Discount parameters are decided by the Aave community and may be changed over time. Check Governance for updates and vote to participate. <0>Learn more":"Discount parameters are decided by the Aave community and may be changed over time. Check Governance for updates and vote to participate. <0>Learn more","Discountable amount":"Discountable amount","Docs":"Docs","Download":"Download","Due to internal stETH mechanics required for rebasing support, it is not possible to perform a collateral switch where stETH is the source token.":"Due to internal stETH mechanics required for rebasing support, it is not possible to perform a collateral switch where stETH is the source token.","Due to the Horizon bridge exploit, certain assets on the Harmony network are not at parity with Ethereum, which affects the Aave V3 Harmony market.":"Due to the Horizon bridge exploit, certain assets on the Harmony network are not at parity with Ethereum, which affects the Aave V3 Harmony market.","E-Mode":"E-Mode","E-Mode Category":"E-Mode Category","E-Mode category":"E-Mode category","E-Mode increases your LTV for a selected category of assets up to 97%. <0>Learn more":"E-Mode increases your LTV for a selected category of assets up to 97%. <0>Learn more","E-Mode increases your LTV for a selected category of assets up to<0/>. <1>Learn more":"E-Mode increases your LTV for a selected category of assets up to<0/>. <1>Learn more","E-Mode increases your LTV for a selected category of assets, meaning that when E-mode is enabled, you will have higher borrowing power over assets of the same E-mode category which are defined by Aave Governance. You can enter E-Mode from your <0>Dashboard. To learn more about E-Mode and applied restrictions in <1>FAQ or <2>Aave V3 Technical Paper.":"E-Mode increases your LTV for a selected category of assets, meaning that when E-mode is enabled, you will have higher borrowing power over assets of the same E-mode category which are defined by Aave Governance. You can enter E-Mode from your <0>Dashboard. To learn more about E-Mode and applied restrictions in <1>FAQ or <2>Aave V3 Technical Paper.","Effective interest rate":"Effective interest rate","Efficiency mode (E-Mode)":"Efficiency mode (E-Mode)","Emode":"Emode","Enable E-Mode":"Enable E-Mode","Enable {symbol} as collateral":["Enable ",["symbol"]," as collateral"],"Enabled":"Enabled","Enabling E-Mode":"Enabling E-Mode","Enabling E-Mode only allows you to borrow assets belonging to the selected category. Please visit our <0>FAQ guide to learn more about how it works and the applied restrictions.":"Enabling E-Mode only allows you to borrow assets belonging to the selected category. Please visit our <0>FAQ guide to learn more about how it works and the applied restrictions.","Enabling this asset as collateral increases your borrowing power and Health Factor. However, it can get liquidated if your health factor drops below 1.":"Enabling this asset as collateral increases your borrowing power and Health Factor. However, it can get liquidated if your health factor drops below 1.","Ended":"Ended","Ends":"Ends","English":"English","Enter ETH address":"Enter ETH address","Enter an amount":"Enter an amount","Error connecting. Try refreshing the page.":"Error connecting. Try refreshing the page.","Estimated compounding interest, including discount for Staking {0}AAVE in Safety Module.":["Estimated compounding interest, including discount for Staking ",["0"],"AAVE in Safety Module."],"Exceeds the discount":"Exceeds the discount","Exchange rate":"Exchange rate","Executed":"Executed","Expected amount to repay":"Expected amount to repay","Expires":"Expires","Export data to":"Export data to","FAQ":"FAQ","FAQS":"FAQS","Failed to load proposal voters. Please refresh the page.":"Failed to load proposal voters. Please refresh the page.","Faucet":"Faucet","Faucet {0}":["Faucet ",["0"]],"Fetching data...":"Fetching data...","Filter":"Filter","Fixed":"Fixed","Fixed rate":"Fixed rate","Flashloan is disabled for this asset, hence this position cannot be migrated.":"Flashloan is disabled for this asset, hence this position cannot be migrated.","For repayment of a specific type of debt, the user needs to have debt that type":"For repayment of a specific type of debt, the user needs to have debt that type","Forum discussion":"Forum discussion","French":"French","Funds in the Safety Module":"Funds in the Safety Module","GHO is a native decentralized, collateral-backed digital asset pegged to USD. It is created by users via borrowing against multiple collateral. When user repays their GHO borrow position, the protocol burns that user's GHO. All the interest payments accrued by minters of GHO would be directly transferred to the AaveDAO treasury.":"GHO is a native decentralized, collateral-backed digital asset pegged to USD. It is created by users via borrowing against multiple collateral. When user repays their GHO borrow position, the protocol burns that user's GHO. All the interest payments accrued by minters of GHO would be directly transferred to the AaveDAO treasury.","Get ABP Token":"Get ABP Token","Global settings":"Global settings","Go Back":"Go Back","Go to Balancer Pool":"Go to Balancer Pool","Go to V3 Dashboard":"Go to V3 Dashboard","Governance":"Governance","Greek":"Greek","Health Factor ({0} v2)":["Health Factor (",["0"]," v2)"],"Health Factor ({0} v3)":["Health Factor (",["0"]," v3)"],"Health factor":"Health factor","Health factor is lesser than the liquidation threshold":"Health factor is lesser than the liquidation threshold","Health factor is not below the threshold":"Health factor is not below the threshold","Hide":"Hide","Holders of stkAAVE receive a discount on the GHO borrowing rate":"Holders of stkAAVE receive a discount on the GHO borrowing rate","I acknowledge the risks involved.":"I acknowledge the risks involved.","I fully understand the risks of migrating.":"I fully understand the risks of migrating.","I understand how cooldown ({0}) and unstaking ({1}) work":["I understand how cooldown (",["0"],") and unstaking (",["1"],") work"],"If the error continues to happen,<0/> you may report it to this":"If the error continues to happen,<0/> you may report it to this","If the health factor goes below 1, the liquidation of your collateral might be triggered.":"If the health factor goes below 1, the liquidation of your collateral might be triggered.","If you DO NOT unstake within {0} of unstake window, you will need to activate cooldown process again.":["If you DO NOT unstake within ",["0"]," of unstake window, you will need to activate cooldown process again."],"If your loan to value goes above the liquidation threshold your collateral supplied may be liquidated.":"If your loan to value goes above the liquidation threshold your collateral supplied may be liquidated.","In E-Mode some assets are not borrowable. Exit E-Mode to get access to all assets":"In E-Mode some assets are not borrowable. Exit E-Mode to get access to all assets","In Isolation mode, you cannot supply other assets as collateral. A global debt ceiling limits the borrowing power of the isolated asset. To exit isolation mode disable {0} as collateral before borrowing another asset. Read more in our <0>FAQ":["In Isolation mode, you cannot supply other assets as collateral. A global debt ceiling limits the borrowing power of the isolated asset. To exit isolation mode disable ",["0"]," as collateral before borrowing another asset. Read more in our <0>FAQ"],"Inconsistent flashloan parameters":"Inconsistent flashloan parameters","Insufficient collateral to cover new borrow position. Wallet must have borrowing power remaining to perform debt switch.":"Insufficient collateral to cover new borrow position. Wallet must have borrowing power remaining to perform debt switch.","Interest accrued":"Interest accrued","Interest rate rebalance conditions were not met":"Interest rate rebalance conditions were not met","Interest rate strategy":"Interest rate strategy","Invalid amount to burn":"Invalid amount to burn","Invalid amount to mint":"Invalid amount to mint","Invalid bridge protocol fee":"Invalid bridge protocol fee","Invalid expiration":"Invalid expiration","Invalid flashloan premium":"Invalid flashloan premium","Invalid return value of the flashloan executor function":"Invalid return value of the flashloan executor function","Invalid signature":"Invalid signature","Isolated":"Isolated","Isolated Debt Ceiling":"Isolated Debt Ceiling","Isolated assets have limited borrowing power and other assets cannot be used as collateral.":"Isolated assets have limited borrowing power and other assets cannot be used as collateral.","Join the community discussion":"Join the community discussion","LEARN MORE":"LEARN MORE","Language":"Language","Learn more":"Learn more","Learn more about risks involved":"Learn more about risks involved","Learn more in our <0>FAQ guide":"Learn more in our <0>FAQ guide","Learn more.":"Learn more.","Links":"Links","Liqudation":"Liqudation","Liquidated collateral":"Liquidated collateral","Liquidation":"Liquidation","Liquidation <0/> threshold":"Liquidation <0/> threshold","Liquidation Threshold":"Liquidation Threshold","Liquidation at":"Liquidation at","Liquidation penalty":"Liquidation penalty","Liquidation risk":"Liquidation risk","Liquidation risk parameters":"Liquidation risk parameters","Liquidation threshold":"Liquidation threshold","Liquidation value":"Liquidation value","Loading data...":"Loading data...","Ltv validation failed":"Ltv validation failed","MAI has been paused due to a community decision. Supply, borrows and repays are impacted. <0>More details":"MAI has been paused due to a community decision. Supply, borrows and repays are impacted. <0>More details","MAX":"MAX","Manage analytics":"Manage analytics","Market":"Market","Markets":"Markets","Max":"Max","Max LTV":"Max LTV","Max slashing":"Max slashing","Max slippage":"Max slippage","Maximum amount available to borrow against this asset is limited because debt ceiling is at {0}%.":["Maximum amount available to borrow against this asset is limited because debt ceiling is at ",["0"],"%."],"Maximum amount available to borrow is <0/> {0} (<1/>).":["Maximum amount available to borrow is <0/> ",["0"]," (<1/>)."],"Maximum amount available to borrow is limited because protocol borrow cap is nearly reached.":"Maximum amount available to borrow is limited because protocol borrow cap is nearly reached.","Maximum amount available to supply is <0/> {0} (<1/>).":["Maximum amount available to supply is <0/> ",["0"]," (<1/>)."],"Maximum amount available to supply is limited because protocol supply cap is at {0}%.":["Maximum amount available to supply is limited because protocol supply cap is at ",["0"],"%."],"Maximum loan to value":"Maximum loan to value","Meet GHO":"Meet GHO","Menu":"Menu","Migrate":"Migrate","Migrate to V3":"Migrate to V3","Migrate to v3":"Migrate to v3","Migrate to {0} v3 Market":["Migrate to ",["0"]," v3 Market"],"Migrated":"Migrated","Migrating":"Migrating","Migrating multiple collaterals and borrowed assets at the same time can be an expensive operation and might fail in certain situations.<0>Therefore it’s not recommended to migrate positions with more than 5 assets (deposited + borrowed) at the same time.":"Migrating multiple collaterals and borrowed assets at the same time can be an expensive operation and might fail in certain situations.<0>Therefore it’s not recommended to migrate positions with more than 5 assets (deposited + borrowed) at the same time.","Migration risks":"Migration risks","Minimum GHO borrow amount":"Minimum GHO borrow amount","Minimum USD value received":"Minimum USD value received","Minimum staked Aave amount":"Minimum staked Aave amount","Minimum {0} received":["Minimum ",["0"]," received"],"More":"More","NAY":"NAY","Need help connecting a wallet? <0>Read our FAQ":"Need help connecting a wallet? <0>Read our FAQ","Net APR":"Net APR","Net APY":"Net APY","Net APY is the combined effect of all supply and borrow positions on net worth, including incentives. It is possible to have a negative net APY if debt APY is higher than supply APY.":"Net APY is the combined effect of all supply and borrow positions on net worth, including incentives. It is possible to have a negative net APY if debt APY is higher than supply APY.","Net worth":"Net worth","Network":"Network","Network not supported for this wallet":"Network not supported for this wallet","New APY":"New APY","No assets selected to migrate.":"No assets selected to migrate.","No rewards to claim":"No rewards to claim","No search results{0}":["No search results",["0"]],"No transactions yet.":"No transactions yet.","No voting power":"No voting power","None":"None","Not a valid address":"Not a valid address","Not enough balance on your wallet":"Not enough balance on your wallet","Not enough collateral to repay this amount of debt with":"Not enough collateral to repay this amount of debt with","Not enough staked balance":"Not enough staked balance","Not enough voting power to participate in this proposal":"Not enough voting power to participate in this proposal","Not reached":"Not reached","Nothing borrowed yet":"Nothing borrowed yet","Nothing found":"Nothing found","Nothing staked":"Nothing staked","Nothing supplied yet":"Nothing supplied yet","Notify":"Notify","Ok, Close":"Ok, Close","Ok, I got it":"Ok, I got it","Operation not supported":"Operation not supported","Oracle price":"Oracle price","Overview":"Overview","Page not found":"Page not found","Participating in this {symbol} reserve gives annualized rewards.":["Participating in this ",["symbol"]," reserve gives annualized rewards."],"Pending...":"Pending...","Per the community, the Fantom market has been frozen.":"Per the community, the Fantom market has been frozen.","Per the community, the V2 AMM market has been deprecated.":"Per the community, the V2 AMM market has been deprecated.","Please always be aware of your <0>Health Factor (HF) when partially migrating a position and that your rates will be updated to V3 rates.":"Please always be aware of your <0>Health Factor (HF) when partially migrating a position and that your rates will be updated to V3 rates.","Please connect a wallet to view your personal information here.":"Please connect a wallet to view your personal information here.","Please connect your wallet to be able to switch your tokens.":"Please connect your wallet to be able to switch your tokens.","Please connect your wallet to get free testnet assets.":"Please connect your wallet to get free testnet assets.","Please connect your wallet to see migration tool.":"Please connect your wallet to see migration tool.","Please connect your wallet to see your supplies, borrowings, and open positions.":"Please connect your wallet to see your supplies, borrowings, and open positions.","Please connect your wallet to view transaction history.":"Please connect your wallet to view transaction history.","Please enter a valid wallet address.":"Please enter a valid wallet address.","Please switch to {networkName}.":["Please switch to ",["networkName"],"."],"Please, connect your wallet":"Please, connect your wallet","Pool addresses provider is not registered":"Pool addresses provider is not registered","Powered by":"Powered by","Preview tx and migrate":"Preview tx and migrate","Price":"Price","Price data is not currently available for this reserve on the protocol subgraph":"Price data is not currently available for this reserve on the protocol subgraph","Price impact":"Price impact","Price impact is the spread between the total value of the entry tokens switched and the destination tokens obtained (in USD), which results from the limited liquidity of the trading pair.":"Price impact is the spread between the total value of the entry tokens switched and the destination tokens obtained (in USD), which results from the limited liquidity of the trading pair.","Price impact {0}%":["Price impact ",["0"],"%"],"Privacy":"Privacy","Proposal details":"Proposal details","Proposal overview":"Proposal overview","Proposals":"Proposals","Proposition":"Proposition","Protocol borrow cap at 100% for this asset. Further borrowing unavailable.":"Protocol borrow cap at 100% for this asset. Further borrowing unavailable.","Protocol borrow cap is at 100% for this asset. Further borrowing unavailable.":"Protocol borrow cap is at 100% for this asset. Further borrowing unavailable.","Protocol debt ceiling is at 100% for this asset. Further borrowing against this asset is unavailable.":"Protocol debt ceiling is at 100% for this asset. Further borrowing against this asset is unavailable.","Protocol debt ceiling is at 100% for this asset. Futher borrowing against this asset is unavailable.":"Protocol debt ceiling is at 100% for this asset. Futher borrowing against this asset is unavailable.","Protocol supply cap at 100% for this asset. Further supply unavailable.":"Protocol supply cap at 100% for this asset. Further supply unavailable.","Protocol supply cap is at 100% for this asset. Further supply unavailable.":"Protocol supply cap is at 100% for this asset. Further supply unavailable.","Quorum":"Quorum","Rate change":"Rate change","Raw-Ipfs":"Raw-Ipfs","Reached":"Reached","Reactivate cooldown period to unstake {0} {stakedToken}":["Reactivate cooldown period to unstake ",["0"]," ",["stakedToken"]],"Read more here.":"Read more here.","Read-only mode allows to see address positions in Aave, but you won't be able to perform transactions.":"Read-only mode allows to see address positions in Aave, but you won't be able to perform transactions.","Read-only mode.":"Read-only mode.","Read-only mode. Connect to a wallet to perform transactions.":"Read-only mode. Connect to a wallet to perform transactions.","Receive (est.)":"Receive (est.)","Received":"Received","Recipient address":"Recipient address","Rejected connection request":"Rejected connection request","Reload":"Reload","Reload the page":"Reload the page","Remaining debt":"Remaining debt","Remaining supply":"Remaining supply","Repaid":"Repaid","Repay":"Repay","Repay with":"Repay with","Repay {symbol}":["Repay ",["symbol"]],"Repaying {symbol}":["Repaying ",["symbol"]],"Repayment amount to reach {0}% utilization":["Repayment amount to reach ",["0"],"% utilization"],"Reserve Size":"Reserve Size","Reserve factor":"Reserve factor","Reserve factor is a percentage of interest which goes to a {0} that is controlled by Aave governance to promote ecosystem growth.":["Reserve factor is a percentage of interest which goes to a ",["0"]," that is controlled by Aave governance to promote ecosystem growth."],"Reserve status & configuration":"Reserve status & configuration","Reset":"Reset","Restake":"Restake","Restake {symbol}":["Restake ",["symbol"]],"Restaked":"Restaked","Restaking {symbol}":["Restaking ",["symbol"]],"Review approval tx details":"Review approval tx details","Review changes to continue":"Review changes to continue","Review tx":"Review tx","Review tx details":"Review tx details","Revoke power":"Revoke power","Reward(s) to claim":"Reward(s) to claim","Rewards APR":"Rewards APR","Risk details":"Risk details","SEE CHARTS":"SEE CHARTS","Safety of your deposited collateral against the borrowed assets and its underlying value.":"Safety of your deposited collateral against the borrowed assets and its underlying value.","Save and share":"Save and share","Seatbelt report":"Seatbelt report","Seems like we can't switch the network automatically. Please check if you can change it from the wallet.":"Seems like we can't switch the network automatically. Please check if you can change it from the wallet.","Select":"Select","Select APY type to switch":"Select APY type to switch","Select an asset":"Select an asset","Select language":"Select language","Select slippage tolerance":"Select slippage tolerance","Select v2 borrows to migrate":"Select v2 borrows to migrate","Select v2 supplies to migrate":"Select v2 supplies to migrate","Selected assets have successfully migrated. Visit the Market Dashboard to see them.":"Selected assets have successfully migrated. Visit the Market Dashboard to see them.","Selected borrow assets":"Selected borrow assets","Selected supply assets":"Selected supply assets","Send feedback":"Send feedback","Set up delegation":"Set up delegation","Setup notifications about your Health Factor using the Hal app.":"Setup notifications about your Health Factor using the Hal app.","Share on Lens":"Share on Lens","Share on twitter":"Share on twitter","Show":"Show","Show Frozen or paused assets":"Show Frozen or paused assets","Show assets with 0 balance":"Show assets with 0 balance","Sign to continue":"Sign to continue","Signatures ready":"Signatures ready","Signing":"Signing","Since this asset is frozen, the only available actions are withdraw and repay which can be accessed from the <0>Dashboard":"Since this asset is frozen, the only available actions are withdraw and repay which can be accessed from the <0>Dashboard","Since this is a test network, you can get any of the assets if you have ETH on your wallet":"Since this is a test network, you can get any of the assets if you have ETH on your wallet","Slippage":"Slippage","Slippage is the difference between the quoted and received amounts from changing market conditions between the moment the transaction is submitted and its verification.":"Slippage is the difference between the quoted and received amounts from changing market conditions between the moment the transaction is submitted and its verification.","Some migrated assets will not be used as collateral due to enabled isolation mode in {marketName} V3 Market. Visit <0>{marketName} V3 Dashboard to manage isolation mode.":["Some migrated assets will not be used as collateral due to enabled isolation mode in ",["marketName"]," V3 Market. Visit <0>",["marketName"]," V3 Dashboard to manage isolation mode."],"Something went wrong":"Something went wrong","Sorry, an unexpected error happened. In the meantime you may try reloading the page, or come back later.":"Sorry, an unexpected error happened. In the meantime you may try reloading the page, or come back later.","Sorry, we couldn't find the page you were looking for.":"Sorry, we couldn't find the page you were looking for.","Spanish":"Spanish","Stable":"Stable","Stable Interest Type is disabled for this currency":"Stable Interest Type is disabled for this currency","Stable borrowing is enabled":"Stable borrowing is enabled","Stable borrowing is not enabled":"Stable borrowing is not enabled","Stable debt supply is not zero":"Stable debt supply is not zero","Stable interest rate will <0>stay the same for the duration of your loan. Recommended for long-term loan periods and for users who prefer predictability.":"Stable interest rate will <0>stay the same for the duration of your loan. Recommended for long-term loan periods and for users who prefer predictability.","Stablecoin":"Stablecoin","Stake":"Stake","Stake AAVE":"Stake AAVE","Stake ABPT":"Stake ABPT","Stake cooldown activated":"Stake cooldown activated","Staked":"Staked","Staking":"Staking","Staking APR":"Staking APR","Staking Rewards":"Staking Rewards","Staking balance":"Staking balance","Staking discount":"Staking discount","Started":"Started","State":"State","Static interest rate that is determined by Aave Governance. This rate may be changed over time depending on the need for the GHO supply to contract/expand. <0>Learn more":"Static interest rate that is determined by Aave Governance. This rate may be changed over time depending on the need for the GHO supply to contract/expand. <0>Learn more","Supplied":"Supplied","Supplied asset amount":"Supplied asset amount","Supply":"Supply","Supply APY":"Supply APY","Supply apy":"Supply apy","Supply balance":"Supply balance","Supply balance after switch":"Supply balance after switch","Supply cap is exceeded":"Supply cap is exceeded","Supply cap on target reserve reached. Try lowering the amount.":"Supply cap on target reserve reached. Try lowering the amount.","Supply {symbol}":["Supply ",["symbol"]],"Supplying your":"Supplying your","Supplying {symbol}":["Supplying ",["symbol"]],"Switch":"Switch","Switch APY type":"Switch APY type","Switch E-Mode":"Switch E-Mode","Switch E-Mode category":"Switch E-Mode category","Switch Network":"Switch Network","Switch borrow position":"Switch borrow position","Switch rate":"Switch rate","Switch to":"Switch to","Switched":"Switched","Switching":"Switching","Switching E-Mode":"Switching E-Mode","Switching rate":"Switching rate","Techpaper":"Techpaper","Terms":"Terms","Test Assets":"Test Assets","Testnet mode":"Testnet mode","Testnet mode is ON":"Testnet mode is ON","Thank you for voting!!":"Thank you for voting!!","The % of your total borrowing power used. This is based on the amount of your collateral supplied and the total amount that you can borrow.":"The % of your total borrowing power used. This is based on the amount of your collateral supplied and the total amount that you can borrow.","The Aave Balancer Pool Token (ABPT) is a liquidity pool token. You can receive ABPT by depositing a combination of AAVE + ETH in the Balancer liquidity pool. You can then stake your BPT in the Safety Module to secure the protocol and earn Safety Incentives.":"The Aave Balancer Pool Token (ABPT) is a liquidity pool token. You can receive ABPT by depositing a combination of AAVE + ETH in the Balancer liquidity pool. You can then stake your BPT in the Safety Module to secure the protocol and earn Safety Incentives.","The Aave Protocol is programmed to always use the price of 1 GHO = $1. This is different from using market pricing via oracles for other crypto assets. This creates stabilizing arbitrage opportunities when the price of GHO fluctuates.":"The Aave Protocol is programmed to always use the price of 1 GHO = $1. This is different from using market pricing via oracles for other crypto assets. This creates stabilizing arbitrage opportunities when the price of GHO fluctuates.","The Maximum LTV ratio represents the maximum borrowing power of a specific collateral. For example, if a collateral has an LTV of 75%, the user can borrow up to 0.75 worth of ETH in the principal currency for every 1 ETH worth of collateral.":"The Maximum LTV ratio represents the maximum borrowing power of a specific collateral. For example, if a collateral has an LTV of 75%, the user can borrow up to 0.75 worth of ETH in the principal currency for every 1 ETH worth of collateral.","The Stable Rate is not enabled for this currency":"The Stable Rate is not enabled for this currency","The address of the pool addresses provider is invalid":"The address of the pool addresses provider is invalid","The app is running in testnet mode. Learn how it works in":"The app is running in testnet mode. Learn how it works in","The caller of the function is not an AToken":"The caller of the function is not an AToken","The caller of this function must be a pool":"The caller of this function must be a pool","The collateral balance is 0":"The collateral balance is 0","The collateral chosen cannot be liquidated":"The collateral chosen cannot be liquidated","The cooldown period is the time required prior to unstaking your tokens (20 days). You can only withdraw your assets from the Security Module after the cooldown period and within the unstake window.<0>Learn more":"The cooldown period is the time required prior to unstaking your tokens (20 days). You can only withdraw your assets from the Security Module after the cooldown period and within the unstake window.<0>Learn more","The cooldown period is {0}. After {1} of cooldown, you will enter unstake window of {2}. You will continue receiving rewards during cooldown and unstake window.":["The cooldown period is ",["0"],". After ",["1"]," of cooldown, you will enter unstake window of ",["2"],". You will continue receiving rewards during cooldown and unstake window."],"The effects on the health factor would cause liquidation. Try lowering the amount.":"The effects on the health factor would cause liquidation. Try lowering the amount.","The loan to value of the migrated positions would cause liquidation. Increase migrated collateral or reduce migrated borrow to continue.":"The loan to value of the migrated positions would cause liquidation. Increase migrated collateral or reduce migrated borrow to continue.","The requested amount is greater than the max loan size in stable rate mode":"The requested amount is greater than the max loan size in stable rate mode","The total amount of your assets denominated in USD that can be used as collateral for borrowing assets.":"The total amount of your assets denominated in USD that can be used as collateral for borrowing assets.","The underlying asset cannot be rescued":"The underlying asset cannot be rescued","The underlying balance needs to be greater than 0":"The underlying balance needs to be greater than 0","The weighted average of APY for all borrowed assets, including incentives.":"The weighted average of APY for all borrowed assets, including incentives.","The weighted average of APY for all supplied assets, including incentives.":"The weighted average of APY for all supplied assets, including incentives.","There are not enough funds in the{0}reserve to borrow":["There are not enough funds in the",["0"],"reserve to borrow"],"There is not enough collateral to cover a new borrow":"There is not enough collateral to cover a new borrow","There is not enough liquidity for the target asset to perform the switch. Try lowering the amount.":"There is not enough liquidity for the target asset to perform the switch. Try lowering the amount.","There was some error. Please try changing the parameters or <0><1>copy the error":"There was some error. Please try changing the parameters or <0><1>copy the error","These assets are temporarily frozen or paused by Aave community decisions, meaning that further supply / borrow, or rate swap of these assets are unavailable. Withdrawals and debt repayments are allowed. Follow the <0>Aave governance forum for further updates.":"These assets are temporarily frozen or paused by Aave community decisions, meaning that further supply / borrow, or rate swap of these assets are unavailable. Withdrawals and debt repayments are allowed. Follow the <0>Aave governance forum for further updates.","These funds have been borrowed and are not available for withdrawal at this time.":"These funds have been borrowed and are not available for withdrawal at this time.","This action will reduce V2 health factor below liquidation threshold. retain collateral or migrate borrow position to continue.":"This action will reduce V2 health factor below liquidation threshold. retain collateral or migrate borrow position to continue.","This action will reduce health factor of V3 below liquidation threshold. Increase migrated collateral or reduce migrated borrow to continue.":"This action will reduce health factor of V3 below liquidation threshold. Increase migrated collateral or reduce migrated borrow to continue.","This action will reduce your health factor. Please be mindful of the increased risk of collateral liquidation.":"This action will reduce your health factor. Please be mindful of the increased risk of collateral liquidation.","This address is blocked on app.aave.com because it is associated with one or more":"This address is blocked on app.aave.com because it is associated with one or more","This asset has almost reached its borrow cap. There is only {messageValue} available to be borrowed from this market.":["This asset has almost reached its borrow cap. There is only ",["messageValue"]," available to be borrowed from this market."],"This asset has almost reached its supply cap. There can only be {messageValue} supplied to this market.":["This asset has almost reached its supply cap. There can only be ",["messageValue"]," supplied to this market."],"This asset has reached its borrow cap. Nothing is available to be borrowed from this market.":"This asset has reached its borrow cap. Nothing is available to be borrowed from this market.","This asset has reached its supply cap. Nothing is available to be supplied from this market.":"This asset has reached its supply cap. Nothing is available to be supplied from this market.","This asset is frozen due to an Aave Protocol Governance decision. <0>More details":"This asset is frozen due to an Aave Protocol Governance decision. <0>More details","This asset is frozen due to an Aave Protocol Governance decision. On the 20th of December 2022, renFIL will no longer be supported and cannot be bridged back to its native network. It is recommended to withdraw supply positions and repay borrow positions so that renFIL can be bridged back to FIL before the deadline. After this date, it will no longer be possible to convert renFIL to FIL. <0>More details":"This asset is frozen due to an Aave Protocol Governance decision. On the 20th of December 2022, renFIL will no longer be supported and cannot be bridged back to its native network. It is recommended to withdraw supply positions and repay borrow positions so that renFIL can be bridged back to FIL before the deadline. After this date, it will no longer be possible to convert renFIL to FIL. <0>More details","This asset is frozen due to an Aave community decision. <0>More details":"This asset is frozen due to an Aave community decision. <0>More details","This asset is planned to be offboarded due to an Aave Protocol Governance decision. <0>More details":"This asset is planned to be offboarded due to an Aave Protocol Governance decision. <0>More details","This gas calculation is only an estimation. Your wallet will set the price of the transaction. You can modify the gas settings directly from your wallet provider.":"This gas calculation is only an estimation. Your wallet will set the price of the transaction. You can modify the gas settings directly from your wallet provider.","This integration was<0>proposed and approvedby the community.":"This integration was<0>proposed and approvedby the community.","This is the total amount available for you to borrow. You can borrow based on your collateral and until the borrow cap is reached.":"This is the total amount available for you to borrow. You can borrow based on your collateral and until the borrow cap is reached.","This is the total amount that you are able to supply to in this reserve. You are able to supply your wallet balance up until the supply cap is reached.":"This is the total amount that you are able to supply to in this reserve. You are able to supply your wallet balance up until the supply cap is reached.","This represents the threshold at which a borrow position will be considered undercollateralized and subject to liquidation for each collateral. For example, if a collateral has a liquidation threshold of 80%, it means that the position will be liquidated when the debt value is worth 80% of the collateral value.":"This represents the threshold at which a borrow position will be considered undercollateralized and subject to liquidation for each collateral. For example, if a collateral has a liquidation threshold of 80%, it means that the position will be liquidated when the debt value is worth 80% of the collateral value.","Time left to be able to withdraw your staked asset.":"Time left to be able to withdraw your staked asset.","Time left to unstake":"Time left to unstake","Time left until the withdrawal window closes.":"Time left until the withdrawal window closes.","Tip: Try increasing slippage or reduce input amount":"Tip: Try increasing slippage or reduce input amount","To borrow you need to supply any asset to be used as collateral.":"To borrow you need to supply any asset to be used as collateral.","To continue, you need to grant Aave smart contracts permission to move your funds from your wallet. Depending on the asset and wallet you use, it is done by signing the permission message (gas free), or by submitting an approval transaction (requires gas). <0>Learn more":"To continue, you need to grant Aave smart contracts permission to move your funds from your wallet. Depending on the asset and wallet you use, it is done by signing the permission message (gas free), or by submitting an approval transaction (requires gas). <0>Learn more","To enable E-mode for the {0} category, all borrow positions outside of this category must be closed.":["To enable E-mode for the ",["0"]," category, all borrow positions outside of this category must be closed."],"To repay on behalf of a user an explicit amount to repay is needed":"To repay on behalf of a user an explicit amount to repay is needed","To request access for this permissioned market, please visit: <0>Acces Provider Name":"To request access for this permissioned market, please visit: <0>Acces Provider Name","To submit a proposal for minor changes to the protocol, you'll need at least 80.00K power. If you want to change the core code base, you'll need 320k power.<0>Learn more.":"To submit a proposal for minor changes to the protocol, you'll need at least 80.00K power. If you want to change the core code base, you'll need 320k power.<0>Learn more.","Top 10 addresses":"Top 10 addresses","Total available":"Total available","Total borrowed":"Total borrowed","Total borrows":"Total borrows","Total emission per day":"Total emission per day","Total interest accrued":"Total interest accrued","Total market size":"Total market size","Total supplied":"Total supplied","Total voting power":"Total voting power","Total worth":"Total worth","Track wallet":"Track wallet","Track wallet balance in read-only mode":"Track wallet balance in read-only mode","Transaction failed":"Transaction failed","Transaction history":"Transaction history","Transaction history is not currently available for this market":"Transaction history is not currently available for this market","Transaction overview":"Transaction overview","Transactions":"Transactions","UNSTAKE {symbol}":["UNSTAKE ",["symbol"]],"Unavailable":"Unavailable","Unbacked":"Unbacked","Unbacked mint cap is exceeded":"Unbacked mint cap is exceeded","Underlying asset does not exist in {marketName} v3 Market, hence this position cannot be migrated.":["Underlying asset does not exist in ",["marketName"]," v3 Market, hence this position cannot be migrated."],"Underlying token":"Underlying token","Unstake now":"Unstake now","Unstake window":"Unstake window","Unstaked":"Unstaked","Unstaking {symbol}":["Unstaking ",["symbol"]],"Update: Disruptions reported for WETH, WBTC, WMATIC, and USDT. AIP 230 will resolve the disruptions and the market will be operating as normal on ~26th May 13h00 UTC.":"Update: Disruptions reported for WETH, WBTC, WMATIC, and USDT. AIP 230 will resolve the disruptions and the market will be operating as normal on ~26th May 13h00 UTC.","Use it to vote for or against active proposals.":"Use it to vote for or against active proposals.","Use your AAVE and stkAAVE balance to delegate your voting and proposition powers. You will not be sending any tokens, only the rights to vote and propose changes to the protocol. You can re-delegate or revoke power to self at any time.":"Use your AAVE and stkAAVE balance to delegate your voting and proposition powers. You will not be sending any tokens, only the rights to vote and propose changes to the protocol. You can re-delegate or revoke power to self at any time.","Used as collateral":"Used as collateral","User cannot withdraw more than the available balance":"User cannot withdraw more than the available balance","User did not borrow the specified currency":"User did not borrow the specified currency","User does not have outstanding stable rate debt on this reserve":"User does not have outstanding stable rate debt on this reserve","User does not have outstanding variable rate debt on this reserve":"User does not have outstanding variable rate debt on this reserve","User is in isolation mode":"User is in isolation mode","User is trying to borrow multiple assets including a siloed one":"User is trying to borrow multiple assets including a siloed one","Users who stake AAVE in Safety Module (i.e. stkAAVE holders) receive a discount on GHO borrow interest rate. The discount applies to 100 GHO for every 1 stkAAVE held. Use the calculator below to see GHO borrow rate with the discount applied.":"Users who stake AAVE in Safety Module (i.e. stkAAVE holders) receive a discount on GHO borrow interest rate. The discount applies to 100 GHO for every 1 stkAAVE held. Use the calculator below to see GHO borrow rate with the discount applied.","Utilization Rate":"Utilization Rate","VIEW TX":"VIEW TX","VOTE NAY":"VOTE NAY","VOTE YAE":"VOTE YAE","Variable":"Variable","Variable debt supply is not zero":"Variable debt supply is not zero","Variable interest rate will <0>fluctuate based on the market conditions. Recommended for short-term positions.":"Variable interest rate will <0>fluctuate based on the market conditions. Recommended for short-term positions.","Variable rate":"Variable rate","Version 2":"Version 2","Version 3":"Version 3","View":"View","View Transactions":"View Transactions","View all votes":"View all votes","View contract":"View contract","View details":"View details","View on Explorer":"View on Explorer","Vote NAY":"Vote NAY","Vote YAE":"Vote YAE","Voted NAY":"Voted NAY","Voted YAE":"Voted YAE","Votes":"Votes","Voting":"Voting","Voting power":"Voting power","Voting results":"Voting results","Wallet Balance":"Wallet Balance","Wallet balance":"Wallet balance","Wallet not detected. Connect or install wallet and retry":"Wallet not detected. Connect or install wallet and retry","Wallets are provided by External Providers and by selecting you agree to Terms of those Providers. Your access to the wallet might be reliant on the External Provider being operational.":"Wallets are provided by External Providers and by selecting you agree to Terms of those Providers. Your access to the wallet might be reliant on the External Provider being operational.","We couldn't find any assets related to your search. Try again with a different asset name, symbol, or address.":"We couldn't find any assets related to your search. Try again with a different asset name, symbol, or address.","We couldn't find any transactions related to your search. Try again with a different asset name, or reset filters.":"We couldn't find any transactions related to your search. Try again with a different asset name, or reset filters.","We couldn’t detect a wallet. Connect a wallet to stake and view your balance.":"We couldn’t detect a wallet. Connect a wallet to stake and view your balance.","We suggest you go back to the Dashboard.":"We suggest you go back to the Dashboard.","Website":"Website","When a liquidation occurs, liquidators repay up to 50% of the outstanding borrowed amount on behalf of the borrower. In return, they can buy the collateral at a discount and keep the difference (liquidation penalty) as a bonus.":"When a liquidation occurs, liquidators repay up to 50% of the outstanding borrowed amount on behalf of the borrower. In return, they can buy the collateral at a discount and keep the difference (liquidation penalty) as a bonus.","With a voting power of <0/>":"With a voting power of <0/>","With testnet Faucet you can get free assets to test the Aave Protocol. Make sure to switch your wallet provider to the appropriate testnet network, select desired asset, and click ‘Faucet’ to get tokens transferred to your wallet. The assets on a testnet are not “real,” meaning they have no monetary value. <0>Learn more":"With testnet Faucet you can get free assets to test the Aave Protocol. Make sure to switch your wallet provider to the appropriate testnet network, select desired asset, and click ‘Faucet’ to get tokens transferred to your wallet. The assets on a testnet are not “real,” meaning they have no monetary value. <0>Learn more","Withdraw":"Withdraw","Withdraw & Switch":"Withdraw & Switch","Withdraw and Switch":"Withdraw and Switch","Withdraw {symbol}":["Withdraw ",["symbol"]],"Withdrawing":"Withdrawing","Withdrawing and Switching":"Withdrawing and Switching","Withdrawing this amount will reduce your health factor and increase risk of liquidation.":"Withdrawing this amount will reduce your health factor and increase risk of liquidation.","Withdrawing {symbol}":["Withdrawing ",["symbol"]],"Wrong Network":"Wrong Network","YAE":"YAE","You are entering Isolation mode":"You are entering Isolation mode","You can borrow this asset with a stable rate only if you borrow more than the amount you are supplying as collateral.":"You can borrow this asset with a stable rate only if you borrow more than the amount you are supplying as collateral.","You can not change Interest Type to stable as your borrowings are higher than your collateral":"You can not change Interest Type to stable as your borrowings are higher than your collateral","You can not disable E-Mode as your current collateralization level is above 80%, disabling E-Mode can cause liquidation. To exit E-Mode supply or repay borrowed positions.":"You can not disable E-Mode as your current collateralization level is above 80%, disabling E-Mode can cause liquidation. To exit E-Mode supply or repay borrowed positions.","You can not switch usage as collateral mode for this currency, because it will cause collateral call":"You can not switch usage as collateral mode for this currency, because it will cause collateral call","You can not use this currency as collateral":"You can not use this currency as collateral","You can not withdraw this amount because it will cause collateral call":"You can not withdraw this amount because it will cause collateral call","You can only switch to tokens with variable APY types. After this transaction, you may change the variable rate to a stable one if available.":"You can only switch to tokens with variable APY types. After this transaction, you may change the variable rate to a stable one if available.","You can only withdraw your assets from the Security Module after the cooldown period ends and the unstake window is active.":"You can only withdraw your assets from the Security Module after the cooldown period ends and the unstake window is active.","You can report incident to our <0>Discord or<1>Github.":"You can report incident to our <0>Discord or<1>Github.","You cancelled the transaction.":"You cancelled the transaction.","You did not participate in this proposal":"You did not participate in this proposal","You do not have supplies in this currency":"You do not have supplies in this currency","You don’t have enough funds in your wallet to repay the full amount. If you proceed to repay with your current amount of funds, you will still have a small borrowing position in your dashboard.":"You don’t have enough funds in your wallet to repay the full amount. If you proceed to repay with your current amount of funds, you will still have a small borrowing position in your dashboard.","You have no AAVE/stkAAVE balance to delegate.":"You have no AAVE/stkAAVE balance to delegate.","You have not borrow yet using this currency":"You have not borrow yet using this currency","You may borrow up to <0/> GHO at <1/> (max discount)":"You may borrow up to <0/> GHO at <1/> (max discount)","You may enter a custom amount in the field.":"You may enter a custom amount in the field.","You switched to {0} rate":["You switched to ",["0"]," rate"],"You unstake here":"You unstake here","You voted {0}":["You voted ",["0"]],"You will exit isolation mode and other tokens can now be used as collateral":"You will exit isolation mode and other tokens can now be used as collateral","You {action} <0/> {symbol}":["You ",["action"]," <0/> ",["symbol"]],"You've successfully switched borrow position.":"You've successfully switched borrow position.","You've successfully switched tokens.":"You've successfully switched tokens.","You've successfully withdrew & switched tokens.":"You've successfully withdrew & switched tokens.","Your balance is lower than the selected amount.":"Your balance is lower than the selected amount.","Your borrows":"Your borrows","Your current loan to value based on your collateral supplied.":"Your current loan to value based on your collateral supplied.","Your health factor and loan to value determine the assurance of your collateral. To avoid liquidations you can supply more collateral or repay borrow positions.":"Your health factor and loan to value determine the assurance of your collateral. To avoid liquidations you can supply more collateral or repay borrow positions.","Your info":"Your info","Your proposition power is based on your AAVE/stkAAVE balance and received delegations.":"Your proposition power is based on your AAVE/stkAAVE balance and received delegations.","Your reward balance is 0":"Your reward balance is 0","Your supplies":"Your supplies","Your voting info":"Your voting info","Your voting power is based on your AAVE/stkAAVE balance and received delegations.":"Your voting power is based on your AAVE/stkAAVE balance and received delegations.","Your {name} wallet is empty. Purchase or transfer assets or use <0>{0} to transfer your {network} assets.":["Your ",["name"]," wallet is empty. Purchase or transfer assets or use <0>",["0"]," to transfer your ",["network"]," assets."],"Your {name} wallet is empty. Purchase or transfer assets.":["Your ",["name"]," wallet is empty. Purchase or transfer assets."],"Your {networkName} wallet is empty. Get free test assets at":["Your ",["networkName"]," wallet is empty. Get free test assets at"],"Your {networkName} wallet is empty. Get free test {0} at":["Your ",["networkName"]," wallet is empty. Get free test ",["0"]," at"],"Zero address not valid":"Zero address not valid","assets":"assets","blocked activities":"blocked activities","copy the error":"copy the error","disabled":"disabled","documentation":"documentation","enabled":"enabled","ends":"ends","for":"for","of":"of","on":"on","please check that the amount you want to supply is not currently being used for staking. If it is being used for staking, your transaction might fail.":"please check that the amount you want to supply is not currently being used for staking. If it is being used for staking, your transaction might fail.","repaid":"repaid","stETH supplied as collateral will continue to accrue staking rewards provided by daily rebases.":"stETH supplied as collateral will continue to accrue staking rewards provided by daily rebases.","stETH tokens will be migrated to Wrapped stETH using Lido Protocol wrapper which leads to supply balance change after migration: {0}":["stETH tokens will be migrated to Wrapped stETH using Lido Protocol wrapper which leads to supply balance change after migration: ",["0"]],"staking view":"staking view","starts":"starts","stkAAVE holders get a discount on GHO borrow rate":"stkAAVE holders get a discount on GHO borrow rate","to":"to","tokens is not the same as staking them. If you wish to stake your":"tokens is not the same as staking them. If you wish to stake your","tokens, please go to the":"tokens, please go to the","withdrew":"withdrew","{0}":[["0"]],"{0} Balance":[["0"]," Balance"],"{0} Faucet":[["0"]," Faucet"],"{0} on-ramp service is provided by External Provider and by selecting you agree to Terms of the Provider. Your access to the service might be reliant on the External Provider being operational.":[["0"]," on-ramp service is provided by External Provider and by selecting you agree to Terms of the Provider. Your access to the service might be reliant on the External Provider being operational."],"{0}{name}":[["0"],["name"]],"{currentMethod}":[["currentMethod"]],"{d}d":[["d"],"d"],"{h}h":[["h"],"h"],"{m}m":[["m"],"m"],"{networkName} Faucet":[["networkName"]," Faucet"],"{notifyText}":[["notifyText"]],"{numSelected}/{numAvailable} assets selected":[["numSelected"],"/",["numAvailable"]," assets selected"],"{s}s":[["s"],"s"],"{title}":[["title"]],"{tooltipText}":[["tooltipText"]]}}; \ No newline at end of file +/*eslint-disable*/module.exports={messages:{"...":"...",".CSV":".CSV",".JSON":".JSON","<0><1><2/>Add <3/> stkAAVE to borrow at <4/> (max discount)":"<0><1><2/>Add <3/> stkAAVE to borrow at <4/> (max discount)","<0><1><2/>Add stkAAVE to see borrow rate with discount":"<0><1><2/>Add stkAAVE to see borrow rate with discount","<0>Ampleforth is a rebasing asset. Visit the <1>documentation to learn more.":"<0>Ampleforth is a rebasing asset. Visit the <1>documentation to learn more.","<0>Attention: Parameter changes via governance can alter your account health factor and risk of liquidation. Follow the <1>Aave governance forum for updates.":"<0>Attention: Parameter changes via governance can alter your account health factor and risk of liquidation. Follow the <1>Aave governance forum for updates.","<0>Slippage tolerance <1>{selectedSlippage}% <2>{0}":["<0>Slippage tolerance <1>",["selectedSlippage"],"% <2>",["0"],""],"AAVE holders (Ethereum network only) can stake their AAVE in the Safety Module to add more security to the protocol and earn Safety Incentives. In the case of a shortfall event, up to 30% of your stake can be slashed to cover the deficit, providing an additional layer of protection for the protocol.":"AAVE holders (Ethereum network only) can stake their AAVE in the Safety Module to add more security to the protocol and earn Safety Incentives. In the case of a shortfall event, up to 30% of your stake can be slashed to cover the deficit, providing an additional layer of protection for the protocol.","APR":"APR","APY":"APY","APY change":"APY change","APY type":"APY type","APY type change":"APY type change","APY with discount applied":"APY with discount applied","APY, fixed rate":"APY, fixed rate","APY, stable":"APY, stable","APY, variable":"APY, variable","AToken supply is not zero":"AToken supply is not zero","Aave Governance":"Aave Governance","Aave aToken":"Aave aToken","Aave debt token":"Aave debt token","Aave is a fully decentralized, community governed protocol by the AAVE token-holders. AAVE token-holders collectively discuss, propose, and vote on upgrades to the protocol. AAVE token-holders (Ethereum network only) can either vote themselves on new proposals or delagate to an address of choice. To learn more check out the Governance":"Aave is a fully decentralized, community governed protocol by the AAVE token-holders. AAVE token-holders collectively discuss, propose, and vote on upgrades to the protocol. AAVE token-holders (Ethereum network only) can either vote themselves on new proposals or delagate to an address of choice. To learn more check out the Governance","Aave per month":"Aave per month","About GHO":"About GHO","Account":"Account","Action cannot be performed because the reserve is frozen":"Action cannot be performed because the reserve is frozen","Action cannot be performed because the reserve is paused":"Action cannot be performed because the reserve is paused","Action requires an active reserve":"Action requires an active reserve","Activate Cooldown":"Activate Cooldown","Add stkAAVE to see borrow APY with the discount":"Add stkAAVE to see borrow APY with the discount","Add to wallet":"Add to wallet","Add {0} to wallet to track your balance.":["Add ",["0"]," to wallet to track your balance."],"Address is not a contract":"Address is not a contract","Addresses":"Addresses","Addresses ({0})":["Addresses (",["0"],")"],"All Assets":"All Assets","All done!":"All done!","All proposals":"All proposals","All transactions":"All transactions","Allowance required action":"Allowance required action","Allows you to decide whether to use a supplied asset as collateral. An asset used as collateral will affect your borrowing power and health factor.":"Allows you to decide whether to use a supplied asset as collateral. An asset used as collateral will affect your borrowing power and health factor.","Allows you to switch between <0>variable and <1>stable interest rates, where variable rate can increase and decrease depending on the amount of liquidity in the reserve, and stable rate will stay the same for the duration of your loan.":"Allows you to switch between <0>variable and <1>stable interest rates, where variable rate can increase and decrease depending on the amount of liquidity in the reserve, and stable rate will stay the same for the duration of your loan.","Amount":"Amount","Amount claimable":"Amount claimable","Amount in cooldown":"Amount in cooldown","Amount must be greater than 0":"Amount must be greater than 0","Amount to unstake":"Amount to unstake","An error has occurred fetching the proposal metadata from IPFS.":"An error has occurred fetching the proposal metadata from IPFS.","Approve Confirmed":"Approve Confirmed","Approve with":"Approve with","Approve {symbol} to continue":["Approve ",["symbol"]," to continue"],"Approving {symbol}...":["Approving ",["symbol"],"..."],"Array parameters that should be equal length are not":"Array parameters that should be equal length are not","Asset":"Asset","Asset can be only used as collateral in isolation mode with limited borrowing power. To enter isolation mode, disable all other collateral.":"Asset can be only used as collateral in isolation mode with limited borrowing power. To enter isolation mode, disable all other collateral.","Asset can only be used as collateral in isolation mode only.":"Asset can only be used as collateral in isolation mode only.","Asset cannot be migrated because you have isolated collateral in {marketName} v3 Market which limits borrowable assets. You can manage your collateral in <0>{marketName} V3 Dashboard":["Asset cannot be migrated because you have isolated collateral in ",["marketName"]," v3 Market which limits borrowable assets. You can manage your collateral in <0>",["marketName"]," V3 Dashboard"],"Asset cannot be migrated due to insufficient liquidity or borrow cap limitation in {marketName} v3 market.":["Asset cannot be migrated due to insufficient liquidity or borrow cap limitation in ",["marketName"]," v3 market."],"Asset cannot be migrated due to supply cap restriction in {marketName} v3 market.":["Asset cannot be migrated due to supply cap restriction in ",["marketName"]," v3 market."],"Asset cannot be migrated to {marketName} V3 Market due to E-mode restrictions. You can disable or manage E-mode categories in your <0>V3 Dashboard":["Asset cannot be migrated to ",["marketName"]," V3 Market due to E-mode restrictions. You can disable or manage E-mode categories in your <0>V3 Dashboard"],"Asset cannot be migrated to {marketName} v3 Market since collateral asset will enable isolation mode.":["Asset cannot be migrated to ",["marketName"]," v3 Market since collateral asset will enable isolation mode."],"Asset cannot be used as collateral.":"Asset cannot be used as collateral.","Asset category":"Asset category","Asset is frozen in {marketName} v3 market, hence this position cannot be migrated.":["Asset is frozen in ",["marketName"]," v3 market, hence this position cannot be migrated."],"Asset is not borrowable in isolation mode":"Asset is not borrowable in isolation mode","Asset is not listed":"Asset is not listed","Asset supply is limited to a certain amount to reduce protocol exposure to the asset and to help manage risks involved.":"Asset supply is limited to a certain amount to reduce protocol exposure to the asset and to help manage risks involved.","Assets":"Assets","Assets to borrow":"Assets to borrow","Assets to supply":"Assets to supply","Assets with zero LTV ({assetsBlockingWithdraw}) must be withdrawn or disabled as collateral to perform this action":["Assets with zero LTV (",["assetsBlockingWithdraw"],") must be withdrawn or disabled as collateral to perform this action"],"At a discount":"At a discount","Author":"Author","Available":"Available","Available assets":"Available assets","Available liquidity":"Available liquidity","Available on":"Available on","Available rewards":"Available rewards","Available to borrow":"Available to borrow","Available to supply":"Available to supply","Back to Dashboard":"Back to Dashboard","Balance":"Balance","Balance to revoke":"Balance to revoke","Be careful - You are very close to liquidation. Consider depositing more collateral or paying down some of your borrowed positions":"Be careful - You are very close to liquidation. Consider depositing more collateral or paying down some of your borrowed positions","Be mindful of the network congestion and gas prices.":"Be mindful of the network congestion and gas prices.","Because this asset is paused, no actions can be taken until further notice":"Because this asset is paused, no actions can be taken until further notice","Before supplying":"Before supplying","Blocked Address":"Blocked Address","Borrow":"Borrow","Borrow APY":"Borrow APY","Borrow APY rate":"Borrow APY rate","Borrow APY, fixed rate":"Borrow APY, fixed rate","Borrow APY, stable":"Borrow APY, stable","Borrow APY, variable":"Borrow APY, variable","Borrow amount to reach {0}% utilization":["Borrow amount to reach ",["0"],"% utilization"],"Borrow and repay in same block is not allowed":"Borrow and repay in same block is not allowed","Borrow apy":"Borrow apy","Borrow balance":"Borrow balance","Borrow balance after repay":"Borrow balance after repay","Borrow balance after switch":"Borrow balance after switch","Borrow cap":"Borrow cap","Borrow cap is exceeded":"Borrow cap is exceeded","Borrow info":"Borrow info","Borrow power used":"Borrow power used","Borrow rate change":"Borrow rate change","Borrow {symbol}":["Borrow ",["symbol"]],"Borrowed":"Borrowed","Borrowed asset amount":"Borrowed asset amount","Borrowing is currently unavailable for {0}.":["Borrowing is currently unavailable for ",["0"],"."],"Borrowing is disabled due to an Aave community decision. <0>More details":"Borrowing is disabled due to an Aave community decision. <0>More details","Borrowing is not enabled":"Borrowing is not enabled","Borrowing is unavailable because you’re using Isolation mode. To manage Isolation mode visit your <0>Dashboard.":"Borrowing is unavailable because you’re using Isolation mode. To manage Isolation mode visit your <0>Dashboard.","Borrowing is unavailable because you’ve enabled Efficiency Mode (E-Mode) and Isolation mode. To manage E-Mode and Isolation mode visit your <0>Dashboard.":"Borrowing is unavailable because you’ve enabled Efficiency Mode (E-Mode) and Isolation mode. To manage E-Mode and Isolation mode visit your <0>Dashboard.","Borrowing is unavailable because you’ve enabled Efficiency Mode (E-Mode) for {0} category. To manage E-Mode categories visit your <0>Dashboard.":["Borrowing is unavailable because you’ve enabled Efficiency Mode (E-Mode) for ",["0"]," category. To manage E-Mode categories visit your <0>Dashboard."],"Borrowing of this asset is limited to a certain amount to minimize liquidity pool insolvency.":"Borrowing of this asset is limited to a certain amount to minimize liquidity pool insolvency.","Borrowing power and assets are limited due to Isolation mode.":"Borrowing power and assets are limited due to Isolation mode.","Borrowing this amount will reduce your health factor and increase risk of liquidation.":"Borrowing this amount will reduce your health factor and increase risk of liquidation.","Borrowing {symbol}":["Borrowing ",["symbol"]],"Both":"Both","Buy Crypto With Fiat":"Buy Crypto With Fiat","Buy Crypto with Fiat":"Buy Crypto with Fiat","Buy {cryptoSymbol} with Fiat":["Buy ",["cryptoSymbol"]," with Fiat"],"COPIED!":"COPIED!","COPY IMAGE":"COPY IMAGE","Can be collateral":"Can be collateral","Can be executed":"Can be executed","Cancel":"Cancel","Cannot disable E-Mode":"Cannot disable E-Mode","Choose how much voting/proposition power to give to someone else by delegating some of your AAVE or stkAAVE balance. Your tokens will remain in your account, but your delegate will be able to vote or propose on your behalf. If your AAVE or stkAAVE balance changes, your delegate's voting/proposition power will be automatically adjusted.":"Choose how much voting/proposition power to give to someone else by delegating some of your AAVE or stkAAVE balance. Your tokens will remain in your account, but your delegate will be able to vote or propose on your behalf. If your AAVE or stkAAVE balance changes, your delegate's voting/proposition power will be automatically adjusted.","Choose one of the on-ramp services":"Choose one of the on-ramp services","Claim":"Claim","Claim all":"Claim all","Claim all rewards":"Claim all rewards","Claim {0}":["Claim ",["0"]],"Claim {symbol}":["Claim ",["symbol"]],"Claimable AAVE":"Claimable AAVE","Claimed":"Claimed","Claiming":"Claiming","Claiming {symbol}":["Claiming ",["symbol"]],"Close":"Close","Collateral":"Collateral","Collateral balance after repay":"Collateral balance after repay","Collateral change":"Collateral change","Collateral is (mostly) the same currency that is being borrowed":"Collateral is (mostly) the same currency that is being borrowed","Collateral to repay with":"Collateral to repay with","Collateral usage":"Collateral usage","Collateral usage is limited because of Isolation mode.":"Collateral usage is limited because of Isolation mode.","Collateral usage is limited because of isolation mode.":"Collateral usage is limited because of isolation mode.","Collateral usage is limited because of isolation mode. <0>Learn More":"Collateral usage is limited because of isolation mode. <0>Learn More","Collateralization":"Collateralization","Collector Contract":"Collector Contract","Collector Info":"Collector Info","Connect wallet":"Connect wallet","Cooldown period":"Cooldown period","Cooldown period warning":"Cooldown period warning","Cooldown time left":"Cooldown time left","Cooldown to unstake":"Cooldown to unstake","Cooling down...":"Cooling down...","Copy address":"Copy address","Copy error message":"Copy error message","Copy error text":"Copy error text","Covered debt":"Covered debt","Created":"Created","Current LTV":"Current LTV","Current differential":"Current differential","Current v2 Balance":"Current v2 Balance","Current v2 balance":"Current v2 balance","Current votes":"Current votes","DAI balance will be converted via DSR contracts and then supplied as sDAI to Aave reserve. Switching incurs no additional costs and no slippage.":"DAI balance will be converted via DSR contracts and then supplied as sDAI to Aave reserve. Switching incurs no additional costs and no slippage.","DAI balance will be converted via DSR contracts and then supplied as sDAI. Switching incurs no additional costs and no slippage.":"DAI balance will be converted via DSR contracts and then supplied as sDAI. Switching incurs no additional costs and no slippage.","Dark mode":"Dark mode","Dashboard":"Dashboard","Data couldn't be fetched, please reload graph.":"Data couldn't be fetched, please reload graph.","Debt":"Debt","Debt ceiling is exceeded":"Debt ceiling is exceeded","Debt ceiling is not zero":"Debt ceiling is not zero","Debt ceiling limits the amount possible to borrow against this asset by protocol users. Debt ceiling is specific to assets in isolation mode and is denoted in USD.":"Debt ceiling limits the amount possible to borrow against this asset by protocol users. Debt ceiling is specific to assets in isolation mode and is denoted in USD.","Delegated power":"Delegated power","Details":"Details","Developers":"Developers","Differential":"Differential","Disable E-Mode":"Disable E-Mode","Disable testnet":"Disable testnet","Disable {symbol} as collateral":["Disable ",["symbol"]," as collateral"],"Disabled":"Disabled","Disabling E-Mode":"Disabling E-Mode","Disabling this asset as collateral affects your borrowing power and Health Factor.":"Disabling this asset as collateral affects your borrowing power and Health Factor.","Disconnect Wallet":"Disconnect Wallet","Discord channel":"Discord channel","Discount":"Discount","Discount applied for <0/> staking AAVE":"Discount applied for <0/> staking AAVE","Discount model parameters":"Discount model parameters","Discount parameters are decided by the Aave community and may be changed over time. Check Governance for updates and vote to participate. <0>Learn more":"Discount parameters are decided by the Aave community and may be changed over time. Check Governance for updates and vote to participate. <0>Learn more","Discountable amount":"Discountable amount","Docs":"Docs","Download":"Download","Due to internal stETH mechanics required for rebasing support, it is not possible to perform a collateral switch where stETH is the source token.":"Due to internal stETH mechanics required for rebasing support, it is not possible to perform a collateral switch where stETH is the source token.","Due to the Horizon bridge exploit, certain assets on the Harmony network are not at parity with Ethereum, which affects the Aave V3 Harmony market.":"Due to the Horizon bridge exploit, certain assets on the Harmony network are not at parity with Ethereum, which affects the Aave V3 Harmony market.","E-Mode":"E-Mode","E-Mode Category":"E-Mode Category","E-Mode category":"E-Mode category","E-Mode increases your LTV for a selected category of assets up to 97%. <0>Learn more":"E-Mode increases your LTV for a selected category of assets up to 97%. <0>Learn more","E-Mode increases your LTV for a selected category of assets up to<0/>. <1>Learn more":"E-Mode increases your LTV for a selected category of assets up to<0/>. <1>Learn more","E-Mode increases your LTV for a selected category of assets, meaning that when E-mode is enabled, you will have higher borrowing power over assets of the same E-mode category which are defined by Aave Governance. You can enter E-Mode from your <0>Dashboard. To learn more about E-Mode and applied restrictions in <1>FAQ or <2>Aave V3 Technical Paper.":"E-Mode increases your LTV for a selected category of assets, meaning that when E-mode is enabled, you will have higher borrowing power over assets of the same E-mode category which are defined by Aave Governance. You can enter E-Mode from your <0>Dashboard. To learn more about E-Mode and applied restrictions in <1>FAQ or <2>Aave V3 Technical Paper.","Effective interest rate":"Effective interest rate","Efficiency mode (E-Mode)":"Efficiency mode (E-Mode)","Emode":"Emode","Enable E-Mode":"Enable E-Mode","Enable {symbol} as collateral":["Enable ",["symbol"]," as collateral"],"Enabled":"Enabled","Enabling E-Mode":"Enabling E-Mode","Enabling E-Mode only allows you to borrow assets belonging to the selected category. Please visit our <0>FAQ guide to learn more about how it works and the applied restrictions.":"Enabling E-Mode only allows you to borrow assets belonging to the selected category. Please visit our <0>FAQ guide to learn more about how it works and the applied restrictions.","Enabling this asset as collateral increases your borrowing power and Health Factor. However, it can get liquidated if your health factor drops below 1.":"Enabling this asset as collateral increases your borrowing power and Health Factor. However, it can get liquidated if your health factor drops below 1.","Ended":"Ended","Ends":"Ends","English":"English","Enter ETH address":"Enter ETH address","Enter an amount":"Enter an amount","Error connecting. Try refreshing the page.":"Error connecting. Try refreshing the page.","Estimated compounding interest, including discount for Staking {0}AAVE in Safety Module.":["Estimated compounding interest, including discount for Staking ",["0"],"AAVE in Safety Module."],"Exceeds the discount":"Exceeds the discount","Exchange rate":"Exchange rate","Executed":"Executed","Expected amount to repay":"Expected amount to repay","Expires":"Expires","Export data to":"Export data to","FAQ":"FAQ","FAQS":"FAQS","Failed to load proposal voters. Please refresh the page.":"Failed to load proposal voters. Please refresh the page.","Faucet":"Faucet","Faucet {0}":["Faucet ",["0"]],"Fetching data...":"Fetching data...","Filter":"Filter","Fixed":"Fixed","Fixed rate":"Fixed rate","Flashloan is disabled for this asset, hence this position cannot be migrated.":"Flashloan is disabled for this asset, hence this position cannot be migrated.","For repayment of a specific type of debt, the user needs to have debt that type":"For repayment of a specific type of debt, the user needs to have debt that type","Forum discussion":"Forum discussion","French":"French","Funds in the Safety Module":"Funds in the Safety Module","GHO is a native decentralized, collateral-backed digital asset pegged to USD. It is created by users via borrowing against multiple collateral. When user repays their GHO borrow position, the protocol burns that user's GHO. All the interest payments accrued by minters of GHO would be directly transferred to the AaveDAO treasury.":"GHO is a native decentralized, collateral-backed digital asset pegged to USD. It is created by users via borrowing against multiple collateral. When user repays their GHO borrow position, the protocol burns that user's GHO. All the interest payments accrued by minters of GHO would be directly transferred to the AaveDAO treasury.","Get ABP Token":"Get ABP Token","Global settings":"Global settings","Go Back":"Go Back","Go to Balancer Pool":"Go to Balancer Pool","Go to V3 Dashboard":"Go to V3 Dashboard","Governance":"Governance","Greek":"Greek","Health Factor ({0} v2)":["Health Factor (",["0"]," v2)"],"Health Factor ({0} v3)":["Health Factor (",["0"]," v3)"],"Health factor":"Health factor","Health factor is lesser than the liquidation threshold":"Health factor is lesser than the liquidation threshold","Health factor is not below the threshold":"Health factor is not below the threshold","Hide":"Hide","Holders of stkAAVE receive a discount on the GHO borrowing rate":"Holders of stkAAVE receive a discount on the GHO borrowing rate","I acknowledge the risks involved.":"I acknowledge the risks involved.","I fully understand the risks of migrating.":"I fully understand the risks of migrating.","I understand how cooldown ({0}) and unstaking ({1}) work":["I understand how cooldown (",["0"],") and unstaking (",["1"],") work"],"If the error continues to happen,<0/> you may report it to this":"If the error continues to happen,<0/> you may report it to this","If the health factor goes below 1, the liquidation of your collateral might be triggered.":"If the health factor goes below 1, the liquidation of your collateral might be triggered.","If you DO NOT unstake within {0} of unstake window, you will need to activate cooldown process again.":["If you DO NOT unstake within ",["0"]," of unstake window, you will need to activate cooldown process again."],"If your loan to value goes above the liquidation threshold your collateral supplied may be liquidated.":"If your loan to value goes above the liquidation threshold your collateral supplied may be liquidated.","In E-Mode some assets are not borrowable. Exit E-Mode to get access to all assets":"In E-Mode some assets are not borrowable. Exit E-Mode to get access to all assets","In Isolation mode, you cannot supply other assets as collateral. A global debt ceiling limits the borrowing power of the isolated asset. To exit isolation mode disable {0} as collateral before borrowing another asset. Read more in our <0>FAQ":["In Isolation mode, you cannot supply other assets as collateral. A global debt ceiling limits the borrowing power of the isolated asset. To exit isolation mode disable ",["0"]," as collateral before borrowing another asset. Read more in our <0>FAQ"],"Inconsistent flashloan parameters":"Inconsistent flashloan parameters","Insufficient collateral to cover new borrow position. Wallet must have borrowing power remaining to perform debt switch.":"Insufficient collateral to cover new borrow position. Wallet must have borrowing power remaining to perform debt switch.","Interest accrued":"Interest accrued","Interest rate rebalance conditions were not met":"Interest rate rebalance conditions were not met","Interest rate strategy":"Interest rate strategy","Invalid amount to burn":"Invalid amount to burn","Invalid amount to mint":"Invalid amount to mint","Invalid bridge protocol fee":"Invalid bridge protocol fee","Invalid expiration":"Invalid expiration","Invalid flashloan premium":"Invalid flashloan premium","Invalid return value of the flashloan executor function":"Invalid return value of the flashloan executor function","Invalid signature":"Invalid signature","Isolated":"Isolated","Isolated Debt Ceiling":"Isolated Debt Ceiling","Isolated assets have limited borrowing power and other assets cannot be used as collateral.":"Isolated assets have limited borrowing power and other assets cannot be used as collateral.","Join the community discussion":"Join the community discussion","LEARN MORE":"LEARN MORE","Language":"Language","Learn more":"Learn more","Learn more about risks involved":"Learn more about risks involved","Learn more in our <0>FAQ guide":"Learn more in our <0>FAQ guide","Learn more.":"Learn more.","Links":"Links","Liqudation":"Liqudation","Liquidated collateral":"Liquidated collateral","Liquidation":"Liquidation","Liquidation <0/> threshold":"Liquidation <0/> threshold","Liquidation Threshold":"Liquidation Threshold","Liquidation at":"Liquidation at","Liquidation penalty":"Liquidation penalty","Liquidation risk":"Liquidation risk","Liquidation risk parameters":"Liquidation risk parameters","Liquidation threshold":"Liquidation threshold","Liquidation value":"Liquidation value","Loading data...":"Loading data...","Ltv validation failed":"Ltv validation failed","MAI has been paused due to a community decision. Supply, borrows and repays are impacted. <0>More details":"MAI has been paused due to a community decision. Supply, borrows and repays are impacted. <0>More details","MAX":"MAX","Manage analytics":"Manage analytics","Market":"Market","Markets":"Markets","Max":"Max","Max LTV":"Max LTV","Max slashing":"Max slashing","Max slippage":"Max slippage","Maximum amount available to borrow against this asset is limited because debt ceiling is at {0}%.":["Maximum amount available to borrow against this asset is limited because debt ceiling is at ",["0"],"%."],"Maximum amount available to borrow is <0/> {0} (<1/>).":["Maximum amount available to borrow is <0/> ",["0"]," (<1/>)."],"Maximum amount available to borrow is limited because protocol borrow cap is nearly reached.":"Maximum amount available to borrow is limited because protocol borrow cap is nearly reached.","Maximum amount available to supply is <0/> {0} (<1/>).":["Maximum amount available to supply is <0/> ",["0"]," (<1/>)."],"Maximum amount available to supply is limited because protocol supply cap is at {0}%.":["Maximum amount available to supply is limited because protocol supply cap is at ",["0"],"%."],"Maximum loan to value":"Maximum loan to value","Meet GHO":"Meet GHO","Menu":"Menu","Migrate":"Migrate","Migrate to V3":"Migrate to V3","Migrate to v3":"Migrate to v3","Migrate to {0} v3 Market":["Migrate to ",["0"]," v3 Market"],"Migrated":"Migrated","Migrating":"Migrating","Migrating multiple collaterals and borrowed assets at the same time can be an expensive operation and might fail in certain situations.<0>Therefore it’s not recommended to migrate positions with more than 5 assets (deposited + borrowed) at the same time.":"Migrating multiple collaterals and borrowed assets at the same time can be an expensive operation and might fail in certain situations.<0>Therefore it’s not recommended to migrate positions with more than 5 assets (deposited + borrowed) at the same time.","Migration risks":"Migration risks","Minimum GHO borrow amount":"Minimum GHO borrow amount","Minimum USD value received":"Minimum USD value received","Minimum staked Aave amount":"Minimum staked Aave amount","Minimum {0} received":["Minimum ",["0"]," received"],"More":"More","NAY":"NAY","Need help connecting a wallet? <0>Read our FAQ":"Need help connecting a wallet? <0>Read our FAQ","Net APR":"Net APR","Net APY":"Net APY","Net APY is the combined effect of all supply and borrow positions on net worth, including incentives. It is possible to have a negative net APY if debt APY is higher than supply APY.":"Net APY is the combined effect of all supply and borrow positions on net worth, including incentives. It is possible to have a negative net APY if debt APY is higher than supply APY.","Net worth":"Net worth","Network":"Network","Network not supported for this wallet":"Network not supported for this wallet","New APY":"New APY","No assets selected to migrate.":"No assets selected to migrate.","No rewards to claim":"No rewards to claim","No search results{0}":["No search results",["0"]],"No transactions yet.":"No transactions yet.","No voting power":"No voting power","None":"None","Not a valid address":"Not a valid address","Not enough balance on your wallet":"Not enough balance on your wallet","Not enough collateral to repay this amount of debt with":"Not enough collateral to repay this amount of debt with","Not enough staked balance":"Not enough staked balance","Not enough voting power to participate in this proposal":"Not enough voting power to participate in this proposal","Not reached":"Not reached","Nothing borrowed yet":"Nothing borrowed yet","Nothing found":"Nothing found","Nothing staked":"Nothing staked","Nothing supplied yet":"Nothing supplied yet","Notify":"Notify","Ok, Close":"Ok, Close","Ok, I got it":"Ok, I got it","Operation not supported":"Operation not supported","Oracle price":"Oracle price","Overview":"Overview","Page not found":"Page not found","Participating in this {symbol} reserve gives annualized rewards.":["Participating in this ",["symbol"]," reserve gives annualized rewards."],"Pending...":"Pending...","Per the community, the Fantom market has been frozen.":"Per the community, the Fantom market has been frozen.","Per the community, the V2 AMM market has been deprecated.":"Per the community, the V2 AMM market has been deprecated.","Please always be aware of your <0>Health Factor (HF) when partially migrating a position and that your rates will be updated to V3 rates.":"Please always be aware of your <0>Health Factor (HF) when partially migrating a position and that your rates will be updated to V3 rates.","Please connect a wallet to view your personal information here.":"Please connect a wallet to view your personal information here.","Please connect your wallet to be able to switch your tokens.":"Please connect your wallet to be able to switch your tokens.","Please connect your wallet to get free testnet assets.":"Please connect your wallet to get free testnet assets.","Please connect your wallet to see migration tool.":"Please connect your wallet to see migration tool.","Please connect your wallet to see your supplies, borrowings, and open positions.":"Please connect your wallet to see your supplies, borrowings, and open positions.","Please connect your wallet to view transaction history.":"Please connect your wallet to view transaction history.","Please enter a valid wallet address.":"Please enter a valid wallet address.","Please switch to {networkName}.":["Please switch to ",["networkName"],"."],"Please, connect your wallet":"Please, connect your wallet","Pool addresses provider is not registered":"Pool addresses provider is not registered","Powered by":"Powered by","Preview tx and migrate":"Preview tx and migrate","Price":"Price","Price data is not currently available for this reserve on the protocol subgraph":"Price data is not currently available for this reserve on the protocol subgraph","Price impact":"Price impact","Price impact is the spread between the total value of the entry tokens switched and the destination tokens obtained (in USD), which results from the limited liquidity of the trading pair.":"Price impact is the spread between the total value of the entry tokens switched and the destination tokens obtained (in USD), which results from the limited liquidity of the trading pair.","Price impact {0}%":["Price impact ",["0"],"%"],"Privacy":"Privacy","Proposal details":"Proposal details","Proposal overview":"Proposal overview","Proposals":"Proposals","Proposition":"Proposition","Protocol borrow cap at 100% for this asset. Further borrowing unavailable.":"Protocol borrow cap at 100% for this asset. Further borrowing unavailable.","Protocol borrow cap is at 100% for this asset. Further borrowing unavailable.":"Protocol borrow cap is at 100% for this asset. Further borrowing unavailable.","Protocol debt ceiling is at 100% for this asset. Further borrowing against this asset is unavailable.":"Protocol debt ceiling is at 100% for this asset. Further borrowing against this asset is unavailable.","Protocol debt ceiling is at 100% for this asset. Futher borrowing against this asset is unavailable.":"Protocol debt ceiling is at 100% for this asset. Futher borrowing against this asset is unavailable.","Protocol supply cap at 100% for this asset. Further supply unavailable.":"Protocol supply cap at 100% for this asset. Further supply unavailable.","Protocol supply cap is at 100% for this asset. Further supply unavailable.":"Protocol supply cap is at 100% for this asset. Further supply unavailable.","Quorum":"Quorum","Rate change":"Rate change","Raw-Ipfs":"Raw-Ipfs","Reached":"Reached","Reactivate cooldown period to unstake {0} {stakedToken}":["Reactivate cooldown period to unstake ",["0"]," ",["stakedToken"]],"Read more here.":"Read more here.","Read-only mode allows to see address positions in Aave, but you won't be able to perform transactions.":"Read-only mode allows to see address positions in Aave, but you won't be able to perform transactions.","Read-only mode.":"Read-only mode.","Read-only mode. Connect to a wallet to perform transactions.":"Read-only mode. Connect to a wallet to perform transactions.","Receive (est.)":"Receive (est.)","Received":"Received","Recipient address":"Recipient address","Rejected connection request":"Rejected connection request","Reload":"Reload","Reload the page":"Reload the page","Remaining debt":"Remaining debt","Remaining supply":"Remaining supply","Repaid":"Repaid","Repay":"Repay","Repay with":"Repay with","Repay {symbol}":["Repay ",["symbol"]],"Repaying {symbol}":["Repaying ",["symbol"]],"Repayment amount to reach {0}% utilization":["Repayment amount to reach ",["0"],"% utilization"],"Reserve Size":"Reserve Size","Reserve factor":"Reserve factor","Reserve factor is a percentage of interest which goes to a {0} that is controlled by Aave governance to promote ecosystem growth.":["Reserve factor is a percentage of interest which goes to a ",["0"]," that is controlled by Aave governance to promote ecosystem growth."],"Reserve status & configuration":"Reserve status & configuration","Reset":"Reset","Restake":"Restake","Restake {symbol}":["Restake ",["symbol"]],"Restaked":"Restaked","Restaking {symbol}":["Restaking ",["symbol"]],"Review approval tx details":"Review approval tx details","Review changes to continue":"Review changes to continue","Review tx":"Review tx","Review tx details":"Review tx details","Revoke power":"Revoke power","Reward(s) to claim":"Reward(s) to claim","Rewards APR":"Rewards APR","Risk details":"Risk details","SEE CHARTS":"SEE CHARTS","Safety of your deposited collateral against the borrowed assets and its underlying value.":"Safety of your deposited collateral against the borrowed assets and its underlying value.","Save and share":"Save and share","Seatbelt report":"Seatbelt report","Seems like we can't switch the network automatically. Please check if you can change it from the wallet.":"Seems like we can't switch the network automatically. Please check if you can change it from the wallet.","Select":"Select","Select APY type to switch":"Select APY type to switch","Select an asset":"Select an asset","Select language":"Select language","Select slippage tolerance":"Select slippage tolerance","Select v2 borrows to migrate":"Select v2 borrows to migrate","Select v2 supplies to migrate":"Select v2 supplies to migrate","Selected assets have successfully migrated. Visit the Market Dashboard to see them.":"Selected assets have successfully migrated. Visit the Market Dashboard to see them.","Selected borrow assets":"Selected borrow assets","Selected supply assets":"Selected supply assets","Send feedback":"Send feedback","Set up delegation":"Set up delegation","Setup notifications about your Health Factor using the Hal app.":"Setup notifications about your Health Factor using the Hal app.","Share on Lens":"Share on Lens","Share on twitter":"Share on twitter","Show":"Show","Show Frozen or paused assets":"Show Frozen or paused assets","Show assets with 0 balance":"Show assets with 0 balance","Sign to continue":"Sign to continue","Signatures ready":"Signatures ready","Signing":"Signing","Since this asset is frozen, the only available actions are withdraw and repay which can be accessed from the <0>Dashboard":"Since this asset is frozen, the only available actions are withdraw and repay which can be accessed from the <0>Dashboard","Since this is a test network, you can get any of the assets if you have ETH on your wallet":"Since this is a test network, you can get any of the assets if you have ETH on your wallet","Slippage":"Slippage","Slippage is the difference between the quoted and received amounts from changing market conditions between the moment the transaction is submitted and its verification.":"Slippage is the difference between the quoted and received amounts from changing market conditions between the moment the transaction is submitted and its verification.","Some migrated assets will not be used as collateral due to enabled isolation mode in {marketName} V3 Market. Visit <0>{marketName} V3 Dashboard to manage isolation mode.":["Some migrated assets will not be used as collateral due to enabled isolation mode in ",["marketName"]," V3 Market. Visit <0>",["marketName"]," V3 Dashboard to manage isolation mode."],"Something went wrong":"Something went wrong","Sorry, an unexpected error happened. In the meantime you may try reloading the page, or come back later.":"Sorry, an unexpected error happened. In the meantime you may try reloading the page, or come back later.","Sorry, we couldn't find the page you were looking for.":"Sorry, we couldn't find the page you were looking for.","Spanish":"Spanish","Stable":"Stable","Stable Interest Type is disabled for this currency":"Stable Interest Type is disabled for this currency","Stable borrowing is enabled":"Stable borrowing is enabled","Stable borrowing is not enabled":"Stable borrowing is not enabled","Stable debt supply is not zero":"Stable debt supply is not zero","Stable interest rate will <0>stay the same for the duration of your loan. Recommended for long-term loan periods and for users who prefer predictability.":"Stable interest rate will <0>stay the same for the duration of your loan. Recommended for long-term loan periods and for users who prefer predictability.","Stablecoin":"Stablecoin","Stake":"Stake","Stake AAVE":"Stake AAVE","Stake ABPT":"Stake ABPT","Stake cooldown activated":"Stake cooldown activated","Staked":"Staked","Staking":"Staking","Staking APR":"Staking APR","Staking Rewards":"Staking Rewards","Staking balance":"Staking balance","Staking discount":"Staking discount","Started":"Started","State":"State","Static interest rate that is determined by Aave Governance. This rate may be changed over time depending on the need for the GHO supply to contract/expand. <0>Learn more":"Static interest rate that is determined by Aave Governance. This rate may be changed over time depending on the need for the GHO supply to contract/expand. <0>Learn more","Supplied":"Supplied","Supplied asset amount":"Supplied asset amount","Supply":"Supply","Supply APY":"Supply APY","Supply apy":"Supply apy","Supply balance":"Supply balance","Supply balance after switch":"Supply balance after switch","Supply cap is exceeded":"Supply cap is exceeded","Supply cap on target reserve reached. Try lowering the amount.":"Supply cap on target reserve reached. Try lowering the amount.","Supply {symbol}":["Supply ",["symbol"]],"Supplying your":"Supplying your","Supplying {symbol}":["Supplying ",["symbol"]],"Switch":"Switch","Switch APY type":"Switch APY type","Switch E-Mode":"Switch E-Mode","Switch E-Mode category":"Switch E-Mode category","Switch Network":"Switch Network","Switch borrow position":"Switch borrow position","Switch rate":"Switch rate","Switch to":"Switch to","Switched":"Switched","Switching":"Switching","Switching E-Mode":"Switching E-Mode","Switching rate":"Switching rate","Techpaper":"Techpaper","Terms":"Terms","Test Assets":"Test Assets","Testnet mode":"Testnet mode","Testnet mode is ON":"Testnet mode is ON","Thank you for voting!!":"Thank you for voting!!","The % of your total borrowing power used. This is based on the amount of your collateral supplied and the total amount that you can borrow.":"The % of your total borrowing power used. This is based on the amount of your collateral supplied and the total amount that you can borrow.","The Aave Balancer Pool Token (ABPT) is a liquidity pool token. You can receive ABPT by depositing a combination of AAVE + ETH in the Balancer liquidity pool. You can then stake your BPT in the Safety Module to secure the protocol and earn Safety Incentives.":"The Aave Balancer Pool Token (ABPT) is a liquidity pool token. You can receive ABPT by depositing a combination of AAVE + ETH in the Balancer liquidity pool. You can then stake your BPT in the Safety Module to secure the protocol and earn Safety Incentives.","The Aave Protocol is programmed to always use the price of 1 GHO = $1. This is different from using market pricing via oracles for other crypto assets. This creates stabilizing arbitrage opportunities when the price of GHO fluctuates.":"The Aave Protocol is programmed to always use the price of 1 GHO = $1. This is different from using market pricing via oracles for other crypto assets. This creates stabilizing arbitrage opportunities when the price of GHO fluctuates.","The Maximum LTV ratio represents the maximum borrowing power of a specific collateral. For example, if a collateral has an LTV of 75%, the user can borrow up to 0.75 worth of ETH in the principal currency for every 1 ETH worth of collateral.":"The Maximum LTV ratio represents the maximum borrowing power of a specific collateral. For example, if a collateral has an LTV of 75%, the user can borrow up to 0.75 worth of ETH in the principal currency for every 1 ETH worth of collateral.","The Stable Rate is not enabled for this currency":"The Stable Rate is not enabled for this currency","The address of the pool addresses provider is invalid":"The address of the pool addresses provider is invalid","The app is running in testnet mode. Learn how it works in":"The app is running in testnet mode. Learn how it works in","The caller of the function is not an AToken":"The caller of the function is not an AToken","The caller of this function must be a pool":"The caller of this function must be a pool","The collateral balance is 0":"The collateral balance is 0","The collateral chosen cannot be liquidated":"The collateral chosen cannot be liquidated","The cooldown period is the time required prior to unstaking your tokens (20 days). You can only withdraw your assets from the Security Module after the cooldown period and within the unstake window.<0>Learn more":"The cooldown period is the time required prior to unstaking your tokens (20 days). You can only withdraw your assets from the Security Module after the cooldown period and within the unstake window.<0>Learn more","The cooldown period is {0}. After {1} of cooldown, you will enter unstake window of {2}. You will continue receiving rewards during cooldown and unstake window.":["The cooldown period is ",["0"],". After ",["1"]," of cooldown, you will enter unstake window of ",["2"],". You will continue receiving rewards during cooldown and unstake window."],"The effects on the health factor would cause liquidation. Try lowering the amount.":"The effects on the health factor would cause liquidation. Try lowering the amount.","The loan to value of the migrated positions would cause liquidation. Increase migrated collateral or reduce migrated borrow to continue.":"The loan to value of the migrated positions would cause liquidation. Increase migrated collateral or reduce migrated borrow to continue.","The requested amount is greater than the max loan size in stable rate mode":"The requested amount is greater than the max loan size in stable rate mode","The total amount of your assets denominated in USD that can be used as collateral for borrowing assets.":"The total amount of your assets denominated in USD that can be used as collateral for borrowing assets.","The underlying asset cannot be rescued":"The underlying asset cannot be rescued","The underlying balance needs to be greater than 0":"The underlying balance needs to be greater than 0","The weighted average of APY for all borrowed assets, including incentives.":"The weighted average of APY for all borrowed assets, including incentives.","The weighted average of APY for all supplied assets, including incentives.":"The weighted average of APY for all supplied assets, including incentives.","There are not enough funds in the{0}reserve to borrow":["There are not enough funds in the",["0"],"reserve to borrow"],"There is not enough collateral to cover a new borrow":"There is not enough collateral to cover a new borrow","There is not enough liquidity for the target asset to perform the switch. Try lowering the amount.":"There is not enough liquidity for the target asset to perform the switch. Try lowering the amount.","There was some error. Please try changing the parameters or <0><1>copy the error":"There was some error. Please try changing the parameters or <0><1>copy the error","These assets are temporarily frozen or paused by Aave community decisions, meaning that further supply / borrow, or rate swap of these assets are unavailable. Withdrawals and debt repayments are allowed. Follow the <0>Aave governance forum for further updates.":"These assets are temporarily frozen or paused by Aave community decisions, meaning that further supply / borrow, or rate swap of these assets are unavailable. Withdrawals and debt repayments are allowed. Follow the <0>Aave governance forum for further updates.","These funds have been borrowed and are not available for withdrawal at this time.":"These funds have been borrowed and are not available for withdrawal at this time.","This action will reduce V2 health factor below liquidation threshold. retain collateral or migrate borrow position to continue.":"This action will reduce V2 health factor below liquidation threshold. retain collateral or migrate borrow position to continue.","This action will reduce health factor of V3 below liquidation threshold. Increase migrated collateral or reduce migrated borrow to continue.":"This action will reduce health factor of V3 below liquidation threshold. Increase migrated collateral or reduce migrated borrow to continue.","This action will reduce your health factor. Please be mindful of the increased risk of collateral liquidation.":"This action will reduce your health factor. Please be mindful of the increased risk of collateral liquidation.","This address is blocked on app.aave.com because it is associated with one or more":"This address is blocked on app.aave.com because it is associated with one or more","This asset has almost reached its borrow cap. There is only {messageValue} available to be borrowed from this market.":["This asset has almost reached its borrow cap. There is only ",["messageValue"]," available to be borrowed from this market."],"This asset has almost reached its supply cap. There can only be {messageValue} supplied to this market.":["This asset has almost reached its supply cap. There can only be ",["messageValue"]," supplied to this market."],"This asset has reached its borrow cap. Nothing is available to be borrowed from this market.":"This asset has reached its borrow cap. Nothing is available to be borrowed from this market.","This asset has reached its supply cap. Nothing is available to be supplied from this market.":"This asset has reached its supply cap. Nothing is available to be supplied from this market.","This asset is frozen due to an Aave Protocol Governance decision. <0>More details":"This asset is frozen due to an Aave Protocol Governance decision. <0>More details","This asset is frozen due to an Aave Protocol Governance decision. On the 20th of December 2022, renFIL will no longer be supported and cannot be bridged back to its native network. It is recommended to withdraw supply positions and repay borrow positions so that renFIL can be bridged back to FIL before the deadline. After this date, it will no longer be possible to convert renFIL to FIL. <0>More details":"This asset is frozen due to an Aave Protocol Governance decision. On the 20th of December 2022, renFIL will no longer be supported and cannot be bridged back to its native network. It is recommended to withdraw supply positions and repay borrow positions so that renFIL can be bridged back to FIL before the deadline. After this date, it will no longer be possible to convert renFIL to FIL. <0>More details","This asset is frozen due to an Aave community decision. <0>More details":"This asset is frozen due to an Aave community decision. <0>More details","This asset is planned to be offboarded due to an Aave Protocol Governance decision. <0>More details":"This asset is planned to be offboarded due to an Aave Protocol Governance decision. <0>More details","This gas calculation is only an estimation. Your wallet will set the price of the transaction. You can modify the gas settings directly from your wallet provider.":"This gas calculation is only an estimation. Your wallet will set the price of the transaction. You can modify the gas settings directly from your wallet provider.","This integration was<0>proposed and approvedby the community.":"This integration was<0>proposed and approvedby the community.","This is the total amount available for you to borrow. You can borrow based on your collateral and until the borrow cap is reached.":"This is the total amount available for you to borrow. You can borrow based on your collateral and until the borrow cap is reached.","This is the total amount that you are able to supply to in this reserve. You are able to supply your wallet balance up until the supply cap is reached.":"This is the total amount that you are able to supply to in this reserve. You are able to supply your wallet balance up until the supply cap is reached.","This represents the threshold at which a borrow position will be considered undercollateralized and subject to liquidation for each collateral. For example, if a collateral has a liquidation threshold of 80%, it means that the position will be liquidated when the debt value is worth 80% of the collateral value.":"This represents the threshold at which a borrow position will be considered undercollateralized and subject to liquidation for each collateral. For example, if a collateral has a liquidation threshold of 80%, it means that the position will be liquidated when the debt value is worth 80% of the collateral value.","Time left to be able to withdraw your staked asset.":"Time left to be able to withdraw your staked asset.","Time left to unstake":"Time left to unstake","Time left until the withdrawal window closes.":"Time left until the withdrawal window closes.","Tip: Try increasing slippage or reduce input amount":"Tip: Try increasing slippage or reduce input amount","To borrow you need to supply any asset to be used as collateral.":"To borrow you need to supply any asset to be used as collateral.","To continue, you need to grant Aave smart contracts permission to move your funds from your wallet. Depending on the asset and wallet you use, it is done by signing the permission message (gas free), or by submitting an approval transaction (requires gas). <0>Learn more":"To continue, you need to grant Aave smart contracts permission to move your funds from your wallet. Depending on the asset and wallet you use, it is done by signing the permission message (gas free), or by submitting an approval transaction (requires gas). <0>Learn more","To enable E-mode for the {0} category, all borrow positions outside of this category must be closed.":["To enable E-mode for the ",["0"]," category, all borrow positions outside of this category must be closed."],"To repay on behalf of a user an explicit amount to repay is needed":"To repay on behalf of a user an explicit amount to repay is needed","To request access for this permissioned market, please visit: <0>Acces Provider Name":"To request access for this permissioned market, please visit: <0>Acces Provider Name","To submit a proposal for minor changes to the protocol, you'll need at least 80.00K power. If you want to change the core code base, you'll need 320k power.<0>Learn more.":"To submit a proposal for minor changes to the protocol, you'll need at least 80.00K power. If you want to change the core code base, you'll need 320k power.<0>Learn more.","Top 10 addresses":"Top 10 addresses","Total available":"Total available","Total borrowed":"Total borrowed","Total borrows":"Total borrows","Total emission per day":"Total emission per day","Total interest accrued":"Total interest accrued","Total market size":"Total market size","Total supplied":"Total supplied","Total voting power":"Total voting power","Total worth":"Total worth","Track wallet":"Track wallet","Track wallet balance in read-only mode":"Track wallet balance in read-only mode","Transaction failed":"Transaction failed","Transaction history":"Transaction history","Transaction history is not currently available for this market":"Transaction history is not currently available for this market","Transaction overview":"Transaction overview","Transactions":"Transactions","UNSTAKE {symbol}":["UNSTAKE ",["symbol"]],"Unavailable":"Unavailable","Unbacked":"Unbacked","Unbacked mint cap is exceeded":"Unbacked mint cap is exceeded","Underlying asset does not exist in {marketName} v3 Market, hence this position cannot be migrated.":["Underlying asset does not exist in ",["marketName"]," v3 Market, hence this position cannot be migrated."],"Underlying token":"Underlying token","Unstake now":"Unstake now","Unstake window":"Unstake window","Unstaked":"Unstaked","Unstaking {symbol}":["Unstaking ",["symbol"]],"Update: Disruptions reported for WETH, WBTC, WMATIC, and USDT. AIP 230 will resolve the disruptions and the market will be operating as normal on ~26th May 13h00 UTC.":"Update: Disruptions reported for WETH, WBTC, WMATIC, and USDT. AIP 230 will resolve the disruptions and the market will be operating as normal on ~26th May 13h00 UTC.","Use it to vote for or against active proposals.":"Use it to vote for or against active proposals.","Use your AAVE and stkAAVE balance to delegate your voting and proposition powers. You will not be sending any tokens, only the rights to vote and propose changes to the protocol. You can re-delegate or revoke power to self at any time.":"Use your AAVE and stkAAVE balance to delegate your voting and proposition powers. You will not be sending any tokens, only the rights to vote and propose changes to the protocol. You can re-delegate or revoke power to self at any time.","Used as collateral":"Used as collateral","User cannot withdraw more than the available balance":"User cannot withdraw more than the available balance","User did not borrow the specified currency":"User did not borrow the specified currency","User does not have outstanding stable rate debt on this reserve":"User does not have outstanding stable rate debt on this reserve","User does not have outstanding variable rate debt on this reserve":"User does not have outstanding variable rate debt on this reserve","User is in isolation mode":"User is in isolation mode","User is trying to borrow multiple assets including a siloed one":"User is trying to borrow multiple assets including a siloed one","Users who stake AAVE in Safety Module (i.e. stkAAVE holders) receive a discount on GHO borrow interest rate. The discount applies to 100 GHO for every 1 stkAAVE held. Use the calculator below to see GHO borrow rate with the discount applied.":"Users who stake AAVE in Safety Module (i.e. stkAAVE holders) receive a discount on GHO borrow interest rate. The discount applies to 100 GHO for every 1 stkAAVE held. Use the calculator below to see GHO borrow rate with the discount applied.","Utilization Rate":"Utilization Rate","VIEW TX":"VIEW TX","VOTE NAY":"VOTE NAY","VOTE YAE":"VOTE YAE","Variable":"Variable","Variable debt supply is not zero":"Variable debt supply is not zero","Variable interest rate will <0>fluctuate based on the market conditions. Recommended for short-term positions.":"Variable interest rate will <0>fluctuate based on the market conditions. Recommended for short-term positions.","Variable rate":"Variable rate","Version 2":"Version 2","Version 3":"Version 3","View":"View","View Transactions":"View Transactions","View all votes":"View all votes","View contract":"View contract","View details":"View details","View on Explorer":"View on Explorer","Vote NAY":"Vote NAY","Vote YAE":"Vote YAE","Voted NAY":"Voted NAY","Voted YAE":"Voted YAE","Votes":"Votes","Voting":"Voting","Voting power":"Voting power","Voting results":"Voting results","Wallet Balance":"Wallet Balance","Wallet balance":"Wallet balance","Wallet not detected. Connect or install wallet and retry":"Wallet not detected. Connect or install wallet and retry","Wallets are provided by External Providers and by selecting you agree to Terms of those Providers. Your access to the wallet might be reliant on the External Provider being operational.":"Wallets are provided by External Providers and by selecting you agree to Terms of those Providers. Your access to the wallet might be reliant on the External Provider being operational.","We couldn't find any assets related to your search. Try again with a different asset name, symbol, or address.":"We couldn't find any assets related to your search. Try again with a different asset name, symbol, or address.","We couldn't find any transactions related to your search. Try again with a different asset name, or reset filters.":"We couldn't find any transactions related to your search. Try again with a different asset name, or reset filters.","We couldn’t detect a wallet. Connect a wallet to stake and view your balance.":"We couldn’t detect a wallet. Connect a wallet to stake and view your balance.","We suggest you go back to the Dashboard.":"We suggest you go back to the Dashboard.","Website":"Website","When a liquidation occurs, liquidators repay up to 50% of the outstanding borrowed amount on behalf of the borrower. In return, they can buy the collateral at a discount and keep the difference (liquidation penalty) as a bonus.":"When a liquidation occurs, liquidators repay up to 50% of the outstanding borrowed amount on behalf of the borrower. In return, they can buy the collateral at a discount and keep the difference (liquidation penalty) as a bonus.","With a voting power of <0/>":"With a voting power of <0/>","With testnet Faucet you can get free assets to test the Aave Protocol. Make sure to switch your wallet provider to the appropriate testnet network, select desired asset, and click ‘Faucet’ to get tokens transferred to your wallet. The assets on a testnet are not “real,” meaning they have no monetary value. <0>Learn more":"With testnet Faucet you can get free assets to test the Aave Protocol. Make sure to switch your wallet provider to the appropriate testnet network, select desired asset, and click ‘Faucet’ to get tokens transferred to your wallet. The assets on a testnet are not “real,” meaning they have no monetary value. <0>Learn more","Withdraw":"Withdraw","Withdraw & Switch":"Withdraw & Switch","Withdraw and Switch":"Withdraw and Switch","Withdraw {symbol}":["Withdraw ",["symbol"]],"Withdrawing":"Withdrawing","Withdrawing and Switching":"Withdrawing and Switching","Withdrawing this amount will reduce your health factor and increase risk of liquidation.":"Withdrawing this amount will reduce your health factor and increase risk of liquidation.","Withdrawing {symbol}":["Withdrawing ",["symbol"]],"Wrong Network":"Wrong Network","YAE":"YAE","You are entering Isolation mode":"You are entering Isolation mode","You can borrow this asset with a stable rate only if you borrow more than the amount you are supplying as collateral.":"You can borrow this asset with a stable rate only if you borrow more than the amount you are supplying as collateral.","You can not change Interest Type to stable as your borrowings are higher than your collateral":"You can not change Interest Type to stable as your borrowings are higher than your collateral","You can not disable E-Mode as your current collateralization level is above 80%, disabling E-Mode can cause liquidation. To exit E-Mode supply or repay borrowed positions.":"You can not disable E-Mode as your current collateralization level is above 80%, disabling E-Mode can cause liquidation. To exit E-Mode supply or repay borrowed positions.","You can not switch usage as collateral mode for this currency, because it will cause collateral call":"You can not switch usage as collateral mode for this currency, because it will cause collateral call","You can not use this currency as collateral":"You can not use this currency as collateral","You can not withdraw this amount because it will cause collateral call":"You can not withdraw this amount because it will cause collateral call","You can only switch to tokens with variable APY types. After this transaction, you may change the variable rate to a stable one if available.":"You can only switch to tokens with variable APY types. After this transaction, you may change the variable rate to a stable one if available.","You can only withdraw your assets from the Security Module after the cooldown period ends and the unstake window is active.":"You can only withdraw your assets from the Security Module after the cooldown period ends and the unstake window is active.","You can report incident to our <0>Discord or<1>Github.":"You can report incident to our <0>Discord or<1>Github.","You cancelled the transaction.":"You cancelled the transaction.","You did not participate in this proposal":"You did not participate in this proposal","You do not have supplies in this currency":"You do not have supplies in this currency","You don’t have enough funds in your wallet to repay the full amount. If you proceed to repay with your current amount of funds, you will still have a small borrowing position in your dashboard.":"You don’t have enough funds in your wallet to repay the full amount. If you proceed to repay with your current amount of funds, you will still have a small borrowing position in your dashboard.","You have no AAVE/stkAAVE balance to delegate.":"You have no AAVE/stkAAVE balance to delegate.","You have not borrow yet using this currency":"You have not borrow yet using this currency","You may borrow up to <0/> GHO at <1/> (max discount)":"You may borrow up to <0/> GHO at <1/> (max discount)","You may enter a custom amount in the field.":"You may enter a custom amount in the field.","You switched to {0} rate":["You switched to ",["0"]," rate"],"You unstake here":"You unstake here","You voted {0}":["You voted ",["0"]],"You will exit isolation mode and other tokens can now be used as collateral":"You will exit isolation mode and other tokens can now be used as collateral","You {action} <0/> {symbol}":["You ",["action"]," <0/> ",["symbol"]],"You've successfully switched borrow position.":"You've successfully switched borrow position.","You've successfully switched tokens.":"You've successfully switched tokens.","You've successfully withdrew & switched tokens.":"You've successfully withdrew & switched tokens.","Your balance is lower than the selected amount.":"Your balance is lower than the selected amount.","Your borrows":"Your borrows","Your current loan to value based on your collateral supplied.":"Your current loan to value based on your collateral supplied.","Your health factor and loan to value determine the assurance of your collateral. To avoid liquidations you can supply more collateral or repay borrow positions.":"Your health factor and loan to value determine the assurance of your collateral. To avoid liquidations you can supply more collateral or repay borrow positions.","Your info":"Your info","Your proposition power is based on your AAVE/stkAAVE balance and received delegations.":"Your proposition power is based on your AAVE/stkAAVE balance and received delegations.","Your reward balance is 0":"Your reward balance is 0","Your supplies":"Your supplies","Your voting info":"Your voting info","Your voting power is based on your AAVE/stkAAVE balance and received delegations.":"Your voting power is based on your AAVE/stkAAVE balance and received delegations.","Your {name} wallet is empty. Purchase or transfer assets or use <0>{0} to transfer your {network} assets.":["Your ",["name"]," wallet is empty. Purchase or transfer assets or use <0>",["0"]," to transfer your ",["network"]," assets."],"Your {name} wallet is empty. Purchase or transfer assets.":["Your ",["name"]," wallet is empty. Purchase or transfer assets."],"Your {networkName} wallet is empty. Get free test assets at":["Your ",["networkName"]," wallet is empty. Get free test assets at"],"Your {networkName} wallet is empty. Get free test {0} at":["Your ",["networkName"]," wallet is empty. Get free test ",["0"]," at"],"Zero address not valid":"Zero address not valid","assets":"assets","blocked activities":"blocked activities","copy the error":"copy the error","disabled":"disabled","documentation":"documentation","enabled":"enabled","ends":"ends","for":"for","of":"of","on":"on","please check that the amount you want to supply is not currently being used for staking. If it is being used for staking, your transaction might fail.":"please check that the amount you want to supply is not currently being used for staking. If it is being used for staking, your transaction might fail.","repaid":"repaid","stETH supplied as collateral will continue to accrue staking rewards provided by daily rebases.":"stETH supplied as collateral will continue to accrue staking rewards provided by daily rebases.","stETH tokens will be migrated to Wrapped stETH using Lido Protocol wrapper which leads to supply balance change after migration: {0}":["stETH tokens will be migrated to Wrapped stETH using Lido Protocol wrapper which leads to supply balance change after migration: ",["0"]],"staking view":"staking view","starts":"starts","stkAAVE holders get a discount on GHO borrow rate":"stkAAVE holders get a discount on GHO borrow rate","to":"to","tokens is not the same as staking them. If you wish to stake your":"tokens is not the same as staking them. If you wish to stake your","tokens, please go to the":"tokens, please go to the","withdrew":"withdrew","{0}":[["0"]],"{0} Balance":[["0"]," Balance"],"{0} Faucet":[["0"]," Faucet"],"{0} on-ramp service is provided by External Provider and by selecting you agree to Terms of the Provider. Your access to the service might be reliant on the External Provider being operational.":[["0"]," on-ramp service is provided by External Provider and by selecting you agree to Terms of the Provider. Your access to the service might be reliant on the External Provider being operational."],"{0}{name}":[["0"],["name"]],"{currentMethod}":[["currentMethod"]],"{d}d":[["d"],"d"],"{h}h":[["h"],"h"],"{m}m":[["m"],"m"],"{networkName} Faucet":[["networkName"]," Faucet"],"{notifyText}":[["notifyText"]],"{numSelected}/{numAvailable} assets selected":[["numSelected"],"/",["numAvailable"]," assets selected"],"{s}s":[["s"],"s"],"{title}":[["title"]],"{tooltipText}":[["tooltipText"]]}}; \ No newline at end of file diff --git a/src/locales/en/messages.po b/src/locales/en/messages.po index a138c5dfeb..98842276ac 100644 --- a/src/locales/en/messages.po +++ b/src/locales/en/messages.po @@ -791,11 +791,14 @@ msgstr "Current v2 balance" msgid "Current votes" msgstr "Current votes" -#: src/components/infoTooltips/WrappedTokenToolTipContent.tsx #: src/components/transactions/Supply/SupplyModalContent.tsx msgid "DAI balance will be converted via DSR contracts and then supplied as sDAI to Aave reserve. Switching incurs no additional costs and no slippage." msgstr "DAI balance will be converted via DSR contracts and then supplied as sDAI to Aave reserve. Switching incurs no additional costs and no slippage." +#: src/components/infoTooltips/WrappedTokenToolTipContent.tsx +msgid "DAI balance will be converted via DSR contracts and then supplied as sDAI. Switching incurs no additional costs and no slippage." +msgstr "DAI balance will be converted via DSR contracts and then supplied as sDAI. Switching incurs no additional costs and no slippage." + #: src/layouts/components/DarkModeSwitcher.tsx msgid "Dark mode" msgstr "Dark mode" From ba05a5562752dff8b7b93f5e0e5d26b5622098a2 Mon Sep 17 00:00:00 2001 From: Mark Grothe Date: Wed, 1 Nov 2023 16:39:19 -0500 Subject: [PATCH 31/46] feat: wrapped token mobile views --- src/locales/en/messages.po | 6 + .../SupplyAssetsList/SupplyAssetsList.tsx | 7 +- .../SupplyAssetsList/SupplyAssetsListItem.tsx | 228 ++++++++++++++++-- 3 files changed, 219 insertions(+), 22 deletions(-) diff --git a/src/locales/en/messages.po b/src/locales/en/messages.po index 98842276ac..6a878ea3b4 100644 --- a/src/locales/en/messages.po +++ b/src/locales/en/messages.po @@ -597,6 +597,7 @@ msgid "COPY IMAGE" msgstr "COPY IMAGE" #: src/modules/dashboard/lists/SupplyAssetsList/SupplyAssetsList.tsx +#: src/modules/dashboard/lists/SupplyAssetsList/SupplyAssetsListItem.tsx #: src/modules/dashboard/lists/SupplyAssetsList/SupplyAssetsListMobileItem.tsx #: src/modules/reserve-overview/SupplyInfo.tsx msgid "Can be collateral" @@ -838,6 +839,7 @@ msgstr "Delegated power" #: src/modules/dashboard/lists/BorrowAssetsList/BorrowAssetsListMobileItem.tsx #: src/modules/dashboard/lists/BorrowAssetsList/GhoBorrowAssetsListItem.tsx #: src/modules/dashboard/lists/BorrowAssetsList/GhoBorrowAssetsListItem.tsx +#: src/modules/dashboard/lists/SupplyAssetsList/SupplyAssetsListItem.tsx #: src/modules/dashboard/lists/SupplyAssetsList/SupplyAssetsListMobileItem.tsx #: src/modules/markets/MarketAssetsListItem.tsx msgid "Details" @@ -2194,6 +2196,7 @@ msgstr "Supplied asset amount" #: src/modules/dashboard/lists/SuppliedPositionsList/SuppliedPositionsListItem.tsx #: src/modules/dashboard/lists/SuppliedPositionsList/SuppliedPositionsListMobileItem.tsx #: src/modules/dashboard/lists/SupplyAssetsList/SupplyAssetsListItem.tsx +#: src/modules/dashboard/lists/SupplyAssetsList/SupplyAssetsListItem.tsx #: src/modules/dashboard/lists/SupplyAssetsList/SupplyAssetsListMobileItem.tsx #: src/modules/history/HistoryFilterMenu.tsx #: src/modules/history/actions/ActionDetails.tsx @@ -2204,6 +2207,7 @@ msgstr "Supply" #: src/components/transactions/Supply/SupplyModalContent.tsx #: src/components/transactions/Supply/SupplyModalContent.tsx #: src/modules/dashboard/lists/SuppliedPositionsList/SuppliedPositionsListMobileItem.tsx +#: src/modules/dashboard/lists/SupplyAssetsList/SupplyAssetsListItem.tsx #: src/modules/dashboard/lists/SupplyAssetsList/SupplyAssetsListMobileItem.tsx #: src/modules/markets/MarketAssetsList.tsx #: src/modules/markets/MarketAssetsListMobileItem.tsx @@ -2222,6 +2226,8 @@ msgstr "Supply apy" #: src/components/transactions/Withdraw/WithdrawAndSwitchModalContent.tsx #: src/components/transactions/Withdraw/WithdrawModalContent.tsx #: src/modules/dashboard/lists/SuppliedPositionsList/SuppliedPositionsListMobileItem.tsx +#: src/modules/dashboard/lists/SupplyAssetsList/SupplyAssetsListItem.tsx +#: src/modules/dashboard/lists/SupplyAssetsList/SupplyAssetsListItem.tsx #: src/modules/dashboard/lists/SupplyAssetsList/SupplyAssetsListMobileItem.tsx msgid "Supply balance" msgstr "Supply balance" diff --git a/src/modules/dashboard/lists/SupplyAssetsList/SupplyAssetsList.tsx b/src/modules/dashboard/lists/SupplyAssetsList/SupplyAssetsList.tsx index ba8d4c2bbc..716bf51be6 100644 --- a/src/modules/dashboard/lists/SupplyAssetsList/SupplyAssetsList.tsx +++ b/src/modules/dashboard/lists/SupplyAssetsList/SupplyAssetsList.tsx @@ -29,7 +29,6 @@ import { DashboardListTopPanel } from '../../DashboardListTopPanel'; import { ListButtonsColumn } from '../ListButtonsColumn'; import { ListLoader } from '../ListLoader'; import { SupplyAssetsListItem } from './SupplyAssetsListItem'; -import { SupplyAssetsListMobileItem } from './SupplyAssetsListMobileItem'; import { WalletEmptyInfo } from './WalletEmptyInfo'; const head = [ @@ -299,11 +298,7 @@ export const SupplyAssetsList = () => { {sortedReserves.map((item) => ( - {downToXSM ? ( - - ) : ( - - )} + ))} diff --git a/src/modules/dashboard/lists/SupplyAssetsList/SupplyAssetsListItem.tsx b/src/modules/dashboard/lists/SupplyAssetsList/SupplyAssetsListItem.tsx index d6d9fbf145..8270c7c9cb 100644 --- a/src/modules/dashboard/lists/SupplyAssetsList/SupplyAssetsListItem.tsx +++ b/src/modules/dashboard/lists/SupplyAssetsList/SupplyAssetsListItem.tsx @@ -1,17 +1,30 @@ import { SwitchHorizontalIcon } from '@heroicons/react/outline'; import { EyeIcon } from '@heroicons/react/solid'; import { Trans } from '@lingui/macro'; -import { Box, Button, ListItemText, Menu, MenuItem, Stack, SvgIcon } from '@mui/material'; +import { + Box, + Button, + ListItemText, + Menu, + MenuItem, + Stack, + SvgIcon, + useMediaQuery, + useTheme, +} from '@mui/material'; import { useState } from 'react'; import { ContentWithTooltip } from 'src/components/ContentWithTooltip'; +import { IncentivesCard } from 'src/components/incentives/IncentivesCard'; import { WrappedTokenTooltipContent } from 'src/components/infoTooltips/WrappedTokenToolTipContent'; import { FormattedNumber } from 'src/components/primitives/FormattedNumber'; import { NoData } from 'src/components/primitives/NoData'; +import { Row } from 'src/components/primitives/Row'; import { TokenIcon } from 'src/components/primitives/TokenIcon'; import { useAppDataContext } from 'src/hooks/app-data-provider/useAppDataProvider'; import { useWalletBalances } from 'src/hooks/app-data-provider/useWalletBalances'; import { useAssetCaps } from 'src/hooks/useAssetCaps'; import { useModalContext } from 'src/hooks/useModal'; +import { useProtocolDataContext } from 'src/hooks/useProtocolDataContext'; import { useRootStore } from 'src/store/root'; import { DashboardReserve } from 'src/utils/dashboardSortUtils'; import { isFeatureEnabled } from 'src/utils/marketsAndNetworksConfig'; @@ -25,9 +38,53 @@ import { ListAPRColumn } from '../ListAPRColumn'; import { ListButtonsColumn } from '../ListButtonsColumn'; import { ListItemCanBeCollateral } from '../ListItemCanBeCollateral'; import { ListItemWrapper } from '../ListItemWrapper'; +import { ListMobileItemWrapper } from '../ListMobileItemWrapper'; import { ListValueColumn } from '../ListValueColumn'; +import { ListValueRow } from '../ListValueRow'; -export const SupplyAssetsListItem = ({ +export const SupplyAssetsListItem = (params: DashboardReserve) => { + const theme = useTheme(); + const downToXSM = useMediaQuery(theme.breakpoints.down('xsm')); + const { supplyCap } = useAssetCaps(); + const { wrappedTokenReserves } = useAppDataContext(); + const currentMarketData = useRootStore((store) => store.currentMarketData); + const { walletBalances } = useWalletBalances(currentMarketData); + + const { isActive, isFreezed, walletBalance, underlyingAsset } = params; + + const wrappedToken = wrappedTokenReserves.find( + (r) => r.tokenOut.underlyingAsset === underlyingAsset + ); + + const canSupplyAsWrappedToken = + wrappedToken && + walletBalances[wrappedToken.tokenIn.underlyingAsset.toLowerCase()].amount !== '0'; + + const disableSupply = + !isActive || + isFreezed || + (Number(walletBalance) <= 0 && !canSupplyAsWrappedToken) || + supplyCap.isMaxed; + + const props: SupplyAssetsListItemProps = { + ...params, + disableSupply, + canSupplyAsWrappedToken: canSupplyAsWrappedToken ?? false, + }; + + if (downToXSM) { + return ; + } else { + return ; + } +}; + +interface SupplyAssetsListItemProps extends DashboardReserve { + disableSupply: boolean; + canSupplyAsWrappedToken: boolean; +} + +export const SupplyAssetsListItemDesktop = ({ symbol, iconSymbol, name, @@ -38,12 +95,12 @@ export const SupplyAssetsListItem = ({ supplyAPY, aIncentivesData, underlyingAsset, - isActive, - isFreezed, isIsolated, usageAsCollateralEnabledOnUser, detailsAddress, -}: DashboardReserve) => { + disableSupply, + canSupplyAsWrappedToken, +}: SupplyAssetsListItemProps) => { const currentMarketData = useRootStore((store) => store.currentMarketData); const currentMarket = useRootStore((store) => store.currentMarket); const { wrappedTokenReserves } = useAppDataContext(); @@ -69,16 +126,6 @@ export const SupplyAssetsListItem = ({ (r) => r.tokenOut.underlyingAsset === underlyingAsset ); - const canSupplyAsWrappedToken = - wrappedToken && - walletBalances[wrappedToken.tokenIn.underlyingAsset.toLowerCase()].amount !== '0'; - - const disableSupply = - !isActive || - isFreezed || - (Number(walletBalance) <= 0 && !canSupplyAsWrappedToken) || - isMaxCapReached; - const onDetailsClick = () => { trackEvent(DASHBOARD.DETAILS_NAVIGATION, { type: 'Button', @@ -104,7 +151,7 @@ export const SupplyAssetsListItem = ({ currentMarket={currentMarket} showDebtCeilingTooltips > - {canSupplyAsWrappedToken && walletBalance === '0' ? ( + {canSupplyAsWrappedToken && wrappedToken && walletBalance === '0' ? ( ); }; + +export const SupplyAssetsListItemMobile = ({ + symbol, + iconSymbol, + name, + walletBalance, + walletBalanceUSD, + supplyCap, + totalLiquidity, + supplyAPY, + aIncentivesData, + isIsolated, + usageAsCollateralEnabledOnUser, + underlyingAsset, + detailsAddress, + disableSupply, + canSupplyAsWrappedToken, +}: SupplyAssetsListItemProps) => { + const { currentMarket } = useProtocolDataContext(); + const { openSupply } = useModalContext(); + const { wrappedTokenReserves } = useAppDataContext(); + const currentMarketData = useRootStore((store) => store.currentMarketData); + const { walletBalances } = useWalletBalances(currentMarketData); + + // Disable the asset to prevent it from being supplied if supply cap has been reached + const { supplyCap: supplyCapUsage } = useAssetCaps(); + const isMaxCapReached = supplyCapUsage.isMaxed; + + const wrappedToken = wrappedTokenReserves.find( + (r) => r.tokenOut.underlyingAsset === underlyingAsset + ); + + return ( + + {canSupplyAsWrappedToken && wrappedToken && walletBalance === '0' ? ( + Supply balance} + align="flex-start" + captionVariant="description" + mb={2} + > + + } + > + + + + + + + + + + ) : ( + Supply balance} + value={Number(walletBalance)} + subValue={walletBalanceUSD} + disabled={Number(walletBalance) === 0 || isMaxCapReached} + capsComponent={ + + } + /> + )} + + Supply APY} + align="flex-start" + captionVariant="description" + mb={2} + > + + + + Can be collateral} + align="flex-start" + captionVariant="description" + mb={2} + > + + + + + + + + + ); +}; From 7626a3b1349abb73af454302c20a0bebc5a56da7 Mon Sep 17 00:00:00 2001 From: Mark Grothe Date: Thu, 2 Nov 2023 09:15:24 -0500 Subject: [PATCH 32/46] feat: wrapped config --- src/ui-config/wrappedTokenConfig.ts | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/ui-config/wrappedTokenConfig.ts b/src/ui-config/wrappedTokenConfig.ts index 65afc9cd1f..d3cf397bc2 100644 --- a/src/ui-config/wrappedTokenConfig.ts +++ b/src/ui-config/wrappedTokenConfig.ts @@ -25,5 +25,16 @@ export const wrappedTokenConfig: { [chainId: number]: WrappedTokenConfig[] } = { }, tokenWrapperContractAddress: '0x437f428930669cd06adab2df4a8d4b203ac729c6', }, + { + tokenIn: { + underlyingAsset: '0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84'.toLowerCase(), + symbol: 'stETH', + }, + tokenOut: { + underlyingAsset: '0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0'.toLowerCase(), + symbol: 'wstETH', + }, + tokenWrapperContractAddress: '0x14aa09449fac437b5c0110614be2c08610e38f62', + }, ], }; From e0f1a14e25e4b776d34a90d5255fdd5251f7c79c Mon Sep 17 00:00:00 2001 From: Mark Grothe Date: Fri, 3 Nov 2023 10:47:07 -0500 Subject: [PATCH 33/46] WIP fetcing reserve info cross market --- .../WrappedTokenToolTipContent.tsx | 8 +-- .../Supply/SupplyModalContent.tsx | 54 +++---------------- .../app-data-provider/useAppDataProvider.tsx | 10 ++-- .../app-data-provider/useWalletBalances.tsx | 7 +++ src/hooks/token-wrapper/useTokenWrapper.ts | 20 +++++++ .../SupplyAssetsList/SupplyAssetsList.tsx | 3 ++ src/services/WalletBalanceService.ts | 14 ++++- src/ui-config/wrappedTokenConfig.ts | 2 + 8 files changed, 62 insertions(+), 56 deletions(-) diff --git a/src/components/infoTooltips/WrappedTokenToolTipContent.tsx b/src/components/infoTooltips/WrappedTokenToolTipContent.tsx index 1a9ac28c86..d8820c019e 100644 --- a/src/components/infoTooltips/WrappedTokenToolTipContent.tsx +++ b/src/components/infoTooltips/WrappedTokenToolTipContent.tsx @@ -1,7 +1,7 @@ import { ArrowNarrowRightIcon } from '@heroicons/react/solid'; import { Trans } from '@lingui/macro'; import { Box, Skeleton, Stack, SvgIcon, Typography } from '@mui/material'; -import { useTokenInForTokenOut } from 'src/hooks/token-wrapper/useTokenWrapper'; +import { useTokenOutForTokenIn } from 'src/hooks/token-wrapper/useTokenWrapper'; import { FormattedNumber } from '../primitives/FormattedNumber'; @@ -16,7 +16,7 @@ export const WrappedTokenTooltipContent = ({ tokenInSymbol: string; tokenOutSymbol: string; }) => { - const { isFetching: loadingExchangeRate, data: exchangeRate } = useTokenInForTokenOut( + const { isFetching: loadingExchangeRate, data: exchangeRate } = useTokenOutForTokenIn( '1', decimals, tokenWrapperAddress @@ -46,7 +46,7 @@ export const WrappedTokenTooltipContent = ({ variant="secondary12" color="text.primary" /> - {tokenOutSymbol} + {tokenInSymbol} @@ -56,7 +56,7 @@ export const WrappedTokenTooltipContent = ({ variant="secondary12" color="text.primary" /> - {tokenInSymbol} + {tokenOutSymbol} )} diff --git a/src/components/transactions/Supply/SupplyModalContent.tsx b/src/components/transactions/Supply/SupplyModalContent.tsx index 0bc0cd9752..35d077977f 100644 --- a/src/components/transactions/Supply/SupplyModalContent.tsx +++ b/src/components/transactions/Supply/SupplyModalContent.tsx @@ -1,10 +1,10 @@ import { API_ETH_MOCK_ADDRESS } from '@aave/contract-helpers'; import { USD_DECIMALS, valueToBigNumber } from '@aave/math-utils'; -import { ArrowNarrowRightIcon } from '@heroicons/react/solid'; import { Trans } from '@lingui/macro'; -import { Box, Skeleton, Stack, SvgIcon, Typography } from '@mui/material'; +import { Skeleton, Stack, Typography } from '@mui/material'; import BigNumber from 'bignumber.js'; import React, { useEffect, useState } from 'react'; +import { WrappedTokenTooltipContent } from 'src/components/infoTooltips/WrappedTokenToolTipContent'; import { FormattedNumber } from 'src/components/primitives/FormattedNumber'; import { TokenIcon } from 'src/components/primitives/TokenIcon'; import { Warning } from 'src/components/primitives/Warning'; @@ -480,12 +480,6 @@ const ExchangeRate = ({ tokenOutSymbol: string; tokenWrapperAddress: string; }) => { - const { isFetching: loadingExchangeRate, data: exchangeRate } = useTokenInForTokenOut( - '1', - decimals, - tokenWrapperAddress - ); - const { isFetching: loading, data: tokenOutAmount } = useTokenOutForTokenIn( supplyAmount, decimals, @@ -514,44 +508,12 @@ const ExchangeRate = ({ )} - - - - DAI balance will be converted via DSR contracts and then supplied as sDAI to Aave - reserve. Switching incurs no additional costs and no slippage. - - - - - - Exchange rate - - - {loadingExchangeRate ? ( - - ) : ( - - - {tokenOutSymbol} - - - - - {tokenInSymbol} - - )} - - + ); diff --git a/src/hooks/app-data-provider/useAppDataProvider.tsx b/src/hooks/app-data-provider/useAppDataProvider.tsx index c329498b8a..63b06a3661 100644 --- a/src/hooks/app-data-provider/useAppDataProvider.tsx +++ b/src/hooks/app-data-provider/useAppDataProvider.tsx @@ -270,16 +270,16 @@ export const AppDataProvider: React.FC = ({ children }) => { (userReserve) => userReserve.underlyingAsset === config.tokenOut.underlyingAsset ); - if (!tokenInReserve || !tokenOutReserve) { + if (!tokenOutReserve) { throw new Error('no wrapped token reserves'); } return { tokenIn: { - symbol: tokenInReserve.reserve.symbol, - underlyingAsset: tokenInReserve.reserve.underlyingAsset, - decimals: tokenInReserve.reserve.decimals, - priceInUSD: tokenInReserve.reserve.priceInUSD, + symbol: config.tokenIn.symbol, + underlyingAsset: config.tokenIn.underlyingAsset, + decimals: 18, + priceInUSD: tokenOutReserve.reserve.priceInUSD, }, tokenOut: { symbol: tokenOutReserve.reserve.symbol, diff --git a/src/hooks/app-data-provider/useWalletBalances.tsx b/src/hooks/app-data-provider/useWalletBalances.tsx index efe38b220a..12763e66c2 100644 --- a/src/hooks/app-data-provider/useWalletBalances.tsx +++ b/src/hooks/app-data-provider/useWalletBalances.tsx @@ -97,3 +97,10 @@ export const useWalletBalances = (marketData: MarketDataType) => { loading: isLoading, }; }; + +// export const useWrappedTokenInBalances = (wrappedTokenConfig: WrappedTokenConfig[]) => { +// const foo = useTokenInBalances(wrappedTokenConfig); +// return { +// balances: foo. +// } +// } diff --git a/src/hooks/token-wrapper/useTokenWrapper.ts b/src/hooks/token-wrapper/useTokenWrapper.ts index 4b32b3f5ec..8b05f08a8c 100644 --- a/src/hooks/token-wrapper/useTokenWrapper.ts +++ b/src/hooks/token-wrapper/useTokenWrapper.ts @@ -1,8 +1,12 @@ import { useQuery } from '@tanstack/react-query'; import { BigNumber } from 'ethers'; import { formatUnits, parseUnits } from 'ethers/lib/utils'; +import { useRootStore } from 'src/store/root'; +import { POLLING_INTERVAL } from 'src/ui-config/queries'; import { useSharedDependencies } from 'src/ui-config/SharedDependenciesProvider'; +import { WrappedTokenConfig } from '../app-data-provider/useAppDataProvider'; + export const useTokenInForTokenOut = ( amount: string, decimals: number, @@ -48,3 +52,19 @@ export const useTokenOutForTokenIn = ( refetchOnMount: false, }); }; + +export const useTokenInBalances = (wrappedTokenConfig: WrappedTokenConfig[]) => { + const { poolTokensBalanceService } = useSharedDependencies(); + const currentMarketData = useRootStore((store) => store.currentMarketData); + const user = useRootStore((store) => store.account); + + const tokenInAddresses = wrappedTokenConfig.map((token) => token.tokenIn.underlyingAsset); + + return useQuery({ + queryFn: () => + poolTokensBalanceService.getWrappedTokenInBalances(tokenInAddresses, currentMarketData, user), + queryKey: [tokenInAddresses, user], + enabled: !!user, + refetchInterval: POLLING_INTERVAL, + }); +}; diff --git a/src/modules/dashboard/lists/SupplyAssetsList/SupplyAssetsList.tsx b/src/modules/dashboard/lists/SupplyAssetsList/SupplyAssetsList.tsx index 716bf51be6..2dda4bc184 100644 --- a/src/modules/dashboard/lists/SupplyAssetsList/SupplyAssetsList.tsx +++ b/src/modules/dashboard/lists/SupplyAssetsList/SupplyAssetsList.tsx @@ -9,6 +9,7 @@ import { ListHeaderTitle } from 'src/components/lists/ListHeaderTitle'; import { ListHeaderWrapper } from 'src/components/lists/ListHeaderWrapper'; import { Warning } from 'src/components/primitives/Warning'; import { MarketWarning } from 'src/components/transactions/Warnings/MarketWarning'; +import { useTokenInBalances } from 'src/hooks/token-wrapper/useTokenWrapper'; import { AssetCapsProvider } from 'src/hooks/useAssetCaps'; import { useRootStore } from 'src/store/root'; import { fetchIconSymbolAndName } from 'src/ui-config/reservePatches'; @@ -53,6 +54,8 @@ export const SupplyAssetsList = () => { loading: loadingReserves, wrappedTokenReserves, } = useAppDataContext(); + const foo = useTokenInBalances(wrappedTokenReserves); + console.log('FOOOO', foo.data); const { walletBalances, loading } = useWalletBalances(currentMarketData); const [displayGho] = useRootStore((store) => [store.displayGho]); const theme = useTheme(); diff --git a/src/services/WalletBalanceService.ts b/src/services/WalletBalanceService.ts index 3e84f364f8..0c68bc4fb2 100644 --- a/src/services/WalletBalanceService.ts +++ b/src/services/WalletBalanceService.ts @@ -1,4 +1,4 @@ -import { WalletBalanceProvider } from '@aave/contract-helpers'; +import { BatchBalanceOfResponse, WalletBalanceProvider } from '@aave/contract-helpers'; import { normalize } from '@aave/math-utils'; import { Provider } from '@ethersproject/providers'; import { governanceConfig } from 'src/ui-config/governanceConfig'; @@ -62,4 +62,16 @@ export class WalletBalanceService { })); return mappedBalances; } + + async getWrappedTokenInBalances( + tokenInAddresses: string[], + marketData: MarketDataType, + user: string + ): Promise { + console.log('token in', tokenInAddresses); + const walletBalanceService = this.getWalletBalanceService(marketData); + const balances = await walletBalanceService.batchBalanceOf([user], tokenInAddresses); + console.log('balances', balances); + return balances; + } } diff --git a/src/ui-config/wrappedTokenConfig.ts b/src/ui-config/wrappedTokenConfig.ts index d3cf397bc2..e3f1430be7 100644 --- a/src/ui-config/wrappedTokenConfig.ts +++ b/src/ui-config/wrappedTokenConfig.ts @@ -9,6 +9,7 @@ interface WrappedTokenConfig { interface Token { underlyingAsset: string; symbol: string; + decimals?: number; } // TODO: need to consider v2/v3 markets @@ -27,6 +28,7 @@ export const wrappedTokenConfig: { [chainId: number]: WrappedTokenConfig[] } = { }, { tokenIn: { + decimals: 18, underlyingAsset: '0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84'.toLowerCase(), symbol: 'stETH', }, From 3dfeb9fe90190937c99e7ad97c10f9dfaf0a9db9 Mon Sep 17 00:00:00 2001 From: Mark Grothe Date: Tue, 21 Nov 2023 16:38:38 -0600 Subject: [PATCH 34/46] feat: cleaning up token wrapping --- .../Supply/SupplyModalContent.tsx | 28 +++++++++++-------- .../Supply/SupplyWrappedTokenActions.tsx | 6 ++-- .../app-data-provider/useAppDataProvider.tsx | 13 ++++++--- src/hooks/token-wrapper/useTokenWrapper.ts | 20 ------------- src/locales/en/messages.js | 2 +- src/locales/en/messages.po | 5 ---- .../SupplyAssetsList/SupplyAssetsList.tsx | 3 -- src/ui-config/marketsConfig.tsx | 2 -- src/ui-config/wrappedTokenConfig.ts | 15 +--------- 9 files changed, 31 insertions(+), 63 deletions(-) diff --git a/src/components/transactions/Supply/SupplyModalContent.tsx b/src/components/transactions/Supply/SupplyModalContent.tsx index 35d077977f..3b9c7f8095 100644 --- a/src/components/transactions/Supply/SupplyModalContent.tsx +++ b/src/components/transactions/Supply/SupplyModalContent.tsx @@ -274,6 +274,7 @@ export const SupplyWrappedTokenModalContent = ({ debtCeilingWarning, addTokenProps, collateralType, + isWrongNetwork, }: SupplyModalContentProps) => { const { marketReferencePriceInUsd, user } = useAppDataContext(); const { currentMarketData } = useProtocolDataContext(); @@ -311,19 +312,16 @@ export const SupplyWrappedTokenModalContent = ({ const [tokenToSupply, setTokenToSupply] = useState(assets[0]); const [amount, setAmount] = useState(''); const [convertedTokenInAmount, setConvertedTokenInAmount] = useState('0'); - const { isFetching: loadingExchangeRate, data: exchangeRate } = useTokenInForTokenOut( + const { data: exchangeRate } = useTokenInForTokenOut( '1', poolReserve.decimals, wrappedTokenConfig.tokenWrapperAddress ); - console.log('loadingExchangeRate', loadingExchangeRate); - useEffect(() => { if (!exchangeRate) return; const convertedAmount = valueToBigNumber(tokenInBalance).multipliedBy(exchangeRate).toString(); setConvertedTokenInAmount(convertedAmount); - console.log('convertedAmount', convertedAmount); }, [exchangeRate, tokenInBalance]); const { supplyCap, totalLiquidity, isFrozen, decimals, debtCeiling, isolationModeTotalDebt } = @@ -348,8 +346,6 @@ export const SupplyWrappedTokenModalContent = ({ .toString(); } - console.log(maxAmountOfTokenInToSupply); - let supplyingWrappedToken = false; if (wrappedTokenConfig) { supplyingWrappedToken = tokenToSupply.address === wrappedTokenConfig.tokenIn.underlyingAsset; @@ -369,7 +365,9 @@ export const SupplyWrappedTokenModalContent = ({ }; const amountInEth = new BigNumber(amount).multipliedBy( - poolReserve.formattedPriceInMarketReferenceCurrency + supplyingWrappedToken + ? wrappedTokenConfig.tokenIn.formattedPriceInMarketReferenceCurrency + : poolReserve.formattedPriceInMarketReferenceCurrency ); const amountInUsd = amountInEth.multipliedBy(marketReferencePriceInUsd).shiftedBy(-USD_DECIMALS); @@ -378,15 +376,22 @@ export const SupplyWrappedTokenModalContent = ({ const healfthFactorAfterSupply = calculateHFAfterSupply(user, poolReserve, amountInEth); - if (supplyTxState.success) + if (supplyTxState.success) { + const successModalAmount = supplyingWrappedToken + ? BigNumber(amount) + .multipliedBy(exchangeRate || '1') + .toString() + : amount; + return ( Supplied} - amount={amount} + amount={successModalAmount} symbol={poolReserve.symbol} addToken={addTokenProps} /> ); + } return ( <> @@ -451,10 +456,11 @@ export const SupplyWrappedTokenModalContent = ({ amountToSupply={amount} decimals={18} symbol={wrappedTokenConfig.tokenIn.symbol} + isWrongNetwork={isWrongNetwork} /> ) : ( Supply amount diff --git a/src/components/transactions/Supply/SupplyWrappedTokenActions.tsx b/src/components/transactions/Supply/SupplyWrappedTokenActions.tsx index 0a62f2e2e1..c4d73f4dfc 100644 --- a/src/components/transactions/Supply/SupplyWrappedTokenActions.tsx +++ b/src/components/transactions/Supply/SupplyWrappedTokenActions.tsx @@ -32,6 +32,7 @@ interface SupplyWrappedTokenActionProps extends BoxProps { decimals: number; symbol: string; tokenWrapperAddress: string; + isWrongNetwork: boolean; } export const SupplyWrappedTokenActions = ({ tokenIn, @@ -39,6 +40,7 @@ export const SupplyWrappedTokenActions = ({ decimals, symbol, tokenWrapperAddress, + isWrongNetwork, sx, ...props }: SupplyWrappedTokenActionProps) => { @@ -187,7 +189,7 @@ export const SupplyWrappedTokenActions = ({ blocked={false} // TODO mainTxState={mainTxState} approvalTxState={approvalTxState} - isWrongNetwork={false} // TODO + isWrongNetwork={isWrongNetwork} requiresAmount amount={amountToSupply} symbol={symbol} @@ -197,7 +199,7 @@ export const SupplyWrappedTokenActions = ({ handleApproval={() => approvalAction()} handleAction={action} requiresApproval={requiresApproval} - tryPermit={usePermit} + tryPermit sx={sx} {...props} /> diff --git a/src/hooks/app-data-provider/useAppDataProvider.tsx b/src/hooks/app-data-provider/useAppDataProvider.tsx index 63b06a3661..e275f67377 100644 --- a/src/hooks/app-data-provider/useAppDataProvider.tsx +++ b/src/hooks/app-data-provider/useAppDataProvider.tsx @@ -64,6 +64,7 @@ export type WrappedToken = { underlyingAsset: string; decimals: number; priceInUSD: string; + formattedPriceInMarketReferenceCurrency: string; }; export type WrappedTokenConfig = { @@ -270,22 +271,26 @@ export const AppDataProvider: React.FC = ({ children }) => { (userReserve) => userReserve.underlyingAsset === config.tokenOut.underlyingAsset ); - if (!tokenOutReserve) { - throw new Error('no wrapped token reserves'); + if (!tokenInReserve || !tokenOutReserve) { + throw new Error('wrapped token reserves not found'); } return { tokenIn: { symbol: config.tokenIn.symbol, underlyingAsset: config.tokenIn.underlyingAsset, - decimals: 18, - priceInUSD: tokenOutReserve.reserve.priceInUSD, + decimals: tokenInReserve.reserve.decimals, + priceInUSD: tokenInReserve.reserve.priceInUSD, + formattedPriceInMarketReferenceCurrency: + tokenInReserve.reserve.formattedPriceInMarketReferenceCurrency, }, tokenOut: { symbol: tokenOutReserve.reserve.symbol, underlyingAsset: tokenOutReserve.reserve.underlyingAsset, decimals: tokenOutReserve.reserve.decimals, priceInUSD: tokenOutReserve.reserve.priceInUSD, + formattedPriceInMarketReferenceCurrency: + tokenOutReserve.reserve.formattedPriceInMarketReferenceCurrency, }, tokenWrapperAddress: config.tokenWrapperContractAddress, }; diff --git a/src/hooks/token-wrapper/useTokenWrapper.ts b/src/hooks/token-wrapper/useTokenWrapper.ts index 8b05f08a8c..4b32b3f5ec 100644 --- a/src/hooks/token-wrapper/useTokenWrapper.ts +++ b/src/hooks/token-wrapper/useTokenWrapper.ts @@ -1,12 +1,8 @@ import { useQuery } from '@tanstack/react-query'; import { BigNumber } from 'ethers'; import { formatUnits, parseUnits } from 'ethers/lib/utils'; -import { useRootStore } from 'src/store/root'; -import { POLLING_INTERVAL } from 'src/ui-config/queries'; import { useSharedDependencies } from 'src/ui-config/SharedDependenciesProvider'; -import { WrappedTokenConfig } from '../app-data-provider/useAppDataProvider'; - export const useTokenInForTokenOut = ( amount: string, decimals: number, @@ -52,19 +48,3 @@ export const useTokenOutForTokenIn = ( refetchOnMount: false, }); }; - -export const useTokenInBalances = (wrappedTokenConfig: WrappedTokenConfig[]) => { - const { poolTokensBalanceService } = useSharedDependencies(); - const currentMarketData = useRootStore((store) => store.currentMarketData); - const user = useRootStore((store) => store.account); - - const tokenInAddresses = wrappedTokenConfig.map((token) => token.tokenIn.underlyingAsset); - - return useQuery({ - queryFn: () => - poolTokensBalanceService.getWrappedTokenInBalances(tokenInAddresses, currentMarketData, user), - queryKey: [tokenInAddresses, user], - enabled: !!user, - refetchInterval: POLLING_INTERVAL, - }); -}; diff --git a/src/locales/en/messages.js b/src/locales/en/messages.js index 19d820bbcd..c0e161c18f 100644 --- a/src/locales/en/messages.js +++ b/src/locales/en/messages.js @@ -1 +1 @@ -/*eslint-disable*/module.exports={messages:{"...":"...",".CSV":".CSV",".JSON":".JSON","<0><1><2/>Add <3/> stkAAVE to borrow at <4/> (max discount)":"<0><1><2/>Add <3/> stkAAVE to borrow at <4/> (max discount)","<0><1><2/>Add stkAAVE to see borrow rate with discount":"<0><1><2/>Add stkAAVE to see borrow rate with discount","<0>Ampleforth is a rebasing asset. Visit the <1>documentation to learn more.":"<0>Ampleforth is a rebasing asset. Visit the <1>documentation to learn more.","<0>Attention: Parameter changes via governance can alter your account health factor and risk of liquidation. Follow the <1>Aave governance forum for updates.":"<0>Attention: Parameter changes via governance can alter your account health factor and risk of liquidation. Follow the <1>Aave governance forum for updates.","<0>Slippage tolerance <1>{selectedSlippage}% <2>{0}":["<0>Slippage tolerance <1>",["selectedSlippage"],"% <2>",["0"],""],"AAVE holders (Ethereum network only) can stake their AAVE in the Safety Module to add more security to the protocol and earn Safety Incentives. In the case of a shortfall event, up to 30% of your stake can be slashed to cover the deficit, providing an additional layer of protection for the protocol.":"AAVE holders (Ethereum network only) can stake their AAVE in the Safety Module to add more security to the protocol and earn Safety Incentives. In the case of a shortfall event, up to 30% of your stake can be slashed to cover the deficit, providing an additional layer of protection for the protocol.","APR":"APR","APY":"APY","APY change":"APY change","APY type":"APY type","APY type change":"APY type change","APY with discount applied":"APY with discount applied","APY, fixed rate":"APY, fixed rate","APY, stable":"APY, stable","APY, variable":"APY, variable","AToken supply is not zero":"AToken supply is not zero","Aave Governance":"Aave Governance","Aave aToken":"Aave aToken","Aave debt token":"Aave debt token","Aave is a fully decentralized, community governed protocol by the AAVE token-holders. AAVE token-holders collectively discuss, propose, and vote on upgrades to the protocol. AAVE token-holders (Ethereum network only) can either vote themselves on new proposals or delagate to an address of choice. To learn more check out the Governance":"Aave is a fully decentralized, community governed protocol by the AAVE token-holders. AAVE token-holders collectively discuss, propose, and vote on upgrades to the protocol. AAVE token-holders (Ethereum network only) can either vote themselves on new proposals or delagate to an address of choice. To learn more check out the Governance","Aave per month":"Aave per month","About GHO":"About GHO","Account":"Account","Action cannot be performed because the reserve is frozen":"Action cannot be performed because the reserve is frozen","Action cannot be performed because the reserve is paused":"Action cannot be performed because the reserve is paused","Action requires an active reserve":"Action requires an active reserve","Activate Cooldown":"Activate Cooldown","Add stkAAVE to see borrow APY with the discount":"Add stkAAVE to see borrow APY with the discount","Add to wallet":"Add to wallet","Add {0} to wallet to track your balance.":["Add ",["0"]," to wallet to track your balance."],"Address is not a contract":"Address is not a contract","Addresses":"Addresses","Addresses ({0})":["Addresses (",["0"],")"],"All Assets":"All Assets","All done!":"All done!","All proposals":"All proposals","All transactions":"All transactions","Allowance required action":"Allowance required action","Allows you to decide whether to use a supplied asset as collateral. An asset used as collateral will affect your borrowing power and health factor.":"Allows you to decide whether to use a supplied asset as collateral. An asset used as collateral will affect your borrowing power and health factor.","Allows you to switch between <0>variable and <1>stable interest rates, where variable rate can increase and decrease depending on the amount of liquidity in the reserve, and stable rate will stay the same for the duration of your loan.":"Allows you to switch between <0>variable and <1>stable interest rates, where variable rate can increase and decrease depending on the amount of liquidity in the reserve, and stable rate will stay the same for the duration of your loan.","Amount":"Amount","Amount claimable":"Amount claimable","Amount in cooldown":"Amount in cooldown","Amount must be greater than 0":"Amount must be greater than 0","Amount to unstake":"Amount to unstake","An error has occurred fetching the proposal metadata from IPFS.":"An error has occurred fetching the proposal metadata from IPFS.","Approve Confirmed":"Approve Confirmed","Approve with":"Approve with","Approve {symbol} to continue":["Approve ",["symbol"]," to continue"],"Approving {symbol}...":["Approving ",["symbol"],"..."],"Array parameters that should be equal length are not":"Array parameters that should be equal length are not","Asset":"Asset","Asset can be only used as collateral in isolation mode with limited borrowing power. To enter isolation mode, disable all other collateral.":"Asset can be only used as collateral in isolation mode with limited borrowing power. To enter isolation mode, disable all other collateral.","Asset can only be used as collateral in isolation mode only.":"Asset can only be used as collateral in isolation mode only.","Asset cannot be migrated because you have isolated collateral in {marketName} v3 Market which limits borrowable assets. You can manage your collateral in <0>{marketName} V3 Dashboard":["Asset cannot be migrated because you have isolated collateral in ",["marketName"]," v3 Market which limits borrowable assets. You can manage your collateral in <0>",["marketName"]," V3 Dashboard"],"Asset cannot be migrated due to insufficient liquidity or borrow cap limitation in {marketName} v3 market.":["Asset cannot be migrated due to insufficient liquidity or borrow cap limitation in ",["marketName"]," v3 market."],"Asset cannot be migrated due to supply cap restriction in {marketName} v3 market.":["Asset cannot be migrated due to supply cap restriction in ",["marketName"]," v3 market."],"Asset cannot be migrated to {marketName} V3 Market due to E-mode restrictions. You can disable or manage E-mode categories in your <0>V3 Dashboard":["Asset cannot be migrated to ",["marketName"]," V3 Market due to E-mode restrictions. You can disable or manage E-mode categories in your <0>V3 Dashboard"],"Asset cannot be migrated to {marketName} v3 Market since collateral asset will enable isolation mode.":["Asset cannot be migrated to ",["marketName"]," v3 Market since collateral asset will enable isolation mode."],"Asset cannot be used as collateral.":"Asset cannot be used as collateral.","Asset category":"Asset category","Asset is frozen in {marketName} v3 market, hence this position cannot be migrated.":["Asset is frozen in ",["marketName"]," v3 market, hence this position cannot be migrated."],"Asset is not borrowable in isolation mode":"Asset is not borrowable in isolation mode","Asset is not listed":"Asset is not listed","Asset supply is limited to a certain amount to reduce protocol exposure to the asset and to help manage risks involved.":"Asset supply is limited to a certain amount to reduce protocol exposure to the asset and to help manage risks involved.","Assets":"Assets","Assets to borrow":"Assets to borrow","Assets to supply":"Assets to supply","Assets with zero LTV ({assetsBlockingWithdraw}) must be withdrawn or disabled as collateral to perform this action":["Assets with zero LTV (",["assetsBlockingWithdraw"],") must be withdrawn or disabled as collateral to perform this action"],"At a discount":"At a discount","Author":"Author","Available":"Available","Available assets":"Available assets","Available liquidity":"Available liquidity","Available on":"Available on","Available rewards":"Available rewards","Available to borrow":"Available to borrow","Available to supply":"Available to supply","Back to Dashboard":"Back to Dashboard","Balance":"Balance","Balance to revoke":"Balance to revoke","Be careful - You are very close to liquidation. Consider depositing more collateral or paying down some of your borrowed positions":"Be careful - You are very close to liquidation. Consider depositing more collateral or paying down some of your borrowed positions","Be mindful of the network congestion and gas prices.":"Be mindful of the network congestion and gas prices.","Because this asset is paused, no actions can be taken until further notice":"Because this asset is paused, no actions can be taken until further notice","Before supplying":"Before supplying","Blocked Address":"Blocked Address","Borrow":"Borrow","Borrow APY":"Borrow APY","Borrow APY rate":"Borrow APY rate","Borrow APY, fixed rate":"Borrow APY, fixed rate","Borrow APY, stable":"Borrow APY, stable","Borrow APY, variable":"Borrow APY, variable","Borrow amount to reach {0}% utilization":["Borrow amount to reach ",["0"],"% utilization"],"Borrow and repay in same block is not allowed":"Borrow and repay in same block is not allowed","Borrow apy":"Borrow apy","Borrow balance":"Borrow balance","Borrow balance after repay":"Borrow balance after repay","Borrow balance after switch":"Borrow balance after switch","Borrow cap":"Borrow cap","Borrow cap is exceeded":"Borrow cap is exceeded","Borrow info":"Borrow info","Borrow power used":"Borrow power used","Borrow rate change":"Borrow rate change","Borrow {symbol}":["Borrow ",["symbol"]],"Borrowed":"Borrowed","Borrowed asset amount":"Borrowed asset amount","Borrowing is currently unavailable for {0}.":["Borrowing is currently unavailable for ",["0"],"."],"Borrowing is disabled due to an Aave community decision. <0>More details":"Borrowing is disabled due to an Aave community decision. <0>More details","Borrowing is not enabled":"Borrowing is not enabled","Borrowing is unavailable because you’re using Isolation mode. To manage Isolation mode visit your <0>Dashboard.":"Borrowing is unavailable because you’re using Isolation mode. To manage Isolation mode visit your <0>Dashboard.","Borrowing is unavailable because you’ve enabled Efficiency Mode (E-Mode) and Isolation mode. To manage E-Mode and Isolation mode visit your <0>Dashboard.":"Borrowing is unavailable because you’ve enabled Efficiency Mode (E-Mode) and Isolation mode. To manage E-Mode and Isolation mode visit your <0>Dashboard.","Borrowing is unavailable because you’ve enabled Efficiency Mode (E-Mode) for {0} category. To manage E-Mode categories visit your <0>Dashboard.":["Borrowing is unavailable because you’ve enabled Efficiency Mode (E-Mode) for ",["0"]," category. To manage E-Mode categories visit your <0>Dashboard."],"Borrowing of this asset is limited to a certain amount to minimize liquidity pool insolvency.":"Borrowing of this asset is limited to a certain amount to minimize liquidity pool insolvency.","Borrowing power and assets are limited due to Isolation mode.":"Borrowing power and assets are limited due to Isolation mode.","Borrowing this amount will reduce your health factor and increase risk of liquidation.":"Borrowing this amount will reduce your health factor and increase risk of liquidation.","Borrowing {symbol}":["Borrowing ",["symbol"]],"Both":"Both","Buy Crypto With Fiat":"Buy Crypto With Fiat","Buy Crypto with Fiat":"Buy Crypto with Fiat","Buy {cryptoSymbol} with Fiat":["Buy ",["cryptoSymbol"]," with Fiat"],"COPIED!":"COPIED!","COPY IMAGE":"COPY IMAGE","Can be collateral":"Can be collateral","Can be executed":"Can be executed","Cancel":"Cancel","Cannot disable E-Mode":"Cannot disable E-Mode","Choose how much voting/proposition power to give to someone else by delegating some of your AAVE or stkAAVE balance. Your tokens will remain in your account, but your delegate will be able to vote or propose on your behalf. If your AAVE or stkAAVE balance changes, your delegate's voting/proposition power will be automatically adjusted.":"Choose how much voting/proposition power to give to someone else by delegating some of your AAVE or stkAAVE balance. Your tokens will remain in your account, but your delegate will be able to vote or propose on your behalf. If your AAVE or stkAAVE balance changes, your delegate's voting/proposition power will be automatically adjusted.","Choose one of the on-ramp services":"Choose one of the on-ramp services","Claim":"Claim","Claim all":"Claim all","Claim all rewards":"Claim all rewards","Claim {0}":["Claim ",["0"]],"Claim {symbol}":["Claim ",["symbol"]],"Claimable AAVE":"Claimable AAVE","Claimed":"Claimed","Claiming":"Claiming","Claiming {symbol}":["Claiming ",["symbol"]],"Close":"Close","Collateral":"Collateral","Collateral balance after repay":"Collateral balance after repay","Collateral change":"Collateral change","Collateral is (mostly) the same currency that is being borrowed":"Collateral is (mostly) the same currency that is being borrowed","Collateral to repay with":"Collateral to repay with","Collateral usage":"Collateral usage","Collateral usage is limited because of Isolation mode.":"Collateral usage is limited because of Isolation mode.","Collateral usage is limited because of isolation mode.":"Collateral usage is limited because of isolation mode.","Collateral usage is limited because of isolation mode. <0>Learn More":"Collateral usage is limited because of isolation mode. <0>Learn More","Collateralization":"Collateralization","Collector Contract":"Collector Contract","Collector Info":"Collector Info","Connect wallet":"Connect wallet","Cooldown period":"Cooldown period","Cooldown period warning":"Cooldown period warning","Cooldown time left":"Cooldown time left","Cooldown to unstake":"Cooldown to unstake","Cooling down...":"Cooling down...","Copy address":"Copy address","Copy error message":"Copy error message","Copy error text":"Copy error text","Covered debt":"Covered debt","Created":"Created","Current LTV":"Current LTV","Current differential":"Current differential","Current v2 Balance":"Current v2 Balance","Current v2 balance":"Current v2 balance","Current votes":"Current votes","DAI balance will be converted via DSR contracts and then supplied as sDAI to Aave reserve. Switching incurs no additional costs and no slippage.":"DAI balance will be converted via DSR contracts and then supplied as sDAI to Aave reserve. Switching incurs no additional costs and no slippage.","DAI balance will be converted via DSR contracts and then supplied as sDAI. Switching incurs no additional costs and no slippage.":"DAI balance will be converted via DSR contracts and then supplied as sDAI. Switching incurs no additional costs and no slippage.","Dark mode":"Dark mode","Dashboard":"Dashboard","Data couldn't be fetched, please reload graph.":"Data couldn't be fetched, please reload graph.","Debt":"Debt","Debt ceiling is exceeded":"Debt ceiling is exceeded","Debt ceiling is not zero":"Debt ceiling is not zero","Debt ceiling limits the amount possible to borrow against this asset by protocol users. Debt ceiling is specific to assets in isolation mode and is denoted in USD.":"Debt ceiling limits the amount possible to borrow against this asset by protocol users. Debt ceiling is specific to assets in isolation mode and is denoted in USD.","Delegated power":"Delegated power","Details":"Details","Developers":"Developers","Differential":"Differential","Disable E-Mode":"Disable E-Mode","Disable testnet":"Disable testnet","Disable {symbol} as collateral":["Disable ",["symbol"]," as collateral"],"Disabled":"Disabled","Disabling E-Mode":"Disabling E-Mode","Disabling this asset as collateral affects your borrowing power and Health Factor.":"Disabling this asset as collateral affects your borrowing power and Health Factor.","Disconnect Wallet":"Disconnect Wallet","Discord channel":"Discord channel","Discount":"Discount","Discount applied for <0/> staking AAVE":"Discount applied for <0/> staking AAVE","Discount model parameters":"Discount model parameters","Discount parameters are decided by the Aave community and may be changed over time. Check Governance for updates and vote to participate. <0>Learn more":"Discount parameters are decided by the Aave community and may be changed over time. Check Governance for updates and vote to participate. <0>Learn more","Discountable amount":"Discountable amount","Docs":"Docs","Download":"Download","Due to internal stETH mechanics required for rebasing support, it is not possible to perform a collateral switch where stETH is the source token.":"Due to internal stETH mechanics required for rebasing support, it is not possible to perform a collateral switch where stETH is the source token.","Due to the Horizon bridge exploit, certain assets on the Harmony network are not at parity with Ethereum, which affects the Aave V3 Harmony market.":"Due to the Horizon bridge exploit, certain assets on the Harmony network are not at parity with Ethereum, which affects the Aave V3 Harmony market.","E-Mode":"E-Mode","E-Mode Category":"E-Mode Category","E-Mode category":"E-Mode category","E-Mode increases your LTV for a selected category of assets up to 97%. <0>Learn more":"E-Mode increases your LTV for a selected category of assets up to 97%. <0>Learn more","E-Mode increases your LTV for a selected category of assets up to<0/>. <1>Learn more":"E-Mode increases your LTV for a selected category of assets up to<0/>. <1>Learn more","E-Mode increases your LTV for a selected category of assets, meaning that when E-mode is enabled, you will have higher borrowing power over assets of the same E-mode category which are defined by Aave Governance. You can enter E-Mode from your <0>Dashboard. To learn more about E-Mode and applied restrictions in <1>FAQ or <2>Aave V3 Technical Paper.":"E-Mode increases your LTV for a selected category of assets, meaning that when E-mode is enabled, you will have higher borrowing power over assets of the same E-mode category which are defined by Aave Governance. You can enter E-Mode from your <0>Dashboard. To learn more about E-Mode and applied restrictions in <1>FAQ or <2>Aave V3 Technical Paper.","Effective interest rate":"Effective interest rate","Efficiency mode (E-Mode)":"Efficiency mode (E-Mode)","Emode":"Emode","Enable E-Mode":"Enable E-Mode","Enable {symbol} as collateral":["Enable ",["symbol"]," as collateral"],"Enabled":"Enabled","Enabling E-Mode":"Enabling E-Mode","Enabling E-Mode only allows you to borrow assets belonging to the selected category. Please visit our <0>FAQ guide to learn more about how it works and the applied restrictions.":"Enabling E-Mode only allows you to borrow assets belonging to the selected category. Please visit our <0>FAQ guide to learn more about how it works and the applied restrictions.","Enabling this asset as collateral increases your borrowing power and Health Factor. However, it can get liquidated if your health factor drops below 1.":"Enabling this asset as collateral increases your borrowing power and Health Factor. However, it can get liquidated if your health factor drops below 1.","Ended":"Ended","Ends":"Ends","English":"English","Enter ETH address":"Enter ETH address","Enter an amount":"Enter an amount","Error connecting. Try refreshing the page.":"Error connecting. Try refreshing the page.","Estimated compounding interest, including discount for Staking {0}AAVE in Safety Module.":["Estimated compounding interest, including discount for Staking ",["0"],"AAVE in Safety Module."],"Exceeds the discount":"Exceeds the discount","Exchange rate":"Exchange rate","Executed":"Executed","Expected amount to repay":"Expected amount to repay","Expires":"Expires","Export data to":"Export data to","FAQ":"FAQ","FAQS":"FAQS","Failed to load proposal voters. Please refresh the page.":"Failed to load proposal voters. Please refresh the page.","Faucet":"Faucet","Faucet {0}":["Faucet ",["0"]],"Fetching data...":"Fetching data...","Filter":"Filter","Fixed":"Fixed","Fixed rate":"Fixed rate","Flashloan is disabled for this asset, hence this position cannot be migrated.":"Flashloan is disabled for this asset, hence this position cannot be migrated.","For repayment of a specific type of debt, the user needs to have debt that type":"For repayment of a specific type of debt, the user needs to have debt that type","Forum discussion":"Forum discussion","French":"French","Funds in the Safety Module":"Funds in the Safety Module","GHO is a native decentralized, collateral-backed digital asset pegged to USD. It is created by users via borrowing against multiple collateral. When user repays their GHO borrow position, the protocol burns that user's GHO. All the interest payments accrued by minters of GHO would be directly transferred to the AaveDAO treasury.":"GHO is a native decentralized, collateral-backed digital asset pegged to USD. It is created by users via borrowing against multiple collateral. When user repays their GHO borrow position, the protocol burns that user's GHO. All the interest payments accrued by minters of GHO would be directly transferred to the AaveDAO treasury.","Get ABP Token":"Get ABP Token","Global settings":"Global settings","Go Back":"Go Back","Go to Balancer Pool":"Go to Balancer Pool","Go to V3 Dashboard":"Go to V3 Dashboard","Governance":"Governance","Greek":"Greek","Health Factor ({0} v2)":["Health Factor (",["0"]," v2)"],"Health Factor ({0} v3)":["Health Factor (",["0"]," v3)"],"Health factor":"Health factor","Health factor is lesser than the liquidation threshold":"Health factor is lesser than the liquidation threshold","Health factor is not below the threshold":"Health factor is not below the threshold","Hide":"Hide","Holders of stkAAVE receive a discount on the GHO borrowing rate":"Holders of stkAAVE receive a discount on the GHO borrowing rate","I acknowledge the risks involved.":"I acknowledge the risks involved.","I fully understand the risks of migrating.":"I fully understand the risks of migrating.","I understand how cooldown ({0}) and unstaking ({1}) work":["I understand how cooldown (",["0"],") and unstaking (",["1"],") work"],"If the error continues to happen,<0/> you may report it to this":"If the error continues to happen,<0/> you may report it to this","If the health factor goes below 1, the liquidation of your collateral might be triggered.":"If the health factor goes below 1, the liquidation of your collateral might be triggered.","If you DO NOT unstake within {0} of unstake window, you will need to activate cooldown process again.":["If you DO NOT unstake within ",["0"]," of unstake window, you will need to activate cooldown process again."],"If your loan to value goes above the liquidation threshold your collateral supplied may be liquidated.":"If your loan to value goes above the liquidation threshold your collateral supplied may be liquidated.","In E-Mode some assets are not borrowable. Exit E-Mode to get access to all assets":"In E-Mode some assets are not borrowable. Exit E-Mode to get access to all assets","In Isolation mode, you cannot supply other assets as collateral. A global debt ceiling limits the borrowing power of the isolated asset. To exit isolation mode disable {0} as collateral before borrowing another asset. Read more in our <0>FAQ":["In Isolation mode, you cannot supply other assets as collateral. A global debt ceiling limits the borrowing power of the isolated asset. To exit isolation mode disable ",["0"]," as collateral before borrowing another asset. Read more in our <0>FAQ"],"Inconsistent flashloan parameters":"Inconsistent flashloan parameters","Insufficient collateral to cover new borrow position. Wallet must have borrowing power remaining to perform debt switch.":"Insufficient collateral to cover new borrow position. Wallet must have borrowing power remaining to perform debt switch.","Interest accrued":"Interest accrued","Interest rate rebalance conditions were not met":"Interest rate rebalance conditions were not met","Interest rate strategy":"Interest rate strategy","Invalid amount to burn":"Invalid amount to burn","Invalid amount to mint":"Invalid amount to mint","Invalid bridge protocol fee":"Invalid bridge protocol fee","Invalid expiration":"Invalid expiration","Invalid flashloan premium":"Invalid flashloan premium","Invalid return value of the flashloan executor function":"Invalid return value of the flashloan executor function","Invalid signature":"Invalid signature","Isolated":"Isolated","Isolated Debt Ceiling":"Isolated Debt Ceiling","Isolated assets have limited borrowing power and other assets cannot be used as collateral.":"Isolated assets have limited borrowing power and other assets cannot be used as collateral.","Join the community discussion":"Join the community discussion","LEARN MORE":"LEARN MORE","Language":"Language","Learn more":"Learn more","Learn more about risks involved":"Learn more about risks involved","Learn more in our <0>FAQ guide":"Learn more in our <0>FAQ guide","Learn more.":"Learn more.","Links":"Links","Liqudation":"Liqudation","Liquidated collateral":"Liquidated collateral","Liquidation":"Liquidation","Liquidation <0/> threshold":"Liquidation <0/> threshold","Liquidation Threshold":"Liquidation Threshold","Liquidation at":"Liquidation at","Liquidation penalty":"Liquidation penalty","Liquidation risk":"Liquidation risk","Liquidation risk parameters":"Liquidation risk parameters","Liquidation threshold":"Liquidation threshold","Liquidation value":"Liquidation value","Loading data...":"Loading data...","Ltv validation failed":"Ltv validation failed","MAI has been paused due to a community decision. Supply, borrows and repays are impacted. <0>More details":"MAI has been paused due to a community decision. Supply, borrows and repays are impacted. <0>More details","MAX":"MAX","Manage analytics":"Manage analytics","Market":"Market","Markets":"Markets","Max":"Max","Max LTV":"Max LTV","Max slashing":"Max slashing","Max slippage":"Max slippage","Maximum amount available to borrow against this asset is limited because debt ceiling is at {0}%.":["Maximum amount available to borrow against this asset is limited because debt ceiling is at ",["0"],"%."],"Maximum amount available to borrow is <0/> {0} (<1/>).":["Maximum amount available to borrow is <0/> ",["0"]," (<1/>)."],"Maximum amount available to borrow is limited because protocol borrow cap is nearly reached.":"Maximum amount available to borrow is limited because protocol borrow cap is nearly reached.","Maximum amount available to supply is <0/> {0} (<1/>).":["Maximum amount available to supply is <0/> ",["0"]," (<1/>)."],"Maximum amount available to supply is limited because protocol supply cap is at {0}%.":["Maximum amount available to supply is limited because protocol supply cap is at ",["0"],"%."],"Maximum loan to value":"Maximum loan to value","Meet GHO":"Meet GHO","Menu":"Menu","Migrate":"Migrate","Migrate to V3":"Migrate to V3","Migrate to v3":"Migrate to v3","Migrate to {0} v3 Market":["Migrate to ",["0"]," v3 Market"],"Migrated":"Migrated","Migrating":"Migrating","Migrating multiple collaterals and borrowed assets at the same time can be an expensive operation and might fail in certain situations.<0>Therefore it’s not recommended to migrate positions with more than 5 assets (deposited + borrowed) at the same time.":"Migrating multiple collaterals and borrowed assets at the same time can be an expensive operation and might fail in certain situations.<0>Therefore it’s not recommended to migrate positions with more than 5 assets (deposited + borrowed) at the same time.","Migration risks":"Migration risks","Minimum GHO borrow amount":"Minimum GHO borrow amount","Minimum USD value received":"Minimum USD value received","Minimum staked Aave amount":"Minimum staked Aave amount","Minimum {0} received":["Minimum ",["0"]," received"],"More":"More","NAY":"NAY","Need help connecting a wallet? <0>Read our FAQ":"Need help connecting a wallet? <0>Read our FAQ","Net APR":"Net APR","Net APY":"Net APY","Net APY is the combined effect of all supply and borrow positions on net worth, including incentives. It is possible to have a negative net APY if debt APY is higher than supply APY.":"Net APY is the combined effect of all supply and borrow positions on net worth, including incentives. It is possible to have a negative net APY if debt APY is higher than supply APY.","Net worth":"Net worth","Network":"Network","Network not supported for this wallet":"Network not supported for this wallet","New APY":"New APY","No assets selected to migrate.":"No assets selected to migrate.","No rewards to claim":"No rewards to claim","No search results{0}":["No search results",["0"]],"No transactions yet.":"No transactions yet.","No voting power":"No voting power","None":"None","Not a valid address":"Not a valid address","Not enough balance on your wallet":"Not enough balance on your wallet","Not enough collateral to repay this amount of debt with":"Not enough collateral to repay this amount of debt with","Not enough staked balance":"Not enough staked balance","Not enough voting power to participate in this proposal":"Not enough voting power to participate in this proposal","Not reached":"Not reached","Nothing borrowed yet":"Nothing borrowed yet","Nothing found":"Nothing found","Nothing staked":"Nothing staked","Nothing supplied yet":"Nothing supplied yet","Notify":"Notify","Ok, Close":"Ok, Close","Ok, I got it":"Ok, I got it","Operation not supported":"Operation not supported","Oracle price":"Oracle price","Overview":"Overview","Page not found":"Page not found","Participating in this {symbol} reserve gives annualized rewards.":["Participating in this ",["symbol"]," reserve gives annualized rewards."],"Pending...":"Pending...","Per the community, the Fantom market has been frozen.":"Per the community, the Fantom market has been frozen.","Per the community, the V2 AMM market has been deprecated.":"Per the community, the V2 AMM market has been deprecated.","Please always be aware of your <0>Health Factor (HF) when partially migrating a position and that your rates will be updated to V3 rates.":"Please always be aware of your <0>Health Factor (HF) when partially migrating a position and that your rates will be updated to V3 rates.","Please connect a wallet to view your personal information here.":"Please connect a wallet to view your personal information here.","Please connect your wallet to be able to switch your tokens.":"Please connect your wallet to be able to switch your tokens.","Please connect your wallet to get free testnet assets.":"Please connect your wallet to get free testnet assets.","Please connect your wallet to see migration tool.":"Please connect your wallet to see migration tool.","Please connect your wallet to see your supplies, borrowings, and open positions.":"Please connect your wallet to see your supplies, borrowings, and open positions.","Please connect your wallet to view transaction history.":"Please connect your wallet to view transaction history.","Please enter a valid wallet address.":"Please enter a valid wallet address.","Please switch to {networkName}.":["Please switch to ",["networkName"],"."],"Please, connect your wallet":"Please, connect your wallet","Pool addresses provider is not registered":"Pool addresses provider is not registered","Powered by":"Powered by","Preview tx and migrate":"Preview tx and migrate","Price":"Price","Price data is not currently available for this reserve on the protocol subgraph":"Price data is not currently available for this reserve on the protocol subgraph","Price impact":"Price impact","Price impact is the spread between the total value of the entry tokens switched and the destination tokens obtained (in USD), which results from the limited liquidity of the trading pair.":"Price impact is the spread between the total value of the entry tokens switched and the destination tokens obtained (in USD), which results from the limited liquidity of the trading pair.","Price impact {0}%":["Price impact ",["0"],"%"],"Privacy":"Privacy","Proposal details":"Proposal details","Proposal overview":"Proposal overview","Proposals":"Proposals","Proposition":"Proposition","Protocol borrow cap at 100% for this asset. Further borrowing unavailable.":"Protocol borrow cap at 100% for this asset. Further borrowing unavailable.","Protocol borrow cap is at 100% for this asset. Further borrowing unavailable.":"Protocol borrow cap is at 100% for this asset. Further borrowing unavailable.","Protocol debt ceiling is at 100% for this asset. Further borrowing against this asset is unavailable.":"Protocol debt ceiling is at 100% for this asset. Further borrowing against this asset is unavailable.","Protocol debt ceiling is at 100% for this asset. Futher borrowing against this asset is unavailable.":"Protocol debt ceiling is at 100% for this asset. Futher borrowing against this asset is unavailable.","Protocol supply cap at 100% for this asset. Further supply unavailable.":"Protocol supply cap at 100% for this asset. Further supply unavailable.","Protocol supply cap is at 100% for this asset. Further supply unavailable.":"Protocol supply cap is at 100% for this asset. Further supply unavailable.","Quorum":"Quorum","Rate change":"Rate change","Raw-Ipfs":"Raw-Ipfs","Reached":"Reached","Reactivate cooldown period to unstake {0} {stakedToken}":["Reactivate cooldown period to unstake ",["0"]," ",["stakedToken"]],"Read more here.":"Read more here.","Read-only mode allows to see address positions in Aave, but you won't be able to perform transactions.":"Read-only mode allows to see address positions in Aave, but you won't be able to perform transactions.","Read-only mode.":"Read-only mode.","Read-only mode. Connect to a wallet to perform transactions.":"Read-only mode. Connect to a wallet to perform transactions.","Receive (est.)":"Receive (est.)","Received":"Received","Recipient address":"Recipient address","Rejected connection request":"Rejected connection request","Reload":"Reload","Reload the page":"Reload the page","Remaining debt":"Remaining debt","Remaining supply":"Remaining supply","Repaid":"Repaid","Repay":"Repay","Repay with":"Repay with","Repay {symbol}":["Repay ",["symbol"]],"Repaying {symbol}":["Repaying ",["symbol"]],"Repayment amount to reach {0}% utilization":["Repayment amount to reach ",["0"],"% utilization"],"Reserve Size":"Reserve Size","Reserve factor":"Reserve factor","Reserve factor is a percentage of interest which goes to a {0} that is controlled by Aave governance to promote ecosystem growth.":["Reserve factor is a percentage of interest which goes to a ",["0"]," that is controlled by Aave governance to promote ecosystem growth."],"Reserve status & configuration":"Reserve status & configuration","Reset":"Reset","Restake":"Restake","Restake {symbol}":["Restake ",["symbol"]],"Restaked":"Restaked","Restaking {symbol}":["Restaking ",["symbol"]],"Review approval tx details":"Review approval tx details","Review changes to continue":"Review changes to continue","Review tx":"Review tx","Review tx details":"Review tx details","Revoke power":"Revoke power","Reward(s) to claim":"Reward(s) to claim","Rewards APR":"Rewards APR","Risk details":"Risk details","SEE CHARTS":"SEE CHARTS","Safety of your deposited collateral against the borrowed assets and its underlying value.":"Safety of your deposited collateral against the borrowed assets and its underlying value.","Save and share":"Save and share","Seatbelt report":"Seatbelt report","Seems like we can't switch the network automatically. Please check if you can change it from the wallet.":"Seems like we can't switch the network automatically. Please check if you can change it from the wallet.","Select":"Select","Select APY type to switch":"Select APY type to switch","Select an asset":"Select an asset","Select language":"Select language","Select slippage tolerance":"Select slippage tolerance","Select v2 borrows to migrate":"Select v2 borrows to migrate","Select v2 supplies to migrate":"Select v2 supplies to migrate","Selected assets have successfully migrated. Visit the Market Dashboard to see them.":"Selected assets have successfully migrated. Visit the Market Dashboard to see them.","Selected borrow assets":"Selected borrow assets","Selected supply assets":"Selected supply assets","Send feedback":"Send feedback","Set up delegation":"Set up delegation","Setup notifications about your Health Factor using the Hal app.":"Setup notifications about your Health Factor using the Hal app.","Share on Lens":"Share on Lens","Share on twitter":"Share on twitter","Show":"Show","Show Frozen or paused assets":"Show Frozen or paused assets","Show assets with 0 balance":"Show assets with 0 balance","Sign to continue":"Sign to continue","Signatures ready":"Signatures ready","Signing":"Signing","Since this asset is frozen, the only available actions are withdraw and repay which can be accessed from the <0>Dashboard":"Since this asset is frozen, the only available actions are withdraw and repay which can be accessed from the <0>Dashboard","Since this is a test network, you can get any of the assets if you have ETH on your wallet":"Since this is a test network, you can get any of the assets if you have ETH on your wallet","Slippage":"Slippage","Slippage is the difference between the quoted and received amounts from changing market conditions between the moment the transaction is submitted and its verification.":"Slippage is the difference between the quoted and received amounts from changing market conditions between the moment the transaction is submitted and its verification.","Some migrated assets will not be used as collateral due to enabled isolation mode in {marketName} V3 Market. Visit <0>{marketName} V3 Dashboard to manage isolation mode.":["Some migrated assets will not be used as collateral due to enabled isolation mode in ",["marketName"]," V3 Market. Visit <0>",["marketName"]," V3 Dashboard to manage isolation mode."],"Something went wrong":"Something went wrong","Sorry, an unexpected error happened. In the meantime you may try reloading the page, or come back later.":"Sorry, an unexpected error happened. In the meantime you may try reloading the page, or come back later.","Sorry, we couldn't find the page you were looking for.":"Sorry, we couldn't find the page you were looking for.","Spanish":"Spanish","Stable":"Stable","Stable Interest Type is disabled for this currency":"Stable Interest Type is disabled for this currency","Stable borrowing is enabled":"Stable borrowing is enabled","Stable borrowing is not enabled":"Stable borrowing is not enabled","Stable debt supply is not zero":"Stable debt supply is not zero","Stable interest rate will <0>stay the same for the duration of your loan. Recommended for long-term loan periods and for users who prefer predictability.":"Stable interest rate will <0>stay the same for the duration of your loan. Recommended for long-term loan periods and for users who prefer predictability.","Stablecoin":"Stablecoin","Stake":"Stake","Stake AAVE":"Stake AAVE","Stake ABPT":"Stake ABPT","Stake cooldown activated":"Stake cooldown activated","Staked":"Staked","Staking":"Staking","Staking APR":"Staking APR","Staking Rewards":"Staking Rewards","Staking balance":"Staking balance","Staking discount":"Staking discount","Started":"Started","State":"State","Static interest rate that is determined by Aave Governance. This rate may be changed over time depending on the need for the GHO supply to contract/expand. <0>Learn more":"Static interest rate that is determined by Aave Governance. This rate may be changed over time depending on the need for the GHO supply to contract/expand. <0>Learn more","Supplied":"Supplied","Supplied asset amount":"Supplied asset amount","Supply":"Supply","Supply APY":"Supply APY","Supply apy":"Supply apy","Supply balance":"Supply balance","Supply balance after switch":"Supply balance after switch","Supply cap is exceeded":"Supply cap is exceeded","Supply cap on target reserve reached. Try lowering the amount.":"Supply cap on target reserve reached. Try lowering the amount.","Supply {symbol}":["Supply ",["symbol"]],"Supplying your":"Supplying your","Supplying {symbol}":["Supplying ",["symbol"]],"Switch":"Switch","Switch APY type":"Switch APY type","Switch E-Mode":"Switch E-Mode","Switch E-Mode category":"Switch E-Mode category","Switch Network":"Switch Network","Switch borrow position":"Switch borrow position","Switch rate":"Switch rate","Switch to":"Switch to","Switched":"Switched","Switching":"Switching","Switching E-Mode":"Switching E-Mode","Switching rate":"Switching rate","Techpaper":"Techpaper","Terms":"Terms","Test Assets":"Test Assets","Testnet mode":"Testnet mode","Testnet mode is ON":"Testnet mode is ON","Thank you for voting!!":"Thank you for voting!!","The % of your total borrowing power used. This is based on the amount of your collateral supplied and the total amount that you can borrow.":"The % of your total borrowing power used. This is based on the amount of your collateral supplied and the total amount that you can borrow.","The Aave Balancer Pool Token (ABPT) is a liquidity pool token. You can receive ABPT by depositing a combination of AAVE + ETH in the Balancer liquidity pool. You can then stake your BPT in the Safety Module to secure the protocol and earn Safety Incentives.":"The Aave Balancer Pool Token (ABPT) is a liquidity pool token. You can receive ABPT by depositing a combination of AAVE + ETH in the Balancer liquidity pool. You can then stake your BPT in the Safety Module to secure the protocol and earn Safety Incentives.","The Aave Protocol is programmed to always use the price of 1 GHO = $1. This is different from using market pricing via oracles for other crypto assets. This creates stabilizing arbitrage opportunities when the price of GHO fluctuates.":"The Aave Protocol is programmed to always use the price of 1 GHO = $1. This is different from using market pricing via oracles for other crypto assets. This creates stabilizing arbitrage opportunities when the price of GHO fluctuates.","The Maximum LTV ratio represents the maximum borrowing power of a specific collateral. For example, if a collateral has an LTV of 75%, the user can borrow up to 0.75 worth of ETH in the principal currency for every 1 ETH worth of collateral.":"The Maximum LTV ratio represents the maximum borrowing power of a specific collateral. For example, if a collateral has an LTV of 75%, the user can borrow up to 0.75 worth of ETH in the principal currency for every 1 ETH worth of collateral.","The Stable Rate is not enabled for this currency":"The Stable Rate is not enabled for this currency","The address of the pool addresses provider is invalid":"The address of the pool addresses provider is invalid","The app is running in testnet mode. Learn how it works in":"The app is running in testnet mode. Learn how it works in","The caller of the function is not an AToken":"The caller of the function is not an AToken","The caller of this function must be a pool":"The caller of this function must be a pool","The collateral balance is 0":"The collateral balance is 0","The collateral chosen cannot be liquidated":"The collateral chosen cannot be liquidated","The cooldown period is the time required prior to unstaking your tokens (20 days). You can only withdraw your assets from the Security Module after the cooldown period and within the unstake window.<0>Learn more":"The cooldown period is the time required prior to unstaking your tokens (20 days). You can only withdraw your assets from the Security Module after the cooldown period and within the unstake window.<0>Learn more","The cooldown period is {0}. After {1} of cooldown, you will enter unstake window of {2}. You will continue receiving rewards during cooldown and unstake window.":["The cooldown period is ",["0"],". After ",["1"]," of cooldown, you will enter unstake window of ",["2"],". You will continue receiving rewards during cooldown and unstake window."],"The effects on the health factor would cause liquidation. Try lowering the amount.":"The effects on the health factor would cause liquidation. Try lowering the amount.","The loan to value of the migrated positions would cause liquidation. Increase migrated collateral or reduce migrated borrow to continue.":"The loan to value of the migrated positions would cause liquidation. Increase migrated collateral or reduce migrated borrow to continue.","The requested amount is greater than the max loan size in stable rate mode":"The requested amount is greater than the max loan size in stable rate mode","The total amount of your assets denominated in USD that can be used as collateral for borrowing assets.":"The total amount of your assets denominated in USD that can be used as collateral for borrowing assets.","The underlying asset cannot be rescued":"The underlying asset cannot be rescued","The underlying balance needs to be greater than 0":"The underlying balance needs to be greater than 0","The weighted average of APY for all borrowed assets, including incentives.":"The weighted average of APY for all borrowed assets, including incentives.","The weighted average of APY for all supplied assets, including incentives.":"The weighted average of APY for all supplied assets, including incentives.","There are not enough funds in the{0}reserve to borrow":["There are not enough funds in the",["0"],"reserve to borrow"],"There is not enough collateral to cover a new borrow":"There is not enough collateral to cover a new borrow","There is not enough liquidity for the target asset to perform the switch. Try lowering the amount.":"There is not enough liquidity for the target asset to perform the switch. Try lowering the amount.","There was some error. Please try changing the parameters or <0><1>copy the error":"There was some error. Please try changing the parameters or <0><1>copy the error","These assets are temporarily frozen or paused by Aave community decisions, meaning that further supply / borrow, or rate swap of these assets are unavailable. Withdrawals and debt repayments are allowed. Follow the <0>Aave governance forum for further updates.":"These assets are temporarily frozen or paused by Aave community decisions, meaning that further supply / borrow, or rate swap of these assets are unavailable. Withdrawals and debt repayments are allowed. Follow the <0>Aave governance forum for further updates.","These funds have been borrowed and are not available for withdrawal at this time.":"These funds have been borrowed and are not available for withdrawal at this time.","This action will reduce V2 health factor below liquidation threshold. retain collateral or migrate borrow position to continue.":"This action will reduce V2 health factor below liquidation threshold. retain collateral or migrate borrow position to continue.","This action will reduce health factor of V3 below liquidation threshold. Increase migrated collateral or reduce migrated borrow to continue.":"This action will reduce health factor of V3 below liquidation threshold. Increase migrated collateral or reduce migrated borrow to continue.","This action will reduce your health factor. Please be mindful of the increased risk of collateral liquidation.":"This action will reduce your health factor. Please be mindful of the increased risk of collateral liquidation.","This address is blocked on app.aave.com because it is associated with one or more":"This address is blocked on app.aave.com because it is associated with one or more","This asset has almost reached its borrow cap. There is only {messageValue} available to be borrowed from this market.":["This asset has almost reached its borrow cap. There is only ",["messageValue"]," available to be borrowed from this market."],"This asset has almost reached its supply cap. There can only be {messageValue} supplied to this market.":["This asset has almost reached its supply cap. There can only be ",["messageValue"]," supplied to this market."],"This asset has reached its borrow cap. Nothing is available to be borrowed from this market.":"This asset has reached its borrow cap. Nothing is available to be borrowed from this market.","This asset has reached its supply cap. Nothing is available to be supplied from this market.":"This asset has reached its supply cap. Nothing is available to be supplied from this market.","This asset is frozen due to an Aave Protocol Governance decision. <0>More details":"This asset is frozen due to an Aave Protocol Governance decision. <0>More details","This asset is frozen due to an Aave Protocol Governance decision. On the 20th of December 2022, renFIL will no longer be supported and cannot be bridged back to its native network. It is recommended to withdraw supply positions and repay borrow positions so that renFIL can be bridged back to FIL before the deadline. After this date, it will no longer be possible to convert renFIL to FIL. <0>More details":"This asset is frozen due to an Aave Protocol Governance decision. On the 20th of December 2022, renFIL will no longer be supported and cannot be bridged back to its native network. It is recommended to withdraw supply positions and repay borrow positions so that renFIL can be bridged back to FIL before the deadline. After this date, it will no longer be possible to convert renFIL to FIL. <0>More details","This asset is frozen due to an Aave community decision. <0>More details":"This asset is frozen due to an Aave community decision. <0>More details","This asset is planned to be offboarded due to an Aave Protocol Governance decision. <0>More details":"This asset is planned to be offboarded due to an Aave Protocol Governance decision. <0>More details","This gas calculation is only an estimation. Your wallet will set the price of the transaction. You can modify the gas settings directly from your wallet provider.":"This gas calculation is only an estimation. Your wallet will set the price of the transaction. You can modify the gas settings directly from your wallet provider.","This integration was<0>proposed and approvedby the community.":"This integration was<0>proposed and approvedby the community.","This is the total amount available for you to borrow. You can borrow based on your collateral and until the borrow cap is reached.":"This is the total amount available for you to borrow. You can borrow based on your collateral and until the borrow cap is reached.","This is the total amount that you are able to supply to in this reserve. You are able to supply your wallet balance up until the supply cap is reached.":"This is the total amount that you are able to supply to in this reserve. You are able to supply your wallet balance up until the supply cap is reached.","This represents the threshold at which a borrow position will be considered undercollateralized and subject to liquidation for each collateral. For example, if a collateral has a liquidation threshold of 80%, it means that the position will be liquidated when the debt value is worth 80% of the collateral value.":"This represents the threshold at which a borrow position will be considered undercollateralized and subject to liquidation for each collateral. For example, if a collateral has a liquidation threshold of 80%, it means that the position will be liquidated when the debt value is worth 80% of the collateral value.","Time left to be able to withdraw your staked asset.":"Time left to be able to withdraw your staked asset.","Time left to unstake":"Time left to unstake","Time left until the withdrawal window closes.":"Time left until the withdrawal window closes.","Tip: Try increasing slippage or reduce input amount":"Tip: Try increasing slippage or reduce input amount","To borrow you need to supply any asset to be used as collateral.":"To borrow you need to supply any asset to be used as collateral.","To continue, you need to grant Aave smart contracts permission to move your funds from your wallet. Depending on the asset and wallet you use, it is done by signing the permission message (gas free), or by submitting an approval transaction (requires gas). <0>Learn more":"To continue, you need to grant Aave smart contracts permission to move your funds from your wallet. Depending on the asset and wallet you use, it is done by signing the permission message (gas free), or by submitting an approval transaction (requires gas). <0>Learn more","To enable E-mode for the {0} category, all borrow positions outside of this category must be closed.":["To enable E-mode for the ",["0"]," category, all borrow positions outside of this category must be closed."],"To repay on behalf of a user an explicit amount to repay is needed":"To repay on behalf of a user an explicit amount to repay is needed","To request access for this permissioned market, please visit: <0>Acces Provider Name":"To request access for this permissioned market, please visit: <0>Acces Provider Name","To submit a proposal for minor changes to the protocol, you'll need at least 80.00K power. If you want to change the core code base, you'll need 320k power.<0>Learn more.":"To submit a proposal for minor changes to the protocol, you'll need at least 80.00K power. If you want to change the core code base, you'll need 320k power.<0>Learn more.","Top 10 addresses":"Top 10 addresses","Total available":"Total available","Total borrowed":"Total borrowed","Total borrows":"Total borrows","Total emission per day":"Total emission per day","Total interest accrued":"Total interest accrued","Total market size":"Total market size","Total supplied":"Total supplied","Total voting power":"Total voting power","Total worth":"Total worth","Track wallet":"Track wallet","Track wallet balance in read-only mode":"Track wallet balance in read-only mode","Transaction failed":"Transaction failed","Transaction history":"Transaction history","Transaction history is not currently available for this market":"Transaction history is not currently available for this market","Transaction overview":"Transaction overview","Transactions":"Transactions","UNSTAKE {symbol}":["UNSTAKE ",["symbol"]],"Unavailable":"Unavailable","Unbacked":"Unbacked","Unbacked mint cap is exceeded":"Unbacked mint cap is exceeded","Underlying asset does not exist in {marketName} v3 Market, hence this position cannot be migrated.":["Underlying asset does not exist in ",["marketName"]," v3 Market, hence this position cannot be migrated."],"Underlying token":"Underlying token","Unstake now":"Unstake now","Unstake window":"Unstake window","Unstaked":"Unstaked","Unstaking {symbol}":["Unstaking ",["symbol"]],"Update: Disruptions reported for WETH, WBTC, WMATIC, and USDT. AIP 230 will resolve the disruptions and the market will be operating as normal on ~26th May 13h00 UTC.":"Update: Disruptions reported for WETH, WBTC, WMATIC, and USDT. AIP 230 will resolve the disruptions and the market will be operating as normal on ~26th May 13h00 UTC.","Use it to vote for or against active proposals.":"Use it to vote for or against active proposals.","Use your AAVE and stkAAVE balance to delegate your voting and proposition powers. You will not be sending any tokens, only the rights to vote and propose changes to the protocol. You can re-delegate or revoke power to self at any time.":"Use your AAVE and stkAAVE balance to delegate your voting and proposition powers. You will not be sending any tokens, only the rights to vote and propose changes to the protocol. You can re-delegate or revoke power to self at any time.","Used as collateral":"Used as collateral","User cannot withdraw more than the available balance":"User cannot withdraw more than the available balance","User did not borrow the specified currency":"User did not borrow the specified currency","User does not have outstanding stable rate debt on this reserve":"User does not have outstanding stable rate debt on this reserve","User does not have outstanding variable rate debt on this reserve":"User does not have outstanding variable rate debt on this reserve","User is in isolation mode":"User is in isolation mode","User is trying to borrow multiple assets including a siloed one":"User is trying to borrow multiple assets including a siloed one","Users who stake AAVE in Safety Module (i.e. stkAAVE holders) receive a discount on GHO borrow interest rate. The discount applies to 100 GHO for every 1 stkAAVE held. Use the calculator below to see GHO borrow rate with the discount applied.":"Users who stake AAVE in Safety Module (i.e. stkAAVE holders) receive a discount on GHO borrow interest rate. The discount applies to 100 GHO for every 1 stkAAVE held. Use the calculator below to see GHO borrow rate with the discount applied.","Utilization Rate":"Utilization Rate","VIEW TX":"VIEW TX","VOTE NAY":"VOTE NAY","VOTE YAE":"VOTE YAE","Variable":"Variable","Variable debt supply is not zero":"Variable debt supply is not zero","Variable interest rate will <0>fluctuate based on the market conditions. Recommended for short-term positions.":"Variable interest rate will <0>fluctuate based on the market conditions. Recommended for short-term positions.","Variable rate":"Variable rate","Version 2":"Version 2","Version 3":"Version 3","View":"View","View Transactions":"View Transactions","View all votes":"View all votes","View contract":"View contract","View details":"View details","View on Explorer":"View on Explorer","Vote NAY":"Vote NAY","Vote YAE":"Vote YAE","Voted NAY":"Voted NAY","Voted YAE":"Voted YAE","Votes":"Votes","Voting":"Voting","Voting power":"Voting power","Voting results":"Voting results","Wallet Balance":"Wallet Balance","Wallet balance":"Wallet balance","Wallet not detected. Connect or install wallet and retry":"Wallet not detected. Connect or install wallet and retry","Wallets are provided by External Providers and by selecting you agree to Terms of those Providers. Your access to the wallet might be reliant on the External Provider being operational.":"Wallets are provided by External Providers and by selecting you agree to Terms of those Providers. Your access to the wallet might be reliant on the External Provider being operational.","We couldn't find any assets related to your search. Try again with a different asset name, symbol, or address.":"We couldn't find any assets related to your search. Try again with a different asset name, symbol, or address.","We couldn't find any transactions related to your search. Try again with a different asset name, or reset filters.":"We couldn't find any transactions related to your search. Try again with a different asset name, or reset filters.","We couldn’t detect a wallet. Connect a wallet to stake and view your balance.":"We couldn’t detect a wallet. Connect a wallet to stake and view your balance.","We suggest you go back to the Dashboard.":"We suggest you go back to the Dashboard.","Website":"Website","When a liquidation occurs, liquidators repay up to 50% of the outstanding borrowed amount on behalf of the borrower. In return, they can buy the collateral at a discount and keep the difference (liquidation penalty) as a bonus.":"When a liquidation occurs, liquidators repay up to 50% of the outstanding borrowed amount on behalf of the borrower. In return, they can buy the collateral at a discount and keep the difference (liquidation penalty) as a bonus.","With a voting power of <0/>":"With a voting power of <0/>","With testnet Faucet you can get free assets to test the Aave Protocol. Make sure to switch your wallet provider to the appropriate testnet network, select desired asset, and click ‘Faucet’ to get tokens transferred to your wallet. The assets on a testnet are not “real,” meaning they have no monetary value. <0>Learn more":"With testnet Faucet you can get free assets to test the Aave Protocol. Make sure to switch your wallet provider to the appropriate testnet network, select desired asset, and click ‘Faucet’ to get tokens transferred to your wallet. The assets on a testnet are not “real,” meaning they have no monetary value. <0>Learn more","Withdraw":"Withdraw","Withdraw & Switch":"Withdraw & Switch","Withdraw and Switch":"Withdraw and Switch","Withdraw {symbol}":["Withdraw ",["symbol"]],"Withdrawing":"Withdrawing","Withdrawing and Switching":"Withdrawing and Switching","Withdrawing this amount will reduce your health factor and increase risk of liquidation.":"Withdrawing this amount will reduce your health factor and increase risk of liquidation.","Withdrawing {symbol}":["Withdrawing ",["symbol"]],"Wrong Network":"Wrong Network","YAE":"YAE","You are entering Isolation mode":"You are entering Isolation mode","You can borrow this asset with a stable rate only if you borrow more than the amount you are supplying as collateral.":"You can borrow this asset with a stable rate only if you borrow more than the amount you are supplying as collateral.","You can not change Interest Type to stable as your borrowings are higher than your collateral":"You can not change Interest Type to stable as your borrowings are higher than your collateral","You can not disable E-Mode as your current collateralization level is above 80%, disabling E-Mode can cause liquidation. To exit E-Mode supply or repay borrowed positions.":"You can not disable E-Mode as your current collateralization level is above 80%, disabling E-Mode can cause liquidation. To exit E-Mode supply or repay borrowed positions.","You can not switch usage as collateral mode for this currency, because it will cause collateral call":"You can not switch usage as collateral mode for this currency, because it will cause collateral call","You can not use this currency as collateral":"You can not use this currency as collateral","You can not withdraw this amount because it will cause collateral call":"You can not withdraw this amount because it will cause collateral call","You can only switch to tokens with variable APY types. After this transaction, you may change the variable rate to a stable one if available.":"You can only switch to tokens with variable APY types. After this transaction, you may change the variable rate to a stable one if available.","You can only withdraw your assets from the Security Module after the cooldown period ends and the unstake window is active.":"You can only withdraw your assets from the Security Module after the cooldown period ends and the unstake window is active.","You can report incident to our <0>Discord or<1>Github.":"You can report incident to our <0>Discord or<1>Github.","You cancelled the transaction.":"You cancelled the transaction.","You did not participate in this proposal":"You did not participate in this proposal","You do not have supplies in this currency":"You do not have supplies in this currency","You don’t have enough funds in your wallet to repay the full amount. If you proceed to repay with your current amount of funds, you will still have a small borrowing position in your dashboard.":"You don’t have enough funds in your wallet to repay the full amount. If you proceed to repay with your current amount of funds, you will still have a small borrowing position in your dashboard.","You have no AAVE/stkAAVE balance to delegate.":"You have no AAVE/stkAAVE balance to delegate.","You have not borrow yet using this currency":"You have not borrow yet using this currency","You may borrow up to <0/> GHO at <1/> (max discount)":"You may borrow up to <0/> GHO at <1/> (max discount)","You may enter a custom amount in the field.":"You may enter a custom amount in the field.","You switched to {0} rate":["You switched to ",["0"]," rate"],"You unstake here":"You unstake here","You voted {0}":["You voted ",["0"]],"You will exit isolation mode and other tokens can now be used as collateral":"You will exit isolation mode and other tokens can now be used as collateral","You {action} <0/> {symbol}":["You ",["action"]," <0/> ",["symbol"]],"You've successfully switched borrow position.":"You've successfully switched borrow position.","You've successfully switched tokens.":"You've successfully switched tokens.","You've successfully withdrew & switched tokens.":"You've successfully withdrew & switched tokens.","Your balance is lower than the selected amount.":"Your balance is lower than the selected amount.","Your borrows":"Your borrows","Your current loan to value based on your collateral supplied.":"Your current loan to value based on your collateral supplied.","Your health factor and loan to value determine the assurance of your collateral. To avoid liquidations you can supply more collateral or repay borrow positions.":"Your health factor and loan to value determine the assurance of your collateral. To avoid liquidations you can supply more collateral or repay borrow positions.","Your info":"Your info","Your proposition power is based on your AAVE/stkAAVE balance and received delegations.":"Your proposition power is based on your AAVE/stkAAVE balance and received delegations.","Your reward balance is 0":"Your reward balance is 0","Your supplies":"Your supplies","Your voting info":"Your voting info","Your voting power is based on your AAVE/stkAAVE balance and received delegations.":"Your voting power is based on your AAVE/stkAAVE balance and received delegations.","Your {name} wallet is empty. Purchase or transfer assets or use <0>{0} to transfer your {network} assets.":["Your ",["name"]," wallet is empty. Purchase or transfer assets or use <0>",["0"]," to transfer your ",["network"]," assets."],"Your {name} wallet is empty. Purchase or transfer assets.":["Your ",["name"]," wallet is empty. Purchase or transfer assets."],"Your {networkName} wallet is empty. Get free test assets at":["Your ",["networkName"]," wallet is empty. Get free test assets at"],"Your {networkName} wallet is empty. Get free test {0} at":["Your ",["networkName"]," wallet is empty. Get free test ",["0"]," at"],"Zero address not valid":"Zero address not valid","assets":"assets","blocked activities":"blocked activities","copy the error":"copy the error","disabled":"disabled","documentation":"documentation","enabled":"enabled","ends":"ends","for":"for","of":"of","on":"on","please check that the amount you want to supply is not currently being used for staking. If it is being used for staking, your transaction might fail.":"please check that the amount you want to supply is not currently being used for staking. If it is being used for staking, your transaction might fail.","repaid":"repaid","stETH supplied as collateral will continue to accrue staking rewards provided by daily rebases.":"stETH supplied as collateral will continue to accrue staking rewards provided by daily rebases.","stETH tokens will be migrated to Wrapped stETH using Lido Protocol wrapper which leads to supply balance change after migration: {0}":["stETH tokens will be migrated to Wrapped stETH using Lido Protocol wrapper which leads to supply balance change after migration: ",["0"]],"staking view":"staking view","starts":"starts","stkAAVE holders get a discount on GHO borrow rate":"stkAAVE holders get a discount on GHO borrow rate","to":"to","tokens is not the same as staking them. If you wish to stake your":"tokens is not the same as staking them. If you wish to stake your","tokens, please go to the":"tokens, please go to the","withdrew":"withdrew","{0}":[["0"]],"{0} Balance":[["0"]," Balance"],"{0} Faucet":[["0"]," Faucet"],"{0} on-ramp service is provided by External Provider and by selecting you agree to Terms of the Provider. Your access to the service might be reliant on the External Provider being operational.":[["0"]," on-ramp service is provided by External Provider and by selecting you agree to Terms of the Provider. Your access to the service might be reliant on the External Provider being operational."],"{0}{name}":[["0"],["name"]],"{currentMethod}":[["currentMethod"]],"{d}d":[["d"],"d"],"{h}h":[["h"],"h"],"{m}m":[["m"],"m"],"{networkName} Faucet":[["networkName"]," Faucet"],"{notifyText}":[["notifyText"]],"{numSelected}/{numAvailable} assets selected":[["numSelected"],"/",["numAvailable"]," assets selected"],"{s}s":[["s"],"s"],"{title}":[["title"]],"{tooltipText}":[["tooltipText"]]}}; \ No newline at end of file +/*eslint-disable*/module.exports={messages:{"...":"...",".CSV":".CSV",".JSON":".JSON","<0><1><2/>Add <3/> stkAAVE to borrow at <4/> (max discount)":"<0><1><2/>Add <3/> stkAAVE to borrow at <4/> (max discount)","<0><1><2/>Add stkAAVE to see borrow rate with discount":"<0><1><2/>Add stkAAVE to see borrow rate with discount","<0>Ampleforth is a rebasing asset. Visit the <1>documentation to learn more.":"<0>Ampleforth is a rebasing asset. Visit the <1>documentation to learn more.","<0>Attention: Parameter changes via governance can alter your account health factor and risk of liquidation. Follow the <1>Aave governance forum for updates.":"<0>Attention: Parameter changes via governance can alter your account health factor and risk of liquidation. Follow the <1>Aave governance forum for updates.","<0>Slippage tolerance <1>{selectedSlippage}% <2>{0}":["<0>Slippage tolerance <1>",["selectedSlippage"],"% <2>",["0"],""],"AAVE holders (Ethereum network only) can stake their AAVE in the Safety Module to add more security to the protocol and earn Safety Incentives. In the case of a shortfall event, up to 30% of your stake can be slashed to cover the deficit, providing an additional layer of protection for the protocol.":"AAVE holders (Ethereum network only) can stake their AAVE in the Safety Module to add more security to the protocol and earn Safety Incentives. In the case of a shortfall event, up to 30% of your stake can be slashed to cover the deficit, providing an additional layer of protection for the protocol.","APR":"APR","APY":"APY","APY change":"APY change","APY type":"APY type","APY type change":"APY type change","APY with discount applied":"APY with discount applied","APY, fixed rate":"APY, fixed rate","APY, stable":"APY, stable","APY, variable":"APY, variable","AToken supply is not zero":"AToken supply is not zero","Aave Governance":"Aave Governance","Aave aToken":"Aave aToken","Aave debt token":"Aave debt token","Aave is a fully decentralized, community governed protocol by the AAVE token-holders. AAVE token-holders collectively discuss, propose, and vote on upgrades to the protocol. AAVE token-holders (Ethereum network only) can either vote themselves on new proposals or delagate to an address of choice. To learn more check out the Governance":"Aave is a fully decentralized, community governed protocol by the AAVE token-holders. AAVE token-holders collectively discuss, propose, and vote on upgrades to the protocol. AAVE token-holders (Ethereum network only) can either vote themselves on new proposals or delagate to an address of choice. To learn more check out the Governance","Aave per month":"Aave per month","About GHO":"About GHO","Account":"Account","Action cannot be performed because the reserve is frozen":"Action cannot be performed because the reserve is frozen","Action cannot be performed because the reserve is paused":"Action cannot be performed because the reserve is paused","Action requires an active reserve":"Action requires an active reserve","Activate Cooldown":"Activate Cooldown","Add stkAAVE to see borrow APY with the discount":"Add stkAAVE to see borrow APY with the discount","Add to wallet":"Add to wallet","Add {0} to wallet to track your balance.":["Add ",["0"]," to wallet to track your balance."],"Address is not a contract":"Address is not a contract","Addresses":"Addresses","Addresses ({0})":["Addresses (",["0"],")"],"All Assets":"All Assets","All done!":"All done!","All proposals":"All proposals","All transactions":"All transactions","Allowance required action":"Allowance required action","Allows you to decide whether to use a supplied asset as collateral. An asset used as collateral will affect your borrowing power and health factor.":"Allows you to decide whether to use a supplied asset as collateral. An asset used as collateral will affect your borrowing power and health factor.","Allows you to switch between <0>variable and <1>stable interest rates, where variable rate can increase and decrease depending on the amount of liquidity in the reserve, and stable rate will stay the same for the duration of your loan.":"Allows you to switch between <0>variable and <1>stable interest rates, where variable rate can increase and decrease depending on the amount of liquidity in the reserve, and stable rate will stay the same for the duration of your loan.","Amount":"Amount","Amount claimable":"Amount claimable","Amount in cooldown":"Amount in cooldown","Amount must be greater than 0":"Amount must be greater than 0","Amount to unstake":"Amount to unstake","An error has occurred fetching the proposal metadata from IPFS.":"An error has occurred fetching the proposal metadata from IPFS.","Approve Confirmed":"Approve Confirmed","Approve with":"Approve with","Approve {symbol} to continue":["Approve ",["symbol"]," to continue"],"Approving {symbol}...":["Approving ",["symbol"],"..."],"Array parameters that should be equal length are not":"Array parameters that should be equal length are not","Asset":"Asset","Asset can be only used as collateral in isolation mode with limited borrowing power. To enter isolation mode, disable all other collateral.":"Asset can be only used as collateral in isolation mode with limited borrowing power. To enter isolation mode, disable all other collateral.","Asset can only be used as collateral in isolation mode only.":"Asset can only be used as collateral in isolation mode only.","Asset cannot be migrated because you have isolated collateral in {marketName} v3 Market which limits borrowable assets. You can manage your collateral in <0>{marketName} V3 Dashboard":["Asset cannot be migrated because you have isolated collateral in ",["marketName"]," v3 Market which limits borrowable assets. You can manage your collateral in <0>",["marketName"]," V3 Dashboard"],"Asset cannot be migrated due to insufficient liquidity or borrow cap limitation in {marketName} v3 market.":["Asset cannot be migrated due to insufficient liquidity or borrow cap limitation in ",["marketName"]," v3 market."],"Asset cannot be migrated due to supply cap restriction in {marketName} v3 market.":["Asset cannot be migrated due to supply cap restriction in ",["marketName"]," v3 market."],"Asset cannot be migrated to {marketName} V3 Market due to E-mode restrictions. You can disable or manage E-mode categories in your <0>V3 Dashboard":["Asset cannot be migrated to ",["marketName"]," V3 Market due to E-mode restrictions. You can disable or manage E-mode categories in your <0>V3 Dashboard"],"Asset cannot be migrated to {marketName} v3 Market since collateral asset will enable isolation mode.":["Asset cannot be migrated to ",["marketName"]," v3 Market since collateral asset will enable isolation mode."],"Asset cannot be used as collateral.":"Asset cannot be used as collateral.","Asset category":"Asset category","Asset is frozen in {marketName} v3 market, hence this position cannot be migrated.":["Asset is frozen in ",["marketName"]," v3 market, hence this position cannot be migrated."],"Asset is not borrowable in isolation mode":"Asset is not borrowable in isolation mode","Asset is not listed":"Asset is not listed","Asset supply is limited to a certain amount to reduce protocol exposure to the asset and to help manage risks involved.":"Asset supply is limited to a certain amount to reduce protocol exposure to the asset and to help manage risks involved.","Assets":"Assets","Assets to borrow":"Assets to borrow","Assets to supply":"Assets to supply","Assets with zero LTV ({assetsBlockingWithdraw}) must be withdrawn or disabled as collateral to perform this action":["Assets with zero LTV (",["assetsBlockingWithdraw"],") must be withdrawn or disabled as collateral to perform this action"],"At a discount":"At a discount","Author":"Author","Available":"Available","Available assets":"Available assets","Available liquidity":"Available liquidity","Available on":"Available on","Available rewards":"Available rewards","Available to borrow":"Available to borrow","Available to supply":"Available to supply","Back to Dashboard":"Back to Dashboard","Balance":"Balance","Balance to revoke":"Balance to revoke","Be careful - You are very close to liquidation. Consider depositing more collateral or paying down some of your borrowed positions":"Be careful - You are very close to liquidation. Consider depositing more collateral or paying down some of your borrowed positions","Be mindful of the network congestion and gas prices.":"Be mindful of the network congestion and gas prices.","Because this asset is paused, no actions can be taken until further notice":"Because this asset is paused, no actions can be taken until further notice","Before supplying":"Before supplying","Blocked Address":"Blocked Address","Borrow":"Borrow","Borrow APY":"Borrow APY","Borrow APY rate":"Borrow APY rate","Borrow APY, fixed rate":"Borrow APY, fixed rate","Borrow APY, stable":"Borrow APY, stable","Borrow APY, variable":"Borrow APY, variable","Borrow amount to reach {0}% utilization":["Borrow amount to reach ",["0"],"% utilization"],"Borrow and repay in same block is not allowed":"Borrow and repay in same block is not allowed","Borrow apy":"Borrow apy","Borrow balance":"Borrow balance","Borrow balance after repay":"Borrow balance after repay","Borrow balance after switch":"Borrow balance after switch","Borrow cap":"Borrow cap","Borrow cap is exceeded":"Borrow cap is exceeded","Borrow info":"Borrow info","Borrow power used":"Borrow power used","Borrow rate change":"Borrow rate change","Borrow {symbol}":["Borrow ",["symbol"]],"Borrowed":"Borrowed","Borrowed asset amount":"Borrowed asset amount","Borrowing is currently unavailable for {0}.":["Borrowing is currently unavailable for ",["0"],"."],"Borrowing is disabled due to an Aave community decision. <0>More details":"Borrowing is disabled due to an Aave community decision. <0>More details","Borrowing is not enabled":"Borrowing is not enabled","Borrowing is unavailable because you’re using Isolation mode. To manage Isolation mode visit your <0>Dashboard.":"Borrowing is unavailable because you’re using Isolation mode. To manage Isolation mode visit your <0>Dashboard.","Borrowing is unavailable because you’ve enabled Efficiency Mode (E-Mode) and Isolation mode. To manage E-Mode and Isolation mode visit your <0>Dashboard.":"Borrowing is unavailable because you’ve enabled Efficiency Mode (E-Mode) and Isolation mode. To manage E-Mode and Isolation mode visit your <0>Dashboard.","Borrowing is unavailable because you’ve enabled Efficiency Mode (E-Mode) for {0} category. To manage E-Mode categories visit your <0>Dashboard.":["Borrowing is unavailable because you’ve enabled Efficiency Mode (E-Mode) for ",["0"]," category. To manage E-Mode categories visit your <0>Dashboard."],"Borrowing of this asset is limited to a certain amount to minimize liquidity pool insolvency.":"Borrowing of this asset is limited to a certain amount to minimize liquidity pool insolvency.","Borrowing power and assets are limited due to Isolation mode.":"Borrowing power and assets are limited due to Isolation mode.","Borrowing this amount will reduce your health factor and increase risk of liquidation.":"Borrowing this amount will reduce your health factor and increase risk of liquidation.","Borrowing {symbol}":["Borrowing ",["symbol"]],"Both":"Both","Buy Crypto With Fiat":"Buy Crypto With Fiat","Buy Crypto with Fiat":"Buy Crypto with Fiat","Buy {cryptoSymbol} with Fiat":["Buy ",["cryptoSymbol"]," with Fiat"],"COPIED!":"COPIED!","COPY IMAGE":"COPY IMAGE","Can be collateral":"Can be collateral","Can be executed":"Can be executed","Cancel":"Cancel","Cannot disable E-Mode":"Cannot disable E-Mode","Choose how much voting/proposition power to give to someone else by delegating some of your AAVE or stkAAVE balance. Your tokens will remain in your account, but your delegate will be able to vote or propose on your behalf. If your AAVE or stkAAVE balance changes, your delegate's voting/proposition power will be automatically adjusted.":"Choose how much voting/proposition power to give to someone else by delegating some of your AAVE or stkAAVE balance. Your tokens will remain in your account, but your delegate will be able to vote or propose on your behalf. If your AAVE or stkAAVE balance changes, your delegate's voting/proposition power will be automatically adjusted.","Choose one of the on-ramp services":"Choose one of the on-ramp services","Claim":"Claim","Claim all":"Claim all","Claim all rewards":"Claim all rewards","Claim {0}":["Claim ",["0"]],"Claim {symbol}":["Claim ",["symbol"]],"Claimable AAVE":"Claimable AAVE","Claimed":"Claimed","Claiming":"Claiming","Claiming {symbol}":["Claiming ",["symbol"]],"Close":"Close","Collateral":"Collateral","Collateral balance after repay":"Collateral balance after repay","Collateral change":"Collateral change","Collateral is (mostly) the same currency that is being borrowed":"Collateral is (mostly) the same currency that is being borrowed","Collateral to repay with":"Collateral to repay with","Collateral usage":"Collateral usage","Collateral usage is limited because of Isolation mode.":"Collateral usage is limited because of Isolation mode.","Collateral usage is limited because of isolation mode.":"Collateral usage is limited because of isolation mode.","Collateral usage is limited because of isolation mode. <0>Learn More":"Collateral usage is limited because of isolation mode. <0>Learn More","Collateralization":"Collateralization","Collector Contract":"Collector Contract","Collector Info":"Collector Info","Connect wallet":"Connect wallet","Cooldown period":"Cooldown period","Cooldown period warning":"Cooldown period warning","Cooldown time left":"Cooldown time left","Cooldown to unstake":"Cooldown to unstake","Cooling down...":"Cooling down...","Copy address":"Copy address","Copy error message":"Copy error message","Copy error text":"Copy error text","Covered debt":"Covered debt","Created":"Created","Current LTV":"Current LTV","Current differential":"Current differential","Current v2 Balance":"Current v2 Balance","Current v2 balance":"Current v2 balance","Current votes":"Current votes","DAI balance will be converted via DSR contracts and then supplied as sDAI. Switching incurs no additional costs and no slippage.":"DAI balance will be converted via DSR contracts and then supplied as sDAI. Switching incurs no additional costs and no slippage.","Dark mode":"Dark mode","Dashboard":"Dashboard","Data couldn't be fetched, please reload graph.":"Data couldn't be fetched, please reload graph.","Debt":"Debt","Debt ceiling is exceeded":"Debt ceiling is exceeded","Debt ceiling is not zero":"Debt ceiling is not zero","Debt ceiling limits the amount possible to borrow against this asset by protocol users. Debt ceiling is specific to assets in isolation mode and is denoted in USD.":"Debt ceiling limits the amount possible to borrow against this asset by protocol users. Debt ceiling is specific to assets in isolation mode and is denoted in USD.","Delegated power":"Delegated power","Details":"Details","Developers":"Developers","Differential":"Differential","Disable E-Mode":"Disable E-Mode","Disable testnet":"Disable testnet","Disable {symbol} as collateral":["Disable ",["symbol"]," as collateral"],"Disabled":"Disabled","Disabling E-Mode":"Disabling E-Mode","Disabling this asset as collateral affects your borrowing power and Health Factor.":"Disabling this asset as collateral affects your borrowing power and Health Factor.","Disconnect Wallet":"Disconnect Wallet","Discord channel":"Discord channel","Discount":"Discount","Discount applied for <0/> staking AAVE":"Discount applied for <0/> staking AAVE","Discount model parameters":"Discount model parameters","Discount parameters are decided by the Aave community and may be changed over time. Check Governance for updates and vote to participate. <0>Learn more":"Discount parameters are decided by the Aave community and may be changed over time. Check Governance for updates and vote to participate. <0>Learn more","Discountable amount":"Discountable amount","Docs":"Docs","Download":"Download","Due to internal stETH mechanics required for rebasing support, it is not possible to perform a collateral switch where stETH is the source token.":"Due to internal stETH mechanics required for rebasing support, it is not possible to perform a collateral switch where stETH is the source token.","Due to the Horizon bridge exploit, certain assets on the Harmony network are not at parity with Ethereum, which affects the Aave V3 Harmony market.":"Due to the Horizon bridge exploit, certain assets on the Harmony network are not at parity with Ethereum, which affects the Aave V3 Harmony market.","E-Mode":"E-Mode","E-Mode Category":"E-Mode Category","E-Mode category":"E-Mode category","E-Mode increases your LTV for a selected category of assets up to 97%. <0>Learn more":"E-Mode increases your LTV for a selected category of assets up to 97%. <0>Learn more","E-Mode increases your LTV for a selected category of assets up to<0/>. <1>Learn more":"E-Mode increases your LTV for a selected category of assets up to<0/>. <1>Learn more","E-Mode increases your LTV for a selected category of assets, meaning that when E-mode is enabled, you will have higher borrowing power over assets of the same E-mode category which are defined by Aave Governance. You can enter E-Mode from your <0>Dashboard. To learn more about E-Mode and applied restrictions in <1>FAQ or <2>Aave V3 Technical Paper.":"E-Mode increases your LTV for a selected category of assets, meaning that when E-mode is enabled, you will have higher borrowing power over assets of the same E-mode category which are defined by Aave Governance. You can enter E-Mode from your <0>Dashboard. To learn more about E-Mode and applied restrictions in <1>FAQ or <2>Aave V3 Technical Paper.","Effective interest rate":"Effective interest rate","Efficiency mode (E-Mode)":"Efficiency mode (E-Mode)","Emode":"Emode","Enable E-Mode":"Enable E-Mode","Enable {symbol} as collateral":["Enable ",["symbol"]," as collateral"],"Enabled":"Enabled","Enabling E-Mode":"Enabling E-Mode","Enabling E-Mode only allows you to borrow assets belonging to the selected category. Please visit our <0>FAQ guide to learn more about how it works and the applied restrictions.":"Enabling E-Mode only allows you to borrow assets belonging to the selected category. Please visit our <0>FAQ guide to learn more about how it works and the applied restrictions.","Enabling this asset as collateral increases your borrowing power and Health Factor. However, it can get liquidated if your health factor drops below 1.":"Enabling this asset as collateral increases your borrowing power and Health Factor. However, it can get liquidated if your health factor drops below 1.","Ended":"Ended","Ends":"Ends","English":"English","Enter ETH address":"Enter ETH address","Enter an amount":"Enter an amount","Error connecting. Try refreshing the page.":"Error connecting. Try refreshing the page.","Estimated compounding interest, including discount for Staking {0}AAVE in Safety Module.":["Estimated compounding interest, including discount for Staking ",["0"],"AAVE in Safety Module."],"Exceeds the discount":"Exceeds the discount","Exchange rate":"Exchange rate","Executed":"Executed","Expected amount to repay":"Expected amount to repay","Expires":"Expires","Export data to":"Export data to","FAQ":"FAQ","FAQS":"FAQS","Failed to load proposal voters. Please refresh the page.":"Failed to load proposal voters. Please refresh the page.","Faucet":"Faucet","Faucet {0}":["Faucet ",["0"]],"Fetching data...":"Fetching data...","Filter":"Filter","Fixed":"Fixed","Fixed rate":"Fixed rate","Flashloan is disabled for this asset, hence this position cannot be migrated.":"Flashloan is disabled for this asset, hence this position cannot be migrated.","For repayment of a specific type of debt, the user needs to have debt that type":"For repayment of a specific type of debt, the user needs to have debt that type","Forum discussion":"Forum discussion","French":"French","Funds in the Safety Module":"Funds in the Safety Module","GHO is a native decentralized, collateral-backed digital asset pegged to USD. It is created by users via borrowing against multiple collateral. When user repays their GHO borrow position, the protocol burns that user's GHO. All the interest payments accrued by minters of GHO would be directly transferred to the AaveDAO treasury.":"GHO is a native decentralized, collateral-backed digital asset pegged to USD. It is created by users via borrowing against multiple collateral. When user repays their GHO borrow position, the protocol burns that user's GHO. All the interest payments accrued by minters of GHO would be directly transferred to the AaveDAO treasury.","Get ABP Token":"Get ABP Token","Global settings":"Global settings","Go Back":"Go Back","Go to Balancer Pool":"Go to Balancer Pool","Go to V3 Dashboard":"Go to V3 Dashboard","Governance":"Governance","Greek":"Greek","Health Factor ({0} v2)":["Health Factor (",["0"]," v2)"],"Health Factor ({0} v3)":["Health Factor (",["0"]," v3)"],"Health factor":"Health factor","Health factor is lesser than the liquidation threshold":"Health factor is lesser than the liquidation threshold","Health factor is not below the threshold":"Health factor is not below the threshold","Hide":"Hide","Holders of stkAAVE receive a discount on the GHO borrowing rate":"Holders of stkAAVE receive a discount on the GHO borrowing rate","I acknowledge the risks involved.":"I acknowledge the risks involved.","I fully understand the risks of migrating.":"I fully understand the risks of migrating.","I understand how cooldown ({0}) and unstaking ({1}) work":["I understand how cooldown (",["0"],") and unstaking (",["1"],") work"],"If the error continues to happen,<0/> you may report it to this":"If the error continues to happen,<0/> you may report it to this","If the health factor goes below 1, the liquidation of your collateral might be triggered.":"If the health factor goes below 1, the liquidation of your collateral might be triggered.","If you DO NOT unstake within {0} of unstake window, you will need to activate cooldown process again.":["If you DO NOT unstake within ",["0"]," of unstake window, you will need to activate cooldown process again."],"If your loan to value goes above the liquidation threshold your collateral supplied may be liquidated.":"If your loan to value goes above the liquidation threshold your collateral supplied may be liquidated.","In E-Mode some assets are not borrowable. Exit E-Mode to get access to all assets":"In E-Mode some assets are not borrowable. Exit E-Mode to get access to all assets","In Isolation mode, you cannot supply other assets as collateral. A global debt ceiling limits the borrowing power of the isolated asset. To exit isolation mode disable {0} as collateral before borrowing another asset. Read more in our <0>FAQ":["In Isolation mode, you cannot supply other assets as collateral. A global debt ceiling limits the borrowing power of the isolated asset. To exit isolation mode disable ",["0"]," as collateral before borrowing another asset. Read more in our <0>FAQ"],"Inconsistent flashloan parameters":"Inconsistent flashloan parameters","Insufficient collateral to cover new borrow position. Wallet must have borrowing power remaining to perform debt switch.":"Insufficient collateral to cover new borrow position. Wallet must have borrowing power remaining to perform debt switch.","Interest accrued":"Interest accrued","Interest rate rebalance conditions were not met":"Interest rate rebalance conditions were not met","Interest rate strategy":"Interest rate strategy","Invalid amount to burn":"Invalid amount to burn","Invalid amount to mint":"Invalid amount to mint","Invalid bridge protocol fee":"Invalid bridge protocol fee","Invalid expiration":"Invalid expiration","Invalid flashloan premium":"Invalid flashloan premium","Invalid return value of the flashloan executor function":"Invalid return value of the flashloan executor function","Invalid signature":"Invalid signature","Isolated":"Isolated","Isolated Debt Ceiling":"Isolated Debt Ceiling","Isolated assets have limited borrowing power and other assets cannot be used as collateral.":"Isolated assets have limited borrowing power and other assets cannot be used as collateral.","Join the community discussion":"Join the community discussion","LEARN MORE":"LEARN MORE","Language":"Language","Learn more":"Learn more","Learn more about risks involved":"Learn more about risks involved","Learn more in our <0>FAQ guide":"Learn more in our <0>FAQ guide","Learn more.":"Learn more.","Links":"Links","Liqudation":"Liqudation","Liquidated collateral":"Liquidated collateral","Liquidation":"Liquidation","Liquidation <0/> threshold":"Liquidation <0/> threshold","Liquidation Threshold":"Liquidation Threshold","Liquidation at":"Liquidation at","Liquidation penalty":"Liquidation penalty","Liquidation risk":"Liquidation risk","Liquidation risk parameters":"Liquidation risk parameters","Liquidation threshold":"Liquidation threshold","Liquidation value":"Liquidation value","Loading data...":"Loading data...","Ltv validation failed":"Ltv validation failed","MAI has been paused due to a community decision. Supply, borrows and repays are impacted. <0>More details":"MAI has been paused due to a community decision. Supply, borrows and repays are impacted. <0>More details","MAX":"MAX","Manage analytics":"Manage analytics","Market":"Market","Markets":"Markets","Max":"Max","Max LTV":"Max LTV","Max slashing":"Max slashing","Max slippage":"Max slippage","Maximum amount available to borrow against this asset is limited because debt ceiling is at {0}%.":["Maximum amount available to borrow against this asset is limited because debt ceiling is at ",["0"],"%."],"Maximum amount available to borrow is <0/> {0} (<1/>).":["Maximum amount available to borrow is <0/> ",["0"]," (<1/>)."],"Maximum amount available to borrow is limited because protocol borrow cap is nearly reached.":"Maximum amount available to borrow is limited because protocol borrow cap is nearly reached.","Maximum amount available to supply is <0/> {0} (<1/>).":["Maximum amount available to supply is <0/> ",["0"]," (<1/>)."],"Maximum amount available to supply is limited because protocol supply cap is at {0}%.":["Maximum amount available to supply is limited because protocol supply cap is at ",["0"],"%."],"Maximum loan to value":"Maximum loan to value","Meet GHO":"Meet GHO","Menu":"Menu","Migrate":"Migrate","Migrate to V3":"Migrate to V3","Migrate to v3":"Migrate to v3","Migrate to {0} v3 Market":["Migrate to ",["0"]," v3 Market"],"Migrated":"Migrated","Migrating":"Migrating","Migrating multiple collaterals and borrowed assets at the same time can be an expensive operation and might fail in certain situations.<0>Therefore it’s not recommended to migrate positions with more than 5 assets (deposited + borrowed) at the same time.":"Migrating multiple collaterals and borrowed assets at the same time can be an expensive operation and might fail in certain situations.<0>Therefore it’s not recommended to migrate positions with more than 5 assets (deposited + borrowed) at the same time.","Migration risks":"Migration risks","Minimum GHO borrow amount":"Minimum GHO borrow amount","Minimum USD value received":"Minimum USD value received","Minimum staked Aave amount":"Minimum staked Aave amount","Minimum {0} received":["Minimum ",["0"]," received"],"More":"More","NAY":"NAY","Need help connecting a wallet? <0>Read our FAQ":"Need help connecting a wallet? <0>Read our FAQ","Net APR":"Net APR","Net APY":"Net APY","Net APY is the combined effect of all supply and borrow positions on net worth, including incentives. It is possible to have a negative net APY if debt APY is higher than supply APY.":"Net APY is the combined effect of all supply and borrow positions on net worth, including incentives. It is possible to have a negative net APY if debt APY is higher than supply APY.","Net worth":"Net worth","Network":"Network","Network not supported for this wallet":"Network not supported for this wallet","New APY":"New APY","No assets selected to migrate.":"No assets selected to migrate.","No rewards to claim":"No rewards to claim","No search results{0}":["No search results",["0"]],"No transactions yet.":"No transactions yet.","No voting power":"No voting power","None":"None","Not a valid address":"Not a valid address","Not enough balance on your wallet":"Not enough balance on your wallet","Not enough collateral to repay this amount of debt with":"Not enough collateral to repay this amount of debt with","Not enough staked balance":"Not enough staked balance","Not enough voting power to participate in this proposal":"Not enough voting power to participate in this proposal","Not reached":"Not reached","Nothing borrowed yet":"Nothing borrowed yet","Nothing found":"Nothing found","Nothing staked":"Nothing staked","Nothing supplied yet":"Nothing supplied yet","Notify":"Notify","Ok, Close":"Ok, Close","Ok, I got it":"Ok, I got it","Operation not supported":"Operation not supported","Oracle price":"Oracle price","Overview":"Overview","Page not found":"Page not found","Participating in this {symbol} reserve gives annualized rewards.":["Participating in this ",["symbol"]," reserve gives annualized rewards."],"Pending...":"Pending...","Per the community, the Fantom market has been frozen.":"Per the community, the Fantom market has been frozen.","Per the community, the V2 AMM market has been deprecated.":"Per the community, the V2 AMM market has been deprecated.","Please always be aware of your <0>Health Factor (HF) when partially migrating a position and that your rates will be updated to V3 rates.":"Please always be aware of your <0>Health Factor (HF) when partially migrating a position and that your rates will be updated to V3 rates.","Please connect a wallet to view your personal information here.":"Please connect a wallet to view your personal information here.","Please connect your wallet to be able to switch your tokens.":"Please connect your wallet to be able to switch your tokens.","Please connect your wallet to get free testnet assets.":"Please connect your wallet to get free testnet assets.","Please connect your wallet to see migration tool.":"Please connect your wallet to see migration tool.","Please connect your wallet to see your supplies, borrowings, and open positions.":"Please connect your wallet to see your supplies, borrowings, and open positions.","Please connect your wallet to view transaction history.":"Please connect your wallet to view transaction history.","Please enter a valid wallet address.":"Please enter a valid wallet address.","Please switch to {networkName}.":["Please switch to ",["networkName"],"."],"Please, connect your wallet":"Please, connect your wallet","Pool addresses provider is not registered":"Pool addresses provider is not registered","Powered by":"Powered by","Preview tx and migrate":"Preview tx and migrate","Price":"Price","Price data is not currently available for this reserve on the protocol subgraph":"Price data is not currently available for this reserve on the protocol subgraph","Price impact":"Price impact","Price impact is the spread between the total value of the entry tokens switched and the destination tokens obtained (in USD), which results from the limited liquidity of the trading pair.":"Price impact is the spread between the total value of the entry tokens switched and the destination tokens obtained (in USD), which results from the limited liquidity of the trading pair.","Price impact {0}%":["Price impact ",["0"],"%"],"Privacy":"Privacy","Proposal details":"Proposal details","Proposal overview":"Proposal overview","Proposals":"Proposals","Proposition":"Proposition","Protocol borrow cap at 100% for this asset. Further borrowing unavailable.":"Protocol borrow cap at 100% for this asset. Further borrowing unavailable.","Protocol borrow cap is at 100% for this asset. Further borrowing unavailable.":"Protocol borrow cap is at 100% for this asset. Further borrowing unavailable.","Protocol debt ceiling is at 100% for this asset. Further borrowing against this asset is unavailable.":"Protocol debt ceiling is at 100% for this asset. Further borrowing against this asset is unavailable.","Protocol debt ceiling is at 100% for this asset. Futher borrowing against this asset is unavailable.":"Protocol debt ceiling is at 100% for this asset. Futher borrowing against this asset is unavailable.","Protocol supply cap at 100% for this asset. Further supply unavailable.":"Protocol supply cap at 100% for this asset. Further supply unavailable.","Protocol supply cap is at 100% for this asset. Further supply unavailable.":"Protocol supply cap is at 100% for this asset. Further supply unavailable.","Quorum":"Quorum","Rate change":"Rate change","Raw-Ipfs":"Raw-Ipfs","Reached":"Reached","Reactivate cooldown period to unstake {0} {stakedToken}":["Reactivate cooldown period to unstake ",["0"]," ",["stakedToken"]],"Read more here.":"Read more here.","Read-only mode allows to see address positions in Aave, but you won't be able to perform transactions.":"Read-only mode allows to see address positions in Aave, but you won't be able to perform transactions.","Read-only mode.":"Read-only mode.","Read-only mode. Connect to a wallet to perform transactions.":"Read-only mode. Connect to a wallet to perform transactions.","Receive (est.)":"Receive (est.)","Received":"Received","Recipient address":"Recipient address","Rejected connection request":"Rejected connection request","Reload":"Reload","Reload the page":"Reload the page","Remaining debt":"Remaining debt","Remaining supply":"Remaining supply","Repaid":"Repaid","Repay":"Repay","Repay with":"Repay with","Repay {symbol}":["Repay ",["symbol"]],"Repaying {symbol}":["Repaying ",["symbol"]],"Repayment amount to reach {0}% utilization":["Repayment amount to reach ",["0"],"% utilization"],"Reserve Size":"Reserve Size","Reserve factor":"Reserve factor","Reserve factor is a percentage of interest which goes to a {0} that is controlled by Aave governance to promote ecosystem growth.":["Reserve factor is a percentage of interest which goes to a ",["0"]," that is controlled by Aave governance to promote ecosystem growth."],"Reserve status & configuration":"Reserve status & configuration","Reset":"Reset","Restake":"Restake","Restake {symbol}":["Restake ",["symbol"]],"Restaked":"Restaked","Restaking {symbol}":["Restaking ",["symbol"]],"Review approval tx details":"Review approval tx details","Review changes to continue":"Review changes to continue","Review tx":"Review tx","Review tx details":"Review tx details","Revoke power":"Revoke power","Reward(s) to claim":"Reward(s) to claim","Rewards APR":"Rewards APR","Risk details":"Risk details","SEE CHARTS":"SEE CHARTS","Safety of your deposited collateral against the borrowed assets and its underlying value.":"Safety of your deposited collateral against the borrowed assets and its underlying value.","Save and share":"Save and share","Seatbelt report":"Seatbelt report","Seems like we can't switch the network automatically. Please check if you can change it from the wallet.":"Seems like we can't switch the network automatically. Please check if you can change it from the wallet.","Select":"Select","Select APY type to switch":"Select APY type to switch","Select an asset":"Select an asset","Select language":"Select language","Select slippage tolerance":"Select slippage tolerance","Select v2 borrows to migrate":"Select v2 borrows to migrate","Select v2 supplies to migrate":"Select v2 supplies to migrate","Selected assets have successfully migrated. Visit the Market Dashboard to see them.":"Selected assets have successfully migrated. Visit the Market Dashboard to see them.","Selected borrow assets":"Selected borrow assets","Selected supply assets":"Selected supply assets","Send feedback":"Send feedback","Set up delegation":"Set up delegation","Setup notifications about your Health Factor using the Hal app.":"Setup notifications about your Health Factor using the Hal app.","Share on Lens":"Share on Lens","Share on twitter":"Share on twitter","Show":"Show","Show Frozen or paused assets":"Show Frozen or paused assets","Show assets with 0 balance":"Show assets with 0 balance","Sign to continue":"Sign to continue","Signatures ready":"Signatures ready","Signing":"Signing","Since this asset is frozen, the only available actions are withdraw and repay which can be accessed from the <0>Dashboard":"Since this asset is frozen, the only available actions are withdraw and repay which can be accessed from the <0>Dashboard","Since this is a test network, you can get any of the assets if you have ETH on your wallet":"Since this is a test network, you can get any of the assets if you have ETH on your wallet","Slippage":"Slippage","Slippage is the difference between the quoted and received amounts from changing market conditions between the moment the transaction is submitted and its verification.":"Slippage is the difference between the quoted and received amounts from changing market conditions between the moment the transaction is submitted and its verification.","Some migrated assets will not be used as collateral due to enabled isolation mode in {marketName} V3 Market. Visit <0>{marketName} V3 Dashboard to manage isolation mode.":["Some migrated assets will not be used as collateral due to enabled isolation mode in ",["marketName"]," V3 Market. Visit <0>",["marketName"]," V3 Dashboard to manage isolation mode."],"Something went wrong":"Something went wrong","Sorry, an unexpected error happened. In the meantime you may try reloading the page, or come back later.":"Sorry, an unexpected error happened. In the meantime you may try reloading the page, or come back later.","Sorry, we couldn't find the page you were looking for.":"Sorry, we couldn't find the page you were looking for.","Spanish":"Spanish","Stable":"Stable","Stable Interest Type is disabled for this currency":"Stable Interest Type is disabled for this currency","Stable borrowing is enabled":"Stable borrowing is enabled","Stable borrowing is not enabled":"Stable borrowing is not enabled","Stable debt supply is not zero":"Stable debt supply is not zero","Stable interest rate will <0>stay the same for the duration of your loan. Recommended for long-term loan periods and for users who prefer predictability.":"Stable interest rate will <0>stay the same for the duration of your loan. Recommended for long-term loan periods and for users who prefer predictability.","Stablecoin":"Stablecoin","Stake":"Stake","Stake AAVE":"Stake AAVE","Stake ABPT":"Stake ABPT","Stake cooldown activated":"Stake cooldown activated","Staked":"Staked","Staking":"Staking","Staking APR":"Staking APR","Staking Rewards":"Staking Rewards","Staking balance":"Staking balance","Staking discount":"Staking discount","Started":"Started","State":"State","Static interest rate that is determined by Aave Governance. This rate may be changed over time depending on the need for the GHO supply to contract/expand. <0>Learn more":"Static interest rate that is determined by Aave Governance. This rate may be changed over time depending on the need for the GHO supply to contract/expand. <0>Learn more","Supplied":"Supplied","Supplied asset amount":"Supplied asset amount","Supply":"Supply","Supply APY":"Supply APY","Supply apy":"Supply apy","Supply balance":"Supply balance","Supply balance after switch":"Supply balance after switch","Supply cap is exceeded":"Supply cap is exceeded","Supply cap on target reserve reached. Try lowering the amount.":"Supply cap on target reserve reached. Try lowering the amount.","Supply {symbol}":["Supply ",["symbol"]],"Supplying your":"Supplying your","Supplying {symbol}":["Supplying ",["symbol"]],"Switch":"Switch","Switch APY type":"Switch APY type","Switch E-Mode":"Switch E-Mode","Switch E-Mode category":"Switch E-Mode category","Switch Network":"Switch Network","Switch borrow position":"Switch borrow position","Switch rate":"Switch rate","Switch to":"Switch to","Switched":"Switched","Switching":"Switching","Switching E-Mode":"Switching E-Mode","Switching rate":"Switching rate","Techpaper":"Techpaper","Terms":"Terms","Test Assets":"Test Assets","Testnet mode":"Testnet mode","Testnet mode is ON":"Testnet mode is ON","Thank you for voting!!":"Thank you for voting!!","The % of your total borrowing power used. This is based on the amount of your collateral supplied and the total amount that you can borrow.":"The % of your total borrowing power used. This is based on the amount of your collateral supplied and the total amount that you can borrow.","The Aave Balancer Pool Token (ABPT) is a liquidity pool token. You can receive ABPT by depositing a combination of AAVE + ETH in the Balancer liquidity pool. You can then stake your BPT in the Safety Module to secure the protocol and earn Safety Incentives.":"The Aave Balancer Pool Token (ABPT) is a liquidity pool token. You can receive ABPT by depositing a combination of AAVE + ETH in the Balancer liquidity pool. You can then stake your BPT in the Safety Module to secure the protocol and earn Safety Incentives.","The Aave Protocol is programmed to always use the price of 1 GHO = $1. This is different from using market pricing via oracles for other crypto assets. This creates stabilizing arbitrage opportunities when the price of GHO fluctuates.":"The Aave Protocol is programmed to always use the price of 1 GHO = $1. This is different from using market pricing via oracles for other crypto assets. This creates stabilizing arbitrage opportunities when the price of GHO fluctuates.","The Maximum LTV ratio represents the maximum borrowing power of a specific collateral. For example, if a collateral has an LTV of 75%, the user can borrow up to 0.75 worth of ETH in the principal currency for every 1 ETH worth of collateral.":"The Maximum LTV ratio represents the maximum borrowing power of a specific collateral. For example, if a collateral has an LTV of 75%, the user can borrow up to 0.75 worth of ETH in the principal currency for every 1 ETH worth of collateral.","The Stable Rate is not enabled for this currency":"The Stable Rate is not enabled for this currency","The address of the pool addresses provider is invalid":"The address of the pool addresses provider is invalid","The app is running in testnet mode. Learn how it works in":"The app is running in testnet mode. Learn how it works in","The caller of the function is not an AToken":"The caller of the function is not an AToken","The caller of this function must be a pool":"The caller of this function must be a pool","The collateral balance is 0":"The collateral balance is 0","The collateral chosen cannot be liquidated":"The collateral chosen cannot be liquidated","The cooldown period is the time required prior to unstaking your tokens (20 days). You can only withdraw your assets from the Security Module after the cooldown period and within the unstake window.<0>Learn more":"The cooldown period is the time required prior to unstaking your tokens (20 days). You can only withdraw your assets from the Security Module after the cooldown period and within the unstake window.<0>Learn more","The cooldown period is {0}. After {1} of cooldown, you will enter unstake window of {2}. You will continue receiving rewards during cooldown and unstake window.":["The cooldown period is ",["0"],". After ",["1"]," of cooldown, you will enter unstake window of ",["2"],". You will continue receiving rewards during cooldown and unstake window."],"The effects on the health factor would cause liquidation. Try lowering the amount.":"The effects on the health factor would cause liquidation. Try lowering the amount.","The loan to value of the migrated positions would cause liquidation. Increase migrated collateral or reduce migrated borrow to continue.":"The loan to value of the migrated positions would cause liquidation. Increase migrated collateral or reduce migrated borrow to continue.","The requested amount is greater than the max loan size in stable rate mode":"The requested amount is greater than the max loan size in stable rate mode","The total amount of your assets denominated in USD that can be used as collateral for borrowing assets.":"The total amount of your assets denominated in USD that can be used as collateral for borrowing assets.","The underlying asset cannot be rescued":"The underlying asset cannot be rescued","The underlying balance needs to be greater than 0":"The underlying balance needs to be greater than 0","The weighted average of APY for all borrowed assets, including incentives.":"The weighted average of APY for all borrowed assets, including incentives.","The weighted average of APY for all supplied assets, including incentives.":"The weighted average of APY for all supplied assets, including incentives.","There are not enough funds in the{0}reserve to borrow":["There are not enough funds in the",["0"],"reserve to borrow"],"There is not enough collateral to cover a new borrow":"There is not enough collateral to cover a new borrow","There is not enough liquidity for the target asset to perform the switch. Try lowering the amount.":"There is not enough liquidity for the target asset to perform the switch. Try lowering the amount.","There was some error. Please try changing the parameters or <0><1>copy the error":"There was some error. Please try changing the parameters or <0><1>copy the error","These assets are temporarily frozen or paused by Aave community decisions, meaning that further supply / borrow, or rate swap of these assets are unavailable. Withdrawals and debt repayments are allowed. Follow the <0>Aave governance forum for further updates.":"These assets are temporarily frozen or paused by Aave community decisions, meaning that further supply / borrow, or rate swap of these assets are unavailable. Withdrawals and debt repayments are allowed. Follow the <0>Aave governance forum for further updates.","These funds have been borrowed and are not available for withdrawal at this time.":"These funds have been borrowed and are not available for withdrawal at this time.","This action will reduce V2 health factor below liquidation threshold. retain collateral or migrate borrow position to continue.":"This action will reduce V2 health factor below liquidation threshold. retain collateral or migrate borrow position to continue.","This action will reduce health factor of V3 below liquidation threshold. Increase migrated collateral or reduce migrated borrow to continue.":"This action will reduce health factor of V3 below liquidation threshold. Increase migrated collateral or reduce migrated borrow to continue.","This action will reduce your health factor. Please be mindful of the increased risk of collateral liquidation.":"This action will reduce your health factor. Please be mindful of the increased risk of collateral liquidation.","This address is blocked on app.aave.com because it is associated with one or more":"This address is blocked on app.aave.com because it is associated with one or more","This asset has almost reached its borrow cap. There is only {messageValue} available to be borrowed from this market.":["This asset has almost reached its borrow cap. There is only ",["messageValue"]," available to be borrowed from this market."],"This asset has almost reached its supply cap. There can only be {messageValue} supplied to this market.":["This asset has almost reached its supply cap. There can only be ",["messageValue"]," supplied to this market."],"This asset has reached its borrow cap. Nothing is available to be borrowed from this market.":"This asset has reached its borrow cap. Nothing is available to be borrowed from this market.","This asset has reached its supply cap. Nothing is available to be supplied from this market.":"This asset has reached its supply cap. Nothing is available to be supplied from this market.","This asset is frozen due to an Aave Protocol Governance decision. <0>More details":"This asset is frozen due to an Aave Protocol Governance decision. <0>More details","This asset is frozen due to an Aave Protocol Governance decision. On the 20th of December 2022, renFIL will no longer be supported and cannot be bridged back to its native network. It is recommended to withdraw supply positions and repay borrow positions so that renFIL can be bridged back to FIL before the deadline. After this date, it will no longer be possible to convert renFIL to FIL. <0>More details":"This asset is frozen due to an Aave Protocol Governance decision. On the 20th of December 2022, renFIL will no longer be supported and cannot be bridged back to its native network. It is recommended to withdraw supply positions and repay borrow positions so that renFIL can be bridged back to FIL before the deadline. After this date, it will no longer be possible to convert renFIL to FIL. <0>More details","This asset is frozen due to an Aave community decision. <0>More details":"This asset is frozen due to an Aave community decision. <0>More details","This asset is planned to be offboarded due to an Aave Protocol Governance decision. <0>More details":"This asset is planned to be offboarded due to an Aave Protocol Governance decision. <0>More details","This gas calculation is only an estimation. Your wallet will set the price of the transaction. You can modify the gas settings directly from your wallet provider.":"This gas calculation is only an estimation. Your wallet will set the price of the transaction. You can modify the gas settings directly from your wallet provider.","This integration was<0>proposed and approvedby the community.":"This integration was<0>proposed and approvedby the community.","This is the total amount available for you to borrow. You can borrow based on your collateral and until the borrow cap is reached.":"This is the total amount available for you to borrow. You can borrow based on your collateral and until the borrow cap is reached.","This is the total amount that you are able to supply to in this reserve. You are able to supply your wallet balance up until the supply cap is reached.":"This is the total amount that you are able to supply to in this reserve. You are able to supply your wallet balance up until the supply cap is reached.","This represents the threshold at which a borrow position will be considered undercollateralized and subject to liquidation for each collateral. For example, if a collateral has a liquidation threshold of 80%, it means that the position will be liquidated when the debt value is worth 80% of the collateral value.":"This represents the threshold at which a borrow position will be considered undercollateralized and subject to liquidation for each collateral. For example, if a collateral has a liquidation threshold of 80%, it means that the position will be liquidated when the debt value is worth 80% of the collateral value.","Time left to be able to withdraw your staked asset.":"Time left to be able to withdraw your staked asset.","Time left to unstake":"Time left to unstake","Time left until the withdrawal window closes.":"Time left until the withdrawal window closes.","Tip: Try increasing slippage or reduce input amount":"Tip: Try increasing slippage or reduce input amount","To borrow you need to supply any asset to be used as collateral.":"To borrow you need to supply any asset to be used as collateral.","To continue, you need to grant Aave smart contracts permission to move your funds from your wallet. Depending on the asset and wallet you use, it is done by signing the permission message (gas free), or by submitting an approval transaction (requires gas). <0>Learn more":"To continue, you need to grant Aave smart contracts permission to move your funds from your wallet. Depending on the asset and wallet you use, it is done by signing the permission message (gas free), or by submitting an approval transaction (requires gas). <0>Learn more","To enable E-mode for the {0} category, all borrow positions outside of this category must be closed.":["To enable E-mode for the ",["0"]," category, all borrow positions outside of this category must be closed."],"To repay on behalf of a user an explicit amount to repay is needed":"To repay on behalf of a user an explicit amount to repay is needed","To request access for this permissioned market, please visit: <0>Acces Provider Name":"To request access for this permissioned market, please visit: <0>Acces Provider Name","To submit a proposal for minor changes to the protocol, you'll need at least 80.00K power. If you want to change the core code base, you'll need 320k power.<0>Learn more.":"To submit a proposal for minor changes to the protocol, you'll need at least 80.00K power. If you want to change the core code base, you'll need 320k power.<0>Learn more.","Top 10 addresses":"Top 10 addresses","Total available":"Total available","Total borrowed":"Total borrowed","Total borrows":"Total borrows","Total emission per day":"Total emission per day","Total interest accrued":"Total interest accrued","Total market size":"Total market size","Total supplied":"Total supplied","Total voting power":"Total voting power","Total worth":"Total worth","Track wallet":"Track wallet","Track wallet balance in read-only mode":"Track wallet balance in read-only mode","Transaction failed":"Transaction failed","Transaction history":"Transaction history","Transaction history is not currently available for this market":"Transaction history is not currently available for this market","Transaction overview":"Transaction overview","Transactions":"Transactions","UNSTAKE {symbol}":["UNSTAKE ",["symbol"]],"Unavailable":"Unavailable","Unbacked":"Unbacked","Unbacked mint cap is exceeded":"Unbacked mint cap is exceeded","Underlying asset does not exist in {marketName} v3 Market, hence this position cannot be migrated.":["Underlying asset does not exist in ",["marketName"]," v3 Market, hence this position cannot be migrated."],"Underlying token":"Underlying token","Unstake now":"Unstake now","Unstake window":"Unstake window","Unstaked":"Unstaked","Unstaking {symbol}":["Unstaking ",["symbol"]],"Update: Disruptions reported for WETH, WBTC, WMATIC, and USDT. AIP 230 will resolve the disruptions and the market will be operating as normal on ~26th May 13h00 UTC.":"Update: Disruptions reported for WETH, WBTC, WMATIC, and USDT. AIP 230 will resolve the disruptions and the market will be operating as normal on ~26th May 13h00 UTC.","Use it to vote for or against active proposals.":"Use it to vote for or against active proposals.","Use your AAVE and stkAAVE balance to delegate your voting and proposition powers. You will not be sending any tokens, only the rights to vote and propose changes to the protocol. You can re-delegate or revoke power to self at any time.":"Use your AAVE and stkAAVE balance to delegate your voting and proposition powers. You will not be sending any tokens, only the rights to vote and propose changes to the protocol. You can re-delegate or revoke power to self at any time.","Used as collateral":"Used as collateral","User cannot withdraw more than the available balance":"User cannot withdraw more than the available balance","User did not borrow the specified currency":"User did not borrow the specified currency","User does not have outstanding stable rate debt on this reserve":"User does not have outstanding stable rate debt on this reserve","User does not have outstanding variable rate debt on this reserve":"User does not have outstanding variable rate debt on this reserve","User is in isolation mode":"User is in isolation mode","User is trying to borrow multiple assets including a siloed one":"User is trying to borrow multiple assets including a siloed one","Users who stake AAVE in Safety Module (i.e. stkAAVE holders) receive a discount on GHO borrow interest rate. The discount applies to 100 GHO for every 1 stkAAVE held. Use the calculator below to see GHO borrow rate with the discount applied.":"Users who stake AAVE in Safety Module (i.e. stkAAVE holders) receive a discount on GHO borrow interest rate. The discount applies to 100 GHO for every 1 stkAAVE held. Use the calculator below to see GHO borrow rate with the discount applied.","Utilization Rate":"Utilization Rate","VIEW TX":"VIEW TX","VOTE NAY":"VOTE NAY","VOTE YAE":"VOTE YAE","Variable":"Variable","Variable debt supply is not zero":"Variable debt supply is not zero","Variable interest rate will <0>fluctuate based on the market conditions. Recommended for short-term positions.":"Variable interest rate will <0>fluctuate based on the market conditions. Recommended for short-term positions.","Variable rate":"Variable rate","Version 2":"Version 2","Version 3":"Version 3","View":"View","View Transactions":"View Transactions","View all votes":"View all votes","View contract":"View contract","View details":"View details","View on Explorer":"View on Explorer","Vote NAY":"Vote NAY","Vote YAE":"Vote YAE","Voted NAY":"Voted NAY","Voted YAE":"Voted YAE","Votes":"Votes","Voting":"Voting","Voting power":"Voting power","Voting results":"Voting results","Wallet Balance":"Wallet Balance","Wallet balance":"Wallet balance","Wallet not detected. Connect or install wallet and retry":"Wallet not detected. Connect or install wallet and retry","Wallets are provided by External Providers and by selecting you agree to Terms of those Providers. Your access to the wallet might be reliant on the External Provider being operational.":"Wallets are provided by External Providers and by selecting you agree to Terms of those Providers. Your access to the wallet might be reliant on the External Provider being operational.","We couldn't find any assets related to your search. Try again with a different asset name, symbol, or address.":"We couldn't find any assets related to your search. Try again with a different asset name, symbol, or address.","We couldn't find any transactions related to your search. Try again with a different asset name, or reset filters.":"We couldn't find any transactions related to your search. Try again with a different asset name, or reset filters.","We couldn’t detect a wallet. Connect a wallet to stake and view your balance.":"We couldn’t detect a wallet. Connect a wallet to stake and view your balance.","We suggest you go back to the Dashboard.":"We suggest you go back to the Dashboard.","Website":"Website","When a liquidation occurs, liquidators repay up to 50% of the outstanding borrowed amount on behalf of the borrower. In return, they can buy the collateral at a discount and keep the difference (liquidation penalty) as a bonus.":"When a liquidation occurs, liquidators repay up to 50% of the outstanding borrowed amount on behalf of the borrower. In return, they can buy the collateral at a discount and keep the difference (liquidation penalty) as a bonus.","With a voting power of <0/>":"With a voting power of <0/>","With testnet Faucet you can get free assets to test the Aave Protocol. Make sure to switch your wallet provider to the appropriate testnet network, select desired asset, and click ‘Faucet’ to get tokens transferred to your wallet. The assets on a testnet are not “real,” meaning they have no monetary value. <0>Learn more":"With testnet Faucet you can get free assets to test the Aave Protocol. Make sure to switch your wallet provider to the appropriate testnet network, select desired asset, and click ‘Faucet’ to get tokens transferred to your wallet. The assets on a testnet are not “real,” meaning they have no monetary value. <0>Learn more","Withdraw":"Withdraw","Withdraw & Switch":"Withdraw & Switch","Withdraw and Switch":"Withdraw and Switch","Withdraw {symbol}":["Withdraw ",["symbol"]],"Withdrawing":"Withdrawing","Withdrawing and Switching":"Withdrawing and Switching","Withdrawing this amount will reduce your health factor and increase risk of liquidation.":"Withdrawing this amount will reduce your health factor and increase risk of liquidation.","Withdrawing {symbol}":["Withdrawing ",["symbol"]],"Wrong Network":"Wrong Network","YAE":"YAE","You are entering Isolation mode":"You are entering Isolation mode","You can borrow this asset with a stable rate only if you borrow more than the amount you are supplying as collateral.":"You can borrow this asset with a stable rate only if you borrow more than the amount you are supplying as collateral.","You can not change Interest Type to stable as your borrowings are higher than your collateral":"You can not change Interest Type to stable as your borrowings are higher than your collateral","You can not disable E-Mode as your current collateralization level is above 80%, disabling E-Mode can cause liquidation. To exit E-Mode supply or repay borrowed positions.":"You can not disable E-Mode as your current collateralization level is above 80%, disabling E-Mode can cause liquidation. To exit E-Mode supply or repay borrowed positions.","You can not switch usage as collateral mode for this currency, because it will cause collateral call":"You can not switch usage as collateral mode for this currency, because it will cause collateral call","You can not use this currency as collateral":"You can not use this currency as collateral","You can not withdraw this amount because it will cause collateral call":"You can not withdraw this amount because it will cause collateral call","You can only switch to tokens with variable APY types. After this transaction, you may change the variable rate to a stable one if available.":"You can only switch to tokens with variable APY types. After this transaction, you may change the variable rate to a stable one if available.","You can only withdraw your assets from the Security Module after the cooldown period ends and the unstake window is active.":"You can only withdraw your assets from the Security Module after the cooldown period ends and the unstake window is active.","You can report incident to our <0>Discord or<1>Github.":"You can report incident to our <0>Discord or<1>Github.","You cancelled the transaction.":"You cancelled the transaction.","You did not participate in this proposal":"You did not participate in this proposal","You do not have supplies in this currency":"You do not have supplies in this currency","You don’t have enough funds in your wallet to repay the full amount. If you proceed to repay with your current amount of funds, you will still have a small borrowing position in your dashboard.":"You don’t have enough funds in your wallet to repay the full amount. If you proceed to repay with your current amount of funds, you will still have a small borrowing position in your dashboard.","You have no AAVE/stkAAVE balance to delegate.":"You have no AAVE/stkAAVE balance to delegate.","You have not borrow yet using this currency":"You have not borrow yet using this currency","You may borrow up to <0/> GHO at <1/> (max discount)":"You may borrow up to <0/> GHO at <1/> (max discount)","You may enter a custom amount in the field.":"You may enter a custom amount in the field.","You switched to {0} rate":["You switched to ",["0"]," rate"],"You unstake here":"You unstake here","You voted {0}":["You voted ",["0"]],"You will exit isolation mode and other tokens can now be used as collateral":"You will exit isolation mode and other tokens can now be used as collateral","You {action} <0/> {symbol}":["You ",["action"]," <0/> ",["symbol"]],"You've successfully switched borrow position.":"You've successfully switched borrow position.","You've successfully switched tokens.":"You've successfully switched tokens.","You've successfully withdrew & switched tokens.":"You've successfully withdrew & switched tokens.","Your balance is lower than the selected amount.":"Your balance is lower than the selected amount.","Your borrows":"Your borrows","Your current loan to value based on your collateral supplied.":"Your current loan to value based on your collateral supplied.","Your health factor and loan to value determine the assurance of your collateral. To avoid liquidations you can supply more collateral or repay borrow positions.":"Your health factor and loan to value determine the assurance of your collateral. To avoid liquidations you can supply more collateral or repay borrow positions.","Your info":"Your info","Your proposition power is based on your AAVE/stkAAVE balance and received delegations.":"Your proposition power is based on your AAVE/stkAAVE balance and received delegations.","Your reward balance is 0":"Your reward balance is 0","Your supplies":"Your supplies","Your voting info":"Your voting info","Your voting power is based on your AAVE/stkAAVE balance and received delegations.":"Your voting power is based on your AAVE/stkAAVE balance and received delegations.","Your {name} wallet is empty. Purchase or transfer assets or use <0>{0} to transfer your {network} assets.":["Your ",["name"]," wallet is empty. Purchase or transfer assets or use <0>",["0"]," to transfer your ",["network"]," assets."],"Your {name} wallet is empty. Purchase or transfer assets.":["Your ",["name"]," wallet is empty. Purchase or transfer assets."],"Your {networkName} wallet is empty. Get free test assets at":["Your ",["networkName"]," wallet is empty. Get free test assets at"],"Your {networkName} wallet is empty. Get free test {0} at":["Your ",["networkName"]," wallet is empty. Get free test ",["0"]," at"],"Zero address not valid":"Zero address not valid","assets":"assets","blocked activities":"blocked activities","copy the error":"copy the error","disabled":"disabled","documentation":"documentation","enabled":"enabled","ends":"ends","for":"for","of":"of","on":"on","please check that the amount you want to supply is not currently being used for staking. If it is being used for staking, your transaction might fail.":"please check that the amount you want to supply is not currently being used for staking. If it is being used for staking, your transaction might fail.","repaid":"repaid","stETH supplied as collateral will continue to accrue staking rewards provided by daily rebases.":"stETH supplied as collateral will continue to accrue staking rewards provided by daily rebases.","stETH tokens will be migrated to Wrapped stETH using Lido Protocol wrapper which leads to supply balance change after migration: {0}":["stETH tokens will be migrated to Wrapped stETH using Lido Protocol wrapper which leads to supply balance change after migration: ",["0"]],"staking view":"staking view","starts":"starts","stkAAVE holders get a discount on GHO borrow rate":"stkAAVE holders get a discount on GHO borrow rate","to":"to","tokens is not the same as staking them. If you wish to stake your":"tokens is not the same as staking them. If you wish to stake your","tokens, please go to the":"tokens, please go to the","withdrew":"withdrew","{0}":[["0"]],"{0} Balance":[["0"]," Balance"],"{0} Faucet":[["0"]," Faucet"],"{0} on-ramp service is provided by External Provider and by selecting you agree to Terms of the Provider. Your access to the service might be reliant on the External Provider being operational.":[["0"]," on-ramp service is provided by External Provider and by selecting you agree to Terms of the Provider. Your access to the service might be reliant on the External Provider being operational."],"{0}{name}":[["0"],["name"]],"{currentMethod}":[["currentMethod"]],"{d}d":[["d"],"d"],"{h}h":[["h"],"h"],"{m}m":[["m"],"m"],"{networkName} Faucet":[["networkName"]," Faucet"],"{notifyText}":[["notifyText"]],"{numSelected}/{numAvailable} assets selected":[["numSelected"],"/",["numAvailable"]," assets selected"],"{s}s":[["s"],"s"],"{title}":[["title"]],"{tooltipText}":[["tooltipText"]]}}; \ No newline at end of file diff --git a/src/locales/en/messages.po b/src/locales/en/messages.po index 6a878ea3b4..8be2a67df3 100644 --- a/src/locales/en/messages.po +++ b/src/locales/en/messages.po @@ -792,10 +792,6 @@ msgstr "Current v2 balance" msgid "Current votes" msgstr "Current votes" -#: src/components/transactions/Supply/SupplyModalContent.tsx -msgid "DAI balance will be converted via DSR contracts and then supplied as sDAI to Aave reserve. Switching incurs no additional costs and no slippage." -msgstr "DAI balance will be converted via DSR contracts and then supplied as sDAI to Aave reserve. Switching incurs no additional costs and no slippage." - #: src/components/infoTooltips/WrappedTokenToolTipContent.tsx msgid "DAI balance will be converted via DSR contracts and then supplied as sDAI. Switching incurs no additional costs and no slippage." msgstr "DAI balance will be converted via DSR contracts and then supplied as sDAI. Switching incurs no additional costs and no slippage." @@ -1019,7 +1015,6 @@ msgid "Exceeds the discount" msgstr "Exceeds the discount" #: src/components/infoTooltips/WrappedTokenToolTipContent.tsx -#: src/components/transactions/Supply/SupplyModalContent.tsx msgid "Exchange rate" msgstr "Exchange rate" diff --git a/src/modules/dashboard/lists/SupplyAssetsList/SupplyAssetsList.tsx b/src/modules/dashboard/lists/SupplyAssetsList/SupplyAssetsList.tsx index 2dda4bc184..716bf51be6 100644 --- a/src/modules/dashboard/lists/SupplyAssetsList/SupplyAssetsList.tsx +++ b/src/modules/dashboard/lists/SupplyAssetsList/SupplyAssetsList.tsx @@ -9,7 +9,6 @@ import { ListHeaderTitle } from 'src/components/lists/ListHeaderTitle'; import { ListHeaderWrapper } from 'src/components/lists/ListHeaderWrapper'; import { Warning } from 'src/components/primitives/Warning'; import { MarketWarning } from 'src/components/transactions/Warnings/MarketWarning'; -import { useTokenInBalances } from 'src/hooks/token-wrapper/useTokenWrapper'; import { AssetCapsProvider } from 'src/hooks/useAssetCaps'; import { useRootStore } from 'src/store/root'; import { fetchIconSymbolAndName } from 'src/ui-config/reservePatches'; @@ -54,8 +53,6 @@ export const SupplyAssetsList = () => { loading: loadingReserves, wrappedTokenReserves, } = useAppDataContext(); - const foo = useTokenInBalances(wrappedTokenReserves); - console.log('FOOOO', foo.data); const { walletBalances, loading } = useWalletBalances(currentMarketData); const [displayGho] = useRootStore((store) => [store.displayGho]); const theme = useTheme(); diff --git a/src/ui-config/marketsConfig.tsx b/src/ui-config/marketsConfig.tsx index ffa553a14b..0fd779afe8 100644 --- a/src/ui-config/marketsConfig.tsx +++ b/src/ui-config/marketsConfig.tsx @@ -67,7 +67,6 @@ export type MarketDataType = { V3_MIGRATOR?: string; GHO_TOKEN_ADDRESS?: string; GHO_UI_DATA_PROVIDER?: string; - SDAI_TOKEN_WRAPPER?: string; }; /** * https://www.hal.xyz/ has integrated aave for healtfactor warning notification @@ -143,7 +142,6 @@ export const marketsData: { GHO_UI_DATA_PROVIDER: AaveV3Ethereum.UI_GHO_DATA_PROVIDER, WITHDRAW_SWITCH_ADAPTER: AaveV3Ethereum.WITHDRAW_SWAP_ADAPTER, DEBT_SWITCH_ADAPTER: AaveV3Ethereum.DEBT_SWAP_ADAPTER, - SDAI_TOKEN_WRAPPER: '0x437f428930669cd06adab2df4a8d4b203ac729c6', }, halIntegration: { URL: 'https://app.hal.xyz/recipes/aave-v3-track-health-factor', diff --git a/src/ui-config/wrappedTokenConfig.ts b/src/ui-config/wrappedTokenConfig.ts index e3f1430be7..0df3b496cf 100644 --- a/src/ui-config/wrappedTokenConfig.ts +++ b/src/ui-config/wrappedTokenConfig.ts @@ -12,7 +12,6 @@ interface Token { decimals?: number; } -// TODO: need to consider v2/v3 markets export const wrappedTokenConfig: { [chainId: number]: WrappedTokenConfig[] } = { [ChainId.mainnet]: [ { @@ -24,19 +23,7 @@ export const wrappedTokenConfig: { [chainId: number]: WrappedTokenConfig[] } = { underlyingAsset: '0x83f20f44975d03b1b09e64809b757c47f942beea'.toLowerCase(), symbol: 'sDAI', }, - tokenWrapperContractAddress: '0x437f428930669cd06adab2df4a8d4b203ac729c6', - }, - { - tokenIn: { - decimals: 18, - underlyingAsset: '0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84'.toLowerCase(), - symbol: 'stETH', - }, - tokenOut: { - underlyingAsset: '0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0'.toLowerCase(), - symbol: 'wstETH', - }, - tokenWrapperContractAddress: '0x14aa09449fac437b5c0110614be2c08610e38f62', + tokenWrapperContractAddress: '0x5d4d4007a4c6336550ddaa2a7c0d5e7972eebd16', }, ], }; From d230bc085b6c3bb2ccb164228b8f97357e5aca64 Mon Sep 17 00:00:00 2001 From: Mark Grothe Date: Tue, 21 Nov 2023 21:10:49 -0600 Subject: [PATCH 35/46] fix: disable permit --- .../transactions/Supply/SupplyWrappedTokenActions.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/transactions/Supply/SupplyWrappedTokenActions.tsx b/src/components/transactions/Supply/SupplyWrappedTokenActions.tsx index c4d73f4dfc..1d7ea068b0 100644 --- a/src/components/transactions/Supply/SupplyWrappedTokenActions.tsx +++ b/src/components/transactions/Supply/SupplyWrappedTokenActions.tsx @@ -199,7 +199,7 @@ export const SupplyWrappedTokenActions = ({ handleApproval={() => approvalAction()} handleAction={action} requiresApproval={requiresApproval} - tryPermit + tryPermit={false} // TODO sx={sx} {...props} /> From 6ffafe5c3bd4dde48235deb588920e699d37dc3c Mon Sep 17 00:00:00 2001 From: Mark Grothe Date: Tue, 21 Nov 2023 21:48:54 -0600 Subject: [PATCH 36/46] fix: cleanup --- package.json | 4 ++-- .../transactions/Supply/SupplyModalContent.tsx | 6 +----- yarn.lock | 16 ++++++++-------- 3 files changed, 11 insertions(+), 15 deletions(-) diff --git a/package.json b/package.json index 8e37e03cea..5b54f2d75c 100644 --- a/package.json +++ b/package.json @@ -32,8 +32,8 @@ "test:coverage": "jest --coverage" }, "dependencies": { - "@aave/contract-helpers": "1.21.1-3c5fc7ba506d4aceaf433900344ace2f391e397b.0", - "@aave/math-utils": "1.20.1-8d191bf193b4e5f74af4086481eb6f23a17f39e5.0", + "@aave/contract-helpers": "1.21.2-c8b03e9731a7d5b362e28af3eba6de7d9ba106ba.0", + "@aave/math-utils": "1.21.2-c8b03e9731a7d5b362e28af3eba6de7d9ba106ba.0", "@bgd-labs/aave-address-book": "^2.7.0", "@emotion/cache": "11.10.3", "@emotion/react": "11.10.4", diff --git a/src/components/transactions/Supply/SupplyModalContent.tsx b/src/components/transactions/Supply/SupplyModalContent.tsx index 3b9c7f8095..f530629486 100644 --- a/src/components/transactions/Supply/SupplyModalContent.tsx +++ b/src/components/transactions/Supply/SupplyModalContent.tsx @@ -50,10 +50,6 @@ import { SNXWarning } from '../Warnings/SNXWarning'; import { SupplyActions } from './SupplyActions'; import { SupplyWrappedTokenActions } from './SupplyWrappedTokenActions'; -interface SupplyAsset extends Asset { - balance: string; -} - export enum ErrorType { CAP_REACHED, } @@ -309,7 +305,7 @@ export const SupplyWrappedTokenModalContent = ({ }); } - const [tokenToSupply, setTokenToSupply] = useState(assets[0]); + const [tokenToSupply, setTokenToSupply] = useState(assets[0]); const [amount, setAmount] = useState(''); const [convertedTokenInAmount, setConvertedTokenInAmount] = useState('0'); const { data: exchangeRate } = useTokenInForTokenOut( diff --git a/yarn.lock b/yarn.lock index 3ed3130065..c4e44a0696 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,17 +2,17 @@ # yarn lockfile v1 -"@aave/contract-helpers@1.21.1-3c5fc7ba506d4aceaf433900344ace2f391e397b.0": - version "1.21.1-3c5fc7ba506d4aceaf433900344ace2f391e397b.0" - resolved "https://registry.yarnpkg.com/@aave/contract-helpers/-/contract-helpers-1.21.1-3c5fc7ba506d4aceaf433900344ace2f391e397b.0.tgz#680026aed17cc839c9b6fa56b56cece2da095096" - integrity sha512-zR1LC9dgoquNop55o74GCkGYT1xaTH7JGiOgNshFb1gQaci+KEwqNTIDlCtSBFIg3mTc4NJXHu75Qz3n8HxyBA== +"@aave/contract-helpers@1.21.2-c8b03e9731a7d5b362e28af3eba6de7d9ba106ba.0": + version "1.21.2-c8b03e9731a7d5b362e28af3eba6de7d9ba106ba.0" + resolved "https://registry.yarnpkg.com/@aave/contract-helpers/-/contract-helpers-1.21.2-c8b03e9731a7d5b362e28af3eba6de7d9ba106ba.0.tgz#95f5451a970f9c9644bca9e13f08c4c87ba12f3e" + integrity sha512-903a+rcTd3xSYCM4DzVr05ViH05eDYN2IdgS6OJlv/Xtmkcye1tywBoP3p07Xyx2c8qhs3lAC9NMfUwWmmcqmQ== dependencies: isomorphic-unfetch "^3.1.0" -"@aave/math-utils@1.20.1-8d191bf193b4e5f74af4086481eb6f23a17f39e5.0": - version "1.20.1-8d191bf193b4e5f74af4086481eb6f23a17f39e5.0" - resolved "https://registry.yarnpkg.com/@aave/math-utils/-/math-utils-1.20.1-8d191bf193b4e5f74af4086481eb6f23a17f39e5.0.tgz#fb516c9ab3388da3c4935b72cf64c4bc752d5a3a" - integrity sha512-aEgIvluZRiJQsELDpGCaKUvGx7BaJB3mqKJAI42NQ+UH4oUsQuiNlG6sZQMVBOQiGpq8vn7qcnXZ7A1LRGZreg== +"@aave/math-utils@1.21.2-c8b03e9731a7d5b362e28af3eba6de7d9ba106ba.0": + version "1.21.2-c8b03e9731a7d5b362e28af3eba6de7d9ba106ba.0" + resolved "https://registry.yarnpkg.com/@aave/math-utils/-/math-utils-1.21.2-c8b03e9731a7d5b362e28af3eba6de7d9ba106ba.0.tgz#3c8f4d0fe58dadab80997910ed6f7d176d3b6003" + integrity sha512-HkTSCtMEkEI7V77USnTqItqAhTC/lMY4krYeUFbzVNI1LiX1ib8L/07aVm1p4uZqqxv6Q1vgBibHXUBEZvhpTA== "@adobe/css-tools@^4.0.1": version "4.0.1" From 47c5d0384ee54f94816f590f68dfa44d2a7c750b Mon Sep 17 00:00:00 2001 From: Mark Grothe Date: Tue, 13 Feb 2024 09:56:30 -0600 Subject: [PATCH 37/46] chore: utils --- package.json | 4 ++-- yarn.lock | 16 ++++++++-------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/package.json b/package.json index a3330d73de..bfc33bfc1a 100644 --- a/package.json +++ b/package.json @@ -32,8 +32,8 @@ "test:coverage": "jest --coverage" }, "dependencies": { - "@aave/contract-helpers": "1.21.2-c8b03e9731a7d5b362e28af3eba6de7d9ba106ba.0", - "@aave/math-utils": "1.21.2-c8b03e9731a7d5b362e28af3eba6de7d9ba106ba.0", + "@aave/contract-helpers": "1.24.1-b0d1f63019ec091d1653805fd1898faa4066245a.0", + "@aave/math-utils": "1.24.1-b0d1f63019ec091d1653805fd1898faa4066245a.0", "@bgd-labs/aave-address-book": "^2.10.0", "@emotion/cache": "11.10.3", "@emotion/react": "11.10.4", diff --git a/yarn.lock b/yarn.lock index f8ae66e71c..b059b032a4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,17 +2,17 @@ # yarn lockfile v1 -"@aave/contract-helpers@1.21.2-c8b03e9731a7d5b362e28af3eba6de7d9ba106ba.0": - version "1.21.2-c8b03e9731a7d5b362e28af3eba6de7d9ba106ba.0" - resolved "https://registry.yarnpkg.com/@aave/contract-helpers/-/contract-helpers-1.21.2-c8b03e9731a7d5b362e28af3eba6de7d9ba106ba.0.tgz#95f5451a970f9c9644bca9e13f08c4c87ba12f3e" - integrity sha512-903a+rcTd3xSYCM4DzVr05ViH05eDYN2IdgS6OJlv/Xtmkcye1tywBoP3p07Xyx2c8qhs3lAC9NMfUwWmmcqmQ== +"@aave/contract-helpers@1.24.1-b0d1f63019ec091d1653805fd1898faa4066245a.0": + version "1.24.1-b0d1f63019ec091d1653805fd1898faa4066245a.0" + resolved "https://registry.yarnpkg.com/@aave/contract-helpers/-/contract-helpers-1.24.1-b0d1f63019ec091d1653805fd1898faa4066245a.0.tgz#a2def98a5478ccb437baf44a303ae6f7caa7352f" + integrity sha512-5Xjqk23pYg6+GNGgE7/Jcr8RXOqAiRPBU3SzoLqK+eBLarZc2lc3GyI6fHZ6I9mqimcQuYQMFeXrz8/M6ysZFA== dependencies: isomorphic-unfetch "^3.1.0" -"@aave/math-utils@1.21.2-c8b03e9731a7d5b362e28af3eba6de7d9ba106ba.0": - version "1.21.2-c8b03e9731a7d5b362e28af3eba6de7d9ba106ba.0" - resolved "https://registry.yarnpkg.com/@aave/math-utils/-/math-utils-1.21.2-c8b03e9731a7d5b362e28af3eba6de7d9ba106ba.0.tgz#3c8f4d0fe58dadab80997910ed6f7d176d3b6003" - integrity sha512-HkTSCtMEkEI7V77USnTqItqAhTC/lMY4krYeUFbzVNI1LiX1ib8L/07aVm1p4uZqqxv6Q1vgBibHXUBEZvhpTA== +"@aave/math-utils@1.24.1-b0d1f63019ec091d1653805fd1898faa4066245a.0": + version "1.24.1-b0d1f63019ec091d1653805fd1898faa4066245a.0" + resolved "https://registry.yarnpkg.com/@aave/math-utils/-/math-utils-1.24.1-b0d1f63019ec091d1653805fd1898faa4066245a.0.tgz#9bf78eab4dae41cabac88387a2e34d330d0c5598" + integrity sha512-/rV6urV7AyQ+7sRNwna/gCEKt/MZxVCsFq06d81s2ca5p/EJls2UsMzG5lAQSmQYOuJtP/I5WBbKJn5m3LlNZQ== "@adobe/css-tools@^4.0.1": version "4.0.1" From d8dad7ec2d906a56cf64c46e3db958469817e1ae Mon Sep 17 00:00:00 2001 From: Mark Grothe Date: Tue, 13 Feb 2024 12:33:54 -0600 Subject: [PATCH 38/46] chore: config --- package.json | 6 +++--- src/ui-config/wrappedTokenConfig.ts | 7 ++++--- yarn.lock | 24 ++++++++++++------------ 3 files changed, 19 insertions(+), 18 deletions(-) diff --git a/package.json b/package.json index bfc33bfc1a..1fa4beeefd 100644 --- a/package.json +++ b/package.json @@ -32,9 +32,9 @@ "test:coverage": "jest --coverage" }, "dependencies": { - "@aave/contract-helpers": "1.24.1-b0d1f63019ec091d1653805fd1898faa4066245a.0", - "@aave/math-utils": "1.24.1-b0d1f63019ec091d1653805fd1898faa4066245a.0", - "@bgd-labs/aave-address-book": "^2.10.0", + "@aave/contract-helpers": "1.24.1-82a145b79d35bde0f05a1a82a3548eaaed18812b.0", + "@aave/math-utils": "1.24.1-82a145b79d35bde0f05a1a82a3548eaaed18812b.0", + "@bgd-labs/aave-address-book": "^2.19.0", "@emotion/cache": "11.10.3", "@emotion/react": "11.10.4", "@emotion/server": "latest", diff --git a/src/ui-config/wrappedTokenConfig.ts b/src/ui-config/wrappedTokenConfig.ts index 0df3b496cf..be28ceab60 100644 --- a/src/ui-config/wrappedTokenConfig.ts +++ b/src/ui-config/wrappedTokenConfig.ts @@ -1,4 +1,5 @@ import { ChainId } from '@aave/contract-helpers'; +import { AaveV3Ethereum } from '@bgd-labs/aave-address-book'; interface WrappedTokenConfig { tokenIn: Token; @@ -16,14 +17,14 @@ export const wrappedTokenConfig: { [chainId: number]: WrappedTokenConfig[] } = { [ChainId.mainnet]: [ { tokenIn: { - underlyingAsset: '0x6B175474E89094C44Da98b954EedeAC495271d0F'.toLowerCase(), + underlyingAsset: AaveV3Ethereum.ASSETS.DAI.UNDERLYING.toLowerCase(), symbol: 'DAI', }, tokenOut: { - underlyingAsset: '0x83f20f44975d03b1b09e64809b757c47f942beea'.toLowerCase(), + underlyingAsset: AaveV3Ethereum.ASSETS.sDAI.UNDERLYING.toLowerCase(), symbol: 'sDAI', }, - tokenWrapperContractAddress: '0x5d4d4007a4c6336550ddaa2a7c0d5e7972eebd16', + tokenWrapperContractAddress: AaveV3Ethereum.SAVINGS_DAI_TOKEN_WRAPPER, }, ], }; diff --git a/yarn.lock b/yarn.lock index b059b032a4..52c868af14 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,17 +2,17 @@ # yarn lockfile v1 -"@aave/contract-helpers@1.24.1-b0d1f63019ec091d1653805fd1898faa4066245a.0": - version "1.24.1-b0d1f63019ec091d1653805fd1898faa4066245a.0" - resolved "https://registry.yarnpkg.com/@aave/contract-helpers/-/contract-helpers-1.24.1-b0d1f63019ec091d1653805fd1898faa4066245a.0.tgz#a2def98a5478ccb437baf44a303ae6f7caa7352f" - integrity sha512-5Xjqk23pYg6+GNGgE7/Jcr8RXOqAiRPBU3SzoLqK+eBLarZc2lc3GyI6fHZ6I9mqimcQuYQMFeXrz8/M6ysZFA== +"@aave/contract-helpers@1.24.1-82a145b79d35bde0f05a1a82a3548eaaed18812b.0": + version "1.24.1-82a145b79d35bde0f05a1a82a3548eaaed18812b.0" + resolved "https://registry.yarnpkg.com/@aave/contract-helpers/-/contract-helpers-1.24.1-82a145b79d35bde0f05a1a82a3548eaaed18812b.0.tgz#002c55520fddace7877a06b5fa2bdea0196b75d4" + integrity sha512-DS5JmwIozDs/9e8XsTdlMxXdArWwO7+ZsQ6iEfL10+n2mmWVtcoQeqzO9i46nFGygz3a9fCCqoCiQ84Olr4q9g== dependencies: isomorphic-unfetch "^3.1.0" -"@aave/math-utils@1.24.1-b0d1f63019ec091d1653805fd1898faa4066245a.0": - version "1.24.1-b0d1f63019ec091d1653805fd1898faa4066245a.0" - resolved "https://registry.yarnpkg.com/@aave/math-utils/-/math-utils-1.24.1-b0d1f63019ec091d1653805fd1898faa4066245a.0.tgz#9bf78eab4dae41cabac88387a2e34d330d0c5598" - integrity sha512-/rV6urV7AyQ+7sRNwna/gCEKt/MZxVCsFq06d81s2ca5p/EJls2UsMzG5lAQSmQYOuJtP/I5WBbKJn5m3LlNZQ== +"@aave/math-utils@1.24.1-82a145b79d35bde0f05a1a82a3548eaaed18812b.0": + version "1.24.1-82a145b79d35bde0f05a1a82a3548eaaed18812b.0" + resolved "https://registry.yarnpkg.com/@aave/math-utils/-/math-utils-1.24.1-82a145b79d35bde0f05a1a82a3548eaaed18812b.0.tgz#4fdc9a5505cc03ccf8ce5f04c78f9a6fa0deee20" + integrity sha512-v7nFJrUu1We+P/07UZ1NVFW8P9XvgO5324suDk0uk2GorblTcZIaMrR3FzR9tXoSFHJL/cAFHGQIJfpAQTCWpA== "@adobe/css-tools@^4.0.1": version "4.0.1" @@ -1328,10 +1328,10 @@ resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== -"@bgd-labs/aave-address-book@^2.10.0": - version "2.10.0" - resolved "https://registry.yarnpkg.com/@bgd-labs/aave-address-book/-/aave-address-book-2.10.0.tgz#19873ec0edf9ee1f1a5539162e6092b0a2b2c4b4" - integrity sha512-DVglkDCYUf7etb6mnCziIY2HPgap4X3AnC/1tC0ZqpXFrhO0lQzWBiMeWy20r1x/b81iHMQa02ULaco3LhdeVw== +"@bgd-labs/aave-address-book@^2.19.0": + version "2.19.0" + resolved "https://registry.yarnpkg.com/@bgd-labs/aave-address-book/-/aave-address-book-2.19.0.tgz#5278bd4c8645b4ee783680c1b9d3df489f571060" + integrity sha512-JrZOZqzunJqFe4+/ZpL3vD7ddtGjjlBRCnMeQ68egNBAB2CYXvkXj6pSZLJBWklkoLgh17or1IdAQHTMYtBSsg== "@coinbase/wallet-sdk@3.1.0", "@coinbase/wallet-sdk@^3.0.4": version "3.1.0" From 605f17ece2f1e215af426b344335b3495bb4acf0 Mon Sep 17 00:00:00 2001 From: Mark Grothe Date: Tue, 13 Feb 2024 14:03:33 -0600 Subject: [PATCH 39/46] chore: cleanup --- .../Supply/SupplyWrappedTokenActions.tsx | 14 +++--- .../transactions/Supply/useApprovedAmount.tsx | 46 ------------------- .../Withdraw/WithdrawAndUnwrapActions.tsx | 18 +++++--- 3 files changed, 18 insertions(+), 60 deletions(-) delete mode 100644 src/components/transactions/Supply/useApprovedAmount.tsx diff --git a/src/components/transactions/Supply/SupplyWrappedTokenActions.tsx b/src/components/transactions/Supply/SupplyWrappedTokenActions.tsx index 1d7ea068b0..80f8423ef1 100644 --- a/src/components/transactions/Supply/SupplyWrappedTokenActions.tsx +++ b/src/components/transactions/Supply/SupplyWrappedTokenActions.tsx @@ -14,7 +14,7 @@ import { useWeb3Context } from 'src/libs/hooks/useWeb3Context'; import { useRootStore } from 'src/store/root'; import { ApprovalMethod } from 'src/store/walletSlice'; import { getErrorTextFromError, TxAction } from 'src/ui-config/errorMapping'; -import { QueryKeys } from 'src/ui-config/queries'; +import { queryKeysFactory } from 'src/ui-config/queries'; import { useSharedDependencies } from 'src/ui-config/SharedDependenciesProvider'; import { TxActionsWrapper } from '../TxActionsWrapper'; @@ -44,14 +44,14 @@ export const SupplyWrappedTokenActions = ({ sx, ...props }: SupplyWrappedTokenActionProps) => { - const [user, walletApprovalMethodPreference, estimateGasLimit, addTransaction] = useRootStore( - (state) => [ + const [user, walletApprovalMethodPreference, estimateGasLimit, addTransaction, marketData] = + useRootStore((state) => [ state.account, state.walletApprovalMethodPreference, state.estimateGasLimit, state.addTransaction, - ] - ); + state.currentMarketData, + ]); const { refetchPoolData } = useBackgroundDataProvider(); const { tokenWrapperService } = useSharedDependencies(); @@ -73,7 +73,7 @@ export const SupplyWrappedTokenActions = ({ data: approvedAmount, isFetching, refetch: fetchApprovedAmount, - } = useApprovedAmount(tokenIn, tokenWrapperAddress); + } = useApprovedAmount({ marketData, token: tokenIn, spender: tokenWrapperAddress }); let requiresApproval = false; if (approvedAmount !== undefined) { @@ -172,7 +172,7 @@ export const SupplyWrappedTokenActions = ({ assetName: symbol, }); - queryClient.invalidateQueries({ queryKey: [QueryKeys.POOL_TOKENS] }); + queryClient.invalidateQueries({ queryKey: queryKeysFactory.pool }); refetchPoolData && refetchPoolData(); } catch (error) { const parsedError = getErrorTextFromError(error, TxAction.GAS_ESTIMATION, false); diff --git a/src/components/transactions/Supply/useApprovedAmount.tsx b/src/components/transactions/Supply/useApprovedAmount.tsx deleted file mode 100644 index d3c6dfe5a4..0000000000 --- a/src/components/transactions/Supply/useApprovedAmount.tsx +++ /dev/null @@ -1,46 +0,0 @@ -import { ApproveType, ERC20Service } from '@aave/contract-helpers'; -import { useCallback, useEffect, useState } from 'react'; -import { useRootStore } from 'src/store/root'; - -export const useApprovedAmount = ({ - spender, - tokenAddress, -}: { - spender: string; - tokenAddress: string; -}) => { - const [provider, account] = useRootStore((state) => [state.jsonRpcProvider, state.account]); - const [loading, setLoading] = useState(false); - const [approval, setApproval] = useState(); - - const fetchApprovedAmount = useCallback( - async (spender: string, tokenAddress: string) => { - setLoading(true); - console.log('fetching approved amount'); - const erc20Service = new ERC20Service(provider()); - const approvedTargetAmount = await erc20Service.approvedAmount({ - user: account, - token: tokenAddress, - spender, - }); - setApproval({ - amount: approvedTargetAmount.toString(), - spender, - token: tokenAddress, - user: account, - }); - setLoading(false); - }, - [provider, account] - ); - - useEffect(() => { - if (!spender || !tokenAddress) return; - fetchApprovedAmount(spender, tokenAddress); - }, [spender, tokenAddress, fetchApprovedAmount]); - - return { - loading, - approval, - }; -}; diff --git a/src/components/transactions/Withdraw/WithdrawAndUnwrapActions.tsx b/src/components/transactions/Withdraw/WithdrawAndUnwrapActions.tsx index d88675aef0..5beccb0237 100644 --- a/src/components/transactions/Withdraw/WithdrawAndUnwrapActions.tsx +++ b/src/components/transactions/Withdraw/WithdrawAndUnwrapActions.tsx @@ -14,7 +14,7 @@ import { useWeb3Context } from 'src/libs/hooks/useWeb3Context'; import { useRootStore } from 'src/store/root'; import { ApprovalMethod } from 'src/store/walletSlice'; import { getErrorTextFromError, TxAction } from 'src/ui-config/errorMapping'; -import { QueryKeys } from 'src/ui-config/queries'; +import { queryKeysFactory } from 'src/ui-config/queries'; import { useSharedDependencies } from 'src/ui-config/SharedDependenciesProvider'; import { TxActionsWrapper } from '../TxActionsWrapper'; @@ -39,14 +39,14 @@ export const WithdrawAndUnwrapAction = ({ isWrongNetwork, tokenWrapperAddress, }: WithdrawAndUnwrapActionProps) => { - const [account, estimateGasLimit, walletApprovalMethodPreference, user] = useRootStore( - (state) => [ + const [account, estimateGasLimit, walletApprovalMethodPreference, user, marketData] = + useRootStore((state) => [ state.account, state.estimateGasLimit, state.walletApprovalMethodPreference, state.account, - ] - ); + state.currentMarketData, + ]); const { sendTx } = useWeb3Context(); @@ -69,7 +69,11 @@ export const WithdrawAndUnwrapAction = ({ data: approvedAmount, isFetching: fetchingApprovedAmount, refetch: fetchApprovedAmount, - } = useApprovedAmount(poolReserve.aTokenAddress, tokenWrapperAddress); + } = useApprovedAmount({ + marketData, + token: poolReserve.aTokenAddress, + spender: tokenWrapperAddress, + }); setLoadingTxns(fetchingApprovedAmount); @@ -141,7 +145,7 @@ export const WithdrawAndUnwrapAction = ({ success: true, }); - queryClient.invalidateQueries({ queryKey: [QueryKeys.POOL_TOKENS] }); + queryClient.invalidateQueries({ queryKey: queryKeysFactory.pool }); refetchPoolData && refetchPoolData(); } catch (error) { const parsedError = getErrorTextFromError(error, TxAction.GAS_ESTIMATION, false); From c4f63098150cd653506faabd771fb05724438fc8 Mon Sep 17 00:00:00 2001 From: Mark Grothe Date: Wed, 14 Feb 2024 11:26:29 -0600 Subject: [PATCH 40/46] chore: refactore --- .../transactions/FlowCommons/ModalWrapper.tsx | 7 +- .../Supply/SupplyModalContent.tsx | 8 +- .../Supply/SupplyWrappedTokenActions.tsx | 18 ++-- .../WithdrawAndSwitchModalContent.tsx | 6 +- .../app-data-provider/useAppDataProvider.tsx | 57 ------------ src/hooks/useWrappedTokens.tsx | 90 +++++++++++++++++++ .../SupplyAssetsList/SupplyAssetsList.tsx | 3 +- .../SupplyAssetsList/SupplyAssetsListItem.tsx | 8 +- 8 files changed, 117 insertions(+), 80 deletions(-) create mode 100644 src/hooks/useWrappedTokens.tsx diff --git a/src/components/transactions/FlowCommons/ModalWrapper.tsx b/src/components/transactions/FlowCommons/ModalWrapper.tsx index 40e32f26c1..fe2608d2a2 100644 --- a/src/components/transactions/FlowCommons/ModalWrapper.tsx +++ b/src/components/transactions/FlowCommons/ModalWrapper.tsx @@ -5,7 +5,6 @@ import { ComputedReserveData, ComputedUserReserveData, useAppDataContext, - WrappedTokenConfig, } from 'src/hooks/app-data-provider/useAppDataProvider'; import { useWalletBalances } from 'src/hooks/app-data-provider/useWalletBalances'; import { AssetCapsProvider } from 'src/hooks/useAssetCaps'; @@ -30,7 +29,6 @@ export interface ModalWrapperProps { nativeBalance: string; isWrongNetwork: boolean; action?: string; - wrappedTokenConfig?: WrappedTokenConfig; } export const ModalWrapper: React.FC<{ @@ -56,7 +54,7 @@ export const ModalWrapper: React.FC<{ const currentMarketData = useRootStore((store) => store.currentMarketData); const currentNetworkConfig = useRootStore((store) => store.currentNetworkConfig); const { walletBalances } = useWalletBalances(currentMarketData); - const { user, reserves, wrappedTokenReserves } = useAppDataContext(); + const { user, reserves } = useAppDataContext(); const { txError, mainTxState } = useModalContext(); const { permissions } = usePermissions(); @@ -117,9 +115,6 @@ export const ModalWrapper: React.FC<{ symbol, underlyingAsset, userReserve, - wrappedTokenConfig: wrappedTokenReserves.find( - (r) => r.tokenOut.underlyingAsset === underlyingAsset - ), })} ); diff --git a/src/components/transactions/Supply/SupplyModalContent.tsx b/src/components/transactions/Supply/SupplyModalContent.tsx index f530629486..d79bf1be08 100644 --- a/src/components/transactions/Supply/SupplyModalContent.tsx +++ b/src/components/transactions/Supply/SupplyModalContent.tsx @@ -19,6 +19,7 @@ import { import { useAssetCaps } from 'src/hooks/useAssetCaps'; import { useModalContext } from 'src/hooks/useModal'; import { useProtocolDataContext } from 'src/hooks/useProtocolDataContext'; +import { useWrappedTokens, WrappedTokenConfig } from 'src/hooks/useWrappedTokens'; import { ERC20TokenType } from 'src/libs/web3-data-provider/Web3Provider'; import { useRootStore } from 'src/store/root'; import { @@ -55,8 +56,9 @@ export enum ErrorType { } export const SupplyModalContentWrapper = (params: ModalWrapperProps) => { - const { user, wrappedTokenReserves } = useAppDataContext(); + const { user } = useAppDataContext(); const { currentMarketData } = useProtocolDataContext(); + const wrappedTokenReserves = useWrappedTokens(); const { walletBalances } = useWalletBalances(currentMarketData); const { supplyCap: supplyCapUsage, debtCeiling: debtCeilingUsage } = useAssetCaps(); @@ -101,6 +103,9 @@ export const SupplyModalContentWrapper = (params: ModalWrapperProps) => { ), supplyCapWarning: supplyCapUsage.determineWarningDisplay({ supplyCap: supplyCapUsage }), debtCeilingWarning: debtCeilingUsage.determineWarningDisplay({ debtCeiling: debtCeilingUsage }), + wrappedTokenConfig: wrappedTokenReserves.find( + (r) => r.tokenOut.underlyingAsset === params.underlyingAsset + ), }; return canSupplyAsWrappedToken ? ( @@ -116,6 +121,7 @@ interface SupplyModalContentProps extends ModalWrapperProps { isolationModeWarning: React.ReactNode; supplyCapWarning: React.ReactNode; debtCeilingWarning: React.ReactNode; + wrappedTokenConfig?: WrappedTokenConfig; } export const SupplyModalContent = React.memo( diff --git a/src/components/transactions/Supply/SupplyWrappedTokenActions.tsx b/src/components/transactions/Supply/SupplyWrappedTokenActions.tsx index 80f8423ef1..b76bd6838c 100644 --- a/src/components/transactions/Supply/SupplyWrappedTokenActions.tsx +++ b/src/components/transactions/Supply/SupplyWrappedTokenActions.tsx @@ -12,7 +12,6 @@ import { useApprovedAmount } from 'src/hooks/useApprovedAmount'; import { useModalContext } from 'src/hooks/useModal'; import { useWeb3Context } from 'src/libs/hooks/useWeb3Context'; import { useRootStore } from 'src/store/root'; -import { ApprovalMethod } from 'src/store/walletSlice'; import { getErrorTextFromError, TxAction } from 'src/ui-config/errorMapping'; import { queryKeysFactory } from 'src/ui-config/queries'; import { useSharedDependencies } from 'src/ui-config/SharedDependenciesProvider'; @@ -44,14 +43,12 @@ export const SupplyWrappedTokenActions = ({ sx, ...props }: SupplyWrappedTokenActionProps) => { - const [user, walletApprovalMethodPreference, estimateGasLimit, addTransaction, marketData] = - useRootStore((state) => [ - state.account, - state.walletApprovalMethodPreference, - state.estimateGasLimit, - state.addTransaction, - state.currentMarketData, - ]); + const [user, estimateGasLimit, addTransaction, marketData] = useRootStore((state) => [ + state.account, + state.estimateGasLimit, + state.addTransaction, + state.currentMarketData, + ]); const { refetchPoolData } = useBackgroundDataProvider(); const { tokenWrapperService } = useSharedDependencies(); @@ -84,7 +81,8 @@ export const SupplyWrappedTokenActions = ({ }); } - const usePermit = walletApprovalMethodPreference === ApprovalMethod.PERMIT; + // Since the only wrapped token right now is sDAI/DAI, disable permit since it is not supported + const usePermit = false; // walletApprovalMethodPreference === ApprovalMethod.PERMIT; // Update gas estimation let supplyGasLimit = 0; diff --git a/src/components/transactions/Withdraw/WithdrawAndSwitchModalContent.tsx b/src/components/transactions/Withdraw/WithdrawAndSwitchModalContent.tsx index e068fcd5b8..6eea621aba 100644 --- a/src/components/transactions/Withdraw/WithdrawAndSwitchModalContent.tsx +++ b/src/components/transactions/Withdraw/WithdrawAndSwitchModalContent.tsx @@ -13,6 +13,7 @@ import { useCollateralSwap } from 'src/hooks/paraswap/useCollateralSwap'; import { useTokenInForTokenOut } from 'src/hooks/token-wrapper/useTokenWrapper'; import { useModalContext } from 'src/hooks/useModal'; import { useProtocolDataContext } from 'src/hooks/useProtocolDataContext'; +import { useWrappedTokens } from 'src/hooks/useWrappedTokens'; import { useWeb3Context } from 'src/libs/hooks/useWeb3Context'; import { ListSlippageButton } from 'src/modules/dashboard/lists/SlippageList'; import { useRootStore } from 'src/store/root'; @@ -42,12 +43,12 @@ export const WithdrawAndSwitchModalContent = ({ userReserve, symbol, isWrongNetwork, - wrappedTokenConfig, }: ModalWrapperProps) => { const { gasLimit, mainTxState: withdrawTxState, txError } = useModalContext(); const { currentAccount } = useWeb3Context(); const { user, reserves } = useAppDataContext(); const { currentNetworkConfig, currentChainId } = useProtocolDataContext(); + const wrappedTokenReserves = useWrappedTokens(); const [_amount, setAmount] = useState(''); const [riskCheckboxAccepted, setRiskCheckboxAccepted] = useState(false); @@ -81,6 +82,9 @@ export const WithdrawAndSwitchModalContent = ({ const underlyingBalance = valueToBigNumber(userReserve?.underlyingBalance || '0'); let withdrawAndUnwrap = false; + const wrappedTokenConfig = wrappedTokenReserves.find( + (config) => config.tokenIn.underlyingAsset === poolReserve.underlyingAsset + ); if (wrappedTokenConfig) { withdrawAndUnwrap = targetReserve.address === wrappedTokenConfig.tokenIn.underlyingAsset; } diff --git a/src/hooks/app-data-provider/useAppDataProvider.tsx b/src/hooks/app-data-provider/useAppDataProvider.tsx index e275f67377..e8fa96093d 100644 --- a/src/hooks/app-data-provider/useAppDataProvider.tsx +++ b/src/hooks/app-data-provider/useAppDataProvider.tsx @@ -17,7 +17,6 @@ import React, { useContext } from 'react'; import { EmodeCategory } from 'src/helpers/types'; import { useWeb3Context } from 'src/libs/hooks/useWeb3Context'; import { useRootStore } from 'src/store/root'; -import { wrappedTokenConfig } from 'src/ui-config/wrappedTokenConfig'; import { GHO_SUPPORTED_MARKETS, GHO_SYMBOL, weightedAverageAPY } from 'src/utils/ghoUtilities'; import { @@ -59,20 +58,6 @@ export type ExtendedFormattedUser = FormatUserSummaryAndIncentivesResponse Promise; isUserHasDeposits: boolean; user: ExtendedFormattedUser; - wrappedTokenReserves: WrappedTokenConfig[]; // refreshIncentives?: () => Promise; // loading: boolean; @@ -114,7 +98,6 @@ export const AppDataProvider: React.FC = ({ children }) => { formattedPoolReserves, userSummary, displayGho, - currentChainId, ] = useRootStore((state) => [ selectCurrentReserves(state), selectCurrentBaseCurrencyData(state), @@ -127,7 +110,6 @@ export const AppDataProvider: React.FC = ({ children }) => { selectFormattedReserves(state, currentTimestamp), selectUserSummaryAndIncentives(state, currentTimestamp), state.displayGho, - state.currentChainId, ]); const formattedGhoReserveData: FormattedGhoReserveData = formatGhoReserveData({ @@ -259,44 +241,6 @@ export const AppDataProvider: React.FC = ({ children }) => { (debtAPY || 0) * (Number(user.totalBorrowsUSD) / Number(user.netWorthUSD !== '0' ? user.netWorthUSD : '1')); - const wrappedTokens = wrappedTokenConfig[currentChainId] ?? []; - let wrappedTokenReserves: WrappedTokenConfig[] = []; - if (user.userReservesData.length > 0) { - wrappedTokenReserves = wrappedTokens.map((config) => { - const tokenInReserve = user.userReservesData.find( - (userReserve) => userReserve.underlyingAsset === config.tokenIn.underlyingAsset - ); - - const tokenOutReserve = user.userReservesData.find( - (userReserve) => userReserve.underlyingAsset === config.tokenOut.underlyingAsset - ); - - if (!tokenInReserve || !tokenOutReserve) { - throw new Error('wrapped token reserves not found'); - } - - return { - tokenIn: { - symbol: config.tokenIn.symbol, - underlyingAsset: config.tokenIn.underlyingAsset, - decimals: tokenInReserve.reserve.decimals, - priceInUSD: tokenInReserve.reserve.priceInUSD, - formattedPriceInMarketReferenceCurrency: - tokenInReserve.reserve.formattedPriceInMarketReferenceCurrency, - }, - tokenOut: { - symbol: tokenOutReserve.reserve.symbol, - underlyingAsset: tokenOutReserve.reserve.underlyingAsset, - decimals: tokenOutReserve.reserve.decimals, - priceInUSD: tokenOutReserve.reserve.priceInUSD, - formattedPriceInMarketReferenceCurrency: - tokenOutReserve.reserve.formattedPriceInMarketReferenceCurrency, - }, - tokenWrapperAddress: config.tokenWrapperContractAddress, - }; - }); - } - return ( { }, ghoUserData: formattedGhoUserData, ghoLoadingData: !ghoReserveDataFetched, - wrappedTokenReserves, }} > {children} diff --git a/src/hooks/useWrappedTokens.tsx b/src/hooks/useWrappedTokens.tsx new file mode 100644 index 0000000000..fddb3e6fac --- /dev/null +++ b/src/hooks/useWrappedTokens.tsx @@ -0,0 +1,90 @@ +import { normalize } from '@aave/math-utils'; +import { selectCurrentReserves } from 'src/store/poolSelectors'; +import { useRootStore } from 'src/store/root'; +import { wrappedTokenConfig } from 'src/ui-config/wrappedTokenConfig'; +import { amountToUsd } from 'src/utils/utils'; + +import { useAppDataContext } from './app-data-provider/useAppDataProvider'; + +export type WrappedToken = { + symbol: string; + underlyingAsset: string; + decimals: number; + priceInUSD: string; + formattedPriceInMarketReferenceCurrency: string; +}; + +export type WrappedTokenConfig = { + tokenIn: WrappedToken; + tokenOut: WrappedToken; + tokenWrapperAddress: string; +}; + +export const useWrappedTokens = () => { + const { marketReferencePriceInUsd, marketReferenceCurrencyDecimals } = useAppDataContext(); + const [reserves, currentChainId] = useRootStore((state) => [ + selectCurrentReserves(state), + state.currentChainId, + ]); + + if (!reserves || reserves.length === 0) { + return []; + } + + const wrappedTokens = wrappedTokenConfig[currentChainId] ?? []; + let wrappedTokenReserves: WrappedTokenConfig[] = []; + + console.log(reserves); + + wrappedTokenReserves = wrappedTokens.map((config) => { + const tokenInReserve = reserves.find( + (userReserve) => userReserve.underlyingAsset === config.tokenIn.underlyingAsset + ); + + const tokenOutReserve = reserves.find( + (userReserve) => userReserve.underlyingAsset === config.tokenOut.underlyingAsset + ); + + if (!tokenInReserve || !tokenOutReserve) { + throw new Error('wrapped token reserves not found'); + } + + const tokenInFormattedPriceInMarketReferenceCurrency = normalize( + tokenInReserve.priceInMarketReferenceCurrency, + marketReferenceCurrencyDecimals + ); + + const tokenOutFormattedPriceInMarketReferenceCurrency = normalize( + tokenOutReserve.priceInMarketReferenceCurrency, + marketReferenceCurrencyDecimals + ); + + return { + tokenIn: { + symbol: config.tokenIn.symbol, + underlyingAsset: config.tokenIn.underlyingAsset, + decimals: tokenInReserve.decimals, + priceInUSD: amountToUsd( + 1, + tokenInFormattedPriceInMarketReferenceCurrency, + marketReferencePriceInUsd + ).toString(), + formattedPriceInMarketReferenceCurrency: tokenInFormattedPriceInMarketReferenceCurrency, + }, + tokenOut: { + symbol: tokenOutReserve.symbol, + underlyingAsset: tokenOutReserve.underlyingAsset, + decimals: tokenOutReserve.decimals, + priceInUSD: amountToUsd( + 1, + tokenOutFormattedPriceInMarketReferenceCurrency, + marketReferencePriceInUsd + ).toString(), + formattedPriceInMarketReferenceCurrency: tokenOutFormattedPriceInMarketReferenceCurrency, + }, + tokenWrapperAddress: config.tokenWrapperContractAddress, + }; + }); + + return wrappedTokenReserves; +}; diff --git a/src/modules/dashboard/lists/SupplyAssetsList/SupplyAssetsList.tsx b/src/modules/dashboard/lists/SupplyAssetsList/SupplyAssetsList.tsx index 716bf51be6..2cefd3a9fe 100644 --- a/src/modules/dashboard/lists/SupplyAssetsList/SupplyAssetsList.tsx +++ b/src/modules/dashboard/lists/SupplyAssetsList/SupplyAssetsList.tsx @@ -10,6 +10,7 @@ import { ListHeaderWrapper } from 'src/components/lists/ListHeaderWrapper'; import { Warning } from 'src/components/primitives/Warning'; import { MarketWarning } from 'src/components/transactions/Warnings/MarketWarning'; import { AssetCapsProvider } from 'src/hooks/useAssetCaps'; +import { useWrappedTokens } from 'src/hooks/useWrappedTokens'; import { useRootStore } from 'src/store/root'; import { fetchIconSymbolAndName } from 'src/ui-config/reservePatches'; @@ -51,8 +52,8 @@ export const SupplyAssetsList = () => { reserves, marketReferencePriceInUsd, loading: loadingReserves, - wrappedTokenReserves, } = useAppDataContext(); + const wrappedTokenReserves = useWrappedTokens(); const { walletBalances, loading } = useWalletBalances(currentMarketData); const [displayGho] = useRootStore((store) => [store.displayGho]); const theme = useTheme(); diff --git a/src/modules/dashboard/lists/SupplyAssetsList/SupplyAssetsListItem.tsx b/src/modules/dashboard/lists/SupplyAssetsList/SupplyAssetsListItem.tsx index 8270c7c9cb..e3fd354a4d 100644 --- a/src/modules/dashboard/lists/SupplyAssetsList/SupplyAssetsListItem.tsx +++ b/src/modules/dashboard/lists/SupplyAssetsList/SupplyAssetsListItem.tsx @@ -20,11 +20,11 @@ import { FormattedNumber } from 'src/components/primitives/FormattedNumber'; import { NoData } from 'src/components/primitives/NoData'; import { Row } from 'src/components/primitives/Row'; import { TokenIcon } from 'src/components/primitives/TokenIcon'; -import { useAppDataContext } from 'src/hooks/app-data-provider/useAppDataProvider'; import { useWalletBalances } from 'src/hooks/app-data-provider/useWalletBalances'; import { useAssetCaps } from 'src/hooks/useAssetCaps'; import { useModalContext } from 'src/hooks/useModal'; import { useProtocolDataContext } from 'src/hooks/useProtocolDataContext'; +import { useWrappedTokens } from 'src/hooks/useWrappedTokens'; import { useRootStore } from 'src/store/root'; import { DashboardReserve } from 'src/utils/dashboardSortUtils'; import { isFeatureEnabled } from 'src/utils/marketsAndNetworksConfig'; @@ -46,7 +46,7 @@ export const SupplyAssetsListItem = (params: DashboardReserve) => { const theme = useTheme(); const downToXSM = useMediaQuery(theme.breakpoints.down('xsm')); const { supplyCap } = useAssetCaps(); - const { wrappedTokenReserves } = useAppDataContext(); + const wrappedTokenReserves = useWrappedTokens(); const currentMarketData = useRootStore((store) => store.currentMarketData); const { walletBalances } = useWalletBalances(currentMarketData); @@ -103,7 +103,7 @@ export const SupplyAssetsListItemDesktop = ({ }: SupplyAssetsListItemProps) => { const currentMarketData = useRootStore((store) => store.currentMarketData); const currentMarket = useRootStore((store) => store.currentMarket); - const { wrappedTokenReserves } = useAppDataContext(); + const wrappedTokenReserves = useWrappedTokens(); const { walletBalances } = useWalletBalances(currentMarketData); const { openSupply, openSwitch } = useModalContext(); @@ -309,7 +309,7 @@ export const SupplyAssetsListItemMobile = ({ }: SupplyAssetsListItemProps) => { const { currentMarket } = useProtocolDataContext(); const { openSupply } = useModalContext(); - const { wrappedTokenReserves } = useAppDataContext(); + const wrappedTokenReserves = useWrappedTokens(); const currentMarketData = useRootStore((store) => store.currentMarketData); const { walletBalances } = useWalletBalances(currentMarketData); From e7c19afaa315477fd20517f4a52c362aa3bec737 Mon Sep 17 00:00:00 2001 From: Mark Grothe Date: Wed, 14 Feb 2024 11:29:39 -0600 Subject: [PATCH 41/46] chore: cleanup dead code --- .../app-data-provider/useWalletBalances.tsx | 7 ------- src/services/WalletBalanceService.ts | 17 +---------------- 2 files changed, 1 insertion(+), 23 deletions(-) diff --git a/src/hooks/app-data-provider/useWalletBalances.tsx b/src/hooks/app-data-provider/useWalletBalances.tsx index 12763e66c2..efe38b220a 100644 --- a/src/hooks/app-data-provider/useWalletBalances.tsx +++ b/src/hooks/app-data-provider/useWalletBalances.tsx @@ -97,10 +97,3 @@ export const useWalletBalances = (marketData: MarketDataType) => { loading: isLoading, }; }; - -// export const useWrappedTokenInBalances = (wrappedTokenConfig: WrappedTokenConfig[]) => { -// const foo = useTokenInBalances(wrappedTokenConfig); -// return { -// balances: foo. -// } -// } diff --git a/src/services/WalletBalanceService.ts b/src/services/WalletBalanceService.ts index 70062c4c01..40c8cc3c79 100644 --- a/src/services/WalletBalanceService.ts +++ b/src/services/WalletBalanceService.ts @@ -1,4 +1,4 @@ -import { BatchBalanceOfResponse, ChainId, WalletBalanceProvider } from '@aave/contract-helpers'; +import { ChainId, WalletBalanceProvider } from '@aave/contract-helpers'; import { normalize } from '@aave/math-utils'; import { Provider } from '@ethersproject/providers'; import { governanceV3Config } from 'src/ui-config/governanceConfig'; @@ -69,19 +69,4 @@ export class WalletBalanceService { })); return mappedBalances; } - - async getWrappedTokenInBalances( - tokenInAddresses: string[], - marketData: MarketDataType, - user: string - ): Promise { - console.log('token in', tokenInAddresses); - const walletBalanceService = this.getWalletBalanceService( - marketData.chainId, - marketData.addresses.WALLET_BALANCE_PROVIDER - ); - const balances = await walletBalanceService.batchBalanceOf([user], tokenInAddresses); - console.log('balances', balances); - return balances; - } } From 69a222b3efb26acbae25a18e6e9bd98e4cd03c2e Mon Sep 17 00:00:00 2001 From: Mark Grothe Date: Wed, 14 Feb 2024 15:05:36 -0600 Subject: [PATCH 42/46] chore: cleanup --- .../Supply/SupplyWrappedTokenActions.tsx | 10 ++++-- .../Withdraw/WithdrawAndUnwrapActions.tsx | 8 +++++ src/hooks/useApprovedAmount.tsx | 8 ----- src/hooks/useWrappedTokens.tsx | 34 ++++++++++++------- src/ui-config/wrappedTokenConfig.ts | 30 ---------------- 5 files changed, 38 insertions(+), 52 deletions(-) delete mode 100644 src/ui-config/wrappedTokenConfig.ts diff --git a/src/components/transactions/Supply/SupplyWrappedTokenActions.tsx b/src/components/transactions/Supply/SupplyWrappedTokenActions.tsx index b76bd6838c..410b398a12 100644 --- a/src/components/transactions/Supply/SupplyWrappedTokenActions.tsx +++ b/src/components/transactions/Supply/SupplyWrappedTokenActions.tsx @@ -72,6 +72,9 @@ export const SupplyWrappedTokenActions = ({ refetch: fetchApprovedAmount, } = useApprovedAmount({ marketData, token: tokenIn, spender: tokenWrapperAddress }); + console.log('approved amount', approvedAmount); + console.log('fetching', isFetching); + let requiresApproval = false; if (approvedAmount !== undefined) { requiresApproval = checkRequiresApproval({ @@ -171,6 +174,9 @@ export const SupplyWrappedTokenActions = ({ }); queryClient.invalidateQueries({ queryKey: queryKeysFactory.pool }); + queryClient.invalidateQueries({ + queryKey: queryKeysFactory.approvedAmount(user, tokenIn, tokenWrapperAddress, marketData), + }); refetchPoolData && refetchPoolData(); } catch (error) { const parsedError = getErrorTextFromError(error, TxAction.GAS_ESTIMATION, false); @@ -184,7 +190,7 @@ export const SupplyWrappedTokenActions = ({ return ( approvalAction()} handleAction={action} requiresApproval={requiresApproval} - tryPermit={false} // TODO + tryPermit={usePermit} sx={sx} {...props} /> diff --git a/src/components/transactions/Withdraw/WithdrawAndUnwrapActions.tsx b/src/components/transactions/Withdraw/WithdrawAndUnwrapActions.tsx index 5beccb0237..a20abfdc21 100644 --- a/src/components/transactions/Withdraw/WithdrawAndUnwrapActions.tsx +++ b/src/components/transactions/Withdraw/WithdrawAndUnwrapActions.tsx @@ -146,6 +146,14 @@ export const WithdrawAndUnwrapAction = ({ }); queryClient.invalidateQueries({ queryKey: queryKeysFactory.pool }); + queryClient.invalidateQueries({ + queryKey: queryKeysFactory.approvedAmount( + user, + poolReserve.aTokenAddress, + tokenWrapperAddress, + marketData + ), + }); refetchPoolData && refetchPoolData(); } catch (error) { const parsedError = getErrorTextFromError(error, TxAction.GAS_ESTIMATION, false); diff --git a/src/hooks/useApprovedAmount.tsx b/src/hooks/useApprovedAmount.tsx index 74cfbb430f..7c25075048 100644 --- a/src/hooks/useApprovedAmount.tsx +++ b/src/hooks/useApprovedAmount.tsx @@ -18,10 +18,6 @@ export const useApprovedAmount = ({ return useQuery({ queryFn: () => approvedAmountService.getApprovedAmount(marketData, user, token, spender), queryKey: queryKeysFactory.approvedAmount(user, token, spender, marketData), - enabled: !!user, - refetchOnMount: false, - refetchOnWindowFocus: false, - refetchOnReconnect: false, }); }; @@ -31,9 +27,5 @@ export const usePoolApprovedAmount = (marketData: MarketDataType, token: string) return useQuery({ queryFn: () => approvedAmountService.getPoolApprovedAmount(marketData, user, token), queryKey: queryKeysFactory.poolApprovedAmount(user, token, marketData), - enabled: !!user, - refetchOnMount: false, - refetchOnWindowFocus: false, - refetchOnReconnect: false, }); }; diff --git a/src/hooks/useWrappedTokens.tsx b/src/hooks/useWrappedTokens.tsx index fddb3e6fac..503b6b01c5 100644 --- a/src/hooks/useWrappedTokens.tsx +++ b/src/hooks/useWrappedTokens.tsx @@ -1,7 +1,8 @@ +import { ChainId } from '@aave/contract-helpers'; import { normalize } from '@aave/math-utils'; +import { AaveV3Ethereum } from '@bgd-labs/aave-address-book'; import { selectCurrentReserves } from 'src/store/poolSelectors'; import { useRootStore } from 'src/store/root'; -import { wrappedTokenConfig } from 'src/ui-config/wrappedTokenConfig'; import { amountToUsd } from 'src/utils/utils'; import { useAppDataContext } from './app-data-provider/useAppDataProvider'; @@ -20,6 +21,22 @@ export type WrappedTokenConfig = { tokenWrapperAddress: string; }; +const wrappedTokenConfig: { + [chainId: number]: Array<{ + tokenIn: string; + tokenOut: string; + tokenWrapperContractAddress: string; + }>; +} = { + [ChainId.mainnet]: [ + { + tokenIn: AaveV3Ethereum.ASSETS.DAI.UNDERLYING.toLowerCase(), + tokenOut: AaveV3Ethereum.ASSETS.sDAI.UNDERLYING.toLowerCase(), + tokenWrapperContractAddress: AaveV3Ethereum.SAVINGS_DAI_TOKEN_WRAPPER, + }, + ], +}; + export const useWrappedTokens = () => { const { marketReferencePriceInUsd, marketReferenceCurrencyDecimals } = useAppDataContext(); const [reserves, currentChainId] = useRootStore((state) => [ @@ -34,16 +51,9 @@ export const useWrappedTokens = () => { const wrappedTokens = wrappedTokenConfig[currentChainId] ?? []; let wrappedTokenReserves: WrappedTokenConfig[] = []; - console.log(reserves); - wrappedTokenReserves = wrappedTokens.map((config) => { - const tokenInReserve = reserves.find( - (userReserve) => userReserve.underlyingAsset === config.tokenIn.underlyingAsset - ); - - const tokenOutReserve = reserves.find( - (userReserve) => userReserve.underlyingAsset === config.tokenOut.underlyingAsset - ); + const tokenInReserve = reserves.find((reserve) => reserve.underlyingAsset === config.tokenIn); + const tokenOutReserve = reserves.find((reserve) => reserve.underlyingAsset === config.tokenOut); if (!tokenInReserve || !tokenOutReserve) { throw new Error('wrapped token reserves not found'); @@ -61,8 +71,8 @@ export const useWrappedTokens = () => { return { tokenIn: { - symbol: config.tokenIn.symbol, - underlyingAsset: config.tokenIn.underlyingAsset, + symbol: tokenInReserve.symbol, + underlyingAsset: tokenInReserve.underlyingAsset, decimals: tokenInReserve.decimals, priceInUSD: amountToUsd( 1, diff --git a/src/ui-config/wrappedTokenConfig.ts b/src/ui-config/wrappedTokenConfig.ts deleted file mode 100644 index be28ceab60..0000000000 --- a/src/ui-config/wrappedTokenConfig.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { ChainId } from '@aave/contract-helpers'; -import { AaveV3Ethereum } from '@bgd-labs/aave-address-book'; - -interface WrappedTokenConfig { - tokenIn: Token; - tokenOut: Token; - tokenWrapperContractAddress: string; -} - -interface Token { - underlyingAsset: string; - symbol: string; - decimals?: number; -} - -export const wrappedTokenConfig: { [chainId: number]: WrappedTokenConfig[] } = { - [ChainId.mainnet]: [ - { - tokenIn: { - underlyingAsset: AaveV3Ethereum.ASSETS.DAI.UNDERLYING.toLowerCase(), - symbol: 'DAI', - }, - tokenOut: { - underlyingAsset: AaveV3Ethereum.ASSETS.sDAI.UNDERLYING.toLowerCase(), - symbol: 'sDAI', - }, - tokenWrapperContractAddress: AaveV3Ethereum.SAVINGS_DAI_TOKEN_WRAPPER, - }, - ], -}; From ae4b4f6159aabc5498cbaef7c36bdc090fcc8271 Mon Sep 17 00:00:00 2001 From: Mark Grothe Date: Wed, 14 Feb 2024 15:55:45 -0600 Subject: [PATCH 43/46] chore: fixes --- .../Withdraw/WithdrawAndSwitchModalContent.tsx | 4 +++- .../Withdraw/WithdrawAndUnwrapActions.tsx | 18 ++++++++++++------ 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/src/components/transactions/Withdraw/WithdrawAndSwitchModalContent.tsx b/src/components/transactions/Withdraw/WithdrawAndSwitchModalContent.tsx index 6eea621aba..6c2b264510 100644 --- a/src/components/transactions/Withdraw/WithdrawAndSwitchModalContent.tsx +++ b/src/components/transactions/Withdraw/WithdrawAndSwitchModalContent.tsx @@ -83,7 +83,7 @@ export const WithdrawAndSwitchModalContent = ({ let withdrawAndUnwrap = false; const wrappedTokenConfig = wrappedTokenReserves.find( - (config) => config.tokenIn.underlyingAsset === poolReserve.underlyingAsset + (config) => config.tokenOut.underlyingAsset === poolReserve.underlyingAsset ); if (wrappedTokenConfig) { withdrawAndUnwrap = targetReserve.address === wrappedTokenConfig.tokenIn.underlyingAsset; @@ -319,6 +319,8 @@ export const WithdrawAndSwitchModalContent = ({ amountToWithdraw={amountRef.current} isWrongNetwork={isWrongNetwork} tokenWrapperAddress={wrappedTokenConfig?.tokenWrapperAddress || ''} + sx={displayRiskCheckbox ? { mt: 0 } : {}} + blocked={blockingError !== undefined || (displayRiskCheckbox && !riskCheckboxAccepted)} /> ) : ( { const [account, estimateGasLimit, walletApprovalMethodPreference, user, marketData] = useRootStore((state) => [ @@ -166,18 +170,18 @@ export const WithdrawAndUnwrapAction = ({ }; useEffect(() => { - let supplyGasLimit = 0; - supplyGasLimit = Number(gasLimitRecommendations[ProtocolAction.withdraw].recommended); + let gasLimit = 0; + gasLimit = Number(gasLimitRecommendations[ProtocolAction.withdraw].recommended); if (requiresApproval && !approvalTxState.success) { - supplyGasLimit += Number(APPROVAL_GAS_LIMIT); + gasLimit += Number(APPROVAL_GAS_LIMIT); } - setGasLimit(supplyGasLimit.toString()); + setGasLimit(gasLimit.toString()); }, [requiresApproval, approvalTxState, usePermit, setGasLimit]); return ( ); }; From fc52ec3a7dbc303c02b8516b33e30159b9ada286 Mon Sep 17 00:00:00 2001 From: Mark Grothe Date: Thu, 15 Feb 2024 09:51:38 -0600 Subject: [PATCH 44/46] fix: exchange rate query --- .../infoTooltips/WrappedTokenToolTipContent.tsx | 2 +- .../transactions/Supply/SupplyModalContent.tsx | 5 +++++ .../transactions/Supply/SupplyWrappedTokenActions.tsx | 3 --- src/hooks/token-wrapper/useTokenWrapper.ts | 10 ++-------- 4 files changed, 8 insertions(+), 12 deletions(-) diff --git a/src/components/infoTooltips/WrappedTokenToolTipContent.tsx b/src/components/infoTooltips/WrappedTokenToolTipContent.tsx index d8820c019e..03a90aac71 100644 --- a/src/components/infoTooltips/WrappedTokenToolTipContent.tsx +++ b/src/components/infoTooltips/WrappedTokenToolTipContent.tsx @@ -16,7 +16,7 @@ export const WrappedTokenTooltipContent = ({ tokenInSymbol: string; tokenOutSymbol: string; }) => { - const { isFetching: loadingExchangeRate, data: exchangeRate } = useTokenOutForTokenIn( + const { isLoading: loadingExchangeRate, data: exchangeRate } = useTokenOutForTokenIn( '1', decimals, tokenWrapperAddress diff --git a/src/components/transactions/Supply/SupplyModalContent.tsx b/src/components/transactions/Supply/SupplyModalContent.tsx index d79bf1be08..c2bbcb2218 100644 --- a/src/components/transactions/Supply/SupplyModalContent.tsx +++ b/src/components/transactions/Supply/SupplyModalContent.tsx @@ -346,6 +346,11 @@ export const SupplyWrappedTokenModalContent = ({ maxAmountOfTokenInToSupply = BigNumber(tokenOutRemainingSupplyCap) .dividedBy(exchangeRate || '0') .toString(); + + maxAmountOfTokenInToSupply = roundToTokenDecimals( + maxAmountOfTokenInToSupply, + poolReserve.decimals + ); } let supplyingWrappedToken = false; diff --git a/src/components/transactions/Supply/SupplyWrappedTokenActions.tsx b/src/components/transactions/Supply/SupplyWrappedTokenActions.tsx index 410b398a12..d537f6b894 100644 --- a/src/components/transactions/Supply/SupplyWrappedTokenActions.tsx +++ b/src/components/transactions/Supply/SupplyWrappedTokenActions.tsx @@ -72,9 +72,6 @@ export const SupplyWrappedTokenActions = ({ refetch: fetchApprovedAmount, } = useApprovedAmount({ marketData, token: tokenIn, spender: tokenWrapperAddress }); - console.log('approved amount', approvedAmount); - console.log('fetching', isFetching); - let requiresApproval = false; if (approvedAmount !== undefined) { requiresApproval = checkRequiresApproval({ diff --git a/src/hooks/token-wrapper/useTokenWrapper.ts b/src/hooks/token-wrapper/useTokenWrapper.ts index 4b32b3f5ec..4b216885df 100644 --- a/src/hooks/token-wrapper/useTokenWrapper.ts +++ b/src/hooks/token-wrapper/useTokenWrapper.ts @@ -18,11 +18,8 @@ export const useTokenInForTokenOut = ( tokenWrapperAddress ); }, - queryKey: [tokenWrapperAddress, amount], + queryKey: ['tokenInForTokenOut', tokenWrapperAddress, amount], select: (data) => formatUnits(data.toString(), decimals), - enabled: tokenWrapperAddress !== '', - refetchOnWindowFocus: false, - refetchOnMount: false, }); }; @@ -41,10 +38,7 @@ export const useTokenOutForTokenIn = ( tokenWrapperAddress ); }, - queryKey: [tokenWrapperAddress, amount], + queryKey: ['tokenOutForTokenIn', tokenWrapperAddress, amount], select: (data) => formatUnits(data.toString(), decimals), - enabled: tokenWrapperAddress !== '', - refetchOnWindowFocus: false, - refetchOnMount: false, }); }; From 90559adfa2b5f0b2219227eb88e7670d37640faf Mon Sep 17 00:00:00 2001 From: Mark Grothe Date: Thu, 15 Feb 2024 11:00:09 -0600 Subject: [PATCH 45/46] fix: success modal --- src/components/transactions/Supply/SupplyModalContent.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/transactions/Supply/SupplyModalContent.tsx b/src/components/transactions/Supply/SupplyModalContent.tsx index c2bbcb2218..150dd1bc83 100644 --- a/src/components/transactions/Supply/SupplyModalContent.tsx +++ b/src/components/transactions/Supply/SupplyModalContent.tsx @@ -386,7 +386,7 @@ export const SupplyWrappedTokenModalContent = ({ if (supplyTxState.success) { const successModalAmount = supplyingWrappedToken ? BigNumber(amount) - .multipliedBy(exchangeRate || '1') + .dividedBy(exchangeRate || '1') .toString() : amount; From c5bd0c9d8c31536623b81815ca167ffcd0c2a744 Mon Sep 17 00:00:00 2001 From: Mark Grothe Date: Thu, 22 Feb 2024 08:57:45 -0600 Subject: [PATCH 46/46] chore: utils --- package.json | 4 ++-- yarn.lock | 16 ++++++++-------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/package.json b/package.json index 7576a229b2..f89bbdba95 100644 --- a/package.json +++ b/package.json @@ -30,8 +30,8 @@ "test:coverage": "jest --coverage" }, "dependencies": { - "@aave/contract-helpers": "1.24.1-82a145b79d35bde0f05a1a82a3548eaaed18812b.0", - "@aave/math-utils": "1.24.1-82a145b79d35bde0f05a1a82a3548eaaed18812b.0", + "@aave/contract-helpers": "1.25.0", + "@aave/math-utils": "1.25.0", "@bgd-labs/aave-address-book": "^2.19.0", "@emotion/cache": "11.10.3", "@emotion/react": "11.10.4", diff --git a/yarn.lock b/yarn.lock index 7a253e57a7..4ac71e94d0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,17 +2,17 @@ # yarn lockfile v1 -"@aave/contract-helpers@1.24.1-82a145b79d35bde0f05a1a82a3548eaaed18812b.0": - version "1.24.1-82a145b79d35bde0f05a1a82a3548eaaed18812b.0" - resolved "https://registry.yarnpkg.com/@aave/contract-helpers/-/contract-helpers-1.24.1-82a145b79d35bde0f05a1a82a3548eaaed18812b.0.tgz#002c55520fddace7877a06b5fa2bdea0196b75d4" - integrity sha512-DS5JmwIozDs/9e8XsTdlMxXdArWwO7+ZsQ6iEfL10+n2mmWVtcoQeqzO9i46nFGygz3a9fCCqoCiQ84Olr4q9g== +"@aave/contract-helpers@1.25.0": + version "1.25.0" + resolved "https://registry.yarnpkg.com/@aave/contract-helpers/-/contract-helpers-1.25.0.tgz#7f196d9418fc55a9503045a1c179f2d2af01c606" + integrity sha512-EejPEa53px0qFo0QgmRwRUge8zEE0iYuS7B9OfYC3gE4/DGSvsRB8fdwkZxpi4r2gH0mFDol6VigpcIZrBYtHQ== dependencies: isomorphic-unfetch "^3.1.0" -"@aave/math-utils@1.24.1-82a145b79d35bde0f05a1a82a3548eaaed18812b.0": - version "1.24.1-82a145b79d35bde0f05a1a82a3548eaaed18812b.0" - resolved "https://registry.yarnpkg.com/@aave/math-utils/-/math-utils-1.24.1-82a145b79d35bde0f05a1a82a3548eaaed18812b.0.tgz#4fdc9a5505cc03ccf8ce5f04c78f9a6fa0deee20" - integrity sha512-v7nFJrUu1We+P/07UZ1NVFW8P9XvgO5324suDk0uk2GorblTcZIaMrR3FzR9tXoSFHJL/cAFHGQIJfpAQTCWpA== +"@aave/math-utils@1.25.0": + version "1.25.0" + resolved "https://registry.yarnpkg.com/@aave/math-utils/-/math-utils-1.25.0.tgz#8c6e112a7d96d7c687c2f106ccac2a16300913ca" + integrity sha512-KCXiujO2Xi3X74GqmrDOtEGpho3VKDts+/dVWFpBoCtWpI35qAI8IxgrmWVfR1/4qzDNDVX0R4QmVjqgTkRF7w== "@adobe/css-tools@^4.0.1": version "4.0.1"