Auto-generated documentation.
Generate a Polygon PoS exit proof for a burn transaction.
polycli pos exit-proof [flags]Generate the ABI-encoded exit payload required to withdraw tokens from Polygon PoS to Ethereum.
polycli pos exit-proof [flags]When a user burns tokens on the Polygon PoS sidechain, they must later submit a cryptographic proof to the Ethereum WithdrawManager contract to finalise the withdrawal. This command constructs that proof by:
- Fetching the burn transaction receipt from L2 to determine the block number and transaction index.
- Fetching all receipts for the burn block via
eth_getBlockReceiptsand reconstructing the receipts Merkle Patricia Trie (MPT). - Generating an MPT proof (sibling nodes from root to leaf) for the burn receipt.
- Binary-searching the
RootChaincontract on L1 to find the checkpoint that covers the burn block. - Fetching the block headers for the checkpoint range and building a binary Merkle proof that the burn block hash is included.
- ABI-encoding all of the above into the payload expected by
startExitWithBurntTokens(bytes).
| Flag | Required | Default | Description |
|---|---|---|---|
--l1-rpc-url |
yes | — | L1 (Ethereum) RPC URL |
--l2-rpc-url |
yes | — | L2 (Polygon PoS) RPC URL |
--root-chain-address |
yes | — | RootChain contract address on L1 |
--tx-hash |
yes | — | burn transaction hash on L2 |
--checkpoint-stride |
no | 10000 |
number of L2 blocks per checkpoint; override for local testnets that use a smaller value |
--log-index |
no | 0 |
index of the burn log within the receipt; 0 works for most ERC20 withdrawals — increase if the token emits extra logs before the burn event |
Writes 0x-prefixed ABI-encoded payload bytes to stdout. All progress and diagnostic messages go to stderr so the output can be captured directly in a shell variable.
# Step 1: burn tokens on L2 (e.g., call ERC20 withdraw on the ChildToken contract)
# burn_tx_hash=0x...
# Step 2: wait for the checkpoint to be submitted (~30 min on mainnet)
# Step 3: generate the exit proof
payload=$(polycli pos exit-proof \
--l1-rpc-url "${L1_RPC_URL}" \
--l2-rpc-url "${L2_RPC_URL}" \
--root-chain-address "${ROOT_CHAIN_ADDRESS}" \
--tx-hash "${burn_tx_hash}")
# Step 4: start the exit on L1
cast send \
--rpc-url "${L1_RPC_URL}" \
--private-key "${PRIVATE_KEY}" \
"${WITHDRAW_MANAGER_PROXY_ADDRESS}" \
"startExitWithBurntTokens(bytes)" \
"${payload}"
# Step 5: process the exit on L1
cast send \
--rpc-url "${L1_RPC_URL}" \
--private-key "${PRIVATE_KEY}" \
"${WITHDRAW_MANAGER_PROXY_ADDRESS}" \
"processExits(address)" \
"${POL_TOKEN_ADDRESS}" --checkpoint-stride uint number of L2 blocks per checkpoint (10000 on mainnet; override for local testnets) (default 10000)
-h, --help help for exit-proof
--l1-rpc-url string Ethereum RPC URL
--l2-rpc-url string Polygon PoS RPC URL
--log-index uint index of the burn log within the receipt (0 works for most ERC20 withdrawals; increase if the token emits extra logs before the burn event)
--root-chain-address string RootChain contract address on L1
--tx-hash string burn transaction hash on L2The command also inherits flags from parent commands.
--config string config file (default is $HOME/.polygon-cli.yaml)
--pretty-logs output logs in pretty format instead of JSON (default true)
-v, --verbosity string log level (string or int):
0 - silent
100 - panic
200 - fatal
300 - error
400 - warn
500 - info (default)
600 - debug
700 - trace (default "info")- polycli pos - Utilities for Polygon PoS.