diff --git a/constants.ts b/constants.ts
index 0ddf873d9..c2b1402b9 100644
--- a/constants.ts
+++ b/constants.ts
@@ -29,7 +29,7 @@ export const INTERFACE_IDS = {
LSP1UniversalReceiver: '0x6bb56a14',
LSP1UniversalReceiverDelegate: '0xa245bbda',
LSP6KeyManager: '0x23f34c62',
- LSP7DigitalAsset: '0xb3c4928f',
+ LSP7DigitalAsset: '0xc52d6008',
LSP8IdentifiableDigitalAsset: '0x3a271706',
LSP9Vault: '0x28af17e6',
LSP11BasicSocialRecovery: '0x049a28f1',
diff --git a/contracts/LSP7DigitalAsset/ILSP7DigitalAsset.sol b/contracts/LSP7DigitalAsset/ILSP7DigitalAsset.sol
index 2a30c935a..1fafbe646 100644
--- a/contracts/LSP7DigitalAsset/ILSP7DigitalAsset.sol
+++ b/contracts/LSP7DigitalAsset/ILSP7DigitalAsset.sol
@@ -122,21 +122,23 @@ interface ILSP7DigitalAsset is IERC165, IERC725Y {
) external;
/**
- * @dev Removes the `operator` address as an operator of callers tokens, disallowing it to send any amount of tokens
- * on behalf of the token owner (the caller of the function `msg.sender`). See also {authorizedAmountFor}.
+ * @dev Enables `tokenOwner` to remove `operator` for its tokens, disallowing it to send any amount of tokens on its behalf.
+ * This function also allows the `operator` to remove itself if it is the caller of this function
*
* @param operator The address to revoke as an operator.
+ * @param tokenOwner The address of the token owner.
* @param notify Boolean indicating whether to notify the operator or not.
* @param operatorNotificationData The data to notify the operator about via LSP1.
*
* @custom:requirements
- * - `operator` cannot be calling address.
+ * - caller MUST be `operator` or `tokenOwner`
* - `operator` cannot be the zero address.
*
* @custom:events {OperatorRevoked} event with address of the operator being revoked for the caller (token holder).
*/
function revokeOperator(
address operator,
+ address tokenOwner,
bool notify,
bytes memory operatorNotificationData
) external;
@@ -184,6 +186,7 @@ interface ILSP7DigitalAsset is IERC165, IERC725Y {
* indicating `operator` does not have any alauthorizedAmountForlowance left for `msg.sender`.
*
* @param operator The operator to decrease allowance for `msg.sender`
+ * @param tokenOwner The address of the token owner.
* @param subtractedAmount The amount to decrease by in the operator's allowance.
*
* @custom:requirements
@@ -192,6 +195,7 @@ interface ILSP7DigitalAsset is IERC165, IERC725Y {
*/
function decreaseAllowance(
address operator,
+ address tokenOwner,
uint256 subtractedAmount,
bytes memory operatorNotificationData
) external;
diff --git a/contracts/LSP7DigitalAsset/LSP7Constants.sol b/contracts/LSP7DigitalAsset/LSP7Constants.sol
index 6bcc63db9..b56398da2 100644
--- a/contracts/LSP7DigitalAsset/LSP7Constants.sol
+++ b/contracts/LSP7DigitalAsset/LSP7Constants.sol
@@ -2,7 +2,7 @@
pragma solidity ^0.8.4;
// --- ERC165 interface ids
-bytes4 constant _INTERFACEID_LSP7 = 0xb3c4928f;
+bytes4 constant _INTERFACEID_LSP7 = 0xc52d6008;
// --- Token Hooks
diff --git a/contracts/LSP7DigitalAsset/LSP7DigitalAssetCore.sol b/contracts/LSP7DigitalAsset/LSP7DigitalAssetCore.sol
index f396cd570..9ca4798f9 100644
--- a/contracts/LSP7DigitalAsset/LSP7DigitalAssetCore.sol
+++ b/contracts/LSP7DigitalAsset/LSP7DigitalAssetCore.sol
@@ -20,7 +20,6 @@ import {LSP1Utils} from "../LSP1UniversalReceiver/LSP1Utils.sol";
// errors
import {
- LSP7CannotSendToSelf,
LSP7AmountExceedsAuthorizedAmount,
LSP7InvalidTransferBatch,
LSP7AmountExceedsBalance,
@@ -31,7 +30,9 @@ import {
LSP7NotifyTokenReceiverContractMissingLSP1Interface,
LSP7NotifyTokenReceiverIsEOA,
OperatorAllowanceCannotBeIncreasedFromZero,
- LSP7BatchCallFailed
+ LSP7BatchCallFailed,
+ LSP7RevokeOperatorNotAuthorized,
+ LSP7DecreaseAllowanceNotAuthorized
} from "./LSP7Errors.sol";
// constants
@@ -173,11 +174,20 @@ abstract contract LSP7DigitalAssetCore is ILSP7DigitalAsset {
*/
function revokeOperator(
address operator,
+ address tokenOwner,
bool notify,
bytes memory operatorNotificationData
) public virtual override {
+ if (msg.sender != tokenOwner && msg.sender != operator) {
+ revert LSP7RevokeOperatorNotAuthorized(
+ msg.sender,
+ tokenOwner,
+ operator
+ );
+ }
+
_updateOperator(
- msg.sender,
+ tokenOwner,
operator,
0,
notify,
@@ -186,7 +196,7 @@ abstract contract LSP7DigitalAssetCore is ILSP7DigitalAsset {
if (notify) {
bytes memory lsp1Data = abi.encode(
- msg.sender,
+ tokenOwner,
0,
operatorNotificationData
);
@@ -254,10 +264,19 @@ abstract contract LSP7DigitalAssetCore is ILSP7DigitalAsset {
*/
function decreaseAllowance(
address operator,
+ address tokenOwner,
uint256 subtractedAmount,
bytes memory operatorNotificationData
) public virtual override {
- uint256 currentAllowance = authorizedAmountFor(operator, msg.sender);
+ if (msg.sender != tokenOwner && msg.sender != operator) {
+ revert LSP7DecreaseAllowanceNotAuthorized(
+ msg.sender,
+ tokenOwner,
+ operator
+ );
+ }
+
+ uint256 currentAllowance = authorizedAmountFor(operator, tokenOwner);
if (currentAllowance < subtractedAmount) {
revert LSP7DecreasedAllowanceBelowZero();
}
@@ -266,7 +285,7 @@ abstract contract LSP7DigitalAssetCore is ILSP7DigitalAsset {
unchecked {
newAllowance = currentAllowance - subtractedAmount;
_updateOperator(
- msg.sender,
+ tokenOwner,
operator,
newAllowance,
true,
@@ -275,7 +294,7 @@ abstract contract LSP7DigitalAssetCore is ILSP7DigitalAsset {
}
bytes memory lsp1Data = abi.encode(
- msg.sender,
+ tokenOwner,
newAllowance,
operatorNotificationData
);
@@ -295,8 +314,6 @@ abstract contract LSP7DigitalAssetCore is ILSP7DigitalAsset {
bool force,
bytes memory data
) public virtual override {
- if (from == to) revert LSP7CannotSendToSelf();
-
if (msg.sender != from) {
_spendAllowance({
operator: msg.sender,
diff --git a/contracts/LSP7DigitalAsset/LSP7Errors.sol b/contracts/LSP7DigitalAsset/LSP7Errors.sol
index 62fa06908..3a247a3f0 100644
--- a/contracts/LSP7DigitalAsset/LSP7Errors.sol
+++ b/contracts/LSP7DigitalAsset/LSP7Errors.sol
@@ -36,11 +36,6 @@ error LSP7CannotUseAddressZeroAsOperator();
*/
error LSP7CannotSendWithAddressZero();
-/**
- * @dev reverts when specifying the same address for `from` or `to` in a token transfer.
- */
-error LSP7CannotSendToSelf();
-
/**
* @dev reverts when the array parameters used in {transferBatch} have different lengths.
*/
@@ -88,3 +83,21 @@ error OperatorAllowanceCannotBeIncreasedFromZero(address operator);
* @notice Batch call failed.
*/
error LSP7BatchCallFailed(uint256 callIndex);
+
+/**
+ * @dev Reverts when the call to revoke operator is not authorized.
+ */
+error LSP7RevokeOperatorNotAuthorized(
+ address caller,
+ address tokenOwner,
+ address operator
+);
+
+/**
+ * @dev Reverts when the call to decrease allowance is not authorized.
+ */
+error LSP7DecreaseAllowanceNotAuthorized(
+ address caller,
+ address tokenOwner,
+ address operator
+);
diff --git a/contracts/LSP8IdentifiableDigitalAsset/LSP8Errors.sol b/contracts/LSP8IdentifiableDigitalAsset/LSP8Errors.sol
index 472ce6016..a74dc36d3 100644
--- a/contracts/LSP8IdentifiableDigitalAsset/LSP8Errors.sol
+++ b/contracts/LSP8IdentifiableDigitalAsset/LSP8Errors.sol
@@ -33,11 +33,6 @@ error LSP8CannotUseAddressZeroAsOperator();
*/
error LSP8CannotSendToAddressZero();
-/**
- * @dev Reverts when specifying the same address for `from` and `to` in a token transfer.
- */
-error LSP8CannotSendToSelf();
-
/**
* @dev Reverts when `operator` is not an operator for the `tokenId`.
*/
@@ -112,3 +107,12 @@ error LSP8TokenOwnerChanged(
address oldOwner,
address newOwner
);
+
+/**
+ * @dev Reverts when the call to revoke operator is not authorized.
+ */
+error LSP8RevokeOperatorNotAuthorized(
+ address caller,
+ address tokenOwner,
+ bytes32 tokenId
+);
diff --git a/contracts/LSP8IdentifiableDigitalAsset/LSP8IdentifiableDigitalAssetCore.sol b/contracts/LSP8IdentifiableDigitalAsset/LSP8IdentifiableDigitalAssetCore.sol
index 89f57b15d..2846c4ac0 100644
--- a/contracts/LSP8IdentifiableDigitalAsset/LSP8IdentifiableDigitalAssetCore.sol
+++ b/contracts/LSP8IdentifiableDigitalAsset/LSP8IdentifiableDigitalAssetCore.sol
@@ -36,13 +36,13 @@ import {
LSP8NonExistingOperator,
LSP8CannotSendToAddressZero,
LSP8TokenIdAlreadyMinted,
- LSP8CannotSendToSelf,
LSP8NotifyTokenReceiverContractMissingLSP1Interface,
LSP8NotifyTokenReceiverIsEOA,
LSP8TokenIdsDataLengthMismatch,
LSP8TokenIdsDataEmptyArray,
LSP8BatchCallFailed,
- LSP8TokenOwnerChanged
+ LSP8TokenOwnerChanged,
+ LSP8RevokeOperatorNotAuthorized
} from "./LSP8Errors.sol";
// constants
@@ -293,8 +293,14 @@ abstract contract LSP8IdentifiableDigitalAssetCore is
) public virtual override {
address tokenOwner = tokenOwnerOf(tokenId);
- if (tokenOwner != msg.sender) {
- revert LSP8NotTokenOwner(tokenOwner, tokenId, msg.sender);
+ if (msg.sender != tokenOwner) {
+ if (operator != msg.sender) {
+ revert LSP8RevokeOperatorNotAuthorized(
+ msg.sender,
+ tokenOwner,
+ tokenId
+ );
+ }
}
if (operator == address(0)) {
@@ -315,7 +321,7 @@ abstract contract LSP8IdentifiableDigitalAssetCore is
if (notify) {
bytes memory lsp1Data = abi.encode(
- msg.sender,
+ tokenOwner,
tokenId,
false, // unauthorized
operatorNotificationData
@@ -625,10 +631,6 @@ abstract contract LSP8IdentifiableDigitalAssetCore is
bool force,
bytes memory data
) internal virtual {
- if (from == to) {
- revert LSP8CannotSendToSelf();
- }
-
address tokenOwner = tokenOwnerOf(tokenId);
if (tokenOwner != from) {
revert LSP8NotTokenOwner(tokenOwner, tokenId, from);
diff --git a/docs/_interface_ids_table.mdx b/docs/_interface_ids_table.mdx
index acba017e9..036a13f80 100644
--- a/docs/_interface_ids_table.mdx
+++ b/docs/_interface_ids_table.mdx
@@ -8,7 +8,7 @@
| **LSP1UniversalReceiver** | `0x6bb56a14` | Interface of the LSP1 - Universal Receiver standard, an entry function for a contract to receive arbitrary information. |
| **LSP1UniversalReceiverDelegate** | `0xa245bbda` | Interface of the LSP1 - Universal Receiver Delegate standard. |
| **LSP6KeyManager** | `0x23f34c62` | Interface of the LSP6 - Key Manager standard, a contract acting as a controller of an ERC725 Account using predfined permissions. |
-| **LSP7DigitalAsset** | `0xb3c4928f` | Interface of the LSP7 - Digital Asset standard, a fungible digital asset. |
+| **LSP7DigitalAsset** | `0xc52d6008` | Interface of the LSP7 - Digital Asset standard, a fungible digital asset. |
| **LSP8IdentifiableDigitalAsset** | `0x3a271706` | Interface of the LSP8 - Identifiable Digital Asset standard, a non-fungible digital asset. |
| **LSP9Vault** | `0x28af17e6` | Interface of LSP9 - Vault standard, a blockchain vault that can hold assets and interact with other smart contracts. |
| **LSP11BasicSocialRecovery** | `0x049a28f1` | Interface of the LSP11 - Basic Social Recovery standard, a contract to recover access control into an account. |
diff --git a/docs/contracts/LSP7DigitalAsset/LSP7DigitalAsset.md b/docs/contracts/LSP7DigitalAsset/LSP7DigitalAsset.md
index 691daae1a..7766d68b5 100644
--- a/docs/contracts/LSP7DigitalAsset/LSP7DigitalAsset.md
+++ b/docs/contracts/LSP7DigitalAsset/LSP7DigitalAsset.md
@@ -250,14 +250,15 @@ Returns the number of decimals used to get its user representation. If the asset
- Specification details: [**LSP-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#decreaseallowance)
- Solidity implementation: [`LSP7DigitalAsset.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/LSP7DigitalAsset.sol)
-- Function signature: `decreaseAllowance(address,uint256,bytes)`
-- Function selector: `0x7b204c4e`
+- Function signature: `decreaseAllowance(address,address,uint256,bytes)`
+- Function selector: `0x78381670`
:::
```solidity
function decreaseAllowance(
address operator,
+ address tokenOwner,
uint256 subtractedAmount,
bytes operatorNotificationData
) external nonpayable;
@@ -272,6 +273,7 @@ Atomically decreases the allowance granted to `operator` by the caller. This is
| Name | Type | Description |
| -------------------------- | :-------: | ------------------------------------------------------ |
| `operator` | `address` | The operator to decrease allowance for `msg.sender` |
+| `tokenOwner` | `address` | The address of the token owner. |
| `subtractedAmount` | `uint256` | The amount to decrease by in the operator's allowance. |
| `operatorNotificationData` | `bytes` | - |
@@ -459,26 +461,28 @@ Leaves the contract without owner. It will not be possible to call `onlyOwner` f
- Specification details: [**LSP-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#revokeoperator)
- Solidity implementation: [`LSP7DigitalAsset.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/LSP7DigitalAsset.sol)
-- Function signature: `revokeOperator(address,bool,bytes)`
-- Function selector: `0x4521748e`
+- Function signature: `revokeOperator(address,address,bool,bytes)`
+- Function selector: `0x30d0dc37`
:::
```solidity
function revokeOperator(
address operator,
+ address tokenOwner,
bool notify,
bytes operatorNotificationData
) external nonpayable;
```
-Removes the `operator` address as an operator of callers tokens, disallowing it to send any amount of tokens on behalf of the token owner (the caller of the function `msg.sender`). See also [`authorizedAmountFor`](#authorizedamountfor).
+Enables `tokenOwner` to remove `operator` for its tokens, disallowing it to send any amount of tokens on its behalf. This function also allows the `operator` to remove itself if it is the caller of this function
#### Parameters
| Name | Type | Description |
| -------------------------- | :-------: | --------------------------------------------------------- |
| `operator` | `address` | The address to revoke as an operator. |
+| `tokenOwner` | `address` | The address of the token owner. |
| `notify` | `bool` | Boolean indicating whether to notify the operator or not. |
| `operatorNotificationData` | `bytes` | The data to notify the operator about via LSP1. |
@@ -1561,25 +1565,6 @@ Reverts when a batch call failed.
-### LSP7CannotSendToSelf
-
-:::note References
-
-- Specification details: [**LSP-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#lsp7cannotsendtoself)
-- Solidity implementation: [`LSP7DigitalAsset.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/LSP7DigitalAsset.sol)
-- Error signature: `LSP7CannotSendToSelf()`
-- Error hash: `0xb9afb000`
-
-:::
-
-```solidity
-error LSP7CannotSendToSelf();
-```
-
-reverts when specifying the same address for `from` or `to` in a token transfer.
-
-
-
### LSP7CannotSendWithAddressZero
:::note References
@@ -1624,6 +1609,37 @@ reverts when trying to set the zero address as an operator.
+### LSP7DecreaseAllowanceNotAuthorized
+
+:::note References
+
+- Specification details: [**LSP-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#lsp7decreaseallowancenotauthorized)
+- Solidity implementation: [`LSP7DigitalAsset.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/LSP7DigitalAsset.sol)
+- Error signature: `LSP7DecreaseAllowanceNotAuthorized(address,address,address)`
+- Error hash: `0x98ce2945`
+
+:::
+
+```solidity
+error LSP7DecreaseAllowanceNotAuthorized(
+ address caller,
+ address tokenOwner,
+ address operator
+);
+```
+
+Reverts when the call to decrease allowance is not authorized.
+
+#### Parameters
+
+| Name | Type | Description |
+| ------------ | :-------: | ----------- |
+| `caller` | `address` | - |
+| `tokenOwner` | `address` | - |
+| `operator` | `address` | - |
+
+
+
### LSP7DecreasedAllowanceBelowZero
:::note References
@@ -1714,6 +1730,37 @@ reverts if the `tokenReceiver` is an EOA when minting or transferring tokens wit
+### LSP7RevokeOperatorNotAuthorized
+
+:::note References
+
+- Specification details: [**LSP-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#lsp7revokeoperatornotauthorized)
+- Solidity implementation: [`LSP7DigitalAsset.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/LSP7DigitalAsset.sol)
+- Error signature: `LSP7RevokeOperatorNotAuthorized(address,address,address)`
+- Error hash: `0x1a525b32`
+
+:::
+
+```solidity
+error LSP7RevokeOperatorNotAuthorized(
+ address caller,
+ address tokenOwner,
+ address operator
+);
+```
+
+Reverts when the call to revoke operator is not authorized.
+
+#### Parameters
+
+| Name | Type | Description |
+| ------------ | :-------: | ----------- |
+| `caller` | `address` | - |
+| `tokenOwner` | `address` | - |
+| `operator` | `address` | - |
+
+
+
### LSP7TokenContractCannotHoldValue
:::note References
diff --git a/docs/contracts/LSP7DigitalAsset/extensions/LSP7Burnable.md b/docs/contracts/LSP7DigitalAsset/extensions/LSP7Burnable.md
index ac6cbe517..6650eee99 100644
--- a/docs/contracts/LSP7DigitalAsset/extensions/LSP7Burnable.md
+++ b/docs/contracts/LSP7DigitalAsset/extensions/LSP7Burnable.md
@@ -275,14 +275,15 @@ Returns the number of decimals used to get its user representation. If the asset
- Specification details: [**LSP-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#decreaseallowance)
- Solidity implementation: [`LSP7Burnable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/extensions/LSP7Burnable.sol)
-- Function signature: `decreaseAllowance(address,uint256,bytes)`
-- Function selector: `0x7b204c4e`
+- Function signature: `decreaseAllowance(address,address,uint256,bytes)`
+- Function selector: `0x78381670`
:::
```solidity
function decreaseAllowance(
address operator,
+ address tokenOwner,
uint256 subtractedAmount,
bytes operatorNotificationData
) external nonpayable;
@@ -297,6 +298,7 @@ Atomically decreases the allowance granted to `operator` by the caller. This is
| Name | Type | Description |
| -------------------------- | :-------: | ------------------------------------------------------ |
| `operator` | `address` | The operator to decrease allowance for `msg.sender` |
+| `tokenOwner` | `address` | The address of the token owner. |
| `subtractedAmount` | `uint256` | The amount to decrease by in the operator's allowance. |
| `operatorNotificationData` | `bytes` | - |
@@ -484,26 +486,28 @@ Leaves the contract without owner. It will not be possible to call `onlyOwner` f
- Specification details: [**LSP-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#revokeoperator)
- Solidity implementation: [`LSP7Burnable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/extensions/LSP7Burnable.sol)
-- Function signature: `revokeOperator(address,bool,bytes)`
-- Function selector: `0x4521748e`
+- Function signature: `revokeOperator(address,address,bool,bytes)`
+- Function selector: `0x30d0dc37`
:::
```solidity
function revokeOperator(
address operator,
+ address tokenOwner,
bool notify,
bytes operatorNotificationData
) external nonpayable;
```
-Removes the `operator` address as an operator of callers tokens, disallowing it to send any amount of tokens on behalf of the token owner (the caller of the function `msg.sender`). See also [`authorizedAmountFor`](#authorizedamountfor).
+Enables `tokenOwner` to remove `operator` for its tokens, disallowing it to send any amount of tokens on its behalf. This function also allows the `operator` to remove itself if it is the caller of this function
#### Parameters
| Name | Type | Description |
| -------------------------- | :-------: | --------------------------------------------------------- |
| `operator` | `address` | The address to revoke as an operator. |
+| `tokenOwner` | `address` | The address of the token owner. |
| `notify` | `bool` | Boolean indicating whether to notify the operator or not. |
| `operatorNotificationData` | `bytes` | The data to notify the operator about via LSP1. |
@@ -1586,25 +1590,6 @@ Reverts when a batch call failed.
-### LSP7CannotSendToSelf
-
-:::note References
-
-- Specification details: [**LSP-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#lsp7cannotsendtoself)
-- Solidity implementation: [`LSP7Burnable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/extensions/LSP7Burnable.sol)
-- Error signature: `LSP7CannotSendToSelf()`
-- Error hash: `0xb9afb000`
-
-:::
-
-```solidity
-error LSP7CannotSendToSelf();
-```
-
-reverts when specifying the same address for `from` or `to` in a token transfer.
-
-
-
### LSP7CannotSendWithAddressZero
:::note References
@@ -1649,6 +1634,37 @@ reverts when trying to set the zero address as an operator.
+### LSP7DecreaseAllowanceNotAuthorized
+
+:::note References
+
+- Specification details: [**LSP-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#lsp7decreaseallowancenotauthorized)
+- Solidity implementation: [`LSP7Burnable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/extensions/LSP7Burnable.sol)
+- Error signature: `LSP7DecreaseAllowanceNotAuthorized(address,address,address)`
+- Error hash: `0x98ce2945`
+
+:::
+
+```solidity
+error LSP7DecreaseAllowanceNotAuthorized(
+ address caller,
+ address tokenOwner,
+ address operator
+);
+```
+
+Reverts when the call to decrease allowance is not authorized.
+
+#### Parameters
+
+| Name | Type | Description |
+| ------------ | :-------: | ----------- |
+| `caller` | `address` | - |
+| `tokenOwner` | `address` | - |
+| `operator` | `address` | - |
+
+
+
### LSP7DecreasedAllowanceBelowZero
:::note References
@@ -1739,6 +1755,37 @@ reverts if the `tokenReceiver` is an EOA when minting or transferring tokens wit
+### LSP7RevokeOperatorNotAuthorized
+
+:::note References
+
+- Specification details: [**LSP-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#lsp7revokeoperatornotauthorized)
+- Solidity implementation: [`LSP7Burnable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/extensions/LSP7Burnable.sol)
+- Error signature: `LSP7RevokeOperatorNotAuthorized(address,address,address)`
+- Error hash: `0x1a525b32`
+
+:::
+
+```solidity
+error LSP7RevokeOperatorNotAuthorized(
+ address caller,
+ address tokenOwner,
+ address operator
+);
+```
+
+Reverts when the call to revoke operator is not authorized.
+
+#### Parameters
+
+| Name | Type | Description |
+| ------------ | :-------: | ----------- |
+| `caller` | `address` | - |
+| `tokenOwner` | `address` | - |
+| `operator` | `address` | - |
+
+
+
### LSP7TokenContractCannotHoldValue
:::note References
diff --git a/docs/contracts/LSP7DigitalAsset/extensions/LSP7CappedSupply.md b/docs/contracts/LSP7DigitalAsset/extensions/LSP7CappedSupply.md
index 9d9823443..c70451ebe 100644
--- a/docs/contracts/LSP7DigitalAsset/extensions/LSP7CappedSupply.md
+++ b/docs/contracts/LSP7DigitalAsset/extensions/LSP7CappedSupply.md
@@ -248,14 +248,15 @@ Returns the number of decimals used to get its user representation. If the asset
- Specification details: [**LSP-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#decreaseallowance)
- Solidity implementation: [`LSP7CappedSupply.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/extensions/LSP7CappedSupply.sol)
-- Function signature: `decreaseAllowance(address,uint256,bytes)`
-- Function selector: `0x7b204c4e`
+- Function signature: `decreaseAllowance(address,address,uint256,bytes)`
+- Function selector: `0x78381670`
:::
```solidity
function decreaseAllowance(
address operator,
+ address tokenOwner,
uint256 subtractedAmount,
bytes operatorNotificationData
) external nonpayable;
@@ -270,6 +271,7 @@ Atomically decreases the allowance granted to `operator` by the caller. This is
| Name | Type | Description |
| -------------------------- | :-------: | ------------------------------------------------------ |
| `operator` | `address` | The operator to decrease allowance for `msg.sender` |
+| `tokenOwner` | `address` | The address of the token owner. |
| `subtractedAmount` | `uint256` | The amount to decrease by in the operator's allowance. |
| `operatorNotificationData` | `bytes` | - |
@@ -457,26 +459,28 @@ Leaves the contract without owner. It will not be possible to call `onlyOwner` f
- Specification details: [**LSP-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#revokeoperator)
- Solidity implementation: [`LSP7CappedSupply.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/extensions/LSP7CappedSupply.sol)
-- Function signature: `revokeOperator(address,bool,bytes)`
-- Function selector: `0x4521748e`
+- Function signature: `revokeOperator(address,address,bool,bytes)`
+- Function selector: `0x30d0dc37`
:::
```solidity
function revokeOperator(
address operator,
+ address tokenOwner,
bool notify,
bytes operatorNotificationData
) external nonpayable;
```
-Removes the `operator` address as an operator of callers tokens, disallowing it to send any amount of tokens on behalf of the token owner (the caller of the function `msg.sender`). See also [`authorizedAmountFor`](#authorizedamountfor).
+Enables `tokenOwner` to remove `operator` for its tokens, disallowing it to send any amount of tokens on its behalf. This function also allows the `operator` to remove itself if it is the caller of this function
#### Parameters
| Name | Type | Description |
| -------------------------- | :-------: | --------------------------------------------------------- |
| `operator` | `address` | The address to revoke as an operator. |
+| `tokenOwner` | `address` | The address of the token owner. |
| `notify` | `bool` | Boolean indicating whether to notify the operator or not. |
| `operatorNotificationData` | `bytes` | The data to notify the operator about via LSP1. |
@@ -1560,25 +1564,6 @@ Reverts when a batch call failed.
-### LSP7CannotSendToSelf
-
-:::note References
-
-- Specification details: [**LSP-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#lsp7cannotsendtoself)
-- Solidity implementation: [`LSP7CappedSupply.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/extensions/LSP7CappedSupply.sol)
-- Error signature: `LSP7CannotSendToSelf()`
-- Error hash: `0xb9afb000`
-
-:::
-
-```solidity
-error LSP7CannotSendToSelf();
-```
-
-reverts when specifying the same address for `from` or `to` in a token transfer.
-
-
-
### LSP7CannotSendWithAddressZero
:::note References
@@ -1665,6 +1650,37 @@ Reverts when setting `0` for the [`tokenSupplyCap`](#tokensupplycap). The max to
+### LSP7DecreaseAllowanceNotAuthorized
+
+:::note References
+
+- Specification details: [**LSP-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#lsp7decreaseallowancenotauthorized)
+- Solidity implementation: [`LSP7CappedSupply.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/extensions/LSP7CappedSupply.sol)
+- Error signature: `LSP7DecreaseAllowanceNotAuthorized(address,address,address)`
+- Error hash: `0x98ce2945`
+
+:::
+
+```solidity
+error LSP7DecreaseAllowanceNotAuthorized(
+ address caller,
+ address tokenOwner,
+ address operator
+);
+```
+
+Reverts when the call to decrease allowance is not authorized.
+
+#### Parameters
+
+| Name | Type | Description |
+| ------------ | :-------: | ----------- |
+| `caller` | `address` | - |
+| `tokenOwner` | `address` | - |
+| `operator` | `address` | - |
+
+
+
### LSP7DecreasedAllowanceBelowZero
:::note References
@@ -1755,6 +1771,37 @@ reverts if the `tokenReceiver` is an EOA when minting or transferring tokens wit
+### LSP7RevokeOperatorNotAuthorized
+
+:::note References
+
+- Specification details: [**LSP-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#lsp7revokeoperatornotauthorized)
+- Solidity implementation: [`LSP7CappedSupply.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/extensions/LSP7CappedSupply.sol)
+- Error signature: `LSP7RevokeOperatorNotAuthorized(address,address,address)`
+- Error hash: `0x1a525b32`
+
+:::
+
+```solidity
+error LSP7RevokeOperatorNotAuthorized(
+ address caller,
+ address tokenOwner,
+ address operator
+);
+```
+
+Reverts when the call to revoke operator is not authorized.
+
+#### Parameters
+
+| Name | Type | Description |
+| ------------ | :-------: | ----------- |
+| `caller` | `address` | - |
+| `tokenOwner` | `address` | - |
+| `operator` | `address` | - |
+
+
+
### LSP7TokenContractCannotHoldValue
:::note References
diff --git a/docs/contracts/LSP7DigitalAsset/presets/LSP7Mintable.md b/docs/contracts/LSP7DigitalAsset/presets/LSP7Mintable.md
index 00e9cb8e7..eb1a125ae 100644
--- a/docs/contracts/LSP7DigitalAsset/presets/LSP7Mintable.md
+++ b/docs/contracts/LSP7DigitalAsset/presets/LSP7Mintable.md
@@ -281,14 +281,15 @@ Returns the number of decimals used to get its user representation. If the asset
- Specification details: [**LSP-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#decreaseallowance)
- Solidity implementation: [`LSP7Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/presets/LSP7Mintable.sol)
-- Function signature: `decreaseAllowance(address,uint256,bytes)`
-- Function selector: `0x7b204c4e`
+- Function signature: `decreaseAllowance(address,address,uint256,bytes)`
+- Function selector: `0x78381670`
:::
```solidity
function decreaseAllowance(
address operator,
+ address tokenOwner,
uint256 subtractedAmount,
bytes operatorNotificationData
) external nonpayable;
@@ -303,6 +304,7 @@ Atomically decreases the allowance granted to `operator` by the caller. This is
| Name | Type | Description |
| -------------------------- | :-------: | ------------------------------------------------------ |
| `operator` | `address` | The operator to decrease allowance for `msg.sender` |
+| `tokenOwner` | `address` | The address of the token owner. |
| `subtractedAmount` | `uint256` | The amount to decrease by in the operator's allowance. |
| `operatorNotificationData` | `bytes` | - |
@@ -523,26 +525,28 @@ Leaves the contract without owner. It will not be possible to call `onlyOwner` f
- Specification details: [**LSP-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#revokeoperator)
- Solidity implementation: [`LSP7Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/presets/LSP7Mintable.sol)
-- Function signature: `revokeOperator(address,bool,bytes)`
-- Function selector: `0x4521748e`
+- Function signature: `revokeOperator(address,address,bool,bytes)`
+- Function selector: `0x30d0dc37`
:::
```solidity
function revokeOperator(
address operator,
+ address tokenOwner,
bool notify,
bytes operatorNotificationData
) external nonpayable;
```
-Removes the `operator` address as an operator of callers tokens, disallowing it to send any amount of tokens on behalf of the token owner (the caller of the function `msg.sender`). See also [`authorizedAmountFor`](#authorizedamountfor).
+Enables `tokenOwner` to remove `operator` for its tokens, disallowing it to send any amount of tokens on its behalf. This function also allows the `operator` to remove itself if it is the caller of this function
#### Parameters
| Name | Type | Description |
| -------------------------- | :-------: | --------------------------------------------------------- |
| `operator` | `address` | The address to revoke as an operator. |
+| `tokenOwner` | `address` | The address of the token owner. |
| `notify` | `bool` | Boolean indicating whether to notify the operator or not. |
| `operatorNotificationData` | `bytes` | The data to notify the operator about via LSP1. |
@@ -1625,25 +1629,6 @@ Reverts when a batch call failed.
-### LSP7CannotSendToSelf
-
-:::note References
-
-- Specification details: [**LSP-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#lsp7cannotsendtoself)
-- Solidity implementation: [`LSP7Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/presets/LSP7Mintable.sol)
-- Error signature: `LSP7CannotSendToSelf()`
-- Error hash: `0xb9afb000`
-
-:::
-
-```solidity
-error LSP7CannotSendToSelf();
-```
-
-reverts when specifying the same address for `from` or `to` in a token transfer.
-
-
-
### LSP7CannotSendWithAddressZero
:::note References
@@ -1688,6 +1673,37 @@ reverts when trying to set the zero address as an operator.
+### LSP7DecreaseAllowanceNotAuthorized
+
+:::note References
+
+- Specification details: [**LSP-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#lsp7decreaseallowancenotauthorized)
+- Solidity implementation: [`LSP7Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/presets/LSP7Mintable.sol)
+- Error signature: `LSP7DecreaseAllowanceNotAuthorized(address,address,address)`
+- Error hash: `0x98ce2945`
+
+:::
+
+```solidity
+error LSP7DecreaseAllowanceNotAuthorized(
+ address caller,
+ address tokenOwner,
+ address operator
+);
+```
+
+Reverts when the call to decrease allowance is not authorized.
+
+#### Parameters
+
+| Name | Type | Description |
+| ------------ | :-------: | ----------- |
+| `caller` | `address` | - |
+| `tokenOwner` | `address` | - |
+| `operator` | `address` | - |
+
+
+
### LSP7DecreasedAllowanceBelowZero
:::note References
@@ -1778,6 +1794,37 @@ reverts if the `tokenReceiver` is an EOA when minting or transferring tokens wit
+### LSP7RevokeOperatorNotAuthorized
+
+:::note References
+
+- Specification details: [**LSP-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#lsp7revokeoperatornotauthorized)
+- Solidity implementation: [`LSP7Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/presets/LSP7Mintable.sol)
+- Error signature: `LSP7RevokeOperatorNotAuthorized(address,address,address)`
+- Error hash: `0x1a525b32`
+
+:::
+
+```solidity
+error LSP7RevokeOperatorNotAuthorized(
+ address caller,
+ address tokenOwner,
+ address operator
+);
+```
+
+Reverts when the call to revoke operator is not authorized.
+
+#### Parameters
+
+| Name | Type | Description |
+| ------------ | :-------: | ----------- |
+| `caller` | `address` | - |
+| `tokenOwner` | `address` | - |
+| `operator` | `address` | - |
+
+
+
### LSP7TokenContractCannotHoldValue
:::note References
diff --git a/docs/contracts/LSP8IdentifiableDigitalAsset/LSP8IdentifiableDigitalAsset.md b/docs/contracts/LSP8IdentifiableDigitalAsset/LSP8IdentifiableDigitalAsset.md
index 708d6a325..227f072ba 100644
--- a/docs/contracts/LSP8IdentifiableDigitalAsset/LSP8IdentifiableDigitalAsset.md
+++ b/docs/contracts/LSP8IdentifiableDigitalAsset/LSP8IdentifiableDigitalAsset.md
@@ -1730,25 +1730,6 @@ Reverts when trying to send token to the zero address.
-### LSP8CannotSendToSelf
-
-:::note References
-
-- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#lsp8cannotsendtoself)
-- Solidity implementation: [`LSP8IdentifiableDigitalAsset.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/LSP8IdentifiableDigitalAsset.sol)
-- Error signature: `LSP8CannotSendToSelf()`
-- Error hash: `0x5d67d6c1`
-
-:::
-
-```solidity
-error LSP8CannotSendToSelf();
-```
-
-Reverts when specifying the same address for `from` and `to` in a token transfer.
-
-
-
### LSP8CannotUseAddressZeroAsOperator
:::note References
@@ -1969,6 +1950,37 @@ Reverts when `operator` is already authorized for the `tokenId`.
+### LSP8RevokeOperatorNotAuthorized
+
+:::note References
+
+- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#lsp8revokeoperatornotauthorized)
+- Solidity implementation: [`LSP8IdentifiableDigitalAsset.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/LSP8IdentifiableDigitalAsset.sol)
+- Error signature: `LSP8RevokeOperatorNotAuthorized(address,address,bytes32)`
+- Error hash: `0x760b5acd`
+
+:::
+
+```solidity
+error LSP8RevokeOperatorNotAuthorized(
+ address caller,
+ address tokenOwner,
+ bytes32 tokenId
+);
+```
+
+Reverts when the call to revoke operator is not authorized.
+
+#### Parameters
+
+| Name | Type | Description |
+| ------------ | :-------: | ----------- |
+| `caller` | `address` | - |
+| `tokenOwner` | `address` | - |
+| `tokenId` | `bytes32` | - |
+
+
+
### LSP8TokenContractCannotHoldValue
:::note References
diff --git a/docs/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8Burnable.md b/docs/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8Burnable.md
index 56f4230c9..86f50029d 100644
--- a/docs/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8Burnable.md
+++ b/docs/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8Burnable.md
@@ -1756,25 +1756,6 @@ Reverts when trying to send token to the zero address.
-### LSP8CannotSendToSelf
-
-:::note References
-
-- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#lsp8cannotsendtoself)
-- Solidity implementation: [`LSP8Burnable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8Burnable.sol)
-- Error signature: `LSP8CannotSendToSelf()`
-- Error hash: `0x5d67d6c1`
-
-:::
-
-```solidity
-error LSP8CannotSendToSelf();
-```
-
-Reverts when specifying the same address for `from` and `to` in a token transfer.
-
-
-
### LSP8CannotUseAddressZeroAsOperator
:::note References
@@ -1995,6 +1976,37 @@ Reverts when `operator` is already authorized for the `tokenId`.
+### LSP8RevokeOperatorNotAuthorized
+
+:::note References
+
+- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#lsp8revokeoperatornotauthorized)
+- Solidity implementation: [`LSP8Burnable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8Burnable.sol)
+- Error signature: `LSP8RevokeOperatorNotAuthorized(address,address,bytes32)`
+- Error hash: `0x760b5acd`
+
+:::
+
+```solidity
+error LSP8RevokeOperatorNotAuthorized(
+ address caller,
+ address tokenOwner,
+ bytes32 tokenId
+);
+```
+
+Reverts when the call to revoke operator is not authorized.
+
+#### Parameters
+
+| Name | Type | Description |
+| ------------ | :-------: | ----------- |
+| `caller` | `address` | - |
+| `tokenOwner` | `address` | - |
+| `tokenId` | `bytes32` | - |
+
+
+
### LSP8TokenContractCannotHoldValue
:::note References
diff --git a/docs/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CappedSupply.md b/docs/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CappedSupply.md
index 372210480..7315d4377 100644
--- a/docs/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CappedSupply.md
+++ b/docs/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CappedSupply.md
@@ -1730,25 +1730,6 @@ Reverts when trying to send token to the zero address.
-### LSP8CannotSendToSelf
-
-:::note References
-
-- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#lsp8cannotsendtoself)
-- Solidity implementation: [`LSP8CappedSupply.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CappedSupply.sol)
-- Error signature: `LSP8CannotSendToSelf()`
-- Error hash: `0x5d67d6c1`
-
-:::
-
-```solidity
-error LSP8CannotSendToSelf();
-```
-
-Reverts when specifying the same address for `from` and `to` in a token transfer.
-
-
-
### LSP8CannotUseAddressZeroAsOperator
:::note References
@@ -2011,6 +1992,37 @@ Reverts when `operator` is already authorized for the `tokenId`.
+### LSP8RevokeOperatorNotAuthorized
+
+:::note References
+
+- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#lsp8revokeoperatornotauthorized)
+- Solidity implementation: [`LSP8CappedSupply.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CappedSupply.sol)
+- Error signature: `LSP8RevokeOperatorNotAuthorized(address,address,bytes32)`
+- Error hash: `0x760b5acd`
+
+:::
+
+```solidity
+error LSP8RevokeOperatorNotAuthorized(
+ address caller,
+ address tokenOwner,
+ bytes32 tokenId
+);
+```
+
+Reverts when the call to revoke operator is not authorized.
+
+#### Parameters
+
+| Name | Type | Description |
+| ------------ | :-------: | ----------- |
+| `caller` | `address` | - |
+| `tokenOwner` | `address` | - |
+| `tokenId` | `bytes32` | - |
+
+
+
### LSP8TokenContractCannotHoldValue
:::note References
diff --git a/docs/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8Enumerable.md b/docs/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8Enumerable.md
index 9495edf7f..e73d15af1 100644
--- a/docs/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8Enumerable.md
+++ b/docs/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8Enumerable.md
@@ -1758,25 +1758,6 @@ Reverts when trying to send token to the zero address.
-### LSP8CannotSendToSelf
-
-:::note References
-
-- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#lsp8cannotsendtoself)
-- Solidity implementation: [`LSP8Enumerable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8Enumerable.sol)
-- Error signature: `LSP8CannotSendToSelf()`
-- Error hash: `0x5d67d6c1`
-
-:::
-
-```solidity
-error LSP8CannotSendToSelf();
-```
-
-Reverts when specifying the same address for `from` and `to` in a token transfer.
-
-
-
### LSP8CannotUseAddressZeroAsOperator
:::note References
@@ -1997,6 +1978,37 @@ Reverts when `operator` is already authorized for the `tokenId`.
+### LSP8RevokeOperatorNotAuthorized
+
+:::note References
+
+- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#lsp8revokeoperatornotauthorized)
+- Solidity implementation: [`LSP8Enumerable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8Enumerable.sol)
+- Error signature: `LSP8RevokeOperatorNotAuthorized(address,address,bytes32)`
+- Error hash: `0x760b5acd`
+
+:::
+
+```solidity
+error LSP8RevokeOperatorNotAuthorized(
+ address caller,
+ address tokenOwner,
+ bytes32 tokenId
+);
+```
+
+Reverts when the call to revoke operator is not authorized.
+
+#### Parameters
+
+| Name | Type | Description |
+| ------------ | :-------: | ----------- |
+| `caller` | `address` | - |
+| `tokenOwner` | `address` | - |
+| `tokenId` | `bytes32` | - |
+
+
+
### LSP8TokenContractCannotHoldValue
:::note References
diff --git a/docs/contracts/LSP8IdentifiableDigitalAsset/presets/LSP8Mintable.md b/docs/contracts/LSP8IdentifiableDigitalAsset/presets/LSP8Mintable.md
index 1a1c1ee76..fca4e87b5 100644
--- a/docs/contracts/LSP8IdentifiableDigitalAsset/presets/LSP8Mintable.md
+++ b/docs/contracts/LSP8IdentifiableDigitalAsset/presets/LSP8Mintable.md
@@ -1796,25 +1796,6 @@ Reverts when trying to send token to the zero address.
-### LSP8CannotSendToSelf
-
-:::note References
-
-- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#lsp8cannotsendtoself)
-- Solidity implementation: [`LSP8Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/presets/LSP8Mintable.sol)
-- Error signature: `LSP8CannotSendToSelf()`
-- Error hash: `0x5d67d6c1`
-
-:::
-
-```solidity
-error LSP8CannotSendToSelf();
-```
-
-Reverts when specifying the same address for `from` and `to` in a token transfer.
-
-
-
### LSP8CannotUseAddressZeroAsOperator
:::note References
@@ -2035,6 +2016,37 @@ Reverts when `operator` is already authorized for the `tokenId`.
+### LSP8RevokeOperatorNotAuthorized
+
+:::note References
+
+- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#lsp8revokeoperatornotauthorized)
+- Solidity implementation: [`LSP8Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/presets/LSP8Mintable.sol)
+- Error signature: `LSP8RevokeOperatorNotAuthorized(address,address,bytes32)`
+- Error hash: `0x760b5acd`
+
+:::
+
+```solidity
+error LSP8RevokeOperatorNotAuthorized(
+ address caller,
+ address tokenOwner,
+ bytes32 tokenId
+);
+```
+
+Reverts when the call to revoke operator is not authorized.
+
+#### Parameters
+
+| Name | Type | Description |
+| ------------ | :-------: | ----------- |
+| `caller` | `address` | - |
+| `tokenOwner` | `address` | - |
+| `tokenId` | `bytes32` | - |
+
+
+
### LSP8TokenContractCannotHoldValue
:::note References
diff --git a/tests/LSP7DigitalAsset/LSP7DigitalAsset.behaviour.ts b/tests/LSP7DigitalAsset/LSP7DigitalAsset.behaviour.ts
index 4761dfc0f..dff9137d8 100644
--- a/tests/LSP7DigitalAsset/LSP7DigitalAsset.behaviour.ts
+++ b/tests/LSP7DigitalAsset/LSP7DigitalAsset.behaviour.ts
@@ -446,10 +446,16 @@ export const shouldBehaveLikeLSP7 = (buildContext: () => Promise {
it('should revert', async () => {
+ const tokenOwner = context.accounts.owner.address;
const subtractedAmount = ethers.BigNumber.from('1');
await expect(
- context.lsp7.decreaseAllowance(ethers.constants.AddressZero, subtractedAmount, '0x'),
+ context.lsp7.decreaseAllowance(
+ ethers.constants.AddressZero,
+ tokenOwner,
+ subtractedAmount,
+ '0x',
+ ),
).to.be.revertedWithCustomError(
context.lsp7,
// Since we can never grant allowance for address(0), address(0) will always have 0 allowance
@@ -469,7 +475,7 @@ export const shouldBehaveLikeLSP7 = (buildContext: () => Promise Promise {
+ it("should decrease the operator's allowance by the `subtractedAmount` + emit `OperatorAuthorizationChanged` event", async () => {
+ const operator = context.accounts.operator.address;
+ const tokenOwner = context.accounts.owner.address;
+
+ const subtractedAmount = ethers.BigNumber.from('1');
+
+ const allowanceBefore = await context.lsp7.authorizedAmountFor(operator, tokenOwner);
+
+ const tx = await context.lsp7
+ .connect(context.accounts.operator)
+ .decreaseAllowance(operator, tokenOwner, subtractedAmount, '0x');
const expectedNewAllowance = allowanceBefore.sub(subtractedAmount);
@@ -505,7 +541,12 @@ export const shouldBehaveLikeLSP7 = (buildContext: () => Promise Promise {
it('should revert', async () => {
+ const tokenOwner = context.accounts.owner.address;
const subtractedAmount = ethers.BigNumber.from('1');
await expect(
- context.lsp7.decreaseAllowance(context.accounts.owner.address, subtractedAmount, '0x'),
+ context.lsp7.decreaseAllowance(
+ context.accounts.owner.address,
+ tokenOwner,
+ subtractedAmount,
+ '0x',
+ ),
).to.be.revertedWithCustomError(context.lsp7, 'LSP7TokenOwnerCannotBeOperator');
});
});
@@ -540,7 +587,12 @@ export const shouldBehaveLikeLSP7 = (buildContext: () => Promise Promise Promise {
+ const operator = context.accounts.operator.address;
+ const tokenOwner = context.accounts.owner.address;
+ const amount = context.initialSupply;
+
+ // pre-conditions
+ await context.lsp7.authorizeOperator(operator, amount, '0x');
+ expect(await context.lsp7.authorizedAmountFor(operator, tokenOwner)).to.equal(amount);
+
+ expect(await context.lsp7.getOperatorsOf(tokenOwner)).to.deep.equal([operator]);
+
+ // effects
+ const tx = await context.lsp7
+ .connect(context.accounts.operator)
+ .revokeOperator(operator, tokenOwner, false, '0x');
+
await expect(tx)
.to.emit(context.lsp7, 'OperatorRevoked')
.withArgs(operator, tokenOwner, false, '0x');
@@ -598,10 +678,11 @@ export const shouldBehaveLikeLSP7 = (buildContext: () => Promise {
it('should revert', async () => {
+ const tokenOwner = context.accounts.owner.address;
const operator = ethers.constants.AddressZero;
await expect(
- context.lsp7.revokeOperator(operator, false, '0x'),
+ context.lsp7.revokeOperator(operator, tokenOwner, false, '0x'),
).to.be.revertedWithCustomError(context.lsp7, 'LSP7CannotUseAddressZeroAsOperator');
});
});
@@ -611,7 +692,7 @@ export const shouldBehaveLikeLSP7 = (buildContext: () => Promise Promise Promise {
const operatorThatReverts: TokenReceiverWithLSP1Revert =
await new TokenReceiverWithLSP1Revert__factory(context.accounts.owner).deploy();
+ const tokenOwner = context.accounts.owner.address;
const operator = operatorThatReverts.address;
await context.lsp7.authorizeOperator(operator, 1, '0x');
await operatorThatReverts.addLSP1Support();
- await expect(context.lsp7.revokeOperator(operator, false, '0xaabbccdd')).to.emit(
- context.lsp7,
- 'OperatorRevoked',
- );
+ await expect(
+ context.lsp7.revokeOperator(operator, tokenOwner, false, '0xaabbccdd'),
+ ).to.emit(context.lsp7, 'OperatorRevoked');
});
});
@@ -1050,7 +1132,7 @@ export const shouldBehaveLikeLSP7 = (buildContext: () => Promise context.accounts.operator);
describe('when `from` and `to` address are the same', () => {
- it('should revert', async () => {
+ it('should pass', async () => {
const operator = context.accounts.operator;
const txParams = {
@@ -1067,17 +1149,15 @@ export const shouldBehaveLikeLSP7 = (buildContext: () => Promise Promise Promise context.accounts.operator);
describe('when `to` and `from` are the same address', () => {
- it('should revert', async () => {
+ it('should pass', async () => {
const operator = context.accounts.operator;
const txParams = {
from: [context.accounts.owner.address, context.accounts.owner.address],
@@ -1641,12 +1721,8 @@ export const shouldBehaveLikeLSP7 = (buildContext: () => Promise Promise {
const revokeOperatorCalldata = context.lsp7.interface.encodeFunctionData(
'revokeOperator',
- [context.accounts.tokenReceiver.address, true, '0x'],
+ [context.accounts.tokenReceiver.address, context.accounts.owner.address, true, '0x'],
);
await expect(
@@ -2335,7 +2411,7 @@ export const shouldBehaveLikeLSP7 = (buildContext: () => Promise {
+ describe('when operator is not the zero address', () => {
+ it('should succeed', async () => {
+ const operator = context.accounts.operator.address;
+ const tokenOwner = context.accounts.owner.address;
+ const tokenId = mintedTokenId;
+
+ // pre-conditions
+ await context.lsp8.authorizeOperator(operator, tokenId, '0x');
+ expect(await context.lsp8.isOperatorFor(operator, tokenId)).to.be.true;
+
+ // effects
+ const tx = await context.lsp8
+ .connect(context.accounts.operator)
+ .revokeOperator(operator, tokenId, false, '0x');
+
+ await expect(tx)
+ .to.emit(context.lsp8, 'OperatorRevoked')
+ .withArgs(operator, tokenOwner, tokenId, false, '0x');
+
+ // post-conditions
+ expect(await context.lsp8.isOperatorFor(operator, tokenId)).to.be.false;
+ });
+ });
+ });
});
describe('isOperatorFor', () => {
@@ -920,30 +946,6 @@ export const shouldBehaveLikeLSP8 = (
});
});
});
-
- describe("when `from == to` address (= sending to tokenId's owner itself)", () => {
- it('should revert', async () => {
- const txParams = {
- from: context.accounts.owner.address,
- to: context.accounts.owner.address,
- tokenId: mintedTokenId,
- force,
- data,
- };
-
- await expect(
- context.lsp8
- .connect(operator)
- .transfer(
- txParams.from,
- txParams.to,
- txParams.tokenId,
- txParams.force,
- txParams.data,
- ),
- ).to.be.revertedWithCustomError(context.lsp8, 'LSP8CannotSendToSelf');
- });
- });
});
describe('when force=false', () => {
@@ -1055,7 +1057,7 @@ export const shouldBehaveLikeLSP8 = (
txParams.force,
txParams.data,
),
- ).to.be.revertedWithCustomError(context.lsp8, 'LSP8CannotSendToSelf');
+ ).to.be.revertedWithCustomError(context.lsp8, 'LSP8NotifyTokenReceiverIsEOA');
});
});
});