Skip to content

Instantly share code, notes, and snippets.

@kacperrams
Created March 17, 2023 18:59
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/cf7703aaf8fc0fe2dfcd3566df90970b to your computer and use it in GitHub Desktop.
Save kacperrams/cf7703aaf8fc0fe2dfcd3566df90970b to your computer and use it in GitHub Desktop.

Compound Optimism Bridge Receiver Audit

Performed by OpenZeppelin

Date: March 17, 2023

We were asked to review the Comet repository on branch silver/optimism-deployment at commit 303315178a59120c6458b4e6ec35555d55b3f295. The following files were in scope:

  • contracts/IGovernorBravo.sol
  • contracts/bridges/optimism/OptimismBridgeReceiver.sol
  • contracts/bridges/BaseBridgeReceiver.sol
  • contracts/vendor/Timelock.sol
  • contracts/ITimelock.sol
  • deployments/optimism/usdc/configuration.json

This deployment is currently marked as a "work-in-progress" project, which means that it may have further changes and that parameters are still under revision.

From the scope above, issues related to all contracts except for OptimismBridgeReceiver and BaseBridgeReceiver were documented in the Compound Polygon Bridge Receiver Audit, as the same codebase is shared by both deployments. As a result, several findings from the previous report affect the current scope and will be addressed as part of remediation of that audit.

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.

System Overview

Similar to the previous Polygon deployment report, Compound also plans to release Comet into the Optimism network which shares a similar architecture.

In order for the Compound Governor contract from Ethereum Mainnet to communicate with the Optimism deployment, a proposal needs to be submitted, voted on, and passed in the usual manner. Then, it will simply be sent through the Optimism bridge to the OptimismBridgeReceiver contract. This contract will then process the message and relay it to Optimism's deployed Timelock contract.

The receiver and the timelock are interlinked but have different responsibilities, which allows either of them to be replaced with a different contract in the future. The receiver is meant to receive messages from the bridge, enqueue the transactions, and initiate their execution. The timelock serves the purpose of ensuring transactions can only be executed during the correct execution period and it handles execution when called upon by the receiver.

Security Considerations & Trust Assumptions

The Optimism network has been actively developing the protocol. This means that projects that develop on top of it must take into consideration that low-level changes may be applied in the near future, and the usage of certain instructions in the contracts could output a different result or the reversion of the transactions. For instance, relying on the block number, its rate or the transaction origin may result in unexpected behavior.

A new Bedrock update will be implemented soon and more changes to the network will be made. Deployments in this network may need to be more closely monitored.

Additionally, synchronization between L1 and L2 is not guaranteed. This can result in critical actions being executed at different times across networks. If a proposal depends on such actions, it should account for this by incorporating a buffer, to ensure all networks are in sync.

The Optimism network enables the replaying of a message, which will resend a transaction with a higher gas limit. This would make it possible to send the same transaction twice, which will have a different eta. So it must be assumed that identical transactions can be part of a single proposal.

Currently, the sequencer is centralized and can order the transactions in any way that they see fit. This means that proposals can have a different order from how they were submitted. Once the sequencers become decentralized, the Compound team must assume that MEV could happen.

Findings

Low

L01 - Denial of service on big proposals

At the moment, the maximum block gas limit in Ethereum is 30M (30,000,000). However, the upcoming Optimism Bedrock update will propose a "target gas limit of 2.5M with an elasticity multiplier of 8", which will have an upper bound of 20M.

As a proposal queues and executes several transactions at the same time, the execution in L2 may fail due to this smaller limit (compared to mainnet).

Consider documenting this limit so it is taken into consideration when creating the proposals. This will prevent transactions from unexpectedly hitting the gas limit in L2 and reverting.

Update: Acknowledged, not resolved. The Compound team stated:

We should note the limits of the bridge transaction needing to be able to execute on the L2 chain. This is also mitigated by simulating the full proposal, its effects, and the scenario suite on top. Also, it seems like Optimism is increasing their block gas limit to 30M from 20M (ethereum-optimism/optimism#2911 (comment))

L02 - Receiver can be initialized by anyone

The initialize function from the BaseBridgeReceiver contract has external visibility and can be called by anyone. This allows any user to call the initialize function after deployment and set the contract's governor and local time-lock addresses at will. In the case that a malicious user front runs the Compound team to call the initialization function, the deployment would have to be abandoned and a new set of BridgeReceiver and Timelock contracts would have to be deployed. While this is manageable, this situation could be exploited by a malicious actor who can keep calling the initialization function and causing a denial of service for that network deployment.

Consider either renaming the initialize function and only allowing the original deployer of the contract to call the function, or encapsulating the entire deployment under a single transaction to prevent someone else from calling the initialize function.

Update: Acknowledged, not resolved. The Compound team stated:

The BridgeReceiver contract is deployed and then initialized shortly thereafter (these events occur in the same deploy script).

It is true that the contract could be maliciously initialized by anyone. In the event that this happened, we would simply abandon the deployment. There would be no borrow/supply activity in the protocol at that point in time, so there would be no harm. We would simply need to redeploy.

Limiting initialization to a particular address (e.g. the contract deployer) would require storing an admin or initializer variable on the contract. Even if that address has a single, one-time capability, it gives the appearance of an address with special privileges.

Notes

N01 - Multiple assets per file

The OptimismBridgeReceiver.sol file defines the OvmL2CrossDomainMessengerInterface interface and the OptimismBridgeReceiver contract. However, it is recommended to have a single definition per file and import the dependencies when needed.

Consider splitting the file to have a single asset per file.

Update: Resolved in pull request #699 at commit 32bf496.

N02 - Deployment script has comment referring to Polygon instead of Optimism

The deployments/optimism/usdc/deploy.ts script has a comment referring to the PolygonBridgeReceiver contract, which instead should be referring to the OptimismBridgeReceiver contract.

Consider updating the comment to reflect the correct contract.

Update: Resolved in pull request #699 at commit 32bf496.

Conclusion

No critical or high severity issues were found.

Monitoring Recommendations

Due to the shared contracts between the Optimism and Polygon deployments, all monitoring recommendations documented in the Compound Polygon Bridge Receiver Audit report should be considered. In addition, specifically for the Optimism deployment, consider monitoring the mempool for any call to the replayMessage function from the L1CrossDomainMessenger contract that passes the data from a Compound submitted proposal, to detect potential inclusions of a similar proposal.

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