Coder Social home page Coder Social logo

aave-debt-swap's Introduction

BGD labs <> Aave Debt Swap Adapter

This repository contains the ParaSwapDebtSwapAdapter, which aims to allow users to arbitrage borrow APY and exit illiquid debt positions. Therefore, this contract is able to swap one debt position to another debt position - either partially or completely.

You could for example swap your 1000 BUSD debt to max(1010 USDC) debt. In order to perform this task, swapDebt:

  1. Creates a flashLoan with variable debt mode with the target debt(1010 USDC) on behalf of the user
    • On aave v2 you need to approve the debtSwapAdapter for credit delegation
    • On aave v3 you can also pass a credit delegation permit
  2. It then swaps the flashed assets to the underlying of the current debt(1000 BUSD) via exact out swap (meaning it will receive 1000 BUSD, but might only need 1000.1 USDC for the swap)
  3. Repays the current debt (1000 BUSD)
  4. Uses potential (9.9 USDC) to repay parts of the newly created target debt

The user has now payed off his 1000 BUSD debt position, and created a new 1000.1 USDC debt position.

In situations where a user's real loan-to-value (LTV) is higher than their maximum LTV but lower than their liquidation threshold (LT), extra collateral is needed to "wrap" around the flashloan-and-swap outlined above. The flow would then look like this:

  1. Create a standard, repayable flashloan with the specified extra collateral asset and amount
  2. Supply the flashed collateral on behalf of the user
  3. Create the variable debt flashloan with the target debt(1010 USDC) on behalf of the user
  4. Swap the flashloaned target debt asset to the underlying of the current debt(1000 BUSD), needing only 1000.1 USDC
  5. Repay the current debt (1000 BUSD)
  6. Repay the flashloaned collateral asset and premium if needed (requires aToken approval)
  7. Use the remaining new debt asset (9.9 USDC) to repay parts of the newly created target debt

Notice how steps 3, 4, 5, and 7 are the same four steps from the collateral-less flow.

The guidelines for selecting a proper extra collateral asset are as follows:

For Aave V3:

  1. Ensure that the potential asset's LTV is nonzero.
  2. Ensure that the potential asset's LT is nonzero.
  3. Ensure that the potential asset's Supply Cap has sufficient capacity.
  4. If the user is in isolation mode, ensure the asset is the same as the isolated collateral asset.

For Aave V2:

  1. Ensure that the potential asset's LTV is nonzero.
  2. Ensure that the potential asset's LT is nonzero.
  3. Ensure that the extra collateral asset is the same as the new debt asset.
  4. Ensure that the collateral flashloan premium is added to the newDebtAmount.

When possible, for both V2 and V3 deployments, use the from/to debt asset in order to reduce cold storage access costs and save gas.

The recommended formula to determine the minimum amount of extra collateral is derived below:

USER_TOTAL_BORROW / (USER_OLD_COLLATERAL * OLD_COLLATERAL_LTV + EXTRA_COLLATERAL * EXTRA_COLLATERAL_ltv) = 1

USER_OLD_COLLATERAL * OLD_COLLATERAL_LTV + EXTRA_COLLATERAL * EXTRA_COLLATERAL_LTV = USER_TOTAL_BORROW

Therefore:

EXTRA_COLLATERAL = USER_TOTAL_BORROW * EXTRA_COLLATERAL_LTV / (USER_OLD_COLLATERAL * OLD_COLLATERAL_LTV)

We recommend a margin to account for interest accrual and health factor fluctuation until execution.

The function swapDebt(DebtSwapParams memory debtSwapParams, CreditDelegationInput memory creditDelegationPermit, PermitInput memory collateralATokenPermit) expects three parameters.

The first one describes the swap:

struct DebtSwapParams {
  address debtAsset; // the asset you want to swap away from
  uint256 debtRepayAmount; // the amount of debt you want to eliminate
  uint256 debtRateMode; // the type of debt (1 for stable, 2 for variable)
  address newDebtAsset; // the asset you want to swap to
  uint256 maxNewDebtAmount; // the max amount of debt your're willing to receive in excahnge for repaying debtRepayAmount
  address extraCollateralAsset; // The asset to flash and add as collateral if needed
  uint256 extraCollateralAmount; // The amount of `extraCollateralAsset` to flash and supply momentarily
  bytes paraswapData; // encoded exactOut swap
}

The second one describes the (optional) creditDelegation permit:

struct CreditDelegationInput {
  ICreditDelegationToken debtToken;
  uint256 value;
  uint256 deadline;
  uint8 v;
  bytes32 r;
  bytes32 s;
}

The third one describes the (optional) collateral aToken permit:

struct PermitInput {
  IERC20WithPermit aToken;
  uint256 value;
  uint256 deadline;
  uint8 v;
  bytes32 r;
  bytes32 s;
}

For usage examples please check the tests.

Security

  • This contract is a extra layer on top of BaseParaswapBuyAdapter which is used in production for ParaSwapRepayAdapter. It uses the exact same mechanism for exact out swap.

  • In contrast to ParaSwapRepayAdapter the ParaSwapDebtSwapAdapter will always repay on the pool on behalf of the user. So instead of having approvals per transaction the adapter will approve type(uint256).max once to reduce gas consumption.

  • The Aave POOL is considered a trustable entity for allowance purposes.

  • The contract only interact with msg.sender and therefore ensures isolation between users.

  • The contract is not upgradable.

  • The contract is ownable and will be owned by governance, so the governance will be the only entity able to call tokenRescue.

  • The approach with credit delegation and borrow-mode flashLoans is very similar to what is done on V2-V3 Migration helper

  • The contract inherits the security and limitations of Aave v2/v3. The contract itself does not validate for frozen/inactive reserves and also does not consider isolation/eMode or borrowCaps. It is the responsibility of the interface integrating this contract to correctly handle all user position compositions and pool configurations.

  • The contract implements an upper bound of 30% price impact, which would revert any swap. The slippage has to be properly configured in incorporated into the DebtSwapParams.maxNewDebt parameter.

Install

This repo has forge and npm dependencies, so you will need to install foundry then run:

forge install

and also run:

yarn

Tests

To run the tests just run:

forge test

References

This code is based on the existing aave paraswap adapters for v3.

The BaseParaSwapAdapter.sol was slightly adjusted to receive the POOL via constructor instead of fetching it.

This makes the code agnostic for v2 and v3, as the only methods used are unchanged between the two versions.

aave-debt-swap's People

Contributors

sakulstra avatar zer0dot avatar eboadom avatar kyzia551 avatar brotherlymite avatar

Stargazers

 avatar

Watchers

 avatar  avatar

Forkers

aave

aave-debt-swap's Issues

allow swaps below ltv requirements

Currently you cannot swap when your ltv is fully utilized.

This can potentially be worked around by:

  • flashing some collateral
  • supplying
  • do the swap
  • withdraw again

better events

Currently the events emitted from the contract are suboptimal.
All the swap adapters emit Bought(BUY order) or Swapped(SELL order).
While this can be used to infer what happened, it would be good to have an exact event also including the potential swap fees etc.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.