This recipe was shared by Liquity in this blogpost
This recipe refinances a Maker ETH-A Vault by utilizing a flashloan to pay back the debt and re-creates the position in Liquity.
CODE SNIPPIT
const ETH_ADDRESS = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE"
const DAI_TOKEN_ADDRESS = "0x6b175474e89094c44da98b954eedeac495271d0f"
const LUSD_TOKEN_ADDRESS = "0x5f98805A4E8be255a32880FDeC7F6728C6568bA0"
const migrateMakerVaultToLiquity = (dsa, helpers, vaultId) => {
// 1. Look up how much collateral and debt exists in the Maker vault
const vault = await helpers.getMakerResolver().getVaultById(vaultId)
const vaultCollateral = vault.ink
const vaultDebt = vault.debt
// 2. Next we flash loan the same amount of ETH as the Maker vault collateral
// so that we can open a Liquity Trove with the same amount.
// NB: We declare this spell at the end of the script, with all the spells
// which follow the flash loan as "child" transactions of the flashloan.
// 3. Create a Trove using the flashloaned ETH, and borrow LUSD
const maxFeePercentage = ethers.utils.parseUnits("0.5", 18)
const { upperHint, lowerHint } = await helpers.getTroveInsertionHints(
vaultCollateral,
vaultDebt
)
const openTroveSpell = {
connector: "LIQUITY-A",
method: "open",
args: [
vaultCollateral,
maxFeePercentage,
vaultDebt,
upperHint,
lowerHint,
[0, 0],
[0, 0],
],
}
// 4. Swap the borrowed LUSD for DAI
const lusdSwapDetails = await helpers.fetch1inchQuote(
LUSD_TOKEN_ADDRESS,
DAI_TOKEN_ADDRESS,
vaultDebt,
dsa.address
)
const swapLusdForDaiSpell = {
connector: "1INCH-A",
method: "sell",
args: [
DAI_TOKEN_ADDRESS,
LUSD_TOKEN_ADDRESS,
vaultDebt,
lusdSwapDetails.unitAmount,
lusdSwapDetails.calldata,
0,
],
}
// 5. Repay all the Maker vault DAI debt
const repayMakerDebtSpell = {
connector: "MAKERDAO-A",
method: "payback",
args: [
vaultId,
ethers.constants.MaxUint256,
0,
0,
],
}
// 6. Withdraw all the Maker vault ETH collateral
const withdrawMakerCollateralSpell = {
connector: "MAKERDAO-A",
method: "withdraw",
args: [
vaultId,
vaultCollateral,
0,
0,
],
}
// 7. Repay ETH flash loan
const paybackFlashLoanSpell = {
connector: "INSTAPOOL-A",
method: "flashPayback",
args: [ETH_ADDRESS, vaultCollateral, 0, 0],
}
const encodedMigrationSpells = helpers.encodeFlashcastData([
openTroveSpell,
swapLusdForDaiSpell,
repayMakerDebtSpell,
withdrawMakerCollateralSpell,
paybackFlashLoanSpell,
])
// 2. Flash loan ETH so we can open a Liquity Trove
// NB: This spell also holds all the other spells that need
// to be executed inside the flash loan
const flashloanWithSpells = [
{
connector: "INSTAPOOL-A",
method: "flashBorrowAndCast",
args: [
ETH_ADDRESS,
vaultCollateral,
0, // route 0 is an ETH flash loan
encodedMigrationSpells,
],
},
]
const spells = dsa.Spell()
spells.add(flashloanWithSpells)
await spells.cast() // Executes the recipe of spells on the user's DSA account
}