In some code blocks you use a lot of uncheckeds scopes, a cleanner pattern would be to use a wider unchecked scope.
InfinityOrderBookComplication.sol
diff --git a/contracts/core/InfinityOrderBookComplication.sol b/contracts/core/InfinityOrderBookComplication.sol
index 17b2b45..dbf4997 100644
--- a/contracts/core/InfinityOrderBookComplication.sol
+++ b/contracts/core/InfinityOrderBookComplication.sol
@@ -242,25 +242,21 @@ contract InfinityOrderBookComplication is IComplication, Ownable {
}
uint256 numCollsMatched = 0;
- // check if taker has all items in maker
- for (uint256 i = 0; i < order2NftsLength; ) {
- for (uint256 j = 0; j < order1NftsLength; ) {
- if (order1Nfts[j].collection == order2Nfts[i].collection) {
- // increment numCollsMatched
- unchecked {
+ unchecked {
+ // check if taker has all items in maker
+ for (uint256 i = 0; i < order2NftsLength; ) {
+ for (uint256 j = 0; j < order1NftsLength; ) {
+ if (order1Nfts[j].collection == order2Nfts[i].collection) {
+ // increment numCollsMatched
++numCollsMatched;
+ // check if tokenIds intersect
+ bool tokenIdsIntersect = doTokenIdsIntersect(order1Nfts[j], order2Nfts[i]);
+ require(tokenIdsIntersect, 'tokenIds dont intersect');
+ // short circuit
+ break;
}
- // check if tokenIds intersect
- bool tokenIdsIntersect = doTokenIdsIntersect(order1Nfts[j], order2Nfts[i]);
- require(tokenIdsIntersect, 'tokenIds dont intersect');
- // short circuit
- break;
- }
- unchecked {
++j;
}
- }
- unchecked {
++i;
}
}
@@ -287,23 +283,19 @@ contract InfinityOrderBookComplication is IComplication, Ownable {
return true;
}
uint256 numTokenIdsPerCollMatched = 0;
- for (uint256 k = 0; k < item2TokensLength; ) {
- for (uint256 l = 0; l < item1TokensLength; ) {
- if (
- item1.tokens[l].tokenId == item2.tokens[k].tokenId && item1.tokens[l].numTokens == item2.tokens[k].numTokens
- ) {
- // increment numTokenIdsPerCollMatched
- unchecked {
+ unchecked {
+ for (uint256 k = 0; k < item2TokensLength; ) {
+ for (uint256 l = 0; l < item1TokensLength; ) {
+ if (
+ item1.tokens[l].tokenId == item2.tokens[k].tokenId && item1.tokens[l].numTokens == item2.tokens[k].numTokens
+ ) {
+ // increment numTokenIdsPerCollMatched
++numTokenIdsPerCollMatched;
+ // short circuit
+ break;
}
- // short circuit
- break;
- }
- unchecked {
++l;
}
- }
- unchecked {
++k;
}
}
[Q-02] Use a common pattern
On InfinityExchange.sol#L1128 the signature of the function is function _transferFees(address seller, address buyer, uint256 amount, address currency)
I recommend you to change it to a more common pattern;
function _transferFees(address seller, address buyer, address currency, uint256 amount)
Critical admin functions rescueTokens, rescueETH, addCurrency, addComplication, removeCurrency, removeComplication and updateMatchExecutor should emit events
[L-04] Solidity version
You are currently using solidity 0.8.14, best recommendation is to switch to 0.8.15 two major bugs introduced on previus versions were fixes, plus its more gas efficient.
QA
[Q-01] Use a wider uncheck
In some code blocks you use a lot of uncheckeds scopes, a cleanner pattern would be to use a wider unchecked scope.
InfinityOrderBookComplication.sol
[Q-02] Use a common pattern
On
InfinityExchange.sol#L1128
the signature of the function isfunction _transferFees(address seller, address buyer, uint256 amount, address currency)
I recommend you to change it to a more common pattern;function _transferFees(address seller, address buyer, address currency, uint256 amount)
[Q-03] Struct definition is never use
On OrderTypes.sol#L46-L48 the struct
TakerOrder
is never used[Q-04] Natspect typo, weth should be uppercase
on
InfinityExchange.sol#L859
the comment is;And should be
Non-critical
[N-01] UNUSED IMPORT
IStaker.sol
In IStaker.sol, the
import {OrderTypes} from '../libs/OrderTypes.sol';
is unusedInfinityOrderBookComplication.sol
Import Ownable on
InfinityOrderBookComplication.sol
InfinityOrderBookComplication
contract is importingOwnable
but no one is using it. My recommendation is to remove it.[N-02] DECLARE AS
IERC20
In InfinityStaker.sol:L25, declare
INFINITY_TOKEN
asIERC20
would avoid it cast toIERC20
when use it and improve code clarity:Cast in the constructor, or declare
_tokenAddress
asIERC20
Remove cast on:
[N-03] NOT DECLARE VISIBILITY
In TimelockConfig.sol, L28, L29, L31, L32: By default, the visibility of variables in solidity is
internal
, but it is good practice to declare it.[N-04] TYPO
In InfinityExchange.sol:
* @param weth weth address
to* @param weth WETH address
updateWethTranferGas
toupdateWethTransferGas
Low Risk
[L-01] EVENTS ARE NOT INDEXED
The emitted events are not indexed, making off-chain scripts such as front-ends of dApps difficult to filter the events efficiently.
Recommended Mitigation Steps: Add the
indexed
keyword in filter parameters of the eventsInstances include:
[L-02]
require
NEVER REVERTIn InfinityStaker.sol, L193: This
require
never reverts the transaction, any number ofuint256
data type it's greater or equal to 0, by definitionRemove the equal in the
require
comparation[L-02] Unnecesary math operations
Unnecesary multiplication by one and unnecesary exponetiation.
InfinityStaker.sol
InfinityExchange.sol
InfinityOrderBookComplication.sol
[L-03] No event emmision on critical function
InfinityStaker.sol
InfinityStaker.sol#L351 function
updateStakeLevelThreshold
should emit event InfinityStaker.sol#L364 functionupdatePenalties
should emit event InfinityStaker.sol#L375 functionupdateInfinityTreasury
should emit eventInfinityExchange.sol
InfinityExchange.sol
Critical admin functions
rescueTokens
,rescueETH
,addCurrency
,addComplication
,removeCurrency
,removeComplication
andupdateMatchExecutor
should emit events[L-04] Solidity version
You are currently using solidity 0.8.14, best recommendation is to switch to 0.8.15 two major bugs introduced on previus versions were fixes, plus its more gas efficient.