2021-08-22 17:35:46 +00:00
|
|
|
import DSA, { Spell } from "dsa-connect";
|
|
|
|
import Web3 from "web3";
|
|
|
|
import slugify from "slugify";
|
|
|
|
import { Strategy } from "./strategy";
|
2021-08-26 18:34:27 +00:00
|
|
|
import BigNumber from "bignumber.js";
|
2021-09-04 17:39:05 +00:00
|
|
|
import tokenIdMapping from "~/constant/tokenIdMapping";
|
2021-09-05 11:01:19 +00:00
|
|
|
import { useFormatting } from "~/composables/useFormatting";
|
2021-08-22 17:35:46 +00:00
|
|
|
export interface IStrategyContext {
|
|
|
|
dsa: DSA;
|
|
|
|
web3: Web3;
|
2021-09-05 11:46:39 +00:00
|
|
|
components: IStrategyComponent<StrategyComponentType>[];
|
2021-09-04 17:39:05 +00:00
|
|
|
|
|
|
|
// TODO: add types in useStrategy.ts
|
2021-08-26 16:38:31 +00:00
|
|
|
dsaBalances?: { [address: string]: IStrategyToken };
|
|
|
|
userBalances?: { [address: string]: IStrategyToken };
|
2021-08-25 19:42:41 +00:00
|
|
|
tokens?: { [address: string]: IStrategyToken };
|
2021-08-26 16:38:31 +00:00
|
|
|
convertTokenAmountToWei?: (value: any, decimals: any) => string;
|
2021-08-25 11:13:23 +00:00
|
|
|
getTokenByKey?: (key: string) => IStrategyToken;
|
2021-08-25 19:42:41 +00:00
|
|
|
position?: any;
|
2021-09-04 23:12:21 +00:00
|
|
|
positionExtra?: { [key: string]: any };
|
2021-08-26 16:38:31 +00:00
|
|
|
variables?: { [key: string]: any };
|
2021-08-26 18:34:27 +00:00
|
|
|
toBN?: (value: any) => BigNumber;
|
2021-09-04 17:39:05 +00:00
|
|
|
tokenIdMapping?: typeof tokenIdMapping;
|
2021-09-05 11:01:19 +00:00
|
|
|
formatting?: ReturnType<typeof useFormatting>;
|
2021-08-22 17:35:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
export interface IStrategyToken {
|
|
|
|
address: string;
|
|
|
|
key: string;
|
|
|
|
symbol: string;
|
|
|
|
balance: string;
|
2021-09-04 23:12:21 +00:00
|
|
|
decimals: string;
|
2021-08-22 17:35:46 +00:00
|
|
|
|
|
|
|
// supply: string;
|
|
|
|
// borrow: string;
|
|
|
|
}
|
|
|
|
|
2021-09-05 11:46:39 +00:00
|
|
|
export enum StrategyComponentType {
|
2021-09-05 11:01:19 +00:00
|
|
|
// INPUT = "input",
|
|
|
|
INPUT_WITH_TOKEN = "input-with-token",
|
|
|
|
|
|
|
|
HEADING = "heading",
|
|
|
|
VALUE = "value"
|
2021-08-22 17:35:46 +00:00
|
|
|
}
|
|
|
|
|
2021-09-05 11:46:39 +00:00
|
|
|
export type StrategyComponentParameterMap = {
|
2021-09-05 11:01:19 +00:00
|
|
|
// [StrategyInputType.INPUT]: {};
|
2021-08-22 17:35:46 +00:00
|
|
|
|
2021-09-05 11:46:39 +00:00
|
|
|
[StrategyComponentType.INPUT_WITH_TOKEN]: {
|
2021-08-22 17:35:46 +00:00
|
|
|
token?: IStrategyToken;
|
|
|
|
};
|
2021-09-05 11:01:19 +00:00
|
|
|
|
2021-09-05 11:46:39 +00:00
|
|
|
[StrategyComponentType.HEADING]: {};
|
|
|
|
[StrategyComponentType.VALUE]: {};
|
2021-08-22 17:35:46 +00:00
|
|
|
};
|
|
|
|
|
2021-09-05 11:46:39 +00:00
|
|
|
export interface IStrategyComponent<ComponentType extends StrategyComponentType> {
|
|
|
|
type: ComponentType;
|
2021-08-22 17:35:46 +00:00
|
|
|
name: string;
|
2021-08-25 19:42:41 +00:00
|
|
|
|
2021-08-26 16:38:31 +00:00
|
|
|
variables?: { [key: string]: any };
|
2021-08-25 19:42:41 +00:00
|
|
|
|
2021-08-22 17:35:46 +00:00
|
|
|
placeholder?: (
|
|
|
|
context: IStrategyContext & {
|
2021-09-05 11:46:39 +00:00
|
|
|
component: IStrategyComponent<ComponentType> & StrategyComponentParameterMap[ComponentType];
|
2021-08-22 17:35:46 +00:00
|
|
|
}
|
|
|
|
) => string;
|
|
|
|
validate?: (
|
|
|
|
context: IStrategyContext & {
|
2021-09-05 11:46:39 +00:00
|
|
|
component: IStrategyComponent<ComponentType> & StrategyComponentParameterMap[ComponentType];
|
2021-08-22 17:35:46 +00:00
|
|
|
}
|
|
|
|
) => string | void;
|
2021-08-23 23:07:53 +00:00
|
|
|
|
2021-09-05 11:46:39 +00:00
|
|
|
defaults?: (context: Omit<IStrategyContext, "components">) => object;
|
2021-09-05 11:01:19 +00:00
|
|
|
update?: (
|
|
|
|
context: IStrategyContext & {
|
2021-09-05 11:46:39 +00:00
|
|
|
component: IStrategyComponent<ComponentType> & StrategyComponentParameterMap[ComponentType];
|
2021-09-05 11:01:19 +00:00
|
|
|
}
|
|
|
|
) => void;
|
2021-08-25 11:13:23 +00:00
|
|
|
|
2021-08-22 17:35:46 +00:00
|
|
|
value?: any;
|
|
|
|
|
|
|
|
[key: string]: any;
|
|
|
|
}
|
|
|
|
|
2021-08-25 11:13:23 +00:00
|
|
|
export enum StrategyProtocol {
|
2021-08-25 19:42:41 +00:00
|
|
|
AAVE_V2 = "aaveV2",
|
|
|
|
COMPOUND = "compound",
|
|
|
|
MAKERDAO = "makerdao",
|
2021-08-26 18:34:27 +00:00
|
|
|
LIQUITY = "liquity"
|
2021-08-25 11:13:23 +00:00
|
|
|
}
|
2021-08-22 17:35:46 +00:00
|
|
|
export interface IStrategy {
|
2021-08-25 11:13:23 +00:00
|
|
|
protocol: StrategyProtocol;
|
2021-08-22 17:35:46 +00:00
|
|
|
id?: string;
|
|
|
|
name: string;
|
|
|
|
description: string;
|
2021-08-25 11:13:23 +00:00
|
|
|
details?: string;
|
2021-08-22 17:35:46 +00:00
|
|
|
author?: string;
|
|
|
|
|
2021-09-05 11:46:39 +00:00
|
|
|
components: IStrategyComponent<StrategyComponentType>[];
|
2021-08-22 17:35:46 +00:00
|
|
|
|
2021-08-25 19:51:05 +00:00
|
|
|
variables?: object;
|
|
|
|
|
2021-08-22 17:35:46 +00:00
|
|
|
spells: (context: IStrategyContext) => Promise<Spell[]> | Spell[];
|
2021-08-26 18:34:27 +00:00
|
|
|
validate?: (
|
|
|
|
context: IStrategyContext
|
|
|
|
) => Promise<void | string> | void | string;
|
2021-08-22 17:35:46 +00:00
|
|
|
|
|
|
|
submitText?: string;
|
|
|
|
}
|
|
|
|
|
2021-09-05 11:46:39 +00:00
|
|
|
export function defineStrategyComponent<ComponentType extends StrategyComponentType>(
|
|
|
|
component: IStrategyComponent<ComponentType>
|
2021-08-22 17:35:46 +00:00
|
|
|
) {
|
2021-09-05 11:46:39 +00:00
|
|
|
return component as IStrategyComponent<ComponentType>;
|
2021-08-22 17:35:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
export function defineStrategy(strategy: IStrategy) {
|
|
|
|
return {
|
|
|
|
...strategy,
|
|
|
|
id: strategy.id ? strategy.id : slugify(strategy.name).toLowerCase()
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
export function buildStrategy(schema: DefineStrategy) {
|
2021-08-23 23:07:53 +00:00
|
|
|
return new Strategy(schema);
|
2021-08-22 17:35:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
export type DefineStrategy = ReturnType<typeof defineStrategy>;
|