--- name: soulzap-hydrex description: Adds Hydrex support to a SoulZap integration - entering any Hydrex strategy on Base with a single token and staking it into its gauge in the same transaction. Use this whenever the task involves a Hydrex strategy deposit, a Hydrex gauge stake, or a one-click deposit button for Hydrex classic, Integral, uniV4, or Morpho and Euler lending pools. Companion to soulzap-integration.txt, which must be read first. --- # Hydrex with the SoulZap API > **Read `soulzap-integration.txt` first** - it carries the flow, the rules and every `lpData` > variant. This file only adds what is specific to Hydrex. Hydrex is on **Base** only - send `"chain": "base"` (or `8453`). The protocol step here is gauge staking: one transaction takes the user's token, builds the LP or vault share, and stakes it. Leave `protocolData` out and the LP token lands in their wallet instead. ## Where the pools come from ``` GET https://api.hydrex.fi/strategies -> [ ... ] ``` Never hardcode a pool address - strategies are gauged and un-gauged continually. Map each entry's `liquidityType` onto an `lpType`, and take the address from the field named below: | `liquidityType` | `lpType` | Seed address | |---|---|---| | `classic-volatile`, `classic-stable` | `solidly` | `address` -> `lpAddress` | | `integral` | `ichi` | `address` -> `lpAddress` | | `uniV4` | `gamma` | `address` -> `lpAddress` | | `integral-manual` | `algebra` | `address` -> `pool` | | `morpho`, `euler` | `single` | `depositToken` -> `toToken` | `gauge.address` is the gauge, when the strategy has one. Two entries to handle carefully: - **`rwa-integral` is not zappable.** It is an Algebra ALM vault (`pcALM`) that no `lpType` mints. Filter it out. - **Lending strategies (`morpho`, `euler`) seed from `depositToken`, not `address`.** Their gauge sets its stake token to the ERC-4626 vault's *underlying* and does the vault deposit itself, so the zap only has to deliver that token. The strategy's `address` is the vault, which the zap never touches. Minting vault shares first produces a token the gauge will not accept. ## Fixed addresses These are Hydrex's own deployments on Base. Use them; do not read them from a request or guess. | Used by | Field | Address | |---|---|---| | `solidly` | `router` | `0x8fB6177eb7AC7D9e75DE2D58D8749755D6BD9EA1` | | `algebra` | `positionManager` | `0xC63E9672f8e93234C73cE954a1d1292e4103Ab86` | `gamma` and `ichi` need nothing beyond `lpAddress`. The API reads Gamma's `uniProxy` off the hypervisor and ICHI's deposit guard off the vault's factory, and Hydrex's ICHI deployment is one it knows. Send `uniProxy`, or `depositGuard` and `vaultDeployer`, only to override that. ## `protocolData` - staking into the gauge ```json { "protocol": "Hydrex", "gauge": "0x..." } ``` Rules: - Valid with `solidly`, `ichi`, `gamma` and `single`. - **Never with `algebra`.** Manual Integral positions have no gauge to enter - their gauge stakes the raw pool, which is not a token, so the request is rejected. They earn through reward campaigns instead, so zap them as a plain LP with no protocol step. - **Skip the step when `gauge.address` is missing or all-zero.** Staking nothing fails the whole transaction. - Omit `protocolData` entirely to leave the LP token in the user's wallet. Unlike a Lynex gauge, a Hydrex stake is an internal balance rather than a receipt token, so nothing comes back to the wallet - do not expect a staking token in the outputs. ## Worked example - 10 USDC into a classic pool, staked Only the request objects; approve and zap exactly as the base guide does. ```ts const strategy = strategies.find(s => s.address === selected) const lpData = { lpType: 'solidly', // classic-volatile fromToken: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913', // USDC on Base fromAmount: '10000000', // 10 USDC, 6 decimals lpAddress: strategy.address, router: '0x8fB6177eb7AC7D9e75DE2D58D8749755D6BD9EA1', slippage: 1, } const gauge = strategy.gauge?.address const stakeable = gauge && !/^0x0{40}$/i.test(gauge) const protocolData = stakeable ? { protocol: 'Hydrex', gauge } : undefined // omit the key entirely if unstaked ``` ## Per-type notes **`solidly`**, **`ichi`**, **`gamma`** - `lpAddress` is the strategy's `address` and nothing else is needed beyond the fixed `router` for `solidly`. **`algebra`** - the strategy's `address` is the `pool`, not an `lpAddress`. Ticks are yours to choose; no `protocolData`, ever. **`single`** - `toToken` is the strategy's `depositToken`. This is the one type where the strategy's own `address` is the wrong value to use. ## Errors you will hit here | Message | Fix | |---|---| | `Gauge ... stakes ..., not ...` | The gauge takes a different token than this `lpData` produces. On `algebra` it always will - drop `protocolData`. | | `Multicall: Something went wrong` | Usually a stale strategy address, or an `rwa-integral` entry that slipped through the filter. |