feat(range-pool): add Range Pool executor adapter - #10
Open
alf1303 wants to merge 2 commits into
Open
Conversation
On-chain settlement for Range Pools, a concentrated-liquidity Balancer-V3-shaped DEX on a custom, non-canonical Balancer V3 Vault (0x955244EDC797A1C1b04134b600f819aC23C76081). executeRangePool performs the swap Vault-direct via unlock -> swap(EXACT_IN) -> settle(tokenIn) -> sendTo(tokenOut, recipient), with a Vault-guarded unlock callback. No Router, no Permit2. Native ETH is wrapped/unwrapped at the edges since the Vault only handles WETH. Foundry mainnet-fork parity: realized output == Router.querySwapSingleTokenExactIn to the wei on both live pools, plus native-ETH in/out and the OnlyVault / minimum-trade guards.
There was a problem hiding this comment.
Pull request overview
Adds a new KyberSwap executor adapter to support Range Pools (a Balancer-V3-shaped DEX) via the custom Range Vault’s unlock → swap → settle/sendTo transient-accounting flow, plus mainnet-fork parity tests against the Range Router quote function.
Changes:
- Introduces
RangePoolAdapterthat executes EXACT_IN swaps via the Range Vault, including native-ETH wrapping/unwrapping support. - Vendors minimal interfaces for the Range Vault and WETH used by the adapter.
- Adds Foundry mainnet-fork parity + guard/symmetry tests for the adapter against live pools.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
src/adapters/range-pool/RangePoolAdapter.sol |
New executor adapter implementing Vault-direct swap settlement + native ETH edge handling. |
src/adapters/range-pool/IRangeVault.sol |
Minimal vendored Vault interface + swap types used by adapter/tests. |
src/adapters/range-pool/IWETH.sol |
Minimal WETH interface for deposit/withdraw bridging. |
test/adapters/range-pool/RangePoolAdapter.t.sol |
Mainnet-fork parity tests vs router quote, native in/out cases, and guard/error symmetry checks. |
Suppressed comments (2)
src/adapters/range-pool/RangePoolAdapter.sol:101
rangePoolUnlockCallbackunwraps WETH and performs a native ETH transfer torecipientwhile still inside the Vaultunlockcallback. This is an external call to an untrusted address during the Vault’s transient-accounting context and can enable reentrancy into the wider system while the Vault is unlocked. Prefer keeping the callback limited to Vault/token interactions and defer the WETH->ETH unwrap + native transfer until afterunlockreturns (inexecuteRangePool).
if (nativeOut) {
IRangeVault(VAULT).sendTo(IERC20(WETH), address(this), amountOut);
IWETH(WETH).withdraw(amountOut);
recipient.safeTransferNative(amountOut);
} else {
src/adapters/range-pool/RangePoolAdapter.sol:51
executeRangePooldoesn’t validatemsg.valuevsamountIn/tokenIn. IftokenInis ERC20 butmsg.value > 0(or if native-in andmsg.value != amountIn), ETH can be unintentionally trapped in the adapter or the call can behave inconsistently. Also, if native-out unwrapping is deferred out of the Vault callback,executeRangePoolshould perform the WETH withdrawal + native transfer afterunlockreturns.
) external payable returns (uint256 amountUnused, uint256 amountOut) {
address pool = data.decodeAddress(0);
bytes memory result = IRangeVault(VAULT)
.unlock(
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
_sweep requires at least 2 wei-parity matches; the docstring referenced a nonexistent minHits parameter. Addresses Copilot review comment.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
feat(range-pool): add Range Pool executor adapter
Background
Range Pools are a concentrated-liquidity, Balancer-V3-shaped DEX on Ethereum mainnet, running on a custom, non-canonical Balancer V3 Vault
0x955244EDC797A1C1b04134b600f819aC23C76081. The off-chain pricing connector is a companion PR toKyberNetwork/kyberswap-dex-lib: KyberNetwork/kyberswap-dex-lib#1612.What this adds
src/adapters/range-pool/RangePoolAdapter.sol—executeRangePool(bytes data, uint256 amountIn, address tokenIn, address tokenOut, address recipient).A Balancer-V3 pool has no direct swap entrypoint; swaps go through the Vault's transient-accounting flow. The adapter settles Vault-direct (no Router, no Permit2):
Vault.unlock(callback)swap(EXACT_IN)→ pay input (transfer tokenInto Vault +settle) →sendTo(tokenOut, recipient)amountOutEXACT_IN only (aggregator settlement). Native ETH is wrapped/unwrapped at the edges since the Vault only handles WETH. Vendored minimal interfaces
IRangeVault.sol/IWETH.sol(structs/enums copied verbatim from the Vault source, not guessed).Testing
test/adapters/range-pool/RangePoolAdapter.t.sol— Foundry mainnet-fork parity: for both live pools (ROME/USDT0xaf037e…b36, 8-token0x67c02f…f29b, WETH idx 6), realized output== Router.querySwapSingleTokenExactInto the wei, plus native-ETH in/out, theOnlyVaultcallback guard, and minimum-trade error symmetry.forge build/forge fmtclean.Run:
forge test --match-path 'test/adapters/range-pool/*' --fork-url <mainnet RPC>Note
Funding uses forge-std
deal(self-verifying); no hardcoded holder or committed slot cache.