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  }