SettleMint
User guidesSystem addonsXvP SettlementHTLC settlements

HTLC explained

Understand how Hash Time-Locked Contracts enable trustless cross-chain asset exchanges. Learn about hashlocks, timelocks, and why the mechanism is cryptographically secure.

Hash Time-Locked Contracts (HTLCs) enable trustless asset exchanges across different blockchains. This page explains how the mechanism works and why it provides strong security guarantees.

The two core components

Hashlock: the cryptographic lock

A hashlock is a cryptographic puzzle created by hashing a secret value:

hashlock = keccak256(secret)

Only someone who knows the original secret can "unlock" the hashlock. Think of it like a combination lock where only the secret holder knows the combination.

Key properties of the hashlock:

  • No one can figure out the secret from the hashlock alone
  • The same secret always produces the same hashlock

Timelock: the deadline

A timelock is a deadline after which the settlement expires. It serves two purposes:

  1. Protection from stuck assets - If something goes wrong, assets are not locked forever
  2. Coordination mechanism - Creates a window during which the exchange must complete

How HTLC ensures atomicity

The best way to understand HTLC security is through a concrete example.

Example: Bank sells bonds to an Investor

Setup:

  • Investor has 100,000 USDC on Polygon
  • Bank has 1,000 BOND tokens on Ethereum
  • They want to exchange these assets atomically

Step 1: Bank generates the secret

The Bank generates a random secret and computes the hashlock:

  • Secret: 0x7a8b9c... (only the Bank knows this)
  • Hashlock: keccak256(secret) = 0xdef456... (shared with the Investor)

Step 2: Bank creates settlement on Ethereum

FieldValue
FlowBank → Investor: 1,000 BOND
Hashlock0xdef456...
TimelockJanuary 15, 2025 at 12:00 PM

The Bank approves, locking 1,000 BOND into the settlement contract.

Step 3: Investor creates settlement on Polygon

The Bank shares only the hashlock (not the secret) with the Investor.

FieldValue
FlowInvestor → Bank: 100,000 USDC
Hashlock0xdef456... (same as Ethereum)
TimelockJanuary 14, 2025 at 12:00 PM (24 hours before Ethereum)

The Investor approves, locking 100,000 USDC into the settlement contract.

Both settlements are now in the Armed state, waiting for the secret.

Step 4: The swap executes

  1. Bank reveals secret on Polygon (January 13) - Settlement executes, Bank receives 100,000 USDC
  2. Secret is now public - The Investor can see it on-chain
  3. Investor reveals secret on Ethereum (January 13) - Settlement executes, Investor receives 1,000 BOND

Both parties received their assets. The exchange was atomic across chains.

Why HTLC is secure

The Investor cannot cheat

The Investor might try to claim the Bank's BOND on Ethereum without providing USDC. To do this, they would need to reveal the secret on Ethereum.

But the Investor only knows the hashlock, not the secret.

The hashlock is created using keccak256, a cryptographic hash function with these properties:

  1. One-way function - Given the hashlock, it's computationally impossible to reverse-engineer the secret
  2. Brute force is impractical - The secret is a 256-bit value with 2^256 possibilities. Even trying 1 trillion guesses per second would take longer than the age of the universe
  3. Collision resistance - No other value produces the same hashlock

The only way the Investor can execute the Ethereum settlement is to wait for the Bank to reveal the secret on Polygon first.

The Bank cannot cheat

After revealing the secret on Polygon, the Bank cannot withdraw their BOND on Ethereum because:

  • The Ethereum timelock doesn't expire until January 15
  • The Investor has until then to use the (now public) secret
  • The Bank's BOND remain locked in the settlement contract

Timelock order is critical

The timelocks must be staggered correctly:

Rendering diagram...

Correct order: Polygon expires January 14, Ethereum expires January 15

The Investor has 24 hours after the secret is revealed on Polygon to use it on Ethereum.

If timelocks were reversed:

ChainReversed Timelocks (UNSAFE)Correct Timelocks
Polygon (Investor → Bank: USDC)January 15, 12:00 PMJanuary 14, 12:00 PM
Ethereum (Bank → Investor: BOND)January 14, 12:00 PMJanuary 15, 12:00 PM

Setup (January 12):

  • Bank creates settlement on Ethereum with January 14 timelock (WRONG - too early)
  • Investor creates settlement on Polygon with January 15 timelock
  • Both settlements are Armed

Bank waits strategically:

  • Bank does NOT reveal the secret yet
  • Both settlements remain in Armed state

The Exploit begins (January 14 at 12:01 PM):

  1. Ethereum timelock expires (January 14 deadline passed)
  2. Bank calls withdraw() on Ethereum settlement
  3. Bank receives their 1,000 BOND back (settlement expired without executing)

The Exploit completes (January 14 at 12:30 PM):

  1. Polygon settlement is still valid (doesn't expire until January 15)
  2. Bank reveals secret on Polygon
  3. Bank receives 100,000 USDC from Polygon

Final State:

  • Bank has: 100,000 USDC (claimed from Polygon) + 1,000 BOND (withdrawn from Ethereum)
  • Investor has: Lost 100,000 USDC, received nothing
  • Investor cannot claim BOND because Ethereum settlement already expired and was withdrawn

The key rule: When you don't have the secret, make sure the cutoff date of the HTLC that you create is before the cutoff date of the HTLC leg that has the secret. This ensures you have time to use the secret after it's revealed, before your settlement expires.

Timelock rule

The settlement where you receive assets should have an earlier timelock than the settlement where you send assets. This ensures you have time to claim your assets after the secret is revealed.

How XvP implements HTLC

XvP settlements incorporate HTLC with these features:

FeatureImplementation
Secret generationUI can generate secrets, or you can provide your own
Hashlock verificationContract validates secret matches hashlock
Armed stateAll local senders must approve before secret can be revealed
Auto-executeWhen enabled, settlement executes automatically when secret is revealed
Cutoff dateEnforces the timelock expiration

The revealSecret() function:

  1. Validates the provided secret matches the hashlock
  2. Confirms all local senders have approved
  3. If auto-execute is enabled, executes all local flows atomically
  4. Records the secret on-chain for transparency

Failure scenarios

ScenarioWhat happens
Bank never reveals secretBoth settlements expire, all parties withdraw their locked assets
Investor never approves on PolygonBank's BOND remain locked until Ethereum timelock expires
Network congestion delays InvestorIf Investor can't use secret before Ethereum expires, they lose the trade

To mitigate network delays, set timelocks with sufficient buffer (24-48 hours between chains is recommended).

Further reading

On this page