Flash Loans

Overview

Curvance provides flash loan functionality through the BorrowableCToken contract, allowing developers to borrow assets without collateral for the duration of a single transaction. This guide walks you through implementing flash loans in your smart contracts.

Key Concepts

What is a Flash Loan?

A flash loan is an uncollateralized loan that must be borrowed and repaid within a single transaction. If the loan is not repaid (plus fees) by the end of the transaction, the entire transaction reverts.

Flash Loan Fee

  • Fee Rate: 4 basis points (0.04%)

  • Calculation: fee = (assets * 4) / 10000

  • The fee is added to the total assets in the market after the flash loan completes

Implementation Steps

Step 1: Implement the IFlashLoan Interface

Your contract must implement the onFlashloan() function to receive flash loan callbacks.

function onFlashLoan(
    uint256 assets,
    uint256 assetsReturned,
    bytes calldata data
) external returns (bytes32) {
    // Verify the callback is from the expected BorrowableCToken
    require(msg.sender == borrowableCToken, "Unauthorized callback");

    // Your custom logic here.
    // At this point, you have received 'assets' amount of tokens.

    // IMPORTANT: You must approve the BorrowableCToken to pull back
    // the loan amount + fee before this function returns.
    SafeTransferLib.safeApprove(asset, borrowableCToken, assetsReturned);

    // Return value (not currently checked by the BorrowableCToken contract).
    return keccak256("ERC3156FlashBorrower.onFlashLoan");
}

Step 2: Initiate the Flash Loan

Call the flashLoan() function on the BorrowableCToken contract.

function myFlashloanFunction() external {
    // Prepare any data you want to pass to the callback
    bytes memory data = abi.encode(msg.sender, someData);

    // Execute the flash loan
    // This will:
    // 1. Transfer 'amount' tokens to this contract
    // 2. Call onFlashLoan() on this contract
    // 3. Pull back 'amount + fee' tokens from this contract
    IBorrowableCToken(borrowableCToken).flashLoan(amount, data);
}

Flash Loan Execution Flow

  1. Your contract calls flashLoan(assets, data) .

  2. Fee is calculated fee = (assets * FLASHLOAN_FEE) / BPS.

  3. Assets are transferred to your contract.

  4. Your callback is executed.

  5. Assets + fee are pulled back into BorrowableCToken.

  6. Event Flashloan(assets, fee, msg.sender) is emitted.

Important Considerations

1. Available liquidity

Before initiating a flash loan, ensure sufficient assets are available:

uint256 availableLiquidity = IBorrowableCToken(borrowableCToken).assetsHeld();
require(loanAmount <= availableLiquidity, "Insufficient liquidity");

2. Fee Calculation

Always calculate the exact fee you'll need to repay:

uint256 fee = IBorrowableCToken(borrowableCToken).flashFee(loanAmount);
uint256 totalRepayment = loanAmount + fee;

3. Token Approval

Your contract must approve the BorrowableCToken to pull back the loan + fee:

IERC20.usdc.approve(borrowableCToken, assetsReturned);

If you fail to approve or don't have sufficient balance, the transaction will revert.

Error Handling

Error
Cause
Solution

BorrowableCToken__ZeroAmount

Requested amount is 0.

Request amount > 0.

BorrowableCToken_InsufficientAssetsHeld

Not enough liquidity.

Reduce loan amount or wait for more liquidity.

Transfer failure

Insufficient approval or balance.

Ensure proper approval and balance for repayment.

Last updated