You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
As an Anticapture user (delegate / security researcher) watching Tornado Cash, I want each on-chain proposal's execution target automatically checked for source-verification and look-alike-address risk, so a malicious proposal like Proposal 67 (2026-06-25) is surfaced in the UI/feed before it can pass — instead of relying on manual decompilation.
Context
Proposal 67 pointed execute()'s delegatecall at an unverified look-alike contract — 0x5efda50f22d34f27… vs the real governor 0x5efda50f22d34F26…, differing only from the 16th hex char — to seize governance over a ~$23M treasury. It was caught manually by L2BEAT / P. Caversaccio via missing code verification + decompilation.
Look-alike address? similarity (prefix/suffix + Levenshtein) vs a known-entity allowlist (governor / vault / token / multisig) ⇒ catches …f27… vs …F26….
(optional, later)behavior diff — decompile executeProposal() / scan for storage-slot writes to governance-critical slots.
Describe solution — adaptation across the 5 components (per the dao-integration skill)
1. address-enrichment (apps/address-enrichment) — new home for the analysis (indexer stays on-chain-only).
Job that, per TORN proposal target, calls Etherscan verification + runs the similarity check against the known-entity list, and writes a risk record. Reuses the app's existing Etherscan/RPC plumbing.
2. DB — add a side table proposal_target_risk (proposalId, daoId, target, verified bool, lookAlikeOf address|null, riskLevel, details jsonb) rather than migrating the shared proposals_onchain schema (keeps other DAOs untouched; consistent with the "no-migration" approach in RESEARCH.md §4).
3. API (apps/api) — layered controller→service→repository→mapper:
GET /proposals/{id}/target-risk (or fold into the proposal-detail mapper).
In clients/torn, expose target-risk via the client and flip alreadySupportCalldataReview() once the signal is populated.
4. gateway + client — regenerate packages/anticapture-client from the updated OpenAPI; apps/gateful passes through.
5. dashboard (apps/dashboard) — render a HIGH-risk banner on features/governance/.../ProposalSection.tsx; add a feedEvent flag for the activity feed; reflect support in shared/dao-config/torn.ts.
Enum sync (the 5th component the skill calls out): add a PROPOSAL_RISK feed/metric type consistently across indexer + api + dashboard enums.
Acceptance / validation
Proposal 67 (and the May 2023 attack proposal) render with a HIGH target-risk badge (unverified + look-alike of 0x5efda5…A1Ce).
Legitimate executed proposals with verified targets render LOW/none.
No schema migration affecting other DAOs.
Want a second opinion on the approach before implementation — see the @codex ask in the comments. Tagging @pikonha (owner of #2002) to validate this is the right next step / right home (address-enrichment vs indexer; side-table vs schema extension).
Feature Request
User story
As an Anticapture user (delegate / security researcher) watching Tornado Cash, I want each on-chain proposal's execution
targetautomatically checked for source-verification and look-alike-address risk, so a malicious proposal like Proposal 67 (2026-06-25) is surfaced in the UI/feed before it can pass — instead of relying on manual decompilation.Context
execute()'sdelegatecallat an unverified look-alike contract —0x5efda50f22d34f27…vs the real governor0x5efda50f22d34F26…, differing only from the 16th hex char — to seize governance over a ~$23M treasury. It was caught manually by L2BEAT / P. Caversaccio via missing code verification + decompilation.targetbut don't analyze it:TORNClient.alreadySupportCalldataReview() === false. Background + roadmap inapps/indexer/src/indexer/torn/RESEARCH.md(PR docs(torn): DAO anatomy, tech funnel & remaining-gap roadmap #2004, §5 P1, §7).Describe the feature request
Compute a proposal target risk signal from the already-indexed
targetand surface it on the proposal detail + activity feed.Risk inputs:
getsourcecode→ emptySourceCode/ABI⇒ unverified ⇒ HIGH.…f27…vs…F26….executeProposal()/ scan for storage-slot writes to governance-critical slots.Describe solution — adaptation across the 5 components (per the
dao-integrationskill)1. address-enrichment (
apps/address-enrichment) — new home for the analysis (indexer stays on-chain-only).target, calls Etherscan verification + runs the similarity check against the known-entity list, and writes a risk record. Reuses the app's existing Etherscan/RPC plumbing.2. DB — add a side table
proposal_target_risk(proposalId,daoId,target,verified bool,lookAlikeOf address|null,riskLevel,details jsonb) rather than migrating the sharedproposals_onchainschema (keeps other DAOs untouched; consistent with the "no-migration" approach in RESEARCH.md §4).3. API (
apps/api) — layered controller→service→repository→mapper:GET /proposals/{id}/target-risk(or fold into the proposal-detail mapper).clients/torn, expose target-risk via the client and flipalreadySupportCalldataReview()once the signal is populated.4. gateway + client — regenerate
packages/anticapture-clientfrom the updated OpenAPI;apps/gatefulpasses through.5. dashboard (
apps/dashboard) — render a HIGH-risk banner onfeatures/governance/.../ProposalSection.tsx; add afeedEventflag for the activity feed; reflect support inshared/dao-config/torn.ts.Enum sync (the 5th component the skill calls out): add a
PROPOSAL_RISKfeed/metric type consistently across indexer + api + dashboard enums.Acceptance / validation
unverified+look-alike of 0x5efda5…A1Ce).