UAV to Oracle Audit
April 12, 2024
Summary
Total Issues: 2 (2 resolved)
Critical Severity Issues: 0 (0 resolved)
High Severity Issues: 0 (0 resolved)
Medium Severity Issues: 0 (0 resolved)
Low Severity Issues: 0 (0 resolved)
Notes & Additional Information: 2 (2 resolved)
Scope
We audited the smartcontractkit/open-oracle repository at commit d15c5fb.
In scope were the following files:
contracts
└── PriceOracle
└── PriceOracle.sol
System Overview
Compound stands as a prominent lending platform that enables liquidity providers to deposit their funds and earn interest, while simultaneously offering borrowers the opportunity to secure loans against collateral. Although the community is gradually transitioning to Compound V3 (aka Comet), Compound V2 continues to be actively utilized. From the start, Compound V3 has been using Chainlink price feeds.
In contrast, Compound V2 employs an anchoring system, which rejects price feeds from Chainlink oracles if there is a significant difference from the recent Time-Weighted Average Price (TWAP), potentially leading to price inaccuracies and delays during periods of market volatility. The price oracle under review in this audit is designed to replace the anchoring system in Compound V2, addressing these price update issues.
Security Model and Trust Assumptions
The PriceOracle
contract is designated to be overseen by an owner address which is tasked with the deployment, addition, and maintenance of price feeds for various assets and cTokens. It is presumed that all incorporated price feeds and configurations are accurately established. The audit focuses on the oracle’s structure and verifies its appropriate interaction with the Comptroller
.
Notes & Additional Information
Redundant Data Storage
The TokenConfig
struct is defined as shown below:
struct TokenConfig {
// Decimals of the underlying asset (e.g. 18 for ETH)
uint8 underlyingAssetDecimals;
// Address of the Compound Token
address cToken;
// Address of the feed used to retrieve the asset's price
address priceFeed;
}
The same struct is stored in the storage like:
/// @dev Mapping of cToken address to TokenConfig used to maintain the supported assets
mapping (address => TokenConfig) tokenConfigs
In this configuration, storing the cToken
address within the struct may seem redundant. However, including the cToken
address enhances code readability and simplifies comprehension of the structure. On the other hand, this approach incurs additional gas costs due to the necessity of updating storage, resulting in users incurring higher expenses for extra SSTORE
and SLOAD
operations.
Update: Resolved at commit 3682d02.
Unnecessary Usage of Storage
In PriceOracle
at line 160, storing the loaded configuration in memory could lower gas expenses. As the storage modifications occur at line 171, unnecessary storage accesses happen in the updateConfigPriceFeed
function.
Consider using memory
as data location for the config
variable to reduce gas costs.
Update: Resolved at commit 4df9c25.
Conclusion
During this audit, we thoroughly examined the PriceOracle
contract, focusing on its role in replacing the UAV. Our analysis covered two key areas:
- We verified that state transitions and management of configurations for diverse price feeds are executed properly within the
PriceOracle
contract. - We confirmed that the
getUnderlyingPrice
function accurately returns the expected price format for theComptroller
.
Based on our evaluation, we are confident that the PriceOracle
contract will seamlessly integrate with the Comptroller
and deliver precise pricing even in times of high volatility, as long as the underlying oracles and price feeds act appropriately and reliably.