diff --git a/composables/useStrategy.ts b/composables/useStrategy.ts
index a71a4b8..ff0ef4b 100644
--- a/composables/useStrategy.ts
+++ b/composables/useStrategy.ts
@@ -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 });
diff --git a/core/strategies/helpers/index.ts b/core/strategies/helpers/index.ts
index a288f48..ee8c2fe 100644
--- a/core/strategies/helpers/index.ts
+++ b/core/strategies/helpers/index.ts
@@ -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
{
diff --git a/core/strategies/helpers/strategy.ts b/core/strategies/helpers/strategy.ts
index cc594f8..8ba043d 100644
--- a/core/strategies/helpers/strategy.ts
+++ b/core/strategies/helpers/strategy.ts
@@ -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);
}
diff --git a/core/strategies/protocols/aave-v2/payback-and-withdraw.ts b/core/strategies/protocols/aave-v2/payback-and-withdraw.ts
index fcb66a2..2f5e033 100644
--- a/core/strategies/protocols/aave-v2/payback-and-withdraw.ts
+++ b/core/strategies/protocols/aave-v2/payback-and-withdraw.ts
@@ -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"
+ }
+ );
+};