The Liquidity Bridge Contract (LBC) manages the interaction between users and liquidity providers (LP) in order to achieve fast peg-ins and peg-outs.
- A user and an LP agree on the conditions of the service
- The user makes a deposit in BTC
- After a number of confirmations, the LP performs a call in RSK on behalf of the user advancing the funds
- After the deposit achieves a number of additional confirmations, the Bridge contract refunds the LBC in RBTC. The LBC then pays the LP for the service.
Note that the call performed by the LP can be a transfer of value to an account or a call to a contract method. This is specified by the value
and data
arguments of the call.
- A user and an LP agree on the conditions of the service
- The user sends RBTC to the LBC using depositPegout function
- After a number of confirmations, the LP makes a deposit in the Bitcoin address specified by user
- After the deposit achieves a number of additional confirmations, the LP calls refundPegout function in LBC so the contract refunds the LP in RBTC and pay him for the service
- Once the LP has been refunded with RBTC he sends that RBTC to the Bridge contract to convert it to BTC and get the liquidity back
The quote structure defines the conditions of a service, and acts as a contract between users and LPs.
PegIn Quotes consist of:
PeginQuote {
bytes20 fedBtcAddress; // the BTC address of the Powpeg
address lbcAddress; // the address of the LBC
address liquidityProviderRskAddress; // the RSK address of the LP
bytes btcRefundAddress; // a user BTC refund address
address rskRefundAddress; // a user RSK refund address
bytes liquidityProviderBtcAddress; // the BTC address of the LP
uint callFee; // the fee charged by the LP
uint penaltyFee; // the penalty that the LP pays if it fails to deliver the service
address contractAddress; // the destination address of the peg-in
bytes data; // the arguments to send in the call
uint gasLimit; // the gas limit
uint nonce; // a nonce that uniquely identifies this quote
uint value; // the value to transfer in the call
uint agreementTimestamp; // the timestamp of the agreement
uint timeForDeposit; // the time (in seconds) that the user has to achieve one confirmation on the BTC deposit
uint callTime; // the time (in seconds) that the LP has to perform the call on behalf of the user after the deposit achieves the number of confirmations
uint depositConfirmations; // the number of confirmations that the LP requires before making the call
bool callOnRegister: // a boolean value indicating whether the callForUser can be called on registerPegIn.
uint256 productFeeAmount; // the fee payed to the network DAO
uint256 gasFee; // the fee payed to the LP to cover the gas of the RSK transaction
}
PegOut Quotes consist of:
PegOutQuote {
address lbcAddress; // the address of the LBC
address lpRskAddress; // the RSK address of the LP
bytes btcRefundAddress; // a user BTC refund address
address rskRefundAddress; // a user RSK refund address
bytes lpBtcAddress; // the BTC address of the LP
uint callFee; // the fee charged by the LP
uint penaltyFee; // the penalty that the LP pays if it fails to deliver the service
uint nonce; // a nonce that uniquely identifies this quote
bytes deposityAddress; // the destination address of the peg-out
uint value; // the value to transfer in the call (in wei)
uint agreementTimestamp; // the timestamp of the agreement
uint depositDateLimit // the limit timestamp for the user to do the deposit
uint depositConfirmations; // the number of confirmations that the LP requires before making the call
uint transferConfirmations; // the number of confirmations that the BTC transfer requires to be refunded
uint transferTime; // the time (in seconds) that the LP has to transfer on behalf of the user after the deposit achieves the number of confirmations
uint expireDate; // the timestamp to consider the quote expired
uint expireBlock; // the block number to consider the quote expired
uint256 productFeeAmount; // the fee payed to the network DAO
uint256 gasFee; // the fee payed to the LP to cover the fee of the BTC transaction
}
function callForUser(
Quote quote
) returns bool success
This method performs a call on behalf of a user.
* quote: The quote that identifies the service
Boolean indicating whether the call was successful
function registerPegIn(
Quote quote,
bytes signature,
bytes btcRawTransaction,
bytes partialMerkleTree,
uint256 height
) returns int executionStatus
This method requests the Bridge contract on RSK a refund for the service.
* quote The quote of the service
* signature The signature of the quote
* btcRawTransaction The peg-in transaction
* partialMerkleTree The merkle tree path that proves transaction inclusion
* height The block that contains the peg-in transaction
This method returns the amount transferred to the contract or an [error code](https://github.com/rsksmart/RSKIPs/blob/fast-bridge-alternative/IPs/RSKIP176.md#error-codes).
function isOperational(address addr) external view returns (bool)
Checks whether a liquidity provider can deliver a pegin service
* addr: address of the liquidity provider
Whether the liquidity provider is registered and has enough locked collateral
function isOperationalForPegout(address addr) external view returns (bool)
Checks whether a liquidity provider can deliver a pegout service
* addr: address of the liquidity provider
Whether the liquidity provider is registered and has enough locked pegout collateral
function register(
string memory _name,
string memory _apiBaseUrl,
bool _status,
string memory _providerType
) external payable onlyEoa returns (uint)
Registers msg.sender as a liquidity provider with msg.value as collateral
* name: name of the LP
* apiBaseUrl: url of this LP's Liquidity Provider Server instance
* status: if the LP is active
* providerType: if the LP allows pegin operations, pegout operations or both
The registered provider ID
function getProviders(
uint[] memory providerIds
) external view returns (LiquidityProvider[] memory)
Retrieves the information of a group of liquidity providers
* providerIds: IDs of the providers to fetch
Array with the information of the requested LPs
function withdrawCollateral() external
Used to withdraw the locked collateral. It is only for LPs who have resigned
function resign() external
Used to resign as a liquidity provider
function addCollateral() external payable
Increases the amount of collateral of the sender
function addPegoutCollateral() external payable
Increases the amount of pegout collateral of the sender
function withdraw(uint256 amount) external
Used by LPs to withdraw funds
* amount: the amount to withdraw
function refundPegOut(
bytes32 quoteHash,
bytes calldata btcTx,
bytes32 btcBlockHeaderHash,
uint256 partialMerkleTree,
bytes32[] memory merkleBranchHashes
) public
Validates that the LP made the deposit of the service and applies the corresponding punishments if any apply
* quoteHash: the hash of the pegout quote representing the service
* btcTx: raw btc transaction
* btcBlockHeaderHash: header of the block where the transaction was included
* partialMerkleTree: PMT to validate transaction
* merkleBranchHashes: merkleBranchHashes used by the bridge to validate transaction
function refundUserPegOut(
bytes32 quoteHash
) public
Allows user to get his money back if LP didn't made the BTC deposit
* quote: the hash of the pegout quote to be refunded
function depositPegout(
PegOutQuote memory quote,
bytes memory signature
) external payable
Used by the user to deposit the payment of a pegout service
* quote: the accepted pegout quote
* signature: signature of the LP expressing commitment to pay for the quote
function setProviderStatus(
uint _providerId,
bool status
) external
Enables or disables an specific liquidity provider
* _providerId: the id of the provider to modify its status
* status: the new status
function updateProvider(
string memory _name,
string memory _url
) external
Updates the stored information about the LP (msg.sender)
* _name: the new provider name
* _url: the new LPS url
function isPegOutQuoteCompleted(
bytes32 quoteHash
) external view returns (bool)
Returns whether a given quote has been completed (refunded to the LP or the user) or not
* quoteHash: hash of the pegout quote
function deposit() external payable
Allows the LP to increase its balance by the msg.value amount
validatePeginDepositAddress(
PeginQuote memory quote,
bytes memory depositAddress
) external view returns (bool)
Validates if a given BTC address is the derivate deposit address for a pegin quote * quote: the quote of the pegin service * depositAddress: the bytes of the deposit address to validate (should include the 4 bytes of the base58check checksum)
Whether the address is the correct deposit address for that quote or not
hashQuote(
PeginQuote memory quote
) public view returns (bytes32)
Calculates hash of a pegin quote. Besides calculation, this function also validates the quote. * quote: the pegin quote to hash
The 32 bytes of the quote hash
hashPegoutQuote(
PegOutQuote memory quote
) public view returns (bytes32)
Calculates hash of a pegout quote. Besides calculation, this function also validates the quote. * quote: the pegout quote to hash
The 32 bytes of the quote hash
getBalance(
address addr
) external view returns (uint256)
Returns the amount of funds of a liquidity provider * addr: The address of the liquidity provider
The balance of the liquidity provider
getCollateral(
address addr
) external view returns (uint256)
Returns the amount of pegin collateral locked by a liquidity provider * addr: The address of the liquidity provider
The amount of locked collateral for pegin operations
getPegoutCollateral(
address addr
) external view returns (uint256)
Returns the amount of pegout collateral locked by a liquidity provider * addr: The address of the liquidity provider
The amount of locked collateral for pegout operations
After the first dploy we don't have to change anymore the LiquidityBridgeContract.sol instead we need to create a new version like LiquidityBridgeContractV2.sol and uncomment and update the 3_upgrade_contracts.js script with the last version that will upgrade the contract. With that we can easily get back on any mistake and swicth version.
If you're working in your own alphanet you must have an environment variable called ALPHANET_RPC_URL
with the RPC server url so truffle can run all the necessary scripts.