LUKSO - Rolezn'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: 6/22

Findings: 2

Award: $714.09

QA:
grade-a
Gas:
grade-a

🌟 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-a
QA (Quality Assurance)
Q-04

Awards

421.2796 USDC - $421.28

External Links

QA Summary<a name="QA Summary">

Low Risk Issues

IssueContexts
LOW‑1Double type casts create complexity within the code2
LOW‑2Constructor is missing zero address check1
LOW‑3Assembly calldata forwarded to external contract is missing contract existence checks2
LOW‑4Missing Checks for Address(0x0)1
LOW‑5Contracts are designed to receive ETH but do not implement function for withdrawal1
LOW‑6Unnecessary Low level calls should be avoided1
LOW‑7Empty receive()/payable fallback() function does not authorize requests3

Total: 11 contexts over 7 issues

Non-critical Issues

IssueContexts
NC‑1Event emit should emit a parameter2
NC‑2Function creates dirty bits2
NC‑3Generate perfect code headers for better solidity code layout and readability7
NC‑4Missing event for critical parameter change2
NC‑5Consider moving msg.sender checks to a common authorization modifier9
NC‑6Non-external/public function names should begin with an underscore37
NC‑7override function arguments that are unused should have the variable name removed or commented out to avoid compiler warnings1
NC‑8Using underscore at the end of variable name8
NC‑9Unusual loop variable4
NC‑10Use named function calls1
NC‑11Use of _renounceOwnership can lead to unexpected behaviors10
NC‑12Use SMTChecker1

Total: 84 contexts over 12 issues

Low Risk Issues

<a href="#qa-summary">[LOW‑1]</a><a name="LOW&#x2011;1"> Double type casts create complexity within the code

Double type casting should be avoided in Solidity contracts to prevent unintended consequences and ensure accurate data representation. Performing multiple type casts in succession can lead to unexpected truncation, rounding errors, or loss of precision, potentially compromising the contract's functionality and reliability. Furthermore, double type casting can make the code less readable and harder to maintain, increasing the likelihood of errors and misunderstandings during development and debugging. To ensure precise and consistent data handling, developers should use appropriate data types and avoid unnecessary or excessive type casting, promoting a more robust and dependable contract execution.

<ins>Proof Of Concept</ins>
File: LSP1UniversalReceiverDelegateUP.sol

139: uint128 arrayIndex = uint128(uint160(bytes20(notifierMapValue)));

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP1UniversalReceiver/LSP1UniversalReceiverDelegateUP/LSP1UniversalReceiverDelegateUP.sol#L139

File: LSP2Utils.sol

296: if (uint224(uint256(key)) != 0) return false;

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP2ERC725YJSONSchema/LSP2Utils.sol#L296

<a href="#qa-summary">[LOW‑2]</a><a name="LOW&#x2011;2"> Constructor is missing zero address check

In Solidity, constructors often take address parameters to initialize important components of a contract, such as owner or linked contracts. However, without a check, there's a risk that an address parameter could be mistakenly set to the zero address (0x0). This could occur due to a mistake or oversight during contract deployment. A zero address in a crucial role can cause serious issues, as it cannot perform actions like a normal address, and any funds sent to it are irretrievable. Therefore, it's crucial to include a zero address check in constructors to prevent such potential problems. If a zero address is detected, the constructor should revert the transaction.

<ins>Proof Of Concept</ins>
File: LSP7DigitalAsset.sol

39: constructor: bool isNonDivisible_

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP7DigitalAsset/LSP7DigitalAsset.sol#L39

<a href="#qa-summary">[LOW‑3]</a><a name="LOW&#x2011;3"> Assembly calldata forwarded to external contract is missing contract existence checks

Low-level calls return success if there is no code present at the specified address. In addition to the zero-address checks, add a check to verify that extcodesize() is non-zero.

<ins>Proof Of Concept</ins>
File: LSP0ERC725AccountCore.sol

821: let success := call(

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP0ERC725Account/LSP0ERC725AccountCore.sol#L821

File: LSP17Extendable.sol

108: let success := call(

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP17ContractExtension/LSP17Extendable.sol#L108

<a href="#qa-summary">[LOW‑4]</a><a name="LOW&#x2011;4"> Missing Checks for Address(0x0)

Lack of zero-address validation on address parameters may lead to transaction reverts, waste gas, require resubmission of transactions and may even force contract redeployments in certain cases within the protocol.

<ins>Proof Of Concept</ins>
File: LSP1Utils.sol

41: function callUniversalReceiverWithCallerInfos: address universalReceiverDelegate

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP1UniversalReceiver/LSP1Utils.sol#L41

<ins>Recommended Mitigation Steps</ins>

Consider adding explicit zero-address validation on input parameters of address type.

<a href="#qa-summary">[LOW‑5]</a><a name="LOW&#x2011;5"> Contracts are designed to receive ETH but do not implement function for withdrawal

The following contracts can receive ETH but can not withdraw, ETH is occasionally sent by users will be stuck in those contracts. This functionality also applies to baseTokens resulting in locked tokens and loss of funds.

<ins>Proof Of Concept</ins>
File: LSP0ERC725AccountCore.sol

117: receive() external payable virtual {

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP0ERC725Account/LSP0ERC725AccountCore.sol#L117

<ins>Recommended Mitigation Steps</ins>

Provide a rescue ETH and rescueTokens function

<a href="#qa-summary">[LOW‑6]</a><a name="LOW&#x2011;6"> Unnecessary Low level calls should be avoided

Avoid making unnecessary low-level calls to the system whenever possible, as they function differently from contract-type calls. For instance: Using address.call(abi.encodeWithSelector("fancy(bytes32)", mybytes) does not confirm whether the target is genuinely a contract, whereas ContractInterface(address).fancy(mybytes) does.

Moreover, when invoking functions declared as view/pure, the Solidity compiler executes a staticcall, offering extra security guarantees that are absent in low-level calls. Additionally, return values must be manually decoded when making low-level calls.

Note: If a low-level call is required, consider using Contract.function.selector instead of employing a hardcoded ABI string for encoding.

<ins>Proof Of Concept</ins>
File: LSP20CallVerification.sol


function _verifyCall(
        address logicVerifier
    ) internal virtual returns (bool verifyAfter) {
        (bool success, bytes memory returnedData) = logicVerifier.call(
            abi.encodeWithSelector(
                ILSP20.lsp20VerifyCall.selector,
                msg.sender,
                msg.value,
                msg.data
            )
        );

        _validateCall(false, success, returnedData);

        bytes4 magicValue = abi.decode(returnedData, (bytes4));

        if (bytes3(magicValue) != bytes3(ILSP20.lsp20VerifyCall.selector))
            revert LSP20InvalidMagicValue(false, returnedData);

        return bytes1(magicValue[3]) == 0x01 ? true : false;
    }

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP20CallVerification/LSP20CallVerification.sol#L26

<ins>Recommended Mitigation Steps</ins>

When reaching out to a known contract within the system, always opt for typed contract calls (interfaces/contracts) rather than low-level calls. This approach helps prevent mistakes, potentially unverified return values, and ensures security guarantees.

<a href="#qa-summary">[LOW‑7]</a><a name="LOW&#x2011;7"> Empty receive()/payable fallback() function does not authorize requests

If the intention is for the Ether to be used, the function should call another function, otherwise it should revert (e.g. require(msg.sender == address(weth))). Having no access control on the function means that someone may send Ether to the contract, and have no way to get anything back out, which is a loss of funds. If the concern is having to spend a small amount of gas to check the sender against an immutable address, the code should at least have a function to rescue unused Ether.

<ins>Proof Of Concept</ins>
File: ERC725.sol

18: receive() external payable {}

https://github.com/code-423n4/2023-06-lukso/tree/main/submodules/ERC725/implementations/contracts/ERC725.sol#L18

File: ERC725Init.sol

12: receive() external payable {}

https://github.com/code-423n4/2023-06-lukso/tree/main/submodules/ERC725/implementations/contracts/ERC725Init.sol#L12

File: ERC725InitAbstract.sol

34: receive() external payable {}

https://github.com/code-423n4/2023-06-lukso/tree/main/submodules/ERC725/implementations/contracts/ERC725InitAbstract.sol#L34

Non Critical Issues

<a href="#qa-summary">[NC‑1]</a><a name="NC&#x2011;1"> Event emit should emit a parameter

Some emitted events do not have any emitted parameters. It is recommended to add some parameter such as state changes or value changes when events are emitted

<ins>Proof Of Concept</ins>
File: LSP14Ownable2Step.sol

165: emit RenounceOwnershipStarted()
178: emit OwnershipRenounced()

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP14Ownable2Step/LSP14Ownable2Step.sol#L165

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP14Ownable2Step/LSP14Ownable2Step.sol#L178

<a href="#qa-summary">[NC‑2]</a><a name="NC&#x2011;2"> Function creates dirty bits

This explanation should be added in the NatSpec comments of this function that sends ether with call;

Note that this code probably isn’t secure or a good use case for assembly because a lot of memory management and security checks are bypassed. Use with caution! Some functions in this contract knowingly create dirty bits at the destination of the free memory pointer.

<ins>Proof Of Concept</ins>
File: LSP0ERC725AccountCore.sol

821: function _fallbackLSP17Extendable() internal virtual override {
        
        address extension = _getExtension(msg.sig);

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

        
        if (extension == address(0))
            revert NoExtensionFoundForFunctionSelector(msg.sig);

        
        
        
        assembly {
            calldatacopy(0, 0, calldatasize())

            
            
            mstore(calldatasize(), shl(96, caller()))

            
            mstore(add(calldatasize(), 20), callvalue())

            
            let success := call(
                gas(),
                extension,
                0,
                0,
                add(calldatasize(), 52),
                0,
                0
            )

            
            returndatacopy(0, 0, returndatasize())

            switch success
            
            case 0 {
                revert(0, returndatasize())
            }
            default {
                return(0, returndatasize())
            }
        }
    }

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP0ERC725Account/LSP0ERC725AccountCore.sol#L821

File: LSP17Extendable.sol

108: function _getExtension(
        bytes4 functionSelector
    ) internal view virtual returns (address);

    
    function _fallbackLSP17Extendable() internal virtual {
        
        address extension = _getExtension(msg.sig);

        
        if (extension == address(0))
            revert NoExtensionFoundForFunctionSelector(msg.sig);

        
        
        
        assembly {
            calldatacopy(0, 0, calldatasize())

            
            
            mstore(calldatasize(), shl(96, caller()))

            
            mstore(add(calldatasize(), 20), callvalue())

            
            let success := call(
                gas(),
                extension,
                0,
                0,
                add(calldatasize(), 52),
                0,
                0
            )

            
            returndatacopy(0, 0, returndatasize())

            switch success
            
            case 0 {
                revert(0, returndatasize())
            }
            default {
                return(0, returndatasize())
            }
        }
    }
}

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP17ContractExtension/LSP17Extendable.sol#L108

<ins>Recommended Mitigation Steps</ins>

Add this comment to the function:

/// @dev Use with caution! Some functions in this contract knowingly create dirty bits at the destination of the free memory pointer. Note that this code probably isn’t secure or a good use case for assembly because a lot of memory management and security checks are bypassed.

<a href="#qa-summary">[NC‑3]</a><a name="NC&#x2011;3"> Generate perfect code headers for better solidity code layout and readability

It is recommended to use pre-made headers for Solidity code layout and readability: https://github.com/transmissions11/headers

/*//////////////////////////////////////////////////////////////
                           TESTING 123
//////////////////////////////////////////////////////////////*/
<ins>Proof Of Concept</ins>
<details>
File: LSP14Ownable2Step.sol

5: LSP14Ownable2Step.sol

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP14Ownable2Step/LSP14Ownable2Step.sol#L5

File: LSP4Compatibility.sol

5: LSP4Compatibility.sol

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP4DigitalAssetMetadata/LSP4Compatibility.sol#L5

File: LSP7CompatibleERC20.sol

6: LSP7CompatibleERC20.sol

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP7DigitalAsset/extensions/LSP7CompatibleERC20.sol#L6

File: LSP7Mintable.sol

6: LSP7Mintable.sol

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP7DigitalAsset/presets/LSP7Mintable.sol#L6

File: LSP8CompatibleERC721.sol

9: LSP8CompatibleERC721.sol
43: LSP8CompatibleERC721.sol

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721.sol#L9

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721.sol#L43

File: LSP8Mintable.sol

6: LSP8Mintable.sol

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP8IdentifiableDigitalAsset/presets/LSP8Mintable.sol#L6

</details>

<a href="#qa-summary">[NC‑4]</a><a name="NC&#x2011;4"> Missing event for critical parameter change

When changing state variables events are not emitted. Emitting events allows monitoring activities with off-chain monitoring tools.

<ins>Proof Of Concept</ins>
File: LSP6Utils.sol

150: function setDataViaKeyManager(

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP6KeyManager/LSP6Utils.sol#L150

File: ERC725YCore.sol

73: function setDataBatch(

https://github.com/code-423n4/2023-06-lukso/tree/main/submodules/ERC725/implementations/contracts/ERC725YCore.sol#L73

<a href="#qa-summary">[NC‑5]</a><a name="NC&#x2011;5"> Consider moving msg.sender checks to a common authorization modifier

<ins>Proof Of Concept</ins>
<details>
File: LSP0ERC725AccountCore.sol

235: if (msg.sender == _owner) {
293: if (msg.sender == _owner) {
350: if (msg.sender == _owner) {
395: if (msg.sender == _owner) {
663: if (msg.sender == _owner) {

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP0ERC725Account/LSP0ERC725AccountCore.sol#L235

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP0ERC725Account/LSP0ERC725AccountCore.sol#L293

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP0ERC725Account/LSP0ERC725AccountCore.sol#L350

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP0ERC725Account/LSP0ERC725AccountCore.sol#L395

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP0ERC725Account/LSP0ERC725AccountCore.sol#L663

File: LSP0ERC725AccountCore.sol

563: if (msg.sender == currentOwner) {

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP0ERC725Account/LSP0ERC725AccountCore.sol#L563

File: LSP6KeyManagerCore.sol

265: if (msg.sender == _target) {
309: if (msg.sender == _target) {

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP6KeyManager/LSP6KeyManagerCore.sol#L265

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP6KeyManager/LSP6KeyManagerCore.sol#L309

File: OwnableUnset.sol

61: require(owner() == msg.sender, "Ownable: caller is not the owner");

https://github.com/code-423n4/2023-06-lukso/tree/main/submodules/ERC725/implementations/contracts/custom/OwnableUnset.sol#L61

</details>

<a href="#qa-summary">[NC‑6]</a><a name="NC&#x2011;6"> Non-external/public function names should begin with an underscore

According to the Solidity Style Guide, Non-external/public function names should begin with an <a href="https://docs.soliditylang.org/en/latest/style-guide.html#underscore-prefix-for-non-external-functions-and-variables">underscore</a>

<ins>Proof Of Concept</ins>
<details>
File: LSP0Utils.sol

24: function getLSP1DelegateValue(
        mapping(bytes32 => bytes) storage erc725YStorage
    ) internal view returns (bytes memory) {

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP0ERC725Account/LSP0Utils.sol#L24

File: LSP0Utils.sol

37: function getLSP1DelegateValueForTypeId(
        mapping(bytes32 => bytes) storage erc725YStorage,
        bytes32 typeId
    ) internal view returns (bytes memory) {

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP0ERC725Account/LSP0Utils.sol#L37

File: LSP10Utils.sol

63: function generateReceivedVaultKeys(
        address receiver,
        address vault,
        bytes32 vaultMapKey
    ) internal view returns (bytes32[] memory keys, bytes[] memory values) {

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP10ReceivedVaults/LSP10Utils.sol#L63

File: LSP10Utils.sol

115: function generateSentVaultKeys(
        address sender,
        bytes32 vaultMapKey,
        uint128 vaultIndex
    ) internal view returns (bytes32[] memory keys, bytes[] memory values) {

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP10ReceivedVaults/LSP10Utils.sol#L115

File: LSP10Utils.sol

233: function getLSP10ReceivedVaultsCount(
        IERC725Y account
    ) internal view returns (bytes memory) {

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP10ReceivedVaults/LSP10Utils.sol#L233

File: LSP17Utils.sol

13: function isExtension(
        uint256 parametersLengthWithOffset,
        uint256 msgDataLength
    ) internal pure returns (bool) {

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP17ContractExtension/LSP17Utils.sol#L13

File: LSP1Utils.sol

22: function tryNotifyUniversalReceiver(
        address lsp1Implementation,
        bytes32 typeId,
        bytes memory data
    ) internal {

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP1UniversalReceiver/LSP1Utils.sol#L22

File: LSP1Utils.sol

40: function callUniversalReceiverWithCallerInfos(
        address universalReceiverDelegate,
        bytes32 typeId,
        bytes calldata receivedData,
        address msgSender,
        uint256 msgValue
    ) internal returns (bytes memory) {

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP1UniversalReceiver/LSP1Utils.sol#L40

File: LSP1Utils.sol

72: function getTransferDetails(
        bytes32 typeId
    )
        internal
        pure
        returns (
            bool invalid,
            bytes10 mapPrefix,
            bytes4 interfaceId,
            bool isReceiving
        )
    {

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP1UniversalReceiver/LSP1Utils.sol#L72

File: LSP2Utils.sol

22: function generateSingletonKey(
        string memory keyName
    ) internal pure returns (bytes32) {

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP2ERC725YJSONSchema/LSP2Utils.sol#L22

File: LSP2Utils.sol

32: function generateArrayKey(
        string memory keyName
    ) internal pure returns (bytes32) {

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP2ERC725YJSONSchema/LSP2Utils.sol#L32

File: LSP2Utils.sol

52: function generateArrayElementKeyAtIndex(
        bytes32 arrayKey,
        uint128 index
    ) internal pure returns (bytes32) {

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP2ERC725YJSONSchema/LSP2Utils.sol#L52

File: LSP2Utils.sol

71: function generateMappingKey(
        string memory firstWord,
        string memory lastWord
    ) internal pure returns (bytes32) {

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP2ERC725YJSONSchema/LSP2Utils.sol#L71

File: LSP2Utils.sol

94: function generateMappingKey(
        string memory firstWord,
        address addr
    ) internal pure returns (bytes32) {

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP2ERC725YJSONSchema/LSP2Utils.sol#L94

File: LSP2Utils.sol

115: function generateMappingKey(
        bytes10 keyPrefix,
        bytes20 bytes20Value
    ) internal pure returns (bytes32) {

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP2ERC725YJSONSchema/LSP2Utils.sol#L115

File: LSP2Utils.sol

136: function generateMappingWithGroupingKey(
        string memory firstWord,
        string memory secondWord,
        address addr
    ) internal pure returns (bytes32) {

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP2ERC725YJSONSchema/LSP2Utils.sol#L136

File: LSP2Utils.sol

161: function generateMappingWithGroupingKey(
        bytes6 keyPrefix,
        bytes4 mapPrefix,
        bytes20 subMapKey
    ) internal pure returns (bytes32) {

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP2ERC725YJSONSchema/LSP2Utils.sol#L161

File: LSP2Utils.sol

181: function generateMappingWithGroupingKey(
        bytes10 keyPrefix,
        bytes20 bytes20Value
    ) internal pure returns (bytes32) {

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP2ERC725YJSONSchema/LSP2Utils.sol#L181

File: LSP2Utils.sol

199: function generateJSONURLValue(
        string memory hashFunction,
        string memory json,
        string memory url
    ) internal pure returns (bytes memory) {

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP2ERC725YJSONSchema/LSP2Utils.sol#L199

File: LSP2Utils.sol

216: function generateASSETURLValue(
        string memory hashFunction,
        string memory assetBytes,
        string memory url
    ) internal pure returns (bytes memory) {

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP2ERC725YJSONSchema/LSP2Utils.sol#L216

File: LSP2Utils.sol

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

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP2ERC725YJSONSchema/LSP2Utils.sol#L231

File: LSP2Utils.sol

251: function isEncodedArrayOfAddresses(
        bytes memory data
    ) internal pure returns (bool) {

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP2ERC725YJSONSchema/LSP2Utils.sol#L251

File: LSP2Utils.sol

283: function isBytes4EncodedArray(
        bytes memory data
    ) internal pure returns (bool) {

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP2ERC725YJSONSchema/LSP2Utils.sol#L283

File: LSP2Utils.sol

312: function isCompactBytesArray(
        bytes memory compactBytesArray
    ) internal pure returns (bool) {

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP2ERC725YJSONSchema/LSP2Utils.sol#L312

File: LSP5Utils.sol

64: function generateReceivedAssetKeys(
        address receiver,
        address asset,
        bytes32 assetMapKey,
        bytes4 interfaceID
    ) internal view returns (bytes32[] memory keys, bytes[] memory values) {

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP5ReceivedAssets/LSP5Utils.sol#L64

File: LSP5Utils.sol

117: function generateSentAssetKeys(
        address sender,
        bytes32 assetMapKey,
        uint128 assetIndex
    ) internal view returns (bytes32[] memory keys, bytes[] memory values) {

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP5ReceivedAssets/LSP5Utils.sol#L117

File: LSP5Utils.sol

244: function getLSP5ReceivedAssetsCount(
        IERC725Y account
    ) internal view returns (bytes memory) {

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP5ReceivedAssets/LSP5Utils.sol#L244

File: LSP6Utils.sol

25: function getPermissionsFor(
        IERC725Y target,
        address caller
    ) internal view returns (bytes32) {

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP6KeyManager/LSP6Utils.sol#L25

File: LSP6Utils.sol

39: function getAllowedCallsFor(
        IERC725Y target,
        address from
    ) internal view returns (bytes memory) {

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP6KeyManager/LSP6Utils.sol#L39

File: LSP6Utils.sol

58: function getAllowedERC725YDataKeysFor(
        IERC725Y target,
        address caller
    ) internal view returns (bytes memory) {

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP6KeyManager/LSP6Utils.sol#L58

File: LSP6Utils.sol

78: function hasPermission(
        bytes32 addressPermission,
        bytes32 permissionToCheck
    ) internal pure returns (bool) {

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP6KeyManager/LSP6Utils.sol#L78

File: LSP6Utils.sol

91: function isCompactBytesArrayOfAllowedCalls(
        bytes memory allowedCallsCompacted
    ) internal pure returns (bool) {

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP6KeyManager/LSP6Utils.sol#L91

File: LSP6Utils.sol

120: function isCompactBytesArrayOfAllowedERC725YDataKeys(
        bytes memory allowedERC725YDataKeysCompacted
    ) internal pure returns (bool) {

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP6KeyManager/LSP6Utils.sol#L120

File: LSP6Utils.sol

150: function setDataViaKeyManager(
        address keyManagerAddress,
        bytes32[] memory keys,
        bytes[] memory values
    ) internal returns (bytes memory result) {

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP6KeyManager/LSP6Utils.sol#L150

File: LSP6Utils.sol

169: function combinePermissions(
        bytes32[] memory permissions
    ) internal pure returns (bytes32) {

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP6KeyManager/LSP6Utils.sol#L169

File: LSP6Utils.sol

194: function generateNewPermissionsKeys(
        IERC725Y account,
        address controller,
        bytes32 permissions
    ) internal view returns (bytes32[] memory keys, bytes[] memory values) {

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP6KeyManager/LSP6Utils.sol#L194

File: LSP6Utils.sol

226: function getPermissionName(
        bytes32 permission
    ) internal pure returns (string memory errorMessage) {

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP6KeyManager/LSP6Utils.sol#L226

</details>

<a href="#qa-summary">[NC‑7]</a><a name="NC&#x2011;7"> override function arguments that are unused should have the variable name removed or commented out to avoid compiler warnings

<ins>Proof Of Concept</ins>
File: LSP0ERC725AccountCore.sol

851: function _getExtension: bytes4 functionSelector

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP0ERC725Account/LSP0ERC725AccountCore.sol#L851

<a href="#qa-summary">[NC‑8]</a><a name="NC&#x2011;8"> 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.

<ins>Proof Of Concept</ins>
<details>
File: LSP6KeyManager.sol

20: target_;

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP6KeyManager/LSP6KeyManager.sol#L20

File: LSP6KeyManagerInitAbstract.sol

22: target_;

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP6KeyManager/LSP6KeyManagerInitAbstract.sol#L22

File: LSP7DigitalAsset.sol

45: isNonDivisible_;

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP7DigitalAsset/LSP7DigitalAsset.sol#L45

File: LSP7DigitalAssetInitAbstract.sol

34: isNonDivisible_;

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP7DigitalAsset/LSP7DigitalAssetInitAbstract.sol#L34

File: LSP7CappedSupply.sol

28: tokenSupplyCap_;

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP7DigitalAsset/extensions/LSP7CappedSupply.sol#L28

File: LSP7CappedSupplyInitAbstract.sol

28: tokenSupplyCap_;

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP7DigitalAsset/extensions/LSP7CappedSupplyInitAbstract.sol#L28

File: LSP8CappedSupply.sol

30: tokenSupplyCap_;

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CappedSupply.sol#L30

File: LSP8CappedSupplyInitAbstract.sol

30: tokenSupplyCap_;

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CappedSupplyInitAbstract.sol#L30

</details>

<a href="#qa-summary">[NC‑9]</a><a name="NC&#x2011;9"> Unusual loop variable

The normal name for loop variables is i, and when there is a nested loop, to use j. The code below chooses to use the variables differently, which may lead to confusion

<ins>Proof Of Concept</ins>
File: LSP2Utils.sol

251: function isEncodedArrayOfAddresses(
        bytes memory data
    ) internal pure returns (bool) {
        if (!isEncodedArray(data)) return false;

        uint256 offset = uint256(bytes32(data));
        uint256 arrayLength = data.toUint256(offset);

        uint256 pointer = offset + 32;

        for (uint256 ii = 0; ii < arrayLength; ) {
            bytes32 key = data.toBytes32(pointer);

            
            
            if (bytes12(key) != bytes12(0)) return false;

            
            pointer += 32;

            unchecked {
                ++ii;
            }
        }

        return true;
    }

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP2ERC725YJSONSchema/LSP2Utils.sol#L251

File: LSP2Utils.sol

283: function isBytes4EncodedArray(
        bytes memory data
    ) internal pure returns (bool) {
        if (!isEncodedArray(data)) return false;

        uint256 offset = uint256(bytes32(data));
        uint256 arrayLength = data.toUint256(offset);
        uint256 pointer = offset + 32;

        for (uint256 ii = 0; ii < arrayLength; ) {
            bytes32 key = data.toBytes32(pointer);

            
            if (uint224(uint256(key)) != 0) return false;

            
            pointer += 32;

            unchecked {
                ++ii;
            }
        }

        return true;
    }

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP2ERC725YJSONSchema/LSP2Utils.sol#L283

File: LSP6ExecuteModule.sol

245: function _verifyAllowedCall(
        address controlledContract,
        address controllerAddress,
        bytes calldata payload
    ) internal view virtual {
        (
            uint256 operationType,
            address to,
            uint256 value,
            bytes4 selector,
            bool isEmptyCall
        ) = _extractExecuteParameters(payload);

        
        bytes memory allowedCalls = ERC725Y(controlledContract)
            .getAllowedCallsFor(controllerAddress);

        if (allowedCalls.length == 0) {
            revert NoCallsAllowed(controllerAddress);
        }

        bytes4 requiredCallTypes = _extractCallType(
            operationType,
            value,
            isEmptyCall
        );

        for (uint256 ii = 0; ii < allowedCalls.length; ii += 34) {
            
            
            
            
            
            
            
            
            

            
            if (ii + 34 > allowedCalls.length) {
                revert InvalidEncodedAllowedCalls(allowedCalls);
            }

            
            bytes memory allowedCall = BytesLib.slice(allowedCalls, ii + 2, 32);

            
            
            
            if (
                bytes28(bytes32(allowedCall) << 32) ==
                bytes28(type(uint224).max)
            ) {
                revert InvalidWhitelistedCall(controllerAddress);
            }

            if (
                _isAllowedCallType(allowedCall, requiredCallTypes) &&
                _isAllowedAddress(allowedCall, to) &&
                _isAllowedStandard(allowedCall, to) &&
                _isAllowedFunction(allowedCall, selector)
            ) return;
        }

        revert NotAllowedCall(controllerAddress, to, selector);
    }

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP6KeyManager/LSP6Modules/LSP6ExecuteModule.sol#L245

File: LSP8IdentifiableDigitalAssetCore.sol

258: function _clearOperators(
        address tokenOwner,
        bytes32 tokenId
    ) internal virtual {
        
        
        
        
        
        
        EnumerableSet.AddressSet storage operatorsForTokenId = _operators[
            tokenId
        ];

        uint256 operatorListLength = operatorsForTokenId.length();
        for (uint256 i = 0; i < operatorListLength; ) {
            
            address operator = operatorsForTokenId.at(0);
            _revokeOperator(operator, tokenOwner, tokenId);

            unchecked {
                ++i;
            }
        }
    }

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP8IdentifiableDigitalAsset/LSP8IdentifiableDigitalAssetCore.sol#L258

<a href="#qa-summary">[NC‑10]</a><a name="NC&#x2011;10"> 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
    });
<ins>Proof Of Concept</ins>
File: ERC725XCore.sol

186: (bool success, bytes memory returnData) = target.call{value: value}(
            data
        );

https://github.com/code-423n4/2023-06-lukso/tree/main/submodules/ERC725/implementations/contracts/ERC725XCore.sol#L186

<a href="#qa-summary">[NC‑11]</a><a name="NC&#x2011;11"> Use of _renounceOwnership can lead to unexpected behaviors

Renouncing to the ownership of a contract can lead to unexpected behaviors. Method setAddresses can only be called once therefore, due to the call from the method to _renounceOwnership. Consider using a method to submit a proposal of new addresses, then another one to accept the proposal where _renounceOwnership is called at the end.

<ins>Proof Of Concept</ins>
File: LSP0ERC725AccountCore.sol

664: return LSP14Ownable2Step._renounceOwnership();
672: LSP14Ownable2Step._renounceOwnership();

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP0ERC725Account/LSP0ERC725AccountCore.sol#L664

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP0ERC725Account/LSP0ERC725AccountCore.sol#L672

File: LSP14Ownable2Step.sol

112: _renounceOwnership();

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP14Ownable2Step/LSP14Ownable2Step.sol#L112

File: LSP14Ownable2Step.sol

130: delete _renounceOwnershipStartedAt;
177: delete _renounceOwnershipStartedAt;

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP14Ownable2Step/LSP14Ownable2Step.sol#L130

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP14Ownable2Step/LSP14Ownable2Step.sol#L177

File: LSP14Ownable2Step.sol

150: function _renounceOwnership() internal virtual {
152: uint256 confirmationPeriodStart = _renounceOwnershipStartedAt +
158: _renounceOwnershipStartedAt == 0
161: _renounceOwnershipStartedAt == 0
163: _renounceOwnershipStartedAt = currentBlock;

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP14Ownable2Step/LSP14Ownable2Step.sol#L150

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP14Ownable2Step/LSP14Ownable2Step.sol#L152

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP14Ownable2Step/LSP14Ownable2Step.sol#L158

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP14Ownable2Step/LSP14Ownable2Step.sol#L161

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP14Ownable2Step/LSP14Ownable2Step.sol#L163

<a href="#qa-summary">[NC‑12]</a><a name="NC&#x2011;12"> Use SMTChecker

The highest tier of smart contract behavior assurance is formal mathematical verification. All assertions that are made are guaranteed to be true across all inputs → The quality of your asserts is the quality of your verification

https://twitter.com/0xOwenThurm/status/1614359896350425088?t=dbG9gHFigBX85Rv29lOjIQ&s=19

#0 - c4-judge

2023-08-02T09:46:17Z

trust1995 marked the issue as grade-a

Findings Information

Labels

bug
G (Gas Optimization)
grade-a
G-09

Awards

292.8073 USDC - $292.81

External Links

GAS Summary<a name="GAS Summary">

Gas Optimizations

IssueContextsEstimated Gas Saved
GAS‑1abi.encode() is less efficient than abi.encodepacked()3159
GAS‑2Consider activating via-ir for deploying1250
GAS‑3Use assembly to emit events481824
GAS‑4Counting down in for statements is more gas efficient143598
GAS‑5Using delete statement can save gas648
GAS‑6Use assembly to write address storage values141036
GAS‑7The result of a function call should be cached rather than re-calling the function251250
GAS‑8Help The Optimizer By Saving A Storage Variable's Reference Instead Of Repeatedly Fetching It13702
GAS‑9Usage of uints/ints smaller than 32 bytes (256 bits) incurs overhead1590
GAS‑10Use nested if and avoid multiple check combinations1484
GAS‑11Using Openzeppelin Ownable2Step.sol is more gas efficient432
GAS‑12Using XOR (^) and AND (&) bitwise equivalents1612093

Total: 326 contexts over 12 issues

Gas Optimizations

<a href="#gas-summary">[GAS‑1]</a><a name="GAS&#x2011;1"> abi.encode() is less efficient than abi.encodepacked()

See for more information: https://github.com/ConnorBlockchain/Solidity-Encode-Gas-Comparison

<ins>Proof Of Concept</ins>
File: LSP0ERC725AccountCore.sol

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

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP0ERC725Account/LSP0ERC725AccountCore.sol#L253

File: LSP0ERC725AccountCore.sol

319: abi.encode(results)

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP0ERC725Account/LSP0ERC725AccountCore.sol#L319

File: LSP0ERC725AccountCore.sol

528: returnedValues = abi.encode(

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP0ERC725Account/LSP0ERC725AccountCore.sol#L528

Test Code
contract GasTest is DSTest { Contract0 c0; Contract1 c1; function setUp() public { c0 = new Contract0(); c1 = new Contract1(); } function testGas() public { c0.not_optimized(); c1.optimized(); } } contract Contract0 { string a = "Code4rena"; function not_optimized() public returns(bytes32){ return keccak256(abi.encode(a)); } } contract Contract1 { string a = "Code4rena"; function optimized() public returns(bytes32){ return keccak256(abi.encodePacked(a)); } }
Gas Test Report
Contract0 contract
Deployment CostDeployment Size
101871683
Function Nameminavgmedianmax# calls
not_optimized26612661266126611
Contract1 contract
Deployment CostDeployment Size
99465671
Function Nameminavgmedianmax# calls
optimized26082608260826081

<a href="#gas-summary">[GAS‑2]</a><a name="GAS&#x2011;2"> Consider activating via-ir for deploying

The IR-based code generator was introduced with an aim to not only allow code generation to be more transparent and auditable but also to enable more powerful optimization passes that span across functions.

You can enable it on the command line using --via-ir or with the option {"viaIR": true}.

This will take longer to compile, but you can just simple test it before deploying and if you got a better benchmark then you can add --via-ir to your deploy command

More on: https://docs.soliditylang.org/en/v0.8.17/ir-breaking-changes.html

<a href="#gas-summary">[GAS‑3]</a><a name="GAS&#x2011;3"> Use assembly to emit events

We can use assembly to emit events efficiently by utilizing scratch space and the free memory pointer. This will allow us to potentially avoid memory expansion costs. Note: In order to do this optimization safely, we will need to cache and restore the free memory pointer.

For example, for a generic emit event for eventSentAmountExample:

// uint256 id, uint256 value, uint256 amount
emit eventSentAmountExample(id, value, amount);

We can use the following assembly emit events:

        assembly {
            let memptr := mload(0x40)
            mstore(0x00, calldataload(0x44))
            mstore(0x20, calldataload(0xa4))
            mstore(0x40, amount)
            log1(
                0x00,
                0x60,
                // keccak256("eventSentAmountExample(uint256,uint256,uint256)")
                0xa622cf392588fbf2cd020ff96b2f4ebd9c76d7a4bc7f3e6b2f18012312e76bc3
            )
            mstore(0x40, memptr)
        }
<ins>Proof Of Concept</ins>
<details>
File: LSP0ERC725AccountCore.sol

229: emit ValueReceived(msg.sender, msg.value);

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP0ERC725Account/LSP0ERC725AccountCore.sol#L229

File: LSP0ERC725AccountCore.sol

287: emit ValueReceived(msg.sender, msg.value);

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP0ERC725Account/LSP0ERC725AccountCore.sol#L287

File: LSP0ERC725AccountCore.sol

344: emit ValueReceived(msg.sender, msg.value);

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP0ERC725Account/LSP0ERC725AccountCore.sol#L344

File: LSP0ERC725AccountCore.sol

385: emit ValueReceived(msg.sender, msg.value);

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP0ERC725Account/LSP0ERC725AccountCore.sol#L385

File: LSP0ERC725AccountCore.sol

465: emit ValueReceived(msg.sender, msg.value);

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP0ERC725Account/LSP0ERC725AccountCore.sol#L465

File: LSP0ERC725AccountCore.sol

566: emit OwnershipTransferStarted(currentOwner, pendingNewOwner);
566: emit OwnershipTransferStarted(currentOwner, pendingNewOwner);

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP0ERC725Account/LSP0ERC725AccountCore.sol#L566

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP0ERC725Account/LSP0ERC725AccountCore.sol#L566

File: LSP0ERC725AccountInitAbstract.sol

63: emit ValueReceived(msg.sender, msg.value);

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP0ERC725Account/LSP0ERC725AccountInitAbstract.sol#L63

File: LSP14Ownable2Step.sol

72: emit OwnershipTransferStarted(currentOwner, newOwner);

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP14Ownable2Step/LSP14Ownable2Step.sol#L72

File: LSP14Ownable2Step.sol

165: emit RenounceOwnershipStarted();
178: emit OwnershipRenounced();

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP14Ownable2Step/LSP14Ownable2Step.sol#L165

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP14Ownable2Step/LSP14Ownable2Step.sol#L178

File: LSP6KeyManagerCore.sol

269: emit VerifiedCall(caller, msgValue, bytes4(data));

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP6KeyManager/LSP6KeyManagerCore.sol#L269

File: LSP6KeyManagerCore.sol

334: emit VerifiedCall(msg.sender, msgValue, bytes4(payload));

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP6KeyManager/LSP6KeyManagerCore.sol#L334

File: LSP6KeyManagerCore.sol

400: emit VerifiedCall(signer, msgValue, bytes4(payload));

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP6KeyManager/LSP6KeyManagerCore.sol#L400

File: LSP7DigitalAssetCore.sol

279: emit AuthorizedOperator(operator, tokenOwner, amount);
281: emit RevokedOperator(operator, tokenOwner);

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP7DigitalAsset/LSP7DigitalAssetCore.sol#L279

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP7DigitalAsset/LSP7DigitalAssetCore.sol#L281

File: LSP7DigitalAssetCore.sol

375: emit Transfer(operator, from, address(0), amount, false, data);

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP7DigitalAsset/LSP7DigitalAssetCore.sol#L375

File: LSP7DigitalAssetCore.sol

422: emit Transfer(operator, from, to, amount, allowNonLSP1Recipient, data);

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP7DigitalAsset/LSP7DigitalAssetCore.sol#L422

File: LSP7CompatibleERC20.sol

113: emit Approval(tokenOwner, operator, amount);

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP7DigitalAsset/extensions/LSP7CompatibleERC20.sol#L113

File: LSP7CompatibleERC20.sol

123: emit Transfer(from, to, amount);

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP7DigitalAsset/extensions/LSP7CompatibleERC20.sol#L123

File: LSP7CompatibleERC20.sol

133: emit Transfer(address(0), to, amount);

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP7DigitalAsset/extensions/LSP7CompatibleERC20.sol#L133

File: LSP7CompatibleERC20.sol

142: emit Transfer(from, address(0), amount);

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP7DigitalAsset/extensions/LSP7CompatibleERC20.sol#L142

File: LSP7CompatibleERC20InitAbstract.sol

121: emit Approval(tokenOwner, operator, amount);

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP7DigitalAsset/extensions/LSP7CompatibleERC20InitAbstract.sol#L121

File: LSP7CompatibleERC20InitAbstract.sol

131: emit Transfer(from, to, amount);

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP7DigitalAsset/extensions/LSP7CompatibleERC20InitAbstract.sol#L131

File: LSP7CompatibleERC20InitAbstract.sol

141: emit Transfer(address(0), to, amount);

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP7DigitalAsset/extensions/LSP7CompatibleERC20InitAbstract.sol#L141

File: LSP7CompatibleERC20InitAbstract.sol

150: emit Transfer(from, address(0), amount);

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP7DigitalAsset/extensions/LSP7CompatibleERC20InitAbstract.sol#L150

File: LSP8IdentifiableDigitalAssetCore.sol

126: emit AuthorizedOperator(operator, tokenOwner, tokenId);

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP8IdentifiableDigitalAsset/LSP8IdentifiableDigitalAssetCore.sol#L126

File: LSP8IdentifiableDigitalAssetCore.sol

252: emit RevokedOperator(operator, tokenOwner, tokenId);

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP8IdentifiableDigitalAsset/LSP8IdentifiableDigitalAssetCore.sol#L252

File: LSP8IdentifiableDigitalAssetCore.sol

373: emit Transfer(operator, tokenOwner, address(0), tokenId, false, data);

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP8IdentifiableDigitalAsset/LSP8IdentifiableDigitalAssetCore.sol#L373

File: LSP8IdentifiableDigitalAssetCore.sol

424: emit Transfer(operator, from, to, tokenId, allowNonLSP1Recipient, data);

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP8IdentifiableDigitalAsset/LSP8IdentifiableDigitalAssetCore.sol#L424

File: LSP8CompatibleERC721.sol

157: emit Approval(tokenOwnerOf(bytes32(tokenId)), operator, tokenId);

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721.sol#L157

File: LSP8CompatibleERC721.sol

223: emit Approval(tokenOwnerOf(tokenId), operator, uint256(tokenId));

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721.sol#L223

File: LSP8CompatibleERC721.sol

242: emit Transfer(from, to, uint256(tokenId));

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721.sol#L242

File: LSP8CompatibleERC721.sol

265: emit Transfer(address(0), to, uint256(tokenId));

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721.sol#L265

File: LSP8CompatibleERC721.sol

275: emit Transfer(tokenOwner, address(0), uint256(tokenId));

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721.sol#L275

File: LSP8CompatibleERC721.sol

294: emit ApprovalForAll(tokensOwner, operator, approved);

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721.sol#L294

File: LSP8CompatibleERC721InitAbstract.sol

157: emit Approval(tokenOwnerOf(bytes32(tokenId)), operator, tokenId);

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721InitAbstract.sol#L157

File: LSP8CompatibleERC721InitAbstract.sol

223: emit Approval(tokenOwnerOf(tokenId), operator, uint256(tokenId));

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721InitAbstract.sol#L223

File: LSP8CompatibleERC721InitAbstract.sol

242: emit Transfer(from, to, uint256(tokenId));

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721InitAbstract.sol#L242

File: LSP8CompatibleERC721InitAbstract.sol

265: emit Transfer(address(0), to, uint256(tokenId));

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721InitAbstract.sol#L265

File: LSP8CompatibleERC721InitAbstract.sol

275: emit Transfer(tokenOwner, address(0), uint256(tokenId));

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721InitAbstract.sol#L275

File: LSP8CompatibleERC721InitAbstract.sol

294: emit ApprovalForAll(tokensOwner, operator, approved);

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721InitAbstract.sol#L294

File: ERC725XCore.sol

183: emit Executed(OPERATION_0_CALL, target, value, bytes4(data));

https://github.com/code-423n4/2023-06-lukso/tree/main/submodules/ERC725/implementations/contracts/ERC725XCore.sol#L183

File: ERC725XCore.sol

207: emit Executed(OPERATION_3_STATICCALL, target, 0, bytes4(data));

https://github.com/code-423n4/2023-06-lukso/tree/main/submodules/ERC725/implementations/contracts/ERC725XCore.sol#L207

File: ERC725XCore.sol

229: emit Executed(OPERATION_4_DELEGATECALL, target, 0, bytes4(data));

https://github.com/code-423n4/2023-06-lukso/tree/main/submodules/ERC725/implementations/contracts/ERC725XCore.sol#L229

File: ERC725XCore.sol

307: emit ContractCreated(OPERATION_2_CREATE2, contractAddress, value, salt);

https://github.com/code-423n4/2023-06-lukso/tree/main/submodules/ERC725/implementations/contracts/ERC725XCore.sol#L307

File: ERC725YCore.sol

109: emit DataChanged(dataKey, dataValue);

https://github.com/code-423n4/2023-06-lukso/tree/main/submodules/ERC725/implementations/contracts/ERC725YCore.sol#L109

File: OwnableUnset.sol

72: emit OwnershipTransferred(oldOwner, newOwner);

https://github.com/code-423n4/2023-06-lukso/tree/main/submodules/ERC725/implementations/contracts/custom/OwnableUnset.sol#L72

</details>

<a href="#gas-summary">[GAS‑4]</a><a name="GAS&#x2011;4"> Counting down in for statements is more gas efficient

Counting down is more gas efficient than counting up because neither we are making zero variable to non-zero variable and also we will get gas refund in the last transaction when making non-zero to zero variable.

<ins>Proof Of Concept</ins>
<details>
File: LSP0ERC725AccountCore.sol

175: for (uint256 i; i < data.length; ) {

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP0ERC725Account/LSP0ERC725AccountCore.sol#L175

File: LSP0ERC725AccountCore.sol

396: for (uint256 i = 0; i < dataKeys.length; ) {

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP0ERC725Account/LSP0ERC725AccountCore.sol#L396

File: LSP2Utils.sol

261: for (uint256 ii = 0; ii < arrayLength; ) {

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP2ERC725YJSONSchema/LSP2Utils.sol#L261

File: LSP2Utils.sol

292: for (uint256 ii = 0; ii < arrayLength; ) {

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP2ERC725YJSONSchema/LSP2Utils.sol#L292

File: LSP6KeyManagerCore.sol

163: for (uint256 ii = 0; ii < payloads.length; ) {

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP6KeyManager/LSP6KeyManagerCore.sol#L163

File: LSP6KeyManagerCore.sol

223: for (uint256 ii = 0; ii < payloads.length; ) {

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP6KeyManager/LSP6KeyManagerCore.sol#L223

File: LSP6Utils.sol

173: for (uint256 i = 0; i < permissions.length; i++) {

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP6KeyManager/LSP6Utils.sol#L173

File: LSP6ExecuteModule.sol

272: for (uint256 ii = 0; ii < allowedCalls.length; ii += 34) {

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP6KeyManager/LSP6Modules/LSP6ExecuteModule.sol#L272

File: LSP7DigitalAssetCore.sol

171: for (uint256 i = 0; i < fromLength; ) {

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP7DigitalAsset/LSP7DigitalAssetCore.sol#L171

File: LSP8IdentifiableDigitalAssetCore.sol

227: for (uint256 i = 0; i < fromLength; ) {

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP8IdentifiableDigitalAsset/LSP8IdentifiableDigitalAssetCore.sol#L227

File: LSP8IdentifiableDigitalAssetCore.sol

273: for (uint256 i = 0; i < operatorListLength; ) {

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP8IdentifiableDigitalAsset/LSP8IdentifiableDigitalAssetCore.sol#L273

File: ERC725XCore.sol

150: for (uint256 i = 0; i < operationsType.length; ) {

https://github.com/code-423n4/2023-06-lukso/tree/main/submodules/ERC725/implementations/contracts/ERC725XCore.sol#L150

File: ERC725YCore.sol

47: for (uint256 i = 0; i < dataKeys.length; ) {

https://github.com/code-423n4/2023-06-lukso/tree/main/submodules/ERC725/implementations/contracts/ERC725YCore.sol#L47

File: ERC725YCore.sol

88: for (uint256 i = 0; i < dataKeys.length; ) {

https://github.com/code-423n4/2023-06-lukso/tree/main/submodules/ERC725/implementations/contracts/ERC725YCore.sol#L88

</details>
Test Code
contract GasTest is DSTest { Contract0 c0; Contract1 c1; function setUp() public { c0 = new Contract0(); c1 = new Contract1(); } function testGas() public { c0.AddNum(); c1.AddNum(); } } contract Contract0 { uint256 num = 3; function AddNum() public { uint256 _num = num; for(uint i=0;i<=9;i++){ _num = _num +1; } num = _num; } } contract Contract1 { uint256 num = 3; function AddNum() public { uint256 _num = num; for(uint i=9;i>=0;i--){ _num = _num +1; } num = _num; } }
Gas Test Report
Contract0 contract
Deployment CostDeployment Size
77011311
Function Nameminavgmedianmax# calls
AddNum70407040704070401
Contract1 contract
Deployment CostDeployment Size
73811295
Function Nameminavgmedianmax# calls
AddNum38193819381938191

<a href="#gas-summary">[GAS‑5]</a><a name="GAS&#x2011;5"> Using delete statement can save gas

<ins>Proof Of Concept</ins>
<details>
File: LSP2Utils.sol

328: uint256 pointer = 0;

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP2ERC725YJSONSchema/LSP2Utils.sol#L328

File: LSP6Utils.sol

94: uint256 pointer = 0;

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP6KeyManager/LSP6Utils.sol#L94

File: LSP6Utils.sol

123: uint256 pointer = 0;

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP6KeyManager/LSP6Utils.sol#L123

File: LSP6Utils.sol

172: uint256 result = 0;

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP6KeyManager/LSP6Utils.sol#L172

File: LSP6SetDataModule.sol

129: uint256 inputDataKeysAllowed = 0;
133: uint256 ii = 0;

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP6KeyManager/LSP6Modules/LSP6SetDataModule.sol#L129

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP6KeyManager/LSP6Modules/LSP6SetDataModule.sol#L133

</details>

<a href="#gas-summary">[GAS‑6]</a><a name="GAS&#x2011;6"> Use assembly to write address storage values

<ins>Proof Of Concept</ins>
<details>
File: LSP14Ownable2Step.sol

129: _pendingOwner = newOwner;

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP14Ownable2Step/LSP14Ownable2Step.sol#L129

File: LSP14Ownable2Step.sol

163: _renounceOwnershipStartedAt = currentBlock;

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP14Ownable2Step/LSP14Ownable2Step.sol#L163

File: LSP6KeyManager.sol

20: _target = target_;

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP6KeyManager/LSP6KeyManager.sol#L20

File: LSP6KeyManagerCore.sol

519: _reentrancyStatus = false;

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP6KeyManager/LSP6KeyManagerCore.sol#L519

File: LSP6KeyManagerCore.sol

553: _reentrancyStatus = false;

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP6KeyManager/LSP6KeyManagerCore.sol#L553

File: LSP6KeyManagerCore.sol

541: _reentrancyStatus = true;

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP6KeyManager/LSP6KeyManagerCore.sol#L541

File: LSP6KeyManagerInitAbstract.sol

22: _target = target_;

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP6KeyManager/LSP6KeyManagerInitAbstract.sol#L22

File: LSP7DigitalAsset.sol

45: _isNonDivisible = isNonDivisible_;

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP7DigitalAsset/LSP7DigitalAsset.sol#L45

File: LSP7DigitalAssetInitAbstract.sol

34: _isNonDivisible = isNonDivisible_;

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP7DigitalAsset/LSP7DigitalAssetInitAbstract.sol#L34

File: LSP7CappedSupply.sol

28: _tokenSupplyCap = tokenSupplyCap_;

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP7DigitalAsset/extensions/LSP7CappedSupply.sol#L28

File: LSP7CappedSupplyInitAbstract.sol

28: _tokenSupplyCap = tokenSupplyCap_;

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP7DigitalAsset/extensions/LSP7CappedSupplyInitAbstract.sol#L28

File: LSP8CappedSupply.sol

30: _tokenSupplyCap = tokenSupplyCap_;

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CappedSupply.sol#L30

File: LSP8CappedSupplyInitAbstract.sol

30: _tokenSupplyCap = tokenSupplyCap_;

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CappedSupplyInitAbstract.sol#L30

File: OwnableUnset.sol

71: _owner = newOwner;

https://github.com/code-423n4/2023-06-lukso/tree/main/submodules/ERC725/implementations/contracts/custom/OwnableUnset.sol#L71

</details>

<a href="#gas-summary">[GAS‑7]</a><a name="GAS&#x2011;7"> The result of a function call should be cached rather than re-calling the function

External calls are expensive. Results of external function calls should be cached rather than call them multiple times. Consider caching the following:

<ins>Proof Of Concept</ins>
<details>
File: LSP0ERC725AccountCore.sol

560: address currentOwner = owner();
577: currentOwner == owner(),
598: currentOwner == owner(),

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP0ERC725Account/LSP0ERC725AccountCore.sol#L560

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP0ERC725Account/LSP0ERC725AccountCore.sol#L577

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP0ERC725Account/LSP0ERC725AccountCore.sol#L598

File: LSP0ERC725AccountCore.sol

664: return LSP14Ownable2Step._renounceOwnership();
672: LSP14Ownable2Step._renounceOwnership();

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP0ERC725Account/LSP0ERC725AccountCore.sol#L664

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP0ERC725Account/LSP0ERC725AccountCore.sol#L672

File: LSP0ERC725AccountCore.sol

811: calldatacopy(0, 0, calldatasize())
815: mstore(calldatasize(), shl(96, caller()))
818: mstore(add(calldatasize(), 20), callvalue())
826: add(calldatasize(), 52),
832: returndatacopy(0, 0, returndatasize())
837: revert(0, returndatasize())
840: return(0, returndatasize())

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP0ERC725Account/LSP0ERC725AccountCore.sol#L811

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP0ERC725Account/LSP0ERC725AccountCore.sol#L815

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP0ERC725Account/LSP0ERC725AccountCore.sol#L818

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP0ERC725Account/LSP0ERC725AccountCore.sol#L826

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP0ERC725Account/LSP0ERC725AccountCore.sol#L832

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP0ERC725Account/LSP0ERC725AccountCore.sol#L837

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP0ERC725Account/LSP0ERC725AccountCore.sol#L840

File: LSP14Ownable2Step.sol

71: address currentOwner = owner();
79: currentOwner == owner(),

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP14Ownable2Step/LSP14Ownable2Step.sol#L71

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP14Ownable2Step/LSP14Ownable2Step.sol#L79

File: LSP17Extendable.sol

98: calldatacopy(0, 0, calldatasize())
102: mstore(calldatasize(), shl(96, caller()))
105: mstore(add(calldatasize(), 20), callvalue())
113: add(calldatasize(), 52),
119: returndatacopy(0, 0, returndatasize())
124: revert(0, returndatasize())
127: return(0, returndatasize())

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP17ContractExtension/LSP17Extendable.sol#L98

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP17ContractExtension/LSP17Extendable.sol#L102

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP17ContractExtension/LSP17Extendable.sol#L105

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP17ContractExtension/LSP17Extendable.sol#L113

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP17ContractExtension/LSP17Extendable.sol#L119

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP17ContractExtension/LSP17Extendable.sol#L124

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP17ContractExtension/LSP17Extendable.sol#L127

File: LSP8Enumerable.sol

37: uint256 index = totalSupply();
41: uint256 lastIndex = totalSupply() - 1;

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8Enumerable.sol#L37

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8Enumerable.sol#L41

File: LSP8EnumerableInitAbstract.sol

39: uint256 index = totalSupply();
43: uint256 lastIndex = totalSupply() - 1;

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8EnumerableInitAbstract.sol#L39

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8EnumerableInitAbstract.sol#L43

</details>

<a href="#gas-summary">[GAS‑8]</a><a name="GAS&#x2011;8"> Help The Optimizer By Saving A Storage Variable's Reference Instead Of Repeatedly Fetching It

To help the optimizer, declare a storage type variable and use it instead of repeatedly fetching the reference in a map or an array. The effect can be quite significant. As an example, instead of repeatedly calling someMap[someIndex], save its reference like this: SomeStruct storage someStruct = someMap[someIndex] and use it.

<ins>Proof Of Concept</ins>
File: LSP6KeyManagerCore.sol

164: if ((totalValues += values[ii]) > msg.value) {

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP6KeyManager/LSP6KeyManagerCore.sol#L164

File: LSP6KeyManagerCore.sol

168: results[ii] = _execute(values[ii], payloads[ii]);

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP6KeyManager/LSP6KeyManagerCore.sol#L168

File: LSP6KeyManagerCore.sol

224: if ((totalValues += values[ii]) > msg.value) {

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP6KeyManager/LSP6KeyManagerCore.sol#L224

File: LSP6KeyManagerCore.sol

229: signatures[ii],

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP6KeyManager/LSP6KeyManagerCore.sol#L229

File: LSP6KeyManagerCore.sol

230: nonces[ii],

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP6KeyManager/LSP6KeyManagerCore.sol#L230

File: LSP6KeyManagerCore.sol

231: validityTimestamps[ii],

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP6KeyManager/LSP6KeyManagerCore.sol#L231

File: LSP6KeyManagerCore.sol

232: values[ii],

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP6KeyManager/LSP6KeyManagerCore.sol#L232

File: LSP6KeyManagerCore.sol

233: payloads[ii]

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP6KeyManager/LSP6KeyManagerCore.sol#L233

File: LSP6SetDataModule.sol

667: allowedERC725YDataKeysCompacted[pointer],

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP6KeyManager/LSP6Modules/LSP6SetDataModule.sol#L667

File: LSP6SetDataModule.sol

729: if (validatedInputKeysList[ii]) {

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP6KeyManager/LSP6Modules/LSP6SetDataModule.sol#L729

File: LSP6SetDataModule.sol

737: if ((inputDataKeys[ii] & mask) == allowedKey) {

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP6KeyManager/LSP6Modules/LSP6SetDataModule.sol#L737

File: LSP6SetDataModule.sol

763: if (!validatedInputKeysList[jj]) {

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP6KeyManager/LSP6Modules/LSP6SetDataModule.sol#L763

File: LSP6SetDataModule.sol

766: inputDataKeys[jj]

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP6KeyManager/LSP6Modules/LSP6SetDataModule.sol#L766

<a href="#gas-summary">[GAS‑9]</a><a name="GAS&#x2011;9"> Usage of uints/ints smaller than 32 bytes (256 bits) incurs overhead

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.

https://docs.soliditylang.org/en/v0.8.11/internals/layout_in_storage.html 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

<ins>Proof Of Concept</ins>
<details>
File: LSP10Utils.sol

83: uint128 oldArrayLength = uint128(bytes16(encodedArrayLength));

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP10ReceivedVaults/LSP10Utils.sol#L83

File: LSP10Utils.sol

89: uint128 newArrayLength = oldArrayLength + 1;

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP10ReceivedVaults/LSP10Utils.sol#L89

File: LSP10Utils.sol

133: uint128 oldArrayLength = uint128(bytes16(lsp10VaultsCountValue));

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP10ReceivedVaults/LSP10Utils.sol#L133

File: LSP10Utils.sol

140: uint128 newArrayLength = oldArrayLength - 1;

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP10ReceivedVaults/LSP10Utils.sol#L140

File: LSP1Utils.sol

89: interfaceId = _INTERFACEID_LSP7;

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP1UniversalReceiver/LSP1Utils.sol#L89

File: LSP1Utils.sol

96: interfaceId = _INTERFACEID_LSP8;

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP1UniversalReceiver/LSP1Utils.sol#L96

File: LSP1Utils.sol

103: interfaceId = _INTERFACEID_LSP9;

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP1UniversalReceiver/LSP1Utils.sol#L103

File: LSP1UniversalReceiverDelegateUP.sol

139: uint128 arrayIndex = uint128(uint160(bytes20(notifierMapValue)));

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP1UniversalReceiver/LSP1UniversalReceiverDelegateUP/LSP1UniversalReceiverDelegateUP.sol#L139

File: LSP5Utils.sol

85: uint128 oldArrayLength = uint128(bytes16(encodedArrayLength));

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP5ReceivedAssets/LSP5Utils.sol#L85

File: LSP5Utils.sol

134: uint128 oldArrayLength = uint128(bytes16(lsp5ReceivedAssetsCountValue));

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP5ReceivedAssets/LSP5Utils.sol#L134

File: LSP5Utils.sol

137: uint128 newArrayLength = oldArrayLength - 1;

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP5ReceivedAssets/LSP5Utils.sol#L137

File: LSP6KeyManagerCore.sol

387: uint128 startingTimestamp = uint128(validityTimestamps >> 128);

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP6KeyManager/LSP6KeyManagerCore.sol#L387

File: LSP6KeyManagerCore.sol

388: uint128 endingTimestamp = uint128(validityTimestamps);

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP6KeyManager/LSP6KeyManagerCore.sol#L388

File: LSP6Utils.sol

205: uint128 newArrayLength = arrayLength + 1;

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP6KeyManager/LSP6Utils.sol#L205

File: LSP6SetDataModule.sol

346: uint128 newLength = uint128(bytes16(inputDataValue));

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP6KeyManager/LSP6Modules/LSP6SetDataModule.sol#L346

</details>

<a href="#gas-summary">[GAS‑10]</a><a name="GAS&#x2011;10"> Use nested if and avoid multiple check combinations

Using nested if, is cheaper than using && multiple check combinations. There are more advantages, such as easier to read code and better coverage reports.

<ins>Proof Of Concept</ins>
<details>
File: LSP0ERC725AccountCore.sol

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

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP0ERC725Account/LSP0ERC725AccountCore.sol#L801

File: LSP10Utils.sol

76: if (encodedArrayLength.length != 0 && encodedArrayLength.length != 16) {

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP10ReceivedVaults/LSP10Utils.sol#L76

File: LSP1UniversalReceiverDelegateUP.sol

227: if (dataKeys.length == 0 && dataValues.length == 0)

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP1UniversalReceiver/LSP1UniversalReceiverDelegateUP/LSP1UniversalReceiverDelegateUP.sol#L227

File: LSP5Utils.sol

78: if (encodedArrayLength.length != 0 && encodedArrayLength.length != 16) {

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP5ReceivedAssets/LSP5Utils.sol#L78

File: LSP6KeyManagerCore.sol

338: if (!isReentrantCall && !isSetData) {

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP6KeyManager/LSP6KeyManagerCore.sol#L338

File: LSP6KeyManagerCore.sol

404: if (!isReentrantCall && !isSetData) {

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP6KeyManager/LSP6KeyManagerCore.sol#L404

File: LSP6ExecuteModule.sol

165: if (isFundingContract && !hasSuperTransferValue) {

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP6KeyManager/LSP6Modules/LSP6ExecuteModule.sol#L165

File: LSP6ExecuteModule.sol

214: if (isTransferringValue && !hasSuperTransferValue) {
224: if (!hasSuperCall && !isCallDataPresent && !isTransferringValue) {
228: if (isCallDataPresent && !hasSuperCall) {
233: if (hasSuperCall && !isTransferringValue) return;
236: if (hasSuperTransferValue && !isCallDataPresent && isTransferringValue)
240: if (hasSuperCall && hasSuperTransferValue) return;

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP6KeyManager/LSP6Modules/LSP6ExecuteModule.sol#L214

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP6KeyManager/LSP6Modules/LSP6ExecuteModule.sol#L224

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP6KeyManager/LSP6Modules/LSP6ExecuteModule.sol#L228

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP6KeyManager/LSP6Modules/LSP6ExecuteModule.sol#L233

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP6KeyManager/LSP6Modules/LSP6ExecuteModule.sol#L236

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP6KeyManager/LSP6Modules/LSP6ExecuteModule.sol#L240

File: LSP6SetDataModule.sol

362: if (inputDataValue.length != 0 && inputDataValue.length != 20) {

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP6KeyManager/LSP6Modules/LSP6SetDataModule.sol#L362

</details>
Test Code
contract GasTest is DSTest { Contract0 c0; Contract1 c1; function setUp() public { c0 = new Contract0(); c1 = new Contract1(); } function testGas() public { c0.checkAge(19); c1.checkAgeOptimized(19); } } contract Contract0 { function checkAge(uint8 _age) public returns(string memory){ if(_age>18 && _age<22){ return "Eligible"; } } } contract Contract1 { function checkAgeOptimized(uint8 _age) public returns(string memory){ if(_age>18){ if(_age<22){ return "Eligible"; } } } }
Gas Test Report
Contract0 contract
Deployment CostDeployment Size
76923416
Function Nameminavgmedianmax# calls
checkAge6516516516511
Contract1 contract
Deployment CostDeployment Size
76323413
Function Nameminavgmedianmax# calls
checkAgeOptimized6456456456451

<a href="#gas-summary">[GAS‑11]</a><a name="GAS&#x2011;11"> Using Openzeppelin Ownable2Step.sol is more gas efficient

The project makes secure Owner changes using the following function:

<ins>Proof Of Concept</ins>
File: LSP0ERC725AccountCore.sol

624: function acceptOwnership() public virtual override {
        address previousOwner = owner();

        _acceptOwnership();

        
        previousOwner.tryNotifyUniversalReceiver(
            _TYPEID_LSP0_OwnershipTransferred_SenderNotification,
            ""
        );

        
        msg.sender.tryNotifyUniversalReceiver(
            _TYPEID_LSP0_OwnershipTransferred_RecipientNotification,
            ""
        );
    }

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP0ERC725Account/LSP0ERC725AccountCore.sol#L624

File: LSP14Ownable2Step.sol

87: function acceptOwnership() public virtual {
        address previousOwner = owner();

        _acceptOwnership();

        previousOwner.tryNotifyUniversalReceiver(
            _TYPEID_LSP14_OwnershipTransferred_SenderNotification,
            ""
        );

        msg.sender.tryNotifyUniversalReceiver(
            _TYPEID_LSP14_OwnershipTransferred_RecipientNotification,
            ""
        );
    }

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP14Ownable2Step/LSP14Ownable2Step.sol#L87

File: LSP14Ownable2Step.sol

136: function _acceptOwnership() internal virtual {
        require(
            msg.sender == pendingOwner(),
            "LSP14: caller is not the pendingOwner"
        );

        _setOwner(msg.sender);
        delete _pendingOwner;
    }

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP14Ownable2Step/LSP14Ownable2Step.sol#L136

However, it is recommended to use the more gas-optimized Openzeppelin project of Ownable2Step.sol as it is much more gas-efficient.

function acceptOwnership() public virtual {
        address sender = _msgSender();
        require(pendingOwner() == sender, "Ownable2Step: caller is not the new owner");
        _transferOwnership(sender);
    }

https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/Ownable2Step.sol

<a href="#gas-summary">[GAS‑12]</a><a name="GAS&#x2011;12"> Using XOR (^) and AND (&) bitwise equivalents

Given 4 variables a, b, c and d represented as such:

0 0 0 0 0 1 1 0 <- a 0 1 1 0 0 1 1 0 <- b 0 0 0 0 0 0 0 0 <- c 1 1 1 1 1 1 1 1 <- d

To have a == b means that every 0 and 1 match on both variables. Meaning that a XOR (operator ^) would evaluate to 0 ((a ^ b) == 0), as it excludes by definition any equalities.Now, if a != b, this means that there’s at least somewhere a 1 and a 0 not matching between a and b, making (a ^ b) != 0.Both formulas are logically equivalent and using the XOR bitwise operator costs actually the same amount of gas.However, it is much cheaper to use the bitwise OR operator (|) than comparing the truthy or falsy values.These are logically equivalent too, as the OR bitwise operator (|) would result in a 1 somewhere if any value is not 0 between the XOR (^) statements, meaning if any XOR (^) statement verifies that its arguments are different.

<ins>Proof Of Concept</ins>
<details>
File: LSP0ERC725AccountCore.sol

235: if (msg.sender == _owner) {

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP0ERC725Account/LSP0ERC725AccountCore.sol#L235

File: LSP0ERC725AccountCore.sol

293: if (msg.sender == _owner) {

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP0ERC725Account/LSP0ERC725AccountCore.sol#L293

File: LSP0ERC725AccountCore.sol

350: if (msg.sender == _owner) {

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP0ERC725Account/LSP0ERC725AccountCore.sol#L350

File: LSP0ERC725AccountCore.sol

395: if (msg.sender == _owner) {

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP0ERC725Account/LSP0ERC725AccountCore.sol#L395

File: LSP0ERC725AccountCore.sol

563: if (msg.sender == currentOwner) {
577: currentOwner == owner(),

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP0ERC725Account/LSP0ERC725AccountCore.sol#L563

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP0ERC725Account/LSP0ERC725AccountCore.sol#L577

File: LSP0ERC725AccountCore.sol

663: if (msg.sender == _owner) {

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP0ERC725Account/LSP0ERC725AccountCore.sol#L663

File: LSP0ERC725AccountCore.sol

702: interfaceId == _INTERFACEID_ERC1271 ||
703: interfaceId == _INTERFACEID_LSP0 ||
704: interfaceId == _INTERFACEID_LSP1 ||
705: interfaceId == _INTERFACEID_LSP14 ||
706: interfaceId == _INTERFACEID_LSP20_CALL_VERIFICATION ||

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP0ERC725Account/LSP0ERC725AccountCore.sol#L702-L706

File: LSP0ERC725AccountCore.sol

751: result.length == 32 &&
770: recoveredAddress == _owner

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP0ERC725Account/LSP0ERC725AccountCore.sol#L751

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP0ERC725Account/LSP0ERC725AccountCore.sol#L770

File: LSP0ERC725AccountCore.sol

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

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP0ERC725Account/LSP0ERC725AccountCore.sol#L801

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP0ERC725Account/LSP0ERC725AccountCore.sol#L804

File: LSP10Utils.sol

85: if (oldArrayLength == type(uint128).max) {

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP10ReceivedVaults/LSP10Utils.sol#L85

File: LSP10Utils.sol

149: if (vaultIndex == newArrayLength) {

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP10ReceivedVaults/LSP10Utils.sol#L149

File: LSP14Ownable2Step.sol

79: currentOwner == owner(),

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP14Ownable2Step/LSP14Ownable2Step.sol#L79

File: LSP14Ownable2Step.sol

127: if (newOwner == address(this)) revert CannotTransferOwnershipToSelf();

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP14Ownable2Step/LSP14Ownable2Step.sol#L127

File: LSP14Ownable2Step.sol

138: msg.sender == pendingOwner(),

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP14Ownable2Step/LSP14Ownable2Step.sol#L138

File: LSP14Ownable2Step.sol

158: _renounceOwnershipStartedAt == 0

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP14Ownable2Step/LSP14Ownable2Step.sol#L158

File: LSP17Extendable.sol

32: interfaceId == _INTERFACEID_LSP17_EXTENDABLE ||

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP17ContractExtension/LSP17Extendable.sol#L32

File: LSP17Extendable.sol

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

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP17ContractExtension/LSP17Extendable.sol#L50

File: LSP17Extendable.sol

91: if (extension == address(0))

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP17ContractExtension/LSP17Extendable.sol#L91

File: LSP17Extension.sol

24: interfaceId == _INTERFACEID_LSP17_EXTENSION ||

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP17ContractExtension/LSP17Extension.sol#L24

File: LSP1Utils.sol

85: typeId == _TYPEID_LSP7_TOKENSSENDER ||
86: typeId == _TYPEID_LSP7_TOKENSRECIPIENT
90: isReceiving = typeId == _TYPEID_LSP7_TOKENSRECIPIENT ? true : false;
92: typeId == _TYPEID_LSP8_TOKENSSENDER ||
93: typeId == _TYPEID_LSP8_TOKENSRECIPIENT
97: isReceiving = typeId == _TYPEID_LSP8_TOKENSRECIPIENT ? true : false;
99: typeId == _TYPEID_LSP9_OwnershipTransferred_SenderNotification ||
100: typeId == _TYPEID_LSP9_OwnershipTransferred_RecipientNotification

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP1UniversalReceiver/LSP1Utils.sol#L85

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP1UniversalReceiver/LSP1Utils.sol#L86

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP1UniversalReceiver/LSP1Utils.sol#L90

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP1UniversalReceiver/LSP1Utils.sol#L92

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP1UniversalReceiver/LSP1Utils.sol#L93

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP1UniversalReceiver/LSP1Utils.sol#L97

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP1UniversalReceiver/LSP1Utils.sol#L99

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP1UniversalReceiver/LSP1Utils.sol#L100

File: LSP1UniversalReceiverDelegateUP.sol

103: if (notifier == tx.origin) revert CannotRegisterEOAsAsAssets(notifier);

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP1UniversalReceiver/LSP1UniversalReceiverDelegateUP/LSP1UniversalReceiverDelegateUP.sol#L103

File: LSP1UniversalReceiverDelegateUP.sol

170: if (balance == 0) return "LSP1: balance not updated";

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP1UniversalReceiver/LSP1UniversalReceiverDelegateUP/LSP1UniversalReceiverDelegateUP.sol#L170

File: LSP1UniversalReceiverDelegateUP.sol

227: if (dataKeys.length == 0 && dataValues.length == 0)

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP1UniversalReceiver/LSP1UniversalReceiverDelegateUP/LSP1UniversalReceiverDelegateUP.sol#L227

File: LSP1UniversalReceiverDelegateUP.sol

263: interfaceId == _INTERFACEID_LSP1 ||

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP1UniversalReceiver/LSP1UniversalReceiverDelegateUP/LSP1UniversalReceiverDelegateUP.sol#L263

File: LSP2Utils.sol

346: if (pointer == compactBytesArray.length) return true;

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP2ERC725YJSONSchema/LSP2Utils.sol#L346

File: LSP4DigitalAssetMetadata.sol

56: if (dataKey == _LSP4_TOKEN_NAME_KEY) {
58: } else if (dataKey == _LSP4_TOKEN_SYMBOL_KEY) {

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP4DigitalAssetMetadata/LSP4DigitalAssetMetadata.sol#L56

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP4DigitalAssetMetadata/LSP4DigitalAssetMetadata.sol#L58

File: LSP4DigitalAssetMetadataInitAbstract.sol

54: if (dataKey == _LSP4_TOKEN_NAME_KEY) {
56: } else if (dataKey == _LSP4_TOKEN_SYMBOL_KEY) {

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP4DigitalAssetMetadata/LSP4DigitalAssetMetadataInitAbstract.sol#L54

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP4DigitalAssetMetadata/LSP4DigitalAssetMetadataInitAbstract.sol#L56

File: LSP5Utils.sol

87: if (oldArrayLength == type(uint128).max) {

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP5ReceivedAssets/LSP5Utils.sol#L87

File: LSP5Utils.sol

146: if (assetIndex == newArrayLength) {

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP5ReceivedAssets/LSP5Utils.sol#L146

File: LSP6KeyManagerCore.sol

98: interfaceId == _INTERFACEID_LSP6 ||
99: interfaceId == _INTERFACEID_ERC1271 ||
100: interfaceId == _INTERFACEID_LSP20_CALL_VERIFIER ||

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP6KeyManager/LSP6KeyManagerCore.sol#L98-L100

File: LSP6KeyManagerCore.sol

265: if (msg.sender == _target) {
273: isSetData || isReentrantCall

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP6KeyManager/LSP6KeyManagerCore.sol#L265

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP6KeyManager/LSP6KeyManagerCore.sol#L273

File: LSP6KeyManagerCore.sol

309: if (msg.sender == _target) {

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP6KeyManager/LSP6KeyManagerCore.sol#L309

File: LSP6KeyManagerCore.sol

463: if (permissions == bytes32(0)) revert NoPermissionsSet(from);
468: if (erc725Function == IERC725Y.setData.selector) {
484: } else if (erc725Function == IERC725Y.setDataBatch.selector) {
498: } else if (erc725Function == IERC725X.execute.selector) {
506: erc725Function == ILSP14Ownable2Step.transferOwnership.selector ||
507: erc725Function == ILSP14Ownable2Step.acceptOwnership.selector

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP6KeyManager/LSP6KeyManagerCore.sol#L463

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP6KeyManager/LSP6KeyManagerCore.sol#L468

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP6KeyManager/LSP6KeyManagerCore.sol#L484

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP6KeyManager/LSP6KeyManagerCore.sol#L498

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP6KeyManager/LSP6KeyManagerCore.sol#L506

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP6KeyManager/LSP6KeyManagerCore.sol#L507

File: LSP6KeyManagerInitAbstract.sol

21: if (target_ == address(0)) revert InvalidLSP6Target();

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP6KeyManager/LSP6KeyManagerInitAbstract.sol#L21

File: LSP6Utils.sol

110: if (pointer == allowedCallsCompacted.length) return true;

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP6KeyManager/LSP6Utils.sol#L110

File: LSP6Utils.sol

137: if (elementLength == 0 || elementLength > 32) return false;
140: if (pointer == allowedERC725YDataKeysCompacted.length) return true;

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP6KeyManager/LSP6Utils.sol#L137

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP6KeyManager/LSP6Utils.sol#L140

File: LSP6Utils.sol

229: if (permission == _PERMISSION_CHANGEOWNER) return "TRANSFEROWNERSHIP";
230: if (permission == _PERMISSION_EDITPERMISSIONS) return "EDITPERMISSIONS";
231: if (permission == _PERMISSION_ADDCONTROLLER) return "ADDCONTROLLER";
232: if (permission == _PERMISSION_ADDEXTENSIONS) return "ADDEXTENSIONS";
233: if (permission == _PERMISSION_CHANGEEXTENSIONS)
235: if (permission == _PERMISSION_ADDUNIVERSALRECEIVERDELEGATE)
237: if (permission == _PERMISSION_CHANGEUNIVERSALRECEIVERDELEGATE)
239: if (permission == _PERMISSION_REENTRANCY) return "REENTRANCY";
240: if (permission == _PERMISSION_SETDATA) return "SETDATA";
241: if (permission == _PERMISSION_CALL) return "CALL";
242: if (permission == _PERMISSION_STATICCALL) return "STATICCALL";
243: if (permission == _PERMISSION_DELEGATECALL) return "DELEGATECALL";
244: if (permission == _PERMISSION_DEPLOY) return "DEPLOY";
245: if (permission == _PERMISSION_TRANSFERVALUE) return "TRANSFERVALUE";
246: if (permission == _PERMISSION_SIGN) return "SIGN";

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP6KeyManager/LSP6Utils.sol#L229

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP6KeyManager/LSP6Utils.sol#L230

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP6KeyManager/LSP6Utils.sol#L231

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP6KeyManager/LSP6Utils.sol#L232

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP6KeyManager/LSP6Utils.sol#L233

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP6KeyManager/LSP6Utils.sol#L235

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP6KeyManager/LSP6Utils.sol#L237

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP6KeyManager/LSP6Utils.sol#L239

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP6KeyManager/LSP6Utils.sol#L240

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP6KeyManager/LSP6Utils.sol#L241

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP6KeyManager/LSP6Utils.sol#L242

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP6KeyManager/LSP6Utils.sol#L243

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP6KeyManager/LSP6Utils.sol#L244

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP6KeyManager/LSP6Utils.sol#L245

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP6KeyManager/LSP6Utils.sol#L246

File: LSP6ExecuteModule.sol

86: if (to == address(this)) {
107: if (operationType == OPERATION_0_CALL) {
119: operationType == OPERATION_1_CREATE ||
120: operationType == OPERATION_2_CREATE2
137: if (operationType == OPERATION_3_STATICCALL) {
148: if (operationType == OPERATION_4_DELEGATECALL) {

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP6KeyManager/LSP6Modules/LSP6ExecuteModule.sol#L86

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP6KeyManager/LSP6Modules/LSP6ExecuteModule.sol#L107

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP6KeyManager/LSP6Modules/LSP6ExecuteModule.sol#L119

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP6KeyManager/LSP6Modules/LSP6ExecuteModule.sol#L120

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP6KeyManager/LSP6Modules/LSP6ExecuteModule.sol#L137

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP6KeyManager/LSP6Modules/LSP6ExecuteModule.sol#L148

File: LSP6ExecuteModule.sol

262: if (allowedCalls.length == 0) {

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP6KeyManager/LSP6Modules/LSP6ExecuteModule.sol#L262

File: LSP6ExecuteModule.sol

329: if (operationType == OPERATION_0_CALL) {
331: } else if (operationType == OPERATION_3_STATICCALL) {
333: } else if (operationType == OPERATION_4_DELEGATECALL) {

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP6KeyManager/LSP6Modules/LSP6ExecuteModule.sol#L329

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP6KeyManager/LSP6Modules/LSP6ExecuteModule.sol#L331

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP6KeyManager/LSP6Modules/LSP6ExecuteModule.sol#L333

File: LSP6ExecuteModule.sol

362: executeCalldata.length == 164

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP6KeyManager/LSP6Modules/LSP6ExecuteModule.sol#L362

File: LSP6ExecuteModule.sol

378: allowedAddress == address(bytes20(type(uint160).max)) ||
379: to == allowedAddress;

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP6KeyManager/LSP6Modules/LSP6ExecuteModule.sol#L378-L379

File: LSP6ExecuteModule.sol

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

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP6KeyManager/LSP6Modules/LSP6ExecuteModule.sol#L395

File: LSP6ExecuteModule.sol

414: allowedFunction == bytes4(type(uint32).max) ||
415: (isFunctionCall && (requiredFunction == allowedFunction));

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP6KeyManager/LSP6Modules/LSP6ExecuteModule.sol#L414-L415

File: LSP6ExecuteModule.sol

430: return (allowedCallType & requiredCallTypes == requiredCallTypes);

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP6KeyManager/LSP6Modules/LSP6ExecuteModule.sol#L430

File: LSP6SetDataModule.sol

142: if (requiredPermission == _PERMISSION_SETDATA) {
97: if (requiredPermission == bytes32(0)) return;

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP6KeyManager/LSP6Modules/LSP6SetDataModule.sol#L142

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP6KeyManager/LSP6Modules/LSP6SetDataModule.sol#L97

File: LSP6SetDataModule.sol

142: if (requiredPermission == _PERMISSION_SETDATA) {

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP6KeyManager/LSP6Modules/LSP6SetDataModule.sol#L142

File: LSP6SetDataModule.sol

282: inputDataKey == _LSP1_UNIVERSAL_RECEIVER_DELEGATE_KEY ||

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP6KeyManager/LSP6Modules/LSP6SetDataModule.sol#L282

File: LSP6SetDataModule.sol

341: if (inputDataKey == _LSP6KEY_ADDRESSPERMISSIONS_ARRAY) {
374: ERC725Y(controlledContract).getData(inputDataKey).length == 0

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP6KeyManager/LSP6Modules/LSP6SetDataModule.sol#L341

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP6KeyManager/LSP6Modules/LSP6SetDataModule.sol#L374

File: LSP6SetDataModule.sol

426: ERC725Y(controlledContract).getData(dataKey).length == 0

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP6KeyManager/LSP6Modules/LSP6SetDataModule.sol#L426

File: LSP6SetDataModule.sol

461: ERC725Y(controlledContract).getData(dataKey).length == 0

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP6KeyManager/LSP6Modules/LSP6SetDataModule.sol#L461

File: LSP6SetDataModule.sol

479: ERC725Y(controlledContract).getData(lsp1DelegateDataKey).length == 0

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP6KeyManager/LSP6Modules/LSP6SetDataModule.sol#L479

File: LSP6SetDataModule.sol

512: if (allowedERC725YDataKeysCompacted.length == 0)

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP6KeyManager/LSP6Modules/LSP6SetDataModule.sol#L512

File: LSP6SetDataModule.sol

629: if (allowedERC725YDataKeysCompacted.length == 0)
747: if (allowedDataKeysFound == inputKeysLength) return;

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP6KeyManager/LSP6Modules/LSP6SetDataModule.sol#L629

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP6KeyManager/LSP6Modules/LSP6SetDataModule.sol#L747

File: LSP7DigitalAsset.sol

55: interfaceId == _INTERFACEID_LSP7 ||

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP7DigitalAsset/LSP7DigitalAsset.sol#L55

File: LSP7DigitalAssetCore.sol

112: if (tokenOwner == operator) {

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP7DigitalAsset/LSP7DigitalAssetCore.sol#L112

File: LSP7DigitalAssetCore.sol

131: if (from == to) revert LSP7CannotSendToSelf();

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP7DigitalAsset/LSP7DigitalAssetCore.sol#L131

File: LSP7DigitalAssetCore.sol

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

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP7DigitalAsset/LSP7DigitalAssetCore.sol#L268

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP7DigitalAsset/LSP7DigitalAssetCore.sol#L272

File: LSP7DigitalAssetCore.sol

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

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP7DigitalAsset/LSP7DigitalAssetCore.sol#L300

File: LSP7DigitalAssetCore.sol

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

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP7DigitalAsset/LSP7DigitalAssetCore.sol#L343

File: LSP7DigitalAssetCore.sol

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

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP7DigitalAsset/LSP7DigitalAssetCore.sol#L406

File: LSP7DigitalAssetInitAbstract.sol

49: interfaceId == _INTERFACEID_LSP7 ||

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP7DigitalAsset/LSP7DigitalAssetInitAbstract.sol#L49

File: LSP7CappedSupplyInitAbstract.sol

24: if (tokenSupplyCap_ == 0) {

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP7DigitalAsset/extensions/LSP7CappedSupplyInitAbstract.sol#L24

File: LSP8IdentifiableDigitalAsset.sol

49: interfaceId == _INTERFACEID_LSP8 ||

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP8IdentifiableDigitalAsset/LSP8IdentifiableDigitalAsset.sol#L49

File: LSP8IdentifiableDigitalAssetCore.sol

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

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP8IdentifiableDigitalAsset/LSP8IdentifiableDigitalAssetCore.sol#L84

File: LSP8IdentifiableDigitalAssetCore.sol

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

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP8IdentifiableDigitalAsset/LSP8IdentifiableDigitalAssetCore.sol#L115

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP8IdentifiableDigitalAsset/LSP8IdentifiableDigitalAssetCore.sol#L119

File: LSP8IdentifiableDigitalAssetCore.sol

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

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP8IdentifiableDigitalAsset/LSP8IdentifiableDigitalAssetCore.sol#L139

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP8IdentifiableDigitalAsset/LSP8IdentifiableDigitalAssetCore.sol#L143

File: LSP8IdentifiableDigitalAssetCore.sol

183: return (caller == tokenOwner || _operators[tokenId].contains(caller));

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP8IdentifiableDigitalAsset/LSP8IdentifiableDigitalAssetCore.sol#L183

File: LSP8IdentifiableDigitalAssetCore.sol

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

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP8IdentifiableDigitalAsset/LSP8IdentifiableDigitalAssetCore.sol#L319

File: LSP8IdentifiableDigitalAssetCore.sol

401: if (from == to) {
410: if (to == address(0)) {

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP8IdentifiableDigitalAsset/LSP8IdentifiableDigitalAssetCore.sol#L401

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP8IdentifiableDigitalAsset/LSP8IdentifiableDigitalAssetCore.sol#L410

File: LSP8IdentifiableDigitalAssetInitAbstract.sol

49: interfaceId == _INTERFACEID_LSP8 ||

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP8IdentifiableDigitalAsset/LSP8IdentifiableDigitalAssetInitAbstract.sol#L49

File: LSP8CappedSupplyInitAbstract.sol

26: if (tokenSupplyCap_ == 0) {

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CappedSupplyInitAbstract.sol#L26

File: LSP8CompatibleERC721.sol

86: interfaceId == _INTERFACEID_ERC721 ||
87: interfaceId == _INTERFACEID_ERC721METADATA ||

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721.sol#L86-L87

File: LSP8CompatibleERC721.sol

129: if (operatorListLength == 0) {

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721.sol#L129

File: LSP8CompatibleERC721.sol

322: return retval == IERC721Receiver.onERC721Received.selector;
324: if (reason.length == 0) {

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721.sol#L322

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721.sol#L324

File: LSP8CompatibleERC721InitAbstract.sol

86: interfaceId == _INTERFACEID_ERC721 ||
87: interfaceId == _INTERFACEID_ERC721METADATA ||

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721InitAbstract.sol#L86-L87

File: LSP8CompatibleERC721InitAbstract.sol

129: if (operatorListLength == 0) {

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721InitAbstract.sol#L129

File: LSP8CompatibleERC721InitAbstract.sol

322: return retval == IERC721Receiver.onERC721Received.selector;
324: if (reason.length == 0) {

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721InitAbstract.sol#L322

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721InitAbstract.sol#L324

File: LSP8Enumerable.sol

36: if (from == address(0)) {
40: } else if (to == address(0)) {

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8Enumerable.sol#L36

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8Enumerable.sol#L40

File: LSP8EnumerableInitAbstract.sol

38: if (from == address(0)) {
42: } else if (to == address(0)) {

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8EnumerableInitAbstract.sol#L38

https://github.com/code-423n4/2023-06-lukso/tree/main/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8EnumerableInitAbstract.sol#L42

File: ERC725.sol

41: interfaceId == _INTERFACEID_ERC725X ||
42: interfaceId == _INTERFACEID_ERC725Y ||

https://github.com/code-423n4/2023-06-lukso/tree/main/submodules/ERC725/implementations/contracts/ERC725.sol#L41-L42

File: ERC725InitAbstract.sol

43: interfaceId == _INTERFACEID_ERC725X ||
44: interfaceId == _INTERFACEID_ERC725Y ||

https://github.com/code-423n4/2023-06-lukso/tree/main/submodules/ERC725/implementations/contracts/ERC725InitAbstract.sol#L43-L44

File: ERC725XCore.sol

68: interfaceId == _INTERFACEID_ERC725X ||

https://github.com/code-423n4/2023-06-lukso/tree/main/submodules/ERC725/implementations/contracts/ERC725XCore.sol#L68

File: ERC725XCore.sol

83: if (operationType == OPERATION_0_CALL) {
88: if (operationType == OPERATION_1_CREATE) {
95: if (operationType == OPERATION_2_CREATE2) {
102: if (operationType == OPERATION_3_STATICCALL) {
119: if (operationType == OPERATION_4_DELEGATECALL) {

https://github.com/code-423n4/2023-06-lukso/tree/main/submodules/ERC725/implementations/contracts/ERC725XCore.sol#L83

https://github.com/code-423n4/2023-06-lukso/tree/main/submodules/ERC725/implementations/contracts/ERC725XCore.sol#L88

https://github.com/code-423n4/2023-06-lukso/tree/main/submodules/ERC725/implementations/contracts/ERC725XCore.sol#L95

https://github.com/code-423n4/2023-06-lukso/tree/main/submodules/ERC725/implementations/contracts/ERC725XCore.sol#L102

https://github.com/code-423n4/2023-06-lukso/tree/main/submodules/ERC725/implementations/contracts/ERC725XCore.sol#L119

File: ERC725XCore.sol

139: (targets.length != values.length || values.length != datas.length)
144: if (operationsType.length == 0) {

https://github.com/code-423n4/2023-06-lukso/tree/main/submodules/ERC725/implementations/contracts/ERC725XCore.sol#L139

https://github.com/code-423n4/2023-06-lukso/tree/main/submodules/ERC725/implementations/contracts/ERC725XCore.sol#L144

File: ERC725XCore.sol

255: if (creationCode.length == 0) {
269: if (contractAddress == address(0)) {

https://github.com/code-423n4/2023-06-lukso/tree/main/submodules/ERC725/implementations/contracts/ERC725XCore.sol#L255

https://github.com/code-423n4/2023-06-lukso/tree/main/submodules/ERC725/implementations/contracts/ERC725XCore.sol#L269

File: ERC725XCore.sol

292: if (creationCode.length == 0) {

https://github.com/code-423n4/2023-06-lukso/tree/main/submodules/ERC725/implementations/contracts/ERC725XCore.sol#L292

File: ERC725YCore.sol

84: if (dataKeys.length == 0) {

https://github.com/code-423n4/2023-06-lukso/tree/main/submodules/ERC725/implementations/contracts/ERC725YCore.sol#L84

File: ERC725YCore.sol

119: interfaceId == _INTERFACEID_ERC725Y ||

https://github.com/code-423n4/2023-06-lukso/tree/main/submodules/ERC725/implementations/contracts/ERC725YCore.sol#L119

</details>
Test Code
contract GasTest is DSTest { Contract0 c0; Contract1 c1; function setUp() public { c0 = new Contract0(); c1 = new Contract1(); } function testGas() public { c0.not_optimized(1,2); c1.optimized(1,2); } } contract Contract0 { function not_optimized(uint8 a,uint8 b) public returns(bool){ return ((a==1) || (b==1)); } } contract Contract1 { function optimized(uint8 a,uint8 b) public returns(bool){ return ((a ^ 1) & (b ^ 1)) == 0; } }
Gas Test Report
Contract0 contract
Deployment CostDeployment Size
46099261
Function Nameminavgmedianmax# calls
not_optimized4564564564561
Contract1 contract
Deployment CostDeployment Size
42493243
Function Nameminavgmedianmax# calls
optimized4304304304301

#0 - c4-judge

2023-08-02T09:46:48Z

trust1995 marked the issue as grade-a

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