Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@pradyuman-verma
Last active December 13, 2021 08:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pradyuman-verma/bb8f8a572e1476c2690b7e8edc4b9f0a to your computer and use it in GitHub Desktop.
Save pradyuman-verma/bb8f8a572e1476c2690b7e8edc4b9f0a to your computer and use it in GitHub Desktop.
FlashLoan

This gist will explain how you can use the dsa-connect Flashloan feature.

I will be using this code.

/**
This code is from the Instadapp terminal, so there is no need to import node modules.
*/

// Connect your metamask account. It will be rendered as USER_ADDRESS
console.log('Connected address', USER_ADDRESS)

// This line will fetch DSA accounts created from your metamask account.
const dsaWallets = await dsa.getAccounts(USER_ADDRESS)
// Fetching dsaId of one of your account.
const dsaId = dsaWallets[0]['id']

// Setting that dsa account to use, as there can be multiple dsa account created from a single metamask account.
dsa.setInstance(dsaId).then(console.log);

if (dsaWallets.length == 0) return alert("Create a DSA")

const dai_token = "0x8f3Cf7ad23Cd3CaDbD9735AFf958023239c6A063"
const eth_token = "0x7ceB23fD6bC0adD59E62ac25578270cFf1b9f619"

let spells = new dsa.Spell()

let amount = web3.utils.toWei("0.5", "ether")
console.log(amount * 1.0005)

// params for the API.
const params = {
	buyToken: eth_token,
	sellToken: dai_token,
	sellAmount: amount,
	maxSlippage: 0.1,
	dsaAddress: USER_ADDRESS,
 	fee: 0
}

// Using 1inch API to fetch details like calldata, unitAmt.
const response = await axios.get(
    `https://api.instadapp.io/defi/polygon/1inch/swap`, {params: params}
);
let res = response.data
console.log(res["unitAmt"]);

/*# FLASHLOAN #*/
// step 1: sell ETH and buy DAI
spells.add({
  connector: "1INCH-A",
  method: "sell",
  args: [
    eth_token,
    dai_token,
    amount,
    res['unitAmt'],
    res['calldata'],
    0
  ]
})
// step 2: deposit ETH
spells.add({
  connector: "AAVE-V2-A",
  method: "deposit",
  args: [
    eth_token,
    0,
    0,
    0
  ]
})
// step 3: borrow DAI
spells.add({
  connector: "AAVE-V2-A",
  method: "borrow",
  args: [
    dai_token,
    (amount * 1.0005).toString(),
    2,
    0,
    0
  ]
})

// step 4: flash playback
spells.add({
  connector: "INSTAPOOL-C",
  method: "flashPayback",
  args: [
    dai_token,
    (amount * 1.0005).toString(),
    0,
    0
  ]
})

// encoding the spells for flashloan
const flashloanSpells = dsa.instapool_v2.encodeFlashCastData(spells);
const flashloanWrappedSpells = new dsa.Spell();
const route = 5; // Balancer route

// step 5: flash borrow and cast
flashloanWrappedSpells.add({
      connector: 'INSTAPOOL-C',
      method: 'flashBorrowAndCast',
      args: [dai_token, amount, route, flashloanSpells, "0x"],
})

console.log(`DSA instance - ${dsa.instance}`)
console.log(`spells: ${dsa.encodeSpells(spells)}`)
console.log(`wrapped spells for flashloan: ${flashloanWrappedSpells}`)
/// Step 6: Final spell.
console.log("Transaction hash:",
 	await dsa.cast({
    flashloanWrappedSpells,
  	value: 0
  }).then((x) => console.log(x)))

Here is what's happening:

  • Taking a DAI flash loan from Balancer.
  • Swapping these DAI's with ETH on 1inch.
  • Supplying this ETH on aave protocol.
  • Borrowing DAI from aave.
  • Payback DAI again to flash loan, i.e., flashPayback.

So, let's start unboxig the code.

const route = 5; // Balancer route

This line sets the route of flash loans we want to use. Currently, flash loan supports seven routes, using route five here. For more info about routes, check here

const flashloanSpells = dsa.instapool_v2.encodeFlashCastData(spells);

We are encoding the spells here; these spells will be used right after taking a flash loan.

flashloanWrappedSpells.add({
      connector: 'INSTAPOOL-C',
      method: 'flashBorrowAndCast',
      args: [dai_token, amount, route, flashloanSpells, "0x"],
})

Adding this spell to flashloanWrappedSpells, this spell will be the first to get executed. In the args, we are providing flashloanWrappedSpells as a args.

await dsa.cast({
    flashloanWrappedSpells,
  	value: 0
  })

Casting the flash loan spell will cast the spell, which will take the flash loan of DAI from route-5. After taking the loan, flashloanSpells will be cast.

As we have DAI now, flashloan will start executing flashloanSpells. In the flashloanSpells the first spell is to swap DAI with ETH #.

spells.add({
  connector: "1INCH-A",
  method: "sell",
  args: [
    eth_token,
    dai_token,
    amount,
    res['unitAmt'],
    res['calldata'],
    0
  ]
})

Now, we have some ETH in our DSA.

Now, we will be supplying these ETH to aave #.

spells.add({
  connector: "AAVE-V2-A",
  method: "deposit",
  args: [
    eth_token,
    0,
    0,
    0
  ]
})

Then Borrowing DAI from aave.

spells.add({
  connector: "AAVE-V2-A",
  method: "borrow",
  args: [
    dai_token,
    (amount * 1.0005).toString(),
    2,
    0,
    0
  ]
})

Now, we have DAI again. Let's pay it back to flash loan.

spells.add({
  connector: "INSTAPOOL-C",
  method: "flashPayback",
  args: [
    dai_token,
    (amount * 1.0005).toString(),
    0,
    0
  ]
})

Done, we have successfully created a flash loan position using dsa-connect.

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment