Kora is a privacy-preserving Dollar Cost Averaging (DCA) bot that leverages Fully Homomorphic Encryption (FHE) and the Zama Confidential Blockchain Protocol to execute automated investment strategies while maintaining complete user privacy. The protocol aggregates encrypted DCA intents from multiple users, executes batched swaps on decentralized exchanges, and distributes purchased tokens proportionally without revealing individual investment amounts or strategies.
- Privacy-Preserving: All user parameters and amounts remain encrypted throughout the entire process
- Batched Execution: Aggregates multiple user intents into single transactions for gas efficiency
- Hook-Based Strategy System: Modular, extensible strategy framework with customizable conditions
- FHE Integration: Leverages Zama's FHE implementation for encrypted computations
- Automated DCA: Executes strategies based on time, frequency, and dynamic market conditions
The protocol is built on Zama's Confidential Blockchain using Fully Homomorphic Encryption (FHE) to enable private computations on encrypted data. The system comprises four main components:
- KoraExecutor: The central smart contract that orchestrates strategy management, batch processing, and swap execution. It handles encrypted operations through FHEVM library integration and manages the complete workflow from intent collection to token distribution.
- Encrypted ERC20 Tokens: Privacy-preserving token implementations that extend standard ERC20 functionality with FHE capabilities. These tokens (e.g., eWETH, eUSDC) maintain encrypted balances and support encrypted transfers while interfacing with underlying standard tokens for DEX interactions.
- Hook System: Modular conditional validators that enforce strategy parameters without revealing them. Each hook implements a specific validation rule through standardized interfaces, allowing strategy composition without modifying the core protocol.
Users create strategies by combining multiple hooks with encrypted parameters. Each strategy receives a unique identifier computed as keccak256(user, token0, token1, salt), ensuring deterministic addressing while preserving privacy. Strategies store only public addresses and encrypted state, with all sensitive data maintained within hooks.
The system collects encrypted intents from multiple users and processes them in batches of up to 64 transactions. The batching operates through two-phase execution:
- Phase 1 - Encrypted Processing:
- Validates intents against strategy hooks using FHE operations
- Aggregates encrypted swap amounts using homomorphic addition
- Packages pre-hook results into packed boolean arrays for efficient decryption
- Phase 2 - Decrypted Execution:
- Receives decrypted totals from FHE oracle after signature verification
- Executes single aggregated swap on Uniswap V2
- Calculates proportional distributions using encrypted arithmetic
- Distributes output tokens back to users based on their contribution percentages
Hooks implement the ISwapHook interface with three functions:
initialize(): Sets up encrypted strategy parameterspreSwap(): Validates intents against strategy rules using FHE comparisonspostSwap(): Updates encrypted state after successful executions
Standard hooks include:
BudgetHook: Enforces maximum total expenditure with FHE.le(spent + amount, budget)PurchaseAmountHook: Validates per-transaction limitsTimeframeHook: Checks timestamp validity using encrypted time comparisonsFrequencyHook: Ensures minimum intervals between executions
sequenceDiagram
participant U as User
participant K as KoraExecutor
participant H as Hook Contracts
U->>U: Generate encrypted strategy parameters
U->>K: createStrategy(user, hooks, salt)
K->>K: Compute strategyId = keccak256(user, token0, token1, salt)
K->>K: Validate hook addresses
loop For each hook
K->>H: initialize(strategyId, hookData)
H-->>K: Hook initialized
end
K->>K: Store strategy mapping
K-->>U: StrategyCreated event
Users create customized DCA strategies by specifying encrypted parameters through hook contracts:
BudgetHook: Sets maximum total spendable amountPurchaseAmountHook: Defines maximum per-transaction amountTimeframeHook: Sets strategy expiration timeFrequencyHook: Controls execution intervalsDynamicConditionHook: Optional conditions like "buy the dip"
Each strategy receives a unique strategyId computed as keccak256(user, token0, token1, salt), ensuring deterministic addressing.
sequenceDiagram
participant U as User
participant K as KoraExecutor
participant H as Hook Contracts
participant T as EncryptedToken
U->>U: Encrypt amount0 with inputProof
U->>K: executeBatch([intents])
K->>K: Validate batch size ≤ MAX_BATCH_SIZE
loop For each intent
K->>K: Validate strategy exists
K->>H: Run preSwap hooks
H-->>K: ebool result
K->>T: pullIn(user, amount0)
T-->>K: Transfer success/failure
K->>K: Aggregate encrypted amounts
end
K->>K: Pack pre-hook results
K->>FHE: requestDecryption(cts, callback)
FHE-->>K: requestId
K->>K: Store batch information
K-->>U: BatchRequested event
Users submit encrypted trading intents containing:
- amount0: Encrypted amount of token0 to swap
- inputProof: Zero-knowledge proof of valid encryption
- intentId: Unique identifier for the intent
- strategyId: Reference to user's strategy
The batch mechanism:
- Collects up to 64 intents (MAX_BATCH_SIZE)
- Validates each against strategy hooks
- Aggregates encrypted amounts using FHE operations
- Packages hooks results (
ebools) into single packedeuint64for single decryption - Requests decryption from FHE oracle
sequenceDiagram
participant FHE as FHE Oracle
participant K as KoraExecutor
participant U as Uniswap V2
participant T0 as Token0
participant T1 as Token1
participant H as Hook Contracts
FHE->>K: decryptionCallback(requestId, totalIn, packedChecks, signatures)
K->>K: Verify oracle signatures
K->>K: Validate batch state
K->>T0: withdraw(totalIn)
K->>U: swapExactTokensForTokens(totalIn, 0)
U->>T0: transferFrom(KoraExecutor, totalIn)
U->>T1: transfer(KoraExecutor, amountOut)
K->>T1: deposit(amountOut)
loop For each successful intent
K->>K: Calculate proportional share
K->>T1: transfer(user, intentAmountOut)
K->>H: Execute postSwap hooks
end
K->>K: Mark batch completed
K-->>K: BatchExecuted event
Upon receiving decrypted values from the FHE oracle:
- Signature Verification: Validates oracle responses
- Token Preparation: Withdraws underlying tokens for swapping
- DEX Execution: Executes single aggregated swap on Uniswap V2
- Proportional Distribution: Calculates and distributes output tokens using encrypted arithmetic
- Post-Hook Execution: Runs strategy completion hooks
interface ISwapHook {
function initialize(bytes32 strategyId, bytes memory data) external;
function preSwap(bytes32 strategyId, Intent calldata intent) external returns (ebool);
function postSwap(bytes32 strategyId, IntentResult memory result) external;
}Budget Hook (BudgetHook.sol)
- Manages total investment budget
- Tracks remaining allocation
- Prevents over-investment
Frequency Hook (FrequencyHook.sol)
- Controls purchase timing
- Manages interval-based execution
- Prevents too-frequent purchases
Purchase Amount Hook (PurchaseAmountHook.sol)
- Manages per-interval amounts
- Implements dynamic amount adjustments
- Handles market condition responses
Timeframe Hook (TimeframeHook.sol)
- Controls strategy duration
- Manages start/end dates
- Implements time-based constraints
Kora has been deployed on Ethereum Sepolia Testnet.
| Contract | Address |
|---|---|
| KoraExecutor | 0xa7fEA89845f65608eb02Ee768949Ac7C32ae83b3 |
| USDC | 0x55922139468662dBB05fde86cce4f08d08Db33F3 |
| WETH | 0xFDEC6aD96E24316d9C305db3E29e977aE6b629B5 |
| eUSDC | 0xCEd8Cc99597E9F5A59Ab4B24253bB7F2ADcdF1A7 |
| eWETH | 0xd5a63Af1FCA951793519D572F485125CcDb92b3d |
| BudgetHook | 0x9054Af6f1FAB2975f6d148B6ff21cae1D104830C |
| PurchaseAmountHook | 0x83723D8bb09Ca8E05Ce4B659c99a1D44737EafA2 |
| TimeframeHook | 0x2C2a201Ac482343393CE8d000139BE83846dffDF |
| FrequencyHook | 0x1C68D590D1CdB7ce071456D89529052Ce3B94C54 |
The test suite is organized into logical modules located in packages/contracts/test:
├── test
│ ├── executor.test.ts
│ ├── helpers
│ │ ├── env.ts
│ │ ├── index.ts
│ │ └── uniswap.ts
│ ├── hooks
│ │ ├── budget.test.ts
│ │ ├── frequency.test.ts
│ │ ├── purchase-amount.test.ts
│ │ └── timeframe.test.ts
│ ├── libraries
│ │ └── packed-bool.test.ts
│ └── wrapped-token.test.ts
- Strategy Creation: Test strategy creation and validation
- Intent Processing: Test intent submission and validation
- Batch Execution: Test batch formation and execution
- Hook Integration: Test pre and post-swap hook execution
- Token Distribution: Test proportional token distribution
- Budget Hook Tests: Test Budget Hook functionality
- Frequency Hook Tests: Test Frequency Hook functionality
- Purchase Amount Hook Tests: Test Purchase Amount Hook functionality
- Timeframe Hook Tests: Test Timeframe Hook functionality
- Library Tests: Test utility libraries and helper functions
- Token Tests: Test encrypted token functionality
- Hook Tests: Test individual hook implementations
- Environment Setup: Configure test environment and contracts
- Uniswap Integration: Mock DEX operations for testing
- Test Utilities: Common testing functions and assertions
- Larger Batch Sizes: Implementation of dynamic batch sizing algorithms that automatically adjust based on network congestion and gas prices.
- Advanced Hook Types: Development of more sophisticated hook patterns including:
- Oracle-Based Hooks: Integration with price oracles for conditional execution based on external market data
- Social Hooks: Strategy templates that can be shared and executed with parameter customization
- Cross-Strategy Hooks: Coordination between multiple strategies for complex portfolio rebalancing
- Intent Matching Engine: Development of an off-chain intent matching system that optimizes batch composition based on strategy compatibility, reducing on-chain computation requirements.