
TLIS-Hook
Encrypt your swaps, get random prices ±1%. MEV protection + gamified trading on Uniswap V4.
Demo
About
TLISHook (Time-Locked Intent System Hook) is a Uniswap V4 hook that eliminates MEV attacks using a combination of time-locked encryption and verifiable randomness. THE PROBLEM: Standard Uniswap V4 pools are still vulnerable to sandwich attacks, front-running, and other MEV exploitation. Traders lose 2-5% of their swap value to sophisticated bots that scan the mempool and manipulate transaction ordering. THE SOLUTION: TLISHook introduces a novel two-layer defense mechanism: 1. PRIVACY LAYER: Users submit encrypted swap intents that are XOR-encrypted with future Drand randomness. These intents remain completely unreadable for a 5-minute collection window, preventing bots from seeing trade flow before execution. 2. RANDOMNESS LAYER: At execution time, each swap executes at a "surprise price" - the market price plus or minus a random offset (±1% in sqrtPriceX96 space). This randomness is derived from Drand (a decentralized randomness beacon), making it verifiable and unpredictable. KEY FEATURES: - Temporal privacy through time-locked encryption (5-minute batches) - Surprise pricing that makes front-running unprofitable - User-defined safety bounds ensure you never get worse than your specified limits - Atomic batch execution prevents partial manipulation - Decentralized coordination via timestamp-based batch IDs - Escrow-based settlement for autonomous execution THE INNOVATION: Beyond security, TLISHook gamifies trading. Users might get lucky and receive better-than-market prices, or unlucky and pay slightly more - but always within their safety bounds. This transforms boring swaps into engaging, strategic experiences while providing stronger MEV protection than traditional approaches. TECHNICAL ARCHITECTURE: - Built on Uniswap V4's hooks system - Integrates Drand quicknet (3-second rounds) for randomness - Uses poolManager.unlock() → unlockCallback() for atomic settlement - Keeper network executes batches after time-lock expires (60-second priority window) - All user funds held in hook's escrow (s_userBalances mapping) IMPACT: Trading becomes both MORE secure (MEV-resistant) AND more fun (gamified with provably fair randomness). Users maintain control via price bounds while potentially benefiting from lucky random outcomes.
How it's made
TECH STACK: - Solidity ^0.8.26 for smart contracts - Foundry (forge, anvil) for development and testing - Uniswap V4 core & periphery libraries - Drand quicknet API for decentralized randomness - Sepolia testnet for deployment CORE ARCHITECTURE: 1. HOOK IMPLEMENTATION (TLISHookV5.sol) Built as a Uniswap V4 hook implementing beforeSwap() lifecycle. The hook intercepts normal swaps and redirects them through our time-locked intent system. Key challenges: - Calculating correct hook permissions bitmap (0x4000 for beforeSwap only) - Managing hook-owned liquidity positions for swap execution - Handling delta accounting with poolManager.unlock() → unlockCallback() pattern 2. ENCRYPTION MECHANISM Used simple XOR encryption (post hackathon AES/complex crypto encryption) for gas efficiency: ```solidity encryptedData = intentData XOR drand_randomness ``` This works because: - XOR is reversible: encrypted XOR same_key = original - Drand randomness is 32 bytes, perfect for uint256 packing - Super cheap on-chain (just one XOR operation per intent) HACKY PART: Pack all intent parameters (zeroForOne, amount, minSqrtPrice, maxSqrtPrice) into a single bytes32, then XOR it with drand. This saves massive gas vs encrypting each field separately. 3. BATCH TIMING COORDINATION No centralized scheduler! Batches self-organize via deterministic timestamp math: ```solidity batchId = block.timestamp / 300 // 5-minute windows unlockTime = (batchId + 1) * 300 + 60 // Close + 60s lock ``` 4. SURPRISE PRICING ALGORITHM The trickiest part was implementing ±1% randomness in sqrtPriceX96 space (Uniswap's price format). can't just do `price * 1.01` because prices are stored as sqrt(price) * 2^96: ```solidity // Extract random percentage from drand (0-10000 basis points) uint256 randomBps = (randomness % 10000); // Apply ±1% offset in sqrtPrice space uint160 surprisePrice = applySqrtPriceOffset(marketPrice, randomBps); // Clamp to user bounds finalPrice = clamp(surprisePrice, minSqrtPrice, maxSqrtPrice); ``` MORE: Instead of complex sqrt calculations, used linear interpolation in sqrt space. 5. DRAND INTEGRATION Integrated Drand's quicknet (3-second rounds) as our randomness source: - On intent submission: Calculate target drandRound = (unlockTime / 3) + 1 - At execution: Keeper fetches drand randomness from HTTP API - Contract verifies randomness via signature check (BLS12-381) - Use verified randomness for both decryption AND surprise pricing - Post hackathon more robust solution to implement. CHALLENGE: Drand verification is expensive (~500k gas for BLS verification). optimized by: - Caching verified randomness in DrandOracle contract - Reusing same randomness for entire batch - Keeper pre-verifies off-chain before submission 6. ESCROW SYSTEM Users deposit tokens into `mapping(address => mapping(Currency => uint256)) s_userBalances`. This escrow approach: - Eliminates need for per-intent approvals (would fail with encryption) - Enables autonomous execution without user signatures - Gas-efficient: only 2 storage updates per intent (debit input, credit output) HACKY OPTIMIZATION: used Uniswap V4's Currency type (address cast) to support both ERC20 and native ETH with same code path. WHAT IMPROVE WITH MORE TIME: - BLS verification in Solidity (currently gas prohibitive, could use precompile) - Multi-pool support (currently hardcoded single ETH/USDC pool) - Advanced pricing strategies (TWAP-based, volatility-adjusted) - Keeper profitability calculator (automated gas vs reward analysis) - AI agent to automatically execute batch, to avoid any execution batch window wastage. ```