Skip to content

Commit

Permalink
feat: Bid with DAI flow (#160)
Browse files Browse the repository at this point in the history
  • Loading branch information
fegbert authored Mar 30, 2022
1 parent 48e1c00 commit 8604b16
Show file tree
Hide file tree
Showing 21 changed files with 699 additions and 286 deletions.
481 changes: 481 additions & 0 deletions core/src/abis/MCD_DOG.json

Large diffs are not rendered by default.

5 changes: 4 additions & 1 deletion core/src/auctions.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { Auction, AuctionInitialInfo, AuctionTransaction, Notifier, TakeEvent } from './types';
import BigNumber from './bignumber';
import fetchAuctionsByCollateralType, { fetchAuctionStatus } from './fetch';
import fetchAuctionsByCollateralType, { fetchAuctionStatus, fetchMinimumBidDai } from './fetch';
import { getCalleeData, getMarketPrice } from './calleeFunctions';
import { fetchCalcParametersByCollateralType } from './params';
import executeTransaction from './execute';
Expand All @@ -27,15 +27,18 @@ const enrichAuctionWithActualNumbers = async function (
if (!auction.isActive || auction.isFinished) {
return {
...auction,
minimumBidDai: new BigNumber(0),
unitPrice: new BigNumber(0),
approximateUnitPrice: new BigNumber(0),
totalPrice: new BigNumber(0),
};
}
const auctionStatus = await fetchAuctionStatus(network, auction.collateralType, auction.index);
const minimumBidDai = await fetchMinimumBidDai(network, auction.collateralType);
return {
...auction,
...auctionStatus,
minimumBidDai,
approximateUnitPrice: auctionStatus.unitPrice,
};
};
Expand Down
4 changes: 4 additions & 0 deletions core/src/contracts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import MCD_VAT from './abis/MCD_VAT.json';
import MCD_JOIN_DAI from './abis/MCD_JOIN_DAI.json';
import MCD_CLIP_CALC from './abis/MCD_CLIP_CALC.json';
import MCD_CLIP from './abis/MCD_CLIP.json';
import MCD_DOG from './abis/MCD_DOG.json';
import WSTETH from './abis/WSTETH.json';
import getSigner from './signer';

Expand All @@ -31,6 +32,9 @@ const getContractInterfaceByName = async function (contractName: string): Promis
if (contractName === 'MCD_VAT') {
return MCD_VAT;
}
if (contractName === 'MCD_DOG') {
return MCD_DOG;
}
if (contractName === 'WSTETH') {
return WSTETH;
}
Expand Down
23 changes: 19 additions & 4 deletions core/src/fetch.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import type { AuctionInitialInfo, AuctionStatus } from './types';
import { ethers } from 'ethers';
import memoizee from 'memoizee';
import BigNumber from './bignumber';
import getContract, { getClipperNameByCollateralType } from './contracts';
import { RAD, RAY, WAD } from './constants/UNITS';
import { getCollateralConfigByType } from './constants/COLLATERALS';
import convertNumberTo32Bytes from './helpers/convertNumberTo32Bytes';

const AUCTION_DURATION_CACHE_EXPIRY_MS = 24 * 60 * 60 * 1000;
const CACHE_EXPIRY_MS = 24 * 60 * 60 * 1000;

const _fetchMaximumAuctionDurationInSeconds = async function (
network: string,
Expand All @@ -18,18 +19,32 @@ const _fetchMaximumAuctionDurationInSeconds = async function (
};

const fetchMaximumAuctionDurationInSeconds = memoizee(_fetchMaximumAuctionDurationInSeconds, {
maxAge: AUCTION_DURATION_CACHE_EXPIRY_MS,
maxAge: CACHE_EXPIRY_MS,
promise: true,
length: 2,
});

const _fetchMinimumBidDai = async function (network: string, collateralType: string): Promise<BigNumber> {
const dogContract = await getContract(network, 'MCD_DOG');
const encodedCollateralType = ethers.utils.formatBytes32String(collateralType);
const collateralParameters = await dogContract.ilks(encodedCollateralType);
const minimumBidDai = new BigNumber(collateralParameters.dirt._hex).div(RAD);
return minimumBidDai;
};

export const fetchMinimumBidDai = memoizee(_fetchMinimumBidDai, {
maxAge: CACHE_EXPIRY_MS,
promise: true,
length: 2,
});

export const fetchAuctionStatus = async function (
network: string,
collateralType: string,
auctionId: number
auctionIndex: number
): Promise<AuctionStatus> {
const contract = await getContract(network, getClipperNameByCollateralType(collateralType));
const statusData = await contract.getStatus(convertNumberTo32Bytes(auctionId));
const statusData = await contract.getStatus(convertNumberTo32Bytes(auctionIndex));
const unitPrice = new BigNumber(statusData.price._hex).div(RAY);
const collateralAmount = new BigNumber(statusData.lot._hex).div(WAD);
const debtDAI = new BigNumber(statusData.tab._hex).div(RAD);
Expand Down
1 change: 1 addition & 0 deletions core/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ export declare interface Auction extends AuctionInitialInfo {
secondsTillNextPriceDrop?: number;
priceDropRatio?: BigNumber;
transactionGrossProfitDate?: Date;
minimumBidDai: BigNumber;
}

export declare interface TransactionFees {
Expand Down
11 changes: 2 additions & 9 deletions frontend/components/Auction.vue
Original file line number Diff line number Diff line change
Expand Up @@ -202,13 +202,10 @@
</template>
<TextBlock>
<div class="flex w-full justify-end flex-wrap mt-4">
<Tooltip placement="top">
<div v-if="!isPageNetworkFake" slot="title">
This feature is currently only supported for stub data.
</div>
<Tooltip :title="auctionError" placement="top">
<div>
<Button
:disabled="!isPageNetworkFake || !!auctionError"
:disabled="!!auctionError"
type="secondary"
class="w-60 mb-4"
@click="$emit('purchase')"
Expand Down Expand Up @@ -264,7 +261,6 @@ import Explain from '~/components/utils/Explain.vue';
import RestartBlock from '~/components/transaction/RestartBlock.vue';
import TimeTillProfitable from '~/components/utils/TimeTillProfitable.vue';
import AuctionEventsBlock from '~/components/AuctionEventsBlock.vue';
import { FAKE_NETWORK_NAME } from '~/store/network';
export default Vue.extend({
name: 'Auction',
Expand Down Expand Up @@ -351,9 +347,6 @@ export default Vue.extend({
}
return null;
},
isPageNetworkFake(): Boolean {
return this.auction?.network === FAKE_NETWORK_NAME;
},
},
watch: {
isExplanationsShown: {
Expand Down
30 changes: 4 additions & 26 deletions frontend/components/MainFlow.vue
Original file line number Diff line number Diff line change
Expand Up @@ -60,27 +60,21 @@
class="mt-6 mb-8 mx-8"
:auction-transaction="selectedAuction"
:is-connecting="isConnecting"
:is-granting-access="isGrantingAccess"
:is-depositing="isDepositingDai"
:is-authorizing="isAuthorizing"
:is-depositing-or-withdrawing="isDepositingOrWithdrawing"
:is-executing="isExecuting"
:is-wallet-authorised="isWalletAuthorised"
:is-dai-access-granted="isDaiAccessGranted"
:is-explanations-shown="isExplanationsShown"
:authorised-collaterals="authorisedCollaterals"
:wallet-address="walletAddress"
:wallet-dai="walletDai"
:wallet-vat-dai="walletVatDai"
:transaction-amount-dai="transactionAmountDai"
:minimum-bid-dai="minimumBidDai"
@inputBidAmount="$emit('inputBidAmount', $event)"
@connect="$emit('connect')"
@disconnect="$emit('disconnect')"
@grantDaiAccess="$emit('grantDaiAccess')"
@deposit="$emit('deposit', $event)"
@manageVat="$emit('manageVat')"
@authorizeWallet="$emit('authorizeWallet')"
@authorizeCollateral="$emit('authorizeCollateral', $event)"
@execute="$emit('execute', $event)"
@bidWithDai="$emit('bidWithDai', $event)"
/>
</template>
</SplitLayout>
Expand Down Expand Up @@ -128,11 +122,7 @@ export default Vue.extend({
type: Boolean,
default: false,
},
isGrantingAccess: {
type: Boolean,
default: false,
},
isDepositingDai: {
isDepositingOrWithdrawing: {
type: Boolean,
default: false,
},
Expand All @@ -148,10 +138,6 @@ export default Vue.extend({
type: Boolean,
default: false,
},
isDaiAccessGranted: {
type: Boolean,
default: false,
},
authorisedCollaterals: {
type: Array as Vue.PropType<string[]>,
default: () => [],
Expand All @@ -172,14 +158,6 @@ export default Vue.extend({
type: Boolean,
default: true,
},
transactionAmountDai: {
type: Object as Vue.PropType<BigNumber>,
default: undefined,
},
minimumBidDai: {
type: Object as Vue.PropType<BigNumber>,
default: null,
},
},
data: () => ({
step: 0,
Expand Down
12 changes: 6 additions & 6 deletions frontend/components/transaction/BidBlock.stories.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,28 +11,28 @@ const common = {
data() {
return {
auction: fakeAuction,
transactionAmountDAI: new BigNumber(faker.finance.amount()),
transactionBidAmount: new BigNumber(faker.finance.amount()),
};
},
};

storiesOf('Transaction/BidBlock', module)
.add('Default', () => ({
...common,
template: '<BidBlock :auctionTransaction="auction" :transactionAmountDAI="transactionAmountDAI" />',
template: '<BidBlock :auctionTransaction="auction" :transactionBidAmount="transactionBidAmount" />',
}))
.add('Disabled', () => ({
...common,
template: '<BidBlock :auctionTransaction="auction" :transactionAmountDAI="transactionAmountDAI" disabled />',
template: '<BidBlock :auctionTransaction="auction" :transactionBidAmount="transactionBidAmount" disabled />',
}))
.add('Loading', () => ({
...common,
template: '<BidBlock :auctionTransaction="auction" :transactionAmountDAI="transactionAmountDAI" is-loading />',
template: '<BidBlock :auctionTransaction="auction" :transactionBidAmount="transactionBidAmount" is-loading />',
}))
.add('Expert Mode', () => ({
...common,
template:
'<BidBlock :auctionTransaction="auction" :transactionAmountDAI="transactionAmountDAI" :is-explanations-shown="false" />',
'<BidBlock :auctionTransaction="auction" :transactionBidAmount="transactionBidAmount" :is-explanations-shown="false" />',
}))
.add('Finished', () => ({
...common,
Expand All @@ -44,5 +44,5 @@ storiesOf('Transaction/BidBlock', module)
};
},
},
template: '<BidBlock :auctionTransaction="finishedAuction" :transactionAmountDAI="transactionAmountDAI" />',
template: '<BidBlock :auctionTransaction="finishedAuction" :transactionBidAmount="transactionBidAmount" />',
}));
6 changes: 3 additions & 3 deletions frontend/components/transaction/BidBlock.vue
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@
class="w-full md:w-80"
:disabled="state === 'disabled' || state === 'executed'"
type="primary"
@click="$emit('execute')"
@click="$emit('bidWithDai')"
>
<span>
Bid <format-currency :value="transactionAmountDai" currency="DAI" /> for
Bid <format-currency :value="transactionBidAmount" currency="DAI" /> for
<format-currency
:value="amountToReceive || auctionTransaction.collateralAmount"
:currency="auctionTransaction.collateralSymbol"
Expand Down Expand Up @@ -56,7 +56,7 @@ export default Vue.extend({
type: Object as Vue.PropType<AuctionTransaction>,
default: null,
},
transactionAmountDai: {
transactionBidAmount: {
type: Object as Vue.PropType<BigNumber>,
default: undefined,
},
Expand Down
48 changes: 10 additions & 38 deletions frontend/components/transaction/BidTransaction.stories.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,16 @@ const data = {
isFinished: false,
},
isConnecting: false,
isGrantingAccess: false,
isDepositing: false,
isDepositingOrWithdrawing: false,
isAuthorizing: false,
isExecuting: false,
isWalletAuthorised: false,
isDaiAccessGranted: false,
isDeposited: false,
authorisedCollaterals: [],
walletAddress: null,
walletDai: new BigNumber(faker.finance.amount()),
walletVatDai: new BigNumber(faker.finance.amount()),
transactionAddress: null,
transactionAmountDai: fakeAuctionTransaction.totalPrice,
minimumBidDai: new BigNumber(faker.finance.amount(0, 100)),
};

const common = {
Expand All @@ -53,21 +49,6 @@ const common = {
this.isConnecting = false;
}, 1000);
},
grantDaiAccess() {
this.isGrantingAccess = true;
setTimeout(() => {
this.isDaiAccessGranted = true;
this.isGrantingAccess = false;
}, 1000);
},
deposit(amount) {
this.isDepositing = true;
setTimeout(() => {
this.walletDai = this.walletDai?.minus(new BigNumber(amount));
this.walletVatDai = this.walletVatDai.plus(new BigNumber(amount));
this.isDepositing = false;
}, 1000);
},
authorizeWallet() {
this.isAuthorizing = true;
setTimeout(() => {
Expand All @@ -93,41 +74,32 @@ const common = {
this.isExecuting = false;
}, 1000);
},
setTransactionAmountDAI(amount) {
this.transactionAmountDai = amount;
},
},
watch: {
transactionAmountDai(newAmount) {
if (newAmount === undefined) {
this.transactionAmountDai = this.auctionTransaction.totalPrice;
}
deposit() {
this.isDepositingOrWithdrawing = true;
setTimeout(() => {
this.walletVatDai = this.transactionAmountDai;
this.isDepositingOrWithdrawing = false;
}, 1000);
},
},
template: `
<BidTransaction
:auctionTransaction="auctionTransaction"
:isConnecting="isConnecting"
:isGrantingAccess="isGrantingAccess"
:isDepositing="isDepositing"
:isDepositingOrWithdrawing="isDepositingOrWithdrawing"
:isAuthorizing="isAuthorizing"
:isExecuting="isExecuting"
:isWalletAuthorised="isWalletAuthorised"
:isDaiAccessGranted="isDaiAccessGranted"
:authorisedCollaterals="authorisedCollaterals"
:walletAddress="walletAddress"
:walletDai="walletDai"
:walletVatDai="walletVatDai"
:transactionAmountDai="transactionAmountDai"
:minimumBidDai="minimumBidDai"
@inputBidAmount="setTransactionAmountDAI($event)"
@connect="connect()"
@disconnect="disconnect()"
@grantDaiAccess="grantDaiAccess()"
@deposit="deposit($event)"
@authorizeWallet="authorizeWallet()"
@authorizeCollateral="authorizeCollateral($event)"
@execute="execute()"
@bidWithDai="execute()"
@manageVat="deposit()"
/>`,
};

Expand Down
Loading

0 comments on commit 8604b16

Please sign in to comment.