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);
 | |
|   }
 | |
| }
 | 
