Platform: Code4rena
Start Date: 17/07/2023
Pot Size: $85,500 USDC
Total HM: 11
Participants: 26
Period: 14 days
Judge: Picodes
Total Solo HM: 1
Id: 263
League: ETH
Rank: 19/26
Findings: 1
Award: $31.38
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: MiloTruck
Also found by: 0xAnah, AlexCzm, Bughunter101, BugzyVonBuggernaut, DavidGiladi, Emmanuel, Iurii3, Kaysoft, MohammedRizwan, Prestige, Rolezn, Sathish9098, Stormreckson, adeolu, descharre, evmboi32, fatherOfBlocks, ginlee, ihtishamsudo, juancito, mrudenko, tnquanghuy0512
31.3772 USDC - $31.38
In MigrationLib.sol
There is an external call to the initializeFollowModule
function of the IFollowModule
contract, which is invoked for each profileId
in function batchMigrateFollowModules
.
The external call could consume a significant amount of gas, and processing a large array of profileIds
could results in a considerable gas cost or function may exceed block gas limit.
IFollowModule(newFeeFollowModule).initializeFollowModule({ profileId: profileIds[i], transactionExecutor: msg.sender, data: abi.encode( feeFollowModuleData.currency, feeFollowModuleData.amount, feeFollowModuleData.recipient ) });
MigrationLib.sol#L141-L175 FollowLib.sol#L54-L81
Manual Review / Solidity Visual Developer
Functions having external calls in loop can batch multiple profileIds per transaction, estimating gas usage before making external calls, and thoroughly testing under various scenarios.
Using Block.timestamp
is not a good practice and must be avoided because it can easily be manipulated by attackers
By manipulating Block.timestamp
attackers can break functionality of smart contract.
function _hasTokenGuardianEnabled(address wallet) internal view returns (bool) { return !wallet.isContract() && (StorageLib.tokenGuardianDisablingTimestamp()[wallet] == 0 || block.timestamp < StorageLib.tokenGuardianDisablingTimestamp()[wallet]); }
LensProfiles.sol#L142-L147 LensHandles.sol#L149 LensHandles.sol#L253 LensHandles.sol#L266
Manual Detection
Avoid Relying on block.timestamp
Uninitialized state variables.
mapping(uint256 id => address actionModule) internal _actionModules
is never initialized but used in LensHub.getActionModuleById
as below
function getActionModuleById(uint256 id) external view override returns (address) { return _actionModules[id]; }
LensHubStorage.sol#L61 LensHub.sol#L567
Static Analyzer
Initialize all the variables. If a variable is meant to be initialized to zero, explicitly set it to zero to improve code readability.
mapping(address => mapping(uint256 => uint256)) private __DEPRECATED__ownedTokens is not mixedCase
#0 - c4-judge
2023-08-28T20:40:06Z
Picodes marked the issue as grade-b
#1 - Picodes
2023-08-28T20:40:19Z
Grade-b for #61