ORYR
Auto-rebalance your DeFi portfolio across chains based on real-time risk
Problem Statement
ORYR (Omnichain Risk-Adjusted Yield Router) is an autonomous cross-chain DeFi protocol that solves the fundamental problem of fragmented liquidity and manual asset management across multiple blockchains.The core innovation is a fully automated system that monitors real-time volatility metrics across chains using Pyth Network price feeds (BTC, ETH, SOL, FX pairs), calculates on-chain risk scores in basis points, and automatically triggers cross-chain rebalancing operations via LayerZero messaging when risk thresholds are exceeded.Here's how it works: Users deposit stablecoins (USDC/USDT) into an OFT Vault on any supported chain (Arbitrum or Base). They receive LayerZero OFT (Omnichain Fungible Token) shares that represent their position across all chains. A backend service continuously fetches price data from Pyth's Hermes API and updates the on-chain Controller contract. The Controller computes risk scores by analyzing price volatility between multiple feeds. When risk exceeds a configurable threshold (e.g., 5% volatility), the system automatically initiates a cross-chain rebalancing operation.The rebalancing flow is fully automated: The Controller sends a LayerZero message containing rebalancing instructions to a Rebalancer contract on the destination chain. The Rebalancer decodes the payload and executes optimal token swaps using 1inch's Aggregation Router to move funds to lower-risk chains or opportunities. If swap execution fails, the system has intelligent fallbacks to ensure users always receive their funds.The project features a beautiful, production-ready web interface built with Next.js, TypeScript, and RainbowKit that provides real-time visibility into: vault balances across all chains, live risk metrics powered by Pyth oracles, cross-chain allocation visualizations, and one-click deposit/withdraw functionality. The UI updates in real-time using Wagmi hooks and displays system health, next rebalance countdown, and transaction history.What makes ORYR special is that it's a genuine "set it and forget it" solution. Users don't need to manually monitor multiple chains, pay expensive bridge fees, or understand complex DeFi operations. The system handles everything autonomously, optimizing their yield while managing risk across the entire omnichain ecosystem. This creates a fundamentally new DeFi primitive that unlocks liquidity efficiency at a scale previously impossible in the fragmented blockchain landscape.
Solution
ORYR is built as a sophisticated multi-chain system with three main components: smart contracts, backend automation services, and a modern web frontend, all working together seamlessly.SMART CONTRACT ARCHITECTUREI deployed three core contracts on both Arbitrum Sepolia and Base Sepolia:Controller.sol - This is the brain of the operation. It inherits from LayerZero's NonblockingLzApp for secure cross-chain messaging, plus OpenZeppelin's ReentrancyGuard, Pausable, and access control. The Controller stores Pyth price feed data (bytes32 feedId => uint256 price mapping), computes risk scores on-chain using basis points arithmetic (10000 = 100%), and orchestrates cross-chain rebalancing. I implemented a job scheduling system that allows delayed execution of rebalancing operations, which is crucial for implementing Pyth Entropy randomization in future phases. The contract has a multi-updater authorization system so multiple backend services can push price updates without exposing the owner key.OFTVault.sol - This extends LayerZero's OFTV2 (Omnichain Fungible Token V2) standard, creating shares that are natively omnichain. Users deposit ERC20 stablecoins and receive 1:1 OFT shares (upgradable to dynamic pricing). The clever part here is the sendCrossChainFrom() function that only the Controller can call - it enables programmatic cross-chain transfers without user signatures, essential for automated rebalancing. I had to carefully handle the OFTV2 inheritance chain since it already includes Ownable through LzApp, avoiding diamond inheritance issues.Rebalancer.sol - Receives LayerZero messages via _nonblockingLzReceive() and executes rebalancing. I integrated 1inch's Aggregation Router with automatic approval management (_ensureApprove() checks allowance before each swap and sets max allowance if needed). The payload structure encodes 6 parameters: tokenIn, user address, amountIn, tokenOut, minOut for slippage protection, and raw swapCalldata from 1inch API. If the swap fails for any reason, the contract has a fallback that does a direct transfer, ensuring users never lose funds.PARTNER TECHNOLOGY INTEGRATION - THE HACKY PARTSLayerZero Integration: The trickiest part was understanding that LayerZero doesn't take destination addresses as parameters - it uses a trusted remote lookup mapping. I had to implement setTrustedRemote() configuration where you pack two addresses together (source and destination). The _lzSend() function signature is: (chainId, payload, refundAddress, zroPaymentAddress, adapterParams, nativeFee). I made all rebalancing functions payable to accept native gas fees for cross-chain execution.Pyth Network: I'm pulling prices from Pyth's Hermes HTTP API rather than doing on-chain pulls (which would be gas-expensive). The backend script fetches multiple feed prices in parallel, formats them to 8 decimals to match Pyth's convention, and batch-updates the Controller in a single transaction for gas efficiency. The computeRisk() function uses a simple but effective volatility calculation: |priceA - priceB| / priceA * 10000, giving basis points that update in real-time.1inch Integration: This was particularly hacky because 1inch's swap API returns raw calldata that needs to be forwarded as-is. I'm encoding the entire 1inch swap instruction as bytes in the LayerZero payload, then using a low-level .call() to execute it. This required careful error handling since failed calls don't revert automatically - I decode the return value and have fallback logic.BACKEND AUTOMATIONBuilt two Node.js services using ethers.js v6:push_pyth_prices.js - Polls Pyth's Hermes API every 10 seconds, fetches BTC/ETH/SOL prices, and calls batchUpdatePrice() on the Controller. Uses proper gas estimation and nonce management.compute_and_send.js - Reads risk scores from the Controller, compares against thresholds, and if exceeded, constructs the rebalancing payload with 1inch swap data and sends it cross-chain. The tricky part was estimating LayerZero gas fees - I settled on a conservative 0.01 ETH per message which works for testnet.FRONTEND ENGINEERINGBuilt with Next.js 14 App Router and TypeScript. The challenge here was making Web3 interactions feel instant:Used Wagmi's useReadContract with refetchInterval for real-time updatesImplemented optimistic UI updates for pending transactionsCreated a custom hook pattern for approve-then-deposit flowsRainbowKit integration required careful configuration of testnet chains and custom RPC URLsThe VaultCard component handles the entire deposit flow: check allowance, show approve button if needed, track approval transaction, automatically switch to deposit mode, then execute deposit and update UI. All with proper loading states and error handling.I built a custom glassmorphism design system with Tailwind using backdrop-filter blur, rgba opacity layers, and custom animations. The risk metrics component color-codes risk levels (green/yellow/red) based on basis points, and the allocation chart uses Recharts with custom tooltips styled to match the dark theme.PARTICULARLY HACKY / NOTABLE ASPECTSCross-chain testing without deploying: I created mock LayerZero endpoints locally to test message flows before spending testnet gas.ABI encoding dance: The payload structure requires encoding once for LayerZero (the outer layer) and the 1inch calldata is already encoded (inner layer) - managing nested encoding was tricky.Gas optimization: Batch price updates save ~60% gas compared to individual updates. I pack feed IDs and prices into arrays.TypeScript contract types: Used Hardhat's TypeChain to generate types, then imported them into the Next.js app for full type safety from contract to UI.Fallback robustness: Every external call (1inch, LayerZero) has fallback behavior. If 1inch swap fails, transfer original token. If cross-chain message fails, LayerZero's non-blocking pattern prevents stuck messages.The entire system is production-ready with ReentrancyGuard on every state-changing function, Pausable for emergency stops, extensive event logging for off-chain monitoring, and comprehensive error messages. Total development time was about 48 hours from concept to deployed testnet app!
Hackathon
ETHGlobal Buenos Aires
2025
Contributors
- anii76
9 contributions