A Leaner, Meaner Comptroller

With ETHOnline in full gear and Compound sponsoring bounties, its a good time to talk about some relatively low-hanging fruit when it comes to reducing the code size of the Comptroller and unlocking other major protocol enhancements.

The Comptroller is the core risk management contract of Compound v2. All CTokens interact with Comptroller, at least once, before allowing users to take action. As such, modifying Comptroller is one of the most powerful ways one could upgrade the protocol (for instance, that’s how we added the autonomous COMP distribution to all users).

But if you’ve tried to perform a Comptroller upgrade recently, then you know that it’s very hard to add any features to it at this point, without going past the code size limit for Ethereum contracts. As the protocol has evolved, some parts of the Comptroller have stood the test of time better than others.

Here’s a few ideas for simplification, that could make a big difference in the ability to add new and exciting features to the Comptroller.

Simplification Ideas

Remove _setCompRate / refreshCompSpeeds, Add _setCompSpeeds

When we launched the COMP distribution, we thought a simple but fair way to distribute COMP would be proportional to the total borrow interest paid by each market, since that was also a metric we thought important to the protocol. Within a week, we were convinced a better metric would be raw total borrows rather than interest.

In retrospect, it’s probably even better to let governance directly choose the relative incentives for each market, rather than having them converge on some path-dependent equilibrium state. When we built the refreshCompSpeeds mechanism, we had also considered this possibility, which is perhaps why it’s relatively easy to remove.

By deleting _setCompRate and refreshCompSpeeds, we can eliminate a bunch of complexity from the Comptroller. What remains is then to add a simple setter method _setCompSpeeds, to directly set the compSpeeds storage for each market.

Remove _setMaxAssets

This one looks like a relatively easy win, if governance agrees that this (unused) ability is not likely to be useful in the future either. It should be as simple as the heading suggests.

Eliminate ErrorReporter/Exponential

The original v2 protocol made heavy use of our legacy error handling and Failure logs in order to indicate to users the source of issues during transactions. Soon after launch, revert messages started being displayed properly on etherscan, and eventually we adopted the modern error-handling via revert mechanism.

However, not all code has been rewritten for the newer, less verbose style, as all code changes come with a cost. At this point, to the extent which the ErrorReporter contract can be removed, it probably should be.

Coupled closely to this issue is the way the protocol does math. The COMP distribution added a few new math functions to Exponential, which could be used for all the math in Comptroller. Likewise, different contracts are using different pieces of the math libraries, if Comptroller were restricted to only including the functions it actually relies upon, it could go a long way in terms of code size savings.

The easiest place to start with something like this might be in e.g. _setCloseFactor, which is a mostly unused function with a lot of verbose checks. It should be rather straightforward to upgrade this function and reduce code size.

A harder change might be e.g. getHypotheticalAccountLiquidityInternal, since that function is used everywhere, and it is inherently a more complex function. Nonetheless the approach is the same and the good thing is these changes would not affect the interface.

Other Advice

Do NOT Modify Storage

In general, the upgrade process works by replacing the logic contract, while continuing to use the same storage contract. Thus, the storage is something that exists between generations of Comptroller code, and it’s important not to modify the contract storage layout when you make upgrades. In general, storage should only be appended to, never deleted.

As long as you don’t modify ComptrollerStorage.sol, this shouldn’t be a problem.

Ask For Help

If you get stuck, reach out on Discord or here in the forum. There might be folks who know a solution, and your questions help others too!

1 Like

Thanks @jared for putting together this list of suggestions. Here at Gauntlet, we’re working on implementing some of these changes. If anyone in the community wants to know more, feel free to reach out to me or @tarun. We’ll also be posting the changes as a PR to the Compound repo shortly so other people can review in detail.