github.com/cwntr/go-defi@v0.0.0-20210629134751-07f9ec2f7e66/contracts/handlers/aave/HAave.sol (about) 1 pragma solidity ^0.5.0; 2 pragma experimental ABIEncoderV2; 3 4 import "../HandlerBase.sol"; 5 import "./FlashLoanReceiverBase.sol"; 6 import "./ILendingPool.sol"; 7 import "./ILendingPoolCore.sol"; 8 import "./IAToken.sol"; 9 import "@openzeppelin/contracts/utils/Address.sol"; 10 import "@openzeppelin/contracts/math/SafeMath.sol"; 11 import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; 12 import "@openzeppelin/contracts/token/ERC20/SafeERC20.sol"; 13 14 15 interface IProxy { 16 function execs(address[] calldata tos, bytes[] calldata datas) external; 17 } 18 19 contract HAave is HandlerBase, FlashLoanReceiverBase { 20 using SafeERC20 for IERC20; 21 22 uint16 constant REFERRAL_CODE = 56; 23 24 function flashLoan( 25 address _reserve, 26 uint256 _amount, 27 bytes calldata _params 28 ) external payable { 29 ILendingPool lendingPool = ILendingPool( 30 ILendingPoolAddressesProvider(PROVIDER).getLendingPool() 31 ); 32 lendingPool.flashLoan(address(this), _reserve, _amount, _params); 33 34 // Update involved token 35 if (_reserve != ETHADDRESS) _updateToken(_reserve); 36 } 37 38 function executeOperation( 39 address _reserve, 40 uint256 _amount, 41 uint256 _fee, 42 bytes calldata _params 43 ) external payable { 44 (address[] memory tos, bytes[] memory datas) = abi.decode( 45 _params, 46 (address[], bytes[]) 47 ); 48 IProxy(address(this)).execs(tos, datas); 49 transferFundsBackToPoolInternal(_reserve, _amount.add(_fee)); 50 } 51 52 function deposit( 53 address _reserve, 54 uint256 _amount 55 ) external payable { 56 ILendingPool lendingPool = ILendingPool( 57 ILendingPoolAddressesProvider(PROVIDER).getLendingPool() 58 ); 59 60 if (_reserve == ETHADDRESS) { 61 lendingPool.deposit.value(_amount)(_reserve, _amount, REFERRAL_CODE); 62 } else { 63 address lendingPoolCore = ILendingPoolAddressesProvider(PROVIDER).getLendingPoolCore(); 64 IERC20(_reserve).safeApprove(lendingPoolCore, _amount); 65 lendingPool.deposit(_reserve, _amount, REFERRAL_CODE); 66 IERC20(_reserve).safeApprove(lendingPoolCore, 0); 67 } 68 69 address aToken = _getAToken(_reserve); 70 _updateToken(aToken); 71 } 72 73 function redeem( 74 address _aToken, 75 uint256 _amount 76 ) external payable { 77 IAToken(_aToken).redeem(_amount); 78 address underlyingAsset = IAToken(_aToken).underlyingAssetAddress(); 79 if (underlyingAsset != ETHADDRESS) _updateToken(underlyingAsset); 80 } 81 82 function _getAToken(address _reserve) internal view returns(address) { 83 ILendingPoolCore lendingPoolCore = ILendingPoolCore( 84 ILendingPoolAddressesProvider(PROVIDER).getLendingPoolCore() 85 ); 86 address aToken = lendingPoolCore.getReserveATokenAddress(_reserve); 87 require(aToken != address(0), "aToken should not be zero address"); 88 89 return aToken; 90 } 91 }