-
Notifications
You must be signed in to change notification settings - Fork 10
/
WstEthHandler.sol
144 lines (129 loc) · 5.48 KB
/
WstEthHandler.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.21;
import { IonPool } from "../../IonPool.sol";
import { IonHandlerBase } from "./base/IonHandlerBase.sol";
import { GemJoin } from "../../join/GemJoin.sol";
import { UniswapFlashswapHandler } from "./base/UniswapFlashswapHandler.sol";
import { BalancerFlashloanDirectMintHandler } from "./base/BalancerFlashloanDirectMintHandler.sol";
import { IWstEth } from "../../interfaces/ProviderInterfaces.sol";
import { LidoLibrary } from "../../libraries/LidoLibrary.sol";
import { Whitelist } from "../../Whitelist.sol";
import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import { IUniswapV3Pool } from "@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol";
/**
* @notice Handler for the wstETH collateral.
*
* @custom:security-contact security@molecularlabs.io
*/
contract WstEthHandler is UniswapFlashswapHandler, BalancerFlashloanDirectMintHandler {
using LidoLibrary for IWstEth;
IERC20 constant STETH = IERC20(0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84);
/**
* @notice Creates a new `WstEthHandler` instance.
* @param _ilkIndex of wstETH.
* @param _ionPool `IonPool` contract address.
* @param _gemJoin `GemJoin` contract address associated with wstETH.
* @param _whitelist Address of the `Whitelist` contract.
* @param _wstEthUniswapPool Adderess of the wstETH/ETH Uniswap V3 pool.
*/
constructor(
uint8 _ilkIndex,
IonPool _ionPool,
GemJoin _gemJoin,
Whitelist _whitelist,
IUniswapV3Pool _wstEthUniswapPool
)
IonHandlerBase(_ilkIndex, _ionPool, _gemJoin, _whitelist)
UniswapFlashswapHandler(_wstEthUniswapPool, false)
{
// NOTE: approves wstETH contract infinite approval to move this contract's stEth
STETH.approve(address(LST_TOKEN), type(uint256).max);
}
/**
* @notice Unwraps weth into eth and deposits into lst contract.
* @dev Unwraps weth into eth and deposits into lst contract.
* @param amountWeth The WETH amount to deposit. [WAD]
* @return Amount of lst received. [WAD]
*/
function _depositWethForLst(uint256 amountWeth) internal override returns (uint256) {
WETH.withdraw(amountWeth);
return IWstEth(address(LST_TOKEN)).depositForLst(amountWeth);
}
/**
* @notice Calculates the amount of eth required to receive `amountLst`.
* @dev Calculates the amount of eth required to receive `amountLst`.
* @param amountLst Desired output amount. [WAD]
* @return Eth required for desired lst output. [WAD]
*/
function _getEthAmountInForLstAmountOut(uint256 amountLst) internal view override returns (uint256) {
return IWstEth(address(LST_TOKEN)).getEthAmountInForLstAmountOut(amountLst);
}
function zapDepositAndBorrow(
uint256 stEthAmount,
uint256 amountToBorrow,
bytes32[] memory proof
)
external
onlyWhitelistedBorrowers(proof)
{
STETH.transferFrom(msg.sender, address(this), stEthAmount);
uint256 outputWstEthAmount = IWstEth(address(LST_TOKEN)).wrap(stEthAmount);
_depositAndBorrow(msg.sender, msg.sender, outputWstEthAmount, amountToBorrow, AmountToBorrow.IS_MAX);
}
function zapFlashLeverageCollateral(
uint256 initialDeposit,
uint256 resultingAdditionalStEthCollateral,
uint256 maxResultingAdditionalDebt,
bytes32[] memory proof
)
external
onlyWhitelistedBorrowers(proof)
{
if (initialDeposit != 0) {
STETH.transferFrom(msg.sender, address(this), initialDeposit);
initialDeposit = IWstEth(address(LST_TOKEN)).wrap(initialDeposit);
}
uint256 resultingAdditionalWstEthCollateral =
IWstEth(address(LST_TOKEN)).getWstETHByStETH(resultingAdditionalStEthCollateral);
_flashLeverageCollateral(initialDeposit, resultingAdditionalWstEthCollateral, maxResultingAdditionalDebt);
}
function zapFlashLeverageWeth(
uint256 initialDeposit,
uint256 resultingAdditionalStEthCollateral,
uint256 maxResultingAdditionalDebt,
bytes32[] memory proof
)
external
onlyWhitelistedBorrowers(proof)
{
if (initialDeposit != 0) {
STETH.transferFrom(msg.sender, address(this), initialDeposit);
initialDeposit = IWstEth(address(LST_TOKEN)).wrap(initialDeposit);
}
uint256 resultingAdditionalWstEthCollateral =
IWstEth(address(LST_TOKEN)).getWstETHByStETH(resultingAdditionalStEthCollateral);
_flashLeverageWeth(initialDeposit, resultingAdditionalWstEthCollateral, maxResultingAdditionalDebt);
}
function zapFlashswapLeverage(
uint256 initialDeposit,
uint256 resultingAdditionalStEthCollateral,
uint256 maxResultingAdditionalDebt,
uint160 sqrtPriceLimitX96,
uint256 deadline,
bytes32[] memory proof
)
external
checkDeadline(deadline)
onlyWhitelistedBorrowers(proof)
{
if (initialDeposit != 0) {
STETH.transferFrom(msg.sender, address(this), initialDeposit);
initialDeposit = IWstEth(address(LST_TOKEN)).wrap(initialDeposit);
}
uint256 resultingAdditionalWstEthCollateral =
IWstEth(address(LST_TOKEN)).getWstETHByStETH(resultingAdditionalStEthCollateral);
_flashswapLeverage(
initialDeposit, resultingAdditionalWstEthCollateral, maxResultingAdditionalDebt, sqrtPriceLimitX96
);
}
}