# Fraud Proof Documentation

## Overview

The trustless bridge system uses cryptographic fraud proofs to verify claims against the source chain (ChainID 138) state. This document describes the fraud proof types, formats, and verification process.

## Fraud Proof Types

### 1. NonExistentDeposit

**Purpose**: Prove that a claimed deposit does not exist on the source chain.

**Proof Structure**:
```solidity
struct NonExistentDepositProof {
    bytes32 stateRoot;           // State root from source chain block
    bytes32 depositHash;         // Hash of deposit data that should exist
    bytes32[] merkleProof;       // Merkle proof path
    bytes32 leftSibling;         // Left sibling for non-existence proof
    bytes32 rightSibling;        // Right sibling for non-existence proof
    bytes blockHeader;           // Block header from source chain
    uint256 blockNumber;         // Block number
}
```

**Verification Process**:
1. Verify state root against block header
2. Hash the claimed deposit data
3. Verify that the deposit hash matches the proof
4. Verify non-existence proof using Merkle proof with left/right siblings

**Use Case**: Relayer claims a deposit that was never made on ChainID 138.

### 2. IncorrectAmount

**Purpose**: Prove that the claimed deposit amount differs from the actual deposit amount.

**Proof Structure**:
```solidity
struct IncorrectAmountProof {
    bytes32 stateRoot;           // State root from source chain block
    bytes32 depositHash;         // Hash of actual deposit data
    bytes32[] merkleProof;      // Merkle proof for actual deposit
    uint256 actualAmount;        // Actual deposit amount from source chain
    bytes blockHeader;           // Block header from source chain
    uint256 blockNumber;         // Block number
}
```

**Verification Process**:
1. Verify state root against block header
2. Verify that actual amount differs from claimed amount
3. Hash the actual deposit data with correct amount
4. Verify Merkle proof for actual deposit

**Use Case**: Relayer claims 2 ETH but actual deposit was 1 ETH.

### 3. IncorrectRecipient

**Purpose**: Prove that the claimed recipient differs from the actual deposit recipient.

**Proof Structure**:
```solidity
struct IncorrectRecipientProof {
    bytes32 stateRoot;           // State root from source chain block
    bytes32 depositHash;         // Hash of actual deposit data
    bytes32[] merkleProof;      // Merkle proof for actual deposit
    address actualRecipient;     // Actual recipient from source chain
    bytes blockHeader;           // Block header from source chain
    uint256 blockNumber;         // Block number
}
```

**Verification Process**:
1. Verify state root against block header
2. Verify that actual recipient differs from claimed recipient
3. Hash the actual deposit data with correct recipient
4. Verify Merkle proof for actual deposit

**Use Case**: Relayer claims recipient A but actual deposit was to recipient B.

### 4. DoubleSpend

**Purpose**: Prove that a deposit was already claimed in a previous claim.

**Proof Structure**:
```solidity
struct DoubleSpendProof {
    uint256 previousClaimId;    // Deposit ID of previous claim
    bytes32 previousClaimHash;   // Hash of previous claim
    bytes32[] merkleProof;      // Merkle proof for previous claim
    bytes blockHeader;           // Block header from source chain
    uint256 blockNumber;         // Block number
}
```

**Verification Process**:
1. Verify that previous claim ID matches current deposit ID
2. Verify that previous claim exists and is finalized
3. Verify that deposit data matches (same deposit, different claim)

**Use Case**: Same deposit is claimed twice by different relayers.

## Deposit Data Hashing

Deposit data is hashed using the following format:

```solidity
keccak256(abi.encodePacked(
    depositId,
    asset,
    amount,
    recipient,
    timestamp
))
```

This hash is used as the leaf in the Merkle tree.

## Merkle Proof Verification

The system uses standard Merkle tree verification:

1. Start with the leaf hash (deposit data hash)
2. For each proof element:
   - If current hash < proof element: hash(current, proof)
   - Else: hash(proof, current)
3. Final hash should equal the state root

## Non-Existence Proofs

For non-existence proofs, the system verifies that:
1. The deposit hash would be between leftSibling and rightSibling in the tree
2. The Merkle proof path shows the deposit doesn't exist

## Block Header Verification

Block headers from ChainID 138 are verified to extract the state root. The current implementation includes a placeholder for RLP decoding and state root extraction.

**Future Enhancement**: Implement full RLP decoding and state root extraction from block headers.

## Light Client Integration (Future)

Future implementations will integrate light clients for trustless state verification without relying on RPC nodes. This will:
- Remove RPC dependency for verification
- Enable fully trustless operation
- Improve security and decentralization

## Proof Generation (Off-Chain)

Fraud proofs are generated off-chain by challengers who:
1. Monitor source chain (ChainID 138) for deposits
2. Monitor destination chain (Ethereum) for claims
3. Compare claims against source chain state
4. Generate appropriate fraud proof when fraud is detected
5. Submit challenge with fraud proof

## Example: Generating a Non-Existence Proof

```python
# Pseudocode for generating non-existence proof
def generate_non_existence_proof(deposit_id, claimed_deposit_data, source_chain_state):
    # Hash the claimed deposit data
    deposit_hash = keccak256(encode(deposit_id, claimed_deposit_data))
    
    # Get state root from source chain block
    state_root = source_chain_state.get_state_root()
    
    # Generate Merkle proof showing deposit doesn't exist
    merkle_proof, left_sibling, right_sibling = generate_non_existence_merkle_proof(
        state_root,
        deposit_hash
    )
    
    # Get block header
    block_header = source_chain_state.get_block_header()
    block_number = source_chain_state.get_block_number()
    
    # Construct proof
    proof = NonExistentDepositProof({
        stateRoot: state_root,
        depositHash: deposit_hash,
        merkleProof: merkle_proof,
        leftSibling: left_sibling,
        rightSibling: right_sibling,
        blockHeader: block_header,
        blockNumber: block_number
    })
    
    return encode(proof)
```

## Security Considerations

1. **State Root Verification**: Always verify state root against block header
2. **Block Finality**: Use finalized blocks from source chain
3. **Proof Validity**: Verify all proof elements are valid
4. **Replay Protection**: Ensure proofs are for the correct deposit and claim

## Testing

Comprehensive test suite available in `test/bridge/trustless/FraudProof.t.sol` covering:
- All fraud proof types
- Encoding/decoding
- Merkle proof verification
- Edge cases

## References

- Merkle Proof Verifier: `contracts/bridge/trustless/libraries/MerkleProofVerifier.sol`
- Fraud Proof Types: `contracts/bridge/trustless/libraries/FraudProofTypes.sol`
- Challenge Manager: `contracts/bridge/trustless/ChallengeManager.sol`

