Skip to content

Pool

contracts/src/core/Pool.sol

The central staking and capacity contract. Users deposit DIEM, which is forwarded to Vault and staked with Venice. The Pool tracks shares and distributes USDC revenue from capacity sales.

Key state

solidity
mapping(address => uint256) public shares;          // total DIEM staked per user
uint256 public totalShares;
uint256 public activeShares;                        // staged shares excluded

mapping(address => uint256) public reserved;        // personal capacity reservation
uint256 public totalReserved;

mapping(address => mapping(uint256 => uint256)) public purchased;  // [user][day]
mapping(address => mapping(uint256 => uint256)) public borrowed;   // [user][day]
mapping(address => uint64)  public capacityChangedAt;              // staleness signal

uint256 public sellPerShare;                        // USDC accumulator (* PRECISION)

Functions

enter(uint256 amount)

Deposits amount DIEM into the pool. DIEM is pulled from msg.sender directly into the vault (no double-hop). Shares are staged for one day before becoming active.

solidity
pool.enter(1000e18);

enterFor(address recipient, uint256 amount)

Same as enter() but DIEM is pulled from msg.sender (e.g. AgentHook) and shares are credited to recipient (e.g. AgentToken contract). Used by the V4 hook to permanently lock buy-side LP fees under the agent's address.

solidity
// Called by AgentHook with buy-side DIEM fees
pool.enterFor(agentToken, feeAmount);

reserve(uint256 newReserve)

Sets the personal capacity reservation. Reserved capacity is withheld from the pool's free capacity and tracked by the gateway as the user's Venice inference quota.

  • Increasing reserve reduces freePoolCapacity().
  • Decreasing reserve releases capacity back to the pool.
  • Updates capacityChangedAt[msg.sender] so the gateway knows to re-sync.
solidity
pool.reserve(500); // reserve 500 DD for personal inference

purchase(uint256 amount)

Buys amount DD of inference capacity by paying USDC (1 USDC per 1 DD, stub pricing). Revenue distributes to all active stakers via sellPerShare. Updates capacityChangedAt.

borrow(uint256 amount)

Takes amount DD of capacity immediately. Repaid by committing capacity for amount * (1 + interestBps/10000) / effectiveShares days — no USDC payment required. On re-borrow, outstanding debt is merged and the lock period extended.

requestExit(uint256 amount)

Queues an unstake request. If the caller has an active loan, they must first pay the remaining debt in USDC (distributed to pool via sellPerShare). Returns requestDay for use in claimExit().

claimExit(uint64 requestDay)

Claims matured DIEM after the Venice cooldown (~24h). Delegates to vault.claimExit().

claim() → uint256

Collects accumulated USDC from capacity sales. Settles the sellPerShare accumulator for msg.sender and transfers the result.

View functions

FunctionReturns
capacityToday(address user)reserved + purchased[today] + borrowed[today]
effectiveShares(address user)Active shares minus reserve — yield and pool-sale basis
freePoolCapacity()activeShares - totalDailyRepay - totalReserved
pendingEarnings(address user)Unsettled USDC from sellPerShare
remainingDebt(address user)Outstanding borrow debt in DD

Staged entry detail

Day 0: enter(X)
  → shares[user] += X
  → stagedShares[user] = X
  → stagedOnDay[day0] += X
  → activeShares unchanged

Day 1: _advanceDays() runs
  → activeShares += stagedOnDay[day0]
  → user's shares are now active

Accumulator (MasterChef)

sellPerShare grows when purchase() is called:
  sellPerShare += usdcPaid * PRECISION / _yieldBase()

_yieldBase() = activeShares - totalReserved

User's pending USDC:
  pending = effectiveShares(user) * (sellPerShare - userSellPerShare[user]) / PRECISION

Released under the MIT License.