# Welcome

[![Discord](https://img.shields.io/discord/590643190281928738.svg)](https://discord.gg/Pc6gV3hFjR) [![Twitter Follow](https://img.shields.io/twitter/follow/airswap?style=social)](https://x.com/airswap) [![Subreddit subscribers](https://img.shields.io/reddit/subreddit-subscribers/AirSwap?style=social)](https://www.reddit.com/r/AirSwap/) [![GitHub stars](https://img.shields.io/github/stars/airswap/airswap-protocols?style=social)](https://github.com/airswap/airswap-protocols)

[AirSwap](https://www.airswap.xyz) is an open developer community focused on decentralized trading systems. AirSwap technology powers peer-to-peer networks using de facto standard [RFQ](/technology/protocols) and [LastLook](/technology/protocols) protocols making it the top choice for traditional market makers entering the decentralized financial system.

**Our vision** is a future where all forms of value are represented as digital assets and flow freely and reliably among people and communities around the world. **Our mission** is to become the standard peer-to-peer trading system: a fundamental primitive of the decentralized economy.

At its core, AirSwap enables two parties to perform an "atomic swap" transaction, through which both sides succeed or the entire transaction reverts. These transactions are "trustless" in a way that neither party needs to trust one another to complete the swap.

* **Not your keys, not your coins**. AirSwap is non-custodial and without deposits or escrow. Every transaction is peer-to-peer with no counterparty risk, no intermediating participants, and no infrastructure beyond an EVM.
* **Competitive and efficient**. Trading firms provide liquidity via AirSwap at competitive prices by hedging on centralized exchanges. Since it’s peer-to-peer, the price you see is the price you get, without slippage, front running, or manipulation.
* **Zero limitations**. Each swap is between two parties, two tokens, and a smart contract. This means any standardized digital token implements its own transfer restrictions and can be swapped at any price or size.

## Technology

AirSwap curates a peer-to-peer network for trading digital assets: a novel design that protects traders from counterparty risk, price slippage, and front running. Any market participant can discover others and trade directly peer-to-peer using a combination of web protocols and smart contracts. AirSwap technology is open source and all code can be found on [GitHub](https://github.com/airswap/).

### Architecture

AirSwap is developed and governed by an open-source community and DAO. The network is comprised of trading protocols and applications that generate protocol fees. These are routed through the swap contracts to other smart-contract based systems that support contributor tips and rewards for those actively participating in the DAO. On the following diagram, blue entities are core contracts, blue-outlined entities are applications, and black-outlined entities are participants.

![](/files/l3IK2Fvxcrm4lK9mocyu)

### Applications

Several end-user applications are available.

* [AirSwap DEX](https://dex.airswap.xyz/) — All things peer-to-peer swaps.
* [AirSwap DAO](https://dao.airswap.xyz/) — Dashboard for community members.
* [AirSwap CLI](https://github.com/airswap/airswap-cli) — Command-line interface to interact with the network.

Several DEX aggregators and market makers implement AirSwap.

* [MetaMask Swaps](https://metamask.io/swaps.html) — Swap directly from the MetaMask wallet browser extension.

Several third-party applications serve important roles.

* [Snapshot](https://snapshot.box/#/s:vote.airswap.eth) — Proposal voting by token holders.
* [Splits](https://app.splits.org/accounts/0xaD30f7EEBD9Bd5150a256F47DA41d4403033CdF0/?chainId=1) — Protocol fee routing.

### Protocols

At the protocol level, each swap is between two parties, a signer and a sender. The signer is the party that creates and cryptographically signs an order, and sender is the party that sends the order to an EVM for settlement.

* [**Request-for-quote**](/about/glossary#request-for-quote-rfq) (RFQ) is an automated request-response protocol for market makers running web servers from which clients request orders via JSON-RPC or WebSocket. Maker servers respond to client requests with signed orders, which are assessed by the client who then has the option to complete the swap on-chain. For example, [MetaMask Swaps](https://medium.com/metamask/introducing-metamask-swaps-84318c643785) implements AirSwap RFQ to enable users to swap tokens directly from within their MetaMask wallet by requesting orders directly from market makers.
* [**LastLook**](/about/glossary#last-look-ll) (LL) is an automated streaming protocol via JSON-RPC over WebSocket. With LastLook, market makers continuously stream asset prices to clients in real-time. Clients can then sign and transmit orders based on the prices they receive to the maker, who then has the "last look" and the option to complete the swap on-chain. LastLook also has the added benefit of being effectively gasless for the client. For example, when a quote on [swap.eth.limo](http://swap.eth.limo) displays the "gasless" label, your web browser is connected directly to a market maker using the LastLook streaming protocol.
* [**Over-the-counter**](/about/glossary#over-the-counter-otc) (OTC) is manual trading between known counterparties, with prices communicated via chat applications or email and using AirSwap for settlement. Some of the [largest trades](https://etherscan.io/tx/0x346a9f45c70d4f323c67fd0f348b2a8aaa7477a719557c27a8130c8873279d3b) in DeFi have been made on AirSwap OTC. For example, Stake DAO, a digital asset management firm, uses AirSwap OTC for an ETH put selling investment strategy.

### Analytics

See the [AirSwap Analytics](https://analytics.airswap.xyz/) dashboard for latest trading network and community stats.

## Community

AirSwap is a community asset held by its token holders, operating as an open project with a transparent decision-making and product development process. Both the network technology and contributor community aim to be maximally decentralized. Community members stake AirSwap tokens (AST) to participate in governance and other community benefits. Ideating, drafting, voting on, and accepting proposals is an open process.

### Values

* **Quality** — We craft software systems that are thoughtful, elegant, and secure. We envision and create the best form of each protocol and product that we deliver.
* **Transparency** — Decisions are made in the open and contributions are open source. New information is continuously and actively shared throughout.
* **Inclusion** — All contribution opportunities are accessible and inclusive. Every community member is treated fairly and consistently.
* **Automation** — We strive to run organizational processes and execute relevant tasks entirely automatically using trustless and transparent tools.

### Token

AirSwap launched with the AirSwap Token (AST) [October 10th, 2017](https://medium.com/fluidity/airswap-token-launch-report-fbd04b748eb1) on the original peer-to-peer swap network. The token initially enabled traders to announce their availability and today also functions as a way for contributors to participate in governance and development. AST gives its holders the opportunity to work commensurate with their holdings, and the opportunity to earn commensurate with their contribution, which fundamentally requires active participation. AST is the gateway to joining and contributing to the AirSwap community.

### Governance

To generate new ideas and directions for the project and cultivate transparency, we use a process called [AirSwap Improvement Proposals (AIP)](/community/proposals). AIPs give the community a way to vote on and finalize proposals on an ongoing basis. For more information see [AIP 1](https://github.com/airswap/airswap-aips/issues/1) and check out [all active proposals](https://github.com/airswap/aips). This is how the community captures, selects, and prioritizes new projects.

Each AIP is ratified by calling it to vote and being accepted by the token holder community. Voting is held on [Snapshot](https://snapshot.org/#/vote.airswap.eth). Once votes are completed, proposals are considered finalized and placed in a backlog for selection by contributors. Based on requirements and feasibility, contributors may accept the proposal for prioritization and implementation.

## History

AirSwap [launched on October 10th, 2017](https://medium.com/fluidity/airswap-token-launch-report-fbd04b748eb1). Over the years, new products and upgrades have been continuously published to further enable and popularize the benefits of trading digital assets using decentralized protocols. See the years in review for [2018](https://medium.com/fluidity/2018-a-year-in-review-d7f5cb0e5d76), [2019](https://medium.com/fluidity/2019-a-year-in-review-6b40035e6edb), [2021](https://medium.com/airswap/2021-a-year-in-review-20dff123b11), [2022](https://medium.com/airswap/2022-a-year-in-review-918f1d7b9a71), [2023](https://medium.com/airswap/2023-a-year-in-review-7bebc102c0d7), and [2024](https://medium.com/airswap/2024-a-year-in-review-545c02635734).

* [AirSwap Roadmap](https://medium.com/fluidity/the-airswap-roadmap-1c1a3c3b20d3) (November 16th, 2017)
* [AirSwap is Here](https://medium.com/fluidity/airswap-is-here-c83c001d5bbe) (April 25, 2018)
* [Spaces is Here](https://medium.com/fluidity/spaces-is-here-a36fa6753474) (October 10, 2018)
* [AirSwap Instant 2.0](https://medium.com/fluidity/airswap-instant-2-0-d10906447838) (April 26, 2019)
* [AirSwap Trader](https://medium.com/fluidity/introducing-airswap-trader-63a0ef9e67c0) (August 6, 2019)
* [AirSwap Delegates](https://medium.com/fluidity/introducing-airswap-delegates-1c3db83be1db) (February 4, 2020)
* [Phase II Kickoff](https://x.com/airswap/status/1346542008345747457) and [Transition Complete](https://x.com/airswap/status/1359190898110853122) (2021)
* [AirSwap Web App](https://medium.com/airswap/airswap-dao-launches-new-app-cb5a9735b9e1) (2021)
* [AirSwap V3](https://medium.com/airswap/introducing-airswap-v3-97f8d14bebad) (2022)
* [AirSwap V4](https://medium.com/airswap/introducing-airswap-v4-1962923ccc74) (2023)
* [AirSwap NFT and OTC 2.0](https://medium.com/airswap/happy-10-10-nft-marketplaces-otc-2-0-protocols-4-1-and-more-b49cf6b1bc2f) (2023)
* [AirSwap V5](https://x.com/airswap/status/1844478269225304095) (2024)

Having achieved its initial goals and delivered its technology roadmap, AirSwap is now an open project and community of contributors who pursue initiatives to continue to develop and grow the network.

* **AirSwap** is recognized by...
  * **St. Louis Fed** as the leading peer-to-peer trading protocol [→](https://research.stlouisfed.org/publications/review/2021/02/05/decentralized-finance-on-blockchain-and-smart-contract-based-financial-markets)
  * **MIT Technology Review** as a protocol built to survive [→](https://www.technologyreview.com/2018/02/22/145100/when-the-cryptocurrency-bubble-pops-these-tokens-are-built-to-survive/)
  * **Stanford Journal** on Blockchain Law and Policy [→](https://stanford-jblp.pubpub.org/pub/deconstructing-dex/release/1)
  * ***Trust Machine***, a 2018 film about the blockchain industry [→](https://www.imdb.com/title/tt7407496/)
* Used for the **first ever peer-to-peer swap** of a tokenized security [→](https://tokenist.com/airswap-facilitates-first-compliant-security-token-transfer-on-a-public-blockchain/)
* **Rated #1 in security** among decentralized exchanges (DEX) [→](https://icorating.com/pdf/65/1/pnN3XH96SRWtSs1YMNn2MSw805II3mD7UwKyMrPA.pdf)
* Founding member of **"wrapped bitcoin" (WBTC)** to represent bitcoin on Ethereum [→](https://www.bitgo.com/newsroom/press-releases/wbtc-brings-bitcoin-to-ethereum)
* Active in the **Ethereum community** and a champion of the technology [→](https://medium.com/fluidity/airswap-devcon-5-43adcf758ba8)

## Explore

* AirSwap [Discord Server](https://discord.gg/Pc6gV3hFjR)
* AirSwap [Member Dashboard](https://dao.airswap.eth.limo/)
* AirSwap [Twitter](https://x.com/airswap)


# Announcements

For up-to-date information see [AirSwap on X](https://x.com/airswap) and [AirSwap on Discord](https://discord.gg/Pc6gV3hFjR).

### 4.1 Migration: 30 January, 2024

* All makers **must** migrate to [V4.1](/technology/deployments) on or after **30 January**, 2024.
* Makers **must** set a server URL and add supported tokens to the [V4.1 Registry](https://github.com/airswap/airswap-about/blob/master/technology/deployments/README.md#airswap-v4.1) contract and approve the [V4.1 SwapERC20](https://github.com/airswap/airswap-about/blob/master/technology/deployments/README.md#airswap-v4.1) contract for supported tokens. AirSwap CLI [4.1.4](https://www.npmjs.com/package/airswap/v/4.1.4) supports these operations.
* Makers **should** remove all tokens from and revoke approvals for the [V3 Registry](https://etherscan.io/address/0x8F9DA6d38939411340b19401E8c54Ea1f51B8f95) and revoke approvals for [V4 SwapERC20](https://github.com/airswap/airswap-about/blob/master/technology/deployments/README.md#airswap-v4) contracts. AirSwap CLI [4.0.6](https://www.npmjs.com/package/airswap/v/4.0.6) supports these operations.
* Only once all supported tokens are removed from the V3 Registry is all staked AST returned to the maker, which can then be staked to the V4.1 Registry.
* For questions and support please see the [#developers](https://discord.com/channels/590643190281928738/877682977616838656) channel on Discord.

### Linea Voyage: 8-16 December, 2023

**To complete the bonus OTC task for** [**Wave 7: Trading**](https://www.intract.io/linea/quest/6572fc0bef415b56fd67608f)

* Either make or take an order. If you make an order, you can take it with another account you own.
* One of the sides (maker or taker) of the order must have a value of $15 or more.
* If you make an order with ETH, it will be wrapped as WETH, a 1:1 conversion of ETH to make it swappable.
* If you take an order with WETH, you can unwrap it by clicking RFQ and swapping WETH to ETH on <https://linea.airswap.eth.limo/>.

**To make an OTC order**

1. Navigate to <https://linea.airswap.eth.limo/>
2. Choose "OTC" from the side menu.
3. Select tokens to send and receive, one of which must have value of at least $15.
4. Optionally change the expiry or set a specific taker address.
5. Sign and share the URL on the [AirSwap Discord](https://discord.gg/9sEBHXnD).
6. Your counterparty (or another account you own) must take the order.

Your order transaction should look [something like this](https://lineascan.build/tx/0x774b7ccc7495fdb1144471bcea1b29cd8de76b1d00a784c21bd8e5c3a6eabc80) (potentially different tokens and amounts).

**To take an OTC order**

1. Find available orders on the [AirSwap Discord](https://discord.gg/9sEBHXnD).
2. Click one of the `linea.airswap.eth.limo` links to take it.

**Verification may take a few hours** but if the swap is valid it will be verified by Intract.

### 4.1.1 Release: 26 October, 2023

* `v4.1.1` release has been tagged on [GitHub](https://github.com/airswap/airswap-protocols/releases).
* Includes latest Registry, SwapERC20, Wrapper, Registry, and Pool across all [19 supported chains](https://github.com/airswap/airswap-protocols/blob/v4.1.1/tools/constants/index.ts#L10).
* All network participants are encouraged to upgrade. [Latest contract addresses](/technology/deployments) are up to date.

### Activate Shutdown: 3 October, 2023

* On **3 October, 2023**, the Activate [Voting Portal](https://activate.codefi.network/staking/airswap/governance) will shut down.
* On **5 October, 2023**, a new application will be available for staking and voter rewards.
* The new application will be shared exclusively via the official [AirSwap X](https://x.com/airswap) account and [AirSwap Discord](https://discord.gg/Pc6gV3hFjR).
* Any unused Activate points will be migrated to the new voter rewards application.


# Introduction

AirSwap trading technology is fully decentralized, powered by smart contracts that enable counterparty discovery and atomic swaps. AirSwap protocols communicate prices **off-chain** and settle **on-chain**. Peers take the form of individuals trading manually or software trading in an automated way, in which case market makers run servers that implement the following protocols.

For information on finding counter-parties, see [Discovery](/technology/discovery). For protocol method specifications, see [Protocols](/technology/protocols).

## Orders

AirSwap orders are mutually signed instructions to perform an atomic swap. Prior to execution, both the signer (party that creates and signs the order) and sender (party that sends the order to the EVM) must have approved the swap contract to transfer the specified tokens on their behalf.

### Properties

An `OrderERC20` has the following properties:

| Property     | Type      | Description                               |
| ------------ | --------- | ----------------------------------------- |
| nonce        | `uint256` | Unique per signer and usually sequential. |
| expiry       | `uint256` | Expiry in seconds since 1 January 1970.   |
| signerWallet | `address` | Wallet that sets and signs terms.         |
| signerToken  | `address` | Token that the signer transfers.          |
| signerAmount | `uint256` | Amount that the signer transfers.         |
| senderToken  | `address` | Token that the sender transfers.          |
| senderAmount | `uint256` | Amount that the sender transfers.         |
| v            | `uint8`   | `v` value of the ECDSA signature.         |
| r            | `bytes32` | `r` value of the ECDSA signature.         |
| s            | `bytes32` | `s` value of the ECDSA signature.         |

### Execution

Orders are passed to the [SwapERC20](/technology/deployments) contract for execution, which emits a `SwapERC20` event on success. The `swapLight` function is more efficient, whereas the `swap` function provides protocol fee rebates to staked AST holders. Either function can execute a properly signed order.

```typescript
  function swapLight(
    uint256 nonce,
    uint256 expiry,
    address signerWallet,
    address signerToken,
    uint256 signerAmount,
    address senderToken,
    uint256 senderAmount,
    uint8 v,
    bytes32 r,
    bytes32 s
  ) external;
```

## RequestForQuoteERC20

AirSwap [RequestForQuoteERC20](/about/glossary#request-for-quote-rfq) is a client-server protocol used by market makers running servers from which clients request ERC20 orders via HTTP or WebSocket. In RFQ, the server is the signer (i.e. `signerAmount`, `signerToken`) and the client is the sender (i.e. `senderAmount`, `senderToken`).

### Example

To find counterparties, see [Discovery](/technology/discovery). With server URLs in hand, clients may call `getSignerSideOrderERC20` or `getSenderSideOrderERC20` as JSON-RPC requests on servers that support RequestForQuoteERC20.

#### Client Request

```javascript
POST / HTTP/1.1
Content-Length: ...
Content-Type: application/json

{
  "jsonrpc": "2.0",
  "id": 123,
  "method": "getSignerSideOrderERC20",
  "params": {
    "chainId": "1",
    "swapContract": "0xD82E10B9A4107939e55fCCa9B53A9ede6CF2fC46",
    "signerToken": "0xdac17f958d2ee523a2206206994597c13d831ec7",
    "senderWallet": "0xed669F5fe2A37Ef204DB178c7a982717B9f03Ec2",
    "senderToken": "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2",
    "senderAmount": "1000000000000000000",
  }
}
```

Requests can also be made using curl or wget for debugging.

```bash
curl -H 'Content-Type: application/json' \
     -d '{"jsonrpc":"2.0","id":"123","method":"getSignerSideOrderERC20","params":{"chainId":"1","swapContract":"0xD82E10B9A4107939e55fCCa9B53A9ede6CF2fC46","signerToken":"0xdac17f958d2ee523a2206206994597c13d831ec7","senderWallet":"0xed669F5fe2A37Ef204DB178c7a982717B9f03Ec2","senderToken":"0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2","senderAmount":"1000000000000000000"}}' \
     http://localhost:3000/
```

#### Server Response

```javascript
HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: *
Access-Control-Allow-Methods: POST, OPTIONS
Content-Length: ...
Content-Type: application/json

{
  "jsonrpc": "2.0",
  "id": 123,
  "result": {
    "nonce": "99",
    "expiry": "1566941284",
    "signerWallet": "0x73BCEb1Cd57C711feaC4224D062b0F6ff338501f",
    "signerToken": "0xdac17f958d2ee523a2206206994597c13d831ec7",
    "signerAmount": "100000000",
    "senderToken": "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2",
    "senderAmount": "1000000000000000000",
    "v": "28",
    "r": "0x67e0723b0afd357d4f28523bf633dfee16e0eab2f3cbcf8ce1afd32a035d2764",
    "s": "0x1b71e6e633b3334fc88faf4ec0ca1b7611883bc0de4df7024abec07af78b97c3"
  }
}
```

#### Client Settlement

With an OrderERC20 in hand, the client sends an Ethereum transaction to the [SwapERC20](/technology/deployments) contract. The `swapLight` function is gas efficient, whereas the `swap` function provides protocol fee rebates to staked AST holders. Either function can settle a correctly signed OrderERC20. A successful swap emits a `SwapERC20` event.

```typescript
  function swapLight(
    uint256 nonce,
    uint256 expiry,
    address signerWallet,
    address signerToken,
    uint256 signerAmount,
    address senderToken,
    uint256 senderAmount,
    uint8 v,
    bytes32 r,
    bytes32 s
  ) external;
```

```typescript
  event SwapERC20(
    uint256 indexed nonce,
    address indexed signerWallet,
    address signerToken,
    uint256 signerAmount,
    uint256 protocolFee,
    address indexed senderWallet,
    address senderToken,
    uint256 senderAmount
  );
```

The server or client may subscribe to a filter for a `SwapERC20` event with the order `nonce` to track fills.

## LastLookERC20

AirSwap [LastLookERC20](/about/glossary#lastlook-ll) is used by servers to stream quotes to clients. Clients periodically send signed OrderERC20s to the server, which then has the "last look" and option to send it to the EVM for settlement. In last-look, the client is the signer (e.g. `signerAmount`, `signerToken`) and the server is the sender (e.g. `senderAmount`, `senderToken`).

### Example

To find counterparties, see [Discovery](/technology/discovery). With WebSocket server URLs in hand (i.e. the URL schema is `wss`), clients connect to each and calls methods as JSON-RPC over WebSocket.

#### WebSocket

Upon connection, the server calls `setProtocols` on the client.

```javascript
{
  "jsonrpc": "2.0",
  "method": "setProtocols",
  "id": 123,
  "params": [
    [
      {
        "interfaceId": "0x2ca4c820",
        "params": {
          "chainId": "1",
          "swapContractAddress": "0xD82E10B9A4107939e55fCCa9B53A9ede6CF2fC46",
          "walletAddress": "0x73BCEb1Cd57C711feaC4224D062b0F6ff338501f"
        }
      }
    ]
  ]
}
```

The client may then subscribe to pricing updates.

```javascript
{
  "jsonrpc": "2.0",
  "method": "subscribeAllPricingERC20",
  "id": 123,
  "params": []
}
```

The server then continuously updates the client with new pricing.

```javascript
{
  "jsonrpc": "2.0",
  "method": "setPricingERC20",
  "id": 123,
  "params": [
    [
      {
        "baseToken": "0xdac17f958d2ee523a2206206994597c13d831ec7",
        "quoteToken": "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2",
        "bid": [
          ["100", "0.00053"],
          ["1000", "0.00061"],
          ["10000", "0.0007"]
        ],
        "ask": [
          ["100", "0.00055"],
          ["1000", "0.00067"],
          ["10000", "0.0008"]
        ]
      }
    ]
  ]
}
```

The client may send an OrderERC20 to the server to consider a swap.

```javascript
{
  "jsonrpc": "2.0",
  "id": 123,
  "method": "considerOrderERC20",
  "params": {
    "nonce": "1",
    "expiry": "1629117312",
    "signerWallet": "0x0...",
    "signerToken": "0xdac17f958d2ee523a2206206994597c13d831ec7",
    "signerAmount": "1000000000",
    "senderToken": "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2",
    "senderAmount": "530000000000000000",
    "v": "28",
    "r": "0x0...",
    "s": "0x0..."
  }
}
```

With an OrderERC20 in hand, the server sends an Ethereum transaction to the [SwapERC20](/technology/deployments) contract. The `swapLight` function is gas efficient, whereas the `swap` function provides protocol fee rebates to staked AST holders. Either function can settle a correctly signed OrderERC20. A successful swap emits a `SwapERC20` event.

The client may subscribe to a filter for a `SwapERC20` event with the `nonce` they provided to the server to track fills.

## Pricing Formats

Server pricing can be communicated either by levels or a formula. All input and output values for pricing are in base units rather than atomic units. When generating orders, all values must be converted to atomic units.

### Levels

A server may provide "levels" to determine its pricing for various tokens and amounts. Each level is a tuple of amount and price at that level. Amounts and minimums are all in `baseToken`. Each level indicates price "up to" the specified amount and therefore the last level is the maximum.

```javascript
;[
  {
    baseToken: '0xdac17f958d2ee523a2206206994597c13d831ec7',
    quoteToken: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2',
    bid: [
      ['100', '0.00053'],
      ['1000', '0.00061'],
      ['10000', '0.0007'],
    ],
    ask: [
      ['100', '0.00055'],
      ['1000', '0.00067'],
      ['10000', '0.0008'],
    ],
  },
  {
    baseToken: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2',
    quoteToken: '0xdac17f958d2ee523a2206206994597c13d831ec7',
    bid: [
      ['0.5', '2000'],
      ['1', '2010'],
      ['10', '2050'],
    ],
    ask: [
      ['0.5', '2001'],
      ['1', '2015'],
      ['10', '2060'],
    ],
  },
]
```

#### Examples

**Client wants to swap `1000` USDT into WETH.** Client looks up baseToken USDT and quoteToken WETH and uses the `bid` levels above. The first `100` would be multiplied by `0.00053` and second `900` would be multiplied by `0.00061` for a total of `0.602` WETH.

**Client wants to swap `1` WETH into USDT.** Client looks up baseToken WETH and quoteToken USDT and uses the `bid` levels above. The first `0.5` would be multiplied by `2000` and second `0.5` would be multiplied by `2010` for a total of `2005` USDT.

**Client wants to swap WETH into `1000` USDT.** Client looks up baseToken USDT and quoteToken WETH and uses the `ask` levels above. The first `100` would be multiplied by `0.00055` and second `900` would be multiplied by `0.00067` for a total of `0.658` WETH.

**Client wants to swap USDT into `1` WETH.** Client looks up baseToken WETH and quoteToken USDT and uses the `ask` levels above. The first `0.5` would be multiplied by `2001` and second `0.5` would be multiplied by `2015` for a total WETH amount of `2008` USDT.

### Formula

The server can specify formulas to use for pricing. Each formula is an expression with operations including addition, subtraction, multiplication, and division, where `x` is provided by the client.

```javascript
;[
  {
    baseToken: '0xdac17f958d2ee523a2206206994597c13d831ec7',
    quoteToken: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2',
    bid: 'x*0.00053',
    ask: 'x*0.00055',
  },
  {
    baseToken: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2',
    quoteToken: '0xdac17f958d2ee523a2206206994597c13d831ec7',
    bid: 'x*2000',
    ask: 'x*2001',
  },
]
```

#### Examples

**Client wants to swap `1000` USDT into WETH.** Client looks up baseToken USDT and quoteToken WETH and uses the `bid` levels above. `1000` is multiplied by `0.00053` for a total of `0.53` WETH.

**Client wants to swap `1` WETH into USDT.** Client looks up baseToken WETH and quoteToken USDT and uses the `bid` levels above. `1` is multiplied by `2000` for a total of `2000` WETH.

**Client wants to swap WETH into `1000` USDT.** Client looks up baseToken USDT and quoteToken WETH and uses the `ask` levels above. `1000` is multiplied by `0.00055` for a total of `0.55` WETH.

**Client wants to swap USDT into `1` WETH.** Client looks up baseToken WETH and quoteToken USDT and uses the `ask` levels above. `1` is multiplied by `2001` for a total of `2001` WETH.

## Signatures

AirSwap signatures are [EIP712](https://eips.ethereum.org/EIPS/eip-712), which includes a domain separator to avoid replays across chains.

**TypeScript**. Swap signatures in TypeScript can be created using the `@airswap/utils` package.

```typescript
import { UnsignedOrder, createOrderERC20, createOrderERC20Signature } from '@airswap/utils'

const order = createOrderERC20({
  nonce: string,
  expiry: string,
  signerWallet: string,
  signerToken: string,
  signerAmount: string,
  protocolFee: string,
  senderWallet: string,
  senderToken: string,
  senderAmount: string,
})

const { v, r, s } = createOrderERC20Signature(
  order: UnsignedOrder,
  privateKey: string,
  swapContract: string,
  chainId: string,
)
```

**Python**. Swap signatures in Python can be created using the [`py_eth_sig_utils`](https://pypi.org/project/py-eth-sig-utils/) package.

```python
from py_eth_sig_utils.signing import *

SIGNER_KEY = "0000000000000000000000000000000000000000000000000000000000000000"
SWAP_CONTRACT = "0x0000000000000000000000000000000000000000"

DOMAIN = "SWAP_ERC20"
VERSION = "4"
CHAIN_ID = 1

order = {
  "nonce": 0,
  "expiry": 0,
  "signerWallet": "0x0000000000000000000000000000000000000000",
  "signerToken": "0x0000000000000000000000000000000000000000",
  "signerAmount": 0,
  "protocolFee": 0,
  "senderWallet": "0x0000000000000000000000000000000000000000",
  "senderToken": "0x0000000000000000000000000000000000000000",
  "senderAmount": 0
}

data = {
  "types": {
    "EIP712Domain": [
      { "name": "name", "type": "string" },
      { "name": "version", "type": "string" },
      { "name": "chainId", "type": "uint256" },
      { "name": "verifyingContract", "type": "address" },
    ],
    "OrderERC20": [
      { "name": "nonce", "type": "uint256" },
      { "name": "expiry", "type": "uint256" },
      { "name": "signerWallet", "type": "address" },
      { "name": "signerToken", "type": "address" },
      { "name": "signerAmount", "type": "uint256" },
      { "name": "protocolFee", "type": "uint256" },
      { "name": "senderWallet", "type": "address" },
      { "name": "senderToken", "type": "address" },
      { "name": "senderAmount", "type": "uint256" },
    ]
  },
  "domain": {
    "name": DOMAIN,
    "version": VERSION,
    "chainId": CHAIN_ID,
    "verifyingContract": SWAP_CONTRACT,
  },
  "primaryType": "OrderERC20",
  "message": order,
}

v, r, s = sign_typed_data(data, bytes.fromhex(SIGNER_KEY))
```

### Authorized Signers

**Optional.** One account may authorize another account to sign orders on its behalf. For example, a server might sign using an account that has been authorized by a contract wallet. To manage signer authorizations, use the following functions on the [SwapERC20](/technology/deployments) contract.

```
function authorize(address signer) external
function revoke() external
```

### EIP712

The following values are used for the EIP712Domain.

| Param               | Type      | Value                                        |
| ------------------- | --------- | -------------------------------------------- |
| `name`              | `bytes32` | `SWAP_ERC20`                                 |
| `version`           | `bytes32` | `4`                                          |
| `chainId`           | `uint256` | Ethereum Mainnet: `1`, Goerli: `5`           |
| `verifyingContract` | `address` | [SwapERC20](/technology/deployments) address |


# Protocols

## Discovery

### `getProtocols`

Peers may call getProtocols to determine protocols supported by a peer. Protocols are identified by interfaceId and configuration params include the chainId, swapContractAddress, and walletAddress that the peer intends to use.

```typescript
getProtocols(
): [SupportedProtocolInfo](#supportedprotocolinfo)[]
```

#### Returns

`[SupportedProtocolInfo](#supportedprotocolinfo)[]` — Array of supported protocol configurations

### `setProtocols`

When connected via WebSocket, the server may send a setProtocols notification to the client to indicate the protocols it supports.

```typescript
setProtocols(
  protocols: [SupportedProtocolInfo](#supportedprotocolinfo)[], // Array of supported protocol configurations
): boolean
```

#### Parameters

| Name        | Type                                               | Required | Description                                |
| ----------- | -------------------------------------------------- | -------- | ------------------------------------------ |
| `protocols` | [SupportedProtocolInfo](#supportedprotocolinfo)\[] | Yes      | Array of supported protocol configurations |

#### Returns

`boolean`

### `getTokens`

Peers may call getTokens to determine tokens supported by another peer, whether connected via HTTPS or WebSocket. The return value is an array of tokens identified by the token contract address.

```typescript
getTokens(
): [Address](#address)[]
```

#### Returns

`[Address](#address)[]` — Array of token contract addresses

### `setTokens`

When connected via WebSocket, the server may send a setTokens notification to indicate the tokens it supports.

```typescript
setTokens(
  tokens: [Address](#address)[], // Array of token contract addresses
): boolean
```

#### Parameters

| Name     | Type                   | Required | Description                       |
| -------- | ---------------------- | -------- | --------------------------------- |
| `tokens` | [Address](#address)\[] | Yes      | Array of token contract addresses |

#### Returns

`boolean`

## RequestForQuoteERC20

### `getSignerSideOrderERC20`

Given a senderAmount the server returns a signed OrderERC20 including the signerAmount. The client is selling to the server. Client may optionally request a minimum expiry in seconds.

```typescript
getSignerSideOrderERC20(
  chainId: [ChainId](#chainid), // The blockchain network chain ID
  swapContract: [Address](#address), // Address of the AirSwap SwapERC20 contract
  senderAmount: [Amount](#amount), // Amount of tokens the sender will provide (in wei)
  signerToken: [Address](#address), // Address of the token the signer will provide
  senderToken: [Address](#address), // Address of the token the sender will provide
  senderWallet: [Address](#address), // Address of the sender's wallet
  minExpiry?: [Amount](#amount), // Minimum expiry in seconds (optional)
  proxyingFor?: [Address](#address), // Address being proxied for (optional)
): [OrderERC20](#ordererc20)
```

#### Parameters

| Name           | Type                | Required | Description                                       |
| -------------- | ------------------- | -------- | ------------------------------------------------- |
| `chainId`      | [ChainId](#chainid) | Yes      | The blockchain network chain ID                   |
| `swapContract` | [Address](#address) | Yes      | Address of the AirSwap SwapERC20 contract         |
| `senderAmount` | [Amount](#amount)   | Yes      | Amount of tokens the sender will provide (in wei) |
| `signerToken`  | [Address](#address) | Yes      | Address of the token the signer will provide      |
| `senderToken`  | [Address](#address) | Yes      | Address of the token the sender will provide      |
| `senderWallet` | [Address](#address) | Yes      | Address of the sender's wallet                    |
| `minExpiry`    | [Amount](#amount)   | No       | Minimum expiry in seconds (optional)              |
| `proxyingFor`  | [Address](#address) | No       | Address being proxied for (optional)              |

#### Returns

`[OrderERC20](#ordererc20)` — Signed ERC20 order

### `getSenderSideOrderERC20`

Given a signerAmount the server returns a signed OrderERC20 with a senderAmount. The client is buying from the server. Client may optionally request a minimum expiry in seconds.

```typescript
getSenderSideOrderERC20(
  chainId: [ChainId](#chainid), // The blockchain network chain ID
  swapContract: [Address](#address), // Address of the AirSwap SwapERC20 contract
  signerAmount: [Amount](#amount), // Amount of tokens the signer will provide (in wei)
  signerToken: [Address](#address), // Address of the token the signer will provide
  senderToken: [Address](#address), // Address of the token the sender will provide
  senderWallet: [Address](#address), // Address of the sender's wallet
  minExpiry?: [Amount](#amount), // Minimum expiry in seconds (optional)
  proxyingFor?: [Address](#address), // Address being proxied for (optional)
): [OrderERC20](#ordererc20)
```

#### Parameters

| Name           | Type                | Required | Description                                       |
| -------------- | ------------------- | -------- | ------------------------------------------------- |
| `chainId`      | [ChainId](#chainid) | Yes      | The blockchain network chain ID                   |
| `swapContract` | [Address](#address) | Yes      | Address of the AirSwap SwapERC20 contract         |
| `signerAmount` | [Amount](#amount)   | Yes      | Amount of tokens the signer will provide (in wei) |
| `signerToken`  | [Address](#address) | Yes      | Address of the token the signer will provide      |
| `senderToken`  | [Address](#address) | Yes      | Address of the token the sender will provide      |
| `senderWallet` | [Address](#address) | Yes      | Address of the sender's wallet                    |
| `minExpiry`    | [Amount](#amount)   | No       | Minimum expiry in seconds (optional)              |
| `proxyingFor`  | [Address](#address) | No       | Address being proxied for (optional)              |

#### Returns

`[OrderERC20](#ordererc20)` — Signed ERC20 order

### `getPricingERC20`

Client may request soft pricing for a list of token pairs. Client may optionally request a minimum expiry in seconds to be factored into pricing. Returns current formula or levels for each pair.

```typescript
getPricingERC20(
  pairs: [TokenPair](#tokenpair)[], // Array of token pairs to get pricing for
  minExpiry?: [Amount](#amount), // Minimum expiry in seconds (optional)
): [Pricing](#pricing)[]
```

#### Parameters

| Name        | Type                       | Required | Description                             |
| ----------- | -------------------------- | -------- | --------------------------------------- |
| `pairs`     | [TokenPair](#tokenpair)\[] | Yes      | Array of token pairs to get pricing for |
| `minExpiry` | [Amount](#amount)          | No       | Minimum expiry in seconds (optional)    |

#### Returns

`[Pricing](#pricing)[]` — Pricing information for each pair

### `getAllPricingERC20`

Client may request pricing for all available pairs.

```typescript
getAllPricingERC20(
): [Pricing](#pricing)[]
```

#### Returns

`[Pricing](#pricing)[]` — Pricing information for all available pairs

## LastLookERC20

### `subscribePricingERC20`

Client subscribes to pricing updates for a list of token pairs. Returns current formula or levels for each pair.

```typescript
subscribePricingERC20(
  pairs: [TokenPair](#tokenpair)[], // Array of token pairs to subscribe to
  minExpiry?: [Amount](#amount), // Minimum expiry in seconds (optional)
): [Pricing](#pricing)[]
```

#### Parameters

| Name        | Type                       | Required | Description                          |
| ----------- | -------------------------- | -------- | ------------------------------------ |
| `pairs`     | [TokenPair](#tokenpair)\[] | Yes      | Array of token pairs to subscribe to |
| `minExpiry` | [Amount](#amount)          | No       | Minimum expiry in seconds (optional) |

#### Returns

`[Pricing](#pricing)[]` — Current pricing for subscribed pairs

### `subscribeAllPricingERC20`

Client subscribes to pricing updates for all available pairs. Returns current formula or levels for each pair.

```typescript
subscribeAllPricingERC20(
): [Pricing](#pricing)[]
```

#### Returns

`[Pricing](#pricing)[]` — Current pricing for all available pairs

### `unsubscribePricingERC20`

Client unsubscribes from pricing updates for a list of token pairs.

```typescript
unsubscribePricingERC20(
  pairs: [TokenPair](#tokenpair)[], // Array of token pairs to unsubscribe from
): boolean
```

#### Parameters

| Name    | Type                       | Required | Description                              |
| ------- | -------------------------- | -------- | ---------------------------------------- |
| `pairs` | [TokenPair](#tokenpair)\[] | Yes      | Array of token pairs to unsubscribe from |

#### Returns

`boolean`

### `unsubscribeAllPricingERC20`

Client unsubscribes from all pricing subscriptions.

```typescript
unsubscribeAllPricingERC20(
): boolean
```

#### Returns

`boolean`

### `setPricingERC20`

Server updates pricing for one or more token pairs.

```typescript
setPricingERC20(
  pricing: [Pricing](#pricing)[], // Array of pricing updates
): boolean
```

#### Parameters

| Name      | Type                   | Required | Description              |
| --------- | ---------------------- | -------- | ------------------------ |
| `pricing` | [Pricing](#pricing)\[] | Yes      | Array of pricing updates |

#### Returns

`boolean`

### `considerOrderERC20`

Client provides a priced OrderERC20 to the server. Returns boolean true if accepted by the server. In last-look, the client is the signer and the server is the sender.

```typescript
considerOrderERC20(
  nonce: [Amount](#amount), // Unique order nonce
  expiry: [Amount](#amount), // Order expiry timestamp
  signerWallet: [Address](#address), // Address of the signer's wallet
  signerToken: [Address](#address), // Address of the token the signer will provide
  signerAmount: [Amount](#amount), // Amount of tokens the signer will provide
  senderToken: [Address](#address), // Address of the token the sender will provide
  senderAmount: [Amount](#amount), // Amount of tokens the sender will provide
  v: [Amount](#amount), // ECDSA signature recovery parameter
  r: [Bytes32](#bytes32), // ECDSA signature r parameter
  s: [Bytes32](#bytes32), // ECDSA signature s parameter
): boolean
```

#### Parameters

| Name           | Type                | Required | Description                                  |
| -------------- | ------------------- | -------- | -------------------------------------------- |
| `nonce`        | [Amount](#amount)   | Yes      | Unique order nonce                           |
| `expiry`       | [Amount](#amount)   | Yes      | Order expiry timestamp                       |
| `signerWallet` | [Address](#address) | Yes      | Address of the signer's wallet               |
| `signerToken`  | [Address](#address) | Yes      | Address of the token the signer will provide |
| `signerAmount` | [Amount](#amount)   | Yes      | Amount of tokens the signer will provide     |
| `senderToken`  | [Address](#address) | Yes      | Address of the token the sender will provide |
| `senderAmount` | [Amount](#amount)   | Yes      | Amount of tokens the sender will provide     |
| `v`            | [Amount](#amount)   | Yes      | ECDSA signature recovery parameter           |
| `r`            | [Bytes32](#bytes32) | Yes      | ECDSA signature r parameter                  |
| `s`            | [Bytes32](#bytes32) | Yes      | ECDSA signature s parameter                  |

#### Returns

`boolean` — Whether the order was accepted

## Indexing

### `addOrder`

Peers may call addOrder to add an order to another peer.

```typescript
addOrder(
  order: [FullOrder](#fullorder), // The full order to add
  tags?: string[], // Tags to associate with the order
): boolean
```

#### Parameters

| Name    | Type                    | Required | Description                      |
| ------- | ----------------------- | -------- | -------------------------------- |
| `order` | [FullOrder](#fullorder) | Yes      | The full order to add            |
| `tags`  | string\[]               | No       | Tags to associate with the order |

#### Returns

`boolean`

### `getOrders`

Peers may call getOrders to query for orders indexed by another peer.

```typescript
getOrders(
  filter: [OrderFilter](#orderfilter), // Filter criteria for orders
  offset?: integer, // Pagination offset
  limit?: integer, // Maximum number of orders to return
  by?: [Indexes](#indexes), // Index to sort by
  direction?: [Direction](#direction), // Sort direction
): [OrderResponse](#orderresponse)
```

#### Parameters

| Name        | Type                        | Required | Description                        |
| ----------- | --------------------------- | -------- | ---------------------------------- |
| `filter`    | [OrderFilter](#orderfilter) | Yes      | Filter criteria for orders         |
| `offset`    | integer                     | No       | Pagination offset                  |
| `limit`     | integer                     | No       | Maximum number of orders to return |
| `by`        | [Indexes](#indexes)         | No       | Index to sort by                   |
| `direction` | [Direction](#direction)     | No       | Sort direction                     |

#### Returns

`[OrderResponse](#orderresponse)`

### `getTags`

Peers may call getTags to get all available tags for a token.

```typescript
getTags(
  token: [Address](#address), // Token contract address
): string[]
```

#### Parameters

| Name    | Type                | Required | Description            |
| ------- | ------------------- | -------- | ---------------------- |
| `token` | [Address](#address) | Yes      | Token contract address |

#### Returns

`string[]`

## IndexingERC20

### `addOrderERC20`

Peers may call addOrderERC20 to add an ERC20 order to another peer.

```typescript
addOrderERC20(
  order: [FullOrderERC20](#fullordererc20), // The full ERC20 order to add
  tags?: string[], // Tags to associate with the order
): boolean
```

#### Parameters

| Name    | Type                              | Required | Description                      |
| ------- | --------------------------------- | -------- | -------------------------------- |
| `order` | [FullOrderERC20](#fullordererc20) | Yes      | The full ERC20 order to add      |
| `tags`  | string\[]                         | No       | Tags to associate with the order |

#### Returns

`boolean`

### `getOrdersERC20`

Peers may call getOrdersERC20 to query for ERC20 orders indexed by another peer.

```typescript
getOrdersERC20(
  filter: [OrderFilter](#orderfilter), // Filter criteria for orders
  offset?: integer, // Pagination offset
  limit?: integer, // Maximum number of orders to return
  by?: [Indexes](#indexes), // Index to sort by
  direction?: [Direction](#direction), // Sort direction
): [OrderResponseERC20](#orderresponseerc20)
```

#### Parameters

| Name        | Type                        | Required | Description                        |
| ----------- | --------------------------- | -------- | ---------------------------------- |
| `filter`    | [OrderFilter](#orderfilter) | Yes      | Filter criteria for orders         |
| `offset`    | integer                     | No       | Pagination offset                  |
| `limit`     | integer                     | No       | Maximum number of orders to return |
| `by`        | [Indexes](#indexes)         | No       | Index to sort by                   |
| `direction` | [Direction](#direction)     | No       | Sort direction                     |

#### Returns

`[OrderResponseERC20](#orderresponseerc20)`

### `getTags`

Peers may call getTags to get all available tags for a token.

```typescript
getTags(
  token: [Address](#address), // Token contract address
): string[]
```

#### Parameters

| Name    | Type                | Required | Description            |
| ------- | ------------------- | -------- | ---------------------- |
| `token` | [Address](#address) | Yes      | Token contract address |

#### Returns

`string[]`

## Types

### Address

Ethereum address (20 bytes)

### Bytes32

32-byte hex string

### Amount

Numeric string representing an amount

### ChainId

Blockchain network chain ID

### SupportedProtocolInfo

Information about a supported trading protocol

| Property      | Type                                                                                                                                                                    | Description                                                               |
| ------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------- |
| `interfaceId` | string                                                                                                                                                                  | Protocol interface identifier (e.g., 0x02ad05d3 for RequestForQuoteERC20) |
| `params`      | { chainId: [ChainId](#chainid), swapContractAddress: [Address](#address), walletAddress: [Address](#address), senderServer: string, senderWallet: [Address](#address) } |                                                                           |

### TokenPair

A pair of tokens for trading

| Property     | Type                | Description         |
| ------------ | ------------------- | ------------------- |
| `baseToken`  | [Address](#address) | Base token address  |
| `quoteToken` | [Address](#address) | Quote token address |

### OrderERC20

Signed ERC20 order in AirSwap format

| Property       | Type                | Description                                       |
| -------------- | ------------------- | ------------------------------------------------- |
| `nonce`        | [Amount](#amount)   | Unique order nonce                                |
| `expiry`       | [Amount](#amount)   | Order expiry timestamp (Unix timestamp)           |
| `signerWallet` | [Address](#address) | Address of the signer's wallet                    |
| `signerToken`  | [Address](#address) | Address of the token the signer will provide      |
| `signerAmount` | [Amount](#amount)   | Amount of tokens the signer will provide (in wei) |
| `protocolFee`  | [Amount](#amount)   | Protocol fee in basis points                      |
| `senderToken`  | [Address](#address) | Address of the token the sender will provide      |
| `senderAmount` | [Amount](#amount)   | Amount of tokens the sender will provide (in wei) |
| `v`            | [Amount](#amount)   | ECDSA signature recovery parameter                |
| `r`            | [Bytes32](#bytes32) | ECDSA signature r parameter                       |
| `s`            | [Bytes32](#bytes32) | ECDSA signature s parameter                       |

### FullOrderERC20

Full ERC20 order including settlement information

### FullOrder

Full order for NFT/ERC721 swaps

| Property          | Type                | Description |
| ----------------- | ------------------- | ----------- |
| `nonce`           | [Amount](#amount)   |             |
| `expiry`          | [Amount](#amount)   |             |
| `signerWallet`    | [Address](#address) |             |
| `signerToken`     | [Address](#address) |             |
| `signerAmount`    | [Amount](#amount)   |             |
| `signerId`        | [Amount](#amount)   |             |
| `senderWallet`    | [Address](#address) |             |
| `senderToken`     | [Address](#address) |             |
| `senderAmount`    | [Amount](#amount)   |             |
| `senderId`        | [Amount](#amount)   |             |
| `affiliateWallet` | [Address](#address) |             |
| `affiliateAmount` | [Amount](#amount)   |             |
| `chainId`         | [ChainId](#chainid) |             |
| `swapContract`    | [Address](#address) |             |
| `v`               | [Amount](#amount)   |             |
| `r`               | [Bytes32](#bytes32) |             |
| `s`               | [Bytes32](#bytes32) |             |

### Pricing

Pricing information for a token pair

| Property     | Type                | Description                                  |
| ------------ | ------------------- | -------------------------------------------- |
| `baseToken`  | [Address](#address) |                                              |
| `quoteToken` | [Address](#address) |                                              |
| `minimum`    | [Amount](#amount)   | Minimum order size                           |
| `bid`        | any                 | Bid pricing (levels array or formula string) |
| `ask`        | any                 | Ask pricing (levels array or formula string) |

### Levels

Array of price levels as \[baseAmount, quoteAmount] tuples in wei

### Formula

Pricing formula where x is the input amount (e.g., 'x\*0.00053')

### OrderFilter

Filter criteria for querying orders

| Property          | Type                | Description |
| ----------------- | ------------------- | ----------- |
| `chainId`         | [ChainId](#chainid) |             |
| `signerWallet`    | [Address](#address) |             |
| `signerToken`     | [Address](#address) |             |
| `signerId`        | [Amount](#amount)   |             |
| `senderWallet`    | [Address](#address) |             |
| `senderToken`     | [Address](#address) |             |
| `minSignerAmount` | [Amount](#amount)   |             |
| `maxSignerAmount` | [Amount](#amount)   |             |
| `minSenderAmount` | [Amount](#amount)   |             |
| `maxSenderAmount` | [Amount](#amount)   |             |
| `tags`            | string\[]           |             |

### Indexes

Index to sort orders by

### Direction

Sort direction

### OrderResponse

Response containing orders and pagination info

| Property | Type                       | Description |
| -------- | -------------------------- | ----------- |
| `orders` | [FullOrder](#fullorder)\[] |             |
| `offset` | integer                    |             |
| `total`  | integer                    |             |

### OrderResponseERC20

Response containing ERC20 orders and pagination info

| Property | Type                                 | Description |
| -------- | ------------------------------------ | ----------- |
| `orders` | [FullOrderERC20](#fullordererc20)\[] |             |
| `offset` | integer                              |             |
| `total`  | integer                              |             |


# Discovery

To find servers that support a token pair, clients call the `getURLsForToken` function on the [Registry](https://github.com/airswap/airswap-about/blob/master/technology/deployments.md) contract for each token and then intersect the results. For example, if the resulting URLs for token A are `[maker1.com, maker2.com]` and for token B are `[maker2.com, maker3.com]` then the only server supporting swapping token A for B is `maker2.com`.

See `getURLsForToken` on the Registry contract:

```typescript
function getURLsForToken(address token) external view returns (string[] memory urls);
```

Check [deployments](https://github.com/airswap/airswap-about/blob/master/technology/deployments.md) for latest contract addresses for Registry.

## Fetching URLs via CLI

Ensure the AirSwap CLI is installed.

```
$ yarn global add airswap
```

Use `airswap chain` to set your chain to Goerli or Mainnet.

```
$ airswap chain
AirSwap CLI 4.0.1 — https://www.airswap.xyz/

set the active ethereum chain

Current chain: 5 (GOERLI)

New chain id:  (5) 1

Set active chain to ETHEREUM.
```

Use `registry:get` to fetch server URLs for a token pair.

```
$ airswap registry:list
AirSwap CLI 4.0.1 — https://www.airswap.xyz/

get urls from the registry ETHEREUM

Registry 0x8F9DA6d38939411340b19401E8c54Ea1f51B8f95

Token pair (e.g. WETH/USDT):  dai/weth

Server
----------------------------------------
https://maker.example.com/
```

### Example: Take an Order

Try `airswap order` with a server URL from the previous command.

## TypeScript

Using the `Registry` library from `@airswap/libraries` returns `Server` instances that you can interact with.

```typescript
import { ProtocolIds } from '@airswap/utils'
import { Registry } from '@airswap/libraries'
const servers = await Registry.getServers(
  provider,
  chainId,
  ProtocolIds.RequestForQuoteERC20,
  signerToken,
  senderToken,
)
```

Calling the Registry directly using `ethers`

```typescript
import { ethers } from 'ethers'
import { chainNames } from '@airswap/utils'
import * as RegistryContract from '@airswap/registry/build/contracts/Registry.sol/Registry.json'
import * as registryDeploys from '@airswap/registry/deploys.js'
const RegistryInterface = new ethers.utils.Interface(
  JSON.stringify(RegistryContract.abi),
)

new ethers.Contract(
  registryDeploys[chainId],
  RegistryInterface,
  ethers.getDefaultProvider(chainNames[chainId].toLowerCase()),
)

const signerTokenURLs = await this.contract.getURLsForToken(signerToken)
const senderTokenURLs = await this.contract.getURLsForToken(senderToken)

const serverURLs = signerTokenURLs.filter((value) =>
  senderTokenURLs.includes(value),
)
```

### Example: Take an Order

```typescript
import { Registry, SwapERC20 } from '@airswap/libraries'
import { ProtocolIds, chainNames, orderERC20ToParams } from '@airswap/utils'

const servers = await Registry.getServers(
  provider,
  chainId,
  ProtocolIds.RequestForQuoteERC20,
  signerToken,
  senderToken,
)

const order = servers[0].getSignerSideOrderERC20(
  senderAmount,
  signerToken,
  senderToken,
  senderWallet,
)

await SwapERC20.getContract(provider, chainId).swapLight(
  ...orderERC20ToParams(order),
)
```


# Makers

Makers run web servers that implement APIs like RFQ and LastLook using JSON-RPC [over HTTP](https://www.jsonrpc.org/historical/json-rpc-over-http.html) or WebSocket. To be reachable by clients, servers run at public endpoints with [CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) enabled. To become discoverable, server URLs are added to the [Registry](/technology/deployments) smart contract, which is queried by clients.

## Introduction

AirSwap liquidity providers are **makers**, generally online and quoting, with **takers** on the other side of each trade. At the lower protocol level, where the software used by makers and takers interacts with Ethereum, there are **signers**, who set and cryptographically sign terms (an order), and **senders** who submit those terms for settlement on the Swap contract.

For the RFQ protocol, a server is always the **signer** and the client is always the **sender**. For LastLook, the client is always the **signer** and a server is always the **sender**.

* **Nonces** are unique identifiers for swaps and used for cancels. They should be generated incrementally but might execute out of order.
* **URLs** may be to either HTTP or WebSocket servers using `https` or `wss` respectively.
* **Registry** is used to signal that a server is available to trade specific tokens, including contact information (URL), without pricing.

## HTTP vs WebSocket

If a URL is HTTPS, it implies that the server supports the latest RFQ protocol at that endpoint. If a URL is WebSocket (`wss`) then the server communicates its supported protocols upon connnection. See the `setProtocols` method of the [Request for Quote](/technology/protocols#rfq) and [LastLook](/technology/protocols#last-look) protocols for details. WebSocket servers can support both RFQ and LastLook protocols.

## Getting Started

Getting started is as easy as standing up a JSON-RPC web server and adding its URL to the Registry.

* Check out the [reference server](https://github.com/airswap/airswap-ref-server) for inspiration.
* Servers generally implement the [RFQ](https://github.com/airswap/airswap-about/blob/master/technology/protocols/README.md) protocol at minimum.
* You can debug your server with the [CLI](#debugging-with-the-cli) or via curl.
* When ready, add your server [to the Registry](#adding-to-the-registry) by calling setURL, addTokens, and addProtocols.
  * Registry staking requirements are as follows (stakingCost, supportCost).
    * ETH: 100K AST, 100 AST
    * BSC: 0.1 WBNB, 0.001 WBNB
    * POLYGON: 100 WMATIC, 1 WMATIC
    * AVALANCHE: 1 WAVAX, 0.01 WAVAX
    * LINEA: 0.05 WETH, 0.0005 WETH
  * Registry enables servers to signal support for multiple protocols with addProtocols.
    * RequestForQuoteERC20 (0x02ad05d3)
    * LastLookERC20 (0x395ca9f1)
    * IndexingERC20 (0x85ccc7d5)
    * Indexing = (0x9498325a)
    * Discovery (0xf3713ede)

## Protocol Fees

When signing orders in RFQ, a protocol fee (in basis points) is [hashed into the signature](broken://pages/ZJDEM2xIqKhSZ1afPJBF#signatures) and verified during settlement. The value of this parameter must match its current value of `protocolFeeLight` on the [SwapERC20](/technology/deployments) contract. The amount is transferred from the `signerWallet` address upon settlement.

100% of protocol fees go toward rewarding AirSwap governance participants and project contributors.

## Handling Errors

Provide descriptive errors where possible. In the case of a server side error, return a JSON-RPC error response.

```javascript
{
  "jsonrpc": "2.0",
  "id": 123,
  "error": { "code": -33605, "message": "Rate limit exceeded" }
}
```

The following are error codes in the [JSON-RPC specification](http://www.jsonrpc.org/specification#error_object):

* `-32700` Parse error
* `-32600` Invalid Request
* `-32601` Method not found
* `-32602` Invalid params
* `-32603` Internal error
* `-32000 to -32099` (Reserved for implementation-defined server-errors)

The following are AirSwap specific errors:

* `-33600` Cannot provide the requested quote or order
* `-33601` Not trading the requested `signerToken` `senderToken` pair
* `-33602` The specified `senderAmount` or `signerAmount` is too low
* `-33603` The specified `senderAmount` or `signerAmount` is too high
* `-33604` Invalid request parameters
* `-33605` Rate limit exceeded
* `-33700 to -33799` (Reserved for implementation specific trading errors)

## Testing with the Web App

To connect directly to your server via the Web App, construct a URL as follows.

```
https://swap.eth.limo/#/swap/:fromToken/:toToken?serverUrl=SERVER_URL
```

* `fromToken` the contract address of the senderToken (client).
* `toToken` the contract address of the signerToken (server).
* `SERVER_URL` a URL-encoded server URL to connect to including schema.

A complete example:

```
https://swap.eth.limo/#/swap/0xdac17f958d2ee523a2206206994597c13d831ec7/0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48?serverUrl=https%3A%2F%2Fmaker.com%2Fapi
```

## Testing with the CLI

Ensure the AirSwap CLI is installed.

```
$ yarn global add airswap
```

In development, set the chain to `5` with the `airswap chain` command. The following examples assume a local development server is running at `http://localhost:3000`.

Several useful commands can help you debug your server:

* `airswap order` to request an order directly from your server. (RFQ)
* `airswap compare` to request an order from servers supporting a specific token pair. Once your server is on the registry it will be queried with this command. (RFQ)
* `airswap stream` to subscribe to a pricing stream and make orders for your server. (LastLook)

## Adding to the Registry

The following steps (setURL, addTokens, and addProtocols) can be called directly on the [Registry](/technology/deployments) contract. Alternatively, you are welcome to use the CLI as follows.

```
$ yarn global add airswap
```

Once your server is up and running at a **public URL**, you're ready to add it to the Registry. First, ensure an account is set with the `airswap account:import` command. You can but are not required to use the same Ethereum account that your Server is using.

Let's take a look at the available Registry commands.

```
$ airswap registry
AirSwap CLI 5.0.3 — https://www.airswap.io/
add and remove supported tokens

USAGE
  $ airswap registry:COMMAND

COMMANDS
  registry:approve  enable staking on the registry
  registry:eject    remove url, protocols, and tokens from registry
  registry:list     get urls from the registry
  registry:revoke   disable staking on the registry
  registry:status   check status of url, protocols, and tokens on registry
  registry:url      set server url on the registry
```

First run the following command to enable staking for your account.

```
$ airswap registry:approve
```

Next run the following command to set your server url on the registry.

```
$ airswap registry:url
```

Next run the following command to add tokens you support.

```
$ airswap tokens:add
```

Next run the following command to add protocols you support.

```
$ airswap protocols:add
```

To ensure your configuration is correct, run the following.

```
$ airswap registry:status
```

Now that your server is running and has been added to the Registry, your quotes will be returned among results of the `airswap compare` command and aggregators like [MetaMask Swaps](https://medium.com/metamask/introducing-metamask-swaps-84318c643785).

```
$ airswap best
AirSwap CLI 5.0.0 — https://www.airswap.xyz/

get the best available order ETHEREUM

buy or sell:  buy
amount:  0.1
of:  weth
for:  dai

Requesting from 7 peers... done

Quote from https://maker.example.com/

✨ Buy 0.1 WETH for 250 DAI
Price 0.0004 WETH/DAI (2500 DAI/WETH)
```


# Delegate

Delegate is a contract that allows users to set on-chain trading rules that accept and execute AirSwap orders that meet price criteria. In terms of the underlying SwapERC20 protocol, a trader setting rules is authorizing the Delegate to act as `sender` on its behalf. The trader interfacing with the delegate is the `signer` of each order. Delegate acts as an on-chain intermediary for cases where a Trader does not have an immediate counterparty or wishes to make an order publicly available.

See the [deployments](/technology/deployments) page for latest deployed Delegate contract addresses.

## Rules

To enable Delegate call the `setRule` function. Token approvals must be set up by `senderWallet` on the `senderToken` to allow Delegate to act as a spender.

```typescript
function setRule(
  address senderWallet,
  address senderToken,
  uint256 senderAmount,
  address signerToken,
  uint256 signerAmount,
  uint256 expiry
) external;
```

Rules can be updated using `setRule` again or deleted using `unsetRule`.

```typescript
function unsetRule(
  address senderWallet,
  address senderToken,
  address signerToken
) external;
```

## Swaps

To trade with Delegate, query event logs `SetRule` and `UnsetRule` for pricing information. With price in hand, create and sign an order at any time and call `swap` on the Delegate contract. Upon success, Delegate emits a `DelegateSwap` event.

```typescript
function swap(
  address senderWallet,
  uint256 nonce,
  uint256 expiry,
  address signerWallet,
  address signerToken,
  uint256 signerAmount,
  address senderToken,
  uint256 senderAmount,
  uint8 v,
  bytes32 r,
  bytes32 s
) external
```

Delegate uses SwapERC20 `swapLight` behind the scenes to complete the swap.

## Managers

A wallet usually manages its own rules. A wallet may authorize another wallet to manage rules on its behalf; for example, a cold wallet may authorize a hot wallet. To authorize a manager, call the `authorize` function on the Delegate.

```typescript
function authorize(address manager) external
```

Delegate will emit an `Authorize` event. To revoke an existing authorization, call `revoke` on the Delegate.

```typescript
function revoke() external
```

Delegate will emit a `Revoke` event.


# Marketplaces

Marketplaces are custom decentralized frontends for NFT communities.

![](/files/0VWqUO47ARZB7QI7zdkG)

## Get the code

From <https://github.com/airswap/airswap-marketplace>...

* Option 1: Clone the repository
* Option 2: [Download a zip file](https://github.com/airswap/airswap-marketplace/releases/)

## Set up environment

Environment variables are required to be set.

* `REACT_APP_CHAIN_ID` — the chain ID the app will run on
* `REACT_APP_COLLECTION_NAME` — a collection name to include on the app
* `REACT_APP_COLLECTION_IMAGE` — a collection cover image to include on the app
* `REACT_APP_COLLECTION_TOKEN` — the ERC721 token address for the collection
* `REACT_APP_CURRENCY_TOKEN` — the ERC20 token address to use as currency
* `REACT_APP_STORAGE_SERVER_URL` — \[optional] a server URL to use for listing storage
* `REACT_APP_RPC_URL_X` — \[optional] a server URL to fetch on-chain data where X is chain ID
* `REACT_APP_WALLET_CONNECT_PROJECT_ID` — \[optional] project ID to support wallet connect

## Deploy your app

* GitHub Pages — Free static site hosting on GitHub. If you fork or otherwise copy the Marketplace codebase into your own repository you can set up deploys to Pages with [the following guide](https://docs.github.com/en/pages/getting-started-with-github-pages/configuring-a-publishing-source-for-your-github-pages-site).
* Other — The build generates static assets that can be easily published to any hosting service.

## Contributions

AirSwap is an open-source development community. If you would like to bugfix, improve, or otherwise contribute to the Marketplace codebase, please see the [repository on GitHub](https://github.com/airswap/airswap-marketplace).


# Deployments

See all releases on [GitHub](https://github.com/airswap/airswap-protocols/releases).

## AirSwap V5.0

### Ethereum (1)

* SwapERC20 — [`0xD82E10B9A4107939e55fCCa9B53A9ede6CF2fC46`](https://etherscan.io/address/0xD82E10B9A4107939e55fCCa9B53A9ede6CF2fC46#code)
* Swap — [`0x01b28Aa66a54c6F2bE5C2eF905A2329270CCa96F`](https://etherscan.io/address/0x01b28Aa66a54c6F2bE5C2eF905A2329270CCa96F#code)
* Wrapper — [`0x88d0D1a1472307d1853809C3aA455B1B76c9bCfe`](https://etherscan.io/address/0x88d0D1a1472307d1853809C3aA455B1B76c9bCfe#code)
* Registry — [`0xe30E9c001dEFb5F0B04fD21662454A2427F4257A`](https://etherscan.io/address/0xe30E9c001dEFb5F0B04fD21662454A2427F4257A#code)
* Pool — [`0xbbcec987E4C189FCbAB0a2534c77b3ba89229F11`](https://etherscan.io/address/0xbbcec987E4C189FCbAB0a2534c77b3ba89229F11#code)
* Staking — [`0x8Bf384296A009723435aD5E8203DA5736b895038`](https://etherscan.io/address/0x8Bf384296A009723435aD5E8203DA5736b895038#code)
* Delegate — [`0xDe1Ebf9b429F5066FD060F86847657e29bD49Bb0`](https://etherscan.io/address/0xDe1Ebf9b429F5066FD060F86847657e29bD49Bb0#code)
* AST — [`0x27054b13b1b798b345b591a4d22e6562d47ea75a`](https://etherscan.io/address/0x27054b13b1b798b345b591a4d22e6562d47ea75a#code)

### BSC (56)

* SwapERC20 — [`0xD82E10B9A4107939e55fCCa9B53A9ede6CF2fC46`](https://bscscan.com/address/0xD82E10B9A4107939e55fCCa9B53A9ede6CF2fC46#code)
* Swap — [`0x01b28Aa66a54c6F2bE5C2eF905A2329270CCa96F`](https://bscscan.com/address/0x01b28Aa66a54c6F2bE5C2eF905A2329270CCa96F#code)
* Wrapper — [`0x88d0D1a1472307d1853809C3aA455B1B76c9bCfe`](https://bscscan.com/address/0x88d0D1a1472307d1853809C3aA455B1B76c9bCfe#code)
* Registry — [`0xe30E9c001dEFb5F0B04fD21662454A2427F4257A`](https://bscscan.com/address/0xe30E9c001dEFb5F0B04fD21662454A2427F4257A#code)
* Pool — [`0xbbcec987E4C189FCbAB0a2534c77b3ba89229F11`](https://bscscan.com/address/0xbbcec987E4C189FCbAB0a2534c77b3ba89229F11#code)

### Polygon (137)

* SwapERC20 — [`0xD82E10B9A4107939e55fCCa9B53A9ede6CF2fC46`](https://polygonscan.com/address/0xD82E10B9A4107939e55fCCa9B53A9ede6CF2fC46#code)
* Swap — [`0x01b28Aa66a54c6F2bE5C2eF905A2329270CCa96F`](https://polygonscan.com/address/0x01b28Aa66a54c6F2bE5C2eF905A2329270CCa96F#code)
* Wrapper — [`0x88d0D1a1472307d1853809C3aA455B1B76c9bCfe`](https://polygonscan.com/address/0x88d0D1a1472307d1853809C3aA455B1B76c9bCfe#code)
* Registry — [`0xe30E9c001dEFb5F0B04fD21662454A2427F4257A`](https://polygonscan.com/address/0xe30E9c001dEFb5F0B04fD21662454A2427F4257A#code)
* Pool — [`0xbbcec987E4C189FCbAB0a2534c77b3ba89229F11`](https://polygonscan.com/address/0xbbcec987E4C189FCbAB0a2534c77b3ba89229F11#code)

### Linea (59144)

* SwapERC20 — [`0xD82E10B9A4107939e55fCCa9B53A9ede6CF2fC46`](https://lineascan.build/address/0xD82E10B9A4107939e55fCCa9B53A9ede6CF2fC46#code)
* Swap — [`0x01b28Aa66a54c6F2bE5C2eF905A2329270CCa96F`](https://lineascan.build/address/0x01b28Aa66a54c6F2bE5C2eF905A2329270CCa96F#code)
* Wrapper — [`0x88d0D1a1472307d1853809C3aA455B1B76c9bCfe`](https://lineascan.build/address/0x88d0D1a1472307d1853809C3aA455B1B76c9bCfe#code)
* Registry — [`0xe30E9c001dEFb5F0B04fD21662454A2427F4257A`](https://lineascan.build/address/0xe30E9c001dEFb5F0B04fD21662454A2427F4257A#code)
* Pool — [`0xbbcec987E4C189FCbAB0a2534c77b3ba89229F11`](https://lineascan.build/address/0xbbcec987E4C189FCbAB0a2534c77b3ba89229F11#code)

### Arbitrum (42161)

* SwapERC20 — [`0xD82E10B9A4107939e55fCCa9B53A9ede6CF2fC46`](https://arbiscan.io/address/0xD82E10B9A4107939e55fCCa9B53A9ede6CF2fC46#code)
* Swap — [`0x01b28Aa66a54c6F2bE5C2eF905A2329270CCa96F`](https://arbiscan.io/address/0x01b28Aa66a54c6F2bE5C2eF905A2329270CCa96F#code)
* Wrapper — [`0x88d0D1a1472307d1853809C3aA455B1B76c9bCfe`](https://arbiscan.io/address/0x88d0D1a1472307d1853809C3aA455B1B76c9bCfe#code)
* Registry — [`0xe30E9c001dEFb5F0B04fD21662454A2427F4257A`](https://arbiscan.io/address/0xe30E9c001dEFb5F0B04fD21662454A2427F4257A#code)
* Pool — [`0xbbcec987E4C189FCbAB0a2534c77b3ba89229F11`](https://arbiscan.io/address/0xbbcec987E4C189FCbAB0a2534c77b3ba89229F11#code)

### Avalanche (43114)

* SwapERC20 — [`0xD82E10B9A4107939e55fCCa9B53A9ede6CF2fC46`](https://snowtrace.io/address/0xD82E10B9A4107939e55fCCa9B53A9ede6CF2fC46#code)
* Swap — [`0x01b28Aa66a54c6F2bE5C2eF905A2329270CCa96F`](https://snowtrace.io/address/0x01b28Aa66a54c6F2bE5C2eF905A2329270CCa96F#code)
* Wrapper — [`0x88d0D1a1472307d1853809C3aA455B1B76c9bCfe`](https://snowtrace.io/address/0x88d0D1a1472307d1853809C3aA455B1B76c9bCfe#code)
* Registry — [`0xe30E9c001dEFb5F0B04fD21662454A2427F4257A`](https://snowtrace.io/address/0xe30E9c001dEFb5F0B04fD21662454A2427F4257A#code)
* Pool — [`0xbbcec987E4C189FCbAB0a2534c77b3ba89229F11`](https://snowtrace.io/address/0xbbcec987E4C189FCbAB0a2534c77b3ba89229F11#code)

### Base (8453)

* SwapERC20 — [`0xD82E10B9A4107939e55fCCa9B53A9ede6CF2fC46`](https://basescan.org/address/0xD82E10B9A4107939e55fCCa9B53A9ede6CF2fC46#code)
* Swap — [`0x01b28Aa66a54c6F2bE5C2eF905A2329270CCa96F`](https://basescan.org/address/0x01b28Aa66a54c6F2bE5C2eF905A2329270CCa96F#code)
* Wrapper — [`0x88d0D1a1472307d1853809C3aA455B1B76c9bCfe`](https://basescan.org/address/0x88d0D1a1472307d1853809C3aA455B1B76c9bCfe#code)
* Registry — [`0xe30E9c001dEFb5F0B04fD21662454A2427F4257A`](https://basescan.org/address/0xe30E9c001dEFb5F0B04fD21662454A2427F4257A#code)
* Pool — [`0xbbcec987E4C189FCbAB0a2534c77b3ba89229F11`](https://basescan.org/address/0xbbcec987E4C189FCbAB0a2534c77b3ba89229F11#code)

### Telos (40)

* Wrapper — [`0x88d0D1a1472307d1853809C3aA455B1B76c9bCfe`](https://teloscan.io/address/0x88d0D1a1472307d1853809C3aA455B1B76c9bCfe#code)
* Pool — [`0xbbcec987E4C189FCbAB0a2534c77b3ba89229F11`](https://teloscan.io/address/0xbbcec987E4C189FCbAB0a2534c77b3ba89229F11#code)

### RSK (30)

* Wrapper — [`0x88d0D1a1472307d1853809C3aA455B1B76c9bCfe`](https://rootstock.blockscout.com/address/0x88d0D1a1472307d1853809C3aA455B1B76c9bCfe#code)
* Pool — [`0xbbcec987E4C189FCbAB0a2534c77b3ba89229F11`](https://rootstock.blockscout.com/address/0xbbcec987E4C189FCbAB0a2534c77b3ba89229F11#code)

## AirSwap V5.0: Testnets

### Sepolia (11155111)

* SwapERC20 — [`0xD82E10B9A4107939e55fCCa9B53A9ede6CF2fC46`](https://sepolia.etherscan.io/address/0xD82E10B9A4107939e55fCCa9B53A9ede6CF2fC46#code)
* Swap — [`0x01b28Aa66a54c6F2bE5C2eF905A2329270CCa96F`](https://sepolia.etherscan.io/address/0x01b28Aa66a54c6F2bE5C2eF905A2329270CCa96F#code)
* Wrapper — [`0x88d0D1a1472307d1853809C3aA455B1B76c9bCfe`](https://sepolia.etherscan.io/address/0x88d0D1a1472307d1853809C3aA455B1B76c9bCfe#code)
* Registry — [`0xe30E9c001dEFb5F0B04fD21662454A2427F4257A`](https://sepolia.etherscan.io/address/0xe30E9c001dEFb5F0B04fD21662454A2427F4257A#code)
* Pool — [`0xbbcec987E4C189FCbAB0a2534c77b3ba89229F11`](https://sepolia.etherscan.io/address/0xbbcec987E4C189FCbAB0a2534c77b3ba89229F11#code)
* Staking — [`0x8Bf384296A009723435aD5E8203DA5736b895038`](https://sepolia.etherscan.io/address/0x8Bf384296A009723435aD5E8203DA5736b895038#code)
* Delegate — [`0x35010796699e5c2C9C002F550756A1548921d503`](https://sepolia.etherscan.io/address/0x35010796699e5c2C9C002F550756A1548921d503#code)

### Holesky (17000)

* SwapERC20 — [`0xD82E10B9A4107939e55fCCa9B53A9ede6CF2fC46`](https://holesky.etherscan.io/address/0xD82E10B9A4107939e55fCCa9B53A9ede6CF2fC46#code)
* Swap — [`0x01b28Aa66a54c6F2bE5C2eF905A2329270CCa96F`](https://holesky.etherscan.io/address/0x01b28Aa66a54c6F2bE5C2eF905A2329270CCa96F#code)
* Wrapper — [`0xCF8EbAd621778b3Ea973Dd12a15b6c90bC14bD3C`](https://holesky.etherscan.io/address/0xCF8EbAd621778b3Ea973Dd12a15b6c90bC14bD3C#code)
* Registry — [`0xe30E9c001dEFb5F0B04fD21662454A2427F4257A`](https://holesky.etherscan.io/address/0xe30E9c001dEFb5F0B04fD21662454A2427F4257A#code)
* Pool — [`0xbbcec987E4C189FCbAB0a2534c77b3ba89229F11`](https://holesky.etherscan.io/address/0xbbcec987E4C189FCbAB0a2534c77b3ba89229F11#code)
* Staking — [`0x8Bf384296A009723435aD5E8203DA5736b895038`](https://holesky.etherscan.io/address/0x8Bf384296A009723435aD5E8203DA5736b895038#code)

### BSC Testnet (97)

* SwapERC20 — [`0xD82E10B9A4107939e55fCCa9B53A9ede6CF2fC46`](https://testnet.bscscan.com/address/0xD82E10B9A4107939e55fCCa9B53A9ede6CF2fC46#code)
* Swap — [`0x01b28Aa66a54c6F2bE5C2eF905A2329270CCa96F`](https://testnet.bscscan.com/address/0x01b28Aa66a54c6F2bE5C2eF905A2329270CCa96F#code)
* Wrapper — [`0x88d0D1a1472307d1853809C3aA455B1B76c9bCfe`](https://testnet.bscscan.com/address/0x88d0D1a1472307d1853809C3aA455B1B76c9bCfe#code)
* Registry — [`0xe30E9c001dEFb5F0B04fD21662454A2427F4257A`](https://testnet.bscscan.com/address/0xe30E9c001dEFb5F0B04fD21662454A2427F4257A#code)
* Pool — [`0xbbcec987E4C189FCbAB0a2534c77b3ba89229F11`](https://testnet.bscscan.com/address/0xbbcec987E4C189FCbAB0a2534c77b3ba89229F11#code)

### Mumbai Testnet (80001)

* SwapERC20 — [`0xD82E10B9A4107939e55fCCa9B53A9ede6CF2fC46`](https://mumbai.polygonscan.com/address/0xD82E10B9A4107939e55fCCa9B53A9ede6CF2fC46#code)
* Swap — [`0x01b28Aa66a54c6F2bE5C2eF905A2329270CCa96F`](https://mumbai.polygonscan.com/address/0x01b28Aa66a54c6F2bE5C2eF905A2329270CCa96F#code)
* Wrapper — [`0x88d0D1a1472307d1853809C3aA455B1B76c9bCfe`](https://mumbai.polygonscan.com/address/0x88d0D1a1472307d1853809C3aA455B1B76c9bCfe#code)
* Registry — [`0xe30E9c001dEFb5F0B04fD21662454A2427F4257A`](https://mumbai.polygonscan.com/address/0xe30E9c001dEFb5F0B04fD21662454A2427F4257A#code)
* Pool — [`0xbbcec987E4C189FCbAB0a2534c77b3ba89229F11`](https://mumbai.polygonscan.com/address/0xbbcec987E4C189FCbAB0a2534c77b3ba89229F11#code)

### Linea Goerli (59140)

* SwapERC20 — [`0xD82E10B9A4107939e55fCCa9B53A9ede6CF2fC46`](https://goerli.lineascan.build/address/0xD82E10B9A4107939e55fCCa9B53A9ede6CF2fC46#code)
* Swap — [`0x01b28Aa66a54c6F2bE5C2eF905A2329270CCa96F`](https://goerli.lineascan.build/address/0x01b28Aa66a54c6F2bE5C2eF905A2329270CCa96F#code)
* Wrapper — [`0x88d0D1a1472307d1853809C3aA455B1B76c9bCfe`](https://goerli.lineascan.build/address/0x88d0D1a1472307d1853809C3aA455B1B76c9bCfe#code)
* Registry — [`0xe30E9c001dEFb5F0B04fD21662454A2427F4257A`](https://goerli.lineascan.build/address/0xe30E9c001dEFb5F0B04fD21662454A2427F4257A#code)
* Pool — [`0xbbcec987E4C189FCbAB0a2534c77b3ba89229F11`](https://goerli.lineascan.build/address/0xbbcec987E4C189FCbAB0a2534c77b3ba89229F11#code)

### Arbitrum Sepolia (421614)

* SwapERC20 — [`0xD82E10B9A4107939e55fCCa9B53A9ede6CF2fC46`](https://sepolia.arbiscan.io/address/0xD82E10B9A4107939e55fCCa9B53A9ede6CF2fC46#code)
* Swap — [`0x01b28Aa66a54c6F2bE5C2eF905A2329270CCa96F`](https://sepolia.arbiscan.io/address/0x01b28Aa66a54c6F2bE5C2eF905A2329270CCa96F#code)
* Registry — [`0xe30E9c001dEFb5F0B04fD21662454A2427F4257A`](https://sepolia.arbiscan.io/address/0xe30E9c001dEFb5F0B04fD21662454A2427F4257A#code)

### Fuji Testnet (43113)

* SwapERC20 — [`0xD82E10B9A4107939e55fCCa9B53A9ede6CF2fC46`](https://testnet.snowtrace.io/address/0xD82E10B9A4107939e55fCCa9B53A9ede6CF2fC46#code)
* Swap — [`0x01b28Aa66a54c6F2bE5C2eF905A2329270CCa96F`](https://testnet.snowtrace.io/address/0x01b28Aa66a54c6F2bE5C2eF905A2329270CCa96F#code)
* Wrapper — [`0x88d0D1a1472307d1853809C3aA455B1B76c9bCfe`](https://testnet.snowtrace.io/address/0x88d0D1a1472307d1853809C3aA455B1B76c9bCfe#code)
* Registry — [`0xe30E9c001dEFb5F0B04fD21662454A2427F4257A`](https://testnet.snowtrace.io/address/0xe30E9c001dEFb5F0B04fD21662454A2427F4257A#code)
* Pool — [`0xbbcec987E4C189FCbAB0a2534c77b3ba89229F11`](https://testnet.snowtrace.io/address/0xbbcec987E4C189FCbAB0a2534c77b3ba89229F11#code)

### Base Sepolia (84532)

* SwapERC20 — [`0xD82E10B9A4107939e55fCCa9B53A9ede6CF2fC46`](https://sepolia.basescan.org/address/0xD82E10B9A4107939e55fCCa9B53A9ede6CF2fC46#code)
* Swap — [`0x01b28Aa66a54c6F2bE5C2eF905A2329270CCa96F`](https://sepolia.basescan.org/address/0x01b28Aa66a54c6F2bE5C2eF905A2329270CCa96F#code)
* Registry — [`0xe30E9c001dEFb5F0B04fD21662454A2427F4257A`](https://sepolia.basescan.org/address/0xe30E9c001dEFb5F0B04fD21662454A2427F4257A#code)

### Telos Testnet (41)

* Swap — [`0x01b28Aa66a54c6F2bE5C2eF905A2329270CCa96F`](https://testnet.teloscan.io/address/0x01b28Aa66a54c6F2bE5C2eF905A2329270CCa96F#code)
* Wrapper — [`0x88d0D1a1472307d1853809C3aA455B1B76c9bCfe`](https://testnet.teloscan.io/address/0x88d0D1a1472307d1853809C3aA455B1B76c9bCfe#code)
* Registry — [`0xe30E9c001dEFb5F0B04fD21662454A2427F4257A`](https://testnet.teloscan.io/address/0xe30E9c001dEFb5F0B04fD21662454A2427F4257A#code)
* Pool — [`0xbbcec987E4C189FCbAB0a2534c77b3ba89229F11`](https://testnet.teloscan.io/address/0xbbcec987E4C189FCbAB0a2534c77b3ba89229F11#code)

### RSK Testnet (31)

* Swap — [`0x01b28Aa66a54c6F2bE5C2eF905A2329270CCa96F`](https://rootstock-testnet.blockscout.com/address/0x01b28Aa66a54c6F2bE5C2eF905A2329270CCa96F#code)
* Wrapper — [`0x88d0D1a1472307d1853809C3aA455B1B76c9bCfe`](https://rootstock-testnet.blockscout.com/address/0x88d0D1a1472307d1853809C3aA455B1B76c9bCfe#code)
* Registry — [`0xe30E9c001dEFb5F0B04fD21662454A2427F4257A`](https://rootstock-testnet.blockscout.com/address/0xe30E9c001dEFb5F0B04fD21662454A2427F4257A#code)
* Pool — [`0xbbcec987E4C189FCbAB0a2534c77b3ba89229F11`](https://rootstock-testnet.blockscout.com/address/0xbbcec987E4C189FCbAB0a2534c77b3ba89229F11#code)

## Legacy

### AirSwap V4

* AirSwap V4: SwapERC20 (1) — [`0xd82FA167727a4dc6D6F55830A2c47aBbB4b3a0F8`](https://etherscan.io/address/0xd82FA167727a4dc6D6F55830A2c47aBbB4b3a0F8#code)
* AirSwap V4: SwapERC20 (56) — [`0xd82FA167727a4dc6D6F55830A2c47aBbB4b3a0F8`](https://bscscan.com/address/0xd82FA167727a4dc6D6F55830A2c47aBbB4b3a0F8#code)
* AirSwap V4: SwapERC20 (137) — [`0xd82FA167727a4dc6D6F55830A2c47aBbB4b3a0F8`](https://polygonscan.com/address/0xd82FA167727a4dc6D6F55830A2c47aBbB4b3a0F8#code)
* AirSwap V4: SwapERC20 (43114) — [`0xd82FA167727a4dc6D6F55830A2c47aBbB4b3a0F8`](https://snowtrace.io/address/0xd82FA167727a4dc6D6F55830A2c47aBbB4b3a0F8#code)
* AirSwap V4: Staking (1) — [`0x9fc450F9AfE2833Eb44f9A1369Ab3678D3929860`](https://etherscan.io/address/0x9fc450F9AfE2833Eb44f9A1369Ab3678D3929860#code)

### AirSwap V3

* AirSwap V3: Swap (1) — [`0x522d6f36c95a1b6509a14272c17747bbb582f2a6`](https://etherscan.io/address/0x522d6f36c95a1b6509a14272c17747bbb582f2a6#code)
* AirSwap V3: Swap (56) — [`0x132f13c3896eab218762b9e46f55c9c478905849`](https://bscscan.com/address/0x132f13c3896eab218762b9e46f55c9c478905849#code)
* AirSwap V3: Swap (137) — [`0x6713c23261c8a9b7d84dd6114e78d9a7b9863c1a`](https://polygonscan.com/address/0x6713c23261c8a9b7d84dd6114e78d9a7b9863c1a#code)
* AirSwap V3: Swap (43114) — [`0xec08261ac8b3d2164d236bd499def9f82ba9d13f`](https://snowtrace.io/address/0xec08261ac8b3d2164d236bd499def9f82ba9d13f#code)
* AirSwap V3: Staking (1) — [`0x6d88B09805b90dad911E5C5A512eEDd984D6860B`](https://etherscan.io/address/0x6d88B09805b90dad911E5C5A512eEDd984D6860B#code)
* AirSwap V3: Registry (1) — [`0x8F9DA6d38939411340b19401E8c54Ea1f51B8f95`](https://etherscan.io/address/0x8F9DA6d38939411340b19401E8c54Ea1f51B8f95#code)
* AirSwap V3: Registry (56) — [`0x9F11691FA842856E44586380b27Ac331ab7De93d`](https://bscscan.com/address/0x9F11691FA842856E44586380b27Ac331ab7De93d#code)
* AirSwap V3: Registry (137) — [`0x9F11691FA842856E44586380b27Ac331ab7De93d`](https://polygonscan.com/address/0x9F11691FA842856E44586380b27Ac331ab7De93d#code)
* AirSwap V3: Registry (43114) — [`0xE40feb39fcb941A633deC965Abc9921b3FE962b2`](https://snowtrace.io/address/0xE40feb39fcb941A633deC965Abc9921b3FE962b2#code)

### AirSwap V2

* AirSwap V2: Swap — [`0x4572f2554421Bd64Bef1c22c8a81840E8D496BeA`](https://etherscan.io/address/0x4572f2554421Bd64Bef1c22c8a81840E8D496BeA#code)
* AirSwap V2: Staking [`0x579120871266ccd8de6c85ef59e2ff6743e7cd15`](https://etherscan.io/address/0x579120871266ccd8de6c85ef59e2ff6743e7cd15#code)
* AirSwap V2: Staking (Legacy) [`0xa4C5107184a88D4B324Dd10D98a11dd8037823Fe`](https://etherscan.io/address/0xa4C5107184a88D4B324Dd10D98a11dd8037823Fe#code)
* AirSwap V2: Staking (Deprecated) [`0x704c5818b574358dfb5225563852639151a943ec`](https://etherscan.io/address/0x704c5818b574358dfb5225563852639151a943ec#code)

## Security Audits

* [AirSwap V4.3: SwapERC20, Swap, Staking, Registry](https://github.com/peckshield/publications/blob/master/audit_reports/PeckShield-Audit-Report-AirSwap-v1.0.2.pdf)
* [AirSwap V4.1: SwapERC20, Pool](https://github.com/peckshield/publications/blob/master/audit_reports/PeckShield-Audit-Report-AirswapV4-SwapERC20-v1.0.pdf)
* [AirSwap V4.1: Pool, Registry](https://github.com/peckshield/publications/blob/master/audit_reports/PeckShield-Audit-Report-AirswapV4-PoolRegistry-v1.0.pdf)
* [AirSwap V4: SwapERC20, Swap, Wrapper](https://github.com/peckshield/publications/blob/master/audit_reports/PeckShield-Audit-Report-AirswapV4-v1.0.pdf)
* [AirSwap V4: Staking, Registry](https://github.com/peckshield/publications/tree/master/audit_reports/PeckShield-Audit-Report-AirSwap-Staking-v1.0.pdf)
* [AirSwap V3: Pool](https://github.com/peckshield/publications/blob/master/audit_reports/PeckShield-Audit-Report-AirSwap-v1.0.pdf)


# Conduct

Code of conduct

[AirSwap](https://www.airswap.xyz) is a DAO focused on decentralized trading systems. Anyone can join, contribute, and earn as a member of our development community. Everything we build is aligned with our mission and generally measured by positive impact on network health and trading volume.

We continuously create a respectful environment where people want to come, stay, and participate over the long term.

The following code of conduct extends the [Berlin Code of Conduct](https://berlincodeofconduct.org).

* **Collaborate rather than compete.** Add energy by working together, building on each other's ideas, and give without expectations. Pay it forward. Put ideas into action.
* **Discuss rather than campaign.** The best ideas are developed through iteration by openly discussing, integrating, and updating as you learn.
* **Be an ally; not an adversary.** Be patient and allow others time to listen and speak. Interact as if you’re face to face. Support other ideas as best you can.

We all work together toward community goals. AirSwap is a positive-sum project with long-term vision. Short-term, extractive behavior is not tolerated.

#### Rules

* **No price talk.** Speculation is detrimental and counterproductive to our mission. Do not talk about price. Keep discussions about building, growing, and governing AirSwap.
* **Respect each other.** This community is built by people across the globe from many walks of life with many perspectives. Honor that diversity; it gives us strength.
* **Win together.** As members of the AirSwap community, we each share common goals and all share the opportunity to contribute and help AirSwap succeed.

### Principles

Decentralized governance starts with shared principles to align our decisions.

1. **Design for simplicity** — Perfection is achieved when there is nothing left to take away. This is especially true with blockchain based technology and applications.
2. **Prioritize security** — Our work is done in an adversarial setting. While blockchain requires users to take security into their own hands, they trust AirSwap to be designed and to operate in a secure way.
3. **Decide with data** — Drive decisions with data that matters. AirSwap performance indicators are trading volume, token holders, community engagement, and tokens used for governance.
4. **Seek opportunity** — Decentralized finance is abundant with opportunities. Seek and prioritize opportunities that positively impact both AirSwap and the broader ecosystem.
5. **Win together** — Our community spans platforms across cyberspace and countries across the globe. We grow by both sharing responsibility and celebrating each success.


# Earning

Learn how community members earn by contributing to AirSwap

Protocol fees on AirSwap support development, growth, and upkeep of AirSwap protocols and apps. Protocol fees are routed to two destinations: a contributor tips pool and a voter rewards pool. This guide explains the system and how you can earn for helping to operate it.

## Contributor Tips

Each month, a contributions thread is opened on [Discord](https://discord.gg/Pc6gV3hFjR). Communicating your contributions is part of your responsibility as a contributor—help your fellow contributors by clearly stating what you have achieved for the month.

{% hint style="warning" %}
If you have not contributed for the month, always **opt-out** of receiving GIVE for that epoch. Anyone who did not describe their contributions or opt out will be removed from the circle and will have to be re-nominated for future rounds.
{% endhint %}

[Coordinape](https://coordinape.com) epochs are 1-6 of each month to allocate GIVE tokens among fellow contributors based on impact. Individual contributors earn proportionally to GIVE received. In case of a shortfall in protocol fees against the monthly minimum ($30K) then AST is requested from `treasury.airswap.eth`.

{% hint style="warning" %}
The allocation system is fully transparent. Allocate fairly and honestly!
{% endhint %}

## Voter Rewards

At the end of each voting period, a number of points is awarded based on the number of staked AST used to vote on proposals. Points enable you to claim a percentage of the rewards pool based on the formula

$$
R = B \* (P / (10^S +P )) \* M/100
$$

where R is the rewards you can obtain, P is the number of points used to claim (multiplied by 10^4), B is the token balance in the rewards pool, S and M are community adjustable parameters (currently set to S = 10 and M = 100). The formula results in rewards being distributed on a smooth curve based on the number of points used to claim.

![Rewards are distributed on a curve based on the number of points](/files/-MlFxlAoVBuJgF3FiMVO)

## Trustless Operations

Protocol fees transfer from Swap and SwapERC20 contracts to a [Split](https://docs.splits.org/core/split) contract, which distributes balances to the rewards pool and contributor tips [Swapper](https://docs.splits.org/core/swapper) contract, which converts various token balances into a single token.

{% hint style="warning" %}
Rewards and tips do not top up until a withdrawal is performed by a community member—so keep an eye on the split balances if you’d like to help out.
{% endhint %}

* **Earn a 1% reward** to perform distributions and withdrawals on the [Split](https://app.0xsplits.xyz/accounts/0xaD30f7EEBD9Bd5150a256F47DA41d4403033CdF0/) contract. Anyone can trigger these anytime by clicking "Distribute & withdraw for all" button.
* **Earn a 1% reward** to perform conversions on the [Swapper](https://app.splits.org/accounts/0x8a14D4a671fBe267844B08D9748eD946348aEbFD/) contract. Anyone can trigger these anytime by clicking the "Swap" button.

{% hint style="info" %}
In both cases, scripts or bots are often developed to perform these actions and earn rewards in an automated way while supporting the trustless operations of AirSwap.
{% endhint %}


# Proposals

Learn how AirSwap continuously upgrades itself through the community

AirSwap is organized as a decentralized network of contributors using a steering process called [AirSwap Improvement Proposals (AIP)](https://github.com/airswap/AIPs/issues/1). Some projects are best presented as AirSwap Improvement Proposals (AIPs) to garner community support. This doesn’t necessarily mean that it’ll be built—that’s up to contributors and based on expected project impact.

Good project proposals…

* **Make a "business case"** for dedicating resources to a project. This could mean identifying a new customer segment or estimating a positive impact on trading volume.
* **Specify a rough project scope** of X taking a rough time of Y to complete without going deep into product details—actual specs can be drafted in parallel or after a vote.
* **Present a clear benefit** to AirSwap. After all, what we work on benefits us and our community. We ultimately build together with and for our fellow contributors.

Some projects are proposed as AIPs…

* Proposals that **request AST from the treasury** must be proposed as an AIP for community vote and if passed will execute on the project multi-signature wallet.
* Proposals that **specify or update parameters** or other configurations that impact the functioning of the DAO or compensation structures.
* Proposals that **would benefit from community support** as a way to signal importance and impact to potential contributors or the community at large.

Each proposal is authored by one or more authors. The AIP is ratified as a community proposal once it is called to vote and accepted by token holders. Once accepted, the AIP is placed in a backlog for selection by developers. Developers select proposals for prioritization and implementation based on their requirements and feasibility. Once complete, ambassadors help to deliver projects and bring awareness to a wider audience.

Several incentives to participate are built in. Every month…

* **Votes are run** for four days on one or more proposals.
* **Rewards are distributed** to contributors for work completed.

{% hint style="info" %}
See a list of [active projects](https://github.com/orgs/airswap/projects) and proposals [ready to be built](https://github.com/airswap/AIPs/issues).
{% endhint %}


# Glossary

## Digital Tokens

**Digital tokens are ownable assets** implemented as [smart contracts](https://ethereum.org/en/smart-contracts/) with internal ledgers and standard interfaces to transfer balances among holders. Tokens are either fungible (each unit is interchangeable) or non-fungible (each unit is unique). Standards include ERC20, ERC777 for fungible and ERC721 and ERC1155 for non-fungible tokens (NFT).

Digital tokens can represent both purely digital assets and real-world assets.

## Decentralized Exchange

**Exchanges have evolved over millennia.** Many involve a centralized venue or entity to coordinate trades. [Limit order books](https://www.investopedia.com/terms/l/limitorderbook.asp), with a digital "book" of bids (buy orders) and asks (sell orders), run high-performance centralized matching engines. These engines are carefully managed and regulated to protect market participants.

**With pseudonymous public ledgers** like Bitcoin and Ethereum came international centralized exchanges without the same management and regulation standards, introducing risk into a system that intended to put power into the hands of participants rather than trusted intermediaries that can be mismanaged, hacked, or broken.

**Early decentralized exchanges failed** because they attempted to replicate the order book model, which is fundamentally centralized. What we’ve since found is that decentralized models that perform well are either peer-to-peer (e.g. [AirSwap](https://airswap.xyz/)) or peer-to-contract (e.g. [Uniswap](https://uniswap.org/)).

## Atomic Swaps

**In database systems** an atomic transaction is an indivisible and irreducible series of operations such that either all occur or none occur. This concept of atomicity translates to smart contracts programmed to perform multiple digital token transfers in a single transaction. This enables multiple assets held by multiple parties to change hands without the risk of any party not receiving his or her funds. Atomic swaps are the core of P2P systems like AirSwap.

## Makers and Takers

**Makers provide prices and "make" a market.** On order books, makers continuously create and cancel bids and asks around market price and profit from the "spread" between the two. On P2P systems, makers are generally online and available to offer prices to other participants.

**Takers accept prices and "take" a market.** On order books, takers execute market buys or sells against existing orders created by makers. On P2P systems, takers come online when they intend to make a trade and connect to available makers to fetch pricing data.

## Slippage and Front-running

**Slippage occurs when** a trade executes differently than the expected price. This is caused by other orders being executed ahead of the submitted order. [Slippage](https://www.investopedia.com/terms/s/slippage.asp) can be to either the detriment or benefit of a trader, depending on which direction it occurs. Slippage is commonplace in all continuous markets, that is, a market where the previous order impacts the price of the next. Slippage is avoidable in P2P systems, which are not continuous.

**Front-running occurs when** a third-party sees an order before it is executed and takes advantage of this information to submit an order of its own to be executed first. [Front-running](https://www.investopedia.com/terms/f/frontrunning.asp) is prohibited in traditional markets. In the land of pseudonymous public ledgers, front-running is commonplace and a fundamental part of on-chain continuous markets through the practice of [MEV](https://ethereum.org/en/developers/docs/mev/). Front-running can also be avoided in P2P systems because they are not continuous.

## Peer-to-Peer (P2P) Swaps

Peer-to-peer token swaps are enabled by an "atomic" transaction in which both sides succeed or the transaction reverts. Pricing is communicated off-chain before executing on-chain. These transactions do not require intermediaries or escrow and are therefore "trustless".

At the protocol level, there are **signers**, which cryptographically sign terms (an order), and **senders** which submit those terms for settlement on the atomic swap contract. Different market participants may take the role of signer or sender depending on the flavor of P2P.

[AirSwap](https://airswap.xyz/) is the original peer-to-peer swaps protocol.

*Strengths*

* No front-running, slippage, or market manipulation.
* Makers run customized high performance pricing strategies.
* Takers interface directly with makers in real-time.
* Low execution costs due to simplicity.

*Limitations*

* Usually requires a maker to be online and available for pricing.
* Makers must program and operate their own pricing strategies.

## Over the Counter (OTC)

**Over-the-counter (OTC) is a form of P2P Swaps** among known counterparties who communicate prices to each other via e.g. chat apps or email and use an atomic swap for settlement. OTC has all the benefits of its underlying P2P Swap protocol.

*Protocol*

1. Bob asks Alice for a price.
2. Alice signs and gives Bob a priced order.
3. Bob sends the order to the Swap contract.

![](/files/XS7DcQW5wBBL06lWUB03)

## Request for Quote (RFQ)

**Request-for-quote (RFQ) is a form of P2P Swaps** among clients and servers on the Internet. RFQ is an automated request-response protocol for market makers running web servers from which clients request orders via HTTP or WebSocket.

*Features*

* Servers are run by makers and clients by takers.
* Servers are signers and clients are senders.
* Clients have the option to accept an order.
* Clients are guaranteed the price until expiry.
* Clients pay for execution.

*Protocol*

1. Server sets URL on the Registry and adds supported tokens.
2. Client queries the Registry for URLs by token.
3. Client sends each Server a web request to swap two tokens.
4. Each Server responds with a signed order including price.
5. Client sends the best order to the Swap contract.

![](/files/aOxoCI0XTzrMAtowbh93)

## LastLook (LL)

**LastLook (LL) is a form of P2P Swaps** among clients and servers on the Internet. LL is an automated streaming protocol that allows servers to stream pricing updates to clients via WebSocket, which in turn sign and transmit orders back to the server.

*Features*

* Servers are run by makers and clients by takers.
* Clients are signers and servers are senders.
* Clients stream real-time pricing from servers.
* Servers have the option to accept an order.
* Servers pay for execution.

*Protocol*

1. Server sets URL on the Registry and adds supported tokens.
2. Client queries the Registry for URLs by token.
3. Client connects to each server and subscribes to the pricing stream.
4. Client signs and transmits an order to the server using server pricing.
5. Server sends the order to the Swap contract.

![](/files/aVetPolqzHnCQaglUTI6)

## Peer-to-Contract (P2C) Swaps

Peer-to-contract token swaps are enabled by on-chain "automated market makers" (AMM), which determine price during on-chain execution based on a constant product formula. These transactions are without intermediaries and involve one party depositing "liquidity" and another party later taking it.

Makers in this case are "liquidity providers" who may make adjustments to their positions by depositing to and configuring the AMM. Takers simply execute a swap transaction on the AMM contract frontend often through an easy to use web app.

[Uniswap](https://uniswap.org/) is the original peer-to-contract swaps protocol.

*Strengths*

* Depositing and swapping against the AMM are easy.
* Does not require makers to be online and available for pricing.

*Limitations*

* Makers have limited ability to customize pricing strategies.
* Front-running and market manipulation are possible.
* Higher execution costs due to heavier swap logic.


# Resources

For smart contract addresses see [Deployments](/technology/deployments).

## Social Media

* [Discord](https://discord.gg/Pc6gV3hFjR)
* [Telegram](https://t.me/airswapofficial)
* [Twitter](https://x.com/airswap)

{% hint style="info" %}
Know some other channels which could be useful for community building? Do drop by our [Discord](https://discord.gg/Pc6gV3hFjR) to let us know how else we can reach out to the community!
{% endhint %}

## Governance

* [AirSwap Improvement Protocols (AIPs)](https://github.com/airswap/airswap-aips/issues)
* [Member Dashboard](https://dao.airswap.eth.limo/)
* [Snapshot Page](https://snapshot.org/#/vote.airswap.eth)

## Code

* [AirSwap Protocols](https://github.com/airswap/airswap-protocols)
* [AirSwap Web](https://github.com/airswap/airswap-web)
* [AirSwap CLI](https://github.com/airswap/airswap-cli)
* [About AirSwap](https://github.com/airswap/airswap-about)

## Analytics

* [AirSwap Dashboard](https://analytics.airswap.xyz/)

## Media Kit

* [Download AirSwap Brand Assets](https://github.com/airswap/airswap-about/blob/master/.gitbook/assets/AirSwap_Brand_Assets.zip)


# FAQ

## Protocols

### Why use AirSwap?

AirSwap has a number of benefits.

* Non-custodial. Unlike a centralized exchange, AirSwap does not take custody of funds.
* No sign-ups. AirSwap does not require users to sign up and does not collect sensitive data.
* No slippage. On AirSwap, prices are exact so the price you see is the price you get.
* Intuitive. AirSwap is designed with UX as a top priority.
* Secure. AirSwap was rated the #1 safest Ethereum decentralized exchange.

Learn more about AirSwap's benefits in the blog post [Why AirSwap?](https://medium.com/fluidity/why-airswap-62ff8b4ee81d)

### How is AirSwap different from Uniswap?

Uniswap is a "peer-to-contract" automated market maker (AMM) that runs fully on-chain. AirSwap is a peer-to-peer network combining off-chain negotiation and on-chain settlement by atomic swap.

There are benefits to each. With AirSwap there is no price slippage and trades are unlimited in size. The trade-off is that it's easier for everyday users to provide liquidity to Uniswap. However, a successful outcome for RFQ is a few high quality liquidity providers covering a variety of digital assets, so AirSwap does not require the same number of liquidity providers to be successful.

### Is AirSwap available on other chains?

AirSwap [RFQ ](/technology/protocols)is currently available through Metamask swaps on BSC. We are currently working on bringing AirSwap swaps to a [chain near you](https://github.com/airswap/airswap-aips/issues/49). Stay tuned...

## Governance

### Why Stake on AirSwap?

AirSwap Tokens (AST) can be staked to participate in governance of the protocol. All are welcome to participate by proposing, discussing, and voting on proposals that move the project and community forward. Voters earn points based on the amount staked. Points can be used to claim a portion of the funds from the rewards pool.

### How do I stake on AirSwap?

You can stake your AST on the [Member Dashboard](https://dao.airswap.eth.limo/).

### What are the rules of staking?

Staked tokens are unlocked over a 20 week period with a 4 week initial cliff. This means that you may not unstake any tokens during the first 4 weeks.

### When is the next vote?

Voting occurs every month, from the 1st to the 4th of each month.

### Do my points expire?

No! Points don't expire and will be carried over to the next cycle.

### How do I unstake from V1?

This will unlock your AST and transfer it to your wallet.

1. Visit this URL to determine your balance (replace 0x000 with your wallet address): <https://etherscan.io/token/0xa4C5107184a88D4B324Dd10D98a11dd8037823Fe?a=0x000>
2. Visit this URL, connect your wallet, go to "unlock" and provide your balance amount: <https://etherscan.io/token/0xa4C5107184a88D4B324Dd10D98a11dd8037823Fe#writeContract>

Note: balances have 4 decimals so e.g. 2,500.00 would have an "unlock" amount of 25000000.

## Contributing

### How can I contribute to AirSwap?

There are lots of ways to get involved in AirSwap, from generating ideas, to coordinating projects, contributing design and code, and helping to spread the word.

### How do contributors earn?

Every month, contributors come together to tip each other using[Coordinape](https://coordinape.com). Funds are then distributed pro rata to each member of the circle based on the about of GIVE received. Learn more about [earning](/community/earning).


