Skip to content

Instantly share code, notes, and snippets.

@thebrittfactor
Created July 19, 2023 12:37
Show Gist options
  • Save thebrittfactor/3dc2ed1320de95e111a25c1744f4d33e to your computer and use it in GitHub Desktop.
Save thebrittfactor/3dc2ed1320de95e111a25c1744f4d33e to your computer and use it in GitHub Desktop.
0x6980-bot-lens.md

Report

Medium Risk Issues

Issue Instances
M-01 approve()/safeApprove() may revert if the current approval is not zero 2
M-02 Condition will not revert when block.timestamp is == to the compared variable 1
M-03 Centralization Risk for trusted owners 16
M-04 No limits when setting fees 1
M-05 Re-org attack 1
M-06 _safeMint() should be used rather than _mint() wherever possible 4
M-07 Overflow 30
Total: 55 instances over 7 issues

Low Risk Issues

Issue Instances
L-01 Enum values should be used in place of constant array indexes 2
L-02 Missing checks for address(0) in function when assigning values to address state variables 4
L-03 address shouldn't be hard-coded 1
L-04 Add to denylist function 5
L-05 Array lengths not checked 27
L-06 File allows a version of solidity that is susceptible to an assembly optimizer bug 2
L-07 Burn functions should be protected with a modifier 8
L-08 Missing zero address check in constructor 19
L-09 Initializers can be front-run 2
L-10 Int casting block.timestamp can reduce the lifespan of a contract 3
L-11 Loss of precision 2
L-12 Missing checks for ecrecover() signature malleability 1
L-13 Missing contract-existence checks before low-level calls 1
L-14 Missing limits when setting min/max amounts 6
L-15 NFT doesn't handle hard forks 4
L-16 Owner can renounce Ownership 9
L-17 Contracts are not using their OZ Upgradeable counterparts 31
L-18 Solidity version 0.8.20 may not work on other chains due to PUSH0 63
L-19 Storage Write Removal Bug On Conditional Early Termination 12
L-20 tokenURI() does not follow EIP-721 4
L-21 Unsafe downcast 3
L-22 Unsafe ERC20 operation(s) 4
L-23 Unspecific compiler version pragma 30
L-24 TransferOwnership Should Be Two Step 1
L-25 Use Ownable2Step rather than Ownable 1
L-26 Using zero as a parameter 8
L-27 Vulnerable versions of packages are being used 1
Total: 254 instances over 27 issues

Non-critical Issues

Issue Instances
N-01 Large assembly blocks should have extensive comments 35
N-02 abi.encodePacked() should not be used with dynamic types when passing the result to a hash function such as keccak256() 8
N-03 Avoid the use of sensitive terms 319
N-04 Variable names that consist of all capital letters should be reserved for constant/immutable variables 1
N-05 Cast to bytes or bytes32 for clearer semantic meaning 9
N-06 Consider disabling renounceOwnership() 9
N-07 Consider using delete rather than assigning zero to clear values 2
N-08 Consider using named mappings 31
N-09 Consistent usage of require vs custom error 10
N-10 constant/immutable variable names should use capital letters and underscore 8
N-11 Constants in comparisons should appear on the left side 58
N-12 Contract implements interface without extending the interface 1
N-13 Custom error has no error details 63
N-14 Empty Function Body - Consider commenting why 2
N-15 Events are missing sender information 42
N-16 Events that mark critical parameter changes should contain both the old and the new value 2
N-17 Events may be emitted out of order due to reentranc 10
N-18 It is standard for all external and public functions to be override from an interface 230
N-19 Function names should differ to make the code more readable 8
N-20 Some variables have a implicit default visibility 53
N-21 Imports could be organized more systematically 34
N-22 Inconsistent spacing in comments 4
N-23 Large or complicated code bases should implement invariant tests 10
N-24 Lines are too long 28
N-25 Long functions should be refactored into multiple functions 4
N-26 NatSpec documentation for contract is missing 32
N-27 NatSpec documentation for function is missing 207
N-28 Use @inheritdoc rather than using a non-standard annotation 54
N-29 NatSpec @param is missing 348
N-30 NatSpec @return is missing 299
N-31 Non-external function names (private or internal.) should begin with an underscore 39
N-32 Non-external variable (private or internal.) should begin with an underscore 17
N-33 Not using the named return variables anywhere in the function is confusing 19
N-34 Overly complicated arithmetic 8
N-35 Public functions not called internally 2
N-36 require() / revert() statements should have descriptive reason strings 115
N-37 Return values of approve() not checked 3
N-38 Strings should use double quotes rather than single quotes 45
N-39 Contract does not follow the Solidity style guide's suggested layout ordering 28
N-40 Function ordering does not follow the Solidity style guide 15
N-41 Contracts should have full test coverage 10
N-42 TODO Left in the code 4
N-43 Event is missing indexed fields 38
N-44 Unused contract variables 39
N-45 Unused error definition 60
N-46 Unused file 44
N-47 Unused parameter 16
N-48 Unused structs 14
N-49 Use abi.encodeCall() instead of abi.encodeSignature()/abi.encodeSelector() 1
N-50 Use bytes.concat() on bytes instead of abi.encodePacked() for clearer semantic 13
N-51 Constants should be defined rather than using magic numbers 2
N-52 Non-library/interface files should use fixed compiler versions, not floating ones 22
N-53 Expressions for constant values such as a call to keccak256(), should use immutable rather than constant 17
N-54 Functions not used internally could be marked external 17
N-55 Use a more recent version of solidity 2
N-56 Use named function calls 1
N-57 Critical Changes Should Use Two-step Procedure 18
N-58 Large numeric literals should use underscores for readability 2
N-59 Using underscore at the end of variable name 13
N-60 Consider implementing two-step procedure for updating protocol addresses 7
N-61 Do not calculate constants 17
N-62 Public functions not used internally can be marked as external to save gas 2
N-63 Use assembly to calculate hashes to save gas 43
N-64 bytes.concat() can be used instead of abi.encodePacked 13
N-65 Reduce gas usage by moving to Solidity 0.8.19 or later 31
Total: 2658 instances over 65 issues
s

Medium Risk Issues

[M-01] approve()/safeApprove() may revert if the current approval is not zero

Calling approve() without first calling approve(0) if the current approval is non-zero will revert with some tokens, such as Tether (USDT). While Tether is known to do this, it applies to other tokens as well, which are trying to protect against this attack vector. safeApprove() itself also implements this protection. Always reset the approval to zero before changing it to a new value, or use safeIncreaseAllowance()/safeDecreaseAllowance()

Instances (2):

File: contracts/base/LensProfiles.sol

117:         super.approve(to, tokenId);

117,

File: contracts/namespaces/LensHandles.sol

144:         super.approve(to, tokenId);

144,

[M-02] Condition will not revert when block.timestamp is == to the compared variable

The condition does not revert when block.timestamp is equal to the compared > or < variable. For example, if there is a check for block.timestamp > identifier then there should be a check for cases where block.timestamp is == to identifier

Instances (1):

File: contracts/libraries/MetaTxLib.sol

470:         if (signature.deadline < block.timestamp) revert Errors.SignatureExpired();

470,

[M-03] Centralization Risk for trusted owners

Impact:

Contracts have owners with privileged rights to perform admin tasks and need to be trusted to not perform malicious updates or drain funds.

Instances (16):

see instances
File: contracts/misc/ImmutableOwnable.sol

5: contract ImmutableOwnable {

5,

File: contracts/misc/LensV2UpgradeContract.sol

9: contract LensV2UpgradeContract is ImmutableOwnable {

32:     ) ImmutableOwnable(owner, lensHub) {

44:     function executeLensV2Upgrade() external onlyOwner {

9, 32, 44,

File: contracts/misc/ProfileCreationProxy.sol

19: contract ProfileCreationProxy is ImmutableOwnable {

28:     ) ImmutableOwnable(owner, hub) {

64:     function proxyCreateHandle(address to, string calldata handle) external onlyOwner returns (uint256) {

19, 28, 64,

File: contracts/misc/access/ControllableByContract.sol

7: contract ControllableByContract is Ownable {

21:     constructor(address owner) Ownable() {

30:     function setControllerContract(address newControllerContract) external onlyOwner {

7, 21, 30,

File: contracts/misc/access/Governance.sol

23:     function lensHub_setGovernance(address newGovernance) external onlyOwner {

27:     function lensHub_setEmergencyAdmin(address newEmergencyAdmin) external onlyOwner {

23, 27,

File: contracts/misc/access/ProxyAdmin.sol

29:     function rollbackLastUpgrade() external onlyOwner {

33:     function proxy_changeAdmin(address newAdmin) external onlyOwner {

29, 33,

File: contracts/namespaces/LensHandles.sol

25: contract LensHandles is ERC721, ImmutableOwnable, ILensHandles {

66:     ) ERC721('', '') ImmutableOwnable(owner, lensHub) {

25, 66,

[M-04] No limits when setting fees

When settings fees state variables, ensure there a require checks in place to prevent incorrect values from being set. This is particularly important when dealing with fee values as without checks fees can be set to 100%

Instances (1):

File: contracts/misc/ModuleGlobals.sol

60:     function setTreasuryFee(uint16 newTreasuryFee) external override onlyGov {
61:            _setTreasuryFee(newTreasuryFee);
62:        }

60,

[M-05] Re-org attack

Re-orgs can happen in all EVM chains. In ethereum, where currently Frankencoin is deployed, it is not “super common” but it still happens, being the last one less than a year ago: ethereum-beacon-chain-blockchain-reorg The issue increases the changes of happening if deploying on L2’s/ rollups. where re-orgs have been much more active: polygon-hit-by-157-block-reorg-despite-hard-fork-to-reduce-reorgs being the last one, less than a year ago. Deploy the cloned Contract via create2 with a specific salt that includes msg.sender and address _existing

Instances (1):

File: contracts/libraries/FollowLib.sol

92:         address followNFT = address(new FollowNFTProxy(functionData));

92,

[M-06] _safeMint() should be used rather than _mint() wherever possible

_mint() is discouragedin favor of _safeMint() which ensures that the recipient is either an EOA or implements IERC721Receiver. Both OpenZeppelinand solmatehave versions of this function

Instances (4):

File: contracts/FollowNFT.sol

184:         _mint(wrappedTokenReceiver == address(0) ? followerProfileOwner : wrappedTokenReceiver, followTokenId);

202:                 _mint(IERC721(HUB).ownerOf(followerProfileId), followTokenId);

184, 202,

File: contracts/misc/LegacyCollectNFT.sol

59:             _mint(to, tokenId);

59,

File: contracts/namespaces/LensHandles.sol

196:         _mint(to, tokenId);

196,

[M-07] Overflow

manual check needed

Instances (30):

see instances
File: contracts/LensHub.sol

96:         unchecked {

96,

File: contracts/FollowNFT.sol

299:         unchecked {

361:         unchecked {

378:             unchecked {

417:         unchecked {

506:         unchecked {

299, 361, 378, 417, 506,

File: contracts/libraries/FollowLib.sol

47:             unchecked {

77:             unchecked {

47, 77,

File: contracts/libraries/MetaTxLib.sol

165:             unchecked {

332:             unchecked {

504:         unchecked {

165, 332, 504,

File: contracts/libraries/MigrationLib.sol

45:             unchecked {

108:             unchecked {

171:             unchecked {

45, 108, 171,

File: contracts/libraries/ProfileLib.sol

160:             unchecked {

241:             unchecked {

160, 241,

File: contracts/libraries/PublicationLib.sol

511:             unchecked {

511,

File: contracts/libraries/ValidationLib.sol

114:             unchecked {

114,

File: contracts/base/LensBaseERC721.sol

360:         unchecked {

388:         unchecked {

425:         unchecked {

360, 388, 425,

File: contracts/misc/LegacyCollectNFT.sol

57:         unchecked {

57,

File: contracts/misc/LensV2UpgradeContract.sol

69:             unchecked {

80:             unchecked {

91:             unchecked {

102:             unchecked {

113:             unchecked {

124:             unchecked {

69, 80, 91, 102, 113, 124,

File: contracts/namespaces/LensHandles.sol

220:             unchecked {

243:             unchecked {

220, 243,

Low Risk Issues

[L-01] Enum values should be used in place of constant array indexes

Create a commented enum value to use in place of constant array indexes, this makes the code far easier to understand

Instances (2):

File: contracts/namespaces/LensHandles.sol

210:         bytes1 firstByte = localNameAsBytes[0];

234:         if (localNameAsBytes[0] == '_') {

210, 234,

[L-02] Missing checks for address(0) in function when assigning values to address state variables

Instances (4):

File: contracts/libraries/StorageLib.sol

195:             sstore(GOVERNANCE_SLOT, newGovernance)

207:             sstore(EMERGENCY_ADMIN_SLOT, newEmergencyAdmin)

195, 207,

File: contracts/base/LensBaseERC721.sol

440:         _tokenApprovals[tokenId] = to;

440,

File: contracts/misc/access/ControllableByContract.sol

32:         controllerContract = newControllerContract;

32,

[L-03] address shouldn't be hard-coded

It is often better to declare addresses as immutable, and assign them via constructor arguments. This allows the code to remain the same across deployments on different networks, and avoids recompilation when addresses need to change.

Instances (1):

File: contracts/libraries/MetaTxLib.sol

41:     address constant LENS_HUB_ADDRESS = 0xDb46d1Dc155634FbC732f92E853b10B288AD5a1d;

41,

[L-04] Add to denylist function

NFT thefts have increased recently, so with the addition of hacked NFTs to the platform, NFTs can be converted into liquidity. To prevent this, I recommend adding the denylist function.

Marketplaces such as Opensea have a denylist feature that will not list NFTs that have been reported theft, NFT projects such as Manifold have denylist functions in their smart contracts.

Here is the project example; Manifold

Manifold Contract

modifier nonDenylistRequired(address extension) {
   require(!_denylistedExtensions.contains(extension), "Extension denylisted");
    _;
}

Instances (5):

File: contracts/FollowNFT.sol

/// @audit Add to Denylist function and modifier.
1: // SPDX-License-Identifier: MIT

1,

File: contracts/base/LensBaseERC721.sol

/// @audit Add to Denylist function and modifier.
1: // SPDX-License-Identifier: MIT

1,

File: contracts/misc/LegacyCollectNFT.sol

/// @audit Add to Denylist function and modifier.
1: // SPDX-License-Identifier: MIT

1,

File: contracts/namespaces/LensHandles.sol

/// @audit Add to Denylist function and modifier.
1: // SPDX-License-Identifier: MIT

1,

File: contracts/interfaces/ILensERC721.sol

/// @audit Add to Denylist function and modifier.
1: // SPDX-License-Identifier: MIT

1,

[L-05] Array lengths not checked

If the length of the arrays are not required to be of the same length, user operations may not be fully executed due to a mismatch in the number of items iterated over, versus the number of items provided in the second array

Instances (27):

see instances
File: contracts/LensHub.sol

149:     function changeDelegatedExecutorsConfig(
150:             uint256 delegatorProfileId,
151:             address[] calldata delegatedExecutors,
152:             bool[] calldata approvals,
153:             uint64 configNumber,
154:             bool switchToGivenConfig
155:         ) external override whenNotPaused onlyProfileOwner(msg.sender, delegatorProfileId) {

165:     function changeDelegatedExecutorsConfig(
166:             uint256 delegatorProfileId,
167:             address[] calldata delegatedExecutors,
168:             bool[] calldata approvals
169:         ) external override whenNotPaused onlyProfileOwner(msg.sender, delegatorProfileId) {

174:     function changeDelegatedExecutorsConfigWithSig(
175:             uint256 delegatorProfileId,
176:             address[] calldata delegatedExecutors,
177:             bool[] calldata approvals,
178:             uint64 configNumber,
179:             bool switchToGivenConfig,
180:             Types.EIP712Signature calldata signature
181:         ) external override whenNotPaused onlyProfileOwner(signature.signer, delegatorProfileId) {

320:     function follow(
321:             uint256 followerProfileId,
322:             uint256[] calldata idsOfProfilesToFollow,
323:             uint256[] calldata followTokenIds,
324:             bytes[] calldata datas
325:         )
326:             external
327:             override
328:             whenNotPaused
329:             onlyProfileOwnerOrDelegatedExecutor(msg.sender, followerProfileId)
330:             returns (uint256[] memory)
331:         {

343:     function followWithSig(
344:             uint256 followerProfileId,
345:             uint256[] calldata idsOfProfilesToFollow,
346:             uint256[] calldata followTokenIds,
347:             bytes[] calldata datas,
348:             Types.EIP712Signature calldata signature
349:         )
350:             external
351:             override
352:             whenNotPaused
353:             onlyProfileOwnerOrDelegatedExecutor(signature.signer, followerProfileId)
354:             returns (uint256[] memory)
355:         {

397:     function setBlockStatus(
398:             uint256 byProfileId,
399:             uint256[] calldata idsOfProfilesToSetBlockStatus,
400:             bool[] calldata blockStatus
401:         ) external override whenNotPaused onlyProfileOwnerOrDelegatedExecutor(msg.sender, byProfileId) {

406:     function setBlockStatusWithSig(
407:             uint256 byProfileId,
408:             uint256[] calldata idsOfProfilesToSetBlockStatus,
409:             bool[] calldata blockStatus,
410:             Types.EIP712Signature calldata signature
411:         ) external override whenNotPaused onlyProfileOwnerOrDelegatedExecutor(signature.signer, byProfileId) {

149, 165, 174, 320, 343, 397, 406,

File: contracts/libraries/FollowLib.sol

15:     function follow(
16:            uint256 followerProfileId,
17:            address transactionExecutor,
18:            uint256[] calldata idsOfProfilesToFollow,
19:            uint256[] calldata followTokenIds,
20:            bytes[] calldata followModuleDatas
21:        ) external returns (uint256[] memory) {

15,

File: contracts/libraries/MetaTxLib.sol

87:     function validateChangeDelegatedExecutorsConfigSignature(
88:            Types.EIP712Signature calldata signature,
89:            uint256 delegatorProfileId,
90:            address[] calldata delegatedExecutors,
91:            bool[] calldata approvals,
92:            uint64 configNumber,
93:            bool switchToGivenConfig
94:        ) external {

320:     function validateFollowSignature(
321:             Types.EIP712Signature calldata signature,
322:             uint256 followerProfileId,
323:             uint256[] calldata idsOfProfilesToFollow,
324:             uint256[] calldata followTokenIds,
325:             bytes[] calldata datas
326:         ) external {

378:     function validateSetBlockStatusSignature(
379:             Types.EIP712Signature calldata signature,
380:             uint256 byProfileId,
381:             uint256[] calldata idsOfProfilesToSetBlockStatus,
382:             bool[] calldata blockStatus
383:         ) external {

87, 320, 378,

File: contracts/libraries/MigrationLib.sol

94:     function batchMigrateFollows(
95:            uint256[] calldata followerProfileIds,
96:            uint256[] calldata idsOfProfileFollowed,
97:            uint256[] calldata followTokenIds
98:        ) external {

94,

File: contracts/libraries/ProfileLib.sol

128:     function setBlockStatus(
129:             uint256 byProfileId,
130:             uint256[] calldata idsOfProfilesToSetBlockStatus,
131:             bool[] calldata blockStatus
132:         ) external {

180:     function changeDelegatedExecutorsConfig(
181:             uint256 delegatorProfileId,
182:             address[] calldata delegatedExecutors,
183:             bool[] calldata approvals
184:         ) external {

198:     function changeGivenDelegatedExecutorsConfig(
199:             uint256 delegatorProfileId,
200:             address[] calldata delegatedExecutors,
201:             bool[] calldata approvals,
202:             uint64 configNumber,
203:             bool switchToGivenConfig
204:         ) external {

222:     function _changeDelegatedExecutorsConfig(
223:             Types.DelegatedExecutorsConfig storage _delegatedExecutorsConfig,
224:             uint256 delegatorProfileId,
225:             address[] memory delegatedExecutors,
226:             bool[] memory approvals,
227:             uint64 configNumber,
228:             bool switchToGivenConfig
229:         ) private {

128, 180, 198, 222,

File: contracts/libraries/PublicationLib.sol

472:     function _initPubActionModules(
473:             uint256 profileId,
474:             address transactionExecutor,
475:             uint256 pubId,
476:             address[] calldata actionModules,
477:             bytes[] calldata actionModulesInitDatas
478:         ) private returns (bytes[] memory) {

472,

File: contracts/libraries/ValidationLib.sol

87:     function validateReferrersAndGetReferrersPubTypes(
88:            uint256[] memory referrerProfileIds,
89:            uint256[] memory referrerPubIds,
90:            uint256 targetedProfileId,
91:            uint256 targetedPubId
92:        ) internal view returns (Types.PublicationType[] memory) {

87,

File: contracts/misc/LensV2Migration.sol

37:     function batchMigrateFollows(
38:            uint256[] calldata followerProfileIds,
39:            uint256[] calldata idsOfProfileFollowed,
40:            uint256[] calldata followTokenIds
41:        ) external {

37,

File: contracts/misc/LensV2UpgradeContract.sol

20:     constructor(
21:            address proxyAdminAddress,
22:            address governanceAddress,
23:            address owner,
24:            address lensHub,
25:            address newImplementationAddress,
26:            address[] memory oldFollowModulesToUnwhitelist_,
27:            address[] memory newFollowModulesToWhitelist_,
28:            address[] memory oldReferenceModulesToUnwhitelist_,
29:            address[] memory newReferenceModulesToWhitelist_,
30:            address[] memory oldCollectModulesToUnwhitelist_,
31:            address[] memory newActionModulesToWhitelist_
32:        ) ImmutableOwnable(owner, lensHub) {

20,

File: contracts/interfaces/ILensProtocol.sol

77:     function changeDelegatedExecutorsConfig(

93:     function changeDelegatedExecutorsConfig(

102:     function changeDelegatedExecutorsConfigWithSig(

230:     function follow(

240:     function followWithSig(

279:     function setBlockStatus(

288:     function setBlockStatusWithSig(

77, 93, 102, 230, 240, 279, 288,

[L-06] File allows a version of solidity that is susceptible to an assembly optimizer bug

In solidity versions 0.8.13 and 0.8.14, there is an optimizer bug where, if the use of a variable is in a separate assembly block from the block in which it was stored, the mstore operation is optimized out, leading to uninitialized memory. The code currently does not have such a pattern of execution, but it does use mstores in assembly blocks, so it is a risk for future changes. The affected solidity versions should be avoided if at all possible.

Instances (2):

File: contracts/base/ERC2981CollectionRoyalties.sol

60:         assembly {
61:                sstore(royaltiesInBasisPointsSlot, royaltiesInBasisPoints)
62:            }

60,

File: contracts/base/LensBaseERC721.sol

482:                     assembly {
483:                             revert(add(32, reason), mload(reason))
484:                         }

482,

[L-07] Burn functions should be protected with a modifier

Instances (8):

see instances
File: contracts/FollowNFT.sol

255:     function burn(uint256 followTokenId) public override {

341:     function _followWithUnwrappedTokenFromBurnedProfile(

255, 341,

File: contracts/libraries/MetaTxLib.sol

309:     function validateBurnSignature(Types.EIP712Signature calldata signature, uint256 tokenId) external {

309,

File: contracts/base/LensBaseERC721.sol

264:     function burn(uint256 tokenId) public virtual override {

380:     function _burn(uint256 tokenId) internal virtual {

264, 380,

File: contracts/namespaces/LensHandles.sol

101:     function burn(uint256 tokenId) external {

101,

File: contracts/interfaces/IERC721Burnable.sol

18:     function burn(uint256 tokenId) external;

18,

File: contracts/interfaces/ILensHandles.sol

33:     function burn(uint256 tokenId) external;

33,

[L-08] Missing zero address check in constructor

Instances (19):

see instances
File: contracts/base/HubRestricted.sol

25:         HUB = hub;

25,

File: contracts/base/LensImplGetters.sol

12:         FOLLOW_NFT_IMPL = followNFTImpl;

13:         __LEGACY__COLLECT_NFT_IMPL = collectNFTImpl;

12, 13,

File: contracts/base/LensProfiles.sol

34:         MODULE_GLOBALS = IModuleGlobals(moduleGlobals);

34,

File: contracts/misc/ImmutableOwnable.sol

27:         OWNER = owner;

28:         LENS_HUB = lensHub;

27, 28,

File: contracts/misc/LensV2Migration.sol

26:         FEE_FOLLOW_MODULE = legacyFeeFollowModule;

27:         PROFILE_FOLLOW_MODULE = legacyProfileFollowModule;

28:         NEW_FEE_FOLLOW_MODULE = newFeeFollowModule;

29:         lensHandles = LensHandles(lensHandlesAddress);

30:         tokenHandleRegistry = TokenHandleRegistry(tokenHandleRegistryAddress);

26, 27, 28, 29, 30,

File: contracts/misc/LensV2UpgradeContract.sol

33:         PROXY_ADMIN = ProxyAdmin(proxyAdminAddress);

34:         GOVERNANCE = Governance(governanceAddress);

35:         newImplementation = newImplementationAddress;

33, 34, 35,

File: contracts/misc/ProfileCreationProxy.sol

29:         LENS_HANDLES = ILensHandles(lensHandles);

30:         TOKEN_HANDLE_REGISTRY = ITokenHandleRegistry(tokenHandleRegistry);

29, 30,

File: contracts/misc/access/ProxyAdmin.sol

18:         previousImplementation = previousImplementation_;

18,

File: contracts/namespaces/TokenHandleRegistry.sol

43:         LENS_HUB = lensHub;

44:         LENS_HANDLES = lensHandles;

43, 44,

[L-09] Initializers can be front-run

Initializers can be front-run, allowing an attacker to either set their own values, take ownership of the contract, and in the best case forcing a re-deployment

Instances (2):

File: contracts/FollowNFT.sol

48:     function initialize(uint256 profileId) external override {

48,

File: contracts/misc/LegacyCollectNFT.sol

45:     function initialize(uint256 profileId, uint256 pubId) external override {

45,

[L-10] Int casting block.timestamp can reduce the lifespan of a contract

Consider removing casting to ensure future functionality.

Instances (3):

File: contracts/FollowNFT.sol

393:         _followDataByFollowTokenId[followTokenId].followTimestamp = uint48(block.timestamp);

396:             _followDataByFollowTokenId[followTokenId].originalFollowTimestamp = uint48(block.timestamp);

393, 396,

File: contracts/base/LensBaseERC721.sol

365:         _tokenData[tokenId].mintTimestamp = uint96(block.timestamp);

365,

[L-11] Loss of precision

Division by large numbers may result in the result being zero, due to solidity not supporting fractions. Consider requiring a minimum amount for the numerator to ensure that it is always larger than the denominator

Instances (2):

File: contracts/base/ERC2981CollectionRoyalties.sol

55:         return (salePrice * _loadRoyaltiesInBasisPoints()) / BASIS_POINTS;

55,

File: contracts/misc/ModuleGlobals.sol

109:         if (newTreasuryFee >= BPS_MAX / 2) revert Errors.InitParamsInvalid();

109,

[L-12] Missing checks for ecrecover() signature malleability

ecrecover() accepts as valid, two versions of signatures, meaning an attacker can use the same signature twice, or an attacker may be able to front-run the original signer with the altered version of the signature, causing the signer's transaction to revert due to nonce reuse. Consider adding checks for signature malleability, or using OpenZeppelin's ECDSA library to perform the extra checks necessary in order to prevent malleability.

Instances (1):

File: contracts/libraries/MetaTxLib.sol

478:             address recoveredAddress = ecrecover(digest, signature.v, signature.r, signature.s);

478,

[L-13] Missing contract-existence checks before low-level calls

Low-level calls return success if there is no code present at the specified address.

Instances (1):

File: contracts/misc/access/Governance.sol

/// @audit executeAsGovernance()
82:         (bool success, bytes memory returnData) = target.call{gas: gasleft(), value: msg.value}(data);

82,

[L-14] Missing limits when setting min/max amounts

There are some missing limits in these functions, and this could lead to unexpected scenarios. Consider adding a min/max limit for the following values, when appropriate.

Instances (6):

File: contracts/FollowNFT.sol

48:     function initialize(uint256 profileId) external override {

386:     function _baseFollow(

428:     function _approveFollow(uint256 approvedProfileId, uint256 followTokenId) internal {

480:     function tryMigrate(

48, 386, 428, 480,

File: contracts/misc/LegacyCollectNFT.sol

45:     function initialize(uint256 profileId, uint256 pubId) external override {

45:     function initialize(uint256 profileId, uint256 pubId) external override {

45, 45,

[L-15] NFT doesn't handle hard forks

When there are hard forks, users often have to go through many hoops to ensure that they control ownership on every fork. Consider adding require(1 == chain.chainId), or the chain ID of whichever chain you prefer, to the functions below, or at least include the chain ID in the URI, so that there is no confusion about which chain is the owner of the NFT.

Instances (4):

File: contracts/FollowNFT.sol

285:     function tokenURI(uint256 followTokenId) public view override returns (string memory) {
286:             if (!_exists(followTokenId)) {
287:                 revert Errors.TokenDoesNotExist();
288:             }
289:             return
290:                 FollowTokenURILib.getTokenURI(
291:                     followTokenId,
292:                     _followedProfileId,
293:                     _followDataByFollowTokenId[followTokenId].originalFollowTimestamp
294:                 );
295:         }

285,

File: contracts/base/LensProfiles.sol

105:     function tokenURI(uint256 tokenId) public view override(LensBaseERC721, IERC721Metadata) returns (string memory) {
106:             if (!_exists(tokenId)) {
107:                 revert Errors.TokenDoesNotExist();
108:             }
109:             return ProfileTokenURILib.getTokenURI(tokenId);
110:         }

105,

File: contracts/misc/LegacyCollectNFT.sol

69:     function tokenURI(uint256 tokenId) public view override returns (string memory) {
70:            if (!_exists(tokenId)) revert Errors.TokenDoesNotExist();
71:            return ILensHub(HUB).getContentURI(_profileId, _pubId);
72:        }

69,

File: contracts/namespaces/LensHandles.sol

81:     function tokenURI(uint256 tokenId) public view override returns (string memory) {
82:            _requireMinted(tokenId);
83:            return HandleTokenURILib.getTokenURI(tokenId, _localNames[tokenId]);
84:        }

81,

[L-16] Owner can renounce Ownership

The Openzeppelin’s Ownable used in this project contract implements renounceOwnership. This can represent a certain risk if the ownership is renounced for any other reason than by design. Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner.

Instances (9):

see instances
File: contracts/misc/LensV2UpgradeContract.sol

9: contract LensV2UpgradeContract is ImmutableOwnable {

9,

File: contracts/misc/ProfileCreationProxy.sol

19: contract ProfileCreationProxy is ImmutableOwnable {

19: contract ProfileCreationProxy is ImmutableOwnable {

19: contract ProfileCreationProxy is ImmutableOwnable {

19, 19, 19,

File: contracts/misc/access/ControllableByContract.sol

7: contract ControllableByContract is Ownable {

7,

File: contracts/misc/access/Governance.sol

12: contract Governance is ControllableByContract {

12: contract Governance is ControllableByContract {

12, 12,

File: contracts/misc/access/ProxyAdmin.sol

8: contract ProxyAdmin is ControllableByContract {

8: contract ProxyAdmin is ControllableByContract {

8, 8,

[L-17] Contracts are not using their OZ Upgradeable counterparts

The non-upgradeable standard version of OpenZeppelin’s library are inherited / used by the contracts. It would be safer to use the upgradeable versions of the library contracts to avoid unexpected behaviour.

Where applicable, use the contracts from @openzeppelin/contracts-upgradeable instead of @openzeppelin/contracts. See this for list of available upgradeable contracts

Instances (31):

see instances
File: contracts/FollowNFT.sol

9: import {IERC721} from '@openzeppelin/contracts/token/ERC721/IERC721.sol';

14: import {Strings} from '@openzeppelin/contracts/utils/Strings.sol';

9, 14,

File: contracts/libraries/LegacyCollectLib.sol

11: import {Clones} from '@openzeppelin/contracts/proxy/Clones.sol';

12: import {Strings} from '@openzeppelin/contracts/utils/Strings.sol';

11, 12,

File: contracts/libraries/MetaTxLib.sol

4: import {IERC1271} from '@openzeppelin/contracts/interfaces/IERC1271.sol';

4,

File: contracts/base/ERC2981CollectionRoyalties.sol

6: import {IERC165} from '@openzeppelin/contracts/utils/introspection/IERC165.sol';

7: import {IERC2981} from '@openzeppelin/contracts/interfaces/IERC2981.sol';

6, 7,

File: contracts/base/LensBaseERC721.sol

12: import {IERC721Receiver} from '@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol';

13: import {IERC721Metadata} from '@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol';

14: import {Address} from '@openzeppelin/contracts/utils/Address.sol';

15: import {Strings} from '@openzeppelin/contracts/utils/Strings.sol';

16: import {ERC165} from '@openzeppelin/contracts/utils/introspection/ERC165.sol';

17: import {IERC165} from '@openzeppelin/contracts/utils/introspection/IERC165.sol';

18: import {IERC721} from '@openzeppelin/contracts/token/ERC721/IERC721.sol';

12, 13, 14, 15, 16, 17, 18,

File: contracts/base/LensProfiles.sol

5: import {IERC721} from '@openzeppelin/contracts/token/ERC721/IERC721.sol';

6: import {IERC721Metadata} from '@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol';

7: import {IERC165} from '@openzeppelin/contracts/utils/introspection/IERC165.sol';

24: import {Address} from '@openzeppelin/contracts/utils/Address.sol';

5, 6, 7, 24,

File: contracts/base/upgradeability/FollowNFTProxy.sol

6: import {Proxy} from '@openzeppelin/contracts/proxy/Proxy.sol';

7: import {Address} from '@openzeppelin/contracts/utils/Address.sol';

6, 7,

File: contracts/misc/LegacyCollectNFT.sol

8: import {IERC721} from '@openzeppelin/contracts/token/ERC721/IERC721.sol';

11: import {Strings} from '@openzeppelin/contracts/utils/Strings.sol';

8, 11,

File: contracts/misc/access/ControllableByContract.sol

5: import {Ownable} from '@openzeppelin/contracts/access/Ownable.sol';

5,

File: contracts/misc/access/ProxyAdmin.sol

5: import {TransparentUpgradeableProxy} from '@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol';

5,

File: contracts/namespaces/LensHandles.sol

5: import {ERC721} from '@openzeppelin/contracts/token/ERC721/ERC721.sol';

12: import {Address} from '@openzeppelin/contracts/utils/Address.sol';

13: import {IERC721} from '@openzeppelin/contracts/token/ERC721/IERC721.sol';

5, 12, 13,

File: contracts/namespaces/TokenHandleRegistry.sol

5: import {IERC721} from '@openzeppelin/contracts/token/ERC721/IERC721.sol';

5,

File: contracts/interfaces/ILensERC721.sol

5: import {IERC721} from '@openzeppelin/contracts/token/ERC721/IERC721.sol';

9: import {IERC721Metadata} from '@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol';

5, 9,

File: contracts/interfaces/ILensHandles.sol

5: import {IERC721} from '@openzeppelin/contracts/token/ERC721/IERC721.sol';

5,

[L-18] Solidity version 0.8.20 may not work on other chains due to PUSH0

The compiler for Solidity 0.8.20 switches the default target EVM version to Shanghai, which includes the new PUSH0 op code. This op code may not yet be implemented on all L2s, so deployment on these chains will fail. To work around this issue, use an earlier EVM version

Instances (63):

see instances
File: contracts/LensHub.sol

3: pragma solidity ^0.8.15;

3,

File: contracts/FollowNFT.sol

3: pragma solidity ^0.8.15;

3,

File: contracts/libraries/ActionLib.sol

3: pragma solidity ^0.8.15;

3,

File: contracts/libraries/FollowLib.sol

3: pragma solidity ^0.8.15;

3,

File: contracts/libraries/GovernanceLib.sol

3: pragma solidity ^0.8.15;

3,

File: contracts/libraries/LegacyCollectLib.sol

3: pragma solidity ^0.8.15;

3,

File: contracts/libraries/MetaTxLib.sol

2: pragma solidity ^0.8.15;

2,

File: contracts/libraries/MigrationLib.sol

3: pragma solidity ^0.8.19;

3,

File: contracts/libraries/ProfileLib.sol

3: pragma solidity ^0.8.15;

3,

File: contracts/libraries/PublicationLib.sol

3: pragma solidity ^0.8.15;

3,

File: contracts/libraries/StorageLib.sol

3: pragma solidity ^0.8.15;

3,

File: contracts/libraries/ValidationLib.sol

3: pragma solidity ^0.8.15;

3,

File: contracts/libraries/constants/Errors.sol

3: pragma solidity >=0.6.0;

3,

File: contracts/libraries/constants/Events.sol

3: pragma solidity >=0.6.0;

3,

File: contracts/libraries/constants/Typehash.sol

3: pragma solidity >=0.6.0;

3,

File: contracts/libraries/constants/Types.sol

3: pragma solidity >=0.6.0;

3,

File: contracts/base/ERC2981CollectionRoyalties.sol

3: pragma solidity ^0.8.0;

3,

File: contracts/base/HubRestricted.sol

3: pragma solidity ^0.8.15;

3,

File: contracts/base/LensBaseERC721.sol

3: pragma solidity ^0.8.0;

3,

File: contracts/base/LensGovernable.sol

3: pragma solidity ^0.8.15;

3,

File: contracts/base/LensHubEventHooks.sol

3: pragma solidity ^0.8.15;

3,

File: contracts/base/LensHubStorage.sol

3: pragma solidity ^0.8.18;

3,

File: contracts/base/LensImplGetters.sol

3: pragma solidity ^0.8.15;

3,

File: contracts/base/LensProfiles.sol

3: pragma solidity ^0.8.15;

3,

File: contracts/base/upgradeability/FollowNFTProxy.sol

3: pragma solidity ^0.8.15;

3,

File: contracts/misc/ImmutableOwnable.sol

3: pragma solidity ^0.8.15;

3,

File: contracts/misc/LegacyCollectNFT.sol

3: pragma solidity ^0.8.15;

3,

File: contracts/misc/LensV2Migration.sol

3: pragma solidity ^0.8.15;

3,

File: contracts/misc/LensV2UpgradeContract.sol

3: pragma solidity ^0.8.19;

3,

File: contracts/misc/ModuleGlobals.sol

3: pragma solidity ^0.8.15;

3,

File: contracts/misc/ProfileCreationProxy.sol

3: pragma solidity ^0.8.15;

3,

File: contracts/misc/access/ControllableByContract.sol

3: pragma solidity ^0.8.15;

3,

File: contracts/misc/access/Governance.sol

3: pragma solidity ^0.8.15;

3,

File: contracts/misc/access/ProxyAdmin.sol

3: pragma solidity ^0.8.15;

3,

File: contracts/namespaces/LensHandles.sol

3: pragma solidity ^0.8.18;

3,

File: contracts/namespaces/TokenHandleRegistry.sol

3: pragma solidity ^0.8.18;

3,

File: contracts/namespaces/constants/Errors.sol

3: pragma solidity >=0.6.0;

3,

File: contracts/namespaces/constants/Events.sol

3: pragma solidity >=0.6.0;

3,

File: contracts/namespaces/constants/Types.sol

3: pragma solidity >=0.6.0;

3,

File: contracts/interfaces/ICollectModule.sol

3: pragma solidity >=0.6.0;

3,

File: contracts/interfaces/ICollectNFT.sol

3: pragma solidity >=0.6.0;

3,

File: contracts/interfaces/IERC721Burnable.sol

3: pragma solidity >=0.6.0;

3,

File: contracts/interfaces/IERC721MetaTx.sol

3: pragma solidity >=0.6.0;

3,

File: contracts/interfaces/IERC721Timestamped.sol

3: pragma solidity >=0.6.0;

3,

File: contracts/interfaces/IFollowModule.sol

3: pragma solidity >=0.6.0;

3,

File: contracts/interfaces/IFollowNFT.sol

3: pragma solidity >=0.6.0;

3,

File: contracts/interfaces/ILegacyCollectModule.sol

3: pragma solidity >=0.6.0;

3,

File: contracts/interfaces/ILegacyCollectNFT.sol

3: pragma solidity >=0.6.0;

3,

File: contracts/interfaces/ILegacyFollowModule.sol

3: pragma solidity ^0.8.15;

3,

File: contracts/interfaces/ILegacyReferenceModule.sol

3: pragma solidity >=0.6.0;

3,

File: contracts/interfaces/ILensERC721.sol

3: pragma solidity >=0.6.0;

3,

File: contracts/interfaces/ILensGovernable.sol

3: pragma solidity >=0.6.0;

3,

File: contracts/interfaces/ILensHandles.sol

3: pragma solidity >=0.6.0;

3,

File: contracts/interfaces/ILensHub.sol

3: pragma solidity >=0.6.0;

3,

File: contracts/interfaces/ILensHubEventHooks.sol

3: pragma solidity >=0.6.0;

3,

File: contracts/interfaces/ILensHubInitializable.sol

3: pragma solidity >=0.6.0;

3,

File: contracts/interfaces/ILensImplGetters.sol

3: pragma solidity >=0.6.0;

3,

File: contracts/interfaces/ILensProfiles.sol

3: pragma solidity >=0.6.0;

3,

File: contracts/interfaces/ILensProtocol.sol

3: pragma solidity >=0.6.0;

3,

File: contracts/interfaces/IModuleGlobals.sol

3: pragma solidity >=0.6.0;

3,

File: contracts/interfaces/IPublicationActionModule.sol

3: pragma solidity >=0.6.0;

3,

File: contracts/interfaces/IReferenceModule.sol

3: pragma solidity >=0.6.0;

3,

File: contracts/interfaces/ITokenHandleRegistry.sol

3: pragma solidity >=0.6.0;

3,

[L-19] Storage Write Removal Bug On Conditional Early Termination

See the following for more info: -https://twitter.com/solidity_lang/status/1567953562151579650?s=20&t=fXIo4hRjOiMXl2dqpD5Oyw-https://blog.soliditylang.org/2022/09/08/storage-write-removal-before-conditional-termination/

Instances (12):

see instances
File: contracts/FollowNFT.sol

467:     function _getRoyaltiesInBasisPointsSlot() internal pure override returns (uint256) {
468:             uint256 slot;
469:             assembly {
470:                 slot := _royaltiesInBasisPoints.slot
471:             }
472:             return slot;
473:         }

467:     function _getRoyaltiesInBasisPointsSlot() internal pure override returns (uint256) {
468:             uint256 slot;
469:             assembly {
470:                 slot := _royaltiesInBasisPoints.slot
471:             }
472:             return slot;
473:         }

467, 467,

File: contracts/libraries/StorageLib.sol

165:     function incrementMaxActionModuleIdUsed() internal returns (uint256) {
166:             uint256 incrementedId;
167:             assembly {
168:                 incrementedId := add(sload(MAX_ACTION_MODULE_ID_USED_SLOT), 1)
169:                 sstore(MAX_ACTION_MODULE_ID_USED_SLOT, incrementedId)
170:             }
171:             if (incrementedId > MAX_ACTION_MODULE_ID_SUPPORTED) {
172:                 revert Errors.MaxActionModuleIdReached();
173:             }
174:             return incrementedId;
175:         }

165:     function incrementMaxActionModuleIdUsed() internal returns (uint256) {
166:             uint256 incrementedId;
167:             assembly {
168:                 incrementedId := add(sload(MAX_ACTION_MODULE_ID_USED_SLOT), 1)
169:                 sstore(MAX_ACTION_MODULE_ID_USED_SLOT, incrementedId)
170:             }
171:             if (incrementedId > MAX_ACTION_MODULE_ID_SUPPORTED) {
172:                 revert Errors.MaxActionModuleIdReached();
173:             }
174:             return incrementedId;
175:         }

165, 165,

File: contracts/libraries/PublicationLib.sol

338:                 assembly {
339:                         /// Equivalent to reverting with the returned error selector if
340:                         /// the length is not zero.
341:                         let length := mload(err)
342:                         if iszero(iszero(length)) {
343:                             revert(add(err, 32), length)
344:                         }
345:                     }

391:                 assembly {
392:                         /// Equivalent to reverting with the returned error selector if
393:                         /// the length is not zero.
394:                         let length := mload(err)
395:                         if iszero(iszero(length)) {
396:                             revert(add(err, 32), length)
397:                         }
398:                     }

444:                 assembly {
445:                         /// Equivalent to reverting with the returned error selector if
446:                         /// the length is not zero.
447:                         let length := mload(err)
448:                         if iszero(iszero(length)) {
449:                             revert(add(err, 32), length)
450:                         }
451:                     }

338, 391, 444,

File: contracts/base/ERC2981CollectionRoyalties.sol

65:     function _loadRoyaltiesInBasisPoints() internal view virtual returns (uint256) {
66:            uint256 royaltiesInBasisPointsSlot = _getRoyaltiesInBasisPointsSlot();
67:            uint256 royaltyAmount;
68:            assembly {
69:                royaltyAmount := sload(royaltiesInBasisPointsSlot)
70:            }
71:            return royaltyAmount;
72:        }

65:     function _loadRoyaltiesInBasisPoints() internal view virtual returns (uint256) {
66:            uint256 royaltiesInBasisPointsSlot = _getRoyaltiesInBasisPointsSlot();
67:            uint256 royaltyAmount;
68:            assembly {
69:                royaltyAmount := sload(royaltiesInBasisPointsSlot)
70:            }
71:            return royaltyAmount;
72:        }

65, 65,

File: contracts/misc/LegacyCollectNFT.sol

116:     function _getRoyaltiesInBasisPointsSlot() internal pure override returns (uint256) {
117:             uint256 slot;
118:             assembly {
119:                 slot := _royaltiesInBasisPoints.slot
120:             }
121:             return slot;
122:         }

116:     function _getRoyaltiesInBasisPointsSlot() internal pure override returns (uint256) {
117:             uint256 slot;
118:             assembly {
119:                 slot := _royaltiesInBasisPoints.slot
120:             }
121:             return slot;
122:         }

116, 116,

File: contracts/misc/access/Governance.sol

86:             assembly {
87:                    revert(add(returnData, 32), len)
88:                }

86,

[L-20] tokenURI() does not follow EIP-721

The EIP states that tokenURI() "Throws if _tokenId is not a valid NFT", which the code below does not do. If the NFT has not yet been minted, tokenURI() should revert

Instances (4):

File: contracts/FollowNFT.sol

285:     function tokenURI(uint256 followTokenId) public view override returns (string memory) {

285,

File: contracts/base/LensProfiles.sol

105:     function tokenURI(uint256 tokenId) public view override(LensBaseERC721, IERC721Metadata) returns (string memory) {

105,

File: contracts/misc/LegacyCollectNFT.sol

69:     function tokenURI(uint256 tokenId) public view override returns (string memory) {

69,

File: contracts/namespaces/LensHandles.sol

81:     function tokenURI(uint256 tokenId) public view override returns (string memory) {

81,

[L-21] Unsafe downcast

When a type is downcast to a smaller type, the higher order bits are truncated, effectively applying a modulo to the original value. Without any other checks, this wrapping will lead to unexpected behavior and bugs

Instances (3):

File: contracts/FollowNFT.sol

/// @audit uint160
392:         _followDataByFollowTokenId[followTokenId].followerProfileId = uint160(followerProfileId);

/// @audit uint160
514:         _followDataByFollowTokenId[followTokenId].followerProfileId = uint160(followerProfileId);

392, 514,

File: contracts/libraries/GovernanceLib.sol

/// @audit uint248
100:                 uint248(id),

100,

[L-22] Unsafe ERC20 operation(s)

Instances (4):

File: contracts/base/LensProfiles.sol

117:         super.approve(to, tokenId);

117,

File: contracts/misc/ProfileCreationProxy.sol

58:         LENS_HANDLES.transferFrom(address(this), destination, handleId);

59:         ILensHub(LENS_HUB).transferFrom(address(this), destination, profileId);

58, 59,

File: contracts/namespaces/LensHandles.sol

144:         super.approve(to, tokenId);

144,

[L-23] Unspecific compiler version pragma

Instances (30):

see instances
File: contracts/libraries/constants/Errors.sol

3: pragma solidity >=0.6.0;

3,

File: contracts/libraries/constants/Events.sol

3: pragma solidity >=0.6.0;

3,

File: contracts/libraries/constants/Typehash.sol

3: pragma solidity >=0.6.0;

3,

File: contracts/libraries/constants/Types.sol

3: pragma solidity >=0.6.0;

3,

File: contracts/namespaces/constants/Errors.sol

3: pragma solidity >=0.6.0;

3,

File: contracts/namespaces/constants/Events.sol

3: pragma solidity >=0.6.0;

3,

File: contracts/namespaces/constants/Types.sol

3: pragma solidity >=0.6.0;

3,

File: contracts/interfaces/ICollectModule.sol

3: pragma solidity >=0.6.0;

3,

File: contracts/interfaces/ICollectNFT.sol

3: pragma solidity >=0.6.0;

3,

File: contracts/interfaces/IERC721Burnable.sol

3: pragma solidity >=0.6.0;

3,

File: contracts/interfaces/IERC721MetaTx.sol

3: pragma solidity >=0.6.0;

3,

File: contracts/interfaces/IERC721Timestamped.sol

3: pragma solidity >=0.6.0;

3,

File: contracts/interfaces/IFollowModule.sol

3: pragma solidity >=0.6.0;

3,

File: contracts/interfaces/IFollowNFT.sol

3: pragma solidity >=0.6.0;

3,

File: contracts/interfaces/ILegacyCollectModule.sol

3: pragma solidity >=0.6.0;

3,

File: contracts/interfaces/ILegacyCollectNFT.sol

3: pragma solidity >=0.6.0;

3,

File: contracts/interfaces/ILegacyReferenceModule.sol

3: pragma solidity >=0.6.0;

3,

File: contracts/interfaces/ILensERC721.sol

3: pragma solidity >=0.6.0;

3,

File: contracts/interfaces/ILensGovernable.sol

3: pragma solidity >=0.6.0;

3,

File: contracts/interfaces/ILensHandles.sol

3: pragma solidity >=0.6.0;

3,

File: contracts/interfaces/ILensHub.sol

3: pragma solidity >=0.6.0;

3,

File: contracts/interfaces/ILensHubEventHooks.sol

3: pragma solidity >=0.6.0;

3,

File: contracts/interfaces/ILensHubInitializable.sol

3: pragma solidity >=0.6.0;

3,

File: contracts/interfaces/ILensImplGetters.sol

3: pragma solidity >=0.6.0;

3,

File: contracts/interfaces/ILensProfiles.sol

3: pragma solidity >=0.6.0;

3,

File: contracts/interfaces/ILensProtocol.sol

3: pragma solidity >=0.6.0;

3,

File: contracts/interfaces/IModuleGlobals.sol

3: pragma solidity >=0.6.0;

3,

File: contracts/interfaces/IPublicationActionModule.sol

3: pragma solidity >=0.6.0;

3,

File: contracts/interfaces/IReferenceModule.sol

3: pragma solidity >=0.6.0;

3,

File: contracts/interfaces/ITokenHandleRegistry.sol

3: pragma solidity >=0.6.0;

3,

[L-24] TransferOwnership Should Be Two Step

Recommend considering implementing a two step process where the owner or admin nominates an account and the nominated account needs to call an acceptOwnership() function for the transfer of ownership to fully succeed. This ensures the nominated EOA account is a valid and active account.

Instances (1):

File: contracts/misc/access/ControllableByContract.sol

22:         _transferOwnership(owner);

22,

[L-25] Use Ownable2Step rather than Ownable

Ownable2Step and Ownable2StepUpgradeable prevent the contract ownership from mistakenly being transferred to an address that cannot handle it (e.g. due to a typo in the address), by requiring that the recipient of the owner permissions actively accept via a contract call of its own.

Instances (1):

File: contracts/misc/access/ControllableByContract.sol

7: contract ControllableByContract is Ownable {

7,

[L-26] Using zero as a parameter

Taking 0 as a valid argument in Solidity without checks can lead to severe security issues. A historical example is the infamous 0x0 address bug where numerous tokens were lost. This happens because 0 can be interpreted as an uninitialized address, leading to transfers to the 0x0 address, effectively burning tokens. Moreover, 0 as a denominator in division operations would cause a runtime exception. It's also often indicative of a logical error in the caller's code. It's important to always validate input and handle edge cases like 0 appropriately. Use require() statements to enforce conditions and provide clear error messages to facilitate debugging and safer code.

Instances (8):

see instances
File: contracts/FollowNFT.sol

331:             _approveFollow(0, followTokenId);

444:             _approveFollow(0, followTokenId);

331, 444,

File: contracts/libraries/ProfileLib.sol

173:             delegatedExecutors: new address[](0),

174:             approvals: new bool[](0),

173, 174,

File: contracts/libraries/PublicationLib.sol

529:             return new bytes(0);

529,

File: contracts/base/LensProfiles.sol

82:         emit Events.TokenGuardianStateChanged({

82,

File: contracts/namespaces/LensHandles.sol

131:         emit HandlesEvents.TokenGuardianStateChanged({

271:         super._beforeTokenTransfer(from, to, 0, batchSize);

131, 271,

[L-27] Vulnerable versions of packages are being used

This project's specific package versions are vulnerable to the specific CVEs listed below. Consider switching to more recent versions of these packages that don't have these vulnerabilities. -CVE-2023-26488 - MEDIUM - OpenZeppelin Contracts is a library for secure smart contract development. The ERC721Consecutive contract designed for minting NFTs in batches does not update balances when a batch has size 1 and consists of a single token. Subsequent transfers from the receiver of that token may overflow the balance as reported by balanceOf. The issue exclusively presents with batches of size 1. The issue has been patched in 4.8.2. (@openzeppelin/contracts >=4.8.0 <4.8.2)-CVE-2023-30541 - MEDIUM - OpenZeppelin Contracts is a library for secure smart contract development. A function in the implementation contract may be inaccessible if its selector clashes with one of the proxy's own selectors. Specifically, if the clashing function has a different signature with incompatible ABI encoding, the proxy could revert while attempting to decode the arguments from calldata. The probability of an accidental clash is negligible, but one could be caused deliberately and could cause a reduction in availability. The issue has been fixed in version 4.8.3. As a workaround if a function appears to be inaccessible for this reason, it may be possible to craft the calldata such that ABI decoding does not fail at the proxy and the function is properly proxied through. (@openzeppelin/contracts >=3.2.0 <4.8.3)-CVE-2023-30542 - HIGH - OpenZeppelin Contracts is a library for secure smart contract development. The proposal creation entrypoint (propose) in GovernorCompatibilityBravo allows the creation of proposals with a signatures array shorter than the calldatas array. This causes the additional elements of the latter to be ignored, and if the proposal succeeds the corresponding actions would eventually execute without any calldata. The ProposalCreated event correctly represents what will eventually execute, but the proposal parameters as queried through getActions appear to respect the original intended calldata. This issue has been patched in 4.8.3. As a workaround, ensure that all proposals that pass through governance have equal length signatures and calldatas parameters. (@openzeppelin/contracts >=4.3.0 <4.8.3)

Instances (1):

File: Various Files

/// @audit Vulnerabilities
1: 

Non-critical Issues

[N-01] Large assembly blocks should have extensive comments

Assembly blocks are take a lot more time to audit than normal Solidity code, and often have gotchas and side-effects that the Solidity versions of the same code do not. Consider adding more comments explaining what is being done in every step of the assembly code

Instances (35):

see instances
File: contracts/FollowNFT.sol

469:         assembly {
470:                 slot := _royaltiesInBasisPoints.slot
471:             }

469,

File: contracts/libraries/MetaTxLib.sol

199:         assembly {
200:                 let lengthWithoutOffset := sub(mload(encodedStruct), 32) // Calculates length without offset.
201:                 encodedStruct := add(encodedStruct, 32) // Skips the offset by shifting the memory pointer.
202:                 mstore(encodedStruct, lengthWithoutOffset) // Stores new length, which now excludes the offset.
203:             }

199,

File: contracts/libraries/MigrationLib.sol

77:                 assembly {
78:                        let handle_length := mload(handle)
79:                        mstore(handle, sub(handle_length, DOT_LENS_SUFFIX_LENGTH)) // Cut 5 chars (.lens) from the end
80:                    }

77,

File: contracts/libraries/PublicationLib.sol

209:         assembly {
210:                 referencePubParams := quoteParams
211:             }

220:         assembly {
221:                 referencePubParams := commentParams
222:             }

338:                 assembly {
339:                         /// Equivalent to reverting with the returned error selector if
340:                         /// the length is not zero.
341:                         let length := mload(err)
342:                         if iszero(iszero(length)) {
343:                             revert(add(err, 32), length)
344:                         }
345:                     }

391:                 assembly {
392:                         /// Equivalent to reverting with the returned error selector if
393:                         /// the length is not zero.
394:                         let length := mload(err)
395:                         if iszero(iszero(length)) {
396:                             revert(add(err, 32), length)
397:                         }
398:                     }

444:                 assembly {
445:                         /// Equivalent to reverting with the returned error selector if
446:                         /// the length is not zero.
447:                         let length := mload(err)
448:                         if iszero(iszero(length)) {
449:                             revert(add(err, 32), length)
450:                         }
451:                     }

209, 220, 338, 391, 444,

File: contracts/libraries/StorageLib.sol

54:         assembly {
55:                mstore(0, profileId)
56:                mstore(32, PUBLICATIONS_MAPPING_SLOT)
57:                mstore(32, keccak256(0, 64))
58:                mstore(0, pubId)
59:                _publication.slot := keccak256(0, 64)
60:            }

64:         assembly {
65:                mstore(0, profileId)
66:                mstore(32, PROFILES_MAPPING_SLOT)
67:                _profiles.slot := keccak256(0, 64)
68:            }

76:         assembly {
77:                mstore(0, delegatorProfileId)
78:                mstore(32, DELEGATED_EXECUTOR_CONFIG_MAPPING_SLOT)
79:                _delegatedExecutorsConfig.slot := keccak256(0, 64)
80:            }

88:         assembly {
89:                _tokenGuardianDisablingTimestamp.slot := TOKEN_GUARDIAN_DISABLING_TIMESTAMP_MAPPING_SLOT
90:            }

94:         assembly {
95:                mstore(0, tokenId)
96:                mstore(32, TOKEN_DATA_MAPPING_SLOT)
97:                _tokenData.slot := keccak256(0, 64)
98:            }

106:         assembly {
107:                 mstore(0, blockerProfileId)
108:                 mstore(32, BLOCKED_STATUS_MAPPING_SLOT)
109:                 _blockedStatus.slot := keccak256(0, 64)
110:             }

114:         assembly {
115:                 _nonces.slot := SIG_NONCES_MAPPING_SLOT
116:             }

124:         assembly {
125:                 _profileIdByHandleHash.slot := PROFILE_ID_BY_HANDLE_HASH_MAPPING_SLOT
126:             }

134:         assembly {
135:                 _profileCreatorWhitelisted.slot := PROFILE_CREATOR_WHITELIST_MAPPING_SLOT
136:             }

144:         assembly {
145:                 _followModuleWhitelisted.slot := FOLLOW_MODULE_WHITELIST_MAPPING_SLOT
146:             }

154:         assembly {
155:                 _actionModuleWhitelistData.slot := ACTION_MODULE_WHITELIST_DATA_MAPPING_SLOT
156:             }

160:         assembly {
161:                 _actionModules.slot := ACTION_MODULES_SLOT
162:             }

167:         assembly {
168:                 incrementedId := add(sload(MAX_ACTION_MODULE_ID_USED_SLOT), 1)
169:                 sstore(MAX_ACTION_MODULE_ID_USED_SLOT, incrementedId)
170:             }

182:         assembly {
183:                 _referenceModuleWhitelisted.slot := REFERENCE_MODULE_WHITELIST_MAPPING_SLOT
184:             }

188:         assembly {
189:                 _governance := sload(GOVERNANCE_SLOT)
190:             }

194:         assembly {
195:                 sstore(GOVERNANCE_SLOT, newGovernance)
196:             }

200:         assembly {
201:                 _emergencyAdmin := sload(EMERGENCY_ADMIN_SLOT)
202:             }

206:         assembly {
207:                 sstore(EMERGENCY_ADMIN_SLOT, newEmergencyAdmin)
208:             }

212:         assembly {
213:                 _state := sload(PROTOCOL_STATE_SLOT)
214:             }

218:         assembly {
219:                 sstore(PROTOCOL_STATE_SLOT, newState)
220:             }

224:         assembly {
225:                 _lastInitializedRevision := sload(LAST_INITIALIZED_REVISION_SLOT)
226:             }

230:         assembly {
231:                 sstore(LAST_INITIALIZED_REVISION_SLOT, newLastInitializedRevision)
232:             }

54, 64, 76, 88, 94, 106, 114, 124, 134, 144, 154, 160, 167, 182, 188, 194, 200, 206, 212, 218, 224, 230,

File: contracts/base/ERC2981CollectionRoyalties.sol

60:         assembly {
61:                sstore(royaltiesInBasisPointsSlot, royaltiesInBasisPoints)
62:            }

68:         assembly {
69:                royaltyAmount := sload(royaltiesInBasisPointsSlot)
70:            }

60, 68,

File: contracts/base/LensBaseERC721.sol

482:                     assembly {
483:                             revert(add(32, reason), mload(reason))
484:                         }

482,

File: contracts/misc/LegacyCollectNFT.sol

118:         assembly {
119:                 slot := _royaltiesInBasisPoints.slot
120:             }

118,

File: contracts/misc/access/Governance.sol

86:             assembly {
87:                    revert(add(returnData, 32), len)
88:                }

86,

[N-02] abi.encodePacked() should not be used with dynamic types when passing the result to a hash function such as keccak256()

Use abi.encode() instead which will pad items to 32 bytes, which will prevent hash collisions (e.g. abi.encodePacked(0x123,0x456) => 0x123456 => abi.encodePacked(0x1,0x23456), but abi.encode(0x123,0x456) => 0x0...1230...456). "Unless there is a compelling reason, abi.encode should be preferred". If there is only one argument to abi.encodePacked() it can often be cast to bytes() or bytes32() instead. If all arguments are strings and or bytes, bytes.concat() should be used instead

Instances (8):

see instances
File: contracts/libraries/MetaTxLib.sol

169:         return keccak256(abi.encodePacked(actionModulesInitDatasHashes));

345:                         keccak256(abi.encodePacked(idsOfProfilesToFollow)),

346:                         keccak256(abi.encodePacked(followTokenIds)),

347:                         keccak256(abi.encodePacked(dataHashes)),

368:                         keccak256(abi.encodePacked(idsOfProfilesToUnfollow)),

390:                         keccak256(abi.encodePacked(idsOfProfilesToSetBlockStatus)),

391:                         keccak256(abi.encodePacked(blockStatus)),

493:         return keccak256(abi.encodePacked('\x19\x01', calculateDomainSeparator(), hashedMessage));

169, 345, 346, 347, 368, 390, 391, 493,

[N-03] Avoid the use of sensitive terms

Use alternative variants, e.g. allowlist/denylist instead of whitelist/blacklist.

Instances (319):

see instances
File: contracts/LensHub.sol

/// @audit whitelist
95:         ValidationLib.validateProfileCreatorWhitelisted(msg.sender);

95,

File: contracts/libraries/ActionLib.sol

/// @audit whitelist
29:         uint256 actionModuleId = StorageLib.actionModuleWhitelistData()[actionModuleAddress].id;

29,

File: contracts/libraries/GovernanceLib.sol

/// @audit whitelist
71:     function whitelistProfileCreator(address profileCreator, bool whitelist) external {

/// @audit whitelist
71:     function whitelistProfileCreator(address profileCreator, bool whitelist) external {

/// @audit whitelist
72:         StorageLib.profileCreatorWhitelisted()[profileCreator] = whitelist;

/// @audit whitelist
72:         StorageLib.profileCreatorWhitelisted()[profileCreator] = whitelist;

/// @audit whitelist
73:         emit Events.ProfileCreatorWhitelisted(profileCreator, whitelist, block.timestamp);

/// @audit whitelist
73:         emit Events.ProfileCreatorWhitelisted(profileCreator, whitelist, block.timestamp);

/// @audit whitelist
76:     function whitelistFollowModule(address followModule, bool whitelist) external {

/// @audit whitelist
76:     function whitelistFollowModule(address followModule, bool whitelist) external {

/// @audit whitelist
77:         StorageLib.followModuleWhitelisted()[followModule] = whitelist;

/// @audit whitelist
77:         StorageLib.followModuleWhitelisted()[followModule] = whitelist;

/// @audit whitelist
78:         emit Events.FollowModuleWhitelisted(followModule, whitelist, block.timestamp);

/// @audit whitelist
78:         emit Events.FollowModuleWhitelisted(followModule, whitelist, block.timestamp);

/// @audit whitelist
81:     function whitelistReferenceModule(address referenceModule, bool whitelist) external {

/// @audit whitelist
81:     function whitelistReferenceModule(address referenceModule, bool whitelist) external {

/// @audit whitelist
82:         StorageLib.referenceModuleWhitelisted()[referenceModule] = whitelist;

/// @audit whitelist
82:         StorageLib.referenceModuleWhitelisted()[referenceModule] = whitelist;

/// @audit whitelist
83:         emit Events.ReferenceModuleWhitelisted(referenceModule, whitelist, block.timestamp);

/// @audit whitelist
83:         emit Events.ReferenceModuleWhitelisted(referenceModule, whitelist, block.timestamp);

/// @audit whitelist
86:     function whitelistActionModule(address actionModule, bool whitelist) external {

/// @audit whitelist
86:     function whitelistActionModule(address actionModule, bool whitelist) external {

/// @audit whitelist
87:         Types.ActionModuleWhitelistData memory actionModuleWhitelistData = StorageLib.actionModuleWhitelistData()[

/// @audit whitelist
87:         Types.ActionModuleWhitelistData memory actionModuleWhitelistData = StorageLib.actionModuleWhitelistData()[

/// @audit whitelist
87:         Types.ActionModuleWhitelistData memory actionModuleWhitelistData = StorageLib.actionModuleWhitelistData()[

/// @audit whitelist
92:         if (actionModuleWhitelistData.id == 0) {

/// @audit whitelist
93:             // The action module with the given address wasn't whitelisted before, a new ID is assigned to it.

/// @audit whitelist
94:             if (!whitelist) {

/// @audit whitelist
95:                 revert Errors.NotWhitelisted();

/// @audit whitelist
99:             StorageLib.actionModuleWhitelistData()[actionModule] = Types.ActionModuleWhitelistData(

/// @audit whitelist
99:             StorageLib.actionModuleWhitelistData()[actionModule] = Types.ActionModuleWhitelistData(

/// @audit whitelist
101:                 whitelist

/// @audit whitelist
105:             // The action module with the given address was already whitelisted before, it has an ID already assigned.

/// @audit whitelist
106:             StorageLib.actionModuleWhitelistData()[actionModule].isWhitelisted = whitelist;

/// @audit whitelist
106:             StorageLib.actionModuleWhitelistData()[actionModule].isWhitelisted = whitelist;

/// @audit whitelist
106:             StorageLib.actionModuleWhitelistData()[actionModule].isWhitelisted = whitelist;

/// @audit whitelist
107:             id = actionModuleWhitelistData.id;

/// @audit whitelist
109:         emit Events.ActionModuleWhitelisted(actionModule, id, whitelist, block.timestamp);

/// @audit whitelist
109:         emit Events.ActionModuleWhitelisted(actionModule, id, whitelist, block.timestamp);

71, 71, 72, 72, 73, 73, 76, 76, 77, 77, 78, 78, 81, 81, 82, 82, 83, 83, 86, 86, 87, 87, 87, 92, 93, 94, 95, 99, 99, 101, 105, 106, 106, 106, 107, 109, 109,

File: contracts/libraries/ProfileLib.sol

/// @audit whitelist
54:             // We don't need to check for deprecated modules here because deprecated ones are no longer whitelisted.

/// @audit whitelist
116:         ValidationLib.validateFollowModuleWhitelisted(followModule);

54, 116,

File: contracts/libraries/PublicationLib.sol

/// @audit whitelist
488:             Types.ActionModuleWhitelistData memory actionModuleWhitelistData = StorageLib.actionModuleWhitelistData()[

/// @audit whitelist
488:             Types.ActionModuleWhitelistData memory actionModuleWhitelistData = StorageLib.actionModuleWhitelistData()[

/// @audit whitelist
488:             Types.ActionModuleWhitelistData memory actionModuleWhitelistData = StorageLib.actionModuleWhitelistData()[

/// @audit whitelist
492:             if (!actionModuleWhitelistData.isWhitelisted) {

/// @audit whitelist
492:             if (!actionModuleWhitelistData.isWhitelisted) {

/// @audit whitelist
493:                 revert Errors.NotWhitelisted();

/// @audit whitelist
496:             uint256 actionModuleIdBitmapMask = 1 << (actionModuleWhitelistData.id - 1);

/// @audit whitelist
531:         ValidationLib.validateReferenceModuleWhitelisted(referenceModule);

488, 488, 488, 492, 492, 493, 496, 531,

File: contracts/libraries/StorageLib.sol

/// @audit whitelist
22:     uint256 constant PROFILE_CREATOR_WHITELIST_MAPPING_SLOT = 13;

/// @audit whitelist
23:     uint256 constant FOLLOW_MODULE_WHITELIST_MAPPING_SLOT = 14;

/// @audit whitelist
24:     uint256 constant ACTION_MODULE_WHITELIST_DATA_MAPPING_SLOT = 15;

/// @audit whitelist
25:     uint256 constant REFERENCE_MODULE_WHITELIST_MAPPING_SLOT = 16;

/// @audit whitelist
129:     function profileCreatorWhitelisted()

/// @audit whitelist
132:         returns (mapping(address => bool) storage _profileCreatorWhitelisted)

/// @audit whitelist
135:             _profileCreatorWhitelisted.slot := PROFILE_CREATOR_WHITELIST_MAPPING_SLOT

/// @audit whitelist
135:             _profileCreatorWhitelisted.slot := PROFILE_CREATOR_WHITELIST_MAPPING_SLOT

/// @audit whitelist
139:     function followModuleWhitelisted()

/// @audit whitelist
142:         returns (mapping(address => bool) storage _followModuleWhitelisted)

/// @audit whitelist
145:             _followModuleWhitelisted.slot := FOLLOW_MODULE_WHITELIST_MAPPING_SLOT

/// @audit whitelist
145:             _followModuleWhitelisted.slot := FOLLOW_MODULE_WHITELIST_MAPPING_SLOT

/// @audit whitelist
149:     function actionModuleWhitelistData()

/// @audit whitelist
152:         returns (mapping(address => Types.ActionModuleWhitelistData) storage _actionModuleWhitelistData)

/// @audit whitelist
152:         returns (mapping(address => Types.ActionModuleWhitelistData) storage _actionModuleWhitelistData)

/// @audit whitelist
155:             _actionModuleWhitelistData.slot := ACTION_MODULE_WHITELIST_DATA_MAPPING_SLOT

/// @audit whitelist
155:             _actionModuleWhitelistData.slot := ACTION_MODULE_WHITELIST_DATA_MAPPING_SLOT

/// @audit whitelist
177:     function referenceModuleWhitelisted()

/// @audit whitelist
180:         returns (mapping(address => bool) storage _referenceModuleWhitelisted)

/// @audit whitelist
183:             _referenceModuleWhitelisted.slot := REFERENCE_MODULE_WHITELIST_MAPPING_SLOT

/// @audit whitelist
183:             _referenceModuleWhitelisted.slot := REFERENCE_MODULE_WHITELIST_MAPPING_SLOT

22, 23, 24, 25, 129, 132, 135, 135, 139, 142, 145, 145, 149, 152, 152, 155, 155, 177, 180, 183, 183,

File: contracts/libraries/ValidationLib.sol

/// @audit whitelist
51:     function validateReferenceModuleWhitelisted(address referenceModule) internal view {

/// @audit whitelist
52:         if (!StorageLib.referenceModuleWhitelisted()[referenceModule]) {

/// @audit whitelist
53:             revert Errors.NotWhitelisted();

/// @audit whitelist
57:     function validateFollowModuleWhitelisted(address followModule) internal view {

/// @audit whitelist
58:         if (!StorageLib.followModuleWhitelisted()[followModule]) {

/// @audit whitelist
59:             revert Errors.NotWhitelisted();

/// @audit whitelist
63:     function validateProfileCreatorWhitelisted(address profileCreator) internal view {

/// @audit whitelist
64:         if (!StorageLib.profileCreatorWhitelisted()[profileCreator]) {

/// @audit whitelist
65:             revert Errors.NotWhitelisted();

51, 52, 53, 57, 58, 59, 63, 64, 65,

File: contracts/libraries/constants/Errors.sol

/// @audit whitelist
23:     error NotWhitelisted();

23,

File: contracts/libraries/constants/Events.sol

/// @audit whitelist
65:      * @dev Emitted when a profile creator is added to or removed from the whitelist.

/// @audit whitelist
68:      * @param whitelisted Whether or not the profile creator is being added to the whitelist.

/// @audit whitelist
68:      * @param whitelisted Whether or not the profile creator is being added to the whitelist.

/// @audit whitelist
71:     event ProfileCreatorWhitelisted(address indexed profileCreator, bool indexed whitelisted, uint256 timestamp);

/// @audit whitelist
71:     event ProfileCreatorWhitelisted(address indexed profileCreator, bool indexed whitelisted, uint256 timestamp);

/// @audit whitelist
74:      * @dev Emitted when a follow module is added to or removed from the whitelist.

/// @audit whitelist
77:      * @param whitelisted Whether or not the follow module is being added to the whitelist.

/// @audit whitelist
77:      * @param whitelisted Whether or not the follow module is being added to the whitelist.

/// @audit whitelist
80:     event FollowModuleWhitelisted(address indexed followModule, bool indexed whitelisted, uint256 timestamp);

/// @audit whitelist
80:     event FollowModuleWhitelisted(address indexed followModule, bool indexed whitelisted, uint256 timestamp);

/// @audit whitelist
83:      * @dev Emitted when a reference module is added to or removed from the whitelist.

/// @audit whitelist
86:      * @param whitelisted Whether or not the reference module is being added to the whitelist.

/// @audit whitelist
86:      * @param whitelisted Whether or not the reference module is being added to the whitelist.

/// @audit whitelist
89:     event ReferenceModuleWhitelisted(address indexed referenceModule, bool indexed whitelisted, uint256 timestamp);

/// @audit whitelist
89:     event ReferenceModuleWhitelisted(address indexed referenceModule, bool indexed whitelisted, uint256 timestamp);

/// @audit whitelist
92:      * @dev Emitted when an action module is added to or removed from the whitelist.

/// @audit whitelist
95:      * @param id Id of the whitelisted action module.

/// @audit whitelist
96:      * @param whitelisted Whether or not the action module is being added to the whitelist.

/// @audit whitelist
96:      * @param whitelisted Whether or not the action module is being added to the whitelist.

/// @audit whitelist
99:     event ActionModuleWhitelisted(

/// @audit whitelist
102:         bool indexed whitelisted,

/// @audit whitelist
400:      * @notice Emitted when a currency is added to or removed from the ModuleGlobals whitelist.

/// @audit whitelist
403:      * @param prevWhitelisted Whether or not the currency was previously whitelisted.

/// @audit whitelist
403:      * @param prevWhitelisted Whether or not the currency was previously whitelisted.

/// @audit whitelist
404:      * @param whitelisted Whether or not the currency is whitelisted.

/// @audit whitelist
404:      * @param whitelisted Whether or not the currency is whitelisted.

/// @audit whitelist
407:     event ModuleGlobalsCurrencyWhitelisted(

/// @audit whitelist
409:         bool indexed prevWhitelisted,

/// @audit whitelist
410:         bool indexed whitelisted,

65, 68, 68, 71, 71, 74, 77, 77, 80, 80, 83, 86, 86, 89, 89, 92, 95, 96, 96, 99, 102, 400, 403, 403, 404, 404, 407, 409, 410,

File: contracts/libraries/constants/Types.sol

/// @audit whitelist
175:      * @param referenceModule The reference module to set for the given publication, must be whitelisted.

/// @audit whitelist
199:      * @param referenceModule The reference module to set for the given publication, must be whitelisted.

/// @audit whitelist
228:      * @param referenceModule The reference module to set for the given publication, must be whitelisted.

/// @audit whitelist
257:      * @param referenceModule The reference module to set for the given publication, must be whitelisted.

/// @audit whitelist
406:     struct ActionModuleWhitelistData {

/// @audit whitelist
408:         bool isWhitelisted;

175, 199, 228, 257, 406, 408,

File: contracts/base/LensGovernable.sol

/// @audit whitelist
41:     function whitelistProfileCreator(address profileCreator, bool whitelist) external override onlyGov {

/// @audit whitelist
41:     function whitelistProfileCreator(address profileCreator, bool whitelist) external override onlyGov {

/// @audit whitelist
42:         GovernanceLib.whitelistProfileCreator(profileCreator, whitelist);

/// @audit whitelist
42:         GovernanceLib.whitelistProfileCreator(profileCreator, whitelist);

/// @audit whitelist
46:     function whitelistFollowModule(address followModule, bool whitelist) external override onlyGov {

/// @audit whitelist
46:     function whitelistFollowModule(address followModule, bool whitelist) external override onlyGov {

/// @audit whitelist
47:         GovernanceLib.whitelistFollowModule(followModule, whitelist);

/// @audit whitelist
47:         GovernanceLib.whitelistFollowModule(followModule, whitelist);

/// @audit whitelist
51:     function whitelistReferenceModule(address referenceModule, bool whitelist) external override onlyGov {

/// @audit whitelist
51:     function whitelistReferenceModule(address referenceModule, bool whitelist) external override onlyGov {

/// @audit whitelist
52:         GovernanceLib.whitelistReferenceModule(referenceModule, whitelist);

/// @audit whitelist
52:         GovernanceLib.whitelistReferenceModule(referenceModule, whitelist);

/// @audit whitelist
56:     function whitelistActionModule(address actionModule, bool whitelist) external override onlyGov {

/// @audit whitelist
56:     function whitelistActionModule(address actionModule, bool whitelist) external override onlyGov {

/// @audit whitelist
57:         GovernanceLib.whitelistActionModule(actionModule, whitelist);

/// @audit whitelist
57:         GovernanceLib.whitelistActionModule(actionModule, whitelist);

/// @audit whitelist
82:     function isProfileCreatorWhitelisted(address profileCreator) external view override returns (bool) {

/// @audit whitelist
83:         return StorageLib.profileCreatorWhitelisted()[profileCreator];

/// @audit whitelist
87:     function isFollowModuleWhitelisted(address followModule) external view override returns (bool) {

/// @audit whitelist
88:         return StorageLib.followModuleWhitelisted()[followModule];

/// @audit whitelist
92:     function isReferenceModuleWhitelisted(address referenceModule) external view override returns (bool) {

/// @audit whitelist
93:         return StorageLib.referenceModuleWhitelisted()[referenceModule];

/// @audit whitelist
97:     function getActionModuleWhitelistData(address actionModule)

/// @audit whitelist
101:         returns (Types.ActionModuleWhitelistData memory)

/// @audit whitelist
103:         return StorageLib.actionModuleWhitelistData()[actionModule];

41, 41, 42, 42, 46, 46, 47, 47, 51, 51, 52, 52, 56, 56, 57, 57, 82, 83, 87, 88, 92, 93, 97, 101, 103,

File: contracts/base/LensHubStorage.sol

/// @audit whitelist
21:     mapping(address profileCreator => bool isWhitelisted) internal _profileCreatorWhitelisted; // Slot 13

/// @audit whitelist
21:     mapping(address profileCreator => bool isWhitelisted) internal _profileCreatorWhitelisted; // Slot 13

/// @audit whitelist
23:     mapping(address => bool isWhitelisted) internal _followModuleWhitelisted; // Slot 14

/// @audit whitelist
23:     mapping(address => bool isWhitelisted) internal _followModuleWhitelisted; // Slot 14

/// @audit whitelist
25:     // `_collectModuleWhitelisted` slot replaced by `_actionModuleWhitelistData` in Lens V2.

/// @audit whitelist
25:     // `_collectModuleWhitelisted` slot replaced by `_actionModuleWhitelistData` in Lens V2.

/// @audit whitelist
26:     // All the old modules need to be unwhitelisted before V2 upgrade to avoid dirty storage.

/// @audit whitelist
27:     // mapping(address collectModule => bool isWhitelisted) internal __DEPRECATED__collectModuleWhitelisted;

/// @audit whitelist
27:     // mapping(address collectModule => bool isWhitelisted) internal __DEPRECATED__collectModuleWhitelisted;

/// @audit whitelist
28:     mapping(address actionModule => Types.ActionModuleWhitelistData whitelistData) internal _actionModuleWhitelistData; // Slot 15

/// @audit whitelist
28:     mapping(address actionModule => Types.ActionModuleWhitelistData whitelistData) internal _actionModuleWhitelistData; // Slot 15

/// @audit whitelist
28:     mapping(address actionModule => Types.ActionModuleWhitelistData whitelistData) internal _actionModuleWhitelistData; // Slot 15

/// @audit whitelist
30:     mapping(address referenceModule => bool isWhitelisted) internal _referenceModuleWhitelisted; // Slot 16

/// @audit whitelist
30:     mapping(address referenceModule => bool isWhitelisted) internal _referenceModuleWhitelisted; // Slot 16

21, 21, 23, 23, 25, 25, 26, 27, 27, 28, 28, 28, 30, 30,

File: contracts/misc/LensV2UpgradeContract.sol

/// @audit whitelist
13:     address[] public oldFollowModulesToUnwhitelist;

/// @audit whitelist
14:     address[] public newFollowModulesToWhitelist;

/// @audit whitelist
15:     address[] public oldReferenceModulesToUnwhitelist;

/// @audit whitelist
16:     address[] public newReferenceModulesToWhitelist;

/// @audit whitelist
17:     address[] public oldCollectModulesToUnwhitelist;

/// @audit whitelist
18:     address[] public newActionModulesToWhitelist;

/// @audit whitelist
26:         address[] memory oldFollowModulesToUnwhitelist_,

/// @audit whitelist
27:         address[] memory newFollowModulesToWhitelist_,

/// @audit whitelist
28:         address[] memory oldReferenceModulesToUnwhitelist_,

/// @audit whitelist
29:         address[] memory newReferenceModulesToWhitelist_,

/// @audit whitelist
30:         address[] memory oldCollectModulesToUnwhitelist_,

/// @audit whitelist
31:         address[] memory newActionModulesToWhitelist_

/// @audit whitelist
36:         oldFollowModulesToUnwhitelist = oldFollowModulesToUnwhitelist_;

/// @audit whitelist
36:         oldFollowModulesToUnwhitelist = oldFollowModulesToUnwhitelist_;

/// @audit whitelist
37:         newFollowModulesToWhitelist = newFollowModulesToWhitelist_;

/// @audit whitelist
37:         newFollowModulesToWhitelist = newFollowModulesToWhitelist_;

/// @audit whitelist
38:         oldReferenceModulesToUnwhitelist = oldReferenceModulesToUnwhitelist_;

/// @audit whitelist
38:         oldReferenceModulesToUnwhitelist = oldReferenceModulesToUnwhitelist_;

/// @audit whitelist
39:         newReferenceModulesToWhitelist = newReferenceModulesToWhitelist_;

/// @audit whitelist
39:         newReferenceModulesToWhitelist = newReferenceModulesToWhitelist_;

/// @audit whitelist
40:         oldCollectModulesToUnwhitelist = oldCollectModulesToUnwhitelist_;

/// @audit whitelist
40:         oldCollectModulesToUnwhitelist = oldCollectModulesToUnwhitelist_;

/// @audit whitelist
41:         newActionModulesToWhitelist = newActionModulesToWhitelist_;

/// @audit whitelist
41:         newActionModulesToWhitelist = newActionModulesToWhitelist_;

/// @audit whitelist
51:         _unwhitelistOldFollowModules();

/// @audit whitelist
52:         _unwhitelistOldReferenceModules();

/// @audit whitelist
53:         _unwhitelistOldCollectModules();

/// @audit whitelist
57:         _whitelistNewFollowModules();

/// @audit whitelist
58:         _whitelistNewReferenceModules();

/// @audit whitelist
59:         _whitelistNewActionModules();

/// @audit whitelist
64:     function _unwhitelistOldFollowModules() internal {

/// @audit whitelist
65:         uint256 oldFollowModulesToUnwhitelistLength = oldFollowModulesToUnwhitelist.length;

/// @audit whitelist
65:         uint256 oldFollowModulesToUnwhitelistLength = oldFollowModulesToUnwhitelist.length;

/// @audit whitelist
67:         while (i < oldFollowModulesToUnwhitelistLength) {

/// @audit whitelist
68:             GOVERNANCE.lensHub_whitelistFollowModule(oldFollowModulesToUnwhitelist[i], false);

/// @audit whitelist
68:             GOVERNANCE.lensHub_whitelistFollowModule(oldFollowModulesToUnwhitelist[i], false);

/// @audit whitelist
75:     function _unwhitelistOldReferenceModules() internal {

/// @audit whitelist
76:         uint256 oldReferenceModulesToUnwhitelistLength = oldReferenceModulesToUnwhitelist.length;

/// @audit whitelist
76:         uint256 oldReferenceModulesToUnwhitelistLength = oldReferenceModulesToUnwhitelist.length;

/// @audit whitelist
78:         while (i < oldReferenceModulesToUnwhitelistLength) {

/// @audit whitelist
79:             GOVERNANCE.lensHub_whitelistReferenceModule(oldReferenceModulesToUnwhitelist[i], false);

/// @audit whitelist
79:             GOVERNANCE.lensHub_whitelistReferenceModule(oldReferenceModulesToUnwhitelist[i], false);

/// @audit whitelist
86:     function _unwhitelistOldCollectModules() internal {

/// @audit whitelist
87:         uint256 oldCollectModulesToUnwhitelistLength = oldCollectModulesToUnwhitelist.length;

/// @audit whitelist
87:         uint256 oldCollectModulesToUnwhitelistLength = oldCollectModulesToUnwhitelist.length;

/// @audit whitelist
89:         while (i < oldCollectModulesToUnwhitelistLength) {

/// @audit whitelist
90:             GOVERNANCE.lensHub_whitelistCollectModule(oldCollectModulesToUnwhitelist[i], false);

/// @audit whitelist
90:             GOVERNANCE.lensHub_whitelistCollectModule(oldCollectModulesToUnwhitelist[i], false);

/// @audit whitelist
97:     function _whitelistNewFollowModules() internal {

/// @audit whitelist
98:         uint256 newFollowModulesToWhitelistLength = newFollowModulesToWhitelist.length;

/// @audit whitelist
98:         uint256 newFollowModulesToWhitelistLength = newFollowModulesToWhitelist.length;

/// @audit whitelist
100:         while (i < newFollowModulesToWhitelistLength) {

/// @audit whitelist
101:             GOVERNANCE.lensHub_whitelistFollowModule(newFollowModulesToWhitelist[i], true);

/// @audit whitelist
101:             GOVERNANCE.lensHub_whitelistFollowModule(newFollowModulesToWhitelist[i], true);

/// @audit whitelist
108:     function _whitelistNewReferenceModules() internal {

/// @audit whitelist
109:         uint256 newReferenceModulesToWhitelistLength = newReferenceModulesToWhitelist.length;

/// @audit whitelist
109:         uint256 newReferenceModulesToWhitelistLength = newReferenceModulesToWhitelist.length;

/// @audit whitelist
111:         while (i < newReferenceModulesToWhitelistLength) {

/// @audit whitelist
112:             GOVERNANCE.lensHub_whitelistReferenceModule(newReferenceModulesToWhitelist[i], true);

/// @audit whitelist
112:             GOVERNANCE.lensHub_whitelistReferenceModule(newReferenceModulesToWhitelist[i], true);

/// @audit whitelist
119:     function _whitelistNewActionModules() internal {

/// @audit whitelist
120:         uint256 newActionModulesToWhitelistLength = newActionModulesToWhitelist.length;

/// @audit whitelist
120:         uint256 newActionModulesToWhitelistLength = newActionModulesToWhitelist.length;

/// @audit whitelist
122:         while (i < newActionModulesToWhitelistLength) {

/// @audit whitelist
123:             GOVERNANCE.lensHub_whitelistActionModule(newActionModulesToWhitelist[i], true);

/// @audit whitelist
123:             GOVERNANCE.lensHub_whitelistActionModule(newActionModulesToWhitelist[i], true);

13, 14, 15, 16, 17, 18, 26, 27, 28, 29, 30, 31, 36, 36, 37, 37, 38, 38, 39, 39, 40, 40, 41, 41, 51, 52, 53, 57, 58, 59, 64, 65, 65, 67, 68, 68, 75, 76, 76, 78, 79, 79, 86, 87, 87, 89, 90, 90, 97, 98, 98, 100, 101, 101, 108, 109, 109, 111, 112, 112, 119, 120, 120, 122, 123, 123,

File: contracts/misc/ModuleGlobals.sol

/// @audit whitelist
22:     mapping(address => bool) internal _currencyWhitelisted;

/// @audit whitelist
65:     function whitelistCurrency(address currency, bool toWhitelist) external override onlyGov {

/// @audit whitelist
65:     function whitelistCurrency(address currency, bool toWhitelist) external override onlyGov {

/// @audit whitelist
66:         _whitelistCurrency(currency, toWhitelist);

/// @audit whitelist
66:         _whitelistCurrency(currency, toWhitelist);

/// @audit whitelist
70:     function isCurrencyWhitelisted(address currency) external view override returns (bool) {

/// @audit whitelist
71:         return _currencyWhitelisted[currency];

/// @audit whitelist
115:     function _whitelistCurrency(address currency, bool toWhitelist) internal {

/// @audit whitelist
115:     function _whitelistCurrency(address currency, bool toWhitelist) internal {

/// @audit whitelist
117:         bool prevWhitelisted = _currencyWhitelisted[currency];

/// @audit whitelist
117:         bool prevWhitelisted = _currencyWhitelisted[currency];

/// @audit whitelist
118:         _currencyWhitelisted[currency] = toWhitelist;

/// @audit whitelist
118:         _currencyWhitelisted[currency] = toWhitelist;

/// @audit whitelist
119:         emit Events.ModuleGlobalsCurrencyWhitelisted(currency, prevWhitelisted, toWhitelist, block.timestamp);

/// @audit whitelist
119:         emit Events.ModuleGlobalsCurrencyWhitelisted(currency, prevWhitelisted, toWhitelist, block.timestamp);

/// @audit whitelist
119:         emit Events.ModuleGlobalsCurrencyWhitelisted(currency, prevWhitelisted, toWhitelist, block.timestamp);

22, 65, 65, 66, 66, 70, 71, 115, 115, 117, 117, 118, 118, 119, 119, 119,

File: contracts/misc/access/Governance.sol

/// @audit whitelist
9:     function whitelistCollectModule(address collectModule, bool whitelist) external;

/// @audit whitelist
9:     function whitelistCollectModule(address collectModule, bool whitelist) external;

/// @audit whitelist
35:     function lensHub_whitelistProfileCreator(address profileCreator, bool whitelist)

/// @audit whitelist
35:     function lensHub_whitelistProfileCreator(address profileCreator, bool whitelist)

/// @audit whitelist
39:         LENS_HUB.whitelistProfileCreator(profileCreator, whitelist);

/// @audit whitelist
39:         LENS_HUB.whitelistProfileCreator(profileCreator, whitelist);

/// @audit whitelist
42:     function lensHub_whitelistFollowModule(address followModule, bool whitelist)

/// @audit whitelist
42:     function lensHub_whitelistFollowModule(address followModule, bool whitelist)

/// @audit whitelist
46:         LENS_HUB.whitelistFollowModule(followModule, whitelist);

/// @audit whitelist
46:         LENS_HUB.whitelistFollowModule(followModule, whitelist);

/// @audit whitelist
49:     function lensHub_whitelistReferenceModule(address referenceModule, bool whitelist)

/// @audit whitelist
49:     function lensHub_whitelistReferenceModule(address referenceModule, bool whitelist)

/// @audit whitelist
53:         LENS_HUB.whitelistReferenceModule(referenceModule, whitelist);

/// @audit whitelist
53:         LENS_HUB.whitelistReferenceModule(referenceModule, whitelist);

/// @audit whitelist
56:     function lensHub_whitelistActionModule(address actionModule, bool whitelist)

/// @audit whitelist
56:     function lensHub_whitelistActionModule(address actionModule, bool whitelist)

/// @audit whitelist
60:         LENS_HUB.whitelistActionModule(actionModule, whitelist);

/// @audit whitelist
60:         LENS_HUB.whitelistActionModule(actionModule, whitelist);

/// @audit whitelist
63:     // Interface to the Deprecated LensHub V1 to unwhitelist collect modules

/// @audit whitelist
64:     function lensHub_whitelistCollectModule(address collectModule, bool whitelist)

/// @audit whitelist
64:     function lensHub_whitelistCollectModule(address collectModule, bool whitelist)

/// @audit whitelist
68:         ILensHub_V1(address(LENS_HUB)).whitelistCollectModule(collectModule, whitelist);

/// @audit whitelist
68:         ILensHub_V1(address(LENS_HUB)).whitelistCollectModule(collectModule, whitelist);

9, 9, 35, 35, 39, 39, 42, 42, 46, 46, 49, 49, 53, 53, 56, 56, 60, 60, 63, 64, 64, 68, 68,

File: contracts/namespaces/LensHandles.sol

/// @audit whitelist
39:     modifier onlyOwnerOrWhitelistedProfileCreator() {

/// @audit whitelist
41:             msg.sender != OWNER && !ILensHub(LENS_HUB).isProfileCreatorWhitelisted(msg.sender)

/// @audit whitelist
43:             revert HandlesErrors.NotOwnerNorWhitelisted();

/// @audit whitelist
89:         onlyOwnerOrWhitelistedProfileCreator

39, 41, 43, 89,

File: contracts/namespaces/constants/Errors.sol

/// @audit whitelist
18:     error NotOwnerNorWhitelisted();

18,

File: contracts/interfaces/ILensGovernable.sol

/// @audit whitelist
42:      * @notice Adds or removes a profile creator from the whitelist.

/// @audit whitelist
45:      * @param profileCreator The profile creator address to add or remove from the whitelist.

/// @audit whitelist
46:      * @param whitelist Whether or not the profile creator should be whitelisted.

/// @audit whitelist
46:      * @param whitelist Whether or not the profile creator should be whitelisted.

/// @audit whitelist
48:     function whitelistProfileCreator(address profileCreator, bool whitelist) external;

/// @audit whitelist
48:     function whitelistProfileCreator(address profileCreator, bool whitelist) external;

/// @audit whitelist
51:      * @notice Adds or removes a follow module from the whitelist.

/// @audit whitelist
54:      * @param followModule The follow module contract address to add or remove from the whitelist.

/// @audit whitelist
55:      * @param whitelist Whether or not the follow module should be whitelisted.

/// @audit whitelist
55:      * @param whitelist Whether or not the follow module should be whitelisted.

/// @audit whitelist
57:     function whitelistFollowModule(address followModule, bool whitelist) external;

/// @audit whitelist
57:     function whitelistFollowModule(address followModule, bool whitelist) external;

/// @audit whitelist
60:      * @notice Adds or removes a reference module from the whitelist.

/// @audit whitelist
63:      * @param referenceModule The reference module contract to add or remove from the whitelist.

/// @audit whitelist
64:      * @param whitelist Whether or not the reference module should be whitelisted.

/// @audit whitelist
64:      * @param whitelist Whether or not the reference module should be whitelisted.

/// @audit whitelist
66:     function whitelistReferenceModule(address referenceModule, bool whitelist) external;

/// @audit whitelist
66:     function whitelistReferenceModule(address referenceModule, bool whitelist) external;

/// @audit whitelist
69:      * @notice Adds or removes an action module from the whitelist. This function can only be called by the current

/// @audit whitelist
73:      * @param actionModule The action module contract address to add or remove from the whitelist.

/// @audit whitelist
74:      * @param whitelist True if the action module should be whitelisted, false if it should be unwhitelisted.

/// @audit whitelist
74:      * @param whitelist True if the action module should be whitelisted, false if it should be unwhitelisted.

/// @audit whitelist
74:      * @param whitelist True if the action module should be whitelisted, false if it should be unwhitelisted.

/// @audit whitelist
76:     function whitelistActionModule(address actionModule, bool whitelist) external;

/// @audit whitelist
76:     function whitelistActionModule(address actionModule, bool whitelist) external;

/// @audit whitelist
95:      * @notice Returns whether or not a profile creator is whitelisted.

/// @audit whitelist
99:      * @return bool True if the profile creator is whitelisted, false otherwise.

/// @audit whitelist
101:     function isProfileCreatorWhitelisted(address profileCreator) external view returns (bool);

/// @audit whitelist
104:      * @notice Returns whether or not a follow module is whitelisted.

/// @audit whitelist
108:      * @return bool True if the follow module is whitelisted, false otherwise.

/// @audit whitelist
110:     function isFollowModuleWhitelisted(address followModule) external view returns (bool);

/// @audit whitelist
113:      * @notice Returns whether or not a reference module is whitelisted.

/// @audit whitelist
117:      * @return bool True if the reference module is whitelisted, false otherwise.

/// @audit whitelist
119:     function isReferenceModuleWhitelisted(address referenceModule) external view returns (bool);

/// @audit whitelist
122:      * @notice Returns whether or not an action module is whitelisted, and its ID assigned.

/// @audit whitelist
123:      * @dev If the ID is zero, it means the module has never been whitelisted, so no ID assigned to it yet.

/// @audit whitelist
125:      * @param actionModule The address of the action module to get whitelist data of.

/// @audit whitelist
127:      * @return ActionModuleWhitelistData The data containing the ID and whitelist status of the given module.

/// @audit whitelist
127:      * @return ActionModuleWhitelistData The data containing the ID and whitelist status of the given module.

/// @audit whitelist
129:     function getActionModuleWhitelistData(address actionModule)

/// @audit whitelist
132:         returns (Types.ActionModuleWhitelistData memory);

42, 45, 46, 46, 48, 48, 51, 54, 55, 55, 57, 57, 60, 63, 64, 64, 66, 66, 69, 73, 74, 74, 74, 76, 76, 95, 99, 101, 104, 108, 110, 113, 117, 119, 122, 123, 125, 127, 127, 129, 132,

File: contracts/interfaces/ILensProtocol.sol

/// @audit whitelist
17:      * @custom:permissions Any whitelisted profile creator.

/// @audit whitelist
46:      * @param followModule The follow module to set for the given profile, must be whitelisted.

/// @audit whitelist
426:      * @notice Returns the address of the action module associated with the given whitelist ID, address(0) if none.

17, 46, 426,

File: contracts/interfaces/IModuleGlobals.sol

/// @audit whitelist
15:  *  - Whitelist of currencies allowed for use in modules

/// @audit whitelist
43:      * @notice Adds or removes a currency from the whitelist.

/// @audit whitelist
46:      * @param currency The currency to add or remove from the whitelist.

/// @audit whitelist
47:      * @param toWhitelist Whether to add (true) or remove (false) the currency from the whitelist.

/// @audit whitelist
47:      * @param toWhitelist Whether to add (true) or remove (false) the currency from the whitelist.

/// @audit whitelist
49:     function whitelistCurrency(address currency, bool toWhitelist) external;

/// @audit whitelist
49:     function whitelistCurrency(address currency, bool toWhitelist) external;

/// @audit whitelist
56:      * @notice Returns whether a currency is whitelisted.

/// @audit whitelist
58:      * @param currency The currency to query the whitelist for.

/// @audit whitelist
60:      * @return bool True if the queried currency is whitelisted, false otherwise.

/// @audit whitelist
62:     function isCurrencyWhitelisted(address currency) external view returns (bool);

15, 43, 46, 47, 47, 49, 49, 56, 58, 60, 62,

[N-04] Variable names that consist of all capital letters should be reserved for constant/immutable variables

If the variable needs to be different based on which class it comes from, a view/pure function should be used instead (e.g. like this).

Instances (1):

File: contracts/FollowNFT.sol

24:     uint256[5] ___DEPRECATED_SLOTS; // Deprecated slots, previously used for delegations.

24,

[N-05] Cast to bytes or bytes32 for clearer semantic meaning

This should especially be done if the new value is not required to be different from the old value

Instances (9):

see instances
File: contracts/libraries/MetaTxLib.sol

103:                         abi.encodePacked(delegatedExecutors),

104:                         abi.encodePacked(approvals),

169:         return keccak256(abi.encodePacked(actionModulesInitDatasHashes));

345:                         keccak256(abi.encodePacked(idsOfProfilesToFollow)),

346:                         keccak256(abi.encodePacked(followTokenIds)),

347:                         keccak256(abi.encodePacked(dataHashes)),

368:                         keccak256(abi.encodePacked(idsOfProfilesToUnfollow)),

390:                         keccak256(abi.encodePacked(idsOfProfilesToSetBlockStatus)),

391:                         keccak256(abi.encodePacked(blockStatus)),

103, 104, 169, 345, 346, 347, 368, 390, 391,

[N-06] Consider disabling renounceOwnership()

If the plan for your project does not include eventually giving up all ownership control, consider overwriting OpenZeppelin's Ownable's renounceOwnership() function in order to disable it.

Instances (9):

see instances
File: contracts/misc/LensV2UpgradeContract.sol

9: contract LensV2UpgradeContract is ImmutableOwnable {

9,

File: contracts/misc/ProfileCreationProxy.sol

19: contract ProfileCreationProxy is ImmutableOwnable {

19: contract ProfileCreationProxy is ImmutableOwnable {

19: contract ProfileCreationProxy is ImmutableOwnable {

19, 19, 19,

File: contracts/misc/access/ControllableByContract.sol

7: contract ControllableByContract is Ownable {

7,

File: contracts/misc/access/Governance.sol

12: contract Governance is ControllableByContract {

12: contract Governance is ControllableByContract {

12, 12,

File: contracts/misc/access/ProxyAdmin.sol

8: contract ProxyAdmin is ControllableByContract {

8: contract ProxyAdmin is ControllableByContract {

8, 8,

[N-07] Consider using delete rather than assigning zero to clear values

The delete keyword more closely matches the semantics of what is being done, and draws more attention to the changing of state, which may lead to a more thorough audit of its associated logic.

Instances (2):

File: contracts/base/LensProfiles.sol

81:         StorageLib.tokenGuardianDisablingTimestamp()[msg.sender] = 0;

81,

File: contracts/namespaces/LensHandles.sol

130:         _tokenGuardianDisablingTimestamp[msg.sender] = 0;

130,

[N-08] Consider using named mappings

Consider moving to solidity version 0.8.18 or later, and using named mappings to make it easier to understand the purpose of each mapping

Instances (31):

see instances
File: contracts/FollowNFT.sol

36:     mapping(uint256 => Types.FollowData) internal _followDataByFollowTokenId;

37:     mapping(uint256 => uint256) internal _followTokenIdByFollowerProfileId;

38:     mapping(uint256 => uint256) internal _followApprovalByFollowTokenId;

36, 37, 38,

File: contracts/libraries/ProfileLib.sol

140:         mapping(uint256 => bool) storage _blockedStatus = StorageLib.blockedStatus(byProfileId);

140,

File: contracts/libraries/StorageLib.sol

86:         returns (mapping(address => uint256) storage _tokenGuardianDisablingTimestamp)

104:         returns (mapping(uint256 => bool) storage _blockedStatus)

113:     function nonces() internal pure returns (mapping(address => uint256) storage _nonces) {

122:         returns (mapping(bytes32 => uint256) storage _profileIdByHandleHash)

132:         returns (mapping(address => bool) storage _profileCreatorWhitelisted)

142:         returns (mapping(address => bool) storage _followModuleWhitelisted)

152:         returns (mapping(address => Types.ActionModuleWhitelistData) storage _actionModuleWhitelistData)

159:     function actionModuleById() internal pure returns (mapping(uint256 => address) storage _actionModules) {

180:         returns (mapping(address => bool) storage _referenceModuleWhitelisted)

86, 104, 113, 122, 132, 142, 152, 159, 180,

File: contracts/libraries/constants/Types.sol

400:         mapping(uint256 => mapping(address => bool)) isApproved; // isApproved[configNumber][delegatedExecutor]

400:         mapping(uint256 => mapping(address => bool)) isApproved; // isApproved[configNumber][delegatedExecutor]

400, 400,

File: contracts/base/LensBaseERC721.sol

42:     mapping(uint256 => Types.TokenData) private _tokenData;

45:     mapping(address => uint256) private _balances;

48:     mapping(uint256 => address) private _tokenApprovals;

51:     mapping(address => mapping(address => bool)) private _operatorApprovals;

51:     mapping(address => mapping(address => bool)) private _operatorApprovals;

54:     mapping(address => mapping(uint256 => uint256)) private __DEPRECATED__ownedTokens;

54:     mapping(address => mapping(uint256 => uint256)) private __DEPRECATED__ownedTokens;

55:     mapping(uint256 => uint256) private __DEPRECATED__ownedTokensIndex;

61:     mapping(uint256 => uint256) private __DEPRECATED__allTokensIndex;

63:     mapping(address => uint256) private _nonces;

42, 45, 48, 51, 51, 54, 54, 55, 61, 63,

File: contracts/base/LensHubStorage.sol

23:     mapping(address => bool isWhitelisted) internal _followModuleWhitelisted; // Slot 14

38:     mapping(uint256 profileId => mapping(uint256 pubId => Types.Publication publication)) internal _publications; // Slot 20

51:     mapping(address => uint256) internal _tokenGuardianDisablingTimestamp; // Slot 25

59:     mapping(uint256 blockerProfileId => mapping(uint256 blockedProfileId => bool isBlocked)) internal _blockedStatus; // Slot 27

23, 38, 51, 59,

File: contracts/misc/ModuleGlobals.sol

22:     mapping(address => bool) internal _currencyWhitelisted;

22,

File: contracts/namespaces/LensHandles.sol

35:     mapping(address => uint256) internal _tokenGuardianDisablingTimestamp;

35,

[N-09] Consistent usage of require vs custom error

Consider using the same approach throughout the codebase to improve the consistency of the code.

require used: 0

cusntom error used: 20

require used: 0

cusntom error used: 46

require used: 0

cusntom error used: 0

require used: 0

cusntom error used: 29

require used: 0

cusntom error used: 0

require used: 0

cusntom error used: 12

require used: 0

cusntom error used: 2

require used: 0

cusntom error used: 23

require used: 0

cusntom error used: 0

require used: 0

cusntom error used: 0

Instances (10):

see instances
File: Various files

1: 

1: 

1: 

1: 

1: 

1: 

1: 

1: 

1: 

1: 

1, 1, 1, 1, 1, 1, 1, 1, 1, 1,

[N-10] constant/immutable variable names should use capital letters and underscore

For immutable variables in Solidity, the convention is to use CAPS_CASE or UPPER_CASE_WITH_UNDERSCORES.

Instances (8):

see instances
File: contracts/libraries/MetaTxLib.sol

21:     string constant EIP712_DOMAIN_VERSION = '2';

22:     bytes32 constant EIP712_DOMAIN_VERSION_HASH = keccak256(bytes(EIP712_DOMAIN_VERSION));

23:     bytes4 constant EIP1271_MAGIC_VALUE = 0x1626ba7e;

21, 22, 23,

File: contracts/libraries/constants/Typehash.sol

17:     bytes32 constant EIP712_DOMAIN = keccak256('EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)');

17,

File: contracts/base/ERC2981CollectionRoyalties.sol

12:     bytes4 internal constant INTERFACE_ID_ERC2981 = 0x2a55205a;

12,

File: contracts/misc/LensV2Migration.sol

16:     LensHandles internal immutable lensHandles;

17:     TokenHandleRegistry internal immutable tokenHandleRegistry;

16, 17,

File: contracts/misc/LensV2UpgradeContract.sol

12:     address public immutable newImplementation;

12,

[N-11] Constants in comparisons should appear on the left side

Doing so will prevent typo bugs.

Instances (58):

see instances
File: contracts/FollowNFT.sol

/// @audit != 0
64:         if (_followTokenIdByFollowerProfileId[followerProfileId] != 0) {

/// @audit == 0
68:         if (followTokenId == 0) {

/// @audit != 0
86:         if (currentFollowerProfileId != 0) {

/// @audit == 0
105:         if (followTokenId == 0) {

/// @audit == 0
173:         if (followerProfileId == 0) {

/// @audit == 0
175:             if (followerProfileId == 0) {

/// @audit == 0
189:         if (_followDataByFollowTokenId[followTokenId].followerProfileId == 0) {

/// @audit != 0
199:         if (followTokenId != 0) {

/// @audit != 0
217:         return _followTokenIdByFollowerProfileId[followerProfileId] != 0;

/// @audit != 0
373:         if (currentFollowerProfileId != 0) {

/// @audit == 0
401:             if (_followDataByFollowTokenId[followTokenId].originalFollowTimestamp == 0) {

/// @audit != 0
410:         if (followerProfileId != 0) {

/// @audit != 0
487:         if (_followDataByFollowTokenId[followTokenId].originalFollowTimestamp != 0) {

64, 68, 86, 105, 173, 175, 189, 199, 217, 373, 401, 410, 487,

File: contracts/libraries/ActionLib.sol

/// @audit == 0
70:         if (actionModuleId == 0) {

/// @audit != 0
74:         return actionModuleIdBitmapMask & _publication.enabledActionModulesBitmap != 0;

70, 74,

File: contracts/libraries/GovernanceLib.sol

/// @audit == 0
92:         if (actionModuleWhitelistData.id == 0) {

92,

File: contracts/libraries/LegacyCollectLib.sol

/// @audit != 0
71:             if (collectParams.referrerProfileId != 0 || collectParams.referrerPubId != 0) {

/// @audit != 0
71:             if (collectParams.referrerProfileId != 0 || collectParams.referrerPubId != 0) {

/// @audit == 0
91:             referrerProfileId: collectParams.referrerProfileId == 0

71, 71, 91,

File: contracts/libraries/MetaTxLib.sol

/// @audit != 0
472:         if (signature.signer.code.length != 0) {

472,

File: contracts/libraries/MigrationLib.sol

/// @audit == 0
70:             if (bytes(handle).length == 0) {

/// @audit != 0
129:         if (mintTimestamp != 0) {

70, 129,

File: contracts/libraries/PublicationLib.sol

/// @audit == 0
173:         if (uint8(pubType) == 0) {

/// @audit != 0
175:             if (_publication.pointedProfileId != 0) {

/// @audit > 0
358:             if (commentParams.referrerProfileIds.length > 0) {

/// @audit > 0
346:                 if (commentParams.referrerProfileIds.length > 0) {

/// @audit > 0
411:             if (quoteParams.referrerProfileIds.length > 0) {

/// @audit > 0
399:                 if (quoteParams.referrerProfileIds.length > 0) {

/// @audit > 0
464:             if (mirrorParams.referrerProfileIds.length > 0) {

/// @audit > 0
452:                 if (mirrorParams.referrerProfileIds.length > 0) {

/// @audit != 0
498:             if (enabledActionModulesBitmap & actionModuleIdBitmapMask != 0) {

173, 175, 358, 346, 411, 399, 464, 452, 498,

File: contracts/libraries/ValidationLib.sol

/// @audit == 0
149:         if (referrerPubId == 0) {

/// @audit == 0
221:                     _referrerPub.rootPubId == 0 ||

149, 221,

File: contracts/base/LensBaseERC721.sol

/// @audit == 0
129:         if (mintTimestamp == 0) {

/// @audit == 0
479:                 if (reason.length == 0) {

129, 479,

File: contracts/base/LensProfiles.sol

/// @audit != 0
64:         if (StorageLib.tokenGuardianDisablingTimestamp()[msg.sender] != 0) {

/// @audit == 0
78:         if (StorageLib.tokenGuardianDisablingTimestamp()[msg.sender] == 0) {

/// @audit == 0
145:             (StorageLib.tokenGuardianDisablingTimestamp()[wallet] == 0 ||

64, 78, 145,

File: contracts/namespaces/LensHandles.sol

/// @audit != 0
114:         if (_tokenGuardianDisablingTimestamp[msg.sender] != 0) {

/// @audit == 0
127:         if (_tokenGuardianDisablingTimestamp[msg.sender] == 0) {

/// @audit == 0
170:         if (bytes(localName).length == 0) {

/// @audit == 0
206:         if (localNameLength == 0 || localNameLength + SEPARATOR_LENGTH + NAMESPACE_LENGTH > MAX_HANDLE_LENGTH) {

/// @audit == -
211:         if (firstByte == '-' || firstByte == '_') {

/// @audit == _
211:         if (firstByte == '-' || firstByte == '_') {

/// @audit != -
217:             if (!_isAlphaNumeric(localNameAsBytes[i]) && localNameAsBytes[i] != '-' && localNameAsBytes[i] != '_') {

/// @audit != _
217:             if (!_isAlphaNumeric(localNameAsBytes[i]) && localNameAsBytes[i] != '-' && localNameAsBytes[i] != '_') {

/// @audit == 0
230:         if (localNameLength == 0 || localNameLength + SEPARATOR_LENGTH + NAMESPACE_LENGTH > MAX_HANDLE_LENGTH) {

/// @audit == _
234:         if (localNameAsBytes[0] == '_') {

/// @audit != _
240:             if (!_isAlphaNumeric(localNameAsBytes[i]) && localNameAsBytes[i] != '_') {

/// @audit >= 0
250:         return (char >= '0' && char <= '9') || (char >= 'a' && char <= 'z');

/// @audit <= 9
250:         return (char >= '0' && char <= '9') || (char >= 'a' && char <= 'z');

/// @audit >= a
250:         return (char >= '0' && char <= '9') || (char >= 'a' && char <= 'z');

/// @audit <= z
250:         return (char >= '0' && char <= '9') || (char >= 'a' && char <= 'z');

/// @audit == 0
256:             (_tokenGuardianDisablingTimestamp[wallet] == 0 ||

114, 127, 170, 206, 211, 211, 217, 217, 230, 234, 240, 250, 250, 250, 250, 256,

File: contracts/namespaces/TokenHandleRegistry.sol

/// @audit == 0
100:         if (resolvedTokenId == 0 || !ILensHub(LENS_HUB).exists(resolvedTokenId)) {

/// @audit == 0
112:         if (defaultHandleId == 0 || !ILensHandles(LENS_HANDLES).exists(defaultHandleId)) {

/// @audit != 0
146:         if (tokenPointedByHandle.collection != address(0) || tokenPointedByHandle.id != 0) {

/// @audit != 0
154:         if (handlePointedByToken.collection != address(0) || handlePointedByToken.id != 0) {

100, 112, 146, 154,

[N-12] Contract implements interface without extending the interface

Not extending the interface may lead to the wrong function signature being used, leading to unexpected behavior. If the interface is in fact being implemented, use the override keyword to indicate that fact

Instances (1):

File: contracts/base/ERC2981CollectionRoyalties.sol

/// @audit IERC2981.royaltyInfo()
9: abstract contract ERC2981CollectionRoyalties is IERC2981 {

9,

[N-13] Custom error has no error details

Consider adding parameters to the error to indicate which user or values caused the failure

Instances (63):

see instances
File: contracts/libraries/constants/Errors.sol

6:     error CannotInitImplementation();

7:     error Initialized();

8:     error SignatureExpired();

9:     error SignatureInvalid();

10:     error InvalidOwner();

11:     error NotOwnerOrApproved();

12:     error NotHub();

13:     error TokenDoesNotExist();

14:     error NotGovernance();

15:     error NotGovernanceOrEmergencyAdmin();

16:     error EmergencyAdminCanOnlyPauseFurther();

17:     error NotProfileOwner();

18:     error PublicationDoesNotExist();

19:     error ProfileImageURILengthInvalid();

20:     error CallerNotFollowNFT();

21:     error CallerNotCollectNFT(); // Legacy

22:     error ArrayMismatch();

23:     error NotWhitelisted();

24:     error InvalidParameter();

25:     error ExecutorInvalid();

26:     error Blocked();

27:     error SelfBlock();

28:     error NotFollowing();

29:     error SelfFollow();

30:     error InvalidReferrer();

31:     error InvalidPointedPub();

32:     error NonERC721ReceiverImplementer();

33:     error AlreadyEnabled();

36:     error MaxActionModuleIdReached(); // This means we need an upgrade

39:     error InitParamsInvalid();

40:     error ActionNotAllowed();

42:     error CollectNotAllowed(); // Used in LegacyCollectLib (pending deprecation)

45:     error Paused();

46:     error PublishingPaused();

49:     error GuardianEnabled();

50:     error NotEOA();

51:     error DisablingAlreadyTriggered();

6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 36, 39, 40, 42, 45, 46, 49, 50, 51,

File: contracts/misc/ImmutableOwnable.sol

9:     error OnlyOwner();

10:     error OnlyOwnerOrHub();

9, 10,

File: contracts/misc/access/ControllableByContract.sol

10:     error Unauthorized();

10,

File: contracts/namespaces/constants/Errors.sol

6:     error NotHandleOwner();

7:     error NotTokenOwner();

8:     error NotHandleNorTokenOwner();

9:     error OnlyLensHub();

10:     error NotLinked();

11:     error DoesNotExist();

15:     error HandleLengthInvalid();

16:     error HandleContainsInvalidCharacters();

17:     error HandleFirstCharInvalid();

18:     error NotOwnerNorWhitelisted();

19:     error NotOwner();

20:     error NotHub();

21:     error DoesNotExist();

22:     error NotEOA();

23:     error DisablingAlreadyTriggered();

24:     error GuardianEnabled();

25:     error AlreadyEnabled();

6, 7, 8, 9, 10, 11, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,

File: contracts/interfaces/IFollowNFT.sol

18:     error AlreadyFollowing();

19:     error NotFollowing();

20:     error FollowTokenDoesNotExist();

21:     error AlreadyWrapped();

22:     error OnlyWrappedFollowTokens();

23:     error DoesNotHavePermissions();

18, 19, 20, 21, 22, 23,

[N-14] Empty Function Body - Consider commenting why

Instances (2):

File: contracts/LensHub.sol

66:     constructor(
67:            address moduleGlobals,
68:            address followNFTImpl,
69:            address collectNFTImpl, // We still pass the deprecated CollectNFTImpl for legacy Collects to work
70:            address lensHandlesAddress,
71:            address tokenHandleRegistryAddress,
72:            address legacyFeeFollowModule,
73:            address legacyProfileFollowModule,
74:            address newFeeFollowModule,
75:            uint256 tokenGuardianCooldown
76:        )
77:            LensProfiles(moduleGlobals, tokenGuardianCooldown)
78:            LensV2Migration(
79:                legacyFeeFollowModule,
80:                legacyProfileFollowModule,
81:                newFeeFollowModule,
82:                lensHandlesAddress,
83:                tokenHandleRegistryAddress
84:            )
85:            LensImplGetters(followNFTImpl, collectNFTImpl)
86:        {}

66,

File: contracts/base/LensBaseERC721.sol

506:     function _beforeTokenTransfer(
507:             address from,
508:             address to,
509:             uint256 tokenId
510:         ) internal virtual {}

506,

[N-15] Events are missing sender information

When an action is triggered based on a user's action, not being able to filter based on who triggered the action makes event processing a lot more cumbersome. Including the msg.sender the events of these types of action will make events much more useful to end users.

Instances (42):

see instances
File: contracts/FollowNFT.sol

430:         emit FollowApproval(approvedProfileId, followTokenId);

430,

File: contracts/libraries/ActionLib.sol

60:         emit Events.Acted(publicationActionParams, actionModuleReturnData, block.timestamp);

60,

File: contracts/libraries/FollowLib.sol

75:             emit Events.Unfollowed(unfollowerProfileId, idOfProfileToUnfollow, block.timestamp);

93:         emit Events.FollowNFTDeployed(profileId, followNFT, block.timestamp);

131:         emit Events.Followed(

75, 93, 131,

File: contracts/libraries/GovernanceLib.sol

73:         emit Events.ProfileCreatorWhitelisted(profileCreator, whitelist, block.timestamp);

78:         emit Events.FollowModuleWhitelisted(followModule, whitelist, block.timestamp);

83:         emit Events.ReferenceModuleWhitelisted(referenceModule, whitelist, block.timestamp);

109:         emit Events.ActionModuleWhitelisted(actionModule, id, whitelist, block.timestamp);

73, 78, 83, 109,

File: contracts/libraries/LegacyCollectLib.sol

102:         emit CollectedLegacy({

142:         emit Events.CollectNFTDeployed(profileId, pubId, collectNFT, block.timestamp);

102, 142,

File: contracts/libraries/MigrationLib.sol

86:             emit ProfileMigrated(profileId, profileOwner, handle, handleId);

130:             emit Events.Followed({

86, 130,

File: contracts/libraries/ProfileLib.sol

102:         emit Events.FollowModuleSet(profileId, followModule, followModuleReturnData, block.timestamp);

107:         emit Events.ProfileMetadataSet(profileId, metadataURI, block.timestamp);

125:         emit Events.ProfileImageURISet(profileId, imageURI, block.timestamp);

151:                     emit Events.Unfollowed(idOfProfileToSetBlockStatus, byProfileId, block.timestamp);

158:                 emit Events.Unblocked(byProfileId, idOfProfileToSetBlockStatus, block.timestamp);

156:                 emit Events.Blocked(byProfileId, idOfProfileToSetBlockStatus, block.timestamp);

245:         emit Events.DelegatedExecutorsConfigChanged(

102, 107, 125, 151, 158, 156, 245,

File: contracts/libraries/PublicationLib.sol

45:         emit Events.PostCreated(

84:         emit Events.CommentCreated(

128:         emit Events.MirrorCreated(mirrorParams, pubIdAssigned, referenceModuleReturnData, block.timestamp);

158:         emit Events.QuoteCreated(

45, 84, 128, 158,

File: contracts/base/LensBaseERC721.sol

367:         emit Transfer(address(0), to, tokenId);

394:         emit Transfer(owner, address(0), tokenId);

431:         emit Transfer(from, to, tokenId);

441:         emit Approval(ownerOf(tokenId), to, tokenId);

456:         emit ApprovalForAll(owner, operator, approved);

367, 394, 431, 441, 456,

File: contracts/base/LensHubEventHooks.sol

17:         emit Events.Unfollowed(unfollowerProfileId, idOfProfileUnfollowed, block.timestamp);

36:         emit Events.CollectNFTTransferred(profileId, pubId, collectNFTId, from, to, block.timestamp);

17, 36,

File: contracts/misc/ModuleGlobals.sol

98:         emit Events.ModuleGlobalsGovernanceSet(prevGovernance, newGovernance, block.timestamp);

105:         emit Events.ModuleGlobalsTreasurySet(prevTreasury, newTreasury, block.timestamp);

112:         emit Events.ModuleGlobalsTreasuryFeeSet(prevTreasuryFee, newTreasuryFee, block.timestamp);

119:         emit Events.ModuleGlobalsCurrencyWhitelisted(currency, prevWhitelisted, toWhitelist, block.timestamp);

98, 105, 112, 119,

File: contracts/misc/access/ControllableByContract.sol

26:         emit ControllerContractUpdated(controllerContract, address(0));

31:         emit ControllerContractUpdated(controllerContract, newControllerContract);

26, 31,

File: contracts/namespaces/LensHandles.sol

198:         emit HandlesEvents.HandleMinted(localName, NAMESPACE, tokenId, to, block.timestamp);

198,

File: contracts/namespaces/TokenHandleRegistry.sol

141:         emit RegistryEvents.HandleLinked(handle, token, block.timestamp);

148:             emit RegistryEvents.HandleUnlinked(handle, tokenPointedByHandle, block.timestamp);

156:             emit RegistryEvents.HandleUnlinked(handlePointedByToken, token, block.timestamp);

164:         emit RegistryEvents.HandleUnlinked(handle, token, block.timestamp);

141, 148, 156, 164,

[N-16] Events that mark critical parameter changes should contain both the old and the new value

This should especially be done if the new value is not required to be different from the old value

Instances (2):

File: contracts/libraries/MigrationLib.sol

86:             emit ProfileMigrated(profileId, profileOwner, handle, handleId);

86,

File: contracts/misc/access/ControllableByContract.sol

31:         emit ControllerContractUpdated(controllerContract, newControllerContract);

31,

[N-17] Events may be emitted out of order due to reentranc

Ensure that events follow the best practice of check-effects-interaction, and are emitted before external calls

Instances (10):

see instances
File: contracts/libraries/ActionLib.sol

/// @audit processPublicationAction() prior to emission of 
60:         emit Events.Acted(publicationActionParams, actionModuleReturnData, block.timestamp);

60,

File: contracts/libraries/FollowLib.sol

/// @audit unfollow() prior to emission of 
75:             emit Events.Unfollowed(unfollowerProfileId, idOfProfileToUnfollow, block.timestamp);

/// @audit encodeWithSelector() prior to emission of 
93:         emit Events.FollowNFTDeployed(profileId, followNFT, block.timestamp);

/// @audit processFollow() prior to emission of 
131:         emit Events.Followed(

75, 93, 131,

File: contracts/libraries/LegacyCollectLib.sol

/// @audit processCollect() prior to emission of CollectedLegacy()
102:         emit CollectedLegacy({

/// @audit initialize() prior to emission of 
142:         emit Events.CollectNFTDeployed(profileId, pubId, collectNFT, block.timestamp);

102, 142,

File: contracts/libraries/MigrationLib.sol

/// @audit tryMigrate() prior to emission of 
130:             emit Events.Followed({

130,

File: contracts/libraries/ProfileLib.sol

/// @audit processBlock() prior to emission of 
151:                     emit Events.Unfollowed(idOfProfileToSetBlockStatus, byProfileId, block.timestamp);

/// @audit processBlock() prior to emission of 
158:                 emit Events.Unblocked(byProfileId, idOfProfileToSetBlockStatus, block.timestamp);

/// @audit processBlock() prior to emission of 
156:                 emit Events.Blocked(byProfileId, idOfProfileToSetBlockStatus, block.timestamp);

151, 158, 156,

[N-18] It is standard for all external and public functions to be override from an interface

This is to ensure the whole API is extracted in a interface.

Instances (230):

see instances
File: contracts/LensHub.sol

492:     function isFollowing(uint256 followerProfileId, uint256 followedProfileId) external view returns (bool) {

498:     function isDelegatedExecutorApproved(
499:             uint256 delegatorProfileId,
500:             address delegatedExecutor,
501:             uint64 configNumber
502:         ) external view returns (bool) {

507:     function isDelegatedExecutorApproved(uint256 delegatorProfileId, address delegatedExecutor)
508:             external
509:             view
510:             returns (bool)
511:         {

516:     function getDelegatedExecutorsConfigNumber(uint256 delegatorProfileId) external view returns (uint64) {

521:     function getDelegatedExecutorsPrevConfigNumber(uint256 delegatorProfileId) external view returns (uint64) {

526:     function getDelegatedExecutorsMaxConfigNumberSet(uint256 delegatorProfileId) external view returns (uint64) {

531:     function isBlocked(uint256 profileId, uint256 byProfileId) external view returns (bool) {

492, 498, 507, 516, 521, 526, 531,

File: contracts/FollowNFT.sol

480:     function tryMigrate(
481:             uint256 followerProfileId,
482:             address followerProfileOwner,
483:             uint256 idOfProfileFollowed,
484:             uint256 followTokenId
485:         ) external onlyHub returns (uint48) {

480,

File: contracts/libraries/ActionLib.sol

13:     function act(
14:            Types.PublicationActionParams calldata publicationActionParams,
15:            address transactionExecutor,
16:            address actorProfileOwner
17:        ) external returns (bytes memory) {

13,

File: contracts/libraries/FollowLib.sol

15:     function follow(
16:            uint256 followerProfileId,
17:            address transactionExecutor,
18:            uint256[] calldata idsOfProfilesToFollow,
19:            uint256[] calldata followTokenIds,
20:            bytes[] calldata followModuleDatas
21:        ) external returns (uint256[] memory) {

54:     function unfollow(
55:            uint256 unfollowerProfileId,
56:            address transactionExecutor,
57:            uint256[] calldata idsOfProfilesToUnfollow
58:        ) external {

15, 54,

File: contracts/libraries/GovernanceLib.sol

16:     function setGovernance(address newGovernance) external {

27:     function setEmergencyAdmin(address newEmergencyAdmin) external {

39:     function initState(Types.ProtocolState newState) external {

50:     function setState(Types.ProtocolState newState) external {

71:     function whitelistProfileCreator(address profileCreator, bool whitelist) external {

76:     function whitelistFollowModule(address followModule, bool whitelist) external {

81:     function whitelistReferenceModule(address referenceModule, bool whitelist) external {

86:     function whitelistActionModule(address actionModule, bool whitelist) external {

16, 27, 39, 50, 71, 76, 81, 86,

File: contracts/libraries/LegacyCollectLib.sol

45:     function collect(
46:            Types.CollectParams calldata collectParams,
47:            address transactionExecutor,
48:            address collectorProfileOwner,
49:            address collectNFTImpl
50:        ) external returns (uint256) {

45,

File: contracts/libraries/MetaTxLib.sol

43:     function validateSetProfileMetadataURISignature(
44:            Types.EIP712Signature calldata signature,
45:            uint256 profileId,
46:            string calldata metadataURI
47:        ) external {

64:     function validateSetFollowModuleSignature(
65:            Types.EIP712Signature calldata signature,
66:            uint256 profileId,
67:            address followModule,
68:            bytes calldata followModuleInitData
69:        ) external {

87:     function validateChangeDelegatedExecutorsConfigSignature(
88:            Types.EIP712Signature calldata signature,
89:            uint256 delegatorProfileId,
90:            address[] calldata delegatedExecutors,
91:            bool[] calldata approvals,
92:            uint64 configNumber,
93:            bool switchToGivenConfig
94:        ) external {

116:     function validateSetProfileImageURISignature(
117:             Types.EIP712Signature calldata signature,
118:             uint256 profileId,
119:             string calldata imageURI
120:         ) external {

137:     function validatePostSignature(Types.EIP712Signature calldata signature, Types.PostParams calldata postParams)
138:             external
139:         {

225:     function validateCommentSignature(
226:             Types.EIP712Signature calldata signature,
227:             Types.CommentParams calldata commentParams
228:         ) external {

256:     function validateQuoteSignature(Types.EIP712Signature calldata signature, Types.QuoteParams calldata quoteParams)
257:             external
258:         {

286:     function validateMirrorSignature(Types.EIP712Signature calldata signature, Types.MirrorParams calldata mirrorParams)
287:             external
288:         {

309:     function validateBurnSignature(Types.EIP712Signature calldata signature, uint256 tokenId) external {

320:     function validateFollowSignature(
321:             Types.EIP712Signature calldata signature,
322:             uint256 followerProfileId,
323:             uint256[] calldata idsOfProfilesToFollow,
324:             uint256[] calldata followTokenIds,
325:             bytes[] calldata datas
326:         ) external {

357:     function validateUnfollowSignature(
358:             Types.EIP712Signature calldata signature,
359:             uint256 unfollowerProfileId,
360:             uint256[] calldata idsOfProfilesToUnfollow
361:         ) external {

378:     function validateSetBlockStatusSignature(
379:             Types.EIP712Signature calldata signature,
380:             uint256 byProfileId,
381:             uint256[] calldata idsOfProfilesToSetBlockStatus,
382:             bool[] calldata blockStatus
383:         ) external {

401:     function validateLegacyCollectSignature(
402:             Types.EIP712Signature calldata signature,
403:             Types.CollectParams calldata collectParams
404:         ) external {

425:     function validateActSignature(
426:             Types.EIP712Signature calldata signature,
427:             Types.PublicationActionParams calldata publicationActionParams
428:         ) external {

43, 64, 87, 116, 137, 225, 256, 286, 309, 320, 357, 378, 401, 425,

File: contracts/libraries/MigrationLib.sol

20:     function getProfileData(uint256 profileId) external view returns (ProfileData memory);

37:     function batchMigrateProfiles(
38:            uint256[] calldata profileIds,
39:            LensHandles lensHandles,
40:            TokenHandleRegistry tokenHandleRegistry
41:        ) external {

94:     function batchMigrateFollows(
95:            uint256[] calldata followerProfileIds,
96:            uint256[] calldata idsOfProfileFollowed,
97:            uint256[] calldata followTokenIds
98:        ) external {

141:     function batchMigrateFollowModules(
142:             uint256[] calldata profileIds,
143:             address legacyFeeFollowModule,
144:             address legacyProfileFollowModule,
145:             address newFeeFollowModule
146:         ) external {

20, 37, 94, 141,

File: contracts/libraries/ProfileLib.sol

39:     function createProfile(Types.CreateProfileParams calldata createProfileParams, uint256 profileId) external {

81:     function setProfileImageURI(uint256 profileId, string calldata imageURI) external {

92:     function setFollowModule(
93:            uint256 profileId,
94:            address followModule,
95:            bytes calldata followModuleInitData
96:        ) external {

105:     function setProfileMetadataURI(uint256 profileId, string calldata metadataURI) external {

128:     function setBlockStatus(
129:             uint256 byProfileId,
130:             uint256[] calldata idsOfProfilesToSetBlockStatus,
131:             bool[] calldata blockStatus
132:         ) external {

166:     function switchToNewFreshDelegatedExecutorsConfig(uint256 profileId) external {

180:     function changeDelegatedExecutorsConfig(
181:             uint256 delegatorProfileId,
182:             address[] calldata delegatedExecutors,
183:             bool[] calldata approvals
184:         ) external {

198:     function changeGivenDelegatedExecutorsConfig(
199:             uint256 delegatorProfileId,
200:             address[] calldata delegatedExecutors,
201:             bool[] calldata approvals,
202:             uint64 configNumber,
203:             bool switchToGivenConfig
204:         ) external {

215:     function isExecutorApproved(uint256 delegatorProfileId, address delegatedExecutor) external view returns (bool) {

39, 81, 92, 105, 128, 166, 180, 198, 215,

File: contracts/libraries/PublicationLib.sol

22:     function post(Types.PostParams calldata postParams, address transactionExecutor) external returns (uint256) {

63:     function comment(Types.CommentParams calldata commentParams, address transactionExecutor)
64:            external
65:            returns (uint256)
66:        {

103:     function mirror(Types.MirrorParams calldata mirrorParams, address transactionExecutor) external returns (uint256) {

140:     function quote(Types.QuoteParams calldata quoteParams, address transactionExecutor) external returns (uint256) {

190:     function getContentURI(uint256 profileId, uint256 pubId) external view returns (string memory) {

22, 63, 103, 140, 190,

File: contracts/libraries/ValidationLib.sol

121:     function validateLegacyCollectReferrer(
122:             uint256 referrerProfileId,
123:             uint256 referrerPubId,
124:             uint256 publicationCollectedProfileId,
125:             uint256 publicationCollectedId
126:         ) external view {

121,

File: contracts/base/ERC2981CollectionRoyalties.sol

17:     function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {

26:     function setRoyalty(uint256 royaltiesInBasisPoints) external {

39:     function royaltyInfo(uint256 tokenId, uint256 salePrice) external view returns (address, uint256) {

17, 26, 39,

File: contracts/base/LensBaseERC721.sol

79:     function tokenURI(uint256 tokenId) external view virtual returns (string memory);

79,

File: contracts/base/LensHubEventHooks.sol

25:     function emitCollectNFTTransferEvent(
26:            uint256 profileId,
27:            uint256 pubId,
28:            uint256 collectNFTId,
29:            address from,
30:            address to
31:        ) external {

25,

File: contracts/base/LensProfiles.sol

58:     function getTokenGuardianDisablingTimestamp(address wallet) external view returns (uint256) {

63:     function DANGER__disableTokenGuardian() external onlyEOA {

77:     function enableTokenGuardian() external onlyEOA {

58, 63, 77,

File: contracts/misc/LensV2Migration.sol

33:     function batchMigrateProfiles(uint256[] calldata profileIds) external {

37:     function batchMigrateFollows(
38:            uint256[] calldata followerProfileIds,
39:            uint256[] calldata idsOfProfileFollowed,
40:            uint256[] calldata followTokenIds
41:        ) external {

45:     function batchMigrateFollowModules(uint256[] calldata profileIds) external {

33, 37, 45,

File: contracts/misc/LensV2UpgradeContract.sol

44:     function executeLensV2Upgrade() external onlyOwner {

44,

File: contracts/misc/ProfileCreationProxy.sol

33:     function proxyCreateProfile(Types.CreateProfileParams calldata createProfileParams)
34:            external
35:            onlyOwner
36:            returns (uint256)
37:        {

41:     function proxyCreateProfileWithHandle(Types.CreateProfileParams memory createProfileParams, string calldata handle)
42:            external
43:            onlyOwner
44:            returns (uint256, uint256)
45:        {

64:     function proxyCreateHandle(address to, string calldata handle) external onlyOwner returns (uint256) {

33, 41, 64,

File: contracts/misc/access/ControllableByContract.sol

25:     function clearControllerContract() external onlyOwnerOrControllerContract {

30:     function setControllerContract(address newControllerContract) external onlyOwner {

25, 30,

File: contracts/misc/access/Governance.sol

9:     function whitelistCollectModule(address collectModule, bool whitelist) external;

23:     function lensHub_setGovernance(address newGovernance) external onlyOwner {

27:     function lensHub_setEmergencyAdmin(address newEmergencyAdmin) external onlyOwner {

35:     function lensHub_whitelistProfileCreator(address profileCreator, bool whitelist)
36:            external
37:            onlyOwnerOrControllerContract
38:        {

42:     function lensHub_whitelistFollowModule(address followModule, bool whitelist)
43:            external
44:            onlyOwnerOrControllerContract
45:        {

49:     function lensHub_whitelistReferenceModule(address referenceModule, bool whitelist)
50:            external
51:            onlyOwnerOrControllerContract
52:        {

56:     function lensHub_whitelistActionModule(address actionModule, bool whitelist)
57:            external
58:            onlyOwnerOrControllerContract
59:        {

64:     function lensHub_whitelistCollectModule(address collectModule, bool whitelist)
65:            external
66:            onlyOwnerOrControllerContract
67:        {

73:     function executeAsGovernance(address target, bytes calldata data)
74:            external
75:            payable
76:            onlyOwnerOrControllerContract
77:            returns (bytes memory)
78:        {

9, 23, 27, 35, 42, 49, 56, 64, 73,

File: contracts/misc/access/ProxyAdmin.sol

21:     function currentImplementation() external returns (address) {

29:     function rollbackLastUpgrade() external onlyOwner {

33:     function proxy_changeAdmin(address newAdmin) external onlyOwner {

41:     function proxy_upgrade(address newImplementation) external onlyOwnerOrControllerContract {

47:     function proxy_upgradeAndCall(address newImplementation, bytes calldata data)
48:            external
49:            onlyOwnerOrControllerContract
50:        {

21, 29, 33, 41, 47,

File: contracts/namespaces/LensHandles.sol

87:     function mintHandle(address to, string calldata localName)
88:            external
89:            onlyOwnerOrWhitelistedProfileCreator
90:            returns (uint256)
91:        {

96:     function migrateHandle(address to, string calldata localName) external onlyHub returns (uint256) {

101:     function burn(uint256 tokenId) external {

113:     function DANGER__disableTokenGuardian() external onlyEOA {

126:     function enableTokenGuardian() external onlyEOA {

155:     function exists(uint256 tokenId) external view returns (bool) {

159:     function getNamespace() external pure returns (string memory) {

163:     function getNamespaceHash() external pure returns (bytes32) {

168:     function getLocalName(uint256 tokenId) public view returns (string memory) {

177:     function getHandle(uint256 tokenId) public view returns (string memory) {

182:     function getTokenId(string memory localName) public pure returns (uint256) {

186:     function getTokenGuardianDisablingTimestamp(address wallet) external view returns (uint256) {

87, 96, 101, 113, 126, 155, 159, 163, 168, 177, 182, 186,

File: contracts/namespaces/TokenHandleRegistry.sol

50:     function migrationLink(uint256 handleId, uint256 tokenId) external {

61:     function link(
62:            uint256 handleId,
63:            uint256 tokenId
64:        ) external onlyTokenOwner(tokenId, msg.sender) onlyHandleOwner(handleId, msg.sender) {

72:     function unlink(uint256 handleId, uint256 tokenId) external {

94:     function resolve(uint256 handleId) external view returns (uint256) {

107:     function getDefaultHandle(uint256 tokenId) external view returns (uint256) {

50, 61, 72, 94, 107,

File: contracts/interfaces/ICollectModule.sol

31:     function initializePublicationCollectModule(

47:     function processCollect(Types.ProcessCollectParams calldata processCollectParams) external returns (bytes memory);

31, 47,

File: contracts/interfaces/ICollectNFT.sol

21:     function initialize(uint256 profileId, uint256 pubId) external;

32:     function mint(address to) external returns (uint256);

39:     function getSourcePublicationPointer() external view returns (uint256, uint256);

21, 32, 39,

File: contracts/interfaces/IERC721Burnable.sol

18:     function burn(uint256 tokenId) external;

18,

File: contracts/interfaces/IERC721MetaTx.sol

19:     function nonces(address signer) external view returns (uint256);

26:     function getDomainSeparator() external view returns (bytes32);

19, 26,

File: contracts/interfaces/IERC721Timestamped.sol

23:     function mintTimestampOf(uint256 tokenId) external view returns (uint256);

33:     function tokenDataOf(uint256 tokenId) external view returns (Types.TokenData memory);

42:     function exists(uint256 tokenId) external view returns (bool);

49:     function totalSupply() external view returns (uint256);

23, 33, 42, 49,

File: contracts/interfaces/IFollowModule.sol

28:     function initializeFollowModule(

48:     function processFollow(

28, 48,

File: contracts/interfaces/IFollowNFT.sol

33:     function initialize(uint256 profileId) external;

46:     function follow(

59:     function unfollow(uint256 unfollowerProfileId, address transactionExecutor) external;

69:     function removeFollower(uint256 followTokenId) external;

83:     function approveFollow(uint256 approvedProfileId, uint256 followTokenId) external;

94:     function wrap(uint256 followTokenId) external;

106:     function wrap(uint256 followTokenId, address wrappedTokenReceiver) external;

114:     function unwrap(uint256 followTokenId) external;

125:     function processBlock(uint256 followerProfileId) external returns (bool);

138:     function getFollowerProfileId(uint256 followTokenId) external view returns (uint256);

147:     function getOriginalFollowTimestamp(uint256 followTokenId) external view returns (uint256);

156:     function getFollowTimestamp(uint256 followTokenId) external view returns (uint256);

165:     function getProfileIdAllowedToRecover(uint256 followTokenId) external view returns (uint256);

174:     function getFollowData(uint256 followTokenId) external view returns (Types.FollowData memory);

183:     function isFollowing(uint256 followerProfileId) external view returns (bool);

192:     function getFollowTokenId(uint256 followerProfileId) external view returns (uint256);

201:     function getFollowApproved(uint256 followTokenId) external view returns (uint256);

209:     function getFollowerCount() external view returns (uint256);

33, 46, 59, 69, 83, 94, 106, 114, 125, 138, 147, 156, 165, 174, 183, 192, 201, 209,

File: contracts/interfaces/ILegacyCollectModule.sol

23:     function initializePublicationCollectModule(

38:     function processCollect(

23, 38,

File: contracts/interfaces/ILegacyCollectNFT.sol

23:     function initialize(

38:     function mint(address to) external returns (uint256);

45:     function getSourcePublicationPointer() external view returns (uint256, uint256);

23, 38, 45,

File: contracts/interfaces/ILegacyFollowModule.sol

20:     function initializeFollowModule(uint256 profileId, bytes calldata data) external returns (bytes memory);

29:     function processFollow(

48:     function followModuleTransferHook(

77:     function isFollowing(

20, 29, 48, 77,

File: contracts/interfaces/ILegacyReferenceModule.sol

23:     function initializeReferenceModule(

37:     function processComment(

52:     function processMirror(

23, 37, 52,

File: contracts/interfaces/ILensGovernable.sol

20:     function setGovernance(address newGovernance) external;

28:     function setEmergencyAdmin(address newEmergencyAdmin) external;

39:     function setState(Types.ProtocolState newState) external;

48:     function whitelistProfileCreator(address profileCreator, bool whitelist) external;

57:     function whitelistFollowModule(address followModule, bool whitelist) external;

66:     function whitelistReferenceModule(address referenceModule, bool whitelist) external;

76:     function whitelistActionModule(address actionModule, bool whitelist) external;

83:     function getGovernance() external view returns (address);

92:     function getState() external view returns (Types.ProtocolState);

101:     function isProfileCreatorWhitelisted(address profileCreator) external view returns (bool);

110:     function isFollowModuleWhitelisted(address followModule) external view returns (bool);

119:     function isReferenceModuleWhitelisted(address referenceModule) external view returns (bool);

129:     function getActionModuleWhitelistData(address actionModule)

20, 28, 39, 48, 57, 66, 76, 83, 92, 101, 110, 119, 129,

File: contracts/interfaces/ILensHandles.sol

25:     function mintHandle(address to, string calldata localName) external returns (uint256);

33:     function burn(uint256 tokenId) external;

40:     function getNamespace() external pure returns (string memory);

47:     function getNamespaceHash() external pure returns (bytes32);

57:     function exists(uint256 tokenId) external view returns (bool);

25, 33, 40, 47, 57,

File: contracts/interfaces/ILensHubEventHooks.sol

20:     function emitUnfollowedEvent(uint256 unfollowerProfileId, uint256 idOfProfileUnfollowed) external;

20,

File: contracts/interfaces/ILensHubInitializable.sol

23:     function initialize(

23,

File: contracts/interfaces/ILensImplGetters.sol

18:     function getFollowNFTImpl() external view returns (address);

26:     function getCollectNFTImpl() external view returns (address);

18, 26,

File: contracts/interfaces/ILensProfiles.sol

15:     function DANGER__disableTokenGuardian() external;

22:     function enableTokenGuardian() external;

31:     function getTokenGuardianDisablingTimestamp(address wallet) external view returns (uint256);

15, 22, 31,

File: contracts/interfaces/ILensProtocol.sol

21:     function createProfile(Types.CreateProfileParams calldata createProfileParams) external returns (uint256);

30:     function setProfileMetadataURI(uint256 profileId, string calldata metadataURI) external;

35:     function setProfileMetadataURIWithSig(

49:     function setFollowModule(

58:     function setFollowModuleWithSig(

77:     function changeDelegatedExecutorsConfig(

93:     function changeDelegatedExecutorsConfig(

102:     function changeDelegatedExecutorsConfigWithSig(

118:     function setProfileImageURI(uint256 profileId, string calldata imageURI) external;

123:     function setProfileImageURIWithSig(

141:     function post(Types.PostParams calldata postParams) external returns (uint256);

146:     function postWithSig(Types.PostParams calldata postParams, Types.EIP712Signature calldata signature)

163:     function comment(Types.CommentParams calldata commentParams) external returns (uint256);

168:     function commentWithSig(Types.CommentParams calldata commentParams, Types.EIP712Signature calldata signature)

184:     function mirror(Types.MirrorParams calldata mirrorParams) external returns (uint256);

189:     function mirrorWithSig(Types.MirrorParams calldata mirrorParams, Types.EIP712Signature calldata signature)

207:     function quote(Types.QuoteParams calldata quoteParams) external returns (uint256);

212:     function quoteWithSig(Types.QuoteParams calldata quoteParams, Types.EIP712Signature calldata signature)

230:     function follow(

240:     function followWithSig(

255:     function unfollow(uint256 unfollowerProfileId, uint256[] calldata idsOfProfilesToUnfollow) external;

260:     function unfollowWithSig(

279:     function setBlockStatus(

288:     function setBlockStatusWithSig(

306:     function collect(Types.CollectParams calldata collectParams) external returns (uint256);

312:     function collectWithSig(Types.CollectParams calldata collectParams, Types.EIP712Signature calldata signature)

326:     function act(Types.PublicationActionParams calldata publicationActionParams) external returns (bytes memory);

331:     function actWithSig(

348:     function isFollowing(uint256 followerProfileId, uint256 followedProfileId) external view returns (bool);

361:     function isDelegatedExecutorApproved(

377:     function isDelegatedExecutorApproved(uint256 delegatorProfileId, address delegatedExecutor)

389:     function getDelegatedExecutorsConfigNumber(uint256 delegatorProfileId) external view returns (uint64);

400:     function getDelegatedExecutorsPrevConfigNumber(uint256 delegatorProfileId) external view returns (uint64);

412:     function getDelegatedExecutorsMaxConfigNumberSet(uint256 delegatorProfileId) external view returns (uint64);

423:     function isBlocked(uint256 profileId, uint256 byProfileId) external view returns (bool);

432:     function getActionModuleById(uint256 id) external view returns (address);

443:     function getContentURI(uint256 profileId, uint256 pubId) external view returns (string memory);

452:     function getProfile(uint256 profileId) external view returns (Types.Profile memory);

462:     function getPublication(uint256 profileId, uint256 pubId) external view returns (Types.Publication memory);

478:     function getPublicationType(uint256 profileId, uint256 pubId) external view returns (Types.PublicationType);

21, 30, 35, 49, 58, 77, 93, 102, 118, 123, 141, 146, 163, 168, 184, 189, 207, 212, 230, 240, 255, 260, 279, 288, 306, 312, 326, 331, 348, 361, 377, 389, 400, 412, 423, 432, 443, 452, 462, 478,

File: contracts/interfaces/IModuleGlobals.sol

24:     function setGovernance(address newGovernance) external;

32:     function setTreasury(address newTreasury) external;

40:     function setTreasuryFee(uint16 newTreasuryFee) external;

49:     function whitelistCurrency(address currency, bool toWhitelist) external;

62:     function isCurrencyWhitelisted(address currency) external view returns (bool);

69:     function getGovernance() external view returns (address);

76:     function getTreasury() external view returns (address);

83:     function getTreasuryFee() external view returns (uint16);

90:     function getTreasuryData() external view returns (address, uint16);

24, 32, 40, 49, 62, 69, 76, 83, 90,

File: contracts/interfaces/IPublicationActionModule.sol

33:     function initializePublicationAction(

50:     function processPublicationAction(Types.ProcessActionParams calldata processActionParams)

33, 50,

File: contracts/interfaces/IReferenceModule.sol

30:     function initializeReferenceModule(

47:     function processComment(Types.ProcessCommentParams calldata processCommentParams) external returns (bytes memory);

59:     function processQuote(Types.ProcessQuoteParams calldata processQuoteParams) external returns (bytes memory);

71:     function processMirror(Types.ProcessMirrorParams calldata processMirrorParams) external returns (bytes memory);

30, 47, 59, 71,

File: contracts/interfaces/ITokenHandleRegistry.sol

26:     function migrationLink(uint256 handleId, uint256 tokenId) external;

43:     function link(uint256 handleId, uint256 tokenId) external;

58:     function unlink(uint256 handleId, uint256 tokenId) external;

73:     function resolve(uint256 handleId) external view returns (uint256);

88:     function getDefaultHandle(uint256 tokenId) external view returns (uint256);

26, 43, 58, 73, 88,

[N-19] Function names should differ to make the code more readable

In Solidity, while function overriding allows for functions with the same name to coexist, it is advisable to avoid this practice to enhance code readability and maintainability. Having multiple functions with the same name, even with different parameters or in inherited contracts, can cause confusion and increase the likelihood of errors during development, testing, and debugging. Using distinct and descriptive function names not only clarifies the purpose and behavior of each function, but also helps prevent unintended function calls or incorrect overriding. By adopting a clear and consistent naming convention, developers can create more comprehensible and maintainable smart contracts.

Instances (8):

see instances
File: contracts/LensHub.sol

/// @audit function name used on lines  149
165:     function changeDelegatedExecutorsConfig(

/// @audit function name used on lines  498
507:     function isDelegatedExecutorApproved(uint256 delegatorProfileId, address delegatedExecutor)

165, 507,

File: contracts/FollowNFT.sol

/// @audit function name used on lines  156
164:     function wrap(uint256 followTokenId) external override {

164,

File: contracts/libraries/PublicationLib.sol

/// @audit function name used on lines  203
214:     function _asReferencePubParams(Types.CommentParams calldata commentParams)

214,

File: contracts/base/LensBaseERC721.sol

/// @audit function name used on lines  234
245:     function safeTransferFrom(

245,

File: contracts/interfaces/IFollowNFT.sol

/// @audit function name used on lines  94
106:     function wrap(uint256 followTokenId, address wrappedTokenReceiver) external;

106,

File: contracts/interfaces/ILensProtocol.sol

/// @audit function name used on lines  77
93:     function changeDelegatedExecutorsConfig(

/// @audit function name used on lines  361
377:     function isDelegatedExecutorApproved(uint256 delegatorProfileId, address delegatedExecutor)

93, 377,

[N-20] Some variables have a implicit default visibility

Consider always adding an explicit visibility modifier for variables, as the default is internal.

Instances (53):

see instances
File: contracts/FollowNFT.sol

21:     string constant FOLLOW_NFT_NAME_SUFFIX = '-Follower';

22:     string constant FOLLOW_NFT_SYMBOL_SUFFIX = '-Fl';

24:     uint256[5] ___DEPRECATED_SLOTS; // Deprecated slots, previously used for delegations.

21, 22, 24,

File: contracts/libraries/MetaTxLib.sol

21:     string constant EIP712_DOMAIN_VERSION = '2';

22:     bytes32 constant EIP712_DOMAIN_VERSION_HASH = keccak256(bytes(EIP712_DOMAIN_VERSION));

23:     bytes4 constant EIP1271_MAGIC_VALUE = 0x1626ba7e;

38:     bytes32 constant LENS_HUB_CACHED_POLYGON_DOMAIN_SEPARATOR =

41:     address constant LENS_HUB_ADDRESS = 0xDb46d1Dc155634FbC732f92E853b10B288AD5a1d;

21, 22, 23, 38, 41,

File: contracts/libraries/ProfileLib.sol

14:     uint16 constant MAX_PROFILE_IMAGE_URI_LENGTH = 6000;

14,

File: contracts/libraries/StorageLib.sol

11:     uint256 constant TOKEN_DATA_MAPPING_SLOT = 2;

19:     uint256 constant SIG_NONCES_MAPPING_SLOT = 10;

20:     uint256 constant LAST_INITIALIZED_REVISION_SLOT = 11; // VersionedInitializable's `lastInitializedRevision` field.

21:     uint256 constant PROTOCOL_STATE_SLOT = 12;

22:     uint256 constant PROFILE_CREATOR_WHITELIST_MAPPING_SLOT = 13;

23:     uint256 constant FOLLOW_MODULE_WHITELIST_MAPPING_SLOT = 14;

24:     uint256 constant ACTION_MODULE_WHITELIST_DATA_MAPPING_SLOT = 15;

25:     uint256 constant REFERENCE_MODULE_WHITELIST_MAPPING_SLOT = 16;

27:     uint256 constant PROFILE_ID_BY_HANDLE_HASH_MAPPING_SLOT = 18; // Deprecated slot, but still needed for V2 migration.

28:     uint256 constant PROFILES_MAPPING_SLOT = 19;

29:     uint256 constant PUBLICATIONS_MAPPING_SLOT = 20;

31:     uint256 constant PROFILE_COUNTER_SLOT = 22;

32:     uint256 constant GOVERNANCE_SLOT = 23;

33:     uint256 constant EMERGENCY_ADMIN_SLOT = 24;

37:     uint256 constant TOKEN_GUARDIAN_DISABLING_TIMESTAMP_MAPPING_SLOT = 25;

41:     uint256 constant DELEGATED_EXECUTOR_CONFIG_MAPPING_SLOT = 26;

42:     uint256 constant BLOCKED_STATUS_MAPPING_SLOT = 27;

43:     uint256 constant ACTION_MODULES_SLOT = 28;

44:     uint256 constant MAX_ACTION_MODULE_ID_USED_SLOT = 29;

45:     uint256 constant PROFILE_ROYALTIES_BPS_SLOT = 30;

47:     uint256 constant MAX_ACTION_MODULE_ID_SUPPORTED = 255;

11, 19, 20, 21, 22, 23, 24, 25, 27, 28, 29, 31, 32, 33, 37, 41, 42, 43, 44, 45, 47,

File: contracts/libraries/constants/Typehash.sol

7:     bytes32 constant ACT = keccak256('Act(uint256 publicationActedProfileId,uint256 publicationActedId,uint256 actorProfileId,uint256[] referrerProfileIds,uint256[] referrerPubIds,address actionModuleAddress,bytes actionModuleData,uint256 nonce,uint256 deadline)');

9:     bytes32 constant BURN = keccak256('Burn(uint256 tokenId,uint256 nonce,uint256 deadline)');

11:     bytes32 constant CHANGE_DELEGATED_EXECUTORS_CONFIG = keccak256('ChangeDelegatedExecutorsConfig(uint256 delegatorProfileId,address[] delegatedExecutors,bool[] approvals,uint64 configNumber,bool switchToGivenConfig,uint256 nonce,uint256 deadline)');

13:     bytes32 constant LEGACY_COLLECT = keccak256('Collect(uint256 publicationCollectedProfileId,uint256 publicationCollectedId,uint256 collectorProfileId,uint256 referrerProfileId,uint256 referrerPubId,bytes collectModuleData,uint256 nonce,uint256 deadline)');

15:     bytes32 constant COMMENT = keccak256('Comment(uint256 profileId,string contentURI,uint256 pointedProfileId,uint256 pointedPubId,uint256[] referrerProfileIds,uint256[] referrerPubIds,bytes referenceModuleData,address collectModule,bytes collectModuleInitData,address referenceModule,bytes referenceModuleInitData,uint256 nonce,uint256 deadline)');

17:     bytes32 constant EIP712_DOMAIN = keccak256('EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)');

19:     bytes32 constant FOLLOW = keccak256('Follow(uint256 followerProfileId,uint256[] idsOfProfilesToFollow,uint256[] followTokenIds,bytes[] datas,uint256 nonce,uint256 deadline)');

21:     bytes32 constant MIRROR = keccak256('Mirror(uint256 profileId,uint256 pointedProfileId,uint256 pointedPubId,uint256[] referrerProfileId,uint256[] referrerPubId,bytes referenceModuleData,uint256 nonce,uint256 deadline)');

23:     bytes32 constant POST = keccak256('Post(uint256 profileId,string contentURI,address collectModule,bytes collectModuleInitData,address referenceModule,bytes referenceModuleInitData,uint256 nonce,uint256 deadline)');

25:     bytes32 constant QUOTE = keccak256('Quote(uint256 profileId,string contentURI,uint256 pointedProfileId,uint256 pointedPubId,uint256[] referrerProfileIds,uint256[] referrerPubIds,bytes referenceModuleData,address collectModule,bytes collectModuleInitData,address referenceModule,bytes referenceModuleInitData,uint256 nonce,uint256 deadline)');

27:     bytes32 constant SET_BLOCK_STATUS = keccak256('SetBlockStatus(uint256 byProfileId,uint256[] idsOfProfilesToSetBlockStatus,bool[] blockStatus,uint256 nonce,uint256 deadline)');

29:     bytes32 constant SET_FOLLOW_MODULE = keccak256('SetFollowModule(uint256 profileId,address followModule,bytes followModuleInitData,uint256 nonce,uint256 deadline)');

31:     bytes32 constant SET_PROFILE_IMAGE_URI = keccak256('SetProfileImageURI(uint256 profileId,string imageURI,uint256 nonce,uint256 deadline)');

33:     bytes32 constant SET_PROFILE_METADATA_URI = keccak256('SetProfileMetadataURI(uint256 profileId,string metadata,uint256 nonce,uint256 deadline)');

35:     bytes32 constant UNFOLLOW = keccak256('Unfollow(uint256 unfollowerProfileId,uint256[] idsOfProfilesToUnfollow,uint256 nonce,uint256 deadline)');

7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35,

File: contracts/base/LensProfiles.sol

29:     IModuleGlobals immutable MODULE_GLOBALS;

29,

File: contracts/base/upgradeability/FollowNFTProxy.sol

11:     address immutable HUB;

11,

File: contracts/misc/ProfileCreationProxy.sol

20:     ILensHandles immutable LENS_HANDLES;

21:     ITokenHandleRegistry immutable TOKEN_HANDLE_REGISTRY;

20, 21,

File: contracts/namespaces/TokenHandleRegistry.sol

21:     address immutable LENS_HUB;

22:     address immutable LENS_HANDLES;

25:     mapping(bytes32 handle => RegistryTypes.Token token) handleToToken;

26:     mapping(bytes32 token => RegistryTypes.Handle handle) tokenToHandle;

21, 22, 25, 26,

[N-21] Imports could be organized more systematically

The contract's interface should be imported first, followed by each of the interfaces it uses, followed by all other files. The examples below do not follow this layout.

Instances (34):

see instances
File: contracts/LensHub.sol

1: // SPDX-License-Identifier: MIT

1,

File: contracts/FollowNFT.sol

8: import {HubRestricted} from 'contracts/base/HubRestricted.sol';

8,

File: contracts/libraries/ActionLib.sol

7: import {ValidationLib} from 'contracts/libraries/ValidationLib.sol';

7,

File: contracts/libraries/FollowLib.sol

1: // SPDX-License-Identifier: MIT

10: import {StorageLib} from 'contracts/libraries/StorageLib.sol';

1, 10,

File: contracts/libraries/LegacyCollectLib.sol

8: import {Events} from 'contracts/libraries/constants/Events.sol';

8,

File: contracts/libraries/MetaTxLib.sol

1: // SPDX-License-Identifier: MIT

1,

File: contracts/libraries/MigrationLib.sol

10: import {TokenHandleRegistry} from 'contracts/namespaces/TokenHandleRegistry.sol';

10,

File: contracts/libraries/ProfileLib.sol

9: import {StorageLib} from 'contracts/libraries/StorageLib.sol';

9,

File: contracts/libraries/PublicationLib.sol

8: import {Errors} from 'contracts/libraries/constants/Errors.sol';

11: import {StorageLib} from 'contracts/libraries/StorageLib.sol';

8, 11,

File: contracts/base/ERC2981CollectionRoyalties.sol

5: import {Errors} from 'contracts/libraries/constants/Errors.sol';

5,

File: contracts/base/LensBaseERC721.sol

7: import {MetaTxLib} from 'contracts/libraries/MetaTxLib.sol';

16: import {ERC165} from '@openzeppelin/contracts/utils/introspection/ERC165.sol';

7, 16,

File: contracts/base/LensGovernable.sol

1: // SPDX-License-Identifier: MIT

1,

File: contracts/base/LensHubEventHooks.sol

1: // SPDX-License-Identifier: MIT

1,

File: contracts/base/LensImplGetters.sol

1: // SPDX-License-Identifier: MIT

1,

File: contracts/base/LensProfiles.sol

1: // SPDX-License-Identifier: MIT

1,

File: contracts/base/upgradeability/FollowNFTProxy.sol

1: // SPDX-License-Identifier: MIT

1,

File: contracts/misc/LegacyCollectNFT.sol

6: import {Errors} from 'contracts/libraries/constants/Errors.sol';

6,

File: contracts/misc/LensV2UpgradeContract.sol

6: import {Governance} from 'contracts/misc/access/Governance.sol';

6,

File: contracts/misc/ModuleGlobals.sol

6: import {Events} from 'contracts/libraries/constants/Events.sol';

6,

File: contracts/misc/ProfileCreationProxy.sol

1: // SPDX-License-Identifier: MIT

6: import {Types} from 'contracts/libraries/constants/Types.sol';

1, 6,

File: contracts/misc/access/Governance.sol

1: // SPDX-License-Identifier: MIT

1,

File: contracts/namespaces/LensHandles.sol

5: import {ERC721} from '@openzeppelin/contracts/token/ERC721/ERC721.sol';

10: import {HandleTokenURILib} from 'contracts/libraries/token-uris/HandleTokenURILib.sol';

12: import {Address} from '@openzeppelin/contracts/utils/Address.sol';

5, 10, 12,

File: contracts/namespaces/TokenHandleRegistry.sol

1: // SPDX-License-Identifier: MIT

9: import {RegistryEvents} from 'contracts/namespaces/constants/Events.sol';

1, 9,

File: contracts/interfaces/ILensERC721.sol

1: // SPDX-License-Identifier: MIT

1,

File: contracts/interfaces/ILensHandles.sol

1: // SPDX-License-Identifier: MIT

1,

File: contracts/interfaces/ILensHub.sol

1: // SPDX-License-Identifier: MIT

1,

File: contracts/interfaces/ILensProfiles.sol

1: // SPDX-License-Identifier: MIT

1,

[N-22] Inconsistent spacing in comments

Some lines use // x and some use //x. The instances below point out the usages that don't follow the majority, within each file

Instances (4):

File: contracts/base/LensBaseERC721.sol

21:  * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including

223:         //solhint-disable-next-line max-line-length

21, 223,

File: contracts/base/LensGovernable.sol

40:     ///@inheritdoc ILensGovernable

40,

File: contracts/misc/ModuleGlobals.sol

89:     //@inheritdoc IModuleGlobals

89,

[N-23] Large or complicated code bases should implement invariant tests

Large code bases, or code with lots of inline-assembly, complicated math, or complicated interactions between multiple contracts, should implementinvariant fuzzing tests. Invariant fuzzers such as Echidna require the test writer to come up with invariants which should not be violated under any circumstances, and the fuzzer tests various inputs and function calls to ensure that the invariants always hold. Even code with 100% code coverage can still have bugs due to the order of the operations a user performs, and invariant fuzzers, with properly and extensively-written invariants, can close this testing gap significantly.

Instances (10):

see instances
File: Various Files

0: undefined

0: undefined

0: undefined

0: undefined

0: undefined

0: undefined

0: undefined

0: undefined

0: undefined

0: undefined

0, 0, 0, 0, 0, 0, 0, 0, 0, 0,

[N-24] Lines are too long

Usually lines in source code are limited to 80characters. Today's screens are much larger so it's reasonable to stretch this in some cases. The solidity style guide recommends a maximumum line length of 120 characters, so the lines below should be split when they reach that length.

Instances (28):

see instances
File: contracts/libraries/GovernanceLib.sol

51:         // NOTE: This does not follow the CEI-pattern, but there is no interaction and this allows to abstract `_setState` logic.

51,

File: contracts/libraries/MigrationLib.sol

33:      * We would still perform the migration in batches by ourselves, but good to allow users to migrate on their own if they want to.

33,

File: contracts/libraries/constants/Typehash.sol

7:     bytes32 constant ACT = keccak256('Act(uint256 publicationActedProfileId,uint256 publicationActedId,uint256 actorProfileId,uint256[] referrerProfileIds,uint256[] referrerPubIds,address actionModuleAddress,bytes actionModuleData,uint256 nonce,uint256 deadline)');

11:     bytes32 constant CHANGE_DELEGATED_EXECUTORS_CONFIG = keccak256('ChangeDelegatedExecutorsConfig(uint256 delegatorProfileId,address[] delegatedExecutors,bool[] approvals,uint64 configNumber,bool switchToGivenConfig,uint256 nonce,uint256 deadline)');

13:     bytes32 constant LEGACY_COLLECT = keccak256('Collect(uint256 publicationCollectedProfileId,uint256 publicationCollectedId,uint256 collectorProfileId,uint256 referrerProfileId,uint256 referrerPubId,bytes collectModuleData,uint256 nonce,uint256 deadline)');

15:     bytes32 constant COMMENT = keccak256('Comment(uint256 profileId,string contentURI,uint256 pointedProfileId,uint256 pointedPubId,uint256[] referrerProfileIds,uint256[] referrerPubIds,bytes referenceModuleData,address collectModule,bytes collectModuleInitData,address referenceModule,bytes referenceModuleInitData,uint256 nonce,uint256 deadline)');

17:     bytes32 constant EIP712_DOMAIN = keccak256('EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)');

19:     bytes32 constant FOLLOW = keccak256('Follow(uint256 followerProfileId,uint256[] idsOfProfilesToFollow,uint256[] followTokenIds,bytes[] datas,uint256 nonce,uint256 deadline)');

21:     bytes32 constant MIRROR = keccak256('Mirror(uint256 profileId,uint256 pointedProfileId,uint256 pointedPubId,uint256[] referrerProfileId,uint256[] referrerPubId,bytes referenceModuleData,uint256 nonce,uint256 deadline)');

23:     bytes32 constant POST = keccak256('Post(uint256 profileId,string contentURI,address collectModule,bytes collectModuleInitData,address referenceModule,bytes referenceModuleInitData,uint256 nonce,uint256 deadline)');

25:     bytes32 constant QUOTE = keccak256('Quote(uint256 profileId,string contentURI,uint256 pointedProfileId,uint256 pointedPubId,uint256[] referrerProfileIds,uint256[] referrerPubIds,bytes referenceModuleData,address collectModule,bytes collectModuleInitData,address referenceModule,bytes referenceModuleInitData,uint256 nonce,uint256 deadline)');

27:     bytes32 constant SET_BLOCK_STATUS = keccak256('SetBlockStatus(uint256 byProfileId,uint256[] idsOfProfilesToSetBlockStatus,bool[] blockStatus,uint256 nonce,uint256 deadline)');

29:     bytes32 constant SET_FOLLOW_MODULE = keccak256('SetFollowModule(uint256 profileId,address followModule,bytes followModuleInitData,uint256 nonce,uint256 deadline)');

31:     bytes32 constant SET_PROFILE_IMAGE_URI = keccak256('SetProfileImageURI(uint256 profileId,string imageURI,uint256 nonce,uint256 deadline)');

33:     bytes32 constant SET_PROFILE_METADATA_URI = keccak256('SetProfileMetadataURI(uint256 profileId,string metadata,uint256 nonce,uint256 deadline)');

35:     bytes32 constant UNFOLLOW = keccak256('Unfollow(uint256 unfollowerProfileId,uint256[] idsOfProfilesToUnfollow,uint256 nonce,uint256 deadline)');

7, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35,

File: contracts/libraries/constants/Types.sol

150:         uint256 enabledActionModulesBitmap; // In future this can be (uint256 => uint256) mapping if we need >256 modules

194:      * @param referrerProfileId The profile token ID of the publication that referred to the publication being commented on/quoted.

223:      * @param referrerProfileId The profile token ID of the publication that referred to the publication being commented on/quoted.

252:      * @param referrerProfileId The profile token ID of the publication that referred to the publication being commented on/quoted.

150, 194, 223, 252,

File: contracts/base/LensBaseERC721.sol

298:      * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.

298,

File: contracts/base/LensHubStorage.sol

28:     mapping(address actionModule => Types.ActionModuleWhitelistData whitelistData) internal _actionModuleWhitelistData; // Slot 15

38:     mapping(uint256 profileId => mapping(uint256 pubId => Types.Publication publication)) internal _publications; // Slot 20

42:     uint256 internal _profileCounter; // Slot 22 - different from totalSupply, as this is not decreased when burning profiles

59:     mapping(uint256 blockerProfileId => mapping(uint256 blockedProfileId => bool isBlocked)) internal _blockedStatus; // Slot 27

28, 38, 42, 59,

File: contracts/interfaces/ICollectNFT.sol

14:      * @notice Initializes the collect NFT, setting the feed as the privileged minter, storing the collected publication pointer

14,

File: contracts/interfaces/IFollowNFT.sol

181:      * @return uint256 The ID of the profile set as a follower in the given token, zero if it is not being used to follow.

181,

File: contracts/interfaces/ILegacyCollectModule.sol

32:      * @param referrerProfileId The LensHub profile token ID of the referrer's profile (only different in case of mirrors).

32,

[N-25] Long functions should be refactored into multiple functions

Consider splitting long functions into multiple, smaller functions to improve the code readability.

Instances (4):

File: contracts/libraries/LegacyCollectLib.sol

/// @audit number of line: 68
45:     function collect(

45,

File: contracts/libraries/PublicationLib.sol

/// @audit number of line: 51
313:     function _processCommentIfNeeded(

/// @audit number of line: 51
366:     function _processQuoteIfNeeded(

/// @audit number of line: 51
419:     function _processMirrorIfNeeded(

313, 366, 419,

[N-26] NatSpec documentation for contract is missing

It is recommended that Solidity contracts are fully annotated using NatSpec for all public interfaces (everything in the ABI). It is clearly stated in the Solidity official documentation. In complex projects such as Defi, the interpretation of all functions and their arguments and returns is important for code readability and auditability.source

Instances (32):

see instances
File: contracts/FollowNFT.sol

18: contract FollowNFT is HubRestricted, LensBaseERC721, ERC2981CollectionRoyalties, IFollowNFT {

18,

File: contracts/libraries/ActionLib.sol

12: library ActionLib {

12,

File: contracts/libraries/FollowLib.sol

14: library FollowLib {

14,

File: contracts/libraries/GovernanceLib.sol

10: library GovernanceLib {

10,

File: contracts/libraries/MigrationLib.sol

13: interface ILegacyFeeFollowModule {

23: library MigrationLib {

13, 23,

File: contracts/libraries/ProfileLib.sol

13: library ProfileLib {

13,

File: contracts/libraries/PublicationLib.sol

14: library PublicationLib {

14,

File: contracts/libraries/StorageLib.sol

8: library StorageLib {

8,

File: contracts/libraries/constants/Errors.sol

5: library Errors {

5,

File: contracts/libraries/constants/Events.sol

7: library Events {

7,

File: contracts/libraries/constants/Typehash.sol

5: library Typehash {

5,

File: contracts/base/ERC2981CollectionRoyalties.sol

9: abstract contract ERC2981CollectionRoyalties is IERC2981 {

9,

File: contracts/base/LensGovernable.sol

11: abstract contract LensGovernable is ILensGovernable {

11,

File: contracts/base/LensHubEventHooks.sol

10: abstract contract LensHubEventHooks is ILensHubEventHooks {

10,

File: contracts/base/LensImplGetters.sol

7: contract LensImplGetters is ILensImplGetters {

7,

File: contracts/base/LensProfiles.sol

26: abstract contract LensProfiles is LensBaseERC721, ERC2981CollectionRoyalties, ILensProfiles {

26,

File: contracts/base/upgradeability/FollowNFTProxy.sol

9: contract FollowNFTProxy is Proxy {

9,

File: contracts/misc/ImmutableOwnable.sol

5: contract ImmutableOwnable {

5,

File: contracts/misc/LensV2Migration.sol

11: contract LensV2Migration {

11,

File: contracts/misc/LensV2UpgradeContract.sol

9: contract LensV2UpgradeContract is ImmutableOwnable {

9,

File: contracts/misc/access/ControllableByContract.sol

7: contract ControllableByContract is Ownable {

7,

File: contracts/misc/access/Governance.sol

8: interface ILensHub_V1 {

12: contract Governance is ControllableByContract {

8, 12,

File: contracts/misc/access/ProxyAdmin.sol

8: contract ProxyAdmin is ControllableByContract {

8,

File: contracts/namespaces/constants/Errors.sol

5: library RegistryErrors {

14: library HandlesErrors {

5, 14,

File: contracts/namespaces/constants/Events.sol

7: library HandlesEvents {

27: library RegistryEvents {

7, 27,

File: contracts/interfaces/ILensERC721.sol

11: interface ILensERC721 is IERC721, IERC721Timestamped, IERC721Burnable, IERC721MetaTx, IERC721Metadata {}

11,

File: contracts/interfaces/ILensHub.sol

11: interface ILensHub is ILensProfiles, ILensProtocol, ILensGovernable, ILensHubEventHooks, ILensImplGetters {}

11,

File: contracts/interfaces/ILensProfiles.sol

7: interface ILensProfiles is ILensERC721 {

7,

[N-27] NatSpec documentation for function is missing

It is recommended that Solidity contracts are fully annotated using NatSpec for all public interfaces (everything in the ABI). It is clearly stated in the Solidity official documentation. In complex projects such as Defi, the interpretation of all functions and their arguments and returns is important for code readability and auditability.source

Instances (207):

see instances
File: contracts/LensHub.sol

66:     constructor(

165:     function changeDelegatedExecutorsConfig(

566:     function getActionModuleById(uint256 id) external view override returns (address) {

66, 165, 566,

File: contracts/FollowNFT.sol

43:     constructor(address hub) HubRestricted(hub) {

168:     function _wrap(uint256 followTokenId, address wrappedTokenReceiver) internal {

255:     function burn(uint256 followTokenId) public override {

274:     function name() public view override returns (string memory) {

278:     function symbol() public view override returns (string memory) {

297:     function _followMintingNewToken(uint256 followerProfileId) internal returns (uint256) {

311:     function _followWithWrappedToken(

341:     function _followWithUnwrappedTokenFromBurnedProfile(

357:     function _followByRecoveringToken(uint256 followerProfileId, uint256 followTokenId) internal returns (uint256) {

368:     function _replaceFollower(

386:     function _baseFollow(

408:     function _unfollowIfHasFollower(uint256 followTokenId) internal {

416:     function _unfollow(uint256 unfollower, uint256 followTokenId) internal {

428:     function _approveFollow(uint256 approvedProfileId, uint256 followTokenId) internal {

449:     function _getReceiver(

455:     function _beforeRoyaltiesSet(

463:     function _isFollowTokenWrapped(uint256 followTokenId) internal view returns (bool) {

467:     function _getRoyaltiesInBasisPointsSlot() internal pure override returns (uint256) {

43, 168, 255, 274, 278, 297, 311, 341, 357, 368, 386, 408, 416, 428, 449, 455, 463, 467,

File: contracts/libraries/ActionLib.sol

13:     function act(

65:     function _isActionEnabled(Types.Publication storage _publication, uint256 actionModuleId)

13, 65,

File: contracts/libraries/FollowLib.sol

15:     function follow(

54:     function unfollow(

98:     function _follow(

15, 54, 98,

File: contracts/libraries/GovernanceLib.sol

64:     function _setState(Types.ProtocolState newState) private returns (Types.ProtocolState) {

71:     function whitelistProfileCreator(address profileCreator, bool whitelist) external {

76:     function whitelistFollowModule(address followModule, bool whitelist) external {

81:     function whitelistReferenceModule(address referenceModule, bool whitelist) external {

86:     function whitelistActionModule(address actionModule, bool whitelist) external {

64, 71, 76, 81, 86,

File: contracts/libraries/LegacyCollectLib.sol

45:     function collect(

115:     function _getOrDeployCollectNFT(

45, 115,

File: contracts/libraries/MetaTxLib.sol

43:     function validateSetProfileMetadataURISignature(

64:     function validateSetFollowModuleSignature(

87:     function validateChangeDelegatedExecutorsConfigSignature(

116:     function validateSetProfileImageURISignature(

137:     function validatePostSignature(Types.EIP712Signature calldata signature, Types.PostParams calldata postParams)

160:     function _hashActionModulesInitDatas(bytes[] memory actionModulesInitDatas) private pure returns (bytes32) {

190:     function _abiEncode(ReferenceParamsForAbiEncode memory referenceParamsForAbiEncode)

225:     function validateCommentSignature(

256:     function validateQuoteSignature(Types.EIP712Signature calldata signature, Types.QuoteParams calldata quoteParams)

286:     function validateMirrorSignature(Types.EIP712Signature calldata signature, Types.MirrorParams calldata mirrorParams)

309:     function validateBurnSignature(Types.EIP712Signature calldata signature, uint256 tokenId) external {

320:     function validateFollowSignature(

357:     function validateUnfollowSignature(

378:     function validateSetBlockStatusSignature(

401:     function validateLegacyCollectSignature(

425:     function validateActSignature(

450:     function calculateDomainSeparator() internal view returns (bytes32) {

43, 64, 87, 116, 137, 160, 190, 225, 256, 286, 309, 320, 357, 378, 401, 425, 450,

File: contracts/libraries/MigrationLib.sol

20:     function getProfileData(uint256 profileId) external view returns (ProfileData memory);

94:     function batchMigrateFollows(

114:     function _migrateFollow(

141:     function batchMigrateFollowModules(

20, 94, 114, 141,

File: contracts/libraries/ProfileLib.sol

16:     function ownerOf(uint256 profileId) internal view returns (address) {

24:     function exists(uint256 profileId) internal view returns (bool) {

105:     function setProfileMetadataURI(uint256 profileId, string calldata metadataURI) external {

110:     function _initFollowModule(

120:     function _setProfileImageURI(uint256 profileId, string calldata imageURI) private {

128:     function setBlockStatus(

166:     function switchToNewFreshDelegatedExecutorsConfig(uint256 profileId) external {

180:     function changeDelegatedExecutorsConfig(

198:     function changeGivenDelegatedExecutorsConfig(

215:     function isExecutorApproved(uint256 delegatorProfileId, address delegatedExecutor) external view returns (bool) {

222:     function _changeDelegatedExecutorsConfig(

255:     function _prepareStorageToApplyChangesUnderGivenConfig(

16, 24, 105, 110, 120, 128, 166, 180, 198, 215, 222, 255,

File: contracts/libraries/PublicationLib.sol

170:     function getPublicationType(uint256 profileId, uint256 pubId) internal view returns (Types.PublicationType) {

190:     function getContentURI(uint256 profileId, uint256 pubId) external view returns (string memory) {

203:     function _asReferencePubParams(Types.QuoteParams calldata quoteParams)

214:     function _asReferencePubParams(Types.CommentParams calldata commentParams)

225:     function _createReferencePublication(

272:     function _fillReferencePublicationStorage(

291:     function _fillRootOfPublicationInStorage(

313:     function _processCommentIfNeeded(

366:     function _processQuoteIfNeeded(

419:     function _processMirrorIfNeeded(

472:     function _initPubActionModules(

521:     function _initPubReferenceModule(

170, 190, 203, 214, 225, 272, 291, 313, 366, 419, 472, 521,

File: contracts/libraries/StorageLib.sol

49:     function getPublication(uint256 profileId, uint256 pubId)

63:     function getProfile(uint256 profileId) internal pure returns (Types.Profile storage _profiles) {

71:     function getDelegatedExecutorsConfig(uint256 delegatorProfileId)

83:     function tokenGuardianDisablingTimestamp()

93:     function getTokenData(uint256 tokenId) internal pure returns (Types.TokenData storage _tokenData) {

101:     function blockedStatus(uint256 blockerProfileId)

113:     function nonces() internal pure returns (mapping(address => uint256) storage _nonces) {

119:     function profileIdByHandleHash()

129:     function profileCreatorWhitelisted()

139:     function followModuleWhitelisted()

149:     function actionModuleWhitelistData()

159:     function actionModuleById() internal pure returns (mapping(uint256 => address) storage _actionModules) {

165:     function incrementMaxActionModuleIdUsed() internal returns (uint256) {

177:     function referenceModuleWhitelisted()

187:     function getGovernance() internal view returns (address _governance) {

193:     function setGovernance(address newGovernance) internal {

199:     function getEmergencyAdmin() internal view returns (address _emergencyAdmin) {

205:     function setEmergencyAdmin(address newEmergencyAdmin) internal {

211:     function getState() internal view returns (Types.ProtocolState _state) {

217:     function setState(Types.ProtocolState newState) internal {

223:     function getLastInitializedRevision() internal view returns (uint256 _lastInitializedRevision) {

229:     function setLastInitializedRevision(uint256 newLastInitializedRevision) internal {

49, 63, 71, 83, 93, 101, 113, 119, 129, 139, 149, 159, 165, 177, 187, 193, 199, 205, 211, 217, 223, 229,

File: contracts/libraries/ValidationLib.sol

16:     function validatePointedPub(uint256 profileId, uint256 pubId) internal view {

24:     function validateAddressIsProfileOwner(address expectedProfileOwner, uint256 profileId) internal view {

30:     function validateAddressIsProfileOwnerOrDelegatedExecutor(

42:     function validateAddressIsDelegatedExecutor(address expectedDelegatedExecutor, uint256 delegatorProfileId)

51:     function validateReferenceModuleWhitelisted(address referenceModule) internal view {

57:     function validateFollowModuleWhitelisted(address followModule) internal view {

63:     function validateProfileCreatorWhitelisted(address profileCreator) internal view {

69:     function validateNotBlocked(uint256 profile, uint256 byProfile) internal view {

75:     function validateProfileExists(uint256 profileId) internal view {

81:     function validateCallerIsGovernance() internal view {

87:     function validateReferrersAndGetReferrersPubTypes(

121:     function validateLegacyCollectReferrer(

143:     function _validateReferrerAndGetReferrerPubType(

181:     function _validateReferrerAsPost(

16, 24, 30, 42, 51, 57, 63, 69, 75, 81, 87, 121, 143, 181,

File: contracts/base/ERC2981CollectionRoyalties.sol

43:     function _setRoyalty(uint256 royaltiesInBasisPoints) internal virtual {

51:     function _getRoyaltyAmount(

58:     function _storeRoyaltiesInBasisPoints(uint256 royaltiesInBasisPoints) internal virtual {

65:     function _loadRoyaltiesInBasisPoints() internal view virtual returns (uint256) {

74:     function _beforeRoyaltiesSet(uint256 royaltiesInBasisPoints) internal view virtual;

76:     function _getRoyaltiesInBasisPointsSlot() internal view virtual returns (uint256);

78:     function _getReceiver(uint256 tokenId) internal view virtual returns (address);

43, 51, 58, 65, 74, 76, 78,

File: contracts/base/HubRestricted.sol

24:     constructor(address hub) {

24,

File: contracts/base/LensBaseERC721.sol

94:     function nonces(address signer) public view override returns (uint256) {

166:     function totalSupply() external view virtual override returns (uint256) {

94, 166,

File: contracts/base/LensImplGetters.sol

11:     constructor(address followNFTImpl, address collectNFTImpl) {

11,

File: contracts/base/LensProfiles.sol

33:     constructor(address moduleGlobals, uint256 tokenGuardianCooldown) {

112:     function approve(address to, uint256 tokenId) public override(LensBaseERC721, IERC721) {

120:     function setApprovalForAll(address operator, bool approved) public override(LensBaseERC721, IERC721) {

142:     function _hasTokenGuardianEnabled(address wallet) internal view returns (bool) {

149:     function _getRoyaltiesInBasisPointsSlot() internal pure override returns (uint256) {

153:     function _getReceiver(

159:     function _beforeRoyaltiesSet(

165:     function _beforeTokenTransfer(

33, 112, 120, 142, 149, 153, 159, 165,

File: contracts/base/upgradeability/FollowNFTProxy.sol

13:     constructor(bytes memory data) {

18:     function _implementation() internal view override returns (address) {

13, 18,

File: contracts/misc/ImmutableOwnable.sol

26:     constructor(address owner, address lensHub) {

26,

File: contracts/misc/LegacyCollectNFT.sol

38:     constructor(address hub) {

69:     function tokenURI(uint256 tokenId) public view override returns (string memory) {

102:     function _getReceiver(

108:     function _beforeRoyaltiesSet(

116:     function _getRoyaltiesInBasisPointsSlot() internal pure override returns (uint256) {

38, 69, 102, 108, 116,

File: contracts/misc/LensV2Migration.sol

19:     constructor(

33:     function batchMigrateProfiles(uint256[] calldata profileIds) external {

37:     function batchMigrateFollows(

45:     function batchMigrateFollowModules(uint256[] calldata profileIds) external {

19, 33, 37, 45,

File: contracts/misc/LensV2UpgradeContract.sol

20:     constructor(

44:     function executeLensV2Upgrade() external onlyOwner {

50:     function _upgrade() internal {

64:     function _unwhitelistOldFollowModules() internal {

75:     function _unwhitelistOldReferenceModules() internal {

86:     function _unwhitelistOldCollectModules() internal {

97:     function _whitelistNewFollowModules() internal {

108:     function _whitelistNewReferenceModules() internal {

119:     function _whitelistNewActionModules() internal {

20, 44, 50, 64, 75, 86, 97, 108, 119,

File: contracts/misc/ModuleGlobals.sol

90:     function getTreasuryData() external view override returns (address, uint16) {

94:     function _setGovernance(address newGovernance) internal {

101:     function _setTreasury(address newTreasury) internal {

108:     function _setTreasuryFee(uint16 newTreasuryFee) internal {

115:     function _whitelistCurrency(address currency, bool toWhitelist) internal {

90, 94, 101, 108, 115,

File: contracts/misc/ProfileCreationProxy.sol

23:     constructor(

33:     function proxyCreateProfile(Types.CreateProfileParams calldata createProfileParams)

41:     function proxyCreateProfileWithHandle(Types.CreateProfileParams memory createProfileParams, string calldata handle)

64:     function proxyCreateHandle(address to, string calldata handle) external onlyOwner returns (uint256) {

23, 33, 41, 64,

File: contracts/misc/access/ControllableByContract.sol

21:     constructor(address owner) Ownable() {

25:     function clearControllerContract() external onlyOwnerOrControllerContract {

30:     function setControllerContract(address newControllerContract) external onlyOwner {

21, 25, 30,

File: contracts/misc/access/Governance.sol

9:     function whitelistCollectModule(address collectModule, bool whitelist) external;

15:     constructor(address lensHubAddress_, address governanceOwner_) ControllableByContract(governanceOwner_) {

27:     function lensHub_setEmergencyAdmin(address newEmergencyAdmin) external onlyOwner {

42:     function lensHub_whitelistFollowModule(address followModule, bool whitelist)

49:     function lensHub_whitelistReferenceModule(address referenceModule, bool whitelist)

56:     function lensHub_whitelistActionModule(address actionModule, bool whitelist)

64:     function lensHub_whitelistCollectModule(address collectModule, bool whitelist)

73:     function executeAsGovernance(address target, bytes calldata data)

9, 15, 27, 42, 49, 56, 64, 73,

File: contracts/misc/access/ProxyAdmin.sol

12:     constructor(

21:     function currentImplementation() external returns (address) {

33:     function proxy_changeAdmin(address newAdmin) external onlyOwner {

47:     function proxy_upgradeAndCall(address newImplementation, bytes calldata data)

12, 21, 33, 47,

File: contracts/namespaces/LensHandles.sol

62:     constructor(

70:     function name() public pure override returns (string memory) {

74:     function symbol() public pure override returns (string memory) {

96:     function migrateHandle(address to, string calldata localName) external onlyHub returns (uint256) {

101:     function burn(uint256 tokenId) external {

126:     function enableTokenGuardian() external onlyEOA {

139:     function approve(address to, uint256 tokenId) public override(IERC721, ERC721) {

147:     function setApprovalForAll(address operator, bool approved) public override(IERC721, ERC721) {

155:     function exists(uint256 tokenId) external view returns (bool) {

159:     function getNamespace() external pure returns (string memory) {

163:     function getNamespaceHash() external pure returns (bytes32) {

168:     function getLocalName(uint256 tokenId) public view returns (string memory) {

177:     function getHandle(uint256 tokenId) public view returns (string memory) {

182:     function getTokenId(string memory localName) public pure returns (uint256) {

186:     function getTokenGuardianDisablingTimestamp(address wallet) external view returns (uint256) {

202:     function _validateLocalNameMigration(string memory localName) internal view {

226:     function _validateLocalName(string memory localName) internal view {

249:     function _isAlphaNumeric(bytes1 char) internal pure returns (bool) {

253:     function _hasTokenGuardianEnabled(address wallet) internal view returns (bool) {

260:     function _beforeTokenTransfer(

62, 70, 74, 96, 101, 126, 139, 147, 155, 159, 163, 168, 177, 182, 186, 202, 226, 249, 253, 260,

File: contracts/namespaces/TokenHandleRegistry.sol

42:     constructor(address lensHub, address lensHandles) {

50:     function migrationLink(uint256 handleId, uint256 tokenId) external {

128:     function _resolveTokenToHandle(

134:     function _link(RegistryTypes.Handle memory handle, RegistryTypes.Token memory token) internal {

144:     function _deleteTokenToHandleLinkageIfAny(RegistryTypes.Handle memory handle) internal {

152:     function _deleteHandleToTokenLinkageIfAny(RegistryTypes.Token memory token) internal {

160:     function _unlink(RegistryTypes.Handle memory handle, RegistryTypes.Token memory token) internal {

167:     function _handleHash(RegistryTypes.Handle memory handle) internal pure returns (bytes32) {

171:     function _tokenHash(RegistryTypes.Token memory token) internal pure returns (bytes32) {

42, 50, 128, 134, 144, 152, 160, 167, 171,

[N-28] Use @inheritdoc rather than using a non-standard annotation

It is recommended that Solidity contracts are fully annotated using NatSpec for all public interfaces (everything in the ABI). It is clearly stated in the Solidity official documentation. In complex projects such as Defi, the interpretation of all functions and their arguments and returns is important for code readability and auditability.source

Instances (54):

see instances
File: contracts/LensHub.sol

165:     function changeDelegatedExecutorsConfig(
166:             uint256 delegatorProfileId,
167:             address[] calldata delegatedExecutors,
168:             bool[] calldata approvals
169:         ) external override whenNotPaused onlyProfileOwner(msg.sender, delegatorProfileId) {

566:     function getActionModuleById(uint256 id) external view override returns (address) {

165, 566,

File: contracts/FollowNFT.sol

255:     function burn(uint256 followTokenId) public override {

260:     /**
261:          * @dev See {IERC165-supportsInterface}.
262:          */
263:         function supportsInterface(bytes4 interfaceId)
264:             public
265:             view
266:             virtual
267:             override(LensBaseERC721, ERC2981CollectionRoyalties)
268:             returns (bool)
269:         {

274:     function name() public view override returns (string memory) {

278:     function symbol() public view override returns (string memory) {

282:     /**
283:          * @dev This returns the follow NFT URI fetched from the hub.
284:          */
285:         function tokenURI(uint256 followTokenId) public view override returns (string memory) {

433:     /**
434:          * @dev Upon transfers, we clear follow approvals and emit the transfer event in the hub.
435:          */
436:         function _beforeTokenTransfer(
437:             address from,
438:             address to,
439:             uint256 followTokenId
440:         ) internal override {

449:     function _getReceiver(
450:             uint256 /* followTokenId */
451:         ) internal view override returns (address) {

455:     function _beforeRoyaltiesSet(
456:             uint256 /* royaltiesInBasisPoints */
457:         ) internal view override {

467:     function _getRoyaltiesInBasisPointsSlot() internal pure override returns (uint256) {

255, 260, 274, 278, 282, 433, 449, 455, 467,

File: contracts/base/LensBaseERC721.sol

81:     /**
82:         * @dev See {IERC165-supportsInterface}.
83:         */
84:        function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {

94:     function nonces(address signer) public view override returns (uint256) {

103:     /**
104:          * @dev See {IERC721-balanceOf}.
105:          */
106:         function balanceOf(address owner) public view virtual override returns (uint256) {

113:     /**
114:          * @dev See {IERC721-ownerOf}.
115:          */
116:         function ownerOf(uint256 tokenId) public view virtual override returns (address) {

124:     /**
125:          * @dev See {IERC721Timestamped-mintTimestampOf}
126:          */
127:         function mintTimestampOf(uint256 tokenId) public view virtual override returns (uint256) {

135:     /**
136:          * @dev See {IERC721Timestamped-tokenDataOf}
137:          */
138:         function tokenDataOf(uint256 tokenId) public view virtual override returns (Types.TokenData memory) {

145:     /**
146:          * @dev See {IERC721Timestamped-exists}
147:          */
148:         function exists(uint256 tokenId) public view virtual override returns (bool) {

152:     /**
153:          * @dev See {IERC721Metadata-name}.
154:          */
155:         function name() public view virtual override returns (string memory) {

159:     /**
160:          * @dev See {IERC721Metadata-symbol}.
161:          */
162:         function symbol() public view virtual override returns (string memory) {

166:     function totalSupply() external view virtual override returns (uint256) {

170:     /**
171:          * @dev See {IERC721-approve}.
172:          */
173:         function approve(address to, uint256 tokenId) public virtual override {

186:     /**
187:          * @dev See {IERC721-getApproved}.
188:          */
189:         function getApproved(uint256 tokenId) public view virtual override returns (address) {

197:     /**
198:          * @dev See {IERC721-setApprovalForAll}.
199:          */
200:         function setApprovalForAll(address operator, bool approved) public virtual override {

208:     /**
209:          * @dev See {IERC721-isApprovedForAll}.
210:          */
211:         function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {

215:     /**
216:          * @dev See {IERC721-transferFrom}.
217:          */
218:         function transferFrom(
219:             address from,
220:             address to,
221:             uint256 tokenId
222:         ) public virtual override {

231:     /**
232:          * @dev See {IERC721-safeTransferFrom}.
233:          */
234:         function safeTransferFrom(
235:             address from,
236:             address to,
237:             uint256 tokenId
238:         ) public virtual override {

242:     /**
243:          * @dev See {IERC721-safeTransferFrom}.
244:          */
245:         function safeTransferFrom(
246:             address from,
247:             address to,
248:             uint256 tokenId,
249:             bytes memory _data
250:         ) public virtual override {

257:     /**
258:          * @dev Burns `tokenId`.
259:          *
260:          * Requirements:
261:          *
262:          * - The caller must own `tokenId` or be an approved operator.
263:          */
264:         function burn(uint256 tokenId) public virtual override {

81, 94, 103, 113, 124, 135, 145, 152, 159, 166, 170, 186, 197, 208, 215, 231, 242, 257,

File: contracts/base/LensGovernable.sol

69:     /**
70:         * @notice Returns the current protocol state.
71:         *
72:         * @return ProtocolState The Protocol state, an enum, where:
73:         *      0: Unpaused
74:         *      1: PublishingPaused
75:         *      2: Paused
76:         */
77:        function getState() external view override returns (Types.ProtocolState) {

69,

File: contracts/base/LensProfiles.sol

90:     /**
91:         * @notice Burns a profile, this maintains the profile data struct.
92:         */
93:        function burn(uint256 tokenId)
94:            public
95:            override(LensBaseERC721, IERC721Burnable)
96:            whenNotPaused
97:            onlyProfileOwner(msg.sender, tokenId)
98:        {

102:     /**
103:          * @dev Overrides the ERC721 tokenURI function to return the associated URI with a given profile.
104:          */
105:         function tokenURI(uint256 tokenId) public view override(LensBaseERC721, IERC721Metadata) returns (string memory) {

112:     function approve(address to, uint256 tokenId) public override(LensBaseERC721, IERC721) {

120:     function setApprovalForAll(address operator, bool approved) public override(LensBaseERC721, IERC721) {

128:     /**
129:          * @dev See {IERC165-supportsInterface}.
130:          */
131:         function supportsInterface(bytes4 interfaceId)
132:             public
133:             view
134:             virtual
135:             override(LensBaseERC721, ERC2981CollectionRoyalties, IERC165)
136:             returns (bool)
137:         {

149:     function _getRoyaltiesInBasisPointsSlot() internal pure override returns (uint256) {

153:     function _getReceiver(
154:             uint256 /* tokenId */
155:         ) internal view override returns (address) {

159:     function _beforeRoyaltiesSet(
160:             uint256 /* royaltiesInBasisPoints */
161:         ) internal view override {

165:     function _beforeTokenTransfer(
166:             address from,
167:             address to,
168:             uint256 tokenId
169:         ) internal override whenNotPaused {

90, 102, 112, 120, 128, 149, 153, 159, 165,

File: contracts/base/upgradeability/FollowNFTProxy.sol

18:     function _implementation() internal view override returns (address) {

18,

File: contracts/misc/LegacyCollectNFT.sol

69:     function tokenURI(uint256 tokenId) public view override returns (string memory) {

74:     /**
75:         * @dev See {IERC721Metadata-name}.
76:         */
77:        function name() public view override returns (string memory) {

81:     /**
82:         * @dev See {IERC721Metadata-symbol}.
83:         */
84:        function symbol() public pure override returns (string memory) {

88:     /**
89:         * @dev See {IERC165-supportsInterface}.
90:         */
91:        function supportsInterface(bytes4 interfaceId)
92:            public
93:            view
94:            virtual
95:            override(ERC2981CollectionRoyalties, LensBaseERC721)
96:            returns (bool)
97:        {

102:     function _getReceiver(
103:             uint256 /* tokenId */
104:         ) internal view override returns (address) {

108:     function _beforeRoyaltiesSet(
109:             uint256 /* royaltiesInBasisPoints */
110:         ) internal view override {

116:     function _getRoyaltiesInBasisPointsSlot() internal pure override returns (uint256) {

69, 74, 81, 88, 102, 108, 116,

File: contracts/misc/ModuleGlobals.sol

90:     function getTreasuryData() external view override returns (address, uint16) {

90,

File: contracts/namespaces/LensHandles.sol

70:     function name() public pure override returns (string memory) {

74:     function symbol() public pure override returns (string memory) {

78:     /**
79:         * @dev See {IERC721Metadata-tokenURI}.
80:         */
81:        function tokenURI(uint256 tokenId) public view override returns (string memory) {

139:     function approve(address to, uint256 tokenId) public override(IERC721, ERC721) {

147:     function setApprovalForAll(address operator, bool approved) public override(IERC721, ERC721) {

260:     function _beforeTokenTransfer(
261:             address from,
262:             address to,
263:             uint256 /* firstTokenId */,
264:             uint256 batchSize
265:         ) internal override {

70, 74, 78, 139, 147, 260,

[N-29] NatSpec @param is missing

It is recommended that Solidity contracts are fully annotated using NatSpec for all public interfaces (everything in the ABI). It is clearly stated in the Solidity official documentation. In complex projects such as Defi, the interpretation of all functions and their arguments and returns is important for code readability and auditability.source

Instances (348):

see instances
File: contracts/LensHub.sol

66:     constructor(
67:            address moduleGlobals,
68:            address followNFTImpl,
69:            address collectNFTImpl, // We still pass the deprecated CollectNFTImpl for legacy Collects to work
70:            address lensHandlesAddress,
71:            address tokenHandleRegistryAddress,
72:            address legacyFeeFollowModule,
73:            address legacyProfileFollowModule,
74:            address newFeeFollowModule,
75:            uint256 tokenGuardianCooldown
76:        )
77:            LensProfiles(moduleGlobals, tokenGuardianCooldown)
78:            LensV2Migration(
79:                legacyFeeFollowModule,
80:                legacyProfileFollowModule,
81:                newFeeFollowModule,
82:                lensHandlesAddress,
83:                tokenHandleRegistryAddress
84:            )
85:            LensImplGetters(followNFTImpl, collectNFTImpl)
86:        {}

88:     /// @inheritdoc ILensProtocol
89:        function createProfile(Types.CreateProfileParams calldata createProfileParams)
90:            external
91:            override
92:            whenNotPaused
93:            returns (uint256)
94:        {

108:     /// @inheritdoc ILensProtocol
109:         function setProfileMetadataURI(uint256 profileId, string calldata metadataURI)
110:             external
111:             override
112:             whenNotPaused
113:             onlyProfileOwnerOrDelegatedExecutor(msg.sender, profileId)
114:         {

118:     /// @inheritdoc ILensProtocol
119:         function setProfileMetadataURIWithSig(
120:             uint256 profileId,
121:             string calldata metadataURI,
122:             Types.EIP712Signature calldata signature
123:         ) external override whenNotPaused onlyProfileOwnerOrDelegatedExecutor(signature.signer, profileId) {

128:     /// @inheritdoc ILensProtocol
129:         function setFollowModule(
130:             uint256 profileId,
131:             address followModule,
132:             bytes calldata followModuleInitData
133:         ) external override whenNotPaused onlyProfileOwnerOrDelegatedExecutor(msg.sender, profileId) {

137:     /// @inheritdoc ILensProtocol
138:         function setFollowModuleWithSig(
139:             uint256 profileId,
140:             address followModule,
141:             bytes calldata followModuleInitData,
142:             Types.EIP712Signature calldata signature
143:         ) external override whenNotPaused onlyProfileOwnerOrDelegatedExecutor(signature.signer, profileId) {

148:     /// @inheritdoc ILensProtocol
149:         function changeDelegatedExecutorsConfig(
150:             uint256 delegatorProfileId,
151:             address[] calldata delegatedExecutors,
152:             bool[] calldata approvals,
153:             uint64 configNumber,
154:             bool switchToGivenConfig
155:         ) external override whenNotPaused onlyProfileOwner(msg.sender, delegatorProfileId) {

165:     function changeDelegatedExecutorsConfig(
166:             uint256 delegatorProfileId,
167:             address[] calldata delegatedExecutors,
168:             bool[] calldata approvals
169:         ) external override whenNotPaused onlyProfileOwner(msg.sender, delegatorProfileId) {

173:     /// @inheritdoc ILensProtocol
174:         function changeDelegatedExecutorsConfigWithSig(
175:             uint256 delegatorProfileId,
176:             address[] calldata delegatedExecutors,
177:             bool[] calldata approvals,
178:             uint64 configNumber,
179:             bool switchToGivenConfig,
180:             Types.EIP712Signature calldata signature
181:         ) external override whenNotPaused onlyProfileOwner(signature.signer, delegatorProfileId) {

199:     /// @inheritdoc ILensProtocol
200:         function setProfileImageURI(uint256 profileId, string calldata imageURI)
201:             external
202:             override
203:             whenNotPaused
204:             onlyProfileOwnerOrDelegatedExecutor(msg.sender, profileId)
205:         {

209:     /// @inheritdoc ILensProtocol
210:         function setProfileImageURIWithSig(
211:             uint256 profileId,
212:             string calldata imageURI,
213:             Types.EIP712Signature calldata signature
214:         ) external override whenNotPaused onlyProfileOwnerOrDelegatedExecutor(signature.signer, profileId) {

223:     /// @inheritdoc ILensProtocol
224:         function post(Types.PostParams calldata postParams)
225:             external
226:             override
227:             whenPublishingEnabled
228:             onlyProfileOwnerOrDelegatedExecutor(msg.sender, postParams.profileId)
229:             returns (uint256)
230:         {

234:     /// @inheritdoc ILensProtocol
235:         function postWithSig(Types.PostParams calldata postParams, Types.EIP712Signature calldata signature)
236:             external
237:             override
238:             whenPublishingEnabled
239:             onlyProfileOwnerOrDelegatedExecutor(signature.signer, postParams.profileId)
240:             returns (uint256)
241:         {

246:     /// @inheritdoc ILensProtocol
247:         function comment(Types.CommentParams calldata commentParams)
248:             external
249:             override
250:             whenPublishingEnabled
251:             onlyProfileOwnerOrDelegatedExecutor(msg.sender, commentParams.profileId)
252:             returns (uint256)
253:         {

257:     /// @inheritdoc ILensProtocol
258:         function commentWithSig(Types.CommentParams calldata commentParams, Types.EIP712Signature calldata signature)
259:             external
260:             override
261:             whenPublishingEnabled
262:             onlyProfileOwnerOrDelegatedExecutor(signature.signer, commentParams.profileId)
263:             returns (uint256)
264:         {

269:     /// @inheritdoc ILensProtocol
270:         function mirror(Types.MirrorParams calldata mirrorParams)
271:             external
272:             override
273:             whenPublishingEnabled
274:             onlyProfileOwnerOrDelegatedExecutor(msg.sender, mirrorParams.profileId)
275:             returns (uint256)
276:         {

280:     /// @inheritdoc ILensProtocol
281:         function mirrorWithSig(Types.MirrorParams calldata mirrorParams, Types.EIP712Signature calldata signature)
282:             external
283:             override
284:             whenPublishingEnabled
285:             onlyProfileOwnerOrDelegatedExecutor(signature.signer, mirrorParams.profileId)
286:             returns (uint256)
287:         {

292:     /// @inheritdoc ILensProtocol
293:         function quote(Types.QuoteParams calldata quoteParams)
294:             external
295:             override
296:             whenPublishingEnabled
297:             onlyProfileOwnerOrDelegatedExecutor(msg.sender, quoteParams.profileId)
298:             returns (uint256)
299:         {

303:     /// @inheritdoc ILensProtocol
304:         function quoteWithSig(Types.QuoteParams calldata quoteParams, Types.EIP712Signature calldata signature)
305:             external
306:             override
307:             whenPublishingEnabled
308:             onlyProfileOwnerOrDelegatedExecutor(signature.signer, quoteParams.profileId)
309:             returns (uint256)
310:         {

319:     /// @inheritdoc ILensProtocol
320:         function follow(
321:             uint256 followerProfileId,
322:             uint256[] calldata idsOfProfilesToFollow,
323:             uint256[] calldata followTokenIds,
324:             bytes[] calldata datas
325:         )
326:             external
327:             override
328:             whenNotPaused
329:             onlyProfileOwnerOrDelegatedExecutor(msg.sender, followerProfileId)
330:             returns (uint256[] memory)
331:         {

342:     /// @inheritdoc ILensProtocol
343:         function followWithSig(
344:             uint256 followerProfileId,
345:             uint256[] calldata idsOfProfilesToFollow,
346:             uint256[] calldata followTokenIds,
347:             bytes[] calldata datas,
348:             Types.EIP712Signature calldata signature
349:         )
350:             external
351:             override
352:             whenNotPaused
353:             onlyProfileOwnerOrDelegatedExecutor(signature.signer, followerProfileId)
354:             returns (uint256[] memory)
355:         {

367:     /// @inheritdoc ILensProtocol
368:         function unfollow(uint256 unfollowerProfileId, uint256[] calldata idsOfProfilesToUnfollow)
369:             external
370:             override
371:             whenNotPaused
372:             onlyProfileOwnerOrDelegatedExecutor(msg.sender, unfollowerProfileId)
373:         {

381:     /// @inheritdoc ILensProtocol
382:         function unfollowWithSig(
383:             uint256 unfollowerProfileId,
384:             uint256[] calldata idsOfProfilesToUnfollow,
385:             Types.EIP712Signature calldata signature
386:         ) external override whenNotPaused onlyProfileOwnerOrDelegatedExecutor(signature.signer, unfollowerProfileId) {

396:     /// @inheritdoc ILensProtocol
397:         function setBlockStatus(
398:             uint256 byProfileId,
399:             uint256[] calldata idsOfProfilesToSetBlockStatus,
400:             bool[] calldata blockStatus
401:         ) external override whenNotPaused onlyProfileOwnerOrDelegatedExecutor(msg.sender, byProfileId) {

405:     /// @inheritdoc ILensProtocol
406:         function setBlockStatusWithSig(
407:             uint256 byProfileId,
408:             uint256[] calldata idsOfProfilesToSetBlockStatus,
409:             bool[] calldata blockStatus,
410:             Types.EIP712Signature calldata signature
411:         ) external override whenNotPaused onlyProfileOwnerOrDelegatedExecutor(signature.signer, byProfileId) {

416:     /// @inheritdoc ILensProtocol
417:         function collect(Types.CollectParams calldata collectParams)
418:             external
419:             override
420:             whenNotPaused
421:             onlyProfileOwnerOrDelegatedExecutor(msg.sender, collectParams.collectorProfileId)
422:             returns (uint256)
423:         {

433:     /// @inheritdoc ILensProtocol
434:         function collectWithSig(Types.CollectParams calldata collectParams, Types.EIP712Signature calldata signature)
435:             external
436:             override
437:             whenNotPaused
438:             onlyProfileOwnerOrDelegatedExecutor(signature.signer, collectParams.collectorProfileId)
439:             returns (uint256)
440:         {

451:     /// @inheritdoc ILensProtocol
452:         function act(Types.PublicationActionParams calldata publicationActionParams)
453:             external
454:             override
455:             whenNotPaused
456:             onlyProfileOwnerOrDelegatedExecutor(msg.sender, publicationActionParams.actorProfileId)
457:             returns (bytes memory)
458:         {

467:     /// @inheritdoc ILensProtocol
468:         function actWithSig(
469:             Types.PublicationActionParams calldata publicationActionParams,
470:             Types.EIP712Signature calldata signature
471:         )
472:             external
473:             override
474:             whenNotPaused
475:             onlyProfileOwnerOrDelegatedExecutor(signature.signer, publicationActionParams.actorProfileId)
476:             returns (bytes memory)
477:         {

491:     /// @inheritdoc ILensProtocol
492:         function isFollowing(uint256 followerProfileId, uint256 followedProfileId) external view returns (bool) {

497:     /// @inheritdoc ILensProtocol
498:         function isDelegatedExecutorApproved(
499:             uint256 delegatorProfileId,
500:             address delegatedExecutor,
501:             uint64 configNumber
502:         ) external view returns (bool) {

506:     /// @inheritdoc ILensProtocol
507:         function isDelegatedExecutorApproved(uint256 delegatorProfileId, address delegatedExecutor)
508:             external
509:             view
510:             returns (bool)
511:         {

515:     /// @inheritdoc ILensProtocol
516:         function getDelegatedExecutorsConfigNumber(uint256 delegatorProfileId) external view returns (uint64) {

520:     /// @inheritdoc ILensProtocol
521:         function getDelegatedExecutorsPrevConfigNumber(uint256 delegatorProfileId) external view returns (uint64) {

525:     /// @inheritdoc ILensProtocol
526:         function getDelegatedExecutorsMaxConfigNumberSet(uint256 delegatorProfileId) external view returns (uint64) {

530:     /// @inheritdoc ILensProtocol
531:         function isBlocked(uint256 profileId, uint256 byProfileId) external view returns (bool) {

535:     /// @inheritdoc ILensProtocol
536:         function getContentURI(uint256 profileId, uint256 pubId) external view override returns (string memory) {

541:     /// @inheritdoc ILensProtocol
542:         function getProfile(uint256 profileId) external view override returns (Types.Profile memory) {

546:     /// @inheritdoc ILensProtocol
547:         function getPublication(uint256 profileId, uint256 pubId)
548:             external
549:             view
550:             override
551:             returns (Types.Publication memory)
552:         {

556:     /// @inheritdoc ILensProtocol
557:         function getPublicationType(uint256 profileId, uint256 pubId)
558:             external
559:             view
560:             override
561:             returns (Types.PublicationType)
562:         {

566:     function getActionModuleById(uint256 id) external view override returns (address) {

66, 88, 108, 118, 128, 137, 148, 165, 173, 199, 209, 223, 234, 246, 257, 269, 280, 292, 303, 319, 342, 367, 381, 396, 405, 416, 433, 451, 467, 491, 497, 506, 515, 520, 525, 530, 535, 541, 546, 556, 566,

File: contracts/FollowNFT.sol

43:     constructor(address hub) HubRestricted(hub) {

47:     /// @inheritdoc IFollowNFT
48:        function initialize(uint256 profileId) external override {

58:     /// @inheritdoc IFollowNFT
59:        function follow(
60:            uint256 followerProfileId,
61:            address transactionExecutor,
62:            uint256 followTokenId
63:        ) external override onlyHub returns (uint256) {

102:     /// @inheritdoc IFollowNFT
103:         function unfollow(uint256 unfollowerProfileId, address transactionExecutor) external override onlyHub {

130:     /// @inheritdoc IFollowNFT
131:         function removeFollower(uint256 followTokenId) external override {

140:     /// @inheritdoc IFollowNFT
141:         function approveFollow(uint256 followerProfileId, uint256 followTokenId) external override {

155:     /// @inheritdoc IFollowNFT
156:         function wrap(uint256 followTokenId, address wrappedTokenReceiver) external override {

163:     /// @inheritdoc IFollowNFT
164:         function wrap(uint256 followTokenId) external override {

168:     function _wrap(uint256 followTokenId, address wrappedTokenReceiver) internal {

187:     /// @inheritdoc IFollowNFT
188:         function unwrap(uint256 followTokenId) external override {

195:     /// @inheritdoc IFollowNFT
196:         function processBlock(uint256 followerProfileId) external override onlyHub returns (bool) {

210:     /// @inheritdoc IFollowNFT
211:         function getFollowerProfileId(uint256 followTokenId) external view override returns (uint256) {

215:     /// @inheritdoc IFollowNFT
216:         function isFollowing(uint256 followerProfileId) external view override returns (bool) {

220:     /// @inheritdoc IFollowNFT
221:         function getFollowTokenId(uint256 followerProfileId) external view override returns (uint256) {

225:     /// @inheritdoc IFollowNFT
226:         function getOriginalFollowTimestamp(uint256 followTokenId) external view override returns (uint256) {

230:     /// @inheritdoc IFollowNFT
231:         function getFollowTimestamp(uint256 followTokenId) external view override returns (uint256) {

235:     /// @inheritdoc IFollowNFT
236:         function getProfileIdAllowedToRecover(uint256 followTokenId) external view override returns (uint256) {

240:     /// @inheritdoc IFollowNFT
241:         function getFollowData(uint256 followTokenId) external view override returns (Types.FollowData memory) {

245:     /// @inheritdoc IFollowNFT
246:         function getFollowApproved(uint256 followTokenId) external view override returns (uint256) {

255:     function burn(uint256 followTokenId) public override {

260:     /**
261:          * @dev See {IERC165-supportsInterface}.
262:          */
263:         function supportsInterface(bytes4 interfaceId)
264:             public
265:             view
266:             virtual
267:             override(LensBaseERC721, ERC2981CollectionRoyalties)
268:             returns (bool)
269:         {

274:     function name() public view override returns (string memory) {

278:     function symbol() public view override returns (string memory) {

282:     /**
283:          * @dev This returns the follow NFT URI fetched from the hub.
284:          */
285:         function tokenURI(uint256 followTokenId) public view override returns (string memory) {

297:     function _followMintingNewToken(uint256 followerProfileId) internal returns (uint256) {

311:     function _followWithWrappedToken(
312:             uint256 followerProfileId,
313:             address transactionExecutor,
314:             uint256 followTokenId,
315:             address followTokenOwner
316:         ) internal returns (uint256) {

341:     function _followWithUnwrappedTokenFromBurnedProfile(
342:             uint256 followerProfileId,
343:             uint256 followTokenId,
344:             uint256 currentFollowerProfileId
345:         ) internal returns (uint256) {

357:     function _followByRecoveringToken(uint256 followerProfileId, uint256 followTokenId) internal returns (uint256) {

368:     function _replaceFollower(
369:             uint256 currentFollowerProfileId,
370:             uint256 newFollowerProfileId,
371:             uint256 followTokenId
372:         ) internal {

386:     function _baseFollow(
387:             uint256 followerProfileId,
388:             uint256 followTokenId,
389:             bool isOriginalFollow
390:         ) internal {

408:     function _unfollowIfHasFollower(uint256 followTokenId) internal {

416:     function _unfollow(uint256 unfollower, uint256 followTokenId) internal {

428:     function _approveFollow(uint256 approvedProfileId, uint256 followTokenId) internal {

433:     /**
434:          * @dev Upon transfers, we clear follow approvals and emit the transfer event in the hub.
435:          */
436:         function _beforeTokenTransfer(
437:             address from,
438:             address to,
439:             uint256 followTokenId
440:         ) internal override {

449:     function _getReceiver(
450:             uint256 /* followTokenId */
451:         ) internal view override returns (address) {

455:     function _beforeRoyaltiesSet(
456:             uint256 /* royaltiesInBasisPoints */
457:         ) internal view override {

463:     function _isFollowTokenWrapped(uint256 followTokenId) internal view returns (bool) {

467:     function _getRoyaltiesInBasisPointsSlot() internal pure override returns (uint256) {

476:     /// Migrations ///
477:         //////////////////
478:     
479:         // This function shouldn't fail under no circumstances, except if wrong parameters are passed.
480:         function tryMigrate(
481:             uint256 followerProfileId,
482:             address followerProfileOwner,
483:             uint256 idOfProfileFollowed,
484:             uint256 followTokenId
485:         ) external onlyHub returns (uint48) {

43, 47, 58, 102, 130, 140, 155, 163, 168, 187, 195, 210, 215, 220, 225, 230, 235, 240, 245, 255, 260, 274, 278, 282, 297, 311, 341, 357, 368, 386, 408, 416, 428, 433, 449, 455, 463, 467, 476,

File: contracts/libraries/ActionLib.sol

13:     function act(
14:            Types.PublicationActionParams calldata publicationActionParams,
15:            address transactionExecutor,
16:            address actorProfileOwner
17:        ) external returns (bytes memory) {

65:     function _isActionEnabled(Types.Publication storage _publication, uint256 actionModuleId)
66:            private
67:            view
68:            returns (bool)
69:        {

13, 65,

File: contracts/libraries/FollowLib.sol

15:     function follow(
16:            uint256 followerProfileId,
17:            address transactionExecutor,
18:            uint256[] calldata idsOfProfilesToFollow,
19:            uint256[] calldata followTokenIds,
20:            bytes[] calldata followModuleDatas
21:        ) external returns (uint256[] memory) {

54:     function unfollow(
55:            uint256 unfollowerProfileId,
56:            address transactionExecutor,
57:            uint256[] calldata idsOfProfilesToUnfollow
58:        ) external {

98:     function _follow(
99:            uint256 followerProfileId,
100:            address transactionExecutor,
101:            uint256 idOfProfileToFollow,
102:            uint256 followTokenId,
103:            bytes calldata followModuleData
104:        ) private returns (uint256) {

15, 54, 98,

File: contracts/libraries/GovernanceLib.sol

64:     function _setState(Types.ProtocolState newState) private returns (Types.ProtocolState) {

71:     function whitelistProfileCreator(address profileCreator, bool whitelist) external {

76:     function whitelistFollowModule(address followModule, bool whitelist) external {

81:     function whitelistReferenceModule(address referenceModule, bool whitelist) external {

86:     function whitelistActionModule(address actionModule, bool whitelist) external {

64, 71, 76, 81, 86,

File: contracts/libraries/LegacyCollectLib.sol

45:     function collect(
46:            Types.CollectParams calldata collectParams,
47:            address transactionExecutor,
48:            address collectorProfileOwner,
49:            address collectNFTImpl
50:        ) external returns (uint256) {

115:     function _getOrDeployCollectNFT(
116:             Types.Publication storage _collectedPublication,
117:             uint256 publicationCollectedProfileId,
118:             uint256 publicationCollectedId,
119:             address collectNFTImpl
120:         ) private returns (address) {

45, 115,

File: contracts/libraries/MetaTxLib.sol

43:     function validateSetProfileMetadataURISignature(
44:            Types.EIP712Signature calldata signature,
45:            uint256 profileId,
46:            string calldata metadataURI
47:        ) external {

64:     function validateSetFollowModuleSignature(
65:            Types.EIP712Signature calldata signature,
66:            uint256 profileId,
67:            address followModule,
68:            bytes calldata followModuleInitData
69:        ) external {

87:     function validateChangeDelegatedExecutorsConfigSignature(
88:            Types.EIP712Signature calldata signature,
89:            uint256 delegatorProfileId,
90:            address[] calldata delegatedExecutors,
91:            bool[] calldata approvals,
92:            uint64 configNumber,
93:            bool switchToGivenConfig
94:        ) external {

116:     function validateSetProfileImageURISignature(
117:             Types.EIP712Signature calldata signature,
118:             uint256 profileId,
119:             string calldata imageURI
120:         ) external {

137:     function validatePostSignature(Types.EIP712Signature calldata signature, Types.PostParams calldata postParams)
138:             external
139:         {

160:     function _hashActionModulesInitDatas(bytes[] memory actionModulesInitDatas) private pure returns (bytes32) {

190:     function _abiEncode(ReferenceParamsForAbiEncode memory referenceParamsForAbiEncode)
191:             private
192:             pure
193:             returns (bytes memory)
194:         {

225:     function validateCommentSignature(
226:             Types.EIP712Signature calldata signature,
227:             Types.CommentParams calldata commentParams
228:         ) external {

256:     function validateQuoteSignature(Types.EIP712Signature calldata signature, Types.QuoteParams calldata quoteParams)
257:             external
258:         {

286:     function validateMirrorSignature(Types.EIP712Signature calldata signature, Types.MirrorParams calldata mirrorParams)
287:             external
288:         {

309:     function validateBurnSignature(Types.EIP712Signature calldata signature, uint256 tokenId) external {

320:     function validateFollowSignature(
321:             Types.EIP712Signature calldata signature,
322:             uint256 followerProfileId,
323:             uint256[] calldata idsOfProfilesToFollow,
324:             uint256[] calldata followTokenIds,
325:             bytes[] calldata datas
326:         ) external {

357:     function validateUnfollowSignature(
358:             Types.EIP712Signature calldata signature,
359:             uint256 unfollowerProfileId,
360:             uint256[] calldata idsOfProfilesToUnfollow
361:         ) external {

378:     function validateSetBlockStatusSignature(
379:             Types.EIP712Signature calldata signature,
380:             uint256 byProfileId,
381:             uint256[] calldata idsOfProfilesToSetBlockStatus,
382:             bool[] calldata blockStatus
383:         ) external {

401:     function validateLegacyCollectSignature(
402:             Types.EIP712Signature calldata signature,
403:             Types.CollectParams calldata collectParams
404:         ) external {

425:     function validateActSignature(
426:             Types.EIP712Signature calldata signature,
427:             Types.PublicationActionParams calldata publicationActionParams
428:         ) external {

450:     function calculateDomainSeparator() internal view returns (bytes32) {

466:     /**
467:          * @dev Wrapper for ecrecover to reduce code size, used in meta-tx specific functions.
468:          */
469:         function _validateRecoveredAddress(bytes32 digest, Types.EIP712Signature calldata signature) private view {

43, 64, 87, 116, 137, 160, 190, 225, 256, 286, 309, 320, 357, 378, 401, 425, 450, 466,

File: contracts/libraries/MigrationLib.sol

20:     function getProfileData(uint256 profileId) external view returns (ProfileData memory);

31:     /**
32:         * @notice Migrates an array of profiles from V1 to V2. This function can be callable by anyone.
33:         * We would still perform the migration in batches by ourselves, but good to allow users to migrate on their own if they want to.
34:         *
35:         * @param profileIds The array of profile IDs to migrate.
36:         */
37:        function batchMigrateProfiles(
38:            uint256[] calldata profileIds,
39:            LensHandles lensHandles,
40:            TokenHandleRegistry tokenHandleRegistry
41:        ) external {

51:     /**
52:         * @notice Migrates a profile from V1 to V2.
53:         *
54:         * @dev We do not revert in any case, as we want to allow the migration to continue even if one profile fails
55:         *      (and it usually fails if already migrated or profileNFT moved).
56:         * @dev Estimated gas cost of one profile migration is around 178k gas.
57:         *
58:         * @param profileId The profile ID to migrate.
59:         */
60:        function _migrateProfile(
61:            uint256 profileId,
62:            LensHandles lensHandles,
63:            TokenHandleRegistry tokenHandleRegistry
64:        ) private {

94:     function batchMigrateFollows(
95:            uint256[] calldata followerProfileIds,
96:            uint256[] calldata idsOfProfileFollowed,
97:            uint256[] calldata followTokenIds
98:        ) external {

114:     function _migrateFollow(
115:             uint256 followerProfileId,
116:             uint256 idOfProfileFollowed,
117:             uint256 followTokenId
118:         ) private {

141:     function batchMigrateFollowModules(
142:             uint256[] calldata profileIds,
143:             address legacyFeeFollowModule,
144:             address legacyProfileFollowModule,
145:             address newFeeFollowModule
146:         ) external {

20, 31, 51, 94, 114, 141,

File: contracts/libraries/ProfileLib.sol

16:     function ownerOf(uint256 profileId) internal view returns (address) {

24:     function exists(uint256 profileId) internal view returns (bool) {

105:     function setProfileMetadataURI(uint256 profileId, string calldata metadataURI) external {

110:     function _initFollowModule(
111:             uint256 profileId,
112:             address transactionExecutor,
113:             address followModule,
114:             bytes memory followModuleInitData
115:         ) private returns (bytes memory) {

120:     function _setProfileImageURI(uint256 profileId, string calldata imageURI) private {

128:     function setBlockStatus(
129:             uint256 byProfileId,
130:             uint256[] calldata idsOfProfilesToSetBlockStatus,
131:             bool[] calldata blockStatus
132:         ) external {

166:     function switchToNewFreshDelegatedExecutorsConfig(uint256 profileId) external {

180:     function changeDelegatedExecutorsConfig(
181:             uint256 delegatorProfileId,
182:             address[] calldata delegatedExecutors,
183:             bool[] calldata approvals
184:         ) external {

198:     function changeGivenDelegatedExecutorsConfig(
199:             uint256 delegatorProfileId,
200:             address[] calldata delegatedExecutors,
201:             bool[] calldata approvals,
202:             uint64 configNumber,
203:             bool switchToGivenConfig
204:         ) external {

215:     function isExecutorApproved(uint256 delegatorProfileId, address delegatedExecutor) external view returns (bool) {

222:     function _changeDelegatedExecutorsConfig(
223:             Types.DelegatedExecutorsConfig storage _delegatedExecutorsConfig,
224:             uint256 delegatorProfileId,
225:             address[] memory delegatedExecutors,
226:             bool[] memory approvals,
227:             uint64 configNumber,
228:             bool switchToGivenConfig
229:         ) private {

255:     function _prepareStorageToApplyChangesUnderGivenConfig(
256:             Types.DelegatedExecutorsConfig storage _delegatedExecutorsConfig,
257:             uint64 configNumber,
258:             bool switchToGivenConfig
259:         ) private returns (bool) {

16, 24, 105, 110, 120, 128, 166, 180, 198, 215, 222, 255,

File: contracts/libraries/PublicationLib.sol

15:     /**
16:         * @notice Publishes a post to a given profile.
17:         *
18:         * @param postParams The PostParams struct.
19:         *
20:         * @return uint256 The created publication's pubId.
21:         */
22:        function post(Types.PostParams calldata postParams, address transactionExecutor) external returns (uint256) {

56:     /**
57:         * @notice Publishes a comment to a given profile via signature.
58:         *
59:         * @param commentParams the CommentParams struct.
60:         *
61:         * @return uint256 The created publication's pubId.
62:         */
63:        function comment(Types.CommentParams calldata commentParams, address transactionExecutor)
64:            external
65:            returns (uint256)
66:        {

96:     /**
97:         * @notice Publishes a mirror to a given profile.
98:         *
99:         * @param mirrorParams the MirrorParams struct.
100:         *
101:         * @return uint256 The created publication's pubId.
102:         */
103:        function mirror(Types.MirrorParams calldata mirrorParams, address transactionExecutor) external returns (uint256) {

133:     /**
134:          * @notice Publishes a quote publication to a given profile via signature.
135:          *
136:          * @param quoteParams the QuoteParams struct.
137:          *
138:          * @return uint256 The created publication's pubId.
139:          */
140:         function quote(Types.QuoteParams calldata quoteParams, address transactionExecutor) external returns (uint256) {

170:     function getPublicationType(uint256 profileId, uint256 pubId) internal view returns (Types.PublicationType) {

190:     function getContentURI(uint256 profileId, uint256 pubId) external view returns (string memory) {

203:     function _asReferencePubParams(Types.QuoteParams calldata quoteParams)
204:             private
205:             pure
206:             returns (Types.ReferencePubParams calldata referencePubParams)
207:         {

214:     function _asReferencePubParams(Types.CommentParams calldata commentParams)
215:             private
216:             pure
217:             returns (Types.ReferencePubParams calldata referencePubParams)
218:         {

225:     function _createReferencePublication(
226:             Types.ReferencePubParams calldata referencePubParams,
227:             address transactionExecutor,
228:             Types.PublicationType referencePubType
229:         )
230:             private
231:             returns (
232:                 uint256,
233:                 bytes[] memory,
234:                 bytes memory,
235:                 Types.PublicationType[] memory
236:             )
237:         {

272:     function _fillReferencePublicationStorage(
273:             Types.ReferencePubParams calldata referencePubParams,
274:             Types.PublicationType referencePubType
275:         ) private returns (uint256) {

291:     function _fillRootOfPublicationInStorage(
292:             Types.Publication storage _publication,
293:             uint256 pointedProfileId,
294:             uint256 pointedPubId
295:         ) internal {

313:     function _processCommentIfNeeded(
314:             Types.CommentParams calldata commentParams,
315:             address transactionExecutor,
316:             Types.PublicationType[] memory referrerPubTypes
317:         ) private returns (bytes memory) {

366:     function _processQuoteIfNeeded(
367:             Types.QuoteParams calldata quoteParams,
368:             address transactionExecutor,
369:             Types.PublicationType[] memory referrerPubTypes
370:         ) private returns (bytes memory) {

419:     function _processMirrorIfNeeded(
420:             Types.MirrorParams calldata mirrorParams,
421:             address transactionExecutor,
422:             Types.PublicationType[] memory referrerPubTypes
423:         ) private returns (bytes memory) {

472:     function _initPubActionModules(
473:             uint256 profileId,
474:             address transactionExecutor,
475:             uint256 pubId,
476:             address[] calldata actionModules,
477:             bytes[] calldata actionModulesInitDatas
478:         ) private returns (bytes[] memory) {

521:     function _initPubReferenceModule(
522:             uint256 profileId,
523:             address transactionExecutor,
524:             uint256 pubId,
525:             address referenceModule,
526:             bytes memory referenceModuleInitData
527:         ) private returns (bytes memory) {

15, 56, 96, 133, 170, 190, 203, 214, 225, 272, 291, 313, 366, 419, 472, 521,

File: contracts/libraries/StorageLib.sol

49:     function getPublication(uint256 profileId, uint256 pubId)
50:            internal
51:            pure
52:            returns (Types.Publication storage _publication)
53:        {

63:     function getProfile(uint256 profileId) internal pure returns (Types.Profile storage _profiles) {

71:     function getDelegatedExecutorsConfig(uint256 delegatorProfileId)
72:            internal
73:            pure
74:            returns (Types.DelegatedExecutorsConfig storage _delegatedExecutorsConfig)
75:        {

83:     function tokenGuardianDisablingTimestamp()
84:            internal
85:            pure
86:            returns (mapping(address => uint256) storage _tokenGuardianDisablingTimestamp)
87:        {

93:     function getTokenData(uint256 tokenId) internal pure returns (Types.TokenData storage _tokenData) {

101:     function blockedStatus(uint256 blockerProfileId)
102:             internal
103:             pure
104:             returns (mapping(uint256 => bool) storage _blockedStatus)
105:         {

113:     function nonces() internal pure returns (mapping(address => uint256) storage _nonces) {

119:     function profileIdByHandleHash()
120:             internal
121:             pure
122:             returns (mapping(bytes32 => uint256) storage _profileIdByHandleHash)
123:         {

129:     function profileCreatorWhitelisted()
130:             internal
131:             pure
132:             returns (mapping(address => bool) storage _profileCreatorWhitelisted)
133:         {

139:     function followModuleWhitelisted()
140:             internal
141:             pure
142:             returns (mapping(address => bool) storage _followModuleWhitelisted)
143:         {

149:     function actionModuleWhitelistData()
150:             internal
151:             pure
152:             returns (mapping(address => Types.ActionModuleWhitelistData) storage _actionModuleWhitelistData)
153:         {

159:     function actionModuleById() internal pure returns (mapping(uint256 => address) storage _actionModules) {

165:     function incrementMaxActionModuleIdUsed() internal returns (uint256) {

177:     function referenceModuleWhitelisted()
178:             internal
179:             pure
180:             returns (mapping(address => bool) storage _referenceModuleWhitelisted)
181:         {

187:     function getGovernance() internal view returns (address _governance) {

193:     function setGovernance(address newGovernance) internal {

199:     function getEmergencyAdmin() internal view returns (address _emergencyAdmin) {

205:     function setEmergencyAdmin(address newEmergencyAdmin) internal {

211:     function getState() internal view returns (Types.ProtocolState _state) {

217:     function setState(Types.ProtocolState newState) internal {

223:     function getLastInitializedRevision() internal view returns (uint256 _lastInitializedRevision) {

229:     function setLastInitializedRevision(uint256 newLastInitializedRevision) internal {

49, 63, 71, 83, 93, 101, 113, 119, 129, 139, 149, 159, 165, 177, 187, 193, 199, 205, 211, 217, 223, 229,

File: contracts/libraries/ValidationLib.sol

16:     function validatePointedPub(uint256 profileId, uint256 pubId) internal view {

24:     function validateAddressIsProfileOwner(address expectedProfileOwner, uint256 profileId) internal view {

30:     function validateAddressIsProfileOwnerOrDelegatedExecutor(
31:            address expectedOwnerOrDelegatedExecutor,
32:            uint256 profileId
33:        ) internal view {

42:     function validateAddressIsDelegatedExecutor(address expectedDelegatedExecutor, uint256 delegatorProfileId)
43:            internal
44:            view
45:        {

51:     function validateReferenceModuleWhitelisted(address referenceModule) internal view {

57:     function validateFollowModuleWhitelisted(address followModule) internal view {

63:     function validateProfileCreatorWhitelisted(address profileCreator) internal view {

69:     function validateNotBlocked(uint256 profile, uint256 byProfile) internal view {

75:     function validateProfileExists(uint256 profileId) internal view {

81:     function validateCallerIsGovernance() internal view {

87:     function validateReferrersAndGetReferrersPubTypes(
88:            uint256[] memory referrerProfileIds,
89:            uint256[] memory referrerPubIds,
90:            uint256 targetedProfileId,
91:            uint256 targetedPubId
92:        ) internal view returns (Types.PublicationType[] memory) {

121:     function validateLegacyCollectReferrer(
122:             uint256 referrerProfileId,
123:             uint256 referrerPubId,
124:             uint256 publicationCollectedProfileId,
125:             uint256 publicationCollectedId
126:         ) external view {

143:     function _validateReferrerAndGetReferrerPubType(
144:             uint256 referrerProfileId,
145:             uint256 referrerPubId,
146:             uint256 targetedProfileId,
147:             uint256 targetedPubId
148:         ) private view returns (Types.PublicationType) {

181:     function _validateReferrerAsPost(
182:             uint256 referrerProfileId,
183:             uint256 referrerPubId,
184:             uint256 targetedProfileId,
185:             uint256 targetedPubId
186:         ) private view {

16, 24, 30, 42, 51, 57, 63, 69, 75, 81, 87, 121, 143, 181,

File: contracts/base/ERC2981CollectionRoyalties.sol

14:     /**
15:         * @dev See {IERC165-supportsInterface}.
16:         */
17:        function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {

43:     function _setRoyalty(uint256 royaltiesInBasisPoints) internal virtual {

51:     function _getRoyaltyAmount(
52:            uint256, /* tokenId */
53:            uint256 salePrice
54:        ) internal view virtual returns (uint256) {

58:     function _storeRoyaltiesInBasisPoints(uint256 royaltiesInBasisPoints) internal virtual {

65:     function _loadRoyaltiesInBasisPoints() internal view virtual returns (uint256) {

74:     function _beforeRoyaltiesSet(uint256 royaltiesInBasisPoints) internal view virtual;

76:     function _getRoyaltiesInBasisPointsSlot() internal view virtual returns (uint256);

78:     function _getReceiver(uint256 tokenId) internal view virtual returns (address);

14, 43, 51, 58, 65, 74, 76, 78,

File: contracts/base/HubRestricted.sol

24:     constructor(address hub) {

24,

File: contracts/base/LensBaseERC721.sol

76:     /**

81:     /**
82:         * @dev See {IERC165-supportsInterface}.
83:         */
84:        function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {

94:     function nonces(address signer) public view override returns (uint256) {

103:     /**
104:          * @dev See {IERC721-balanceOf}.
105:          */
106:         function balanceOf(address owner) public view virtual override returns (uint256) {

113:     /**
114:          * @dev See {IERC721-ownerOf}.
115:          */
116:         function ownerOf(uint256 tokenId) public view virtual override returns (address) {

124:     /**
125:          * @dev See {IERC721Timestamped-mintTimestampOf}
126:          */
127:         function mintTimestampOf(uint256 tokenId) public view virtual override returns (uint256) {

135:     /**
136:          * @dev See {IERC721Timestamped-tokenDataOf}
137:          */
138:         function tokenDataOf(uint256 tokenId) public view virtual override returns (Types.TokenData memory) {

145:     /**
146:          * @dev See {IERC721Timestamped-exists}
147:          */
148:         function exists(uint256 tokenId) public view virtual override returns (bool) {

166:     function totalSupply() external view virtual override returns (uint256) {

170:     /**
171:          * @dev See {IERC721-approve}.
172:          */
173:         function approve(address to, uint256 tokenId) public virtual override {

186:     /**
187:          * @dev See {IERC721-getApproved}.
188:          */
189:         function getApproved(uint256 tokenId) public view virtual override returns (address) {

197:     /**
198:          * @dev See {IERC721-setApprovalForAll}.
199:          */
200:         function setApprovalForAll(address operator, bool approved) public virtual override {

208:     /**
209:          * @dev See {IERC721-isApprovedForAll}.
210:          */
211:         function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {

215:     /**
216:          * @dev See {IERC721-transferFrom}.
217:          */
218:         function transferFrom(
219:             address from,
220:             address to,
221:             uint256 tokenId
222:         ) public virtual override {

231:     /**
232:          * @dev See {IERC721-safeTransferFrom}.
233:          */
234:         function safeTransferFrom(
235:             address from,
236:             address to,
237:             uint256 tokenId
238:         ) public virtual override {

242:     /**
243:          * @dev See {IERC721-safeTransferFrom}.
244:          */
245:         function safeTransferFrom(
246:             address from,
247:             address to,
248:             uint256 tokenId,
249:             bytes memory _data
250:         ) public virtual override {

257:     /**
258:          * @dev Burns `tokenId`.
259:          *
260:          * Requirements:
261:          *
262:          * - The caller must own `tokenId` or be an approved operator.
263:          */
264:         function burn(uint256 tokenId) public virtual override {

284:     /**
285:          * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
286:          * are aware of the ERC721 protocol to prevent tokens from being forever locked.
287:          *
288:          * `_data` is additional data, it has no specified format and it is sent in call to `to`.
289:          *
290:          * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.
291:          * implement alternative mechanisms to perform a token transfer, such as signature-based.
292:          *
293:          * Requirements:
294:          *
295:          * - `from` cannot be the zero address.
296:          * - `to` cannot be the zero address.
297:          * - `tokenId` token must exist and be owned by `from`.
298:          * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
299:          *
300:          * Emits a {Transfer} event.
301:          */
302:         function _safeTransfer(
303:             address from,
304:             address to,
305:             uint256 tokenId,
306:             bytes memory _data
307:         ) internal virtual {

314:     /**
315:          * @dev Returns whether `tokenId` exists.
316:          *
317:          * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.
318:          *
319:          * Tokens start existing when they are minted (`_mint`),
320:          * and stop existing when they are burned (`_burn`).
321:          */
322:         function _exists(uint256 tokenId) internal view virtual returns (bool) {

326:     /**
327:          * @dev Returns whether `spender` is allowed to manage `tokenId`.
328:          *
329:          * Requirements:
330:          *
331:          * - `tokenId` must exist.
332:          */
333:         function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {

341:     /**
342:          * @dev Mints `tokenId` and transfers it to `to`.
343:          *
344:          * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible
345:          *
346:          * Requirements:
347:          *
348:          * - `tokenId` must not exist.
349:          * - `to` cannot be the zero address.
350:          *
351:          * Emits a {Transfer} event.
352:          */
353:         function _mint(address to, uint256 tokenId) internal virtual {

370:     /**
371:          * @dev Destroys `tokenId`.
372:          * The approval is cleared when the token is burned.
373:          *
374:          * Requirements:
375:          *
376:          * - `tokenId` must exist.
377:          *
378:          * Emits a {Transfer} event.
379:          */
380:         function _burn(uint256 tokenId) internal virtual {

397:     /**
398:          * @dev Transfers `tokenId` from `from` to `to`.
399:          *  As opposed to {transferFrom}, this imposes no restrictions on msg.sender.
400:          *
401:          * Requirements:
402:          *
403:          * - `to` cannot be the zero address.
404:          * - `tokenId` token must be owned by `from`.
405:          *
406:          * Emits a {Transfer} event.
407:          */
408:         function _transfer(
409:             address from,
410:             address to,
411:             uint256 tokenId
412:         ) internal virtual {

434:     /**
435:          * @dev Approve `to` to operate on `tokenId`
436:          *
437:          * Emits a {Approval} event.
438:          */
439:         function _approve(address to, uint256 tokenId) internal virtual {

444:     /**
445:          * @dev Refactored from the original OZ ERC721 implementation: approve or revoke approval from
446:          * `operator` to operate on all tokens owned by `owner`.
447:          *
448:          * Emits a {ApprovalForAll} event.
449:          */
450:         function _setOperatorApproval(
451:             address owner,
452:             address operator,
453:             bool approved
454:         ) internal virtual {

492:     /**
493:          * @dev Hook that is called before any token transfer. This includes minting
494:          * and burning.
495:          *
496:          * Calling conditions:
497:          *
498:          * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be
499:          * transferred to `to`.
500:          * - When `from` is zero, `tokenId` will be minted for `to`.
501:          * - When `to` is zero, ``from``'s `tokenId` will be burned.
502:          * - `from` and `to` are never both zero.
503:          *
504:          * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
505:          */
506:         function _beforeTokenTransfer(
507:             address from,
508:             address to,
509:             uint256 tokenId
510:         ) internal virtual {}

76, 81, 94, 103, 113, 124, 135, 145, 166, 170, 186, 197, 208, 215, 231, 242, 257, 284, 314, 326, 341, 370, 397, 434, 444, 492,

File: contracts/base/LensGovernable.sol

24:     /// @inheritdoc ILensGovernable
25:        function setGovernance(address newGovernance) external override onlyGov {

29:     /// @inheritdoc ILensGovernable
30:        function setEmergencyAdmin(address newEmergencyAdmin) external override onlyGov {

34:     /// @inheritdoc ILensGovernable
35:        function setState(Types.ProtocolState newState) external override {

40:     ///@inheritdoc ILensGovernable
41:        function whitelistProfileCreator(address profileCreator, bool whitelist) external override onlyGov {

45:     /// @inheritdoc ILensGovernable
46:        function whitelistFollowModule(address followModule, bool whitelist) external override onlyGov {

50:     /// @inheritdoc ILensGovernable
51:        function whitelistReferenceModule(address referenceModule, bool whitelist) external override onlyGov {

55:     /// @inheritdoc ILensGovernable
56:        function whitelistActionModule(address actionModule, bool whitelist) external override onlyGov {

81:     /// @inheritdoc ILensGovernable
82:        function isProfileCreatorWhitelisted(address profileCreator) external view override returns (bool) {

86:     /// @inheritdoc ILensGovernable
87:        function isFollowModuleWhitelisted(address followModule) external view override returns (bool) {

91:     /// @inheritdoc ILensGovernable
92:        function isReferenceModuleWhitelisted(address referenceModule) external view override returns (bool) {

96:     /// @inheritdoc ILensGovernable
97:        function getActionModuleWhitelistData(address actionModule)
98:            external
99:            view
100:            override
101:            returns (Types.ActionModuleWhitelistData memory)
102:        {

24, 29, 34, 40, 45, 50, 55, 81, 86, 91, 96,

File: contracts/base/LensHubEventHooks.sol

11:     /// @inheritdoc ILensHubEventHooks
12:        function emitUnfollowedEvent(uint256 unfollowerProfileId, uint256 idOfProfileUnfollowed) external override {

21:     ///       DEPRECATED FUNCTIONS     ///
22:        //////////////////////////////////////
23:    
24:        // Deprecated in V2. Kept here just for backwards compatibility with Lens V1 Collect NFTs.
25:        function emitCollectNFTTransferEvent(
26:            uint256 profileId,
27:            uint256 pubId,
28:            uint256 collectNFTId,
29:            address from,
30:            address to
31:        ) external {

11, 21,

File: contracts/base/LensImplGetters.sol

11:     constructor(address followNFTImpl, address collectNFTImpl) {

11,

File: contracts/base/LensProfiles.sol

33:     constructor(address moduleGlobals, uint256 tokenGuardianCooldown) {

57:     /// @inheritdoc ILensProfiles
58:        function getTokenGuardianDisablingTimestamp(address wallet) external view returns (uint256) {

90:     /**
91:         * @notice Burns a profile, this maintains the profile data struct.
92:         */
93:        function burn(uint256 tokenId)
94:            public
95:            override(LensBaseERC721, IERC721Burnable)
96:            whenNotPaused
97:            onlyProfileOwner(msg.sender, tokenId)
98:        {

102:     /**
103:          * @dev Overrides the ERC721 tokenURI function to return the associated URI with a given profile.
104:          */
105:         function tokenURI(uint256 tokenId) public view override(LensBaseERC721, IERC721Metadata) returns (string memory) {

112:     function approve(address to, uint256 tokenId) public override(LensBaseERC721, IERC721) {

120:     function setApprovalForAll(address operator, bool approved) public override(LensBaseERC721, IERC721) {

128:     /**
129:          * @dev See {IERC165-supportsInterface}.
130:          */
131:         function supportsInterface(bytes4 interfaceId)
132:             public
133:             view
134:             virtual
135:             override(LensBaseERC721, ERC2981CollectionRoyalties, IERC165)
136:             returns (bool)
137:         {

142:     function _hasTokenGuardianEnabled(address wallet) internal view returns (bool) {

149:     function _getRoyaltiesInBasisPointsSlot() internal pure override returns (uint256) {

153:     function _getReceiver(
154:             uint256 /* tokenId */
155:         ) internal view override returns (address) {

159:     function _beforeRoyaltiesSet(
160:             uint256 /* royaltiesInBasisPoints */
161:         ) internal view override {

165:     function _beforeTokenTransfer(
166:             address from,
167:             address to,
168:             uint256 tokenId
169:         ) internal override whenNotPaused {

33, 57, 90, 102, 112, 120, 128, 142, 149, 153, 159, 165,

File: contracts/base/upgradeability/FollowNFTProxy.sol

13:     constructor(bytes memory data) {

18:     function _implementation() internal view override returns (address) {

13, 18,

File: contracts/misc/ImmutableOwnable.sol

26:     constructor(address owner, address lensHub) {

26,

File: contracts/misc/LegacyCollectNFT.sol

38:     constructor(address hub) {

44:     /// @inheritdoc ICollectNFT
45:        function initialize(uint256 profileId, uint256 pubId) external override {

54:     /// @inheritdoc ICollectNFT
55:        function mint(address to) external override returns (uint256) {

69:     function tokenURI(uint256 tokenId) public view override returns (string memory) {

88:     /**
89:         * @dev See {IERC165-supportsInterface}.
90:         */
91:        function supportsInterface(bytes4 interfaceId)
92:            public
93:            view
94:            virtual
95:            override(ERC2981CollectionRoyalties, LensBaseERC721)
96:            returns (bool)
97:        {

102:     function _getReceiver(
103:             uint256 /* tokenId */
104:         ) internal view override returns (address) {

108:     function _beforeRoyaltiesSet(
109:             uint256 /* royaltiesInBasisPoints */
110:         ) internal view override {

116:     function _getRoyaltiesInBasisPointsSlot() internal pure override returns (uint256) {

38, 44, 54, 69, 88, 102, 108, 116,

File: contracts/misc/LensV2Migration.sol

19:     constructor(
20:            address legacyFeeFollowModule,
21:            address legacyProfileFollowModule,
22:            address newFeeFollowModule,
23:            address lensHandlesAddress,
24:            address tokenHandleRegistryAddress
25:        ) {

33:     function batchMigrateProfiles(uint256[] calldata profileIds) external {

37:     function batchMigrateFollows(
38:            uint256[] calldata followerProfileIds,
39:            uint256[] calldata idsOfProfileFollowed,
40:            uint256[] calldata followTokenIds
41:        ) external {

45:     function batchMigrateFollowModules(uint256[] calldata profileIds) external {

19, 33, 37, 45,

File: contracts/misc/LensV2UpgradeContract.sol

20:     constructor(
21:            address proxyAdminAddress,
22:            address governanceAddress,
23:            address owner,
24:            address lensHub,
25:            address newImplementationAddress,
26:            address[] memory oldFollowModulesToUnwhitelist_,
27:            address[] memory newFollowModulesToWhitelist_,
28:            address[] memory oldReferenceModulesToUnwhitelist_,
29:            address[] memory newReferenceModulesToWhitelist_,
30:            address[] memory oldCollectModulesToUnwhitelist_,
31:            address[] memory newActionModulesToWhitelist_
32:        ) ImmutableOwnable(owner, lensHub) {

44:     function executeLensV2Upgrade() external onlyOwner {

50:     function _upgrade() internal {

64:     function _unwhitelistOldFollowModules() internal {

75:     function _unwhitelistOldReferenceModules() internal {

86:     function _unwhitelistOldCollectModules() internal {

97:     function _whitelistNewFollowModules() internal {

108:     function _whitelistNewReferenceModules() internal {

119:     function _whitelistNewActionModules() internal {

20, 44, 50, 64, 75, 86, 97, 108, 119,

File: contracts/misc/ModuleGlobals.sol

49:     /// @inheritdoc IModuleGlobals
50:        function setGovernance(address newGovernance) external override onlyGov {

54:     /// @inheritdoc IModuleGlobals
55:        function setTreasury(address newTreasury) external override onlyGov {

59:     /// @inheritdoc IModuleGlobals
60:        function setTreasuryFee(uint16 newTreasuryFee) external override onlyGov {

64:     /// @inheritdoc IModuleGlobals
65:        function whitelistCurrency(address currency, bool toWhitelist) external override onlyGov {

69:     /// @inheritdoc IModuleGlobals
70:        function isCurrencyWhitelisted(address currency) external view override returns (bool) {

90:     function getTreasuryData() external view override returns (address, uint16) {

94:     function _setGovernance(address newGovernance) internal {

101:     function _setTreasury(address newTreasury) internal {

108:     function _setTreasuryFee(uint16 newTreasuryFee) internal {

115:     function _whitelistCurrency(address currency, bool toWhitelist) internal {

49, 54, 59, 64, 69, 90, 94, 101, 108, 115,

File: contracts/misc/ProfileCreationProxy.sol

23:     constructor(
24:            address owner,
25:            address hub,
26:            address lensHandles,
27:            address tokenHandleRegistry
28:        ) ImmutableOwnable(owner, hub) {

33:     function proxyCreateProfile(Types.CreateProfileParams calldata createProfileParams)
34:            external
35:            onlyOwner
36:            returns (uint256)
37:        {

41:     function proxyCreateProfileWithHandle(Types.CreateProfileParams memory createProfileParams, string calldata handle)
42:            external
43:            onlyOwner
44:            returns (uint256, uint256)
45:        {

64:     function proxyCreateHandle(address to, string calldata handle) external onlyOwner returns (uint256) {

23, 33, 41, 64,

File: contracts/misc/access/ControllableByContract.sol

21:     constructor(address owner) Ownable() {

25:     function clearControllerContract() external onlyOwnerOrControllerContract {

30:     function setControllerContract(address newControllerContract) external onlyOwner {

21, 25, 30,

File: contracts/misc/access/Governance.sol

9:     function whitelistCollectModule(address collectModule, bool whitelist) external;

15:     constructor(address lensHubAddress_, address governanceOwner_) ControllableByContract(governanceOwner_) {

20:     ///               ONLY GOVERNANCE OWNER              ///
21:        ////////////////////////////////////////////////////////
22:    
23:        function lensHub_setGovernance(address newGovernance) external onlyOwner {

27:     function lensHub_setEmergencyAdmin(address newEmergencyAdmin) external onlyOwner {

32:     ///   ONLY GOVERNANCE OWNER OR CONTROLLER CONTRACT   ///
33:        ////////////////////////////////////////////////////////
34:    
35:        function lensHub_whitelistProfileCreator(address profileCreator, bool whitelist)
36:            external
37:            onlyOwnerOrControllerContract
38:        {

42:     function lensHub_whitelistFollowModule(address followModule, bool whitelist)
43:            external
44:            onlyOwnerOrControllerContract
45:        {

49:     function lensHub_whitelistReferenceModule(address referenceModule, bool whitelist)
50:            external
51:            onlyOwnerOrControllerContract
52:        {

56:     function lensHub_whitelistActionModule(address actionModule, bool whitelist)
57:            external
58:            onlyOwnerOrControllerContract
59:        {

64:     function lensHub_whitelistCollectModule(address collectModule, bool whitelist)
65:            external
66:            onlyOwnerOrControllerContract
67:        {

73:     function executeAsGovernance(address target, bytes calldata data)
74:            external
75:            payable
76:            onlyOwnerOrControllerContract
77:            returns (bytes memory)
78:        {

9, 15, 20, 27, 32, 42, 49, 56, 64, 73,

File: contracts/misc/access/ProxyAdmin.sol

12:     constructor(
13:            address lensHubAddress_,
14:            address previousImplementation_,
15:            address proxyAdminOwner_
16:        ) ControllableByContract(proxyAdminOwner_) {

21:     function currentImplementation() external returns (address) {

33:     function proxy_changeAdmin(address newAdmin) external onlyOwner {

38:     ///   ONLY PROXY ADMIN OWNER OR CONTROLLER CONTRACT   ///
39:        /////////////////////////////////////////////////////////
40:    
41:        function proxy_upgrade(address newImplementation) external onlyOwnerOrControllerContract {

47:     function proxy_upgradeAndCall(address newImplementation, bytes calldata data)
48:            external
49:            onlyOwnerOrControllerContract
50:        {

12, 21, 33, 38, 47,

File: contracts/namespaces/LensHandles.sol

62:     constructor(
63:            address owner,
64:            address lensHub,
65:            uint256 tokenGuardianCooldown
66:        ) ERC721('', '') ImmutableOwnable(owner, lensHub) {

70:     function name() public pure override returns (string memory) {

74:     function symbol() public pure override returns (string memory) {

78:     /**
79:         * @dev See {IERC721Metadata-tokenURI}.
80:         */
81:        function tokenURI(uint256 tokenId) public view override returns (string memory) {

86:     /// @inheritdoc ILensHandles
87:        function mintHandle(address to, string calldata localName)
88:            external
89:            onlyOwnerOrWhitelistedProfileCreator
90:            returns (uint256)
91:        {

96:     function migrateHandle(address to, string calldata localName) external onlyHub returns (uint256) {

101:     function burn(uint256 tokenId) external {

126:     function enableTokenGuardian() external onlyEOA {

139:     function approve(address to, uint256 tokenId) public override(IERC721, ERC721) {

147:     function setApprovalForAll(address operator, bool approved) public override(IERC721, ERC721) {

155:     function exists(uint256 tokenId) external view returns (bool) {

159:     function getNamespace() external pure returns (string memory) {

163:     function getNamespaceHash() external pure returns (bytes32) {

168:     function getLocalName(uint256 tokenId) public view returns (string memory) {

177:     function getHandle(uint256 tokenId) public view returns (string memory) {

182:     function getTokenId(string memory localName) public pure returns (uint256) {

186:     function getTokenGuardianDisablingTimestamp(address wallet) external view returns (uint256) {

191:     ///        INTERNAL FUNCTIONS      ///
192:         //////////////////////////////////////
193:     
194:         function _mintHandle(address to, string calldata localName) internal returns (uint256) {

202:     function _validateLocalNameMigration(string memory localName) internal view {

226:     function _validateLocalName(string memory localName) internal view {

249:     function _isAlphaNumeric(bytes1 char) internal pure returns (bool) {

253:     function _hasTokenGuardianEnabled(address wallet) internal view returns (bool) {

260:     function _beforeTokenTransfer(
261:             address from,
262:             address to,
263:             uint256 /* firstTokenId */,
264:             uint256 batchSize
265:         ) internal override {

62, 70, 74, 78, 86, 96, 101, 126, 139, 147, 155, 159, 163, 168, 177, 182, 186, 191, 202, 226, 249, 253, 260,

File: contracts/namespaces/TokenHandleRegistry.sol

42:     constructor(address lensHub, address lensHandles) {

50:     function migrationLink(uint256 handleId, uint256 tokenId) external {

60:     /// @inheritdoc ITokenHandleRegistry
61:        function link(
62:            uint256 handleId,
63:            uint256 tokenId
64:        ) external onlyTokenOwner(tokenId, msg.sender) onlyHandleOwner(handleId, msg.sender) {

71:     /// @inheritdoc ITokenHandleRegistry
72:        function unlink(uint256 handleId, uint256 tokenId) external {

93:     /// @inheritdoc ITokenHandleRegistry
94:        function resolve(uint256 handleId) external view returns (uint256) {

106:     /// @inheritdoc ITokenHandleRegistry
107:         function getDefaultHandle(uint256 tokenId) external view returns (uint256) {

119:     ///        INTERNAL FUNCTIONS      ///
120:         //////////////////////////////////////
121:     
122:         function _resolveHandleToToken(
123:             RegistryTypes.Handle memory handle
124:         ) internal view returns (RegistryTypes.Token storage) {

128:     function _resolveTokenToHandle(
129:             RegistryTypes.Token memory token
130:         ) internal view returns (RegistryTypes.Handle storage) {

134:     function _link(RegistryTypes.Handle memory handle, RegistryTypes.Token memory token) internal {

144:     function _deleteTokenToHandleLinkageIfAny(RegistryTypes.Handle memory handle) internal {

152:     function _deleteHandleToTokenLinkageIfAny(RegistryTypes.Token memory token) internal {

160:     function _unlink(RegistryTypes.Handle memory handle, RegistryTypes.Token memory token) internal {

167:     function _handleHash(RegistryTypes.Handle memory handle) internal pure returns (bytes32) {

171:     function _tokenHash(RegistryTypes.Token memory token) internal pure returns (bytes32) {

42, 50, 60, 71, 93, 106, 119, 128, 134, 144, 152, 160, 167, 171,

File: contracts/interfaces/ILensHandles.sol

49:     /**

49,

File: contracts/interfaces/ILensProtocol.sol

32:     /**

55:     /**

99:     /**

120:     /**

143:     /**

165:     /**

186:     /**

209:     /**

237:     /**

257:     /**

285:     /**

308:     /**

328:     /**

32, 55, 99, 120, 143, 165, 186, 209, 237, 257, 285, 308, 328,

[N-30] NatSpec @return is missing

It is recommended that Solidity contracts are fully annotated using NatSpec for all public interfaces (everything in the ABI). It is clearly stated in the Solidity official documentation. In complex projects such as Defi, the interpretation of all functions and their arguments and returns is important for code readability and auditability.source

Instances (299):

see instances
File: contracts/LensHub.sol

66:     constructor(
67:            address moduleGlobals,
68:            address followNFTImpl,
69:            address collectNFTImpl, // We still pass the deprecated CollectNFTImpl for legacy Collects to work
70:            address lensHandlesAddress,
71:            address tokenHandleRegistryAddress,
72:            address legacyFeeFollowModule,
73:            address legacyProfileFollowModule,
74:            address newFeeFollowModule,
75:            uint256 tokenGuardianCooldown
76:        )
77:            LensProfiles(moduleGlobals, tokenGuardianCooldown)
78:            LensV2Migration(
79:                legacyFeeFollowModule,
80:                legacyProfileFollowModule,
81:                newFeeFollowModule,
82:                lensHandlesAddress,
83:                tokenHandleRegistryAddress
84:            )
85:            LensImplGetters(followNFTImpl, collectNFTImpl)
86:        {}

88:     /// @inheritdoc ILensProtocol
89:        function createProfile(Types.CreateProfileParams calldata createProfileParams)
90:            external
91:            override
92:            whenNotPaused
93:            returns (uint256)
94:        {

165:     function changeDelegatedExecutorsConfig(
166:             uint256 delegatorProfileId,
167:             address[] calldata delegatedExecutors,
168:             bool[] calldata approvals
169:         ) external override whenNotPaused onlyProfileOwner(msg.sender, delegatorProfileId) {

223:     /// @inheritdoc ILensProtocol
224:         function post(Types.PostParams calldata postParams)
225:             external
226:             override
227:             whenPublishingEnabled
228:             onlyProfileOwnerOrDelegatedExecutor(msg.sender, postParams.profileId)
229:             returns (uint256)
230:         {

234:     /// @inheritdoc ILensProtocol
235:         function postWithSig(Types.PostParams calldata postParams, Types.EIP712Signature calldata signature)
236:             external
237:             override
238:             whenPublishingEnabled
239:             onlyProfileOwnerOrDelegatedExecutor(signature.signer, postParams.profileId)
240:             returns (uint256)
241:         {

246:     /// @inheritdoc ILensProtocol
247:         function comment(Types.CommentParams calldata commentParams)
248:             external
249:             override
250:             whenPublishingEnabled
251:             onlyProfileOwnerOrDelegatedExecutor(msg.sender, commentParams.profileId)
252:             returns (uint256)
253:         {

257:     /// @inheritdoc ILensProtocol
258:         function commentWithSig(Types.CommentParams calldata commentParams, Types.EIP712Signature calldata signature)
259:             external
260:             override
261:             whenPublishingEnabled
262:             onlyProfileOwnerOrDelegatedExecutor(signature.signer, commentParams.profileId)
263:             returns (uint256)
264:         {

269:     /// @inheritdoc ILensProtocol
270:         function mirror(Types.MirrorParams calldata mirrorParams)
271:             external
272:             override
273:             whenPublishingEnabled
274:             onlyProfileOwnerOrDelegatedExecutor(msg.sender, mirrorParams.profileId)
275:             returns (uint256)
276:         {

280:     /// @inheritdoc ILensProtocol
281:         function mirrorWithSig(Types.MirrorParams calldata mirrorParams, Types.EIP712Signature calldata signature)
282:             external
283:             override
284:             whenPublishingEnabled
285:             onlyProfileOwnerOrDelegatedExecutor(signature.signer, mirrorParams.profileId)
286:             returns (uint256)
287:         {

292:     /// @inheritdoc ILensProtocol
293:         function quote(Types.QuoteParams calldata quoteParams)
294:             external
295:             override
296:             whenPublishingEnabled
297:             onlyProfileOwnerOrDelegatedExecutor(msg.sender, quoteParams.profileId)
298:             returns (uint256)
299:         {

303:     /// @inheritdoc ILensProtocol
304:         function quoteWithSig(Types.QuoteParams calldata quoteParams, Types.EIP712Signature calldata signature)
305:             external
306:             override
307:             whenPublishingEnabled
308:             onlyProfileOwnerOrDelegatedExecutor(signature.signer, quoteParams.profileId)
309:             returns (uint256)
310:         {

319:     /// @inheritdoc ILensProtocol
320:         function follow(
321:             uint256 followerProfileId,
322:             uint256[] calldata idsOfProfilesToFollow,
323:             uint256[] calldata followTokenIds,
324:             bytes[] calldata datas
325:         )
326:             external
327:             override
328:             whenNotPaused
329:             onlyProfileOwnerOrDelegatedExecutor(msg.sender, followerProfileId)
330:             returns (uint256[] memory)
331:         {

342:     /// @inheritdoc ILensProtocol
343:         function followWithSig(
344:             uint256 followerProfileId,
345:             uint256[] calldata idsOfProfilesToFollow,
346:             uint256[] calldata followTokenIds,
347:             bytes[] calldata datas,
348:             Types.EIP712Signature calldata signature
349:         )
350:             external
351:             override
352:             whenNotPaused
353:             onlyProfileOwnerOrDelegatedExecutor(signature.signer, followerProfileId)
354:             returns (uint256[] memory)
355:         {

416:     /// @inheritdoc ILensProtocol
417:         function collect(Types.CollectParams calldata collectParams)
418:             external
419:             override
420:             whenNotPaused
421:             onlyProfileOwnerOrDelegatedExecutor(msg.sender, collectParams.collectorProfileId)
422:             returns (uint256)
423:         {

433:     /// @inheritdoc ILensProtocol
434:         function collectWithSig(Types.CollectParams calldata collectParams, Types.EIP712Signature calldata signature)
435:             external
436:             override
437:             whenNotPaused
438:             onlyProfileOwnerOrDelegatedExecutor(signature.signer, collectParams.collectorProfileId)
439:             returns (uint256)
440:         {

451:     /// @inheritdoc ILensProtocol
452:         function act(Types.PublicationActionParams calldata publicationActionParams)
453:             external
454:             override
455:             whenNotPaused
456:             onlyProfileOwnerOrDelegatedExecutor(msg.sender, publicationActionParams.actorProfileId)
457:             returns (bytes memory)
458:         {

467:     /// @inheritdoc ILensProtocol
468:         function actWithSig(
469:             Types.PublicationActionParams calldata publicationActionParams,
470:             Types.EIP712Signature calldata signature
471:         )
472:             external
473:             override
474:             whenNotPaused
475:             onlyProfileOwnerOrDelegatedExecutor(signature.signer, publicationActionParams.actorProfileId)
476:             returns (bytes memory)
477:         {

491:     /// @inheritdoc ILensProtocol
492:         function isFollowing(uint256 followerProfileId, uint256 followedProfileId) external view returns (bool) {

497:     /// @inheritdoc ILensProtocol
498:         function isDelegatedExecutorApproved(
499:             uint256 delegatorProfileId,
500:             address delegatedExecutor,
501:             uint64 configNumber
502:         ) external view returns (bool) {

506:     /// @inheritdoc ILensProtocol
507:         function isDelegatedExecutorApproved(uint256 delegatorProfileId, address delegatedExecutor)
508:             external
509:             view
510:             returns (bool)
511:         {

515:     /// @inheritdoc ILensProtocol
516:         function getDelegatedExecutorsConfigNumber(uint256 delegatorProfileId) external view returns (uint64) {

520:     /// @inheritdoc ILensProtocol
521:         function getDelegatedExecutorsPrevConfigNumber(uint256 delegatorProfileId) external view returns (uint64) {

525:     /// @inheritdoc ILensProtocol
526:         function getDelegatedExecutorsMaxConfigNumberSet(uint256 delegatorProfileId) external view returns (uint64) {

530:     /// @inheritdoc ILensProtocol
531:         function isBlocked(uint256 profileId, uint256 byProfileId) external view returns (bool) {

535:     /// @inheritdoc ILensProtocol
536:         function getContentURI(uint256 profileId, uint256 pubId) external view override returns (string memory) {

541:     /// @inheritdoc ILensProtocol
542:         function getProfile(uint256 profileId) external view override returns (Types.Profile memory) {

546:     /// @inheritdoc ILensProtocol
547:         function getPublication(uint256 profileId, uint256 pubId)
548:             external
549:             view
550:             override
551:             returns (Types.Publication memory)
552:         {

556:     /// @inheritdoc ILensProtocol
557:         function getPublicationType(uint256 profileId, uint256 pubId)
558:             external
559:             view
560:             override
561:             returns (Types.PublicationType)
562:         {

566:     function getActionModuleById(uint256 id) external view override returns (address) {

66, 88, 165, 223, 234, 246, 257, 269, 280, 292, 303, 319, 342, 416, 433, 451, 467, 491, 497, 506, 515, 520, 525, 530, 535, 541, 546, 556, 566,

File: contracts/FollowNFT.sol

43:     constructor(address hub) HubRestricted(hub) {

58:     /// @inheritdoc IFollowNFT
59:        function follow(
60:            uint256 followerProfileId,
61:            address transactionExecutor,
62:            uint256 followTokenId
63:        ) external override onlyHub returns (uint256) {

168:     function _wrap(uint256 followTokenId, address wrappedTokenReceiver) internal {

195:     /// @inheritdoc IFollowNFT
196:         function processBlock(uint256 followerProfileId) external override onlyHub returns (bool) {

210:     /// @inheritdoc IFollowNFT
211:         function getFollowerProfileId(uint256 followTokenId) external view override returns (uint256) {

215:     /// @inheritdoc IFollowNFT
216:         function isFollowing(uint256 followerProfileId) external view override returns (bool) {

220:     /// @inheritdoc IFollowNFT
221:         function getFollowTokenId(uint256 followerProfileId) external view override returns (uint256) {

225:     /// @inheritdoc IFollowNFT
226:         function getOriginalFollowTimestamp(uint256 followTokenId) external view override returns (uint256) {

230:     /// @inheritdoc IFollowNFT
231:         function getFollowTimestamp(uint256 followTokenId) external view override returns (uint256) {

235:     /// @inheritdoc IFollowNFT
236:         function getProfileIdAllowedToRecover(uint256 followTokenId) external view override returns (uint256) {

240:     /// @inheritdoc IFollowNFT
241:         function getFollowData(uint256 followTokenId) external view override returns (Types.FollowData memory) {

245:     /// @inheritdoc IFollowNFT
246:         function getFollowApproved(uint256 followTokenId) external view override returns (uint256) {

250:     /// @inheritdoc IFollowNFT
251:         function getFollowerCount() external view override returns (uint256) {

255:     function burn(uint256 followTokenId) public override {

260:     /**
261:          * @dev See {IERC165-supportsInterface}.
262:          */
263:         function supportsInterface(bytes4 interfaceId)
264:             public
265:             view
266:             virtual
267:             override(LensBaseERC721, ERC2981CollectionRoyalties)
268:             returns (bool)
269:         {

274:     function name() public view override returns (string memory) {

278:     function symbol() public view override returns (string memory) {

282:     /**
283:          * @dev This returns the follow NFT URI fetched from the hub.
284:          */
285:         function tokenURI(uint256 followTokenId) public view override returns (string memory) {

297:     function _followMintingNewToken(uint256 followerProfileId) internal returns (uint256) {

311:     function _followWithWrappedToken(
312:             uint256 followerProfileId,
313:             address transactionExecutor,
314:             uint256 followTokenId,
315:             address followTokenOwner
316:         ) internal returns (uint256) {

341:     function _followWithUnwrappedTokenFromBurnedProfile(
342:             uint256 followerProfileId,
343:             uint256 followTokenId,
344:             uint256 currentFollowerProfileId
345:         ) internal returns (uint256) {

357:     function _followByRecoveringToken(uint256 followerProfileId, uint256 followTokenId) internal returns (uint256) {

368:     function _replaceFollower(
369:             uint256 currentFollowerProfileId,
370:             uint256 newFollowerProfileId,
371:             uint256 followTokenId
372:         ) internal {

386:     function _baseFollow(
387:             uint256 followerProfileId,
388:             uint256 followTokenId,
389:             bool isOriginalFollow
390:         ) internal {

408:     function _unfollowIfHasFollower(uint256 followTokenId) internal {

416:     function _unfollow(uint256 unfollower, uint256 followTokenId) internal {

428:     function _approveFollow(uint256 approvedProfileId, uint256 followTokenId) internal {

449:     function _getReceiver(
450:             uint256 /* followTokenId */
451:         ) internal view override returns (address) {

455:     function _beforeRoyaltiesSet(
456:             uint256 /* royaltiesInBasisPoints */
457:         ) internal view override {

463:     function _isFollowTokenWrapped(uint256 followTokenId) internal view returns (bool) {

467:     function _getRoyaltiesInBasisPointsSlot() internal pure override returns (uint256) {

476:     /// Migrations ///
477:         //////////////////
478:     
479:         // This function shouldn't fail under no circumstances, except if wrong parameters are passed.
480:         function tryMigrate(
481:             uint256 followerProfileId,
482:             address followerProfileOwner,
483:             uint256 idOfProfileFollowed,
484:             uint256 followTokenId
485:         ) external onlyHub returns (uint48) {

43, 58, 168, 195, 210, 215, 220, 225, 230, 235, 240, 245, 250, 255, 260, 274, 278, 282, 297, 311, 341, 357, 368, 386, 408, 416, 428, 449, 455, 463, 467, 476,

File: contracts/libraries/ActionLib.sol

13:     function act(
14:            Types.PublicationActionParams calldata publicationActionParams,
15:            address transactionExecutor,
16:            address actorProfileOwner
17:        ) external returns (bytes memory) {

65:     function _isActionEnabled(Types.Publication storage _publication, uint256 actionModuleId)
66:            private
67:            view
68:            returns (bool)
69:        {

13, 65,

File: contracts/libraries/FollowLib.sol

15:     function follow(
16:            uint256 followerProfileId,
17:            address transactionExecutor,
18:            uint256[] calldata idsOfProfilesToFollow,
19:            uint256[] calldata followTokenIds,
20:            bytes[] calldata followModuleDatas
21:        ) external returns (uint256[] memory) {

54:     function unfollow(
55:            uint256 unfollowerProfileId,
56:            address transactionExecutor,
57:            uint256[] calldata idsOfProfilesToUnfollow
58:        ) external {

98:     function _follow(
99:            uint256 followerProfileId,
100:            address transactionExecutor,
101:            uint256 idOfProfileToFollow,
102:            uint256 followTokenId,
103:            bytes calldata followModuleData
104:        ) private returns (uint256) {

15, 54, 98,

File: contracts/libraries/GovernanceLib.sol

64:     function _setState(Types.ProtocolState newState) private returns (Types.ProtocolState) {

71:     function whitelistProfileCreator(address profileCreator, bool whitelist) external {

76:     function whitelistFollowModule(address followModule, bool whitelist) external {

81:     function whitelistReferenceModule(address referenceModule, bool whitelist) external {

86:     function whitelistActionModule(address actionModule, bool whitelist) external {

64, 71, 76, 81, 86,

File: contracts/libraries/LegacyCollectLib.sol

45:     function collect(
46:            Types.CollectParams calldata collectParams,
47:            address transactionExecutor,
48:            address collectorProfileOwner,
49:            address collectNFTImpl
50:        ) external returns (uint256) {

115:     function _getOrDeployCollectNFT(
116:             Types.Publication storage _collectedPublication,
117:             uint256 publicationCollectedProfileId,
118:             uint256 publicationCollectedId,
119:             address collectNFTImpl
120:         ) private returns (address) {

45, 115,

File: contracts/libraries/MetaTxLib.sol

43:     function validateSetProfileMetadataURISignature(
44:            Types.EIP712Signature calldata signature,
45:            uint256 profileId,
46:            string calldata metadataURI
47:        ) external {

64:     function validateSetFollowModuleSignature(
65:            Types.EIP712Signature calldata signature,
66:            uint256 profileId,
67:            address followModule,
68:            bytes calldata followModuleInitData
69:        ) external {

87:     function validateChangeDelegatedExecutorsConfigSignature(
88:            Types.EIP712Signature calldata signature,
89:            uint256 delegatorProfileId,
90:            address[] calldata delegatedExecutors,
91:            bool[] calldata approvals,
92:            uint64 configNumber,
93:            bool switchToGivenConfig
94:        ) external {

116:     function validateSetProfileImageURISignature(
117:             Types.EIP712Signature calldata signature,
118:             uint256 profileId,
119:             string calldata imageURI
120:         ) external {

137:     function validatePostSignature(Types.EIP712Signature calldata signature, Types.PostParams calldata postParams)
138:             external
139:         {

160:     function _hashActionModulesInitDatas(bytes[] memory actionModulesInitDatas) private pure returns (bytes32) {

190:     function _abiEncode(ReferenceParamsForAbiEncode memory referenceParamsForAbiEncode)
191:             private
192:             pure
193:             returns (bytes memory)
194:         {

225:     function validateCommentSignature(
226:             Types.EIP712Signature calldata signature,
227:             Types.CommentParams calldata commentParams
228:         ) external {

256:     function validateQuoteSignature(Types.EIP712Signature calldata signature, Types.QuoteParams calldata quoteParams)
257:             external
258:         {

286:     function validateMirrorSignature(Types.EIP712Signature calldata signature, Types.MirrorParams calldata mirrorParams)
287:             external
288:         {

309:     function validateBurnSignature(Types.EIP712Signature calldata signature, uint256 tokenId) external {

320:     function validateFollowSignature(
321:             Types.EIP712Signature calldata signature,
322:             uint256 followerProfileId,
323:             uint256[] calldata idsOfProfilesToFollow,
324:             uint256[] calldata followTokenIds,
325:             bytes[] calldata datas
326:         ) external {

357:     function validateUnfollowSignature(
358:             Types.EIP712Signature calldata signature,
359:             uint256 unfollowerProfileId,
360:             uint256[] calldata idsOfProfilesToUnfollow
361:         ) external {

378:     function validateSetBlockStatusSignature(
379:             Types.EIP712Signature calldata signature,
380:             uint256 byProfileId,
381:             uint256[] calldata idsOfProfilesToSetBlockStatus,
382:             bool[] calldata blockStatus
383:         ) external {

401:     function validateLegacyCollectSignature(
402:             Types.EIP712Signature calldata signature,
403:             Types.CollectParams calldata collectParams
404:         ) external {

425:     function validateActSignature(
426:             Types.EIP712Signature calldata signature,
427:             Types.PublicationActionParams calldata publicationActionParams
428:         ) external {

450:     function calculateDomainSeparator() internal view returns (bytes32) {

43, 64, 87, 116, 137, 160, 190, 225, 256, 286, 309, 320, 357, 378, 401, 425, 450,

File: contracts/libraries/MigrationLib.sol

20:     function getProfileData(uint256 profileId) external view returns (ProfileData memory);

94:     function batchMigrateFollows(
95:            uint256[] calldata followerProfileIds,
96:            uint256[] calldata idsOfProfileFollowed,
97:            uint256[] calldata followTokenIds
98:        ) external {

114:     function _migrateFollow(
115:             uint256 followerProfileId,
116:             uint256 idOfProfileFollowed,
117:             uint256 followTokenId
118:         ) private {

141:     function batchMigrateFollowModules(
142:             uint256[] calldata profileIds,
143:             address legacyFeeFollowModule,
144:             address legacyProfileFollowModule,
145:             address newFeeFollowModule
146:         ) external {

20, 94, 114, 141,

File: contracts/libraries/ProfileLib.sol

16:     function ownerOf(uint256 profileId) internal view returns (address) {

24:     function exists(uint256 profileId) internal view returns (bool) {

105:     function setProfileMetadataURI(uint256 profileId, string calldata metadataURI) external {

110:     function _initFollowModule(
111:             uint256 profileId,
112:             address transactionExecutor,
113:             address followModule,
114:             bytes memory followModuleInitData
115:         ) private returns (bytes memory) {

120:     function _setProfileImageURI(uint256 profileId, string calldata imageURI) private {

128:     function setBlockStatus(
129:             uint256 byProfileId,
130:             uint256[] calldata idsOfProfilesToSetBlockStatus,
131:             bool[] calldata blockStatus
132:         ) external {

166:     function switchToNewFreshDelegatedExecutorsConfig(uint256 profileId) external {

180:     function changeDelegatedExecutorsConfig(
181:             uint256 delegatorProfileId,
182:             address[] calldata delegatedExecutors,
183:             bool[] calldata approvals
184:         ) external {

198:     function changeGivenDelegatedExecutorsConfig(
199:             uint256 delegatorProfileId,
200:             address[] calldata delegatedExecutors,
201:             bool[] calldata approvals,
202:             uint64 configNumber,
203:             bool switchToGivenConfig
204:         ) external {

215:     function isExecutorApproved(uint256 delegatorProfileId, address delegatedExecutor) external view returns (bool) {

222:     function _changeDelegatedExecutorsConfig(
223:             Types.DelegatedExecutorsConfig storage _delegatedExecutorsConfig,
224:             uint256 delegatorProfileId,
225:             address[] memory delegatedExecutors,
226:             bool[] memory approvals,
227:             uint64 configNumber,
228:             bool switchToGivenConfig
229:         ) private {

255:     function _prepareStorageToApplyChangesUnderGivenConfig(
256:             Types.DelegatedExecutorsConfig storage _delegatedExecutorsConfig,
257:             uint64 configNumber,
258:             bool switchToGivenConfig
259:         ) private returns (bool) {

16, 24, 105, 110, 120, 128, 166, 180, 198, 215, 222, 255,

File: contracts/libraries/PublicationLib.sol

170:     function getPublicationType(uint256 profileId, uint256 pubId) internal view returns (Types.PublicationType) {

190:     function getContentURI(uint256 profileId, uint256 pubId) external view returns (string memory) {

203:     function _asReferencePubParams(Types.QuoteParams calldata quoteParams)
204:             private
205:             pure
206:             returns (Types.ReferencePubParams calldata referencePubParams)
207:         {

214:     function _asReferencePubParams(Types.CommentParams calldata commentParams)
215:             private
216:             pure
217:             returns (Types.ReferencePubParams calldata referencePubParams)
218:         {

225:     function _createReferencePublication(
226:             Types.ReferencePubParams calldata referencePubParams,
227:             address transactionExecutor,
228:             Types.PublicationType referencePubType
229:         )
230:             private
231:             returns (
232:                 uint256,
233:                 bytes[] memory,
234:                 bytes memory,
235:                 Types.PublicationType[] memory
236:             )
237:         {

272:     function _fillReferencePublicationStorage(
273:             Types.ReferencePubParams calldata referencePubParams,
274:             Types.PublicationType referencePubType
275:         ) private returns (uint256) {

291:     function _fillRootOfPublicationInStorage(
292:             Types.Publication storage _publication,
293:             uint256 pointedProfileId,
294:             uint256 pointedPubId
295:         ) internal {

313:     function _processCommentIfNeeded(
314:             Types.CommentParams calldata commentParams,
315:             address transactionExecutor,
316:             Types.PublicationType[] memory referrerPubTypes
317:         ) private returns (bytes memory) {

366:     function _processQuoteIfNeeded(
367:             Types.QuoteParams calldata quoteParams,
368:             address transactionExecutor,
369:             Types.PublicationType[] memory referrerPubTypes
370:         ) private returns (bytes memory) {

419:     function _processMirrorIfNeeded(
420:             Types.MirrorParams calldata mirrorParams,
421:             address transactionExecutor,
422:             Types.PublicationType[] memory referrerPubTypes
423:         ) private returns (bytes memory) {

472:     function _initPubActionModules(
473:             uint256 profileId,
474:             address transactionExecutor,
475:             uint256 pubId,
476:             address[] calldata actionModules,
477:             bytes[] calldata actionModulesInitDatas
478:         ) private returns (bytes[] memory) {

521:     function _initPubReferenceModule(
522:             uint256 profileId,
523:             address transactionExecutor,
524:             uint256 pubId,
525:             address referenceModule,
526:             bytes memory referenceModuleInitData
527:         ) private returns (bytes memory) {

170, 190, 203, 214, 225, 272, 291, 313, 366, 419, 472, 521,

File: contracts/libraries/StorageLib.sol

49:     function getPublication(uint256 profileId, uint256 pubId)
50:            internal
51:            pure
52:            returns (Types.Publication storage _publication)
53:        {

63:     function getProfile(uint256 profileId) internal pure returns (Types.Profile storage _profiles) {

71:     function getDelegatedExecutorsConfig(uint256 delegatorProfileId)
72:            internal
73:            pure
74:            returns (Types.DelegatedExecutorsConfig storage _delegatedExecutorsConfig)
75:        {

83:     function tokenGuardianDisablingTimestamp()
84:            internal
85:            pure
86:            returns (mapping(address => uint256) storage _tokenGuardianDisablingTimestamp)
87:        {

93:     function getTokenData(uint256 tokenId) internal pure returns (Types.TokenData storage _tokenData) {

101:     function blockedStatus(uint256 blockerProfileId)
102:             internal
103:             pure
104:             returns (mapping(uint256 => bool) storage _blockedStatus)
105:         {

113:     function nonces() internal pure returns (mapping(address => uint256) storage _nonces) {

119:     function profileIdByHandleHash()
120:             internal
121:             pure
122:             returns (mapping(bytes32 => uint256) storage _profileIdByHandleHash)
123:         {

129:     function profileCreatorWhitelisted()
130:             internal
131:             pure
132:             returns (mapping(address => bool) storage _profileCreatorWhitelisted)
133:         {

139:     function followModuleWhitelisted()
140:             internal
141:             pure
142:             returns (mapping(address => bool) storage _followModuleWhitelisted)
143:         {

149:     function actionModuleWhitelistData()
150:             internal
151:             pure
152:             returns (mapping(address => Types.ActionModuleWhitelistData) storage _actionModuleWhitelistData)
153:         {

159:     function actionModuleById() internal pure returns (mapping(uint256 => address) storage _actionModules) {

165:     function incrementMaxActionModuleIdUsed() internal returns (uint256) {

177:     function referenceModuleWhitelisted()
178:             internal
179:             pure
180:             returns (mapping(address => bool) storage _referenceModuleWhitelisted)
181:         {

187:     function getGovernance() internal view returns (address _governance) {

193:     function setGovernance(address newGovernance) internal {

199:     function getEmergencyAdmin() internal view returns (address _emergencyAdmin) {

205:     function setEmergencyAdmin(address newEmergencyAdmin) internal {

211:     function getState() internal view returns (Types.ProtocolState _state) {

217:     function setState(Types.ProtocolState newState) internal {

223:     function getLastInitializedRevision() internal view returns (uint256 _lastInitializedRevision) {

229:     function setLastInitializedRevision(uint256 newLastInitializedRevision) internal {

49, 63, 71, 83, 93, 101, 113, 119, 129, 139, 149, 159, 165, 177, 187, 193, 199, 205, 211, 217, 223, 229,

File: contracts/libraries/ValidationLib.sol

16:     function validatePointedPub(uint256 profileId, uint256 pubId) internal view {

24:     function validateAddressIsProfileOwner(address expectedProfileOwner, uint256 profileId) internal view {

30:     function validateAddressIsProfileOwnerOrDelegatedExecutor(
31:            address expectedOwnerOrDelegatedExecutor,
32:            uint256 profileId
33:        ) internal view {

42:     function validateAddressIsDelegatedExecutor(address expectedDelegatedExecutor, uint256 delegatorProfileId)
43:            internal
44:            view
45:        {

51:     function validateReferenceModuleWhitelisted(address referenceModule) internal view {

57:     function validateFollowModuleWhitelisted(address followModule) internal view {

63:     function validateProfileCreatorWhitelisted(address profileCreator) internal view {

69:     function validateNotBlocked(uint256 profile, uint256 byProfile) internal view {

75:     function validateProfileExists(uint256 profileId) internal view {

81:     function validateCallerIsGovernance() internal view {

87:     function validateReferrersAndGetReferrersPubTypes(
88:            uint256[] memory referrerProfileIds,
89:            uint256[] memory referrerPubIds,
90:            uint256 targetedProfileId,
91:            uint256 targetedPubId
92:        ) internal view returns (Types.PublicationType[] memory) {

121:     function validateLegacyCollectReferrer(
122:             uint256 referrerProfileId,
123:             uint256 referrerPubId,
124:             uint256 publicationCollectedProfileId,
125:             uint256 publicationCollectedId
126:         ) external view {

143:     function _validateReferrerAndGetReferrerPubType(
144:             uint256 referrerProfileId,
145:             uint256 referrerPubId,
146:             uint256 targetedProfileId,
147:             uint256 targetedPubId
148:         ) private view returns (Types.PublicationType) {

181:     function _validateReferrerAsPost(
182:             uint256 referrerProfileId,
183:             uint256 referrerPubId,
184:             uint256 targetedProfileId,
185:             uint256 targetedPubId
186:         ) private view {

16, 24, 30, 42, 51, 57, 63, 69, 75, 81, 87, 121, 143, 181,

File: contracts/base/ERC2981CollectionRoyalties.sol

14:     /**
15:         * @dev See {IERC165-supportsInterface}.
16:         */
17:        function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {

31:     /**
32:         * @notice Called with the sale price to determine how much royalty is owed and to whom.
33:         *
34:         * @param tokenId The ID of the token queried for royalty information.
35:         * @param salePrice The sale price of the token specified.
36:         * @return A tuple with the address that should receive the royalties and the royalty
37:         * payment amount for the given sale price.
38:         */
39:        function royaltyInfo(uint256 tokenId, uint256 salePrice) external view returns (address, uint256) {

43:     function _setRoyalty(uint256 royaltiesInBasisPoints) internal virtual {

51:     function _getRoyaltyAmount(
52:            uint256, /* tokenId */
53:            uint256 salePrice
54:        ) internal view virtual returns (uint256) {

58:     function _storeRoyaltiesInBasisPoints(uint256 royaltiesInBasisPoints) internal virtual {

65:     function _loadRoyaltiesInBasisPoints() internal view virtual returns (uint256) {

74:     function _beforeRoyaltiesSet(uint256 royaltiesInBasisPoints) internal view virtual;

76:     function _getRoyaltiesInBasisPointsSlot() internal view virtual returns (uint256);

78:     function _getReceiver(uint256 tokenId) internal view virtual returns (address);

14, 31, 43, 51, 58, 65, 74, 76, 78,

File: contracts/base/HubRestricted.sol

24:     constructor(address hub) {

24,

File: contracts/base/LensBaseERC721.sol

76:     /**

81:     /**
82:         * @dev See {IERC165-supportsInterface}.
83:         */
84:        function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {

94:     function nonces(address signer) public view override returns (uint256) {

98:     /// @inheritdoc IERC721MetaTx
99:        function getDomainSeparator() external view virtual override returns (bytes32) {

103:     /**
104:          * @dev See {IERC721-balanceOf}.
105:          */
106:         function balanceOf(address owner) public view virtual override returns (uint256) {

113:     /**
114:          * @dev See {IERC721-ownerOf}.
115:          */
116:         function ownerOf(uint256 tokenId) public view virtual override returns (address) {

124:     /**
125:          * @dev See {IERC721Timestamped-mintTimestampOf}
126:          */
127:         function mintTimestampOf(uint256 tokenId) public view virtual override returns (uint256) {

135:     /**
136:          * @dev See {IERC721Timestamped-tokenDataOf}
137:          */
138:         function tokenDataOf(uint256 tokenId) public view virtual override returns (Types.TokenData memory) {

145:     /**
146:          * @dev See {IERC721Timestamped-exists}
147:          */
148:         function exists(uint256 tokenId) public view virtual override returns (bool) {

152:     /**
153:          * @dev See {IERC721Metadata-name}.
154:          */
155:         function name() public view virtual override returns (string memory) {

159:     /**
160:          * @dev See {IERC721Metadata-symbol}.
161:          */
162:         function symbol() public view virtual override returns (string memory) {

166:     function totalSupply() external view virtual override returns (uint256) {

186:     /**
187:          * @dev See {IERC721-getApproved}.
188:          */
189:         function getApproved(uint256 tokenId) public view virtual override returns (address) {

208:     /**
209:          * @dev See {IERC721-isApprovedForAll}.
210:          */
211:         function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {

314:     /**
315:          * @dev Returns whether `tokenId` exists.
316:          *
317:          * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.
318:          *
319:          * Tokens start existing when they are minted (`_mint`),
320:          * and stop existing when they are burned (`_burn`).
321:          */
322:         function _exists(uint256 tokenId) internal view virtual returns (bool) {

326:     /**
327:          * @dev Returns whether `spender` is allowed to manage `tokenId`.
328:          *
329:          * Requirements:
330:          *
331:          * - `tokenId` must exist.
332:          */
333:         function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {

76, 81, 94, 98, 103, 113, 124, 135, 145, 152, 159, 166, 186, 208, 314, 326,

File: contracts/base/LensGovernable.sol

64:     /// @inheritdoc ILensGovernable
65:        function getGovernance() external view override returns (address) {

81:     /// @inheritdoc ILensGovernable
82:        function isProfileCreatorWhitelisted(address profileCreator) external view override returns (bool) {

86:     /// @inheritdoc ILensGovernable
87:        function isFollowModuleWhitelisted(address followModule) external view override returns (bool) {

91:     /// @inheritdoc ILensGovernable
92:        function isReferenceModuleWhitelisted(address referenceModule) external view override returns (bool) {

96:     /// @inheritdoc ILensGovernable
97:        function getActionModuleWhitelistData(address actionModule)
98:            external
99:            view
100:            override
101:            returns (Types.ActionModuleWhitelistData memory)
102:        {

64, 81, 86, 91, 96,

File: contracts/base/LensImplGetters.sol

11:     constructor(address followNFTImpl, address collectNFTImpl) {

16:     /// @inheritdoc ILensImplGetters
17:        function getFollowNFTImpl() external view override returns (address) {

21:     /// @inheritdoc ILensImplGetters
22:        function getCollectNFTImpl() external view override returns (address) {

11, 16, 21,

File: contracts/base/LensProfiles.sol

33:     constructor(address moduleGlobals, uint256 tokenGuardianCooldown) {

57:     /// @inheritdoc ILensProfiles
58:        function getTokenGuardianDisablingTimestamp(address wallet) external view returns (uint256) {

102:     /**
103:          * @dev Overrides the ERC721 tokenURI function to return the associated URI with a given profile.
104:          */
105:         function tokenURI(uint256 tokenId) public view override(LensBaseERC721, IERC721Metadata) returns (string memory) {

112:     function approve(address to, uint256 tokenId) public override(LensBaseERC721, IERC721) {

120:     function setApprovalForAll(address operator, bool approved) public override(LensBaseERC721, IERC721) {

128:     /**
129:          * @dev See {IERC165-supportsInterface}.
130:          */
131:         function supportsInterface(bytes4 interfaceId)
132:             public
133:             view
134:             virtual
135:             override(LensBaseERC721, ERC2981CollectionRoyalties, IERC165)
136:             returns (bool)
137:         {

142:     function _hasTokenGuardianEnabled(address wallet) internal view returns (bool) {

149:     function _getRoyaltiesInBasisPointsSlot() internal pure override returns (uint256) {

153:     function _getReceiver(
154:             uint256 /* tokenId */
155:         ) internal view override returns (address) {

159:     function _beforeRoyaltiesSet(
160:             uint256 /* royaltiesInBasisPoints */
161:         ) internal view override {

165:     function _beforeTokenTransfer(
166:             address from,
167:             address to,
168:             uint256 tokenId
169:         ) internal override whenNotPaused {

33, 57, 102, 112, 120, 128, 142, 149, 153, 159, 165,

File: contracts/base/upgradeability/FollowNFTProxy.sol

13:     constructor(bytes memory data) {

18:     function _implementation() internal view override returns (address) {

13, 18,

File: contracts/misc/ImmutableOwnable.sol

26:     constructor(address owner, address lensHub) {

26,

File: contracts/misc/LegacyCollectNFT.sol

38:     constructor(address hub) {

54:     /// @inheritdoc ICollectNFT
55:        function mint(address to) external override returns (uint256) {

64:     /// @inheritdoc ICollectNFT
65:        function getSourcePublicationPointer() external view override returns (uint256, uint256) {

69:     function tokenURI(uint256 tokenId) public view override returns (string memory) {

74:     /**
75:         * @dev See {IERC721Metadata-name}.
76:         */
77:        function name() public view override returns (string memory) {

81:     /**
82:         * @dev See {IERC721Metadata-symbol}.
83:         */
84:        function symbol() public pure override returns (string memory) {

88:     /**
89:         * @dev See {IERC165-supportsInterface}.
90:         */
91:        function supportsInterface(bytes4 interfaceId)
92:            public
93:            view
94:            virtual
95:            override(ERC2981CollectionRoyalties, LensBaseERC721)
96:            returns (bool)
97:        {

102:     function _getReceiver(
103:             uint256 /* tokenId */
104:         ) internal view override returns (address) {

108:     function _beforeRoyaltiesSet(
109:             uint256 /* royaltiesInBasisPoints */
110:         ) internal view override {

116:     function _getRoyaltiesInBasisPointsSlot() internal pure override returns (uint256) {

38, 54, 64, 69, 74, 81, 88, 102, 108, 116,

File: contracts/misc/LensV2Migration.sol

19:     constructor(
20:            address legacyFeeFollowModule,
21:            address legacyProfileFollowModule,
22:            address newFeeFollowModule,
23:            address lensHandlesAddress,
24:            address tokenHandleRegistryAddress
25:        ) {

33:     function batchMigrateProfiles(uint256[] calldata profileIds) external {

37:     function batchMigrateFollows(
38:            uint256[] calldata followerProfileIds,
39:            uint256[] calldata idsOfProfileFollowed,
40:            uint256[] calldata followTokenIds
41:        ) external {

45:     function batchMigrateFollowModules(uint256[] calldata profileIds) external {

19, 33, 37, 45,

File: contracts/misc/LensV2UpgradeContract.sol

20:     constructor(
21:            address proxyAdminAddress,
22:            address governanceAddress,
23:            address owner,
24:            address lensHub,
25:            address newImplementationAddress,
26:            address[] memory oldFollowModulesToUnwhitelist_,
27:            address[] memory newFollowModulesToWhitelist_,
28:            address[] memory oldReferenceModulesToUnwhitelist_,
29:            address[] memory newReferenceModulesToWhitelist_,
30:            address[] memory oldCollectModulesToUnwhitelist_,
31:            address[] memory newActionModulesToWhitelist_
32:        ) ImmutableOwnable(owner, lensHub) {

44:     function executeLensV2Upgrade() external onlyOwner {

50:     function _upgrade() internal {

64:     function _unwhitelistOldFollowModules() internal {

75:     function _unwhitelistOldReferenceModules() internal {

86:     function _unwhitelistOldCollectModules() internal {

97:     function _whitelistNewFollowModules() internal {

108:     function _whitelistNewReferenceModules() internal {

119:     function _whitelistNewActionModules() internal {

20, 44, 50, 64, 75, 86, 97, 108, 119,

File: contracts/misc/ModuleGlobals.sol

69:     /// @inheritdoc IModuleGlobals
70:        function isCurrencyWhitelisted(address currency) external view override returns (bool) {

74:     /// @inheritdoc IModuleGlobals
75:        function getGovernance() external view override returns (address) {

79:     /// @inheritdoc IModuleGlobals
80:        function getTreasury() external view override returns (address) {

84:     /// @inheritdoc IModuleGlobals
85:        function getTreasuryFee() external view override returns (uint16) {

90:     function getTreasuryData() external view override returns (address, uint16) {

94:     function _setGovernance(address newGovernance) internal {

101:     function _setTreasury(address newTreasury) internal {

108:     function _setTreasuryFee(uint16 newTreasuryFee) internal {

115:     function _whitelistCurrency(address currency, bool toWhitelist) internal {

69, 74, 79, 84, 90, 94, 101, 108, 115,

File: contracts/misc/ProfileCreationProxy.sol

23:     constructor(
24:            address owner,
25:            address hub,
26:            address lensHandles,
27:            address tokenHandleRegistry
28:        ) ImmutableOwnable(owner, hub) {

33:     function proxyCreateProfile(Types.CreateProfileParams calldata createProfileParams)
34:            external
35:            onlyOwner
36:            returns (uint256)
37:        {

41:     function proxyCreateProfileWithHandle(Types.CreateProfileParams memory createProfileParams, string calldata handle)
42:            external
43:            onlyOwner
44:            returns (uint256, uint256)
45:        {

64:     function proxyCreateHandle(address to, string calldata handle) external onlyOwner returns (uint256) {

23, 33, 41, 64,

File: contracts/misc/access/ControllableByContract.sol

21:     constructor(address owner) Ownable() {

25:     function clearControllerContract() external onlyOwnerOrControllerContract {

30:     function setControllerContract(address newControllerContract) external onlyOwner {

21, 25, 30,

File: contracts/misc/access/Governance.sol

9:     function whitelistCollectModule(address collectModule, bool whitelist) external;

15:     constructor(address lensHubAddress_, address governanceOwner_) ControllableByContract(governanceOwner_) {

27:     function lensHub_setEmergencyAdmin(address newEmergencyAdmin) external onlyOwner {

42:     function lensHub_whitelistFollowModule(address followModule, bool whitelist)
43:            external
44:            onlyOwnerOrControllerContract
45:        {

49:     function lensHub_whitelistReferenceModule(address referenceModule, bool whitelist)
50:            external
51:            onlyOwnerOrControllerContract
52:        {

56:     function lensHub_whitelistActionModule(address actionModule, bool whitelist)
57:            external
58:            onlyOwnerOrControllerContract
59:        {

64:     function lensHub_whitelistCollectModule(address collectModule, bool whitelist)
65:            external
66:            onlyOwnerOrControllerContract
67:        {

73:     function executeAsGovernance(address target, bytes calldata data)
74:            external
75:            payable
76:            onlyOwnerOrControllerContract
77:            returns (bytes memory)
78:        {

9, 15, 27, 42, 49, 56, 64, 73,

File: contracts/misc/access/ProxyAdmin.sol

12:     constructor(
13:            address lensHubAddress_,
14:            address previousImplementation_,
15:            address proxyAdminOwner_
16:        ) ControllableByContract(proxyAdminOwner_) {

21:     function currentImplementation() external returns (address) {

33:     function proxy_changeAdmin(address newAdmin) external onlyOwner {

47:     function proxy_upgradeAndCall(address newImplementation, bytes calldata data)
48:            external
49:            onlyOwnerOrControllerContract
50:        {

12, 21, 33, 47,

File: contracts/namespaces/LensHandles.sol

62:     constructor(
63:            address owner,
64:            address lensHub,
65:            uint256 tokenGuardianCooldown
66:        ) ERC721('', '') ImmutableOwnable(owner, lensHub) {

70:     function name() public pure override returns (string memory) {

74:     function symbol() public pure override returns (string memory) {

78:     /**
79:         * @dev See {IERC721Metadata-tokenURI}.
80:         */
81:        function tokenURI(uint256 tokenId) public view override returns (string memory) {

86:     /// @inheritdoc ILensHandles
87:        function mintHandle(address to, string calldata localName)
88:            external
89:            onlyOwnerOrWhitelistedProfileCreator
90:            returns (uint256)
91:        {

96:     function migrateHandle(address to, string calldata localName) external onlyHub returns (uint256) {

101:     function burn(uint256 tokenId) external {

126:     function enableTokenGuardian() external onlyEOA {

139:     function approve(address to, uint256 tokenId) public override(IERC721, ERC721) {

147:     function setApprovalForAll(address operator, bool approved) public override(IERC721, ERC721) {

155:     function exists(uint256 tokenId) external view returns (bool) {

159:     function getNamespace() external pure returns (string memory) {

163:     function getNamespaceHash() external pure returns (bytes32) {

168:     function getLocalName(uint256 tokenId) public view returns (string memory) {

177:     function getHandle(uint256 tokenId) public view returns (string memory) {

182:     function getTokenId(string memory localName) public pure returns (uint256) {

186:     function getTokenGuardianDisablingTimestamp(address wallet) external view returns (uint256) {

191:     ///        INTERNAL FUNCTIONS      ///
192:         //////////////////////////////////////
193:     
194:         function _mintHandle(address to, string calldata localName) internal returns (uint256) {

202:     function _validateLocalNameMigration(string memory localName) internal view {

226:     function _validateLocalName(string memory localName) internal view {

249:     function _isAlphaNumeric(bytes1 char) internal pure returns (bool) {

253:     function _hasTokenGuardianEnabled(address wallet) internal view returns (bool) {

260:     function _beforeTokenTransfer(
261:             address from,
262:             address to,
263:             uint256 /* firstTokenId */,
264:             uint256 batchSize
265:         ) internal override {

62, 70, 74, 78, 86, 96, 101, 126, 139, 147, 155, 159, 163, 168, 177, 182, 186, 191, 202, 226, 249, 253, 260,

File: contracts/namespaces/TokenHandleRegistry.sol

42:     constructor(address lensHub, address lensHandles) {

50:     function migrationLink(uint256 handleId, uint256 tokenId) external {

93:     /// @inheritdoc ITokenHandleRegistry
94:        function resolve(uint256 handleId) external view returns (uint256) {

106:     /// @inheritdoc ITokenHandleRegistry
107:         function getDefaultHandle(uint256 tokenId) external view returns (uint256) {

119:     ///        INTERNAL FUNCTIONS      ///
120:         //////////////////////////////////////
121:     
122:         function _resolveHandleToToken(
123:             RegistryTypes.Handle memory handle
124:         ) internal view returns (RegistryTypes.Token storage) {

128:     function _resolveTokenToHandle(
129:             RegistryTypes.Token memory token
130:         ) internal view returns (RegistryTypes.Handle storage) {

134:     function _link(RegistryTypes.Handle memory handle, RegistryTypes.Token memory token) internal {

144:     function _deleteTokenToHandleLinkageIfAny(RegistryTypes.Handle memory handle) internal {

152:     function _deleteHandleToTokenLinkageIfAny(RegistryTypes.Token memory token) internal {

160:     function _unlink(RegistryTypes.Handle memory handle, RegistryTypes.Token memory token) internal {

167:     function _handleHash(RegistryTypes.Handle memory handle) internal pure returns (bytes32) {

171:     function _tokenHash(RegistryTypes.Token memory token) internal pure returns (bytes32) {

42, 50, 93, 106, 119, 128, 134, 144, 152, 160, 167, 171,

File: contracts/interfaces/ICollectNFT.sol

34:     /**

34,

File: contracts/interfaces/ILegacyCollectNFT.sol

40:     /**

40,

File: contracts/interfaces/ILensProtocol.sol

15:     /**

143:     /**

165:     /**

186:     /**

209:     /**

237:     /**

308:     /**

328:     /**

15, 143, 165, 186, 209, 237, 308, 328,

File: contracts/interfaces/IModuleGlobals.sol

85:     /**

85,

[N-31] Non-external function names (private or internal.) should begin with an underscore

According to the Solidity Style Guide, Non-external variable and function names should begin0 with anunderscore

Instances (39):

see instances
File: contracts/libraries/MetaTxLib.sol

450:     function calculateDomainSeparator() internal view returns (bytes32) {

450,

File: contracts/libraries/ProfileLib.sol

16:     function ownerOf(uint256 profileId) internal view returns (address) {

24:     function exists(uint256 profileId) internal view returns (bool) {

16, 24,

File: contracts/libraries/PublicationLib.sol

170:     function getPublicationType(uint256 profileId, uint256 pubId) internal view returns (Types.PublicationType) {

170,

File: contracts/libraries/StorageLib.sol

49:     function getPublication(uint256 profileId, uint256 pubId)

63:     function getProfile(uint256 profileId) internal pure returns (Types.Profile storage _profiles) {

71:     function getDelegatedExecutorsConfig(uint256 delegatorProfileId)

83:     function tokenGuardianDisablingTimestamp()

93:     function getTokenData(uint256 tokenId) internal pure returns (Types.TokenData storage _tokenData) {

101:     function blockedStatus(uint256 blockerProfileId)

113:     function nonces() internal pure returns (mapping(address => uint256) storage _nonces) {

119:     function profileIdByHandleHash()

129:     function profileCreatorWhitelisted()

139:     function followModuleWhitelisted()

149:     function actionModuleWhitelistData()

159:     function actionModuleById() internal pure returns (mapping(uint256 => address) storage _actionModules) {

165:     function incrementMaxActionModuleIdUsed() internal returns (uint256) {

177:     function referenceModuleWhitelisted()

187:     function getGovernance() internal view returns (address _governance) {

193:     function setGovernance(address newGovernance) internal {

199:     function getEmergencyAdmin() internal view returns (address _emergencyAdmin) {

205:     function setEmergencyAdmin(address newEmergencyAdmin) internal {

211:     function getState() internal view returns (Types.ProtocolState _state) {

217:     function setState(Types.ProtocolState newState) internal {

223:     function getLastInitializedRevision() internal view returns (uint256 _lastInitializedRevision) {

229:     function setLastInitializedRevision(uint256 newLastInitializedRevision) internal {

49, 63, 71, 83, 93, 101, 113, 119, 129, 139, 149, 159, 165, 177, 187, 193, 199, 205, 211, 217, 223, 229,

File: contracts/libraries/ValidationLib.sol

16:     function validatePointedPub(uint256 profileId, uint256 pubId) internal view {

24:     function validateAddressIsProfileOwner(address expectedProfileOwner, uint256 profileId) internal view {

30:     function validateAddressIsProfileOwnerOrDelegatedExecutor(

42:     function validateAddressIsDelegatedExecutor(address expectedDelegatedExecutor, uint256 delegatorProfileId)

51:     function validateReferenceModuleWhitelisted(address referenceModule) internal view {

57:     function validateFollowModuleWhitelisted(address followModule) internal view {

63:     function validateProfileCreatorWhitelisted(address profileCreator) internal view {

69:     function validateNotBlocked(uint256 profile, uint256 byProfile) internal view {

75:     function validateProfileExists(uint256 profileId) internal view {

81:     function validateCallerIsGovernance() internal view {

87:     function validateReferrersAndGetReferrersPubTypes(

16, 24, 30, 42, 51, 57, 63, 69, 75, 81, 87,

File: contracts/base/HubRestricted.sol

24:     constructor(address hub) {

24,

File: contracts/base/LensProfiles.sol

33:     constructor(address moduleGlobals, uint256 tokenGuardianCooldown) {

33,

[N-32] Non-external variable (private or internal.) should begin with an underscore

According to the Solidity Style Guide, Non-external variable and function names should begin0 with anunderscore

Instances (17):

see instances
File: contracts/base/LensImplGetters.sol

8:     address internal immutable FOLLOW_NFT_IMPL;

8,

File: contracts/base/LensProfiles.sol

29:     IModuleGlobals immutable MODULE_GLOBALS;

31:     uint256 internal immutable TOKEN_GUARDIAN_COOLDOWN;

29, 31,

File: contracts/base/upgradeability/FollowNFTProxy.sol

11:     address immutable HUB;

11,

File: contracts/misc/LensV2Migration.sol

12:     address internal immutable FEE_FOLLOW_MODULE;

13:     address internal immutable PROFILE_FOLLOW_MODULE;

14:     address internal immutable NEW_FEE_FOLLOW_MODULE;

16:     LensHandles internal immutable lensHandles;

17:     TokenHandleRegistry internal immutable tokenHandleRegistry;

12, 13, 14, 16, 17,

File: contracts/misc/ProfileCreationProxy.sol

20:     ILensHandles immutable LENS_HANDLES;

21:     ITokenHandleRegistry immutable TOKEN_HANDLE_REGISTRY;

20, 21,

File: contracts/namespaces/LensHandles.sol

30:     uint256 internal immutable NAMESPACE_LENGTH = bytes(NAMESPACE).length;

33:     uint256 internal immutable TOKEN_GUARDIAN_COOLDOWN;

30, 33,

File: contracts/namespaces/TokenHandleRegistry.sol

21:     address immutable LENS_HUB;

22:     address immutable LENS_HANDLES;

25:     mapping(bytes32 handle => RegistryTypes.Token token) handleToToken;

26:     mapping(bytes32 token => RegistryTypes.Handle handle) tokenToHandle;

21, 22, 25, 26,

[N-33] Not using the named return variables anywhere in the function is confusing

Consider changing the variable to be an unnamed one, since the variable is never assigned, nor is it returned by name

Instances (19):

see instances
File: contracts/libraries/PublicationLib.sol

203:     function _asReferencePubParams(Types.QuoteParams calldata quoteParams)
204:             private
205:             pure
206:             returns (Types.ReferencePubParams calldata referencePubParams)
207:         {

214:     function _asReferencePubParams(Types.CommentParams calldata commentParams)
215:             private
216:             pure
217:             returns (Types.ReferencePubParams calldata referencePubParams)
218:         {

203, 214,

File: contracts/libraries/StorageLib.sol

49:     function getPublication(uint256 profileId, uint256 pubId)
50:            internal
51:            pure
52:            returns (Types.Publication storage _publication)
53:        {

63:     function getProfile(uint256 profileId) internal pure returns (Types.Profile storage _profiles) {

71:     function getDelegatedExecutorsConfig(uint256 delegatorProfileId)
72:            internal
73:            pure
74:            returns (Types.DelegatedExecutorsConfig storage _delegatedExecutorsConfig)
75:        {

83:     function tokenGuardianDisablingTimestamp()
84:            internal
85:            pure
86:            returns (mapping(address => uint256) storage _tokenGuardianDisablingTimestamp)
87:        {

93:     function getTokenData(uint256 tokenId) internal pure returns (Types.TokenData storage _tokenData) {

101:     function blockedStatus(uint256 blockerProfileId)
102:             internal
103:             pure
104:             returns (mapping(uint256 => bool) storage _blockedStatus)
105:         {

113:     function nonces() internal pure returns (mapping(address => uint256) storage _nonces) {

119:     function profileIdByHandleHash()
120:             internal
121:             pure
122:             returns (mapping(bytes32 => uint256) storage _profileIdByHandleHash)
123:         {

129:     function profileCreatorWhitelisted()
130:             internal
131:             pure
132:             returns (mapping(address => bool) storage _profileCreatorWhitelisted)
133:         {

139:     function followModuleWhitelisted()
140:             internal
141:             pure
142:             returns (mapping(address => bool) storage _followModuleWhitelisted)
143:         {

149:     function actionModuleWhitelistData()
150:             internal
151:             pure
152:             returns (mapping(address => Types.ActionModuleWhitelistData) storage _actionModuleWhitelistData)
153:         {

159:     function actionModuleById() internal pure returns (mapping(uint256 => address) storage _actionModules) {

177:     function referenceModuleWhitelisted()
178:             internal
179:             pure
180:             returns (mapping(address => bool) storage _referenceModuleWhitelisted)
181:         {

187:     function getGovernance() internal view returns (address _governance) {

199:     function getEmergencyAdmin() internal view returns (address _emergencyAdmin) {

211:     function getState() internal view returns (Types.ProtocolState _state) {

223:     function getLastInitializedRevision() internal view returns (uint256 _lastInitializedRevision) {

49, 63, 71, 83, 93, 101, 113, 119, 129, 139, 149, 159, 177, 187, 199, 211, 223,

[N-34] Overly complicated arithmetic

To maintain readability in code, particularly in Solidity which can involve complex mathematical operations, it is often recommended to limit the number of arithmetic operations to a maximum of 2-3 per line. Too many operations in a single line can make the code difficult to read and understand, increase the likelihood of mistakes, and complicate the process of debugging and reviewing the code. Consider splitting such operations over more than one line, take special care when dealing with division however. Try to limit the number of arithmetic operations to a maximum of 3 per line.

Instances (8):

see instances
File: contracts/FollowNFT.sol

450:         uint256 /* followTokenId */

456:         uint256 /* royaltiesInBasisPoints */

450, 456,

File: contracts/base/ERC2981CollectionRoyalties.sol

52:         uint256, /* tokenId */

52,

File: contracts/base/LensProfiles.sol

154:         uint256 /* tokenId */

160:         uint256 /* royaltiesInBasisPoints */

154, 160,

File: contracts/misc/LegacyCollectNFT.sol

103:         uint256 /* tokenId */

109:         uint256 /* royaltiesInBasisPoints */

103, 109,

File: contracts/namespaces/LensHandles.sol

263:         uint256 /* firstTokenId */,

263,

[N-35] Public functions not called internally

Those functions should be declared as external instead of public, as they are never called internally by the contract. Contracts are allowed to override their parents' functions and change the visibility from external to public.

Instances (2):

File: contracts/base/ERC2981CollectionRoyalties.sol

17:     function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {

17,

File: contracts/namespaces/LensHandles.sol

177:     function getHandle(uint256 tokenId) public view returns (string memory) {

177,

[N-36] require() / revert() statements should have descriptive reason strings

Instances (115):

see instances
File: contracts/LensHub.sol

61:             revert Errors.PublishingPaused();

61,

File: contracts/FollowNFT.sol

51:             revert Errors.Initialized();

143:             revert Errors.TokenDoesNotExist();

158:             revert Errors.InvalidParameter();

287:             revert Errors.TokenDoesNotExist();

459:             revert Errors.NotProfileOwner();

492:             revert Errors.InvalidParameter();

51, 143, 158, 287, 459, 492,

File: contracts/libraries/ActionLib.sol

37:             revert Errors.ActionNotAllowed();

37,

File: contracts/libraries/FollowLib.sol

26:             revert Errors.ArrayMismatch();

36:                 revert Errors.SelfFollow();

67:                 revert Errors.NotFollowing();

26, 36, 67,

File: contracts/libraries/GovernanceLib.sol

59:             revert Errors.NotGovernanceOrEmergencyAdmin();

56:                 revert Errors.EmergencyAdminCanOnlyPauseFurther();

95:                 revert Errors.NotWhitelisted();

59, 56, 95,

File: contracts/libraries/LegacyCollectLib.sol

68:                 revert Errors.CollectNotAllowed();

68,

File: contracts/libraries/MetaTxLib.sol

470:         if (signature.deadline < block.timestamp) revert Errors.SignatureExpired();

480:                 revert Errors.SignatureInvalid();

475:                 revert Errors.SignatureInvalid();

470, 480, 475,

File: contracts/libraries/MigrationLib.sol

103:             revert Errors.ArrayMismatch();

103,

File: contracts/libraries/ProfileLib.sol

19:             revert Errors.TokenDoesNotExist();

41:             revert Errors.ProfileImageURILengthInvalid();

122:             revert Errors.ProfileImageURILengthInvalid();

134:             revert Errors.ArrayMismatch();

145:                 revert Errors.SelfBlock();

231:             revert Errors.ArrayMismatch();

262:             revert Errors.InvalidParameter();

19, 41, 122, 134, 145, 231, 262,

File: contracts/libraries/PublicationLib.sol

360:                 revert Errors.InvalidReferrer();

348:                     revert Errors.InvalidReferrer();

413:                 revert Errors.InvalidReferrer();

401:                     revert Errors.InvalidReferrer();

466:                 revert Errors.InvalidReferrer();

454:                     revert Errors.InvalidReferrer();

480:             revert Errors.ArrayMismatch();

493:                 revert Errors.NotWhitelisted();

499:                 revert Errors.AlreadyEnabled();

360, 348, 413, 401, 466, 454, 480, 493, 499,

File: contracts/libraries/StorageLib.sol

172:             revert Errors.MaxActionModuleIdReached();

172,

File: contracts/libraries/ValidationLib.sol

20:             revert Errors.InvalidPointedPub();

26:             revert Errors.NotProfileOwner();

47:             revert Errors.ExecutorInvalid();

53:             revert Errors.NotWhitelisted();

59:             revert Errors.NotWhitelisted();

65:             revert Errors.NotWhitelisted();

71:             revert Errors.Blocked();

77:             revert Errors.TokenDoesNotExist();

83:             revert Errors.NotGovernance();

94:             revert Errors.ArrayMismatch();

131:             revert Errors.InvalidReferrer();

139:             revert Errors.InvalidReferrer();

161:                 revert Errors.InvalidReferrer();

165:                 revert Errors.InvalidReferrer();

152:                 revert Errors.InvalidReferrer();

191:             revert Errors.InvalidReferrer();

226:                     revert Errors.InvalidReferrer();

20, 26, 47, 53, 59, 65, 71, 77, 83, 94, 131, 139, 161, 165, 152, 191, 226,

File: contracts/base/ERC2981CollectionRoyalties.sol

45:             revert Errors.InvalidParameter();

45,

File: contracts/base/HubRestricted.sol

19:             revert Errors.NotHub();

19,

File: contracts/base/LensBaseERC721.sol

108:             revert Errors.InvalidParameter();

119:             revert Errors.TokenDoesNotExist();

130:             revert Errors.TokenDoesNotExist();

140:             revert Errors.TokenDoesNotExist();

176:             revert Errors.InvalidParameter();

180:             revert Errors.NotOwnerOrApproved();

191:             revert Errors.TokenDoesNotExist();

202:             revert Errors.InvalidParameter();

225:             revert Errors.NotOwnerOrApproved();

252:             revert Errors.NotOwnerOrApproved();

266:             revert Errors.NotOwnerOrApproved();

310:             revert Errors.NonERC721ReceiverImplementer();

335:             revert Errors.TokenDoesNotExist();

355:             revert Errors.InvalidParameter();

414:             revert Errors.InvalidOwner();

417:             revert Errors.InvalidParameter();

480:                     revert Errors.NonERC721ReceiverImplementer();

108, 119, 130, 140, 176, 180, 191, 202, 225, 252, 266, 310, 335, 355, 414, 417, 480,

File: contracts/base/LensHubEventHooks.sol

15:             revert Errors.CallerNotFollowNFT();

34:             revert Errors.CallerNotCollectNFT();

15, 34,

File: contracts/base/LensProfiles.sol

40:             revert Errors.Paused();

52:             revert Errors.NotEOA();

65:             revert Errors.DisablingAlreadyTriggered();

79:             revert Errors.AlreadyEnabled();

107:             revert Errors.TokenDoesNotExist();

115:             revert Errors.GuardianEnabled();

123:             revert Errors.GuardianEnabled();

172:             revert Errors.GuardianEnabled();

40, 52, 65, 79, 107, 115, 123, 172,

File: contracts/misc/LegacyCollectNFT.sol

39:         if (hub == address(0)) revert Errors.InitParamsInvalid();

46:         if (_initialized) revert Errors.Initialized();

56:         if (msg.sender != HUB) revert Errors.NotHub();

70:         if (!_exists(tokenId)) revert Errors.TokenDoesNotExist();

112:             revert Errors.NotProfileOwner();

39, 46, 56, 70, 112,

File: contracts/misc/ModuleGlobals.sol

28:         if (msg.sender != _governance) revert Errors.NotGovernance();

95:         if (newGovernance == address(0)) revert Errors.InitParamsInvalid();

102:         if (newTreasury == address(0)) revert Errors.InitParamsInvalid();

109:         if (newTreasuryFee >= BPS_MAX / 2) revert Errors.InitParamsInvalid();

116:         if (currency == address(0)) revert Errors.InitParamsInvalid();

28, 95, 102, 109, 116,

File: contracts/namespaces/LensHandles.sol

43:             revert HandlesErrors.NotOwnerNorWhitelisted();

50:             revert HandlesErrors.NotEOA();

57:             revert HandlesErrors.NotHub();

103:             revert HandlesErrors.NotOwner();

115:             revert HandlesErrors.DisablingAlreadyTriggered();

128:             revert HandlesErrors.AlreadyEnabled();

142:             revert HandlesErrors.GuardianEnabled();

150:             revert HandlesErrors.GuardianEnabled();

171:             revert HandlesErrors.DoesNotExist();

207:             revert HandlesErrors.HandleLengthInvalid();

212:             revert HandlesErrors.HandleFirstCharInvalid();

218:                 revert HandlesErrors.HandleContainsInvalidCharacters();

231:             revert HandlesErrors.HandleLengthInvalid();

235:             revert HandlesErrors.HandleFirstCharInvalid();

241:                 revert HandlesErrors.HandleContainsInvalidCharacters();

268:             revert HandlesErrors.GuardianEnabled();

43, 50, 57, 103, 115, 128, 142, 150, 171, 207, 212, 218, 231, 235, 241, 268,

File: contracts/namespaces/TokenHandleRegistry.sol

30:             revert RegistryErrors.NotHandleOwner();

37:             revert RegistryErrors.NotTokenOwner();

52:             revert RegistryErrors.OnlyLensHub();

80:             revert RegistryErrors.NotHandleNorTokenOwner();

88:             revert RegistryErrors.NotLinked();

96:             revert RegistryErrors.DoesNotExist();

109:             revert RegistryErrors.DoesNotExist();

30, 37, 52, 80, 88, 96, 109,

[N-37] Return values of approve() not checked

Not all IERC20 implementations revert() when there's a failure in approve(). The function signature has a boolean return value and they indicate errors that way instead. By not checking the return value, operations that should have marked as failed, may potentially go through without actually approving anything

Instances (3):

File: contracts/base/LensBaseERC721.sol

183:         _approve(to, tokenId);

183,

File: contracts/base/LensProfiles.sol

117:         super.approve(to, tokenId);

117,

File: contracts/namespaces/LensHandles.sol

144:         super.approve(to, tokenId);

144,

[N-38] Strings should use double quotes rather than single quotes

See the Solidity Style Guide

Instances (45):

see instances
File: contracts/FollowNFT.sol

21:     string constant FOLLOW_NFT_NAME_SUFFIX = '-Follower';

22:     string constant FOLLOW_NFT_SYMBOL_SUFFIX = '-Fl';

21, 22,

File: contracts/libraries/MetaTxLib.sol

21:     string constant EIP712_DOMAIN_VERSION = '2';

493:         return keccak256(abi.encodePacked('\x19\x01', calculateDomainSeparator(), hashedMessage));

21, 493,

File: contracts/libraries/MigrationLib.sol

134:                 followModuleData: '',

135:                 processFollowModuleReturnData: '',

134, 135,

File: contracts/libraries/PublicationLib.sol

363:         return '';

416:         return '';

469:         return '';

363, 416, 469,

File: contracts/libraries/constants/Typehash.sol

7:     bytes32 constant ACT = keccak256('Act(uint256 publicationActedProfileId,uint256 publicationActedId,uint256 actorProfileId,uint256[] referrerProfileIds,uint256[] referrerPubIds,address actionModuleAddress,bytes actionModuleData,uint256 nonce,uint256 deadline)');

9:     bytes32 constant BURN = keccak256('Burn(uint256 tokenId,uint256 nonce,uint256 deadline)');

11:     bytes32 constant CHANGE_DELEGATED_EXECUTORS_CONFIG = keccak256('ChangeDelegatedExecutorsConfig(uint256 delegatorProfileId,address[] delegatedExecutors,bool[] approvals,uint64 configNumber,bool switchToGivenConfig,uint256 nonce,uint256 deadline)');

13:     bytes32 constant LEGACY_COLLECT = keccak256('Collect(uint256 publicationCollectedProfileId,uint256 publicationCollectedId,uint256 collectorProfileId,uint256 referrerProfileId,uint256 referrerPubId,bytes collectModuleData,uint256 nonce,uint256 deadline)');

15:     bytes32 constant COMMENT = keccak256('Comment(uint256 profileId,string contentURI,uint256 pointedProfileId,uint256 pointedPubId,uint256[] referrerProfileIds,uint256[] referrerPubIds,bytes referenceModuleData,address collectModule,bytes collectModuleInitData,address referenceModule,bytes referenceModuleInitData,uint256 nonce,uint256 deadline)');

17:     bytes32 constant EIP712_DOMAIN = keccak256('EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)');

19:     bytes32 constant FOLLOW = keccak256('Follow(uint256 followerProfileId,uint256[] idsOfProfilesToFollow,uint256[] followTokenIds,bytes[] datas,uint256 nonce,uint256 deadline)');

21:     bytes32 constant MIRROR = keccak256('Mirror(uint256 profileId,uint256 pointedProfileId,uint256 pointedPubId,uint256[] referrerProfileId,uint256[] referrerPubId,bytes referenceModuleData,uint256 nonce,uint256 deadline)');

23:     bytes32 constant POST = keccak256('Post(uint256 profileId,string contentURI,address collectModule,bytes collectModuleInitData,address referenceModule,bytes referenceModuleInitData,uint256 nonce,uint256 deadline)');

25:     bytes32 constant QUOTE = keccak256('Quote(uint256 profileId,string contentURI,uint256 pointedProfileId,uint256 pointedPubId,uint256[] referrerProfileIds,uint256[] referrerPubIds,bytes referenceModuleData,address collectModule,bytes collectModuleInitData,address referenceModule,bytes referenceModuleInitData,uint256 nonce,uint256 deadline)');

27:     bytes32 constant SET_BLOCK_STATUS = keccak256('SetBlockStatus(uint256 byProfileId,uint256[] idsOfProfilesToSetBlockStatus,bool[] blockStatus,uint256 nonce,uint256 deadline)');

29:     bytes32 constant SET_FOLLOW_MODULE = keccak256('SetFollowModule(uint256 profileId,address followModule,bytes followModuleInitData,uint256 nonce,uint256 deadline)');

31:     bytes32 constant SET_PROFILE_IMAGE_URI = keccak256('SetProfileImageURI(uint256 profileId,string imageURI,uint256 nonce,uint256 deadline)');

33:     bytes32 constant SET_PROFILE_METADATA_URI = keccak256('SetProfileMetadataURI(uint256 profileId,string metadata,uint256 nonce,uint256 deadline)');

35:     bytes32 constant UNFOLLOW = keccak256('Unfollow(uint256 unfollowerProfileId,uint256[] idsOfProfilesToUnfollow,uint256 nonce,uint256 deadline)');

7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35,

File: contracts/base/LensBaseERC721.sol

239:         safeTransferFrom(from, to, tokenId, '');

239,

File: contracts/misc/LegacyCollectNFT.sol

78:         return string.concat('Lens Collect | Profile #', _profileId.toString(), ' - Publication #', _pubId.toString());

78:         return string.concat('Lens Collect | Profile #', _profileId.toString(), ' - Publication #', _pubId.toString());

85:         return 'LENS-COLLECT';

78, 78, 85,

File: contracts/namespaces/LensHandles.sol

29:     string internal constant NAMESPACE = 'lens';

31:     uint256 internal constant SEPARATOR_LENGTH = 1; // bytes('.').length;

66:     ) ERC721('', '') ImmutableOwnable(owner, lensHub) {

66:     ) ERC721('', '') ImmutableOwnable(owner, lensHub) {

71:         return string.concat(symbol(), ' Handles');

75:         return string.concat('.', NAMESPACE);

179:         return string.concat(localName, '.', NAMESPACE);

211:         if (firstByte == '-' || firstByte == '_') {

211:         if (firstByte == '-' || firstByte == '_') {

217:             if (!_isAlphaNumeric(localNameAsBytes[i]) && localNameAsBytes[i] != '-' && localNameAsBytes[i] != '_') {

217:             if (!_isAlphaNumeric(localNameAsBytes[i]) && localNameAsBytes[i] != '-' && localNameAsBytes[i] != '_') {

234:         if (localNameAsBytes[0] == '_') {

240:             if (!_isAlphaNumeric(localNameAsBytes[i]) && localNameAsBytes[i] != '_') {

250:         return (char >= '0' && char <= '9') || (char >= 'a' && char <= 'z');

250:         return (char >= '0' && char <= '9') || (char >= 'a' && char <= 'z');

250:         return (char >= '0' && char <= '9') || (char >= 'a' && char <= 'z');

250:         return (char >= '0' && char <= '9') || (char >= 'a' && char <= 'z');

29, 31, 66, 66, 71, 75, 179, 211, 211, 217, 217, 234, 240, 250, 250, 250, 250,

[N-39] Contract does not follow the Solidity style guide's suggested layout ordering

The style guidesays that, within a contract, the ordering should be 1) Type declarations, 2) State variables, 3) Events, 4) Modifiers, and 5) Functions, but the contract(s) below do not follow this ordering

Instances (28):

see instances
File: contracts/FollowNFT.sol

19:     using Strings for uint256;

19,

File: contracts/libraries/LegacyCollectLib.sol

21:     using Strings for uint256;

21,

File: contracts/libraries/MetaTxLib.sol

21:     string constant EIP712_DOMAIN_VERSION = '2';

43:     function validateSetProfileMetadataURISignature(

173:     struct ReferenceParamsForAbiEncode {

21, 43, 173,

File: contracts/libraries/constants/Types.sol

48:     enum ProtocolState {

65:     enum PublicationType {

48, 65,

File: contracts/base/LensBaseERC721.sol

31:     using Address for address;

32:     using Strings for uint256;

31, 32,

File: contracts/base/LensProfiles.sol

27:     using Address for address;

33:     constructor(address moduleGlobals, uint256 tokenGuardianCooldown) {

50:     modifier onlyEOA() {

27, 33, 50,

File: contracts/base/upgradeability/FollowNFTProxy.sol

10:     using Address for address;

10,

File: contracts/misc/ImmutableOwnable.sol

9:     error OnlyOwner();

10:     error OnlyOwnerOrHub();

12:     modifier onlyOwner() {

9, 10, 12,

File: contracts/misc/LegacyCollectNFT.sol

24:     using Strings for uint256;

24,

File: contracts/misc/access/ControllableByContract.sol

8:     event ControllerContractUpdated(address previousControllerContract, address newControllerContract);

10:     error Unauthorized();

12:     address public controllerContract;

14:     modifier onlyOwnerOrControllerContract() {

8, 10, 12, 14,

File: contracts/namespaces/LensHandles.sol

26:     using Address for address;

26,

File: contracts/interfaces/IFollowNFT.sol

18:     error AlreadyFollowing();

19:     error NotFollowing();

20:     error FollowTokenDoesNotExist();

21:     error AlreadyWrapped();

22:     error OnlyWrappedFollowTokens();

23:     error DoesNotHavePermissions();

18, 19, 20, 21, 22, 23,

[N-40] Function ordering does not follow the Solidity style guide

According to the Solidity style guide, functions should be laid out in the following order :constructor(), receive(), fallback(), external, public, internal, private, but the cases below do not follow this pattern

Instances (15):

see instances
File: contracts/FollowNFT.sol

480:     function tryMigrate(
481:             uint256 followerProfileId,
482:             address followerProfileOwner,
483:             uint256 idOfProfileFollowed,
484:             uint256 followTokenId
485:         ) external onlyHub returns (uint48) {

285:     function tokenURI(uint256 followTokenId) public view override returns (string memory) {

480, 285,

File: contracts/libraries/GovernanceLib.sol

86:     function whitelistActionModule(address actionModule, bool whitelist) external {

86,

File: contracts/libraries/MetaTxLib.sol

425:     function validateActSignature(
426:             Types.EIP712Signature calldata signature,
427:             Types.PublicationActionParams calldata publicationActionParams
428:         ) external {

450:     function calculateDomainSeparator() internal view returns (bytes32) {

425, 450,

File: contracts/libraries/MigrationLib.sol

141:     function batchMigrateFollowModules(
142:             uint256[] calldata profileIds,
143:             address legacyFeeFollowModule,
144:             address legacyProfileFollowModule,
145:             address newFeeFollowModule
146:         ) external {

141,

File: contracts/libraries/ProfileLib.sol

215:     function isExecutorApproved(uint256 delegatorProfileId, address delegatedExecutor) external view returns (bool) {

215,

File: contracts/libraries/PublicationLib.sol

190:     function getContentURI(uint256 profileId, uint256 pubId) external view returns (string memory) {

291:     function _fillRootOfPublicationInStorage(
292:             Types.Publication storage _publication,
293:             uint256 pointedProfileId,
294:             uint256 pointedPubId
295:         ) internal {

190, 291,

File: contracts/libraries/ValidationLib.sol

121:     function validateLegacyCollectReferrer(
122:             uint256 referrerProfileId,
123:             uint256 referrerPubId,
124:             uint256 publicationCollectedProfileId,
125:             uint256 publicationCollectedId
126:         ) external view {

121,

File: contracts/base/ERC2981CollectionRoyalties.sol

39:     function royaltyInfo(uint256 tokenId, uint256 salePrice) external view returns (address, uint256) {

39,

File: contracts/base/LensBaseERC721.sol

166:     function totalSupply() external view virtual override returns (uint256) {

264:     function burn(uint256 tokenId) public virtual override {

506:     function _beforeTokenTransfer(
507:             address from,
508:             address to,
509:             uint256 tokenId
510:         ) internal virtual {}

166, 264, 506,

File: contracts/namespaces/LensHandles.sol

186:     function getTokenGuardianDisablingTimestamp(address wallet) external view returns (uint256) {

186,

[N-41] Contracts should have full test coverage

While 100% code coverage does not guarantee that there are no bugs, it often will catch easy-to-find bugs, and will ensure that there are fewer regressions when the code invariably has to be modified. Furthermore, in order to get full coverage, code authors will often have to re-organize their code so that it is more modular, so that each component can be tested separately, which reduces interdependencies between modules and layers, and makes for code that is easier to reason about and audit.

Instances (10):

see instances
File: Various Files

0: undefined

0: undefined

0: undefined

0: undefined

0: undefined

0: undefined

0: undefined

0: undefined

0: undefined

0: undefined

0, 0, 0, 0, 0, 0, 0, 0, 0, 0,

[N-42] TODO Left in the code

TODOs may signal that a feature is missing or not ready for audit, consider resolving the issue and removing the TODO comment

Instances (4):

File: contracts/libraries/constants/Types.sol

49:         // TODO: Reverse order, so Paused becomes 0 and the default. This will get rid of the initializer needs.

345:     // TODO: Shouldn't this be in the modules Types?

49, 345,

File: contracts/namespaces/LensHandles.sol

167:     // TODO: Should we revert if it doesn't exist?

176:     // TODO: Should we revert if it doesn't exist?

167, 176,

[N-43] Event is missing indexed fields

Index event fields make the field more quickly accessible to off-chain tools that parse events. This is especially useful when it comes to filtering based on an address. However, note that each index field costs extra gas during emission, so it's not necessarily best to index the maximum allowed per event (three fields). Where applicable, each event should use three indexed fields if there are three or more fields, and gas usage is not particularly of concern for the events in question. If there are fewer than three applicable fields, all of the applicable fields should be indexed.

Instances (38):

see instances
File: contracts/libraries/LegacyCollectLib.sol

35:     event CollectedLegacy(

35,

File: contracts/libraries/MigrationLib.sol

29:     event ProfileMigrated(uint256 profileId, address profileDestination, string handle, uint256 handleId);

29,

File: contracts/libraries/constants/Events.sol

15:     event BaseInitialized(string name, string symbol, uint256 timestamp);

25:     event StateSet(

41:     event GovernanceSet(

57:     event EmergencyAdminSet(

71:     event ProfileCreatorWhitelisted(address indexed profileCreator, bool indexed whitelisted, uint256 timestamp);

80:     event FollowModuleWhitelisted(address indexed followModule, bool indexed whitelisted, uint256 timestamp);

89:     event ReferenceModuleWhitelisted(address indexed referenceModule, bool indexed whitelisted, uint256 timestamp);

99:     event ActionModuleWhitelisted(

118:     event ProfileCreated(

139:     event DelegatedExecutorsConfigChanged(

155:     event ProfileImageURISet(uint256 indexed profileId, string imageURI, uint256 timestamp);

166:     event FollowModuleSet(

184:     event PostCreated(

205:     event CommentCreated(

223:     event MirrorCreated(

243:     event QuoteCreated(

259:     event FollowNFTDeployed(uint256 indexed profileId, address indexed followNFT, uint256 timestamp);

269:     event CollectNFTDeployed(

287:     event Collected(

304:     event Acted(Types.PublicationActionParams publicationActionParams, bytes actionModuleReturnData, uint256 timestamp);

317:     event Followed(

333:     event Unfollowed(uint256 indexed unfollowerProfileId, uint256 idOfProfileUnfollowed, uint256 timestamp);

342:     event Blocked(uint256 indexed byProfileId, uint256 idOfProfileBlocked, uint256 timestamp);

351:     event Unblocked(uint256 indexed byProfileId, uint256 idOfProfileUnblocked, uint256 timestamp);

363:     event CollectNFTTransferred(

379:     event ModuleGlobalsGovernanceSet(address indexed prevGovernance, address indexed newGovernance, uint256 timestamp);

388:     event ModuleGlobalsTreasurySet(address indexed prevTreasury, address indexed newTreasury, uint256 timestamp);

397:     event ModuleGlobalsTreasuryFeeSet(uint16 indexed prevTreasuryFee, uint16 indexed newTreasuryFee, uint256 timestamp);

407:     event ModuleGlobalsCurrencyWhitelisted(

421:     event ProfileMetadataSet(uint256 indexed profileId, string metadata, uint256 timestamp);

432:     event TokenGuardianStateChanged(

15, 25, 41, 57, 71, 80, 89, 99, 118, 139, 155, 166, 184, 205, 223, 243, 259, 269, 287, 304, 317, 333, 342, 351, 363, 379, 388, 397, 407, 421, 432,

File: contracts/misc/access/ControllableByContract.sol

8:     event ControllerContractUpdated(address previousControllerContract, address newControllerContract);

8,

File: contracts/namespaces/constants/Events.sol

8:     event HandleMinted(string handle, string namespace, uint256 handleId, address to, uint256 timestamp);

19:     event TokenGuardianStateChanged(

28:     event HandleLinked(RegistryTypes.Handle handle, RegistryTypes.Token token, uint256 timestamp);

35:     event HandleUnlinked(RegistryTypes.Handle handle, RegistryTypes.Token token, uint256 timestamp);

8, 19, 28, 35,

[N-44] Unused contract variables

Note that there may be cases where a variable appears to be used, but this is only because there are multiple definitions of the varible in different files. In such cases, the variable definition should be moved into a separate file. The instances below are the unused variables.

Instances (39):

see instances
File: contracts/FollowNFT.sol

24:     uint256[5] ___DEPRECATED_SLOTS; // Deprecated slots, previously used for delegations.

24,

File: contracts/libraries/StorageLib.sol

31:     uint256 constant PROFILE_COUNTER_SLOT = 22;

45:     uint256 constant PROFILE_ROYALTIES_BPS_SLOT = 30;

31, 45,

File: contracts/libraries/constants/Typehash.sol

7:     bytes32 constant ACT = keccak256('Act(uint256 publicationActedProfileId,uint256 publicationActedId,uint256 actorProfileId,uint256[] referrerProfileIds,uint256[] referrerPubIds,address actionModuleAddress,bytes actionModuleData,uint256 nonce,uint256 deadline)');

9:     bytes32 constant BURN = keccak256('Burn(uint256 tokenId,uint256 nonce,uint256 deadline)');

11:     bytes32 constant CHANGE_DELEGATED_EXECUTORS_CONFIG = keccak256('ChangeDelegatedExecutorsConfig(uint256 delegatorProfileId,address[] delegatedExecutors,bool[] approvals,uint64 configNumber,bool switchToGivenConfig,uint256 nonce,uint256 deadline)');

13:     bytes32 constant LEGACY_COLLECT = keccak256('Collect(uint256 publicationCollectedProfileId,uint256 publicationCollectedId,uint256 collectorProfileId,uint256 referrerProfileId,uint256 referrerPubId,bytes collectModuleData,uint256 nonce,uint256 deadline)');

15:     bytes32 constant COMMENT = keccak256('Comment(uint256 profileId,string contentURI,uint256 pointedProfileId,uint256 pointedPubId,uint256[] referrerProfileIds,uint256[] referrerPubIds,bytes referenceModuleData,address collectModule,bytes collectModuleInitData,address referenceModule,bytes referenceModuleInitData,uint256 nonce,uint256 deadline)');

17:     bytes32 constant EIP712_DOMAIN = keccak256('EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)');

21:     bytes32 constant MIRROR = keccak256('Mirror(uint256 profileId,uint256 pointedProfileId,uint256 pointedPubId,uint256[] referrerProfileId,uint256[] referrerPubId,bytes referenceModuleData,uint256 nonce,uint256 deadline)');

23:     bytes32 constant POST = keccak256('Post(uint256 profileId,string contentURI,address collectModule,bytes collectModuleInitData,address referenceModule,bytes referenceModuleInitData,uint256 nonce,uint256 deadline)');

25:     bytes32 constant QUOTE = keccak256('Quote(uint256 profileId,string contentURI,uint256 pointedProfileId,uint256 pointedPubId,uint256[] referrerProfileIds,uint256[] referrerPubIds,bytes referenceModuleData,address collectModule,bytes collectModuleInitData,address referenceModule,bytes referenceModuleInitData,uint256 nonce,uint256 deadline)');

27:     bytes32 constant SET_BLOCK_STATUS = keccak256('SetBlockStatus(uint256 byProfileId,uint256[] idsOfProfilesToSetBlockStatus,bool[] blockStatus,uint256 nonce,uint256 deadline)');

29:     bytes32 constant SET_FOLLOW_MODULE = keccak256('SetFollowModule(uint256 profileId,address followModule,bytes followModuleInitData,uint256 nonce,uint256 deadline)');

31:     bytes32 constant SET_PROFILE_IMAGE_URI = keccak256('SetProfileImageURI(uint256 profileId,string imageURI,uint256 nonce,uint256 deadline)');

33:     bytes32 constant SET_PROFILE_METADATA_URI = keccak256('SetProfileMetadataURI(uint256 profileId,string metadata,uint256 nonce,uint256 deadline)');

35:     bytes32 constant UNFOLLOW = keccak256('Unfollow(uint256 unfollowerProfileId,uint256[] idsOfProfilesToUnfollow,uint256 nonce,uint256 deadline)');

7, 9, 11, 13, 15, 17, 21, 23, 25, 27, 29, 31, 33, 35,

File: contracts/base/LensBaseERC721.sol

55:     mapping(uint256 => uint256) private __DEPRECATED__ownedTokensIndex;

61:     mapping(uint256 => uint256) private __DEPRECATED__allTokensIndex;

55, 61,

File: contracts/base/LensHubStorage.sol

17:     uint256 private _lastInitializedRevision; // Slot 11.

19:     Types.ProtocolState internal _state; // Slot 12

21:     mapping(address profileCreator => bool isWhitelisted) internal _profileCreatorWhitelisted; // Slot 13

23:     mapping(address => bool isWhitelisted) internal _followModuleWhitelisted; // Slot 14

28:     mapping(address actionModule => Types.ActionModuleWhitelistData whitelistData) internal _actionModuleWhitelistData; // Slot 15

30:     mapping(address referenceModule => bool isWhitelisted) internal _referenceModuleWhitelisted; // Slot 16

32:     mapping(uint256 profileId => address dispatcher) internal __DEPRECATED__dispatcherByProfile; // Slot 17

34:     mapping(bytes32 handleHash => uint256 profileId) internal __DEPRECATED__profileIdByHandleHash; // Slot 18

36:     mapping(uint256 profileId => Types.Profile profile) internal _profiles; // Slot 19

38:     mapping(uint256 profileId => mapping(uint256 pubId => Types.Publication publication)) internal _publications; // Slot 20

40:     mapping(address userAddress => uint256 profileId) internal __DEPRECATED__defaultProfiles; // Slot 21

42:     uint256 internal _profileCounter; // Slot 22 - different from totalSupply, as this is not decreased when burning profiles

44:     address internal _governance; // Slot 23

46:     address internal _emergencyAdmin; // Slot 24

51:     mapping(address => uint256) internal _tokenGuardianDisablingTimestamp; // Slot 25

57:     mapping(uint256 profileId => Types.DelegatedExecutorsConfig config) internal _delegatedExecutorsConfigs; // Slot 26

59:     mapping(uint256 blockerProfileId => mapping(uint256 blockedProfileId => bool isBlocked)) internal _blockedStatus; // Slot 27

61:     mapping(uint256 id => address actionModule) internal _actionModules; // Slot 28

63:     uint256 internal _maxActionModuleIdUsed; // Slot 29

65:     uint256 internal _profileRoyaltiesBps; // Slot 30

17, 19, 21, 23, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 51, 57, 59, 61, 63, 65,

[N-45] Unused error definition

Note that there may be cases where an error superficially appears to be used, but this is only because there are multiple definitions of the error in different files. In such cases, the error definition should be moved into a separate file. The instances below are the unused definitions.

Instances (60):

see instances
File: contracts/libraries/constants/Errors.sol

6:     error CannotInitImplementation();

7:     error Initialized();

8:     error SignatureExpired();

9:     error SignatureInvalid();

10:     error InvalidOwner();

11:     error NotOwnerOrApproved();

12:     error NotHub();

13:     error TokenDoesNotExist();

14:     error NotGovernance();

15:     error NotGovernanceOrEmergencyAdmin();

16:     error EmergencyAdminCanOnlyPauseFurther();

17:     error NotProfileOwner();

18:     error PublicationDoesNotExist();

19:     error ProfileImageURILengthInvalid();

20:     error CallerNotFollowNFT();

21:     error CallerNotCollectNFT(); // Legacy

22:     error ArrayMismatch();

23:     error NotWhitelisted();

24:     error InvalidParameter();

25:     error ExecutorInvalid();

26:     error Blocked();

27:     error SelfBlock();

28:     error NotFollowing();

29:     error SelfFollow();

30:     error InvalidReferrer();

31:     error InvalidPointedPub();

32:     error NonERC721ReceiverImplementer();

33:     error AlreadyEnabled();

36:     error MaxActionModuleIdReached(); // This means we need an upgrade

39:     error InitParamsInvalid();

40:     error ActionNotAllowed();

42:     error CollectNotAllowed(); // Used in LegacyCollectLib (pending deprecation)

45:     error Paused();

46:     error PublishingPaused();

49:     error GuardianEnabled();

50:     error NotEOA();

51:     error DisablingAlreadyTriggered();

6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 36, 39, 40, 42, 45, 46, 49, 50, 51,

File: contracts/namespaces/constants/Errors.sol

6:     error NotHandleOwner();

7:     error NotTokenOwner();

8:     error NotHandleNorTokenOwner();

9:     error OnlyLensHub();

10:     error NotLinked();

11:     error DoesNotExist();

15:     error HandleLengthInvalid();

16:     error HandleContainsInvalidCharacters();

17:     error HandleFirstCharInvalid();

18:     error NotOwnerNorWhitelisted();

19:     error NotOwner();

20:     error NotHub();

21:     error DoesNotExist();

22:     error NotEOA();

23:     error DisablingAlreadyTriggered();

24:     error GuardianEnabled();

25:     error AlreadyEnabled();

6, 7, 8, 9, 10, 11, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,

File: contracts/interfaces/IFollowNFT.sol

18:     error AlreadyFollowing();

19:     error NotFollowing();

20:     error FollowTokenDoesNotExist();

21:     error AlreadyWrapped();

22:     error OnlyWrappedFollowTokens();

23:     error DoesNotHavePermissions();

18, 19, 20, 21, 22, 23,

[N-46] Unused file

The file is never imported by any other source file. If the file is needed for tests, it should be moved to a test directory

Instances (44):

see instances
File: contracts/LensHub.sol

1: // SPDX-License-Identifier: MIT

1,

File: contracts/FollowNFT.sol

1: // SPDX-License-Identifier: MIT

1,

File: contracts/libraries/ActionLib.sol

1: // SPDX-License-Identifier: MIT

1,

File: contracts/libraries/FollowLib.sol

1: // SPDX-License-Identifier: MIT

1,

File: contracts/libraries/GovernanceLib.sol

1: // SPDX-License-Identifier: MIT

1,

File: contracts/libraries/LegacyCollectLib.sol

1: // SPDX-License-Identifier: MIT

1,

File: contracts/libraries/MetaTxLib.sol

1: // SPDX-License-Identifier: MIT

1,

File: contracts/libraries/MigrationLib.sol

1: // SPDX-License-Identifier: MIT

1,

File: contracts/libraries/constants/Errors.sol

1: // SPDX-License-Identifier: MIT

1,

File: contracts/libraries/constants/Events.sol

1: // SPDX-License-Identifier: MIT

1,

File: contracts/libraries/constants/Typehash.sol

1: // SPDX-License-Identifier: MIT

1,

File: contracts/base/HubRestricted.sol

1: // SPDX-License-Identifier: MIT

1,

File: contracts/base/LensGovernable.sol

1: // SPDX-License-Identifier: MIT

1,

File: contracts/base/LensHubEventHooks.sol

1: // SPDX-License-Identifier: MIT

1,

File: contracts/base/LensHubStorage.sol

1: // SPDX-License-Identifier: MIT

1,

File: contracts/base/LensImplGetters.sol

1: // SPDX-License-Identifier: MIT

1,

File: contracts/base/LensProfiles.sol

1: // SPDX-License-Identifier: MIT

1,

File: contracts/base/upgradeability/FollowNFTProxy.sol

1: // SPDX-License-Identifier: MIT

1,

File: contracts/misc/LegacyCollectNFT.sol

1: // SPDX-License-Identifier: MIT

1,

File: contracts/misc/LensV2Migration.sol

1: // SPDX-License-Identifier: MIT

1,

File: contracts/misc/LensV2UpgradeContract.sol

1: // SPDX-License-Identifier: MIT

1,

File: contracts/misc/ModuleGlobals.sol

1: // SPDX-License-Identifier: MIT

1,

File: contracts/misc/ProfileCreationProxy.sol

1: // SPDX-License-Identifier: MIT

1,

File: contracts/misc/access/Governance.sol

1: // SPDX-License-Identifier: MIT

1,

File: contracts/misc/access/ProxyAdmin.sol

1: // SPDX-License-Identifier: MIT

1,

File: contracts/namespaces/LensHandles.sol

1: // SPDX-License-Identifier: MIT

1,

File: contracts/namespaces/TokenHandleRegistry.sol

1: // SPDX-License-Identifier: MIT

1,

File: contracts/namespaces/constants/Errors.sol

1: // SPDX-License-Identifier: MIT

1,

File: contracts/namespaces/constants/Events.sol

1: // SPDX-License-Identifier: MIT

1,

File: contracts/interfaces/ICollectModule.sol

1: // SPDX-License-Identifier: MIT

1,

File: contracts/interfaces/ICollectNFT.sol

1: // SPDX-License-Identifier: MIT

1,

File: contracts/interfaces/IFollowModule.sol

1: // SPDX-License-Identifier: MIT

1,

File: contracts/interfaces/IFollowNFT.sol

1: // SPDX-License-Identifier: MIT

1,

File: contracts/interfaces/ILegacyCollectModule.sol

1: // SPDX-License-Identifier: MIT

1,

File: contracts/interfaces/ILegacyCollectNFT.sol

1: // SPDX-License-Identifier: MIT

1,

File: contracts/interfaces/ILegacyFollowModule.sol

1: // SPDX-License-Identifier: MIT

1,

File: contracts/interfaces/ILegacyReferenceModule.sol

1: // SPDX-License-Identifier: MIT

1,

File: contracts/interfaces/ILensHandles.sol

1: // SPDX-License-Identifier: MIT

1,

File: contracts/interfaces/ILensHub.sol

1: // SPDX-License-Identifier: MIT

1,

File: contracts/interfaces/ILensHubInitializable.sol

1: // SPDX-License-Identifier: MIT

1,

File: contracts/interfaces/IModuleGlobals.sol

1: // SPDX-License-Identifier: MIT

1,

File: contracts/interfaces/IPublicationActionModule.sol

1: // SPDX-License-Identifier: MIT

1,

File: contracts/interfaces/IReferenceModule.sol

1: // SPDX-License-Identifier: MIT

1,

File: contracts/interfaces/ITokenHandleRegistry.sol

1: // SPDX-License-Identifier: MIT

1,

[N-47] Unused parameter

possible for issue

Instances (16):

see instances
File: contracts/libraries/PublicationLib.sol

/// @audit quoteParams not used
203:     function _asReferencePubParams(Types.QuoteParams calldata quoteParams)
204:             private
205:             pure
206:             returns (Types.ReferencePubParams calldata referencePubParams)
207:         {

/// @audit commentParams not used
214:     function _asReferencePubParams(Types.CommentParams calldata commentParams)
215:             private
216:             pure
217:             returns (Types.ReferencePubParams calldata referencePubParams)
218:         {

203, 214,

File: contracts/libraries/StorageLib.sol

/// @audit profileId not used
49:     function getPublication(uint256 profileId, uint256 pubId)
50:            internal
51:            pure
52:            returns (Types.Publication storage _publication)
53:        {

/// @audit pubId not used
49:     function getPublication(uint256 profileId, uint256 pubId)
50:            internal
51:            pure
52:            returns (Types.Publication storage _publication)
53:        {

/// @audit profileId not used
63:     function getProfile(uint256 profileId) internal pure returns (Types.Profile storage _profiles) {

/// @audit delegatorProfileId not used
71:     function getDelegatedExecutorsConfig(uint256 delegatorProfileId)
72:            internal
73:            pure
74:            returns (Types.DelegatedExecutorsConfig storage _delegatedExecutorsConfig)
75:        {

/// @audit tokenId not used
93:     function getTokenData(uint256 tokenId) internal pure returns (Types.TokenData storage _tokenData) {

/// @audit blockerProfileId not used
101:     function blockedStatus(uint256 blockerProfileId)
102:             internal
103:             pure
104:             returns (mapping(uint256 => bool) storage _blockedStatus)
105:         {

/// @audit newGovernance not used
193:     function setGovernance(address newGovernance) internal {

/// @audit newEmergencyAdmin not used
205:     function setEmergencyAdmin(address newEmergencyAdmin) internal {

/// @audit newState not used
217:     function setState(Types.ProtocolState newState) internal {

/// @audit newLastInitializedRevision not used
229:     function setLastInitializedRevision(uint256 newLastInitializedRevision) internal {

49, 49, 63, 71, 93, 101, 193, 205, 217, 229,

File: contracts/base/ERC2981CollectionRoyalties.sol

/// @audit royaltiesInBasisPoints not used
58:     function _storeRoyaltiesInBasisPoints(uint256 royaltiesInBasisPoints) internal virtual {

58,

File: contracts/base/LensBaseERC721.sol

/// @audit from not used
506:     function _beforeTokenTransfer(
507:             address from,
508:             address to,
509:             uint256 tokenId
510:         ) internal virtual {}

/// @audit to not used
506:     function _beforeTokenTransfer(
507:             address from,
508:             address to,
509:             uint256 tokenId
510:         ) internal virtual {}

/// @audit tokenId not used
506:     function _beforeTokenTransfer(
507:             address from,
508:             address to,
509:             uint256 tokenId
510:         ) internal virtual {}

506, 506, 506,

[N-48] Unused structs

If these serve no purpose, they should be safely removed

Instances (14):

see instances
File: contracts/libraries/constants/Types.sol

21:     struct TokenData {
22:            address owner;
23:            uint96 mintTimestamp;
24:        }

34:     struct FollowData {
35:            uint160 followerProfileId;
36:            uint48 originalFollowTimestamp;
37:            uint48 followTimestamp;
38:            uint256 profileIdAllowedToRecover;
39:        }

82:     struct EIP712Signature {
83:            address signer;
84:            uint8 v;
85:            bytes32 r;
86:            bytes32 s;
87:            uint256 deadline;
88:        }

161:     struct CreateProfileParams {
162:             address to;
163:             string imageURI;
164:             address followModule;
165:             bytes followModuleInitData;
166:         }

178:     struct PostParams {
179:             uint256 profileId;
180:             string contentURI;
181:             address[] actionModules;
182:             bytes[] actionModulesInitDatas;
183:             address referenceModule;
184:             bytes referenceModuleInitData;
185:         }

260:     struct ReferencePubParams {
261:             uint256 profileId;
262:             string contentURI;
263:             uint256 pointedProfileId;
264:             uint256 pointedPubId;
265:             uint256[] referrerProfileIds;
266:             uint256[] referrerPubIds;
267:             bytes referenceModuleData;
268:             address[] actionModules;
269:             bytes[] actionModulesInitDatas;
270:             address referenceModule;
271:             bytes referenceModuleInitData;
272:         }

323:     struct PublicationActionParams {
324:             uint256 publicationActedProfileId;
325:             uint256 publicationActedId;
326:             uint256 actorProfileId;
327:             uint256[] referrerProfileIds;
328:             uint256[] referrerPubIds;
329:             address actionModuleAddress;
330:             bytes actionModuleData;
331:         }

333:     struct ProcessActionParams {
334:             uint256 publicationActedProfileId;
335:             uint256 publicationActedId;
336:             uint256 actorProfileId;
337:             address actorProfileOwner;
338:             address transactionExecutor;
339:             uint256[] referrerProfileIds;
340:             uint256[] referrerPubIds;
341:             Types.PublicationType[] referrerPubTypes;
342:             bytes actionModuleData;
343:         }

346:     struct ProcessCollectParams {
347:             uint256 publicationCollectedProfileId;
348:             uint256 publicationCollectedId;
349:             uint256 collectorProfileId;
350:             address collectorProfileOwner;
351:             address transactionExecutor;
352:             uint256[] referrerProfileIds;
353:             uint256[] referrerPubIds;
354:             Types.PublicationType[] referrerPubTypes;
355:             bytes data;
356:         }

358:     struct ProcessCommentParams {
359:             uint256 profileId;
360:             address transactionExecutor;
361:             uint256 pointedProfileId;
362:             uint256 pointedPubId;
363:             uint256[] referrerProfileIds;
364:             uint256[] referrerPubIds;
365:             Types.PublicationType[] referrerPubTypes;
366:             bytes data;
367:         }

369:     struct ProcessQuoteParams {
370:             uint256 profileId;
371:             address transactionExecutor;
372:             uint256 pointedProfileId;
373:             uint256 pointedPubId;
374:             uint256[] referrerProfileIds;
375:             uint256[] referrerPubIds;
376:             Types.PublicationType[] referrerPubTypes;
377:             bytes data;
378:         }

380:     struct ProcessMirrorParams {
381:             uint256 profileId;
382:             address transactionExecutor;
383:             uint256 pointedProfileId;
384:             uint256 pointedPubId;
385:             uint256[] referrerProfileIds;
386:             uint256[] referrerPubIds;
387:             Types.PublicationType[] referrerPubTypes;
388:             bytes data;
389:         }

399:     struct DelegatedExecutorsConfig {
400:             mapping(uint256 => mapping(address => bool)) isApproved; // isApproved[configNumber][delegatedExecutor]
401:             uint64 configNumber;
402:             uint64 prevConfigNumber;
403:             uint64 maxConfigNumberSet;
404:         }

406:     struct ActionModuleWhitelistData {
407:             uint248 id;
408:             bool isWhitelisted;
409:         }

21, 34, 82, 161, 178, 260, 323, 333, 346, 358, 369, 380, 399, 406,

[N-49] Use abi.encodeCall() instead of abi.encodeSignature()/abi.encodeSelector()

abi.encodeCall() has compiler type safety, whereas the other two functions do not

Instances (1):

File: contracts/libraries/FollowLib.sol

91:         bytes memory functionData = abi.encodeWithSelector(IFollowNFT.initialize.selector, profileId);

91,

[N-50] Use bytes.concat() on bytes instead of abi.encodePacked() for clearer semantic

Starting with version 0.8.4, Solidity has the bytes.concat() function, which allows one to concatenate a list of bytes/strings, without extra padding. Using this function rather than abi.encodePacked() makes the intended operation more clear, leading to less reviewer confusion.

Instances (13):

see instances
File: contracts/FollowNFT.sol

275:         return string(abi.encodePacked(_followedProfileId.toString(), FOLLOW_NFT_NAME_SUFFIX));

279:         return string(abi.encodePacked(_followedProfileId.toString(), FOLLOW_NFT_SYMBOL_SUFFIX));

275, 279,

File: contracts/libraries/MetaTxLib.sol

103:                         abi.encodePacked(delegatedExecutors),

104:                         abi.encodePacked(approvals),

169:         return keccak256(abi.encodePacked(actionModulesInitDatasHashes));

345:                         keccak256(abi.encodePacked(idsOfProfilesToFollow)),

346:                         keccak256(abi.encodePacked(followTokenIds)),

347:                         keccak256(abi.encodePacked(dataHashes)),

368:                         keccak256(abi.encodePacked(idsOfProfilesToUnfollow)),

390:                         keccak256(abi.encodePacked(idsOfProfilesToSetBlockStatus)),

391:                         keccak256(abi.encodePacked(blockStatus)),

473:             bytes memory concatenatedSig = abi.encodePacked(signature.r, signature.s, signature.v);

493:         return keccak256(abi.encodePacked('\x19\x01', calculateDomainSeparator(), hashedMessage));

103, 104, 169, 345, 346, 347, 368, 390, 391, 473, 493,

[N-51] Constants should be defined rather than using magic numbers

Even assemblycan benefit from using readable constants instead of hex/numeric literals

Instances (2):

File: contracts/FollowNFT.sol

/// @audit 1000
55:         _setRoyalty(1000); // 10% of royalties

55,

File: contracts/misc/LegacyCollectNFT.sol

/// @audit 1000
48:         _setRoyalty(1000); // 10% of royalties

48,

[N-52] Non-library/interface files should use fixed compiler versions, not floating ones

Instances (22):

see instances
File: contracts/LensHub.sol

3: pragma solidity ^0.8.15;

3,

File: contracts/FollowNFT.sol

3: pragma solidity ^0.8.15;

3,

File: contracts/base/ERC2981CollectionRoyalties.sol

3: pragma solidity ^0.8.0;

3,

File: contracts/base/HubRestricted.sol

3: pragma solidity ^0.8.15;

3,

File: contracts/base/LensBaseERC721.sol

3: pragma solidity ^0.8.0;

3,

File: contracts/base/LensGovernable.sol

3: pragma solidity ^0.8.15;

3,

File: contracts/base/LensHubEventHooks.sol

3: pragma solidity ^0.8.15;

3,

File: contracts/base/LensHubStorage.sol

3: pragma solidity ^0.8.18;

3,

File: contracts/base/LensImplGetters.sol

3: pragma solidity ^0.8.15;

3,

File: contracts/base/LensProfiles.sol

3: pragma solidity ^0.8.15;

3,

File: contracts/base/upgradeability/FollowNFTProxy.sol

3: pragma solidity ^0.8.15;

3,

File: contracts/misc/ImmutableOwnable.sol

3: pragma solidity ^0.8.15;

3,

File: contracts/misc/LegacyCollectNFT.sol

3: pragma solidity ^0.8.15;

3,

File: contracts/misc/LensV2Migration.sol

3: pragma solidity ^0.8.15;

3,

File: contracts/misc/LensV2UpgradeContract.sol

3: pragma solidity ^0.8.19;

3,

File: contracts/misc/ModuleGlobals.sol

3: pragma solidity ^0.8.15;

3,

File: contracts/misc/ProfileCreationProxy.sol

3: pragma solidity ^0.8.15;

3,

File: contracts/misc/access/ControllableByContract.sol

3: pragma solidity ^0.8.15;

3,

File: contracts/misc/access/Governance.sol

3: pragma solidity ^0.8.15;

3,

File: contracts/misc/access/ProxyAdmin.sol

3: pragma solidity ^0.8.15;

3,

File: contracts/namespaces/LensHandles.sol

3: pragma solidity ^0.8.18;

3,

File: contracts/namespaces/TokenHandleRegistry.sol

3: pragma solidity ^0.8.18;

3,

[N-53] Expressions for constant values such as a call to keccak256(), should use immutable rather than constant

While it doesn't save any gas because the compiler knows that developers often make this mistake, it's still best to use theright tool for the task at hand. There is a difference between constant variables and immutable variables, and they shouldeach be used in their appropriate contexts. constants should be used for literal values written into the code, and immutablevariables should be used for expressions, or values calculated in, or passed into the constructor.

Instances (17):

see instances
File: contracts/libraries/MetaTxLib.sol

22:     bytes32 constant EIP712_DOMAIN_VERSION_HASH = keccak256(bytes(EIP712_DOMAIN_VERSION));

22,

File: contracts/libraries/constants/Typehash.sol

7:     bytes32 constant ACT = keccak256('Act(uint256 publicationActedProfileId,uint256 publicationActedId,uint256 actorProfileId,uint256[] referrerProfileIds,uint256[] referrerPubIds,address actionModuleAddress,bytes actionModuleData,uint256 nonce,uint256 deadline)');

9:     bytes32 constant BURN = keccak256('Burn(uint256 tokenId,uint256 nonce,uint256 deadline)');

11:     bytes32 constant CHANGE_DELEGATED_EXECUTORS_CONFIG = keccak256('ChangeDelegatedExecutorsConfig(uint256 delegatorProfileId,address[] delegatedExecutors,bool[] approvals,uint64 configNumber,bool switchToGivenConfig,uint256 nonce,uint256 deadline)');

13:     bytes32 constant LEGACY_COLLECT = keccak256('Collect(uint256 publicationCollectedProfileId,uint256 publicationCollectedId,uint256 collectorProfileId,uint256 referrerProfileId,uint256 referrerPubId,bytes collectModuleData,uint256 nonce,uint256 deadline)');

15:     bytes32 constant COMMENT = keccak256('Comment(uint256 profileId,string contentURI,uint256 pointedProfileId,uint256 pointedPubId,uint256[] referrerProfileIds,uint256[] referrerPubIds,bytes referenceModuleData,address collectModule,bytes collectModuleInitData,address referenceModule,bytes referenceModuleInitData,uint256 nonce,uint256 deadline)');

17:     bytes32 constant EIP712_DOMAIN = keccak256('EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)');

19:     bytes32 constant FOLLOW = keccak256('Follow(uint256 followerProfileId,uint256[] idsOfProfilesToFollow,uint256[] followTokenIds,bytes[] datas,uint256 nonce,uint256 deadline)');

21:     bytes32 constant MIRROR = keccak256('Mirror(uint256 profileId,uint256 pointedProfileId,uint256 pointedPubId,uint256[] referrerProfileId,uint256[] referrerPubId,bytes referenceModuleData,uint256 nonce,uint256 deadline)');

23:     bytes32 constant POST = keccak256('Post(uint256 profileId,string contentURI,address collectModule,bytes collectModuleInitData,address referenceModule,bytes referenceModuleInitData,uint256 nonce,uint256 deadline)');

25:     bytes32 constant QUOTE = keccak256('Quote(uint256 profileId,string contentURI,uint256 pointedProfileId,uint256 pointedPubId,uint256[] referrerProfileIds,uint256[] referrerPubIds,bytes referenceModuleData,address collectModule,bytes collectModuleInitData,address referenceModule,bytes referenceModuleInitData,uint256 nonce,uint256 deadline)');

27:     bytes32 constant SET_BLOCK_STATUS = keccak256('SetBlockStatus(uint256 byProfileId,uint256[] idsOfProfilesToSetBlockStatus,bool[] blockStatus,uint256 nonce,uint256 deadline)');

29:     bytes32 constant SET_FOLLOW_MODULE = keccak256('SetFollowModule(uint256 profileId,address followModule,bytes followModuleInitData,uint256 nonce,uint256 deadline)');

31:     bytes32 constant SET_PROFILE_IMAGE_URI = keccak256('SetProfileImageURI(uint256 profileId,string imageURI,uint256 nonce,uint256 deadline)');

33:     bytes32 constant SET_PROFILE_METADATA_URI = keccak256('SetProfileMetadataURI(uint256 profileId,string metadata,uint256 nonce,uint256 deadline)');

35:     bytes32 constant UNFOLLOW = keccak256('Unfollow(uint256 unfollowerProfileId,uint256[] idsOfProfilesToUnfollow,uint256 nonce,uint256 deadline)');

7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35,

File: contracts/namespaces/LensHandles.sol

32:     bytes32 internal constant NAMESPACE_HASH = keccak256(bytes(NAMESPACE));

32,

[N-54] Functions not used internally could be marked external

Instances (17):

see instances
File: contracts/FollowNFT.sol

255:     function burn(uint256 followTokenId) public override {

274:     function name() public view override returns (string memory) {

278:     function symbol() public view override returns (string memory) {

285:     function tokenURI(uint256 followTokenId) public view override returns (string memory) {

255, 274, 278, 285,

File: contracts/base/LensBaseERC721.sol

94:     function nonces(address signer) public view override returns (uint256) {

94,

File: contracts/base/LensProfiles.sol

93:     function burn(uint256 tokenId)

105:     function tokenURI(uint256 tokenId) public view override(LensBaseERC721, IERC721Metadata) returns (string memory) {

112:     function approve(address to, uint256 tokenId) public override(LensBaseERC721, IERC721) {

120:     function setApprovalForAll(address operator, bool approved) public override(LensBaseERC721, IERC721) {

93, 105, 112, 120,

File: contracts/misc/LegacyCollectNFT.sol

69:     function tokenURI(uint256 tokenId) public view override returns (string memory) {

77:     function name() public view override returns (string memory) {

84:     function symbol() public pure override returns (string memory) {

69, 77, 84,

File: contracts/namespaces/LensHandles.sol

70:     function name() public pure override returns (string memory) {

81:     function tokenURI(uint256 tokenId) public view override returns (string memory) {

139:     function approve(address to, uint256 tokenId) public override(IERC721, ERC721) {

147:     function setApprovalForAll(address operator, bool approved) public override(IERC721, ERC721) {

177:     function getHandle(uint256 tokenId) public view returns (string memory) {

70, 81, 139, 147, 177,

[N-55] Use a more recent version of solidity

Use a solidity version of at least 0.8.13 to get the ability to use using for with a list of free functions In 0.8.15 the conditions necessary for inlining are relaxed. Benchmarks show that the change significantly decreases the bytecode size (which impacts the deployment cost) while the effect on the runtime gas usage is smaller.In 0.8.17 prevent the incorrect removal of storage writes before calls to Yul functions that conditionally terminate the external EVM call; Simplify the starting offset of zero-length operations to zero. More efficient overflow checks for multiplication.

Instances (2):

File: contracts/base/ERC2981CollectionRoyalties.sol

3: pragma solidity ^0.8.0;

3,

File: contracts/base/LensBaseERC721.sol

3: pragma solidity ^0.8.0;

3,

[N-56] Use named function calls

Code base has an extensive use of named function calls, but it somehow missed one instance where this would be appropriate. It should use named function calls on function call, as such:

library.exampleFunction{value: _data.amount.value}({
    _id: _data.id,
    _amount: _data.amount.value,
    _token: _data.token,
    _example: "",    _metadata: _data.metadata
});

Instances (1):

File: contracts/misc/access/Governance.sol

82:         (bool success, bytes memory returnData) = target.call{gas: gasleft(), value: msg.value}(data);

82,

[N-57] Critical Changes Should Use Two-step Procedure

The critical procedures should be two step process. See similar findings in previous Code4rena contests for reference:code4rena.com illuminate-report

Instances (18):

see instances
File: contracts/libraries/GovernanceLib.sol

16:     function setGovernance(address newGovernance) external {

27:     function setEmergencyAdmin(address newEmergencyAdmin) external {

16, 27,

File: contracts/libraries/StorageLib.sol

193:     function setGovernance(address newGovernance) internal {

205:     function setEmergencyAdmin(address newEmergencyAdmin) internal {

229:     function setLastInitializedRevision(uint256 newLastInitializedRevision) internal {

193, 205, 229,

File: contracts/base/ERC2981CollectionRoyalties.sol

26:     function setRoyalty(uint256 royaltiesInBasisPoints) external {

43:     function _setRoyalty(uint256 royaltiesInBasisPoints) internal virtual {

26, 43,

File: contracts/base/LensGovernable.sol

25:     function setGovernance(address newGovernance) external override onlyGov {

30:     function setEmergencyAdmin(address newEmergencyAdmin) external override onlyGov {

25, 30,

File: contracts/misc/ModuleGlobals.sol

50:     function setGovernance(address newGovernance) external override onlyGov {

55:     function setTreasury(address newTreasury) external override onlyGov {

60:     function setTreasuryFee(uint16 newTreasuryFee) external override onlyGov {

94:     function _setGovernance(address newGovernance) internal {

101:     function _setTreasury(address newTreasury) internal {

108:     function _setTreasuryFee(uint16 newTreasuryFee) internal {

50, 55, 60, 94, 101, 108,

File: contracts/misc/access/ControllableByContract.sol

30:     function setControllerContract(address newControllerContract) external onlyOwner {

30,

File: contracts/misc/access/Governance.sol

23:     function lensHub_setGovernance(address newGovernance) external onlyOwner {

27:     function lensHub_setEmergencyAdmin(address newEmergencyAdmin) external onlyOwner {

23, 27,

[N-58] Large numeric literals should use underscores for readability

Instances (2):

File: contracts/base/ERC2981CollectionRoyalties.sol

10:     uint16 internal constant BASIS_POINTS = 10000;

10,

File: contracts/misc/ModuleGlobals.sol

20:     uint16 internal constant BPS_MAX = 10000;

20,

[N-59] Using underscore at the end of variable name

The use of underscore at the end of the variable name is uncommon and also suggests that the variable name was not completely changed. Consider refactoring variableName_ to variableName.

Instances (13):

see instances
File: contracts/base/LensBaseERC721.sol

71:     function _initialize(string calldata name_, string calldata symbol_) internal {

71:     function _initialize(string calldata name_, string calldata symbol_) internal {

71, 71,

File: contracts/misc/LensV2UpgradeContract.sol

26:         address[] memory oldFollowModulesToUnwhitelist_,

27:         address[] memory newFollowModulesToWhitelist_,

28:         address[] memory oldReferenceModulesToUnwhitelist_,

29:         address[] memory newReferenceModulesToWhitelist_,

30:         address[] memory oldCollectModulesToUnwhitelist_,

31:         address[] memory newActionModulesToWhitelist_

26, 27, 28, 29, 30, 31,

File: contracts/misc/access/Governance.sol

15:     constructor(address lensHubAddress_, address governanceOwner_) ControllableByContract(governanceOwner_) {

15:     constructor(address lensHubAddress_, address governanceOwner_) ControllableByContract(governanceOwner_) {

15, 15,

File: contracts/misc/access/ProxyAdmin.sol

13:         address lensHubAddress_,

14:         address previousImplementation_,

15:         address proxyAdminOwner_

13, 14, 15,

[N-60] Consider implementing two-step procedure for updating protocol addresses

A copy-paste error or a typo may end up bricking protocol functionality, or sending tokens to an address with no known private key. Consider implementing a two-step procedure for updating protocol addresses, where the recipient is set as pending, and must 'accept' the assignment by making an affirmative call. A straight forward way of doing this would be to have the target contracts implement EIP-165, and to have the 'set' functions ensure that the recipient is of the right interface type.

Instances (7):

File: contracts/base/LensGovernable.sol

25:     function setGovernance(address newGovernance) external override onlyGov {
26:            GovernanceLib.setGovernance(newGovernance);
27:        }

30:     function setEmergencyAdmin(address newEmergencyAdmin) external override onlyGov {
31:            GovernanceLib.setEmergencyAdmin(newEmergencyAdmin);
32:        }

25, 30,

File: contracts/misc/ModuleGlobals.sol

50:     function setGovernance(address newGovernance) external override onlyGov {
51:            _setGovernance(newGovernance);
52:        }

55:     function setTreasury(address newTreasury) external override onlyGov {
56:            _setTreasury(newTreasury);
57:        }

50, 55,

File: contracts/misc/access/ControllableByContract.sol

30:     function setControllerContract(address newControllerContract) external onlyOwner {
31:            emit ControllerContractUpdated(controllerContract, newControllerContract);
32:            controllerContract = newControllerContract;
33:        }

30,

File: contracts/misc/access/Governance.sol

23:     function lensHub_setGovernance(address newGovernance) external onlyOwner {
24:            LENS_HUB.setGovernance(newGovernance);
25:        }

27:     function lensHub_setEmergencyAdmin(address newEmergencyAdmin) external onlyOwner {
28:            LENS_HUB.setEmergencyAdmin(newEmergencyAdmin);
29:        }

23, 27,

[N-61] Do not calculate constants

Due to how constant variables are implemented (replacements at compile-time), an expression assigned to a constant variable is recomputed each time that the variable is used, which wastes some gas.

Instances (17):

see instances
File: contracts/libraries/MetaTxLib.sol

22:     bytes32 constant EIP712_DOMAIN_VERSION_HASH = keccak256(bytes(EIP712_DOMAIN_VERSION));

22,

File: contracts/libraries/constants/Typehash.sol

7:     bytes32 constant ACT = keccak256('Act(uint256 publicationActedProfileId,uint256 publicationActedId,uint256 actorProfileId,uint256[] referrerProfileIds,uint256[] referrerPubIds,address actionModuleAddress,bytes actionModuleData,uint256 nonce,uint256 deadline)');

9:     bytes32 constant BURN = keccak256('Burn(uint256 tokenId,uint256 nonce,uint256 deadline)');

11:     bytes32 constant CHANGE_DELEGATED_EXECUTORS_CONFIG = keccak256('ChangeDelegatedExecutorsConfig(uint256 delegatorProfileId,address[] delegatedExecutors,bool[] approvals,uint64 configNumber,bool switchToGivenConfig,uint256 nonce,uint256 deadline)');

13:     bytes32 constant LEGACY_COLLECT = keccak256('Collect(uint256 publicationCollectedProfileId,uint256 publicationCollectedId,uint256 collectorProfileId,uint256 referrerProfileId,uint256 referrerPubId,bytes collectModuleData,uint256 nonce,uint256 deadline)');

15:     bytes32 constant COMMENT = keccak256('Comment(uint256 profileId,string contentURI,uint256 pointedProfileId,uint256 pointedPubId,uint256[] referrerProfileIds,uint256[] referrerPubIds,bytes referenceModuleData,address collectModule,bytes collectModuleInitData,address referenceModule,bytes referenceModuleInitData,uint256 nonce,uint256 deadline)');

17:     bytes32 constant EIP712_DOMAIN = keccak256('EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)');

19:     bytes32 constant FOLLOW = keccak256('Follow(uint256 followerProfileId,uint256[] idsOfProfilesToFollow,uint256[] followTokenIds,bytes[] datas,uint256 nonce,uint256 deadline)');

21:     bytes32 constant MIRROR = keccak256('Mirror(uint256 profileId,uint256 pointedProfileId,uint256 pointedPubId,uint256[] referrerProfileId,uint256[] referrerPubId,bytes referenceModuleData,uint256 nonce,uint256 deadline)');

23:     bytes32 constant POST = keccak256('Post(uint256 profileId,string contentURI,address collectModule,bytes collectModuleInitData,address referenceModule,bytes referenceModuleInitData,uint256 nonce,uint256 deadline)');

25:     bytes32 constant QUOTE = keccak256('Quote(uint256 profileId,string contentURI,uint256 pointedProfileId,uint256 pointedPubId,uint256[] referrerProfileIds,uint256[] referrerPubIds,bytes referenceModuleData,address collectModule,bytes collectModuleInitData,address referenceModule,bytes referenceModuleInitData,uint256 nonce,uint256 deadline)');

27:     bytes32 constant SET_BLOCK_STATUS = keccak256('SetBlockStatus(uint256 byProfileId,uint256[] idsOfProfilesToSetBlockStatus,bool[] blockStatus,uint256 nonce,uint256 deadline)');

29:     bytes32 constant SET_FOLLOW_MODULE = keccak256('SetFollowModule(uint256 profileId,address followModule,bytes followModuleInitData,uint256 nonce,uint256 deadline)');

31:     bytes32 constant SET_PROFILE_IMAGE_URI = keccak256('SetProfileImageURI(uint256 profileId,string imageURI,uint256 nonce,uint256 deadline)');

33:     bytes32 constant SET_PROFILE_METADATA_URI = keccak256('SetProfileMetadataURI(uint256 profileId,string metadata,uint256 nonce,uint256 deadline)');

35:     bytes32 constant UNFOLLOW = keccak256('Unfollow(uint256 unfollowerProfileId,uint256[] idsOfProfilesToUnfollow,uint256 nonce,uint256 deadline)');

7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35,

File: contracts/namespaces/LensHandles.sol

32:     bytes32 internal constant NAMESPACE_HASH = keccak256(bytes(NAMESPACE));

32,

[N-62] Public functions not used internally can be marked as external to save gas

public functions that aren't used internally in Solidity contracts should be made external to optimize gas usage and improve contract efficiency. external functions can only be called from outside the contract, and their arguments are directly read from the calldata, which is more gas-efficient than loading them into memory, as is the case for public functions. By using external visibility, developers can reduce gas consumption for external calls and ensure that the contract operates more cost-effectively for users. Moreover, setting the appropriate visibility level for functions also enhances code readability and maintainability, promoting a more secure and well-structured contract design.

Instances (2):

File: contracts/base/ERC2981CollectionRoyalties.sol

17:     function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {

17,

File: contracts/namespaces/LensHandles.sol

177:     function getHandle(uint256 tokenId) public view returns (string memory) {

177,

[N-63] Use assembly to calculate hashes to save gas

Use assembly to calculate hashes to save gas

Instances (43):

see instances
File: contracts/libraries/MetaTxLib.sol

50:                 keccak256(

54:                         keccak256(bytes(metadataURI)),

72:                 keccak256(

77:                         keccak256(followModuleInitData),

99:                 keccak256(

123:                 keccak256(

127:                         keccak256(bytes(imageURI)),

142:                 keccak256(

146:                         keccak256(bytes(postParams.contentURI)),

150:                         keccak256(postParams.referenceModuleInitData),

164:             actionModulesInitDatasHashes[i] = keccak256(abi.encode(actionModulesInitDatas[i]));

169:         return keccak256(abi.encodePacked(actionModulesInitDatasHashes));

229:         bytes32 contentURIHash = keccak256(bytes(commentParams.contentURI));

230:         bytes32 referenceModuleDataHash = keccak256(commentParams.referenceModuleData);

232:         bytes32 referenceModuleInitDataHash = keccak256(commentParams.referenceModuleInitData);

253:         _validateRecoveredAddress(_calculateDigest(keccak256(encodedAbi)), signature);

259:         bytes32 contentURIHash = keccak256(bytes(quoteParams.contentURI));

260:         bytes32 referenceModuleDataHash = keccak256(quoteParams.referenceModuleData);

262:         bytes32 referenceModuleInitDataHash = keccak256(quoteParams.referenceModuleInitData);

283:         _validateRecoveredAddress(_calculateDigest(keccak256(encodedAbi)), signature);

291:                 keccak256(

299:                         keccak256(mirrorParams.referenceModuleData),

312:                 keccak256(

331:             dataHashes[i] = keccak256(datas[i]);

341:                 keccak256(

345:                         keccak256(abi.encodePacked(idsOfProfilesToFollow)),

346:                         keccak256(abi.encodePacked(followTokenIds)),

347:                         keccak256(abi.encodePacked(dataHashes)),

364:                 keccak256(

368:                         keccak256(abi.encodePacked(idsOfProfilesToUnfollow)),

386:                 keccak256(

390:                         keccak256(abi.encodePacked(idsOfProfilesToSetBlockStatus)),

391:                         keccak256(abi.encodePacked(blockStatus)),

407:                 keccak256(

415:                         keccak256(collectParams.collectModuleData),

431:                 keccak256(

440:                         keccak256(publicationActionParams.actionModuleData),

455:             keccak256(

458:                     keccak256(bytes(ILensERC721(address(this)).name())),

493:         return keccak256(abi.encodePacked('\x19\x01', calculateDomainSeparator(), hashedMessage));

50, 54, 72, 77, 99, 123, 127, 142, 146, 150, 164, 169, 229, 230, 232, 253, 259, 260, 262, 283, 291, 299, 312, 331, 341, 345, 346, 347, 364, 368, 386, 390, 391, 407, 415, 431, 440, 455, 458, 493,

File: contracts/namespaces/LensHandles.sol

183:         return uint256(keccak256(bytes(localName)));

183,

File: contracts/namespaces/TokenHandleRegistry.sol

168:         return keccak256(abi.encode(handle.collection, handle.id));

172:         return keccak256(abi.encode(token.collection, token.id));

168, 172,

[N-64] bytes.concat() can be used instead of abi.encodePacked

Given concatenation is not going to be used for hashing bytes.concat is the preferred method to use as its more gas efficient

Instances (13):

see instances
File: contracts/FollowNFT.sol

275:         return string(abi.encodePacked(_followedProfileId.toString(), FOLLOW_NFT_NAME_SUFFIX));

279:         return string(abi.encodePacked(_followedProfileId.toString(), FOLLOW_NFT_SYMBOL_SUFFIX));

275, 279,

File: contracts/libraries/MetaTxLib.sol

103:                         abi.encodePacked(delegatedExecutors),

104:                         abi.encodePacked(approvals),

169:         return keccak256(abi.encodePacked(actionModulesInitDatasHashes));

345:                         keccak256(abi.encodePacked(idsOfProfilesToFollow)),

346:                         keccak256(abi.encodePacked(followTokenIds)),

347:                         keccak256(abi.encodePacked(dataHashes)),

368:                         keccak256(abi.encodePacked(idsOfProfilesToUnfollow)),

390:                         keccak256(abi.encodePacked(idsOfProfilesToSetBlockStatus)),

391:                         keccak256(abi.encodePacked(blockStatus)),

473:             bytes memory concatenatedSig = abi.encodePacked(signature.r, signature.s, signature.v);

493:         return keccak256(abi.encodePacked('\x19\x01', calculateDomainSeparator(), hashedMessage));

103, 104, 169, 345, 346, 347, 368, 390, 391, 473, 493,

[N-65] Reduce gas usage by moving to Solidity 0.8.19 or later

See this link for the full details

Instances (31):

see instances
File: contracts/LensHub.sol

3: pragma solidity ^0.8.15;

3,

File: contracts/FollowNFT.sol

3: pragma solidity ^0.8.15;

3,

File: contracts/libraries/ActionLib.sol

3: pragma solidity ^0.8.15;

3,

File: contracts/libraries/FollowLib.sol

3: pragma solidity ^0.8.15;

3,

File: contracts/libraries/GovernanceLib.sol

3: pragma solidity ^0.8.15;

3,

File: contracts/libraries/LegacyCollectLib.sol

3: pragma solidity ^0.8.15;

3,

File: contracts/libraries/MetaTxLib.sol

2: pragma solidity ^0.8.15;

2,

File: contracts/libraries/ProfileLib.sol

3: pragma solidity ^0.8.15;

3,

File: contracts/libraries/PublicationLib.sol

3: pragma solidity ^0.8.15;

3,

File: contracts/libraries/StorageLib.sol

3: pragma solidity ^0.8.15;

3,

File: contracts/libraries/ValidationLib.sol

3: pragma solidity ^0.8.15;

3,

File: contracts/base/ERC2981CollectionRoyalties.sol

3: pragma solidity ^0.8.0;

3,

File: contracts/base/HubRestricted.sol

3: pragma solidity ^0.8.15;

3,

File: contracts/base/LensBaseERC721.sol

3: pragma solidity ^0.8.0;

3,

File: contracts/base/LensGovernable.sol

3: pragma solidity ^0.8.15;

3,

File: contracts/base/LensHubEventHooks.sol

3: pragma solidity ^0.8.15;

3,

File: contracts/base/LensHubStorage.sol

3: pragma solidity ^0.8.18;

3,

File: contracts/base/LensImplGetters.sol

3: pragma solidity ^0.8.15;

3,

File: contracts/base/LensProfiles.sol

3: pragma solidity ^0.8.15;

3,

File: contracts/base/upgradeability/FollowNFTProxy.sol

3: pragma solidity ^0.8.15;

3,

File: contracts/misc/ImmutableOwnable.sol

3: pragma solidity ^0.8.15;

3,

File: contracts/misc/LegacyCollectNFT.sol

3: pragma solidity ^0.8.15;

3,

File: contracts/misc/LensV2Migration.sol

3: pragma solidity ^0.8.15;

3,

File: contracts/misc/ModuleGlobals.sol

3: pragma solidity ^0.8.15;

3,

File: contracts/misc/ProfileCreationProxy.sol

3: pragma solidity ^0.8.15;

3,

File: contracts/misc/access/ControllableByContract.sol

3: pragma solidity ^0.8.15;

3,

File: contracts/misc/access/Governance.sol

3: pragma solidity ^0.8.15;

3,

File: contracts/misc/access/ProxyAdmin.sol

3: pragma solidity ^0.8.15;

3,

File: contracts/namespaces/LensHandles.sol

3: pragma solidity ^0.8.18;

3,

File: contracts/namespaces/TokenHandleRegistry.sol

3: pragma solidity ^0.8.18;

3,

File: contracts/interfaces/ILegacyFollowModule.sol

3: pragma solidity ^0.8.15;

3,

@thebrittfactor
Copy link
Author

For transparency, the sponsor has responded via discord communication with the following in regards to the Medium findings in this bot report:

I've reviewed the bot-race report mentioned - and here are my thoughts:
M-03 is out of scope
M-06 might be considered
M-07 just points every unchecked keyword for manual checking
the rest is false

@thebrittfactor
Copy link
Author

The judge has responded via discord with the following in regards to the Medium findings in this bot report:

I agree that only M-06 could be valid, the rest are either invalid either have to many false positives.
M-03 is very generic on purpose to flag centralization risks and make them OOS for the contest.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment