4 Checks to Reconcile a Pending Across Transfer
To verify an escrow balance, compare the tokens held by the origin SpokePool with the transfer claims and settlement activity recorded for that chain and token. A contract’s balance alone cannot prove your deposit is safe or refunded: funds are pooled, and each transfer moves through deposit, fill, and settlement states.
A block explorer shows what one contract did; an acrossbridge service status view connects the origin deposit to a destination fill, which is the more useful comparison when your transfer is pending. For an acrossbridge transfer, keep the origin chain, transaction hash, and deposit ID together so you do not confuse a similar transfer from another chain.
Four checks separate escrow from an unpaid claim
- Match the deposit to its chain and token.
- Check whether the destination fill occurred.
- Separate user delivery from relayer repayment.
- Check expiry, partial fills, and refund status.
1. Match the deposit to its chain and token. Find the successful deposit transaction and the SpokePool event it emitted. Match the origin chain, deposit ID, input token address, amount, recipient, destination chain, and fillDeadline. Token symbols are not enough: the same symbol can refer to different contracts, and balances must be compared in the token’s smallest units.
2. Check whether the destination fill occurred. Look for the matching fill event on the destination SpokePool or query the deposit status. Current deployments use the updated FundsDeposited and FilledRelay event names; older interfaces may label them V3FundsDeposited and FilledV3Relay. Match the event parameters, not just an explorer’s “success” label. If the destination transaction failed or no matching fill exists, the recipient has not been paid by that transaction.
3. Separate user delivery from relayer repayment. A relayer can front destination funds and wait for later reimbursement through protocol settlement. So a filled transfer can still appear as an outstanding relayer claim even though the recipient already received tokens. The origin SpokePool’s token balance is pooled capital, not a deposit-specific vault; it may rise or fall as bundles rebalance funds. A lower balance than the sum of deposits is not, by itself, evidence that a particular claim is unpaid.
4. Check expiry, partial fills, and refund status. A deposit past its fillDeadline may become eligible for a refund, but expiry is not the same as refund execution. A refund is processed through a later settlement bundle and can take hours. Partial fills also change the accounting: the remaining amount may follow a slow-fill path instead of a full refund. Use the status endpoint as a useful index, then confirm terminal actions on-chain.
Use the claim state to decide what to do next
For a balance reconciliation, group records by chain, token contract, and settlement block range. Compare the SpokePool’s token balance with deposits, fills, refund executions, and bundle transfers over that same range. Then inspect the bundle’s block bounds and relevant roots: relayer refund roots represent amounts owed to relayers, while slow-relay roots represent deposits queued for fallback fills. A raw balance comparison that ignores these pending claims and movements will not balance reliably.
For example, say 100 USDC leaves your wallet on Base, and the matching destination fill sends 99.8 USDC to your recipient. Before the fill, your claim is for delivery; after it, delivery is complete, while the relayer’s reimbursement can remain unsettled. If no fill appears and the deadline has passed, look for expiry and then an origin-chain refund execution to the configured refund address. Do not resend the same transfer just because reimbursement is still pending.
If the status view and chain events disagree, trust the confirmed chain events for what happened and check that you used the right chain, token, and deposit ID. In your place, I’d save both transaction hashes, verify the recipient’s destination balance, and wait for the refund or settlement path indicated by the on-chain state before taking another action.
Comments
Post a Comment