Address
0x85a0914fd8a08d85d2d64a10d4179657c7d4cd17Current Holdings
$0.00
TXs sent
not counted
First Active
2023-05-17
block 17,286,388
Last Active
1,104 days ago
block 18,262,609
Net worth historyi
3 snapshots · to block 27,539,724coverage change 26 Augcoverage change 27 Augcoverage change 27 Augcoverage change 27 Augcoverage change 27 Aug
exact matchWETHGatewaysolc 0.7.6+commit.7338295fruntime exact · creation exact
// SPDX-License-Identifier: agpl-3.0
pragma solidity 0.7.6;
pragma experimental ABIEncoderV2;
import {Ownable} from "../dependencies/openzeppelin/contracts/Ownable.sol";
import {SafeERC20} from "../dependencies/openzeppelin/contracts/SafeERC20.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;
using SafeERC20 for IERC20;
IWETH internal immutable WETH;
/**
* @dev Sets the WETH address and the LendingPoolAddressesProvider address. Infinite approves lending pool.
* @param weth Address of the Wrapped Ether contract
**/
constructor(address weth) {
WETH = IWETH(weth);
}
function authorizeLendingPool(address lendingPool) external onlyOwner {
WETH.approve(lendingPool, uint256(-1));
}
/**
* @dev deposits WETH into the reserve, using native ETH. A corresponding amount of the overlying asset (aTokens)
* is minted.
* @param lendingPool address of the targeted underlying lending pool
* @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 lendingPool,
address onBehalfOf,
uint16 referralCode
) external payable override {
WETH.deposit{value: msg.value}();
ILendingPool(lendingPool).deposit(
address(WETH),
msg.value,
onBehalfOf,
referralCode
);
}
/**
* @dev withdraws the WETH _reserves of msg.sender.
* @param lendingPool address of the targeted underlying lending pool
* @param amount amount of aWETH to withdraw and receive native ETH
* @param to address of the user who will receive native ETH
*/
function withdrawETH(
address lendingPool,
uint256 amount,
address to
) external override {
IAToken aWETH = IAToken(
ILendingPool(lendingPool)
.getReserveData(address(WETH))
.aTokenAddress
);
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;
}
IERC20(aWETH).safeTransferFrom(
msg.sender,
address(this),
amountToWithdraw
);
ILendingPool(lendingPool).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 lendingPool address of the targeted underlying lending pool
* @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(
address lendingPool,
uint256 amount,
uint256 rateMode,
address onBehalfOf
) external payable override {
(uint256 stableDebt, uint256 variableDebt) = Helpers
.getUserCurrentDebtMemory(
onBehalfOf,
ILendingPool(lendingPool).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}();
ILendingPool(lendingPool).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 lendingPool address of the targeted underlying lending pool
* @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(
address lendingPool,
uint256 amount,
uint256 interesRateMode,
uint16 referralCode
) external override {
ILendingPool(lendingPool).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).safeTransfer(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 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");
}
}