Quantstamp reviewed Ondo Finance (Ondo Finance V2) on 3 Sep 2021: 15 findings, 0 critical; 7 marked fixed, 8 acknowledged.
Report hosted on certificate.quantstamp.com.
Trustblock does not review code.
Statuses are the security firm’s own, from its report.
| Severity | Open | Acknowledged | Fixed |
|---|---|---|---|
| Critical | 0 | 0 | 0 |
| High | 0 | 0 | 0 |
| Medium | 0 | 2 | 2 |
| Low | 0 | 6 | 5 |
`updateRewardPath` requirement in [L282](https://github.com/ondoprotocol/protocol-dev/blob/610a6291951bb12b2cf9dbbd8ff31faeb2e22d11/contracts/strategies/SushiStakingV2Strategy.sol#L282) seems incorrect since in the case if reward token and end token are similar the required length is set to be higher than 1, meaning that resetting a path length equal to 1 is not allowed.
The implemented staking mechanism in `SushiStakingV2Strategy` is highly optimized and helps avoid any extra computation. However, setting the values of the initial shares for a specific pool is important and should be analyzed carefully. The algorithm is designed in a way to compute smaller shares every time that the LP rewards get higher, meaning that depositing the same LP tokens values for a specific vault will result in giving different shares values (while the reward is accruing). However, if the initial deposit is low enough and if the LP rewards are significantly greater than the initial LP deposit, new deposits to the vault will see their computed share being truncated. In a worst-case scenario, if for any reason higher LP rewards can be introduced by an attacker, the next deposits will be truncated following the value of rewards introduced. The attacker will profit by getting higher returns.
The `SushiStakingV2Strategy.updateRewardPath(...)` function allows paths with lengths greater than one, yet, with the reward and end token being the same (circular). It is just wasteful to trade a token for itself. At the code level (L278--281), this appears as follows: ``` L278. require( L279. rewardToken != endToken || _pathFromReward.length > 1, <=== L280. "Invalid path" ); ``` For `_pathFromReward.length > 1` to be evaluated, `rewardToken` must be the same as `endToken`, in which case the length is already greater than one. Otherwise, if `rewardToken == endToken`, the length should be exactly one, which is not the condition being checked.
Function `calculateSwapInAmount(...)` appears to have been cloned from Alpha Homora and Zapper, but the inline code comment does not indicate the commit hash and file from which it was taken. If buggy, faulty behavior may be permanently set in unless one is able to trace the code and corresponding fixes that might surface.
To allow reacting to a potential hack, it is always a good practice to allow pausing a contract. However, `SushiStakingV2Strategy.harvest(...)` can still be called when the contract is paused. Note that the latter calls `_compound`, which is itself not affected by any pauses. Hence, one can invoke `harvest(...)` while the strategy is paused. That should not be allowed, especially in the case of reacting to a hack.
The `SushiStakingV2Strategy.removeLp(...)` does not validate its `to` argument. If `address(0)`, the removal essentially burn funds.
`depositIntoChef()` does not accumulate the vault shares but rewrites them, using the input value. This scheme is not used any of the other functions that update the shares. Even if `depositIntoChef` can be called only once, developers should be careful with future contract updates.
The report names a repository or files. Open the report to see its scope.
Repository and files the report names (2)
236 projects reviewed · 332 reports · latest Oct 2026
See Quantstamp’s auditsSomething 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