From 860bf566c3cdf0cd28773f2dda5954ee5d140d70 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 27 May 2026 14:57:32 +0000 Subject: [PATCH 1/4] Initial plan From 74815e46ba2c4dd4ea8ab160808e498dfdcc036f Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 27 May 2026 15:03:28 +0000 Subject: [PATCH 2/4] chore: outline goodreserve-widget implementation plan --- .agents/skills/gooddollar/CONTRIBUTING.md | 121 ++ .agents/skills/gooddollar/SKILL.md | 215 ++++ .../contracts/BuyGDCloneFactory.abi.yaml | 205 ++++ .../BuyGDCloneFactory.selectors.yaml | 27 + .../contracts/BuyGDCloneV2.abi.yaml | 282 +++++ .../contracts/BuyGDCloneV2.selectors.yaml | 36 + .../contracts/CFAv1Forwarder.abi.yaml | 237 ++++ .../contracts/CFAv1Forwarder.selectors.yaml | 19 + .../ConstantFlowAgreementV1.abi.yaml | 560 +++++++++ .../ConstantFlowAgreementV1.selectors.yaml | 33 + .../contracts/GoodDollarOFTAdapter.abi.yaml | 100 ++ .../GoodDollarOFTAdapter.selectors.yaml | 12 + .../GooddollarSavingsStream.abi.yaml | 210 ++++ .../GooddollarSavingsStream.selectors.yaml | 27 + .../contracts/GovernanceStakingV2.abi.yaml | 202 ++++ .../GovernanceStakingV2.selectors.yaml | 26 + .../references/contracts/IdentityV3.abi.yaml | 390 +++++++ .../contracts/IdentityV3.selectors.yaml | 49 + .../references/contracts/IdentityV4.abi.yaml | 424 +++++++ .../contracts/IdentityV4.selectors.yaml | 51 + .../references/contracts/InvitesV2.abi.yaml | 333 ++++++ .../contracts/InvitesV2.selectors.yaml | 41 + .../references/contracts/MentoBroker.abi.yaml | 259 +++++ .../contracts/MentoBroker.selectors.yaml | 24 + .../contracts/MessagePassingBridge.abi.yaml | 542 +++++++++ .../MessagePassingBridge.selectors.yaml | 52 + .../references/contracts/NameService.abi.yaml | 104 ++ .../contracts/NameService.selectors.yaml | 11 + .../references/contracts/SuperToken.abi.yaml | 1033 +++++++++++++++++ .../contracts/SuperToken.selectors.yaml | 99 ++ .../references/contracts/Superfluid.abi.yaml | 757 ++++++++++++ .../contracts/Superfluid.selectors.yaml | 51 + .../references/contracts/UBISchemeV2.abi.yaml | 305 +++++ .../contracts/UBISchemeV2.selectors.yaml | 40 + .../contracts/_rich-abi-yaml-format.md | 93 ++ .../deep-researches/faucet-flows.md | 42 + .../fuse-to-celo-staking-migration.md | 38 + .../gooddao-daostack-surface.md | 37 + .../deep-researches/how-ubi-is-minted.md | 68 ++ .../inviter-invitee-reward-model.md | 58 + .../mento-reserve-economics.md | 27 + .../deep-researches/on-off-ramp-service.md | 69 ++ .../gooddollar/references/guides/bridge.md | 187 +++ .../references/guides/check-identity.md | 87 ++ .../gooddollar/references/guides/claim.md | 83 ++ .../gooddollar/references/guides/faucet.md | 76 ++ .../gooddollar/references/guides/gooddocs.md | 37 + .../gooddollar/references/guides/goodsdks.md | 110 ++ .../references/guides/hypersync-hyperrpc.md | 110 ++ .../references/guides/invite-bounties.md | 115 ++ .../migrate-fuse-staking-to-celo-savings.md | 116 ++ .../references/guides/on-off-ramp.md | 77 ++ .../gooddollar/references/guides/save.md | 93 ++ .../gooddollar/references/guides/stream.md | 135 +++ .../gooddollar/references/guides/swap.md | 83 ++ .../references/subgraphs/_query-patterns.md | 35 + .../subgraphs/goodcollective-guide.md | 54 + .../subgraphs/goodcollective.graphql | 200 ++++ .../subgraphs/gooddollar-celo-guide.md | 104 ++ .../subgraphs/gooddollar-celo.graphql | 113 ++ .../subgraphs/reserve-celo-guide.md | 41 + .../references/subgraphs/reserve-celo.graphql | 90 ++ skills-lock.json | 11 + 63 files changed, 9266 insertions(+) create mode 100644 .agents/skills/gooddollar/CONTRIBUTING.md create mode 100644 .agents/skills/gooddollar/SKILL.md create mode 100644 .agents/skills/gooddollar/references/contracts/BuyGDCloneFactory.abi.yaml create mode 100644 .agents/skills/gooddollar/references/contracts/BuyGDCloneFactory.selectors.yaml create mode 100644 .agents/skills/gooddollar/references/contracts/BuyGDCloneV2.abi.yaml create mode 100644 .agents/skills/gooddollar/references/contracts/BuyGDCloneV2.selectors.yaml create mode 100644 .agents/skills/gooddollar/references/contracts/CFAv1Forwarder.abi.yaml create mode 100644 .agents/skills/gooddollar/references/contracts/CFAv1Forwarder.selectors.yaml create mode 100644 .agents/skills/gooddollar/references/contracts/ConstantFlowAgreementV1.abi.yaml create mode 100644 .agents/skills/gooddollar/references/contracts/ConstantFlowAgreementV1.selectors.yaml create mode 100644 .agents/skills/gooddollar/references/contracts/GoodDollarOFTAdapter.abi.yaml create mode 100644 .agents/skills/gooddollar/references/contracts/GoodDollarOFTAdapter.selectors.yaml create mode 100644 .agents/skills/gooddollar/references/contracts/GooddollarSavingsStream.abi.yaml create mode 100644 .agents/skills/gooddollar/references/contracts/GooddollarSavingsStream.selectors.yaml create mode 100644 .agents/skills/gooddollar/references/contracts/GovernanceStakingV2.abi.yaml create mode 100644 .agents/skills/gooddollar/references/contracts/GovernanceStakingV2.selectors.yaml create mode 100644 .agents/skills/gooddollar/references/contracts/IdentityV3.abi.yaml create mode 100644 .agents/skills/gooddollar/references/contracts/IdentityV3.selectors.yaml create mode 100644 .agents/skills/gooddollar/references/contracts/IdentityV4.abi.yaml create mode 100644 .agents/skills/gooddollar/references/contracts/IdentityV4.selectors.yaml create mode 100644 .agents/skills/gooddollar/references/contracts/InvitesV2.abi.yaml create mode 100644 .agents/skills/gooddollar/references/contracts/InvitesV2.selectors.yaml create mode 100644 .agents/skills/gooddollar/references/contracts/MentoBroker.abi.yaml create mode 100644 .agents/skills/gooddollar/references/contracts/MentoBroker.selectors.yaml create mode 100644 .agents/skills/gooddollar/references/contracts/MessagePassingBridge.abi.yaml create mode 100644 .agents/skills/gooddollar/references/contracts/MessagePassingBridge.selectors.yaml create mode 100644 .agents/skills/gooddollar/references/contracts/NameService.abi.yaml create mode 100644 .agents/skills/gooddollar/references/contracts/NameService.selectors.yaml create mode 100644 .agents/skills/gooddollar/references/contracts/SuperToken.abi.yaml create mode 100644 .agents/skills/gooddollar/references/contracts/SuperToken.selectors.yaml create mode 100644 .agents/skills/gooddollar/references/contracts/Superfluid.abi.yaml create mode 100644 .agents/skills/gooddollar/references/contracts/Superfluid.selectors.yaml create mode 100644 .agents/skills/gooddollar/references/contracts/UBISchemeV2.abi.yaml create mode 100644 .agents/skills/gooddollar/references/contracts/UBISchemeV2.selectors.yaml create mode 100644 .agents/skills/gooddollar/references/contracts/_rich-abi-yaml-format.md create mode 100644 .agents/skills/gooddollar/references/deep-researches/faucet-flows.md create mode 100644 .agents/skills/gooddollar/references/deep-researches/fuse-to-celo-staking-migration.md create mode 100644 .agents/skills/gooddollar/references/deep-researches/gooddao-daostack-surface.md create mode 100644 .agents/skills/gooddollar/references/deep-researches/how-ubi-is-minted.md create mode 100644 .agents/skills/gooddollar/references/deep-researches/inviter-invitee-reward-model.md create mode 100644 .agents/skills/gooddollar/references/deep-researches/mento-reserve-economics.md create mode 100644 .agents/skills/gooddollar/references/deep-researches/on-off-ramp-service.md create mode 100644 .agents/skills/gooddollar/references/guides/bridge.md create mode 100644 .agents/skills/gooddollar/references/guides/check-identity.md create mode 100644 .agents/skills/gooddollar/references/guides/claim.md create mode 100644 .agents/skills/gooddollar/references/guides/faucet.md create mode 100644 .agents/skills/gooddollar/references/guides/gooddocs.md create mode 100644 .agents/skills/gooddollar/references/guides/goodsdks.md create mode 100644 .agents/skills/gooddollar/references/guides/hypersync-hyperrpc.md create mode 100644 .agents/skills/gooddollar/references/guides/invite-bounties.md create mode 100644 .agents/skills/gooddollar/references/guides/migrate-fuse-staking-to-celo-savings.md create mode 100644 .agents/skills/gooddollar/references/guides/on-off-ramp.md create mode 100644 .agents/skills/gooddollar/references/guides/save.md create mode 100644 .agents/skills/gooddollar/references/guides/stream.md create mode 100644 .agents/skills/gooddollar/references/guides/swap.md create mode 100644 .agents/skills/gooddollar/references/subgraphs/_query-patterns.md create mode 100644 .agents/skills/gooddollar/references/subgraphs/goodcollective-guide.md create mode 100644 .agents/skills/gooddollar/references/subgraphs/goodcollective.graphql create mode 100644 .agents/skills/gooddollar/references/subgraphs/gooddollar-celo-guide.md create mode 100644 .agents/skills/gooddollar/references/subgraphs/gooddollar-celo.graphql create mode 100644 .agents/skills/gooddollar/references/subgraphs/reserve-celo-guide.md create mode 100644 .agents/skills/gooddollar/references/subgraphs/reserve-celo.graphql create mode 100644 skills-lock.json diff --git a/.agents/skills/gooddollar/CONTRIBUTING.md b/.agents/skills/gooddollar/CONTRIBUTING.md new file mode 100644 index 0000000..ab855d3 --- /dev/null +++ b/.agents/skills/gooddollar/CONTRIBUTING.md @@ -0,0 +1,121 @@ +# Contributing to GoodSkills + +This repository is an AI skill pack. The goal of each update is to make agent behavior more reliable, more explicit, and easier to audit. + +## Update workflow + +1. Define the user-facing problem first. +2. For contract-related updates, add or update Rich ABI first (`references/contracts/*.abi.yaml`), then refresh selectors. +3. Decide the remaining artifact types: + - `references/guides/` for "what to do" + - `references/deep-researches/` for "why it works this way" + - `scripts/` for deterministic and repeatable execution +4. Update `SKILL.md` routing so the new artifact is discoverable. +5. Validate consistency (paths, naming, links, selectors, assumptions). + +If a change touches contract behavior, treat Rich ABI update/add as mandatory first step before guides, deep-research, or scripts. + +## Add or update a guide + +Use guides for execution playbooks and operator workflows. + +Required structure: + +- title and one-line usage trigger +- `## Goal` +- `## Required inputs` +- `## Execution flow` as numbered steps +- deterministic snippet when execution is non-trivial +- failure handling and output contract + +Guide rules: + +- prefer explicit pre-checks before state-changing actions +- include only one primary workflow per file +- use [GoodProtocol `releases/deployment.json`](https://github.com/GoodDollar/GoodProtocol/blob/master/releases/deployment.json) as the **only** source for contract addresses (rich ABI `meta.deployments` mirrors those rows); use GoodDocs for behavior and UX, not for resolving addresses; use on-chain `NameService.getAddress` only when the deployment documents the string key +- avoid implementation-deep theory; keep that in deep-research files + +After adding a guide: + +- add it to `SKILL.md` in `Guides` +- add an entry in `Use-case to guide map` + +## Add or update a deep-research note + +Use deep-research files for architecture, rationale, tradeoffs, and root-cause logic. + +Deep-research rules: + +- explain causality, not only API surfaces +- distinguish current behavior from legacy behavior +- link source contracts/docs for traceability +- keep language natural and decision-oriented + +Do not turn deep-research files into step-by-step runbooks; move operational steps into guides. + +## Add or update Rich ABI YAML + +Location: `references/contracts/`. + +For each contract: + +- create or update `Foo.abi.yaml` +- generate or refresh `Foo.selectors.yaml` +- include function-level notes for non-obvious behavior +- when `meta.deployments` lists concrete addresses, add **`creationBlock`** next to each **`address`** (placement: `references/contracts/_rich-abi-yaml-format.md`; using it as **`fromBlock`** for log or HyperSync fetches: `references/guides/hypersync-hyperrpc.md`) + +Minimum ABI documentation quality: + +- correct mutability, inputs, outputs +- access pattern (`owner`, `avatar`, `anyone`, etc.) where relevant +- emitted events and practical errors +- notes for routing/edge-case semantics + +Source-of-truth policy: + +- prefer canonical contract repos (GoodProtocol, GoodBridge, mento-core) +- avoid inferred behavior when source is unclear +- update notes when protocol behavior changed + +Selector generation: + +```bash +node scripts/selectors.mjs generate Foo.abi.yaml +``` + +## Add or update scripts + +Location: `scripts/`. + +Use scripts when: + +- a workflow is repeated +- deterministic output is needed +- manual querying is error-prone + +Script standards: + +- require inputs through env vars or explicit args +- fail loudly with actionable messages +- print structured output for easy reuse +- keep script intent narrow + +When a script supports a guide: + +- reference it from that guide +- document expected inputs and outputs in the guide + +## Naming and organization + +- use lowercase kebab-case for guides and deep-research files +- keep one topic per file +- avoid duplicate guidance across files +- prefer updating existing files over creating near-duplicates + +## Update checklist before merge + +- `SKILL.md` routing updated +- links resolve and point to public sources +- guides and deep-research files respect "what" vs "why" separation +- ABI + selectors pairs are in sync +- new behavior is reflected in notes where needed diff --git a/.agents/skills/gooddollar/SKILL.md b/.agents/skills/gooddollar/SKILL.md new file mode 100644 index 0000000..2d59116 --- /dev/null +++ b/.agents/skills/gooddollar/SKILL.md @@ -0,0 +1,215 @@ +--- +name: gooddollar +description: > + Knowledge base for GoodProtocol action execution and GoodDollar (G$) integrations. + Use this skill BEFORE ad-hoc web search for claim, save/stake, swap, bridge, + stream, and identity tasks. Prefer GoodDocs (https://docs.gooddollar.org/) for + narrative; contract addresses only from GoodProtocol releases/deployment.json. +metadata: + version: 1.0.0 +license: MIT +--- + +# GoodDollar Skill Pack + +Routing index for GoodProtocol. This repo complements [GoodDocs](https://docs.gooddollar.org/) for behavior and user flows. **Contract addresses** come only from [GoodProtocol/releases/deployment.json](https://github.com/GoodDollar/GoodProtocol/blob/master/releases/deployment.json) (and `meta.deployments` in `references/contracts/*.abi.yaml`, which mirror those rows)—not from GoodDocs pages. + +Repository maintenance and update process is documented in `CONTRIBUTING.md`. + +## Protocol snapshot (from GoodDocs) + +- G$ is reserve-backed; issuance and pricing tie to the reserve and bonding-curve mechanics described in [How GoodDollar works](https://docs.gooddollar.org/how-gooddollar-works). +- The stack is multi-chain; which contracts exist per environment is defined only in [deployment.json](https://github.com/GoodDollar/GoodProtocol/blob/master/releases/deployment.json) (for example `GoodDollar`, `Identity`, `NameService`, `UBIScheme`, Mento keys, `MpbBridge`, and related entries under `production`, `production-celo`, and `production-xdc`). +- UBI is daily for verified users; identity verification and connected accounts are documented under [user guides](https://docs.gooddollar.org/user-guides). + +## Guides (single location for action playbooks) + +All task-specific instructions live under `references/guides/`. + +- `references/guides/claim.md` — daily UBI (`claim` / UBIScheme). +- `references/guides/save.md` — stake, rewards, unstake. +- `references/guides/swap.md` — buy or sell G$ (Mento on supported chains). +- `references/guides/bridge.md` — MessagePassingBridge (GoodDocs); optional OFT path via ABI refs. +- `references/guides/stream.md` — Superfluid streams (Celo-oriented in GoodDocs). +- `references/guides/check-identity.md` — whitelist and connected-address semantics. +- `references/guides/goodsdks.md` — SDK-first integration routing for GoodSDKs packages. +- `references/guides/gooddocs.md` — hub links to [GoodDocs](https://docs.gooddollar.org/). +- `references/guides/hypersync-hyperrpc.md` — Envio HyperSync/HyperRPC data-source routing for high-volume historical reads. +- `references/guides/faucet.md` — Faucet gas top-up execution flow and preflight checks. +- `references/guides/on-off-ramp.md` — stable-token ramp service flow into and out of G$. +- `references/guides/invite-bounties.md` — verify and execute inviter-invitee bounty payouts. +- `references/guides/migrate-fuse-staking-to-celo-savings.md` — migrate Fuse governance stake to CELO savings flow. + +## Subgraphs (indexed chain history) + +Use this folder with the same pattern as the protocol subgraph references: one `*-guide.md` plus one companion `.graphql` per deployment. + +For historical on-chain data, **start with the subgraph**: confirm the deployment covers the question (entities and fields in the guide, freshness via `_meta`). If the subgraph does not work for the request—missing schema coverage, stale or lagging indexing, query limits, or endpoint errors—**then** move to **HyperSync** or **HyperRPC** using `references/guides/hypersync-hyperrpc.md`. + +- `references/subgraphs/_query-patterns.md` — cross-cutting query discipline. +- `references/subgraphs/reserve-celo-guide.md` + `references/subgraphs/reserve-celo.graphql` — reserve pricing and swap history. +- `references/subgraphs/gooddollar-celo-guide.md` + `references/subgraphs/gooddollar-celo.graphql` — GoodDollar Celo schema discovery and starter probes. +- `references/subgraphs/goodcollective-guide.md` + `references/subgraphs/goodcollective.graphql` — GoodCollective schema discovery and starter probes. + +For Superfluid protocol subgraphs (streams, pools, vesting schedulers), see [Superfluid documentation](https://docs.superfluid.finance/) and [subgraph endpoints](https://subgraph-endpoints.superfluid.dev/). + +## Historical data routing policy (strict) + +1. Query subgraphs first for all historical/indexed requests. +2. Validate required entities and fields against the target subgraph schema and guide before declaring a gap. +3. Use **HyperSync** or **HyperRPC** fallback only when at least one of these is true: + - required entities or fields are not available in subgraph schema + - indexing lag makes subgraph data stale for the requested range + - query limits or endpoint instability block reliable retrieval +4. Do not start with HyperSync or HyperRPC when subgraph data is available and fresh. +5. HyperRPC fallback requires a valid Envio API key; if missing, **explicitly ask the user** to provide `HYPERRPC_API_TOKEN` or `ENVIO_API_TOKEN` (or paste a full `HYPERRPC_URL`); do not treat anonymous HyperRPC as production. +6. When **HyperSync** is the best option for the query and no Envio API token is available (`ENVIO_API_TOKEN` or equivalent per `references/guides/hypersync-hyperrpc.md`), **explicitly ask the user** to provide the token before proceeding; do not silently substitute anonymous HyperSync usage. +7. When fallback is used, report reason explicitly (schema gap, lag, or reliability issue). + +## Data source decision table + +| Query type | Primary source | Secondary source | Notes | +|---|---|---|---| +| Current on-chain state (latest balances, allowances, config, flags, view calls) | RPC | None | Use direct contract RPC reads for latest state. | +| Historical indexed entity data (time-series, aggregates, protocol entities, event-derived analytics) | Subgraph | HyperSync/HyperRPC | Prefer subgraph first; fall back when it cannot answer. | +| Historical raw on-chain data when subgraph is missing fields/entities or stale | HyperSync | HyperRPC | Prefer HyperSync for bulk scans and data pipelines. | +| Historical data for existing JSON-RPC integrations | HyperRPC | HyperSync | Use HyperRPC when strict JSON-RPC compatibility is required. | + +Decision rule: + +1. If request is current state -> use RPC. +2. If request is historical/indexed -> query subgraph first. +3. If subgraph cannot satisfy request -> fallback to HyperSync or HyperRPC per compatibility and scale needs. +4. HyperRPC fallback requires Envio API key credentials. +5. HyperSync client usage requires an Envio API token; if HyperSync is chosen and the token is missing, explicitly ask the user to provide it (see `references/guides/hypersync-hyperrpc.md`). + +## Mapping data retrieval rule + +Solidity mappings are not iterable on-chain by keyspace scan. Do not assume full-key enumeration is possible from RPC alone. + +When data is stored in mapping-like structures: + +1. Check contract source and ABI for key-discovery paths first: + - events emitted on set or update + - arrays, counters, linked lists, or index getters storing keys + - dedicated pagination or enumerable view functions +2. If key discovery exists, reconstruct key set from those sources and then read mapping entries. +3. If key discovery does not exist, report that complete iteration is not possible from chain state alone. +4. For historical reconstruction, prefer subgraph indexing first; if unavailable, use HyperSync or HyperRPC log scans with explicit limitations. + +## Use-case to guide map + +- Claim requests -> `references/guides/claim.md` +- Eligibility or connected-address questions -> `references/guides/check-identity.md` +- Stake, save, unstake -> `references/guides/save.md` +- Buy or sell G$ against reserve rails -> `references/guides/swap.md` +- Cross-chain bridge -> `references/guides/bridge.md` +- Stream management -> `references/guides/stream.md` +- SDK app integration tasks -> `references/guides/goodsdks.md` +- Bulk historical reads or data-engineering fetches -> `references/guides/hypersync-hyperrpc.md` +- Faucet top-up tasks -> `references/guides/faucet.md` +- On-/off-ramp service flow tasks -> `references/guides/on-off-ramp.md` +- Invite bounty eligibility and payout tasks -> `references/guides/invite-bounties.md` +- Fuse to CELO staking migration tasks -> `references/guides/migrate-fuse-staking-to-celo-savings.md` +- Indexed history, analytics, or GraphQL against GoodDollar subgraphs -> `references/subgraphs/_query-patterns.md` +- Historical on-chain fetch when subgraph data is insufficient -> subgraphs first, then HyperSync or HyperRPC per `references/guides/hypersync-hyperrpc.md`; if HyperSync is best and `ENVIO_API_TOKEN` is missing, ask the user for it explicitly. + +## Ambiguous prompts and incomplete inputs + +Stop and **ask the user** whenever the task is underspecified or required facts are missing. List what you need in short, concrete questions (for example chain, contract, address, amount, account, RPC or signer access, time or block range, prior tx hash, approval scope). + +- **Ambiguous** means the goal, environment, contract surface, or acceptance criteria are not clear enough to choose a safe path. +- **Incomplete** means you lack inputs that would change what you build, call, or sign next. + +**Do not invent** chain, address, amount, or policy details that affect correctness, funds, or eligibility. For **information-only** work you may state a single explicit assumption, label it, and ask the user to confirm or correct it before going further. + +**Execution work** (writing or editing runnable code, sending transactions, migrations, or anything that can move funds or alter on-chain state) has **no guessing**: settle every required input with the user, then implement or run. + +## Execution rules + +1. Collect missing required inputs before sending transactions. +2. Run pre-checks first (allowance, whitelist, quotes, bridge **amount** limits, peer wiring when using OFT paths). +3. If a pre-check fails, stop and return the exact corrective action. +4. Return tx hash and key output values. +5. Never fabricate addresses, amounts, or ABI behavior. +6. Resolve decimals and units per chain as in [How to integrate the G$ token](https://docs.gooddollar.org/for-developers/developer-guides/how-to-integrate-the-gusd-token) (for example 18 decimals on Celo, 2 on Fuse and Ethereum where applicable). + +## Pre-check matrix + +- Claim: verify identity whitelist status before `claim()`. +- Save or stake: verify balance and allowance before `stake()`. +- Swap: fetch quote, apply slippage bounds, verify allowance; confirm Mento contract keys for the active chain exist in `deployment.json` (for example `MentoBroker` under `production-celo` or `production-xdc`). +- Bridge (MessagePassingBridge): on the **source** chain approve G$ to the bridge; optionally preflight `canBridge(from, amount)` on that same contract (outbound `_bridgeTo` does not call it internally). For LZ use `estimateSendFee` with the **normalized** burn amount per `references/guides/bridge.md`, then `bridgeToWithLz` with nonzero `msg.value` for the **cross-chain transport** fee only (distinct from destination **`bridgeFees`** on minted G$; see **Bridge fee context** in that guide). Read **`bridgeLimits`** / daily trackers when debugging **amount** caps; see **Bridge amount limit context** in that guide. Respect `isClosed`, `LZ_FEE`, `MISSING_FEE`, and `UNSUPPORTED_CHAIN`. **Destination** mint applies `_enforceLimits` and can still revert. Use **Axelar** only when `toAxelarChainId` returns a route (implementation maps 1, 5, 42220, 44787); for Fuse or XDC style targets prefer LZ unless mapping is extended on-chain. +- Bridge (OFT adapter path): verify peer wiring and `quoteSend` fee data. +- Stream: confirm Celo (or documented Superfluid network) and correct Super Token and forwarder or host addresses. +- Identity: resolve Identity from NameService; remember connected addresses do not multiply daily claims ([connect wallet guide](https://docs.gooddollar.org/user-guides/connect-another-wallet-address-to-identity)). + +## Output format requirements + +For any state-changing action return: + +- network and key contract addresses used +- normalized input amounts and min or max guards +- tx hash +- key post-state output when available +- follow-up action if user intervention is required + +## Rich contract ABI references + +Convention: each `Foo.abi.yaml` has a companion `Foo.selectors.yaml` (function, event, and custom error selectors). Schema: `references/contracts/_rich-abi-yaml-format.md`. + +GoodDollar / Mento: + +- `references/contracts/NameService.abi.yaml` +- `references/contracts/IdentityV3.abi.yaml` +- `references/contracts/IdentityV4.abi.yaml` +- `references/contracts/InvitesV2.abi.yaml` +- `references/contracts/BuyGDCloneFactory.abi.yaml` +- `references/contracts/BuyGDCloneV2.abi.yaml` +- `references/contracts/GovernanceStakingV2.abi.yaml` +- `references/contracts/GooddollarSavingsStream.abi.yaml` (Ubeswap Superfluid stream savings; Celo deployment) +- `references/contracts/UBISchemeV2.abi.yaml` +- `references/contracts/MentoBroker.abi.yaml` +- `references/contracts/MessagePassingBridge.abi.yaml` +- `references/contracts/GoodDollarOFTAdapter.abi.yaml` +- `references/contracts/CFAv1Forwarder.abi.yaml` +- `references/contracts/ConstantFlowAgreementV1.abi.yaml` +- `references/contracts/Superfluid.abi.yaml` +- `references/contracts/SuperToken.abi.yaml` + +Superfluid (CFA, CFAv1Forwarder, Host, full ABI library): use [Superfluid docs](https://docs.superfluid.finance/), npm packages such as `@superfluid-finance/ethereum-contracts` and `@sfpro/sdk`, and contract ABIs published with those packages. + +## Deep researches + +- `references/deep-researches/on-off-ramp-service.md` +- `references/deep-researches/how-ubi-is-minted.md` +- `references/deep-researches/inviter-invitee-reward-model.md` +- `references/deep-researches/mento-reserve-economics.md` +- `references/deep-researches/gooddao-daostack-surface.md` +- `references/deep-researches/faucet-flows.md` +- `references/deep-researches/fuse-to-celo-staking-migration.md` + +## Revert debugging quick map + +- Identity or eligibility errors -> Identity and UBIScheme ABIs; live addresses from `deployment.json` only; GoodDocs for whitelist and claim behavior. +- Approval or transfer failures -> token approvals and balances; see integration guide for `transferAndCall` vs `approve` plus `transferFrom`. +- Swap bound failures -> quote freshness and slippage settings. +- MessagePassingBridge failures -> `canBridge`; **`BRIDGE_LIMITS`** (amount caps, whitelist, **`closed`**, and related policy strings); transport `msg.value` (`MISSING_FEE`, `LZ_FEE`) vs destination protocol fee (`bridgeFees`, `feeRecipient`); correct `bridgeTo` arguments; [Bridge GoodDollars](https://docs.gooddollar.org/user-guides/bridge-gooddollars). +- OFT path failures -> peer wiring and `quoteSend` fee data. +- Stream failures -> CFA forwarder or host agreement calls, buffer and flow-rate limits per Superfluid docs linked from GoodDocs. +- Faucet top-up failures -> `canTop`, `onlyAuthorized`, daily or weekly caps; `references/deep-researches/faucet-flows.md`. +- DAO-gated reverts -> caller is not avatar; scheme not registered; `references/deep-researches/gooddao-daostack-surface.md`. + +## Library usage discipline + +1. Open `references/guides/gooddocs.md` when unsure which GoodDocs page applies. +2. Start at this file to classify intent. +3. Open one guide under `references/guides/` unless the user requests a multi-step workflow. For subgraph or indexed-data tasks, start at `references/subgraphs/_query-patterns.md`. +4. Read only the ABI references and matching `.selectors.yaml` files needed for the chosen action. +5. Prefer GoodDocs for documented behavior; use only `deployment.json` (and rich ABI `meta.deployments` aligned with it) for contract addresses—never infer addresses from GoodDocs. +6. For large historical reads, prefer `references/guides/hypersync-hyperrpc.md` and choose HyperSync over HyperRPC unless strict JSON-RPC compatibility is required. +7. Historical data routing is strict: subgraphs first; HyperSync or HyperRPC only with an explicit fallback reason. +8. HyperRPC usage requires Envio API key credentials; when absent, **explicitly ask the user** for `HYPERRPC_API_TOKEN` or `ENVIO_API_TOKEN` (or a full `HYPERRPC_URL`) and do not attempt anonymous production flow. +9. When HyperSync is the best historical-data path and no Envio API token is available, explicitly ask the user to provide `ENVIO_API_TOKEN` (or the token your client expects) before continuing; see `references/guides/hypersync-hyperrpc.md`. +10. For subgraph tasks, validate field availability from the relevant `references/subgraphs/*-guide.md` and companion `.graphql` before guessing alternate entities. +11. For local shells repeating HyperRPC log pulls (for example last N whitelist events), from the **GoodSkills repository root** run `scripts/fetch-whitelist-events-hyperrpc.mjs` per `references/guides/hypersync-hyperrpc.md` instead of re-deriving JSON-RPC setup each time; that script ships with **defaults for production Celo** (HyperRPC host + `Identity` contract from `deployment.json`) and URL composition from `HYPERRPC_API_TOKEN` or `ENVIO_API_TOKEN` unless you override `CONTRACT_ADDRESS` / `HYPERRPC_URL`. HyperSync remains a separate client install path documented in the same guide. diff --git a/.agents/skills/gooddollar/references/contracts/BuyGDCloneFactory.abi.yaml b/.agents/skills/gooddollar/references/contracts/BuyGDCloneFactory.abi.yaml new file mode 100644 index 0000000..40226b3 --- /dev/null +++ b/.agents/skills/gooddollar/references/contracts/BuyGDCloneFactory.abi.yaml @@ -0,0 +1,205 @@ +meta: + name: BuyGDCloneFactory + version: "1" + source: + - https://raw.githubusercontent.com/GoodDollar/GoodProtocol/master/contracts/utils/BuyGDClone.sol + note: > + Deterministic clone factory for BuyGDCloneV2 and DonateGDClone. Used to create per-owner + executors and optional create+swap flows for ramp services. + deployments: + mainnet: + production-celo: + BuyGDFactoryV2: + networkId: 42220 + address: "0x1F60C4C7037C6766924A43666B781ED1479587a2" + creationBlock: 22909812 + BuyGDFactory: + networkId: 42220 + address: "0x00e533B7d6255D05b7f15034B1c989c21F51b91C" + creationBlock: 21006324 + related: + - references/deep-researches/on-off-ramp-service.md + - references/guides/on-off-ramp.md + +create: + notes: + - "Deploys deterministic BuyGDCloneV2 clone for owner and initializes it." + - "Difference vs createAndSwap: this only deploys; no swap is executed." + mutability: nonpayable + access: anyone + inputs: + - owner: address + outputs: + - clone: address + +createDonation: + notes: + - "Deploys deterministic DonateGDClone with donation target and call payload." + - "Difference vs create: deploys donation-capable implementation instead of plain swap clone." + mutability: nonpayable + access: anyone + inputs: + - owner: address + - donateOrExecTo: address + - callData: bytes + outputs: + - clone: address + +createAndSwap: + notes: + - "One-transaction helper: create BuyGDCloneV2 then immediately call clone.swap(minAmount, msg.sender)." + - "Difference vs create: bundles deployment and first swap for faster ramp UX." + mutability: nonpayable + access: anyone + inputs: + - owner: address + - minAmount: uint256 + outputs: + - clone: address + +createDonationAndSwap: + notes: + - "One-transaction helper for DonateGDClone: deploy, then execute donation flow with optional pre-swap." + - "Difference vs createDonation: can execute immediate swap and/or target call instead of deployment only." + mutability: nonpayable + access: anyone + inputs: + - owner: address + - donateOrExecTo: address + - withSwap: bool + - minAmount: uint256 + - callData: bytes + outputs: + - clone: address + +predict: + notes: + - "Computes deterministic address for create(owner) salt." + mutability: view + inputs: + - owner: address + outputs: + - clone: address + +predictDonation: + notes: + - "Computes deterministic address for createDonation(owner, donateOrExecTo, callData) salt." + mutability: view + inputs: + - owner: address + - donateOrExecTo: address + - callData: bytes + outputs: + - clone: address + +getBaseFee: + mutability: view + inputs: [] + outputs: + - baseFee: uint256 + +quoter: + mutability: pure + inputs: [] + outputs: + - addr: address + +CUSD: + mutability: pure + inputs: [] + outputs: + - token: address + +celo: + mutability: pure + inputs: [] + outputs: + - token: address + +USDC: + mutability: pure + inputs: [] + outputs: + - token: address + +GLOUSD: + mutability: pure + inputs: [] + outputs: + - token: address + +PERIOD: + mutability: pure + inputs: [] + outputs: + - seconds: uint24 + +impl: + mutability: view + inputs: [] + outputs: + - addr: address + +donateImpl: + mutability: view + inputs: [] + outputs: + - addr: address + +gd: + mutability: view + inputs: [] + outputs: + - token: address + +stable: + mutability: view + inputs: [] + outputs: + - token: address + +oracle: + mutability: view + inputs: [] + outputs: + - addr: address + +router: + mutability: view + inputs: [] + outputs: + - addr: address + +mentoBroker: + mutability: view + inputs: [] + outputs: + - addr: address + +mentoExchangeProvider: + mutability: view + inputs: [] + outputs: + - addr: address + +mentoExchangeId: + mutability: view + inputs: [] + outputs: + - id: bytes32 + +events: + GDSwapToCusd: + indexed: [] + data: + - from: address + - to: address + - amountIn: uint256 + - amountOut: uint256 + - note: bytes + +errors: + NOT_GD_TOKEN: "onTokenTransfer caller is not G$ token." + INVALID_TWAP: "TWAP validation failed." + RECIPIENT_ZERO: "Recipient cannot be zero address." + ZERO_MINAMOUNT: "Minimum amount cannot be zero." diff --git a/.agents/skills/gooddollar/references/contracts/BuyGDCloneFactory.selectors.yaml b/.agents/skills/gooddollar/references/contracts/BuyGDCloneFactory.selectors.yaml new file mode 100644 index 0000000..16b13f2 --- /dev/null +++ b/.agents/skills/gooddollar/references/contracts/BuyGDCloneFactory.selectors.yaml @@ -0,0 +1,27 @@ +# Generated by scripts/selectors.mjs +functions: + create(address): 0x9ed93318 + createDonation(address,address,bytes): 0x48199e6b + createAndSwap(address,uint256): 0x89643a29 + createDonationAndSwap(address,address,bool,uint256,bytes): 0xeb5621b8 + predict(address): 0x901b96e7 + predictDonation(address,address,bytes): 0x3895de30 + getBaseFee(): 0x15e812ad + quoter(): 0xc6bbd5a7 + CUSD(): 0x758316c9 + celo(): 0x051ed8ef + USDC(): 0x89a30271 + GLOUSD(): 0x4b5b02d6 + PERIOD(): 0xb4d1d795 + impl(): 0x8abf6077 + donateImpl(): 0x21fc2eef + gd(): 0xa5e598fc + stable(): 0x22be3de1 + oracle(): 0x7dc0d1d0 + router(): 0xf887ea40 + mentoBroker(): 0x7b89f117 + mentoExchangeProvider(): 0x4f62feec + mentoExchangeId(): 0xd373b333 +events: + GDSwapToCusd(address,address,uint256,uint256,bytes): 0x252bc23e3fb01f9986fa157af621236fb8a706ea12622da296e7f2f30d4f1a56 +errors: {} diff --git a/.agents/skills/gooddollar/references/contracts/BuyGDCloneV2.abi.yaml b/.agents/skills/gooddollar/references/contracts/BuyGDCloneV2.abi.yaml new file mode 100644 index 0000000..5f35ee9 --- /dev/null +++ b/.agents/skills/gooddollar/references/contracts/BuyGDCloneV2.abi.yaml @@ -0,0 +1,282 @@ +meta: + name: BuyGDCloneV2 + version: "2" + source: + - https://raw.githubusercontent.com/GoodDollar/GoodProtocol/master/contracts/utils/BuyGDClone.sol + inherits: + - Initializable + note: > + Clone implementation used by BuyGDCloneFactory for deterministic per-owner swap executors. + Supports CELO and cUSD flows, with cUSD route selection between Uniswap and Mento when configured. + deployments: + mainnet: + production-celo: + BuyGDFactoryV2: + networkId: 42220 + address: "0x1F60C4C7037C6766924A43666B781ED1479587a2" + creationBlock: 22909812 + related: + - references/deep-researches/on-off-ramp-service.md + - references/guides/on-off-ramp.md + +initialize: + mutability: nonpayable + access: initializer + inputs: + - _owner: address + outputs: [] + +getSwapPath: + mutability: pure + inputs: + - tokens: address[] + - fees: uint24[] + outputs: + - path: bytes + +swap: + notes: + - "Dispatcher entrypoint: if clone holds native CELO balance it executes CELO route, otherwise uses cUSD route." + - "Difference vs swapCelo/swapCusd: this function chooses route by contract balances; specialized functions force a specific asset path." + mutability: payable + access: anyone + inputs: + - _minAmount: uint256 + - refundGas: address + outputs: + - bought: uint256 + emits: [Bought] + errors: [NO_BALANCE] + +swapCelo: + notes: + - "CELO-only convenience path using the default preconfigured Uniswap route." + - "Difference vs swapCeloWithPath: same Uniswap execution, but caller cannot override token path and fee tiers." + - "Difference vs cUSD paths: CELO path does not use Mento route selection." + mutability: payable + access: anyone + inputs: + - _minAmount: uint256 + - refundGas: address + outputs: + - bought: uint256 + emits: [BoughtFromUniswap] + errors: [REFUND_FAILED] + +swapCeloWithPath: + notes: + - "CELO-only path with caller-supplied Uniswap multi-hop route." + - "Difference vs swapCelo: allows custom path optimization when default route is not preferred." + - "Difference vs cUSD paths: still Uniswap-only and does not compare against Mento." + mutability: payable + access: anyone + inputs: + - _minAmount: uint256 + - refundGas: address + - _path: (address[],uint24[]) + outputs: + - bought: uint256 + emits: [BoughtFromUniswap] + errors: [REFUND_FAILED] + +swapCusd: + notes: + - "cUSD-only convenience path that compares expected output from default-path Uniswap and Mento, then executes the better quote." + - "Difference vs swapCusdWithPath: this uses hardcoded default Uniswap path for comparison." + - "Difference vs CELO paths: includes dual-route best-execution logic with optional Mento." + mutability: nonpayable + access: anyone + inputs: + - _minAmount: uint256 + - refundGas: address + outputs: + - bought: uint256 + emits: [BoughtFromMento, BoughtFromUniswap] + errors: [MENTO_NOT_CONFIGURED] + +swapCusdWithPath: + notes: + - "cUSD path with caller-supplied Uniswap route; still compares custom Uniswap quote against Mento quote and picks larger expected output." + - "Difference vs swapCusd: custom path changes only the Uniswap side of the comparison." + - "Difference vs swapCeloWithPath: this function performs route competition (Uniswap vs Mento), not only route customization." + mutability: nonpayable + access: anyone + inputs: + - _minAmount: uint256 + - refundGas: address + - _path: (address[],uint24[]) + outputs: + - bought: uint256 + emits: [BoughtFromMento, BoughtFromUniswap] + errors: [MENTO_NOT_CONFIGURED] + +getExpectedReturnFromUniswapPath: + notes: + - "Quote helper for Uniswap path expected output used by cUSD route selection and preflight checks." + mutability: nonpayable + inputs: + - amountIn: uint256 + - _path: (address[],uint24[]) + outputs: + - expectedReturn: uint256 + +getExpectedReturnFromMento: + notes: + - "Quote helper for Mento expected output for cUSD->G$ used in best-route decision." + mutability: view + inputs: + - cusdAmount: uint256 + outputs: + - expectedReturn: uint256 + errors: [MENTO_NOT_CONFIGURED] + +minAmountByTWAP: + mutability: view + inputs: + - baseAmount: uint256 + - baseToken: address + - period: uint32 + outputs: + - minTwap: uint256 + - quote: uint256 + +recover: + mutability: nonpayable + access: anyone + inputs: + - token: address + outputs: [] + errors: [REFUND_FAILED] + +router: + mutability: view + inputs: [] + outputs: + - addr: address + +celo: + mutability: pure + inputs: [] + outputs: + - token: address + +CUSD: + mutability: pure + inputs: [] + outputs: + - token: address + +USDC: + mutability: pure + inputs: [] + outputs: + - token: address + +GLOUSD: + mutability: pure + inputs: [] + outputs: + - token: address + +GD_FEE_TIER: + mutability: pure + inputs: [] + outputs: + - tier: uint24 + +CUSD_STABLE_FEE_TIER: + mutability: pure + inputs: [] + outputs: + - tier: uint24 + +CELO_STABLE_FEE_TIER: + mutability: pure + inputs: [] + outputs: + - tier: uint24 + +twapPeriod: + mutability: view + inputs: [] + outputs: + - period: uint32 + +stable: + mutability: view + inputs: [] + outputs: + - token: address + +gd: + mutability: view + inputs: [] + outputs: + - token: address + +oracle: + mutability: view + inputs: [] + outputs: + - addr: address + +quoter: + mutability: view + inputs: [] + outputs: + - addr: address + +mentoBroker: + mutability: view + inputs: [] + outputs: + - addr: address + +mentoExchangeProvider: + mutability: view + inputs: [] + outputs: + - addr: address + +mentoExchangeId: + mutability: view + inputs: [] + outputs: + - id: bytes32 + +owner: + mutability: view + inputs: [] + outputs: + - addr: address + +CUSD_GAS_COSTS: + mutability: pure + inputs: [] + outputs: + - amount: uint256 + +events: + Bought: + indexed: [] + data: + - inToken: address + - inAmount: uint256 + - outAmount: uint256 + BoughtFromMento: + indexed: [] + data: + - inToken: address + - inAmount: uint256 + - outAmount: uint256 + BoughtFromUniswap: + indexed: [] + data: + - inToken: address + - inAmount: uint256 + - outAmount: uint256 + +errors: + REFUND_FAILED: "Refund call failed." + NO_BALANCE: "No CELO or cUSD available on clone." + MENTO_NOT_CONFIGURED: "Mento broker path not configured." diff --git a/.agents/skills/gooddollar/references/contracts/BuyGDCloneV2.selectors.yaml b/.agents/skills/gooddollar/references/contracts/BuyGDCloneV2.selectors.yaml new file mode 100644 index 0000000..1476ae3 --- /dev/null +++ b/.agents/skills/gooddollar/references/contracts/BuyGDCloneV2.selectors.yaml @@ -0,0 +1,36 @@ +# Generated by scripts/selectors.mjs +functions: + initialize(address): 0xc4d66de8 + getSwapPath(address[],uint24[]): 0xf0036d5d + swap(uint256,address): 0xd3986f08 + swapCelo(uint256,address): 0xaa6bfa9d + swapCeloWithPath(uint256,address,(address[],uint24[])): 0x81b7d2e0 + swapCusd(uint256,address): 0xb1a5fa9f + swapCusdWithPath(uint256,address,(address[],uint24[])): 0x170ba915 + getExpectedReturnFromUniswapPath(uint256,(address[],uint24[])): 0x12194320 + getExpectedReturnFromMento(uint256): 0xdbb15eb2 + minAmountByTWAP(uint256,address,uint32): 0x821dc910 + recover(address): 0x0cd865ec + router(): 0xf887ea40 + celo(): 0x051ed8ef + CUSD(): 0x758316c9 + USDC(): 0x89a30271 + GLOUSD(): 0x4b5b02d6 + GD_FEE_TIER(): 0xe00e8fdd + CUSD_STABLE_FEE_TIER(): 0xba428926 + CELO_STABLE_FEE_TIER(): 0x60e4bf4b + twapPeriod(): 0xf6207326 + stable(): 0x22be3de1 + gd(): 0xa5e598fc + oracle(): 0x7dc0d1d0 + quoter(): 0xc6bbd5a7 + mentoBroker(): 0x7b89f117 + mentoExchangeProvider(): 0x4f62feec + mentoExchangeId(): 0xd373b333 + owner(): 0x8da5cb5b + CUSD_GAS_COSTS(): 0x32f90ac3 +events: + Bought(address,uint256,uint256): 0xa9a40dec7a304e5915d11358b968c1e8d365992abf20f82285d1df1b30c8e24c + BoughtFromMento(address,uint256,uint256): 0x8e2ac24d7ef5662ee242823a19dbd1c952b3e96ae127228f4bbce83e2816e3fb + BoughtFromUniswap(address,uint256,uint256): 0xdb1f2a6cbbfd964f19c648b140a35992aa80f482df8f519d3211d0bd86c9f335 +errors: {} diff --git a/.agents/skills/gooddollar/references/contracts/CFAv1Forwarder.abi.yaml b/.agents/skills/gooddollar/references/contracts/CFAv1Forwarder.abi.yaml new file mode 100644 index 0000000..32ba0de --- /dev/null +++ b/.agents/skills/gooddollar/references/contracts/CFAv1Forwarder.abi.yaml @@ -0,0 +1,237 @@ +# CFAv1Forwarder — convenience wrapper for ConstantFlowAgreementV1 +# Allows direct interaction with CFA functions without manually routing through +# the Host's batchCall / forwardBatchCall. Operates as a trusted forwarder, +# preserving msg.sender via EIP-2771. +# +# Each forwarder call is a standalone transaction — forwarder calls cannot be +# combined in a Host.batchCall. To batch multiple operations atomically (e.g. +# wrap tokens + create stream), use Host.batchCall with the raw CFA agreement +# (operationType 201). See Superfluid.abi.yaml for batch operation details. +# Tradeoff: forwarder calls produce human-readable descriptions in wallets +# (e.g. "setFlowrate(token, receiver, flowrate)"), while Host.batchCall +# shows encoded tuples that are difficult for users to verify. +# +# This contract has no events — all events are emitted by the underlying CFA. +# Errors from the CFA (and Host) propagate through to the caller. + +meta: + name: CFAv1Forwarder + version: v1 + source: + - https://raw.githubusercontent.com/superfluid-org/protocol-monorepo/refs/heads/dev/packages/ethereum-contracts/contracts/utils/CFAv1Forwarder.sol + - https://raw.githubusercontent.com/superfluid-org/protocol-monorepo/refs/heads/dev/packages/ethereum-contracts/contracts/utils/ForwarderBase.sol + inherits: [ForwarderBase] + deployments: + # Same address on all networks except avalanche-fuji + mainnet: + eth-mainnet: "0xcfA132E353cB4E398080B9700609bb008eceB125" + polygon-mainnet: "0xcfA132E353cB4E398080B9700609bb008eceB125" + xdai-mainnet: "0xcfA132E353cB4E398080B9700609bb008eceB125" + base-mainnet: "0xcfA132E353cB4E398080B9700609bb008eceB125" + optimism-mainnet: "0xcfA132E353cB4E398080B9700609bb008eceB125" + arbitrum-one: "0xcfA132E353cB4E398080B9700609bb008eceB125" + bsc-mainnet: "0xcfA132E353cB4E398080B9700609bb008eceB125" + avalanche-c: "0xcfA132E353cB4E398080B9700609bb008eceB125" + celo-mainnet: "0xcfA132E353cB4E398080B9700609bb008eceB125" + scroll-mainnet: "0xcfA132E353cB4E398080B9700609bb008eceB125" + degenchain: "0xcfA132E353cB4E398080B9700609bb008eceB125" + testnet: + avalanche-fuji: "0x2CDd45c5182602a36d391F7F16DD9f8386C3bD8D" + base-sepolia: "0xcfA132E353cB4E398080B9700609bb008eceB125" + eth-sepolia: "0xcfA132E353cB4E398080B9700609bb008eceB125" + optimism-sepolia: "0xcfA132E353cB4E398080B9700609bb008eceB125" + scroll-sepolia: "0xcfA132E353cB4E398080B9700609bb008eceB125" + deploymentCreationBlocks: + mainnet: + celo-mainnet: 17404156 + +# == Glossary == +# flowrate — token transfer rate in wad/second (int96) +# flowOperator — account authorized to create/update/delete flows on behalf of another +# buffer — deposit locked as solvency collateral while a flow is active +# permissions — bitmask of create | update | delete rights for an operator +# flowrateAllowance — max flowrate an operator may set per individual flow + +# == Flow Management == +# High-level functions that automatically create, update, or delete flows as needed. + +setFlowrate: + # Smart setter: creates a new flow if none exists, updates if flowrate changed, + # deletes if flowrate is zero. No-ops if the current rate already matches. + notes: + - "Gotcha: Negative flowrate values revert with CFA_FWD_INVALID_FLOW_RATE." + mutability: nonpayable + access: anyone # flow from msg.sender + inputs: + - token: address + - receiver: address + - flowrate: int96 # must be >= 0 + outputs: + - bool + errors: [CFA_FWD_INVALID_FLOW_RATE] + +setFlowrateFrom: + # Same as setFlowrate but can be called by a flow operator on behalf of `sender`. + # msg.sender must have sufficient operator permissions and flowrateAllowance. + mutability: nonpayable + access: sender | operator + inputs: + - token: address + - sender: address + - receiver: address + - flowrate: int96 + outputs: + - bool + errors: [CFA_FWD_INVALID_FLOW_RATE] + +# == Low-Level Flow Operations == +# Direct wrappers around CFA functions. These give full control (including userData) +# but require the caller to know whether a flow already exists. +# If sender != msg.sender, the *ByOperator variant is used internally. + +createFlow: + # Create a new flow. Reverts if a flow already exists between sender and receiver. + mutability: nonpayable + access: sender | operator + inputs: + - token: address + - sender: address + - receiver: address + - flowrate: int96 + - userData: bytes + outputs: + - bool + +updateFlow: + # Update an existing flow's rate. Reverts if no flow exists. + mutability: nonpayable + access: sender | operator + inputs: + - token: address + - sender: address + - receiver: address + - flowrate: int96 + - userData: bytes + outputs: + - bool + +deleteFlow: + # Delete an existing flow. Can be called by sender, receiver, or an operator. + # If msg.sender is neither sender nor receiver, deleteFlowByOperator is used. + mutability: nonpayable + access: sender | receiver | operator + inputs: + - token: address + - sender: address + - receiver: address + - userData: bytes + outputs: + - bool + +# == ACL (Operator Permissions) == + +grantPermissions: + # Grant full create/update/delete permissions with max flowrateAllowance to an operator. + # Convenience wrapper — equivalent to updateFlowOperatorPermissions with full control. + mutability: nonpayable + access: anyone # grants on msg.sender's flows + inputs: + - token: address + - flowOperator: address + outputs: + - bool + +revokePermissions: + # Revoke all permissions from an operator. Does not affect existing flows. + mutability: nonpayable + access: anyone # revokes on msg.sender's flows + inputs: + - token: address + - flowOperator: address + outputs: + - bool + +updateFlowOperatorPermissions: + # Set granular operator permissions and flowrate allowance. + notes: + - "Gotcha: flowrateAllowance limits per-flow rate, NOT aggregate net flow." + mutability: nonpayable + access: anyone # grants on msg.sender's flows + inputs: + - token: address + - flowOperator: address + - permissions: uint8 # bitmask: 1=create, 2=update, 4=delete + - flowrateAllowance: int96 + outputs: + - bool + +# == Flow Queries == + +getFlowrate: + mutability: view + inputs: + - token: address + - sender: address + - receiver: address + outputs: + - flowrate: int96 + +getFlowInfo: + mutability: view + inputs: + - token: address + - sender: address + - receiver: address + outputs: + - lastUpdated: uint256 + - flowrate: int96 + - deposit: uint256 + - owedDeposit: uint256 + +getBufferAmountByFlowrate: + # Returns the deposit/buffer required for a given flowrate. + notes: + - "Gotcha: This value is governance-configurable and may change over time. Changes only affect newly created/updated flows." + mutability: view + inputs: + - token: address + - flowrate: int96 + outputs: + - bufferAmount: uint256 + +getAccountFlowrate: + # Net aggregate flowrate for an account (incoming minus outgoing). + mutability: view + inputs: + - token: address + - account: address + outputs: + - flowrate: int96 + +getAccountFlowInfo: + mutability: view + inputs: + - token: address + - account: address + outputs: + - lastUpdated: uint256 + - flowrate: int96 + - deposit: uint256 + - owedDeposit: uint256 + +# == ACL Queries == + +getFlowOperatorPermissions: + mutability: view + inputs: + - token: address + - sender: address + - flowOperator: address + outputs: + - permissions: uint8 + - flowrateAllowance: int96 + +# == Errors == + +errors: + - CFA_FWD_INVALID_FLOW_RATE # flowrate argument was negative diff --git a/.agents/skills/gooddollar/references/contracts/CFAv1Forwarder.selectors.yaml b/.agents/skills/gooddollar/references/contracts/CFAv1Forwarder.selectors.yaml new file mode 100644 index 0000000..f98e21e --- /dev/null +++ b/.agents/skills/gooddollar/references/contracts/CFAv1Forwarder.selectors.yaml @@ -0,0 +1,19 @@ +# Generated by scripts/selectors.mjs +functions: + setFlowrate(address,address): 0x2f57fb6f + setFlowrateFrom(address,address,address,int96): 0xc5ad5c1a + createFlow(address,address,address,int96,bytes): 0xe15536b6 + updateFlow(address,address,address,int96,bytes): 0x0c033991 + deleteFlow(address,address,address,bytes): 0xb4b333c6 + grantPermissions(address,address): 0x7243fb93 + revokePermissions(address,address): 0x0bd0728d + updateFlowOperatorPermissions(address,address): 0x42294caf + getFlowrate(address,address,address): 0x1d8b6526 + getFlowInfo(address,address,address): 0x2860fd93 + getBufferAmountByFlowrate(address,int96): 0x09f0b495 + getAccountFlowrate(address,address): 0x22c904d9 + getAccountFlowInfo(address,address): 0x0f1ac495 + getFlowOperatorPermissions(address,address,address): 0x4d3f60f9 +events: +{} +errors: {} diff --git a/.agents/skills/gooddollar/references/contracts/ConstantFlowAgreementV1.abi.yaml b/.agents/skills/gooddollar/references/contracts/ConstantFlowAgreementV1.abi.yaml new file mode 100644 index 0000000..afaec5d --- /dev/null +++ b/.agents/skills/gooddollar/references/contracts/ConstantFlowAgreementV1.abi.yaml @@ -0,0 +1,560 @@ +# Superfluid Constant Flow Agreement (CFA) v1 +# Manages continuous per-second token streams between accounts. +# +# NOTE: emits/errors mappings are traced from source code — verify against implementation. +# Proxy/upgradability functions (castrate, updateCode, getCodeAddress, proxiableUUID) +# are omitted — they belong to the UUPSProxiable / AgreementBase layer. +# Pure helpers addPermissions/removePermissions are omitted — they were made public +# for testability only and are not part of the protocol interface. + +meta: + name: ConstantFlowAgreementV1 + version: v1 + source: + - https://raw.githubusercontent.com/superfluid-org/protocol-monorepo/refs/heads/dev/packages/ethereum-contracts/contracts/agreements/ConstantFlowAgreementV1.sol + - https://raw.githubusercontent.com/superfluid-org/protocol-monorepo/refs/heads/dev/packages/ethereum-contracts/contracts/interfaces/agreements/IConstantFlowAgreementV1.sol + - https://raw.githubusercontent.com/superfluid-org/protocol-monorepo/refs/heads/dev/packages/ethereum-contracts/contracts/agreements/AgreementBase.sol + implements: [IConstantFlowAgreementV1, ISuperAgreement] + inherits: [AgreementBase] + deployments: + mainnet: + eth-mainnet: "0x2844c1BBdA121E9E43105630b9C8310e5c72744b" + polygon-mainnet: "0x6EeE6060f715257b970700bc2656De21dEdF074C" + xdai-mainnet: "0xEbdA4ceF883A7B12c4E669Ebc58927FBa8447C7D" + base-mainnet: "0x19ba78B9cDB05A877718841c574325fdB53601bb" + optimism-mainnet: "0x204C6f131bb7F258b2Ea1593f5309911d8E458eD" + arbitrum-one: "0x731FdBB12944973B500518aea61942381d7e240D" + bsc-mainnet: "0x49c38108870e74Cb9420C0991a85D3edd6363F75" + avalanche-c: "0x6946c5B38Ffea373b0a2340b4AEf0De8F6782e58" + celo-mainnet: "0x9d369e78e1a682cE0F8d9aD849BeA4FE1c3bD3Ad" + scroll-mainnet: "0xB3bcD6da1eeB6c97258B3806A853A6dcD3B6C00c" + degenchain: "0x82cc052d1b17aC554a22A88D5876B56c6b51e95c" + testnet: + avalanche-fuji: "0x16843ac25Ccc58Aa7960ba05f61cBB17b36b130A" + base-sepolia: "0x6836F23d6171D74Ef62FcF776655aBcD2bcd62Ef" + eth-sepolia: "0x6836F23d6171D74Ef62FcF776655aBcD2bcd62Ef" + optimism-sepolia: "0x8a3170AdbC67233196371226141736E4151e7C26" + scroll-sepolia: "0xbc46B4Aa41c055578306820013d4B65fff42711E" + deploymentCreationBlocks: + mainnet: + celo-mainnet: 16393492 + +# == Abbreviations == +# 3Ps — Three Periods: liquidation, patrician, and pleb (solvency model) +# ACL — Access Control List (flow operator permissions) +# CFA — Constant Flow Agreement +# ctx — context (Superfluid call context bytes, carries msg.sender and userData) +# GDA — General Distribution Agreement (the other Superfluid agreement) +# PPP — Patrician-Pleb-Pirate (the 3Ps solvency periods) + +# == Glossary == +# flow / stream — continuous per-second token transfer, used interchangeably +# flowRate — tokens per second (int96, wei-denominated); positive = outgoing +# deposit — buffer locked when opening a flow; protects against insolvency +# owed deposit — portion of deposit owed back to the sender by a Super App receiver +# flow operator — an address authorized to create/update/delete flows on behalf of a sender +# flow rate allowance — maximum net flow rate an operator may allocate (int96); decrements on use +# permissions bitmask — uint8: bit 0 = create (1), bit 1 = update (2), bit 2 = delete (4) +# liquidation — closing an insolvent sender's flow; rewards go to the liquidator or bond +# patrician period — grace window after insolvency where reward goes to the bond account +# pleb period — window after patrician where reward goes to the liquidator +# pirate / bailout — state where total deposit cannot cover the deficit; protocol bails out +# Super App — a contract registered with the Host that receives agreement callbacks +# app credit — deposit credit enabling "zero-balance Super Apps" to relay flows +# without pre-funded tokens. 1:1 relay (one in, one out at same rate) +# always works at zero balance. Fan-out (1:N) needs the app to hold +# tokens. Credit is settled as "owed deposit" on the original sender. +# critical — an account whose available balance is negative (eligible for liquidation) +# jailed — a Super App penalized for violating protocol rules; loses callbacks +# +# == Time Conventions == +# Conventional seconds-per-period used in Superfluid apps for flow rate conversion: +# month: 2628000 (365.25 / 12 * 86400) +# year: 31536000 (365 * 86400) +# Flow rate from a monthly amount: flowRate = monthlyAmount / 2628000 +# Flow rate from a yearly amount: flowRate = yearlyAmount / 31536000 + +# == Flow Management == +# Core operations for creating, updating, and deleting token streams. +# Functions with ctx are called through the Host — either via +# Host.callAgreement (single op) or Host.batchCall (operationType 201). +# For batchCall, the data field is abi.encode(callData, userData) where +# callData is the full ABI-encoded function call with an empty ctx ("0x") +# as placeholder. The Host replaces the placeholder with the real context. +# The access field reflects who can initiate the call, not the direct caller. + +createFlow: + # Start a new stream from ctx.msgSender to receiver. + # The deposit amount depends on the governance-configured liquidation period + # and minimum deposit. The lower 32 bits of the deposit are clipped (rounded up). + notes: + - "Gotcha: A deposit is taken as a safety margin for solvency agents." + mutability: nonpayable + access: anyone # flow from ctx.msgSender + inputs: + - token: address + - receiver: address + - flowRate: int96 # must be > 0 + - ctx: bytes + outputs: + - newCtx: bytes + emits: [FlowUpdated, FlowUpdatedExtension] + errors: [CFA_ZERO_ADDRESS_RECEIVER, CFA_NO_SELF_FLOW, CFA_INVALID_FLOW_RATE, CFA_FLOW_ALREADY_EXISTS, CFA_INSUFFICIENT_BALANCE] + +updateFlow: + # Change the flow rate of an existing stream from ctx.msgSender to receiver. + # Note: owedDeposit accumulates when a Super App receiver uses app credit to + # open outgoing streams. The sender bears the deposit cost for those streams. + notes: + - "Gotcha: Deposit is adjusted to match the new flow rate but never refunds owed deposit — that adjustment happens separately via the app credit system." + mutability: nonpayable + access: anyone # flow from ctx.msgSender + inputs: + - token: address + - receiver: address + - flowRate: int96 # must be > 0 + - ctx: bytes + outputs: + - newCtx: bytes + emits: [FlowUpdated, FlowUpdatedExtension] + errors: [CFA_ZERO_ADDRESS_RECEIVER, CFA_NO_SELF_FLOW, CFA_INVALID_FLOW_RATE, CFA_FLOW_DOES_NOT_EXIST, CFA_INSUFFICIENT_BALANCE] + +deleteFlow: + # Stop a stream between sender and receiver. + # During liquidation the reward distribution depends on the solvency period: + # patrician → bond account gets reward; pleb → liquidator gets reward; + # pirate → liquidator gets full single deposit, protocol covers the bailout. + notes: + - "Gotcha: Third-party callers (not sender, receiver, or operator) only succeed if the sender is critical (negative available balance) or either party is jailed." + mutability: nonpayable + access: sender | receiver | operator | anyone(if-critical-or-jailed) + inputs: + - token: address + - sender: address + - receiver: address + - ctx: bytes + outputs: + - newCtx: bytes + emits: [FlowUpdated, FlowUpdatedExtension] + errors: [CFA_ZERO_ADDRESS_SENDER, CFA_ZERO_ADDRESS_RECEIVER, CFA_FLOW_DOES_NOT_EXIST, CFA_NON_CRITICAL_SENDER] + +# == Operator Flow Management == +# Act on behalf of another account. Requires ACL permissions granted by the sender. +# The operator's flow rate allowance is decremented on create/update. +# Functions with ctx are called through the Host. + +createFlowByOperator: + # Create a flow on behalf of sender. Consumes flow rate allowance. + notes: + - "Gotcha: Reverts if ctx.msgSender IS the sender — use createFlow instead." + mutability: nonpayable + access: operator + inputs: + - token: address + - sender: address + - receiver: address + - flowRate: int96 # must be > 0 + - ctx: bytes + outputs: + - newCtx: bytes + emits: [FlowUpdated, FlowUpdatedExtension] + errors: [CFA_ACL_NO_SENDER_CREATE, CFA_ACL_OPERATOR_NO_CREATE_PERMISSIONS, CFA_ACL_FLOW_RATE_ALLOWANCE_EXCEEDED, CFA_ZERO_ADDRESS_RECEIVER, CFA_NO_SELF_FLOW, CFA_INVALID_FLOW_RATE, CFA_FLOW_ALREADY_EXISTS, CFA_INSUFFICIENT_BALANCE] + +updateFlowByOperator: + # Update a flow on behalf of sender. Only consumes allowance if flow rate increases. + # If flowRateAllowance is type(int96).max, it is treated as unlimited. + notes: + - "Gotcha: If the new rate is lower than the old rate, no allowance is consumed." + mutability: nonpayable + access: operator + inputs: + - token: address + - sender: address + - receiver: address + - flowRate: int96 # must be > 0 + - ctx: bytes + outputs: + - newCtx: bytes + emits: [FlowUpdated, FlowUpdatedExtension] + errors: [CFA_ACL_NO_SENDER_UPDATE, CFA_ACL_OPERATOR_NO_UPDATE_PERMISSIONS, CFA_ACL_FLOW_RATE_ALLOWANCE_EXCEEDED, CFA_ZERO_ADDRESS_RECEIVER, CFA_NO_SELF_FLOW, CFA_INVALID_FLOW_RATE, CFA_FLOW_DOES_NOT_EXIST, CFA_INSUFFICIENT_BALANCE] + +deleteFlowByOperator: + # Delete a flow on behalf of sender. Does not consume flow rate allowance. + mutability: nonpayable + access: operator + inputs: + - token: address + - sender: address + - receiver: address + - ctx: bytes + outputs: + - newCtx: bytes + emits: [FlowUpdated, FlowUpdatedExtension] + errors: [CFA_ACL_OPERATOR_NO_DELETE_PERMISSIONS, CFA_ZERO_ADDRESS_SENDER, CFA_ZERO_ADDRESS_RECEIVER, CFA_FLOW_DOES_NOT_EXIST, CFA_NON_CRITICAL_SENDER] + +# == Flow Queries == + +realtimeBalanceOf: + # Compute the real-time CFA balance contribution for an account. + # Returns the dynamic balance delta (flowRate * elapsed), total deposit held, + # and total owed deposit. This is called by the token's realtimeBalanceOfNow + # to assemble the full balance across all agreements. + # To get an account's actual token balance, use SuperToken.realtimeBalanceOfNow + # (or SuperToken.balanceOf for ERC-20 compatible, clamped to zero). + # It can be deeply negative for net-outflow accounts as time progresses. + notes: + - "Gotcha: Returns only the CFA portion of the balance, not the total." + - "Gotcha: The returned dynamicBalance is a delta, not an absolute balance." + mutability: view + inputs: + - token: address + - account: address + - time: uint256 + outputs: + - dynamicBalance: int256 # flowRate * (time - lastUpdate); can be negative + - deposit: uint256 # total deposit locked across all outflows + - owedDeposit: uint256 # total owed deposit from Super App receivers + +getFlow: + # Get flow data between a specific sender-receiver pair. + mutability: view + inputs: + - token: address + - sender: address + - receiver: address + outputs: + - timestamp: uint256 # last update time + - flowRate: int96 + - deposit: uint256 + - owedDeposit: uint256 + +getFlowByID: + # Get flow data using the agreement ID (keccak256 of sender and receiver). + mutability: view + inputs: + - token: address + - flowId: bytes32 # keccak256(abi.encode(sender, receiver)) + outputs: + - timestamp: uint256 + - flowRate: int96 + - deposit: uint256 + - owedDeposit: uint256 + +getAccountFlowInfo: + # Aggregated flow state for an account across all its CFA flows. + mutability: view + inputs: + - token: address + - account: address + outputs: + - timestamp: uint256 # last time any flow was updated for this account + - flowRate: int96 # net flow rate (inflows - outflows) + - deposit: uint256 # sum of deposits across all outflows + - owedDeposit: uint256 # sum of owed deposits across all outflows + +getNetFlow: + # Net flow rate for an account (sum of inflows minus outflows). + mutability: view + inputs: + - token: address + - account: address + outputs: + - flowRate: int96 + +# == ACL Management == +# Manage flow operator permissions and flow rate allowances. +# The caller (ctx.msgSender) is always the permission granter — they control +# who can operate on their own flows. +# Functions with ctx are called through the Host. + +updateFlowOperatorPermissions: + # Set exact permissions and flow rate allowance for a flow operator. + mutability: nonpayable + access: anyone # grants on ctx.msgSender's flows + inputs: + - token: address + - flowOperator: address + - permissions: uint8 # bitmask: 1=create, 2=update, 4=delete + - flowRateAllowance: int96 + - ctx: bytes + outputs: + - newCtx: bytes + emits: [FlowOperatorUpdated] + errors: [CFA_ACL_UNCLEAN_PERMISSIONS, CFA_ACL_NO_SENDER_FLOW_OPERATOR, CFA_ACL_NO_NEGATIVE_ALLOWANCE] + +authorizeFlowOperatorWithFullControl: + # Grant all permissions (create+update+delete) with unlimited allowance. + # Shorthand for updateFlowOperatorPermissions(token, op, 7, type(int96).max, ctx). + mutability: nonpayable + access: anyone # grants on ctx.msgSender's flows + inputs: + - token: address + - flowOperator: address + - ctx: bytes + outputs: + - newCtx: bytes + emits: [FlowOperatorUpdated] + errors: [CFA_ACL_UNCLEAN_PERMISSIONS, CFA_ACL_NO_SENDER_FLOW_OPERATOR, CFA_ACL_NO_NEGATIVE_ALLOWANCE] + +revokeFlowOperatorWithFullControl: + # Revoke all permissions and set allowance to zero. + # Shorthand for updateFlowOperatorPermissions(token, op, 0, 0, ctx). + mutability: nonpayable + access: anyone # revokes on ctx.msgSender's flows + inputs: + - token: address + - flowOperator: address + - ctx: bytes + outputs: + - newCtx: bytes + emits: [FlowOperatorUpdated] + errors: [CFA_ACL_UNCLEAN_PERMISSIONS, CFA_ACL_NO_SENDER_FLOW_OPERATOR, CFA_ACL_NO_NEGATIVE_ALLOWANCE] + +increaseFlowRateAllowance: + # Increase flow rate allowance for an operator by a delta. + # Delegates to increaseFlowRateAllowanceWithPermissions with permissionsToAdd=0. + mutability: nonpayable + access: anyone # ctx.msgSender's allowance + inputs: + - token: address + - flowOperator: address + - addedFlowRateAllowance: int96 + - ctx: bytes + outputs: + - newCtx: bytes + emits: [FlowOperatorUpdated] + errors: [CFA_ACL_UNCLEAN_PERMISSIONS, CFA_ACL_NO_SENDER_FLOW_OPERATOR, CFA_ACL_NO_NEGATIVE_ALLOWANCE] + +decreaseFlowRateAllowance: + # Decrease flow rate allowance for an operator by a delta. + # Delegates to decreaseFlowRateAllowanceWithPermissions with permissionsToRemove=0. + mutability: nonpayable + access: anyone # ctx.msgSender's allowance + inputs: + - token: address + - flowOperator: address + - subtractedFlowRateAllowance: int96 + - ctx: bytes + outputs: + - newCtx: bytes + emits: [FlowOperatorUpdated] + errors: [CFA_ACL_UNCLEAN_PERMISSIONS, CFA_ACL_NO_SENDER_FLOW_OPERATOR, CFA_ACL_NO_NEGATIVE_ALLOWANCE] + +increaseFlowRateAllowanceWithPermissions: + # Increase flow rate allowance and add permission bits in one call. + # permissionsToAdd is OR'd with existing permissions. + mutability: nonpayable + access: anyone # ctx.msgSender's allowance + inputs: + - token: address + - flowOperator: address + - permissionsToAdd: uint8 # bitmask OR'd onto existing permissions + - addedFlowRateAllowance: int96 + - ctx: bytes + outputs: + - newCtx: bytes + emits: [FlowOperatorUpdated] + errors: [CFA_ACL_UNCLEAN_PERMISSIONS, CFA_ACL_NO_SENDER_FLOW_OPERATOR, CFA_ACL_NO_NEGATIVE_ALLOWANCE] + +decreaseFlowRateAllowanceWithPermissions: + # Decrease flow rate allowance and remove permission bits in one call. + # permissionsToRemove is AND-NOT'd from existing permissions. + notes: + - "Gotcha: Reverts if the resulting allowance would go negative." + mutability: nonpayable + access: anyone # ctx.msgSender's allowance + inputs: + - token: address + - flowOperator: address + - permissionsToRemove: uint8 # bitmask AND-NOT'd from existing permissions + - subtractedFlowRateAllowance: int96 + - ctx: bytes + outputs: + - newCtx: bytes + emits: [FlowOperatorUpdated] + errors: [CFA_ACL_UNCLEAN_PERMISSIONS, CFA_ACL_NO_SENDER_FLOW_OPERATOR, CFA_ACL_NO_NEGATIVE_ALLOWANCE] + +# == ACL Queries == + +getFlowOperatorData: + # Get permissions and allowance for a flow operator. + mutability: view + inputs: + - token: address + - sender: address # the permission granter + - flowOperator: address # the permission grantee + outputs: + - flowOperatorId: bytes32 # keccak256(abi.encode("flowOperator", sender, flowOperator)) + - permissions: uint8 # bitmask: 1=create, 2=update, 4=delete + - flowRateAllowance: int96 + +getFlowOperatorDataByID: + # Get permissions and allowance using the pre-computed operator ID. + mutability: view + inputs: + - token: address + - flowOperatorId: bytes32 + outputs: + - permissions: uint8 + - flowRateAllowance: int96 + +# == Solvency Queries == +# Check whether an account is in the patrician period (grace window for liquidation). + +isPatricianPeriodNow: + # Check patrician period status using the Host's current timestamp. + mutability: view + inputs: + - token: address + - account: address + outputs: + - isCurrentlyPatricianPeriod: bool + - timestamp: uint256 # the Host's block.timestamp used for the check + +isPatricianPeriod: + # Check patrician period status at a specific timestamp. + mutability: view + inputs: + - token: address + - account: address + - timestamp: uint256 + outputs: + - bool + +# == Deposit Helpers == + +getMaximumFlowRateFromDeposit: + # Calculate the maximum flow rate achievable with a given deposit. + notes: + - "Gotcha: Deposit is clipped (lower 32 bits zeroed) and rounded down." + mutability: view + inputs: + - token: address # needed to look up liquidation period from governance + - deposit: uint256 + outputs: + - flowRate: int96 + errors: [CFA_DEPOSIT_TOO_BIG] + +getDepositRequiredForFlowRate: + # Calculate the deposit required for a given flow rate. + # Returns max(minimumDeposit, flowRate * liquidationPeriod) with rounding. + mutability: view + inputs: + - token: address # needed to look up liquidation period and minimum deposit + - flowRate: int96 + outputs: + - deposit: uint256 + errors: [CFA_INVALID_FLOW_RATE, CFA_FLOW_RATE_TOO_BIG] + +# == Protocol Constants == + +agreementType: + # Returns keccak256("org.superfluid-finance.agreements.ConstantFlowAgreement.v1") + mutability: pure + outputs: + - bytes32 + +DEFAULT_MINIMUM_DEPOSIT: + # Minimum deposit floor: uint96(1 << 32) ≈ 4.29 * 10^9 wei. + # Governance may set a higher per-token minimum; this is the absolute floor. + mutability: view + outputs: + - uint256 + +MAXIMUM_DEPOSIT: + # Maximum deposit cap: type(int96).max + mutability: view + outputs: + - uint256 + +MAXIMUM_FLOW_RATE: + # Maximum flow rate: type(int96).max + mutability: view + outputs: + - uint256 + +CFA_HOOK_GAS_LIMIT: + # Gas limit for external hook calls (Super App callbacks): 250,000 + mutability: view + outputs: + - uint64 + +# == Events == + +events: + FlowUpdated: + # Emitted on every create, update, and delete flow operation. + # totalSenderFlowRate and totalReceiverFlowRate are the NET flow rates + # after the operation, not the individual flow rate. + notes: + - "Gotcha: Always emitted together with FlowUpdatedExtension." + indexed: + - token: address + - sender: address + - receiver: address + data: + - flowRate: int96 # new rate for this specific flow (0 on delete) + - totalSenderFlowRate: int256 # sender's net flow rate after this operation + - totalReceiverFlowRate: int256 + - userData: bytes + + FlowUpdatedExtension: + # Companion event to FlowUpdated. Carries the operator and new deposit. + # Emitted immediately after FlowUpdated so indexers can correlate them. + indexed: + - flowOperator: address # ctx.msgSender who initiated the operation + data: + - deposit: uint256 # new deposit for this specific flow + + FlowOperatorUpdated: + # Emitted when operator permissions or flow rate allowance change. + indexed: + - token: address + - sender: address # the permission granter + - flowOperator: address # the permission grantee + data: + - permissions: uint8 # updated bitmask + - flowRateAllowance: int96 # updated allowance + + # Inherited events (from AgreementBase / UUPSProxiable): + # CodeUpdated — emitted on proxy upgrade (uuid, codeAddress) + # Initialized — emitted on proxy initialization (version) + +# == Errors == + +errors: + # Flow validation + - CFA_FLOW_ALREADY_EXISTS # createFlow when flow exists + - CFA_FLOW_DOES_NOT_EXIST # update/delete when no flow + - CFA_INVALID_FLOW_RATE # flowRate <= 0 + - CFA_NO_SELF_FLOW # sender == receiver + - CFA_ZERO_ADDRESS_SENDER # sender is address(0) + - CFA_ZERO_ADDRESS_RECEIVER # receiver is address(0) + # Solvency + - CFA_INSUFFICIENT_BALANCE # sender cannot cover deposit + - CFA_NON_CRITICAL_SENDER # third-party delete but sender is solvent + - CFA_DEPOSIT_TOO_BIG # deposit > MAXIMUM_DEPOSIT + - CFA_FLOW_RATE_TOO_BIG # flowRate * liquidationPeriod overflows + # ACL + - CFA_ACL_FLOW_RATE_ALLOWANCE_EXCEEDED # operator exceeds granted allowance + - CFA_ACL_NO_NEGATIVE_ALLOWANCE # resulting allowance would be < 0 + - CFA_ACL_NO_SENDER_CREATE # operator cannot be the sender (use createFlow) + - CFA_ACL_NO_SENDER_FLOW_OPERATOR # cannot set yourself as your own operator + - CFA_ACL_NO_SENDER_UPDATE # operator cannot be the sender (use updateFlow) + - CFA_ACL_OPERATOR_NO_CREATE_PERMISSIONS + - CFA_ACL_OPERATOR_NO_DELETE_PERMISSIONS + - CFA_ACL_OPERATOR_NO_UPDATE_PERMISSIONS + - CFA_ACL_UNCLEAN_PERMISSIONS # permission bits outside valid range + # Super App / Host + - CFA_HOOK_OUT_OF_GAS # Super App callback exceeded gas limit + - APP_RULE: # Super App rule violation + inputs: + - _code: uint256 + - AGREEMENT_BASE_ONLY_HOST # call not routed through the Host contract + # SafeCast (inherited from OpenZeppelin) + - SafeCastOverflowedIntToUint: # int256 value overflows on cast to uint256 + inputs: + - value: int256 + - SafeCastOverflowedUintToInt: # uint256 value overflows on cast to int256 + inputs: + - value: uint256 diff --git a/.agents/skills/gooddollar/references/contracts/ConstantFlowAgreementV1.selectors.yaml b/.agents/skills/gooddollar/references/contracts/ConstantFlowAgreementV1.selectors.yaml new file mode 100644 index 0000000..a929e06 --- /dev/null +++ b/.agents/skills/gooddollar/references/contracts/ConstantFlowAgreementV1.selectors.yaml @@ -0,0 +1,33 @@ +# Generated by scripts/selectors.mjs +functions: + createFlow(address,address): 0x7deac86a + updateFlow(address,address): 0xb6214437 + deleteFlow(address,address,address,bytes): 0xb4b333c6 + createFlowByOperator(address,address,address): 0x97b0b745 + updateFlowByOperator(address,address,address): 0xaea4dc29 + deleteFlowByOperator(address,address,address,bytes): 0x4c8b181f + realtimeBalanceOf(address,address,uint256): 0x9b2e48bc + getFlow(address,address,address): 0xe6a1e888 + getFlowByID(address): 0x4eccd8ac + getAccountFlowInfo(address,address): 0x0f1ac495 + getNetFlow(address,address): 0xe8e7e2d1 + updateFlowOperatorPermissions(address,address): 0x42294caf + authorizeFlowOperatorWithFullControl(address,address,bytes): 0x54b770e3 + revokeFlowOperatorWithFullControl(address,address,bytes): 0x062e56ec + increaseFlowRateAllowance(address,address,int96,bytes): 0xac5f5d00 + decreaseFlowRateAllowance(address,address,int96,bytes): 0x5f51fb23 + increaseFlowRateAllowanceWithPermissions(address,address): 0x5e6a4dc3 + decreaseFlowRateAllowanceWithPermissions(address,address): 0x8de39d9b + getFlowOperatorData(address): 0x5f13dbbc + getFlowOperatorDataByID(address,bytes32): 0x09d256ef + isPatricianPeriodNow(address,address): 0x4fe9c291 + isPatricianPeriod(address,address,uint256): 0x4b839e0b + getMaximumFlowRateFromDeposit(): 0x4ba52c34 + getDepositRequiredForFlowRate(): 0xcc111b9e + CFA_HOOK_GAS_LIMIT(): 0xbf3fbc28 +events: + FlowUpdated(address,address,address,int256,bytes): 0x8e3b8f31fe09d2ca20fa7f76ec574bc9fea49f16a91f1ca828154ea76e76a20a + FlowUpdatedExtension(): 0x9bf0b3e0199b411ca09607d040b7672430af5dae9d159b715c9f8004c876065f + FlowOperatorUpdated(address): 0x401d2cb05b3db80617d70aabf976f52d2a5dac64298eadeed7a81ad4bb5d4fdd + # Inherited events (from AgreementBase / UUPSProxiable)(): 0xcabfd4ad95e3bb803739ac513717fccee724fc0c5741e01cf84319a96120eefa +errors: {} diff --git a/.agents/skills/gooddollar/references/contracts/GoodDollarOFTAdapter.abi.yaml b/.agents/skills/gooddollar/references/contracts/GoodDollarOFTAdapter.abi.yaml new file mode 100644 index 0000000..c60d498 --- /dev/null +++ b/.agents/skills/gooddollar/references/contracts/GoodDollarOFTAdapter.abi.yaml @@ -0,0 +1,100 @@ +# GoodDollarOFTAdapter — LayerZero V2 OFT adapter pattern bridging underlying G$ +# Exact bytecode lives in the GoodDollar OFT deployment; this documents the surface agents call. + +meta: + name: GoodDollarOFTAdapter + version: LayerZero-OFT-adapter (generic) + source: + - https://docs.layerzero.network/ + - https://github.com/LayerZero-Labs/devtools + note: > + Flow: optional peers(dstEid) check -> approve underlying to minterBurner if + MessagingFee, refundAddress) paying nativeFee in msg.value when applicable. + SendParam mirrors LayerZero OFT: dstEid, to (bytes32 padded recipient), + amountLD, minAmountLD, extraOptions, composeMsg, oftCmd. + Verify tuple field order and OFT revision against your deployed artifact before mainnet use. + Event names and topic0 hashes vary by OFT package version — pull from the deployment ABI. + related: + - references/guides/bridge.md + +token: + mutability: view + inputs: [] + outputs: + - underlyingToken: address + +minterBurner: + notes: + - "Underlying G$ must approve this spender when burning for cross-chain send." + mutability: view + inputs: [] + outputs: + - minterBurner: address + +oftVersion: + mutability: view + inputs: [] + outputs: + - interfaceId: bytes4 + - version: uint64 + +peers: + notes: + - "Returns bytes32 peer address configured for destination endpoint id." + mutability: view + inputs: + - dstEid: uint32 + outputs: + - peer: bytes32 + +endpoint: + mutability: view + inputs: [] + outputs: + - lzEndpoint: address + +owner: + mutability: view + inputs: [] + outputs: + - account: address + +quoteSend: + notes: + - "Simulates messaging + bridge fee; use nativeFee as msg.value on send when paying in native gas token." + mutability: view + inputs: + - sendParam: SendParam + - payInLzToken: bool + outputs: + - nativeFee: uint256 + - lzTokenFee: uint256 + errors: + - NO_PEER + - LZ_INVALID_OPTIONS + +send: + notes: + - "Payable: include MessagingFee.nativeFee in msg.value when fee is native." + - "Consumes sendParam.amountLD from sender on source chain and emits cross-chain message to dstEid peer." + - "sendParam.to must be destination receiver encoded as bytes32." + mutability: payable + access: sender + inputs: + - sendParam: SendParam + - fee: MessagingFee + - refundAddress: address + outputs: + - msgReceipt: MessageReceipt + - oftReceipt: OFTReceipt + errors: + - NO_PEER + - SLIPPAGE_OR_AMOUNT + - LZ_INVALID_OPTIONS + +events: {} + +errors: + NO_PEER: "Destination peer not configured for dstEid." + LZ_INVALID_OPTIONS: "Composer/options payload rejected by LayerZero." + SLIPPAGE_OR_AMOUNT: "Bridged amount violates minAmount or available balance." diff --git a/.agents/skills/gooddollar/references/contracts/GoodDollarOFTAdapter.selectors.yaml b/.agents/skills/gooddollar/references/contracts/GoodDollarOFTAdapter.selectors.yaml new file mode 100644 index 0000000..e5615a1 --- /dev/null +++ b/.agents/skills/gooddollar/references/contracts/GoodDollarOFTAdapter.selectors.yaml @@ -0,0 +1,12 @@ +# Generated by scripts/selectors.mjs +functions: + token(): 0xfc0c546a + minterBurner(): 0x2ef8c5a4 + approvalRequired(): 0x9f68b964 + oftVersion(): 0x156a0d0f + peers(uint32): 0xbb0b6a53 + endpoint(): 0x5e280f11 + owner(): 0x8da5cb5b +events: +{} +errors: {} diff --git a/.agents/skills/gooddollar/references/contracts/GooddollarSavingsStream.abi.yaml b/.agents/skills/gooddollar/references/contracts/GooddollarSavingsStream.abi.yaml new file mode 100644 index 0000000..d736bc1 --- /dev/null +++ b/.agents/skills/gooddollar/references/contracts/GooddollarSavingsStream.abi.yaml @@ -0,0 +1,210 @@ +# GooddollarSavingsStream (Ubeswap) — G$ native Super Token stake with Superfluid GDA reward stream + +meta: + name: GooddollarSavingsStream + version: "1" + source: + - https://raw.githubusercontent.com/Ubeswap/gooddollar-contracts/main/contracts/GooddollarSavingsStream.sol + - https://raw.githubusercontent.com/Ubeswap/gooddollar-contracts/main/contracts/interfaces/IGooddollarSavingsStream.sol + - https://raw.githubusercontent.com/Ubeswap/gooddollar-contracts/main/contracts/StakingVault.sol + inherits: + - IGooddollarSavingsStream + - Ownable + - ERC2771Context + - ReentrancyGuard + note: > + Celo production savings. Staked principal sits in StakingVault; this contract holds reward + balance and streams via a Superfluid GDA distribution pool (`distributeFlow`). Effective rate is + min(rewardRate, maxRewardRatePerToken * totalSupply / 1e18), throttled when reward balance is low. + Staking token is the G$ native Super Token (`superToken`). Fuse->CELO migration uses `stakeFor` + after bridge. Ubeswap lists this as Celo mainnet savings (streaming). + deployments: + mainnet: + production-celo: + GooddollarSavingsStream: + networkId: 42220 + address: "0x059ee811414230d1Fb157878D2b491240F4D8d3B" + creationBlock: 66685884 + related: + - https://github.com/Ubeswap/gooddollar-contracts/blob/main/README.md + - https://celoscan.io/address/0x059ee811414230d1Fb157878D2b491240F4D8d3B + - references/contracts/SuperToken.abi.yaml + - references/guides/migrate-fuse-staking-to-celo-savings.md + - references/deep-researches/fuse-to-celo-staking-migration.md + +totalSupply: + mutability: view + inputs: [] + outputs: + - supply: uint256 + +balanceOf: + mutability: view + inputs: + - account: address + outputs: + - balance: uint256 + +getDailyRewards: + mutability: view + inputs: [] + outputs: + - daily: uint256 + +getEffectiveFlowRate: + notes: + - "Returns 0 when totalSupply is 0, rewardRate is 0, or reward balance cannot sustain MIN_STREAM_BUFFER_SECONDS." + - "Otherwise min(global rewardRate, APR cap) as int96 for Superfluid distributeFlow." + mutability: view + inputs: [] + outputs: + - flowRate: int96 + +periodFinish: + notes: + - "Estimated timestamp when current reward balance is drained at getEffectiveFlowRate; 0 if not streaming." + mutability: view + inputs: [] + outputs: + - finish: uint256 + +getUnits: + mutability: view + inputs: + - account: address + outputs: + - units: uint128 + +getTotalUnits: + mutability: view + inputs: [] + outputs: + - units: uint128 + +stake: + notes: + - "Pulls G$ Super Token from msg.sender, deposits principal to StakingVault, updates GDA pool units, syncFlowRate." + - "Requires prior superToken.approve(this, amount)." + mutability: nonpayable + access: anyone + inputs: + - amount: uint256 + outputs: [] + emits: [Staked] + +stakeFor: + notes: + - "Migrator path: caller funds transfer; stake credits `_balances[recipient]` and pool units for recipient." + - "recipient must not be zero, this, superToken, or vault." + - "Used after Fuse->CELO bridge when backend wallet holds bridged G$." + mutability: nonpayable + access: anyone + inputs: + - amount: uint256 + - recipient: address + outputs: [] + emits: [Staked] + +withdraw: + notes: + - "Reduces stake and pool units, syncFlowRate, then vault.withdraw to msg.sender." + mutability: nonpayable + access: anyone + inputs: + - amount: uint256 + outputs: [] + emits: [Withdrawn] + +exit: + notes: + - "Full withdraw of caller principal via withdraw(balance)." + mutability: nonpayable + access: anyone + inputs: [] + outputs: [] + emits: [Withdrawn] + +addToReward: + notes: + - "Pulls reward Super Token from caller; re-syncs flow rate when balance was throttling the stream." + mutability: nonpayable + access: anyone + inputs: + - reward: uint256 + outputs: [] + emits: [RewardAdded] + +syncFlowRate: + notes: + - "Permissionless; call when tokens were sent directly to the contract so distributeFlow picks up balance." + mutability: nonpayable + access: anyone + inputs: [] + outputs: [] + emits: [FlowRateUpdated] + +setDailyRewards: + mutability: nonpayable + access: owner + inputs: + - _dailyRewards: uint256 + outputs: [] + emits: [DailyRewardsUpdated] + +setMaxRewardRatePerToken: + mutability: nonpayable + access: owner + inputs: + - _value: uint256 + outputs: [] + emits: [MaxRewardRateUpdated] + +recoverERC20: + notes: + - "Cannot recover the G$ Super Token (staking/reward asset)." + mutability: nonpayable + access: owner + inputs: + - tokenAddress: address + - tokenAmount: uint256 + outputs: [] + emits: [Recovered] + +events: + Staked: + indexed: + - user: address + data: + - amount: uint256 + Withdrawn: + indexed: + - user: address + data: + - amount: uint256 + RewardAdded: + data: + - reward: uint256 + DailyRewardsUpdated: + data: + - rewardRate: uint256 + - givenDailyRewards: uint256 + MaxRewardRateUpdated: + data: + - newMaxRate: uint256 + FlowRateUpdated: + data: + - newFlowRate: int96 + Recovered: + indexed: + - token: address + data: + - amount: uint256 + - receiver: address + +errors: + - CannotStakeZero + - CannotWithdrawZero + - InsufficientStake + - InvalidAddress + - NoRewardToAdd + - CannotRecoverStakingToken diff --git a/.agents/skills/gooddollar/references/contracts/GooddollarSavingsStream.selectors.yaml b/.agents/skills/gooddollar/references/contracts/GooddollarSavingsStream.selectors.yaml new file mode 100644 index 0000000..f04d75a --- /dev/null +++ b/.agents/skills/gooddollar/references/contracts/GooddollarSavingsStream.selectors.yaml @@ -0,0 +1,27 @@ +# Generated by scripts/selectors.mjs +functions: + totalSupply(): 0x18160ddd + balanceOf(address): 0x70a08231 + getDailyRewards(): 0x68527008 + getEffectiveFlowRate(): 0xa2efe857 + periodFinish(): 0xebe2b12b + getUnits(address): 0x0fefbc09 + getTotalUnits(): 0xa754a702 + stake(uint256): 0xa694fc3a + stakeFor(uint256,address): 0x51746bb2 + withdraw(uint256): 0x2e1a7d4d + exit(): 0xe9fad8ee + addToReward(uint256): 0x2ce618fa + syncFlowRate(): 0x0e83284a + setDailyRewards(uint256): 0x4adef718 + setMaxRewardRatePerToken(uint256): 0x6a03a9e2 + recoverERC20(address,uint256): 0x8980f11f +events: + Staked(address,uint256): 0x9e71bc8eea02a63969f509818f2dafb9254532904319f9dbda79b67bd34a5f3d + Withdrawn(address,uint256): 0x7084f5476618d8e60b11ef0d7d3f06914655adb8793e28ff7f018d4c76d505d5 + RewardAdded(uint256): 0xde88a922e0d3b88b24e9623efeb464919c6bf9f66857a65e2bfcf2ce87a9433d + DailyRewardsUpdated(uint256,uint256): 0x54f5b7ef058007cebca11af0127cd80c0bac4e968788eabb3c1e70d1bfb78edd + MaxRewardRateUpdated(uint256): 0x9041b23d05af9bceefc73becffefd1887907ad55c3d6c6655230b37ef87dbb07 + FlowRateUpdated(int96): 0xd02fcf6b96acb60ac68942c7d5075e11a8a0b38cc865c1916934f4e1f129ded0 + Recovered(address,uint256,address): 0xb197f0a554c4d7840105e6ae65f0e275e9e8605a969dffa8caa7f1f118a2e1f5 +errors: {} diff --git a/.agents/skills/gooddollar/references/contracts/GovernanceStakingV2.abi.yaml b/.agents/skills/gooddollar/references/contracts/GovernanceStakingV2.abi.yaml new file mode 100644 index 0000000..5adccb3 --- /dev/null +++ b/.agents/skills/gooddollar/references/contracts/GovernanceStakingV2.abi.yaml @@ -0,0 +1,202 @@ +# GovernanceStakingV2 (Fuse) — G$ staking share token with GDAO reward accrual +# Deployment key in GoodProtocol release metadata is GovernanceStakingV2. + +meta: + name: GovernanceStakingV2 + version: "2" + source: + - https://raw.githubusercontent.com/GoodDollar/GoodProtocol/master/contracts/governance/GovernanceStaking.sol + - https://raw.githubusercontent.com/GoodDollar/GoodProtocol/master/releases/deployment.json + inherits: + - ERC20Upgradeable + - MultiBaseGovernanceShareField + - DAOUpgradeableContract + - ReentrancyGuardUpgradeable + note: > + Fuse governance staking contract where users stake G$ and receive staking shares (`sG$`) with + GDAO-style rewards minted on reward withdrawal paths. `withdrawStake(0)` means full unstake. + In GoodProtocol `releases/deployment.json` this address is listed as GovernanceStakingV2 on Fuse `production`. + This is the old staking contract in Fuse->CELO migration flows. + deployments: + mainnet: + production: + GovernanceStakingV2: + networkId: 122 + address: "0xB7C3e738224625289C573c54d402E9Be46205546" + creationBlock: 15956809 + related: + - references/guides/migrate-fuse-staking-to-celo-savings.md + - references/deep-researches/fuse-to-celo-staking-migration.md + +getChainBlocksPerMonth: + mutability: pure + inputs: [] + outputs: + - blocks: uint256 + +stake: + notes: + - "Requires prior G$ ERC20 approval to staking contract." + - "Mints staking share token and updates reward productivity before event emission." + mutability: nonpayable + access: anyone + inputs: + - _amount: uint256 + outputs: [] + emits: [Staked] + +withdrawStake: + notes: + - "If _amount is 0, contract interprets it as full user unstake." + - "Burns staking shares, updates productivity, mints pending rewards, then transfers G$ out." + mutability: nonpayable + access: anyone + inputs: + - _amount: uint256 + outputs: [] + emits: [StakeWithdraw] + +withdrawRewards: + notes: + - "Claims rewards without changing staked principal." + mutability: nonpayable + access: anyone + inputs: [] + outputs: + - minted: uint256 + emits: [ReputationEarned] + +setMonthlyRewards: + notes: + - "DAO-controlled update of rewardsPerBlock schedule via avatar authorization." + mutability: nonpayable + access: avatar + inputs: + - _monthlyAmount: uint256 + outputs: [] + +getRewardsPerBlock: + mutability: view + inputs: [] + outputs: + - amount: uint256 + +getProductivity: + mutability: view + inputs: + - _user: address + outputs: + - productivity: uint256 + - rewardDebt: uint256 + +getUserPendingReward: + mutability: view + inputs: + - _user: address + outputs: + - pending: uint256 + +users: + notes: + - "UserInfo getter for internal staking productivity record." + mutability: view + inputs: + - _user: address + outputs: + - amount: uint256 + - rewardDebt: uint256 + +totalRewardsPerShare: + mutability: view + inputs: [] + outputs: + - value: uint256 + +decimals: + mutability: view + inputs: [] + outputs: + - d: uint8 + +totalSupply: + mutability: view + inputs: [] + outputs: + - supply: uint256 + +balanceOf: + mutability: view + inputs: + - account: address + outputs: + - balance: uint256 + +allowance: + mutability: view + inputs: + - owner: address + - spender: address + outputs: + - amount: uint256 + +approve: + mutability: nonpayable + access: anyone + inputs: + - spender: address + - amount: uint256 + outputs: + - ok: bool + emits: [Approval] + +transfer: + mutability: nonpayable + access: anyone + inputs: + - to: address + - amount: uint256 + outputs: + - ok: bool + emits: [Transfer] + +transferFrom: + mutability: nonpayable + access: anyone + inputs: + - from: address + - to: address + - amount: uint256 + outputs: + - ok: bool + emits: [Transfer, Approval] + +events: + ReputationEarned: + indexed: + - staker: address + data: + - amount: uint256 + Staked: + indexed: + - staker: address + data: + - amount: uint256 + StakeWithdraw: + indexed: + - staker: address + data: + - amount: uint256 + Transfer: + indexed: + - from: address + - to: address + data: + - value: uint256 + Approval: + indexed: + - owner: address + - spender: address + data: + - value: uint256 + +errors: {} diff --git a/.agents/skills/gooddollar/references/contracts/GovernanceStakingV2.selectors.yaml b/.agents/skills/gooddollar/references/contracts/GovernanceStakingV2.selectors.yaml new file mode 100644 index 0000000..37388ba --- /dev/null +++ b/.agents/skills/gooddollar/references/contracts/GovernanceStakingV2.selectors.yaml @@ -0,0 +1,26 @@ +# Generated by scripts/selectors.mjs +functions: + getChainBlocksPerMonth(): 0x213b329e + stake(uint256): 0xa694fc3a + withdrawStake(uint256): 0x25d5971f + withdrawRewards(): 0xc7b8981c + setMonthlyRewards(uint256): 0xc76279a2 + getRewardsPerBlock(): 0x0c1cd7f3 + getProductivity(address): 0x28e964e9 + getUserPendingReward(address): 0xc6710629 + users(address): 0xa87430ba + totalRewardsPerShare(): 0xbf8e9b6e + decimals(): 0x313ce567 + totalSupply(): 0x18160ddd + balanceOf(address): 0x70a08231 + allowance(address,address): 0xdd62ed3e + approve(address,uint256): 0x095ea7b3 + transfer(address,uint256): 0xa9059cbb + transferFrom(address,address,uint256): 0x23b872dd +events: + ReputationEarned(address,uint256): 0x43848d0574703c28d68ae8958e0571521618f60c4bcacfb094cff2156eaae0f1 + Staked(address,uint256): 0x9e71bc8eea02a63969f509818f2dafb9254532904319f9dbda79b67bd34a5f3d + StakeWithdraw(address,uint256): 0x1248d48e2de900a1010c7fce73506969ecec243600bfc08b641b158f26d857cd + Transfer(address,address,uint256): 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef + Approval(address,address,uint256): 0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925 +errors: {} diff --git a/.agents/skills/gooddollar/references/contracts/IdentityV3.abi.yaml b/.agents/skills/gooddollar/references/contracts/IdentityV3.abi.yaml new file mode 100644 index 0000000..aea2efe --- /dev/null +++ b/.agents/skills/gooddollar/references/contracts/IdentityV3.abi.yaml @@ -0,0 +1,390 @@ +# IdentityV3 — whitelist, blacklist, DID, and connected-account graph for GoodDollar +# UBI eligibility uses getWhitelistedRoot; connectAccount links extra wallets to a root. + +meta: + name: IdentityV3 + version: v3 + source: + - https://raw.githubusercontent.com/GoodDollar/GoodProtocol/master/contracts/identity/IdentityV3.sol + inherits: + - DAOUpgradeableContract + - AccessControlUpgradeable + - PausableUpgradeable + - EIP712Upgradeable + note: > + isWhitelisted enforces authenticationPeriod against dateAuthenticated and status==1, + with fallback to oldIdentity. getWhitelistedRoot returns the root address for a + connected wallet or the wallet itself when directly whitelisted. + deployments: + mainnet: + production: + Identity: + networkId: 122 + address: "0x2F9C28de9e6d44b71B91b8BA337A5D82e308E7BE" + creationBlock: 22022901 + IdentityOld: + networkId: 122 + address: "0xFa8d865A962ca8456dF331D78806152d3aC5B84F" + creationBlock: 6246324 + production-celo: + Identity: + networkId: 42220 + address: "0xC361A6E67822a0EDc17D899227dd9FC50BD62F42" + creationBlock: 17237952 + production-xdc: + Identity: + networkId: 50 + address: "0x27a4a02C9ed591E1a86e2e5D05870292c34622C9" + creationBlock: 95143058 + related: + - https://docs.gooddollar.org/for-developers/core-contracts/identity + - https://docs.gooddollar.org/user-guides/connect-another-wallet-address-to-identity + +initialize: + mutability: nonpayable + access: initializer + inputs: + - _owner: address + - _oldIdentity: address + outputs: [] + +initDAO: + notes: + - "Wires NameService via setDAO and transfers DEFAULT_ADMIN_ROLE, PAUSER_ROLE, IDENTITY_ADMIN_ROLE to avatar." + mutability: nonpayable + access: DEFAULT_ADMIN_ROLE + inputs: + - _ns: address + outputs: [] + errors: [ALREADY_INITIALIZED] + +setAuthenticationPeriod: + mutability: nonpayable + access: avatar + inputs: + - period: uint256 + outputs: [] + errors: [WHEN_NOT_PAUSED_REVERT] + +authenticate: + notes: + - "Public wrapper; forwards to authenticateWithTimestamp(account, block.timestamp)." + mutability: nonpayable + inputs: + - account: address + outputs: [] + +authenticateWithTimestamp: + mutability: nonpayable + access: IDENTITY_ADMIN_ROLE + inputs: + - account: address + - timestamp: uint256 + outputs: [] + emits: [WhitelistedAuthenticated] + errors: [NOT_WHITELISTED_STATUS, WHEN_NOT_PAUSED_REVERT] + +addWhitelisted: + mutability: nonpayable + access: IDENTITY_ADMIN_ROLE + inputs: + - account: address + outputs: [] + emits: [WhitelistedAdded] + errors: [ALREADY_HAS_STATUS, WHEN_NOT_PAUSED_REVERT] + +addWhitelistedWithDIDAndChain: + mutability: nonpayable + access: IDENTITY_ADMIN_ROLE + inputs: + - account: address + - did: string + - orgChain: uint256 + - dateAuthenticated: uint256 + outputs: [] + emits: [WhitelistedAdded] + errors: [DID_ALREADY_REGISTERED, ALREADY_HAS_STATUS, WHEN_NOT_PAUSED_REVERT] + +addWhitelistedWithDID: + mutability: nonpayable + access: IDENTITY_ADMIN_ROLE + inputs: + - account: address + - did: string + outputs: [] + emits: [WhitelistedAdded] + errors: [DID_ALREADY_REGISTERED, ALREADY_HAS_STATUS, WHEN_NOT_PAUSED_REVERT] + +removeWhitelisted: + mutability: nonpayable + access: IDENTITY_ADMIN_ROLE + inputs: + - account: address + outputs: [] + emits: [WhitelistedRemoved] + errors: [WHEN_NOT_PAUSED_REVERT] + +renounceWhitelisted: + mutability: nonpayable + access: whitelisted sender + inputs: [] + outputs: [] + emits: [WhitelistedRemoved] + errors: [NOT_WHITELISTED_SENDER, WHEN_NOT_PAUSED_REVERT] + +isWhitelisted: + notes: + - "Combines local Identity record with optional oldIdentity.isWhitelisted try/catch." + mutability: view + inputs: + - account: address + outputs: + - ok: bool + +lastAuthenticated: + mutability: view + inputs: + - account: address + outputs: + - ts: uint256 + +addBlacklisted: + mutability: nonpayable + access: IDENTITY_ADMIN_ROLE + inputs: + - account: address + outputs: [] + emits: [BlacklistAdded, WhitelistedRemoved] + errors: [WHEN_NOT_PAUSED_REVERT] + +removeBlacklisted: + mutability: nonpayable + access: IDENTITY_ADMIN_ROLE + inputs: + - account: address + outputs: [] + emits: [BlacklistRemoved] + errors: [WHEN_NOT_PAUSED_REVERT] + +addContract: + mutability: nonpayable + access: IDENTITY_ADMIN_ROLE + inputs: + - account: address + outputs: [] + emits: [ContractAdded] + errors: [NOT_CONTRACT, ALREADY_HAS_STATUS, WHEN_NOT_PAUSED_REVERT] + +removeContract: + mutability: nonpayable + access: IDENTITY_ADMIN_ROLE + inputs: + - account: address + outputs: [] + emits: [ContractRemoved] + errors: [WHEN_NOT_PAUSED_REVERT] + +isDAOContract: + mutability: view + inputs: + - account: address + outputs: + - ok: bool + +isBlacklisted: + mutability: view + inputs: + - account: address + outputs: + - ok: bool + +connectAccount: + notes: + - "Caller must be whitelisted; target must not already be whitelisted or blacklisted; stores connectedAccounts[account]=msg.sender." + mutability: nonpayable + access: whitelisted sender + inputs: + - account: address + outputs: [] + emits: [AccountConnected] + errors: [INVALID_ACCOUNT_FOR_CONNECT, ALREADY_CONNECTED, WHEN_NOT_PAUSED_REVERT] + +disconnectAccount: + notes: + - "Caller must be either the linked root or the connected wallet." + mutability: nonpayable + inputs: + - connected: address + outputs: [] + emits: [AccountDisconnected] + errors: [UNAUTHORIZED_DISCONNECT] + +getWhitelistedRoot: + notes: + - "Returns account if directly whitelisted; returns connected root if connected account is whitelisted; else zero." + mutability: view + inputs: + - account: address + outputs: + - whitelisted: address + +pause: + mutability: nonpayable + access: PAUSER_ROLE + inputs: + - toPause: bool + outputs: [] + +setDID: + mutability: nonpayable + inputs: + - account: address + - did: string + outputs: [] + errors: [NOT_AUTHORIZED_SET_DID, NOT_WHITELISTED_FOR_DID, DID_EMPTY, DID_ALREADY_REGISTERED, DID_ALREADY_REGISTERED_OLD, WHEN_NOT_PAUSED_REVERT] + +addrToDID: + mutability: view + inputs: + - account: address + outputs: + - did: string + +getWhitelistedOnChainId: + mutability: view + inputs: + - account: address + outputs: + - chainId: uint256 + +isRegistered: + notes: + - "Compatibility shim; always returns true." + mutability: pure + inputs: [] + outputs: + - ok: bool + +IDENTITY_ADMIN_ROLE: + mutability: view + inputs: [] + outputs: + - role: bytes32 + +PAUSER_ROLE: + mutability: view + inputs: [] + outputs: + - role: bytes32 + +TYPED_STRUCTURE: + mutability: view + inputs: [] + outputs: + - schema: string + +whitelistedCount: + mutability: view + inputs: [] + outputs: + - n: uint256 + +whitelistedContracts: + mutability: view + inputs: [] + outputs: + - n: uint256 + +authenticationPeriod: + mutability: view + inputs: [] + outputs: + - seconds: uint256 + +identities: + mutability: view + inputs: + - account: address + outputs: + - dateAuthenticated: uint256 + - dateAdded: uint256 + - did: string + - whitelistedOnChainId: uint256 + - status: uint8 + +didHashToAddress: + mutability: view + inputs: + - hash: bytes32 + outputs: + - account: address + +connectedAccounts: + mutability: view + inputs: + - account: address + outputs: + - root: address + +oldIdentity: + mutability: view + inputs: [] + outputs: + - addr: address + +events: + BlacklistAdded: + indexed: + - account: address + data: [] + BlacklistRemoved: + indexed: + - account: address + data: [] + WhitelistedAdded: + indexed: + - account: address + data: [] + WhitelistedRemoved: + indexed: + - account: address + data: [] + WhitelistedAuthenticated: + indexed: + - account: address + data: + - timestamp: uint256 + ContractAdded: + indexed: + - account: address + data: [] + ContractRemoved: + indexed: + - account: address + data: [] + AccountConnected: + indexed: + - connected: address + - to: address + data: [] + AccountDisconnected: + indexed: + - disconnected: address + - from: address + data: [] + +errors: + ALREADY_INITIALIZED: "already initialized — initDAO twice." + NOT_WHITELISTED_STATUS: "not whitelisted — authenticateWithTimestamp." + NOT_WHITELISTED_SENDER: "not whitelisted — renounceWhitelisted modifier." + NOT_WHITELISTED_FOR_DID: "not whitelisted — setDID internal." + ALREADY_HAS_STATUS: "already has status — _addWhitelisted." + DID_ALREADY_REGISTERED: "DID already registered — _addWhitelistedWithDID or _setDID." + DID_ALREADY_REGISTERED_OLD: "DID already registered oldIdentity — _setDID conflict path." + NOT_CONTRACT: "Given address is not a contract — addContract." + INVALID_ACCOUNT_FOR_CONNECT: "invalid account — connectAccount target checks." + ALREADY_CONNECTED: "already connected — connectAccount." + UNAUTHORIZED_DISCONNECT: "unauthorized — disconnectAccount." + NOT_AUTHORIZED_SET_DID: "not authorized — setDID caller." + DID_EMPTY: "did empty — _setDID." + WHEN_NOT_PAUSED_REVERT: "OpenZeppelin Pausable whenNotPaused on gated calls." diff --git a/.agents/skills/gooddollar/references/contracts/IdentityV3.selectors.yaml b/.agents/skills/gooddollar/references/contracts/IdentityV3.selectors.yaml new file mode 100644 index 0000000..9b53f00 --- /dev/null +++ b/.agents/skills/gooddollar/references/contracts/IdentityV3.selectors.yaml @@ -0,0 +1,49 @@ +# Generated by scripts/selectors.mjs +functions: + initialize(address,address): 0x485cc955 + initDAO(address): 0x2b14dda8 + setAuthenticationPeriod(uint256): 0xfff930d4 + authenticate(address): 0x08e0d29d + authenticateWithTimestamp(address,uint256): 0x96a1ef79 + addWhitelisted(address): 0x10154bad + addWhitelistedWithDIDAndChain(address,string,uint256,uint256): 0xe737031a + addWhitelistedWithDID(address,string): 0x1b027099 + removeWhitelisted(address): 0x291d9549 + renounceWhitelisted(): 0xd6cd9473 + isWhitelisted(address): 0x3af32abf + lastAuthenticated(address): 0xe1e360ba + addBlacklisted(address): 0x188efc16 + removeBlacklisted(address): 0xc6a276c2 + addContract(address): 0x5f539d69 + removeContract(address): 0xc375c2ef + isDAOContract(address): 0xc73cc4ae + isBlacklisted(address): 0xfe575a87 + connectAccount(address): 0xd21685f4 + disconnectAccount(address): 0x37a1a987 + getWhitelistedRoot(address): 0x2d0e9b46 + pause(bool): 0x02329a29 + setDID(address,string): 0xd3262816 + addrToDID(address): 0x54f9f7a3 + getWhitelistedOnChainId(address): 0xa061922d + isRegistered(): 0x22366844 + IDENTITY_ADMIN_ROLE(): 0x1aaff63c + PAUSER_ROLE(): 0xe63ab1e9 + TYPED_STRUCTURE(): 0x2cec5330 + whitelistedCount(): 0xb2a1de22 + whitelistedContracts(): 0xb30f7e7f + authenticationPeriod(): 0x31b376e2 + identities(address): 0xf653b81e + didHashToAddress(bytes32): 0x67c75937 + connectedAccounts(address): 0x61320040 + oldIdentity(): 0x4125f0f2 +events: + BlacklistAdded(address): 0x44d5fe68b00f68950fb9c1ff0a61ef7f747b1a36359a7e3a7f3324db4b878967 + BlacklistRemoved(address): 0x1747ca720b1a174a464b6513ace29b1d3190b5f632b9f34147017c81425bfde8 + WhitelistedAdded(address): 0xee1504a83b6d4a361f4c1dc78ab59bfa30d6a3b6612c403e86bb01ef2984295f + WhitelistedRemoved(address): 0x270d9b30cf5b0793bbfd54c9d5b94aeb49462b8148399000265144a8722da6b6 + WhitelistedAuthenticated(address,uint256): 0xb2a82fce6d8c7a633efe9579f77b4edb96bfdf171a49bfc2ce666dc543a1f500 + ContractAdded(address): 0x89c66952b48f3e96bf1d8ba1b63189520fd988a6979b8b740bd5c5d8dc53e205 + ContractRemoved(address): 0x8d30d41865a0b811b9545d879520d2dde9f4cc49e4241f486ad9752bc904b565 + AccountConnected(address,address): 0x18f7736ef54539debd9afd3c9500b106e12ae7c70e685f5a5efd727b1ce1d54c + AccountDisconnected(address,address): 0x7cdef5f9c5cb8ce728661ede956fef26cb91eb4d7d2180cc041b73f9fef568d2 +errors: {} diff --git a/.agents/skills/gooddollar/references/contracts/IdentityV4.abi.yaml b/.agents/skills/gooddollar/references/contracts/IdentityV4.abi.yaml new file mode 100644 index 0000000..485254d --- /dev/null +++ b/.agents/skills/gooddollar/references/contracts/IdentityV4.abi.yaml @@ -0,0 +1,424 @@ +# IdentityV4 — whitelist, blacklist, DID, connected accounts, and reverification schedule +# isWhitelisted uses shouldReverify against reverifyDaysOptions and authCount; oldIdentity fallback preserved. + +meta: + name: IdentityV4 + version: v4 + source: + - https://raw.githubusercontent.com/GoodDollar/GoodProtocol/master/contracts/identity/IdentityV4.sol + inherits: + - DAOUpgradeableContract + - AccessControlUpgradeable + - PausableUpgradeable + - EIP712Upgradeable + note: > + authenticationPeriod() returns the largest reverify interval in days (last entry of reverifyDaysOptions), + not seconds. isWhitelisted is false when shouldReverify is true for the current elapsed days since + dateAuthenticated. Post-upgrade, accounts with dateAuthenticated before 1772697574 are treated as + having authCount at the last schedule step for reverify logic. + deployments: + mainnet: + production: + Identity: + networkId: 122 + address: "0x2F9C28de9e6d44b71B91b8BA337A5D82e308E7BE" + creationBlock: 22022901 + production-celo: + Identity: + networkId: 42220 + address: "0xC361A6E67822a0EDc17D899227dd9FC50BD62F42" + creationBlock: 17237952 + production-xdc: + Identity: + networkId: 50 + address: "0x27a4a02C9ed591E1a86e2e5D05870292c34622C9" + creationBlock: 95143058 + related: + - https://docs.gooddollar.org/for-developers/core-contracts/identity + - https://docs.gooddollar.org/user-guides/connect-another-wallet-address-to-identity + +initialize: + mutability: nonpayable + access: initializer + inputs: + - _owner: address + - _oldIdentity: address + outputs: [] + +initDAO: + notes: + - "Wires NameService via setDAO and transfers DEFAULT_ADMIN_ROLE, PAUSER_ROLE, IDENTITY_ADMIN_ROLE to avatar." + mutability: nonpayable + access: DEFAULT_ADMIN_ROLE + inputs: + - _ns: address + outputs: [] + errors: [ALREADY_INITIALIZED] + +setReverifyDaysOptions: + notes: + - "Replaces the full schedule; values must be strictly ascending uint8 days; non-empty array." + mutability: nonpayable + access: IDENTITY_ADMIN_ROLE + inputs: + - options: uint8[] + outputs: [] + errors: [EMPTY_REVERIFY_OPTIONS, OPTIONS_NOT_ASCENDING, WHEN_NOT_PAUSED_REVERT] + +authenticate: + notes: + - "Forwards to authenticateWithTimestamp(account, block.timestamp); requires IDENTITY_ADMIN_ROLE on the inner call." + mutability: nonpayable + access: IDENTITY_ADMIN_ROLE + inputs: + - account: address + outputs: [] + errors: [NOT_WHITELISTED_STATUS, WHEN_NOT_PAUSED_REVERT] + +authenticateWithTimestamp: + notes: + - "Refreshes authentication timestamp for status-1 account and advances authCount when reverification threshold is reached." + - "Legacy accounts before cutoff are evaluated at last schedule step for reverify math." + mutability: nonpayable + access: IDENTITY_ADMIN_ROLE + inputs: + - account: address + - timestamp: uint256 + outputs: [] + emits: [WhitelistedAuthenticated] + errors: [NOT_WHITELISTED_STATUS, WHEN_NOT_PAUSED_REVERT] + +addWhitelisted: + mutability: nonpayable + access: IDENTITY_ADMIN_ROLE + inputs: + - account: address + outputs: [] + emits: [WhitelistedAdded] + errors: [ALREADY_HAS_STATUS, WHEN_NOT_PAUSED_REVERT] + +addWhitelistedWithDIDAndChain: + notes: + - "Adds whitelisted account and stores DID plus originating chain id and authentication timestamp." + mutability: nonpayable + access: IDENTITY_ADMIN_ROLE + inputs: + - account: address + - did: string + - orgChain: uint256 + - dateAuthenticated: uint256 + outputs: [] + emits: [WhitelistedAdded] + errors: [DID_ALREADY_REGISTERED, ALREADY_HAS_STATUS, WHEN_NOT_PAUSED_REVERT] + +addWhitelistedWithDID: + mutability: nonpayable + access: IDENTITY_ADMIN_ROLE + inputs: + - account: address + - did: string + outputs: [] + emits: [WhitelistedAdded] + errors: [DID_ALREADY_REGISTERED, ALREADY_HAS_STATUS, WHEN_NOT_PAUSED_REVERT] + +removeWhitelisted: + mutability: nonpayable + access: IDENTITY_ADMIN_ROLE + inputs: + - account: address + outputs: [] + emits: [WhitelistedRemoved] + errors: [WHEN_NOT_PAUSED_REVERT] + +renounceWhitelisted: + mutability: nonpayable + access: whitelisted sender + inputs: [] + outputs: [] + emits: [WhitelistedRemoved] + errors: [NOT_WHITELISTED_SENDER, WHEN_NOT_PAUSED_REVERT] + +shouldReverify: + notes: + - "Compares daysSinceAuth against current reverifyDaysOptions step selected by authCount." + mutability: view + inputs: + - account: address + - daysSinceAuth: uint256 + outputs: + - needed: bool + +isWhitelisted: + notes: + - "Local status 1 with shouldReverify false; else oldIdentity.isWhitelisted try/catch." + mutability: view + inputs: + - account: address + outputs: + - ok: bool + +lastAuthenticated: + notes: + - "Returns local dateAuthenticated or falls back to oldIdentity when local record has no timestamp." + mutability: view + inputs: + - account: address + outputs: + - ts: uint256 + +addBlacklisted: + mutability: nonpayable + access: IDENTITY_ADMIN_ROLE + inputs: + - account: address + outputs: [] + emits: [BlacklistAdded, WhitelistedRemoved] + errors: [WHEN_NOT_PAUSED_REVERT] + +removeBlacklisted: + mutability: nonpayable + access: IDENTITY_ADMIN_ROLE + inputs: + - account: address + outputs: [] + emits: [BlacklistRemoved] + errors: [WHEN_NOT_PAUSED_REVERT] + +addContract: + mutability: nonpayable + access: IDENTITY_ADMIN_ROLE + inputs: + - account: address + outputs: [] + emits: [ContractAdded] + errors: [NOT_CONTRACT, ALREADY_HAS_STATUS, WHEN_NOT_PAUSED_REVERT] + +removeContract: + mutability: nonpayable + access: IDENTITY_ADMIN_ROLE + inputs: + - account: address + outputs: [] + emits: [ContractRemoved] + errors: [WHEN_NOT_PAUSED_REVERT] + +isDAOContract: + mutability: view + inputs: + - account: address + outputs: + - ok: bool + +isBlacklisted: + mutability: view + inputs: + - account: address + outputs: + - ok: bool + +connectAccount: + notes: + - "Caller must be whitelisted; target must not already be whitelisted or blacklisted; stores connectedAccounts[account]=msg.sender." + mutability: nonpayable + access: whitelisted sender + inputs: + - account: address + outputs: [] + emits: [AccountConnected] + errors: [INVALID_ACCOUNT_FOR_CONNECT, ALREADY_CONNECTED, WHEN_NOT_PAUSED_REVERT] + +disconnectAccount: + notes: + - "Caller must be either the linked root or the connected wallet." + mutability: nonpayable + inputs: + - connected: address + outputs: [] + emits: [AccountDisconnected] + errors: [UNAUTHORIZED_DISCONNECT] + +getWhitelistedRoot: + notes: + - "Returns account if directly whitelisted; returns connected root if connected account is whitelisted; else zero." + mutability: view + inputs: + - account: address + outputs: + - whitelisted: address + +pause: + mutability: nonpayable + access: PAUSER_ROLE + inputs: + - toPause: bool + outputs: [] + +setDID: + notes: + - "Sets DID for account by admin or account itself when whitelisted; enforces uniqueness across local and old identity." + mutability: nonpayable + inputs: + - account: address + - did: string + outputs: [] + errors: [NOT_AUTHORIZED_SET_DID, NOT_WHITELISTED_FOR_DID, DID_EMPTY, DID_ALREADY_REGISTERED, DID_ALREADY_REGISTERED_OLD, WHEN_NOT_PAUSED_REVERT] + +addrToDID: + mutability: view + inputs: + - account: address + outputs: + - did: string + +getWhitelistedOnChainId: + notes: + - "Returns chain id recorded during whitelisting for cross-chain eligibility checks." + mutability: view + inputs: + - account: address + outputs: + - chainId: uint256 + +isRegistered: + notes: + - "Compatibility shim; always returns true." + mutability: pure + inputs: [] + outputs: + - ok: bool + +IDENTITY_ADMIN_ROLE: + mutability: view + inputs: [] + outputs: + - role: bytes32 + +PAUSER_ROLE: + mutability: view + inputs: [] + outputs: + - role: bytes32 + +TYPED_STRUCTURE: + mutability: view + inputs: [] + outputs: + - schema: string + +whitelistedCount: + mutability: view + inputs: [] + outputs: + - n: uint256 + +whitelistedContracts: + mutability: view + inputs: [] + outputs: + - n: uint256 + +authenticationPeriod: + notes: + - "Returns reverifyDaysOptions[last] in days, not seconds." + mutability: view + inputs: [] + outputs: + - days: uint256 + +reverifyDaysOptions: + mutability: view + inputs: + - index: uint256 + outputs: + - days: uint32 + +identities: + mutability: view + inputs: + - account: address + outputs: + - dateAuthenticated: uint256 + - dateAdded: uint256 + - did: string + - whitelistedOnChainId: uint256 + - status: uint8 + - authCount: uint32 + +didHashToAddress: + mutability: view + inputs: + - hash: bytes32 + outputs: + - account: address + +connectedAccounts: + mutability: view + inputs: + - account: address + outputs: + - root: address + +oldIdentity: + mutability: view + inputs: [] + outputs: + - addr: address + +events: + BlacklistAdded: + indexed: + - account: address + data: [] + BlacklistRemoved: + indexed: + - account: address + data: [] + WhitelistedAdded: + indexed: + - account: address + data: [] + WhitelistedRemoved: + indexed: + - account: address + data: [] + WhitelistedAuthenticated: + indexed: + - account: address + data: + - timestamp: uint256 + ContractAdded: + indexed: + - account: address + data: [] + ContractRemoved: + indexed: + - account: address + data: [] + AccountConnected: + indexed: + - connected: address + - to: address + data: [] + AccountDisconnected: + indexed: + - disconnected: address + - from: address + data: [] + +errors: + ALREADY_INITIALIZED: "already initialized — initDAO twice." + EMPTY_REVERIFY_OPTIONS: "empty options — setReverifyDaysOptions." + OPTIONS_NOT_ASCENDING: "options not in ascending order — setReverifyDaysOptions." + NOT_WHITELISTED_STATUS: "not whitelisted — authenticateWithTimestamp." + NOT_WHITELISTED_SENDER: "not whitelisted — renounceWhitelisted modifier." + NOT_WHITELISTED_FOR_DID: "not whitelisted — _setDID." + ALREADY_HAS_STATUS: "already has status — _addWhitelisted." + DID_ALREADY_REGISTERED: "DID already registered — _addWhitelistedWithDID or _setDID." + DID_ALREADY_REGISTERED_OLD: "DID already registered oldIdentity — _setDID conflict path." + NOT_CONTRACT: "Given address is not a contract — addContract." + INVALID_ACCOUNT_FOR_CONNECT: "invalid account — connectAccount target checks." + ALREADY_CONNECTED: "already connected — connectAccount." + UNAUTHORIZED_DISCONNECT: "unauthorized — disconnectAccount." + NOT_AUTHORIZED_SET_DID: "not authorized — setDID caller." + DID_EMPTY: "did empty — _setDID." + WHEN_NOT_PAUSED_REVERT: "OpenZeppelin Pausable whenNotPaused on gated calls." diff --git a/.agents/skills/gooddollar/references/contracts/IdentityV4.selectors.yaml b/.agents/skills/gooddollar/references/contracts/IdentityV4.selectors.yaml new file mode 100644 index 0000000..3440a5e --- /dev/null +++ b/.agents/skills/gooddollar/references/contracts/IdentityV4.selectors.yaml @@ -0,0 +1,51 @@ +# Generated by scripts/selectors.mjs +functions: + initialize(address,address): 0x485cc955 + initDAO(address): 0x2b14dda8 + setReverifyDaysOptions(uint8[]): 0x925e8c1a + authenticate(address): 0x08e0d29d + authenticateWithTimestamp(address,uint256): 0x96a1ef79 + addWhitelisted(address): 0x10154bad + addWhitelistedWithDIDAndChain(address,string,uint256,uint256): 0xe737031a + addWhitelistedWithDID(address,string): 0x1b027099 + removeWhitelisted(address): 0x291d9549 + renounceWhitelisted(): 0xd6cd9473 + shouldReverify(address,uint256): 0x4a03813f + isWhitelisted(address): 0x3af32abf + lastAuthenticated(address): 0xe1e360ba + addBlacklisted(address): 0x188efc16 + removeBlacklisted(address): 0xc6a276c2 + addContract(address): 0x5f539d69 + removeContract(address): 0xc375c2ef + isDAOContract(address): 0xc73cc4ae + isBlacklisted(address): 0xfe575a87 + connectAccount(address): 0xd21685f4 + disconnectAccount(address): 0x37a1a987 + getWhitelistedRoot(address): 0x2d0e9b46 + pause(bool): 0x02329a29 + setDID(address,string): 0xd3262816 + addrToDID(address): 0x54f9f7a3 + getWhitelistedOnChainId(address): 0xa061922d + isRegistered(): 0x22366844 + IDENTITY_ADMIN_ROLE(): 0x1aaff63c + PAUSER_ROLE(): 0xe63ab1e9 + TYPED_STRUCTURE(): 0x2cec5330 + whitelistedCount(): 0xb2a1de22 + whitelistedContracts(): 0xb30f7e7f + authenticationPeriod(): 0x31b376e2 + reverifyDaysOptions(uint256): 0xcadef5ac + identities(address): 0xf653b81e + didHashToAddress(bytes32): 0x67c75937 + connectedAccounts(address): 0x61320040 + oldIdentity(): 0x4125f0f2 +events: + BlacklistAdded(address): 0x44d5fe68b00f68950fb9c1ff0a61ef7f747b1a36359a7e3a7f3324db4b878967 + BlacklistRemoved(address): 0x1747ca720b1a174a464b6513ace29b1d3190b5f632b9f34147017c81425bfde8 + WhitelistedAdded(address): 0xee1504a83b6d4a361f4c1dc78ab59bfa30d6a3b6612c403e86bb01ef2984295f + WhitelistedRemoved(address): 0x270d9b30cf5b0793bbfd54c9d5b94aeb49462b8148399000265144a8722da6b6 + WhitelistedAuthenticated(address,uint256): 0xb2a82fce6d8c7a633efe9579f77b4edb96bfdf171a49bfc2ce666dc543a1f500 + ContractAdded(address): 0x89c66952b48f3e96bf1d8ba1b63189520fd988a6979b8b740bd5c5d8dc53e205 + ContractRemoved(address): 0x8d30d41865a0b811b9545d879520d2dde9f4cc49e4241f486ad9752bc904b565 + AccountConnected(address,address): 0x18f7736ef54539debd9afd3c9500b106e12ae7c70e685f5a5efd727b1ce1d54c + AccountDisconnected(address,address): 0x7cdef5f9c5cb8ce728661ede956fef26cb91eb4d7d2180cc041b73f9fef568d2 +errors: {} diff --git a/.agents/skills/gooddollar/references/contracts/InvitesV2.abi.yaml b/.agents/skills/gooddollar/references/contracts/InvitesV2.abi.yaml new file mode 100644 index 0000000..d69e3d6 --- /dev/null +++ b/.agents/skills/gooddollar/references/contracts/InvitesV2.abi.yaml @@ -0,0 +1,333 @@ +# InvitesV2 — invite codes, inviter levels, and G$ bounties (UUPS upgradeable) +# Bounty amounts on Level use G$ cents (2 decimals). Invitee receives half the inviter bounty on payout. + +meta: + name: InvitesV2 + version: "2.4" + source: + - https://raw.githubusercontent.com/GoodDollar/GoodProtocol/master/contracts/invite/InvitesV2.sol + inherits: + - DAOUpgradeableContract + note: > + join binds invite code and optional inviter; bounty eligibility uses minimumDays, minimumClaims, + whitelist on invitee (and inviter when present), and same-chain whitelisting via Identity + getWhitelistedOnChainId. collectBounties and bountyFor pay invitee bountyToPay/2 and inviter + bountyToPay when applicable. Campaign inviter is address(this) when inviter code maps to contract. + deployments: + mainnet: + production: + Invites: + networkId: 122 + address: "0xCa2F09c3ccFD7aD5cB9276918Bd1868f2b922ea0" + creationBlock: 8853311 + production-celo: + Invites: + networkId: 42220 + address: "0x36829D1Cda92FFF5782d5d48991620664FC857d3" + creationBlock: 18003063 + production-xdc: + Invites: + networkId: 50 + address: "0x6bd698566632bf2e81e2278f1656CB24aAF06D2e" + creationBlock: 95144756 + related: + - references/deep-researches/inviter-invitee-reward-model.md + +initialize: + mutability: nonpayable + access: initializer + inputs: + - _ns: address + - _level0Bounty: uint256 + - _owner: address + outputs: [] + +updateAvatar: + mutability: nonpayable + access: anyone + inputs: [] + outputs: [] + +nativeToken: + mutability: view + inputs: [] + outputs: + - token: address + +dao: + mutability: view + inputs: [] + outputs: + - controller: address + +avatar: + mutability: view + inputs: [] + outputs: + - addr: address + +nameService: + mutability: view + inputs: [] + outputs: + - ns: address + +upgradeTo: + mutability: nonpayable + access: ownerOrAvatar + inputs: + - newImplementation: address + outputs: [] + +upgradeToAndCall: + mutability: payable + access: ownerOrAvatar + inputs: + - newImplementation: address + - data: bytes + outputs: [] + +proxiableUUID: + mutability: view + inputs: [] + outputs: + - slot: bytes32 + +setLevelExpirationEnabled: + mutability: nonpayable + access: ownerOrAvatar + inputs: + - _isEnabled: bool + outputs: [] + +getIdentity: + mutability: view + inputs: [] + outputs: + - identity: address + +join: + notes: + - "Registers invite code; may set inviter; may trigger _bountyFor when canCollectBountyFor is already true." + mutability: nonpayable + access: anyone + inputs: + - _myCode: bytes32 + - _inviterCode: bytes32 + outputs: [] + emits: [InviteeJoined] + errors: [NOT_ACTIVE, INVITE_CODE_IN_USE, SELF_INVITE, USER_ALREADY_JOINED] + +canCollectBountyFor: + notes: + - "Primary eligibility gate: checks active state, whitelist, minimumDays, minimumClaims, unpaid bounty, and chain constraints." + mutability: view + inputs: + - _invitee: address + outputs: + - ok: bool + +getInvitees: + mutability: view + inputs: + - _inviter: address + outputs: + - invitees: address[] + +getPendingInvitees: + mutability: view + inputs: + - _inviter: address + outputs: + - pending: address[] + +getPendingBounties: + mutability: view + inputs: + - _inviter: address + outputs: + - count: uint256 + +bountyFor: + notes: + - "Single-invitee payout path; revalidates eligibility and transfers bounty shares to inviter/invitee on success." + mutability: nonpayable + access: anyone + inputs: + - _invitee: address + outputs: + - bounty: uint256 + emits: [InviterBounty] + errors: [NOT_ACTIVE, NOT_ELIGIBLE_BOUNTY] + +collectBounties: + notes: + - "Batch payout path over caller pending invitees; useful for claiming multiple matured bounties in one tx." + mutability: nonpayable + access: anyone + inputs: [] + outputs: [] + emits: [InviterBounty] + errors: [NOT_ACTIVE] + +setLevel: + notes: + - "Configures inviter level progression rule and bounty amount (bounty units are G$ cents)." + mutability: nonpayable + access: ownerOrAvatar + inputs: + - _lvl: uint256 + - _toNext: uint256 + - _bounty: uint256 + - _daysToComplete: uint256 + outputs: [] + +setActive: + mutability: nonpayable + access: ownerOrAvatar + inputs: + - _active: bool + outputs: [] + +setCampaignCode: + notes: + - "Maps a campaign code to contract-address inviter flow (address(this)) used by join." + mutability: nonpayable + access: ownerOrAvatar + inputs: + - _code: bytes32 + outputs: [] + +setMinimums: + notes: + - "Sets minimumClaims and minimumDays thresholds used by canCollectBountyFor." + mutability: nonpayable + access: ownerOrAvatar + inputs: + - _minClaims: uint8 + - _minDays: uint8 + outputs: [] + +end: + mutability: nonpayable + access: ownerOrAvatar + inputs: [] + outputs: [] + errors: [NOT_ACTIVE] + +setOwner: + mutability: nonpayable + access: ownerOrAvatar + inputs: + - _owner: address + outputs: [] + +version: + mutability: pure + inputs: [] + outputs: + - v: string + +codeToUser: + mutability: view + inputs: + - code: bytes32 + outputs: + - user: address + +users: + notes: + - "Public getter omits dynamic invitees/pending arrays; use getInvitees and getPendingInvitees." + mutability: view + inputs: + - user: address + outputs: + - invitedBy: address + - inviteCode: bytes32 + - bountyPaid: bool + - level: uint256 + - levelStarted: uint256 + - totalApprovedInvites: uint256 + - totalEarned: uint256 + - joinedAt: uint256 + - bountyAtJoin: uint256 + +levels: + notes: + - "bounty is in G$ cents (2 decimals). Reserved struct slots are not exposed on the getter." + mutability: view + inputs: + - lvl: uint256 + outputs: + - toNext: uint256 + - bounty: uint256 + - daysToComplete: uint256 + +owner: + mutability: view + inputs: [] + outputs: + - addr: address + +goodDollar: + mutability: view + inputs: [] + outputs: + - token: address + +active: + mutability: view + inputs: [] + outputs: + - ok: bool + +stats: + notes: + - "Reserved Stats struct slots are not exposed on the getter." + mutability: view + inputs: [] + outputs: + - totalApprovedInvites: uint256 + - totalBountiesPaid: uint256 + - totalInvited: uint256 + +levelExpirationEnabled: + mutability: view + inputs: [] + outputs: + - ok: bool + +minimumClaims: + mutability: view + inputs: [] + outputs: + - n: uint8 + +minimumDays: + mutability: view + inputs: [] + outputs: + - n: uint8 + +events: + InviteeJoined: + indexed: + - inviter: address + - invitee: address + data: [] + InviterBounty: + indexed: + - inviter: address + - invitee: address + data: + - bountyPaid: uint256 + - inviterLevel: uint256 + - earnedLevel: bool + +errors: + NOT_ACTIVE: "not active — isActive modifier." + ONLY_OWNER_OR_AVATAR: "Only owner or avatar can perform this action — ownerOrAvatar." + INVITE_CODE_IN_USE: "invite code already in use — join." + SELF_INVITE: "self invite — join." + USER_ALREADY_JOINED: "user already joined — join." + NOT_ELIGIBLE_BOUNTY: "user not elligble for bounty yet — bountyFor." diff --git a/.agents/skills/gooddollar/references/contracts/InvitesV2.selectors.yaml b/.agents/skills/gooddollar/references/contracts/InvitesV2.selectors.yaml new file mode 100644 index 0000000..d717955 --- /dev/null +++ b/.agents/skills/gooddollar/references/contracts/InvitesV2.selectors.yaml @@ -0,0 +1,41 @@ +# Generated by scripts/selectors.mjs +functions: + initialize(address,uint256,address): 0xc350a1b5 + updateAvatar(): 0x1b3c90a8 + nativeToken(): 0xe1758bd8 + dao(): 0x4162169f + avatar(): 0x5aef7de6 + nameService(): 0x3e6326fc + upgradeTo(address): 0x3659cfe6 + upgradeToAndCall(address,bytes): 0x4f1ef286 + proxiableUUID(): 0x52d1902d + setLevelExpirationEnabled(bool): 0x21132aad + getIdentity(): 0x36afc6fa + join(bytes32,bytes32): 0x5b419a65 + canCollectBountyFor(address): 0x6d619ef8 + getInvitees(address): 0xe9881a5e + getPendingInvitees(address): 0xe951a3aa + getPendingBounties(address): 0x41155d5e + bountyFor(address): 0xb6567cd5 + collectBounties(): 0xaf6346b0 + setLevel(uint256,uint256,uint256,uint256): 0xb9fb2d18 + setActive(bool): 0xacec338a + setCampaignCode(bytes32): 0xf14b8649 + setMinimums(uint8,uint8): 0x47826c82 + end(): 0xefbe1c1c + setOwner(address): 0x13af4035 + version(): 0x54fd4d50 + codeToUser(bytes32): 0xba6f5680 + users(address): 0xa87430ba + levels(uint256): 0xb2596a67 + owner(): 0x8da5cb5b + goodDollar(): 0x119e5bf3 + active(): 0x02fb0c5e + stats(): 0xd80528ae + levelExpirationEnabled(): 0xa1df6fd3 + minimumClaims(): 0xc121cb92 + minimumDays(): 0xdf0dca04 +events: + InviteeJoined(address,address): 0xd8c638d8979e2ba5dba1f0d66246ee4b1c54b838f0e0a2b601365345eb23b051 + InviterBounty(address,address,uint256,uint256,bool): 0x6081787cd1bd02ab1576c52f03e8710d792d460e7881c3155d77d23893f3768b +errors: {} diff --git a/.agents/skills/gooddollar/references/contracts/MentoBroker.abi.yaml b/.agents/skills/gooddollar/references/contracts/MentoBroker.abi.yaml new file mode 100644 index 0000000..f6f47f4 --- /dev/null +++ b/.agents/skills/gooddollar/references/contracts/MentoBroker.abi.yaml @@ -0,0 +1,259 @@ +# Mento Broker (IBroker + IBrokerAdmin) — swap router and trading-limit gate for GoodDollar Mento rails +# Interface definitions are vendored in GoodProtocol; implementation lives in mento-core. + +meta: + name: Broker + version: IBroker / IBrokerAdmin + source: + - https://raw.githubusercontent.com/GoodDollar/GoodProtocol/master/contracts/MentoInterfaces.sol + - https://raw.githubusercontent.com/mento-org/mento-core/main/contracts/swap/Broker.sol + - https://raw.githubusercontent.com/mento-org/mento-core/main/contracts/interfaces/IBroker.sol + implements: [IBroker, IBrokerAdmin] + note: > + swapIn is exact-input; swapOut is exact-output. Quotes route through the + configured exchangeProvider + exchangeId. Reverts use require strings in + Broker.sol plus TradingLimits library checks ("amountOutMin not met", + "amountInMax exceeded", trading-limit errors). + deployments: + mainnet: + production-celo: + MentoBroker: + networkId: 42220 + address: "0x88de45906D4F5a57315c133620cfa484cB297541" + creationBlock: 31415857 + production-xdc: + MentoBroker: + networkId: 50 + address: "0x88de45906D4F5a57315c133620cfa484cB297541" + creationBlock: 100091095 + related: + - https://docs.gooddollar.org/for-developers/core-contracts/mentobroker + - references/guides/swap.md + +initialize: + mutability: nonpayable + access: initializer + inputs: + - _exchangeProviders: address[] + - _reserves: address[] + outputs: [] + +setReserves: + notes: + - "Updates reserve address per already-listed provider without changing provider registration." + mutability: nonpayable + access: owner + inputs: + - _exchangeProviders: address[] + - _reserves: address[] + outputs: [] + emits: [ReserveSet] + errors: + - EXCHANGE_PROVIDER_MISSING + - RESERVE_ZERO + +addExchangeProvider: + mutability: nonpayable + access: owner + inputs: + - exchangeProvider: address + - reserve: address + outputs: + - index: uint256 + emits: [ExchangeProviderAdded, ReserveSet] + errors: + - PROVIDER_ALREADY_LISTED + - PROVIDER_ZERO + - RESERVE_ZERO + +removeExchangeProvider: + mutability: nonpayable + access: owner + inputs: + - exchangeProvider: address + - index: uint256 + outputs: [] + emits: [ExchangeProviderRemoved] + errors: + - INDEX_MISMATCH + +getAmountIn: + notes: + - "Exact-output quote path: returns required tokenIn for target amountOut." + - "Pre-checks collateral reserve balance when tokenOut is collateral." + mutability: view + inputs: + - exchangeProvider: address + - exchangeId: bytes32 + - tokenIn: address + - tokenOut: address + - amountOut: uint256 + outputs: + - amountIn: uint256 + errors: + - EXCHANGE_PROVIDER_MISSING + - INSUFFICIENT_RESERVE_BALANCE + +getAmountOut: + notes: + - "Exact-input quote path: returns expected tokenOut for fixed amountIn." + - "Pre-checks collateral reserve balance when tokenOut is collateral." + mutability: view + inputs: + - exchangeProvider: address + - exchangeId: bytes32 + - tokenIn: address + - tokenOut: address + - amountIn: uint256 + outputs: + - amountOut: uint256 + errors: + - EXCHANGE_PROVIDER_MISSING + - INSUFFICIENT_RESERVE_BALANCE + +swapIn: + notes: + - "Transfers tokenIn from msg.sender then delivers tokenOut; enforces amountOut >= amountOutMin after exchange + limits." + mutability: nonpayable + access: nonReentrant + inputs: + - exchangeProvider: address + - exchangeId: bytes32 + - tokenIn: address + - tokenOut: address + - amountIn: uint256 + - amountOutMin: uint256 + outputs: + - amountOut: uint256 + emits: [Swap] + errors: + - EXCHANGE_PROVIDER_MISSING + - INSUFFICIENT_RESERVE_BALANCE + - AMOUNT_OUT_MIN_NOT_MET + - TRADING_LIMIT_OR_SAFE_TRANSFER + +swapOut: + notes: + - "Computes required tokenIn then pulls up to amountInMax; reverts if amountIn would exceed cap." + mutability: nonpayable + access: nonReentrant + inputs: + - exchangeProvider: address + - exchangeId: bytes32 + - tokenIn: address + - tokenOut: address + - amountOut: uint256 + - amountInMax: uint256 + outputs: + - amountIn: uint256 + emits: [Swap] + errors: + - EXCHANGE_PROVIDER_MISSING + - INSUFFICIENT_RESERVE_BALANCE + - AMOUNT_IN_MAX_EXCEEDED + - TRADING_LIMIT_OR_SAFE_TRANSFER + +burnStableTokens: + notes: + - "Owner-maintained escape hatch burning stables from msg.sender via reserve plumbing." + mutability: nonpayable + access: owner + inputs: + - token: address + - amount: uint256 + outputs: + - ok: bool + errors: + - COLLATERAL_TRANSFER_FAILED + +configureTradingLimit: + notes: + - "Sets per (exchangeId, token) limit config used by swapIn/swapOut guardTradingLimits checks." + mutability: nonpayable + access: owner + inputs: + - exchangeId: bytes32 + - token: address + - config: TradingLimits.Config + outputs: [] + emits: [TradingLimitConfigured] + +getExchangeProviders: + notes: + - "Discovery helper for clients that need the active provider set before quoting/swapping." + mutability: view + inputs: [] + outputs: + - providers: address[] + +exchangeProviders: + mutability: view + inputs: + - index: uint256 + outputs: + - exchangeProvider: address + +isExchangeProvider: + mutability: view + inputs: + - exchangeProvider: address + outputs: + - ok: bool + +tradingLimitsState: + mutability: view + inputs: + - eid: bytes32 + outputs: + - state: TradingLimits.State + +tradingLimitsConfig: + mutability: view + inputs: + - eid: bytes32 + outputs: + - config: TradingLimits.Config + +events: + Swap: + indexed: + - exchangeId: bytes32 + - trader: address + - tokenIn: address + data: + - exchangeProvider: address + - tokenOut: address + - amountIn: uint256 + - amountOut: uint256 + TradingLimitConfigured: + indexed: [] + data: + - exchangeId: bytes32 + - token: address + - config: TradingLimits.Config + ExchangeProviderAdded: + indexed: + - exchangeProvider: address + data: [] + ExchangeProviderRemoved: + indexed: + - exchangeProvider: address + data: [] + ReserveSet: + indexed: + - newAddress: address + - prevAddress: address + data: [] + +errors: + EXCHANGE_PROVIDER_MISSING: "ExchangeProvider does not exist" + EXCHANGE_PROVIDER_EXISTS: "ExchangeProvider already exists in the list" + PROVIDER_ZERO: "ExchangeProvider address can't be 0" + RESERVE_ZERO: "Reserve address can't be 0" + INDEX_MISMATCH: "index doesn't match provider" + INSUFFICIENT_RESERVE_BALANCE: "Insufficient balance in reserve" + AMOUNT_OUT_MIN_NOT_MET: "amountOutMin not met" + AMOUNT_IN_MAX_EXCEEDED: "amountInMax exceeded" + COLLATERAL_TRANSFER_FAILED: "Transfer of the collateral asset failed" + AMOUNT_TOO_LARGE: "amountIn too large / amountOut too large — uint256 to int256 safety checks" + TRADING_LIMIT_OR_SAFE_TRANSFER: "TradingLimits library reverts or ERC20 safety failures during swap" diff --git a/.agents/skills/gooddollar/references/contracts/MentoBroker.selectors.yaml b/.agents/skills/gooddollar/references/contracts/MentoBroker.selectors.yaml new file mode 100644 index 0000000..249edce --- /dev/null +++ b/.agents/skills/gooddollar/references/contracts/MentoBroker.selectors.yaml @@ -0,0 +1,24 @@ +# Generated by scripts/selectors.mjs +functions: + initialize(address[],address[]): 0x73cf25f8 + setReserves(address[],address[]): 0xddeb9dd2 + addExchangeProvider(address,address): 0x770d0a34 + removeExchangeProvider(address,uint256): 0x04710d53 + getAmountIn(address,bytes32,address,address,uint256): 0x04e45640 + getAmountOut(address,bytes32,address,address,uint256): 0xa20f2305 + swapIn(address,bytes32,address,address,uint256,uint256): 0xddbbe850 + swapOut(address,bytes32,address,address,uint256,uint256): 0xd163b135 + burnStableTokens(address,uint256): 0x131cab2a + configureTradingLimit(bytes32,address,(uint32,uint32,int48,int48,int48,int48,int48,uint8)): 0xa868d140 + getExchangeProviders(): 0x2cac2568 + exchangeProviders(uint256): 0xc4454fdc + isExchangeProvider(address): 0xd1d786b1 + tradingLimitsState(bytes32): 0xf01ecd17 + tradingLimitsConfig(bytes32): 0x821a816c +events: + Swap(bytes32,address,address,address,address,uint256,uint256): 0x46e6aeaebfb8f1b6a9be6403b5fc420d9827172046f365e786acb9d5b56c9409 + TradingLimitConfigured(bytes32,address,(uint32,uint32,int48,int48,int48,int48,int48,uint8)): 0x3ed50aa123e1e547aa90fcf88624ef8278d253e252bb1feac75eda93e1905bb6 + ExchangeProviderAdded(address): 0x2ee2cb0721ec60b86190cae5c48e25064b69b35abad32452a4ec99d232033de2 + ExchangeProviderRemoved(address): 0x29e92ab2e30f4f74283034c28c451b6faac986b554f1808101eb6418bdba19d4 + ReserveSet(address,address): 0xb69e1c416d8be92ac92c8e97e77c4626fba5e6ab50161099f659ea3303479e50 +errors: {} diff --git a/.agents/skills/gooddollar/references/contracts/MessagePassingBridge.abi.yaml b/.agents/skills/gooddollar/references/contracts/MessagePassingBridge.abi.yaml new file mode 100644 index 0000000..d4bb1f2 --- /dev/null +++ b/.agents/skills/gooddollar/references/contracts/MessagePassingBridge.abi.yaml @@ -0,0 +1,542 @@ +meta: + name: MessagePassingBridge + version: Axelar + LayerZero message passing + source: + - https://raw.githubusercontent.com/GoodDollar/GoodBridge/master/packages/bridge-contracts/contracts/messagePassingBridge/MessagePassingBridge.sol + - https://raw.githubusercontent.com/GoodDollar/GoodBridge/master/packages/bridge-contracts/contracts/messagePassingBridge/IMessagePassingBridge.sol + note: > + Bridge implementation that burns source tokens and mints destination tokens, + transporting requests through Axelar or LayerZero. + Cross-chain transport uses msg.value on the source (LayerZero estimateSendFee path, Axelar gas prepay); destination mint applies bridgeFees bps to the delivered G$ amount. See references/guides/bridge.md "Bridge fee context". + deployments: + mainnet: + production: + MpbBridge: + networkId: 122 + address: "0xa3247276DbCC76Dd7705273f766eB3E8a5ecF4a5" + creationBlock: 25464921 + production-celo: + MpbBridge: + networkId: 42220 + address: "0xa3247276DbCC76Dd7705273f766eB3E8a5ecF4a5" + creationBlock: 21473545 + production-xdc: + MpbBridge: + networkId: 50 + address: "0xa3247276DbCC76Dd7705273f766eB3E8a5ecF4a5" + creationBlock: 95254417 + related: + - references/guides/bridge.md + +initialize: + notes: + - "Initial bootstrap for DAO wiring and bridge policy state." + - "Sets guardian to msg.sender and uses NameService UBISCHEME as feeRecipient fallback to avatar when missing." + - "Preloads default LZ mappings for Ethereum, Celo, Fuse, and XDC using this contract as trusted remote." + mutability: nonpayable + access: initializer + inputs: + - nameService: address + - limits: (uint256,uint256,uint256,uint256,bool) + - fees: (uint256,uint256,uint256) + outputs: [] + +upgrade: + notes: + - "Reinitializer for migration path; re-applies default LZ mappings through internal add function." + - "Used when upgrading existing proxy deployments to mapping-aware version." + mutability: nonpayable + access: reinitializer + inputs: [] + outputs: [] + +addLzChainSupport: + notes: + - "Administrative chain wiring method for LayerZero transport." + - "Writes both forward (chainId->lzChainId) and reverse (lzChainId->chainId) mappings." + - "Also updates trustedRemoteLookup to enforce source-contract authenticity on receive." + mutability: nonpayable + access: ownerOrAvatarOrGuardian + inputs: + - lzChainId: uint16 + - chainId: uint256 + - remote: address + outputs: [] + +approveRequest: + notes: + - "Manual override for stuck/exceptional inbound requests." + - "When approved, destination _bridgeFrom skips limits enforcement for that request id." + mutability: nonpayable + access: ownerOrAvatarOrGuardian + inputs: + - id: uint256 + outputs: [] + +preventRequest: + notes: + - "Emergency/manual block for a specific request id." + - "Prevents execution by pre-marking executedRequests[id]=true." + mutability: nonpayable + access: ownerOrAvatarOrGuardian + inputs: + - id: uint256 + outputs: [] + +setFeeRecipient: + notes: + - "Sets destination fee mint recipient." + - "If feeRecipient is zero, fee minting is skipped in _bridgeFrom." + mutability: nonpayable + access: ownerOrAvatarOrGuardian + inputs: + - recipient: address + outputs: [] + +setBridgeLimits: + notes: + - "Updates operational throttles: min amount, tx cap, account/day cap, global/day cap, whitelist mode." + - "These limits are checked by canBridge and enforced in _enforceLimits." + mutability: nonpayable + access: ownerOrAvatarOrGuardian + inputs: + - limits: (uint256,uint256,uint256,uint256,bool) + outputs: [] + +setBridgeFees: + notes: + - "Updates bridge fee parameters in basis points with min/max clamps." + - "Reverts when fee exceeds 10000 bps." + - "Effective fee deduction is computed in _takeFee during destination execution." + mutability: nonpayable + access: ownerOrAvatarOrGuardian + inputs: + - fees: (uint256,uint256,uint256) + outputs: [] + +setDisabledBridges: + notes: + - "Toggles allowlist state for source bridge combinations." + - "Key format is keccak256(abi.encode(sourceChainId, BridgeService))." + - "Checked in _bridgeFrom before request execution." + mutability: nonpayable + access: ownerOrAvatarOrGuardian + inputs: + - bridgeKeys: bytes32[] + - disabled: bool[] + outputs: [] + +setFaucet: + notes: + - "Configures optional faucet top-up callback used after successful destination processing." + mutability: nonpayable + access: ownerOrAvatarOrGuardian + inputs: + - _faucet: address + outputs: [] + +setGuardian: + notes: + - "Rotates guardian authority used by owner/avatar/guardian admin gate." + mutability: nonpayable + access: ownerOrAvatarOrGuardian + inputs: + - _guardian: address + outputs: [] + +withdraw: + notes: + - "Avatar-only rescue function for arbitrary token balances held by bridge." + - "Amount 0 means full balance withdrawal." + mutability: nonpayable + access: avatar + inputs: + - token: address + - amount: uint256 + outputs: [] + +pauseBridge: + notes: + - "Sets isClosed state for outbound flow." + - "When closed, _bridgeTo reverts with BRIDGE_LIMITS('closed')." + mutability: nonpayable + access: ownerOrAvatarOrGuardian + inputs: + - isPaused: bool + outputs: [] + +canBridge: + notes: + - "Purely diagnostic read path for preflight checks." + - "Returns (ok, reason) using BridgeHelperLibrary policy evaluation." + - "Includes close flag, whitelist gate, and per-account/global daily limit windows." + mutability: view + inputs: + - from: address + - amount: uint256 + outputs: + - isWithinLimit: bool + - error: string + +bridgeTo: + notes: + - "Generic outbound bridge entrypoint selecting BridgeService.AXELAR or BridgeService.LZ." + - "Burns source-side token amount, normalizes to 18 decimals, and emits BridgeRequest with request id." + - "Requires msg.value for transport fee payment." + mutability: payable + access: anyone + inputs: + - target: address + - targetChainId: uint256 + - amount: uint256 + - bridge: uint8 + outputs: [] + +bridgeToWithLz: + notes: + - "Outbound convenience wrapper fixed to LayerZero transport." + - "If adapterParams is empty, contract injects default type-1 options with 400k gas." + - "Compares required native fee from estimateSendFee against msg.value and reverts on underpayment." + mutability: payable + access: anyone + inputs: + - target: address + - targetChainId: uint256 + - amount: uint256 + - adapterParams: bytes + outputs: [] + +bridgeToWithAxelar: + notes: + - "Outbound convenience wrapper fixed to Axelar transport." + - "Uses gasRefundAddress when provided, otherwise msg.sender as refund recipient." + mutability: payable + access: anyone + inputs: + - target: address + - targetChainId: uint256 + - amount: uint256 + - gasRefundAddress: address + outputs: [] + +toLzChainId: + notes: + - "Lookup helper from local chain id to LayerZero chain id." + mutability: view + inputs: + - chainId: uint256 + outputs: + - lzChainId: uint16 + +fromLzChainId: + notes: + - "Lookup helper from LayerZero chain id to local chain id." + mutability: view + inputs: + - lzChainId: uint16 + outputs: + - chainId: uint256 + +toAxelarChainId: + notes: + - "Pure mapping in current implementation: chainId 1 -> 'Ethereum', 5 -> 'ethereum-2', 42220 and 44787 -> 'celo'; any other id returns empty string and outbound Axelar reverts UNSUPPORTED_CHAIN." + mutability: pure + inputs: + - chainId: uint256 + outputs: + - axlChainId: string + +fromAxelarChainId: + notes: + - "Maps Axelar chain-name strings back into local numeric chain ids." + mutability: pure + inputs: + - axlChainId: string + outputs: + - chainId: uint256 + +estimateSendFee: + notes: + - "Transport fee preflight for LZ path." + - "Builds payload with request id set to 0 for estimation." + - "Returns (0,0) on endpoint estimation failure in handler implementation." + - "_normalizedAmount must match BridgeHelperLibrary.normalizeFromTokenTo18Decimals burned raw amount using native token decimals on the outbound chain." + mutability: view + inputs: + - _dstChainId: uint16 + - _fromAddress: address + - _toAddress: address + - _normalizedAmount: uint256 + - _useZro: bool + - _adapterParams: bytes + outputs: + - nativeFee: uint256 + - zroFee: uint256 + +lzReceive: + notes: + - "LayerZero receive entrypoint." + - "Validates caller is configured endpoint before dispatching nonblocking receive pipeline." + mutability: nonpayable + inputs: + - _srcChainId: uint16 + - _srcAddress: bytes + - _nonce: uint64 + - _payload: bytes + outputs: [] + +lzEndpoint_: + notes: + - "Immutable LayerZero endpoint configured in constructor." + mutability: view + inputs: [] + outputs: + - endpoint: address + +HOME_CHAIN_ID: + notes: + - "Immutable deployment home chain marker." + mutability: view + inputs: [] + outputs: + - chainId: uint32 + +guardian: + notes: + - "Current guardian account authorized for admin operations." + mutability: view + inputs: [] + outputs: + - account: address + +executedRequests: + notes: + - "Replay protection state for inbound request ids." + mutability: view + inputs: + - id: uint256 + outputs: + - done: bool + +disabledSourceBridges: + notes: + - "Per-source bridge toggle state keyed by (sourceChainId, bridgeService) hash." + mutability: view + inputs: + - key: bytes32 + outputs: + - disabled: bool + +isClosed: + notes: + - "Outbound bridge pause state." + mutability: view + inputs: [] + outputs: + - closed: bool + +bridgeFees: + notes: + - "Current fee policy parameters: minFee, maxFee, feeBps." + mutability: view + inputs: [] + outputs: + - minFee: uint256 + - maxFee: uint256 + - fee: uint256 + +bridgeLimits: + notes: + - "Current bridge traffic limits and whitelist policy." + mutability: view + inputs: [] + outputs: + - dailyLimit: uint256 + - txLimit: uint256 + - accountDailyLimit: uint256 + - minAmount: uint256 + - onlyWhitelisted: bool + +bridgeDailyLimit: + notes: + - "Aggregate 24h bridge usage tracker." + mutability: view + inputs: [] + outputs: + - lastTransferReset: uint256 + - bridged24Hours: uint256 + +accountsDailyLimit: + notes: + - "Per-account 24h usage tracker." + mutability: view + inputs: + - account: address + outputs: + - lastTransferReset: uint256 + - bridged24Hours: uint256 + +faucet: + notes: + - "Optional gas top-up contract used on destination completion." + mutability: view + inputs: [] + outputs: + - addr: address + +currentId: + notes: + - "Monotonic nonce component used to derive outbound request ids." + mutability: view + inputs: [] + outputs: + - id: uint256 + +lzChainIdsMapping: + notes: + - "Local chain id -> LayerZero chain id mapping." + mutability: view + inputs: + - chainId: uint256 + outputs: + - lzChainId: uint16 + +feeRecipient: + notes: + - "Address receiving bridge fee mints on destination." + mutability: view + inputs: [] + outputs: + - recipient: address + +approvedRequests: + notes: + - "Manual approvals allowing request execution above standard limits." + mutability: view + inputs: + - id: uint256 + outputs: + - approved: bool + +lzChainToIdsMapping: + notes: + - "LayerZero chain id -> local chain id mapping." + mutability: view + inputs: + - lzChainId: uint16 + outputs: + - chainId: uint256 + +trustedRemoteLookup: + notes: + - "Trusted remote path used to authenticate inbound LZ/Axelar source contract." + mutability: view + inputs: + - lzChainId: uint16 + outputs: + - path: bytes + +gateway: + notes: + - "Axelar gateway address inherited from AxelarExecutable." + mutability: view + inputs: [] + outputs: + - addr: address + +gasService: + notes: + - "Axelar gas service used to prepay cross-chain execution." + mutability: view + inputs: [] + outputs: + - addr: address + +nameService: + notes: + - "DAO NameService pointer from DAOUpgradeableContract." + mutability: view + inputs: [] + outputs: + - addr: address + +avatar: + notes: + - "DAO avatar authority address." + mutability: view + inputs: [] + outputs: + - addr: address + +owner: + notes: + - "Ownable owner from upgradeable ownership flow." + mutability: view + inputs: [] + outputs: + - account: address + +events: + BridgeRequest: + indexed: + - from: address + - to: address + - id: uint256 + data: + - targetChainId: uint256 + - normalizedAmount: uint256 + - timestamp: uint256 + - bridge: uint8 + note: "Outbound intent event; relayers consume this to deliver payload on destination." + ExecutedTransfer: + indexed: + - from: address + - to: address + - id: uint256 + data: + - normalizedAmount: uint256 + - fee: uint256 + - sourceChainId: uint256 + - bridge: uint8 + note: "Destination completion event after replay checks, source-auth checks, limit checks, and mint/fee mint." + FalseSender: + indexed: [] + data: + - sourceChainId: uint256 + - sourceAddress: address + note: "Inbound message ignored because source contract does not match trusted remote path." + +errors: + AlreadyInitialized: "LZ chain support already initialized for this lz chain id." + NOT_GUARDIAN: + inputs: + - sender: address + WRONG_TOKEN: + inputs: + - token: address + INVALID_TARGET_OR_CHAINID: + inputs: + - target: address + - chainId: uint256 + BRIDGE_LIMITS: + inputs: + - reason: string + TRANSFER_FROM: "Source burn/transferFrom style failure." + TRANSFER: "Destination transfer style failure." + ALREADY_EXECUTED: + inputs: + - requestId: uint256 + MISSING_FEE: "Bridge call requires msg.value for transport fee." + UNSUPPORTED_CHAIN: + inputs: + - chainId: uint256 + LZ_FEE: + inputs: + - required: uint256 + - sent: uint256 + INVALID_SENDER: + inputs: + - _srcAddress: bytes + INVALID_ENDPOINT: + inputs: + - lzEndpoint: address diff --git a/.agents/skills/gooddollar/references/contracts/MessagePassingBridge.selectors.yaml b/.agents/skills/gooddollar/references/contracts/MessagePassingBridge.selectors.yaml new file mode 100644 index 0000000..104b943 --- /dev/null +++ b/.agents/skills/gooddollar/references/contracts/MessagePassingBridge.selectors.yaml @@ -0,0 +1,52 @@ +# Generated by scripts/selectors.mjs +functions: + initialize(address,(uint256,uint256,uint256,uint256,bool),(uint256,uint256,uint256)): 0xfad16abe + upgrade(): 0xd55ec697 + addLzChainSupport(uint16,uint256,address): 0xc01c8123 + approveRequest(uint256): 0xd7d1bbdb + preventRequest(uint256): 0xc612f9ea + setFeeRecipient(address): 0xe74b981b + setBridgeLimits((uint256,uint256,uint256,uint256,bool)): 0x29b70872 + setBridgeFees((uint256,uint256,uint256)): 0x82dc737d + setDisabledBridges(bytes32[],bool[]): 0xc78ab882 + setFaucet(address): 0xd8b31c77 + setGuardian(address): 0x8a0dac4a + withdraw(address,uint256): 0xf3fef3a3 + pauseBridge(bool): 0x1a394795 + canBridge(address,uint256): 0x3095634a + bridgeTo(address,uint256,uint256,uint8): 0x1fec5c5c + bridgeToWithLz(address,uint256,uint256,bytes): 0xc56bbdd9 + bridgeToWithAxelar(address,uint256,uint256,address): 0x40a00aaf + toLzChainId(uint256): 0x5b23a990 + fromLzChainId(uint16): 0x16ad5512 + toAxelarChainId(uint256): 0x9a9ee081 + fromAxelarChainId(string): 0x56026f37 + estimateSendFee(uint16,address,address,uint256,bool,bytes): 0x05fead15 + lzReceive(uint16,bytes,uint64,bytes): 0x001d3567 + lzEndpoint_(): 0x020051cf + HOME_CHAIN_ID(): 0x8f65be85 + guardian(): 0x452a9320 + executedRequests(uint256): 0x425cfb53 + disabledSourceBridges(bytes32): 0x69c20d36 + isClosed(): 0xc2b6b58c + bridgeFees(): 0x7b0240c0 + bridgeLimits(): 0xc6dd812f + bridgeDailyLimit(): 0xb2f7667f + accountsDailyLimit(address): 0xd4227947 + faucet(): 0xde5f72fd + currentId(): 0xe00dd161 + lzChainIdsMapping(uint256): 0xb5569f18 + feeRecipient(): 0x46904840 + approvedRequests(uint256): 0x0dce292e + lzChainToIdsMapping(uint16): 0x73800fc4 + trustedRemoteLookup(uint16): 0x7533d788 + gateway(): 0x116191b6 + gasService(): 0x6a22d8cc + nameService(): 0x3e6326fc + avatar(): 0x5aef7de6 + owner(): 0x8da5cb5b +events: + BridgeRequest(address,address,uint256,uint256,uint256,uint256,uint8): 0x34b675c8c84b6a9e7979a0d3a54f2b036a19d6444167091a925af2d81e8e66fe + ExecutedTransfer(address,address,uint256,uint256,uint256,uint256,uint8): 0x81e772e0c4366ddbae472926005267ef278dbb257be45dfe97c676ceae348dbe + FalseSender(uint256,address): 0x1eafb58197ea0dc76b9278ccad47f61a239f00b017d89a19081a89321cce213d +errors: {} diff --git a/.agents/skills/gooddollar/references/contracts/NameService.abi.yaml b/.agents/skills/gooddollar/references/contracts/NameService.abi.yaml new file mode 100644 index 0000000..01692b7 --- /dev/null +++ b/.agents/skills/gooddollar/references/contracts/NameService.abi.yaml @@ -0,0 +1,104 @@ +# NameService — string-key to address registry for GoodProtocol deployments +# Resolves keys such as IDENTITY, UBISCHEME, GOODDOLLAR, GDAO_STAKING. + +meta: + name: NameService + version: UUPS-upgradeable v1 + source: + - https://raw.githubusercontent.com/GoodDollar/GoodProtocol/master/contracts/utils/NameService.sol + implements: [] + inherits: [Initializable, UUPSUpgradeable] + note: > + Almost every integration starts here. Writes are restricted to the DAO + avatar. Reads are permissionless. Use getAddress(string) with the same + key strings your deployment documented in releases/deployment.json. + deployments: + mainnet: + production: + NameService: + networkId: 122 + address: "0xec6dcE387B1616a0c44fF2E4fA9E90e53Cf14eb0" + creationBlock: 15740314 + production-celo: + NameService: + networkId: 42220 + address: "0x0F5dB7a64A6a64052693676CA898EC7F7A94FF4e" + creationBlock: 17237962 + production-xdc: + NameService: + networkId: 50 + address: "0x1e5154Bf5e31FF56051bbd45958b879Fb7a290FE" + creationBlock: 95143608 + related: + - https://docs.gooddollar.org/for-developers/core-contracts/nameservice + - https://github.com/GoodDollar/GoodProtocol/blob/master/releases/deployment.json + +addresses: + # Solidity auto-getter for public mapping addresses(bytes32 => address). + notes: + - "Prefer getAddress(string) off-chain; this expects keccak256(abi.encodePacked(name)) for manual lookups." + mutability: view + inputs: + - nameHash: bytes32 + outputs: + - addr: address + +dao: + mutability: view + inputs: [] + outputs: + - controller: address + +initialize: + notes: + - "Initializer wires Controller and optional pre-hashed name batch." + - "Automatically registers CONTROLLER and AVATAR hashes to dao and dao.avatar()." + mutability: nonpayable + access: initializer + inputs: + - _dao: address + - _nameHashes: bytes32[] + - _addresses: address[] + outputs: [] + +setAddress: + notes: + - "Stores addresses[keccak256(bytes(name))] = addr and emits AddressChanged." + mutability: nonpayable + access: avatar + inputs: + - name: string + - addr: address + outputs: [] + emits: [AddressChanged] + errors: [ONLY_AVATAR] + +setAddresses: + notes: + - "Batch write by raw bytes32 keys; no per-name event emission in this loop." + mutability: nonpayable + access: avatar + inputs: + - hash: bytes32[] + - addrs: address[] + outputs: [] + errors: [ONLY_AVATAR] + +getAddress: + notes: + - "Primary lookup used by claim, staking, identity, and swap integrations." + mutability: view + inputs: + - name: string + outputs: + - addr: address + +events: + AddressChanged: + indexed: [] + data: + - name: string + - addr: address + +errors: + ONLY_AVATAR: "only avatar can call this method — revert string on any avatar-gated path including UUPS _authorizeUpgrade." diff --git a/.agents/skills/gooddollar/references/contracts/NameService.selectors.yaml b/.agents/skills/gooddollar/references/contracts/NameService.selectors.yaml new file mode 100644 index 0000000..48e1bcf --- /dev/null +++ b/.agents/skills/gooddollar/references/contracts/NameService.selectors.yaml @@ -0,0 +1,11 @@ +# Generated by scripts/selectors.mjs +functions: + addresses(bytes32): 0x699f200f + dao(): 0x4162169f + initialize(address,bytes32[],address[]): 0xd41b4e72 + setAddress(string,address): 0x9b2ea4bd + setAddresses(bytes32[],address[]): 0x4ab01f5b + getAddress(string): 0xbf40fac1 +events: + AddressChanged(string,address): 0x135cf55549d8538a41f19f46cc85625da93e68b63484cca8fcb9aaf19e520137 +errors: {} diff --git a/.agents/skills/gooddollar/references/contracts/SuperToken.abi.yaml b/.agents/skills/gooddollar/references/contracts/SuperToken.abi.yaml new file mode 100644 index 0000000..abfc91c --- /dev/null +++ b/.agents/skills/gooddollar/references/contracts/SuperToken.abi.yaml @@ -0,0 +1,1033 @@ +# SuperToken — the Superfluid Protocol's token standard +# Merges three variants into a single ABI surface: +# • Wrapper Super Token — wraps an existing ERC-20 (upgrade / downgrade) +# • Native Asset Super Token (SETH) — wraps chain-native asset (upgradeByETH / downgradeToETH) +# • Pure Super Token — pre-minted, no underlying token (upgrade/downgrade revert) +# +# Inherits ERC-20, ERC-777, ERC-2612 (permit), EIP-5267, and the Superfluid real-time +# balance and agreement hosting layer from SuperfluidToken. +# +# Proxy / upgradability functions are omitted: +# castrate, getCodeAddress, proxiableUUID, initialize, initializeWithAdmin, updateCode +# Proxy-related events are also omitted: CodeUpdated, Initialized. + +meta: + name: SuperToken + version: v1 + source: + - https://raw.githubusercontent.com/superfluid-org/protocol-monorepo/refs/heads/dev/packages/ethereum-contracts/contracts/superfluid/SuperToken.sol + - https://raw.githubusercontent.com/superfluid-org/protocol-monorepo/refs/heads/dev/packages/ethereum-contracts/contracts/interfaces/superfluid/ISuperToken.sol + - https://raw.githubusercontent.com/superfluid-org/protocol-monorepo/refs/heads/dev/packages/ethereum-contracts/contracts/superfluid/SuperfluidToken.sol + - https://raw.githubusercontent.com/superfluid-org/protocol-monorepo/refs/heads/dev/packages/ethereum-contracts/contracts/interfaces/superfluid/IYieldBackend.sol + inherits: [SuperfluidToken, ISuperToken, UUPSProxiable] + yield_backends: + - name: AaveYieldBackend + note: "Production backend for ERC-20 wrapper tokens using Aave V3" + source: https://raw.githubusercontent.com/superfluid-org/protocol-monorepo/refs/heads/dev/packages/ethereum-contracts/contracts/superfluid/AaveYieldBackend.sol + - name: AaveETHYieldBackend + note: "Variant for native-asset (ETH/WETH) wrapper tokens using Aave V3" + source: https://raw.githubusercontent.com/superfluid-org/protocol-monorepo/refs/heads/dev/packages/ethereum-contracts/contracts/superfluid/AaveETHYieldBackend.sol + - name: ERC4626YieldBackend + note: "Generic backend for any ERC-4626 vault" + source: https://raw.githubusercontent.com/superfluid-org/protocol-monorepo/refs/heads/dev/packages/ethereum-contracts/contracts/superfluid/ERC4626YieldBackend.sol + - name: SparkYieldBackend + note: "Extends ERC4626YieldBackend for Spark Protocol vaults with referral tracking" + source: https://raw.githubusercontent.com/superfluid-org/protocol-monorepo/refs/heads/dev/packages/ethereum-contracts/contracts/superfluid/SparkYieldBackend.sol + variants: + wrapper: "Standard ERC-20 wrapper — upgrade() / downgrade()" + native-asset: "Native asset wrapper (SETH) — upgradeByETH() / downgradeToETH()" + pure: "Pre-minted supply, no underlying — upgrade/downgrade revert" + note: > + Super Tokens are deployed as individual proxies (one per token) by the + SuperTokenFactory. There is no single canonical deployment address. + All proxies share the same logic contract which is upgraded via governance. + +# wrapper super token — a Super Token backed by an ERC-20 underlying token +# native asset super token (SETH) — a Super Token backed by the chain-native asset (ETH, MATIC, etc.) +# pure super token — a Super Token with no underlying; supply is pre-minted at deploy time +# underlying token — the ERC-20 token that a wrapper super token wraps +# real-time balance — balance that changes continuously based on active agreements (CFA/GDA) +# available balance — real-time balance minus locked deposits +# critical — an account whose available balance is negative +# solvent — an account whose real-time balance (before deposit deductions) is non-negative +# operator (ERC-777) — an address authorized to send/burn tokens on behalf of a holder +# buffer / deposit — collateral locked while an outgoing flow is active + +# == ERC-20 Token Info == + +name: + mutability: view + inputs: [] + outputs: + - string + +symbol: + mutability: view + inputs: [] + outputs: + - string + +decimals: + # Always returns 18 regardless of underlying token decimals. + notes: + - "Always returns 18, regardless of the underlying token's decimals (e.g. USDC has 6). The upgrade/downgrade functions handle decimal conversion internally." + mutability: pure + inputs: [] + outputs: + - uint8 + +totalSupply: + mutability: view + inputs: [] + outputs: + - uint256 + +# == ERC-20 Balance & Allowance == + +balanceOf: + # Returns max(0, availableBalance) — clamps negative balances to zero. + # For the full real-time picture, use realtimeBalanceOfNow. + notes: + - "Returns max(0, availableBalance) — negative/critical balances are clamped to zero. Use realtimeBalanceOfNow to detect critical accounts." + mutability: view + inputs: + - account: address + outputs: + - balance: uint256 + +allowance: + mutability: view + inputs: + - account: address + - spender: address + outputs: + - uint256 + +approve: + mutability: nonpayable + access: anyone + inputs: + - spender: address + - amount: uint256 + outputs: + - bool + emits: [Approval] + errors: [SUPER_TOKEN_APPROVE_FROM_ZERO_ADDRESS, SUPER_TOKEN_APPROVE_TO_ZERO_ADDRESS] + +increaseAllowance: + mutability: nonpayable + access: anyone + inputs: + - spender: address + - addedValue: uint256 + outputs: + - bool + emits: [Approval] + errors: [SUPER_TOKEN_APPROVE_FROM_ZERO_ADDRESS, SUPER_TOKEN_APPROVE_TO_ZERO_ADDRESS] + +decreaseAllowance: + mutability: nonpayable + access: anyone + inputs: + - spender: address + - subtractedValue: uint256 + outputs: + - bool + emits: [Approval] + errors: [SUPER_TOKEN_APPROVE_FROM_ZERO_ADDRESS, SUPER_TOKEN_APPROVE_TO_ZERO_ADDRESS] + +# == ERC-20 Transfers == + +transfer: + # ERC-20 transfer. Does NOT invoke ERC-777 send/receive hooks (by design). + mutability: nonpayable + access: anyone + inputs: + - recipient: address + - amount: uint256 + outputs: + - bool + emits: [Sent, Transfer] + errors: [SUPER_TOKEN_TRANSFER_FROM_ZERO_ADDRESS, SUPER_TOKEN_TRANSFER_TO_ZERO_ADDRESS, SF_TOKEN_MOVE_INSUFFICIENT_BALANCE] + +transferFrom: + # ERC-20 transferFrom. Does NOT invoke ERC-777 send/receive hooks. + # Does NOT emit an Approval event on allowance spend (OZ v5 behaviour). + mutability: nonpayable + access: anyone + inputs: + - holder: address + - recipient: address + - amount: uint256 + outputs: + - bool + emits: [Sent, Transfer] + errors: [SUPER_TOKEN_TRANSFER_FROM_ZERO_ADDRESS, SUPER_TOKEN_TRANSFER_TO_ZERO_ADDRESS, SF_TOKEN_MOVE_INSUFFICIENT_BALANCE] + +transferAll: + # Transfer the caller's entire balanceOf to recipient. + mutability: nonpayable + access: anyone # transfers msg.sender's entire balance + inputs: + - recipient: address + emits: [Sent, Transfer] + errors: [SUPER_TOKEN_TRANSFER_FROM_ZERO_ADDRESS, SUPER_TOKEN_TRANSFER_TO_ZERO_ADDRESS, SF_TOKEN_MOVE_INSUFFICIENT_BALANCE] + +# == ERC-777 == + +granularity: + # Always returns 1. + mutability: pure + inputs: [] + outputs: + - uint256 + +send: + # ERC-777 send — invokes tokensToSend / tokensReceived hooks. + mutability: nonpayable + access: anyone + inputs: + - recipient: address + - amount: uint256 + - userData: bytes + emits: [Sent, Transfer] + errors: [SUPER_TOKEN_TRANSFER_FROM_ZERO_ADDRESS, SUPER_TOKEN_TRANSFER_TO_ZERO_ADDRESS, SF_TOKEN_MOVE_INSUFFICIENT_BALANCE, SUPER_TOKEN_NOT_ERC777_TOKENS_RECIPIENT] + +burn: + # ERC-777 burn — in SuperToken this actually performs a downgrade (unwrap). + notes: + - "Gotcha: Reverts with SUPER_TOKEN_NO_UNDERLYING_TOKEN on Pure Super Tokens." + mutability: nonpayable + access: anyone + inputs: + - amount: uint256 + - userData: bytes + emits: [Burned, Transfer, TokenDowngraded] + errors: [SUPER_TOKEN_NO_UNDERLYING_TOKEN, SUPER_TOKEN_BURN_FROM_ZERO_ADDRESS, SF_TOKEN_BURN_INSUFFICIENT_BALANCE, SUPER_TOKEN_INFLATIONARY_DEFLATIONARY_NOT_SUPPORTED] + +authorizeOperator: + mutability: nonpayable + access: anyone + inputs: + - operator: address + emits: [AuthorizedOperator] + +revokeOperator: + mutability: nonpayable + access: anyone + inputs: + - operator: address + emits: [RevokedOperator] + +isOperatorFor: + mutability: view + inputs: + - operator: address + - tokenHolder: address + outputs: + - bool + +defaultOperators: + mutability: view + inputs: [] + outputs: + - "address[]" + +operatorSend: + # ERC-777 operatorSend — invokes tokensToSend / tokensReceived hooks. + mutability: nonpayable + access: operator + inputs: + - sender: address + - recipient: address + - amount: uint256 + - userData: bytes + - operatorData: bytes + emits: [Sent, Transfer] + errors: [SUPER_TOKEN_CALLER_IS_NOT_OPERATOR_FOR_HOLDER, SUPER_TOKEN_TRANSFER_FROM_ZERO_ADDRESS, SUPER_TOKEN_TRANSFER_TO_ZERO_ADDRESS, SF_TOKEN_MOVE_INSUFFICIENT_BALANCE, SUPER_TOKEN_NOT_ERC777_TOKENS_RECIPIENT] + +operatorBurn: + # ERC-777 operatorBurn — like burn(), actually performs a downgrade. + mutability: nonpayable + access: operator + inputs: + - account: address + - amount: uint256 + - userData: bytes + - operatorData: bytes + emits: [Burned, Transfer, TokenDowngraded] + errors: [SUPER_TOKEN_CALLER_IS_NOT_OPERATOR_FOR_HOLDER, SUPER_TOKEN_NO_UNDERLYING_TOKEN, SUPER_TOKEN_BURN_FROM_ZERO_ADDRESS, SF_TOKEN_BURN_INSUFFICIENT_BALANCE, SUPER_TOKEN_INFLATIONARY_DEFLATIONARY_NOT_SUPPORTED] + +# == ERC-20 Permit == + +permit: + mutability: nonpayable + access: anyone + inputs: + - owner: address + - spender: address + - value: uint256 + - deadline: uint256 + - v: uint8 + - r: bytes32 + - s: bytes32 + emits: [Approval] + errors: [SUPER_TOKEN_PERMIT_EXPIRED_SIGNATURE, SUPER_TOKEN_PERMIT_INVALID_SIGNER, ECDSAInvalidSignature, ECDSAInvalidSignatureLength, ECDSAInvalidSignatureS, SUPER_TOKEN_APPROVE_FROM_ZERO_ADDRESS, SUPER_TOKEN_APPROVE_TO_ZERO_ADDRESS] + +nonces: + mutability: view + inputs: + - owner: address + outputs: + - uint256 + +DOMAIN_SEPARATOR: + mutability: view + inputs: [] + outputs: + - bytes32 + +eip712Domain: + # EIP-5267 domain retrieval. + mutability: view + inputs: [] + outputs: + - fields: bytes1 + - name: string + - version: string + - chainId: uint256 + - verifyingContract: address + - salt: bytes32 + - "extensions: uint256[]" + +# == ERC-20 Wrapping == +# These functions interact with the underlying ERC-20 token. +# They revert with SUPER_TOKEN_NO_UNDERLYING_TOKEN on Pure and Native Asset +# Super Tokens (use upgradeByETH / downgradeToETH for SETH). + +upgrade: + # Wrap underlying ERC-20 into Super Tokens for msg.sender. + # Requires prior ERC-20 approval on the underlying token. + notes: + - "Gotcha: amount is always in SuperToken decimals (18), regardless of the underlying token's decimals. The contract handles downscaling internally when pulling from the underlying via transferFrom. However, the ERC-20 approval on the underlying token must use the underlying's native decimals. Example: to wrap 1000 USDC, approve 1000e6 on USDC, then call upgrade(1000e18)." + mutability: nonpayable + access: anyone # wraps for msg.sender + inputs: + - amount: uint256 # in SuperToken decimals (always 18) + emits: [Minted, Transfer, TokenUpgraded] + errors: [SUPER_TOKEN_NO_UNDERLYING_TOKEN, SUPER_TOKEN_INFLATIONARY_DEFLATIONARY_NOT_SUPPORTED, SUPER_TOKEN_MINT_TO_ZERO_ADDRESS, SafeERC20FailedOperation, SafeCastOverflowedUintToInt] + +upgradeTo: + # Wrap underlying ERC-20 and mint Super Tokens to a different address. + mutability: nonpayable + access: anyone + inputs: + - to: address + - amount: uint256 + - userData: bytes + emits: [Minted, Transfer, TokenUpgraded] + errors: [SUPER_TOKEN_NO_UNDERLYING_TOKEN, SUPER_TOKEN_INFLATIONARY_DEFLATIONARY_NOT_SUPPORTED, SUPER_TOKEN_MINT_TO_ZERO_ADDRESS, SUPER_TOKEN_NOT_ERC777_TOKENS_RECIPIENT, SafeERC20FailedOperation, SafeCastOverflowedUintToInt] + +downgrade: + # Unwrap Super Tokens back to underlying ERC-20 for msg.sender. + mutability: nonpayable + access: anyone # unwraps to msg.sender + inputs: + - amount: uint256 + emits: [Burned, Transfer, TokenDowngraded] + errors: [SUPER_TOKEN_NO_UNDERLYING_TOKEN, SUPER_TOKEN_BURN_FROM_ZERO_ADDRESS, SF_TOKEN_BURN_INSUFFICIENT_BALANCE, SUPER_TOKEN_INFLATIONARY_DEFLATIONARY_NOT_SUPPORTED, SafeERC20FailedOperation] + +downgradeTo: + # Unwrap Super Tokens and send underlying ERC-20 to a different address. + mutability: nonpayable + access: anyone + inputs: + - to: address + - amount: uint256 + emits: [Burned, Transfer, TokenDowngraded] + errors: [SUPER_TOKEN_NO_UNDERLYING_TOKEN, SUPER_TOKEN_BURN_FROM_ZERO_ADDRESS, SF_TOKEN_BURN_INSUFFICIENT_BALANCE, SUPER_TOKEN_INFLATIONARY_DEFLATIONARY_NOT_SUPPORTED, SafeERC20FailedOperation] + +getUnderlyingToken: + # Returns address(0) for Pure and Native Asset Super Tokens. + mutability: view + inputs: [] + outputs: + - address + +getUnderlyingDecimals: + mutability: view + inputs: [] + outputs: + - uint8 + +toUnderlyingAmount: + # Convert a Super Token amount to its underlying equivalent, accounting for + # decimal differences. adjustedAmount strips precision loss. + mutability: view + inputs: + - amount: uint256 + outputs: + - underlyingAmount: uint256 + - adjustedAmount: uint256 + +# == Native Asset Wrapping (SETH only) == +# These functions exist only on Native Asset Super Token (SETH) proxies. +# They are defined in the SETHProxy contract, not in the SuperToken logic. +# The SETH proxy also accepts plain ETH transfers via receive() which mints +# Super Tokens to the sender. + +upgradeByETH: + # Wrap sent ETH/native asset into Super Tokens for msg.sender. + # Variant: native-asset + mutability: payable + access: anyone # wraps for msg.sender + inputs: [] + emits: [Minted, Transfer, TokenUpgraded] + +upgradeByETHTo: + # Wrap sent ETH/native asset into Super Tokens for a different address. + # Variant: native-asset + mutability: payable + access: anyone + inputs: + - to: address + emits: [Minted, Transfer, TokenUpgraded] + +downgradeToETH: + # Unwrap Super Tokens back to ETH/native asset for msg.sender. + # Variant: native-asset + mutability: nonpayable + access: anyone # unwraps to msg.sender + inputs: + - wad: uint256 + emits: [Burned, Transfer, TokenDowngraded] + +# == Real-time Balance == + +realtimeBalanceOf: + # Full real-time balance across ALL agreements at a given timestamp. + # This aggregates the realtimeBalanceOf from every agreement (CFA, GDA, IDA) + # into a single balance. Use this (or realtimeBalanceOfNow) to check an + # account's actual balance — not the per-agreement versions. + # availableBalance = settled + agreement dynamics − max(0, deposit − owedDeposit) + mutability: view + inputs: + - account: address + - timestamp: uint256 + outputs: + - availableBalance: int256 + - deposit: uint256 + - owedDeposit: uint256 + +realtimeBalanceOfNow: + # Convenience wrapper: realtimeBalanceOf at the current Host timestamp. + # This is the recommended way to check an account's real-time balance. + mutability: view + inputs: + - account: address + outputs: + - availableBalance: int256 + - deposit: uint256 + - owedDeposit: uint256 + - timestamp: uint256 + +isAccountCritical: + # True if availableBalance < 0 at the given timestamp. + mutability: view + inputs: + - account: address + - timestamp: uint256 + outputs: + - isCritical: bool + +isAccountCriticalNow: + mutability: view + inputs: + - account: address + outputs: + - isCritical: bool + +isAccountSolvent: + # True if realtime balance (before deposit deduction) >= 0 at the given timestamp. + mutability: view + inputs: + - account: address + - timestamp: uint256 + outputs: + - isSolvent: bool + +isAccountSolventNow: + mutability: view + inputs: + - account: address + outputs: + - isSolvent: bool + +# == Admin == +# The admin defaults to the Host contract when address(0). +# An explicit admin can be set during initializeWithAdmin or via changeAdmin. + +changeAdmin: + mutability: nonpayable + access: admin + inputs: + - newAdmin: address + emits: [AdminChanged] + errors: [SUPER_TOKEN_ONLY_ADMIN] + +getAdmin: + # Returns address(0) if the Host is the implicit admin. + mutability: view + inputs: [] + outputs: + - address + +# == Yield Backend == +# Hot-pluggable yield generation for wrapper Super Tokens. The yield backend is a +# contract implementing IYieldBackend that is invoked via delegatecall. When enabled, +# the underlying ERC-20 is deposited into a yield protocol (e.g. Aave, Spark, ERC4626 vaults). +# Surplus yield (balance exceeding totalSupply) can be withdrawn by the admin. + +enableYieldBackend: + # Enable a yield backend and deposit all underlying token balance into it. + # Requires no existing yield backend to be set. + notes: + - "Gotcha: Reverts if a yield backend is already enabled — must call disableYieldBackend first to switch backends." + - "The yield backend contract is invoked via delegatecall — it executes in the SuperToken's context." + mutability: nonpayable + access: admin + inputs: + - newYieldBackend: address # must implement IYieldBackend + emits: [YieldBackendEnabled] + +disableYieldBackend: + # Withdraw all assets from the yield backend and disable it. + notes: + - "Calls withdrawMax() then disable() on the backend via delegatecall." + mutability: nonpayable + access: admin + inputs: [] + emits: [YieldBackendDisabled] + +getYieldBackend: + # Returns the current yield backend address, or address(0) if none is set. + mutability: view + inputs: [] + outputs: + - yieldBackend: address + +withdrawSurplusFromYieldBackend: + # Withdraw yield surplus (deposited amount exceeding totalSupply) from the backend. + # The surplus is sent to a receiver defined by the yield backend implementation. + mutability: nonpayable + access: admin + inputs: [] + +# == Self Operations == +# Can only be called by the token contract itself (address(this)). +# Used by custom super token proxies (SETH, Pure) to mint/burn/approve/transfer +# tokens through their own proxy logic. + +selfMint: + mutability: nonpayable + access: self + inputs: + - account: address + - amount: uint256 + - userData: bytes + emits: [Minted, Transfer] + errors: [SUPER_TOKEN_ONLY_SELF, SUPER_TOKEN_MINT_TO_ZERO_ADDRESS] + +selfBurn: + mutability: nonpayable + access: self + inputs: + - account: address + - amount: uint256 + - userData: bytes + emits: [Burned, Transfer] + errors: [SUPER_TOKEN_ONLY_SELF, SUPER_TOKEN_BURN_FROM_ZERO_ADDRESS, SF_TOKEN_BURN_INSUFFICIENT_BALANCE] + +selfApproveFor: + mutability: nonpayable + access: self + inputs: + - account: address + - spender: address + - amount: uint256 + emits: [Approval] + errors: [SUPER_TOKEN_ONLY_SELF, SUPER_TOKEN_APPROVE_FROM_ZERO_ADDRESS, SUPER_TOKEN_APPROVE_TO_ZERO_ADDRESS] + +selfTransferFrom: + mutability: nonpayable + access: self + inputs: + - holder: address + - spender: address + - recipient: address + - amount: uint256 + emits: [Sent, Transfer] + errors: [SUPER_TOKEN_ONLY_SELF, SUPER_TOKEN_TRANSFER_FROM_ZERO_ADDRESS, SUPER_TOKEN_TRANSFER_TO_ZERO_ADDRESS, SF_TOKEN_MOVE_INSUFFICIENT_BALANCE] + +# == Host Batch Operations == +# Called by the Host contract on behalf of a user within batchCall / +# forwardBatchCall. Each mirrors a user-facing function but takes the +# account address explicitly. + +operationApprove: + mutability: nonpayable + access: host + inputs: + - account: address + - spender: address + - amount: uint256 + emits: [Approval] + errors: [SF_TOKEN_ONLY_HOST, SUPER_TOKEN_APPROVE_FROM_ZERO_ADDRESS, SUPER_TOKEN_APPROVE_TO_ZERO_ADDRESS] + +operationIncreaseAllowance: + mutability: nonpayable + access: host + inputs: + - account: address + - spender: address + - addedValue: uint256 + emits: [Approval] + errors: [SF_TOKEN_ONLY_HOST, SUPER_TOKEN_APPROVE_FROM_ZERO_ADDRESS, SUPER_TOKEN_APPROVE_TO_ZERO_ADDRESS] + +operationDecreaseAllowance: + mutability: nonpayable + access: host + inputs: + - account: address + - spender: address + - subtractedValue: uint256 + emits: [Approval] + errors: [SF_TOKEN_ONLY_HOST, SUPER_TOKEN_APPROVE_FROM_ZERO_ADDRESS, SUPER_TOKEN_APPROVE_TO_ZERO_ADDRESS] + +operationTransferFrom: + mutability: nonpayable + access: host + inputs: + - account: address + - spender: address + - recipient: address + - amount: uint256 + emits: [Sent, Transfer] + errors: [SF_TOKEN_ONLY_HOST, SUPER_TOKEN_TRANSFER_FROM_ZERO_ADDRESS, SUPER_TOKEN_TRANSFER_TO_ZERO_ADDRESS, SF_TOKEN_MOVE_INSUFFICIENT_BALANCE] + +operationSend: + mutability: nonpayable + access: host + inputs: + - spender: address + - recipient: address + - amount: uint256 + - userData: bytes + emits: [Sent, Transfer] + errors: [SF_TOKEN_ONLY_HOST, SUPER_TOKEN_TRANSFER_FROM_ZERO_ADDRESS, SUPER_TOKEN_TRANSFER_TO_ZERO_ADDRESS, SF_TOKEN_MOVE_INSUFFICIENT_BALANCE, SUPER_TOKEN_NOT_ERC777_TOKENS_RECIPIENT] + +operationUpgrade: + mutability: nonpayable + access: host + inputs: + - account: address + - amount: uint256 + emits: [Minted, Transfer, TokenUpgraded] + errors: [SF_TOKEN_ONLY_HOST, SUPER_TOKEN_NO_UNDERLYING_TOKEN, SUPER_TOKEN_INFLATIONARY_DEFLATIONARY_NOT_SUPPORTED, SUPER_TOKEN_MINT_TO_ZERO_ADDRESS, SafeERC20FailedOperation, SafeCastOverflowedUintToInt] + +operationDowngrade: + mutability: nonpayable + access: host + inputs: + - account: address + - amount: uint256 + emits: [Burned, Transfer, TokenDowngraded] + errors: [SF_TOKEN_ONLY_HOST, SUPER_TOKEN_NO_UNDERLYING_TOKEN, SUPER_TOKEN_BURN_FROM_ZERO_ADDRESS, SF_TOKEN_BURN_INSUFFICIENT_BALANCE, SUPER_TOKEN_INFLATIONARY_DEFLATIONARY_NOT_SUPPORTED, SafeERC20FailedOperation] + +operationUpgradeTo: + mutability: nonpayable + access: host + inputs: + - account: address + - to: address + - amount: uint256 + emits: [Minted, Transfer, TokenUpgraded] + errors: [SF_TOKEN_ONLY_HOST, SUPER_TOKEN_NO_UNDERLYING_TOKEN, SUPER_TOKEN_INFLATIONARY_DEFLATIONARY_NOT_SUPPORTED, SUPER_TOKEN_MINT_TO_ZERO_ADDRESS, SafeERC20FailedOperation, SafeCastOverflowedUintToInt] + +operationDowngradeTo: + mutability: nonpayable + access: host + inputs: + - account: address + - to: address + - amount: uint256 + emits: [Burned, Transfer, TokenDowngraded] + errors: [SF_TOKEN_ONLY_HOST, SUPER_TOKEN_NO_UNDERLYING_TOKEN, SUPER_TOKEN_BURN_FROM_ZERO_ADDRESS, SF_TOKEN_BURN_INSUFFICIENT_BALANCE, SUPER_TOKEN_INFLATIONARY_DEFLATIONARY_NOT_SUPPORTED, SafeERC20FailedOperation] + +# == Agreement Hosting == +# The token acts as storage host for agreement data. These functions are +# called by registered agreement contracts (CFA, GDA, IDA) through the Host. + +createAgreement: + mutability: nonpayable + access: agreement + inputs: + - id: bytes32 + - "data: bytes32[]" + emits: [AgreementCreated] + errors: [SF_TOKEN_AGREEMENT_ALREADY_EXISTS] + +getAgreementData: + mutability: view + inputs: + - agreementClass: address + - id: bytes32 + - dataLength: uint256 + outputs: + - "data: bytes32[]" + +updateAgreementData: + mutability: nonpayable + access: agreement + inputs: + - id: bytes32 + - "data: bytes32[]" + emits: [AgreementUpdated] + +terminateAgreement: + mutability: nonpayable + access: agreement + inputs: + - id: bytes32 + - dataLength: uint256 + emits: [AgreementTerminated] + errors: [SF_TOKEN_AGREEMENT_DOES_NOT_EXIST] + +updateAgreementStateSlot: + mutability: nonpayable + access: agreement + inputs: + - account: address + - slotId: uint256 + - "slotData: bytes32[]" + emits: [AgreementStateUpdated] + +getAgreementStateSlot: + mutability: view + inputs: + - agreementClass: address + - account: address + - slotId: uint256 + - dataLength: uint256 + outputs: + - "slotData: bytes32[]" + +settleBalance: + # Adjust an account's settled balance. Only listed agreements can call this. + mutability: nonpayable + access: agreement + inputs: + - account: address + - delta: int256 + errors: [SF_TOKEN_ONLY_LISTED_AGREEMENT] + +makeLiquidationPayoutsV2: + # Execute liquidation payouts. Transfers reward to liquidator or reward account, + # and adjusts the target account's balance. Only listed agreements can call this. + mutability: nonpayable + access: agreement + inputs: + - id: bytes32 + - liquidationTypeData: bytes + - liquidatorAccount: address + - useDefaultRewardAccount: bool + - targetAccount: address + - rewardAmount: uint256 + - targetAccountBalanceDelta: int256 + emits: [Transfer, AgreementLiquidatedV2] + errors: [SF_TOKEN_ONLY_LISTED_AGREEMENT] + +getAccountActiveAgreements: + mutability: view + inputs: + - account: address + outputs: + - "ISuperAgreement[]" + +# == Protocol Info == + +getHost: + mutability: view + inputs: [] + outputs: + - host: address + +POOL_ADMIN_NFT: + # Immutable address of the canonical PoolAdminNFT proxy. + mutability: view + inputs: [] + outputs: + - address + +POOL_MEMBER_NFT: + # Immutable address of the (deprecated) PoolMemberNFT proxy. + mutability: view + inputs: [] + outputs: + - address + +VERSION: + # Returns the version string of the SuperToken logic contract (e.g. "1.0.0"). + mutability: view + inputs: [] + outputs: + - string + +# == Events == + +events: + + # -- ERC-20 -- + + Transfer: + indexed: + - from: address + - to: address + data: + - value: uint256 + + Approval: + indexed: + - owner: address + - spender: address + data: + - value: uint256 + + # -- ERC-777 -- + + Sent: + indexed: + - operator: address + - from: address + - to: address + data: + - amount: uint256 + - data: bytes + - operatorData: bytes + + Minted: + indexed: + - operator: address + - to: address + data: + - amount: uint256 + - data: bytes + - operatorData: bytes + + Burned: + indexed: + - operator: address + - from: address + data: + - amount: uint256 + - data: bytes + - operatorData: bytes + + AuthorizedOperator: + indexed: + - operator: address + - tokenHolder: address + + RevokedOperator: + indexed: + - operator: address + - tokenHolder: address + + # -- EIP-5267 -- + + EIP712DomainChanged: + # Signalled when the EIP-712 domain changes. Not explicitly emitted by + # SuperToken, but declared in the EIP-5267 interface for indexing support. + + # -- Wrapping -- + + TokenUpgraded: + indexed: + - account: address + data: + - amount: uint256 + + TokenDowngraded: + indexed: + - account: address + data: + - amount: uint256 + + # -- Admin -- + + AdminChanged: + indexed: [] + data: + - oldAdmin: address + - newAdmin: address + + # -- Yield Backend -- + + YieldBackendEnabled: + indexed: + - yieldBackend: address + data: + - depositAmount: uint256 + + YieldBackendDisabled: + indexed: + - yieldBackend: address + + PoolAdminNFTCreated: + # Emitted once during logic contract constructor deployment. + indexed: [] + data: + - poolAdminNFT: address + + # -- Agreement Hosting -- + + AgreementCreated: + indexed: + - agreementClass: address + - id: bytes32 + data: + - "data: bytes32[]" + + AgreementUpdated: + indexed: + - agreementClass: address + - id: bytes32 + data: + - "data: bytes32[]" + + AgreementTerminated: + indexed: + - agreementClass: address + - id: bytes32 + + AgreementStateUpdated: + indexed: + - agreementClass: address + - account: address + data: + - slotId: uint256 + + AgreementLiquidatedV2: + indexed: + - agreementClass: address + - id: bytes32 + data: + - liquidatorAccount: address + - targetAccount: address + - rewardAmountReceiver: address + - rewardAmount: uint256 + - targetAccountBalanceDelta: int256 + - liquidationTypeData: bytes + + # -- Deprecated events (from ISuperfluidToken, no longer emitted) -- + + AgreementLiquidated: + deprecated: true + note: "Use AgreementLiquidatedV2" + indexed: + - agreementClass: address + - id: bytes32 + data: + - penaltyAccount: address + - rewardAccount: address + - rewardAmount: uint256 + + AgreementLiquidatedBy: + deprecated: true + note: "Use AgreementLiquidatedV2" + indexed: + - liquidatorAccount: address + - agreementClass: address + - id: bytes32 + data: + - penaltyAccount: address + - bondAccount: address + - rewardAmount: uint256 + - bailoutAmount: uint256 + + Bailout: + deprecated: true + note: "Use AgreementLiquidatedV2" + indexed: + - bailoutAccount: address + - bailoutAmount: uint256 + +# == Errors == + +errors: + + # -- Super Token access -- + - SUPER_TOKEN_ONLY_SELF + - SUPER_TOKEN_ONLY_ADMIN + - SUPER_TOKEN_ONLY_GOV_OWNER + + # -- SuperfluidToken access -- + - SF_TOKEN_ONLY_HOST + - SF_TOKEN_ONLY_LISTED_AGREEMENT + + # -- Wrapping -- + - SUPER_TOKEN_NO_UNDERLYING_TOKEN + - SUPER_TOKEN_INFLATIONARY_DEFLATIONARY_NOT_SUPPORTED + + # -- ERC-20 / ERC-777 transfer -- + - SUPER_TOKEN_TRANSFER_FROM_ZERO_ADDRESS + - SUPER_TOKEN_TRANSFER_TO_ZERO_ADDRESS + - SF_TOKEN_MOVE_INSUFFICIENT_BALANCE + + # -- Approve -- + - SUPER_TOKEN_APPROVE_FROM_ZERO_ADDRESS + - SUPER_TOKEN_APPROVE_TO_ZERO_ADDRESS + + # -- Mint / Burn -- + - SUPER_TOKEN_MINT_TO_ZERO_ADDRESS + - SUPER_TOKEN_BURN_FROM_ZERO_ADDRESS + - SF_TOKEN_BURN_INSUFFICIENT_BALANCE + + # -- ERC-777 operator -- + - SUPER_TOKEN_CALLER_IS_NOT_OPERATOR_FOR_HOLDER + - SUPER_TOKEN_NOT_ERC777_TOKENS_RECIPIENT + + # -- ERC-2612 permit -- + - SUPER_TOKEN_PERMIT_EXPIRED_SIGNATURE: + inputs: + - deadline: uint256 + - SUPER_TOKEN_PERMIT_INVALID_SIGNER: + inputs: + - signer: address + - owner: address + + # -- NFT proxy -- + - SUPER_TOKEN_NFT_PROXY_ADDRESS_CHANGED + + # -- Agreement hosting -- + - SF_TOKEN_AGREEMENT_ALREADY_EXISTS + - SF_TOKEN_AGREEMENT_DOES_NOT_EXIST + + # -- OpenZeppelin ECDSA (from permit) -- + - ECDSAInvalidSignature + - ECDSAInvalidSignatureLength: + inputs: + - length: uint256 + - ECDSAInvalidSignatureS: + inputs: + - s: bytes32 + + # -- OpenZeppelin SafeCast -- + - SafeCastOverflowedUintToInt: + inputs: + - value: uint256 + + # -- OpenZeppelin SafeERC20 -- + - SafeERC20FailedOperation: + inputs: + - token: address diff --git a/.agents/skills/gooddollar/references/contracts/SuperToken.selectors.yaml b/.agents/skills/gooddollar/references/contracts/SuperToken.selectors.yaml new file mode 100644 index 0000000..f9bb474 --- /dev/null +++ b/.agents/skills/gooddollar/references/contracts/SuperToken.selectors.yaml @@ -0,0 +1,99 @@ +# Generated by scripts/selectors.mjs +functions: + name(): 0x06fdde03 + symbol(): 0x95d89b41 + decimals(): 0x313ce567 + totalSupply(): 0x18160ddd + balanceOf(address): 0x70a08231 + allowance(address,address): 0xdd62ed3e + approve(address,uint256): 0x095ea7b3 + increaseAllowance(address,uint256): 0x39509351 + decreaseAllowance(address,uint256): 0xa457c2d7 + transfer(address,uint256): 0xa9059cbb + transferFrom(address,address,uint256): 0x23b872dd + transferAll(address): 0xa3a7e7f3 + granularity(): 0x556f0dc7 + send(address,uint256,bytes): 0x9bd9bbc6 + burn(uint256,bytes): 0xfe9d9303 + authorizeOperator(address): 0x959b8c3f + revokeOperator(address): 0xfad8b32a + isOperatorFor(address,address): 0xd95b6371 + defaultOperators(): 0x06e48538 + operatorSend(address,address,uint256,bytes,bytes): 0x62ad1b83 + operatorBurn(address,uint256,bytes,bytes): 0xfc673c4f + permit(address,address,uint256,uint256,uint8,bytes32,bytes32): 0xd505accf + nonces(address): 0x7ecebe00 + DOMAIN_SEPARATOR(): 0x3644e515 + eip712Domain(): 0x84b0196e + upgrade(): 0xd55ec697 + upgradeTo(address,uint256,bytes): 0x5b9d09cc + downgrade(uint256): 0x11bcc81e + downgradeTo(address,uint256): 0x83ba2525 + getUnderlyingToken(): 0xee719bc8 + getUnderlyingDecimals(): 0x92081a47 + toUnderlyingAmount(uint256): 0x282a050b + upgradeByETH(): 0xcf81464b + upgradeByETHTo(address): 0x7687d19b + downgradeToETH(uint256): 0x160e8be3 + realtimeBalanceOf(address,uint256): 0xeb3537cc + realtimeBalanceOfNow(address): 0x2ec8eec7 + isAccountCritical(address,uint256): 0xd9d078d6 + isAccountCriticalNow(address): 0x79359f6f + isAccountSolvent(address,uint256): 0xb84cdd4a + isAccountSolventNow(address): 0xbb0d196e + changeAdmin(address): 0x8f283970 + getAdmin(): 0x6e9960c3 + enableYieldBackend(): 0x5127b621 + disableYieldBackend(): 0x370a190f + getYieldBackend(): 0xe729804b + withdrawSurplusFromYieldBackend(): 0x4a3acda0 + selfMint(address,uint256,bytes): 0xc68d4283 + selfBurn(address,uint256,bytes): 0x9d876741 + selfApproveFor(address,address,uint256): 0x66a12fb6 + selfTransferFrom(address,address,address,uint256): 0x41b706be + operationApprove(address,address,uint256): 0x62aa5287 + operationIncreaseAllowance(address,address,uint256): 0x4b2763b3 + operationDecreaseAllowance(address,address,uint256): 0xc780fd82 + operationTransferFrom(address,address,address,uint256): 0x16d055d6 + operationSend(address,address,uint256,bytes): 0xca0c1e7f + operationUpgrade(address,uint256): 0xca789464 + operationDowngrade(address,uint256): 0x245887fc + operationUpgradeTo(address,address,uint256): 0x1ae88ffc + operationDowngradeTo(address,address,uint256): 0x47ba7ad1 + createAgreement(bytes32,bytes32[]"): 0x816e2dc5 + getAgreementData(address,bytes32,uint256): 0x6c2d9f2f + updateAgreementData(bytes32,bytes32[]"): 0x1bced9c7 + terminateAgreement(bytes32,uint256): 0x27048397 + updateAgreementStateSlot(address,uint256,bytes32[]"): 0x003af740 + getAgreementStateSlot(address,address,uint256,uint256): 0x4b61cc33 + settleBalance(address,int256): 0xcf97256d + makeLiquidationPayoutsV2(bytes32,bytes,address,bool,address,uint256,int256): 0x1863e809 + getAccountActiveAgreements(address): 0x386fa221 + getHost(): 0x20bc4425 + POOL_ADMIN_NFT(): 0xb20db1ac + POOL_MEMBER_NFT(): 0xf5a8b4dd + VERSION(): 0xffa1ad74 +events: + Transfer(address,address,uint256): 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef + Approval(address,address,uint256): 0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925 + Sent(address,address,address,uint256,bytes,bytes): 0x06b541ddaa720db2b10a4d0cdac39b8d360425fc073085fac19bc82614677987 + Minted(address,address,uint256,bytes,bytes): 0x2fe5be0146f74c5bce36c0b80911af6c7d86ff27e89d5cfa61fc681327954e5d + Burned(address,address,uint256,bytes,bytes): 0xa78a9be3a7b862d26933ad85fb11d80ef66b8f972d7cbba06621d583943a4098 + AuthorizedOperator(address,address): 0xf4caeb2d6ca8932a215a353d0703c326ec2d81fc68170f320eb2ab49e9df61f9 + RevokedOperator(address,address): 0x50546e66e5f44d728365dc3908c63bc5cfeeab470722c1677e3073a6ac294aa1 + EIP712DomainChanged(): 0x0a6387c9ea3628b88a633bb4f3b151770f70085117a15f9bf3787cda53f13d31 + TokenUpgraded(address,uint256): 0x25ca84076773b0455db53621c459ddc84fe40840e4932a62706a032566f399df + TokenDowngraded(address,uint256): 0x3bc27981aebbb57f9247dc00fde9d6cd91e4b230083fec3238fedbcba1f9ab3d + AdminChanged(address,address): 0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f + YieldBackendEnabled(address,uint256): 0x8d15dd569157df615aedb4b16273001ae8980ce2aac93e39adc48481dfaefbb5 + YieldBackendDisabled(address): 0x2486b5241145ce1b97a13655ecd4e8e51094ac93259a0589d24524304d6d70d4 + PoolAdminNFTCreated(address): 0xeb87fb34067547f3dc0b85096c3da73c99d4fbb08ff41212b8d7c0b5008b42e6 + AgreementCreated(address,bytes32,bytes32[]"): 0x9a5caaf4460c6dff81ed3dc58f3aef40fe511737a163340e06a4abc1bfe21a73 + AgreementUpdated(address,bytes32,bytes32[]"): 0xc00aaaf56818c1a9d6c54e14c6f93965eb34c9729232fdafa62f90a10600e70a + AgreementTerminated(address,bytes32): 0x71a63dc095de07aa5512ad57a7596a39516317e316981a1cd71000057be1537b + AgreementStateUpdated(address,address,uint256): 0x30f416fa68fca014a0f334464c64b000ba53e99b6d2afdea9d5ca756372d5985 + AgreementLiquidatedV2(address,bytes32,address,address,address,uint256,int256,bytes): 0xb8381a3ce157650e06186e3e8f4dd4dc29236f2688b6eed1893d0a60d7c6386f + AgreementLiquidated(address,bytes32,address,address,uint256): 0x8505c3d8f1f184f032cf0bc4cd80ee61c8b9d94f8907c3281bf0101a2610fe80 + AgreementLiquidatedBy(address,address,bytes32,address,address,uint256,uint256): 0x5f22b60e58b1d6de858bc27c48d5a4653e052da99e083c1d88bb8c58e1abc8ef + Bailout(address,uint256): 0xd6c9a04afc81e8c614310bbee6c9e84f5abe15b82038bf8347014ce0852e6ffd +errors: {} diff --git a/.agents/skills/gooddollar/references/contracts/Superfluid.abi.yaml b/.agents/skills/gooddollar/references/contracts/Superfluid.abi.yaml new file mode 100644 index 0000000..33ac5a9 --- /dev/null +++ b/.agents/skills/gooddollar/references/contracts/Superfluid.abi.yaml @@ -0,0 +1,757 @@ +# Superfluid Host — the central protocol router +# All agreement calls (CFA, IDA, GDA) are routed through the Host, which manages +# the Superfluid call context, Super App callbacks, app credit, and governance. +# The Host is also the entry point for batch calls and meta-transactions. +# +# NOTE: emits/errors mappings are traced from source code — verify against implementation. +# Proxy/upgradability functions (castrate, updateCode, getCodeAddress, proxiableUUID, initialize) +# are omitted — they belong to the UUPSProxiable layer. + +meta: + name: Superfluid + version: v1 + source: + - https://raw.githubusercontent.com/superfluid-org/protocol-monorepo/refs/heads/dev/packages/ethereum-contracts/contracts/superfluid/Superfluid.sol + - https://raw.githubusercontent.com/superfluid-org/protocol-monorepo/refs/heads/dev/packages/ethereum-contracts/contracts/interfaces/superfluid/ISuperfluid.sol + implements: [ISuperfluid] + inherits: [UUPSProxiable, BaseRelayRecipient] + deployments: + mainnet: + eth-mainnet: "0x4E583d9390082B65Bef884b629DFA426114CED6d" + polygon-mainnet: "0x3E14dC1b13c488a8d5D310918780c983bD5982E7" + xdai-mainnet: "0x2dFe937cD98Ab92e59cF3139138f18c823a4efE7" + base-mainnet: "0x4C073B3baB6d8826b8C5b229f3cfdC1eC6E47E74" + optimism-mainnet: "0x567c4B141ED61923967cA25Ef4906C8781069a10" + arbitrum-one: "0xCf8Acb4eF033efF16E8080aed4c7D5B9285D2192" + bsc-mainnet: "0xd1e2cFb6441680002Eb7A44223160aB9B67d7E6E" + avalanche-c: "0x60377C7016E4cdB03C87EF474896C11cB560752C" + celo-mainnet: "0xA4Ff07cF81C02CFD356184879D953970cA957585" + scroll-mainnet: "0x0F86a21F6216c061B222c224e315d9FC34520bb7" + degenchain: "0xc1314EdcD7e478C831a7a24169F7dEADB2646eD2" + testnet: + avalanche-fuji: "0x85Fe79b998509B77BF10A8BD4001D58475D29386" + base-sepolia: "0x109412E3C84f0539b43d39dB691B08c90f58dC7c" + eth-sepolia: "0x109412E3C84f0539b43d39dB691B08c90f58dC7c" + optimism-sepolia: "0xd399e2Fb5f4cf3722a11F65b88FAB6B2B8621005" + scroll-sepolia: "0x42b05a6016B9eED232E13fd56a8F0725693DBF8e" + deploymentCreationBlocks: + mainnet: + celo-mainnet: 16393469 + +# == Abbreviations == +# ctx — context (Superfluid call context bytes) +# ACL — Access Control List +# ERC — Ethereum Request for Comments + +# == Glossary == +# Host — central Superfluid contract routing agreement/app calls +# agreement class — a registered agreement contract (CFA, IDA, GDA) +# Super App — a smart contract registered with the Host that receives callbacks +# callback — beforeAgreement* / afterAgreement* hooks called on Super Apps +# context (ctx) — encoded call metadata: msgSender, timestamp, userData, app credit +# app credit — temporary token allowance granted to a Super App during a callback +# jailed — a Super App that violated protocol rules; its callbacks are bypassed +# configWord — bitmask encoding a Super App's app level and callback noop flags. +# App level: APP_LEVEL_FINAL (1 << 1) or APP_LEVEL_SECOND (1 << 0). +# Noop flags disable specific before/after callbacks per agreement type. +# batch operation — a single step in a batchCall array (see BatchOperation in Definitions.sol) +# trusted forwarder — a contract allowed to call forwardBatchCall for meta-transactions + +# == Batch Call == +# Primary entry point for interacting with the protocol. Users compose arrays of +# typed operations (ERC-20 approvals, SuperToken wrapping, agreement calls, etc.). +# +# == Batch Operation Types == +# Used in the operationType field of batchCall/forwardBatchCall operations. +# Data encoding varies by category — see notes on each type. +# +# Category 1–5: ERC-20/ERC-777 token ops +# target: must be a SuperToken (routes through SuperToken.operation* methods, +# NOT arbitrary ERC-20 contracts — use a separate tx for underlying approvals) +# data: abi-encoded parameters only (strip the 4-byte function selector) +# +# Category 101–102: SuperToken wrap/unwrap +# target: the SuperToken +# data: abi-encoded parameters only (strip the 4-byte function selector) +# +# Category 201: agreement call +# target: the agreement contract (e.g. CFA, GDA) +# data: abi.encode(callData, userData) where callData is full +# encodeFunctionData (selector included, with empty ctx placeholder "0x") +# +# Category 202: app action +# target: the Super App +# data: abi.encode(callData) where callData is full encodeFunctionData +# (selector included, with empty ctx placeholder "0x") +# +# Category 301: simple forward +# target: any contract +# data: full encodeFunctionData (selector included), or "0x" for pure value transfers +# +# Category 302: ERC-2771 forward +# target: any contract (must be an ERC-2771 recipient to extract the real sender) +# data: full encodeFunctionData (selector included) +# The ERC2771Forwarder appends the original msg.sender to calldata per ERC-2771. +# Use when the target contract needs to know who initiated the batch. + +batch_operation_types: + ERC20_APPROVE: 1 + ERC20_TRANSFER_FROM: 2 + ERC777_SEND: 3 # deprecated — ERC-777 is being phased out + ERC20_INCREASE_ALLOWANCE: 4 + ERC20_DECREASE_ALLOWANCE: 5 + SUPERTOKEN_UPGRADE: 101 + SUPERTOKEN_DOWNGRADE: 102 + SUPERFLUID_CALL_AGREEMENT: 201 + CALL_APP_ACTION: 202 + SIMPLE_FORWARD_CALL: 301 + ERC2771_FORWARD_CALL: 302 + +batchCall: + # Execute an array of operations in a single transaction as msg.sender. + notes: + - "Gotcha: For SIMPLE_FORWARD_CALL (type 301), target sees msg.sender as the SimpleForwarder contract, NOT the original caller. Use only when the target doesn't need to identify the sender." + - "Gotcha: ERC-20 ops (types 1-5) route through SuperToken.operation* methods, NOT arbitrary ERC-20 contracts. The target must be a SuperToken address. To approve an underlying ERC-20 (e.g. for wrapping), use a separate transaction." + - "Gotcha: If msg.value > 0, the entire amount is forwarded to the first CALL_APP_ACTION, SIMPLE_FORWARD, or ERC2771_FORWARD operation. If none exist, the native tokens are returned to the sender." + mutability: payable + access: anyone + inputs: + - operations: tuple[] + components: + - operationType: uint32 # see batch_operation_types above + - target: address + - data: bytes # encoding varies by operationType — see above + errors: [HOST_UNKNOWN_BATCH_CALL_OPERATION_TYPE] + +forwardBatchCall: + # Same as batchCall but uses EIP-2771 to extract msgSender from calldata. + # Can only be called by contracts registered as trusted forwarders in governance. + # If native tokens are left over, they are refunded to the EIP-2771 sender. + mutability: payable + access: trusted-forwarder + inputs: + - operations: tuple[] + components: + - operationType: uint32 # see batch_operation_types above + - target: address + - data: bytes # encoding varies by operationType — see above + errors: [HOST_UNKNOWN_BATCH_CALL_OPERATION_TYPE] + +# == Contextless Call Proxies == +# Entry points for EOAs and non-app contracts to interact with agreements or apps. +# These create a fresh Superfluid context with msg.sender, inject it into the call, +# and route through to the target agreement/app. + +callAgreement: + # Call an agreement function. The Host creates a context with msg.sender and replaces + # the placeholder ctx bytes in callData. This is how EOAs interact with CFA/IDA/GDA. + mutability: nonpayable + access: anyone # context set to msg.sender + inputs: + - agreementClass: address # must be a registered agreement + - callData: bytes # abi-encoded agreement call with placeholder ctx + - userData: bytes # extra data forwarded to Super App callbacks + outputs: + - returnedData: bytes + errors: [APP_RULE, HOST_ONLY_LISTED_AGREEMENT] + +callAppAction: + # Call an app action function on a Super App. The Host creates a context and routes + # the call. The action must not be an agreement callback selector. + mutability: nonpayable + access: anyone # context set to msg.sender + inputs: + - app: address # must be a registered, non-jailed Super App + - callData: bytes # abi-encoded app action call with placeholder ctx + outputs: + - returnedData: bytes + errors: [APP_RULE, HOST_NOT_A_SUPER_APP, HOST_SUPER_APP_IS_JAILED, HOST_AGREEMENT_CALLBACK_IS_NOT_ACTION] + +# == Contextual Call Proxies == +# For Super Apps to chain calls during callbacks. The app must pass the ctx it received. +# Only callable by the app currently executing a callback (ctx.appAddress == msg.sender). + +callAgreementWithContext: + # Chain an agreement call from within a Super App callback. + # The ctx must be valid and msg.sender must be the current callback app. + mutability: nonpayable + access: super-app + inputs: + - agreementClass: address + - callData: bytes + - userData: bytes + - ctx: bytes + outputs: + - newCtx: bytes + - returnedData: bytes + errors: [APP_RULE, HOST_ONLY_LISTED_AGREEMENT, HOST_CALL_AGREEMENT_WITH_CTX_FROM_WRONG_ADDRESS] + +callAppActionWithContext: + # Chain an app action call from within a Super App callback. + mutability: nonpayable + access: super-app + inputs: + - app: address + - callData: bytes + - ctx: bytes + outputs: + - newCtx: bytes + errors: [APP_RULE, HOST_NOT_A_SUPER_APP, HOST_SUPER_APP_IS_JAILED, HOST_AGREEMENT_CALLBACK_IS_NOT_ACTION, HOST_CALL_APP_ACTION_WITH_CTX_FROM_WRONG_ADDRESS] + +# == Context Utilities == + +decodeCtx: + # Decode a raw context bytes blob into the structured Context fields. + mutability: pure + inputs: + - ctx: bytes + outputs: + - context: + type: tuple + components: + - appCallbackLevel: uint8 + - callType: uint8 + - timestamp: uint256 + - msgSender: address + - agreementSelector: bytes4 + - userData: bytes + - appCreditGranted: uint256 + - appCreditWantedDeprecated: uint256 + - appCreditUsed: int256 + - appAddress: address + - appCreditToken: address + +isCtxValid: + # Check if a context blob matches the current transaction's context stamp. + mutability: view + inputs: + - ctx: bytes + outputs: + - bool + +# == App Registry == +# Super App registration. On some deployments, governance permission (via SimpleACL +# or legacy governance config) is required before an app can register. + +registerApp: + # Register msg.sender as a Super App with the given config word. + # On whitelisting-enabled deployments, tx.origin must have the + # ACL_SUPERAPP_REGISTRATION_ROLE or a valid legacy governance key. + mutability: nonpayable + access: self + inputs: + - configWord: uint256 # Super App manifest flags (see SuperAppDefinitions) + emits: [AppRegistered] + errors: [HOST_NO_APP_REGISTRATION_PERMISSION, HOST_INVALID_CONFIG_WORD, HOST_SUPER_APP_ALREADY_REGISTERED] + +registerApp(address,uint256): + # Register an external contract as a Super App. + # Useful for factory patterns where the deployer registers the app. + mutability: nonpayable + access: anyone + inputs: + - app: address # must be a contract + - configWord: uint256 + emits: [AppRegistered] + errors: [HOST_MUST_BE_CONTRACT, HOST_NO_APP_REGISTRATION_PERMISSION, HOST_INVALID_CONFIG_WORD, HOST_SUPER_APP_ALREADY_REGISTERED] + +registerAppWithKey: + # DEPRECATED — use registerApp(uint256) instead. + # Legacy registration using a governance-provided registration key string. + mutability: nonpayable + access: self + inputs: + - configWord: uint256 + - registrationKey: string + emits: [AppRegistered] + errors: [HOST_NO_APP_REGISTRATION_PERMISSION, HOST_INVALID_CONFIG_WORD, HOST_SUPER_APP_ALREADY_REGISTERED] + +registerAppByFactory: + # DEPRECATED — use registerApp(address, uint256) instead. + # Legacy factory-based registration using governance-authorized factory addresses. + mutability: nonpayable + access: factory + inputs: + - app: address + - configWord: uint256 + emits: [AppRegistered] + errors: [HOST_MUST_BE_CONTRACT, HOST_NO_APP_REGISTRATION_PERMISSION, HOST_INVALID_CONFIG_WORD, HOST_SUPER_APP_ALREADY_REGISTERED] + +# == App Queries == + +isApp: + mutability: view + inputs: + - app: address + outputs: + - bool + +getAppCallbackLevel: + mutability: view + inputs: + - appAddr: address + outputs: + - uint8 + +getAppManifest: + # Returns the full manifest of a Super App. + # isSuperApp is false if the address was never registered. + mutability: view + inputs: + - app: address + outputs: + - isSuperApp: bool + - isJailed: bool + - noopMask: uint256 # bitmask of noop'd agreement callback selectors + +isAppJailed: + mutability: view + inputs: + - app: address + outputs: + - isJail: bool + +# == App Composition == +# Source apps can whitelist target apps for composability (calling downstream). +# Currently limited to MAX_APP_CALLBACK_LEVEL = 1 (one level of nesting). + +allowCompositeApp: + # Whitelist a target Super App for composition. msg.sender must be a Super App + # with a higher callback level than the target. + mutability: nonpayable + access: super-app + inputs: + - targetApp: address + errors: [HOST_SENDER_IS_NOT_SUPER_APP, HOST_RECEIVER_IS_NOT_SUPER_APP, HOST_SOURCE_APP_NEEDS_HIGHER_APP_LEVEL] + +isCompositeAppAllowed: + mutability: view + inputs: + - app: address + - targetApp: address + outputs: + - isAppAllowed: bool + +# == Agreement Framework == +# Internal protocol functions called by registered agreement contracts (CFA, IDA, GDA) +# to manage Super App callbacks and app credit. Only callable by agreements. +# +# Callback lifecycle (called by agreement during flow operations): +# 1. appCallbackPush — set up credit, push callback frame +# 2. callAppBeforeCallback — staticcall app's before hook (read-only) +# 3. (agreement executes core logic) +# 4. callAppAfterCallback — call app's after hook (state changes OK) +# 5. appCallbackPop — finalize credit accounting, pop frame + +callAppBeforeCallback: + # StaticCall a Super App's before-callback. Returns the callback data. + # If the callback reverts during a termination, the app is jailed instead of reverting. + mutability: nonpayable + access: agreement + inputs: + - app: address + - callData: bytes + - isTermination: bool + - ctx: bytes + outputs: + - cbdata: bytes + errors: [HOST_ONLY_LISTED_AGREEMENT, HOST_NEED_MORE_GAS, APP_RULE] + +callAppAfterCallback: + # Call a Super App's after-callback. Returns the (potentially modified) context. + # If the app returns an invalid ctx, it is jailed on termination or reverts otherwise. + mutability: nonpayable + access: agreement + inputs: + - app: address + - callData: bytes + - isTermination: bool + - ctx: bytes + outputs: + - newCtx: bytes + errors: [HOST_ONLY_LISTED_AGREEMENT, HOST_NEED_MORE_GAS, APP_RULE] + +appCallbackPush: + # Push a new callback frame onto the context stack before invoking a Super App. + # Sets up app credit and tracks the callback nesting level. + notes: + - "Gotcha: The appCreditGranted is backed by the flow sender's deposit as \"owed deposit\". If the Super App opens outgoing streams using this credit, the sender's total locked capital increases accordingly (roughly doubles for 1:1 relay, more for fan-out patterns)." + mutability: nonpayable + access: agreement + inputs: + - ctx: bytes + - app: address + - appCreditGranted: uint256 + - appCreditUsed: int256 + - appCreditToken: address + outputs: + - appCtx: bytes + errors: [HOST_ONLY_LISTED_AGREEMENT, APP_RULE] + +appCallbackPop: + # Pop the callback frame after a Super App callback completes. + # Adjusts appCreditUsed by the delta from the callback. + mutability: nonpayable + access: agreement + inputs: + - ctx: bytes + - appCreditUsedDelta: int256 + outputs: + - newCtx: bytes + errors: [HOST_ONLY_LISTED_AGREEMENT] + +ctxUseCredit: + # Record additional app credit usage during an agreement operation. + mutability: nonpayable + access: agreement + inputs: + - ctx: bytes + - appCreditUsedMore: int256 + outputs: + - newCtx: bytes + errors: [HOST_ONLY_LISTED_AGREEMENT] + +jailApp: + # Jail a Super App from within an agreement. Jailed apps have their callbacks bypassed. + mutability: nonpayable + access: agreement + inputs: + - ctx: bytes + - app: address + - reason: uint256 # see SuperAppDefinitions for jail reason codes + outputs: + - newCtx: bytes + emits: [Jail] + errors: [HOST_ONLY_LISTED_AGREEMENT] + +# == Governance == + +getGovernance: + mutability: view + outputs: + - governance: address + +replaceGovernance: + mutability: nonpayable + access: governance + inputs: + - newGov: address + emits: [GovernanceReplaced] + errors: [HOST_ONLY_GOVERNANCE] + +# == Agreement Whitelisting == +# Governance registers and upgrades agreement classes (CFA, IDA, GDA). + +registerAgreementClass: + # Register a new agreement class. Creates a UUPS proxy in upgradable deployments. + mutability: nonpayable + access: governance + inputs: + - agreementClassLogic: address + emits: [AgreementClassRegistered] + errors: [HOST_ONLY_GOVERNANCE, HOST_AGREEMENT_ALREADY_REGISTERED, HOST_MAX_256_AGREEMENTS] + +updateAgreementClass: + # Upgrade an existing agreement class to a new implementation. + mutability: nonpayable + access: governance + inputs: + - agreementClassLogic: address + emits: [AgreementClassUpdated] + errors: [HOST_ONLY_GOVERNANCE, HOST_NON_UPGRADEABLE, HOST_AGREEMENT_IS_NOT_REGISTERED] + +isAgreementTypeListed: + mutability: view + inputs: + - agreementType: bytes32 # keccak256 of agreement name string + outputs: + - yes: bool + +isAgreementClassListed: + mutability: view + inputs: + - agreementClass: address + outputs: + - yes: bool + +getAgreementClass: + mutability: view + inputs: + - agreementType: bytes32 + outputs: + - agreementClass: address + errors: [HOST_AGREEMENT_IS_NOT_REGISTERED] + +mapAgreementClasses: + # Decode a bitmap into an array of agreement class addresses. + mutability: view + inputs: + - bitmap: uint256 + outputs: + - agreementClasses: address[] + +addToAgreementClassesBitmap: + mutability: view + inputs: + - bitmap: uint256 + - agreementType: bytes32 + outputs: + - newBitmap: uint256 + errors: [HOST_AGREEMENT_IS_NOT_REGISTERED] + +removeFromAgreementClassesBitmap: + mutability: view + inputs: + - bitmap: uint256 + - agreementType: bytes32 + outputs: + - newBitmap: uint256 + errors: [HOST_AGREEMENT_IS_NOT_REGISTERED] + +# == Super Token Factory == + +getSuperTokenFactory: + mutability: view + outputs: + - factory: address + +getSuperTokenFactoryLogic: + # Returns the logic address behind the factory proxy. For non-upgradable + # deployments, returns the factory address itself. + mutability: view + outputs: + - logic: address + +updateSuperTokenFactory: + # Deploy or upgrade the SuperTokenFactory. On first call, creates a UUPS proxy. + mutability: nonpayable + access: governance + inputs: + - newFactory: address + emits: [SuperTokenFactoryUpdated] + errors: [HOST_ONLY_GOVERNANCE, HOST_NON_UPGRADEABLE] + +updateSuperTokenLogic: + # Upgrade a SuperToken proxy to new logic. If newLogicOverride is address(0), + # uses the canonical logic from the SuperTokenFactory. + mutability: nonpayable + access: governance + inputs: + - token: address + - newLogicOverride: address # address(0) means use canonical logic + emits: [SuperTokenLogicUpdated] + errors: [HOST_ONLY_GOVERNANCE] + +changeSuperTokenAdmin: + # Change the admin of a SuperToken. The admin is the only account allowed to + # upgrade the token logic. Default admin is the Host itself. + mutability: nonpayable + access: governance + inputs: + - token: address + - newAdmin: address + errors: [HOST_ONLY_GOVERNANCE] + +# == Pool Beacon == + +updatePoolBeaconLogic: + # Upgrade the SuperfluidPool beacon to new logic. Affects all GDA pool proxies. + mutability: nonpayable + access: governance + inputs: + - newLogic: address + emits: [PoolBeaconLogicUpdated] + errors: [HOST_ONLY_GOVERNANCE] + +# == ERC2771 / Forwarder == + +isTrustedForwarder: + # Check if an address is a governance-approved trusted forwarder for meta-transactions. + mutability: view + inputs: + - forwarder: address + outputs: + - bool + +versionRecipient: + # ERC2771 relay recipient version string. Returns "v1". + mutability: pure + outputs: + - string + +getERC2771Forwarder: + # Returns the ERC2771Forwarder contract used for ERC2771_FORWARD_CALL batch operations. + mutability: view + outputs: + - address + +getSimpleACL: + # Returns the SimpleACL contract used for Super App registration permissioning. + mutability: view + outputs: + - address + +# == Time == + +getNow: + # Returns block.timestamp. Useful for off-chain tooling and testing. + mutability: view + outputs: + - uint256 + +# == Protocol Constants == + +NON_UPGRADABLE_DEPLOYMENT: + # True if the Host was deployed in non-upgradable mode. + mutability: view + outputs: + - bool + +APP_WHITE_LISTING_ENABLED: + # True if Super App registration requires governance permission. + mutability: view + outputs: + - bool + +CALLBACK_GAS_LIMIT: + # Maximum gas forwarded to Super App callbacks. + mutability: view + outputs: + - uint64 + +MAX_APP_CALLBACK_LEVEL: + # Maximum callback nesting depth for composed Super Apps. Currently 1. + mutability: view + outputs: + - uint256 + +MAX_NUM_AGREEMENTS: + # Maximum number of agreement classes that can be registered. 256. + mutability: view + outputs: + - uint32 + +ACL_SUPERAPP_REGISTRATION_ROLE: + # keccak256("ACL_SUPERAPP_REGISTRATION_ROLE") — the SimpleACL role for app registration. + mutability: view + outputs: + - bytes32 + +SIMPLE_FORWARDER: + # Address of the SimpleForwarder used for SIMPLE_FORWARD_CALL batch operations. + mutability: view + outputs: + - address + +# == Events == + +events: + GovernanceReplaced: + data: + - oldGov: address + - newGov: address + + AgreementClassRegistered: + # agreementType is keccak256("org.superfluid-finance.agreements..") + data: + - agreementType: bytes32 + - code: address + + AgreementClassUpdated: + data: + - agreementType: bytes32 + - code: address + + SuperTokenFactoryUpdated: + data: + - newFactory: address + + SuperTokenLogicUpdated: + indexed: + - token: address + data: + - code: address + + PoolBeaconLogicUpdated: + indexed: + - beaconProxy: address + data: + - newBeaconLogic: address + + AppRegistered: + indexed: + - app: address + + Jail: + # Emitted when a Super App is jailed for violating protocol rules. + # See APP_RULE error below for reason code values. + indexed: + - app: address + data: + - reason: uint256 + + # Inherited events (from UUPSProxiable): + # CodeUpdated — emitted on proxy upgrade (uuid, codeAddress) + # Initialized — emitted on proxy initialization (version) + +# == Errors == + +errors: + # Governance + - HOST_ONLY_GOVERNANCE # caller is not the governance contract + + # Agreement whitelisting + - HOST_AGREEMENT_ALREADY_REGISTERED + - HOST_AGREEMENT_IS_NOT_REGISTERED + - HOST_MAX_256_AGREEMENTS # maximum agreement slots exhausted + - HOST_ONLY_LISTED_AGREEMENT # caller is not a registered agreement + + # Upgradability + - HOST_NON_UPGRADEABLE # deployment is non-upgradable + - HOST_CANNOT_DOWNGRADE_TO_NON_UPGRADEABLE + + # App registration + - HOST_MUST_BE_CONTRACT # app address has no code + - HOST_NO_APP_REGISTRATION_PERMISSION + - HOST_INVALID_CONFIG_WORD # invalid Super App manifest flags + - HOST_SUPER_APP_ALREADY_REGISTERED + - HOST_NOT_A_SUPER_APP # target is not a registered Super App + - HOST_SUPER_APP_IS_JAILED + + # App composition + - HOST_SENDER_IS_NOT_SUPER_APP + - HOST_RECEIVER_IS_NOT_SUPER_APP + - HOST_SOURCE_APP_NEEDS_HIGHER_APP_LEVEL + + # Context & call proxies + - HOST_NON_ZERO_LENGTH_PLACEHOLDER_CTX # placeholder ctx must be empty + - HOST_CALL_AGREEMENT_WITH_CTX_FROM_WRONG_ADDRESS # msg.sender != ctx.appAddress + - HOST_CALL_APP_ACTION_WITH_CTX_FROM_WRONG_ADDRESS # msg.sender != ctx.appAddress + - HOST_AGREEMENT_CALLBACK_IS_NOT_ACTION # app action selector matches a callback + + # Batch call + - HOST_UNKNOWN_BATCH_CALL_OPERATION_TYPE + + # Callback execution + - HOST_NEED_MORE_GAS # insufficient gas for Super App callback + + # Super App rule violations (generic, carries a reason code) + # Reason codes (from SuperAppDefinitions.sol): + # 10 — NO_REVERT_ON_TERMINATION_CALLBACK (delete callback reverted) + # 11 — NO_CRITICAL_SENDER_ACCOUNT (callback made sender critical) + # 12 — NO_CRITICAL_RECEIVER_ACCOUNT (callback made receiver critical) + # 20 — CTX_IS_READONLY (state change in before-callback staticcall) + # 21 — CTX_IS_NOT_CLEAN (context not properly returned) + # 22 — CTX_IS_MALFORMATED (context bytes corrupted/fabricated) + # 30 — COMPOSITE_APP_IS_NOT_WHITELISTED (no allowCompositeApp) + # 31 — COMPOSITE_APP_IS_JAILED (downstream app is jailed) + # 40 — MAX_APP_LEVEL_REACHED (callback nesting exceeded limit) + - APP_RULE: + inputs: + - _code: uint256 + + # SafeCast (inherited from OpenZeppelin) + - SafeCastOverflowedUintDowncast: + inputs: + - bits: uint8 + - value: uint256 diff --git a/.agents/skills/gooddollar/references/contracts/Superfluid.selectors.yaml b/.agents/skills/gooddollar/references/contracts/Superfluid.selectors.yaml new file mode 100644 index 0000000..18edf9b --- /dev/null +++ b/.agents/skills/gooddollar/references/contracts/Superfluid.selectors.yaml @@ -0,0 +1,51 @@ +# Generated by scripts/selectors.mjs +functions: + batchCall(tuple[]): 0x31131761 + forwardBatchCall(tuple[]): 0xbc5a2101 + callAgreement(): 0xb7a9d0f0 + callAppAction(): 0x40df3d29 + callAgreementWithContext(address,bytes,bytes,bytes): 0x4329d293 + callAppActionWithContext(address,bytes,bytes): 0xba48b5f8 + decodeCtx(bytes): 0x3f6c923a + isCtxValid(bytes): 0xbf428734 + registerApp(): 0x6d6c85c3 + registerAppWithKey(uint256,string): 0xbd1c448b + registerAppByFactory(address,uint256): 0xf3733052 + isApp(address): 0x3ca3ad4e + getAppCallbackLevel(address): 0x9378fa13 + getAppManifest(address): 0xf9f522f4 + isAppJailed(address): 0x6b4f3335 + allowCompositeApp(address): 0x57121e0c + isCompositeAppAllowed(address,address): 0xbb84cfa1 + callAppBeforeCallback(address,bytes,bool,bytes): 0x74041e02 + callAppAfterCallback(address,bytes,bool,bytes): 0x1e6d0a84 + appCallbackPush(bytes,address,uint256,int256,address): 0x768fabb0 + appCallbackPop(bytes,int256): 0x989b0c3e + ctxUseCredit(bytes,int256): 0x59a29141 + jailApp(bytes,address): 0x5578431e + replaceGovernance(address): 0x7283100c + registerAgreementClass(address): 0x15a024e1 + updateAgreementClass(address): 0x06cecba8 + isAgreementTypeListed(): 0xf8dba358 + isAgreementClassListed(address): 0x8ca48484 + getAgreementClass(bytes32): 0xb6d200de + mapAgreementClasses(uint256): 0xc56a069d + addToAgreementClassesBitmap(uint256,bytes32): 0xbced3ddc + removeFromAgreementClassesBitmap(uint256,bytes32): 0xa5dbbbcd + updateSuperTokenFactory(address): 0x54fbc493 + updateSuperTokenLogic(address): 0x787afde7 + changeSuperTokenAdmin(address,address): 0x0c565075 + updatePoolBeaconLogic(address): 0x2f89bf89 + isTrustedForwarder(address): 0x572b6c05 + SIMPLE_FORWARDER(): 0xf85263b9 +events: + GovernanceReplaced(address,address): 0x13abda02e63c790d0e2818b251282cfe5cbe0a8abd69c54bf5d2260c0907bd2e + AgreementClassRegistered(bytes32,address): 0x878135063a6cfb3bc333e534b1fdc83f4f12221cad6705c31c0567048a8bd3d1 + AgreementClassUpdated(bytes32,address): 0x9279aa773f2b588996032d8de89911555039f28b13a11a7c17074330bc082d9a + SuperTokenFactoryUpdated(address): 0xce13a9895a1719ad4493b2ac1a9bfb36070566161abab408e7ecbe586da8d499 + SuperTokenLogicUpdated(address,address): 0x840acbd291b38534819f47f875839277e502f40e1c7bfea2c5fc2c8017442cd3 + PoolBeaconLogicUpdated(address,address): 0x052cea8931962dd445ef48b0b998d3056bd0705f437087d60fe3c46a3fa09e1f + AppRegistered(address): 0x0d540ad8f39e07d19909687352b9fa017405d93c91a6760981fbae9cf28bfef7 + Jail(address,uint256): 0xbe3aa33bd245135e4e26b223d79d14ea479a47bff09f2b03c53838af1edbb14b + # Inherited events (from UUPSProxiable)(): 0x3a1d0f622cf5be33dc2558b359f025fbeca1d6fb271fb70452a02b0ec2666ce8 +errors: {} diff --git a/.agents/skills/gooddollar/references/contracts/UBISchemeV2.abi.yaml b/.agents/skills/gooddollar/references/contracts/UBISchemeV2.abi.yaml new file mode 100644 index 0000000..75e5e43 --- /dev/null +++ b/.agents/skills/gooddollar/references/contracts/UBISchemeV2.abi.yaml @@ -0,0 +1,305 @@ +# UBISchemeV2 — dynamic daily UBI pool with per-root claiming and cycle accounting +# Claim uses Identity getWhitelistedRoot(msg.sender); transfers use the root as claim key. + +meta: + name: UBISchemeV2 + version: v2 + source: + - https://raw.githubusercontent.com/GoodDollar/GoodProtocol/master/contracts/ubi/UBISchemeV2.sol + inherits: [DAOUpgradeableContract] + note: > + Pool sizing uses cycleLength, reserveFactor, minActiveUsers, and on-chain G$ + balance. claim() reverts if Identity root is zero. Internal accounting keys + claims by whitelisted root, payouts go to msg.sender. + deployments: + mainnet: + production: + UBIScheme: + networkId: 122 + address: "0xd253A5203817225e9768C05E5996d642fb96bA86" + creationBlock: 15747401 + production-celo: + UBIScheme: + networkId: 42220 + address: "0x43d72Ff17701B2DA814620735C39C620Ce0ea4A1" + creationBlock: 18006679 + production-xdc: + UBIScheme: + networkId: 50 + address: "0x22867567E2D80f2049200E25C6F31CB6Ec2F0faf" + creationBlock: 95249624 + related: + - https://docs.gooddollar.org/for-developers/core-contracts/ubischeme + - references/guides/claim.md + +getClaimerCount: + mutability: view + inputs: + - day: uint256 + outputs: + - count: uint256 + +getClaimAmount: + notes: + - "Returns aggregate amount claimed for the provided day index." + mutability: view + inputs: + - day: uint256 + outputs: + - amount: uint256 + +getDailyStats: + notes: + - "Returns (claimer count, total claimed amount) for the calendar day derived from periodStart." + mutability: view + inputs: [] + outputs: + - claimerCount: uint256 + - claimAmount: uint256 + +setCycleLength: + mutability: nonpayable + access: avatar + inputs: + - _newLength: uint256 + outputs: [] + emits: [CycleLengthSet] + errors: [CYCLE_TOO_SHORT, ONLY_AVATAR] + +setDay: + notes: + - "Anyone may advance currentDay when wall-clock day crosses the next boundary." + mutability: nonpayable + inputs: [] + outputs: [] + emits: [DaySet] + +hasClaimed: + mutability: view + inputs: + - account: address + outputs: + - claimed: bool + +isNotNewUser: + mutability: view + inputs: + - _account: address + outputs: + - isReturning: bool + +estimateNextDailyUBI: + notes: + - "View-only projection when dailyUbi not yet fixed for the current wall day." + mutability: view + inputs: [] + outputs: + - projected: uint256 + +"checkEntitlement()": + notes: + - "Uses msg.sender as member; resolves Identity root before hasClaimed check." + mutability: view + inputs: [] + outputs: + - amount: uint256 + +"checkEntitlement(address)": + notes: + - "Checks claimable amount for the provided member using that account's whitelisted root." + mutability: view + inputs: + - _member: address + outputs: + - amount: uint256 + +claim: + notes: + - "Resolves whitelistedRoot = Identity.getWhitelistedRoot(msg.sender); reverts if zero." + - "_claim keys bookkeeping by root but pays msg.sender." + - "May notify ClaimersDistribution at GDAO_CLAIMERS if configured." + - "On success emits UBIClaimed; distributionFormula may emit UBICalculated, UBICycleCalculated, DaySet, WithdrawFromDao." + mutability: nonpayable + access: anyone + inputs: [] + outputs: + - didClaim: bool + errors: + - NOT_IN_PERIOD_OR_PAUSED + - NOT_WHITELISTED + - CLAIM_TRANSFER_FAILED + - DAO_TRANSFER_FAILED + +setShouldWithdrawFromDAO: + mutability: nonpayable + access: avatar + inputs: + - _shouldWithdraw: bool + outputs: [] + emits: [ShouldWithdrawFromDAOSet] + errors: [ONLY_AVATAR] + +pause: + mutability: nonpayable + access: avatar + inputs: + - _pause: bool + outputs: [] + errors: [ONLY_AVATAR] + +setNewClaimersReserveFactor: + notes: + - "Adjusts reserveFactor used by distribution formula to reserve part of pool for new claimers." + mutability: nonpayable + access: avatar + inputs: + - _reserveFactor: uint32 + outputs: [] + errors: [ONLY_AVATAR] + +withdraw: + notes: + - "Avatar-controlled treasury action transferring G$ from scheme balance to recipient." + mutability: nonpayable + access: avatar + inputs: + - _amount: uint256 + - _recipient: address + outputs: [] + errors: + - ONLY_AVATAR + - WITHDRAW_FAILED + +lastClaimed: + notes: + - "Returns last claim timestamp keyed by account root logic used by hasClaimed checks." + mutability: view + inputs: + - account: address + outputs: + - ts: uint256 + +currentDay: + mutability: view + inputs: [] + outputs: + - day: uint256 + +periodStart: + mutability: view + inputs: [] + outputs: + - ts: uint256 + +dailyUbi: + mutability: view + inputs: [] + outputs: + - amount: uint256 + +lastWithdrawDay: + mutability: view + inputs: [] + outputs: + - day: uint256 + +shouldWithdrawFromDAO: + mutability: view + inputs: [] + outputs: + - flag: bool + +cycleLength: + mutability: view + inputs: [] + outputs: + - days: uint256 + +dailyCyclePool: + mutability: view + inputs: [] + outputs: + - pool: uint256 + +startOfCycle: + mutability: view + inputs: [] + outputs: + - ts: uint256 + +currentCycleLength: + mutability: view + inputs: [] + outputs: + - length: uint256 + +minActiveUsers: + mutability: view + inputs: [] + outputs: + - n: uint256 + +totalClaimsPerUser: + mutability: view + inputs: + - account: address + outputs: + - count: uint256 + +reserveFactor: + mutability: view + inputs: [] + outputs: + - bps: uint32 + +paused: + mutability: view + inputs: [] + outputs: + - isPaused: bool + +events: + WithdrawFromDao: + indexed: [] + data: + - prevBalance: uint256 + - newBalance: uint256 + UBICalculated: + indexed: [] + data: + - day: uint256 + - dailyUbi: uint256 + - blockNumber: uint256 + UBICycleCalculated: + indexed: [] + data: + - day: uint256 + - pool: uint256 + - cycleLength: uint256 + - dailyUBIPool: uint256 + UBIClaimed: + indexed: + - claimer: address + data: + - amount: uint256 + CycleLengthSet: + indexed: [] + data: + - newCycleLength: uint256 + DaySet: + indexed: [] + data: + - newDay: uint256 + ShouldWithdrawFromDAOSet: + indexed: [] + data: + - ShouldWithdrawFromDAO: bool + +errors: + NOT_IN_PERIOD_OR_PAUSED: "not in periodStarted or paused — requireStarted modifier." + CYCLE_TOO_SHORT: "cycle must be at least 1 day long" + DAO_TRANSFER_FAILED: "DAO transfer has failed — _withdrawFromDao balance check." + NOT_WHITELISTED: "UBIScheme: not whitelisted — claim()" + CLAIM_TRANSFER_FAILED: "claim transfer failed — G$ transfer in _transferTokens." + WITHDRAW_FAILED: "withdraw failed — avatar withdraw." + ONLY_AVATAR: "Inherited avatar-only guard on DAOUpgradeable paths." diff --git a/.agents/skills/gooddollar/references/contracts/UBISchemeV2.selectors.yaml b/.agents/skills/gooddollar/references/contracts/UBISchemeV2.selectors.yaml new file mode 100644 index 0000000..666b89d --- /dev/null +++ b/.agents/skills/gooddollar/references/contracts/UBISchemeV2.selectors.yaml @@ -0,0 +1,40 @@ +# Generated by scripts/selectors.mjs +functions: + getClaimerCount(uint256): 0xc7a76adf + getClaimAmount(uint256): 0xcef63600 + getDailyStats(): 0x069786ea + setCycleLength(uint256): 0x3d84ceca + setDay(): 0xdddc3616 + hasClaimed(address): 0x73b2e80e + isNotNewUser(address): 0xa21f698a + estimateNextDailyUBI(): 0xc7713870 + checkEntitlement(): 0x98d6621b + checkEntitlement(address): 0x1a787f2e + claim(): 0x4e71d92d + setShouldWithdrawFromDAO(bool): 0xde1de3a0 + pause(bool): 0x02329a29 + setNewClaimersReserveFactor(uint32): 0x414089be + withdraw(uint256,address): 0x00f714ce + lastClaimed(address): 0x013eba92 + currentDay(): 0x5c9302c9 + periodStart(): 0xeda4e6d6 + dailyUbi(): 0x1d8f5ea9 + lastWithdrawDay(): 0xd7c4cbb8 + shouldWithdrawFromDAO(): 0x456ac1c2 + cycleLength(): 0xeac471a0 + dailyCyclePool(): 0x9dc2c033 + startOfCycle(): 0xba075410 + currentCycleLength(): 0x741470ac + minActiveUsers(): 0x37658574 + totalClaimsPerUser(address): 0xcc054dfc + reserveFactor(): 0x4322b714 + paused(): 0x5c975abb +events: + WithdrawFromDao(uint256,uint256): 0x3107ec7eaa50b775d2486c7a394472235804b6fe1c0d4b7bd1d79b09df60f2ba + UBICalculated(uint256,uint256,uint256): 0x836fa39995340265746dfe9587d9fe5c5de35b7bce778afd9b124ce1cfeafdc4 + UBICycleCalculated(uint256,uint256,uint256,uint256): 0x83e0d535b9e84324e0a25922406398d6ff5f96d0c686204ee490e16d7670566f + UBIClaimed(address,uint256): 0x89ed24731df6b066e4c5186901fffdba18cd9a10f07494aff900bdee260d1304 + CycleLengthSet(uint256): 0xa61e6cca2c12e2a0a493683acfe95b034f0f50d793434f4dfe3ba06ea201f344 + DaySet(uint256): 0x67eb03bd555181f9dd23f546e4331ddfb8b4a7d0c8d261ba44e037f30ce894ea + ShouldWithdrawFromDAOSet(bool): 0x6cd9a0fd2e006be39a9918bf56c85cae1d4f4599474483ff18cb93355ebaaf8e +errors: {} diff --git a/.agents/skills/gooddollar/references/contracts/_rich-abi-yaml-format.md b/.agents/skills/gooddollar/references/contracts/_rich-abi-yaml-format.md new file mode 100644 index 0000000..41e2bae --- /dev/null +++ b/.agents/skills/gooddollar/references/contracts/_rich-abi-yaml-format.md @@ -0,0 +1,93 @@ +# Reading the Rich ABI YAMLs + +Each YAML is a self-contained contract reference. Here's how to parse them. + +## Root structure + +``` +# Header comment — contract name, description, key notes +meta: # name, version, source, implements, inherits, deployments, + # deploymentCreationBlocks (optional), notes +# == Section == # Grouped functions (these are the core content) +events: # All events the contract emits +errors: # Complete error index +``` + +Three root keys are reserved: `meta`, `events`, `errors`. Every other +root-level key is a **function**. + +## Function entries + +```yaml +createFlow: + # Description of what the function does. + notes: + - "Gotcha: Non-obvious behavior or edge cases listed here as structured data." + mutability: nonpayable # view | pure | nonpayable | payable + access: sender | operator # who can call (omitted for view/pure) + inputs: + - token: address + - receiver: address + - flowRate: int96 # inline comments for non-obvious params + - ctx: bytes + outputs: + - newCtx: bytes + emits: [FlowUpdated, FlowUpdatedExtension] # ordered by emission sequence + errors: [CFA_FLOW_ALREADY_EXISTS, CFA_INVALID_FLOW_RATE] # ordered by check sequence +``` + +Fields appear in this order: description comment, `notes`, `mutability`, +`access`, `inputs`, `outputs`, `emits`, `errors`. All are omitted when not +applicable. + +## Key conventions + +- **`ctx: bytes` parameter** = function is called through the Host + (`callAgreement` / `batchCall`), never directly. +- **`access` labels**: `anyone`, `host`, `self`, `admin`, `governance`, + `sender`, `receiver`, `operator`, `manager`, `pic`, `agreement`, + `trusted-forwarder`, `factory`, `super-app`. Combine with `|`. Conditional: + `anyone(if-critical-or-jailed)`. +- **`emits` and `errors` ordering** carries meaning: matches execution flow, + not alphabetical. First errors in the list are the most likely causes. +- **`notes:` field** on functions (and `meta.notes:` at contract level) + lists non-obvious behavior, common mistakes, or edge cases. Always read + these carefully. +- **`meta.source`** is an array of raw GitHub URLs to the Solidity source files + (implementation, interface, base — filenames are self-documenting). +- **`meta.deployments`** has per-network addresses split into `mainnet` and + `testnet` subgroups. +- **`creationBlock`**: decimal block where that **`address`** first has code; + put it on the same object as **`networkId`** / **`address`**, immediately after **`address`**. +- **`meta.deploymentCreationBlocks`**: same shape as **`meta.deployments`**, for + deployments stored as plain address strings; leaves are decimal block numbers. + +## Events section + +```yaml +events: + FlowUpdated: + indexed: # log topics (filterable) + - token: address + - sender: address + data: # log payload + - flowRate: int96 +``` + +## Errors section + +```yaml +errors: + # -- Category -- + - SIMPLE_ERROR # description + - PARAMETERIZED_ERROR: # errors with diagnostic data + inputs: + - value: uint256 +``` + +## Selector sidecar files + +Every `Foo.abi.yaml` has a companion `Foo.selectors.yaml` in the same +directory. These contain computed hex selectors (function 4-byte, error +4-byte, event 32-byte topic0) with full Solidity signatures for +verification. Generated by `scripts/selectors.mjs`. diff --git a/.agents/skills/gooddollar/references/deep-researches/faucet-flows.md b/.agents/skills/gooddollar/references/deep-researches/faucet-flows.md new file mode 100644 index 0000000..12b1899 --- /dev/null +++ b/.agents/skills/gooddollar/references/deep-researches/faucet-flows.md @@ -0,0 +1,42 @@ +# Faucet flows (user-facing explanation) + +This note explains the Faucet in plain language: what it does for users, why a top-up can fail, and what limits exist. + +The on-chain Faucet contract is used to add a small amount of native gas token to a wallet so the user can pay transaction fees. +Reference implementation: [`contracts/fuseFaucet/Faucet.sol`](https://github.com/GoodDollar/GoodProtocol/blob/master/contracts/fuseFaucet/Faucet.sol). +Addresses per chain: [deployment.json](https://github.com/GoodDollar/GoodProtocol/blob/master/releases/deployment.json) only (for example `Faucet` under `production`, `production-celo`, `production-xdc`). + +## What this means for users + +- If your wallet is eligible, Faucet can send a small gas top-up. +- Eligibility usually depends on identity status and anti-abuse limits. +- This is a support mechanism for transaction fees, not a general transfer or swap service. + +## Main actions (in user language) + +- **Top up wallet** (`topWallet`) + Attempts to send gas to the target wallet after checks pass. + +- **Check eligibility first** (`canTop`) + Fast pre-check to see if top-up is currently allowed. + +- **Estimate top-up amount** (`getToppingAmount`) + Shows the amount Faucet would try to send right now. + +## Why a top-up may fail + +- You are not currently authorized by identity rules. +- Daily limit reached. +- Weekly limit reached. +- Wallet is temporarily banned. +- Wallet is too new for current policy. +- Calculated top-up is below minimum threshold. + +## Important safety note + +- The `onTokenTransfer` path includes a swap-like mechanism and is not meant as a normal user swap route. +- It does not enforce slippage protection in the same way users expect from a dedicated swap UI. + +## For developers and agents + +Use `references/guides/faucet.md` for step-by-step execution flow and deterministic preflight calls. diff --git a/.agents/skills/gooddollar/references/deep-researches/fuse-to-celo-staking-migration.md b/.agents/skills/gooddollar/references/deep-researches/fuse-to-celo-staking-migration.md new file mode 100644 index 0000000..261c2d7 --- /dev/null +++ b/.agents/skills/gooddollar/references/deep-researches/fuse-to-celo-staking-migration.md @@ -0,0 +1,38 @@ +# Why Fuse to CELO staking migration uses a staged backend flow + +This explains why the migration is split into allowance detection, unstake, bridge, and destination re-stake instead of a single transaction. In this context, Fuse `GovernanceStakingV2` is the old/source staking contract and Celo **`GooddollarSavingsStream`** is the destination staking contract ([source](https://github.com/Ubeswap/gooddollar-contracts/blob/main/contracts/GooddollarSavingsStream.sol), [0x059ee811414230d1Fb157878D2b491240F4D8d3B](https://celoscan.io/address/0x059ee811414230d1Fb157878D2b491240F4D8d3B)). + +## Why this cannot be one-chain atomic + +Fuse governance staking and CELO destination savings live on different chains, so the system cannot atomically close and reopen stake in one EVM transaction. Cross-chain migration is asynchronous by design and must tolerate timing gaps between source completion and destination finalization. + +## Why user allowance is first + +The migration flow assumes a backend-operated execution wallet. If that wallet needs to pull or operate on user funds in the source path, user approval must exist first. Without allowance, all downstream steps fail, so approval state is the earliest hard gate. + +## Why unstake is separated from bridge + +The source staking position is the canonical balance record on Fuse. The migration must first materialize transferable G$ by closing or reducing stake, then bridge only the confirmed unlocked amount. Bridging before final unstake confirmation introduces mismatch risk. + +## Why bridge finalization must be explicit + +Bridge transfers are eventually consistent across chains. The destination stake step must only run after the bridged G$ is confirmed on CELO. This avoids phantom staking attempts and preserves deterministic accounting. + +## Why destination uses `stakeFor` + +Ubeswap `GooddollarSavingsStream` on Celo supports `stakeFor(amount, recipient)`, which allows the backend execution wallet to stake on behalf of the user after bridge finalization. This fits migration operations where custody is temporary during the transfer window. + +## Main operational risks + +- partial migration from source unstake or bridge limit constraints +- stuck-in-transit bridge messages delaying destination staking +- stale assumptions about contract addresses across networks +- reward expectation mismatch when moving from Fuse governance staking mechanics to CELO savings mechanics + +## Contract/source map + +- Fuse staking family (GoodProtocol): [`GovernanceStaking.sol`](https://github.com/GoodDollar/GoodProtocol/blob/master/contracts/governance/GovernanceStaking.sol) +- Fuse deployment mapping: [`deployment.json`](https://github.com/GoodDollar/GoodProtocol/blob/master/releases/deployment.json) (`production.GovernanceStakingV2`) +- Celo savings (Ubeswap): [`GooddollarSavingsStream.sol`](https://github.com/Ubeswap/gooddollar-contracts/blob/main/contracts/GooddollarSavingsStream.sol) +- Ubeswap contracts repository: [Ubeswap/gooddollar-contracts](https://github.com/Ubeswap/gooddollar-contracts) +- Bridge normalization for LZ quotes: [`BridgeHelperLibrary.normalizeFromTokenTo18Decimals`](https://github.com/GoodDollar/GoodBridge/blob/master/packages/bridge-contracts/contracts/messagePassingBridge/BridgeHelperLibrary.sol) (off-chain LayerZero fee estimation must match this; `canBridge` and `bridgeToWithLz` use the raw burn amount on the source chain) diff --git a/.agents/skills/gooddollar/references/deep-researches/gooddao-daostack-surface.md b/.agents/skills/gooddollar/references/deep-researches/gooddao-daostack-surface.md new file mode 100644 index 0000000..754a3a0 --- /dev/null +++ b/.agents/skills/gooddollar/references/deep-researches/gooddao-daostack-surface.md @@ -0,0 +1,37 @@ +# GoodDAO and DAOStack surface + +GoodProtocol’s on-chain **governance shell** is largely **DAOStack-shaped**: an **Avatar** holds protocol assets and reputation context; a **Controller** registers **schemes** and routes privileged calls. GoodDocs summarizes DAO-facing roles; **Avatar**, **Controller**, and other DAO contract addresses live only in [deployment.json](https://github.com/GoodDollar/GoodProtocol/blob/master/releases/deployment.json). Implementation follows [DAOStack Arc](https://github.com/daostack/arc) patterns. + +## Core interfaces (GoodProtocol) + +[`DAOStackInterfaces.sol`](https://github.com/GoodDollar/GoodProtocol/blob/master/contracts/DAOStackInterfaces.sol) defines the pieces most integrations touch: + +### Avatar + +- **`nativeToken()`** — often the G$ token address for the deployment. +- **`nativeReputation()`** — **`GReputation`** token for voting weight (see `GReputation` in `deployment.json`). +- **`owner()`** — owner of the Avatar, typically the **`Controller`** contract. + +### Controller + +- **`avatar()`** — address of the Avatar contract. +- **`registerScheme` / `unregisterScheme` / `unregisterSelf` / `isSchemeRegistered` / `getSchemePermissions`** — scheme lifecycle and permission bitmask per scheme+avatar. +- **`genericCall(contract, data, avatar, value)`** — executes arbitrary calls **as the avatar** (used heavily by DAO-backed contracts to move tokens or call NameService). +- **`mintTokens`**, **`externalTokenTransfer`**, **`sendEther`** — treasury-style operations through the controller/avatar. + +## How GoodProtocol contracts use it + +- **`DAOUpgradeableContract`** / **`DAOContract`** descendants resolve **`dao`** (Controller) and **`avatar`** from **NameService** keys such as **`CONTROLLER`** and **`AVATAR`** (also written during **NameService.initialize**). +- **Avatar-gated writes** (for example **NameService.setAddress**, **UBISchemeV2** admin functions, **IdentityV3** after `initDAO`) require **`msg.sender == dao.avatar()`** (or equivalent role), not EOAs. +- Schemes that upgrade themselves (for example staking **`upgrade()`**) use **`dao.genericCall`** and **`unregisterSelf`** against the avatar. + +## What agents should do + +1. Treat **DAO calls** as **governance-only** unless the user explicitly controls the avatar or a registered scheme. +2. For **read-only** work, use **NameService** and per-contract **view** functions; use **Controller.isSchemeRegistered** when validating that a target contract is an approved scheme (for example staking migrations). +3. Never fabricate **Avatar** or **Controller** addresses — use [deployment.json](https://github.com/GoodDollar/GoodProtocol/blob/master/releases/deployment.json) or NameService. + +## References + +- [Core contracts — DAO contracts](https://docs.gooddollar.org/for-developers/core-contracts) (narrative only; addresses from [deployment.json](https://github.com/GoodDollar/GoodProtocol/blob/master/releases/deployment.json) only) +- DAOStack Arc controller and avatar concepts in the upstream repo linked from GoodDocs. diff --git a/.agents/skills/gooddollar/references/deep-researches/how-ubi-is-minted.md b/.agents/skills/gooddollar/references/deep-researches/how-ubi-is-minted.md new file mode 100644 index 0000000..96d321a --- /dev/null +++ b/.agents/skills/gooddollar/references/deep-researches/how-ubi-is-minted.md @@ -0,0 +1,68 @@ +# How UBI is minted + +This document aligns agent explanations with [How GoodDollar works](https://docs.gooddollar.org/how-gooddollar-works) and GoodDocs component pages; **contract addresses** come only from [deployment.json](https://github.com/GoodDollar/GoodProtocol/blob/master/releases/deployment.json). + +## Monetary creation (protocol level) + +- New G$ is created in connection with reserve mechanics: purchases into the reserve and reserve-side parameters (including reserve ratio) influence how much G$ can be issued while maintaining backing (see sustainability and issuance sections in GoodDocs). +- Selling G$ back to the reserve burns supply in that model. +- G$ that the protocol creates is allocated across UBI, savings incentives, treasury, and ecosystem uses per the distribution section of GoodDocs. + +## Where G$ is actually created + +Creation happens at the G$ token `mint(...)` call site, not inside `UBIScheme.claim()`. + +Current implementation uses the Mento-core expansion path: + +- `GoodDollarExpansionController` mints and routes to distribution helper. + +**DistributionHelper recipients** decide how much eventually lands in the UBI pool. + +## Claim vs reserve minting (important distinction) + +- **Reserve path:** Buying G$ through the reserve-backed AMM (or related Mento rails) is where mint and burn tied to the reserve model most directly apply at the token level. +- **Daily UBI `claim()`:** On `UBISchemeV2`, a successful claim typically **transfers G$ from the scheme contract’s balance** to the user (`token.transfer` in `_transferTokens`). The scheme may be **refilled** from the DAO avatar via internal `_withdrawFromDao` when configured, not necessarily minting in the same transaction as `claim()`. So describe user-facing UBI as **receipt from the UBI scheme balance**; reserve **minting** is the macro story, **transfer** is the usual claim-time mechanism. + +## Mento-core expansion flow (detailed) + +This is the detailed path for modern reserve-ratio-aware expansion. + +1. A caller triggers `mintUBIFromExpansion(exchangeId)` on `GoodDollarExpansionController`. +2. Expansion is time-gated by config (`expansionFrequency`, `lastExpansion`), so it does not run every block. +3. Controller computes a reserve-ratio scalar (effectively compounding `(1 - expansionRate)` for elapsed periods). +4. Controller calls `GoodDollarExchangeProvider.mintFromExpansion(exchangeId, reserveRatioScalar)`. +5. Exchange provider updates exchange state (including reserve-ratio math) and returns `amountToMint`. +6. Controller mints G$ to `distributionHelper`. +7. Controller triggers distribution (`onDistribution`) so recipients (including UBIScheme when configured) receive allocation. + +Also in `GoodDollarExpansionController`: + +- `mintUBIFromInterest(exchangeId, reserveInterest)` +- `mintUBIFromReserveBalance(exchangeId)` + +These are additional funding paths that mint to distribution helper as part of reserve-driven policy. + +## Reserve ratio, expansion, and risk + +- Practical reserve-ratio intuition: collateral backing strength per unit of G$ supply. +- Lower reserve ratio means weaker backing and higher risk when adding new supply. +- Expansion uses reserve-ratio-aware math instead of blind fixed minting, but aggressive params can still increase sell pressure. +- Key policy levers are expansion rate and expansion frequency (plus caller cadence/automation quality). + +## What claimers experience + +- Verified users receive daily UBI from a pool split among those who claim in each period (GoodDocs). +- The user-facing transaction is a UBIScheme-style `claim` on chains where it is deployed; ABI and version follow your deployment. + +## On-chain components (typical) + +- Identity system for verification and whitelist roots. +- UBIScheme (or successor) for entitlement and claim execution. +- G$ token: value reaches users via **transfer** from scheme balance and/or broader minting economics from the reserve side depending on which action you analyze. +- DistributionHelper: bridge layer between mint source and recipient buckets (UBI, others). + +## Agent guidance + +- Use GoodDocs for macro issuance and allocation; use UBIScheme + token transfer behavior for **claim** explanations. +- Use [deployment.json](https://github.com/GoodDollar/GoodProtocol/blob/master/releases/deployment.json) for contract addresses instead of guessing. +- When users ask "why no UBI funding today", check whether mint functions were executed, then verify DistributionHelper recipient config and UBIScheme balance. diff --git a/.agents/skills/gooddollar/references/deep-researches/inviter-invitee-reward-model.md b/.agents/skills/gooddollar/references/deep-researches/inviter-invitee-reward-model.md new file mode 100644 index 0000000..267fa74 --- /dev/null +++ b/.agents/skills/gooddollar/references/deep-researches/inviter-invitee-reward-model.md @@ -0,0 +1,58 @@ +# Inviter and invitee reward model + +This explains why invite rewards sometimes work and sometimes fail, in user-facing terms. + +Invite rewards are handled by `InvitesV2`, but eligibility depends heavily on the identity system (`Identity`, often `IdentityV4`). In practice, most confusing cases are caused by whitelist or reverification state, not by the invite contract itself. + +## How the reward model works + +There are two separate moments: + +- `join`: the invitee registers with an invite code. +- bounty payout: the contract later checks if this invitee is eligible and pays inviter and invitee when rules pass. + +So joining does not guarantee immediate payout. Payout depends on current eligibility at claim time. + +## Why whitelist status is the main gate + +For bounty eligibility, `InvitesV2` checks whitelist state through Identity. + +The important behavior is: + +- A user can still have status `1` in identity storage but fail `isWhitelisted(...)` if reverification is due. +- When reverification is due, bounty checks fail until an admin refreshes authentication(Face Verification). +- Connected-wallet setups can still fail if the specific address used in invite flow does not pass the whitelist check expected by the contract path. + +## Why reverification blocks rewards + +Reverification cadence is defined in `IdentityV4` with day-based options (`reverifyDaysOptions`) and per-user progression (`authCount`). + +When too many days pass since the last authentication for that user’s current step: + +- `shouldReverify(...)` becomes true +- `isWhitelisted(...)` becomes false for bounty gating +- `canCollectBountyFor(...)` fails until authentication is refreshed + +This is why teams may see users who were once valid but are currently not eligible for invite rewards. + +## Common reasons a bounty is not paid + +- Invitee or inviter is not currently whitelisted. +- Reverification is due for invitee or inviter. +- `minimumClaims` or `minimumDays` thresholds are not met yet. +- Bounty was already paid or was zero at join time. +- Contract is inactive, or identity-chain checks do not match the active chain. +- Invite code or join state is invalid (duplicate code, self-invite, already joined). + +## What to measure for analytics + +- Historical pass: account was authenticated at least once (`lastAuthenticated > 0`). +- Current eligibility: account is currently whitelist-valid (`isWhitelisted`/non-zero root, depending on query design). + +Do not treat these as the same metric. Historical pass explains past onboarding success; current eligibility explains current payout success. + +## Contract sources + +- Invite contract: [`InvitesV2.sol`](https://github.com/GoodDollar/GoodProtocol/blob/master/contracts/invite/InvitesV2.sol) +- Identity contract: [`IdentityV4.sol`](https://github.com/GoodDollar/GoodProtocol/blob/master/contracts/identity/IdentityV4.sol) +- Deployment addresses: [deployment.json](https://github.com/GoodDollar/GoodProtocol/blob/master/releases/deployment.json) diff --git a/.agents/skills/gooddollar/references/deep-researches/mento-reserve-economics.md b/.agents/skills/gooddollar/references/deep-researches/mento-reserve-economics.md new file mode 100644 index 0000000..e46db2a --- /dev/null +++ b/.agents/skills/gooddollar/references/deep-researches/mento-reserve-economics.md @@ -0,0 +1,27 @@ +# Mento and reserve economics + +This note ties **macro G$ economics** (GoodDocs) to **Mento trading surfaces** (broker, reserve, expansion) that agents integrate on-chain. + +## Protocol-level story (GoodDocs) + +- G$ is **reserve-backed**; issuance and price discovery follow an **augmented bonding curve** (Bancor-style dynamics) described in [How GoodDollar works](https://docs.gooddollar.org/how-gooddollar-works). +- **Buying** from the reserve side increases reserve assets and can support **new G$ supply** within reserve rules; **selling back** burns G$ and returns collateral, with parameters governed by **GoodDAO**. +- Distribution of newly created G$ spans UBI, savings incentives, treasury, and ecosystem allocations (same doc), but execution timing depends on the mint path and distribution trigger used by the deployment flow. + +## User-facing buy and sell (historical vs current) + +- [Buy and Sell G$](https://docs.gooddollar.org/user-guides) describes reserve interaction, fees (including exit contribution on some paths), and older explorer flows (GoodMarketMaker / exchangeHelper on Ethereum testnets). Treat that page as **product narrative**; **live contract addresses** must come only from [deployment.json](https://github.com/GoodDollar/GoodProtocol/blob/master/releases/deployment.json). + +## Mento stack (agent integration) + +On networks where GoodDollar uses Mento (see `MentoBroker` and related keys in [deployment.json](https://github.com/GoodDollar/GoodProtocol/blob/master/releases/deployment.json) for your environment): + +- **`IBroker`** (implementation in [mento-core `Broker.sol`](https://github.com/mento-org/mento-core)) is the usual **swap entrypoint**: `getAmountIn` / `getAmountOut`, `swapIn` (exact in), `swapOut` (exact out), plus **trading limits** state per exchange id and token. +- **Reserve** holds collateral; **exchange provider** contracts price trades against the reserve; **GoodDollarExpansionController** and related interfaces in GoodProtocol’s [`MentoInterfaces.sol`](https://github.com/GoodDollar/GoodProtocol/blob/master/contracts/MentoInterfaces.sol) describe expansion and avatar wiring for governance-facing changes. +- Agents should not hardcode **exchangeId** or provider addresses: read them from [deployment.json](https://github.com/GoodDollar/GoodProtocol/blob/master/releases/deployment.json) or discover via `getExchangeProviders()` after confirming the broker address for the chain from that file. + +## Agent guidance + +1. Explain **macro** supply and reserve behavior with GoodDocs language. +2. Execute **swaps** with broker quotes, slippage bounds, and allowances per `references/guides/swap.md`. +3. On revert, distinguish **slippage / limit** failures (broker) from **reserve liquidity** messages (see `MentoBroker.abi.yaml` error map and mento-core source). diff --git a/.agents/skills/gooddollar/references/deep-researches/on-off-ramp-service.md b/.agents/skills/gooddollar/references/deep-researches/on-off-ramp-service.md new file mode 100644 index 0000000..b59e5c9 --- /dev/null +++ b/.agents/skills/gooddollar/references/deep-researches/on-off-ramp-service.md @@ -0,0 +1,69 @@ +# On- and off-ramp service via stable token swap + +Use this note for the service pattern where ramp providers do not list G$ directly. The practical path is: ramp in/out with a listed stable token (for example cUSD), then swap between stable and G$ on-chain. + +## Why this is required + +- Most on-/off-ramp providers list mainstream stable tokens, not G$. +- Service needs a bridge asset for fiat rails. +- Stable token becomes the integration point with ramp providers, while G$ remains the in-app asset. + +## On-chain source of truth + +- Solidity: [`contracts/utils/BuyGDClone.sol`](https://github.com/GoodDollar/GoodProtocol/blob/master/contracts/utils/BuyGDClone.sol) +- Components: + - `BuyGDCloneFactory` + - `BuyGDCloneV2` + - `DonateGDClone` +- Deployments: [releases/deployment.json](https://github.com/GoodDollar/GoodProtocol/blob/master/releases/deployment.json) + +## Service architecture + +The factory deploys EIP-1167 minimal clones and wires swap infrastructure (router, oracle, quoter, optional Mento broker configuration, G$ token, stable token). + +Swap execution is **dual-path**: + +- **Uniswap-style route** (router/quoter path) +- **Mento-based route** (broker/exchange-provider path) + +For each swap request, the service compares quoted outputs and selects the route with the **larger `amountOut`** (best execution for the same input amount), then enforces `minAmount` guard on the selected path. + +Each user gets a deterministic clone address from owner-based salt: + +- `predict(owner)` for buy clone +- `predictDonation(owner, donor)` for donation clone + +This is why clone-per-user design is used: + +- predictable per-user addresses for audit and routing +- isolated execution context +- cheaper deployment than full contract instances + +## Execution surface (conceptual) + +The operational surface is intentionally small and deterministic: + +- `create(owner)` +- `createAndSwap(owner, minAmount)` +- `predict(owner)` +- `createDonation`, `createDonationAndSwap`, `predictDonation` + +This keeps on-/off-ramp architecture auditable and predictable across users. + +## Risks + +- Wrong factory or wrong chain causes permanent fund loss risk. +- Stale router/oracle/mento config can fail swap or produce bad execution. +- Missing `minAmount` protection increases slippage risk. +- Quote source mismatch or stale quotes across Uniswap/Mento can pick a suboptimal route if not refreshed just before execution. + +## Boundary note + +This file explains **why** this architecture exists for ramp services and why per-user clones matter. +For step-by-step service execution flow, use `references/guides/on-off-ramp.md`. + +## Cross-reference + +- User narrative: [Buy and Sell G$](https://docs.gooddollar.org/user-guides) +- Token integration details: [How to integrate the G$ token](https://docs.gooddollar.org/for-developers/developer-guides/how-to-integrate-the-gusd-token) +- Broker ABI: `references/contracts/MentoBroker.abi.yaml` diff --git a/.agents/skills/gooddollar/references/guides/bridge.md b/.agents/skills/gooddollar/references/guides/bridge.md new file mode 100644 index 0000000..71fd6e8 --- /dev/null +++ b/.agents/skills/gooddollar/references/guides/bridge.md @@ -0,0 +1,187 @@ +# Bridge guide + +Use for moving G$ across supported networks with deployment-specific bridge contracts. + +Primary local ABI reference for MessagePassingBridge flow: + +- `references/contracts/MessagePassingBridge.abi.yaml` + +## GoodDocs alignment + +- User flow and high-level behavior: [Bridge GoodDollars](https://docs.gooddollar.org/user-guides/bridge-gooddollars). +- Resolve supported bridge contract addresses per chain from [deployment.json](https://github.com/GoodDollar/GoodProtocol/blob/master/releases/deployment.json) only (for example `MpbBridge` under `production`, `production-celo`, `production-xdc`). Use [Bridge GoodDollars](https://docs.gooddollar.org/user-guides/bridge-gooddollars) for user-facing flow and troubleshooting, not for addresses. + +## Goal + +Bridge with deterministic pre-checks: bridge support, allowance, amount, cross-chain transport fee, and delivered G$ after destination **amount** limits and protocol fee. + +## Required inputs + +- source and destination chain metadata +- bridge contract address for source chain +- source G$ token address +- amount in source token decimals +- signer and rpc url + +## Execution flow + +1. Resolve source bridge and token addresses for the network pair. +2. Run bridge eligibility checks for sender and amount via `canBridge(from, amount)` on the **source** bridge (same contract you call for `bridgeToWithLz` / `bridgeToWithAxelar`). Outbound burn does not invoke `canBridge` inside `_bridgeTo`; destination mint still enforces **amount** limits (see **Bridge amount limit context**). +3. Read allowance and approve bridge spender when required. +4. Resolve transport mode (`LZ` or `AXELAR`) and estimate required native fee. +5. Send bridge transaction with nonzero `msg.value` and explicit transport method. +6. Return tx hash and normalized bridge parameters. + +## Bridge fee context + +Two different costs show up on `MessagePassingBridge`; do not conflate them. + +**1. Cross-chain transport fee (native gas token on the source chain)** +Paid as **`msg.value`** on the outbound call. The contract reverts with **`MISSING_FEE`** if `msg.value` is zero. On the **LayerZero** path the contract compares your `msg.value` to **`estimateSendFee`** and reverts **`LZ_FEE(required, sent)`** if it is too low. Use the same **normalized** amount for `estimateSendFee` as the contract uses internally (see the next section). On the **Axelar** path you still attach native value for Gas Service / execution; there is no single `estimateSendFee` analogue in the snippet—follow Envio/Axelar docs or simulate the exact call for production amounts. + +**2. Protocol fee on minted G$ (destination chain, basis points)** +When the message is executed on the **destination** chain, the bridge applies **`bridgeFees`** (min / max / fee bps via `setBridgeFees`) and mints the recipient **minus** that fee; the fee portion is minted to **`feeRecipient`** when it is non-zero (see `bridgeFees()`, `feeRecipient`, and `_takeFee` / `ExecutedTransfer` in `references/contracts/MessagePassingBridge.abi.yaml`). This is **not** the LayerZero relayer fee; it is a separate cut on the **token amount** delivered on arrival. + +**3. Optional OFT / LayerZero token-adapter path** +If the flow uses the GoodDollar OFT-style adapter instead of `MessagePassingBridge`, fee quoting follows **`quoteSend`** / **`MessagingFee`** on that contract; see `references/contracts/GoodDollarOFTAdapter.abi.yaml`. + +## Bridge amount limit context + +**Bridge limit** means **bridge amount limit**: policy on **how much G$** (token volume) may move—**`minAmount`**, per-transfer cap, per-account daily cap, and aggregate daily cap—plus **`onlyWhitelisted`**. It does **not** mean the cross-chain **native** transport fee (`msg.value`, **`LZ_FEE`**), and it does **not** mean the **destination mint fee** in **`bridgeFees`** (bps); those are covered under **Bridge fee context**. + +Amount caps and counters are **per bridge deployment**: read the **source** contract for outbound **amount** policy and usage meters tied to the burn, and the **destination** contract for **`_enforceLimits`** at inbound mint completion; do not assume identical **`bridgeLimits`** across chains. + +**1. Amount caps and usage meters** +**`bridgeLimits()`** exposes **`dailyLimit`**, **`txLimit`**, **`accountDailyLimit`**, **`minAmount`**, and **`onlyWhitelisted`**. Compare those caps to **`bridgeDailyLimit()`** (aggregate **`bridged24Hours`** and **`lastTransferReset`**) and **`accountsDailyLimit(account)`** (same fields per sender). Updates use **`setBridgeLimits`** (access per the ABI). Field-level notes and accessors live in `references/contracts/MessagePassingBridge.abi.yaml`. + +**2. Source preflight vs destination enforcement** +**`canBridge(from, amount)`** on the **source** is a view-only diagnostic for **that amount**: same policy family as amount limit checks, evaluated on the **raw** burn size (not the LayerZero fee normalization). Outbound **`_bridgeTo`** does **not** call **`canBridge`**; call it from the client if you want **`(false, reason)`** before signing instead of learning only from a revert after burn setup. When the message is executed on the **destination**, **`_enforceLimits`** is the hard gate for **amount** throttles and whitelist behavior at mint time. + +## Outbound pause, approved requests, and inbound source bridges + +These controls are separate from numeric **amount** caps; they still block or relax bridging and can surface as **`BRIDGE_LIMITS`** or inbound skips. + +**`pauseBridge`** sets **`isClosed`**; when closed, outbound flow reverts with **`BRIDGE_LIMITS('closed')`**. **`approvedRequests(requestId)`** on the destination lets **`_bridgeFrom`** skip standard **amount** limit enforcement for that completion when set. **`setDisabledBridges`** toggles **`disabledSourceBridges`** entries keyed by **`keccak256(abi.encode(sourceChainId, BridgeService))`**, controlling whether an inbound relay from that source is accepted before the rest of destination handling. See `references/contracts/MessagePassingBridge.abi.yaml`. + +## Axelar vs LayerZero on GoodDollar deployments + +LayerZero mappings are initialized for Ethereum, Celo, Fuse, and XDC in `initialize` / `upgrade` on `MessagePassingBridge`. The **Axelar** path is only usable where `toAxelarChainId(targetChainId)` returns a non-empty string; the on-chain pure function currently maps **1**, **5**, **42220**, and **44787** only. For **Fuse (122)** or **XDC (50)** targets, use **LZ** (`bridgeToWithLz`) unless governance ships a broader Axelar mapping. + +## LayerZero fee and `estimateSendFee` + +`bridgeToWithLz` burns the G$ **raw** amount in the source token’s `decimals()`. Inside the contract, LayerZero payload and `estimateSendFee` use a value normalized to **18 decimals** the same way as [GoodBridge `BridgeHelperLibrary.normalizeFromTokenTo18Decimals`](https://github.com/GoodDollar/GoodBridge/blob/master/packages/bridge-contracts/contracts/messagePassingBridge/BridgeHelperLibrary.sol): if `decimals < 18`, multiply by `10^(18 - decimals)`; if `decimals > 18`, divide by `10^(decimals - 18)`; otherwise use the raw amount. + +`canBridge(from, amount)` is evaluated on the **raw** burn amount, not the normalized value. + +Read `decimals()` from the source G$ contract when building off-chain fee quotes so you stay aligned if a deployment differs. + +## Deterministic snippet + +```js +import { ethers } from "ethers"; + +function normalizedForLzFee(raw, tokenDecimals) { + if (tokenDecimals < 18) return raw * 10n ** BigInt(18 - tokenDecimals); + if (tokenDecimals > 18) return raw / 10n ** BigInt(tokenDecimals - 18); + return raw; +} + +const provider = new ethers.JsonRpcProvider(process.env.RPC_URL); +const signer = new ethers.Wallet(process.env.PRIVATE_KEY, provider); + +const token = new ethers.Contract( + process.env.GOODDOLLAR_ADDRESS, + [ + "function decimals() view returns (uint8)", + "function allowance(address,address) view returns (uint256)", + "function approve(address,uint256) returns (bool)", + ], + signer, +); + +const bridge = new ethers.Contract( + process.env.BRIDGE_ADDRESS, + [ + "function canBridge(address,uint256) view returns (bool,string)", + "function toLzChainId(uint256) view returns (uint16)", + "function estimateSendFee(uint16,address,address,uint256,bool,bytes) view returns (uint256,uint256)", + "function bridgeToWithLz(address,uint256,uint256,bytes) payable", + "function bridgeToWithAxelar(address,uint256,uint256,address) payable", + ], + signer, +); + +const owner = await signer.getAddress(); +const targetChainId = Number(process.env.TARGET_CHAIN_ID); +const recipient = process.env.RECIPIENT; +const amount = ethers.parseUnits(process.env.AMOUNT, Number(process.env.DECIMALS)); +const transport = (process.env.BRIDGE_TRANSPORT || "LZ").toUpperCase(); +const tokenDecimals = await token.decimals(); +const normalizedForLzEstimate = normalizedForLzFee(amount, Number(tokenDecimals)); + +const [canBridge, reason] = await bridge.canBridge(owner, amount); +if (!canBridge) throw new Error(`Bridge blocked: ${reason}`); + +const allowance = await token.allowance(owner, process.env.BRIDGE_ADDRESS); +if (allowance < amount) { + const approveTx = await token.approve(process.env.BRIDGE_ADDRESS, amount); + await approveTx.wait(); +} + +let tx; + +if (transport === "LZ") { + const dstEid = await bridge.toLzChainId(targetChainId); + if (dstEid === 0) throw new Error("Unsupported target chain for LayerZero"); + + const adapterParams = process.env.LZ_ADAPTER_PARAMS || "0x"; + const [nativeFee] = await bridge.estimateSendFee( + dstEid, + owner, + recipient, + normalizedForLzEstimate, + false, + adapterParams, + ); + if (nativeFee <= 0n) throw new Error("Estimated LayerZero fee is zero"); + + tx = await bridge.bridgeToWithLz(recipient, targetChainId, amount, adapterParams, { + value: nativeFee, + }); +} else if (transport === "AXELAR") { + const nativeFee = ethers.parseEther(process.env.AXELAR_FEE_ETH || "0.01"); + tx = await bridge.bridgeToWithAxelar(recipient, targetChainId, amount, owner, { + value: nativeFee, + }); +} else { + throw new Error("Unsupported BRIDGE_TRANSPORT. Use LZ or AXELAR"); +} + +const receipt = await tx.wait(); +console.log( + JSON.stringify( + { + txHash: receipt.hash, + sourceBridge: process.env.BRIDGE_ADDRESS, + targetChainId, + transport, + recipient, + rawAmount: amount.toString(), + tokenDecimals: Number(tokenDecimals), + normalizedAmountForLz: normalizedForLzEstimate.toString(), + }, + null, + 2, + ), +); +``` + +## Failure handling + +- unsupported destination: return targetChainId, bridge address, and transport mode +- fee too low (`LZ_FEE` or underpriced Axelar fee): re-estimate and retry with user confirmation +- approval or balance issue: return required delta +- credited G$ on destination is reduced by **`bridgeFees`** (bps / min / max); that is independent of the source **`msg.value`** transport fee +- **`canBridge`** false on source: return the **`reason`** string from the view call +- **`BRIDGE_LIMITS(reason)`** custom error (see `references/contracts/MessagePassingBridge.abi.yaml` **errors**): **`reason`** labels the failing check (numeric **amount** limit, whitelist, **`closed`**, or other policy string from the implementation) +- source preflight passed but destination still reverts: re-read **`bridgeLimits`** and daily counters for **amount** caps and **`onlyWhitelisted`**; check **`isClosed`**, **`approvedRequests`**, and **`disabledSourceBridges`** per **Outbound pause, approved requests, and inbound source bridges**; message delivery can cross a reset boundary or policy change diff --git a/.agents/skills/gooddollar/references/guides/check-identity.md b/.agents/skills/gooddollar/references/guides/check-identity.md new file mode 100644 index 0000000..adc0165 --- /dev/null +++ b/.agents/skills/gooddollar/references/guides/check-identity.md @@ -0,0 +1,87 @@ +# Check identity guide + +Use when the user asks whether an address is eligible for UBI or how identity links wallets. + +## GoodDocs alignment + +- [Connect another wallet address to identity](https://docs.gooddollar.org/user-guides/connect-another-wallet-address-to-identity): associated addresses resolve to a verified root in the Identity contract; `connectAccount` links wallets. +- One claim per day applies across all connected addresses for the same verified identity (see the hint on that page). + +## Goal + +Determine whitelist or authentication status with deterministic on-chain reads. + +## Metric semantics + +- **Passed whitelisting (historical):** use `lastAuthenticated(account) > 0`. +- **Still whitelisted (current):** use `getWhitelistedRoot(account) != 0x0` or `isWhitelisted(account) == true`. +- `getWhitelistedRoot(account) != 0x0` is a current-state signal, not an "ever passed" signal. + +## Required inputs + +- `nameServiceAddress` or explicit Identity address +- `account` to check +- `rpcUrl` and chain configuration + +## Execution flow + +1. Resolve `IDENTITY` from NameService when used on the deployment. +2. Read `getWhitelistedRoot(account)` or equivalent for the deployed Identity version. +3. Treat non-zero root as tied to a whitelisted identity tree when that is the protocol rule for the deployment. +4. Read `lastAuthenticated(account)` for historical pass status and `getWhitelistedRoot(account)` or `isWhitelisted(account)` for current status. + +## Deterministic snippet + +```js +import { ethers } from "ethers"; + +const provider = new ethers.JsonRpcProvider(process.env.RPC_URL); + +const nameService = new ethers.Contract( + process.env.NAMESERVICE_ADDRESS, + ["function getAddress(string) view returns (address)"], + provider, +); + +const identityAddress = await nameService.getAddress("IDENTITY"); +const identity = new ethers.Contract( + identityAddress, + [ + "function getWhitelistedRoot(address) view returns (address)", + "function isWhitelisted(address) view returns (bool)", + "function lastAuthenticated(address) view returns (uint256)", + ], + provider, +); + +const account = process.env.ACCOUNT; +const root = await identity.getWhitelistedRoot(account); +const isWhitelisted = await identity.isWhitelisted(account); +const lastAuthenticated = await identity.lastAuthenticated(account); + +console.log( + JSON.stringify( + { + account, + identityAddress, + whitelistedRoot: root, + isWhitelisted, + lastAuthenticated: lastAuthenticated.toString(), + }, + null, + 2, + ), +); +``` + +## Return shape + +- `isWhitelisted` or equivalent boolean summary +- `whitelistedRoot` or equivalent +- `lastAuthenticated` for historical-pass classification +- optional metadata fields when available + +## Failure handling + +- NameService cannot resolve `IDENTITY`: stop and fix inputs using [deployment.json](https://github.com/GoodDollar/GoodProtocol/blob/master/releases/deployment.json) (`Identity` / `NameService` for the target environment)—not GoodDocs tables. +- Read failures: return the failing call and next step. diff --git a/.agents/skills/gooddollar/references/guides/claim.md b/.agents/skills/gooddollar/references/guides/claim.md new file mode 100644 index 0000000..bd51abd --- /dev/null +++ b/.agents/skills/gooddollar/references/guides/claim.md @@ -0,0 +1,83 @@ +# Claim guide + +Use when the user wants to claim daily UBI. Protocol context: [How GoodDollar works](https://docs.gooddollar.org/how-gooddollar-works) and [UBIScheme (GoodDocs behavior)](https://docs.gooddollar.org/for-developers/core-contracts/ubischeme)—contract addresses only from [deployment.json](https://github.com/GoodDollar/GoodProtocol/blob/master/releases/deployment.json). + +## Goal + +Execute a safe `claim()` with identity pre-checks and clear outputs. + +## GoodDocs alignment + +- UBI is distributed daily to verified users; the active pool is split among claimers in each period (see [How GoodDollar works](https://docs.gooddollar.org/how-gooddollar-works)). +- UBIScheme deployments vary by chain (Fuse, Celo, XDC); resolve live contract addresses only from [deployment.json](https://github.com/GoodDollar/GoodProtocol/blob/master/releases/deployment.json) (`UBIScheme` under `production`, `production-celo`, or `production-xdc`). Use [Core contracts / UBIScheme](https://docs.gooddollar.org/for-developers/core-contracts/ubischeme) for documented behavior, not for addresses. + +## Required inputs + +- `nameServiceAddress` or explicit UBIScheme and Identity addresses from [deployment.json](https://github.com/GoodDollar/GoodProtocol/blob/master/releases/deployment.json) +- `rpcUrl` and chain configuration +- signer context + +## Execution flow + +1. Resolve `IDENTITY` and `UBISCHEME` from NameService when NameService is the source of truth for the deployment. +2. Confirm whitelist status for the claiming account. +3. Optionally read entitlement or claimable state before sending `claim()`. +4. Call `claim()` on the resolved UBIScheme (contract generation may differ by deployment; align ABI with your target). +5. Return tx hash and claimed amount when derivable from events or balance delta. + +## Deterministic snippet + +```js +import { ethers } from "ethers"; + +const provider = new ethers.JsonRpcProvider(process.env.RPC_URL); +const signer = new ethers.Wallet(process.env.PRIVATE_KEY, provider); + +const nameService = new ethers.Contract( + process.env.NAMESERVICE_ADDRESS, + ["function getAddress(string) view returns (address)"], + provider, +); + +const identityAddress = await nameService.getAddress("IDENTITY"); +const ubiAddress = await nameService.getAddress("UBISCHEME"); + +const identity = new ethers.Contract( + identityAddress, + [ + "function isWhitelisted(address) view returns (bool)", + "function getWhitelistedRoot(address) view returns (address)", + ], + provider, +); + +const account = await signer.getAddress(); +const isWhitelisted = await identity.isWhitelisted(account); +if (!isWhitelisted) throw new Error("Account is not whitelisted"); + +const root = await identity.getWhitelistedRoot(account); +if (root === ethers.ZeroAddress) throw new Error("No whitelisted root"); + +const ubi = new ethers.Contract( + ubiAddress, + ["function claim()", "event UBICalculated(address,uint256,uint256,uint256)"], + signer, +); + +const tx = await ubi.claim(); +const receipt = await tx.wait(); +console.log(JSON.stringify({ txHash: receipt.hash, account, root }, null, 2)); +``` + +## Pre-check failures + +- Not whitelisted: stop and point the user to identity verification flows in GoodDocs. +- Missing contract address: stop; use [deployment.json](https://github.com/GoodDollar/GoodProtocol/blob/master/releases/deployment.json) only. +- Zero entitlement: communicate that nothing is claimable in the current period without guessing amounts. + +## Output contract + +- network +- resolved contract addresses +- tx hash +- claim outcome details when available diff --git a/.agents/skills/gooddollar/references/guides/faucet.md b/.agents/skills/gooddollar/references/guides/faucet.md new file mode 100644 index 0000000..d224e85 --- /dev/null +++ b/.agents/skills/gooddollar/references/guides/faucet.md @@ -0,0 +1,76 @@ +# Faucet top-up guide + +Use when the user needs native gas top-up via GoodProtocol Faucet. + +## Goal + +Run deterministic pre-checks and call `topWallet` only when eligibility and limits pass. + +## Required inputs + +- `rpcUrl`, chain configuration, signer +- Faucet address for the chain (from [deployment.json](https://github.com/GoodDollar/GoodProtocol/blob/master/releases/deployment.json) `Faucet` under the matching environment, or `NameService.getAddress` when the deployment documents the key) +- target user address + +## Execution flow + +1. Resolve Faucet contract address for the active chain from [deployment.json](https://github.com/GoodDollar/GoodProtocol/blob/master/releases/deployment.json). +2. Run `canTop(user)` as preflight. +3. Read `getToppingAmount(user)` and communicate expected top-up. +4. If eligible, call `topWallet(user)`. +5. Return tx hash and resulting top-up context. + +## Deterministic snippet + +```js +import { ethers } from "ethers"; + +const provider = new ethers.JsonRpcProvider(process.env.RPC_URL); +const signer = new ethers.Wallet(process.env.PRIVATE_KEY, provider); + +const faucet = new ethers.Contract( + process.env.FAUCET_ADDRESS, + [ + "function canTop(address) view returns (bool)", + "function getToppingAmount(address) view returns (uint256)", + "function topWallet(address payable)", + ], + signer, +); + +const user = process.env.USER; +const canTop = await faucet.canTop(user); +if (!canTop) throw new Error("Faucet canTop returned false"); + +const amount = await faucet.getToppingAmount(user); +const tx = await faucet.topWallet(user); +const receipt = await tx.wait(); + +console.log( + JSON.stringify( + { + txHash: receipt.hash, + user, + toppingAmount: amount.toString(), + }, + null, + 2, + ), +); +``` + +## Common rejection reasons + +- `not authorized` +- daily or weekly cap reached +- banned address +- low effective `toTop` vs minimum threshold +- faucet inactive or wrong chain/address + +## Output contract + +- network +- faucet address +- `canTop` preflight result +- top-up amount estimate +- tx hash (when executed) diff --git a/.agents/skills/gooddollar/references/guides/gooddocs.md b/.agents/skills/gooddollar/references/guides/gooddocs.md new file mode 100644 index 0000000..5e5b4b3 --- /dev/null +++ b/.agents/skills/gooddollar/references/guides/gooddocs.md @@ -0,0 +1,37 @@ +# GoodDocs hub + +Canonical protocol documentation lives at [GoodDocs](https://docs.gooddollar.org/). + +This is a **routing guide** (quick link map), not a deep protocol analysis note. + +## Start here + +- [Welcome](https://docs.gooddollar.org/) +- [How GoodDollar works](https://docs.gooddollar.org/how-gooddollar-works) + +## User guides + +- [Buy and Sell G$](https://docs.gooddollar.org/user-guides) (reserve-backed buy/sell; includes historical Ethereum/Kovan explorer workflows in the doc) +- [Bridge GoodDollars](https://docs.gooddollar.org/user-guides/bridge-gooddollars) (MessagePassingBridge, fees, limits, troubleshooting) +- [Connect another wallet address to identity](https://docs.gooddollar.org/user-guides/connect-another-wallet-address-to-identity) + +## Developers + +- [Core contracts](https://docs.gooddollar.org/for-developers/core-contracts) (module overview; **do not** read contract addresses from GoodDocs—use [deployment.json](https://github.com/GoodDollar/GoodProtocol/blob/master/releases/deployment.json) only) +- [Developer guides index](https://docs.gooddollar.org/for-developers/developer-guides) +- [Integrate the G$ token](https://docs.gooddollar.org/for-developers/developer-guides/how-to-integrate-the-gusd-token) (ERC-677, ERC-777, decimals by chain, `transferAndCall`, fees) +- [Use G$ streaming](https://docs.gooddollar.org/for-developers/developer-guides/use-gusd-streaming) (Superfluid on Celo, CFAv1Forwarder) + +## Chain IDs (bridge doc) + +| Network | Chain ID | +| -------- | -------- | +| Ethereum | 1 | +| Fuse | 122 | +| Celo | 42220 | +| XDC | 50 | + +## This repo + +- Action playbooks: `references/guides/*.md`. +- Rich ABIs: `references/contracts/*.abi.yaml`. diff --git a/.agents/skills/gooddollar/references/guides/goodsdks.md b/.agents/skills/gooddollar/references/guides/goodsdks.md new file mode 100644 index 0000000..8092e40 --- /dev/null +++ b/.agents/skills/gooddollar/references/guides/goodsdks.md @@ -0,0 +1,110 @@ +# GoodSDKs integration guide + +Use this guide when the task is SDK-first (app integration), not raw contract-first. + +## Scope + +GoodSDKs is the app integration layer for GoodDollar: + +- `@goodsdks/citizen-sdk` for identity and claim flows. +- `@goodsdks/react-hooks` for Wagmi React hooks. +- `@goodsdks/good-reserve` for reserve buy or sell flows. +- `@goodsdks/engagement-sdk` for engagement rewards flows. +- `@goodsdks/ui-components` and `@goodsdks/savings-widget` for web components. + +## Routing map + +- Check whitelist, identity root, FV link -> `@goodsdks/citizen-sdk` (`IdentitySDK`) +- Claim UBI with entitlement checks and fallback chains -> `@goodsdks/citizen-sdk` (`ClaimSDK`) +- React app with Wagmi and minimal glue code -> `@goodsdks/react-hooks` +- Buy or sell via reserve rails (Celo or XDC support rules) -> `@goodsdks/good-reserve` +- Reward app registration, claims, reward history -> `@goodsdks/engagement-sdk` +- Embeddable UI in non-React or mixed stacks -> `@goodsdks/ui-components` or `@goodsdks/savings-widget` + +## Deterministic setup + +Monorepo prerequisites: + +```bash +cd ~/Projects/GoodSDKs +corepack enable +yarn install --immutable +yarn build +``` + +Target one workspace: + +```bash +yarn workspace @goodsdks/citizen-sdk build +yarn workspace @goodsdks/react-hooks build +``` + +## Deterministic usage snippets + +Identity SDK: + +```ts +import { createPublicClient, createWalletClient, custom, http } from "viem"; +import { IdentitySDK } from "@goodsdks/citizen-sdk"; + +const publicClient = createPublicClient({ transport: http("https://forno.celo.org") }); +const walletClient = createWalletClient({ transport: custom(window.ethereum) }); + +const identitySDK = await IdentitySDK.init({ + publicClient, + walletClient, + env: "production", +}); + +const { isWhitelisted, root } = await identitySDK.getWhitelistedRoot("0xYourAccount"); +console.log({ isWhitelisted, root }); +``` + +Claim SDK: + +```ts +import { ClaimSDK, IdentitySDK } from "@goodsdks/citizen-sdk"; + +const identitySDK = await IdentitySDK.init({ publicClient, walletClient, env: "production" }); +const claimSDK = await ClaimSDK.init({ + publicClient, + walletClient, + identitySDK, + env: "production", +}); + +const entitlement = await claimSDK.checkEntitlement(); +if (entitlement.amount > 0n) { + const receipt = await claimSDK.claim(); + console.log(receipt.transactionHash); +} +``` + +React hooks: + +```tsx +import { useIdentitySDK, useClaimSDK, useGoodReserve } from "@goodsdks/react-hooks"; + +const identity = useIdentitySDK("production"); +const claim = useClaimSDK("production"); +const reserve = useGoodReserve("production"); +``` + +Reserve SDK: + +```ts +import { GoodReserveSDK } from "@goodsdks/good-reserve"; + +const sdk = new GoodReserveSDK(publicClient, walletClient, "production"); +const quote = await sdk.getBuyQuote(CUSD_ADDRESS, amountIn); +const tx = await sdk.buy(CUSD_ADDRESS, amountIn, (quote * 95n) / 100n); +console.log(tx.hash); +``` + +## Agent rules + +1. Prefer SDK methods first for app tasks. +2. Use contract-level guides only when SDK does not expose required behavior. +3. Do not invent SDK method names; align with package READMEs and exported types. +4. For chain support errors, report chain and env explicitly (do not silently fallback). +5. For UI tasks, prefer hooks or components over bespoke wallet and viem plumbing. diff --git a/.agents/skills/gooddollar/references/guides/hypersync-hyperrpc.md b/.agents/skills/gooddollar/references/guides/hypersync-hyperrpc.md new file mode 100644 index 0000000..e7b6f28 --- /dev/null +++ b/.agents/skills/gooddollar/references/guides/hypersync-hyperrpc.md @@ -0,0 +1,110 @@ +# Envio HyperSync and HyperRPC + +Use this guide when the task is high-volume historical blockchain data fetch (events, blocks, txs), especially analytics and indexing workflows. + +## Official docs + +- HyperSync overview: [docs.envio.dev/docs/HyperSync/overview](https://docs.envio.dev/docs/HyperSync/overview) +- HyperRPC overview: [docs.envio.dev/docs/HyperRPC/overview-hyperrpc](https://docs.envio.dev/docs/HyperRPC/overview-hyperrpc) +- HyperRPC supported networks: [docs.envio.dev/docs/HyperRPC/hyperrpc-supported-networks](https://docs.envio.dev/docs/HyperRPC/hyperrpc-supported-networks) + +## What to use + +- **HyperSync**: preferred for new data pipelines and heavy historical scans. +- **HyperRPC**: read-only JSON-RPC drop-in for existing RPC code paths. + +## HyperRPC vs HyperSync (avoid mixing them up) + +- **HyperRPC** is a **hosted JSON-RPC URL** (same methods as `eth_getLogs`, `eth_blockNumber`, and so on). Any HTTP client or existing RPC stack can call it; put the API token in the URL path as Envio documents. +- **HyperSync** is a **separate high-throughput query API** used through **Envio client libraries** (for example `@envio-dev/hypersync-client` in Node). It is **not** “just another RPC endpoint” with the same ergonomics as a one-line `fetch` to `eth_getLogs` at large scale. + +## Decision rule + +1. For GoodDollar protocol history that exists on subgraphs, query the subgraph first and validate fields in `references/subgraphs/*-guide.md`. +2. If subgraph schema or freshness cannot satisfy the request, use **HyperSync** for large scans and pipelines, or **HyperRPC** when you must stay inside standard JSON-RPC. +3. For write operations (sending tx), use normal RPC providers; HyperRPC is read-only. + +## GoodDollar-relevant network coverage + +- Celo and XDC are supported on HyperRPC. +- Fuse is not currently listed; treat this as non-blocking and use existing providers for Fuse. + +## Access and auth + +- HyperRPC/HyperSync usage is account-based. +- HyperRPC requires an API key for reliable production use. +- Requests without API token are rate-limited and should be treated as non-production fallback only. +- Add API key in endpoint URL as documented by Envio. +- HyperRPC token pattern example from docs: `https://.rpc.hypersync.xyz/` + +## Agents: Envio API token when HyperSync is the best option + +After you decide **HyperSync** is the right tool for the user query (for example large historical scans or pipeline-scale log pulls where subgraphs are insufficient), check for a usable Envio credential in the execution environment (`ENVIO_API_TOKEN` for `@envio-dev/hypersync-client`, or the token Envio documents for your chosen URL pattern). + +If **no** Envio API token is available and you cannot complete the HyperSync path without it, **stop and explicitly ask the user** to provide an Envio API token (name the env var you need, typically `ENVIO_API_TOKEN`). Do not silently rely on anonymous or heavily rate-limited access as a substitute when HyperSync was already identified as the best approach. + +## Practical use in this repo + +- Keep subgraphs as first option for indexed protocol entities. +- Use HyperSync/HyperRPC when subgraph coverage is missing, stale, or insufficient for bulk historical pulls. +- When an agent chooses **HyperSync** as the best path and no Envio API token is available, follow **Agents: Envio API token when HyperSync is the best option** in this file and ask the user for `ENVIO_API_TOKEN` before proceeding. +- Keep contract addresses from [GoodProtocol/deployment.json](https://github.com/GoodDollar/GoodProtocol/blob/master/releases/deployment.json) only; use GoodDocs for product context, not for resolving contract addresses. +- For implementation details (client setup, query structure, supported methods), follow the Envio docs links above directly. + +## From block for historical fetches + +For **`eth_getLogs`**, HyperRPC, and HyperSync range queries, the lower bound is **`fromBlock`** (or the client’s equivalent). Prefer the deployment’s **`creationBlock`** from the matching row in `references/contracts/*.abi.yaml` (or **`meta.deploymentCreationBlocks`** where deployments are plain address strings) so scans do not start at genesis when you only need post-deploy history. Field placement for **`creationBlock`** is defined in `references/contracts/_rich-abi-yaml-format.md`. If you cannot determine the creation block, **`fromBlock` 0** is valid. + +## Prebuilt scripts (developers and local agents) + +These scripts avoid rediscovering HyperRPC wiring on every task. They require **Node.js 18 or newer** (global `fetch`). Paths like `scripts/...` are relative to the **GoodSkills repository root** (the directory that contains both `skills/` and `scripts/`), not relative to `skills/gooddollar/` alone. + +### Last N Identity `WhitelistedAdded` logs via HyperRPC + +- Script: `scripts/fetch-whitelist-events-hyperrpc.mjs` +- Default `EVENT_TOPIC0` matches `WhitelistedAdded(address)` on `IdentityV4`; override `EVENT_TOPIC0` for other events. +- Production Celo defaults: `CONTRACT_ADDRESS` defaults to `Identity` from `production-celo` in [GoodProtocol deployment.json](https://github.com/GoodDollar/GoodProtocol/blob/master/releases/deployment.json) (`0xC361A6E67822a0EDc17D899227dd9FC50BD62F42`). If `HYPERRPC_URL` is unset, the script builds `https://celo.rpc.hypersync.xyz/` from `HYPERRPC_API_TOKEN` or `ENVIO_API_TOKEN`. +- Optional env: `HYPERRPC_URL` (overrides token-based default), `CONTRACT_ADDRESS`, `LIMIT` (default `500`), `STEP` (default `2000`), `FROM_BLOCK` (decimal; omit to read **`creationBlock`** for `CONTRACT_ADDRESS` from `ABI_PATH` or the default `skills/gooddollar/references/contracts/IdentityV4.abi.yaml`), `ABI_PATH`, `TO_BLOCK` (default `latest`). **`fromBlock`** behavior is described in **From block for historical fetches** above. + +```bash +cd /path/to/GoodSkills +export HYPERRPC_API_TOKEN='' +node scripts/fetch-whitelist-events-hyperrpc.mjs +``` + +Web-only assistants without a shell cannot run the file; they should return the same env keys and command text so the user runs it locally. + +## HyperSync client minimal path (install required) + +HyperSync uses the official client. Install and query pattern (Celo example URLs from [Envio Celo docs](https://docs.envio.dev/docs/HyperIndex/celo)): + +```bash +npm install @envio-dev/hypersync-client +export ENVIO_API_TOKEN='' +``` + +Save as a `.mjs` file (or use `"type": "module"` in a local `package.json`) and run with `node`: + +```javascript +import { HypersyncClient, presetQueryLogsOfEvent } from "@envio-dev/hypersync-client"; + +const client = new HypersyncClient({ + url: "https://celo.hypersync.xyz", + apiToken: process.env.ENVIO_API_TOKEN, +}); + +const identity = "0x..."; +const whitelistedAddedTopic0 = + "0xee1504a83b6d4a361f4c1dc78ab59bfa30d6a3b6612c403e86bb01ef2984295f"; + +const fromBlock = 17237952; +const toBlock = await client.getHeight(); + +const query = presetQueryLogsOfEvent(identity, whitelistedAddedTopic0, fromBlock, toBlock); +const res = await client.get(query); +console.log(res.data.logs.length); +``` + +The example **`fromBlock`** matches **`creationBlock`** for production Celo Identity in `skills/gooddollar/references/contracts/IdentityV4.abi.yaml`; see **From block for historical fetches** above. + +Full API and streaming patterns: [HyperSync clients](https://docs.envio.dev/docs/HyperSync/hypersync-clients) and the package README for `@envio-dev/hypersync-client`. diff --git a/.agents/skills/gooddollar/references/guides/invite-bounties.md b/.agents/skills/gooddollar/references/guides/invite-bounties.md new file mode 100644 index 0000000..d60aafd --- /dev/null +++ b/.agents/skills/gooddollar/references/guides/invite-bounties.md @@ -0,0 +1,115 @@ +# Invite bounties guide + +Use when the task is to verify or execute inviter-invitee bounty payout flow and explain why payout is blocked. + +## Goal + +Check eligibility deterministically, execute payout only when eligible, and return exact failure reason when not eligible. + +## Required inputs + +- target chain +- `InvitesV2` address +- `Identity` address +- optional `UBISchemeV2` address when claims threshold is active +- invitee address +- inviter address +- rpc url and signer + +## Execution flow + +1. Resolve contract addresses from `deployment.json`. +2. Read invitee state from `users(invitee)` and global thresholds (`minimumClaims`, `minimumDays`, `active`). +3. Check current eligibility with `canCollectBountyFor(invitee)`. +4. If not eligible, read identity whitelist for invitee and inviter and return concrete blocker. +5. If eligible, execute `bountyFor(invitee)` or `collectBounties()` and return tx hash plus payout values from events. + +## Deterministic snippet + +```js +import { ethers } from "ethers"; + +const provider = new ethers.JsonRpcProvider(process.env.RPC_URL); +const signer = new ethers.Wallet(process.env.PRIVATE_KEY, provider); + +const invites = new ethers.Contract( + process.env.INVITES_ADDRESS, + [ + "function canCollectBountyFor(address) view returns (bool)", + "function bountyFor(address)", + "function users(address) view returns (bytes32,address,uint40,uint24,bool,uint256)", + "function minimumClaims() view returns (uint256)", + "function minimumDays() view returns (uint256)", + "function active() view returns (bool)", + "event InviterBounty(address indexed inviter,address indexed invitee,uint256 bountyPaid,uint256 inviterLevel,bool earnedLevel)" + ], + signer, +); + +const identity = new ethers.Contract( + process.env.IDENTITY_ADDRESS, + [ + "function isWhitelisted(address) view returns (bool)" + ], + provider, +); + +const invitee = process.env.INVITEE_ADDRESS; +const inviter = process.env.INVITER_ADDRESS; + +const [isActive, eligible, inviteeWhitelisted, inviterWhitelisted, minClaims, minDays] = await Promise.all([ + invites.active(), + invites.canCollectBountyFor(invitee), + identity.isWhitelisted(invitee), + identity.isWhitelisted(inviter), + invites.minimumClaims(), + invites.minimumDays(), +]); + +if (!isActive) throw new Error("Invites contract is inactive"); +if (!eligible) { + throw new Error( + `Not eligible. inviteeWhitelisted=${inviteeWhitelisted} inviterWhitelisted=${inviterWhitelisted} minimumClaims=${minClaims} minimumDays=${minDays}`, + ); +} + +const tx = await invites.bountyFor(invitee); +const receipt = await tx.wait(); +const bountyEvent = receipt.logs + .map((log) => { + try { + return invites.interface.parseLog(log); + } catch { + return null; + } + }) + .find((e) => e && e.name === "InviterBounty"); + +console.log( + JSON.stringify( + { + txHash: receipt.hash, + invitee, + inviter, + bountyPaid: bountyEvent?.args?.bountyPaid?.toString() ?? null, + }, + null, + 2, + ), +); +``` + +## Failure handling + +- invitee or inviter is not currently whitelisted +- reverification is due and whitelist check fails until re-authentication +- minimum claims or minimum days is not met +- bounty already paid or bounty-at-join is zero +- contract inactive or wrong deployment addresses + +## Output contract + +- network and addresses used +- eligibility status and blockers +- tx hash when sent +- payout values when available from logs diff --git a/.agents/skills/gooddollar/references/guides/migrate-fuse-staking-to-celo-savings.md b/.agents/skills/gooddollar/references/guides/migrate-fuse-staking-to-celo-savings.md new file mode 100644 index 0000000..4ad9fd2 --- /dev/null +++ b/.agents/skills/gooddollar/references/guides/migrate-fuse-staking-to-celo-savings.md @@ -0,0 +1,116 @@ +# Fuse to CELO staking migration guide + +Use when the user wants to migrate an existing Fuse governance stake into a CELO destination savings flow. In this flow, Fuse `GovernanceStakingV2` is the old staking contract (source) and **`GooddollarSavingsStream`** on Celo is the destination savings contract ([`GooddollarSavingsStream.sol`](https://github.com/Ubeswap/gooddollar-contracts/blob/main/contracts/GooddollarSavingsStream.sol), [CeloScan](https://celoscan.io/address/0x059ee811414230d1Fb157878D2b491240F4D8d3B)). + +## Goal + +Close a user stake on Fuse, bridge the resulting G$ to CELO, and stake on CELO for that user in a controlled backend flow. + +## Required inputs + +- user address on Fuse and corresponding destination address on CELO +- Fuse `GovernanceStakingV2` address (`production.GovernanceStakingV2` in [deployment.json](https://github.com/GoodDollar/GoodProtocol/blob/master/releases/deployment.json)) +- Fuse G$ token address and bridge contract address (from [deployment.json](https://github.com/GoodDollar/GoodProtocol/blob/master/releases/deployment.json): `GoodDollar`, `MpbBridge` under `production`) +- CELO G$ token address (from `production-celo` in the same file) and destination savings contract address +- backend signer or service wallet with required execution permissions +- chain RPC URLs for Fuse and CELO + +## Address resolution quick table + +| Purpose | Network | Source key/path | Value | +|---|---|---|---| +| Governance staking (source close) | Fuse (`production`, `networkId: 122`) | `deployment.json` -> `production.GovernanceStakingV2` | `0xB7C3e738224625289C573c54d402E9Be46205546` | +| Governance staking (previous) | Fuse (`production`, `networkId: 122`) | `deployment.json` -> `production.GovernanceStaking` | `0xFAF457Fb4A978Be059506F6CD41f9B30fCa753b0` | +| Fuse G$ token | Fuse (`production`, `networkId: 122`) | `deployment.json` -> `production.GoodDollar` | `0x495d133B938596C9984d462F007B676bDc57eCEC` | +| Fuse bridge | Fuse (`production`, `networkId: 122`) | `deployment.json` -> `production.MpbBridge` | `0xa3247276DbCC76Dd7705273f766eB3E8a5ecF4a5` | +| Destination savings | CELO (`networkId: 42220`) | [CeloScan](https://celoscan.io/address/0x059ee811414230d1Fb157878D2b491240F4D8d3B) / `GooddollarSavingsStream` | `0x059ee811414230d1Fb157878D2b491240F4D8d3B` (`process.env.CELO_SAVINGS`) | + +Canonical sources: + +- [GoodProtocol deployment.json](https://github.com/GoodDollar/GoodProtocol/blob/master/releases/deployment.json) +- [Fuse explorer contract (GovernanceStakingV2 address)](https://explorer.fuse.io/address/0xB7C3e738224625289C573c54d402E9Be46205546?tab=contract) +- [Ubeswap gooddollar-contracts](https://github.com/Ubeswap/gooddollar-contracts) +- [GoodBridge bridge helper normalization](https://github.com/GoodDollar/GoodBridge/blob/master/packages/bridge-contracts/contracts/messagePassingBridge/BridgeHelperLibrary.sol) + +## Token decimals and `MessagePassingBridge` LZ fees + +Production deployments checked on-chain: Fuse `GoodDollar` uses **2** decimals and Celo `GoodDollar` uses **18**. Fuse `GovernanceStakingV2` (sG$) uses **2** decimals. Resolve `decimals()` from each live token in your runner so you stay correct if deployments change. + +On the Fuse `MpbBridge` (`MessagePassingBridge`), `canBridge(from, amount)` and `bridgeToWithLz(..., amount, ...)` use the **raw G$ burn amount** in source token decimals. Off-chain **`estimateSendFee`’s `_normalizedAmount` argument** must match what the contract builds internally: **`normalizeFromTokenTo18Decimals(amount, IERC20(nativeToken()).decimals())`** ([`BridgeHelperLibrary`](https://github.com/GoodDollar/GoodBridge/blob/master/packages/bridge-contracts/contracts/messagePassingBridge/BridgeHelperLibrary.sol)). Format displayed amounts per chain (`formatUnits`/UI) using each chain’s G$ decimals. + +## Execution flow + +1. Confirm allowance for whichever asset your flow spends first (for example sG$ allowance to the backend on Fuse `GovernanceStakingV2`, or Fuse G$ allowance if you pull G$ directly), before any transfers or bridges. +2. Verify current stake state on Fuse before closing: + - stake token balance + - withdrawable stake amount + - pending rewards if any +3. Execute Fuse unstake or close flow on governance staking (`withdrawStake` or equivalent full-close path). +4. Compute net G$ available for migration after unstake completion and any reward claim behavior. +5. Bridge G$ from Fuse to CELO using the configured bridge path and track the transfer id or tx hash pair. +6. Wait for destination finalization on CELO and verify credited G$ balance at the backend execution wallet. +7. Approve destination savings contract to spend migrated G$ amount. +8. Stake for the user on CELO with `stakeFor(amount, recipient)` on `GooddollarSavingsStream` (G$ native Super Token; approve the savings contract, not only ERC20 GoodDollar from `deployment.json` if your wallet holds the Super Token). +9. Return a migration result with both chain tx hashes and final CELO staked amount. + +## Deterministic snippet + +```js +import { ethers } from "ethers"; + +const fuse = new ethers.JsonRpcProvider(process.env.FUSE_RPC_URL); +const celo = new ethers.JsonRpcProvider(process.env.CELO_RPC_URL); +const signerFuse = new ethers.Wallet(process.env.BACKEND_PK, fuse); +const signerCelo = new ethers.Wallet(process.env.BACKEND_PK, celo); + +const user = process.env.USER_ADDRESS; +const migrateAmount = BigInt(process.env.MIGRATE_AMOUNT); + +const celoGd = new ethers.Contract( + process.env.CELO_GD_TOKEN, + [ + "function approve(address spender,uint256 amount) returns (bool)", + "function balanceOf(address) view returns (uint256)", + ], + signerCelo, +); + +const savings = new ethers.Contract( + process.env.CELO_SAVINGS, + ["function stakeFor(uint256 amount,address recipient)"], + signerCelo, +); + +const approveTx = await celoGd.approve(process.env.CELO_SAVINGS, migrateAmount); +await approveTx.wait(); + +const stakeTx = await savings.stakeFor(migrateAmount, user); +const receipt = await stakeTx.wait(); + +console.log( + JSON.stringify( + { + user, + celoStakeTx: receipt.hash, + migratedAmount: migrateAmount.toString(), + }, + null, + 2, + ), +); +``` + +## Pre-check failures + +- User allowance missing on Fuse: stop and request allowance tx from user. +- Stake close fails on Fuse: stop and return exact revert reason before bridge. +- Bridge transfer not finalized on CELO: do not call `stakeFor` until destination balance is confirmed. +- CELO savings approval missing or too low: re-approve exact amount before staking. + +## Output contract + +- user address +- Fuse unstake tx hash +- bridge tx hash or transfer identifier +- CELO stake tx hash +- final staked amount on CELO diff --git a/.agents/skills/gooddollar/references/guides/on-off-ramp.md b/.agents/skills/gooddollar/references/guides/on-off-ramp.md new file mode 100644 index 0000000..d212705 --- /dev/null +++ b/.agents/skills/gooddollar/references/guides/on-off-ramp.md @@ -0,0 +1,77 @@ +# On- and off-ramp service guide + +Use when implementing service flow where fiat ramps support a listed stable token (for example cUSD), and the app needs stable <-> G$ swap on-chain. + +## Goal + +Operate deterministic clone-based swap routing with explicit chain/factory verification and slippage guard. + +## Required inputs + +- target chain and factory address +- owner address used for clone derivation +- stable token and G$ token addresses +- direction: on-ramp or off-ramp +- `minAmount` guard +- signer and rpc url + +## Execution flow + +1. Resolve factory for target chain from [deployment.json](https://github.com/GoodDollar/GoodProtocol/blob/master/releases/deployment.json) (`BuyGDFactory` / `BuyGDFactoryV2` under `production-celo`, or the key your deployment uses). +2. Compute expected clone via `predict(owner)`. +3. If clone not yet deployed for flow, call `create(owner)` or `createAndSwap(owner, minAmount)`. +4. Execute stable -> G$ (on-ramp) or G$ -> stable (off-ramp) through clone path. +5. Return chain id, factory, predicted clone, effective clone, tx hashes. + +## Deterministic snippet + +```js +import { ethers } from "ethers"; + +const provider = new ethers.JsonRpcProvider(process.env.RPC_URL); +const signer = new ethers.Wallet(process.env.PRIVATE_KEY, provider); + +const factory = new ethers.Contract( + process.env.BUY_GD_CLONE_FACTORY, + [ + "function predict(address) view returns (address)", + "function create(address) returns (address)", + "function createAndSwap(address,uint256) returns (address)", + ], + signer, +); + +const owner = process.env.OWNER; +const minAmount = ethers.parseUnits(process.env.MIN_AMOUNT, Number(process.env.DECIMALS_OUT)); +const predicted = await factory.predict(owner); + +const tx = await factory.createAndSwap(owner, minAmount); +const receipt = await tx.wait(); + +console.log( + JSON.stringify( + { + txHash: receipt.hash, + owner, + predictedClone: predicted, + chainId: (await provider.getNetwork()).chainId.toString(), + }, + null, + 2, + ), +); +``` + +## Failure handling + +- predicted clone mismatch with trusted expectation +- wrong chain or wrong factory address +- swap output below `minAmount` +- stale router/oracle or exchange configuration + +## Output contract + +- network and chain id +- factory address +- predicted and actual clone addresses +- tx hashes diff --git a/.agents/skills/gooddollar/references/guides/save.md b/.agents/skills/gooddollar/references/guides/save.md new file mode 100644 index 0000000..d0e716c --- /dev/null +++ b/.agents/skills/gooddollar/references/guides/save.md @@ -0,0 +1,93 @@ +# Save and stake guide + +Use when the user wants to stake G$, withdraw rewards, or exit stake. Staking economics sit alongside other protocol allocations described in [How GoodDollar works](https://docs.gooddollar.org/how-gooddollar-works). + +## GoodDocs alignment + +- Token integration and fee awareness: [How to integrate the G$ token](https://docs.gooddollar.org/for-developers/developer-guides/how-to-integrate-the-gusd-token) (`_processFees`, decimals per chain). +- Contract addresses: [deployment.json](https://github.com/GoodDollar/GoodProtocol/blob/master/releases/deployment.json) only (for example staking and G$ token keys under `production` / `production-celo`). GoodDocs covers behavior and decimals patterns, not canonical deployment addresses. + +## Goal + +Run staking actions with balance and allowance safety checks. + +## Required inputs + +- `nameServiceAddress` or explicit staking and token addresses +- `amount` or `shares` depending on the action +- `rpcUrl`, chain configuration, signer + +## Execution flow + +1. Resolve staking and G$ token addresses from [deployment.json](https://github.com/GoodDollar/GoodProtocol/blob/master/releases/deployment.json) or, when the deployment documents the key, from `NameService.getAddress` on chain. +2. Read token balance and allowance. +3. Approve the staking contract when `stake` uses `transferFrom`. +4. Execute `stake`, `withdrawRewards`, or `withdrawStake` as requested. +5. Return tx hash and key resulting balances or events. + +## Deterministic snippets + +```js +import { ethers } from "ethers"; + +const provider = new ethers.JsonRpcProvider(process.env.RPC_URL); +const signer = new ethers.Wallet(process.env.PRIVATE_KEY, provider); + +const token = new ethers.Contract( + process.env.GOODDOLLAR_ADDRESS, + [ + "function balanceOf(address) view returns (uint256)", + "function allowance(address,address) view returns (uint256)", + "function approve(address,uint256) returns (bool)", + ], + signer, +); + +const staking = new ethers.Contract( + process.env.STAKING_ADDRESS, + [ + "function stake(uint256)", + "function withdrawRewards()", + "function withdrawStake(uint256)", + ], + signer, +); +``` + +Stake: + +```js +const amount = ethers.parseUnits(process.env.AMOUNT, Number(process.env.DECIMALS)); +const owner = await signer.getAddress(); +const allowance = await token.allowance(owner, process.env.STAKING_ADDRESS); +if (allowance < amount) { + const approveTx = await token.approve(process.env.STAKING_ADDRESS, amount); + await approveTx.wait(); +} +const tx = await staking.stake(amount); +const receipt = await tx.wait(); +console.log(JSON.stringify({ txHash: receipt.hash, action: "stake" }, null, 2)); +``` + +Withdraw rewards: + +```js +const tx = await staking.withdrawRewards(); +const receipt = await tx.wait(); +console.log(JSON.stringify({ txHash: receipt.hash, action: "withdrawRewards" }, null, 2)); +``` + +Withdraw stake: + +```js +const shares = ethers.parseUnits(process.env.SHARES, Number(process.env.DECIMALS)); +const tx = await staking.withdrawStake(shares); +const receipt = await tx.wait(); +console.log(JSON.stringify({ txHash: receipt.hash, action: "withdrawStake" }, null, 2)); +``` + +## Failure handling + +- Insufficient balance: report shortfall. +- Approval issues: report token, spender, and required allowance. +- Reverts: return attempted function and parameters without guessing custom errors. diff --git a/.agents/skills/gooddollar/references/guides/stream.md b/.agents/skills/gooddollar/references/guides/stream.md new file mode 100644 index 0000000..6cbf7a4 --- /dev/null +++ b/.agents/skills/gooddollar/references/guides/stream.md @@ -0,0 +1,135 @@ +# Stream guide + +Primary references for stream execution are local ABI assets in this repo: + +- `references/contracts/CFAv1Forwarder.abi.yaml` +- `references/contracts/ConstantFlowAgreementV1.abi.yaml` +- `references/contracts/Superfluid.abi.yaml` +- `references/contracts/SuperToken.abi.yaml` + +## Goal + +Create, update, or delete Superfluid constant flows using deterministic contract calls and local ABI references. + +## Protocol facts used by this guide + +- Forwarder path uses `CFAv1Forwarder.createFlow`, `updateFlow`, `deleteFlow`. +- Host path uses `Superfluid.callAgreement` with CFA calldata for `createFlow`, `updateFlow`, `deleteFlow`. +- Stream token is a SuperToken; flow rates are `int96` in token-wei per second. +- `getBufferAmountByFlowrate(token, flowRate)` is the canonical pre-check for required buffer. + +## Two implementation styles in this repo + +1. **Forwarder (matches GoodDocs):** call CFAv1Forwarder with token, sender, receiver, flowRate, userData. +2. **Host callAgreement:** encode CFA `createFlow` / `updateFlow` / `deleteFlow` and call `Superfluid.callAgreement`. + +## Minimal method map + +- Forwarder: + - `createFlow(address token, address receiver, int96 flowrate, bytes userData)` + - `updateFlow(address token, address receiver, int96 flowrate, bytes userData)` + - `deleteFlow(address token, address sender, address receiver, bytes userData)` + - `getBufferAmountByFlowrate(address token, int96 flowrate)` +- Host: + - `callAgreement(address agreementClass, bytes callData, bytes userData)` +- CFA: + - `createFlow(address token, address receiver, int96 flowRate, bytes ctx)` + - `updateFlow(address token, address receiver, int96 flowRate, bytes ctx)` + - `deleteFlow(address token, address sender, address receiver, bytes ctx)` + +## Required inputs + +- G$ Super Token address for the environment +- CFA forwarder address, or Superfluid host address plus CFA agreement address +- `action`: create, update, delete +- `receiver`, `flowRate` where applicable +- `rpcUrl`, chain configuration, signer + +## Deterministic snippet + +```js +import { ethers } from "ethers"; + +const provider = new ethers.JsonRpcProvider(process.env.RPC_URL); +const signer = new ethers.Wallet(process.env.PRIVATE_KEY, provider); + +const forwarder = new ethers.Contract( + process.env.CFA_FORWARDER, + [ + "function createFlow(address,address,int96,bytes)", + "function updateFlow(address,address,int96,bytes)", + "function deleteFlow(address,address,address,bytes)", + ], + signer, +); + +const token = process.env.SUPER_TOKEN; +const sender = await signer.getAddress(); +const receiver = process.env.RECEIVER; +const flowRate = BigInt(process.env.FLOW_RATE); + +if (process.env.ACTION === "create") { + const tx = await forwarder.createFlow(token, receiver, flowRate, "0x"); + const receipt = await tx.wait(); + console.log(JSON.stringify({ txHash: receipt.hash, action: "create" }, null, 2)); +} + +if (process.env.ACTION === "update") { + const tx = await forwarder.updateFlow(token, receiver, flowRate, "0x"); + const receipt = await tx.wait(); + console.log(JSON.stringify({ txHash: receipt.hash, action: "update" }, null, 2)); +} + +if (process.env.ACTION === "delete") { + const tx = await forwarder.deleteFlow(token, sender, receiver, "0x"); + const receipt = await tx.wait(); + console.log(JSON.stringify({ txHash: receipt.hash, action: "delete" }, null, 2)); +} +``` + +Host callAgreement example: + +```js +import { ethers } from "ethers"; + +const provider = new ethers.JsonRpcProvider(process.env.RPC_URL); +const signer = new ethers.Wallet(process.env.PRIVATE_KEY, provider); + +const cfa = new ethers.Interface([ + "function createFlow(address,address,int96,bytes)", + "function updateFlow(address,address,int96,bytes)", + "function deleteFlow(address,address,address,bytes)", +]); + +const host = new ethers.Contract( + process.env.SUPERFLUID_HOST, + ["function callAgreement(address,bytes,bytes) returns (bytes)"], + signer, +); + +const token = process.env.SUPER_TOKEN; +const sender = await signer.getAddress(); +const receiver = process.env.RECEIVER; +const flowRate = BigInt(process.env.FLOW_RATE); + +let callData = "0x"; +if (process.env.ACTION === "create") { + callData = cfa.encodeFunctionData("createFlow", [token, receiver, flowRate, "0x"]); +} +if (process.env.ACTION === "update") { + callData = cfa.encodeFunctionData("updateFlow", [token, receiver, flowRate, "0x"]); +} +if (process.env.ACTION === "delete") { + callData = cfa.encodeFunctionData("deleteFlow", [token, sender, receiver, "0x"]); +} + +const tx = await host.callAgreement(process.env.CFA_ADDRESS, callData, "0x"); +const receipt = await tx.wait(); +console.log(JSON.stringify({ txHash: receipt.hash, action: process.env.ACTION }, null, 2)); +``` + +## Failure handling + +- Wrong network or missing addresses: stop and return missing host or forwarder or token addresses. +- Insufficient buffer: use `getBufferAmountByFlowrate` and reduce flow rate or top up balance. +- Revert on create or update: verify token is a SuperToken and flowRate is positive. diff --git a/.agents/skills/gooddollar/references/guides/swap.md b/.agents/skills/gooddollar/references/guides/swap.md new file mode 100644 index 0000000..3db8c2d --- /dev/null +++ b/.agents/skills/gooddollar/references/guides/swap.md @@ -0,0 +1,83 @@ +# Swap guide + +Use for buying or selling G$ through Mento-connected contracts on networks where they appear in [deployment.json](https://github.com/GoodDollar/GoodProtocol/blob/master/releases/deployment.json) (for example `MentoBroker`, `MentoReserve`, `MentoExchangeProvider`, `MentoExpansionController` keys under `production-celo` or `production-xdc`). GoodDocs describes Mento product behavior, not deployment addresses. + +## GoodDocs alignment + +- Reserve and buy or sell mechanics at the protocol level: [How GoodDollar works](https://docs.gooddollar.org/how-gooddollar-works) and [Buy and Sell G$ user guide](https://docs.gooddollar.org/user-guides) (includes reserve AMM narrative; older explorer step-by-step for Ethereum testnets remains in that page for reference). +- Integration patterns and decimals: [How to integrate the G$ token](https://docs.gooddollar.org/for-developers/developer-guides/how-to-integrate-the-gusd-token). + +## Goal + +Execute bounded swaps using broker quotes and correct allowances. + +## Required inputs + +- `direction` as buy or sell +- broker and exchange identifiers for the deployment +- amounts in correct token decimals for the chain +- `rpcUrl`, chain configuration, signer + +## Execution flow + +1. Confirm Mento Broker (and related) addresses for the chain from [deployment.json](https://github.com/GoodDollar/GoodProtocol/blob/master/releases/deployment.json) only. +2. Fetch quote (`getAmountOut` or `getAmountIn` depending on direction and ABI). +3. Apply slippage bounds. +4. Approve the spent token for the broker when required. +5. Call `swapIn` or `swapOut` per your integration. +6. Return tx hash and effective amounts. + +## Deterministic snippet + +```js +import { ethers } from "ethers"; + +const provider = new ethers.JsonRpcProvider(process.env.RPC_URL); +const signer = new ethers.Wallet(process.env.PRIVATE_KEY, provider); + +const broker = new ethers.Contract( + process.env.BROKER_ADDRESS, + [ + "function getAmountOut(address,address,uint256) view returns (uint256)", + "function swapIn(address,address,uint256,uint256) returns (uint256)", + ], + signer, +); + +const tokenIn = new ethers.Contract( + process.env.TOKEN_IN, + [ + "function allowance(address,address) view returns (uint256)", + "function approve(address,uint256) returns (bool)", + ], + signer, +); + +const amountIn = ethers.parseUnits(process.env.AMOUNT_IN, Number(process.env.DECIMALS_IN)); +const quotedOut = await broker.getAmountOut(process.env.TOKEN_IN, process.env.TOKEN_OUT, amountIn); +const slippageBps = BigInt(process.env.SLIPPAGE_BPS); +const minOut = quotedOut * (10000n - slippageBps) / 10000n; + +const owner = await signer.getAddress(); +const allowance = await tokenIn.allowance(owner, process.env.BROKER_ADDRESS); +if (allowance < amountIn) { + const approveTx = await tokenIn.approve(process.env.BROKER_ADDRESS, amountIn); + await approveTx.wait(); +} + +const tx = await broker.swapIn(process.env.TOKEN_IN, process.env.TOKEN_OUT, amountIn, minOut); +const receipt = await tx.wait(); +console.log( + JSON.stringify( + { txHash: receipt.hash, amountIn: amountIn.toString(), minOut: minOut.toString() }, + null, + 2, + ), +); +``` + +## Failure handling + +- No deployment on chain: direct the user to an environment that defines the needed keys in [deployment.json](https://github.com/GoodDollar/GoodProtocol/blob/master/releases/deployment.json) (for example `production-celo` with `MentoBroker`). +- Stale quote or tight slippage: refresh quote or relax bounds with user consent. +- Allowance or balance shortfall: report exact delta. diff --git a/.agents/skills/gooddollar/references/subgraphs/_query-patterns.md b/.agents/skills/gooddollar/references/subgraphs/_query-patterns.md new file mode 100644 index 0000000..36af639 --- /dev/null +++ b/.agents/skills/gooddollar/references/subgraphs/_query-patterns.md @@ -0,0 +1,35 @@ +# Subgraph query discipline (GoodDollar) + +## Subgraph vs RPC + +- **Subgraph:** historical events, lists, aggregates, time ranges, analytics. Data lags chain head. +- **RPC / SDK:** current balances, live `claim` eligibility, exact view calls. Prefer for user-facing “what is true right now”. + +## Generic GraphQL mechanics + +Graph-node generates `entity`, `entities`, `Entity_filter`, `Entity_orderBy`, pagination, and `_meta` from each deployment’s `schema.graphql`. For scalar rules, filters, `_meta`, and common pitfalls, see [The Graph — Querying a subgraph](https://thegraph.com/docs/en/querying/graphql-api/). + +## GoodDollar-specific + +- **Addresses in `where` clauses:** normalize to **lowercase** hex strings; subgraphs store addresses lowercased. +- **BigInt fields:** query as **string** literals in GraphQL JSON (e.g. `"1000000000000000000"`). +- **Schema truth:** entity names differ per deployment. Run introspection or read the deployment’s `schema.graphql` under the relevant package in [GoodDollar/GoodSubGraphs](https://github.com/GoodDollar/GoodSubGraphs) before assuming field names. + +## Meta block + +Use `_meta { block { number } }` to detect how far behind indexing is when debugging stale data. + +```graphql +{ + _meta { + block { + number + } + hasIndexingErrors + } +} +``` + +## When subgraphs are not enough + +If the subgraph cannot answer the question (missing entities or fields, or stale indexing per `_meta`), switch to the decision rules in `references/guides/hypersync-hyperrpc.md`. When **HyperSync** is the best fit and no Envio API token is available in the environment, **ask the user directly** for `ENVIO_API_TOKEN` (or the token your HyperSync client expects) before running large scans; do not silently use anonymous quota as a stand-in. diff --git a/.agents/skills/gooddollar/references/subgraphs/goodcollective-guide.md b/.agents/skills/gooddollar/references/subgraphs/goodcollective-guide.md new file mode 100644 index 0000000..a266cea --- /dev/null +++ b/.agents/skills/gooddollar/references/subgraphs/goodcollective-guide.md @@ -0,0 +1,54 @@ +# GoodCollective — Subgraph Usage Guide + +Companion to `goodcollective.graphql`. + +## Endpoint + +- Explorer: [GoodCollective](https://thegraph.com/explorer/subgraphs/3LbJh9DXhJVvuVDdm5i6StNboJmL9oMNNkBaKyzc4Y8Y?view=Query&chain=arbitrum-one) +- Gateway form: `https://gateway.thegraph.com/api/subgraphs/id/3LbJh9DXhJVvuVDdm5i6StNboJmL9oMNNkBaKyzc4Y8Y` + +--- + +## Terminology: “claim” here is not daily UBI + +In this subgraph, **Claim** and **ClaimEvent** refer to **GoodCollective reward or pool claim flows**, not the protocol’s **daily UBI claim** from `UBIScheme` / `UBISchemeV2`. + +When a user says **“claim”** in normal GoodDollar product language, they almost always mean **claim daily UBI**. For that, use the GoodDollar Celo subgraph (`walletStats` / claim-related aggregates) and on-chain `claim` per `references/guides/claim.md` — do not answer “last N UBI claims” from GoodCollective **Claim** alone. + +--- + +## Entity Overview + +### Core collective graph + +**Collective** — pool identity, limits/settings links, totals, and claim/payment counters. +**Donor** / **Steward** — participant-level donation/support state. +**DonorCollective** / **StewardCollective** — join entities tying participants to a collective. + +### Claim and support flow + +**Claim** and **ClaimEvent** — GoodCollective **reward** claim lifecycle and per-claim reward events (not daily UBI from UBIScheme). +**SupportEvent** — support/donation change events across donor/collective links. + +### Metadata and policy entities + +**IpfsCollective** — IPFS metadata projection. +**PoolSettings**, **UBILimits**, **SafetyLimits** — pool policy and operational bounds. +**ProvableNFT** — NFT linkage used in claim/reward flows. + +--- + +## Typical Questions This Subgraph Answers + +- Which donors/stewards are attached to a collective? +- How much was donated/rewarded per collective and per participant? +- Which claim events occurred and what reward quantities were emitted? +- What limits and settings govern a specific collective pool? + +--- + +## Query Discipline + +- Use authenticated gateway access for programmatic queries. +- Lowercase address-like identifiers where applicable. +- Validate `_meta` before operational dashboards or reporting exports. diff --git a/.agents/skills/gooddollar/references/subgraphs/goodcollective.graphql b/.agents/skills/gooddollar/references/subgraphs/goodcollective.graphql new file mode 100644 index 0000000..e503db9 --- /dev/null +++ b/.agents/skills/gooddollar/references/subgraphs/goodcollective.graphql @@ -0,0 +1,200 @@ +scalar BigDecimal + +scalar BigInt + +scalar Boolean + +scalar Bytes + +type Claim { + id: String! + collective: Collective! + txHash: String! + networkFee: BigInt! + totalRewards: BigInt! + events: [ClaimEvent!]! + timestamp: Int! +} + +type ClaimEvent { + id: String! + eventType: Int! + timestamp: Int! + quantity: BigInt! + rewardPerContributor: BigInt! + contributors: [Steward!]! + nft: ProvableNFT + claim: Claim! +} + +type Collective { + id: String! + pooltype: PoolType! + ipfs: IpfsCollective + settings: PoolSettings! + ubiLimits: UBILimits + limits: SafetyLimits + donors: [DonorCollective!] + stewards: [StewardCollective!] + projectId: String! + isVerified: Boolean! + poolFactory: String! + timestamp: Int! + paymentsMade: Int! + totalDonations: BigInt! + totalRewards: BigInt! + claims: [Claim!]! +} + +type Donor { + id: String! + timestamp: Int! + totalDonated: BigInt! + collectives: [DonorCollective!]! +} + +""" +Represents the relationship between a Donor and a Collective + +""" + +type DonorCollective { + id: String! + donor: Donor! + collective: Collective! + contribution: BigInt! + flowRate: BigInt! + timestamp: Int! + events: [SupportEvent!]! +} + +scalar Float + +scalar ID + +""" +4 bytes signed integer + +""" + +scalar Int + +""" +8 bytes signed integer + +""" + +scalar Int8 + +type IpfsCollective { + id: String! + name: String! + description: String! + rewardDescription: String + goodidDescription: String + email: String + website: String + twitter: String + instagram: String + threads: String + infoLabel: String + headerImage: String! + logo: String! + images: [String!] +} + +type PoolSettings { + id: String! + nftType: BigInt! + manager: Bytes! + membersValidator: Bytes! + uniquenessValidator: Bytes! + rewardToken: Bytes! +} + +enum PoolType { + DirectPayments + UBI +} + +type ProvableNFT { + id: String! + owner: String! + hash: String! + stewards: [Steward!]! + collective: Collective +} + +type SafetyLimits { + id: String! + maxTotalPerMonth: BigInt! + maxMemberPerMonth: BigInt! + maxMemberPerDay: BigInt! +} + +type Steward { + """ + { user address} + + """ + id: String! + """ + Number of actions performed + + """ + actions: Int! + totalEarned: BigInt! + totalUBIEarned: BigInt! + """ + NFT's minted to steward + + """ + nfts: [ProvableNFT!]! + """ + Collectives the steward is apart of + + """ + collectives: [StewardCollective!]! +} + +""" +Represents the relationship between a Steward and a Collective + +""" + +type StewardCollective { + id: String! + steward: Steward! + collective: Collective! + actions: Int! + totalEarned: BigInt! +} + +scalar String + +type SupportEvent { + id: String! + networkFee: BigInt! + donor: Donor! + collective: Collective! + donorCollective: DonorCollective! + contribution: BigInt! + previousContribution: BigInt! + isFlowUpdate: Boolean! + flowRate: BigInt! + previousFlowRate: BigInt! + timestamp: Int! +} + +scalar Timestamp + +type UBILimits { + id: String! + cycleLengthDays: BigInt! + claimPeriodDays: BigInt! + minActiveUsers: BigInt! + claimForEnabled: Boolean! + maxClaimAmount: BigInt! + maxClaimers: BigInt! + onlyMembers: Boolean! +} diff --git a/.agents/skills/gooddollar/references/subgraphs/gooddollar-celo-guide.md b/.agents/skills/gooddollar/references/subgraphs/gooddollar-celo-guide.md new file mode 100644 index 0000000..347951f --- /dev/null +++ b/.agents/skills/gooddollar/references/subgraphs/gooddollar-celo-guide.md @@ -0,0 +1,104 @@ +# GoodDollar Celo — Subgraph Usage Guide + +Companion to `gooddollar-celo.graphql`. + +## Endpoint + +- Explorer: [GoodDollarCelo](https://thegraph.com/explorer/subgraphs/F7314rxGdcpKPC1nN5KCoFW84EGRoUyzseY2sAT9PEkw?view=Query&chain=arbitrum-one) +- Gateway form: `https://gateway.thegraph.com/api/subgraphs/id/F7314rxGdcpKPC1nN5KCoFW84EGRoUyzseY2sAT9PEkw` + +--- + +## Entity Overview + +### UBI and usage statistics + +**DailyUBI** — day-level UBI pool/quota activity and cycle fields. +**WalletStat** — wallet behavior aggregates: tx counts/values, claim stats, active/whitelist indicators. +**TransactionStat** — day-level transaction totals and circulation view. +**GlobalStatistics** — global claim and distribution rollups. + +### Additional UBI history entities + +**UBICollected** — collected UBI/community-pool values by block event. +**UBIHistory** — timeline totals for daily UBI/community-pool. + +--- + +## Field Availability Reference (use before drafting queries) + +Use this section to validate what the subgraph already provides before switching data sources. + +### DailyUBI + +- `id` — day index key (`unix / 86400`) +- `pool` — UBI cycle pool for that day +- `quota` — daily UBI amount per eligible claimer +- `activeUsers` — active users count in scheme context +- `totalUBIDistributed` — amount actually claimed/distributed that day +- `totalClaims` — claim tx count for that day +- `newClaimers` — newly whitelisted users for that day +- `timestamp` — last update timestamp for the record +- `ubiSchemeAddress` — UBIScheme address used for the record +- `balance` — G$ balance held by UBIScheme +- `cycleLength` — current cycle length +- `dayInCycle` — current day position inside cycle + +### WalletStat + +- `id` — wallet address +- `dateAppeared` — first indexed wallet activity timestamp +- `balance` — running token balance from transfers +- `inTransactionsCount`, `inTransactionsValue` — incoming tx count and value +- `outTransactionsCount`, `outTransactionsValue` — outgoing tx count and value +- `totalTransactionsCount`, `totalTransactionsValue` — total tx count and value +- `inTransactionsCountClean`, `inTransactionsValueClean` — incoming metrics excluding contract-address flows +- `outTransactionsCountClean`, `outTransactionsValueClean` — outgoing metrics excluding contract-address flows +- `totalTransactionsCountClean`, `totalTransactionsValueClean` — total clean traffic metrics +- `lastClaimed` — timestamp of latest UBI claim +- `totalClaimedCount`, `totalClaimedValue` — total claims and cumulative claimed value +- `claimStreak`, `longestClaimStreak` — current and best historical streaks +- `isWhitelisted` — current whitelist status +- `isActiveUser` — current active-user status +- `dateJoined` — first-whitelist timestamp +- `lastTransactionFrom`, `lastTransactionTo` — latest outgoing and incoming tx timestamps + +### TransactionStat + +- `id` — bucket key (day key or `"aggregated"`) +- `dayStartBlockNumber` — first block in bucket +- `transactionsCount`, `transactionsValue` — all transfer tx count and value +- `transactionsCountClean`, `transactionsValueClean` — transfer metrics excluding contract-address flows +- `totalInCirculation` — inferred circulating supply from mint or burn behavior + +### GlobalStatistics + +- `id` — fixed key (`"statistics"`) +- `TransactionStat` — link to aggregated transaction stats +- `totalUBIDistributed` — lifetime distributed UBI +- `uniqueClaimers` — tracked unique claimers via whitelist add or remove +- `totalClaims` — lifetime UBI claim events + +### Explorer naming + +- Singular names (`dailyUBI`, `walletStat`) fetch by `id` +- Plural names (`dailyUBIs`, `walletStats`) query lists with filters and pagination + +--- + +## Typical Questions This Subgraph Answers + +- How much UBI was distributed on a day/cycle? +- Which wallets are active or recently claiming? +- What are aggregate tx/circulation trends? +- How did collected UBI/community-pool values evolve over time? + +--- + +## Query Discipline + +- Use lowercase address strings in filters. +- Use string-safe handling for large integer values. +- Use `_meta` to validate freshness before cross-day analytics. +- Use authenticated gateway access for programmatic queries. +- Before claiming a field or entity is missing, verify availability from this guide and schema first. diff --git a/.agents/skills/gooddollar/references/subgraphs/gooddollar-celo.graphql b/.agents/skills/gooddollar/references/subgraphs/gooddollar-celo.graphql new file mode 100644 index 0000000..e544a0d --- /dev/null +++ b/.agents/skills/gooddollar/references/subgraphs/gooddollar-celo.graphql @@ -0,0 +1,113 @@ +scalar BigDecimal + +scalar BigInt + +scalar Boolean + +scalar Bytes + +type DailyUBI { + id: ID! + pool: BigInt! + quota: BigInt! + activeUsers: BigInt! + totalUBIDistributed: BigInt! + totalClaims: BigInt! + newClaimers: BigInt! + timestamp: BigInt! + ubiSchemeAddress: Bytes + balance: BigInt! + cycleLength: BigInt! + dayInCycle: BigInt! +} + +scalar Float + +type GlobalStatistics { + id: ID! + TransactionStat: TransactionStat + totalUBIDistributed: BigInt! + uniqueClaimers: BigInt! + totalClaims: BigInt! +} + +scalar ID + +""" +4 bytes signed integer +""" + +scalar Int + +""" +8 bytes signed integer +""" + +scalar Int8 + +""" +Defines the order direction, either ascending or descending +""" + +scalar String + +""" +A string representation of microseconds UNIX timestamp (16 digits) +""" + +scalar Timestamp + +type TransactionStat { + id: ID! + dayStartBlockNumber: BigInt! + transactionsCount: BigInt! + transactionsCountClean: BigInt! + transactionsValue: BigInt! + transactionsValueClean: BigInt! + totalInCirculation: BigInt! +} + +type UBICollected { + id: ID! + contract: Bytes + block: BigInt! + blockTimestamp: BigInt! + ubi: BigDecimal! + communityPool: BigDecimal! +} + +type UBIHistory { + id: ID! + block: BigInt! + blockTimestamp: BigInt! + totalDailyUBI: BigDecimal! + totalDailyCommunityPool: BigDecimal! +} + +type WalletStat { + id: ID! + dateAppeared: BigInt! + balance: BigInt! + inTransactionsCount: BigInt! + inTransactionsCountClean: BigInt! + inTransactionsValue: BigInt! + inTransactionsValueClean: BigInt! + outTransactionsCount: BigInt! + outTransactionsCountClean: BigInt! + outTransactionsValue: BigInt! + outTransactionsValueClean: BigInt! + totalTransactionsCount: BigInt! + totalTransactionsCountClean: BigInt! + totalTransactionsValue: BigInt! + totalTransactionsValueClean: BigInt! + lastClaimed: BigInt! + totalClaimedCount: BigInt! + totalClaimedValue: BigInt! + claimStreak: BigInt! + longestClaimStreak: BigInt! + isWhitelisted: Boolean! + isActiveUser: Boolean! + dateJoined: BigInt! + lastTransactionFrom: BigInt! + lastTransactionTo: BigInt! +} diff --git a/.agents/skills/gooddollar/references/subgraphs/reserve-celo-guide.md b/.agents/skills/gooddollar/references/subgraphs/reserve-celo-guide.md new file mode 100644 index 0000000..9f55b73 --- /dev/null +++ b/.agents/skills/gooddollar/references/subgraphs/reserve-celo-guide.md @@ -0,0 +1,41 @@ +# Reserve Celo — Subgraph Usage Guide + +Companion to `reserve-celo.graphql`. This guide is for reserve pricing and broker swap indexing on Celo. + +## Endpoint + +- Goldsky: `https://api.goldsky.com/api/public/project_cmizuamdtfouu01x4csuk5dk1/subgraphs/reserve_celo/1.0/gn` + +--- + +## Entity Overview + +### Core entity + +**ReservePrice** — one indexed reserve pricing point produced from broker swap flow plus exchange-provider price read. +Key fields: `exchangeId`, `exchangeProvider`, `price`, `timestamp`, `day`, `tokenIn`, `tokenOut`, `amountIn`, `amountOut`, `user`, `blockNumber`, `transactionHash`. + +--- + +## Typical Questions This Subgraph Answers + +- What are the most recent reserve prices? +- What was the reserve price on a specific day window? +- Which token pair and user triggered a pricing point? +- Which tx hash/block produced a given price point? + +--- + +## Query Discipline + +- Lowercase all address values in filters. +- Use string values for large integer variables. +- Use `_meta` before analytics queries when stale indexing is suspected. + +--- + +## Practical Start + +1. Check `_meta` block height and `hasIndexingErrors`. +2. Pull latest `ReservePrice` records sorted by `timestamp desc`. +3. Add `day`-based narrowing for historical windows. diff --git a/.agents/skills/gooddollar/references/subgraphs/reserve-celo.graphql b/.agents/skills/gooddollar/references/subgraphs/reserve-celo.graphql new file mode 100644 index 0000000..56cac37 --- /dev/null +++ b/.agents/skills/gooddollar/references/subgraphs/reserve-celo.graphql @@ -0,0 +1,90 @@ +scalar BigDecimal + +scalar BigInt + +scalar Boolean + +scalar Bytes + +scalar Float + +scalar ID + +""" +4 bytes signed integer +""" + +scalar Int + +""" +8 bytes signed integer +""" + +scalar Int8 + +""" +Defines the order direction, either ascending or descending +""" + +type ReservePrice { + """ + Exchange ID combined with timestamp + """ + id: ID! + """ + The exchange ID from the Swap event + """ + exchangeId: Bytes! + """ + The exchange provider address + """ + exchangeProvider: Bytes! + """ + The current price from IBancorExchangeProvider.currentPrice() + """ + price: BigInt! + """ + Transaction timestamp + """ + timestamp: BigInt! + """ + Day ID (timestamp / 86400) + """ + day: BigInt! + """ + Token in address from the swap + """ + tokenIn: Bytes! + """ + Token out address from the swap + """ + tokenOut: Bytes! + """ + Amount in from the swap + """ + amountIn: BigInt! + """ + Amount out from the swap + """ + amountOut: BigInt! + """ + User who initiated the swap + """ + user: Bytes! + """ + Block number + """ + blockNumber: BigInt! + """ + Transaction hash + """ + transactionHash: Bytes! +} + +scalar String + +""" +A string representation of microseconds UNIX timestamp (16 digits) +""" + +scalar Timestamp diff --git a/skills-lock.json b/skills-lock.json new file mode 100644 index 0000000..9b92c72 --- /dev/null +++ b/skills-lock.json @@ -0,0 +1,11 @@ +{ + "version": 1, + "skills": { + "gooddollar": { + "source": "GoodDollar/GoodSkills", + "sourceType": "github", + "skillPath": "skills/gooddollar/SKILL.md", + "computedHash": "d5f8cc5079f386e7170925e61214fb3334176aa6d0fc6bdc50400e535692b377" + } + } +} From 40370313502cc3828d03b4c2562c93d0dce4d3ac Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 27 May 2026 15:14:25 +0000 Subject: [PATCH 3/4] feat: scaffold and implement goodreserve swap widget package --- ARCHITECTURE.md | 2 + README.md | 2 + examples/storybook/package.json | 1 + .../src/fixtures/goodReserveWidgetMock.ts | 132 ++++++ .../GoodReserveWidget.stories.tsx | 84 ++++ packages/goodreserve-widget/package.json | 50 +++ .../src/GoodReserveWidget.tsx | 62 +++ .../src/ReserveSwapView.tsx | 231 ++++++++++ packages/goodreserve-widget/src/constants.ts | 16 + packages/goodreserve-widget/src/element.ts | 13 + packages/goodreserve-widget/src/errors.ts | 17 + packages/goodreserve-widget/src/index.ts | 17 + .../goodreserve-widget/src/integration.ts | 26 ++ packages/goodreserve-widget/src/register.ts | 13 + .../src/useGoodReserveAdapter.ts | 406 ++++++++++++++++++ .../src/widgetRuntimeContract.ts | 87 ++++ .../goodreserve-widget/tsconfig.build.json | 11 + packages/goodreserve-widget/tsconfig.json | 15 + packages/goodreserve-widget/tsup.config.ts | 15 + pnpm-lock.yaml | 37 ++ .../widgets/goodreserve-widget/states.spec.ts | 49 +++ 21 files changed, 1286 insertions(+) create mode 100644 examples/storybook/src/fixtures/goodReserveWidgetMock.ts create mode 100644 examples/storybook/src/stories/goodreserve-widget/GoodReserveWidget.stories.tsx create mode 100644 packages/goodreserve-widget/package.json create mode 100644 packages/goodreserve-widget/src/GoodReserveWidget.tsx create mode 100644 packages/goodreserve-widget/src/ReserveSwapView.tsx create mode 100644 packages/goodreserve-widget/src/constants.ts create mode 100644 packages/goodreserve-widget/src/element.ts create mode 100644 packages/goodreserve-widget/src/errors.ts create mode 100644 packages/goodreserve-widget/src/index.ts create mode 100644 packages/goodreserve-widget/src/integration.ts create mode 100644 packages/goodreserve-widget/src/register.ts create mode 100644 packages/goodreserve-widget/src/useGoodReserveAdapter.ts create mode 100644 packages/goodreserve-widget/src/widgetRuntimeContract.ts create mode 100644 packages/goodreserve-widget/tsconfig.build.json create mode 100644 packages/goodreserve-widget/tsconfig.json create mode 100644 packages/goodreserve-widget/tsup.config.ts create mode 100644 tests/widgets/goodreserve-widget/states.spec.ts diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md index a764d66..70f4bdd 100644 --- a/ARCHITECTURE.md +++ b/ARCHITECTURE.md @@ -41,6 +41,7 @@ GoodWidget/ ui/ # Tamagui tokens, preset, themes, config assembly, manifest, primitives embed/ # Web Component wrapper + CSS custom property bridge claim-widget/ # Example widget package using core + ui + embed + goodreserve-widget/ # Reserve swap widget package using core + ui + embed examples/ react-web/ # React web override and theming demo @@ -69,6 +70,7 @@ GoodWidget/ @goodwidget/embed @goodwidget/claim-widget -> depends on core + ui + embed +@goodwidget/goodreserve-widget -> depends on core + ui + embed ``` `@goodwidget/ui` is the leaf design-system package and must not depend on `@goodwidget/core`. diff --git a/README.md b/README.md index 1df7da8..ace9479 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,7 @@ A cross-platform mini app framework for building web3 widgets that run inside wa | `@goodwidget/ui` | Tamagui-based themeable component library (React + React Native Web) | | `@goodwidget/embed` | Web Component wrapper for embedding mini apps in any HTML page | | `@goodwidget/claim-widget` | Sample publishable widget — React component + Web Component | +| `@goodwidget/goodreserve-widget` | Reserve swap widget package (buy/sell flow on Celo/XDC) | ## Quick Start @@ -170,6 +171,7 @@ GoodWidget/ ui/ → @goodwidget/ui (component library, theme system) embed/ → @goodwidget/embed (Web Component wrapper) claim-widget/ → @goodwidget/claim-widget (sample publishable widget) + goodreserve-widget/ → @goodwidget/goodreserve-widget (reserve swap widget) examples/ react-web/ → React demo with style override showcase html/ → Plain HTML consuming a web component widget diff --git a/examples/storybook/package.json b/examples/storybook/package.json index 25373c9..a3d0d37 100644 --- a/examples/storybook/package.json +++ b/examples/storybook/package.json @@ -13,6 +13,7 @@ "@goodwidget/ui": "workspace:*", "@goodwidget/claim-widget-theme-demo": "workspace:*", "@goodwidget/citizen-claim-widget": "workspace:*", + "@goodwidget/goodreserve-widget": "workspace:*", "react": "^18.3.0", "react-dom": "^18.3.0", "react-native-web": "^0.19.13", diff --git a/examples/storybook/src/fixtures/goodReserveWidgetMock.ts b/examples/storybook/src/fixtures/goodReserveWidgetMock.ts new file mode 100644 index 0000000..3bcdf47 --- /dev/null +++ b/examples/storybook/src/fixtures/goodReserveWidgetMock.ts @@ -0,0 +1,132 @@ +import type { ReserveSwapWidgetAdapterState } from '@goodwidget/goodreserve-widget' + +// Deterministic reserve widget state fixtures used by Storybook and CI tests. +export const reserveWidgetMockStates: Record> = { + noProvider: { + status: 'no_provider', + hasProvider: false, + chainId: null, + address: null, + }, + unsupportedChain: { + status: 'unsupported_chain', + hasProvider: true, + chainId: 8453, + address: '0x1111111111111111111111111111111111111111', + }, + idleBuy: { + status: 'idle_buy', + chainId: 42220, + address: '0x1111111111111111111111111111111111111111', + hasProvider: true, + tokenInBalance: '120.00', + tokenOutBalance: '10340.22', + inputAmount: '', + direction: 'buy', + }, + amountEditing: { + status: 'amount_editing', + chainId: 42220, + hasProvider: true, + inputAmount: '25', + tokenInBalance: '120.00', + }, + quoteLoading: { + status: 'quote_loading', + chainId: 42220, + hasProvider: true, + inputAmount: '25', + tokenInBalance: '120.00', + }, + quoteReady: { + status: 'quote_ready', + chainId: 42220, + hasProvider: true, + inputAmount: '25', + tokenInBalance: '120.00', + quote: { + outputAmount: '108.2500', + price: '0.2310', + minimumReceived: '108.1417', + priceImpactPercent: '~0.01%', + exitContributionPercent: '0%', + }, + }, + quoteError: { + status: 'quote_error', + chainId: 42220, + hasProvider: true, + inputAmount: '25', + error: 'Reserve quote failed. Try again in a moment.', + }, + insufficientBalance: { + status: 'insufficient_balance', + chainId: 42220, + hasProvider: true, + inputAmount: '9999', + tokenInBalance: '120.00', + warning: 'Input exceeds your available token balance.', + }, + slippageSelection: { + status: 'slippage_selection', + chainId: 42220, + hasProvider: true, + slippagePercent: 0.5, + }, + confirmDialog: { + status: 'confirm_dialog', + chainId: 42220, + hasProvider: true, + inputAmount: '25', + quote: { + outputAmount: '108.2500', + price: '0.2310', + minimumReceived: '108.1417', + priceImpactPercent: '~0.01%', + exitContributionPercent: '0%', + }, + }, + swapPending: { + status: 'swap_pending', + chainId: 42220, + hasProvider: true, + inputAmount: '25', + quote: { + outputAmount: '108.2500', + price: '0.2310', + minimumReceived: '108.1417', + priceImpactPercent: '~0.01%', + exitContributionPercent: '0%', + }, + }, + swapSuccess: { + status: 'swap_success', + chainId: 42220, + hasProvider: true, + txHash: '0xabc123', + }, + swapError: { + status: 'swap_error', + chainId: 42220, + hasProvider: true, + error: 'Swap reverted due to reserve limits.', + }, + sellQuoteReady: { + status: 'quote_ready', + chainId: 42220, + hasProvider: true, + direction: 'sell', + tokenInSymbol: 'G$', + tokenOutSymbol: 'USDm', + tokenInBalance: '300.00', + tokenOutBalance: '84.00', + inputAmount: '40', + quote: { + outputAmount: '8.9231', + price: '4.4820', + minimumReceived: '8.9142', + priceImpactPercent: '~0.02%', + exitContributionPercent: '0%', + }, + }, +} diff --git a/examples/storybook/src/stories/goodreserve-widget/GoodReserveWidget.stories.tsx b/examples/storybook/src/stories/goodreserve-widget/GoodReserveWidget.stories.tsx new file mode 100644 index 0000000..79558c0 --- /dev/null +++ b/examples/storybook/src/stories/goodreserve-widget/GoodReserveWidget.stories.tsx @@ -0,0 +1,84 @@ +import React from 'react' +import type { Meta, StoryObj } from '@storybook/react' +import { GoodReserveWidget } from '@goodwidget/goodreserve-widget' +import { createCustodialEip1193Provider } from '../../fixtures/custodialEip1193' +import { reserveWidgetMockStates } from '../../fixtures/goodReserveWidgetMock' + +const provider = createCustodialEip1193Provider() + +const meta: Meta = { + title: 'Widgets/GoodReserveWidget', + component: GoodReserveWidget, + tags: ['autodocs'], + parameters: { layout: 'padded' }, +} + +export default meta +type Story = StoryObj + +// Renders one deterministic reserve state per story for CI-safe widget coverage. +const renderStory = (mockState: Story['args']['mockState'], dataTestId: string) => ( +
+ +
+) + +export const NoProvider: Story = { + render: () => renderStory(reserveWidgetMockStates.noProvider, 'GoodReserveWidget-no-provider'), +} + +export const UnsupportedChain: Story = { + render: () => + renderStory(reserveWidgetMockStates.unsupportedChain, 'GoodReserveWidget-unsupported-chain'), +} + +export const IdleBuy: Story = { + render: () => renderStory(reserveWidgetMockStates.idleBuy, 'GoodReserveWidget-idle-buy'), +} + +export const AmountEditing: Story = { + render: () => renderStory(reserveWidgetMockStates.amountEditing, 'GoodReserveWidget-amount-editing'), +} + +export const QuoteLoading: Story = { + render: () => renderStory(reserveWidgetMockStates.quoteLoading, 'GoodReserveWidget-quote-loading'), +} + +export const QuoteReadyBuy: Story = { + render: () => renderStory(reserveWidgetMockStates.quoteReady, 'GoodReserveWidget-quote-ready-buy'), +} + +export const QuoteReadySell: Story = { + render: () => + renderStory(reserveWidgetMockStates.sellQuoteReady, 'GoodReserveWidget-quote-ready-sell'), +} + +export const QuoteError: Story = { + render: () => renderStory(reserveWidgetMockStates.quoteError, 'GoodReserveWidget-quote-error'), +} + +export const InsufficientBalance: Story = { + render: () => + renderStory(reserveWidgetMockStates.insufficientBalance, 'GoodReserveWidget-insufficient-balance'), +} + +export const SlippageSelection: Story = { + render: () => + renderStory(reserveWidgetMockStates.slippageSelection, 'GoodReserveWidget-slippage-selection'), +} + +export const ConfirmDialog: Story = { + render: () => renderStory(reserveWidgetMockStates.confirmDialog, 'GoodReserveWidget-confirm-dialog'), +} + +export const SwapPending: Story = { + render: () => renderStory(reserveWidgetMockStates.swapPending, 'GoodReserveWidget-swap-pending'), +} + +export const SwapSuccess: Story = { + render: () => renderStory(reserveWidgetMockStates.swapSuccess, 'GoodReserveWidget-swap-success'), +} + +export const SwapError: Story = { + render: () => renderStory(reserveWidgetMockStates.swapError, 'GoodReserveWidget-swap-error'), +} diff --git a/packages/goodreserve-widget/package.json b/packages/goodreserve-widget/package.json new file mode 100644 index 0000000..87ebc21 --- /dev/null +++ b/packages/goodreserve-widget/package.json @@ -0,0 +1,50 @@ +{ + "name": "@goodwidget/goodreserve-widget", + "version": "0.1.0", + "description": "GoodReserve swap widget for GoodWidget", + "type": "module", + "main": "./dist/index.cjs", + "module": "./dist/index.js", + "types": "./dist/index.d.ts", + "exports": { + ".": { + "types": "./dist/index.d.ts", + "import": "./dist/index.js", + "require": "./dist/index.cjs" + }, + "./element": { + "types": "./dist/element.d.ts", + "import": "./dist/element.js", + "require": "./dist/element.cjs" + }, + "./register": { + "types": "./dist/register.d.ts", + "import": "./dist/register.js", + "require": "./dist/register.cjs" + } + }, + "scripts": { + "build": "tsup", + "dev": "tsup --watch", + "lint": "eslint src/", + "clean": "rm -rf dist .turbo" + }, + "peerDependencies": { + "react": ">=18.0.0", + "react-dom": ">=18.0.0" + }, + "dependencies": { + "@goodwidget/core": "workspace:*", + "@goodwidget/embed": "workspace:*", + "@goodwidget/ui": "workspace:*", + "viem": "^2.0.0" + }, + "devDependencies": { + "@types/react": "^18.3.0", + "@types/react-dom": "^18.3.0", + "react": "^18.3.0", + "react-dom": "^18.3.0", + "tsup": "^8.4.0", + "typescript": "^5.7.0" + } +} diff --git a/packages/goodreserve-widget/src/GoodReserveWidget.tsx b/packages/goodreserve-widget/src/GoodReserveWidget.tsx new file mode 100644 index 0000000..a0473e8 --- /dev/null +++ b/packages/goodreserve-widget/src/GoodReserveWidget.tsx @@ -0,0 +1,62 @@ +import React, { useEffect } from 'react' +import { GoodWidgetProvider } from '@goodwidget/core' +import type { EIP1193Provider } from '@goodwidget/core' +import { ReserveSwapView } from './ReserveSwapView' +import { useGoodReserveAdapter } from './useGoodReserveAdapter' +import type { ReserveSwapWidgetProps } from './widgetRuntimeContract' + +function GoodReserveWidgetInner({ + onSwapSuccess, + onSwapError, + mockState, +}: Pick) { + const adapter = useGoodReserveAdapter(mockState) + + // Emits swap lifecycle callbacks for host integrations. + useEffect(() => { + if (adapter.state.status === 'swap_success' && adapter.state.txHash) { + onSwapSuccess?.({ + address: adapter.state.address, + chainId: adapter.state.chainId, + transactionHash: adapter.state.txHash, + }) + return + } + + if (adapter.state.status === 'swap_error' && adapter.state.error) { + onSwapError?.({ + address: adapter.state.address, + chainId: adapter.state.chainId, + message: adapter.state.error, + }) + } + }, [adapter.state, onSwapError, onSwapSuccess]) + + return +} + +// Public widget entry wired to GoodWidget runtime context + theming contract. +export function GoodReserveWidget({ + provider, + config, + themeOverrides, + defaultTheme = 'dark', + onSwapSuccess, + onSwapError, + mockState, +}: ReserveSwapWidgetProps) { + return ( + + + + ) +} diff --git a/packages/goodreserve-widget/src/ReserveSwapView.tsx b/packages/goodreserve-widget/src/ReserveSwapView.tsx new file mode 100644 index 0000000..d19ec0e --- /dev/null +++ b/packages/goodreserve-widget/src/ReserveSwapView.tsx @@ -0,0 +1,231 @@ +import React from 'react' +import { + Button, + ButtonText, + Card, + Heading, + Input, + Text, + XStack, + YStack, + createComponent, +} from '@goodwidget/ui' +import type { ReserveSwapWidgetAdapterResult } from './widgetRuntimeContract' +import { CELO_CHAIN_ID } from './constants' + +const SwapShell = createComponent(Card, { + name: 'ReserveSwapShell', + extends: 'Card', + padding: '$4', + gap: '$3', + borderRadius: '$4', +}) + +const AmountCard = createComponent(Card, { + name: 'ReserveAmountCard', + extends: 'Card', + padding: '$3', + gap: '$2', + borderRadius: '$3', +}) + +interface ReserveSwapViewProps { + adapter: ReserveSwapWidgetAdapterResult +} + +// Renders the reserve swap states with GoodWalletV2-like structure for amount cards and CTA. +export function ReserveSwapView({ adapter }: ReserveSwapViewProps) { + const { state, actions } = adapter + + const ctaDisabled = + state.status === 'quote_loading' || + state.status === 'swap_pending' || + state.status === 'insufficient_balance' || + !state.inputAmount || + !state.quote + + const ctaLabel = + state.status === 'swap_pending' + ? 'Swapping...' + : state.status === 'unsupported_chain' + ? 'Switch Network' + : state.status === 'no_provider' + ? 'Connect Wallet' + : 'Review Swap' + + return ( + + + + GoodReserve + + Swap on {state.chainId === CELO_CHAIN_ID ? 'CELO' : 'XDC'} + + Swap on CELO + + Buy or sell GoodDollars using the reserve. Review quote, slippage, and liquidity before + confirming. + + + + + + + + + + + + Swap from + + + + {state.tokenInSymbol} + Balance: {state.tokenInBalance} + + + + + + Swap to + + {state.tokenOutSymbol} + {state.quote?.outputAmount ?? '0.00'} + + + + + + + Slippage tolerance + + {state.slippagePercent}% + + + + Price + + {state.quote?.price ?? '0.00000'} G$ per {state.tokenInSymbol} + + + + Price impact + + {state.quote?.priceImpactPercent ?? '~0.00%'} + + + + Exit contribution + + {state.quote?.exitContributionPercent ?? '0%'} + + + + Minimum received + + {state.quote?.minimumReceived ?? '0.00'} {state.tokenOutSymbol} + + + + {state.warning && ( + + {state.warning} + + )} + + {state.error && ( + + {state.error} + + )} + + {state.status === 'swap_success' && state.txHash && ( + + Swap succeeded. Tx: {state.txHash} + + )} + + {state.status === 'slippage_selection' && ( + + {[0.1, 0.5, 1].map((option) => ( + + ))} + + + )} + + {state.status === 'confirm_dialog' && ( + + + Confirm Swap + + {state.inputAmount} {state.tokenInSymbol} → {state.quote?.outputAmount ?? '0.00'}{' '} + {state.tokenOutSymbol} + + + + + + + + )} + + + + + + + FAQ + What is USDm? A stable token used as reserve collateral on Celo. + + + + ) +} diff --git a/packages/goodreserve-widget/src/constants.ts b/packages/goodreserve-widget/src/constants.ts new file mode 100644 index 0000000..bf56c18 --- /dev/null +++ b/packages/goodreserve-widget/src/constants.ts @@ -0,0 +1,16 @@ +// Supported reserve chains for this widget. +export const CELO_CHAIN_ID = 42220 +export const XDC_CHAIN_ID = 50 + +// Stable token decimals and G$ decimals used by reserve quotes. +export const DEFAULT_STABLE_DECIMALS = 18 +export const DEFAULT_GD_DECIMALS = 2 + +// Debounce used for quote requests while user edits amount. +export const QUOTE_DEBOUNCE_MS = 400 + +// Default slippage persisted in widget-local state. +export const DEFAULT_SLIPPAGE_PERCENT = 0.1 + +// Reserve chain guard list. +export const SUPPORTED_RESERVE_CHAINS = [CELO_CHAIN_ID, XDC_CHAIN_ID] as const diff --git a/packages/goodreserve-widget/src/element.ts b/packages/goodreserve-widget/src/element.ts new file mode 100644 index 0000000..0c00469 --- /dev/null +++ b/packages/goodreserve-widget/src/element.ts @@ -0,0 +1,13 @@ +import { createMiniAppElement } from '@goodwidget/embed' +import type React from 'react' +import { GoodReserveWidget } from './GoodReserveWidget' + +// Custom element wrapper for HTML hosts embedding the reserve widget. +export const GoodReserveWidgetElement = createMiniAppElement( + GoodReserveWidget as React.ComponentType>, + { + shadow: true, + defaultTheme: 'dark', + events: ['swap-success', 'swap-error'], + }, +) diff --git a/packages/goodreserve-widget/src/errors.ts b/packages/goodreserve-widget/src/errors.ts new file mode 100644 index 0000000..79c2325 --- /dev/null +++ b/packages/goodreserve-widget/src/errors.ts @@ -0,0 +1,17 @@ +// Converts low-level reserve/viem errors into concise user-facing messages. +export function mapReserveError(err: unknown, fallback: string): string { + const message = err instanceof Error ? err.message : String(err ?? fallback) + const lower = message.toLowerCase() + + if (lower.includes('user rejected')) return 'Transaction canceled in wallet.' + if (lower.includes('insufficient funds')) return 'Insufficient funds for token amount or gas.' + if (lower.includes('allowance')) return 'Insufficient allowance. Approve and try again.' + if (lower.includes('slippage')) return 'Slippage too high. Increase tolerance or reduce trade size.' + if (lower.includes('revert')) return 'Quote or swap reverted on-chain. Try a smaller amount.' + if (lower.includes('unsupported chain')) return 'Switch to Celo or XDC to continue.' + if (lower.includes('cannot find package') || lower.includes('module not found')) { + return 'GoodReserve SDK package is unavailable in this environment.' + } + + return message || fallback +} diff --git a/packages/goodreserve-widget/src/index.ts b/packages/goodreserve-widget/src/index.ts new file mode 100644 index 0000000..a84a38d --- /dev/null +++ b/packages/goodreserve-widget/src/index.ts @@ -0,0 +1,17 @@ +export { goodReserveWidgetIntegration } from './integration' +export type { GoodReserveWidgetIntegration } from './integration' + +export type { + ReserveSwapDirection, + ReserveSwapQuoteView, + ReserveSwapWidgetStatus, + ReserveSwapWidgetAdapterState, + ReserveSwapWidgetAdapterActions, + ReserveSwapWidgetAdapterResult, + ReserveSwapWidgetProps, + ReserveSwapSuccessDetail, + ReserveSwapErrorDetail, +} from './widgetRuntimeContract' + +export { useGoodReserveAdapter } from './useGoodReserveAdapter' +export { GoodReserveWidget } from './GoodReserveWidget' diff --git a/packages/goodreserve-widget/src/integration.ts b/packages/goodreserve-widget/src/integration.ts new file mode 100644 index 0000000..4e07225 --- /dev/null +++ b/packages/goodreserve-widget/src/integration.ts @@ -0,0 +1,26 @@ +export const goodReserveWidgetIntegration = { + id: 'goodreserve-swap', + sdk: '@goodsdks/good-reserve', + capabilitySource: 'goodReserveSdkCapabilities', + uses: ['getBuyQuote', 'getSellQuote', 'buy', 'sell', 'getReserveStats'], + chains: [42220, 50], + states: [ + 'no_provider', + 'unsupported_chain', + 'sdk_initializing', + 'idle_buy', + 'amount_editing', + 'quote_loading', + 'quote_ready', + 'quote_error', + 'insufficient_balance', + 'slippage_selection', + 'confirm_dialog', + 'swap_pending', + 'swap_success', + 'swap_error', + ], + events: ['swap-success', 'swap-error'], +} as const + +export type GoodReserveWidgetIntegration = typeof goodReserveWidgetIntegration diff --git a/packages/goodreserve-widget/src/register.ts b/packages/goodreserve-widget/src/register.ts new file mode 100644 index 0000000..8cc54fc --- /dev/null +++ b/packages/goodreserve-widget/src/register.ts @@ -0,0 +1,13 @@ +import { GoodReserveWidgetElement } from './element' + +const DEFAULT_TAG_NAME = 'gw-goodreserve-widget' + +// Registers the reserve widget custom element for non-React hosts. +export function register(tagName: string = DEFAULT_TAG_NAME): string { + if (!customElements.get(tagName)) { + customElements.define(tagName, GoodReserveWidgetElement) + } + return tagName +} + +register() diff --git a/packages/goodreserve-widget/src/useGoodReserveAdapter.ts b/packages/goodreserve-widget/src/useGoodReserveAdapter.ts new file mode 100644 index 0000000..3b09e70 --- /dev/null +++ b/packages/goodreserve-widget/src/useGoodReserveAdapter.ts @@ -0,0 +1,406 @@ +import { useCallback, useEffect, useMemo, useRef, useState } from 'react' +import { useWallet } from '@goodwidget/core' +import { createPublicClient, createWalletClient, custom, formatUnits, parseUnits } from 'viem' +import type { + ReserveSwapDirection, + ReserveSwapWidgetAdapterResult, + ReserveSwapWidgetAdapterState, +} from './widgetRuntimeContract' +import { + DEFAULT_GD_DECIMALS, + DEFAULT_SLIPPAGE_PERCENT, + DEFAULT_STABLE_DECIMALS, + QUOTE_DEBOUNCE_MS, + SUPPORTED_RESERVE_CHAINS, + XDC_CHAIN_ID, +} from './constants' +import { mapReserveError } from './errors' + +type GoodReserveSDKLike = { + getStableTokenAddress: () => `0x${string}` + getGoodDollarAddress: () => `0x${string}` + getReserveStats: () => Promise<{ + stableTokenDecimals?: number + goodDollarDecimals?: number + exitContribution?: number | null + }> + getBuyQuote: (stableToken: `0x${string}`, amountIn: bigint) => Promise + getSellQuote: (gdAmount: bigint, stableToken: `0x${string}`) => Promise + buy: ( + stableToken: `0x${string}`, + amountIn: bigint, + minReturn: bigint, + ) => Promise<{ receipt: { transactionHash: string } }> + sell: ( + stableToken: `0x${string}`, + amountIn: bigint, + minReturn: bigint, + ) => Promise<{ receipt: { transactionHash: string } }> +} + +type GoodReserveSDKConstructor = new ( + publicClient: unknown, + walletClient: unknown, + env: 'production' | 'development', +) => GoodReserveSDKLike + +type Erc20ReadClient = { + readContract: (params: { + address: `0x${string}` + abi: readonly unknown[] + functionName: 'balanceOf' + args: [`0x${string}`] + }) => Promise +} + +const erc20BalanceOfAbi = [ + { + type: 'function', + stateMutability: 'view', + name: 'balanceOf', + inputs: [{ name: 'account', type: 'address' }], + outputs: [{ name: '', type: 'uint256' }], + }, +] as const + +// Loads the SDK module dynamically so workspace builds still run if the SDK package is missing. +async function loadGoodReserveSdkConstructor(): Promise< + GoodReserveSDKConstructor | null +> { + try { + const importer = new Function('moduleName', 'return import(moduleName)') as ( + moduleName: string, + ) => Promise> + const module = await importer('@goodsdks/good-reserve') + const ctor = module.GoodReserveSDK + if (typeof ctor !== 'function') return null + return ctor as GoodReserveSDKConstructor + } catch { + return null + } +} + +const initialState: ReserveSwapWidgetAdapterState = { + status: 'no_provider', + chainId: null, + address: null, + hasProvider: false, + direction: 'buy', + inputAmount: '', + slippagePercent: DEFAULT_SLIPPAGE_PERCENT, + tokenInSymbol: 'USDm', + tokenOutSymbol: 'G$', + tokenInBalance: '0.00', + tokenOutBalance: '0.00', + quote: null, + warning: null, + error: null, + txHash: null, +} + +function getStableSymbol(chainId: number | null): string { + return chainId === XDC_CHAIN_ID ? 'USDC' : 'USDm' +} + +export function useGoodReserveAdapter( + mockState?: Partial, +): ReserveSwapWidgetAdapterResult { + const { address, chainId, isConnected, provider, connect } = useWallet() + + const [state, setState] = useState({ + ...initialState, + ...mockState, + }) + + const sdkRef = useRef(null) + const readClientRef = useRef(null) + const decimalsRef = useRef({ stable: DEFAULT_STABLE_DECIMALS, gd: DEFAULT_GD_DECIMALS }) + const mountedRef = useRef(true) + + useEffect(() => { + mountedRef.current = true + return () => { + mountedRef.current = false + } + }, []) + + const applyStatePatch = useCallback((patch: Partial) => { + if (!mountedRef.current) return + setState((current) => ({ ...current, ...patch })) + }, []) + + const chainSupported = chainId !== null && SUPPORTED_RESERVE_CHAINS.includes(chainId as never) + + const reserveEnvironment = chainId === XDC_CHAIN_ID ? 'development' : 'production' + + const refreshBalances = useCallback(async () => { + if (!address || !sdkRef.current || !readClientRef.current) return + + const stableToken = sdkRef.current.getStableTokenAddress() + const gdToken = sdkRef.current.getGoodDollarAddress() + const [stable, gd] = await Promise.all([ + readClientRef.current.readContract({ + address: stableToken, + abi: erc20BalanceOfAbi, + functionName: 'balanceOf', + args: [address as `0x${string}`], + }), + readClientRef.current.readContract({ + address: gdToken, + abi: erc20BalanceOfAbi, + functionName: 'balanceOf', + args: [address as `0x${string}`], + }), + ]) + + applyStatePatch({ + tokenInBalance: formatUnits(stable, decimalsRef.current.stable), + tokenOutBalance: formatUnits(gd, decimalsRef.current.gd), + }) + }, [address, applyStatePatch]) + + const bootstrapSdk = useCallback(async () => { + if (!provider || !address || !chainId || !chainSupported) return + + applyStatePatch({ status: 'sdk_initializing', hasProvider: true, error: null }) + + const constructor = await loadGoodReserveSdkConstructor() + if (!constructor) { + applyStatePatch({ + status: 'quote_error', + error: + 'GoodReserve SDK is not available in this environment. Install @goodsdks/good-reserve to enable live swaps.', + }) + return + } + + try { + const transport = custom(provider as Parameters[0]) + const publicClient = createPublicClient({ transport }) + const walletClient = createWalletClient({ + account: address as `0x${string}`, + transport, + }) + + const sdk = new constructor(publicClient, walletClient, reserveEnvironment) + const stats = await sdk.getReserveStats() + + sdkRef.current = sdk + readClientRef.current = publicClient as unknown as Erc20ReadClient + decimalsRef.current = { + stable: stats.stableTokenDecimals ?? DEFAULT_STABLE_DECIMALS, + gd: stats.goodDollarDecimals ?? DEFAULT_GD_DECIMALS, + } + + await refreshBalances() + applyStatePatch({ + status: 'idle_buy', + tokenInSymbol: getStableSymbol(chainId), + tokenOutSymbol: 'G$', + warning: null, + error: null, + }) + } catch (err: unknown) { + applyStatePatch({ + status: 'quote_error', + error: mapReserveError(err, 'Failed to initialize GoodReserve SDK.'), + }) + } + }, [address, applyStatePatch, chainId, chainSupported, provider, refreshBalances, reserveEnvironment]) + + useEffect(() => { + if (mockState) return + + if (!provider || !isConnected || !address) { + sdkRef.current = null + readClientRef.current = null + applyStatePatch({ + ...initialState, + status: 'no_provider', + hasProvider: Boolean(provider), + }) + return + } + + applyStatePatch({ address, chainId, hasProvider: true }) + + if (!chainSupported) { + applyStatePatch({ status: 'unsupported_chain', error: null }) + return + } + + void bootstrapSdk() + }, [address, applyStatePatch, bootstrapSdk, chainId, chainSupported, isConnected, mockState, provider]) + + useEffect(() => { + if (mockState || !sdkRef.current) return + if (!state.inputAmount) { + applyStatePatch({ quote: null, warning: null, error: null, status: 'idle_buy' }) + return + } + + const amount = Number(state.inputAmount) + if (!Number.isFinite(amount) || amount <= 0) { + applyStatePatch({ quote: null, status: 'amount_editing' }) + return + } + + const timeoutId = window.setTimeout(async () => { + try { + const inputBalance = Number(state.tokenInBalance) + if (Number.isFinite(inputBalance) && amount > inputBalance) { + applyStatePatch({ + status: 'insufficient_balance', + warning: 'Input exceeds your available token balance.', + quote: null, + error: null, + }) + return + } + + applyStatePatch({ status: 'quote_loading', warning: null, error: null }) + const stableToken = sdkRef.current!.getStableTokenAddress() + const input = parseUnits( + state.inputAmount, + state.direction === 'buy' ? decimalsRef.current.stable : decimalsRef.current.gd, + ) + const output = + state.direction === 'buy' + ? await sdkRef.current!.getBuyQuote(stableToken, input) + : await sdkRef.current!.getSellQuote(input, stableToken) + + const outputFormatted = formatUnits( + output, + state.direction === 'buy' ? decimalsRef.current.gd : decimalsRef.current.stable, + ) + + applyStatePatch({ + status: 'quote_ready', + quote: { + outputAmount: outputFormatted, + price: output === 0n ? '0.00000' : (amount / Number(outputFormatted || '1')).toFixed(5), + minimumReceived: (Number(outputFormatted) * (1 - state.slippagePercent / 100)).toFixed(4), + priceImpactPercent: '~0.01%', + exitContributionPercent: '0%', + }, + error: null, + }) + } catch (err: unknown) { + applyStatePatch({ + status: 'quote_error', + quote: null, + error: mapReserveError(err, 'Failed to fetch reserve quote.'), + }) + } + }, QUOTE_DEBOUNCE_MS) + + return () => window.clearTimeout(timeoutId) + }, [applyStatePatch, mockState, state.direction, state.inputAmount, state.slippagePercent, state.tokenInBalance]) + + const actions = useMemo( + () => ({ + connect: async () => { + await connect() + }, + switchChain: async (targetChainId: number) => { + const walletProvider = provider as + | { request?: (args: { method: string; params?: unknown[] }) => Promise } + | undefined + if (!walletProvider?.request) return + await walletProvider.request({ + method: 'wallet_switchEthereumChain', + params: [{ chainId: `0x${targetChainId.toString(16)}` }], + }) + }, + setDirection: (direction: ReserveSwapDirection) => { + const stableSymbol = getStableSymbol(chainId) + applyStatePatch({ + direction, + tokenInSymbol: direction === 'buy' ? stableSymbol : 'G$', + tokenOutSymbol: direction === 'buy' ? 'G$' : stableSymbol, + inputAmount: '', + quote: null, + status: direction === 'buy' ? 'idle_buy' : 'amount_editing', + error: null, + warning: null, + }) + }, + setInputAmount: (value: string) => { + applyStatePatch({ inputAmount: value, status: value ? 'amount_editing' : 'idle_buy' }) + }, + setMaxAmount: () => { + applyStatePatch({ inputAmount: state.tokenInBalance, status: 'amount_editing' }) + }, + setSlippagePercent: (value: number) => { + applyStatePatch({ slippagePercent: value, status: 'idle_buy' }) + }, + openSlippage: () => { + applyStatePatch({ status: 'slippage_selection' }) + }, + closeSlippage: () => { + applyStatePatch({ status: state.quote ? 'quote_ready' : 'idle_buy' }) + }, + openConfirm: () => { + applyStatePatch({ status: 'confirm_dialog' }) + }, + closeConfirm: () => { + applyStatePatch({ status: state.quote ? 'quote_ready' : 'idle_buy' }) + }, + executeSwap: async () => { + if (!sdkRef.current || !state.quote || !state.inputAmount) return + try { + applyStatePatch({ status: 'swap_pending', error: null }) + const stableToken = sdkRef.current.getStableTokenAddress() + const amountIn = parseUnits( + state.inputAmount, + state.direction === 'buy' ? decimalsRef.current.stable : decimalsRef.current.gd, + ) + const quoteOut = parseUnits( + state.quote.outputAmount, + state.direction === 'buy' ? decimalsRef.current.gd : decimalsRef.current.stable, + ) + const slippageBps = BigInt(Math.round(state.slippagePercent * 100)) + const minReturn = (quoteOut * (10_000n - slippageBps)) / 10_000n + + const result = + state.direction === 'buy' + ? await sdkRef.current.buy(stableToken, amountIn, minReturn) + : await sdkRef.current.sell(stableToken, amountIn, minReturn) + + await refreshBalances() + applyStatePatch({ + status: 'swap_success', + txHash: result.receipt.transactionHash, + inputAmount: '', + quote: null, + }) + } catch (err: unknown) { + applyStatePatch({ + status: 'swap_error', + error: mapReserveError(err, 'Swap failed.'), + }) + } + }, + refresh: async () => { + if (mockState) return + await bootstrapSdk() + }, + }), + [ + applyStatePatch, + bootstrapSdk, + connect, + mockState, + provider, + refreshBalances, + state.direction, + state.inputAmount, + state.quote, + state.slippagePercent, + state.tokenInBalance, + chainId, + ], + ) + + return { state: { ...state, ...(mockState ?? {}) }, actions } +} diff --git a/packages/goodreserve-widget/src/widgetRuntimeContract.ts b/packages/goodreserve-widget/src/widgetRuntimeContract.ts new file mode 100644 index 0000000..4abe3f4 --- /dev/null +++ b/packages/goodreserve-widget/src/widgetRuntimeContract.ts @@ -0,0 +1,87 @@ +import type { GoodWidgetConfig, GoodWidgetThemeOverrides } from '@goodwidget/ui' + +export type ReserveSwapDirection = 'buy' | 'sell' + +export type ReserveSwapWidgetStatus = + | 'no_provider' + | 'unsupported_chain' + | 'sdk_initializing' + | 'idle_buy' + | 'amount_editing' + | 'quote_loading' + | 'quote_ready' + | 'quote_error' + | 'insufficient_balance' + | 'slippage_selection' + | 'confirm_dialog' + | 'swap_pending' + | 'swap_success' + | 'swap_error' + +export interface ReserveSwapQuoteView { + outputAmount: string + price: string + minimumReceived: string + priceImpactPercent: string + exitContributionPercent: string +} + +export interface ReserveSwapWidgetAdapterState { + status: ReserveSwapWidgetStatus + chainId: number | null + address: string | null + hasProvider: boolean + direction: ReserveSwapDirection + inputAmount: string + slippagePercent: number + tokenInSymbol: string + tokenOutSymbol: string + tokenInBalance: string + tokenOutBalance: string + quote: ReserveSwapQuoteView | null + warning: string | null + error: string | null + txHash: string | null +} + +export interface ReserveSwapWidgetAdapterActions { + connect: () => Promise + switchChain: (chainId: number) => Promise + setDirection: (direction: ReserveSwapDirection) => void + setInputAmount: (value: string) => void + setMaxAmount: () => void + setSlippagePercent: (value: number) => void + openSlippage: () => void + closeSlippage: () => void + openConfirm: () => void + closeConfirm: () => void + executeSwap: () => Promise + refresh: () => Promise +} + +export interface ReserveSwapWidgetAdapterResult { + state: ReserveSwapWidgetAdapterState + actions: ReserveSwapWidgetAdapterActions +} + +export interface ReserveSwapSuccessDetail { + address: string | null + chainId: number | null + transactionHash: string +} + +export interface ReserveSwapErrorDetail { + address: string | null + chainId: number | null + message: string +} + +export interface ReserveSwapWidgetProps { + provider?: unknown + config?: GoodWidgetConfig + themeOverrides?: GoodWidgetThemeOverrides + defaultTheme?: 'light' | 'dark' + onSwapSuccess?: (detail: ReserveSwapSuccessDetail) => void + onSwapError?: (detail: ReserveSwapErrorDetail) => void + mockState?: Partial +} diff --git a/packages/goodreserve-widget/tsconfig.build.json b/packages/goodreserve-widget/tsconfig.build.json new file mode 100644 index 0000000..54871c4 --- /dev/null +++ b/packages/goodreserve-widget/tsconfig.build.json @@ -0,0 +1,11 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "outDir": "dist", + "rootDir": "src", + "paths": { + "react-native": ["./node_modules/react-native-web"] + } + }, + "include": ["src"] +} diff --git a/packages/goodreserve-widget/tsconfig.json b/packages/goodreserve-widget/tsconfig.json new file mode 100644 index 0000000..66f66cf --- /dev/null +++ b/packages/goodreserve-widget/tsconfig.json @@ -0,0 +1,15 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "outDir": "dist", + "rootDir": "src", + "paths": { + "@goodwidget/core": ["../core/src/index.ts"], + "@goodwidget/core/*": ["../core/src/*"], + "@goodwidget/ui": ["../ui/src/index.ts"], + "@goodwidget/embed": ["../embed/src/index.ts"], + "react-native": ["./node_modules/react-native-web"] + } + }, + "include": ["src"] +} diff --git a/packages/goodreserve-widget/tsup.config.ts b/packages/goodreserve-widget/tsup.config.ts new file mode 100644 index 0000000..95c2de0 --- /dev/null +++ b/packages/goodreserve-widget/tsup.config.ts @@ -0,0 +1,15 @@ +import { defineConfig } from 'tsup' + +export default defineConfig({ + entry: { + index: 'src/index.ts', + element: 'src/element.ts', + register: 'src/register.ts', + }, + format: ['esm', 'cjs'], + dts: true, + sourcemap: true, + clean: true, + tsconfig: 'tsconfig.build.json', + external: ['react', 'react-dom', 'react-native', 'react-native-web'], +}) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 04afa8b..faff95f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -170,6 +170,9 @@ importers: '@goodwidget/core': specifier: workspace:* version: link:../../packages/core + '@goodwidget/goodreserve-widget': + specifier: workspace:* + version: link:../../packages/goodreserve-widget '@goodwidget/ui': specifier: workspace:* version: link:../../packages/ui @@ -344,6 +347,40 @@ importers: specifier: ^5.7.0 version: 5.9.3 + packages/goodreserve-widget: + dependencies: + '@goodwidget/core': + specifier: workspace:* + version: link:../core + '@goodwidget/embed': + specifier: workspace:* + version: link:../embed + '@goodwidget/ui': + specifier: workspace:* + version: link:../ui + viem: + specifier: ^2.0.0 + version: 2.48.4(typescript@5.9.3) + devDependencies: + '@types/react': + specifier: ^18.3.0 + version: 18.3.28 + '@types/react-dom': + specifier: ^18.3.0 + version: 18.3.7(@types/react@18.3.28) + react: + specifier: ^18.3.0 + version: 18.3.1 + react-dom: + specifier: ^18.3.0 + version: 18.3.1(react@18.3.1) + tsup: + specifier: ^8.4.0 + version: 8.5.1(@swc/core@1.15.30)(postcss@8.5.8)(typescript@5.9.3)(yaml@2.8.3) + typescript: + specifier: ^5.7.0 + version: 5.9.3 + packages/ui: dependencies: '@tamagui/animations-react-native': diff --git a/tests/widgets/goodreserve-widget/states.spec.ts b/tests/widgets/goodreserve-widget/states.spec.ts new file mode 100644 index 0000000..95b03ef --- /dev/null +++ b/tests/widgets/goodreserve-widget/states.spec.ts @@ -0,0 +1,49 @@ +import { expect, test, type Page } from '@playwright/test' + +async function gotoStory(page: Page, storyId: string): Promise { + await page.goto(`/?path=/story/${storyId}`) + await page.waitForSelector('#storybook-preview-iframe', { timeout: 30_000 }) + await page.waitForLoadState('networkidle') +} + +async function frame(page: Page) { + return page.frameLocator('#storybook-preview-iframe') +} + +// Covers deterministic reserve states so CI does not require live reserve RPC calls. +test('GoodReserveWidget no provider state renders connect CTA', async ({ page }) => { + await gotoStory(page, 'widgets-goodreservewidget--no-provider') + const storyFrame = await frame(page) + await expect(storyFrame.getByTestId('GoodReserveWidget-no-provider')).toBeVisible() + await expect(storyFrame.getByText('Connect Wallet')).toBeVisible() +}) + +test('GoodReserveWidget unsupported chain state renders switch CTA', async ({ page }) => { + await gotoStory(page, 'widgets-goodreservewidget--unsupported-chain') + const storyFrame = await frame(page) + await expect(storyFrame.getByText('Switch Network')).toBeVisible() +}) + +test('GoodReserveWidget quote-ready buy/sell stories render quoted output', async ({ page }) => { + await gotoStory(page, 'widgets-goodreservewidget--quote-ready-buy') + let storyFrame = await frame(page) + await expect(storyFrame.getByText('108.2500')).toBeVisible() + + await gotoStory(page, 'widgets-goodreservewidget--quote-ready-sell') + storyFrame = await frame(page) + await expect(storyFrame.getByText('8.9231')).toBeVisible() +}) + +test('GoodReserveWidget transaction states render pending/success/error', async ({ page }) => { + await gotoStory(page, 'widgets-goodreservewidget--swap-pending') + let storyFrame = await frame(page) + await expect(storyFrame.getByText('Swapping...')).toBeVisible() + + await gotoStory(page, 'widgets-goodreservewidget--swap-success') + storyFrame = await frame(page) + await expect(storyFrame.getByTestId('GoodReserveWidget-success')).toContainText('Swap succeeded') + + await gotoStory(page, 'widgets-goodreservewidget--swap-error') + storyFrame = await frame(page) + await expect(storyFrame.getByTestId('GoodReserveWidget-error')).toContainText('Swap reverted') +}) From f31eb12b5f1e4828884007030cbd72359e4f4c59 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 28 May 2026 10:52:43 +0000 Subject: [PATCH 4/4] chore: remove skills artifacts and add goodreserve story screenshots --- .agents/skills/gooddollar/CONTRIBUTING.md | 121 -- .agents/skills/gooddollar/SKILL.md | 215 ---- .../contracts/BuyGDCloneFactory.abi.yaml | 205 ---- .../BuyGDCloneFactory.selectors.yaml | 27 - .../contracts/BuyGDCloneV2.abi.yaml | 282 ----- .../contracts/BuyGDCloneV2.selectors.yaml | 36 - .../contracts/CFAv1Forwarder.abi.yaml | 237 ---- .../contracts/CFAv1Forwarder.selectors.yaml | 19 - .../ConstantFlowAgreementV1.abi.yaml | 560 --------- .../ConstantFlowAgreementV1.selectors.yaml | 33 - .../contracts/GoodDollarOFTAdapter.abi.yaml | 100 -- .../GoodDollarOFTAdapter.selectors.yaml | 12 - .../GooddollarSavingsStream.abi.yaml | 210 ---- .../GooddollarSavingsStream.selectors.yaml | 27 - .../contracts/GovernanceStakingV2.abi.yaml | 202 ---- .../GovernanceStakingV2.selectors.yaml | 26 - .../references/contracts/IdentityV3.abi.yaml | 390 ------- .../contracts/IdentityV3.selectors.yaml | 49 - .../references/contracts/IdentityV4.abi.yaml | 424 ------- .../contracts/IdentityV4.selectors.yaml | 51 - .../references/contracts/InvitesV2.abi.yaml | 333 ------ .../contracts/InvitesV2.selectors.yaml | 41 - .../references/contracts/MentoBroker.abi.yaml | 259 ----- .../contracts/MentoBroker.selectors.yaml | 24 - .../contracts/MessagePassingBridge.abi.yaml | 542 --------- .../MessagePassingBridge.selectors.yaml | 52 - .../references/contracts/NameService.abi.yaml | 104 -- .../contracts/NameService.selectors.yaml | 11 - .../references/contracts/SuperToken.abi.yaml | 1033 ----------------- .../contracts/SuperToken.selectors.yaml | 99 -- .../references/contracts/Superfluid.abi.yaml | 757 ------------ .../contracts/Superfluid.selectors.yaml | 51 - .../references/contracts/UBISchemeV2.abi.yaml | 305 ----- .../contracts/UBISchemeV2.selectors.yaml | 40 - .../contracts/_rich-abi-yaml-format.md | 93 -- .../deep-researches/faucet-flows.md | 42 - .../fuse-to-celo-staking-migration.md | 38 - .../gooddao-daostack-surface.md | 37 - .../deep-researches/how-ubi-is-minted.md | 68 -- .../inviter-invitee-reward-model.md | 58 - .../mento-reserve-economics.md | 27 - .../deep-researches/on-off-ramp-service.md | 69 -- .../gooddollar/references/guides/bridge.md | 187 --- .../references/guides/check-identity.md | 87 -- .../gooddollar/references/guides/claim.md | 83 -- .../gooddollar/references/guides/faucet.md | 76 -- .../gooddollar/references/guides/gooddocs.md | 37 - .../gooddollar/references/guides/goodsdks.md | 110 -- .../references/guides/hypersync-hyperrpc.md | 110 -- .../references/guides/invite-bounties.md | 115 -- .../migrate-fuse-staking-to-celo-savings.md | 116 -- .../references/guides/on-off-ramp.md | 77 -- .../gooddollar/references/guides/save.md | 93 -- .../gooddollar/references/guides/stream.md | 135 --- .../gooddollar/references/guides/swap.md | 83 -- .../references/subgraphs/_query-patterns.md | 35 - .../subgraphs/goodcollective-guide.md | 54 - .../subgraphs/goodcollective.graphql | 200 ---- .../subgraphs/gooddollar-celo-guide.md | 104 -- .../subgraphs/gooddollar-celo.graphql | 113 -- .../subgraphs/reserve-celo-guide.md | 41 - .../references/subgraphs/reserve-celo.graphql | 90 -- .../screenshots/amount-editing.png | Bin 0 -> 69868 bytes .../screenshots/confirm-dialog.png | Bin 0 -> 70513 bytes .../screenshots/idle-buy.png | Bin 0 -> 69932 bytes .../screenshots/insufficient-balance.png | Bin 0 -> 67574 bytes .../screenshots/no-provider.png | Bin 0 -> 5063 bytes .../screenshots/quote-error.png | Bin 0 -> 66028 bytes .../screenshots/quote-loading.png | Bin 0 -> 69868 bytes .../screenshots/quote-ready-buy.png | Bin 0 -> 70987 bytes .../screenshots/quote-ready-sell.png | Bin 0 -> 71175 bytes .../screenshots/slippage-selection.png | Bin 0 -> 68814 bytes .../screenshots/swap-error.png | Bin 0 -> 70156 bytes .../screenshots/swap-pending.png | Bin 0 -> 70248 bytes .../screenshots/swap-success.png | Bin 0 -> 69348 bytes .../screenshots/unsupported-chain.png | Bin 0 -> 70033 bytes skills-lock.json | 11 - 77 files changed, 9266 deletions(-) delete mode 100644 .agents/skills/gooddollar/CONTRIBUTING.md delete mode 100644 .agents/skills/gooddollar/SKILL.md delete mode 100644 .agents/skills/gooddollar/references/contracts/BuyGDCloneFactory.abi.yaml delete mode 100644 .agents/skills/gooddollar/references/contracts/BuyGDCloneFactory.selectors.yaml delete mode 100644 .agents/skills/gooddollar/references/contracts/BuyGDCloneV2.abi.yaml delete mode 100644 .agents/skills/gooddollar/references/contracts/BuyGDCloneV2.selectors.yaml delete mode 100644 .agents/skills/gooddollar/references/contracts/CFAv1Forwarder.abi.yaml delete mode 100644 .agents/skills/gooddollar/references/contracts/CFAv1Forwarder.selectors.yaml delete mode 100644 .agents/skills/gooddollar/references/contracts/ConstantFlowAgreementV1.abi.yaml delete mode 100644 .agents/skills/gooddollar/references/contracts/ConstantFlowAgreementV1.selectors.yaml delete mode 100644 .agents/skills/gooddollar/references/contracts/GoodDollarOFTAdapter.abi.yaml delete mode 100644 .agents/skills/gooddollar/references/contracts/GoodDollarOFTAdapter.selectors.yaml delete mode 100644 .agents/skills/gooddollar/references/contracts/GooddollarSavingsStream.abi.yaml delete mode 100644 .agents/skills/gooddollar/references/contracts/GooddollarSavingsStream.selectors.yaml delete mode 100644 .agents/skills/gooddollar/references/contracts/GovernanceStakingV2.abi.yaml delete mode 100644 .agents/skills/gooddollar/references/contracts/GovernanceStakingV2.selectors.yaml delete mode 100644 .agents/skills/gooddollar/references/contracts/IdentityV3.abi.yaml delete mode 100644 .agents/skills/gooddollar/references/contracts/IdentityV3.selectors.yaml delete mode 100644 .agents/skills/gooddollar/references/contracts/IdentityV4.abi.yaml delete mode 100644 .agents/skills/gooddollar/references/contracts/IdentityV4.selectors.yaml delete mode 100644 .agents/skills/gooddollar/references/contracts/InvitesV2.abi.yaml delete mode 100644 .agents/skills/gooddollar/references/contracts/InvitesV2.selectors.yaml delete mode 100644 .agents/skills/gooddollar/references/contracts/MentoBroker.abi.yaml delete mode 100644 .agents/skills/gooddollar/references/contracts/MentoBroker.selectors.yaml delete mode 100644 .agents/skills/gooddollar/references/contracts/MessagePassingBridge.abi.yaml delete mode 100644 .agents/skills/gooddollar/references/contracts/MessagePassingBridge.selectors.yaml delete mode 100644 .agents/skills/gooddollar/references/contracts/NameService.abi.yaml delete mode 100644 .agents/skills/gooddollar/references/contracts/NameService.selectors.yaml delete mode 100644 .agents/skills/gooddollar/references/contracts/SuperToken.abi.yaml delete mode 100644 .agents/skills/gooddollar/references/contracts/SuperToken.selectors.yaml delete mode 100644 .agents/skills/gooddollar/references/contracts/Superfluid.abi.yaml delete mode 100644 .agents/skills/gooddollar/references/contracts/Superfluid.selectors.yaml delete mode 100644 .agents/skills/gooddollar/references/contracts/UBISchemeV2.abi.yaml delete mode 100644 .agents/skills/gooddollar/references/contracts/UBISchemeV2.selectors.yaml delete mode 100644 .agents/skills/gooddollar/references/contracts/_rich-abi-yaml-format.md delete mode 100644 .agents/skills/gooddollar/references/deep-researches/faucet-flows.md delete mode 100644 .agents/skills/gooddollar/references/deep-researches/fuse-to-celo-staking-migration.md delete mode 100644 .agents/skills/gooddollar/references/deep-researches/gooddao-daostack-surface.md delete mode 100644 .agents/skills/gooddollar/references/deep-researches/how-ubi-is-minted.md delete mode 100644 .agents/skills/gooddollar/references/deep-researches/inviter-invitee-reward-model.md delete mode 100644 .agents/skills/gooddollar/references/deep-researches/mento-reserve-economics.md delete mode 100644 .agents/skills/gooddollar/references/deep-researches/on-off-ramp-service.md delete mode 100644 .agents/skills/gooddollar/references/guides/bridge.md delete mode 100644 .agents/skills/gooddollar/references/guides/check-identity.md delete mode 100644 .agents/skills/gooddollar/references/guides/claim.md delete mode 100644 .agents/skills/gooddollar/references/guides/faucet.md delete mode 100644 .agents/skills/gooddollar/references/guides/gooddocs.md delete mode 100644 .agents/skills/gooddollar/references/guides/goodsdks.md delete mode 100644 .agents/skills/gooddollar/references/guides/hypersync-hyperrpc.md delete mode 100644 .agents/skills/gooddollar/references/guides/invite-bounties.md delete mode 100644 .agents/skills/gooddollar/references/guides/migrate-fuse-staking-to-celo-savings.md delete mode 100644 .agents/skills/gooddollar/references/guides/on-off-ramp.md delete mode 100644 .agents/skills/gooddollar/references/guides/save.md delete mode 100644 .agents/skills/gooddollar/references/guides/stream.md delete mode 100644 .agents/skills/gooddollar/references/guides/swap.md delete mode 100644 .agents/skills/gooddollar/references/subgraphs/_query-patterns.md delete mode 100644 .agents/skills/gooddollar/references/subgraphs/goodcollective-guide.md delete mode 100644 .agents/skills/gooddollar/references/subgraphs/goodcollective.graphql delete mode 100644 .agents/skills/gooddollar/references/subgraphs/gooddollar-celo-guide.md delete mode 100644 .agents/skills/gooddollar/references/subgraphs/gooddollar-celo.graphql delete mode 100644 .agents/skills/gooddollar/references/subgraphs/reserve-celo-guide.md delete mode 100644 .agents/skills/gooddollar/references/subgraphs/reserve-celo.graphql create mode 100644 examples/storybook/src/stories/goodreserve-widget/screenshots/amount-editing.png create mode 100644 examples/storybook/src/stories/goodreserve-widget/screenshots/confirm-dialog.png create mode 100644 examples/storybook/src/stories/goodreserve-widget/screenshots/idle-buy.png create mode 100644 examples/storybook/src/stories/goodreserve-widget/screenshots/insufficient-balance.png create mode 100644 examples/storybook/src/stories/goodreserve-widget/screenshots/no-provider.png create mode 100644 examples/storybook/src/stories/goodreserve-widget/screenshots/quote-error.png create mode 100644 examples/storybook/src/stories/goodreserve-widget/screenshots/quote-loading.png create mode 100644 examples/storybook/src/stories/goodreserve-widget/screenshots/quote-ready-buy.png create mode 100644 examples/storybook/src/stories/goodreserve-widget/screenshots/quote-ready-sell.png create mode 100644 examples/storybook/src/stories/goodreserve-widget/screenshots/slippage-selection.png create mode 100644 examples/storybook/src/stories/goodreserve-widget/screenshots/swap-error.png create mode 100644 examples/storybook/src/stories/goodreserve-widget/screenshots/swap-pending.png create mode 100644 examples/storybook/src/stories/goodreserve-widget/screenshots/swap-success.png create mode 100644 examples/storybook/src/stories/goodreserve-widget/screenshots/unsupported-chain.png delete mode 100644 skills-lock.json diff --git a/.agents/skills/gooddollar/CONTRIBUTING.md b/.agents/skills/gooddollar/CONTRIBUTING.md deleted file mode 100644 index ab855d3..0000000 --- a/.agents/skills/gooddollar/CONTRIBUTING.md +++ /dev/null @@ -1,121 +0,0 @@ -# Contributing to GoodSkills - -This repository is an AI skill pack. The goal of each update is to make agent behavior more reliable, more explicit, and easier to audit. - -## Update workflow - -1. Define the user-facing problem first. -2. For contract-related updates, add or update Rich ABI first (`references/contracts/*.abi.yaml`), then refresh selectors. -3. Decide the remaining artifact types: - - `references/guides/` for "what to do" - - `references/deep-researches/` for "why it works this way" - - `scripts/` for deterministic and repeatable execution -4. Update `SKILL.md` routing so the new artifact is discoverable. -5. Validate consistency (paths, naming, links, selectors, assumptions). - -If a change touches contract behavior, treat Rich ABI update/add as mandatory first step before guides, deep-research, or scripts. - -## Add or update a guide - -Use guides for execution playbooks and operator workflows. - -Required structure: - -- title and one-line usage trigger -- `## Goal` -- `## Required inputs` -- `## Execution flow` as numbered steps -- deterministic snippet when execution is non-trivial -- failure handling and output contract - -Guide rules: - -- prefer explicit pre-checks before state-changing actions -- include only one primary workflow per file -- use [GoodProtocol `releases/deployment.json`](https://github.com/GoodDollar/GoodProtocol/blob/master/releases/deployment.json) as the **only** source for contract addresses (rich ABI `meta.deployments` mirrors those rows); use GoodDocs for behavior and UX, not for resolving addresses; use on-chain `NameService.getAddress` only when the deployment documents the string key -- avoid implementation-deep theory; keep that in deep-research files - -After adding a guide: - -- add it to `SKILL.md` in `Guides` -- add an entry in `Use-case to guide map` - -## Add or update a deep-research note - -Use deep-research files for architecture, rationale, tradeoffs, and root-cause logic. - -Deep-research rules: - -- explain causality, not only API surfaces -- distinguish current behavior from legacy behavior -- link source contracts/docs for traceability -- keep language natural and decision-oriented - -Do not turn deep-research files into step-by-step runbooks; move operational steps into guides. - -## Add or update Rich ABI YAML - -Location: `references/contracts/`. - -For each contract: - -- create or update `Foo.abi.yaml` -- generate or refresh `Foo.selectors.yaml` -- include function-level notes for non-obvious behavior -- when `meta.deployments` lists concrete addresses, add **`creationBlock`** next to each **`address`** (placement: `references/contracts/_rich-abi-yaml-format.md`; using it as **`fromBlock`** for log or HyperSync fetches: `references/guides/hypersync-hyperrpc.md`) - -Minimum ABI documentation quality: - -- correct mutability, inputs, outputs -- access pattern (`owner`, `avatar`, `anyone`, etc.) where relevant -- emitted events and practical errors -- notes for routing/edge-case semantics - -Source-of-truth policy: - -- prefer canonical contract repos (GoodProtocol, GoodBridge, mento-core) -- avoid inferred behavior when source is unclear -- update notes when protocol behavior changed - -Selector generation: - -```bash -node scripts/selectors.mjs generate Foo.abi.yaml -``` - -## Add or update scripts - -Location: `scripts/`. - -Use scripts when: - -- a workflow is repeated -- deterministic output is needed -- manual querying is error-prone - -Script standards: - -- require inputs through env vars or explicit args -- fail loudly with actionable messages -- print structured output for easy reuse -- keep script intent narrow - -When a script supports a guide: - -- reference it from that guide -- document expected inputs and outputs in the guide - -## Naming and organization - -- use lowercase kebab-case for guides and deep-research files -- keep one topic per file -- avoid duplicate guidance across files -- prefer updating existing files over creating near-duplicates - -## Update checklist before merge - -- `SKILL.md` routing updated -- links resolve and point to public sources -- guides and deep-research files respect "what" vs "why" separation -- ABI + selectors pairs are in sync -- new behavior is reflected in notes where needed diff --git a/.agents/skills/gooddollar/SKILL.md b/.agents/skills/gooddollar/SKILL.md deleted file mode 100644 index 2d59116..0000000 --- a/.agents/skills/gooddollar/SKILL.md +++ /dev/null @@ -1,215 +0,0 @@ ---- -name: gooddollar -description: > - Knowledge base for GoodProtocol action execution and GoodDollar (G$) integrations. - Use this skill BEFORE ad-hoc web search for claim, save/stake, swap, bridge, - stream, and identity tasks. Prefer GoodDocs (https://docs.gooddollar.org/) for - narrative; contract addresses only from GoodProtocol releases/deployment.json. -metadata: - version: 1.0.0 -license: MIT ---- - -# GoodDollar Skill Pack - -Routing index for GoodProtocol. This repo complements [GoodDocs](https://docs.gooddollar.org/) for behavior and user flows. **Contract addresses** come only from [GoodProtocol/releases/deployment.json](https://github.com/GoodDollar/GoodProtocol/blob/master/releases/deployment.json) (and `meta.deployments` in `references/contracts/*.abi.yaml`, which mirror those rows)—not from GoodDocs pages. - -Repository maintenance and update process is documented in `CONTRIBUTING.md`. - -## Protocol snapshot (from GoodDocs) - -- G$ is reserve-backed; issuance and pricing tie to the reserve and bonding-curve mechanics described in [How GoodDollar works](https://docs.gooddollar.org/how-gooddollar-works). -- The stack is multi-chain; which contracts exist per environment is defined only in [deployment.json](https://github.com/GoodDollar/GoodProtocol/blob/master/releases/deployment.json) (for example `GoodDollar`, `Identity`, `NameService`, `UBIScheme`, Mento keys, `MpbBridge`, and related entries under `production`, `production-celo`, and `production-xdc`). -- UBI is daily for verified users; identity verification and connected accounts are documented under [user guides](https://docs.gooddollar.org/user-guides). - -## Guides (single location for action playbooks) - -All task-specific instructions live under `references/guides/`. - -- `references/guides/claim.md` — daily UBI (`claim` / UBIScheme). -- `references/guides/save.md` — stake, rewards, unstake. -- `references/guides/swap.md` — buy or sell G$ (Mento on supported chains). -- `references/guides/bridge.md` — MessagePassingBridge (GoodDocs); optional OFT path via ABI refs. -- `references/guides/stream.md` — Superfluid streams (Celo-oriented in GoodDocs). -- `references/guides/check-identity.md` — whitelist and connected-address semantics. -- `references/guides/goodsdks.md` — SDK-first integration routing for GoodSDKs packages. -- `references/guides/gooddocs.md` — hub links to [GoodDocs](https://docs.gooddollar.org/). -- `references/guides/hypersync-hyperrpc.md` — Envio HyperSync/HyperRPC data-source routing for high-volume historical reads. -- `references/guides/faucet.md` — Faucet gas top-up execution flow and preflight checks. -- `references/guides/on-off-ramp.md` — stable-token ramp service flow into and out of G$. -- `references/guides/invite-bounties.md` — verify and execute inviter-invitee bounty payouts. -- `references/guides/migrate-fuse-staking-to-celo-savings.md` — migrate Fuse governance stake to CELO savings flow. - -## Subgraphs (indexed chain history) - -Use this folder with the same pattern as the protocol subgraph references: one `*-guide.md` plus one companion `.graphql` per deployment. - -For historical on-chain data, **start with the subgraph**: confirm the deployment covers the question (entities and fields in the guide, freshness via `_meta`). If the subgraph does not work for the request—missing schema coverage, stale or lagging indexing, query limits, or endpoint errors—**then** move to **HyperSync** or **HyperRPC** using `references/guides/hypersync-hyperrpc.md`. - -- `references/subgraphs/_query-patterns.md` — cross-cutting query discipline. -- `references/subgraphs/reserve-celo-guide.md` + `references/subgraphs/reserve-celo.graphql` — reserve pricing and swap history. -- `references/subgraphs/gooddollar-celo-guide.md` + `references/subgraphs/gooddollar-celo.graphql` — GoodDollar Celo schema discovery and starter probes. -- `references/subgraphs/goodcollective-guide.md` + `references/subgraphs/goodcollective.graphql` — GoodCollective schema discovery and starter probes. - -For Superfluid protocol subgraphs (streams, pools, vesting schedulers), see [Superfluid documentation](https://docs.superfluid.finance/) and [subgraph endpoints](https://subgraph-endpoints.superfluid.dev/). - -## Historical data routing policy (strict) - -1. Query subgraphs first for all historical/indexed requests. -2. Validate required entities and fields against the target subgraph schema and guide before declaring a gap. -3. Use **HyperSync** or **HyperRPC** fallback only when at least one of these is true: - - required entities or fields are not available in subgraph schema - - indexing lag makes subgraph data stale for the requested range - - query limits or endpoint instability block reliable retrieval -4. Do not start with HyperSync or HyperRPC when subgraph data is available and fresh. -5. HyperRPC fallback requires a valid Envio API key; if missing, **explicitly ask the user** to provide `HYPERRPC_API_TOKEN` or `ENVIO_API_TOKEN` (or paste a full `HYPERRPC_URL`); do not treat anonymous HyperRPC as production. -6. When **HyperSync** is the best option for the query and no Envio API token is available (`ENVIO_API_TOKEN` or equivalent per `references/guides/hypersync-hyperrpc.md`), **explicitly ask the user** to provide the token before proceeding; do not silently substitute anonymous HyperSync usage. -7. When fallback is used, report reason explicitly (schema gap, lag, or reliability issue). - -## Data source decision table - -| Query type | Primary source | Secondary source | Notes | -|---|---|---|---| -| Current on-chain state (latest balances, allowances, config, flags, view calls) | RPC | None | Use direct contract RPC reads for latest state. | -| Historical indexed entity data (time-series, aggregates, protocol entities, event-derived analytics) | Subgraph | HyperSync/HyperRPC | Prefer subgraph first; fall back when it cannot answer. | -| Historical raw on-chain data when subgraph is missing fields/entities or stale | HyperSync | HyperRPC | Prefer HyperSync for bulk scans and data pipelines. | -| Historical data for existing JSON-RPC integrations | HyperRPC | HyperSync | Use HyperRPC when strict JSON-RPC compatibility is required. | - -Decision rule: - -1. If request is current state -> use RPC. -2. If request is historical/indexed -> query subgraph first. -3. If subgraph cannot satisfy request -> fallback to HyperSync or HyperRPC per compatibility and scale needs. -4. HyperRPC fallback requires Envio API key credentials. -5. HyperSync client usage requires an Envio API token; if HyperSync is chosen and the token is missing, explicitly ask the user to provide it (see `references/guides/hypersync-hyperrpc.md`). - -## Mapping data retrieval rule - -Solidity mappings are not iterable on-chain by keyspace scan. Do not assume full-key enumeration is possible from RPC alone. - -When data is stored in mapping-like structures: - -1. Check contract source and ABI for key-discovery paths first: - - events emitted on set or update - - arrays, counters, linked lists, or index getters storing keys - - dedicated pagination or enumerable view functions -2. If key discovery exists, reconstruct key set from those sources and then read mapping entries. -3. If key discovery does not exist, report that complete iteration is not possible from chain state alone. -4. For historical reconstruction, prefer subgraph indexing first; if unavailable, use HyperSync or HyperRPC log scans with explicit limitations. - -## Use-case to guide map - -- Claim requests -> `references/guides/claim.md` -- Eligibility or connected-address questions -> `references/guides/check-identity.md` -- Stake, save, unstake -> `references/guides/save.md` -- Buy or sell G$ against reserve rails -> `references/guides/swap.md` -- Cross-chain bridge -> `references/guides/bridge.md` -- Stream management -> `references/guides/stream.md` -- SDK app integration tasks -> `references/guides/goodsdks.md` -- Bulk historical reads or data-engineering fetches -> `references/guides/hypersync-hyperrpc.md` -- Faucet top-up tasks -> `references/guides/faucet.md` -- On-/off-ramp service flow tasks -> `references/guides/on-off-ramp.md` -- Invite bounty eligibility and payout tasks -> `references/guides/invite-bounties.md` -- Fuse to CELO staking migration tasks -> `references/guides/migrate-fuse-staking-to-celo-savings.md` -- Indexed history, analytics, or GraphQL against GoodDollar subgraphs -> `references/subgraphs/_query-patterns.md` -- Historical on-chain fetch when subgraph data is insufficient -> subgraphs first, then HyperSync or HyperRPC per `references/guides/hypersync-hyperrpc.md`; if HyperSync is best and `ENVIO_API_TOKEN` is missing, ask the user for it explicitly. - -## Ambiguous prompts and incomplete inputs - -Stop and **ask the user** whenever the task is underspecified or required facts are missing. List what you need in short, concrete questions (for example chain, contract, address, amount, account, RPC or signer access, time or block range, prior tx hash, approval scope). - -- **Ambiguous** means the goal, environment, contract surface, or acceptance criteria are not clear enough to choose a safe path. -- **Incomplete** means you lack inputs that would change what you build, call, or sign next. - -**Do not invent** chain, address, amount, or policy details that affect correctness, funds, or eligibility. For **information-only** work you may state a single explicit assumption, label it, and ask the user to confirm or correct it before going further. - -**Execution work** (writing or editing runnable code, sending transactions, migrations, or anything that can move funds or alter on-chain state) has **no guessing**: settle every required input with the user, then implement or run. - -## Execution rules - -1. Collect missing required inputs before sending transactions. -2. Run pre-checks first (allowance, whitelist, quotes, bridge **amount** limits, peer wiring when using OFT paths). -3. If a pre-check fails, stop and return the exact corrective action. -4. Return tx hash and key output values. -5. Never fabricate addresses, amounts, or ABI behavior. -6. Resolve decimals and units per chain as in [How to integrate the G$ token](https://docs.gooddollar.org/for-developers/developer-guides/how-to-integrate-the-gusd-token) (for example 18 decimals on Celo, 2 on Fuse and Ethereum where applicable). - -## Pre-check matrix - -- Claim: verify identity whitelist status before `claim()`. -- Save or stake: verify balance and allowance before `stake()`. -- Swap: fetch quote, apply slippage bounds, verify allowance; confirm Mento contract keys for the active chain exist in `deployment.json` (for example `MentoBroker` under `production-celo` or `production-xdc`). -- Bridge (MessagePassingBridge): on the **source** chain approve G$ to the bridge; optionally preflight `canBridge(from, amount)` on that same contract (outbound `_bridgeTo` does not call it internally). For LZ use `estimateSendFee` with the **normalized** burn amount per `references/guides/bridge.md`, then `bridgeToWithLz` with nonzero `msg.value` for the **cross-chain transport** fee only (distinct from destination **`bridgeFees`** on minted G$; see **Bridge fee context** in that guide). Read **`bridgeLimits`** / daily trackers when debugging **amount** caps; see **Bridge amount limit context** in that guide. Respect `isClosed`, `LZ_FEE`, `MISSING_FEE`, and `UNSUPPORTED_CHAIN`. **Destination** mint applies `_enforceLimits` and can still revert. Use **Axelar** only when `toAxelarChainId` returns a route (implementation maps 1, 5, 42220, 44787); for Fuse or XDC style targets prefer LZ unless mapping is extended on-chain. -- Bridge (OFT adapter path): verify peer wiring and `quoteSend` fee data. -- Stream: confirm Celo (or documented Superfluid network) and correct Super Token and forwarder or host addresses. -- Identity: resolve Identity from NameService; remember connected addresses do not multiply daily claims ([connect wallet guide](https://docs.gooddollar.org/user-guides/connect-another-wallet-address-to-identity)). - -## Output format requirements - -For any state-changing action return: - -- network and key contract addresses used -- normalized input amounts and min or max guards -- tx hash -- key post-state output when available -- follow-up action if user intervention is required - -## Rich contract ABI references - -Convention: each `Foo.abi.yaml` has a companion `Foo.selectors.yaml` (function, event, and custom error selectors). Schema: `references/contracts/_rich-abi-yaml-format.md`. - -GoodDollar / Mento: - -- `references/contracts/NameService.abi.yaml` -- `references/contracts/IdentityV3.abi.yaml` -- `references/contracts/IdentityV4.abi.yaml` -- `references/contracts/InvitesV2.abi.yaml` -- `references/contracts/BuyGDCloneFactory.abi.yaml` -- `references/contracts/BuyGDCloneV2.abi.yaml` -- `references/contracts/GovernanceStakingV2.abi.yaml` -- `references/contracts/GooddollarSavingsStream.abi.yaml` (Ubeswap Superfluid stream savings; Celo deployment) -- `references/contracts/UBISchemeV2.abi.yaml` -- `references/contracts/MentoBroker.abi.yaml` -- `references/contracts/MessagePassingBridge.abi.yaml` -- `references/contracts/GoodDollarOFTAdapter.abi.yaml` -- `references/contracts/CFAv1Forwarder.abi.yaml` -- `references/contracts/ConstantFlowAgreementV1.abi.yaml` -- `references/contracts/Superfluid.abi.yaml` -- `references/contracts/SuperToken.abi.yaml` - -Superfluid (CFA, CFAv1Forwarder, Host, full ABI library): use [Superfluid docs](https://docs.superfluid.finance/), npm packages such as `@superfluid-finance/ethereum-contracts` and `@sfpro/sdk`, and contract ABIs published with those packages. - -## Deep researches - -- `references/deep-researches/on-off-ramp-service.md` -- `references/deep-researches/how-ubi-is-minted.md` -- `references/deep-researches/inviter-invitee-reward-model.md` -- `references/deep-researches/mento-reserve-economics.md` -- `references/deep-researches/gooddao-daostack-surface.md` -- `references/deep-researches/faucet-flows.md` -- `references/deep-researches/fuse-to-celo-staking-migration.md` - -## Revert debugging quick map - -- Identity or eligibility errors -> Identity and UBIScheme ABIs; live addresses from `deployment.json` only; GoodDocs for whitelist and claim behavior. -- Approval or transfer failures -> token approvals and balances; see integration guide for `transferAndCall` vs `approve` plus `transferFrom`. -- Swap bound failures -> quote freshness and slippage settings. -- MessagePassingBridge failures -> `canBridge`; **`BRIDGE_LIMITS`** (amount caps, whitelist, **`closed`**, and related policy strings); transport `msg.value` (`MISSING_FEE`, `LZ_FEE`) vs destination protocol fee (`bridgeFees`, `feeRecipient`); correct `bridgeTo` arguments; [Bridge GoodDollars](https://docs.gooddollar.org/user-guides/bridge-gooddollars). -- OFT path failures -> peer wiring and `quoteSend` fee data. -- Stream failures -> CFA forwarder or host agreement calls, buffer and flow-rate limits per Superfluid docs linked from GoodDocs. -- Faucet top-up failures -> `canTop`, `onlyAuthorized`, daily or weekly caps; `references/deep-researches/faucet-flows.md`. -- DAO-gated reverts -> caller is not avatar; scheme not registered; `references/deep-researches/gooddao-daostack-surface.md`. - -## Library usage discipline - -1. Open `references/guides/gooddocs.md` when unsure which GoodDocs page applies. -2. Start at this file to classify intent. -3. Open one guide under `references/guides/` unless the user requests a multi-step workflow. For subgraph or indexed-data tasks, start at `references/subgraphs/_query-patterns.md`. -4. Read only the ABI references and matching `.selectors.yaml` files needed for the chosen action. -5. Prefer GoodDocs for documented behavior; use only `deployment.json` (and rich ABI `meta.deployments` aligned with it) for contract addresses—never infer addresses from GoodDocs. -6. For large historical reads, prefer `references/guides/hypersync-hyperrpc.md` and choose HyperSync over HyperRPC unless strict JSON-RPC compatibility is required. -7. Historical data routing is strict: subgraphs first; HyperSync or HyperRPC only with an explicit fallback reason. -8. HyperRPC usage requires Envio API key credentials; when absent, **explicitly ask the user** for `HYPERRPC_API_TOKEN` or `ENVIO_API_TOKEN` (or a full `HYPERRPC_URL`) and do not attempt anonymous production flow. -9. When HyperSync is the best historical-data path and no Envio API token is available, explicitly ask the user to provide `ENVIO_API_TOKEN` (or the token your client expects) before continuing; see `references/guides/hypersync-hyperrpc.md`. -10. For subgraph tasks, validate field availability from the relevant `references/subgraphs/*-guide.md` and companion `.graphql` before guessing alternate entities. -11. For local shells repeating HyperRPC log pulls (for example last N whitelist events), from the **GoodSkills repository root** run `scripts/fetch-whitelist-events-hyperrpc.mjs` per `references/guides/hypersync-hyperrpc.md` instead of re-deriving JSON-RPC setup each time; that script ships with **defaults for production Celo** (HyperRPC host + `Identity` contract from `deployment.json`) and URL composition from `HYPERRPC_API_TOKEN` or `ENVIO_API_TOKEN` unless you override `CONTRACT_ADDRESS` / `HYPERRPC_URL`. HyperSync remains a separate client install path documented in the same guide. diff --git a/.agents/skills/gooddollar/references/contracts/BuyGDCloneFactory.abi.yaml b/.agents/skills/gooddollar/references/contracts/BuyGDCloneFactory.abi.yaml deleted file mode 100644 index 40226b3..0000000 --- a/.agents/skills/gooddollar/references/contracts/BuyGDCloneFactory.abi.yaml +++ /dev/null @@ -1,205 +0,0 @@ -meta: - name: BuyGDCloneFactory - version: "1" - source: - - https://raw.githubusercontent.com/GoodDollar/GoodProtocol/master/contracts/utils/BuyGDClone.sol - note: > - Deterministic clone factory for BuyGDCloneV2 and DonateGDClone. Used to create per-owner - executors and optional create+swap flows for ramp services. - deployments: - mainnet: - production-celo: - BuyGDFactoryV2: - networkId: 42220 - address: "0x1F60C4C7037C6766924A43666B781ED1479587a2" - creationBlock: 22909812 - BuyGDFactory: - networkId: 42220 - address: "0x00e533B7d6255D05b7f15034B1c989c21F51b91C" - creationBlock: 21006324 - related: - - references/deep-researches/on-off-ramp-service.md - - references/guides/on-off-ramp.md - -create: - notes: - - "Deploys deterministic BuyGDCloneV2 clone for owner and initializes it." - - "Difference vs createAndSwap: this only deploys; no swap is executed." - mutability: nonpayable - access: anyone - inputs: - - owner: address - outputs: - - clone: address - -createDonation: - notes: - - "Deploys deterministic DonateGDClone with donation target and call payload." - - "Difference vs create: deploys donation-capable implementation instead of plain swap clone." - mutability: nonpayable - access: anyone - inputs: - - owner: address - - donateOrExecTo: address - - callData: bytes - outputs: - - clone: address - -createAndSwap: - notes: - - "One-transaction helper: create BuyGDCloneV2 then immediately call clone.swap(minAmount, msg.sender)." - - "Difference vs create: bundles deployment and first swap for faster ramp UX." - mutability: nonpayable - access: anyone - inputs: - - owner: address - - minAmount: uint256 - outputs: - - clone: address - -createDonationAndSwap: - notes: - - "One-transaction helper for DonateGDClone: deploy, then execute donation flow with optional pre-swap." - - "Difference vs createDonation: can execute immediate swap and/or target call instead of deployment only." - mutability: nonpayable - access: anyone - inputs: - - owner: address - - donateOrExecTo: address - - withSwap: bool - - minAmount: uint256 - - callData: bytes - outputs: - - clone: address - -predict: - notes: - - "Computes deterministic address for create(owner) salt." - mutability: view - inputs: - - owner: address - outputs: - - clone: address - -predictDonation: - notes: - - "Computes deterministic address for createDonation(owner, donateOrExecTo, callData) salt." - mutability: view - inputs: - - owner: address - - donateOrExecTo: address - - callData: bytes - outputs: - - clone: address - -getBaseFee: - mutability: view - inputs: [] - outputs: - - baseFee: uint256 - -quoter: - mutability: pure - inputs: [] - outputs: - - addr: address - -CUSD: - mutability: pure - inputs: [] - outputs: - - token: address - -celo: - mutability: pure - inputs: [] - outputs: - - token: address - -USDC: - mutability: pure - inputs: [] - outputs: - - token: address - -GLOUSD: - mutability: pure - inputs: [] - outputs: - - token: address - -PERIOD: - mutability: pure - inputs: [] - outputs: - - seconds: uint24 - -impl: - mutability: view - inputs: [] - outputs: - - addr: address - -donateImpl: - mutability: view - inputs: [] - outputs: - - addr: address - -gd: - mutability: view - inputs: [] - outputs: - - token: address - -stable: - mutability: view - inputs: [] - outputs: - - token: address - -oracle: - mutability: view - inputs: [] - outputs: - - addr: address - -router: - mutability: view - inputs: [] - outputs: - - addr: address - -mentoBroker: - mutability: view - inputs: [] - outputs: - - addr: address - -mentoExchangeProvider: - mutability: view - inputs: [] - outputs: - - addr: address - -mentoExchangeId: - mutability: view - inputs: [] - outputs: - - id: bytes32 - -events: - GDSwapToCusd: - indexed: [] - data: - - from: address - - to: address - - amountIn: uint256 - - amountOut: uint256 - - note: bytes - -errors: - NOT_GD_TOKEN: "onTokenTransfer caller is not G$ token." - INVALID_TWAP: "TWAP validation failed." - RECIPIENT_ZERO: "Recipient cannot be zero address." - ZERO_MINAMOUNT: "Minimum amount cannot be zero." diff --git a/.agents/skills/gooddollar/references/contracts/BuyGDCloneFactory.selectors.yaml b/.agents/skills/gooddollar/references/contracts/BuyGDCloneFactory.selectors.yaml deleted file mode 100644 index 16b13f2..0000000 --- a/.agents/skills/gooddollar/references/contracts/BuyGDCloneFactory.selectors.yaml +++ /dev/null @@ -1,27 +0,0 @@ -# Generated by scripts/selectors.mjs -functions: - create(address): 0x9ed93318 - createDonation(address,address,bytes): 0x48199e6b - createAndSwap(address,uint256): 0x89643a29 - createDonationAndSwap(address,address,bool,uint256,bytes): 0xeb5621b8 - predict(address): 0x901b96e7 - predictDonation(address,address,bytes): 0x3895de30 - getBaseFee(): 0x15e812ad - quoter(): 0xc6bbd5a7 - CUSD(): 0x758316c9 - celo(): 0x051ed8ef - USDC(): 0x89a30271 - GLOUSD(): 0x4b5b02d6 - PERIOD(): 0xb4d1d795 - impl(): 0x8abf6077 - donateImpl(): 0x21fc2eef - gd(): 0xa5e598fc - stable(): 0x22be3de1 - oracle(): 0x7dc0d1d0 - router(): 0xf887ea40 - mentoBroker(): 0x7b89f117 - mentoExchangeProvider(): 0x4f62feec - mentoExchangeId(): 0xd373b333 -events: - GDSwapToCusd(address,address,uint256,uint256,bytes): 0x252bc23e3fb01f9986fa157af621236fb8a706ea12622da296e7f2f30d4f1a56 -errors: {} diff --git a/.agents/skills/gooddollar/references/contracts/BuyGDCloneV2.abi.yaml b/.agents/skills/gooddollar/references/contracts/BuyGDCloneV2.abi.yaml deleted file mode 100644 index 5f35ee9..0000000 --- a/.agents/skills/gooddollar/references/contracts/BuyGDCloneV2.abi.yaml +++ /dev/null @@ -1,282 +0,0 @@ -meta: - name: BuyGDCloneV2 - version: "2" - source: - - https://raw.githubusercontent.com/GoodDollar/GoodProtocol/master/contracts/utils/BuyGDClone.sol - inherits: - - Initializable - note: > - Clone implementation used by BuyGDCloneFactory for deterministic per-owner swap executors. - Supports CELO and cUSD flows, with cUSD route selection between Uniswap and Mento when configured. - deployments: - mainnet: - production-celo: - BuyGDFactoryV2: - networkId: 42220 - address: "0x1F60C4C7037C6766924A43666B781ED1479587a2" - creationBlock: 22909812 - related: - - references/deep-researches/on-off-ramp-service.md - - references/guides/on-off-ramp.md - -initialize: - mutability: nonpayable - access: initializer - inputs: - - _owner: address - outputs: [] - -getSwapPath: - mutability: pure - inputs: - - tokens: address[] - - fees: uint24[] - outputs: - - path: bytes - -swap: - notes: - - "Dispatcher entrypoint: if clone holds native CELO balance it executes CELO route, otherwise uses cUSD route." - - "Difference vs swapCelo/swapCusd: this function chooses route by contract balances; specialized functions force a specific asset path." - mutability: payable - access: anyone - inputs: - - _minAmount: uint256 - - refundGas: address - outputs: - - bought: uint256 - emits: [Bought] - errors: [NO_BALANCE] - -swapCelo: - notes: - - "CELO-only convenience path using the default preconfigured Uniswap route." - - "Difference vs swapCeloWithPath: same Uniswap execution, but caller cannot override token path and fee tiers." - - "Difference vs cUSD paths: CELO path does not use Mento route selection." - mutability: payable - access: anyone - inputs: - - _minAmount: uint256 - - refundGas: address - outputs: - - bought: uint256 - emits: [BoughtFromUniswap] - errors: [REFUND_FAILED] - -swapCeloWithPath: - notes: - - "CELO-only path with caller-supplied Uniswap multi-hop route." - - "Difference vs swapCelo: allows custom path optimization when default route is not preferred." - - "Difference vs cUSD paths: still Uniswap-only and does not compare against Mento." - mutability: payable - access: anyone - inputs: - - _minAmount: uint256 - - refundGas: address - - _path: (address[],uint24[]) - outputs: - - bought: uint256 - emits: [BoughtFromUniswap] - errors: [REFUND_FAILED] - -swapCusd: - notes: - - "cUSD-only convenience path that compares expected output from default-path Uniswap and Mento, then executes the better quote." - - "Difference vs swapCusdWithPath: this uses hardcoded default Uniswap path for comparison." - - "Difference vs CELO paths: includes dual-route best-execution logic with optional Mento." - mutability: nonpayable - access: anyone - inputs: - - _minAmount: uint256 - - refundGas: address - outputs: - - bought: uint256 - emits: [BoughtFromMento, BoughtFromUniswap] - errors: [MENTO_NOT_CONFIGURED] - -swapCusdWithPath: - notes: - - "cUSD path with caller-supplied Uniswap route; still compares custom Uniswap quote against Mento quote and picks larger expected output." - - "Difference vs swapCusd: custom path changes only the Uniswap side of the comparison." - - "Difference vs swapCeloWithPath: this function performs route competition (Uniswap vs Mento), not only route customization." - mutability: nonpayable - access: anyone - inputs: - - _minAmount: uint256 - - refundGas: address - - _path: (address[],uint24[]) - outputs: - - bought: uint256 - emits: [BoughtFromMento, BoughtFromUniswap] - errors: [MENTO_NOT_CONFIGURED] - -getExpectedReturnFromUniswapPath: - notes: - - "Quote helper for Uniswap path expected output used by cUSD route selection and preflight checks." - mutability: nonpayable - inputs: - - amountIn: uint256 - - _path: (address[],uint24[]) - outputs: - - expectedReturn: uint256 - -getExpectedReturnFromMento: - notes: - - "Quote helper for Mento expected output for cUSD->G$ used in best-route decision." - mutability: view - inputs: - - cusdAmount: uint256 - outputs: - - expectedReturn: uint256 - errors: [MENTO_NOT_CONFIGURED] - -minAmountByTWAP: - mutability: view - inputs: - - baseAmount: uint256 - - baseToken: address - - period: uint32 - outputs: - - minTwap: uint256 - - quote: uint256 - -recover: - mutability: nonpayable - access: anyone - inputs: - - token: address - outputs: [] - errors: [REFUND_FAILED] - -router: - mutability: view - inputs: [] - outputs: - - addr: address - -celo: - mutability: pure - inputs: [] - outputs: - - token: address - -CUSD: - mutability: pure - inputs: [] - outputs: - - token: address - -USDC: - mutability: pure - inputs: [] - outputs: - - token: address - -GLOUSD: - mutability: pure - inputs: [] - outputs: - - token: address - -GD_FEE_TIER: - mutability: pure - inputs: [] - outputs: - - tier: uint24 - -CUSD_STABLE_FEE_TIER: - mutability: pure - inputs: [] - outputs: - - tier: uint24 - -CELO_STABLE_FEE_TIER: - mutability: pure - inputs: [] - outputs: - - tier: uint24 - -twapPeriod: - mutability: view - inputs: [] - outputs: - - period: uint32 - -stable: - mutability: view - inputs: [] - outputs: - - token: address - -gd: - mutability: view - inputs: [] - outputs: - - token: address - -oracle: - mutability: view - inputs: [] - outputs: - - addr: address - -quoter: - mutability: view - inputs: [] - outputs: - - addr: address - -mentoBroker: - mutability: view - inputs: [] - outputs: - - addr: address - -mentoExchangeProvider: - mutability: view - inputs: [] - outputs: - - addr: address - -mentoExchangeId: - mutability: view - inputs: [] - outputs: - - id: bytes32 - -owner: - mutability: view - inputs: [] - outputs: - - addr: address - -CUSD_GAS_COSTS: - mutability: pure - inputs: [] - outputs: - - amount: uint256 - -events: - Bought: - indexed: [] - data: - - inToken: address - - inAmount: uint256 - - outAmount: uint256 - BoughtFromMento: - indexed: [] - data: - - inToken: address - - inAmount: uint256 - - outAmount: uint256 - BoughtFromUniswap: - indexed: [] - data: - - inToken: address - - inAmount: uint256 - - outAmount: uint256 - -errors: - REFUND_FAILED: "Refund call failed." - NO_BALANCE: "No CELO or cUSD available on clone." - MENTO_NOT_CONFIGURED: "Mento broker path not configured." diff --git a/.agents/skills/gooddollar/references/contracts/BuyGDCloneV2.selectors.yaml b/.agents/skills/gooddollar/references/contracts/BuyGDCloneV2.selectors.yaml deleted file mode 100644 index 1476ae3..0000000 --- a/.agents/skills/gooddollar/references/contracts/BuyGDCloneV2.selectors.yaml +++ /dev/null @@ -1,36 +0,0 @@ -# Generated by scripts/selectors.mjs -functions: - initialize(address): 0xc4d66de8 - getSwapPath(address[],uint24[]): 0xf0036d5d - swap(uint256,address): 0xd3986f08 - swapCelo(uint256,address): 0xaa6bfa9d - swapCeloWithPath(uint256,address,(address[],uint24[])): 0x81b7d2e0 - swapCusd(uint256,address): 0xb1a5fa9f - swapCusdWithPath(uint256,address,(address[],uint24[])): 0x170ba915 - getExpectedReturnFromUniswapPath(uint256,(address[],uint24[])): 0x12194320 - getExpectedReturnFromMento(uint256): 0xdbb15eb2 - minAmountByTWAP(uint256,address,uint32): 0x821dc910 - recover(address): 0x0cd865ec - router(): 0xf887ea40 - celo(): 0x051ed8ef - CUSD(): 0x758316c9 - USDC(): 0x89a30271 - GLOUSD(): 0x4b5b02d6 - GD_FEE_TIER(): 0xe00e8fdd - CUSD_STABLE_FEE_TIER(): 0xba428926 - CELO_STABLE_FEE_TIER(): 0x60e4bf4b - twapPeriod(): 0xf6207326 - stable(): 0x22be3de1 - gd(): 0xa5e598fc - oracle(): 0x7dc0d1d0 - quoter(): 0xc6bbd5a7 - mentoBroker(): 0x7b89f117 - mentoExchangeProvider(): 0x4f62feec - mentoExchangeId(): 0xd373b333 - owner(): 0x8da5cb5b - CUSD_GAS_COSTS(): 0x32f90ac3 -events: - Bought(address,uint256,uint256): 0xa9a40dec7a304e5915d11358b968c1e8d365992abf20f82285d1df1b30c8e24c - BoughtFromMento(address,uint256,uint256): 0x8e2ac24d7ef5662ee242823a19dbd1c952b3e96ae127228f4bbce83e2816e3fb - BoughtFromUniswap(address,uint256,uint256): 0xdb1f2a6cbbfd964f19c648b140a35992aa80f482df8f519d3211d0bd86c9f335 -errors: {} diff --git a/.agents/skills/gooddollar/references/contracts/CFAv1Forwarder.abi.yaml b/.agents/skills/gooddollar/references/contracts/CFAv1Forwarder.abi.yaml deleted file mode 100644 index 32ba0de..0000000 --- a/.agents/skills/gooddollar/references/contracts/CFAv1Forwarder.abi.yaml +++ /dev/null @@ -1,237 +0,0 @@ -# CFAv1Forwarder — convenience wrapper for ConstantFlowAgreementV1 -# Allows direct interaction with CFA functions without manually routing through -# the Host's batchCall / forwardBatchCall. Operates as a trusted forwarder, -# preserving msg.sender via EIP-2771. -# -# Each forwarder call is a standalone transaction — forwarder calls cannot be -# combined in a Host.batchCall. To batch multiple operations atomically (e.g. -# wrap tokens + create stream), use Host.batchCall with the raw CFA agreement -# (operationType 201). See Superfluid.abi.yaml for batch operation details. -# Tradeoff: forwarder calls produce human-readable descriptions in wallets -# (e.g. "setFlowrate(token, receiver, flowrate)"), while Host.batchCall -# shows encoded tuples that are difficult for users to verify. -# -# This contract has no events — all events are emitted by the underlying CFA. -# Errors from the CFA (and Host) propagate through to the caller. - -meta: - name: CFAv1Forwarder - version: v1 - source: - - https://raw.githubusercontent.com/superfluid-org/protocol-monorepo/refs/heads/dev/packages/ethereum-contracts/contracts/utils/CFAv1Forwarder.sol - - https://raw.githubusercontent.com/superfluid-org/protocol-monorepo/refs/heads/dev/packages/ethereum-contracts/contracts/utils/ForwarderBase.sol - inherits: [ForwarderBase] - deployments: - # Same address on all networks except avalanche-fuji - mainnet: - eth-mainnet: "0xcfA132E353cB4E398080B9700609bb008eceB125" - polygon-mainnet: "0xcfA132E353cB4E398080B9700609bb008eceB125" - xdai-mainnet: "0xcfA132E353cB4E398080B9700609bb008eceB125" - base-mainnet: "0xcfA132E353cB4E398080B9700609bb008eceB125" - optimism-mainnet: "0xcfA132E353cB4E398080B9700609bb008eceB125" - arbitrum-one: "0xcfA132E353cB4E398080B9700609bb008eceB125" - bsc-mainnet: "0xcfA132E353cB4E398080B9700609bb008eceB125" - avalanche-c: "0xcfA132E353cB4E398080B9700609bb008eceB125" - celo-mainnet: "0xcfA132E353cB4E398080B9700609bb008eceB125" - scroll-mainnet: "0xcfA132E353cB4E398080B9700609bb008eceB125" - degenchain: "0xcfA132E353cB4E398080B9700609bb008eceB125" - testnet: - avalanche-fuji: "0x2CDd45c5182602a36d391F7F16DD9f8386C3bD8D" - base-sepolia: "0xcfA132E353cB4E398080B9700609bb008eceB125" - eth-sepolia: "0xcfA132E353cB4E398080B9700609bb008eceB125" - optimism-sepolia: "0xcfA132E353cB4E398080B9700609bb008eceB125" - scroll-sepolia: "0xcfA132E353cB4E398080B9700609bb008eceB125" - deploymentCreationBlocks: - mainnet: - celo-mainnet: 17404156 - -# == Glossary == -# flowrate — token transfer rate in wad/second (int96) -# flowOperator — account authorized to create/update/delete flows on behalf of another -# buffer — deposit locked as solvency collateral while a flow is active -# permissions — bitmask of create | update | delete rights for an operator -# flowrateAllowance — max flowrate an operator may set per individual flow - -# == Flow Management == -# High-level functions that automatically create, update, or delete flows as needed. - -setFlowrate: - # Smart setter: creates a new flow if none exists, updates if flowrate changed, - # deletes if flowrate is zero. No-ops if the current rate already matches. - notes: - - "Gotcha: Negative flowrate values revert with CFA_FWD_INVALID_FLOW_RATE." - mutability: nonpayable - access: anyone # flow from msg.sender - inputs: - - token: address - - receiver: address - - flowrate: int96 # must be >= 0 - outputs: - - bool - errors: [CFA_FWD_INVALID_FLOW_RATE] - -setFlowrateFrom: - # Same as setFlowrate but can be called by a flow operator on behalf of `sender`. - # msg.sender must have sufficient operator permissions and flowrateAllowance. - mutability: nonpayable - access: sender | operator - inputs: - - token: address - - sender: address - - receiver: address - - flowrate: int96 - outputs: - - bool - errors: [CFA_FWD_INVALID_FLOW_RATE] - -# == Low-Level Flow Operations == -# Direct wrappers around CFA functions. These give full control (including userData) -# but require the caller to know whether a flow already exists. -# If sender != msg.sender, the *ByOperator variant is used internally. - -createFlow: - # Create a new flow. Reverts if a flow already exists between sender and receiver. - mutability: nonpayable - access: sender | operator - inputs: - - token: address - - sender: address - - receiver: address - - flowrate: int96 - - userData: bytes - outputs: - - bool - -updateFlow: - # Update an existing flow's rate. Reverts if no flow exists. - mutability: nonpayable - access: sender | operator - inputs: - - token: address - - sender: address - - receiver: address - - flowrate: int96 - - userData: bytes - outputs: - - bool - -deleteFlow: - # Delete an existing flow. Can be called by sender, receiver, or an operator. - # If msg.sender is neither sender nor receiver, deleteFlowByOperator is used. - mutability: nonpayable - access: sender | receiver | operator - inputs: - - token: address - - sender: address - - receiver: address - - userData: bytes - outputs: - - bool - -# == ACL (Operator Permissions) == - -grantPermissions: - # Grant full create/update/delete permissions with max flowrateAllowance to an operator. - # Convenience wrapper — equivalent to updateFlowOperatorPermissions with full control. - mutability: nonpayable - access: anyone # grants on msg.sender's flows - inputs: - - token: address - - flowOperator: address - outputs: - - bool - -revokePermissions: - # Revoke all permissions from an operator. Does not affect existing flows. - mutability: nonpayable - access: anyone # revokes on msg.sender's flows - inputs: - - token: address - - flowOperator: address - outputs: - - bool - -updateFlowOperatorPermissions: - # Set granular operator permissions and flowrate allowance. - notes: - - "Gotcha: flowrateAllowance limits per-flow rate, NOT aggregate net flow." - mutability: nonpayable - access: anyone # grants on msg.sender's flows - inputs: - - token: address - - flowOperator: address - - permissions: uint8 # bitmask: 1=create, 2=update, 4=delete - - flowrateAllowance: int96 - outputs: - - bool - -# == Flow Queries == - -getFlowrate: - mutability: view - inputs: - - token: address - - sender: address - - receiver: address - outputs: - - flowrate: int96 - -getFlowInfo: - mutability: view - inputs: - - token: address - - sender: address - - receiver: address - outputs: - - lastUpdated: uint256 - - flowrate: int96 - - deposit: uint256 - - owedDeposit: uint256 - -getBufferAmountByFlowrate: - # Returns the deposit/buffer required for a given flowrate. - notes: - - "Gotcha: This value is governance-configurable and may change over time. Changes only affect newly created/updated flows." - mutability: view - inputs: - - token: address - - flowrate: int96 - outputs: - - bufferAmount: uint256 - -getAccountFlowrate: - # Net aggregate flowrate for an account (incoming minus outgoing). - mutability: view - inputs: - - token: address - - account: address - outputs: - - flowrate: int96 - -getAccountFlowInfo: - mutability: view - inputs: - - token: address - - account: address - outputs: - - lastUpdated: uint256 - - flowrate: int96 - - deposit: uint256 - - owedDeposit: uint256 - -# == ACL Queries == - -getFlowOperatorPermissions: - mutability: view - inputs: - - token: address - - sender: address - - flowOperator: address - outputs: - - permissions: uint8 - - flowrateAllowance: int96 - -# == Errors == - -errors: - - CFA_FWD_INVALID_FLOW_RATE # flowrate argument was negative diff --git a/.agents/skills/gooddollar/references/contracts/CFAv1Forwarder.selectors.yaml b/.agents/skills/gooddollar/references/contracts/CFAv1Forwarder.selectors.yaml deleted file mode 100644 index f98e21e..0000000 --- a/.agents/skills/gooddollar/references/contracts/CFAv1Forwarder.selectors.yaml +++ /dev/null @@ -1,19 +0,0 @@ -# Generated by scripts/selectors.mjs -functions: - setFlowrate(address,address): 0x2f57fb6f - setFlowrateFrom(address,address,address,int96): 0xc5ad5c1a - createFlow(address,address,address,int96,bytes): 0xe15536b6 - updateFlow(address,address,address,int96,bytes): 0x0c033991 - deleteFlow(address,address,address,bytes): 0xb4b333c6 - grantPermissions(address,address): 0x7243fb93 - revokePermissions(address,address): 0x0bd0728d - updateFlowOperatorPermissions(address,address): 0x42294caf - getFlowrate(address,address,address): 0x1d8b6526 - getFlowInfo(address,address,address): 0x2860fd93 - getBufferAmountByFlowrate(address,int96): 0x09f0b495 - getAccountFlowrate(address,address): 0x22c904d9 - getAccountFlowInfo(address,address): 0x0f1ac495 - getFlowOperatorPermissions(address,address,address): 0x4d3f60f9 -events: -{} -errors: {} diff --git a/.agents/skills/gooddollar/references/contracts/ConstantFlowAgreementV1.abi.yaml b/.agents/skills/gooddollar/references/contracts/ConstantFlowAgreementV1.abi.yaml deleted file mode 100644 index afaec5d..0000000 --- a/.agents/skills/gooddollar/references/contracts/ConstantFlowAgreementV1.abi.yaml +++ /dev/null @@ -1,560 +0,0 @@ -# Superfluid Constant Flow Agreement (CFA) v1 -# Manages continuous per-second token streams between accounts. -# -# NOTE: emits/errors mappings are traced from source code — verify against implementation. -# Proxy/upgradability functions (castrate, updateCode, getCodeAddress, proxiableUUID) -# are omitted — they belong to the UUPSProxiable / AgreementBase layer. -# Pure helpers addPermissions/removePermissions are omitted — they were made public -# for testability only and are not part of the protocol interface. - -meta: - name: ConstantFlowAgreementV1 - version: v1 - source: - - https://raw.githubusercontent.com/superfluid-org/protocol-monorepo/refs/heads/dev/packages/ethereum-contracts/contracts/agreements/ConstantFlowAgreementV1.sol - - https://raw.githubusercontent.com/superfluid-org/protocol-monorepo/refs/heads/dev/packages/ethereum-contracts/contracts/interfaces/agreements/IConstantFlowAgreementV1.sol - - https://raw.githubusercontent.com/superfluid-org/protocol-monorepo/refs/heads/dev/packages/ethereum-contracts/contracts/agreements/AgreementBase.sol - implements: [IConstantFlowAgreementV1, ISuperAgreement] - inherits: [AgreementBase] - deployments: - mainnet: - eth-mainnet: "0x2844c1BBdA121E9E43105630b9C8310e5c72744b" - polygon-mainnet: "0x6EeE6060f715257b970700bc2656De21dEdF074C" - xdai-mainnet: "0xEbdA4ceF883A7B12c4E669Ebc58927FBa8447C7D" - base-mainnet: "0x19ba78B9cDB05A877718841c574325fdB53601bb" - optimism-mainnet: "0x204C6f131bb7F258b2Ea1593f5309911d8E458eD" - arbitrum-one: "0x731FdBB12944973B500518aea61942381d7e240D" - bsc-mainnet: "0x49c38108870e74Cb9420C0991a85D3edd6363F75" - avalanche-c: "0x6946c5B38Ffea373b0a2340b4AEf0De8F6782e58" - celo-mainnet: "0x9d369e78e1a682cE0F8d9aD849BeA4FE1c3bD3Ad" - scroll-mainnet: "0xB3bcD6da1eeB6c97258B3806A853A6dcD3B6C00c" - degenchain: "0x82cc052d1b17aC554a22A88D5876B56c6b51e95c" - testnet: - avalanche-fuji: "0x16843ac25Ccc58Aa7960ba05f61cBB17b36b130A" - base-sepolia: "0x6836F23d6171D74Ef62FcF776655aBcD2bcd62Ef" - eth-sepolia: "0x6836F23d6171D74Ef62FcF776655aBcD2bcd62Ef" - optimism-sepolia: "0x8a3170AdbC67233196371226141736E4151e7C26" - scroll-sepolia: "0xbc46B4Aa41c055578306820013d4B65fff42711E" - deploymentCreationBlocks: - mainnet: - celo-mainnet: 16393492 - -# == Abbreviations == -# 3Ps — Three Periods: liquidation, patrician, and pleb (solvency model) -# ACL — Access Control List (flow operator permissions) -# CFA — Constant Flow Agreement -# ctx — context (Superfluid call context bytes, carries msg.sender and userData) -# GDA — General Distribution Agreement (the other Superfluid agreement) -# PPP — Patrician-Pleb-Pirate (the 3Ps solvency periods) - -# == Glossary == -# flow / stream — continuous per-second token transfer, used interchangeably -# flowRate — tokens per second (int96, wei-denominated); positive = outgoing -# deposit — buffer locked when opening a flow; protects against insolvency -# owed deposit — portion of deposit owed back to the sender by a Super App receiver -# flow operator — an address authorized to create/update/delete flows on behalf of a sender -# flow rate allowance — maximum net flow rate an operator may allocate (int96); decrements on use -# permissions bitmask — uint8: bit 0 = create (1), bit 1 = update (2), bit 2 = delete (4) -# liquidation — closing an insolvent sender's flow; rewards go to the liquidator or bond -# patrician period — grace window after insolvency where reward goes to the bond account -# pleb period — window after patrician where reward goes to the liquidator -# pirate / bailout — state where total deposit cannot cover the deficit; protocol bails out -# Super App — a contract registered with the Host that receives agreement callbacks -# app credit — deposit credit enabling "zero-balance Super Apps" to relay flows -# without pre-funded tokens. 1:1 relay (one in, one out at same rate) -# always works at zero balance. Fan-out (1:N) needs the app to hold -# tokens. Credit is settled as "owed deposit" on the original sender. -# critical — an account whose available balance is negative (eligible for liquidation) -# jailed — a Super App penalized for violating protocol rules; loses callbacks -# -# == Time Conventions == -# Conventional seconds-per-period used in Superfluid apps for flow rate conversion: -# month: 2628000 (365.25 / 12 * 86400) -# year: 31536000 (365 * 86400) -# Flow rate from a monthly amount: flowRate = monthlyAmount / 2628000 -# Flow rate from a yearly amount: flowRate = yearlyAmount / 31536000 - -# == Flow Management == -# Core operations for creating, updating, and deleting token streams. -# Functions with ctx are called through the Host — either via -# Host.callAgreement (single op) or Host.batchCall (operationType 201). -# For batchCall, the data field is abi.encode(callData, userData) where -# callData is the full ABI-encoded function call with an empty ctx ("0x") -# as placeholder. The Host replaces the placeholder with the real context. -# The access field reflects who can initiate the call, not the direct caller. - -createFlow: - # Start a new stream from ctx.msgSender to receiver. - # The deposit amount depends on the governance-configured liquidation period - # and minimum deposit. The lower 32 bits of the deposit are clipped (rounded up). - notes: - - "Gotcha: A deposit is taken as a safety margin for solvency agents." - mutability: nonpayable - access: anyone # flow from ctx.msgSender - inputs: - - token: address - - receiver: address - - flowRate: int96 # must be > 0 - - ctx: bytes - outputs: - - newCtx: bytes - emits: [FlowUpdated, FlowUpdatedExtension] - errors: [CFA_ZERO_ADDRESS_RECEIVER, CFA_NO_SELF_FLOW, CFA_INVALID_FLOW_RATE, CFA_FLOW_ALREADY_EXISTS, CFA_INSUFFICIENT_BALANCE] - -updateFlow: - # Change the flow rate of an existing stream from ctx.msgSender to receiver. - # Note: owedDeposit accumulates when a Super App receiver uses app credit to - # open outgoing streams. The sender bears the deposit cost for those streams. - notes: - - "Gotcha: Deposit is adjusted to match the new flow rate but never refunds owed deposit — that adjustment happens separately via the app credit system." - mutability: nonpayable - access: anyone # flow from ctx.msgSender - inputs: - - token: address - - receiver: address - - flowRate: int96 # must be > 0 - - ctx: bytes - outputs: - - newCtx: bytes - emits: [FlowUpdated, FlowUpdatedExtension] - errors: [CFA_ZERO_ADDRESS_RECEIVER, CFA_NO_SELF_FLOW, CFA_INVALID_FLOW_RATE, CFA_FLOW_DOES_NOT_EXIST, CFA_INSUFFICIENT_BALANCE] - -deleteFlow: - # Stop a stream between sender and receiver. - # During liquidation the reward distribution depends on the solvency period: - # patrician → bond account gets reward; pleb → liquidator gets reward; - # pirate → liquidator gets full single deposit, protocol covers the bailout. - notes: - - "Gotcha: Third-party callers (not sender, receiver, or operator) only succeed if the sender is critical (negative available balance) or either party is jailed." - mutability: nonpayable - access: sender | receiver | operator | anyone(if-critical-or-jailed) - inputs: - - token: address - - sender: address - - receiver: address - - ctx: bytes - outputs: - - newCtx: bytes - emits: [FlowUpdated, FlowUpdatedExtension] - errors: [CFA_ZERO_ADDRESS_SENDER, CFA_ZERO_ADDRESS_RECEIVER, CFA_FLOW_DOES_NOT_EXIST, CFA_NON_CRITICAL_SENDER] - -# == Operator Flow Management == -# Act on behalf of another account. Requires ACL permissions granted by the sender. -# The operator's flow rate allowance is decremented on create/update. -# Functions with ctx are called through the Host. - -createFlowByOperator: - # Create a flow on behalf of sender. Consumes flow rate allowance. - notes: - - "Gotcha: Reverts if ctx.msgSender IS the sender — use createFlow instead." - mutability: nonpayable - access: operator - inputs: - - token: address - - sender: address - - receiver: address - - flowRate: int96 # must be > 0 - - ctx: bytes - outputs: - - newCtx: bytes - emits: [FlowUpdated, FlowUpdatedExtension] - errors: [CFA_ACL_NO_SENDER_CREATE, CFA_ACL_OPERATOR_NO_CREATE_PERMISSIONS, CFA_ACL_FLOW_RATE_ALLOWANCE_EXCEEDED, CFA_ZERO_ADDRESS_RECEIVER, CFA_NO_SELF_FLOW, CFA_INVALID_FLOW_RATE, CFA_FLOW_ALREADY_EXISTS, CFA_INSUFFICIENT_BALANCE] - -updateFlowByOperator: - # Update a flow on behalf of sender. Only consumes allowance if flow rate increases. - # If flowRateAllowance is type(int96).max, it is treated as unlimited. - notes: - - "Gotcha: If the new rate is lower than the old rate, no allowance is consumed." - mutability: nonpayable - access: operator - inputs: - - token: address - - sender: address - - receiver: address - - flowRate: int96 # must be > 0 - - ctx: bytes - outputs: - - newCtx: bytes - emits: [FlowUpdated, FlowUpdatedExtension] - errors: [CFA_ACL_NO_SENDER_UPDATE, CFA_ACL_OPERATOR_NO_UPDATE_PERMISSIONS, CFA_ACL_FLOW_RATE_ALLOWANCE_EXCEEDED, CFA_ZERO_ADDRESS_RECEIVER, CFA_NO_SELF_FLOW, CFA_INVALID_FLOW_RATE, CFA_FLOW_DOES_NOT_EXIST, CFA_INSUFFICIENT_BALANCE] - -deleteFlowByOperator: - # Delete a flow on behalf of sender. Does not consume flow rate allowance. - mutability: nonpayable - access: operator - inputs: - - token: address - - sender: address - - receiver: address - - ctx: bytes - outputs: - - newCtx: bytes - emits: [FlowUpdated, FlowUpdatedExtension] - errors: [CFA_ACL_OPERATOR_NO_DELETE_PERMISSIONS, CFA_ZERO_ADDRESS_SENDER, CFA_ZERO_ADDRESS_RECEIVER, CFA_FLOW_DOES_NOT_EXIST, CFA_NON_CRITICAL_SENDER] - -# == Flow Queries == - -realtimeBalanceOf: - # Compute the real-time CFA balance contribution for an account. - # Returns the dynamic balance delta (flowRate * elapsed), total deposit held, - # and total owed deposit. This is called by the token's realtimeBalanceOfNow - # to assemble the full balance across all agreements. - # To get an account's actual token balance, use SuperToken.realtimeBalanceOfNow - # (or SuperToken.balanceOf for ERC-20 compatible, clamped to zero). - # It can be deeply negative for net-outflow accounts as time progresses. - notes: - - "Gotcha: Returns only the CFA portion of the balance, not the total." - - "Gotcha: The returned dynamicBalance is a delta, not an absolute balance." - mutability: view - inputs: - - token: address - - account: address - - time: uint256 - outputs: - - dynamicBalance: int256 # flowRate * (time - lastUpdate); can be negative - - deposit: uint256 # total deposit locked across all outflows - - owedDeposit: uint256 # total owed deposit from Super App receivers - -getFlow: - # Get flow data between a specific sender-receiver pair. - mutability: view - inputs: - - token: address - - sender: address - - receiver: address - outputs: - - timestamp: uint256 # last update time - - flowRate: int96 - - deposit: uint256 - - owedDeposit: uint256 - -getFlowByID: - # Get flow data using the agreement ID (keccak256 of sender and receiver). - mutability: view - inputs: - - token: address - - flowId: bytes32 # keccak256(abi.encode(sender, receiver)) - outputs: - - timestamp: uint256 - - flowRate: int96 - - deposit: uint256 - - owedDeposit: uint256 - -getAccountFlowInfo: - # Aggregated flow state for an account across all its CFA flows. - mutability: view - inputs: - - token: address - - account: address - outputs: - - timestamp: uint256 # last time any flow was updated for this account - - flowRate: int96 # net flow rate (inflows - outflows) - - deposit: uint256 # sum of deposits across all outflows - - owedDeposit: uint256 # sum of owed deposits across all outflows - -getNetFlow: - # Net flow rate for an account (sum of inflows minus outflows). - mutability: view - inputs: - - token: address - - account: address - outputs: - - flowRate: int96 - -# == ACL Management == -# Manage flow operator permissions and flow rate allowances. -# The caller (ctx.msgSender) is always the permission granter — they control -# who can operate on their own flows. -# Functions with ctx are called through the Host. - -updateFlowOperatorPermissions: - # Set exact permissions and flow rate allowance for a flow operator. - mutability: nonpayable - access: anyone # grants on ctx.msgSender's flows - inputs: - - token: address - - flowOperator: address - - permissions: uint8 # bitmask: 1=create, 2=update, 4=delete - - flowRateAllowance: int96 - - ctx: bytes - outputs: - - newCtx: bytes - emits: [FlowOperatorUpdated] - errors: [CFA_ACL_UNCLEAN_PERMISSIONS, CFA_ACL_NO_SENDER_FLOW_OPERATOR, CFA_ACL_NO_NEGATIVE_ALLOWANCE] - -authorizeFlowOperatorWithFullControl: - # Grant all permissions (create+update+delete) with unlimited allowance. - # Shorthand for updateFlowOperatorPermissions(token, op, 7, type(int96).max, ctx). - mutability: nonpayable - access: anyone # grants on ctx.msgSender's flows - inputs: - - token: address - - flowOperator: address - - ctx: bytes - outputs: - - newCtx: bytes - emits: [FlowOperatorUpdated] - errors: [CFA_ACL_UNCLEAN_PERMISSIONS, CFA_ACL_NO_SENDER_FLOW_OPERATOR, CFA_ACL_NO_NEGATIVE_ALLOWANCE] - -revokeFlowOperatorWithFullControl: - # Revoke all permissions and set allowance to zero. - # Shorthand for updateFlowOperatorPermissions(token, op, 0, 0, ctx). - mutability: nonpayable - access: anyone # revokes on ctx.msgSender's flows - inputs: - - token: address - - flowOperator: address - - ctx: bytes - outputs: - - newCtx: bytes - emits: [FlowOperatorUpdated] - errors: [CFA_ACL_UNCLEAN_PERMISSIONS, CFA_ACL_NO_SENDER_FLOW_OPERATOR, CFA_ACL_NO_NEGATIVE_ALLOWANCE] - -increaseFlowRateAllowance: - # Increase flow rate allowance for an operator by a delta. - # Delegates to increaseFlowRateAllowanceWithPermissions with permissionsToAdd=0. - mutability: nonpayable - access: anyone # ctx.msgSender's allowance - inputs: - - token: address - - flowOperator: address - - addedFlowRateAllowance: int96 - - ctx: bytes - outputs: - - newCtx: bytes - emits: [FlowOperatorUpdated] - errors: [CFA_ACL_UNCLEAN_PERMISSIONS, CFA_ACL_NO_SENDER_FLOW_OPERATOR, CFA_ACL_NO_NEGATIVE_ALLOWANCE] - -decreaseFlowRateAllowance: - # Decrease flow rate allowance for an operator by a delta. - # Delegates to decreaseFlowRateAllowanceWithPermissions with permissionsToRemove=0. - mutability: nonpayable - access: anyone # ctx.msgSender's allowance - inputs: - - token: address - - flowOperator: address - - subtractedFlowRateAllowance: int96 - - ctx: bytes - outputs: - - newCtx: bytes - emits: [FlowOperatorUpdated] - errors: [CFA_ACL_UNCLEAN_PERMISSIONS, CFA_ACL_NO_SENDER_FLOW_OPERATOR, CFA_ACL_NO_NEGATIVE_ALLOWANCE] - -increaseFlowRateAllowanceWithPermissions: - # Increase flow rate allowance and add permission bits in one call. - # permissionsToAdd is OR'd with existing permissions. - mutability: nonpayable - access: anyone # ctx.msgSender's allowance - inputs: - - token: address - - flowOperator: address - - permissionsToAdd: uint8 # bitmask OR'd onto existing permissions - - addedFlowRateAllowance: int96 - - ctx: bytes - outputs: - - newCtx: bytes - emits: [FlowOperatorUpdated] - errors: [CFA_ACL_UNCLEAN_PERMISSIONS, CFA_ACL_NO_SENDER_FLOW_OPERATOR, CFA_ACL_NO_NEGATIVE_ALLOWANCE] - -decreaseFlowRateAllowanceWithPermissions: - # Decrease flow rate allowance and remove permission bits in one call. - # permissionsToRemove is AND-NOT'd from existing permissions. - notes: - - "Gotcha: Reverts if the resulting allowance would go negative." - mutability: nonpayable - access: anyone # ctx.msgSender's allowance - inputs: - - token: address - - flowOperator: address - - permissionsToRemove: uint8 # bitmask AND-NOT'd from existing permissions - - subtractedFlowRateAllowance: int96 - - ctx: bytes - outputs: - - newCtx: bytes - emits: [FlowOperatorUpdated] - errors: [CFA_ACL_UNCLEAN_PERMISSIONS, CFA_ACL_NO_SENDER_FLOW_OPERATOR, CFA_ACL_NO_NEGATIVE_ALLOWANCE] - -# == ACL Queries == - -getFlowOperatorData: - # Get permissions and allowance for a flow operator. - mutability: view - inputs: - - token: address - - sender: address # the permission granter - - flowOperator: address # the permission grantee - outputs: - - flowOperatorId: bytes32 # keccak256(abi.encode("flowOperator", sender, flowOperator)) - - permissions: uint8 # bitmask: 1=create, 2=update, 4=delete - - flowRateAllowance: int96 - -getFlowOperatorDataByID: - # Get permissions and allowance using the pre-computed operator ID. - mutability: view - inputs: - - token: address - - flowOperatorId: bytes32 - outputs: - - permissions: uint8 - - flowRateAllowance: int96 - -# == Solvency Queries == -# Check whether an account is in the patrician period (grace window for liquidation). - -isPatricianPeriodNow: - # Check patrician period status using the Host's current timestamp. - mutability: view - inputs: - - token: address - - account: address - outputs: - - isCurrentlyPatricianPeriod: bool - - timestamp: uint256 # the Host's block.timestamp used for the check - -isPatricianPeriod: - # Check patrician period status at a specific timestamp. - mutability: view - inputs: - - token: address - - account: address - - timestamp: uint256 - outputs: - - bool - -# == Deposit Helpers == - -getMaximumFlowRateFromDeposit: - # Calculate the maximum flow rate achievable with a given deposit. - notes: - - "Gotcha: Deposit is clipped (lower 32 bits zeroed) and rounded down." - mutability: view - inputs: - - token: address # needed to look up liquidation period from governance - - deposit: uint256 - outputs: - - flowRate: int96 - errors: [CFA_DEPOSIT_TOO_BIG] - -getDepositRequiredForFlowRate: - # Calculate the deposit required for a given flow rate. - # Returns max(minimumDeposit, flowRate * liquidationPeriod) with rounding. - mutability: view - inputs: - - token: address # needed to look up liquidation period and minimum deposit - - flowRate: int96 - outputs: - - deposit: uint256 - errors: [CFA_INVALID_FLOW_RATE, CFA_FLOW_RATE_TOO_BIG] - -# == Protocol Constants == - -agreementType: - # Returns keccak256("org.superfluid-finance.agreements.ConstantFlowAgreement.v1") - mutability: pure - outputs: - - bytes32 - -DEFAULT_MINIMUM_DEPOSIT: - # Minimum deposit floor: uint96(1 << 32) ≈ 4.29 * 10^9 wei. - # Governance may set a higher per-token minimum; this is the absolute floor. - mutability: view - outputs: - - uint256 - -MAXIMUM_DEPOSIT: - # Maximum deposit cap: type(int96).max - mutability: view - outputs: - - uint256 - -MAXIMUM_FLOW_RATE: - # Maximum flow rate: type(int96).max - mutability: view - outputs: - - uint256 - -CFA_HOOK_GAS_LIMIT: - # Gas limit for external hook calls (Super App callbacks): 250,000 - mutability: view - outputs: - - uint64 - -# == Events == - -events: - FlowUpdated: - # Emitted on every create, update, and delete flow operation. - # totalSenderFlowRate and totalReceiverFlowRate are the NET flow rates - # after the operation, not the individual flow rate. - notes: - - "Gotcha: Always emitted together with FlowUpdatedExtension." - indexed: - - token: address - - sender: address - - receiver: address - data: - - flowRate: int96 # new rate for this specific flow (0 on delete) - - totalSenderFlowRate: int256 # sender's net flow rate after this operation - - totalReceiverFlowRate: int256 - - userData: bytes - - FlowUpdatedExtension: - # Companion event to FlowUpdated. Carries the operator and new deposit. - # Emitted immediately after FlowUpdated so indexers can correlate them. - indexed: - - flowOperator: address # ctx.msgSender who initiated the operation - data: - - deposit: uint256 # new deposit for this specific flow - - FlowOperatorUpdated: - # Emitted when operator permissions or flow rate allowance change. - indexed: - - token: address - - sender: address # the permission granter - - flowOperator: address # the permission grantee - data: - - permissions: uint8 # updated bitmask - - flowRateAllowance: int96 # updated allowance - - # Inherited events (from AgreementBase / UUPSProxiable): - # CodeUpdated — emitted on proxy upgrade (uuid, codeAddress) - # Initialized — emitted on proxy initialization (version) - -# == Errors == - -errors: - # Flow validation - - CFA_FLOW_ALREADY_EXISTS # createFlow when flow exists - - CFA_FLOW_DOES_NOT_EXIST # update/delete when no flow - - CFA_INVALID_FLOW_RATE # flowRate <= 0 - - CFA_NO_SELF_FLOW # sender == receiver - - CFA_ZERO_ADDRESS_SENDER # sender is address(0) - - CFA_ZERO_ADDRESS_RECEIVER # receiver is address(0) - # Solvency - - CFA_INSUFFICIENT_BALANCE # sender cannot cover deposit - - CFA_NON_CRITICAL_SENDER # third-party delete but sender is solvent - - CFA_DEPOSIT_TOO_BIG # deposit > MAXIMUM_DEPOSIT - - CFA_FLOW_RATE_TOO_BIG # flowRate * liquidationPeriod overflows - # ACL - - CFA_ACL_FLOW_RATE_ALLOWANCE_EXCEEDED # operator exceeds granted allowance - - CFA_ACL_NO_NEGATIVE_ALLOWANCE # resulting allowance would be < 0 - - CFA_ACL_NO_SENDER_CREATE # operator cannot be the sender (use createFlow) - - CFA_ACL_NO_SENDER_FLOW_OPERATOR # cannot set yourself as your own operator - - CFA_ACL_NO_SENDER_UPDATE # operator cannot be the sender (use updateFlow) - - CFA_ACL_OPERATOR_NO_CREATE_PERMISSIONS - - CFA_ACL_OPERATOR_NO_DELETE_PERMISSIONS - - CFA_ACL_OPERATOR_NO_UPDATE_PERMISSIONS - - CFA_ACL_UNCLEAN_PERMISSIONS # permission bits outside valid range - # Super App / Host - - CFA_HOOK_OUT_OF_GAS # Super App callback exceeded gas limit - - APP_RULE: # Super App rule violation - inputs: - - _code: uint256 - - AGREEMENT_BASE_ONLY_HOST # call not routed through the Host contract - # SafeCast (inherited from OpenZeppelin) - - SafeCastOverflowedIntToUint: # int256 value overflows on cast to uint256 - inputs: - - value: int256 - - SafeCastOverflowedUintToInt: # uint256 value overflows on cast to int256 - inputs: - - value: uint256 diff --git a/.agents/skills/gooddollar/references/contracts/ConstantFlowAgreementV1.selectors.yaml b/.agents/skills/gooddollar/references/contracts/ConstantFlowAgreementV1.selectors.yaml deleted file mode 100644 index a929e06..0000000 --- a/.agents/skills/gooddollar/references/contracts/ConstantFlowAgreementV1.selectors.yaml +++ /dev/null @@ -1,33 +0,0 @@ -# Generated by scripts/selectors.mjs -functions: - createFlow(address,address): 0x7deac86a - updateFlow(address,address): 0xb6214437 - deleteFlow(address,address,address,bytes): 0xb4b333c6 - createFlowByOperator(address,address,address): 0x97b0b745 - updateFlowByOperator(address,address,address): 0xaea4dc29 - deleteFlowByOperator(address,address,address,bytes): 0x4c8b181f - realtimeBalanceOf(address,address,uint256): 0x9b2e48bc - getFlow(address,address,address): 0xe6a1e888 - getFlowByID(address): 0x4eccd8ac - getAccountFlowInfo(address,address): 0x0f1ac495 - getNetFlow(address,address): 0xe8e7e2d1 - updateFlowOperatorPermissions(address,address): 0x42294caf - authorizeFlowOperatorWithFullControl(address,address,bytes): 0x54b770e3 - revokeFlowOperatorWithFullControl(address,address,bytes): 0x062e56ec - increaseFlowRateAllowance(address,address,int96,bytes): 0xac5f5d00 - decreaseFlowRateAllowance(address,address,int96,bytes): 0x5f51fb23 - increaseFlowRateAllowanceWithPermissions(address,address): 0x5e6a4dc3 - decreaseFlowRateAllowanceWithPermissions(address,address): 0x8de39d9b - getFlowOperatorData(address): 0x5f13dbbc - getFlowOperatorDataByID(address,bytes32): 0x09d256ef - isPatricianPeriodNow(address,address): 0x4fe9c291 - isPatricianPeriod(address,address,uint256): 0x4b839e0b - getMaximumFlowRateFromDeposit(): 0x4ba52c34 - getDepositRequiredForFlowRate(): 0xcc111b9e - CFA_HOOK_GAS_LIMIT(): 0xbf3fbc28 -events: - FlowUpdated(address,address,address,int256,bytes): 0x8e3b8f31fe09d2ca20fa7f76ec574bc9fea49f16a91f1ca828154ea76e76a20a - FlowUpdatedExtension(): 0x9bf0b3e0199b411ca09607d040b7672430af5dae9d159b715c9f8004c876065f - FlowOperatorUpdated(address): 0x401d2cb05b3db80617d70aabf976f52d2a5dac64298eadeed7a81ad4bb5d4fdd - # Inherited events (from AgreementBase / UUPSProxiable)(): 0xcabfd4ad95e3bb803739ac513717fccee724fc0c5741e01cf84319a96120eefa -errors: {} diff --git a/.agents/skills/gooddollar/references/contracts/GoodDollarOFTAdapter.abi.yaml b/.agents/skills/gooddollar/references/contracts/GoodDollarOFTAdapter.abi.yaml deleted file mode 100644 index c60d498..0000000 --- a/.agents/skills/gooddollar/references/contracts/GoodDollarOFTAdapter.abi.yaml +++ /dev/null @@ -1,100 +0,0 @@ -# GoodDollarOFTAdapter — LayerZero V2 OFT adapter pattern bridging underlying G$ -# Exact bytecode lives in the GoodDollar OFT deployment; this documents the surface agents call. - -meta: - name: GoodDollarOFTAdapter - version: LayerZero-OFT-adapter (generic) - source: - - https://docs.layerzero.network/ - - https://github.com/LayerZero-Labs/devtools - note: > - Flow: optional peers(dstEid) check -> approve underlying to minterBurner if - MessagingFee, refundAddress) paying nativeFee in msg.value when applicable. - SendParam mirrors LayerZero OFT: dstEid, to (bytes32 padded recipient), - amountLD, minAmountLD, extraOptions, composeMsg, oftCmd. - Verify tuple field order and OFT revision against your deployed artifact before mainnet use. - Event names and topic0 hashes vary by OFT package version — pull from the deployment ABI. - related: - - references/guides/bridge.md - -token: - mutability: view - inputs: [] - outputs: - - underlyingToken: address - -minterBurner: - notes: - - "Underlying G$ must approve this spender when burning for cross-chain send." - mutability: view - inputs: [] - outputs: - - minterBurner: address - -oftVersion: - mutability: view - inputs: [] - outputs: - - interfaceId: bytes4 - - version: uint64 - -peers: - notes: - - "Returns bytes32 peer address configured for destination endpoint id." - mutability: view - inputs: - - dstEid: uint32 - outputs: - - peer: bytes32 - -endpoint: - mutability: view - inputs: [] - outputs: - - lzEndpoint: address - -owner: - mutability: view - inputs: [] - outputs: - - account: address - -quoteSend: - notes: - - "Simulates messaging + bridge fee; use nativeFee as msg.value on send when paying in native gas token." - mutability: view - inputs: - - sendParam: SendParam - - payInLzToken: bool - outputs: - - nativeFee: uint256 - - lzTokenFee: uint256 - errors: - - NO_PEER - - LZ_INVALID_OPTIONS - -send: - notes: - - "Payable: include MessagingFee.nativeFee in msg.value when fee is native." - - "Consumes sendParam.amountLD from sender on source chain and emits cross-chain message to dstEid peer." - - "sendParam.to must be destination receiver encoded as bytes32." - mutability: payable - access: sender - inputs: - - sendParam: SendParam - - fee: MessagingFee - - refundAddress: address - outputs: - - msgReceipt: MessageReceipt - - oftReceipt: OFTReceipt - errors: - - NO_PEER - - SLIPPAGE_OR_AMOUNT - - LZ_INVALID_OPTIONS - -events: {} - -errors: - NO_PEER: "Destination peer not configured for dstEid." - LZ_INVALID_OPTIONS: "Composer/options payload rejected by LayerZero." - SLIPPAGE_OR_AMOUNT: "Bridged amount violates minAmount or available balance." diff --git a/.agents/skills/gooddollar/references/contracts/GoodDollarOFTAdapter.selectors.yaml b/.agents/skills/gooddollar/references/contracts/GoodDollarOFTAdapter.selectors.yaml deleted file mode 100644 index e5615a1..0000000 --- a/.agents/skills/gooddollar/references/contracts/GoodDollarOFTAdapter.selectors.yaml +++ /dev/null @@ -1,12 +0,0 @@ -# Generated by scripts/selectors.mjs -functions: - token(): 0xfc0c546a - minterBurner(): 0x2ef8c5a4 - approvalRequired(): 0x9f68b964 - oftVersion(): 0x156a0d0f - peers(uint32): 0xbb0b6a53 - endpoint(): 0x5e280f11 - owner(): 0x8da5cb5b -events: -{} -errors: {} diff --git a/.agents/skills/gooddollar/references/contracts/GooddollarSavingsStream.abi.yaml b/.agents/skills/gooddollar/references/contracts/GooddollarSavingsStream.abi.yaml deleted file mode 100644 index d736bc1..0000000 --- a/.agents/skills/gooddollar/references/contracts/GooddollarSavingsStream.abi.yaml +++ /dev/null @@ -1,210 +0,0 @@ -# GooddollarSavingsStream (Ubeswap) — G$ native Super Token stake with Superfluid GDA reward stream - -meta: - name: GooddollarSavingsStream - version: "1" - source: - - https://raw.githubusercontent.com/Ubeswap/gooddollar-contracts/main/contracts/GooddollarSavingsStream.sol - - https://raw.githubusercontent.com/Ubeswap/gooddollar-contracts/main/contracts/interfaces/IGooddollarSavingsStream.sol - - https://raw.githubusercontent.com/Ubeswap/gooddollar-contracts/main/contracts/StakingVault.sol - inherits: - - IGooddollarSavingsStream - - Ownable - - ERC2771Context - - ReentrancyGuard - note: > - Celo production savings. Staked principal sits in StakingVault; this contract holds reward - balance and streams via a Superfluid GDA distribution pool (`distributeFlow`). Effective rate is - min(rewardRate, maxRewardRatePerToken * totalSupply / 1e18), throttled when reward balance is low. - Staking token is the G$ native Super Token (`superToken`). Fuse->CELO migration uses `stakeFor` - after bridge. Ubeswap lists this as Celo mainnet savings (streaming). - deployments: - mainnet: - production-celo: - GooddollarSavingsStream: - networkId: 42220 - address: "0x059ee811414230d1Fb157878D2b491240F4D8d3B" - creationBlock: 66685884 - related: - - https://github.com/Ubeswap/gooddollar-contracts/blob/main/README.md - - https://celoscan.io/address/0x059ee811414230d1Fb157878D2b491240F4D8d3B - - references/contracts/SuperToken.abi.yaml - - references/guides/migrate-fuse-staking-to-celo-savings.md - - references/deep-researches/fuse-to-celo-staking-migration.md - -totalSupply: - mutability: view - inputs: [] - outputs: - - supply: uint256 - -balanceOf: - mutability: view - inputs: - - account: address - outputs: - - balance: uint256 - -getDailyRewards: - mutability: view - inputs: [] - outputs: - - daily: uint256 - -getEffectiveFlowRate: - notes: - - "Returns 0 when totalSupply is 0, rewardRate is 0, or reward balance cannot sustain MIN_STREAM_BUFFER_SECONDS." - - "Otherwise min(global rewardRate, APR cap) as int96 for Superfluid distributeFlow." - mutability: view - inputs: [] - outputs: - - flowRate: int96 - -periodFinish: - notes: - - "Estimated timestamp when current reward balance is drained at getEffectiveFlowRate; 0 if not streaming." - mutability: view - inputs: [] - outputs: - - finish: uint256 - -getUnits: - mutability: view - inputs: - - account: address - outputs: - - units: uint128 - -getTotalUnits: - mutability: view - inputs: [] - outputs: - - units: uint128 - -stake: - notes: - - "Pulls G$ Super Token from msg.sender, deposits principal to StakingVault, updates GDA pool units, syncFlowRate." - - "Requires prior superToken.approve(this, amount)." - mutability: nonpayable - access: anyone - inputs: - - amount: uint256 - outputs: [] - emits: [Staked] - -stakeFor: - notes: - - "Migrator path: caller funds transfer; stake credits `_balances[recipient]` and pool units for recipient." - - "recipient must not be zero, this, superToken, or vault." - - "Used after Fuse->CELO bridge when backend wallet holds bridged G$." - mutability: nonpayable - access: anyone - inputs: - - amount: uint256 - - recipient: address - outputs: [] - emits: [Staked] - -withdraw: - notes: - - "Reduces stake and pool units, syncFlowRate, then vault.withdraw to msg.sender." - mutability: nonpayable - access: anyone - inputs: - - amount: uint256 - outputs: [] - emits: [Withdrawn] - -exit: - notes: - - "Full withdraw of caller principal via withdraw(balance)." - mutability: nonpayable - access: anyone - inputs: [] - outputs: [] - emits: [Withdrawn] - -addToReward: - notes: - - "Pulls reward Super Token from caller; re-syncs flow rate when balance was throttling the stream." - mutability: nonpayable - access: anyone - inputs: - - reward: uint256 - outputs: [] - emits: [RewardAdded] - -syncFlowRate: - notes: - - "Permissionless; call when tokens were sent directly to the contract so distributeFlow picks up balance." - mutability: nonpayable - access: anyone - inputs: [] - outputs: [] - emits: [FlowRateUpdated] - -setDailyRewards: - mutability: nonpayable - access: owner - inputs: - - _dailyRewards: uint256 - outputs: [] - emits: [DailyRewardsUpdated] - -setMaxRewardRatePerToken: - mutability: nonpayable - access: owner - inputs: - - _value: uint256 - outputs: [] - emits: [MaxRewardRateUpdated] - -recoverERC20: - notes: - - "Cannot recover the G$ Super Token (staking/reward asset)." - mutability: nonpayable - access: owner - inputs: - - tokenAddress: address - - tokenAmount: uint256 - outputs: [] - emits: [Recovered] - -events: - Staked: - indexed: - - user: address - data: - - amount: uint256 - Withdrawn: - indexed: - - user: address - data: - - amount: uint256 - RewardAdded: - data: - - reward: uint256 - DailyRewardsUpdated: - data: - - rewardRate: uint256 - - givenDailyRewards: uint256 - MaxRewardRateUpdated: - data: - - newMaxRate: uint256 - FlowRateUpdated: - data: - - newFlowRate: int96 - Recovered: - indexed: - - token: address - data: - - amount: uint256 - - receiver: address - -errors: - - CannotStakeZero - - CannotWithdrawZero - - InsufficientStake - - InvalidAddress - - NoRewardToAdd - - CannotRecoverStakingToken diff --git a/.agents/skills/gooddollar/references/contracts/GooddollarSavingsStream.selectors.yaml b/.agents/skills/gooddollar/references/contracts/GooddollarSavingsStream.selectors.yaml deleted file mode 100644 index f04d75a..0000000 --- a/.agents/skills/gooddollar/references/contracts/GooddollarSavingsStream.selectors.yaml +++ /dev/null @@ -1,27 +0,0 @@ -# Generated by scripts/selectors.mjs -functions: - totalSupply(): 0x18160ddd - balanceOf(address): 0x70a08231 - getDailyRewards(): 0x68527008 - getEffectiveFlowRate(): 0xa2efe857 - periodFinish(): 0xebe2b12b - getUnits(address): 0x0fefbc09 - getTotalUnits(): 0xa754a702 - stake(uint256): 0xa694fc3a - stakeFor(uint256,address): 0x51746bb2 - withdraw(uint256): 0x2e1a7d4d - exit(): 0xe9fad8ee - addToReward(uint256): 0x2ce618fa - syncFlowRate(): 0x0e83284a - setDailyRewards(uint256): 0x4adef718 - setMaxRewardRatePerToken(uint256): 0x6a03a9e2 - recoverERC20(address,uint256): 0x8980f11f -events: - Staked(address,uint256): 0x9e71bc8eea02a63969f509818f2dafb9254532904319f9dbda79b67bd34a5f3d - Withdrawn(address,uint256): 0x7084f5476618d8e60b11ef0d7d3f06914655adb8793e28ff7f018d4c76d505d5 - RewardAdded(uint256): 0xde88a922e0d3b88b24e9623efeb464919c6bf9f66857a65e2bfcf2ce87a9433d - DailyRewardsUpdated(uint256,uint256): 0x54f5b7ef058007cebca11af0127cd80c0bac4e968788eabb3c1e70d1bfb78edd - MaxRewardRateUpdated(uint256): 0x9041b23d05af9bceefc73becffefd1887907ad55c3d6c6655230b37ef87dbb07 - FlowRateUpdated(int96): 0xd02fcf6b96acb60ac68942c7d5075e11a8a0b38cc865c1916934f4e1f129ded0 - Recovered(address,uint256,address): 0xb197f0a554c4d7840105e6ae65f0e275e9e8605a969dffa8caa7f1f118a2e1f5 -errors: {} diff --git a/.agents/skills/gooddollar/references/contracts/GovernanceStakingV2.abi.yaml b/.agents/skills/gooddollar/references/contracts/GovernanceStakingV2.abi.yaml deleted file mode 100644 index 5adccb3..0000000 --- a/.agents/skills/gooddollar/references/contracts/GovernanceStakingV2.abi.yaml +++ /dev/null @@ -1,202 +0,0 @@ -# GovernanceStakingV2 (Fuse) — G$ staking share token with GDAO reward accrual -# Deployment key in GoodProtocol release metadata is GovernanceStakingV2. - -meta: - name: GovernanceStakingV2 - version: "2" - source: - - https://raw.githubusercontent.com/GoodDollar/GoodProtocol/master/contracts/governance/GovernanceStaking.sol - - https://raw.githubusercontent.com/GoodDollar/GoodProtocol/master/releases/deployment.json - inherits: - - ERC20Upgradeable - - MultiBaseGovernanceShareField - - DAOUpgradeableContract - - ReentrancyGuardUpgradeable - note: > - Fuse governance staking contract where users stake G$ and receive staking shares (`sG$`) with - GDAO-style rewards minted on reward withdrawal paths. `withdrawStake(0)` means full unstake. - In GoodProtocol `releases/deployment.json` this address is listed as GovernanceStakingV2 on Fuse `production`. - This is the old staking contract in Fuse->CELO migration flows. - deployments: - mainnet: - production: - GovernanceStakingV2: - networkId: 122 - address: "0xB7C3e738224625289C573c54d402E9Be46205546" - creationBlock: 15956809 - related: - - references/guides/migrate-fuse-staking-to-celo-savings.md - - references/deep-researches/fuse-to-celo-staking-migration.md - -getChainBlocksPerMonth: - mutability: pure - inputs: [] - outputs: - - blocks: uint256 - -stake: - notes: - - "Requires prior G$ ERC20 approval to staking contract." - - "Mints staking share token and updates reward productivity before event emission." - mutability: nonpayable - access: anyone - inputs: - - _amount: uint256 - outputs: [] - emits: [Staked] - -withdrawStake: - notes: - - "If _amount is 0, contract interprets it as full user unstake." - - "Burns staking shares, updates productivity, mints pending rewards, then transfers G$ out." - mutability: nonpayable - access: anyone - inputs: - - _amount: uint256 - outputs: [] - emits: [StakeWithdraw] - -withdrawRewards: - notes: - - "Claims rewards without changing staked principal." - mutability: nonpayable - access: anyone - inputs: [] - outputs: - - minted: uint256 - emits: [ReputationEarned] - -setMonthlyRewards: - notes: - - "DAO-controlled update of rewardsPerBlock schedule via avatar authorization." - mutability: nonpayable - access: avatar - inputs: - - _monthlyAmount: uint256 - outputs: [] - -getRewardsPerBlock: - mutability: view - inputs: [] - outputs: - - amount: uint256 - -getProductivity: - mutability: view - inputs: - - _user: address - outputs: - - productivity: uint256 - - rewardDebt: uint256 - -getUserPendingReward: - mutability: view - inputs: - - _user: address - outputs: - - pending: uint256 - -users: - notes: - - "UserInfo getter for internal staking productivity record." - mutability: view - inputs: - - _user: address - outputs: - - amount: uint256 - - rewardDebt: uint256 - -totalRewardsPerShare: - mutability: view - inputs: [] - outputs: - - value: uint256 - -decimals: - mutability: view - inputs: [] - outputs: - - d: uint8 - -totalSupply: - mutability: view - inputs: [] - outputs: - - supply: uint256 - -balanceOf: - mutability: view - inputs: - - account: address - outputs: - - balance: uint256 - -allowance: - mutability: view - inputs: - - owner: address - - spender: address - outputs: - - amount: uint256 - -approve: - mutability: nonpayable - access: anyone - inputs: - - spender: address - - amount: uint256 - outputs: - - ok: bool - emits: [Approval] - -transfer: - mutability: nonpayable - access: anyone - inputs: - - to: address - - amount: uint256 - outputs: - - ok: bool - emits: [Transfer] - -transferFrom: - mutability: nonpayable - access: anyone - inputs: - - from: address - - to: address - - amount: uint256 - outputs: - - ok: bool - emits: [Transfer, Approval] - -events: - ReputationEarned: - indexed: - - staker: address - data: - - amount: uint256 - Staked: - indexed: - - staker: address - data: - - amount: uint256 - StakeWithdraw: - indexed: - - staker: address - data: - - amount: uint256 - Transfer: - indexed: - - from: address - - to: address - data: - - value: uint256 - Approval: - indexed: - - owner: address - - spender: address - data: - - value: uint256 - -errors: {} diff --git a/.agents/skills/gooddollar/references/contracts/GovernanceStakingV2.selectors.yaml b/.agents/skills/gooddollar/references/contracts/GovernanceStakingV2.selectors.yaml deleted file mode 100644 index 37388ba..0000000 --- a/.agents/skills/gooddollar/references/contracts/GovernanceStakingV2.selectors.yaml +++ /dev/null @@ -1,26 +0,0 @@ -# Generated by scripts/selectors.mjs -functions: - getChainBlocksPerMonth(): 0x213b329e - stake(uint256): 0xa694fc3a - withdrawStake(uint256): 0x25d5971f - withdrawRewards(): 0xc7b8981c - setMonthlyRewards(uint256): 0xc76279a2 - getRewardsPerBlock(): 0x0c1cd7f3 - getProductivity(address): 0x28e964e9 - getUserPendingReward(address): 0xc6710629 - users(address): 0xa87430ba - totalRewardsPerShare(): 0xbf8e9b6e - decimals(): 0x313ce567 - totalSupply(): 0x18160ddd - balanceOf(address): 0x70a08231 - allowance(address,address): 0xdd62ed3e - approve(address,uint256): 0x095ea7b3 - transfer(address,uint256): 0xa9059cbb - transferFrom(address,address,uint256): 0x23b872dd -events: - ReputationEarned(address,uint256): 0x43848d0574703c28d68ae8958e0571521618f60c4bcacfb094cff2156eaae0f1 - Staked(address,uint256): 0x9e71bc8eea02a63969f509818f2dafb9254532904319f9dbda79b67bd34a5f3d - StakeWithdraw(address,uint256): 0x1248d48e2de900a1010c7fce73506969ecec243600bfc08b641b158f26d857cd - Transfer(address,address,uint256): 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef - Approval(address,address,uint256): 0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925 -errors: {} diff --git a/.agents/skills/gooddollar/references/contracts/IdentityV3.abi.yaml b/.agents/skills/gooddollar/references/contracts/IdentityV3.abi.yaml deleted file mode 100644 index aea2efe..0000000 --- a/.agents/skills/gooddollar/references/contracts/IdentityV3.abi.yaml +++ /dev/null @@ -1,390 +0,0 @@ -# IdentityV3 — whitelist, blacklist, DID, and connected-account graph for GoodDollar -# UBI eligibility uses getWhitelistedRoot; connectAccount links extra wallets to a root. - -meta: - name: IdentityV3 - version: v3 - source: - - https://raw.githubusercontent.com/GoodDollar/GoodProtocol/master/contracts/identity/IdentityV3.sol - inherits: - - DAOUpgradeableContract - - AccessControlUpgradeable - - PausableUpgradeable - - EIP712Upgradeable - note: > - isWhitelisted enforces authenticationPeriod against dateAuthenticated and status==1, - with fallback to oldIdentity. getWhitelistedRoot returns the root address for a - connected wallet or the wallet itself when directly whitelisted. - deployments: - mainnet: - production: - Identity: - networkId: 122 - address: "0x2F9C28de9e6d44b71B91b8BA337A5D82e308E7BE" - creationBlock: 22022901 - IdentityOld: - networkId: 122 - address: "0xFa8d865A962ca8456dF331D78806152d3aC5B84F" - creationBlock: 6246324 - production-celo: - Identity: - networkId: 42220 - address: "0xC361A6E67822a0EDc17D899227dd9FC50BD62F42" - creationBlock: 17237952 - production-xdc: - Identity: - networkId: 50 - address: "0x27a4a02C9ed591E1a86e2e5D05870292c34622C9" - creationBlock: 95143058 - related: - - https://docs.gooddollar.org/for-developers/core-contracts/identity - - https://docs.gooddollar.org/user-guides/connect-another-wallet-address-to-identity - -initialize: - mutability: nonpayable - access: initializer - inputs: - - _owner: address - - _oldIdentity: address - outputs: [] - -initDAO: - notes: - - "Wires NameService via setDAO and transfers DEFAULT_ADMIN_ROLE, PAUSER_ROLE, IDENTITY_ADMIN_ROLE to avatar." - mutability: nonpayable - access: DEFAULT_ADMIN_ROLE - inputs: - - _ns: address - outputs: [] - errors: [ALREADY_INITIALIZED] - -setAuthenticationPeriod: - mutability: nonpayable - access: avatar - inputs: - - period: uint256 - outputs: [] - errors: [WHEN_NOT_PAUSED_REVERT] - -authenticate: - notes: - - "Public wrapper; forwards to authenticateWithTimestamp(account, block.timestamp)." - mutability: nonpayable - inputs: - - account: address - outputs: [] - -authenticateWithTimestamp: - mutability: nonpayable - access: IDENTITY_ADMIN_ROLE - inputs: - - account: address - - timestamp: uint256 - outputs: [] - emits: [WhitelistedAuthenticated] - errors: [NOT_WHITELISTED_STATUS, WHEN_NOT_PAUSED_REVERT] - -addWhitelisted: - mutability: nonpayable - access: IDENTITY_ADMIN_ROLE - inputs: - - account: address - outputs: [] - emits: [WhitelistedAdded] - errors: [ALREADY_HAS_STATUS, WHEN_NOT_PAUSED_REVERT] - -addWhitelistedWithDIDAndChain: - mutability: nonpayable - access: IDENTITY_ADMIN_ROLE - inputs: - - account: address - - did: string - - orgChain: uint256 - - dateAuthenticated: uint256 - outputs: [] - emits: [WhitelistedAdded] - errors: [DID_ALREADY_REGISTERED, ALREADY_HAS_STATUS, WHEN_NOT_PAUSED_REVERT] - -addWhitelistedWithDID: - mutability: nonpayable - access: IDENTITY_ADMIN_ROLE - inputs: - - account: address - - did: string - outputs: [] - emits: [WhitelistedAdded] - errors: [DID_ALREADY_REGISTERED, ALREADY_HAS_STATUS, WHEN_NOT_PAUSED_REVERT] - -removeWhitelisted: - mutability: nonpayable - access: IDENTITY_ADMIN_ROLE - inputs: - - account: address - outputs: [] - emits: [WhitelistedRemoved] - errors: [WHEN_NOT_PAUSED_REVERT] - -renounceWhitelisted: - mutability: nonpayable - access: whitelisted sender - inputs: [] - outputs: [] - emits: [WhitelistedRemoved] - errors: [NOT_WHITELISTED_SENDER, WHEN_NOT_PAUSED_REVERT] - -isWhitelisted: - notes: - - "Combines local Identity record with optional oldIdentity.isWhitelisted try/catch." - mutability: view - inputs: - - account: address - outputs: - - ok: bool - -lastAuthenticated: - mutability: view - inputs: - - account: address - outputs: - - ts: uint256 - -addBlacklisted: - mutability: nonpayable - access: IDENTITY_ADMIN_ROLE - inputs: - - account: address - outputs: [] - emits: [BlacklistAdded, WhitelistedRemoved] - errors: [WHEN_NOT_PAUSED_REVERT] - -removeBlacklisted: - mutability: nonpayable - access: IDENTITY_ADMIN_ROLE - inputs: - - account: address - outputs: [] - emits: [BlacklistRemoved] - errors: [WHEN_NOT_PAUSED_REVERT] - -addContract: - mutability: nonpayable - access: IDENTITY_ADMIN_ROLE - inputs: - - account: address - outputs: [] - emits: [ContractAdded] - errors: [NOT_CONTRACT, ALREADY_HAS_STATUS, WHEN_NOT_PAUSED_REVERT] - -removeContract: - mutability: nonpayable - access: IDENTITY_ADMIN_ROLE - inputs: - - account: address - outputs: [] - emits: [ContractRemoved] - errors: [WHEN_NOT_PAUSED_REVERT] - -isDAOContract: - mutability: view - inputs: - - account: address - outputs: - - ok: bool - -isBlacklisted: - mutability: view - inputs: - - account: address - outputs: - - ok: bool - -connectAccount: - notes: - - "Caller must be whitelisted; target must not already be whitelisted or blacklisted; stores connectedAccounts[account]=msg.sender." - mutability: nonpayable - access: whitelisted sender - inputs: - - account: address - outputs: [] - emits: [AccountConnected] - errors: [INVALID_ACCOUNT_FOR_CONNECT, ALREADY_CONNECTED, WHEN_NOT_PAUSED_REVERT] - -disconnectAccount: - notes: - - "Caller must be either the linked root or the connected wallet." - mutability: nonpayable - inputs: - - connected: address - outputs: [] - emits: [AccountDisconnected] - errors: [UNAUTHORIZED_DISCONNECT] - -getWhitelistedRoot: - notes: - - "Returns account if directly whitelisted; returns connected root if connected account is whitelisted; else zero." - mutability: view - inputs: - - account: address - outputs: - - whitelisted: address - -pause: - mutability: nonpayable - access: PAUSER_ROLE - inputs: - - toPause: bool - outputs: [] - -setDID: - mutability: nonpayable - inputs: - - account: address - - did: string - outputs: [] - errors: [NOT_AUTHORIZED_SET_DID, NOT_WHITELISTED_FOR_DID, DID_EMPTY, DID_ALREADY_REGISTERED, DID_ALREADY_REGISTERED_OLD, WHEN_NOT_PAUSED_REVERT] - -addrToDID: - mutability: view - inputs: - - account: address - outputs: - - did: string - -getWhitelistedOnChainId: - mutability: view - inputs: - - account: address - outputs: - - chainId: uint256 - -isRegistered: - notes: - - "Compatibility shim; always returns true." - mutability: pure - inputs: [] - outputs: - - ok: bool - -IDENTITY_ADMIN_ROLE: - mutability: view - inputs: [] - outputs: - - role: bytes32 - -PAUSER_ROLE: - mutability: view - inputs: [] - outputs: - - role: bytes32 - -TYPED_STRUCTURE: - mutability: view - inputs: [] - outputs: - - schema: string - -whitelistedCount: - mutability: view - inputs: [] - outputs: - - n: uint256 - -whitelistedContracts: - mutability: view - inputs: [] - outputs: - - n: uint256 - -authenticationPeriod: - mutability: view - inputs: [] - outputs: - - seconds: uint256 - -identities: - mutability: view - inputs: - - account: address - outputs: - - dateAuthenticated: uint256 - - dateAdded: uint256 - - did: string - - whitelistedOnChainId: uint256 - - status: uint8 - -didHashToAddress: - mutability: view - inputs: - - hash: bytes32 - outputs: - - account: address - -connectedAccounts: - mutability: view - inputs: - - account: address - outputs: - - root: address - -oldIdentity: - mutability: view - inputs: [] - outputs: - - addr: address - -events: - BlacklistAdded: - indexed: - - account: address - data: [] - BlacklistRemoved: - indexed: - - account: address - data: [] - WhitelistedAdded: - indexed: - - account: address - data: [] - WhitelistedRemoved: - indexed: - - account: address - data: [] - WhitelistedAuthenticated: - indexed: - - account: address - data: - - timestamp: uint256 - ContractAdded: - indexed: - - account: address - data: [] - ContractRemoved: - indexed: - - account: address - data: [] - AccountConnected: - indexed: - - connected: address - - to: address - data: [] - AccountDisconnected: - indexed: - - disconnected: address - - from: address - data: [] - -errors: - ALREADY_INITIALIZED: "already initialized — initDAO twice." - NOT_WHITELISTED_STATUS: "not whitelisted — authenticateWithTimestamp." - NOT_WHITELISTED_SENDER: "not whitelisted — renounceWhitelisted modifier." - NOT_WHITELISTED_FOR_DID: "not whitelisted — setDID internal." - ALREADY_HAS_STATUS: "already has status — _addWhitelisted." - DID_ALREADY_REGISTERED: "DID already registered — _addWhitelistedWithDID or _setDID." - DID_ALREADY_REGISTERED_OLD: "DID already registered oldIdentity — _setDID conflict path." - NOT_CONTRACT: "Given address is not a contract — addContract." - INVALID_ACCOUNT_FOR_CONNECT: "invalid account — connectAccount target checks." - ALREADY_CONNECTED: "already connected — connectAccount." - UNAUTHORIZED_DISCONNECT: "unauthorized — disconnectAccount." - NOT_AUTHORIZED_SET_DID: "not authorized — setDID caller." - DID_EMPTY: "did empty — _setDID." - WHEN_NOT_PAUSED_REVERT: "OpenZeppelin Pausable whenNotPaused on gated calls." diff --git a/.agents/skills/gooddollar/references/contracts/IdentityV3.selectors.yaml b/.agents/skills/gooddollar/references/contracts/IdentityV3.selectors.yaml deleted file mode 100644 index 9b53f00..0000000 --- a/.agents/skills/gooddollar/references/contracts/IdentityV3.selectors.yaml +++ /dev/null @@ -1,49 +0,0 @@ -# Generated by scripts/selectors.mjs -functions: - initialize(address,address): 0x485cc955 - initDAO(address): 0x2b14dda8 - setAuthenticationPeriod(uint256): 0xfff930d4 - authenticate(address): 0x08e0d29d - authenticateWithTimestamp(address,uint256): 0x96a1ef79 - addWhitelisted(address): 0x10154bad - addWhitelistedWithDIDAndChain(address,string,uint256,uint256): 0xe737031a - addWhitelistedWithDID(address,string): 0x1b027099 - removeWhitelisted(address): 0x291d9549 - renounceWhitelisted(): 0xd6cd9473 - isWhitelisted(address): 0x3af32abf - lastAuthenticated(address): 0xe1e360ba - addBlacklisted(address): 0x188efc16 - removeBlacklisted(address): 0xc6a276c2 - addContract(address): 0x5f539d69 - removeContract(address): 0xc375c2ef - isDAOContract(address): 0xc73cc4ae - isBlacklisted(address): 0xfe575a87 - connectAccount(address): 0xd21685f4 - disconnectAccount(address): 0x37a1a987 - getWhitelistedRoot(address): 0x2d0e9b46 - pause(bool): 0x02329a29 - setDID(address,string): 0xd3262816 - addrToDID(address): 0x54f9f7a3 - getWhitelistedOnChainId(address): 0xa061922d - isRegistered(): 0x22366844 - IDENTITY_ADMIN_ROLE(): 0x1aaff63c - PAUSER_ROLE(): 0xe63ab1e9 - TYPED_STRUCTURE(): 0x2cec5330 - whitelistedCount(): 0xb2a1de22 - whitelistedContracts(): 0xb30f7e7f - authenticationPeriod(): 0x31b376e2 - identities(address): 0xf653b81e - didHashToAddress(bytes32): 0x67c75937 - connectedAccounts(address): 0x61320040 - oldIdentity(): 0x4125f0f2 -events: - BlacklistAdded(address): 0x44d5fe68b00f68950fb9c1ff0a61ef7f747b1a36359a7e3a7f3324db4b878967 - BlacklistRemoved(address): 0x1747ca720b1a174a464b6513ace29b1d3190b5f632b9f34147017c81425bfde8 - WhitelistedAdded(address): 0xee1504a83b6d4a361f4c1dc78ab59bfa30d6a3b6612c403e86bb01ef2984295f - WhitelistedRemoved(address): 0x270d9b30cf5b0793bbfd54c9d5b94aeb49462b8148399000265144a8722da6b6 - WhitelistedAuthenticated(address,uint256): 0xb2a82fce6d8c7a633efe9579f77b4edb96bfdf171a49bfc2ce666dc543a1f500 - ContractAdded(address): 0x89c66952b48f3e96bf1d8ba1b63189520fd988a6979b8b740bd5c5d8dc53e205 - ContractRemoved(address): 0x8d30d41865a0b811b9545d879520d2dde9f4cc49e4241f486ad9752bc904b565 - AccountConnected(address,address): 0x18f7736ef54539debd9afd3c9500b106e12ae7c70e685f5a5efd727b1ce1d54c - AccountDisconnected(address,address): 0x7cdef5f9c5cb8ce728661ede956fef26cb91eb4d7d2180cc041b73f9fef568d2 -errors: {} diff --git a/.agents/skills/gooddollar/references/contracts/IdentityV4.abi.yaml b/.agents/skills/gooddollar/references/contracts/IdentityV4.abi.yaml deleted file mode 100644 index 485254d..0000000 --- a/.agents/skills/gooddollar/references/contracts/IdentityV4.abi.yaml +++ /dev/null @@ -1,424 +0,0 @@ -# IdentityV4 — whitelist, blacklist, DID, connected accounts, and reverification schedule -# isWhitelisted uses shouldReverify against reverifyDaysOptions and authCount; oldIdentity fallback preserved. - -meta: - name: IdentityV4 - version: v4 - source: - - https://raw.githubusercontent.com/GoodDollar/GoodProtocol/master/contracts/identity/IdentityV4.sol - inherits: - - DAOUpgradeableContract - - AccessControlUpgradeable - - PausableUpgradeable - - EIP712Upgradeable - note: > - authenticationPeriod() returns the largest reverify interval in days (last entry of reverifyDaysOptions), - not seconds. isWhitelisted is false when shouldReverify is true for the current elapsed days since - dateAuthenticated. Post-upgrade, accounts with dateAuthenticated before 1772697574 are treated as - having authCount at the last schedule step for reverify logic. - deployments: - mainnet: - production: - Identity: - networkId: 122 - address: "0x2F9C28de9e6d44b71B91b8BA337A5D82e308E7BE" - creationBlock: 22022901 - production-celo: - Identity: - networkId: 42220 - address: "0xC361A6E67822a0EDc17D899227dd9FC50BD62F42" - creationBlock: 17237952 - production-xdc: - Identity: - networkId: 50 - address: "0x27a4a02C9ed591E1a86e2e5D05870292c34622C9" - creationBlock: 95143058 - related: - - https://docs.gooddollar.org/for-developers/core-contracts/identity - - https://docs.gooddollar.org/user-guides/connect-another-wallet-address-to-identity - -initialize: - mutability: nonpayable - access: initializer - inputs: - - _owner: address - - _oldIdentity: address - outputs: [] - -initDAO: - notes: - - "Wires NameService via setDAO and transfers DEFAULT_ADMIN_ROLE, PAUSER_ROLE, IDENTITY_ADMIN_ROLE to avatar." - mutability: nonpayable - access: DEFAULT_ADMIN_ROLE - inputs: - - _ns: address - outputs: [] - errors: [ALREADY_INITIALIZED] - -setReverifyDaysOptions: - notes: - - "Replaces the full schedule; values must be strictly ascending uint8 days; non-empty array." - mutability: nonpayable - access: IDENTITY_ADMIN_ROLE - inputs: - - options: uint8[] - outputs: [] - errors: [EMPTY_REVERIFY_OPTIONS, OPTIONS_NOT_ASCENDING, WHEN_NOT_PAUSED_REVERT] - -authenticate: - notes: - - "Forwards to authenticateWithTimestamp(account, block.timestamp); requires IDENTITY_ADMIN_ROLE on the inner call." - mutability: nonpayable - access: IDENTITY_ADMIN_ROLE - inputs: - - account: address - outputs: [] - errors: [NOT_WHITELISTED_STATUS, WHEN_NOT_PAUSED_REVERT] - -authenticateWithTimestamp: - notes: - - "Refreshes authentication timestamp for status-1 account and advances authCount when reverification threshold is reached." - - "Legacy accounts before cutoff are evaluated at last schedule step for reverify math." - mutability: nonpayable - access: IDENTITY_ADMIN_ROLE - inputs: - - account: address - - timestamp: uint256 - outputs: [] - emits: [WhitelistedAuthenticated] - errors: [NOT_WHITELISTED_STATUS, WHEN_NOT_PAUSED_REVERT] - -addWhitelisted: - mutability: nonpayable - access: IDENTITY_ADMIN_ROLE - inputs: - - account: address - outputs: [] - emits: [WhitelistedAdded] - errors: [ALREADY_HAS_STATUS, WHEN_NOT_PAUSED_REVERT] - -addWhitelistedWithDIDAndChain: - notes: - - "Adds whitelisted account and stores DID plus originating chain id and authentication timestamp." - mutability: nonpayable - access: IDENTITY_ADMIN_ROLE - inputs: - - account: address - - did: string - - orgChain: uint256 - - dateAuthenticated: uint256 - outputs: [] - emits: [WhitelistedAdded] - errors: [DID_ALREADY_REGISTERED, ALREADY_HAS_STATUS, WHEN_NOT_PAUSED_REVERT] - -addWhitelistedWithDID: - mutability: nonpayable - access: IDENTITY_ADMIN_ROLE - inputs: - - account: address - - did: string - outputs: [] - emits: [WhitelistedAdded] - errors: [DID_ALREADY_REGISTERED, ALREADY_HAS_STATUS, WHEN_NOT_PAUSED_REVERT] - -removeWhitelisted: - mutability: nonpayable - access: IDENTITY_ADMIN_ROLE - inputs: - - account: address - outputs: [] - emits: [WhitelistedRemoved] - errors: [WHEN_NOT_PAUSED_REVERT] - -renounceWhitelisted: - mutability: nonpayable - access: whitelisted sender - inputs: [] - outputs: [] - emits: [WhitelistedRemoved] - errors: [NOT_WHITELISTED_SENDER, WHEN_NOT_PAUSED_REVERT] - -shouldReverify: - notes: - - "Compares daysSinceAuth against current reverifyDaysOptions step selected by authCount." - mutability: view - inputs: - - account: address - - daysSinceAuth: uint256 - outputs: - - needed: bool - -isWhitelisted: - notes: - - "Local status 1 with shouldReverify false; else oldIdentity.isWhitelisted try/catch." - mutability: view - inputs: - - account: address - outputs: - - ok: bool - -lastAuthenticated: - notes: - - "Returns local dateAuthenticated or falls back to oldIdentity when local record has no timestamp." - mutability: view - inputs: - - account: address - outputs: - - ts: uint256 - -addBlacklisted: - mutability: nonpayable - access: IDENTITY_ADMIN_ROLE - inputs: - - account: address - outputs: [] - emits: [BlacklistAdded, WhitelistedRemoved] - errors: [WHEN_NOT_PAUSED_REVERT] - -removeBlacklisted: - mutability: nonpayable - access: IDENTITY_ADMIN_ROLE - inputs: - - account: address - outputs: [] - emits: [BlacklistRemoved] - errors: [WHEN_NOT_PAUSED_REVERT] - -addContract: - mutability: nonpayable - access: IDENTITY_ADMIN_ROLE - inputs: - - account: address - outputs: [] - emits: [ContractAdded] - errors: [NOT_CONTRACT, ALREADY_HAS_STATUS, WHEN_NOT_PAUSED_REVERT] - -removeContract: - mutability: nonpayable - access: IDENTITY_ADMIN_ROLE - inputs: - - account: address - outputs: [] - emits: [ContractRemoved] - errors: [WHEN_NOT_PAUSED_REVERT] - -isDAOContract: - mutability: view - inputs: - - account: address - outputs: - - ok: bool - -isBlacklisted: - mutability: view - inputs: - - account: address - outputs: - - ok: bool - -connectAccount: - notes: - - "Caller must be whitelisted; target must not already be whitelisted or blacklisted; stores connectedAccounts[account]=msg.sender." - mutability: nonpayable - access: whitelisted sender - inputs: - - account: address - outputs: [] - emits: [AccountConnected] - errors: [INVALID_ACCOUNT_FOR_CONNECT, ALREADY_CONNECTED, WHEN_NOT_PAUSED_REVERT] - -disconnectAccount: - notes: - - "Caller must be either the linked root or the connected wallet." - mutability: nonpayable - inputs: - - connected: address - outputs: [] - emits: [AccountDisconnected] - errors: [UNAUTHORIZED_DISCONNECT] - -getWhitelistedRoot: - notes: - - "Returns account if directly whitelisted; returns connected root if connected account is whitelisted; else zero." - mutability: view - inputs: - - account: address - outputs: - - whitelisted: address - -pause: - mutability: nonpayable - access: PAUSER_ROLE - inputs: - - toPause: bool - outputs: [] - -setDID: - notes: - - "Sets DID for account by admin or account itself when whitelisted; enforces uniqueness across local and old identity." - mutability: nonpayable - inputs: - - account: address - - did: string - outputs: [] - errors: [NOT_AUTHORIZED_SET_DID, NOT_WHITELISTED_FOR_DID, DID_EMPTY, DID_ALREADY_REGISTERED, DID_ALREADY_REGISTERED_OLD, WHEN_NOT_PAUSED_REVERT] - -addrToDID: - mutability: view - inputs: - - account: address - outputs: - - did: string - -getWhitelistedOnChainId: - notes: - - "Returns chain id recorded during whitelisting for cross-chain eligibility checks." - mutability: view - inputs: - - account: address - outputs: - - chainId: uint256 - -isRegistered: - notes: - - "Compatibility shim; always returns true." - mutability: pure - inputs: [] - outputs: - - ok: bool - -IDENTITY_ADMIN_ROLE: - mutability: view - inputs: [] - outputs: - - role: bytes32 - -PAUSER_ROLE: - mutability: view - inputs: [] - outputs: - - role: bytes32 - -TYPED_STRUCTURE: - mutability: view - inputs: [] - outputs: - - schema: string - -whitelistedCount: - mutability: view - inputs: [] - outputs: - - n: uint256 - -whitelistedContracts: - mutability: view - inputs: [] - outputs: - - n: uint256 - -authenticationPeriod: - notes: - - "Returns reverifyDaysOptions[last] in days, not seconds." - mutability: view - inputs: [] - outputs: - - days: uint256 - -reverifyDaysOptions: - mutability: view - inputs: - - index: uint256 - outputs: - - days: uint32 - -identities: - mutability: view - inputs: - - account: address - outputs: - - dateAuthenticated: uint256 - - dateAdded: uint256 - - did: string - - whitelistedOnChainId: uint256 - - status: uint8 - - authCount: uint32 - -didHashToAddress: - mutability: view - inputs: - - hash: bytes32 - outputs: - - account: address - -connectedAccounts: - mutability: view - inputs: - - account: address - outputs: - - root: address - -oldIdentity: - mutability: view - inputs: [] - outputs: - - addr: address - -events: - BlacklistAdded: - indexed: - - account: address - data: [] - BlacklistRemoved: - indexed: - - account: address - data: [] - WhitelistedAdded: - indexed: - - account: address - data: [] - WhitelistedRemoved: - indexed: - - account: address - data: [] - WhitelistedAuthenticated: - indexed: - - account: address - data: - - timestamp: uint256 - ContractAdded: - indexed: - - account: address - data: [] - ContractRemoved: - indexed: - - account: address - data: [] - AccountConnected: - indexed: - - connected: address - - to: address - data: [] - AccountDisconnected: - indexed: - - disconnected: address - - from: address - data: [] - -errors: - ALREADY_INITIALIZED: "already initialized — initDAO twice." - EMPTY_REVERIFY_OPTIONS: "empty options — setReverifyDaysOptions." - OPTIONS_NOT_ASCENDING: "options not in ascending order — setReverifyDaysOptions." - NOT_WHITELISTED_STATUS: "not whitelisted — authenticateWithTimestamp." - NOT_WHITELISTED_SENDER: "not whitelisted — renounceWhitelisted modifier." - NOT_WHITELISTED_FOR_DID: "not whitelisted — _setDID." - ALREADY_HAS_STATUS: "already has status — _addWhitelisted." - DID_ALREADY_REGISTERED: "DID already registered — _addWhitelistedWithDID or _setDID." - DID_ALREADY_REGISTERED_OLD: "DID already registered oldIdentity — _setDID conflict path." - NOT_CONTRACT: "Given address is not a contract — addContract." - INVALID_ACCOUNT_FOR_CONNECT: "invalid account — connectAccount target checks." - ALREADY_CONNECTED: "already connected — connectAccount." - UNAUTHORIZED_DISCONNECT: "unauthorized — disconnectAccount." - NOT_AUTHORIZED_SET_DID: "not authorized — setDID caller." - DID_EMPTY: "did empty — _setDID." - WHEN_NOT_PAUSED_REVERT: "OpenZeppelin Pausable whenNotPaused on gated calls." diff --git a/.agents/skills/gooddollar/references/contracts/IdentityV4.selectors.yaml b/.agents/skills/gooddollar/references/contracts/IdentityV4.selectors.yaml deleted file mode 100644 index 3440a5e..0000000 --- a/.agents/skills/gooddollar/references/contracts/IdentityV4.selectors.yaml +++ /dev/null @@ -1,51 +0,0 @@ -# Generated by scripts/selectors.mjs -functions: - initialize(address,address): 0x485cc955 - initDAO(address): 0x2b14dda8 - setReverifyDaysOptions(uint8[]): 0x925e8c1a - authenticate(address): 0x08e0d29d - authenticateWithTimestamp(address,uint256): 0x96a1ef79 - addWhitelisted(address): 0x10154bad - addWhitelistedWithDIDAndChain(address,string,uint256,uint256): 0xe737031a - addWhitelistedWithDID(address,string): 0x1b027099 - removeWhitelisted(address): 0x291d9549 - renounceWhitelisted(): 0xd6cd9473 - shouldReverify(address,uint256): 0x4a03813f - isWhitelisted(address): 0x3af32abf - lastAuthenticated(address): 0xe1e360ba - addBlacklisted(address): 0x188efc16 - removeBlacklisted(address): 0xc6a276c2 - addContract(address): 0x5f539d69 - removeContract(address): 0xc375c2ef - isDAOContract(address): 0xc73cc4ae - isBlacklisted(address): 0xfe575a87 - connectAccount(address): 0xd21685f4 - disconnectAccount(address): 0x37a1a987 - getWhitelistedRoot(address): 0x2d0e9b46 - pause(bool): 0x02329a29 - setDID(address,string): 0xd3262816 - addrToDID(address): 0x54f9f7a3 - getWhitelistedOnChainId(address): 0xa061922d - isRegistered(): 0x22366844 - IDENTITY_ADMIN_ROLE(): 0x1aaff63c - PAUSER_ROLE(): 0xe63ab1e9 - TYPED_STRUCTURE(): 0x2cec5330 - whitelistedCount(): 0xb2a1de22 - whitelistedContracts(): 0xb30f7e7f - authenticationPeriod(): 0x31b376e2 - reverifyDaysOptions(uint256): 0xcadef5ac - identities(address): 0xf653b81e - didHashToAddress(bytes32): 0x67c75937 - connectedAccounts(address): 0x61320040 - oldIdentity(): 0x4125f0f2 -events: - BlacklistAdded(address): 0x44d5fe68b00f68950fb9c1ff0a61ef7f747b1a36359a7e3a7f3324db4b878967 - BlacklistRemoved(address): 0x1747ca720b1a174a464b6513ace29b1d3190b5f632b9f34147017c81425bfde8 - WhitelistedAdded(address): 0xee1504a83b6d4a361f4c1dc78ab59bfa30d6a3b6612c403e86bb01ef2984295f - WhitelistedRemoved(address): 0x270d9b30cf5b0793bbfd54c9d5b94aeb49462b8148399000265144a8722da6b6 - WhitelistedAuthenticated(address,uint256): 0xb2a82fce6d8c7a633efe9579f77b4edb96bfdf171a49bfc2ce666dc543a1f500 - ContractAdded(address): 0x89c66952b48f3e96bf1d8ba1b63189520fd988a6979b8b740bd5c5d8dc53e205 - ContractRemoved(address): 0x8d30d41865a0b811b9545d879520d2dde9f4cc49e4241f486ad9752bc904b565 - AccountConnected(address,address): 0x18f7736ef54539debd9afd3c9500b106e12ae7c70e685f5a5efd727b1ce1d54c - AccountDisconnected(address,address): 0x7cdef5f9c5cb8ce728661ede956fef26cb91eb4d7d2180cc041b73f9fef568d2 -errors: {} diff --git a/.agents/skills/gooddollar/references/contracts/InvitesV2.abi.yaml b/.agents/skills/gooddollar/references/contracts/InvitesV2.abi.yaml deleted file mode 100644 index d69e3d6..0000000 --- a/.agents/skills/gooddollar/references/contracts/InvitesV2.abi.yaml +++ /dev/null @@ -1,333 +0,0 @@ -# InvitesV2 — invite codes, inviter levels, and G$ bounties (UUPS upgradeable) -# Bounty amounts on Level use G$ cents (2 decimals). Invitee receives half the inviter bounty on payout. - -meta: - name: InvitesV2 - version: "2.4" - source: - - https://raw.githubusercontent.com/GoodDollar/GoodProtocol/master/contracts/invite/InvitesV2.sol - inherits: - - DAOUpgradeableContract - note: > - join binds invite code and optional inviter; bounty eligibility uses minimumDays, minimumClaims, - whitelist on invitee (and inviter when present), and same-chain whitelisting via Identity - getWhitelistedOnChainId. collectBounties and bountyFor pay invitee bountyToPay/2 and inviter - bountyToPay when applicable. Campaign inviter is address(this) when inviter code maps to contract. - deployments: - mainnet: - production: - Invites: - networkId: 122 - address: "0xCa2F09c3ccFD7aD5cB9276918Bd1868f2b922ea0" - creationBlock: 8853311 - production-celo: - Invites: - networkId: 42220 - address: "0x36829D1Cda92FFF5782d5d48991620664FC857d3" - creationBlock: 18003063 - production-xdc: - Invites: - networkId: 50 - address: "0x6bd698566632bf2e81e2278f1656CB24aAF06D2e" - creationBlock: 95144756 - related: - - references/deep-researches/inviter-invitee-reward-model.md - -initialize: - mutability: nonpayable - access: initializer - inputs: - - _ns: address - - _level0Bounty: uint256 - - _owner: address - outputs: [] - -updateAvatar: - mutability: nonpayable - access: anyone - inputs: [] - outputs: [] - -nativeToken: - mutability: view - inputs: [] - outputs: - - token: address - -dao: - mutability: view - inputs: [] - outputs: - - controller: address - -avatar: - mutability: view - inputs: [] - outputs: - - addr: address - -nameService: - mutability: view - inputs: [] - outputs: - - ns: address - -upgradeTo: - mutability: nonpayable - access: ownerOrAvatar - inputs: - - newImplementation: address - outputs: [] - -upgradeToAndCall: - mutability: payable - access: ownerOrAvatar - inputs: - - newImplementation: address - - data: bytes - outputs: [] - -proxiableUUID: - mutability: view - inputs: [] - outputs: - - slot: bytes32 - -setLevelExpirationEnabled: - mutability: nonpayable - access: ownerOrAvatar - inputs: - - _isEnabled: bool - outputs: [] - -getIdentity: - mutability: view - inputs: [] - outputs: - - identity: address - -join: - notes: - - "Registers invite code; may set inviter; may trigger _bountyFor when canCollectBountyFor is already true." - mutability: nonpayable - access: anyone - inputs: - - _myCode: bytes32 - - _inviterCode: bytes32 - outputs: [] - emits: [InviteeJoined] - errors: [NOT_ACTIVE, INVITE_CODE_IN_USE, SELF_INVITE, USER_ALREADY_JOINED] - -canCollectBountyFor: - notes: - - "Primary eligibility gate: checks active state, whitelist, minimumDays, minimumClaims, unpaid bounty, and chain constraints." - mutability: view - inputs: - - _invitee: address - outputs: - - ok: bool - -getInvitees: - mutability: view - inputs: - - _inviter: address - outputs: - - invitees: address[] - -getPendingInvitees: - mutability: view - inputs: - - _inviter: address - outputs: - - pending: address[] - -getPendingBounties: - mutability: view - inputs: - - _inviter: address - outputs: - - count: uint256 - -bountyFor: - notes: - - "Single-invitee payout path; revalidates eligibility and transfers bounty shares to inviter/invitee on success." - mutability: nonpayable - access: anyone - inputs: - - _invitee: address - outputs: - - bounty: uint256 - emits: [InviterBounty] - errors: [NOT_ACTIVE, NOT_ELIGIBLE_BOUNTY] - -collectBounties: - notes: - - "Batch payout path over caller pending invitees; useful for claiming multiple matured bounties in one tx." - mutability: nonpayable - access: anyone - inputs: [] - outputs: [] - emits: [InviterBounty] - errors: [NOT_ACTIVE] - -setLevel: - notes: - - "Configures inviter level progression rule and bounty amount (bounty units are G$ cents)." - mutability: nonpayable - access: ownerOrAvatar - inputs: - - _lvl: uint256 - - _toNext: uint256 - - _bounty: uint256 - - _daysToComplete: uint256 - outputs: [] - -setActive: - mutability: nonpayable - access: ownerOrAvatar - inputs: - - _active: bool - outputs: [] - -setCampaignCode: - notes: - - "Maps a campaign code to contract-address inviter flow (address(this)) used by join." - mutability: nonpayable - access: ownerOrAvatar - inputs: - - _code: bytes32 - outputs: [] - -setMinimums: - notes: - - "Sets minimumClaims and minimumDays thresholds used by canCollectBountyFor." - mutability: nonpayable - access: ownerOrAvatar - inputs: - - _minClaims: uint8 - - _minDays: uint8 - outputs: [] - -end: - mutability: nonpayable - access: ownerOrAvatar - inputs: [] - outputs: [] - errors: [NOT_ACTIVE] - -setOwner: - mutability: nonpayable - access: ownerOrAvatar - inputs: - - _owner: address - outputs: [] - -version: - mutability: pure - inputs: [] - outputs: - - v: string - -codeToUser: - mutability: view - inputs: - - code: bytes32 - outputs: - - user: address - -users: - notes: - - "Public getter omits dynamic invitees/pending arrays; use getInvitees and getPendingInvitees." - mutability: view - inputs: - - user: address - outputs: - - invitedBy: address - - inviteCode: bytes32 - - bountyPaid: bool - - level: uint256 - - levelStarted: uint256 - - totalApprovedInvites: uint256 - - totalEarned: uint256 - - joinedAt: uint256 - - bountyAtJoin: uint256 - -levels: - notes: - - "bounty is in G$ cents (2 decimals). Reserved struct slots are not exposed on the getter." - mutability: view - inputs: - - lvl: uint256 - outputs: - - toNext: uint256 - - bounty: uint256 - - daysToComplete: uint256 - -owner: - mutability: view - inputs: [] - outputs: - - addr: address - -goodDollar: - mutability: view - inputs: [] - outputs: - - token: address - -active: - mutability: view - inputs: [] - outputs: - - ok: bool - -stats: - notes: - - "Reserved Stats struct slots are not exposed on the getter." - mutability: view - inputs: [] - outputs: - - totalApprovedInvites: uint256 - - totalBountiesPaid: uint256 - - totalInvited: uint256 - -levelExpirationEnabled: - mutability: view - inputs: [] - outputs: - - ok: bool - -minimumClaims: - mutability: view - inputs: [] - outputs: - - n: uint8 - -minimumDays: - mutability: view - inputs: [] - outputs: - - n: uint8 - -events: - InviteeJoined: - indexed: - - inviter: address - - invitee: address - data: [] - InviterBounty: - indexed: - - inviter: address - - invitee: address - data: - - bountyPaid: uint256 - - inviterLevel: uint256 - - earnedLevel: bool - -errors: - NOT_ACTIVE: "not active — isActive modifier." - ONLY_OWNER_OR_AVATAR: "Only owner or avatar can perform this action — ownerOrAvatar." - INVITE_CODE_IN_USE: "invite code already in use — join." - SELF_INVITE: "self invite — join." - USER_ALREADY_JOINED: "user already joined — join." - NOT_ELIGIBLE_BOUNTY: "user not elligble for bounty yet — bountyFor." diff --git a/.agents/skills/gooddollar/references/contracts/InvitesV2.selectors.yaml b/.agents/skills/gooddollar/references/contracts/InvitesV2.selectors.yaml deleted file mode 100644 index d717955..0000000 --- a/.agents/skills/gooddollar/references/contracts/InvitesV2.selectors.yaml +++ /dev/null @@ -1,41 +0,0 @@ -# Generated by scripts/selectors.mjs -functions: - initialize(address,uint256,address): 0xc350a1b5 - updateAvatar(): 0x1b3c90a8 - nativeToken(): 0xe1758bd8 - dao(): 0x4162169f - avatar(): 0x5aef7de6 - nameService(): 0x3e6326fc - upgradeTo(address): 0x3659cfe6 - upgradeToAndCall(address,bytes): 0x4f1ef286 - proxiableUUID(): 0x52d1902d - setLevelExpirationEnabled(bool): 0x21132aad - getIdentity(): 0x36afc6fa - join(bytes32,bytes32): 0x5b419a65 - canCollectBountyFor(address): 0x6d619ef8 - getInvitees(address): 0xe9881a5e - getPendingInvitees(address): 0xe951a3aa - getPendingBounties(address): 0x41155d5e - bountyFor(address): 0xb6567cd5 - collectBounties(): 0xaf6346b0 - setLevel(uint256,uint256,uint256,uint256): 0xb9fb2d18 - setActive(bool): 0xacec338a - setCampaignCode(bytes32): 0xf14b8649 - setMinimums(uint8,uint8): 0x47826c82 - end(): 0xefbe1c1c - setOwner(address): 0x13af4035 - version(): 0x54fd4d50 - codeToUser(bytes32): 0xba6f5680 - users(address): 0xa87430ba - levels(uint256): 0xb2596a67 - owner(): 0x8da5cb5b - goodDollar(): 0x119e5bf3 - active(): 0x02fb0c5e - stats(): 0xd80528ae - levelExpirationEnabled(): 0xa1df6fd3 - minimumClaims(): 0xc121cb92 - minimumDays(): 0xdf0dca04 -events: - InviteeJoined(address,address): 0xd8c638d8979e2ba5dba1f0d66246ee4b1c54b838f0e0a2b601365345eb23b051 - InviterBounty(address,address,uint256,uint256,bool): 0x6081787cd1bd02ab1576c52f03e8710d792d460e7881c3155d77d23893f3768b -errors: {} diff --git a/.agents/skills/gooddollar/references/contracts/MentoBroker.abi.yaml b/.agents/skills/gooddollar/references/contracts/MentoBroker.abi.yaml deleted file mode 100644 index f6f47f4..0000000 --- a/.agents/skills/gooddollar/references/contracts/MentoBroker.abi.yaml +++ /dev/null @@ -1,259 +0,0 @@ -# Mento Broker (IBroker + IBrokerAdmin) — swap router and trading-limit gate for GoodDollar Mento rails -# Interface definitions are vendored in GoodProtocol; implementation lives in mento-core. - -meta: - name: Broker - version: IBroker / IBrokerAdmin - source: - - https://raw.githubusercontent.com/GoodDollar/GoodProtocol/master/contracts/MentoInterfaces.sol - - https://raw.githubusercontent.com/mento-org/mento-core/main/contracts/swap/Broker.sol - - https://raw.githubusercontent.com/mento-org/mento-core/main/contracts/interfaces/IBroker.sol - implements: [IBroker, IBrokerAdmin] - note: > - swapIn is exact-input; swapOut is exact-output. Quotes route through the - configured exchangeProvider + exchangeId. Reverts use require strings in - Broker.sol plus TradingLimits library checks ("amountOutMin not met", - "amountInMax exceeded", trading-limit errors). - deployments: - mainnet: - production-celo: - MentoBroker: - networkId: 42220 - address: "0x88de45906D4F5a57315c133620cfa484cB297541" - creationBlock: 31415857 - production-xdc: - MentoBroker: - networkId: 50 - address: "0x88de45906D4F5a57315c133620cfa484cB297541" - creationBlock: 100091095 - related: - - https://docs.gooddollar.org/for-developers/core-contracts/mentobroker - - references/guides/swap.md - -initialize: - mutability: nonpayable - access: initializer - inputs: - - _exchangeProviders: address[] - - _reserves: address[] - outputs: [] - -setReserves: - notes: - - "Updates reserve address per already-listed provider without changing provider registration." - mutability: nonpayable - access: owner - inputs: - - _exchangeProviders: address[] - - _reserves: address[] - outputs: [] - emits: [ReserveSet] - errors: - - EXCHANGE_PROVIDER_MISSING - - RESERVE_ZERO - -addExchangeProvider: - mutability: nonpayable - access: owner - inputs: - - exchangeProvider: address - - reserve: address - outputs: - - index: uint256 - emits: [ExchangeProviderAdded, ReserveSet] - errors: - - PROVIDER_ALREADY_LISTED - - PROVIDER_ZERO - - RESERVE_ZERO - -removeExchangeProvider: - mutability: nonpayable - access: owner - inputs: - - exchangeProvider: address - - index: uint256 - outputs: [] - emits: [ExchangeProviderRemoved] - errors: - - INDEX_MISMATCH - -getAmountIn: - notes: - - "Exact-output quote path: returns required tokenIn for target amountOut." - - "Pre-checks collateral reserve balance when tokenOut is collateral." - mutability: view - inputs: - - exchangeProvider: address - - exchangeId: bytes32 - - tokenIn: address - - tokenOut: address - - amountOut: uint256 - outputs: - - amountIn: uint256 - errors: - - EXCHANGE_PROVIDER_MISSING - - INSUFFICIENT_RESERVE_BALANCE - -getAmountOut: - notes: - - "Exact-input quote path: returns expected tokenOut for fixed amountIn." - - "Pre-checks collateral reserve balance when tokenOut is collateral." - mutability: view - inputs: - - exchangeProvider: address - - exchangeId: bytes32 - - tokenIn: address - - tokenOut: address - - amountIn: uint256 - outputs: - - amountOut: uint256 - errors: - - EXCHANGE_PROVIDER_MISSING - - INSUFFICIENT_RESERVE_BALANCE - -swapIn: - notes: - - "Transfers tokenIn from msg.sender then delivers tokenOut; enforces amountOut >= amountOutMin after exchange + limits." - mutability: nonpayable - access: nonReentrant - inputs: - - exchangeProvider: address - - exchangeId: bytes32 - - tokenIn: address - - tokenOut: address - - amountIn: uint256 - - amountOutMin: uint256 - outputs: - - amountOut: uint256 - emits: [Swap] - errors: - - EXCHANGE_PROVIDER_MISSING - - INSUFFICIENT_RESERVE_BALANCE - - AMOUNT_OUT_MIN_NOT_MET - - TRADING_LIMIT_OR_SAFE_TRANSFER - -swapOut: - notes: - - "Computes required tokenIn then pulls up to amountInMax; reverts if amountIn would exceed cap." - mutability: nonpayable - access: nonReentrant - inputs: - - exchangeProvider: address - - exchangeId: bytes32 - - tokenIn: address - - tokenOut: address - - amountOut: uint256 - - amountInMax: uint256 - outputs: - - amountIn: uint256 - emits: [Swap] - errors: - - EXCHANGE_PROVIDER_MISSING - - INSUFFICIENT_RESERVE_BALANCE - - AMOUNT_IN_MAX_EXCEEDED - - TRADING_LIMIT_OR_SAFE_TRANSFER - -burnStableTokens: - notes: - - "Owner-maintained escape hatch burning stables from msg.sender via reserve plumbing." - mutability: nonpayable - access: owner - inputs: - - token: address - - amount: uint256 - outputs: - - ok: bool - errors: - - COLLATERAL_TRANSFER_FAILED - -configureTradingLimit: - notes: - - "Sets per (exchangeId, token) limit config used by swapIn/swapOut guardTradingLimits checks." - mutability: nonpayable - access: owner - inputs: - - exchangeId: bytes32 - - token: address - - config: TradingLimits.Config - outputs: [] - emits: [TradingLimitConfigured] - -getExchangeProviders: - notes: - - "Discovery helper for clients that need the active provider set before quoting/swapping." - mutability: view - inputs: [] - outputs: - - providers: address[] - -exchangeProviders: - mutability: view - inputs: - - index: uint256 - outputs: - - exchangeProvider: address - -isExchangeProvider: - mutability: view - inputs: - - exchangeProvider: address - outputs: - - ok: bool - -tradingLimitsState: - mutability: view - inputs: - - eid: bytes32 - outputs: - - state: TradingLimits.State - -tradingLimitsConfig: - mutability: view - inputs: - - eid: bytes32 - outputs: - - config: TradingLimits.Config - -events: - Swap: - indexed: - - exchangeId: bytes32 - - trader: address - - tokenIn: address - data: - - exchangeProvider: address - - tokenOut: address - - amountIn: uint256 - - amountOut: uint256 - TradingLimitConfigured: - indexed: [] - data: - - exchangeId: bytes32 - - token: address - - config: TradingLimits.Config - ExchangeProviderAdded: - indexed: - - exchangeProvider: address - data: [] - ExchangeProviderRemoved: - indexed: - - exchangeProvider: address - data: [] - ReserveSet: - indexed: - - newAddress: address - - prevAddress: address - data: [] - -errors: - EXCHANGE_PROVIDER_MISSING: "ExchangeProvider does not exist" - EXCHANGE_PROVIDER_EXISTS: "ExchangeProvider already exists in the list" - PROVIDER_ZERO: "ExchangeProvider address can't be 0" - RESERVE_ZERO: "Reserve address can't be 0" - INDEX_MISMATCH: "index doesn't match provider" - INSUFFICIENT_RESERVE_BALANCE: "Insufficient balance in reserve" - AMOUNT_OUT_MIN_NOT_MET: "amountOutMin not met" - AMOUNT_IN_MAX_EXCEEDED: "amountInMax exceeded" - COLLATERAL_TRANSFER_FAILED: "Transfer of the collateral asset failed" - AMOUNT_TOO_LARGE: "amountIn too large / amountOut too large — uint256 to int256 safety checks" - TRADING_LIMIT_OR_SAFE_TRANSFER: "TradingLimits library reverts or ERC20 safety failures during swap" diff --git a/.agents/skills/gooddollar/references/contracts/MentoBroker.selectors.yaml b/.agents/skills/gooddollar/references/contracts/MentoBroker.selectors.yaml deleted file mode 100644 index 249edce..0000000 --- a/.agents/skills/gooddollar/references/contracts/MentoBroker.selectors.yaml +++ /dev/null @@ -1,24 +0,0 @@ -# Generated by scripts/selectors.mjs -functions: - initialize(address[],address[]): 0x73cf25f8 - setReserves(address[],address[]): 0xddeb9dd2 - addExchangeProvider(address,address): 0x770d0a34 - removeExchangeProvider(address,uint256): 0x04710d53 - getAmountIn(address,bytes32,address,address,uint256): 0x04e45640 - getAmountOut(address,bytes32,address,address,uint256): 0xa20f2305 - swapIn(address,bytes32,address,address,uint256,uint256): 0xddbbe850 - swapOut(address,bytes32,address,address,uint256,uint256): 0xd163b135 - burnStableTokens(address,uint256): 0x131cab2a - configureTradingLimit(bytes32,address,(uint32,uint32,int48,int48,int48,int48,int48,uint8)): 0xa868d140 - getExchangeProviders(): 0x2cac2568 - exchangeProviders(uint256): 0xc4454fdc - isExchangeProvider(address): 0xd1d786b1 - tradingLimitsState(bytes32): 0xf01ecd17 - tradingLimitsConfig(bytes32): 0x821a816c -events: - Swap(bytes32,address,address,address,address,uint256,uint256): 0x46e6aeaebfb8f1b6a9be6403b5fc420d9827172046f365e786acb9d5b56c9409 - TradingLimitConfigured(bytes32,address,(uint32,uint32,int48,int48,int48,int48,int48,uint8)): 0x3ed50aa123e1e547aa90fcf88624ef8278d253e252bb1feac75eda93e1905bb6 - ExchangeProviderAdded(address): 0x2ee2cb0721ec60b86190cae5c48e25064b69b35abad32452a4ec99d232033de2 - ExchangeProviderRemoved(address): 0x29e92ab2e30f4f74283034c28c451b6faac986b554f1808101eb6418bdba19d4 - ReserveSet(address,address): 0xb69e1c416d8be92ac92c8e97e77c4626fba5e6ab50161099f659ea3303479e50 -errors: {} diff --git a/.agents/skills/gooddollar/references/contracts/MessagePassingBridge.abi.yaml b/.agents/skills/gooddollar/references/contracts/MessagePassingBridge.abi.yaml deleted file mode 100644 index d4bb1f2..0000000 --- a/.agents/skills/gooddollar/references/contracts/MessagePassingBridge.abi.yaml +++ /dev/null @@ -1,542 +0,0 @@ -meta: - name: MessagePassingBridge - version: Axelar + LayerZero message passing - source: - - https://raw.githubusercontent.com/GoodDollar/GoodBridge/master/packages/bridge-contracts/contracts/messagePassingBridge/MessagePassingBridge.sol - - https://raw.githubusercontent.com/GoodDollar/GoodBridge/master/packages/bridge-contracts/contracts/messagePassingBridge/IMessagePassingBridge.sol - note: > - Bridge implementation that burns source tokens and mints destination tokens, - transporting requests through Axelar or LayerZero. - Cross-chain transport uses msg.value on the source (LayerZero estimateSendFee path, Axelar gas prepay); destination mint applies bridgeFees bps to the delivered G$ amount. See references/guides/bridge.md "Bridge fee context". - deployments: - mainnet: - production: - MpbBridge: - networkId: 122 - address: "0xa3247276DbCC76Dd7705273f766eB3E8a5ecF4a5" - creationBlock: 25464921 - production-celo: - MpbBridge: - networkId: 42220 - address: "0xa3247276DbCC76Dd7705273f766eB3E8a5ecF4a5" - creationBlock: 21473545 - production-xdc: - MpbBridge: - networkId: 50 - address: "0xa3247276DbCC76Dd7705273f766eB3E8a5ecF4a5" - creationBlock: 95254417 - related: - - references/guides/bridge.md - -initialize: - notes: - - "Initial bootstrap for DAO wiring and bridge policy state." - - "Sets guardian to msg.sender and uses NameService UBISCHEME as feeRecipient fallback to avatar when missing." - - "Preloads default LZ mappings for Ethereum, Celo, Fuse, and XDC using this contract as trusted remote." - mutability: nonpayable - access: initializer - inputs: - - nameService: address - - limits: (uint256,uint256,uint256,uint256,bool) - - fees: (uint256,uint256,uint256) - outputs: [] - -upgrade: - notes: - - "Reinitializer for migration path; re-applies default LZ mappings through internal add function." - - "Used when upgrading existing proxy deployments to mapping-aware version." - mutability: nonpayable - access: reinitializer - inputs: [] - outputs: [] - -addLzChainSupport: - notes: - - "Administrative chain wiring method for LayerZero transport." - - "Writes both forward (chainId->lzChainId) and reverse (lzChainId->chainId) mappings." - - "Also updates trustedRemoteLookup to enforce source-contract authenticity on receive." - mutability: nonpayable - access: ownerOrAvatarOrGuardian - inputs: - - lzChainId: uint16 - - chainId: uint256 - - remote: address - outputs: [] - -approveRequest: - notes: - - "Manual override for stuck/exceptional inbound requests." - - "When approved, destination _bridgeFrom skips limits enforcement for that request id." - mutability: nonpayable - access: ownerOrAvatarOrGuardian - inputs: - - id: uint256 - outputs: [] - -preventRequest: - notes: - - "Emergency/manual block for a specific request id." - - "Prevents execution by pre-marking executedRequests[id]=true." - mutability: nonpayable - access: ownerOrAvatarOrGuardian - inputs: - - id: uint256 - outputs: [] - -setFeeRecipient: - notes: - - "Sets destination fee mint recipient." - - "If feeRecipient is zero, fee minting is skipped in _bridgeFrom." - mutability: nonpayable - access: ownerOrAvatarOrGuardian - inputs: - - recipient: address - outputs: [] - -setBridgeLimits: - notes: - - "Updates operational throttles: min amount, tx cap, account/day cap, global/day cap, whitelist mode." - - "These limits are checked by canBridge and enforced in _enforceLimits." - mutability: nonpayable - access: ownerOrAvatarOrGuardian - inputs: - - limits: (uint256,uint256,uint256,uint256,bool) - outputs: [] - -setBridgeFees: - notes: - - "Updates bridge fee parameters in basis points with min/max clamps." - - "Reverts when fee exceeds 10000 bps." - - "Effective fee deduction is computed in _takeFee during destination execution." - mutability: nonpayable - access: ownerOrAvatarOrGuardian - inputs: - - fees: (uint256,uint256,uint256) - outputs: [] - -setDisabledBridges: - notes: - - "Toggles allowlist state for source bridge combinations." - - "Key format is keccak256(abi.encode(sourceChainId, BridgeService))." - - "Checked in _bridgeFrom before request execution." - mutability: nonpayable - access: ownerOrAvatarOrGuardian - inputs: - - bridgeKeys: bytes32[] - - disabled: bool[] - outputs: [] - -setFaucet: - notes: - - "Configures optional faucet top-up callback used after successful destination processing." - mutability: nonpayable - access: ownerOrAvatarOrGuardian - inputs: - - _faucet: address - outputs: [] - -setGuardian: - notes: - - "Rotates guardian authority used by owner/avatar/guardian admin gate." - mutability: nonpayable - access: ownerOrAvatarOrGuardian - inputs: - - _guardian: address - outputs: [] - -withdraw: - notes: - - "Avatar-only rescue function for arbitrary token balances held by bridge." - - "Amount 0 means full balance withdrawal." - mutability: nonpayable - access: avatar - inputs: - - token: address - - amount: uint256 - outputs: [] - -pauseBridge: - notes: - - "Sets isClosed state for outbound flow." - - "When closed, _bridgeTo reverts with BRIDGE_LIMITS('closed')." - mutability: nonpayable - access: ownerOrAvatarOrGuardian - inputs: - - isPaused: bool - outputs: [] - -canBridge: - notes: - - "Purely diagnostic read path for preflight checks." - - "Returns (ok, reason) using BridgeHelperLibrary policy evaluation." - - "Includes close flag, whitelist gate, and per-account/global daily limit windows." - mutability: view - inputs: - - from: address - - amount: uint256 - outputs: - - isWithinLimit: bool - - error: string - -bridgeTo: - notes: - - "Generic outbound bridge entrypoint selecting BridgeService.AXELAR or BridgeService.LZ." - - "Burns source-side token amount, normalizes to 18 decimals, and emits BridgeRequest with request id." - - "Requires msg.value for transport fee payment." - mutability: payable - access: anyone - inputs: - - target: address - - targetChainId: uint256 - - amount: uint256 - - bridge: uint8 - outputs: [] - -bridgeToWithLz: - notes: - - "Outbound convenience wrapper fixed to LayerZero transport." - - "If adapterParams is empty, contract injects default type-1 options with 400k gas." - - "Compares required native fee from estimateSendFee against msg.value and reverts on underpayment." - mutability: payable - access: anyone - inputs: - - target: address - - targetChainId: uint256 - - amount: uint256 - - adapterParams: bytes - outputs: [] - -bridgeToWithAxelar: - notes: - - "Outbound convenience wrapper fixed to Axelar transport." - - "Uses gasRefundAddress when provided, otherwise msg.sender as refund recipient." - mutability: payable - access: anyone - inputs: - - target: address - - targetChainId: uint256 - - amount: uint256 - - gasRefundAddress: address - outputs: [] - -toLzChainId: - notes: - - "Lookup helper from local chain id to LayerZero chain id." - mutability: view - inputs: - - chainId: uint256 - outputs: - - lzChainId: uint16 - -fromLzChainId: - notes: - - "Lookup helper from LayerZero chain id to local chain id." - mutability: view - inputs: - - lzChainId: uint16 - outputs: - - chainId: uint256 - -toAxelarChainId: - notes: - - "Pure mapping in current implementation: chainId 1 -> 'Ethereum', 5 -> 'ethereum-2', 42220 and 44787 -> 'celo'; any other id returns empty string and outbound Axelar reverts UNSUPPORTED_CHAIN." - mutability: pure - inputs: - - chainId: uint256 - outputs: - - axlChainId: string - -fromAxelarChainId: - notes: - - "Maps Axelar chain-name strings back into local numeric chain ids." - mutability: pure - inputs: - - axlChainId: string - outputs: - - chainId: uint256 - -estimateSendFee: - notes: - - "Transport fee preflight for LZ path." - - "Builds payload with request id set to 0 for estimation." - - "Returns (0,0) on endpoint estimation failure in handler implementation." - - "_normalizedAmount must match BridgeHelperLibrary.normalizeFromTokenTo18Decimals burned raw amount using native token decimals on the outbound chain." - mutability: view - inputs: - - _dstChainId: uint16 - - _fromAddress: address - - _toAddress: address - - _normalizedAmount: uint256 - - _useZro: bool - - _adapterParams: bytes - outputs: - - nativeFee: uint256 - - zroFee: uint256 - -lzReceive: - notes: - - "LayerZero receive entrypoint." - - "Validates caller is configured endpoint before dispatching nonblocking receive pipeline." - mutability: nonpayable - inputs: - - _srcChainId: uint16 - - _srcAddress: bytes - - _nonce: uint64 - - _payload: bytes - outputs: [] - -lzEndpoint_: - notes: - - "Immutable LayerZero endpoint configured in constructor." - mutability: view - inputs: [] - outputs: - - endpoint: address - -HOME_CHAIN_ID: - notes: - - "Immutable deployment home chain marker." - mutability: view - inputs: [] - outputs: - - chainId: uint32 - -guardian: - notes: - - "Current guardian account authorized for admin operations." - mutability: view - inputs: [] - outputs: - - account: address - -executedRequests: - notes: - - "Replay protection state for inbound request ids." - mutability: view - inputs: - - id: uint256 - outputs: - - done: bool - -disabledSourceBridges: - notes: - - "Per-source bridge toggle state keyed by (sourceChainId, bridgeService) hash." - mutability: view - inputs: - - key: bytes32 - outputs: - - disabled: bool - -isClosed: - notes: - - "Outbound bridge pause state." - mutability: view - inputs: [] - outputs: - - closed: bool - -bridgeFees: - notes: - - "Current fee policy parameters: minFee, maxFee, feeBps." - mutability: view - inputs: [] - outputs: - - minFee: uint256 - - maxFee: uint256 - - fee: uint256 - -bridgeLimits: - notes: - - "Current bridge traffic limits and whitelist policy." - mutability: view - inputs: [] - outputs: - - dailyLimit: uint256 - - txLimit: uint256 - - accountDailyLimit: uint256 - - minAmount: uint256 - - onlyWhitelisted: bool - -bridgeDailyLimit: - notes: - - "Aggregate 24h bridge usage tracker." - mutability: view - inputs: [] - outputs: - - lastTransferReset: uint256 - - bridged24Hours: uint256 - -accountsDailyLimit: - notes: - - "Per-account 24h usage tracker." - mutability: view - inputs: - - account: address - outputs: - - lastTransferReset: uint256 - - bridged24Hours: uint256 - -faucet: - notes: - - "Optional gas top-up contract used on destination completion." - mutability: view - inputs: [] - outputs: - - addr: address - -currentId: - notes: - - "Monotonic nonce component used to derive outbound request ids." - mutability: view - inputs: [] - outputs: - - id: uint256 - -lzChainIdsMapping: - notes: - - "Local chain id -> LayerZero chain id mapping." - mutability: view - inputs: - - chainId: uint256 - outputs: - - lzChainId: uint16 - -feeRecipient: - notes: - - "Address receiving bridge fee mints on destination." - mutability: view - inputs: [] - outputs: - - recipient: address - -approvedRequests: - notes: - - "Manual approvals allowing request execution above standard limits." - mutability: view - inputs: - - id: uint256 - outputs: - - approved: bool - -lzChainToIdsMapping: - notes: - - "LayerZero chain id -> local chain id mapping." - mutability: view - inputs: - - lzChainId: uint16 - outputs: - - chainId: uint256 - -trustedRemoteLookup: - notes: - - "Trusted remote path used to authenticate inbound LZ/Axelar source contract." - mutability: view - inputs: - - lzChainId: uint16 - outputs: - - path: bytes - -gateway: - notes: - - "Axelar gateway address inherited from AxelarExecutable." - mutability: view - inputs: [] - outputs: - - addr: address - -gasService: - notes: - - "Axelar gas service used to prepay cross-chain execution." - mutability: view - inputs: [] - outputs: - - addr: address - -nameService: - notes: - - "DAO NameService pointer from DAOUpgradeableContract." - mutability: view - inputs: [] - outputs: - - addr: address - -avatar: - notes: - - "DAO avatar authority address." - mutability: view - inputs: [] - outputs: - - addr: address - -owner: - notes: - - "Ownable owner from upgradeable ownership flow." - mutability: view - inputs: [] - outputs: - - account: address - -events: - BridgeRequest: - indexed: - - from: address - - to: address - - id: uint256 - data: - - targetChainId: uint256 - - normalizedAmount: uint256 - - timestamp: uint256 - - bridge: uint8 - note: "Outbound intent event; relayers consume this to deliver payload on destination." - ExecutedTransfer: - indexed: - - from: address - - to: address - - id: uint256 - data: - - normalizedAmount: uint256 - - fee: uint256 - - sourceChainId: uint256 - - bridge: uint8 - note: "Destination completion event after replay checks, source-auth checks, limit checks, and mint/fee mint." - FalseSender: - indexed: [] - data: - - sourceChainId: uint256 - - sourceAddress: address - note: "Inbound message ignored because source contract does not match trusted remote path." - -errors: - AlreadyInitialized: "LZ chain support already initialized for this lz chain id." - NOT_GUARDIAN: - inputs: - - sender: address - WRONG_TOKEN: - inputs: - - token: address - INVALID_TARGET_OR_CHAINID: - inputs: - - target: address - - chainId: uint256 - BRIDGE_LIMITS: - inputs: - - reason: string - TRANSFER_FROM: "Source burn/transferFrom style failure." - TRANSFER: "Destination transfer style failure." - ALREADY_EXECUTED: - inputs: - - requestId: uint256 - MISSING_FEE: "Bridge call requires msg.value for transport fee." - UNSUPPORTED_CHAIN: - inputs: - - chainId: uint256 - LZ_FEE: - inputs: - - required: uint256 - - sent: uint256 - INVALID_SENDER: - inputs: - - _srcAddress: bytes - INVALID_ENDPOINT: - inputs: - - lzEndpoint: address diff --git a/.agents/skills/gooddollar/references/contracts/MessagePassingBridge.selectors.yaml b/.agents/skills/gooddollar/references/contracts/MessagePassingBridge.selectors.yaml deleted file mode 100644 index 104b943..0000000 --- a/.agents/skills/gooddollar/references/contracts/MessagePassingBridge.selectors.yaml +++ /dev/null @@ -1,52 +0,0 @@ -# Generated by scripts/selectors.mjs -functions: - initialize(address,(uint256,uint256,uint256,uint256,bool),(uint256,uint256,uint256)): 0xfad16abe - upgrade(): 0xd55ec697 - addLzChainSupport(uint16,uint256,address): 0xc01c8123 - approveRequest(uint256): 0xd7d1bbdb - preventRequest(uint256): 0xc612f9ea - setFeeRecipient(address): 0xe74b981b - setBridgeLimits((uint256,uint256,uint256,uint256,bool)): 0x29b70872 - setBridgeFees((uint256,uint256,uint256)): 0x82dc737d - setDisabledBridges(bytes32[],bool[]): 0xc78ab882 - setFaucet(address): 0xd8b31c77 - setGuardian(address): 0x8a0dac4a - withdraw(address,uint256): 0xf3fef3a3 - pauseBridge(bool): 0x1a394795 - canBridge(address,uint256): 0x3095634a - bridgeTo(address,uint256,uint256,uint8): 0x1fec5c5c - bridgeToWithLz(address,uint256,uint256,bytes): 0xc56bbdd9 - bridgeToWithAxelar(address,uint256,uint256,address): 0x40a00aaf - toLzChainId(uint256): 0x5b23a990 - fromLzChainId(uint16): 0x16ad5512 - toAxelarChainId(uint256): 0x9a9ee081 - fromAxelarChainId(string): 0x56026f37 - estimateSendFee(uint16,address,address,uint256,bool,bytes): 0x05fead15 - lzReceive(uint16,bytes,uint64,bytes): 0x001d3567 - lzEndpoint_(): 0x020051cf - HOME_CHAIN_ID(): 0x8f65be85 - guardian(): 0x452a9320 - executedRequests(uint256): 0x425cfb53 - disabledSourceBridges(bytes32): 0x69c20d36 - isClosed(): 0xc2b6b58c - bridgeFees(): 0x7b0240c0 - bridgeLimits(): 0xc6dd812f - bridgeDailyLimit(): 0xb2f7667f - accountsDailyLimit(address): 0xd4227947 - faucet(): 0xde5f72fd - currentId(): 0xe00dd161 - lzChainIdsMapping(uint256): 0xb5569f18 - feeRecipient(): 0x46904840 - approvedRequests(uint256): 0x0dce292e - lzChainToIdsMapping(uint16): 0x73800fc4 - trustedRemoteLookup(uint16): 0x7533d788 - gateway(): 0x116191b6 - gasService(): 0x6a22d8cc - nameService(): 0x3e6326fc - avatar(): 0x5aef7de6 - owner(): 0x8da5cb5b -events: - BridgeRequest(address,address,uint256,uint256,uint256,uint256,uint8): 0x34b675c8c84b6a9e7979a0d3a54f2b036a19d6444167091a925af2d81e8e66fe - ExecutedTransfer(address,address,uint256,uint256,uint256,uint256,uint8): 0x81e772e0c4366ddbae472926005267ef278dbb257be45dfe97c676ceae348dbe - FalseSender(uint256,address): 0x1eafb58197ea0dc76b9278ccad47f61a239f00b017d89a19081a89321cce213d -errors: {} diff --git a/.agents/skills/gooddollar/references/contracts/NameService.abi.yaml b/.agents/skills/gooddollar/references/contracts/NameService.abi.yaml deleted file mode 100644 index 01692b7..0000000 --- a/.agents/skills/gooddollar/references/contracts/NameService.abi.yaml +++ /dev/null @@ -1,104 +0,0 @@ -# NameService — string-key to address registry for GoodProtocol deployments -# Resolves keys such as IDENTITY, UBISCHEME, GOODDOLLAR, GDAO_STAKING. - -meta: - name: NameService - version: UUPS-upgradeable v1 - source: - - https://raw.githubusercontent.com/GoodDollar/GoodProtocol/master/contracts/utils/NameService.sol - implements: [] - inherits: [Initializable, UUPSUpgradeable] - note: > - Almost every integration starts here. Writes are restricted to the DAO - avatar. Reads are permissionless. Use getAddress(string) with the same - key strings your deployment documented in releases/deployment.json. - deployments: - mainnet: - production: - NameService: - networkId: 122 - address: "0xec6dcE387B1616a0c44fF2E4fA9E90e53Cf14eb0" - creationBlock: 15740314 - production-celo: - NameService: - networkId: 42220 - address: "0x0F5dB7a64A6a64052693676CA898EC7F7A94FF4e" - creationBlock: 17237962 - production-xdc: - NameService: - networkId: 50 - address: "0x1e5154Bf5e31FF56051bbd45958b879Fb7a290FE" - creationBlock: 95143608 - related: - - https://docs.gooddollar.org/for-developers/core-contracts/nameservice - - https://github.com/GoodDollar/GoodProtocol/blob/master/releases/deployment.json - -addresses: - # Solidity auto-getter for public mapping addresses(bytes32 => address). - notes: - - "Prefer getAddress(string) off-chain; this expects keccak256(abi.encodePacked(name)) for manual lookups." - mutability: view - inputs: - - nameHash: bytes32 - outputs: - - addr: address - -dao: - mutability: view - inputs: [] - outputs: - - controller: address - -initialize: - notes: - - "Initializer wires Controller and optional pre-hashed name batch." - - "Automatically registers CONTROLLER and AVATAR hashes to dao and dao.avatar()." - mutability: nonpayable - access: initializer - inputs: - - _dao: address - - _nameHashes: bytes32[] - - _addresses: address[] - outputs: [] - -setAddress: - notes: - - "Stores addresses[keccak256(bytes(name))] = addr and emits AddressChanged." - mutability: nonpayable - access: avatar - inputs: - - name: string - - addr: address - outputs: [] - emits: [AddressChanged] - errors: [ONLY_AVATAR] - -setAddresses: - notes: - - "Batch write by raw bytes32 keys; no per-name event emission in this loop." - mutability: nonpayable - access: avatar - inputs: - - hash: bytes32[] - - addrs: address[] - outputs: [] - errors: [ONLY_AVATAR] - -getAddress: - notes: - - "Primary lookup used by claim, staking, identity, and swap integrations." - mutability: view - inputs: - - name: string - outputs: - - addr: address - -events: - AddressChanged: - indexed: [] - data: - - name: string - - addr: address - -errors: - ONLY_AVATAR: "only avatar can call this method — revert string on any avatar-gated path including UUPS _authorizeUpgrade." diff --git a/.agents/skills/gooddollar/references/contracts/NameService.selectors.yaml b/.agents/skills/gooddollar/references/contracts/NameService.selectors.yaml deleted file mode 100644 index 48e1bcf..0000000 --- a/.agents/skills/gooddollar/references/contracts/NameService.selectors.yaml +++ /dev/null @@ -1,11 +0,0 @@ -# Generated by scripts/selectors.mjs -functions: - addresses(bytes32): 0x699f200f - dao(): 0x4162169f - initialize(address,bytes32[],address[]): 0xd41b4e72 - setAddress(string,address): 0x9b2ea4bd - setAddresses(bytes32[],address[]): 0x4ab01f5b - getAddress(string): 0xbf40fac1 -events: - AddressChanged(string,address): 0x135cf55549d8538a41f19f46cc85625da93e68b63484cca8fcb9aaf19e520137 -errors: {} diff --git a/.agents/skills/gooddollar/references/contracts/SuperToken.abi.yaml b/.agents/skills/gooddollar/references/contracts/SuperToken.abi.yaml deleted file mode 100644 index abfc91c..0000000 --- a/.agents/skills/gooddollar/references/contracts/SuperToken.abi.yaml +++ /dev/null @@ -1,1033 +0,0 @@ -# SuperToken — the Superfluid Protocol's token standard -# Merges three variants into a single ABI surface: -# • Wrapper Super Token — wraps an existing ERC-20 (upgrade / downgrade) -# • Native Asset Super Token (SETH) — wraps chain-native asset (upgradeByETH / downgradeToETH) -# • Pure Super Token — pre-minted, no underlying token (upgrade/downgrade revert) -# -# Inherits ERC-20, ERC-777, ERC-2612 (permit), EIP-5267, and the Superfluid real-time -# balance and agreement hosting layer from SuperfluidToken. -# -# Proxy / upgradability functions are omitted: -# castrate, getCodeAddress, proxiableUUID, initialize, initializeWithAdmin, updateCode -# Proxy-related events are also omitted: CodeUpdated, Initialized. - -meta: - name: SuperToken - version: v1 - source: - - https://raw.githubusercontent.com/superfluid-org/protocol-monorepo/refs/heads/dev/packages/ethereum-contracts/contracts/superfluid/SuperToken.sol - - https://raw.githubusercontent.com/superfluid-org/protocol-monorepo/refs/heads/dev/packages/ethereum-contracts/contracts/interfaces/superfluid/ISuperToken.sol - - https://raw.githubusercontent.com/superfluid-org/protocol-monorepo/refs/heads/dev/packages/ethereum-contracts/contracts/superfluid/SuperfluidToken.sol - - https://raw.githubusercontent.com/superfluid-org/protocol-monorepo/refs/heads/dev/packages/ethereum-contracts/contracts/interfaces/superfluid/IYieldBackend.sol - inherits: [SuperfluidToken, ISuperToken, UUPSProxiable] - yield_backends: - - name: AaveYieldBackend - note: "Production backend for ERC-20 wrapper tokens using Aave V3" - source: https://raw.githubusercontent.com/superfluid-org/protocol-monorepo/refs/heads/dev/packages/ethereum-contracts/contracts/superfluid/AaveYieldBackend.sol - - name: AaveETHYieldBackend - note: "Variant for native-asset (ETH/WETH) wrapper tokens using Aave V3" - source: https://raw.githubusercontent.com/superfluid-org/protocol-monorepo/refs/heads/dev/packages/ethereum-contracts/contracts/superfluid/AaveETHYieldBackend.sol - - name: ERC4626YieldBackend - note: "Generic backend for any ERC-4626 vault" - source: https://raw.githubusercontent.com/superfluid-org/protocol-monorepo/refs/heads/dev/packages/ethereum-contracts/contracts/superfluid/ERC4626YieldBackend.sol - - name: SparkYieldBackend - note: "Extends ERC4626YieldBackend for Spark Protocol vaults with referral tracking" - source: https://raw.githubusercontent.com/superfluid-org/protocol-monorepo/refs/heads/dev/packages/ethereum-contracts/contracts/superfluid/SparkYieldBackend.sol - variants: - wrapper: "Standard ERC-20 wrapper — upgrade() / downgrade()" - native-asset: "Native asset wrapper (SETH) — upgradeByETH() / downgradeToETH()" - pure: "Pre-minted supply, no underlying — upgrade/downgrade revert" - note: > - Super Tokens are deployed as individual proxies (one per token) by the - SuperTokenFactory. There is no single canonical deployment address. - All proxies share the same logic contract which is upgraded via governance. - -# wrapper super token — a Super Token backed by an ERC-20 underlying token -# native asset super token (SETH) — a Super Token backed by the chain-native asset (ETH, MATIC, etc.) -# pure super token — a Super Token with no underlying; supply is pre-minted at deploy time -# underlying token — the ERC-20 token that a wrapper super token wraps -# real-time balance — balance that changes continuously based on active agreements (CFA/GDA) -# available balance — real-time balance minus locked deposits -# critical — an account whose available balance is negative -# solvent — an account whose real-time balance (before deposit deductions) is non-negative -# operator (ERC-777) — an address authorized to send/burn tokens on behalf of a holder -# buffer / deposit — collateral locked while an outgoing flow is active - -# == ERC-20 Token Info == - -name: - mutability: view - inputs: [] - outputs: - - string - -symbol: - mutability: view - inputs: [] - outputs: - - string - -decimals: - # Always returns 18 regardless of underlying token decimals. - notes: - - "Always returns 18, regardless of the underlying token's decimals (e.g. USDC has 6). The upgrade/downgrade functions handle decimal conversion internally." - mutability: pure - inputs: [] - outputs: - - uint8 - -totalSupply: - mutability: view - inputs: [] - outputs: - - uint256 - -# == ERC-20 Balance & Allowance == - -balanceOf: - # Returns max(0, availableBalance) — clamps negative balances to zero. - # For the full real-time picture, use realtimeBalanceOfNow. - notes: - - "Returns max(0, availableBalance) — negative/critical balances are clamped to zero. Use realtimeBalanceOfNow to detect critical accounts." - mutability: view - inputs: - - account: address - outputs: - - balance: uint256 - -allowance: - mutability: view - inputs: - - account: address - - spender: address - outputs: - - uint256 - -approve: - mutability: nonpayable - access: anyone - inputs: - - spender: address - - amount: uint256 - outputs: - - bool - emits: [Approval] - errors: [SUPER_TOKEN_APPROVE_FROM_ZERO_ADDRESS, SUPER_TOKEN_APPROVE_TO_ZERO_ADDRESS] - -increaseAllowance: - mutability: nonpayable - access: anyone - inputs: - - spender: address - - addedValue: uint256 - outputs: - - bool - emits: [Approval] - errors: [SUPER_TOKEN_APPROVE_FROM_ZERO_ADDRESS, SUPER_TOKEN_APPROVE_TO_ZERO_ADDRESS] - -decreaseAllowance: - mutability: nonpayable - access: anyone - inputs: - - spender: address - - subtractedValue: uint256 - outputs: - - bool - emits: [Approval] - errors: [SUPER_TOKEN_APPROVE_FROM_ZERO_ADDRESS, SUPER_TOKEN_APPROVE_TO_ZERO_ADDRESS] - -# == ERC-20 Transfers == - -transfer: - # ERC-20 transfer. Does NOT invoke ERC-777 send/receive hooks (by design). - mutability: nonpayable - access: anyone - inputs: - - recipient: address - - amount: uint256 - outputs: - - bool - emits: [Sent, Transfer] - errors: [SUPER_TOKEN_TRANSFER_FROM_ZERO_ADDRESS, SUPER_TOKEN_TRANSFER_TO_ZERO_ADDRESS, SF_TOKEN_MOVE_INSUFFICIENT_BALANCE] - -transferFrom: - # ERC-20 transferFrom. Does NOT invoke ERC-777 send/receive hooks. - # Does NOT emit an Approval event on allowance spend (OZ v5 behaviour). - mutability: nonpayable - access: anyone - inputs: - - holder: address - - recipient: address - - amount: uint256 - outputs: - - bool - emits: [Sent, Transfer] - errors: [SUPER_TOKEN_TRANSFER_FROM_ZERO_ADDRESS, SUPER_TOKEN_TRANSFER_TO_ZERO_ADDRESS, SF_TOKEN_MOVE_INSUFFICIENT_BALANCE] - -transferAll: - # Transfer the caller's entire balanceOf to recipient. - mutability: nonpayable - access: anyone # transfers msg.sender's entire balance - inputs: - - recipient: address - emits: [Sent, Transfer] - errors: [SUPER_TOKEN_TRANSFER_FROM_ZERO_ADDRESS, SUPER_TOKEN_TRANSFER_TO_ZERO_ADDRESS, SF_TOKEN_MOVE_INSUFFICIENT_BALANCE] - -# == ERC-777 == - -granularity: - # Always returns 1. - mutability: pure - inputs: [] - outputs: - - uint256 - -send: - # ERC-777 send — invokes tokensToSend / tokensReceived hooks. - mutability: nonpayable - access: anyone - inputs: - - recipient: address - - amount: uint256 - - userData: bytes - emits: [Sent, Transfer] - errors: [SUPER_TOKEN_TRANSFER_FROM_ZERO_ADDRESS, SUPER_TOKEN_TRANSFER_TO_ZERO_ADDRESS, SF_TOKEN_MOVE_INSUFFICIENT_BALANCE, SUPER_TOKEN_NOT_ERC777_TOKENS_RECIPIENT] - -burn: - # ERC-777 burn — in SuperToken this actually performs a downgrade (unwrap). - notes: - - "Gotcha: Reverts with SUPER_TOKEN_NO_UNDERLYING_TOKEN on Pure Super Tokens." - mutability: nonpayable - access: anyone - inputs: - - amount: uint256 - - userData: bytes - emits: [Burned, Transfer, TokenDowngraded] - errors: [SUPER_TOKEN_NO_UNDERLYING_TOKEN, SUPER_TOKEN_BURN_FROM_ZERO_ADDRESS, SF_TOKEN_BURN_INSUFFICIENT_BALANCE, SUPER_TOKEN_INFLATIONARY_DEFLATIONARY_NOT_SUPPORTED] - -authorizeOperator: - mutability: nonpayable - access: anyone - inputs: - - operator: address - emits: [AuthorizedOperator] - -revokeOperator: - mutability: nonpayable - access: anyone - inputs: - - operator: address - emits: [RevokedOperator] - -isOperatorFor: - mutability: view - inputs: - - operator: address - - tokenHolder: address - outputs: - - bool - -defaultOperators: - mutability: view - inputs: [] - outputs: - - "address[]" - -operatorSend: - # ERC-777 operatorSend — invokes tokensToSend / tokensReceived hooks. - mutability: nonpayable - access: operator - inputs: - - sender: address - - recipient: address - - amount: uint256 - - userData: bytes - - operatorData: bytes - emits: [Sent, Transfer] - errors: [SUPER_TOKEN_CALLER_IS_NOT_OPERATOR_FOR_HOLDER, SUPER_TOKEN_TRANSFER_FROM_ZERO_ADDRESS, SUPER_TOKEN_TRANSFER_TO_ZERO_ADDRESS, SF_TOKEN_MOVE_INSUFFICIENT_BALANCE, SUPER_TOKEN_NOT_ERC777_TOKENS_RECIPIENT] - -operatorBurn: - # ERC-777 operatorBurn — like burn(), actually performs a downgrade. - mutability: nonpayable - access: operator - inputs: - - account: address - - amount: uint256 - - userData: bytes - - operatorData: bytes - emits: [Burned, Transfer, TokenDowngraded] - errors: [SUPER_TOKEN_CALLER_IS_NOT_OPERATOR_FOR_HOLDER, SUPER_TOKEN_NO_UNDERLYING_TOKEN, SUPER_TOKEN_BURN_FROM_ZERO_ADDRESS, SF_TOKEN_BURN_INSUFFICIENT_BALANCE, SUPER_TOKEN_INFLATIONARY_DEFLATIONARY_NOT_SUPPORTED] - -# == ERC-20 Permit == - -permit: - mutability: nonpayable - access: anyone - inputs: - - owner: address - - spender: address - - value: uint256 - - deadline: uint256 - - v: uint8 - - r: bytes32 - - s: bytes32 - emits: [Approval] - errors: [SUPER_TOKEN_PERMIT_EXPIRED_SIGNATURE, SUPER_TOKEN_PERMIT_INVALID_SIGNER, ECDSAInvalidSignature, ECDSAInvalidSignatureLength, ECDSAInvalidSignatureS, SUPER_TOKEN_APPROVE_FROM_ZERO_ADDRESS, SUPER_TOKEN_APPROVE_TO_ZERO_ADDRESS] - -nonces: - mutability: view - inputs: - - owner: address - outputs: - - uint256 - -DOMAIN_SEPARATOR: - mutability: view - inputs: [] - outputs: - - bytes32 - -eip712Domain: - # EIP-5267 domain retrieval. - mutability: view - inputs: [] - outputs: - - fields: bytes1 - - name: string - - version: string - - chainId: uint256 - - verifyingContract: address - - salt: bytes32 - - "extensions: uint256[]" - -# == ERC-20 Wrapping == -# These functions interact with the underlying ERC-20 token. -# They revert with SUPER_TOKEN_NO_UNDERLYING_TOKEN on Pure and Native Asset -# Super Tokens (use upgradeByETH / downgradeToETH for SETH). - -upgrade: - # Wrap underlying ERC-20 into Super Tokens for msg.sender. - # Requires prior ERC-20 approval on the underlying token. - notes: - - "Gotcha: amount is always in SuperToken decimals (18), regardless of the underlying token's decimals. The contract handles downscaling internally when pulling from the underlying via transferFrom. However, the ERC-20 approval on the underlying token must use the underlying's native decimals. Example: to wrap 1000 USDC, approve 1000e6 on USDC, then call upgrade(1000e18)." - mutability: nonpayable - access: anyone # wraps for msg.sender - inputs: - - amount: uint256 # in SuperToken decimals (always 18) - emits: [Minted, Transfer, TokenUpgraded] - errors: [SUPER_TOKEN_NO_UNDERLYING_TOKEN, SUPER_TOKEN_INFLATIONARY_DEFLATIONARY_NOT_SUPPORTED, SUPER_TOKEN_MINT_TO_ZERO_ADDRESS, SafeERC20FailedOperation, SafeCastOverflowedUintToInt] - -upgradeTo: - # Wrap underlying ERC-20 and mint Super Tokens to a different address. - mutability: nonpayable - access: anyone - inputs: - - to: address - - amount: uint256 - - userData: bytes - emits: [Minted, Transfer, TokenUpgraded] - errors: [SUPER_TOKEN_NO_UNDERLYING_TOKEN, SUPER_TOKEN_INFLATIONARY_DEFLATIONARY_NOT_SUPPORTED, SUPER_TOKEN_MINT_TO_ZERO_ADDRESS, SUPER_TOKEN_NOT_ERC777_TOKENS_RECIPIENT, SafeERC20FailedOperation, SafeCastOverflowedUintToInt] - -downgrade: - # Unwrap Super Tokens back to underlying ERC-20 for msg.sender. - mutability: nonpayable - access: anyone # unwraps to msg.sender - inputs: - - amount: uint256 - emits: [Burned, Transfer, TokenDowngraded] - errors: [SUPER_TOKEN_NO_UNDERLYING_TOKEN, SUPER_TOKEN_BURN_FROM_ZERO_ADDRESS, SF_TOKEN_BURN_INSUFFICIENT_BALANCE, SUPER_TOKEN_INFLATIONARY_DEFLATIONARY_NOT_SUPPORTED, SafeERC20FailedOperation] - -downgradeTo: - # Unwrap Super Tokens and send underlying ERC-20 to a different address. - mutability: nonpayable - access: anyone - inputs: - - to: address - - amount: uint256 - emits: [Burned, Transfer, TokenDowngraded] - errors: [SUPER_TOKEN_NO_UNDERLYING_TOKEN, SUPER_TOKEN_BURN_FROM_ZERO_ADDRESS, SF_TOKEN_BURN_INSUFFICIENT_BALANCE, SUPER_TOKEN_INFLATIONARY_DEFLATIONARY_NOT_SUPPORTED, SafeERC20FailedOperation] - -getUnderlyingToken: - # Returns address(0) for Pure and Native Asset Super Tokens. - mutability: view - inputs: [] - outputs: - - address - -getUnderlyingDecimals: - mutability: view - inputs: [] - outputs: - - uint8 - -toUnderlyingAmount: - # Convert a Super Token amount to its underlying equivalent, accounting for - # decimal differences. adjustedAmount strips precision loss. - mutability: view - inputs: - - amount: uint256 - outputs: - - underlyingAmount: uint256 - - adjustedAmount: uint256 - -# == Native Asset Wrapping (SETH only) == -# These functions exist only on Native Asset Super Token (SETH) proxies. -# They are defined in the SETHProxy contract, not in the SuperToken logic. -# The SETH proxy also accepts plain ETH transfers via receive() which mints -# Super Tokens to the sender. - -upgradeByETH: - # Wrap sent ETH/native asset into Super Tokens for msg.sender. - # Variant: native-asset - mutability: payable - access: anyone # wraps for msg.sender - inputs: [] - emits: [Minted, Transfer, TokenUpgraded] - -upgradeByETHTo: - # Wrap sent ETH/native asset into Super Tokens for a different address. - # Variant: native-asset - mutability: payable - access: anyone - inputs: - - to: address - emits: [Minted, Transfer, TokenUpgraded] - -downgradeToETH: - # Unwrap Super Tokens back to ETH/native asset for msg.sender. - # Variant: native-asset - mutability: nonpayable - access: anyone # unwraps to msg.sender - inputs: - - wad: uint256 - emits: [Burned, Transfer, TokenDowngraded] - -# == Real-time Balance == - -realtimeBalanceOf: - # Full real-time balance across ALL agreements at a given timestamp. - # This aggregates the realtimeBalanceOf from every agreement (CFA, GDA, IDA) - # into a single balance. Use this (or realtimeBalanceOfNow) to check an - # account's actual balance — not the per-agreement versions. - # availableBalance = settled + agreement dynamics − max(0, deposit − owedDeposit) - mutability: view - inputs: - - account: address - - timestamp: uint256 - outputs: - - availableBalance: int256 - - deposit: uint256 - - owedDeposit: uint256 - -realtimeBalanceOfNow: - # Convenience wrapper: realtimeBalanceOf at the current Host timestamp. - # This is the recommended way to check an account's real-time balance. - mutability: view - inputs: - - account: address - outputs: - - availableBalance: int256 - - deposit: uint256 - - owedDeposit: uint256 - - timestamp: uint256 - -isAccountCritical: - # True if availableBalance < 0 at the given timestamp. - mutability: view - inputs: - - account: address - - timestamp: uint256 - outputs: - - isCritical: bool - -isAccountCriticalNow: - mutability: view - inputs: - - account: address - outputs: - - isCritical: bool - -isAccountSolvent: - # True if realtime balance (before deposit deduction) >= 0 at the given timestamp. - mutability: view - inputs: - - account: address - - timestamp: uint256 - outputs: - - isSolvent: bool - -isAccountSolventNow: - mutability: view - inputs: - - account: address - outputs: - - isSolvent: bool - -# == Admin == -# The admin defaults to the Host contract when address(0). -# An explicit admin can be set during initializeWithAdmin or via changeAdmin. - -changeAdmin: - mutability: nonpayable - access: admin - inputs: - - newAdmin: address - emits: [AdminChanged] - errors: [SUPER_TOKEN_ONLY_ADMIN] - -getAdmin: - # Returns address(0) if the Host is the implicit admin. - mutability: view - inputs: [] - outputs: - - address - -# == Yield Backend == -# Hot-pluggable yield generation for wrapper Super Tokens. The yield backend is a -# contract implementing IYieldBackend that is invoked via delegatecall. When enabled, -# the underlying ERC-20 is deposited into a yield protocol (e.g. Aave, Spark, ERC4626 vaults). -# Surplus yield (balance exceeding totalSupply) can be withdrawn by the admin. - -enableYieldBackend: - # Enable a yield backend and deposit all underlying token balance into it. - # Requires no existing yield backend to be set. - notes: - - "Gotcha: Reverts if a yield backend is already enabled — must call disableYieldBackend first to switch backends." - - "The yield backend contract is invoked via delegatecall — it executes in the SuperToken's context." - mutability: nonpayable - access: admin - inputs: - - newYieldBackend: address # must implement IYieldBackend - emits: [YieldBackendEnabled] - -disableYieldBackend: - # Withdraw all assets from the yield backend and disable it. - notes: - - "Calls withdrawMax() then disable() on the backend via delegatecall." - mutability: nonpayable - access: admin - inputs: [] - emits: [YieldBackendDisabled] - -getYieldBackend: - # Returns the current yield backend address, or address(0) if none is set. - mutability: view - inputs: [] - outputs: - - yieldBackend: address - -withdrawSurplusFromYieldBackend: - # Withdraw yield surplus (deposited amount exceeding totalSupply) from the backend. - # The surplus is sent to a receiver defined by the yield backend implementation. - mutability: nonpayable - access: admin - inputs: [] - -# == Self Operations == -# Can only be called by the token contract itself (address(this)). -# Used by custom super token proxies (SETH, Pure) to mint/burn/approve/transfer -# tokens through their own proxy logic. - -selfMint: - mutability: nonpayable - access: self - inputs: - - account: address - - amount: uint256 - - userData: bytes - emits: [Minted, Transfer] - errors: [SUPER_TOKEN_ONLY_SELF, SUPER_TOKEN_MINT_TO_ZERO_ADDRESS] - -selfBurn: - mutability: nonpayable - access: self - inputs: - - account: address - - amount: uint256 - - userData: bytes - emits: [Burned, Transfer] - errors: [SUPER_TOKEN_ONLY_SELF, SUPER_TOKEN_BURN_FROM_ZERO_ADDRESS, SF_TOKEN_BURN_INSUFFICIENT_BALANCE] - -selfApproveFor: - mutability: nonpayable - access: self - inputs: - - account: address - - spender: address - - amount: uint256 - emits: [Approval] - errors: [SUPER_TOKEN_ONLY_SELF, SUPER_TOKEN_APPROVE_FROM_ZERO_ADDRESS, SUPER_TOKEN_APPROVE_TO_ZERO_ADDRESS] - -selfTransferFrom: - mutability: nonpayable - access: self - inputs: - - holder: address - - spender: address - - recipient: address - - amount: uint256 - emits: [Sent, Transfer] - errors: [SUPER_TOKEN_ONLY_SELF, SUPER_TOKEN_TRANSFER_FROM_ZERO_ADDRESS, SUPER_TOKEN_TRANSFER_TO_ZERO_ADDRESS, SF_TOKEN_MOVE_INSUFFICIENT_BALANCE] - -# == Host Batch Operations == -# Called by the Host contract on behalf of a user within batchCall / -# forwardBatchCall. Each mirrors a user-facing function but takes the -# account address explicitly. - -operationApprove: - mutability: nonpayable - access: host - inputs: - - account: address - - spender: address - - amount: uint256 - emits: [Approval] - errors: [SF_TOKEN_ONLY_HOST, SUPER_TOKEN_APPROVE_FROM_ZERO_ADDRESS, SUPER_TOKEN_APPROVE_TO_ZERO_ADDRESS] - -operationIncreaseAllowance: - mutability: nonpayable - access: host - inputs: - - account: address - - spender: address - - addedValue: uint256 - emits: [Approval] - errors: [SF_TOKEN_ONLY_HOST, SUPER_TOKEN_APPROVE_FROM_ZERO_ADDRESS, SUPER_TOKEN_APPROVE_TO_ZERO_ADDRESS] - -operationDecreaseAllowance: - mutability: nonpayable - access: host - inputs: - - account: address - - spender: address - - subtractedValue: uint256 - emits: [Approval] - errors: [SF_TOKEN_ONLY_HOST, SUPER_TOKEN_APPROVE_FROM_ZERO_ADDRESS, SUPER_TOKEN_APPROVE_TO_ZERO_ADDRESS] - -operationTransferFrom: - mutability: nonpayable - access: host - inputs: - - account: address - - spender: address - - recipient: address - - amount: uint256 - emits: [Sent, Transfer] - errors: [SF_TOKEN_ONLY_HOST, SUPER_TOKEN_TRANSFER_FROM_ZERO_ADDRESS, SUPER_TOKEN_TRANSFER_TO_ZERO_ADDRESS, SF_TOKEN_MOVE_INSUFFICIENT_BALANCE] - -operationSend: - mutability: nonpayable - access: host - inputs: - - spender: address - - recipient: address - - amount: uint256 - - userData: bytes - emits: [Sent, Transfer] - errors: [SF_TOKEN_ONLY_HOST, SUPER_TOKEN_TRANSFER_FROM_ZERO_ADDRESS, SUPER_TOKEN_TRANSFER_TO_ZERO_ADDRESS, SF_TOKEN_MOVE_INSUFFICIENT_BALANCE, SUPER_TOKEN_NOT_ERC777_TOKENS_RECIPIENT] - -operationUpgrade: - mutability: nonpayable - access: host - inputs: - - account: address - - amount: uint256 - emits: [Minted, Transfer, TokenUpgraded] - errors: [SF_TOKEN_ONLY_HOST, SUPER_TOKEN_NO_UNDERLYING_TOKEN, SUPER_TOKEN_INFLATIONARY_DEFLATIONARY_NOT_SUPPORTED, SUPER_TOKEN_MINT_TO_ZERO_ADDRESS, SafeERC20FailedOperation, SafeCastOverflowedUintToInt] - -operationDowngrade: - mutability: nonpayable - access: host - inputs: - - account: address - - amount: uint256 - emits: [Burned, Transfer, TokenDowngraded] - errors: [SF_TOKEN_ONLY_HOST, SUPER_TOKEN_NO_UNDERLYING_TOKEN, SUPER_TOKEN_BURN_FROM_ZERO_ADDRESS, SF_TOKEN_BURN_INSUFFICIENT_BALANCE, SUPER_TOKEN_INFLATIONARY_DEFLATIONARY_NOT_SUPPORTED, SafeERC20FailedOperation] - -operationUpgradeTo: - mutability: nonpayable - access: host - inputs: - - account: address - - to: address - - amount: uint256 - emits: [Minted, Transfer, TokenUpgraded] - errors: [SF_TOKEN_ONLY_HOST, SUPER_TOKEN_NO_UNDERLYING_TOKEN, SUPER_TOKEN_INFLATIONARY_DEFLATIONARY_NOT_SUPPORTED, SUPER_TOKEN_MINT_TO_ZERO_ADDRESS, SafeERC20FailedOperation, SafeCastOverflowedUintToInt] - -operationDowngradeTo: - mutability: nonpayable - access: host - inputs: - - account: address - - to: address - - amount: uint256 - emits: [Burned, Transfer, TokenDowngraded] - errors: [SF_TOKEN_ONLY_HOST, SUPER_TOKEN_NO_UNDERLYING_TOKEN, SUPER_TOKEN_BURN_FROM_ZERO_ADDRESS, SF_TOKEN_BURN_INSUFFICIENT_BALANCE, SUPER_TOKEN_INFLATIONARY_DEFLATIONARY_NOT_SUPPORTED, SafeERC20FailedOperation] - -# == Agreement Hosting == -# The token acts as storage host for agreement data. These functions are -# called by registered agreement contracts (CFA, GDA, IDA) through the Host. - -createAgreement: - mutability: nonpayable - access: agreement - inputs: - - id: bytes32 - - "data: bytes32[]" - emits: [AgreementCreated] - errors: [SF_TOKEN_AGREEMENT_ALREADY_EXISTS] - -getAgreementData: - mutability: view - inputs: - - agreementClass: address - - id: bytes32 - - dataLength: uint256 - outputs: - - "data: bytes32[]" - -updateAgreementData: - mutability: nonpayable - access: agreement - inputs: - - id: bytes32 - - "data: bytes32[]" - emits: [AgreementUpdated] - -terminateAgreement: - mutability: nonpayable - access: agreement - inputs: - - id: bytes32 - - dataLength: uint256 - emits: [AgreementTerminated] - errors: [SF_TOKEN_AGREEMENT_DOES_NOT_EXIST] - -updateAgreementStateSlot: - mutability: nonpayable - access: agreement - inputs: - - account: address - - slotId: uint256 - - "slotData: bytes32[]" - emits: [AgreementStateUpdated] - -getAgreementStateSlot: - mutability: view - inputs: - - agreementClass: address - - account: address - - slotId: uint256 - - dataLength: uint256 - outputs: - - "slotData: bytes32[]" - -settleBalance: - # Adjust an account's settled balance. Only listed agreements can call this. - mutability: nonpayable - access: agreement - inputs: - - account: address - - delta: int256 - errors: [SF_TOKEN_ONLY_LISTED_AGREEMENT] - -makeLiquidationPayoutsV2: - # Execute liquidation payouts. Transfers reward to liquidator or reward account, - # and adjusts the target account's balance. Only listed agreements can call this. - mutability: nonpayable - access: agreement - inputs: - - id: bytes32 - - liquidationTypeData: bytes - - liquidatorAccount: address - - useDefaultRewardAccount: bool - - targetAccount: address - - rewardAmount: uint256 - - targetAccountBalanceDelta: int256 - emits: [Transfer, AgreementLiquidatedV2] - errors: [SF_TOKEN_ONLY_LISTED_AGREEMENT] - -getAccountActiveAgreements: - mutability: view - inputs: - - account: address - outputs: - - "ISuperAgreement[]" - -# == Protocol Info == - -getHost: - mutability: view - inputs: [] - outputs: - - host: address - -POOL_ADMIN_NFT: - # Immutable address of the canonical PoolAdminNFT proxy. - mutability: view - inputs: [] - outputs: - - address - -POOL_MEMBER_NFT: - # Immutable address of the (deprecated) PoolMemberNFT proxy. - mutability: view - inputs: [] - outputs: - - address - -VERSION: - # Returns the version string of the SuperToken logic contract (e.g. "1.0.0"). - mutability: view - inputs: [] - outputs: - - string - -# == Events == - -events: - - # -- ERC-20 -- - - Transfer: - indexed: - - from: address - - to: address - data: - - value: uint256 - - Approval: - indexed: - - owner: address - - spender: address - data: - - value: uint256 - - # -- ERC-777 -- - - Sent: - indexed: - - operator: address - - from: address - - to: address - data: - - amount: uint256 - - data: bytes - - operatorData: bytes - - Minted: - indexed: - - operator: address - - to: address - data: - - amount: uint256 - - data: bytes - - operatorData: bytes - - Burned: - indexed: - - operator: address - - from: address - data: - - amount: uint256 - - data: bytes - - operatorData: bytes - - AuthorizedOperator: - indexed: - - operator: address - - tokenHolder: address - - RevokedOperator: - indexed: - - operator: address - - tokenHolder: address - - # -- EIP-5267 -- - - EIP712DomainChanged: - # Signalled when the EIP-712 domain changes. Not explicitly emitted by - # SuperToken, but declared in the EIP-5267 interface for indexing support. - - # -- Wrapping -- - - TokenUpgraded: - indexed: - - account: address - data: - - amount: uint256 - - TokenDowngraded: - indexed: - - account: address - data: - - amount: uint256 - - # -- Admin -- - - AdminChanged: - indexed: [] - data: - - oldAdmin: address - - newAdmin: address - - # -- Yield Backend -- - - YieldBackendEnabled: - indexed: - - yieldBackend: address - data: - - depositAmount: uint256 - - YieldBackendDisabled: - indexed: - - yieldBackend: address - - PoolAdminNFTCreated: - # Emitted once during logic contract constructor deployment. - indexed: [] - data: - - poolAdminNFT: address - - # -- Agreement Hosting -- - - AgreementCreated: - indexed: - - agreementClass: address - - id: bytes32 - data: - - "data: bytes32[]" - - AgreementUpdated: - indexed: - - agreementClass: address - - id: bytes32 - data: - - "data: bytes32[]" - - AgreementTerminated: - indexed: - - agreementClass: address - - id: bytes32 - - AgreementStateUpdated: - indexed: - - agreementClass: address - - account: address - data: - - slotId: uint256 - - AgreementLiquidatedV2: - indexed: - - agreementClass: address - - id: bytes32 - data: - - liquidatorAccount: address - - targetAccount: address - - rewardAmountReceiver: address - - rewardAmount: uint256 - - targetAccountBalanceDelta: int256 - - liquidationTypeData: bytes - - # -- Deprecated events (from ISuperfluidToken, no longer emitted) -- - - AgreementLiquidated: - deprecated: true - note: "Use AgreementLiquidatedV2" - indexed: - - agreementClass: address - - id: bytes32 - data: - - penaltyAccount: address - - rewardAccount: address - - rewardAmount: uint256 - - AgreementLiquidatedBy: - deprecated: true - note: "Use AgreementLiquidatedV2" - indexed: - - liquidatorAccount: address - - agreementClass: address - - id: bytes32 - data: - - penaltyAccount: address - - bondAccount: address - - rewardAmount: uint256 - - bailoutAmount: uint256 - - Bailout: - deprecated: true - note: "Use AgreementLiquidatedV2" - indexed: - - bailoutAccount: address - - bailoutAmount: uint256 - -# == Errors == - -errors: - - # -- Super Token access -- - - SUPER_TOKEN_ONLY_SELF - - SUPER_TOKEN_ONLY_ADMIN - - SUPER_TOKEN_ONLY_GOV_OWNER - - # -- SuperfluidToken access -- - - SF_TOKEN_ONLY_HOST - - SF_TOKEN_ONLY_LISTED_AGREEMENT - - # -- Wrapping -- - - SUPER_TOKEN_NO_UNDERLYING_TOKEN - - SUPER_TOKEN_INFLATIONARY_DEFLATIONARY_NOT_SUPPORTED - - # -- ERC-20 / ERC-777 transfer -- - - SUPER_TOKEN_TRANSFER_FROM_ZERO_ADDRESS - - SUPER_TOKEN_TRANSFER_TO_ZERO_ADDRESS - - SF_TOKEN_MOVE_INSUFFICIENT_BALANCE - - # -- Approve -- - - SUPER_TOKEN_APPROVE_FROM_ZERO_ADDRESS - - SUPER_TOKEN_APPROVE_TO_ZERO_ADDRESS - - # -- Mint / Burn -- - - SUPER_TOKEN_MINT_TO_ZERO_ADDRESS - - SUPER_TOKEN_BURN_FROM_ZERO_ADDRESS - - SF_TOKEN_BURN_INSUFFICIENT_BALANCE - - # -- ERC-777 operator -- - - SUPER_TOKEN_CALLER_IS_NOT_OPERATOR_FOR_HOLDER - - SUPER_TOKEN_NOT_ERC777_TOKENS_RECIPIENT - - # -- ERC-2612 permit -- - - SUPER_TOKEN_PERMIT_EXPIRED_SIGNATURE: - inputs: - - deadline: uint256 - - SUPER_TOKEN_PERMIT_INVALID_SIGNER: - inputs: - - signer: address - - owner: address - - # -- NFT proxy -- - - SUPER_TOKEN_NFT_PROXY_ADDRESS_CHANGED - - # -- Agreement hosting -- - - SF_TOKEN_AGREEMENT_ALREADY_EXISTS - - SF_TOKEN_AGREEMENT_DOES_NOT_EXIST - - # -- OpenZeppelin ECDSA (from permit) -- - - ECDSAInvalidSignature - - ECDSAInvalidSignatureLength: - inputs: - - length: uint256 - - ECDSAInvalidSignatureS: - inputs: - - s: bytes32 - - # -- OpenZeppelin SafeCast -- - - SafeCastOverflowedUintToInt: - inputs: - - value: uint256 - - # -- OpenZeppelin SafeERC20 -- - - SafeERC20FailedOperation: - inputs: - - token: address diff --git a/.agents/skills/gooddollar/references/contracts/SuperToken.selectors.yaml b/.agents/skills/gooddollar/references/contracts/SuperToken.selectors.yaml deleted file mode 100644 index f9bb474..0000000 --- a/.agents/skills/gooddollar/references/contracts/SuperToken.selectors.yaml +++ /dev/null @@ -1,99 +0,0 @@ -# Generated by scripts/selectors.mjs -functions: - name(): 0x06fdde03 - symbol(): 0x95d89b41 - decimals(): 0x313ce567 - totalSupply(): 0x18160ddd - balanceOf(address): 0x70a08231 - allowance(address,address): 0xdd62ed3e - approve(address,uint256): 0x095ea7b3 - increaseAllowance(address,uint256): 0x39509351 - decreaseAllowance(address,uint256): 0xa457c2d7 - transfer(address,uint256): 0xa9059cbb - transferFrom(address,address,uint256): 0x23b872dd - transferAll(address): 0xa3a7e7f3 - granularity(): 0x556f0dc7 - send(address,uint256,bytes): 0x9bd9bbc6 - burn(uint256,bytes): 0xfe9d9303 - authorizeOperator(address): 0x959b8c3f - revokeOperator(address): 0xfad8b32a - isOperatorFor(address,address): 0xd95b6371 - defaultOperators(): 0x06e48538 - operatorSend(address,address,uint256,bytes,bytes): 0x62ad1b83 - operatorBurn(address,uint256,bytes,bytes): 0xfc673c4f - permit(address,address,uint256,uint256,uint8,bytes32,bytes32): 0xd505accf - nonces(address): 0x7ecebe00 - DOMAIN_SEPARATOR(): 0x3644e515 - eip712Domain(): 0x84b0196e - upgrade(): 0xd55ec697 - upgradeTo(address,uint256,bytes): 0x5b9d09cc - downgrade(uint256): 0x11bcc81e - downgradeTo(address,uint256): 0x83ba2525 - getUnderlyingToken(): 0xee719bc8 - getUnderlyingDecimals(): 0x92081a47 - toUnderlyingAmount(uint256): 0x282a050b - upgradeByETH(): 0xcf81464b - upgradeByETHTo(address): 0x7687d19b - downgradeToETH(uint256): 0x160e8be3 - realtimeBalanceOf(address,uint256): 0xeb3537cc - realtimeBalanceOfNow(address): 0x2ec8eec7 - isAccountCritical(address,uint256): 0xd9d078d6 - isAccountCriticalNow(address): 0x79359f6f - isAccountSolvent(address,uint256): 0xb84cdd4a - isAccountSolventNow(address): 0xbb0d196e - changeAdmin(address): 0x8f283970 - getAdmin(): 0x6e9960c3 - enableYieldBackend(): 0x5127b621 - disableYieldBackend(): 0x370a190f - getYieldBackend(): 0xe729804b - withdrawSurplusFromYieldBackend(): 0x4a3acda0 - selfMint(address,uint256,bytes): 0xc68d4283 - selfBurn(address,uint256,bytes): 0x9d876741 - selfApproveFor(address,address,uint256): 0x66a12fb6 - selfTransferFrom(address,address,address,uint256): 0x41b706be - operationApprove(address,address,uint256): 0x62aa5287 - operationIncreaseAllowance(address,address,uint256): 0x4b2763b3 - operationDecreaseAllowance(address,address,uint256): 0xc780fd82 - operationTransferFrom(address,address,address,uint256): 0x16d055d6 - operationSend(address,address,uint256,bytes): 0xca0c1e7f - operationUpgrade(address,uint256): 0xca789464 - operationDowngrade(address,uint256): 0x245887fc - operationUpgradeTo(address,address,uint256): 0x1ae88ffc - operationDowngradeTo(address,address,uint256): 0x47ba7ad1 - createAgreement(bytes32,bytes32[]"): 0x816e2dc5 - getAgreementData(address,bytes32,uint256): 0x6c2d9f2f - updateAgreementData(bytes32,bytes32[]"): 0x1bced9c7 - terminateAgreement(bytes32,uint256): 0x27048397 - updateAgreementStateSlot(address,uint256,bytes32[]"): 0x003af740 - getAgreementStateSlot(address,address,uint256,uint256): 0x4b61cc33 - settleBalance(address,int256): 0xcf97256d - makeLiquidationPayoutsV2(bytes32,bytes,address,bool,address,uint256,int256): 0x1863e809 - getAccountActiveAgreements(address): 0x386fa221 - getHost(): 0x20bc4425 - POOL_ADMIN_NFT(): 0xb20db1ac - POOL_MEMBER_NFT(): 0xf5a8b4dd - VERSION(): 0xffa1ad74 -events: - Transfer(address,address,uint256): 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef - Approval(address,address,uint256): 0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925 - Sent(address,address,address,uint256,bytes,bytes): 0x06b541ddaa720db2b10a4d0cdac39b8d360425fc073085fac19bc82614677987 - Minted(address,address,uint256,bytes,bytes): 0x2fe5be0146f74c5bce36c0b80911af6c7d86ff27e89d5cfa61fc681327954e5d - Burned(address,address,uint256,bytes,bytes): 0xa78a9be3a7b862d26933ad85fb11d80ef66b8f972d7cbba06621d583943a4098 - AuthorizedOperator(address,address): 0xf4caeb2d6ca8932a215a353d0703c326ec2d81fc68170f320eb2ab49e9df61f9 - RevokedOperator(address,address): 0x50546e66e5f44d728365dc3908c63bc5cfeeab470722c1677e3073a6ac294aa1 - EIP712DomainChanged(): 0x0a6387c9ea3628b88a633bb4f3b151770f70085117a15f9bf3787cda53f13d31 - TokenUpgraded(address,uint256): 0x25ca84076773b0455db53621c459ddc84fe40840e4932a62706a032566f399df - TokenDowngraded(address,uint256): 0x3bc27981aebbb57f9247dc00fde9d6cd91e4b230083fec3238fedbcba1f9ab3d - AdminChanged(address,address): 0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f - YieldBackendEnabled(address,uint256): 0x8d15dd569157df615aedb4b16273001ae8980ce2aac93e39adc48481dfaefbb5 - YieldBackendDisabled(address): 0x2486b5241145ce1b97a13655ecd4e8e51094ac93259a0589d24524304d6d70d4 - PoolAdminNFTCreated(address): 0xeb87fb34067547f3dc0b85096c3da73c99d4fbb08ff41212b8d7c0b5008b42e6 - AgreementCreated(address,bytes32,bytes32[]"): 0x9a5caaf4460c6dff81ed3dc58f3aef40fe511737a163340e06a4abc1bfe21a73 - AgreementUpdated(address,bytes32,bytes32[]"): 0xc00aaaf56818c1a9d6c54e14c6f93965eb34c9729232fdafa62f90a10600e70a - AgreementTerminated(address,bytes32): 0x71a63dc095de07aa5512ad57a7596a39516317e316981a1cd71000057be1537b - AgreementStateUpdated(address,address,uint256): 0x30f416fa68fca014a0f334464c64b000ba53e99b6d2afdea9d5ca756372d5985 - AgreementLiquidatedV2(address,bytes32,address,address,address,uint256,int256,bytes): 0xb8381a3ce157650e06186e3e8f4dd4dc29236f2688b6eed1893d0a60d7c6386f - AgreementLiquidated(address,bytes32,address,address,uint256): 0x8505c3d8f1f184f032cf0bc4cd80ee61c8b9d94f8907c3281bf0101a2610fe80 - AgreementLiquidatedBy(address,address,bytes32,address,address,uint256,uint256): 0x5f22b60e58b1d6de858bc27c48d5a4653e052da99e083c1d88bb8c58e1abc8ef - Bailout(address,uint256): 0xd6c9a04afc81e8c614310bbee6c9e84f5abe15b82038bf8347014ce0852e6ffd -errors: {} diff --git a/.agents/skills/gooddollar/references/contracts/Superfluid.abi.yaml b/.agents/skills/gooddollar/references/contracts/Superfluid.abi.yaml deleted file mode 100644 index 33ac5a9..0000000 --- a/.agents/skills/gooddollar/references/contracts/Superfluid.abi.yaml +++ /dev/null @@ -1,757 +0,0 @@ -# Superfluid Host — the central protocol router -# All agreement calls (CFA, IDA, GDA) are routed through the Host, which manages -# the Superfluid call context, Super App callbacks, app credit, and governance. -# The Host is also the entry point for batch calls and meta-transactions. -# -# NOTE: emits/errors mappings are traced from source code — verify against implementation. -# Proxy/upgradability functions (castrate, updateCode, getCodeAddress, proxiableUUID, initialize) -# are omitted — they belong to the UUPSProxiable layer. - -meta: - name: Superfluid - version: v1 - source: - - https://raw.githubusercontent.com/superfluid-org/protocol-monorepo/refs/heads/dev/packages/ethereum-contracts/contracts/superfluid/Superfluid.sol - - https://raw.githubusercontent.com/superfluid-org/protocol-monorepo/refs/heads/dev/packages/ethereum-contracts/contracts/interfaces/superfluid/ISuperfluid.sol - implements: [ISuperfluid] - inherits: [UUPSProxiable, BaseRelayRecipient] - deployments: - mainnet: - eth-mainnet: "0x4E583d9390082B65Bef884b629DFA426114CED6d" - polygon-mainnet: "0x3E14dC1b13c488a8d5D310918780c983bD5982E7" - xdai-mainnet: "0x2dFe937cD98Ab92e59cF3139138f18c823a4efE7" - base-mainnet: "0x4C073B3baB6d8826b8C5b229f3cfdC1eC6E47E74" - optimism-mainnet: "0x567c4B141ED61923967cA25Ef4906C8781069a10" - arbitrum-one: "0xCf8Acb4eF033efF16E8080aed4c7D5B9285D2192" - bsc-mainnet: "0xd1e2cFb6441680002Eb7A44223160aB9B67d7E6E" - avalanche-c: "0x60377C7016E4cdB03C87EF474896C11cB560752C" - celo-mainnet: "0xA4Ff07cF81C02CFD356184879D953970cA957585" - scroll-mainnet: "0x0F86a21F6216c061B222c224e315d9FC34520bb7" - degenchain: "0xc1314EdcD7e478C831a7a24169F7dEADB2646eD2" - testnet: - avalanche-fuji: "0x85Fe79b998509B77BF10A8BD4001D58475D29386" - base-sepolia: "0x109412E3C84f0539b43d39dB691B08c90f58dC7c" - eth-sepolia: "0x109412E3C84f0539b43d39dB691B08c90f58dC7c" - optimism-sepolia: "0xd399e2Fb5f4cf3722a11F65b88FAB6B2B8621005" - scroll-sepolia: "0x42b05a6016B9eED232E13fd56a8F0725693DBF8e" - deploymentCreationBlocks: - mainnet: - celo-mainnet: 16393469 - -# == Abbreviations == -# ctx — context (Superfluid call context bytes) -# ACL — Access Control List -# ERC — Ethereum Request for Comments - -# == Glossary == -# Host — central Superfluid contract routing agreement/app calls -# agreement class — a registered agreement contract (CFA, IDA, GDA) -# Super App — a smart contract registered with the Host that receives callbacks -# callback — beforeAgreement* / afterAgreement* hooks called on Super Apps -# context (ctx) — encoded call metadata: msgSender, timestamp, userData, app credit -# app credit — temporary token allowance granted to a Super App during a callback -# jailed — a Super App that violated protocol rules; its callbacks are bypassed -# configWord — bitmask encoding a Super App's app level and callback noop flags. -# App level: APP_LEVEL_FINAL (1 << 1) or APP_LEVEL_SECOND (1 << 0). -# Noop flags disable specific before/after callbacks per agreement type. -# batch operation — a single step in a batchCall array (see BatchOperation in Definitions.sol) -# trusted forwarder — a contract allowed to call forwardBatchCall for meta-transactions - -# == Batch Call == -# Primary entry point for interacting with the protocol. Users compose arrays of -# typed operations (ERC-20 approvals, SuperToken wrapping, agreement calls, etc.). -# -# == Batch Operation Types == -# Used in the operationType field of batchCall/forwardBatchCall operations. -# Data encoding varies by category — see notes on each type. -# -# Category 1–5: ERC-20/ERC-777 token ops -# target: must be a SuperToken (routes through SuperToken.operation* methods, -# NOT arbitrary ERC-20 contracts — use a separate tx for underlying approvals) -# data: abi-encoded parameters only (strip the 4-byte function selector) -# -# Category 101–102: SuperToken wrap/unwrap -# target: the SuperToken -# data: abi-encoded parameters only (strip the 4-byte function selector) -# -# Category 201: agreement call -# target: the agreement contract (e.g. CFA, GDA) -# data: abi.encode(callData, userData) where callData is full -# encodeFunctionData (selector included, with empty ctx placeholder "0x") -# -# Category 202: app action -# target: the Super App -# data: abi.encode(callData) where callData is full encodeFunctionData -# (selector included, with empty ctx placeholder "0x") -# -# Category 301: simple forward -# target: any contract -# data: full encodeFunctionData (selector included), or "0x" for pure value transfers -# -# Category 302: ERC-2771 forward -# target: any contract (must be an ERC-2771 recipient to extract the real sender) -# data: full encodeFunctionData (selector included) -# The ERC2771Forwarder appends the original msg.sender to calldata per ERC-2771. -# Use when the target contract needs to know who initiated the batch. - -batch_operation_types: - ERC20_APPROVE: 1 - ERC20_TRANSFER_FROM: 2 - ERC777_SEND: 3 # deprecated — ERC-777 is being phased out - ERC20_INCREASE_ALLOWANCE: 4 - ERC20_DECREASE_ALLOWANCE: 5 - SUPERTOKEN_UPGRADE: 101 - SUPERTOKEN_DOWNGRADE: 102 - SUPERFLUID_CALL_AGREEMENT: 201 - CALL_APP_ACTION: 202 - SIMPLE_FORWARD_CALL: 301 - ERC2771_FORWARD_CALL: 302 - -batchCall: - # Execute an array of operations in a single transaction as msg.sender. - notes: - - "Gotcha: For SIMPLE_FORWARD_CALL (type 301), target sees msg.sender as the SimpleForwarder contract, NOT the original caller. Use only when the target doesn't need to identify the sender." - - "Gotcha: ERC-20 ops (types 1-5) route through SuperToken.operation* methods, NOT arbitrary ERC-20 contracts. The target must be a SuperToken address. To approve an underlying ERC-20 (e.g. for wrapping), use a separate transaction." - - "Gotcha: If msg.value > 0, the entire amount is forwarded to the first CALL_APP_ACTION, SIMPLE_FORWARD, or ERC2771_FORWARD operation. If none exist, the native tokens are returned to the sender." - mutability: payable - access: anyone - inputs: - - operations: tuple[] - components: - - operationType: uint32 # see batch_operation_types above - - target: address - - data: bytes # encoding varies by operationType — see above - errors: [HOST_UNKNOWN_BATCH_CALL_OPERATION_TYPE] - -forwardBatchCall: - # Same as batchCall but uses EIP-2771 to extract msgSender from calldata. - # Can only be called by contracts registered as trusted forwarders in governance. - # If native tokens are left over, they are refunded to the EIP-2771 sender. - mutability: payable - access: trusted-forwarder - inputs: - - operations: tuple[] - components: - - operationType: uint32 # see batch_operation_types above - - target: address - - data: bytes # encoding varies by operationType — see above - errors: [HOST_UNKNOWN_BATCH_CALL_OPERATION_TYPE] - -# == Contextless Call Proxies == -# Entry points for EOAs and non-app contracts to interact with agreements or apps. -# These create a fresh Superfluid context with msg.sender, inject it into the call, -# and route through to the target agreement/app. - -callAgreement: - # Call an agreement function. The Host creates a context with msg.sender and replaces - # the placeholder ctx bytes in callData. This is how EOAs interact with CFA/IDA/GDA. - mutability: nonpayable - access: anyone # context set to msg.sender - inputs: - - agreementClass: address # must be a registered agreement - - callData: bytes # abi-encoded agreement call with placeholder ctx - - userData: bytes # extra data forwarded to Super App callbacks - outputs: - - returnedData: bytes - errors: [APP_RULE, HOST_ONLY_LISTED_AGREEMENT] - -callAppAction: - # Call an app action function on a Super App. The Host creates a context and routes - # the call. The action must not be an agreement callback selector. - mutability: nonpayable - access: anyone # context set to msg.sender - inputs: - - app: address # must be a registered, non-jailed Super App - - callData: bytes # abi-encoded app action call with placeholder ctx - outputs: - - returnedData: bytes - errors: [APP_RULE, HOST_NOT_A_SUPER_APP, HOST_SUPER_APP_IS_JAILED, HOST_AGREEMENT_CALLBACK_IS_NOT_ACTION] - -# == Contextual Call Proxies == -# For Super Apps to chain calls during callbacks. The app must pass the ctx it received. -# Only callable by the app currently executing a callback (ctx.appAddress == msg.sender). - -callAgreementWithContext: - # Chain an agreement call from within a Super App callback. - # The ctx must be valid and msg.sender must be the current callback app. - mutability: nonpayable - access: super-app - inputs: - - agreementClass: address - - callData: bytes - - userData: bytes - - ctx: bytes - outputs: - - newCtx: bytes - - returnedData: bytes - errors: [APP_RULE, HOST_ONLY_LISTED_AGREEMENT, HOST_CALL_AGREEMENT_WITH_CTX_FROM_WRONG_ADDRESS] - -callAppActionWithContext: - # Chain an app action call from within a Super App callback. - mutability: nonpayable - access: super-app - inputs: - - app: address - - callData: bytes - - ctx: bytes - outputs: - - newCtx: bytes - errors: [APP_RULE, HOST_NOT_A_SUPER_APP, HOST_SUPER_APP_IS_JAILED, HOST_AGREEMENT_CALLBACK_IS_NOT_ACTION, HOST_CALL_APP_ACTION_WITH_CTX_FROM_WRONG_ADDRESS] - -# == Context Utilities == - -decodeCtx: - # Decode a raw context bytes blob into the structured Context fields. - mutability: pure - inputs: - - ctx: bytes - outputs: - - context: - type: tuple - components: - - appCallbackLevel: uint8 - - callType: uint8 - - timestamp: uint256 - - msgSender: address - - agreementSelector: bytes4 - - userData: bytes - - appCreditGranted: uint256 - - appCreditWantedDeprecated: uint256 - - appCreditUsed: int256 - - appAddress: address - - appCreditToken: address - -isCtxValid: - # Check if a context blob matches the current transaction's context stamp. - mutability: view - inputs: - - ctx: bytes - outputs: - - bool - -# == App Registry == -# Super App registration. On some deployments, governance permission (via SimpleACL -# or legacy governance config) is required before an app can register. - -registerApp: - # Register msg.sender as a Super App with the given config word. - # On whitelisting-enabled deployments, tx.origin must have the - # ACL_SUPERAPP_REGISTRATION_ROLE or a valid legacy governance key. - mutability: nonpayable - access: self - inputs: - - configWord: uint256 # Super App manifest flags (see SuperAppDefinitions) - emits: [AppRegistered] - errors: [HOST_NO_APP_REGISTRATION_PERMISSION, HOST_INVALID_CONFIG_WORD, HOST_SUPER_APP_ALREADY_REGISTERED] - -registerApp(address,uint256): - # Register an external contract as a Super App. - # Useful for factory patterns where the deployer registers the app. - mutability: nonpayable - access: anyone - inputs: - - app: address # must be a contract - - configWord: uint256 - emits: [AppRegistered] - errors: [HOST_MUST_BE_CONTRACT, HOST_NO_APP_REGISTRATION_PERMISSION, HOST_INVALID_CONFIG_WORD, HOST_SUPER_APP_ALREADY_REGISTERED] - -registerAppWithKey: - # DEPRECATED — use registerApp(uint256) instead. - # Legacy registration using a governance-provided registration key string. - mutability: nonpayable - access: self - inputs: - - configWord: uint256 - - registrationKey: string - emits: [AppRegistered] - errors: [HOST_NO_APP_REGISTRATION_PERMISSION, HOST_INVALID_CONFIG_WORD, HOST_SUPER_APP_ALREADY_REGISTERED] - -registerAppByFactory: - # DEPRECATED — use registerApp(address, uint256) instead. - # Legacy factory-based registration using governance-authorized factory addresses. - mutability: nonpayable - access: factory - inputs: - - app: address - - configWord: uint256 - emits: [AppRegistered] - errors: [HOST_MUST_BE_CONTRACT, HOST_NO_APP_REGISTRATION_PERMISSION, HOST_INVALID_CONFIG_WORD, HOST_SUPER_APP_ALREADY_REGISTERED] - -# == App Queries == - -isApp: - mutability: view - inputs: - - app: address - outputs: - - bool - -getAppCallbackLevel: - mutability: view - inputs: - - appAddr: address - outputs: - - uint8 - -getAppManifest: - # Returns the full manifest of a Super App. - # isSuperApp is false if the address was never registered. - mutability: view - inputs: - - app: address - outputs: - - isSuperApp: bool - - isJailed: bool - - noopMask: uint256 # bitmask of noop'd agreement callback selectors - -isAppJailed: - mutability: view - inputs: - - app: address - outputs: - - isJail: bool - -# == App Composition == -# Source apps can whitelist target apps for composability (calling downstream). -# Currently limited to MAX_APP_CALLBACK_LEVEL = 1 (one level of nesting). - -allowCompositeApp: - # Whitelist a target Super App for composition. msg.sender must be a Super App - # with a higher callback level than the target. - mutability: nonpayable - access: super-app - inputs: - - targetApp: address - errors: [HOST_SENDER_IS_NOT_SUPER_APP, HOST_RECEIVER_IS_NOT_SUPER_APP, HOST_SOURCE_APP_NEEDS_HIGHER_APP_LEVEL] - -isCompositeAppAllowed: - mutability: view - inputs: - - app: address - - targetApp: address - outputs: - - isAppAllowed: bool - -# == Agreement Framework == -# Internal protocol functions called by registered agreement contracts (CFA, IDA, GDA) -# to manage Super App callbacks and app credit. Only callable by agreements. -# -# Callback lifecycle (called by agreement during flow operations): -# 1. appCallbackPush — set up credit, push callback frame -# 2. callAppBeforeCallback — staticcall app's before hook (read-only) -# 3. (agreement executes core logic) -# 4. callAppAfterCallback — call app's after hook (state changes OK) -# 5. appCallbackPop — finalize credit accounting, pop frame - -callAppBeforeCallback: - # StaticCall a Super App's before-callback. Returns the callback data. - # If the callback reverts during a termination, the app is jailed instead of reverting. - mutability: nonpayable - access: agreement - inputs: - - app: address - - callData: bytes - - isTermination: bool - - ctx: bytes - outputs: - - cbdata: bytes - errors: [HOST_ONLY_LISTED_AGREEMENT, HOST_NEED_MORE_GAS, APP_RULE] - -callAppAfterCallback: - # Call a Super App's after-callback. Returns the (potentially modified) context. - # If the app returns an invalid ctx, it is jailed on termination or reverts otherwise. - mutability: nonpayable - access: agreement - inputs: - - app: address - - callData: bytes - - isTermination: bool - - ctx: bytes - outputs: - - newCtx: bytes - errors: [HOST_ONLY_LISTED_AGREEMENT, HOST_NEED_MORE_GAS, APP_RULE] - -appCallbackPush: - # Push a new callback frame onto the context stack before invoking a Super App. - # Sets up app credit and tracks the callback nesting level. - notes: - - "Gotcha: The appCreditGranted is backed by the flow sender's deposit as \"owed deposit\". If the Super App opens outgoing streams using this credit, the sender's total locked capital increases accordingly (roughly doubles for 1:1 relay, more for fan-out patterns)." - mutability: nonpayable - access: agreement - inputs: - - ctx: bytes - - app: address - - appCreditGranted: uint256 - - appCreditUsed: int256 - - appCreditToken: address - outputs: - - appCtx: bytes - errors: [HOST_ONLY_LISTED_AGREEMENT, APP_RULE] - -appCallbackPop: - # Pop the callback frame after a Super App callback completes. - # Adjusts appCreditUsed by the delta from the callback. - mutability: nonpayable - access: agreement - inputs: - - ctx: bytes - - appCreditUsedDelta: int256 - outputs: - - newCtx: bytes - errors: [HOST_ONLY_LISTED_AGREEMENT] - -ctxUseCredit: - # Record additional app credit usage during an agreement operation. - mutability: nonpayable - access: agreement - inputs: - - ctx: bytes - - appCreditUsedMore: int256 - outputs: - - newCtx: bytes - errors: [HOST_ONLY_LISTED_AGREEMENT] - -jailApp: - # Jail a Super App from within an agreement. Jailed apps have their callbacks bypassed. - mutability: nonpayable - access: agreement - inputs: - - ctx: bytes - - app: address - - reason: uint256 # see SuperAppDefinitions for jail reason codes - outputs: - - newCtx: bytes - emits: [Jail] - errors: [HOST_ONLY_LISTED_AGREEMENT] - -# == Governance == - -getGovernance: - mutability: view - outputs: - - governance: address - -replaceGovernance: - mutability: nonpayable - access: governance - inputs: - - newGov: address - emits: [GovernanceReplaced] - errors: [HOST_ONLY_GOVERNANCE] - -# == Agreement Whitelisting == -# Governance registers and upgrades agreement classes (CFA, IDA, GDA). - -registerAgreementClass: - # Register a new agreement class. Creates a UUPS proxy in upgradable deployments. - mutability: nonpayable - access: governance - inputs: - - agreementClassLogic: address - emits: [AgreementClassRegistered] - errors: [HOST_ONLY_GOVERNANCE, HOST_AGREEMENT_ALREADY_REGISTERED, HOST_MAX_256_AGREEMENTS] - -updateAgreementClass: - # Upgrade an existing agreement class to a new implementation. - mutability: nonpayable - access: governance - inputs: - - agreementClassLogic: address - emits: [AgreementClassUpdated] - errors: [HOST_ONLY_GOVERNANCE, HOST_NON_UPGRADEABLE, HOST_AGREEMENT_IS_NOT_REGISTERED] - -isAgreementTypeListed: - mutability: view - inputs: - - agreementType: bytes32 # keccak256 of agreement name string - outputs: - - yes: bool - -isAgreementClassListed: - mutability: view - inputs: - - agreementClass: address - outputs: - - yes: bool - -getAgreementClass: - mutability: view - inputs: - - agreementType: bytes32 - outputs: - - agreementClass: address - errors: [HOST_AGREEMENT_IS_NOT_REGISTERED] - -mapAgreementClasses: - # Decode a bitmap into an array of agreement class addresses. - mutability: view - inputs: - - bitmap: uint256 - outputs: - - agreementClasses: address[] - -addToAgreementClassesBitmap: - mutability: view - inputs: - - bitmap: uint256 - - agreementType: bytes32 - outputs: - - newBitmap: uint256 - errors: [HOST_AGREEMENT_IS_NOT_REGISTERED] - -removeFromAgreementClassesBitmap: - mutability: view - inputs: - - bitmap: uint256 - - agreementType: bytes32 - outputs: - - newBitmap: uint256 - errors: [HOST_AGREEMENT_IS_NOT_REGISTERED] - -# == Super Token Factory == - -getSuperTokenFactory: - mutability: view - outputs: - - factory: address - -getSuperTokenFactoryLogic: - # Returns the logic address behind the factory proxy. For non-upgradable - # deployments, returns the factory address itself. - mutability: view - outputs: - - logic: address - -updateSuperTokenFactory: - # Deploy or upgrade the SuperTokenFactory. On first call, creates a UUPS proxy. - mutability: nonpayable - access: governance - inputs: - - newFactory: address - emits: [SuperTokenFactoryUpdated] - errors: [HOST_ONLY_GOVERNANCE, HOST_NON_UPGRADEABLE] - -updateSuperTokenLogic: - # Upgrade a SuperToken proxy to new logic. If newLogicOverride is address(0), - # uses the canonical logic from the SuperTokenFactory. - mutability: nonpayable - access: governance - inputs: - - token: address - - newLogicOverride: address # address(0) means use canonical logic - emits: [SuperTokenLogicUpdated] - errors: [HOST_ONLY_GOVERNANCE] - -changeSuperTokenAdmin: - # Change the admin of a SuperToken. The admin is the only account allowed to - # upgrade the token logic. Default admin is the Host itself. - mutability: nonpayable - access: governance - inputs: - - token: address - - newAdmin: address - errors: [HOST_ONLY_GOVERNANCE] - -# == Pool Beacon == - -updatePoolBeaconLogic: - # Upgrade the SuperfluidPool beacon to new logic. Affects all GDA pool proxies. - mutability: nonpayable - access: governance - inputs: - - newLogic: address - emits: [PoolBeaconLogicUpdated] - errors: [HOST_ONLY_GOVERNANCE] - -# == ERC2771 / Forwarder == - -isTrustedForwarder: - # Check if an address is a governance-approved trusted forwarder for meta-transactions. - mutability: view - inputs: - - forwarder: address - outputs: - - bool - -versionRecipient: - # ERC2771 relay recipient version string. Returns "v1". - mutability: pure - outputs: - - string - -getERC2771Forwarder: - # Returns the ERC2771Forwarder contract used for ERC2771_FORWARD_CALL batch operations. - mutability: view - outputs: - - address - -getSimpleACL: - # Returns the SimpleACL contract used for Super App registration permissioning. - mutability: view - outputs: - - address - -# == Time == - -getNow: - # Returns block.timestamp. Useful for off-chain tooling and testing. - mutability: view - outputs: - - uint256 - -# == Protocol Constants == - -NON_UPGRADABLE_DEPLOYMENT: - # True if the Host was deployed in non-upgradable mode. - mutability: view - outputs: - - bool - -APP_WHITE_LISTING_ENABLED: - # True if Super App registration requires governance permission. - mutability: view - outputs: - - bool - -CALLBACK_GAS_LIMIT: - # Maximum gas forwarded to Super App callbacks. - mutability: view - outputs: - - uint64 - -MAX_APP_CALLBACK_LEVEL: - # Maximum callback nesting depth for composed Super Apps. Currently 1. - mutability: view - outputs: - - uint256 - -MAX_NUM_AGREEMENTS: - # Maximum number of agreement classes that can be registered. 256. - mutability: view - outputs: - - uint32 - -ACL_SUPERAPP_REGISTRATION_ROLE: - # keccak256("ACL_SUPERAPP_REGISTRATION_ROLE") — the SimpleACL role for app registration. - mutability: view - outputs: - - bytes32 - -SIMPLE_FORWARDER: - # Address of the SimpleForwarder used for SIMPLE_FORWARD_CALL batch operations. - mutability: view - outputs: - - address - -# == Events == - -events: - GovernanceReplaced: - data: - - oldGov: address - - newGov: address - - AgreementClassRegistered: - # agreementType is keccak256("org.superfluid-finance.agreements..") - data: - - agreementType: bytes32 - - code: address - - AgreementClassUpdated: - data: - - agreementType: bytes32 - - code: address - - SuperTokenFactoryUpdated: - data: - - newFactory: address - - SuperTokenLogicUpdated: - indexed: - - token: address - data: - - code: address - - PoolBeaconLogicUpdated: - indexed: - - beaconProxy: address - data: - - newBeaconLogic: address - - AppRegistered: - indexed: - - app: address - - Jail: - # Emitted when a Super App is jailed for violating protocol rules. - # See APP_RULE error below for reason code values. - indexed: - - app: address - data: - - reason: uint256 - - # Inherited events (from UUPSProxiable): - # CodeUpdated — emitted on proxy upgrade (uuid, codeAddress) - # Initialized — emitted on proxy initialization (version) - -# == Errors == - -errors: - # Governance - - HOST_ONLY_GOVERNANCE # caller is not the governance contract - - # Agreement whitelisting - - HOST_AGREEMENT_ALREADY_REGISTERED - - HOST_AGREEMENT_IS_NOT_REGISTERED - - HOST_MAX_256_AGREEMENTS # maximum agreement slots exhausted - - HOST_ONLY_LISTED_AGREEMENT # caller is not a registered agreement - - # Upgradability - - HOST_NON_UPGRADEABLE # deployment is non-upgradable - - HOST_CANNOT_DOWNGRADE_TO_NON_UPGRADEABLE - - # App registration - - HOST_MUST_BE_CONTRACT # app address has no code - - HOST_NO_APP_REGISTRATION_PERMISSION - - HOST_INVALID_CONFIG_WORD # invalid Super App manifest flags - - HOST_SUPER_APP_ALREADY_REGISTERED - - HOST_NOT_A_SUPER_APP # target is not a registered Super App - - HOST_SUPER_APP_IS_JAILED - - # App composition - - HOST_SENDER_IS_NOT_SUPER_APP - - HOST_RECEIVER_IS_NOT_SUPER_APP - - HOST_SOURCE_APP_NEEDS_HIGHER_APP_LEVEL - - # Context & call proxies - - HOST_NON_ZERO_LENGTH_PLACEHOLDER_CTX # placeholder ctx must be empty - - HOST_CALL_AGREEMENT_WITH_CTX_FROM_WRONG_ADDRESS # msg.sender != ctx.appAddress - - HOST_CALL_APP_ACTION_WITH_CTX_FROM_WRONG_ADDRESS # msg.sender != ctx.appAddress - - HOST_AGREEMENT_CALLBACK_IS_NOT_ACTION # app action selector matches a callback - - # Batch call - - HOST_UNKNOWN_BATCH_CALL_OPERATION_TYPE - - # Callback execution - - HOST_NEED_MORE_GAS # insufficient gas for Super App callback - - # Super App rule violations (generic, carries a reason code) - # Reason codes (from SuperAppDefinitions.sol): - # 10 — NO_REVERT_ON_TERMINATION_CALLBACK (delete callback reverted) - # 11 — NO_CRITICAL_SENDER_ACCOUNT (callback made sender critical) - # 12 — NO_CRITICAL_RECEIVER_ACCOUNT (callback made receiver critical) - # 20 — CTX_IS_READONLY (state change in before-callback staticcall) - # 21 — CTX_IS_NOT_CLEAN (context not properly returned) - # 22 — CTX_IS_MALFORMATED (context bytes corrupted/fabricated) - # 30 — COMPOSITE_APP_IS_NOT_WHITELISTED (no allowCompositeApp) - # 31 — COMPOSITE_APP_IS_JAILED (downstream app is jailed) - # 40 — MAX_APP_LEVEL_REACHED (callback nesting exceeded limit) - - APP_RULE: - inputs: - - _code: uint256 - - # SafeCast (inherited from OpenZeppelin) - - SafeCastOverflowedUintDowncast: - inputs: - - bits: uint8 - - value: uint256 diff --git a/.agents/skills/gooddollar/references/contracts/Superfluid.selectors.yaml b/.agents/skills/gooddollar/references/contracts/Superfluid.selectors.yaml deleted file mode 100644 index 18edf9b..0000000 --- a/.agents/skills/gooddollar/references/contracts/Superfluid.selectors.yaml +++ /dev/null @@ -1,51 +0,0 @@ -# Generated by scripts/selectors.mjs -functions: - batchCall(tuple[]): 0x31131761 - forwardBatchCall(tuple[]): 0xbc5a2101 - callAgreement(): 0xb7a9d0f0 - callAppAction(): 0x40df3d29 - callAgreementWithContext(address,bytes,bytes,bytes): 0x4329d293 - callAppActionWithContext(address,bytes,bytes): 0xba48b5f8 - decodeCtx(bytes): 0x3f6c923a - isCtxValid(bytes): 0xbf428734 - registerApp(): 0x6d6c85c3 - registerAppWithKey(uint256,string): 0xbd1c448b - registerAppByFactory(address,uint256): 0xf3733052 - isApp(address): 0x3ca3ad4e - getAppCallbackLevel(address): 0x9378fa13 - getAppManifest(address): 0xf9f522f4 - isAppJailed(address): 0x6b4f3335 - allowCompositeApp(address): 0x57121e0c - isCompositeAppAllowed(address,address): 0xbb84cfa1 - callAppBeforeCallback(address,bytes,bool,bytes): 0x74041e02 - callAppAfterCallback(address,bytes,bool,bytes): 0x1e6d0a84 - appCallbackPush(bytes,address,uint256,int256,address): 0x768fabb0 - appCallbackPop(bytes,int256): 0x989b0c3e - ctxUseCredit(bytes,int256): 0x59a29141 - jailApp(bytes,address): 0x5578431e - replaceGovernance(address): 0x7283100c - registerAgreementClass(address): 0x15a024e1 - updateAgreementClass(address): 0x06cecba8 - isAgreementTypeListed(): 0xf8dba358 - isAgreementClassListed(address): 0x8ca48484 - getAgreementClass(bytes32): 0xb6d200de - mapAgreementClasses(uint256): 0xc56a069d - addToAgreementClassesBitmap(uint256,bytes32): 0xbced3ddc - removeFromAgreementClassesBitmap(uint256,bytes32): 0xa5dbbbcd - updateSuperTokenFactory(address): 0x54fbc493 - updateSuperTokenLogic(address): 0x787afde7 - changeSuperTokenAdmin(address,address): 0x0c565075 - updatePoolBeaconLogic(address): 0x2f89bf89 - isTrustedForwarder(address): 0x572b6c05 - SIMPLE_FORWARDER(): 0xf85263b9 -events: - GovernanceReplaced(address,address): 0x13abda02e63c790d0e2818b251282cfe5cbe0a8abd69c54bf5d2260c0907bd2e - AgreementClassRegistered(bytes32,address): 0x878135063a6cfb3bc333e534b1fdc83f4f12221cad6705c31c0567048a8bd3d1 - AgreementClassUpdated(bytes32,address): 0x9279aa773f2b588996032d8de89911555039f28b13a11a7c17074330bc082d9a - SuperTokenFactoryUpdated(address): 0xce13a9895a1719ad4493b2ac1a9bfb36070566161abab408e7ecbe586da8d499 - SuperTokenLogicUpdated(address,address): 0x840acbd291b38534819f47f875839277e502f40e1c7bfea2c5fc2c8017442cd3 - PoolBeaconLogicUpdated(address,address): 0x052cea8931962dd445ef48b0b998d3056bd0705f437087d60fe3c46a3fa09e1f - AppRegistered(address): 0x0d540ad8f39e07d19909687352b9fa017405d93c91a6760981fbae9cf28bfef7 - Jail(address,uint256): 0xbe3aa33bd245135e4e26b223d79d14ea479a47bff09f2b03c53838af1edbb14b - # Inherited events (from UUPSProxiable)(): 0x3a1d0f622cf5be33dc2558b359f025fbeca1d6fb271fb70452a02b0ec2666ce8 -errors: {} diff --git a/.agents/skills/gooddollar/references/contracts/UBISchemeV2.abi.yaml b/.agents/skills/gooddollar/references/contracts/UBISchemeV2.abi.yaml deleted file mode 100644 index 75e5e43..0000000 --- a/.agents/skills/gooddollar/references/contracts/UBISchemeV2.abi.yaml +++ /dev/null @@ -1,305 +0,0 @@ -# UBISchemeV2 — dynamic daily UBI pool with per-root claiming and cycle accounting -# Claim uses Identity getWhitelistedRoot(msg.sender); transfers use the root as claim key. - -meta: - name: UBISchemeV2 - version: v2 - source: - - https://raw.githubusercontent.com/GoodDollar/GoodProtocol/master/contracts/ubi/UBISchemeV2.sol - inherits: [DAOUpgradeableContract] - note: > - Pool sizing uses cycleLength, reserveFactor, minActiveUsers, and on-chain G$ - balance. claim() reverts if Identity root is zero. Internal accounting keys - claims by whitelisted root, payouts go to msg.sender. - deployments: - mainnet: - production: - UBIScheme: - networkId: 122 - address: "0xd253A5203817225e9768C05E5996d642fb96bA86" - creationBlock: 15747401 - production-celo: - UBIScheme: - networkId: 42220 - address: "0x43d72Ff17701B2DA814620735C39C620Ce0ea4A1" - creationBlock: 18006679 - production-xdc: - UBIScheme: - networkId: 50 - address: "0x22867567E2D80f2049200E25C6F31CB6Ec2F0faf" - creationBlock: 95249624 - related: - - https://docs.gooddollar.org/for-developers/core-contracts/ubischeme - - references/guides/claim.md - -getClaimerCount: - mutability: view - inputs: - - day: uint256 - outputs: - - count: uint256 - -getClaimAmount: - notes: - - "Returns aggregate amount claimed for the provided day index." - mutability: view - inputs: - - day: uint256 - outputs: - - amount: uint256 - -getDailyStats: - notes: - - "Returns (claimer count, total claimed amount) for the calendar day derived from periodStart." - mutability: view - inputs: [] - outputs: - - claimerCount: uint256 - - claimAmount: uint256 - -setCycleLength: - mutability: nonpayable - access: avatar - inputs: - - _newLength: uint256 - outputs: [] - emits: [CycleLengthSet] - errors: [CYCLE_TOO_SHORT, ONLY_AVATAR] - -setDay: - notes: - - "Anyone may advance currentDay when wall-clock day crosses the next boundary." - mutability: nonpayable - inputs: [] - outputs: [] - emits: [DaySet] - -hasClaimed: - mutability: view - inputs: - - account: address - outputs: - - claimed: bool - -isNotNewUser: - mutability: view - inputs: - - _account: address - outputs: - - isReturning: bool - -estimateNextDailyUBI: - notes: - - "View-only projection when dailyUbi not yet fixed for the current wall day." - mutability: view - inputs: [] - outputs: - - projected: uint256 - -"checkEntitlement()": - notes: - - "Uses msg.sender as member; resolves Identity root before hasClaimed check." - mutability: view - inputs: [] - outputs: - - amount: uint256 - -"checkEntitlement(address)": - notes: - - "Checks claimable amount for the provided member using that account's whitelisted root." - mutability: view - inputs: - - _member: address - outputs: - - amount: uint256 - -claim: - notes: - - "Resolves whitelistedRoot = Identity.getWhitelistedRoot(msg.sender); reverts if zero." - - "_claim keys bookkeeping by root but pays msg.sender." - - "May notify ClaimersDistribution at GDAO_CLAIMERS if configured." - - "On success emits UBIClaimed; distributionFormula may emit UBICalculated, UBICycleCalculated, DaySet, WithdrawFromDao." - mutability: nonpayable - access: anyone - inputs: [] - outputs: - - didClaim: bool - errors: - - NOT_IN_PERIOD_OR_PAUSED - - NOT_WHITELISTED - - CLAIM_TRANSFER_FAILED - - DAO_TRANSFER_FAILED - -setShouldWithdrawFromDAO: - mutability: nonpayable - access: avatar - inputs: - - _shouldWithdraw: bool - outputs: [] - emits: [ShouldWithdrawFromDAOSet] - errors: [ONLY_AVATAR] - -pause: - mutability: nonpayable - access: avatar - inputs: - - _pause: bool - outputs: [] - errors: [ONLY_AVATAR] - -setNewClaimersReserveFactor: - notes: - - "Adjusts reserveFactor used by distribution formula to reserve part of pool for new claimers." - mutability: nonpayable - access: avatar - inputs: - - _reserveFactor: uint32 - outputs: [] - errors: [ONLY_AVATAR] - -withdraw: - notes: - - "Avatar-controlled treasury action transferring G$ from scheme balance to recipient." - mutability: nonpayable - access: avatar - inputs: - - _amount: uint256 - - _recipient: address - outputs: [] - errors: - - ONLY_AVATAR - - WITHDRAW_FAILED - -lastClaimed: - notes: - - "Returns last claim timestamp keyed by account root logic used by hasClaimed checks." - mutability: view - inputs: - - account: address - outputs: - - ts: uint256 - -currentDay: - mutability: view - inputs: [] - outputs: - - day: uint256 - -periodStart: - mutability: view - inputs: [] - outputs: - - ts: uint256 - -dailyUbi: - mutability: view - inputs: [] - outputs: - - amount: uint256 - -lastWithdrawDay: - mutability: view - inputs: [] - outputs: - - day: uint256 - -shouldWithdrawFromDAO: - mutability: view - inputs: [] - outputs: - - flag: bool - -cycleLength: - mutability: view - inputs: [] - outputs: - - days: uint256 - -dailyCyclePool: - mutability: view - inputs: [] - outputs: - - pool: uint256 - -startOfCycle: - mutability: view - inputs: [] - outputs: - - ts: uint256 - -currentCycleLength: - mutability: view - inputs: [] - outputs: - - length: uint256 - -minActiveUsers: - mutability: view - inputs: [] - outputs: - - n: uint256 - -totalClaimsPerUser: - mutability: view - inputs: - - account: address - outputs: - - count: uint256 - -reserveFactor: - mutability: view - inputs: [] - outputs: - - bps: uint32 - -paused: - mutability: view - inputs: [] - outputs: - - isPaused: bool - -events: - WithdrawFromDao: - indexed: [] - data: - - prevBalance: uint256 - - newBalance: uint256 - UBICalculated: - indexed: [] - data: - - day: uint256 - - dailyUbi: uint256 - - blockNumber: uint256 - UBICycleCalculated: - indexed: [] - data: - - day: uint256 - - pool: uint256 - - cycleLength: uint256 - - dailyUBIPool: uint256 - UBIClaimed: - indexed: - - claimer: address - data: - - amount: uint256 - CycleLengthSet: - indexed: [] - data: - - newCycleLength: uint256 - DaySet: - indexed: [] - data: - - newDay: uint256 - ShouldWithdrawFromDAOSet: - indexed: [] - data: - - ShouldWithdrawFromDAO: bool - -errors: - NOT_IN_PERIOD_OR_PAUSED: "not in periodStarted or paused — requireStarted modifier." - CYCLE_TOO_SHORT: "cycle must be at least 1 day long" - DAO_TRANSFER_FAILED: "DAO transfer has failed — _withdrawFromDao balance check." - NOT_WHITELISTED: "UBIScheme: not whitelisted — claim()" - CLAIM_TRANSFER_FAILED: "claim transfer failed — G$ transfer in _transferTokens." - WITHDRAW_FAILED: "withdraw failed — avatar withdraw." - ONLY_AVATAR: "Inherited avatar-only guard on DAOUpgradeable paths." diff --git a/.agents/skills/gooddollar/references/contracts/UBISchemeV2.selectors.yaml b/.agents/skills/gooddollar/references/contracts/UBISchemeV2.selectors.yaml deleted file mode 100644 index 666b89d..0000000 --- a/.agents/skills/gooddollar/references/contracts/UBISchemeV2.selectors.yaml +++ /dev/null @@ -1,40 +0,0 @@ -# Generated by scripts/selectors.mjs -functions: - getClaimerCount(uint256): 0xc7a76adf - getClaimAmount(uint256): 0xcef63600 - getDailyStats(): 0x069786ea - setCycleLength(uint256): 0x3d84ceca - setDay(): 0xdddc3616 - hasClaimed(address): 0x73b2e80e - isNotNewUser(address): 0xa21f698a - estimateNextDailyUBI(): 0xc7713870 - checkEntitlement(): 0x98d6621b - checkEntitlement(address): 0x1a787f2e - claim(): 0x4e71d92d - setShouldWithdrawFromDAO(bool): 0xde1de3a0 - pause(bool): 0x02329a29 - setNewClaimersReserveFactor(uint32): 0x414089be - withdraw(uint256,address): 0x00f714ce - lastClaimed(address): 0x013eba92 - currentDay(): 0x5c9302c9 - periodStart(): 0xeda4e6d6 - dailyUbi(): 0x1d8f5ea9 - lastWithdrawDay(): 0xd7c4cbb8 - shouldWithdrawFromDAO(): 0x456ac1c2 - cycleLength(): 0xeac471a0 - dailyCyclePool(): 0x9dc2c033 - startOfCycle(): 0xba075410 - currentCycleLength(): 0x741470ac - minActiveUsers(): 0x37658574 - totalClaimsPerUser(address): 0xcc054dfc - reserveFactor(): 0x4322b714 - paused(): 0x5c975abb -events: - WithdrawFromDao(uint256,uint256): 0x3107ec7eaa50b775d2486c7a394472235804b6fe1c0d4b7bd1d79b09df60f2ba - UBICalculated(uint256,uint256,uint256): 0x836fa39995340265746dfe9587d9fe5c5de35b7bce778afd9b124ce1cfeafdc4 - UBICycleCalculated(uint256,uint256,uint256,uint256): 0x83e0d535b9e84324e0a25922406398d6ff5f96d0c686204ee490e16d7670566f - UBIClaimed(address,uint256): 0x89ed24731df6b066e4c5186901fffdba18cd9a10f07494aff900bdee260d1304 - CycleLengthSet(uint256): 0xa61e6cca2c12e2a0a493683acfe95b034f0f50d793434f4dfe3ba06ea201f344 - DaySet(uint256): 0x67eb03bd555181f9dd23f546e4331ddfb8b4a7d0c8d261ba44e037f30ce894ea - ShouldWithdrawFromDAOSet(bool): 0x6cd9a0fd2e006be39a9918bf56c85cae1d4f4599474483ff18cb93355ebaaf8e -errors: {} diff --git a/.agents/skills/gooddollar/references/contracts/_rich-abi-yaml-format.md b/.agents/skills/gooddollar/references/contracts/_rich-abi-yaml-format.md deleted file mode 100644 index 41e2bae..0000000 --- a/.agents/skills/gooddollar/references/contracts/_rich-abi-yaml-format.md +++ /dev/null @@ -1,93 +0,0 @@ -# Reading the Rich ABI YAMLs - -Each YAML is a self-contained contract reference. Here's how to parse them. - -## Root structure - -``` -# Header comment — contract name, description, key notes -meta: # name, version, source, implements, inherits, deployments, - # deploymentCreationBlocks (optional), notes -# == Section == # Grouped functions (these are the core content) -events: # All events the contract emits -errors: # Complete error index -``` - -Three root keys are reserved: `meta`, `events`, `errors`. Every other -root-level key is a **function**. - -## Function entries - -```yaml -createFlow: - # Description of what the function does. - notes: - - "Gotcha: Non-obvious behavior or edge cases listed here as structured data." - mutability: nonpayable # view | pure | nonpayable | payable - access: sender | operator # who can call (omitted for view/pure) - inputs: - - token: address - - receiver: address - - flowRate: int96 # inline comments for non-obvious params - - ctx: bytes - outputs: - - newCtx: bytes - emits: [FlowUpdated, FlowUpdatedExtension] # ordered by emission sequence - errors: [CFA_FLOW_ALREADY_EXISTS, CFA_INVALID_FLOW_RATE] # ordered by check sequence -``` - -Fields appear in this order: description comment, `notes`, `mutability`, -`access`, `inputs`, `outputs`, `emits`, `errors`. All are omitted when not -applicable. - -## Key conventions - -- **`ctx: bytes` parameter** = function is called through the Host - (`callAgreement` / `batchCall`), never directly. -- **`access` labels**: `anyone`, `host`, `self`, `admin`, `governance`, - `sender`, `receiver`, `operator`, `manager`, `pic`, `agreement`, - `trusted-forwarder`, `factory`, `super-app`. Combine with `|`. Conditional: - `anyone(if-critical-or-jailed)`. -- **`emits` and `errors` ordering** carries meaning: matches execution flow, - not alphabetical. First errors in the list are the most likely causes. -- **`notes:` field** on functions (and `meta.notes:` at contract level) - lists non-obvious behavior, common mistakes, or edge cases. Always read - these carefully. -- **`meta.source`** is an array of raw GitHub URLs to the Solidity source files - (implementation, interface, base — filenames are self-documenting). -- **`meta.deployments`** has per-network addresses split into `mainnet` and - `testnet` subgroups. -- **`creationBlock`**: decimal block where that **`address`** first has code; - put it on the same object as **`networkId`** / **`address`**, immediately after **`address`**. -- **`meta.deploymentCreationBlocks`**: same shape as **`meta.deployments`**, for - deployments stored as plain address strings; leaves are decimal block numbers. - -## Events section - -```yaml -events: - FlowUpdated: - indexed: # log topics (filterable) - - token: address - - sender: address - data: # log payload - - flowRate: int96 -``` - -## Errors section - -```yaml -errors: - # -- Category -- - - SIMPLE_ERROR # description - - PARAMETERIZED_ERROR: # errors with diagnostic data - inputs: - - value: uint256 -``` - -## Selector sidecar files - -Every `Foo.abi.yaml` has a companion `Foo.selectors.yaml` in the same -directory. These contain computed hex selectors (function 4-byte, error -4-byte, event 32-byte topic0) with full Solidity signatures for -verification. Generated by `scripts/selectors.mjs`. diff --git a/.agents/skills/gooddollar/references/deep-researches/faucet-flows.md b/.agents/skills/gooddollar/references/deep-researches/faucet-flows.md deleted file mode 100644 index 12b1899..0000000 --- a/.agents/skills/gooddollar/references/deep-researches/faucet-flows.md +++ /dev/null @@ -1,42 +0,0 @@ -# Faucet flows (user-facing explanation) - -This note explains the Faucet in plain language: what it does for users, why a top-up can fail, and what limits exist. - -The on-chain Faucet contract is used to add a small amount of native gas token to a wallet so the user can pay transaction fees. -Reference implementation: [`contracts/fuseFaucet/Faucet.sol`](https://github.com/GoodDollar/GoodProtocol/blob/master/contracts/fuseFaucet/Faucet.sol). -Addresses per chain: [deployment.json](https://github.com/GoodDollar/GoodProtocol/blob/master/releases/deployment.json) only (for example `Faucet` under `production`, `production-celo`, `production-xdc`). - -## What this means for users - -- If your wallet is eligible, Faucet can send a small gas top-up. -- Eligibility usually depends on identity status and anti-abuse limits. -- This is a support mechanism for transaction fees, not a general transfer or swap service. - -## Main actions (in user language) - -- **Top up wallet** (`topWallet`) - Attempts to send gas to the target wallet after checks pass. - -- **Check eligibility first** (`canTop`) - Fast pre-check to see if top-up is currently allowed. - -- **Estimate top-up amount** (`getToppingAmount`) - Shows the amount Faucet would try to send right now. - -## Why a top-up may fail - -- You are not currently authorized by identity rules. -- Daily limit reached. -- Weekly limit reached. -- Wallet is temporarily banned. -- Wallet is too new for current policy. -- Calculated top-up is below minimum threshold. - -## Important safety note - -- The `onTokenTransfer` path includes a swap-like mechanism and is not meant as a normal user swap route. -- It does not enforce slippage protection in the same way users expect from a dedicated swap UI. - -## For developers and agents - -Use `references/guides/faucet.md` for step-by-step execution flow and deterministic preflight calls. diff --git a/.agents/skills/gooddollar/references/deep-researches/fuse-to-celo-staking-migration.md b/.agents/skills/gooddollar/references/deep-researches/fuse-to-celo-staking-migration.md deleted file mode 100644 index 261c2d7..0000000 --- a/.agents/skills/gooddollar/references/deep-researches/fuse-to-celo-staking-migration.md +++ /dev/null @@ -1,38 +0,0 @@ -# Why Fuse to CELO staking migration uses a staged backend flow - -This explains why the migration is split into allowance detection, unstake, bridge, and destination re-stake instead of a single transaction. In this context, Fuse `GovernanceStakingV2` is the old/source staking contract and Celo **`GooddollarSavingsStream`** is the destination staking contract ([source](https://github.com/Ubeswap/gooddollar-contracts/blob/main/contracts/GooddollarSavingsStream.sol), [0x059ee811414230d1Fb157878D2b491240F4D8d3B](https://celoscan.io/address/0x059ee811414230d1Fb157878D2b491240F4D8d3B)). - -## Why this cannot be one-chain atomic - -Fuse governance staking and CELO destination savings live on different chains, so the system cannot atomically close and reopen stake in one EVM transaction. Cross-chain migration is asynchronous by design and must tolerate timing gaps between source completion and destination finalization. - -## Why user allowance is first - -The migration flow assumes a backend-operated execution wallet. If that wallet needs to pull or operate on user funds in the source path, user approval must exist first. Without allowance, all downstream steps fail, so approval state is the earliest hard gate. - -## Why unstake is separated from bridge - -The source staking position is the canonical balance record on Fuse. The migration must first materialize transferable G$ by closing or reducing stake, then bridge only the confirmed unlocked amount. Bridging before final unstake confirmation introduces mismatch risk. - -## Why bridge finalization must be explicit - -Bridge transfers are eventually consistent across chains. The destination stake step must only run after the bridged G$ is confirmed on CELO. This avoids phantom staking attempts and preserves deterministic accounting. - -## Why destination uses `stakeFor` - -Ubeswap `GooddollarSavingsStream` on Celo supports `stakeFor(amount, recipient)`, which allows the backend execution wallet to stake on behalf of the user after bridge finalization. This fits migration operations where custody is temporary during the transfer window. - -## Main operational risks - -- partial migration from source unstake or bridge limit constraints -- stuck-in-transit bridge messages delaying destination staking -- stale assumptions about contract addresses across networks -- reward expectation mismatch when moving from Fuse governance staking mechanics to CELO savings mechanics - -## Contract/source map - -- Fuse staking family (GoodProtocol): [`GovernanceStaking.sol`](https://github.com/GoodDollar/GoodProtocol/blob/master/contracts/governance/GovernanceStaking.sol) -- Fuse deployment mapping: [`deployment.json`](https://github.com/GoodDollar/GoodProtocol/blob/master/releases/deployment.json) (`production.GovernanceStakingV2`) -- Celo savings (Ubeswap): [`GooddollarSavingsStream.sol`](https://github.com/Ubeswap/gooddollar-contracts/blob/main/contracts/GooddollarSavingsStream.sol) -- Ubeswap contracts repository: [Ubeswap/gooddollar-contracts](https://github.com/Ubeswap/gooddollar-contracts) -- Bridge normalization for LZ quotes: [`BridgeHelperLibrary.normalizeFromTokenTo18Decimals`](https://github.com/GoodDollar/GoodBridge/blob/master/packages/bridge-contracts/contracts/messagePassingBridge/BridgeHelperLibrary.sol) (off-chain LayerZero fee estimation must match this; `canBridge` and `bridgeToWithLz` use the raw burn amount on the source chain) diff --git a/.agents/skills/gooddollar/references/deep-researches/gooddao-daostack-surface.md b/.agents/skills/gooddollar/references/deep-researches/gooddao-daostack-surface.md deleted file mode 100644 index 754a3a0..0000000 --- a/.agents/skills/gooddollar/references/deep-researches/gooddao-daostack-surface.md +++ /dev/null @@ -1,37 +0,0 @@ -# GoodDAO and DAOStack surface - -GoodProtocol’s on-chain **governance shell** is largely **DAOStack-shaped**: an **Avatar** holds protocol assets and reputation context; a **Controller** registers **schemes** and routes privileged calls. GoodDocs summarizes DAO-facing roles; **Avatar**, **Controller**, and other DAO contract addresses live only in [deployment.json](https://github.com/GoodDollar/GoodProtocol/blob/master/releases/deployment.json). Implementation follows [DAOStack Arc](https://github.com/daostack/arc) patterns. - -## Core interfaces (GoodProtocol) - -[`DAOStackInterfaces.sol`](https://github.com/GoodDollar/GoodProtocol/blob/master/contracts/DAOStackInterfaces.sol) defines the pieces most integrations touch: - -### Avatar - -- **`nativeToken()`** — often the G$ token address for the deployment. -- **`nativeReputation()`** — **`GReputation`** token for voting weight (see `GReputation` in `deployment.json`). -- **`owner()`** — owner of the Avatar, typically the **`Controller`** contract. - -### Controller - -- **`avatar()`** — address of the Avatar contract. -- **`registerScheme` / `unregisterScheme` / `unregisterSelf` / `isSchemeRegistered` / `getSchemePermissions`** — scheme lifecycle and permission bitmask per scheme+avatar. -- **`genericCall(contract, data, avatar, value)`** — executes arbitrary calls **as the avatar** (used heavily by DAO-backed contracts to move tokens or call NameService). -- **`mintTokens`**, **`externalTokenTransfer`**, **`sendEther`** — treasury-style operations through the controller/avatar. - -## How GoodProtocol contracts use it - -- **`DAOUpgradeableContract`** / **`DAOContract`** descendants resolve **`dao`** (Controller) and **`avatar`** from **NameService** keys such as **`CONTROLLER`** and **`AVATAR`** (also written during **NameService.initialize**). -- **Avatar-gated writes** (for example **NameService.setAddress**, **UBISchemeV2** admin functions, **IdentityV3** after `initDAO`) require **`msg.sender == dao.avatar()`** (or equivalent role), not EOAs. -- Schemes that upgrade themselves (for example staking **`upgrade()`**) use **`dao.genericCall`** and **`unregisterSelf`** against the avatar. - -## What agents should do - -1. Treat **DAO calls** as **governance-only** unless the user explicitly controls the avatar or a registered scheme. -2. For **read-only** work, use **NameService** and per-contract **view** functions; use **Controller.isSchemeRegistered** when validating that a target contract is an approved scheme (for example staking migrations). -3. Never fabricate **Avatar** or **Controller** addresses — use [deployment.json](https://github.com/GoodDollar/GoodProtocol/blob/master/releases/deployment.json) or NameService. - -## References - -- [Core contracts — DAO contracts](https://docs.gooddollar.org/for-developers/core-contracts) (narrative only; addresses from [deployment.json](https://github.com/GoodDollar/GoodProtocol/blob/master/releases/deployment.json) only) -- DAOStack Arc controller and avatar concepts in the upstream repo linked from GoodDocs. diff --git a/.agents/skills/gooddollar/references/deep-researches/how-ubi-is-minted.md b/.agents/skills/gooddollar/references/deep-researches/how-ubi-is-minted.md deleted file mode 100644 index 96d321a..0000000 --- a/.agents/skills/gooddollar/references/deep-researches/how-ubi-is-minted.md +++ /dev/null @@ -1,68 +0,0 @@ -# How UBI is minted - -This document aligns agent explanations with [How GoodDollar works](https://docs.gooddollar.org/how-gooddollar-works) and GoodDocs component pages; **contract addresses** come only from [deployment.json](https://github.com/GoodDollar/GoodProtocol/blob/master/releases/deployment.json). - -## Monetary creation (protocol level) - -- New G$ is created in connection with reserve mechanics: purchases into the reserve and reserve-side parameters (including reserve ratio) influence how much G$ can be issued while maintaining backing (see sustainability and issuance sections in GoodDocs). -- Selling G$ back to the reserve burns supply in that model. -- G$ that the protocol creates is allocated across UBI, savings incentives, treasury, and ecosystem uses per the distribution section of GoodDocs. - -## Where G$ is actually created - -Creation happens at the G$ token `mint(...)` call site, not inside `UBIScheme.claim()`. - -Current implementation uses the Mento-core expansion path: - -- `GoodDollarExpansionController` mints and routes to distribution helper. - -**DistributionHelper recipients** decide how much eventually lands in the UBI pool. - -## Claim vs reserve minting (important distinction) - -- **Reserve path:** Buying G$ through the reserve-backed AMM (or related Mento rails) is where mint and burn tied to the reserve model most directly apply at the token level. -- **Daily UBI `claim()`:** On `UBISchemeV2`, a successful claim typically **transfers G$ from the scheme contract’s balance** to the user (`token.transfer` in `_transferTokens`). The scheme may be **refilled** from the DAO avatar via internal `_withdrawFromDao` when configured, not necessarily minting in the same transaction as `claim()`. So describe user-facing UBI as **receipt from the UBI scheme balance**; reserve **minting** is the macro story, **transfer** is the usual claim-time mechanism. - -## Mento-core expansion flow (detailed) - -This is the detailed path for modern reserve-ratio-aware expansion. - -1. A caller triggers `mintUBIFromExpansion(exchangeId)` on `GoodDollarExpansionController`. -2. Expansion is time-gated by config (`expansionFrequency`, `lastExpansion`), so it does not run every block. -3. Controller computes a reserve-ratio scalar (effectively compounding `(1 - expansionRate)` for elapsed periods). -4. Controller calls `GoodDollarExchangeProvider.mintFromExpansion(exchangeId, reserveRatioScalar)`. -5. Exchange provider updates exchange state (including reserve-ratio math) and returns `amountToMint`. -6. Controller mints G$ to `distributionHelper`. -7. Controller triggers distribution (`onDistribution`) so recipients (including UBIScheme when configured) receive allocation. - -Also in `GoodDollarExpansionController`: - -- `mintUBIFromInterest(exchangeId, reserveInterest)` -- `mintUBIFromReserveBalance(exchangeId)` - -These are additional funding paths that mint to distribution helper as part of reserve-driven policy. - -## Reserve ratio, expansion, and risk - -- Practical reserve-ratio intuition: collateral backing strength per unit of G$ supply. -- Lower reserve ratio means weaker backing and higher risk when adding new supply. -- Expansion uses reserve-ratio-aware math instead of blind fixed minting, but aggressive params can still increase sell pressure. -- Key policy levers are expansion rate and expansion frequency (plus caller cadence/automation quality). - -## What claimers experience - -- Verified users receive daily UBI from a pool split among those who claim in each period (GoodDocs). -- The user-facing transaction is a UBIScheme-style `claim` on chains where it is deployed; ABI and version follow your deployment. - -## On-chain components (typical) - -- Identity system for verification and whitelist roots. -- UBIScheme (or successor) for entitlement and claim execution. -- G$ token: value reaches users via **transfer** from scheme balance and/or broader minting economics from the reserve side depending on which action you analyze. -- DistributionHelper: bridge layer between mint source and recipient buckets (UBI, others). - -## Agent guidance - -- Use GoodDocs for macro issuance and allocation; use UBIScheme + token transfer behavior for **claim** explanations. -- Use [deployment.json](https://github.com/GoodDollar/GoodProtocol/blob/master/releases/deployment.json) for contract addresses instead of guessing. -- When users ask "why no UBI funding today", check whether mint functions were executed, then verify DistributionHelper recipient config and UBIScheme balance. diff --git a/.agents/skills/gooddollar/references/deep-researches/inviter-invitee-reward-model.md b/.agents/skills/gooddollar/references/deep-researches/inviter-invitee-reward-model.md deleted file mode 100644 index 267fa74..0000000 --- a/.agents/skills/gooddollar/references/deep-researches/inviter-invitee-reward-model.md +++ /dev/null @@ -1,58 +0,0 @@ -# Inviter and invitee reward model - -This explains why invite rewards sometimes work and sometimes fail, in user-facing terms. - -Invite rewards are handled by `InvitesV2`, but eligibility depends heavily on the identity system (`Identity`, often `IdentityV4`). In practice, most confusing cases are caused by whitelist or reverification state, not by the invite contract itself. - -## How the reward model works - -There are two separate moments: - -- `join`: the invitee registers with an invite code. -- bounty payout: the contract later checks if this invitee is eligible and pays inviter and invitee when rules pass. - -So joining does not guarantee immediate payout. Payout depends on current eligibility at claim time. - -## Why whitelist status is the main gate - -For bounty eligibility, `InvitesV2` checks whitelist state through Identity. - -The important behavior is: - -- A user can still have status `1` in identity storage but fail `isWhitelisted(...)` if reverification is due. -- When reverification is due, bounty checks fail until an admin refreshes authentication(Face Verification). -- Connected-wallet setups can still fail if the specific address used in invite flow does not pass the whitelist check expected by the contract path. - -## Why reverification blocks rewards - -Reverification cadence is defined in `IdentityV4` with day-based options (`reverifyDaysOptions`) and per-user progression (`authCount`). - -When too many days pass since the last authentication for that user’s current step: - -- `shouldReverify(...)` becomes true -- `isWhitelisted(...)` becomes false for bounty gating -- `canCollectBountyFor(...)` fails until authentication is refreshed - -This is why teams may see users who were once valid but are currently not eligible for invite rewards. - -## Common reasons a bounty is not paid - -- Invitee or inviter is not currently whitelisted. -- Reverification is due for invitee or inviter. -- `minimumClaims` or `minimumDays` thresholds are not met yet. -- Bounty was already paid or was zero at join time. -- Contract is inactive, or identity-chain checks do not match the active chain. -- Invite code or join state is invalid (duplicate code, self-invite, already joined). - -## What to measure for analytics - -- Historical pass: account was authenticated at least once (`lastAuthenticated > 0`). -- Current eligibility: account is currently whitelist-valid (`isWhitelisted`/non-zero root, depending on query design). - -Do not treat these as the same metric. Historical pass explains past onboarding success; current eligibility explains current payout success. - -## Contract sources - -- Invite contract: [`InvitesV2.sol`](https://github.com/GoodDollar/GoodProtocol/blob/master/contracts/invite/InvitesV2.sol) -- Identity contract: [`IdentityV4.sol`](https://github.com/GoodDollar/GoodProtocol/blob/master/contracts/identity/IdentityV4.sol) -- Deployment addresses: [deployment.json](https://github.com/GoodDollar/GoodProtocol/blob/master/releases/deployment.json) diff --git a/.agents/skills/gooddollar/references/deep-researches/mento-reserve-economics.md b/.agents/skills/gooddollar/references/deep-researches/mento-reserve-economics.md deleted file mode 100644 index e46db2a..0000000 --- a/.agents/skills/gooddollar/references/deep-researches/mento-reserve-economics.md +++ /dev/null @@ -1,27 +0,0 @@ -# Mento and reserve economics - -This note ties **macro G$ economics** (GoodDocs) to **Mento trading surfaces** (broker, reserve, expansion) that agents integrate on-chain. - -## Protocol-level story (GoodDocs) - -- G$ is **reserve-backed**; issuance and price discovery follow an **augmented bonding curve** (Bancor-style dynamics) described in [How GoodDollar works](https://docs.gooddollar.org/how-gooddollar-works). -- **Buying** from the reserve side increases reserve assets and can support **new G$ supply** within reserve rules; **selling back** burns G$ and returns collateral, with parameters governed by **GoodDAO**. -- Distribution of newly created G$ spans UBI, savings incentives, treasury, and ecosystem allocations (same doc), but execution timing depends on the mint path and distribution trigger used by the deployment flow. - -## User-facing buy and sell (historical vs current) - -- [Buy and Sell G$](https://docs.gooddollar.org/user-guides) describes reserve interaction, fees (including exit contribution on some paths), and older explorer flows (GoodMarketMaker / exchangeHelper on Ethereum testnets). Treat that page as **product narrative**; **live contract addresses** must come only from [deployment.json](https://github.com/GoodDollar/GoodProtocol/blob/master/releases/deployment.json). - -## Mento stack (agent integration) - -On networks where GoodDollar uses Mento (see `MentoBroker` and related keys in [deployment.json](https://github.com/GoodDollar/GoodProtocol/blob/master/releases/deployment.json) for your environment): - -- **`IBroker`** (implementation in [mento-core `Broker.sol`](https://github.com/mento-org/mento-core)) is the usual **swap entrypoint**: `getAmountIn` / `getAmountOut`, `swapIn` (exact in), `swapOut` (exact out), plus **trading limits** state per exchange id and token. -- **Reserve** holds collateral; **exchange provider** contracts price trades against the reserve; **GoodDollarExpansionController** and related interfaces in GoodProtocol’s [`MentoInterfaces.sol`](https://github.com/GoodDollar/GoodProtocol/blob/master/contracts/MentoInterfaces.sol) describe expansion and avatar wiring for governance-facing changes. -- Agents should not hardcode **exchangeId** or provider addresses: read them from [deployment.json](https://github.com/GoodDollar/GoodProtocol/blob/master/releases/deployment.json) or discover via `getExchangeProviders()` after confirming the broker address for the chain from that file. - -## Agent guidance - -1. Explain **macro** supply and reserve behavior with GoodDocs language. -2. Execute **swaps** with broker quotes, slippage bounds, and allowances per `references/guides/swap.md`. -3. On revert, distinguish **slippage / limit** failures (broker) from **reserve liquidity** messages (see `MentoBroker.abi.yaml` error map and mento-core source). diff --git a/.agents/skills/gooddollar/references/deep-researches/on-off-ramp-service.md b/.agents/skills/gooddollar/references/deep-researches/on-off-ramp-service.md deleted file mode 100644 index b59e5c9..0000000 --- a/.agents/skills/gooddollar/references/deep-researches/on-off-ramp-service.md +++ /dev/null @@ -1,69 +0,0 @@ -# On- and off-ramp service via stable token swap - -Use this note for the service pattern where ramp providers do not list G$ directly. The practical path is: ramp in/out with a listed stable token (for example cUSD), then swap between stable and G$ on-chain. - -## Why this is required - -- Most on-/off-ramp providers list mainstream stable tokens, not G$. -- Service needs a bridge asset for fiat rails. -- Stable token becomes the integration point with ramp providers, while G$ remains the in-app asset. - -## On-chain source of truth - -- Solidity: [`contracts/utils/BuyGDClone.sol`](https://github.com/GoodDollar/GoodProtocol/blob/master/contracts/utils/BuyGDClone.sol) -- Components: - - `BuyGDCloneFactory` - - `BuyGDCloneV2` - - `DonateGDClone` -- Deployments: [releases/deployment.json](https://github.com/GoodDollar/GoodProtocol/blob/master/releases/deployment.json) - -## Service architecture - -The factory deploys EIP-1167 minimal clones and wires swap infrastructure (router, oracle, quoter, optional Mento broker configuration, G$ token, stable token). - -Swap execution is **dual-path**: - -- **Uniswap-style route** (router/quoter path) -- **Mento-based route** (broker/exchange-provider path) - -For each swap request, the service compares quoted outputs and selects the route with the **larger `amountOut`** (best execution for the same input amount), then enforces `minAmount` guard on the selected path. - -Each user gets a deterministic clone address from owner-based salt: - -- `predict(owner)` for buy clone -- `predictDonation(owner, donor)` for donation clone - -This is why clone-per-user design is used: - -- predictable per-user addresses for audit and routing -- isolated execution context -- cheaper deployment than full contract instances - -## Execution surface (conceptual) - -The operational surface is intentionally small and deterministic: - -- `create(owner)` -- `createAndSwap(owner, minAmount)` -- `predict(owner)` -- `createDonation`, `createDonationAndSwap`, `predictDonation` - -This keeps on-/off-ramp architecture auditable and predictable across users. - -## Risks - -- Wrong factory or wrong chain causes permanent fund loss risk. -- Stale router/oracle/mento config can fail swap or produce bad execution. -- Missing `minAmount` protection increases slippage risk. -- Quote source mismatch or stale quotes across Uniswap/Mento can pick a suboptimal route if not refreshed just before execution. - -## Boundary note - -This file explains **why** this architecture exists for ramp services and why per-user clones matter. -For step-by-step service execution flow, use `references/guides/on-off-ramp.md`. - -## Cross-reference - -- User narrative: [Buy and Sell G$](https://docs.gooddollar.org/user-guides) -- Token integration details: [How to integrate the G$ token](https://docs.gooddollar.org/for-developers/developer-guides/how-to-integrate-the-gusd-token) -- Broker ABI: `references/contracts/MentoBroker.abi.yaml` diff --git a/.agents/skills/gooddollar/references/guides/bridge.md b/.agents/skills/gooddollar/references/guides/bridge.md deleted file mode 100644 index 71fd6e8..0000000 --- a/.agents/skills/gooddollar/references/guides/bridge.md +++ /dev/null @@ -1,187 +0,0 @@ -# Bridge guide - -Use for moving G$ across supported networks with deployment-specific bridge contracts. - -Primary local ABI reference for MessagePassingBridge flow: - -- `references/contracts/MessagePassingBridge.abi.yaml` - -## GoodDocs alignment - -- User flow and high-level behavior: [Bridge GoodDollars](https://docs.gooddollar.org/user-guides/bridge-gooddollars). -- Resolve supported bridge contract addresses per chain from [deployment.json](https://github.com/GoodDollar/GoodProtocol/blob/master/releases/deployment.json) only (for example `MpbBridge` under `production`, `production-celo`, `production-xdc`). Use [Bridge GoodDollars](https://docs.gooddollar.org/user-guides/bridge-gooddollars) for user-facing flow and troubleshooting, not for addresses. - -## Goal - -Bridge with deterministic pre-checks: bridge support, allowance, amount, cross-chain transport fee, and delivered G$ after destination **amount** limits and protocol fee. - -## Required inputs - -- source and destination chain metadata -- bridge contract address for source chain -- source G$ token address -- amount in source token decimals -- signer and rpc url - -## Execution flow - -1. Resolve source bridge and token addresses for the network pair. -2. Run bridge eligibility checks for sender and amount via `canBridge(from, amount)` on the **source** bridge (same contract you call for `bridgeToWithLz` / `bridgeToWithAxelar`). Outbound burn does not invoke `canBridge` inside `_bridgeTo`; destination mint still enforces **amount** limits (see **Bridge amount limit context**). -3. Read allowance and approve bridge spender when required. -4. Resolve transport mode (`LZ` or `AXELAR`) and estimate required native fee. -5. Send bridge transaction with nonzero `msg.value` and explicit transport method. -6. Return tx hash and normalized bridge parameters. - -## Bridge fee context - -Two different costs show up on `MessagePassingBridge`; do not conflate them. - -**1. Cross-chain transport fee (native gas token on the source chain)** -Paid as **`msg.value`** on the outbound call. The contract reverts with **`MISSING_FEE`** if `msg.value` is zero. On the **LayerZero** path the contract compares your `msg.value` to **`estimateSendFee`** and reverts **`LZ_FEE(required, sent)`** if it is too low. Use the same **normalized** amount for `estimateSendFee` as the contract uses internally (see the next section). On the **Axelar** path you still attach native value for Gas Service / execution; there is no single `estimateSendFee` analogue in the snippet—follow Envio/Axelar docs or simulate the exact call for production amounts. - -**2. Protocol fee on minted G$ (destination chain, basis points)** -When the message is executed on the **destination** chain, the bridge applies **`bridgeFees`** (min / max / fee bps via `setBridgeFees`) and mints the recipient **minus** that fee; the fee portion is minted to **`feeRecipient`** when it is non-zero (see `bridgeFees()`, `feeRecipient`, and `_takeFee` / `ExecutedTransfer` in `references/contracts/MessagePassingBridge.abi.yaml`). This is **not** the LayerZero relayer fee; it is a separate cut on the **token amount** delivered on arrival. - -**3. Optional OFT / LayerZero token-adapter path** -If the flow uses the GoodDollar OFT-style adapter instead of `MessagePassingBridge`, fee quoting follows **`quoteSend`** / **`MessagingFee`** on that contract; see `references/contracts/GoodDollarOFTAdapter.abi.yaml`. - -## Bridge amount limit context - -**Bridge limit** means **bridge amount limit**: policy on **how much G$** (token volume) may move—**`minAmount`**, per-transfer cap, per-account daily cap, and aggregate daily cap—plus **`onlyWhitelisted`**. It does **not** mean the cross-chain **native** transport fee (`msg.value`, **`LZ_FEE`**), and it does **not** mean the **destination mint fee** in **`bridgeFees`** (bps); those are covered under **Bridge fee context**. - -Amount caps and counters are **per bridge deployment**: read the **source** contract for outbound **amount** policy and usage meters tied to the burn, and the **destination** contract for **`_enforceLimits`** at inbound mint completion; do not assume identical **`bridgeLimits`** across chains. - -**1. Amount caps and usage meters** -**`bridgeLimits()`** exposes **`dailyLimit`**, **`txLimit`**, **`accountDailyLimit`**, **`minAmount`**, and **`onlyWhitelisted`**. Compare those caps to **`bridgeDailyLimit()`** (aggregate **`bridged24Hours`** and **`lastTransferReset`**) and **`accountsDailyLimit(account)`** (same fields per sender). Updates use **`setBridgeLimits`** (access per the ABI). Field-level notes and accessors live in `references/contracts/MessagePassingBridge.abi.yaml`. - -**2. Source preflight vs destination enforcement** -**`canBridge(from, amount)`** on the **source** is a view-only diagnostic for **that amount**: same policy family as amount limit checks, evaluated on the **raw** burn size (not the LayerZero fee normalization). Outbound **`_bridgeTo`** does **not** call **`canBridge`**; call it from the client if you want **`(false, reason)`** before signing instead of learning only from a revert after burn setup. When the message is executed on the **destination**, **`_enforceLimits`** is the hard gate for **amount** throttles and whitelist behavior at mint time. - -## Outbound pause, approved requests, and inbound source bridges - -These controls are separate from numeric **amount** caps; they still block or relax bridging and can surface as **`BRIDGE_LIMITS`** or inbound skips. - -**`pauseBridge`** sets **`isClosed`**; when closed, outbound flow reverts with **`BRIDGE_LIMITS('closed')`**. **`approvedRequests(requestId)`** on the destination lets **`_bridgeFrom`** skip standard **amount** limit enforcement for that completion when set. **`setDisabledBridges`** toggles **`disabledSourceBridges`** entries keyed by **`keccak256(abi.encode(sourceChainId, BridgeService))`**, controlling whether an inbound relay from that source is accepted before the rest of destination handling. See `references/contracts/MessagePassingBridge.abi.yaml`. - -## Axelar vs LayerZero on GoodDollar deployments - -LayerZero mappings are initialized for Ethereum, Celo, Fuse, and XDC in `initialize` / `upgrade` on `MessagePassingBridge`. The **Axelar** path is only usable where `toAxelarChainId(targetChainId)` returns a non-empty string; the on-chain pure function currently maps **1**, **5**, **42220**, and **44787** only. For **Fuse (122)** or **XDC (50)** targets, use **LZ** (`bridgeToWithLz`) unless governance ships a broader Axelar mapping. - -## LayerZero fee and `estimateSendFee` - -`bridgeToWithLz` burns the G$ **raw** amount in the source token’s `decimals()`. Inside the contract, LayerZero payload and `estimateSendFee` use a value normalized to **18 decimals** the same way as [GoodBridge `BridgeHelperLibrary.normalizeFromTokenTo18Decimals`](https://github.com/GoodDollar/GoodBridge/blob/master/packages/bridge-contracts/contracts/messagePassingBridge/BridgeHelperLibrary.sol): if `decimals < 18`, multiply by `10^(18 - decimals)`; if `decimals > 18`, divide by `10^(decimals - 18)`; otherwise use the raw amount. - -`canBridge(from, amount)` is evaluated on the **raw** burn amount, not the normalized value. - -Read `decimals()` from the source G$ contract when building off-chain fee quotes so you stay aligned if a deployment differs. - -## Deterministic snippet - -```js -import { ethers } from "ethers"; - -function normalizedForLzFee(raw, tokenDecimals) { - if (tokenDecimals < 18) return raw * 10n ** BigInt(18 - tokenDecimals); - if (tokenDecimals > 18) return raw / 10n ** BigInt(tokenDecimals - 18); - return raw; -} - -const provider = new ethers.JsonRpcProvider(process.env.RPC_URL); -const signer = new ethers.Wallet(process.env.PRIVATE_KEY, provider); - -const token = new ethers.Contract( - process.env.GOODDOLLAR_ADDRESS, - [ - "function decimals() view returns (uint8)", - "function allowance(address,address) view returns (uint256)", - "function approve(address,uint256) returns (bool)", - ], - signer, -); - -const bridge = new ethers.Contract( - process.env.BRIDGE_ADDRESS, - [ - "function canBridge(address,uint256) view returns (bool,string)", - "function toLzChainId(uint256) view returns (uint16)", - "function estimateSendFee(uint16,address,address,uint256,bool,bytes) view returns (uint256,uint256)", - "function bridgeToWithLz(address,uint256,uint256,bytes) payable", - "function bridgeToWithAxelar(address,uint256,uint256,address) payable", - ], - signer, -); - -const owner = await signer.getAddress(); -const targetChainId = Number(process.env.TARGET_CHAIN_ID); -const recipient = process.env.RECIPIENT; -const amount = ethers.parseUnits(process.env.AMOUNT, Number(process.env.DECIMALS)); -const transport = (process.env.BRIDGE_TRANSPORT || "LZ").toUpperCase(); -const tokenDecimals = await token.decimals(); -const normalizedForLzEstimate = normalizedForLzFee(amount, Number(tokenDecimals)); - -const [canBridge, reason] = await bridge.canBridge(owner, amount); -if (!canBridge) throw new Error(`Bridge blocked: ${reason}`); - -const allowance = await token.allowance(owner, process.env.BRIDGE_ADDRESS); -if (allowance < amount) { - const approveTx = await token.approve(process.env.BRIDGE_ADDRESS, amount); - await approveTx.wait(); -} - -let tx; - -if (transport === "LZ") { - const dstEid = await bridge.toLzChainId(targetChainId); - if (dstEid === 0) throw new Error("Unsupported target chain for LayerZero"); - - const adapterParams = process.env.LZ_ADAPTER_PARAMS || "0x"; - const [nativeFee] = await bridge.estimateSendFee( - dstEid, - owner, - recipient, - normalizedForLzEstimate, - false, - adapterParams, - ); - if (nativeFee <= 0n) throw new Error("Estimated LayerZero fee is zero"); - - tx = await bridge.bridgeToWithLz(recipient, targetChainId, amount, adapterParams, { - value: nativeFee, - }); -} else if (transport === "AXELAR") { - const nativeFee = ethers.parseEther(process.env.AXELAR_FEE_ETH || "0.01"); - tx = await bridge.bridgeToWithAxelar(recipient, targetChainId, amount, owner, { - value: nativeFee, - }); -} else { - throw new Error("Unsupported BRIDGE_TRANSPORT. Use LZ or AXELAR"); -} - -const receipt = await tx.wait(); -console.log( - JSON.stringify( - { - txHash: receipt.hash, - sourceBridge: process.env.BRIDGE_ADDRESS, - targetChainId, - transport, - recipient, - rawAmount: amount.toString(), - tokenDecimals: Number(tokenDecimals), - normalizedAmountForLz: normalizedForLzEstimate.toString(), - }, - null, - 2, - ), -); -``` - -## Failure handling - -- unsupported destination: return targetChainId, bridge address, and transport mode -- fee too low (`LZ_FEE` or underpriced Axelar fee): re-estimate and retry with user confirmation -- approval or balance issue: return required delta -- credited G$ on destination is reduced by **`bridgeFees`** (bps / min / max); that is independent of the source **`msg.value`** transport fee -- **`canBridge`** false on source: return the **`reason`** string from the view call -- **`BRIDGE_LIMITS(reason)`** custom error (see `references/contracts/MessagePassingBridge.abi.yaml` **errors**): **`reason`** labels the failing check (numeric **amount** limit, whitelist, **`closed`**, or other policy string from the implementation) -- source preflight passed but destination still reverts: re-read **`bridgeLimits`** and daily counters for **amount** caps and **`onlyWhitelisted`**; check **`isClosed`**, **`approvedRequests`**, and **`disabledSourceBridges`** per **Outbound pause, approved requests, and inbound source bridges**; message delivery can cross a reset boundary or policy change diff --git a/.agents/skills/gooddollar/references/guides/check-identity.md b/.agents/skills/gooddollar/references/guides/check-identity.md deleted file mode 100644 index adc0165..0000000 --- a/.agents/skills/gooddollar/references/guides/check-identity.md +++ /dev/null @@ -1,87 +0,0 @@ -# Check identity guide - -Use when the user asks whether an address is eligible for UBI or how identity links wallets. - -## GoodDocs alignment - -- [Connect another wallet address to identity](https://docs.gooddollar.org/user-guides/connect-another-wallet-address-to-identity): associated addresses resolve to a verified root in the Identity contract; `connectAccount` links wallets. -- One claim per day applies across all connected addresses for the same verified identity (see the hint on that page). - -## Goal - -Determine whitelist or authentication status with deterministic on-chain reads. - -## Metric semantics - -- **Passed whitelisting (historical):** use `lastAuthenticated(account) > 0`. -- **Still whitelisted (current):** use `getWhitelistedRoot(account) != 0x0` or `isWhitelisted(account) == true`. -- `getWhitelistedRoot(account) != 0x0` is a current-state signal, not an "ever passed" signal. - -## Required inputs - -- `nameServiceAddress` or explicit Identity address -- `account` to check -- `rpcUrl` and chain configuration - -## Execution flow - -1. Resolve `IDENTITY` from NameService when used on the deployment. -2. Read `getWhitelistedRoot(account)` or equivalent for the deployed Identity version. -3. Treat non-zero root as tied to a whitelisted identity tree when that is the protocol rule for the deployment. -4. Read `lastAuthenticated(account)` for historical pass status and `getWhitelistedRoot(account)` or `isWhitelisted(account)` for current status. - -## Deterministic snippet - -```js -import { ethers } from "ethers"; - -const provider = new ethers.JsonRpcProvider(process.env.RPC_URL); - -const nameService = new ethers.Contract( - process.env.NAMESERVICE_ADDRESS, - ["function getAddress(string) view returns (address)"], - provider, -); - -const identityAddress = await nameService.getAddress("IDENTITY"); -const identity = new ethers.Contract( - identityAddress, - [ - "function getWhitelistedRoot(address) view returns (address)", - "function isWhitelisted(address) view returns (bool)", - "function lastAuthenticated(address) view returns (uint256)", - ], - provider, -); - -const account = process.env.ACCOUNT; -const root = await identity.getWhitelistedRoot(account); -const isWhitelisted = await identity.isWhitelisted(account); -const lastAuthenticated = await identity.lastAuthenticated(account); - -console.log( - JSON.stringify( - { - account, - identityAddress, - whitelistedRoot: root, - isWhitelisted, - lastAuthenticated: lastAuthenticated.toString(), - }, - null, - 2, - ), -); -``` - -## Return shape - -- `isWhitelisted` or equivalent boolean summary -- `whitelistedRoot` or equivalent -- `lastAuthenticated` for historical-pass classification -- optional metadata fields when available - -## Failure handling - -- NameService cannot resolve `IDENTITY`: stop and fix inputs using [deployment.json](https://github.com/GoodDollar/GoodProtocol/blob/master/releases/deployment.json) (`Identity` / `NameService` for the target environment)—not GoodDocs tables. -- Read failures: return the failing call and next step. diff --git a/.agents/skills/gooddollar/references/guides/claim.md b/.agents/skills/gooddollar/references/guides/claim.md deleted file mode 100644 index bd51abd..0000000 --- a/.agents/skills/gooddollar/references/guides/claim.md +++ /dev/null @@ -1,83 +0,0 @@ -# Claim guide - -Use when the user wants to claim daily UBI. Protocol context: [How GoodDollar works](https://docs.gooddollar.org/how-gooddollar-works) and [UBIScheme (GoodDocs behavior)](https://docs.gooddollar.org/for-developers/core-contracts/ubischeme)—contract addresses only from [deployment.json](https://github.com/GoodDollar/GoodProtocol/blob/master/releases/deployment.json). - -## Goal - -Execute a safe `claim()` with identity pre-checks and clear outputs. - -## GoodDocs alignment - -- UBI is distributed daily to verified users; the active pool is split among claimers in each period (see [How GoodDollar works](https://docs.gooddollar.org/how-gooddollar-works)). -- UBIScheme deployments vary by chain (Fuse, Celo, XDC); resolve live contract addresses only from [deployment.json](https://github.com/GoodDollar/GoodProtocol/blob/master/releases/deployment.json) (`UBIScheme` under `production`, `production-celo`, or `production-xdc`). Use [Core contracts / UBIScheme](https://docs.gooddollar.org/for-developers/core-contracts/ubischeme) for documented behavior, not for addresses. - -## Required inputs - -- `nameServiceAddress` or explicit UBIScheme and Identity addresses from [deployment.json](https://github.com/GoodDollar/GoodProtocol/blob/master/releases/deployment.json) -- `rpcUrl` and chain configuration -- signer context - -## Execution flow - -1. Resolve `IDENTITY` and `UBISCHEME` from NameService when NameService is the source of truth for the deployment. -2. Confirm whitelist status for the claiming account. -3. Optionally read entitlement or claimable state before sending `claim()`. -4. Call `claim()` on the resolved UBIScheme (contract generation may differ by deployment; align ABI with your target). -5. Return tx hash and claimed amount when derivable from events or balance delta. - -## Deterministic snippet - -```js -import { ethers } from "ethers"; - -const provider = new ethers.JsonRpcProvider(process.env.RPC_URL); -const signer = new ethers.Wallet(process.env.PRIVATE_KEY, provider); - -const nameService = new ethers.Contract( - process.env.NAMESERVICE_ADDRESS, - ["function getAddress(string) view returns (address)"], - provider, -); - -const identityAddress = await nameService.getAddress("IDENTITY"); -const ubiAddress = await nameService.getAddress("UBISCHEME"); - -const identity = new ethers.Contract( - identityAddress, - [ - "function isWhitelisted(address) view returns (bool)", - "function getWhitelistedRoot(address) view returns (address)", - ], - provider, -); - -const account = await signer.getAddress(); -const isWhitelisted = await identity.isWhitelisted(account); -if (!isWhitelisted) throw new Error("Account is not whitelisted"); - -const root = await identity.getWhitelistedRoot(account); -if (root === ethers.ZeroAddress) throw new Error("No whitelisted root"); - -const ubi = new ethers.Contract( - ubiAddress, - ["function claim()", "event UBICalculated(address,uint256,uint256,uint256)"], - signer, -); - -const tx = await ubi.claim(); -const receipt = await tx.wait(); -console.log(JSON.stringify({ txHash: receipt.hash, account, root }, null, 2)); -``` - -## Pre-check failures - -- Not whitelisted: stop and point the user to identity verification flows in GoodDocs. -- Missing contract address: stop; use [deployment.json](https://github.com/GoodDollar/GoodProtocol/blob/master/releases/deployment.json) only. -- Zero entitlement: communicate that nothing is claimable in the current period without guessing amounts. - -## Output contract - -- network -- resolved contract addresses -- tx hash -- claim outcome details when available diff --git a/.agents/skills/gooddollar/references/guides/faucet.md b/.agents/skills/gooddollar/references/guides/faucet.md deleted file mode 100644 index d224e85..0000000 --- a/.agents/skills/gooddollar/references/guides/faucet.md +++ /dev/null @@ -1,76 +0,0 @@ -# Faucet top-up guide - -Use when the user needs native gas top-up via GoodProtocol Faucet. - -## Goal - -Run deterministic pre-checks and call `topWallet` only when eligibility and limits pass. - -## Required inputs - -- `rpcUrl`, chain configuration, signer -- Faucet address for the chain (from [deployment.json](https://github.com/GoodDollar/GoodProtocol/blob/master/releases/deployment.json) `Faucet` under the matching environment, or `NameService.getAddress` when the deployment documents the key) -- target user address - -## Execution flow - -1. Resolve Faucet contract address for the active chain from [deployment.json](https://github.com/GoodDollar/GoodProtocol/blob/master/releases/deployment.json). -2. Run `canTop(user)` as preflight. -3. Read `getToppingAmount(user)` and communicate expected top-up. -4. If eligible, call `topWallet(user)`. -5. Return tx hash and resulting top-up context. - -## Deterministic snippet - -```js -import { ethers } from "ethers"; - -const provider = new ethers.JsonRpcProvider(process.env.RPC_URL); -const signer = new ethers.Wallet(process.env.PRIVATE_KEY, provider); - -const faucet = new ethers.Contract( - process.env.FAUCET_ADDRESS, - [ - "function canTop(address) view returns (bool)", - "function getToppingAmount(address) view returns (uint256)", - "function topWallet(address payable)", - ], - signer, -); - -const user = process.env.USER; -const canTop = await faucet.canTop(user); -if (!canTop) throw new Error("Faucet canTop returned false"); - -const amount = await faucet.getToppingAmount(user); -const tx = await faucet.topWallet(user); -const receipt = await tx.wait(); - -console.log( - JSON.stringify( - { - txHash: receipt.hash, - user, - toppingAmount: amount.toString(), - }, - null, - 2, - ), -); -``` - -## Common rejection reasons - -- `not authorized` -- daily or weekly cap reached -- banned address -- low effective `toTop` vs minimum threshold -- faucet inactive or wrong chain/address - -## Output contract - -- network -- faucet address -- `canTop` preflight result -- top-up amount estimate -- tx hash (when executed) diff --git a/.agents/skills/gooddollar/references/guides/gooddocs.md b/.agents/skills/gooddollar/references/guides/gooddocs.md deleted file mode 100644 index 5e5b4b3..0000000 --- a/.agents/skills/gooddollar/references/guides/gooddocs.md +++ /dev/null @@ -1,37 +0,0 @@ -# GoodDocs hub - -Canonical protocol documentation lives at [GoodDocs](https://docs.gooddollar.org/). - -This is a **routing guide** (quick link map), not a deep protocol analysis note. - -## Start here - -- [Welcome](https://docs.gooddollar.org/) -- [How GoodDollar works](https://docs.gooddollar.org/how-gooddollar-works) - -## User guides - -- [Buy and Sell G$](https://docs.gooddollar.org/user-guides) (reserve-backed buy/sell; includes historical Ethereum/Kovan explorer workflows in the doc) -- [Bridge GoodDollars](https://docs.gooddollar.org/user-guides/bridge-gooddollars) (MessagePassingBridge, fees, limits, troubleshooting) -- [Connect another wallet address to identity](https://docs.gooddollar.org/user-guides/connect-another-wallet-address-to-identity) - -## Developers - -- [Core contracts](https://docs.gooddollar.org/for-developers/core-contracts) (module overview; **do not** read contract addresses from GoodDocs—use [deployment.json](https://github.com/GoodDollar/GoodProtocol/blob/master/releases/deployment.json) only) -- [Developer guides index](https://docs.gooddollar.org/for-developers/developer-guides) -- [Integrate the G$ token](https://docs.gooddollar.org/for-developers/developer-guides/how-to-integrate-the-gusd-token) (ERC-677, ERC-777, decimals by chain, `transferAndCall`, fees) -- [Use G$ streaming](https://docs.gooddollar.org/for-developers/developer-guides/use-gusd-streaming) (Superfluid on Celo, CFAv1Forwarder) - -## Chain IDs (bridge doc) - -| Network | Chain ID | -| -------- | -------- | -| Ethereum | 1 | -| Fuse | 122 | -| Celo | 42220 | -| XDC | 50 | - -## This repo - -- Action playbooks: `references/guides/*.md`. -- Rich ABIs: `references/contracts/*.abi.yaml`. diff --git a/.agents/skills/gooddollar/references/guides/goodsdks.md b/.agents/skills/gooddollar/references/guides/goodsdks.md deleted file mode 100644 index 8092e40..0000000 --- a/.agents/skills/gooddollar/references/guides/goodsdks.md +++ /dev/null @@ -1,110 +0,0 @@ -# GoodSDKs integration guide - -Use this guide when the task is SDK-first (app integration), not raw contract-first. - -## Scope - -GoodSDKs is the app integration layer for GoodDollar: - -- `@goodsdks/citizen-sdk` for identity and claim flows. -- `@goodsdks/react-hooks` for Wagmi React hooks. -- `@goodsdks/good-reserve` for reserve buy or sell flows. -- `@goodsdks/engagement-sdk` for engagement rewards flows. -- `@goodsdks/ui-components` and `@goodsdks/savings-widget` for web components. - -## Routing map - -- Check whitelist, identity root, FV link -> `@goodsdks/citizen-sdk` (`IdentitySDK`) -- Claim UBI with entitlement checks and fallback chains -> `@goodsdks/citizen-sdk` (`ClaimSDK`) -- React app with Wagmi and minimal glue code -> `@goodsdks/react-hooks` -- Buy or sell via reserve rails (Celo or XDC support rules) -> `@goodsdks/good-reserve` -- Reward app registration, claims, reward history -> `@goodsdks/engagement-sdk` -- Embeddable UI in non-React or mixed stacks -> `@goodsdks/ui-components` or `@goodsdks/savings-widget` - -## Deterministic setup - -Monorepo prerequisites: - -```bash -cd ~/Projects/GoodSDKs -corepack enable -yarn install --immutable -yarn build -``` - -Target one workspace: - -```bash -yarn workspace @goodsdks/citizen-sdk build -yarn workspace @goodsdks/react-hooks build -``` - -## Deterministic usage snippets - -Identity SDK: - -```ts -import { createPublicClient, createWalletClient, custom, http } from "viem"; -import { IdentitySDK } from "@goodsdks/citizen-sdk"; - -const publicClient = createPublicClient({ transport: http("https://forno.celo.org") }); -const walletClient = createWalletClient({ transport: custom(window.ethereum) }); - -const identitySDK = await IdentitySDK.init({ - publicClient, - walletClient, - env: "production", -}); - -const { isWhitelisted, root } = await identitySDK.getWhitelistedRoot("0xYourAccount"); -console.log({ isWhitelisted, root }); -``` - -Claim SDK: - -```ts -import { ClaimSDK, IdentitySDK } from "@goodsdks/citizen-sdk"; - -const identitySDK = await IdentitySDK.init({ publicClient, walletClient, env: "production" }); -const claimSDK = await ClaimSDK.init({ - publicClient, - walletClient, - identitySDK, - env: "production", -}); - -const entitlement = await claimSDK.checkEntitlement(); -if (entitlement.amount > 0n) { - const receipt = await claimSDK.claim(); - console.log(receipt.transactionHash); -} -``` - -React hooks: - -```tsx -import { useIdentitySDK, useClaimSDK, useGoodReserve } from "@goodsdks/react-hooks"; - -const identity = useIdentitySDK("production"); -const claim = useClaimSDK("production"); -const reserve = useGoodReserve("production"); -``` - -Reserve SDK: - -```ts -import { GoodReserveSDK } from "@goodsdks/good-reserve"; - -const sdk = new GoodReserveSDK(publicClient, walletClient, "production"); -const quote = await sdk.getBuyQuote(CUSD_ADDRESS, amountIn); -const tx = await sdk.buy(CUSD_ADDRESS, amountIn, (quote * 95n) / 100n); -console.log(tx.hash); -``` - -## Agent rules - -1. Prefer SDK methods first for app tasks. -2. Use contract-level guides only when SDK does not expose required behavior. -3. Do not invent SDK method names; align with package READMEs and exported types. -4. For chain support errors, report chain and env explicitly (do not silently fallback). -5. For UI tasks, prefer hooks or components over bespoke wallet and viem plumbing. diff --git a/.agents/skills/gooddollar/references/guides/hypersync-hyperrpc.md b/.agents/skills/gooddollar/references/guides/hypersync-hyperrpc.md deleted file mode 100644 index e7b6f28..0000000 --- a/.agents/skills/gooddollar/references/guides/hypersync-hyperrpc.md +++ /dev/null @@ -1,110 +0,0 @@ -# Envio HyperSync and HyperRPC - -Use this guide when the task is high-volume historical blockchain data fetch (events, blocks, txs), especially analytics and indexing workflows. - -## Official docs - -- HyperSync overview: [docs.envio.dev/docs/HyperSync/overview](https://docs.envio.dev/docs/HyperSync/overview) -- HyperRPC overview: [docs.envio.dev/docs/HyperRPC/overview-hyperrpc](https://docs.envio.dev/docs/HyperRPC/overview-hyperrpc) -- HyperRPC supported networks: [docs.envio.dev/docs/HyperRPC/hyperrpc-supported-networks](https://docs.envio.dev/docs/HyperRPC/hyperrpc-supported-networks) - -## What to use - -- **HyperSync**: preferred for new data pipelines and heavy historical scans. -- **HyperRPC**: read-only JSON-RPC drop-in for existing RPC code paths. - -## HyperRPC vs HyperSync (avoid mixing them up) - -- **HyperRPC** is a **hosted JSON-RPC URL** (same methods as `eth_getLogs`, `eth_blockNumber`, and so on). Any HTTP client or existing RPC stack can call it; put the API token in the URL path as Envio documents. -- **HyperSync** is a **separate high-throughput query API** used through **Envio client libraries** (for example `@envio-dev/hypersync-client` in Node). It is **not** “just another RPC endpoint” with the same ergonomics as a one-line `fetch` to `eth_getLogs` at large scale. - -## Decision rule - -1. For GoodDollar protocol history that exists on subgraphs, query the subgraph first and validate fields in `references/subgraphs/*-guide.md`. -2. If subgraph schema or freshness cannot satisfy the request, use **HyperSync** for large scans and pipelines, or **HyperRPC** when you must stay inside standard JSON-RPC. -3. For write operations (sending tx), use normal RPC providers; HyperRPC is read-only. - -## GoodDollar-relevant network coverage - -- Celo and XDC are supported on HyperRPC. -- Fuse is not currently listed; treat this as non-blocking and use existing providers for Fuse. - -## Access and auth - -- HyperRPC/HyperSync usage is account-based. -- HyperRPC requires an API key for reliable production use. -- Requests without API token are rate-limited and should be treated as non-production fallback only. -- Add API key in endpoint URL as documented by Envio. -- HyperRPC token pattern example from docs: `https://.rpc.hypersync.xyz/` - -## Agents: Envio API token when HyperSync is the best option - -After you decide **HyperSync** is the right tool for the user query (for example large historical scans or pipeline-scale log pulls where subgraphs are insufficient), check for a usable Envio credential in the execution environment (`ENVIO_API_TOKEN` for `@envio-dev/hypersync-client`, or the token Envio documents for your chosen URL pattern). - -If **no** Envio API token is available and you cannot complete the HyperSync path without it, **stop and explicitly ask the user** to provide an Envio API token (name the env var you need, typically `ENVIO_API_TOKEN`). Do not silently rely on anonymous or heavily rate-limited access as a substitute when HyperSync was already identified as the best approach. - -## Practical use in this repo - -- Keep subgraphs as first option for indexed protocol entities. -- Use HyperSync/HyperRPC when subgraph coverage is missing, stale, or insufficient for bulk historical pulls. -- When an agent chooses **HyperSync** as the best path and no Envio API token is available, follow **Agents: Envio API token when HyperSync is the best option** in this file and ask the user for `ENVIO_API_TOKEN` before proceeding. -- Keep contract addresses from [GoodProtocol/deployment.json](https://github.com/GoodDollar/GoodProtocol/blob/master/releases/deployment.json) only; use GoodDocs for product context, not for resolving contract addresses. -- For implementation details (client setup, query structure, supported methods), follow the Envio docs links above directly. - -## From block for historical fetches - -For **`eth_getLogs`**, HyperRPC, and HyperSync range queries, the lower bound is **`fromBlock`** (or the client’s equivalent). Prefer the deployment’s **`creationBlock`** from the matching row in `references/contracts/*.abi.yaml` (or **`meta.deploymentCreationBlocks`** where deployments are plain address strings) so scans do not start at genesis when you only need post-deploy history. Field placement for **`creationBlock`** is defined in `references/contracts/_rich-abi-yaml-format.md`. If you cannot determine the creation block, **`fromBlock` 0** is valid. - -## Prebuilt scripts (developers and local agents) - -These scripts avoid rediscovering HyperRPC wiring on every task. They require **Node.js 18 or newer** (global `fetch`). Paths like `scripts/...` are relative to the **GoodSkills repository root** (the directory that contains both `skills/` and `scripts/`), not relative to `skills/gooddollar/` alone. - -### Last N Identity `WhitelistedAdded` logs via HyperRPC - -- Script: `scripts/fetch-whitelist-events-hyperrpc.mjs` -- Default `EVENT_TOPIC0` matches `WhitelistedAdded(address)` on `IdentityV4`; override `EVENT_TOPIC0` for other events. -- Production Celo defaults: `CONTRACT_ADDRESS` defaults to `Identity` from `production-celo` in [GoodProtocol deployment.json](https://github.com/GoodDollar/GoodProtocol/blob/master/releases/deployment.json) (`0xC361A6E67822a0EDc17D899227dd9FC50BD62F42`). If `HYPERRPC_URL` is unset, the script builds `https://celo.rpc.hypersync.xyz/` from `HYPERRPC_API_TOKEN` or `ENVIO_API_TOKEN`. -- Optional env: `HYPERRPC_URL` (overrides token-based default), `CONTRACT_ADDRESS`, `LIMIT` (default `500`), `STEP` (default `2000`), `FROM_BLOCK` (decimal; omit to read **`creationBlock`** for `CONTRACT_ADDRESS` from `ABI_PATH` or the default `skills/gooddollar/references/contracts/IdentityV4.abi.yaml`), `ABI_PATH`, `TO_BLOCK` (default `latest`). **`fromBlock`** behavior is described in **From block for historical fetches** above. - -```bash -cd /path/to/GoodSkills -export HYPERRPC_API_TOKEN='' -node scripts/fetch-whitelist-events-hyperrpc.mjs -``` - -Web-only assistants without a shell cannot run the file; they should return the same env keys and command text so the user runs it locally. - -## HyperSync client minimal path (install required) - -HyperSync uses the official client. Install and query pattern (Celo example URLs from [Envio Celo docs](https://docs.envio.dev/docs/HyperIndex/celo)): - -```bash -npm install @envio-dev/hypersync-client -export ENVIO_API_TOKEN='' -``` - -Save as a `.mjs` file (or use `"type": "module"` in a local `package.json`) and run with `node`: - -```javascript -import { HypersyncClient, presetQueryLogsOfEvent } from "@envio-dev/hypersync-client"; - -const client = new HypersyncClient({ - url: "https://celo.hypersync.xyz", - apiToken: process.env.ENVIO_API_TOKEN, -}); - -const identity = "0x..."; -const whitelistedAddedTopic0 = - "0xee1504a83b6d4a361f4c1dc78ab59bfa30d6a3b6612c403e86bb01ef2984295f"; - -const fromBlock = 17237952; -const toBlock = await client.getHeight(); - -const query = presetQueryLogsOfEvent(identity, whitelistedAddedTopic0, fromBlock, toBlock); -const res = await client.get(query); -console.log(res.data.logs.length); -``` - -The example **`fromBlock`** matches **`creationBlock`** for production Celo Identity in `skills/gooddollar/references/contracts/IdentityV4.abi.yaml`; see **From block for historical fetches** above. - -Full API and streaming patterns: [HyperSync clients](https://docs.envio.dev/docs/HyperSync/hypersync-clients) and the package README for `@envio-dev/hypersync-client`. diff --git a/.agents/skills/gooddollar/references/guides/invite-bounties.md b/.agents/skills/gooddollar/references/guides/invite-bounties.md deleted file mode 100644 index d60aafd..0000000 --- a/.agents/skills/gooddollar/references/guides/invite-bounties.md +++ /dev/null @@ -1,115 +0,0 @@ -# Invite bounties guide - -Use when the task is to verify or execute inviter-invitee bounty payout flow and explain why payout is blocked. - -## Goal - -Check eligibility deterministically, execute payout only when eligible, and return exact failure reason when not eligible. - -## Required inputs - -- target chain -- `InvitesV2` address -- `Identity` address -- optional `UBISchemeV2` address when claims threshold is active -- invitee address -- inviter address -- rpc url and signer - -## Execution flow - -1. Resolve contract addresses from `deployment.json`. -2. Read invitee state from `users(invitee)` and global thresholds (`minimumClaims`, `minimumDays`, `active`). -3. Check current eligibility with `canCollectBountyFor(invitee)`. -4. If not eligible, read identity whitelist for invitee and inviter and return concrete blocker. -5. If eligible, execute `bountyFor(invitee)` or `collectBounties()` and return tx hash plus payout values from events. - -## Deterministic snippet - -```js -import { ethers } from "ethers"; - -const provider = new ethers.JsonRpcProvider(process.env.RPC_URL); -const signer = new ethers.Wallet(process.env.PRIVATE_KEY, provider); - -const invites = new ethers.Contract( - process.env.INVITES_ADDRESS, - [ - "function canCollectBountyFor(address) view returns (bool)", - "function bountyFor(address)", - "function users(address) view returns (bytes32,address,uint40,uint24,bool,uint256)", - "function minimumClaims() view returns (uint256)", - "function minimumDays() view returns (uint256)", - "function active() view returns (bool)", - "event InviterBounty(address indexed inviter,address indexed invitee,uint256 bountyPaid,uint256 inviterLevel,bool earnedLevel)" - ], - signer, -); - -const identity = new ethers.Contract( - process.env.IDENTITY_ADDRESS, - [ - "function isWhitelisted(address) view returns (bool)" - ], - provider, -); - -const invitee = process.env.INVITEE_ADDRESS; -const inviter = process.env.INVITER_ADDRESS; - -const [isActive, eligible, inviteeWhitelisted, inviterWhitelisted, minClaims, minDays] = await Promise.all([ - invites.active(), - invites.canCollectBountyFor(invitee), - identity.isWhitelisted(invitee), - identity.isWhitelisted(inviter), - invites.minimumClaims(), - invites.minimumDays(), -]); - -if (!isActive) throw new Error("Invites contract is inactive"); -if (!eligible) { - throw new Error( - `Not eligible. inviteeWhitelisted=${inviteeWhitelisted} inviterWhitelisted=${inviterWhitelisted} minimumClaims=${minClaims} minimumDays=${minDays}`, - ); -} - -const tx = await invites.bountyFor(invitee); -const receipt = await tx.wait(); -const bountyEvent = receipt.logs - .map((log) => { - try { - return invites.interface.parseLog(log); - } catch { - return null; - } - }) - .find((e) => e && e.name === "InviterBounty"); - -console.log( - JSON.stringify( - { - txHash: receipt.hash, - invitee, - inviter, - bountyPaid: bountyEvent?.args?.bountyPaid?.toString() ?? null, - }, - null, - 2, - ), -); -``` - -## Failure handling - -- invitee or inviter is not currently whitelisted -- reverification is due and whitelist check fails until re-authentication -- minimum claims or minimum days is not met -- bounty already paid or bounty-at-join is zero -- contract inactive or wrong deployment addresses - -## Output contract - -- network and addresses used -- eligibility status and blockers -- tx hash when sent -- payout values when available from logs diff --git a/.agents/skills/gooddollar/references/guides/migrate-fuse-staking-to-celo-savings.md b/.agents/skills/gooddollar/references/guides/migrate-fuse-staking-to-celo-savings.md deleted file mode 100644 index 4ad9fd2..0000000 --- a/.agents/skills/gooddollar/references/guides/migrate-fuse-staking-to-celo-savings.md +++ /dev/null @@ -1,116 +0,0 @@ -# Fuse to CELO staking migration guide - -Use when the user wants to migrate an existing Fuse governance stake into a CELO destination savings flow. In this flow, Fuse `GovernanceStakingV2` is the old staking contract (source) and **`GooddollarSavingsStream`** on Celo is the destination savings contract ([`GooddollarSavingsStream.sol`](https://github.com/Ubeswap/gooddollar-contracts/blob/main/contracts/GooddollarSavingsStream.sol), [CeloScan](https://celoscan.io/address/0x059ee811414230d1Fb157878D2b491240F4D8d3B)). - -## Goal - -Close a user stake on Fuse, bridge the resulting G$ to CELO, and stake on CELO for that user in a controlled backend flow. - -## Required inputs - -- user address on Fuse and corresponding destination address on CELO -- Fuse `GovernanceStakingV2` address (`production.GovernanceStakingV2` in [deployment.json](https://github.com/GoodDollar/GoodProtocol/blob/master/releases/deployment.json)) -- Fuse G$ token address and bridge contract address (from [deployment.json](https://github.com/GoodDollar/GoodProtocol/blob/master/releases/deployment.json): `GoodDollar`, `MpbBridge` under `production`) -- CELO G$ token address (from `production-celo` in the same file) and destination savings contract address -- backend signer or service wallet with required execution permissions -- chain RPC URLs for Fuse and CELO - -## Address resolution quick table - -| Purpose | Network | Source key/path | Value | -|---|---|---|---| -| Governance staking (source close) | Fuse (`production`, `networkId: 122`) | `deployment.json` -> `production.GovernanceStakingV2` | `0xB7C3e738224625289C573c54d402E9Be46205546` | -| Governance staking (previous) | Fuse (`production`, `networkId: 122`) | `deployment.json` -> `production.GovernanceStaking` | `0xFAF457Fb4A978Be059506F6CD41f9B30fCa753b0` | -| Fuse G$ token | Fuse (`production`, `networkId: 122`) | `deployment.json` -> `production.GoodDollar` | `0x495d133B938596C9984d462F007B676bDc57eCEC` | -| Fuse bridge | Fuse (`production`, `networkId: 122`) | `deployment.json` -> `production.MpbBridge` | `0xa3247276DbCC76Dd7705273f766eB3E8a5ecF4a5` | -| Destination savings | CELO (`networkId: 42220`) | [CeloScan](https://celoscan.io/address/0x059ee811414230d1Fb157878D2b491240F4D8d3B) / `GooddollarSavingsStream` | `0x059ee811414230d1Fb157878D2b491240F4D8d3B` (`process.env.CELO_SAVINGS`) | - -Canonical sources: - -- [GoodProtocol deployment.json](https://github.com/GoodDollar/GoodProtocol/blob/master/releases/deployment.json) -- [Fuse explorer contract (GovernanceStakingV2 address)](https://explorer.fuse.io/address/0xB7C3e738224625289C573c54d402E9Be46205546?tab=contract) -- [Ubeswap gooddollar-contracts](https://github.com/Ubeswap/gooddollar-contracts) -- [GoodBridge bridge helper normalization](https://github.com/GoodDollar/GoodBridge/blob/master/packages/bridge-contracts/contracts/messagePassingBridge/BridgeHelperLibrary.sol) - -## Token decimals and `MessagePassingBridge` LZ fees - -Production deployments checked on-chain: Fuse `GoodDollar` uses **2** decimals and Celo `GoodDollar` uses **18**. Fuse `GovernanceStakingV2` (sG$) uses **2** decimals. Resolve `decimals()` from each live token in your runner so you stay correct if deployments change. - -On the Fuse `MpbBridge` (`MessagePassingBridge`), `canBridge(from, amount)` and `bridgeToWithLz(..., amount, ...)` use the **raw G$ burn amount** in source token decimals. Off-chain **`estimateSendFee`’s `_normalizedAmount` argument** must match what the contract builds internally: **`normalizeFromTokenTo18Decimals(amount, IERC20(nativeToken()).decimals())`** ([`BridgeHelperLibrary`](https://github.com/GoodDollar/GoodBridge/blob/master/packages/bridge-contracts/contracts/messagePassingBridge/BridgeHelperLibrary.sol)). Format displayed amounts per chain (`formatUnits`/UI) using each chain’s G$ decimals. - -## Execution flow - -1. Confirm allowance for whichever asset your flow spends first (for example sG$ allowance to the backend on Fuse `GovernanceStakingV2`, or Fuse G$ allowance if you pull G$ directly), before any transfers or bridges. -2. Verify current stake state on Fuse before closing: - - stake token balance - - withdrawable stake amount - - pending rewards if any -3. Execute Fuse unstake or close flow on governance staking (`withdrawStake` or equivalent full-close path). -4. Compute net G$ available for migration after unstake completion and any reward claim behavior. -5. Bridge G$ from Fuse to CELO using the configured bridge path and track the transfer id or tx hash pair. -6. Wait for destination finalization on CELO and verify credited G$ balance at the backend execution wallet. -7. Approve destination savings contract to spend migrated G$ amount. -8. Stake for the user on CELO with `stakeFor(amount, recipient)` on `GooddollarSavingsStream` (G$ native Super Token; approve the savings contract, not only ERC20 GoodDollar from `deployment.json` if your wallet holds the Super Token). -9. Return a migration result with both chain tx hashes and final CELO staked amount. - -## Deterministic snippet - -```js -import { ethers } from "ethers"; - -const fuse = new ethers.JsonRpcProvider(process.env.FUSE_RPC_URL); -const celo = new ethers.JsonRpcProvider(process.env.CELO_RPC_URL); -const signerFuse = new ethers.Wallet(process.env.BACKEND_PK, fuse); -const signerCelo = new ethers.Wallet(process.env.BACKEND_PK, celo); - -const user = process.env.USER_ADDRESS; -const migrateAmount = BigInt(process.env.MIGRATE_AMOUNT); - -const celoGd = new ethers.Contract( - process.env.CELO_GD_TOKEN, - [ - "function approve(address spender,uint256 amount) returns (bool)", - "function balanceOf(address) view returns (uint256)", - ], - signerCelo, -); - -const savings = new ethers.Contract( - process.env.CELO_SAVINGS, - ["function stakeFor(uint256 amount,address recipient)"], - signerCelo, -); - -const approveTx = await celoGd.approve(process.env.CELO_SAVINGS, migrateAmount); -await approveTx.wait(); - -const stakeTx = await savings.stakeFor(migrateAmount, user); -const receipt = await stakeTx.wait(); - -console.log( - JSON.stringify( - { - user, - celoStakeTx: receipt.hash, - migratedAmount: migrateAmount.toString(), - }, - null, - 2, - ), -); -``` - -## Pre-check failures - -- User allowance missing on Fuse: stop and request allowance tx from user. -- Stake close fails on Fuse: stop and return exact revert reason before bridge. -- Bridge transfer not finalized on CELO: do not call `stakeFor` until destination balance is confirmed. -- CELO savings approval missing or too low: re-approve exact amount before staking. - -## Output contract - -- user address -- Fuse unstake tx hash -- bridge tx hash or transfer identifier -- CELO stake tx hash -- final staked amount on CELO diff --git a/.agents/skills/gooddollar/references/guides/on-off-ramp.md b/.agents/skills/gooddollar/references/guides/on-off-ramp.md deleted file mode 100644 index d212705..0000000 --- a/.agents/skills/gooddollar/references/guides/on-off-ramp.md +++ /dev/null @@ -1,77 +0,0 @@ -# On- and off-ramp service guide - -Use when implementing service flow where fiat ramps support a listed stable token (for example cUSD), and the app needs stable <-> G$ swap on-chain. - -## Goal - -Operate deterministic clone-based swap routing with explicit chain/factory verification and slippage guard. - -## Required inputs - -- target chain and factory address -- owner address used for clone derivation -- stable token and G$ token addresses -- direction: on-ramp or off-ramp -- `minAmount` guard -- signer and rpc url - -## Execution flow - -1. Resolve factory for target chain from [deployment.json](https://github.com/GoodDollar/GoodProtocol/blob/master/releases/deployment.json) (`BuyGDFactory` / `BuyGDFactoryV2` under `production-celo`, or the key your deployment uses). -2. Compute expected clone via `predict(owner)`. -3. If clone not yet deployed for flow, call `create(owner)` or `createAndSwap(owner, minAmount)`. -4. Execute stable -> G$ (on-ramp) or G$ -> stable (off-ramp) through clone path. -5. Return chain id, factory, predicted clone, effective clone, tx hashes. - -## Deterministic snippet - -```js -import { ethers } from "ethers"; - -const provider = new ethers.JsonRpcProvider(process.env.RPC_URL); -const signer = new ethers.Wallet(process.env.PRIVATE_KEY, provider); - -const factory = new ethers.Contract( - process.env.BUY_GD_CLONE_FACTORY, - [ - "function predict(address) view returns (address)", - "function create(address) returns (address)", - "function createAndSwap(address,uint256) returns (address)", - ], - signer, -); - -const owner = process.env.OWNER; -const minAmount = ethers.parseUnits(process.env.MIN_AMOUNT, Number(process.env.DECIMALS_OUT)); -const predicted = await factory.predict(owner); - -const tx = await factory.createAndSwap(owner, minAmount); -const receipt = await tx.wait(); - -console.log( - JSON.stringify( - { - txHash: receipt.hash, - owner, - predictedClone: predicted, - chainId: (await provider.getNetwork()).chainId.toString(), - }, - null, - 2, - ), -); -``` - -## Failure handling - -- predicted clone mismatch with trusted expectation -- wrong chain or wrong factory address -- swap output below `minAmount` -- stale router/oracle or exchange configuration - -## Output contract - -- network and chain id -- factory address -- predicted and actual clone addresses -- tx hashes diff --git a/.agents/skills/gooddollar/references/guides/save.md b/.agents/skills/gooddollar/references/guides/save.md deleted file mode 100644 index d0e716c..0000000 --- a/.agents/skills/gooddollar/references/guides/save.md +++ /dev/null @@ -1,93 +0,0 @@ -# Save and stake guide - -Use when the user wants to stake G$, withdraw rewards, or exit stake. Staking economics sit alongside other protocol allocations described in [How GoodDollar works](https://docs.gooddollar.org/how-gooddollar-works). - -## GoodDocs alignment - -- Token integration and fee awareness: [How to integrate the G$ token](https://docs.gooddollar.org/for-developers/developer-guides/how-to-integrate-the-gusd-token) (`_processFees`, decimals per chain). -- Contract addresses: [deployment.json](https://github.com/GoodDollar/GoodProtocol/blob/master/releases/deployment.json) only (for example staking and G$ token keys under `production` / `production-celo`). GoodDocs covers behavior and decimals patterns, not canonical deployment addresses. - -## Goal - -Run staking actions with balance and allowance safety checks. - -## Required inputs - -- `nameServiceAddress` or explicit staking and token addresses -- `amount` or `shares` depending on the action -- `rpcUrl`, chain configuration, signer - -## Execution flow - -1. Resolve staking and G$ token addresses from [deployment.json](https://github.com/GoodDollar/GoodProtocol/blob/master/releases/deployment.json) or, when the deployment documents the key, from `NameService.getAddress` on chain. -2. Read token balance and allowance. -3. Approve the staking contract when `stake` uses `transferFrom`. -4. Execute `stake`, `withdrawRewards`, or `withdrawStake` as requested. -5. Return tx hash and key resulting balances or events. - -## Deterministic snippets - -```js -import { ethers } from "ethers"; - -const provider = new ethers.JsonRpcProvider(process.env.RPC_URL); -const signer = new ethers.Wallet(process.env.PRIVATE_KEY, provider); - -const token = new ethers.Contract( - process.env.GOODDOLLAR_ADDRESS, - [ - "function balanceOf(address) view returns (uint256)", - "function allowance(address,address) view returns (uint256)", - "function approve(address,uint256) returns (bool)", - ], - signer, -); - -const staking = new ethers.Contract( - process.env.STAKING_ADDRESS, - [ - "function stake(uint256)", - "function withdrawRewards()", - "function withdrawStake(uint256)", - ], - signer, -); -``` - -Stake: - -```js -const amount = ethers.parseUnits(process.env.AMOUNT, Number(process.env.DECIMALS)); -const owner = await signer.getAddress(); -const allowance = await token.allowance(owner, process.env.STAKING_ADDRESS); -if (allowance < amount) { - const approveTx = await token.approve(process.env.STAKING_ADDRESS, amount); - await approveTx.wait(); -} -const tx = await staking.stake(amount); -const receipt = await tx.wait(); -console.log(JSON.stringify({ txHash: receipt.hash, action: "stake" }, null, 2)); -``` - -Withdraw rewards: - -```js -const tx = await staking.withdrawRewards(); -const receipt = await tx.wait(); -console.log(JSON.stringify({ txHash: receipt.hash, action: "withdrawRewards" }, null, 2)); -``` - -Withdraw stake: - -```js -const shares = ethers.parseUnits(process.env.SHARES, Number(process.env.DECIMALS)); -const tx = await staking.withdrawStake(shares); -const receipt = await tx.wait(); -console.log(JSON.stringify({ txHash: receipt.hash, action: "withdrawStake" }, null, 2)); -``` - -## Failure handling - -- Insufficient balance: report shortfall. -- Approval issues: report token, spender, and required allowance. -- Reverts: return attempted function and parameters without guessing custom errors. diff --git a/.agents/skills/gooddollar/references/guides/stream.md b/.agents/skills/gooddollar/references/guides/stream.md deleted file mode 100644 index 6cbf7a4..0000000 --- a/.agents/skills/gooddollar/references/guides/stream.md +++ /dev/null @@ -1,135 +0,0 @@ -# Stream guide - -Primary references for stream execution are local ABI assets in this repo: - -- `references/contracts/CFAv1Forwarder.abi.yaml` -- `references/contracts/ConstantFlowAgreementV1.abi.yaml` -- `references/contracts/Superfluid.abi.yaml` -- `references/contracts/SuperToken.abi.yaml` - -## Goal - -Create, update, or delete Superfluid constant flows using deterministic contract calls and local ABI references. - -## Protocol facts used by this guide - -- Forwarder path uses `CFAv1Forwarder.createFlow`, `updateFlow`, `deleteFlow`. -- Host path uses `Superfluid.callAgreement` with CFA calldata for `createFlow`, `updateFlow`, `deleteFlow`. -- Stream token is a SuperToken; flow rates are `int96` in token-wei per second. -- `getBufferAmountByFlowrate(token, flowRate)` is the canonical pre-check for required buffer. - -## Two implementation styles in this repo - -1. **Forwarder (matches GoodDocs):** call CFAv1Forwarder with token, sender, receiver, flowRate, userData. -2. **Host callAgreement:** encode CFA `createFlow` / `updateFlow` / `deleteFlow` and call `Superfluid.callAgreement`. - -## Minimal method map - -- Forwarder: - - `createFlow(address token, address receiver, int96 flowrate, bytes userData)` - - `updateFlow(address token, address receiver, int96 flowrate, bytes userData)` - - `deleteFlow(address token, address sender, address receiver, bytes userData)` - - `getBufferAmountByFlowrate(address token, int96 flowrate)` -- Host: - - `callAgreement(address agreementClass, bytes callData, bytes userData)` -- CFA: - - `createFlow(address token, address receiver, int96 flowRate, bytes ctx)` - - `updateFlow(address token, address receiver, int96 flowRate, bytes ctx)` - - `deleteFlow(address token, address sender, address receiver, bytes ctx)` - -## Required inputs - -- G$ Super Token address for the environment -- CFA forwarder address, or Superfluid host address plus CFA agreement address -- `action`: create, update, delete -- `receiver`, `flowRate` where applicable -- `rpcUrl`, chain configuration, signer - -## Deterministic snippet - -```js -import { ethers } from "ethers"; - -const provider = new ethers.JsonRpcProvider(process.env.RPC_URL); -const signer = new ethers.Wallet(process.env.PRIVATE_KEY, provider); - -const forwarder = new ethers.Contract( - process.env.CFA_FORWARDER, - [ - "function createFlow(address,address,int96,bytes)", - "function updateFlow(address,address,int96,bytes)", - "function deleteFlow(address,address,address,bytes)", - ], - signer, -); - -const token = process.env.SUPER_TOKEN; -const sender = await signer.getAddress(); -const receiver = process.env.RECEIVER; -const flowRate = BigInt(process.env.FLOW_RATE); - -if (process.env.ACTION === "create") { - const tx = await forwarder.createFlow(token, receiver, flowRate, "0x"); - const receipt = await tx.wait(); - console.log(JSON.stringify({ txHash: receipt.hash, action: "create" }, null, 2)); -} - -if (process.env.ACTION === "update") { - const tx = await forwarder.updateFlow(token, receiver, flowRate, "0x"); - const receipt = await tx.wait(); - console.log(JSON.stringify({ txHash: receipt.hash, action: "update" }, null, 2)); -} - -if (process.env.ACTION === "delete") { - const tx = await forwarder.deleteFlow(token, sender, receiver, "0x"); - const receipt = await tx.wait(); - console.log(JSON.stringify({ txHash: receipt.hash, action: "delete" }, null, 2)); -} -``` - -Host callAgreement example: - -```js -import { ethers } from "ethers"; - -const provider = new ethers.JsonRpcProvider(process.env.RPC_URL); -const signer = new ethers.Wallet(process.env.PRIVATE_KEY, provider); - -const cfa = new ethers.Interface([ - "function createFlow(address,address,int96,bytes)", - "function updateFlow(address,address,int96,bytes)", - "function deleteFlow(address,address,address,bytes)", -]); - -const host = new ethers.Contract( - process.env.SUPERFLUID_HOST, - ["function callAgreement(address,bytes,bytes) returns (bytes)"], - signer, -); - -const token = process.env.SUPER_TOKEN; -const sender = await signer.getAddress(); -const receiver = process.env.RECEIVER; -const flowRate = BigInt(process.env.FLOW_RATE); - -let callData = "0x"; -if (process.env.ACTION === "create") { - callData = cfa.encodeFunctionData("createFlow", [token, receiver, flowRate, "0x"]); -} -if (process.env.ACTION === "update") { - callData = cfa.encodeFunctionData("updateFlow", [token, receiver, flowRate, "0x"]); -} -if (process.env.ACTION === "delete") { - callData = cfa.encodeFunctionData("deleteFlow", [token, sender, receiver, "0x"]); -} - -const tx = await host.callAgreement(process.env.CFA_ADDRESS, callData, "0x"); -const receipt = await tx.wait(); -console.log(JSON.stringify({ txHash: receipt.hash, action: process.env.ACTION }, null, 2)); -``` - -## Failure handling - -- Wrong network or missing addresses: stop and return missing host or forwarder or token addresses. -- Insufficient buffer: use `getBufferAmountByFlowrate` and reduce flow rate or top up balance. -- Revert on create or update: verify token is a SuperToken and flowRate is positive. diff --git a/.agents/skills/gooddollar/references/guides/swap.md b/.agents/skills/gooddollar/references/guides/swap.md deleted file mode 100644 index 3db8c2d..0000000 --- a/.agents/skills/gooddollar/references/guides/swap.md +++ /dev/null @@ -1,83 +0,0 @@ -# Swap guide - -Use for buying or selling G$ through Mento-connected contracts on networks where they appear in [deployment.json](https://github.com/GoodDollar/GoodProtocol/blob/master/releases/deployment.json) (for example `MentoBroker`, `MentoReserve`, `MentoExchangeProvider`, `MentoExpansionController` keys under `production-celo` or `production-xdc`). GoodDocs describes Mento product behavior, not deployment addresses. - -## GoodDocs alignment - -- Reserve and buy or sell mechanics at the protocol level: [How GoodDollar works](https://docs.gooddollar.org/how-gooddollar-works) and [Buy and Sell G$ user guide](https://docs.gooddollar.org/user-guides) (includes reserve AMM narrative; older explorer step-by-step for Ethereum testnets remains in that page for reference). -- Integration patterns and decimals: [How to integrate the G$ token](https://docs.gooddollar.org/for-developers/developer-guides/how-to-integrate-the-gusd-token). - -## Goal - -Execute bounded swaps using broker quotes and correct allowances. - -## Required inputs - -- `direction` as buy or sell -- broker and exchange identifiers for the deployment -- amounts in correct token decimals for the chain -- `rpcUrl`, chain configuration, signer - -## Execution flow - -1. Confirm Mento Broker (and related) addresses for the chain from [deployment.json](https://github.com/GoodDollar/GoodProtocol/blob/master/releases/deployment.json) only. -2. Fetch quote (`getAmountOut` or `getAmountIn` depending on direction and ABI). -3. Apply slippage bounds. -4. Approve the spent token for the broker when required. -5. Call `swapIn` or `swapOut` per your integration. -6. Return tx hash and effective amounts. - -## Deterministic snippet - -```js -import { ethers } from "ethers"; - -const provider = new ethers.JsonRpcProvider(process.env.RPC_URL); -const signer = new ethers.Wallet(process.env.PRIVATE_KEY, provider); - -const broker = new ethers.Contract( - process.env.BROKER_ADDRESS, - [ - "function getAmountOut(address,address,uint256) view returns (uint256)", - "function swapIn(address,address,uint256,uint256) returns (uint256)", - ], - signer, -); - -const tokenIn = new ethers.Contract( - process.env.TOKEN_IN, - [ - "function allowance(address,address) view returns (uint256)", - "function approve(address,uint256) returns (bool)", - ], - signer, -); - -const amountIn = ethers.parseUnits(process.env.AMOUNT_IN, Number(process.env.DECIMALS_IN)); -const quotedOut = await broker.getAmountOut(process.env.TOKEN_IN, process.env.TOKEN_OUT, amountIn); -const slippageBps = BigInt(process.env.SLIPPAGE_BPS); -const minOut = quotedOut * (10000n - slippageBps) / 10000n; - -const owner = await signer.getAddress(); -const allowance = await tokenIn.allowance(owner, process.env.BROKER_ADDRESS); -if (allowance < amountIn) { - const approveTx = await tokenIn.approve(process.env.BROKER_ADDRESS, amountIn); - await approveTx.wait(); -} - -const tx = await broker.swapIn(process.env.TOKEN_IN, process.env.TOKEN_OUT, amountIn, minOut); -const receipt = await tx.wait(); -console.log( - JSON.stringify( - { txHash: receipt.hash, amountIn: amountIn.toString(), minOut: minOut.toString() }, - null, - 2, - ), -); -``` - -## Failure handling - -- No deployment on chain: direct the user to an environment that defines the needed keys in [deployment.json](https://github.com/GoodDollar/GoodProtocol/blob/master/releases/deployment.json) (for example `production-celo` with `MentoBroker`). -- Stale quote or tight slippage: refresh quote or relax bounds with user consent. -- Allowance or balance shortfall: report exact delta. diff --git a/.agents/skills/gooddollar/references/subgraphs/_query-patterns.md b/.agents/skills/gooddollar/references/subgraphs/_query-patterns.md deleted file mode 100644 index 36af639..0000000 --- a/.agents/skills/gooddollar/references/subgraphs/_query-patterns.md +++ /dev/null @@ -1,35 +0,0 @@ -# Subgraph query discipline (GoodDollar) - -## Subgraph vs RPC - -- **Subgraph:** historical events, lists, aggregates, time ranges, analytics. Data lags chain head. -- **RPC / SDK:** current balances, live `claim` eligibility, exact view calls. Prefer for user-facing “what is true right now”. - -## Generic GraphQL mechanics - -Graph-node generates `entity`, `entities`, `Entity_filter`, `Entity_orderBy`, pagination, and `_meta` from each deployment’s `schema.graphql`. For scalar rules, filters, `_meta`, and common pitfalls, see [The Graph — Querying a subgraph](https://thegraph.com/docs/en/querying/graphql-api/). - -## GoodDollar-specific - -- **Addresses in `where` clauses:** normalize to **lowercase** hex strings; subgraphs store addresses lowercased. -- **BigInt fields:** query as **string** literals in GraphQL JSON (e.g. `"1000000000000000000"`). -- **Schema truth:** entity names differ per deployment. Run introspection or read the deployment’s `schema.graphql` under the relevant package in [GoodDollar/GoodSubGraphs](https://github.com/GoodDollar/GoodSubGraphs) before assuming field names. - -## Meta block - -Use `_meta { block { number } }` to detect how far behind indexing is when debugging stale data. - -```graphql -{ - _meta { - block { - number - } - hasIndexingErrors - } -} -``` - -## When subgraphs are not enough - -If the subgraph cannot answer the question (missing entities or fields, or stale indexing per `_meta`), switch to the decision rules in `references/guides/hypersync-hyperrpc.md`. When **HyperSync** is the best fit and no Envio API token is available in the environment, **ask the user directly** for `ENVIO_API_TOKEN` (or the token your HyperSync client expects) before running large scans; do not silently use anonymous quota as a stand-in. diff --git a/.agents/skills/gooddollar/references/subgraphs/goodcollective-guide.md b/.agents/skills/gooddollar/references/subgraphs/goodcollective-guide.md deleted file mode 100644 index a266cea..0000000 --- a/.agents/skills/gooddollar/references/subgraphs/goodcollective-guide.md +++ /dev/null @@ -1,54 +0,0 @@ -# GoodCollective — Subgraph Usage Guide - -Companion to `goodcollective.graphql`. - -## Endpoint - -- Explorer: [GoodCollective](https://thegraph.com/explorer/subgraphs/3LbJh9DXhJVvuVDdm5i6StNboJmL9oMNNkBaKyzc4Y8Y?view=Query&chain=arbitrum-one) -- Gateway form: `https://gateway.thegraph.com/api/subgraphs/id/3LbJh9DXhJVvuVDdm5i6StNboJmL9oMNNkBaKyzc4Y8Y` - ---- - -## Terminology: “claim” here is not daily UBI - -In this subgraph, **Claim** and **ClaimEvent** refer to **GoodCollective reward or pool claim flows**, not the protocol’s **daily UBI claim** from `UBIScheme` / `UBISchemeV2`. - -When a user says **“claim”** in normal GoodDollar product language, they almost always mean **claim daily UBI**. For that, use the GoodDollar Celo subgraph (`walletStats` / claim-related aggregates) and on-chain `claim` per `references/guides/claim.md` — do not answer “last N UBI claims” from GoodCollective **Claim** alone. - ---- - -## Entity Overview - -### Core collective graph - -**Collective** — pool identity, limits/settings links, totals, and claim/payment counters. -**Donor** / **Steward** — participant-level donation/support state. -**DonorCollective** / **StewardCollective** — join entities tying participants to a collective. - -### Claim and support flow - -**Claim** and **ClaimEvent** — GoodCollective **reward** claim lifecycle and per-claim reward events (not daily UBI from UBIScheme). -**SupportEvent** — support/donation change events across donor/collective links. - -### Metadata and policy entities - -**IpfsCollective** — IPFS metadata projection. -**PoolSettings**, **UBILimits**, **SafetyLimits** — pool policy and operational bounds. -**ProvableNFT** — NFT linkage used in claim/reward flows. - ---- - -## Typical Questions This Subgraph Answers - -- Which donors/stewards are attached to a collective? -- How much was donated/rewarded per collective and per participant? -- Which claim events occurred and what reward quantities were emitted? -- What limits and settings govern a specific collective pool? - ---- - -## Query Discipline - -- Use authenticated gateway access for programmatic queries. -- Lowercase address-like identifiers where applicable. -- Validate `_meta` before operational dashboards or reporting exports. diff --git a/.agents/skills/gooddollar/references/subgraphs/goodcollective.graphql b/.agents/skills/gooddollar/references/subgraphs/goodcollective.graphql deleted file mode 100644 index e503db9..0000000 --- a/.agents/skills/gooddollar/references/subgraphs/goodcollective.graphql +++ /dev/null @@ -1,200 +0,0 @@ -scalar BigDecimal - -scalar BigInt - -scalar Boolean - -scalar Bytes - -type Claim { - id: String! - collective: Collective! - txHash: String! - networkFee: BigInt! - totalRewards: BigInt! - events: [ClaimEvent!]! - timestamp: Int! -} - -type ClaimEvent { - id: String! - eventType: Int! - timestamp: Int! - quantity: BigInt! - rewardPerContributor: BigInt! - contributors: [Steward!]! - nft: ProvableNFT - claim: Claim! -} - -type Collective { - id: String! - pooltype: PoolType! - ipfs: IpfsCollective - settings: PoolSettings! - ubiLimits: UBILimits - limits: SafetyLimits - donors: [DonorCollective!] - stewards: [StewardCollective!] - projectId: String! - isVerified: Boolean! - poolFactory: String! - timestamp: Int! - paymentsMade: Int! - totalDonations: BigInt! - totalRewards: BigInt! - claims: [Claim!]! -} - -type Donor { - id: String! - timestamp: Int! - totalDonated: BigInt! - collectives: [DonorCollective!]! -} - -""" -Represents the relationship between a Donor and a Collective - -""" - -type DonorCollective { - id: String! - donor: Donor! - collective: Collective! - contribution: BigInt! - flowRate: BigInt! - timestamp: Int! - events: [SupportEvent!]! -} - -scalar Float - -scalar ID - -""" -4 bytes signed integer - -""" - -scalar Int - -""" -8 bytes signed integer - -""" - -scalar Int8 - -type IpfsCollective { - id: String! - name: String! - description: String! - rewardDescription: String - goodidDescription: String - email: String - website: String - twitter: String - instagram: String - threads: String - infoLabel: String - headerImage: String! - logo: String! - images: [String!] -} - -type PoolSettings { - id: String! - nftType: BigInt! - manager: Bytes! - membersValidator: Bytes! - uniquenessValidator: Bytes! - rewardToken: Bytes! -} - -enum PoolType { - DirectPayments - UBI -} - -type ProvableNFT { - id: String! - owner: String! - hash: String! - stewards: [Steward!]! - collective: Collective -} - -type SafetyLimits { - id: String! - maxTotalPerMonth: BigInt! - maxMemberPerMonth: BigInt! - maxMemberPerDay: BigInt! -} - -type Steward { - """ - { user address} - - """ - id: String! - """ - Number of actions performed - - """ - actions: Int! - totalEarned: BigInt! - totalUBIEarned: BigInt! - """ - NFT's minted to steward - - """ - nfts: [ProvableNFT!]! - """ - Collectives the steward is apart of - - """ - collectives: [StewardCollective!]! -} - -""" -Represents the relationship between a Steward and a Collective - -""" - -type StewardCollective { - id: String! - steward: Steward! - collective: Collective! - actions: Int! - totalEarned: BigInt! -} - -scalar String - -type SupportEvent { - id: String! - networkFee: BigInt! - donor: Donor! - collective: Collective! - donorCollective: DonorCollective! - contribution: BigInt! - previousContribution: BigInt! - isFlowUpdate: Boolean! - flowRate: BigInt! - previousFlowRate: BigInt! - timestamp: Int! -} - -scalar Timestamp - -type UBILimits { - id: String! - cycleLengthDays: BigInt! - claimPeriodDays: BigInt! - minActiveUsers: BigInt! - claimForEnabled: Boolean! - maxClaimAmount: BigInt! - maxClaimers: BigInt! - onlyMembers: Boolean! -} diff --git a/.agents/skills/gooddollar/references/subgraphs/gooddollar-celo-guide.md b/.agents/skills/gooddollar/references/subgraphs/gooddollar-celo-guide.md deleted file mode 100644 index 347951f..0000000 --- a/.agents/skills/gooddollar/references/subgraphs/gooddollar-celo-guide.md +++ /dev/null @@ -1,104 +0,0 @@ -# GoodDollar Celo — Subgraph Usage Guide - -Companion to `gooddollar-celo.graphql`. - -## Endpoint - -- Explorer: [GoodDollarCelo](https://thegraph.com/explorer/subgraphs/F7314rxGdcpKPC1nN5KCoFW84EGRoUyzseY2sAT9PEkw?view=Query&chain=arbitrum-one) -- Gateway form: `https://gateway.thegraph.com/api/subgraphs/id/F7314rxGdcpKPC1nN5KCoFW84EGRoUyzseY2sAT9PEkw` - ---- - -## Entity Overview - -### UBI and usage statistics - -**DailyUBI** — day-level UBI pool/quota activity and cycle fields. -**WalletStat** — wallet behavior aggregates: tx counts/values, claim stats, active/whitelist indicators. -**TransactionStat** — day-level transaction totals and circulation view. -**GlobalStatistics** — global claim and distribution rollups. - -### Additional UBI history entities - -**UBICollected** — collected UBI/community-pool values by block event. -**UBIHistory** — timeline totals for daily UBI/community-pool. - ---- - -## Field Availability Reference (use before drafting queries) - -Use this section to validate what the subgraph already provides before switching data sources. - -### DailyUBI - -- `id` — day index key (`unix / 86400`) -- `pool` — UBI cycle pool for that day -- `quota` — daily UBI amount per eligible claimer -- `activeUsers` — active users count in scheme context -- `totalUBIDistributed` — amount actually claimed/distributed that day -- `totalClaims` — claim tx count for that day -- `newClaimers` — newly whitelisted users for that day -- `timestamp` — last update timestamp for the record -- `ubiSchemeAddress` — UBIScheme address used for the record -- `balance` — G$ balance held by UBIScheme -- `cycleLength` — current cycle length -- `dayInCycle` — current day position inside cycle - -### WalletStat - -- `id` — wallet address -- `dateAppeared` — first indexed wallet activity timestamp -- `balance` — running token balance from transfers -- `inTransactionsCount`, `inTransactionsValue` — incoming tx count and value -- `outTransactionsCount`, `outTransactionsValue` — outgoing tx count and value -- `totalTransactionsCount`, `totalTransactionsValue` — total tx count and value -- `inTransactionsCountClean`, `inTransactionsValueClean` — incoming metrics excluding contract-address flows -- `outTransactionsCountClean`, `outTransactionsValueClean` — outgoing metrics excluding contract-address flows -- `totalTransactionsCountClean`, `totalTransactionsValueClean` — total clean traffic metrics -- `lastClaimed` — timestamp of latest UBI claim -- `totalClaimedCount`, `totalClaimedValue` — total claims and cumulative claimed value -- `claimStreak`, `longestClaimStreak` — current and best historical streaks -- `isWhitelisted` — current whitelist status -- `isActiveUser` — current active-user status -- `dateJoined` — first-whitelist timestamp -- `lastTransactionFrom`, `lastTransactionTo` — latest outgoing and incoming tx timestamps - -### TransactionStat - -- `id` — bucket key (day key or `"aggregated"`) -- `dayStartBlockNumber` — first block in bucket -- `transactionsCount`, `transactionsValue` — all transfer tx count and value -- `transactionsCountClean`, `transactionsValueClean` — transfer metrics excluding contract-address flows -- `totalInCirculation` — inferred circulating supply from mint or burn behavior - -### GlobalStatistics - -- `id` — fixed key (`"statistics"`) -- `TransactionStat` — link to aggregated transaction stats -- `totalUBIDistributed` — lifetime distributed UBI -- `uniqueClaimers` — tracked unique claimers via whitelist add or remove -- `totalClaims` — lifetime UBI claim events - -### Explorer naming - -- Singular names (`dailyUBI`, `walletStat`) fetch by `id` -- Plural names (`dailyUBIs`, `walletStats`) query lists with filters and pagination - ---- - -## Typical Questions This Subgraph Answers - -- How much UBI was distributed on a day/cycle? -- Which wallets are active or recently claiming? -- What are aggregate tx/circulation trends? -- How did collected UBI/community-pool values evolve over time? - ---- - -## Query Discipline - -- Use lowercase address strings in filters. -- Use string-safe handling for large integer values. -- Use `_meta` to validate freshness before cross-day analytics. -- Use authenticated gateway access for programmatic queries. -- Before claiming a field or entity is missing, verify availability from this guide and schema first. diff --git a/.agents/skills/gooddollar/references/subgraphs/gooddollar-celo.graphql b/.agents/skills/gooddollar/references/subgraphs/gooddollar-celo.graphql deleted file mode 100644 index e544a0d..0000000 --- a/.agents/skills/gooddollar/references/subgraphs/gooddollar-celo.graphql +++ /dev/null @@ -1,113 +0,0 @@ -scalar BigDecimal - -scalar BigInt - -scalar Boolean - -scalar Bytes - -type DailyUBI { - id: ID! - pool: BigInt! - quota: BigInt! - activeUsers: BigInt! - totalUBIDistributed: BigInt! - totalClaims: BigInt! - newClaimers: BigInt! - timestamp: BigInt! - ubiSchemeAddress: Bytes - balance: BigInt! - cycleLength: BigInt! - dayInCycle: BigInt! -} - -scalar Float - -type GlobalStatistics { - id: ID! - TransactionStat: TransactionStat - totalUBIDistributed: BigInt! - uniqueClaimers: BigInt! - totalClaims: BigInt! -} - -scalar ID - -""" -4 bytes signed integer -""" - -scalar Int - -""" -8 bytes signed integer -""" - -scalar Int8 - -""" -Defines the order direction, either ascending or descending -""" - -scalar String - -""" -A string representation of microseconds UNIX timestamp (16 digits) -""" - -scalar Timestamp - -type TransactionStat { - id: ID! - dayStartBlockNumber: BigInt! - transactionsCount: BigInt! - transactionsCountClean: BigInt! - transactionsValue: BigInt! - transactionsValueClean: BigInt! - totalInCirculation: BigInt! -} - -type UBICollected { - id: ID! - contract: Bytes - block: BigInt! - blockTimestamp: BigInt! - ubi: BigDecimal! - communityPool: BigDecimal! -} - -type UBIHistory { - id: ID! - block: BigInt! - blockTimestamp: BigInt! - totalDailyUBI: BigDecimal! - totalDailyCommunityPool: BigDecimal! -} - -type WalletStat { - id: ID! - dateAppeared: BigInt! - balance: BigInt! - inTransactionsCount: BigInt! - inTransactionsCountClean: BigInt! - inTransactionsValue: BigInt! - inTransactionsValueClean: BigInt! - outTransactionsCount: BigInt! - outTransactionsCountClean: BigInt! - outTransactionsValue: BigInt! - outTransactionsValueClean: BigInt! - totalTransactionsCount: BigInt! - totalTransactionsCountClean: BigInt! - totalTransactionsValue: BigInt! - totalTransactionsValueClean: BigInt! - lastClaimed: BigInt! - totalClaimedCount: BigInt! - totalClaimedValue: BigInt! - claimStreak: BigInt! - longestClaimStreak: BigInt! - isWhitelisted: Boolean! - isActiveUser: Boolean! - dateJoined: BigInt! - lastTransactionFrom: BigInt! - lastTransactionTo: BigInt! -} diff --git a/.agents/skills/gooddollar/references/subgraphs/reserve-celo-guide.md b/.agents/skills/gooddollar/references/subgraphs/reserve-celo-guide.md deleted file mode 100644 index 9f55b73..0000000 --- a/.agents/skills/gooddollar/references/subgraphs/reserve-celo-guide.md +++ /dev/null @@ -1,41 +0,0 @@ -# Reserve Celo — Subgraph Usage Guide - -Companion to `reserve-celo.graphql`. This guide is for reserve pricing and broker swap indexing on Celo. - -## Endpoint - -- Goldsky: `https://api.goldsky.com/api/public/project_cmizuamdtfouu01x4csuk5dk1/subgraphs/reserve_celo/1.0/gn` - ---- - -## Entity Overview - -### Core entity - -**ReservePrice** — one indexed reserve pricing point produced from broker swap flow plus exchange-provider price read. -Key fields: `exchangeId`, `exchangeProvider`, `price`, `timestamp`, `day`, `tokenIn`, `tokenOut`, `amountIn`, `amountOut`, `user`, `blockNumber`, `transactionHash`. - ---- - -## Typical Questions This Subgraph Answers - -- What are the most recent reserve prices? -- What was the reserve price on a specific day window? -- Which token pair and user triggered a pricing point? -- Which tx hash/block produced a given price point? - ---- - -## Query Discipline - -- Lowercase all address values in filters. -- Use string values for large integer variables. -- Use `_meta` before analytics queries when stale indexing is suspected. - ---- - -## Practical Start - -1. Check `_meta` block height and `hasIndexingErrors`. -2. Pull latest `ReservePrice` records sorted by `timestamp desc`. -3. Add `day`-based narrowing for historical windows. diff --git a/.agents/skills/gooddollar/references/subgraphs/reserve-celo.graphql b/.agents/skills/gooddollar/references/subgraphs/reserve-celo.graphql deleted file mode 100644 index 56cac37..0000000 --- a/.agents/skills/gooddollar/references/subgraphs/reserve-celo.graphql +++ /dev/null @@ -1,90 +0,0 @@ -scalar BigDecimal - -scalar BigInt - -scalar Boolean - -scalar Bytes - -scalar Float - -scalar ID - -""" -4 bytes signed integer -""" - -scalar Int - -""" -8 bytes signed integer -""" - -scalar Int8 - -""" -Defines the order direction, either ascending or descending -""" - -type ReservePrice { - """ - Exchange ID combined with timestamp - """ - id: ID! - """ - The exchange ID from the Swap event - """ - exchangeId: Bytes! - """ - The exchange provider address - """ - exchangeProvider: Bytes! - """ - The current price from IBancorExchangeProvider.currentPrice() - """ - price: BigInt! - """ - Transaction timestamp - """ - timestamp: BigInt! - """ - Day ID (timestamp / 86400) - """ - day: BigInt! - """ - Token in address from the swap - """ - tokenIn: Bytes! - """ - Token out address from the swap - """ - tokenOut: Bytes! - """ - Amount in from the swap - """ - amountIn: BigInt! - """ - Amount out from the swap - """ - amountOut: BigInt! - """ - User who initiated the swap - """ - user: Bytes! - """ - Block number - """ - blockNumber: BigInt! - """ - Transaction hash - """ - transactionHash: Bytes! -} - -scalar String - -""" -A string representation of microseconds UNIX timestamp (16 digits) -""" - -scalar Timestamp diff --git a/examples/storybook/src/stories/goodreserve-widget/screenshots/amount-editing.png b/examples/storybook/src/stories/goodreserve-widget/screenshots/amount-editing.png new file mode 100644 index 0000000000000000000000000000000000000000..8b704752374f6f6acfbe00d123a17dca33083cad GIT binary patch literal 69868 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�}6j9vcC~-o2x|o&qto=!HNnMKBrwTPCo_ z{H>gRmF-{qOm2a~841JzXa8<de8cFq~Vc>N1tNijqfoM>ZEVp+Z{X-S|KAn=aj`FOW4}OWY>_rEc_5R z)89tRI`y=kCO`r)_C0g4;>!3$JYjp~m;YF%cyvmCLTOGGLiEchP-_>RwUHwW|89Qb zs66GO?Qf%5naES#$ZWI=f-{`rTo=&P!mM`MQ8+fOYyX=cU*Ae|u0jyOX8{g8-W8Du zdt6#fvk-^$V6LFl6kMST^}n57t-F+csZ$1^EJf?1Z+e1LI&4bHC(^>ot_*t!txY4Go!TZSxlufjeuk%!2fnS9f<4rGVh~$qIvjU-m zjr{Y~BD^H8DGO#{hdHkQ)|AAEwItMg05v^c&^`m)vcV4@wz3PQI$GGHuP|IpsJm@ zu<6#VYO`#N)l^8WF6qpjnoBzU5If@U9#F@{^Nh2sBQ7!ejeaNAyBR;*LLubikG)a> z;W{VRxUxURmoB1%Sao-=4Z6KceOxlKnJGH6gp;rD9{Tj1`?zJX(cStdc>ZG0k4Q&i z^TJ*2Fa!I!yt=Dx-f=-u+`k%jz00qNSV*SHm(RyC;T<+vWZ@d*O1EyTWK?u)vTKkx zf`MN8LdM>c*<`#uSow4zXgBIVON2KdGc+35bk2%|Rty`@E2|I)IH3pS6H0AZ(uQ#C z^TSzQV62&GhJS-4`mw&#=Ey=qy7L9quU}ZVSG_e6C)nG&m(F`%=c`&H3BCq}L85dV zGy6#wY&?jKv16k5qmnYspvB4lA*7p1PC#IZX?D6)XE@xMTY_P9qVgLdG@W|ArqhP+ z1d8llDL`VLnw_J%L*iXQ?%D7HH;_!-@Q@6+EmH;sq;-n(WN;+`6{#K z_ObS+OtSG+v=in5zx%0<6bs*CjY!4|5yE)Y;p{@3F|N_%`Ym4?u8#7EjRd(3h7+~l zN1ls+#Gwdb^tt8epD?r?GSu80#s4jNi1ji8#)?h9J;>v(W6_M{h1U0f0BQ^T4zn(V z8>kw4bKVm8My`P&BlAz&lWz9zrNyi za@rUFDLqIMLF5}47YUXY0qcTG)8)|ey;}}O>CCshkb|K2)Lu1^(Sx1z!EW%jjq@JL zl?W^V(5}Dq0pP3Y`YU$9yU)A+BmpC77le>6TCQl$=1zk20m=aM<>w9D%-V(3e3>-g z)n_%n4+R_dz-XA2?14rqcunOKhm?&506%4P-E!pWBc@BOfotn6pQ7?27)(ZV*4DXj z;m$Z{99BIpjD$Du84vy98#`7B+MFQ3U<4}>@f90)$^BUyD-B|M_S)^g9oza@Evs;; zlhb6^XHRD~R67fjVrG6`%Bs_e>py&hlgU6`|_hvPbBksukl<$Nf&jZu{!z zbT|SOyW=Y!rL4u$&@03+8hR>pje*`Mulo>ElI?Aikig!TX*V)YW%-VB774=_VWoB^adliW`gHJGDe~Hpy^EF$&`_u z3EYM}@_Qo5av==Dhw%frJN)2ScX8OkEIVWRL;qMT*tl|Nax?*sB$bfj1CD0^nD|Q0 z9WvnPdz-DJIgO0|l%1|Y?_77Qfnd?C-#znMqdr)?u-?LEc@hX9CL^ZFt zRgCSeC4*Gwv!>|FM;BOPyHUaIp(p?1rQ5;rT45gG?QJ76ioz)~m?jSCC%@02rOiRk ztD_gbGP`<4b3_lG!0$eVg;x2c^7Ah>?jqCunJ`h)Im5ZidZ+&{w|y=4~&>L3>%kr3)bMr?je^>@L(BCCNE0&H}k6YyRgLuLc+LqdFBN5 zw9NY*VhlTC>Hg=%#R^Evoh;9tLdMeL?nNV3HaBz~2d@pa=r^xt4>{`|{rZMSv*JChVDetWIGV zWOD{T_nS8UhT})uvu8(Jma8%6OZUK{bL_uPRe81m64aeeDUea9|?9N)e3#1~k4 z==M52j!Svkr$!S$0Lzv7>q<)VJ)=~Gou1q70N}_#Sr=WN*Ky}gBD-EW-RrD6g>T(=43*f68MGS+;aY^@g z95565K;+fiXN?mAH-Bi<+pa^nNI#KcTTe$i(I|3wWn8cpRmWIel>~gx1}6N}~5VZuB${PaIet>Q*{89HrjajwAs{ReA08NG+!UxEq99!4Ut0-$iIniE^jI& zMrWl4RFQ?nMg@vtyUb&R3}y{(D?#N3LIJOhuf`ZuaTK#6PPviSRV8jW*QTty(M=Rq zN9tL^4_46035d^U5*+#6qNVEIoEPyoAX~pXdz)*teK_+;fFsgAlM&7E=E&16F0eOa zXh-ftsGbj|RBz7&A?LNjlNY#GFZKAiIieuON6vk3=456Eje?^ST^?lDS6XZagAY@P?mym0zy1pWZ=@fB2eu&k+!NldXwbFg?5i zL0K8i%r%#Nx53ma__NJ9fl-AY&LW;D6(k=J6nbNbB56{25)0b;M;B@T7ITBFBU^0J z^T-3q$tNR0S;7uu3CaHLqB?uGoj&oB*!ylpwCK(gZ58oJ)yrJ;W zD3LQVPD=A6H9#}$^@BQC?WMbyHSx9|?!UPJH}m1Z(g#hBK17|z!|mUxJL>{JZ0sIV z$#f*Z9iKHJ(jz=-%seJ0YQL>(gH9~=5@sCs*c$8B&(?k_IsKdwcYe<)oh#|QKL=~9 zxmbIQ_Nmjgg0pMZps2V*Ua>!=-8C}*FfD7urudD!SRQ{Ot{@sS>5dDF6$&ecPnJ_+ zwcO4W%(R4qL64sorI5`15!yjX3#JK8Z!Ppj7p^vqT)MX9aqY5)dJYT92mAxz6b3WU zvB^UsKrEKVo!D>!#6L=DN?Yh7Gzo8!nERZHm9X*gO zNeStWVX_-d^dKDJ_pWDYcH@u6*7Vrg?asZyB%F7a`W_C7(0WdLXS1F#!}2v^oSbEG zG-}f6@yDMBfjWb|bU*=kyE&HI#K6pP>@fkw0ZbJ0v9xbE?eqR9(+PFLTXrOZJ4)9a zsJKYj&4Pwuw-}E~U)gG|_hm~2OvKP=%vJG=?pA`_0wce9gnY$krOi0TGd1_?TW0M_ zMfSe?4}P9apn`_(tX}Ua-fWb{@`CI1F>z0kY<+#E(b=IW$fOg$5I#4hGjcxXQ`Che zHodj^RixJAP|i31oKwe;0lgYq*Elb;P=i_~9OMe!ZJWf2JY}qj%rZ+0L-@r(7m__s zwo~Lj@$tRDm!V1)xzJP|0VZSb6O=)MpOZWW-l7(q#jT3+%AUG^#C^oA z%;2HVRm#_43%tj2#57=Mui0$3K0*1Voeq`AXldmAMNSwHS4?8PSk^UxC@AS{iyTSy zYgwzfozKIK2w0g&k5CgXyS#xabM&mBl63$!o#Ub3%_Qw%n`vv#-#^X7+TYA(v|~6Mtl~QNhWuP#07GA3a4(gQ%~^F@I)4S^VF`CGR?1&yA zt(S~4SXA`mbd5vG!CEEP&0D?-1-O1ng!>Jzw8D8_mM&t^+nf~z7k-&Y&Si7}CaV|5 zM`LYxdub`fAe$j;@g6Z@>#8}Ag)Ifo=STs!9{V_rHnu8IiWY06f--((^~8R`VD2Q` zXg@u^pSQWKt);;Hw*Yf;nx)e~1*|3#(%wmLJwaWg{O%}I{L_rrRD^}GVR!&iRCYnb z)qw%i92@or2uN?y=F)>P*=8Y~`r^46+k(12@lMYNMkPuIsva6Z{ioc`tQR9G0263R zQo=D})g+dqsmaDiK-4?iRYTv@+sP@J<0p&cXfm{CM5j0Kkqudy_y}2WWK58gQ z#|vQmf<=JNf8Hx?uPw905hbULnU$i0nD32^5wj^~STDmh9)y)IV3WxSMS>;_EX<96 zRW@R2hB}-E;sOifK&{nhBYu_j+qdS9??#nfLI3IucT~U)Nq~XOqiDkJxGde^p(Q;!JpQ=?8mkg+xcT6Qp13neV=0V zzoYdE^ZMs#oz+pA>Zgud85q=lJUaFb8a%LHA~QJYFcGKNB+nqR=_H9tJ!C)#3k^|E zCeQQXbp2`0!kkxMz*s50$?{cgY+yh?;e85Re&h!f1g!gb4(<}`ME3Q1cIVCHVsa9w zRT-_6cm7gTbJf+>2rGDkGl%<vhq zG@tbhJG8el)-Xm;qCl|~-8r;HI)@t>TpV2(F5)v(!`9s4%e?5Di1VzF>mq9bCNdt4 zFq|Alb0L}pD}DryuuaI#(OGL`#N5G#d9^OEewAho!N#i#($93&Tsf{x#E37_uD25=|l$P50%zexC&Q+2u&O;h%BlJ#*=N$p@6W z>*o$;G~ODRp@w~Xh3KM{UnCw4z+%#HW=>p8R^7dd7eOTm^$SDi(zfA7vCY*QtBsum zQeic1;KgC4D}(Fiz0>a^U&*DfPEXN(fg*G=K>&yH8p-7z)CyfAD^%;U3jJB8tytn( ztxiP^f;ilE&Sf>V3JxW|qJSZonX>-hOlk$NB4NG1HpWy#PAXBfDA=`W=#<|vWF=)% zDaHfmEFuB~*p%`6R5FJXnpeK1Lj{p|uf((2)|~|5vy2M`!T!LA4OJt=Z&` zV5E*}5`V2QjgNudN>p$NY0ywQPQz}0@Uw_at#MUu6)Q0PVS290_Q%-vCg%XL@}q;# zB4Ox@ODpQLW$lLV>PCIT{K>jnszDG@(c@dSsy`e-xt*4PW z?WDkV1}lT}(Zf4Iq>}B}T4h12!S75DqNHCx_XiF9HDhtmF68$p+TEVts>7-`%$leD z-06CLx@Q0`T-DOnDEU%NGO$~hQI;IG?_a#5;W-mSzYyn7b1un@a+vQ+~c)IxPvwTwi8wrGCR$5`NtC^wJm&r5>butN!E1&HpVw zX~s?_1auiIbW|TjeU(0Hvot|^XekBxBv2kl>_*D_B`4s7B<4V6_BIXCmw~D1+$=Lv znyMA}>)M5n2PV9qryV^n>|h~Q9>MvQDU)%g7c?#W8<|xKjG4Lu0Kg9NtGZ5#<^RF% zi0A_7d~_z?yT~jyw?G3t+@Bh;omRMKOmKotuj=H~q{FKui{&@QX$_dz7R)1L#G#Ye zHoodvnmCmlyvl1fgnzY2s*m!vIEu=zVz}L20AyzoGIhzC)=h9Z!m`#^%17FNX>*h3aQa*5SBb?7GxcP>oMQF^@ea1Ea~0 zN9k#FewndyT#@M%rM*R&h7Vc_k^@jIUmV*|m0ShjA6LfI&EQqCqI>|`x?FKpm^~YI zez2~)@ICv{31O5T2ugL|34h;=E+byM^QBGrAB-sn-bF1?*Y-Yl)yHVXi@y+x;>DH9 z7~KHQ%=g8BqU3zY1{DAHcF%}bYNkEjIJ9Xg%ov(yvjx{i(yX?mR^k4mCAUmF7Vwyt zwA%?e6~dtNa!EYFYi9h)J{DzauB=T(r}WTQ=-kki_h@Qb5pKnM`IH^nFkx!7wPW5> zk_BaJxH9*LV;l~ixuwlEvx1JZ!a$Oi5t!QqF%N1M@E+GJ%-$Tm?7B*qx9Wj6iO-qA z#D5+{`^X1^VDB$EO?GY`RzNech`^gh`jy&YD05eSsv98~vSh(AJwAw~r~UzApnf!|8Hl(f|C z3peh+JxR8)CNbW-Y9O)AV@Z~9)?!T_UBGfP&?4(*S3Ymt*$Q0e|i zK1*9#=_ulhip`~)JhQ{JJz;`ZRT&F~>wgCF{qoZ&qLMvA?HHg)@<23yQvdt%dRR6v z>(UE<^j1z2Ym`(nRCVqp6rbd(@Sw;9)KtmzsQ(Erf<0!~S$m z)45SiP+_aFgs$i#y4+Z8{xWDeGjD-Y-D&n2xNMR`{vdl}V0r+7To!9&1cI(nb~Uf_ zxhZ}Iq@p)F?ybp#i{!FOYo!swGCPyUi4)10^Lo+66KQp^ElLtsZ^h8rScus&T&|(O zY{2p$a`aHS7$~Fv44V;{91+1i`fajTFJ+3yev35h&BxH1*{`_%!#!Iv;B2bU@@(Wb z>|h~CKbbuP(PoxXuk`213;_Xas)NGQ*+p)jf>RnJS?kM?Q~#U3+w5j3G{vO2QzC+` zbgz7woYYcDh7;*J8{1?~$7kluJqT$eR+LNMWB8n{qD%hoqQos&Q98B5(SzvJ$oh?G zOY^R?m0K<~Ty1EGdMS&&F~FkDOk(b&T73@o{SJnTN<=YUi*Ix_QOf>FO`Hfq#u@&i z*(gRe4CcIm59c{$WjsyYn2nO5fjR$cyh zug4O;<9Ognq7iLm#0SN6Mdx%^mU$5h#L5*Ap(Z$+ni|j0AXnILR0hoAt)sWAtaHK! zt*dma(o%;mL_zaxNc~r6lbJjWLpl7~8rHh8c<6DI``QeAL*!pqy%T^`PEx?}h?qN7 ztc6BOj1}F-hVJai^Fp6X{P zg0MPWpODG9ceT2wP@Ro+jFBM+r{q?!gONi!GQ4L>>qSXk$D8yNqnV06_%gk$)hMW- zf!T06eILu%z4ux3%uYj^vYc+c@g@D~Ygv;bi^sf;;az0P#c4h3lrs;ZbtyG9bv;E_ zNo`<~$Y_6zU}nwAl1t_BHqco7?jMBkTJH22Ii6=!U~*jrs~HOGOUhbrKPma=6wn=a z%j@c>$S7H}xasZZ1g6h`MiJ^OO8W#q_=&ucHN5Xnt>^)2M&u;A$zvans_4`TbeWY{ zwBSi-;LayGRfoiM^BXTNvzS~I>vw04tL)+K=s|wt3zF9i8%NE$%(n(wP1e5@eH6 zH()_A_4%nUSzjXf&9%p5M*F6YZ>yzK#wl)?5ATm^{pPU7eDS(!HgThN--3#~#|B6h z-K6T|T+?VGSJ_{RQ)mwTx=Dr0H0K-Ggn(bcHqyQ!v+%0nMc1TE$;qw{R(n`Vt>(t5 z9@tg818DaK(&>EOW@qpp;s|ULMD%FdOKqwYIifqs1!Je%lP>gz`VMX-xzfC-5yJJf z%H`7esPuM8!7r{)Lgjs$omnNrB5q*Xskdtwh~mN^HW&))Cc zFNc5GfvDSBs_U1tvEYQld(=r|;!~g5mGNp!E}Fv!5La|77O*L2XFuviwuvlg>Znz) zajDdophkXct1XhB-~3%iA?EGOgPYsG_`sxvZx&)W==TN1xc1^pVh0JFhcha6`Mj7>8<(O2 z*j=AOh`H(R!ZHqVI@K+KoV!IF82h7h%2j!=mVjVFTP0Z||HKn&#YRMQ#EB6nAJd>8 z)2lB3*-(j%4S6!~0v*9LGU5okrHY}UvRLD2aEJpk5b~uU&1BG#6YBJZo-zdKS4EPB zt4lB2oFIy@J17?^Xr|ifW~iyAWM4szfZ1mE{dPSv?Wo$7c0!P)OMLf&)qu55(rbw- zttdGD@=4DT5 zsu2sDO7sRd+@9oX=5i1UBqr6+lGa`1jA4AcvlD+HB*_AF69S^NVy-7RK;9=i zY!yRH*k<&KjKBNjC%c-$a~9UrPU|yU*UBQ^$rV;`C+%KL_+_J%PkPXxcaTH%fNAn`tR-=HeSBGl7GVV^D_b_3&7TkPQ@pk&mX<{& z_G_O7-)*YoJ8z<&e5&%l!U@F9@BX9cvl6N*CNY{W_#*Bjge?{2QZ9l@k$BU!see3t zvblyy-R&Va{FUoT=34Sd`` z#xBzfmRa28fF&4i@t=*xjS8C65_7TH=z#`=8f>1@58r!Da%d6 zFITAS>-Edt&uB|zg12%1Nj=|cMK$sDlc4L;xK;c*!W$3wL)ZYr7_DC+rj|tx%h_S#%DOH3)XNm?iYhX zrWzww-h5G~izf^SI=C{>#MghSFcy2r4AIfH*=n5ncf;0IDo`?}^`jD9&Biwruj=}A z%D`4n-7UqB&M;p~%S(%hcxN|zQ`<6|!sDjpLN+F+B}d(w>b@v@{eAhFter$docJ(~ zsdK!Ee9qCjs947N&ku8_+6ykT7gVZ!+_M9RBw?v8R%NEzjkHaA*_=EpmMXeME!zCt zY}A>C2X2Q*WT_+rJ<;VYQ(tuahHJmXvKBm=SPEt*nu#AlT5U>$mSJr^SfBS^c*MOc&YX84Nh){Hs?2}W!&r( zy>`wURPU~;`h9#h-=V)vCA;@gd|m-TXJ_Q$axvKaV-GnK|1N&;Seu!c-tzBFUbdq4 zHAmpDHblFgzZ#d@I^guz4_|%`7oIhNqQ`fI0~wueqMTc_{!B%L9q-Z1^7Cb9@OjL& z;+b~{t-{f>_#riI3%7&wm~kG*%5G1#8}D#QhYxm#CUY1CJk#-n%$2q$>!nbWMl&tr zyW9oXhH(n2CGXdpYLdd|H!R9onALu2VoZ)}x~Nf+p*);TV8dp>&DRe8QVkumppRvbhH9NKc z76zjKPr%_Fz>mzob@pzf*?0?jZ`KyS)3~Iq;kmD=B!Yv{0jhK-94ew~ih(N~FCl76d zX$39MS=r5~3&8nr<@$_hq;5u~9o7cmJM$uiQrRCUTWd|Xq@g2~j$-r#jGt5Cy`2+! z)s+tdS64_7f^tb-n${G#$qh(&WGl^dgqv1mqlw*~1y3vRBwj>G~Jba+D0kd3W_ zA#c6@mfV5vNe21Daw3@n)jhZ%_0TbRS*5O6k^b3Nibem51@*81Ehwp)M%M;GZp zt%`n27z?T4QD!k1ADk+HVRt};xi=gAWvDOdD=GtDpHsl!s5&oAGo-X=RWoJMj-KJQ z#Qi50u&mMb0~O?`-D7le<|~vw$s3D6{ZlZNoD;{_+WKa`pq~z;*!*6KA@wsG>NL*T z#K&Uq5`ol+SOgU^8PsgVl$cX6LA|A1H^PVmW|DYH81zAPc}^>7J#@R`R<00gF_RsJ zTYw-^Q`cq@s>#tkIiac*o28))(LLID-7^%KMW5PH5Za`cOZU;a_`W$*7Q5iV%@QBH z6(!f8CwL|owa}G8%vM>{+ir- z+HqoMYvZG>j{6!79b)S>F(yBs@!!QClB9l9G5ty7B09j{aT={0R1zGQ`49(h+wPSY z&Ch&Pl`Vdw=N&g5Wr_?^F_NMKGu?U2Bvh{a9%aQPVcL*3%I)xJ`fso# zH4^a_nk%Q>-Lzp&eCH~ov+~~<9O=c#@#1gfp_{Cc4D%@}c=5K0Bk+e$m+)|KEH7Zu z!2NpIHj6GxN}*c(Hba`lljV7$*qLQiA_|#%H3u{2ctc)wX{EHpJ%y1nWh+0gt*<$U z9-sRc@dD{qE2MK!rSPPUP3f%jK!pruPKOV6b=2-24mQaEx9X0bbLN{+^WBbkdRLqz zWcg}HSS;0V7TS5C#5vKoARf=H34-O}X@Esg+;GiLm(pax8$BSXIisxWaW83nC{pxm zq}~$C*n(B*Wq<4zvZ&m&)7?-`VG3f=UQ4b}X3-JTd#C#xa}|wIlKb{)@i1#k8o}{! z4eH>Z%>&4u`{ExRdPLb6{W=9Ig;x4sM*=v__*tG&dA+pbe({erc|=^qfEN0oD8>JK zZpS&n1^|elX{7Vjoj81;4wKXU8E<8^;4W_6sGV$^!e#$0u+3}R#WTFMiG|z3O__Mf z7<^dmOf^k?bBD%_!NQi@Xc#DpFf6~NUlE(M$q=YirGz}$5|B!B8>{W9^l18IsVp^N zWIWkMQC5T9%R)rSnS}R9**?NgZ*_d%6@ODEMBJc@vT%1Py3~Jw03_2h!`!peurss_ z`b-yHzs=q_E1gIBiekGjZC05-QOH1aG&Fx)wsvE3q2KkIa8UkP8Sja* zWp6d9i4Qzw&npQICxJWEJnQVFde-NX-*?lSs@Ps~=JNKGSWogRwQ$6%X7ME3>f_v@ zO#L^&BDyc_W2chw&1s91w?DIO7ax6ToG^5$NRAtUcw`rkoP?H$>e8$)Ll6r=RQhLmac!aE}iaAf2(ZmP=4i@%*>htW79 zQoqGTjWqSzL(@xGGNVw`$kOAY+`+V40Ko=(JI7IVf&#$kemaRcO?ME#`YJN!5 z@EnOR6K-w{xt^$=sE)2yf-o^XhNqf_r$mrk)l_=Z#N3mqMZ~ztUgkjZ!jMUrEg4;E z@7g=E{{0mhFOb2eqV~!Vv*05Z~|1nwiCYt8xMT$wMS*raNyEYn@f?-MVNv zYg=+vuH_Eyl;1t=ssXY=w;gWkhqZ~*j&7XE&7i_)1=jn2hG-}!y}4@UJCcWV$rB&; zD)nWfJIz#xgMFdtbzgj97e>7Vu* zGJ~OhIZ_X5VMF!5q#W%K(Qtj$QhG4o)vyXKPAW2M)W^JVpa~CX`3Ma>LkfF0QATJQ z7pg1e+U;6%g>5gMt6B_hFSjJh;1J>@*iTE&ETO=H@A{VcTMV-6bI@~JoT|Ri8*Ejo zboIqQvb;>;)d$OpVpNlAO{&IAf|^=OSMhZ`Cg@RmM+PQM>gNbl?M{#Vw77A#gSpw! zfQ}I%EXDgGa>2d;VAFa-b`Llo33)}g-*YU3s06hn`dw+F+;`J8g-7?A!x$skoH4N| zP=lt$^(tMC4;52+TE&MnRkVv`6lA3=M|hpJBwmuHf;A79bm73J;5U(f*_r9IiN!C> zbU?YYB;9|^OtlioslpU$s~KGbP_X(ClLffPm9=fDT8h}tMT?q6Ahr;}!BO21$;iQL z+drm3BK>wD|2@+6<$Gyc&JZI8l9Sam&`${Zukdm95^E@8zecRxgh~6~TYK+T zGu{fFNOk1oG1@txwRAk^?LCknJeWPN{loP}+^Uib#0VaZ1NQkV)aPAe@HfBn<}cH~ zEpzcWHoO&T&ZjnrA86}Ks?Em}NCf`M$cN}ZfB~FF)$@4qH3R*?O=|fd8W}Zm?C*B1 zgua=mT8&4wK1p*0$Bz~Nb#%LL??F7Fdhe@l*eU?RCn}%9&-GwVVthl?U4EHVLrrtK znD=4c*EE#@IeI(6g~h0tc`<7#`R99IRxd+U6rE^}DK&lik|{QMcOAyNJ%fYAruNLc zf3m$ifk6o19&(rFlgO>6yNL1g_1v6o0oKWSTGVNciau-YbS6VfrF5RYA$e^cKGWBC zkXXyM<+=9_6$?3xLXGXrY@TlGv6fMeZ$ZTSq`?mNyXUtzP3fs5{T!4JFW?&AaX*Vo z|LD}f7dZ|h&C)oO>+MZCBDy=FsbWdzF8H;}@94N}xM#h+QuD3b^KXANOU8`H8Ke`* zBKFVRnp4Rlus1*4iPML*S5TpB!N}F3S+y& zxrY(GtGVZ%+*OZUA4>6W5_jD56Ta#0>UE7U=(8x1M$e?5B_D-{YsBOrc>UE-G)@Vw z5&aiTiRbTsohidKcK=rcC78Pp`~5E*P{UaEjiOiujp0e)n?Q`{emg8$tYs7TXnK=% zlLkc6!_NniZWC?~X5R2@dJXluv`4dLk!svH2vR!m1hk8!n!CqDV*EjNP*6wB%Bt7L zd~Lb18Ff@PtGSbUqOwbF*R2_SCm?2oi|~ZCwjq4@+vH=X?mgMD%1&d`6=byo7nxQz z?^?xM&_Zt6>wIB8O~a26-0!e%a#b0;)S0NbCc~5josZ4b^E}sf)PPcQN02znueug| zhW;oJ;yz5W$GZo(ESSh+$!d&_9>84xNi&)*o`XBM` zO#3-$XHVWW{NWL($1%~$Z0*iifz?{aX7i-y3JNIIe^7Jl_V6Yy!s~VddLL~mvXGE6|^St!^u*M7eH$PS_;E_SgGt@)bJoLJE2EV z=XNfEV!=*V!`3@P1uJzkxN+b?W(zd);{)~Fk$WH^rAL}Qr__~tyBV{g--ydrxh9J% z%X8H0h!{u#_{s)T4mWtG?miNDW3T*SHg0@J(3Q(wE^+JLe~G7c`e+-~Nkg$8GM8F# zvk9?rqRj2_(ls1;^k00r!Q-qCE@H0PYz5E&xK+Jp`U5;>pwldIBcEj@GUtI%Q;EMz z+65eeZSB{)&89S*U^|~Dh>~1@?%euLq;K?c>BpW2|FE~S;jo?wJPRCwuKrOkKKV^8 zJ&`-jHX#h9|64%=OE3ZNW!{}#eBw90g$kAKzjSifN-&qbBV7}8Ok~E#1nzHihegEc zmC78no(F*|KGU2F%S$^wm#P2A^c`?pO+31oaY zalIn2hAp{8O4yR~eJj%RbhN5#N3%d?HRCVecW-Hu7TqjxU77YTn`oti;%XtXHM&tD z(iK@(^10_QBxH9uGPUyh$vNwck=?BEPTUE%b@UjY0P&dZpy;3KppZU=alp+k@^QPg zd)6rrZ0MiK5Wi@-M`ELwL}UB#JC8BJ#+y-1ue-tFNompTvOSoCRd|Jc5{vokUO*Pg zS1>9tSHIHkBA(>M1VnnM+3W{Z1kp7kkJ??>>YGtkqXJfdcXq1Qg&Gl`+M!MJWNoG-J@$( znVobBH_N!A>|CtND2>&f_gS&~{u2v`yt$^a`kMtG**gLrFCN-K6hRKadaq5$o z)YxV1gq;_Cb4&L{*z2{_%oiWXoRH(6XNeIuOLNI$3X-?}{XB*cwJ_2diu9(6w9yus z9(XsQ`Boq)3eG_TP{oFOcSR5l_PmXA{Ju18c*(LsTHj?grF9_P=V8$5HezMv=Knqj zxcJX5%)LvJ7*C&n3W#8=Cn0r;`I&l`x;5l&a&K^zxMU6kn{v^C(fhJ=&4B(9rB!m5 z^s-P**TlAzY9qLAZDnQw^Gd&r3b>4Q0BGQ!X{B~;;ht>rW3J1w6TqCrp7uE1c<*OF zD_V;a0LR;nT$y9c1~df0Hedk@L+5o9ZsEeZV}1hr(%F$FxfF4W7qB@VhuIaDVF91e zv@{}u;JGC?bRv^@Pq!awYEM)fSm2!i()Yki7s-K*-NEvBt;l4N&}9d(VvD68#d`|U z5_;zvVKZdF0Z?teB5!y#1yjX34%VL^W4%fKhNS-;CanmE0{e)+B;CQ&+hHd~=p2rK zgQza~F24mO%G~u`o7OGfU%lWSfB8HLZ=NrOY`$feEqW5R(mT0ywWRFV6U{`S6eYoR z_}qlh1Lf=I9#|+Q?-UPa^6}cqUStmfB*XXOt7Fq!{h!vCm>CPsgX{VI*TB?-km>|) z(rAM$?2kUWiHr3Na>w;u$x`wOKC1Y5wNuibcwU&gh3;A5``w(0TkP zoU=&#=nGXBvfe>Uu5&rsGd~2H+dQ&sl#f|rC){`oeVN<{UGKH;SK7tauLy6Wtv~}t z^Dm%B{&jHuCWepZAB8fMG5(dm!g4W%I|MFxm7dCrnt&7#86R#1&xV0X|Gf*NI@Aym z(5*fAM-4A}T%72&PV!0oo&U@aK=mh%;;``mBc?XuL0Z4w^QeXoL~yGm9vhoVb-HUF zS!=T7on<5YPjUO`Rs^KmVDtbTT~I6G#8&riXt+w{b4K|j&-p^FUOgj4!Mw`WIkAVKh6 zS^MEf2NAt&wx8h91?>~A-7&(>PcrQKkafv`u-4Ih>H@)r+05jiL9W(BjB$O8Xr+N@ z(uMOaeK%so+ACetN-EQ4gz>Do#|5&6`@Mh%hII^LTGV<#JZnOKKKavN`>ny%jrZv$ zuoO`c83KWt0*eAcnXY@GQ5v=?jN}-si`A?50 z8&s*H3)X%1(4R8U38ibMGZjLNcgk*w_fQ@JFFynHzZ0XsAxMEfRe$u5Cb5s^pnd?y zw;7itvwp8mL%k~QhOYby_nZw1l*Um={3ilG50RP5AulY4Bckx_p5=3!$%TLaR_Te47c2JMrYpi^``P1=W9sQ+Bvu~S;jEC1XT*tis zE_rmBVW3pX9(`z0iWG)TavR+wlCs`hEV=5j{|USfL4$p6g2DiyE{u^X8mV4%lb83%izW;cfsS0c3kWQ~3Q zer>HD_jhSWR_KDrk6!lbZvjdqe!gN0)+^g3UV1D$WDV;XB%t3_c_JVAEw`8?N~DC> zC;j=-bv&*&P%(QQgS(hf+7L99&`6vm;_h^1U7ehNaLA^n0`QS~pvziM?)QX>vLseo zHy@vn(3R`%ZYglf`W?N`ikRO&@uW_w?C)}&%@=_^K)8-Bnk&ko@Iq*A%9KVg{PiD+mjE-7s4zD}r=wqv2 z2<;nha>ox&-hUxdO)`1CqxR-Ul-^}ekEZhd4T9ECbs1TE42I0$)uXFI-g~=CKE9PN zxZi&Nu!@S^{aG`4~)& zx-fz{P)RsDLs&6oG1}i(b6w25CJ?x}4Fjr>IL6~d-^<$3W-l$Q){3rTY>oR4 zfVJG+|x!r(vpvH#xQ)wRub-lmVX_chp-cHix$vUcwfJ1TQ0E<3Gx`=m1cDQrlW=n1y)_2=O==Qce?(%SK`Ue2Rgv8NHhPw0w`in{$v%$4FlBcxXZ{x^s=y zMT$0PSMoPUtzzGukSOm5M2t3fWZ`i}|7sJ*JwouWxEdhVwmF73TI#XSD3Mrom0j&} zIRoD<9cep+2${no6nh-k)p@!<3Mn7~`A@Ka|Mt^&V$}b1D$ak1;Xtn_{}3W)odxmT zi-Lro#c{PH($5etJnlr<^sAcLdY&GYVv1KoZ!RZO)?593_7#FvcU=Kt-X7fld3aBN z)-Yyb*E74Rm)%#Ku<8FWFf()Ee@t^n*k{XXT2`mN!<(@Q{Uc(f-F!2LY_hn{^w8yG zS)t~c3K#Lc>sqU+V6+*Fn-BV;7Zn=NJ8kio7VF@an zEf6}L5qJ|){a(lH2bXbJn5LE$-}@Cj#vYJf(h;;T@*b~m!GeCcT$t?Xm*j4j^CW(! zD@Vx?q0oQTOD2=6Pkq!4?#vs*`cD1BMDW9ku0sMghy+=SouqAAmkQ4g8e+x(z|5{u z-BD_nrgcxrDX5f>G|s=Wouu{rR$0uLcI|Q znc`K~m7 zBQ=o2LSak_j%!d7r~yvCRJ{9{O-KnKiz0Z7rC@_HJ_VqitL4wZoB{7?v8zqAvw>+U zbFV&mLw9UL(D^^Nb%BHkEuZl~02QEJfkg`r4X`-HrIJfM6@8#*wC~qP<1h?X1k&WeZC8jOj(Yk;l`-todcD1RG{)oruESZ%b z2W|Il*l!oV`w18hzqmqBmVM&H^9_SF!WqUKfUmY1l+_10`CE|S+(p_} zJeu8j;x&bvN)7gN+rN?Kb=Gf4O=UJ;uHm{*i+Bmt=WxRc{4nlw#%#Uh2|NbQ7!KB; zcZ(Ka`n!^?4u7Q&k3_Ukbi4Z^liy1=#r1uU4O$q+uPAqXpw@LyHH;8zKr?|LUQsyfVv6e))n*|y}yxw;Y^Er4}Ta?$`#~Qb$ zI;(hEmFh~npRe4_(=4_-{wEdy5<#{JW!c9VIeYRwUzu0WO{|^L(XrM4t!8}Z*Ev`9 z=T&A}fzT;-^@=Tbi_OYX_n@t3^?vfrW?CQ{4AI1ogCPQTvyognm!>p?MBB{jv&(E$7@v7XB z_64^zy7>MGywB&ma}*%?06>en^y6;1dCSVa13sI)&*Mo78&64#>xP5}qe1IUL6b5; z%OXK3pe3tq0l@D6{QJKw!vT{)|Mjfe!b;lMv;D}t%st1S?7m$~PadsWVM5De-M!*^OzV}400@Pr+VD9N40TZe=$x3N`jY7KC z%LsD2sH?mUGod+d9-w;NpD|d}Z@mYU>N`>ai~Ons^LrdTy;!w#IB*_(WI2)zw42e{ z-v2HO)31ZIL*!N}Kv${qp#IzwZq;tzXSV6m?`eLe#E#@-{?Q0l5bw`B*dt4JL8xvL z!q)E0V}6}wB{y_%i+loUq1sEtSKvq2UJ(-*cMt|Nvi#K|JY+xtu7y5vBn@6cFD}+S zJr~*<7ZG2<9dpL*iOZB!<#o?3SWR&^q{`Av@Zo-B#sMk^!l68GfpK*;kmT}0i@PVF z#v9c)?mNX2;Dl6u(68OGQx?Ds(^$W4^r!9a@s7{BSC82bT+;a3X4HeVcg>>x>UGpF zUcZK8WdeHU@Kp1$ovxA*wR&Zd&i!h4&nUO*C~O_?C7dzJT|o+s?}xjs#=B1zW1_M8 z{e#%twrYM7nfwI?-yO~ckMy$;rs^QVMPR)V9h_ee zcQ)&7Y-&PJM?@gZSb`?zgPvx@G03r)vtk#N_!0sLNQe+D#V-F!w`Z7XJc@ zl%4Rl#nVFPjf4NH_i5>pXc*=N3p^a_XV`Kv@=B-h^7O1HguI1|a4sveJ%lvf3C6w$ zayMWdk*P|0N38a$WO^{%+(zvEEBq^Moyg_oOp=q6@&>^5KzRXtN{taw=c3#a6ejK7 zo@c-TNh5lty$SSa@p6V{NgxVvso%p~4>gwyY5R?B9{o)x+Qmjg8aURGDti+NMFsBR2Rirsdp_s*65{&R8;Mu`NXf+UECI7tLxcB3b^*1^ z=6Xbh*;UwpSk8L#RKs5#j5UfimQD}hJ zs&NHnY|&Pegqv?I+tG1G-x+mud$nD&(cS(YIXR+E7|JUH7f;CvvbbB<#WjUdO>UX7 zl~VE=c1+Rc#I%@L!CXEJD`&Ts1{p&zwWQZtq${*k5&;Cc->0O21YGj^`+56QivpHX z4>no&DE>2y`aU=ENc79+k1`4Zr+0GxkM-X%&QA0UJ4JVC-|w%l%MhmXb?RcqCZ@bI z@{dH$D@l~%zfFlmi^-=A_2PdoB_DTDh+(DRS9xRYO?4r;a53Xmq~A55(O^0U|6A}R zpzMy}U+f#W##z`d@kThfizak$9klG_3DE#wk@5NPcwg1ea{If7Ry9;J#`$Lu81gx8 z)3)gpDkU6AH)M(5<@x;7@$8$Cl?O@!27}S!>E`xxa+v&2f*JW_!Y?i&gEvjJ$d33` z4XmRJ;z{OD8#ia5zhJfOlH4kA5sg;*%Em068mQh-S6PodxeOwB%V0BP7@ah~O(n}{ zvsJLmQ_h?0lc`=FKD0>hZ5X{77w=6U_zq828hd?1U3RzosVaTx%Q2n;)lGIQ>Bac+ zh~K$_RzgQx{NC#CA=Rn}C0geRKPkqzha(jnr-X;>5HUt`MDL*-`s;IuH-k+BztOx< z>Afuk>F)ma{^;b0UX&P+rM!9`4nSoHKl+_z>Ge!)kHuyX17@aC+Nbcmaho;K_gV(v zUUd1e^U1zJ>^G@-pzHmn1Y~n&pR)j;*!rUljpp+FvtJK!%3^0i74ow3OD^&9-X~y^ z5)m&`jsP3T#NGiK-6gd>C<2i6T+|*LvXgnQ7emhiX=dk=z1tlZ7CRR+_!{V;~!3q3iGQg;ahf$o1CV?{8W1RNnG$6uW>Y?|IkL>+oLFLgvQ zkmWKk&ipfHLfM)88%rgmHu8cuR1))aKF271%%SSn#GjGayXl#X`5RL!wfX)f$TB1s zQ9)~-q;mo1uHFtpTT&PgHEz3Hn@ZIeyj2E5 zVqi1@u3s)#?G;K~pA&7?)xY?wGHUaOvZ~wf;`Rp96|0q;3zJ;kA(1%@t zrxlv3Z{Sm?Pr5gS2=bN(y@taldR`EwKTrI))QO4O&n`)LO(Q&}C00oKA%^yZR)s@J zM1irIj*>3QZ<~@6GAd5P*KY3m1a-EY9HDbn5-5EqE zYC5te1N}@VtCcdgGfH^f2@fdIJnQmuMAYZJzYAvul}Tzhx<#v}Lp{O-Fb2*+b>Xpb zvFqI~rcsB=ZRv_jAOe!WTdlB)imcCIZPAL%GAK~4gqw+A`7zJ+%k ztbla)D8!q2H+g;Bv!J!NGs1SB^urnlNxC5*uiAgnb;@7`8eC8@*-b;BjQ#K%s-Xo| z-@r(Vt^YJs$N`mllxjsPQO`=ozkAj6i%j-VNyo!)6pT_zM=`M73!<&ZK*AGHX`%!!!)&C}${C0N{ z+{bA3yEE56dEB>$d{oI|6{MtZtU3RkxgqOwQ`V|gB(aEfVv`;OK#Q!nu#gqydz9v7 ze|a=lxr~C0PKTeV;AMUpNk%c1z9krGz>gr?LHtXguwIS{eq@d$b%-1$8x;Ait*!JH z0}U0ua7V#j2zAAwhjU8h?0^7ONxh98b>!Qma!*$sv&Q|gWuNJPFAcl1K{cvt2i)zc z^r+}D`R&y=h@pZf6~SyRM2m>x2~S&@>Fhx*4x=NvVQnB9zw7FFi)cSQye`*T!aQ(q ziX!P;%ie>K-J^3AC8prz%z0=Cu&ZA^yYKJu<@(79uo||5(A%%Wm;-#8>A&@RT3pWD_ErVg^ZtZg%XGwBs@NB7BPY&R_hCSE zrLVh!l(~|cj=|RhQa=+%D6q5_8@P4R7@_ct3QEy?r zJrNi`4I)$L>ko*%FvYxM9{#o>L+KMl9#!!x$bJhF9{SSqHs>ug`u(20jbp@z>{~a; zU9f6I_G+4t9jHp8V-7VfOJ0Nuu;jBmKrsErtdRe{{~%as&%PS^ujlhhr0$2Tl~ju5 z1!H!Vm{#5o-p*I>Cs%r&{Rjsu{wXM*ov-IL9j{*AR4}2mn<5O_%?D2MqVf`9c`r_z z*-8#kz%_g$Yha&0jaA(?xhl2%fa58IyBnwcs>@itrxRJ*yltN@l<}(NNm!ziqtC7V zQg~q2o(hqFJ#(&}&Az*y!i5K@wt@a1zEbY(asR)Q+YB4JYnAW+6qc^^wRZ2qCZ|=8 zN8%5U+x!oSXb(QNQ;JptVfmlrXMR7-!(u^#sepS2Hq{yv>{9`MZ~*=PD#(ZgxQVde z|4OF8|IV@eUws$=K72CxkcZVIf#{yfo zKSn}ugI^>1`aa78%1zJbU{kf1>&9OTuRDsK-s0o%N6zq>>CO9BbHbq3r80b zW$AtPd2TIsQHhYLq`;$7fIi0MPVy)L#Ryg{!`4;XPFvtTO<@{lWUHGiH+<}B`q~Ctyys&QEIl> zyy!Q#k1mz}QYo>N+s5gmhmcK*w_ei{6&A&Id7=m3K052m*G*OqWe|ezx!L@N+p+Nm zi1q+NSJR#ft?3D9Fiwr?Z8IXRjo;+iOTpUVDj^FSWmuV z)?2xO`=^@lxg1@a+v52K*;_}-?=_&Oqcvh?xxpAU!n z{``W=W`2SY#wTX7lsakiZ{CLclVIU)f-W{D&GMV7@{3nxLnp==VpG%qS=^$i^cOXM zvNTyWQ9zq4jLqP66`r4|qbaZ8akLxac#`7iT`VqBOMLpGsBT>=m+wPiMmvg#{BO(ZXVG^+5N%SNacGl249U ztqXO6kJ&i$5TX-YXW$_5V!a6&aoDD&NgI=7q1XsnDjJvcHk|syqiqYk=3-5y6nj;* zV{|JMUcJNDl|J?3}=Z4ue8rvu-}?uIVCr{frJx2lt4#q2GcFD|N8kY_;f>tvDd?3_~jZgcxwV&Z>~=mzS0qm6VZ_ z4)ZmEzq{_uz$ITFV~i) z=ZjFXX>LPBy4RC0o_?V{=Jv%5!?M?QBq<7R<)DZ6Wmfeb=Z9qs_J1<~p^OZA+}ktH zj2d5l_}9Qst7Sjt6H?%QCuo?j=a zX@)lF7cK8%ENMwOv?G>%mof(4ZK-u{r3R%G#k5B?+A#h-{l3HO%@d}q%L1aewPM4U zYe6svMf^^`_seVP3Qzn$%Mpfcg{Ya;1hHL83fJophZ(0yEBr26eqCE$SIx;G63jB- zW2bb2=(>n;M`FKn9%Ps}C=tD>?xI1$T)&j<;o_bqA6AWXG1oinJM$O!p2-Yt_~7&` zuhAz}6kkWlakU6INb`CQvpVrP2;omxgD))REDt2aht&6N;?i*r@FNd*$#0OQV&6iP zA6|)kq%utD3Q&z#vzT*zzY|F$s}e9yJaT@SACh^7ihRzdPVzCqy>3`A<}71j6r_>K z$`E2sH!9$lKcn<+Qy!IM|HLpqvdZClSw2;vnjrQeKrDkv->po8QZBseFDtuJ*jc1} z>ec%up9=#!vC(oPrm{%XH|skaA7Yvp90|yeC@;2?T|d&cR%l1uivI|_LGn_3)tb{0@&%CWa6nP=xx2+-P!K{nbNP3rpoX-c`xMN+%JEN z!u=s50=OS}<9zl@Qg_|#He5_4 zy_X+Z=OxF7?eef$AUpowJHGeT_?$>2op^v)M1ws0jK*~BgrK0RF(5jA_*gt%7x_6h z$A@AEr0|X_YmisX(YiOgUS5KTR}f>ZEy~Z4uHskUCk1gGwGEreL-H>lobEe2eTZ?y z!azvqzalx+2seJI05!*_egQ|GtUPif8vgxKj~1Ot2qI9^txSzNgo0AI>S?;w&4Z1WIUM&%SAjYW_J))Ep z#^djY_41_5rAXnoz5Hk(3#-c9G;A~w56$BXg$akI;=j}*1FHvKbBc)L4+j`}voIYOd{DwI%f`=pJ@yo@NsJ@J-R7tsu z%dD;qhnu!9XuXPz1~dj~$W{^I+D zk`{>v1HjG31yI?qc3T1kRb9a(qq4bOdZ^Y@pj$hFtWKbgx zng=<)@ZXNsMA4-7>`(S0?F>h1UEaN_x3VZ?8Dz$$8FAy<4;1siF)6=VoDY3^5F#@R zFxUW@pKq==8L@NZ-)5oTk8uf6KdzZ79Zrd{X(ISHM?u;Bnlt>e;UKZqf52tL<{<^iYcd&<@>X$S4`lV8^&;4hqR!d3Pl8pbK zi{7310LKK;|A#8^4K2^wcJ7URa|QoVp7*&1I4tn^f2>FU|7!U2EN=|MtAK z)uSa8i)NJ)+kk4R(U6M}f-=m!pX&9TnPG6TX7dKlpwP$Hm!jkIn}EMIT$~)W%PpR9 zK$TfXclRt-!|x5VUHYSbg*nPa))qjZ_)Nit`$6@Ir+dX;T346k#nFIv z{rTp_F?(y96qDbd;o(TY3od;2g1e?Z`TrLF>YY+F3>!x!k)ypY9QD6Ki}h9u7={Wz<}oM_f?0+qJ;pk zIQ}ypkZ8V$C$xO=MOsePT5`cUMg?if{r_~i3kmVSB9J8x=e(Q0)!UIPI$ZL7n!f27 zjGiE+?J3vXS9!`mO!T{P*2lfb13^!_{fZjc3)=ENIaZ0w|vk+ zGC=(s26)IVSkJ*34C0k#p7+z%NgNxBqtM;7^&ZBg8fun@G0>9-*N>H&7iJ;=a0e7w zF33Yi?nF>K-mf2e++7`<3YSk3mo+(iJn_Ej@Vx)(WFBxQnrS8*c@Litj4k+ZaVA9S+w0zg;wN+oAfX^&8tzzYFbGa+F|bPRc(^EJmphNwmN zYf?`SU{69w1L?kl#1%re|LYQ1w$KG&$@#0M;PVy!KNzOy0&rRS4-c;^Ue!QPS1&%l zi=YskaeXkNCYXbjy9s{s`sFDW}f~=-WEx8(-eE;qB_o>TH z9ohm0j=fhezYJ8m01cA~vB(1mJ~^pX$TzQ9Y9Anjqrm9iB?O)V(3$o~?whIc1u0U&}JZwNb#2e}tfmo%cPiYgZuLZp`= zuBoXFn;1mE2neW3fJD18xmR_Nnv_1%y>Sp#}!X)*JSa!fL2!tRy z3$E+WC5J9+p|}`#fKM8=!a)HJm_m^t_a!qwk7pQS5#}K%GQdn7&JsCv1sw4X_IeSY z$-Pj)uzqcFL=R0FctVicA1xg<7fm~YG`+?Al5j-8egcoXe}eTDEvTUh0b>~aa~Q|F z>OqCfl-Im0b1dZ>1|u`0Y}SbBk}z~(C6#|5lhV)M<2GZv29|Fuis2pfzT73fuZ45~ z;BKsV%E`EM!tL*EiQ8}u#J-I9F6TZXawCa@wEE#(>6~`uv_1Yfmv@ZLAT@Z;6}}H; z$L9yQUaK%bKvjcrRWLfB!mF97iziSJBKTu-ws|w^DTQ#FMC#$?UQt+wtLvNVJ7?#Uf3a@_m)2%gR!JJtF(pkmkK0uslccZ|EUY2bX}7@s zV>?JbX#J93IRurm#9@=(sAe?eyC0ZclrEiPO8mYpF?}3lHKfe(<9pQL=Hlh2pO>a@ z3R6;o94g)%xn6vj4F+2JIX>mVkda?40;nCL^Xh0->_TTg@j)vHc!*VdD#oDommOGq_f2kAm`OOKMhqK^% zv^>Z|ap3c_}t-ZS8pw1xY zWDbi5PO=VaLerU9cHgY)lR>YA6C~vW>VZG-* zH>-@kU-xEu_Z)E^;tb_`Hr1@hiBCJvjl3Dqz^=I5t!(9%?aFwSjQXDYN#Q~asoifpsdbNN@Uy_+7 zou5>%y469ekQ0yg?>3?D4n8UufnSgf(g5{=GYHGSY`aCAdk2llJv0EO#9d(qe)T;(( zI095E!Lz+*Yz=LsudjS!S`eg_Y-(< zl^+~bcHamt+NYu(9b>_dir06qIQt6J;?9!o4cm88voXbvh~vDvaKt5iwOR>HA-9hM z_>gokw}f&m=b}|}^}vzwdW}gR1uh`C!vY#Y25P~pR8e3NhN3Uw)B^=WzY4UN=0*96q|RG>+&Jnlg}6`8FH*WBr~#INv_$rFCunh5O4 zO$r+|K60?cum1W&u<8TTDmjYc>d&;teLXuu5L!fd=N$N% zeBITqAQ58DNDM0^*EiuhAj5!1fq5YMZrqlIch{?ob2FlYfGm0s^jqLPu7UjV^BYk> z)AKCd$U+x^n>ri`8pD?=CF6B|%yN*nk&$UgDC&)ZF5 zO$5>p8?_TBquW0N#+$n@;DPW++ylLUS=WIb;TWJkE^q~>=PUeQu|3S`=vf|wJVb`g zB;3AbCJKr0v7^SIMy8{vRe+fDL4FWpqZX1~d!7{FaI;o-QJF=#q&&-IS(-uGOQ+~j zEc-TO{eSFTp#B!2o>QleM1agr!>LE{&OI^ft!DGhgt)O&0MkS4fRymLvnQ8Y&oks+ z`NQf1(5G5VB>sBk_^M~EZ$x~Wp$Tq-?%OO27f&R@)(E-z^qYVp-Sq1F!d_N0W!EXih8jEFB_yCMWAuMa7TC10 zfXB#+-`FP5$(6Yuv@q^A1=*0dNpP!9up>jOShm zeEOIDAu|DFdmb#GKm8x%qxgS4+4Ev7l#ZRtwk=P8bO)t$*c+fIC(z3>>#ICd<+Zn& z)0UzTc|-=5&Ryby2tZdXCK=6242%p+<4b+>K*nMX4Hbn2qa8dZRg!W30<5>sZc0xm@ae{=8!5 z%RGSukTp^o65-SGb335Fnp+JlcDkf`GQP!7xc0}ro`(RamW=(8e@Pi;T}-jDbZ4ic z9mW%}jGM<vVae7&0$v&n9&DT-7fSzLOOLcP` z93D>(U1f1Ecq>xn$d(o@gAJdyEY9B@Ag@R?oGRw-sV9(Jd()(0HprlBENmm8ZlOP7r>;SIW z4Ix`JzZZsL2?XO?mN#cb_g2=~f(lklVzDU#phLyKbj-<#YI}Vih>-bi>rOJGyYO4Y zDy*B4j@dY43My6So0P~`QYfdtO$=Ic1!EvY3j$>Ij1}TV`zuf*a}rT$TlYK`NAQCN z79|D}Nb&Os8tyz+Hb;>%73n4Zozqe?i>w-c2R%?mYwHs>B(KxV1Ux518$*1a4rhC) zMIypHZUX>=C~H%gS?Lu;Ta12l;{$p0skO!*#XVG677KU#g;py&7O1O6j@-rnpsi`a zn}mLY@%i(zZtaC&>_eBmRDt?c|C~RQncDsjsj9P{S0b%J60Woi6;3nJVE1@OZaDXd zR`))g{4MDQd=k!oq%6Zv*wlcMm01tY_)nCqKSsT$=m+>w<7n1~RgAy&YrEco2cvUu z)#Q!7Zh_e;qV;*=6H0D_8Q6CM5k7jnTISX>HaDX~DheNJFX9)zgK1>j6jYa8LNcV^ z#l>ztLqBHU%65`6i{Iw3&IGaSWPOlFg!j#|}9$ zf(tgV%0bKQy*UFrc08Itm_olJ^K@k`Rw~kewGtJujQtVWCuV!jdE6+P=|M$f$FOF?(1zFlVh z;-*uzU0qxhd|S@nis)bu%Y!h>cZ$;};7sy}wd6DYC`aEb2$l>U^~==s8gXzA?LQnN6dKGzrCRc&oL28J?c9QaPe zkWzJ;yP8GWi7mUUWZP_43iiv(_RxeHYobj-%l1Z=PdY4BLFDIJ7&wx-xZEbo z=H%B&zE`Zhr{O6H4TXc>Btas1t6cU9#f2!n0_A|`Vp+fBMSXAf`2(7QNN!AwXiU#j z{u0j<>~Y!aW{#)3Bgn0_m?EnGJy(^X0l5!Apkvwc8$s_EASVGJPQihNNAWljID(M+{t4+tm*lbK&2MwXmwt)CUFRB>fhgW>s6&No(Uh)&(K1c$2 zTcZ0(2EGF^%Ag^LJ~6{fEXsl*(8JDa@)f(7rzBHc3Zykgu_V2Ea+}Jz5}o9bN1D(r z2loQB%m%q?egJ%}g8?180S6w-#)-R8N{T&+k+hLnKMpP| zMw$C=aEQWy8ZO~CNam{0=bO$x44x&1EgNTSK!s+L5&|~40&!qTS_Wf|PRig56-n0s zFY@ax?EU<_cT=Rf%L2{XJ9c{mQg%kv#6bQu&OlU<(?pdSa-Y6Ttr}^(m@(+w=^-5K znTCT;fek|Ck0DZF{rJq6nL_w7Wx*Ic!`f|p9RTGk>w z8TaYeXU8P%^X*X+#{H3MoYu8Qv@-_b%8q+UM%BNFWY;^EAsU?~{NXqFI$~#eoD+`E z?+LtLhR@Ic+>W$g1iD!-mu?}6>5C0Rb@T|5xu_RdlhBqlaGiN%Rrj^*3p%ok*g+G3 z`2nRu7CauesT3%rWTb5xq^P9zk=dlOxrvxR($A>H&-tLP=>s>rJXLHy{%BTG!BsPc z6991H@(ko*bC9_Hh_p+gi@rh8OP5t4Kxp<0 z1j2Q9blR0*TiwJW4AWon-96FB>Q_vZhes8ii#S_#tGM1|)`3FLHu`KqOpQ z3MG&vQvn7g(HZIO3lFu7Sj<zPll;S6C3XD-?3?^#xI|JsG41GK99D(~WlUK*zfQ zqjMX!?=blR3Q>szptHK!^9^~+oUVfebbCN8d!H-fiuD045H$H3XtOfuyq+2tDz$`2 zPz&ida-es=fb{OhNj$h0%awkRFSH?F9Bd{<3HyPP;A}pCT7n@oxG>)uWT{yu@$N4? z>{S3!sY>88i`dWhs>Mb9kgC?V)7+fwaK$uS#kI$TJRMreiGU+Orv5aUpoj^j!jt8d zI`vyl5vp~YY5zNyH~6-2j%OZw%OKd3^;neF#gq9%+9D;wS6XMfF&h#&v*H3aD0c7~ z^>#~D_uc~-llbg1iZZ{V`ju!rZHx)+c`})+s+qU-lk>MaW4{!aD3^5<^5lowY3!x0 z!vJg%3@`{rbm-|H^{Walf` zT3vc->v*BVIbtBk(6_a6kGh~(tX4&}c!}1TZDMfTdepQ{l>J6G_3Iznf})8!{7WJr zvbO;Qu%aJaOPxDZIu{n$j4s9u45!(*B_%b+S@p%jnx=RyQW_rCmK#0R<%>ABi4k~mKHc|Ww7RQ$RNE;r!G zT6t(ILUu2Ln4vb=}fIEGaIHkVMjSA`NGFqo!%6tpU zr}NA=ASe25hPR-ZU_@nF59`7qvV{eQP0c6Ar`@Te_oA14s`d^?PI+t$_L=;NgAK zBd56avkiR7^~o`jt+4b1^Q3q`^E?N>WM#dgO6z)3vi0R98&OZiet<~usZs`25e>7ueKf)UyTy`Q^yXoUu>cNe0E8etyi)8Q?bY5=YIFFhFu(n z**$56>J+D~LLwl;COn|hg+kI+l;IquZ9f`hB+)ULE1#9}9dtdU()Q=~_u7`)QO0d$ z(x=LgIuu4EUkhhfVTD^;m&y@lOBu2{)eL@(DUKpOvf_yvewh-I&e+aS-l@|wmqKsgW4j(}z}C3Tb4cBAl;0vXQ&c1V!N53i8Ukb70f zCDek~^mhK(qc7I8Of7v%k3>jHREQ&GcT@MxRH3Q2GxVH_!(9<)b3ZVuNkP!|2i}rX zrFt+9g2Zc+z?te*s*1978PR}vgU^E5UrUo?#bU3OVuSSY;aG?%e0^T&So@Y1=Em&R zpC&H659*c3S)_-hMGihjDg6G)$5**SRG*^bM2(KuGz4>y8@`}Wx?g}*Fpf+=;Om|) zu``2T`RGpyktJ|2zoA`7GgL)qbg!+| z?_VTkVkiyw?fA6xYAHxfLJRhE+jmX(#*2zL@UsOw?>N6jgxhvFm>P%TLinwRVSO}E z8D?SBdn5W-6J@_h6S4fuDU1L<*{12d^8DVUcR!eV8&+@Q*zLFPVAF@mtWhBNdcZP$fNa+frhJLD<5n>I}MKiO)*) zk={L5*^#x>?;ueV=w{Pe6T=P3eXVz9XX0R9{IcZbqAvbrw*x85tK7wk=oCDB2@AxQ zfw_OU0MXvjJgCZ!p#!IWqtH-+F?GZRJTQVFR+dU{@2Oo>0`!J4$O{25(tyga3iFK} zt8tQ;C`8;kkFc7by6#%B(syGGH|H@p=8gxOWr7XW+7xLJT&~CUo*X|F-5zLG1nVBI z)MM5sR~%{|U@y3zrg$p9598r*ts=F{BmHOZ`0Ip zO+rZOv4N`=E461NNpT^#3mZL5#!fEn_C^y=Jd}am=`3h{cqHwqBXONPQ?ZF2Ztch5 z&_Hed;8F;l#m)8_%Q`W}xiguIMGa@)qL>q;X~tdF7;Kl1b2XU_1+gz~c`2LU{#ZX& zYglqyLGe63zVpl?p*edfF3uL5(AS%Dn27N(#I_T3Qdqitgr4YK-?zLsC4zmIe7AsL zXwovbAi+W89v@A#Cs?TNe!FIQZwz&`TT35w3Lp}{0F*#LL{UOC|Ko5eEcGIyt{7~N&{pVe`QC`9PE)`J4+u_gOMI#a&s!|{TP{izF;UiIZdt$yly z++f>Xp*Iw^^P!<%2S{XHRmiDeaNL8vT`S)p> z`}T&S^M`0dGfT#H7n;Wh)*1VT2mYj|F|jzLpMHQJJd=6-N(u^V5i zw&j=4&N?ocMz9@f-fY1tM#TR*SSP+tTO|{gmsUKOPTLHyXynJx$hRvJ3I?!^n7CCL)^ye z4Re)~e}i;hYkxsHT!bmJ7K}rN-t4+!6)u9sG20~-m)|Z)t)DP761@FrWWTuG8&p%b zL|Pdx4PHrbRC;SH^&*Dki8&hcK^a1)R0K^g8PliE%V$@-vwB^B(a&!f-hoPzno6^l zXdwIL>Q_p^$^-)Sgy_@)j~c^Wlyvyn^Z>r=uB1wk*@S<6u>-nsqdJ#I)^2V!8712Z z{=(aPoh%vBzhQ3AmUd-!+$9EIS%~prjf*C^OSa*l8H46Rg(;TV0A(OtYttV1=;+xp*K*GY^^1tDSFr8nrg^FC}twYF7I;F55{31&Kt$j z-f^_@=SFrpweJ3q0@GjL4L%qU5>j$lRTOgBtgNm&u-!A!qsSLgZQ2V(X;W@iLnq!6 zeq_YZ_+3sfni6!~pROmqV#qm0A1FwoOGwERp@=S`%WX-AzQ`-ftwSzD--aCe12+6t zMw)ClDMVD%b|ZxGab7VV{b&?rin=~r(|RR#wfp#&|F)c4GTay?Wq-{4TkfaT41c3t zkIT*^=vE*)GAbb~**H?kGNqob2a_4kf=dJa{x;p8YC&)E`<7ek@4Um|KqbvI=hhX? z3+;v>i}3MSb6L77a(8U?+)kUdRvy9AE3l>W)xk0U(twmjVnxFG2CsNJ-=C@5Ne49j8tWJ{JELqOIWZ z0X4Q1KCpe%wyPFvsC)ZY%`xq#C*oE|BvE#vvj#;&ECs?%@5pig1Zu9!$NKu%^V$Am zU(fr_!*X}b0LTY#5 zd=Ia%7xNkOpt%Tus)%P)^Xm_AhJ5z+*>#Me<`s31>O%*6?t`(P@KQT91PLWC$u=6- z5bu1m5YAQd5we!-5!sDbQ+CP~!8Bj#A-(CD5SXEMZ;{cGHYS;I3a7SIVL-|C377PV zt8gY^@KvjP7%%4LX6EUk&O$hY!O7;accT*IK{ccBp=a`>KhX!{5R4-$-?p%-%x9d? z31%+zBCbcDSa6RA?l7m45)cSRxxq%K_7C6PL_|QPUG1JnmewGBG(OMZsj~EV0um_V zNHy8g*%uog@AF7to9y8ryuRpKGPawS#4oPde}5X;zr~8bwyKlM-XqL9LrN_Hy-fl4GHO<>yEl|e6wL`l)YyLR|bcFzjo$+1p`(pb!rvRzzT4o%KnE`qWhMM=8N9zRa1O zS&Vh6gju1XxmG-p>N}liiUuV~#Ov*152mQOI<>G|LUyG_(g;0BX z!xK@On#?pxq*F0f0)5^L_0VYABvnD4G0<1>H@aedo4&20Hw^| z7oGZ>Ei1CkCWFB0_`-KyealktUA5c!39bza+-(CY7mFJHcl=Bq_vHGsdlq|Yf6oUX zj8XgWx{S}>a>Rp%3*U^g4uoNvlIZeyDUZjP#Q-HvrVPIx+s*I-|TFV=AG=M;Bz1-1@b z{W`3Xp$U7fe)%mQ)5SO?McqZ|sJ}vY|8j;V7*Q3-hlD5?BTNhfYH=}wtBO|C9(fGX zkT_`afxEQ~Bc4@FI+}O?4AALVSt~#3U1+h9<535RN6_j$iq=k~YMC5M^p7gTitq?U zGf-s|x5ETtfMR3zwkP6Tgdot~zhK2@n!gMgT;^~NaG~8ckarSPBG>M*Q4P5IK+2$h z*8u>S2-%)#{^w8KGS7PhpZ_b&>1C)R7WUZVFH~Ksr>k+i0y&I__`idc?a`smfBcJ4 zWv9tY04k3*1z0H^m;-9p)~<*YftmH*kO@)BRGp%e0SKgo3gO%8JBTj#(jIf3 z4#1BmyL6hfHoI1dW;5_^)1Qp0%sG*orrTb8q7{_&ypLG)1gMeY9rPr#r<1tR4OPrY z`HJM-WZHq09$-D>{qlKFKqBV|rW( zfa#gB&bC9$wCxKgFG|1wA-ntdUc2JrMg*^j(v!@J2u1SksCe;&Lv6iLfs^6Z&TdU3lT6gqe5`hv{{vX2RbH%EL)}q#?oaqSw{cDOAW8LO#OJC|>k9h}$5$aLakh%NQoGAuNa(Xq z?gX$x<7cO~EV?e4uxb>E;EfF_bb)7R2? zXP_D&9iNn^f63wfB2b+78Y{lnlXJ+n!6$Y&97vpsR(>ukbtJN|S_?CT){W(-txts- zJ|KnJl6^3_|E&Sz081yjXzu`{UE~Hcr zj+);eKZ;d}>-NpXh453XWTK{%&`T4_cFWI6J?yT@o<+~g%x;Dj%rk71|_l_-_lg-cc()_SpDJW@xS@$AmesPYiUy7pYFYIeS-CxqqpSeXMH> z3|1__;?;{8xeSkJqDP4rV90bMw?iz?TMb#vY4_+z{p53%HcP)MME*uYK?&%llPs_T_i8Ymz>deS5dIX(mDY4DiEk?(iidNRR&(ZX@<&B)zB)yF!WQ%E5Yip5#hx{8w9@U5Si%IY3Qg%_QZy=&bW1l zcIW~qNrO2HZ8J@U^1g&ETr7u?eylRY>6+F&lse^+#QaLU6!RwBPnpc0FeDtg>}=hb zu(V@LK2r9LiRh%li~<~yAY^zh5tQBw?d$*6mg6yzjIBSu2lt;cSbA;LvZ-gDhHH6C zj{^0qoA^zxrD9lLMsyEt% zy2u51vM(VFZ;SD^4mqDB)caO6J(F>56F8doMG!!3zkBl}dK15_&@Bv44;0_{OZQisb}vB&F*||1@1YWZF1Cy;3+B)`(MwPX zK15A`Z2!tHg#oC~$((;*(ZlpPMJNvjFzr6?^~^m%KK*Zj3TExMN!+*PsDjwe@)#JO zfeCDA(Q=_P3PI~Hu)%Vv1f24^=Z`Zmy9bxnO(HH8D$UZxVVwVV7OuZ-Mz&sAa z5oCc9;SP&64CHPu*oCEyg)PDVS5bMSAl7}?oJY{U zaC4KxwJ4w+HSy!eY*L5-1%05@RciCFcJSNEce5GPL-D|x{M+2r;T#`lCIl>?*$Tv{ zpi>e&uBftbybsx#jxv1A)Sap)gZqxJk)=S_lxo}PY+12&>0#XwHPYjJ zb-X~yLWQ4Nk|o4#vQp$}J@p5+V+iV~GWRg;NTJ!f_b2hXce4d?X&`QMJ&w6sz3;pz z27#gyT`NYFn^jrM*2;v5Z%9^Ff~q2Z-N?KjIJQ8mIyG^7ztkzCeQZphbIgol`?6yk zWpEAF7I}3g-=3k9@YAO_zj|7>lN+FIke}P;M0#(bKFjjGN#T!O82Rcrq55W=b1NT_ zCEQP*wuO2dVJRWAcIzo^&Q*iKnEitR{Fw&Z@G@&7EblhiiXYDO!~2I_3LelLSI+Qh zQp%0Y(fLff>%pC;;)WiR4RONW zBj#kByJF^=(o1@BGCwG{$lU&CxvmO$XS^^W7J?ZGDoVE75lyhf(%WZ>n+&sbsaF4C zc|G^4Bcyn5z6ECuDU-aAA|Ro70Z%-RickZwF$NtM&Ur8Nj_!DTQ|j`44;xV zfkQaWt#c;HWn?&pNI^ZO>k{@1bT5ph(8+Lum9}_zja8^dsZ46NgGbJG^QiegOohXe z^)yc^V#E|*-(EHNOAp(dJC`n~>&2J95r<=9_PIYj)jHde)9ChtFYE$ z*&-x9w)`?<*Vvu`m}2@UDCvnb7@=8PD4l%~!w)C2-y*gMkv+1ewraH^#1@d@{B-## zl(!DuDqm-Qi?G6r_mJiu9DA*suuk~$o^`t`mFy;}e=97K&IfTMoa3lk?S`xmoe;j+ z?);Zs#aONdw}I6{-KPY{l0yCJqh2p?nk>l6zRegIw^BPXK2_`+WbeE6ctl&=e8gGp z>C1t_LNMlx+z?4588h0|ohTb;5-gHqI58rw>g_AK?3c=1k&V@$2^6Iu9l>%pQ-g_1 zRE!_~P)*0-?4mtYt_9*Db+`d0lGbuh0&h8r!6T8~RXQ#Hro0^SuXHss3rCBae* zCFw{n7O)uG^M|-3@ahYT7Wn;&HMkw^z2x2-sX0t?b2FeC%8BlrZsyQ=ZN;=J8IHfb zqGJeE5TW#w>?8h|Pa(_L`W1VERKRGTW64B6WFqzEBYY%!BD{(MR*GkQ?gxV;E8Fvt zF=UZ%8r0&{O!5aZIjMfZ0#1PxmN&H&la;`oW=FWUbfPQ74kHBgQ07nCOn&nX8w;77 zR$^MX7#=to(ejbb%POFfA`5gTyuN-3GJ91Q^76BTstY{93Bvu@OrW}dXuI3N;u^Wo zn_>hD9^0BfmlNt!_k7o0&Q>mtr_y3V*cWRI)5DXgR+470JECL@+RHEBz;4x2+HR7XiR z(6W6Uwf&iYs>2`lJZ-6%dyO{P6x8Ux6T&sTVVx`Ndv8x|=rKbWJY8R`iIo6u3G7)| zs9+p*oFRDC{<|_?%JV*y$9!3xi$!om6Ah%r#~;Z59Rw=yuhQahM#nfP-kumg6s!69 zv?-j?Sa~zJ01aq7=Ks9{1ex&ucf=XU{{IUTWPzXw=fjE+HIBg=W5Xtv{Y0W>v!P5= z3vPsb^7TdY?+J@pc~H`if{NTqwJ(5V^f~|*^m$Upz7X7`TAccLSzewJ-9YC%!qjv% z_$R~Y3H)gFK)*$gc-570pBL_V2w%+R(aAWAn-pd~%K|EXA*j4)mp33sO!lQ~xl-)P zJTk{Xn|Y!u{5{jUh|XAM3QG~Z%MCO4*Myw(2QTU3xIjRN+^Rx2p9h4x^Ua9ATEwnY45nvQg6deI=@Lhb&} zx@^zsF7VS+PCQjQ$+yr6FssAYorcRhxTXd_mhdWO*Fk$p8&jtbnV%|~mlT$F>K}G~ zGGgh<&wgjnRnE2P-QNl6@L@ocr|&@BoYRQaJPV9_Sqr$%pzX4U`e^X z?mb>U_0ktoviZ57=qr)XoT2f%rknes_>X2c%X;62+VUsfV)xa$Sg1R1Z^jK+aZYIy zy%}>*-j_ZKt;bMa2*mJ~Y@LC&)Z9siiJY&imWoXrN@4Uj&Qw&kUiGfawbkT27Z#Ol zm}*r@VaP1yM|mvTbJ+T|*>d8SVnWI~V!M&#A4Z~&DyZtZ`(CymS=vP2OmF$L)>>H? zvf3|fd|vIN#s%qAW@lfL>P7~|$!EI`X>OMYVC##Vow8xuPvkm=EV(~cjvbfF)|`41mb>N1-H>Qz2Z4%0ScmKY}Af(PN{u7gx!>~xXnrBXj zlZ|5HDEqP|+P>a@rrpS1+(XAPv7q}Org6mIDvf@>Un|)vWp)Ou&W@KQftwt-n#o5U zhuZRBgZu!-+ea7j%ugD+Ot#?QRpLr+>dzY%>TEDY1+%36ZwDVQubwV~wXN;X4s+fm z>Be-pOuDR;OAR4JE#wR}7_Zhf-|joc7pw;P-SS>yi?z@>>$`X?-y1g9o5Zs;-*~8= z=xxm`wcy8Mtk17B;;C{7Jnt)qYzqT zQ`^t1jDLD~x|e!7=qw4(#4dLBW!swiGHr0u*DE&OgQ+{g(bqnPA>_0nME_P-)itx< zW8*5#ZFXk@J6Jx%=X0EnyufI}5Uw~$)o@HWd61kKcX^0-ra>!>W}X}7g@hoQIF6FG?Jq>dGWw|)%2pEaVG2A%sx?D`U`DP%%gWB6kk`9}e8^ATyUMj| z*gR|d2ezX&@4-K8+J6Z+OX)WxxGn>AWa9qe0-Eec!6k{*MKCAl7s{O4;pSS?ZNDc* z4MXZ$qlfv2?)%luY)U-maeq`?hWRR+FOC7S6VBm#%-#^Qk-zDH6~sIIr278kNu>|E zXj$^FkCkCoa7Ay|y$eK0kF^$>yXrVwWS|Rb$1Ufx-EVp>>~!AcU>Oh ze)N3Ay*=x5+^$A(v(qtCabHdepAE?(^)CGyBn_k)`2?@-4gxu)nG+f?O!UOi?|Fp} zX*$z{t&N7Na1Sz~(6>`xJ|h=7M9qV(q9Z$)<{_w$emD5NCwk?U}P`AHD=? z)4-hm>EW-13lp~*>h@c;<%o^H z0oSt`#J34DS7$Gb%ywwJQZY;*x><+*b7mbC;)q5RC#=zsjr{L^8N9~?HJr(F=L!Rq z%``4D?Qu9UOotE&7KH<<(^8icxhXxn389Y&^n~(#ScG_o9o?sTD0bKb8ftXiB0)AA zAt{?2f^qpe8I#>nh}d8_XlGx^4irzhZJoT>({#Fr#kE?*keg(DnX0)6j`?z%(O@T1 zs?C?^jPrd=?!zTwrcJ@x`oNQU=7o(E;NX{7uWm3|{2q9eLcdjc@ipWzrICIVRF+Z9 zaXsPhuJtP{U40nP&qal0fQTLF?_ltfqpbh*!^r?`gH(q1{xxJ zoI(M`+X^=dpei04cA+p+*_o`1yYemA?X$DQ^Ywfe`%OaG7xLv)RP-q%JZY5erSaPg zd(R*;6eJTL%yq;RG9eG~p!L(?XVtdEG!|i)t;^Rs45t~aj#D>Dk!{pq_j|wO_V3(B z{6h%w{#S{XsYKKVmJg>0H}~Y3l!LYBGrW?){#^RY{zp>QLoSac8=VpprF`IrGG9Nb zctaOKKbp*$;HxBBwN*rXkEh~_cKxQO3wcu;C(OSU4UCoKZ^;Lf8)0>EjLl||0{aV7 zwD6pp3ZBb4^Lj(ROE);Ph*w_0#y$&=*Gu9VeXv%bDb5d^!tM1;v0)aFj z#@OfWzmfnT|NJj)Cy;;sFCZJpZvUx=r5$n$!+sbX8PiO%5!pqq$ zxji$`$%iwLG?jnHo?%Z+9H2)5*n@K5kL;% z5JR-qdw%CP(mUFb;$om>eZZv8Z+$kO`EC^qtR9ZrAjW5qr+v z-eM{s*T5oF>27gORTmEUl=&g=3{||W3yd++GBa_MscjV)5SETlA+1G4FgqC&ttkRp zt|T5+7!8d9E-D5o2T~$@_-^E~?G;Evm(7l7U=9L8^&wW3?ueZPbwhqa;KxiQ3b)H8 zr{hvV7Q2vS6cKT<)q~N^B?u6wvzn`xwoSynkM3ogw9l0>2c}5#S-?s0b3W zAI+<2JAM-AolY?b%!S+&Qlv$-ktse9k0C%jH4+*R+!7olSimeEiJt8iC^M6UwBWQu z3Peh1WkOKtT;N+%Y5Z5yzqUJ*WR-x^{QdRDdJ+uCOoh;_6$GM%G-O$lk|dhIE6^uu zb;H^kR`fd@H+s_(UYrF1xLLd7_$v$lDaLcbstwwccHRoq~T8z z&!!kYLW<+pU_;Nf_jJiinHq=n`>wZ#k^P0?ARIr3>}5(y`jz)hDN{Zl5wD7DglY#L z@5Xm(qRpNG3~(IA)d0;_KZ);vR@7c&qVOV_fS=Q6y)(4%gva*mJ@{~i#6aADpP>Wr zO45JC3O4yS{9C~-qr0)C{iRuE-vpjCxu##aI|W_dCOC?VAK3JV>#bLQr1#e>5S5_} ze)D>3A?$3c`jwmON^mlu#MDIjItT(rNM@Z%o5zkt(SnUz?N0Pp*&x=0k)Pu2*L>x~ zrUU7(32`)LPJFzHX=yH#r7{&VlCq*p4jTshB0WT~7nanym>*<>a?_|5BL{M(;*NEL zscr+Pc`>q@)ur{`rWY4#TFoTThw*v4(ut5O?ZU%1 zdc3GG^JPQoH?;<;VucyGB#(RpnK&aTD1P=Q! zY*3<|w?IJnj{5_X*`MNvFj<#@c(W=+9bo}WYSZyy{%6aKr3WG{cpB8*z?njmR% z@Oab*y0`J{;;93Uqicvt#If<&GPM-iaSWq40S5__%adC>o?8!Q0}lFQ!WiT@#0gTb z$OY8I=?44p?zeagYSY{vWSqw3`e3$l;KCE*cIYN#Z9~~6^hA!32^*Rn$O+Nk|CfF% zu0uSW$KxxrxV$1q0!F%Sx3!D0z%qeqB{_d1b@5JIE22tr`%l?W$(kg)L{v|4-10&m z%{@Dr$N+ZUo}{Q<4$^2TO|R0RN4FhJIq5@(i44D;DQ2ZY^q=0HEa#&L2#GWEYQ`$R z(AnhL%bjR{Flkp|3@1p{(RU?FttPIH!apf{GDKjt`ng2Jtx~t8!OlV+Yv9j!5_S+( zNGUEDg9jMsDhMZhtewW4!(+b>FjWPo(a5;g&T0Li{@F+Gt{Y;R=_|9j2m><1s}BZ| z`cgHANw+5dk^_f@n??R5;&2yyf(xZCF;C7UBsbn$z!}{`9m2W~)YwA1NpV|wSn0SR zEldb`B@%A2zskfa))*nIrTuMf! zyc|()Fc$E{s$nP4HJo8@wG`;d-jg5tJ|DwgdjwDrTK%gYQC#c{*Lp^;K?a}q^l=P<-1hWl+Q?P z;Lq5IfXI}EwddfK+?BU*q+zrAnaw=9Y5YFlF#2rF+?9$Fj1hjca&lWnsc_+nN0!25+Yi zA(!QUS1{myO8^hCVo-W6Z82s!E!SsV-i3(0Ih~XK_*NNB#h4U}KjDc?wb%omLEvnh z@*F$CE!iU`s%5}tS1;{6Av1AHEtkc_(v{O%n)o^Wo?s^%3kdBI;#tx&C>B-6>FF-d zqNu|76}L+7EW#mpT~0M|gL_KL69bAgcS4X7P9b5WR#UQCLCq4X=SY818kLa)qQp&I z8Q3l^yV?>Djf*vWu!u}qQsLMfB-=EgQrkS=SB#7D-E)H_X2 z@j?%+4ons_OTwu3%fy&1<&LVyGK}}JJQWv@>ScuC`!g9AO^@jM_bYa@o)2c@YEhWT zkfHa|81EBFna%1-<$DU)eKq$Z@nRF0%2--UQ-|a;D7x_`xFw%?KJExp+4=`$3lLK1 zPnuaM_NQ~8dq$(}($O@N(Mfp`ooSs;mH{R{~n9SP4l|az{ z0NTmHfId$4|Ae!FG~+xynwR*kHULTV1ybM_-~qys1d1q_m4k91fk35dqTFp44%N=T zA7GPTeJ+<=d|;~mUo`^pl&j*P0C|Loo489fFY6tcO~9hL-arT12B8b-o62iD2RDps zCE)9vL;VLz@@S0FJ;<5s zb`Wq&5IK1`uPz(_ddwX*sQ>r>f2Mr7aqR|_@?7EKe-&X?F@WIzpHR{o;SdWvh7R(2 z`eW)kBL@Y0xWJf*^p?kx2*yIDUbmm1BdlCtb+7#baM^3%r(fh>&U^B8p;*(^jRHv? zcv~+#sCFbpTA)*Sx4St6R8`t@NxLi!eJE%XLD0~Mzb7wRHYMmRLuObW_{SIEHHQ90 zQ{QRPcE1V#{*e!=N*4b+it>b!9tnLoD1!;oAl)!^{hc$W5Q_@(LZU2^x?2y#K8IrU zR9PsXq{@3E%?iub<-eZx4KaDe0zN zY?6;C!hnP;gB|sFtXPO8fW+VJ7buDq__inG_JT4O$ zY-9Y)q`U$&A7PdWicMV051tk6@&l0cnJF|<(&En5kq&fe+$w3rX!w|<$&^5g04g^m z$CkbA3wQKmVj+`VO9HAng}H!yej*sVa!@^2aXk|GD#*6mu;?9 zmr1L51KK&S3!g__7Y&~m3Bst13;QNstm@f$VQk9cfCMt50WNcE?KN%ByHKLgXp2$B zR|NCRhZGjDzTe^duhwXSHnZ*KgP2=DMhbf;K_?u5ZfXXItv)L-ULAKjb^dbVAy1V- z0R6)MyDUK~kht`@;N&Gdi)|0-&z$HGA#>)+-fcmpa&Sl0jR7(c;{iU6dEp+E1W z+VzG&>)SaKhpazDF`eFi=gXynI5 zH4fIwE~O8*V(4Yzb31omKOOV?U3)%#kSB zFKPg@kuB3z@pt_@I#pl3&LvR-{PagqzbN#)@Iong%)(wgDh#e-$t?QBb+Bd zMrv`rpbG-GcqwXF=$%mslw!*#Ri8Rhm~WYMR$)WfJO|Ok1s>^!)IS z9}n$kC@78ydJ9#IaB+w?i#jD`eFIIRtUDhPaF>Elsa@*iHT-(%H4+%5`S23yrU^jy z8_Hzb8RQMeeXf^ILoK94p*`~F$s5tkSA+*atn5Ekj2<77C=l_a&6`qUBXL9kRSWab zUVU73Q&y;XmnCfbIa@D250ZJ~T4GPcc%vF9am!n5AC|F(#q&h*F$??R2cnqyR);h(;uClNtwcmLcwWXd2?5tWJ=V?ZouuYngI zE>SbscR#SO@DJ5JxTU3MSl-NnnodtLPbs?x0rXgJH&0%4CDNi-6gRZx@MFPYA%Fdm1Y<0 zKNpB{V4C-4%D9s#C}u=E*VQR45wH5$_28m|gcJJ`>$r~Wgl`cUkP&K?D{e3t2DU$8$h~-a2P_=h>|Ay-D zSl|cBjIMq(^BoH4M#c=#0623(RswuCP`VkCu+AdrJ@7K|HE#3;B^s!u4!b)6nGMk9 zK|Gmzx|1hKfi|6SAy7-K^N|F2Xx=!kqaA4S^bsVX1C&1QypfWFG-yVOV^uE&fr%%9~_-idZZO&j843{QI(Q zt#$F=vWvx8oOs{UfgUl#u-!@i0G|EqJui?JWY1)NUwJ_k7-XjSNhvr{aqEXQeB9dv z0$=iF2~r4TNd332G;D zl454Sf(_lR)J~|ZxO-~d;SHB-j9xCk`JpBLih4Rp^hKC#;=>5GOQpI<<>2l}UW zu1*(FC)S%%4_58FI<1&qq+f zMyBDx6ng!uROu--%>dzZ03MZZJe-ous-4PS(@E!~z=B9K|Jhvf2Nde6$(PGTMAJG} zU_aY6JTN<2jBjm4GpRdl#xRcT9@s_&~b>NvJXB%e~qCUABOv2ga_ z?3RP^pZ&?i%4XY-Rmz}#WT=nOrUFa|JzTF4W)lYHmrl4iT}VPfZ!#L-_F?`Ju%8ud zj0?Q(iG&q`>5>KbhJf+qOpET_Q>2I&u(YwLw6xFL)DI^eyL z^6FSaL?uGztc4@^?(H8VrY2X zEdsQTr~qyaf*${*XJ&Ze&%a-M0yiGwC4`%vHy0PS{0CEBPH`w!W0&r4`rPG63Kk&G zFSi4C4=9O{*rnF{ftQ!xg0cW>2DG0E2Vh1~W3GWg-L-4rL(}fj{v>wj5lRsF#r?{$ ziI&9AyUy%1JtZNA`B?A3L4R@earWi$@aNpwpRwns=-fCnrNeI|&-;P5Vo%vXQYx@{ zoeWexZ)}DK#6-ZX#U%&Dw53)eGYZD~%M3j*CII<@uJ5*YH-Ql2%;yQm-jD}%_rSZ; z0A;N9JMOOMz$XjZr0?g6tA5wdfsa)$kert`Lqnf4k`q`2;CX*hhd^sYWzhYH7TveH zTiV3*Q%^##f%K~?xxB`)z<8r7o5wy$r+o3pk9K>5fp-(K9*vF1;(h-Z{~loAND1th zA)32VY<;K(Pnp93nW^p8W>_=%y5QD! z)z0l`GzD~yjWD2$J85f&uSRg%Q-I1b=T?sI zX@bV^d6|afdDrkoDd({%rRyQ~WjjI4^J4bp`sMs%a>0%8Q)3MF6JSuM zRn49!t7WGDtj8i0NZo^G=r7mmUd}%M8yz2L8UT9y-zI1N$Cm~@>;Frp=l|Wspz&6% zbWGkxKU~GZdD$+%U0tb6RMABRd-UB>PjX$8{rII_Mh1rC@gkqg^P^ys-)cHHeZGER zy8touVM9YntxBI#RMcII`i{{RBMBjWwZ2eb-&Jt=^vs26@nWRk?5KfZyZpq27zrV> zhv)Y$4z5H$Q61G>@sgyWGDp>YI-_r`5)xZZcB}S>iYG-g(d$2>i3}i7#{W2O{>2RCzqhNX+T` z-@1U_P@!KyAcqgdcjat2SBh^p7TqLVdbu)fBIP*$Aht4N?qbn5&gCghOh%|}giYdk z)o?M5NGBKRI9T{CjaAH??FKpAq)eZ#R96(j#Q@tZJzj_BJ`Y%DD_bGTU2en92BX5O znk1s|fBQ~oT;L*6IrGWbiqF6Vx81vR5l{bRgQdm%;kqP0Cf8T2UCptCZHgrI!cd?1 zyz*KtO4KkH>luDK8J9!s1gR&yp?rnpZKke91I_AAbtNm*w%UcDZl~?cIF?_Q&Q0en zI}xf%Ps$QGR(f`I9k8$`ISZo|$*BLq=ORwKbSSWE5c=-BckuRNVmw3L-rJ$y<+x0D zbT||DkcRht9c|57onq=_d}U}f(v_}FOar$%kQ8NSe+Q(EhAA)y)24n~36{AS`kPyS3Azyum~;2+k7r`3ZN2F5 z9gJ{W@S`G#4S8J|?$~x8B8!&U^)j5P?(LScBYdaM{$yykF+8V< znNgePSIR?t)mF?PMsWOlU{ITN9cD<@-}R9_J2I2_;E36`xW-IL=HwQ&;z(vlSD2?9 zzs)(Y)k?|UJ2&VJk?GTo4@n~V=1NAy#D*TakHCcYjjmKJgi*L{?+4%g-J^O z2j(%HZzCNYxf$2g9l6p6^%V=su7%SZ3$>1g(?b>4hg!dA2XBrRRmmRd#1h@^NO&wX z4Ctfu3|FhWOmwrO$ZD!x%bW5Su>)*0B<{vNV;vGvP57STWztZ+Zl~`YmoHz(X^ts5+#d-DY;vRIeb2OOjCo5x~3VZbQ2z5S<9HX5QmVH*m{1 z>B)%h(+=81!Hi(^5WaV4 z>Q9Sq?{6jCQXQJ@cBUL%R zv#5l}t+j#0j&t=e2ia9Xzfq6t8&?zeU-6yalPmD7QzX1hL_R!b?iCgE6eJ!xOMYKM zi?+!e=~^OO=}|}!dCI>odlarT7hnH9U+NRjhmVR~B1lbD&#*z^R>(Qj@{wP`Rxsau zR`Kw$>aSTaPA#9&%8+}sh#dO;LBRJ0hahsR@jM-CSKqs#yw<0%?3qtRiTaT)cK5#b z+x=-&sqEeb3ICv8r`zd1a#>XS9{oQT7siRtb_=#(! zY_}^NPf;dtN2Fe_@PbR|78MEU){k~h;2eZvD_i}KX$ogYJrx+=Im$cicbmcu4)ip< z)8Aa@)o9w?D!qqsm{?jA{v#ttcT@kJ53JWbb2`e9Yo}{p_+-3WcxaGUW^KJ3Xcf4o z^361*d~9Z7C!c2UEQ_poWP&F(!`3LlLjR*qt7e zXN5XZhd)OS8a7y8FklTVe2|=Mhc8EnNU9t!ksWh zI&;^(2wCC8Jf#eeTmRnzIii50_!c};;pQ$_4G8jqTVOx{1BBIVY+(Fdyf<#@7 zGmYntxP-#M58pevItkxvyn^R$`h9qAuJyCVu4z5xhkBEDjkD*YHi( zmh${Y;cDvFV`uFLaSO>UN!9pjcu-6P(9!>T?-2X=0 zy~S!2`7l#btqPn^lRT9%_=%lHr9LpRV68>9wCGOU)Oc@ma;k4HY#C+mYhxmEY1?V< zy0m<4FFi6M5aux<@|2e{EY|?H^i@80S5Btl4a!|gg!Jm%s|t@h@88c2`(*PR;NKL^ zzIo{(*_O6i$i_d}!0;fAzk-p(IZW?`E0g2BGe6Z9ycz zC`F!$iCM^Njz#6;owEz{a)#xp9iENNchwy z1kMaPqGj|t%B}ho4TZ7SQE#)p$P32hWFbS65qT?)D^4fDV-sVZ6*V#om_IV@Uq1^Oe3C5rqmNLq2r%J%~AL&T`hki{F$vr39S-Sp2>3I5*rpg)I! z5gC02XPZrlV3)_?JYsFrO`pN%%Wy`2+|PpdI9?tP2FgYZdGWqI@ezTKQMPt$8nw~b z`h74;B%+Nm)1tuitli-@ncaoxz8_*!s(|N{DYy5&!C{m;J)_Td?q8bt<|>DryVXLA zgHvQlJhrtj7sg}P$ywtxh@>$n8#X-mT-;kYhVxE#*Dxipb`K}Pr>MeKyQt8@K1-7s z7XNy7s)^umGk4$|ZD=hmIsgG&t*Zr2sqcJ9t&k&Ol~`4|@Mq-Ja*K%_bumj8p~Z@c zE;k~MjlM#G1+VX6SX)1JM*zasu_~auaDX&4ZVJhBkYX`N(9EM(qxEtO{A3jeQLeI0 zsi0+=7{J;n8EI(jW-PelSPbrU@HC4-GL4iqFdE~-!98u`Sm~?wme_`!%)ZBvxTqSt zYEHRn-^#03p;^hGDco+j3+GjNtAI4nrUCZO(%{z2QyuS-(%3ibmwxx2FElt+O=|Yr zJJ_Xct6S}_v$PTKCD_PQrn_#+?*B}_qmy-!3f15P3aHDr_jz+34vlaT=q+&^iea42 zO6xS>&!c-R;rM-1um5bde0D@4dB6THc*}KCWlnD=8M8bMg{DhOnwmVoX0K6Vy!u6p z|7E1XxAZG$-;r68yz+#fLQW_^fCQ=hg`2#`vzDivIr`)=D!*$J5&+)8PSU_FJ3z^q zT6)|>;vW-Sw{pKTp8Z|er+%SK@>C%k!r5Rxj))1fW#gPQos_&IVXt|*B9jAQmr||2 zZK~;2;s=2qtD%Va-H1fUZ}{kY#Mfd$C@`hidwO%n>o$l{SSkY>uidwTwFs-E_s^eW19>AUKU&^u5`KS`s zEUL#by zol8x84!g_6n%x|JA)*fKluemAqNsF4Bnb$oQY++;!LeIb@SMWi_?9IDA$l9l6st5E%hb~a&DO*`s1cu$84r}a17 zm72-TC0gWvc!rRvTOV_)#2c2+^JNqFT9ipvC6u?m9|*d5ERItrxU?ZR=md>D)C2p; zpuB^w+GsdVJ`~hqH5u|Kt-C15@0EPQYZ!8Rioc(5a`o|cEf0~D#Fl<;THRNAiy)~A(a=TMt<@z`HCBXwZSH%ZAUo)Z#9oO37V|ZtEi8v$0iM; z>{-+1ADZi~yUG;8c&8`a**1Of0D-ycrxdgd^peHPz$l06PlQlwwrXH$uHM*=YzXs zdXIX>j&ZYCY4}L8co?y_dZt;s4>&|djbui_K=G?>Tw)nF zW>|hoO{sZ!W)aR%eNE}qkHah%2JfLUEk^qC70YM7VEi`$0IiC$E+hU?%`%dA1m$&z zZ!Cd%aF1vrN>|InuLcuNuNjZSgVdGYC*Q&AM*MveIpcyE)=1MoVtlV>__Ka~z4DF8 zPKub^CHsETIVYBs|MP40>PIQZkv3Q9*>_EmC4P(@p8Ks*POG-r`8;Q zHKV19i98^4my!n|OH)nUeCe;RDo!W1cZ(RGR(0r5_Enkr__4yUv67D&s}jQZzxA26 zc^QMlJnNsJp`0POa6;Rn_ zb2v@UEHV{vDtYs~Bk1_#ou76_)^>N@wBUbLid=kn_wRd_`M(r7|4+&c5IHYQO=}pO zHZzlxqdlckppO&1@5p#Gw1HiZ8R=!e3IjNMssGWg7$CI%N0l=W078%dUr4SbAVnaO zVx;D)n6=X985rQrFpQzGdeL12v$zfM)Kkiah;UWq)kZnTMm1XuppZ+=`rW&ES8v+& zc_lrr;d(1e6qdGsDpsba@?$_pZqE9;+_CwkWmn*nvd=}<>xuYCL-z-7fL=LMg>Kme z0;+SOIjI{1O@=w!=D(sQ>aN`PzWU0>XI_IGgCrTA*IX}N#oa)E`>REW*@YOO`|tqz z1JsWn_47ic?js(HVXIGHe5FTBEE1Y^Kuh*Ea7mFFDCcBXClPpind!5-{5)SPXwFA9 zr0w{89x6!3I5)YZRj5f%MM-=f<>|Rh04YX?$)~L>UsYAtp><<^f2W6hXmpxJKV26e ze|Si6t!X!u$V!Rr5p(6?wg?`eORR6d`udwr_Xbzhpp^NO^kd4yb3##2DZQoR;*PHb zoos9lZ@IJH!$FE_TH`%ixkyG%db$i#^0x6!nr<4uR4zA>T_wX{Vgv$?i=x2Z0TD!~ zN|knCJP8`*WAE2rPMf0T`1+k00DbKy6Lhu#itXKAPNcu^!<7&pjj;Ra<6SPPl8ejG zA<9hZeggAWlkSQ8H9vU3AXR>)lig9nwR8VUBRn(Vw&-rKFdii6_$6B}QP z7Zf6@{mUP|WRB5SEKT}|4(he?p>NGU`a9NZvc|&s@)yI@5zZ%+#k0vHleuyrrH}~C zI~WzyFf`c{en6(w*1Z|!F8F5wvvuZbyZIVmkW25rEYr|Gp_Sqr^{8H>Bg6w zQYaiG+d+oz3c^?jt}a(^Wzic7G;Rm8A3Cw0(7Bp_0vw*;*q*pcC;5|iA*5W zH}#h=m~**O`NpWtgI}lAl;uz{ugVcHOQmjG@TlfE)+DxXwBuBe6U4YsH%5AeVjx44 zScCAb>8WCeF0uEyf}aQ>ukpe2K5<(3p4rCz7HJzAUpL3$;w5*A(x2;AoX`Noh_8k| zY~O`hVt!dk)u&rxgXW70e)ZVe=u4WHv68_J^G;IRf|+*17wP3|4HZz(=5TsOq1g&{_zG>*Sf>+mT@fgH&ykl1HvsLe-m6v z%BVl(YLw0kSa`nO;eX>Wo`g-mncZfZEq@sJpHP(#YxA0>SbUjlRn#~fqD}NA0`aQ> z>&L|R`LtXIxG#T$|F)dZ4^`V?e&Ta&ktJl&%{j;dVu(SP^u1=mIBjYn0Zz0v-G~TR z?c#^@?#Kbgc~wJeh6%)FL)DFT(G0OX`l+^pjAK5axm4p=EEw!dqWhY&;ofgwn&rEX z+piNXJ$lo|1G?*@3Wo7*I?8lmA++cqs%J}NhE}SkdJ&nrLfe2!8iz%<9yOJs#F#fK zT|FhUoH;YiRz@jFgZq$#tG?QX_NvP^@9UqEfHL*7!aq6*{lzR-wx^mcl+3%R>1Cd6?GX#R;=ciqLRX8j6};k}e@Q zyV*LRgahv?qDF+Lsa_rkBYORpTvLtlLe<&i1^DVj_l)*M&-J{<%P#zqI@Lp}tGDpJ ze9~!unTto8w5t%@lgd*U0af>fMTi~NnpTifIF^mHSE}d%M^hp(mI%JWwCg=Z6 zPSVV<(T%n0zbiB4$akU?;-8zhjb-w0{p_eLt#z-mf?)frzNwwk({JKaCH2a)8`7~i zF!x`?1eh(h8N4InqHrac6a>-((%$FCA%2PQweXJn-%*&m78P$sp5;@>S_=)~`VvYT zF;j)Xg|cBS_tE3=FqUL))nB&BCr<~Y!brynM(SGZ_UgTIwLzvSI_=UREC@$r1%wjK z)wqd9JW664;G^)Ce?92f<(J_Ddb|dx5Jo!|g|FA&_i$Ra(sxU{*s9nWJVQeDr|_Gr zyNiWgudVAnJrX|G{qbCelIkd&y=iAhw0V(>w=$En=i=+f))X?qI$HtUs#S}>@4c7h zT;J_NLS>wl!$aMRVt$yq$i2s>-Z=|yk>Is2q}kql6a|}1!**nZ`9nM>q~vhaJM&Hu zGz-dUQxPr~z_vaRzX?$d70l#)Gh6Sq#A<$Ab}ak|D{ancX1B7+b`eR7UYJ9nZ-TqT zcy9PQQAoahIEwrqRmMs+CG=I-IlHQM%c0-#KWjA_<)7eJTQTsxXUzIz<1YX0jxl4R zmQCWUJDNDP{^E8WeUy`RJ#D=oTR}o0p7Owns?D}Fw3CQgsODwF^Gajrwt!n!Z1g{| zN5G9ut^?Cib?afK!oxHr7w=vg3elKOXmM}Tch}gf7YSYR#Zx~IuZ?y^ZcBz`Qx;(T(a;@VQpxPva|obD zrM_1&4aqEYZ?XEd87&m>_i4}V@Qdf_2Rwor{?|%rOE6;AWO!Zv{(p>>?@AWY%ns9&{FM_YWmu zjH?6(5yr5IPX)&AkhxB+1=IO>v#)kSIKLAz+jM#6`vyX?o1WX1$4E>8# z>A0V&>vR{|EmxhtQo0g@f6X0N2MvRv9+1eW3j^K%jWr-{)R(F)*lphrN)|5M_*dceN( zBME4Y^XoF8f?|aNW8eTP9wGm7<39kwqc$QSzMiYMI%JG*5ryv)M2o}&S|!1{d4BZ7 z2REo8_h_g8N0?2rTSEU(t84qRqNgl<{Z6F*&-{zwH#Yrg>kjK?>WVbYk0QdaL` zfq3NA(=#n*c5WLoCLB;x4;2tmCu_M$h@*!a@zi4h_tYY2ZG#U6yUo^=-0*(n0rp0M zR(fTs6sc;8CbcUDigu@q!$k7}Wr=TOf`iuYh@|NdBmU|G4fLVAu-Pe!wncNTh?lZ63UI!ZU|gW)$6z7ocneFrbttb%Jlz^xct-J_hp%so#ho)*shK9G zPZd~FQJ)%NYP5jl5yR9g3Eus6GZn)Rh0LjH@Z8oSm;dRP35?p|^}-v`gwf!E((tLk z^mhyOlZWpb@Hy?LCGzXW=W#ot`hb9H{v(4$!9>MGMM8xxm1{U}Y~QJy0@Xw6u9@uD zQsdHub*1|DE?Quy%n$%W(Q2AyLM@_>Ot8e1qhxazCBp!eTi$eqbeg4ca@%Ylh8)NM z=`GKRj2AUJ;z%%<{fp5aLLbfK53A06tAm0|`V=?>=(VC>2tc5h7toZz0bqKt&|v>H YXvyPDKk~jo8)}U*5{lxLqDDdg2mi9qf&c&j literal 0 HcmV?d00001 diff --git a/examples/storybook/src/stories/goodreserve-widget/screenshots/confirm-dialog.png b/examples/storybook/src/stories/goodreserve-widget/screenshots/confirm-dialog.png new file mode 100644 index 0000000000000000000000000000000000000000..e13699e135756079a249774598e5e270574f1a95 GIT binary patch literal 70513 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 literal 0 HcmV?d00001 diff --git a/examples/storybook/src/stories/goodreserve-widget/screenshots/insufficient-balance.png b/examples/storybook/src/stories/goodreserve-widget/screenshots/insufficient-balance.png new file mode 100644 index 0000000000000000000000000000000000000000..73df20972af2cd9b765450aed00651a3b5dc354f GIT binary patch literal 67574 zcmc$Gbx_=2_ufYF5S*aF-8E=%_YhnHEbi{^?iwJtySux)LvUMcaTe+Fef$2}&a|Cr z=Qr)=AMPx>ckj9Kobx>A+zpYJ6+?o@fd>EpND|`0iU7d-N&w)UKkQrRD}2a0WdOiu zfP}EX59i;YC%ErQPU{TMUYosmh|$4<0H4XXHsAFWd_RRDWMfPfP@WWCt#ds*E>AUS zfllt>!!SDN$-+Hz)|3Da*<)GflMZSX&6s*1u%A`N4A#=iFRY0JTHaxTU;p)*wF0dF zzy3)N@ALVeR;LKj=T{>DfJVyqg8wuCSOMQ*|7rcr{tWx(pOz;2|8-}5&{6d4&>%wp zFg_fxQojW-;uZcUeCPJ(x1D|yuZCMITUuH|Eqw5SjvJZW|2x3?;NHaB8Wv!U0JX_^ z@+sfELuGzgY7X*-5J)UQ*F_H z{`+Qs&$)uz^2YCJ@;mu^z<207n5;S}jq4aDG2WJ~?FyKk1psu-ZS5Qfp2yFm{VnI) z5gcg)6^Q_iJkW2&UU`u7n;&=mQ+HWk0|e-XA78LL9zSK&bNOnE9UK>a;fe|v^auQ{ zhK@%U@t6Y1QTanz8&;LvS#U6{9{@Sy)G*s}E%RL@*%uOsTOiawotek50c?Jf2=`bDF zU+u8|#}JcF*2T5&vlm+EsGQ&AjhQsmBP`0w`kT4v+_w9XSfCw^G}_?Ftvk!fWlUO4 z_hfCaQQa=9mnmvVf$k?vPY%rcmlddmq5XZe#I8gD1dga+3!ZWqWoqG@R2u!7^c#tY z#N=RQ)o#ge3W?$dU~Ql7vAa~i2oriP?ZWrl_Yhp;VF*Gvj8d#iVFc4fMF4=ncNkFP z+&)VC)wA#n^!auPyzzO{zN=DRUss0)-PfQ@pIJ7C1>7`(n8z*k^!oh#3?y$${DklO z4ua@#Z#w51(E#2|6-E}5F(1pAW<0xgZO4bgNY5Zh-$hu|vF4 zN01QDg)BY;e(N3k3&aJi+H8Xeaq$W9DN)~g)BN++(wsh(fe?HMSqNs5PLm{bBX@ZU zR}!Mnj|YB;ME)EP|E3cNJ*AzCK*ArR{bQzt!W68em7A_4t}$=C-(W{rETmm!{{^^V z+S^?*n|Aof!ve}-q364wRjh|zLtjD9Aq|hR)lo(W0QlJJDgS<{oYellYxur8EoL|$GQh9d8~6g7qRdf-FI`T$BB3k(1l&> zAarp7gUZI>hzdWx^*)B8l6Te6^3%k{?rs1)5dbkEM{x1_jb2c@=$lTASA&xcPD~Hx zmZm5n1J6H6po@hF2eH}Q-CeqVvz5HK?e_uDsr=7i3{LD;hIb=dY!%SuK&M4#5FDV9@%3EIaE)(U6T<)+ zx|XkzY@naR`0p{#8|K|}^I7O!h!qxfq`B-4n)ix-)F*(o!)s?hH+d`(|2*ZIJzIa( z`C0Vikd?YF`w!#sL|T#@z7If5N}Kb~{NjxsL~+>m_K`^GNDL5&NJs_vo5~5rEnU*d z%`Yn*4`!ml%rBiBZsQ|tAJwt>WN^}|PfeOYW3(7Tr_DE^T4^uNfN^Jm>FTt+_*YSa%*2}fXpCkYqi)u$Et8me?3X6 zJ)LN>4JdP_nY_~~c z%OdQuhlSlk`M}w}4~9>RMMxYCYTnexS6?Lx7>kmUI$ywg2Hp;Nn)?=jq1rcl)O6<=a3iqQ@7~8c=sa4OnLlN4B$1JmRzMWL+&*m7mmLI06Vw_H zDcKB9sE~`uY28dcpE1-)DaLW_O$iq&%@9kz{R^K8^73AL*4g%5_8+}!ZgGzO4*^W}oS1N`m&33Dan1>)dJKrAiIec0i-4(ibnU< zTJ2UN^B&9zUAmLXmc8E!m{RWMk5U(7{$YnYoIKg zE#?`rgXfRXb^oF%^g0c_m>*WSEpgG^*43!C5%NknDiA2@P1S={zoQ2sBzzpGHdPxZ zYhx9rJZBevKNBeR4ICNv!V1pmOT~~t^QF)-b23K$MQIK}5GCz_qv z>b;`azVceW%Nx}lG1-FU7g)6uqsch7F+b@O@lDnL~nE#c(*b?9a2cq&B>)#xyXdwe4Ol7|Gn^k8t#?#kujXX?)~ zNGSfjC$#SFMo|`&Qj@0WP|I+kr~|-$6E2X&_}L~{{QC%E{i8u4<#5s0?wg$jkWZyP z74M;`+);2OLFC}<`ns8Zq#6h*uok&i3Bu-&F}nFA2GqFmY(6pROPv6QNASJ)&5knA zJg{o7L1)8L^x>_E{VKS@t7UVEaK6lQu3iw*cS4h7!E4nBG+B0x2d$p^8P4_vNnNeP zCW*JthRu-eOy4|8ihVL%R&JT6bz{TwSOx$(3j@h>purnzEx5-8XS4O%>^CxVm+=pH zUbq-hd-O5mc2ykdV`WJhJCA@=6j5=mG-I&H6zZFtShMT!pGC~Dg889b^@9x+r?m%$ zlk0Xtt_^) zAG=2T$9_tQ6bx#7euFh~i$Vq34%&TpWO@EMA(Q|>xGfZe0gS|~A9O5-rX}Y+ZuVv5 zfVp&%`W=bQnAOUp<+xO}!vE^9Tpyv0-Y&$U`_73|&@%jJdqG%OY4cQc}nJRLULn&(a5 zDHz*$a^aKkG=r>|q4wOf;>RYp{~9^|g2JlvFgs5tS0Hj}B8Wf+HzTS*&IAK( zY~Z=c^K30!g_Raslsoi5`paY97Jr#lerHv5qFJrorIZM#ZO$ zD9?Rjq$7W0y?L{yb&TL7wfeWk#FJ$~TSETLPRp^j$;RWfn_9^S0#~5tO^F#Fr@5SZ zpf7)WWz4hj_KMh!*VjNPH8mLj6qF~BmWST0!dM2zaguvV2jm!Qp0UEh^`?%ug#X5P zfo5(vv=#YeNG2XUZMD!bV`ColeAoSHzQp!*=5rR>eXg4Sf6R+*xDD z@>Wkkaa~DYYK|NHY`T<*9ec%d-O=@!8Q-^NweMFrd7@ga5K5?f!v?OF{-k*W!2YE3 z3$}^S)m^)a1D{Z*-U`%_*30EJUh12D2@NldQMZkDGWd>VS3!$#k+>k3ur&QQ1G7~k z1qvtt@6GRV3V?r}|6FqOf6tU`pljGUnC(uiw?B#sbAK*wCNwrjgC#kfFowyzEU%rN zauE{K<(Yxk&AKqB`Mi+AOvYj}UXdtsd#F9EX}5PwI1<9?AYwi;bp|$*Ze!m>L&^O8 z8FRECWT~)CJvB|`rxh{O;2g}?ASRslbSFhBwkLI0gg<@`=TIUmJA_q46n|K%Rrj!a z$O6m)gG_ymss8yZJTeBHDZ2T4*5b=ghDnERqN-L#Y3C8zcXuGTxqtyDW!BGUx`(Z~ zz!4Xi+sqOHCZ~vQy?_S70mI<*KtNei{}SFKp;MSG6U3$oV&-Qfg zAvi@TV7Ol6mV?NA+&4wx&3f;jCQWCs{RiBgR^pjNNh%o@-mWx`j2TUj2Vn)}GgPt# z9cC$m7(y=Fhg9CSlv-urGW7}~KeKSFu1Tr9hV%KI+=4|K`_FVfY3Gq`qmYVKRC4G> z6Gi@)ry15WH?6)Crq?_VUfd`tVKp`>wP2NlPwgaIg%d!76(Z-f406?|b*Kl4sp0HU zRJT8B+?bHzvsoFcis_;<;r&|+kciBFB2SilY1%*AIH55|NaNtJ6+AN~;b63pP&BqX zMD|*_6q2wr2ItrbYeHOCL)ur1JqYDd@DaQ*|zc8Npp`vT7MKql8JQ{oGU4vZ-e^29JKVD(}{w(XUm;GM^Ki zE{#vZB}_+UY;P^fGt*i1W<*iekXO~-kQQHRdOJ0(h9X#A9U^12Q1NWv_cO% z%3QpJ-7)EeGF1visb=c%-QRQHI2E3>Rhx;g{C8tR%k5GMn)E7EbMP4@3>qb7_ou4?X*;8y3yb~(%yZGP*#?t{y}?1 zhUOAzir-Vt%y$rzQbXGHhK~orK)n}w(k#SorbgRun6F<$9!SI*b)3BU-EP1x8B=Hg z)gsUk&8XWsm9^?PCH2dIo?%!SK;l+2Le*R#@^~x}DGfri`Ujm*sv$*nyV+ER&Eim#Si|~Th)HfyzOW0h4L<3|P zk8lt%S1>&6^vGv1o-dDI9x5hYT+j9NRitD?_vHR^tLrLmdpM)(gXRX~m{LY-u{ub~ zZSL1KYpNo?Ja*DX466qca`k0OStco{Xbr&j5(_v%wkkLmx9WjbT;%0hfSHR>4kb`nE}RJk%L)5SZQGXJslle zb3Lc0QbZfJadFZ}Dkg(=Q}Nv5{OYXv0ezKPxP!6-T5QH6+l0Bi*5Ehg^;vF<6jM1u zZVsca9Jz@L^0L$sBU^a$w!lwWr$$pF$VRw^I!{!xNPzGslT$uo5}$ zXHFubHynj>v)dgZN57ZlAGI7e`iWkFZEWmSU-I5O#|Vsu zWDV?NxXoN#03rR)EfS@d`=iv9TylQ}3~?RxiVlX6gD`TeRo$@d{?8qeHPS0aV_>ey z!8pALLs9#$r9i;{D}C;N>%z96qp*&|6!j1Ce;?*w`u8)@nDMM+#LpbXqD5TlG9MxU zi7z2-f^1#K`JG@Ep$v9}WZ6_D18<$8TG2FLa0Sn@9C13)r$gt#w}MwVb^W@Nlr;3i z^vZw7J^~o^Ue(2i^R(2a&4`70(lDNn>cv_Wih~S87#Ox{5>=qq)-4|%xgfV7!YbpF zz&R;Yqu!AB@8}9D1}DBfjGcM}!BZnOjKZtcUY;jKAq<_Eb~JkIZk6r3wa4CvSP`zh zgg2g5gC}BV_@XzK!ZL2sVyd1GDP~Y}^)>-#>}}PhjbGgsZYq#fu%XU)RrxiFCz^>}toTu#*jBJyXL?c6#HkUmA`sMDv3A#QmQp3;yoN#?EIzE; zkzuB?bFz3d9t5Eo*wG&QN z8S-gjwf^>?o+wYiyTzYD?fN3-(c=t>3F+o9k*s!F%4fkirXa$Y=c!E+w+4FLJvW); z+MBqXCLMF}D_lQh9Dr{8D->A&rLcGa<&46v#vu11?&mOlpK+i|p;jk*Mb5kfI zFXwZob2d)u{>W<8*I^x&;rmcF-l)_V_!;0W5;pUb^x7^~onc~xp*&jUhbikv;&U`H z|DfQU?c6HjTH1gWQ5Ylh=bf@#AMPjxjD0Lj6-`CT+VG%EMp8{Y6cj8D{mxSrQ8q5U zJ~s`OP>9YSEwxxBc~#ny+1ks1*dhsuAq3K=>u3`3<@0Badm5dwIjF?l`0jO)>TB#w zBpYjLK%s=%&Zl!$4Bt*@0trz%zS8lMkg$m`8%|7a@}ZFPLDUV!z3f&n#GK3_J90q` z-|#KE=D!^FC+Um^6ZGqlE+gnjsI|3hwcqp!Lh{U=9RizjEAjk955hNBVvfCWmfB0 zfl2m&2IP!5%*~UYC@5Xe#Qa1$x{#5_&o>IOFprX)YPKOsOmKVzZ z(2OlP6}|gYU}!FWRw181;q|g`%r|k?aSANttoL}T!e7B`t3TW&GZ_6tGOeSzF8A># zfivG_0<~1kqd0B|k+P1zZW`sJ( z_Q9%$qBej^R40c!Sv?wEuIU*;k;|E z-azQ=m`J2h-qRKf2hXL!ax3SQ{BWXcUslD&+RgoDwI?AZe$|#$5WkxB@#TzmD{!e= zj)AG(hfCY_H~>S!!*QXUYN_UMcVlf%00q=D&)eX6-)i#2&(&7F(|bC>x9U;)LUep5 zq45b%b)(=N(eC=3Nk!$R@0!$JKZo|H^g#<++hb=?nrBDJ-^hO6&*Xe{?H&Eup%tDr zrz4L<@A2}t78C0zUU~~ss+ivU=}e~TCP#cVO zIOMi%kJrb82Y9ap$N~WX^WP4tgGu5&RxJzge%Y0(OGd@Irm?vbRIgo(7&NZ&Dc zBIsVM<3`52vsUO`J4Bk6Yd#GVRJ+OK$d$!CpMn#vin4mH7I)mq+1>2fV8Lg8xo&G( zBCL?HZbtJlSaNe~U*_3}TIJ(65v?A)FNKPR&&e#|l|$HwflRS51%|ntXWc59m-m^r zv+pX#;!hyfaw#)vZ%tgGx)1ILK%>X&`SLeeFuU@gaFf=!eReZ5JhwVCpRuOWS#Q87 zvR29&wd4pJgvmf`D%GW0prL|hyRlty|=ybGOR&S z@Z$*0C$i5s%H3&)L5~+&2d5 zODu6;$&OpSnwsV&DGF*-Fhv6}b7Bc{m{`CvvqeVKGZYy9Q(J!N7Li>TmFB1pL!DAK znv-h*75DdjC11Z!S`%$FS%F5k0-6htk2MR6sG9aj7@&KvscDe zm-)kB`(O^lWisj0P~Z<#pw#I%4B35HVa0GIWPml~)fXZX%XS}K}TNXuudyD*@kqZ)(CWX)#~UyUk~8R1%a!H~P}>TWaqqo8S62bJOU3(%N9 zgthTZ4_>>Tf4Xvoj7gF}a;2%^yb)wOM`jJ-aVL4DLuInJ&^Am;DdD zDxwJyvY z&c|z_UHQbT&%xPoiKUMxdvZ6J@mj<8dY9m$rw{mk%yRihEXs^*MMmS>FccCGCJt2L z30IBblb&yWZN!--&~`XYaGdy0nS~;IT(mgQY>^PVi^Lu@-d`q_K3_kmXsf=A7KZ~b zw@C%2iaM5*w@3j9TMLG=`0GV=?Vz9&t5RsPOgXg~9B}KjTljn5H0mIn?V`bM{uJwF z1*zy+_Li3ayoIeuNvL-dHN;9>@Thr0mh%bDRk(C5ny;0;0!9IhxNO5nh+r@-^q= zjg-UH3_SKB66q#*A3KZXL_oKC=^8rI9hwF9uNi^ecGVOe>~C!h_N+hcGVD98x3(94 ztZgqlWhJ9WIy31>3+Eox7xtS9Xn_MxP3Wv6JNNChs z9xntTP_q?FecSMSHr?A&UXl7uPN^__6#pwJ(^#V4?#p<;k#UmO#j*0l8RzP^!S@>5 zYcE|DEINEUrGYy!S62_YS&r|NGB2O2d+$f)+nYRY+j+V9ogK!GHb4sBG$!TnY`Bxk zT_&H<6R-92yplI_Oqw%$=gW-(@qE9C_SD|icp$!q2UxGX+Kz`k_srqdX0w(3prJK_X{!fx0FX3OQ3iTHv>s-KF1HX&e zjzO)EsqcXCF0;eNjG2#h@r(Sib}?c7)5T<2&IfF8Lr0C!DX3M8(ILbjIo)o0Q)0x3 zv!tM?y8hdjqNt+5XKS~tnwuOVsu3f^Lt@cg9~oS?sE5wN%Uc5-`|83V`BB3D$@BDs zXF*bZV+!QrXF}E-D?(dDOQVO7QS-mT(4hRU5<6vetPe6I= zYKtwEp)mq)`mEB2^`(o>?)v3Vkkabq0mCiRDE60d6o4-4YdCq(CvRg8dFWHhnenOt zo`r0|KSh_Y6T}wi9NWDi$e|uOTVc~%F!p~u&uz>QsTqFk5xaD&mqQFmztPCnY12MI}Oo547JK+efaVnRC6r_iXMpU<>Zvo+)pP&?!5Buc4RBnkuFHB|Hg(_qS zK~aw^)_CfBR<}@U3jLCu#5{{4_UwIMF_zT{JGn41(jMVFbN4}GGy#f)TB44E#K?~h z3@7@tuD#B`_`n2vao;!u*aWis21g-51hmX&`+Z!5Q{CtwqMM1VDdPt-(7*wWg~JHn zX2mwhYp@Sb{WFNQ?}#nc(~bBSqNGMaj&J)4j{Amd-Kt4j0+ADg730Tyv;T&$flp99VKS+~eTNh&sWPAvY) z(;+maql!lpnVfn9*7=k`2^oSRAe!3JaGRc`hL=2o&{8G#!<(p6hD062AYOrq14K&( zD?kd7sKIgFOQa;R{WopimD)e;M}n{Hg^$FX;y(tJr%zpNz({(@+yyT6R(Fv5zGMFk zDo{5t+mQJ9t3?0X8hA|_*L9aHVFamie0F3`Htm-itbU)+Bf@)r&hkt%`D@99*VNs= zP7ESGG~isRbyTxm=BD_au@3+Ekg;aEBLe0_a0^Du4>%VInc`*m`U5@Q1Y4Ah0pzlj zC7$|qkGsuVo`He#SPOe|pv=WY!plUy!ZuvA(QHBGrlO4>-E8m#x3WyfE8YDd$f-!h ztBeK)B$%5SHjUl$S0wkwQ_9Eb0+mfvS#fm&aBPz@v<1V0!i=LV!mkfIE*|%(sDy}% zl%1;E#YcX#bdwbTKtzG!b7$q3;c6#*N7p1IO2y|Ci99>s#6aF5C;j%*wSar6JX0cSx^WXehy0e!*W_=#Yxbd z(=@8$SJ18RclFPw_Jaa#znnv&r_9o|d#FCcLGY)e_riW_(=J+FpJlN8*xR{{gN@5j zPvaboR2_izBd%CQu`74YV9Pud$#ZD`3_qIW&c2R}>$KEZTWH*Vsz;ZUHLMBq7s3g z&6b5#YfFcf4%Or53&s}bLmAS;iVa!lo^hQ2X51p0Mey^s%v@{8D-LzQ7LdV}WogH{AgziPpg+)S0e#b+-46Ez(Sy!%5s>Hrf7UHnJq|>0~96xbPe0e`e!>VGl^gzHT&> z{K<5t)_z(@pCCsfLYqbjV?X1vws$if#Fp^CZ|R_SB=8f;SOt6T0h9$h?iT9X;&)p4 zDdw`$muz3n;eKV+lOotj_x&nO)v=}gr70U;w*-&pqh*p+-1@I?~DS! z$_wDUz4D}EuFY51u}sLXHx-C4MvviszZGkoHIUqN5Dj&WGoA^TF4?pEXZLz`>du)k zLI`;@d}~jAVK(F2x^5Q>E#RR0?6&~#bw<#8KqnoKutW*JVaM|IaHy26OMqg|&!So! zUX(zn0zk5*sJQ)b*eIeFz0V3}Os#eofuL>z=ve1$U4SYXER<3P)XWy%o%t0!Qw7WY z2Xpl_rR;s8rK*{dCKmeddmBFEGr#ar$Y!`ea1tLp?F+2?rb5 zRMof( zatRp3+m}Pbj%}dxVrd3mFN2fyiwxqt?n^IXI8yGr59q^4LWif@-W+Iu>_tJbv0>@$ z-h4UWLFJ<_ymO|MqP{Jcb=y6c&!8K!b1B{rti+olbp7V?#D|eHw)A`-5`UZi5-vQ% za5}D0K|4f6Nt>u_x_qxU^g}`s{B{W7vG)_SR4>OK>Idu}5hqI+4{p;^r~dx40FOujMB%NKPM!Y@`IY2L1es7H?Z*ScJJ%Zf+Ys zAuE7TZ)oBWefYc}xMzFWJW%gbFlm4e_a0rRH^am*)&#Y^&f0eFlw?4&{u7K|SV$M9boz&j( zxDfdIOhY$YBu70SK|-56bAlRfCS;8W!-hz@@0mlT;=cG!mita2eer74svaYY3p$Sd z*U<9R_u=t&!D5x;`wkN&Jmk=ELzIf33IE_mwYx4qrkxr;2EFoV^yZ1Op5wcd}G437|I zQxuGA%s9W0U#ar5(kG>=vw-k|b>1I8&+N5;n;f_*qdJ!Y<7>ev;q}IlRA3Qq$FLL5 z?4o$RiAeV!1(!m^>huXx@tMpG&#NtOetf8&lSU^uAcfU&ev-#Dof}P;>d|f~u{B$} zzrGfyQi?}QdPoDV;dAqJ0ng^nY22tp&KVm(Xhtu?(3S`fd>*^jtz3aiA-rd$(!V=E zbso(AP$X^{{txkfed*4jq2zxm-=7jJGiVZrB#IkKALATEFi|R-Mu_IbW-^pxUl-&( z{>_cQs_oT9Ubzc4O^__3q#tF#z4Q)Yx5tyO_6n!H8P@&vB zhm3L97sMMh5vA$yKZtqxUn10trc8feFfZl7WRYcA{23`CCJJLfe}FR{povyUOi#kV z!c5`~jtRbr6E_ML;v!_meamJV(e+2+r)IoXF=O~3iEMagjN3ygw@r;c1*c^tA+2TP z2Rx+#%=G@ea>)!u@GdAwSf0=c3eH7NnobI@3SnVW554V?aFLwt<~7g(i3_;xQ7b(#~#Jw(t|% zP3h$_+A0p31LWJQ4&}(Dk5Wwx!$tkt^INZUfJa29O$#~4br%Xol>EUfLNc)F1c!Na zG-nSk3TVWHIv8^BHC}fntb7>ItfBDh)RXj;ChTJtMfh*Yz#@jBi;YQK@8UmZiMu7q z&57|3OT|Z5bBc<8`H?gt$&gfwlEKJI%lU)HtcYW&=B1z?WgN{=uaqyH!K&K2aogol z0;+{h=-H?)F1-u#EcWX3#Fkdl;%%6+zs;0irl2JkRn7ac`UF4*0B&FF7dyqPuyIY} zj|^`TtD9R}x$ae@3Icd{l(Ic01qXFo`!39JNaq3|kqL)f1a8Xra{k~?=wXyBO)%19 z*LA~@`&vW{RBb$N7t_gVQgPRAk;=G3emy^4X0o2%LkkxV{=r^2gq~yz!e&f2j{tCH zN)u1@MXys3^)lXNQ}(@F9^6U96QzRW1G7R;%vlsoD))STYoCUS== zKRNkCI5_jW-Dp`vT@u3OgtkQ$XMJjHm*vq92@O?gRY0a8`U?onhjQKEqEuBvb@IL3 zC;drN)8UckR3%%FKD+(CzLpx)B_)2MDPzpj^QXelZ zT-qN)njpWEHXTi`3kLme-^Tz?_vKMmj`<%Lzo`xjvlP(KGQ=|tsi`JE^b5b2y{i3@ zIXFzuaWC3S-XHkk{({qR`}#qoplj^kTEH@RIu=3Yy5Te!tMxo2K!9za#cOqa>q=Ro zH5TMSR)3Qc?^J1EIC@q2eZ>-KVQ!cvZ-3a#(xhd@1yFGGHZKPB#yVLv0W?~KFkD}5 zG)F<~xoK|WUC<}5b#ipSYp;;VM$xgPF~r+(5m*qF{-f6~imZA+c&= zd-BbcM2%jzuLq@&%>5zSesS|pLz*6z?S0{oH7(@QHO-H!7v0peSa1GSq~?t>kp3B) zJR}0lVg}^L{m4&bSwd6NOdlB^{9YLtS@`{eFauSXO^b4dQ^Ifk7eZ2jG*RlvzHD*I zMOO@yjZ~s5!7!g^9ZQo7Up%&k+vZMJ&NU{%oTHRLI5RXe01(G#ox~ZPHc!t z^|dZy^zQBge*_d9n}zim)i_&2_*g}%mXZ-+78ow7`evx+0%|CZQvRb)$r-zl#Ud)h$N!2Qp#}qp&GUj%ZwB$J(pX4m?pvR=5 zp`77X=L1GgBZ#Z^6}w4)E%wKLz3l)Hg~#WzIs8&^suf z3C^^yA7o)-o{l;gr?U50*n8;j4V+3<+90H@qmvxQIGW!*oH3H5r<^$C8gETG%8m4v&(W{{ScX#5c#6uO9fZ;26K*|`%F=YFvNK7=Ag3r37_}t>-c30k$HaJ?RZ#yy4N;5d^`2j@p;#)$ zcPrQxR4`dYt5P6l_y7s|Xu1`jEU&K7Y}K*NL|r~Rs(Dd@-Ci@M8oqFRl=kJ)SxBp_ zx~2tZ_<3zrHT7v*?gq9dQJ6@Q1cfA`0xmb;L9Bvg~plQRwmO&@}kuw|5Gq`X@6Qccr_gl4ct_u~_F zeipW*{Q~>z>ByQXM`?eTK?+T+FANg$a8VxSZag1f=iUW*M{e*Veb_J@!GUo_kC4_) zMjj|Ev;^_6OW9c{=eStPS0bydfe3NF^zr1p6JFho;9B%MX z8Xv&Z)Y{sdZ}NwqIXTVDp}!nM0}*lexTlWS*eYuyuy5B?XQ6t+n@^ZR)l|VZ9ZyuUA+!tG?y;^x+4uE7=DCw#YwwUDBz5Sy)TCywH$2 zQ9_RlC{!HHN;6Utj?hE=4tSmVXHcFmhp)`uQ36-Q&5kpCs`o0{kU4b}k3KV->oiT~ z-FxJ)a!}`Oe(w@X0R=xRZ_3n9svRJBWEfL0s=#FHOWoaJ;W`bY3{NOxdf)8y@Mj$> zhI;gUPDCj?htnumf}mrxbXFBse=z|&li^X;TS_K%T2V)hbWnvZI z68FH{kkKkT)a-rwkkk=YWg7YsDGX(q9uRQwheqW~Araqm(zJ_GZf;#U*jCM@sCy}x z9Q1~f+%AeD@@XK8v%Y8B+T&3rdm5+zDe34s#C%q>b(uIa7!d)7 zkbLV4`mSk#$Tx%;b3-(=Gz)PR7*-y>q#kk8Ci>9iQ4GPVF0;6nygmmWL&rxKn)R!RqHXZgm#g4QVoi<;WQ^17;lera};sm}x- zdPLbidA&^&;--;8?=w0}kq%FZ_=?FAlWlEdQ<$6* z=m%he{q7CKY4eYVtL>_bF}HY!f==UB==wziC*6IF_VJd*4ti{2+0u?n4EA^G3FA9% zDnd_T)SZkAu3e;V|#7T3VNGy7M@No>;0SH1gVITiu)baexyGau&SJ&?+%( z;6Fk(6}pvTbYYH)+%mK#Y)b}Fg`PXm!nmBS!%&@CB3aq1x;6tG5uT35o7M6iXk=2_ zu8IaRrnD%hqB^^ktglbalq?phDVUHlGx%Japrkn!~oqvf#)QD0Y%Ovps!o1!bv z$&lAuvI7m1DYgsK)X+u96h_bz%YNJEJxVIKtqURuBL_j4z$D+4#|*H;hhtY2H>Z>R zDO5h_&?+r_QKzjRuYIoGlDMNQEE1Lfpk*XPKW+bSv)F zX0<3zOc>yymr*n3acIsC$-rx|))vpa$=0-b`Ho_7JjWuAPK^3NHWyCG?nXBw$K9c2 zBCG7qB!wXoB`H%8yUmyM0%3`e>C2zF-MdPcD9JY5V(M9S5;w*!rdYVWep8E$XGdDP zVeqmJ`M_w%)P7_qFJ^h+VY8~Y z9}49ZR6nNAqtf6j7%_?13S>D=g^Ct{2f_!QvC7qGdXdJ4K*oF`k$QqcT zZ_z)g`*kxrnG`N_k8#X_4Jc+SiE)#4PupA#I#WkAnm`{Qm9BC~HkqX^+1*XubfTQe z=drWSwA}l>SZM-BG=n#jOkTG&icA)oYB-`B)jh3ga|EN*^SH!>Kxh{(RCu@lTy6s^ z!xkX+Db~f#kWPy`$b*^<3qdMHZHkwLDCoRBr2M`@*)DbxPwflJPwY@tKxYH zcAEaZ*k^_Y%TyRDHLeI(g^wIM#eqW=L&?q>D3+FT%yqpaM21!Isi3V8A5v-_vRW zh&tunq?VSCP=$7?>pzr_|7F=C0j2g;_T-5ZQ3c@+t<{#qtYAcJ~P%f|S#|lg0gN1h)-03W1MRRTQK}pZ(W3t&x(d0HU zKLC*QPtfyl{&t^M0xmCg4y@#ocaVT03eWJ>usnXhaZO#tIjlo61e-nL`NKls2a}5hYlrdNPZKJP8eOu48%GmBu%`Ju& zp_$wwEcQqRA@nLL%xi&IUP?&SgMEAJQ1|ACP{NQ5R2Bx^w{>UMF5CF&!5ZOQ7WgJL z;axQ@|EBJgXF$xVWSryLe)3#GXuaFQ>lxGhUDVY6Q_YH4SSzm-n4!u;N68ahVB8wV zX<(x8o2T$Aqk-u4p;sYvZaR5i^C^t1v%UTl(*-G#@b*4TC_ZSsbaNEd)gu~>?ORQk zdOhxKCXr3bC5h>y3}se!rJZTC85lHh2&sREej%#M$ha(Z4A0_!3&X-@;r47cM$IJO z`x%jaFj@pYCSO4;rzF!)Dct-IW=|2g-LtMq&O({Y^MgyProwcbNfujBO(e}qb802d4ot^4HM6v1e!D(fo9z&g5C)wG za^f-WH-0kq(I_L6A6is&N)NpSj`f|nk4A>{QRX}sYgwW7Q!OW@%&ojKHJJP_U#~1m+fg%!7d`Eaad7_~@Ey(UiY+Rtc9y=t=bSy^|+qZ=5Ya+R`+c=Q{JeE3xrV7 zlE-@le9kYbCgrclEiD-{`?nS_KQ*4T^+8gPq(|824IhZ$i=V7VR%PLp`oggfI3!qy zQv>g>3DfKk9m=AuQBBU00lA}k9jSMx4VTIuf3mo!zhk7Y>yqtml&Tt;APJ*c3yJehbR!Y!rZE=M;;$L6Y;8wXPZ91=4O1QMDBBVwUs{f z2N5bHR7!xo&)IOAz_bvYGw!7@t>0&70|llIn8P#t(Nz#y0x? z0@P$TgK6hE%I8sbX*Ap}XgG(NImo9f=T4Z?#!2KrHT2wtGQOm;{JyxU_^Ntb81gYF zL};IWQ>~qQ%lX1tY;;T|=5E-U1eikf)~~1i%oVHgRa_GO8~ODJQ_OnW1x-@5=Uv~#cV8nRT>dhZoc(x1 zS*VRmaB#tl1B@e^jR8P!C-Dhulx^MzzIRSKOdWuPz3-LR-Y0dic}E)iRWS{sFSbtE zq26*H(x-4GPe8f(p-)^$;yT1H@_`!CXqtQljHy!E0nL{$%yF>nT?96(1C1WGLO(ha ze3W(6Y=3z_EUz5xRDMapz2lf=DAQF%9B?vKmyp4^ds&jFP?d#sgpn@yQOPBL8zY-` zcxcy%){~UHmM7^c1{#qMyi6@=HV7)HW7hA4G{rJ@?V@U&*horKmeH*>y!?J5D{WL{ zvFoeQyNe7s1J$ukdUEI2D`Q|JETiepEp?A%=WU4-$*Ea@+lswaEjiqTFS*&ORvOtUH}!Ka zGEoLa!+ta9zS4Peb=_Y(29t<++5Yabdm{L>m&R5w%$7c22?ZTfx{I#ox5dxR0xo&u z%nZ^zhdK+3$-PLrVTs{^bn5G=(H~t}EgXh1QE?AOXjq(KU?v}EfGUrBeWC76NiuPQ z9#q@PZr!a8Y1(hh>8dVlWfpSS*?-L8=8(q`{e9rU8#MCsxV=a|DmPUp%lh?ZdsoI| zCI1tc2Qe9zF7SaojMV&@cqE{j20m||^9q3l*Q@;Sf~BmOMHVgKVJg&cU}Dz2t$5&4 zO=a%C@b=bGbv)g+C^3Q)+#v*aciF++-66O;1W$syy9E#KuEE{i-6hz@;r7n&eCK`l zjx)v??~U_r|GCHR>aMEQRco#_Yp#wUf2;J`L9HEgcN+#!*Y8i~;B2bR?O#qaY|wv! z?^|F4*Y6(&(D%r)b0VSKR5y#o`IJH{mSM_Q^veA~Bu`t(G(Jc73!$l49P4;NUGnx4 zt4ev+$Sz|3nE3YSE8UU)qkD1oRCluXp}HDnGHHAw$694m_P(FqmwO^f>ek3~EwqvZCA zrej%t;}{Y!{+L4Pz2g1>_a1EbaOQ^ADy_Zq(hFtmtkCz9`P{~_v9lrQCnFo`VdRcC z)kX$M!~t{B2VnrTFO><2zqiD~WpLQQ)O-J)L> zxFzrM7lxChr6W%&Tww$GI!0l`CZ@M;anK&B(u{ay1@DCOX{9pef64a`rXq~cAtZBp ztdFaSG^T%o237!{8WRJJ1tcTx<0C)YKQH?muh;>;*nOsLSh~72tlzmw zst#YxkfAT0`NuD)dv`Y#F;{$Fg02rvH_S!yW^_Y|vYC9G~F0`G? zWdNuyrcqLw-%{r+VTYc&LunsX5Z!uYl$r3Ih=GZ%@Ce)f8ztj#UudBc2kv!lzCWfv zv_I?#)(7q(Su1_URI1gl?625dXDr>8PuI*bwXW8$%$f!_6w}Jwj-^v{(mthErtZ2; z;7e5x95CYe@*}^gW>rlaD&rKhUufYIL1l3?kGer#!pbMREfXewnp{4|@7v055svnbt0TSXmTQVQ^=w!XNDDXe>)N{c8eS=fhc|cjSj+my z`@IQrh|}1(gu;s0J0S6d0AXLTYlPLR9VUIulrYg*_>6c+3yCD)(#3WX!e3wSqNcYs zZQhq8$F?MYx~t8~xa0<3?*r-&n*^WPwB?;x_3#gw5TXmgf&*il(~Rc1Elt}^b&_6u zn#V(Im~lLE{Jrk}lOO0qkWvL-^C8Y8TBbRRnd2OvGb7G$51~gJ!S!X+8C#kr^jacH zOPe9!{Xrmemc`T1)I2=Y;*3UqcNcenf7it$f4t`PF3aDXi4lFxl~-kAf~7#N!*A3j zj9kbIjRY3`y_=4W!__7W|7ZMt2~GMXJk}ICE81Mnm3BfIU{r++m~_+<(hXaDy9~+i z#+65Yg4{9*BO_=K;MbX&EUeWgqF9({%{&{oaK)F-<+8ObPkNNgdh&U=+~ttq{~YrM zKtdK7Yt{xLwBnGMk~Y zPb}Ab|MX9l514W~5 z78@tXOi8D(MU$6@i7dn5$mJNCC>dw4H?pi{T3gF|q((W0vH01@oNosYhlj#lP_4DJ zu}B!Rm6ORpH#;v*Cm9@`L9(mUp2koQD#m={;ivQ?yT?G-)+E&MdM@?78)1XM`6b#L zO{2bx2d7qMeyi0S#j}7SxY}8>jXysONzsPGt;(8fx6-wet)t~qP;I%?tUa2tO=T}_ znxfQJay$sQS-n^BzZ^XWa&Vd00MK)M0z+OaT~Tf%t~+SDARaR_&~TRm)XmRSN&pHu zQj;t;RLsF5$AcfbHj(@g|6#$aa8a-p1Y&HC1H4n` zjus>gto8y{P=P;3D4{x9ARv1%9b5TR8%-$P4N#T>joIr!b*;_VLTl_N`w2uiCm7-UVU$mJJ*eQ3hjO@^KwUSPaTN%PX?^3E&S) z%OsaD+0DjKYK^i@V-oSZ)tP$LUhh?tk)I#;9G@@s64Uag%uOU0h^V<=a58w${unm3 zuEwR$_<~m-c>HfC%zs;-3E)S_KW?t*jm@UB96X}tKLW3=PWaqI?%(%vy?X;j%O{=j5~Nw zw-?FE65zHN0j(}Y{zzI~rXlS=E9a+K@A?|LZ*dw6#+uMLcwByLK|lQ7+*R*ja<-Z< zR|d2RI3e*(fTgLO`B_hqhGqtk>X85Xn<)||Z0@S=kXDV6%*EteBRDf8ii`^`vmV}G0wFKZ~-q-P; zz!7BxJU|wr;|&yq?xFraDg_5oDiUQI^l|CkLXqjaAymVL1+ac$O~+p}o!n1wP`l9P zeiDS*O*&%1K*iLyCXt+0w0DpbC3lL&K&(-Aa=Yp9!xYDbEW!D?`dwg*Nx&4u z=e^LDShKTR_UYmpp{2^Fd_a?=9?PJd#0?8?Vt?Ka;FgL#u;EK|J;MMz^D+pPMxT~x z=Ecbj)QCqLZrrG0ETmm0Vt?`T$FdK)?dwQZwfKaD$dwDMlb*d~yq!F(!Ezo!Eysxo zT8FviRyAPu8s0*@$;$0n=YXiI(ce9b8c!|arB`W#%UqiN6${Wn9g8(RqxsSm zkjP1AnB{ucb~bi^Kj4chp4lIj64F*#`*=KM6o*Bbo=A!z^D`;n5YEk=0&svV>E>)W#IGIh9-S-STdVa-OEJ^=;>T4-Yderp;O+qoM9`DePvn zXTu)Gv9;;(Y9Pj2Dm^ZdlAQlM`ZGu_1qkmB9>SB6!KDwhosV~KCo4RonME|#R)QT2 zo)?PgB1->!!sM^j7o15RB2`4iT$f1=cMfrEG@ZYu%-ruu9{66T*E-pk84sRU$nh+1 z9Wd)_@=v6yB#qNaOwVv8JFdJk@6Gl#)|RkRPGXpo*VEDbdg`$C^}J;M0OhxLjYKi0 z>tonfgN^wS57S2Qm3e-QlJob;{th5qpRYj1<9PU^YGm>b>cQvfKW(nLA$uV-QL@(( zBd>9ge9>nxjV#(TC5No5FP&0GO6JPCkd~%o5~V#TXR;6-i{03`(s7@w z%nlyqm1>vUDkv@71ueMG_K{63c;JKZ+xL^FXB^+Z=vwDCB$#ZXwc3d|z!Vm@L>1WN zzA4~Ctv+Tt{r+?(OK+Cj(hZ+LkLg&e5~8HWhTy7LA&$K*L*)eUgR~lWjo~J=`CS!9 z!jL1vg0-rqFXh4K#pz?%ra!)#G;A&xdIhFZDOer0+XesbMkK-KHZ!4qagT2yRU-}y2~Ww~C75Pi zO`IMKy4z>Uj)2n6sz6N{Q%+&QJ<#iLjIpw6NJ_i8P1zt-WK}^xO`= zmfOlNikd`lLWzQ5>BdT#6`v!A!!FF*mNCi(i=9K6F?)O8Qpr-KS`?S#j4%OeY`ejm zd0Dyl-M_6K^5;!|21w{(;_!%g3$IS&MBolZ?!_-XSelcp8Vs-q{c7s;dKfyMP|5mb zu35>eic4I6C*dQNvU%S}%FnCo#m)0TA=X$@^jHwV)y7n5P?NK2RteJiPu2!cXl30B z=5E3Qn&w^ORIG1eNdB#TEnDvq8yli%X!1VmjAWll-_!&q%ZlY(FLj+!Q5~P#F~}nO z$+cG3U@RH>nfzXmCbUx3{yxZVk0G*2a9^S<7-PgI8^4c-6d7 zUKtlGY!%lprI1hIr3+#U4^;*?Qzee)Ku<5m=RaO1l< zG14m|+@d2Mc=v?5l;XL-HZrN|`yW-|FLp+Zk@N1}!C`Rvm->zQYe$d6bHx@-gOS$G zDu`hP@~q#bCFx0V>WrqtjxRN z^RA6U$>rylG||*)I9Z60oTI_IO_$=`puN8gR?TW*qpXVW`b)FOv~0rdPq_l}XAyGx zQF3#tVNI4gG$~;+)_!|CGO<}qvpUudWRj@>32AgCIaNz@#H3Ww@Hk1InKcz=E_7{d z?d!-$ZPVz8Mi?D*z~)Rn)$mik~iu$}S?{QjH3^9P=t)hQ_gT1}6CunQD^< zNSB!YJ>u}Yf9uL|9>MUql4^-XKi`agCV6<6{Egv(?sq9PZYP0VczAc)!ib>*+byr= zqg*pvq`>rvtzc7@%z@#J3+v`uPM4+2J;C8)VWa}f(~eV?jvVIAUxr-KST z>Bzv5d`_f?W3Cm=a%Y0~9c^~Mn(yvk0SONX+|&=N5_#RZap68)N4feoWz&hFLlm0b z->L6I$kJFow$|$nu=Hyy7u;D}nAp=0ZLDN$0!(3Y|2ypBF;!$%@^>dATZ*|X-zHlC z(95KbowFc~3&Hsad}%-9Wk(+3+rk~;cL5jjVX_nmZ3eH1 zJNGzO-;mmh<|r36x0jjYrL%(Aa1K+GGEzTnz3Kj*kt?#a?|IgHUzDP{*cWI~qHwe9 z9bQ%{_m;)Hya>@KTb;Dw8mGF(+*x!Jixzy6)|LJ*hJgBEYV3r{(fr(4SLY}QP5yC! zn7<$JAL*fq9-*KNIx_D zuzU(2!GwRpb7I>y#X|Ay_C8`J0ZVCD=nYytb!!~o~;vDJvo1{ zGslfAy*TNAhmf-*h|V)=gVfGpQ(d!z-n{eN9$*Gj5cdiblEKDrAf=s7=waw~%5Qj; zcKhoW7qUz}frQZY49!IfCWWQCCOQQYGfV95n6yUkbDdF2IR|_HNopOSTl4?q;PE@* z1DpDY@pi+NZ$=YeI>i0#BH`e<0x^@?6p#`iNkGmDGlfTej zL})jBS$*3Rxlm9ZUZ}ZuBKhAYm!TRAwZHpx_hwse<(u=%%BOLu?^Z$Z&%UYHlX*2LBwaV+5loj28Q4g##83@7R!C_VM5miCcA30G zBdu%DSas^0Hq1Sl%Z}M>ZbKuMrnb6w_E+Rx=V&WkgwDuX!u||Z+KZ-A?(RDymOVNP zk;{xOv|JH$>8J~M8PC&k#-~FrYbD$+)fe+4MLscLQ2OG*d z;joSJ_#wGEILkXiv1S~Lhr={`1m_5T*}}x`OMdE=u}&sCqk|0L4Iac)v7CaFwAHK^Ziai@i3zej_SiI;VLE+L5^m6a3p8*_ z16ka>8v_|OpT}}epCh9@M)~yb8(!?^`M$v7Fxd#SZ$IzhOmVyzs9;5T3>EPjF5Yn7 z98_EVjskA)c!FrsuKUGja}8+q@_~)#%sg%~@a8O+eU8_MJreDB`&V`es{>;H6df>3 ziCgkDGNhCzKc6X&rg5wkl#&BY*kuBW%}`gwFgwqYzBdiYW z{34fcZQeDm*&KTyt5YJ_6<}wOkg#IC1G&RaSWGYW@87Y53K1LccQ`KZVt!z&b6Ofu{vpM$g zT)rspZ+LL&0Xp=}^6!y(Qkb3L6=_kXr43lYfs^b^?orQcN}N(@Jv#iGY5TuD_yFla zpnWL6JzgJ44z|bFG`F*;B|$RVMtdh;ElUEbyS?Op#R70@Q!I!3I213v<$zwS>q2b1 z!alXBlg|tj=lWNL|8Z7~fdhQX&MBU;3RcX-ND=qe=}VB-&p6=k|727;dTHIYCtsv` zVV1HKuPRhGhP|gecae=~^&?~XH2=QQTi}hL>@&e}sRbY$l6fHl)idT(gU}Mu^x87N zuy=s@mgJk<1S!i(D@f*lfWNGP#Tw09~bH zCcO0GXV-YB->HI}`i#hIuOzdJI^MH&DV_aGj|1e%e=`%>1lOU)MhLi@21=2Siw@=t zIF_`D?Ky-RGQdCd{Q&It&2kHN<#m26Q@_i+FD84RoD-U#=FwBdH3^!52%q9y+t6s}c@bVj>f1`KbUIBLd?a0B0 zvL}2qhAEWqYkgF%_Z~m%nu9qJPIE~@>I?rmd5Re1-Mjz!Ybv%t0M#`}d?dBCjo$j> zLUBKffzhw7*Q+Y0-z%R+FT$(pEcz=Zh%Yl&+$ig%vnI`zx${a$P0!X`9t{9Nl*g>n zvCNl1)Nt#SK|VQ=3OP7}HgYMOr8sg|%gqn<6TdB{8y}v3EbG){I?XKk7!v(d%uCoK zoWFL-pN=H7yUWFT_WW4zQ_N+d-HQ9GAd zmXc>J`F&dpH}Lk*eSlHWhwh1;CUu00FOrxO{JOLnYwA0q>ts&pF| zALEXRnds{r+O8d?1?q!3#-)*B_z$*;(!C<-;8?rb_2Z} z%%ARQHkl;vCWJiNZl}O+LcndQ2no5;*B|fEmR4_9cGr9w^h9`nY~}v08#EKXx5Ps= zyGtZG<@W()@B%hQ4AJe=PHZlSTE?l3@wE4+%`k43@o=iamC==cURsS}xnXp>=QVJb zy^DT4gTA;a5N8dnnTzTJM@fMv6>bqO3~^CDD7qv(9&+Nid+QVZ$jj8I$AG!}^1T&3 zpK7t~+Lu-Z!U+}tM)tr2hMe>w5r@egN`Cs?#DT8xwfLZ zl|L|_Xb21fKV23qPJU#HeUsS#XR`|m`8x$^uK~26Xz}=bv3}?D$P(z;Z0P7nZ6tQt z!JojVH-PVb+hP>=NCx!M!XrtDm*-L28!b%#^=UaD@U$yU{@@x>~l zoOqgPFxBfyR`t&Tkt;vaR(>#2vG9>Gv9VD7K%Bxd))W|&N@ejId^+k-Bv@>_;5KwfdZ zX4@9$!%28W*miq)wmmXj@H$2yD+ z4WMkU2VJf0%!5DaK8#vY{oXEXYQ_-M?5J9^;4n*y$W-yzGmd7}6JL}4$%cOBxyNva z`x560K7HAisC?ecK<1CTD_u*XpTvK%dyqh+CxnPlA_C5ccG6B+dZ`$%Ab$|SA)DVJ zwL=HtqhP1_k8gf~OPWzta6X?b;Bg3tRuJ*S4*#SMO|IUO>&;v`aJ@7bpIQ4*h0|gD zBZi|X1BaUVbhNSD*_Bz6$VuobzWliUV280Y&g9D4yf&ju!C@@km0MUiG-WC*zGurx zt^VAr3G4Xffg&*J7Lf-jZvNgfJ`w-^t5-G=H=r2yk37G2V(m3J^^%J_K6uf927$Y3 z>hY~sljCW^Q7ul@4aI||uFxShkO69?)9ko zZ54+0=7Nfx97THzQPj-R9Df+@vTU@VPu*XZ62<44{24yLomy-f4Eb6`M=g^{H;d-f zuU+hyLA(Fqv0=n*eMai66>yeNwbM1$-`~fuwGIOG@qLndXcsO9v~VhGJkRvN%5a;i zZS|KYWW+&$PsZ5vccrevJ-fQ67kYDd$Vz2TDu}$f|10Leib|5l;iHHkudPny1>AsT z<%+oU$KsO{5fznOdAR_~pMm<*^YkS6gehlp@liDw%U(+yZI2toV$Diz?cd~Bpu<AvPX*1z>|y8f_IW0YOo2is#xPCt;+i$Yf#pX{b-JIf*Yy zmD8b6gFUNSKQCc0D4;=X8lg)T>f2FMEL>KpQu4g6(ja{_ug8-_X^qMYrU%LfLx15* z{Tf}|qp(rrhr%brhSm(DHPt^j>%_|@u?ooF+etUpsm6pq=c5%>y zby|l|)qU{~40k>hC)Q6YCyQQ*)nhtHeswgYprvS{7uA?=L2A!;e+EYnfCU`{nm)tE z`<>hz`N)+gW~o0hSUzZVM18~C`n9X_R2a|%+w3*|wDWz<(|wX%K`BA0#LZLU_`cK@ z9vvka)kRVw0^d*`@VEAV{N0?IXYePaBhaH>;+L4dyq)^I`uv_N`zVQuhPeD?+lWkP z?-s3_5NXJ!_;fqD#E(Pn7e&o}JA;Jx9T{MgSu6`dW}>ocR%S+~FaB;?8?OzIwf>Sv+Kcvx6cT)t@Jl=)PlbL_qi<}r z#IXfHuFWd8+4mwtz^m<_-zEg_18@{lDGOU-Ul|%oJ0*`h@?M0yvF~bo;bdFGp@8;@ z74yWQ`Xb5W_7gj13{y~emEl!CfC+m)CgdV= zKA@Npu=}GxxYuQ+d83-H-@^pzy4aCsr7S!E=vt)pnHI-#nS8A3a1hp402g=zQOG&` zhNe_swif(!8&yJ_!7mB$&6E=4IF`TmrKJwm{yN=|!Zdcy367Z>*OJWn>WI`scMO45 z+ao?_uJCb9GU&0DT_YTmGL(&OWT`--9WW3)pJ-}e^LX?U#k3*QC3eI4UNwKg;gQWji`Ffb zE7FE!HFn@v4_3I8+nB?J^;v|FWz=ZZqw}d z0{o@YhT_O-F>#>zb;7@(%;jVTb7Wdo+(ptEv^%ONJ(EQ^3M{u1$TMmtkr1XUG#) zAx~(Czq{>CO$jxcZYZQ#9U&Fg z$8%ToIZ(AYewpI9%og3#ljH$(W&=on9Qo}|`K&x&1Q6T4V6(^{t;x)@6g- z<4VmIiZ%yef_6TCdB)o&GnIHAEG5twje#Z5*Wr8z9OW4wNlrwI4_*@2pZ|2)(^LcI zO-eFGx1YGBN?-@Tq$|B@pxPbK11|`oVEkBIH+(ho`bKP4zOvo^20bR)sanOOdb>O! z(60OuAE7l8zAfbn32gTxOIeuvkk zR<*0sKVq?+_}G2%IqJ=nKCMfYnZaCmsnxz8wSHTMjUQL5>SDNtX0;I!3pQmh)u2DA z*5wg9MXevGrj*D}&Flv7FtBhzEG!2au&@sKN`;eM{}*PRTZZ~VnnFF=9KpR9zz8P1 ztMkVJlbDtA2!879dD!0_<2p`!U`TL`(REE_-7%Q~*{Tv6wxbpMBP8jB z+$?HzI)5qyi1eSDf|9P6YYz(yg78+s^oRDNlP?~ZYYVD52{qGNTGo2GDuxfQGAuB^x{oE?|X?&k>LqhWz=yoc-qZ%xfBiW!0bF1$=>)2}T} zO@;35m_KYf^r1jCtV!qN(UtZlU>aH$E37SBFei(jsqfb)2T23GSxD7JJDJ&08^fmT z?30(+H~wgESC4a54YhRA6P~=c0+N9xgxv-U|9^xJK=b3a6(NNR zPchQ=s6;B8#iGXu!JjAL$Fl|g93eor-#7x_D1D#(3eW~Ae#BBqgV^-pVrH==3{;r= zv6hOC5*FwPC89Z}&}?sM;V_`s`xR8cI{@Gi+5u(w>hlF$U2l>rBhzAaSXt{)p|D91 z0uriwuuMn7>>VA6IMI;UuP6cb4`i3aG6WePAM;JSY)sS?Zu;mIeu83zj@K(pVQ1^K z81e+WWbv)81M3Ak#7R)(9>pysXdP7def^{rZv6}Kb(n%xdPQlem&3Pl-S;&vE?8j! zIgl^|Fm1@p1vxUDi}95&z4nd3Xg1h<(3fu3)Y;nVBAVk8l%B(Dp{T)q2epq3nYxHF zru`EPK^l~=m*aH^>%Tj0HZ__9(aH98prQ1GAQstk#VK-iabd+)hXRGYrKzizaPl{e*9|hh<#iCe-y*h4>MfrUyhJ9=3ZUN zozo%&Y70VoNZ+}5#4hHP}c>~!VA=m%q znxo$oB9Ua5u2izLv!;H*)puXQcIb!&mfUA6=1eZMPji(^HS3wy7>%r+Y6ND)kMpTr zNiFIAJW49=Ut!JZJDLK7ol*Kq21`tv*~J5M&uCp}86K93?0}uP;|cOfGjej1dOv|% zBgFH8P}{=wc|eVa>!+ba-s{Db!Vqhkf&f2KD|+S+-=cSjC43YQ=j;PPY=$EU0zRPu z!~Nn22b#8;lJ_;I!oL8?xMzC*lZ1~4dG)jN)t?AjjHZqvL#@z`9G`DbpCtj8;XfXU z{Tw#u;(4wMN40wSo8~Cvd88NQt@In_?xw6_gZK*VgR}iP8RBUA1|h7(kTgtXd$0c_ zh7>8`6Rl{V_*ASgAGvtU6e*vD-(oD0&HW%DEME+JTea#TR^{V$DGnH_aO}Zus12?q z7tk-`0OtLhz<G#FwV8eLUqhPYyTFhJnbYXRG(S`L+y9U{x36i*jZXD~i#_ZVZVvX!nfZ$~0!*P1Bm z6$>ZLx5+eo`j5@h`sx|(&Y}Ba2LIL-yuBkUy}SKfnYN;H8c`7YIIfF)51{P!yMhvN z1HC~&{?Vjpo_}T_rbch_!pP@A+h5x_6TMRZ4#6N&g!P?|r>h(=4Pvwpf${A&IwpF$ zne8V}e8xdQ`uv6n;uYv4Xd-T*d)3R39{L5C8SZ$il^ca&y;- z;j{X*kP;M83e$aXw1p5@*M50Q=-j<1*Y*S)3NC(&<@$2I@?>Gqd!#id*Mkvk2j6;Z z))wG(&<#pvSHX@+OYYol28U{h4Dw4&62sz1fO~WAv)ip6n&vZbdZ-R`N@c9Etw-x_ z+AGVCi9^zN)p=hc+m{?+fr^;=tbb{jZ*vA8?3P}U?>x1@xoJE{lQggDvb5(6_Wc?R zVS6;c?7DNRARUm4cl<2-DMr|{?iV%%t2XT~){4+=??z)&7w=?E6&Ht_*_#`)PNf9b zz6zI~Hae}F0cvXFHSY>@x#W-Zd{jm-D$S742Y)~H6fVNB-vSLLjLMpox2c$bvA@+? zg3JT@<1K{}zL$L)G{;EV>4aFZRGs2x5@1J(1;%hIqx=R zTUXqwTDRqZx3j0C1&}htnP8;!^}M;P+?>DNv9%eaGVG?|e+G-Mx_C^<3mLa9e~jx6 z5z3Ag?C&W#_6*lcW91Z1`yeo{q50)3%48&vzzYc9Rq4gS_z8ONk!ghK+UqXZXIsk; zPP;G4@qQIHTvRc>h=7MP2jtWj?Wp?N7!pLiYt)7OP{j=8116M}ITMT!sKc{#l(P2K z6^bXYdHp2F?; z?OAQMVT9OTI+!pPXQ_z~v(ucLv#bB+B<3J^OJ!O&p|+rZoC8^u)KvVWyvn7tmxP_n zIwMKJ{J8ot)*YkiAZmIfHNn}HZwuvNF~Ky?tONmyk^8UzpD2(sUN_|#T^eWF9u|c( zrXK%M8DmgIQ$zqKIv13@-|#K!gLea|A0?7cdb~%Qpz+5aFqIXi@1ih+OoF&iFGVI{ zUgabpmoq5jw+W8GkdPAVXay(0V8?40Q$W>+D(oH87uBy>C7uk$;M_l!{$LmoKil`5 zCUHNh8*5v9+R>|b$>%rl6jih{-IL(!OTOL2^Qcw?s%We&F}?w6X#DF_0V-Tf=@8kf z$7Uqd1w9RF-_(^7q!*FunK#1?dgEl-X=?ik=w=&Xhi8kE1<9Z?f#G4SttEG;$w{dM zItvbhM9QswJc29cdih9c*ljh5!(kH3+`TMK8V<)-J!k&BHt5M>s8Zgr*HLPUlf9c6cWA+Csw2tP4v@wu--^Rq5MS81YbvxJK<~8>v%M;Gm zocjVrJ`F2LP|G~_dW3}mb9g|8B)~s}&*uwCU85=cF&<>|~YiY|ceu zZWF8|4B|gO+13$GMHx(Hc)G68tYM?B4h{17+#*Z$PpHkcxT*W|!nlfR)sQ*b3l0vd zAs44_3rO6f20tb2cG%_u3+0DCwed&Si<2JV@2p+|Zy&^>uIkx&dXwe7s;_;8sC(uA zT%Xm&&yyG&-^+}V69dImmu>L@l=p^3neh2)q$?B5q2=*aDElm+%zw;Q0>$=#DYdYF zH7>ce(4+HxD~ImI#v-yV*_#P`Z+_L~R>5b>%Pw24jw&se4JQeq(SUA3*IJDuv}%|R z>-9c5IhPjFc&-IL%SCCCRpfW~x#+LXlcLY}TV@Z+c_cRn`G`E{QD_mXR?a+=E@reO zUISKAZ_}?;R|`V`MBkRh0M`rH>wmR*kv}eZo8rNFXMTM2x_O%0eQ4WtVu^2NA!}|v zBYIdIs2jB%i?RYdY({DbhXry0Dvm%-W}V-F-dgVmHzbR>EcZWAT^*Qz$o2n!dHDZ| z{sL^ekn8`wLgjzeSRjC-u|E)`HE#81#?rUO)VaI9n_}ZKy2Eng+1kNNEM3+yPn8TT zu=d=l-8ugf-Ql|*4@eqoEM%?tER(QQRL`DqUFgP$?G>H41BI_zoXqwpd=`BMKI^0B z0QCo%2@&&}$r(!#oiQ$a;wcZqh16GgXuW2%Gk87pCY<4M!hgXU1jC|6x9ew9JYeI6 zv=7mjobfA`+3wev*{es5&jt1|;g!!Rr_)g@>`U{_5}h$5NJkv~Qa zB=S6=(;T`Dt%;u=6&KSa40cW!9!L3fP3E(3rP20V=;IZd*s%DZI(Tyw5XUcnba$)^ zA!aOMs_k*hVP`vYe=N!b)RWnf5dEG?rYQaS{lH}K4rhu8!u5mZTvD}pVd~Pv8ECOl)&Wa z2i5QYphwqdSDFt~2*xtMw7a5c)r89EFOt~*2^wJCuGV?9T9#nK{s{nW zgyfQw^G5TJC_5C<%j4p3PQ-Sx78#k!>d4nQTL&M}$fgmn^!U6UVXC*VjNbua0ChsG ztEn=Bk_W0gUweMV@6;}*2YFRFR=f62FHatol{NK#4BiYcpz1tL&`2USrv1wz`^T4r{GNMPhQTb~FS%`V@PHGY_~IpOk`$N3 ztadEJwQCP3Qi8i%D9`F>_D1o!G?g`N&yiC4tBK;|t~xOaQ9=1&!PNmDOx09R!vsD| zhE1+nJO){nl-&QQYnUQd$Y?leFK|gIsJd|RKb?!)|KW00$?R0UoOwJh zPM1=R8={WMkcJPxpeuFNj_G@rwJGKExX@N%`F8piD*nHCNx7g+Qx6g5tl^QP2 zeE}^(XeI&j&i)U8X62GOH9DINO+ud}$u=A4;LOBOO7dd{2HI!VcVrfQ#PU{I71g?j z`jtuZ9;>W9{Bc_JPdN>|AzcX~9`x4CDI<|1fRqb_kY=aGnDS#xEzgJ| zFV8eLkDRQBzb)g*{b0OzrhQ@M<@!5bGsWDO#Q7H7& zquGzoUu~UTsD*w3tZw;APVy(vFW(nR2O|~>!Tl?ZnEnB8G(H}m;uN}7UXS8IEjx-3 zL&Jhl|29wEy=;WcF){+Lnh%bSrDZIlnh?7G#dRgd2dWJDV<|lJkS2cO*gZVl^?_-0 z6<0tjW}*-yyizebN-f{Eu7(Q9C-0+c7^*lXT{@8{wOm@u_``h%53Hrh(8(Au`OT2k zT;C4ifk?*V%A!c3dj92F(h1u6xjwU6?^xSlbINDssW%2ILz4T-MApYxFogm20=7{3 zkmpi|$8g-0ZiKN8mXAT$XfgPGIA+d`E<_yBO~t;^#M{JTn}LLWNz$%molA-^JR6W7 zmXb`>L=Z(g+ep47p`vKlqXN`gdP02{sWC!mn(}vd**EDjSa{;TaD9niuriS5Q;a&n z4BVXGo!l}na(z{5S!{(EKAr{7tfxNiAxdyl_7qW1boa2fZ>x{pjkO9e zdeK*)7)sPRnh~G+V#TO~^d>G_Vgs4fSOV3kyl&|Jl0Uh=TR5una&|5U;O0xLM^jbxIj(Q)jx z&CS>lXWR~XBoDul?_|Q$`|PtAd>0upp>X-+etP|B?$hR+trwNV&#|@Ya%|tJNUE#1 z#F0Y71UXFVv{nXVlgXM5Xg%2yqlOv&bgxoy9MyU(J-=~&4I=oU5r*p@u@Tz+szu8b z=cw31)0~K?s8Y04*~MpOe-V%d0m@GA(aU^b&m7`XvA68Ys*@GN3 z|5*+oOmA7u9Sb#>Y~Kb3-f>cgpzEO%e#WybV(k@xY|lXurjx#1N*cpUT8 z@z5Y&xdpPU#^qHkD!I=T1;sJe<9Qwf!F;k+KLc;HQZ8dnb!|J@k*>SqbVmEmk!NYn ztync$Uhw52B4KCHZEl=jZZ3?^q__PX&DdG*N534xKrB|S`3V`gKrDQ;mnaJJ2JIRB z)SpUoObP~(K|9Vn(3;q69yV!uAUp%yIPM`&`>=+`xXyhH(qKKxbMkK9+&2~b<>(2b zbeXlBBMwEmi{jxo@NgLCKP~z&OC$~jIpjdq-Y1GboZ4*+iCx5=FZw9fRoJPAR&J9C&@7mKQ;S0{7P)VP ze-rd|vd+vbb!AB?X=?J2ahV)^I<)fl(!XcS5b!Q4Dzy9<-nX?s1oBL^CDLw_(J30| z$7gY!@YFSr_u9YvoK4sI(@9zNeFnsrg9OI)VUnbp=So?vJojqDFl_1E0;0g~J$E_` zEtjYDiTJgAqS38h@6)3b{%jT$zau!>XE=4cj8ETd4)yslzvg|vW4jQ4O&y=j>@zp< z*tMY1m?%$x|7O3VVY;KCtXaCNC+CIt$Sm8ugx{;gZuB?_qg_J3I3VD#YFW@=Q`$5~ zR{bhbZr6P*Bl#Bea;d-$!~X2aE=Qk1M=oSo^m5Q~W9_K4Nu-0?Q?_C;&Owa<29c@b z4msZ7?I_$^ACUnHzjw%w1OZD)MCVmcNBzJ95_cKJ01df`a`3@&Z!z z>BTu3*>yhg2(Vb9{P!$|_DdDuIPd>)0KwLcqwjS@p=-n7e!_p7*5RaRO|xA?@?=0E`K|>7 zAbojve=qD8i~#MsU}a%u*6Mai{_0zE-^z;Da)bS%VKS>C5^0>X#065oVWf~+wTzr~?EU!yt-5kh>lylM zHm{!BV##Gc0)B1`#LtD^I6cKgAs57b+t7D)PhNRT%)!9{KyDI91t|Rwv2UKDp=fh=*a4MZ?-(c!*quq+u4(=OPlqf>r!SWmYH6{SDCv= z4j0cv%e8Kw)~8!^24K9Q7#;q?4y4mKidD}$Slhcy4&L+bfONJ0Mc!LS#Sv~_q8%d; zJV0;=AwUQY!7V|9L$Kfkhla-8Lm!*`~#$u#*?{nlzzY(z^qy4gBJ?#<>%C7sKdb6wHYdjH(@d ztq9_e(Z0Uw+e6RKU%8v8&o42SwpbL^jiMQn!lZNF5uhz@_;h~Lw^uAHZN&Wn`FJHz zktafBO-M|VLqt8SpPY6G@7h+Gavyrlym0zC-rSt_9gMN+j4R$Gz(p=`xgAKsfZ>N+ z$uYlccCMkem2%#eVXmuPJm3l*qg7b7n+!QC-_F=b?@axOwPHsnmHPQ;0^i!&dg|DI zfq;D{knVR>^-R+@x-mw#zeze{4su?lUxw=FUdVmnW-}g~qRVPPyjy$;oa7&H1(qp( zdvireNv+`F@a_!eOhHX(EX-Z?u0+qDe{SyNC_3&g)!m^JU75s4-2oF0FC6U@x>@cF zXcIPCGx0uNUS{yW8{_1D7xiLtSHY>9w(zPrv&P$-I$eVq)&Xe}L*9-A#*vlqzqkNY zfZ1r89RzF%d&PI1SCvUK1D(Rskn^(`6g;-k7rS0in<~#hDKu+Kg$AbsO%66rvMZz3 zQibgv6lS-p;aCPjQq2juzYQ0&-d=`!V={-=IbBd!VQy+%U>r4lM8@~|-T8pqPWL&_ zvs9~GREYlJ)ZKyNj&Rrw%-=;S?XGywNgxg9uQ4^kyFl)j@myK~r(EJ$hqrgtEEl`K zl}Zp@7W~QG&++HQ^a_x>-Nw1k_}w%!^uc4yi4H5Bb!l3_?1D`6@6W`ly0(MhT)BWw zhc|41YiX|zmYf^nrdwv(_wKF@=Z~zf>-E{y&-Ut4ti3!UnMfmB8uyY8rZ3LuSqi3A_n$(J`u$;EcekY$BY=MyKw;Gyg=!B$tYiR(XeWGp zUT0vbyVa|5k+3$Ki&=&(0p0quEfFSl5$sLx5MA zh>fQmxSMZ-6I_rPo`;|_GGP4@QnCjAgJdZESl?AC;)?^bzu}yln9*F^Bif0@M#)WG6dpI*kl2Mk$>tY2F0odh6>`*mRR4w#{ii72PX(SR{( zVQI;}P;J_#J`g$bkWJ@_zFxYeOj@QsKlrIzT=kg|hz8aFO*q3BM|=FRlFNn8d>|A! z=qFPCM*q@}TUft~sURw>oAl++}%RL;2CMBo z$mh#_*kt`&sOBh_Qj0WcfdoJ{m`I&l60kX0xw)L8ieag+Bm$mua~-0G{bq|!?v~X{j1|R zsr5|B#N1R^;xA~qCh)5HA+IZLadnl)(82zgL)xOq+_mn&qk#}O;$zd<>8}kily926 zDvUPs@7I62VwgJ$&*Zr6l)Px{q=|t2-W(EQ>oLOYz`QuFKw$q11e+$uYR5{F9Y&nm z$%X_b?%=-Iz99F)P@_-HZU6NLt_JWv_&iMz zJm5_kJLr$Vu#RVXB2M^~?n?Mtk@bO(63h0&Jb)E0o~*%N$e4=mV?nB%-fhPJut5dQ zlL1p-HO^_lz?24$O}QhBXhE3B*OgWHQPy25*)q5IH4Z-%3N3_=PFPsNY+GeP^IoLf zVM|@4dmCLx$7KB|?`Kc4!Q);|4%o)nK5C1ryJLcH1iJyn_uc@)+yO`Qzj41bgQjuv zk;H0{JO71(Nm42!`p*{K-BHf3TwM>UXKWt>a(UE-giLU0O%}9L-jwxS(nRBkLj^8P z3U|Tm5>D-xCNw}=1Dp^(Pm_0AKIB9DzxC~r*9_<~SFDMgiYbo|a&6rYN-k9nv*)U0bI~5x%bcp3nq}HH35%jzIi<7qgk36wtGs#03u|BEn($z z_0_wIEeyP!0njc@Rncvlo2T>E9Vi9{m^tr{YvP>LN{k5O`(nCU9=R)FJ{Fcr z|Is-RC+4ZoRdZqIU7?O@OW2!_d>k31h~FSk)gz>(TgHa(R?PVkM^)dEbUyW^;~24} z4xy$J(c|jkf|R|sJ{Y-mci0xHdj)>G8BnvRH2`UxewKqNxnug1J210fY0*qzYF2}4 zqe$!}-oqIdNWHZdfBsjUagbKZtuLuLFy!7Khn)XRBpSap|J1KZ2EQ@gdbJ6{O+W#} ze>kHB>DzONc~Yp80^#jQ0&WNAel3};QHz(fe_LU`hNdaJWQ~_zp7p_QeweMn zB@F0c`QjDugJF;tQ33sL(bghBh7S>WK!>z@bF!uz7t@vw-L@tBlx@Z&jD@)3#gl5i z+RU^Ya`4VJdbL7ThK~OS$+Ko)>I*=Y4ATC~#3asdxF9!#`$S6euspIM^TjLR>aeS@ zm?tJJDwYJde)vNmRh2Fx$Sy6ffE2-ops$GZ^=Z5*e@q2Xrl#B;?dtD0wIPOAPApiU zv-hUZ;x$ihNsR4v(~(VJxVjz$k8aT1Th08CR-3qaMocFtF4QUd@s6MT!2g7Y%+kB2 z)CnJBXRu#Nf#WZ7f=7PO_=xJG?VzB_I|VG9XMmAx=YMDzSYV?w;|&59p6ML#50 zM+FA=y>H9qCoj2G%V1H+4R=^i%FF!@M_~7<(M=Lc%G>HbT!UJ~ykPq18_;|2`Ix)*Fq0`9%!V@JOueXumu7fMu_kdlw7awP3U%rDO^BT-HVl^>z{7+xrXKvs!aA$2&9uDdn5N>=)_@xRo}46|P0o zB~&XJ1lyeYSyozSx<&h?FT~={MnP3X*#Fh^_8vfgZkCK?ha(?K) za%9@;z1r##S$PsQUVE7IbSEwPZRDM;v4P!YN2bHn)f_|*cPRh(?_Xh^dJ9Q^-GkAx zA2@pHF1KSxuV3F}&ZgaPWgNElE}vJ-t)Z)5yPlbXUn!O%ujdQWnMm~itkXwfCn$C& z$WyCwH%e8dyWvKEIF}A&KM0Q68T;{d)uz{d^An>GcijjR?x?rDD8fnaIe!r`GDN|@yIZ- zjr-g-0NE-)zZ!$YzcOVt*fLAt%J`duOGn=0^gP9)p|{Vvf4siw66<{O?b|*;5R2KK zZxzfO5xjkbEB3=*kiny5pe8vmc8sX!5`X#j`ZpMA7U-kY z1$6`FI}oeDJ(mAPt>#g?wS);C8XkI4s+X{Z@Ur$S_zoCTx=@5VjlZ>++v1|Q21b5) z7xXITC6`p&1k1|`D1A(R{LkNy(bBT1U({FL?9jC6lAir6n5Z-NfA>necJrh#VIfb{ z{YbUyv4~UBrqhRSV(ZoWKmYI?i^sn8*vTH}$XcKpIv(c|WExz%S+Su32reLEK3zgO z`o9iFlSRT^>_%m_XmD>SzO6GHVmFrCU5)dG1)pQYT(FN?w>y+lKPbCU98Dc@eL(f) zt+Um&=ijloTUvLi_Z){eS594N(i>9_{FwsBQ0?o>!G~1l-W|XVO=zaflvGru_kiqjEi+qvkIJhcAJv!btkJRU~iw)N7pA z|B#lQ78Sa<9t1Q{0ev^=*t{fmH_CV0;9)8A)y)knv&gkhh=sSAY4Vw`fRXG=n~A*Z z|E9*sz2*JtTTO*$pb-%F0B~!4zvvwJ^gm82Z}lpGCCC3*BY->v=>)&u{Ugnh{4Ud%7+cF-%uRZ(nt}><*^@^YG&)8l{Fo`f!#XXzcmu@~b@# zb-BFZ+5PA%C*|*)?Y4(HO%%@9bm;|Rw8pjp^-j>r1jqR!Qi=I?9|Yd;y*f$>AM1#` zK8q{7($032ovFG~ZVCS!9U*d@;{U$Eput=>8U`?eug zR~^@24{}q>f$7AmLN={4SflbcBizZO>>F>1aqIYy zV^`wrl@Wz<*1Me#c#jgpTKshA)Xt=X^y;(&+y@qYQqWAf)ouTIV4DB(&(DB6r)5*5=LFT!Dmt?daU8qI@@s!lH+ zxF{;63PriJeO8|vi@8BIjp9w-OR zO0R%;!B!mrOk}JN8-CKdg=z}xr-u)!TM+rWcolqp57K@hu54*z7{6O>f|Pc*j~l$L zvjJV#&?ND{(RKets5MtaX+^#yzuCsklFqU9AfL3{Qw^Z+@p7J4qFsrq`^qv-n+=&b zyiB}UScjlcxHx~R=g@+91Nz|%!Tlu1mdlCq3I_#!Jq#`6?Uge)Rkwb%#u?juqIv?F zY`MmP7WvJX^i0>t>>$!q=$32GPd#tiGF!*EYRE@CDVEO;i2 zPDxt`P8Cv^%d@Wyz&qailjy%Qz6f%{ma+({=9nfPDVqVz(raBRo<(oplrt61cXTWuvsj%i!T%)&M-(6b0yRY?P-I2r{ zWhmp9$w(%xh6Pe0Sy?OA_zBKc17Ry@Cd=Z|F>0zb1T4k?R49u2X&#N>l zEkQZ@i;Wt2>62&QJbH($AvIch<@TKiCKnC(soB!t&h43)Ej7}&R#={wk=L&`a|Ood zl~x^hOdo*ed+xgxJrEg2#8J9dTsAhI-?&q{LpBV3BLqX!c5lWzy${9^!FG#y1$5Y) zx3h-A7d`!tWeX-WE#&;Na<|!+^UrW!=}nSI~F5pc=Ly)n1i*#V^S?iinG_O z@+Z6%)yq6?XY)-;zk3#PW<6z?s>5@80RlC=PJS)*7{p2(d#+MT5I|Nup+CP*bEofp z^SV%1$!2k6lGM9P4yOt-&9WzWdv;fykDK+ur}(4N!eXmr4`&^h!RRAmn0mdKh-La31T%zz6i+eEfS?!;N?>N zJtI7FyJ~G2u%pnQGUR8UPKoj4ul56yB3Y#FldG_!#a&TU zww<0nu{I6(^r(r6?n%ya7st@|U* zwm*CNP{=#hL^N3e7ZN_3fIufRkRA=>*ImvR;Tm7cRd=v30e!+eE z2=c4WJ5=5W5MV*HsL1hWoGklMRGy9C)B0Bt$T>d9X3M7e=8!KA9m#>ok|9srcb@Pw zz)6qoHw!VSn%oBOLK6i^z9Bu0??WHvge-NoG@}7;4Vu^okPkibEjdZFVSMZ}O_Bk; z2+_zFVG1)@`W5j*S(d-PAP_eeaN?J!bN~gzTBqP9*3kF5~&~K z$~GgutHDPGt-=-ldY@ZMvtuG>BUW28_Gh5H>~fX5}7y?!GIzNTr z*-D@wN}z*G*B5K6k%TjuLde7TTbHHn>yvhkK-^`^A|a1?ht|KCT5%;dlif4XVo?qK zmj|bhPJGu~WmY#A>x}%Wpcw@fwK51MM=6F~t#u*SbJ--|TJ@!oIGljvcQK-bQ74yS zw)Ez1+IC&mFK+zsdH}5r5wJNGphb@QVE47hyB zQyJk(tl6_y97p!&o1WHYn307sJn~a!sn_R8mNb4{R*pf^Af6hBTxRAA`HocuX9*(AdvfC}_o##wC6j$_CcL$NvCa+6L$gn$Ceq&JlW?aoc zvN&D9SvlmwZezDzPQ+oXbr}bZZu2joF#mt?Ex& zx?51Aj;EK2xSHTTon6di=Wu91chWYPSAB9(ZOE=1CzYs>+VGP+$z&LLvE}+fP(~H3 zb)gZgsu2U05}xglA55udXLQQE~2r^wKj=9*4%r zm`EM~Q;sq+56w-S(D7bXydhr1j6MF!*`rpxQ`xA;-}gI19W}K*C_@s*QNl@=fsSsF zJdf$}aj^nv(RkUUF+Nj2{9_2`MhqPv$w|R`)A`BAB4(dHD3atH@|8E^R4x1NF%y4| zgvs}(66ff*yp7}=oZUey3WQBFWyhcR(Y3mX8hxX8yus@)pd=c_Ey5O4Z>GlRrFAaRn1 zF%y{%ov>oM35G^v5`R)FL@(x_G+_Q5HR!f&h#AO~WE$6YM7QnjbfoZj>a{7oW}zsB>Znq}d+*ZSq0&5EknnSZh*6CkK~i zkM^LYzw)q!SgHj*!)iVED9njs=UsYAYQ#*K$?F4_7=N~Z6cUgxT5v&;2rI|;**fG) z(e*S?c|6zV^caC-yePuq|rnX%Mc8_4uTA0wl_vI7#IxsAHerD5-2#p&2x zWF*_8Tg$ppiy01tvdFf+!y|It!6ky_i$S>_y=q@uiCy%oWg0u#)67SCDoytV*(f|WVMrR*?Df!OKMgYFKF zc3VtLZ-$X=6HWE!dc+vm_gzY+F+V$I*Yy0Y(r7uFsbH<*M$9Cr!f*!WV}({_dhFqz z9kzT=tD*b)I43i|A){baXtDk{tR`S-f1+DxHI7;DPV7T&+#vIJ@OIXGG+B|%cG0Z! zdq&NM3k`JWSnBP%{x5YM1gkybYlY0%=8LLa8D>NsO=qsGSO1)GWVuEEv@w$}mi5|N zzpc7g!EwP>X^c8;as67UKq-I$uvUZsW6*p%{B*yO|MK^~Un(DI{kLQ@)vpXD`|`@X}N5aSAFTGO4x zj1aT>0S)IeBq~c@ACfZdV$@7ciohXHr)i#?oKkdL{5`sxRU86YE&Dz$9@|(oxB0BV z!Km*h$!>?zT6m1=Fv7gXUmRU|@l|gB;Gm+GV|E#$8GDk(QzR|F6QO9Iam}D(3Iaiq zteE3bO_I=LIc&->F$J1YZF6JS&;NaMR+J9Moiq=OrvF&TWN^y3Yc>agn1*!gD3?_Z z9Nb0(d`ZG0UVRbEI5NKDnIrvCv$Uw>HO&3&g4s5i@Nh68KbYfN(2ccrwkudY4&S-a zzG?HhW0%Z0KCu?o-o)CEKA5wrt*>XlRO}6Hi9?F*Mf2-Jz^a z-1bT+;E%PBU1o82F*)u#Q>dcCdkFI21;9IqsCdclL=SIO;O7hDAF}jQ6##G?A<4uX z@jCWlveKaY|8j{>j&JkK0F+|syAf2oI*%x`qdr_WGjKeH{4PG+2GcuMbVB06kV%< z&HICas@9`4=$EBe%_iKYCYpc06!K^fMwNQ3WH@B5S34{=9lVXkeE`aS4CFWO(}Sg? zun242XS^02J9s?dPxs=w#nE)6HEn|SLl#eHx>CFa_vPj6S%?i^J&tg&eL|{c;-J2J zpOq2b? z^Hlx=r6K$NZmHgz#OJL~B;z=65ZXIf-5=i_aPAUu%mFPV#mK`m;h74-LGxN3<2toe z=BfUg;hel}Z0d+y$MK3u`o7nfb@i6|A%W5L`fFELJNQxVbAo5gJF~6@I%!Zl!*qm` zWq$(~8=Lh-5OlIHyl>k4oS6eRWBkimyj@%jYD^6D1U|deAnWjs6KI8NDshNOQ5j!d zK?I&`sG2F&)6+U{x~V^jk*uW5tjJ=B!_OWEmV_H~gPQP>8EdUMCVf7|?e1IGfwgLf zbN#5KNU=dxJ#%tb3$Sdr6t&jmfwYrBw?j|Nd!4B|3{Urqu1ym{Qe`b&{xw9eOKUq~ z>%~X?+F{b;*Uu2|AL5D+GHg1!rD9^qrjHW4TqHD64{p7O}E@*W}+K|DdcozgQ38->Z!4<7%5KUIyLVoAb7Itjd?;8{HvK?K$A1 zPK2TLJ=(!lJI4*PMKd!6Godm;8jd%g+7A@oYIRK6ioI}mtyeQwc)GmUW0+ExNW^Pcm{4oZHFj);~g6 zvx>YI6HXpw^0iC`){xR=JM$^wOmL;6e`8HuVL@;kWJZXR6MrS_C|!IJ{QY6D6VTdF zWpVa>?r<4Z1Pv9h#HWH(?6B3zqYRlo-*GKI_pJFSYMNl(ZH3l!@v#_4_?DxI9~GqQ(VPxDYXmH;FcQ42 zV*(O3`dLpfNEqLkQ*)_e51pyy_$SnQiVKi4ofF8q&7B}nkf z)RsHZF;B=-b+xQ==;^$Hn#C_uTuqWA8pm>8^CfQ9wsP1hM|Zi%m^cL#4NvtB>9`!W zT+`S`g%s49%XYv0+r#R@zg^#ocu1Mb%I&>WYbgp=rMV<}0y-bMSL!}cXiaur53Ova zy+J);pIWhTjNTJm)YU!T=QtDlIq%>wsvZrULSvHH^FV|}xnr-qVD>&tc#~dpy8fM@ zTZhu6wbvDWh*=|FYlac7BXAfIU$xlWDRWMt)t)ZstA!eNBk~*uJ|o8ojQ z(G>c$G$PY1UO9tz{&;p;HhYQ_MwL6sDM?i5t{3oYsA z)n=*&JP-F1*j6z>AUtH9*W9H3+2bz$#@o>(Yw`lz;b-G43fv*_@3*aTi>%_^Ue=Yy zJ(AV)=*@ukM8XsrZ&vxUFawHtB&FEsd z+wtd^c-6YM{6Zqz*V|E|k}Rh`0-__IPG-QM5}D0S=$HgoJq1`wMMkTP@ScPed_pRx zQLUcvluD-_v?wOG!NV4sf*_IQ3i4^s5#Lc&UmrbYp3a?&yS$ zp}+}ylA)V}`-M?^nk}kH{WxUrq_&HBwT;*%pUYlKb1&f$(?mBwb|IS{_=pfjMUpW) zoK@enZH3rgCSoI4V$iW`qbug|7l_-pWFqb8PeFGuQkr>iq(eO6B1OUZ!8 zyVSWvyN`59b~)FPK2UzU-1*rhQIzlYswLym09Tu#r)R7zFXABQUkIo9R0!o{=(L>glCvC?Q&of2t^X4&@#x5u!?HF# z^iky2PAqjvLIT1*=V&!YLuU{u{vDD9 zLyIUU1BmtkTvrr{XAp(7OvoHek_0klEL+!SG<2Z8To#1D|C2+}+?iA!`+~-Sau$|9 zIk?4PY(4oC|MR;IYB@KN?<6)o)tlIj)&Rbg)KFHPETOy7rck0Z#Inq&V;dAJ>S^Ux z8{Dxu3T$@zU56mcIy9Q)8c#lR?8N^;gxZ#aQ*AtT@UWAq3OOD|_tY+A_?Iz~n- zV#&@$%m3oV3p!jNPo>4K2j~mgko>H?53)TyvWmO(xxrx^TYslD4e=rybbmrrg2?LF zm?xjhbNl@Fa71?z`nptl z#`jDQ^MC{`WQW{wcm1N=(52G!w=s>fa?DU(RJgp}r`&BxgYd#U|1@5`-D!0~4i=6n zCDq|>_RRc0dCf^bQ(BxDxNHFoMN4WH0M}xVd+ijPwznTdk(0!o*yQ-mxW(xnAHPXvd1ea2k}1#oAr84+LQt@JqP5QclaUM+Ol zKX~5Isb*`YFu(hC*^1}%U~r}-G@OuRM$S}dQk}De=1A%2Xswz-7!qr`^1nlwRnY!} zB*Xqn)};O`*XCd$bA@CP-%?E9hx~Ij(ycHY{7b9#!wCv`VPJG0;$M+v2jIY?k?r>vprq934!!W-%*iYs#MD z^8-OS38U43&|osa4?IfK$aIfV3>!s#rUU*Hv!#h}`!D+AE1m#{|Ii+%;RxafAQhyY zVFbPgxikW%q|`0i*Mqa4wB)J=;2IA~tI}&@K@f25auzr!gz3BUw!PTeEG)0OsbS41 ziTNMk!O4Dm)6q2n4)8@6-;(`f$Bx{80xB>B1jN858xI$WgARg#yjgcJxq*x3LC16Z z+1>Cy{@x3%F^QC`eSEz-w+0P`q_ofPM{MoZ_z84GTYmRN#x(K?a}55b(OavjzY61W zS=M~YpP52VN>#g=A4VxOyZqd>r{#pS{F_?Upuy0_AK2ke$=UvufarU!5L%`nfgW5Imcl|N-5@-sVs3(g>YfTJNN{(i?JbFT*t$xS7Hs zJT=~WR>4}7hO3j07ZUP!>4PA=*N9Fh(T*U_{BifQoq}}(Jkmvj_8a#~yd@Uh0s2vKEBLAX8}+n=Xl51$C3`F8H5mV ztiQW*nQ4wk;u*%M`e*PB)n2?6GqtKK*1wJMjB$F$=3k6ut$!tNokCsW?Mh}v;i;+e z?eiXv!$z!)?hokxu8Fmg34+XeG#!Qe0jMbysoOgalYCMWyq;BUmh8(Dw2p(i%*xS) zO;#3YHEQ(mcb}=qv0@!Wm`@(;PPIzr#YFnUdiuObBH8i8v?k4K#y*TnGJN7Tg|n-d zz5gfzhS&7eTaFb~(#CmF z3@KGFXzemVjN37nD5|@c|BNCk%#Y4_a2~YJ=NEQ{W?<8Z_e8CRYx5is?ed}>lhSl{ zOH&xZVSV)JwXIHu^0r?B2B)=kTzBoT8>)aXhb)$>SY=y8bv%`nSYH#|Ry!1|gD2Rt z>`0qB;}qvSQEemWnl$TcYoJ#pGZH|0ylj#nzmMAdXZe=>c-uwbEl!Ybl@=NJB4d2x z7$p@ax&ER57M&{(rFHw~m#>S*Nwss=@g{=~>dJyZdYF}y!T9;uR?c;)bc5|&&ZX0u zmxN&Yu345sO+sDgvUcqf+RT%Qh0XPh#g>b(p*)CX4hR$#Ff9+59J6KqG9>p`aR<`t z^#_r<2BV}M+B<*@spMXZI`9ZvlF4}Tl~b{Xg|m{lrgbuflusP23Xq_uWzV~9$Sr6d zqHaTlcs~ck7MXs4*w~TOmqlr?`4sb{E0&sx;?y*fYS+K zghPHx5tmu7I-rFi06hO?B)bywJ1GIi7i@v$Rkx;3V9cV!zF6d$0qgHf3R$355MIF& zm_A9UNqBKVjKDEuD+~G(3=JJBABNY>s7lDI{oY!n>2xs;0j}+tLO@#qMzH*Dinp#> z-GCzC1}NTj*jkE$A5MHL*mhlQvaI{6HIkGeiO4tj#DKD|YR9R{>4I0LJb~3FnX~q} zt}?GVV7QLPUdq7q;sUF9-L}>>lULjHN7yjB6E~M0$mh>{q=;9wFpd+Mxyb_CT4U<} zJ=N-6zj*NJWMOjzsP;s1yQQ+#B-55Uwb^&kogZ+<{+7=od^^2mbk5~E^#>4fnZr+_ zL@!m_lhWwb_>Kgi#gTHt@{6QGYuJgMI$))3NSS1uz>RFO+D~_4CiNoC?Mezka#)7T z(p~y^VAv^^seXN3A=I(&YW#ZkZ0xZcF(%xwmw*~yW1egNzmJ;(zIc?J!ro!9!zB~m zmu{9TFF*D`l*e>%fF+7NO%~9<(lP zwtC*PXb^jYwEErT0eabKZcx<&1P{Nrr>&a7W8S2EY)T%Wu^(sPe~Oua8Z?i-Vt%N` z0+;0?tytc&cX+3wnw$%76D@?jJdI9d3IMB>40X2$9R$J)!IAN zW8h-`=AFK2lR`^sANr+C4s}9PRD!FyYT2W)B4+wsuQi`hPR5dr|47OEaZ{Z4@)jRn zrAApH(CU72n-(Ip$*hY7Zsi?=l?M_S4>l4u%sWn}AQ2c+HSPX-{Xa&P)g-{fHHMuG z({%tT5{0ZTzqyLXuc=khW&hlf9Il&Ue9CB%zZakITYxaN1`roI(^GP4&%d=WZ7q^J z4O)i1Tdyl5=#=hvc9E1V;mWJ=WiR`LDY8^krmQ9kk@_N$jF?vOtUETU56-aL(@WEZ znJQSZ@NaPTF-=BJH>}+pIeAKV`T5sjO5)A_iwh`h|Cx}Gu~)C+b#0{8I|OyL@2x9u z$T%LjSp8y*hX8W@Y{v9StBQDs-MsKKZ7xQ7BrRaUa!(7aKn)yX3$8~m5&~(})HVdF zoaY8numSFXh?mB?Pq&f&Xs9n-lYLi9xOibHg+O{kg0SkinRE5XT_|sdd`q>huRX3n zL*pj|pFGqNelD0{QpanR+O7(P)%qLP^vi2`>ipN8Pg9zP17o=?&lu3I=$yG2YOv-ftNI zxWPv*sZiuqs+dk}JI4qPb0|HEY^R-`kbC2*95Sg|bJfp(yYCgsm7{-~+q3Fo_^GU~ za&Ol8RAu-YlXMS$n0is{JSU_-+y~c+{srqG*#~&ivd_@7*(z)yq|Yg zxbL>cy&3auT{Jovhzz@Z`+rq6Pg%vM7^uC-=IECichXF9@AM*|Owg!v3rzpx(0S@C z@6>Kgo8ThoE4?8bxbQWzhxnsqk<(Lg+Qa~>@;a)H-m^-+hb#QZyq{ZAe1F_Ky)QB~ zckfU6Nk}PwSsbaO2-rP;I=`+iAATwNpv{`)%t=#0u-Vd{*GCUGrRMWo?(PhB@?XiZst+yKa)qD^yoq%x+X2Lw1{B zDo+?Tvtm)60-MM$7YoPIy2k=`2}*H1ETVI|US+j4uyNb0%DORdR|xn1KLEv&Wb{<< z`feGltu%+M>{;Kc+xIVOwaKWCj7tYjTIJy63(`dnCPb}r&g3(GW_7YZoA{_BLHB;1 z^kPL1%OB&!0Xrmzh6uVJ%~E1qg?+ihI(PnVToL^{rzkADI+xu29(V5B{Yyy`RnIeW zZVhr=H?qG6a}1ZUv*Wc4=HmiZ#q>YeAfI)!T*9(4J4}gYwG|x0&eZO$6BGpt@wC5N zPyyk(n8bBQm>*sVyBR;mrRxk`3U$4gI5C@dHta`s+|NF?4(xYImX^el!7XU(7oj9M| zIHP_khxJJ4&Wcs4t)6i&&YKy_d8vk(U~VzeV>9+VUEQ4Fe1(vp`J~ScOPETu2t#}9 z>Azy>qNvEaZsw%TN4cSj`6+#ba8&=8E8fmOk zvrh4AV;%r-4#_y{YZT^WTlV*z^;pz4R**d6f8-RHUGX{gw~L`P1Tqs!Ct?i_mHT+< z_Q7pl;_E#rz^sS!dA6v(7p_udw~Wd5f?D`Ay0s?J3QP2I{OHrUnpTwi^#yFY&`F4w zu06Ld;z>g355KpxQ(*9R059*MYT3UWHdwB7?AZV+ihr$sq%Eh4iTGw|>=!8CU+Q9| zT5v0{i~iJfC+`j{9>?o_)6wD(tVCC3!qpk?S18>&Tvk5xbvmmrnFt=7eh949l6{V3 z0N4jdN4GOrqN*;A|Ku&!g@&(gbWJa;<6<~u){(EchgZiD3SIXK;=bk~*Eu0DE_51H zayP;zD7x)fIupYJ`a`;!)X+Z?~T za@_)Fp;uTx#Cy1f!RcdD!<6I|^s})2fP|wLzjeyG&oGX;$ga-KAPXIUfU}#;k+z** zyGVZLFX}q|_OyQIuU5UoWUCCu;f1u`T2^pQH>sP(%hyMBky)^H`j zAm#^?iJN*yjlJ3QpUWfNYkn-!@i_9_9OYkUt<@mckG(`L%{_lBMq{TCW44=A>5KFA zvdbc~UsLMWv|ns20XUUmQ5MM*wtxKGQrEx!SrG?xz4hsi^Q}a!V4hzXD%3SljY;S2?-iox!|Ex#|lv z@DeX(JmgNct``(r#p?sT_N{~})ULyFNkC;YoW$uw zXku&nnfv*)Us|eprW-x;9S zizj&qH!4(TK_}#4i{-ffImx`xdE20H8yCcyRO%Vh<|pog+wyzEwBypiOv5K?YXbw* z{)Fk1d;UEqYXU;}#SWF$Q1vy-g&ydYy3aVJHIA5Y<~;AwF}Z+xQCuwrrv%ag8H?gN z(u}Xg)G8U+j&UGq$u~(+yEEV6tUrSAK#6nHOPq5{@omc0z~ODI;(|JSpqkh(fbL>kUQm;KMtq>OyT^h1sFH(e z&juAA$b2_$6ZNE-I#m4UvrG+*A(z!P>Pco$Zt=^)a@BA5~; zhq7~ulJZp-Tg&Tvw$;d59r10ZLayQcLP)SUv05fM(d(U8oJDx6+ zulThIV$Y1=u{>@+swg1VwbKJ!-2(9A`~ zs}i?+5&@D<51kgsV-$Z{+gP}tZLi?#5CIvA7c{J~xlYhn+D;2R4~O^_h+ob(-h7do zvR~@B?PW4PHMUC)Ns_Erd?ht)nsh!DE1@bLBaE3t<>GhX6SQMHXNR>{{o)Dm2o4brE zfSjRZ0$l!kSf8ZvMUxY=4i>q zeaMdKk@>8j#CGWM2c`X*VPPbv#9+2rS;d zTWjPbrpF0d^k}Dedg&M?`3ChgTo zw?ZEoI-e<>}r1j%*6Rffqy?HWmp_hFLjw2^PGj2+s}E4xV)T{qb$cPFoy&GP zh+?2OEh}>I4834GQKe^$3rQCYs6f1VG(O5Kgm&J_&wJ*uSD37fIlOUvVVw z@s*^PlSeVuY})s&LW}!qZc9s}YWJr2nTVj-NGRlFBs`tGp;Q0j50%aPQrEk zbpXX;Q;D;WOy&3d0E^4Z@DdGb3y*KLV=bBcJ51`UcQG}_LaufVQXLI33oC|<}qld5TEWZEHg;jpVWerRb!}jo90GkWi5o_?AgcCu0v{D6Ja=|GSfDiv?;1+`aTr%E3r7Q9L-)@P zX|xR5&dDg=nOUJCVJ`fRy}f|GYa~SLyKa|1g`&3oYnMkIHf`b@{aXuPa|K4MokKdA zBHyU)rY(8@ggAQ-x-?+f@fGPD6faNwa#q$$Y9f!>{u?@Y8EAW$W*Me^f3)W}e=>bm z<{Vd~6l+1bEOa|<&yOSAcuk*@)O`aay8Z&k9PVv=)3Ybw_3YwZ!e(hP64T&s0=;?i zZws=Eg4Wz*I5>o2j^{6$mWJ2|{0c2{h5jB+c@(uE8Lu~T-`h3vkme$<~U zMHS_rk3|APQ6HDF=X?e`k4uU6sD*BB2Wd+gn&gKSAGK&rnxO2+w~ZHJtO4@fx?qjqYvguWJSDG5+%^{k~uw7uF+kgQSUF0S!7I;4^4 zvy&`$N-kS48aDn=hF_sFXV1m?$&OYqGsa^KA$BVogZw4X>;TaBzTWzb7>PJPFRu+bBBn=k@ccwn<|T3`Nl z>@qg@-qoM4%Le&AE;!Te+P0A!IjADbZ)R1Op7q+cACSfA^Mk`H*Nk@b#?*lux_;Rx z=pb^s@ffiL_ICx zb_ts=m&ZrccA7HB_?iTtx^Hu$oD6sNv+srg*oGo*M24YOFkLCFRoj`0`%wGB>mKb> zwco~^)W&Irk18)BxwDJHsE4GSCacD*pC48mY|ui-PA8C3EzhxwTVn)%;*R~rSu?rp zvvrxW$WTf2OvN*i*|JYIdHJF`_mbA|#;Ho{9m&Olu;AAp=LWfg_QiGO(RT&ukRGP? zDFv@BI}@&FZv)!6_ApD^!u%@IU$z^L6}xgverxvgE-}Y!G@cwweShbZ*oqJ(9+c)N zt>N(pKWbcL3b6c~84$?qa6jgJ^b1?QYQ~o9I+r>>xm|+<8{|E`WKvkGzOZwF7 zPA0XIC(9Hbf0+%dq5H|6;zNgiJ@7V_t2*rp@#Vh3_`V)yxoOjY4-R=xV+7Sn`%@&y z;PH)PPLijUK5tLPi(w^v%^SM`7e9N(rq7kgBj87uGALrR3}JnsSBi@F5GN3PKF~p@ zuMsn!86Cl=%6$I%9XH?UwxVK}k>JN?4_Ci)1fVX)8aM&KM-X=fi}$=<9?WJcFd4vmYJZ*3oR>W-%^O|LCE?WH_FV_}=slaXXW2Yt zPoTmGe9P!Spj%RL`)6r?weebz+i5H(k^bxHxnF*jBC$0Wd(*&fp+(G$fs5v?y~~&r zWCOCl&}96xPWURmu|L@P`sk?kg7a?_+0aiafl8;9{-IPZ$*WX%@#G}0eZsY_%Pn|u zKs4v_CTiC2jvPKP8dk4&4Tl@&AZPJhv##rYq1dh?r~+TM^M7S}`wN!fUgBTXFu*sd z3_n4gY7WJL`%zkWx?{?IFmmMz`1YE`Dvo9bIdp1n{rt<=@M3=byIT8gl3V*ih+MT? zd;Np!Iz)8*cR^3Qs@*VD@Uxv_LxIdj+Z;L{$3Dc>atYNnv1Hvi${^ixuko_@M@g~L z_Y1+DRT~t&V^rJ6j@~I}nXA!;&SCTLZzqx{Vg{=pH0zM}#R5xYK*oR#<43}s4C$6`*C>#qN!%eJ=Sy^UgQMa9qf#2})zCoqYx{Slpo^!` z*Z;wvH0trx|DHQ!3^8SdSi~Qz&I=e8pBezq2%5hK2sHHdKNSfjqr*9f-}=shrB(Zk9(DyRr;*7}qQJ zmEXc=IBC4_CC`lT(@b;ACC21id&uKHC!vSucpq?KNT205>E%onHe5l@Q!m3~Qv;G9 z0TP&8xDyeYY8?6qB>1ZB()Pcbb=}pLPvlBV83eAte#$qaey(GFe_R3$C3moySA_mw zHW&%*yXdI-^ZTg5_cb}^sBN!Rsq9pigrB^);xG$!V{y*A?Tb}Us>KTtR9{Ni9vScf zSBj(o4&xxnMOI0dSEbk4gi^O$C|bshdghzftaba8oB-9ws*JY{$$lq&8Q)^I_X7%S z-Jf0c?A-;kqBNAGE?=PhdDDE~wru0XIfxUn9b_M&I5JTibgILSs22o_#`&}MdCNDg zmq}t4E#qTOviylqr9{s=rJK9v&dK=(nc6>D5biRxd(62D9RWMLg2|F&83qUXs_p9k z`lbjoo;>DtRZZAzet&Slz{SQPB4fx#{$^}jL`XQ(FX2tSPP2oR1^~~62p_@_T)4gc z;d1%ZN*3DZ;~DlDqpQmnRD$vjE37*NvTqMBZ4~=|Pcflse1UB(f)2P#2-jZ_NV=Yn z=;lk`7;1g>31FYr;A#u_0iINpFgu+n@K>9mIEjP~wcSZbE^RKiPCM-vVhMB37b4?q z6p}^*UC-maiG=A@9PKD+dyPG`5ZhnEt0z}jqOMoS=`${rnH~Vk{9iA7K#n-pEm^UQ zhOy-51R_DrUxUVlFTs~>?sBEaJE{xXW&-A4eLj#`lbv2ePW@1{VkvzFN_)_eANm^h z|Ah}V)z40qC+OPhv~4MbgiA-|fae1=1=)k3pxuw70Vl6u;$-*9-S~YAWrH2%t~X*H zU}xABZ903!>t*Z}m*0kJXCyWaJ*8F+i^ta;pJW&cpWw~8+7>XbcP@3baXK53(%C>S zP!LrFkTncy{6LJ-hN4UfdbXS^*GGyEkpyg*UHrPQGX)SEk=(kPo9~AjxB!?ve-{%aQ~dtg3@w@w8{ZVe?u=sumXSH(o=Sa-$*G;+26APckdS#LU5nLo z|GSqE#B#s_yxhQXE~7Tm&^!-%t9GEnBnUnks5P3T?U9fB8?L@B`@Z$oxr!I*MKs1<$v9|*sH_y6BW&Hs--90OWiE#y`?b6Gwc;`#Yt4ro{Z zV;xFOD+l6{K21Q-BNrwP6Rsre(<{UZhsAt=w>c7_;d|-(QtnMIE}iuB8`j{l?Bh9sdMVKDSG=^?0H z#VG6}Vva*JbK~813!rw6EYLcq2|r38q>!$wK_k${_)9TXWRgS?okztPaK|$R24$uuHxQ4|ez(<^gGC_us{7lC< z@Hf0)fNu&$XYc@o)YJ%A<6urG;t*}sOi?`EJME>n7$(gAQpq@&bjb0v4eI(`C-nRqQI<# z(S0z27*XjBM`t~s^w}li z030hX8cu4A(*ZJ)GPG#lZwmVe5X7ix+iy)Wa4-OV3bd`K@lw^E>|RG*j~O}EfBxQa z?qReF11P;gqyZ=54S;1;&>g%>D9QP;y-HvdQUB!&$j44!nvwi;tq$Bl`tJ^$FbvQ* zH90>pL{la7JKGpy<5X^{W&l}2J{4Zvx8TPMn1EK)X=jCW_i9FU>&VX z%1|@Z!iKQg){~egqbS66_OFiDSQbRw1pxOcBYF|vi-dj$`tH~%ayImaPaQadC?u>$1Mp5p`4aT@EMf)-kg#`RF z0Cxa>@DUcWv>>8v(S1}go~uwK_Quen_j5TP{inM3LPLC7VRAW5K#+aa0Rt=a>x z1}&J6B?Y;>0(DxNWDM zqAe^MMr^l39LSAH-8zJfFTF%d+9 zbZ{9zW_~!Tk)b{N_$>YXMo=0JW3dbreD{&qyvS)?D<`1@TJ|y}sxFz7R7G`@f>G;< zhr34KJ94_=!Cd%2qH=<-MYsVCjA@h}hec4uB$WFqIclc=sq1Pq!B8q*)mKs?MavB{ zKZ0iYEiCRc)+lYNH+x&!0~~{KjKso!Xw+=)i1=A_6+=Vx)PjJ~v$xB!|DsRJ%6=hS z&j`b}iO$D%wSG&{sk3rT1Efizn?&fSMDX`#N>>*DSvO5}6DwIP|AbeNkDK^%|L^E1 zqBK7OxBAqStjETthuZc=MJ<4Hz*T~WHBRN*1T1g1dhn0|nnfz#NHi%wssz(zE~h;x zg~jBI=tAV!6k$^HB|l|eWn~Q|(kULMR$AinywSo?cgee%TBSDMlniE@vrg6etP-7q zT4!5(DYnzkc=d{PR@L?{fNRbxhtf|WkX7Do+=f20Is8B=pMP&&sYlbgdG!42!ZH(&)8i z@#3;z4`pH$uds%KljG6Ix>sM^ zR%j6)63cz!Om>ffnw!a4l{S(}`W7W)F{D<92+V}JRVh}lFOWSJJOaI5KQE~b?~ZPI zXP|y+1&b_+F>BhPwO=Q*`@is*lU%zcabiJj!mkc(*uIWHU%F@&8&Htt1 z)1*CV#SkRvsu2^Q0n2)HFUVKXM3`JMbcN}6eIY?oW++y8DBSd22&HE8=;s_OXuH2W z_6sFPl&Elq*pCpO!T~b#`(VZnXKWm5<-S-!~`F zU%%R;_uX*KH$iSYyZvJQe02@jQcMKsT?=iqD>& zZrL`sFkY?8#rwimFSZc96<(sPJ2>2nu!2I2K^&thuavTuK9gj^$7(dOb!#}3wQDJI ztH7u{Hq_u7!6^jE;Z)Aa2_fS+kABzR)E{H9u|Ut`;%hp_Z%>Wbbn~* zG1s5Qw~@S!!!hzDPkW82v>yj+Dtu><@Mihp#W-XJ@i^k@aeO4So9lRi;x0eQ_N z1{802|7a^cYQyQP`<}4&ZL8-1Xwppz^dJt3_R-X861~cD&kt=UVkWSHX<0P-N3BF* zMMIUD@|&Luc%_a#<8!u)$mt{(YS7fXk6B(9*fJxtw&<1zv=Ofxy~1ej8xEl!)aF9r z-r(;wu{BnIpkHX4I4GWwK0WT|6vvDb^CuxnKVYjjTB9{$FXlUE_PX3oCA*?KEqgQ! z#axWxQi@Hqi(39}==hqFKd|e=GOj_JbHBN8N@Icimw)M`L8bph3og)rAm()%<;HnZ zVKN5XQPV)DVI*^_q(;73MXg|geYFf2I&*9&DNkM+SNI)~e}K-s-?ukLB?VGbgN+cv z8&{6xL;YoWa)Wga%E*Lci@-d5o2<5Vk`4Q*XVK~Qs}(MD@2|vl9FzQn_m9KnkOQ;w zDdan$zLYacOk$9PVQ}HG+V06u(WE!4$1xLp!*~bWRU6@CD}V9`%C=)%Yzv)fUJ={_ zl6GAZ!@^lXJfiQs87frGlu3F*G z0lvn<18$K404(tM{8J;b+45Qd^zct%C=*vt!4QsxZ}9=cOh(sdlreb-uV~o@?Zoc? zSVT95(MA(%mi3-pXgRS1Xoa!bm_h;z;HUYAJF>%m0)&tJ11$`Y`{SiOQIhEQlt?~Yz+mO8YC=uHk_bwHwX~3 zpjCxqVQNND`rDf``I%ufdV7Ed!z7E~%j{U->0#^k`8nKxlyF4TQ%ZmSz|Q!W4S;(H z=1T``^q zE}ijB1&od_KElPqM8NM0%NLIq!D5nI48SK`Q4UA*)@mN_*vyMcvFpF95ln4u+SbPa z3CC<+mlk>&YG9eK_zbp+# z;GyXa;n1G5^Yb^aDIWg2AtWG%qTOcu4#xSq}h2 zp(!AXs!a)kjdG!yWlq*nyz)#Kq=jMrPQgR_?zbRK)>Fx1on5MkOAl zP3h}0W;HqW)#oX|TZHc!dHJ<0j)p5)K2IoL0RY->fn&+z;M~>TZ51D~<)&1?&2_X@ zw&Kt}mYO33c<$uBq~t7&Ot5(eJiv|(?uvF*cq-oSTtaz2NDMd+9d*4f3)0VUNghRI z??3&~wYK^mSi;D#rkSU{0orbMB~F^G&ZIBMTbQ1L09P9@rmNLg#`kOJ^13lu$VqZu zLOP$=$z>CQu&RKbFx0w8edCoMog+lDlw+eTe1O$MgkBu0;HBqHrj>l1QiG^rU6Uj4 zuI6iMi09tgNi0sCIM>YnSu_ zL*?&w&QC9Z!+*eGW@hk~;8P^eYdH!!x*z(3cD9ao_V%z5SV-Pm%+8KJOxk79;E|;z z1t8xX-AW?K)9%3wV|HRT0u~Aam^3x+o35w)?!EmF3wY`H#yYUvTX^mVy^H}UJI-4C z{1(;pxT%_UiJDBU^1JaSFb@|56wu$(2c3uF6(p@ZX6mOUO6i(+XL)}}K1EXx^Ki2K zmd3MB+Ws}|6OdQxN+6B(!@>5`O#w=zm9;$&2wzP=juHc;fo`yp9w=w5s8GQFdqp&d zL|im^{&iK7lxMU;XD=)ialga8_;qW?9S7#vb3Db6Kfgc6nO7uWxtswf5)b%j3%pqT zd1D$ntWR8B1D>Z}CCA`mJIW4y6w4&g1$+QktJd3`o7n9nt5|{7O(X7MbAU7_ zR+oXAf~Ltt;Za2AXxAP2pD_0ohzKi2lPsk>BtVJ;uU9D#iYvzKQe5*Zirk1^q|`CKKvM6{DnaoHzrL& zodA;6BYfieqQkw{_%QhR+ep7qelR^2`L0Pg2sD8%emt=6Dljd<85`j*zy|n#JMe5I zqm8LSE0hAjw#>#O!RkZCf%8Z3b`{%q!mx_NL2S8y{%BQ2NpB-cqF!OgR#(Vjfi!Rc zm$@k=l?x@gNSn4CmXjoH8Igi);QbC7ZVC+95cy~z0)Vxr_*zCMGVLb;_JfHWaaEPT}SBlv>|#_$y|GFeY=Mx5~DJnE|^UT#)~4}gixj$V`0 zUgc1&DoP&bh(|E4=d2e{3K0~QmN>AE!=EeOq+Aa>XEC|&X+B<;WTd16c&X4m#7wWA zO5tHSa*G^&FC5=dWeVlx1GYIK5m5yW4n0T%8{iMFM2ydG9qjMzxtyQ*wQ1!pT5rFF z^#l5hp)tSX;{=FD5eJ$ z5F-&0h;&}rtqbKi$E}npe6ERi0`BlAUcTRT_+kG^dVyZEjAlzpo%WkF29pB)&l2i{ z-|=F!LwfT53fib-ILaJo__>NKaeYw z8T)7h&w*F973?V~1Hm4anR|H!1?*A~GYSND1qZIX1gWhp{(n@l@??KvBfz&|Ei05U z=~~QA)4oLlf&c)0xSjYolTa{6Ke$8_pFB9UH~kAC`2;A)7cDwZ$(!miUIr%>Vv2eN zXhMM2YQ2AZ$o0t9e`y<#VmK*30OeYu_g=uq!O%gTYi=LQ5NBO!2SQLqUL#`v>>QyI zO|THmbo%iLW!(LL(VvbwUQc>1nAF3lCLZH-(Ydfata~dh6-GAku~Co5Z9*HFX--B$ z-WGsz@zD=9Rvi0Gn@D2u=`}nE(D&3<(E?hz;HOC5`@k7S$H`T+LnV4@4=?rU1isLT z>$L%U_nw}_{g>7XgA&TJYa_NKpoxE4sn(S31G9(Ghp^veTWt40DnVOigimd9J7A#- zA%G$DZx#cpZyrd^RK1|f%Ki;Fkuki*_2_Yb2j7+4&nBTK0o2JqZB5cL7lD)2UG0SQ zFf)^c0%DQ41D{;XIK3MWLk3oTj}FiY{}iS+J=e7igb&1nNss?rBoWZ|=ryGY>LR}e z%$O(bYWG3)=uUMz3Y1n9Ak)Xr3im)~fEP5##%?7uAPau4BN-F_`L;DMh5u2l4D4uW zi_-yu+u!cDBX_RMEuXp6z%J5gVjbWiQExp@+GLU)kW6T_nQvZ>FEP7uRM3W&=4zYP66C| zWr!fuMuW-U zt&w%kzODLhKHPhqQjT%vLPji_IXoAxM{Imd(Z6Y{ZyoYaNU1|PKgGofPuY~t3+S%LV$Dug37-X zjad@Eommkm8v2ORH<{8LXRue%&&q=|`Y2rS51NNv$P)8lQ z0;jCFkwmhN4z{yhei*1TMMP;+Q@j8^ZnVD%-lx6WI*$mvScluA%zs1fjv=(xaX`-~ z0u+LC_R0-@cM&fs|BszNeR!l47gUlh`BC@&T80{p_&o22ueF;K_c9eLsCUH%?=1E< zQFl{Yy&kBey$gcCqbn)8U3-nSrWihDk6b%FC>%Uu+&&h9or^(l% z-hS(^6o&-2+kefv>_T05L8$c3$GpJa7krPyK;wD`KUyV4eKY9e%pro*%*#1BI5*rp z!8hIR=1xuwfcpX+6gB0;xGsfUFC}rOc>Y3Ot%}h6TYsy6okD7itd?()`uBlhq@SaW w5A^l_cSNTYMGFFZwV}eAOHXW literal 0 HcmV?d00001 diff --git a/examples/storybook/src/stories/goodreserve-widget/screenshots/no-provider.png b/examples/storybook/src/stories/goodreserve-widget/screenshots/no-provider.png new file mode 100644 index 0000000000000000000000000000000000000000..4dc4fdb5a83afc8f4a88987a171b7b3feb186603 GIT binary patch literal 5063 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 z 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�}6j9vcC~-o2x|o&qto=!HNnMKBrwTPCo_ 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 YXvyPDKk~jo8)}U*5{lxLqDDdg2mi9qf&c&j literal 0 HcmV?d00001 diff --git a/examples/storybook/src/stories/goodreserve-widget/screenshots/quote-ready-buy.png b/examples/storybook/src/stories/goodreserve-widget/screenshots/quote-ready-buy.png new file mode 100644 index 0000000000000000000000000000000000000000..44ff0c9b114013730ae5470e7c1621c1d563fb49 GIT binary patch literal 70987 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 jbfRMN$L-naR*kj`N@I1=3Pcro8>f^8BavPf5N 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 M#O1|GMfAV^5BcSP;Q#;t literal 0 HcmV?d00001 diff --git a/examples/storybook/src/stories/goodreserve-widget/screenshots/quote-ready-sell.png b/examples/storybook/src/stories/goodreserve-widget/screenshots/quote-ready-sell.png new file mode 100644 index 0000000000000000000000000000000000000000..787629fe29abc9cb3b0d7996c95d30ec156688cc GIT binary patch literal 71175 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

M-1!Z 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 literal 0 HcmV?d00001 diff --git a/examples/storybook/src/stories/goodreserve-widget/screenshots/slippage-selection.png b/examples/storybook/src/stories/goodreserve-widget/screenshots/slippage-selection.png new file mode 100644 index 0000000000000000000000000000000000000000..60c7bd4b38222b08758936e561d47829b638edd0 GIT binary patch literal 68814 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�#Yc(n4!@X-A?DfvQDUag?gYnl44iD(=1 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

W!XNB@oPA33D{2@^aCA3lGS0>4+MMw+BL~ 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

2;^6s4nn>R{dj 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

R1vEI+~>`p7Ho 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 literal 0 HcmV?d00001 diff --git a/examples/storybook/src/stories/goodreserve-widget/screenshots/swap-success.png b/examples/storybook/src/stories/goodreserve-widget/screenshots/swap-success.png new file mode 100644 index 0000000000000000000000000000000000000000..1faa729765c209f84671b75eaf9f3f055c18de2a GIT binary patch literal 69348 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ⅇ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 Kq)OhI1pGI^flT56 literal 0 HcmV?d00001 diff --git a/examples/storybook/src/stories/goodreserve-widget/screenshots/unsupported-chain.png b/examples/storybook/src/stories/goodreserve-widget/screenshots/unsupported-chain.png new file mode 100644 index 0000000000000000000000000000000000000000..cd3fd551594973cb0197ea0a3f679f8317bd6595 GIT binary patch literal 70033 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 Dlb9t# literal 0 HcmV?d00001 diff --git a/skills-lock.json b/skills-lock.json deleted file mode 100644 index 9b92c72..0000000 --- a/skills-lock.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "version": 1, - "skills": { - "gooddollar": { - "source": "GoodDollar/GoodSkills", - "sourceType": "github", - "skillPath": "skills/gooddollar/SKILL.md", - "computedHash": "d5f8cc5079f386e7170925e61214fb3334176aa6d0fc6bdc50400e535692b377" - } - } -}