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

M-02 [Oval] Attempts to Push Price to the CoinbaseOracle Will Always Fail #18

Conversation

md0x
Copy link
Collaborator

@md0x md0x commented Jun 17, 2024

Fixes the following issue reported in the Oval Incremental Audit:

The CoinbaseOracle contract serves as an oracle for price data reported and signed by
Coinbase. In order to supply such price data to the contract, users have to call the
pushPrice function which, in case of the correct data passed, updates the price data for a
given asset. In order to verify the correctness of provided data, several checks are made,
including the check for a valid kind field. However, this check reverts when kind is different
than "price". The data signed by the Coinbase oracle will always contain kind equal to
"prices", resulting in the pushPrice function always reverting, making it impossible to
provide asset prices.
Consider verifying that the provided kind value is equal to "prices".

Changes:

  • CoinbaseOracle now takes a string memory _dataKind argument instead of having a hardcoded "price" value
  • Add forge tests that push real prices from Coinbase Oracle API
  • Small interface updates to simplify contract

Copy link

linear bot commented Jun 17, 2024

@@ -7,10 +7,10 @@ interface IAggregatorV3SourceCoinbase {
function latestRoundData(string memory ticker)
external
view
returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound);
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Additionally, we can simplify the return values, given that they don’t match the Chainlink Aggregator interface anymore with the ticker argument.

* @param _reporter The address of the reporter allowed to push price data.
*/
constructor(uint8 _decimals, address _reporter) {
constructor(uint8 _decimals, string memory _dataKind, address _reporter) {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We now can pass a data kind in the constructor

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if it's always prices then we should not yet the deployer to define this, I think? if it should always be a hard-coded value then we should hard-code it.

@md0x md0x changed the title feat: Fix Coinbase Oracle and test against production API fix[oval-audit-m-02]: Attempts to Push Price to the CoinbaseOracle Will Always Fail Jun 17, 2024
@md0x md0x marked this pull request as ready for review June 17, 2024 12:57
@md0x md0x changed the title fix[oval-audit-m-02]: Attempts to Push Price to the CoinbaseOracle Will Always Fail M-02 [Oval: Attempts to Push Price to the CoinbaseOracle Will Always Fail Jun 18, 2024
@md0x md0x changed the title M-02 [Oval: Attempts to Push Price to the CoinbaseOracle Will Always Fail M-02 [Oval] Attempts to Push Price to the CoinbaseOracle Will Always Fail Jun 18, 2024
uint256 timestamp, // e.g. 1629350000
string memory ticker, // e.g. "BTC"
uint256 price // 6 decimals
) = abi.decode(priceData, (string, uint256, string, uint256));

require(keccak256(abi.encodePacked(kind)) == keccak256(abi.encodePacked("price")), "Invalid kind.");
require(keccak256(abi.encodePacked(kind)) == keccak256(abi.encodePacked("prices")), "Invalid kind.");
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it might be better to use constant for KIND

Copy link
Collaborator

@Reinis-FRP Reinis-FRP Jun 18, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

or bytes32 public immutable KIND_HASH = keccak256(abi.encodePacked("prices"));

Comment on lines 31 to 32
function reporter() public view virtual returns (address) {
return 0xfCEAdAFab14d46e20144F48824d0C09B1a03F2BC;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

better leave as immutable. If mock needs override then can do that in mock constructor

@@ -8,48 +8,45 @@ import {IAggregatorV3SourceCoinbase} from "../interfaces/coinbase/IAggregatorV3S
* @notice A smart contract that serves as an oracle for price data reported by a designated reporter.
*/
contract CoinbaseOracle is IAggregatorV3SourceCoinbase {
address immutable reporter;
uint8 public immutable decimals = 6;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also if we make it immutable I think it should be all uppercase, no?

Copy link
Member

@chrismaree chrismaree left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks good so far but needs a bit of refinement to be more consistent. ever immutable should be uppercase, for example.

Signed-off-by: Pablo Maldonado <[email protected]>
@@ -8,48 +8,47 @@ import {IAggregatorV3SourceCoinbase} from "../interfaces/coinbase/IAggregatorV3S
* @notice A smart contract that serves as an oracle for price data reported by a designated reporter.
*/
contract CoinbaseOracle is IAggregatorV3SourceCoinbase {
address immutable reporter;
address public reporter = 0xfCEAdAFab14d46e20144F48824d0C09B1a03F2BC;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this will have state reading overhead in production. better use the same approach as for decimals, like have upper case constant and lovercase getter function

Signed-off-by: Pablo Maldonado <[email protected]>
@md0x md0x merged commit ff31b1b into master Jun 18, 2024
3 checks passed
@md0x md0x deleted the pablo/uma-2647-m-02-oval-attempts-to-push-price-to-the-coinbaseoracle-will branch June 18, 2024 16:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants