-
Notifications
You must be signed in to change notification settings - Fork 168
Price feeds for WETH deployment + Bulker changes for OZ audit #625
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
Merged
Merged
Changes from all commits
Commits
Show all changes
17 commits
Select commit
Hold shift + click to select a range
d1a3b0e
Implement scaling price feed
kevincheng96 daa7949
Update wstETH price feed to return prices in terms of ETH as well
kevincheng96 de9fdab
Change price feed address in deploy
kevincheng96 fad6572
Add constant price feed
kevincheng96 6da6ef1
Add constant price feed to deploy script
kevincheng96 0672517
Style changes to remove shadowing variables
kevincheng96 d280f30
Other stylistic changes; remove extra IWstETH interface
kevincheng96 d175adb
Add more docstrings
kevincheng96 4ebe1f8
Add cbETH scaling price feed to deploy script
kevincheng96 61bc2ee
Fix flaky scenario and support negative token amounts in constraints
kevincheng96 cd1fdce
Add constantPrice as a constructor arg
kevincheng96 2c67c8d
Add decimals as a constructor arg to wstETH price feed
kevincheng96 a01908b
Fix deployment manager to allow bigint deploy args
kevincheng96 e7e00e6
Define IPriceFeed interface for wrapper price feeds
kevincheng96 12a3a20
Use IPriceFeed in Comet
kevincheng96 6de3f12
Update cbETH / ETH price feed address in deploy script
kevincheng96 72cfa51
wstETHPriceFeed and BaseBulker stylistic changes (#634)
kevincheng96 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
// SPDX-License-Identifier: BUSL-1.1 | ||
pragma solidity 0.8.15; | ||
|
||
import "./IPriceFeed.sol"; | ||
|
||
contract ConstantPriceFeed is IPriceFeed { | ||
/// @notice Version of the price feed | ||
uint public constant override version = 1; | ||
|
||
/// @notice Description of the price feed | ||
string public constant description = "Constant price feed"; | ||
|
||
/// @notice Number of decimals for returned prices | ||
uint8 public immutable override decimals; | ||
|
||
/// @notice The constant price | ||
int public immutable constantPrice; | ||
|
||
/** | ||
* @notice Construct a new scaling price feed | ||
* @param decimals_ The number of decimals for the returned prices | ||
**/ | ||
constructor(uint8 decimals_, int256 constantPrice_) { | ||
decimals = decimals_; | ||
constantPrice = constantPrice_; | ||
} | ||
|
||
/** | ||
* @notice Price for the latest round | ||
* @return roundId Round id from the underlying price feed | ||
* @return answer Latest price for the asset (will always be a constant price) | ||
* @return startedAt Timestamp when the round was started; passed on from underlying price feed | ||
* @return updatedAt Timestamp when the round was last updated; passed on from underlying price feed | ||
* @return answeredInRound Round id in which the answer was computed; passed on from underlying price feed | ||
**/ | ||
function latestRoundData() external view returns ( | ||
uint80 roundId, | ||
int256 answer, | ||
uint256 startedAt, | ||
uint256 updatedAt, | ||
uint80 answeredInRound | ||
) { | ||
return (0, constantPrice, block.timestamp, block.timestamp, 0); | ||
} | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
// SPDX-License-Identifier: BUSL-1.1 | ||
pragma solidity 0.8.15; | ||
|
||
/** | ||
* @title IERC20NonStandard | ||
* @dev Version of ERC20 with no return values for `transfer` and `transferFrom` | ||
* See https://medium.com/coinmonks/missing-return-value-bug-at-least-130-tokens-affected-d67bf08521ca | ||
*/ | ||
interface IERC20NonStandard { | ||
function approve(address spender, uint256 amount) external; | ||
function transfer(address to, uint256 value) external; | ||
function transferFrom(address from, address to, uint256 value) external; | ||
function balanceOf(address account) external view returns (uint256); | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
// SPDX-License-Identifier: BUSL-1.1 | ||
pragma solidity 0.8.15; | ||
|
||
/** | ||
* @dev Interface for price feeds used by Comet | ||
* Note This is Chainlink's AggregatorV3Interface, but without the `getRoundData` function. | ||
*/ | ||
interface IPriceFeed { | ||
function decimals() external view returns (uint8); | ||
|
||
function description() external view returns (string memory); | ||
|
||
function version() external view returns (uint256); | ||
|
||
function latestRoundData() | ||
external | ||
view | ||
returns ( | ||
uint80 roundId, | ||
int256 answer, | ||
uint256 startedAt, | ||
uint256 updatedAt, | ||
uint80 answeredInRound | ||
); | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
// SPDX-License-Identifier: BUSL-1.1 | ||
pragma solidity 0.8.15; | ||
|
||
import "./vendor/@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol"; | ||
import "./IPriceFeed.sol"; | ||
|
||
contract ScalingPriceFeed is IPriceFeed { | ||
/** Custom errors **/ | ||
error InvalidInt256(); | ||
|
||
/// @notice Version of the price feed | ||
uint public constant override version = 1; | ||
|
||
/// @notice Description of the price feed | ||
string public description; | ||
|
||
/// @notice Number of decimals for returned prices | ||
uint8 public immutable override decimals; | ||
|
||
/// @notice Underlying Chainlink price feed where prices are fetched from | ||
address public immutable underlyingPriceFeed; | ||
|
||
/// @notice Whether or not the price should be upscaled | ||
bool internal immutable shouldUpscale; | ||
|
||
/// @notice The amount to upscale or downscale the price by | ||
int256 internal immutable rescaleFactor; | ||
|
||
/** | ||
* @notice Construct a new scaling price feed | ||
* @param underlyingPriceFeed_ The address of the underlying price feed to fetch prices from | ||
* @param decimals_ The number of decimals for the returned prices | ||
**/ | ||
constructor(address underlyingPriceFeed_, uint8 decimals_) { | ||
underlyingPriceFeed = underlyingPriceFeed_; | ||
decimals = decimals_; | ||
description = AggregatorV3Interface(underlyingPriceFeed_).description(); | ||
|
||
uint8 chainlinkPriceFeedDecimals = AggregatorV3Interface(underlyingPriceFeed_).decimals(); | ||
// Note: Solidity does not allow setting immutables in if/else statements | ||
shouldUpscale = chainlinkPriceFeedDecimals < decimals_ ? true : false; | ||
rescaleFactor = (shouldUpscale | ||
? signed256(10 ** (decimals_ - chainlinkPriceFeedDecimals)) | ||
: signed256(10 ** (chainlinkPriceFeedDecimals - decimals_)) | ||
); | ||
} | ||
|
||
/** | ||
* @notice Price for the latest round | ||
* @return roundId Round id from the underlying price feed | ||
* @return answer Latest price for the asset in terms of ETH | ||
* @return startedAt Timestamp when the round was started; passed on from underlying price feed | ||
* @return updatedAt Timestamp when the round was last updated; passed on from underlying price feed | ||
* @return answeredInRound Round id in which the answer was computed; passed on from underlying price feed | ||
**/ | ||
function latestRoundData() override external view returns ( | ||
uint80 roundId, | ||
int256 answer, | ||
uint256 startedAt, | ||
uint256 updatedAt, | ||
uint80 answeredInRound | ||
) { | ||
(uint80 roundId_, int256 price, uint256 startedAt_, uint256 updatedAt_, uint80 answeredInRound_) = AggregatorV3Interface(underlyingPriceFeed).latestRoundData(); | ||
return (roundId_, scalePrice(price), startedAt_, updatedAt_, answeredInRound_); | ||
} | ||
|
||
function signed256(uint256 n) internal pure returns (int256) { | ||
if (n > uint256(type(int256).max)) revert InvalidInt256(); | ||
return int256(n); | ||
} | ||
|
||
function scalePrice(int256 price) internal view returns (int256) { | ||
int256 scaledPrice; | ||
if (shouldUpscale) { | ||
scaledPrice = price * rescaleFactor; | ||
} else { | ||
scaledPrice = price / rescaleFactor; | ||
} | ||
return scaledPrice; | ||
} | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
Are we ever going to upscale prices?
It seems like the only use case for this contract is truncating an 18 decimal price feed to 8 decimals.
Would it be simpler/more efficient to have
scalePrice
always returnprice / rescaleFactor
?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.
Yeah maybe simpler is better. But my goal was to make this flexible in case there was ever a need to scale up. There's not much extra gas costs to it, so it just depends on how much we value the extra flexibility.
Personally, I rather have the flexibility (hardcoding price feed decimals has made the WETH deployment trickier, for example), but not a super strong opinion if we think it's not worth it.