Credit Delegation

Native Credit Delegation (CD) is a new feature in Aave v2. It allows a depositor to deposit funds in the protocol to earn interest, and delegate borrowing power (i.e. their credit) to other users. The enforcement of the loan and its terms are agreed upon between the depositor and borrowers, which can be either off-chain via legal agreements or on-chain via smart contracts.

This enables:

  • The depositor (delegator) to earn extra yield on top of the yield they already earn from the protocol,

  • The borrowers (delegatees) to access an uncollateralized loan.

Follow the below steps to create your first Credit Delegation.

TL;DR: A starter example contract can be found on Kovan etherscan and Github code examples repo, with a twitter discussion here.

In the following guide, we refer to borrower and delegatee. However credit delegation allows the delegation to multiple users, so it can also be read as borrowers and delegatees.

Approving the delegation

The approveDelegation() method must be called by the depositor (delegator), approving the borrower (delegatee) a certain amount.

This is done for each debt token that needs to be delegated.

The depositor (delegator) does not need to already have deposited funds in the protocol to approveDelegation(). However, before the borrower (delegatee) executes borrow(), there must be sufficient collateral assigned to the depositor (delegator) in the protocol.

// Import relevant interfaces
import './IAaveProtocolDataProvider.sol';
import './IDebtToken.sol';

// ... beginning of your contract. Constructors etc...

// Within a relevant function in your contract:

    // Get the Protocol Data Provider
    IAaveProtocolDataProvider provider = IAaveProtocolDataProvider(address(INSERT_DATA_PROVIDER_ADDRESS));
  
    // Get the relevant debt token address
    (, address stableDebtTokenAddress, address variableDebtTokenAddress) = provider.getReserveTokensAddresses(INSERT_ASSET_ADDRESS);

    // Relevant details for credit delegation
    address borrower = address(INSERT_BORROWER_ADDRESS);
    uint256 amountInWei = INSERT_DELEGATED_AMOUNT;
    
    // For stable debt tokens
    IDebtToken(stableDebtTokenAddress).approveDelegation(borrower, amountInWei);
    
    // For variable debt tokens
    IDebtToken(variableDebtTokenAddress).approveDelegation(borrower, amountInWei);

Borrowing the credit

The borrower (delegatee) calls the borrow() method on the LendingPool, using the depositor's (delegator's) address in final parameter onBehalfOf.

The borrower's available credit is reduced by the borrowed amount.

// Import relevant interfaces
import './IAddressesProvider.sol';
import './ILendingPool.sol';

// ... beginning of your contract. Constructors etc...

// Within a relevant function in your contract:

    // Get the latest LendingPool contract for the relevant market
    IAddressesProvider provider = IAddressesProvider(address(INSERT_ADDRESSES_PROVIDER_ADDRESS));
    ILendingPool lendingPool = ILendingPool(provider.getLendingPool());
    
    // Borrow the relevant amount
    address assetToBorrow = address(INSERT_ASSET_ADDRESS); // E.g. the address for Dai
    uint256 amountToBorrowInWei = INSERT_AMOUNT; // must be equal to or less than the amount delegated to the borrower
    uint256 interestRateMode = INSERT_INTEREST_RATE_MODE; // must be of the same type as the debt token that is delegated. I.e. stable = 1, variable = 2.
    uint16 referralCode = INSERT_REFERRAL_CODE;
    address delegatorAddress = INSERT_DELEGATOR_ADDRESS;
    
    lendingPool.borrow(assetToBorrow, amountToBorrowInWei, interestRateMode, referralCode, delegatorAddress);
    

Repaying the credit

The borrower (delegatee) can also call repay() at anytime to repay their uncollateralized loan, passing in the depositor's (delegator's) address as the final parameter onBehalfOf.

There is no change to the borrower's available credit after repayment.

// Import relevant interfaces
import './IAddressesProvider.sol';
import './ILendingPool.sol';
import './IERC20.sol';

// ... beginning of your contract. Constructors etc...

// Within a relevant function in your contract:

// Get the latest LendingPool contract for the relevant market
IAddressesProvider provider = IAddressesProvider(address(INSERT_ADDRESSES_PROVIDER_ADDRESS));
ILendingPool lendingPool = ILendingPool(provider.getLendingPool());

// Approve the asset to be repaid  
address assetToRepay = address(INSERT_ASSET_ADDRESS); // E.g. the address for Dai
uint256 amountToRepayInWei = INSERT_AMOUNT; // must be equal to or less than the amount delegated to the borrower

IERC20(assetToRepay).approve(address(lendingPool), amounToRepayInWei);

// Repay the relevant amount
uint256 interestRateMode = INSERT_INTEREST_RATE_MODE; // must be of the same type as the debt token that is delegated. I.e. stable = 1, variable = 2.
address delegatorAddress = INSERT_DELEGATOR_ADDRESS;

lendingPool.repay(assetToRepay, amountToRepayInWei, interestRateMode, delegatorAddress);
    

Increasing the credit delegation

To increase or decrease a borrower's available credit, the approveDelegation() method should be called again. This sets that new amount available to borrow on top of (not including) outstanding borrows.

This is done for each debt token that requires a modification.

// Import relevant interfaces
import './IAaveProtocolDataProvider.sol';
import './IDebtToken.sol';

// ... beginning of your contract. Constructors etc...

// Within a relevant function in your contract:

    // Get the Protocol Data Provider
    IAaveProtocolDataProvider provider = IAaveProtocolDataProvider(address(INSERT_DATA_PROVIDER_ADDRESS));
  
    // Get the relevant debt token address
    (, address stableDebtTokenAddress, address variableDebtTokenAddress) = provider.getReserveTokensAddresses(INSERT_ASSET_ADDRESS);

    // Relevant details for credit delegation
    address borrower = address(INSERT_BORROWER_ADDRESS);
    uint256 amountInWei = INSERT_DELEGATED_AMOUNT; // This is the total amount to be delegated (not just the increase)
    
    // For stable debt tokens
    IDebtToken(stableDebtTokenAddress).approveDelegation(borrower, amountInWei);
    
    // For variable debt tokens
    IDebtToken(variableDebtTokenAddress).approveDelegation(borrower, amountInWei);

Checking the amount delegated

To check the current allowance of a user, simply call borrowAllowance() passing in the depositor (delegator) and borrower (delegatee) addresses.

This is done for each debt token that is delegated.

// Import relevant interfaces
import './IAaveProtocolDataProvider.sol';
import './IDebtToken.sol';

// ... beginning of your contract. Constructors etc...

// Within a relevant function in your contract:

    // Get the Protocol Data Provider
    IAaveProtocolDataProvider provider = IAaveProtocolDataProvider(address(INSERT_DATA_PROVIDER_ADDRESS));
  
    // Get the relevant debt token address
    (, address stableDebtTokenAddress, address variableDebtTokenAddress) = provider.getReserveTokensAddresses(INSERT_ASSET_ADDRESS);

    // Relevant details for credit delegation
    address delegator = address(INSERT_DEPOSITOR_ADDRESS)
    address delegatee = address(INSERT_BORROWER_ADDRESS);
    
    // For stable debt tokens
    uint256 stableAllowance = IDebtToken(stableDebtTokenAddress).borrowAllowance(delegator, delegatee);
    
    // For variable debt tokens
    uint256 variableAllowance = IDebtToken(variableDebtTokenAddress).borrowAllowance(delegator, delegatee);

Last updated