CertiK reviewed RAI Finance on 26 Oct 2022: 12 findings, 1 critical; 7 marked fixed, 2 acknowledged, 3 open.
Report hosted on skynet.certik.com.
Trustblock does not review code.
Statuses are the security firm’s own, from its report.
| Severity | Open | Acknowledged | Fixed |
|---|---|---|---|
| Critical | 0 | 1 | 0 |
| High | 3 | 0 | 2 |
| Medium | 0 | 1 | 1 |
| Low | 0 | 0 | 4 |
The `_portfolio` manager calls the function `trade` to swap `_sendToken` to `_receiveToken`, `_sendToken` has been checked when creating `portfolio`, but `_receiveToken` is not checked, `manager` can swap to any token, it's unsafe.
In the contract, `SimpleERC20`, the role, `_owner`, has the authority over the functions shown in the diagram below. Any compromise to the privileged account which has access to `_owner` may allow the hacker to take advantage of this. 
`onlyModule` can call `editPositionMultiplier` to update `positionMultiplier`, if `Portfolio.totalSupply()` is not zero, minted tokens don't keep consistent with components assets when `positionMultiplier` is modified. So it's unsafe to update `positionMultiplier`.
In the function `sellExactPortfolioForETH`, `totalEth` is a evaluation value, which can be manipulated by attackers, check `totalEth > _minEthOut` is not safe.
`isRouter` is maintained in the contract but not used in `tradeXXX` functions.
These functions implemented, but the module to call these functions are not implemented. -addExternalPositionModule -removeExternalPositionModule -editExternalPositionUnit -editExternalPositionData -editPositionMultiplier -lock -unlock
When users call the function `issue`, it calls `onlyValidAndInitializedPortfolio` twice, it's better to optimise it as following. ```=js function getRequiredComponentUnitsForIssue( IPortfolio _portfolio, uint256 _quantity ) public view onlyValidAndInitializedPortfolio(_portfolio) returns (address[] memory, uint256[] memory) { return _getRequiredComponentUnitsForIssue(_portfolio, _quantity); } function _getRequiredComponentUnitsForIssue( IPortfolio _portfolio, uint256 _quantity ) internal view returns (address[] memory, uint256[] memory) { address[] memory components = _portfolio.getComponents(); uint256[] memory notionalUnits = new uint256[](components.length); for (uint256 i = 0; i < components.length; i++) { require(!_portfolio.hasExternalPosition(components[i]), "Only default positions are supported"); notionalUnits[i] = _portfolio.getDefaultPositionRealUnit(components[i]).toUint256().preciseMulCeil(_quantity); } return (components, notionalUnits); } ```
The report names a repository or files. Open the report to see its scope.
Repository and files the report names (31)
1,044 projects reviewed · 1,375 reports · latest May 2025
See CertiK’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