@bloxchain/contracts 1.0.0-alpha.19 → 1.0.0-alpha.20
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/abi/BaseStateMachine.abi.json +0 -16
- package/abi/EngineBlox.abi.json +46 -4
- package/abi/GuardController.abi.json +28 -7
- package/abi/GuardControllerDefinitions.abi.json +1 -1
- package/abi/RuntimeRBAC.abi.json +28 -7
- package/abi/SecureOwnable.abi.json +23 -7
- package/core/access/RuntimeRBAC.sol +13 -1
- package/core/base/BaseStateMachine.sol +967 -948
- package/core/base/interface/IBaseStateMachine.sol +1 -0
- package/core/execution/GuardController.sol +454 -448
- package/core/execution/lib/definitions/GuardControllerDefinitions.sol +70 -13
- package/core/lib/EngineBlox.sol +182 -38
- package/core/lib/utils/SharedValidation.sol +540 -492
- package/core/security/SecureOwnable.sol +39 -7
- package/package.json +3 -3
|
@@ -32,13 +32,36 @@ import "./interface/ISecureOwnable.sol";
|
|
|
32
32
|
* (a broadcaster update may still be pending). A new broadcaster-update request is allowed only
|
|
33
33
|
* when neither type has a pending request.
|
|
34
34
|
*
|
|
35
|
+
* **Ownership transfer vs recovery (threat model):**
|
|
36
|
+
* - `transferOwnershipRequest` snapshots `getRecovery()` into the pending tx `executionParams`. On execution,
|
|
37
|
+
* `executeTransferOwnership` receives that snapshotted address as the new owner. Rotating recovery after
|
|
38
|
+
* the request does **not** rewrite the pending payload; the beneficiary remains the recovery address
|
|
39
|
+
* at request time.
|
|
40
|
+
* - `transferOwnershipDelayedApproval` authorizes the **current** owner or **current** recovery (`getRecovery()`
|
|
41
|
+
* at approval time). It does **not** require the approver to match the snapshotted beneficiary. Integrators
|
|
42
|
+
* must treat approval as consent to execute the **stored** transfer, not “transfer to whoever is recovery now.”
|
|
43
|
+
* - `transferOwnershipCancellation` allows only the **current** recovery to cancel. If owner and broadcaster
|
|
44
|
+
* rotate recovery via `updateRecoveryRequestAndApprove` while a transfer is pending, the **previous**
|
|
45
|
+
* recovery loses cancel rights immediately; the pending tx still targets the old address until approved,
|
|
46
|
+
* cancelled by the new recovery, or superseded operationally.
|
|
47
|
+
* - Recovery and timelock updates use a request-and-approve meta-tx path without an additional timelock and
|
|
48
|
+
* are **not** blocked when an ownership transfer is pending (unlike broadcaster update requests). This is
|
|
49
|
+
* intentional: fast recovery rotation when owner and broadcaster still cooperate; operators who need a
|
|
50
|
+
* strict “recovery cannot change during pending ownership transfer” invariant must enforce it off-chain or
|
|
51
|
+
* extend this contract.
|
|
52
|
+
*
|
|
35
53
|
* This contract focuses purely on security logic while leveraging the BaseStateMachine
|
|
36
54
|
* for transaction management, meta-transactions, and state machine operations.
|
|
37
55
|
*/
|
|
38
56
|
abstract contract SecureOwnable is BaseStateMachine, ISecureOwnable {
|
|
39
57
|
using SharedValidation for *;
|
|
40
58
|
|
|
41
|
-
/// @dev
|
|
59
|
+
/// @dev Lane flags for **delayed** ownership-transfer and broadcaster-update requests only (`transferOwnershipRequest`,
|
|
60
|
+
/// `updateBroadcasterRequest`). Recovery and timelock updates use `_requestAndApproveTransaction` and do **not**
|
|
61
|
+
/// read or write these booleans. Each flag is set only after a successful `_requestTransaction` in that same tx;
|
|
62
|
+
/// clearing happens only in `_completeApprove` / `_completeCancel` in the **same** transaction as a successful
|
|
63
|
+
/// `_approveTransaction` / `_cancelTransaction`, so a revert unwinds engine state and flag writes together.
|
|
64
|
+
/// @dev Upgrading from legacy `_hasOpenRequest` / `_pendingBits` requires no pending requests.
|
|
42
65
|
bool private _hasOpenOwnershipRequest;
|
|
43
66
|
bool private _hasOpenBroadcasterRequest;
|
|
44
67
|
|
|
@@ -81,7 +104,9 @@ abstract contract SecureOwnable is BaseStateMachine, ISecureOwnable {
|
|
|
81
104
|
|
|
82
105
|
// Ownership Management
|
|
83
106
|
/**
|
|
84
|
-
* @dev Requests a transfer of
|
|
107
|
+
* @dev Requests a time-delayed transfer of the OWNER role to the **recovery address at request time**.
|
|
108
|
+
* @notice Encodes `getRecovery()` into `executionParams`; that address becomes the new owner on successful
|
|
109
|
+
* execution. Changing recovery later does not update this pending record.
|
|
85
110
|
* @return txId The transaction ID (use getTransaction(txId) for full record)
|
|
86
111
|
*/
|
|
87
112
|
function transferOwnershipRequest() public returns (uint256 txId) {
|
|
@@ -104,7 +129,9 @@ abstract contract SecureOwnable is BaseStateMachine, ISecureOwnable {
|
|
|
104
129
|
}
|
|
105
130
|
|
|
106
131
|
/**
|
|
107
|
-
* @dev Approves a pending ownership transfer
|
|
132
|
+
* @dev Approves a pending ownership transfer after `releaseTime` (timelock on the direct path).
|
|
133
|
+
* @notice Callable by **current** owner or **current** recovery. Execution still transfers ownership to
|
|
134
|
+
* the address snapshotted at request time, which may differ from `getRecovery()` at approval time.
|
|
108
135
|
* @param txId The transaction ID
|
|
109
136
|
* @return The transaction ID
|
|
110
137
|
*/
|
|
@@ -124,7 +151,9 @@ abstract contract SecureOwnable is BaseStateMachine, ISecureOwnable {
|
|
|
124
151
|
}
|
|
125
152
|
|
|
126
153
|
/**
|
|
127
|
-
* @dev Cancels a pending ownership transfer transaction
|
|
154
|
+
* @dev Cancels a pending ownership transfer transaction.
|
|
155
|
+
* @notice Only the **current** `getRecovery()` may cancel. After a recovery rotation, the prior recovery
|
|
156
|
+
* address can no longer cancel.
|
|
128
157
|
* @param txId The transaction ID
|
|
129
158
|
* @return The transaction ID
|
|
130
159
|
*/
|
|
@@ -219,7 +248,9 @@ abstract contract SecureOwnable is BaseStateMachine, ISecureOwnable {
|
|
|
219
248
|
// Recovery Management
|
|
220
249
|
|
|
221
250
|
/**
|
|
222
|
-
* @dev Requests and approves a recovery address update using a meta-transaction
|
|
251
|
+
* @dev Requests and approves a recovery address update using a meta-transaction (owner signs, broadcaster submits).
|
|
252
|
+
* @notice Does **not** revert when an ownership transfer is pending. A pending transfer continues to target
|
|
253
|
+
* the recovery address snapshotted at its request until executed or cancelled by **current** recovery.
|
|
223
254
|
* @param metaTx The meta-transaction
|
|
224
255
|
* @return The transaction ID
|
|
225
256
|
*/
|
|
@@ -248,8 +279,9 @@ abstract contract SecureOwnable is BaseStateMachine, ISecureOwnable {
|
|
|
248
279
|
|
|
249
280
|
// Execution Functions
|
|
250
281
|
/**
|
|
251
|
-
* @dev External function that can only be called by the contract itself to execute ownership transfer
|
|
252
|
-
* @param newOwner The new owner address
|
|
282
|
+
* @dev External function that can only be called by the contract itself to execute ownership transfer.
|
|
283
|
+
* @param newOwner The new owner; for the OWNERSHIP_TRANSFER flow this is the recovery address encoded at
|
|
284
|
+
* request time (see `transferOwnershipRequest`), not necessarily `getRecovery()` at execution time.
|
|
253
285
|
*/
|
|
254
286
|
function executeTransferOwnership(address newOwner) external {
|
|
255
287
|
_validateExecuteBySelf();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bloxchain/contracts",
|
|
3
|
-
"version": "1.0.0-alpha.
|
|
3
|
+
"version": "1.0.0-alpha.20",
|
|
4
4
|
"description": "Library engine for building enterprise grade decentralized permissioned applications",
|
|
5
5
|
"files": [
|
|
6
6
|
"core",
|
|
@@ -40,8 +40,8 @@
|
|
|
40
40
|
"access": "public"
|
|
41
41
|
},
|
|
42
42
|
"dependencies": {
|
|
43
|
-
"@openzeppelin/contracts": "^5.
|
|
44
|
-
"@openzeppelin/contracts-upgradeable": "^5.
|
|
43
|
+
"@openzeppelin/contracts": "^5.6.1",
|
|
44
|
+
"@openzeppelin/contracts-upgradeable": "^5.6.1"
|
|
45
45
|
},
|
|
46
46
|
"engines": {
|
|
47
47
|
"node": ">=18.0.0"
|