Add status component

This commit is contained in:
Georges KABBOUCHI 2021-09-05 18:28:08 +03:00
parent 60b01e884a
commit 75cd0fdac9
5 changed files with 203 additions and 94 deletions

View File

@ -24,7 +24,11 @@
<div class="mx-auto h-full" style="max-width: 296px">
<div class="space-y-4 py-9 h-full flex flex-col">
<div class="flex-1">
<div v-for="(component, index) in components" :key="index" class="mb-6">
<div
v-for="(component, index) in components"
:key="index"
class="mb-6"
>
<input-amount
v-if="component.type === 'input-with-token'"
:key="index"
@ -58,6 +62,13 @@
{{ component.value }}
</value-display>
</div>
<SidebarSectionStatus
v-else-if="component.type === 'status'"
:key="index"
:liquidation="component.liquidation || '0'"
:status="component.status || '0'"
/>
</div>
</div>

View File

@ -14,7 +14,11 @@ import {
import { position as aaveV2Position } from "./protocols/useAaveV2Position";
import { position as compoundPosition } from "./protocols/useCompoundPosition";
import { vault as makerPosition } from "./protocols/useMakerdaoPosition";
import { trove as liquityPosition, troveTypes, troveOverallDetails } from "./protocols/useLiquityPosition";
import {
trove as liquityPosition,
troveTypes,
troveOverallDetails
} from "./protocols/useLiquityPosition";
import { useBalances } from "./useBalances";
import { useDSA } from "./useDSA";
import useEventBus from "./useEventBus";
@ -71,33 +75,44 @@ export function useStrategy(defineStrategy: DefineStrategy) {
pending.value = false;
};
watchEffect(() => {
let position = null;
let positionExtra = {}
watch(
() => [
aaveV2Position,
makerPosition,
compoundPosition,
liquityPosition,
troveTypes,
troveOverallDetails
],
() => {
let position = null;
let positionExtra = {};
if (strategy.schema.protocol == StrategyProtocol.AAVE_V2) {
position = aaveV2Position.value;
} else if (strategy.schema.protocol == StrategyProtocol.MAKERDAO) {
position = makerPosition.value;
} else if (strategy.schema.protocol == StrategyProtocol.COMPOUND) {
position = compoundPosition.value;
} else if (strategy.schema.protocol == StrategyProtocol.LIQUITY) {
position = liquityPosition.value;
positionExtra["troveTypes"] = troveTypes.value;
positionExtra["troveOverallDetails"] = troveOverallDetails.value;
}
if (strategy.schema.protocol == StrategyProtocol.AAVE_V2) {
position = aaveV2Position.value;
} else if (strategy.schema.protocol == StrategyProtocol.MAKERDAO) {
position = makerPosition.value;
} else if (strategy.schema.protocol == StrategyProtocol.COMPOUND) {
position = compoundPosition.value;
} else if (strategy.schema.protocol == StrategyProtocol.LIQUITY) {
position = liquityPosition.value;
strategy.setProps({
convertTokenAmountToWei: valInt,
getTokenByKey,
toBN,
position,
positionExtra,
tokenIdMapping,
formatting,
});
});
positionExtra["troveTypes"] = troveTypes.value;
positionExtra["troveOverallDetails"] = troveOverallDetails.value;
}
strategy.setProps({
convertTokenAmountToWei: valInt,
getTokenByKey,
toBN,
position,
positionExtra,
tokenIdMapping,
formatting
});
},
{ immediate: true }
);
watch(web3, () => strategy.setWeb3(web3.value), { immediate: true });
watch(dsa, () => strategy.setDSA(dsa.value), { immediate: true });

View File

@ -40,7 +40,8 @@ export enum StrategyComponentType {
INPUT_WITH_TOKEN = "input-with-token",
HEADING = "heading",
VALUE = "value"
VALUE = "value",
STATUS = "status",
}
export type StrategyComponentParameterMap = {
@ -52,6 +53,10 @@ export type StrategyComponentParameterMap = {
[StrategyComponentType.HEADING]: {};
[StrategyComponentType.VALUE]: {};
[StrategyComponentType.STATUS]: {
liquidation?: any,
status?: any,
};
};
export interface IStrategyComponent<ComponentType extends StrategyComponentType> {

View File

@ -58,7 +58,7 @@ export class Strategy {
component.defaulted = true;
}
this.notifyListeners();
this.notifyListeners("SET_PROPS");
}
generateComponents(components) {
@ -86,7 +86,7 @@ export class Strategy {
});
}
this.notifyListeners();
this.notifyListeners("onInput");
},
onCustomInput: (values: object) => {
this.components[idx] = Object.assign(this.components[idx], values);
@ -95,7 +95,7 @@ export class Strategy {
...this.getContext(),
component: this.components[idx]
});
this.notifyListeners();
this.notifyListeners("onCustomInput");
}
};
@ -164,16 +164,21 @@ export class Strategy {
setWeb3(web3: Web3) {
this.context.web3 = web3;
this.notifyListeners();
this.notifyListeners("WEB3");
}
setDSA(dsa: DSA) {
this.context.dsa = dsa;
this.notifyListeners();
this.notifyListeners("DSA");
}
async notifyListeners() {
async notifyListeners( from = "") {
if(from && process.env.NODE_ENV === "development") {
console.log(`${from} updated`);
}
for (const listener of this.listeners) {
await listener(this);
}

View File

@ -72,6 +72,72 @@ export default defineStrategy({
defaults: ({ getTokenByKey }) => ({
token: getTokenByKey?.("eth")
})
}),
defineStrategyComponent({
type: StrategyComponentType.HEADING,
name: "Projected Debt Position"
}),
defineStrategyComponent({
type: StrategyComponentType.STATUS,
name: "Status",
update: ({ position, component, components, toBN }) => {
if (
toBN(components[0].value).isZero() &&
toBN(components[1].value).isZero()
) {
return;
}
if (!position) {
return;
}
const newPositionData = changedPositionData(position, components);
const stats = calculateStats(newPositionData);
component.liquidation = BigNumber.max(
toBN(stats.totalMaxLiquidationLimitInEth).div(stats.totalSupplyInEth),
"0"
).toFixed();
component.status = BigNumber.max(
toBN(stats.totalBorrowInEth).div(stats.totalSupplyInEth),
"0"
).toFixed();
}
}),
defineStrategyComponent({
type: StrategyComponentType.VALUE,
name: "LIQUIDATION PRICE (IN ETH)",
value: "-",
update: ({ position, component, components, toBN, formatting }) => {
if (!position) {
return;
}
const newPositionData = changedPositionData(position, components);
const initialStats = calculateStats(position.data);
const newStats = calculateStats(newPositionData);
const stats =
toBN(components[0].value).isZero() &&
toBN(components[1].value).isZero()
? initialStats
: newStats;
const liquidationPrice = BigNumber.max(
toBN(stats.totalBorrowInEth)
.div(stats.totalMaxLiquidationLimitInEth)
.times(position.ethPriceInUsd),
"0"
).toFixed();
console.log(liquidationPrice);
component.value = `${formatting.formatUsdMax(
liquidationPrice,
position.ethPriceInUsd
)} / ${formatting.formatUsd(position.ethPriceInUsd)}`;
}
})
],
@ -80,66 +146,8 @@ export default defineStrategy({
return;
}
const newPositionData = position.data.map(position => {
const changedPosition = { ...position };
if (inputs[0].token.key === position.key) {
changedPosition.borrow = BigNumber.max(
toBN(position.borrow).minus(inputs[0].value),
"0"
).toFixed();
}
if (inputs[1].token.key === position.key) {
changedPosition.supply = BigNumber.max(
toBN(position.supply).minus(inputs[1].value),
"0"
).toFixed();
}
return changedPosition;
});
const stats = newPositionData.reduce(
(
stats,
{ key, supply, borrow, borrowStable, priceInEth, factor, liquidation }
) => {
if (key === "eth") {
stats.ethSupplied = supply;
}
const borrowTotal = toBN(borrow).plus(borrowStable);
stats.totalSupplyInEth = toBN(supply)
.times(priceInEth)
.plus(stats.totalSupplyInEth)
.toFixed();
stats.totalBorrowInEth = toBN(borrowTotal)
.times(priceInEth)
.plus(stats.totalBorrowInEth)
.toFixed();
stats.totalMaxBorrowLimitInEth = toBN(priceInEth)
.times(factor)
.times(supply)
.plus(stats.totalMaxBorrowLimitInEth)
.toFixed();
stats.totalMaxLiquidationLimitInEth = toBN(priceInEth)
.times(liquidation)
.times(supply)
.plus(stats.totalMaxLiquidationLimitInEth)
.toFixed();
return stats;
},
{
totalSupplyInEth: "0",
totalBorrowInEth: "0",
totalMaxBorrowLimitInEth: "0",
totalMaxLiquidationLimitInEth: "0"
}
);
const newPositionData = changedPositionData(position, inputs);
const stats = calculateStats(newPositionData);
let maxLiquidation = "0";
@ -186,3 +194,68 @@ export default defineStrategy({
];
}
});
const changedPositionData = (position, inputs) => {
return position.data.map(position => {
const changedPosition = { ...position };
if (inputs[0].token.key === position.key) {
changedPosition.borrow = BigNumber.max(
new BigNumber(position.borrow).minus(inputs[0].value),
"0"
).toFixed();
}
if (inputs[1].token.key === position.key) {
changedPosition.supply = BigNumber.max(
new BigNumber(position.supply).minus(inputs[1].value),
"0"
).toFixed();
}
return changedPosition;
});
};
const calculateStats = positionData => {
return positionData.reduce(
(
stats,
{ key, supply, borrow, borrowStable, priceInEth, factor, liquidation }
) => {
if (key === "eth") {
stats.ethSupplied = supply;
}
const borrowTotal = new BigNumber(borrow).plus(borrowStable);
stats.totalSupplyInEth = new BigNumber(supply)
.times(priceInEth)
.plus(stats.totalSupplyInEth)
.toFixed();
stats.totalBorrowInEth = new BigNumber(borrowTotal)
.times(priceInEth)
.plus(stats.totalBorrowInEth)
.toFixed();
stats.totalMaxBorrowLimitInEth = new BigNumber(priceInEth)
.times(factor)
.times(supply)
.plus(stats.totalMaxBorrowLimitInEth)
.toFixed();
stats.totalMaxLiquidationLimitInEth = new BigNumber(priceInEth)
.times(liquidation)
.times(supply)
.plus(stats.totalMaxLiquidationLimitInEth)
.toFixed();
return stats;
},
{
totalSupplyInEth: "0",
totalBorrowInEth: "0",
totalMaxBorrowLimitInEth: "0",
totalMaxLiquidationLimitInEth: "0"
}
);
};