Borrowing from XycLoans

To borrow a flash loan from a xycLoan's pool, you first need to select the pool you want to borrow from.

Selecting the right pool

All xycLoans pool have a fixed fee of 0.08% so the pool fee is not a deciding factor, rather, you have to choose the pool to borrow from given:

  • Pool asset. You can either rely on a verified pool where you can see the asset from the webapp, or manually check the pool's associated token contract (kept in contract instance with key TokenId).

  • Pool supply. You have to choose a pool with supply >= amount_to_borrow.

Writing the Receiver contract

Next up is writing your receiver contract. The receiver contract contains the logic of your borrow. For instance, if you're using flash loans for liquidations the receiver contract contains the liquidation logic.

When writing a receiver contract you can either write a erc3156 receiver contract (recommended) or a simple receiver contract.

Writing a receiver contract is pretty straightforward. You have a exec_op method that is called by the flash loan contract and:

  1. Make sure to require the correct authorizations. We recommend always requiring the authorization for the flash loan pool, and depending on your logic also the auth of a receiver contract admin (the loan initiator).

  2. Write your borrow logic (cdp actions, arbitrage, etc).

  3. Re-pay the loan + fee, which is done through the standard token's approve method.

Invoking the flash loan pool

Once you have deployed your receiver contract, you can call the xycLoan's pool borrow functionality:

pub trait FlashLoanModErc3156 {
    /// The entry point for executing a flash loan, the initiator (or borrower) provides:
    /// `receiver_id: Address` The address of the receiver contract which contains the borrowing logic.
    /// `amount` Amount of `token_id` to borrow (`token_id` is set when the contract is initialized).
    fn borrow_erc(e: Env, initiator: Address, receiver_id: Address, amount: i128) -> Result<(), Error>;
}

pub trait FlashLoan {
    /// The entry point for executing a flash loan, the initiator (or borrower) provides:
    /// `receiver_id: Address` The address of the receiver contract which contains the borrowing logic.
    /// `amount` Amount of `token_id` to borrow (`token_id` is set when the contract is initialized).
    fn borrow(e: Env, receiver_id: Address, amount: i128) -> Result<(), Error>;
}

Depending on the receiver contract you've built, you can either call borrow_erc or borrow.

Understanding Errors

A successful flash loan execution should return void, however, if you're seeing an error returned there are some common causes:

  1. Insufficient fees/resources. Make sure that the fee calculation and resource declaration from your RPC are valid for the current network state.

  2. Error within your receiver contract logic.

  3. Contract error. This propagates the pool's errors, within the borrow functionality can either be of status 4 (when the loan + fee wasn't repaid within the execution) or status 6 (borrow amount = 0).

Last updated