feat: add TIP-403 policy data endpoint#214
Conversation
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
|
cyclops audit fast |
1 similar comment
|
cyclops audit fast |
3e6c152 to
e10d844
Compare
|
cyclops audit fast |
e10d844 to
06121cf
Compare
|
cyclops audit fast |
06121cf to
6e29907
Compare
|
cyclops audit fast |
|
cc @legion2002 Cyclops audit event published. View workflow run Config: config: |
tempoxyz-cyclops-bot
left a comment
There was a problem hiding this comment.
👁️ Cyclops Review
PR #214 adds a public GET /policy-data endpoint that reconstructs TIP-403 policy metadata and direct whitelist/blacklist membership from indexed logs. Two actionable issues were found and are commented inline: unbounded member materialization on the public endpoint, and missing support for valid compound TIP-403 policies.
Reviewer Callouts
- ⚡ Collection endpoint limits: Require mandatory
limit/cursor semantics and response-size caps for public APIs that return collections derived from indexed logs. - ⚡ Hardcoded TIP-403 address literals:
src/api/tip403_registry.rsimportsTIP403_REGISTRY_ADDRESSbut duplicates the raw\x403c...bytea literal in SQL filters. If the precompile address changes, these queries will silently return empty results; consider binding the imported constant or centralizing the literal.
## Summary - add bounded member pagination to `/policy-data` with a hard max page size and cursor support - support `CompoundPolicyCreated` and resolve compound policies to sender, recipient, and mint-recipient child policy data - bind the TIP-403 registry address constant in SQL instead of duplicating the byte literal ## Verification - cargo fmt --check - cargo test --test api_live_test policy_data --no-run - cargo test --test api_live_test policy_data -- --nocapture (compiled, then blocked because DATABASE_URL is not set) Prompted by: @0xrusowsky
|
cyclops audit fast |
|
cc @0xrusowsky Cyclops audit event published. View workflow run Config: config: |
tempoxyz-bot
left a comment
There was a problem hiding this comment.
👁️ Cyclops Review
PR #214 adds a public read-only /policy-data endpoint that reconstructs TIP-403 policy data from indexed registry logs. Two verified security issues remain: virtual built-in policies are not modeled, and first-page member pagination skips address(0).
Reviewer Callouts
- ⚡ Compound child pagination:
load_tip403_child_policyalways callsload_tip403_policy_memberswithcursor = None, so a compound response can expose a childnext_member_cursorwithout any child-specific cursor parameter to resume that page in the same compound view. Decide whether to document that clients must query the child policy directly for pagination or add child-scoped cursor parameters. - ⚡ Latest-update query plan: The reported DoS from
selector = ANY(...)was not verified because the existing(topic1, address, block_num DESC)index can avoid a full scan on tested PostgreSQL versions. Still, production should confirm the plan with real data; if it regresses, split the latest-update lookup into per-selectorLIMIT 1queries or aUNION ALL.
| ) | ||
| .await?; | ||
|
|
||
| let Some(row) = row else { return Ok(None) }; |
There was a problem hiding this comment.
🚨 [SECURITY] Built-in TIP-403 policies are reported as missing
load_tip403_policy_metadata reconstructs every policy only from PolicyCreated/CompoundPolicyCreated logs and returns None when no creation log exists. Tempo policy IDs 0 (REJECT_ALL) and 1 (ALLOW_ALL) are virtual built-ins that always exist but do not emit creation logs, so direct lookups return 404 and valid compound policies referencing them fail during child expansion.
Recommended Fix:
Special-case policy IDs 0 and 1 before the creation-log query, returning synthetic zero-admin metadata with empty members (0 => WHITELIST, 1 => BLACKLIST), and reuse that path for compound child resolution.
| topic2, topic3, data | ||
| FROM logs | ||
| WHERE address = $1 | ||
| AND selector = $2 AND topic1 = $3 AND topic3 IS NOT NULL AND topic3 > $4 |
There was a problem hiding this comment.
🚨 [SECURITY] First-page member pagination skips address(0)
When no cursor is supplied, the code substitutes an all-zero 32-byte cursor and then filters with topic3 > $4. An indexed EVM address(0) member is also the all-zero topic, so it is excluded from the first page forever. Consumers can receive incomplete whitelist/blacklist data and make incorrect enforcement decisions.
Recommended Fix:
Do not apply the cursor predicate unless a cursor was provided, or use a separate first-page query that includes the zero topic. Avoid changing all pages to >= without handling duplicate cursor rows.
No description provided.