Rari Capital security record

Arbitrum, Ethereum, Fantomrari.capitalXGitHub

As of 3 Nov 2026, Rari Capital has 3 audit reports by 1 security firm on Trustblock; the latest is by Quantstamp, dated 2 Jul 2021. Those reports list no open critical findings. It also holds 1 incident (latest 7 May 2021).

Critical findings
No open critical findings
Across 3 reports.
Incident
Incident 7 May 2021
Source: De.Fi incident database. 1 audit has been published since. See the incident
Open the latest report
Your label, live
Get the label for your site

Record last updated . It holds audits, findings and contracts up to Nov 2026, and incidents up to Oct 2026. Trustblock does not review code.

Audits3

Newest first

AuditSecurity firmDateScopeCritical findingsReport
Rari Capital (On-chain Governance)Security firm: QuantstampDate: Scope: Files named in the reportNo open critical findingsOpen · certificate.quantstamp.com
RariCapitalSecurity firm: QuantstampDate: Scope: Files named in the reportNo open critical findingsOpen · certificate.quantstamp.com
RariCapital V2Security firm: QuantstampDate: Scope: Files named in the reportNo open critical findingsOpen · certificate.quantstamp.com

Findings82

Statuses are the security firm’s own, from each report.

SeverityOpenAcknowledgedFixed
Critical000
High006
Medium2210
Low93320
HighInaccurate token pricesRariCapital · Quantstamp · 20 Aug 2020Fixed

The `getRawFundBalance()` function should return the total balance of all RFT holders’ funds and all unclaimed fees of all currencies, in USD. However, the computation on L503 assumes that all currencies are worth 1 USD. This has significant impact on the entire system, including accrued interest, fees, deposits and withdrawals.

Open the report
HighInaccurate token pricesRariCapital V2 · Quantstamp · 20 Aug 2020Fixed

The `getRawFundBalance()` function should return the total balance of all RFT holders’ funds and all unclaimed fees of all currencies, in USD. However, the computation on L503 assumes that all currencies are worth 1 USD. This has significant impact on the entire system, including accrued interest, fees, deposits and withdrawals.

Open the report
HighIncorrect Rari Governance Token amountRariCapital · Quantstamp · 20 Aug 2020Fixed

There is a typo on L27 of `RariGovernanceToken.sol`, namely 8570000 should be 8750000 according to the comment on L23: "Initializer that reserves 8.75 million RGT for liquidity mining and 1.25 million RGT to the team.". This will conflict with L157 of `RariGovernanceTokenDistributor.sol`: `finalRgtDistribution = 8750000e18`.

Open the report
HighIncorrect Rari Governance Token amountRariCapital V2 · Quantstamp · 20 Aug 2020Fixed

There is a typo on L27 of `RariGovernanceToken.sol`, namely 8570000 should be 8750000 according to the comment on L23: "Initializer that reserves 8.75 million RGT for liquidity mining and 1.25 million RGT to the team.". This will conflict with L157 of `RariGovernanceTokenDistributor.sol`: `finalRgtDistribution = 8750000e18`.

Open the report
HighUninitialized `_ethUsdPriceFeed`RariCapital · Quantstamp · 20 Aug 2020Fixed

The `AggregatorV3Interface private _ethUsdPriceFeed` state variable defined on L234 in `RariGovernanceTokenDistributor.sol` is never initialized (assigned a value). However, it is used in the `getEthUsdPrice` function. This means that the `getEthUsdPrice` will always return `0`, which will affect the Ethereum fund pool of Rari.

Open the report
HighUninitialized `_ethUsdPriceFeed`RariCapital V2 · Quantstamp · 20 Aug 2020Fixed

The `AggregatorV3Interface private _ethUsdPriceFeed` state variable defined on L234 in `RariGovernanceTokenDistributor.sol` is never initialized (assigned a value). However, it is used in the `getEthUsdPrice` function. This means that the `getEthUsdPrice` will always return `0`, which will affect the Ethereum fund pool of Rari.

Open the report
Medium`ChainlinkPriceOracleV2._price` Does Not Consult Decimal ValuesRari Capital (On-chain Governance) · Quantstamp · 2 Jul 2021Fixed

The function `_price` queries various Chainlink oracles, however, the decimal value associated with each price feed is not considered. This may lead to over/undervaluing the price of the `underlying` token being considered.

Open the report
Medium`FixedEurPriceOracle` May Return Stale PricesRari Capital (On-chain Governance) · Quantstamp · 2 Jul 2021Fixed

The function `_price` consults several oracles without ensuring that the returned data is recent. This may lead to stale pricing results and potential arbitrage.

Open the report
MediumAmount in pools may be incorrectRariCapital · Quantstamp · 20 Aug 2020Fixed

The issue is visible in the `rari-yield-pool-contracts` repo, in the `_withdrawFrom` function in `RariFundManager.sol`: 1. L666 computes: `uint256 contractBalance = token.balanceOf(_rariFundControllerContract);` 1. L668-683 iterate over all pools in order to withdraw the remaining balance and add it to `contractBalance` 1. L685 checks: `require(amount <= contractBalance, "Available balance not enough to cover amount even after withdrawing from pools.");` 1. L686 recomputes the same value as on L666 into another variable: `uint256 realContractBalance = token.balanceOf(_rariFundControllerContract);` 1. L709 checks if `realContractBalance < amount ? realContractBalance : amount` and transfers the resulting value. This clearly shows that the following condition is possible: `realContractBalance < amount <= contractBalance`, which would indicate that the amounts withdrawn from the pools in the `for`-loop on L668-683 is discarded.

Open the report
MediumAmount in pools may be incorrectRariCapital V2 · Quantstamp · 20 Aug 2020Fixed

The issue is visible in the `rari-yield-pool-contracts` repo, in the `_withdrawFrom` function in `RariFundManager.sol`: 1. L666 computes: `uint256 contractBalance = token.balanceOf(_rariFundControllerContract);` 1. L668-683 iterate over all pools in order to withdraw the remaining balance and add it to `contractBalance` 1. L685 checks: `require(amount <= contractBalance, "Available balance not enough to cover amount even after withdrawing from pools.");` 1. L686 recomputes the same value as on L666 into another variable: `uint256 realContractBalance = token.balanceOf(_rariFundControllerContract);` 1. L709 checks if `realContractBalance < amount ? realContractBalance : amount` and transfers the resulting value. This clearly shows that the following condition is possible: `realContractBalance < amount <= contractBalance`, which would indicate that the amounts withdrawn from the pools in the `for`-loop on L668-683 is discarded.

Open the report
Show 10 more
MediumIncorrect value for supported currenciesRariCapital · Quantstamp · 20 Aug 2020Fixed

The array index of the left-hand side member of the assignment in the following code snippet located in `RariFundManager.sol` does not change for any loop iteration and it is out of bounds for the `acceptedCurrencies` array: ``` for (uint256 i = 0; i < _supportedCurrencies.length; i++) if (_acceptedCurrencies[_supportedCurrencies[i]]) acceptedCurrencies[acceptedCurrencies.length] = _supportedCurrencies[i]; ``` Therefore this loop will not fill in all the supported currencies as the function is expected to do and the return values will be incorrect.

Open the report
MediumIncorrect value for supported currenciesRariCapital V2 · Quantstamp · 20 Aug 2020Fixed

The array index of the left-hand side member of the assignment in the following code snippet located in `RariFundManager.sol` does not change for any loop iteration and it is out of bounds for the `acceptedCurrencies` array: ``` for (uint256 i = 0; i < _supportedCurrencies.length; i++) if (_acceptedCurrencies[_supportedCurrencies[i]]) acceptedCurrencies[acceptedCurrencies.length] = _supportedCurrencies[i]; ``` Therefore this loop will not fill in all the supported currencies as the function is expected to do and the return values will be incorrect.

Open the report
MediumUnchecked Return ValueRariCapital · Quantstamp · 20 Aug 2020Fixed

Most functions will return a value indicating success or failure. It's important to ensure that every necessary function is checked. Otherwise, the caller just assumes that the function call was successful and continues execution. This is the case for the function call `cErc20.accrueInterest() ` on L49 in `CompoundPoolController.sol`, whose return value is not checked.

Open the report
MediumUnchecked Return ValueRariCapital V2 · Quantstamp · 20 Aug 2020Fixed

Most functions will return a value indicating success or failure. It's important to ensure that every necessary function is checked. Otherwise, the caller just assumes that the function call was successful and continues execution. This is the case for the function call `cErc20.accrueInterest() ` on L49 in `CompoundPoolController.sol`, whose return value is not checked.

Open the report
MediumUnfinished token upgradesRariCapital · Quantstamp · 20 Aug 2020Fixed

If a user upgrades, but is then sent old fund tokens (which seems possible since it's an ERC20), that user cannot upgrade the received tokens. Further, if token transfers from an already updated account occur, the conditional on L69 will never hold, because there will be old tokens in an account that cannot be upgraded (since it was already upgraded). Therefore, `finished` will never be set to true.

Open the report
MediumUnfinished token upgradesRariCapital V2 · Quantstamp · 20 Aug 2020Fixed

If a user upgrades, but is then sent old fund tokens (which seems possible since it's an ERC20), that user cannot upgrade the received tokens. Further, if token transfers from an already updated account occur, the conditional on L69 will never hold, because there will be old tokens in an account that cannot be upgraded (since it was already upgraded). Therefore, `finished` will never be set to true.

Open the report
LowIncorrect `getUnderlyingPrice` ComputationRari Capital (On-chain Governance) · Quantstamp · 2 Jul 2021Fixed

The function `getUnderlyingPrice` appears to be copied from `FixedEthPriceOracle.sol`, and therefore relates the token price to ETH, not EUR.

Open the report
LowUnintended Code Removal In `Comptroller.mintAllowed`Rari Capital (On-chain Governance) · Quantstamp · 2 Jul 2021Fixed

The following snippet was removed, however, it seems this check is necessary based on the function name. ``` // Make sure minter is whitelisted if (enforceWhitelist && !whitelist[minter]) { return uint(Error.SUPPLIER_NOT_WHITELISTED); } ```

Open the report
LowChecks-Effects-Interactions PatternRariCapital · Quantstamp · 20 Aug 2020Fixed

The Checks-Effects-Interactions coding pattern is meant to mitigate any chance of other contracts manipulating the state of the blockchain in unexpected and possibly malicious ways before control is returned to the original contract. As the name implied, only after checking whether appropriate conditions are met and acting internally on those conditions should any external calls to, or interactions with, other contracts be done.

Open the report
LowChecks-Effects-Interactions PatternRariCapital V2 · Quantstamp · 20 Aug 2020Fixed

The Checks-Effects-Interactions coding pattern is meant to mitigate any chance of other contracts manipulating the state of the blockchain in unexpected and possibly malicious ways before control is returned to the original contract. As the name implied, only after checking whether appropriate conditions are met and acting internally on those conditions should any external calls to, or interactions with, other contracts be done.

Open the report
Show 10 more
LowDangerous cast from uint256 to int256RariCapital · Quantstamp · 20 Aug 2020Fixed

There is a cast to `int256` on L515 in the `RariFundManager`, which would cause a large enough unsigned value to be converted to a negative value. However, this is highly unlikely to occur.

Open the report
LowDangerous cast from uint256 to int256RariCapital V2 · Quantstamp · 20 Aug 2020Fixed

There is a cast to `int256` on L515 in the `RariFundManager`, which would cause a large enough unsigned value to be converted to a negative value. However, this is highly unlikely to occur.

Open the report
LowDuration of RGT distribution may be different from 60 daysRariCapital · Quantstamp · 20 Aug 2020Fixed

The duration of the distribution period is set to `345600` blocks on L152 in `RariGovernanceTokenDistributor.sol`. Assuming that the average block duration over a 60 day period is 15 seconds results in 60 days. However, according to the latest [statistics on Etherscan](https://etherscan.io/chart/blocktime) we foresee an average block duration of 13 seconds, which would reduce the distribution period to 52 days. However, this is also an approximate estimate as the actual duration could be even lower.

Open the report
LowDuration of RGT distribution may be different from 60 daysRariCapital V2 · Quantstamp · 20 Aug 2020Fixed

The duration of the distribution period is set to `345600` blocks on L152 in `RariGovernanceTokenDistributor.sol`. Assuming that the average block duration over a 60 day period is 15 seconds results in 60 days. However, according to the latest [statistics on Etherscan](https://etherscan.io/chart/blocktime) we foresee an average block duration of 13 seconds, which would reduce the distribution period to 52 days. However, this is also an approximate estimate as the actual duration could be even lower.

Open the report
LowFallback function can receive funds from any addressRariCapital · Quantstamp · 20 Aug 2020Fixed

The fallback function is meant to only be “called by 0x exchange to refund unspent protocol fee.” However, there are no restrictions/checks in place to guarantee this. This means that anyone could send funds to this contract by mistake.

Open the report
LowFallback function can receive funds from any addressRariCapital V2 · Quantstamp · 20 Aug 2020Fixed

The fallback function is meant to only be “called by 0x exchange to refund unspent protocol fee.” However, there are no restrictions/checks in place to guarantee this. This means that anyone could send funds to this contract by mistake.

Open the report
LowFaulty dev environment might not print some enum and struct layout errorsRariCapital V2 · Quantstamp · 20 Aug 2020Fixed

As described in this [forum update] (https://forum.openzeppelin.com/t/problem-in-upgrades-plugins-for-users-of-unsafeallowcustomtypes/5066), `truffle-upgrades` supports the `unsafeAllowCustomTypes` flag. Due to an implementation error of this flag, older versions might not display some storage layout errors for enum and struct.

Open the report
LowMisaligned comments and implementationRariCapital · Quantstamp · 20 Aug 2020Fixed

The comment on L23 says 20 million tokens will be minted, but on L27 only 10 million are minted.

Open the report
LowMisaligned comments and implementationRariCapital V2 · Quantstamp · 20 Aug 2020Fixed

The comment on L23 says 20 million tokens will be minted, but on L27 only 10 million are minted.

Open the report
LowNo example of token distribution implementation is presentedRariCapital V2 · Quantstamp · 20 Aug 2020Fixed

`distributionEndBlock` is a critical parameter used on the interface for governance distribution `IRariGovernanceTokenDistributor`. This method is only called in `RariFundManager` when the block number is below `distributionEndBlock`. No example implementation of `IRariGovernanceTokenDistributor` is presented, and `distributionEndBlock` must be used there to make this parameter effective.

Open the report
Show 6 more
LowPrivileged Roles and OwnershipRariCapital V2 · Quantstamp · 20 Aug 2020Fixed

Smart contracts will often have `owner` variables to designate the person with special privileges to make modifications to the smart contract. In particular: 1. In `RariFundController.sol`, the owner can invoke `setEnzymeComptroller` at any point. 1. In `RariGovernanceTokenUniswapDistributor.sol`, if the owner changes the Uniswap pair address using `setRgtEthUniswapV2Pair`, users that have already deposited may not be able to withdraw.

Open the report
LowRounding errorRariCapital · Quantstamp · 20 Aug 2020Fixed

In the function `withdraw()`, the amount of withdrawal credits is rounded up on L81. It seems that if all users would choose to redeem credits and some would get rounded-up, then the last user to withdraw would fail due to lack of credits.

Open the report
LowRounding errorRariCapital V2 · Quantstamp · 20 Aug 2020Fixed

In the function `withdraw()`, the amount of withdrawal credits is rounded up on L81. It seems that if all users would choose to redeem credits and some would get rounded-up, then the last user to withdraw would fail due to lack of credits.

Open the report
LowUnclear `addPool` omission in `initialize`RariCapital V2 · Quantstamp · 20 Aug 2020Fixed

In `initialize`, it is unclear why `addPool(5)`, which would correspond to Enzyme, is not invoked.

Open the report
LowUnlocked PragmaRariCapital · Quantstamp · 20 Aug 2020Fixed

Every Solidity file specifies in the header a version number of the format `pragma solidity (^)0.5.*`. The caret (`^`) before the version number implies an unlocked pragma, meaning that the compiler will use the specified version _and above_, hence the term "unlocked."

Open the report
LowUnlocked PragmaRariCapital V2 · Quantstamp · 20 Aug 2020Fixed

Every Solidity file specifies in the header a version number of the format `pragma solidity (^)0.5.*`. The caret (`^`) before the version number implies an unlocked pragma, meaning that the compiler will use the specified version _and above_, hence the term "unlocked."

Open the report

Incidents1

Attached through a shared contract address. Our incident data ends in Oct 2026.

Incident

Incident,

totalETH() value, resulting in the withdrawal of more ETH than deposited by the attacker.

Source: De.Fi incident database.

Audits before it
2.
Audits since
1, the latest dated 2 Jul 2021.

Contracts

No deployed address is recorded for these audits.

The reports name a repository or files. Open a report to see its scope.

The repositories and files the reports name

Show this on your site

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.

Content

Facts

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.

Fixed as
Language

Style

Layout
Theme
Accent
Corners

Format

Size
Date
Embed as
HTML
<head>
<script src="https://widget.trustblock.run/project-widget.min.js" defer></script>
</head>
<body>
<div
data-tb-project-widget
data-tb-project-slug="rari-capital"
></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