Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added VaultLiquidationTransactionTable and VaultLiquidationTransactionFlow #454

Merged
merged 19 commits into from
Sep 15, 2022
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
b3e4fdc
Add VaultLiquidationTransactionTable component and stories
aomafarag Sep 9, 2022
47d7e48
Use float for transaction fees and correct net profit calculation
aomafarag Sep 9, 2022
11dcdf0
Add signs in transaction table and remove extra space in FormatCurrency
aomafarag Sep 9, 2022
8b5d765
Merge branch 'main' into vault-transaction-table
aomafarag Sep 12, 2022
000870d
Add AnimatedArrow
aomafarag Sep 12, 2022
512b271
Merge branch 'main' into vault-transaction-table
aomafarag Sep 13, 2022
d7a2039
Add explanations for incentives
aomafarag Sep 13, 2022
5ed7bc7
Remove Explain block from transaction fee
aomafarag Sep 13, 2022
7a6e629
Move vault directory
aomafarag Sep 13, 2022
fe7c0f8
Added VaultLiquidationTransactionFlow and improved VaultLiquidationTr…
zoey-kaiser Sep 14, 2022
580ae57
Requested changes
zoey-kaiser Sep 14, 2022
3294272
Merge branch 'main' into vault-transaction-table
zoey-kaiser Sep 14, 2022
5a83a51
Integrated VaultLiquidationLimitsCheck into VaultLiquidationTransacti…
zoey-kaiser Sep 14, 2022
d016be5
Updated VaultLiquidationLimitsCheckPanel with more fallbacks
zoey-kaiser Sep 15, 2022
254fb5a
Sync is-correct with VaultLiquidationLimitsCheckPanel
zoey-kaiser Sep 15, 2022
cf54cab
merge main into vault-transaction-table
zoey-kaiser Sep 15, 2022
79a887e
Added final changes and panel
zoey-kaiser Sep 15, 2022
39abfe3
Made more props required in VaultLiquidationLimitsCheckPanel
zoey-kaiser Sep 15, 2022
f3022ab
Update frontend/components/vault/VaultLiquidationTransactionFlow.vue
valiafetisov Sep 15, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion frontend/components/common/formatters/FormatCurrency.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<template>
<span>
<span v-if="isNotANumber">Unknown</span>
<span v-else> {{ sign }}<animated-number :value="value" :decimal-places="decimalPlaces" /> </span>
<span v-else>{{ sign }}<animated-number :value="value" :decimal-places="decimalPlaces" /> </span>
<span class="uppercase">{{ currency }}</span>
</span>
</template>
Expand Down
2 changes: 1 addition & 1 deletion frontend/components/common/formatters/FormatPercentage.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export default Vue.extend({
name: 'FormatPercentage',
props: {
value: {
type: Number,
type: [Number, String],
required: true,
},
},
Expand Down
9 changes: 6 additions & 3 deletions frontend/components/common/other/AnimatedArrow.vue
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
<template>
<UpArrow :style="style" />
<UpArrow v-if="direction" :style="style" />
zoey-kaiser marked this conversation as resolved.
Show resolved Hide resolved
</template>

<script lang="ts">
import Vue from 'vue';
import UpArrow from '~/assets/icons/uparrow.svg';

type ArrowDirections = 'up' | 'down' | 'left' | 'right';
export type ArrowDirections = 'up' | 'down' | 'left' | 'right';

export default Vue.extend({
components: {
Expand All @@ -15,11 +15,14 @@ export default Vue.extend({
props: {
direction: {
type: String as Vue.PropType<ArrowDirections>,
required: true,
default: undefined,
},
zoey-kaiser marked this conversation as resolved.
Show resolved Hide resolved
},
computed: {
style(): Object {
if (!this.direction) {
return undefined;
}
zoey-kaiser marked this conversation as resolved.
Show resolved Hide resolved
let rotationDegree = 0;
if (this.direction === 'down') {
rotationDegree = 180;
Expand Down
75 changes: 39 additions & 36 deletions frontend/components/panels/VaultLiquidationLimitsCheckPanel.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,31 +9,31 @@
</TextBlock>
<div class="flex justify-between mt-4">
<span>Current global limit</span>
<span v-if="!isGlobalLimitMissing"
><Explain :text="format(liquidationLimits.maximumProtocolDebtDai)"
>The maximum allowed amount of DAI needed to cover the debt and liquidation incentives of all
active auctions. In maker terms it is called
<span v-if="!isGlobalLimitMissing && debtAndIncentives">
<Explain :text="format(liquidationLimits.maximumProtocolDebtDai)">
The maximum allowed amount of DAI needed to cover the debt and liquidation incentives of all active
auctions. In maker terms it is called
<a
href="https://docs.makerdao.com/smart-contract-modules/dog-and-clipper-detailed-documentation#dog-hole-rad"
target="_blank"
>dog.Hole</a
></Explain
>
>
</Explain>
-
<Explain :text="format(liquidationLimits.currentProtocolDebtDai)"
>The amount of DAI needed to cover the debt and liquidation incentives of all active auctions. In
<Explain :text="format(liquidationLimits.currentProtocolDebtDai)">
The amount of DAI needed to cover the debt and liquidation incentives of all active auctions. In
maker terms it is called
<a
href="https://docs.makerdao.com/smart-contract-modules/dog-and-clipper-detailed-documentation#limits-on-dai-needed-to-cover-debt-and-fees-of-active-auctions"
target="_blank"
>dog.Dirt</a
></Explain
>
>
</Explain>
-
<Explain :text="format(debtAndIncentives)"
>The amount of DAI that will be auctioned after the current liquidation plus liquidation incentives
of this auction</Explain
>
<Explain :text="format(debtAndIncentives)">
The amount of DAI that will be auctioned after the current liquidation plus liquidation incentives
of this auction
</Explain>
= <FormatCurrency :value="globalDifference" currency="DAI"
/></span>
<div v-else>
Expand All @@ -43,31 +43,31 @@
</div>
<div class="flex justify-between">
<span>Current {{ collateralType }} limit</span>
<span v-if="!isCollateralLimitMissing"
><Explain :text="format(liquidationLimits.maximumCollateralDebtDai)"
>The amount of DAI needed to cover the debt and liquidation incentives of active
<span v-if="!isCollateralLimitMissing && debtAndIncentives">
<Explain :text="format(liquidationLimits.maximumCollateralDebtDai)">
The amount of DAI needed to cover the debt and liquidation incentives of active
{{ collateralType }} auctions. In maker terms it is called
<a
href="https://docs.makerdao.com/smart-contract-modules/dog-and-clipper-detailed-documentation#dog-ilk.hole-rad"
target="_blank"
>ilk.hole</a
></Explain
>
>
</Explain>
-
<Explain :text="format(liquidationLimits.currentCollateralDebtDai)"
>The amount of DAI needed to cover the debt and liquidation incentives of active
<Explain :text="format(liquidationLimits.currentCollateralDebtDai)">
The amount of DAI needed to cover the debt and liquidation incentives of active
{{ collateralType }} auctions. In maker terms it is called
<a
href="https://docs.makerdao.com/smart-contract-modules/dog-and-clipper-detailed-documentation#limits-on-dai-needed-to-cover-debt-and-fees-of-active-auctions"
target="_blank"
>ilk.dirt</a
></Explain
>
>
</Explain>
-
<Explain :text="format(debtAndIncentives)"
>The amount of DAI that will be auctioned after the current liquidation plus liquidation incentives
of this auction</Explain
>
<Explain :text="format(debtAndIncentives)">
The amount of DAI that will be auctioned after the current liquidation plus liquidation incentives
of this auction
</Explain>
= <FormatCurrency :value="collateralDifference" currency="DAI"
/></span>
<div v-else>
Expand Down Expand Up @@ -111,23 +111,23 @@ export default Vue.extend({
props: {
liquidationLimits: {
type: Object as Vue.PropType<LiquidationLimits>,
default: undefined,
zoey-kaiser marked this conversation as resolved.
Show resolved Hide resolved
},
collateralType: {
type: String,
required: true,
},
debtDai: {
type: BigNumber,
required: true,
default: undefined,
zoey-kaiser marked this conversation as resolved.
Show resolved Hide resolved
},
incentiveRelativeDai: {
type: BigNumber,
required: true,
default: undefined,
},
incentiveConstantDai: {
type: BigNumber,
required: true,
},
collateralType: {
type: String,
required: true,
default: undefined,
},
isRefreshing: {
type: Boolean,
Expand All @@ -139,7 +139,10 @@ export default Vue.extend({
},
},
computed: {
debtAndIncentives(): BigNumber {
debtAndIncentives(): BigNumber | undefined {
if (!this.debtDai || !this.incentiveConstantDai || !this.incentiveRelativeDai) {
return undefined;
}
zoey-kaiser marked this conversation as resolved.
Show resolved Hide resolved
return this.debtDai.plus(this.incentiveRelativeDai).plus(this.incentiveConstantDai);
},
globalDifference(): BigNumber {
Expand All @@ -161,7 +164,7 @@ export default Vue.extend({
);
},
currentStateAndTitle(): PanelProps {
if (this.isGlobalLimitMissing || this.isCollateralLimitMissing) {
if (this.isGlobalLimitMissing || this.isCollateralLimitMissing || !this.debtAndIncentives) {
return {
name: 'inactive',
title: 'Current liquidation limits are unknown',
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import { storiesOf } from '@storybook/vue';
import faker from 'faker';
import BigNumber from 'bignumber.js';
import VaultLiquidationTransactionFlow from '~/components/vault/VaultLiquidationTransactionFlow';
import {
generateFakeLiquidationLimits,
generateFakeVaultLiquidatedTransaction,
generateFakeVaultNotLiquidatedTransaction,
} from '~/helpers/generateFakeVault';

const common = {
components: { VaultLiquidationTransactionFlow },
data: () => ({
vaultTransaction: generateFakeVaultNotLiquidatedTransaction(),
liquidationLimits: generateFakeLiquidationLimits(),

isConnectingWallet: false,
walletAddress: undefined,

isRefreshingLimits: false,
}),
methods: {
connect() {
this.isConnectingWallet = true;
setTimeout(() => {
this.walletAddress = faker.finance.ethereumAddress();
this.isConnectingWallet = false;
}, 1000);
},
disconnect() {
this.isConnectingWallet = true;
setTimeout(() => {
this.walletAddress = undefined;
this.isConnectingWallet = false;
}, 1000);
},
refreshLimits() {
this.isRefreshingLimits = true;
setTimeout(() => {
this.liquidationLimits = {
maximumProtocolDebtDai: new BigNumber(1000000),
maximumCollateralDebtDai: new BigNumber(1000000),
currentProtocolDebtDai: new BigNumber(0),
currentCollateralDebtDai: new BigNumber(0),
};
this.isRefreshingLimits = false;
}, 1000);
},
},
template: `
<VaultLiquidationTransactionFlow
v-bind="$data"
@connectWallet="connect"
@disconnectWallet="disconnect"
@refreshLimits='refreshLimits'
/>`,
};

storiesOf('Vault/VaultLiquidationTransactionFlow', module)
.add('Default', () => ({
...common,
}))
.add('Liquidated', () => ({
...common,
data: () => ({
...common.data(),
vaultTransaction: generateFakeVaultLiquidatedTransaction(),
}),
}));
127 changes: 127 additions & 0 deletions frontend/components/vault/VaultLiquidationTransactionFlow.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
<template>
<div>
<TextBlock title="Vault Liquidation transaction" />
<Alert v-if="vaultTransaction.state === 'liquidated'" show-icon type="warning">
<div slot="message">
<p>This vault has been liquidated into a collateral auction</p>
<div class="flex justify-end mt-2">
<nuxt-link :to="auctionLink">
<Button> View collateral auction {{ vaultTransaction.auctionId }} </Button>
</nuxt-link>
</div>
</div>
</Alert>
<VaultLiquidationTransactionTable class="my-4" :vault-transaction="vaultTransaction" />
zoey-kaiser marked this conversation as resolved.
Show resolved Hide resolved
<TextBlock class="mb-8">
<template v-if="vaultTransaction.state === 'liquidated'">
This vault was liquidated <TimeTill :date="vaultTransaction.liqudiationDate" /> in the transaction
<FormatAddress :value="vaultTransaction.transactionHash" />.
</template>
<template v-else>
Please note, the
<Explain text="transaction fee" width="350px">
<TransactionFeesTable
:fees="{ LiquidationFee: vaultTransaction.transactionFeeLiquidationEth }"
:combined-fees-eth="vaultTransaction.transactionFeeLiquidationEth"
/>
</Explain>
is a suggested value based on the current gas prices on the market; the “potential net profit” is also
approximate, since it is extrapolated from the exchange rates and may change during the transaction. If
you’re executing transactions with other participants at the same time, the one who pays a higher
transaction fee has more chances to receive the incentive. In case your transaction will be rejected,
it will only result in the loss of the transaction fee.
</template>
</TextBlock>
<div class="mb-4">
<WalletConnectionCheckPanel
:wallet-address="walletAddress"
:is-loading="isConnectingWallet"
:is-explanations-shown="isExplanationsShown"
:is-correct.sync="isWalletConnected"
@connectWallet="$emit('connectWallet')"
@disconnectWallet="$emit('disconnectWallet')"
/>
<VaultLiquidationLimitsCheckPanel
zoey-kaiser marked this conversation as resolved.
Show resolved Hide resolved
:liquidation-limits="liquidationLimits"
:collateral-type="vaultTransaction.collateralType"
:debt-dai="vaultTransaction.debtDai"
:incentive-relative-dai="vaultTransaction.incentiveRelativeDai"
:incentive-constant-dai="vaultTransaction.incentiveConstantDai"
:is-refreshing="isRefreshingLimits"
:is-explanations-shown="isExplanationsShown"
@refreshLimits="$emit('refreshLimits')"
/>
<!-- LiquidationPanel -->
zoey-kaiser marked this conversation as resolved.
Show resolved Hide resolved
</div>
</div>
</template>

<script lang="ts">
import Vue from 'vue';
import { Alert, Button } from 'ant-design-vue';
import { LiquidationLimits, VaultTransactionNotLiquidated } from 'auctions-core/dist/src/types';
import TransactionFeesTable from '../auction/TransactionFeesTable.vue';
import { generateLink } from '../../helpers/generateLink';
import TimeTill from '../common/formatters/TimeTill.vue';
import FormatAddress from '../common/formatters/FormatAddress.vue';
import VaultLiquidationLimitsCheckPanel from '../panels/VaultLiquidationLimitsCheckPanel.vue';
import VaultLiquidationTransactionTable from './VaultLiquidationTransactionTable.vue';
import WalletConnectionCheckPanel from '~/components/panels/WalletConnectionCheckPanel.vue';
import TextBlock from '~/components/common/other/TextBlock.vue';
import Explain from '~/components/common/other/Explain.vue';

export default Vue.extend({
components: {
VaultLiquidationLimitsCheckPanel,
FormatAddress,
TimeTill,
TransactionFeesTable,
VaultLiquidationTransactionTable,
TextBlock,
Alert,
Button,
WalletConnectionCheckPanel,
Explain,
},
props: {
vaultTransaction: {
type: Object as Vue.PropType<VaultTransactionNotLiquidated>,
required: true,
},
valiafetisov marked this conversation as resolved.
Show resolved Hide resolved
liquidationLimits: {
type: Object as Vue.PropType<LiquidationLimits>,
required: true,
},
walletAddress: {
type: String,
default: null,
},
isConnectingWallet: {
type: Boolean,
default: false,
},
isRefreshingLimits: {
type: Boolean,
default: false,
},
isExplanationsShown: {
type: Boolean,
default: true,
},
},
data() {
return {
isWalletConnected: false,
};
},
computed: {
auctionLink(): string | undefined {
if (!this.vaultTransaction || !this.vaultTransaction.auctionId) {
return undefined;
}
const link = generateLink(this.vaultTransaction.network, 'collateral');
return `${link}&auction=${encodeURIComponent(this.vaultTransaction.auctionId)}`;
},
},
});
</script>
Loading