Skip to content

Commit

Permalink
add DUSD price - hardcode activePrice to DUSD (#1438)
Browse files Browse the repository at this point in the history
* fix: interest per block calculation

* feat: add vault and loan token selector

To hardcode DUSD activePrice

* revert: remove interestPerBlock checking
  • Loading branch information
kyleleow authored Nov 24, 2021
1 parent 6bf6f83 commit f45c1a0
Show file tree
Hide file tree
Showing 9 changed files with 98 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { EmptyVault } from './components/EmptyVault'
import { SkeletonLoader, SkeletonLoaderScreen } from '@components/SkeletonLoader'
import { useDispatch, useSelector } from 'react-redux'
import { RootState } from '@store'
import { fetchLoanSchemes, fetchLoanTokens, fetchVaults } from '@store/loans'
import { fetchLoanSchemes, fetchLoanTokens, fetchVaults, loanTokensSelector } from '@store/loans'
import { useWhaleApiClient } from '@shared-contexts/WhaleContext'
import { useWalletContext } from '@shared-contexts/WalletContext'
import { LoanCards } from './components/LoanCards'
Expand All @@ -31,10 +31,10 @@ export function LoansScreen ({ navigation }: Props): JSX.Element {
const blockCount = useSelector((state: RootState) => state.block.count)
const {
vaults,
loanTokens: loans,
hasFetchedVaultsData,
hasFetchedLoansData
} = useSelector((state: RootState) => state.loans)
const loans = useSelector((state: RootState) => loanTokensSelector(state.loans))
const [activeTab, setActiveTab] = useState<string>(TabKey.YourVaults)
const dispatch = useDispatch()
const client = useWhaleApiClient()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { LoanParamList } from '../LoansNavigator'
import { TouchableOpacity } from 'react-native'
import { ScrollableButton, ScrollButton } from '../components/ScrollableButton'
import { VaultDetailTabSection } from './components/VaultDetailTabSection'
import { LoanVault } from '@store/loans'
import { LoanVault, vaultsSelector } from '@store/loans'
import { useSelector } from 'react-redux'
import { RootState } from '@store'
import { LoanVaultState } from '@defichain/whale-api-client/dist/api/loan'
Expand All @@ -33,7 +33,7 @@ export function VaultDetailScreen ({
}: Props): JSX.Element {
const { vaultId, tab } = route.params
const [vault, setVault] = useState<LoanVault>()
const vaults = useSelector((state: RootState) => state.loans.vaults)
const vaults = useSelector((state: RootState) => vaultsSelector(state.loans))
const canUseOperations = useLoanOperations(vault?.state)
const vaultActionButtons: ScrollButton[] = [
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { LoanParamList } from '../LoansNavigator'
import { ActivePrice } from '@defichain/whale-api-client/dist/api/prices'
import { useSelector } from 'react-redux'
import { RootState } from '@store'
import { vaultsSelector } from '@store/loans'

interface LoanCardsProps {
loans: LoanToken[]
Expand All @@ -33,7 +34,7 @@ export interface LoanCardOptions {

export function LoanCards (props: LoanCardsProps): JSX.Element {
const navigation = useNavigation<NavigationProp<LoanParamList>>()
const vaults = useSelector((state: RootState) => state.loans.vaults)
const vaults = useSelector((state: RootState) => vaultsSelector(state.loans))
const activeVault = vaults.find((v) => v.vaultId === props.vaultId && v.state !== LoanVaultState.IN_LIQUIDATION) as LoanVaultActive
const { isBetaFeature } = useFeatureFlagContext()
return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { translate } from '@translations'
import { useDispatch, useSelector } from 'react-redux'
import { RootState } from '@store'
import { useEffect } from 'react'
import { fetchCollateralTokens, fetchVaults } from '@store/loans'
import { fetchCollateralTokens, fetchVaults, vaultsSelector } from '@store/loans'
import { useWhaleApiClient } from '@shared-contexts/WhaleContext'
import { useWalletContext } from '@shared-contexts/WalletContext'

Expand All @@ -18,7 +18,7 @@ export function Vaults (): JSX.Element {
const client = useWhaleApiClient()
const { address } = useWalletContext()
const blockCount = useSelector((state: RootState) => state.block.count)
const vaults = useSelector((state: RootState) => state.loans.vaults)
const vaults = useSelector((state: RootState) => vaultsSelector(state.loans))

useEffect(() => {
dispatch(fetchVaults({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@ export function useInterestPerBlock (vaultInterest: BigNumber, loanTokenInterest
const { network } = useNetworkContext()
const blocksPerDay = network === EnvironmentNetwork.MainNet || network === EnvironmentNetwork.TestNet ? 2880 : 144

return vaultInterest.plus(loanTokenInterest).multipliedBy(loanAmount).dividedBy(
return vaultInterest.plus(loanTokenInterest).dividedBy(100).multipliedBy(loanAmount).dividedBy(
new BigNumber(365).multipliedBy(blocksPerDay))
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import NumberFormat from 'react-number-format'
import { WalletTextInput } from '@components/WalletTextInput'
import { NumberRow } from '@components/NumberRow'
import { BottomSheetVaultList } from '../components/BottomSheetVaultList'
import { fetchVaults, LoanVault } from '@store/loans'
import { fetchVaults, LoanVault, vaultsSelector } from '@store/loans'
import { LoanToken, LoanVaultActive, LoanVaultState } from '@defichain/whale-api-client/dist/api/loan'
import { ActivePrice } from '@defichain/whale-api-client/dist/api/prices'
import { TextRow } from '@components/TextRow'
Expand All @@ -38,7 +38,6 @@ import { useVaultStatus, VaultStatusTag } from '@screens/AppNavigator/screens/Lo
import { queueConvertTransaction } from '@hooks/wallet/Conversion'
import { useResultingCollateralRatio } from '../hooks/CollateralPrice'
import { CollateralizationRatioRow } from '../components/CollateralizationRatioRow'
import { useInterestPerBlock } from '../hooks/InterestPerBlock'
import { useLoanOperations } from '@screens/AppNavigator/screens/Loans/hooks/LoanOperations'
import { VaultSectionTextRow } from '../components/VaultSectionTextRow'
import { useMaxLoanAmount } from '../hooks/MaxLoanAmount'
Expand All @@ -57,7 +56,7 @@ export function BorrowLoanTokenScreen ({
const { address } = useWalletContext()
const dispatch = useDispatch()
const blockCount = useSelector((state: RootState) => state.block.count)
const vaults = useSelector((state: RootState) => (state.loans.vaults))
const vaults = useSelector((state: RootState) => vaultsSelector(state.loans))
const [vault, setVault] = useState<LoanVaultActive | undefined>(route.params.vault)
const [amountToBorrow, setAmountToBorrow] = useState('')
const [totalInterestAmount, setTotalInterestAmount] = useState(new BigNumber(NaN))
Expand All @@ -66,7 +65,6 @@ export function BorrowLoanTokenScreen ({
const [valid, setValid] = useState(false)
const resultingColRatio = useResultingCollateralRatio(new BigNumber(vault?.collateralValue ?? NaN), new BigNumber(vault?.loanValue ?? NaN),
new BigNumber(totalLoanWithInterest), new BigNumber(loanToken.activePrice?.active?.amount ?? 0))
const interestPerBlock = useInterestPerBlock(new BigNumber(vault?.loanScheme.interestRate ?? 0), new BigNumber(loanToken.interest), new BigNumber(amountToBorrow))

// Conversion
const DFIUtxo = useSelector((state: RootState) => DFIUtxoSelector(state.wallet))
Expand Down Expand Up @@ -128,8 +126,7 @@ export function BorrowLoanTokenScreen ({
vault === undefined ||
resultingColRatio === undefined ||
resultingColRatio.isNaN() ||
resultingColRatio.isLessThan(vault.loanScheme.minColRatio) ||
interestPerBlock.isLessThanOrEqualTo(0.00000009))
resultingColRatio.isLessThan(vault.loanScheme.minColRatio))
}

const updateInterestAmount = (): void => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,11 @@ import { useWhaleApiClient } from '@shared-contexts/WhaleContext'
import { useLogger } from '@shared-contexts/NativeLoggingProvider'
import { useSelector } from 'react-redux'
import { RootState } from '@store'
import { loanTokenByTokenId } from '@store/loans'
import { loanTokenByTokenId, vaultsSelector } from '@store/loans'
import { Button } from '@components/Button'
import { hasTxQueued } from '@store/transaction_queue'
import { hasTxQueued as hasBroadcastQueued } from '@store/ocean'
import { LoanVaultActive } from '@defichain/whale-api-client/dist/api/loan'
import { useInterestPerBlock } from '../hooks/InterestPerBlock'
import { useLoanOperations } from '../hooks/LoanOperations'

type Props = StackScreenProps<LoanParamList, 'BorrowMoreScreen'>
Expand All @@ -31,7 +30,7 @@ export function BorrowMoreScreen ({ route, navigation }: Props): JSX.Element {
} = route.params
const client = useWhaleApiClient()
const logger = useLogger()
const vaults = useSelector((state: RootState) => (state.loans.vaults))
const vaults = useSelector((state: RootState) => vaultsSelector(state.loans))
const loanToken = useSelector((state: RootState) => loanTokenByTokenId(state.loans, loanTokenAmount.id))
const [vault, setVault] = useState<LoanVaultActive>(vaultFromRoute)
const [amountToAdd, setAmountToAdd] = useState('')
Expand All @@ -43,7 +42,6 @@ export function BorrowMoreScreen ({ route, navigation }: Props): JSX.Element {
new BigNumber(totalLoanWithInterest), new BigNumber(loanTokenAmount.activePrice?.active?.amount ?? 0))
const hasPendingJob = useSelector((state: RootState) => hasTxQueued(state.transactionQueue))
const hasPendingBroadcastJob = useSelector((state: RootState) => hasBroadcastQueued(state.ocean))
const interestPerBlock = useInterestPerBlock(new BigNumber(vault.loanScheme.interestRate), new BigNumber(loanToken?.interest ?? 0), new BigNumber(amountToAdd))
const canUseOperations = useLoanOperations(vault?.state)

// Form update
Expand All @@ -54,8 +52,7 @@ export function BorrowMoreScreen ({ route, navigation }: Props): JSX.Element {
amount.isLessThanOrEqualTo(0) ||
vault === undefined ||
resultingColRatio === undefined ||
resultingColRatio.isLessThan(vault.loanScheme.minColRatio) ||
interestPerBlock.isLessThanOrEqualTo(0.00000009))
resultingColRatio.isLessThan(vault.loanScheme.minColRatio))
}

const updateInterestAmount = (): void => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,15 @@ import { useDispatch, useSelector } from 'react-redux'
import { RootState } from '@store'
import { LoanToken } from '@defichain/whale-api-client/dist/api/loan'
import { useWhaleApiClient } from '@shared-contexts/WhaleContext'
import { fetchLoanTokens } from '@store/loans'
import { fetchLoanTokens, loanTokensSelector } from '@store/loans'
import { HeaderSearchIcon } from '@components/HeaderSearchIcon'
import { HeaderSearchInput } from '@components/HeaderSearchInput'

type Props = StackScreenProps<LoanParamList, 'ChooseLoanTokenScreen'>

export function ChooseLoanTokenScreen ({ navigation, route }: Props): JSX.Element {
const { vaultId } = route.params
const loans = useSelector((state: RootState) => state.loans.loanTokens)
const loans = useSelector((state: RootState) => loanTokensSelector(state.loans))
const blockCount = useSelector((state: RootState) => state.block.count)
const dispatch = useDispatch()
const client = useWhaleApiClient()
Expand Down
83 changes: 81 additions & 2 deletions shared/store/loans.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { WhaleApiClient } from '@defichain/whale-api-client'
import { CollateralToken, LoanScheme, LoanToken, LoanVaultActive, LoanVaultLiquidated, LoanVaultState } from '@defichain/whale-api-client/dist/api/loan'
import { CollateralToken, LoanScheme, LoanToken, LoanVaultActive, LoanVaultLiquidated, LoanVaultState, LoanVaultTokenAmount } from '@defichain/whale-api-client/dist/api/loan'
import { createAsyncThunk, createSlice, PayloadAction, createSelector } from '@reduxjs/toolkit'
import BigNumber from 'bignumber.js'

Expand All @@ -23,6 +23,35 @@ const initialState: LoansState = {
hasFetchedLoansData: false
}

const customDUSDActivePrice = {
id: 'custom_DUSD',
key: 'custom_DUSD',
sort: '',
isLive: true,
block: {
hash: '',
height: 0,
time: 0,
medianTime: 0
},
active: {
amount: '1',
weightage: 1,
oracles: {
active: 1,
total: 1
}
},
next: {
amount: '1',
weightage: 1,
oracles: {
active: 1,
total: 1
}
}
}

// TODO (Harsh) Manage pagination for all api
export const fetchVaults = createAsyncThunk(
'wallet/fetchVaults',
Expand Down Expand Up @@ -81,8 +110,58 @@ export const nonLiquidatedVault = createSelector((state: LoansState) => state.va
export const ascColRatioLoanScheme = createSelector((state: LoansState) => state.loanSchemes,
(schemes) => schemes.map((c) => c).sort((a, b) => new BigNumber(a.minColRatio).minus(b.minColRatio).toNumber()))

export const loanTokensSelector = createSelector((state: LoansState) => state.loanTokens, loanTokens => {
return loanTokens.map(loanToken => {
if (loanToken.token.symbol === 'DUSD') {
const modifiedLoanToken: LoanToken = {
...loanToken,
activePrice: customDUSDActivePrice
}
return modifiedLoanToken
} else {
return { ...loanToken }
}
})
})

const selectTokenId = (state: LoansState, tokenId: string): string => tokenId

export const loanTokenByTokenId = createSelector([selectTokenId, (state: LoansState) => state.loanTokens], (tokenId, loanTokens) => {
export const loanTokenByTokenId = createSelector([selectTokenId, loanTokensSelector], (tokenId, loanTokens) => {
return loanTokens.find(loanToken => loanToken.token.id === tokenId)
})

export const vaultsSelector = createSelector((state: LoansState) => state.vaults, vaults => {
return vaults.map(vault => {
if (vault.state === LoanVaultState.IN_LIQUIDATION) {
return { ...vault }
}

const modifiedLoanAmounts = vault.loanAmounts.map(loanAmount => {
if (loanAmount.symbol === 'DUSD') {
const modifiedLoanAmount: LoanVaultTokenAmount = {
...loanAmount,
activePrice: customDUSDActivePrice
}
return modifiedLoanAmount
}
return { ...loanAmount }
})

const modifiedInterestAmounts = vault.interestAmounts.map(interestAmount => {
if (interestAmount.symbol === 'DUSD') {
const modifiedInterestAmount: LoanVaultTokenAmount = {
...interestAmount,
activePrice: customDUSDActivePrice
}
return modifiedInterestAmount
}
return { ...interestAmount }
})

return {
...vault,
loanAmounts: modifiedLoanAmounts,
interestAmounts: modifiedInterestAmounts
}
}) as LoanVault[]
})

0 comments on commit f45c1a0

Please sign in to comment.