mirror of
				https://github.com/Instadapp/aave-protocol-v2.git
				synced 2024-07-29 21:47:30 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			183 lines
		
	
	
		
			6.5 KiB
		
	
	
	
		
			Solidity
		
	
	
	
	
	
			
		
		
	
	
			183 lines
		
	
	
		
			6.5 KiB
		
	
	
	
		
			Solidity
		
	
	
	
	
	
| // SPDX-License-Identifier: agpl-3.0
 | |
| pragma solidity 0.6.12;
 | |
| pragma experimental ABIEncoderV2;
 | |
| 
 | |
| import {Ownable} from '../dependencies/openzeppelin/contracts/Ownable.sol';
 | |
| import {IERC20} from '../dependencies/openzeppelin/contracts/IERC20.sol';
 | |
| import {IWETH} from './interfaces/IWETH.sol';
 | |
| import {IWETHGateway} from './interfaces/IWETHGateway.sol';
 | |
| import {ILendingPool} from '../interfaces/ILendingPool.sol';
 | |
| import {IAToken} from '../interfaces/IAToken.sol';
 | |
| import {ReserveConfiguration} from '../protocol/libraries/configuration/ReserveConfiguration.sol';
 | |
| import {UserConfiguration} from '../protocol/libraries/configuration/UserConfiguration.sol';
 | |
| import {Helpers} from '../protocol/libraries/helpers/Helpers.sol';
 | |
| import {DataTypes} from '../protocol/libraries/types/DataTypes.sol';
 | |
| 
 | |
| contract WETHGateway is IWETHGateway, Ownable {
 | |
|   using ReserveConfiguration for DataTypes.ReserveConfigurationMap;
 | |
|   using UserConfiguration for DataTypes.UserConfigurationMap;
 | |
| 
 | |
|   IWETH internal immutable WETH;
 | |
|   ILendingPool internal immutable POOL;
 | |
|   IAToken internal immutable aWETH;
 | |
| 
 | |
|   /**
 | |
|    * @dev Sets the WETH address and the LendingPoolAddressesProvider address. Infinite approves lending pool.
 | |
|    * @param weth Address of the Wrapped Ether contract
 | |
|    * @param pool Address of the LendingPool contract
 | |
|    **/
 | |
|   constructor(address weth, address pool) public {
 | |
|     ILendingPool poolInstance = ILendingPool(pool);
 | |
|     WETH = IWETH(weth);
 | |
|     POOL = poolInstance;
 | |
|     aWETH = IAToken(poolInstance.getReserveData(weth).aTokenAddress);
 | |
|     IWETH(weth).approve(pool, uint256(-1));
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * @dev deposits WETH into the reserve, using native ETH. A corresponding amount of the overlying asset (aTokens)
 | |
|    * is minted.
 | |
|    * @param onBehalfOf address of the user who will receive the aTokens representing the deposit
 | |
|    * @param referralCode integrators are assigned a referral code and can potentially receive rewards.
 | |
|    **/
 | |
|   function depositETH(address onBehalfOf, uint16 referralCode) external payable override {
 | |
|     WETH.deposit{value: msg.value}();
 | |
|     POOL.deposit(address(WETH), msg.value, onBehalfOf, referralCode);
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * @dev withdraws the WETH _reserves of msg.sender.
 | |
|    * @param amount amount of aWETH to withdraw and receive native ETH
 | |
|    * @param to address of the user who will receive native ETH
 | |
|    */
 | |
|   function withdrawETH(uint256 amount, address to) external override {
 | |
|     uint256 userBalance = aWETH.balanceOf(msg.sender);
 | |
|     uint256 amountToWithdraw = amount;
 | |
| 
 | |
|     // if amount is equal to uint(-1), the user wants to redeem everything
 | |
|     if (amount == type(uint256).max) {
 | |
|       amountToWithdraw = userBalance;
 | |
|     }
 | |
|     aWETH.transferFrom(msg.sender, address(this), amountToWithdraw);
 | |
|     POOL.withdraw(address(WETH), amountToWithdraw, address(this));
 | |
|     WETH.withdraw(amountToWithdraw);
 | |
|     _safeTransferETH(to, amountToWithdraw);
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * @dev repays a borrow on the WETH reserve, for the specified amount (or for the whole amount, if uint256(-1) is specified).
 | |
|    * @param amount the amount to repay, or uint256(-1) if the user wants to repay everything
 | |
|    * @param rateMode the rate mode to repay
 | |
|    * @param onBehalfOf the address for which msg.sender is repaying
 | |
|    */
 | |
|   function repayETH(
 | |
|     uint256 amount,
 | |
|     uint256 rateMode,
 | |
|     address onBehalfOf
 | |
|   ) external payable override {
 | |
|     (uint256 stableDebt, uint256 variableDebt) =
 | |
|       Helpers.getUserCurrentDebtMemory(onBehalfOf, POOL.getReserveData(address(WETH)));
 | |
| 
 | |
|     uint256 paybackAmount =
 | |
|       DataTypes.InterestRateMode(rateMode) == DataTypes.InterestRateMode.STABLE
 | |
|         ? stableDebt
 | |
|         : variableDebt;
 | |
| 
 | |
|     if (amount < paybackAmount) {
 | |
|       paybackAmount = amount;
 | |
|     }
 | |
|     require(msg.value >= paybackAmount, 'msg.value is less than repayment amount');
 | |
|     WETH.deposit{value: paybackAmount}();
 | |
|     POOL.repay(address(WETH), msg.value, rateMode, onBehalfOf);
 | |
| 
 | |
|     // refund remaining dust eth
 | |
|     if (msg.value > paybackAmount) _safeTransferETH(msg.sender, msg.value - paybackAmount);
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * @dev borrow WETH, unwraps to ETH and send both the ETH and DebtTokens to msg.sender, via `approveDelegation` and onBehalf argument in `LendingPool.borrow`.
 | |
|    * @param amount the amount of ETH to borrow
 | |
|    * @param interesRateMode the interest rate mode
 | |
|    * @param referralCode integrators are assigned a referral code and can potentially receive rewards
 | |
|    */
 | |
|   function borrowETH(
 | |
|     uint256 amount,
 | |
|     uint256 interesRateMode,
 | |
|     uint16 referralCode
 | |
|   ) external override {
 | |
|     POOL.borrow(address(WETH), amount, interesRateMode, referralCode, msg.sender);
 | |
|     WETH.withdraw(amount);
 | |
|     _safeTransferETH(msg.sender, amount);
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * @dev transfer ETH to an address, revert if it fails.
 | |
|    * @param to recipient of the transfer
 | |
|    * @param value the amount to send
 | |
|    */
 | |
|   function _safeTransferETH(address to, uint256 value) internal {
 | |
|     (bool success, ) = to.call{value: value}(new bytes(0));
 | |
|     require(success, 'ETH_TRANSFER_FAILED');
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * @dev transfer ERC20 from the utility contract, for ERC20 recovery in case of stuck tokens due
 | |
|    * direct transfers to the contract address.
 | |
|    * @param token token to transfer
 | |
|    * @param to recipient of the transfer
 | |
|    * @param amount amount to send
 | |
|    */
 | |
|   function emergencyTokenTransfer(
 | |
|     address token,
 | |
|     address to,
 | |
|     uint256 amount
 | |
|   ) external onlyOwner {
 | |
|     IERC20(token).transfer(to, amount);
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * @dev transfer native Ether from the utility contract, for native Ether recovery in case of stuck Ether
 | |
|    * due selfdestructs or transfer ether to pre-computated contract address before deployment.
 | |
|    * @param to recipient of the transfer
 | |
|    * @param amount amount to send
 | |
|    */
 | |
|   function emergencyEtherTransfer(address to, uint256 amount) external onlyOwner {
 | |
|     _safeTransferETH(to, amount);
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * @dev Get WETH address used by WETHGateway
 | |
|    */
 | |
|   function getWETHAddress() external view returns (address) {
 | |
|     return address(WETH);
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * @dev Get aWETH address used by WETHGateway
 | |
|    */
 | |
|   function getAWETHAddress() external view returns (address) {
 | |
|     return address(aWETH);
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * @dev Get LendingPool address used by WETHGateway
 | |
|    */
 | |
|   function getLendingPoolAddress() external view returns (address) {
 | |
|     return address(POOL);
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * @dev Only WETH contract is allowed to transfer ETH here. Prevent other addresses to send Ether to this contract.
 | |
|    */
 | |
|   receive() external payable {
 | |
|     require(msg.sender == address(WETH), 'Receive not allowed');
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * @dev Revert fallback calls
 | |
|    */
 | |
|   fallback() external payable {
 | |
|     revert('Fallback not allowed');
 | |
|   }
 | |
| }
 | 
