-
-
Save Franceshe/95ee68bdcb8f76bbfeccddfcfdc5e927 to your computer and use it in GitHub Desktop.
Creating a Flash Loan using Aave
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
pragma solidity ^0.6.6; | |
import "./FlashLoanReceiverBase.sol"; | |
import "./ILendingPoolAddressesProvider.sol"; | |
import "./ILendingPool.sol"; | |
contract Flashloan is FlashLoanReceiverBase { | |
constructor(address _addressProvider) FlashLoanReceiverBase(_addressProvider) public {} | |
/** | |
This function is called after your contract has received the flash loaned amount | |
*/ | |
function executeOperation( | |
address _reserve, | |
uint256 _amount, | |
uint256 _fee, | |
bytes calldata _params | |
) | |
external | |
override | |
{ | |
require(_amount <= getBalanceInternal(address(this), _reserve), "Invalid balance, was the flashLoan successful?"); | |
// | |
// Your logic goes here. | |
// !! Ensure that *this contract* has enough of `_reserve` funds to payback the `_fee` !! | |
// | |
uint totalDebt = _amount.add(_fee); | |
transferFundsBackToPoolInternal(_reserve, totalDebt); | |
} | |
/** | |
Flash loan 1000000000000000000 wei (1 ether) worth of `_asset` | |
*/ | |
function flashloan(address _asset) public onlyOwner { | |
bytes memory data = ""; | |
uint amount = 1 ether; | |
ILendingPool lendingPool = ILendingPool(addressesProvider.getLendingPool()); | |
lendingPool.flashLoan(address(this), _asset, amount, data); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
pragma solidity ^0.6.6; | |
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/docs-v3.x/contracts/math/SafeMath.sol"; | |
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/docs-v3.x/contracts/token/ERC20/IERC20.sol"; | |
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/docs-v3.x/contracts/token/ERC20/SafeERC20.sol"; | |
import "./IFlashLoanReceiver.sol"; | |
import "./ILendingPoolAddressesProvider.sol"; | |
import "./Withdrawable.sol"; | |
abstract contract FlashLoanReceiverBase is IFlashLoanReceiver, Withdrawable { | |
using SafeERC20 for IERC20; | |
using SafeMath for uint256; | |
address constant ethAddress = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE; | |
ILendingPoolAddressesProvider public addressesProvider; | |
constructor(address _addressProvider) public { | |
addressesProvider = ILendingPoolAddressesProvider(_addressProvider); | |
} | |
receive() payable external {} | |
function transferFundsBackToPoolInternal(address _reserve, uint256 _amount) internal { | |
address payable core = addressesProvider.getLendingPoolCore(); | |
transferInternal(core, _reserve, _amount); | |
} | |
function transferInternal(address payable _destination, address _reserve, uint256 _amount) internal { | |
if(_reserve == ethAddress) { | |
(bool success, ) = _destination.call{value: _amount}(""); | |
require(success == true, "Couldn't transfer ETH"); | |
return; | |
} | |
IERC20(_reserve).safeTransfer(_destination, _amount); | |
} | |
function getBalanceInternal(address _target, address _reserve) internal view returns(uint256) { | |
if(_reserve == ethAddress) { | |
return _target.balance; | |
} | |
return IERC20(_reserve).balanceOf(_target); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
pragma solidity ^0.6.6; | |
/** | |
* @title IFlashLoanReceiver interface | |
* @notice Interface for the Aave fee IFlashLoanReceiver. | |
* @author Aave | |
* @dev implement this interface to develop a flashloan-compatible flashLoanReceiver contract | |
**/ | |
interface IFlashLoanReceiver { | |
function executeOperation(address _reserve, uint256 _amount, uint256 _fee, bytes calldata _params) external; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
pragma solidity ^0.6.6; | |
interface ILendingPool { | |
function addressesProvider () external view returns ( address ); | |
function deposit ( address _reserve, uint256 _amount, uint16 _referralCode ) external payable; | |
function redeemUnderlying ( address _reserve, address _user, uint256 _amount ) external; | |
function borrow ( address _reserve, uint256 _amount, uint256 _interestRateMode, uint16 _referralCode ) external; | |
function repay ( address _reserve, uint256 _amount, address _onBehalfOf ) external payable; | |
function swapBorrowRateMode ( address _reserve ) external; | |
function rebalanceFixedBorrowRate ( address _reserve, address _user ) external; | |
function setUserUseReserveAsCollateral ( address _reserve, bool _useAsCollateral ) external; | |
function liquidationCall ( address _collateral, address _reserve, address _user, uint256 _purchaseAmount, bool _receiveAToken ) external payable; | |
function flashLoan ( address _receiver, address _reserve, uint256 _amount, bytes calldata _params ) external; | |
function getReserveConfigurationData ( address _reserve ) external view returns ( uint256 ltv, uint256 liquidationThreshold, uint256 liquidationDiscount, address interestRateStrategyAddress, bool usageAsCollateralEnabled, bool borrowingEnabled, bool fixedBorrowRateEnabled, bool isActive ); | |
function getReserveData ( address _reserve ) external view returns ( uint256 totalLiquidity, uint256 availableLiquidity, uint256 totalBorrowsFixed, uint256 totalBorrowsVariable, uint256 liquidityRate, uint256 variableBorrowRate, uint256 fixedBorrowRate, uint256 averageFixedBorrowRate, uint256 utilizationRate, uint256 liquidityIndex, uint256 variableBorrowIndex, address aTokenAddress, uint40 lastUpdateTimestamp ); | |
function getUserAccountData ( address _user ) external view returns ( uint256 totalLiquidityETH, uint256 totalCollateralETH, uint256 totalBorrowsETH, uint256 availableBorrowsETH, uint256 currentLiquidationThreshold, uint256 ltv, uint256 healthFactor ); | |
function getUserReserveData ( address _reserve, address _user ) external view returns ( uint256 currentATokenBalance, uint256 currentUnderlyingBalance, uint256 currentBorrowBalance, uint256 principalBorrowBalance, uint256 borrowRateMode, uint256 borrowRate, uint256 liquidityRate, uint256 originationFee, uint256 variableBorrowIndex, uint256 lastUpdateTimestamp, bool usageAsCollateralEnabled ); | |
function getReserves () external view; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
pragma solidity ^0.6.6; | |
/** | |
@title ILendingPoolAddressesProvider interface | |
@notice provides the interface to fetch the LendingPoolCore address | |
*/ | |
interface ILendingPoolAddressesProvider { | |
function getLendingPoolCore() external view returns (address payable); | |
function getLendingPool() external view returns (address); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
pragma solidity ^0.6.6 <= 0.9.0; | |
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/docs-v3.x/contracts/token/ERC20/ERC20.sol"; | |
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/docs-v3.x/contracts/token/ERC20/SafeERC20.sol"; | |
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/docs-v3.x/contracts/access/Ownable.sol"; | |
/** | |
Ensures that any contract that inherits from this contract is able to | |
withdraw funds that are accidentally received or stuck. | |
*/ | |
contract Withdrawable is Ownable { | |
using SafeERC20 for ERC20; | |
address constant ETHER = address(0); | |
event LogWithdraw( | |
address indexed _from, | |
address indexed _assetAddress, | |
uint amount | |
); | |
/** | |
* @dev Withdraw asset. | |
* @param _assetAddress Asset to be withdrawn. | |
*/ | |
function withdraw(address _assetAddress) public onlyOwner { | |
uint assetBalance; | |
if (_assetAddress == ETHER) { | |
address self = address(this); // workaround for a possible solidity bug | |
assetBalance = self.balance; | |
msg.sender.transfer(assetBalance); | |
} else { | |
assetBalance = ERC20(_assetAddress).balanceOf(address(this)); | |
ERC20(_assetAddress).safeTransfer(msg.sender, assetBalance); | |
} | |
emit LogWithdraw(msg.sender, _assetAddress, assetBalance); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment