Skip to main content

Funding Journey

How capital enters the Green Goods system. Two parallel mechanisms — the principal-preserving Octant Vault (yield-bearing ERC-4626) and the Cookie Jar (direct grant pool with on-chain access policy) — and one cross-cutting binding to Hypercerts for impact-purchase markets.

Personas

  • D: Funder (Capital Provider) — primary subject. Either a public supporter (Public Fund page) or an operator-funder hybrid using the admin dashboard.
  • B: Operator — administers vault parameters, cookie jar policies, yield split config; does not deposit on behalf of funders.

State machine

Entry points

EntrySurfaceTrigger
Public PWApackages/client/src/views/Public/Fund.tsxAnyone visiting /fund (no login required to browse; AppKit modal on deposit click)
Admin Garden / Vaultpackages/admin/src/views/Garden/Vault.tsxOperator-funder picks a garden, opens Vault tab
Admin Hub / Cookie Jarpackages/admin/src/views/Hub/components/CookieJarDepositModal.tsx, CookieJarManageModal.tsx, CookieJarPayoutPanel.tsxOperator opens cookie jar modals from Hub workspace
Admin Garden / Strategiespackages/admin/src/views/Garden/Strategies.tsx, SignalPool.tsxOperator configures yield split + conviction strategy

Steps

Vault deposit (Persona D)

#StatePersonaSurface (package + view)Hook / ServiceSide effectsStatus
1BrowsingDclient / views/Public/FunduseGardens, useUserAggregate stats: gardens count, gardener countshipped
2ChoosingGarden + ChoosingChannelDclient / views/Public/Fundlocal state activeDialogWallet not yet connected — useAppKit().open() if no primaryAddressshipped
3ApprovingToken (if needed)Dclient / components/Dialogs/VaultDepositDialoguseVaultDeposit, useMarketplaceApprovals (for hypercerts)ERC-20 approve(vault, amount)shipped
4DepositingDsameuseVaultDeposit, useVaultOperationsvault.deposit(assets, receiver) — vault is ERC-4626 (OctantVault)shipped
5SharesMinted(chain)EVMn/aVault mints shares to receiver, emits Deposit eventshipped
6Indexed(system)Envioevent handlersUpdates GardenVault.totalDeposited, VaultDeposit.shares, creates VaultEvent { eventType: DEPOSIT }shipped
7UI invalidationDclient/adminuseDelayedInvalidation (~2s)Funder sees updated balance + success toastshipped
#StatePersonaSurface (package + view)Hook / ServiceSide effectsStatus
8Configure jarBadmin / views/Hub/components/CookieJarManageModaluseCookieJarAdminSets payout policy, allowlist, and amountsshipped
9Fund jarDclient / views/Public/Fund (CookieJarDepositDialog) or admin / views/Hub/components/CookieJarDepositModaluseCookieJarDepositFunder transfers assets into the jar contractshipped
10Withdraw / payoutBadmin / views/Hub/components/CookieJarPayoutPanel, CookieJarWithdrawModaluseCookieJarWithdraw, useUserCookieJars, useAccessibleCookieJarsTriggers an authorized withdraw against the jar policyshipped

Yield split + conviction (Persona B)

#StatePersonaSurface (package + view)Hook / ServiceSide effectsStatus
11Set split configBadmin / views/Garden/StrategiesuseSplitConfig, useSetConvictionStrategiesThree-way split between cookieJarAmount / fractionsAmount / juiceboxAmountshipped
12Set decay / points-per-voterBsameuseSetDecay, useSetPointsPerVoterConviction parameters tracked on-chain via Gardens V2shipped
13Surface yield to funderDadmin / views/Garden/Vault (PositionCard), admin / views/Community/PayoutsuseFunderLeaderboard, useGardenYieldSummary, usePendingYield, useHarvestableYieldRead from YieldAllocation indexer entityshipped

Hypercert listing (impact purchase market)

#StatePersonaSurface (package + view)Hook / ServiceSide effectsStatus
14Operator lists hypercert for yieldB(no dedicated view yet — workflow lives in shared hook)useCreateListing, useBatchListForYield, useMarketplaceApprovalsMarketplace approval + listing txshipped
15Octant Vault auto-buysD / systemn/aaspirationalSpec § 3.3 calls for Octant Vault to use yield to purchase listed hypercerts; automation not in codebaseaspirational
16Karma GAP reportDpartial — Garden.gapProjectUID field on indexermanual linkageSpec § 3.1 calls for "automated Karma GAP report showing yield utilization" — automated reporting not builtpartial

Failure / recovery paths

  • Allowance insufficient. useVaultOperations.deposit() checks allowance first (see sequence diagram). Triggers ERC-20 approve before deposit. If the user rejects approval, deposit aborts cleanly.
  • Vault paused. useEmergencyPause flips paused flag on the indexer entity. UI surfaces "Vault paused" alert via useGardenVaults.
  • Cookie jar policy reject. Withdraw call reverts when the requester is not in the allowlist or the rate-limit clock has not elapsed. parseContractError extracts the resolver-defined revert reason.
  • Public path: wallet not connected. Fund.tsx handleOpenDialog opens AppKit modal first; deposit dialog only opens once primaryAddress is present.
  • Tx submitted offline. Funding deposits do not go through the gardener job queue. Funders must be online; otherwise wallet returns a connection error directly.
  • Indexer lag. useDelayedInvalidation (~2s) hides the lag for the depositor's own row. Cross-user views may show stale TVL until the indexer catches up.

Connections

  • Upstream: Onboarding — Persona D arrives via wallet connect (AppKit), reuses the same useAuth flow. No passkey path for funders today.
  • Downstream: Harvest — vault yield is the substrate that feeds hypercert minting and yield distribution.
  • Sequence diagram: Funding deposit flow.

Notes for builders

  • Vault is ERC-4626; never assume 1:1 share-to-asset. Always use previewDeposit / previewWithdraw (see useVaultPreview).
  • Cookie Jar is not indexed by Envio — cookie jar reads come directly from RPC via useGardenCookieJars / useUserCookieJars. Do not add cookie jar entities to schema.graphql.
  • Public fund page is deposit-only by ADR D37. Withdraws happen in the admin surface; the public page intentionally does not surface them to keep the funder JTBD focused.
  • The yield 3-way split is configured per-garden, not per-vault. See useSplitConfig and YieldAllocation indexer entity (cookieJarAmount / fractionsAmount / juiceboxAmount).
  • Octant Vault auto-buy and automated Karma GAP reports are spec-level requirements without shipped automation — flag explicitly in any PR that claims "completes funding journey."