Appearance
Overview
Pasanaku is a single Vyper contract that runs fixed-membership rotating savings pools against one immutable ERC-20 asset and one immutable ERC-4626 vault. Vault shares are the canonical collateral unit.
Say “six-participant pasanaku” or “twelve-participant pasanaku.” Do not describe size as a continuous range between six and twelve.
Deployment model
Each deployed instance binds:
| Immutable | Role |
|---|---|
_ASSET | Underlying ERC-20 for round deposits and payouts |
_VAULT | ERC-4626 vault that holds collateral shares |
The constructor requires vault.asset() == asset. Pools do not choose assets or vaults. Many pools can run concurrently on the same instance; token_id scopes locked shares, reserve, escrow, and payouts.
What a pasanaku is
A pasanaku is a Pasanaku struct keyed by token_id:
round_assets— per-round obligation in raw asset unitsparticipant_count— exactly6or12participants— roster; after start, indexkis the recipient of roundkindex— next round fortickcreated/stale_time— pending-pool lifetimeyield_fee— fee bps snapshotted at createstarted/updated/ended— lifecycle timestamps (0means unset)
Lifecycle
mermaid
flowchart TD
deposit[deposit free shares] --> create[create_pasanaku]
create --> join[join_pasanaku]
join -->|roster full| start[_start_pasanaku]
join -->|stale| leave[leave_pasanaku]
start --> roundDep[deposit_to_pasanaku]
roundDep --> tickFn[tick]
tickFn --> claim[claim_round_payout]
tickFn -->|last round| endSettle[_end_pasanaku]- Users
depositunderlying; the contract vaults it and credits free shares. - A creator calls
create_pasanaku(round_assets, participant_count)and locks a pledge. - Others
join_pasanakuuntil the roster fills, which calls_start_pasanaku. - Each round, obligors (everyone except the current recipient) fund exactly
round_assetsviadeposit_to_pasanaku. - After
_MIN_TIME_INTERVAL(28 days) from the last tick or start, anyone maytick. - The recipient
claim_round_payoutpulls accrued assets. Unclaimed payouts do not block later ticks. - The final tick runs
_end_pasanaku: principal return, reserve shortfall cover, yield fee accrual, weighted surplus distribution.
Accounting layers
Two ledgers coexist:
Vault shares (owned by the contract)
text
vault.balanceOf(Pasanaku)
= all free shares
+ all locked shares
+ all pool reserve sharesLiquid underlying (held by the contract)
_pool_escrow[token_id]— current-round contributions / slash recoveries_pending_payout[token_id][round_idx]— claimable recipient balances
Escrow and pending payouts are outside the share invariant.
Yield boundary
Pool yield accounting begins at _start_pasanaku, not at create or join. Pre-start vault appreciation or loss is normalized into free shares when the pool starts. After start, locked-share appreciation is pooled surplus at end settlement.
See also
- Domain guardrails: repository
CONTEXT.md - Unitary lifecycle coverage:
tests/unitary/pasanaku/test_lifecycle.py