Vault Nomination

Overview

Vault Nomination is a feature aimed at increasing ONEBTC issuance capacity which introduces two actors: Nominators and Operators. Vaults who opt in to this feature take on the additional role of nomination Operators. A Nominator is anyone who locks their free collateral so that Operators they trust can issue ONEBTC backed by the nominated collateral. Nominators are rewarded a fraction of the fees generated by their collateral, while the rest of the fees is given to the Operator. Operators are assumed to be trusted by their nominators not to steal Bitcoin backed by nominated collateral.

Step-by-step

  1. Vaults opt in to the nomination feature, becoming Operators.
  2. The maximum nomination an Operator can receive is bounded by their own locked collateral.
  3. Nominators select one or more Operators and lock their collateral balance onto the BTC Bridge.
  4. Nominators can go offline and their nominated collateral will generate rewards passively.
  5. Operator and Nominator collateral cannot be withdrawn directly. Rather, withdrawals are subject to an unbonding period.
  6. In case of Operator failure, Nominators are returned any left-over collateral (after victim users are reimbursed).

Protocol

Security Assumptions and Considerations

  1. The operating Vault is trusted by its Nominators not to steal the ONEBTC issued with their collateral.
  2. There is no transitive trust. If a user trusts Vault A and Vault A trusts Vault B, the user does not trust Vault B.
  3. Nominators are mostly-offline agents, who are slow to respond to system changes.
  4. Vaults are always-online agents, who can promptly react to system updates.
  5. A Nominator may expose the Vault and the other Nominators to additional economic risk by withdrawing nominated collateral during an exchange rate spike. Similarly, the Vault may expose its Nominators to additional economic risk by withdrawing excess collateral.
    • Note: in the usual case, this should be handled by having the different collateral thresholds (secure, premium redeem, liquidation). But in extreme cases (very high exchange rate volatility), it might cause concern.

Vault Nomination Protocol

  1. Vaults can choose to opt in and out of the Nomination protocol. If they opt-in they take on the additional role of an Operator.
  2. Nominators select an Operator to which they can delegate ONE balance as collateral. As a reward, they will earn a fraction of the ONEBTC and ONE fees generated by this collateral. The other fraction of these fees is received by the Operator.
  3. Vault replacement is disallowed for Operators with nominated collateral. Otherwise, Security Assumptions 1 and 2 would be violated.
  4. The nominated ONE:
    1. Is locked on the bridge
    2. Cannot be withdrawn by the operating Vault
    3. Is capped at a fraction of the Vault’s deposited collateral (Max Nomination Ratio). This prevents the Operator from withdrawing its entire collateral and only exposing Nominators to economic risk, or stealing without liquidation consequences. This means that an Operator can only withdraw collateral as long as the fraction of nominated collateral does not exceed the threshold cap. Capping Nominator collateral also prevents Operators being “outnumbered” by Nominators and their relative fee earnings being marginalized.
  5. Liquidation slashing is handled as follows.
    1. In case the collateral managed by the Operator falls below the liquidation threshold, the Operator and Nominators are slashed proportionally to their collateral.
    2. In case the Operator steals Bitcoin deposited at its address, its collateral is used to cover as much of the slashed amount as possible. If the Operator’s collateral was not enough to cover the entire amount, the Nominators are slashed proportionally for the remaining amount.
  6. Collateral withdrawals are first requested and then executed. A withdrawal request:
    1. Decreases the issuable ONEBTC capacity.
    2. May be cancelled if not executed. The amount in the cancelled withdrawal request becomes backing collateral again.
    3. Is subject to a window of delay (unbonding period) that allows Nominators and the Operator to react.
      1. Operator Unbonding Period. This window is longer, because Nominators are assumed to be mostly offline.
      2. Nominator Unbonding Period. This window is shorter, because the Vault Operator is assumed to always be online.
  7. Collateral withdrawals are subject to the following restrictions.
    1. The remaining collateralization of an operator must not be below the secure collateral threshold.
    2. Operator withdrawals must not cause nominated collateral to exceed the Max Nomination Ratio.
  8. Forced collateral withdrawal. If an operator’s withdrawal would result in a violation of the Max Nomination Ratio, automatically refund excess nominated collateral to the nominators, proportionally. Both the operator withdrawal and the nominator refunds are subject to the unbonding period.
  9. If an Operator issued zero ONEBTC, it can deregister and automatically refund Nominators their collateral.
  10. When an Operator is banned, its collateralization is lowered to the secure collateral threshold by automatically refunding nominated ONE, proportionally.

Data Model

Scalars

NominationEnabled

Flag indicating whether this feature is enabled. As Operators may have issued ONEBTC with nominated collateral when this feature is turned off, a False value of this scalar only prevents the opting in of new Operators.

MaxNominatorsPerOperator

Maximum number of nominators a single operator can have.

  • Initial value: 100

OperatorUnbondingPeriod

Unbonding period, measured in blocks, that Operator withdrawal requests are subject to.

  • Initial value: 14400 (24 hours)

NominatorUnbondingPeriod

Unbonding period, measured in blocks, that Nominator withdrawal requests are subject to.

  • Initial value: 7200 (12 hours)

Maps

Operators

Mapping from accounts to Operator structs.

Structs

Nominator

Stores the information of a Nominator.

Parameter Type Description
id AccountId The ID of the Nominator represented by this struct.
collateral ONE Collateral amount nominated.
pendingWithdrawals BTreeMap Mapping from the withdrawal request ID to the (maturityBlock, amount) tuple.
collateralToBeWithdrawn ONE Collateral that is not backing any ONEBTC and has been requested for withdrawal.

Operator

Stores the information of an Operator.

Parameter Type Description
id AccountId The ID of the Nominator represented by this struct.
nominators BTreeMap Mapping from the ID of a nominator to a Nominator struct.
totalNominatedCollateral ONE Total amount of collateral received as nomination.
pendingWithdrawals BTreeMap Mapping from the withdrawal request ID to the (maturityBlock, amount) tuple.
collateralToBeWithdrawn ONE Collateral that is not backing any ONEBTC and has been requested for withdrawal.

Functions

getMaxNominationRatio

Returns the maximum nomination ratio (as %), denoting the maximum totalNominatedCollateral:operatorCollateral value allowed.

  • Example (current parameterization): (1.5 / 1.2) - 1 = 25%

Specification

Function Signature

getMaxNominationRatio()

Function Sequence

  1. Return (secureCollateralThreshold / auctionCollateralThreshold) - 1

setNominationEnabled

Set the feature flag for vault nomination.

Specification

Function Signature

setNominationEnabled(enabled)

Parameters

  • enabled: True if nomination should be enabled, False if it should be disabled

Function Sequence

  1. Ensure the calling account is root.
  2. Set the NominationEnabled scalar to the value of the enabled parameter

optInToNomination

Become an Operator in the Vault Nomination protocol

Specification

Function Signature

optInToNomination(operatorId)

Parameters

  • operatorId: the id of the vault to mark as Nomination Operator.

Events

  • NominationOptIn(operatorId)

Errors

  • VaultNominationDisabled: the nomination feature is disabled.
  • NotAVault: the caller of the function is not a vault.
  • VaultAlreadyOptedInToNomination: the caller of the function is already opted in.

Preconditions

  • The BTC Bridge status in the Security component must be set to RUNNING:0.

Function Sequence

  1. Check if the nomination feature is enabled. If not, throw VaultNominationDisabled.
  2. Check if the caller is a vault. If not, throw NotAVault.
  3. Check if the caller is not already opted in to nomination. If not, throw VaultAlreadyOptedInToNomination.
  4. Instantiate an Operator struct.
  5. Add the struct to the Operators mapping.

optOutOfNomination

Deregister from being an Operator in the Vault Nomination protocol.

Specification

Function Signature

optOutOfNomination(operatorId)

Parameters

  • operatorId: the id of the vault to deregister from the nomination feature.

Events

  • NominationOptOut(operatorId)

Errors

  • VaultNotOptedInToNomination: the caller is not an Operator.

Preconditions

  • The BTC Bridge status in the Security component must be set to RUNNING:0.

Function Sequence

  1. Check if the caller is a nomination Operator. If not, throw VaultNotOptedInToNomination.
  2. Immediately refund all nominated collateral, bypassing the unbonding period.
  3. Remove caller from the Operators mapping.

depositNominatedCollateral

Nominate collateral to a selected Operator.

Specification

Function Signature

depositNominatedCollateral(nominatorId, operatorId, amount)

Parameters

  • nominatorId: the id of the user nominating collateral.
  • operatorId: the id of the operator to receive the nomination.
  • amount: the amount of collateral to nominate.

Events

  • IncreaseNominatedCollateral(nominatorId, operatorId, amount)

Errors

  • VaultNominationDisabled: the nomination feature is disabled.
  • VaultNotOptedInToNomination: the vault is not an Operator.
  • DepositViolatesMaxNominationRatio: the amount of nomination would cause the Max Nomination Ratio to be exceeded for this operatorId.
  • OperatorHasTooManyNominators: the number of Nominators to the current Operator has reached MaxNominatorsPerOperator.

Preconditions

  • The BTC Bridge status in the Security component must be set to RUNNING:0.

Function Sequence

  1. Check if the nomination feature is enabled. If not, throw VaultNominationDisabled.
  2. Check if operatorId represents an operator. If not, throw VaultNotOptedInToNomination.
  3. Check that the additional nominated amount does not cause the Max Nomination Ratio to be exceeded. If not, throw DepositViolatesMaxNominationRatio.
  4. If the caller had no nomination to this Operator, check that the MaxNominatorsPerOperator would not be exceeded by receiving this nomination. If MaxNominatorsPerOperator would be exceeded, throw OperatorHasTooManyNominators.
  5. Update the Operator object to create or update the Nominator entry of the caller.
  6. Move collateral from nominatorId to the backing_collateral of operatorId in the Vault Registry.

requestOperatorCollateralWithdrawal

Request an operator collateral withdrawal, subject to an unbonding period.

Specification

Function Signature

requestOperatorCollateralWithdrawal(operatorId, amount)

Parameters

  • operatorId: the id of the caller.
  • amount: the amount to withdraw.

Events

  • RequestOperatorCollateralWithdrawal(requestId, operatorId, maturity, amount)

Errors

  • VaultNotOptedInToNomination: the caller is not an Operator.
  • InsufficientCollateral: the caller has requested to withdraw more collateral than it owns.

Preconditions

  • The BTC Bridge status in the Security component must be set to RUNNING:0.

Function Sequence

  1. Check if operatorId is an operator. If not, throw VaultNotOptedInToNomination.
  2. Check if the operator has enough collateral of its own (excluding nominations). If not, throw InsufficientCollateral.
  3. Immediately refund, proportionally, nominated collateral that would cause the Max Nomination Ratio to be exceeded.
  4. Add the withdrawal request to the pendingWithdrawals array in the Operator struct.
  5. Decrease the backing_collateral of operatorId in the Vault Registry.

requestNominatorCollateralWithdrawal

Request a nominator collateral withdrawal, subject to an unbonding period.

Specification

Function Signature

requestNominatorCollateralWithdrawal(nominatorId, operatorId, amount)

Parameters

  • nominatorId: the id of the requester.
  • operatorId: the id of the operator to withdraw from.
  • amount: the amount to withdraw.

Events

  • RequestNominatorCollateralWithdrawal(requestId, nominatorId, operatorId, maturity, amount)

Errors

  • VaultNotOptedInToNomination: the operatorId is not an Operator.
  • NominatorNotFound: the nominatorId is not a Nominator.
  • TooLittleNominatedCollateral: the caller has requested to withdraw more collateral than it owns.

Preconditions

  • The BTC Bridge status in the Security component must be set to RUNNING:0.

Function Sequence

  1. Check operatorId is an operator. If not, throw VaultNotOptedInToNomination.
  2. Check nominatorId is a nominator. If not, throw NominatorNotFound.
  3. Check if the caller has at least as much nominated collateral as amount. If not, throw TooLittleNominatedCollateral.
  4. Add the withdrawal request to the pendingWithdrawals array in the Nominator struct for nominatorId, inside the Operator struct of operatorId.
  5. Decrease the backing_collateral of operatorId in the Vault Registry.

executeOperatorWithdrawal

Execute all matured (unbonded) withdrawal requests of an operator.

Specification

Function Signature

executeOperatorWithdrawal(operatorId)

Parameters

  • operatorId: the id of the requester.

Events

  • ExecuteOperatorCollateralWithdrawal(operatorId, unbondedCollateral)

Errors

  • VaultNotOptedInToNomination: the operatorId is not an Operator.
  • NoMaturedCollateral: either no collateral withdrawal has been requested, or the requests have not matured yet.

Preconditions

  • The BTC Bridge status in the Security component must be set to RUNNING:0.

Function Sequence

  1. Check operatorId is an operator. If not, throw VaultNotOptedInToNomination.
  2. Iterate through the withdrawalRequests in the Operator struct to determine how much collateral was unbonded, removing matured requests.
  3. If there is zero unbonded collateral, throw NoMaturedCollateral.

executeNominatorWithdrawal

Execute all matured (unbonded) withdrawal requests of a nominator.

Specification

Function Signature

executeNominatorWithdrawal(nominatorId, operatorId)

Parameters

  • nominatorId: the id of the requester.
  • operatorId: the id of the operator.

Events

  • ExecuteNominatorCollateralWithdrawal(nominatorId, operatorId, unbondedCollateral)

Errors

  • VaultNotOptedInToNomination: the operatorId is not an Operator.
  • NoMaturedCollateral: either no collateral withdrawal has been requested, or the requests have not matured yet.
  • NominatorNotFound: the nominatorId is not a Nominator.

Preconditions

  • The BTC Bridge status in the Security component must be set to RUNNING:0.

Function Sequence

  1. Check operatorId is an operator. If not, throw VaultNotOptedInToNomination.
  2. Check nominatorId is a nominator. If not, throw NominatorNotFound.
  3. Iterate through the withdrawalRequests array in the Nominator struct inside the Operator struct for operatorId. Determine how much collateral was unbonded, removing matured requests.
  4. If there is zero unbonded collateral, throw NoMaturedCollateral.

cancelOperatorWithdrawal

Cancel an operator’s withdrawal request.

Specification

Function Signature

cancelOperatorWithdrawal(operatorId, requestId)

Parameters

  • operatorId: the id of the operator.
  • requestId: the id of the withdrawal request.

Events

  • CancelOperatorCollateralWithdrawal(requestId, operatorId)

Errors

  • VaultNotOptedInToNomination: the operatorId is not an Operator.
  • WithdrawalRequestNotFound: no withdrawal request found for the given id.

Preconditions

  • The BTC Bridge status in the Security component must be set to RUNNING:0.

Function Sequence

  1. Check operatorId is an operator. If not, throw VaultNotOptedInToNomination.
  2. Check requestId corresponds to an actual withdrawal request. If not, throw WithdrawalRequestNotFound.
  3. Remove the withdrawal request from the withdrawalRequests array in the Operator struct for operatorId.
  4. Increase the backing collateral of operatorId in the Vault Registry by the amount in the withdrawal request.

cancelNominatorWithdrawal

Cancel a nominator’s withdrawal request.

Specification

Function Signature

cancelNominatorWithdrawal(nominatorId, operatorId, requestId)

Parameters

  • nominatorId: the id of the nominator.
  • operatorId: the id of the operator.
  • requestId: the id of the withdrawal request.

Events

  • CancelNominatorCollateralWithdrawal(requestId, nominatorId, operatorId)

Errors

  • VaultNotOptedInToNomination: the operatorId is not an Operator.
  • NominatorNotFound: the nominatorId is not a Nominator.
  • WithdrawalRequestNotFound: no withdrawal request found for the given id.

Preconditions

  • The BTC Bridge status in the Security component must be set to RUNNING:0.

Function Sequence

  1. Check operatorId is an operator. If not, throw VaultNotOptedInToNomination.
  2. Check nominatorId is a nominator. If not, throw NominatorNotFound.
  3. Check requestId corresponds to an actual withdrawal request. If not, throw WithdrawalRequestNotFound.
  1. Remove the withdrawal request from the withdrawalRequests array in the Nominator struct inside the Operator struct for operatorId.
  2. Increase the backing collateral of operatorId in the Vault Registry by the amount in the withdrawal request.

Events

NominationOptIn

Event Signature

NominationOptIn(account)

Parameters

  • account: the id of the operator who opten in

Functions

NominationOptOut

Event Signature

NominationOptOut(account)

Parameters

  • account: the id of the operator who opten out

Functions

IncreaseNominatedCollateral

Event Signature

IncreaseNominatedCollateral(nominatorId, operatorId, amount)

Parameters

  • nominatorId: the id of the nominator who is depositing collateral
  • operatorId: the id of the operator who receives the nomination
  • amount: the amount of nominated collateral

Functions

RequestOperatorCollateralWithdrawal

Event Signature

RequestOperatorCollateralWithdrawal(requestId, operatorId, maturityBlock, amount)

Parameters

  • requestId: the id of the request
  • operatorId: the id of the operator withdrawing collateral
  • maturityBlock: the block when the request can be executed
  • amount: the amount to withdraw

Functions

ExecuteOperatorCollateralWithdrawal

Event Signature

ExecuteOperatorCollateralWithdrawal(operatorId, amount)

Parameters

  • operatorId: the id of the operator withdrawing collateral
  • amount: the withdrawn amount

Functions

CancelOperatorCollateralWithdrawal

Event Signature

CancelOperatorCollateralWithdrawal(requestId, operatorId)

Parameters

  • requestId: the id of the withdrawal request to cancel
  • operatorId: the id of the operator who requested the withdrawal

Functions

RequestNominatorCollateralWithdrawal

Event Signature

RequestNominatorCollateralWithdrawal(requestId, nominatorId, operatorId, maturityBlock, amount)

Parameters

  • requestId: the id of the request
  • nominatorId: the id of the operator withdrawing collateral
  • operatorId: the id of the operator who nominated collateral is being withdrawn
  • maturityBlock: the block when the request can be executed
  • amount: the amount to withdraw

Functions

ExecuteNominatorCollateralWithdrawal

Event Signature

ExecuteNominatorCollateralWithdrawal(nominatorId, operatorId, amount)

Parameters

  • nominatorId: the id of the operator withdrawing collateral
  • operatorId: the id of the operator who nominated collateral is being withdrawn
  • amount: the withdrawn amount

Functions

CancelNominatorCollateralWithdrawal

Event Signature

CancelNominatorCollateralWithdrawal(requestId, nominatorId, operatorId)

Parameters

  • requestId: the id of the withdrawal request to cancel
  • nominatorId: the id of the nominator who requested the withdrawal
  • operatorId: the id of the operator who nominated collateral is being withdrawn

Functions