Celerbridge

Celerbridge contract LPs request withdrawals through WithdrawInbox on their first deposit chain

Celerbridge lets smart contract liquidity providers (LPs) request withdrawals through WithdrawInbox on the chain where they first added liquidity. This is the contract LP path in Celer's cBridge pool-based model. A request can draw the same supported token from several chains and direct the withdrawal to one receiving chain. The request chain, liquidity source chains, and receiving chain have different roles. The contract initiates the request; Celer State Guardian Network (SGN) validators then co-sign authorization for an on-chain withdrawal. Support requires the relevant contract deployments, and the documented frontend removal flow excludes smart contract LPs. The request's status identifies when validator authorization is ready for the receiving-chain pool's separate withdrawal call.

Each withdrawal ratio applies to its corresponding source-chain balance, allowing a contract LP to select different shares across supported chains.

Gathering pool liquidity on one destination chain

A contract LP can withdraw liquidity held across several supported chains to one receiving chain. For a pool position spread across networks, the request specifies each source chain separately. It pairs each chain with its token address, withdrawal percentage, and slippage allowance. Those entries describe liquidity to remove. The receiver and destination chain describe where tokens should arrive. Cross-chain transfers can move an LP's liquidity away from its original deposit chain.

The facility belongs to xLiquidity, cBridge's pool-based bridging model. LP removal concerns supplied pool liquidity. Transfer refunds concern tokens from failed bridging transactions. Their status queries and transaction inputs belong to different operations, even when both eventually return tokens.


WithdrawInbox connects the contract LP with SGN authorization

WithdrawInbox accepts the LP contract's instruction; SGN validators prepare authorization for execution by the pool on the receiving chain.

The contract's request

The LP contract calls the inbox's withdraw function on its permitted request chain. The request records the sender, receiving address, destination chain, and selected source-chain inputs. A confirmed inbox transaction establishes submission of those instructions, while SGN acceptance and validator signatures establish readiness for on-chain execution.

The pool's authorized withdrawal

The pool contract receives a validator-signed withdrawal message. Its call takes the message, signatures, signer addresses, and signing powers, while the inbox takes source-chain arrays and withdrawal preferences. Both contracts expose a withdraw function, so the contract address and argument types identify the operation.

Illustration: Celerbridge - The pool's authorized withdrawal

View full-size image

Which chain must a contract LP use to request a withdrawal?

A contract LP must submit its withdrawal request on the chain where it first added liquidity. cBridge identifies LPs by address across chains. Different entities can control the same address on different networks, so the origin rule limits where a contract can initiate requests. It leaves supported liquidity source chains and the receiving chain as separate choices. The getLPOrigin query returns the registered chain_id for the LP address.


Contract preparation before a pool deposit

Contract LP support requires a WithdrawInbox deployment and a contract able to interact with both the Pool and WithdrawInbox interfaces. The documented contract LP deployment list includes Ethereum, BNB Chain, Optimism, Polygon, Avalanche, Arbitrum, Conflux, Kava, zkSync Era, Moonbeam, Manta Pacific, and Base. Each chain has its own WithdrawInbox address. Token availability on every involved chain remains a separate requirement. Broader support for ordinary bridging does not establish compatibility with the contract withdrawal path.

For a previously unused LP address, getLPOrigin returning chain_id 0 indicates no registered origin. A nonzero response requires control of that address on the returned chain; otherwise, a different LP address is necessary. A custom contract needs the required interfaces before calling addLiquidity .


Encoding the balances, destination, and limits

Withdrawal parameters separate the destination from source balances, with a withdrawal ratio and cross-chain slippage limit for each source entry.

Source chains and token addresses

_fromChains lists the chains supplying liquidity, and _tokens contains the corresponding token address on each chain. The token entries must refer to the same symbol and have cBridge support throughout the withdrawal. _ratios and _slippages correspond to those same source entries. Keep each chain paired with its own token, ratio, and limit. The arrays must have matching lengths, and the source-chain array cannot be empty.

Recipient and request identifier

_receiver identifies the receiving address on _toChain , the destination chain ID. _wdSeq uniquely identifies the withdrawal request. Every new request needs a different sequence number. Keep that identifier alongside the receiver and destination chain because the status query uses those values. The request's sequence number and the submitting transaction's hash are separate identifiers.

Withdrawal ratios and slippage

_ratios uses a scale where 100,000,000 represents 100%. Each entry must be positive and cannot exceed that full-withdrawal value, applying to liquidity on its corresponding source chain. _slippages supplies maximal acceptable slippage for cross-chain withdrawal. Its scale makes 5,000 equivalent to 0.5%. A low allowance can cause failure when the withdrawal cannot satisfy it. An implementation with minimalMaxSlippage also enforces that configured lower bound. The allowance must meet the deployed value before the inbox accepts the request.


Conditions for withdrawing back to the deposit chain

Liquidity can return to the original deposit chain even when transfers have redistributed the LP's balances. The registered origin fixes where the contract requests removal. Choosing that same chain in _toChain makes it the withdrawal destination, while _fromChains identifies the balances now supplying the tokens.

  • The contract controls the LP address on its registered origin chain.
  • The origin chain has the required WithdrawInbox deployment.
  • The selected source chains support the same token symbol at their specified token addresses.
  • The withdrawal ratios and slippage limits correspond to those source balances.
  • _receiver identifies the intended recipient on the chosen destination chain.

Insufficient liquidity, disabled transfers, or unsuitable slippage can still prevent completion, even when the request uses the correct origin chain.

Reading withdrawal status before on-chain submission

queryLiquidityStatus tracks the contract withdrawal after the request transaction has had time to confirm. Set seq_num to _wdSeq , lp_addr to _receiver , and chain_id to _toChain . Keep type as 2 and tx_hash empty for this query.

Status 0 means the query found no withdrawal request, possibly because the system has not yet reflected it. Incorrect query arguments can produce this state too. Persistent absence can also involve rejected request arguments or amount-related limits. Status 1 means the system accepted the request, and validators have not yet co-signed it. Neither state establishes token delivery.

A queryLiquidityStatus response with status 2 means the withdrawal is ready for on-chain submission. Its response supplies wd_onchain , sorted_sigs , signers , and powers . Save these fields together for preparing the pool call.

Status 3 reports on-chain submission in progress. Status 4 denotes completion and delivery to the specified receiver, provided no large-amount delay still applies. The receiving chain and address must match the original request when checking token delivery.

Status 5 reports a failed withdrawal. Possible causes include insufficient slippage allowance, insufficient liquidity, or disabled token transfers. Status 6 identifies a delay triggered by the withdrawal amount. Monitor that existing request while the delay clears. A failed request, or persistent status 0 despite correct query arguments, calls for cBridge support before another attempt.

Preparing the pool contract's withdrawal arguments

Once status 2 supplies validator authorization, the receiving-chain pool's withdraw call needs correctly decoded bytes and numeric signing powers, with every returned array kept in order.

Message, signatures, and signer addresses

For the Base64-encoded response format, decode wd_onchain to hexadecimal and prefix the bytes with 0x for _wdmsg . Apply the same conversion to each sorted_sigs entry for _sigs and each signers entry for _signers . Preserve the order inside each returned array. Rebuilding a signature list independently of its signer list can break their alignment.

Signing powers as numeric values

Decode the powers entries from Base64, interpret their hexadecimal values as decimal integers, and supply the resulting numeric array as _powers . These final numbers do not take a 0x prefix. Signing powers belong to validator authorization. Withdrawal ratios describe the share of the LP's liquidity to remove.

What happens if a contract deposited before withdrawal support arrived?

An earlier contract LP needs another small deposit from the same contract if getLPOrigin still returns chain_id 0 after withdrawal support becomes available. This registration step applies to liquidity added before the relevant chain gained contract withdrawal support. The zero result concerns missing LP origin registration in this case. Registering the existing contract is a prerequisite for withdrawing its earlier liquidity through this path. It remains subject to the supported-chain and withdrawal requirements.


Liquidity redistribution and the amount still available

An LP's chain balances can change during cBridge activity because transfers redistribute supplied liquidity across networks. Once transfers redistribute the position, the original deposit no longer describes its chain-by-chain balances. Significant liquidity imbalance can also cause loss similar to impermanent loss in automated market makers. Later transfers in the reverse direction may recover that loss.

Liquidity fee earnings automatically add to total liquidity, so withdrawal percentages concern the available position with those accumulated earnings. A full-withdrawal ratio targets the available liquidity on its selected source chain. It does not guarantee recovery of the original deposit's value or restore the original distribution across networks.

Common questions about Celerbridge

Does a Gnosis Safe LP need custom contract preparation?

Gnosis Safe wallets can skip the custom contract preparation step in the contract LP procedure. That exception concerns preparation for interacting with Pool and WithdrawInbox. The wallet still follows the special contract withdrawal process and the origin-chain restriction. The exception does not extend support to chains lacking a WithdrawInbox deployment.

Are farming rewards paid out with a contract LP's liquidity withdrawal?

CELR farming rewards require a manual claim separate from liquidity removal. Pools with active farming sessions can earn those rewards alongside liquidity fees. Liquidity fee earnings automatically add to total liquidity, while farming rewards follow their own unlocking and claim process.

How can a contract LP query its remaining pool balances?

getLPInfoList returns liquidity information for the LP contract address supplied in addr. Inspect the liquidity_amt fields for the reported balances. This query uses the contract's LP address, which serves a different role from the withdrawal receiver. It reads liquidity information; it does not submit a removal request or establish that a pending withdrawal has completed.

Must the withdrawal receiver match the LP contract address?

WithdrawInbox permits a separate _receiver address from the contract submitting the request. The receiver identifies the destination account on _toChain. The sending contract remains the LP initiating removal through its registered origin chain. When tracking this withdrawal, the query's lp_addr parameter uses _receiver, even when it differs from the LP contract address.

Is the lifetime of a WithdrawInbox request fixed?

WithdrawInbox implementations exposing validityPeriod set each new request's deadline to the block timestamp plus that period. The contract owner can change the setting through setValidityPeriod for subsequent requests. This period describes the request's intended validity. It is separate from token arrival time and any amount-triggered delay, so it does not promise delivery within the same interval.

· updated