Skip to content

Instantly share code, notes, and snippets.

@DappaDanDev
Last active February 1, 2024 15:24
Show Gist options
  • Star 25 You must be signed in to star a gist
  • Fork 14 You must be signed in to fork a gist
  • Save DappaDanDev/3f4d8247b505f6226b0be04853696a50 to your computer and use it in GitHub Desktop.
Save DappaDanDev/3f4d8247b505f6226b0be04853696a50 to your computer and use it in GitHub Desktop.
Creating a Flash Loan using Aave
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);
}
}
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);
}
}
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;
}
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;
}
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);
}
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);
}
}
@aniket-bansode2311
Copy link

code needs to be updated.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment