@bananapus/router-terminal-v6 0.0.21 → 0.0.23
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/ARCHITECTURE.md +1 -1
- package/AUDIT_INSTRUCTIONS.md +4 -4
- package/CHANGE_LOG.md +2 -2
- package/README.md +2 -2
- package/RISKS.md +7 -7
- package/SKILLS.md +2 -2
- package/package.json +1 -1
- package/script/Deploy.s.sol +12 -7
- package/src/JBRouterTerminal.sol +182 -60
- package/src/JBRouterTerminalRegistry.sol +3 -7
- package/src/interfaces/IGeomeanOracle.sol +21 -0
- package/test/RouterTerminal.t.sol +56 -36
- package/test/RouterTerminalCashOutFork.t.sol +0 -1
- package/test/RouterTerminalCreditCashout.t.sol +0 -5
- package/test/RouterTerminalERC2771.t.sol +0 -5
- package/test/RouterTerminalFeeCashOutFork.t.sol +0 -1
- package/test/RouterTerminalFork.t.sol +0 -1
- package/test/RouterTerminalMultihopFork.t.sol +0 -1
- package/test/RouterTerminalPreviewFork.t.sol +7 -5
- package/test/RouterTerminalReentrancy.t.sol +0 -5
- package/test/RouterTerminalRegistry.t.sol +3 -1
- package/test/RouterTerminalSandwichFork.t.sol +0 -1
- package/test/TestAuditGaps.sol +5 -7
- package/test/audit/LeftoverRefund.t.sol +45 -25
- package/test/audit/PayerTrackerRefund.t.sol +12 -8
- package/test/audit/RefundToBeneficiary.t.sol +0 -2
- package/test/audit/RegistryAddToBalancePartialFill.t.sol +48 -37
- package/test/fork/V4QuoteAndSettlementFork.t.sol +0 -1
- package/test/invariant/RouterTerminalInvariant.t.sol +1 -5
- package/test/regression/CashOutLoopLimit.t.sol +1 -4
- package/test/regression/RouterTerminalEdgeCases.t.sol +49 -27
package/ARCHITECTURE.md
CHANGED
|
@@ -56,7 +56,7 @@ Payer → JBRouterTerminal.pay(projectId, token, amount)
|
|
|
56
56
|
│ ├─ Quote & slippage (_pickPoolAndQuote):
|
|
57
57
|
│ │ 1. User-provided quote (metadata "quoteForSwap") — used as-is
|
|
58
58
|
│ │ 2. V3 fallback: 10-min TWAP via OracleLibrary.consult()
|
|
59
|
-
│ │ 3. V4 fallback: spot price from getSlot0()
|
|
59
|
+
│ │ 3. V4 fallback: TWAP from oracle hook if available, else spot price from getSlot0()
|
|
60
60
|
│ │ Apply sigmoid slippage: minSlippage + range * impact/(impact+K)
|
|
61
61
|
│ │
|
|
62
62
|
│ ├─ Execute swap via V3 pool.swap() or V4 POOL_MANAGER.unlock()
|
package/AUDIT_INSTRUCTIONS.md
CHANGED
|
@@ -83,7 +83,7 @@ Quote priority in `_pickPoolAndQuote()`:
|
|
|
83
83
|
|
|
84
84
|
1. **User-provided quote** -- If `quoteForSwap` metadata key is present, its value is used as `minAmountOut` directly. This is the recommended path for all swaps, especially V4.
|
|
85
85
|
2. **V3 TWAP** -- `_getV3TwapQuote()` uses `OracleLibrary.consult()` with a 10-minute window (capped to oldest available observation). Computes `minAmountOut = twapQuote * (1 - sigmoidSlippage)`.
|
|
86
|
-
3. **V4 spot
|
|
86
|
+
3. **V4 TWAP-then-spot** -- `_getV4Quote()` first attempts a 30-second TWAP from the pool's oracle hook (e.g., `IGeomeanOracle.observe()`). If no oracle hook exists or the call fails, it falls back to the instantaneous tick from `getSlot0()`. Same sigmoid slippage formula applied to both paths. The spot fallback is manipulable within a single block.
|
|
87
87
|
|
|
88
88
|
### Sigmoid Slippage Formula
|
|
89
89
|
|
|
@@ -123,7 +123,7 @@ When the input token is a JB project token (detected via `TOKENS.projectIdOf()`
|
|
|
123
123
|
|
|
124
124
|
**Iteration cap:** `_MAX_CASHOUT_ITERATIONS = 20`. Exceeding this reverts with `JBRouterTerminal_CashOutLoopLimit()`.
|
|
125
125
|
|
|
126
|
-
**Slippage:** The `cashOutMinReclaimed` metadata value is applied
|
|
126
|
+
**Slippage:** The `cashOutMinReclaimed` metadata value is applied to the first cashout step. Subsequent steps use proportionally scaled slippage protection based on the first step's ratio. The final output amount is also validated by the destination terminal's `minReturnedTokens` parameter.
|
|
127
127
|
|
|
128
128
|
**Circular dependency:** If token A cashes out to token B and token B cashes out to token A, the loop hits the 20-iteration cap and reverts cleanly (no fund loss, only gas wasted).
|
|
129
129
|
|
|
@@ -187,7 +187,7 @@ The most complex and highest-value code path. Follow a payment from `pay()` thro
|
|
|
187
187
|
7. `_beforeTransferFor()` -- allowance setup before forwarding
|
|
188
188
|
8. `destTerminal.pay()` -- final forwarding
|
|
189
189
|
|
|
190
|
-
**Key question:** Can any combination of inputs cause tokens to be stuck in the router? The contract has no sweep/rescue function
|
|
190
|
+
**Key question:** Can any combination of inputs cause tokens to be stuck in the router? The contract has no sweep/rescue function. This is intentional — the router is stateless by design. After each swap, the full remaining input token balance is refunded to the caller. If tokens are accidentally sent to the contract (e.g., via `receive()` or direct ERC-20 transfers), they are absorbed into the next caller's refund. This is a deliberate design choice: recovering accidentally-sent funds is preferable to locking them permanently, and there should never be a persistent balance to protect.
|
|
191
191
|
|
|
192
192
|
### Callback Verification
|
|
193
193
|
|
|
@@ -298,7 +298,7 @@ No prior formal audit with finding IDs has been conducted on this codebase. All
|
|
|
298
298
|
|
|
299
299
|
| Pattern | Where to Look | Why It's Dangerous |
|
|
300
300
|
|---------|--------------|-------------------|
|
|
301
|
-
| V4 spot
|
|
301
|
+
| V4 oracle-then-spot fallback | `_getV4Quote()` | V4 pools attempt a 30-second TWAP via the oracle hook first. If unavailable, the spot price fallback is manipulable within a block. The sigmoid slippage mitigates but doesn't eliminate. |
|
|
302
302
|
| Silent TWAP window degradation | `_getV3TwapQuote()` | If `oldestObservation < twapWindow`, the window is silently capped. A 10-second observation produces a near-spot quote labeled as "TWAP." |
|
|
303
303
|
| Partial swap leftover refund | `_handleSwap()` | Leftover tokens are refunded to `_msgSender()`. If the caller is a contract, the refund must be receivable. Verify ETH refund doesn't fail silently. |
|
|
304
304
|
| Stateless design assumption | All of `JBRouterTerminal` | No persistent balances. If any code path fails to forward or refund tokens, they're stuck permanently. No sweep function exists. |
|
package/CHANGE_LOG.md
CHANGED
|
@@ -83,7 +83,7 @@ New V4-specific components:
|
|
|
83
83
|
- `IPoolManager POOL_MANAGER` immutable (can be `address(0)` if V4 is unavailable).
|
|
84
84
|
- `IUnlockCallback` interface implemented via `unlockCallback()`.
|
|
85
85
|
- `_executeV4Swap()`, `_settleV4()`, `_takeV4()`, `_discoverV4Pool()` internal functions.
|
|
86
|
-
- `
|
|
86
|
+
- `_getV4Quote()` — first attempts a 30-second TWAP from the pool's oracle hook (e.g., `IGeomeanOracle.observe()`); falls back to instantaneous spot price if no oracle hook exists or the call fails. Both paths apply sigmoid slippage (security note: spot fallback is not MEV-resistant; users should provide `quoteForSwap` metadata).
|
|
87
87
|
- `_V4_FEES` and `_V4_TICK_SPACINGS` arrays for vanilla V4 pool search.
|
|
88
88
|
|
|
89
89
|
### 2.2 Automatic Pool Discovery
|
|
@@ -289,7 +289,7 @@ v5 contained both `JBSwapTerminal.sol` and `JBSwapTerminal5_1.sol` (a minor revi
|
|
|
289
289
|
|
|
290
290
|
### 6.14 `_pickPoolAndQuote` Redesigned
|
|
291
291
|
- **v5:** Looked up stored pools from `_poolFor` mappings. If no user quote was provided, used project-specific TWAP windows with fallback to slot0 for pools with no observations.
|
|
292
|
-
- **v6:** Auto-discovers pools via `_discoverPool()`. If no user quote is provided, dispatches to `_getV3TwapQuote()` (for V3 pools, using a fixed 10-minute TWAP window) or `
|
|
292
|
+
- **v6:** Auto-discovers pools via `_discoverPool()`. If no user quote is provided, dispatches to `_getV3TwapQuote()` (for V3 pools, using a fixed 10-minute TWAP window) or `_getV4Quote()` (for V4 pools, attempting oracle TWAP first then falling back to spot price). Reverts with `JBRouterTerminal_NoPoolFound` if no pool exists (v5 reverted with `JBSwapTerminal_NoDefaultPoolDefined`).
|
|
293
293
|
|
|
294
294
|
### 6.15 New Metadata Keys
|
|
295
295
|
- `cashOutSource` — specifies a source project ID and credit amount for credit-based cashouts.
|
package/README.md
CHANGED
|
@@ -192,7 +192,7 @@ routerTerminal.pay(projectId, usdc, 1000e6, beneficiary, 0, "swap with quote", m
|
|
|
192
192
|
|
|
193
193
|
If no `quoteForSwap` is provided, the terminal calculates one automatically:
|
|
194
194
|
- **V3 pools**: TWAP oracle with a configurable window (default 10 minutes, capped by oldest observation). Reverts if no observation history exists.
|
|
195
|
-
- **V4 pools**:
|
|
195
|
+
- **V4 pools**: The terminal first attempts a 30-second TWAP via the pool's oracle hook. If no oracle hook exists or the call fails, it falls back to the instantaneous spot tick. Both use the sigmoid slippage formula.
|
|
196
196
|
- **Both**: Dynamic sigmoid slippage tolerance based on estimated price impact and pool fee. Range: 2% minimum to 88% maximum ceiling.
|
|
197
197
|
|
|
198
198
|
## Supported Chains
|
|
@@ -219,7 +219,7 @@ Each chain is configured with the appropriate WETH, Uniswap V3 Factory, and V4 P
|
|
|
219
219
|
- The terminal never holds a token balance between transactions. After every swap, all output tokens are forwarded to the destination terminal, and leftover input tokens from partial fills are returned to the payer.
|
|
220
220
|
- Pool discovery is dynamic -- the terminal searches V3 and V4 pools at runtime. If pool liquidity changes between discovery and execution, slippage protection prevents excessive losses.
|
|
221
221
|
- The `receive()` function accepts ETH from any sender. This is required because ETH arrives from multiple sources: WETH unwraps, cash out reclaims from project terminals, and V4 PoolManager takes. The terminal processes all received ETH within the same transaction.
|
|
222
|
-
- TWAP fallback: V3 pools with no TWAP observation history (`oldestObservation == 0`) will cause the transaction to revert with `JBRouterTerminal_NoObservationHistory()`. V4
|
|
222
|
+
- TWAP fallback: V3 pools with no TWAP observation history (`oldestObservation == 0`) will cause the transaction to revert with `JBRouterTerminal_NoObservationHistory()`. V4 attempts a TWAP via the pool's oracle hook first, falling back to spot price if unavailable.
|
|
223
223
|
- Uniswap V4 requires `cancun` EVM version (transient storage opcodes). On chains without EIP-1153 support, the terminal falls back to V3-only routing.
|
|
224
224
|
- Credit cashouts require the payer to grant `TRANSFER_CREDITS` permission (ID 13) to the router terminal address. Without this, credit-based routing will revert.
|
|
225
225
|
- The `_cashOutLoop` recursively cashes out JB project tokens. Deeply nested project token chains (project A's token backed by project B's token backed by project C's token, etc.) will consume more gas per level of recursion.
|
package/RISKS.md
CHANGED
|
@@ -11,10 +11,10 @@
|
|
|
11
11
|
|
|
12
12
|
## 2. Economic / Manipulation Risks
|
|
13
13
|
|
|
14
|
-
- **V4
|
|
14
|
+
- **V4 price manipulation.** `_getV4Quote` first attempts a 30-second TWAP from the pool's oracle hook (e.g., `IGeomeanOracle.observe()`). If no oracle hook exists or the call fails, it falls back to the instantaneous `getSlot0` tick, which is manipulable via sandwich attacks or flash loans. The sigmoid slippage formula provides a floor (min 2%) but does NOT provide full MEV protection. Without user-supplied `quoteForSwap` metadata, V4 swaps using the spot fallback are vulnerable to extraction. Front-ends MUST supply `quoteForSwap` metadata for V4 swaps without oracle hooks. Note: `_getV4Quote` normalizes WETH to `address(0)` before calling OracleLibrary, since V4 uses `address(0)` for native ETH -- without this normalization, token sorting would mismatch the pool's currency ordering and produce inverted quotes.
|
|
15
15
|
- **V3 TWAP manipulation.** Short TWAP windows (falls back to `oldestObservation` if < 10 minutes) reduce manipulation resistance. A newly created pool with minimal history can be manipulated within the TWAP window.
|
|
16
|
-
- **Cashout loop value extraction.** `_cashOutLoop` iterates up to 20 times, cashing out JB project tokens recursively. Each cashout incurs bonding curve slippage. `minTokensReclaimed` is
|
|
17
|
-
- **Leftover token
|
|
16
|
+
- **Cashout loop value extraction.** `_cashOutLoop` iterates up to 20 times, cashing out JB project tokens recursively. Each cashout incurs bonding curve slippage. `minTokensReclaimed` is applied to the first step, and subsequent steps use proportionally scaled slippage protection. Gas cost: each cashout iteration involves `terminal.cashOutTokensOf` (external call, ~100-200k gas) plus token transfer and balance accounting. At 20 iterations maximum, the worst case is ~4M gas for the loop alone, leaving headroom within a 30M block but consuming a significant portion.
|
|
17
|
+
- **Leftover token handling.** `_handleSwap` refunds the full remaining input token balance after a swap. The router is stateless and should never hold funds between transactions. If tokens are accidentally sent to the contract, they are absorbed into the next caller's refund rather than being permanently stuck — this is intentional, as recovering stuck funds is preferable to locking them forever. There is no sweep mechanism because there should be no persistent balance to sweep.
|
|
18
18
|
- **V4 native ETH settlement.** `_settleV4` unwraps WETH to native ETH when settling a `Currency.wrap(address(0))` debt with PoolManager. This is necessary because the router may hold WETH (from ERC-20 transfers or prior wrapping) but V4 native pools require `msg.value` settlement. If `address(this).balance` is already sufficient, no unwrap occurs.
|
|
19
19
|
- **Pool selection by liquidity.** `_discoverPool` selects the pool with the highest `liquidity()` value. An attacker can deploy a pool with high but concentrated (out-of-range) liquidity to win selection, then manipulate the actual swap execution at worse prices.
|
|
20
20
|
|
|
@@ -46,12 +46,12 @@
|
|
|
46
46
|
- **Registry default terminal change.** Projects without explicit terminal assignments use `defaultTerminal`. If the registry owner changes the default, all unlocked projects are silently migrated. `lockTerminalFor` mitigates this.
|
|
47
47
|
- **safeIncreaseAllowance for terminal transfers.** `_beforeTransferFor` uses `safeIncreaseAllowance` which adds to existing allowance. If previous transactions left stale allowance, the cumulative allowance could exceed intended amounts.
|
|
48
48
|
- **Callback data trust.** `uniswapV3SwapCallback` validates the caller by reconstructing the pool address from `(tokenIn, tokenOut, fee)`. The factory `getPool` lookup makes spoofing infeasible in practice.
|
|
49
|
-
- **receive() function.** The contract accepts arbitrary ETH via `receive()`. This ETH is absorbed into the next swap
|
|
49
|
+
- **receive() function.** The contract accepts arbitrary ETH via `receive()`. This is necessary for WETH unwraps, cashout reclaims, and V4 PoolManager takes. Any ETH received is absorbed into the next swap's leftover refund. Since the router is stateless by design, this is acceptable — funds should not persist between transactions, and recovering accidentally-sent ETH is preferable to locking it permanently.
|
|
50
50
|
|
|
51
51
|
## 6. MEV Surface
|
|
52
52
|
|
|
53
53
|
- **V3 path: TWAP-protected.** The 10-minute TWAP oracle makes single-block manipulation futile. Multi-block attacks require sustained capital.
|
|
54
|
-
- **V4 path: spot-
|
|
54
|
+
- **V4 path: TWAP-first, spot-fallback.** V4 pools attempt a 30-second TWAP via the oracle hook first. If unavailable, the spot fallback is vulnerable. Without `quoteForSwap` metadata, V4 swaps using the spot fallback are exposed to up to sigmoid-slippage% loss per trade. The 2% floor bounds worst-case extraction.
|
|
55
55
|
- **Cross-route arbitrage.** When JB routing bypasses the AMM (minting tokens directly), an arbitrage opportunity exists between the JB bonding curve price and the AMM price.
|
|
56
56
|
|
|
57
57
|
## 7. Invariants to Verify
|
|
@@ -80,6 +80,6 @@ Verified in `RouterTerminalReentrancy.t.sol`: re-entrant calls via both `pay()`
|
|
|
80
80
|
|
|
81
81
|
`_resolveRefundWithBackupRecipient` calls `IJBPayerTracker(msg.sender).originalPayer()` in a try-catch. If the call succeeds and returns a non-zero address, leftover tokens from partial swap fills are sent to that address instead of the beneficiary or `_msgSender()`. The router does not verify that `msg.sender` is the registry or any specific contract -- it trusts any caller that implements the interface. This is accepted because: (1) the caller (`msg.sender`) is the entity that supplied the funds, so redirecting its own leftovers is a legitimate operation, (2) if the call reverts or returns `address(0)`, the router falls back to the normal beneficiary/`_msgSender()` logic, and (3) decoupling from the registry allows other intermediary contracts (e.g. batch payers, aggregators) to participate in refund routing without requiring changes to the router terminal.
|
|
82
82
|
|
|
83
|
-
### 8.3 Cashout loop slippage
|
|
83
|
+
### 8.3 Cashout loop slippage uses proportional scaling
|
|
84
84
|
|
|
85
|
-
`_cashOutLoop` applies `minTokensReclaimed`
|
|
85
|
+
`_cashOutLoop` applies `minTokensReclaimed` to the first cashout step. Subsequent recursive cashouts (steps 2-20) use proportionally scaled slippage protection based on the first step's ratio. This ensures intermediate hops have meaningful slippage bounds without requiring the caller to predict exact intermediate amounts. The final output is also validated by the destination terminal's `minReturnedTokens` parameter.
|
package/SKILLS.md
CHANGED
|
@@ -195,7 +195,7 @@ The router uses `_route` (mutative) and `_previewRoute` (view) as the top-level
|
|
|
195
195
|
- When `tokenIn == NATIVE_TOKEN`, the terminal wraps ETH to WETH before swapping. When the output is `NATIVE_TOKEN`, it unwraps WETH after swapping.
|
|
196
196
|
- The `receive()` function accepts ETH from any sender. This is necessary because ETH arrives from WETH unwraps, cashout reclaims from project terminals, and V4 PoolManager takes. The terminal handles all ETH within the same transaction.
|
|
197
197
|
- **V3 TWAP**: Reverts with `JBRouterTerminal_NoObservationHistory()` when a V3 pool has no observation history, or with `JBRouterTerminal_InsufficientTwapHistory()` when the oldest observation is less than `MIN_TWAP_WINDOW` (120 seconds). The TWAP window is capped by the pool's oldest observation if shorter than 10 minutes.
|
|
198
|
-
- **V4
|
|
198
|
+
- **V4 price**: V4 pools: the terminal first attempts to read a 30-second TWAP from the pool's oracle hook (e.g., `IGeomeanOracle.observe()`). If no oracle hook exists or the call fails, it falls back to the instantaneous spot tick. Both use the sigmoid slippage formula.
|
|
199
199
|
- **V4 requires cancun EVM**: Chains without EIP-1153 (transient storage) cannot use V4 routing. If `POOL_MANAGER` is `address(0)`, V4 discovery is skipped entirely.
|
|
200
200
|
- **Preview estimates**: `previewPayFor()` returns exact values for direct and wrap-unwrap routes, and best-effort estimates for swap routes using current pool state or caller-provided quotes.
|
|
201
201
|
- The `JBRouterTerminalRegistry` handles token custody during delegation -- it transfers tokens from the payer to itself, then approves and forwards to the underlying terminal.
|
|
@@ -206,7 +206,7 @@ The router uses `_route` (mutative) and `_previewRoute` (view) as the top-level
|
|
|
206
206
|
- **Credit cashouts**: When using `cashOutSource` metadata, the payer must have granted `TRANSFER_CREDITS` permission (ID 13) to the router terminal for the source project. The router calls `TOKENS.transferCreditsFrom()` to pull credits.
|
|
207
207
|
- **Cashout loop depth**: The `_cashOutLoop` iterates through JB project token chains with a cap of 20 iterations (`_MAX_CASHOUT_ITERATIONS`). Exceeding this limit reverts with `JBRouterTerminal_CashOutLoopLimit()`.
|
|
208
208
|
- **V3 callback verification**: The `uniswapV3SwapCallback` verifies the caller by reading the pool's `fee()` and checking `FACTORY.getPool()`. This is standard V3 security.
|
|
209
|
-
- **V4 amount overflow**: Both `_getV3TwapQuote` and `
|
|
209
|
+
- **V4 amount overflow**: Both `_getV3TwapQuote` and `_getV4Quote` revert if `amount > type(uint128).max` because `OracleLibrary.getQuoteAtTick` requires `uint128`.
|
|
210
210
|
- **Disallowing the default terminal**: `disallowTerminal()` clears `defaultTerminal` if it matches the terminal being disallowed.
|
|
211
211
|
- **Locking snapshots default**: `lockTerminalFor(projectId, expectedTerminal)` snapshots the current `defaultTerminal` into `_terminalOf[projectId]` if no explicit terminal was set, preventing future default changes from affecting locked projects. The `expectedTerminal` parameter prevents race conditions where the default changes between transaction submission and execution.
|
|
212
212
|
- **Cashout loop limit**: `_cashOutLoop` is capped at 20 iterations. Circular JB token dependencies (A -> B -> A) will revert with `CashOutLoopLimit` instead of consuming all gas.
|
package/package.json
CHANGED
package/script/Deploy.s.sol
CHANGED
|
@@ -62,32 +62,38 @@ contract DeployScript is Script, Sphinx {
|
|
|
62
62
|
} else if (block.chainid == 10) {
|
|
63
63
|
weth = 0x4200000000000000000000000000000000000006;
|
|
64
64
|
factory = 0x1F98431c8aD98523631AE4a59f267346ea31F984;
|
|
65
|
-
|
|
65
|
+
// https://docs.uniswap.org/contracts/v4/deployments
|
|
66
|
+
poolManager = 0x9a13F98Cb987694C9F086b1F5eB990EeA8264Ec3;
|
|
66
67
|
// Base Mainnet
|
|
67
68
|
} else if (block.chainid == 8453) {
|
|
68
69
|
weth = 0x4200000000000000000000000000000000000006;
|
|
69
70
|
factory = 0x33128a8fC17869897dcE68Ed026d694621f6FDfD;
|
|
70
|
-
|
|
71
|
+
// https://docs.uniswap.org/contracts/v4/deployments
|
|
72
|
+
poolManager = 0x498581fF718922c3f8e6A244956aF099B2652b2b;
|
|
71
73
|
// Optimism Sepolia
|
|
72
74
|
} else if (block.chainid == 11_155_420) {
|
|
73
75
|
weth = 0x4200000000000000000000000000000000000006;
|
|
74
76
|
factory = 0x4752ba5DBc23f44D87826276BF6Fd6b1C372aD24;
|
|
75
|
-
|
|
77
|
+
// https://docs.uniswap.org/contracts/v4/deployments
|
|
78
|
+
poolManager = 0x1390B1276c3C0dd59E0e666d4cF97e30267E72E0;
|
|
76
79
|
// BASE Sepolia
|
|
77
80
|
} else if (block.chainid == 84_532) {
|
|
78
81
|
weth = 0x4200000000000000000000000000000000000006;
|
|
79
82
|
factory = 0x4752ba5DBc23f44D87826276BF6Fd6b1C372aD24;
|
|
80
|
-
|
|
83
|
+
// https://docs.uniswap.org/contracts/v4/deployments
|
|
84
|
+
poolManager = 0x05E73354cFDd6745C338b50BcFDfA3Aa6fA03408;
|
|
81
85
|
// Arbitrum Mainnet
|
|
82
86
|
} else if (block.chainid == 42_161) {
|
|
83
87
|
weth = 0x82aF49447D8a07e3bd95BD0d56f35241523fBab1;
|
|
84
88
|
factory = 0x1F98431c8aD98523631AE4a59f267346ea31F984;
|
|
85
|
-
|
|
89
|
+
// https://docs.uniswap.org/contracts/v4/deployments
|
|
90
|
+
poolManager = 0x360E68faCcca8cA495c1B759Fd9EEe466db9FB32;
|
|
86
91
|
// Arbitrum Sepolia
|
|
87
92
|
} else if (block.chainid == 421_614) {
|
|
88
93
|
weth = 0x980B62Da83eFf3D4576C647993b0c1D7faf17c73;
|
|
89
94
|
factory = 0x248AB79Bbb9bC29bB72f7Cd42F17e054Fc40188e;
|
|
90
|
-
|
|
95
|
+
// https://docs.uniswap.org/contracts/v4/deployments
|
|
96
|
+
poolManager = 0xFB3e0C6F74eB1a21CC1Da29aeC80D2Dfe6C9a317;
|
|
91
97
|
} else {
|
|
92
98
|
revert("Invalid RPC / no juice contracts deployed on this network");
|
|
93
99
|
}
|
|
@@ -108,7 +114,6 @@ contract DeployScript is Script, Sphinx {
|
|
|
108
114
|
JBRouterTerminal terminal = new JBRouterTerminal{salt: ROUTER_TERMINAL}({
|
|
109
115
|
directory: core.directory,
|
|
110
116
|
permissions: core.permissions,
|
|
111
|
-
projects: core.projects,
|
|
112
117
|
tokens: core.tokens,
|
|
113
118
|
permit2: IPermit2(permit2),
|
|
114
119
|
owner: safeAddress(),
|