Skip to content
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

document RTokenAsset.price() oracleError double-counting #916

Merged
merged 1 commit into from
Aug 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
9 changes: 8 additions & 1 deletion contracts/plugins/assets/RTokenAsset.sol
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ uint256 constant ORACLE_TIMEOUT = 15 minutes;

/// Once an RToken gets large enough to get a price feed, replacing this asset with
/// a simpler one will do wonders for gas usage
// @dev This RTokenAsset is ONLY compatible with Protocol ^3.0.0
/// @dev This RTokenAsset is ONLY compatible with Protocol ^3.0.0
contract RTokenAsset is IAsset, VersionedAsset, IRTokenOracle {
using FixLib for uint192;
using OracleLib for AggregatorV3Interface;
Expand Down Expand Up @@ -48,6 +48,11 @@ contract RTokenAsset is IAsset, VersionedAsset, IRTokenOracle {
}

/// Can revert, used by other contract functions in order to catch errors
/// @dev This method for calculating the price can provide a 2x larger range than the average
/// oracleError of the RToken's backing collateral. This only occurs when there is
/// less RSR overcollateralization in % terms than the average (weighted) oracleError.
/// This arises from the use of oracleErrors inside of `basketRange()` and inside
/// `basketHandler.price()`. When `range.bottom == range.top` then there is no compounding.
/// @return low {UoA/tok} The low price estimate
/// @return high {UoA/tok} The high price estimate
function tryPrice() external view virtual returns (uint192 low, uint192 high) {
Expand Down Expand Up @@ -81,6 +86,7 @@ contract RTokenAsset is IAsset, VersionedAsset, IRTokenOracle {
// solhint-enable no-empty-blocks

/// Should not revert
/// @dev See `tryPrice` caveat about possible compounding error in calculating price
/// @return {UoA/tok} The lower end of the price estimate
/// @return {UoA/tok} The upper end of the price estimate
function price() public view virtual returns (uint192, uint192) {
Expand All @@ -95,6 +101,7 @@ contract RTokenAsset is IAsset, VersionedAsset, IRTokenOracle {

/// Should not revert
/// lotLow should be nonzero when the asset might be worth selling
/// @dev See `tryPrice` caveat about possible compounding error in calculating price
/// @return lotLow {UoA/tok} The lower end of the lot price estimate
/// @return lotHigh {UoA/tok} The upper end of the lot price estimate
function lotPrice() external view returns (uint192 lotLow, uint192 lotHigh) {
Expand Down
2 changes: 2 additions & 0 deletions docs/collateral.md
Original file line number Diff line number Diff line change
Expand Up @@ -428,6 +428,8 @@ Should never revert.

Should return a lower and upper estimate for the price of the token on secondary markets.

The difference between the upper and lower estimate should not exceed 5%, though this is not a hard-and-fast rule. When the difference (usually arising from an oracleError) is large, it can lead to [the price estimation of the RToken](../contracts/plugins/assets/RTokenAsset.sol) somewhat degrading. While this is not usually an issue it can come into play when one RToken is using another RToken as collateral either directly or indirectly through an LP token. If there is RSR overcollateralization then this issue is mitigated.

Lower estimate must be <= upper estimate.

Should return `(0, FIX_MAX)` if pricing data is unavailable or stale.
Expand Down
1 change: 1 addition & 0 deletions docs/writing-collateral-plugins.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ Here are some basic questions to answer before beginning to write a new collater
7. **What amount of revenue should this plugin hide? (a minimum of `1e-6`% is recommended, but some collateral may require higher thresholds, and, in rare cases, `0` can be used)**
8. **Are there rewards that can be claimed by holding this collateral? If so, how are they claimed?** Include a github link to the callable function or an example of how to claim.
9. **Does the collateral need to be "refreshed" in order to update its internal state before refreshing the plugin?** Include a github link to the callable function.
10. **Can the `price()` range be kept <5%? What is the largest possible % difference (while priced) between `price().high` and `price().low`?** See [RTokenAsset.tryPrice()](../contracts/plugins/assets/RTokenAsset.sol) and [docs/collateral.md](./collateral.md#price) for additional context.

## Implementation

Expand Down