mirror of
https://github.com/Instadapp/assembly.git
synced 2024-07-29 22:37:06 +00:00
328 lines
8.4 KiB
TypeScript
328 lines
8.4 KiB
TypeScript
import { computed, Ref, ref, watch } from "@nuxtjs/composition-api";
|
|
import BigNumber from "bignumber.js";
|
|
BigNumber.config({ POW_PRECISION: 200 });
|
|
import abis from "~/constant/abis";
|
|
import addresses from "~/constant/addresses";
|
|
import makerVaults from "~/constant/tokens/vaults";
|
|
import { useBigNumber } from "~/composables/useBigNumber";
|
|
import { useDSA } from "~/composables/useDSA";
|
|
import { useToken } from "~/composables/useToken";
|
|
import { useWeb3 } from "@instadapp/vue-web3";
|
|
import { AbiItem } from "web3-utils";
|
|
import useEventBus from "../useEventBus";
|
|
|
|
const defaultVault = {
|
|
id: null,
|
|
tokenKey: "eth",
|
|
token: "ETH",
|
|
collateralName: "ETH-A",
|
|
collateral: "0",
|
|
debt: "0",
|
|
liquidatedCollateral: "0",
|
|
status: "0",
|
|
rate: "0",
|
|
liquidation: "0",
|
|
price: "0",
|
|
netvalue: "0"
|
|
};
|
|
|
|
const vaultId = ref(null);
|
|
const vaults = ref([]);
|
|
const isNewVault = ref(false);
|
|
const vaultTypes = ref([]);
|
|
const vaultType = ref("");
|
|
|
|
export const vault = computed(() => {
|
|
const vlt = vaults.value.find(v => v.id === vaultId.value);
|
|
if (!isNewVault.value && !!vlt) {
|
|
return vlt;
|
|
}
|
|
|
|
const vt = vaultTypes.value.find(vt => vt.type === vaultType.value);
|
|
if (vt) {
|
|
return { ...defaultVault, ...vt };
|
|
}
|
|
|
|
const defaultVaultType = vaultTypes.value[0];
|
|
if (defaultVaultType) {
|
|
return { ...defaultVault, ...defaultVaultType };
|
|
}
|
|
|
|
return defaultVault;
|
|
});
|
|
|
|
export function useMakerdaoPosition(
|
|
collateralAmountRef: Ref = null,
|
|
debtAmountRef: Ref = null
|
|
) {
|
|
const { library } = useWeb3();
|
|
const { onEvent } = useEventBus()
|
|
const { activeAccount } = useDSA();
|
|
const { isZero, ensureValue, times, div, max, gt } = useBigNumber();
|
|
const { getTokenByKey } = useToken();
|
|
|
|
const vaultTokenType = computed(() => vault.value.vaultTokenType);
|
|
|
|
const price = computed(() => ensureValue(vault.value.price).toFixed());
|
|
|
|
const collateralUsd = computed(() =>
|
|
times(collateral.value, price.value).toFixed()
|
|
);
|
|
const collateral = computed(() =>
|
|
ensureValue(vault.value.collateral).toFixed()
|
|
);
|
|
|
|
const liquidation = computed(() =>
|
|
ensureValue(vault.value.liquidation).toFixed()
|
|
);
|
|
const tokenKey = computed(() => vault.value.tokenKey);
|
|
|
|
const token = computed(() => getTokenByKey(tokenKey.value));
|
|
const symbol = computed(() => token.value.symbol ?? "ETH");
|
|
const rate = computed(() => ensureValue(vault.value.rate).toFixed());
|
|
const netValue = computed(() => ensureValue(vault.value.netValue).toFixed());
|
|
|
|
const status = computed(() => {
|
|
if (!collateralAmountRef || !debtAmountRef)
|
|
return ensureValue(vault.value.status).toFixed();
|
|
return isZero(collateralAmountRef.value) && !isZero(debtAmountRef.value)
|
|
? "1.1"
|
|
: div(
|
|
debtAmountRef.value,
|
|
times(collateralAmountRef.value, price.value)
|
|
).toFixed();
|
|
});
|
|
|
|
const liquidationPrice = computed(() => {
|
|
if (!collateralAmountRef || !debtAmountRef)
|
|
return max(
|
|
div(div(debt.value, collateral.value), liquidation.value),
|
|
"0"
|
|
).toFixed();
|
|
return isZero(collateralAmountRef.value) && !isZero(debtAmountRef.value)
|
|
? times(price.value, "1.1").toFixed()
|
|
: max(
|
|
div(
|
|
div(debtAmountRef.value, collateralAmountRef.value),
|
|
liquidation.value
|
|
),
|
|
"0"
|
|
).toFixed();
|
|
});
|
|
|
|
const debt = computed(() => ensureValue(vault.value.debt).toFixed());
|
|
const minDebt = computed(() => vaultTypes.value[0]?.totalFloor.toString() || "5000");
|
|
const debtCeilingReached = computed(() =>
|
|
vaultTypes.value?.some(v =>
|
|
gt(v.overallTotalDebt, v.overallTotalDebtCeiling)
|
|
)
|
|
);
|
|
|
|
const fetchPosition = async () => {
|
|
if (!library.value) {
|
|
return;
|
|
}
|
|
|
|
vaultTypes.value = await getVaultTypes(library.value);
|
|
|
|
if (!activeAccount.value) {
|
|
return;
|
|
}
|
|
vaults.value = await getVaults(activeAccount.value.address, library.value);
|
|
if (vaults.value.length > 0 && !vaultId.value) {
|
|
vaultId.value = vaults.value[0].id;
|
|
}
|
|
};
|
|
|
|
onEvent("protocol::makerdao::refresh", fetchPosition);
|
|
|
|
watch(
|
|
library,
|
|
async val => {
|
|
if (val) {
|
|
fetchPosition();
|
|
}
|
|
},
|
|
{ immediate: true }
|
|
);
|
|
|
|
watch(
|
|
activeAccount,
|
|
async val => {
|
|
if (val) {
|
|
fetchPosition();
|
|
}
|
|
},
|
|
{ immediate: true }
|
|
);
|
|
|
|
const selectVault = vid => {
|
|
if (vid === vaultId.value && !isNewVault.value) return;
|
|
vaultId.value = vid;
|
|
isNewVault.value = false;
|
|
};
|
|
|
|
return {
|
|
fetchPosition,
|
|
vaultId: computed(() => (isNewVault.value ? "0" : vaultId.value || "0")),
|
|
selectVault,
|
|
vaultTokenType,
|
|
vault,
|
|
vaults,
|
|
vaultType,
|
|
vaultTypes,
|
|
isNewVault,
|
|
collateralUsd,
|
|
collateral,
|
|
price,
|
|
liquidation,
|
|
tokenKey,
|
|
token,
|
|
symbol,
|
|
rate,
|
|
netValue,
|
|
status,
|
|
liquidationPrice,
|
|
liquidationMaxPrice: price,
|
|
debt,
|
|
minDebt,
|
|
debtCeilingReached
|
|
};
|
|
}
|
|
|
|
async function getVaultTypes(web3) {
|
|
const makerResolveABI = abis.resolver.maker;
|
|
const makerResolveAddr = addresses.mainnet.resolver.maker;
|
|
|
|
const makerResolverInstance = new web3.eth.Contract(
|
|
makerResolveABI as AbiItem[],
|
|
makerResolveAddr
|
|
);
|
|
|
|
try {
|
|
const rawData: any[] = await makerResolverInstance.methods
|
|
.getColInfo(makerVaults.types)
|
|
.call();
|
|
|
|
return makerVaults.allVaults.map(
|
|
({ type, token, key: tokenKey, disabled, vaultTokenType }, i) => {
|
|
const [
|
|
rate,
|
|
price,
|
|
ratioCbyD,
|
|
debtCeiling,
|
|
totalFloor,
|
|
totalDebt,
|
|
overallTotalDebtCeiling,
|
|
overallTotalDebt
|
|
] = rawData[i];
|
|
|
|
return {
|
|
type,
|
|
token,
|
|
tokenKey,
|
|
disabled,
|
|
vaultTokenType,
|
|
rate: calRate(rate),
|
|
price: new BigNumber(price).dividedBy(1e27).toFixed(),
|
|
liquidation: new BigNumber(1)
|
|
.dividedBy(new BigNumber(ratioCbyD).dividedBy(1e27))
|
|
.toFixed(),
|
|
debtCeiling: debtCeiling,
|
|
totalDebt: new BigNumber(totalFloor)
|
|
.dividedBy(1e18)
|
|
.multipliedBy(1.00002)
|
|
.toFixed(),
|
|
totalFloor: new BigNumber(totalDebt).dividedBy(1e45),
|
|
overallTotalDebtCeiling: new BigNumber(
|
|
overallTotalDebtCeiling
|
|
).dividedBy(1e45),
|
|
overallTotalDebt: new BigNumber(overallTotalDebt).dividedBy(1e45)
|
|
};
|
|
}
|
|
);
|
|
} catch (error) {
|
|
console.error(error);
|
|
return [];
|
|
}
|
|
}
|
|
async function getVaults(user, web3) {
|
|
try {
|
|
const makerResolveABI = abis.resolver.maker;
|
|
const makerResolveAddr = addresses.mainnet.resolver.maker;
|
|
|
|
const makerResolverInstance = new web3.eth.Contract(
|
|
makerResolveABI as AbiItem[],
|
|
makerResolveAddr
|
|
);
|
|
|
|
const rawData: any[] = await makerResolverInstance.methods
|
|
.getVaults(user)
|
|
.call();
|
|
|
|
return rawData.map(
|
|
([
|
|
id,
|
|
owner,
|
|
type,
|
|
collInWei,
|
|
,
|
|
debtInWei,
|
|
liquidatedColInWei,
|
|
ratePerBlock,
|
|
priceInWei,
|
|
liquidationRatioCbyD,
|
|
urn
|
|
]) => {
|
|
const collateral = new BigNumber(collInWei).dividedBy(1e18);
|
|
const debt = new BigNumber(debtInWei).dividedBy(1e18);
|
|
const price = new BigNumber(priceInWei).dividedBy(1e27);
|
|
|
|
const vault = makerVaults.getVaultByType(type);
|
|
|
|
return {
|
|
id,
|
|
owner,
|
|
type,
|
|
tokenKey: vault.key,
|
|
token: vault.token,
|
|
vaultTokenType: vault.vaultTokenType,
|
|
collateral: collateral.toFixed(),
|
|
debt: debt.toFixed(),
|
|
liquidatedCollateral: new BigNumber(liquidatedColInWei)
|
|
.dividedBy(1e18)
|
|
.toFixed(),
|
|
rate: calRate(ratePerBlock),
|
|
price: price.toFixed(),
|
|
liquidation: new BigNumber(1)
|
|
.dividedBy(new BigNumber(liquidationRatioCbyD).dividedBy(1e27))
|
|
.toFixed(),
|
|
urn,
|
|
netValue: collateral
|
|
.multipliedBy(price)
|
|
.minus(debt)
|
|
.toFixed(),
|
|
status: collateral.isZero()
|
|
? "0"
|
|
: debt.dividedBy(collateral.multipliedBy(price)).toFixed()
|
|
};
|
|
}
|
|
);
|
|
} catch (error) {
|
|
console.error(error);
|
|
return [];
|
|
}
|
|
}
|
|
|
|
function calRate(ilkRate) {
|
|
try {
|
|
return new BigNumber(ilkRate)
|
|
.dividedBy(1e27)
|
|
.pow(31545000)
|
|
.minus(1)
|
|
.toFixed(18);
|
|
} catch (error) {
|
|
console.log("error", error);
|
|
}
|
|
}
|