Skip to content

Instantly share code, notes, and snippets.

@jordaniza
Last active December 1, 2025 08:11
Show Gist options
  • Select an option

  • Save jordaniza/35b0db54a16472b671bceb4e7aa3fb2a to your computer and use it in GitHub Desktop.

Select an option

Save jordaniza/35b0db54a16472b671bceb4e7aa3fb2a to your computer and use it in GitHub Desktop.
avKAT Integration Guide for CEXs and Custodians - KAT/vKAT/avKAT token flows

avKAT Integration Guide for CEXs and Custodians

Overview

avKAT is a derivative of the KAT token that automates governance and yield generation for stakers. This guide covers the essential integration flows for stake/unstake operations.

Key Parameters

  • No minimum lock period - Users can exit anytime
  • Token Mechanics - 1 KAT = 1 vKAT at deposit, but avKAT is an ERC-4626 vault token that accrues yield compounded in KAT, so the exchange rate is expected to drift upward over time.
  • Exit Tax - 25% early withdrawal penalty that declines over time
  • Transferrable - unlike the vKAT position it is derived from, avKAT is fully tradeable, composable and usable in DeFi

Core Functions

Staking KAT → avKAT

1. Approve KAT Spending

// KAT Token Contract
function approve(address spender, uint256 amount) external returns (bool)
  • spender: avKAT vault contract address
  • amount: Amount of KAT to deposit

2. Deposit to avKAT Vault

// avKAT Vault Contract (ERC-4626)
function deposit(uint256 assets, address receiver) external returns (uint256 shares)
  • assets: Amount of KAT tokens to deposit
  • receiver: Address to receive avKAT shares
  • Returns: Amount of avKAT shares minted

Alternative: Deposit Existing vKAT NFT

  • KAT tokens can be staked inside the VotingEscrow contract to mind a vKAT veNFT position (see Direct Locking below). The avKAT vault accepts vKAT postions as well as naked KAT tokens.
// avKAT Vault Contract
function depositTokenId(uint256 tokenId, address receiver) external returns (uint256 shares)
  • tokenId: Existing vKAT NFT to deposit
  • receiver: Address to receive avKAT shares
  • Returns: Amount of avKAT shares minted

Unstaking avKAT → vKAT NFT

Option 1: Standard Withdrawal (for UI/EOA)

// avKAT Vault Contract - Standard ERC-4626
function withdraw(uint256 assets, address receiver, address owner) external returns (uint256 shares)
  • Creates a vKAT NFT and emits TokenIdWithdrawn event with the tokenId
  • Use this when calling from UI or EOA

Option 2: Withdrawal with Token ID Return (for contracts)

// avKAT Vault Contract
function withdrawTokenId(uint256 assets, address receiver, address owner) external returns (uint256 tokenId)
  • Same as above but returns the created vKAT NFT tokenId
  • Use this when calling from another contract that needs the tokenId

Parameters for both:

  • assets: Amount of underlying KAT to withdraw
  • receiver: Address to receive the new vKAT NFT
  • owner: Owner of avKAT shares being burned

Note: Both functions return a vKAT NFT, not liquid KAT. Users must then withdraw from vKAT to receive KAT (subject to exit tax).

Direct Locking: KAT → vKAT NFT

// VotingEscrow Contract
function createLock(uint256 _value) external returns (uint256 tokenId)
function createLockFor(uint256 _value, address _to) external returns (uint256 tokenId)
  • _value: Amount of KAT to lock (must be ≥ minDeposit)
  • _to: Address to receive the vKAT NFT (only for createLockFor)
  • Returns: New vKAT NFT token ID

Unstaking vKAT → KAT (Two-Step Process)

Step 1: Begin Withdrawal

// VotingEscrow Contract
function beginWithdrawal(uint256 _tokenId) external
  • _tokenId: vKAT NFT to unstake
  • Transfers NFT to contract and creates exit queue ticket

Step 2: Complete Withdrawal (after queue period)

// VotingEscrow Contract
function withdraw(uint256 _tokenId) external
  • _tokenId: vKAT NFT to withdraw
  • Burns NFT and returns KAT minus exit tax

Optional: Cancel Withdrawal

// VotingEscrow Contract
function cancelWithdrawalRequest(uint256 _tokenId) external
  • _tokenId: vKAT NFT to restore
  • Returns NFT to caller with voting power restored

Key Mechanics

avKAT Vault Architecture

  • ERC-4626 Vault: avKAT is a yield-bearing vault token
  • Master Token Strategy: Vault maintains one aggregated vKAT NFT position
  • Exchange Rate: Starts at 1:1 but is expected to drift up due to compounding strategy. Technically the ratio could go down although with the currently implemented strategy this is not possible.
  • Yield Source: Exit taxes and protocol revenue compound into the vault

vKAT NFT Management

  • Merge Function: merge(uint256 from, uint256 to) - Combine two NFTs
  • Split Function: split(uint256 tokenId, uint256 amount) - Divide one NFT (requires whitelist)
  • Non-transferable: NFTs cannot be transferred except to whitelisted contracts

Exit Mechanics from vKAT

  • Withdrawal Queue: beginWithdrawal(uint256 tokenId) → wait → withdraw(uint256 tokenId)
  • Exit Tax: 25% penalty that declines linearly over time
  • Tax Destination: Collected taxes go to treasury, not back to avKAT vault

Essential Events to Monitor

avKAT Vault Events (ERC-4626)

// Standard ERC-4626 Events
event Deposit(address indexed sender, address indexed owner, uint256 assets, uint256 shares);
event Withdraw(address indexed sender, address indexed receiver, address indexed owner, uint256 assets, uint256 shares);

// NFT-specific Events
event TokenIdDepositted(uint256 indexed tokenId, address indexed sender);
event TokenIdWithdrawn(uint256 indexed tokenId, address indexed receiver);

vKAT (VotingEscrow) Events

// Lock Creation/Withdrawal
event Deposit(address indexed provider, uint256 indexed tokenId, uint256 indexed depositedAt, uint256 value, uint256 totalLocked);
event Withdraw(address indexed provider, uint256 indexed tokenId, uint256 value, uint256 timestamp, uint256 totalLocked);

// Position Management
event Merged(address indexed sender, uint256 indexed from, uint256 indexed to, uint208 amountFrom, uint208 amountTo, uint208 amountFinal);
event Split(uint256 indexed from, uint256 indexed newTokenId, address sender, uint208 splitAmount1, uint208 splitAmount2);

Integration Checklist

Required Steps

  1. Implement ERC-4626 Support - avKAT follows standard vault interface
  2. Handle Two-Step Withdrawals - avKAT → vKAT NFT → KAT (with tax)
  3. Track Exchange Rate - Use convertToAssets() and convertToShares() for accurate conversions
  4. Monitor Events - Both avKAT vault and vKAT contract events
  5. Display Tax Impact - Show users the exit tax before they withdraw from vKAT

Useful Functions

// Check avKAT exchange rate
uint256 katPerShare = avKAT.convertToAssets(1e18);

// Preview deposit/withdrawal amounts
uint256 sharesOut = avKAT.previewDeposit(katAmount);  // KAT → avKAT shares
uint256 sharesNeeded = avKAT.previewWithdraw(katAmount);  // How many shares needed to withdraw X KAT
uint256 assetsOut = avKAT.previewRedeem(shareAmount);  // avKAT shares → KAT amount

// Check vKAT position details
LockedBalance memory lock = vKAT.locked(tokenId);
uint256 votingPower = vKAT.votingPower(tokenId);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment