🔗
SoftLink
WebsiteGithubMediumTwitter
  • Welcome
  • GETTING STARTED
    • White Paper
    • Overview
    • Quick Links
  • PROTOCOL
    • Reserves
    • Lending
    • Flash Loans
    • Gas-Free Flash Loans
    • Cross Chain
    • Fee Distribution
    • CFR Distribution
    • Staking
    • Locking
    • Governance
    • Looking Forward
  • DEVELOPERS
    • Addresses
    • Contracts
      • CoreReserveFactory
      • CoreReserve
      • LendingYieldManagers (LYM)
        • AaveLYM
        • CompoundLYM
        • EulerLYM
        • IronBankLYM
      • CoreFlashLoanParams
      • CoreFlashLoanReceiver
      • CoreRewardsDistributor
      • CoreStakingManager
      • CoreLockManager
      • SOFT
    • Interfaces
      • IFlashLoanReceiver
      • ILendingYieldManager
  • SUPPORT
    • Contact Us
Powered by GitBook
On this page
  1. PROTOCOL

Flash Loans

SoftLink Flash Loans V0

API Design

Each deployed reserve contains the following two accessible functions for performing flash loans:

struct FlashLoanParams {
    address receiver;
    uint256 amount;
    bytes params;
}

// NOTE: Can only be executed on reserves configured to manage currencies native to the network (ETH, FTM, NEAR, SOL, etc.)
function flashLoanETH(FlashLoanParams calldata params) public returns (bool)

// NOTE: Can only be executed on reserves configured to manage ERC20 tokens (DAI, AAVE, COMP, ETH/DAI, etc.)
function flashLoanERC20(FlashLoanParams calldata params) public returns (bool)

The following is an example of how one can design a simple smart contract to perform a flash loan on the protocol:

pragma solidity ^0.8.10;

import "./CoreReserve.sol";
import "./CoreFlashLoanReceiver.sol";
import "./dependencies/openzeppelin/SafeMath.sol";

contract MockCoreFlashLoanReceiver is CoreFlashLoanReceiver {
    using SafeMath for uint256;

    constructor() {}

    function executeOperation(
        address _reserve,
        uint256 _amount,
        uint256 _fee,
        bytes calldata _params
    ) external returns (bool) {
        // Perform any logic with the loan
        (bool success, ) = address(0).call(_params);
        require(success, "Strategy failed.");

        // Return the funds + amount fee
        (, , bool isNativeTokenReserve, address reserveToken) = CoreReserve(
            payable(_reserve)
        ).reserveData();

        transferInternal(
            payable(_reserve),
            reserveToken,
            isNativeTokenReserve,
            _amount.add(_fee)
        );

        return true;
    }

    function tI(
        address payable _reserve,
        address _reserveToken,
        bool _isNativeReserve,
        uint256 _amount
    ) public {
        transferInternal(_reserve, _reserveToken, _isNativeReserve, _amount);
    }

    function gBI(
        address payable _reserve,
        address _reserveToken,
        bool _isNativeReserve
    ) public view returns (uint256) {
        return getBalanceInternal(_reserve, _reserveToken, _isNativeReserve);
    }
}

// Option 1: Create a new core flash loan receiver to perform the flash loan
MockCoreFlashLoanReceiver mockCoreFlashLoanReceiver = new MockCoreFlashLoanReceiver();

// Option 2: Attach to an existing receiver on the network
IFlashLoanReceiver mockCoreFlashLoanReceiver = IFlashLoanReceiver(0x123...);

// NOTE: Initial deposits will most likely be handled on the UI
uint256 initialDeposit = 333 ether;
initialETHSnipingReserve.deposit{value: initialDeposit}(
    initialDeposit,
    address(mockCoreFlashLoanReceiver)
);

// Execute the flash loan
uint256 loanAmount = 22 ether;
initialETHSnipingReserve.flashLoanETH(
    CoreReserve.FlashLoanParams({
        receiver: address(mockCoreFlashLoanReceiver),
        amount: loanAmount,
        params: bytes("")
    })
);
PreviousLendingNextGas-Free Flash Loans

Last updated 2 years ago