Smart Contract as LP
The liquidity pool mode of cBridge supports using a smart contract (eg. a multi-sig wallet) to provide liquidity, with the caveat of having to follow a special process to withdraw liquidity. This tutorial describes the process of adding and withdrawing liquidity using smart contracts.
This feature has only been released on a limited number of chains.
Note: Before adding any liquidity to cBridge from a smart contract, make sure you have read this tutorial and are comfortable with following the technical instructions.
In cBridge, all LPs are identified by their address regardless of the chain they use. Technically, it is possible for two different entities to occupy the same address but on different chains. For security purposes, a contract LP is only allowed to submit withdraw requests to the WithdrawInbox on the first chain on which they added liquidity. Note that this only restricts on which chain you can submit the withdraw request and it does not affect where the withdrawn liquidity comes from. For example, if you first added liquidity on Ethereum, then you need to submit the withdraw request to the WithdrawInbox on Ethereum. Within the request, you are still free to withdraw liquidity from BSC to Optimism.
To make sure your intended LP address is not occupied by someone else and to check which chain you can submit the withdraw request on, execute the following command:
curl -X GET 'https://cbridge-prod2.celer.app/v1/getLPOrigin?usr_addr=<your contract address>'
A response with a
0means that no LP with the given address has added liquidity. Since the address is not registered with the system, there is also no chain where you can submit a withdraw request yet, and you can proceed to Add Liquidity with confidence. A non-zero
chain-idrequires you to confirm that you have control of the address on the returned
chain_id. If not, it means the address has been occupied by someone else and you need to use a different address.
NOTE: If you added liquidity via a smart contract / multi-sig wallet before we added support for withdrawal on a particular chain and receive a
0response from the command above, please add liquidity again with a small value from the same contract to register it with the system. Only then will you be able to withdraw your previously added liquidity.
Skip this step if you are using generic multi-sig wallets such as Gnosis Safe.
You can query the liquidity by:
curl -X GET 'https://cbridge-prod2.celer.app/v1/getLPInfoList?addr=<your contract address>'
Look for the
Some explanations of the parameters:
_wdSeqis a unique identifier for each withdrawal.
_receiveris the receiver address on
_toChainis the chain ID to receive the tokens withdrawn.
_fromChainsare a list of chain IDs to withdraw the tokens from. We support cross-chain withdrawals, that is to withdraw the liquidity from multiple chains to a single chain.
_tokensare the token addresses on each chain. Make sure they refer to the same token symbol and they are supported by cBridge on all the chains involved.
_ratiosare the percentages of liquidity to be withdrawn from each chain. They should be all positive. The max ratio is 100000000, which means 100%.
_slippagesare the maximal allowed slippages for cross-chain withdrawals. Usually a small number such as 5000, which means 0.5%, should suffice. The max slippage is 1000000, which means 100%.
After the transaction has been confirmed for some period of time. Use the command below to query your withdrawal request, replace
<_toChain>with the input parameters when you submitted the withdrawal request to WithdrawInbox. Leave
curl -X GET 'https://cbridge-prod2.celer.app/v1/queryLiquidityStatus?seq_num=<_wdSeq>&lp_addr=<_receiver>&chain_id=<_toChain>&type=2&tx_hash='
Here is an example response:
A little explanation about the
statusfield in the response:
0means no withdrawal request found. Check your query command first. If the fields were set correctly, it is possible that your withdrawal request has not been reflected in the cBridge / SGN system yet so please retry after a little while. If it keeps being
0after quite a while, your request is likely rejected due to bad arguments. Check the instructions and try again. If you are sure the arguments are correct, it is possible that the withdraw amount is too large that it hit certain rate limits. Please contact us before you make another try.
1means the withdrawal request has been accepted, but not yet co-signed by validators. Please query again after a little while.
2means the withdrawal request is ready to be submitted on-chain. In this case, you will see a hex string in
wd_onchainalong with a number of strings in
3means the withdrawal request is being submitted on-chain.
4means the withdrawal request is completed, and tokens have been sent to the given address on the given chain if the request is not delayed due to large amount.
5means the withdrawal request has failed. Probably due to slippage being too small, but could be caused by other reasons such as insufficient liquidity or token transfer being disabled. Contact us for details before you make another try.
6means the withdrawal request has been delayed due to the amount being too large. It should usually turn into a
4after about 30 minutes.
If you see a
2, copy and save the
powersfields for later use.
Once you have received a response with status
2, prepare the input parameters for the on-chain withdrawal transaction. As described in the withdraw function, you need to supply
_powers. You can use an explorer like Etherscan to send the transaction.
wd_onchainyou saved corresponds to
_wdmsg. Go to base64-to-hex, paste
wd_onchainon the left, switch
NONEon the right, add a hex prefix
0xto the result on the right, and you will get
powers, do not change the order of parameters within the arrays.
_sigs. Convert the signature strings in
sorted_sigsone by one using the same way as with
wd_onchain, and put all
0xprefixed strings in an array
_signers. Prepare them the same way as
_powers. First, convert the strings the same way as with
wd_onchainbut this time without adding
0xprefixes. Second, go to hex-binary, switch
Decimal(10)in the middle and convert the result from the first step to decimal number. Put all the numbers you get in an array
With all the prepared parameters. Open Etherscan or whatever explorer you use, search for the cBridge address and connect to your wallet. Input the parameters to the withdraw function and send the transaction.
Note that large withdrawals might be subject to delays.