Cypher Protocol Substreams
A comprehensive Substreams package for monitoring and processing Cypher Protocol events and calls on Ethereum networks. This project provides foundational modules for extracting, filtering, and processing blockchain data with a specific focus on the Cypher Protocol ecosystem.
Overview
This Substreams package is designed to monitor and process events from the Cypher Protocol smart contracts, including:
- VotingEscrow: NFT-based voting power system
- Election: Voting and bribe management
- CypherToken: ERC-20 governance token
- RewardDistributor: Merkle tree-based reward distribution
- DistributionModule: Token emission management
- Airdrop: Merkle tree-based airdrop distribution
Features
Core Functionality
- Event Processing: Extract and decode all Ethereum events from successful transactions
- Call Processing: Monitor all contract calls including internal calls
- Advanced Filtering: Filter events and calls using complex expressions with logical operators
- Transfer Tracking: Monitor both ERC-20 and ERC-721 transfer events
- Contract-Specific Processing: Specialized event decoding for Cypher Protocol contracts
- Dynamic Configuration: Configurable contract addresses without code changes
Key Modules
Basic Event and Call Processing
all_events: Extracts all events from successful transactions
all_calls: Extracts all calls including internal calls
index_events: Creates searchable indexes for events
index_calls: Creates searchable indexes for calls
index_events_and_calls: Combined indexing for both events and calls
Advanced Filtering
filtered_events: Filter events by address and signature
filtered_calls: Filter calls by contract, caller, and method
filtered_transactions: Filter complete transactions
filtered_events_and_calls: Combined filtering of events and calls
Cypher Protocol Specific
filter_cypher_events: Enhanced processor with configurable contract addresses
Installation and Setup
Prerequisites
- Rust toolchain (latest stable)
- Substreams CLI
- WASM target:
rustup target add wasm32-unknown-unknown
Building
cargo build --target wasm32-unknown-unknown --release
Publishing
To publish the Substreams package:
substreams publish cypher-protocol-v0.0.{NEW_VERSION}.spkg
Important: Before publishing, ensure you update the version in both:
substreams.yaml - Update the version field
Cargo.toml - Update the version field
This ensures version consistency across all package files.
Configuration
The package uses configurable contract addresses that can be set via parameters:
"query_string|contract_addresses_string"
"voting_escrow:0xaddr1,election:0xaddr2,cypher_token:0xaddr3,reward_distributor:0xaddr4,distribution_module:0xaddr5,airdrop:0xaddr6"
Usage Examples
Basic Event Filtering
substreams run substreams.yaml filtered_events \
--param='(evt_addr:0x1234... || evt_addr:0x5678...) && evt_sig:0xdeadbeef...'
Call Filtering
substreams run substreams.yaml filtered_calls \
--param='call_method:0xa9059cbb && call_to:0xdac17f958d2ee523a2206206994597c13d831ec7'
Cypher Protocol Events
substreams run substreams.yaml filter_cypher_events \
--param='(call_to:0xabc || call_to:0xdef)|voting_escrow:0xf65e1e90269373a60b2abdaf2dc52b2a5a8fdb5c,election:0x0c132c3841b9cdbb3a305275ee02d571a551ce70,cypher_token:0xd36f05bc341b3286c1fd15a809d3315741796f26,reward_distributor:0x7f91980325a294b2affaac6f26e1644864160d41,distribution_module:0x636bdc02170e04c917204f858fa110ce9a5bf05f,airdrop:0xfcbebe31e067a8c460563bcb1d7458fae1949f29'
Supported Event Types
VotingEscrow Events
CreateLock: User creates new lock position
DepositFor: Add tokens to existing lock
Withdraw: Withdraw expired lock
IncreaseUnlockTime: Extend lock duration
LockIndefinite: Convert to indefinite lock
UnlockIndefinite: Convert back to timed lock
Merge: Merge two lock positions
Transfer: NFT Transfer (ERC-721)
Approval: NFT Approval (ERC-721)
Election Events
Vote: User votes for candidate
BribeClaimed: User claims bribe reward
BribeAdded: Bribe added for candidate
CandidateEnabled: Candidate enabled for voting
CandidateDisabled: Candidate disabled
BribeTokenEnabled: Token approved for bribes
BribeTokenDisabled: Token disabled for bribes
CypherToken Events (ERC-20)
Transfer: ERC-20 Transfer
Approval: ERC-20 Approval
RewardDistributor Events
RootAdded: New merkle root added
Claimed: User claimed reward
DistributionModule Events
TokensEmitted: Tokens emitted to recipient
EmissionAddressUpdated: Emission address changed
Airdrop Events
CypherTokenClaimed: CypherToken claimed
VeCypherNftClaimed: VeCypherNft claimed
Query Language
The package supports a powerful query language for filtering events and calls:
Operators
||: Logical OR
&&: Logical AND
(): Parentheses for grouping
Event Filters
evt_addr:0x...: Filter by event contract address
evt_sig:0x...: Filter by event signature
Call Filters
call_to:0x...: Filter by called contract address
call_from:0x...: Filter by caller address
call_method:0x...: Filter by method signature (4 bytes)
substreams run substreams.yaml filter_cypher_events
--param='(call_to:0xabc || call_to:0xdef)
Example Queries
'(evt_addr:0x1234... || evt_addr:0x5678...) && evt_sig:0xdeadbeef...'
'evt_sig:0x9bb8f83800000000000000000000000000000000000000000000000000000000 || (call_method:0xa9059cbb && call_to:0xdac17f958d2ee523a2206206994597c13d831ec7)'
Output Formats
ProcessedEvents
The filter_cypher_events module outputs structured data:
message ProcessedEvents {
repeated TransferEvent transfer_events = 1;
repeated ContractEvent contract_events = 2;
Clock clock = 3;
}
message TransferEvent {
string from = 1;
string to = 2;
string value = 3;
string token_id = 4;
string hash = 5;
uint64 block_number = 6;
uint64 timestamp = 7;
}
message ContractEvent {
string contract_name = 1;
string event_name = 2;
map<string, string> event_data = 3;
uint64 block_number = 4;
string transaction_hash = 5;
uint64 timestamp = 6;
string contract_address = 7;
string from = 8;
string to = 9;
}
Error Handling and Logging
The package includes comprehensive error handling and logging:
- Verbose Comments: All functions include detailed documentation
- Standard Logging: Uses Substreams logging framework
- Error Handling: Graceful handling of malformed data
- Debug Information: Extensive debug logging for troubleshooting
Development
Project Structure
src/
├── calls.rs # Call processing modules
├── events.rs # Event processing modules
├── combined.rs # Combined processing and Cypher Protocol specific logic
├── lib.rs # Module exports and initialization
└── pb/ # Generated protobuf bindings
Testing
cargo test
cargo test -- --nocapture
Adding New Event Types
To add support for new event types:
- Add event signature constants in
combined.rs
- Add event processing logic in
extract_event_data()
- Create specific extractor functions for the new event
- Update the event matching logic in
process_contract_event()
Dependencies
substreams: Core Substreams framework
substreams-ethereum: Ethereum-specific functionality
num-bigint: Big integer arithmetic for token amounts
hex: Hexadecimal encoding/decoding
ethabi: Ethereum ABI parsing
anyhow: Error handling
License
This project is part of the Substreams foundational modules ecosystem.
Contributing
- Fork the repository
- Create a feature branch
- Make your changes with comprehensive logging and error handling
- Add tests for new functionality
- Submit a pull request
Support
For issues and questions:
- Check the Substreams documentation
- Review the extensive logging output for debugging
- Ensure contract addresses are correctly configured
- Verify event signatures match your contract ABIs