mirror of
				https://github.com/Instadapp/assembly.git
				synced 2024-07-29 22:37:06 +00:00 
			
		
		
		
	wip
This commit is contained in:
		
							parent
							
								
									b1b221876c
								
							
						
					
					
						commit
						cd003cc517
					
				| 
						 | 
				
			
			@ -1,6 +1,6 @@
 | 
			
		|||
<template>
 | 
			
		||||
  <div>
 | 
			
		||||
    <div v-if="active" class="relative w-[193px]" v-click-outside="hide">
 | 
			
		||||
    <div v-if="active && activeAccount" class="relative w-[193px]" v-click-outside="hide">
 | 
			
		||||
      <button
 | 
			
		||||
        type="button"
 | 
			
		||||
        class=" relative w-full border border-primary-blue-border rounded pl-3 pr-10 py-2 text-left focus:outline-none focus:ring-1 focus:ring-[#0846E4] focus:border-[#0846E4] sm:text-sm"
 | 
			
		||||
| 
						 | 
				
			
			@ -142,7 +142,7 @@
 | 
			
		|||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
    <button
 | 
			
		||||
      v-else
 | 
			
		||||
      v-if="!active"
 | 
			
		||||
      @click="activate"
 | 
			
		||||
      class="hidden md:flex bg-primary-blue-dark hover:bg-primary-blue-hover shadow text-white p-3 rounded h-9  items-center justify-center w-40"
 | 
			
		||||
    >
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,32 +1,70 @@
 | 
			
		|||
<template>
 | 
			
		||||
  <SidebarContextContainer class="h-full overflow-hidden">
 | 
			
		||||
    <SidebarContextHeader class="xxl:hidden">Strategy</SidebarContextHeader>
 | 
			
		||||
    <SidebarContextHeader>
 | 
			
		||||
      <h1 class="font-bold text-primary-black text-lg">
 | 
			
		||||
        {{ activeStrategy.schema.name }}
 | 
			
		||||
      </h1>
 | 
			
		||||
      <p
 | 
			
		||||
        v-if="activeStrategy.schema.author"
 | 
			
		||||
        class="font-medium text-[#1874FF] text-sm mt-2.5"
 | 
			
		||||
      >
 | 
			
		||||
        {{ activeStrategy.schema.author }}
 | 
			
		||||
      </p>
 | 
			
		||||
    </SidebarContextHeader>
 | 
			
		||||
 | 
			
		||||
    <div class="h-full overflow-y-scroll scrollbar-hover">
 | 
			
		||||
      <div class="mx-auto" style="max-width: 296px">
 | 
			
		||||
        <div class="py-2 sm:py-4">
 | 
			
		||||
          <div v-for="(input, index) in inputs" :key="index">
 | 
			
		||||
            <input-amount
 | 
			
		||||
              :key="index"
 | 
			
		||||
              :value="input.value"
 | 
			
		||||
              :token-key="input.token ? input.token.key : 'eth'"
 | 
			
		||||
              :token-keys="input.tokenKeys ? input.tokenKeys : activeStrategy.getContext()['tokenKeys']"
 | 
			
		||||
              :placeholder="input.placeholder()"
 | 
			
		||||
              :error="input.error"
 | 
			
		||||
              @input="$event => input.onInput($event)"
 | 
			
		||||
              @tokenKeyChanged="
 | 
			
		||||
                tokenKey => {
 | 
			
		||||
                  input.onCustomInput({
 | 
			
		||||
                    token: getTokenByKey(tokenKey)
 | 
			
		||||
                  });
 | 
			
		||||
                }
 | 
			
		||||
              "
 | 
			
		||||
            />
 | 
			
		||||
    <div class="h-full overflow-y-scroll scrollbar-hover flex flex-col">
 | 
			
		||||
      <div class="mx-auto mb-9" style="width: 296px">
 | 
			
		||||
        <div
 | 
			
		||||
          class="flex-shrink-0 font-medium prose prose-sm text-primary-gray"
 | 
			
		||||
          v-if="activeStrategy.schema.details"
 | 
			
		||||
          v-html="activeStrategy.schema.details"
 | 
			
		||||
        ></div>
 | 
			
		||||
      </div>
 | 
			
		||||
      <div class="flex-1 bg-[#1874FF] bg-opacity-[0.04]">
 | 
			
		||||
        <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="(input, index) in inputs" :key="index">
 | 
			
		||||
                <input-amount
 | 
			
		||||
                  :key="index"
 | 
			
		||||
                  :value="input.value"
 | 
			
		||||
                  :token-key="input.token ? input.token.key : 'eth'"
 | 
			
		||||
                  :token-keys="
 | 
			
		||||
                    input.tokenKeys
 | 
			
		||||
                      ? input.tokenKeys
 | 
			
		||||
                      : activeStrategy.getContext()['tokenKeys']
 | 
			
		||||
                  "
 | 
			
		||||
                  :placeholder="input.placeholder()"
 | 
			
		||||
                  @input="$event => input.onInput($event)"
 | 
			
		||||
                  @tokenKeyChanged="
 | 
			
		||||
                    tokenKey => {
 | 
			
		||||
                      input.onCustomInput({
 | 
			
		||||
                        token: getTokenByKey(tokenKey)
 | 
			
		||||
                      });
 | 
			
		||||
                    }
 | 
			
		||||
                  "
 | 
			
		||||
                />
 | 
			
		||||
              </div>
 | 
			
		||||
            </div>
 | 
			
		||||
 | 
			
		||||
            <div class="mt-auto">
 | 
			
		||||
              <ValidationErrors
 | 
			
		||||
                :error-messages="error ? [error] : []"
 | 
			
		||||
                class="mb-6"
 | 
			
		||||
              />
 | 
			
		||||
 | 
			
		||||
              <ButtonCTA
 | 
			
		||||
                class="w-full"
 | 
			
		||||
                @click="submit"
 | 
			
		||||
                :loading="pending"
 | 
			
		||||
                :disabled="pending"
 | 
			
		||||
              >
 | 
			
		||||
                {{ activeStrategy.schema.submitText || "Submit" }}
 | 
			
		||||
              </ButtonCTA>
 | 
			
		||||
 | 
			
		||||
              <p class="text-xs text-[#9FB0C9] mt-2.5 text-center">Instadapp does not charge a fee for this operation</p>
 | 
			
		||||
            </div>
 | 
			
		||||
          </div>
 | 
			
		||||
 | 
			
		||||
          <button @click="submit">Submit</button>
 | 
			
		||||
 | 
			
		||||
          {{ error }}
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
| 
						 | 
				
			
			@ -40,9 +78,9 @@ import { protocolStrategies, DefineStrategy } from "~/core/strategies";
 | 
			
		|||
import { useStrategy } from "~/composables/useStrategy";
 | 
			
		||||
import InputAmount from "~/components/common/input/InputAmount.vue";
 | 
			
		||||
import { useToken } from "~/composables/useToken";
 | 
			
		||||
 | 
			
		||||
import ButtonCTA from "~/components/common/input/ButtonCTA.vue";
 | 
			
		||||
export default defineComponent({
 | 
			
		||||
  components: { InputAmount },
 | 
			
		||||
  components: { InputAmount, ButtonCTA },
 | 
			
		||||
  props: {
 | 
			
		||||
    protocol: {
 | 
			
		||||
      type: String,
 | 
			
		||||
| 
						 | 
				
			
			@ -60,7 +98,13 @@ export default defineComponent({
 | 
			
		|||
    const strategies: DefineStrategy[] =
 | 
			
		||||
      protocolStrategies[props.protocol] || [];
 | 
			
		||||
 | 
			
		||||
    const { inputs, submit, error, strategy : activeStrategy} = useStrategy(
 | 
			
		||||
    const {
 | 
			
		||||
      inputs,
 | 
			
		||||
      submit,
 | 
			
		||||
      error,
 | 
			
		||||
      strategy: activeStrategy,
 | 
			
		||||
      pending
 | 
			
		||||
    } = useStrategy(
 | 
			
		||||
      strategies.find(strategy => strategy.id === props.strategy)
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -70,6 +114,7 @@ export default defineComponent({
 | 
			
		|||
      submit,
 | 
			
		||||
      activeStrategy,
 | 
			
		||||
      getTokenByKey,
 | 
			
		||||
      pending
 | 
			
		||||
    };
 | 
			
		||||
  }
 | 
			
		||||
});
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -12,6 +12,7 @@ import { useBigNumber } from "~/composables/useBigNumber";
 | 
			
		|||
import { usePosition } from "~/composables/usePosition";
 | 
			
		||||
import { useToken } from "~/composables/useToken";
 | 
			
		||||
import { useSorting } from "~/composables/useSorting";
 | 
			
		||||
import useEventBus from "../useEventBus";
 | 
			
		||||
 | 
			
		||||
const {
 | 
			
		||||
  times,
 | 
			
		||||
| 
						 | 
				
			
			@ -69,6 +70,7 @@ export function useAaveV2Position(
 | 
			
		|||
  const { activeAccount } = useDSA();
 | 
			
		||||
  const { getTokenByKey, allATokensV2 } = useToken();
 | 
			
		||||
  const { byMaxSupplyOrBorrowDesc } = useSorting()
 | 
			
		||||
  const { onEvent } = useEventBus()
 | 
			
		||||
  
 | 
			
		||||
  const resolver = computed(() =>
 | 
			
		||||
    chainId.value === 1
 | 
			
		||||
| 
						 | 
				
			
			@ -107,6 +109,7 @@ export function useAaveV2Position(
 | 
			
		|||
    position.value = await fetchPosition();
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  onEvent("protocol::aaveV2::refresh", refreshPosition);
 | 
			
		||||
 | 
			
		||||
  watch(
 | 
			
		||||
    web3,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										24
									
								
								composables/useEventBus.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								composables/useEventBus.ts
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,24 @@
 | 
			
		|||
import { onBeforeUnmount } from "@nuxtjs/composition-api";
 | 
			
		||||
import { TinyEmitter } from "tiny-emitter";
 | 
			
		||||
 | 
			
		||||
const eventEmitter = new TinyEmitter();
 | 
			
		||||
 | 
			
		||||
export default function useEventBus() {
 | 
			
		||||
  const eventHandlers = [];
 | 
			
		||||
 | 
			
		||||
  onBeforeUnmount(() =>
 | 
			
		||||
    eventHandlers.forEach(eventHandler =>
 | 
			
		||||
      eventEmitter.off(eventHandler.event, eventHandler.handler)
 | 
			
		||||
    )
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
  return {
 | 
			
		||||
    onEvent(event, handler) {
 | 
			
		||||
      eventHandlers.push({ event, handler });
 | 
			
		||||
      eventEmitter.on(event, handler);
 | 
			
		||||
    },
 | 
			
		||||
    emitEvent(event, payload) {
 | 
			
		||||
      eventEmitter.emit(event, payload);
 | 
			
		||||
    }
 | 
			
		||||
  };
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -3,15 +3,18 @@ import tokens from "~/constant/tokens";
 | 
			
		|||
import { buildStrategy, DefineStrategy, IStrategy } from "~/core/strategies";
 | 
			
		||||
import { useBalances } from "./useBalances";
 | 
			
		||||
import { useDSA } from "./useDSA";
 | 
			
		||||
import useEventBus from "./useEventBus";
 | 
			
		||||
import { useNotification } from "./useNotification";
 | 
			
		||||
import { useSidebar } from "./useSidebar";
 | 
			
		||||
import { useToken } from "./useToken";
 | 
			
		||||
import { useWeb3 } from "./useWeb3";
 | 
			
		||||
 | 
			
		||||
export function useStrategy(defineStrategy: DefineStrategy) {
 | 
			
		||||
  const { web3, networkName, account } = useWeb3();
 | 
			
		||||
  const { dsa } = useDSA();
 | 
			
		||||
  const { prices, balances, fetchBalances } = useBalances();
 | 
			
		||||
  const { close } = useSidebar();
 | 
			
		||||
  const { valInt, getTokenByKey } = useToken();
 | 
			
		||||
  const { emitEvent } = useEventBus();
 | 
			
		||||
  const {
 | 
			
		||||
    showPendingTransaction,
 | 
			
		||||
    showConfirmedTransaction
 | 
			
		||||
| 
						 | 
				
			
			@ -20,6 +23,7 @@ export function useStrategy(defineStrategy: DefineStrategy) {
 | 
			
		|||
  const strategy = buildStrategy(defineStrategy);
 | 
			
		||||
  const inputs = ref(strategy.inputs);
 | 
			
		||||
  const error = ref("");
 | 
			
		||||
  const pending = ref(false);
 | 
			
		||||
 | 
			
		||||
  strategy.onUpdated(async () => {
 | 
			
		||||
    await nextTick();
 | 
			
		||||
| 
						 | 
				
			
			@ -31,21 +35,32 @@ export function useStrategy(defineStrategy: DefineStrategy) {
 | 
			
		|||
 | 
			
		||||
  const submit = async () => {
 | 
			
		||||
    error.value = "";
 | 
			
		||||
    pending.value = true;
 | 
			
		||||
    try {
 | 
			
		||||
      const tx = await strategy.submit({
 | 
			
		||||
        onReceipt: async () => {
 | 
			
		||||
          showConfirmedTransaction(tx);
 | 
			
		||||
          await fetchBalances(true);
 | 
			
		||||
 | 
			
		||||
          emitEvent(`protocol::${strategy.schema.protocol}::refresh`,{});
 | 
			
		||||
        },
 | 
			
		||||
        from: account.value
 | 
			
		||||
      });
 | 
			
		||||
      showPendingTransaction(tx);
 | 
			
		||||
      close();
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      console.error(e);
 | 
			
		||||
      
 | 
			
		||||
      error.value = e.message;
 | 
			
		||||
    }
 | 
			
		||||
    pending.value = false;
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  strategy.setProps({
 | 
			
		||||
    convertTokenAmountToBigNumber: valInt,
 | 
			
		||||
    getTokenByKey,
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
  watch(web3, () => strategy.setWeb3(web3.value), { immediate: true });
 | 
			
		||||
  watch(dsa, () => strategy.setDSA(dsa.value), { immediate: true });
 | 
			
		||||
  watch(
 | 
			
		||||
| 
						 | 
				
			
			@ -83,6 +98,7 @@ export function useStrategy(defineStrategy: DefineStrategy) {
 | 
			
		|||
    strategy,
 | 
			
		||||
    inputs,
 | 
			
		||||
    submit,
 | 
			
		||||
    error
 | 
			
		||||
    error,
 | 
			
		||||
    pending,
 | 
			
		||||
  };
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -8,6 +8,8 @@ export interface IStrategyContext {
 | 
			
		|||
  inputs: IStrategyInput<StrategyInputType>[];
 | 
			
		||||
  dsaTokens?: { [address: string]: IStrategyToken };
 | 
			
		||||
  userTokens?: { [address: string]: IStrategyToken };
 | 
			
		||||
  convertTokenAmountToBigNumber?: (value: any, decimals: any) => string;
 | 
			
		||||
  getTokenByKey?: (key: string) => IStrategyToken;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface IStrategyToken {
 | 
			
		||||
| 
						 | 
				
			
			@ -47,17 +49,22 @@ export interface IStrategyInput<InputType extends StrategyInputType> {
 | 
			
		|||
    }
 | 
			
		||||
  ) => string | void;
 | 
			
		||||
 | 
			
		||||
  defaults?: (context: Omit<IStrategyContext, 'inputs'>) => object;
 | 
			
		||||
  
 | 
			
		||||
  defaults?: (context: Omit<IStrategyContext, "inputs">) => object;
 | 
			
		||||
 | 
			
		||||
  value?: any;
 | 
			
		||||
 | 
			
		||||
  [key: string]: any;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export enum StrategyProtocol {
 | 
			
		||||
  AAVE_V2 = "aaveV2"
 | 
			
		||||
}
 | 
			
		||||
export interface IStrategy {
 | 
			
		||||
  protocol: StrategyProtocol;
 | 
			
		||||
  id?: string;
 | 
			
		||||
  name: string;
 | 
			
		||||
  description: string;
 | 
			
		||||
  details?: string;
 | 
			
		||||
  author?: string;
 | 
			
		||||
 | 
			
		||||
  inputs: IStrategyInput<StrategyInputType>[];
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -6,8 +6,8 @@ export class Strategy {
 | 
			
		|||
  schema: DefineStrategy;
 | 
			
		||||
  inputs = [];
 | 
			
		||||
  context = {
 | 
			
		||||
    web3: null,
 | 
			
		||||
    dsa: null
 | 
			
		||||
    web3: null as Web3,
 | 
			
		||||
    dsa: null as DSA
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  listeners = [];
 | 
			
		||||
| 
						 | 
				
			
			@ -62,11 +62,6 @@ export class Strategy {
 | 
			
		|||
        value: input.value || "",
 | 
			
		||||
        error: input.error || "",
 | 
			
		||||
        placeholder: () => {
 | 
			
		||||
          console.log({
 | 
			
		||||
            ...this.getContext(),
 | 
			
		||||
            input: this.inputs[idx]
 | 
			
		||||
          });
 | 
			
		||||
 | 
			
		||||
          return input.placeholder
 | 
			
		||||
            ? input.placeholder({
 | 
			
		||||
                ...this.getContext(),
 | 
			
		||||
| 
						 | 
				
			
			@ -111,10 +106,14 @@ export class Strategy {
 | 
			
		|||
    });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  async spells() {
 | 
			
		||||
    return await this.schema.spells(this.getContext());
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  async submit(options) {
 | 
			
		||||
    await this.validate();
 | 
			
		||||
 | 
			
		||||
    const allSpells = await this.schema.spells(this.getContext());
 | 
			
		||||
    const allSpells = await this.spells();
 | 
			
		||||
 | 
			
		||||
    const spells = this.context.dsa.Spell();
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,56 +1,94 @@
 | 
			
		|||
import tokens from "~/constant/tokens";
 | 
			
		||||
import { defineStrategy, defineInput, StrategyInputType } from "../../helpers";
 | 
			
		||||
import {
 | 
			
		||||
  defineStrategy,
 | 
			
		||||
  defineInput,
 | 
			
		||||
  StrategyInputType,
 | 
			
		||||
  StrategyProtocol
 | 
			
		||||
} from "../../helpers";
 | 
			
		||||
 | 
			
		||||
export default defineStrategy({
 | 
			
		||||
  protocol: StrategyProtocol.AAVE_V2,
 | 
			
		||||
  name: "Deposit & Borrow",
 | 
			
		||||
  description: "Deposit collateral & borrow asset in a single txn.",
 | 
			
		||||
 | 
			
		||||
  details: `<p class="text-center">This strategy executes:</p>
 | 
			
		||||
  <ul>
 | 
			
		||||
    <li>Deposit collateral</li>
 | 
			
		||||
    <li>Borrow Debt</li>
 | 
			
		||||
  </ul>`,
 | 
			
		||||
 | 
			
		||||
  author: "Instadapp Team",
 | 
			
		||||
 | 
			
		||||
  inputs: [
 | 
			
		||||
    defineInput({
 | 
			
		||||
      type: StrategyInputType.INPUT_WITH_TOKEN,
 | 
			
		||||
      name: "Debt",
 | 
			
		||||
      placeholder: ({ input }) => `${input.token?.symbol} to Payback`,
 | 
			
		||||
      placeholder: ({ input }) =>
 | 
			
		||||
        input.token ? `${input.token.symbol} to Payback` : "",
 | 
			
		||||
      validate: ({ input }) => {
 | 
			
		||||
        if (!input.token) {
 | 
			
		||||
          return "Token is required";
 | 
			
		||||
          return "Debt token is required";
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (input.token.balance < input.value) {
 | 
			
		||||
          return "Your amount exceeds your maximum limit.";
 | 
			
		||||
        if (!input.value) {
 | 
			
		||||
          return "Deb amount is required";
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // if (input.token.balance < input.value) {
 | 
			
		||||
        //   return "Your amount exceeds your maximum limit.";
 | 
			
		||||
        // }
 | 
			
		||||
      },
 | 
			
		||||
      defaults: context => {
 | 
			
		||||
        return {
 | 
			
		||||
          token: context.dsaTokens
 | 
			
		||||
            ? Object.values(context.dsaTokens).find(t => t.key === "eth")
 | 
			
		||||
            : null
 | 
			
		||||
        };
 | 
			
		||||
      }
 | 
			
		||||
      defaults: ({ getTokenByKey }) => ({
 | 
			
		||||
        token: getTokenByKey?.("eth")
 | 
			
		||||
      })
 | 
			
		||||
    }),
 | 
			
		||||
    defineInput({
 | 
			
		||||
      type: StrategyInputType.INPUT_WITH_TOKEN,
 | 
			
		||||
      name: "Collateral",
 | 
			
		||||
      placeholder: ({ input }) => `${input.token?.symbol} to Withdraw`,
 | 
			
		||||
      defaults: ({ dsaTokens }) => ({
 | 
			
		||||
        token: dsaTokens
 | 
			
		||||
          ? Object.values(dsaTokens).find(t => t.key === "dai")
 | 
			
		||||
          : null
 | 
			
		||||
      placeholder: ({ input }) =>
 | 
			
		||||
        input.token ? `${input.token.symbol} to Withdraw` : "",
 | 
			
		||||
      validate: ({ input }) => {
 | 
			
		||||
        if (!input.token) {
 | 
			
		||||
          return "Collateral token is required";
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!input.value) {
 | 
			
		||||
          return "Collateral amount is required";
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      defaults: ({ getTokenByKey }) => ({
 | 
			
		||||
        token: getTokenByKey?.("dai")
 | 
			
		||||
      })
 | 
			
		||||
    })
 | 
			
		||||
  ],
 | 
			
		||||
 | 
			
		||||
  spells: async ({ inputs }) => {
 | 
			
		||||
  spells: async ({ inputs, convertTokenAmountToBigNumber }) => {
 | 
			
		||||
    return [
 | 
			
		||||
      {
 | 
			
		||||
        connector: "aave_v2",
 | 
			
		||||
        method: "deposit",
 | 
			
		||||
        args: [inputs[0].token.address, inputs[0].value, 0, 0]
 | 
			
		||||
        args: [
 | 
			
		||||
          inputs[0].token.address,
 | 
			
		||||
          convertTokenAmountToBigNumber(
 | 
			
		||||
            inputs[0].value,
 | 
			
		||||
            inputs[0].token.decimals
 | 
			
		||||
          ),
 | 
			
		||||
          0,
 | 
			
		||||
          0
 | 
			
		||||
        ]
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        connector: "aave_v2",
 | 
			
		||||
        method: "borrow",
 | 
			
		||||
        args: [inputs[1].token.address, inputs[1].value, 1, 0, 0]
 | 
			
		||||
        args: [
 | 
			
		||||
          inputs[1].token.address,
 | 
			
		||||
          convertTokenAmountToBigNumber(
 | 
			
		||||
            inputs[1].value,
 | 
			
		||||
            inputs[1].token.decimals
 | 
			
		||||
          ),
 | 
			
		||||
          2,
 | 
			
		||||
          0,
 | 
			
		||||
          0
 | 
			
		||||
        ]
 | 
			
		||||
      }
 | 
			
		||||
    ];
 | 
			
		||||
  }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,16 +1,29 @@
 | 
			
		|||
import tokens from "~/constant/tokens";
 | 
			
		||||
import { defineStrategy, defineInput, StrategyInputType } from "../../helpers";
 | 
			
		||||
import {
 | 
			
		||||
  defineStrategy,
 | 
			
		||||
  defineInput,
 | 
			
		||||
  StrategyInputType,
 | 
			
		||||
  StrategyProtocol
 | 
			
		||||
} from "../../helpers";
 | 
			
		||||
 | 
			
		||||
export default defineStrategy({
 | 
			
		||||
  protocol: StrategyProtocol.AAVE_V2,
 | 
			
		||||
  name: "Payback & Withdraw",
 | 
			
		||||
  description: "Payback debt & withdraw collateral in a single txn.",
 | 
			
		||||
  author: "Instadapp Team",
 | 
			
		||||
 | 
			
		||||
  details: `<p class="text-center">This strategy executes:</p>
 | 
			
		||||
  <ul>
 | 
			
		||||
    <li>Payback debt</li>
 | 
			
		||||
    <li>Withdraw collateral</li>
 | 
			
		||||
  </ul>`,
 | 
			
		||||
 | 
			
		||||
  inputs: [
 | 
			
		||||
    defineInput({
 | 
			
		||||
      type: StrategyInputType.INPUT_WITH_TOKEN,
 | 
			
		||||
      name: "Debt",
 | 
			
		||||
      placeholder: ({ input }) => `${input.token.symbol} to Payback`,
 | 
			
		||||
      placeholder: ({ input }) =>
 | 
			
		||||
        input.token ? `${input.token.symbol} to Payback` : "",
 | 
			
		||||
      validate: ({ input }) => {
 | 
			
		||||
        if (!input.token) {
 | 
			
		||||
          return "Token is required";
 | 
			
		||||
| 
						 | 
				
			
			@ -20,27 +33,49 @@ export default defineStrategy({
 | 
			
		|||
          return "Your amount exceeds your maximum limit.";
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      token: tokens.mainnet.getTokenByKey("eth")
 | 
			
		||||
      defaults: ({ getTokenByKey }) => ({
 | 
			
		||||
        token: getTokenByKey?.("dai")
 | 
			
		||||
      })
 | 
			
		||||
    }),
 | 
			
		||||
    defineInput({
 | 
			
		||||
      type: StrategyInputType.INPUT_WITH_TOKEN,
 | 
			
		||||
      name: "Collateral",
 | 
			
		||||
      placeholder: ({ input }) => `${input.token.symbol} to Withdraw`,
 | 
			
		||||
      token: tokens.mainnet.getTokenByKey("dai")
 | 
			
		||||
      placeholder: ({ input }) =>
 | 
			
		||||
        input.token ? `${input.token.symbol} to Withdraw` : "",
 | 
			
		||||
      defaults: ({ getTokenByKey }) => ({
 | 
			
		||||
        token: getTokenByKey?.("eth")
 | 
			
		||||
      })
 | 
			
		||||
    })
 | 
			
		||||
  ],
 | 
			
		||||
 | 
			
		||||
  spells: async ({ inputs }) => {
 | 
			
		||||
  spells: async ({ inputs, convertTokenAmountToBigNumber }) => {
 | 
			
		||||
    return [
 | 
			
		||||
      {
 | 
			
		||||
        connector: "aave_v2",
 | 
			
		||||
        method: "payback",
 | 
			
		||||
        args: [inputs[0].token.address, inputs[0].value, 1, 0, 0]
 | 
			
		||||
        args: [
 | 
			
		||||
          inputs[0].token.address,
 | 
			
		||||
          convertTokenAmountToBigNumber(
 | 
			
		||||
            inputs[0].value,
 | 
			
		||||
            inputs[0].token.decimals
 | 
			
		||||
          ),
 | 
			
		||||
          12,
 | 
			
		||||
          0,
 | 
			
		||||
          0
 | 
			
		||||
        ]
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        connector: "aave_v2",
 | 
			
		||||
        method: "withdraw",
 | 
			
		||||
        args: [inputs[1].token.address, inputs[1].value, 0, 0]
 | 
			
		||||
        args: [
 | 
			
		||||
          inputs[1].token.address,
 | 
			
		||||
          convertTokenAmountToBigNumber(
 | 
			
		||||
            inputs[1].value,
 | 
			
		||||
            inputs[1].token.decimals
 | 
			
		||||
          ),
 | 
			
		||||
          0,
 | 
			
		||||
          0
 | 
			
		||||
        ]
 | 
			
		||||
      }
 | 
			
		||||
    ];
 | 
			
		||||
  }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -137,7 +137,8 @@ export default defineComponent({
 | 
			
		|||
      }
 | 
			
		||||
    }, { immediate: true })
 | 
			
		||||
 | 
			
		||||
    onErrorCaptured(() => {
 | 
			
		||||
    onErrorCaptured((error) => {
 | 
			
		||||
      console.error(error)
 | 
			
		||||
      return false
 | 
			
		||||
    })
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -13,6 +13,7 @@
 | 
			
		|||
    "@nuxtjs/composition-api": "^0.24.7",
 | 
			
		||||
    "@portis/web3": "^4.0.5",
 | 
			
		||||
    "@tailwindcss/forms": "^0.3.3",
 | 
			
		||||
    "@tailwindcss/typography": "^0.4.1",
 | 
			
		||||
    "@vueuse/core": "^5.1.4",
 | 
			
		||||
    "@walletconnect/web3-provider": "^1.4.1",
 | 
			
		||||
    "bignumber.js": "^9.0.1",
 | 
			
		||||
| 
						 | 
				
			
			@ -22,6 +23,7 @@
 | 
			
		|||
    "nuxt": "^2.15.7",
 | 
			
		||||
    "qrcode": "^1.4.4",
 | 
			
		||||
    "slugify": "^1.6.0",
 | 
			
		||||
    "tiny-emitter": "^2.1.0",
 | 
			
		||||
    "v-click-outside": "^3.1.2",
 | 
			
		||||
    "v-tooltip": "^2.1.3",
 | 
			
		||||
    "vue-clipboard2": "^0.3.1",
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -120,5 +120,6 @@ module.exports = {
 | 
			
		|||
  },
 | 
			
		||||
  plugins: [
 | 
			
		||||
    require('@tailwindcss/forms'),
 | 
			
		||||
    require('@tailwindcss/typography'),
 | 
			
		||||
  ],
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										27
									
								
								yarn.lock
									
									
									
									
									
								
							
							
						
						
									
										27
									
								
								yarn.lock
									
									
									
									
									
								
							| 
						 | 
				
			
			@ -1707,6 +1707,16 @@
 | 
			
		|||
  dependencies:
 | 
			
		||||
    mini-svg-data-uri "^1.2.3"
 | 
			
		||||
 | 
			
		||||
"@tailwindcss/typography@^0.4.1":
 | 
			
		||||
  version "0.4.1"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/@tailwindcss/typography/-/typography-0.4.1.tgz#51ddbceea6a0ee9902c649dbe58871c81a831212"
 | 
			
		||||
  integrity sha512-ovPPLUhs7zAIJfr0y1dbGlyCuPhpuv/jpBoFgqAc658DWGGrOBWBMpAWLw2KlzbNeVk4YBJMzue1ekvIbdw6XA==
 | 
			
		||||
  dependencies:
 | 
			
		||||
    lodash.castarray "^4.4.0"
 | 
			
		||||
    lodash.isplainobject "^4.0.6"
 | 
			
		||||
    lodash.merge "^4.6.2"
 | 
			
		||||
    lodash.uniq "^4.5.0"
 | 
			
		||||
 | 
			
		||||
"@types/anymatch@*":
 | 
			
		||||
  version "3.0.0"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/@types/anymatch/-/anymatch-3.0.0.tgz#c95ff14401dbb2869913afac3935af4ad0d37f1a"
 | 
			
		||||
| 
						 | 
				
			
			@ -7277,11 +7287,21 @@ lodash._reinterpolate@^3.0.0:
 | 
			
		|||
  resolved "https://registry.yarnpkg.com/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d"
 | 
			
		||||
  integrity sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=
 | 
			
		||||
 | 
			
		||||
lodash.castarray@^4.4.0:
 | 
			
		||||
  version "4.4.0"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/lodash.castarray/-/lodash.castarray-4.4.0.tgz#c02513515e309daddd4c24c60cfddcf5976d9115"
 | 
			
		||||
  integrity sha1-wCUTUV4wna3dTCTGDP3c9ZdtkRU=
 | 
			
		||||
 | 
			
		||||
lodash.debounce@^4.0.8:
 | 
			
		||||
  version "4.0.8"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af"
 | 
			
		||||
  integrity sha1-gteb/zCmfEAF/9XiUVMArZyk168=
 | 
			
		||||
 | 
			
		||||
lodash.isplainobject@^4.0.6:
 | 
			
		||||
  version "4.0.6"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb"
 | 
			
		||||
  integrity sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=
 | 
			
		||||
 | 
			
		||||
lodash.kebabcase@^4.1.1:
 | 
			
		||||
  version "4.1.1"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz#8489b1cb0d29ff88195cceca448ff6d6cc295c36"
 | 
			
		||||
| 
						 | 
				
			
			@ -7292,6 +7312,11 @@ lodash.memoize@^4.1.2:
 | 
			
		|||
  resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe"
 | 
			
		||||
  integrity sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=
 | 
			
		||||
 | 
			
		||||
lodash.merge@^4.6.2:
 | 
			
		||||
  version "4.6.2"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a"
 | 
			
		||||
  integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==
 | 
			
		||||
 | 
			
		||||
lodash.template@^4.5.0:
 | 
			
		||||
  version "4.5.0"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/lodash.template/-/lodash.template-4.5.0.tgz#f976195cf3f347d0d5f52483569fe8031ccce8ab"
 | 
			
		||||
| 
						 | 
				
			
			@ -11030,7 +11055,7 @@ timsort@^0.3.0:
 | 
			
		|||
  resolved "https://registry.yarnpkg.com/timsort/-/timsort-0.3.0.tgz#405411a8e7e6339fe64db9a234de11dc31e02bd4"
 | 
			
		||||
  integrity sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=
 | 
			
		||||
 | 
			
		||||
tiny-emitter@^2.0.0:
 | 
			
		||||
tiny-emitter@^2.0.0, tiny-emitter@^2.1.0:
 | 
			
		||||
  version "2.1.0"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/tiny-emitter/-/tiny-emitter-2.1.0.tgz#1d1a56edfc51c43e863cbb5382a72330e3555423"
 | 
			
		||||
  integrity sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue
	
	Block a user