Skip to content

Commit

Permalink
Merge pull request #39 from iiAku/fix/update-collateral-ratio
Browse files Browse the repository at this point in the history
fix: make sure all computations are on-chain value collateral ratio b…
  • Loading branch information
Fitblip authored Oct 12, 2023
2 parents 07ab2b6 + 8a88b7e commit 5d92347
Show file tree
Hide file tree
Showing 11 changed files with 82 additions and 56 deletions.
1 change: 1 addition & 0 deletions src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ export default {
this.$store.collateralRate = minterStorage.collateralizationPercentage;
this.$store.privateLiquidationThreshold = minterStorage.privateOwnerLiquidationThreshold || null;
this.$store.collateralOperand = this.$store.collateralRate.minus(this.$store.privateLiquidationThreshold ?? 0).dividedBy(Math.pow(10, 20))
},
async updateAllOvenData(){
try {
Expand Down
47 changes: 16 additions & 31 deletions src/components/Oven.vue
Original file line number Diff line number Diff line change
Expand Up @@ -182,16 +182,16 @@
</p>
<p class="heading">
Collateral Utilization:
<strong v-if="collatoralizedRate(ovenData.balance) < 80"
>{{ collatoralizedRate(ovenData.balance) }}%</strong
<strong v-if="collatoralizedRate(ovenData) < 80"
>{{ collatoralizedRate(ovenData) }}%</strong
>
<strong
v-else-if="collatoralizedRate(ovenData.balance) < 100"
v-else-if="collatoralizedRate(ovenData) < 100"
class="has-text-warning"
>{{ collatoralizedRate(ovenData.balance) }}%</strong
>{{ collatoralizedRate(ovenData) }}%</strong
>
<strong v-else class="has-text-danger"
>{{ collatoralizedRate(ovenData.balance) }}%</strong
>{{ collatoralizedRate(ovenData) }}%</strong
>

<span v-if="!outstandingTokens(ovenAddress).isZero()">
Expand All @@ -211,28 +211,28 @@

<div class="allocation-info is-fullwidth">
<progress
v-if="collatoralizedRate(ovenData.balance) < 80"
v-if="collatoralizedRate(ovenData) < 80"
class="progress is-primary"
:value="collatoralizedRate(ovenData.balance)"
:value="collatoralizedRate(ovenData)"
max="100"
>
{{ collatoralizedRate(ovenData.balance) }}%
{{ collatoralizedRate(ovenData) }}%
</progress>
<progress
v-else-if="collatoralizedRate(ovenData.balance) < 100"
v-else-if="collatoralizedRate(ovenData) < 100"
class="progress is-warning"
:value="collatoralizedRate(ovenData.balance)"
:value="collatoralizedRate(ovenData)"
max="100"
>
{{ collatoralizedRate(ovenData.balance) }}%
{{ collatoralizedRate(ovenData) }}%
</progress>
<progress
v-else
class="progress is-danger"
:value="collatoralizedRate(ovenData.balance)"
:value="collatoralizedRate(ovenData)"
max="100"
>
{{ collatoralizedRate(ovenData.balance) }}%
{{ collatoralizedRate(ovenData) }}%
</progress>
</div>
</div>
Expand Down Expand Up @@ -402,31 +402,16 @@ export default {
.dividedBy(Math.pow(10, 6))
.multipliedBy(ovenBalance.dividedBy(Math.pow(10, 6)));
let valueHalf = currentValue.dividedBy(2);
let valueHalf = currentValue.dividedBy(this.$store.collateralOperand);
let borrowedTokens = this.ovenData.outstandingTokens.dividedBy(
Math.pow(10, 18)
);
return valueHalf.minus(borrowedTokens).decimalPlaces(18);
},
collatoralizedRate(ovenBalance) {
if (parseInt(ovenBalance) === 0) {
return 0;
}
let currentValue = this.$store.priceData.price
.dividedBy(Math.pow(10, 6))
.multipliedBy(ovenBalance.dividedBy(Math.pow(10, 6)))
let valueHalf = currentValue.dividedBy(2);
let rate = this.ovenData.outstandingTokens
.dividedBy(Math.pow(10, 18))
.dividedBy(valueHalf)
.times(100);
return rate.toFixed(2);
collatoralizedRate(oven) {
return this.collatoralizedRateForOven(oven)
},
async updateOvenData() {
const keys = [
Expand Down
4 changes: 2 additions & 2 deletions src/components/PegVisualizer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -105,10 +105,10 @@ export default {
const harbingerPrice = this.$store.priceData.price.div(tezMantissa)
const percentOff = new BigNumber(1).minus(harbingerPrice.dividedBy(quipuPrice))
const halfPercentOff = percentOff.dividedBy(2)
const halfPercentOff = percentOff.dividedBy(this.$store.collateralOperand)
const kusdToRecv = tokenPool.times(halfPercentOff)
const onePercentOff = new BigNumber("0.01").dividedBy(2)
const onePercentOff = new BigNumber("0.01").dividedBy(this.$store.collateralOperand)
const pegDepth = tokenPool.times(onePercentOff)
const updatedTokenPoolAmt = tokenPool.minus(kusdToRecv)
Expand Down
10 changes: 5 additions & 5 deletions src/components/PublicOven.vue
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@
!oven.isLiquidated &&
$store.collateralRate
.dividedBy(Math.pow(10, 18))
.dividedBy(2)
.dividedBy(this.$store.collateralOperand)
.isLessThan(collatoralizedRateForOven(oven))
"
class="button is-danger is-small">
Expand Down Expand Up @@ -305,7 +305,7 @@ export default {
let currentValue = this.$store.priceData.price
.multipliedBy(ovenBalance)
.dividedBy(Math.pow(10, 10));
let valueHalf = currentValue.dividedBy(2);
let valueHalf = currentValue.dividedBy(this.$store.collateralOperand);
let borrowedTokens = this.oven.outstandingTokens.dividedBy(Math.pow(10, 18));
Expand All @@ -319,7 +319,7 @@ export default {
let currentValue = this.$store.priceData.price
.multipliedBy(ovenBalance)
.dividedBy(Math.pow(10, 10));
let valueHalf = currentValue.dividedBy(2);
let valueHalf = currentValue.dividedBy(this.$store.collateralOperand);
let rate = this.oven.outstandingTokens
.dividedBy(valueHalf)
Expand All @@ -339,12 +339,12 @@ export default {
return this.$store.collateralRate
.plus(this.$store.privateLiquidationThreshold)
.dividedBy(Math.pow(10, 18))
.dividedBy(2)
.dividedBy(this.$store.collateralOperand)
},
lpLiquidationThreshold(){
return this.$store.collateralRate
.dividedBy(Math.pow(10, 18))
.dividedBy(2)
.dividedBy(this.$store.collateralOperand)
}
},
components: {
Expand Down
12 changes: 6 additions & 6 deletions src/components/modal-subviews/Borrow.vue
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
<p class="heading">
<a
v-if="borrowAmtNumber.isLessThanOrEqualTo(maxSafeAmt.times(1.01))"
@click="borrowAmount = maxSafeAmt"
@click="borrowAmount = maxSafeAmt.toFixed(2)"
class="has-text-weight-bold"
>Max Safe (80%)</a
>
Expand Down Expand Up @@ -178,10 +178,10 @@ export default {
computed: {
maxSafeAmt() {
return this.ovenDollarValue(this.ovenAddress)
.dividedBy(2)
.multipliedBy(0.8)
.minus(this.outstandingTokensFormatted(this.ovenAddress))
.decimalPlaces(18);
.dividedBy(this.$store.collateralOperand)
.multipliedBy(0.8)
.minus(this.outstandingTokensFormatted(this.ovenAddress))
.decimalPlaces(18);
},
shouldAllowBorrow() {
if (!this.borrowAmount || this.borrowAmount <= 0) {
Expand All @@ -203,7 +203,7 @@ export default {
borrowAmount = 0;
}
const maxCollateral = this.ovenDollarValue(this.ovenAddress).dividedBy(2);
const maxCollateral = this.ovenDollarValue(this.ovenAddress).dividedBy(this.$store.collateralOperand);
const borrowedTokens = this.outstandingTokensFormatted(this.ovenAddress);
Expand Down
2 changes: 1 addition & 1 deletion src/components/modal-subviews/Deposit.vue
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ export default {
depositAmount = 0
}
const maxCollateral = this.ovenDollarValuePlusDeposit(this.ovenAddress, depositAmount).dividedBy(2)
const maxCollateral = this.ovenDollarValuePlusDeposit(this.ovenAddress, depositAmount).dividedBy(this.$store.collateralOperand)
const borrowedTokens = this.outstandingTokensFormatted(this.ovenAddress)
Expand Down
2 changes: 1 addition & 1 deletion src/components/modal-subviews/Repay.vue
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ export default {
repayAmount = 0;
}
const maxCollateral = this.ovenDollarValue(this.ovenAddress).dividedBy(2);
const maxCollateral = this.ovenDollarValue(this.ovenAddress).dividedBy(this.$store.collateralOperand);
const borrowedTokens = this.outstandingTokensFormatted(this.ovenAddress);
Expand Down
4 changes: 2 additions & 2 deletions src/components/modal-subviews/Withdraw.vue
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ export default {
const ovenValue = this.ovenDollarValue(this.ovenAddress); // USD
let ovenValueFormatted = ovenValue
.dividedBy(2)
.dividedBy(this.$store.collateralOperand)
.minus(borrowedTokens)
.dividedBy(this.currentPriceFormatted())
.times(2)
Expand Down Expand Up @@ -198,7 +198,7 @@ export default {
const maxCollateralDollars = this.ovenDollarValueMinusWithdraw(
this.ovenAddress,
withdrawAmount
).dividedBy(2);
).dividedBy(this.$store.collateralOperand);
const borrowedTokens = this.outstandingTokensFormatted(this.ovenAddress);
Expand Down
24 changes: 16 additions & 8 deletions src/mixins.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import _, { find } from 'lodash'

import {ContractErrors} from '@hover-labs/kolibri-js'
import { ConversionUtils } from "@hover-labs/kolibri-js"
import axios from "axios";
import {customGetCollateralUtilization} from './utils'
import moment from "moment";

const errorMap = {
Expand Down Expand Up @@ -142,7 +145,7 @@ export default {
maxBorrowAmtkUSD(ovenAddress) {
const borrowedTokens = this.outstandingTokensFormatted(ovenAddress)
const ovenValue = this.ovenDollarValue(ovenAddress)
return ovenValue.dividedBy(2).minus(borrowedTokens).decimalPlaces(18)
return ovenValue.dividedBy(this.$store.collateralOperand).minus(borrowedTokens).decimalPlaces(18)
},
collatoralizationWarningClasses(rate) {
if (rate > 100) {
Expand All @@ -154,7 +157,7 @@ export default {
}
},
currentCollateralRate(ovenAddress) {
const maxCollateral = this.ovenDollarValue(ovenAddress).dividedBy(2)
const maxCollateral = this.ovenDollarValue(ovenAddress).dividedBy(this.$store.collateralOperand)

const borrowedTokens = this.outstandingTokensFormatted(ovenAddress)

Expand All @@ -166,14 +169,19 @@ export default {
return borrowedTokens.dividedBy(maxCollateral).times(100)
},
collatoralizedRateForOven(oven){
if (parseInt(oven.balance) === 0) { return 0 }

let currentValue = this.$store.priceData.price.multipliedBy(oven.balance).dividedBy(Math.pow(10, 10))
let valueHalf = currentValue.dividedBy(2)
const collateralUtilization = customGetCollateralUtilization(
this.$store.priceData.price,
oven.balance,
oven.outstandingTokens
)

let rate = oven.outstandingTokens.dividedBy(valueHalf).dividedBy(Math.pow(10, 14))
const rate = collateralUtilization.multipliedBy(
this.$store.collateralOperand
)

return rate.toFixed(2)
return parseFloat(
ConversionUtils.shardToHumanReadablePercentage(rate)
).toFixed(2)
},
ovenBalance(ovenAddress){
if (!this.$store.ownedOvens[ovenAddress]) { return 0 }
Expand Down
1 change: 1 addition & 0 deletions src/store.js
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@ let state = Vue.observable({
stabilityFee: null,
privateLiquidationThreshold: null,
collateralRate: null,
collateralOperand: null,
ownedOvens: null,
balanceData: null,
wallet: null,
Expand Down
31 changes: 31 additions & 0 deletions src/utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import BigNumber from "bignumber.js"
/*
Credits goes to: https://github.com/Hover-Labs/kolibri-js/blob/master/src/oven-client.ts
As the vast majority of helpers from here were either took, modified or inspired from kolibri-js module
*/

const MUTEZ_DIGITS = 6
const SHARD_DIGITS = 18

const MUTEZ_TO_SHARD = new BigNumber(Math.pow(10, SHARD_DIGITS - MUTEZ_DIGITS))

const SHARD_PRECISION = new BigNumber(Math.pow(10, SHARD_DIGITS))

export const customGetCollateralUtilization = (
price,
balance,
outstandingTokens
) => {
const priceShard = price.multipliedBy(MUTEZ_TO_SHARD)
const collateralValue = balance
.multipliedBy(MUTEZ_TO_SHARD)
.multipliedBy(priceShard)
.dividedBy(SHARD_PRECISION)

return new BigNumber(
outstandingTokens
.times(Math.pow(10, SHARD_DIGITS))
.dividedBy(collateralValue)
.toFixed(0)
)
}

0 comments on commit 5d92347

Please sign in to comment.