Resonance Security reviewed Primex Finance on 14 Oct 2024: 7 findings, 1 critical; 6 marked fixed, 1 open.
Trustblock does not review code.
Statuses are the security firm’s own, from its report.
| Severity | Open | Acknowledged | Fixed |
|---|---|---|---|
| Critical | 0 | 0 | 1 |
| High | 0 | 0 | 2 |
| Medium | 0 | 0 | 1 |
| Low | 1 | 0 | 2 |
The function flashLoan() does not update important variables right after the transfer of the assets. Essentially, there are three steps to the function flashLoan():Calculate fees, available liquidities and transfer the assets to the borrower.Give control to the borrower to execute the intended operation.Handle the repayment of the flash loan.During the first step, the transfer of the assets to the receiver is performed but the calls to the functions _updateRates() and _updateIndexes() are not performed. These are only performed later after the executeOperation() function call on the third step during _handleFlashLoanRepayment(). This effectively means that malicious borrowers may execute operations within the flash loan transaction, such as deposit() and withdraw(), that will operate under outdated rates and indexes variables. Taking into additional consideration that flash loans can amount to big numbers and different buckets, the execution of such functions may yield unfavorable results to the protocol.The same attack vector is true for the variable availableLiquidity.
The function updatePullOracle() does not properly validate the amount of Ether sent to the smart contract and allows for funds to be drained to an external contract. This can occur when the validation on the variable msg.value is being done after funds have been transferred. While it seems counterintuitive, the variable msg.value does not change throughout the transaction, even after successful outbound transfers of native funds.The following describes an example of an attack scenario for this specific case:User calls updatePullOracle() while sending 10 Wei. The variable msg.value will contain the value 10.For the Pyth if branch, the variable updateFee is calculated via pyth.getUpdateFee().Supposing a value of 9 for the variable updateFee, the require statement will pass successfully.9 Wei is sent to the external contract pyth via updatePriceFeeds(). 1 Wei is left from the funds deposited by the user.Supposing input parameters that will result in the execution of multiple iterations of the for loop, and supposing a calculation result of 9 for the second updateFee, the next iteration of the require statement will still pass successfully (9 <= 10) since the value of msg.value does not change, even though funds have been transferred away on the first iteration. This means that if the contract PriceOracle contains funds, these will be used along with the 1 Wei left from the user.Next iterations will drain the funds of the PriceOracle smart contract completely.
The function updatePullOracle() is payable and therefore, it can receive native Ether from callers of this function. When using UpdatePullOracle.Pyth as an oracle type, the calculated updateFee is required to be less than or equal to the amount of native Ether received via msg.value. When the caller of the function sends a higher amount of Ether than the one required by updateFee, the smart contract PriceOracle will retain the excess funds and it will be impossible to retrieve them, making the contract act as a sink for unrecoverable funds.
The function updatePullOracle() does not validate the input arrays _data and _oracleTypes. It is possible for this function to be called with mismatching input array lengths and allowing transactions to occur on only a subset of the input elements.
The function getEstimatedMinProtocolFee() does not account for gas calculations for the newly introduced Optimistic chain integration. The variable l1CostWei will always yield a value of 0. While this may be intended, it does not conform with code implemented across other smart contracts on the protocol.
The FlashLoanManager contract contains logic related to flashloans. Most notably - the flashLoan function used to initiated the loan. Among other arguments, this function takes two arrays - buckets and amounts which specify assets to be used in the flashloan. It was observed that the flashLoan function does not verify the uniqueness of entries in the buckets array. Hence, it is possible to use the same asset multiple times during the same flashloan. As a consequence, in this scenario the contract will need to perform additional cross-contract calls and use more memory for the execution which would be inefficient.
The report names a repository or files. Open the report to see its scope.
18 projects reviewed · 25 reports · latest Aug 2025
See Resonance Security’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