LCOV - code coverage report
Current view: top level - helpers - WrappedTokenGatewayV3.sol (source / functions) Coverage Total Hit
Test: lcov.info.p Lines: 90.2 % 41 37
Test Date: 2024-09-24 09:34:24 Functions: 100.0 % 10 10
Branches: - 0 0

             Branch data     Line data    Source code
       1                 :             : // SPDX-License-Identifier: BUSL-1.1
       2                 :             : pragma solidity ^0.8.10;
       3                 :             : 
       4                 :             : import {Ownable} from '../dependencies/openzeppelin/contracts/Ownable.sol';
       5                 :             : import {IERC20} from '../dependencies/openzeppelin/contracts/IERC20.sol';
       6                 :             : import {GPv2SafeERC20} from '../dependencies/gnosis/contracts/GPv2SafeERC20.sol';
       7                 :             : import {IWETH} from './interfaces/IWETH.sol';
       8                 :             : import {IPool} from '../interfaces/IPool.sol';
       9                 :             : import {IAToken} from '../interfaces/IAToken.sol';
      10                 :             : import {ReserveConfiguration} from '../protocol/libraries/configuration/ReserveConfiguration.sol';
      11                 :             : import {UserConfiguration} from '../protocol/libraries/configuration/UserConfiguration.sol';
      12                 :             : import {DataTypes} from '../protocol/libraries/types/DataTypes.sol';
      13                 :             : import {IWrappedTokenGatewayV3} from './interfaces/IWrappedTokenGatewayV3.sol';
      14                 :             : 
      15                 :             : /**
      16                 :             :  * @dev This contract is an upgrade of the WrappedTokenGatewayV3 contract, with immutable pool address.
      17                 :             :  * This contract keeps the same interface of the deprecated WrappedTokenGatewayV3 contract.
      18                 :             :  */
      19                 :             : contract WrappedTokenGatewayV3 is IWrappedTokenGatewayV3, Ownable {
      20                 :             :   using ReserveConfiguration for DataTypes.ReserveConfigurationMap;
      21                 :             :   using UserConfiguration for DataTypes.UserConfigurationMap;
      22                 :             :   using GPv2SafeERC20 for IERC20;
      23                 :             : 
      24                 :             :   IWETH internal immutable WETH;
      25                 :             :   IPool internal immutable POOL;
      26                 :             : 
      27                 :             :   /**
      28                 :             :    * @dev Sets the WETH address and the PoolAddressesProvider address. Infinite approves pool.
      29                 :             :    * @param weth Address of the Wrapped Ether contract
      30                 :             :    * @param owner Address of the owner of this contract
      31                 :             :    **/
      32                 :             :   constructor(address weth, address owner, IPool pool) {
      33                 :           0 :     WETH = IWETH(weth);
      34                 :           0 :     POOL = pool;
      35                 :           0 :     transferOwnership(owner);
      36                 :           0 :     IWETH(weth).approve(address(pool), type(uint256).max);
      37                 :             :   }
      38                 :             : 
      39                 :             :   /**
      40                 :             :    * @dev deposits WETH into the reserve, using native ETH. A corresponding amount of the overlying asset (aTokens)
      41                 :             :    * is minted.
      42                 :             :    * @param onBehalfOf address of the user who will receive the aTokens representing the deposit
      43                 :             :    * @param referralCode integrators are assigned a referral code and can potentially receive rewards.
      44                 :             :    **/
      45                 :             :   function depositETH(address, address onBehalfOf, uint16 referralCode) external payable override {
      46                 :           8 :     WETH.deposit{value: msg.value}();
      47                 :           8 :     POOL.deposit(address(WETH), msg.value, onBehalfOf, referralCode);
      48                 :             :   }
      49                 :             : 
      50                 :             :   /**
      51                 :             :    * @dev withdraws the WETH _reserves of msg.sender.
      52                 :             :    * @param amount amount of aWETH to withdraw and receive native ETH
      53                 :             :    * @param to address of the user who will receive native ETH
      54                 :             :    */
      55                 :             :   function withdrawETH(address, uint256 amount, address to) external override {
      56                 :           2 :     IAToken aWETH = IAToken(POOL.getReserveData(address(WETH)).aTokenAddress);
      57                 :           2 :     uint256 userBalance = aWETH.balanceOf(msg.sender);
      58                 :           2 :     uint256 amountToWithdraw = amount;
      59                 :             : 
      60                 :             :     // if amount is equal to uint(-1), the user wants to redeem everything
      61                 :           2 :     if (amount == type(uint256).max) {
      62                 :           1 :       amountToWithdraw = userBalance;
      63                 :             :     }
      64                 :           2 :     aWETH.transferFrom(msg.sender, address(this), amountToWithdraw);
      65                 :           2 :     POOL.withdraw(address(WETH), amountToWithdraw, address(this));
      66                 :           2 :     WETH.withdraw(amountToWithdraw);
      67                 :           2 :     _safeTransferETH(to, amountToWithdraw);
      68                 :             :   }
      69                 :             : 
      70                 :             :   /**
      71                 :             :    * @dev repays a borrow on the WETH reserve, for the specified amount (or for the whole amount, if uint256(-1) is specified).
      72                 :             :    * @param amount the amount to repay, or uint256(-1) if the user wants to repay everything
      73                 :             :    * @param onBehalfOf the address for which msg.sender is repaying
      74                 :             :    */
      75                 :             :   function repayETH(address, uint256 amount, address onBehalfOf) external payable override {
      76                 :           5 :     uint256 paybackAmount = IERC20((POOL.getReserveData(address(WETH))).variableDebtTokenAddress)
      77                 :             :       .balanceOf(onBehalfOf);
      78                 :             : 
      79                 :           5 :     if (amount < paybackAmount) {
      80                 :           2 :       paybackAmount = amount;
      81                 :             :     }
      82                 :           5 :     require(msg.value >= paybackAmount, 'msg.value is less than repayment amount');
      83                 :           5 :     WETH.deposit{value: paybackAmount}();
      84                 :           5 :     POOL.repay(
      85                 :             :       address(WETH),
      86                 :             :       paybackAmount,
      87                 :             :       uint256(DataTypes.InterestRateMode.VARIABLE),
      88                 :             :       onBehalfOf
      89                 :             :     );
      90                 :             : 
      91                 :             :     // refund remaining dust eth
      92                 :           5 :     if (msg.value > paybackAmount) _safeTransferETH(msg.sender, msg.value - paybackAmount);
      93                 :             :   }
      94                 :             : 
      95                 :             :   /**
      96                 :             :    * @dev borrow WETH, unwraps to ETH and send both the ETH and DebtTokens to msg.sender, via `approveDelegation` and onBehalf argument in `Pool.borrow`.
      97                 :             :    * @param amount the amount of ETH to borrow
      98                 :             :    * @param referralCode integrators are assigned a referral code and can potentially receive rewards
      99                 :             :    */
     100                 :             :   function borrowETH(address, uint256 amount, uint16 referralCode) external override {
     101                 :           1 :     POOL.borrow(
     102                 :             :       address(WETH),
     103                 :             :       amount,
     104                 :             :       uint256(DataTypes.InterestRateMode.VARIABLE),
     105                 :             :       referralCode,
     106                 :             :       msg.sender
     107                 :             :     );
     108                 :           1 :     WETH.withdraw(amount);
     109                 :           1 :     _safeTransferETH(msg.sender, amount);
     110                 :             :   }
     111                 :             : 
     112                 :             :   /**
     113                 :             :    * @dev withdraws the WETH _reserves of msg.sender.
     114                 :             :    * @param amount amount of aWETH to withdraw and receive native ETH
     115                 :             :    * @param to address of the user who will receive native ETH
     116                 :             :    * @param deadline validity deadline of permit and so depositWithPermit signature
     117                 :             :    * @param permitV V parameter of ERC712 permit sig
     118                 :             :    * @param permitR R parameter of ERC712 permit sig
     119                 :             :    * @param permitS S parameter of ERC712 permit sig
     120                 :             :    */
     121                 :             :   function withdrawETHWithPermit(
     122                 :             :     address,
     123                 :             :     uint256 amount,
     124                 :             :     address to,
     125                 :             :     uint256 deadline,
     126                 :             :     uint8 permitV,
     127                 :             :     bytes32 permitR,
     128                 :             :     bytes32 permitS
     129                 :             :   ) external override {
     130                 :           2 :     IAToken aWETH = IAToken(POOL.getReserveData(address(WETH)).aTokenAddress);
     131                 :           2 :     uint256 userBalance = aWETH.balanceOf(msg.sender);
     132                 :           2 :     uint256 amountToWithdraw = amount;
     133                 :             : 
     134                 :             :     // if amount is equal to type(uint256).max, the user wants to redeem everything
     135                 :           2 :     if (amount == type(uint256).max) {
     136                 :           1 :       amountToWithdraw = userBalance;
     137                 :             :     }
     138                 :             :     // permit `amount` rather than `amountToWithdraw` to make it easier for front-ends and integrators
     139                 :           2 :     aWETH.permit(msg.sender, address(this), amount, deadline, permitV, permitR, permitS);
     140                 :           2 :     aWETH.transferFrom(msg.sender, address(this), amountToWithdraw);
     141                 :           2 :     POOL.withdraw(address(WETH), amountToWithdraw, address(this));
     142                 :           2 :     WETH.withdraw(amountToWithdraw);
     143                 :           2 :     _safeTransferETH(to, amountToWithdraw);
     144                 :             :   }
     145                 :             : 
     146                 :             :   /**
     147                 :             :    * @dev transfer ETH to an address, revert if it fails.
     148                 :             :    * @param to recipient of the transfer
     149                 :             :    * @param value the amount to send
     150                 :             :    */
     151                 :             :   function _safeTransferETH(address to, uint256 value) internal {
     152                 :           7 :     (bool success, ) = to.call{value: value}(new bytes(0));
     153                 :           7 :     require(success, 'ETH_TRANSFER_FAILED');
     154                 :             :   }
     155                 :             : 
     156                 :             :   /**
     157                 :             :    * @dev transfer ERC20 from the utility contract, for ERC20 recovery in case of stuck tokens due
     158                 :             :    * direct transfers to the contract address.
     159                 :             :    * @param token token to transfer
     160                 :             :    * @param to recipient of the transfer
     161                 :             :    * @param amount amount to send
     162                 :             :    */
     163                 :             :   function emergencyTokenTransfer(address token, address to, uint256 amount) external onlyOwner {
     164                 :           1 :     IERC20(token).safeTransfer(to, amount);
     165                 :             :   }
     166                 :             : 
     167                 :             :   /**
     168                 :             :    * @dev transfer native Ether from the utility contract, for native Ether recovery in case of stuck Ether
     169                 :             :    * due to selfdestructs or ether transfers to the pre-computed contract address before deployment.
     170                 :             :    * @param to recipient of the transfer
     171                 :             :    * @param amount amount to send
     172                 :             :    */
     173                 :             :   function emergencyEtherTransfer(address to, uint256 amount) external onlyOwner {
     174                 :           1 :     _safeTransferETH(to, amount);
     175                 :             :   }
     176                 :             : 
     177                 :             :   /**
     178                 :             :    * @dev Get WETH address used by WrappedTokenGatewayV3
     179                 :             :    */
     180                 :             :   function getWETHAddress() external view returns (address) {
     181                 :           1 :     return address(WETH);
     182                 :             :   }
     183                 :             : 
     184                 :             :   /**
     185                 :             :    * @dev Only WETH contract is allowed to transfer ETH here. Prevent other addresses to send Ether to this contract.
     186                 :             :    */
     187                 :             :   receive() external payable {
     188                 :             :     require(msg.sender == address(WETH), 'Receive not allowed');
     189                 :             :   }
     190                 :             : 
     191                 :             :   /**
     192                 :             :    * @dev Revert fallback calls
     193                 :             :    */
     194                 :             :   fallback() external payable {
     195                 :           2 :     revert('Fallback not allowed');
     196                 :             :   }
     197                 :             : }
        

Generated by: LCOV version 2.1-1