Exactly Protocol Audits Cover

Exactly Protocol Audits

In this blog post, we recap the findings of four different security audits of the Exactly Protocol conducted by Coinspect between November 2021 and October 2022.

Exactly is a non-custodial protocol that provides financial instruments for lenders and borrowers. Interest rates are based on supply and demand for credit of each supported token, for a certain period of time. Specifically, it allows users to take loans and make deposits to Variable and Fixed Interest Rate Pools, with different maturity dates. Exactly enables investments that ponderate the “time value of money”.

A total of nine high-risk, fourteen medium-risk and five low-risk issues were identified and addressed over the course of the audits. Among most significant changes made to the protocol during this period are:

  • Migrated from an immutable to an upgradable architecture.
  • Improved the liquidation and debt distribution mechanisms.
  • Mathematical corrections to the interest rate model curve.
  • Added variable borrows and how its interest rate is calculated.
  • Added a fee collection system.
  • Changed the base currency from USD to ETH.
  • Included over 750 unit tests across the audits.

It is important to remark that the Exactly team was always open to discuss potential issues, provide extensive analysis of scenarios when requested and to analyze the suggested fixes, or provide better alternatives. The Exactly team prioritized improving their protocol as many iterations as needed over releasing on a fixed schedule. The security standpoint of the protocol increased as a result of these interactions between Coinspect and Exactly because of the willingness to discuss and improve as much as possible before the deployment.

The following sections briefly describe the most important findings in each audit, and how they were addressed. For a more detailed discussion please refer to the full audit reports listed below:

First Audit (November, 2021):

In this first audit, Coinspect familiarized with the protocol specs and the initial implementation. Four high-risk issues and one medium-risk issue were identified, all of them were addressed or acknowledged.

The first high-risk issue, EXA-1, shows how the rewards distribution process could be exploited to claim all the available rewards, addressed by changing how accountancy is updated. Then, EXA-3 shows how users could be forced to accept higher commision rates than expected. The issue was fixed by adding a maximum rate as an input. EXA-4 demonstrates how the administrator could arbitrarily seize all funds, addressed by adding a timelock mechanism. Finally, EXA-5 shows how wrong accounting results in a maturity pool not repaying its debt (no longer an issue because of the changes introduced later).

As for the medium-risk issue, EXA-2 shows how ETokens minting could be abused by minting more tokens than it should in certain scenarios.

Second Audit (May, 2022):

In the second audit Coinspect saw the code increase in both complexity and number of features. Most of the issues were caused by design decisions that the dev team promptly fixed. Three high-risk issues, seven medium-risk issues and one low-risk were identified. All of them were addressed or acknowledged.

Regarding the high-risk issues: EXA-06 shows how the protocol could accumulate debt because of unprofitable liquidations. The issue was fixed by modifying the liquidation process. EXA-07 refers to bypassing liquidity checks. The issue was addressed by adding account shortfall validations. Lastly, EXA-08 shows an insolvency scenario where some users are not able to redeem funds when the protocol is in debt.

The seven medium-risk issues had the following causes:

  • Interest curve rounding errors (EXA-09) as well as manipulations (EXA-11) on rate calculations.
  • Rounding down errors that allowed bypassing allowance checks (EXA-12).
  • The liquidation process such as debt accumulated because of cascading liquidations (EXA-10), allowance check bypass (EXA-13) and reverting liquidations because of shortfall (EXA-14).
  • Using fixed decimals for every retrieved Chainlink pair (EXA-15).

The low risk issue, EXA-16, shows a griefing attack on withdrawals.

Third Audit (October, 2022):

The code has gone through refactoring and new functionalities have been added, prior to the third audit. This introduced some issues, mostly due to implementation decisions, and less by design mistakes. Two high-risk issues, four medium-risk issues and three low-risk were identified, all of them were addressed or acknowledged. All addressed by the dev team.

As for the high-risk issues, EXA-23 shows how liquidity checks could be bypassed when outdated accountancy values are used. The issue was fixed by changing how the variables are updated. EXA–24 shows how bad debt distribution (non-recoverable debt) of the protocol could be front-run, harming depositors. Fixed by changing the bad debt distribution mechanism.

The medium-risk issues were related to:

  • Interest rate curve’s lack of precision (EXA-27), similar to EXA-09.
  • How variables are updated, affecting the bad debt distribution (EXA-25) and performing incorrect calculations when protocol’s parameters are modified (EXA-28).
  • A hard cap on earnings when deposits exceeded a certain threshold (EXA-26)

The three low-risk issues show how some inherited contracts do not respect a recommended upgradeability pattern (EXA-29); the existence of unbounded protocol’s setters (EXA-30); loss of precision while calculating the adjustFactor (EXA-31).

Fourth Audit (October, 2022):

In the fourth audit, the code was close to release, with few changes detected and correspondingly few issues, reflecting the maturity the code has gathered. The last release prior to the deployment modifies the base currency (using ETH instead of USD), the retrieval mechanism of Chainlink’s pairs, and the inclusion of a wrapper to allow calling external contracts.

Two medium-risk issues and one low-risk issue were found, all of them were addressed or acknowledged.

The medium-risk issues are related to the lack of liveness checks on Chainlink’s retrieved pairs (EXA-36) and not checking return values on a low level staticcall (EXA-37).

The low-risk issue shows how markets could be enabled with invalid price feeds (EXA-38).