@lukso/lsp8-contracts 0.17.3 → 0.18.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +69 -24
- package/artifacts/IAccessControlExtended.json +1 -1
- package/artifacts/ILSP8CappedBalance.json +1 -1
- package/artifacts/ILSP8CappedSupply.json +1 -1
- package/artifacts/ILSP8IdentifiableDigitalAsset.json +1 -1
- package/artifacts/ILSP8Mintable.json +1 -1
- package/artifacts/ILSP8NonTransferable.json +8 -2
- package/artifacts/ILSP8Revokable.json +38 -1
- package/artifacts/LSP8Burnable.json +1 -1
- package/artifacts/LSP8BurnableInitAbstract.json +1 -1
- package/artifacts/LSP8CappedBalanceAbstract.json +1 -1
- package/artifacts/LSP8CappedBalanceInitAbstract.json +1 -1
- package/artifacts/LSP8CappedSupplyAbstract.json +1 -1
- package/artifacts/LSP8CappedSupplyInitAbstract.json +1 -1
- package/artifacts/LSP8CustomizableToken.json +64 -21
- package/artifacts/LSP8CustomizableTokenInit.json +59 -16
- package/artifacts/LSP8Enumerable.json +1 -1
- package/artifacts/LSP8EnumerableInitAbstract.json +1 -1
- package/artifacts/LSP8IdentifiableDigitalAsset.json +1 -1
- package/artifacts/LSP8IdentifiableDigitalAssetInitAbstract.json +1 -1
- package/artifacts/LSP8Mintable.json +1 -1
- package/artifacts/LSP8MintableAbstract.json +1 -1
- package/artifacts/LSP8MintableInit.json +1 -1
- package/artifacts/LSP8MintableInitAbstract.json +1 -1
- package/artifacts/LSP8NonTransferableAbstract.json +20 -14
- package/artifacts/LSP8NonTransferableInitAbstract.json +20 -14
- package/artifacts/LSP8RevokableAbstract.json +38 -1
- package/artifacts/LSP8RevokableInitAbstract.json +38 -1
- package/artifacts/LSP8Votes.json +1 -1
- package/artifacts/LSP8VotesInitAbstract.json +1 -1
- package/contracts/extensions/LSP8NonTransferable/ILSP8NonTransferable.sol +9 -3
- package/contracts/extensions/LSP8NonTransferable/LSP8NonTransferableAbstract.sol +17 -8
- package/contracts/extensions/LSP8NonTransferable/LSP8NonTransferableInitAbstract.sol +17 -8
- package/contracts/extensions/LSP8Revokable/ILSP8Revokable.sol +9 -0
- package/contracts/extensions/LSP8Revokable/LSP8RevokableAbstract.sol +8 -0
- package/contracts/extensions/LSP8Revokable/LSP8RevokableInitAbstract.sol +15 -1
- package/dist/abi.cjs +169 -29
- package/dist/abi.d.cts +216 -41
- package/dist/abi.d.mts +216 -41
- package/dist/abi.d.ts +216 -41
- package/dist/abi.mjs +169 -29
- package/package.json +1 -1
|
@@ -564,6 +564,12 @@
|
|
|
564
564
|
{
|
|
565
565
|
"anonymous": false,
|
|
566
566
|
"inputs": [
|
|
567
|
+
{
|
|
568
|
+
"indexed": true,
|
|
569
|
+
"internalType": "bool",
|
|
570
|
+
"name": "nonTransferabilityEnabled",
|
|
571
|
+
"type": "bool"
|
|
572
|
+
},
|
|
567
573
|
{
|
|
568
574
|
"indexed": true,
|
|
569
575
|
"internalType": "uint256",
|
|
@@ -943,6 +949,19 @@
|
|
|
943
949
|
"stateMutability": "nonpayable",
|
|
944
950
|
"type": "function"
|
|
945
951
|
},
|
|
952
|
+
{
|
|
953
|
+
"inputs": [],
|
|
954
|
+
"name": "nonTransferabilityEnabled",
|
|
955
|
+
"outputs": [
|
|
956
|
+
{
|
|
957
|
+
"internalType": "bool",
|
|
958
|
+
"name": "",
|
|
959
|
+
"type": "bool"
|
|
960
|
+
}
|
|
961
|
+
],
|
|
962
|
+
"stateMutability": "view",
|
|
963
|
+
"type": "function"
|
|
964
|
+
},
|
|
946
965
|
{
|
|
947
966
|
"inputs": [],
|
|
948
967
|
"name": "owner",
|
|
@@ -1282,19 +1301,6 @@
|
|
|
1282
1301
|
"stateMutability": "nonpayable",
|
|
1283
1302
|
"type": "function"
|
|
1284
1303
|
},
|
|
1285
|
-
{
|
|
1286
|
-
"inputs": [],
|
|
1287
|
-
"name": "transferLockEnabled",
|
|
1288
|
-
"outputs": [
|
|
1289
|
-
{
|
|
1290
|
-
"internalType": "bool",
|
|
1291
|
-
"name": "",
|
|
1292
|
-
"type": "bool"
|
|
1293
|
-
}
|
|
1294
|
-
],
|
|
1295
|
-
"stateMutability": "view",
|
|
1296
|
-
"type": "function"
|
|
1297
|
-
},
|
|
1298
1304
|
{
|
|
1299
1305
|
"inputs": [],
|
|
1300
1306
|
"name": "transferLockEnd",
|
|
@@ -1363,5 +1369,5 @@
|
|
|
1363
1369
|
"deployedLinkReferences": {},
|
|
1364
1370
|
"immutableReferences": {},
|
|
1365
1371
|
"inputSourceName": "project/contracts/extensions/LSP8NonTransferable/LSP8NonTransferableAbstract.sol",
|
|
1366
|
-
"buildInfoId": "solc-0_8_28-
|
|
1372
|
+
"buildInfoId": "solc-0_8_28-a1f189205db65800e276c245fa7f2fa7071cb3a5"
|
|
1367
1373
|
}
|
|
@@ -572,6 +572,12 @@
|
|
|
572
572
|
{
|
|
573
573
|
"anonymous": false,
|
|
574
574
|
"inputs": [
|
|
575
|
+
{
|
|
576
|
+
"indexed": true,
|
|
577
|
+
"internalType": "bool",
|
|
578
|
+
"name": "nonTransferabilityEnabled",
|
|
579
|
+
"type": "bool"
|
|
580
|
+
},
|
|
575
581
|
{
|
|
576
582
|
"indexed": true,
|
|
577
583
|
"internalType": "uint256",
|
|
@@ -951,6 +957,19 @@
|
|
|
951
957
|
"stateMutability": "nonpayable",
|
|
952
958
|
"type": "function"
|
|
953
959
|
},
|
|
960
|
+
{
|
|
961
|
+
"inputs": [],
|
|
962
|
+
"name": "nonTransferabilityEnabled",
|
|
963
|
+
"outputs": [
|
|
964
|
+
{
|
|
965
|
+
"internalType": "bool",
|
|
966
|
+
"name": "",
|
|
967
|
+
"type": "bool"
|
|
968
|
+
}
|
|
969
|
+
],
|
|
970
|
+
"stateMutability": "view",
|
|
971
|
+
"type": "function"
|
|
972
|
+
},
|
|
954
973
|
{
|
|
955
974
|
"inputs": [],
|
|
956
975
|
"name": "owner",
|
|
@@ -1290,19 +1309,6 @@
|
|
|
1290
1309
|
"stateMutability": "nonpayable",
|
|
1291
1310
|
"type": "function"
|
|
1292
1311
|
},
|
|
1293
|
-
{
|
|
1294
|
-
"inputs": [],
|
|
1295
|
-
"name": "transferLockEnabled",
|
|
1296
|
-
"outputs": [
|
|
1297
|
-
{
|
|
1298
|
-
"internalType": "bool",
|
|
1299
|
-
"name": "",
|
|
1300
|
-
"type": "bool"
|
|
1301
|
-
}
|
|
1302
|
-
],
|
|
1303
|
-
"stateMutability": "view",
|
|
1304
|
-
"type": "function"
|
|
1305
|
-
},
|
|
1306
1312
|
{
|
|
1307
1313
|
"inputs": [],
|
|
1308
1314
|
"name": "transferLockEnd",
|
|
@@ -1371,5 +1377,5 @@
|
|
|
1371
1377
|
"deployedLinkReferences": {},
|
|
1372
1378
|
"immutableReferences": {},
|
|
1373
1379
|
"inputSourceName": "project/contracts/extensions/LSP8NonTransferable/LSP8NonTransferableInitAbstract.sol",
|
|
1374
|
-
"buildInfoId": "solc-0_8_28-
|
|
1380
|
+
"buildInfoId": "solc-0_8_28-a1f189205db65800e276c245fa7f2fa7071cb3a5"
|
|
1375
1381
|
}
|
|
@@ -516,6 +516,43 @@
|
|
|
516
516
|
"name": "TokenIdDataChanged",
|
|
517
517
|
"type": "event"
|
|
518
518
|
},
|
|
519
|
+
{
|
|
520
|
+
"anonymous": false,
|
|
521
|
+
"inputs": [
|
|
522
|
+
{
|
|
523
|
+
"indexed": true,
|
|
524
|
+
"internalType": "address",
|
|
525
|
+
"name": "revoker",
|
|
526
|
+
"type": "address"
|
|
527
|
+
},
|
|
528
|
+
{
|
|
529
|
+
"indexed": true,
|
|
530
|
+
"internalType": "address",
|
|
531
|
+
"name": "from",
|
|
532
|
+
"type": "address"
|
|
533
|
+
},
|
|
534
|
+
{
|
|
535
|
+
"indexed": true,
|
|
536
|
+
"internalType": "address",
|
|
537
|
+
"name": "to",
|
|
538
|
+
"type": "address"
|
|
539
|
+
},
|
|
540
|
+
{
|
|
541
|
+
"indexed": false,
|
|
542
|
+
"internalType": "bytes32",
|
|
543
|
+
"name": "tokenId",
|
|
544
|
+
"type": "bytes32"
|
|
545
|
+
},
|
|
546
|
+
{
|
|
547
|
+
"indexed": false,
|
|
548
|
+
"internalType": "bytes",
|
|
549
|
+
"name": "data",
|
|
550
|
+
"type": "bytes"
|
|
551
|
+
}
|
|
552
|
+
],
|
|
553
|
+
"name": "TokenRevoked",
|
|
554
|
+
"type": "event"
|
|
555
|
+
},
|
|
519
556
|
{
|
|
520
557
|
"anonymous": false,
|
|
521
558
|
"inputs": [
|
|
@@ -1313,5 +1350,5 @@
|
|
|
1313
1350
|
"deployedLinkReferences": {},
|
|
1314
1351
|
"immutableReferences": {},
|
|
1315
1352
|
"inputSourceName": "project/contracts/extensions/LSP8Revokable/LSP8RevokableAbstract.sol",
|
|
1316
|
-
"buildInfoId": "solc-0_8_28-
|
|
1353
|
+
"buildInfoId": "solc-0_8_28-a1f189205db65800e276c245fa7f2fa7071cb3a5"
|
|
1317
1354
|
}
|
|
@@ -524,6 +524,43 @@
|
|
|
524
524
|
"name": "TokenIdDataChanged",
|
|
525
525
|
"type": "event"
|
|
526
526
|
},
|
|
527
|
+
{
|
|
528
|
+
"anonymous": false,
|
|
529
|
+
"inputs": [
|
|
530
|
+
{
|
|
531
|
+
"indexed": true,
|
|
532
|
+
"internalType": "address",
|
|
533
|
+
"name": "revoker",
|
|
534
|
+
"type": "address"
|
|
535
|
+
},
|
|
536
|
+
{
|
|
537
|
+
"indexed": true,
|
|
538
|
+
"internalType": "address",
|
|
539
|
+
"name": "from",
|
|
540
|
+
"type": "address"
|
|
541
|
+
},
|
|
542
|
+
{
|
|
543
|
+
"indexed": true,
|
|
544
|
+
"internalType": "address",
|
|
545
|
+
"name": "to",
|
|
546
|
+
"type": "address"
|
|
547
|
+
},
|
|
548
|
+
{
|
|
549
|
+
"indexed": false,
|
|
550
|
+
"internalType": "bytes32",
|
|
551
|
+
"name": "tokenId",
|
|
552
|
+
"type": "bytes32"
|
|
553
|
+
},
|
|
554
|
+
{
|
|
555
|
+
"indexed": false,
|
|
556
|
+
"internalType": "bytes",
|
|
557
|
+
"name": "data",
|
|
558
|
+
"type": "bytes"
|
|
559
|
+
}
|
|
560
|
+
],
|
|
561
|
+
"name": "TokenRevoked",
|
|
562
|
+
"type": "event"
|
|
563
|
+
},
|
|
527
564
|
{
|
|
528
565
|
"anonymous": false,
|
|
529
566
|
"inputs": [
|
|
@@ -1321,5 +1358,5 @@
|
|
|
1321
1358
|
"deployedLinkReferences": {},
|
|
1322
1359
|
"immutableReferences": {},
|
|
1323
1360
|
"inputSourceName": "project/contracts/extensions/LSP8Revokable/LSP8RevokableInitAbstract.sol",
|
|
1324
|
-
"buildInfoId": "solc-0_8_28-
|
|
1361
|
+
"buildInfoId": "solc-0_8_28-a1f189205db65800e276c245fa7f2fa7071cb3a5"
|
|
1325
1362
|
}
|
package/artifacts/LSP8Votes.json
CHANGED
|
@@ -1229,5 +1229,5 @@
|
|
|
1229
1229
|
"deployedLinkReferences": {},
|
|
1230
1230
|
"immutableReferences": {},
|
|
1231
1231
|
"inputSourceName": "project/contracts/extensions/LSP8Votes/LSP8Votes.sol",
|
|
1232
|
-
"buildInfoId": "solc-0_8_28-
|
|
1232
|
+
"buildInfoId": "solc-0_8_28-a1f189205db65800e276c245fa7f2fa7071cb3a5"
|
|
1233
1233
|
}
|
|
@@ -1221,5 +1221,5 @@
|
|
|
1221
1221
|
"deployedLinkReferences": {},
|
|
1222
1222
|
"immutableReferences": {},
|
|
1223
1223
|
"inputSourceName": "project/contracts/extensions/LSP8Votes/LSP8VotesInitAbstract.sol",
|
|
1224
|
-
"buildInfoId": "solc-0_8_28-
|
|
1224
|
+
"buildInfoId": "solc-0_8_28-a1f189205db65800e276c245fa7f2fa7071cb3a5"
|
|
1225
1225
|
}
|
|
@@ -5,9 +5,14 @@ pragma solidity ^0.8.27;
|
|
|
5
5
|
/// @dev Interface for a non-transferable LSP8 token, enabling control over transferability, lock periods, and role-based exemptions.
|
|
6
6
|
interface ILSP8NonTransferable {
|
|
7
7
|
/// @dev Emitted when the transfer lock period is updated.
|
|
8
|
+
/// @param nonTransferabilityEnabled Whether the non-transferability feature is enabled or not.
|
|
8
9
|
/// @param start The new start timestamp of the transfer lock period.
|
|
9
10
|
/// @param end The new end timestamp of the transfer lock period.
|
|
10
|
-
event TransferLockPeriodChanged(
|
|
11
|
+
event TransferLockPeriodChanged(
|
|
12
|
+
bool indexed nonTransferabilityEnabled,
|
|
13
|
+
uint256 indexed start,
|
|
14
|
+
uint256 indexed end
|
|
15
|
+
);
|
|
11
16
|
|
|
12
17
|
/// @notice The start timestamp of the transfer lock period, at which point the token becomes non-transferable.
|
|
13
18
|
function transferLockStart() external view returns (uint256);
|
|
@@ -17,7 +22,7 @@ interface ILSP8NonTransferable {
|
|
|
17
22
|
|
|
18
23
|
/// @notice Returns whether the transfer lock feature is still enabled.
|
|
19
24
|
/// @dev When this returns `false`, the token has been permanently made transferable and the lock period can no longer be updated.
|
|
20
|
-
function
|
|
25
|
+
function nonTransferabilityEnabled() external view returns (bool);
|
|
21
26
|
|
|
22
27
|
/// @notice Checks if the token is currently transferable.
|
|
23
28
|
/// @dev Returns true if the token is transferable (based on the lock period). Note that transfers from addresses holding the bypass role and burning (transfers to address(0)) is always allowed, regardless of transferability status.
|
|
@@ -34,7 +39,8 @@ interface ILSP8NonTransferable {
|
|
|
34
39
|
/// - When `transferLockStart` is set to a value and `transferLockEnd` is 0, it means the tokens becomes non-transferable at a certain point in time and indefinitely (no end time).
|
|
35
40
|
///
|
|
36
41
|
/// - To make the token always non-transferable, set `transferLockStart` to 0 and `transferLockEnd` to type(uint256).max.
|
|
37
|
-
/// - To
|
|
42
|
+
/// - To remove the active lock while keeping the non-transferability feature configurable, set both `newTransferLockStart` and `newTransferLockEnd` to 0. In this state, transfers are currently unrestricted, but the owner can still configure a new lock period later.
|
|
43
|
+
/// - To permanently disable the non-transferability feature and prevent future lock-period updates, use the {makeTransferable} function.
|
|
38
44
|
///
|
|
39
45
|
/// @dev Can only be called by the contract owner. Reverts once {makeTransferable} has been called.
|
|
40
46
|
///
|
|
@@ -39,7 +39,7 @@ abstract contract LSP8NonTransferableAbstract is
|
|
|
39
39
|
uint256 public transferLockEnd;
|
|
40
40
|
|
|
41
41
|
/// @inheritdoc ILSP8NonTransferable
|
|
42
|
-
bool public
|
|
42
|
+
bool public nonTransferabilityEnabled;
|
|
43
43
|
|
|
44
44
|
/// @notice Initializes the contract with lock period.
|
|
45
45
|
/// @param transferLockStart_ The start timestamp of the transfer lock period, 0 to disable.
|
|
@@ -51,9 +51,13 @@ abstract contract LSP8NonTransferableAbstract is
|
|
|
51
51
|
);
|
|
52
52
|
transferLockStart = transferLockStart_;
|
|
53
53
|
transferLockEnd = transferLockEnd_;
|
|
54
|
-
|
|
54
|
+
nonTransferabilityEnabled = true;
|
|
55
55
|
|
|
56
|
-
emit TransferLockPeriodChanged(
|
|
56
|
+
emit TransferLockPeriodChanged({
|
|
57
|
+
nonTransferabilityEnabled: true,
|
|
58
|
+
start: transferLockStart_,
|
|
59
|
+
end: transferLockEnd_
|
|
60
|
+
});
|
|
57
61
|
_grantRole(NON_TRANSFERABLE_BYPASS_ROLE, owner());
|
|
58
62
|
}
|
|
59
63
|
|
|
@@ -75,7 +79,7 @@ abstract contract LSP8NonTransferableAbstract is
|
|
|
75
79
|
// solhint-disable not-rely-on-time
|
|
76
80
|
// Transfer-lock windows are inherently time-based; `block.timestamp` is the intended source.
|
|
77
81
|
function isTransferable() public view virtual override returns (bool) {
|
|
78
|
-
if (!
|
|
82
|
+
if (!nonTransferabilityEnabled) return true;
|
|
79
83
|
|
|
80
84
|
bool isTransferLockStartEnabled = transferLockStart != 0;
|
|
81
85
|
bool isTransferLockEndEnabled = transferLockEnd != 0;
|
|
@@ -105,13 +109,17 @@ abstract contract LSP8NonTransferableAbstract is
|
|
|
105
109
|
/// @inheritdoc ILSP8NonTransferable
|
|
106
110
|
/// @custom:info The list of addresses holding the `NON_TRANSFERABLE_BYPASS_ROLE` remains populated after the non-transferable feature is switched off.
|
|
107
111
|
function makeTransferable() public virtual override onlyOwner {
|
|
108
|
-
require(
|
|
112
|
+
require(nonTransferabilityEnabled, LSP8TokenAlreadyTransferable());
|
|
109
113
|
|
|
110
|
-
|
|
114
|
+
nonTransferabilityEnabled = false;
|
|
111
115
|
transferLockStart = 0;
|
|
112
116
|
transferLockEnd = 0;
|
|
113
117
|
|
|
114
|
-
emit TransferLockPeriodChanged({
|
|
118
|
+
emit TransferLockPeriodChanged({
|
|
119
|
+
nonTransferabilityEnabled: false,
|
|
120
|
+
start: 0,
|
|
121
|
+
end: 0
|
|
122
|
+
});
|
|
115
123
|
}
|
|
116
124
|
|
|
117
125
|
/// @inheritdoc ILSP8NonTransferable
|
|
@@ -119,7 +127,7 @@ abstract contract LSP8NonTransferableAbstract is
|
|
|
119
127
|
uint256 newTransferLockStart,
|
|
120
128
|
uint256 newTransferLockEnd
|
|
121
129
|
) public virtual override onlyOwner {
|
|
122
|
-
require(
|
|
130
|
+
require(nonTransferabilityEnabled, LSP8CannotUpdateTransferLockPeriod());
|
|
123
131
|
|
|
124
132
|
// When transferLockEnd is 0, it means no end time is set (transfers locked indefinitely after transferLockStart)
|
|
125
133
|
// When transferLockStart is 0, it means no start time is set (transfers locked up until transferLockEnd)
|
|
@@ -134,6 +142,7 @@ abstract contract LSP8NonTransferableAbstract is
|
|
|
134
142
|
transferLockEnd = newTransferLockEnd;
|
|
135
143
|
|
|
136
144
|
emit TransferLockPeriodChanged({
|
|
145
|
+
nonTransferabilityEnabled: true,
|
|
137
146
|
start: newTransferLockStart,
|
|
138
147
|
end: newTransferLockEnd
|
|
139
148
|
});
|
|
@@ -42,7 +42,7 @@ abstract contract LSP8NonTransferableInitAbstract is
|
|
|
42
42
|
uint256 public transferLockEnd;
|
|
43
43
|
|
|
44
44
|
/// @inheritdoc ILSP8NonTransferable
|
|
45
|
-
bool public
|
|
45
|
+
bool public nonTransferabilityEnabled;
|
|
46
46
|
|
|
47
47
|
/// @notice Initializes the LSP8NonTransferable contract with base token params and transfer settings.
|
|
48
48
|
/// @dev Initializes the LSP8IdentifiableDigitalAsset base, the access control layer and transfer settings.
|
|
@@ -90,9 +90,13 @@ abstract contract LSP8NonTransferableInitAbstract is
|
|
|
90
90
|
);
|
|
91
91
|
transferLockStart = transferLockStart_;
|
|
92
92
|
transferLockEnd = transferLockEnd_;
|
|
93
|
-
|
|
93
|
+
nonTransferabilityEnabled = true;
|
|
94
94
|
|
|
95
|
-
emit TransferLockPeriodChanged(
|
|
95
|
+
emit TransferLockPeriodChanged({
|
|
96
|
+
nonTransferabilityEnabled: true,
|
|
97
|
+
start: transferLockStart_,
|
|
98
|
+
end: transferLockEnd_
|
|
99
|
+
});
|
|
96
100
|
_grantRole(NON_TRANSFERABLE_BYPASS_ROLE, owner());
|
|
97
101
|
}
|
|
98
102
|
|
|
@@ -119,7 +123,7 @@ abstract contract LSP8NonTransferableInitAbstract is
|
|
|
119
123
|
// solhint-disable not-rely-on-time
|
|
120
124
|
// Transfer-lock windows are inherently time-based; `block.timestamp` is the intended source.
|
|
121
125
|
function isTransferable() public view virtual override returns (bool) {
|
|
122
|
-
if (!
|
|
126
|
+
if (!nonTransferabilityEnabled) return true;
|
|
123
127
|
|
|
124
128
|
bool isTransferLockStartEnabled = transferLockStart != 0;
|
|
125
129
|
bool isTransferLockEndEnabled = transferLockEnd != 0;
|
|
@@ -149,13 +153,17 @@ abstract contract LSP8NonTransferableInitAbstract is
|
|
|
149
153
|
/// @inheritdoc ILSP8NonTransferable
|
|
150
154
|
/// @custom:info The list of addresses holding the `NON_TRANSFERABLE_BYPASS_ROLE` remains populated after the non-transferable feature is switched off.
|
|
151
155
|
function makeTransferable() public virtual override onlyOwner {
|
|
152
|
-
require(
|
|
156
|
+
require(nonTransferabilityEnabled, LSP8TokenAlreadyTransferable());
|
|
153
157
|
|
|
154
|
-
|
|
158
|
+
nonTransferabilityEnabled = false;
|
|
155
159
|
transferLockStart = 0;
|
|
156
160
|
transferLockEnd = 0;
|
|
157
161
|
|
|
158
|
-
emit TransferLockPeriodChanged({
|
|
162
|
+
emit TransferLockPeriodChanged({
|
|
163
|
+
nonTransferabilityEnabled: false,
|
|
164
|
+
start: 0,
|
|
165
|
+
end: 0
|
|
166
|
+
});
|
|
159
167
|
}
|
|
160
168
|
|
|
161
169
|
/// @inheritdoc ILSP8NonTransferable
|
|
@@ -163,7 +171,7 @@ abstract contract LSP8NonTransferableInitAbstract is
|
|
|
163
171
|
uint256 newTransferLockStart,
|
|
164
172
|
uint256 newTransferLockEnd
|
|
165
173
|
) public virtual override onlyOwner {
|
|
166
|
-
require(
|
|
174
|
+
require(nonTransferabilityEnabled, LSP8CannotUpdateTransferLockPeriod());
|
|
167
175
|
|
|
168
176
|
// When transferLockEnd is 0, it means no end time is set (transfers locked indefinitely after transferLockStart)
|
|
169
177
|
// When transferLockStart is 0, it means no start time is set (transfers locked up until transferLockEnd)
|
|
@@ -178,6 +186,7 @@ abstract contract LSP8NonTransferableInitAbstract is
|
|
|
178
186
|
transferLockEnd = newTransferLockEnd;
|
|
179
187
|
|
|
180
188
|
emit TransferLockPeriodChanged({
|
|
189
|
+
nonTransferabilityEnabled: true,
|
|
181
190
|
start: newTransferLockStart,
|
|
182
191
|
end: newTransferLockEnd
|
|
183
192
|
});
|
|
@@ -9,6 +9,15 @@ interface ILSP8Revokable {
|
|
|
9
9
|
/// @dev Emitted when revokable status is changed.
|
|
10
10
|
event RevokableStatusChanged(bool indexed enabled);
|
|
11
11
|
|
|
12
|
+
/// @dev Emitted when a token is revoked from a holder.
|
|
13
|
+
event TokenRevoked(
|
|
14
|
+
address indexed revoker,
|
|
15
|
+
address indexed from,
|
|
16
|
+
address indexed to,
|
|
17
|
+
bytes32 tokenId,
|
|
18
|
+
bytes data
|
|
19
|
+
);
|
|
20
|
+
|
|
12
21
|
/// @notice Returns whether the feature to revoke tokens from users is enabled or not.
|
|
13
22
|
function isRevokable() external view returns (bool);
|
|
14
23
|
|
|
@@ -75,6 +75,14 @@ abstract contract LSP8RevokableAbstract is
|
|
|
75
75
|
AccessControlUnauthorizedAccount(to, REVOKER_ROLE)
|
|
76
76
|
);
|
|
77
77
|
|
|
78
|
+
emit TokenRevoked({
|
|
79
|
+
revoker: msg.sender,
|
|
80
|
+
from: from,
|
|
81
|
+
to: to,
|
|
82
|
+
tokenId: tokenId,
|
|
83
|
+
data: data
|
|
84
|
+
});
|
|
85
|
+
|
|
78
86
|
// We assume revokers are trusted when specifying revocation destinations.
|
|
79
87
|
// Therefore, we bypass LSP1 receiver checks.
|
|
80
88
|
_transfer({
|
|
@@ -109,9 +109,23 @@ abstract contract LSP8RevokableInitAbstract is
|
|
|
109
109
|
AccessControlUnauthorizedAccount(to, REVOKER_ROLE)
|
|
110
110
|
);
|
|
111
111
|
|
|
112
|
+
emit TokenRevoked({
|
|
113
|
+
revoker: msg.sender,
|
|
114
|
+
from: from,
|
|
115
|
+
to: to,
|
|
116
|
+
tokenId: tokenId,
|
|
117
|
+
data: data
|
|
118
|
+
});
|
|
119
|
+
|
|
112
120
|
// We assume revokers are trusted when specifying revocation destinations.
|
|
113
121
|
// Therefore, we bypass LSP1 receiver checks.
|
|
114
|
-
_transfer(
|
|
122
|
+
_transfer({
|
|
123
|
+
from: from,
|
|
124
|
+
to: to,
|
|
125
|
+
tokenId: tokenId,
|
|
126
|
+
force: true,
|
|
127
|
+
data: data
|
|
128
|
+
});
|
|
115
129
|
}
|
|
116
130
|
|
|
117
131
|
function supportsInterface(
|