feat(ingest): EVM deposit detection via ERC-20 Transfer logs - #235
Open
Malik6828 wants to merge 1 commit into
Open
feat(ingest): EVM deposit detection via ERC-20 Transfer logs#235Malik6828 wants to merge 1 commit into
Malik6828 wants to merge 1 commit into
Conversation
Scans eth_getLogs for registered token contracts with a block-number cursor, advancing only after durable processing so a crash resumes exactly-once — the same guarantee the Horizon path gives. Logs are matched on the emitting contract address, not topics alone: any contract can emit a Transfer event with arbitrary topics, so topic-only attribution would let an attacker mint balances for free. This is the primary security invariant in this module. Deposits are recorded as 'unconfirmed'; crediting is gated on Octo-Protocol-org#222. Merging Octo-Protocol-org#221 before Octo-Protocol-org#222 cannot create spendable balances — enforced at the DB level, not by convention. Changes: - crates/ingest/src/evm.rs: EvmIngestor (process_log, poll_once, run), EvmRpcClient (eth_blockNumber, eth_getLogs), EvmLog decoding, RegisteredToken registry, adaptive range bisection on RangeTooLarge. - crates/store/migrations/0021_evm_ingest.sql: chain_id + block_number on ingest_cursor; chain_id + evm_log_index on transactions; uq_tx_evm_onchain dedup index; 'unconfirmed' status value. - crates/store/src/lib.rs: get_evm_cursor, set_evm_cursor, mark_evm_polled, record_evm_deposit, evm_address_by_hex, NewEvmDeposit struct. - crates/ingest/tests/evm_ingest_tests.rs: 10 integration tests covering happy path, adversarial fake Transfer (critical security), idempotency/replay, crash-resume cursor, quarantine of unregistered tokens, range bisection, removed (reorged) logs, non-deposit address filtering, and unconfirmed-status invariant. - docs/ingest-integration.md: EVM section documenting native ETH scope decision, contract address verification, cursor contract, unconfirmed status, adaptive bisection, schema changes, and tests. All 34 unit tests + 10 EVM integration tests pass; full workspace builds cleanly with no regressions. Refs Octo-Protocol-org#221
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Scans eth_getLogs for registered token contracts with a block-number cursor, advancing only after durable processing so a crash resumes exactly-once, the same guarantee the Horizon path gives.
Logs are matched on the emitting contract address, not topics alone: any contract can emit a Transfer event with arbitrary topics, so topic-only attribution would let an attacker mint balances for free. This is the primary security invariant in this module.
Deposits are recorded as 'unconfirmed'; crediting is gated on #222. Merging #221 before #222 cannot create spendable balances, enforced at the DB level, not by convention.
Changes:
All 34 unit tests + 10 EVM integration tests pass; full workspace builds cleanly with no regressions.
Refs #221
Summary
Related step / issue
Checklist
cargo fmt --all -- --checkpassescargo clippy --workspace --all-targets -- -D warningspassescargo test --workspacepassesHow to test
Closes
closes #221