Architecture
Vaults use a minimal proxy pattern (ERC-1167) for gas-efficient deployment:- One vault per intent, deployed on-demand
 - Deterministic addresses computed from intent hash
 - Only the Portal can manage vault operations
 - No persistent state between intents (stateless implementation)
 
Deployment
CREATE2 Determinism
Vault addresses are computed using CREATE2 with the intent hash as salt:On-Demand Deployment
Vaults are deployed lazily when first needed:- Intent Publishing: Address is computed but not deployed
 - First Funding: Vault deployed if not already exists
 - Withdrawal/Refund: Vault deployed if not already exists
 
Chain Compatibility
The CREATE2 prefix adapts to different chains:- Standard EVM Chains: 
0xffprefix - TRON Mainnet (728126428): 
0x41prefix - TRON Testnet (2494104990): 
0x41prefix 
Access Control
- Only validated intents can withdraw funds
 - Refunds require proper deadline checks
 - Token recovery follows protocol rules
 
Funding
Standard Funding
Called duringPortal.publishAndFund() or Portal.fund():
- Check native token balance against 
reward.nativeAmount - For each ERC20 token:
- Attempt permit-based transfer first (if permit contract provided)
 - Fall back to standard 
transferFromwith allowance 
 - Return true only if all tokens fully funded
 
- Funder’s token balance
 - Funder’s allowance/permit to vault
 - Existing vault balance
 
Permit-Based Funding
Vaults support gasless approvals via permit contracts (e.g., Permit2): Permit Transfer:approve() call.
Standard Transfer (Fallback):
transferFrom based on existing allowance.
Funding Strategy:
- Check current vault balance
 - Try permit transfer if permit contract provided
 - Fall back to standard transfer for any remaining amount
 - Return unfunded amount
 
Withdrawal
Solvers claim rewards after intent fulfillment and proof verification:- Transfer all reward ERC20 tokens to claimant (up to reward amounts)
 - Transfer native tokens to claimant (up to reward amount)
 - Use actual balance (may be less than reward if partially funded)
 
- Uses 
SafeERC20.safeTransferfor token transfers - Minimum of reward amount and actual balance prevents over-withdrawal
 - Native transfers use low-level call with success check
 - Reverts on failed native transfer with 
NativeTransferFailederror 
Refund
Creators reclaim rewards after intent expiry:- Transfer all ERC20 token balances to 
reward.creator - Transfer all native token balance to 
reward.creator - No amount restrictions (returns full vault contents)
 
- Returns actual balance, not limited to reward amounts
 - Always transfers to 
reward.creator - Portal validates deadline before calling
 
Token Recovery
Recover tokens mistakenly sent to vault:- User accidentally sent tokens directly to vault address
 - Tokens sent to wrong vault
 - Extra tokens beyond reward amounts
 
- Cannot recover zero address (native tokens)
 - Cannot recover any token in 
reward.tokensarray - Intent must have zero native rewards OR already be claimed/refunded
 
Fund Flow
Publishing Flow
Withdrawal Flow
Refund Flow
Security Model
Immutable Portal
The portal address is set at construction and cannot be changed:- Unauthorized withdrawals
 - Fake refunds before expiry
 - Bypassing protocol validation
 
Balance-Based Logic
All transfers use actual balance rather than storing state:- No accounting variables to manipulate
 - Always transfers real tokens held by vault
 - Cannot withdraw more than vault contains
 
SafeERC20 Integration
Uses OpenZeppelin’s SafeERC20 for all token transfers:- Handles non-standard ERC20 returns
 - Prevents silent transfer failures
 - Reverts on insufficient balance
 
Minimal Proxy Pattern
Using ERC-1167 minimal proxies provides:- Gas Efficiency: ~2,500 gas to deploy vs ~200,000 for full contract
 - Security: Implementation cannot be changed after proxy deployment
 - Predictability: Deterministic addresses enable pre-funding
 
Integration Examples
Computing Vault Address
Pre-Funding Vault
Users can send tokens directly to the computed vault address before publishing:Funded status check, so verify funding manually with portal.isIntentFunded().
Partial Funding
Using Permit for Gasless Funding
Error Handling
NotPortalCaller(address): Caller is not the authorized Portal contractNativeTransferFailed(address, uint256): Failed to send native tokens to recipientZeroRecoverTokenBalance(address): Attempted to recover token with zero balance
Gas Considerations
Deployment Costs
- Full Vault Contract: ~200,000 gas
 - Minimal Proxy: ~2,500 gas (98.75% savings)
 - Implementation: One-time cost, shared across all vaults
 
Operation Costs
Funding:- Native transfer: ~21,000 gas
 - ERC20 transfer: ~50,000 gas per token
 - Permit transfer: ~70,000 gas per token (includes permit verification)
 
- Per token: ~50,000 gas
 - Native transfer: ~21,000 gas
 
- Similar to withdrawal costs
 - No amount validation overhead
 
Optimization Strategies
- Batch Operations: Use 
Portal.batchWithdraw()to amortize vault deployment costs - Pre-Funding: Send tokens to vault address before publishing to skip funding transaction
 - Single Token Rewards: Minimize token array length in rewards
 - Standard Transfers: Use regular approvals instead of permits when possible (lower gas)
 
Cross-Chain Considerations
Address Consistency
Vault addresses are deterministic across chains with same:- Portal deployment address
 - Intent parameters (destination, route, reward)
 - CREATE2 prefix (chain-specific)
 
Native Token Handling
Each chain’s native token is handled uniformly:- Ethereum: ETH
 - Polygon: MATIC
 - Arbitrum: ETH
 - TRON: TRX
 
reward.nativeAmount.
Best Practices
For Intent Creators
- Verify Funding: Call 
portal.isIntentFunded()before expecting fulfillment - Adequate Approvals: Ensure sufficient allowance for all reward tokens
 - Gas Budgeting: Include native amount for destination chain execution
 - Deadline Buffer: Set 
reward.deadlinewith buffer for proof verification time 
For Solvers
- Check Vault Balance: Verify vault is fully funded before fulfilling
 - Gas Estimation: Account for withdrawal transaction costs in profitability calculations
 - Claimant Address: Ensure claimant address is correct and can receive tokens
 - Token Compatibility: Verify all reward tokens are standard ERC20
 
For Integrators
- Address Prediction: Compute vault addresses off-chain to display to users
 - Event Monitoring: Watch 
IntentFundedevents to track funding progress - Error Handling: Handle partial funding scenarios gracefully
 - Permit Integration: Support gasless approvals for better UX
 
