Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kacperrams/0f961d746f53e2a000cd92c60410c685 to your computer and use it in GitHub Desktop.
Save kacperrams/0f961d746f53e2a000cd92c60410c685 to your computer and use it in GitHub Desktop.

Review of Mainnet ETH

Performed by OpenZeppelin

Date: January 3, 2022

We were asked to review the Comet repository on branch mainnet-eth at commit 4db8aca43bc1f48c3666df0fe29ca5e9f012fe43. As we conducted a previous code review in pull request 587 at commit cc7e500e0e69e3d3ef5bb9c1b16dd062cd292427, this engagement focused on the changes from commits cc7e500e0e69e3d3ef5bb9c1b16dd062cd292427 and 4db8aca43bc1f48c3666df0fe29ca5e9f012fe43 for the following files in scope:

  • BaseBulker.sol
  • MainnetBulker.sol
  • Liquidator.sol
  • Comet.sol
  • CometCore.sol
  • ConstantPriceFeed.sol
  • IERC20NonStandard.sol
  • IPriceFeed.sol
  • ScalingPriceFeed.sol
  • WstETHPriceFeed.sol

Overview

Between both commits several changes have been made in the codebase. The most relevants are the addition of more documentation, the refactor of certain parts of the code, fixes from a previous engagement, the possibility to choose a different exchange when liquidating assets, the possibility to use non-standard ERC20 tokens in the protocol, and the construction of a constant and a scaled price feed.

Update: The Compound team applied several fixes based on our recommendations. We have reviewed and addressed each fix submitted by the team and updated the report accordingly. Moreover, as the Liquidator contract is still work-in-progress, any recommendations will be taken into account for a future version of such contract. Fixes for such contract were not included in this update. We suggest a second review of the Liquidator contract once the new changes and fixes have been applied.

Findings

Low

L01 - Lack of input validation

In the BaseBulker contract, the transferAdmin function does not validate if the new admin address is non-zero address. It is unclear whether this is a conscious decision so that the ownership can be renounced or not.

Consider documenting if this is intended to be used for renouncing the ownership. Otherwise, consider adding validation to ensure that the new admin address is non-zero address.

Update: Resolved in commit 00cf59d89a2d834c332928cd96f73e05754f761a from pull request 641.

L02 - Improper implementation of Chainlink AggregatorV3Interface

In the ConstantPriceFeed contract, the latestRoundData function returns 0 for the roundId and answeredInRound returned values.

However, the Chainlink documentation states that the roundId should start at 1. This could lead to unnecessary confusion or unexpected behavior in the future for users or other protocols that make use of this contract.

Consider setting as 1 the return value for roundId and answeredInRound to comply with the Chainlink specification.

Update: Resolved in commit d7ab1dd12be37efe5988a3fa8214cfd748f9b2c7 from pull request 641.

L03 - Contract admin and recipient cannot be updated

In the Liquidator contract, the admin and the recipient addresses are set on deployment. However, once those are set, they cannot be updated. The operator would not be able to update either address and would be forced to deploy a new contract.

Consider using the OpenZeppelin's Ownable library for management of the admin role and adding an admin-allowed function to update the recipient address.

Update: Acknowledged, will resolve. The Compound team stated:

In the latest version (OnChainLiquidator.sol), the admin role is eliminated and the profits of liquidation are returned to msg.sender.

L04 - Incomplete/confusing documentation

Throughout the codebase there are instances of confusing, incomplete, or inconsistent inline documentation that should be fixed. The following are instances of confusing inline documentation:

  • In line 6 from IERC20NonStandard.sol, the documentation states that it is a "Version of ERC20 with no return values for transfer and transferFrom", but the approve function is also modified from the EIP20
  • Missing documentation explaining the overall details of the ConstantPriceFeed and ScalingPriceFeed contracts
  • In line 69 from WstETHPriceFeed.sol, the documentation states "Assumes the stETH price feed has an equal or larger amount of decimals than this price feed", but this is enforced by the validation done in line 42, which prevents having something bigger than that
  • Missing documentation for all the variables inside the PoolConfig struct

Clear inline documentation is fundamental for outlining the intended behavior of the code. Mismatches between the inline documentation and the implementation can lead to serious misconceptions about how the system is expected to behave.

Consider fixing these errors to avoid confusion for developers, users, and auditors alike.

Update: Resolved in commit 89f6b166fe3e3a2095da666996d1f6f522700a0c from pull request 641.

L05 - Liquidation points may get lost

When a position in Comet becomes absorbable by the protocol, the Comet contract assigns "liquidator points" to the absorber address, which is passed as input.

However, because the Liquidator contract passes its address as the absorber, this could cause a few problems:

  1. The Liquidator does not have any method to handle "liquidation points" once Compound implements the feature
  2. If the Liquidator contract becomes deprecated, the points held by the Comet contract for it cannot be transferred and will be lost
  3. If collateral purchases are paused while absorptions are still allowed, the Liquidator contract will not be able to absorb collateral to collect those points (even though it may not be desired to purchase collateral) as the encapsulation of both operations would revert the transaction. The admin must manually absorb the assets, but these points will not be included with the Liquidator's points

To ensure that the liquidation points are used correctly in the future, consider passing the Liquidator admin's address or the msg.sender when calling absorb in the initFlash function. Alternatively, you might consider using a proxy contract behind the Liquidator contract to extend the contract's features.

Update: Acknowledged, will resolve. The Compound team stated:

Great point. We will update OnChainLiquidator.sol to accrue liquidator points to msg.sender when absorbing, so that the caller can redeem the liquidator points in the future.

Notes

N01 - Multiple contracts/interfaces per file

The Liquidator.sol file contains the IUniswapV2Router interface and the Liquidator contract.

Consider moving the interface to another file and then importing it to the Liquidator contract, to maintain the best practice of using a single interface or contract per file.

Update: Acknowledged, will resolve. The Compound team stated:

The same issue exists in OnChainLiquidator.sol. We will move interfaces into separate files.

N02 - Code style could be improved

Throughout the codebase, there are cases of inconsistent coding style or possible improvements to it. In particular:

Consider fixing and keeping a consistent coding style throughout the codebase to improve the code's readability.

Update: Resolved for the WstETHPriceFeed contract. Acknowledged, will resolve for the Liquidator contract. A detailed reasons of the lack of dual scaling features in the WstETHPriceFeed contract was given. We suggest documenting it along with the contract's documentation. The Compound team stated:

ScalingPriceFeed is a generic contract that allows for scaling in both directions. WstETHPriceFeed is a more specific contract that converts the price from a stETH Chainlink price feed (18 decimals) to a price that Comet supports (<= 18 decimals), meaning only down-scaling needs to be supported. The Liquidator contracts are still being worked on and are out of scope for this audit, but we will definitely take this suggestion into consideration when making updates to OnChainLiquidator. The underscore postfixes in ScalingPriceFeed are consistent with the style of the other core Comet contracts (e.g. Configurator). Same comment regarding Liquidator contracts being out of scope.

N03 - TODOs in code

There are multiple "TODO" comments in the codebase (written as "XXX"). In particular, lines 64, 272, and 320 from Liquidator.sol.

Consider removing those commets and instead track those issues in the project backlog.

Update: Acknowledged, will resolve. The Compound team stated:

We will remove all the TODOs once the liquidator contract is in its final state.

Conclusion

No critical or high severity issues were found.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment