mirror of
https://github.com/Instadapp/assembly.git
synced 2024-07-29 22:37:06 +00:00
MakerDAO Collateral
This commit is contained in:
parent
e79ad82e84
commit
5410695e47
46
components/common/input/Dropdown.vue
Normal file
46
components/common/input/Dropdown.vue
Normal file
|
|
@ -0,0 +1,46 @@
|
||||||
|
<template>
|
||||||
|
<div ref="menu" class="relative inline-block text-left">
|
||||||
|
<slot name="trigger" :toggle="toggle" :is-shown="isShown" />
|
||||||
|
<transition
|
||||||
|
enter-active-class="transition duration-100 ease-out"
|
||||||
|
enter-class="transform scale-95 opacity-0"
|
||||||
|
enter-to-class="transform scale-100 opacity-100"
|
||||||
|
leave-active-class="transition duration-75 ease-in"
|
||||||
|
leave-class="transform scale-100 opacity-100"
|
||||||
|
leave-to-class="transform scale-95 opacity-0"
|
||||||
|
>
|
||||||
|
<slot v-if="isShown" name="menu" :close="close" />
|
||||||
|
</transition>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { defineComponent, onBeforeUnmount, onMounted, ref } from '@nuxtjs/composition-api'
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
setup() {
|
||||||
|
const menu = ref(null)
|
||||||
|
const isShown = ref(false)
|
||||||
|
|
||||||
|
function toggle() {
|
||||||
|
isShown.value = !isShown.value
|
||||||
|
}
|
||||||
|
|
||||||
|
function close() {
|
||||||
|
isShown.value = false
|
||||||
|
}
|
||||||
|
|
||||||
|
function closeOnOutsideClick(event) {
|
||||||
|
if (!isShown.value) return
|
||||||
|
if (menu.value.contains(event.target)) return
|
||||||
|
|
||||||
|
close()
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => window.addEventListener('click', closeOnOutsideClick))
|
||||||
|
onBeforeUnmount(() => window.removeEventListener('click', closeOnOutsideClick))
|
||||||
|
|
||||||
|
return { toggle, isShown, menu, close }
|
||||||
|
},
|
||||||
|
})
|
||||||
|
</script>
|
||||||
96
components/protocols/DropdownMakerdao.vue
Normal file
96
components/protocols/DropdownMakerdao.vue
Normal file
|
|
@ -0,0 +1,96 @@
|
||||||
|
<template>
|
||||||
|
<dropdown>
|
||||||
|
<template #trigger="{ toggle, isShown }">
|
||||||
|
<Button
|
||||||
|
:class="{
|
||||||
|
'bg-grey-light': isShown
|
||||||
|
}"
|
||||||
|
:large="true"
|
||||||
|
color="grey"
|
||||||
|
class="w-20 px-3 xxl:w-23"
|
||||||
|
aria-label="Makerdao Dropdown"
|
||||||
|
aria-haspopup="true"
|
||||||
|
@click="toggle()"
|
||||||
|
>
|
||||||
|
<span class="mr-2">#{{ vaultId }}</span>
|
||||||
|
|
||||||
|
<SVGChevronUp
|
||||||
|
class="ml-auto"
|
||||||
|
:class="{ 'transform rotate-180': !isShown }"
|
||||||
|
/>
|
||||||
|
</Button>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template #menu="{ close }">
|
||||||
|
<dropdown-menu style="width: 240px; max-height: 440px">
|
||||||
|
<div class="flex flex-col overflow-x-hidden overflow-y-auto scrollbar-hover scrollbar">
|
||||||
|
<button
|
||||||
|
v-for="vault in vaults"
|
||||||
|
:key="vault.id"
|
||||||
|
class="flex items-center w-full px-4 py-2 hover:bg-opacity-50 focus:bg-opacity-50 hover:bg-grey-light dark:hover:bg-dark-300 dark:focus:bg-dark-300 focus:outline-none focus:bg-grey-light"
|
||||||
|
@click="setVault(vault.id, close)"
|
||||||
|
>
|
||||||
|
<div class="mr-2 font-semibold whitespace-no-wrap">
|
||||||
|
#{{ vault.id }}
|
||||||
|
</div>
|
||||||
|
<IconCurrency
|
||||||
|
:currency="vault.tokenKey"
|
||||||
|
class="w-6 h-6 ml-auto"
|
||||||
|
no-height
|
||||||
|
/>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<hr v-if="!!vaults.length" class="w-full my-2" />
|
||||||
|
|
||||||
|
<button
|
||||||
|
class="flex items-center w-full px-4 py-2 font-medium hover:bg-opacity-75 focus:bg-opacity-75 text-ocean-blue-pure hover:bg-ocean-blue-light focus:bg-ocean-blue-light focus:outline-none dark:hover:bg-opacity-17 dark:focus:bg-opacity-17"
|
||||||
|
@click="openNewVault(close)"
|
||||||
|
>
|
||||||
|
New Vault
|
||||||
|
</button>
|
||||||
|
</dropdown-menu>
|
||||||
|
</template>
|
||||||
|
</dropdown>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { defineComponent, useRouter } from '@nuxtjs/composition-api'
|
||||||
|
import SVGChevronUp from '@/assets/img/icons/chevron-up.svg?inline'
|
||||||
|
import { useMakerdaoPosition } from '~/composables/useMakerdaoPosition'
|
||||||
|
import { useSidebar } from '~/composables/useSidebar'
|
||||||
|
import Dropdown from '../common/input/Dropdown.vue'
|
||||||
|
import DropdownMenu from './DropdownMenu.vue'
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
components: {
|
||||||
|
SVGChevronUp,
|
||||||
|
Dropdown,
|
||||||
|
DropdownMenu,
|
||||||
|
},
|
||||||
|
|
||||||
|
setup() {
|
||||||
|
const router = useRouter()
|
||||||
|
const { vaultId, vaults, selectVault, isNewVault } = useMakerdaoPosition()
|
||||||
|
const { back } = useSidebar()
|
||||||
|
|
||||||
|
function openNewVault(cb) {
|
||||||
|
router.push({ hash: 'collateral' })
|
||||||
|
|
||||||
|
cb();
|
||||||
|
}
|
||||||
|
|
||||||
|
function setVault(vaultId, cb) {
|
||||||
|
selectVault(vaultId)
|
||||||
|
|
||||||
|
if (isNewVault.value) {
|
||||||
|
back()
|
||||||
|
}
|
||||||
|
|
||||||
|
cb()
|
||||||
|
}
|
||||||
|
|
||||||
|
return { vaultId, vaults, openNewVault, setVault }
|
||||||
|
},
|
||||||
|
})
|
||||||
|
</script>
|
||||||
21
components/protocols/DropdownMenu.vue
Normal file
21
components/protocols/DropdownMenu.vue
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
<template>
|
||||||
|
<div
|
||||||
|
class="rounded-lg flex-shrink-0 bg-white absolute z-10 flex flex-col py-2 mt-1 overflow-hidden border border-opacity-25 select-none shadow-notification dark:bg-dark-400 dark:border-opacity-20 border-ocean-blue-pure"
|
||||||
|
:class="{
|
||||||
|
'right-0 origin-top-right': align === 'right',
|
||||||
|
'left-0 origin-top-left': align === 'left',
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<slot />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { defineComponent } from '@nuxtjs/composition-api'
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
props: {
|
||||||
|
align: { type: String, default: 'right' },
|
||||||
|
},
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
@ -0,0 +1,83 @@
|
||||||
|
<template>
|
||||||
|
<SidebarContextRootContainer>
|
||||||
|
<template #title>Select Collateral</template>
|
||||||
|
<div>
|
||||||
|
<div class="px-8 pb-6 -mt-4">
|
||||||
|
<SearchInput
|
||||||
|
v-model.trim="search"
|
||||||
|
class="mt-1"
|
||||||
|
placeholder="Search Collateral"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="bg-[#C5CCE1] bg-opacity-[0.15] px-8 py-6 min-h-screen">
|
||||||
|
<div
|
||||||
|
v-for="(vaultType, index) in filteredVaults"
|
||||||
|
:key="index"
|
||||||
|
class="flex items-center justify-between px-4 py-4 mt-4 cursor-pointer first:mt-0 group bg-white rounded-lg border border-grey-dark/[0.15] hover:bg-selection"
|
||||||
|
@click="select(vaultType.type)"
|
||||||
|
>
|
||||||
|
<div class="flex flex-col mr-4">
|
||||||
|
<div class="mb-1 font-semibold whitespace-no-wrap text-12">
|
||||||
|
{{ vaultType.type }}
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="mb-1 font-medium whitespace-no-wrap text-12 text-grey-pure"
|
||||||
|
>
|
||||||
|
Stability Fee: {{ formatPercent(vaultType.rate) }}
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="mb-1 font-medium whitespace-no-wrap text-12 text-grey-pure"
|
||||||
|
>
|
||||||
|
Liquidation: {{ formatPercent(vaultType.liquidation) }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<IconCurrency :currency="vaultType.tokenKey" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</SidebarContextRootContainer>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { defineComponent, useContext, computed } from '@nuxtjs/composition-api'
|
||||||
|
import { useFormatting } from '~/composables/useFormatting'
|
||||||
|
import { useMakerdaoPosition } from '~/composables/useMakerdaoPosition'
|
||||||
|
import { useSearchFilter } from '~/composables/useSearchFilter'
|
||||||
|
import { useSidebar } from '~/composables/useSidebar'
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
props: {
|
||||||
|
vaultType: { type: String, default: null },
|
||||||
|
},
|
||||||
|
setup(props) {
|
||||||
|
const { store, app, route } = useContext()
|
||||||
|
const { formatPercent } = useFormatting()
|
||||||
|
const { back } = useSidebar()
|
||||||
|
const { vaultTypes: makerVaultTypes, vaultType, isNewVault } = useMakerdaoPosition()
|
||||||
|
|
||||||
|
const vaultTypes = computed(() => {
|
||||||
|
const shouldFilter = !!props.vaultType && (props.vaultType === 'token' || props.vaultType === 'uniLPT')
|
||||||
|
const filtered = makerVaultTypes.value.filter((vault) => !vault.disabled)
|
||||||
|
const final = shouldFilter ? filtered.filter((vault) => vault.vaultTokenType === props.vaultType) : filtered
|
||||||
|
if (route.value.hash.startsWith('#collateral')) return final
|
||||||
|
return filtered.filter((vault) => vault.vaultTokenType === 'token')
|
||||||
|
})
|
||||||
|
|
||||||
|
const { filtered: filteredVaults, search } = useSearchFilter(vaultTypes, 'type', 'token')
|
||||||
|
|
||||||
|
function select(vt, tokenKey) {
|
||||||
|
vaultType.value = vt;
|
||||||
|
isNewVault.value = true
|
||||||
|
app.router.push({ hash: 'supply' })
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
filteredVaults,
|
||||||
|
search,
|
||||||
|
formatPercent,
|
||||||
|
select,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
@ -25,7 +25,7 @@ const defaultVault = {
|
||||||
netvalue: "0"
|
netvalue: "0"
|
||||||
};
|
};
|
||||||
|
|
||||||
const vaultId = ref("0");
|
const vaultId = ref(null);
|
||||||
const vaults = ref([]);
|
const vaults = ref([]);
|
||||||
const isNewVault = ref(false);
|
const isNewVault = ref(false);
|
||||||
const vaultTypes = ref([]);
|
const vaultTypes = ref([]);
|
||||||
|
|
@ -50,7 +50,10 @@ const vault = computed(() => {
|
||||||
return defaultVault;
|
return defaultVault;
|
||||||
});
|
});
|
||||||
|
|
||||||
export function useMakerdaoPosition(collateralAmountRef: Ref =null, debtAmountRef: Ref = null) {
|
export function useMakerdaoPosition(
|
||||||
|
collateralAmountRef: Ref = null,
|
||||||
|
debtAmountRef: Ref = null
|
||||||
|
) {
|
||||||
const { web3, chainId, networkName } = useWeb3();
|
const { web3, chainId, networkName } = useWeb3();
|
||||||
const { activeAccount } = useDSA();
|
const { activeAccount } = useDSA();
|
||||||
const { isZero, ensureValue, times, div, max, gt } = useBigNumber();
|
const { isZero, ensureValue, times, div, max, gt } = useBigNumber();
|
||||||
|
|
@ -78,19 +81,32 @@ export function useMakerdaoPosition(collateralAmountRef: Ref =null, debtAmountRe
|
||||||
const netValue = computed(() => ensureValue(vault.value.netValue).toFixed());
|
const netValue = computed(() => ensureValue(vault.value.netValue).toFixed());
|
||||||
|
|
||||||
const status = computed(() => {
|
const status = computed(() => {
|
||||||
if (!collateralAmountRef || !debtAmountRef) return ensureValue(vault.value.status).toFixed()
|
if (!collateralAmountRef || !debtAmountRef)
|
||||||
|
return ensureValue(vault.value.status).toFixed();
|
||||||
return isZero(collateralAmountRef.value) && !isZero(debtAmountRef.value)
|
return isZero(collateralAmountRef.value) && !isZero(debtAmountRef.value)
|
||||||
? '1.1'
|
? "1.1"
|
||||||
: div(debtAmountRef.value, times(collateralAmountRef.value, price.value)).toFixed()
|
: div(
|
||||||
})
|
debtAmountRef.value,
|
||||||
|
times(collateralAmountRef.value, price.value)
|
||||||
|
).toFixed();
|
||||||
|
});
|
||||||
|
|
||||||
const liquidationPrice = computed(() => {
|
const liquidationPrice = computed(() => {
|
||||||
if (!collateralAmountRef || !debtAmountRef)
|
if (!collateralAmountRef || !debtAmountRef)
|
||||||
return max(div(div(debt.value, collateral.value), liquidation.value), '0').toFixed()
|
return max(
|
||||||
|
div(div(debt.value, collateral.value), liquidation.value),
|
||||||
|
"0"
|
||||||
|
).toFixed();
|
||||||
return isZero(collateralAmountRef.value) && !isZero(debtAmountRef.value)
|
return isZero(collateralAmountRef.value) && !isZero(debtAmountRef.value)
|
||||||
? times(price.value, '1.1').toFixed()
|
? times(price.value, "1.1").toFixed()
|
||||||
: max(div(div(debtAmountRef.value, collateralAmountRef.value), liquidation.value), '0').toFixed()
|
: max(
|
||||||
})
|
div(
|
||||||
|
div(debtAmountRef.value, collateralAmountRef.value),
|
||||||
|
liquidation.value
|
||||||
|
),
|
||||||
|
"0"
|
||||||
|
).toFixed();
|
||||||
|
});
|
||||||
|
|
||||||
const debt = computed(() => ensureValue(vault.value.debt).toFixed());
|
const debt = computed(() => ensureValue(vault.value.debt).toFixed());
|
||||||
const minDebt = computed(() => vaultTypes.value[0]?.totalFloor || "5000");
|
const minDebt = computed(() => vaultTypes.value[0]?.totalFloor || "5000");
|
||||||
|
|
@ -136,9 +152,16 @@ export function useMakerdaoPosition(collateralAmountRef: Ref =null, debtAmountRe
|
||||||
{ immediate: true }
|
{ immediate: true }
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const selectVault = vid => {
|
||||||
|
if (vid === vaultId.value && !isNewVault.value) return;
|
||||||
|
vaultId.value = vid;
|
||||||
|
isNewVault.value = false;
|
||||||
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
fetchPosition,
|
fetchPosition,
|
||||||
vaultId,
|
vaultId: computed(() => (isNewVault.value ? "0" : vaultId.value || "0")),
|
||||||
|
selectVault,
|
||||||
vaultTokenType,
|
vaultTokenType,
|
||||||
vault,
|
vault,
|
||||||
vaults,
|
vaults,
|
||||||
|
|
@ -245,7 +268,7 @@ async function getVaults(user, web3) {
|
||||||
ratePerBlock,
|
ratePerBlock,
|
||||||
priceInWei,
|
priceInWei,
|
||||||
liquidationRatioCbyD,
|
liquidationRatioCbyD,
|
||||||
urn,
|
urn
|
||||||
]) => {
|
]) => {
|
||||||
const collateral = new BigNumber(collInWei).dividedBy(1e18);
|
const collateral = new BigNumber(collInWei).dividedBy(1e18);
|
||||||
const debt = new BigNumber(debtInWei).dividedBy(1e18);
|
const debt = new BigNumber(debtInWei).dividedBy(1e18);
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@ import SidebarCompoundSupply from '~/components/sidebar/context/compound/Sidebar
|
||||||
import SidebarCompoundBorrow from '~/components/sidebar/context/compound/SidebarCompoundBorrow.vue'
|
import SidebarCompoundBorrow from '~/components/sidebar/context/compound/SidebarCompoundBorrow.vue'
|
||||||
import SidebarCompoundPayback from '~/components/sidebar/context/compound/SidebarCompoundPayback.vue'
|
import SidebarCompoundPayback from '~/components/sidebar/context/compound/SidebarCompoundPayback.vue'
|
||||||
|
|
||||||
|
import SidebarMakerdaoCollateral from '~/components/sidebar/context/makerdao/SidebarMakerdaoCollateral.vue'
|
||||||
import SidebarMakerdaoSupply from '~/components/sidebar/context/makerdao/SidebarMakerdaoSupply.vue'
|
import SidebarMakerdaoSupply from '~/components/sidebar/context/makerdao/SidebarMakerdaoSupply.vue'
|
||||||
import SidebarMakerdaoWithdraw from '~/components/sidebar/context/makerdao/SidebarMakerdaoWithdraw.vue'
|
import SidebarMakerdaoWithdraw from '~/components/sidebar/context/makerdao/SidebarMakerdaoWithdraw.vue'
|
||||||
import SidebarMakerdaoBorrow from '~/components/sidebar/context/makerdao/SidebarMakerdaoBorrow.vue'
|
import SidebarMakerdaoBorrow from '~/components/sidebar/context/makerdao/SidebarMakerdaoBorrow.vue'
|
||||||
|
|
@ -53,6 +54,7 @@ const sidebars = {
|
||||||
"/mainnet/compound#payback": { component: SidebarCompoundPayback },
|
"/mainnet/compound#payback": { component: SidebarCompoundPayback },
|
||||||
|
|
||||||
"/mainnet/maker": { component: null },
|
"/mainnet/maker": { component: null },
|
||||||
|
'/mainnet/maker#collateral': { component: SidebarMakerdaoCollateral },
|
||||||
"/mainnet/maker#supply": { component: SidebarMakerdaoSupply },
|
"/mainnet/maker#supply": { component: SidebarMakerdaoSupply },
|
||||||
"/mainnet/maker#withdraw": { component: SidebarMakerdaoWithdraw },
|
"/mainnet/maker#withdraw": { component: SidebarMakerdaoWithdraw },
|
||||||
"/mainnet/maker#borrow": { component: SidebarMakerdaoBorrow },
|
"/mainnet/maker#borrow": { component: SidebarMakerdaoBorrow },
|
||||||
|
|
|
||||||
|
|
@ -115,10 +115,9 @@ export default defineComponent({
|
||||||
}
|
}
|
||||||
}, { immediate: true })
|
}, { immediate: true })
|
||||||
|
|
||||||
// onErrorCaptured(() => {
|
onErrorCaptured(() => {
|
||||||
|
return false
|
||||||
// return false
|
})
|
||||||
// })
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
active,
|
active,
|
||||||
|
|
|
||||||
|
|
@ -10,8 +10,10 @@
|
||||||
</nuxt-link>
|
</nuxt-link>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mt-10">
|
<div class="mt-10 flex items-center">
|
||||||
<h1 class="text-primary-black text-2xl font-semibold">MakerDAO</h1>
|
<h1 class="text-primary-black text-2xl font-semibold">MakerDAO</h1>
|
||||||
|
|
||||||
|
<dropdown-makerdao class="ml-auto"/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mt-10">
|
<div class="mt-10">
|
||||||
|
|
@ -148,6 +150,7 @@ import { useFormatting } from "~/composables/useFormatting";
|
||||||
import { useMakerdaoPosition } from "~/composables/useMakerdaoPosition";
|
import { useMakerdaoPosition } from "~/composables/useMakerdaoPosition";
|
||||||
import { useStatus } from "~/composables/useStatus";
|
import { useStatus } from "~/composables/useStatus";
|
||||||
import { useNotification } from "~/composables/useNotification";
|
import { useNotification } from "~/composables/useNotification";
|
||||||
|
import DropdownMakerdao from "~/components/protocols/DropdownMakerdao.vue";
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
components: {
|
components: {
|
||||||
|
|
@ -157,7 +160,8 @@ export default defineComponent({
|
||||||
SVGBalance,
|
SVGBalance,
|
||||||
SVGEarnings,
|
SVGEarnings,
|
||||||
SVGArrowRight,
|
SVGArrowRight,
|
||||||
SVGPercent
|
SVGPercent,
|
||||||
|
DropdownMakerdao
|
||||||
},
|
},
|
||||||
setup() {
|
setup() {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
|
||||||
|
|
@ -1,3 +0,0 @@
|
||||||
<template>
|
|
||||||
<SidebarMakerdaoWithdraw />
|
|
||||||
</template>
|
|
||||||
Loading…
Reference in New Issue
Block a user