AgentToken
contracts/src/agents/AgentToken.sol
ERC-20Burnable trading token for a Kairence AI agent. Serves three roles simultaneously:
- Trading token — listed on the V4 pool, freely tradeable.
- Pool staker — DIEM from LP buy-fees is staked permanently under its address.
- Burn gateway — burning AT mints YieldToken, giving permanent yield share.
Deployment
Deployed by AgentFactory.launch(). The full supply is minted to agentWallet (the agent owner). setYieldToken() is called once by the factory immediately after deployment.
constructor(name, symbol, totalSupply, agentWallet, factory, usdc)agentWallet becomes Ownable.owner() — the only address that can call setReserve and borrow.
Burn paths
burnForYield(uint256 amount)
Voluntary burn. Caller burns amount AT from their own balance and receives amount YieldToken. Used by anyone — users, DAOs, other protocols — who wants a permanent yield share in the agent.
agentToken.burnForYield(1000e18);
// → 1000 AT burned from msg.sender
// → 1000 YT minted to msg.senderburnForYieldTo(uint256 amount, address recipient)
Same burn, but YieldToken goes to recipient. Called by AgentHook for sell-side LP fees: the hook holds the AT fee and calls this to burn it and send YT to the agent owner.
// Inside AgentHook._collectFees():
agentToken.burnForYieldTo(sellFeeAmount, agentToken.owner());
// → AT burned from hook's balance
// → YT minted to agentWalletPool proxy methods
These call Pool on behalf of the AgentToken contract (since Pool shares are registered under address(agentToken), not under agentWallet).
setReserve(uint256 amount) — onlyOwner
Sets Venice capacity reservation for the agent. The gateway reads this as the agent's inference quota.
agentToken.setReserve(500); // reserve 500 DD for agent inferenceborrow(uint256 amount) — onlyOwner
Borrows capacity from the pool. Repaid by capacity lock (no USDC payment).
harvest()
Permissionless. Pulls accumulated USDC from Pool and forwards it to YieldToken holders.
function harvest() external {
uint256 amount = pool.claim(); // claim from Pool
usdc.transfer(address(yieldToken), amount);
yieldToken.receiveYield(amount); // update YT accumulator
}Anyone can call harvest() — it only benefits YieldToken holders and costs the caller gas.
Lock-by-design
AgentToken has no requestExit() path. It can call pool.enterFor() but never pool.requestExit(). DIEM staked under AgentToken's address is permanently locked, which means the agent's capacity in Pool only grows over time.
Dynamic pool reference
pool is read via IFactory(factory).pool() on every call, not cached. If the Kairence Pool is upgraded, only the Factory needs to be updated — existing AgentToken contracts continue to work without redeployment.