Seamlessly Migrate Collateral, Debt & aLEND from Aave V1 to Aave V2 (Unofficial)
DISCLAIMER: This code is unaudited. The Aave genesis team is working on their own migration tool, and it’s almost certainly going to be orders of magnitude better than mine. Only use my tool if you are technical enough to look at and understand the code. I tried to make it as difficult as possible to mess up, but I cannot offer any guarantees. It is also good practice to always check and revoke unused allowances using a tool like this. Use the Migrator at your own risk. See the code, deployments and instructions here.
Having spent most of my time recently focused on learning solidity & DeFi building blocks, I’ve decided to build my own version of a migrator for Aave V1 positions to Aave V2.
This allowed me to learn a whole lot about the architecture of Aave V2! I highly recommend anyone interested in building atop of the protocol to really dig deep into their Github.
Moving forward, I previously noticed that Instadapp had released their own migrator, but if I recall it migrates directly into an Instadapp smart wallet.
This was awesome to see pop up so fast! However, I don’t have an Instadapp smart wallet and I didn’t really want to create one. So, I built the tool to migrate without a smart wallet on my own.
How Does It Work?
In a nutshell, the contract “replaces” your debts with debt-bearing flash loans, redeems your V1 aTokens and deposits them into V2 on your behalf.
This process is only made possible because of a few innovative Aave V2 features:
- Native credit delegation
- Debt-bearing flash loans
- Deposits on behalf of another address
Let’s talk about each of these and why I believe they are vastly underappreciated.
Native Credit Delegation
In Aave V2, debt is tokenized. In other words, upon taking a loan, the debt-bearing address is minted “debt tokens.” These can represent either stable or variable debt, and largely present the same end user experience as Aave V1 debt.
However, one of the more interesting features brought along with the tokenization of debt, aside from great gas optimizations, is the ability to natively delegate individual credit allowances. Each debt token has a function that allows any address to easily delegate credit to an address of their choice, so that address may borrow on behalf of the delegator. This results in the delegatee receiving the actual currency, and the delegator receiving the debt tokens.
There’s not a single doubt on my mind that this feature will be a strong building block for new DeFi products, such as perhaps a DAO to DAO lending system (who knows?).
Furthermore, this feature allows for the seamless migration of V1 debt to V2 debt because credit on debt tokens can be delegated regardless of the current collateralization or state of the account. This ties in nicely to the next point…
Debt-Bearing Flash Loans
Flash loans are still extremely new tech, and yet here we have yet another fantastic innovation! In addition to the more widely-recognized use cases of the new batch flash loan feature, Aave V2 introduces a new type of protocol-specific flash loans: debt-bearing flash loans.
These are essentially regular flash loans, except instead of having to pay back the debt, the account now accumulates that debt and premium in the form of newly-minted debt tokens.
Use cases for this beyond debt migration probably haven’t been thought of just yet, but keep in mind that you’re able to flash loan the funds to one contract and incur the debt on another address.
Deposits on Behalf of Another Address
In Aave V2, the standard deposit function allows users to send their newly minted aTokens to an address of their choice. This shortens the process of having to deposit the tokens, then transfer the aTokens to another address.
Furthermore, this also allows for (work in progress) a seamless implementation of an optional withdrawal of aTokens using a simple proxy for Aave V2 and “batch depositing” (i.e. Payroll) set amounts to different addresses. (Also WIP!)
How It All Comes Together
This is where I’ll be explaining how all of these features come together in the Migrator contract.
As is shown in the instructions on Github, there are a few basic steps that need to be taken before migration can take place, this section assumes those steps are taken.
So, the migration process is fairly simple and can be summed up in 5 steps:
- Obtain the appropriate balances of aTokens and debt reserve to migrate.
- If there is debt, repay it using a debt-bearing flash loan on behalf of the caller.
- Transfer out the caller’s aTokens.
- Redeem the transferred out aTokens.
- Deposit the token reserves into V2 aTokens on behalf of the caller.
That’s it! This is the entire process undergone by the Migrator contract, not too complex right?
Now with that out of the way, I want to go over a few lessons I’ve learned that might help other aspiring DeFi developers to use Aave V2 flash loans…
To keep things simple, I’ve created a list of bullet points that might prove useful when developing with Aave V2 flash loans:
- Empty flash loans can be called. This allows any contract to call “executeOperation” with any encoded data on your contract through the V2 lendingPool.
- Debt-bearing flash loans incur the debt at the end of the flash loan. Allowing aTokens to be moved around as needed without worrying about collateralization mid-flash loan.
- As stated before, debt-bearing flash loans incur the premiums as additional debt. You don’t need to transfer in the premiums from the caller in this case.
- Slightly unrelated, but when testing on a forked network, ensure you set your timeouts correctly!
- If you run into numbered errors, check out the Errors library on the Aave V2 Github here.
That about wraps up the Migrator contract, I hope this article serves you well in your flash loan adventures! Additionally, if you’re more experienced and have any feedback, I’m always looking to learn. You can check out the code, instructions and deployed contracts here.
Remember, migrate at your own risk!
- Aave V2 Github
- Aave V2 Errors Contract
- Contract on Etherscan (Ensure you know what you’re doing!)
- Contract repo on Github
- Kovan contract on Etherscan (note: There are some asset mismatches between V1 and V2 assets, the WBTC in V1 for instance is different from the WBTC in V2)
- Demo mainnet transaction (with unreasonably small amounts) ETH deposit & DAI borrow