Fraud

Fraud

The library handles the logic for challenging Bridge wallets that committed fraud.

Anyone can submit a fraud challenge indicating that a UTXO being under the wallet control was unlocked by the wallet but was not used according to the protocol rules. That means the wallet signed a transaction input pointing to that UTXO and there is a unique sighash and signature pair associated with that input.

In order to defeat the challenge, the same wallet public key and signature must be provided as were used to calculate the sighash during the challenge. The wallet provides the preimage which produces sighash used to generate the ECDSA signature that is the subject of the fraud claim.

The fraud challenge defeat attempt will succeed if the inputs in the preimage are considered honestly spent by the wallet. Therefore the transaction spending the UTXO must be proven in the Bridge before a challenge defeat is called.

Another option is when a malicious wallet member used a signed heartbeat message periodically produced by the wallet off-chain to challenge the wallet for a fraud. Anyone from the wallet can defeat the challenge by proving the sighash and signature were produced for a heartbeat message following a strict format.

FraudChallenge

struct FraudChallenge {
  address challenger;
  uint256 depositAmount;
  uint32 reportedAt;
  bool resolved;
}

FraudChallengeSubmitted

event FraudChallengeSubmitted(bytes20 walletPubKeyHash, bytes32 sighash, uint8 v, bytes32 r, bytes32 s)

FraudChallengeDefeated

event FraudChallengeDefeated(bytes20 walletPubKeyHash, bytes32 sighash)

FraudChallengeDefeatTimedOut

event FraudChallengeDefeatTimedOut(bytes20 walletPubKeyHash, bytes32 sighash)

submitFraudChallenge

function submitFraudChallenge(struct BridgeState.Storage self, bytes walletPublicKey, bytes preimageSha256, struct BitcoinTx.RSVSignature signature) external

Submits a fraud challenge indicating that a UTXO being under wallet control was unlocked by the wallet but was not used according to the protocol rules. That means the wallet signed a transaction input pointing to that UTXO and there is a unique sighash and signature pair associated with that input. This function uses those parameters to create a fraud accusation that proves a given transaction input unlocking the given UTXO was actually signed by the wallet. This function cannot determine whether the transaction was actually broadcast and the input was consumed in a fraudulent way so it just opens a challenge period during which the wallet can defeat the challenge by submitting proof of a transaction that consumes the given input according to protocol rules. To prevent spurious allegations, the caller must deposit ETH that is returned back upon justified fraud challenge or confiscated otherwise.

Requirements:

  • Wallet behind walletPublicKey must be in Live or MovingFunds or Closing state,

  • The challenger must send appropriate amount of ETH used as fraud challenge deposit,

  • The signature (represented by r, s and v) must be generated by the wallet behind walletPubKey during signing of sighash which was calculated from preimageSha256,

  • Wallet can be challenged for the given signature only once.

Parameters

NameTypeDescription

self

struct BridgeState.Storage

walletPublicKey

bytes

The public key of the wallet in the uncompressed and unprefixed format (64 bytes).

preimageSha256

bytes

The hash that was generated by applying SHA-256 one time over the preimage used during input signing. The preimage is a serialized subset of the transaction and its structure depends on the transaction input (see BIP-143 for reference). Notice that applying SHA-256 over the preimageSha256 results in sighash. The path from preimage to sighash looks like this: preimage -> (SHA-256) -> preimageSha256 -> (SHA-256) -> sighash.

signature

struct BitcoinTx.RSVSignature

Bitcoin signature in the R/S/V format

defeatFraudChallenge

function defeatFraudChallenge(struct BridgeState.Storage self, bytes walletPublicKey, bytes preimage, bool witness) external

Allows to defeat a pending fraud challenge against a wallet if the transaction that spends the UTXO follows the protocol rules. In order to defeat the challenge the same walletPublicKey and signature (represented by r, s and v) must be provided as were used to calculate the sighash during input signing. The fraud challenge defeat attempt will only succeed if the inputs in the preimage are considered honestly spent by the wallet. Therefore the transaction spending the UTXO must be proven in the Bridge before a challenge defeat is called. If successfully defeated, the fraud challenge is marked as resolved and the amount of ether deposited by the challenger is sent to the treasury.

Requirements:

  • walletPublicKey and sighash calculated as hash256(preimage) must identify an open fraud challenge,

  • the preimage must be a valid preimage of a transaction generated according to the protocol rules and already proved in the Bridge,

  • before a defeat attempt is made the transaction that spends the given UTXO must be proven in the Bridge.

Parameters

NameTypeDescription

self

struct BridgeState.Storage

walletPublicKey

bytes

The public key of the wallet in the uncompressed and unprefixed format (64 bytes).

preimage

bytes

The preimage which produces sighash used to generate the ECDSA signature that is the subject of the fraud claim. It is a serialized subset of the transaction. The exact subset used as the preimage depends on the transaction input the signature is produced for. See BIP-143 for reference.

witness

bool

Flag indicating whether the preimage was produced for a witness input. True for witness, false for non-witness input.

defeatFraudChallengeWithHeartbeat

function defeatFraudChallengeWithHeartbeat(struct BridgeState.Storage self, bytes walletPublicKey, bytes heartbeatMessage) external

Allows to defeat a pending fraud challenge against a wallet by proving the sighash and signature were produced for an off-chain wallet heartbeat message following a strict format. In order to defeat the challenge the same walletPublicKey and signature (represented by r, s and v) must be provided as were used to calculate the sighash during heartbeat message signing. The fraud challenge defeat attempt will only succeed if the signed message follows a strict format required for heartbeat messages. If successfully defeated, the fraud challenge is marked as resolved and the amount of ether deposited by the challenger is sent to the treasury.

Requirements:

  • walletPublicKey and sighash calculated as hash256(heartbeatMessage) must identify an open fraud challenge,

  • heartbeatMessage must follow a strict format of heartbeat messages.

Parameters

NameTypeDescription

self

struct BridgeState.Storage

walletPublicKey

bytes

The public key of the wallet in the uncompressed and unprefixed format (64 bytes),

heartbeatMessage

bytes

Off-chain heartbeat message meeting the heartbeat message format requirements which produces sighash used to generate the ECDSA signature that is the subject of the fraud claim.

resolveFraudChallenge

function resolveFraudChallenge(struct BridgeState.Storage self, bytes walletPublicKey, struct Fraud.FraudChallenge challenge, bytes32 sighash) internal

Called only for successfully defeated fraud challenges. The fraud challenge is marked as resolved and the amount of ether deposited by the challenger is sent to the treasury.

Requirements:

  • Must be called only for successfully defeated fraud challenges.

notifyFraudChallengeDefeatTimeout

function notifyFraudChallengeDefeatTimeout(struct BridgeState.Storage self, bytes walletPublicKey, uint32[] walletMembersIDs, bytes preimageSha256) external

Notifies about defeat timeout for the given fraud challenge. Can be called only if there was a fraud challenge identified by the provided walletPublicKey and sighash and it was not defeated on time. The amount of time that needs to pass after a fraud challenge is reported is indicated by the challengeDefeatTimeout. After a successful fraud challenge defeat timeout notification the fraud challenge is marked as resolved, the stake of each operator is slashed, the ether deposited is returned to the challenger and the challenger is rewarded.

Requirements:

  • The wallet must be in the Live or MovingFunds or Closing or Terminated state,

  • The walletPublicKey and sighash calculated from preimageSha256 must identify an open fraud challenge,

  • The expression keccak256(abi.encode(walletMembersIDs)) must be exactly the same as the hash stored under membersIdsHash for the given walletID. Those IDs are not directly stored in the contract for gas efficiency purposes but they can be read from appropriate DkgResultSubmitted and DkgResultApproved events of the WalletRegistry contract,

  • The amount of time indicated by challengeDefeatTimeout must pass after the challenge was reported.

Parameters

NameTypeDescription

self

struct BridgeState.Storage

walletPublicKey

bytes

The public key of the wallet in the uncompressed and unprefixed format (64 bytes).

walletMembersIDs

uint32[]

Identifiers of the wallet signing group members.

preimageSha256

bytes

The hash that was generated by applying SHA-256 one time over the preimage used during input signing. The preimage is a serialized subset of the transaction and its structure depends on the transaction input (see BIP-143 for reference). Notice that applying SHA-256 over the preimageSha256 results in sighash. The path from preimage to sighash looks like this: preimage -> (SHA-256) -> preimageSha256 -> (SHA-256) -> sighash.

extractUtxoKeyFromWitnessPreimage

function extractUtxoKeyFromWitnessPreimage(bytes preimage) internal pure returns (uint256 utxoKey)

Extracts the UTXO keys from the given preimage used during signing of a witness input.

Parameters

NameTypeDescription

preimage

bytes

The preimage which produces sighash used to generate the ECDSA signature that is the subject of the fraud claim. It is a serialized subset of the transaction. The exact subset used as the preimage depends on the transaction input the signature is produced for. See BIP-143 for reference

Return Values

NameTypeDescription

utxoKey

uint256

UTXO key that identifies spent input.

extractUtxoKeyFromNonWitnessPreimage

function extractUtxoKeyFromNonWitnessPreimage(bytes preimage) internal pure returns (uint256 utxoKey)

Extracts the UTXO key from the given preimage used during signing of a non-witness input.

Parameters

NameTypeDescription

preimage

bytes

The preimage which produces sighash used to generate the ECDSA signature that is the subject of the fraud claim. It is a serialized subset of the transaction. The exact subset used as the preimage depends on the transaction input the signature is produced for. See BIP-143 for reference.

Return Values

NameTypeDescription

utxoKey

uint256

UTXO key that identifies spent input.

extractSighashType

function extractSighashType(bytes preimage) internal pure returns (uint32 sighashType)

Extracts the sighash type from the given preimage.

Sighash type is stored as the last 4 bytes in the preimage (little endian).

Parameters

NameTypeDescription

preimage

bytes

Serialized subset of the transaction. See BIP-143 for reference.

Return Values

NameTypeDescription

sighashType

uint32

Sighash type as a 32-bit integer.

Last updated