This commit is contained in:
Linkie Link 2023-08-02 11:25:13 +02:00
parent 2ebc64a9d9
commit 6b6d717fac
No known key found for this signature in database
GPG Key ID: 5318B0F2564D38EA
48 changed files with 2644 additions and 1430 deletions

View File

@ -29,13 +29,16 @@ Copy `.env.example` to `.env` and modify the values to suit your needs.
We allow the use of environment variables to be passed to the Docker container to specify custom endpoints for the app. The variables are:
| Variable | Description | Default |
| --------------------- | ------------------------------------------------ | ------------------------------------------------------------------------------------ |
| --------------------- | ------------------------------------------------ | ----------------------------------------------------------------------------------------- |
| URL_OSMOSIS_GQL | The Osmosis Hive GraphQL endpoint to use | https://osmosis-node.marsprotocol.io/GGSFGSFGFG34/osmosis-hive-front/graphql |
| URL_OSMOSIS_REST | The Osmosis node REST endpoint to use | https://lcd-osmosis.blockapsis.com |
| URL_OSMOSIS_RPC | The Osmosis node RPC endpoint to use | https://rpc-osmosis.blockapsis.com |
| URL_OSMOSIS_TEST_GQL | The Osmosis Testnet Hive GraphQL endpoint to use | https://testnet-osmosis-node.marsprotocol.io/XF32UOOU55CX/osmosis-hive-front/graphql |
| URL_OSMOSIS_TEST_REST | The Osmosis Testnet node REST endpoint to use | https://lcd.osmotest5.osmosis.zone |
| URL_OSMOSIS_TEST_RPC | The Osmosis Testnet node RPC endpoint to use | https://rpc.osmotest5.osmosis.zone |
| URL_NEUTRON_GQL | The Neutron Hive GraphQL endpoint to use | https://neutron.rpc.p2p.world/qgrnU6PsQZA8F9S5Fb8Fn3tV3kXmMBl2M9bcc9jWLjQy8p/hive/graphql |
| URL_NEUTRON_REST | The Neutron node REST endpoint to use | https://rest-kralum.neutron-1.neutron.org |
| URL_NEUTRON_RPC | The Neutron node RPC endpoint to use | https://rpc-kralum.neutron-1.neutron.org |
| URL_NEUTRON_TEST_GQL | The Neutron Testnet Hive GraphQL endpoint to use | https://testnet-neutron-gql.marsprotocol.io/graphql |
| URL_NEUTRON_TEST_REST | The Neutron Testnet node REST endpoint to use | https://rest-palvus.pion-1.ntrn.tech |
| URL_NEUTRON_TEST_RPC | The Neutron Testnet node RPC endpoint to use | https://rpc-palvus.pion-1.ntrn.tech |
@ -52,6 +55,9 @@ docker run -it -p 3000:3000 \
-e URL_OSMOSIS_TEST_GQL=https://testnet-osmosis-node.marsprotocol.io/XF32UOOU55CX/osmosis-hive-front/graphql \
-e URL_OSMOSIS_TEST_REST=https://lcd.osmotest5.osmosis.zone \
-e URL_OSMOSIS_TEST_RPC=https://rpc.osmotest5.osmosis.zone \
-e URL_NEUTRON_GQL=https://neutron.rpc.p2p.world/qgrnU6PsQZA8F9S5Fb8Fn3tV3kXmMBl2M9bcc9jWLjQy8p/hive/graphql \
-e URL_NEUTRON_REST=https://rest-palvus.pion-1.ntrn.tech \
-e URL_NEUTRON_RPC=https://rpc-palvus.pion-1.ntrn.tech \
-e URL_NEUTRON_TEST_GQL=https://testnet-neutron-gql.marsprotocol.io/graphql \
-e URL_NEUTRON_TEST_REST=https://rest-palvus.pion-1.ntrn.tech \
-e URL_NEUTRON_TEST_RPC=https://rpc-palvus.pion-1.ntrn.tech marsprotocol/interface:latest

View File

@ -10,6 +10,9 @@ echo "APP_NEXT_OSMOSIS_GQL=$URL_OSMOSIS_GQL" >> $envFilename
echo "APP_NEXT_OSMOSIS_TEST_RPC=$URL_OSMOSIS_TEST_RPC" >> $envFilename
echo "APP_NEXT_OSMOSIS_TEST_REST=$URL_OSMOSIS_TEST_REST" >> $envFilename
echo "APP_NEXT_OSMOSIS_TEST_GQL=$URL_OSMOSIS_TEST_GQL" >> $envFilename
echo "APP_NEXT_NEUTRON_RPC=$URL_NEUTRON_RPC" >> $envFilename
echo "APP_NEXT_NEUTRON_REST=$URL_NEUTRON_REST" >> $envFilename
echo "APP_NEXT_NEUTRON_GQL=$URL_NEUTRON_TEST_GQL" >> $envFilename
echo "APP_NEXT_NEUTRON_TEST_RPC=$URL_NEUTRON_TEST_RPC" >> $envFilename
echo "APP_NEXT_NEUTRON_TEST_REST=$URL_NEUTRON_TEST_REST" >> $envFilename
echo "APP_NEXT_NEUTRON_TEST_GQL=$URL_NEUTRON_TEST_GQL" >> $envFilename

View File

@ -1,7 +1,7 @@
{
"name": "mars",
"homepage": "./",
"version": "1.5.3",
"version": "1.6.0",
"license": "SEE LICENSE IN LICENSE FILE",
"private": false,
"scripts": {
@ -18,14 +18,15 @@
"test:coverage": "jest --coverage"
},
"dependencies": {
"@cosmjs/cosmwasm-stargate": "^0.30.1",
"@cosmjs/cosmwasm-stargate": "^0.31.0",
"@cosmjs/launchpad": "^0.27.1",
"@cosmjs/proto-signing": "^0.30.1",
"@cosmjs/stargate": "^0.30.1",
"@marsprotocol/wallet-connector": "^1.8.6",
"@cosmjs/proto-signing": "^0.31.0",
"@cosmjs/stargate": "^0.31.0",
"@marsprotocol/wallet-connector": "^1.9.6",
"@material-ui/core": "^4.12.4",
"@material-ui/icons": "^4.11.3",
"@ramonak/react-progress-bar": "^5.0.3",
"@sentry/nextjs": "^7.36.0",
"@tanstack/react-query": "^4.24.4",
"@tanstack/react-table": "^8.7.9",
"@testing-library/dom": "^8.20.0",

View File

@ -7,7 +7,6 @@ import {
WalletConnectionStatus,
} from '@marsprotocol/wallet-connector'
import { useQueryClient } from '@tanstack/react-query'
import { MARS_SYMBOL } from 'constants/appConstants'
import {
useBlockHeight,
useDepositAndDebt,
@ -18,8 +17,8 @@ import {
useUserDebt,
useUserIcns,
} from 'hooks/queries'
import { useMarsPrice } from 'hooks/queries/useMarsPrice'
import { usePythVaa } from 'hooks/queries/usePythVaa'
import { useSpotPrice } from 'hooks/queries/useSpotPrice'
import { useUserCollaterals } from 'hooks/queries/useUserCollaterals'
import { ReactNode, useEffect, useState } from 'react'
import useStore from 'store'
@ -52,7 +51,6 @@ export const CommonContainer = ({ children }: CommonContainerProps) => {
const networkConfig = useStore((s) => s.networkConfig)
const marketDeposits = useStore((s) => s.marketDeposits)
const marketInfo = useStore((s) => s.marketInfo)
const marketIncentiveInfo = useStore((s) => s.marketIncentiveInfo)
const migrationInProgress = useStore((s) => s.migrationInProgress)
const redBankState = useStore((s) => s.redBankState)
const rpc = useStore((s) => s.networkConfig.rpcUrl)
@ -145,7 +143,6 @@ export const CommonContainer = ({ children }: CommonContainerProps) => {
userBalancesState,
exchangeRates,
marketInfo,
marketIncentiveInfo,
userDebts,
userDeposits,
whitelistedAssets,
@ -168,7 +165,7 @@ export const CommonContainer = ({ children }: CommonContainerProps) => {
useUserDebt()
useUserCollaterals()
useMarsOracle()
useSpotPrice(MARS_SYMBOL)
useMarsPrice()
useDepositAndDebt()
useRedBank()
usePythVaa()

View File

@ -30,15 +30,17 @@ export const CosmosWalletConnectProvider = ({ children }: Props) => {
rpc: networkConfig.rpcUrl,
rest: networkConfig.restUrl,
}}
walletConnectProjectId='d93fdffb159bae5ec87d8fee4cdbb045'
chainIds={supportedChains}
closeIcon={<SVG.Close />}
defaultChainId={currentNetwork}
enabledWallets={[
WalletID.Keplr,
WalletID.Xdefi,
WalletID.StationWallet,
WalletID.Station,
WalletID.Leap,
WalletID.Cosmostation,
WalletID.Vectis,
WalletID.KeplrMobile,
WalletID.CosmostationMobile,
]}

View File

@ -65,7 +65,6 @@ export const ChainSelect = () => {
exchangeRates: [],
assetPricesUSD: [],
marketAssetLiquidity: [],
marketIncentiveInfo: [],
marketInfo: [],
userIcns: undefined,
redBankAssets: [],

View File

@ -5,7 +5,7 @@ import { findByDenom } from 'functions'
import { useUserBalance } from 'hooks/queries'
import { formatValue, lookup } from 'libs/parse'
import { truncate } from 'libs/text'
import { useCallback, useEffect, useState } from 'react'
import { useCallback, useEffect, useMemo, useState } from 'react'
import { useTranslation } from 'react-i18next'
import useClipboard from 'react-use-clipboard'
import useStore from 'store'
@ -61,6 +61,11 @@ export const ConnectedButton = () => {
baseCurrency.decimals,
)
const [connectedWalletAddress, connectedWalletIsLedger] = useMemo(() => {
if (!connectedWallet?.account) return ['', false]
return [connectedWallet.account.address, connectedWallet.account.isLedger]
}, [connectedWallet])
useEffect(() => {
if (!chainInfo) return
setIsTestnet(
@ -71,10 +76,10 @@ export const ConnectedButton = () => {
}, [chainInfo])
useEffect(() => {
if (userWalletAddress === connectedWallet?.account.address) return
if (userWalletAddress === connectedWalletAddress) return
useStore.setState({
isLedger: !!connectedWallet?.account.isLedger,
userWalletAddress: connectedWallet?.account.address,
isLedger: connectedWalletIsLedger,
userWalletAddress: connectedWalletAddress,
marketAssetLiquidity: [],
marketInfo: [],
userIcns: undefined,
@ -82,7 +87,7 @@ export const ConnectedButton = () => {
redBankState: State.INITIALISING,
userBalancesState: State.INITIALISING,
})
}, [connectedWallet?.account.address, userWalletAddress])
}, [connectedWalletAddress, connectedWalletIsLedger, userWalletAddress])
return (
<div className={styles.wrapper}>

View File

@ -10,13 +10,15 @@ import {
Tooltip,
TxLink,
} from 'components/common'
import { MARS_DECIMALS, MARS_SYMBOL } from 'constants/appConstants'
import { MARS_SYMBOL } from 'constants/appConstants'
import { findByDenom } from 'functions'
import { getClaimUserRewardsMsgOptions } from 'functions/messages'
import { useEstimateFee } from 'hooks/queries'
import { lookup, lookupDenomBySymbol, lookupSymbol } from 'libs/parse'
import { lookup, lookupSymbol } from 'libs/parse'
import { useCallback, useEffect, useMemo, useState } from 'react'
import { useTranslation } from 'react-i18next'
import useStore from 'store'
import { State } from 'types/enums'
import { QUERY_KEYS } from 'types/enums/queryKeys'
import styles from './IncentivesButton.module.scss'
@ -32,9 +34,13 @@ export const IncentivesButton = () => {
// STORE STATE
// ---------------
const client = useStore((s) => s.client)
const whitelistedAssets = useStore((s) => s.whitelistedAssets)
const otherAssets = useStore((s) => s.otherAssets)
const userWalletAddress = useStore((s) => s.userWalletAddress)
const networkConfig = useStore((s) => s.networkConfig)
const unclaimedRewards = useStore((s) => s.userUnclaimedRewards)
const convertToDisplayCurrency = useStore((s) => s.convertToDisplayCurrency)
const marsPriceState = useStore((s) => s.marsPriceState)
const incentivesContractAddress = useStore((s) => s.networkConfig.contracts.incentives)
const chainInfo = useStore((s) => s.chainInfo)
const executeMsg = useStore((s) => s.executeMsg)
@ -49,12 +55,13 @@ export const IncentivesButton = () => {
const [response, setResponse] = useState<TxBroadcastResult>()
const [error, setError] = useState<string>()
const [hasUnclaimedRewards, setHasUnclaimedRewards] = useState(false)
const [unclaimedRewardsValue, setUnclaimedRewardsValue] = useState(0)
// ---------------
// LOCAL VARIABLES
// ---------------
const marsDenom = lookupDenomBySymbol(MARS_SYMBOL, otherAssets)
const explorerUrl = chainInfo && SimpleChainInfoList[chainInfo.chainId as ChainInfoID].explorer
const assets = [...whitelistedAssets, ...otherAssets]
// ---------------
// FUNCTIONS
@ -66,8 +73,18 @@ export const IncentivesButton = () => {
}, [])
useEffect(() => {
setHasUnclaimedRewards(Number(unclaimedRewards) > 0)
}, [unclaimedRewards])
let rewardsValue = 0
let rewardsAmount = 0
if (marsPriceState !== State.READY) return
unclaimedRewards.forEach((reward) => {
rewardsValue += convertToDisplayCurrency(reward)
rewardsAmount += Number(reward.amount)
})
setUnclaimedRewardsValue(rewardsValue)
setHasUnclaimedRewards(rewardsAmount > 0)
}, [unclaimedRewards, convertToDisplayCurrency, marsPriceState])
const txMsgOptions = useMemo(() => {
if (!hasUnclaimedRewards) return
@ -137,31 +154,39 @@ export const IncentivesButton = () => {
}
const transactionHash = response?.hash || ''
if (!userWalletAddress) return null
return (
<div className={styles.wrapper}>
<button
className={classNames(
Number(unclaimedRewards) > 1000000
? `${styles.button} ${styles.buttonHighlight}`
: styles.button,
unclaimedRewardsValue > 1 ? `${styles.button} ${styles.buttonHighlight}` : styles.button,
)}
onClick={() => {
setShowDetails(!showDetails)
}}
>
{networkConfig.hasMultiAssetIncentives ? (
<AnimatedNumber
amount={unclaimedRewardsValue}
minDecimals={2}
maxDecimals={2}
prefix='$'
/>
) : (
<>
<SVG.Logo />
<span>
<AnimatedNumber
amount={Number(unclaimedRewards) / 1e6}
className={styles.marsAmount}
amount={Number(unclaimedRewards[0]?.amount ?? 0) / 1e6}
minDecimals={2}
maxDecimals={2}
className={styles.marsAmount}
/>
{MARS_SYMBOL}
</span>
{MARS_SYMBOL}
</>
)}
</button>
{showDetails && (
@ -181,36 +206,48 @@ export const IncentivesButton = () => {
<TxLink hash={transactionHash} link={`${explorerUrl}/txs/${transactionHash}`} />
</div>
) : (
<div className={styles.container}>
<>
{unclaimedRewards.map((rewards, index) => {
const asset = findByDenom(assets, rewards.denom)
if (!asset) return null
return (
<div className={styles.container} key={index}>
<div className={styles.position}>
<div className={styles.label}>
<p className={styles.token}>{lookupSymbol(marsDenom, otherAssets)}</p>
<p className={styles.token}>{lookupSymbol(asset.denom, assets)}</p>
<p className={styles.subhead}>{t('redbank.redBankRewards')}</p>
</div>
<div className={styles.value}>
<AnimatedNumber
className={styles.tokenAmount}
amount={lookup(Number(unclaimedRewards) || 0, MARS_SYMBOL, MARS_DECIMALS)}
maxDecimals={MARS_DECIMALS}
amount={lookup(
Number(rewards.amount) || 0,
asset.symbol,
asset.decimals,
)}
maxDecimals={asset.decimals}
minDecimals={2}
/>
<DisplayCurrency
className={styles.tokenValue}
coin={{
amount: unclaimedRewards,
denom: marsDenom,
amount: rewards.amount,
denom: asset.denom,
}}
/>
</div>
</div>
</div>
)
})}
</>
)}
<div className={styles.claimButton}>
<Button
disabled={disabled}
showProgressIndicator={fetching}
text={
Number(unclaimedRewards) > 0 && !disabled
hasUnclaimedRewards && !disabled
? t('incentives.claimRewards')
: t('incentives.nothingToClaim')
}

View File

@ -31,12 +31,13 @@ export const Apr = ({ data }: Props) => {
subtitle: key === 0 ? t('incentives.interestApr') : t('incentives.depositRewards'),
})
})
return items
}
useEffect(
() => {
const baseData = data.incentiveInfo ? [data, data.incentiveInfo] : [data]
const baseData = data.incentiveInfo ? [data, ...data.incentiveInfo] : [data]
setAprData(produceData(baseData))
},
// eslint-disable-next-line react-hooks/exhaustive-deps

View File

@ -225,14 +225,7 @@ export const Action = ({
const assetLiquidity = Number(findByDenom(marketAssetLiquidity, denom)?.amount || 0)
return maxBorrowableAmount(assetLiquidity, availableBalanceBaseCurrency, currentAssetPrice)
}, [
denom,
availableBalanceBaseCurrency,
currentAssetPrice,
marketAssetLiquidity,
baseCurrency.decimals,
currentAsset?.decimals,
])
}, [denom, availableBalanceBaseCurrency, currentAssetPrice, marketAssetLiquidity])
const repayMax = Math.min(assetBorrowBalance, walletBalance)

View File

@ -21,18 +21,23 @@ export const ActionsRow = ({ row, type }: Props) => {
const redBankAssets = useStore((s) => s.redBankAssets)
const assetPricesUSD = useStore((s) => s.assetPricesUSD)
const hasBalance = Number(row.original.walletBalance ?? 0) > 0
const hasDeposits = Number(row.original.depositBalance ?? 0) > 0
const hasNeverDeposited = Number(balanceSum(redBankAssets, 'depositBalanceBaseCurrency')) === 0
const appUrl = useStore((s) => s.networkConfig.appUrl) || ''
const networkConfig = useStore((s) => s.networkConfig)
const appUrl = networkConfig.appUrl
const classes = classNames.bind(styles)
const trClasses = classes({
tr: true,
expanded: row.getIsExpanded(),
})
const assetID = row.original.id
const assetPrice = assetPricesUSD?.find((asset) => asset.denom === row.original.denom)?.amount
const fromAsset =
networkConfig.assets.base.denom === row.original.denom
? networkConfig.assets.whitelist[1]
: networkConfig.assets.base
const toAsset = row.original
const assetID = row.original.id
return (
<tr key={row.id} className={trClasses} onClick={() => row.toggleExpanded()}>
@ -46,7 +51,9 @@ export const ActionsRow = ({ row, type }: Props) => {
window.open(
getSwapUrl({
baseUrl: appUrl,
to: assetID,
from: fromAsset,
to: toAsset,
chain: networkConfig.name,
}),
)
}}
@ -99,7 +106,9 @@ export const ActionsRow = ({ row, type }: Props) => {
window.open(
getSwapUrl({
baseUrl: appUrl,
to: assetID,
from: fromAsset,
to: toAsset,
chain: networkConfig.name,
}),
)
}}

View File

@ -73,13 +73,24 @@ export const useDepositColumns = () => {
header: () => (
<TextTooltip text={t('common.apr')} tooltip={t('redbank.tooltips.deposit.apy')} />
),
cell: (info) =>
info.row.original.borrowEnabled ? (
cell: (info) => {
const isEnabled = info.row.original.borrowEnabled
const incentives = info.row.original.incentiveInfo
let borrowApy = 0
if (!!incentives) {
incentives.forEach((incentive) => {
borrowApy += Number(incentive.apy)
})
}
if (isEnabled)
return (
<TextTooltip
hideStyling
text={
<AnimatedNumber
amount={info.getValue() + Number(info.row.original.incentiveInfo?.apy || 0)}
amount={info.getValue() + borrowApy}
suffix='%'
abbreviated={false}
rounded={false}
@ -88,7 +99,8 @@ export const useDepositColumns = () => {
}
tooltip={<Apr data={info.row.original} />}
/>
) : (
)
return (
<TextTooltip
text=''
hideUnderline
@ -97,7 +109,8 @@ export const useDepositColumns = () => {
symbol: info.row.original.symbol,
})}
/>
),
)
},
}),
columnHelper.accessor('depositCap', {
enableSorting: enableSorting,

View File

@ -180,6 +180,9 @@ export const RedbankAction = React.memo(
}
const handleClose = () => {
queryClient.invalidateQueries([QUERY_KEYS.REDBANK])
queryClient.invalidateQueries([QUERY_KEYS.USER_DEPOSIT])
queryClient.invalidateQueries([QUERY_KEYS.USER_DEBT])
reset()
// path on redbank action will always be /redbank/deposit/<denom> etce
@ -236,10 +239,7 @@ export const RedbankAction = React.memo(
error={error}
handleClose={handleClose}
onSuccess={() => {
queryClient.invalidateQueries([QUERY_KEYS.USER_DEPOSIT])
queryClient.invalidateQueries([QUERY_KEYS.REDBANK])
queryClient.invalidateQueries([QUERY_KEYS.USER_BALANCE])
queryClient.invalidateQueries([QUERY_KEYS.USER_DEBT])
}}
response={response}
title={t('common.summaryOfTheTransaction')}

101
src/configs/neutron-1.ts Normal file
View File

@ -0,0 +1,101 @@
import { ChainInfoID } from '@marsprotocol/wallet-connector'
import atom from 'images/atom.svg'
import axlusdc from 'images/axlusdc.svg'
import mars from 'images/mars.svg'
import ntrn from 'images/ntrn.svg'
import osmo from 'images/osmo.svg'
import colors from 'styles/_assets.module.scss'
export const ASSETS: NetworkAssets = {
ntrn: {
symbol: 'NTRN',
name: 'Neutron',
id: 'NTRN',
denom: 'untrn',
color: colors.ntrn,
logo: ntrn,
decimals: 6,
priceFeedId: 'a8e6517966a52cb1df864b2764f3629fde3f21d2b640b5c572fcd654cbccd65e',
},
axlusdc: {
symbol: 'USDC.axl',
name: 'Axelar USDC',
id: 'axlUSDC',
denom: 'ibc/F082B65C88E4B6D5EF1DB243CDA1D331D002759E938A0F5CD3FFDC5D53B3E349',
color: colors.usdc,
decimals: 6,
logo: axlusdc,
priceFeedId: 'eaa020c61cc479712813461ce153894a96a6c00b21ed0cfc2798d1f9a9e9c94a',
},
atom: {
symbol: 'ATOM',
name: 'Atom',
id: 'ATOM',
denom: 'ibc/C4CFF46FD6DE35CA4CF4CE031E643C8FDC9BA4B99AE598E9B0ED98FE3A2319F9',
color: colors.atom,
logo: atom,
decimals: 6,
priceFeedId: 'b00b60f88b03a6a625a8d1c048c3f66653edf217439983d037e7222c4e612819',
},
}
const OTHER_ASSETS: { [denom: string]: OtherAsset } = {
mars: {
symbol: 'MARS',
id: 'MARS',
name: 'Mars',
denom: 'ibc/9598CDEB7C6DB7FC21E746C8E0250B30CD5154F39CA111A9D4948A4362F638BD',
color: colors.mars,
logo: mars,
decimals: 6,
},
osmo: {
symbol: 'OSMO',
name: 'Osmosis',
id: 'OSMO',
denom: 'uosmo',
color: colors.osmo,
logo: osmo,
decimals: 6,
priceFeedId: '5867f5683c757393a0670ef0f701490950fe93fdb006d181c8265a831ac0c5c6',
},
usd: {
symbol: '',
prefix: '$',
name: 'US Dollar',
denom: 'usd',
color: '',
logo: '',
decimals: 2,
},
}
export const NETWORK_CONFIG: NetworkConfig = {
name: ChainInfoID.Neutron,
displayName: 'Neutron',
hiveUrl:
process.env.NEXT_PUBLIC_NEUTRON_GQL ??
'https://neutron.rpc.p2p.world/qgrnU6PsQZA8F9S5Fb8Fn3tV3kXmMBl2M9bcc9jWLjQy8p/hive/graphql',
rpcUrl: process.env.NEXT_PUBLIC_NEUTRON_RPC ?? 'https://rpc-kralum.neutron-1.neutron.org',
restUrl: process.env.NEXT_PUBLIC_NEUTRON_REST ?? 'https://rest-kralum.neutron-1.neutron.org',
usdPriceUrl: 'https://xc-mainnet.pyth.network/api/',
chainIcon: ntrn,
contracts: {
redBank: 'neutron1n97wnm7q6d2hrcna3rqlnyqw2we6k0l8uqvmyqq6gsml92epdu7quugyph',
incentives: 'neutron1aszpdh35zsaz0yj80mz7f5dtl9zq5jfl8hgm094y0j0vsychfekqxhzd39',
oracle: 'neutron1dwp6m7pdrz6rnhdyrx5ha0acsduydqcpzkylvfgspsz60pj2agxqaqrr7g',
pyth: 'neutron1m2emc93m9gpwgsrsf2vylv9xvgqh654630v7dfrhrkmr5slly53spg85wv',
},
assets: {
base: ASSETS.ntrn,
whitelist: [ASSETS.axlusdc, ASSETS.ntrn, ASSETS.atom],
other: [OTHER_ASSETS.usd, OTHER_ASSETS.mars, OTHER_ASSETS.osmo],
currencies: [OTHER_ASSETS.usd, ASSETS.axlusdc, ASSETS.ntrn, ASSETS.atom, OTHER_ASSETS.mars],
},
displayCurrency: OTHER_ASSETS.usd,
appUrl: 'https://neutron.astroport.fi/swap',
isFieldsEnabled: false,
hasMultiAssetIncentives: true,
}
export const VAULT_CONFIGS: Vault[] = []

View File

@ -3,7 +3,6 @@ import atom from 'images/atom.svg'
import axl from 'images/axl.svg'
import axlusdc from 'images/axlusdc.svg'
import mars from 'images/mars.svg'
import nusdc from 'images/nusdc.svg'
import osmo from 'images/osmo.svg'
import colors from 'styles/_assets.module.scss'
@ -36,6 +35,7 @@ const ASSETS: NetworkAssets = {
color: colors.axl,
logo: axl,
decimals: 6,
priceFeedId: '60144b1d5c9e9851732ad1d9760e3485ef80be39b984f6bf60f82b28a2b7f126',
},
axlusdc: {
symbol: 'USDC.axl',
@ -47,16 +47,6 @@ const ASSETS: NetworkAssets = {
logo: axlusdc,
priceFeedId: 'eaa020c61cc479712813461ce153894a96a6c00b21ed0cfc2798d1f9a9e9c94a',
},
nusdc: {
symbol: 'USDC.n',
name: 'Noble USDC',
id: 'nUSDC',
denom: 'ibc/B3504E092456BA618CC28AC671A71FB08C6CA0FD0BE7C8A5B5A3E2DD933CC9E4',
color: colors.usdc,
decimals: 6,
logo: nusdc,
priceFeedId: 'eaa020c61cc479712813461ce153894a96a6c00b21ed0cfc2798d1f9a9e9c94a',
},
}
const OTHER_ASSETS: { [denom: string]: OtherAsset } = {
@ -68,7 +58,6 @@ const OTHER_ASSETS: { [denom: string]: OtherAsset } = {
color: colors.mars,
logo: mars,
decimals: 6,
poolId: 9,
},
usd: {
symbol: '',
@ -95,14 +84,14 @@ export const NETWORK_CONFIG: NetworkConfig = {
contracts: {
redBank: 'osmo1dl4rylasnd7mtfzlkdqn2gr0ss4gvyykpvr6d7t5ylzf6z535n9s5jjt8u',
incentives: 'osmo1zyz57xf82963mcsgqu3hq5y0h9mrltm4ttq2qe5mjth9ezp3375qe0sm7d',
oracle: 'osmo1tx9987hjkx3kc9jvxmdzaf9uz8ukzscl88c476r7854205rkhecsc20tnk',
oracle: 'osmo1khe29uw3t85nmmp3mtr8dls7v2qwsfk3tndu5h4w5g2r5tzlz5qqarq2e2',
creditManager: 'osmo15ywk53ck3wp6tnqgedfd8cnfx7fuhz9dr583hw8scp0xjgw46m0sf3kyyp',
accountNft: 'osmo1ye2rntzz9qmxgv7eg09supww6k6xs0y0sekcr3x5clp087fymn4q3y33s4',
pyth: 'osmo12u2vqdecdte84kg6c3d40nwzjsya59hsj048n687m9q3t6wdmqgsq6zrlx',
},
assets: {
base: ASSETS.osmo,
whitelist: [ASSETS.osmo, ASSETS.atom, ASSETS.axl, ASSETS.axlusdc, ASSETS.nusdc],
whitelist: [ASSETS.osmo, ASSETS.atom, ASSETS.axl, ASSETS.axlusdc],
other: [OTHER_ASSETS.usd, OTHER_ASSETS.mars],
currencies: [
OTHER_ASSETS.usd,
@ -110,7 +99,6 @@ export const NETWORK_CONFIG: NetworkConfig = {
ASSETS.atom,
ASSETS.axl,
ASSETS.axlusdc,
ASSETS.nusdc,
OTHER_ASSETS.mars,
],
},
@ -121,21 +109,21 @@ export const NETWORK_CONFIG: NetworkConfig = {
export const VAULT_CONFIGS: Vault[] = [
{
address: 'osmo1q40xvrzpldwq5he4ftsf7zm2jf80tj373qaven38yqrvhex8r9rs8n94kv',
name: { name: 'OSMO-USDC.n LP', unlockDuration: 1, unlockTimeframe: 'day' },
address: 'osmo1m45ap4rq4m2mfjkcqu9ks9mxmyx2hvx0cdca9sjmrg46q7lghzqqhxxup5',
name: { name: 'OSMO-ATOM LP', unlockDuration: 1, unlockTimeframe: 'day' },
denoms: {
primary: 'uosmo',
secondary: 'ibc/B3504E092456BA618CC28AC671A71FB08C6CA0FD0BE7C8A5B5A3E2DD933CC9E4',
lpToken: 'gamm/pool/6',
secondary: 'ibc/A8C2D23A1E6F95DA4E48BA349667E322BD7A6C996D8A4AAE8BA72E190F3D1477',
lpToken: 'gamm/pool/12',
},
symbols: {
primary: 'OSMO',
secondary: 'USDC.n',
secondary: 'ATOM',
},
color: colors.usdc,
lockup: 86400 * 1,
provider: 'Apollo vault',
description: { maxLeverage: 1.43, lpName: 'OSMO-USDC.n' },
description: { maxLeverage: 1.43, lpName: 'OSMO-ATOM' },
ltv: {
max: 0.295,
contract: 0.3,
@ -150,48 +138,20 @@ export const VAULT_CONFIGS: Vault[] = [
},
{
address: 'osmo14lu7m4ganxs20258dazafrjfaulmfxruq9n0r0th90gs46jk3tuqwfkqwn',
name: { name: 'OSMO-USDC.n LP', unlockDuration: 7, unlockTimeframe: 'days' },
name: { name: 'OSMO-USDC.axl LP', unlockDuration: 7, unlockTimeframe: 'days' },
denoms: {
primary: 'uosmo',
secondary: 'ibc/B3504E092456BA618CC28AC671A71FB08C6CA0FD0BE7C8A5B5A3E2DD933CC9E4',
lpToken: 'gamm/pool/6',
secondary: 'ibc/6F34E1BD664C36CE49ACC28E60D62559A5F96C4F9A6CCE4FC5A67B2852E24CFE',
lpToken: 'gamm/pool/5',
},
symbols: {
primary: 'OSMO',
secondary: 'USDC.n',
secondary: 'USDC.axl',
},
color: colors.usdc,
lockup: 86400 * 7,
provider: 'Apollo vault',
description: { maxLeverage: 1.43, lpName: 'OSMO-USDC.n' },
ltv: {
max: 0.295,
contract: 0.3,
liq: 0.4,
},
apy: {
apys: null,
fees: null,
total: null,
vaultAddress: '',
},
},
{
address: 'osmo1fmq9hw224fgz8lk48wyd0gfg028kvvzggt6c3zvnaqkw23x68cws5nd5em',
name: { name: 'OSMO-USDC.n LP', unlockDuration: 14, unlockTimeframe: 'days' },
denoms: {
primary: 'uosmo',
secondary: 'ibc/B3504E092456BA618CC28AC671A71FB08C6CA0FD0BE7C8A5B5A3E2DD933CC9E4',
lpToken: 'gamm/pool/6',
},
symbols: {
primary: 'OSMO',
secondary: 'USDC.n',
},
color: colors.usdc,
lockup: 86400 * 14,
provider: 'Apollo vault',
description: { maxLeverage: 1.43, lpName: 'OSMO-USDC.n' },
description: { maxLeverage: 1.43, lpName: 'OSMO-USDC.axl' },
ltv: {
max: 0.295,
contract: 0.3,

View File

@ -90,7 +90,6 @@ const OTHER_ASSETS: { [denom: string]: OtherAsset } = {
color: colors.mars,
logo: mars,
decimals: 6,
poolId: 907,
},
usd: {
symbol: '',
@ -166,11 +165,11 @@ export const VAULT_CONFIGS: Vault[] = [
color: '#6f7390',
lockup: 86400 * 14,
provider: 'Apollo vault',
description: { maxLeverage: 2.7, lpName: 'OSMO-ATOM' },
description: { maxLeverage: 3.7, lpName: 'OSMO-ATOM' },
ltv: {
max: 0.625,
contract: 0.63,
liq: 0.65,
max: 0.725,
contract: 0.73,
liq: 0.75,
},
apy: {
apys: null,
@ -194,11 +193,11 @@ export const VAULT_CONFIGS: Vault[] = [
color: '#478edc',
lockup: 86400 * 14,
provider: 'Apollo vault',
description: { maxLeverage: 2.86, lpName: 'OSMO-USDC.axl' },
description: { maxLeverage: 4, lpName: 'OSMO-USDC.axl' },
ltv: {
max: 0.645,
contract: 0.65,
liq: 0.66,
max: 0.745,
contract: 0.75,
liq: 0.77,
},
apy: {
apys: null,
@ -222,11 +221,11 @@ export const VAULT_CONFIGS: Vault[] = [
color: '#a446db',
lockup: 86400 * 14,
provider: 'Apollo vault',
description: { maxLeverage: 2.56, lpName: 'stATOM-ATOM' },
description: { maxLeverage: 2.78, lpName: 'stATOM-ATOM' },
ltv: {
max: 0.6,
contract: 0.61,
liq: 0.625,
max: 0.635,
contract: 0.64,
liq: 0.65,
},
apy: {
apys: null,
@ -250,11 +249,11 @@ export const VAULT_CONFIGS: Vault[] = [
color: colors.wbtc,
lockup: 86400 * 14,
provider: 'Apollo vault',
description: { maxLeverage: 2.44, lpName: 'OSMO-WBTC.axl' },
description: { maxLeverage: 4, lpName: 'OSMO-WBTC.axl' },
ltv: {
max: 0.58,
contract: 0.59,
liq: 0.62,
max: 0.745,
contract: 0.75,
liq: 0.77,
},
apy: {
apys: null,
@ -278,11 +277,11 @@ export const VAULT_CONFIGS: Vault[] = [
color: colors.weth,
lockup: 86400 * 14,
provider: 'Apollo vault',
description: { maxLeverage: 2.86, lpName: 'OSMO-WETH.axl' },
description: { maxLeverage: 4, lpName: 'OSMO-WETH.axl' },
ltv: {
max: 0.645,
contract: 0.65,
liq: 0.67,
max: 0.745,
contract: 0.75,
liq: 0.77,
},
apy: {
apys: null,

View File

@ -3,6 +3,7 @@ import atom from 'images/atom.svg'
import axlusdc from 'images/axlusdc.svg'
import mars from 'images/mars.svg'
import ntrn from 'images/ntrn.svg'
import osmo from 'images/osmo.svg'
import colors from 'styles/_assets.module.scss'
export const ASSETS: NetworkAssets = {
@ -14,6 +15,7 @@ export const ASSETS: NetworkAssets = {
color: colors.ntrn,
logo: ntrn,
decimals: 6,
priceFeedId: 'a8e6517966a52cb1df864b2764f3629fde3f21d2b640b5c572fcd654cbccd65e',
},
atom: {
symbol: 'ATOM',
@ -23,15 +25,17 @@ export const ASSETS: NetworkAssets = {
color: colors.atom,
logo: atom,
decimals: 6,
priceFeedId: 'b00b60f88b03a6a625a8d1c048c3f66653edf217439983d037e7222c4e612819',
},
axlusdc: {
symbol: 'USDC.axl',
name: 'Axelar USDC',
id: 'axlUSDC',
denom: 'ibc/EFB00E728F98F0C4BBE8CA362123ACAB466EDA2826DC6837E49F4C1902F21BBA',
denom: 'ibc/F91EA2C0A23697A1048E08C2F787E3A58AC6F706A1CD2257A504925158CFC0F3',
color: colors.usdc,
decimals: 6,
logo: axlusdc,
priceFeedId: 'eaa020c61cc479712813461ce153894a96a6c00b21ed0cfc2798d1f9a9e9c94a',
},
}
@ -40,11 +44,21 @@ const OTHER_ASSETS: { [denom: string]: OtherAsset } = {
symbol: 'MARS',
id: 'MARS',
name: 'Mars',
denom: 'ibc/FAD9EE91F499D275D9135F95F52D59D90C621B8438A9CFF1757BB886EEE90E3E',
denom: 'ibc/584A4A23736884E0C198FD1EE932455A9357A492A7B94324E4A02B5628687831',
color: colors.mars,
logo: mars,
decimals: 6,
},
osmo: {
symbol: 'OSMO',
name: 'Osmosis',
id: 'OSMO',
denom: 'uosmo',
color: colors.osmo,
logo: osmo,
decimals: 6,
priceFeedId: '5867f5683c757393a0670ef0f701490950fe93fdb006d181c8265a831ac0c5c6',
},
usd: {
symbol: '',
prefix: '$',
@ -64,21 +78,24 @@ export const NETWORK_CONFIG: NetworkConfig = {
'https://testnet-neutron-gql.marsprotocol.io/graphql',
rpcUrl: process.env.NEXT_PUBLIC_NEUTRON_TEST_RPC ?? 'https://rpc-palvus.pion-1.ntrn.tech/',
restUrl: process.env.NEXT_PUBLIC_NEUTRON_TEST_REST ?? 'https://rest-palvus.pion-1.ntrn.tech/',
usdPriceUrl: 'https://xc-mainnet.pyth.network/api/',
chainIcon: ntrn,
contracts: {
redBank: 'neutron15dld0kmz0zl89zt4yeks4gy8mhmawy3gp4x5rwkcgkj5krqvu9qs4q7wve',
incentives: 'neutron1t8fectc2ntxhuee2f9ty2mxh8l0ykzm6yxfsp9k35vdktksm2vfsd2d6rl',
oracle: 'neutron1nx9txtmpmkt58gxka20z72wdkguw4n0606zkeqvelv7q7uc06zmsym3qgx',
redBank: 'neutron1q53jr6wwus0c6g5had2zs6fzzachu5zun0c6etxuyarh5w7phxpq4wf39z',
incentives: 'neutron1pg2fxw87fkzfwyn8q45hes4mmlt4ywjg53hf655mh83edd9yq65quqe07u',
oracle: 'neutron1u3lmzs3zhhhlvkmrnq9u4ep6pgqp3gxawt3xg82hl9jydwmug7jsgmhjrn',
pyth: 'neutron1f86ct5az9qpz2hqfd5uxru02px2a3tz5zkw7hugd7acqq496dcms22ehpy',
},
assets: {
base: ASSETS.ntrn,
whitelist: [ASSETS.ntrn, ASSETS.atom, ASSETS.axlusdc],
other: [OTHER_ASSETS.usd, OTHER_ASSETS.mars],
other: [OTHER_ASSETS.usd, OTHER_ASSETS.mars, OTHER_ASSETS.osmo],
currencies: [OTHER_ASSETS.usd, ASSETS.ntrn, ASSETS.atom, ASSETS.axlusdc, OTHER_ASSETS.mars],
},
displayCurrency: OTHER_ASSETS.usd,
appUrl: 'https://app.astroport.fi/swap',
appUrl: 'https://testnet-neutron.astroport.fi/swap',
isFieldsEnabled: false,
hasMultiAssetIncentives: true,
}
export const VAULT_CONFIGS: Vault[] = []

View File

@ -37,6 +37,7 @@ export const TERMS_OF_SERVICE = 'termsOfService'
/* chains */
export const SUPPORTED_CHAINS: { chainId: ChainInfoID; type: 'testnet' | 'mainnet' }[] = [
{ chainId: ChainInfoID.Osmosis1, type: 'mainnet' },
{ chainId: ChainInfoID.Neutron, type: 'mainnet' },
{ chainId: ChainInfoID.OsmosisTestnet, type: 'testnet' },
{ chainId: ChainInfoID.NeutronTestnet, type: 'testnet' },
]

View File

@ -1,19 +1,34 @@
import { ChainInfoID } from '@marsprotocol/wallet-connector'
type Options = {
from?: string
to: string
from: Asset
to: Asset
baseUrl: string
chain?: ChainInfoID
}
export const getSwapUrl = (options: Options) => {
const { from, to, baseUrl } = options
let fromName = from
let toName = to
const { from, to, baseUrl, chain } = options
let fromName: string
let toName: string
if (!fromName) fromName = 'OSMO'
if (fromName === to) fromName = 'ATOM'
if (to === 'axlUSDC') toName = 'USDC'
if (to === 'axlWBTC') toName = 'WBTC'
if (to === 'axlWETH') toName = 'ETH'
if (!chain) return '#'
if (chain === ChainInfoID.Osmosis1 || chain === ChainInfoID.OsmosisTestnet) {
fromName = from.id
toName = to.id
if (fromName === to.id) fromName = 'ATOM'
if (to.id === 'axlUSDC') toName = 'USDC'
if (to.id === 'axlWBTC') toName = 'WBTC'
if (to.id === 'axlWETH') toName = 'ETH'
return `${baseUrl}?from=${fromName}&to=${toName}`
}
if (chain === ChainInfoID.Neutron || chain === ChainInfoID.NeutronTestnet) {
fromName = from.denom.replace('/', '%2F')
toName = to.denom.replace('/', '%2F')
return `${baseUrl}?from=${fromName}&to=${toName}`
}
}

View File

@ -46,7 +46,6 @@ export const getDepositDebtQuery = (
}
}`,
)
return query
})

View File

@ -1,7 +1,10 @@
export const getIncentiveQuery = (denom: string) => {
export const getIncentiveQuery = (denom: string, hasMultiAssetIncentives: boolean) => {
const queryMethod = hasMultiAssetIncentives ? 'active_emissions' : 'asset_incentive'
const queryKey = hasMultiAssetIncentives ? 'collateral_denom' : 'denom'
return `{
asset_incentive: {
denom: "${denom}"
${queryMethod}: {
${queryKey}: "${denom}"
}
}`
}

View File

@ -12,6 +12,7 @@ export const getRedbankQuery = (
address: string,
redBankContractAddress: string,
incentivesContractAddress: string,
hasMultiAssetIncentives: boolean,
whitelistedAssets?: Asset[],
) => {
const wasmQueries = whitelistedAssets?.map((asset: Asset) => {
@ -38,7 +39,7 @@ export const getRedbankQuery = (
getContractQuery(
incentiveKey,
incentivesContractAddress || '',
getIncentiveQuery(asset.denom || ''),
getIncentiveQuery(asset.denom || '', hasMultiAssetIncentives),
)
return query
})

View File

@ -6,12 +6,12 @@ export { useEditPosition } from './useEditPosition'
export { useEstimateFarmFee } from './useEstimateFarmFee'
export { useEstimateFee } from './useEstimateFee'
export { useMarsOracle } from './useMarsOracle'
export { useMarsPrice } from './useMarsPrice'
export { useProvideLiquidity } from './useProvideLiquidity'
export { usePythVaa } from './usePythVaa'
export { useRedBank } from './useRedBank'
export { useRepayPosition } from './useRepayPosition'
export { useRequestUnlockPosition } from './useRequestUnlockPosition'
export { useSpotPrice } from './useSpotPrice'
export { useUnlockMessages } from './useUnlockMessages'
export { useUsdPrice } from './useUsdPrice'
export { useUserBalance } from './useUserBalance'

View File

@ -11,6 +11,8 @@ export interface DepositAndDebtData {
OSMODebt: string
ATOMDeposits: string
ATOMDebt: string
ASTRODeposits: string
ASTRODebt: string
AXLDeposits: string
AXLDebt: string
JUNODeposits: string

View File

@ -9,7 +9,6 @@ export const useMarsOracle = () => {
const hiveUrl = useStore((s) => s.networkConfig.hiveUrl)
const oracleAddress = useStore((s) => s.networkConfig.contracts.oracle)
const whitelistedAssets = useStore((s) => s.whitelistedAssets) || []
const basePriceState = useStore((s) => s.basePriceState)
const processMarsOracleQuery = useStore((s) => s.processMarsOracleQuery)
const setExchangeRatesState = useStore((s) => s.setExchangeRatesState)
@ -42,7 +41,7 @@ export const useMarsOracle = () => {
[QUERY_KEYS.MARS_ORACLE],
async () => {
return await request(
hiveUrl!,
hiveUrl,
gql`
query MarsOracle {
oracle: wasm {
@ -59,7 +58,7 @@ export const useMarsOracle = () => {
)
},
{
enabled: !!hiveUrl && !!oracleAddress && basePriceState === State.READY,
enabled: !!hiveUrl && !!oracleAddress,
staleTime: 30000,
refetchInterval: 30000,
onError: () => setExchangeRatesState(State.ERROR),

View File

@ -7,44 +7,34 @@ import useStore from 'store'
import { State } from 'types/enums'
import { QUERY_KEYS } from 'types/enums/queryKeys'
const poolsEndpoint = 'osmosis/gamm/v1beta1/pools/'
const poolsEndpoint = `${process.env.NEXT_PUBLIC_OSMOSIS_REST}osmosis/gamm/v1beta1/pools/`
export const useSpotPrice = (symbol: string) => {
export const useMarsPrice = () => {
const networkConfig = useStore((s) => s.networkConfig)
const baseCurrency = networkConfig.assets.base
const displayCurrency = networkConfig.displayCurrency
const exchangeRates = useStore((s) => s.exchangeRates)
const assetPricesUSD = useStore((s) => s.assetPricesUSD)
const exchangeRatesState = useStore((s) => s.assetPricesUSDState)
const basePriceState = useStore((s) => s.assetPricesUSDState)
const asset = useAsset({ symbol })
const lcd = networkConfig.restUrl ?? ''
const poolBase = asset?.poolBase
? exchangeRates?.find((ratesAsset) => ratesAsset.denom === asset.poolBase)
: true
const asset = useAsset({ symbol: 'MARS' })
const marsOsmosDenom = 'ibc/573FCD90FACEE750F55A8864EF7D38265F07E5A9273FA0E8DAFD39951332B580'
const marsPoolId = 907
useQuery<PoolResponse>(
[QUERY_KEYS.SPOT_PRICE, asset?.poolId],
[QUERY_KEYS.SPOT_PRICE, marsPoolId],
async () => {
return fetch(`${lcd}${poolsEndpoint}${asset?.poolId}`).then(async (response) => {
return fetch(`${poolsEndpoint}${marsPoolId}`).then(async (response) => {
const data = await response.json()
return data
})
},
{
enabled:
!!asset &&
!!asset.poolId &&
!!poolBase &&
basePriceState === State.READY &&
exchangeRatesState === State.READY,
enabled: !!asset && exchangeRatesState === State.READY,
staleTime: 30000,
refetchInterval: 30000,
onSuccess: (data) => {
if (!asset || !assetPricesUSD) return
const poolDataAssets = data.pool.pool_assets
const assetFirst = poolDataAssets[0].token.denom === asset.denom
const assetFirst = poolDataAssets[0].token.denom === marsOsmosDenom
const primaryAsset = poolDataAssets[assetFirst ? 0 : 1]
const secondaryAsset = poolDataAssets[assetFirst ? 1 : 0]
@ -74,28 +64,23 @@ export const useSpotPrice = (symbol: string) => {
amount: rate.times(secondaryRate).toString(),
}
if (typeof poolBase === 'object') {
const baseRate = Number(rate.toString()) * Number(poolBase.amount)
coinExchangeRate.amount = baseRate.toString()
useStore.setState({
exchangeRates: updateExchangeRate(coinExchangeRate, exchangeRates || []),
})
} else {
useStore.setState({
exchangeRates: updateExchangeRate(coinExchangeRate, exchangeRates || []),
})
}
const baseCurrencyPrice = assetPricesUSD.find(
(asset) => asset.denom === baseCurrency.denom,
const secondaryAssetPrice = assetPricesUSD.find(
(asset) => asset.denom === secondaryAsset.token.denom,
)?.amount
if (!baseCurrencyPrice) return
if (!secondaryAssetPrice) return
const assetPriceCoin = {
denom: coinExchangeRate.denom,
amount: new BigNumber(coinExchangeRate.amount).times(baseCurrencyPrice).toString(),
amount: new BigNumber(coinExchangeRate.amount).times(secondaryAssetPrice).toString(),
}
useStore.setState({
assetPricesUSD: updateAssetPrices(assetPriceCoin, assetPricesUSD || []),
marsPriceState: State.READY,
})
}
},

View File

@ -6,14 +6,17 @@ import { State } from 'types/enums'
import { QUERY_KEYS } from 'types/enums/queryKeys'
export const useRedBank = () => {
const hiveUrl = useStore((s) => s.networkConfig.hiveUrl)
const networkConfig = useStore((s) => s.networkConfig)
const userWalletAddress = useStore((s) => s.userWalletAddress)
const whitelistedAssets = useStore((s) => s.whitelistedAssets)
const redbankAddress = useStore((s) => s.networkConfig.contracts.redBank)
const incentivesAddress = useStore((s) => s.networkConfig.contracts.incentives)
const processRedBankQuery = useStore((s) => s.processRedBankQuery)
const setRedBankState = useStore((s) => s.setRedBankState)
const hiveUrl = networkConfig.hiveUrl
const redbankAddress = networkConfig.contracts.redBank
const incentivesAddress = networkConfig.contracts.incentives
const hasMultiAssetIncentives = networkConfig.hasMultiAssetIncentives
useQuery<RedBankData>(
[QUERY_KEYS.REDBANK],
async () =>
@ -24,6 +27,7 @@ export const useRedBank = () => {
userWalletAddress,
redbankAddress,
incentivesAddress,
!!hasMultiAssetIncentives,
whitelistedAssets,
)}
`,

View File

@ -10,17 +10,19 @@ export const useUsdPrice = () => {
let usdPriceUrl = useStore((s) => s.networkConfig.usdPriceUrl)
let hasPriceFeeds = false
const whitelistedAssets = useStore((s) => s.whitelistedAssets)
const otherAssets = useStore((s) => s.otherAssets)
const assetPricesUSD = useStore((s) => s.assetPricesUSD ?? [])
const basePriceState = useStore((s) => s.basePriceState)
const baseAsset = useStore((s) => s.networkConfig.assets.base)
if (!usdPriceUrl && basePriceState !== State.READY) {
useStore.setState({ basePriceState: State.READY })
}
const assets = [...whitelistedAssets, ...otherAssets]
if (usdPriceUrl && whitelistedAssets) {
if (!usdPriceUrl && basePriceState !== State.READY)
useStore.setState({ basePriceState: State.READY })
if (usdPriceUrl && assets) {
const pythApiUrl = new URL(usdPriceUrl + 'latest_price_feeds')
whitelistedAssets.forEach((asset) => {
assets.forEach((asset) => {
if (asset.priceFeedId) {
hasPriceFeeds = true
pythApiUrl.searchParams.append('ids[]', asset.priceFeedId)
@ -32,20 +34,18 @@ export const useUsdPrice = () => {
useQuery<CoinPriceData[]>(
[QUERY_KEYS.USD_PRICE],
async () => {
if (!usdPriceUrl || !whitelistedAssets || !hasPriceFeeds) return
if (!usdPriceUrl || !assets || !hasPriceFeeds) return
const res = await fetch(usdPriceUrl)
return res.json()
},
{
enabled: !!usdPriceUrl || !!whitelistedAssets,
enabled: !!usdPriceUrl || !!assets,
staleTime: 30000,
refetchInterval: 30000,
onSuccess: (data) => {
let updatedAssetPricesUSD: Coin[] = []
data.map((priceData) => {
const denom = whitelistedAssets.find(
(asset) => asset?.priceFeedId === priceData.id,
)?.denom
const denom = assets.find((asset) => asset?.priceFeedId === priceData.id)?.denom
if (denom) {
const amount = new BigNumber(priceData.price.price)

30
src/images/astro.svg Normal file
View File

@ -0,0 +1,30 @@
<svg viewBox="0 0 400 400" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle cx="200" cy="200" r="146.41" transform="rotate(-30 200 200)" fill="url(#paint0_linear)" />
<g clip-path="url(#clip0)">
<path
d="M219.326 213.744V213.704C208.627 213.49 200.02 204.963 200.02 194.456C200.02 204.94 191.444 213.455 180.777 213.699V213.744C191.444 213.988 200.02 222.502 200.02 232.986C200.016 222.485 208.627 213.957 219.326 213.744Z"
fill="white"
/>
<path
d="M215.362 117.865H185.558C181.715 117.865 178.196 120.008 176.435 123.422L108.567 254.96C106.592 258.792 109.372 263.358 113.687 263.358H147.957C151.836 263.358 155.381 261.175 157.125 257.716L175.354 221.556C177.832 216.639 177.792 210.832 175.243 205.951L162.125 180.821C158.557 173.988 163.522 165.807 171.235 165.816L229.752 165.878C237.465 165.887 242.412 174.077 238.831 180.901L224.067 209.054C222.528 211.984 222.501 215.479 223.992 218.435L243.795 257.721C245.539 261.18 249.084 263.363 252.963 263.363H287.233C291.548 263.363 294.328 258.797 292.353 254.964L224.485 123.422C222.724 120.008 219.201 117.865 215.362 117.865Z"
fill="white"
/>
</g>
<defs>
<linearGradient
id="paint0_linear"
x1="200"
y1="53.5898"
x2="200"
y2="346.41"
gradientUnits="userSpaceOnUse"
>
<stop offset="0.140625" stop-color="#1A9FD5" />
<stop offset="0.71875" stop-color="#5643F2" />
<stop offset="0.993058" stop-color="#2233E2" />
</linearGradient>
<clipPath id="clip0">
<rect width="185.085" height="145.489" fill="white" transform="translate(107.918 117.865)" />
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@ -14,7 +14,7 @@ export function getCouncilLink(currentNetwork: ChainInfoID, currentProvider?: Wa
case WalletID.Leap:
return DocURL.COUNCIL_LEAP
case WalletID.StationWallet || WalletID.StationWalletMobile:
case WalletID.Station:
return DocURL.COUNCIL_STATION
default:

View File

@ -1,17 +1,11 @@
import BN from 'bignumber.js'
import { isNil } from 'ramda'
export const plus = (a?: BN.Value, b?: BN.Value): string => new BN(a || 0).plus(b || 0).toString()
export const times = (a?: BN.Value, b?: BN.Value): string => new BN(a || 0).times(b || 0).toString()
export const min = (array: BN.Value[]): string =>
BN.min.apply(null, array.filter(isFinite)).toString()
export const ceil = (n: BN.Value): string => new BN(n).integerValue(BN.ROUND_CEIL).toString()
export const isFinite = (n?: BN.Value): boolean => !isNil(n) && new BN(n).isFinite()
export const safeGetInputPercentage = (value: number) => {
let increasePercentage = 0
if (value >= 0) {

View File

@ -1,3 +1,7 @@
import {
NETWORK_CONFIG as neutronMainnetConfig,
VAULT_CONFIGS as neutronMainnetVaultConfig,
} from '../configs/neutron-1'
import {
NETWORK_CONFIG as osmosisTestnetConfig,
VAULT_CONFIGS as osmosisTestnetVaultConfig,
@ -15,6 +19,10 @@ export const getNetworkConfig = (network: string): NetworkConfig => {
let networkConfig
switch (network) {
case 'neutron-1':
networkConfig = neutronMainnetConfig
break
case 'osmo-test-5':
networkConfig = osmosisTestnetConfig
break
@ -34,6 +42,10 @@ export const getNetworkVaultConfig = (network: string): Vault[] => {
let vaultConfig
switch (network) {
case 'neutron-1':
vaultConfig = neutronMainnetVaultConfig
break
case 'osmo-test-5':
vaultConfig = osmosisTestnetVaultConfig
break

View File

@ -23,15 +23,17 @@ export const redBankData: RedBankData = {
deposit_enabled: true,
borrow_enabled: true,
deposit_cap: '10000000000000',
},
OSMOMarketIncentive: {
denom: 'uosmo',
incentives: [
{
denom: 'ibc/2E7368A14AC9AB7870F32CFEA687551C5064FA861868EDF7437BC877358A81F9',
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',
@ -54,15 +56,17 @@ export const redBankData: RedBankData = {
deposit_enabled: true,
borrow_enabled: true,
deposit_cap: '350000000000',
},
ATOMMarketIncentive: {
denom: 'ibc/27394FB092D2ECCD56123C74F36E4C1F926001CEADA9CA97EA622B25F41E5EB2',
incentives: [
{
denom: 'ibc/2E7368A14AC9AB7870F32CFEA687551C5064FA861868EDF7437BC877358A81F9',
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',
@ -85,15 +89,17 @@ export const redBankData: RedBankData = {
deposit_enabled: true,
borrow_enabled: false,
deposit_cap: '350000000000',
},
stATOMMarketIncentive: {
denom: 'ibc/C140AFD542AE77BD7DCC83F13FDD8C5E5BB8C4929785E6EC2F4C636F98F17901',
incentives: [
{
denom: 'ibc/2E7368A14AC9AB7870F32CFEA687551C5064FA861868EDF7437BC877358A81F9',
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',
@ -116,15 +122,17 @@ export const redBankData: RedBankData = {
deposit_enabled: true,
borrow_enabled: true,
deposit_cap: '1500000000000',
},
axlUSDCMarketIncentive: {
denom: 'ibc/D189335C6E4A68B513C10AB227BF1C1D38C746766278BA3EEB4FB14124F1D858',
incentives: [
{
denom: 'ibc/2E7368A14AC9AB7870F32CFEA687551C5064FA861868EDF7437BC877358A81F9',
emission_per_second: '48225',
start_time: 1675793700,
duration: 2592000,
index: '0.000000143742920378',
last_updated: 1678369620,
},
],
},
unclaimedRewards: '4679062',
},
}

View File

@ -3,6 +3,7 @@ import 'index.scss'
import 'styles/App.scss'
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import BigNumber from 'bignumber.js'
import {
CommonContainer,
CosmosWalletConnectProvider,
@ -13,6 +14,7 @@ import type { AppProps, NextWebVitalsMetric } from 'next/app'
import Head from 'next/head'
import { Suspense } from 'react'
BigNumber.config({ EXPONENTIAL_AT: 1e9 })
const queryClient = new QueryClient()
const App = ({ Component, pageProps }: AppProps) => {

View File

@ -78,12 +78,7 @@ const RedBank = () => {
)
useEffect(() => {
if (
redBankAssets.length === 0 ||
marketInfo.length === 0 ||
userBalancesState !== State.READY ||
redBankState === State.READY
)
if (redBankAssets.length === 0 || marketInfo.length === 0 || redBankState === State.READY)
return
setRedBankState(State.READY)
}, [redBankAssets, marketInfo, redBankState, userBalancesState, setRedBankState])

View File

@ -46,7 +46,7 @@ export interface CommonSlice {
slippage: number
tutorialSteps: { redbank: number; fields: number }
userBalances: Coin[]
userUnclaimedRewards: string
userUnclaimedRewards: Coin[]
userMarsTokenBalances: Coin[]
userWalletAddress: string
userIcns?: string

View File

@ -9,6 +9,7 @@ export interface OraclesSlice {
exchangeRatesState: State
assetPricesUSD?: Coin[]
assetPricesUSDState: State
marsPriceState: State
basePriceState: State
migrationInProgress: boolean
pythVaa: VaaInformation

View File

@ -6,7 +6,6 @@ export interface RedBankSlice {
// VARIABLES
// ------------------
marketAssetLiquidity: Coin[]
marketIncentiveInfo: MarketIncentive[]
marketInfo: Market[]
redBankAssets: RedBankAsset[]
redBankState: State
@ -18,10 +17,10 @@ export interface RedBankSlice {
// ------------------
// GENERAL FUNCTIONS
// ------------------
calculateIncentiveAssetInfo: (
calculateIncentiveAssetsInfo: (
incentive?: MarketIncentive | Record<string, any>,
marketTotalLiquidity?: Coin,
) => IncentiveInfo | undefined
) => IncentiveInfo[] | undefined
computeMarketLiquidity: (denom: string) => number
findUserDebt: (denom: string) => number
findUserDeposit: (denom: string) => number

View File

@ -52,7 +52,7 @@ const commonSlice = (
tutorialSteps: { redbank: 1, fields: 1 },
userBalances: [],
userMarsTokenBalances: [],
userUnclaimedRewards: '0',
userUnclaimedRewards: [],
userWalletAddress: '',
vaultConfigs: [],
whitelistedAssets: [],
@ -189,7 +189,7 @@ const commonSlice = (
marketDeposits: [],
userBalances: [],
userMarsTokenBalances: [],
userUnclaimedRewards: '0',
userUnclaimedRewards: [],
})
},
queryContract: async <T>(contractAddress: string, queryMsg: object, retries = 3) => {

View File

@ -2,7 +2,7 @@ import { Coin } from '@cosmjs/stargate'
import BigNumber from 'bignumber.js'
import { updateExchangeRate } from 'functions'
import { updateAssetPrices } from 'functions/updateAssetPrices'
import { findAssetByDenom, lookup, magnify } from 'libs/parse'
import { findAssetByDenom, lookup } from 'libs/parse'
import isEqual from 'lodash.isequal'
import { OraclesSlice } from 'store/interfaces/oracles.interface'
import { Store } from 'store/interfaces/store.interface'
@ -16,6 +16,7 @@ const oraclesSlice = (set: NamedSet<Store>, get: GetState<Store>): OraclesSlice
// ------------------
exchangeRatesState: State.INITIALISING,
assetPricesUSDState: State.INITIALISING,
marsPriceState: State.INITIALISING,
basePriceState: State.INITIALISING,
migrationInProgress: false,
pythVaa: {
@ -98,9 +99,7 @@ const oraclesSlice = (set: NamedSet<Store>, get: GetState<Store>): OraclesSlice
const asset2Price = assetPricesUSD?.find((coin) => coin.denom === denom2)?.amount
if (asset1Price && asset1 && asset2Price && asset2) {
return new BigNumber(magnify(Number(asset1Price), asset1.decimals))
.div(magnify(Number(asset2Price), asset2.decimals))
.toNumber()
return new BigNumber(asset1Price).div(asset2Price).toNumber()
}
return 1
},
@ -199,9 +198,11 @@ const oraclesSlice = (set: NamedSet<Store>, get: GetState<Store>): OraclesSlice
const id = asset.id
const queryResult = pricesQueryResult[`${id}`]?.price ?? '0.00'
const isNonUSDOracle = oracleBaseDenom.toLowerCase().indexOf('usd') === -1
// Non-USD denominated oracle prices
if (oracleBaseDenom.toLowerCase().indexOf('usd') === -1) {
if (isNonUSDOracle) {
if (get().basePriceState !== State.READY) return
const baseCurrencyPrice = assetPricesUSD.find(
(assetPrice) => assetPrice.denom === oracleBaseDenom,
)
@ -225,6 +226,10 @@ const oraclesSlice = (set: NamedSet<Store>, get: GetState<Store>): OraclesSlice
}
} else {
// USD denominated oracle prices
if (asset.denom === get().baseAsset?.denom) {
set({ basePriceState: State.READY })
}
const assetPrice = {
denom,
amount: typeof queryResult === 'string' ? queryResult : '0.00',

View File

@ -2,18 +2,17 @@ import { Coin } from '@cosmjs/stargate'
import { MARS_SYMBOL } from 'constants/appConstants'
import { SECONDS_IN_YEAR } from 'constants/timeConstants'
import { findByDenom } from 'functions'
import { lookupDenomBySymbol } from 'libs/parse'
import { findAssetByDenom, lookupDenomBySymbol } from 'libs/parse'
import isEqual from 'lodash.isequal'
import moment from 'moment'
import { RedBankSlice } from 'store/interfaces/redBank.interface'
import { Store } from 'store/interfaces/store.interface'
import colors from 'styles/_assets.module.scss'
import { State } from 'types/enums'
import { GetState } from 'zustand'
import { NamedSet } from 'zustand/middleware'
const redBankSlice = (set: NamedSet<Store>, get: GetState<Store>): RedBankSlice => ({
marketAssetLiquidity: [],
marketIncentiveInfo: [],
marketInfo: [],
redBankAssets: [],
redBankState: State.INITIALISING,
@ -22,30 +21,33 @@ const redBankSlice = (set: NamedSet<Store>, get: GetState<Store>): RedBankSlice
// ------------------
// GENERAL FUNCTIONS
// ------------------
calculateIncentiveAssetInfo: (
incentive?: MarketIncentive | Record<string, any>,
calculateIncentiveAssetsInfo: (
incentives?: MarketIncentive[] | Record<string, any>,
marketTotalLiquidity?: Coin,
): IncentiveInfo | undefined => {
const otherAssets = get().otherAssets
const whitelistedAssets = get().whitelistedAssets
): IncentiveInfo[] | undefined => {
const assets = [...get().otherAssets, ...get().whitelistedAssets]
const convertToBaseCurrency = get().convertToBaseCurrency
const marsAsset = get().otherAssets?.find((asset) => asset.denom === MARS_SYMBOL)
if (!incentive || !marketTotalLiquidity || !whitelistedAssets || !convertToBaseCurrency) return
if (!incentives?.length || !marketTotalLiquidity || !assets || !convertToBaseCurrency) return
const incentiveAssetsInfo = incentives.map((incentive: MarketIncentive) => {
const incentiveAsset = findAssetByDenom(incentive.denom, assets)
if (!incentiveAsset) return
const anualEmission = Number(incentive.emission_per_second) * SECONDS_IN_YEAR
const anualEmissionVaule = convertToBaseCurrency({
denom: lookupDenomBySymbol(MARS_SYMBOL, otherAssets),
denom: incentive.denom,
amount: anualEmission.toString(),
})
const liquidityValue = convertToBaseCurrency(marketTotalLiquidity)
const incentiveApr = anualEmissionVaule / liquidityValue
return {
symbol: marsAsset?.symbol || MARS_SYMBOL,
color: marsAsset?.color || colors.mars,
symbol: incentiveAsset.symbol,
color: incentiveAsset.color,
apy: incentiveApr * 100,
}
})
return incentiveAssetsInfo
},
computeMarketLiquidity: (denom: string) => {
return Number(get().marketAssetLiquidity.find((asset) => asset.denom === denom)?.amount) || 0
@ -87,8 +89,8 @@ const redBankSlice = (set: NamedSet<Store>, get: GetState<Store>): RedBankSlice
const marketLiquidity = (depositLiquidity - debtLiquidity).toString()
marketAssetLiquidity.push({ denom: asset.denom, amount: marketLiquidity })
const incentiveInfo = get().calculateIncentiveAssetInfo(
findByDenom(get().marketIncentiveInfo, asset.denom),
const incentiveInfo = get().calculateIncentiveAssetsInfo(
findByDenom(get().marketInfo, asset.denom)?.incentives,
{ denom: asset.denom, amount: depositLiquidity.toString() },
)
@ -134,29 +136,52 @@ const redBankSlice = (set: NamedSet<Store>, get: GetState<Store>): RedBankSlice
processRedBankQuery: (data: RedBankData, whitelistedAssets: Asset[]) => {
if (isEqual(data, get().previousRedBankQueryData) && get().marketInfo.length) return
const userUnclaimedRewards = data.rbwasmkey.unclaimedRewards
const marketInfo: Market[] = []
const marketIncentiveInfo: MarketIncentive[] = []
const assets = [...whitelistedAssets, ...get().otherAssets]
const MARS_DENOM = lookupDenomBySymbol(MARS_SYMBOL, assets)
const hasMultiAssetIncentives = get().networkConfig.hasMultiAssetIncentives
whitelistedAssets?.forEach((asset: Asset) => {
const denom = asset.denom
const id = asset.id
const queryResult = data.rbwasmkey
const marketData = {
const marketData: Market = {
...queryResult[`${id}Market`],
denom: denom,
incentives: [],
}
marketInfo.push(marketData)
if (hasMultiAssetIncentives) {
const marketIncentiveData = queryResult[
`${id}MarketIncentive`
] as MultiAssetMarketIncentive[]
marketIncentiveData.forEach((incentive) => {
marketData.incentives.push({
denom: incentive.denom,
emission_per_second: String(incentive.emission_rate),
})
})
} else {
const marketIncentiveData = {
...queryResult[`${id}MarketIncentive`],
denom: denom,
denom: MARS_DENOM,
} as MarketIncentive
const isValid =
marketIncentiveData?.emission_per_second &&
moment(
(marketIncentiveData?.start_time ?? 0) + (marketIncentiveData?.duration ?? 0),
).isBefore(moment.now())
if (isValid) marketData.incentives.push(marketIncentiveData)
}
marketIncentiveInfo.push(marketIncentiveData)
marketInfo.push(marketData)
})
const userUnclaimedRewards =
hasMultiAssetIncentives && typeof data.rbwasmkey.unclaimedRewards === 'object'
? data.rbwasmkey.unclaimedRewards
: [{ denom: MARS_DENOM, amount: data.rbwasmkey.unclaimedRewards }]
set({
marketInfo,
marketIncentiveInfo,
previousRedBankQueryData: data,
userUnclaimedRewards,
})

View File

@ -7,6 +7,7 @@
atom: $colorTokenATOM;
axl: $colorTokenAXL;
usdc: $colorTokenUSDC;
astro: $colorTokenASTRO;
wbtc: $colorTokenWBTC;
weth: $colorTokenWETH;
juno: $colorTokenJUNO;

View File

@ -39,6 +39,7 @@ $colorTokenStATOM: #e50571;
$colorTokenWBTC: #f09242;
$colorTokenWETH: #343434;
$colorTokenNTRN: #284fe0;
$colorTokenASTRO: #2233e2;
$colorGradientOSMO: linear-gradient(to bottom, #3a02e2, #e700ca);
$colorGradientATOM: linear-gradient(to bottom, #2e3148, #6f7390);

View File

@ -6,6 +6,7 @@ interface Asset {
| 'OSMO'
| 'NTRN'
| 'ATOM'
| 'ASTRO'
| 'AXL'
| 'JUNO'
| 'USDC.axl'
@ -21,6 +22,7 @@ interface Asset {
| 'axlWBTC'
| 'axlWETH'
| 'ATOM'
| 'ASTRO'
| 'AXL'
| 'JUNO'
| 'stATOM'
@ -28,7 +30,6 @@ interface Asset {
contract_addr?: string
logo: string
decimals: number
poolId?: number
poolBase?: string
priceFeedId?: string
}
@ -56,7 +57,7 @@ interface RedBankAsset extends Asset {
depositBalanceBaseCurrency: number
marketLiquidity: string
isCollateral: boolean
incentiveInfo?: IncentiveInfo
incentiveInfo?: IncentiveInfo[]
depositCap: number
depositLiquidity: numnber
borrowEnabled: boolean

View File

@ -1,6 +1,6 @@
interface HoverItem {
color?: string
name: string
coin: import('@cosmjs/proto-signing').Coin
coin: import('@cosmjs/stargate').Coin
negative?: boolean
}

View File

@ -24,6 +24,7 @@ interface NetworkConfig {
displayCurrency: displayCurrency
appUrl: string
isFieldsEnabled: boolean
hasMultiAssetIncentives?: boolean
}
interface DisplayCurrency {

View File

@ -4,27 +4,29 @@ interface RedBankData {
}
rbwasmkey: {
OSMOMarket: Market
OSMOMarketIncentive: MarketIncentive
OSMOMarketIncentive: MarketIncentive | MultiAssetMarketIncentive[]
ATOMMarket: Market
ATOMMarketIncentive: MarketIncentive
ATOMMarketIncentive: MarketIncentive | MultiAssetMarketIncentive[]
AXLMarket: Market
AXLMarketIncentive: MarketIncentive
AXLMarketIncentive: MarketIncentive | MultiAssetMarketIncentive[]
JUNOMarket: Market
JUNOMarketIncentive: MarketIncentive
JUNOMarketIncentive: MarketIncentive | MultiAssetMarketIncentive[]
ASTROMarket: Market
ASTROMarketIncentive: MarketIncentive | MultiAssetMarketIncentive[]
axlUSDCMarket: Market
axlUSDCMarketIncentive: MarketIncentive
axlUSDCMarketIncentive: MarketIncentive | MultiAssetMarketIncentive[]
axlWBTCMarket: Market
axlWBTCMarketIncentive: MarketIncentive
axlWBTCMarketIncentive: MarketIncentive | MultiAssetMarketIncentive[]
axlWETHMarket: Market
axlWETHMarketIncentive: MarketIncentive
axlWETHMarketIncentive: MarketIncentive | MultiAssetMarketIncentive[]
stATOMMarket: Market
stATOMMarketIncentive: MarketIncentive
stATOMMarketIncentive: MarketIncentive | MultiAssetMarketIncentive[]
nUSDCMarket: Market
nUSDCMarketIncentive: MarketIncentive
nUSDCMarketIncentive: MarketIncentive | MultiAssetMarketIncentive[]
NTRNMarket: Market
NTRNMarketIncentive: MarketIncentive
NTRNMarketIncentive: MarketIncentive | MultiAssetMarketIncentive[]
collateral: UserCollateral[]
unclaimedRewards: string
unclaimedRewards: string | Coin[]
}
}
@ -45,6 +47,7 @@ interface Market {
deposit_enabled: boolean
borrow_enabled: boolean
deposit_cap: string
incentives: MarketIncentive[]
}
interface InterestRateModel {
@ -57,8 +60,13 @@ interface InterestRateModel {
interface MarketIncentive {
denom: string
emission_per_second: string
index: string
last_updated: number
start_time: number
duration: number
index?: string
last_updated?: number
start_time?: number
duration?: number
}
interface MultiAssetMarketIncentive {
denom: string
emission_rate: number
}

3121
yarn.lock

File diff suppressed because it is too large Load Diff