LUKSO - matrix_0wl's results

Provides creators and users with future-proof tools and standards to unleash their creative force in an open interoperable ecosystem.

General Information

Platform: Code4rena

Start Date: 30/06/2023

Pot Size: $100,000 USDC

Total HM: 8

Participants: 22

Period: 14 days

Judge: Trust

Total Solo HM: 6

Id: 253

League: ETH

LUKSO

Findings Distribution

Researcher Performance

Rank: 14/22

Findings: 2

Award: $93.68

QA:
grade-b
Gas:
grade-b

🌟 Selected for report: 0

🚀 Solo Findings: 0

Findings Information

🌟 Selected for report: gpersoon

Also found by: DavidGiladi, MiloTruck, Rolezn, banpaleo5, catellatech, matrix_0wl, naman1778, vnavascues

Labels

bug
grade-b
QA (Quality Assurance)
Q-07

Awards

60.1995 USDC - $60.20

External Links

Non Critical Issues

Issue
NC-1ADD A TIMELOCK TO CRITICAL FUNCTIONS
NC-2ADD TO BLACKLIST FUNCTION
NC-3GENERATE PERFECT CODE HEADERS EVERY TIME
NC-4COMMENTED CODE
NC-5INCONSISTENT SOLIDITY VERSIONS
NC-6IMPLEMENTATION CONTRACT MAY NOT BE INITIALIZED
NC-7MARK VISIBILITY OF INITIALIZE(…) FUNCTIONS AS EXTERNAL
NC-8DON’T WORRY ABOUT KECCAK256 COLLISIONS
NC-9LACK OF EVENT EMISSION AFTER CRITICAL INITIALIZE() FUNCTIONS
NC-10FOR EXTENDED “USING-FOR” USAGE, USE THE LATEST PRAGMA VERSION
NC-11Omissions in events
NC-12FOR FUNCTIONS AND VARIABLES FOLLOW SOLIDITY STANDARD NAMING CONVENTIONS
NC-13Functions not used internally could be marked external

[NC-1] ADD A TIMELOCK TO CRITICAL FUNCTIONS

Description:

It is a good practice to give time for users to react and adjust to critical changes. A timelock provides more guarantees and reduces the level of trust required, thus decreasing risk for users. It also indicates that the project is legitimate (less risk of a malicious owner making a sandwich attack on a user).

Proof Of Concept
File: /contracts/LSP0ERC725Account/LSP0ERC725AccountCore.sol

339:     function setData(

380:     function setDataBatch(

875:     function _setData(
File: /contracts/LSP4DigitalAssetMetadata/LSP4DigitalAssetMetadata.sol

52:     function _setData(
File: /contracts/LSP4DigitalAssetMetadata/LSP4DigitalAssetMetadataInitAbstract.sol

50:     function _setData(
File: /submodules/ERC725/implementations/contracts/ERC725YCore.sol

62:     function setData(

73:     function setDataBatch(

104:     function _setData(

[NC-2] ADD TO BLACKLIST FUNCTION

Description:

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 blacklist function.

Add to Blacklist function and modifier.

[NC-3] GENERATE PERFECT CODE HEADERS EVERY TIME

Description:

I recommend using header for Solidity code layout and readability: https://github.com/transmissions11/headers

/*//////////////////////////////////////////////////////////////
                           TESTING 123
//////////////////////////////////////////////////////////////*/

[NC-4] COMMENTED CODE

Proof Of Concept
File: /contracts/LSP2ERC725YJSONSchema/LSP2Utils.sol

38:             dataKey[dataKey.length - 2] == 0x5b && // "[" in utf8 encoded

39:                 dataKey[dataKey.length - 1] == 0x5d, // "]" in utf8

[NC-5] INCONSISTENT SOLIDITY VERSIONS

Description:

The project is compiled with different versions of Solidity, which is not recommended because it can lead to undefined behaviors.

It is better to use one Solidity compiler version across all contracts instead of different versions with different bugs and security checks.

Proof Of Concept
File: /contracts/LSP0ERC725Account/ILSP0ERC725Account.sol

2: pragma solidity ^0.8.4;
File: /contracts/LSP0ERC725Account/LSP0Constants.sol

2: pragma solidity ^0.8.4;
File: /contracts/LSP0ERC725Account/LSP0ERC725Account.sol

2: pragma solidity ^0.8.4;
File: /contracts/LSP0ERC725Account/LSP0ERC725AccountCore.sol

2: pragma solidity ^0.8.4;
File: /contracts/LSP0ERC725Account/LSP0ERC725AccountInit.sol

2: pragma solidity ^0.8.4;
File: /contracts/LSP0ERC725Account/LSP0ERC725AccountInitAbstract.sol

2: pragma solidity ^0.8.4;
File: /contracts/LSP0ERC725Account/LSP0Utils.sol

2: pragma solidity ^0.8.4;
File: /contracts/LSP14Ownable2Step/ILSP14Ownable2Step.sol

2: pragma solidity ^0.8.4;
File: /contracts/LSP14Ownable2Step/LSP14Constants.sol

2: pragma solidity ^0.8.4;
File: /contracts/LSP14Ownable2Step/LSP14Errors.sol

2: pragma solidity ^0.8.4;
File: /contracts/LSP14Ownable2Step/LSP14Ownable2Step.sol

2: pragma solidity ^0.8.4;
File: /contracts/LSP17ContractExtension/LSP17Constants.sol

2: pragma solidity ^0.8.4;
File: /contracts/LSP17ContractExtension/LSP17Errors.sol

2: pragma solidity ^0.8.4;
File: /contracts/LSP17ContractExtension/LSP17Extendable.sol

2: pragma solidity ^0.8.4;
File: /contracts/LSP17ContractExtension/LSP17Extension.sol

2: pragma solidity ^0.8.4;
File: /contracts/LSP17ContractExtension/LSP17Utils.sol

2: pragma solidity ^0.8.4;
File: /contracts/LSP1UniversalReceiver/LSP1UniversalReceiverDelegateUP/LSP1UniversalReceiverDelegateUP.sol

2: pragma solidity ^0.8.4;
File: /contracts/LSP20CallVerification/ILSP20CallVerifier.sol

2: pragma solidity ^0.8.4;
File: /contracts/LSP20CallVerification/LSP20CallVerification.sol

2: pragma solidity ^0.8.4;
File: /contracts/LSP20CallVerification/LSP20Constants.sol

2: pragma solidity ^0.8.4;
File: /contracts/LSP20CallVerification/LSP20Errors.sol

2: pragma solidity ^0.8.4;
File: /contracts/LSP2ERC725YJSONSchema/LSP2Utils.sol

2: pragma solidity ^0.8.4;
File: /contracts/LSP4DigitalAssetMetadata/ILSP4Compatibility.sol

3: pragma solidity ^0.8.4;
File: /contracts/LSP4DigitalAssetMetadata/LSP4Compatibility.sol

2: pragma solidity ^0.8.4;
File: /contracts/LSP4DigitalAssetMetadata/LSP4Constants.sol

2: pragma solidity ^0.8.4;
File: /contracts/LSP4DigitalAssetMetadata/LSP4DigitalAssetMetadata.sol

2: pragma solidity ^0.8.4;
File: /contracts/LSP4DigitalAssetMetadata/LSP4DigitalAssetMetadataInitAbstract.sol

2: pragma solidity ^0.8.4;
File: /contracts/LSP4DigitalAssetMetadata/LSP4Errors.sol

2: pragma solidity ^0.8.4;
File: /contracts/LSP6KeyManager/LSP6Modules/LSP6ExecuteModule.sol

2: pragma solidity ^0.8.5;
File: /contracts/LSP6KeyManager/LSP6Modules/LSP6OwnershipModule.sol

2: pragma solidity ^0.8.5;
File: /contracts/LSP6KeyManager/LSP6Modules/LSP6SetDataModule.sol

2: pragma solidity ^0.8.5;
File: /contracts/LSP7DigitalAsset/ILSP7DigitalAsset.sol

3: pragma solidity ^0.8.4;
File: /contracts/LSP7DigitalAsset/LSP7Constants.sol

2: pragma solidity ^0.8.4;
File: /contracts/LSP7DigitalAsset/LSP7DigitalAsset.sol

2: pragma solidity ^0.8.4;
File: /contracts/LSP7DigitalAsset/LSP7DigitalAssetCore.sol

2: pragma solidity ^0.8.4;
File: /contracts/LSP7DigitalAsset/LSP7DigitalAssetInitAbstract.sol

2: pragma solidity ^0.8.4;
File: /contracts/LSP7DigitalAsset/LSP7Errors.sol

2: pragma solidity ^0.8.4;
File: /contracts/LSP8IdentifiableDigitalAsset/ILSP8IdentifiableDigitalAsset.sol

3: pragma solidity ^0.8.4;
File: /contracts/LSP8IdentifiableDigitalAsset/LSP8Constants.sol

2: pragma solidity ^0.8.4;
File: /contracts/LSP8IdentifiableDigitalAsset/LSP8Errors.sol

2: pragma solidity ^0.8.4;
File: /contracts/LSP8IdentifiableDigitalAsset/LSP8IdentifiableDigitalAsset.sol

2: pragma solidity ^0.8.4;
File: /contracts/LSP8IdentifiableDigitalAsset/LSP8IdentifiableDigitalAssetCore.sol

2: pragma solidity ^0.8.4;
File: /contracts/LSP8IdentifiableDigitalAsset/LSP8IdentifiableDigitalAssetInitAbstract.sol

2: pragma solidity ^0.8.4;
File: /contracts/UniversalProfile.sol

2: pragma solidity ^0.8.4;
File: /contracts/UniversalProfileInit.sol

2: pragma solidity ^0.8.4;
File: /contracts/UniversalProfileInitAbstract.sol

2: pragma solidity ^0.8.4;
File: /submodules/ERC725/implementations/contracts/ERC725.sol

2: pragma solidity ^0.8.0;
File: /submodules/ERC725/implementations/contracts/ERC725Init.sol

2: pragma solidity ^0.8.0;
File: /submodules/ERC725/implementations/contracts/ERC725InitAbstract.sol

2: pragma solidity ^0.8.0;
File: /submodules/ERC725/implementations/contracts/ERC725X.sol

2: pragma solidity ^0.8.0;
File: /submodules/ERC725/implementations/contracts/ERC725XCore.sol

2: pragma solidity ^0.8.0;
File: /submodules/ERC725/implementations/contracts/ERC725XInit.sol

2: pragma solidity ^0.8.0;
File: /submodules/ERC725/implementations/contracts/ERC725XInitAbstract.sol

2: pragma solidity ^0.8.0;
File: /submodules/ERC725/implementations/contracts/ERC725Y.sol

2: pragma solidity ^0.8.0;
File: /submodules/ERC725/implementations/contracts/ERC725YCore.sol

2: pragma solidity ^0.8.0;
File: /submodules/ERC725/implementations/contracts/ERC725YInit.sol

2: pragma solidity ^0.8.0;
File: /submodules/ERC725/implementations/contracts/ERC725YInitAbstract.sol

2: pragma solidity ^0.8.0;
File: /submodules/ERC725/implementations/contracts/constants.sol

2: pragma solidity ^0.8.0;
File: /submodules/ERC725/implementations/contracts/errors.sol

2: pragma solidity ^0.8.0;

[NC-6] IMPLEMENTATION CONTRACT MAY NOT BE INITIALIZED

Description:

OpenZeppelin recommends that the initializer modifier be applied to constructors.

Per OZs Post implementation contract should be initialized to avoid potential griefs or exploits.

https://forum.openzeppelin.com/t/uupsupgradeable-vulnerability-post-mortem/15680/5

Proof Of Concept
File: /contracts/LSP0ERC725Account/LSP0ERC725AccountInitAbstract.sol

7:     Initializable

8: } from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";

45:     Initializable,
File: /submodules/ERC725/implementations/contracts/ERC725InitAbstract.sol

7:     Initializable

22:     Initializable,
File: /submodules/ERC725/implementations/contracts/ERC725XInitAbstract.sol

6:     Initializable
File: /submodules/ERC725/implementations/contracts/ERC725YInitAbstract.sol

6:     Initializable

[NC-7] MARK VISIBILITY OF INITIALIZE(…) FUNCTIONS AS EXTERNAL

Description:

If someone wants to extend via inheritance, it might make more sense that the overridden initialize(...) function calls the internal {...}_init function, not the parent public initialize(...) function.

External instead of public would give more sense of the initialize(...) functions to behave like a constructor (only called on deployment, so should only be called externally).

From a security point of view, it might be safer so that it cannot be called internally by accident in the child contract.

Proof Of Concept
File: /submodules/ERC725/implementations/contracts/ERC725Init.sol

27:     function initialize(address newOwner) public payable virtual initializer {
File: /submodules/ERC725/implementations/contracts/ERC725XInit.sol

26:     function initialize(address newOwner) public payable virtual initializer {
File: /submodules/ERC725/implementations/contracts/ERC725YInit.sol

26:     function initialize(address newOwner) public payable virtual initializer {

[NC-8] DON’T WORRY ABOUT KECCAK256 COLLISIONS

Proof Of Concept
File: /contracts/LSP6KeyManager/LSP6Modules/LSP6SetDataModule.sol

733:                     continue;

[NC-9] LACK OF EVENT EMISSION AFTER CRITICAL INITIALIZE() FUNCTIONS

Description:

To record the init parameters for off-chain monitoring and transparency reasons, please consider emitting an event after the initialize() functions.

Proof Of Concept
File: /contracts/LSP0ERC725Account/LSP0ERC725AccountInit.sol

62:     function initialize(
File: /contracts/UniversalProfileInit.sol

34:     function initialize(
File: /submodules/ERC725/implementations/contracts/ERC725Init.sol

27:     function initialize(address newOwner) public payable virtual initializer {
File: /submodules/ERC725/implementations/contracts/ERC725XInit.sol

26:     function initialize(address newOwner) public payable virtual initializer {
File: /submodules/ERC725/implementations/contracts/ERC725YInit.sol

26:     function initialize(address newOwner) public payable virtual initializer {

[NC-10] FOR EXTENDED “USING-FOR” USAGE, USE THE LATEST PRAGMA VERSION

Proof Of Concept
File: /contracts/LSP0ERC725Account/ILSP0ERC725Account.sol

2: pragma solidity ^0.8.4;
File: /contracts/LSP0ERC725Account/LSP0Constants.sol

2: pragma solidity ^0.8.4;
File: /contracts/LSP0ERC725Account/LSP0ERC725Account.sol

2: pragma solidity ^0.8.4;
File: /contracts/LSP0ERC725Account/LSP0ERC725AccountCore.sol

2: pragma solidity ^0.8.4;
File: /contracts/LSP0ERC725Account/LSP0ERC725AccountInit.sol

2: pragma solidity ^0.8.4;
File: /contracts/LSP0ERC725Account/LSP0ERC725AccountInitAbstract.sol

2: pragma solidity ^0.8.4;
File: /contracts/LSP0ERC725Account/LSP0Utils.sol

2: pragma solidity ^0.8.4;
File: /contracts/LSP14Ownable2Step/ILSP14Ownable2Step.sol

2: pragma solidity ^0.8.4;
File: /contracts/LSP14Ownable2Step/LSP14Constants.sol

2: pragma solidity ^0.8.4;
File: /contracts/LSP14Ownable2Step/LSP14Errors.sol

2: pragma solidity ^0.8.4;
File: /contracts/LSP14Ownable2Step/LSP14Ownable2Step.sol

2: pragma solidity ^0.8.4;
File: /contracts/LSP17ContractExtension/LSP17Constants.sol

2: pragma solidity ^0.8.4;
File: /contracts/LSP17ContractExtension/LSP17Errors.sol

2: pragma solidity ^0.8.4;
File: /contracts/LSP17ContractExtension/LSP17Extendable.sol

2: pragma solidity ^0.8.4;
File: /contracts/LSP17ContractExtension/LSP17Extension.sol

2: pragma solidity ^0.8.4;
File: /contracts/LSP17ContractExtension/LSP17Utils.sol

2: pragma solidity ^0.8.4;
File: /contracts/LSP1UniversalReceiver/LSP1UniversalReceiverDelegateUP/LSP1UniversalReceiverDelegateUP.sol

2: pragma solidity ^0.8.4;
File: /contracts/LSP20CallVerification/ILSP20CallVerifier.sol

2: pragma solidity ^0.8.4;
File: /contracts/LSP20CallVerification/LSP20CallVerification.sol

2: pragma solidity ^0.8.4;
File: /contracts/LSP20CallVerification/LSP20Constants.sol

2: pragma solidity ^0.8.4;
File: /contracts/LSP20CallVerification/LSP20Errors.sol

2: pragma solidity ^0.8.4;
File: /contracts/LSP2ERC725YJSONSchema/LSP2Utils.sol

2: pragma solidity ^0.8.4;
File: /contracts/LSP4DigitalAssetMetadata/ILSP4Compatibility.sol

3: pragma solidity ^0.8.4;
File: /contracts/LSP4DigitalAssetMetadata/LSP4Compatibility.sol

2: pragma solidity ^0.8.4;
File: /contracts/LSP4DigitalAssetMetadata/LSP4Constants.sol

2: pragma solidity ^0.8.4;
File: /contracts/LSP4DigitalAssetMetadata/LSP4DigitalAssetMetadata.sol

2: pragma solidity ^0.8.4;
File: /contracts/LSP4DigitalAssetMetadata/LSP4DigitalAssetMetadataInitAbstract.sol

2: pragma solidity ^0.8.4;
File: /contracts/LSP4DigitalAssetMetadata/LSP4Errors.sol

2: pragma solidity ^0.8.4;
File: /contracts/LSP6KeyManager/LSP6Modules/LSP6ExecuteModule.sol

2: pragma solidity ^0.8.5;
File: /contracts/LSP6KeyManager/LSP6Modules/LSP6OwnershipModule.sol

2: pragma solidity ^0.8.5;
File: /contracts/LSP6KeyManager/LSP6Modules/LSP6SetDataModule.sol

2: pragma solidity ^0.8.5;
File: /contracts/LSP7DigitalAsset/ILSP7DigitalAsset.sol

3: pragma solidity ^0.8.4;
File: /contracts/LSP7DigitalAsset/LSP7Constants.sol

2: pragma solidity ^0.8.4;
File: /contracts/LSP7DigitalAsset/LSP7DigitalAsset.sol

2: pragma solidity ^0.8.4;
File: /contracts/LSP7DigitalAsset/LSP7DigitalAssetCore.sol

2: pragma solidity ^0.8.4;
File: /contracts/LSP7DigitalAsset/LSP7DigitalAssetInitAbstract.sol

2: pragma solidity ^0.8.4;
File: /contracts/LSP7DigitalAsset/LSP7Errors.sol

2: pragma solidity ^0.8.4;
File: /contracts/LSP8IdentifiableDigitalAsset/ILSP8IdentifiableDigitalAsset.sol

3: pragma solidity ^0.8.4;
File: /contracts/LSP8IdentifiableDigitalAsset/LSP8Constants.sol

2: pragma solidity ^0.8.4;
File: /contracts/LSP8IdentifiableDigitalAsset/LSP8Errors.sol

2: pragma solidity ^0.8.4;
File: /contracts/LSP8IdentifiableDigitalAsset/LSP8IdentifiableDigitalAsset.sol

2: pragma solidity ^0.8.4;
File: /contracts/LSP8IdentifiableDigitalAsset/LSP8IdentifiableDigitalAssetCore.sol

2: pragma solidity ^0.8.4;
File: /contracts/LSP8IdentifiableDigitalAsset/LSP8IdentifiableDigitalAssetInitAbstract.sol

2: pragma solidity ^0.8.4;
File: /contracts/UniversalProfile.sol

2: pragma solidity ^0.8.4;
File: /contracts/UniversalProfileInit.sol

2: pragma solidity ^0.8.4;
File: /contracts/UniversalProfileInitAbstract.sol

2: pragma solidity ^0.8.4;
File: /submodules/ERC725/implementations/contracts/ERC725.sol

2: pragma solidity ^0.8.0;
File: /submodules/ERC725/implementations/contracts/ERC725Init.sol

2: pragma solidity ^0.8.0;
File: /submodules/ERC725/implementations/contracts/ERC725InitAbstract.sol

2: pragma solidity ^0.8.0;
File: /submodules/ERC725/implementations/contracts/ERC725X.sol

2: pragma solidity ^0.8.0;
File: /submodules/ERC725/implementations/contracts/ERC725XCore.sol

2: pragma solidity ^0.8.0;
File: /submodules/ERC725/implementations/contracts/ERC725XInit.sol

2: pragma solidity ^0.8.0;
File: /submodules/ERC725/implementations/contracts/ERC725XInitAbstract.sol

2: pragma solidity ^0.8.0;
File: /submodules/ERC725/implementations/contracts/ERC725Y.sol

2: pragma solidity ^0.8.0;
File: /submodules/ERC725/implementations/contracts/ERC725YCore.sol

2: pragma solidity ^0.8.0;
File: /submodules/ERC725/implementations/contracts/ERC725YInit.sol

2: pragma solidity ^0.8.0;
File: /submodules/ERC725/implementations/contracts/ERC725YInitAbstract.sol

2: pragma solidity ^0.8.0;
File: /submodules/ERC725/implementations/contracts/constants.sol

2: pragma solidity ^0.8.0;
File: /submodules/ERC725/implementations/contracts/errors.sol

2: pragma solidity ^0.8.0;

Use solidity pragma version min. 0.8.13

[NC-11] Omissions in events

Description:

Throughout the codebase, events are generally emitted when sensitive changes are made to the contracts. However, some events are missing important parameters.

Proof Of Concept
File: /contracts/LSP14Ownable2Step/LSP14Ownable2Step.sol

165:             emit RenounceOwnershipStarted();

178:         emit OwnershipRenounced();

[NC-12] FOR FUNCTIONS AND VARIABLES FOLLOW SOLIDITY STANDARD NAMING CONVENTIONS

Description:

Solidity’s standard naming convention for internal and private functions and variables (apart from constants): the mixedCase format starting with an underscore (_mixedCase starting with an underscore)

Solidity’s standard naming convention for internal and private constants variables: the snake_case format starting with an underscore (_mixedCase starting with an underscore) and use ALL_CAPS for naming them.

Proof Of Concept
File: /contracts/LSP2ERC725YJSONSchema/LSP2Utils.sol

231:     function isEncodedArray(bytes memory data) internal pure returns (bool) {

[NC-13] Functions not used internally could be marked external

Proof Of Concept
File: /contracts/LSP0ERC725Account/LSP0ERC725AccountCore.sol

171:     function batchCalls(

Low Issues

Issue
L-1Initializing state-variables in proxy-based upgradeable contracts
L-2CRITICAL CHANGES SHOULD USE TWO-STEP PROCEDURE
L-3UNIFY RETURN CRITERIA
L-4TOKEN SHOULD THROW AN ERROR IF _TOKENID IS NOT A VALID NFT

[L-1] Initializing state-variables in proxy-based upgradeable contracts

Description:

This should be done in initializer functions and not as part of the state variable declarations in which case they won’t be set.

https://docs.openzeppelin.com/upgrades-plugins/1.x/writing-upgradeable#avoid-initial-values-in-field-declarations

Proof Of Concept
File: /contracts/LSP0ERC725Account/LSP0ERC725AccountInit.sol

62:     function initialize(
File: /contracts/UniversalProfileInit.sol

34:     function initialize(
File: /submodules/ERC725/implementations/contracts/ERC725Init.sol

27:     function initialize(address newOwner) public payable virtual initializer {
File: /submodules/ERC725/implementations/contracts/ERC725XInit.sol

26:     function initialize(address newOwner) public payable virtual initializer {
File: /submodules/ERC725/implementations/contracts/ERC725YInit.sol

26:     function initialize(address newOwner) public payable virtual initializer {

[L-2] CRITICAL CHANGES SHOULD USE TWO-STEP PROCEDURE

Description:

The critical procedures should be two step process.

Proof Of Concept
File: /contracts/LSP4DigitalAssetMetadata/LSP4DigitalAssetMetadata.sol

52:     function _setData(
File: /contracts/LSP4DigitalAssetMetadata/LSP4DigitalAssetMetadataInitAbstract.sol

50:     function _setData(
File: /contracts/LSP6KeyManager/LSP6Modules/LSP6OwnershipModule.sol

14:     function _verifyOwnershipPermissions(
File: /submodules/ERC725/implementations/contracts/ERC725YCore.sol

62:     function setData(

73:     function setDataBatch(

104:     function _setData(

Lack of two-step procedure for critical operations leaves them error-prone. Consider adding two step procedure on the critical functions.

[L-3] UNIFY RETURN CRITERIA

Description:

In contracts, sometimes the name of the return variable is not defined and sometimes is, unifying the way of writing the code makes the code more uniform and readable.

Proof Of Concept
File: /contracts/LSP0ERC725Account/ILSP0ERC725Account.sol

69:     ) external returns (bytes[] memory results);
File: /contracts/LSP0ERC725Account/LSP0ERC725AccountCore.sol

173:     ) public returns (bytes[] memory results) {

227:     ) public payable virtual override returns (bytes memory) {

285:     ) public payable virtual override returns (bytes[] memory) {

463:     ) public payable virtual returns (bytes memory returnedValues) {

699:         returns (bool)

737:     ) public view virtual returns (bytes4 magicValue) {

853:     ) internal view virtual override returns (address) {
File: /contracts/LSP0ERC725Account/LSP0Utils.sol

26:     ) internal view returns (bytes memory) {

40:     ) internal view returns (bytes memory) {
File: /contracts/LSP14Ownable2Step/ILSP14Ownable2Step.sol

42:     function pendingOwner() external view returns (address);
File: /contracts/LSP14Ownable2Step/LSP14Ownable2Step.sol

59:     function pendingOwner() public view virtual returns (address) {
File: /contracts/LSP17ContractExtension/LSP17Extendable.sol

30:     ) public view virtual override returns (bool) {

46:     ) internal view virtual returns (bool) {

67:     ) internal view virtual returns (address);
File: /contracts/LSP17ContractExtension/LSP17Extension.sol

22:     ) public view virtual override returns (bool) {

36:         returns (bytes calldata)

44:     function _extendableMsgSender() internal view virtual returns (address) {

54:     function _extendableMsgValue() internal view virtual returns (uint256) {
File: /contracts/LSP17ContractExtension/LSP17Utils.sol

16:     ) internal pure returns (bool) {
File: /contracts/LSP1UniversalReceiver/LSP1UniversalReceiverDelegateUP/LSP1UniversalReceiverDelegateUP.sol

81:     ) public payable virtual returns (bytes memory result) {

157:     ) internal virtual returns (bytes memory) {

206:     ) internal virtual returns (bytes memory) {

261:     ) public view virtual override returns (bool) {
File: /contracts/LSP20CallVerification/ILSP20CallVerifier.sol

23:     ) external returns (bytes4 magicValue);

34:     ) external returns (bytes4);
File: /contracts/LSP20CallVerification/LSP20CallVerification.sol

25:     ) internal virtual returns (bool verifyAfter) {
File: /contracts/LSP2ERC725YJSONSchema/LSP2Utils.sol

24:     ) internal pure returns (bytes32) {

34:     ) internal pure returns (bytes32) {

55:     ) internal pure returns (bytes32) {

74:     ) internal pure returns (bytes32) {

97:     ) internal pure returns (bytes32) {

118:     ) internal pure returns (bytes32) {

140:     ) internal pure returns (bytes32) {

165:     ) internal pure returns (bytes32) {

184:     ) internal pure returns (bytes32) {

203:     ) internal pure returns (bytes memory) {

220:     ) internal pure returns (bytes memory) {

231:     function isEncodedArray(bytes memory data) internal pure returns (bool) {

253:     ) internal pure returns (bool) {

285:     ) internal pure returns (bool) {

314:     ) internal pure returns (bool) {
File: /contracts/LSP4DigitalAssetMetadata/ILSP4Compatibility.sol

18:     function name() external view returns (string memory);

24:     function symbol() external view returns (string memory);
File: /contracts/LSP4DigitalAssetMetadata/LSP4Compatibility.sol

25:     function name() public view virtual override returns (string memory) {

34:     function symbol() public view virtual override returns (string memory) {
File: /contracts/LSP6KeyManager/LSP6Modules/LSP6ExecuteModule.sol

321:     ) internal pure returns (bytes4 requiredCallTypes) {

341:     ) internal pure returns (uint256, address, uint256, bytes4, bool) {

369:     ) internal pure returns (bool) {

385:     ) internal view returns (bool) {

402:     ) internal pure returns (bool) {

421:     ) internal pure returns (bool) {
File: /contracts/LSP6KeyManager/LSP6Modules/LSP6SetDataModule.sol

195:     ) internal view virtual returns (bytes32) {

339:     ) internal view virtual returns (bytes32) {

388:     ) internal view virtual returns (bytes32) {

411:     ) internal view virtual returns (bytes32) {

443:     ) internal view returns (bytes32) {

477:     ) internal view virtual returns (bytes32) {

493:     ) internal view virtual returns (bytes32) {
File: /contracts/LSP7DigitalAsset/ILSP7DigitalAsset.sol

65:     function decimals() external view returns (uint8);

71:     function totalSupply() external view returns (uint256);

80:     function balanceOf(address tokenOwner) external view returns (uint256);

134:     ) external view returns (uint256);
File: /contracts/LSP7DigitalAsset/LSP7DigitalAsset.sol

53:     ) public view virtual override(IERC165, ERC725YCore) returns (bool) {
File: /contracts/LSP7DigitalAsset/LSP7DigitalAssetCore.sol

54:     function decimals() public view virtual returns (uint8) {

61:     function totalSupply() public view virtual returns (uint256) {

72:     ) public view virtual returns (uint256) {

111:     ) public view virtual returns (uint256) {
File: /contracts/LSP7DigitalAsset/LSP7DigitalAssetInitAbstract.sol

47:     ) public view virtual override(IERC165, ERC725YCore) returns (bool) {
File: /contracts/LSP8IdentifiableDigitalAsset/ILSP8IdentifiableDigitalAsset.sol

66:     function totalSupply() external view returns (uint256);

77:     function balanceOf(address tokenOwner) external view returns (uint256);

88:     function tokenOwnerOf(bytes32 tokenId) external view returns (address);

97:     ) external view returns (bytes32[] memory);

150:     ) external view returns (bool);

163:     ) external view returns (address[] memory);
File: /contracts/LSP8IdentifiableDigitalAsset/LSP8IdentifiableDigitalAsset.sol

47:     ) public view virtual override(IERC165, ERC725YCore) returns (bool) {
File: /contracts/LSP8IdentifiableDigitalAsset/LSP8IdentifiableDigitalAssetCore.sol

61:     function totalSupply() public view virtual returns (uint256) {

72:     ) public view virtual returns (uint256) {

81:     ) public view virtual returns (address) {

96:     ) public view virtual returns (bytes32[] memory) {

156:     ) public view virtual returns (bool) {

167:     ) public view virtual returns (address[] memory) {

180:     ) internal view virtual returns (bool) {

290:     function _exists(bytes32 tokenId) internal view virtual returns (bool) {
File: /contracts/LSP8IdentifiableDigitalAsset/LSP8IdentifiableDigitalAssetInitAbstract.sol

47:     ) public view virtual override(IERC165, ERC725YCore) returns (bool) {
File: /submodules/ERC725/implementations/contracts/ERC725.sol

39:     ) public view virtual override(ERC725XCore, ERC725YCore) returns (bool) {
File: /submodules/ERC725/implementations/contracts/ERC725InitAbstract.sol

41:     ) public view virtual override(ERC725XCore, ERC725YCore) returns (bool) {
File: /submodules/ERC725/implementations/contracts/ERC725XCore.sol

45:     ) public payable virtual override onlyOwner returns (bytes memory) {

57:     ) public payable virtual override onlyOwner returns (bytes[] memory) {

66:     ) public view virtual override(IERC165, ERC165) returns (bool) {

81:     ) internal virtual returns (bytes memory) {

136:     ) internal virtual returns (bytes[] memory) {

178:     ) internal virtual returns (bytes memory result) {

206:     ) internal virtual returns (bytes memory result) {

228:     ) internal virtual returns (bytes memory result) {

250:     ) internal virtual returns (bytes memory newContract) {

291:     ) internal virtual returns (bytes memory newContract) {
File: /submodules/ERC725/implementations/contracts/ERC725YCore.sol

35:     ) public view virtual override returns (bytes memory dataValue) {

44:     ) public view virtual override returns (bytes[] memory dataValues) {

100:     ) internal view virtual returns (bytes memory dataValue) {

117:     ) public view virtual override(IERC165, ERC165) returns (bool) {

add {return x} if you want to return the updated value or else remove returns(uint) from the function(){} if no value you wanted to return

[L-4] TOKEN SHOULD THROW AN ERROR IF _TOKENID IS NOT A VALID NFT

File: /contracts/LSP8IdentifiableDigitalAsset/LSP8IdentifiableDigitalAssetCore.sol

54:     mapping(address => EnumerableSet.Bytes32Set) private _tokenIdsForOperator;

Consider throwing an error if _tokenId is not a valid NFT.

#0 - c4-judge

2023-08-02T09:28:40Z

trust1995 marked the issue as grade-b

Findings Information

Labels

bug
G (Gas Optimization)
grade-b
G-13

Awards

33.4768 USDC - $33.48

External Links

Gas Optimizations

Issue
GAS-1Use selfbalance() instead of address(this).balance
GAS-2ABI.ENCODE() IS LESS EFFICIENT THAN ABI.ENCODEPACKED()
GAS-3Use assembly to check for address(0)
GAS-4BEFORE SOME FUNCTIONS, WE SHOULD CHECK SOME VARIABLES FOR POSSIBLE GAS SAVE
GAS-5USING CALLDATA INSTEAD OF MEMORY FOR READ-ONLY ARGUMENTS IN EXTERNAL FUNCTIONS SAVES GAS
GAS-5Setting the constructor to payable
GAS-7INTERNAL FUNCTIONS NOT CALLED BY THE CONTRACT SHOULD BE REMOVED TO SAVE DEPLOYMENT GAS
GAS-8MAKING CONSTANT VARIABLES PRIVATE WILL SAVE GAS DURING DEPLOYMENT
GAS-9SAVE GAS BY NOT REQURING NON-ZERO INTERVAL IF NO LINEAR AMOUNT
GAS-10The increment in for loop postcondition can be made unchecked
GAS-11Use a more recent version of solidity
GAS-12TERNARY OPERATION IS CHEAPER THAN IF-ELSE STATEMENT
GAS-13Usage of uint/int smaller than 32 bytes (256 bits) incurs overhead
GAS-14Use != 0 instead of > 0 for unsigned integer comparison
GAS-15USE BYTES32 INSTEAD OF STRING
GAS-16Public functions not called by the contract should be declared external instead OR Functions not used internally could be marked external

[GAS-1] Use selfbalance() instead of address(this).balance

Description:

You can use selfbalance() instead of address(this).balance when getting your contract's balance of ETH to save gas.

Additionally, you can use balance(address) instead of address.balance() when getting an external contract's balance of ETH.

Proof Of Concept
File: /submodules/ERC725/implementations/contracts/ERC725XCore.sol

179:         if (address(this).balance < value) {

180:             revert ERC725X_InsufficientBalance(address(this).balance, value);

251:         if (address(this).balance < value) {

252:             revert ERC725X_InsufficientBalance(address(this).balance, value);

[GAS-2] ABI.ENCODE() IS LESS EFFICIENT THAN ABI.ENCODEPACKED()

Description:

Use abi.encodePacked() where possible to save gas

Proof Of Concept
File: /contracts/LSP0ERC725Account/LSP0ERC725AccountCore.sol

253:             LSP20CallVerification._verifyCallResult(_owner, abi.encode(result));

319:                 abi.encode(results)

[GAS-3] Use assembly to check for address(0)

Proof Of Concept
File: /contracts/LSP0ERC725Account/LSP0ERC725AccountCore.sol

801:         if (msg.sig == bytes4(0) && extension == address(0)) return;

801:         if (msg.sig == bytes4(0) && extension == address(0)) return;

804:         if (extension == address(0))
File: /contracts/LSP17ContractExtension/LSP17Extendable.sol

50:         if (erc165Extension == address(0)) return false;

91:         if (extension == address(0))
File: /contracts/LSP1UniversalReceiver/LSP1UniversalReceiverDelegateUP/LSP1UniversalReceiverDelegateUP.sol

116:         bool isMapValueSet = bytes20(notifierMapValue) != bytes20(0);
File: /contracts/LSP20CallVerification/LSP20CallVerification.sol

80:             bytes28(bytes32(returnedData) << 32) != bytes28(0)
File: /contracts/LSP2ERC725YJSONSchema/LSP2Utils.sol

266:             if (bytes12(key) != bytes12(0)) return false;
File: /contracts/LSP6KeyManager/LSP6Modules/LSP6ExecuteModule.sol

345:         if (bytes12(executeCalldata[36:48]) != bytes12(0)) {

410:         bool isFunctionCall = requiredFunction != bytes4(0);
File: /contracts/LSP6KeyManager/LSP6Modules/LSP6SetDataModule.sol

97:             if (requiredPermission == bytes32(0)) return;

146:                 if (requiredPermission != bytes32(0)) {

392:             bytes32(
File: /contracts/LSP7DigitalAsset/LSP7DigitalAssetCore.sol

268:         if (operator == address(0)) {

300:         if (to == address(0)) {

343:         if (from == address(0)) {

406:         if (from == address(0) || to == address(0)) {

406:         if (from == address(0) || to == address(0)) {
File: /contracts/LSP8IdentifiableDigitalAsset/LSP8IdentifiableDigitalAssetCore.sol

84:         if (tokenOwner == address(0)) {

115:         if (operator == address(0)) {

139:         if (operator == address(0)) {

291:         return _tokenOwners[tokenId] != address(0);

319:         if (to == address(0)) {

410:         if (to == address(0)) {
File: /submodules/ERC725/implementations/contracts/ERC725.sol

28:             newOwner != address(0),
File: /submodules/ERC725/implementations/contracts/ERC725InitAbstract.sol

28:             newOwner != address(0),
File: /submodules/ERC725/implementations/contracts/ERC725X.sol

22:             newOwner != address(0),
File: /submodules/ERC725/implementations/contracts/ERC725XCore.sol

89:             if (target != address(0))

96:             if (target != address(0))

269:         if (contractAddress == address(0)) {
File: /submodules/ERC725/implementations/contracts/ERC725XInitAbstract.sol

21:             newOwner != address(0),
File: /submodules/ERC725/implementations/contracts/ERC725Y.sol

23:             newOwner != address(0),
File: /submodules/ERC725/implementations/contracts/ERC725YInitAbstract.sol

21:             newOwner != address(0),

[GAS-4] BEFORE SOME FUNCTIONS, WE SHOULD CHECK SOME VARIABLES FOR POSSIBLE GAS SAVE

Description:

Before transfer, we should check for amount being 0 so the function doesnt run when its not gonna do anything:

Proof Of Concept
File: /contracts/LSP0ERC725Account/LSP0ERC725AccountCore.sol

557:     function transferOwnership(

565:             LSP14Ownable2Step._transferOwnership(pendingNewOwner);

586:             LSP14Ownable2Step._transferOwnership(pendingNewOwner);
File: /contracts/LSP14Ownable2Step/ILSP14Ownable2Step.sol

54:     function transferOwnership(address newOwner) external;
File: /contracts/LSP14Ownable2Step/LSP14Ownable2Step.sol

66:     function transferOwnership(

69:         _transferOwnership(newOwner);

126:     function _transferOwnership(address newOwner) internal virtual {
File: /contracts/LSP7DigitalAsset/ILSP7DigitalAsset.sol

159:     function transfer(

189:     function transferBatch(
File: /contracts/LSP7DigitalAsset/LSP7DigitalAssetCore.sol

124:     function transfer(

148:         _transfer(from, to, amount, allowNonLSP1Recipient, data);

154:     function transferBatch(

173:             transfer(

399:     function _transfer(
File: /contracts/LSP8IdentifiableDigitalAsset/ILSP8IdentifiableDigitalAsset.sol

186:     function transfer(

216:     function transferBatch(
File: /contracts/LSP8IdentifiableDigitalAsset/LSP8IdentifiableDigitalAssetCore.sol

191:     function transfer(

204:         _transfer(from, to, tokenId, allowNonLSP1Recipient, data);

210:     function transferBatch(

228:             transfer(

394:     function _transfer(

[GAS-5] USING CALLDATA INSTEAD OF MEMORY FOR READ-ONLY ARGUMENTS IN EXTERNAL FUNCTIONS SAVES GAS

Description:

Mark data types as calldata instead of memory where possible. This makes it so that the data is not automatically loaded into memory. If the data passed into the function does not need to be changed (like updating values in an array), it can be passed in as calldata. The one exception to this is if the argument must later be passed into another function that takes an argument that specifies memory storage. Source Source 2

Proof Of Concept
File: /contracts/LSP0ERC725Account/LSP0ERC725AccountCore.sol

226:         bytes memory data

281:         uint256[] memory operationsType,

282:         address[] memory targets,

283:         uint256[] memory values,

284:         bytes[] memory datas

341:         bytes memory dataValue

381:         bytes32[] memory dataKeys,

382:         bytes[] memory dataValues

736:         bytes memory signature
File: /contracts/LSP1UniversalReceiver/LSP1UniversalReceiverDelegateUP/LSP1UniversalReceiverDelegateUP.sol

80:         bytes memory /* data */
File: /contracts/LSP20CallVerification/ILSP20CallVerifier.sol

22:         bytes memory receivedCalldata

33:         bytes memory result
File: /contracts/LSP7DigitalAsset/ILSP7DigitalAsset.sol

164:         bytes memory data

190:         address[] memory from,

191:         address[] memory to,

192:         uint256[] memory amount,

193:         bool[] memory allowNonLSP1Recipient,

194:         bytes[] memory data
File: /contracts/LSP7DigitalAsset/LSP7DigitalAssetCore.sol

129:         bytes memory data

155:         address[] memory from,

156:         address[] memory to,

157:         uint256[] memory amount,

158:         bool[] memory allowNonLSP1Recipient,

159:         bytes[] memory data
File: /contracts/LSP8IdentifiableDigitalAsset/ILSP8IdentifiableDigitalAsset.sol

191:         bytes memory data

217:         address[] memory from,

218:         address[] memory to,

219:         bytes32[] memory tokenId,

220:         bool[] memory allowNonLSP1Recipient,

221:         bytes[] memory data
File: /contracts/LSP8IdentifiableDigitalAsset/LSP8IdentifiableDigitalAssetCore.sol

196:         bytes memory data

211:         address[] memory from,

212:         address[] memory to,

213:         bytes32[] memory tokenId,

214:         bool[] memory allowNonLSP1Recipient,

215:         bytes[] memory data
File: /submodules/ERC725/implementations/contracts/ERC725XCore.sol

44:         bytes memory data

53:         uint256[] memory operationsType,

54:         address[] memory targets,

55:         uint256[] memory values,

56:         bytes[] memory datas
File: /submodules/ERC725/implementations/contracts/ERC725YCore.sol

43:         bytes32[] memory dataKeys

64:         bytes memory dataValue

74:         bytes32[] memory dataKeys,

75:         bytes[] memory dataValues

[GAS-6] Setting the constructor to payable

Description:

Saves ~13 gas per instance

Proof Of Concept
File: /contracts/LSP0ERC725Account/LSP0ERC725AccountInit.sol

47:     constructor() {
File: /contracts/LSP4DigitalAssetMetadata/LSP4DigitalAssetMetadata.sol

31:     constructor(
File: /contracts/LSP7DigitalAsset/LSP7DigitalAsset.sol

39:     constructor(
File: /contracts/LSP8IdentifiableDigitalAsset/LSP8IdentifiableDigitalAsset.sol

36:     constructor(
File: /contracts/UniversalProfileInit.sol

19:     constructor() {
File: /submodules/ERC725/implementations/contracts/ERC725Init.sol

19:     constructor() {
File: /submodules/ERC725/implementations/contracts/ERC725XInit.sol

18:     constructor() {
File: /submodules/ERC725/implementations/contracts/ERC725YInit.sol

18:     constructor() {

[GAS-7] INTERNAL FUNCTIONS NOT CALLED BY THE CONTRACT SHOULD BE REMOVED TO SAVE DEPLOYMENT GAS

Description:

If the functions are required by an interface, the contract should inherit from that interface and use the override keyword

Proof Of Concept
File: /contracts/LSP17ContractExtension/LSP17Extendable.sol

86:     function _fallbackLSP17Extendable() internal virtual {
File: /contracts/LSP17ContractExtension/LSP17Extension.sol

44:     function _extendableMsgSender() internal view virtual returns (address) {

54:     function _extendableMsgValue() internal view virtual returns (uint256) {
File: /contracts/LSP8IdentifiableDigitalAsset/LSP8IdentifiableDigitalAssetCore.sol

359:     function _burn(bytes32 tokenId, bytes memory data) internal virtual {
File: /submodules/ERC725/implementations/contracts/ERC725InitAbstract.sol

26:     function _initialize(address newOwner) internal virtual onlyInitializing {
File: /submodules/ERC725/implementations/contracts/ERC725XInitAbstract.sol

19:     function _initialize(address newOwner) internal virtual onlyInitializing {
File: /submodules/ERC725/implementations/contracts/ERC725YInitAbstract.sol

19:     function _initialize(address newOwner) internal virtual onlyInitializing {

[GAS-8] MAKING CONSTANT VARIABLES PRIVATE WILL SAVE GAS DURING DEPLOYMENT

Description:

When constants are marked public, extra getter functions are created, increasing the deployment cost. Marking these functions private will decrease gas cost. One can still read these variables through the source code. If they need to be accessed by an external contract, a separate single getter function can be used to return all constants as a tuple. There are four instances of public constants.

Proof Of Concept
File: /contracts/LSP14Ownable2Step/LSP14Ownable2Step.sol

39:     uint256 public constant RENOUNCE_OWNERSHIP_CONFIRMATION_DELAY = 200;

44:     uint256 public constant RENOUNCE_OWNERSHIP_CONFIRMATION_PERIOD = 200;

[GAS-9] SAVE GAS BY NOT REQURING NON-ZERO INTERVAL IF NO LINEAR AMOUNT

Description:

If there is no linear amount, a Gsset for the claim’s interval can be converted to a Gsreset, saving 17100 gas.

Proof Of Concept
File: /contracts/LSP14Ownable2Step/LSP14Errors.sol

7: error NotInRenounceOwnershipInterval(
File: /contracts/LSP14Ownable2Step/LSP14Ownable2Step.sol

170:             revert NotInRenounceOwnershipInterval(

[GAS-10] The increment in for loop postcondition can be made unchecked

Description:

This is only relevant if you are using the default solidity checked arithmetic. the for loop postcondition, i.e., i++ involves checked arithmetic, which is not required. This is because the value of i is always strictly less than length <= 2**256 - 1. Therefore, the theoretical maximum value of i to enter the for-loop body is 2**256 - 2. This means that the i++ in the for loop can never overflow. Regardless, the overflow checks are performed by the compiler.

Unfortunately, the Solidity optimizer is not smart enough to detect this and remove the checks.One can manually do this.

Source

Proof Of Concept
File: /contracts/LSP6KeyManager/LSP6Modules/LSP6SetDataModule.sol

156:                 inputDataKeysAllowed++;

743:                         allowedDataKeysFound++;

771:                 jj++;

[GAS-11] Use a more recent version of solidity

Proof Of Concept
File: /contracts/LSP0ERC725Account/ILSP0ERC725Account.sol

2: pragma solidity ^0.8.4;
File: /contracts/LSP0ERC725Account/LSP0Constants.sol

2: pragma solidity ^0.8.4;
File: /contracts/LSP0ERC725Account/LSP0ERC725Account.sol

2: pragma solidity ^0.8.4;
File: /contracts/LSP0ERC725Account/LSP0ERC725AccountCore.sol

2: pragma solidity ^0.8.4;
File: /contracts/LSP0ERC725Account/LSP0ERC725AccountInit.sol

2: pragma solidity ^0.8.4;
File: /contracts/LSP0ERC725Account/LSP0ERC725AccountInitAbstract.sol

2: pragma solidity ^0.8.4;
File: /contracts/LSP0ERC725Account/LSP0Utils.sol

2: pragma solidity ^0.8.4;
File: /contracts/LSP14Ownable2Step/ILSP14Ownable2Step.sol

2: pragma solidity ^0.8.4;
File: /contracts/LSP14Ownable2Step/LSP14Constants.sol

2: pragma solidity ^0.8.4;
File: /contracts/LSP14Ownable2Step/LSP14Errors.sol

2: pragma solidity ^0.8.4;
File: /contracts/LSP14Ownable2Step/LSP14Ownable2Step.sol

2: pragma solidity ^0.8.4;
File: /contracts/LSP17ContractExtension/LSP17Constants.sol

2: pragma solidity ^0.8.4;
File: /contracts/LSP17ContractExtension/LSP17Errors.sol

2: pragma solidity ^0.8.4;
File: /contracts/LSP17ContractExtension/LSP17Extendable.sol

2: pragma solidity ^0.8.4;
File: /contracts/LSP17ContractExtension/LSP17Extension.sol

2: pragma solidity ^0.8.4;
File: /contracts/LSP17ContractExtension/LSP17Utils.sol

2: pragma solidity ^0.8.4;
File: /contracts/LSP1UniversalReceiver/LSP1UniversalReceiverDelegateUP/LSP1UniversalReceiverDelegateUP.sol

2: pragma solidity ^0.8.4;
File: /contracts/LSP20CallVerification/ILSP20CallVerifier.sol

2: pragma solidity ^0.8.4;
File: /contracts/LSP20CallVerification/LSP20CallVerification.sol

2: pragma solidity ^0.8.4;
File: /contracts/LSP20CallVerification/LSP20Constants.sol

2: pragma solidity ^0.8.4;
File: /contracts/LSP20CallVerification/LSP20Errors.sol

2: pragma solidity ^0.8.4;
File: /contracts/LSP2ERC725YJSONSchema/LSP2Utils.sol

2: pragma solidity ^0.8.4;
File: /contracts/LSP4DigitalAssetMetadata/ILSP4Compatibility.sol

3: pragma solidity ^0.8.4;
File: /contracts/LSP4DigitalAssetMetadata/LSP4Compatibility.sol

2: pragma solidity ^0.8.4;
File: /contracts/LSP4DigitalAssetMetadata/LSP4Constants.sol

2: pragma solidity ^0.8.4;
File: /contracts/LSP4DigitalAssetMetadata/LSP4DigitalAssetMetadata.sol

2: pragma solidity ^0.8.4;
File: /contracts/LSP4DigitalAssetMetadata/LSP4DigitalAssetMetadataInitAbstract.sol

2: pragma solidity ^0.8.4;
File: /contracts/LSP4DigitalAssetMetadata/LSP4Errors.sol

2: pragma solidity ^0.8.4;
File: /contracts/LSP6KeyManager/LSP6Modules/LSP6ExecuteModule.sol

2: pragma solidity ^0.8.5;
File: /contracts/LSP6KeyManager/LSP6Modules/LSP6OwnershipModule.sol

2: pragma solidity ^0.8.5;
File: /contracts/LSP6KeyManager/LSP6Modules/LSP6SetDataModule.sol

2: pragma solidity ^0.8.5;
File: /contracts/LSP7DigitalAsset/ILSP7DigitalAsset.sol

3: pragma solidity ^0.8.4;
File: /contracts/LSP7DigitalAsset/LSP7Constants.sol

2: pragma solidity ^0.8.4;
File: /contracts/LSP7DigitalAsset/LSP7DigitalAsset.sol

2: pragma solidity ^0.8.4;
File: /contracts/LSP7DigitalAsset/LSP7DigitalAssetCore.sol

2: pragma solidity ^0.8.4;
File: /contracts/LSP7DigitalAsset/LSP7DigitalAssetInitAbstract.sol

2: pragma solidity ^0.8.4;
File: /contracts/LSP7DigitalAsset/LSP7Errors.sol

2: pragma solidity ^0.8.4;
File: /contracts/LSP8IdentifiableDigitalAsset/ILSP8IdentifiableDigitalAsset.sol

3: pragma solidity ^0.8.4;
File: /contracts/LSP8IdentifiableDigitalAsset/LSP8Constants.sol

2: pragma solidity ^0.8.4;
File: /contracts/LSP8IdentifiableDigitalAsset/LSP8Errors.sol

2: pragma solidity ^0.8.4;
File: /contracts/LSP8IdentifiableDigitalAsset/LSP8IdentifiableDigitalAsset.sol

2: pragma solidity ^0.8.4;
File: /contracts/LSP8IdentifiableDigitalAsset/LSP8IdentifiableDigitalAssetCore.sol

2: pragma solidity ^0.8.4;
File: /contracts/LSP8IdentifiableDigitalAsset/LSP8IdentifiableDigitalAssetInitAbstract.sol

2: pragma solidity ^0.8.4;
File: /contracts/UniversalProfile.sol

2: pragma solidity ^0.8.4;
File: /contracts/UniversalProfileInit.sol

2: pragma solidity ^0.8.4;
File: /contracts/UniversalProfileInitAbstract.sol

2: pragma solidity ^0.8.4;
File: /submodules/ERC725/implementations/contracts/ERC725.sol

2: pragma solidity ^0.8.0;
File: /submodules/ERC725/implementations/contracts/ERC725Init.sol

2: pragma solidity ^0.8.0;
File: /submodules/ERC725/implementations/contracts/ERC725InitAbstract.sol

2: pragma solidity ^0.8.0;
File: /submodules/ERC725/implementations/contracts/ERC725X.sol

2: pragma solidity ^0.8.0;
File: /submodules/ERC725/implementations/contracts/ERC725XCore.sol

2: pragma solidity ^0.8.0;
File: /submodules/ERC725/implementations/contracts/ERC725XInit.sol

2: pragma solidity ^0.8.0;
File: /submodules/ERC725/implementations/contracts/ERC725XInitAbstract.sol

2: pragma solidity ^0.8.0;
File: /submodules/ERC725/implementations/contracts/ERC725Y.sol

2: pragma solidity ^0.8.0;
File: /submodules/ERC725/implementations/contracts/ERC725YCore.sol

2: pragma solidity ^0.8.0;
File: /submodules/ERC725/implementations/contracts/ERC725YInit.sol

2: pragma solidity ^0.8.0;
File: /submodules/ERC725/implementations/contracts/ERC725YInitAbstract.sol

2: pragma solidity ^0.8.0;
File: /submodules/ERC725/implementations/contracts/constants.sol

2: pragma solidity ^0.8.0;
File: /submodules/ERC725/implementations/contracts/errors.sol

2: pragma solidity ^0.8.0;

[GAS-12] TERNARY OPERATION IS CHEAPER THAN IF-ELSE STATEMENT

Description:

There are instances where a ternary operation can be used instead of if-else statement. In these cases, using ternary operation will save modest amounts of gas. Note that this optimization seems to be dependent on usage of a more recent Solidity version. The following gas savings are on version 0.8.17.

Proof Of Concept
File: /contracts/LSP7DigitalAsset/LSP7DigitalAssetCore.sol

112:    if (tokenOwner == operator) {
            return _tokenOwnerBalances[tokenOwner];
        } else {
            return _operatorAuthorizedAmount[tokenOwner][operator];
        }

278:    if (amount != 0) {
            emit AuthorizedOperator(operator, tokenOwner, amount);
        } else {
            emit RevokedOperator(operator, tokenOwner);
        }

491:    if (to.code.length > 0) {
                revert LSP7NotifyTokenReceiverContractMissingLSP1Interface(to);
            } else {
                revert LSP7NotifyTokenReceiverIsEOA(to);
            }
File: /contracts/LSP8IdentifiableDigitalAsset/LSP8IdentifiableDigitalAssetCore.sol

493:       if (to.code.length > 0) {
                revert LSP8NotifyTokenReceiverContractMissingLSP1Interface(to);
            } else {
                revert LSP8NotifyTokenReceiverIsEOA(to);
            }

[GAS-13] Usage of uint/int smaller than 32 bytes (256 bits) incurs overhead

Description:

When using elements that are smaller than 32 bytes, your contract’s gas usage may be higher. This is because the EVM operates on 32 bytes at a time. Therefore, if the element is smaller than that, the EVM must use more operations in order to reduce the size of the element from 32 bytes to the desired size. Each operation involving a uint8 costs an extra 22-28 gas (depending on whether the other operand is also a variable of type uint8) as compared to ones involving uint256, due to the compiler having to clear the higher bits of the memory word before operating on the uint8, as well as the associated stack operations of doing so. Use a larger size then downcast where needed. https://docs.soliditylang.org/en/v0.8.11/internals/layout_in_storage.html Use a larger size then downcast where needed.

Proof Of Concept
File: /contracts/LSP2ERC725YJSONSchema/LSP2Utils.sol

336:             uint256 elementLength = uint16(
File: /contracts/LSP6KeyManager/LSP6Modules/LSP6ExecuteModule.sol

395:             allowedStandard == bytes4(type(uint32).max) ||

414:             allowedFunction == bytes4(type(uint32).max) ||
File: /contracts/LSP6KeyManager/LSP6Modules/LSP6SetDataModule.sol

544:             length = uint16(

664:             length = uint16(
File: /contracts/LSP7DigitalAsset/ILSP7DigitalAsset.sol

65:     function decimals() external view returns (uint8);
File: /contracts/LSP7DigitalAsset/LSP7DigitalAssetCore.sol

54:     function decimals() public view virtual returns (uint8) {

[GAS-14] Use != 0 instead of > 0 for unsigned integer comparison

Description:

To update this with using at least 0.8.6 there is no difference in gas usage with!= 0 or > 0. Source

Proof Of Concept
File: /contracts/LSP0ERC725Account/LSP0ERC725AccountCore.sol

182:                 if (result.length > 0) {

741:         if (_owner.code.length > 0) {
File: /contracts/LSP1UniversalReceiver/LSP1UniversalReceiverDelegateUP/LSP1UniversalReceiverDelegateUP.sol

165:             if (notifier.code.length > 0) {
File: /contracts/LSP20CallVerification/LSP20CallVerification.sol

86:         if (returnedData.length > 0) {
File: /contracts/LSP7DigitalAsset/LSP7DigitalAssetCore.sol

491:             if (to.code.length > 0) {
File: /contracts/LSP8IdentifiableDigitalAsset/LSP8IdentifiableDigitalAssetCore.sol

493:             if (to.code.length > 0) {

[GAS-15] USE BYTES32 INSTEAD OF STRING

Description:

Use bytes32 instead of string to save gas whenever possible. String is a dynamic data structure and therefore is more gas consuming then bytes32.

Proof Of Concept
File: /contracts/LSP2ERC725YJSONSchema/LSP2Utils.sol

23:         string memory keyName

33:         string memory keyName

72:         string memory firstWord,

73:         string memory lastWord

95:         string memory firstWord,

137:         string memory firstWord,

138:         string memory secondWord,

200:         string memory hashFunction,

201:         string memory json,

202:         string memory url

217:         string memory hashFunction,

218:         string memory assetBytes,

219:         string memory url
File: /contracts/LSP4DigitalAssetMetadata/ILSP4Compatibility.sol

18:     function name() external view returns (string memory);

24:     function symbol() external view returns (string memory);
File: /contracts/LSP4DigitalAssetMetadata/LSP4Compatibility.sol

25:     function name() public view virtual override returns (string memory) {

27:         return string(data);

34:     function symbol() public view virtual override returns (string memory) {

36:         return string(data);
File: /contracts/LSP4DigitalAssetMetadata/LSP4DigitalAssetMetadata.sol

32:         string memory name_,

33:         string memory symbol_,
File: /contracts/LSP4DigitalAssetMetadata/LSP4DigitalAssetMetadataInitAbstract.sol

28:         string memory name_,

29:         string memory symbol_,
File: /contracts/LSP6KeyManager/LSP6Modules/LSP6ExecuteModule.sol

445:             string memory permissionErrorString = LSP6Utils.getPermissionName(
File: /contracts/LSP6KeyManager/LSP6Modules/LSP6OwnershipModule.sol

24:             string memory permissionErrorString = LSP6Utils.getPermissionName(
File: /contracts/LSP6KeyManager/LSP6Modules/LSP6SetDataModule.sol

788:             string memory permissionErrorString = LSP6Utils.getPermissionName(
File: /contracts/LSP7DigitalAsset/LSP7DigitalAsset.sol

40:         string memory name_,

41:         string memory symbol_,
File: /contracts/LSP7DigitalAsset/LSP7DigitalAssetInitAbstract.sol

29:         string memory name_,

30:         string memory symbol_,
File: /contracts/LSP8IdentifiableDigitalAsset/LSP8IdentifiableDigitalAsset.sol

37:         string memory name_,

38:         string memory symbol_,
File: /contracts/LSP8IdentifiableDigitalAsset/LSP8IdentifiableDigitalAssetInitAbstract.sol

31:         string memory name_,

32:         string memory symbol_,

[GAS-16] Public functions not called by the contract should be declared external instead OR Functions not used internally could be marked external

Description:

Contracts are allowed to override their parents’ functions and change the visibility from external to public and can save gas by doing so.

Proof Of Concept
File: /contracts/LSP0ERC725Account/LSP0ERC725AccountCore.sol

171:     function batchCalls(

#0 - c4-judge

2023-08-02T09:11:20Z

trust1995 marked the issue as grade-b

AuditHub

A portfolio for auditors, a security profile for protocols, a hub for web3 security.

Built bymalatrax © 2024

Auditors

Browse

Contests

Browse

Get in touch

ContactTwitter