@bananapus/suckers-v6 0.0.41 → 0.0.42
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/foundry.toml +1 -0
- package/package.json +1 -1
- package/src/JBSwapCCIPSucker.sol +8 -0
- package/src/libraries/JBSwapPoolLib.sol +13 -0
package/foundry.toml
CHANGED
package/package.json
CHANGED
package/src/JBSwapCCIPSucker.sol
CHANGED
|
@@ -309,6 +309,14 @@ contract JBSwapCCIPSucker is JBCCIPSucker, IUnlockCallback, IUniswapV3SwapCallba
|
|
|
309
309
|
delivered: deliveredToken, expected: address(BRIDGE_TOKEN)
|
|
310
310
|
});
|
|
311
311
|
}
|
|
312
|
+
// Zero delivery alongside a positive root is structurally indistinguishable from
|
|
313
|
+
// "no delivery + positive root" — both leave the local sucker with nothing to back
|
|
314
|
+
// the leaves the root advertises. Reject so a peer cannot mint a claimable rate
|
|
315
|
+
// that records `leafTotal=N, localTotal=0` and lets later claims withdraw against
|
|
316
|
+
// unrelated balance.
|
|
317
|
+
if (leafTotal > 0 && deliveredAmount == 0) {
|
|
318
|
+
revert JBSwapCCIPSucker_PositiveRootWithoutDelivery(leafTotal);
|
|
319
|
+
}
|
|
312
320
|
}
|
|
313
321
|
}
|
|
314
322
|
|
|
@@ -51,6 +51,7 @@ library JBSwapPoolLib {
|
|
|
51
51
|
error JBSwapPoolLib_InsufficientTwapHistory(address pool, uint256 availableWindow, uint256 requiredWindow);
|
|
52
52
|
error JBSwapPoolLib_NoLiquidity(address pool, PoolId poolId);
|
|
53
53
|
error JBSwapPoolLib_NoPool(address tokenIn, address tokenOut);
|
|
54
|
+
error JBSwapPoolLib_PartialFill(uint256 consumed, uint256 requested);
|
|
54
55
|
error JBSwapPoolLib_SlippageExceeded(uint256 amountOut, uint256 minAmountOut);
|
|
55
56
|
|
|
56
57
|
//*********************************************************************//
|
|
@@ -989,6 +990,18 @@ library JBSwapPoolLib {
|
|
|
989
990
|
data: abi.encode(originalTokenIn, normalizedTokenIn, normalizedTokenOut)
|
|
990
991
|
});
|
|
991
992
|
|
|
993
|
+
// Reject partial fills: when the V3 pool's price limit is hit before the full input is
|
|
994
|
+
// consumed, the pool returns only the consumed portion of `amount` and the caller is left
|
|
995
|
+
// holding the unconsumed remainder. The sucker's accounting assumes the full bridge amount
|
|
996
|
+
// was either swapped or made retryable, so a silent partial fill strands input tokens and
|
|
997
|
+
// breaks cross-chain solvency. Revert so the caller can either retry with a smaller size
|
|
998
|
+
// or wait for liquidity to return.
|
|
999
|
+
// forge-lint: disable-next-line(unsafe-typecast)
|
|
1000
|
+
uint256 consumedAmount = uint256(zeroForOne ? amount0 : amount1);
|
|
1001
|
+
if (consumedAmount < amount) {
|
|
1002
|
+
revert JBSwapPoolLib_PartialFill({consumed: consumedAmount, requested: amount});
|
|
1003
|
+
}
|
|
1004
|
+
|
|
992
1005
|
// Extract the output amount from the signed delta (negative = tokens received).
|
|
993
1006
|
amountOut = uint256(-(zeroForOne ? amount1 : amount0));
|
|
994
1007
|
|