Links

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("")
})
);