Issue

Overview

The Issue module allows as user to create new interBTC tokens. The user needs to request interBTC through the requestIssue function, then send BTC to a Vault, and finally complete the issuing of interBTC by calling the executeIssue function. If the user does not complete the process in time, the Vault can cancel the issue request and receive a griefing collateral from the user by invoking the cancelIssue function. Below is a high-level step-by-step description of the protocol.

Step-by-step

The nominal control flow is as follows:

  1. Precondition: a Vault has locked collateral as described in the Vault Registry.

  2. A user executes the requestIssue function to open an issue request. The issue request includes the amount of interBTC the user wants to issue, the selected Vault, and a small collateral reserve to prevent Griefing.

  3. A user sends the equivalent amount of BTC to issue as interBTC to the Vault on the Bitcoin blockchain.

  4. The user or Vault acting on behalf of the user extracts a transaction inclusion proof of that locking transaction on the Bitcoin blockchain. The user or a Vault acting on behalf of the user executes the executeIssue function on the BTC Parachain. The issue function requires a reference to the issue request and the transaction inclusion proof of the Bitcoin locking transaction. If the function completes successfully, the user receives the requested amount of interBTC into his account.

  5. Optional: If the user is not able to complete the issue request within the predetermined time frame (IssuePeriod), the Vault is able to call the cancelIssue function to cancel the issue request adn will receive the griefing collateral locked by the user.

User Failsafe

To accommodate for user error, the bridge allows the execution of issue requests even when the user sends an incorrect BTC amount. Specifically, we distinguish the following cases:

  • The user sends less than the expected amount. The user has the option to execute the issue with this amount. However, it will lose part of its griefing collateral. If it sends e.g. 10% of the expected amount, it loses 90% of the griefing collateral. It will also receive 10% of the wrapped tokens. Because there is a cost associated with this choice, automatic execution of this issue request by Vaults is disallowed. The alternative for the user is to make another Bitcoin transfer, and to execute the issue with that transaction. In this case, however, it loses the Bitcoin sent in the first transaction.

  • The user sends more than the expected amount.

    • If the Vault has sufficient collateral to issue wrapped tokens for the sent amount, the size of the issue request is automatically increased and more collateral of the Vault is reserved. The user receives the amount corresponding to the received amount of Bitcoin. The issue fee is deducted from the updated (increased) amount.

    • If the Vault does not have sufficient collateral to issue the additional amount, only the amount that was originally requested is issued. A refund request is sent to the Vault to return the surplus Bitcoin (excluding a fee). Note, however, that there is no penalty for the Vault if it does not return the surplus Bitcoin since this is a user fault rather than a Vault fault.

Security

Vault Registry

The data access and state changes to the Vault registry are documented in Fig. 15 below.

Vault-Registry Issue

Fig. 15 The issue protocol interacts with three functions in the Vault Registry that handle updating the different token balances.

Fee Model

  • Issue fees are paid by users in interBTC when executing the request. The fees are transferred to the Parachain Fee Pool.

  • If an issue request is executed, the user’s griefing collateral is returned.

  • If an issue request is canceled, the Vault assigned to this issue request receives the griefing collateral.

Data Model

Scalars

IssuePeriod

The time difference between when an issue request is created and required completion time by a user. Concretely, this period is the amount by which ActiveBlockCount is allowed to increase before the issue is considered to be expired. The period has an upper limit to prevent griefing of Vault collateral.

IssueBtcDustValue

The minimum amount of BTC that is required for issue requests; lower values would risk the rejection of payment on Bitcoin.

Maps

IssueRequests

Users create issue requests to issue interBTC. This mapping provides access from a unique hash IssueId to a Issue struct. <IssueId, IssueRequest>.

Structs

IssueRequest

Stores the status and information about a single issue request.

Parameter

Type

Description

vault

AccountId

The address of the Vault responsible for this issue request.

opentime

BlockNumber

The ActiveBlockCount when the issue request was created.

period

BlockNumber

Value of the IssuePeriod when the request was made.

griefingCollateral

DOT

Security deposit provided by a user.

amount

interBTC

Amount of interBTC to be issued.

fee

interBTC

Fee charged to the user for issuing.

requester

AccountId

User account receiving interBTC upon successful issuing.

btcAddress

BtcAddress

Vault’s P2WPKH Bitcoin deposit address.

btcPublicKey

BtcPublicKey

Vault’s Bitcoin public key used to generate the deposit address.

btcHeight

u32

The highest recorded height of the relay at time of opening.

status

Enum

Status of the request: Pending, Completed or Cancelled.

Functions

requestIssue

A user opens an issue request to create a specific amount of interBTC. When calling this function, a user provides their parachain account identifier, the to be issued amount of interBTC, and the Vault to use in this process (account identifier). Further, they provide some (small) amount of DOT collateral (griefingCollateral) to prevent griefing.

Specification

Function Signature

requestIssue(requester, amount, vault, griefingCollateral)

Parameters

  • requester: The user’s account identifier.

  • amount: The amount of interBTC to be issued.

  • vault: The address of the Vault involved in this issue request.

  • griefingCollateral: The collateral amount provided by the user as griefing protection.

Events

Preconditions

  • The function call MUST be signed by requester.

  • The BTC Parachain status in the Security component MUST NOT be SHUTDOWN:2.

  • The BTC-Relay MUST be initialized.

  • The Vault MUST be registered and active.

  • The Vault MUST NOT be banned.

  • The amount MUST be greater than or equal to IssueBtcDustValue.

  • The griefingCollateral MUST exceed or equal the value of request amount at the current exchange-rate, multiplied by IssueGriefingCollateral.

  • The griefingCollateral MUST be equal or less than the requester’s free balance in the Griefing Collateral Currency.

  • The tryIncreaseToBeIssuedTokens function MUST return a new BTC deposit address for the Vault ensuring that the Vault’s free collateral is above the SecureCollateralThreshold for the requested amount and that a unique BTC address is used for depositing BTC.

  • A new unique issuedId MUST be generated via the generateSecureId function.

Postconditions

  • The Vault’s toBeIssuedTokens MUST increase by amount.

  • The requester’s free balance in the Griefing Collateral Currency MUST decrease by griefingCollateral.

  • The requester’s locked balance in the Griefing Collateral Currency MUST increase by griefingCollateral.

  • A new BTC deposit address for the Vault MUST be generated by the tryIncreaseToBeIssuedTokens.

  • The new issue request MUST be created as follows:

    • issue.vault: MUST be the vault.

    • issue.opentime: MUST be the ActiveBlockCount of the current block of this transaction.

    • issue.period: MUST be the current IssuePeriod.

    • issue.griefingCollateral: MUST be the griefingCollateral amount passed to the function.

    • issue.amount: MUST be amount minus issue.fee.

    • issue.fee: MUST equal amount multiplied by IssueFee.

    • issue.requester: MUST be the requester

    • issue.btcAddress: MUST be the BTC address returned from the tryIncreaseToBeIssuedTokens

    • issue.btcPublicKey: MUST be the BTC public key returned from the tryIncreaseToBeIssuedTokens

    • issue.btcHeight: MUST be the current Bitcoin height as stored in the BTC-Relay.

    • issue.status: MUST be Pending.

  • The new issue request MUST be inserted into IssueRequests using the generated issueId as the key.

executeIssue

An executor completes the issue request by sending a proof of transferring the defined amount of BTC to the vault’s address.

Specification

Function Signature

executeIssue(executorId, issueId, rawMerkleProof, rawTx)

Parameters

  • executor: the account of the user.

  • issueId: the unique hash created during the requestIssue function.

  • rawMerkleProof: Raw Merkle tree path (concatenated LE SHA256 hashes).

  • rawTx: Raw Bitcoin transaction including the transaction inputs and outputs.

Events

Preconditions

  • The function call MUST be signed by executor.

  • The BTC Parachain status in the Security component MUST NOT be SHUTDOWN:2.

  • The issue request for issueId MUST exist in IssueRequests.

  • The issue request for issueId MUST NOT have expired.

  • The rawTx MUST be valid and contain a payment to the Vault.

  • The rawMerkleProof MUST be valid and prove inclusion to the main chain.

  • If the amount transferred is less than issue.amount + issue.fee, then the executor MUST be the account that made the issue request.

Postconditions

  • If the amount transferred IS less than the issue.amount + issue.fee:

    • The Vault’s toBeIssuedTokens MUST decrease by the deficit (issue.amount - amountTransferred).

    • The Vault’s free balance in the Griefing Collateral Currency MUST increase by the griefingCollateral * (1 - amountTransferred / (issue.amount + issue.fee)).

    • The requester’s free balance in the Griefing Collateral Currency MUST increase by the griefingCollateral * amountTransferred / (issue.amount + issue.fee).

    • The issue.fee MUST be updated to the amount transferred multiplied by the IssueFee.

    • The issue.amount MUST be set to the amount transferred minus the updated issue.fee.

  • If the amount transferred IS NOT less than the expected amount:

    • The requester’s free balance in the Griefing Collateral Currency MUST increase by the griefingCollateral.

    • If the amount transferred IS greater than the expected amount:

      • If the Vault IS NOT liquidated and has sufficient collateral:

        • The Vault’s toBeIssuedTokens MUST increase by the surplus (amountTransferred - issue.amount).

        • The issue.fee MUST be updated to the amount transferred multiplied by the IssueFee.

        • The issue.amount MUST be set to the amount transferred minus the updated issue.fee.

      • If the Vault IS NOT liquidated and does not have sufficient collateral:

        • There MUST exist a Refund request which references issueId.

  • The requester’s locked balance in the Griefing Collateral Currency MUST decrease by issue.griefingCollateral.

  • The issue.status MUST be set to Completed.

  • The Vault’s toBeIssuedTokens MUST decrease by issue.amount + issue.fee.

  • The Vault’s issuedTokens MUST increase by issue.amount + issue.fee.

  • The user MUST receive issue.amount interBTC in its free balance.

  • Function distributeReward MUST complete successfully - parameterized by issue.fee.

cancelIssue

If an issue request is not completed on time, the issue request can be cancelled.

Specification

Function Signature

cancelIssue(requester, issueId)

Parameters

  • requester: The sender of the cancel transaction.

  • issueId: the unique hash of the issue request.

Events

Preconditions

  • The function call MUST be signed by requester.

  • The BTC Parachain status in the Security component MUST NOT be SHUTDOWN:2.

  • The issue request for issueId MUST exist in IssueRequests.

  • The issue request MUST have expired.

Postconditions

  • If the vault IS liquidated:

  • If the Vault IS NOT liquidated:

  • The requester’s locked balance in the Griefing Collateral Currency MUST decrease by the griefingCollateral.

  • The vault’s toBeIssuedTokens MUST decrease by issue.amount + issue.fee.

  • The issue status MUST be set to Cancelled.

Events

RequestIssue

Emit an event if a user successfully open a issue request.

Event Signature

RequestIssue(issueId, requester, amount, fee, griefingCollateral, vault, btcAddress, btcPublicKey)

Parameters

  • issueId: A unique hash identifying the issue request.

  • requester: The user’s account identifier.

  • amount: The amount of interBTC requested.

  • fee: The amount of interBTC to mint as fees.

  • griefingCollateral: The security deposit provided by the user.

  • vault: The address of the Vault involved in this issue request.

  • btcAddress: The Bitcoin address of the Vault.

  • btcPublicKey: The Bitcoin public key of the Vault.

Functions

IssueAmountChange

Emit an event if the issue amount changed for any reason.

Event Signature

IssueAmountChange(issueId, amount, fee, griefingCollateral)

Parameters

  • issueId: A unique hash identifying the issue request.

  • amount: The amount of interBTC requested.

  • fee: The amount of interBTC to mint as fees.

  • griefingCollateral: Confiscated griefing collateral.

Functions

ExecuteIssue

Event Signature

ExecuteIssue(issueId, requester, amount, vault, fee)

Parameters

  • issueId: A unique hash identifying the issue request.

  • requester: The user’s account identifier.

  • amount: The amount of interBTC issued to the user.

  • vault: The address of the Vault involved in this issue request.

  • fee: The amount of interBTC minted as fees.

Functions

CancelIssue

Event Signature

CancelIssue(issueId, requester, griefingCollateral)

Parameters

  • issueId: the unique hash of the issue request.

  • requester: The sender of the cancel transaction.

  • griefingCollateral: The released griefing collateral.

Functions

Error Codes

ERR_VAULT_NOT_FOUND

  • Message: “There exists no Vault with the given account id.”

  • Function: requestIssue

  • Cause: The specified Vault does not exist.

ERR_VAULT_BANNED

  • Message: “The selected Vault has been temporarily banned.”

  • Function: requestIssue

  • Cause: Issue requests are not possible with temporarily banned Vaults

ERR_INSUFFICIENT_COLLATERAL

ERR_UNAUTHORIZED_USER

  • Message: “Unauthorized: Caller must be associated user”

  • Function: executeIssue

  • Cause: The caller of this function is not the associated user, and hence not authorized to take this action.

ERR_ISSUE_ID_NOT_FOUND

  • Message: “Requested issue id not found.”

  • Function: executeIssue

  • Cause: Issue id not found in the IssueRequests mapping.

ERR_COMMIT_PERIOD_EXPIRED

  • Message: “Time to issue interBTC expired.”

  • Function: executeIssue

  • Cause: The user did not complete the issue request within the block time limit defined by the IssuePeriod.

ERR_TIME_NOT_EXPIRED

  • Message: “Time to issue interBTC not yet expired.”

  • Function: cancelIssue

  • Cause: Raises an error if the time limit to call executeIssue has not yet passed.

ERR_ISSUE_COMPLETED

  • Message: “Issue completed and cannot be cancelled.”

  • Function: cancelIssue

  • Cause: Raises an error if the issue is already completed.