# Plutus HTLC: Atomic Swap Smart Contract

### 📌 Table of Contents

1. 🔍 Overview
2. ⚙️ Contract Structure
3. 🧩 HTLCParams – Contract Parameters
4. 🎯 HTLCRedeemer – User Actions
5. 🧪 mkValidator – Core Logic
6. 📜 Typed Validator & Wrapping
7. 📫 Script Address
8. 📘 Glossary of Terms

***

### 1️⃣ 🔍 Overview

This contract implements a **Hashed Timelock Contract (HTLC)**, which enables **secure, trustless, and time-limited swaps** of assets between two parties. The contract has two unlock conditions:

* ✅ **Hashlock**: Receiver must reveal the **preimage** of a given hash before the deadline.
* ⏳ **Timelock**: If deadline passes, the sender can reclaim the funds.

***

### 2️⃣ ⚙️ Contract Structure

The contract consists of:

* 📦 `HTLCParams`: The configuration (sender, receiver, hash, and deadline).
* 🎯 `HTLCRedeemer`: The action chosen (Redeem with a secret, or Refund).
* 🧪 `mkValidator`: The validator logic.
* 🧵 Typed validator & script address.

***

### 3️⃣ 🧩 `HTLCParams` — Contract Parameters

```haskell
data HTLCParams = HTLCParams
  { sender    :: PubKeyHash
  , receiver  :: PubKeyHash
  , hashlock  :: BuiltinByteString  -- sha2_256 of secret
  , deadline  :: POSIXTime
  }
```

#### 🔍 Explanation:

* `sender`: Person initiating the swap (can reclaim funds after deadline).
* `receiver`: Person claiming funds with the secret.
* `hashlock`: A SHA-256 hash of the secret.
* `deadline`: Time after which refund is allowed.

🚀 Make this value once off-chain, and lift it using Template Haskell:

```haskell
PlutusTx.makeLift ''HTLCParams
```

***

### 4️⃣ 🎯 `HTLCRedeemer` — User Actions

```haskell
data HTLCRedeemer = Redeem BuiltinByteString | Refund
```

#### ✨ Purpose:

* `Redeem secret` — Receiver provides the secret before the deadline.
* `Refund` — Sender reclaims after the deadline.

Must be serializable:

```haskell
PlutusTx.unstableMakeIsData ''HTLCRedeemer
```

***

### 5️⃣ 🧪 `mkValidator` — Core Validation Logic

```haskell
mkValidator :: HTLCParams -> () -> HTLCRedeemer -> ScriptContext -> Bool
mkValidator htlc _ redeemer ctx =
  case redeemer of
    Redeem secret ->
      traceIfFalse "Hash mismatch" correctHash &&
      traceIfFalse "Not signed by receiver" signedByReceiver &&
      traceIfFalse "Too late" withinDeadline
      where
        correctHash     = sha2_256 secret == hashlock htlc
        signedByReceiver = txSignedBy info (receiver htlc)
        withinDeadline   = to (deadline htlc) `contains` txInfoValidRange info

    Refund ->
      traceIfFalse "Too early" pastDeadline &&
      traceIfFalse "Not signed by sender" signedBySender
      where
        pastDeadline    = from (deadline htlc) `contains` txInfoValidRange info
        signedBySender  = txSignedBy info (sender htlc)
  where
    info = scriptContextTxInfo ctx
```

#### 🔍 What this does:

**🔑 If `Redeem secret`:**

* Checks `sha2_256(secret) == hashlock`
* Ensures the receiver signed the tx
* Ensures the current time is **before** the deadline

**💸 If `Refund`:**

* Checks time is **after** the deadline
* Ensures the **sender** signed it

All conditions use `traceIfFalse` for on-chain debugging.

***

### 6️⃣ 📜 Typed Validator & Wrapping

#### ✂️ Define the validator types:

```haskell
data HTLC
instance Scripts.ValidatorTypes HTLC where
  type instance DatumType HTLC = ()
  type instance RedeemerType HTLC = HTLCRedeemer
```

#### 🧵 Compile the validator:

```haskell
typedValidator :: HTLCParams -> Scripts.TypedValidator HTLC
typedValidator htlc = Scripts.mkTypedValidator @HTLC
  ($$(PlutusTx.compile [|| mkValidator ||]) `PlutusTx.applyCode` PlutusTx.liftCode htlc)
  $$(PlutusTx.compile [|| wrap ||])
  where
    wrap = Scripts.wrapValidator @() @HTLCRedeemer
```

🔁 This connects the raw `mkValidator` to Plutus's typed validation system.

***

### 7️⃣ 📫 Script Address

This lets you lock funds at the HTLC address on-chain:

```haskell
validator :: HTLCParams -> Validator
validator = Scripts.validatorScript . typedValidator

scrAddress :: HTLCParams -> Address
scrAddress = scriptAddress . validator
```

***

### 8️⃣ 📘 Glossary of Terms

| Term                  | Meaning                                         |
| --------------------- | ----------------------------------------------- |
| `sha2_256`            | Hash function used for locking the secret       |
| `PubKeyHash`          | Public key identifier                           |
| `txSignedBy`          | Verifies transaction is signed by a given party |
| `scriptContextTxInfo` | Retrieves transaction info for validation       |
| `contains`            | Checks if a time range contains a point         |
| `traceIfFalse`        | On-chain debugging that fails with a message    |
| `POSIXTime`           | UTC timestamp used in Plutus timelocks          |
| `Validator`           | A Plutus smart contract function                |
| `BuiltinByteString`   | On-chain byte string                            |
| `Redeemer`            | Input that unlocks a validator                  |
| `TypedValidator`      | Type-safe validator using Plutus type system    |

***

### 🧪 Sample Off-Chain Parameter Setup

```haskell
exampleParams = HTLCParams
  { sender    = <senderPubKeyHash>
  , receiver  = <receiverPubKeyHash>
  , hashlock  = sha2_256 "superSecret123"
  , deadline  = <somePOSIXTime>
  }
```

You'd pass this into `typedValidator` and derive the address to fund it.

***

### ✅ Summary

This HTLC Plutus contract allows:

* **Atomic swaps** between chains or users
* Time-bound claim and refund
* Secure hash-based locking

It's ideal for use cases like:

* 💱 Cross-chain asset exchanges
* 🧾 Conditional token access
* 🔐 Trustless payments with refund guarantees

***
