Skip to content

Commit

Permalink
feat: add Aave V2 support
Browse files Browse the repository at this point in the history
  • Loading branch information
emilianobonassi committed Jan 3, 2021
1 parent fa91241 commit 8e1fa3b
Show file tree
Hide file tree
Showing 17 changed files with 944 additions and 121 deletions.
237 changes: 144 additions & 93 deletions README.md

Large diffs are not rendered by default.

12 changes: 6 additions & 6 deletions contracts/Flashloan.sol → contracts/v1/FlashloanV1.sol
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
pragma solidity ^0.6.6;

import "./aave/FlashLoanReceiverBase.sol";
import "../interfaces/ILendingPoolAddressesProvider.sol";
import "../interfaces/ILendingPool.sol";
import "./aave/FlashLoanReceiverBaseV1.sol";
import "../../interfaces/v1/ILendingPoolAddressesProviderV1.sol";
import "../../interfaces/v1/ILendingPoolV1.sol";

contract Flashloan is FlashLoanReceiverBase {
contract FlashloanV1 is FlashLoanReceiverBaseV1 {

constructor(address _addressProvider) FlashLoanReceiverBase(_addressProvider) public {}
constructor(address _addressProvider) FlashLoanReceiverBaseV1(_addressProvider) public {}

/**
This function is called after your contract has received the flash loaned amount
Expand Down Expand Up @@ -38,7 +38,7 @@ contract Flashloan is FlashLoanReceiverBase {
bytes memory data = "";
uint amount = 1 ether;

ILendingPool lendingPool = ILendingPool(addressesProvider.getLendingPool());
ILendingPoolV1 lendingPool = ILendingPoolV1(addressesProvider.getLendingPool());
lendingPool.flashLoan(address(this), _asset, amount, data);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,20 @@ pragma solidity ^0.6.6;
import "@openzeppelin/contracts/math/SafeMath.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/token/ERC20/SafeERC20.sol";
import "../../interfaces/IFlashLoanReceiver.sol";
import "../../interfaces/ILendingPoolAddressesProvider.sol";
import "../utils/Withdrawable.sol";
import "../../../interfaces/v1/IFlashLoanReceiverV1.sol";
import "../../../interfaces/v1/ILendingPoolAddressesProviderV1.sol";
import "../../utils/Withdrawable.sol";

abstract contract FlashLoanReceiverBase is IFlashLoanReceiver, Withdrawable {
abstract contract FlashLoanReceiverBaseV1 is IFlashLoanReceiverV1, Withdrawable {

using SafeERC20 for IERC20;
using SafeMath for uint256;

address constant ethAddress = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;
ILendingPoolAddressesProvider public addressesProvider;
ILendingPoolAddressesProviderV1 public addressesProvider;

constructor(address _addressProvider) public {
addressesProvider = ILendingPoolAddressesProvider(_addressProvider);
addressesProvider = ILendingPoolAddressesProviderV1(_addressProvider);
}

receive() payable external {}
Expand Down
99 changes: 99 additions & 0 deletions contracts/v2/FlashloanV2.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
pragma solidity ^0.6.6;

import "./aave/FlashLoanReceiverBaseV2.sol";
import "../../interfaces/v2/ILendingPoolAddressesProviderV2.sol";
import "../../interfaces/v2/ILendingPoolV2.sol";

contract FlashloanV2 is FlashLoanReceiverBaseV2, Withdrawable {

constructor(address _addressProvider) FlashLoanReceiverBaseV2(_addressProvider) public {}

/**
* @dev This function must be called only be the LENDING_POOL and takes care of repaying
* active debt positions, migrating collateral and incurring new V2 debt token debt.
*
* @param assets The array of flash loaned assets used to repay debts.
* @param amounts The array of flash loaned asset amounts used to repay debts.
* @param premiums The array of premiums incurred as additional debts.
* @param initiator The address that initiated the flash loan, unused.
* @param params The byte array containing, in this case, the arrays of aTokens and aTokenAmounts.
*/
function executeOperation(
address[] calldata assets,
uint256[] calldata amounts,
uint256[] calldata premiums,
address initiator,
bytes calldata params
)
external
override
returns (bool)
{

//
// This contract now has the funds requested.
// Your logic goes here.
//

// At the end of your logic above, this contract owes
// the flashloaned amounts + premiums.
// Therefore ensure your contract has enough to repay
// these amounts.

// Approve the LendingPool contract allowance to *pull* the owed amount
for (uint i = 0; i < assets.length; i++) {
uint amountOwing = amounts[i].add(premiums[i]);
IERC20(assets[i]).approve(address(LENDING_POOL), amountOwing);
}

return true;
}

function _flashloan(address[] memory assets, uint256[] memory amounts) internal {
address receiverAddress = address(this);

address onBehalfOf = address(this);
bytes memory params = "";
uint16 referralCode = 0;

uint256[] memory modes = new uint256[](assets.length);

// 0 = no debt (flash), 1 = stable, 2 = variable
for (uint256 i = 0; i < assets.length; i++) {
modes[i] = 0;
}

LENDING_POOL.flashLoan(
receiverAddress,
assets,
amounts,
modes,
onBehalfOf,
params,
referralCode
);
}

/*
* Flash multiple assets
*/
function flashloan(address[] memory assets, uint256[] memory amounts) public onlyOwner {
_flashloan(assets, amounts);
}

/*
* Flash loan 1000000000000000000 wei (1 ether) worth of `_asset`
*/
function flashloan(address _asset) public onlyOwner {
bytes memory data = "";
uint amount = 1 ether;

address[] memory assets = new address[](1);
assets[0] = _asset;

uint256[] memory amounts = new uint256[](1);
amounts[0] = amount;

_flashloan(assets, amounts);
}
}
31 changes: 31 additions & 0 deletions contracts/v2/aave/FlashLoanReceiverBaseV2.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// SPDX-License-Identifier: agpl-3.0
pragma solidity ^0.6.8;

import { SafeMath } from '@openzeppelin/contracts/math/SafeMath.sol';
import { IERC20 } from '@openzeppelin/contracts/token/ERC20/IERC20.sol';
import { SafeERC20 } from '@openzeppelin/contracts/token/ERC20/SafeERC20.sol';
import { IFlashLoanReceiverV2 } from './../../../interfaces/v2/IFlashLoanReceiverV2.sol';
import { ILendingPoolAddressesProviderV2 } from './../../../interfaces/v2/ILendingPoolAddressesProviderV2.sol';
import { ILendingPoolV2 } from './../../../interfaces/v2/ILendingPoolV2.sol';
import "../../utils/Withdrawable.sol";

/**
!!!
Never keep funds permanently on your FlashLoanReceiverBase contract as they could be
exposed to a 'griefing' attack, where the stored funds are used by an attacker.
!!!
*/
abstract contract FlashLoanReceiverBaseV2 is IFlashLoanReceiverV2 {
using SafeERC20 for IERC20;
using SafeMath for uint256;

ILendingPoolAddressesProviderV2 public immutable override ADDRESSES_PROVIDER;
ILendingPoolV2 public immutable override LENDING_POOL;

constructor(address provider) public {
ADDRESSES_PROVIDER = ILendingPoolAddressesProviderV2(provider);
LENDING_POOL = ILendingPoolV2(ILendingPoolAddressesProviderV2(provider).getLendingPool());
}

receive() payable external {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@ pragma solidity ^0.6.6;
* @author Aave
* @dev implement this interface to develop a flashloan-compatible flashLoanReceiver contract
**/
interface IFlashLoanReceiver {
interface IFlashLoanReceiverV1 {
function executeOperation(address _reserve, uint256 _amount, uint256 _fee, bytes calldata _params) external;
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ pragma solidity ^0.6.6;
@notice provides the interface to fetch the LendingPoolCore address
*/

interface ILendingPoolAddressesProvider {
interface ILendingPoolAddressesProviderV1 {
function getLendingPoolCore() external view returns (address payable);
function getLendingPool() external view returns (address);
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
pragma solidity ^0.6.6;

interface ILendingPool {
interface ILendingPoolV1 {
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;
Expand Down
25 changes: 25 additions & 0 deletions interfaces/v2/IFlashLoanReceiverV2.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// SPDX-License-Identifier: agpl-3.0
pragma solidity ^0.6.6;

import { ILendingPoolAddressesProviderV2 } from './ILendingPoolAddressesProviderV2.sol';
import { ILendingPoolV2 } from './ILendingPoolV2.sol';

/**
* @title IFlashLoanReceiverV2 interface
* @notice Interface for the Aave fee IFlashLoanReceiver.
* @author Aave
* @dev implement this interface to develop a flashloan-compatible flashLoanReceiver contract
**/
interface IFlashLoanReceiverV2 {
function executeOperation(
address[] calldata assets,
uint256[] calldata amounts,
uint256[] calldata premiums,
address initiator,
bytes calldata params
) external returns (bool);

function ADDRESSES_PROVIDER() external view returns (ILendingPoolAddressesProviderV2);

function LENDING_POOL() external view returns (ILendingPoolV2);
}
60 changes: 60 additions & 0 deletions interfaces/v2/ILendingPoolAddressesProviderV2.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// SPDX-License-Identifier: agpl-3.0
pragma solidity ^0.6.6;

/**
* @title LendingPoolAddressesProvider contract
* @dev Main registry of addresses part of or connected to the protocol, including permissioned roles
* - Acting also as factory of proxies and admin of those, so with right to change its implementations
* - Owned by the Aave Governance
* @author Aave
**/
interface ILendingPoolAddressesProviderV2 {
event MarketIdSet(string newMarketId);
event LendingPoolUpdated(address indexed newAddress);
event ConfigurationAdminUpdated(address indexed newAddress);
event EmergencyAdminUpdated(address indexed newAddress);
event LendingPoolConfiguratorUpdated(address indexed newAddress);
event LendingPoolCollateralManagerUpdated(address indexed newAddress);
event PriceOracleUpdated(address indexed newAddress);
event LendingRateOracleUpdated(address indexed newAddress);
event ProxyCreated(bytes32 id, address indexed newAddress);
event AddressSet(bytes32 id, address indexed newAddress, bool hasProxy);

function getMarketId() external view returns (string memory);

function setMarketId(string calldata marketId) external;

function setAddress(bytes32 id, address newAddress) external;

function setAddressAsProxy(bytes32 id, address impl) external;

function getAddress(bytes32 id) external view returns (address);

function getLendingPool() external view returns (address);

function setLendingPoolImpl(address pool) external;

function getLendingPoolConfigurator() external view returns (address);

function setLendingPoolConfiguratorImpl(address configurator) external;

function getLendingPoolCollateralManager() external view returns (address);

function setLendingPoolCollateralManager(address manager) external;

function getPoolAdmin() external view returns (address);

function setPoolAdmin(address admin) external;

function getEmergencyAdmin() external view returns (address);

function setEmergencyAdmin(address admin) external;

function getPriceOracle() external view returns (address);

function setPriceOracle(address priceOracle) external;

function getLendingRateOracle() external view returns (address);

function setLendingRateOracle(address lendingRateOracle) external;
}
Loading

0 comments on commit 8e1fa3b

Please sign in to comment.