// SPDX-License-Identifier: agpl-3.0 pragma solidity ^0.6.8; import '@openzeppelin/contracts/math/SafeMath.sol'; import '@openzeppelin/contracts/token/ERC20/IERC20.sol'; import '../../flashloan/base/FlashLoanReceiverBase.sol'; import '../tokens/MintableERC20.sol'; import '../../libraries/UniversalERC20.sol'; contract MockFlashLoanReceiver is FlashLoanReceiverBase { using SafeMath for uint256; using UniversalERC20 for IERC20; event ExecutedWithFail(address _reserve, uint256 _amount, uint256 _fee); event ExecutedWithSuccess(address _reserve, uint256 _amount, uint256 _fee); bool failExecution = false; constructor(ILendingPoolAddressesProvider _provider) public FlashLoanReceiverBase(_provider) {} function setFailExecutionTransfer(bool _fail) public { failExecution = _fail; } function executeOperation( address _reserve, address _destination, uint256 _amount, uint256 _fee, bytes memory _params ) public override { //mint to this contract the specific amount MintableERC20 token = MintableERC20(_reserve); //check the contract has the specified balance require( _amount <= getBalanceInternal(address(this), _reserve), 'Invalid balance for the contract' ); if (failExecution) { emit ExecutedWithFail(_reserve, _amount, _fee); return; } //execution does not fail - mint tokens and return them to the _destination //note: if the reserve is eth, the mock contract must receive at least _fee ETH before calling executeOperation if (!IERC20(_reserve).isETH()) { token.mint(_fee); } //returning amount + fee to the destination transferFundsBackInternal(_reserve, _destination, _amount.add(_fee)); emit ExecutedWithSuccess(_reserve, _amount, _fee); } }