Skip to main content

KuruAMMVault Contract

ERC20 vault for AMM liquidity provision. Users deposit tokens to receive LP shares and earn trading fees.
contract KuruAMMVault is IKuruAMMVault, ERC20, Initializable, UUPSUpgradeable, ReentrancyGuardTransient

State Variables

address public token1;
address public token2;
IMarginAccount public marginAccount;
IOrderBook public market;
MarketParams public marketParams;
uint96 public SPREAD_CONSTANT;
  • token1 & token2 - The two tokens in the liquidity pair (one may be native)
  • market - Associated OrderBook that uses this vault for AMM liquidity
  • SPREAD_CONSTANT - Spread between bid/ask prices (e.g., 100 = 1% spread)

Core Functions

initialize

One-time initialization of the KuruAMMVault contract.
function initialize(
    address _owner,
    address token1_,
    address token2_,
    address _marginAccount,
    address _market,
    uint96 _spreadConstant
) public initializer
Sets up the vault with token pair, market reference, and spread constant. Approves margin account for unlimited transfers. Can only be called once.

setMarketParams

Fetch and cache market parameters from OrderBook.
function setMarketParams() public
Updates internal marketParams struct with current market configuration from the associated OrderBook.

Liquidity Operations

deposit

Deposit tokens and receive LP shares.
function deposit(
    uint256 baseDeposit,
    uint256 quoteDeposit,
    uint256 minQuoteConsumed,
    address receiver
) external payable returns (uint256)
Deposits base and quote assets. Mints LP shares based on current reserves and price. For first deposit, mints minimum liquidity (10^3 shares) to margin account. Returns shares minted. Updates vault order sizes in the OrderBook.

mint

Mint specific amount of LP shares.
function mint(uint256 shares, address receiver) external payable returns (uint256, uint256)
Calculates required base/quote deposits via previewMint, then calls deposit.

withdraw

Burn LP shares to withdraw tokens.
function withdraw(
    uint256 _shares,
    address _receiver,
    address _owner
) public returns (uint256, uint256)
Burns shares and returns proportional base and quote tokens. Supports approval-based withdrawals. Updates vault order sizes in the OrderBook.

Preview Functions

previewDeposit

Calculate shares for a given deposit.
function previewDeposit(uint256 asset1, uint256 asset2) public view returns (uint256)
Returns how many LP shares would be minted for the deposit amounts.

previewMint

Calculate required deposits to mint shares.
function previewMint(uint256 shares) public view returns (uint256, uint256)
Returns required base and quote amounts to mint the specified shares.

previewWithdraw

Calculate token amounts from burning shares.
function previewWithdraw(uint256 shares) public view returns (uint256, uint256)
Returns base and quote amounts that would be received for the shares.

totalAssets

Get vault’s total token balances.
function totalAssets() public view returns (uint256, uint256)
Returns vault’s current balance of token1 and token2 from margin account.

Ownership Functions

transferOwnership

Transfer vault ownership.
function transferOwnership(address _newOwner) external
Changes the owner address. Owner can authorize contract upgrades.

Events

KuruVaultDeposit

event KuruVaultDeposit(
    uint256 amount1,
    uint256 amount2,
    uint256 shares,
    address userAddress
);
Emitted when liquidity is deposited. amount1 and amount2 are the deposited tokens, shares is the LP tokens minted.

KuruVaultWithdraw

event KuruVaultWithdraw(
    uint256 amount1,
    uint256 amount2,
    uint256 shares,
    address userAddress
);
Emitted when liquidity is withdrawn. amount1 and amount2 are the withdrawn tokens, shares is the LP tokens burned.

Key Mechanics

Virtual Rebalancing

Unlike traditional AMMs that rebalance continuously, the Kuru vault accrues profits in base and quote tokens without rebalancing on-chain. This creates reserve skew where actual reserves may differ from the curve’s implied reserves. Problem: Standard Uniswap V2 share calculation would penalize depositors when reserves are skewed:
shares = min(amount0 * totalSupply / reserve0, amount1 * totalSupply / reserve1)
Solution: Virtual rebalancing assumes vault ask price is the fair price and calculates shares as if reserves were rebalanced at that price. Given:
  • Actual reserves: x' = x + profitInBase, y' = y + profitInQuote
  • Current vault price: p
  • Total value: value = x'*p + y'
Virtually rebalanced reserves:
  • x_rebalanced = (x'*p + y') / 2p
  • y_rebalanced = (x'*p + y') / 2
Shares are calculated using these virtual reserves, preventing depositor disadvantage while maintaining fairness. Note: Withdrawal ratios may differ from deposit ratios due to skew. This creates arbitrage opportunities that help reduce skew over time.

Share Calculation

  • First deposit: Shares = sqrt(baseDeposit * quoteDeposit) - MIN_LIQUIDITY
  • Subsequent deposits: Proportional to virtually rebalanced reserves
  • Uses fixed-point math to handle decimal precision

Vault Rebalancing

Vault maintains bid/ask spread around current price:
  • Ask size: (SPREAD_CONSTANT * baseAmount) / (20000 + SPREAD_CONSTANT)
  • Bid size: (SPREAD_CONSTANT * baseAmount) / 20000

Price Updates

  • On deposit: Recalculates ask price and updates OrderBook
  • On withdraw: Updates sizes only (prices set on first deposit)
  • Vault prices: vaultBestAsk and vaultBestBid stored in OrderBook

Partial Fills

When withdrawing with pending partial fills:
  • Adjusts owed amounts based on vault’s profit/loss from fills
  • Returns _nullifyPartialFills flag to clear OrderBook state