Skip to content

Commit

Permalink
feat: pool & weth gateway update
Browse files Browse the repository at this point in the history
  • Loading branch information
0xmikko committed Mar 6, 2023
1 parent 8906053 commit 1274f63
Show file tree
Hide file tree
Showing 13 changed files with 1,105 additions and 848 deletions.
116 changes: 98 additions & 18 deletions contracts/core/WETHGateway.sol
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {AddressProvider} from "./AddressProvider.sol";
import {ContractsRegister} from "./ContractsRegister.sol";

import {IPoolService} from "../interfaces/IPoolService.sol";
import {IPool4626} from "../interfaces/IPool4626.sol";

import {IWETH} from "../interfaces/external/IWETH.sol";
import {IWETHGateway} from "../interfaces/IWETHGateway.sol";
Expand All @@ -23,27 +24,43 @@ contract WETHGateway is IWETHGateway {
using SafeERC20 for IERC20;
using Address for address payable;

address public immutable wethAddress;
ContractsRegister internal immutable _contractsRegister;
error RegisteredPoolsOnlyException();
error WethPoolsOnlyException();
error RegisteredCreditManagersOnly();
error ReceiveIsNotAllowedException();

// Contract version
uint256 public constant version = 1;
address public immutable weth;
ContractsRegister internal immutable cr;

event WithdrawETH(address indexed pool, address indexed to);
// Contract version
uint256 public constant version = 3_00;

/// @dev Checks that the pool is registered and the underlying token is WETH
modifier wethPoolOnly(address pool) {
require(_contractsRegister.isPool(pool), Errors.REGISTERED_POOLS_ONLY); // T:[WG-1]

require(IPoolService(pool).underlyingToken() == wethAddress, Errors.WG_DESTINATION_IS_NOT_WETH_COMPATIBLE); // T:[WG-2]
if (!cr.isPool(pool)) revert RegisteredPoolsOnlyException(); // T:[WG-1]
if (IPoolService(pool).underlyingToken() != weth) revert WethPoolsOnlyException(); // T:[WG-2]
_;
}

/// @dev Checks that credit manager is registered
modifier creditManagerOnly(address creditManager) {
require(_contractsRegister.isCreditManager(creditManager), Errors.REGISTERED_CREDIT_ACCOUNT_MANAGERS_ONLY); // T:[WG-3]
if (!cr.isCreditManager(creditManager)) revert RegisteredCreditManagersOnly(); // T:[WG-3]

_;
}

/// @dev Measures WETH balance before and after function call and transfers
/// difference to providced address
modifier unwrapAndTransferWethTo(address to) {
uint256 balanceBefore = IERC20(weth).balanceOf(address(this));

_;

uint256 diff = IERC20(weth).balanceOf(address(this)) - balanceBefore;

if (diff > 0) {
_unwrapWETH(to, diff);
}
}

//
Expand All @@ -54,10 +71,75 @@ contract WETHGateway is IWETHGateway {
/// @param addressProvider Address Repository for upgradable contract model
constructor(address addressProvider) {
require(addressProvider != address(0), Errors.ZERO_ADDRESS_IS_NOT_ALLOWED);
wethAddress = AddressProvider(addressProvider).getWethToken();
_contractsRegister = ContractsRegister(AddressProvider(addressProvider).getContractsRegister());
weth = AddressProvider(addressProvider).getWethToken();
cr = ContractsRegister(AddressProvider(addressProvider).getContractsRegister());
}

/// FOR POOLS V3

function deposit(address pool, address receiver)
external
payable
override
wethPoolOnly(pool)
returns (uint256 shares)
{
IWETH(weth).deposit{value: msg.value}();

_checkAllowance(pool, msg.value);
return IPool4626(pool).deposit(msg.value, receiver);
}

function depositReferral(address pool, address receiver, uint16 referralCode)
external
payable
override
wethPoolOnly(pool)
returns (uint256 shares)
{
IWETH(weth).deposit{value: msg.value}();

_checkAllowance(pool, msg.value);
return IPool4626(pool).depositReferral(msg.value, receiver, referralCode);
}

function mint(address pool, uint256 shares, address receiver)
external
payable
override
wethPoolOnly(pool)
unwrapAndTransferWethTo(msg.sender)
returns (uint256 assets)
{
IWETH(weth).deposit{value: msg.value}();

_checkAllowance(pool, msg.value);
assets = IPool4626(pool).mint(shares, receiver);
}

function withdraw(address pool, uint256 assets, address receiver, address owner)
external
override
wethPoolOnly(pool)
unwrapAndTransferWethTo(receiver)
returns (uint256 shares)
{
return IPool4626(pool).withdraw(assets, address(this), owner);
}

function redeem(address pool, uint256 shares, address receiver, address owner)
external
payable
override
wethPoolOnly(pool)
unwrapAndTransferWethTo(receiver)
returns (uint256 assets)
{
return IPool4626(pool).redeem(shares, address(this), owner);
}

/// FOR POOLS V1

/// @dev convert ETH to WETH and add liqudity to the pool
/// @param pool Address of PoolService contract to add liquidity to. This pool must have WETH as an underlying.
/// @param onBehalfOf The address that will receive the diesel token.
Expand All @@ -68,7 +150,7 @@ contract WETHGateway is IWETHGateway {
override
wethPoolOnly(pool) // T:[WG-1, 2]
{
IWETH(wethAddress).deposit{value: msg.value}(); // T:[WG-8]
IWETH(weth).deposit{value: msg.value}(); // T:[WG-8]

_checkAllowance(pool, msg.value); // T:[WG-8]
IPoolService(pool).addLiquidity(msg.value, onBehalfOf, referralCode); // T:[WG-8]
Expand All @@ -89,8 +171,6 @@ contract WETHGateway is IWETHGateway {

uint256 amountGet = IPoolService(pool).removeLiquidity(amount, address(this)); // T: [WG-9]
_unwrapWETH(to, amountGet); // T: [WG-9]

emit WithdrawETH(pool, to);
}

/// @dev Converts WETH to ETH, and sends to the passed address
Expand All @@ -106,21 +186,21 @@ contract WETHGateway is IWETHGateway {

/// @dev Internal implementation for unwrapETH
function _unwrapWETH(address to, uint256 amount) internal {
IWETH(wethAddress).withdraw(amount); // T: [WG-7]
IWETH(weth).withdraw(amount); // T: [WG-7]
payable(to).sendValue(amount); // T: [WG-7]
}

/// @dev Checks that the allowance is sufficient before a transaction, and sets to max if not
/// @param spender Account that would spend WETH
/// @param amount Amount to compare allowance with
function _checkAllowance(address spender, uint256 amount) internal {
if (IERC20(wethAddress).allowance(address(this), spender) < amount) {
IERC20(wethAddress).approve(spender, type(uint256).max);
if (IERC20(weth).allowance(address(this), spender) < amount) {
IERC20(weth).approve(spender, type(uint256).max);
}
}

/// @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(wethAddress), Errors.WG_RECEIVE_IS_NOT_ALLOWED); // T:[WG-6]
if (msg.sender != address(weth)) revert ReceiveIsNotAllowedException(); // T:[WG-6]
}
}
17 changes: 6 additions & 11 deletions contracts/interfaces/IPool4626.sol
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ interface IPool4626Exceptions {
error CreditManagerOnlyException();
error IncorrectWithdrawalFeeException();
error ZeroAssetsException();
error AssetIsNotWETHException();

error PoolQuotaKeeperOnly();
error IncompatibleCreditManagerException();
error CreditManagerNotRegsiterException();
error AdditionalYieldPoolException();
Expand All @@ -40,6 +41,9 @@ interface IPool4626Events {
/// @dev Emits on updating the interest rate model
event NewInterestRateModel(address indexed newInterestRateModel);

/// @dev Emits each time when new Pool Quota Manager updated
event NewPoolQuotaKeeper(address indexed newPoolQuotaKeeper);

/// @dev Emits on connecting a new Credit Manager
event NewCreditManagerConnected(address indexed creditManager);

Expand Down Expand Up @@ -67,12 +71,6 @@ interface IPool4626Events {
interface IPool4626 is IPool4626Events, IPool4626Exceptions, IERC4626, IVersion {
function depositReferral(uint256 assets, address receiver, uint16 referralCode) external returns (uint256 shares);

function depositETHReferral(address receiver, uint16 referralCode) external payable returns (uint256 shares);

function withdrawETH(uint256 assets, address receiver, address owner) external returns (uint256 shares);

function redeemETH(uint256 shares, address receiver, address owner) external returns (uint256 assets);

function burn(uint256 shares) external;

/// CREDIT MANAGERS FUNCTIONS
Expand Down Expand Up @@ -112,14 +110,11 @@ interface IPool4626 is IPool4626Events, IPool4626Exceptions, IERC4626, IVersion
function calcLinearCumulative_RAY() external view returns (uint256);

/// @dev Calculates the current borrow rate, RAY format
function borrowRate_RAY() external view returns (uint256);
function borrowRate() external view returns (uint256);

/// @dev Total borrowed amount (includes principal only)
function totalBorrowed() external view returns (uint256);

/// @dev diesel rate in RAY format
function getDieselRate_RAY() external view returns (uint256);

/// @dev Address of the underlying
function underlyingToken() external view returns (address);

Expand Down
21 changes: 21 additions & 0 deletions contracts/interfaces/IWETHGateway.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,27 @@
pragma solidity ^0.8.10;

interface IWETHGateway {
/// @dev POOL V3:
function deposit(address pool, address receiver) external payable returns (uint256 shares);

function depositReferral(address pool, address receiver, uint16 referralCode)
external
payable
returns (uint256 shares);

function mint(address pool, uint256 shares, address receiver) external payable returns (uint256 assets);

function withdraw(address pool, uint256 assets, address receiver, address owner)
external
returns (uint256 shares);

function redeem(address pool, uint256 shares, address receiver, address owner)
external
payable
returns (uint256 assets);

/// @dev POOL V1:

/// @dev Converts ETH to WETH and add liqudity to the pool
/// @param pool Address of PoolService contract to add liquidity to. This pool must have WETH as an underlying.
/// @param onBehalfOf The address that will receive the diesel token.
Expand Down
Loading

0 comments on commit 1274f63

Please sign in to comment.