mirror of
https://github.com/cerc-io/mars-interface.git
synced 2025-07-03 07:35:19 +00:00
releave v.1.4.0
This commit is contained in:
parent
d028d61a11
commit
6b86879fad
@ -7,7 +7,7 @@ import {
|
|||||||
WalletConnectionStatus,
|
WalletConnectionStatus,
|
||||||
} from '@marsprotocol/wallet-connector'
|
} from '@marsprotocol/wallet-connector'
|
||||||
import { useQueryClient } from '@tanstack/react-query'
|
import { useQueryClient } from '@tanstack/react-query'
|
||||||
import { MARS_SYMBOL, USDC_SYMBOL } from 'constants/appConstants'
|
import { MARS_SYMBOL } from 'constants/appConstants'
|
||||||
import { IS_TESTNET } from 'constants/env'
|
import { IS_TESTNET } from 'constants/env'
|
||||||
import {
|
import {
|
||||||
useBlockHeight,
|
useBlockHeight,
|
||||||
@ -155,7 +155,6 @@ export const CommonContainer = ({ children }: CommonContainerProps) => {
|
|||||||
useUserDebt()
|
useUserDebt()
|
||||||
useMarsOracle()
|
useMarsOracle()
|
||||||
useSpotPrice(MARS_SYMBOL)
|
useSpotPrice(MARS_SYMBOL)
|
||||||
useSpotPrice(USDC_SYMBOL)
|
|
||||||
useDepositAndDebt()
|
useDepositAndDebt()
|
||||||
useRedBank()
|
useRedBank()
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import { Coin } from '@cosmjs/stargate'
|
import { Coin } from '@cosmjs/stargate'
|
||||||
import { AnimatedNumber } from 'components/common'
|
import { AnimatedNumber } from 'components/common'
|
||||||
|
import { useEffect, useState } from 'react'
|
||||||
import useStore from 'store'
|
import useStore from 'store'
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
@ -20,7 +21,15 @@ export const DisplayCurrency = ({
|
|||||||
const networkConfig = useStore((s) => s.networkConfig)
|
const networkConfig = useStore((s) => s.networkConfig)
|
||||||
const convertToDisplayCurrency = useStore((s) => s.convertToDisplayCurrency)
|
const convertToDisplayCurrency = useStore((s) => s.convertToDisplayCurrency)
|
||||||
const amount = convertToDisplayCurrency(coin)
|
const amount = convertToDisplayCurrency(coin)
|
||||||
const displayCurrency = networkConfig?.displayCurrency
|
const [displayCurrency, setDisplayCurrency] = useState<DisplayCurrency>(
|
||||||
|
networkConfig?.displayCurrency,
|
||||||
|
)
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!networkConfig) return
|
||||||
|
if (displayCurrency.denom !== networkConfig?.displayCurrency.denom)
|
||||||
|
setDisplayCurrency(networkConfig?.displayCurrency)
|
||||||
|
}, [networkConfig?.displayCurrency, displayCurrency.denom, networkConfig])
|
||||||
|
|
||||||
if (!displayCurrency) return null
|
if (!displayCurrency) return null
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@ import { useTranslation } from 'react-i18next'
|
|||||||
import useStore from 'store'
|
import useStore from 'store'
|
||||||
import { DocURL } from 'types/enums/docURL'
|
import { DocURL } from 'types/enums/docURL'
|
||||||
|
|
||||||
import { version } from '../../../../package.json'
|
import packageInfo from '../../../../package.json'
|
||||||
import styles from './Footer.module.scss'
|
import styles from './Footer.module.scss'
|
||||||
|
|
||||||
export const Footer = () => {
|
export const Footer = () => {
|
||||||
@ -211,7 +211,7 @@ export const Footer = () => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className={styles.version}>
|
<div className={styles.version}>
|
||||||
<p className='faded xs'>Mars Protocol v{version}</p>
|
<p className='faded xs'>Mars Protocol v{packageInfo.version}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
|
@ -18,6 +18,10 @@
|
|||||||
outline: none;
|
outline: none;
|
||||||
background: $alphaBlack10;
|
background: $alphaBlack10;
|
||||||
|
|
||||||
|
.marsAmount {
|
||||||
|
margin: 0 space(1);
|
||||||
|
}
|
||||||
|
|
||||||
svg {
|
svg {
|
||||||
margin-top: space(-0.5);
|
margin-top: space(-0.5);
|
||||||
height: rem-calc(19);
|
height: rem-calc(19);
|
||||||
|
@ -153,13 +153,15 @@ export const IncentivesButton = () => {
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<SVG.Logo />
|
<SVG.Logo />
|
||||||
<DisplayCurrency
|
<span>
|
||||||
className={styles.balance}
|
<AnimatedNumber
|
||||||
coin={{
|
amount={Number(unclaimedRewards) / 1e6}
|
||||||
amount: unclaimedRewards,
|
minDecimals={2}
|
||||||
denom: marsDenom,
|
maxDecimals={2}
|
||||||
}}
|
className={styles.marsAmount}
|
||||||
/>
|
/>
|
||||||
|
{MARS_SYMBOL}
|
||||||
|
</span>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
{showDetails && (
|
{showDetails && (
|
||||||
|
@ -43,6 +43,17 @@
|
|||||||
flex: 0 0 100%;
|
flex: 0 0 100%;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
|
.select {
|
||||||
|
border-radius: $borderRadiusS;
|
||||||
|
border: rem-calc(1) solid $alphaBlack20;
|
||||||
|
@include padding(1, 2);
|
||||||
|
color: $colorSecondaryDark;
|
||||||
|
background-color: $fontColorLightPrimary;
|
||||||
|
outline: none;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
.name {
|
.name {
|
||||||
@include margin(1, 0);
|
@include margin(1, 0);
|
||||||
@ -62,12 +73,16 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.reduceMotion {
|
||||||
|
flex-direction: row;
|
||||||
|
}
|
||||||
|
|
||||||
.content {
|
.content {
|
||||||
@include margin(1, 0);
|
@include margin(1, 0);
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
justify-content: flex-end;
|
justify-content: space-between;
|
||||||
gap: space(2);
|
gap: space(2);
|
||||||
|
|
||||||
.button {
|
.button {
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import { useWalletManager, WalletConnectionStatus } from '@marsprotocol/wallet-connector'
|
import { useWalletManager, WalletConnectionStatus } from '@marsprotocol/wallet-connector'
|
||||||
|
import { useQueryClient } from '@tanstack/react-query'
|
||||||
import BigNumber from 'bignumber.js'
|
import BigNumber from 'bignumber.js'
|
||||||
import classNames from 'classnames'
|
import classNames from 'classnames'
|
||||||
import { Button, NumberInput, SVG, Toggle, Tooltip } from 'components/common'
|
import { Button, NumberInput, SVG, Toggle, Tooltip } from 'components/common'
|
||||||
@ -12,15 +13,39 @@ import styles from './Settings.module.scss'
|
|||||||
export const Settings = () => {
|
export const Settings = () => {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
const inputPlaceholder = '...'
|
const inputPlaceholder = '...'
|
||||||
|
const queryClient = useQueryClient()
|
||||||
const slippages = [0.02, 0.03]
|
const slippages = [0.02, 0.03]
|
||||||
const [showDetails, setShowDetails] = useState(false)
|
const [showDetails, setShowDetails] = useState(false)
|
||||||
const slippage = useStore((s) => s.slippage)
|
const slippage = useStore((s) => s.slippage)
|
||||||
|
const networkConfig = useStore((s) => s.networkConfig)
|
||||||
|
const baseCurrency = useStore((s) => s.baseCurrency)
|
||||||
|
const whitelistedAssets = useStore((s) => s.whitelistedAssets)
|
||||||
|
const otherAssets = useStore((s) => s.otherAssets)
|
||||||
|
const assets: Asset[] = [...whitelistedAssets, ...otherAssets]
|
||||||
const [customSlippage, setCustomSlippage] = useState<string>(inputPlaceholder)
|
const [customSlippage, setCustomSlippage] = useState<string>(inputPlaceholder)
|
||||||
const [inputRef, setInputRef] = useState<React.RefObject<HTMLInputElement>>()
|
const [inputRef, setInputRef] = useState<React.RefObject<HTMLInputElement>>()
|
||||||
const [isCustom, setIsCustom] = useState(false)
|
const [isCustom, setIsCustom] = useState(false)
|
||||||
const enableAnimations = useStore((s) => s.enableAnimations)
|
const enableAnimations = useStore((s) => s.enableAnimations)
|
||||||
const { status } = useWalletManager()
|
const { status } = useWalletManager()
|
||||||
|
const exchangeRates = useStore((s) => s.exchangeRates)
|
||||||
|
const [displayCurrency, setDisplayCurrency] = useState<DisplayCurrency>(() => {
|
||||||
|
const currency = {
|
||||||
|
denom: baseCurrency.denom,
|
||||||
|
prefix: '',
|
||||||
|
suffix: baseCurrency.symbol,
|
||||||
|
decimals: 2,
|
||||||
|
}
|
||||||
|
const currentCurrency = assets.find(
|
||||||
|
(asset) => asset.denom === networkConfig?.displayCurrency.denom,
|
||||||
|
)
|
||||||
|
|
||||||
|
if (currentCurrency) {
|
||||||
|
currency.denom = currentCurrency.denom
|
||||||
|
currency.prefix = ''
|
||||||
|
currency.suffix = currentCurrency.symbol
|
||||||
|
}
|
||||||
|
return currency
|
||||||
|
})
|
||||||
|
|
||||||
const onInputChange = (value: number) => {
|
const onInputChange = (value: number) => {
|
||||||
setCustomSlippage(value.toString())
|
setCustomSlippage(value.toString())
|
||||||
@ -57,6 +82,24 @@ export const Settings = () => {
|
|||||||
localStorage.setItem('enableAnimations', reduce ? 'false' : 'true')
|
localStorage.setItem('enableAnimations', reduce ? 'false' : 'true')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const changeDisplayCurrency = (denom: string) => {
|
||||||
|
const selectedAsset = assets.find((asset) => asset.denom === denom)
|
||||||
|
if (!selectedAsset || !networkConfig || !exchangeRates?.length) return
|
||||||
|
const newDisplayCurrency = {
|
||||||
|
denom: selectedAsset.denom,
|
||||||
|
prefix: '',
|
||||||
|
suffix: selectedAsset.symbol,
|
||||||
|
decimals: 2,
|
||||||
|
}
|
||||||
|
const exchangeRate = exchangeRates.find((rate) => rate.denom === newDisplayCurrency.denom)
|
||||||
|
if (!exchangeRate) return
|
||||||
|
setDisplayCurrency(newDisplayCurrency)
|
||||||
|
useStore.setState({ networkConfig: { ...networkConfig, displayCurrency: newDisplayCurrency } })
|
||||||
|
useStore.setState({ baseToDisplayCurrencyRatio: 1 / Number(exchangeRate.amount) })
|
||||||
|
localStorage.setItem('displayCurrency', JSON.stringify(newDisplayCurrency))
|
||||||
|
queryClient.invalidateQueries()
|
||||||
|
}
|
||||||
|
|
||||||
if (status !== WalletConnectionStatus.Connected) return null
|
if (status !== WalletConnectionStatus.Connected) return null
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -75,7 +118,7 @@ export const Settings = () => {
|
|||||||
<p className={styles.text}>{t('common.settings')}</p>
|
<p className={styles.text}>{t('common.settings')}</p>
|
||||||
</div>
|
</div>
|
||||||
<div className={styles.settings}>
|
<div className={styles.settings}>
|
||||||
<div className={styles.setting}>
|
<div className={`${styles.setting} ${styles.reduceMotion}`}>
|
||||||
<div className={styles.name}>
|
<div className={styles.name}>
|
||||||
{t('common.reduceMotion')}
|
{t('common.reduceMotion')}
|
||||||
<Tooltip content={t('common.tooltips.reduceMotion')} className={styles.tooltip} />
|
<Tooltip content={t('common.tooltips.reduceMotion')} className={styles.tooltip} />
|
||||||
@ -88,6 +131,31 @@ export const Settings = () => {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div className={styles.setting}>
|
||||||
|
<div className={styles.name}>
|
||||||
|
{t('common.displayCurrency')}
|
||||||
|
<Tooltip
|
||||||
|
content={t('common.tooltips.displayCurrency', {
|
||||||
|
baseCurrencySymbol: baseCurrency.symbol,
|
||||||
|
})}
|
||||||
|
className={styles.tooltip}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className={styles.content}>
|
||||||
|
<select
|
||||||
|
onChange={(e) => changeDisplayCurrency(e.target.value)}
|
||||||
|
className={classNames([styles.select, 's'])}
|
||||||
|
tabIndex={2}
|
||||||
|
value={displayCurrency.denom}
|
||||||
|
>
|
||||||
|
{assets.map((currency) => (
|
||||||
|
<option key={currency.denom} value={currency.denom}>
|
||||||
|
{`${currency.name} (${currency.symbol})`}
|
||||||
|
</option>
|
||||||
|
))}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{FIELDS_FEATURE && (
|
{FIELDS_FEATURE && (
|
||||||
<>
|
<>
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import Tippy from '@tippyjs/react'
|
import Tippy from '@tippyjs/react'
|
||||||
|
import classNames from 'classnames'
|
||||||
|
|
||||||
import styles from './TextTooltip.module.scss'
|
import styles from './TextTooltip.module.scss'
|
||||||
|
|
||||||
@ -7,6 +8,7 @@ interface Props {
|
|||||||
tooltip: string | React.ReactNode
|
tooltip: string | React.ReactNode
|
||||||
hideUnderline?: boolean
|
hideUnderline?: boolean
|
||||||
hideStyling?: boolean
|
hideStyling?: boolean
|
||||||
|
className?: string
|
||||||
}
|
}
|
||||||
export const TextTooltip = (props: Props) => {
|
export const TextTooltip = (props: Props) => {
|
||||||
return (
|
return (
|
||||||
@ -23,7 +25,13 @@ export const TextTooltip = (props: Props) => {
|
|||||||
)
|
)
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<span className={props.hideUnderline ? styles.pointer : styles.tooltip} style={{}}>
|
<span
|
||||||
|
className={classNames(
|
||||||
|
props.hideUnderline ? styles.pointer : styles.tooltip,
|
||||||
|
props.className,
|
||||||
|
)}
|
||||||
|
style={{}}
|
||||||
|
>
|
||||||
{props.text}
|
{props.text}
|
||||||
</span>
|
</span>
|
||||||
</Tippy>
|
</Tippy>
|
||||||
|
@ -66,7 +66,7 @@ export const Tutorial = (props: Props) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const maxLeverage = props.availableVault
|
const maxLeverage = props.availableVault
|
||||||
? formatValue(ltvToLeverage(props.availableVault?.ltv.max), 2, 2)
|
? formatValue(ltvToLeverage(props.availableVault?.ltv.contract), 2, 2)
|
||||||
: ''
|
: ''
|
||||||
|
|
||||||
const content = (
|
const content = (
|
||||||
|
@ -15,11 +15,16 @@ export const EditContent = (props: Props) => {
|
|||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
const convertValueToAmount = useStore((s) => s.convertValueToAmount)
|
const convertValueToAmount = useStore((s) => s.convertValueToAmount)
|
||||||
|
|
||||||
|
const borrowKey =
|
||||||
|
props.position.borrowDenom === props.vault.denoms.primary
|
||||||
|
? 'borrowedPrimary'
|
||||||
|
: 'borrowedSecondary'
|
||||||
|
|
||||||
const primaryAmount = props.position.amounts.primary - (props.prevPosition?.amounts.primary || 0)
|
const primaryAmount = props.position.amounts.primary - (props.prevPosition?.amounts.primary || 0)
|
||||||
const secondaryAmount =
|
const secondaryAmount =
|
||||||
props.position.amounts.secondary - (props.prevPosition?.amounts.secondary || 0)
|
props.position.amounts.secondary - (props.prevPosition?.amounts.secondary || 0)
|
||||||
const borrowedAmount =
|
const borrowedAmount =
|
||||||
props.position.amounts.borrowed - (props.prevPosition?.amounts.borrowed || 0)
|
props.position.amounts[borrowKey] - (props.prevPosition?.amounts[borrowKey] || 0)
|
||||||
|
|
||||||
const depositPrimary = (
|
const depositPrimary = (
|
||||||
<TokenBalance
|
<TokenBalance
|
||||||
@ -43,10 +48,10 @@ export const EditContent = (props: Props) => {
|
|||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
|
|
||||||
const borrowSecondary = (
|
const borrow = (
|
||||||
<TokenBalance
|
<TokenBalance
|
||||||
coin={{
|
coin={{
|
||||||
denom: props.vault.denoms.secondary,
|
denom: props.position.borrowDenom || props.vault.denoms.secondary,
|
||||||
amount: borrowedAmount.toString(),
|
amount: borrowedAmount.toString(),
|
||||||
}}
|
}}
|
||||||
className={styles.marginRight}
|
className={styles.marginRight}
|
||||||
@ -78,14 +83,14 @@ export const EditContent = (props: Props) => {
|
|||||||
return (
|
return (
|
||||||
<li>
|
<li>
|
||||||
<span className={styles.marginRight}>{t('redbank.borrow')}</span>
|
<span className={styles.marginRight}>{t('redbank.borrow')}</span>
|
||||||
{borrowSecondary}
|
{borrow}
|
||||||
</li>
|
</li>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const getSwapMessage = () => {
|
const getSwapMessage = () => {
|
||||||
const primaryValue = props.position.values.primary
|
const primaryValue = props.position.values.primary + props.position.values.borrowedPrimary
|
||||||
const secondaryValue = props.position.values.secondary + props.position.values.borrowed
|
const secondaryValue = props.position.values.secondary + props.position.values.borrowedSecondary
|
||||||
const difference = Math.abs(primaryValue - secondaryValue)
|
const difference = Math.abs(primaryValue - secondaryValue)
|
||||||
if (difference < SWAP_THRESHOLD) return null
|
if (difference < SWAP_THRESHOLD) return null
|
||||||
|
|
||||||
|
@ -15,14 +15,21 @@ export const UnlockContent = (props: Props) => {
|
|||||||
<>
|
<>
|
||||||
<li>{t('fields.removeLiquidity', { vault: props.vault.provider })}</li>
|
<li>{t('fields.removeLiquidity', { vault: props.vault.provider })}</li>
|
||||||
<li>
|
<li>
|
||||||
<span className={styles.marginRight}>{t('redbank.repay')}</span>
|
{props.position.borrowDenom && (
|
||||||
<TokenBalance
|
<>
|
||||||
coin={{
|
<span className={styles.marginRight}>{t('redbank.repay')}</span>
|
||||||
denom: props.vault.denoms.secondary,
|
<TokenBalance
|
||||||
amount: props.position.amounts.borrowed.toString(),
|
coin={{
|
||||||
}}
|
denom: props.position.borrowDenom,
|
||||||
showSymbol
|
amount: Math.max(
|
||||||
/>
|
props.position.amounts.borrowedPrimary,
|
||||||
|
props.position.amounts.borrowedSecondary,
|
||||||
|
).toString(),
|
||||||
|
}}
|
||||||
|
showSymbol
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<span className={styles.marginRight}>{t('redbank.withdraw')}</span>
|
<span className={styles.marginRight}>{t('redbank.withdraw')}</span>
|
||||||
|
@ -123,7 +123,10 @@ export const ActiveVaultsTableMobile = () => {
|
|||||||
<DisplayCurrency
|
<DisplayCurrency
|
||||||
coin={{
|
coin={{
|
||||||
denom: baseCurrency.denom,
|
denom: baseCurrency.denom,
|
||||||
amount: vault.position.values.borrowed.toString(),
|
amount: (vault.position.borrowDenom === vault.denoms.primary
|
||||||
|
? vault.position.amounts.borrowedPrimary
|
||||||
|
: vault.position.amounts.borrowedSecondary
|
||||||
|
).toString(),
|
||||||
}}
|
}}
|
||||||
className={styles.inline}
|
className={styles.inline}
|
||||||
/>
|
/>
|
||||||
@ -136,9 +139,13 @@ export const ActiveVaultsTableMobile = () => {
|
|||||||
<div className={styles.borrowCapacity}>
|
<div className={styles.borrowCapacity}>
|
||||||
<BorrowCapacity
|
<BorrowCapacity
|
||||||
showPercentageText={true}
|
showPercentageText={true}
|
||||||
max={getLiqBorrowValue(vault, maxBorrowValue)}
|
max={getLiqBorrowValue(vault, vault.position.values.net)}
|
||||||
limit={maxBorrowValue}
|
limit={maxBorrowValue}
|
||||||
balance={vault.position.values.borrowed}
|
balance={
|
||||||
|
vault.position.borrowDenom === vault.denoms.primary
|
||||||
|
? vault.position.values.borrowedPrimary
|
||||||
|
: vault.position.values.borrowedSecondary
|
||||||
|
}
|
||||||
showTitle={false}
|
showTitle={false}
|
||||||
barHeight={'16px'}
|
barHeight={'16px'}
|
||||||
hideValues
|
hideValues
|
||||||
|
@ -75,13 +75,16 @@ export const useActiveVaultsColumns = () => {
|
|||||||
cell: ({ row }) => {
|
cell: ({ row }) => {
|
||||||
const primaryCoin = {
|
const primaryCoin = {
|
||||||
denom: row.original.denoms.primary,
|
denom: row.original.denoms.primary,
|
||||||
amount: row.original.position.amounts.primary.toString(),
|
amount: (
|
||||||
|
row.original.position.amounts.primary + row.original.position.amounts.borrowedPrimary
|
||||||
|
).toString(),
|
||||||
}
|
}
|
||||||
|
|
||||||
const secondaryCoin = {
|
const secondaryCoin = {
|
||||||
denom: row.original.denoms.secondary,
|
denom: row.original.denoms.secondary,
|
||||||
amount: (
|
amount: (
|
||||||
row.original.position.amounts.secondary + row.original.position.amounts.borrowed
|
row.original.position.amounts.secondary +
|
||||||
|
row.original.position.amounts.borrowedSecondary
|
||||||
).toString(),
|
).toString(),
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -97,9 +100,13 @@ export const useActiveVaultsColumns = () => {
|
|||||||
}
|
}
|
||||||
tooltip={
|
tooltip={
|
||||||
<>
|
<>
|
||||||
<TokenBalance coin={primaryCoin} maxDecimals={2} showSymbol />
|
{Number(primaryCoin.amount) > 0 && (
|
||||||
|
<TokenBalance coin={primaryCoin} maxDecimals={2} showSymbol />
|
||||||
|
)}
|
||||||
<br />
|
<br />
|
||||||
<TokenBalance coin={secondaryCoin} maxDecimals={2} showSymbol />
|
{Number(secondaryCoin.amount) > 0 && (
|
||||||
|
<TokenBalance coin={secondaryCoin} maxDecimals={2} showSymbol />
|
||||||
|
)}
|
||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
@ -134,41 +141,50 @@ export const useActiveVaultsColumns = () => {
|
|||||||
}
|
}
|
||||||
tooltip={
|
tooltip={
|
||||||
<>
|
<>
|
||||||
<TokenBalance coin={coins[0]} maxDecimals={2} showSymbol />
|
{Number(coins[0].amount) > 0 && (
|
||||||
|
<TokenBalance coin={coins[0]} maxDecimals={2} showSymbol />
|
||||||
|
)}
|
||||||
<br />
|
<br />
|
||||||
<TokenBalance coin={coins[1]} maxDecimals={2} showSymbol />
|
{Number(coins[1].amount) > 0 && (
|
||||||
|
<TokenBalance coin={coins[1]} maxDecimals={2} showSymbol />
|
||||||
|
)}{' '}
|
||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
columnHelper.accessor('position.values.borrowed', {
|
columnHelper.accessor('position.values.borrowedPrimary', {
|
||||||
enableSorting: true,
|
enableSorting: true,
|
||||||
header: () => (
|
header: () => (
|
||||||
<TextTooltip text={t('common.borrowed')} tooltip={t('fields.tooltips.borrowValue')} />
|
<TextTooltip text={t('common.borrowed')} tooltip={t('fields.tooltips.borrowValue')} />
|
||||||
),
|
),
|
||||||
cell: (info) => {
|
cell: ({ row }) => {
|
||||||
const borrowAsset = whitelistedAssets.find(
|
const borrowAsset = whitelistedAssets.find(
|
||||||
(asset) => asset.denom === info.row.original.denoms.secondary,
|
(asset) => asset.denom === row.original.position.borrowDenom,
|
||||||
)
|
)
|
||||||
if (!borrowAsset) return
|
if (!borrowAsset) return
|
||||||
|
|
||||||
|
const borrowKey =
|
||||||
|
row.original.position.borrowDenom === row.original.denoms.primary
|
||||||
|
? 'borrowedPrimary'
|
||||||
|
: 'borrowedSecondary'
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<TextTooltip
|
<TextTooltip
|
||||||
text={
|
text={
|
||||||
<DisplayCurrency
|
<DisplayCurrency
|
||||||
coin={{
|
coin={{
|
||||||
denom: baseCurrency.denom,
|
denom: baseCurrency.denom,
|
||||||
amount: info.row.original.position.values.borrowed.toString(),
|
amount: row.original.position.values[borrowKey].toString(),
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
tooltip={
|
tooltip={
|
||||||
<TokenBalance
|
<TokenBalance
|
||||||
coin={{
|
coin={{
|
||||||
denom: info.row.original.denoms.secondary,
|
denom: borrowAsset.denom,
|
||||||
amount: info.row.original.position.amounts.borrowed.toString(),
|
amount: row.original.position.amounts[borrowKey].toString(),
|
||||||
}}
|
}}
|
||||||
maxDecimals={2}
|
maxDecimals={2}
|
||||||
showSymbol
|
showSymbol
|
||||||
@ -291,7 +307,7 @@ export const useActiveVaultsColumns = () => {
|
|||||||
</p>
|
</p>
|
||||||
<p className='s faded'>
|
<p className='s faded'>
|
||||||
{formatValue(
|
{formatValue(
|
||||||
ltvToLeverage(row.original.ltv.max),
|
ltvToLeverage(row.original.ltv.contract),
|
||||||
2,
|
2,
|
||||||
2,
|
2,
|
||||||
false,
|
false,
|
||||||
@ -303,7 +319,7 @@ export const useActiveVaultsColumns = () => {
|
|||||||
)
|
)
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
columnHelper.accessor('position.amounts.borrowed', {
|
columnHelper.accessor('position.amounts.borrowedPrimary', {
|
||||||
enableSorting: false,
|
enableSorting: false,
|
||||||
header: () => (
|
header: () => (
|
||||||
<TextTooltip
|
<TextTooltip
|
||||||
@ -313,13 +329,19 @@ export const useActiveVaultsColumns = () => {
|
|||||||
),
|
),
|
||||||
cell: ({ row }) => {
|
cell: ({ row }) => {
|
||||||
const maxBorrowValue = getMaxBorrowValue(row.original, row.original.position)
|
const maxBorrowValue = getMaxBorrowValue(row.original, row.original.position)
|
||||||
|
const borrowKey =
|
||||||
|
row.original.position.borrowDenom === row.original.denoms.primary
|
||||||
|
? 'borrowedPrimary'
|
||||||
|
: 'borrowedSecondary'
|
||||||
|
|
||||||
|
const liqBorrowValue = getLiqBorrowValue(row.original, row.original.position.values.net)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<BorrowCapacity
|
<BorrowCapacity
|
||||||
showPercentageText={true}
|
showPercentageText={true}
|
||||||
max={getLiqBorrowValue(row.original, maxBorrowValue)}
|
max={liqBorrowValue}
|
||||||
limit={maxBorrowValue}
|
limit={maxBorrowValue}
|
||||||
balance={row.original.position.values.borrowed}
|
balance={row.original.position.values[borrowKey]}
|
||||||
showTitle={false}
|
showTitle={false}
|
||||||
barHeight={'16px'}
|
barHeight={'16px'}
|
||||||
hideValues
|
hideValues
|
||||||
|
@ -24,11 +24,20 @@ export const AvailableVaultsTableMobile = () => {
|
|||||||
>
|
>
|
||||||
<div className={styles.container}>
|
<div className={styles.container}>
|
||||||
{availableVaults.map((vault, i) => {
|
{availableVaults.map((vault, i) => {
|
||||||
const borrowAsset = redBankAssets.find((asset) => asset.denom === vault.denoms.secondary)
|
const primaryBorrowAsset = redBankAssets.find(
|
||||||
const maxBorrowRate = Number(borrowAsset?.borrowRate ?? 0) * vault.ltv.max
|
(asset) => asset.denom === vault.denoms.primary,
|
||||||
|
)
|
||||||
|
const secondaryBorrowAsset = redBankAssets.find(
|
||||||
|
(asset) => asset.denom === vault.denoms.secondary,
|
||||||
|
)
|
||||||
|
const borrowRate = Math.min(
|
||||||
|
Number(primaryBorrowAsset?.borrowRate ?? 0),
|
||||||
|
Number(secondaryBorrowAsset?.borrowRate ?? 0),
|
||||||
|
)
|
||||||
|
const maxBorrowRate = borrowRate * (ltvToLeverage(vault.ltv.contract) - 1)
|
||||||
const minAPY = new BigNumber(vault.apy || 0).toNumber()
|
const minAPY = new BigNumber(vault.apy || 0).toNumber()
|
||||||
|
|
||||||
const leverage = ltvToLeverage(vault.ltv.max)
|
const leverage = ltvToLeverage(vault.ltv.contract)
|
||||||
const maxAPY =
|
const maxAPY =
|
||||||
new BigNumber(minAPY).times(leverage).decimalPlaces(2).toNumber() - maxBorrowRate
|
new BigNumber(minAPY).times(leverage).decimalPlaces(2).toNumber() - maxBorrowRate
|
||||||
const apyDataNoLev = { total: vault.apy || 0, borrow: 0 }
|
const apyDataNoLev = { total: vault.apy || 0, borrow: 0 }
|
||||||
@ -60,7 +69,10 @@ export const AvailableVaultsTableMobile = () => {
|
|||||||
hideStyling
|
hideStyling
|
||||||
text={<AnimatedNumber amount={maxAPY} suffix='%' />}
|
text={<AnimatedNumber amount={maxAPY} suffix='%' />}
|
||||||
tooltip={
|
tooltip={
|
||||||
<Apy apyData={apyDataLev} leverage={ltvToLeverage(vault.ltv.max)} />
|
<Apy
|
||||||
|
apyData={apyDataLev}
|
||||||
|
leverage={ltvToLeverage(vault.ltv.contract)}
|
||||||
|
/>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
</span>
|
</span>
|
||||||
|
@ -69,7 +69,7 @@ export const useAvailableVaultsColumns = () => {
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<p className='m'>
|
<p className='m'>
|
||||||
{formatValue(ltvToLeverage(row.original.ltv.max), 2, 2, false, false, 'x')}
|
{formatValue(ltvToLeverage(row.original.ltv.contract), 2, 2, false, false, 'x')}
|
||||||
</p>
|
</p>
|
||||||
<p className='s faded'>{t('global.max_lower')}</p>
|
<p className='s faded'>{t('global.max_lower')}</p>
|
||||||
</>
|
</>
|
||||||
@ -87,12 +87,20 @@ export const useAvailableVaultsColumns = () => {
|
|||||||
return <Loading />
|
return <Loading />
|
||||||
}
|
}
|
||||||
|
|
||||||
const maxLeverage = ltvToLeverage(row.original.ltv.max)
|
const maxLeverage = ltvToLeverage(row.original.ltv.contract)
|
||||||
const borrowAsset = redBankAssets.find(
|
const primaryBorrowAsset = redBankAssets.find(
|
||||||
|
(asset) => asset.denom === row.original.denoms.primary,
|
||||||
|
)
|
||||||
|
const secondaryBorrowAsset = redBankAssets.find(
|
||||||
(asset) => asset.denom === row.original.denoms.secondary,
|
(asset) => asset.denom === row.original.denoms.secondary,
|
||||||
)
|
)
|
||||||
const maxBorrowRate =
|
|
||||||
Number(borrowAsset?.borrowRate ?? 0) * (ltvToLeverage(row.original.ltv.max) - 1)
|
const borrowRate = Math.min(
|
||||||
|
Number(primaryBorrowAsset?.borrowRate ?? 0),
|
||||||
|
Number(secondaryBorrowAsset?.borrowRate ?? 0),
|
||||||
|
)
|
||||||
|
|
||||||
|
const maxBorrowRate = borrowRate * (ltvToLeverage(row.original.ltv.contract) - 1)
|
||||||
|
|
||||||
const minAPY = new BigNumber(row.original.apy).toNumber()
|
const minAPY = new BigNumber(row.original.apy).toNumber()
|
||||||
|
|
||||||
@ -128,7 +136,7 @@ export const useAvailableVaultsColumns = () => {
|
|||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
tooltip={
|
tooltip={
|
||||||
<Apy apyData={apyDataLev} leverage={ltvToLeverage(row.original.ltv.max)} />
|
<Apy apyData={apyDataLev} leverage={ltvToLeverage(row.original.ltv.contract)} />
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
@ -18,7 +18,11 @@ export const BreakdownGraph = (props: Props) => {
|
|||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
const convertToDisplayCurrency = useStore((s) => s.convertToDisplayCurrency)
|
const convertToDisplayCurrency = useStore((s) => s.convertToDisplayCurrency)
|
||||||
const baseCurrency = useStore((s) => s.baseCurrency)
|
const baseCurrency = useStore((s) => s.baseCurrency)
|
||||||
const yAxisLimit = Math.max(props.position.values.net, props.position.values.borrowed)
|
const borrowKey =
|
||||||
|
props.position.borrowDenom === props.vault.denoms.primary
|
||||||
|
? 'borrowedPrimary'
|
||||||
|
: 'borrowedSecondary'
|
||||||
|
const yAxisLimit = Math.max(props.position.values.net, props.position.values[borrowKey])
|
||||||
|
|
||||||
const containerClasses = classNames([
|
const containerClasses = classNames([
|
||||||
styles.container,
|
styles.container,
|
||||||
@ -40,7 +44,7 @@ export const BreakdownGraph = (props: Props) => {
|
|||||||
denom: props.vault.denoms.primary,
|
denom: props.vault.denoms.primary,
|
||||||
}),
|
}),
|
||||||
convertToDisplayCurrency({
|
convertToDisplayCurrency({
|
||||||
amount: props.position.values.borrowed.toString(),
|
amount: props.position.values[borrowKey].toString(),
|
||||||
denom: props.vault.denoms.primary,
|
denom: props.vault.denoms.primary,
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
@ -123,7 +127,11 @@ export const BreakdownGraph = (props: Props) => {
|
|||||||
<div className={`${styles.bar3}`} style={{ height: `${getBarHeightPercentage(3)}%` }}>
|
<div className={`${styles.bar3}`} style={{ height: `${getBarHeightPercentage(3)}%` }}>
|
||||||
<AssetBar
|
<AssetBar
|
||||||
type='debt'
|
type='debt'
|
||||||
symbol={props.vault.symbols.secondary}
|
symbol={
|
||||||
|
borrowKey === 'borrowedPrimary'
|
||||||
|
? props.vault.symbols.primary
|
||||||
|
: props.vault.symbols.secondary
|
||||||
|
}
|
||||||
height={getBarHeightPercentage(3)}
|
height={getBarHeightPercentage(3)}
|
||||||
showLabel={hasSpaceForLabel('debt')}
|
showLabel={hasSpaceForLabel('debt')}
|
||||||
/>
|
/>
|
||||||
|
@ -29,6 +29,10 @@
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
border-collapse: collapse;
|
border-collapse: collapse;
|
||||||
|
|
||||||
|
td {
|
||||||
|
min-width: space(12);
|
||||||
|
}
|
||||||
|
|
||||||
tr {
|
tr {
|
||||||
td:nth-child(2) {
|
td:nth-child(2) {
|
||||||
width: 20px;
|
width: 20px;
|
||||||
|
@ -47,10 +47,16 @@ export const BreakdownTable = (props: Props) => {
|
|||||||
|
|
||||||
const primaryPrice = usePrice(props.vault.denoms.primary)
|
const primaryPrice = usePrice(props.vault.denoms.primary)
|
||||||
const secondaryPrice = usePrice(props.vault.denoms.secondary)
|
const secondaryPrice = usePrice(props.vault.denoms.secondary)
|
||||||
|
const primaryRedBankAsset = useRedBankAsset(props.vault.denoms.primary)
|
||||||
const secondaryRedBankAsset = useRedBankAsset(props.vault.denoms.secondary)
|
const secondaryRedBankAsset = useRedBankAsset(props.vault.denoms.secondary)
|
||||||
const primaryChange = props.newPosition.amounts.primary - props.prevPosition.amounts.primary
|
const primaryChange = props.newPosition.amounts.primary - props.prevPosition.amounts.primary
|
||||||
const secondaryChange = props.newPosition.amounts.secondary - props.prevPosition.amounts.secondary
|
const secondaryChange = props.newPosition.amounts.secondary - props.prevPosition.amounts.secondary
|
||||||
const borrowedChange = props.newPosition.amounts.borrowed - props.prevPosition.amounts.borrowed
|
const borrowKey =
|
||||||
|
props.newPosition.borrowDenom === props.vault.denoms.primary
|
||||||
|
? 'borrowedPrimary'
|
||||||
|
: 'borrowedSecondary'
|
||||||
|
const borrowedChange =
|
||||||
|
props.newPosition.amounts[borrowKey] - props.prevPosition.amounts[borrowKey]
|
||||||
|
|
||||||
const containerClasses = classNames([
|
const containerClasses = classNames([
|
||||||
props.className,
|
props.className,
|
||||||
@ -71,15 +77,15 @@ export const BreakdownTable = (props: Props) => {
|
|||||||
denom = props.vault.denoms.secondary
|
denom = props.vault.denoms.secondary
|
||||||
break
|
break
|
||||||
case AmountType.DEBT:
|
case AmountType.DEBT:
|
||||||
amount = props.newPosition.amounts.borrowed
|
amount = props.newPosition.amounts[borrowKey]
|
||||||
denom = props.vault.denoms.secondary
|
denom = props.vault.denoms.secondary
|
||||||
break
|
break
|
||||||
case AmountType.POSITION_PRIMARY:
|
case AmountType.POSITION_PRIMARY:
|
||||||
amount = props.newPosition.amounts.primary
|
amount = props.newPosition.amounts.primary + props.newPosition.amounts.borrowedPrimary
|
||||||
denom = props.vault.denoms.primary
|
denom = props.vault.denoms.primary
|
||||||
break
|
break
|
||||||
case AmountType.POSITION_SECONDARY:
|
case AmountType.POSITION_SECONDARY:
|
||||||
amount = props.newPosition.amounts.secondary + props.newPosition.amounts.borrowed
|
amount = props.newPosition.amounts.secondary + props.newPosition.amounts.borrowedSecondary
|
||||||
denom = props.vault.denoms.secondary
|
denom = props.vault.denoms.secondary
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@ -122,7 +128,9 @@ export const BreakdownTable = (props: Props) => {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const getValueText = (type: 'net' | 'borrowed' | 'total') => (
|
const getValueText = (
|
||||||
|
type: 'primary' | 'secondary' | 'net' | 'borrowedPrimary' | 'borrowedSecondary' | 'total',
|
||||||
|
) => (
|
||||||
<DisplayCurrency
|
<DisplayCurrency
|
||||||
prefixClass='s faded'
|
prefixClass='s faded'
|
||||||
valueClass='m faded'
|
valueClass='m faded'
|
||||||
@ -152,7 +160,8 @@ export const BreakdownTable = (props: Props) => {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const isReducingDebt = props.newPosition.amounts.borrowed < props.prevPosition.amounts.borrowed
|
const isReducingDebt =
|
||||||
|
props.newPosition.amounts[borrowKey] < props.prevPosition.amounts[borrowKey]
|
||||||
if (isReducingDebt) {
|
if (isReducingDebt) {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@ -208,8 +217,12 @@ export const BreakdownTable = (props: Props) => {
|
|||||||
/* APY CALCULATION */
|
/* APY CALCULATION */
|
||||||
const currentLeverage = props.newPosition.currentLeverage
|
const currentLeverage = props.newPosition.currentLeverage
|
||||||
|
|
||||||
const trueBorrowRate =
|
const borrowRate = Number(
|
||||||
Number(secondaryRedBankAsset?.borrowRate ?? 0) * (Number(currentLeverage) - 1)
|
borrowKey === 'borrowedPrimary'
|
||||||
|
? primaryRedBankAsset?.borrowRate
|
||||||
|
: secondaryRedBankAsset?.borrowRate,
|
||||||
|
)
|
||||||
|
const trueBorrowRate = borrowRate * (Number(currentLeverage) - 1)
|
||||||
|
|
||||||
const apy = (props.vault.apy || 0) * currentLeverage - trueBorrowRate
|
const apy = (props.vault.apy || 0) * currentLeverage - trueBorrowRate
|
||||||
|
|
||||||
@ -291,9 +304,11 @@ export const BreakdownTable = (props: Props) => {
|
|||||||
<tr className={styles.debtRow}>
|
<tr className={styles.debtRow}>
|
||||||
<td className={`${styles.showDesktop} faded`}>{t('common.debt')}</td>
|
<td className={`${styles.showDesktop} faded`}>{t('common.debt')}</td>
|
||||||
<td className={styles.alignRight}>{getTokenBalance(AmountType.DEBT)}</td>
|
<td className={styles.alignRight}>{getTokenBalance(AmountType.DEBT)}</td>
|
||||||
<td>{secondaryAsset?.symbol}</td>
|
<td>
|
||||||
|
{borrowKey === 'borrowedPrimary' ? primaryAsset?.symbol : secondaryAsset?.symbol}
|
||||||
|
</td>
|
||||||
<td>{getChangeText(borrowedChange, 'secondary', true)}</td>
|
<td>{getChangeText(borrowedChange, 'secondary', true)}</td>
|
||||||
<td>{getValueText('borrowed')}</td>
|
<td>{getValueText(borrowKey)}</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
<tr className={`${styles.labelRow} faded`}>
|
<tr className={`${styles.labelRow} faded`}>
|
||||||
@ -320,11 +335,14 @@ export const BreakdownTable = (props: Props) => {
|
|||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
{!props.isRepay && <div className={styles.reduceMessage}>{getWarningMessage()}</div>}
|
{!props.isRepay && <div className={styles.reduceMessage}>{getWarningMessage()}</div>}
|
||||||
|
|
||||||
<BorrowCapacity
|
<BorrowCapacity
|
||||||
className={styles.borrowCapacity}
|
className={styles.borrowCapacity}
|
||||||
limit={maxBorrowValue}
|
limit={maxBorrowValue}
|
||||||
max={getLiqBorrowValue(props.vault, maxBorrowValue)}
|
max={getLiqBorrowValue(props.vault, props.newPosition.values.net)}
|
||||||
balance={props.newPosition.values.borrowed}
|
balance={
|
||||||
|
props.newPosition.values.borrowedPrimary + props.newPosition.values.borrowedSecondary
|
||||||
|
}
|
||||||
barHeight={'24px'}
|
barHeight={'24px'}
|
||||||
showPercentageText
|
showPercentageText
|
||||||
/>
|
/>
|
||||||
|
@ -2,6 +2,7 @@ import classNames from 'classnames'
|
|||||||
import { Tutorial } from 'components/common'
|
import { Tutorial } from 'components/common'
|
||||||
import { TokenInput } from 'components/fields'
|
import { TokenInput } from 'components/fields'
|
||||||
import { FIELDS_TUTORIAL_KEY } from 'constants/appConstants'
|
import { FIELDS_TUTORIAL_KEY } from 'constants/appConstants'
|
||||||
|
import { useState } from 'react'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
import useStore from 'store'
|
import useStore from 'store'
|
||||||
|
|
||||||
@ -9,33 +10,106 @@ import styles from './BorrowInput.module.scss'
|
|||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
vault: Vault
|
vault: Vault
|
||||||
borrowAmount: number
|
borrowedPrimaryAmount: number
|
||||||
|
borrowedSecondaryAmount: number
|
||||||
maxAmount: number
|
maxAmount: number
|
||||||
onChange: (amount: number) => void
|
prevPosition?: Position
|
||||||
|
onChangePrimary: (amount: number) => void
|
||||||
|
onChangeSecondary: (amount: number) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
export const BorrowInput = (props: Props) => {
|
export const BorrowInput = (props: Props) => {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
const redBankAssets = useStore((s) => s.redBankAssets)
|
const redBankAssets = useStore((s) => s.redBankAssets)
|
||||||
const showTutorial = !localStorage.getItem(FIELDS_TUTORIAL_KEY)
|
const showTutorial = !localStorage.getItem(FIELDS_TUTORIAL_KEY)
|
||||||
const asset = redBankAssets.find((asset) => asset.denom === props.vault.denoms.secondary)
|
const primaryAsset = redBankAssets.find((asset) => asset.denom === props.vault.denoms.primary)
|
||||||
|
const secondaryAsset = redBankAssets.find((asset) => asset.denom === props.vault.denoms.secondary)
|
||||||
const containerClasses = classNames([styles.container])
|
const containerClasses = classNames([styles.container])
|
||||||
const input: Input = {
|
const [cachedPrimaryAmount, setCachedPrimaryAmount] = useState(props.borrowedPrimaryAmount)
|
||||||
visible: true,
|
const [cachedSecondaryAmount, setCachedSecondaryAmount] = useState(props.borrowedSecondaryAmount)
|
||||||
|
|
||||||
|
const primaryInputVisisble =
|
||||||
|
props.borrowedPrimaryAmount > 0 ||
|
||||||
|
props.prevPosition?.borrowDenom === props.vault.denoms.primary
|
||||||
|
? true
|
||||||
|
: false
|
||||||
|
|
||||||
|
const [primaryInput, setPrimaryInput] = useState<Input>({
|
||||||
|
visible: primaryInputVisisble,
|
||||||
|
denom: props.vault.denoms.primary,
|
||||||
|
symbol: props.vault.symbols.primary,
|
||||||
|
})
|
||||||
|
|
||||||
|
const [secondaryInput, setSecondaryInput] = useState<Input>({
|
||||||
|
visible: !primaryInputVisisble,
|
||||||
denom: props.vault.denoms.secondary,
|
denom: props.vault.denoms.secondary,
|
||||||
symbol: props.vault.symbols.secondary,
|
symbol: props.vault.symbols.secondary,
|
||||||
|
})
|
||||||
|
|
||||||
|
const selectInput = (symbol: string) => {
|
||||||
|
if (symbol === primaryInput.symbol) {
|
||||||
|
primaryInput.visible = true
|
||||||
|
secondaryInput.visible = false
|
||||||
|
setCachedSecondaryAmount(props.borrowedSecondaryAmount)
|
||||||
|
props.onChangePrimary(cachedPrimaryAmount)
|
||||||
|
} else {
|
||||||
|
primaryInput.visible = false
|
||||||
|
secondaryInput.visible = true
|
||||||
|
setCachedPrimaryAmount(props.borrowedPrimaryAmount)
|
||||||
|
props.onChangeSecondary(cachedSecondaryAmount)
|
||||||
|
}
|
||||||
|
|
||||||
|
setPrimaryInput({ ...primaryInput })
|
||||||
|
setSecondaryInput({ ...secondaryInput })
|
||||||
|
}
|
||||||
|
|
||||||
|
const onChangePrimary = (amount: number) => {
|
||||||
|
setCachedPrimaryAmount(amount)
|
||||||
|
props.onChangePrimary(amount)
|
||||||
|
}
|
||||||
|
|
||||||
|
const onChangeSecondary = (amount: number) => {
|
||||||
|
setCachedSecondaryAmount(amount)
|
||||||
|
props.onChangeSecondary(amount)
|
||||||
}
|
}
|
||||||
|
|
||||||
const tokenInput = (
|
const tokenInput = (
|
||||||
<TokenInput
|
<>
|
||||||
input={input}
|
{primaryInput.visible && (
|
||||||
amount={props.borrowAmount}
|
<TokenInput
|
||||||
maxAmount={props.maxAmount}
|
input={primaryInput}
|
||||||
maxAmountLabel={t('global.max')}
|
amount={props.borrowedPrimaryAmount}
|
||||||
onChange={props.onChange}
|
onChange={onChangePrimary}
|
||||||
tokens={[props.vault.symbols.secondary]}
|
tokens={
|
||||||
borrowRate={asset?.borrowRate}
|
props.prevPosition?.borrowDenom === props.vault.denoms.primary
|
||||||
/>
|
? [primaryInput.symbol]
|
||||||
|
: [primaryInput.symbol, secondaryInput.symbol]
|
||||||
|
}
|
||||||
|
onSelect={selectInput}
|
||||||
|
maxAmountLabel={t('global.max')}
|
||||||
|
maxAmount={props.maxAmount}
|
||||||
|
borrowRate={primaryAsset?.borrowRate}
|
||||||
|
disableGasWarning
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
{secondaryInput.visible && (
|
||||||
|
<TokenInput
|
||||||
|
input={secondaryInput}
|
||||||
|
amount={props.borrowedSecondaryAmount}
|
||||||
|
onChange={onChangeSecondary}
|
||||||
|
tokens={
|
||||||
|
props.prevPosition?.borrowDenom === props.vault.denoms.secondary
|
||||||
|
? [secondaryInput.symbol]
|
||||||
|
: [primaryInput.symbol, secondaryInput.symbol]
|
||||||
|
}
|
||||||
|
onSelect={selectInput}
|
||||||
|
maxAmountLabel={t('global.max')}
|
||||||
|
maxAmount={props.maxAmount}
|
||||||
|
borrowRate={secondaryAsset?.borrowRate}
|
||||||
|
disableGasWarning
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
)
|
)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -2,7 +2,7 @@ import BigNumber from 'bignumber.js'
|
|||||||
import classNames from 'classnames'
|
import classNames from 'classnames'
|
||||||
import { InputSlider, Tutorial } from 'components/common'
|
import { InputSlider, Tutorial } from 'components/common'
|
||||||
import { FIELDS_TUTORIAL_KEY } from 'constants/appConstants'
|
import { FIELDS_TUTORIAL_KEY } from 'constants/appConstants'
|
||||||
import { formatValue, ltvToLeverage } from 'libs/parse'
|
import { formatValue, leverageToLtv, ltvToLeverage } from 'libs/parse'
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
import colors from 'styles/_assets.module.scss'
|
import colors from 'styles/_assets.module.scss'
|
||||||
@ -29,7 +29,7 @@ export const LeverageSlider = (props: Props) => {
|
|||||||
isLeverage
|
isLeverage
|
||||||
value={props.leverage}
|
value={props.leverage}
|
||||||
maxValue={props.leverageMax}
|
maxValue={props.leverageMax}
|
||||||
leverageMax={ltvToLeverage(props.vault.ltv.max)}
|
leverageMax={ltvToLeverage(props.vault.ltv.contract)}
|
||||||
leverageLimit={props.leverageLimit}
|
leverageLimit={props.leverageLimit}
|
||||||
onChange={props.onChange}
|
onChange={props.onChange}
|
||||||
sliderColor={colors.secondary}
|
sliderColor={colors.secondary}
|
||||||
@ -51,8 +51,11 @@ export const LeverageSlider = (props: Props) => {
|
|||||||
) : (
|
) : (
|
||||||
<>{slider}</>
|
<>{slider}</>
|
||||||
)}
|
)}
|
||||||
|
{leverageToLtv(props.leverage) > props.vault.ltv.max && (
|
||||||
|
<span className={styles.warning}>{t('fields.messages.closeToMaxLtv')}</span>
|
||||||
|
)}
|
||||||
{props.leverage >= props.leverageLimit &&
|
{props.leverage >= props.leverageLimit &&
|
||||||
props.leverageLimit < ltvToLeverage(props.vault.ltv.max) && (
|
props.leverageLimit < ltvToLeverage(props.vault.ltv.contract) && (
|
||||||
<span className={styles.warning}>
|
<span className={styles.warning}>
|
||||||
{t('fields.messages.unableToIncreaseLeverage', {
|
{t('fields.messages.unableToIncreaseLeverage', {
|
||||||
leverage: formatValue(props.leverageLimit, 2, 2),
|
leverage: formatValue(props.leverageLimit, 2, 2),
|
||||||
|
@ -54,6 +54,6 @@
|
|||||||
@media only screen and (min-width: $bpMediumHigh) {
|
@media only screen and (min-width: $bpMediumHigh) {
|
||||||
.grid {
|
.grid {
|
||||||
grid-template-areas: 'supply leverage borrow';
|
grid-template-areas: 'supply leverage borrow';
|
||||||
grid-template-columns: auto 2fr 1fr;
|
grid-auto-columns: auto;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,9 @@ export const PositionInput = (props: Props) => {
|
|||||||
const marketAssetLiquidity = useStore((s) => s.marketAssetLiquidity)
|
const marketAssetLiquidity = useStore((s) => s.marketAssetLiquidity)
|
||||||
const convertToBaseCurrency = useStore((s) => s.convertToBaseCurrency)
|
const convertToBaseCurrency = useStore((s) => s.convertToBaseCurrency)
|
||||||
const convertValueToAmount = useStore((s) => s.convertValueToAmount)
|
const convertValueToAmount = useStore((s) => s.convertValueToAmount)
|
||||||
const [maxAllowedLeverage, setMaxAllowedLeverage] = useState(ltvToLeverage(props.vault.ltv.max))
|
const [maxAllowedLeverage, setMaxAllowedLeverage] = useState(
|
||||||
|
ltvToLeverage(props.vault.ltv.contract),
|
||||||
|
)
|
||||||
const tutorialStep = useStore((s) => s.tutorialSteps['fields'])
|
const tutorialStep = useStore((s) => s.tutorialSteps['fields'])
|
||||||
const showTutorial = !localStorage.getItem(FIELDS_TUTORIAL_KEY)
|
const showTutorial = !localStorage.getItem(FIELDS_TUTORIAL_KEY)
|
||||||
|
|
||||||
@ -33,13 +35,26 @@ export const PositionInput = (props: Props) => {
|
|||||||
denom: props.vault.denoms.secondary,
|
denom: props.vault.denoms.secondary,
|
||||||
amount: position.amounts.secondary.toString(),
|
amount: position.amounts.secondary.toString(),
|
||||||
})
|
})
|
||||||
const borrowValue = convertToBaseCurrency({
|
const borrowedPrimaryValue = convertToBaseCurrency({
|
||||||
denom: props.vault.denoms.secondary,
|
denom: props.vault.denoms.primary,
|
||||||
amount: position.amounts.borrowed.toString(),
|
amount: position.amounts.borrowedPrimary.toString(),
|
||||||
})
|
})
|
||||||
position.values.borrowed = borrowValue
|
const borrowedSecondaryValue = convertToBaseCurrency({
|
||||||
position.values.total = borrowValue + primaryValue + secondaryValue
|
denom: props.vault.denoms.secondary,
|
||||||
|
amount: position.amounts.borrowedSecondary.toString(),
|
||||||
|
})
|
||||||
|
position.values.borrowedPrimary = borrowedPrimaryValue
|
||||||
|
position.values.borrowedSecondary = borrowedSecondaryValue
|
||||||
|
position.values.total =
|
||||||
|
borrowedPrimaryValue + borrowedSecondaryValue + primaryValue + secondaryValue
|
||||||
position.values.net = primaryValue + secondaryValue
|
position.values.net = primaryValue + secondaryValue
|
||||||
|
|
||||||
|
if (borrowedPrimaryValue > 0) {
|
||||||
|
props.position.borrowDenom = props.vault.denoms.primary
|
||||||
|
} else if (borrowedSecondaryValue > 0) {
|
||||||
|
props.position.borrowDenom = props.vault.denoms.secondary
|
||||||
|
}
|
||||||
|
|
||||||
return position
|
return position
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -53,20 +68,27 @@ export const PositionInput = (props: Props) => {
|
|||||||
computeBorrowAmount()
|
computeBorrowAmount()
|
||||||
}
|
}
|
||||||
|
|
||||||
const onBorrowChange = (amount: number) => {
|
const onBorrowChange = (amount: number, type: 'primary' | 'secondary') => {
|
||||||
|
props.position.borrowDenom =
|
||||||
|
type === 'primary' ? props.vault.denoms.primary : props.vault.denoms.secondary
|
||||||
const borrowValue = convertToBaseCurrency({
|
const borrowValue = convertToBaseCurrency({
|
||||||
denom: props.vault.denoms.secondary,
|
denom: props.position.borrowDenom,
|
||||||
amount: amount.toString(),
|
amount: amount.toString(),
|
||||||
})
|
})
|
||||||
props.position.amounts.borrowed = amount
|
const borrowKey = type === 'primary' ? 'borrowedPrimary' : 'borrowedSecondary'
|
||||||
props.position.values.borrowed = borrowValue
|
const secondaryBorrowKey = type !== 'primary' ? 'borrowedPrimary' : 'borrowedSecondary'
|
||||||
|
props.position.amounts[borrowKey] = amount
|
||||||
|
props.position.amounts[secondaryBorrowKey] = 0
|
||||||
|
props.position.values[borrowKey] = borrowValue
|
||||||
|
props.position.values[secondaryBorrowKey] = 0
|
||||||
props.position.currentLeverage = getLeverageFromValues(props.position.values)
|
props.position.currentLeverage = getLeverageFromValues(props.position.values)
|
||||||
props.setPosition({ ...updateValues(props.position) })
|
props.setPosition({ ...updateValues(props.position) })
|
||||||
|
computeBorrowAmount()
|
||||||
}
|
}
|
||||||
|
|
||||||
const computeMaxAllowedLeverage = () => {
|
const computeMaxAllowedLeverage = () => {
|
||||||
const maxBorrowValue = convertToBaseCurrency({
|
const maxBorrowValue = convertToBaseCurrency({
|
||||||
denom: props.vault.denoms.secondary,
|
denom: props.position.borrowDenom || props.vault.denoms.secondary,
|
||||||
amount: computeMaxBorrowAmount().toString(),
|
amount: computeMaxBorrowAmount().toString(),
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -76,16 +98,20 @@ export const PositionInput = (props: Props) => {
|
|||||||
props.position.values.primary,
|
props.position.values.primary,
|
||||||
props.position.values.secondary,
|
props.position.values.secondary,
|
||||||
)
|
)
|
||||||
: ltvToLeverage(props.vault.ltv.max)
|
: ltvToLeverage(props.vault.ltv.contract)
|
||||||
}
|
}
|
||||||
|
|
||||||
const computeBorrowAmount = (leverage?: number) => {
|
const computeBorrowAmount = (leverage?: number) => {
|
||||||
const supplyBorrowRatio = leverage ? leverage - 1 : props.position.currentLeverage - 1
|
const supplyBorrowRatio = leverage ? leverage - 1 : props.position.currentLeverage - 1
|
||||||
const supplyValue = props.position.values.primary + props.position.values.secondary
|
const supplyValue = props.position.values.primary + props.position.values.secondary
|
||||||
const borrowValue = new BigNumber(supplyValue).times(supplyBorrowRatio).toNumber()
|
const borrowValue = new BigNumber(supplyValue).times(supplyBorrowRatio).toNumber()
|
||||||
|
const borrowDenom = props.position.borrowDenom
|
||||||
|
? props.position.borrowDenom
|
||||||
|
: props.vault.denoms.secondary
|
||||||
|
|
||||||
const borrowAmount = Math.floor(
|
const borrowAmount = Math.floor(
|
||||||
convertValueToAmount({
|
convertValueToAmount({
|
||||||
denom: props.vault.denoms.secondary,
|
denom: borrowDenom,
|
||||||
amount: borrowValue.toString(),
|
amount: borrowValue.toString(),
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
@ -97,12 +123,15 @@ export const PositionInput = (props: Props) => {
|
|||||||
: props.position.currentLeverage
|
: props.position.currentLeverage
|
||||||
const maxAllowedLeverage = computeMaxAllowedLeverage()
|
const maxAllowedLeverage = computeMaxAllowedLeverage()
|
||||||
|
|
||||||
|
const borrowKey =
|
||||||
|
borrowDenom === props.vault.denoms.primary ? 'borrowedPrimary' : 'borrowedSecondary'
|
||||||
|
|
||||||
if (targetLeverage > maxAllowedLeverage) {
|
if (targetLeverage > maxAllowedLeverage) {
|
||||||
const borrowAmount = computeMaxBorrowAmount()
|
const borrowAmount = computeMaxBorrowAmount()
|
||||||
props.position.amounts.borrowed = borrowAmount
|
props.position.amounts[borrowKey] = borrowAmount
|
||||||
props.position.currentLeverage = maxAllowedLeverage
|
props.position.currentLeverage = maxAllowedLeverage
|
||||||
} else {
|
} else {
|
||||||
props.position.amounts.borrowed = borrowAmount
|
props.position.amounts[borrowKey] = borrowAmount
|
||||||
props.position.currentLeverage = targetLeverage
|
props.position.currentLeverage = targetLeverage
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -111,25 +140,28 @@ export const PositionInput = (props: Props) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const computeMaxBorrowAmount = () => {
|
const computeMaxBorrowAmount = () => {
|
||||||
|
const borrowDenom = props.position.borrowDenom || props.vault.denoms.secondary
|
||||||
|
|
||||||
const maxAmount = Math.floor(
|
const maxAmount = Math.floor(
|
||||||
convertValueToAmount({
|
convertValueToAmount({
|
||||||
denom: props.vault.denoms.secondary,
|
denom: borrowDenom,
|
||||||
amount: getMaxBorrowValue(props.vault, props.position).toString(),
|
amount: getMaxBorrowValue(props.vault, props.position).toString(),
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
|
|
||||||
const marketLiquidity = Number(
|
const marketLiquidity = Number(
|
||||||
marketAssetLiquidity.find((market) => market.denom === props.vault.denoms.secondary)
|
marketAssetLiquidity.find((market) => market.denom === borrowDenom)?.amount || 0,
|
||||||
?.amount || 0,
|
|
||||||
)
|
)
|
||||||
|
const borrowKey =
|
||||||
|
borrowDenom === props.vault.denoms.primary ? 'borrowedPrimary' : 'borrowedSecondary'
|
||||||
|
|
||||||
const maxBorrowAmount = Math.min(
|
const maxBorrowAmount = Math.min(
|
||||||
maxAmount,
|
maxAmount,
|
||||||
(props.prevPosition?.amounts.borrowed || 0) + marketLiquidity,
|
(props.prevPosition?.amounts[borrowKey] || 0) + marketLiquidity,
|
||||||
)
|
)
|
||||||
|
|
||||||
if (props.prevPosition) {
|
if (props.prevPosition) {
|
||||||
return Math.max(maxBorrowAmount, props.prevPosition.amounts.borrowed)
|
return Math.max(maxBorrowAmount, props.prevPosition.amounts[borrowKey])
|
||||||
}
|
}
|
||||||
|
|
||||||
return maxBorrowAmount
|
return maxBorrowAmount
|
||||||
@ -154,7 +186,7 @@ export const PositionInput = (props: Props) => {
|
|||||||
leverage={props.position.currentLeverage || 1}
|
leverage={props.position.currentLeverage || 1}
|
||||||
leverageLimit={maxAllowedLeverage}
|
leverageLimit={maxAllowedLeverage}
|
||||||
leverageMax={Math.max(
|
leverageMax={Math.max(
|
||||||
ltvToLeverage(props.vault.ltv.max),
|
ltvToLeverage(props.vault.ltv.contract),
|
||||||
props.prevPosition?.currentLeverage || 1,
|
props.prevPosition?.currentLeverage || 1,
|
||||||
)}
|
)}
|
||||||
onChange={computeBorrowAmount}
|
onChange={computeBorrowAmount}
|
||||||
@ -162,10 +194,13 @@ export const PositionInput = (props: Props) => {
|
|||||||
</Highlight>
|
</Highlight>
|
||||||
<Highlight show={tutorialStep === 3 || !showTutorial} className={styles.borrow}>
|
<Highlight show={tutorialStep === 3 || !showTutorial} className={styles.borrow}>
|
||||||
<BorrowInput
|
<BorrowInput
|
||||||
borrowAmount={props.position.amounts.borrowed}
|
borrowedPrimaryAmount={props.position.amounts.borrowedPrimary}
|
||||||
onChange={onBorrowChange}
|
borrowedSecondaryAmount={props.position.amounts.borrowedSecondary}
|
||||||
|
onChangePrimary={(amount) => onBorrowChange(amount, 'primary')}
|
||||||
|
onChangeSecondary={(amount) => onBorrowChange(amount, 'secondary')}
|
||||||
maxAmount={computeMaxBorrowAmount()}
|
maxAmount={computeMaxBorrowAmount()}
|
||||||
vault={props.vault}
|
vault={props.vault}
|
||||||
|
prevPosition={props.prevPosition}
|
||||||
/>
|
/>
|
||||||
</Highlight>
|
</Highlight>
|
||||||
</div>
|
</div>
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: space(2);
|
gap: space(2);
|
||||||
flex: 1;
|
flex: 1;
|
||||||
|
min-width: rem-calc(160);
|
||||||
|
|
||||||
.input {
|
.input {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
@ -16,6 +16,7 @@ interface Props {
|
|||||||
maxAmount?: number
|
maxAmount?: number
|
||||||
maxAmountLabel: string
|
maxAmountLabel: string
|
||||||
borrowRate?: number
|
borrowRate?: number
|
||||||
|
disableGasWarning?: boolean
|
||||||
onChange: (amount: number) => void
|
onChange: (amount: number) => void
|
||||||
onSelect?: (denom: string) => void
|
onSelect?: (denom: string) => void
|
||||||
}
|
}
|
||||||
@ -62,7 +63,10 @@ export const TokenInput = (props: Props) => {
|
|||||||
10 ** asset.decimals
|
10 ** asset.decimals
|
||||||
|
|
||||||
const showGasWarning =
|
const showGasWarning =
|
||||||
props.maxAmount && props.amount >= props.maxAmount && asset.denom === baseCurrency.denom
|
props.maxAmount &&
|
||||||
|
props.amount >= props.maxAmount &&
|
||||||
|
asset.denom === baseCurrency.denom &&
|
||||||
|
!props.disableGasWarning
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.wrapper}>
|
<div className={styles.wrapper}>
|
||||||
|
@ -19,18 +19,28 @@ interface Props {
|
|||||||
export const RepayInput = (props: Props) => {
|
export const RepayInput = (props: Props) => {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
const convertToBaseCurrency = useStore((s) => s.convertToBaseCurrency)
|
const convertToBaseCurrency = useStore((s) => s.convertToBaseCurrency)
|
||||||
const debtAmount = props.prevPosition.amounts.borrowed
|
const borrowKey =
|
||||||
|
props.position.borrowDenom === props.vault.denoms.primary
|
||||||
|
? 'borrowedPrimary'
|
||||||
|
: 'borrowedSecondary'
|
||||||
|
const supplyKey = borrowKey === 'borrowedPrimary' ? 'primary' : 'secondary'
|
||||||
|
const debtAmount = props.prevPosition.amounts[borrowKey]
|
||||||
const userBalances = useStore((s) => s.userBalances)
|
const userBalances = useStore((s) => s.userBalances)
|
||||||
|
|
||||||
|
const borrowSymbol =
|
||||||
|
props.position.borrowDenom === props.vault.denoms.primary
|
||||||
|
? props.vault.symbols.primary
|
||||||
|
: props.vault.symbols.secondary
|
||||||
|
|
||||||
const walletBalance = Number(
|
const walletBalance = Number(
|
||||||
(findByDenom(userBalances, props.vault.denoms.secondary) as Coin)?.amount || 0,
|
(findByDenom(userBalances, props.vault.denoms.secondary) as Coin)?.amount || 0,
|
||||||
)
|
)
|
||||||
|
|
||||||
const maxRepayAmount = Math.min(walletBalance, debtAmount)
|
const maxRepayAmount = Math.min(walletBalance, debtAmount)
|
||||||
const amount = props.prevPosition.amounts.borrowed - props.position.amounts.borrowed
|
const amount = props.prevPosition.amounts[borrowKey] - props.position.amounts[borrowKey]
|
||||||
const maxValue = Math.max(
|
const maxValue = Math.max(
|
||||||
getLeverageFromValues(props.prevPosition.values),
|
getLeverageFromValues(props.prevPosition.values),
|
||||||
ltvToLeverage(props.vault.ltv.max),
|
ltvToLeverage(props.vault.ltv.contract),
|
||||||
)
|
)
|
||||||
|
|
||||||
const updateValues = (position: Position) => {
|
const updateValues = (position: Position) => {
|
||||||
@ -42,21 +52,29 @@ export const RepayInput = (props: Props) => {
|
|||||||
denom: props.vault.denoms.secondary,
|
denom: props.vault.denoms.secondary,
|
||||||
amount: position.amounts.secondary.toString(),
|
amount: position.amounts.secondary.toString(),
|
||||||
})
|
})
|
||||||
const borrowValue = convertToBaseCurrency({
|
const borrowedPrimaryValue = convertToBaseCurrency({
|
||||||
denom: props.vault.denoms.secondary,
|
denom: props.vault.denoms.primary,
|
||||||
amount: position.amounts.borrowed.toString(),
|
amount: position.amounts.borrowedPrimary.toString(),
|
||||||
})
|
})
|
||||||
|
const borrowedSecondaryValue = convertToBaseCurrency({
|
||||||
|
denom: props.vault.denoms.secondary,
|
||||||
|
amount: position.amounts.borrowedSecondary.toString(),
|
||||||
|
})
|
||||||
|
position.values.primary = primaryValue
|
||||||
position.values.secondary = secondaryValue
|
position.values.secondary = secondaryValue
|
||||||
position.values.borrowed = borrowValue
|
position.values.borrowedPrimary = borrowedPrimaryValue
|
||||||
position.values.total = borrowValue + primaryValue + secondaryValue
|
position.values.borrowedSecondary = borrowedSecondaryValue
|
||||||
|
position.values.total =
|
||||||
|
borrowedPrimaryValue + borrowedSecondaryValue + primaryValue + secondaryValue
|
||||||
position.values.net = primaryValue + secondaryValue
|
position.values.net = primaryValue + secondaryValue
|
||||||
position.currentLeverage = getLeverageFromValues(position.values)
|
position.currentLeverage = getLeverageFromValues(position.values)
|
||||||
|
|
||||||
return position
|
return position
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleChange = (amount: number) => {
|
const handleChange = (amount: number) => {
|
||||||
props.position.amounts.borrowed = props.prevPosition.amounts.borrowed - amount
|
props.position.amounts[borrowKey] = props.prevPosition.amounts[borrowKey] - amount
|
||||||
props.position.amounts.secondary = props.prevPosition.amounts.secondary + amount
|
props.position.amounts[supplyKey] = props.prevPosition.amounts[supplyKey] + amount
|
||||||
props.setPosition({ ...updateValues(props.position) })
|
props.setPosition({ ...updateValues(props.position) })
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -66,21 +84,22 @@ export const RepayInput = (props: Props) => {
|
|||||||
<p className={styles.headline}>{t('fields.repayDebt')}</p>
|
<p className={styles.headline}>{t('fields.repayDebt')}</p>
|
||||||
<TokenInput
|
<TokenInput
|
||||||
amount={amount}
|
amount={amount}
|
||||||
tokens={[props.vault.symbols.secondary]}
|
tokens={[borrowSymbol]}
|
||||||
input={{
|
input={{
|
||||||
denom: props.vault.denoms.secondary,
|
denom: props.position.borrowDenom || props.vault.denoms.secondary,
|
||||||
symbol: props.vault.symbols.secondary,
|
symbol: borrowSymbol,
|
||||||
visible: true,
|
visible: true,
|
||||||
}}
|
}}
|
||||||
maxAmount={maxRepayAmount}
|
maxAmount={maxRepayAmount}
|
||||||
maxAmountLabel={t('global.max')}
|
maxAmountLabel={t('global.max')}
|
||||||
onChange={handleChange}
|
onChange={handleChange}
|
||||||
|
disableGasWarning
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<RepayLeverage
|
<RepayLeverage
|
||||||
value={props.position.currentLeverage}
|
value={props.position.currentLeverage}
|
||||||
maxValue={maxValue}
|
maxValue={maxValue}
|
||||||
leverageMax={ltvToLeverage(props.vault.ltv.max)}
|
leverageMax={ltvToLeverage(props.vault.ltv.contract)}
|
||||||
/>
|
/>
|
||||||
<div>
|
<div>
|
||||||
<strong className='m'>{t('fields.repayingDebtFromWallet')}</strong>
|
<strong className='m'>{t('fields.repayingDebtFromWallet')}</strong>
|
||||||
|
@ -91,6 +91,12 @@ export const AssetTable = ({ data, columns, type, disabled = false }: Props) =>
|
|||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{table.getRowModel().rows.map((row) => {
|
{table.getRowModel().rows.map((row) => {
|
||||||
|
if (
|
||||||
|
(type === 'deposit' && !row.original.depositEnabled) ||
|
||||||
|
(type === 'borrow' && !row.original.borrowEnabled)
|
||||||
|
)
|
||||||
|
return null
|
||||||
|
|
||||||
if (row.depth === 1) {
|
if (row.depth === 1) {
|
||||||
return (
|
return (
|
||||||
<React.Fragment key={`${row.id}_subrow`}>
|
<React.Fragment key={`${row.id}_subrow`}>
|
||||||
|
@ -86,14 +86,16 @@ export const MetricsRow = ({ row, type }: Props) => {
|
|||||||
valueClass='s'
|
valueClass='s'
|
||||||
labelClass='xs faded'
|
labelClass='xs faded'
|
||||||
/>
|
/>
|
||||||
<ValueWithLabel
|
{row.original.borrowEnabled && (
|
||||||
percent={utilizationRatePercent}
|
<ValueWithLabel
|
||||||
label={t('redbank.utilizationRate')}
|
percent={utilizationRatePercent}
|
||||||
orientation='left'
|
label={t('redbank.utilizationRate')}
|
||||||
prefixClass='xxs faded prefix'
|
orientation='left'
|
||||||
valueClass='s'
|
prefixClass='xxs faded prefix'
|
||||||
labelClass='xs faded'
|
valueClass='s'
|
||||||
/>
|
labelClass='xs faded'
|
||||||
|
/>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
|
@ -70,17 +70,15 @@ export const useBorrowColumns = () => {
|
|||||||
header: () => (
|
header: () => (
|
||||||
<TextTooltip text={t('common.rate')} tooltip={t('redbank.tooltips.borrow.rate')} />
|
<TextTooltip text={t('common.rate')} tooltip={t('redbank.tooltips.borrow.rate')} />
|
||||||
),
|
),
|
||||||
cell: (info) => {
|
cell: (info) => (
|
||||||
return (
|
<AnimatedNumber
|
||||||
<AnimatedNumber
|
amount={info.getValue()}
|
||||||
amount={info.getValue()}
|
suffix='%'
|
||||||
suffix='%'
|
abbreviated={false}
|
||||||
abbreviated={false}
|
rounded={false}
|
||||||
rounded={false}
|
className='m'
|
||||||
className='m'
|
/>
|
||||||
/>
|
),
|
||||||
)
|
|
||||||
},
|
|
||||||
}),
|
}),
|
||||||
columnHelper.accessor('marketLiquidity', {
|
columnHelper.accessor('marketLiquidity', {
|
||||||
enableSorting: enableSorting,
|
enableSorting: enableSorting,
|
||||||
@ -100,15 +98,13 @@ export const useBorrowColumns = () => {
|
|||||||
}),
|
}),
|
||||||
columnHelper.display({
|
columnHelper.display({
|
||||||
id: 'actions',
|
id: 'actions',
|
||||||
cell: ({ row }) => {
|
cell: ({ row }) => (
|
||||||
return (
|
<Button
|
||||||
<Button
|
color='quaternary'
|
||||||
color='quaternary'
|
prefix={row.getIsExpanded() ? <SVG.Collapse /> : <SVG.Expand />}
|
||||||
prefix={row.getIsExpanded() ? <SVG.Collapse /> : <SVG.Expand />}
|
variant='round'
|
||||||
variant='round'
|
/>
|
||||||
/>
|
),
|
||||||
)
|
|
||||||
},
|
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
@ -18,6 +18,10 @@
|
|||||||
&.axlUSDC {
|
&.axlUSDC {
|
||||||
background-image: $colorGradientAxlUSDC;
|
background-image: $colorGradientAxlUSDC;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.stATOM {
|
||||||
|
background-image: $colorGradientStATOM;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.logo {
|
.logo {
|
||||||
@ -25,3 +29,8 @@
|
|||||||
margin: auto;
|
margin: auto;
|
||||||
width: rem-calc(32);
|
width: rem-calc(32);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.notBorrowable {
|
||||||
|
width: 100%;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
@ -59,37 +59,45 @@ export const useDepositColumns = () => {
|
|||||||
tooltip={t('redbank.tooltips.deposit.deposited')}
|
tooltip={t('redbank.tooltips.deposit.deposited')}
|
||||||
/>
|
/>
|
||||||
),
|
),
|
||||||
cell: (info) => {
|
cell: (info) => (
|
||||||
return (
|
<CellAmount
|
||||||
<CellAmount
|
amount={Number(info.row.original.depositBalance)}
|
||||||
amount={Number(info.row.original.depositBalance)}
|
decimals={info.row.original.decimals}
|
||||||
decimals={info.row.original.decimals}
|
denom={info.row.original.denom}
|
||||||
denom={info.row.original.denom}
|
noBalanceText={t('common.noDeposit')}
|
||||||
noBalanceText={t('common.noDeposit')}
|
/>
|
||||||
/>
|
),
|
||||||
)
|
|
||||||
},
|
|
||||||
}),
|
}),
|
||||||
columnHelper.accessor('apy', {
|
columnHelper.accessor('apy', {
|
||||||
enableSorting: enableSorting,
|
enableSorting: enableSorting,
|
||||||
header: () => (
|
header: () => (
|
||||||
<TextTooltip text={t('common.apr')} tooltip={t('redbank.tooltips.deposit.apy')} />
|
<TextTooltip text={t('common.apr')} tooltip={t('redbank.tooltips.deposit.apy')} />
|
||||||
),
|
),
|
||||||
cell: (info) => (
|
cell: (info) =>
|
||||||
<TextTooltip
|
info.row.original.borrowEnabled ? (
|
||||||
hideStyling
|
<TextTooltip
|
||||||
text={
|
hideStyling
|
||||||
<AnimatedNumber
|
text={
|
||||||
amount={info.getValue() + Number(info.row.original.incentiveInfo?.apy || 0)}
|
<AnimatedNumber
|
||||||
suffix='%'
|
amount={info.getValue() + Number(info.row.original.incentiveInfo?.apy || 0)}
|
||||||
abbreviated={false}
|
suffix='%'
|
||||||
rounded={false}
|
abbreviated={false}
|
||||||
className='m'
|
rounded={false}
|
||||||
/>
|
className='m'
|
||||||
}
|
/>
|
||||||
tooltip={<Apr data={info.row.original} />}
|
}
|
||||||
/>
|
tooltip={<Apr data={info.row.original} />}
|
||||||
),
|
/>
|
||||||
|
) : (
|
||||||
|
<TextTooltip
|
||||||
|
text='–'
|
||||||
|
hideUnderline
|
||||||
|
className={styles.notBorrowable}
|
||||||
|
tooltip={t('redbank.tooltips.deposit.notBorrowable', {
|
||||||
|
symbol: info.row.original.symbol,
|
||||||
|
})}
|
||||||
|
/>
|
||||||
|
),
|
||||||
}),
|
}),
|
||||||
columnHelper.accessor('depositCap', {
|
columnHelper.accessor('depositCap', {
|
||||||
enableSorting: enableSorting,
|
enableSorting: enableSorting,
|
||||||
@ -108,7 +116,6 @@ export const useDepositColumns = () => {
|
|||||||
'faded',
|
'faded',
|
||||||
percent >= 100 ? 'colorInfoLoss' : '',
|
percent >= 100 ? 'colorInfoLoss' : '',
|
||||||
)
|
)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<p className='number'>
|
<p className='number'>
|
||||||
@ -129,15 +136,13 @@ export const useDepositColumns = () => {
|
|||||||
}),
|
}),
|
||||||
columnHelper.display({
|
columnHelper.display({
|
||||||
id: 'actions',
|
id: 'actions',
|
||||||
cell: ({ row }) => {
|
cell: ({ row }) => (
|
||||||
return (
|
<Button
|
||||||
<Button
|
color='quaternary'
|
||||||
color='quaternary'
|
prefix={row.getIsExpanded() ? <SVG.Collapse /> : <SVG.Expand />}
|
||||||
prefix={row.getIsExpanded() ? <SVG.Collapse /> : <SVG.Expand />}
|
variant='round'
|
||||||
variant='round'
|
/>
|
||||||
/>
|
),
|
||||||
)
|
|
||||||
},
|
|
||||||
}),
|
}),
|
||||||
]
|
]
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
@ -42,6 +42,8 @@ export const RedbankNotConnected = () => {
|
|||||||
depositBalanceBaseCurrency: 0,
|
depositBalanceBaseCurrency: 0,
|
||||||
depositCap: 0,
|
depositCap: 0,
|
||||||
depositLiquidity: 0,
|
depositLiquidity: 0,
|
||||||
|
borrowEnabled: true,
|
||||||
|
depositEnabled: true,
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -14,7 +14,6 @@ export const ASSETS: { [denom: string]: Asset } = {
|
|||||||
denom: 'uosmo',
|
denom: 'uosmo',
|
||||||
color: colors.osmo,
|
color: colors.osmo,
|
||||||
decimals: 6,
|
decimals: 6,
|
||||||
hasOraclePrice: true,
|
|
||||||
logo: osmo,
|
logo: osmo,
|
||||||
poolId: 678,
|
poolId: 678,
|
||||||
},
|
},
|
||||||
@ -25,7 +24,6 @@ export const ASSETS: { [denom: string]: Asset } = {
|
|||||||
color: colors.atom,
|
color: colors.atom,
|
||||||
logo: atom,
|
logo: atom,
|
||||||
decimals: 6,
|
decimals: 6,
|
||||||
hasOraclePrice: true,
|
|
||||||
},
|
},
|
||||||
juno: {
|
juno: {
|
||||||
symbol: 'JUNO',
|
symbol: 'JUNO',
|
||||||
@ -34,7 +32,6 @@ export const ASSETS: { [denom: string]: Asset } = {
|
|||||||
color: colors.juno,
|
color: colors.juno,
|
||||||
logo: juno,
|
logo: juno,
|
||||||
decimals: 6,
|
decimals: 6,
|
||||||
hasOraclePrice: true,
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -46,7 +43,6 @@ const OTHER_ASSETS: { [denom: string]: OtherAsset } = {
|
|||||||
color: colors.mars,
|
color: colors.mars,
|
||||||
logo: mars,
|
logo: mars,
|
||||||
decimals: 6,
|
decimals: 6,
|
||||||
hasOraclePrice: true,
|
|
||||||
poolId: 768,
|
poolId: 768,
|
||||||
},
|
},
|
||||||
axlusdc: {
|
axlusdc: {
|
||||||
@ -57,7 +53,6 @@ const OTHER_ASSETS: { [denom: string]: OtherAsset } = {
|
|||||||
color: colors.axlusdc,
|
color: colors.axlusdc,
|
||||||
logo: axlusdc,
|
logo: axlusdc,
|
||||||
decimals: 6,
|
decimals: 6,
|
||||||
hasOraclePrice: false,
|
|
||||||
poolId: 674,
|
poolId: 674,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -70,6 +65,7 @@ export const NETWORK_CONFIG: NetworkConfig = {
|
|||||||
rpcUrl: URL_RPC ?? 'https://rpc-test.osmosis.zone/',
|
rpcUrl: URL_RPC ?? 'https://rpc-test.osmosis.zone/',
|
||||||
restUrl: URL_REST ?? 'https://lcd-test.osmosis.zone/',
|
restUrl: URL_REST ?? 'https://lcd-test.osmosis.zone/',
|
||||||
apolloAprUrl: 'https://api.apollo.farm/api/vault_infos/v2/osmo-test-4',
|
apolloAprUrl: 'https://api.apollo.farm/api/vault_infos/v2/osmo-test-4',
|
||||||
|
priceApiUrl: 'https://api-osmosis.imperator.co/tokens/v2/OSMO',
|
||||||
contracts: {
|
contracts: {
|
||||||
redBank: 'osmo1t0dl6r27phqetfu0geaxrng0u9zn8qgrdwztapt5xr32adtwptaq6vwg36',
|
redBank: 'osmo1t0dl6r27phqetfu0geaxrng0u9zn8qgrdwztapt5xr32adtwptaq6vwg36',
|
||||||
incentives: 'osmo1zxs8fry3m8j94pqg7h4muunyx86en27cl0xgk76fc839xg2qnn6qtpjs48',
|
incentives: 'osmo1zxs8fry3m8j94pqg7h4muunyx86en27cl0xgk76fc839xg2qnn6qtpjs48',
|
||||||
@ -93,30 +89,6 @@ export const NETWORK_CONFIG: NetworkConfig = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const VAULT_CONFIGS: Vault[] = [
|
export const VAULT_CONFIGS: Vault[] = [
|
||||||
{
|
|
||||||
address: 'osmo1zktjv92f76epswjvyxzzt3yyskpw7k6jsyu0kmq4zzc5fphrjumqlahctp',
|
|
||||||
name: 'OSMO-ATOM LP (1 day)',
|
|
||||||
denoms: {
|
|
||||||
primary: 'uosmo',
|
|
||||||
secondary: 'ibc/27394FB092D2ECCD56123C74F36E4C1F926001CEADA9CA97EA622B25F41E5EB2',
|
|
||||||
lpToken: 'gamm/pool/1',
|
|
||||||
},
|
|
||||||
symbols: {
|
|
||||||
primary: 'OSMO',
|
|
||||||
secondary: 'ATOM',
|
|
||||||
},
|
|
||||||
color: '#DD5B65',
|
|
||||||
lockup: 86400,
|
|
||||||
provider: 'Apollo vault',
|
|
||||||
description:
|
|
||||||
'Up to 2.67× leveraged yield farming with auto compounding of the OSMO-ATOM LP tokens.',
|
|
||||||
ltv: {
|
|
||||||
max: 0.625,
|
|
||||||
contract: 0.63,
|
|
||||||
liq: 0.65,
|
|
||||||
},
|
|
||||||
apy: 0,
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
address: 'osmo1tp2m6g39h8mvhnu3plqjyen5s63023gj8w873l8wvly0cd77l6hsaa73wt',
|
address: 'osmo1tp2m6g39h8mvhnu3plqjyen5s63023gj8w873l8wvly0cd77l6hsaa73wt',
|
||||||
name: 'OSMO-ATOM LP (14 day)',
|
name: 'OSMO-ATOM LP (14 day)',
|
||||||
@ -133,11 +105,11 @@ export const VAULT_CONFIGS: Vault[] = [
|
|||||||
lockup: 86400 * 14,
|
lockup: 86400 * 14,
|
||||||
provider: 'Apollo vault',
|
provider: 'Apollo vault',
|
||||||
description:
|
description:
|
||||||
'Up to 2.67× leveraged yield farming with auto compounding of the OSMO-ATOM LP tokens.',
|
'Up to 1.43× leveraged yield farming with auto compounding of the OSMO-ATOM LP tokens.',
|
||||||
ltv: {
|
ltv: {
|
||||||
max: 0.625,
|
max: 0.295,
|
||||||
contract: 0.63,
|
contract: 0.3,
|
||||||
liq: 0.65,
|
liq: 0.4,
|
||||||
},
|
},
|
||||||
apy: 0,
|
apy: 0,
|
||||||
},
|
},
|
||||||
@ -157,11 +129,11 @@ export const VAULT_CONFIGS: Vault[] = [
|
|||||||
lockup: 86400 * 1,
|
lockup: 86400 * 1,
|
||||||
provider: 'Apollo vault',
|
provider: 'Apollo vault',
|
||||||
description:
|
description:
|
||||||
'Up to 1.67× leveraged yield farming with auto compounding of the OSMO-JUNO LP tokens.',
|
'Up to 1.43× leveraged yield farming with auto compounding of the OSMO-JUNO LP tokens.',
|
||||||
ltv: {
|
ltv: {
|
||||||
max: 0.4,
|
max: 0.295,
|
||||||
contract: 0.4115,
|
contract: 0.3,
|
||||||
liq: 0.441,
|
liq: 0.4,
|
||||||
},
|
},
|
||||||
apy: 0,
|
apy: 0,
|
||||||
},
|
},
|
||||||
@ -181,11 +153,11 @@ export const VAULT_CONFIGS: Vault[] = [
|
|||||||
lockup: 86400 * 14,
|
lockup: 86400 * 14,
|
||||||
provider: 'Apollo vault',
|
provider: 'Apollo vault',
|
||||||
description:
|
description:
|
||||||
'Up to 1.67× leveraged yield farming with auto compounding of the OSMO-JUNO LP tokens.',
|
'Up to 1.43× leveraged yield farming with auto compounding of the OSMO-JUNO LP tokens.',
|
||||||
ltv: {
|
ltv: {
|
||||||
max: 0.4,
|
max: 0.295,
|
||||||
contract: 4.115,
|
contract: 0.3,
|
||||||
liq: 0.441,
|
liq: 0.4,
|
||||||
},
|
},
|
||||||
apy: 0,
|
apy: 0,
|
||||||
},
|
},
|
||||||
|
@ -4,6 +4,7 @@ import atom from 'images/atom.svg'
|
|||||||
import axlusdc from 'images/axlusdc.svg'
|
import axlusdc from 'images/axlusdc.svg'
|
||||||
import mars from 'images/mars.svg'
|
import mars from 'images/mars.svg'
|
||||||
import osmo from 'images/osmo.svg'
|
import osmo from 'images/osmo.svg'
|
||||||
|
import statom from 'images/statom.svg'
|
||||||
import colors from 'styles/_assets.module.scss'
|
import colors from 'styles/_assets.module.scss'
|
||||||
|
|
||||||
export const ASSETS: { [denom: string]: Asset } = {
|
export const ASSETS: { [denom: string]: Asset } = {
|
||||||
@ -13,17 +14,15 @@ export const ASSETS: { [denom: string]: Asset } = {
|
|||||||
denom: 'uosmo',
|
denom: 'uosmo',
|
||||||
color: colors.osmo,
|
color: colors.osmo,
|
||||||
decimals: 6,
|
decimals: 6,
|
||||||
hasOraclePrice: true,
|
|
||||||
logo: osmo,
|
logo: osmo,
|
||||||
},
|
},
|
||||||
axlusdc: {
|
axlusdc: {
|
||||||
symbol: 'axlUSDC',
|
symbol: 'axlUSDC',
|
||||||
name: 'Axelar USDC',
|
name: 'Axelar USDC',
|
||||||
denom: 'ibc/D189335C6E4A68B513C10AB227BF1C1D38C746766278BA3EEB4FB14124F1D858',
|
denom: 'ibc/D189335C6E4A68B513C10AB227BF1C1D38C746766278BA3EEB4FB14124F1D858',
|
||||||
color: colors.axlUSDC,
|
color: colors.axlusdc,
|
||||||
logo: axlusdc,
|
logo: axlusdc,
|
||||||
decimals: 6,
|
decimals: 6,
|
||||||
hasOraclePrice: true,
|
|
||||||
poolId: 678,
|
poolId: 678,
|
||||||
},
|
},
|
||||||
atom: {
|
atom: {
|
||||||
@ -33,7 +32,16 @@ export const ASSETS: { [denom: string]: Asset } = {
|
|||||||
color: colors.atom,
|
color: colors.atom,
|
||||||
logo: atom,
|
logo: atom,
|
||||||
decimals: 6,
|
decimals: 6,
|
||||||
hasOraclePrice: true,
|
},
|
||||||
|
statom: {
|
||||||
|
symbol: 'stATOM',
|
||||||
|
name: 'Stride Atom',
|
||||||
|
denom: 'ibc/C140AFD542AE77BD7DCC83F13FDD8C5E5BB8C4929785E6EC2F4C636F98F17901',
|
||||||
|
color: colors.statom,
|
||||||
|
logo: statom,
|
||||||
|
decimals: 6,
|
||||||
|
poolId: 803,
|
||||||
|
poolBase: 'ibc/27394FB092D2ECCD56123C74F36E4C1F926001CEADA9CA97EA622B25F41E5EB2',
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -45,7 +53,6 @@ const OTHER_ASSETS: { [denom: string]: OtherAsset } = {
|
|||||||
color: colors.mars,
|
color: colors.mars,
|
||||||
logo: mars,
|
logo: mars,
|
||||||
decimals: 6,
|
decimals: 6,
|
||||||
hasOraclePrice: true,
|
|
||||||
poolId: 907,
|
poolId: 907,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -57,6 +64,7 @@ export const NETWORK_CONFIG: NetworkConfig = {
|
|||||||
rpcUrl: URL_RPC ?? 'https://rpc-osmosis.blockapsis.com/',
|
rpcUrl: URL_RPC ?? 'https://rpc-osmosis.blockapsis.com/',
|
||||||
restUrl: URL_REST ?? 'https://lcd-osmosis.blockapsis.com/',
|
restUrl: URL_REST ?? 'https://lcd-osmosis.blockapsis.com/',
|
||||||
apolloAprUrl: 'https://api.apollo.farm/api/vault_infos/v2/osmosis-1',
|
apolloAprUrl: 'https://api.apollo.farm/api/vault_infos/v2/osmosis-1',
|
||||||
|
priceApiUrl: 'https://api-osmosis.imperator.co/tokens/v2/OSMO',
|
||||||
contracts: {
|
contracts: {
|
||||||
redBank: 'osmo1c3ljch9dfw5kf52nfwpxd2zmj2ese7agnx0p9tenkrryasrle5sqf3ftpg',
|
redBank: 'osmo1c3ljch9dfw5kf52nfwpxd2zmj2ese7agnx0p9tenkrryasrle5sqf3ftpg',
|
||||||
incentives: 'osmo1nkahswfr8shg8rlxqwup0vgahp0dk4x8w6tkv3rra8rratnut36sk22vrm',
|
incentives: 'osmo1nkahswfr8shg8rlxqwup0vgahp0dk4x8w6tkv3rra8rratnut36sk22vrm',
|
||||||
@ -66,7 +74,7 @@ export const NETWORK_CONFIG: NetworkConfig = {
|
|||||||
},
|
},
|
||||||
assets: {
|
assets: {
|
||||||
base: ASSETS.osmo,
|
base: ASSETS.osmo,
|
||||||
whitelist: [ASSETS.osmo, ASSETS.atom, ASSETS.axlusdc],
|
whitelist: [ASSETS.osmo, ASSETS.atom, ASSETS.axlusdc, ASSETS.statom],
|
||||||
other: [OTHER_ASSETS.mars],
|
other: [OTHER_ASSETS.mars],
|
||||||
},
|
},
|
||||||
displayCurrency: {
|
displayCurrency: {
|
||||||
@ -129,7 +137,7 @@ export const VAULT_CONFIGS: Vault[] = [
|
|||||||
description:
|
description:
|
||||||
'Up to 2.78× leveraged yield farming with auto compounding of the OSMO-axlUSDC LP tokens.',
|
'Up to 2.78× leveraged yield farming with auto compounding of the OSMO-axlUSDC LP tokens.',
|
||||||
ltv: {
|
ltv: {
|
||||||
max: 0.64,
|
max: 0.645,
|
||||||
contract: 0.65,
|
contract: 0.65,
|
||||||
liq: 0.66,
|
liq: 0.66,
|
||||||
},
|
},
|
||||||
|
@ -5,6 +5,7 @@ export const FORUM_URL = 'https://forum.marsprotocol.io/'
|
|||||||
export const MARS_SYMBOL = 'MARS'
|
export const MARS_SYMBOL = 'MARS'
|
||||||
export const MARS_DECIMALS = 6
|
export const MARS_DECIMALS = 6
|
||||||
export const USDC_SYMBOL = 'axlUSDC'
|
export const USDC_SYMBOL = 'axlUSDC'
|
||||||
|
export const STATOM_SYMBOL = 'stATOM'
|
||||||
|
|
||||||
/* borrow capacity */
|
/* borrow capacity */
|
||||||
export const DEFAULT_SLIPPAGE = 0.01
|
export const DEFAULT_SLIPPAGE = 0.01
|
||||||
|
@ -4,7 +4,8 @@ export const DEFAULT_POSITION: Position = {
|
|||||||
amounts: {
|
amounts: {
|
||||||
primary: 0,
|
primary: 0,
|
||||||
secondary: 0,
|
secondary: 0,
|
||||||
borrowed: 0,
|
borrowedPrimary: 0,
|
||||||
|
borrowedSecondary: 0,
|
||||||
lp: {
|
lp: {
|
||||||
amount: '0',
|
amount: '0',
|
||||||
primary: 0,
|
primary: 0,
|
||||||
@ -15,7 +16,8 @@ export const DEFAULT_POSITION: Position = {
|
|||||||
values: {
|
values: {
|
||||||
primary: 0,
|
primary: 0,
|
||||||
secondary: 0,
|
secondary: 0,
|
||||||
borrowed: 0,
|
borrowedPrimary: 0,
|
||||||
|
borrowedSecondary: 0,
|
||||||
total: 0,
|
total: 0,
|
||||||
net: 0,
|
net: 0,
|
||||||
},
|
},
|
||||||
@ -26,4 +28,5 @@ export const DEFAULT_POSITION: Position = {
|
|||||||
},
|
},
|
||||||
ltv: 0.5,
|
ltv: 0.5,
|
||||||
currentLeverage: 1,
|
currentLeverage: 1,
|
||||||
|
borrowDenom: null,
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,10 @@ export const getClosePositionActions = (
|
|||||||
const swapMessage: Action[] = []
|
const swapMessage: Action[] = []
|
||||||
|
|
||||||
// Increase the borrow amount by factor to account for an increase of borrow over time
|
// Increase the borrow amount by factor to account for an increase of borrow over time
|
||||||
const borrowAmount = Math.ceil(vault.position.amounts.borrowed * 1.001)
|
const borrowAmount = Math.ceil(
|
||||||
|
Math.max(vault.position.amounts.borrowedPrimary, vault.position.amounts.borrowedSecondary) *
|
||||||
|
1.001,
|
||||||
|
)
|
||||||
const secondaryAmount = vault.position.amounts.lp.secondary
|
const secondaryAmount = vault.position.amounts.lp.secondary
|
||||||
|
|
||||||
if (secondaryAmount < borrowAmount) {
|
if (secondaryAmount < borrowAmount) {
|
||||||
@ -46,11 +49,11 @@ export const getClosePositionActions = (
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
...swapMessage,
|
...swapMessage,
|
||||||
...(vault.position.amounts.borrowed
|
...(Math.max(vault.position.amounts.borrowedPrimary, vault.position.amounts.borrowedSecondary)
|
||||||
? [
|
? [
|
||||||
{
|
{
|
||||||
repay: {
|
repay: {
|
||||||
denom: vault.denoms.secondary,
|
denom: vault.position.borrowDenom || vault.denoms.secondary,
|
||||||
amount: 'account_balance' as ActionAmount,
|
amount: 'account_balance' as ActionAmount,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
export const getCoinFromPosition = (
|
export const getCoinFromPosition = (
|
||||||
position: Position,
|
position: Position,
|
||||||
vault: Vault,
|
vault: Vault,
|
||||||
type: 'primary' | 'secondary' | 'borrowed',
|
type: 'primary' | 'secondary' | 'borrowedPrimary' | 'borrowedSecondary',
|
||||||
) => {
|
) => {
|
||||||
const denom = type === 'primary' ? vault.denoms.primary : vault.denoms.secondary
|
const denom = type === 'primary' ? vault.denoms.primary : vault.denoms.secondary
|
||||||
return {
|
return {
|
||||||
|
@ -3,7 +3,17 @@ import BigNumber from 'bignumber.js'
|
|||||||
export const getLeverageFromValues = (values: {
|
export const getLeverageFromValues = (values: {
|
||||||
primary: number
|
primary: number
|
||||||
secondary: number
|
secondary: number
|
||||||
borrowed: number
|
borrowedPrimary: number
|
||||||
|
borrowedSecondary: number
|
||||||
net: number
|
net: number
|
||||||
total: number
|
total: number
|
||||||
}) => Number(new BigNumber(values.borrowed).div(values.net || 1).plus(1))
|
}) =>
|
||||||
|
Number(
|
||||||
|
new BigNumber(
|
||||||
|
values.borrowedPrimary > values.borrowedSecondary
|
||||||
|
? values.borrowedPrimary
|
||||||
|
: values.borrowedSecondary,
|
||||||
|
)
|
||||||
|
.div(values.net || 1)
|
||||||
|
.plus(1),
|
||||||
|
)
|
||||||
|
@ -1,3 +1,8 @@
|
|||||||
export const getLiqBorrowValue = (vault: Vault, maxBorrowValue: number) => {
|
import BigNumber from 'bignumber.js'
|
||||||
return ((vault.ltv.liq - vault.ltv.max) / vault.ltv.max + 1) * maxBorrowValue
|
import { ltvToLeverage } from 'libs/parse'
|
||||||
|
|
||||||
|
export const getLiqBorrowValue = (vault: Vault, netValue: number) => {
|
||||||
|
const liqLev = ltvToLeverage(vault.ltv.liq)
|
||||||
|
|
||||||
|
return new BigNumber(netValue).times(liqLev - 1).toNumber()
|
||||||
}
|
}
|
||||||
|
@ -9,5 +9,5 @@ export const getMaxAllowedLeverage = (
|
|||||||
new BigNumber(borrowValue)
|
new BigNumber(borrowValue)
|
||||||
.div(new BigNumber(primaryValue).plus(secondaryValue))
|
.div(new BigNumber(primaryValue).plus(secondaryValue))
|
||||||
.plus(1)
|
.plus(1)
|
||||||
.toPrecision(2),
|
.toPrecision(4),
|
||||||
)
|
)
|
||||||
|
@ -2,5 +2,8 @@ import BigNumber from 'bignumber.js'
|
|||||||
import { ltvToLeverage } from 'libs/parse'
|
import { ltvToLeverage } from 'libs/parse'
|
||||||
|
|
||||||
export const getMaxBorrowValue = (vault: Vault, position: Position): number => {
|
export const getMaxBorrowValue = (vault: Vault, position: Position): number => {
|
||||||
return new BigNumber(ltvToLeverage(vault.ltv.max)).minus(1).times(position.values.net).toNumber()
|
return new BigNumber(ltvToLeverage(vault.ltv.contract))
|
||||||
|
.minus(1)
|
||||||
|
.times(position.values.net)
|
||||||
|
.toNumber()
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@ import { vault } from 'mocks/vault'
|
|||||||
|
|
||||||
describe('getMaxBorrowValue', () => {
|
describe('getMaxBorrowValue', () => {
|
||||||
test('should return 0 when netValue = 0', () => {
|
test('should return 0 when netValue = 0', () => {
|
||||||
vault.ltv.max = 0.5
|
vault.ltv.contract = 0.5
|
||||||
position.values.net = 0
|
position.values.net = 0
|
||||||
|
|
||||||
const maxBorrowValue = getMaxBorrowValue(vault, position)
|
const maxBorrowValue = getMaxBorrowValue(vault, position)
|
||||||
@ -17,7 +17,7 @@ describe('getMaxBorrowValue', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
test('should return 0 when maxLTV = 0', () => {
|
test('should return 0 when maxLTV = 0', () => {
|
||||||
vault.ltv.max = 0
|
vault.ltv.contract = 0
|
||||||
position.values.net = 100
|
position.values.net = 100
|
||||||
|
|
||||||
const maxBorrowValue = getMaxBorrowValue(vault, position)
|
const maxBorrowValue = getMaxBorrowValue(vault, position)
|
||||||
@ -25,7 +25,7 @@ describe('getMaxBorrowValue', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
test('should return 1x netValue when maxLTV = 0.5', () => {
|
test('should return 1x netValue when maxLTV = 0.5', () => {
|
||||||
vault.ltv.max = 0.5
|
vault.ltv.contract = 0.5
|
||||||
position.values.net = 100
|
position.values.net = 100
|
||||||
|
|
||||||
const maxBorrowValue = getMaxBorrowValue(vault, position)
|
const maxBorrowValue = getMaxBorrowValue(vault, position)
|
||||||
@ -33,7 +33,7 @@ describe('getMaxBorrowValue', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
test('should return 4.5x netValue when maxLTV = ', () => {
|
test('should return 4.5x netValue when maxLTV = ', () => {
|
||||||
vault.ltv.max = 0.75
|
vault.ltv.contract = 0.75
|
||||||
position.values.net = 100
|
position.values.net = 100
|
||||||
|
|
||||||
const maxBorrowValue = getMaxBorrowValue(vault, position)
|
const maxBorrowValue = getMaxBorrowValue(vault, position)
|
||||||
@ -62,7 +62,8 @@ describe('getLeverageFromValues', () => {
|
|||||||
const values = {
|
const values = {
|
||||||
primary: 0,
|
primary: 0,
|
||||||
secondary: 0,
|
secondary: 0,
|
||||||
borrowed: 0,
|
borrowedPrimary: 0,
|
||||||
|
borrowedSecondary: 0,
|
||||||
net: 0,
|
net: 0,
|
||||||
total: 0,
|
total: 0,
|
||||||
}
|
}
|
||||||
@ -73,14 +74,14 @@ describe('getLeverageFromValues', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
test('should return 1.5 when borrowed = 50 and net = 100', () => {
|
test('should return 1.5 when borrowed = 50 and net = 100', () => {
|
||||||
values.borrowed = 50
|
values.borrowedPrimary = 50
|
||||||
values.net = 100
|
values.net = 100
|
||||||
const leverage = getLeverageFromValues(values)
|
const leverage = getLeverageFromValues(values)
|
||||||
expect(leverage).toBe(1.5)
|
expect(leverage).toBe(1.5)
|
||||||
})
|
})
|
||||||
|
|
||||||
test('should return 2.25 when borrowed = 125 and net = 100', () => {
|
test('should return 2.25 when borrowed = 125 and net = 100', () => {
|
||||||
values.borrowed = 125
|
values.borrowedPrimary = 125
|
||||||
values.net = 100
|
values.net = 100
|
||||||
const leverage = getLeverageFromValues(values)
|
const leverage = getLeverageFromValues(values)
|
||||||
expect(leverage).toBe(2.25)
|
expect(leverage).toBe(2.25)
|
||||||
|
@ -3,9 +3,10 @@ import { Coin } from '@cosmjs/proto-signing'
|
|||||||
export const updateExchangeRate = (coin: Coin, exchangeRates: Coin[]) => {
|
export const updateExchangeRate = (coin: Coin, exchangeRates: Coin[]) => {
|
||||||
const assetIndex = exchangeRates.findIndex((xAsset) => xAsset.denom === coin.denom)
|
const assetIndex = exchangeRates.findIndex((xAsset) => xAsset.denom === coin.denom)
|
||||||
if (assetIndex > -1) {
|
if (assetIndex > -1) {
|
||||||
exchangeRates[assetIndex] = coin
|
if (coin.amount !== '0.00') exchangeRates[assetIndex] = coin
|
||||||
} else {
|
} else {
|
||||||
exchangeRates.push(coin)
|
exchangeRates.push(coin)
|
||||||
}
|
}
|
||||||
|
|
||||||
return exchangeRates
|
return exchangeRates
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,7 @@ export { useRepayPosition } from './useRepayPosition'
|
|||||||
export { useRequestUnlockPosition } from './useRequestUnlockPosition'
|
export { useRequestUnlockPosition } from './useRequestUnlockPosition'
|
||||||
export { useSpotPrice } from './useSpotPrice'
|
export { useSpotPrice } from './useSpotPrice'
|
||||||
export { useUnlockMessages } from './useUnlockMessages'
|
export { useUnlockMessages } from './useUnlockMessages'
|
||||||
|
export { useUsdPrice } from './useUsdPrice'
|
||||||
export { useUserBalance } from './useUserBalance'
|
export { useUserBalance } from './useUserBalance'
|
||||||
export { useUserDebt } from './useUserDebt'
|
export { useUserDebt } from './useUserDebt'
|
||||||
export { useUserDeposit } from './useUserDeposit'
|
export { useUserDeposit } from './useUserDeposit'
|
||||||
|
@ -15,6 +15,8 @@ export interface DepositAndDebtData {
|
|||||||
JUNODebt: string
|
JUNODebt: string
|
||||||
axlUSDCDeposits: string
|
axlUSDCDeposits: string
|
||||||
axlUSDCDebt: string
|
axlUSDCDebt: string
|
||||||
|
stATOMDeposits: string
|
||||||
|
stATOMDebt: string
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,15 +27,20 @@ export const useEditPosition = (props: Props) => {
|
|||||||
props.position.amounts.primary - (props.prevPosition?.amounts.primary || 0)
|
props.position.amounts.primary - (props.prevPosition?.amounts.primary || 0)
|
||||||
const secondaryAmount =
|
const secondaryAmount =
|
||||||
props.position.amounts.secondary - (props.prevPosition?.amounts.secondary || 0)
|
props.position.amounts.secondary - (props.prevPosition?.amounts.secondary || 0)
|
||||||
const borrowedAmount =
|
const borrowedPrimaryAmount =
|
||||||
props.position.amounts.borrowed - (props.prevPosition?.amounts.borrowed || 0)
|
props.position.amounts.borrowedPrimary - (props.prevPosition?.amounts.borrowedPrimary || 0)
|
||||||
|
|
||||||
|
const borrowedSecondaryAmount =
|
||||||
|
props.position.amounts.borrowedSecondary -
|
||||||
|
(props.prevPosition?.amounts.borrowedSecondary || 0)
|
||||||
|
|
||||||
const editPosition = {
|
const editPosition = {
|
||||||
...props.position,
|
...props.position,
|
||||||
amounts: {
|
amounts: {
|
||||||
primary: primaryAmount,
|
primary: primaryAmount,
|
||||||
secondary: secondaryAmount,
|
secondary: secondaryAmount,
|
||||||
borrowed: borrowedAmount,
|
borrowedPrimary: borrowedPrimaryAmount,
|
||||||
|
borrowedSecondary: borrowedSecondaryAmount,
|
||||||
lp: {
|
lp: {
|
||||||
amount: '0',
|
amount: '0',
|
||||||
primary: 0,
|
primary: 0,
|
||||||
@ -47,15 +52,15 @@ export const useEditPosition = (props: Props) => {
|
|||||||
|
|
||||||
const primaryBaseAmount = convertToBaseCurrency({
|
const primaryBaseAmount = convertToBaseCurrency({
|
||||||
denom: props.vault.denoms.primary,
|
denom: props.vault.denoms.primary,
|
||||||
amount: primaryAmount.toString(),
|
amount: (primaryAmount + borrowedPrimaryAmount).toString(),
|
||||||
})
|
})
|
||||||
const secondaryBaseAmount = convertToBaseCurrency({
|
const secondaryBaseAmount = convertToBaseCurrency({
|
||||||
denom: props.vault.denoms.secondary,
|
denom: props.vault.denoms.secondary,
|
||||||
amount: (secondaryAmount + borrowedAmount).toString(),
|
amount: (secondaryAmount + borrowedSecondaryAmount).toString(),
|
||||||
})
|
})
|
||||||
|
|
||||||
let primaryAfterSwap = primaryAmount
|
let primaryAfterSwap = primaryAmount + borrowedPrimaryAmount
|
||||||
let secondaryAfterSwap = secondaryAmount + borrowedAmount
|
let secondaryAfterSwap = secondaryAmount + borrowedSecondaryAmount
|
||||||
|
|
||||||
// If difference is larger than threshold, initiate a swap
|
// If difference is larger than threshold, initiate a swap
|
||||||
const difference = primaryBaseAmount - secondaryBaseAmount
|
const difference = primaryBaseAmount - secondaryBaseAmount
|
||||||
@ -105,7 +110,8 @@ export const useEditPosition = (props: Props) => {
|
|||||||
}, [
|
}, [
|
||||||
props.position.amounts.primary,
|
props.position.amounts.primary,
|
||||||
props.position.amounts.secondary,
|
props.position.amounts.secondary,
|
||||||
props.position.amounts.borrowed,
|
props.position.amounts.borrowedPrimary,
|
||||||
|
props.position.amounts.borrowedSecondary,
|
||||||
])
|
])
|
||||||
|
|
||||||
const { data: minLpToReceive } = useProvideLiquidity({
|
const { data: minLpToReceive } = useProvideLiquidity({
|
||||||
@ -128,9 +134,12 @@ export const useEditPosition = (props: Props) => {
|
|||||||
amount: editPosition.amounts.secondary.toString(),
|
amount: editPosition.amounts.secondary.toString(),
|
||||||
}
|
}
|
||||||
|
|
||||||
const borrow = editPosition.amounts.borrowed && {
|
const borrow = editPosition.borrowDenom && {
|
||||||
denom: props.vault.denoms.secondary,
|
denom: editPosition.borrowDenom,
|
||||||
amount: editPosition.amounts.borrowed.toString(),
|
amount: Math.max(
|
||||||
|
editPosition.amounts.borrowedPrimary,
|
||||||
|
editPosition.amounts.borrowedSecondary,
|
||||||
|
).toString(),
|
||||||
}
|
}
|
||||||
|
|
||||||
if (primary) coins.supply.push(primary)
|
if (primary) coins.supply.push(primary)
|
||||||
@ -139,12 +148,12 @@ export const useEditPosition = (props: Props) => {
|
|||||||
|
|
||||||
const primaryBaseAmount = convertToBaseCurrency({
|
const primaryBaseAmount = convertToBaseCurrency({
|
||||||
denom: props.vault.denoms.primary,
|
denom: props.vault.denoms.primary,
|
||||||
amount: String(editPosition.amounts.primary),
|
amount: String(editPosition.amounts.primary + editPosition.amounts.borrowedPrimary),
|
||||||
})
|
})
|
||||||
|
|
||||||
const secondaryBaseAmount = convertToBaseCurrency({
|
const secondaryBaseAmount = convertToBaseCurrency({
|
||||||
denom: props.vault.denoms.secondary,
|
denom: props.vault.denoms.secondary,
|
||||||
amount: String(editPosition.amounts.secondary + editPosition.amounts.borrowed),
|
amount: String(editPosition.amounts.secondary + editPosition.amounts.borrowedSecondary),
|
||||||
})
|
})
|
||||||
|
|
||||||
const swapMessage: Action[] = []
|
const swapMessage: Action[] = []
|
||||||
|
@ -14,16 +14,29 @@ export const useRepayPosition = (props: Props) => {
|
|||||||
const [amount, setAmount] = useState(0)
|
const [amount, setAmount] = useState(0)
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setAmount(props.prevPosition.amounts.borrowed - props.repayPosition.amounts.borrowed)
|
const borrowKey =
|
||||||
}, [props.repayPosition.amounts.borrowed, props.prevPosition.amounts.borrowed])
|
props.prevPosition.borrowDenom === props.activeVault.denoms.primary
|
||||||
|
? 'borrowedPrimary'
|
||||||
|
: 'borrowedSecondary'
|
||||||
|
setAmount(props.prevPosition.amounts[borrowKey] - props.repayPosition.amounts[borrowKey])
|
||||||
|
}, [
|
||||||
|
props.repayPosition.amounts.borrowedPrimary,
|
||||||
|
props.repayPosition.amounts.borrowedSecondary,
|
||||||
|
props.prevPosition.amounts.borrowedPrimary,
|
||||||
|
props.prevPosition.amounts.borrowedSecondary,
|
||||||
|
props.activeVault.denoms.primary,
|
||||||
|
props.prevPosition.amounts,
|
||||||
|
props.prevPosition.borrowDenom,
|
||||||
|
props.repayPosition.amounts,
|
||||||
|
])
|
||||||
|
|
||||||
const [actions, funds] = useMemo(() => {
|
const [actions, funds] = useMemo(() => {
|
||||||
if (!amount) return [[], []]
|
if (!amount) return [[], []]
|
||||||
return getRepayActionsAndFunds({
|
return getRepayActionsAndFunds({
|
||||||
denom: props.activeVault.denoms.secondary,
|
denom: props.activeVault.position.borrowDenom || props.activeVault.denoms.secondary,
|
||||||
amount: amount.toString(),
|
amount: amount.toString(),
|
||||||
})
|
})
|
||||||
}, [amount, props.activeVault.denoms.secondary])
|
}, [amount, props.activeVault.denoms.secondary, props.activeVault.position.borrowDenom])
|
||||||
|
|
||||||
const { data: fee } = useEstimateFarmFee({
|
const { data: fee } = useEstimateFarmFee({
|
||||||
accountId: props.prevPosition.accountId,
|
accountId: props.prevPosition.accountId,
|
||||||
|
@ -9,15 +9,16 @@ const poolsEndpoint = 'osmosis/gamm/v1beta1/pools/'
|
|||||||
|
|
||||||
export const useSpotPrice = (symbol: string) => {
|
export const useSpotPrice = (symbol: string) => {
|
||||||
const networkConfig = useStore((s) => s.networkConfig)
|
const networkConfig = useStore((s) => s.networkConfig)
|
||||||
|
const displayCurrency = networkConfig?.displayCurrency
|
||||||
const lcd = useStore((s) => s.chainInfo?.rest)
|
const lcd = useStore((s) => s.chainInfo?.rest)
|
||||||
const exchangeRates = useStore((s) => s.exchangeRates)
|
const exchangeRates = useStore((s) => s.exchangeRates)
|
||||||
|
|
||||||
const asset = useAsset({ symbol })
|
const asset = useAsset({ symbol })
|
||||||
|
const poolBase = asset?.poolBase
|
||||||
const displayCurrency = networkConfig?.displayCurrency
|
? exchangeRates?.find((ratesAsset) => ratesAsset.denom === asset.poolBase)
|
||||||
|
: true
|
||||||
|
|
||||||
useQuery<PoolResponse>(
|
useQuery<PoolResponse>(
|
||||||
[QUERY_KEYS.MARS_PRICE, asset?.poolId],
|
[QUERY_KEYS.SPOT_PRICE, asset?.poolId],
|
||||||
async () => {
|
async () => {
|
||||||
return fetch(`${lcd}${poolsEndpoint}${asset?.poolId}`).then(async (response) => {
|
return fetch(`${lcd}${poolsEndpoint}${asset?.poolId}`).then(async (response) => {
|
||||||
const data = await response.json()
|
const data = await response.json()
|
||||||
@ -25,7 +26,7 @@ export const useSpotPrice = (symbol: string) => {
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
enabled: !!lcd && !!asset && !!asset.poolId,
|
enabled: !!lcd && !!asset && !!asset.poolId && !!poolBase,
|
||||||
staleTime: 30000,
|
staleTime: 30000,
|
||||||
refetchInterval: 30000,
|
refetchInterval: 30000,
|
||||||
onSuccess: (data) => {
|
onSuccess: (data) => {
|
||||||
@ -44,11 +45,22 @@ export const useSpotPrice = (symbol: string) => {
|
|||||||
.div(targetAssetAmount)
|
.div(targetAssetAmount)
|
||||||
.multipliedBy(otherAssetWeight.div(targetAssetWeight))
|
.multipliedBy(otherAssetWeight.div(targetAssetWeight))
|
||||||
|
|
||||||
if (displayCurrency.denom === asset.denom) {
|
const hasDisplayCurrency = exchangeRates?.find(
|
||||||
|
(ratesAsset) => ratesAsset.denom === displayCurrency.denom,
|
||||||
|
)
|
||||||
|
|
||||||
|
if (displayCurrency.denom === asset.denom && !hasDisplayCurrency) {
|
||||||
useStore.setState({ baseToDisplayCurrencyRatio: 1 / rate.toNumber() })
|
useStore.setState({ baseToDisplayCurrencyRatio: 1 / rate.toNumber() })
|
||||||
} else {
|
} else {
|
||||||
const coin = { denom: asset.denom, amount: rate.toString() }
|
const coin = { denom: asset.denom, amount: rate.toString() }
|
||||||
useStore.setState({ exchangeRates: updateExchangeRate(coin, exchangeRates || []) })
|
|
||||||
|
if (typeof poolBase === 'object') {
|
||||||
|
const baseRate = Number(rate.toString()) * Number(poolBase.amount)
|
||||||
|
coin.amount = baseRate.toString()
|
||||||
|
useStore.setState({ exchangeRates: updateExchangeRate(coin, exchangeRates || []) })
|
||||||
|
} else {
|
||||||
|
useStore.setState({ exchangeRates: updateExchangeRate(coin, exchangeRates || []) })
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
46
src/hooks/queries/useUsdPrice.tsx
Normal file
46
src/hooks/queries/useUsdPrice.tsx
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
import { useQuery } from '@tanstack/react-query'
|
||||||
|
import { updateExchangeRate } from 'functions'
|
||||||
|
import useStore from 'store'
|
||||||
|
import { QUERY_KEYS } from 'types/enums/queryKeys'
|
||||||
|
|
||||||
|
interface CoinPriceData {
|
||||||
|
price: number
|
||||||
|
denom: string
|
||||||
|
symbol: string
|
||||||
|
liquidity: number
|
||||||
|
liquidity_24h_change: number
|
||||||
|
volume_24h: number
|
||||||
|
volume_24h_change: number
|
||||||
|
name: string
|
||||||
|
price_24h_change: number
|
||||||
|
exponent: number
|
||||||
|
display: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export const useUsdPrice = () => {
|
||||||
|
const apiUrl = useStore((s) => s.networkConfig?.priceApiUrl ?? '')
|
||||||
|
const exchangeRates = useStore((s) => s.exchangeRates ?? [])
|
||||||
|
const networkConfig = useStore((s) => s.networkConfig)
|
||||||
|
const displayCurrency = networkConfig?.displayCurrency
|
||||||
|
|
||||||
|
useQuery<CoinPriceData[]>(
|
||||||
|
[QUERY_KEYS.USD_PRICE],
|
||||||
|
async () => {
|
||||||
|
const res = await fetch(apiUrl)
|
||||||
|
return res.json()
|
||||||
|
},
|
||||||
|
{
|
||||||
|
enabled: !!apiUrl && !!exchangeRates.length && !!displayCurrency,
|
||||||
|
staleTime: 30000,
|
||||||
|
refetchInterval: 30000,
|
||||||
|
onSuccess: (data) => {
|
||||||
|
const coin = { denom: 'usd', amount: (1 / data[0].price).toString() }
|
||||||
|
if (displayCurrency.denom === coin.denom) {
|
||||||
|
useStore.setState({ baseToDisplayCurrencyRatio: data[0].price })
|
||||||
|
}
|
||||||
|
|
||||||
|
updateExchangeRate(coin, exchangeRates)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
38
src/images/statom.svg
Normal file
38
src/images/statom.svg
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||||
|
viewBox="0 0 2500 2500" style="enable-background:new 0 0 2500 2500;" xml:space="preserve">
|
||||||
|
<circle style="fill:#E50571;" cx="1250" cy="1250" r="1250"/>
|
||||||
|
<circle style="fill:#FFFFFF;" cx="1250" cy="1250" r="128.6"/>
|
||||||
|
<path style="fill:#FFFFFF;" d="M1709.1,1253.5c336.5-233.9,543.2-454.9,491.6-544.9c-33.3-58.1-168.1-50.8-359.4,8.1
|
||||||
|
c-13-22.6-36.8-37.7-64.1-37.7c-41.2,0-74.6,34.5-74.6,77.2c0,2.8,0.2,5.6,0.4,8.3c-69.8,26.5-144.5,58.1-222.5,94.3
|
||||||
|
c-35.3-409.1-124.1-699.3-228-699.3c-103.7,0-192.4,289.3-227.8,697.4c-370.9-173.9-665.9-242-718-152.1
|
||||||
|
c-32.5,56.3,35.9,164.2,173.9,294.7c-1.5,6.1-2.3,12.5-2.3,19.1c0,42.6,33.4,77.2,74.6,77.2c10.5,0,20.5-2.3,29.6-6.3
|
||||||
|
c62.9,52.3,134.6,106.9,213.5,162.2c-336.6,233.9-543.3,454.9-491.6,544.9c51.7,90.1,347.6,22.7,720.2-150.2
|
||||||
|
c7.9,91.7,18.5,177.4,31.4,255.2c-19.5,13.9-32.3,37.2-32.3,63.5c0,37.3,25.6,68.4,59.6,75.6c43.9,188.9,103.6,305.1,169.3,305.1
|
||||||
|
c103.8,0,192.4-289.4,227.8-697.6c371,174,665.9,242.2,717.9,152.3C2250.4,1710.6,2044.5,1488.8,1709.1,1253.5z M1725.6,811.8
|
||||||
|
c13.4,13.3,31.6,21.5,51.7,21.5c37.1,0,67.9-28,73.6-64.8c190.7-59.8,268.1-52.8,295.1-45.4c9.1,2.5,15,11.2,14,20.6
|
||||||
|
c-5.1,56-104.2,157-104.2,157c-132.1,131.9-271.4,241.7-387.7,324.4c-54.8-37.5-112.7-75.2-173.3-112.6
|
||||||
|
c-2-69.4-5.4-136.8-10.2-201.5C1576.7,870.1,1656.5,837.6,1725.6,811.8z M1398,1397.6c-47.4,29.1-96.7,57-146.1,83.3
|
||||||
|
c-33.6-18.8-52-30.1-52-30.1c-46.3-25-92.5-52-137.6-79.9c-2.2-85.5-2.7-164-2.4-227.6c71-43.2,136.9-81.4,190.9-112.1
|
||||||
|
c76.2,41.6,145,81.1,199.8,113.2c0.4,34.7-0.1,54.1-0.1,54.1c1.7,55.9,1.3,112.8-0.5,169.1C1417,1387.3,1398,1397.6,1398,1397.6z
|
||||||
|
M1448,1421.5c-2.5,53.4-6.2,105.5-10.4,154.9c-54.3-25.8-101-49.7-138.3-69.6c24.9-13.7,50-27.8,75.2-42.2
|
||||||
|
C1399.3,1450.2,1423.8,1435.9,1448,1421.5z M1203.7,1506c-45.2,23.2-90.1,44.9-133,65c-3-49.4-5.2-98.4-6.8-145.8
|
||||||
|
c21.7,13.1,43.8,26.1,66.1,39C1154.8,1478.5,1179.3,1492.4,1203.7,1506z M1009,1337.3c-43.2-27.8-85-56-124.2-83.4
|
||||||
|
c41.7-27.4,83.5-53.9,124.1-79.1c-0.4,25.7-0.6,51.7-0.6,77.9C1008.2,1281.1,1008.5,1309.3,1009,1337.3z M1066.8,934.6
|
||||||
|
c44.8,22.5,88.9,45.4,131.2,68c-22.3,12.4-44.8,25-67.3,37.9c-23.7,13.6-47.2,27.3-70.2,41.1c0.8-61.8,2.1-99.1,2.1-99.1
|
||||||
|
C1063.9,966.2,1065.4,950.3,1066.8,934.6z M1304.9,1000.9c54.2-30.2,87.3-47.7,87.3-47.7c16.4-7.6,32.4-15,48-22.1
|
||||||
|
c4.9,59.5,7.5,111.6,9,153.5c-24.3-14.6-48.9-29.2-73.9-43.7C1351.8,1027.3,1328.3,1013.9,1304.9,1000.9z M1496.2,1171.4
|
||||||
|
c53.4,31.9,85.3,51.8,85.3,51.8c15.2,10.6,30,21.1,44.5,31.4c-49.7,34.2-93.9,62.7-129.8,85c0.5-28.7,0.8-57.8,0.8-87.1
|
||||||
|
C1496.9,1225.3,1496.7,1198.2,1496.2,1171.4z M1238.2,214.2c6.7-6.6,17.1-7.4,24.7-2c45.9,32.5,84.4,168.5,84.4,168.5
|
||||||
|
c48.7,180.9,74.7,357.1,88.4,499.3c-59.3,28.4-120.2,59.3-182.3,92.6c-61.6-33.4-122.2-64.5-181.2-93
|
||||||
|
C1124.6,369.7,1208.5,243.6,1238.2,214.2z M619.2,1054c5.3-10.6,8.4-22.7,8.4-35.5c0-42.6-33.4-77.2-74.6-77.2
|
||||||
|
c-16.7,0-32,5.7-44.5,15.2C364.1,818,351.7,750.1,351.7,750.1l-0.1-0.3c-10-23.7,11.1-29.4,11.1-29.4
|
||||||
|
c93.5-17.6,224.7,22.6,224.7,22.6c123.5,28.1,280.4,94.2,432.9,168.6c-4.7,64.4-8.1,131.3-10.1,200.3
|
||||||
|
c-59.6,36.5-116.7,73.2-170.8,109.8C736.8,1148.2,656.4,1084.2,619.2,1054z M736.1,1711.7c-280.1,100.9-369.7,68.8-369.7,68.8h0
|
||||||
|
c-25.7-3.2-19.9-24.4-19.9-24.4c31.5-89.7,132-183.2,132-183.2c86.2-92.8,222-195.4,362.8-290c53.6,36.5,110.1,73.2,169,109.7
|
||||||
|
c2,69.5,5.4,136.9,10.2,201.7C859.5,1666.9,736.1,1711.7,736.1,1711.7z M1393.7,1929c-51.8,293.2-124.2,355-124.2,355
|
||||||
|
c-15.4,20.6-30.9,5.1-30.9,5.1c-62.1-72-93.2-205.8-93.2-205.8c-4.9-15.7-9.5-32.1-13.8-49.3c24.5-12.7,41.3-38.8,41.3-69
|
||||||
|
c0-41.1-31-74.7-70.2-77c-12.9-83.4-22.1-174.2-28.5-265.2c57.8-27.8,117.3-58,177.7-90.4c61.7,33.4,122.3,64.5,181.2,93.1
|
||||||
|
C1416.1,1800.5,1393.7,1929,1393.7,1929z M2147.6,1782.8c-51.1,23.4-188.1-11.5-188.1-11.5c-180.4-48.4-345.3-113.9-475.1-173.2
|
||||||
|
c4.9-65.8,8.4-134.4,10.5-205.1c59.6-36.5,116.7-73.3,170.8-109.9c414.9,300.9,482,436.8,492.5,477.1
|
||||||
|
C2160.7,1769.5,2156.1,1778.9,2147.6,1782.8z"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 3.9 KiB |
@ -1,5 +1,6 @@
|
|||||||
// @index(['./*.ts'], f => `export { ${f.name.split('.')[0]} } from '${f.path}'`)
|
// @index(['./*.ts'], f => `export { ${f.name.split('.')[0]} } from '${f.path}'`)
|
||||||
export { position } from './position'
|
export { position } from './position'
|
||||||
export { redBankAssets } from './redBankAssets'
|
export { redBankAssets } from './redBankAssets'
|
||||||
|
export { redBankData } from './redBankData'
|
||||||
export { vault } from './vault'
|
export { vault } from './vault'
|
||||||
// @endindex
|
// @endindex
|
||||||
|
@ -4,7 +4,8 @@ export const position: Position = {
|
|||||||
amounts: {
|
amounts: {
|
||||||
primary: 0,
|
primary: 0,
|
||||||
secondary: 0,
|
secondary: 0,
|
||||||
borrowed: 0,
|
borrowedPrimary: 0,
|
||||||
|
borrowedSecondary: 0,
|
||||||
lp: {
|
lp: {
|
||||||
amount: '0',
|
amount: '0',
|
||||||
primary: 0,
|
primary: 0,
|
||||||
@ -15,7 +16,8 @@ export const position: Position = {
|
|||||||
values: {
|
values: {
|
||||||
primary: 0,
|
primary: 0,
|
||||||
secondary: 0,
|
secondary: 0,
|
||||||
borrowed: 0,
|
borrowedPrimary: 0,
|
||||||
|
borrowedSecondary: 0,
|
||||||
total: 0,
|
total: 0,
|
||||||
net: 0,
|
net: 0,
|
||||||
},
|
},
|
||||||
@ -26,4 +28,5 @@ export const position: Position = {
|
|||||||
},
|
},
|
||||||
ltv: 0.5,
|
ltv: 0.5,
|
||||||
currentLeverage: 1,
|
currentLeverage: 1,
|
||||||
|
borrowDenom: null,
|
||||||
}
|
}
|
||||||
|
@ -11,13 +11,14 @@ export const redBankAssets: RedBankAsset[] = [
|
|||||||
depositBalanceBaseCurrency: 0,
|
depositBalanceBaseCurrency: 0,
|
||||||
depositCap: 1_000_000,
|
depositCap: 1_000_000,
|
||||||
depositLiquidity: 5_000,
|
depositLiquidity: 5_000,
|
||||||
hasOraclePrice: true,
|
|
||||||
isCollateral: true,
|
isCollateral: true,
|
||||||
logo: '',
|
logo: '',
|
||||||
marketLiquidity: '5000',
|
marketLiquidity: '5000',
|
||||||
name: 'Atom',
|
name: 'Atom',
|
||||||
symbol: 'ATOM',
|
symbol: 'ATOM',
|
||||||
walletBalance: '100',
|
walletBalance: '100',
|
||||||
|
borrowEnabled: true,
|
||||||
|
depositEnabled: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
borrowRate: 30,
|
borrowRate: 30,
|
||||||
@ -31,12 +32,13 @@ export const redBankAssets: RedBankAsset[] = [
|
|||||||
depositBalanceBaseCurrency: 0,
|
depositBalanceBaseCurrency: 0,
|
||||||
depositCap: 1_000_000,
|
depositCap: 1_000_000,
|
||||||
depositLiquidity: 5_000,
|
depositLiquidity: 5_000,
|
||||||
hasOraclePrice: true,
|
|
||||||
isCollateral: true,
|
isCollateral: true,
|
||||||
logo: '',
|
logo: '',
|
||||||
marketLiquidity: '5000',
|
marketLiquidity: '5000',
|
||||||
name: 'Osmo',
|
name: 'Osmo',
|
||||||
symbol: 'OSMO',
|
symbol: 'OSMO',
|
||||||
walletBalance: '100',
|
walletBalance: '100',
|
||||||
|
borrowEnabled: true,
|
||||||
|
depositEnabled: true,
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
150
src/mocks/redBankData.ts
Normal file
150
src/mocks/redBankData.ts
Normal file
@ -0,0 +1,150 @@
|
|||||||
|
export const redBankData: RedBankData = {
|
||||||
|
//@ts-ignore
|
||||||
|
rbwasmkey: {
|
||||||
|
OSMOMarket: {
|
||||||
|
denom: 'uosmo',
|
||||||
|
max_loan_to_value: '0.59',
|
||||||
|
liquidation_threshold: '0.61',
|
||||||
|
liquidation_bonus: '0.15',
|
||||||
|
reserve_factor: '0.2',
|
||||||
|
interest_rate_model: {
|
||||||
|
optimal_utilization_rate: '0.6',
|
||||||
|
base: '0',
|
||||||
|
slope_1: '0.15',
|
||||||
|
slope_2: '3',
|
||||||
|
},
|
||||||
|
borrow_index: '1.007594298500875037',
|
||||||
|
liquidity_index: '1.002246982368900673',
|
||||||
|
borrow_rate: '0.093460151948703559',
|
||||||
|
liquidity_rate: '0.027951360007279224',
|
||||||
|
indexes_last_updated: 1678369905,
|
||||||
|
collateral_total_scaled: '9114923539298761562',
|
||||||
|
debt_total_scaled: '3389444761162622058',
|
||||||
|
deposit_enabled: true,
|
||||||
|
borrow_enabled: true,
|
||||||
|
deposit_cap: '10000000000000',
|
||||||
|
},
|
||||||
|
OSMOMarketIncentive: {
|
||||||
|
denom: 'uosmo',
|
||||||
|
emission_per_second: '231482',
|
||||||
|
start_time: 1675793700,
|
||||||
|
duration: 2592000,
|
||||||
|
index: '0.000000139928505817',
|
||||||
|
last_updated: 1678369905,
|
||||||
|
},
|
||||||
|
ATOMMarket: {
|
||||||
|
denom: 'ibc/27394FB092D2ECCD56123C74F36E4C1F926001CEADA9CA97EA622B25F41E5EB2',
|
||||||
|
max_loan_to_value: '0.68',
|
||||||
|
liquidation_threshold: '0.7',
|
||||||
|
liquidation_bonus: '0.15',
|
||||||
|
reserve_factor: '0.2',
|
||||||
|
interest_rate_model: {
|
||||||
|
optimal_utilization_rate: '0.6',
|
||||||
|
base: '0',
|
||||||
|
slope_1: '0.15',
|
||||||
|
slope_2: '3',
|
||||||
|
},
|
||||||
|
borrow_index: '1.007258580949970929',
|
||||||
|
liquidity_index: '1.002076728614660732',
|
||||||
|
borrow_rate: '0.09442052103774879',
|
||||||
|
liquidity_rate: '0.028528751337727877',
|
||||||
|
indexes_last_updated: 1678368967,
|
||||||
|
collateral_total_scaled: '349274630628750224',
|
||||||
|
debt_total_scaled: '131236134520805186',
|
||||||
|
deposit_enabled: true,
|
||||||
|
borrow_enabled: true,
|
||||||
|
deposit_cap: '350000000000',
|
||||||
|
},
|
||||||
|
ATOMMarketIncentive: {
|
||||||
|
denom: 'ibc/27394FB092D2ECCD56123C74F36E4C1F926001CEADA9CA97EA622B25F41E5EB2',
|
||||||
|
emission_per_second: '106095',
|
||||||
|
start_time: 1675793700,
|
||||||
|
duration: 2592000,
|
||||||
|
index: '0.000001514531327288',
|
||||||
|
last_updated: 1678369638,
|
||||||
|
},
|
||||||
|
stATOMMarket: {
|
||||||
|
denom: 'ibc/C140AFD542AE77BD7DCC83F13FDD8C5E5BB8C4929785E6EC2F4C636F98F17901',
|
||||||
|
max_loan_to_value: '0.68',
|
||||||
|
liquidation_threshold: '0.7',
|
||||||
|
liquidation_bonus: '0.15',
|
||||||
|
reserve_factor: '0.2',
|
||||||
|
interest_rate_model: {
|
||||||
|
optimal_utilization_rate: '0.6',
|
||||||
|
base: '0',
|
||||||
|
slope_1: '0.15',
|
||||||
|
slope_2: '3',
|
||||||
|
},
|
||||||
|
borrow_index: '1.007258580949970929',
|
||||||
|
liquidity_index: '1.002076728614660732',
|
||||||
|
borrow_rate: '0.09442052103774879',
|
||||||
|
liquidity_rate: '0.028528751337727877',
|
||||||
|
indexes_last_updated: 1678368967,
|
||||||
|
collateral_total_scaled: '349274630628750224',
|
||||||
|
debt_total_scaled: '131236134520805186',
|
||||||
|
deposit_enabled: true,
|
||||||
|
borrow_enabled: false,
|
||||||
|
deposit_cap: '350000000000',
|
||||||
|
},
|
||||||
|
stATOMMarketIncentive: {
|
||||||
|
denom: 'ibc/C140AFD542AE77BD7DCC83F13FDD8C5E5BB8C4929785E6EC2F4C636F98F17901',
|
||||||
|
emission_per_second: '106095',
|
||||||
|
start_time: 1675793700,
|
||||||
|
duration: 2592000,
|
||||||
|
index: '0.000001514531327288',
|
||||||
|
last_updated: 1678369638,
|
||||||
|
},
|
||||||
|
axlUSDCMarket: {
|
||||||
|
denom: 'ibc/D189335C6E4A68B513C10AB227BF1C1D38C746766278BA3EEB4FB14124F1D858',
|
||||||
|
max_loan_to_value: '0.74',
|
||||||
|
liquidation_threshold: '0.75',
|
||||||
|
liquidation_bonus: '0.1',
|
||||||
|
reserve_factor: '0.2',
|
||||||
|
interest_rate_model: {
|
||||||
|
optimal_utilization_rate: '0.8',
|
||||||
|
base: '0',
|
||||||
|
slope_1: '0.2',
|
||||||
|
slope_2: '2',
|
||||||
|
},
|
||||||
|
borrow_index: '1.010875731969102527',
|
||||||
|
liquidity_index: '1.00525118991986623',
|
||||||
|
borrow_rate: '0.193514001505802393',
|
||||||
|
liquidity_rate: '0.11983254009212061',
|
||||||
|
indexes_last_updated: 1678369620,
|
||||||
|
collateral_total_scaled: '1494717184985439254',
|
||||||
|
debt_total_scaled: '1158255523619905561',
|
||||||
|
deposit_enabled: true,
|
||||||
|
borrow_enabled: true,
|
||||||
|
deposit_cap: '1500000000000',
|
||||||
|
},
|
||||||
|
axlUSDCMarketIncentive: {
|
||||||
|
denom: 'ibc/D189335C6E4A68B513C10AB227BF1C1D38C746766278BA3EEB4FB14124F1D858',
|
||||||
|
emission_per_second: '48225',
|
||||||
|
start_time: 1675793700,
|
||||||
|
duration: 2592000,
|
||||||
|
index: '0.000000143742920378',
|
||||||
|
last_updated: 1678369620,
|
||||||
|
},
|
||||||
|
collateral: [
|
||||||
|
{
|
||||||
|
denom: 'ibc/27394FB092D2ECCD56123C74F36E4C1F926001CEADA9CA97EA622B25F41E5EB2',
|
||||||
|
amount_scaled: '2559593418324',
|
||||||
|
amount: '2564911',
|
||||||
|
enabled: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
denom: 'ibc/D189335C6E4A68B513C10AB227BF1C1D38C746766278BA3EEB4FB14124F1D858',
|
||||||
|
amount_scaled: '20000000000000',
|
||||||
|
amount: '20105061',
|
||||||
|
enabled: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
denom: 'uosmo',
|
||||||
|
amount_scaled: '48000037051741',
|
||||||
|
amount: '48107901',
|
||||||
|
enabled: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
unclaimedRewards: '4679062',
|
||||||
|
},
|
||||||
|
}
|
@ -65,6 +65,11 @@ const EditVault = (props: Props) => {
|
|||||||
[prevPosition.values.total, position.values.total],
|
[prevPosition.values.total, position.values.total],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const borrowKey =
|
||||||
|
props.activeVault.position.borrowDenom === props.activeVault.denoms.primary
|
||||||
|
? 'borrowedPrimary'
|
||||||
|
: 'borrowedSecondary'
|
||||||
|
|
||||||
const { repayActions, repayFunds, repayFee } = useRepayPosition({
|
const { repayActions, repayFunds, repayFee } = useRepayPosition({
|
||||||
prevPosition,
|
prevPosition,
|
||||||
repayPosition,
|
repayPosition,
|
||||||
@ -131,7 +136,8 @@ const EditVault = (props: Props) => {
|
|||||||
const actionButtons = useMemo(
|
const actionButtons = useMemo(
|
||||||
() => (
|
() => (
|
||||||
<>
|
<>
|
||||||
{prevPosition.amounts.borrowed > 0 && (
|
{(prevPosition.amounts.borrowedPrimary > 0 ||
|
||||||
|
prevPosition.amounts.borrowedSecondary > 0) && (
|
||||||
<Button
|
<Button
|
||||||
onClick={() => setIsRepay(!isRepay)}
|
onClick={() => setIsRepay(!isRepay)}
|
||||||
text={isRepay ? t('fields.managePosition') : t('fields.repayDebt')}
|
text={isRepay ? t('fields.managePosition') : t('fields.repayDebt')}
|
||||||
@ -158,7 +164,8 @@ const EditVault = (props: Props) => {
|
|||||||
setIsRepay,
|
setIsRepay,
|
||||||
lockupTimeAndUnit.time,
|
lockupTimeAndUnit.time,
|
||||||
lockupTimeAndUnit.unit,
|
lockupTimeAndUnit.unit,
|
||||||
prevPosition.amounts.borrowed,
|
prevPosition.amounts.borrowedPrimary,
|
||||||
|
prevPosition.amounts.borrowedSecondary,
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -200,9 +207,13 @@ const EditVault = (props: Props) => {
|
|||||||
!isRepay &&
|
!isRepay &&
|
||||||
(prevPosition.amounts.primary > position.amounts.primary ||
|
(prevPosition.amounts.primary > position.amounts.primary ||
|
||||||
prevPosition.amounts.secondary > position.amounts.secondary ||
|
prevPosition.amounts.secondary > position.amounts.secondary ||
|
||||||
prevPosition.amounts.borrowed > position.amounts.borrowed)
|
prevPosition.amounts.borrowedPrimary > position.amounts.borrowedPrimary ||
|
||||||
|
prevPosition.amounts.borrowedSecondary > position.amounts.borrowedSecondary)
|
||||||
|
|
||||||
const isNotRepaying = isRepay && repayPosition.amounts.borrowed >= prevPosition.amounts.borrowed
|
const isNotRepaying =
|
||||||
|
isRepay &&
|
||||||
|
repayPosition.amounts.borrowedPrimary >= prevPosition.amounts.borrowedPrimary &&
|
||||||
|
repayPosition.amounts.borrowedSecondary >= prevPosition.amounts.borrowedSecondary
|
||||||
const isWithoutFee = (!isRepay && !editFee) || (isRepay && !repayFee)
|
const isWithoutFee = (!isRepay && !editFee) || (isRepay && !repayFee)
|
||||||
const isSameAmounts =
|
const isSameAmounts =
|
||||||
(isEqual(prevPosition.amounts, position.amounts) && !isRepay) ||
|
(isEqual(prevPosition.amounts, position.amounts) && !isRepay) ||
|
||||||
@ -280,7 +291,7 @@ const EditVault = (props: Props) => {
|
|||||||
type={isRepay ? 'repay' : showUnlockBtn ? 'unlock' : 'edit'}
|
type={isRepay ? 'repay' : showUnlockBtn ? 'unlock' : 'edit'}
|
||||||
position={position}
|
position={position}
|
||||||
prevPosition={prevPosition}
|
prevPosition={prevPosition}
|
||||||
repayAmount={prevPosition.amounts.borrowed - repayPosition.amounts.borrowed}
|
repayAmount={prevPosition.amounts[borrowKey] - repayPosition.amounts[borrowKey]}
|
||||||
vault={props.activeVault}
|
vault={props.activeVault}
|
||||||
className={styles.tooltip}
|
className={styles.tooltip}
|
||||||
/>
|
/>
|
||||||
|
@ -56,6 +56,11 @@ const RepayVault = (props: Props) => {
|
|||||||
|
|
||||||
const disableConfirmBtn = !repayFee || isSameAmounts
|
const disableConfirmBtn = !repayFee || isSameAmounts
|
||||||
|
|
||||||
|
const borrowKey =
|
||||||
|
props.activeVault.position.borrowDenom === props.activeVault.denoms.primary
|
||||||
|
? 'borrowedPrimary'
|
||||||
|
: 'borrowedSecondary'
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Notification
|
<Notification
|
||||||
@ -102,7 +107,7 @@ const RepayVault = (props: Props) => {
|
|||||||
type={'repay'}
|
type={'repay'}
|
||||||
position={repayPosition}
|
position={repayPosition}
|
||||||
prevPosition={prevPosition}
|
prevPosition={prevPosition}
|
||||||
repayAmount={prevPosition.amounts.borrowed - repayPosition.amounts.borrowed}
|
repayAmount={prevPosition.amounts[borrowKey] - repayPosition.amounts[borrowKey]}
|
||||||
vault={props.activeVault}
|
vault={props.activeVault}
|
||||||
className={styles.tooltip}
|
className={styles.tooltip}
|
||||||
/>
|
/>
|
||||||
|
@ -115,6 +115,11 @@ const commonSlice = (
|
|||||||
config.NETWORK_CONFIG.rpcUrl = serializeUrl(config.NETWORK_CONFIG.rpcUrl)
|
config.NETWORK_CONFIG.rpcUrl = serializeUrl(config.NETWORK_CONFIG.rpcUrl)
|
||||||
config.NETWORK_CONFIG.restUrl = serializeUrl(config.NETWORK_CONFIG.restUrl)
|
config.NETWORK_CONFIG.restUrl = serializeUrl(config.NETWORK_CONFIG.restUrl)
|
||||||
|
|
||||||
|
const storageDisplayCurrency = localStorage.getItem('displayCurrency')
|
||||||
|
if (storageDisplayCurrency) {
|
||||||
|
config.NETWORK_CONFIG.displayCurrency = JSON.parse(storageDisplayCurrency)
|
||||||
|
}
|
||||||
|
|
||||||
set({
|
set({
|
||||||
otherAssets: config.NETWORK_CONFIG.assets.other,
|
otherAssets: config.NETWORK_CONFIG.assets.other,
|
||||||
whitelistedAssets: config.NETWORK_CONFIG.assets.whitelist,
|
whitelistedAssets: config.NETWORK_CONFIG.assets.whitelist,
|
||||||
|
@ -25,9 +25,16 @@ const oraclesSlice = (set: NamedSet<Store>, get: GetState<Store>): OraclesSlice
|
|||||||
const baseCurrency = get().baseCurrency
|
const baseCurrency = get().baseCurrency
|
||||||
const networkConfig = get().networkConfig
|
const networkConfig = get().networkConfig
|
||||||
const displayCurrency = networkConfig?.displayCurrency
|
const displayCurrency = networkConfig?.displayCurrency
|
||||||
const assets = [...whitelistedAssets, ...otherAssets]
|
const exchangeRatesState = get().exchangeRatesState
|
||||||
|
const assets: Asset[] = [...whitelistedAssets, ...otherAssets]
|
||||||
|
|
||||||
if (!coin || !exchangeRates || !assets.length || !displayCurrency) {
|
if (
|
||||||
|
!coin ||
|
||||||
|
exchangeRatesState === State.INITIALISING ||
|
||||||
|
!exchangeRates?.find((rate) => rate.denom === displayCurrency.denom) ||
|
||||||
|
!assets.length ||
|
||||||
|
!displayCurrency
|
||||||
|
) {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -88,13 +95,19 @@ const oraclesSlice = (set: NamedSet<Store>, get: GetState<Store>): OraclesSlice
|
|||||||
|
|
||||||
const wasmQueryResults = data.prices
|
const wasmQueryResults = data.prices
|
||||||
const exchangeRates: Coin[] = get().exchangeRates ?? []
|
const exchangeRates: Coin[] = get().exchangeRates ?? []
|
||||||
|
const baseCurrency = get().baseCurrency
|
||||||
|
const networkConfig = get().networkConfig
|
||||||
|
const displayCurrency = networkConfig?.displayCurrency
|
||||||
|
|
||||||
get()
|
get()
|
||||||
.whitelistedAssets?.filter((asset: Asset) => !!asset.denom)
|
.whitelistedAssets?.filter((asset: Asset) => !!asset.denom)
|
||||||
.forEach((asset: Asset) => {
|
.forEach((asset: Asset) => {
|
||||||
const denom = asset.denom
|
const denom = asset.denom
|
||||||
|
const hasBaseCurrency = exchangeRates?.find(
|
||||||
|
(ratesAsset) => ratesAsset.denom === baseCurrency.denom,
|
||||||
|
)
|
||||||
|
|
||||||
if (denom === get().baseCurrency.denom) {
|
if (denom === baseCurrency.denom && !hasBaseCurrency) {
|
||||||
exchangeRates.push({ denom, amount: '1' })
|
exchangeRates.push({ denom, amount: '1' })
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -106,6 +119,11 @@ const oraclesSlice = (set: NamedSet<Store>, get: GetState<Store>): OraclesSlice
|
|||||||
denom,
|
denom,
|
||||||
amount: typeof exchangeRateResult === 'string' ? exchangeRateResult || '0.00' : '0.00',
|
amount: typeof exchangeRateResult === 'string' ? exchangeRateResult || '0.00' : '0.00',
|
||||||
}
|
}
|
||||||
|
if (asset.denom === displayCurrency.denom) {
|
||||||
|
set({
|
||||||
|
baseToDisplayCurrencyRatio: 1 / Number(exchangeRate.amount),
|
||||||
|
})
|
||||||
|
}
|
||||||
updateExchangeRate(exchangeRate, exchangeRates)
|
updateExchangeRate(exchangeRate, exchangeRates)
|
||||||
})
|
})
|
||||||
set({
|
set({
|
||||||
|
@ -119,6 +119,8 @@ const redBankSlice = (set: NamedSet<Store>, get: GetState<Store>): RedBankSlice
|
|||||||
incentiveInfo,
|
incentiveInfo,
|
||||||
isCollateral: true,
|
isCollateral: true,
|
||||||
depositCap: depositCap,
|
depositCap: depositCap,
|
||||||
|
borrowEnabled: marketInfo?.borrow_enabled ?? false,
|
||||||
|
depositEnabled: marketInfo?.deposit_enabled ?? false,
|
||||||
}
|
}
|
||||||
redBankAsset.subRows = [{ ...redBankAsset }]
|
redBankAsset.subRows = [{ ...redBankAsset }]
|
||||||
redBankAssets.push(redBankAsset)
|
redBankAssets.push(redBankAsset)
|
||||||
|
@ -324,25 +324,50 @@ export const vaultsSlice = (set: NamedSet<Store>, get: GetState<Store>): VaultsS
|
|||||||
(unlockTime) => unlockTime?.vaultAddress === curr.address,
|
(unlockTime) => unlockTime?.vaultAddress === curr.address,
|
||||||
)?.unlockAtTimestamp
|
)?.unlockAtTimestamp
|
||||||
|
|
||||||
let primarySupplyAmount = Number(
|
let primaryAmount = Number(
|
||||||
findByDenom(primaryAndSecondaryAmount.coins, curr.denoms.primary)?.amount || 0,
|
findByDenom(primaryAndSecondaryAmount.coins, curr.denoms.primary)?.amount || 0,
|
||||||
)
|
)
|
||||||
const secondaryAmount = Number(
|
let secondaryAmount = Number(
|
||||||
findByDenom(primaryAndSecondaryAmount.coins, curr.denoms.secondary)?.amount || 0,
|
findByDenom(primaryAndSecondaryAmount.coins, curr.denoms.secondary)?.amount || 0,
|
||||||
)
|
)
|
||||||
const borrowedAmount = Number(creditAccountPosition.debts[0]?.amount || 0)
|
|
||||||
|
|
||||||
if (borrowedAmount > secondaryAmount) {
|
let borrowedPrimaryAmount = 0
|
||||||
const swappedToPrimary = Math.round(
|
let borrowedSecondaryAmount = 0
|
||||||
get().convertToBaseCurrency({
|
|
||||||
denom: curr.denoms.secondary,
|
const debt = creditAccountPosition.debts[0]
|
||||||
amount: (borrowedAmount - secondaryAmount).toString(),
|
if (debt) {
|
||||||
}),
|
if (debt.denom === curr.denoms.primary) {
|
||||||
)
|
borrowedPrimaryAmount = Number(debt.amount)
|
||||||
primarySupplyAmount -= swappedToPrimary
|
} else {
|
||||||
|
borrowedSecondaryAmount = Number(debt.amount)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const secondarySupplyAmount = Math.max(secondaryAmount - borrowedAmount, 0)
|
const borrowedDenom: string = creditAccountPosition.debts[0]?.denom || ''
|
||||||
|
|
||||||
|
if (borrowedPrimaryAmount > primaryAmount) {
|
||||||
|
const swapped = Math.round(
|
||||||
|
get().convertToBaseCurrency({
|
||||||
|
denom: borrowedDenom,
|
||||||
|
amount: (borrowedPrimaryAmount - primaryAmount).toString(),
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
secondaryAmount -= swapped
|
||||||
|
}
|
||||||
|
|
||||||
|
if (borrowedSecondaryAmount > secondaryAmount) {
|
||||||
|
const swapped = Math.round(
|
||||||
|
get().convertToBaseCurrency({
|
||||||
|
denom: borrowedDenom,
|
||||||
|
amount: (borrowedSecondaryAmount - secondaryAmount).toString(),
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
primaryAmount -= swapped
|
||||||
|
}
|
||||||
|
|
||||||
|
const primarySupplyAmount = Math.max(primaryAmount - borrowedPrimaryAmount, 0)
|
||||||
|
const secondarySupplyAmount = Math.max(secondaryAmount - borrowedSecondaryAmount, 0)
|
||||||
|
const borrowedAmount = Math.max(borrowedPrimaryAmount, borrowedSecondaryAmount)
|
||||||
|
|
||||||
const convertToBaseCurrency = get().convertToBaseCurrency
|
const convertToBaseCurrency = get().convertToBaseCurrency
|
||||||
const redBankAssets = get().redBankAssets
|
const redBankAssets = get().redBankAssets
|
||||||
@ -357,14 +382,15 @@ export const vaultsSlice = (set: NamedSet<Store>, get: GetState<Store>): VaultsS
|
|||||||
})
|
})
|
||||||
|
|
||||||
const borrowedValue = convertToBaseCurrency({
|
const borrowedValue = convertToBaseCurrency({
|
||||||
denom: curr.denoms.secondary,
|
denom: borrowedDenom,
|
||||||
amount: borrowedAmount.toString(),
|
amount: borrowedAmount.toString(),
|
||||||
})
|
})
|
||||||
|
|
||||||
const values = {
|
const values = {
|
||||||
primary: primaryValue,
|
primary: primaryValue,
|
||||||
secondary: secondaryValue,
|
secondary: secondaryValue,
|
||||||
borrowed: borrowedValue,
|
borrowedPrimary: borrowedDenom === curr.denoms.primary ? borrowedValue : 0,
|
||||||
|
borrowedSecondary: borrowedDenom === curr.denoms.secondary ? borrowedValue : 0,
|
||||||
net: primaryValue + secondaryValue,
|
net: primaryValue + secondaryValue,
|
||||||
total: primaryValue + secondaryValue + borrowedValue,
|
total: primaryValue + secondaryValue + borrowedValue,
|
||||||
}
|
}
|
||||||
@ -390,7 +416,8 @@ export const vaultsSlice = (set: NamedSet<Store>, get: GetState<Store>): VaultsS
|
|||||||
amounts: {
|
amounts: {
|
||||||
primary: primarySupplyAmount,
|
primary: primarySupplyAmount,
|
||||||
secondary: secondarySupplyAmount,
|
secondary: secondarySupplyAmount,
|
||||||
borrowed: borrowedAmount,
|
borrowedPrimary: borrowedDenom === curr.denoms.primary ? borrowedAmount : 0,
|
||||||
|
borrowedSecondary: borrowedDenom === curr.denoms.secondary ? borrowedAmount : 0,
|
||||||
lp: {
|
lp: {
|
||||||
amount: vaultTokenAmounts.unlocking,
|
amount: vaultTokenAmounts.unlocking,
|
||||||
primary: Number(
|
primary: Number(
|
||||||
@ -416,6 +443,7 @@ export const vaultsSlice = (set: NamedSet<Store>, get: GetState<Store>): VaultsS
|
|||||||
ltv: leverageToLtv(leverage),
|
ltv: leverageToLtv(leverage),
|
||||||
...(unlockTime ? { unlockAtTimestamp: unlockTime } : {}),
|
...(unlockTime ? { unlockAtTimestamp: unlockTime } : {}),
|
||||||
status: getPositionStatus(unlockTime),
|
status: getPositionStatus(unlockTime),
|
||||||
|
borrowDenom: borrowedDenom,
|
||||||
}
|
}
|
||||||
|
|
||||||
prev.activeVaults.push({ ...curr, position })
|
prev.activeVaults.push({ ...curr, position })
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
atom: $colorTokenATOM;
|
atom: $colorTokenATOM;
|
||||||
axlusdc: $colorTokenAxlUSDC;
|
axlusdc: $colorTokenAxlUSDC;
|
||||||
juno: $colorTokenJUNO;
|
juno: $colorTokenJUNO;
|
||||||
|
statom: $colorTokenStATOM;
|
||||||
|
|
||||||
/* COLORS */
|
/* COLORS */
|
||||||
success: $colorInfoProfit;
|
success: $colorInfoProfit;
|
||||||
|
@ -1,43 +1,45 @@
|
|||||||
@use 'sass:math';
|
@use 'sass:math';
|
||||||
$rem-base: 15px;
|
$rem-base: 16px;
|
||||||
|
|
||||||
/* Colors */
|
/* Colors */
|
||||||
$colorWhite: #ffffff;
|
$colorWhite: #f5f5f5;
|
||||||
$colorGrey: #3a3c49;
|
$colorGrey: #bdbdbd;
|
||||||
$colorGreyLight: #bfbfbf;
|
$colorGreyLight: #e0e0e0;
|
||||||
$colorGreyHighlight: #4c4c4c;
|
$colorGreyHighlight: #efefef;
|
||||||
$colorGreyMedium: #5f697a;
|
$colorGreyMedium: #9e9e9e;
|
||||||
$colorGreyDark: #1a1c25;
|
$colorGreyDark: #616161;
|
||||||
|
|
||||||
/* CI Colors */
|
/* CI Colors */
|
||||||
$colorPrimary: #14a693;
|
$colorPrimary: #0000ff;
|
||||||
$colorPrimaryHighlight: #15bfa9;
|
$colorPrimaryHighlight: #6962cc;
|
||||||
$colorPrimaryAlpha: rgba(20, 166, 147, 0.15);
|
$colorPrimaryAlpha: rgba(0, 0, 255, 0.05);
|
||||||
$colorSecondary: #524bb1;
|
$colorSecondary: #212121;
|
||||||
$colorSecondaryHighlight: #6962cc;
|
$colorSecondaryHighlight: #424242;
|
||||||
$colorSecondaryDark: #440b37;
|
$colorSecondaryDark: #111111;
|
||||||
$colorSecondaryAlpha: rgba(68, 11, 55, 0.7);
|
$colorSecondaryAlpha: rgba(17, 17, 17, 0.15);
|
||||||
$colorAccent: #2c1b2f;
|
$colorAccent: $colorGreyMedium;
|
||||||
$colorAccentHighlight: #421f32;
|
$colorAccentHighlight: $colorGreyMedium;
|
||||||
$colorAccentDark: #341a2a;
|
$colorAccentDark: $colorGreyDark;
|
||||||
$colorAccentInverted: #345dff;
|
$colorAccentInverted: $colorGreyLight;
|
||||||
|
|
||||||
/* Info Colors */
|
/* Info Colors */
|
||||||
$colorInfoProfit: #41a4a9;
|
$colorInfoProfit: #c4e7e9;
|
||||||
$colorInfoLoss: #f96363;
|
$colorInfoLoss: #c8aaaa;
|
||||||
$colorInfoWarning: #c83333;
|
$colorInfoWarning: #ffb5b5;
|
||||||
$colorInfoVoteAgainst: #eb9e49;
|
$colorInfoVoteAgainst: #6c5a46;
|
||||||
|
|
||||||
/* Token Colors */
|
/* Token Colors */
|
||||||
$colorTokenMARS: #a03b45;
|
$colorTokenMARS: #dd5b65;
|
||||||
$colorTokenOSMO: #9f1ab9;
|
$colorTokenOSMO: #9f1ab9;
|
||||||
$colorTokenATOM: #6f7390;
|
$colorTokenATOM: #6f7390;
|
||||||
$colorTokenAxlUSDC: #478edc;
|
$colorTokenAxlUSDC: #478edc;
|
||||||
$colorTokenJUNO: black;
|
$colorTokenJUNO: black;
|
||||||
|
$colorTokenStATOM: #e50571;
|
||||||
|
|
||||||
$colorGradientOSMO: linear-gradient(to bottom, #3a02e2, #e700ca);
|
$colorGradientOSMO: linear-gradient(to bottom, #3a02e2, #e700ca);
|
||||||
$colorGradientATOM: linear-gradient(to bottom, #2e3148, #6f7390);
|
$colorGradientATOM: linear-gradient(to bottom, #2e3148, #6f7390);
|
||||||
$colorGradientAxlUSDC: linear-gradient(to bottom, #1f5c9e, #478edc);
|
$colorGradientAxlUSDC: linear-gradient(to bottom, #1f5c9e, #478edc);
|
||||||
|
$colorGradientStATOM: linear-gradient(to bottom, #e50571, #fb5da9);
|
||||||
|
|
||||||
/* Alpha Colors */
|
/* Alpha Colors */
|
||||||
$alphaWhite10: rgba(255, 255, 255, 0.1);
|
$alphaWhite10: rgba(255, 255, 255, 0.1);
|
||||||
@ -60,32 +62,29 @@ $alphaBlack80: rgba(0, 0, 0, 0.8);
|
|||||||
$alphaBlack90: rgba(0, 0, 0, 0.9);
|
$alphaBlack90: rgba(0, 0, 0, 0.9);
|
||||||
|
|
||||||
/* Background Colors */
|
/* Background Colors */
|
||||||
$backgroundBody: #562a3b;
|
$backgroundBody: $colorGrey;
|
||||||
$backgroundBodyDark: #141621;
|
$backgroundBodyDark: $backgroundBody;
|
||||||
$backgroundInTile: $alphaBlack30;
|
$backgroundInTile: transparent;
|
||||||
$backgroundFooter: $alphaBlack20;
|
$backgroundFooter: transparent;
|
||||||
|
|
||||||
/* Slider Colors */
|
/* Slider Colors */
|
||||||
$sliderThumb: $colorWhite;
|
$sliderThumb: $colorGreyDark;
|
||||||
$sliderMark: $colorGreyLight;
|
$sliderMark: $colorGreyDark;
|
||||||
|
|
||||||
/* Tooltip Colors */
|
/* Tooltip Colors */
|
||||||
$tooltipIconColor: $alphaWhite20;
|
$tooltipIconColor: $alphaBlack60;
|
||||||
$tableSort: $alphaWhite20;
|
|
||||||
$tableSortActive: $colorWhite;
|
|
||||||
$tableHeader: $alphaWhite50;
|
|
||||||
|
|
||||||
/* Table Colors */
|
/* Table Colors */
|
||||||
$tableBorder: $alphaWhite10;
|
$tableBorder: $alphaBlack30;
|
||||||
$tableBorderEnd: $alphaWhite80;
|
$tableBorderEnd: $alphaBlack80;
|
||||||
$tableSort: $alphaWhite20;
|
$tableSort: $alphaBlack20;
|
||||||
$tableSortActive: $colorWhite;
|
$tableSortActive: $alphaBlack90;
|
||||||
$tableHeader: $alphaWhite40;
|
$tableHeader: $alphaBlack40;
|
||||||
$tableLabel: $alphaWhite60;
|
$tableLabel: $colorSecondaryDark;
|
||||||
|
|
||||||
/* Graph Colors */
|
/* Graph Colors */
|
||||||
$graphLiquidationsLine: $alphaWhite70;
|
$graphLiquidationsLine: $alphaBlack70;
|
||||||
$graphAxis: $alphaWhite40;
|
$graphAxis: $alphaBlack40;
|
||||||
|
|
||||||
/* Shadows */
|
/* Shadows */
|
||||||
$shadowInset: inset 0px 2px 2px rgba(0, 0, 0, 0.25);
|
$shadowInset: inset 0px 2px 2px rgba(0, 0, 0, 0.25);
|
||||||
@ -96,43 +95,40 @@ $shadowInset: inset 0px 2px 2px rgba(0, 0, 0, 0.25);
|
|||||||
|
|
||||||
/* Devider */
|
/* Devider */
|
||||||
@mixin devider10 {
|
@mixin devider10 {
|
||||||
border-bottom: 1px solid $alphaWhite10;
|
border-bottom: 1px solid $alphaBlack10;
|
||||||
}
|
}
|
||||||
|
|
||||||
@mixin devider20 {
|
@mixin devider20 {
|
||||||
border-bottom: 1px solid $alphaWhite20;
|
border-bottom: 1px solid $alphaBlack20;
|
||||||
}
|
}
|
||||||
|
|
||||||
@mixin devider40 {
|
@mixin devider40 {
|
||||||
border-bottom: 1px solid $alphaWhite40;
|
border-bottom: 1px solid $alphaBlack40;
|
||||||
}
|
}
|
||||||
|
|
||||||
@mixin devider60 {
|
@mixin devider60 {
|
||||||
border-bottom: 1px solid $alphaWhite60;
|
border-bottom: 1px solid $alphaBlack60;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Backgrounds */
|
/* Backgrounds */
|
||||||
@mixin bgBody {
|
@mixin bgBody {
|
||||||
background-color: $backgroundBody;
|
background-color: $backgroundBody;
|
||||||
background-size: 100% auto;
|
}
|
||||||
background-image: url('../images/bg.svg');
|
|
||||||
background-position: center top;
|
@mixin bgTableHover {
|
||||||
|
background-color: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
@mixin bgBodyDark {
|
@mixin bgBodyDark {
|
||||||
background-color: $backgroundBodyDark;
|
background-color: $backgroundBodyDark;
|
||||||
}
|
}
|
||||||
|
|
||||||
@mixin bgTableHover {
|
|
||||||
background-color: rgba($colorPrimary, 0.2);
|
|
||||||
}
|
|
||||||
|
|
||||||
@mixin bgProposalActive {
|
@mixin bgProposalActive {
|
||||||
background: linear-gradient(90deg, #10aa93 2.6%, #248aa9 97.92%);
|
background: linear-gradient(90deg, #10aa93 2.6%, #248aa9 97.92%);
|
||||||
}
|
}
|
||||||
|
|
||||||
@mixin bgProposalHover {
|
@mixin bgProposalHover {
|
||||||
background-color: #05252f;
|
background-color: $colorGreyMedium;
|
||||||
}
|
}
|
||||||
|
|
||||||
@mixin bgTile($deg: 99.79) {
|
@mixin bgTile($deg: 99.79) {
|
||||||
@ -144,7 +140,7 @@ $shadowInset: inset 0px 2px 2px rgba(0, 0, 0, 0.25);
|
|||||||
}
|
}
|
||||||
|
|
||||||
@mixin bgInTile {
|
@mixin bgInTile {
|
||||||
background: $alphaBlack30;
|
background: $backgroundInTile;
|
||||||
}
|
}
|
||||||
|
|
||||||
@mixin bgOverlay {
|
@mixin bgOverlay {
|
||||||
@ -161,11 +157,11 @@ $shadowInset: inset 0px 2px 2px rgba(0, 0, 0, 0.25);
|
|||||||
}
|
}
|
||||||
|
|
||||||
@mixin bgTileDevider {
|
@mixin bgTileDevider {
|
||||||
background-color: $alphaWhite60;
|
background-color: $alphaBlack60;
|
||||||
}
|
}
|
||||||
|
|
||||||
@mixin bgDevider {
|
@mixin bgDevider {
|
||||||
background-color: $alphaWhite20;
|
background-color: $alphaBlack20;
|
||||||
}
|
}
|
||||||
|
|
||||||
@mixin bgInput {
|
@mixin bgInput {
|
||||||
@ -174,68 +170,60 @@ $shadowInset: inset 0px 2px 2px rgba(0, 0, 0, 0.25);
|
|||||||
|
|
||||||
@mixin bgPrimary {
|
@mixin bgPrimary {
|
||||||
background-color: $colorPrimary;
|
background-color: $colorPrimary;
|
||||||
|
color: $colorWhite;
|
||||||
}
|
}
|
||||||
|
|
||||||
@mixin bgSecondary {
|
@mixin bgSecondary {
|
||||||
background-color: $colorSecondary;
|
background-color: $colorSecondary;
|
||||||
|
color: $colorWhite;
|
||||||
}
|
}
|
||||||
|
|
||||||
@mixin bgTertiary {
|
@mixin bgTertiary {
|
||||||
background-color: rgba(82, 75, 177, 0.5);
|
background-color: $alphaBlack60;
|
||||||
|
color: $colorWhite;
|
||||||
}
|
}
|
||||||
|
|
||||||
@mixin bgLimit {
|
@mixin bgLimit {
|
||||||
background: linear-gradient(
|
background: $colorPrimary;
|
||||||
to right,
|
|
||||||
#15bfa9 20.9%,
|
|
||||||
#5e4bb1 49.68%,
|
|
||||||
#382685 82.55%,
|
|
||||||
#c83333 100%
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@mixin bgLimitOpacity {
|
@mixin bgLimitOpacity {
|
||||||
background: linear-gradient(
|
background: $colorPrimary;
|
||||||
to right,
|
|
||||||
#15bfa830 20.9%,
|
|
||||||
#5e4bb130 49.68%,
|
|
||||||
#38268530 82.55%,
|
|
||||||
#c8333330 100%
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@mixin bgHatched {
|
@mixin bgHatched {
|
||||||
background-image: linear-gradient(
|
background-image: linear-gradient(
|
||||||
135deg,
|
135deg,
|
||||||
transparent 33.33%,
|
#1a1c25 33.33%,
|
||||||
#826d6b 33.33%,
|
rgba(255, 255, 255, 0.2) 33.33%,
|
||||||
#826d6b 50%,
|
rgba(255, 255, 255, 0.2) 50%,
|
||||||
transparent 50%,
|
#1a1c25 50%,
|
||||||
transparent 83.33%,
|
#1a1c25 83.33%,
|
||||||
#826d6b 83.33%,
|
rgba(255, 255, 255, 0.2) 83.33%,
|
||||||
#826d6b 100%
|
rgba(255, 255, 255, 0.2) 100%
|
||||||
);
|
);
|
||||||
background-size: 5px 5px;
|
background-size: 5px 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* GLOWS */
|
||||||
/* GLOWS */
|
/* GLOWS */
|
||||||
@mixin glowXS {
|
@mixin glowXS {
|
||||||
filter: blur(1px);
|
display: none;
|
||||||
}
|
}
|
||||||
@mixin glowS {
|
@mixin glowS {
|
||||||
filter: blur(3px);
|
display: none;
|
||||||
}
|
}
|
||||||
@mixin glowM {
|
@mixin glowM {
|
||||||
filter: blur(4px);
|
display: none;
|
||||||
}
|
}
|
||||||
@mixin glowL {
|
@mixin glowL {
|
||||||
filter: blur(5px);
|
display: none;
|
||||||
}
|
}
|
||||||
@mixin glowXL {
|
@mixin glowXL {
|
||||||
filter: blur(8px);
|
display: none;
|
||||||
}
|
}
|
||||||
@mixin glowXXL {
|
@mixin glowXXL {
|
||||||
filter: blur(24px);
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Typography */
|
/* Typography */
|
||||||
@ -243,11 +231,11 @@ $fontWeightLight: 300;
|
|||||||
$fontWeightRegular: 400;
|
$fontWeightRegular: 400;
|
||||||
$fontWeightSemibold: 600;
|
$fontWeightSemibold: 600;
|
||||||
|
|
||||||
$fontColorDarkPrimary: $colorSecondaryDark;
|
$fontColorDarkPrimary: $colorWhite;
|
||||||
$fontColorDarkSecondary: rgba(68, 8, 55, 0.7);
|
$fontColorDarkSecondary: $colorSecondaryDark;
|
||||||
$fontColorLightPrimary: $colorWhite;
|
$fontColorLightPrimary: $colorSecondaryDark;
|
||||||
$fontColorLightSecondary: $alphaWhite60;
|
$fontColorLightSecondary: $alphaBlack30;
|
||||||
$fontColorLightTertiary: rgba(255, 255, 255, 0.4);
|
$fontColorLightTertiary: $colorSecondaryDark;
|
||||||
$fontColorLtv: $colorWhite;
|
$fontColorLtv: $colorWhite;
|
||||||
|
|
||||||
@mixin typoH1 {
|
@mixin typoH1 {
|
||||||
@ -263,8 +251,6 @@ $fontColorLtv: $colorWhite;
|
|||||||
|
|
||||||
@mixin typoH2caps {
|
@mixin typoH2caps {
|
||||||
@include typoH2;
|
@include typoH2;
|
||||||
text-transform: uppercase;
|
|
||||||
letter-spacing: rem-calc(9);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@mixin typoH3 {
|
@mixin typoH3 {
|
||||||
@ -274,8 +260,6 @@ $fontColorLtv: $colorWhite;
|
|||||||
|
|
||||||
@mixin typoH3caps {
|
@mixin typoH3caps {
|
||||||
font-size: rem-calc(30.42);
|
font-size: rem-calc(30.42);
|
||||||
line-height: space(10);
|
|
||||||
text-transform: uppercase;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@mixin typoH4 {
|
@mixin typoH4 {
|
||||||
@ -286,8 +270,6 @@ $fontColorLtv: $colorWhite;
|
|||||||
|
|
||||||
@mixin typoH4caps {
|
@mixin typoH4caps {
|
||||||
@include typoH4;
|
@include typoH4;
|
||||||
text-transform: uppercase;
|
|
||||||
letter-spacing: rem-calc(3);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@mixin typoXXL {
|
@mixin typoXXL {
|
||||||
@ -297,9 +279,7 @@ $fontColorLtv: $colorWhite;
|
|||||||
|
|
||||||
@mixin typoXXLcaps {
|
@mixin typoXXLcaps {
|
||||||
@include typoXXL;
|
@include typoXXL;
|
||||||
font-weight: $fontWeightRegular;
|
font-weight: $fontWeightLight;
|
||||||
text-transform: uppercase;
|
|
||||||
letter-spacing: rem-calc(3);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@mixin typoXL {
|
@mixin typoXL {
|
||||||
@ -309,8 +289,6 @@ $fontColorLtv: $colorWhite;
|
|||||||
|
|
||||||
@mixin typoXLcaps {
|
@mixin typoXLcaps {
|
||||||
@include typoXL;
|
@include typoXL;
|
||||||
letter-spacing: rem-calc(5);
|
|
||||||
text-transform: uppercase;
|
|
||||||
font-weight: $fontWeightLight;
|
font-weight: $fontWeightLight;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -322,8 +300,6 @@ $fontColorLtv: $colorWhite;
|
|||||||
@mixin typoLcaps {
|
@mixin typoLcaps {
|
||||||
@include typoL;
|
@include typoL;
|
||||||
font-weight: $fontWeightSemibold;
|
font-weight: $fontWeightSemibold;
|
||||||
text-transform: uppercase;
|
|
||||||
letter-spacing: rem-calc(3);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@mixin typoM {
|
@mixin typoM {
|
||||||
@ -333,7 +309,6 @@ $fontColorLtv: $colorWhite;
|
|||||||
|
|
||||||
@mixin typoMcaps {
|
@mixin typoMcaps {
|
||||||
@include typoM;
|
@include typoM;
|
||||||
text-transform: uppercase;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@mixin typoS {
|
@mixin typoS {
|
||||||
@ -344,8 +319,6 @@ $fontColorLtv: $colorWhite;
|
|||||||
@mixin typoScaps {
|
@mixin typoScaps {
|
||||||
@include typoS;
|
@include typoS;
|
||||||
font-weight: $fontWeightSemibold;
|
font-weight: $fontWeightSemibold;
|
||||||
text-transform: uppercase;
|
|
||||||
letter-spacing: rem-calc(3);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@mixin typoXS {
|
@mixin typoXS {
|
||||||
@ -356,8 +329,6 @@ $fontColorLtv: $colorWhite;
|
|||||||
@mixin typoXScaps {
|
@mixin typoXScaps {
|
||||||
@include typoXS;
|
@include typoXS;
|
||||||
font-weight: $fontWeightSemibold;
|
font-weight: $fontWeightSemibold;
|
||||||
text-transform: uppercase;
|
|
||||||
letter-spacing: rem-calc(3);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@mixin typoXXS {
|
@mixin typoXXS {
|
||||||
@ -368,8 +339,6 @@ $fontColorLtv: $colorWhite;
|
|||||||
@mixin typoXXScaps {
|
@mixin typoXXScaps {
|
||||||
@include typoXXS;
|
@include typoXXS;
|
||||||
font-weight: $fontWeightSemibold;
|
font-weight: $fontWeightSemibold;
|
||||||
text-transform: uppercase;
|
|
||||||
letter-spacing: rem-calc(2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@mixin typoXXXS {
|
@mixin typoXXXS {
|
||||||
@ -380,20 +349,15 @@ $fontColorLtv: $colorWhite;
|
|||||||
@mixin typoXXXScaps {
|
@mixin typoXXXScaps {
|
||||||
@include typoXXXS;
|
@include typoXXXS;
|
||||||
font-weight: $fontWeightSemibold;
|
font-weight: $fontWeightSemibold;
|
||||||
text-transform: uppercase;
|
|
||||||
letter-spacing: rem-calc(2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@mixin typoButton {
|
@mixin typoButton {
|
||||||
font-family: Inter, sans-serif;
|
|
||||||
@include typoS;
|
@include typoS;
|
||||||
font-weight: $fontWeightSemibold;
|
font-weight: $fontWeightSemibold;
|
||||||
}
|
}
|
||||||
|
|
||||||
@mixin typoNav {
|
@mixin typoNav {
|
||||||
@include typoL;
|
@include typoL;
|
||||||
text-transform: uppercase;
|
|
||||||
letter-spacing: rem-calc(5);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@mixin typoNetwork {
|
@mixin typoNetwork {
|
||||||
@ -467,100 +431,70 @@ $spacingBase: 4;
|
|||||||
|
|
||||||
/* LAYOUTS */
|
/* LAYOUTS */
|
||||||
@mixin layoutTile {
|
@mixin layoutTile {
|
||||||
@include bgTile;
|
padding: space(1);
|
||||||
border: rem-calc(7) solid $colorAccentHighlight;
|
background: $colorGreyHighlight;
|
||||||
border-radius: $borderRadiusXL;
|
border: 2px solid $colorWhite;
|
||||||
|
box-shadow: 0 0 0 3px $colorGreyHighlight, 12px 12px 0 0 rgb(0 0 0 / 50%) !important;
|
||||||
height: fit-content;
|
height: fit-content;
|
||||||
}
|
}
|
||||||
|
|
||||||
@mixin layoutTooltip {
|
@mixin layoutTooltip {
|
||||||
@include padding(2, 4);
|
padding: space(3);
|
||||||
@include bgTooltip;
|
background: $colorGreyLight;
|
||||||
@include typoS;
|
border: 1px solid $colorSecondaryDark;
|
||||||
box-shadow: 0 rem-calc(3) rem-calc(4) rgba(0, 0, 0, 0.14),
|
|
||||||
0 rem-calc(3) rem-calc(3) rgba(0, 0, 0, 0.12), 0 rem-calc(1) rem-calc(8) rgba(0, 0, 0, 0.2);
|
|
||||||
border-radius: $borderRadiusL;
|
|
||||||
max-width: rem-calc(350);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@mixin layoutPopover {
|
@mixin layoutPopover {
|
||||||
@include bgPopover;
|
padding: space(3);
|
||||||
box-shadow: 0 rem-calc(2) rem-calc(2) rgba(0, 0, 0, 0.14),
|
background: $colorGreyLight;
|
||||||
0 rem-calc(1) rem-calc(5) rgba(0, 0, 0, 0.2);
|
border: 1px solid $colorSecondaryDark;
|
||||||
border-radius: $borderRadiusL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@mixin layoutIncentiveButton {
|
@mixin layoutIncentiveButton {
|
||||||
--border-width: 3px;
|
|
||||||
background-color: #946582;
|
|
||||||
position: relative;
|
|
||||||
border: none;
|
|
||||||
margin: rem-calc(3) rem-calc(11) 0 0;
|
|
||||||
height: rem-calc(28);
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
border: none;
|
|
||||||
background-color: darken(#946582, 10%);
|
|
||||||
}
|
|
||||||
|
|
||||||
&::after {
|
|
||||||
border-radius: $borderRadiusXXL;
|
|
||||||
position: absolute;
|
|
||||||
content: '';
|
|
||||||
top: calc(-1 * var(--border-width));
|
|
||||||
left: calc(-1 * var(--border-width));
|
|
||||||
z-index: -1;
|
|
||||||
width: calc(100% + var(--border-width) * 2);
|
|
||||||
height: calc(100% + var(--border-width) * 2);
|
|
||||||
background: linear-gradient(
|
|
||||||
90deg,
|
|
||||||
rgba(105, 98, 204, 0.8) 0%,
|
|
||||||
rgba(105, 98, 204, 1) 40%,
|
|
||||||
rgba(255, 255, 255, 1) 50%,
|
|
||||||
rgba(105, 98, 204, 1) 60%,
|
|
||||||
rgba(105, 98, 204, 0.8) 100%
|
|
||||||
);
|
|
||||||
background-size: 300% 300%;
|
|
||||||
background-position: 0 50%;
|
|
||||||
animation: moveGradient 6s alternate infinite;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@mixin layoutLogo {
|
@mixin layoutLogo {
|
||||||
> svg {
|
> svg {
|
||||||
width: rem-calc(50);
|
width: rem-calc(57);
|
||||||
height: rem-calc(50);
|
height: rem-calc(57);
|
||||||
|
|
||||||
|
path {
|
||||||
|
stroke: $fontColorLightPrimary;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@mixin layoutGlobal {
|
@mixin layoutGlobal {
|
||||||
|
opacity: 1 !important;
|
||||||
|
box-shadow: none !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Buttons */
|
/* Buttons */
|
||||||
$buttonBorder: $alphaWhite40;
|
$buttonBorder: $alphaBlack40;
|
||||||
$buttonBorderHover: $colorWhite;
|
$buttonBorderHover: $colorSecondaryDark;
|
||||||
|
|
||||||
@mixin buttonS {
|
@mixin buttonS {
|
||||||
@include typoS;
|
@include typoS;
|
||||||
@include padding(1.5, 5);
|
@include padding(1.5, 5);
|
||||||
min-height: rem-calc(32);
|
height: rem-calc(32);
|
||||||
}
|
}
|
||||||
|
|
||||||
@mixin buttonM {
|
@mixin buttonM {
|
||||||
@include typoM;
|
@include typoM;
|
||||||
@include padding(2.5, 6);
|
@include padding(2.5, 6);
|
||||||
min-height: rem-calc(40);
|
height: rem-calc(40);
|
||||||
}
|
}
|
||||||
|
|
||||||
@mixin buttonL {
|
@mixin buttonL {
|
||||||
@include typoL;
|
@include typoL;
|
||||||
@include padding(2.5, 6);
|
@include padding(2.5, 6);
|
||||||
min-height: rem-calc(56);
|
height: rem-calc(56);
|
||||||
}
|
}
|
||||||
|
|
||||||
@mixin buttonSolidPrimary {
|
@mixin buttonSolidPrimary {
|
||||||
&.primary {
|
&.primary {
|
||||||
background-color: $colorPrimary;
|
background-color: $colorPrimary;
|
||||||
|
color: $colorWhite;
|
||||||
|
|
||||||
&:hover,
|
&:hover,
|
||||||
&:focus {
|
&:focus {
|
||||||
@ -576,6 +510,7 @@ $buttonBorderHover: $colorWhite;
|
|||||||
@mixin buttonSolidSecondary {
|
@mixin buttonSolidSecondary {
|
||||||
&.secondary {
|
&.secondary {
|
||||||
background-color: $colorSecondary;
|
background-color: $colorSecondary;
|
||||||
|
color: $colorWhite;
|
||||||
|
|
||||||
&:hover,
|
&:hover,
|
||||||
&:focus {
|
&:focus {
|
||||||
@ -590,34 +525,33 @@ $buttonBorderHover: $colorWhite;
|
|||||||
|
|
||||||
@mixin buttonSolidTertiary {
|
@mixin buttonSolidTertiary {
|
||||||
&.tertiary {
|
&.tertiary {
|
||||||
background-color: $colorSecondaryAlpha;
|
background-color: $colorSecondaryDark;
|
||||||
border: 1px solid $alphaWhite60;
|
color: $colorWhite;
|
||||||
|
border: 1px solid $alphaBlack30;
|
||||||
|
|
||||||
&:hover,
|
&:hover,
|
||||||
&:focus {
|
&:focus {
|
||||||
border: 1px solid $fontColorLightPrimary;
|
border: 1px solid $alphaBlack20;
|
||||||
background-color: $colorSecondaryDark;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
&:active {
|
&:active {
|
||||||
border: 1px solid $fontColorLightPrimary;
|
|
||||||
background-color: lighten($colorSecondaryDark, 10%);
|
background-color: lighten($colorSecondaryDark, 10%);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Border Radius */
|
/* Border Radius */
|
||||||
$borderRadiusXXXS: rem-calc(3);
|
$borderRadiusXXXS: 0;
|
||||||
$borderRadiusXXS: rem-calc(4);
|
$borderRadiusXXS: 0;
|
||||||
$borderRadiusXS: rem-calc(5);
|
$borderRadiusXS: 0;
|
||||||
$borderRadiusS: rem-calc(8);
|
$borderRadiusS: 0;
|
||||||
$borderRadiusM: rem-calc(9);
|
$borderRadiusM: 0;
|
||||||
$borderRadiusL: rem-calc(12);
|
$borderRadiusL: 0;
|
||||||
$borderRadiusXL: rem-calc(16);
|
$borderRadiusXL: 0;
|
||||||
$borderRadiusXXL: rem-calc(20);
|
$borderRadiusXXL: 0;
|
||||||
$borderRadiusXXXL: rem-calc(30);
|
$borderRadiusXXXL: 0;
|
||||||
$borderRadiusXXXXL: rem-calc(100);
|
$borderRadiusXXXXL: 0;
|
||||||
$borderRadiusRound: 50%;
|
$borderRadiusRound: 0;
|
||||||
|
|
||||||
/* Dimensions */
|
/* Dimensions */
|
||||||
$headerHeight: rem-calc(86);
|
$headerHeight: rem-calc(86);
|
||||||
|
@ -2,7 +2,7 @@ export enum QUERY_KEYS {
|
|||||||
BLOCK_HEIGHT = 'blockHeight',
|
BLOCK_HEIGHT = 'blockHeight',
|
||||||
MARS_BALANCE = 'marsBalance',
|
MARS_BALANCE = 'marsBalance',
|
||||||
MARS_ORACLE = 'marsOracle',
|
MARS_ORACLE = 'marsOracle',
|
||||||
MARS_PRICE = 'marsPrice',
|
SPOT_PRICE = 'spotPrice',
|
||||||
REDBANK = 'redbank',
|
REDBANK = 'redbank',
|
||||||
USER_BALANCE = 'userBalance',
|
USER_BALANCE = 'userBalance',
|
||||||
USER_DEBT = 'userDebt',
|
USER_DEBT = 'userDebt',
|
||||||
@ -15,4 +15,5 @@ export enum QUERY_KEYS {
|
|||||||
ESTIMATE_FARM_FEE = 'estimateFarmFee',
|
ESTIMATE_FARM_FEE = 'estimateFarmFee',
|
||||||
PROVIDE_LIQUIDITY = 'provideLiquidity',
|
PROVIDE_LIQUIDITY = 'provideLiquidity',
|
||||||
UNLOCK_MESSAGE = 'unlockMessage',
|
UNLOCK_MESSAGE = 'unlockMessage',
|
||||||
|
USD_PRICE = 'usdPrice',
|
||||||
}
|
}
|
||||||
|
6
src/types/interfaces/asset.d.ts
vendored
6
src/types/interfaces/asset.d.ts
vendored
@ -2,12 +2,12 @@ interface Asset {
|
|||||||
color: string
|
color: string
|
||||||
name: string
|
name: string
|
||||||
denom: string
|
denom: string
|
||||||
symbol: 'OSMO' | 'ATOM' | 'JUNO' | 'axlUSDC'
|
symbol: 'OSMO' | 'ATOM' | 'JUNO' | 'axlUSDC' | 'stATOM'
|
||||||
contract_addr?: string
|
contract_addr?: string
|
||||||
logo: string
|
logo: string
|
||||||
decimals: number
|
decimals: number
|
||||||
hasOraclePrice: boolean
|
|
||||||
poolId?: number
|
poolId?: number
|
||||||
|
poolBase?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
interface OtherAsset extends Omit<Asset, 'symbol'> {
|
interface OtherAsset extends Omit<Asset, 'symbol'> {
|
||||||
@ -33,6 +33,8 @@ interface RedBankAsset extends Asset {
|
|||||||
incentiveInfo?: IncentiveInfo
|
incentiveInfo?: IncentiveInfo
|
||||||
depositCap: number
|
depositCap: number
|
||||||
depositLiquidity: numnber
|
depositLiquidity: numnber
|
||||||
|
borrowEnabled: boolean
|
||||||
|
depositEnabled: boolean
|
||||||
// This is a hack, subRows can only contain same data model
|
// This is a hack, subRows can only contain same data model
|
||||||
subRows?: DepositAsset[]
|
subRows?: DepositAsset[]
|
||||||
}
|
}
|
||||||
|
7
src/types/interfaces/fields.d.ts
vendored
7
src/types/interfaces/fields.d.ts
vendored
@ -38,7 +38,8 @@ interface Position {
|
|||||||
amounts: {
|
amounts: {
|
||||||
primary: number
|
primary: number
|
||||||
secondary: number
|
secondary: number
|
||||||
borrowed: number
|
borrowedPrimary: number
|
||||||
|
borrowedSecondary: number
|
||||||
lp: {
|
lp: {
|
||||||
amount: string // Need to be string as number can be extremely large
|
amount: string // Need to be string as number can be extremely large
|
||||||
primary: number
|
primary: number
|
||||||
@ -49,7 +50,8 @@ interface Position {
|
|||||||
values: {
|
values: {
|
||||||
primary: number
|
primary: number
|
||||||
secondary: number
|
secondary: number
|
||||||
borrowed: number
|
borrowedPrimary: number
|
||||||
|
borrowedSecondary: number
|
||||||
total: number
|
total: number
|
||||||
net: number
|
net: number
|
||||||
}
|
}
|
||||||
@ -61,6 +63,7 @@ interface Position {
|
|||||||
ltv: number
|
ltv: number
|
||||||
currentLeverage: number
|
currentLeverage: number
|
||||||
unlockAtTimestamp?: number
|
unlockAtTimestamp?: number
|
||||||
|
borrowDenom: string | null
|
||||||
}
|
}
|
||||||
|
|
||||||
interface PositionBarItem {
|
interface PositionBarItem {
|
||||||
|
15
src/types/interfaces/networkConfig.d.ts
vendored
15
src/types/interfaces/networkConfig.d.ts
vendored
@ -4,6 +4,7 @@ interface NetworkConfig {
|
|||||||
rpcUrl: string
|
rpcUrl: string
|
||||||
restUrl: string
|
restUrl: string
|
||||||
apolloAprUrl: string
|
apolloAprUrl: string
|
||||||
|
priceApiUrl: string
|
||||||
contracts: {
|
contracts: {
|
||||||
redBank: string
|
redBank: string
|
||||||
incentives: string
|
incentives: string
|
||||||
@ -16,12 +17,14 @@ interface NetworkConfig {
|
|||||||
whitelist: Asset[]
|
whitelist: Asset[]
|
||||||
other: OtherAsset[]
|
other: OtherAsset[]
|
||||||
}
|
}
|
||||||
displayCurrency: {
|
displayCurrency: displayCurrency
|
||||||
denom: string
|
|
||||||
prefix: string
|
|
||||||
suffix: string
|
|
||||||
decimals: number
|
|
||||||
}
|
|
||||||
appUrl: string
|
appUrl: string
|
||||||
wallets: import('@marsprotocol/wallet-connector').WalletID[]
|
wallets: import('@marsprotocol/wallet-connector').WalletID[]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface DisplayCurrency {
|
||||||
|
denom: string
|
||||||
|
prefix: string
|
||||||
|
suffix: string
|
||||||
|
decimals: number
|
||||||
|
}
|
||||||
|
10
src/types/interfaces/redbank.d.ts
vendored
10
src/types/interfaces/redbank.d.ts
vendored
@ -1,5 +1,5 @@
|
|||||||
interface RedBankData {
|
interface RedBankData {
|
||||||
balance: {
|
balance?: {
|
||||||
balance: import('@cosmjs/stargate').Coin[]
|
balance: import('@cosmjs/stargate').Coin[]
|
||||||
}
|
}
|
||||||
rbwasmkey: {
|
rbwasmkey: {
|
||||||
@ -11,6 +11,8 @@ interface RedBankData {
|
|||||||
JUNOMarketIncentive: MarketIncentive
|
JUNOMarketIncentive: MarketIncentive
|
||||||
axlUSDCMarket: Market
|
axlUSDCMarket: Market
|
||||||
axlUSDCMarketIncentive: MarketIncentive
|
axlUSDCMarketIncentive: MarketIncentive
|
||||||
|
stATOMMarket: Market
|
||||||
|
stATOMMarketIncentive: MarketIncentive
|
||||||
collateral: UserCollateral[]
|
collateral: UserCollateral[]
|
||||||
unclaimedRewards: string
|
unclaimedRewards: string
|
||||||
}
|
}
|
||||||
@ -44,7 +46,9 @@ interface InterestRateModel {
|
|||||||
|
|
||||||
interface MarketIncentive {
|
interface MarketIncentive {
|
||||||
denom: string
|
denom: string
|
||||||
emission_per_second: number
|
emission_per_second: string
|
||||||
index: number
|
index: string
|
||||||
last_updated: number
|
last_updated: number
|
||||||
|
start_time: number
|
||||||
|
duration: number
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user