diff --git a/contracts/LSP0ERC725Account/LSP0ERC725AccountCore.sol b/contracts/LSP0ERC725Account/LSP0ERC725AccountCore.sol index 4ff55adb7..0c30e27be 100644 --- a/contracts/LSP0ERC725Account/LSP0ERC725AccountCore.sol +++ b/contracts/LSP0ERC725Account/LSP0ERC725AccountCore.sol @@ -821,6 +821,7 @@ abstract contract LSP0ERC725AccountCore is bytes memory dataValue ) internal virtual override { ERC725YCore._store[dataKey] = dataValue; + emit DataChanged( dataKey, dataValue.length <= 256 diff --git a/contracts/LSP20CallVerification/LSP20CallVerification.sol b/contracts/LSP20CallVerification/LSP20CallVerification.sol index 6a7732222..489918a8f 100644 --- a/contracts/LSP20CallVerification/LSP20CallVerification.sol +++ b/contracts/LSP20CallVerification/LSP20CallVerification.sol @@ -20,48 +20,58 @@ import { abstract contract LSP20CallVerification { /** * @dev Calls {lsp20VerifyCall} function on the logicVerifier. - * Reverts in case the value returned does not match the success value (lsp20VerifyCall selector) - * Returns whether a verification after the execution should happen based on the last byte of the returnedStatus + * + * @custom:info + * - Reverts in case the value returned does not match the magic value (lsp20VerifyCall selector). + * - Returns whether a verification after the execution should happen based on the last byte of the magicValue. + * - Reverts with no reason if the data returned by `ILSP20(logicVerifier).lsp20VerifyCall(...)` cannot be decoded (_e.g:_ any other data type besides `bytes4`). + * See this link for more info: https://forum.soliditylang.org/t/call-for-feedback-the-future-of-try-catch-in-solidity/1497. */ function _verifyCall( address logicVerifier ) internal virtual returns (bool verifyAfter) { - if (logicVerifier.code.length == 0) + if (logicVerifier.code.length == 0) { revert LSP20EOACannotVerifyCall(logicVerifier); + } - (bool success, bytes memory returnedData) = logicVerifier.call( - abi.encodeWithSelector( - ILSP20.lsp20VerifyCall.selector, + // Reverts with no reason if the returned data type is not a `bytes4` value + try + ILSP20(logicVerifier).lsp20VerifyCall( msg.sender, address(this), msg.sender, msg.value, msg.data ) - ); - - _validateCall(false, success, returnedData); - - bytes4 returnedStatus = abi.decode(returnedData, (bytes4)); + returns (bytes4 magicValue) { + if (bytes3(magicValue) != bytes3(ILSP20.lsp20VerifyCall.selector)) { + revert LSP20CallVerificationFailed( + false, + abi.encode(magicValue) + ); + } - if (bytes3(returnedStatus) != bytes3(ILSP20.lsp20VerifyCall.selector)) { - revert LSP20CallVerificationFailed(false, returnedData); + return magicValue[3] == 0x01; + } catch (bytes memory errorData) { + _revertWithLSP20DefaultError(false, errorData); } - - return returnedStatus[3] == 0x01; } /** * @dev Calls {lsp20VerifyCallResult} function on the logicVerifier. - * Reverts in case the value returned does not match the success value (lsp20VerifyCallResult selector) + * + * @custom:info + * - Reverts in case the value returned does not match the magic value (lsp20VerifyCallResult selector). + * - Reverts with no reason if the data returned by `ILSP20(logicVerifier).lsp20VerifyCallResult(...)` cannot be decoded (_e.g:_ any other data type besides `bytes4`). + * See this link for more info: https://forum.soliditylang.org/t/call-for-feedback-the-future-of-try-catch-in-solidity/1497. */ function _verifyCallResult( address logicVerifier, bytes memory callResult ) internal virtual { - (bool success, bytes memory returnedData) = logicVerifier.call( - abi.encodeWithSelector( - ILSP20.lsp20VerifyCallResult.selector, + // Reverts with no reason if the returned data type is not a `bytes4` value + try + ILSP20(logicVerifier).lsp20VerifyCallResult( keccak256( abi.encodePacked( msg.sender, @@ -73,37 +83,18 @@ abstract contract LSP20CallVerification { ), callResult ) - ); - - _validateCall(true, success, returnedData); - - if ( - abi.decode(returnedData, (bytes4)) != - ILSP20.lsp20VerifyCallResult.selector - ) - revert LSP20CallVerificationFailed({ - postCall: true, - returnedData: returnedData - }); - } - - function _validateCall( - bool postCall, - bool success, - bytes memory returnedData - ) internal pure virtual { - if (!success) _revertWithLSP20DefaultError(postCall, returnedData); + returns (bytes4 magicValue) { + if (magicValue != ILSP20.lsp20VerifyCallResult.selector) { + revert LSP20CallVerificationFailed( + true, + abi.encode(magicValue) + ); + } - // check if the returned data contains at least 32 bytes, potentially an abi encoded bytes4 value - // check if the returned data has in the first 32 bytes an abi encoded bytes4 value - if ( - returnedData.length < 32 || - bytes28(bytes32(returnedData) << 32) != bytes28(0) - ) - revert LSP20CallVerificationFailed({ - postCall: postCall, - returnedData: returnedData - }); + return; + } catch (bytes memory errorData) { + _revertWithLSP20DefaultError(true, errorData); + } } function _revertWithLSP20DefaultError( diff --git a/contracts/LSP4DigitalAssetMetadata/LSP4DigitalAssetMetadata.sol b/contracts/LSP4DigitalAssetMetadata/LSP4DigitalAssetMetadata.sol index a57731572..b20813260 100644 --- a/contracts/LSP4DigitalAssetMetadata/LSP4DigitalAssetMetadata.sol +++ b/contracts/LSP4DigitalAssetMetadata/LSP4DigitalAssetMetadata.sol @@ -65,6 +65,7 @@ abstract contract LSP4DigitalAssetMetadata is ERC725Y { revert LSP4TokenSymbolNotEditable(); } else { _store[dataKey] = dataValue; + emit DataChanged( dataKey, dataValue.length <= 256 diff --git a/contracts/LSP4DigitalAssetMetadata/LSP4DigitalAssetMetadataInitAbstract.sol b/contracts/LSP4DigitalAssetMetadata/LSP4DigitalAssetMetadataInitAbstract.sol index 56603d4ff..892f1d467 100644 --- a/contracts/LSP4DigitalAssetMetadata/LSP4DigitalAssetMetadataInitAbstract.sol +++ b/contracts/LSP4DigitalAssetMetadata/LSP4DigitalAssetMetadataInitAbstract.sol @@ -69,6 +69,7 @@ abstract contract LSP4DigitalAssetMetadataInitAbstract is ERC725YInitAbstract { revert LSP4TokenSymbolNotEditable(); } else { _store[dataKey] = dataValue; + emit DataChanged( dataKey, dataValue.length <= 256 diff --git a/contracts/LSP6KeyManager/LSP6KeyManagerCore.sol b/contracts/LSP6KeyManager/LSP6KeyManagerCore.sol index 0a25eec83..f499591da 100644 --- a/contracts/LSP6KeyManager/LSP6KeyManagerCore.sol +++ b/contracts/LSP6KeyManager/LSP6KeyManagerCore.sol @@ -10,6 +10,9 @@ import { IERC725Y } from "@erc725/smart-contracts/contracts/interfaces/IERC725Y.sol"; import {ILSP6KeyManager as ILSP6} from "./ILSP6KeyManager.sol"; +import { + ILSP14Ownable2Step as ILSP14 +} from "../LSP14Ownable2Step/ILSP14Ownable2Step.sol"; import { ILSP20CallVerifier as ILSP20 } from "../LSP20CallVerification/ILSP20CallVerifier.sol"; @@ -18,7 +21,6 @@ import { } from "../LSP25ExecuteRelayCall/ILSP25ExecuteRelayCall.sol"; // modules -import {ILSP14Ownable2Step} from "../LSP14Ownable2Step/ILSP14Ownable2Step.sol"; import {ERC725Y} from "@erc725/smart-contracts/contracts/ERC725Y.sol"; import {ERC165} from "@openzeppelin/contracts/utils/introspection/ERC165.sol"; import {LSP6SetDataModule} from "./LSP6Modules/LSP6SetDataModule.sol"; @@ -32,7 +34,6 @@ import { } from "../LSP25ExecuteRelayCall/LSP25MultiChannelNonce.sol"; // libraries -import {BytesLib} from "solidity-bytes-utils/contracts/BytesLib.sol"; import {ECDSA} from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; import {Address} from "@openzeppelin/contracts/utils/Address.sol"; import {LSP6Utils} from "./LSP6Utils.sol"; @@ -91,7 +92,6 @@ abstract contract LSP6KeyManagerCore is { using LSP6Utils for *; using ECDSA for *; - using BytesLib for bytes; address internal _target; @@ -324,48 +324,117 @@ abstract contract LSP6KeyManagerCore is uint256 msgValue, bytes calldata callData ) external virtual override returns (bytes4) { - bool isSetData = bytes4(callData) == IERC725Y.setData.selector || - bytes4(callData) == IERC725Y.setDataBatch.selector; + bytes32 permissions = ERC725Y(targetContract).getPermissionsFor(caller); + if (permissions == bytes32(0)) revert NoPermissionsSet(caller); + + bool reentrancyStatus = _reentrancyStatus[targetContract]; + if (reentrancyStatus) { + _requirePermissions(caller, permissions, _PERMISSION_REENTRANCY); + } + + bytes4 erc725Function = bytes4(callData); + + bytes4 lsp20MagicValue = _lsp20VerifyPermissions( + targetContract, + caller, + permissions, + erc725Function, + callData, + reentrancyStatus + ); // If target is invoking the verification, emit the event and change the reentrancy guard if (msg.sender == targetContract) { - bool reentrancyStatus = _nonReentrantBefore( + if (!reentrancyStatus) { + if ( + bytes4(callData) != IERC725Y.setData.selector && + bytes4(callData) != IERC725Y.setDataBatch.selector + ) { + _reentrancyStatus[targetContract] = true; + } + } + + emit PermissionsVerified(caller, msgValue, erc725Function); + } + + return lsp20MagicValue; + } + + function _lsp20VerifyPermissions( + address targetContract, + address caller, + bytes32 permissions, + bytes4 erc725Function, + bytes calldata data, + bool reentrancyStatus + ) internal view returns (bytes4) { + if (erc725Function == IERC725Y.setData.selector) { + (bytes32 inputKey, bytes memory inputValue) = abi.decode( + data[4:], + (bytes32, bytes) + ); + + LSP6SetDataModule._verifyCanSetData( + targetContract, + caller, + permissions, + inputKey, + inputValue + ); + + return _LSP20_VERIFY_CALL_SUCCESS_VALUE_WITHOUT_POST_VERIFICATION; + } else if (erc725Function == IERC725Y.setDataBatch.selector) { + (bytes32[] memory inputKeys, bytes[] memory inputValues) = abi + .decode(data[4:], (bytes32[], bytes[])); + + LSP6SetDataModule._verifyCanSetData( targetContract, - isSetData, - caller + caller, + permissions, + inputKeys, + inputValues ); - _verifyPermissions(targetContract, caller, false, callData); + return _LSP20_VERIFY_CALL_SUCCESS_VALUE_WITHOUT_POST_VERIFICATION; + } else if (erc725Function == IERC725X.execute.selector) { + ( + uint256 operationType, + address to, + uint256 value, + bytes memory payload + ) = abi.decode(data[4:], (uint256, address, uint256, bytes)); - emit PermissionsVerified(caller, msgValue, bytes4(callData)); + LSP6ExecuteModule._verifyCanExecute( + targetContract, + caller, + permissions, + operationType, + to, + value, + payload + ); - // if it's a setData call, do not invoke the `lsp20VerifyCallResult(..)` function return - isSetData || reentrancyStatus + reentrancyStatus ? _LSP20_VERIFY_CALL_SUCCESS_VALUE_WITHOUT_POST_VERIFICATION : _LSP20_VERIFY_CALL_SUCCESS_VALUE_WITH_POST_VERIFICATION; - } - /// @dev If a different address is invoking the verification, - /// do not change the state or emit the event to allow read-only verification - else { - bool reentrancyStatus = _reentrancyStatus[targetContract]; - - if (reentrancyStatus) { - _requirePermissions( - caller, - ERC725Y(targetContract).getPermissionsFor(caller), - _PERMISSION_REENTRANCY - ); - } - - _verifyPermissions(targetContract, caller, false, callData); + } else if ( + erc725Function == ILSP14.transferOwnership.selector || + erc725Function == ILSP14.acceptOwnership.selector || + erc725Function == ILSP14.renounceOwnership.selector + ) { + LSP6OwnershipModule._verifyOwnershipPermissions( + caller, + permissions + ); - // if it's a setData call, do not invoke the `lsp20VerifyCallResult(..)` function return - isSetData || reentrancyStatus + reentrancyStatus ? _LSP20_VERIFY_CALL_SUCCESS_VALUE_WITHOUT_POST_VERIFICATION : _LSP20_VERIFY_CALL_SUCCESS_VALUE_WITH_POST_VERIFICATION; } + + revert InvalidERC725Function(erc725Function); } /** @@ -376,10 +445,9 @@ abstract contract LSP6KeyManagerCore is bytes memory /* callResult */ ) external virtual override returns (bytes4) { // If it's the target calling, set back the reentrancy guard - // to false, if not return the success value - if (msg.sender == _target) { - _nonReentrantAfter(msg.sender); - } + // to false, if not return the magic value + _nonReentrantAfter(msg.sender); + return _LSP20_VERIFY_CALL_RESULT_SUCCESS_VALUE; } @@ -584,9 +652,9 @@ abstract contract LSP6KeyManagerCore is data ); } else if ( - erc725Function == ILSP14Ownable2Step.transferOwnership.selector || - erc725Function == ILSP14Ownable2Step.acceptOwnership.selector || - erc725Function == ILSP14Ownable2Step.renounceOwnership.selector + erc725Function == ILSP14.transferOwnership.selector || + erc725Function == ILSP14.acceptOwnership.selector || + erc725Function == ILSP14.renounceOwnership.selector ) { LSP6OwnershipModule._verifyOwnershipPermissions(from, permissions); } else { @@ -595,8 +663,8 @@ abstract contract LSP6KeyManagerCore is } /** - * @dev Update the status from `_NON_ENTERED` to `_ENTERED` and checks if - * the status is `_ENTERED` in order to revert the call unless the caller has the REENTRANCY permission + * @dev Update the status from `true` to `false` and checks if + * the status is `true` in order to revert the call unless the caller has the REENTRANCY permission * Used in the beginning of the `nonReentrant` modifier, before the method execution starts. */ function _nonReentrantBefore( @@ -625,8 +693,6 @@ abstract contract LSP6KeyManagerCore is * Used in the end of the `nonReentrant` modifier after the method execution is terminated */ function _nonReentrantAfter(address targetContract) internal virtual { - // By storing the original value once again, a refund is triggered (see - // https://eips.ethereum.org/EIPS/eip-2200) _reentrancyStatus[targetContract] = false; } diff --git a/contracts/LSP6KeyManager/LSP6Modules/LSP6ExecuteModule.sol b/contracts/LSP6KeyManager/LSP6Modules/LSP6ExecuteModule.sol index f3aab5d24..ad8ca2343 100644 --- a/contracts/LSP6KeyManager/LSP6Modules/LSP6ExecuteModule.sol +++ b/contracts/LSP6KeyManager/LSP6Modules/LSP6ExecuteModule.sol @@ -5,8 +5,8 @@ pragma solidity ^0.8.5; import {ERC725Y} from "@erc725/smart-contracts/contracts/ERC725Y.sol"; // libraries -import {LSP6Utils} from "../LSP6Utils.sol"; import {BytesLib} from "solidity-bytes-utils/contracts/BytesLib.sol"; +import {LSP6Utils} from "../LSP6Utils.sol"; import { ERC165Checker } from "@openzeppelin/contracts/utils/introspection/ERC165Checker.sol"; @@ -45,6 +45,7 @@ import { } from "../LSP6Errors.sol"; abstract contract LSP6ExecuteModule { + using BytesLib for bytes; using ERC165Checker for address; using LSP6Utils for *; @@ -188,15 +189,14 @@ abstract contract LSP6ExecuteModule { bytes memory data ) internal view virtual { bool isValueTransfer = value != 0; + bool isEmptyCall = data.length == 0; bool hasSuperTransferValue = permissions.hasPermission( _PERMISSION_SUPER_TRANSFERVALUE ); - - bool isEmptyCall = data.length == 0; - bool hasSuperCall = permissions.hasPermission(_PERMISSION_SUPER_CALL); + // CHECK if we are doing a value transfer if (isValueTransfer && !hasSuperTransferValue) { _requirePermissions( controller, @@ -206,11 +206,12 @@ abstract contract LSP6ExecuteModule { } // CHECK if we are doing an empty call, as the receive() or fallback() function - // of the controlledContract could run some code. + // of the contract being called could run some code if (isEmptyCall && !isValueTransfer && !hasSuperCall) { _requirePermissions(controller, permissions, _PERMISSION_CALL); } + // CHECK if we are doing an external call with some calldata if (!isEmptyCall && !hasSuperCall) { _requirePermissions(controller, permissions, _PERMISSION_CALL); } @@ -243,10 +244,10 @@ abstract contract LSP6ExecuteModule { bytes memory data ) internal view virtual { // CHECK for ALLOWED CALLS - bytes memory allowedCalls = ERC725Y(controlledContract) + bytes memory allowedCallsCompacted = ERC725Y(controlledContract) .getAllowedCallsFor(controllerAddress); - if (allowedCalls.length == 0) { + if (allowedCallsCompacted.length == 0) { revert NoCallsAllowed(controllerAddress); } @@ -261,7 +262,9 @@ abstract contract LSP6ExecuteModule { isEmptyCall ); - for (uint256 ii; ii < allowedCalls.length; ii += 34) { + bytes32 allowedCall; + + for (uint256 ii; ii < allowedCallsCompacted.length; ii += 34) { /// @dev structure of an AllowedCall // /// AllowedCall = 0x00200000000ncafecafecafecafecafecafecafecafecafecafe5a5a5a5af1f1f1f1 @@ -273,20 +276,19 @@ abstract contract LSP6ExecuteModule { /// f1f1f1f1 = function // CHECK that we can extract an AllowedCall - if (ii + 34 > allowedCalls.length) { - revert InvalidEncodedAllowedCalls(allowedCalls); + if (ii + 34 > allowedCallsCompacted.length) { + revert InvalidEncodedAllowedCalls(allowedCallsCompacted); } // extract one AllowedCall at a time - bytes memory allowedCall = BytesLib.slice(allowedCalls, ii + 2, 32); + allowedCall = allowedCallsCompacted + .slice({_start: ii + 2, _length: 32}) + .toBytes32({_start: 0}); - // 0xxxxxxxxxffffffffffffffffffffffffffffffffffffffffffffffffffffffff - // (excluding the callTypes) not allowed + // 0xctctctctffffffffffffffffffffffffffffffffffffffffffffffffffffffff + // (excluding the callTypes `ct`) not allowed // as equivalent to whitelisting any call (= SUPER permission) - if ( - bytes28(bytes32(allowedCall) << 32) == - bytes28(type(uint224).max) - ) { + if (bytes28(allowedCall << 32) == bytes28(type(uint224).max)) { revert InvalidWhitelistedCall(controllerAddress); } @@ -329,14 +331,14 @@ abstract contract LSP6ExecuteModule { } function _isAllowedAddress( - bytes memory allowedCall, + bytes32 allowedCall, address to ) internal pure virtual returns (bool) { // = 4 bytes x 8 bits = 32 bits // // v----------------address---------------v // 0000000ncafecafecafecafecafecafecafecafecafecafe5a5a5a5af1f1f1f1 - address allowedAddress = address(bytes20(bytes32(allowedCall) << 32)); + address allowedAddress = address(bytes20(allowedCall << 32)); // ANY address = 0xffffffffffffffffffffffffffffffffffffffff return @@ -345,7 +347,7 @@ abstract contract LSP6ExecuteModule { } function _isAllowedStandard( - bytes memory allowedCall, + bytes32 allowedCall, address to ) internal view virtual returns (bool) { // = 24 bytes x 8 bits = 192 bits @@ -353,7 +355,7 @@ abstract contract LSP6ExecuteModule { // standard // <-------------------------------------->v------v // 0000000ncafecafecafecafecafecafecafecafecafecafe5a5a5a5af1f1f1f1 - bytes4 allowedStandard = bytes4(bytes32(allowedCall) << 192); + bytes4 allowedStandard = bytes4(allowedCall << 192); // ANY Standard = 0xffffffff return @@ -362,7 +364,7 @@ abstract contract LSP6ExecuteModule { } function _isAllowedFunction( - bytes memory allowedCall, + bytes32 allowedCall, bytes4 requiredFunction ) internal pure virtual returns (bool) { // = 28 bytes x 8 bits = 224 bits @@ -370,7 +372,7 @@ abstract contract LSP6ExecuteModule { // function // <---------------------------------------------->v------v // 0000000ncafecafecafecafecafecafecafecafecafecafe5a5a5a5af1f1f1f1 - bytes4 allowedFunction = bytes4(bytes32(allowedCall) << 224); + bytes4 allowedFunction = bytes4(allowedCall << 224); bool isFunctionCall = requiredFunction != bytes4(0); @@ -381,7 +383,7 @@ abstract contract LSP6ExecuteModule { } function _isAllowedCallType( - bytes memory allowedCall, + bytes32 allowedCall, bytes4 requiredCallTypes ) internal pure virtual returns (bool) { // extract callType diff --git a/contracts/LSP6KeyManager/LSP6Modules/LSP6SetDataModule.sol b/contracts/LSP6KeyManager/LSP6Modules/LSP6SetDataModule.sol index ab623774e..514ec3283 100644 --- a/contracts/LSP6KeyManager/LSP6Modules/LSP6SetDataModule.sol +++ b/contracts/LSP6KeyManager/LSP6Modules/LSP6SetDataModule.sol @@ -583,7 +583,7 @@ abstract contract LSP6SetDataModule { bytes32 mask; /** - * iterate over each data key and update the `pointer` variable with the index where to find the length of each data key. + * Iterate over each data key and update the `pointer` variable with the index where to find the length of each data key. * * 0x 0003 a00000 0003 fff83a 0020 aa00...00cafe * ↑↑↑↑ ↑↑↑↑ ↑↑↑↑ @@ -614,7 +614,7 @@ abstract contract LSP6SetDataModule { ); } - /** + /* * The bitmask discard the last `32 - length` bytes of the input data key via ANDing & * It is used to compare only the relevant parts of each input data key against dynamic allowed data keys. * @@ -627,7 +627,7 @@ abstract contract LSP6SetDataModule { * input data key = 0xa00000cafecafecafecafecafecafecafe000000000000000000000011223344 * * & discard this part - * vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + * vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv * mask = 0xffffff0000000000000000000000000000000000000000000000000000000000 */ mask = @@ -735,7 +735,7 @@ abstract contract LSP6SetDataModule { ); } - /** + /* * The bitmask discard the last `32 - length` bytes of the input data key via ANDing & * It is used to compare only the relevant parts of each input data key against dynamic allowed data keys. * @@ -821,7 +821,7 @@ abstract contract LSP6SetDataModule { } unchecked { - jj++; + ++jj; } } } diff --git a/contracts/LSP9Vault/LSP9VaultCore.sol b/contracts/LSP9Vault/LSP9VaultCore.sol index 3e090c70d..0597f29dd 100644 --- a/contracts/LSP9Vault/LSP9VaultCore.sol +++ b/contracts/LSP9Vault/LSP9VaultCore.sol @@ -610,6 +610,7 @@ contract LSP9VaultCore is bytes memory dataValue ) internal virtual override { _store[dataKey] = dataValue; + emit DataChanged( dataKey, dataValue.length <= 256 diff --git a/docs/contracts/LSP0ERC725Account/LSP0ERC725Account.md b/docs/contracts/LSP0ERC725Account/LSP0ERC725Account.md index 5da23d51a..213708cff 100644 --- a/docs/contracts/LSP0ERC725Account/LSP0ERC725Account.md +++ b/docs/contracts/LSP0ERC725Account/LSP0ERC725Account.md @@ -1198,8 +1198,6 @@ function _verifyCall( ``` Calls [`lsp20VerifyCall`](#lsp20verifycall) function on the logicVerifier. -Reverts in case the value returned does not match the success value (lsp20VerifyCall selector) -Returns whether a verification after the execution should happen based on the last byte of the returnedStatus
@@ -1213,19 +1211,6 @@ function _verifyCallResult( ``` Calls [`lsp20VerifyCallResult`](#lsp20verifycallresult) function on the logicVerifier. -Reverts in case the value returned does not match the success value (lsp20VerifyCallResult selector) - -
- -### \_validateCall - -```solidity -function _validateCall( - bool postCall, - bool success, - bytes returnedData -) internal pure; -```
diff --git a/docs/contracts/LSP20CallVerification/LSP20CallVerification.md b/docs/contracts/LSP20CallVerification/LSP20CallVerification.md index c34f97ff7..78e29308a 100644 --- a/docs/contracts/LSP20CallVerification/LSP20CallVerification.md +++ b/docs/contracts/LSP20CallVerification/LSP20CallVerification.md @@ -33,8 +33,6 @@ function _verifyCall( ``` Calls [`lsp20VerifyCall`](#lsp20verifycall) function on the logicVerifier. -Reverts in case the value returned does not match the success value (lsp20VerifyCall selector) -Returns whether a verification after the execution should happen based on the last byte of the returnedStatus
@@ -48,19 +46,6 @@ function _verifyCallResult( ``` Calls [`lsp20VerifyCallResult`](#lsp20verifycallresult) function on the logicVerifier. -Reverts in case the value returned does not match the success value (lsp20VerifyCallResult selector) - -
- -### \_validateCall - -```solidity -function _validateCall( - bool postCall, - bool success, - bytes returnedData -) internal pure; -```
diff --git a/docs/contracts/LSP6KeyManager/LSP6KeyManager.md b/docs/contracts/LSP6KeyManager/LSP6KeyManager.md index a1b0b76df..e6dddc5e1 100644 --- a/docs/contracts/LSP6KeyManager/LSP6KeyManager.md +++ b/docs/contracts/LSP6KeyManager/LSP6KeyManager.md @@ -905,7 +905,7 @@ extract the bytes4 representation of a single bit for the type of call according ```solidity function _isAllowedAddress( - bytes allowedCall, + bytes32 allowedCall, address to ) internal pure returns (bool); ``` @@ -916,7 +916,7 @@ function _isAllowedAddress( ```solidity function _isAllowedStandard( - bytes allowedCall, + bytes32 allowedCall, address to ) internal view returns (bool); ``` @@ -927,7 +927,7 @@ function _isAllowedStandard( ```solidity function _isAllowedFunction( - bytes allowedCall, + bytes32 allowedCall, bytes4 requiredFunction ) internal pure returns (bool); ``` @@ -938,7 +938,7 @@ function _isAllowedFunction( ```solidity function _isAllowedCallType( - bytes allowedCall, + bytes32 allowedCall, bytes4 requiredCallTypes ) internal pure returns (bool); ``` @@ -1089,6 +1089,21 @@ The "idx" is a 256bits (unsigned) integer, where:
+### \_lsp20VerifyPermissions + +```solidity +function _lsp20VerifyPermissions( + address targetContract, + address caller, + bytes32 permissions, + bytes4 erc725Function, + bytes data, + bool reentrancyStatus +) internal view returns (bytes4); +``` + +
+ ### \_execute ```solidity @@ -1197,8 +1212,8 @@ function _nonReentrantBefore( ) internal nonpayable returns (bool reentrancyStatus); ``` -Update the status from `_NON_ENTERED` to `_ENTERED` and checks if -the status is `_ENTERED` in order to revert the call unless the caller has the REENTRANCY permission +Update the status from `true` to `false` and checks if +the status is `true` in order to revert the call unless the caller has the REENTRANCY permission Used in the beginning of the `nonReentrant` modifier, before the method execution starts.
diff --git a/docs/contracts/UniversalProfile.md b/docs/contracts/UniversalProfile.md index 180c43ddc..d8f048a2c 100644 --- a/docs/contracts/UniversalProfile.md +++ b/docs/contracts/UniversalProfile.md @@ -1141,8 +1141,6 @@ function _verifyCall( ``` Calls [`lsp20VerifyCall`](#lsp20verifycall) function on the logicVerifier. -Reverts in case the value returned does not match the success value (lsp20VerifyCall selector) -Returns whether a verification after the execution should happen based on the last byte of the returnedStatus
@@ -1156,19 +1154,6 @@ function _verifyCallResult( ``` Calls [`lsp20VerifyCallResult`](#lsp20verifycallresult) function on the logicVerifier. -Reverts in case the value returned does not match the success value (lsp20VerifyCallResult selector) - -
- -### \_validateCall - -```solidity -function _validateCall( - bool postCall, - bool success, - bytes returnedData -) internal pure; -```
diff --git a/tests/LSP20CallVerification/LSP20CallVerification.behaviour.ts b/tests/LSP20CallVerification/LSP20CallVerification.behaviour.ts index c96c659ab..01a7ddfa4 100644 --- a/tests/LSP20CallVerification/LSP20CallVerification.behaviour.ts +++ b/tests/LSP20CallVerification/LSP20CallVerification.behaviour.ts @@ -266,9 +266,9 @@ export const shouldBehaveLikeLSP20 = (buildContext: () => Promise Promise