@bananapus/suckers-v6 0.0.71 → 0.0.73

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.
@@ -1,115 +0,0 @@
1
- // SPDX-License-Identifier: MIT
2
- pragma solidity 0.8.28;
3
-
4
- // External packages (alphabetized).
5
- import {IJBDirectory} from "@bananapus/core-v6/src/interfaces/IJBDirectory.sol";
6
- import {IJBPermissions} from "@bananapus/core-v6/src/interfaces/IJBPermissions.sol";
7
- import {IJBTokens} from "@bananapus/core-v6/src/interfaces/IJBTokens.sol";
8
- import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
9
- import {IPoolManager} from "@uniswap/v4-core/src/interfaces/IPoolManager.sol";
10
- import {IUniswapV3Factory} from "@uniswap/v3-core/contracts/interfaces/IUniswapV3Factory.sol";
11
-
12
- // Local: interfaces.
13
- import {IJBSwapCCIPSuckerDeployer} from "../interfaces/IJBSwapCCIPSuckerDeployer.sol";
14
-
15
- // Local: deployers.
16
- import {JBCCIPSuckerDeployer} from "./JBCCIPSuckerDeployer.sol";
17
-
18
- /// @notice An `IJBSuckerDeployer` implementation to deploy `JBSwapCCIPSucker` contracts.
19
- /// @dev Extends `JBCCIPSuckerDeployer` with Uniswap V3/V4 swap configuration for cross-currency bridging.
20
- contract JBSwapCCIPSuckerDeployer is JBCCIPSuckerDeployer, IJBSwapCCIPSuckerDeployer {
21
- //*********************************************************************//
22
- // --------------------------- custom errors ------------------------- //
23
- //*********************************************************************//
24
-
25
- error JBSwapCCIPSuckerDeployer_InvalidSwapConfig(address bridgeToken);
26
- error JBSwapCCIPSuckerDeployer_SwapAlreadyConfigured(address bridgeToken);
27
-
28
- //*********************************************************************//
29
- // ---------------------- public stored properties ------------------- //
30
- //*********************************************************************//
31
-
32
- /// @notice The ERC-20 token used for CCIP bridging (e.g., USDC).
33
- IERC20 public bridgeToken;
34
-
35
- /// @notice The Uniswap V4 PoolManager. Can be address(0) if V4 is unavailable.
36
- IPoolManager public poolManager;
37
-
38
- /// @notice The Uniswap V3 factory. Can be address(0) if V3 is unavailable.
39
- IUniswapV3Factory public v3Factory;
40
-
41
- /// @notice The Uniswap V4 hook address for pool discovery (optional).
42
- address public univ4Hook;
43
-
44
- /// @notice The ERC-20 wrapper address for the chain's native token (e.g. WETH on Ethereum).
45
- address public wrappedNativeToken;
46
-
47
- //*********************************************************************//
48
- // ---------------------------- constructor -------------------------- //
49
- //*********************************************************************//
50
-
51
- /// @param directory The directory of terminals and controllers for projects.
52
- /// @param permissions The permissions contract for the deployer.
53
- /// @param tokens The contract that manages token minting and burning.
54
- /// @param configurator The address of the configurator.
55
- /// @param trustedForwarder The trusted forwarder for ERC-2771 meta-transactions.
56
- constructor(
57
- IJBDirectory directory,
58
- IJBPermissions permissions,
59
- IJBTokens tokens,
60
- address configurator,
61
- address trustedForwarder
62
- )
63
- JBCCIPSuckerDeployer(directory, permissions, tokens, configurator, trustedForwarder)
64
- {}
65
-
66
- //*********************************************************************//
67
- // --------------------- external transactions ----------------------- //
68
- //*********************************************************************//
69
-
70
- /// @notice Configure the swap-specific constants. Can only be called once by the configurator.
71
- /// @param newBridgeToken The ERC-20 token used for CCIP bridging.
72
- /// @param newPoolManager The Uniswap V4 PoolManager (can be address(0) if V4 unavailable).
73
- /// @param newV3Factory The Uniswap V3 factory (can be address(0) if V3 unavailable).
74
- /// @param newUniv4Hook The V4 hook for pool discovery (optional, address(0) if none).
75
- /// @param newWrappedNativeToken The ERC-20 wrapper address for the chain's native token (e.g. WETH on Ethereum).
76
- function setSwapConstants(
77
- IERC20 newBridgeToken,
78
- IPoolManager newPoolManager,
79
- IUniswapV3Factory newV3Factory,
80
- address newUniv4Hook,
81
- address newWrappedNativeToken
82
- )
83
- external
84
- {
85
- // Make sure the swap configuration has not already been set.
86
- if (address(bridgeToken) != address(0)) {
87
- revert JBSwapCCIPSuckerDeployer_SwapAlreadyConfigured({bridgeToken: address(bridgeToken)});
88
- }
89
-
90
- // Make sure only the configurator can call this function.
91
- if (_msgSender() != LAYER_SPECIFIC_CONFIGURATOR) {
92
- revert JBSuckerDeployer_Unauthorized({caller: _msgSender(), expected: LAYER_SPECIFIC_CONFIGURATOR});
93
- }
94
-
95
- // Make sure the bridge token is not the zero address.
96
- if (address(newBridgeToken) == address(0)) {
97
- revert JBSwapCCIPSuckerDeployer_InvalidSwapConfig({bridgeToken: address(newBridgeToken)});
98
- }
99
-
100
- // Store the bridge token.
101
- bridgeToken = newBridgeToken;
102
-
103
- // Store the Uniswap V4 pool manager.
104
- poolManager = newPoolManager;
105
-
106
- // Store the Uniswap V3 factory.
107
- v3Factory = newV3Factory;
108
-
109
- // Store the Uniswap V4 hook address.
110
- univ4Hook = newUniv4Hook;
111
-
112
- // Store the wrapped native token address.
113
- wrappedNativeToken = newWrappedNativeToken;
114
- }
115
- }
@@ -1,148 +0,0 @@
1
- // SPDX-License-Identifier: MIT
2
- pragma solidity 0.8.28;
3
-
4
- import {Math} from "@openzeppelin/contracts/utils/math/Math.sol";
5
- import {mulDiv} from "@prb/math/src/Common.sol";
6
- import {TickMath} from "@uniswap/v3-core/contracts/libraries/TickMath.sol";
7
-
8
- /// @notice Shared library for slippage tolerance and price limit calculations.
9
- /// @dev Uses continuous sigmoid formula for smooth slippage tolerance across all swap sizes.
10
- library JBSwapLib {
11
- /// @notice The denominator used for slippage tolerance basis points.
12
- uint256 internal constant _SLIPPAGE_DENOMINATOR = 10_000;
13
-
14
- /// @notice The maximum slippage ceiling (88%).
15
- uint256 internal constant _MAX_SLIPPAGE = 8800;
16
-
17
- /// @notice The precision multiplier for impact calculations.
18
- /// @dev Using 1e18 instead of 1e5 gives 13 extra orders of magnitude,
19
- /// preventing small-swap-in-deep-pool impacts from rounding to zero.
20
- uint256 internal constant _IMPACT_PRECISION = 1e18;
21
-
22
- /// @notice The K parameter for the sigmoid curve, scaled to match _IMPACT_PRECISION.
23
- /// @dev K_new = 5000 * 1e18 / 1e5 = 5e16
24
- uint256 internal constant _SIGMOID_K = 5e16;
25
-
26
- //*********************************************************************//
27
- // -------------------- Slippage Tolerance -------------------------- //
28
- //*********************************************************************//
29
-
30
- /// @notice Compute a continuous sigmoid slippage tolerance based on swap impact and pool fee.
31
- /// @dev tolerance = minSlippage + (maxSlippage - minSlippage) * impact / (impact + K)
32
- /// @param impact The estimated price impact from calculateImpact (scaled by _IMPACT_PRECISION).
33
- /// @param poolFeeBps The pool fee in basis points (e.g., 30 for 0.3%).
34
- /// @return tolerance The slippage tolerance in basis points of _SLIPPAGE_DENOMINATOR.
35
- function getSlippageTolerance(uint256 impact, uint256 poolFeeBps) internal pure returns (uint256) {
36
- if (poolFeeBps >= _MAX_SLIPPAGE) return _MAX_SLIPPAGE;
37
-
38
- uint256 minSlippage = poolFeeBps + 100;
39
- if (minSlippage < 200) minSlippage = 200;
40
- if (minSlippage >= _MAX_SLIPPAGE) return _MAX_SLIPPAGE;
41
-
42
- if (impact == 0) return minSlippage;
43
-
44
- if (impact > type(uint256).max - _SIGMOID_K) return _MAX_SLIPPAGE;
45
-
46
- uint256 range = _MAX_SLIPPAGE - minSlippage;
47
- uint256 tolerance = minSlippage + mulDiv({x: range, y: impact, denominator: impact + _SIGMOID_K});
48
-
49
- return tolerance;
50
- }
51
-
52
- //*********************************************************************//
53
- // -------------------- Impact Calculation -------------------------- //
54
- //*********************************************************************//
55
-
56
- /// @notice Estimate the price impact of a swap, scaled by _IMPACT_PRECISION.
57
- /// @param amountIn The amount of tokens to swap in.
58
- /// @param liquidity The pool's in-range liquidity.
59
- /// @param sqrtP The sqrt price in Q96 format.
60
- /// @param zeroForOne Whether the swap is token0 -> token1.
61
- /// @return impact The estimated price impact scaled by _IMPACT_PRECISION.
62
- function calculateImpact(
63
- uint256 amountIn,
64
- uint128 liquidity,
65
- uint160 sqrtP,
66
- bool zeroForOne
67
- )
68
- internal
69
- pure
70
- returns (uint256 impact)
71
- {
72
- if (liquidity == 0 || sqrtP == 0) return 0;
73
-
74
- uint256 base = mulDiv({x: amountIn, y: _IMPACT_PRECISION, denominator: uint256(liquidity)});
75
-
76
- impact = zeroForOne
77
- ? mulDiv({x: base, y: uint256(sqrtP), denominator: uint256(1) << 96})
78
- : mulDiv({x: base, y: uint256(1) << 96, denominator: uint256(sqrtP)});
79
- }
80
-
81
- //*********************************************************************//
82
- // -------------------- Price Limit -------------------------------- //
83
- //*********************************************************************//
84
-
85
- /// @notice Compute a sqrtPriceLimitX96 from input/output amounts so the swap stops
86
- /// if the execution price would be worse than the minimum acceptable rate.
87
- /// @param amountIn The amount of tokens to swap in.
88
- /// @param minimumAmountOut The minimum acceptable output.
89
- /// @param zeroForOne True when selling token0 for token1 (price decreases).
90
- /// @return sqrtPriceLimit The V3-compatible sqrtPriceLimitX96.
91
- function sqrtPriceLimitFromAmounts(
92
- uint256 amountIn,
93
- uint256 minimumAmountOut,
94
- bool zeroForOne
95
- )
96
- internal
97
- pure
98
- returns (uint160 sqrtPriceLimit)
99
- {
100
- if (minimumAmountOut == 0 || amountIn == 0) {
101
- return zeroForOne ? TickMath.MIN_SQRT_RATIO + 1 : TickMath.MAX_SQRT_RATIO - 1;
102
- }
103
-
104
- uint256 num;
105
- uint256 den;
106
- if (zeroForOne) {
107
- num = minimumAmountOut;
108
- den = amountIn;
109
- } else {
110
- num = amountIn;
111
- den = minimumAmountOut;
112
- }
113
-
114
- uint256 sqrtResult;
115
-
116
- if (num / den >= (uint256(1) << 128)) {
117
- return zeroForOne ? TickMath.MIN_SQRT_RATIO + 1 : TickMath.MAX_SQRT_RATIO - 1;
118
- } else if (num / den >= (uint256(1) << 64)) {
119
- uint256 ratioX128 = mulDiv({x: num, y: uint256(1) << 128, denominator: den});
120
- sqrtResult = Math.sqrt(ratioX128) * (uint256(1) << 32);
121
- } else {
122
- uint256 ratioX192 = mulDiv({x: num, y: uint256(1) << 192, denominator: den});
123
- sqrtResult = Math.sqrt(ratioX192);
124
- }
125
-
126
- if (zeroForOne) {
127
- if (sqrtResult <= uint256(TickMath.MIN_SQRT_RATIO)) {
128
- return TickMath.MIN_SQRT_RATIO + 1;
129
- }
130
- if (sqrtResult >= uint256(TickMath.MAX_SQRT_RATIO)) {
131
- return TickMath.MAX_SQRT_RATIO - 1;
132
- }
133
- // The bounds above clamp `sqrtResult` into the uint160 Uniswap sqrt-price domain.
134
- // forge-lint: disable-next-line(unsafe-typecast)
135
- return uint160(sqrtResult);
136
- } else {
137
- if (sqrtResult >= uint256(TickMath.MAX_SQRT_RATIO)) {
138
- return TickMath.MAX_SQRT_RATIO - 1;
139
- }
140
- if (sqrtResult <= uint256(TickMath.MIN_SQRT_RATIO)) {
141
- return TickMath.MIN_SQRT_RATIO + 1;
142
- }
143
- // The bounds above clamp `sqrtResult` into the uint160 Uniswap sqrt-price domain.
144
- // forge-lint: disable-next-line(unsafe-typecast)
145
- return uint160(sqrtResult);
146
- }
147
- }
148
- }