Skip to content

Commit

Permalink
decimal changes
Browse files Browse the repository at this point in the history
  • Loading branch information
onnovisser committed Sep 29, 2023
1 parent fb56b73 commit 5754922
Show file tree
Hide file tree
Showing 7 changed files with 74 additions and 161 deletions.
4 changes: 2 additions & 2 deletions centrifuge-app/src/pages/IssuerPool/Assets/CreateLoan.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -237,12 +237,12 @@ function IssuerCreateLoan() {
valuationMethod: values.pricing.valuationMethod,
maxPriceVariation: Rate.fromPercent(values.pricing.maxPriceVariation),
maxBorrowAmount: values.pricing.maxBorrowQuantity
? CurrencyBalance.fromFloat(values.pricing.maxBorrowQuantity, decimals)
? Price.fromFloat(values.pricing.maxBorrowQuantity)
: null,
Isin: values.pricing.Isin || '',
maturityDate: new Date(values.pricing.maturityDate),
interestRate: Rate.fromPercent(values.pricing.interestRate),
notional: Price.fromFloat(values.pricing.notional),
notional: CurrencyBalance.fromFloat(values.pricing.notional, decimals),
}
: {
valuationMethod: values.pricing.valuationMethod,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ export function PricingInput({ poolId }: { poolId: string }) {
errorMessage={meta.touched ? meta.error : undefined}
onChange={(value) => form.setFieldValue('pricing.notional', value)}
variant="small"
currency={pool.currency.symbol}
/>
)}
</Field>
Expand Down
34 changes: 12 additions & 22 deletions centrifuge-app/src/pages/Loan/ExternalFinanceForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { formatBalance } from '../../utils/formatting'
import { useFocusInvalidInput } from '../../utils/useFocusInvalidInput'
import { useAvailableFinancing } from '../../utils/useLoans'
import { useBorrower } from '../../utils/usePermissions'
import { useBorrowerAssetTransactions, usePool } from '../../utils/usePools'
import { usePool } from '../../utils/usePools'
import { combine, max, positiveNumber, settlementPrice } from '../../utils/validation'

type FinanceValues = {
Expand Down Expand Up @@ -60,11 +60,9 @@ export function ExternalFinanceForm({ loan }: { loan: LoanType }) {
faceValue: '',
},
onSubmit: (values, actions) => {
const price = CurrencyBalance.fromFloat(values.price, pool.currency.decimals).div(new BN(100))
const price = CurrencyBalance.fromFloat(values.price, pool.currency.decimals)
const quantity = Price.fromFloat(
Price.fromFloat(values.faceValue)
.div((loan.pricing as ExternalPricingInfo).notional)
.toString()
Dec(values.faceValue).div((loan.pricing as ExternalPricingInfo).notional.toDecimal())
)

doFinanceTransaction([loan.poolId, loan.id, quantity, price], {
Expand All @@ -81,11 +79,9 @@ export function ExternalFinanceForm({ loan }: { loan: LoanType }) {
faceValue: '',
},
onSubmit: (values, actions) => {
const price = CurrencyBalance.fromFloat(values.price, pool.currency.decimals).div(new BN(100))
const price = CurrencyBalance.fromFloat(values.price, pool.currency.decimals)
const quantity = Price.fromFloat(
Price.fromFloat(values.faceValue)
.div((loan.pricing as ExternalPricingInfo).notional)
.toString()
Dec(values.faceValue).div((loan.pricing as ExternalPricingInfo).notional.toDecimal())
)

doRepayTransaction([loan.poolId, loan.id, quantity, new BN(0), new BN(0), price], {
Expand All @@ -102,8 +98,6 @@ export function ExternalFinanceForm({ loan }: { loan: LoanType }) {
const repayFormRef = React.useRef<HTMLFormElement>(null)
useFocusInvalidInput(repayForm, repayFormRef)

const { currentFace } = useBorrowerAssetTransactions(loan.poolId, loan.id)

if (loan.status === 'Closed' || ('valuationMethod' in loan.pricing && loan.pricing.valuationMethod !== 'oracle')) {
return null
}
Expand Down Expand Up @@ -150,7 +144,7 @@ export function ExternalFinanceForm({ loan }: { loan: LoanType }) {
const num = val instanceof Decimal ? val.toNumber() : val
const financeAmount = Dec(num)
.mul(financeForm.values.faceValue || 1)
.div(100)
.div((loan.pricing as ExternalPricingInfo).notional.toDecimal())

return financeAmount.gt(availableFinancing)
? `Amount exceeds available reserve (${formatBalance(
Expand All @@ -163,7 +157,7 @@ export function ExternalFinanceForm({ loan }: { loan: LoanType }) {
(val) => {
const financeAmount = Dec(val)
.mul(financeForm.values.faceValue || 1)
.div(100)
.div((loan.pricing as ExternalPricingInfo).notional.toDecimal())

return financeAmount.gt(maxBorrow)
? `Amount exceeds max borrow (${formatBalance(maxBorrow, pool?.currency.symbol, 2)})`
Expand Down Expand Up @@ -195,7 +189,7 @@ export function ExternalFinanceForm({ loan }: { loan: LoanType }) {
? formatBalance(
Dec(financeForm.values.price || 0)
.mul(Dec(financeForm.values.faceValue || 0))
.div(100),
.div((loan.pricing as ExternalPricingInfo).notional.toDecimal()),
pool?.currency.symbol,
2
)
Expand All @@ -221,11 +215,7 @@ export function ExternalFinanceForm({ loan }: { loan: LoanType }) {
<Shelf justifyContent="space-between">
<Text variant="label2">Outstanding</Text>
{/* outstandingDebt needs to be rounded down, b/c onSetMax displays the rounded down value as well */}
<Text variant="label2">
{'valuationMethod' in loan.pricing && loan.pricing.valuationMethod === 'oracle'
? formatBalance(new CurrencyBalance(currentFace, 18), pool.currency.symbol, 2, 2)
: ''}
</Text>
<Text variant="label2">{formatBalance(loan.outstandingDebt, pool.currency.symbol, 2, 2)}</Text>
</Shelf>
</Stack>

Expand Down Expand Up @@ -260,7 +250,7 @@ export function ExternalFinanceForm({ loan }: { loan: LoanType }) {
const num = val instanceof Decimal ? val.toNumber() : val
const repayAmount = Dec(num)
.mul(repayForm.values.faceValue || 1)
.div(100)
.div((loan.pricing as ExternalPricingInfo).notional.toDecimal())

return repayAmount.gt(balance)
? `Your wallet balance (${formatBalance(
Expand All @@ -275,7 +265,7 @@ export function ExternalFinanceForm({ loan }: { loan: LoanType }) {
const num = val instanceof Decimal ? val.toNumber() : val
const repayAmount = Dec(num)
.mul(repayForm.values.faceValue || 1)
.div(100)
.div((loan.pricing as ExternalPricingInfo).notional.toDecimal())

return repayAmount.gt(debt) ? 'Amount exceeds outstanding' : ''
}
Expand Down Expand Up @@ -306,7 +296,7 @@ export function ExternalFinanceForm({ loan }: { loan: LoanType }) {
? formatBalance(
Dec(repayForm.values.price || 0)
.mul(Dec(repayForm.values.faceValue || 0))
.div(100),
.div((loan.pricing as ExternalPricingInfo).notional.toDecimal()),
pool?.currency.symbol,
2
)
Expand Down
50 changes: 17 additions & 33 deletions centrifuge-app/src/pages/Loan/HoldingsValues.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { BorrowerTransaction, CurrencyBalance, ExternalPricingInfo, Pool, PricingInfo } from '@centrifuge/centrifuge-js'
import BN from 'bn.js'
import { LabelValueStack } from '../../components/LabelValueStack'
import { Dec } from '../../utils/Decimal'
import { formatBalance } from '../../utils/formatting'

type Props = {
Expand All @@ -14,43 +15,15 @@ export function HoldingsValues({ pool, transactions, currentFace, pricing }: Pro
const netSpent =
transactions?.reduce((sum, trx) => {
if (trx.type === 'REPAID') {
sum = new CurrencyBalance(
sum.add(
trx.quantity && trx.settlementPrice
? new CurrencyBalance(
new BN(trx.quantity)
.mul((pricing as ExternalPricingInfo).notional)
.mul(new BN(trx.settlementPrice))
.div(new BN(10).pow(new BN(18)))
.div(new BN(10).pow(new BN(6))),
18
)
: new CurrencyBalance(0, pool.currency.decimals)
),
18
)
sum = trx.amount ? sum.add(trx.amount.toDecimal()) : sum
}

if (trx.type === 'BORROWED') {
sum = new CurrencyBalance(
sum.sub(
trx.quantity && trx.settlementPrice
? new CurrencyBalance(
new BN(trx.quantity)
.mul((pricing as ExternalPricingInfo).notional)
.mul(new BN(trx.settlementPrice))
.div(new BN(10).pow(new BN(18)))
.div(new BN(10).pow(new BN(6))),
18
)
: new CurrencyBalance(0, pool.currency.decimals)
),
18
)
sum = trx.amount ? sum.sub(trx.amount.toDecimal()) : sum
}

return sum
}, new CurrencyBalance(0, 18)) || new CurrencyBalance(0, 18)
}, Dec(0)) || Dec(0)

const getAverageSettlePrice = () => {
const settlementTransactions =
Expand Down Expand Up @@ -80,21 +53,32 @@ export function HoldingsValues({ pool, transactions, currentFace, pricing }: Pro

return (
<>
<LabelValueStack label="Current face" value={`${formatBalance(currentFace!, pool.currency.symbol, 2, 2)}`} />
<LabelValueStack
label="Current face"
value={currentFace ? `${formatBalance(currentFace, pool.currency.symbol, 2, 2)}` : '-'}
/>
<LabelValueStack label="Net spent" value={`${formatBalance(netSpent, pool.currency.symbol, 2, 2)}`} />
<LabelValueStack
label="Average settle price"
value={
getAverageSettlePrice().isZero()
? '-'
: `${formatBalance(
new CurrencyBalance(getAverageSettlePrice().mul(new BN(100)), pool.currency.decimals),
new CurrencyBalance(getAverageSettlePrice(), pool.currency.decimals),
pool.currency.symbol,
2,
2
)}`
}
/>
<LabelValueStack
label="Notional"
value={`${formatBalance((pricing as ExternalPricingInfo).notional, pool.currency.symbol, 2, 2)}`}
/>
<LabelValueStack
label="Quantity"
value={`${formatBalance((pricing as ExternalPricingInfo).outstandingQuantity, undefined, 2, 0)}`}
/>
</>
)
}
66 changes: 28 additions & 38 deletions centrifuge-app/src/pages/Loan/TransactionTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import BN from 'bn.js'
import { useMemo } from 'react'
import { DataTable } from '../../components/DataTable'
import { formatDate } from '../../utils/date'
import { Dec } from '../../utils/Decimal'
import { formatBalance } from '../../utils/formatting'

type Props = {
Expand Down Expand Up @@ -35,48 +36,39 @@ export const TransactionTable = ({ transactions, currency, loanType, decimals, p

return sortedTransactions.map((transaction, index, array) => ({
type: transaction.type,
amount: transaction.amount,
quantity: transaction.quantity ? new CurrencyBalance(transaction.quantity, 18) : null,
transactionDate: transaction.timestamp,
settlePrice: transaction.settlementPrice
? new CurrencyBalance(new BN(transaction.settlementPrice).mul(new BN(100)), decimals)
? new CurrencyBalance(new BN(transaction.settlementPrice), decimals)
: null,
faceFlow:
transaction.quantity && (pricing as ExternalPricingInfo).notional
? new CurrencyBalance(
new BN(transaction.quantity)
.mul((pricing as ExternalPricingInfo).notional)
.div(new BN(10).pow(new BN(18))),
18
)
? new CurrencyBalance(transaction.quantity, 18)
.toDecimal()
.mul((pricing as ExternalPricingInfo).notional.toDecimal())
: null,
position: array.slice(0, index + 1).reduce((sum, trx) => {
if (trx.type === 'BORROWED') {
sum = new CurrencyBalance(
sum.add(
trx.quantity
? new CurrencyBalance(
new BN(trx.quantity).mul((pricing as ExternalPricingInfo).notional).div(new BN(10).pow(new BN(18))),
18
)
: new CurrencyBalance(0, decimals)
),
decimals
sum = sum.add(
trx.quantity
? new CurrencyBalance(trx.quantity, 18)
.toDecimal()
.mul((pricing as ExternalPricingInfo).notional.toDecimal())
: Dec(0)
)
}
if (trx.type === 'REPAID') {
sum = new CurrencyBalance(
sum.sub(
trx.quantity
? new CurrencyBalance(
new BN(trx.quantity).mul((pricing as ExternalPricingInfo).notional).div(new BN(10).pow(new BN(18))),
18
)
: new CurrencyBalance(0, decimals)
),
decimals
sum = sum.sub(
trx.quantity
? new CurrencyBalance(trx.quantity, 18)
.toDecimal()
.mul((pricing as ExternalPricingInfo).notional.toDecimal())
: Dec(0)
)
}
return sum
}, new CurrencyBalance(0, 18)),
}, Dec(0)),
}))
}, [transactions, decimals, pricing])

Expand Down Expand Up @@ -126,6 +118,12 @@ export const TransactionTable = ({ transactions, currency, loanType, decimals, p
row.faceFlow ? `${row.type === 'REPAID' ? '-' : ''}${formatBalance(row.faceFlow, currency, 2, 2)}` : '-',
flex: '3',
},
{
align: 'left',
header: 'Quantity',
cell: (row) => (row.quantity ? formatBalance(row.quantity, undefined, 2, 0) : '-'),
flex: '2',
},
{
align: 'left',
header: 'Settle price',
Expand All @@ -136,21 +134,13 @@ export const TransactionTable = ({ transactions, currency, loanType, decimals, p
align: 'left',
header: 'Net cash flow',
cell: (row) =>
row.faceFlow && row.settlePrice
? `${row.type === 'BORROWED' ? '-' : ''}${formatBalance(
row.faceFlow.toDecimal().mul(new CurrencyBalance(row.settlePrice, decimals).toDecimal().div(100)),
currency,
2,
2
)}`
: '-',
row.amount ? `${row.type === 'BORROWED' ? '-' : ''}${formatBalance(row.amount, currency, 2, 2)}` : '-',
flex: '3',
},
{
align: 'left',
header: 'Position',
cell: (row) =>
row.type === 'CREATED' ? '-' : formatBalance(new CurrencyBalance(row.position, 18), currency, 2, 2),
cell: (row) => (row.type === 'CREATED' ? '-' : formatBalance(row.position, currency, 2, 2)),
flex: '3',
},
// TODO: add link to transaction
Expand Down
7 changes: 2 additions & 5 deletions centrifuge-app/src/pages/Loan/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -94,10 +94,7 @@ const Loan: React.FC<{ setShowOraclePricing?: () => void }> = ({ setShowOraclePr

const currentFace =
loan?.pricing && 'outstandingQuantity' in loan.pricing
? new CurrencyBalance(
loan.pricing.outstandingQuantity.mul(loan.pricing.notional).div(new BN(10).pow(new BN(18))),
18
)
? loan.pricing.outstandingQuantity.toDecimal().mul(loan.pricing.notional.toDecimal())
: null

const templateIds = poolMetadata?.loanTemplates?.map((s) => s.id) ?? []
Expand Down Expand Up @@ -136,7 +133,7 @@ const Loan: React.FC<{ setShowOraclePricing?: () => void }> = ({ setShowOraclePr

const getLatestPrice = () => {
if (loan?.pricing && 'oracle' in loan.pricing) {
const settlementPrice = borrowerAssetTransactions?.[borrowerAssetTransactions.length - 1].settlementPrice
const settlementPrice = borrowerAssetTransactions?.[borrowerAssetTransactions.length - 1]?.settlementPrice
const latestSettlementPrice = settlementPrice ? new BN(settlementPrice).mul(new BN(100)) : null

if (latestSettlementPrice && loan.pricing.oracle.value.isZero()) {
Expand Down
Loading

0 comments on commit 5754922

Please sign in to comment.