Open code423n4 opened 2 years ago
Great report, well documented and valid! We choose to keep the follow NFT algorithms inlined because we're not pressed for code size, so the added gas would not be worth it.
The uint padding is technically valid but constants and immutables are not stored in storage, so I don't believe this makes sense here. Furthermore, the treasury fee uint16 variable is packed in the same slot as the treasury, which reduces the cold SLOADs when modules fetch the treasury data. Variable zero initialization is handled by the optimizer afaik.
Unchecked is valid, and the typehash is a good catch! Changes overall are included here: https://github.com/aave/lens-protocol/pull/80
LensHubStorage.CREATE_PROFILE_WITH_SIG_TYPEHASH is unused
https://github.com/code-423n4/2022-02-aave-lens/blob/aaf6c116345f3647e11a35010f28e3b90e7b4862/contracts/core/storage/LensHubStorage.sol#L8-L12
Duplicated code between
getPowerByBlockNumber()
andgetDelegatedSupplyByBlockNumber()
Save gas by not duplicating approximate binary search algorthm in
getPowerByBlockNumber()
andgetDelegatedSupplyByBlockNumber()
in deployed code. Instead refactor and use a common internal function https://github.com/code-423n4/2022-02-aave-lens/blob/aaf6c116345f3647e11a35010f28e3b90e7b4862/contracts/core/FollowNFT.sol#L114-L144 https://github.com/code-423n4/2022-02-aave-lens/blob/aaf6c116345f3647e11a35010f28e3b90e7b4862/contracts/core/FollowNFT.sol#L156-L186Duplicated code between
_writeSnapshot()
and_writeSupplySnapshot()
Save gas by not duplicating snapshot-for-block existence checks in
_writeSnapshot()
and_writeSupplySnapshot()
. Instead refactor and use a common internal function, renaming the orignals to_writeSnapshotSnapshot()
and_writeSnapshotSupplySnapshot()
https://github.com/code-423n4/2022-02-aave-lens/blob/aaf6c116345f3647e11a35010f28e3b90e7b4862/contracts/core/FollowNFT.sol#L287-L296 https://github.com/code-423n4/2022-02-aave-lens/blob/aaf6c116345f3647e11a35010f28e3b90e7b4862/contracts/core/FollowNFT.sol#L304-L313abi.encode()
is less efficient thanabi.encodePacked()
1.
https://github.com/code-423n4/2022-02-aave-lens/blob/main/contracts/core/modules/collect/TimedFeeCollectModule.sol#L90
2.
https://github.com/code-423n4/2022-02-aave-lens/blob/main/contracts/core/modules/collect/LimitedTimedFeeCollectModule.sol#L96
<array>.length
should not be looked up in every loop of a for-loopEven memory arrays incur the overhead of bit tests and bit shifts to calculate the array length 1.
https://github.com/code-423n4/2022-02-aave-lens/blob/main/contracts/libraries/InteractionLogic.sol#L47
2.
https://github.com/code-423n4/2022-02-aave-lens/blob/main/contracts/libraries/PublishingLogic.sol#L403
3.
https://github.com/code-423n4/2022-02-aave-lens/blob/main/contracts/core/LensHub.sol#L541
4.
https://github.com/code-423n4/2022-02-aave-lens/blob/main/contracts/core/modules/follow/ApprovalFollowModule.sol#L41
5.
https://github.com/code-423n4/2022-02-aave-lens/blob/main/contracts/core/modules/follow/ApprovalFollowModule.sol#L66
6.
https://github.com/code-423n4/2022-02-aave-lens/blob/main/contracts/core/modules/follow/ApprovalFollowModule.sol#L128
++i
/i++
should beunchecked{++i}
/unchecked{++i}
when it is not possible for them to overflow, as is the case when used in for- and while-loops1.
https://github.com/code-423n4/2022-02-aave-lens/blob/main/contracts/libraries/InteractionLogic.sol#L47
2.
https://github.com/code-423n4/2022-02-aave-lens/blob/main/contracts/libraries/PublishingLogic.sol#L403
3.
https://github.com/code-423n4/2022-02-aave-lens/blob/main/contracts/core/LensHub.sol#L541
4.
https://github.com/code-423n4/2022-02-aave-lens/blob/main/contracts/core/modules/follow/ApprovalFollowModule.sol#L41
5.
https://github.com/code-423n4/2022-02-aave-lens/blob/main/contracts/core/modules/follow/ApprovalFollowModule.sol#L66
6.
https://github.com/code-423n4/2022-02-aave-lens/blob/main/contracts/core/modules/follow/ApprovalFollowModule.sol#L128
It costs more gas to initialize variables to zero than to let the default of zero be applied
1.
https://github.com/code-423n4/2022-02-aave-lens/blob/main/contracts/libraries/InteractionLogic.sol#L47
2.
https://github.com/code-423n4/2022-02-aave-lens/blob/main/contracts/libraries/PublishingLogic.sol#L403
3.
https://github.com/code-423n4/2022-02-aave-lens/blob/main/contracts/core/LensHub.sol#L541
4.
https://github.com/code-423n4/2022-02-aave-lens/blob/main/contracts/core/modules/follow/ApprovalFollowModule.sol#L41
5.
https://github.com/code-423n4/2022-02-aave-lens/blob/main/contracts/core/modules/follow/ApprovalFollowModule.sol#L66
6.
https://github.com/code-423n4/2022-02-aave-lens/blob/main/contracts/core/modules/follow/ApprovalFollowModule.sol#L128
7.
https://github.com/code-423n4/2022-02-aave-lens/blob/main/contracts/upgradeability/VersionedInitializable.sol:29:
8.
https://github.com/code-423n4/2022-02-aave-lens/blob/main/contracts/core/FollowNFT.sol:120:
9.
https://github.com/code-423n4/2022-02-aave-lens/blob/main/contracts/core/FollowNFT.sol:162:
Storage of
uints
smaller than 32 bytes incur overheadhttps://docs.soliditylang.org/en/v0.8.11/internals/layout_in_storage.html Use a larger size then downcast where needed
https://github.com/code-423n4/2022-02-aave-lens/blob/main/contracts/libraries/Constants.sol#L10
https://github.com/code-423n4/2022-02-aave-lens/blob/main/contracts/core/modules/FeeModuleBase.sol#L17
https://github.com/code-423n4/2022-02-aave-lens/blob/main/contracts/core/modules/ModuleGlobals.sol#L20
https://github.com/code-423n4/2022-02-aave-lens/blob/main/contracts/core/modules/ModuleGlobals.sol#L25
https://github.com/code-423n4/2022-02-aave-lens/blob/main/contracts/core/modules/collect/TimedFeeCollectModule.sol#L48
https://github.com/code-423n4/2022-02-aave-lens/blob/main/contracts/core/modules/collect/LimitedTimedFeeCollectModule.sol#L48
Using
bool
s for storage incurs overheadhttps://github.com/OpenZeppelin/openzeppelin-contracts/blob/58f635312aa21f947cae5f8578638a85aa2519f5/contracts/security/ReentrancyGuard.sol#L23-L27
1.
https://github.com/code-423n4/2022-02-aave-lens/blob/main/contracts/libraries/PublishingLogic.sol#L44
2.
https://github.com/code-423n4/2022-02-aave-lens/blob/main/contracts/libraries/PublishingLogic.sol#L85
3.
https://github.com/code-423n4/2022-02-aave-lens/blob/main/contracts/libraries/PublishingLogic.sol#L132
4.
https://github.com/code-423n4/2022-02-aave-lens/blob/main/contracts/libraries/PublishingLogic.sol#L133
5.
https://github.com/code-423n4/2022-02-aave-lens/blob/main/contracts/libraries/PublishingLogic.sol#L188
6.
https://github.com/code-423n4/2022-02-aave-lens/blob/main/contracts/libraries/PublishingLogic.sol#L189
7.
https://github.com/code-423n4/2022-02-aave-lens/blob/main/contracts/libraries/PublishingLogic.sol#L256
8.
https://github.com/code-423n4/2022-02-aave-lens/blob/main/contracts/libraries/PublishingLogic.sol#L306
9.
https://github.com/code-423n4/2022-02-aave-lens/blob/main/contracts/libraries/PublishingLogic.sol#L325
10.
https://github.com/code-423n4/2022-02-aave-lens/blob/main/contracts/libraries/PublishingLogic.sol#L346
11.
https://github.com/code-423n4/2022-02-aave-lens/blob/main/contracts/core/base/ERC721Time.sol#L44
12.
https://github.com/code-423n4/2022-02-aave-lens/blob/main/contracts/core/FollowNFT.sol#L45
13.
https://github.com/code-423n4/2022-02-aave-lens/blob/main/contracts/core/CollectNFT.sol#L25
14.
https://github.com/code-423n4/2022-02-aave-lens/blob/main/contracts/core/storage/LensHubStorage.sol#L59
15.
https://github.com/code-423n4/2022-02-aave-lens/blob/main/contracts/core/storage/LensHubStorage.sol#L60
16.
https://github.com/code-423n4/2022-02-aave-lens/blob/main/contracts/core/storage/LensHubStorage.sol#L61
17.
https://github.com/code-423n4/2022-02-aave-lens/blob/main/contracts/core/storage/LensHubStorage.sol#L62
18
https://github.com/code-423n4/2022-02-aave-lens/blob/main/contracts/core/modules/ModuleGlobals.sol#L22