-
Notifications
You must be signed in to change notification settings - Fork 98
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
draft steth pricer #439
draft steth pricer #439
Changes from all commits
1d6ae7a
1cdcc3b
b139efe
ab3531e
58f20f3
c644960
2a2910a
81cad09
26426a8
2c41406
d205b42
eb63a23
0ab9163
a7ee3c8
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity 0.6.10; | ||
|
||
interface STETHInterface { | ||
function name() external view returns (string memory); | ||
|
||
function symbol() external view returns (string memory); | ||
|
||
function decimals() external view returns (uint8); | ||
|
||
function getPooledEthByShares(uint256 sharesAmount) external view returns (uint256); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
// SPDX-License-Identifier: UNLICENSED | ||
pragma solidity 0.6.10; | ||
|
||
import {ERC20Upgradeable} from "../packages/oz/upgradeability/ERC20Upgradeable.sol"; | ||
|
||
contract MockSTETHToken is ERC20Upgradeable { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is a mock for stETH, but we need a wstETH token, which has doesn't have getPooledEthByShares. |
||
mapping(uint256 => uint256) public getPooledEthByShares; | ||
|
||
constructor(string memory _name, string memory _symbol) public { | ||
__ERC20_init_unchained(_name, _symbol); | ||
_setupDecimals(18); | ||
} | ||
|
||
function mint(address account, uint256 amount) public { | ||
_mint(account, amount); | ||
} | ||
|
||
function setPooledEthByShares(uint256 _pooledEthByShares) external { | ||
getPooledEthByShares[1 ether] = _pooledEthByShares; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
// SPDX-License-Identifier: UNLICENSED | ||
pragma solidity 0.6.10; | ||
|
||
import {OracleInterface} from "../interfaces/OracleInterface.sol"; | ||
import {OpynPricerInterface} from "../interfaces/OpynPricerInterface.sol"; | ||
import {STETHInterface} from "../interfaces/STETHInterface.sol"; | ||
import {ERC20Interface} from "../interfaces/ERC20Interface.sol"; | ||
import {SafeMath} from "../packages/oz/SafeMath.sol"; | ||
|
||
/** | ||
* @notice A Pricer contract for a Yearn yToken | ||
*/ | ||
contract STETHPricer is OpynPricerInterface { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we should probably call it WSTETHPricer as it is pricing wstETH collateral. |
||
using SafeMath for uint256; | ||
|
||
/// @notice opyn oracle address | ||
OracleInterface public oracle; | ||
|
||
/// @notice stETH token | ||
STETHInterface public stETH; | ||
|
||
/// @notice underlying asset for this yToken | ||
ERC20Interface public underlying; | ||
|
||
/** | ||
* @param _stETH stETH | ||
* @param _underlying underlying asset for stETH | ||
* @param _oracle Opyn Oracle contract address | ||
*/ | ||
constructor( | ||
address _stETH, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Throughout, I think should change to wstETH to make it clear we are collateralizing with wstETH. |
||
address _underlying, | ||
address _oracle | ||
) public { | ||
require(_stETH != address(0), "STETHPricer: stETH address can not be 0"); | ||
require(_underlying != address(0), "STETHPricer: underlying address can not be 0"); | ||
require(_oracle != address(0), "STETHPricer: oracle address can not be 0"); | ||
|
||
stETH = STETHInterface(_stETH); | ||
underlying = ERC20Interface(_underlying); | ||
oracle = OracleInterface(_oracle); | ||
} | ||
|
||
/** | ||
* @notice get the live price for the asset | ||
* @dev overrides the getPrice function in OpynPricerInterface | ||
* @return price of 1e18 stETH in USD, scaled by 1e18 | ||
*/ | ||
function getPrice() external view override returns (uint256) { | ||
uint256 underlyingPrice = oracle.getPrice(address(underlying)); | ||
require(underlyingPrice > 0, "STETHPricer: underlying price is 0"); | ||
return _underlyingPriceToSTETHPrice(underlyingPrice); | ||
} | ||
|
||
/** | ||
* @notice set the expiry price in the oracle | ||
* @dev requires that the underlying price has been set before setting a stETH price | ||
* @param _expiryTimestamp expiry to set a price for | ||
*/ | ||
function setExpiryPriceInOracle(uint256 _expiryTimestamp) external { | ||
(uint256 underlyingPriceExpiry, ) = oracle.getExpiryPrice(address(underlying), _expiryTimestamp); | ||
require(underlyingPriceExpiry > 0, "STETHPricer: underlying price not set yet"); | ||
uint256 stETHPrice = _underlyingPriceToSTETHPrice(underlyingPriceExpiry); | ||
oracle.setExpiryPrice(address(stETH), _expiryTimestamp, stETHPrice); | ||
} | ||
|
||
/** | ||
* @dev convert underlying price to stETH price with the stETH to underlying exchange rate | ||
* @param _underlyingPrice price of 1 underlying token (ie 1e18 WETH) in USD, scaled by 1e8 | ||
* @return price of 1e8 stETH in USD, scaled by 1e8 | ||
*/ | ||
function _underlyingPriceToSTETHPrice(uint256 _underlyingPrice) private view returns (uint256) { | ||
uint256 pricePerShare = stETH.getPooledEthByShares(1 ether); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Here we can use |
||
uint8 underlyingDecimals = underlying.decimals(); | ||
|
||
return pricePerShare.mul(_underlyingPrice).div(10**uint256(underlyingDecimals)); | ||
} | ||
|
||
function getHistoricalPrice(uint80 _roundId) external view override returns (uint256, uint256) { | ||
revert("STETHPricer: Deprecated"); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need to use the wstETH interface here, which doesn't include getPooledEthByShares.