Skip to content

Experimental DSL for Ethereum Dapp/Protocol Addition by adding Safe#99

Open
prasanna-anchorage wants to merge 20 commits intofeat/ethereum-ethglobal-e2efrom
experimental-dsl-safe
Open

Experimental DSL for Ethereum Dapp/Protocol Addition by adding Safe#99
prasanna-anchorage wants to merge 20 commits intofeat/ethereum-ethglobal-e2efrom
experimental-dsl-safe

Conversation

@prasanna-anchorage
Copy link
Contributor

The intent here is to show that you can very easily add a Visualization for a smart contract protocol like Safe by writing a Config and some relatively boilerplate mapping. We can eventually turn the whole thing into a simpler DSL that doesn't need Rust experience but baby steps first.

prasanna-anchorage and others added 19 commits November 19, 2025 12:17
  Add VisualizerContext struct with nested call support and token formatting.
  Includes Clone implementation, for_nested_call() method, and unit tests.

Roadmap: Milestone 1-1, core datastructure
  - Rename VisualizerRegistry to EthereumVisualizerRegistry to avoid naming conflicts
  - Split into immutable EthereumVisualizerRegistry and mutable EthereumVisualizerRegistryBuilder
  - Clarify lifecycle: setup phase (builder) vs. execution phase (registry)
  - Make register() return Option<Box<dyn ContractVisualizer>> to signal overwrites
  - Add with_default_protocols() for explicit protocol initialization
  - Improve maintainability by enforcing setup/runtime separation in type system

Roadmap: Milestone 1.1 - ContractVisualizer trait
  - Format code for better readability (alignment, line breaks)
  - Replace custom token formatting with Alloy's format_units utility
  - Implement ContractRegistry module with token and contract type
  management
  - Add comprehensive token formatting with metadata lookup
  - Update test fixtures to use proper formatting conventions

Roadmap: Milestone 1.1 - Registry
Co-Authored-By: Claude <noreply@anthropic.com>
  - Create token_metadata module as canonical wallet format for chain
  and token data
  - Define TokenMetadata struct with symbol, name, erc_standard,
  contract_address, decimals
  - Define ChainMetadata struct for wallet token metadata (network_id:
   String, assets: HashMap<symbol, TokenMetadata>)
  - Implement parse_network_id() to map network identifiers to chain
  IDs
  - Implement compute_metadata_hash() for SHA256 hashing of protobuf
  bytes
  - Refactor ContractRegistry to use canonical TokenMetadata structure
  - Registry internally maps (chain_id, Address) -> TokenMetadata for
  efficient lookup
  - Consolidate duplicate TokenMetadata and AssetInfo definitions
  - Update load_chain_metadata() to transform wallet format to
  registry format
  - Add sha2 dependency for metadata hashing

Co-Authored-By: Claude <noreply@anthropic.com>
Roadmap: Milestone 1.1 - Token and Contract registry
  - Document field builder functions from visualsign crate
  - Include token metadata and registry usage patterns
  - Add supported networks and chain ID mappings
  - Provide best practices and common code examples
  - Reference Milestone 1.1 token and contract registry work

Co-Authored-By: Claude <noreply@anthropic.com>
Roadmap: Milestone 1.1 - code complete, starting on Uniswap using these
  - Document proposed registry refactor with provenance tracking
  - Add debug trace for contract/token lookups in transaction
  visualization
  - TODO marks for future registry layer implementation

Roadmap: This marks reaching Stage1,we can start on contracts
- Implement ContractType trait with compile-time uniqueness guarantees
- Restructure: contracts/core/ for standards, protocols/ for DeFi protocols
- Create protocols/uniswap module with config, contracts/, and register()
- Add register_contract_typed<T>() for type-safe contract registration
- Implement FallbackVisualizer for unknown contract calls
- Document Uniswap versions (V1, V1.2, V2) and V4 PoolManager for future

Impact: Prevents duplicate type identifiers at compile-time, enables
scalable addition of protocols (Aave, Compound, etc.), and provides
clear architectural patterns for contract organization.

Roadmap: Milestone 2
- Add ContractType trait for compile-time unique contract identifiers
- Restructure: contracts/core/ (standards) vs protocols/ (DeFi protocols)
- Implement protocols/uniswap module with config-driven registration
- Rename UniswapV4Visualizer → UniversalRouterVisualizer (matches IUniversalRouter)
- Stub ERC721, Permit2, and V4 PoolManager for future Etherscan decoding
- Add FallbackVisualizer for unknown contracts
- Document Uniswap versions (V1, V1.2, V2) and V4 PoolManager

Impact: Prevents duplicate type identifiers at compile-time, enables scalable
addition of protocols with clear separation of concerns.

Roadmap: Uniswap transaction decoding
Implements complete visualization support for Uniswap Universal Router transactions,
transforming raw hex calldata into human-readable command descriptions.

Key changes:
- Support for both execute() overloads (with/without deadline)
- Decoders for V2/V3 swaps, Permit2, PayPortion, UnwrapWeth, and other commands
- Manual ABI decoding for V2SwapExactIn to work around Alloy decoder limitations
- UniversalRouterContractVisualizer registered in visualizer registry
- Added EthereumVisualizerRegistry to converter for protocol-specific visualization
- Refactored to use UniswapConfig::weth_address instead of WellKnownAddresses
- All documentation references official Uniswap technical docs

Transactions that previously showed raw hex now display structured command breakdowns
with token symbols, amounts, and operation details. All 91 tests passing.

Co-Authored-By: Claude <noreply@anthropic.com>
… offsets

Fixed byte-level parsing of Permit2 Permit (0x0a) commands in Uniswap Universal Router.
Corrected EVM slot layout offsets and added "Unlimited Amount" display for max approvals.

- **Fixed byte offsets** for PermitSingle struct parsing:
  - Expiration: bytes 90-95 (Slot 2, right-aligned at end of slot)
  - Spender: bytes 140-159 (Slot 4, left-padded address)
  - SigDeadline: bytes 160-191 (Slot 5, full 32-byte slot)

- **Added Unlimited Amount detection**: Display "Unlimited Amount" in condensed
  view when approval amount is max uint160/uint256, while keeping exact value
  in expanded view for transparency

- **Added comprehensive tests** (6 new test cases):
  - Unit test for custom decoder byte-level parsing
  - Unit test for field visualization structure
  - Integration test with fixture transaction
  - Edge case tests for timestamp boundaries
  - Input validation tests (empty/short input rejection)

- Token: 0x72b658Bd674f9c2B4954682f517c17D14476e417 ✓
- Amount: 1461501637330902918203684832716283019655932542975 ✓
- Spender: 0x3fc91a3afd70395cd496c647d5a6cc9d4b2b7fad (Uniswap) ✓
- Expires: 2025-12-15 18:44 UTC (1765824281) ✓
- Sig Deadline: 2025-11-15 19:14 UTC (1763234081) ✓

- All 97 tests passing ✓
- Verified with user's fixture transaction ✓
- Both MAX_UINT160 and MAX_UINT256 cases handled ✓

Co-Authored-By: Claude <noreply@anthropic.com>
  Replace sol! macro decoder with manual ABI decoding for V3SwapExactInputParams.
  The sol! macro's abi_decode() cannot handle raw calldata bytes from the
  Universal Router's inputs array, which contain offset pointers to dynamic fields.

  Manual decoding:
  - Reads fixed-size fields (amountIn, amountOutMinimum) from known byte offsets
  - Follows offset pointers to parse dynamic bytes path field
  - Extracts token addresses and fee from path data
  - Properly formats output with token symbols and decimals

  This fixes V3 Swap Exact In commands that were previously showing
  "Failed to decode parameters". They now display complete swap details including
  amounts, tokens, and fees.

Co-Authored-By: Claude <noreply@anthropic.com>
… pattern

  Replace manual byte slicing with SolType::abi_decode_params for better code
  organization and maintainability. Apply the same pattern to both V3SwapExactIn
  and V3SwapExactOut decoders.

  Changes:
  - Use abi_decode_params for proper ABI decoding instead of manual offsets
  - Define parameter types as tuples: (Address, U256, U256, Bytes, bool)
  - Remove ~70 lines of manual byte manipulation code
  - Add comments explaining parameter structures and validation steps
  - Fix ambiguous method calls by explicitly specifying trait implementations
  - Improve error handling consistency across all decoders

  Benefits:
  - More maintainable: Uses standard Alloy patterns
  - More readable: Clear type definitions, self-documenting code
  - More robust: Proper ABI decoding validated by the compiler
  - Easier to extend: Same pattern for future swap decoders

  Testing:
  - All 102 Ethereum unit tests pass
  - V3 Swap Exact In/Out commands decode correctly
  - Transaction parsing shows complete swap details with amounts, tokens, fees

Co-Authored-By: Claude <noreply@anthropic.com>
…ails

  Update the fixture to reflect improved Uniswap Universal Router visualization
  with expanded field details for V2 Swap, Pay Portion, and Unwrap commands.
@prasanna-anchorage prasanna-anchorage force-pushed the feat/ethereum-ethglobal-e2e branch from 8f443ed to df1e3e2 Compare November 19, 2025 12:17
@prasanna-anchorage prasanna-anchorage force-pushed the feat/ethereum-ethglobal-e2e branch 2 times, most recently from 3475edb to 2d3cd3f Compare November 21, 2025 14:33
@prasanna-anchorage prasanna-anchorage force-pushed the feat/ethereum-ethglobal-e2e branch 3 times, most recently from fa0577a to 7e672cc Compare December 2, 2025 15:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant