CertiK reviewed LinoSwap on 20 Oct 2022: 11 findings, 1 critical; 8 marked fixed, 3 acknowledged.
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 | 0 | 1 |
| High | 0 | 1 | 1 |
| Medium | 0 | 0 | 0 |
| Low | 0 | 2 | 6 |
It is possible for the pool to become imbalanced so that a user cannot remove liquidity, even when they have LP tokens. This can happen when many NFT's have been swapped for in the pool, so that no matter what NFT a user chooses from those remaining in the pool, its percentage of the pool will be higher than the percentage of LP tokens a user holds. A possible scenario is as follows: - Assume a user has a high valued rare NFT. - There is a pool from the same project with only low value common NFT's such that the rare NFT is worth as much as all of the NFT's in the pool currently. - The user adds liquidity with high high valued NFT. - The user then removes all their liquidity, but removes all the low value NFT's instead of their high valued NFT. - In this case there would only be one NFT left in the pool and non of the original LP providers would be able to remove liquidity.
The signature for a `liquidityNFT` allows the same signature to be submitted multiple times for a replay attack. Additional NFT's may be minted in a collection changing the `rarityRankPercentage` for each NFT, in this case an old signature can be used to calculate the value based on the old `rarityRankPercentage`.
There should always be events emitted in the sensitive functions that are controlled by centralization roles.
The **require** can be used to check for conditions and throw an exception if the condition is not met. It is better to provide a string message containing details about the error that will be passed back to the caller.
Addresses should be checked before assignment or external call to make sure they are not zero addresses. ```solidity=34 protocolFeeRecipient = _protocolFeeRecipient; ``` - `_protocolFeeRecipient` is not zero-checked before being used. --- ```solidity=76 protocolFeeRecipient = _protocolFeeRecipient; ``` - `_protocolFeeRecipient` is not zero-checked before being used. --- ```solidity=16 factory = _factory; ``` - `_factory` is not zero-checked before being used.
The `_afterTokenTransfer()` only checks that `to` is not the zero address. If the amount of token transferred is `0`, then `to` will be added to the `_liquidityProviderSet` when they do not hold any LP tokens.
Both `createLiquidity()` from the router and `createPoolETH()` from the factory check that `getPool[poolID] == address(0)`. Since `createLiquidity()` calls `createPoolETH()` this makes this check redundant.
There are the following typos in the code: - In line 63 of LinoswapV1Pool.sol, there is a commented out line that should be removed. - In line 314 of LinoswapV1Pool.sol, there is a commented out line that should be removed. - In line 346 of LinoswapV1Pool.sol, there is a commented out line that should be removed. - In XykCurve.sol, the error message should say invalid instead of invalidate.
The report names a repository or files. Open the report to see its scope.
Repository and files the report names (13)
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