Agent-managed cross-chain liquidity for earning fees on USDC-ETH pairs on Uniswap v4

CrossLiquid is agent-managed, cross-chain liquidity for earning fees on USDC-ETH pairs across Uniswap v4 pools.
Concentrated liquidity generates great yield but comes with amplified impermanent loss and requires constant rebalancing. Also, the best opportunities shift between chains. Managing this manually is a hassle.
CrossLiquid's off-chain agent automatically manages and rebalances positions across multiple L2s. It scores opportunities per chain (based on yield, volatility, gas costs) and moves funds via li.fi to the highest-yielding chain.
Users deposit ETH into a vault on one chain (Base) and receive $CLQ tokens. After that the agent handles everything: swapping for USDC, bridging, adding to uniswap v4 and rebalancing if necessary.
A SvelteKit frontend shows real-time scores and position status.
Core technologies:
Uniswap V4
This was my first time working with Uniswap V4. It took some time getting familiar with the PoolManager and doing everything as part of the unlock callback. It also took some time getting the local setup with the full v4 stack to work, but after that was done it worked great.
Li.Fi integration
It was a bit harder because I couldn't test it locally or on a testnet. I tested everything thoroughly up to the point of sending a transaction, and then deployed to Base & Unichain to make it all work, and there were no surprises then.
Agent logic
The typescript agent has a loop for executing actions that are needed for rebalancing and getting funds from the vault to the PositionManager. It tracks these in-flight actions and makes sure there are not multiple actions affecting the same chain.
It also has a 'stats' loop where it fetches univ4 pool data every 30s. It stores fee growth, liquidity and current price in a sqlite database. That's how we can calculate the "Liquidity Opportunity Score" by looking at recent pool APR, volatility and we also factor in gas costs.
(Interestingly the volatility is not so useful to compare between chains because all chains are nearly 100% correlated, even during the high volatility events of last week).

