Skip to main content

Harbor Swap

Status: Library live on main; Velora primary aggregator on open PR velora-swap (#3)
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
maindefaultRegistry + UniV3 / Curve / Balancer / FxSave↔wstETH executors; SwapExecutorBase hardening; minAmountOutPerUnitIn rate floor (#2, #4 merged)
velora-swap / #3openVelora Augustus v6.2 as primary aggregator adapter; 1inch remains optional
refund-handlingmerged → mainRefund / amount-spent pro-rating on executor envelope
swap-executor-hardeningmerged → mainShared SwapExecutorBase (exact-pull, ZeroAmountOut, refunds)
swap-adapterolder branchHistorical adapter work

Source docs on the PR branch: src/swap/README.md, script/DEPLOY_SWAP.md.

Architecture

FieldValue
RegistrySwapper_v1(from, to) → {executor, routeCostRatio}
Direct executorsUniV3, Curve, Balancer V2, FxSaveWstEthSwapper_v1 (composite)
AggregatorsVeloraSwapper_v1 (primary, PR #3); OneInchSwapper_v1 (optional)
Shared envelopeSwapExecutorBase — same-token guard, exact pull, amountOut == 0 reverts, authoritative minAmountOutPerUnitIn (out per 1e18 in spent), 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 envelope: minAmountOutPerUnitInrate floor (out per 1e18 in spent)
AggregatorDiscretionary (redistribute)Consumer-provided absolute minAmountOut (or equivalent) on the Yield/redistribute call; 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. Rely on the direct executor’s minAmountOutPerUnitIn for registry routes, and on the absolute output minimum for aggregator redistribute paths — do not assume the per-unit rate bound covers both modes.

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/:chainIdveloraSwapper
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 (mainnet fxSAVE ↔ wstETH)

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