-
Stability pool zap implementation
- Direct wrapped collateral deposits (wstETH/fxSAVE):
zapWstEthToStabilityPool/zapWstEthToStabilityPoolWithPermitzapFxSaveToStabilityPool/zapFxSaveToStabilityPoolWithPermit- Implemented in
AnchorDepositModalandAnchorDepositWithdrawModal
- After swap deposits (ETH/stETH/USDC/fxUSD):
zapEthToStabilityPool(payable, no permit needed)zapStEthToStabilityPool/zapStEthToStabilityPoolWithPermitzapUsdcToStabilityPool/zapUsdcToStabilityPoolWithPermit(withminFxSaveOut)zapFxUsdToStabilityPool/zapFxUsdToStabilityPoolWithPermit(withminFxSaveOut)- Implemented in
AnchorDepositWithdrawModal
- Direct wrapped collateral deposits (wstETH/fxSAVE):
-
Permit/approval toggle
- Defaults to permit (1 transaction)
- Toggle to switch to approval (2 transactions)
- Automatic fallback if permit fails
-
Stability pool selection
- Correctly passes
stabilityPoolAddress(collateral or sail/leveraged) - Works in both permit and approval flows
- Correctly passes
-
MinOut calculations
minPeggedOut=expectedOutput * 99n / 100n(1% slippage)minStabilityPoolOut=expectedOutput * 99n / 100n(same value)minFxSaveOutfor USDC/fxUSD:calculateMinFxSaveOut()helper function inutils/zapCalculations.ts- USDC:
(usdcAmount * 10^12 * 1e18) / fxSAVERate * 99 / 100 - fxUSD:
(fxusdAmount * 1e18) / fxSAVERate * 99 / 100
- USDC:
-
Code quality
- No linter errors
- No TODOs/FIXMEs
- Proper error handling with fallbacks
Before (Traditional Flow):
- Approve wstETH/fxSAVE for minter → 1 transaction
- Mint pegged token → 1 transaction
- Approve pegged token for stability pool → 1 transaction
- Deposit pegged token to stability pool → 1 transaction
- Total: 4 transactions
After (Stability Pool Zap with Permit):
- Sign permit (off-chain, no gas) → 0 transactions
- Zap wstETH/fxSAVE to stability pool (permit) → 1 transaction
- Total: 1 transaction 🎉
After (Stability Pool Zap with Approval):
- Approve wstETH/fxSAVE for zap contract → 1 transaction
- Zap wstETH/fxSAVE to stability pool → 1 transaction
- Total: 2 transactions
- 75% fewer transactions (4 → 1 with permit)
- 50% fewer transactions (4 → 2 with approval)
- Faster deposits - single zap transaction vs multiple approvals
- Lower gas costs - reduced transaction overhead
- User control - toggle between permit and approval methods
- Better reliability - automatic fallback if permit fails
- Reduced complexity - single function call instead of multi-step flow
- Better error handling - automatic fallback mechanisms
- Flexible approval method - user can choose permit or approval
- Proper minOut protection - slippage protection at all stages
- Support for both pool types - collateral and sail/leveraged pools
Traditional Flow (4 transactions):
- Approve collateral: ~46,000 gas
- Mint pegged: ~150,000 gas
- Approve pegged: ~46,000 gas
- Deposit to pool: ~100,000 gas
- Total: ~342,000 gas
Zap with Permit (1 transaction):
- Zap with permit: ~200,000 gas
- Savings: ~142,000 gas (41% reduction)
Zap with Approval (2 transactions):
- Approve: ~46,000 gas
- Zap: ~200,000 gas
- Total: ~246,000 gas
- Savings: ~96,000 gas (28% reduction)
Note: Actual gas costs vary based on network conditions and contract state
✅ wstETH markets (BTC/stETH)
- Direct wstETH stability pool zap:
zapWstEthToStabilityPool/zapWstEthToStabilityPoolWithPermit - After swap (ETH/stETH):
zapEthToStabilityPool/zapStEthToStabilityPool/zapStEthToStabilityPoolWithPermit - Permit and approval flows
✅ fxSAVE markets (ETH/fxUSD, BTC/fxUSD)
- Direct fxSAVE stability pool zap:
zapFxSaveToStabilityPool/zapFxSaveToStabilityPoolWithPermit - After swap (USDC/fxUSD):
zapUsdcToStabilityPool/zapUsdcToStabilityPoolWithPermit/zapFxUsdToStabilityPool/zapFxUsdToStabilityPoolWithPermit - Permit and approval flows
minFxSaveOutcalculation viacalculateMinFxSaveOut()helper
Components:
AnchorDepositModal: Direct wstETH/fxSAVE deposits to stability poolsAnchorDepositWithdrawModal: All deposit paths including:- Direct wstETH/fxSAVE deposits (with stability pool zaps)
- After swap: ETH/stETH/USDC/fxUSD → stability pools (with stability pool zaps)
- Swap-based flow: any token → swap to ETH/USDC → stability pool zaps
Helper Functions:
usePermitOrApprovalhook: Centralized permit/approval logiccalculateMinFxSaveOut()inutils/zapCalculations.ts: Reusable calculation for USDC/fxUSD → fxSAVE conversion with slippage protection
ABIs:
STABILITY_POOL_ZAP_ABIandSTABILITY_POOL_ZAP_PERMIT_ABIinutils/permit.ts- Includes all stability pool zap functions (wstETH, fxSAVE, ETH, stETH, USDC, fxUSD)
When testing, verify:
- ✅ Permit flow works (when permit is enabled and supported)
- ✅ Approval flow works (when toggle is off or permit fails)
- ✅ Stability pool address is correct (check collateral vs sail pools)
- ✅ MinOut values are reasonable (check console/contract calls)
- ✅ Both wstETH and fxSAVE markets work correctly
- ✅ Toggle between permit/approval works as expected
- ✅ Automatic fallback works if permit fails
- Genesis zaps - Stability pool zaps for genesis deposits
- Permit/Approval Logic: Centralized in
usePermitOrApprovalhook - MinFxSaveOut Calculation: Helper function
calculateMinFxSaveOut()created inutils/zapCalculations.tsand used inAnchorDepositWithdrawModalGenesisDepositModalkeeps inline calculation (acceptable for now - separate feature, working correctly)
The stability pool zap execution pattern has some repetition but is context-specific:
- Different token addresses (ETH is payable, stETH/USDC/fxUSD need addresses)
- Different ABIs (ETH vs USDC-based zaps)
- Different parameters (ETH has
value, others don't; USDC/fxUSD needminFxSaveOut) - Different approval/permit flows per asset type
Decision: Current structure is acceptable. The patterns are similar but extracting them into a helper would require many parameters and might reduce readability more than it helps. Code is clean, maintainable, and ready for testing.