@bananapus/ownable-v6 0.0.16 → 0.0.17
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/package.json +2 -2
- package/src/JBOwnable.sol +14 -7
- package/test/OwnableEdgeCases.t.sol +21 -5
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bananapus/ownable-v6",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.17",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
"node": ">=20.0.0"
|
|
11
11
|
},
|
|
12
12
|
"dependencies": {
|
|
13
|
-
"@bananapus/core-v6": "^0.0.
|
|
13
|
+
"@bananapus/core-v6": "^0.0.31",
|
|
14
14
|
"@bananapus/permission-ids-v6": "^0.0.15",
|
|
15
15
|
"@openzeppelin/contracts": "^5.6.1"
|
|
16
16
|
},
|
package/src/JBOwnable.sol
CHANGED
|
@@ -59,8 +59,8 @@ contract JBOwnable is JBOwnableOverrides {
|
|
|
59
59
|
/// @dev This function exists because some contracts need to deploy contracts for a project before the project's NFT
|
|
60
60
|
/// has been minted, so the transfer event resolves the project's current owner at emission time.
|
|
61
61
|
/// @dev Unlike `_transferOwnership` (which uses try-catch to resolve the *old* owner in case its project NFT was
|
|
62
|
-
/// burned), this function
|
|
63
|
-
///
|
|
62
|
+
/// burned), this function resolves the *new* owner's current address for event purposes only.
|
|
63
|
+
/// If the new project NFT does not exist yet, the event uses `address(0)` until ownership can resolve normally.
|
|
64
64
|
function _emitTransferEvent(
|
|
65
65
|
address previousOwner,
|
|
66
66
|
address newOwner,
|
|
@@ -70,10 +70,17 @@ contract JBOwnable is JBOwnableOverrides {
|
|
|
70
70
|
virtual
|
|
71
71
|
override
|
|
72
72
|
{
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
73
|
+
address resolvedNewOwner = newOwner;
|
|
74
|
+
if (newProjectId != 0) {
|
|
75
|
+
try PROJECTS.ownerOf(newProjectId) returns (address projectOwner) {
|
|
76
|
+
resolvedNewOwner = projectOwner;
|
|
77
|
+
} catch {
|
|
78
|
+
// Allow constructor-time handoff to an unminted project. Ownership resolves dynamically
|
|
79
|
+
// once the project NFT exists, so the transfer event uses address(0) until then.
|
|
80
|
+
resolvedNewOwner = address(0);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
emit OwnershipTransferred({previousOwner: previousOwner, newOwner: resolvedNewOwner, caller: _msgSender()});
|
|
78
85
|
}
|
|
79
86
|
}
|
|
@@ -292,7 +292,23 @@ contract OwnableEdgeCases is Test {
|
|
|
292
292
|
}
|
|
293
293
|
|
|
294
294
|
// =========================================================================
|
|
295
|
-
// Test 10:
|
|
295
|
+
// Test 10: Constructor tolerates an unminted project owner
|
|
296
|
+
// =========================================================================
|
|
297
|
+
function test_constructorWithUnmintedProject_emitsZeroOwnerUntilMinted() public {
|
|
298
|
+
vm.expectEmit(true, true, false, true);
|
|
299
|
+
emit IJBOwnable.OwnershipTransferred(address(0), address(0), address(this));
|
|
300
|
+
|
|
301
|
+
MockOwnable ownable = new MockOwnable(projects, permissions, address(0), uint88(1));
|
|
302
|
+
|
|
303
|
+
assertEq(ownable.owner(), address(0), "Owner should resolve to zero before the project exists");
|
|
304
|
+
|
|
305
|
+
uint256 projectId = projects.createFor(alice);
|
|
306
|
+
assertEq(projectId, 1, "Expected the first minted project to match the configured future owner");
|
|
307
|
+
assertEq(ownable.owner(), alice, "Owner should resolve once the project is minted");
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
// =========================================================================
|
|
311
|
+
// Test 11: Fuzz — transfer to any valid project, verify owner resolution
|
|
296
312
|
// =========================================================================
|
|
297
313
|
function testFuzz_transferToProject(address projectOwner) public isNotContract(projectOwner) {
|
|
298
314
|
vm.assume(projectOwner != address(0));
|
|
@@ -313,7 +329,7 @@ contract OwnableEdgeCases is Test {
|
|
|
313
329
|
}
|
|
314
330
|
|
|
315
331
|
// =========================================================================
|
|
316
|
-
// Test
|
|
332
|
+
// Test 12: Renounced contract cannot reclaim ownership
|
|
317
333
|
// =========================================================================
|
|
318
334
|
/// @notice After renouncing, no one can call transferOwnership, transferOwnershipToProject,
|
|
319
335
|
/// setPermissionId, or renounceOwnership again.
|
|
@@ -350,7 +366,7 @@ contract OwnableEdgeCases is Test {
|
|
|
350
366
|
}
|
|
351
367
|
|
|
352
368
|
// =========================================================================
|
|
353
|
-
// Test
|
|
369
|
+
// Test 13: _msgSender is NOT ERC2771-aware (design documentation)
|
|
354
370
|
// =========================================================================
|
|
355
371
|
/// @notice JBOwnable uses plain Context._msgSender() (returns msg.sender),
|
|
356
372
|
/// NOT ERC2771Context. This test documents that a trusted forwarder
|
|
@@ -374,7 +390,7 @@ contract OwnableEdgeCases is Test {
|
|
|
374
390
|
}
|
|
375
391
|
|
|
376
392
|
// =========================================================================
|
|
377
|
-
// Test
|
|
393
|
+
// Test 14: OwnershipTransferred event uses _msgSender() (L-27 fix)
|
|
378
394
|
// =========================================================================
|
|
379
395
|
/// @notice When a subclass overrides _msgSender() (e.g., for ERC-2771),
|
|
380
396
|
/// the OwnershipTransferred event's caller field should reflect the
|
|
@@ -397,7 +413,7 @@ contract OwnableEdgeCases is Test {
|
|
|
397
413
|
}
|
|
398
414
|
|
|
399
415
|
// =========================================================================
|
|
400
|
-
// Test
|
|
416
|
+
// Test 15: PermissionIdChanged event uses _msgSender() (L-27 fix)
|
|
401
417
|
// =========================================================================
|
|
402
418
|
/// @notice When a subclass overrides _msgSender() (e.g., for ERC-2771),
|
|
403
419
|
/// the PermissionIdChanged event's caller field should reflect the
|