Uniswap Pools
Access: Dashboard sidebar > Operations > Uniswap Pools
Info Cards
The pool detail page displays four info cards:
| Card | Source | Description |
|---|---|---|
| Pool Price | StateView.getSlot0(poolId) on-chain | Current pool price derived from sqrtPriceX96 |
| Oracle Price | Oracle contract on-chain | Latest oracle price for the token pair |
| APR / APY | Calculated by APR_CALCULATION cron | Annualized return based on fee revenue |
| TVL | StateView.getLiquidity(poolId) on-chain | Total value locked (active liquidity approximation) |
Price formula: price = sqrtPriceX96^2 / 2^192 * 10^(decimals0 - decimals1)
TVL formula: Uses the active liquidity at the current tick to approximate total value locked. This is only the liquidity concentrated around the current price, not the full range.
Position Info
Each position (NFT) shows:
- Position ID (NFT ID)
- Liquidity amount
- Token0 / Token1 amounts (calculated via concentrated liquidity math)
- Tick range (lower, upper)
- In-range / out-of-range status
Data is read from PositionManager.positionInfo(nftId) and getPositionLiquidity(nftId).
Operations
Add Liquidity
Increases liquidity on an existing position. Sends increaseLiquidity call via BitGo Express.
- Amounts include slippage buffer:
amount * (10000 + slippageBps) / 10000 - Approvals (ERC20 -> Permit2, Permit2 -> PositionManager) also use slippage-adjusted amounts
- Each approval waits for receipt before proceeding
Mint Position
Creates a new position with a specified tick range.
- Lower tick uses
Math.flooralignment (alignTickToSpacing) - Upper tick uses
Math.ceilalignment (alignTickToSpacingCeil) - Out-of-range positions (entire range above or below current price) only require one token. The frontend detects this and disables the unnecessary token input.
- Backend validates
liquidity > 0nbefore sending the TX
Remove Liquidity
Removes all or partial liquidity from a position. Returns tokens to the wallet.
Rebalance
Removes all liquidity from current position and mints a new position centered on the oracle price.
- After remove TX, reads
balanceOffor both tokens to get actual wallet balances - Uses
min(walletBalance, maxBudget)as desired amounts (maxBudget acts as a cap, not a fixed amount) - Validates
newLiquidity > 0nbefore sending the mint TX
Auto-Calc Amounts
When entering an amount for one token, the complementary token amount is auto-calculated using concentrated liquidity math with Decimal.js (40 digits of precision):
Code
Decimal.js is used instead of native floating-point to avoid catastrophic cancellation in the subtraction 1/sqrtP - 1/sqrtPb.
Bot Config
Each Uniswap bot (wallet) has the following configuration:
| Field | Description |
|---|---|
rebalanceTriggerPercent | Deviation % between pool and oracle price to trigger auto-rebalance |
priceBandPercent | Width of the new position range (oracle price +/- this %) |
maxBudgetToken0 | Maximum amount of token0 to use in rebalance |
maxBudgetToken1 | Maximum amount of token1 to use in rebalance |
slippageBps | Slippage tolerance in basis points (e.g., 100 = 1%) |
Recommendations
- To test auto-rebalance, temporarily lower
rebalanceTriggerPercentand run the cron on-demand from the Cron Jobs page. - Monitor the oracle price vs pool price deviation in the info cards. If they diverge significantly, a manual rebalance may be warranted.
- After any liquidity operation, verify the position in the TX history table.
TX History
All liquidity operations (add, mint, remove, rebalance) are logged with their BitGo transaction ID, status, amounts, and timestamps. Operations are async -- they return a transactionId immediately while the on-chain work runs in the background.