diff --git a/components/CreditManager/index.tsx b/components/CreditManager/index.tsx
index 461f3d64..20121620 100644
--- a/components/CreditManager/index.tsx
+++ b/components/CreditManager/index.tsx
@@ -128,7 +128,7 @@ const CreditManager = () => {
})}
- {(Number(marketsData?.[coin.denom].borrow_rate) * 100).toFixed(1)}%
+ -{(Number(marketsData?.[coin.denom].borrow_rate) * 100).toFixed(1)}%
))}
diff --git a/config/contracts.ts b/config/contracts.ts
index 08df9365..8377ae26 100644
--- a/config/contracts.ts
+++ b/config/contracts.ts
@@ -1,8 +1,13 @@
// https://github.com/mars-protocol/rover/blob/master/scripts/deploy/addresses/osmo-test-4.json
-export const contractAddresses = {
+export const roverContracts = {
accountNft: 'osmo1dravtyd0425fkdmkysc3ns7zud05clf5uhj6qqsnkdtrpkewu73q9f3f02',
mockVault: 'osmo1emcckulm2mkx36xeanhsn3z3zjeql6pgd8yf8a5cf03ccvy7a4dqjw9tl7',
marsOracleAdapter: 'osmo1cw6pv97g7fmhqykrn0gc9ngrx5tnky75rmlwkzxuqhsk58u0n8asz036g0',
swapper: 'osmo1w2552km2u9w4k2gjw4n8drmuz5yxw8x4qzy6dl3da824km5cjlys00x3qp',
creditManager: 'osmo18dt5y0ecyd5qg8nqwzrgxuljfejglyh2fjd984s8cy7fcx8mxh9qfl3hwq',
}
+
+export const contractAddresses = {
+ ...roverContracts,
+ redBank: 'osmo1w5rqrdhut890jplmsqnr8gj3uf0wq6lj5rfdnhrtl63lpf6e7v6qalrhhn',
+}
diff --git a/hooks/useBorrowFunds.tsx b/hooks/useBorrowFunds.tsx
index e873e9d2..d91d5d98 100644
--- a/hooks/useBorrowFunds.tsx
+++ b/hooks/useBorrowFunds.tsx
@@ -10,6 +10,7 @@ import { contractAddresses } from 'config/contracts'
import { hardcodedFee } from 'utils/contants'
import useCreditManagerStore from 'stores/useCreditManagerStore'
import { queryKeys } from 'types/query-keys-factory'
+import { getTokenDecimals } from 'utils/tokens'
const useBorrowFunds = (
amount: string | number,
@@ -36,6 +37,8 @@ const useBorrowFunds = (
}, [address])
const executeMsg = useMemo(() => {
+ const tokenDecimals = getTokenDecimals(denom)
+
if (!withdraw) {
return {
update_credit_account: {
@@ -45,7 +48,7 @@ const useBorrowFunds = (
borrow: {
denom: denom,
amount: BigNumber(amount)
- .times(10 ** 6)
+ .times(10 ** tokenDecimals)
.toString(),
},
},
@@ -62,7 +65,7 @@ const useBorrowFunds = (
borrow: {
denom: denom,
amount: BigNumber(amount)
- .times(10 ** 6)
+ .times(10 ** tokenDecimals)
.toString(),
},
},
@@ -70,14 +73,14 @@ const useBorrowFunds = (
withdraw: {
denom: denom,
amount: BigNumber(amount)
- .times(10 ** 6)
+ .times(10 ** tokenDecimals)
.toString(),
},
},
],
},
}
- }, [amount, denom, withdraw, selectedAccount])
+ }, [withdraw, selectedAccount, denom, amount])
return useMutation(
async () =>
@@ -90,6 +93,7 @@ const useBorrowFunds = (
{
onSettled: () => {
queryClient.invalidateQueries(queryKeys.creditAccountsPositions(selectedAccount ?? ''))
+ queryClient.invalidateQueries(queryKeys.redbankBalances())
// if withdrawing to wallet, need to explicility invalidate balances queries
if (withdraw) {
diff --git a/hooks/useCalculateMaxBorrowAmount.tsx b/hooks/useCalculateMaxBorrowAmount.tsx
index 6d3b0c4c..3e89abf3 100644
--- a/hooks/useCalculateMaxBorrowAmount.tsx
+++ b/hooks/useCalculateMaxBorrowAmount.tsx
@@ -6,6 +6,7 @@ import { getTokenDecimals } from 'utils/tokens'
import useCreditAccountPositions from './useCreditAccountPositions'
import useMarkets from './useMarkets'
import useTokenPrices from './useTokenPrices'
+import useRedbankBalances from './useRedbankBalances'
const useCalculateMaxBorrowAmount = (denom: string, isUnderCollateralized: boolean) => {
const selectedAccount = useCreditManagerStore((s) => s.selectedAccount)
@@ -13,9 +14,10 @@ const useCalculateMaxBorrowAmount = (denom: string, isUnderCollateralized: boole
const { data: positionsData } = useCreditAccountPositions(selectedAccount ?? '')
const { data: marketsData } = useMarkets()
const { data: tokenPrices } = useTokenPrices()
+ const { data: redbankBalances } = useRedbankBalances()
return useMemo(() => {
- if (!marketsData || !tokenPrices || !positionsData) return 0
+ if (!marketsData || !tokenPrices || !positionsData || !redbankBalances) return 0
const getTokenTotalUSDValue = (amount: string, denom: string) => {
// early return if prices are not fetched yet
@@ -27,6 +29,7 @@ const useCalculateMaxBorrowAmount = (denom: string, isUnderCollateralized: boole
.toNumber()
}
+ // max ltv adjusted collateral
const totalWeightedPositions = positionsData?.coins.reduce((acc, coin) => {
const tokenWeightedValue = BigNumber(getTokenTotalUSDValue(coin.amount, coin.denom)).times(
Number(marketsData[coin.denom].max_loan_to_value)
@@ -35,6 +38,7 @@ const useCalculateMaxBorrowAmount = (denom: string, isUnderCollateralized: boole
return tokenWeightedValue.plus(acc).toNumber()
}, 0)
+ // total debt value
const totalLiabilitiesValue = positionsData?.debts.reduce((acc, coin) => {
const tokenUSDValue = BigNumber(getTokenTotalUSDValue(coin.amount, coin.denom))
@@ -44,20 +48,31 @@ const useCalculateMaxBorrowAmount = (denom: string, isUnderCollateralized: boole
const borrowTokenPrice = tokenPrices[denom]
const tokenDecimals = getTokenDecimals(denom)
+ let maxValue
if (isUnderCollateralized) {
- return BigNumber(totalLiabilitiesValue)
+ // MAX TO CREDIT ACCOUNT
+ maxValue = BigNumber(totalLiabilitiesValue)
.minus(totalWeightedPositions)
.div(borrowTokenPrice * Number(marketsData[denom].max_loan_to_value) - borrowTokenPrice)
.decimalPlaces(tokenDecimals)
.toNumber()
} else {
- return BigNumber(totalWeightedPositions)
+ // MAX TO WALLET
+ maxValue = BigNumber(totalWeightedPositions)
.minus(totalLiabilitiesValue)
.div(borrowTokenPrice)
.decimalPlaces(tokenDecimals)
.toNumber()
}
- }, [denom, isUnderCollateralized, marketsData, positionsData, tokenPrices])
+
+ const marketLiquidity = BigNumber(redbankBalances?.[denom] ?? '')
+ .div(10 ** getTokenDecimals(denom))
+ .toNumber()
+
+ if (marketLiquidity < maxValue) return marketLiquidity
+
+ return maxValue > 0 ? maxValue : 0
+ }, [denom, isUnderCollateralized, marketsData, positionsData, redbankBalances, tokenPrices])
}
export default useCalculateMaxBorrowAmount
diff --git a/hooks/useMarkets.tsx b/hooks/useMarkets.tsx
index 164c1a8b..bf42ecde 100644
--- a/hooks/useMarkets.tsx
+++ b/hooks/useMarkets.tsx
@@ -38,8 +38,8 @@ const useMarkets = () => {
wasm: {
uosmo: {
denom: 'uosmo',
- max_loan_to_value: '0.65',
- liquidation_threshold: '0.7',
+ max_loan_to_value: '0.55',
+ liquidation_threshold: '0.65',
liquidation_bonus: '0.1',
reserve_factor: '0.2',
interest_rate_model: {
@@ -61,8 +61,8 @@ const useMarkets = () => {
},
'ibc/27394FB092D2ECCD56123C74F36E4C1F926001CEADA9CA97EA622B25F41E5EB2': {
denom: 'ibc/27394FB092D2ECCD56123C74F36E4C1F926001CEADA9CA97EA622B25F41E5EB2',
- max_loan_to_value: '0.77',
- liquidation_threshold: '0.8',
+ max_loan_to_value: '0.65',
+ liquidation_threshold: '0.7',
liquidation_bonus: '0.1',
reserve_factor: '0.2',
interest_rate_model: {
diff --git a/hooks/useRedbankBalances.tsx b/hooks/useRedbankBalances.tsx
new file mode 100644
index 00000000..4fb96a58
--- /dev/null
+++ b/hooks/useRedbankBalances.tsx
@@ -0,0 +1,59 @@
+import { useMemo } from 'react'
+import { useQuery } from '@tanstack/react-query'
+import { Coin } from '@cosmjs/stargate'
+
+import { contractAddresses } from 'config/contracts'
+import { queryKeys } from 'types/query-keys-factory'
+import { chain } from 'utils/chains'
+
+interface Result {
+ data: {
+ bank: {
+ balance: Coin[]
+ }
+ }
+}
+
+const fetchBalances = () => {
+ return fetch(chain.hive, {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ body: JSON.stringify({
+ query: `
+ query RedbankBalances {
+ bank {
+ balance(
+ address: "${contractAddresses.redBank}"
+ ) {
+ amount
+ denom
+ }
+ }
+ }
+ `,
+ }),
+ }).then((res) => res.json())
+}
+
+const useRedbankBalances = () => {
+ const result = useQuery(queryKeys.redbankBalances(), fetchBalances)
+
+ return {
+ ...result,
+ data: useMemo(() => {
+ if (!result.data) return
+
+ return result.data?.data.bank.balance.reduce(
+ (acc, coin) => ({
+ ...acc,
+ [coin.denom]: coin.amount,
+ }),
+ {}
+ ) as { [key in string]: string }
+ }, [result.data]),
+ }
+}
+
+export default useRedbankBalances
diff --git a/hooks/useRepayFunds.tsx b/hooks/useRepayFunds.tsx
index 6ffee088..13e59b89 100644
--- a/hooks/useRepayFunds.tsx
+++ b/hooks/useRepayFunds.tsx
@@ -10,6 +10,7 @@ import { contractAddresses } from 'config/contracts'
import { hardcodedFee } from 'utils/contants'
import useCreditManagerStore from 'stores/useCreditManagerStore'
import { queryKeys } from 'types/query-keys-factory'
+import { getTokenDecimals } from 'utils/tokens'
const useRepayFunds = (
amount: string | number,
@@ -34,23 +35,33 @@ const useRepayFunds = (
})()
}, [address])
+ const tokenDecimals = getTokenDecimals(denom)
+
const executeMsg = useMemo(() => {
return {
update_credit_account: {
account_id: selectedAccount,
actions: [
+ {
+ deposit: {
+ denom: denom,
+ amount: BigNumber(amount)
+ .times(10 ** tokenDecimals)
+ .toString(),
+ },
+ },
{
repay: {
denom: denom,
amount: BigNumber(amount)
- .times(10 ** 6)
+ .times(10 ** tokenDecimals)
.toString(),
},
},
],
},
}
- }, [amount, denom, selectedAccount])
+ }, [amount, denom, selectedAccount, tokenDecimals])
return useMutation(
async () =>
@@ -58,13 +69,23 @@ const useRepayFunds = (
address,
contractAddresses.creditManager,
executeMsg,
- hardcodedFee
+ hardcodedFee,
+ undefined,
+ [
+ {
+ denom,
+ amount: BigNumber(amount)
+ .times(10 ** tokenDecimals)
+ .toString(),
+ },
+ ]
),
{
onSettled: () => {
queryClient.invalidateQueries(queryKeys.creditAccountsPositions(selectedAccount ?? ''))
queryClient.invalidateQueries(queryKeys.tokenBalance(address, denom))
queryClient.invalidateQueries(queryKeys.allBalances(address))
+ queryClient.invalidateQueries(queryKeys.redbankBalances())
},
onError: (err: Error) => {
toast.error(err.message)
diff --git a/hooks/useTokenPrices.tsx b/hooks/useTokenPrices.tsx
index 71b5b79c..e4f56b49 100644
--- a/hooks/useTokenPrices.tsx
+++ b/hooks/useTokenPrices.tsx
@@ -4,8 +4,8 @@ const useTokenPrices = () => {
return useQuery<{ [key in string]: number }>(
['tokenPrices'],
() => ({
- uosmo: 1.1,
- 'ibc/27394FB092D2ECCD56123C74F36E4C1F926001CEADA9CA97EA622B25F41E5EB2': 11,
+ uosmo: 1,
+ 'ibc/27394FB092D2ECCD56123C74F36E4C1F926001CEADA9CA97EA622B25F41E5EB2': 1.5,
}),
{
staleTime: Infinity,
diff --git a/pages/borrow.tsx b/pages/borrow.tsx
index 66dae478..0b157a38 100644
--- a/pages/borrow.tsx
+++ b/pages/borrow.tsx
@@ -10,6 +10,7 @@ import useMarkets from 'hooks/useMarkets'
import useTokenPrices from 'hooks/useTokenPrices'
import { BorrowFunds, RepayFunds } from 'components/Borrow'
import BorrowTable from 'components/Borrow/BorrowTable'
+import useRedbankBalances from 'hooks/useRedbankBalances'
type ModuleState =
| {
@@ -35,6 +36,7 @@ const Borrow = () => {
const { data: positionsData } = useCreditAccountPositions(selectedAccount ?? '')
const { data: marketsData } = useMarkets()
const { data: tokenPrices } = useTokenPrices()
+ const { data: redbankBalances } = useRedbankBalances()
const borrowedAssetsMap = useMemo(() => {
let borrowedAssetsMap: Map = new Map()
@@ -54,7 +56,7 @@ const Borrow = () => {
.map((denom) => {
const { symbol, chain, icon } = getTokenInfo(denom)
const borrowRate = Number(marketsData?.[denom].borrow_rate) || 0
- const marketLiquidity = BigNumber(marketsData?.[denom].deposit_cap ?? '')
+ const marketLiquidity = BigNumber(redbankBalances?.[denom] ?? '')
.div(10 ** getTokenDecimals(denom))
.toNumber()
@@ -84,7 +86,7 @@ const Borrow = () => {
.map((denom) => {
const { symbol, chain, icon } = getTokenInfo(denom)
const borrowRate = Number(marketsData?.[denom].borrow_rate) || 0
- const marketLiquidity = BigNumber(marketsData?.[denom].deposit_cap ?? '')
+ const marketLiquidity = BigNumber(redbankBalances?.[denom] ?? '')
.div(10 ** getTokenDecimals(denom))
.toNumber()
@@ -101,7 +103,7 @@ const Borrow = () => {
return rowData
}) ?? [],
}
- }, [allowedCoinsData, borrowedAssetsMap, marketsData, tokenPrices])
+ }, [allowedCoinsData, borrowedAssetsMap, marketsData, redbankBalances, tokenPrices])
const handleBorrowClick = (denom: string) => {
setModuleState({ show: 'borrow', data: { tokenDenom: denom } })
diff --git a/types/query-keys-factory.ts b/types/query-keys-factory.ts
index 9494ab23..523ad14a 100644
--- a/types/query-keys-factory.ts
+++ b/types/query-keys-factory.ts
@@ -1,6 +1,7 @@
export const queryKeys = {
allBalances: (address: string) => ['allBalances', address],
allowedCoins: () => ['allowedCoins'],
+ redbankBalances: () => ['redbankBalances'],
creditAccounts: (address: string) => ['creditAccounts', address],
creditAccountsPositions: (accountId: string) => ['creditAccountPositions', accountId],
tokenBalance: (address: string, denom: string) => ['tokenBalance', address, denom],
diff --git a/utils/chains.ts b/utils/chains.ts
index 001554e5..c042274a 100644
--- a/utils/chains.ts
+++ b/utils/chains.ts
@@ -42,6 +42,7 @@ export const chainsInfo = {
chainId: 'osmo-test-4',
rpc: 'https://osmosis-delphi-testnet-1.simply-vc.com.mt/XF32UOOU55CX/osmosis-rpc',
rest: 'https://osmosis-delphi-testnet-1.simply-vc.com.mt/XF32UOOU55CX/osmosis-lcd',
+ hive: 'https://osmosis-delphi-testnet-1.simply-vc.com.mt/XF32UOOU55CX/osmosis-hive/graphql',
stakeCurrency: {
coinDenom: 'OSMO',
coinMinimalDenom: 'uosmo',