@bananapus/omnichain-deployers-v6 0.0.47 → 0.0.49

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/omnichain-deployers-v6",
3
- "version": "0.0.47",
3
+ "version": "0.0.49",
4
4
  "license": "MIT",
5
5
  "repository": {
6
6
  "type": "git",
@@ -24,16 +24,16 @@
24
24
  "artifacts": "source ./.env && npx sphinx artifacts --org-id 'ea165b21-7cdc-4d7b-be59-ecdd4c26bee4' --project-name 'nana-omnichain-deployers-v6'"
25
25
  },
26
26
  "dependencies": {
27
- "@bananapus/721-hook-v6": "^0.0.54",
28
- "@bananapus/core-v6": "^0.0.57",
29
- "@bananapus/ownable-v6": "^0.0.27",
30
- "@bananapus/permission-ids-v6": "^0.0.26",
31
- "@bananapus/suckers-v6": "^0.0.49",
27
+ "@bananapus/721-hook-v6": "^0.0.55",
28
+ "@bananapus/core-v6": "^0.0.60",
29
+ "@bananapus/ownable-v6": "^0.0.28",
30
+ "@bananapus/permission-ids-v6": "^0.0.27",
31
+ "@bananapus/suckers-v6": "^0.0.52",
32
32
  "@openzeppelin/contracts": "5.6.1"
33
33
  },
34
34
  "devDependencies": {
35
35
  "@bananapus/address-registry-v6": "^0.0.26",
36
- "@bananapus/buyback-hook-v6": "^0.0.49",
36
+ "@bananapus/buyback-hook-v6": "^0.0.51",
37
37
  "@sphinx-labs/plugins": "0.33.3",
38
38
  "@uniswap/v4-core": "1.0.2"
39
39
  }
@@ -155,10 +155,10 @@ contract JBOmnichainDeployer is
155
155
 
156
156
  /// @notice Deploy new cross-chain suckers for an existing project. Each sucker enables token bridging between this
157
157
  /// chain and a peer chain. The registry also maps configured tokens on each new sucker in the same call.
158
- /// @dev Only the project's owner or an operator with `JBPermissionIds.DEPLOY_SUCKERS` can call this. The salt
159
- /// includes `msg.sender` for replay protection the same sender must call on both chains for deterministic
160
- /// address
161
- /// matching.
158
+ /// @dev Only the project's owner or an operator with `JBPermissionIds.DEPLOY_SUCKERS` can call this. Supplying
159
+ /// an explicit non-default peer also requires `JBPermissionIds.SET_SUCKER_PEER`, matching the registry's
160
+ /// direct-call authorization model. The salt includes `msg.sender` for replay protection — the same sender must
161
+ /// call on both chains for deterministic address matching.
162
162
  /// @param projectId The ID of the project to deploy suckers for.
163
163
  /// @param suckerDeploymentConfiguration The suckers to set up for the project.
164
164
  function deploySuckersFor(
@@ -169,9 +169,17 @@ contract JBOmnichainDeployer is
169
169
  override
170
170
  returns (address[] memory suckers)
171
171
  {
172
- // Enforce permissions.
173
- _requirePermissionFrom({
174
- account: PROJECTS.ownerOf(projectId), projectId: projectId, permissionId: JBPermissionIds.DEPLOY_SUCKERS
172
+ // Resolve the project owner once because Juicebox permissions are checked against the owner's permission table.
173
+ address owner = PROJECTS.ownerOf(projectId);
174
+
175
+ // `DEPLOY_SUCKERS` authorizes this wrapper to ask the registry for new suckers, but it does not authorize
176
+ // choosing a non-default remote peer.
177
+ _requirePermissionFrom({account: owner, projectId: projectId, permissionId: JBPermissionIds.DEPLOY_SUCKERS});
178
+
179
+ // Mirror the registry's explicit-peer gate against the original project authority before this wrapper becomes
180
+ // the registry caller.
181
+ _requireExplicitSuckerPeerPermissionFrom({
182
+ account: owner, projectId: projectId, suckerDeploymentConfiguration: suckerDeploymentConfiguration
175
183
  });
176
184
 
177
185
  // Deploy the suckers.
@@ -802,6 +810,12 @@ contract JBOmnichainDeployer is
802
810
 
803
811
  // Deploy the suckers (if applicable).
804
812
  if (suckerDeploymentConfiguration.salt != bytes32(0)) {
813
+ // A launch-time project is still owned by this wrapper until the final NFT transfer, so check the
814
+ // intended owner before the registry sees `address(this)` as the current project owner.
815
+ _requireExplicitSuckerPeerPermissionFrom({
816
+ account: owner, projectId: projectId, suckerDeploymentConfiguration: suckerDeploymentConfiguration
817
+ });
818
+
805
819
  suckers = SUCKER_REGISTRY.deploySuckersFor({
806
820
  projectId: projectId,
807
821
  salt: keccak256(abi.encode(suckerDeploymentConfiguration.salt, _msgSender())),
@@ -1056,4 +1070,42 @@ contract JBOmnichainDeployer is
1056
1070
  });
1057
1071
  }
1058
1072
  }
1073
+
1074
+ /// @notice Revert unless the caller may set explicit sucker peers for `projectId`.
1075
+ /// @dev The registry enforces this against its direct caller. Since this deployer wraps the registry call, it must
1076
+ /// mirror the check against the original caller so `DEPLOY_SUCKERS` alone cannot smuggle in arbitrary peers.
1077
+ /// @param account The project owner account whose permission table is checked.
1078
+ /// @param projectId The ID of the project to deploy suckers for.
1079
+ /// @param suckerDeploymentConfiguration The sucker deployment configuration to inspect.
1080
+ function _requireExplicitSuckerPeerPermissionFrom(
1081
+ address account,
1082
+ uint256 projectId,
1083
+ JBSuckerDeploymentConfig calldata suckerDeploymentConfiguration
1084
+ )
1085
+ internal
1086
+ view
1087
+ {
1088
+ // Scan every requested sucker configuration because a single explicit peer changes cross-chain authority.
1089
+ for (uint256 i; i < suckerDeploymentConfiguration.deployerConfigurations.length;) {
1090
+ // Cache the configured peer so the default/explicit branch is evaluated from the exact value sent onward.
1091
+ bytes32 peer = suckerDeploymentConfiguration.deployerConfigurations[i].peer;
1092
+
1093
+ // `peer == 0` preserves the sucker's deterministic same-address peer behavior.
1094
+ // Any nonzero peer is written directly into the new sucker and changes who can deliver remote roots.
1095
+ if (peer != bytes32(0)) {
1096
+ // Require the original project authority, not this wrapper, to authorize explicit remote peers.
1097
+ _requirePermissionFrom({
1098
+ account: account, projectId: projectId, permissionId: JBPermissionIds.SET_SUCKER_PEER
1099
+ });
1100
+
1101
+ // One explicit peer is enough to prove the caller needs the stronger permission.
1102
+ return;
1103
+ }
1104
+
1105
+ unchecked {
1106
+ // Skip overflow checks because `i` is bounded by the calldata array length.
1107
+ ++i;
1108
+ }
1109
+ }
1110
+ }
1059
1111
  }