Try   HackMD

Scroll Prover Bug bounty (Scroll sepolia testnet)

Goal

Construct and send txs that makes the scroll prover cannot generate its proof.

Repo

l2geth: https://github.com/scroll-tech/go-ethereum
circuits: https://github.com/scroll-tech/zkevm-circuits
circuits sepc: https://github.com/scroll-tech/zkevm-specs/tree/master/specs
contracts: https://github.com/scroll-tech/scroll/tree/develop/contracts

Scroll overview workflow:

  1. The sequencer (an l2geth signer instance) collects transactions from L2 mempool and L1 (rollup sync service) and packs these into L2 blocks. It also provides p2p and RPC access so that other l2geth nodes can connect and sync the chain.

  2. Rollup-relayer collects L2 blocks (eth_getBlockByHash API in l2geth), packs these into batches and submits them to the L1 rollup contract (this is the Data Availability step). https://github.com/scroll-tech/scroll/blob/develop/contracts/src/L1/rollup/ScrollChain.sol#L164

  3. The provers receive batches, collect the detailed traces (scroll_getBlockTraceByNumberOrHash API in l2geth), and produce ZK proofs. https://github.com/scroll-tech/go-ethereum/blob/develop/eth/tracers/api_blocktrace.go#L19

  4. Rollup-relayer verifies the proofs and submits them to the L1 rollup contract (finalization step). https://github.com/scroll-tech/scroll/blob/develop/contracts/src/L1/rollup/ScrollChain.sol#L290

Possible Reasons

Divergent behavior between l2geth and zkevm circuit

The proof of a scroll tx is established by first generating a trace through executing it in the l2geth EVM, then the scroll circuit constrains this trace step, any divergent behavior between the geth EVM and the circuit will result in this transaction cannot be proved.

example:
The calldatasize in the evm create is 0, but circuits uses the tx.data length as the calldatasize.
https://github.com/scroll-tech/zkevm-circuits/pull/909/files

Missing info in the generated trace

If any information required for circuit proofing is absent from the generated trace, the transaction will not be proved.

trace generate logic:
https://github.com/scroll-tech/go-ethereum/blob/develop/eth/tracers/api_blocktrace.go#L19

example: https://github.com/scroll-tech/go-ethereum/pull/465
When generating a trace, a transaction without tx.data will be categorized as a non-contract call, resulting in the exclusion of its code from the trace.
Therefore a contract fallback call transaction will not be provable due to the absence of code information in the trace.

Bypass circuit capacity check

Due to the limited circuit capacity, transactions exceeding this threshold cannot be proven. To address this, Scroll initiates a pre-execution of the transaction, generating a trace. It then utilizes this trace to calculate the transaction's capacity usage. If the capacity exceeds the established limit, the execution and prove are skipped.

If the circuit capacity check can be bypassed (https://github.com/scroll-tech/go-ethereum/blob/develop/miner/worker.go#L875), it's possible to send txs that cannot be proved.

capacity checker:
https://github.com/scroll-tech/zkevm-circuits/blob/develop/prover/src/zkevm/capacity_checker.rs

bus-mapping got error when process geth trace

Bus-Mapping is a crate designed to parse EVM execution traces and manipulate all of the data, if bus-mapping is unable to parse some opcode step or the parsing behavior is inconsistent with evm, also result in the transaction cannot be proved.

bus-mapping:
https://github.com/scroll-tech/zkevm-circuits/tree/develop/bus-mapping

RPC

https://sepolia-rpc.scroll.io
Send Txs to scroll l2 testnet, not sepolia testnet.

Some idea

Reward

Scroll's transactions (blocks) have three confirmation states: "Precommitted," "Committed," and "Finalized."

Precommitted signifies that the transaction has been confirmed by the Sequencer, Committed means that the transaction bytes have been submitted to L1, and Finalized means that the transaction's proof has been correctly generated and verified on L1.

Successfully sending a transaction that cannot be finalized considered achieving the goal and is eligible for the bounty.

Verification Process:

  1. Open the Rollup explorer at https://scroll.io/rollupscan, search for the block containing the sent transaction.

    Image Not Showing Possible Reasons
    • The image was uploaded to a note which you don't have access to
    • The note which the image was originally uploaded to has been deleted
    Learn More →

  2. Check the batch status of the transaction. if the transaction cannot be finalized even after 2 hours of committed, the proof may not be generated correctly.

    Image Not Showing Possible Reasons
    • The image was uploaded to a note which you don't have access to
    • The note which the image was originally uploaded to has been deleted
    Learn More →

  3. Provide the transaction hash and relevant information to contact Scroll personnel to confirm if the transaction is the cause of the batch not being finalized.

A reward of $5,000 USD is offered for each unique unprovable transaction type identified. Repeated submissions for the same issue will not be eligible for additional rewards. In the event that two individuals discover the same vulnerability type, the reward will be granted to the first person who sends the transaction.

And if any other vulnerabilities leading to funds loss are discovered in l2geth and contract(except the gas swap), the reward will be determined based on the funds affected, with a maximum reward of $100,000 USD.

Restriction

Current employees, vendors (auditors) and contractors are not eligible to participate in the bug bounty program.

Contact group

Join the following group to contact the Scroll staff for obtaining the test ether and submitting reports.

Telegram: https://t.me/+XmC8N1u8oQ80NTlh

Wechat:

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

End time

The program will be discontinued once scroll launch the mainnet bug bounty program.