As of 28 Oct 2026, Exactly Protocol has 8 audit reports by 3 security firms on Trustblock; the latest is by ABDK Consulting, dated 31 Oct 2025. Those reports list no open critical findings.
Record last updated . It holds audits and findings, contracts and incidents up to Oct 2026. Trustblock does not review code.
Newest first
| Audit | Security firm | Date | Scope | Critical findings | Report |
|---|---|---|---|---|---|
| Exactly Protocol Update audit (October 2025) | Security firm: ABDK Consulting | Date: | Scope: Not recorded (see the report) | No open critical findings | Open · GitHub |
| Exactly Protocol Update audit (March 2025) | Security firm: ABDK Consulting | Date: | Scope: Not recorded (see the report) | No open critical findings | Open · GitHub |
| Exactly Protocol Update audit (April 2024) | Security firm: ABDK Consulting | Date: | Scope: Not recorded (see the report) | No open critical findings | Open · GitHub |
| Exactly EscrowedExa Audit | Security firm: OpenZeppelin | Date: | Scope: Files named in the report | 1 critical finding, fixed | Open · blog.openzeppelin.com |
| Exactly Escrowed EXA audit | Security firm: ABDK Consulting | Date: | Scope: Not recorded (see the report) | No open critical findings | Open · GitHub |
| Exactly Peripheral Contracts audit | Security firm: ABDK Consulting | Date: | Scope: Not recorded (see the report) | No open critical findings | Open · GitHub |
| Exactly Protocol Phase II audit | Security firm: ABDK Consulting | Date: | Scope: Not recorded (see the report) | No open critical findings | Open · GitHub |
| Exactly | Security firm: CertiK | Date: | Scope: Files named in the report | No open critical findings | Open · skynet.certik.com |
Statuses are the security firm’s own, from each report.
| Severity | Open | Acknowledged | Fixed |
|---|---|---|---|
| Critical | 0 | 0 | 1 |
| High | 1 | 0 | 18 |
| Medium | 1 | 25 | 10 |
| Low | 4 | 69 | 48 |
In the contract `FixedLender`, the role `DEFAULT_ADMIN_ROLE` has authority over the following functions: - `setMaxFuturePools` will set the protocol's max future weekly pools for borrowing and lending. - `setAccumulatedEarningsSmoothFactor` will set the factor used when smoothly accruing earnings to the smart pool. the role `PAUSER_ROLE` has authority over the following functions: - `pause` will set the `_pause` state to true in case of emergency - `unpause` will set the `_pause` state to false when the threat is gone Any compromise to the `DEFAULT_ADMIN_ROLE` and `PAUSER_ROLE` accounts may allow a hacker to take advantage of this authority. In the contract `ExactlyOracle`, the role `DEFAULT_ADMIN_ROLE` has authority over the following functions: - `setAssetSources` will set or replace the sources of assets. Any compromise to the `DEFAULT_ADMIN_ROLE` account may allow a hacker to take advantage of this authority. In the contract `Auditor`, the role `DEFAULT_ADMIN_ROLE` has authority over the following functions: - `setOracle` will set Oracle's to be used - `setLiquidationIncentive` will set liquidation incentive for the whole ecosystem - `enableMarket` will enable a certain FixedLender market - `setCollateralFactor` will set the collateral factor for a certain fixedLender - `setMarketBorrowCaps` will set the given borrow caps for the given fixedLender markets Any compromise to the `DEFAULT_ADMIN_ROLE` account may allow a hacker to take advantage of this authority. In the contract `InterestRateModel`, the role `DEFAULT_ADMIN_ROLE` has authority over the following functions: - `setCurveParameters` will update this model's curve parameters. - `setSPFeeRate` will update `spFeeRate` Any compromise to the `DEFAULT_ADMIN_ROLE` account may allow a hacker to take advantage of this authority. In the contract `PoolAccounting`, the role `DEFAULT_ADMIN_ROLE` has authority over the following functions: - `setInterestRateModel` will set the interest rate model to be used by this PoolAccounting - `setPenaltyRate` will set the penalty rate per second. - `setSmartPoolReserveFactor` will set the percentage that represents the smart pool liquidity reserves that can't be borrowed. Any compromise to the `DEFAULT_ADMIN_ROLE` account may allow a hacker to take advantage of this authority.
Open the reportThe `liquidate` function is designed to liquidate an uncollateralized position. It will call `auditor.liquidateCalculateSeizeAmount` to get the number of tokens to be liquidated and call `_seize` or `collateralFixedLender.seize` to seize a certain amount of tokens. According to the logic of `liquidateCalculateSeizeAmount` function, we have the following equation: $$seizeTokens = \frac{actualRepayAmount * priceBorrowed * 10^{markets[fixedLenderCollateral].decimals} * liquidationIncentive}{priceCollateral * 10^{markets[fixedLenderBorrowed].decimals} * 1e18}$$ ```solidity function liquidateCalculateSeizeAmount( FixedLender fixedLenderBorrowed, FixedLender fixedLenderCollateral, uint256 actualRepayAmount ) external view override returns (uint256) { // Read oracle prices for borrowed and collateral markets uint256 priceBorrowed = oracle.getAssetPrice(FixedLender(fixedLenderBorrowed).assetSymbol()); uint256 priceCollateral = oracle.getAssetPrice(FixedLender(fixedLenderCollateral).assetSymbol()); uint256 amountInUSD = actualRepayAmount.fmul(priceBorrowed, 10**markets[fixedLenderBorrowed].decimals); // 10**18: usd amount decimals uint256 seizeTokens = amountInUSD.fmul(10**markets[fixedLenderCollateral].decimals, priceCollateral); return seizeTokens.fmul(liquidationIncentive, 1e18); } ``` In order to simplify the calculation, assuming that there are the same decimals and the `liquidationIncentive` is 1e18, so the equation will be : $$seizeTokens = \frac{actualRepayAmount * priceBorrowed}{priceCollateral}$$ When the borrower is delayed, there are more and more penalties and the amount of `actualRepayAmount` will increase. When the `actualRepayAmount` increases, the `seizeTokens` will also increase. If the `seizeTokens` is greater than the balance of the collateral asset, the `liquidate` function will revert: ```solidity uint256 seizeTokens = auditor.liquidateCalculateSeizeAmount(this, collateralFixedLender, assets); // Revert if borrower collateral token balance < seizeTokens (uint256 balance, ) = collateralFixedLender.getAccountSnapshot(borrower, maturity); if (balance < seizeTokens) revert BalanceExceeded(); ``` In this case, no one can liquidate this uncollateralized position anymore.
Open the reportIn the Exactly protocol's liquidation logic, the liquidator could repay the debt of the original borrower to get the original borrow's assets. However, if the liquidation is not processed in time, or there is a sharp price drop on certain asset. It could lead to the borrowed assets' value much larger than the collateral's value. Therefore, the protocol might suffer unexpected loss.
Open the reportWhen transferring standard ERC20 deflationary tokens, the input amount may not be equal to the received amount due to the charged transaction fee. For example, if a user stakes 100 deflationary tokens (with a 10% transaction fee) in a `FixedLender`, only 90 tokens actually arrived in the contract. However, the user can still withdraw 100 tokens from the contract, which causes the contract to lose 10 tokens in such a transaction.
Open the reportThe `enableMarket()` enables a certain FixedLender market of the protocol. However, there is no explicit validation in `enableMarket` function to ensure the `collateralFactor` is properly set. ```solidity function enableMarket( FixedLender fixedLender, uint128 collateralFactor, string memory symbol, string memory name, uint8 decimals ) external onlyRole(DEFAULT_ADMIN_ROLE) { ```
Open the reportThe contract is serving as the underlying entity to interact with third-party `chainlink` and `WETH` protocols. The scope of the audit treats 3rd party entities as black boxes and assumes their functional correctness. However, in the real world, 3rd parties can be compromised and this may lead to lost or stolen assets. In addition, upgrades of 3rd parties can possibly create severe impacts. For example, if the price of chainlink oracle is inaccurate, it could lead to the loss of the Exactly protocol. Reference: https://twitter.com/CertiKAlert/status/1524968003049332756
Open the reportThe reports name a repository or files. Open a report to see its scope.
Is this your project? Show this record on your own website. The label states what the record holds, links to this page and updates by itself. It is free and needs no sign-in.
Automatic: the three strongest facts of this project’s own record (its last audit and two more), highlighted. They update with the record. Picking a fact turns Automatic off.
<head><script src="https://widget.trustblock.run/project-widget.min.js" defer></script></head><body><divdata-tb-project-widgetdata-tb-project-slug="exactly"></div></body>
Paste the code where the label should appear. It uses no API credit and updates by itself.
Something wrong on this page? A missing report, a wrong date, a finding that was fixed since. Tell us and we check it against its source.
Tell us