@bananapus/suckers-v6 0.0.53 → 0.0.55

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bananapus/suckers-v6",
3
- "version": "0.0.53",
3
+ "version": "0.0.55",
4
4
  "license": "MIT",
5
5
  "repository": {
6
6
  "type": "git",
@@ -49,7 +49,8 @@ contract JBCCIPSucker is JBSucker, IAny2EVMMessageReceiver {
49
49
  /// committing the bridge message.
50
50
  /// @param recipient The address that was supposed to receive the refund.
51
51
  /// @param amount The amount of the failed refund.
52
- event TransportPaymentRefundFailed(address indexed recipient, uint256 amount);
52
+ /// @param caller The address that triggered the CCIP send.
53
+ event TransportPaymentRefundFailed(address indexed recipient, uint256 amount, address caller);
53
54
 
54
55
  //*********************************************************************//
55
56
  // ----------------------- internal constants ------------------------ //
@@ -255,7 +256,7 @@ contract JBCCIPSucker is JBSucker, IAny2EVMMessageReceiver {
255
256
  if (refundFailed) {
256
257
  // Refund accounting is isolated per caller; reentry cannot increase the retained credit.
257
258
  _retainTransportPaymentRefund({account: _msgSender(), amount: refundAmount});
258
- emit TransportPaymentRefundFailed({recipient: _msgSender(), amount: refundAmount});
259
+ emit TransportPaymentRefundFailed({recipient: _msgSender(), amount: refundAmount, caller: _msgSender()});
259
260
  }
260
261
  }
261
262
 
package/src/JBSucker.sol CHANGED
@@ -446,7 +446,9 @@ abstract contract JBSucker is ERC2771Context, JBPermissioned, Initializable, ERC
446
446
  } else {
447
447
  // Emit an event when a root is rejected due to a stale (non-increasing) nonce.
448
448
  // This aids off-chain monitoring in detecting out-of-order or duplicate deliveries.
449
- emit StaleRootRejected({token: localToken, receivedNonce: root.remoteRoot.nonce, currentNonce: inbox.nonce});
449
+ emit StaleRootRejected({
450
+ token: localToken, receivedNonce: root.remoteRoot.nonce, currentNonce: inbox.nonce, caller: _msgSender()
451
+ });
450
452
  }
451
453
 
452
454
  // --- Project-wide shared state update (gated by source freshness key) ---
@@ -1590,7 +1592,7 @@ abstract contract JBSucker is ERC2771Context, JBPermissioned, Initializable, ERC
1590
1592
  function _retainToRemoteFee(address account, uint256 amount) internal {
1591
1593
  retainedToRemoteFeeOf[account] += amount;
1592
1594
  retainedToRemoteFeeBalance += amount;
1593
- emit RetainedToRemoteFee({account: account, amount: amount});
1595
+ emit RetainedToRemoteFee({account: account, amount: amount, caller: _msgSender()});
1594
1596
  }
1595
1597
 
1596
1598
  /// @notice Retains a failed transport-payment refund as account-scoped native credit.
@@ -1599,7 +1601,7 @@ abstract contract JBSucker is ERC2771Context, JBPermissioned, Initializable, ERC
1599
1601
  function _retainTransportPaymentRefund(address account, uint256 amount) internal {
1600
1602
  retainedTransportPaymentRefundOf[account] += amount;
1601
1603
  retainedTransportPaymentRefundBalance += amount;
1602
- emit RetainedTransportPaymentRefund({account: account, amount: amount});
1604
+ emit RetainedTransportPaymentRefund({account: account, amount: amount, caller: _msgSender()});
1603
1605
  }
1604
1606
 
1605
1607
  /// @notice Returns the peer address as an EVM address.
@@ -500,8 +500,13 @@ contract JBSuckerRegistry is ERC2771Context, Ownable, JBPermissioned, IJBSuckerR
500
500
  override
501
501
  returns (address[] memory suckers)
502
502
  {
503
+ // Cache the project owner so deployment and explicit-peer authorization are both checked against the same
504
+ // project authority, not a delegated operator.
505
+ address projectOwner = PROJECTS.ownerOf(projectId);
506
+
507
+ // `DEPLOY_SUCKERS` authorizes creating suckers and applying their launch-time token mappings.
503
508
  _requirePermissionFrom({
504
- account: PROJECTS.ownerOf(projectId), projectId: projectId, permissionId: JBPermissionIds.DEPLOY_SUCKERS
509
+ account: projectOwner, projectId: projectId, permissionId: JBPermissionIds.DEPLOY_SUCKERS
505
510
  });
506
511
 
507
512
  // Create an array to store the suckers as they are deployed.
@@ -516,16 +521,9 @@ contract JBSuckerRegistry is ERC2771Context, Ownable, JBPermissioned, IJBSuckerR
516
521
  // default peer symmetry assumption will not hold.
517
522
  salt = keccak256(abi.encode(sender, salt));
518
523
 
519
- // Cache the project owner so the explicit-peer gate can check against the original authority, not a
520
- // delegated operator. The default same-address peering invariant (peer == 0 or peer == address(this))
521
- // does not need this stronger gate, but a non-symmetric explicit peer authorizes that arbitrary address
522
- // to deliver outbox roots and mint project tokens — so it must require a permission strictly broader
523
- // than ops automation's `DEPLOY_SUCKERS`.
524
- address projectOwner = PROJECTS.ownerOf(projectId);
525
-
526
524
  // Iterate through the configurations and deploy the suckers.
527
525
  for (uint256 i; i < configurations.length;) {
528
- // Get the configuration being iterated over.
526
+ // Copy the configuration once because its deployer, peer, mappings, and event payload are all reused below.
529
527
  JBSuckerDeployerConfig memory configuration = configurations[i];
530
528
 
531
529
  // Make sure the deployer is allowed.
@@ -533,13 +531,11 @@ contract JBSuckerRegistry is ERC2771Context, Ownable, JBPermissioned, IJBSuckerR
533
531
  revert JBSuckerRegistry_InvalidDeployer({deployer: configuration.deployer});
534
532
  }
535
533
 
536
- // If the configuration specifies a non-symmetric explicit peer, require the additional
537
- // `SET_SUCKER_PEER` permission. Default peering (peer == 0 or peer == bytes32 of address(this)) is
538
- // unaffected. Without this gate, a delegated operator with only `DEPLOY_SUCKERS` could register an
539
- // attacker peer and use the resulting sucker's mint authority to deliver fabricated outbox roots.
540
- // forge-lint: disable-next-line(unsafe-typecast)
541
- bytes32 selfPeer = bytes32(uint256(uint160(address(this))));
542
- if (configuration.peer != bytes32(0) && configuration.peer != selfPeer) {
534
+ // `peer == 0` tells the sucker to use its own clone address as the deterministic same-address peer, so the
535
+ // deploy permission is enough for that default path.
536
+ // Every nonzero value is an explicit remote authority, including this registry's address.
537
+ if (configuration.peer != bytes32(0)) {
538
+ // Only a caller with `SET_SUCKER_PEER` may choose that explicit remote authority.
543
539
  _requirePermissionFrom({
544
540
  account: projectOwner, projectId: projectId, permissionId: JBPermissionIds.SET_SUCKER_PEER
545
541
  });
@@ -106,7 +106,10 @@ contract JBSwapCCIPSucker is JBCCIPSucker, IUnlockCallback, IUniswapV3SwapCallba
106
106
  /// @param nonce The nonce of the batch whose swap was retried.
107
107
  /// @param bridgeAmount The amount of bridge tokens that were swapped.
108
108
  /// @param localAmount The amount of local tokens received from the retry swap.
109
- event SwapRetried(address indexed localToken, uint64 indexed nonce, uint256 bridgeAmount, uint256 localAmount);
109
+ /// @param caller The address that retried the swap.
110
+ event SwapRetried(
111
+ address indexed localToken, uint64 indexed nonce, uint256 bridgeAmount, uint256 localAmount, address caller
112
+ );
110
113
 
111
114
  //*********************************************************************//
112
115
  // --------------- public immutable stored properties ---------------- //
@@ -510,7 +513,11 @@ contract JBSwapCCIPSucker is JBCCIPSucker, IUnlockCallback, IUniswapV3SwapCallba
510
513
 
511
514
  _retrySwapLocked = false;
512
515
  emit SwapRetried({
513
- localToken: localToken, nonce: nonce, bridgeAmount: pending.bridgeAmount, localAmount: localAmount
516
+ localToken: localToken,
517
+ nonce: nonce,
518
+ bridgeAmount: pending.bridgeAmount,
519
+ localAmount: localAmount,
520
+ caller: _msgSender()
514
521
  });
515
522
  }
516
523
 
@@ -643,7 +650,7 @@ contract JBSwapCCIPSucker is JBCCIPSucker, IUnlockCallback, IUniswapV3SwapCallba
643
650
 
644
651
  if (refundFailed) {
645
652
  _retainTransportPaymentRefund({account: _msgSender(), amount: refundAmount});
646
- emit TransportPaymentRefundFailed({recipient: _msgSender(), amount: refundAmount});
653
+ emit TransportPaymentRefundFailed({recipient: _msgSender(), amount: refundAmount, caller: _msgSender()});
647
654
  }
648
655
  }
649
656
  }
@@ -74,7 +74,8 @@ interface IJBSucker is IERC165 {
74
74
  /// @param token The terminal token address.
75
75
  /// @param receivedNonce The nonce of the rejected root.
76
76
  /// @param currentNonce The current nonce that was expected.
77
- event StaleRootRejected(address indexed token, uint64 receivedNonce, uint64 currentNonce);
77
+ /// @param caller The address that relayed the stale root.
78
+ event StaleRootRejected(address indexed token, uint64 receivedNonce, uint64 currentNonce, address caller);
78
79
 
79
80
  // View functions
80
81
 
@@ -34,12 +34,14 @@ interface IJBSuckerExtended is IJBSucker {
34
34
  /// @notice Emitted when a failed `toRemoteFee` payment is retained for later refund.
35
35
  /// @param account The account that can reclaim the retained fee.
36
36
  /// @param amount The retained fee amount.
37
- event RetainedToRemoteFee(address indexed account, uint256 amount);
37
+ /// @param caller The address that caused the fee to be retained.
38
+ event RetainedToRemoteFee(address indexed account, uint256 amount, address caller);
38
39
 
39
40
  /// @notice Emitted when a failed transport-payment refund is retained for later refund.
40
41
  /// @param account The account that can reclaim the retained refund.
41
42
  /// @param amount The retained refund amount.
42
- event RetainedTransportPaymentRefund(address indexed account, uint256 amount);
43
+ /// @param caller The address that caused the refund to be retained.
44
+ event RetainedTransportPaymentRefund(address indexed account, uint256 amount, address caller);
43
45
 
44
46
  /// @notice Emitted when an account claims retained `toRemoteFee` ETH.
45
47
  /// @param account The account whose retained fee balance was claimed.