mirror of
https://github.com/Instadapp/assembly.git
synced 2024-07-29 22:37:06 +00:00
347 lines
9.0 KiB
TypeScript
347 lines
9.0 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 reflexerSafes from "~/constant/tokens/safes";
|
|
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 { useBalances } from "../useBalances";
|
|
|
|
const defaultSafe = {
|
|
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 oracleRelayerAddress = "0x4ed9C0dCa0479bC64d8f4EB3007126D5791f7851";
|
|
|
|
const safeId = ref(null);
|
|
const safes = ref([]);
|
|
const isNewSafe = ref(false);
|
|
const safeTypes = ref([]);
|
|
const safeType = ref("");
|
|
|
|
const safe = computed(() => {
|
|
const vlt = safes.value.find(v => v.id === safeId.value);
|
|
if (!isNewSafe.value && !!vlt) {
|
|
return vlt;
|
|
}
|
|
|
|
const vt = safeTypes.value.find(vt => vt.type === safeType.value);
|
|
if (vt) {
|
|
return { ...defaultSafe, ...vt };
|
|
}
|
|
|
|
const defaultSafeType = safeTypes.value[0];
|
|
if (defaultSafeType) {
|
|
return { ...defaultSafe, ...defaultSafeType };
|
|
}
|
|
|
|
return defaultSafe;
|
|
});
|
|
|
|
export function useReflexerPosition(
|
|
collateralAmountRef: Ref = null,
|
|
debtAmountRef: Ref = null
|
|
) {
|
|
const { library } = useWeb3();
|
|
const { activeAccount } = useDSA();
|
|
const { isZero, ensureValue, times, div, max, gt, toBN } = useBigNumber();
|
|
const { getTokenByKey } = useToken();
|
|
const { prices } = useBalances();
|
|
|
|
const raiToken = computed(() => getTokenByKey("rai"));
|
|
const raiInUsd = computed(() =>
|
|
raiToken.value ? prices.mainnet[raiToken.value.address] || "0" : "0"
|
|
);
|
|
|
|
const safeTokenType = computed(() => safe.value.safeTokenType);
|
|
|
|
const price = computed(() => ensureValue(safe.value.price).toFixed());
|
|
const spotPrice = computed(() => ensureValue(safe.value.spotPrice).toFixed());
|
|
|
|
const collateralUsd = computed(() =>
|
|
times(collateral.value, price.value).toFixed()
|
|
);
|
|
const collateral = computed(() =>
|
|
ensureValue(safe.value.collateral).toFixed()
|
|
);
|
|
|
|
const liquidation = computed(() =>
|
|
ensureValue(safe.value.liquidation).toFixed()
|
|
);
|
|
const tokenKey = computed(() => safe.value.tokenKey);
|
|
|
|
const token = computed(() => getTokenByKey(tokenKey.value));
|
|
const symbol = computed(() => token.value.symbol ?? "ETH");
|
|
const rate = computed(() => ensureValue(safe.value.rate).toFixed());
|
|
const netValue = computed(() => ensureValue(safe.value.netValue).toFixed());
|
|
|
|
const status = computed(() => {
|
|
if (!collateralAmountRef || !debtAmountRef)
|
|
return ensureValue(safe.value.status).toFixed();
|
|
return isZero(collateralAmountRef.value) && !isZero(debtAmountRef.value)
|
|
? "1.1"
|
|
: div(
|
|
debtAmountRef.value,
|
|
times(collateralAmountRef.value, spotPrice.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),
|
|
toBN(liquidation.value)
|
|
.multipliedBy(spotPrice.value)
|
|
.dividedBy(price.value)
|
|
),
|
|
"0"
|
|
).toFixed();
|
|
});
|
|
|
|
const debt = computed(() => ensureValue(safe.value.debt).toFixed());
|
|
const debtUsd = computed(() =>
|
|
times(debt.value, raiInUsd.value).toFixed()
|
|
);
|
|
|
|
const minDebt = computed(
|
|
() => safeTypes.value[0]?.totalDebt?.toString() || "699"
|
|
);
|
|
const debtCeilingReached = computed(() =>
|
|
safeTypes.value?.some(v =>
|
|
gt(v.overallTotalDebt, v.overallTotalDebtCeiling)
|
|
)
|
|
);
|
|
|
|
const fetchPosition = async () => {
|
|
if (!library.value) {
|
|
return;
|
|
}
|
|
|
|
safeTypes.value = await getSafeTypes(library.value);
|
|
|
|
if (!activeAccount.value) {
|
|
return;
|
|
}
|
|
safes.value = await getSafes(activeAccount.value.address, library.value);
|
|
if (safes.value.length > 0 && !safeId.value) {
|
|
safeId.value = safes.value[0].id;
|
|
}
|
|
};
|
|
|
|
watch(
|
|
library,
|
|
async val => {
|
|
if (val) {
|
|
fetchPosition();
|
|
}
|
|
},
|
|
{ immediate: true }
|
|
);
|
|
|
|
watch(
|
|
activeAccount,
|
|
async val => {
|
|
if (val) {
|
|
fetchPosition();
|
|
}
|
|
},
|
|
{ immediate: true }
|
|
);
|
|
|
|
const selectSafe = vid => {
|
|
if (vid === safeId.value && !isNewSafe.value) return;
|
|
safeId.value = vid;
|
|
isNewSafe.value = false;
|
|
};
|
|
|
|
return {
|
|
fetchPosition,
|
|
safeId: computed(() => (isNewSafe.value ? "0" : safeId.value || "0")),
|
|
selectSafe,
|
|
safeTokenType,
|
|
safe,
|
|
safes,
|
|
safeType,
|
|
safeTypes,
|
|
isNewSafe,
|
|
collateralUsd,
|
|
collateral,
|
|
price,
|
|
raiInUsd,
|
|
liquidation,
|
|
tokenKey,
|
|
token,
|
|
symbol,
|
|
rate,
|
|
netValue,
|
|
status,
|
|
liquidationPrice,
|
|
liquidationMaxPrice: price,
|
|
debt,
|
|
debtUsd,
|
|
minDebt,
|
|
debtCeilingReached
|
|
};
|
|
}
|
|
|
|
async function getSafeTypes(web3) {
|
|
const reflexerResolveABI = abis.resolver.reflexer;
|
|
const reflexerResolveAddr = addresses.mainnet.resolver.reflexer;
|
|
|
|
const reflexerResolverInstance = new web3.eth.Contract(
|
|
reflexerResolveABI as AbiItem[],
|
|
reflexerResolveAddr
|
|
);
|
|
|
|
try {
|
|
const rawData: any[] = await reflexerResolverInstance.methods
|
|
.getColInfo(reflexerSafes.types)
|
|
.call();
|
|
|
|
const rawRedemptionPrice = await web3.eth.getStorageAt(
|
|
oracleRelayerAddress,
|
|
4
|
|
);
|
|
return reflexerSafes.allSafes.map(
|
|
({ type, token, key: tokenKey, disabled, safeTokenType }, i) => {
|
|
const [rate, price, ratioCbyD, debtCeiling, totalDebt] = rawData[i];
|
|
|
|
return {
|
|
type,
|
|
token,
|
|
tokenKey,
|
|
disabled,
|
|
safeTokenType,
|
|
rate: calRate(rate),
|
|
redemptionPrice: new BigNumber(rawRedemptionPrice)
|
|
.dividedBy(1e27)
|
|
.toFixed(),
|
|
spotPrice: new BigNumber(price).dividedBy(1e27).toFixed(),
|
|
price: new BigNumber(price)
|
|
.times(rawRedemptionPrice)
|
|
.dividedBy(1e54)
|
|
.toFixed(),
|
|
liquidation: new BigNumber(1)
|
|
.dividedBy(new BigNumber(ratioCbyD).dividedBy(1e27))
|
|
.toFixed(),
|
|
debtCeiling: debtCeiling,
|
|
totalDebt: new BigNumber(totalDebt).multipliedBy(1.00002).toFixed()
|
|
};
|
|
}
|
|
);
|
|
} catch (error) {
|
|
console.error(error);
|
|
return [];
|
|
}
|
|
}
|
|
async function getSafes(user, web3) {
|
|
try {
|
|
const reflexerResolveABI = abis.resolver.reflexer;
|
|
const reflexerResolveAddr = addresses.mainnet.resolver.reflexer;
|
|
|
|
const reflexerResolverInstance = new web3.eth.Contract(
|
|
reflexerResolveABI as AbiItem[],
|
|
reflexerResolveAddr
|
|
);
|
|
|
|
const rawData: any[] = await reflexerResolverInstance.methods
|
|
.getSafes(user)
|
|
.call();
|
|
|
|
const rawRedemptionPrice = await web3.eth.getStorageAt(
|
|
oracleRelayerAddress,
|
|
4
|
|
);
|
|
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 spotPrice = new BigNumber(priceInWei).dividedBy(1e27);
|
|
const price = new BigNumber(priceInWei)
|
|
.times(rawRedemptionPrice)
|
|
.dividedBy(1e54);
|
|
|
|
const safe = reflexerSafes.getSafeByType(type);
|
|
|
|
return {
|
|
id,
|
|
owner,
|
|
type,
|
|
tokenKey: safe.key,
|
|
token: safe.token,
|
|
safeTokenType: safe.safeTokenType,
|
|
collateral: collateral.toFixed(),
|
|
debt: debt.toFixed(),
|
|
liquidatedCollateral: new BigNumber(liquidatedColInWei)
|
|
.dividedBy(1e18)
|
|
.toFixed(),
|
|
rate: calRate(ratePerBlock),
|
|
price: price.toFixed(),
|
|
spotPrice,
|
|
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(spotPrice)).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);
|
|
}
|
|
}
|