Skip to main content

Harbor Swap

Status: Library on main (checked 3 Nov 2026, 00111f3, 29 Sep 2026). Velora landed with #3, merged 28 Sep 2026. No mainnet swapper address is published yet.
Repo: baofinance/harbor-swap
Consumed by: Harbor Yield (and future Harbor products)

Integrator notes (not for mint/redeem): Harbor Swap.

Branch / PR snapshot (audit)​

RefStateWhat it delivers
maindefault (00111f3)Registry; UniV3, Curve, Balancer; fxSAVE composites (wstETH, WBTC, LBTC, EURC); wstETH↔WBTC and wstETH↔LBTC; Velora + optional 1inch; SwapExecutorBase. Empty Base and Robinhood config placeholders
velora-swap / #3merged 28 Sep 2026Velora Augustus v6.2 as primary aggregator; 1inch stays optional
#4 refund-handlingmerged → mainRefund of unspent input. Later commits on main state the floor as a whole-order minAmountOut, pro-rated by the input actually spent
#2 swap-executor-hardeningmerged → mainShared SwapExecutorBase (exact-pull, ZeroAmountOut, refunds)
swap-adapterolder branchHistorical adapter work

Source docs on main: src/swap/README.md, script/DEPLOY_SWAP.md.

Architecture​

FieldValue
RegistrySwapper_v1 — (from, to) → {executor, routeCostRatio}
Direct executorsUniV3, Curve, Balancer V2, FxSaveWstEthSwapper_v1, FxSaveWbtcSwapper_v1, FxSaveLbtcSwapper_v1, FxSaveEurcSwapper_v1, WstEthWbtcSwapper_v1, WstEthLbtcSwapper_v1
AggregatorsVeloraSwapper_v1 (primary, on main); OneInchSwapper_v1 (optional)
Shared envelopeSwapExecutorBase — same-token guard, exact pull, amountOut == 0 reverts, whole-order minAmountOut in toToken units (pro-rated by the fraction of amountIn spent; 0 disables the floor), refund unspent
DeployBaoFactory CREATE3 via Harbor deploy helpers

Architecture diagram​

Direct executors for compound. Aggregator path for redistribute.

Architecture diagram (Mermaid)​

Two execution modes​

ModeTypical callerSlippage / floor
DirectHot path (HarborYield.compound)Executor swap(..., minAmountOut) — whole-order floor in toToken units, pro-rated by input spent
AggregatorDiscretionary (redistribute)Same whole-order minAmountOut on IAggregatorSwapper.swap, plus opaque routerData to Velora / 1inch

Authorization for aggregators lives on the consumer (Harbor Yield), not inside the open-access adapter. Selector allowlists do not validate swap parameters — treat calldata as untrusted. Both modes use that whole-order floor. A partial fill must meet the same price as the full order, because the executor scales the floor by the fraction of amountIn it actually spent.

Velora (primary)​

FieldValue
WhyFixed-router aggregator for low-urgency rebalances; public Market API without 1inch KYC
RouterAugustus v6.2 (same address pattern across supported chains)
Keeper flowGET /prices (version=6.2, allowlisted methods) → POST /transactions/:chainId → veloraSwapper
SelectorsAllowlisted in VeloraV62Selectors (e.g. swapExactAmountIn / swapExactAmountOut)
Addresses in quoteuserAddress = adapter proxy; txOrigin = redistributor EOA (or Safe, not the relayer)

1inch (optional)​

FieldValue
WhenPrefer 1inch path or Velora unavailable
APISwap / Pathfinder (swap selector); typically needs 1inch developer KYC
AdapterOneInchSwapper_v1 on the same SwapExecutorBase

CREATE3 salt keys (peg-agnostic)​

Full salt = {saltPrefix}::{key} (e.g. harbor_v1::eth::swapper). Predict with _predictAddress before deploy.

KeyContract
swapperSwapper_v1
uniV3SwapperUniV3Swapper_v1
curveSwapperCurveSwapper_v1
balancerSwapperBalancerSwapper_v1
veloraSwapperVeloraSwapper_v1
oneInchSwapperOneInchSwapper_v1
fxSaveWstEthSwapperFxSaveWstEthSwapper_v1 (fxSAVE ↔ wstETH)
fxSaveWbtcSwapperFxSaveWbtcSwapper_v1 (fxSAVE ↔ WBTC)
fxSaveLbtcSwapperFxSaveLbtcSwapper_v1 (fxSAVE ↔ LBTC)
fxSaveEurcSwapperFxSaveEurcSwapper_v1
wstEthWbtcSwapperWstEthWbtcSwapper_v1
wstEthLbtcSwapperWstEthLbtcSwapper_v1

Per-peg Harbor Yield salts ({pegKey}::harborYield, beacons, …) live in the yield consumer deploy config — not in this registry table.

Deploy phases​

PhaseRepoDelivers (swap-relevant)
1aharbor #33Minter_v3, StabilityPool_v3, StabilityPoolManager_v2
1bharbor-price-aggregators #4Yield peg oracles (CREATE3)
2aharbor-swapThis package — registry + executors + aggregators
2bHarbor Yield consumerHarborYield_v1, Compounder_v1, ERC-7575 doors, route wiring, REDISTRIBUTOR_ROLE

Harbor Yield passes swapper = _predictAddress("swapper") as an immutable at HY deploy time.

Known design tradeoffs​

TopicNote
FxSaveWstEth intermediate legsSome Curve hops use min_dy = 0; only final wstETH out is bounded by consumer minAmountOut. Route changes need impl upgrade.
Aggregator opennessAdapters are callable; safety is consumer role + envelope + minAmountOut.
Mainnet disciplineDeploy only via package deploy helpers; do not hard-code proxy addresses — use CREATE3 prediction.

See also​

ResourceUse for
Harbor YieldConsumer stack / phases
Harbor Yield (product)Velora vs 1inch in product language
Supporting FeaturesOracles + zaps vs yield plumbing
Coverage auditOpen PR checklist
Bao FactoryCREATE3 deployer