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

View File

@ -14,7 +14,11 @@ import {
import { position as aaveV2Position } from "./protocols/useAaveV2Position"; import { position as aaveV2Position } from "./protocols/useAaveV2Position";
import { position as compoundPosition } from "./protocols/useCompoundPosition"; import { position as compoundPosition } from "./protocols/useCompoundPosition";
import { vault as makerPosition } from "./protocols/useMakerdaoPosition"; 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 { useBalances } from "./useBalances";
import { useDSA } from "./useDSA"; import { useDSA } from "./useDSA";
import useEventBus from "./useEventBus"; import useEventBus from "./useEventBus";
@ -71,33 +75,44 @@ export function useStrategy(defineStrategy: DefineStrategy) {
pending.value = false; pending.value = false;
}; };
watchEffect(() => { watch(
let position = null; () => [
let positionExtra = {} aaveV2Position,
makerPosition,
compoundPosition,
liquityPosition,
troveTypes,
troveOverallDetails
],
() => {
let position = null;
let positionExtra = {};
if (strategy.schema.protocol == StrategyProtocol.AAVE_V2) { if (strategy.schema.protocol == StrategyProtocol.AAVE_V2) {
position = aaveV2Position.value; position = aaveV2Position.value;
} else if (strategy.schema.protocol == StrategyProtocol.MAKERDAO) { } else if (strategy.schema.protocol == StrategyProtocol.MAKERDAO) {
position = makerPosition.value; position = makerPosition.value;
} else if (strategy.schema.protocol == StrategyProtocol.COMPOUND) { } else if (strategy.schema.protocol == StrategyProtocol.COMPOUND) {
position = compoundPosition.value; position = compoundPosition.value;
} else if (strategy.schema.protocol == StrategyProtocol.LIQUITY) { } else if (strategy.schema.protocol == StrategyProtocol.LIQUITY) {
position = liquityPosition.value; position = liquityPosition.value;
positionExtra["troveTypes"] = troveTypes.value;
positionExtra["troveOverallDetails"] = troveOverallDetails.value;
}
strategy.setProps({ positionExtra["troveTypes"] = troveTypes.value;
convertTokenAmountToWei: valInt, positionExtra["troveOverallDetails"] = troveOverallDetails.value;
getTokenByKey, }
toBN,
position, strategy.setProps({
positionExtra, convertTokenAmountToWei: valInt,
tokenIdMapping, getTokenByKey,
formatting, toBN,
}); position,
}); positionExtra,
tokenIdMapping,
formatting
});
},
{ immediate: true }
);
watch(web3, () => strategy.setWeb3(web3.value), { immediate: true }); watch(web3, () => strategy.setWeb3(web3.value), { immediate: true });
watch(dsa, () => strategy.setDSA(dsa.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", INPUT_WITH_TOKEN = "input-with-token",
HEADING = "heading", HEADING = "heading",
VALUE = "value" VALUE = "value",
STATUS = "status",
} }
export type StrategyComponentParameterMap = { export type StrategyComponentParameterMap = {
@ -52,6 +53,10 @@ export type StrategyComponentParameterMap = {
[StrategyComponentType.HEADING]: {}; [StrategyComponentType.HEADING]: {};
[StrategyComponentType.VALUE]: {}; [StrategyComponentType.VALUE]: {};
[StrategyComponentType.STATUS]: {
liquidation?: any,
status?: any,
};
}; };
export interface IStrategyComponent<ComponentType extends StrategyComponentType> { export interface IStrategyComponent<ComponentType extends StrategyComponentType> {

View File

@ -58,7 +58,7 @@ export class Strategy {
component.defaulted = true; component.defaulted = true;
} }
this.notifyListeners(); this.notifyListeners("SET_PROPS");
} }
generateComponents(components) { generateComponents(components) {
@ -86,7 +86,7 @@ export class Strategy {
}); });
} }
this.notifyListeners(); this.notifyListeners("onInput");
}, },
onCustomInput: (values: object) => { onCustomInput: (values: object) => {
this.components[idx] = Object.assign(this.components[idx], values); this.components[idx] = Object.assign(this.components[idx], values);
@ -95,7 +95,7 @@ export class Strategy {
...this.getContext(), ...this.getContext(),
component: this.components[idx] component: this.components[idx]
}); });
this.notifyListeners(); this.notifyListeners("onCustomInput");
} }
}; };
@ -164,16 +164,21 @@ export class Strategy {
setWeb3(web3: Web3) { setWeb3(web3: Web3) {
this.context.web3 = web3; this.context.web3 = web3;
this.notifyListeners(); this.notifyListeners("WEB3");
} }
setDSA(dsa: DSA) { setDSA(dsa: DSA) {
this.context.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) { for (const listener of this.listeners) {
await listener(this); await listener(this);
} }

View File

@ -72,6 +72,72 @@ export default defineStrategy({
defaults: ({ getTokenByKey }) => ({ defaults: ({ getTokenByKey }) => ({
token: getTokenByKey?.("eth") 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; return;
} }
const newPositionData = position.data.map(position => { const newPositionData = changedPositionData(position, inputs);
const changedPosition = { ...position }; const stats = calculateStats(newPositionData);
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"
}
);
let maxLiquidation = "0"; 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"
}
);
};