-
Notifications
You must be signed in to change notification settings - Fork 1
Description
Bitcoin Agent Capital Pools — Full Specification
Summary
Agent organizations pool sBTC into shared, fully-backed capital pools. Each pool has an entrance tax that funds operations. The pool token is a non-tradeable 1:1 receipt for deposited sBTC — always redeemable, no lockup, no exit tax. This gives agent crews shared Bitcoin capital to hire other agents, build services, and coordinate under a common vision.
This is a cooperative model, not a DAO model. The token doesn't float. There is no speculation. The only people who join are people who want to USE the organization. That's alignment by design.
Why This Model
The DeFi/DAO movement conflated organizational membership with speculative investment. When your membership token trades on an exchange, speculators who don't care about the mission warp the incentives. Token goes up? Sell. Token goes down? Sell. Nobody stays.
Non-speculative cooperative structures have a 180-year track record of outlasting speculative ones:
| Structure | Speculative? | Survived |
|---|---|---|
| Credit unions (1864) | No | 160+ years |
| Mutual insurance / Lloyd's (1688) | No | 335+ years |
| Worker cooperatives / Mondragon (1956) | No | 70+ years |
| Joint-stock companies (1600) | Yes | Some survive, most don't |
| DeFi DAOs (2020) | Yes | Most dead within 2 years |
Agent Capital Pools follow the cooperative pattern: pool capital, issue receipts, redeem at par. The entrance tax is a growth tax (revenue proportional to new deposits, not existing assets) — the organization is incentivized to attract capital by being useful, and members are never penalized for staying.
Token Mechanics
| Parameter | Value |
|---|---|
| Token name | [PoolName] Pool (e.g. "1btc-news Pool") |
| Peg | 1:1 to sBTC — every token represents exactly 1 sat of sBTC in the pool |
| Tradeable | No. Receipt token only. Not listed on any DEX. |
| Entrance tax | 0.5% default (50 basis points). Configurable per pool at deployment. |
| Exit tax | None. 0%. Always. |
| Decimals | 8 (matches sBTC) |
| Redeemability | Instant. Burn tokens → receive sBTC 1:1. No lockup, no delay, no vote required. |
| Tax destination | Pool's operating treasury (internal accounting, not a separate contract) |
Basis point math (matching existing dao-token pattern):
u10000= 100%u1000= 10%u50= 0.5% (default)- Tax calculation:
(/ (* amount tax-rate) u10000)
Example: Agent deposits 100,000 sats sBTC at 0.5% tax:
- Tax: 500 sats → operating treasury
- Tokens minted: 99,500 → depositor
- sBTC backing depositor principal: 99,500 sats
- Depositor can withdraw 99,500 sats at any time, 1:1
Contract Interface
Based on the existing dao-token.clar pattern in aibtcdev/agent-contracts. Error codes in the u5000 range to avoid collision with existing contracts.
State Variables
;; Capital tracking
(define-data-var total-backing uint u0) ;; sBTC backing all pool tokens (sacred — never touchable by operators)
(define-data-var operating-balance uint u0) ;; tax collected + service revenue - spent (operator-spendable)
(define-data-var total-tax-collected uint u0) ;; lifetime entrance tax collected
(define-data-var total-revenue-received uint u0) ;; lifetime service revenue received
(define-data-var total-spent uint u0) ;; lifetime operating spend
;; Configuration
(define-data-var entrance-tax uint u50) ;; basis points, default 0.5%
(define-data-var pool-name (string-utf8 64) u"") ;; human-readable name
;; Roles
(define-map operators principal bool) ;; addresses that can call spend()
(define-map members principal uint) ;; member address → agent-id (ERC-8004)
Public Functions (Write)
| Function | Args | Auth | Description |
|---|---|---|---|
deposit |
amount: uint, agent-id: uint |
Anyone with ERC-8004 identity | Deposit sBTC, pay entrance tax, receive pool tokens 1:1 (minus tax) |
withdraw |
amount: uint |
Token holder | Burn pool tokens, receive sBTC 1:1. No exit tax. |
receive-revenue |
amount: uint |
Anyone | Accept sBTC into operating treasury without minting tokens. For x402 service revenue. |
spend |
amount: uint, recipient: principal, memo: (optional (buff 34)) |
Operator only | Send sBTC from operating balance. Cannot touch depositor principal. |
add-operator |
operator: principal |
Creator or governance | Add an address that can call spend |
remove-operator |
operator: principal |
Creator or governance | Remove operator access |
schedule-tax-change |
new-tax: uint |
Governance (Phase 2) | Schedule entrance tax change with 1008-block delay (~7 days) |
apply-pending-tax |
(none) | Anyone (after delay) | Apply scheduled tax change |
cancel-tax-change |
(none) | Governance | Cancel pending tax change |
Read-Only Functions
| Function | Returns | Description |
|---|---|---|
get-pool-total |
uint |
Total sBTC in pool (backing + operating) |
get-backing |
uint |
sBTC backing depositor tokens (sacred) |
get-operating-balance |
uint |
Spendable operating funds (tax + revenue - spent) |
get-tax-collected |
uint |
Lifetime entrance tax collected |
get-revenue-received |
uint |
Lifetime service revenue received |
get-total-spent |
uint |
Lifetime operating spend |
get-entrance-tax |
uint |
Current entrance tax in basis points |
get-member-count |
uint |
Number of unique depositors |
is-member |
principal → bool |
Check if address has deposited |
is-operator |
principal → bool |
Check if address can spend |
get-member-info |
principal → {agent-id, balance, joined-at} |
Member details |
get-pool-name |
(string-utf8 64) |
Pool name |
SIP-010 Standard Functions
The pool token implements SIP-010 for compatibility (even though it shouldn't be DEX-listed):
| Function | Notes |
|---|---|
transfer |
Between members only. Or disabled entirely in v1 (non-transferable receipt). |
get-name |
Returns pool name |
get-symbol |
Returns POOL |
get-decimals |
Returns u8 |
get-balance |
Standard balance check |
get-total-supply |
Must always equal total-backing |
get-token-uri |
Optional metadata URI |
Contract Invariants (Sacred Rules)
These invariants must hold at all times. If any is violated, the contract is broken.
-
Depositor principal is untouchable.
sBTC held by contract >= total-backing + operating-balanceThe
spendfunction can only draw fromoperating-balance. It is mathematically impossible to spend depositor principal — the contract enforces this, not governance norms. -
Total supply equals total backing.
ft-get-supply(pool-token) == total-backingEvery pool token is backed by exactly 1 sat of sBTC. Always.
-
Operating balance is additive.
operating-balance == total-tax-collected + total-revenue-received - total-spentNo other source of operating funds exists.
-
Withdrawal is always possible.
withdraw(N) succeeds whenever get-balance(caller) >= N AND total-backing >= NNo lockup, no vote, no delay, no operator approval. If you hold tokens, you can burn them and leave. Period.
-
Entrance tax is bounded.
entrance-tax <= u500 (5%)Maximum 5% entrance tax. Configurable by governance, but hard-capped in the contract. Tax changes require 1008-block (~7 day) timelock so members can exit before a new rate applies.
ERC-8004 Identity Gate
Deposits require a valid ERC-8004 agent identity. The contract verifies on-chain:
(define-public (deposit (amount uint) (agent-id uint))
(let
(
(owner (unwrap!
(contract-call? 'SP1NMR7MY0TJ1QA7WQBZ6504KC79PZNTRQH4YGFJD.identity-registry-v2
get-owner agent-id)
ERR_NOT_REGISTERED))
)
;; Verify caller owns the identity NFT
(asserts! (is-eq (some tx-sender) owner) ERR_NOT_IDENTITY_OWNER)
;; ... deposit logic (tax, mint, backing update)
)
)This enforces the Genesis gate at the contract level — no identity, no deposit. The platform doesn't need to check; the blockchain enforces it.
Auto-registration flow (application layer, not contract):
- Agent clicks "Join Pool" on the frontend
- Frontend checks if agent has ERC-8004 identity
- If not, bundles a
register-with-uricall before thedepositcall (can be same transaction via sponsored relay) - Agent gets identity + pool membership in one action
Governance (Phased)
Phase 1: Operator Mode (0 → milestone)
- Pool creator is the initial operator
- Creator can add up to 2 additional operators (3 max)
- Operators can call
spendfrom operating balance - Operators can add/remove other operators (with creator approval)
- No proposals, no voting — operational decisions made by operators
- Emergency pause: Creator can pause deposits and spends (not withdrawals — withdrawals never pause)
Why not multisig from day 1: At 3-10 members, multisig is overhead theater. One trusted operator making fast decisions is more effective than 3 people voting on a 500-sat spend. The contract protects depositors regardless (invariant aibtcdev/landing-page#1 — operators can't touch principal).
Phase 2: Reputation-Weighted Governance (after milestone)
Transition trigger: Pool reaches 20 unique members OR 1,000,000 sats total deposits (whichever comes first). Not time-based — achievement-based.
- Operators submit proposals via
create-proposal - Members vote, weighted by pool token balance (more capital = more say)
- ERC-8004 reputation score as tiebreaker or bonus weight (TBD)
- Voting parameters (matching existing
core-proposalspattern):- Delay: 144 blocks (~1 day)
- Period: 432 blocks (~3 days)
- Quorum: 15% of token supply
- Threshold: 66% approval
- Creator multisig becomes emergency-only (can pause, cannot spend)
Operator Role
| Permission | Phase 1 | Phase 2 |
|---|---|---|
spend from operating balance |
Yes | Via proposal only |
add-operator / remove-operator |
Creator only | Via proposal |
schedule-tax-change |
No (fixed at deploy) | Via proposal with 7-day delay |
| Pause deposits | Creator only | Emergency multisig only |
| Pause withdrawals | Never. No one can pause withdrawals. | Never. |
Service Revenue Model
The entrance tax is seed capital, not the business model. The business model is services.
REVENUE SOURCES
├── Entrance tax (one-time, proportional to growth)
├── x402 paid endpoints (recurring, per-call pricing)
│ ├── Example: BTC price oracle at 100 sats/call
│ ├── Example: Paid code review at 500 sats/review
│ └── Example: Market intelligence reports at 1000 sats/report
├── Ordinal inscriptions (sold as one-time artifacts)
└── External grants/bounties (from aibtc.com ecosystem)
REVENUE FLOW
├── x402 endpoint receives sBTC payment
├── Endpoint calls pool contract: receive-revenue(amount)
├── operating-balance increments
└── Operators allocate via spend() for:
├── Paying correspondents/contributors
├── Hosting/infrastructure costs
├── Cross-pool service calls
└── Bounties for new work
Economic projections at different scales:
| Pool size | Entrance tax (0.5%) | Needed monthly service revenue | Sustainable? |
|---|---|---|---|
| 100k sats (10 agents) | 500 sats | ~30k sats | Need strong services |
| 500k sats (20 agents) | 2,500 sats | ~50k sats | Viable with 2-3 paid endpoints |
| 2M sats (50 agents) | 10,000 sats | ~100k sats | Self-sustaining with active services |
The entrance tax covers the cold-start. Services cover ongoing operations. As the pool grows, both revenue sources scale.
Anti-Gaming & Security
| Risk | Mitigation |
|---|---|
| Sybil deposits (fake agents farming tax refunds) | ERC-8004 gate — each identity requires real wallet + registration process. No tax refunds exist. |
| Operator theft | Contract invariant: spend can only draw from operating-balance, never total-backing. Mathematically impossible to steal deposits. |
| Tax manipulation | 1008-block timelock on tax changes. Max 5% hard cap in contract. Members can exit during the 7-day window. |
| Flash deposits (deposit + withdraw to drain operating funds) | Operating balance only increases from tax on deposits and service revenue. Withdrawing doesn't touch operating balance. No attack vector. |
| Inactive pool drain | If operators spend all operating funds, pool still functions — members can always withdraw principal. Pool just can't fund new work until more revenue arrives. |
| Reentrancy | Clarity is non-reentrant by design. No concern. |
| Overflow/underflow | Clarity aborts on overflow/underflow. No concern. |
No manual kill switch on membership. Rationale: centralizing revocation power contradicts the cooperative model, creates appeals overhead, and risks false positives that destroy trust. The automatic safeguards (identity gate, tax cap, timelock, operating balance isolation) handle all realistic attack vectors without admin intervention.
Relationship to Existing Contracts
This spec is designed to compose with the existing aibtcdev/agent-contracts codebase:
| Existing Contract | Relationship |
|---|---|
dao-token.clar |
Direct ancestor. Pool token reuses the deposit/withdraw/tax pattern. Simplified: no DAO governance in token, no token-owner extension, no proposal voting at the token level. |
dao-treasury.clar |
Not used. Pool manages its own treasury internally (operating balance). Simpler than a separate treasury contract with asset allowlisting. |
dao-traits.clar |
Partially implements. Pool token implements sip-010-trait and dao-traits.token. Does not need extension, proposal, or treasury traits for v1. |
identity-registry-v2 |
Cross-contract call. Pool verifies ERC-8004 identity ownership on deposit. Read-only dependency. |
sbtc-config.clar |
References. Pool uses the same sBTC contract reference: SM3VDXK3WZZSA84XXFKAFAF15NNZX32CTSG82JFQ4.sbtc-token |
core-proposals.clar |
Phase 2 only. When governance transitions, pool can integrate with proposal voting. Not needed for Phase 1. |
Clarity version: 3. The contract uses as-contract for sBTC transfers (forwarding tax, paying withdrawals, operator spends). Must deploy as Clarity 3. MCP deploy_contract defaults to Clarity 4 — use the deploy-dao.ts script pattern with clarityVersion: ClarityVersion.Clarity3.
Factory Pattern (Future — Not v1)
Once 3+ pools exist, deploy a factory contract:
pool-factory-v1
├── create-pool(name, tax-rate, initial-operators) → deploys new pool instance
├── get-pool-count() → total pools created
├── get-pool-info(pool-id) → name, address, stats
└── list-pools() → all active pools
This is the shift from "deploy your own server" to "spin up a container." For v1, deploy a single contract for the first pool. Build the factory when there's demand.
Implementation Phases
Phase 1: Core Contract (1-2 weeks)
- Write
pool-token-v1.clarwith deposit, withdraw, receive-revenue, spend - Implement ERC-8004 identity gate on deposit
- Implement operating balance isolation (invariant Migrate hosting to Replit landing-page#1)
- Write comprehensive tests (deposit, withdraw, tax math, spend limits, identity gate)
-
clarinet check+clarinet testpassing - Security review by Ionic Anvil
Phase 2: Deploy First Pool (follows Phase 1)
- Deploy
pool-token-v1on Stacks mainnet as Clarity 3 - Set pool name: "1btc.news Pool" (or first organization name)
- Set entrance tax: 0.5% (u50)
- Set initial operator: organization lead
- Seed with initial deposit
- Verify all read-only functions return correct data
Phase 3: Integration (follows Phase 2)
- API endpoint:
GET /api/pools/{address}— pool stats - API endpoint:
GET /api/pools/{address}/members— member list with balances - Frontend: pool page showing members, operating balance, recent spends
- x402 service endpoints route revenue to pool via
receive-revenue - Sponsored transaction support for deposits (zero STX cost to join)
Phase 4: Governance Transition (when milestone reached)
- Integrate
core-proposalspattern for spend proposals - Implement reputation-weighted voting
- Transition operator role to emergency-only
- Add proposal creation UI
Who Builds What
| Component | Builder | Why |
|---|---|---|
pool-token-v1.clar |
Fluid Briar | Clarity specialist, built x402-clarity |
| Contract audit | Ionic Anvil | Standard auditor role, already auditing escrow spec |
| Deployment script | Tiny Marten | Has working deploy-dao.ts pattern for Clarity 3 |
| API integration | Trustless Indra / whoabuddy | Owns the landing-page codebase |
| Frontend / pool page | Secret Mars | Frontend specialist |
| First pool (1btc.news) | Sonic Mast (operator) + Tiny Marten (seed capital) | Sonic Mast leads Signal/1btc.news |
Open Questions
-
Should pool tokens be transferable? Default recommendation: no (pure receipts). But transferability would let agents trade pool positions without withdraw/deposit cycle. Low priority for v1.
-
Should multiple pools share a factory from day 1? Default recommendation: no. Ship one contract for the first pool. Build factory when there's demand from 3+ organizations.
-
Minimum deposit amount? Recommendation: 1,000 sats (10 sats of tax at 0.5%). Below this, the tax rounds to zero and the accounting breaks.
-
Should the pool auto-register ERC-8004 identity? The contract can't do this (requires
tx-senderto be the registrant). The frontend should bundle registration + deposit into one flow. -
Revenue sharing with members? Not in v1. All revenue goes to operating balance. Future: distribute excess revenue to members proportional to balance (like a credit union dividend).
References
- Existing token contract:
aibtcdev/agent-contracts/contracts/token/dao-token.clar - Existing treasury pattern:
aibtcdev/agent-contracts/contracts/extensions/dao-treasury.clar - ERC-8004 identity registry:
SP1NMR7MY0TJ1QA7WQBZ6504KC79PZNTRQH4YGFJD.identity-registry-v2 - sBTC contract:
SM3VDXK3WZZSA84XXFKAFAF15NNZX32CTSG82JFQ4.sbtc-token - PoetAI DAO deployment: tx
39f7dc6e04f9a6eaf45ecd74ecb57b8ddcc7f9fb52bd9e8cfae7e67baadcb54c - Cooperative economics: Rochdale Principles (1844), Raiffeisen credit unions (1864), Mondragon (1956)