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.
- 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
// KAT Token Contract
function approve(address spender, uint256 amount) external returns (bool)spender: avKAT vault contract addressamount: Amount of KAT to deposit
// avKAT Vault Contract (ERC-4626)
function deposit(uint256 assets, address receiver) external returns (uint256 shares)assets: Amount of KAT tokens to depositreceiver: Address to receive avKAT shares- Returns: Amount of avKAT shares minted
- 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 depositreceiver: Address to receive avKAT shares- Returns: Amount of avKAT shares minted
// avKAT Vault Contract - Standard ERC-4626
function withdraw(uint256 assets, address receiver, address owner) external returns (uint256 shares)- Creates a vKAT NFT and emits
TokenIdWithdrawnevent with the tokenId - Use this when calling from UI or EOA
// 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 withdrawreceiver: Address to receive the new vKAT NFTowner: 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).
// 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
// VotingEscrow Contract
function beginWithdrawal(uint256 _tokenId) external_tokenId: vKAT NFT to unstake- Transfers NFT to contract and creates exit queue ticket
// VotingEscrow Contract
function withdraw(uint256 _tokenId) external_tokenId: vKAT NFT to withdraw- Burns NFT and returns KAT minus exit tax
// VotingEscrow Contract
function cancelWithdrawalRequest(uint256 _tokenId) external_tokenId: vKAT NFT to restore- Returns NFT to caller with voting power restored
- 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
- 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
- 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
// 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);// 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);- Implement ERC-4626 Support - avKAT follows standard vault interface
- Handle Two-Step Withdrawals - avKAT → vKAT NFT → KAT (with tax)
- Track Exchange Rate - Use
convertToAssets()andconvertToShares()for accurate conversions - Monitor Events - Both avKAT vault and vKAT contract events
- Display Tax Impact - Show users the exit tax before they withdraw from vKAT
// 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);