> For the complete documentation index, see [llms.txt](https://docs.xft.finance/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.xft.finance/bitnet/technical/swap-facilities/xftassetswaps_v5.md).

# XFTAssetSwaps\_V5

XFT acts as the liquidity provider and escrow manager, enabling instant redemptions for illiquid CLO shares.

XFTAssetSwaps\_V4 [0xfbae4ba53a2FcCD599047d4B2Ff77647e0eb308C](https://sepolia.arbiscan.io/address/0xfbae4ba53a2FcCD599047d4B2Ff77647e0eb308C)\
XFTAssetSwaps\_V5 [0x05EC1faCe695f78a5A9530c612345603f926EAa7](https://sepolia.arbiscan.io/address/0x05ec1face695f78a5a9530c612345603f926eaa7)\
USDXT [0xC1BF9854E43b84f3abec5f5d1C72F0a6f602034b](https://sepolia.arbiscan.io/token/0xC1BF9854E43b84f3abec5f5d1C72F0a6f602034b)\
OCTIX [0x42bAcAaE1D28b3310a4415cb1684491A2fdcC65E](https://sepolia.arbiscan.io/address/0x42bacaae1d28b3310a4415cb1684491a2fdcc65e)

COUNTERPARTIES

XFT [0x2f572059DbC598C8acfeA4AF06FE4f7669D1b3b1](https://sepolia.arbiscan.io/address/0x2f572059DbC598C8acfeA4AF06FE4f7669D1b3b1)\
Octagon [0x82fcEd3D9D0CC5e770C00a3763354B76AF140546](https://sepolia.arbiscan.io/address/0x82fcEd3D9D0CC5e770C00a3763354B76AF140546)\
Investor [0xE4e26f8B4C69E554a113880cF40D21ca70d51e0a](https://sepolia.arbiscan.io/address/0xE4e26f8B4C69E554a113880cF40D21ca70d51e0a)

<mark style="color:purple;">**INSTANT REDEMPTION**</mark>

1\. Investor requests redemption from OCTAGON\
2\. OCTAGON notifies XFT\
3\. XFT initiates escrow mint via `swap.connect(admin).initiateEscrowMint()`\
\
4\. Investor deposits OCTIX and gets USDXT\
5\. XFT releases escrow as OCTAGON pays USD

<mark style="color:purple;">**INSTANT SUBSCRIPTION**</mark>

1\. Investor requests subscription from OCTAGON\
2\. OCTAGON notifies XFT\
3\. XFT calls `initiateEscrowMint(id, investor, USDXT, OCTIX, amount, timelock)`\
4\. Investor calls `depositEscrow(id)` → locks USDXT + mints OCTIX\
5\. XFT calls `releaseEscrow(id, amount)` → sends USDXT to OCTAGON

<mark style="color:red;">**Why instant redemption?**</mark>\
Liquidity management.

<mark style="color:red;">**Why instant subscription?**</mark>\
Programmable 24/7/365 investing at NAV.

<mark style="color:red;">**Why standard?**</mark>\
Permissionless atomic P2P swaps.

***

### CORE FUNCTIONALITY

* Hash Time Locked Contracts (HTLC)
* Salts
* Standard vs. Escrow

**Hash Time Locked Contracts (HTLC)** The protocol combines cryptographic hash locks with time-based expiration to enable trustless atomic swaps. Each swap requires a secret preimage generating a cryptographic hash, ensuring exchanges execute atomically or not at all. Time locks provide automatic refunds if swaps remain incomplete.

**Salt-based ID Generation** The contract generates unique swap identifiers using salt parameters combined with sender addresses and blockchain data. Zero salt values trigger automatic collision-resistant generation. Non-zero salts enable predictable coordination while maintaining sender-specific uniqueness.

**Standard & Escrow.** XFTAssetSwaps\_V5 offers two types of swaps. Standard for P2P trustless exchange with hashlock reveal. Escrow for admin-controlled instant minting

***

#### SWAP TYPES

**1) STANDARD**

No admin involvement: Parties swap tokens directly using cryptographic proofs. Permissionless.

1 Initiator locks tokens with hashlock (secret preimage)\
2 Participant locks counterpart tokens\
3 Either party reveals preimage to unlock both sides\
4 Time-locked refunds if not completed

**2) ESCROW**

Admin-controlled operations enabling instant token minting against locked collateral deposits. Users deposit escrow tokens and receive minted tokens immediately upon confirmation. Administrators progressively release escrowed collateral to designated recipients as external payment confirmations arrive, supporting partial release mechanisms and emergency refund capabilities.

***

### SEQUENCES

**STANDARD SWAP**\
1 Alice calls `initiateSwap(id,Bob,assetA,assetB,amtA,amtB,hl,tl)`\
2 Bob calls `participateSwap(id)`\
3 either calls `claimSwap(id,preimage)` → assets swapped\
4 after tl either calls `refundSwap(id)` → deposits returned

```
Alice: 100 USDX → Contract
Bob: 100 USDXT → Contract
Alice reveals preimage → gets 100 USDXT
Bob uses preimage → gets 100 USDX
```

<figure><img src="https://2428002264-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FtrPSEWidaltiEcFI8sNW%2Fuploads%2FLPGjsIFIInghy09hKXPM%2Fimage.png?alt=media&#x26;token=c589910f-08d2-4191-bb69-32ba7e4b35c3" alt=""><figcaption></figcaption></figure>

**ESCROW**\
1 Admin calls `initiateEscrowMint(id,User,escrowToken,mintToken,amt,tl)`\
2 User calls `depositEscrow(id)` → escrowToken locked + mintToken minted\
3 Admin calls `releaseEscrow(id,partialAmt)` → escrowToken → recipient\
4 Admin calls `releaseEscrow(id,remainingAmt)` → final release

```
User: 100 FOBXX → Contract
Contract: 100 USDXT → User (instant)
Admin: releases 50 FOBXX → Fund (payment 1)
Admin: releases 50 FOBXX → Fund (payment 2)
```

<figure><img src="https://2428002264-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FtrPSEWidaltiEcFI8sNW%2Fuploads%2FnfmU0wCWHKNGGmhRQqzo%2Fimage.png?alt=media&#x26;token=5f371372-004d-4be0-b4e0-074e5df24ef3" alt=""><figcaption></figcaption></figure>

***

**FUNCTIONS**

```
PUBLIC AND EXTERNAL FUNCTIONS
initiateSwap(salt, participant, assetA, assetB, amtA, amtB, hashlock, timelock): Creates P2P atomic swap
participateSwap(id): Participant deposits their asset
claimSwap(id, preimage): Reveals secret to claim both assets atomically
refundSwap(id): Returns assets after timelock expiry
initiateEscrowMint(salt, user, escrowToken, mintToken, amount, timelock, recipient): Admin creates escrow with instant mint
setEscrowRecipient(id, recipient): Admin updates release target
depositEscrow(id): User deposits collateral, gets instant tokens
releaseEscrow(id, amount): Admin releases collateral to recipient progressively
refundEscrow(id): Admin refunds escrow to user
batchReleaseEscrow(ids, amounts): Admin releases multiple escrows efficiently
getSwap(id): Returns complete swap details
getBasic(id): Returns core swap info
getStatus(id): Returns swap status and progress
isIdUsed(id): Checks ID collision
previewId(salt): Previews ID before creation

PRIVATE AND INTERNAL FUNCTIONS
generateId(salt): Creates unique ID from salt or auto-generates
_releaseEscrowInternal(id, amount): Internal batch release helper

EVENTS
SwapInitiated(swapId, swapType, initiator, participant): Swap creation
SwapCompleted(swapId): Successful completion
SwapRefunded(swapId): Refund execution
TokensLocked(swapId, token, user, amount): Asset lockup
TokensMinted(swapId, token, to, amount): Token creation
TokensReleased(swapId, token, to, amount): Asset release
EscrowProgress(swapId, released, remaining): Progressive release tracking
RecipientChanged(swapId, oldRecipient, newRecipient): Recipient updates

ROLES
DEFAULT_ADMIN_ROLE: Grant/revoke roles
ADMIN_ROLE: Execute escrow operations, manage flows
```

**CONTRACT ABI**

```
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"swapId","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"released","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"remaining","type":"uint256"}],"name":"EscrowProgress","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"swapId","type":"bytes32"},{"indexed":true,"internalType":"address","name":"oldRecipient","type":"address"},{"indexed":true,"internalType":"address","name":"newRecipient","type":"address"}],"name":"RecipientChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"swapId","type":"bytes32"}],"name":"SwapCompleted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"swapId","type":"bytes32"},{"indexed":false,"internalType":"enum XFTAssetSwaps_V5.SwapType","name":"swapType","type":"uint8"},{"indexed":true,"internalType":"address","name":"initiator","type":"address"},{"indexed":true,"internalType":"address","name":"participant","type":"address"}],"name":"SwapInitiated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"swapId","type":"bytes32"}],"name":"SwapRefunded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"swapId","type":"bytes32"},{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"TokensLocked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"swapId","type":"bytes32"},{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"TokensMinted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"swapId","type":"bytes32"},{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"TokensReleased","type":"event"},{"inputs":[],"name":"ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32[]","name":"ids","type":"bytes32[]"},{"internalType":"uint128[]","name":"amounts","type":"uint128[]"}],"name":"batchReleaseEscrow","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"id","type":"bytes32"},{"internalType":"bytes32","name":"preimage","type":"bytes32"}],"name":"claimSwap","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"id","type":"bytes32"}],"name":"depositEscrow","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"id","type":"bytes32"}],"name":"getBasic","outputs":[{"internalType":"enum XFTAssetSwaps_V5.SwapType","name":"swapType","type":"uint8"},{"internalType":"address","name":"initiator","type":"address"},{"internalType":"address","name":"participant","type":"address"},{"internalType":"address","name":"initiatorAsset","type":"address"},{"internalType":"address","name":"participantAsset","type":"address"},{"internalType":"uint256","name":"initiatorAmount","type":"uint256"},{"internalType":"uint256","name":"participantAmount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"id","type":"bytes32"}],"name":"getStatus","outputs":[{"internalType":"bytes32","name":"hashlock","type":"bytes32"},{"internalType":"uint256","name":"timelock","type":"uint256"},{"internalType":"bool","name":"initiatorDeposited","type":"bool"},{"internalType":"bool","name":"participantDeposited","type":"bool"},{"internalType":"bool","name":"completed","type":"bool"},{"internalType":"bool","name":"refunded","type":"bool"},{"internalType":"uint256","name":"releasedAmount","type":"uint256"},{"internalType":"address","name":"recipient","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"id","type":"bytes32"}],"name":"getSwap","outputs":[{"internalType":"enum XFTAssetSwaps_V5.SwapType","name":"swapType","type":"uint8"},{"internalType":"address","name":"initiator","type":"address"},{"internalType":"address","name":"participant","type":"address"},{"internalType":"address","name":"initiatorAsset","type":"address"},{"internalType":"address","name":"participantAsset","type":"address"},{"internalType":"uint256","name":"initiatorAmount","type":"uint256"},{"internalType":"uint256","name":"participantAmount","type":"uint256"},{"internalType":"bytes32","name":"hashlock","type":"bytes32"},{"internalType":"uint256","name":"timelock","type":"uint256"},{"internalType":"bool","name":"initiatorDeposited","type":"bool"},{"internalType":"bool","name":"participantDeposited","type":"bool"},{"internalType":"bool","name":"completed","type":"bool"},{"internalType":"bool","name":"refunded","type":"bool"},{"internalType":"uint256","name":"releasedAmount","type":"uint256"},{"internalType":"address","name":"recipient","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"salt","type":"bytes32"},{"internalType":"address","name":"user","type":"address"},{"internalType":"address","name":"escrowToken","type":"address"},{"internalType":"address","name":"mintToken","type":"address"},{"internalType":"uint128","name":"amount","type":"uint128"},{"internalType":"uint64","name":"timelock","type":"uint64"},{"internalType":"address","name":"recipient","type":"address"}],"name":"initiateEscrowMint","outputs":[{"internalType":"bytes32","name":"id","type":"bytes32"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"salt","type":"bytes32"},{"internalType":"address","name":"participant","type":"address"},{"internalType":"address","name":"assetA","type":"address"},{"internalType":"address","name":"assetB","type":"address"},{"internalType":"uint128","name":"amtA","type":"uint128"},{"internalType":"uint128","name":"amtB","type":"uint128"},{"internalType":"bytes32","name":"hashlock","type":"bytes32"},{"internalType":"uint64","name":"timelock","type":"uint64"}],"name":"initiateSwap","outputs":[{"internalType":"bytes32","name":"id","type":"bytes32"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"id","type":"bytes32"}],"name":"isIdUsed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"id","type":"bytes32"}],"name":"participateSwap","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"salt","type":"bytes32"}],"name":"previewId","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"id","type":"bytes32"}],"name":"refundEscrow","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"id","type":"bytes32"}],"name":"refundSwap","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"id","type":"bytes32"},{"internalType":"uint128","name":"amount","type":"uint128"}],"name":"releaseEscrow","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"id","type":"bytes32"},{"internalType":"address","name":"recipient","type":"address"}],"name":"setEscrowRecipient","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"swaps","outputs":[{"internalType":"enum XFTAssetSwaps_V5.SwapType","name":"swapType","type":"uint8"},{"internalType":"address","name":"initiator","type":"address"},{"internalType":"address","name":"participant","type":"address"},{"internalType":"address","name":"initiatorAsset","type":"address"},{"internalType":"address","name":"participantAsset","type":"address"},{"internalType":"uint128","name":"initiatorAmount","type":"uint128"},{"internalType":"uint128","name":"participantAmount","type":"uint128"},{"internalType":"bytes32","name":"hashlock","type":"bytes32"},{"internalType":"uint64","name":"timelock","type":"uint64"},{"internalType":"uint128","name":"releasedAmount","type":"uint128"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"bool","name":"initiatorDeposited","type":"bool"},{"internalType":"bool","name":"participantDeposited","type":"bool"},{"internalType":"bool","name":"completed","type":"bool"},{"internalType":"bool","name":"refunded","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"usedIds","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"}]
```

<figure><img src="https://2428002264-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FtrPSEWidaltiEcFI8sNW%2Fuploads%2FY0lTNHkw6HroiK8JPix4%2Fimage.png?alt=media&#x26;token=4531c9f0-d965-4d86-9ad1-eed46e9043ea" alt=""><figcaption></figcaption></figure>

<figure><img src="https://2428002264-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FtrPSEWidaltiEcFI8sNW%2Fuploads%2FEvC2NVNCl0WQCJsTYjYG%2Foctagon.png?alt=media&#x26;token=3e8eb8fa-1cea-4837-86b3-226bc814de03" alt=""><figcaption></figcaption></figure>

EXAMPLE STANDARD TRANSACTIONS

[Standard Example](https://sepolia.arbiscan.io/tx/0x04612ec0742264f05d3c3af6195db02ee7af9b54410721f8412a89e07b345cf8)

[Full lifecycle video demo](https://youtu.be/t-8Fkgigja4)

EXAMPLE ESCROW TRANSACTIONS

[Instant mint 100 USDXT to investor](https://sepolia.arbiscan.io/tx/0x0622409dbfa4ea80c0fbd5defac648ef21fe2351a5e5926b38216a89cbac74e0)

[Release 30 OCTIX](https://sepolia.arbiscan.io/tx/0x51f94c65ae39c00138fcca5490e0c629c1bc3e790d8fb3cc3ac24417b5a8b0c8)

[Release 55 OCTIX](https://sepolia.arbiscan.io/tx/0x2fcdbe758420cddb02793723f1c0a5bd6e150b5369a6db6078fadf4dcd974dd4)

[Release 15 OCTIX](https://sepolia.arbiscan.io/tx/0x2fcdbe758420cddb02793723f1c0a5bd6e150b5369a6db6078fadf4dcd974dd4)

[Full lifecycle video demo](https://youtu.be/X62sJKmFVBM)
