Audit · firm’s term: audit report
QuillAudits reviewed Nex Labs Cross Chain (Nex Labs Stock Index) on 15 Jan 2025: 13 findings, 0 critical; 11 marked fixed, 2 open.
Report hosted on quillaudits.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 | 1 | 0 | 3 |
| Low | 1 | 0 | 8 |
The failure to disable initializers at the constructor level of the proxy upgradeable contract raises concern as it is susceptible to exploit. This oversight presents the potential of attackers initializing the implementation contract itself.
The mint function of the IndexToken contract has 5 require statements to check for address validity and the supply cap being less or equal to the supplyCeiling, however mintToFeeReceiver() function does not have a similar check for token supply minted. This would make the owner able to mint new tokens above the supplyCeiling set and also cause a DOS the next time an address with MINTER role calls mint() because totalSupply() + amount would already have exceeded the supplyCeiling. require(totalSupply() + amount <= supplyCeiling, "will exceed supply ceiling"); If the owner address gets hijacked at any point, the compromised account would be able to mint new tokens without any restrictions leading to economic loss for legitimate users of the protocol
The Index smart contract integrates Chainlink oracle for price derivation. However, when it fetches the price of a token, it fails to check that the price value is not stale as it is possible for an attacker to manipulate this.
In contract IndexFactoryStorage you can see that there are 2 functions, setWrappedDShareAd dresses() and setPriceFeedAddresses(). In both they are checking dShares array with wrapped DShares and priceFeedAddress array. Even though they are called by the owner and the owner is trusted and won’t make a mistake still, say the owner called setWappedDShareAddresses with 10 addresses in both arrays and in setPriceFeedAddresses you just called with 9. And for the last one if while buying/selling if the price feed is not available then it might fail/revert until they are set correctly again. Also there are chances of messing the order of the priceFeed or wrappedDshares.
It is expected that initialize functions get invoked before normal contract interactions begin to ensure the contract state is as expected. The initialize functions in the contracts listed above do not call ReentrancyGuard’s init function and could lead to potential inconsistencies in state if the codeblock contains instructions to set up the contract state.
The current arithmetic implementation for minting tokens to the fee receiver is heavily gas intensive because it performs the arithmetic for compounding with a loop. This would become considerably expensive when the number of days grows to a large number. With current tests, it costs ~500k gas units to call this function when 300 days have passed from the initial feeTimestamp value. Conversely, using a logarithmic approximation for compounding is just as precise with ~80% gas savings
The functionality of the pausable contract does not apply to the mintToFeeReceiver function and allows for the owner to continue token minting to the fee receiver while the contract is paused.
There are a couple of commented lines of code across all contracts. Some were imports which were commented out, some were functions
The setFeeRate is conditioned to be called after 12 hours from the last time of update. After 12 hours and 59 minutes, it’s impossible to reset the fee rate until 13 hours.
With the use of safeTransferLib, there is assurance of safety transfer of tokens.<br>
There’s a function called calculateFees where it gets the flat fee and percentage fee rate and then accumulates the overall fees. Similar implementation is present in the requestBuyOrder and requestBuyOrderFromCurrentBalance. Rather than replicating these logics in both functions, call the calculateFees in its place to avoid code repetition.
The report names a repository or files. Open the report to see its scope.
Repository and files the report names (15)
350 projects reviewed · 459 reports · latest Apr 2025
See QuillAudits’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