@bananapus/suckers-v6 0.0.32 → 0.0.34
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 +1 -1
- package/script/Deploy.s.sol +9 -8
- package/src/JBArbitrumSucker.sol +5 -2
- package/src/JBBaseSucker.sol +2 -1
- package/src/JBCCIPSucker.sol +5 -2
- package/src/JBCeloSucker.sol +2 -1
- package/src/JBOptimismSucker.sol +5 -2
- package/src/JBSucker.sol +37 -25
- package/src/JBSuckerRegistry.sol +12 -9
- package/src/JBSwapCCIPSucker.sol +2 -1
- package/src/deployers/JBArbitrumSuckerDeployer.sol +2 -1
- package/src/deployers/JBCCIPSuckerDeployer.sol +2 -1
- package/src/deployers/JBOptimismSuckerDeployer.sol +2 -1
- package/src/deployers/JBSuckerDeployer.sol +10 -6
- package/src/libraries/ARBAddresses.sol +1 -1
- package/src/libraries/ARBChains.sol +1 -1
package/package.json
CHANGED
package/script/Deploy.s.sol
CHANGED
|
@@ -4,6 +4,7 @@ pragma solidity 0.8.28;
|
|
|
4
4
|
import {IInbox} from "@arbitrum/nitro-contracts/src/bridge/IInbox.sol";
|
|
5
5
|
import {IJBDirectory} from "@bananapus/core-v6/src/interfaces/IJBDirectory.sol";
|
|
6
6
|
import {IJBPermissions} from "@bananapus/core-v6/src/interfaces/IJBPermissions.sol";
|
|
7
|
+
import {IJBPrices} from "@bananapus/core-v6/src/interfaces/IJBPrices.sol";
|
|
7
8
|
import {IJBTokens} from "@bananapus/core-v6/src/interfaces/IJBTokens.sol";
|
|
8
9
|
import {CoreDeployment, CoreDeploymentLib} from "@bananapus/core-v6/script/helpers/CoreDeploymentLib.sol";
|
|
9
10
|
import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
|
|
@@ -224,7 +225,7 @@ contract DeployScript is Script, Sphinx {
|
|
|
224
225
|
deployer: _opDeployer,
|
|
225
226
|
directory: core.directory,
|
|
226
227
|
permissions: core.permissions,
|
|
227
|
-
prices:
|
|
228
|
+
prices: core.prices,
|
|
228
229
|
tokens: core.tokens,
|
|
229
230
|
feeProjectId: 1,
|
|
230
231
|
registry: REGISTRY,
|
|
@@ -276,7 +277,7 @@ contract DeployScript is Script, Sphinx {
|
|
|
276
277
|
deployer: _opDeployer,
|
|
277
278
|
directory: core.directory,
|
|
278
279
|
permissions: core.permissions,
|
|
279
|
-
prices:
|
|
280
|
+
prices: core.prices,
|
|
280
281
|
tokens: core.tokens,
|
|
281
282
|
feeProjectId: 1,
|
|
282
283
|
registry: REGISTRY,
|
|
@@ -359,7 +360,7 @@ contract DeployScript is Script, Sphinx {
|
|
|
359
360
|
deployer: _baseDeployer,
|
|
360
361
|
directory: core.directory,
|
|
361
362
|
permissions: core.permissions,
|
|
362
|
-
prices:
|
|
363
|
+
prices: core.prices,
|
|
363
364
|
tokens: core.tokens,
|
|
364
365
|
feeProjectId: 1,
|
|
365
366
|
registry: REGISTRY,
|
|
@@ -411,7 +412,7 @@ contract DeployScript is Script, Sphinx {
|
|
|
411
412
|
deployer: _baseDeployer,
|
|
412
413
|
directory: core.directory,
|
|
413
414
|
permissions: core.permissions,
|
|
414
|
-
prices:
|
|
415
|
+
prices: core.prices,
|
|
415
416
|
tokens: core.tokens,
|
|
416
417
|
feeProjectId: 1,
|
|
417
418
|
registry: REGISTRY,
|
|
@@ -490,7 +491,7 @@ contract DeployScript is Script, Sphinx {
|
|
|
490
491
|
deployer: _arbDeployer,
|
|
491
492
|
directory: core.directory,
|
|
492
493
|
permissions: core.permissions,
|
|
493
|
-
prices:
|
|
494
|
+
prices: core.prices,
|
|
494
495
|
tokens: core.tokens,
|
|
495
496
|
feeProjectId: 1,
|
|
496
497
|
registry: REGISTRY,
|
|
@@ -545,7 +546,7 @@ contract DeployScript is Script, Sphinx {
|
|
|
545
546
|
deployer: _arbDeployer,
|
|
546
547
|
directory: core.directory,
|
|
547
548
|
permissions: core.permissions,
|
|
548
|
-
prices:
|
|
549
|
+
prices: core.prices,
|
|
549
550
|
tokens: core.tokens,
|
|
550
551
|
feeProjectId: 1,
|
|
551
552
|
registry: REGISTRY,
|
|
@@ -721,7 +722,7 @@ contract DeployScript is Script, Sphinx {
|
|
|
721
722
|
salt: salt,
|
|
722
723
|
directory: core.directory,
|
|
723
724
|
permissions: core.permissions,
|
|
724
|
-
prices:
|
|
725
|
+
prices: core.prices,
|
|
725
726
|
tokens: core.tokens,
|
|
726
727
|
configurator: safeAddress(),
|
|
727
728
|
trustedForwarder: TRUSTED_FORWARDER,
|
|
@@ -738,7 +739,7 @@ contract DeployScript is Script, Sphinx {
|
|
|
738
739
|
bytes32 salt,
|
|
739
740
|
IJBDirectory directory,
|
|
740
741
|
IJBPermissions permissions,
|
|
741
|
-
|
|
742
|
+
IJBPrices prices,
|
|
742
743
|
IJBTokens tokens,
|
|
743
744
|
address configurator,
|
|
744
745
|
address trustedForwarder,
|
package/src/JBArbitrumSucker.sol
CHANGED
|
@@ -8,6 +8,7 @@ import {AddressAliasHelper} from "@arbitrum/nitro-contracts/src/libraries/Addres
|
|
|
8
8
|
import {ArbSys} from "@arbitrum/nitro-contracts/src/precompiles/ArbSys.sol";
|
|
9
9
|
import {IJBDirectory} from "@bananapus/core-v6/src/interfaces/IJBDirectory.sol";
|
|
10
10
|
import {IJBPermissions} from "@bananapus/core-v6/src/interfaces/IJBPermissions.sol";
|
|
11
|
+
import {IJBPrices} from "@bananapus/core-v6/src/interfaces/IJBPrices.sol";
|
|
11
12
|
import {IJBTokens} from "@bananapus/core-v6/src/interfaces/IJBTokens.sol";
|
|
12
13
|
import {JBConstants} from "@bananapus/core-v6/src/libraries/JBConstants.sol";
|
|
13
14
|
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
|
|
@@ -26,7 +27,9 @@ import {ARBChains} from "./libraries/ARBChains.sol";
|
|
|
26
27
|
import {JBMessageRoot} from "./structs/JBMessageRoot.sol";
|
|
27
28
|
import {JBRemoteToken} from "./structs/JBRemoteToken.sol";
|
|
28
29
|
|
|
29
|
-
/// @notice A `JBSucker` implementation
|
|
30
|
+
/// @notice A `JBSucker` implementation that bridges Juicebox project tokens and terminal-token funds between Ethereum
|
|
31
|
+
/// L1 and Arbitrum L2 using the native Arbitrum Inbox/Outbox (for messages) and Gateway Router (for ERC-20 transfers).
|
|
32
|
+
/// Deploys on both layers — L1 instances create retryable tickets, L2 instances call `ArbSys` for L2-to-L1 messages.
|
|
30
33
|
contract JBArbitrumSucker is JBSucker, IJBArbitrumSucker {
|
|
31
34
|
//*********************************************************************//
|
|
32
35
|
// --------------------------- custom errors ------------------------- //
|
|
@@ -59,7 +62,7 @@ contract JBArbitrumSucker is JBSucker, IJBArbitrumSucker {
|
|
|
59
62
|
JBArbitrumSuckerDeployer deployer,
|
|
60
63
|
IJBDirectory directory,
|
|
61
64
|
IJBPermissions permissions,
|
|
62
|
-
|
|
65
|
+
IJBPrices prices,
|
|
63
66
|
IJBTokens tokens,
|
|
64
67
|
uint256 feeProjectId,
|
|
65
68
|
IJBSuckerRegistry registry,
|
package/src/JBBaseSucker.sol
CHANGED
|
@@ -3,6 +3,7 @@ pragma solidity 0.8.28;
|
|
|
3
3
|
|
|
4
4
|
import {IJBDirectory} from "@bananapus/core-v6/src/interfaces/IJBDirectory.sol";
|
|
5
5
|
import {IJBPermissions} from "@bananapus/core-v6/src/interfaces/IJBPermissions.sol";
|
|
6
|
+
import {IJBPrices} from "@bananapus/core-v6/src/interfaces/IJBPrices.sol";
|
|
6
7
|
import {IJBTokens} from "@bananapus/core-v6/src/interfaces/IJBTokens.sol";
|
|
7
8
|
|
|
8
9
|
import {JBOptimismSucker} from "./JBOptimismSucker.sol";
|
|
@@ -24,7 +25,7 @@ contract JBBaseSucker is JBOptimismSucker {
|
|
|
24
25
|
JBOptimismSuckerDeployer deployer,
|
|
25
26
|
IJBDirectory directory,
|
|
26
27
|
IJBPermissions permissions,
|
|
27
|
-
|
|
28
|
+
IJBPrices prices,
|
|
28
29
|
IJBTokens tokens,
|
|
29
30
|
uint256 feeProjectId,
|
|
30
31
|
IJBSuckerRegistry registry,
|
package/src/JBCCIPSucker.sol
CHANGED
|
@@ -4,6 +4,7 @@ pragma solidity 0.8.28;
|
|
|
4
4
|
// External packages (alphabetized)
|
|
5
5
|
import {IJBDirectory} from "@bananapus/core-v6/src/interfaces/IJBDirectory.sol";
|
|
6
6
|
import {IJBPermissions} from "@bananapus/core-v6/src/interfaces/IJBPermissions.sol";
|
|
7
|
+
import {IJBPrices} from "@bananapus/core-v6/src/interfaces/IJBPrices.sol";
|
|
7
8
|
import {IJBTokens} from "@bananapus/core-v6/src/interfaces/IJBTokens.sol";
|
|
8
9
|
import {JBConstants} from "@bananapus/core-v6/src/libraries/JBConstants.sol";
|
|
9
10
|
import {IAny2EVMMessageReceiver} from "@chainlink/contracts-ccip/contracts/interfaces/IAny2EVMMessageReceiver.sol";
|
|
@@ -28,7 +29,9 @@ import {JBMessageRoot} from "./structs/JBMessageRoot.sol";
|
|
|
28
29
|
import {JBRemoteToken} from "./structs/JBRemoteToken.sol";
|
|
29
30
|
import {JBTokenMapping} from "./structs/JBTokenMapping.sol";
|
|
30
31
|
|
|
31
|
-
/// @notice A `JBSucker` implementation
|
|
32
|
+
/// @notice A `JBSucker` implementation that bridges Juicebox project tokens and terminal-token funds across any pair of
|
|
33
|
+
/// chains supported by Chainlink CCIP. Messages and token transfers are bundled into a single CCIP lane message, with
|
|
34
|
+
/// the CCIP Router handling cross-chain delivery and fee estimation.
|
|
32
35
|
contract JBCCIPSucker is JBSucker, IAny2EVMMessageReceiver {
|
|
33
36
|
//*********************************************************************//
|
|
34
37
|
// --------------------------- custom errors ------------------------- //
|
|
@@ -84,7 +87,7 @@ contract JBCCIPSucker is JBSucker, IAny2EVMMessageReceiver {
|
|
|
84
87
|
JBCCIPSuckerDeployer deployer,
|
|
85
88
|
IJBDirectory directory,
|
|
86
89
|
IJBPermissions permissions,
|
|
87
|
-
|
|
90
|
+
IJBPrices prices,
|
|
88
91
|
IJBTokens tokens,
|
|
89
92
|
uint256 feeProjectId,
|
|
90
93
|
IJBSuckerRegistry registry,
|
package/src/JBCeloSucker.sol
CHANGED
|
@@ -3,6 +3,7 @@ pragma solidity 0.8.28;
|
|
|
3
3
|
|
|
4
4
|
import {IJBDirectory} from "@bananapus/core-v6/src/interfaces/IJBDirectory.sol";
|
|
5
5
|
import {IJBPermissions} from "@bananapus/core-v6/src/interfaces/IJBPermissions.sol";
|
|
6
|
+
import {IJBPrices} from "@bananapus/core-v6/src/interfaces/IJBPrices.sol";
|
|
6
7
|
import {IJBTerminal} from "@bananapus/core-v6/src/interfaces/IJBTerminal.sol";
|
|
7
8
|
import {IJBTokens} from "@bananapus/core-v6/src/interfaces/IJBTokens.sol";
|
|
8
9
|
import {JBConstants} from "@bananapus/core-v6/src/libraries/JBConstants.sol";
|
|
@@ -43,7 +44,7 @@ contract JBCeloSucker is JBOptimismSucker {
|
|
|
43
44
|
JBCeloSuckerDeployer deployer,
|
|
44
45
|
IJBDirectory directory,
|
|
45
46
|
IJBPermissions permissions,
|
|
46
|
-
|
|
47
|
+
IJBPrices prices,
|
|
47
48
|
IJBTokens tokens,
|
|
48
49
|
uint256 feeProjectId,
|
|
49
50
|
IJBSuckerRegistry registry,
|
package/src/JBOptimismSucker.sol
CHANGED
|
@@ -3,6 +3,7 @@ pragma solidity 0.8.28;
|
|
|
3
3
|
|
|
4
4
|
import {IJBDirectory} from "@bananapus/core-v6/src/interfaces/IJBDirectory.sol";
|
|
5
5
|
import {IJBPermissions} from "@bananapus/core-v6/src/interfaces/IJBPermissions.sol";
|
|
6
|
+
import {IJBPrices} from "@bananapus/core-v6/src/interfaces/IJBPrices.sol";
|
|
6
7
|
import {IJBTokens} from "@bananapus/core-v6/src/interfaces/IJBTokens.sol";
|
|
7
8
|
import {JBConstants} from "@bananapus/core-v6/src/libraries/JBConstants.sol";
|
|
8
9
|
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
|
|
@@ -17,7 +18,9 @@ import {IOPStandardBridge} from "./interfaces/IOPStandardBridge.sol";
|
|
|
17
18
|
import {JBMessageRoot} from "./structs/JBMessageRoot.sol";
|
|
18
19
|
import {JBRemoteToken} from "./structs/JBRemoteToken.sol";
|
|
19
20
|
|
|
20
|
-
/// @notice A `JBSucker` implementation
|
|
21
|
+
/// @notice A `JBSucker` implementation that bridges Juicebox project tokens and terminal-token funds between two
|
|
22
|
+
/// chains connected by an OP Stack bridge (Optimism, Base, etc.). Uses the `CrossDomainMessenger` for merkle-root
|
|
23
|
+
/// messages and the `StandardBridge` for ERC-20/native token transfers.
|
|
21
24
|
contract JBOptimismSucker is JBSucker, IJBOptimismSucker {
|
|
22
25
|
//*********************************************************************//
|
|
23
26
|
// --------------- public immutable stored properties ---------------- //
|
|
@@ -42,7 +45,7 @@ contract JBOptimismSucker is JBSucker, IJBOptimismSucker {
|
|
|
42
45
|
JBOptimismSuckerDeployer deployer,
|
|
43
46
|
IJBDirectory directory,
|
|
44
47
|
IJBPermissions permissions,
|
|
45
|
-
|
|
48
|
+
IJBPrices prices,
|
|
46
49
|
IJBTokens tokens,
|
|
47
50
|
uint256 feeProjectId,
|
|
48
51
|
IJBSuckerRegistry registry,
|
package/src/JBSucker.sol
CHANGED
|
@@ -43,17 +43,19 @@ import {JBOutboxTree} from "./structs/JBOutboxTree.sol";
|
|
|
43
43
|
import {JBRemoteToken} from "./structs/JBRemoteToken.sol";
|
|
44
44
|
import {JBTokenMapping} from "./structs/JBTokenMapping.sol";
|
|
45
45
|
|
|
46
|
-
/// @notice
|
|
47
|
-
///
|
|
48
|
-
///
|
|
49
|
-
///
|
|
46
|
+
/// @notice Bridges a Juicebox project's tokens and their backing terminal-token funds between two chains. Token
|
|
47
|
+
/// holders call `prepare` to cash out their project tokens and queue the resulting funds+tokens into an outbox merkle
|
|
48
|
+
/// tree. Anyone can then call `toRemote` to send that tree's root (and the locked funds) across the bridge to the
|
|
49
|
+
/// peer sucker on the remote chain. Once the root arrives, beneficiaries call `claim` with a merkle proof to mint
|
|
50
|
+
/// project tokens and deposit the corresponding terminal tokens into the remote project's balance.
|
|
51
|
+
///
|
|
52
|
+
/// @dev Dual merkle trees: the **outbox** accumulates leaves for tokens leaving the local chain; the **inbox** stores
|
|
53
|
+
/// the root received from the remote chain so claims can be verified locally.
|
|
50
54
|
/// @dev Throughout this contract, "terminal token" refers to any token accepted by a project's terminal.
|
|
51
|
-
/// @dev This contract does *NOT* support
|
|
52
|
-
/// @dev Cross-chain message authentication is delegated
|
|
53
|
-
///
|
|
54
|
-
///
|
|
55
|
-
/// through the Chainlink `Router`. Deployers of new bridge integrations must implement `_isRemotePeer` to
|
|
56
|
-
/// guarantee that only messages from the legitimate remote peer are accepted.
|
|
55
|
+
/// @dev This contract does *NOT* support fee-on-transfer or rebasing tokens.
|
|
56
|
+
/// @dev Cross-chain message authentication is delegated to each bridge-specific subclass via `_isRemotePeer`.
|
|
57
|
+
/// Optimism uses `CrossDomainMessenger`, Arbitrum validates against `Bridge`/`Outbox`, and CCIP verifies through
|
|
58
|
+
/// Chainlink's `Router`.
|
|
57
59
|
abstract contract JBSucker is ERC2771Context, JBPermissioned, Initializable, ERC165, IJBSuckerExtended {
|
|
58
60
|
using BitMaps for BitMaps.BitMap;
|
|
59
61
|
using MerkleLib for MerkleLib.Tree;
|
|
@@ -223,7 +225,7 @@ abstract contract JBSucker is ERC2771Context, JBPermissioned, Initializable, ERC
|
|
|
223
225
|
constructor(
|
|
224
226
|
IJBDirectory directory,
|
|
225
227
|
IJBPermissions permissions,
|
|
226
|
-
|
|
228
|
+
IJBPrices prices,
|
|
227
229
|
IJBTokens tokens,
|
|
228
230
|
uint256 feeProjectId,
|
|
229
231
|
IJBSuckerRegistry registry,
|
|
@@ -234,7 +236,7 @@ abstract contract JBSucker is ERC2771Context, JBPermissioned, Initializable, ERC
|
|
|
234
236
|
{
|
|
235
237
|
DIRECTORY = directory;
|
|
236
238
|
FEE_PROJECT_ID = feeProjectId;
|
|
237
|
-
PRICES =
|
|
239
|
+
PRICES = prices;
|
|
238
240
|
PROJECTS = directory.PROJECTS();
|
|
239
241
|
REGISTRY = registry;
|
|
240
242
|
TOKENS = tokens;
|
|
@@ -265,7 +267,8 @@ abstract contract JBSucker is ERC2771Context, JBPermissioned, Initializable, ERC
|
|
|
265
267
|
// --------------------- external transactions ----------------------- //
|
|
266
268
|
//*********************************************************************//
|
|
267
269
|
|
|
268
|
-
/// @notice
|
|
270
|
+
/// @notice Claim multiple bridged entries in a single transaction. Each claim mints project tokens for the
|
|
271
|
+
/// beneficiary and deposits the corresponding terminal tokens into the project's local balance.
|
|
269
272
|
/// @param claims A list of claims to perform (including the terminal token, merkle tree leaf, and proof for each
|
|
270
273
|
/// claim).
|
|
271
274
|
function claim(JBClaim[] calldata claims) external override {
|
|
@@ -278,7 +281,8 @@ abstract contract JBSucker is ERC2771Context, JBPermissioned, Initializable, ERC
|
|
|
278
281
|
}
|
|
279
282
|
}
|
|
280
283
|
|
|
281
|
-
/// @notice
|
|
284
|
+
/// @notice Claim a single bridged entry: verifies the merkle proof against the inbox root, mints the specified
|
|
285
|
+
/// project tokens for the beneficiary, and deposits the terminal tokens into the project's local balance.
|
|
282
286
|
/// @param claimData The terminal token, merkle tree leaf, and proof for the claim.
|
|
283
287
|
function claim(JBClaim calldata claimData) public virtual override {
|
|
284
288
|
// Attempt to validate the proof against the inbox tree for the terminal token.
|
|
@@ -334,8 +338,10 @@ abstract contract JBSucker is ERC2771Context, JBPermissioned, Initializable, ERC
|
|
|
334
338
|
emit EmergencyHatchOpened({tokens: tokens, caller: _msgSender()});
|
|
335
339
|
}
|
|
336
340
|
|
|
337
|
-
/// @notice
|
|
338
|
-
///
|
|
341
|
+
/// @notice Emergency escape hatch: lets a user reclaim their project tokens and terminal tokens on the chain they
|
|
342
|
+
/// originally deposited from, when the bridge has become permanently non-functional. Must be enabled by the project
|
|
343
|
+
/// owner via the registry's `setEmergencyHatchStatusOf`.
|
|
344
|
+
/// @param claimData The terminal token, merkle tree leaf, and proof for the claim.
|
|
339
345
|
function exitThroughEmergencyHatch(JBClaim calldata claimData) external override {
|
|
340
346
|
// Does all the needed validation to ensure that the claim is valid *and* that claiming through the emergency
|
|
341
347
|
// hatch is allowed.
|
|
@@ -368,7 +374,8 @@ abstract contract JBSucker is ERC2771Context, JBPermissioned, Initializable, ERC
|
|
|
368
374
|
});
|
|
369
375
|
}
|
|
370
376
|
|
|
371
|
-
/// @notice Receive a merkle root
|
|
377
|
+
/// @notice Receive a merkle root and peer-chain accounting snapshot from the remote sucker. Updates the inbox tree
|
|
378
|
+
/// so that users can claim bridged tokens. Also accepts any native-token funds delivered with the message.
|
|
372
379
|
/// @dev This can only be called by the messenger contract on the local chain, with a message from the remote peer.
|
|
373
380
|
/// @dev Nonce ordering: This function accepts any nonce strictly greater than the current inbox nonce, rather than
|
|
374
381
|
/// requiring sequential (nonce == inbox.nonce + 1) processing. This is intentional because some bridges (e.g.,
|
|
@@ -448,8 +455,10 @@ abstract contract JBSucker is ERC2771Context, JBPermissioned, Initializable, ERC
|
|
|
448
455
|
}
|
|
449
456
|
}
|
|
450
457
|
|
|
451
|
-
/// @notice
|
|
452
|
-
/// tokens to
|
|
458
|
+
/// @notice Configure which remote-chain tokens each local terminal token maps to, enabling (or disabling) those
|
|
459
|
+
/// tokens for cross-chain bridging. Setting a remote token to `bytes32(0)` disables bridging and flushes any
|
|
460
|
+
/// pending outbox entries. Requires `MAP_SUCKER_TOKEN` permission from the project owner (or called by the
|
|
461
|
+
/// registry during deployment).
|
|
453
462
|
/// @param maps A list of local and remote terminal token addresses to map, and minimum amount/gas limits for
|
|
454
463
|
/// bridging them.
|
|
455
464
|
function mapTokens(JBTokenMapping[] calldata maps) external payable override {
|
|
@@ -495,7 +504,9 @@ abstract contract JBSucker is ERC2771Context, JBPermissioned, Initializable, ERC
|
|
|
495
504
|
}
|
|
496
505
|
}
|
|
497
506
|
|
|
498
|
-
/// @notice
|
|
507
|
+
/// @notice Queue project tokens for bridging to the remote chain. Transfers the caller's project tokens into this
|
|
508
|
+
/// contract, cashes them out for the specified terminal token, and inserts a leaf into the outbox merkle tree. The
|
|
509
|
+
/// queued entry will be bridged the next time anyone calls `toRemote` for the same `token`.
|
|
499
510
|
/// @dev This adds the tokens and funds to the outbox tree for the `token`. They will be bridged by the next call to
|
|
500
511
|
/// `toRemote` for the same `token`.
|
|
501
512
|
/// @dev Reentrancy protection: This function has implicit reentrancy protection through `_pullBackingAssets`.
|
|
@@ -562,8 +573,9 @@ abstract contract JBSucker is ERC2771Context, JBPermissioned, Initializable, ERC
|
|
|
562
573
|
});
|
|
563
574
|
}
|
|
564
575
|
|
|
565
|
-
/// @notice
|
|
566
|
-
///
|
|
576
|
+
/// @notice Schedule (or cancel) the deprecation of this sucker. Once deprecated, no new outbound transfers are
|
|
577
|
+
/// accepted and users can exit via the emergency hatch. Requires `SET_SUCKER_DEPRECATION` permission. A mandatory
|
|
578
|
+
/// 14-day buffer ensures in-flight messages have time to arrive before the sucker fully shuts down.
|
|
567
579
|
/// @param timestamp The time after which the sucker will be deprecated. Or `0` to remove the upcoming deprecation.
|
|
568
580
|
function setDeprecation(uint40 timestamp) external override {
|
|
569
581
|
// As long as the sucker has not started letting users withdrawal, its deprecation time can be
|
|
@@ -599,9 +611,9 @@ abstract contract JBSucker is ERC2771Context, JBPermissioned, Initializable, ERC
|
|
|
599
611
|
emit DeprecationTimeUpdated({timestamp: timestamp, caller: _msgSender()});
|
|
600
612
|
}
|
|
601
613
|
|
|
602
|
-
/// @notice
|
|
603
|
-
/// remote
|
|
604
|
-
///
|
|
614
|
+
/// @notice Send the accumulated outbox merkle root and locked terminal-token funds for a given `token` across the
|
|
615
|
+
/// bridge to the remote peer sucker. Anyone can call this once entries exist in the outbox. Requires `msg.value`
|
|
616
|
+
/// to cover the registry's `toRemoteFee` plus any bridge transport payment.
|
|
605
617
|
/// @dev This sends the outbox root for the specified `token` to the remote chain.
|
|
606
618
|
/// @dev Fee payment failure handling: The registry fee payment uses a best-effort pattern (try/catch). If the
|
|
607
619
|
/// fee project's terminal doesn't exist or the `pay` call reverts, the fee ETH is retained as a refundable balance
|
package/src/JBSuckerRegistry.sol
CHANGED
|
@@ -19,7 +19,10 @@ import {IJBSuckerRegistry} from "./interfaces/IJBSuckerRegistry.sol";
|
|
|
19
19
|
import {JBSuckerDeployerConfig} from "./structs/JBSuckerDeployerConfig.sol";
|
|
20
20
|
import {JBSuckersPair} from "./structs/JBSuckersPair.sol";
|
|
21
21
|
|
|
22
|
-
/// @notice
|
|
22
|
+
/// @notice The canonical registry that deploys, tracks, and governs cross-chain suckers for Juicebox projects. It
|
|
23
|
+
/// maintains an allowlist of approved deployer contracts, enforces one active sucker per peer chain per project,
|
|
24
|
+
/// manages the global `toRemoteFee` (paid into the protocol fee project on each bridge send), and provides aggregate
|
|
25
|
+
/// views of remote-chain balances, surplus, and token supply across all of a project's suckers.
|
|
23
26
|
contract JBSuckerRegistry is ERC2771Context, Ownable, JBPermissioned, IJBSuckerRegistry {
|
|
24
27
|
using EnumerableMap for EnumerableMap.AddressToUintMap;
|
|
25
28
|
|
|
@@ -55,7 +58,7 @@ contract JBSuckerRegistry is ERC2771Context, Ownable, JBPermissioned, IJBSuckerR
|
|
|
55
58
|
// --------------- public immutable stored properties ---------------- //
|
|
56
59
|
//*********************************************************************//
|
|
57
60
|
|
|
58
|
-
/// @notice The
|
|
61
|
+
/// @notice The Juicebox directory used to look up project terminals and controllers.
|
|
59
62
|
IJBDirectory public immutable override DIRECTORY;
|
|
60
63
|
|
|
61
64
|
/// @notice A contract which mints ERC-721s that represent project ownership and transfers.
|
|
@@ -105,8 +108,8 @@ contract JBSuckerRegistry is ERC2771Context, Ownable, JBPermissioned, IJBSuckerR
|
|
|
105
108
|
// ------------------------- external views -------------------------- //
|
|
106
109
|
//*********************************************************************//
|
|
107
110
|
|
|
108
|
-
/// @notice
|
|
109
|
-
///
|
|
111
|
+
/// @notice Whether the given address is a sucker (active or deprecated) that was deployed through this registry for
|
|
112
|
+
/// the specified project. Used by controllers to authorize mint calls from suckers.
|
|
110
113
|
/// @param projectId The ID of the project to check for.
|
|
111
114
|
/// @param addr The address of the sucker to check.
|
|
112
115
|
/// @return flag A flag indicating if the sucker belongs to the project, and was deployed through this registry.
|
|
@@ -115,7 +118,7 @@ contract JBSuckerRegistry is ERC2771Context, Ownable, JBPermissioned, IJBSuckerR
|
|
|
115
118
|
return exists && (val == _SUCKER_EXISTS || val == _SUCKER_DEPRECATED);
|
|
116
119
|
}
|
|
117
120
|
|
|
118
|
-
/// @notice
|
|
121
|
+
/// @notice All active (non-deprecated) suckers for a project, with their remote peer address and chain ID.
|
|
119
122
|
/// @param projectId The ID of the project to get the suckers of.
|
|
120
123
|
/// @return pairs The pairs of suckers and their metadata.
|
|
121
124
|
function suckerPairsOf(uint256 projectId) external view override returns (JBSuckersPair[] memory pairs) {
|
|
@@ -498,10 +501,10 @@ contract JBSuckerRegistry is ERC2771Context, Ownable, JBPermissioned, IJBSuckerR
|
|
|
498
501
|
}
|
|
499
502
|
}
|
|
500
503
|
|
|
501
|
-
/// @notice Deploy one or more suckers for
|
|
502
|
-
///
|
|
503
|
-
///
|
|
504
|
-
///
|
|
504
|
+
/// @notice Deploy one or more cross-chain suckers for a project in a single transaction. Each sucker is created via
|
|
505
|
+
/// its deployer, registered in this registry, checked for duplicate peer chains, and immediately configured with
|
|
506
|
+
/// its token mappings. The caller must have `DEPLOY_SUCKERS` permission, and this registry must hold
|
|
507
|
+
/// `MAP_SUCKER_TOKEN` permission for the project.
|
|
505
508
|
/// @param projectId The ID of the project to deploy suckers for.
|
|
506
509
|
/// @param salt The salt used to deploy the contract. For the suckers to be peers, this must be the same value on
|
|
507
510
|
/// each chain where suckers are deployed.
|
package/src/JBSwapCCIPSucker.sol
CHANGED
|
@@ -4,6 +4,7 @@ pragma solidity 0.8.28;
|
|
|
4
4
|
// Core JB imports.
|
|
5
5
|
import {IJBDirectory} from "@bananapus/core-v6/src/interfaces/IJBDirectory.sol";
|
|
6
6
|
import {IJBPermissions} from "@bananapus/core-v6/src/interfaces/IJBPermissions.sol";
|
|
7
|
+
import {IJBPrices} from "@bananapus/core-v6/src/interfaces/IJBPrices.sol";
|
|
7
8
|
import {IJBTokens} from "@bananapus/core-v6/src/interfaces/IJBTokens.sol";
|
|
8
9
|
// CCIP imports.
|
|
9
10
|
import {Client} from "@chainlink/contracts-ccip/contracts/libraries/Client.sol";
|
|
@@ -209,7 +210,7 @@ contract JBSwapCCIPSucker is JBCCIPSucker, IUnlockCallback, IUniswapV3SwapCallba
|
|
|
209
210
|
JBSwapCCIPSuckerDeployer deployer,
|
|
210
211
|
IJBDirectory directory,
|
|
211
212
|
IJBPermissions permissions,
|
|
212
|
-
|
|
213
|
+
IJBPrices prices,
|
|
213
214
|
IJBTokens tokens,
|
|
214
215
|
uint256 feeProjectId,
|
|
215
216
|
IJBSuckerRegistry registry,
|
|
@@ -17,7 +17,8 @@ import {IJBArbitrumSuckerDeployer} from "../interfaces/IJBArbitrumSuckerDeployer
|
|
|
17
17
|
// Local: deployers.
|
|
18
18
|
import {JBSuckerDeployer} from "./JBSuckerDeployer.sol";
|
|
19
19
|
|
|
20
|
-
/// @notice
|
|
20
|
+
/// @notice Deployer for Arbitrum suckers. Stores the Inbox and Gateway Router for the target layer (L1 or L2) and
|
|
21
|
+
/// clones `JBArbitrumSucker` instances via CREATE2.
|
|
21
22
|
contract JBArbitrumSuckerDeployer is JBSuckerDeployer, IJBArbitrumSuckerDeployer {
|
|
22
23
|
//*********************************************************************//
|
|
23
24
|
// ---------------------- public stored properties ------------------- //
|
|
@@ -13,7 +13,8 @@ import {IJBCCIPSuckerDeployer} from "../interfaces/IJBCCIPSuckerDeployer.sol";
|
|
|
13
13
|
// Local: deployers.
|
|
14
14
|
import {JBSuckerDeployer} from "./JBSuckerDeployer.sol";
|
|
15
15
|
|
|
16
|
-
/// @notice
|
|
16
|
+
/// @notice Deployer for Chainlink CCIP suckers. Stores the CCIP router, remote chain ID, and remote chain selector,
|
|
17
|
+
/// then clones `JBCCIPSucker` instances via CREATE2.
|
|
17
18
|
contract JBCCIPSuckerDeployer is JBSuckerDeployer, IJBCCIPSuckerDeployer {
|
|
18
19
|
//*********************************************************************//
|
|
19
20
|
// ---------------------- public stored properties ------------------- //
|
|
@@ -14,7 +14,8 @@ import {IOPStandardBridge} from "../interfaces/IOPStandardBridge.sol";
|
|
|
14
14
|
// Local: deployers.
|
|
15
15
|
import {JBSuckerDeployer} from "./JBSuckerDeployer.sol";
|
|
16
16
|
|
|
17
|
-
/// @notice
|
|
17
|
+
/// @notice Deployer for OP Stack suckers (Optimism, Base, etc.). Stores the CrossDomainMessenger and StandardBridge
|
|
18
|
+
/// for this chain and clones `JBOptimismSucker` instances via CREATE2.
|
|
18
19
|
contract JBOptimismSuckerDeployer is JBSuckerDeployer, IJBOpSuckerDeployer {
|
|
19
20
|
//*********************************************************************//
|
|
20
21
|
// ---------------------- public stored properties ------------------- //
|
|
@@ -17,7 +17,10 @@ import {JBSucker} from "../JBSucker.sol";
|
|
|
17
17
|
import {IJBSucker} from "../interfaces/IJBSucker.sol";
|
|
18
18
|
import {IJBSuckerDeployer} from "../interfaces/IJBSuckerDeployer.sol";
|
|
19
19
|
|
|
20
|
-
/// @notice
|
|
20
|
+
/// @notice Base factory for deploying cross-chain suckers using CREATE2 clones. Each bridge-specific deployer (OP,
|
|
21
|
+
/// Arbitrum, CCIP) extends this contract with its own chain configuration. Setup is two-step: first the configurator
|
|
22
|
+
/// calls `setChainSpecificConstants` (bridge addresses, chain selectors), then `configureSingleton` (the
|
|
23
|
+
/// implementation to clone). After setup, anyone may call `createForSender` to deploy a new sucker for a project.
|
|
21
24
|
abstract contract JBSuckerDeployer is ERC2771Context, JBPermissioned, IJBSuckerDeployer {
|
|
22
25
|
//*********************************************************************//
|
|
23
26
|
// --------------------------- custom errors ------------------------- //
|
|
@@ -47,7 +50,7 @@ abstract contract JBSuckerDeployer is ERC2771Context, JBPermissioned, IJBSuckerD
|
|
|
47
50
|
// ---------------------- public stored properties ------------------- //
|
|
48
51
|
//*********************************************************************//
|
|
49
52
|
|
|
50
|
-
/// @notice
|
|
53
|
+
/// @notice Whether a given address was deployed by this deployer.
|
|
51
54
|
mapping(address => bool) public override isSucker;
|
|
52
55
|
|
|
53
56
|
/// @notice The singleton used to clone suckers.
|
|
@@ -117,8 +120,8 @@ abstract contract JBSuckerDeployer is ERC2771Context, JBPermissioned, IJBSuckerD
|
|
|
117
120
|
// --------------------- external transactions ----------------------- //
|
|
118
121
|
//*********************************************************************//
|
|
119
122
|
|
|
120
|
-
/// @notice
|
|
121
|
-
/// @dev
|
|
123
|
+
/// @notice Set the implementation contract that all future suckers will be cloned from. Can only be called once.
|
|
124
|
+
/// @dev Must be called by the layer-specific configurator after `setChainSpecificConstants`.
|
|
122
125
|
/// @param _singleton The address of the singleton.
|
|
123
126
|
function configureSingleton(JBSucker _singleton) external {
|
|
124
127
|
// Make sure only the configurator can call this function.
|
|
@@ -138,8 +141,9 @@ abstract contract JBSuckerDeployer is ERC2771Context, JBPermissioned, IJBSuckerD
|
|
|
138
141
|
singleton = _singleton;
|
|
139
142
|
}
|
|
140
143
|
|
|
141
|
-
/// @notice
|
|
142
|
-
///
|
|
144
|
+
/// @notice Deploy a new sucker clone for a project via CREATE2. The same sender must call this on both chains to
|
|
145
|
+
/// produce matching deterministic addresses.
|
|
146
|
+
/// @dev Called by the registry during `deploySuckersFor`.
|
|
143
147
|
/// @param localProjectId The project's ID on the local chain.
|
|
144
148
|
/// @param salt The salt to use for the `create2` address.
|
|
145
149
|
/// @param peer The remote peer address. Leave zero to use the default deterministic same-address peer.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// SPDX-License-Identifier: MIT
|
|
2
2
|
pragma solidity 0.8.28;
|
|
3
3
|
|
|
4
|
-
/// @notice
|
|
4
|
+
/// @notice Arbitrum bridge infrastructure addresses (Inbox and Gateway Routers) for mainnet and Sepolia.
|
|
5
5
|
library ARBAddresses {
|
|
6
6
|
/// @notice The respective Inbox used by L1 or Testnet L1
|
|
7
7
|
address public constant L1_ETH_INBOX = 0x4Dbd4fc535Ac27206064B68FfCf827b0A60BAB3f;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// SPDX-License-Identifier: MIT
|
|
2
2
|
pragma solidity 0.8.28;
|
|
3
3
|
|
|
4
|
-
/// @notice
|
|
4
|
+
/// @notice Arbitrum chain IDs for mainnet and Sepolia testnet pairs.
|
|
5
5
|
library ARBChains {
|
|
6
6
|
/// @notice Arbitrum relevant chains and their respective ids.
|
|
7
7
|
uint256 public constant ETH_CHAINID = 1;
|