@bloxchain/contracts 1.0.0-alpha → 1.0.0-alpha.10
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 +55 -18
- package/abi/{ControlBlox.abi.json → AccountBlox.abi.json} +699 -2974
- package/abi/BareBlox.abi.json +127 -90
- package/abi/BaseStateMachine.abi.json +127 -90
- package/abi/EngineBlox.abi.json +11 -31
- package/abi/GuardController.abi.json +217 -895
- package/abi/GuardControllerDefinitions.abi.json +380 -0
- package/abi/IDefinition.abi.json +19 -0
- package/abi/RoleBlox.abi.json +818 -2404
- package/abi/RuntimeRBAC.abi.json +122 -328
- package/abi/RuntimeRBACDefinitions.abi.json +243 -0
- package/abi/SecureBlox.abi.json +620 -1952
- package/abi/SecureOwnable.abi.json +469 -1801
- package/abi/SecureOwnableDefinitions.abi.json +57 -0
- package/abi/SimpleRWA20.abi.json +486 -1999
- package/abi/SimpleRWA20Definitions.abi.json +19 -0
- package/abi/SimpleVault.abi.json +884 -2685
- package/abi/SimpleVaultDefinitions.abi.json +19 -0
- package/components/README.md +8 -0
- package/core/access/RuntimeRBAC.sol +184 -0
- package/core/access/interface/IRuntimeRBAC.sol +55 -0
- package/{contracts/core → core}/access/lib/definitions/RuntimeRBACDefinitions.sol +121 -1
- package/{contracts/core → core}/base/BaseStateMachine.sol +187 -54
- package/{contracts/core → core}/base/interface/IBaseStateMachine.sol +7 -0
- package/{contracts/core → core}/execution/GuardController.sol +89 -155
- package/{contracts/core → core}/execution/interface/IGuardController.sol +52 -12
- package/{contracts/core → core}/execution/lib/definitions/GuardControllerDefinitions.sol +91 -2
- package/{contracts/core → core}/lib/EngineBlox.sol +167 -64
- package/{contracts → core/lib}/interfaces/IDefinition.sol +15 -6
- package/{contracts → core/lib}/interfaces/IEventForwarder.sol +1 -1
- package/{contracts → core/lib}/utils/SharedValidation.sol +490 -486
- package/core/pattern/Account.sol +75 -0
- package/core/research/BloxchainWallet.sol +133 -0
- package/core/research/FactoryBlox/FactoryBlox.sol +344 -0
- package/core/research/FactoryBlox/FactoryBloxDefinitions.sol +144 -0
- package/core/research/erc1155-blox/ERC1155Blox.sol +170 -0
- package/core/research/erc1155-blox/lib/definitions/ERC1155BloxDefinitions.sol +203 -0
- package/core/research/erc20-blox/ERC20Blox.sol +135 -0
- package/core/research/erc20-blox/lib/definitions/ERC20BloxDefinitions.sol +185 -0
- package/core/research/erc721-blox/ERC721Blox.sol +131 -0
- package/core/research/erc721-blox/lib/definitions/ERC721BloxDefinitions.sol +172 -0
- package/core/research/lending-blox/.gitkeep +1 -0
- package/core/research/p2p-blox/P2PBlox.sol +266 -0
- package/core/research/p2p-blox/README.md +85 -0
- package/core/research/p2p-blox/lib/definitions/P2PBloxDefinitions.sol +19 -0
- package/{contracts/core → core}/security/SecureOwnable.sol +390 -419
- package/{contracts/core → core}/security/interface/ISecureOwnable.sol +27 -40
- package/{contracts/core → core}/security/lib/definitions/SecureOwnableDefinitions.sol +786 -757
- package/package.json +49 -47
- package/standards/README.md +12 -0
- package/standards/behavior/ICopyable.sol +36 -0
- package/standards/hooks/IOnActionHook.sol +21 -0
- package/contracts/core/access/RuntimeRBAC.sol +0 -344
- package/contracts/core/access/interface/IRuntimeRBAC.sol +0 -108
- package/contracts/interfaces/IOnActionHook.sol +0 -79
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MPL-2.0
|
|
2
|
+
pragma solidity 0.8.33;
|
|
3
|
+
|
|
4
|
+
import "../../../../lib/EngineBlox.sol";
|
|
5
|
+
import "../../../../lib/interfaces/IDefinition.sol";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* @title ERC20BloxDefinitions
|
|
9
|
+
* @dev Definition library for ERC20Blox execution selectors (transfer, transferFrom, mint, burn, burnFrom).
|
|
10
|
+
* Registers function schemas and role permissions so the GuardController can execute these functions
|
|
11
|
+
* via time-lock and meta-transaction workflows. Handler permissions (executeWithTimeLock, etc.) are
|
|
12
|
+
* defined in GuardControllerDefinitions.
|
|
13
|
+
* @custom:security-contact security@particlecrypto.com
|
|
14
|
+
*/
|
|
15
|
+
library ERC20BloxDefinitions {
|
|
16
|
+
|
|
17
|
+
// System macro selectors (allowed to target address(this) for GuardController execution)
|
|
18
|
+
bytes4 public constant TRANSFER_SELECTOR = bytes4(keccak256("transfer(address,uint256)"));
|
|
19
|
+
bytes4 public constant TRANSFER_FROM_SELECTOR = bytes4(keccak256("transferFrom(address,address,uint256)"));
|
|
20
|
+
bytes4 public constant MINT_SELECTOR = bytes4(keccak256("mint(address,uint256)"));
|
|
21
|
+
bytes4 public constant BURN_SELECTOR = bytes4(keccak256("burn(uint256)"));
|
|
22
|
+
bytes4 public constant BURN_FROM_SELECTOR = bytes4(keccak256("burnFrom(address,uint256)"));
|
|
23
|
+
|
|
24
|
+
bytes32 public constant ERC20_OPERATION = keccak256("ERC20_OPERATION");
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* @dev Returns function schemas for ERC20Blox execution selectors (used by controller).
|
|
28
|
+
*/
|
|
29
|
+
function getFunctionSchemas() public pure returns (EngineBlox.FunctionSchema[] memory) {
|
|
30
|
+
EngineBlox.FunctionSchema[] memory schemas = new EngineBlox.FunctionSchema[](5);
|
|
31
|
+
|
|
32
|
+
EngineBlox.TxAction[] memory timeDelayRequestActions = new EngineBlox.TxAction[](1);
|
|
33
|
+
timeDelayRequestActions[0] = EngineBlox.TxAction.EXECUTE_TIME_DELAY_REQUEST;
|
|
34
|
+
EngineBlox.TxAction[] memory timeDelayApproveActions = new EngineBlox.TxAction[](1);
|
|
35
|
+
timeDelayApproveActions[0] = EngineBlox.TxAction.EXECUTE_TIME_DELAY_APPROVE;
|
|
36
|
+
EngineBlox.TxAction[] memory timeDelayCancelActions = new EngineBlox.TxAction[](1);
|
|
37
|
+
timeDelayCancelActions[0] = EngineBlox.TxAction.EXECUTE_TIME_DELAY_CANCEL;
|
|
38
|
+
EngineBlox.TxAction[] memory metaTxRequestApproveActions = new EngineBlox.TxAction[](2);
|
|
39
|
+
metaTxRequestApproveActions[0] = EngineBlox.TxAction.SIGN_META_REQUEST_AND_APPROVE;
|
|
40
|
+
metaTxRequestApproveActions[1] = EngineBlox.TxAction.EXECUTE_META_REQUEST_AND_APPROVE;
|
|
41
|
+
EngineBlox.TxAction[] memory metaTxApproveActions = new EngineBlox.TxAction[](2);
|
|
42
|
+
metaTxApproveActions[0] = EngineBlox.TxAction.SIGN_META_APPROVE;
|
|
43
|
+
metaTxApproveActions[1] = EngineBlox.TxAction.EXECUTE_META_APPROVE;
|
|
44
|
+
EngineBlox.TxAction[] memory metaTxCancelActions = new EngineBlox.TxAction[](2);
|
|
45
|
+
metaTxCancelActions[0] = EngineBlox.TxAction.SIGN_META_CANCEL;
|
|
46
|
+
metaTxCancelActions[1] = EngineBlox.TxAction.EXECUTE_META_CANCEL;
|
|
47
|
+
|
|
48
|
+
uint16 actionsBitmap = EngineBlox.createBitmapFromActions(timeDelayRequestActions)
|
|
49
|
+
| EngineBlox.createBitmapFromActions(timeDelayApproveActions)
|
|
50
|
+
| EngineBlox.createBitmapFromActions(timeDelayCancelActions)
|
|
51
|
+
| EngineBlox.createBitmapFromActions(metaTxRequestApproveActions)
|
|
52
|
+
| EngineBlox.createBitmapFromActions(metaTxApproveActions)
|
|
53
|
+
| EngineBlox.createBitmapFromActions(metaTxCancelActions);
|
|
54
|
+
|
|
55
|
+
bytes4[] memory transferHandlers = new bytes4[](1);
|
|
56
|
+
transferHandlers[0] = TRANSFER_SELECTOR;
|
|
57
|
+
bytes4[] memory transferFromHandlers = new bytes4[](1);
|
|
58
|
+
transferFromHandlers[0] = TRANSFER_FROM_SELECTOR;
|
|
59
|
+
bytes4[] memory mintHandlers = new bytes4[](1);
|
|
60
|
+
mintHandlers[0] = MINT_SELECTOR;
|
|
61
|
+
bytes4[] memory burnHandlers = new bytes4[](1);
|
|
62
|
+
burnHandlers[0] = BURN_SELECTOR;
|
|
63
|
+
bytes4[] memory burnFromHandlers = new bytes4[](1);
|
|
64
|
+
burnFromHandlers[0] = BURN_FROM_SELECTOR;
|
|
65
|
+
|
|
66
|
+
schemas[0] = EngineBlox.FunctionSchema({
|
|
67
|
+
functionSignature: "transfer(address,uint256)",
|
|
68
|
+
functionSelector: TRANSFER_SELECTOR,
|
|
69
|
+
operationType: ERC20_OPERATION,
|
|
70
|
+
operationName: "ERC20_TRANSFER",
|
|
71
|
+
supportedActionsBitmap: actionsBitmap,
|
|
72
|
+
isProtected: true,
|
|
73
|
+
handlerForSelectors: transferHandlers
|
|
74
|
+
});
|
|
75
|
+
schemas[1] = EngineBlox.FunctionSchema({
|
|
76
|
+
functionSignature: "transferFrom(address,address,uint256)",
|
|
77
|
+
functionSelector: TRANSFER_FROM_SELECTOR,
|
|
78
|
+
operationType: ERC20_OPERATION,
|
|
79
|
+
operationName: "ERC20_TRANSFER_FROM",
|
|
80
|
+
supportedActionsBitmap: actionsBitmap,
|
|
81
|
+
isProtected: true,
|
|
82
|
+
handlerForSelectors: transferFromHandlers
|
|
83
|
+
});
|
|
84
|
+
schemas[2] = EngineBlox.FunctionSchema({
|
|
85
|
+
functionSignature: "mint(address,uint256)",
|
|
86
|
+
functionSelector: MINT_SELECTOR,
|
|
87
|
+
operationType: ERC20_OPERATION,
|
|
88
|
+
operationName: "ERC20_MINT",
|
|
89
|
+
supportedActionsBitmap: actionsBitmap,
|
|
90
|
+
isProtected: true,
|
|
91
|
+
handlerForSelectors: mintHandlers
|
|
92
|
+
});
|
|
93
|
+
schemas[3] = EngineBlox.FunctionSchema({
|
|
94
|
+
functionSignature: "burn(uint256)",
|
|
95
|
+
functionSelector: BURN_SELECTOR,
|
|
96
|
+
operationType: ERC20_OPERATION,
|
|
97
|
+
operationName: "ERC20_BURN",
|
|
98
|
+
supportedActionsBitmap: actionsBitmap,
|
|
99
|
+
isProtected: true,
|
|
100
|
+
handlerForSelectors: burnHandlers
|
|
101
|
+
});
|
|
102
|
+
schemas[4] = EngineBlox.FunctionSchema({
|
|
103
|
+
functionSignature: "burnFrom(address,uint256)",
|
|
104
|
+
functionSelector: BURN_FROM_SELECTOR,
|
|
105
|
+
operationType: ERC20_OPERATION,
|
|
106
|
+
operationName: "ERC20_BURN_FROM",
|
|
107
|
+
supportedActionsBitmap: actionsBitmap,
|
|
108
|
+
isProtected: true,
|
|
109
|
+
handlerForSelectors: burnFromHandlers
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
return schemas;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* @dev Returns role permissions for ERC20Blox execution selectors (OWNER and BROADCASTER).
|
|
117
|
+
*/
|
|
118
|
+
function getRolePermissions() public pure returns (IDefinition.RolePermission memory) {
|
|
119
|
+
bytes32[] memory roleHashes = new bytes32[](10);
|
|
120
|
+
EngineBlox.FunctionPermission[] memory functionPermissions = new EngineBlox.FunctionPermission[](10);
|
|
121
|
+
|
|
122
|
+
EngineBlox.TxAction[] memory ownerTimeLockRequest = new EngineBlox.TxAction[](1);
|
|
123
|
+
ownerTimeLockRequest[0] = EngineBlox.TxAction.EXECUTE_TIME_DELAY_REQUEST;
|
|
124
|
+
EngineBlox.TxAction[] memory ownerTimeLockApprove = new EngineBlox.TxAction[](1);
|
|
125
|
+
ownerTimeLockApprove[0] = EngineBlox.TxAction.EXECUTE_TIME_DELAY_APPROVE;
|
|
126
|
+
EngineBlox.TxAction[] memory ownerTimeLockCancel = new EngineBlox.TxAction[](1);
|
|
127
|
+
ownerTimeLockCancel[0] = EngineBlox.TxAction.EXECUTE_TIME_DELAY_CANCEL;
|
|
128
|
+
EngineBlox.TxAction[] memory ownerMetaSign = new EngineBlox.TxAction[](1);
|
|
129
|
+
ownerMetaSign[0] = EngineBlox.TxAction.SIGN_META_REQUEST_AND_APPROVE;
|
|
130
|
+
EngineBlox.TxAction[] memory ownerMetaApprove = new EngineBlox.TxAction[](1);
|
|
131
|
+
ownerMetaApprove[0] = EngineBlox.TxAction.SIGN_META_APPROVE;
|
|
132
|
+
EngineBlox.TxAction[] memory ownerMetaCancel = new EngineBlox.TxAction[](1);
|
|
133
|
+
ownerMetaCancel[0] = EngineBlox.TxAction.SIGN_META_CANCEL;
|
|
134
|
+
EngineBlox.TxAction[] memory broadcasterMetaExec = new EngineBlox.TxAction[](1);
|
|
135
|
+
broadcasterMetaExec[0] = EngineBlox.TxAction.EXECUTE_META_REQUEST_AND_APPROVE;
|
|
136
|
+
EngineBlox.TxAction[] memory broadcasterMetaApprove = new EngineBlox.TxAction[](1);
|
|
137
|
+
broadcasterMetaApprove[0] = EngineBlox.TxAction.EXECUTE_META_APPROVE;
|
|
138
|
+
EngineBlox.TxAction[] memory broadcasterMetaCancel = new EngineBlox.TxAction[](1);
|
|
139
|
+
broadcasterMetaCancel[0] = EngineBlox.TxAction.EXECUTE_META_CANCEL;
|
|
140
|
+
|
|
141
|
+
uint16 ownerBitmap = EngineBlox.createBitmapFromActions(ownerTimeLockRequest)
|
|
142
|
+
| EngineBlox.createBitmapFromActions(ownerTimeLockApprove)
|
|
143
|
+
| EngineBlox.createBitmapFromActions(ownerTimeLockCancel)
|
|
144
|
+
| EngineBlox.createBitmapFromActions(ownerMetaSign)
|
|
145
|
+
| EngineBlox.createBitmapFromActions(ownerMetaApprove)
|
|
146
|
+
| EngineBlox.createBitmapFromActions(ownerMetaCancel);
|
|
147
|
+
uint16 broadcasterBitmap = EngineBlox.createBitmapFromActions(broadcasterMetaExec)
|
|
148
|
+
| EngineBlox.createBitmapFromActions(broadcasterMetaApprove)
|
|
149
|
+
| EngineBlox.createBitmapFromActions(broadcasterMetaCancel);
|
|
150
|
+
|
|
151
|
+
bytes4[5] memory selectors = [TRANSFER_SELECTOR, TRANSFER_FROM_SELECTOR, MINT_SELECTOR, BURN_SELECTOR, BURN_FROM_SELECTOR];
|
|
152
|
+
for (uint256 i = 0; i < 5; i++) {
|
|
153
|
+
bytes4[] memory selfRef = new bytes4[](1);
|
|
154
|
+
selfRef[0] = selectors[i];
|
|
155
|
+
roleHashes[i] = EngineBlox.OWNER_ROLE;
|
|
156
|
+
functionPermissions[i] = EngineBlox.FunctionPermission({
|
|
157
|
+
functionSelector: selectors[i],
|
|
158
|
+
grantedActionsBitmap: ownerBitmap,
|
|
159
|
+
handlerForSelectors: selfRef
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
for (uint256 i = 0; i < 5; i++) {
|
|
163
|
+
bytes4[] memory selfRef = new bytes4[](1);
|
|
164
|
+
selfRef[0] = selectors[i];
|
|
165
|
+
roleHashes[5 + i] = EngineBlox.BROADCASTER_ROLE;
|
|
166
|
+
functionPermissions[5 + i] = EngineBlox.FunctionPermission({
|
|
167
|
+
functionSelector: selectors[i],
|
|
168
|
+
grantedActionsBitmap: broadcasterBitmap,
|
|
169
|
+
handlerForSelectors: selfRef
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
return IDefinition.RolePermission({
|
|
174
|
+
roleHashes: roleHashes,
|
|
175
|
+
functionPermissions: functionPermissions
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* @dev ERC165: report support for IDefinition when this library is used at an address
|
|
181
|
+
*/
|
|
182
|
+
function supportsInterface(bytes4 interfaceId) external pure returns (bool) {
|
|
183
|
+
return interfaceId == type(IDefinition).interfaceId;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
// SPDX-License-Identifier: AGPL-3.0-or-later
|
|
2
|
+
// Copyright (c) 2025 Particle Crypto Security
|
|
3
|
+
pragma solidity 0.8.33;
|
|
4
|
+
|
|
5
|
+
// OpenZeppelin
|
|
6
|
+
import "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol";
|
|
7
|
+
import "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721BurnableUpgradeable.sol";
|
|
8
|
+
import "@openzeppelin/contracts/token/ERC721/IERC721.sol";
|
|
9
|
+
import "@openzeppelin/contracts/utils/introspection/IERC165.sol";
|
|
10
|
+
|
|
11
|
+
// Core
|
|
12
|
+
import "../../pattern/Account.sol";
|
|
13
|
+
import "../../lib/interfaces/IDefinition.sol";
|
|
14
|
+
import "../../lib/utils/SharedValidation.sol";
|
|
15
|
+
import "./lib/definitions/ERC721BloxDefinitions.sol";
|
|
16
|
+
|
|
17
|
+
// Standards
|
|
18
|
+
import "../../../standards/behavior/ICopyable.sol";
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* @title ERC721Blox
|
|
22
|
+
* @dev ERC721 NFT (IERC721) with Account pattern and ICopyable for cloning.
|
|
23
|
+
* Exposes transferFrom, safeTransferFrom (callable only via GuardController), mint (owner-only via controller), and burn (ERC721Burnable via controller).
|
|
24
|
+
* @custom:security-contact security@particlecrypto.com
|
|
25
|
+
*/
|
|
26
|
+
contract ERC721Blox is
|
|
27
|
+
IERC721,
|
|
28
|
+
ICopyable,
|
|
29
|
+
ERC721Upgradeable,
|
|
30
|
+
ERC721BurnableUpgradeable,
|
|
31
|
+
Account
|
|
32
|
+
{
|
|
33
|
+
/// @custom:oz-upgrades-unsafe-allow constructor
|
|
34
|
+
constructor() {
|
|
35
|
+
_disableInitializers();
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* @dev ICopyable: full init with custom data. initData must be abi.encode(name, symbol).
|
|
40
|
+
* Runs Account init, ERC721Blox definitions, and ERC721 name/symbol in one step.
|
|
41
|
+
*/
|
|
42
|
+
function initializeWithData(
|
|
43
|
+
address initialOwner,
|
|
44
|
+
address broadcaster,
|
|
45
|
+
address recovery,
|
|
46
|
+
uint256 timeLockPeriodSec,
|
|
47
|
+
address eventForwarder,
|
|
48
|
+
bytes calldata initData
|
|
49
|
+
) external virtual initializer {
|
|
50
|
+
super.initialize(initialOwner, broadcaster, recovery, timeLockPeriodSec, eventForwarder);
|
|
51
|
+
|
|
52
|
+
IDefinition.RolePermission memory erc721Permissions = ERC721BloxDefinitions.getRolePermissions();
|
|
53
|
+
_loadDefinitions(
|
|
54
|
+
ERC721BloxDefinitions.getFunctionSchemas(),
|
|
55
|
+
erc721Permissions.roleHashes,
|
|
56
|
+
erc721Permissions.functionPermissions,
|
|
57
|
+
true
|
|
58
|
+
);
|
|
59
|
+
|
|
60
|
+
_addMacroSelector(ERC721BloxDefinitions.TRANSFER_FROM_SELECTOR);
|
|
61
|
+
_addMacroSelector(ERC721BloxDefinitions.SAFE_TRANSFER_FROM_SELECTOR);
|
|
62
|
+
_addMacroSelector(ERC721BloxDefinitions.MINT_SELECTOR);
|
|
63
|
+
_addMacroSelector(ERC721BloxDefinitions.BURN_SELECTOR);
|
|
64
|
+
(string memory name, string memory symbol) = abi.decode(initData, (string, string));
|
|
65
|
+
__ERC721_init(name, symbol);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* @notice Transfer NFT from one account to another; callable only by this contract via GuardController
|
|
70
|
+
* @param from Sender address
|
|
71
|
+
* @param to Recipient address
|
|
72
|
+
* @param tokenId Token ID to transfer
|
|
73
|
+
*/
|
|
74
|
+
function transferFrom(address from, address to, uint256 tokenId) public virtual override(ERC721Upgradeable, IERC721) {
|
|
75
|
+
_validateExecuteBySelf();
|
|
76
|
+
super.transferFrom(from, to, tokenId);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* @notice Safe transfer NFT from one account to another (with data); callable only by this contract via GuardController.
|
|
81
|
+
* The 3-arg overload (no data) in the base contract calls this with empty data, so it is also guarded.
|
|
82
|
+
* @param from Sender address
|
|
83
|
+
* @param to Recipient address
|
|
84
|
+
* @param tokenId Token ID to transfer
|
|
85
|
+
* @param data Additional data for recipient hook
|
|
86
|
+
*/
|
|
87
|
+
function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data)
|
|
88
|
+
public
|
|
89
|
+
virtual
|
|
90
|
+
override(ERC721Upgradeable, IERC721)
|
|
91
|
+
{
|
|
92
|
+
_validateExecuteBySelf();
|
|
93
|
+
super.safeTransferFrom(from, to, tokenId, data);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* @notice Mint an NFT to an account (callable only by this contract via GuardController)
|
|
98
|
+
* @param to Recipient address
|
|
99
|
+
* @param tokenId Token ID to mint
|
|
100
|
+
*/
|
|
101
|
+
function mint(address to, uint256 tokenId) external virtual {
|
|
102
|
+
_validateExecuteBySelf();
|
|
103
|
+
_mint(to, tokenId);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* @notice Burn an NFT (callable only by this contract via GuardController)
|
|
108
|
+
* @param tokenId Token ID to burn
|
|
109
|
+
*/
|
|
110
|
+
function burn(uint256 tokenId) public virtual override(ERC721BurnableUpgradeable) {
|
|
111
|
+
_validateExecuteBySelf();
|
|
112
|
+
super.burn(tokenId);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
function supportsInterface(bytes4 interfaceId) public view virtual override(ERC721Upgradeable, Account, IERC165) returns (bool) {
|
|
116
|
+
return interfaceId == type(IERC721).interfaceId || interfaceId == type(ICopyable).interfaceId || super.supportsInterface(interfaceId);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* @dev Base initialization (5 params only) is disallowed; use initializeWithData(..., initData) with abi.encode(name, symbol).
|
|
121
|
+
*/
|
|
122
|
+
function initialize(
|
|
123
|
+
address initialOwner,
|
|
124
|
+
address broadcaster,
|
|
125
|
+
address recovery,
|
|
126
|
+
uint256 timeLockPeriodSec,
|
|
127
|
+
address eventForwarder
|
|
128
|
+
) public virtual override(Account) initializer {
|
|
129
|
+
revert SharedValidation.NotSupported();
|
|
130
|
+
}
|
|
131
|
+
}
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MPL-2.0
|
|
2
|
+
pragma solidity 0.8.33;
|
|
3
|
+
|
|
4
|
+
import "../../../../lib/EngineBlox.sol";
|
|
5
|
+
import "../../../../lib/interfaces/IDefinition.sol";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* @title ERC721BloxDefinitions
|
|
9
|
+
* @dev Definition library for ERC721Blox execution selectors (transferFrom, safeTransferFrom, mint, burn).
|
|
10
|
+
* Registers function schemas and role permissions so the GuardController can execute these functions
|
|
11
|
+
* via time-lock and meta-transaction workflows.
|
|
12
|
+
* @custom:security-contact security@particlecrypto.com
|
|
13
|
+
*/
|
|
14
|
+
library ERC721BloxDefinitions {
|
|
15
|
+
|
|
16
|
+
// System macro selectors (allowed to target address(this) for GuardController execution)
|
|
17
|
+
bytes4 public constant TRANSFER_FROM_SELECTOR = bytes4(keccak256("transferFrom(address,address,uint256)"));
|
|
18
|
+
bytes4 public constant SAFE_TRANSFER_FROM_SELECTOR = bytes4(keccak256("safeTransferFrom(address,address,uint256,bytes)"));
|
|
19
|
+
bytes4 public constant MINT_SELECTOR = bytes4(keccak256("mint(address,uint256)"));
|
|
20
|
+
bytes4 public constant BURN_SELECTOR = bytes4(keccak256("burn(uint256)"));
|
|
21
|
+
|
|
22
|
+
bytes32 public constant ERC721_OPERATION = keccak256("ERC721_OPERATION");
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* @dev Returns function schemas for ERC721Blox execution selectors (used by controller).
|
|
26
|
+
*/
|
|
27
|
+
function getFunctionSchemas() public pure returns (EngineBlox.FunctionSchema[] memory) {
|
|
28
|
+
EngineBlox.FunctionSchema[] memory schemas = new EngineBlox.FunctionSchema[](4);
|
|
29
|
+
|
|
30
|
+
EngineBlox.TxAction[] memory timeDelayRequestActions = new EngineBlox.TxAction[](1);
|
|
31
|
+
timeDelayRequestActions[0] = EngineBlox.TxAction.EXECUTE_TIME_DELAY_REQUEST;
|
|
32
|
+
EngineBlox.TxAction[] memory timeDelayApproveActions = new EngineBlox.TxAction[](1);
|
|
33
|
+
timeDelayApproveActions[0] = EngineBlox.TxAction.EXECUTE_TIME_DELAY_APPROVE;
|
|
34
|
+
EngineBlox.TxAction[] memory timeDelayCancelActions = new EngineBlox.TxAction[](1);
|
|
35
|
+
timeDelayCancelActions[0] = EngineBlox.TxAction.EXECUTE_TIME_DELAY_CANCEL;
|
|
36
|
+
EngineBlox.TxAction[] memory metaTxRequestApproveActions = new EngineBlox.TxAction[](2);
|
|
37
|
+
metaTxRequestApproveActions[0] = EngineBlox.TxAction.SIGN_META_REQUEST_AND_APPROVE;
|
|
38
|
+
metaTxRequestApproveActions[1] = EngineBlox.TxAction.EXECUTE_META_REQUEST_AND_APPROVE;
|
|
39
|
+
EngineBlox.TxAction[] memory metaTxApproveActions = new EngineBlox.TxAction[](2);
|
|
40
|
+
metaTxApproveActions[0] = EngineBlox.TxAction.SIGN_META_APPROVE;
|
|
41
|
+
metaTxApproveActions[1] = EngineBlox.TxAction.EXECUTE_META_APPROVE;
|
|
42
|
+
EngineBlox.TxAction[] memory metaTxCancelActions = new EngineBlox.TxAction[](2);
|
|
43
|
+
metaTxCancelActions[0] = EngineBlox.TxAction.SIGN_META_CANCEL;
|
|
44
|
+
metaTxCancelActions[1] = EngineBlox.TxAction.EXECUTE_META_CANCEL;
|
|
45
|
+
|
|
46
|
+
uint16 actionsBitmap = EngineBlox.createBitmapFromActions(timeDelayRequestActions)
|
|
47
|
+
| EngineBlox.createBitmapFromActions(timeDelayApproveActions)
|
|
48
|
+
| EngineBlox.createBitmapFromActions(timeDelayCancelActions)
|
|
49
|
+
| EngineBlox.createBitmapFromActions(metaTxRequestApproveActions)
|
|
50
|
+
| EngineBlox.createBitmapFromActions(metaTxApproveActions)
|
|
51
|
+
| EngineBlox.createBitmapFromActions(metaTxCancelActions);
|
|
52
|
+
|
|
53
|
+
bytes4[] memory transferFromHandlers = new bytes4[](1);
|
|
54
|
+
transferFromHandlers[0] = TRANSFER_FROM_SELECTOR;
|
|
55
|
+
bytes4[] memory safeTransferFromHandlers = new bytes4[](1);
|
|
56
|
+
safeTransferFromHandlers[0] = SAFE_TRANSFER_FROM_SELECTOR;
|
|
57
|
+
bytes4[] memory mintHandlers = new bytes4[](1);
|
|
58
|
+
mintHandlers[0] = MINT_SELECTOR;
|
|
59
|
+
bytes4[] memory burnHandlers = new bytes4[](1);
|
|
60
|
+
burnHandlers[0] = BURN_SELECTOR;
|
|
61
|
+
|
|
62
|
+
schemas[0] = EngineBlox.FunctionSchema({
|
|
63
|
+
functionSignature: "transferFrom(address,address,uint256)",
|
|
64
|
+
functionSelector: TRANSFER_FROM_SELECTOR,
|
|
65
|
+
operationType: ERC721_OPERATION,
|
|
66
|
+
operationName: "ERC721_TRANSFER_FROM",
|
|
67
|
+
supportedActionsBitmap: actionsBitmap,
|
|
68
|
+
isProtected: true,
|
|
69
|
+
handlerForSelectors: transferFromHandlers
|
|
70
|
+
});
|
|
71
|
+
schemas[1] = EngineBlox.FunctionSchema({
|
|
72
|
+
functionSignature: "safeTransferFrom(address,address,uint256,bytes)",
|
|
73
|
+
functionSelector: SAFE_TRANSFER_FROM_SELECTOR,
|
|
74
|
+
operationType: ERC721_OPERATION,
|
|
75
|
+
operationName: "ERC721_SAFE_TRANSFER_FROM",
|
|
76
|
+
supportedActionsBitmap: actionsBitmap,
|
|
77
|
+
isProtected: true,
|
|
78
|
+
handlerForSelectors: safeTransferFromHandlers
|
|
79
|
+
});
|
|
80
|
+
schemas[2] = EngineBlox.FunctionSchema({
|
|
81
|
+
functionSignature: "mint(address,uint256)",
|
|
82
|
+
functionSelector: MINT_SELECTOR,
|
|
83
|
+
operationType: ERC721_OPERATION,
|
|
84
|
+
operationName: "ERC721_MINT",
|
|
85
|
+
supportedActionsBitmap: actionsBitmap,
|
|
86
|
+
isProtected: true,
|
|
87
|
+
handlerForSelectors: mintHandlers
|
|
88
|
+
});
|
|
89
|
+
schemas[3] = EngineBlox.FunctionSchema({
|
|
90
|
+
functionSignature: "burn(uint256)",
|
|
91
|
+
functionSelector: BURN_SELECTOR,
|
|
92
|
+
operationType: ERC721_OPERATION,
|
|
93
|
+
operationName: "ERC721_BURN",
|
|
94
|
+
supportedActionsBitmap: actionsBitmap,
|
|
95
|
+
isProtected: true,
|
|
96
|
+
handlerForSelectors: burnHandlers
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
return schemas;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* @dev Returns role permissions for ERC721Blox execution selectors (OWNER and BROADCASTER).
|
|
104
|
+
*/
|
|
105
|
+
function getRolePermissions() public pure returns (IDefinition.RolePermission memory) {
|
|
106
|
+
bytes32[] memory roleHashes = new bytes32[](8);
|
|
107
|
+
EngineBlox.FunctionPermission[] memory functionPermissions = new EngineBlox.FunctionPermission[](8);
|
|
108
|
+
|
|
109
|
+
EngineBlox.TxAction[] memory ownerTimeLockRequest = new EngineBlox.TxAction[](1);
|
|
110
|
+
ownerTimeLockRequest[0] = EngineBlox.TxAction.EXECUTE_TIME_DELAY_REQUEST;
|
|
111
|
+
EngineBlox.TxAction[] memory ownerTimeLockApprove = new EngineBlox.TxAction[](1);
|
|
112
|
+
ownerTimeLockApprove[0] = EngineBlox.TxAction.EXECUTE_TIME_DELAY_APPROVE;
|
|
113
|
+
EngineBlox.TxAction[] memory ownerTimeLockCancel = new EngineBlox.TxAction[](1);
|
|
114
|
+
ownerTimeLockCancel[0] = EngineBlox.TxAction.EXECUTE_TIME_DELAY_CANCEL;
|
|
115
|
+
EngineBlox.TxAction[] memory ownerMetaSign = new EngineBlox.TxAction[](1);
|
|
116
|
+
ownerMetaSign[0] = EngineBlox.TxAction.SIGN_META_REQUEST_AND_APPROVE;
|
|
117
|
+
EngineBlox.TxAction[] memory ownerMetaApprove = new EngineBlox.TxAction[](1);
|
|
118
|
+
ownerMetaApprove[0] = EngineBlox.TxAction.SIGN_META_APPROVE;
|
|
119
|
+
EngineBlox.TxAction[] memory ownerMetaCancel = new EngineBlox.TxAction[](1);
|
|
120
|
+
ownerMetaCancel[0] = EngineBlox.TxAction.SIGN_META_CANCEL;
|
|
121
|
+
EngineBlox.TxAction[] memory broadcasterMetaExec = new EngineBlox.TxAction[](1);
|
|
122
|
+
broadcasterMetaExec[0] = EngineBlox.TxAction.EXECUTE_META_REQUEST_AND_APPROVE;
|
|
123
|
+
EngineBlox.TxAction[] memory broadcasterMetaApprove = new EngineBlox.TxAction[](1);
|
|
124
|
+
broadcasterMetaApprove[0] = EngineBlox.TxAction.EXECUTE_META_APPROVE;
|
|
125
|
+
EngineBlox.TxAction[] memory broadcasterMetaCancel = new EngineBlox.TxAction[](1);
|
|
126
|
+
broadcasterMetaCancel[0] = EngineBlox.TxAction.EXECUTE_META_CANCEL;
|
|
127
|
+
|
|
128
|
+
uint16 ownerBitmap = EngineBlox.createBitmapFromActions(ownerTimeLockRequest)
|
|
129
|
+
| EngineBlox.createBitmapFromActions(ownerTimeLockApprove)
|
|
130
|
+
| EngineBlox.createBitmapFromActions(ownerTimeLockCancel)
|
|
131
|
+
| EngineBlox.createBitmapFromActions(ownerMetaSign)
|
|
132
|
+
| EngineBlox.createBitmapFromActions(ownerMetaApprove)
|
|
133
|
+
| EngineBlox.createBitmapFromActions(ownerMetaCancel);
|
|
134
|
+
uint16 broadcasterBitmap = EngineBlox.createBitmapFromActions(broadcasterMetaExec)
|
|
135
|
+
| EngineBlox.createBitmapFromActions(broadcasterMetaApprove)
|
|
136
|
+
| EngineBlox.createBitmapFromActions(broadcasterMetaCancel);
|
|
137
|
+
|
|
138
|
+
bytes4[4] memory selectors = [TRANSFER_FROM_SELECTOR, SAFE_TRANSFER_FROM_SELECTOR, MINT_SELECTOR, BURN_SELECTOR];
|
|
139
|
+
for (uint256 i = 0; i < 4; i++) {
|
|
140
|
+
bytes4[] memory selfRef = new bytes4[](1);
|
|
141
|
+
selfRef[0] = selectors[i];
|
|
142
|
+
roleHashes[i] = EngineBlox.OWNER_ROLE;
|
|
143
|
+
functionPermissions[i] = EngineBlox.FunctionPermission({
|
|
144
|
+
functionSelector: selectors[i],
|
|
145
|
+
grantedActionsBitmap: ownerBitmap,
|
|
146
|
+
handlerForSelectors: selfRef
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
for (uint256 i = 0; i < 4; i++) {
|
|
150
|
+
bytes4[] memory selfRef = new bytes4[](1);
|
|
151
|
+
selfRef[0] = selectors[i];
|
|
152
|
+
roleHashes[4 + i] = EngineBlox.BROADCASTER_ROLE;
|
|
153
|
+
functionPermissions[4 + i] = EngineBlox.FunctionPermission({
|
|
154
|
+
functionSelector: selectors[i],
|
|
155
|
+
grantedActionsBitmap: broadcasterBitmap,
|
|
156
|
+
handlerForSelectors: selfRef
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
return IDefinition.RolePermission({
|
|
161
|
+
roleHashes: roleHashes,
|
|
162
|
+
functionPermissions: functionPermissions
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* @dev ERC165: report support for IDefinition when this library is used at an address
|
|
168
|
+
*/
|
|
169
|
+
function supportsInterface(bytes4 interfaceId) external pure returns (bool) {
|
|
170
|
+
return interfaceId == type(IDefinition).interfaceId;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# Placeholder to keep lending-blox directory in version control
|