> ## Documentation Index
> Fetch the complete documentation index at: https://docs.rialto.xyz/llms.txt
> Use this file to discover all available pages before exploring further.

# For Liquidators

> Use Rialto as the swap leg inside liquidation and executor contracts.

Permit2 is the preferred flow for swap transactions through Rialto. Contract
signers can also use Permit2 when they implement EIP-1271 signature validation.

For legacy integrations that cannot provide a valid Permit2 signature, Rialto
also supports allowance settlement. For integration instructions, see the
Taker-submitted flow in the [Rialto API docs](https://github.com/rialto-plds/rialto-api-docs/blob/main/RIALTO_SWAP_API.md).

## Contract-based executors

Most liquidation bots execute through an executor or liquidator contract. That
contract may receive the seized collateral, approve a swap router, perform the
swap, and then send the output to the bot, treasury, or another recipient.

The example below shows allowance settlement for executors that cannot provide a
valid Permit2 signature. In this flow, the quote can be executed after the
contract approves the spender returned by Rialto.

For allowance flow, the quote should have:

* `settlement: "allowance"`
* `taker` set to the account or contract that holds and pays the sell token
* `tx.to` set to the active Rialto router
* `tx.data` executable by the executor contract
* `tx.value` set for native-token sells, or `0` for ERC20 sells
* `issues.allowance.spender` set when an ERC20 approval is needed

## Integration flow

1. Detect a liquidatable position.
2. Estimate the collateral amount to sell and the token you want to receive.
3. Call `GET /quote` with the executor contract as the taker.
4. If `issues.balance` is present, do not execute the liquidation.
5. If `issues.allowance` is present, approve the returned spender from the
   executor contract for at least `sell_amount`, preferably within the same
   transaction.
6. Execute `tx.to`, `tx.data`, and `tx.value` from the executor contract.
7. Reset the token allowance to zero after execution, preferably within the same
   transaction.

## Quote request

```bash theme={null}
curl -sS 'https://rialto-trade-api.rialto.xyz/quote?sell_token=WETH&buy_token=USDG&sell_amount=0.01&taker=<executor_contract>&slippage_bps=50&chain_id=4663' \
  -H "Authorization: Bearer $RIALTO_API_KEY"
```

Use the executor contract as `taker` when the executor will hold the sell token
and submit the swap call.

## Response fields to use

```json theme={null}
{
  "settlement": "allowance",
  "sell_token": "<sell_token_address>",
  "buy_token": "<buy_token_address>",
  "sell_amount": "10000000000000000",
  "buy_amount": "19800022",
  "min_buy_amount": "19701021",
  "issues": {
    "allowance": {
      "actual": "0",
      "spender": "<rialto_router_or_spender>"
    },
    "balance": null,
    "simulationIncomplete": false
  },
  "tx": {
    "to": "<rialto_router_address>",
    "data": "0x...",
    "value": "0",
    "estimated_gas": 226046
  }
}
```

For allowance settlement, use `issues.allowance.spender` as the approval target.
Use `tx.to`, `tx.data`, and `tx.value` as the swap call.

Do not recompute the route, fee logic, slippage math, or calldata. The returned
transaction is the integration boundary.

## Executor sketch

```solidity theme={null}
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;

import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";

contract LiquidationExecutor {
    address public owner;

    modifier onlyOwner() {
        require(msg.sender == owner, "not owner");
        _;
    }

    constructor(address _owner) {
        owner = _owner;
    }

    function executeRialtoSwap(
        address sellToken,
        address spender,
        uint256 sellAmount,
        address rialtoRouter,
        bytes calldata rialtoData,
        uint256 value
    ) external payable onlyOwner {
        if (sellToken != address(0)) {
            IERC20(sellToken).approve(spender, sellAmount);
        }

        (bool ok, bytes memory result) = rialtoRouter.call{value: value}(rialtoData);
        if (!ok) {
            assembly {
                revert(add(result, 32), mload(result))
            }
        }

        if (sellToken != address(0)) {
            IERC20(sellToken).approve(spender, 0);
        }
    }
}
```

The executor should already include its liquidation logic, access control,
profit checks, and token recovery functions. The example only shows the swap
boundary.

## Q\&A

### What should the approval lifecycle be?

For allowance settlement, use scoped approvals. Approve only the amount needed
for the input token, execute the swap, then reset the allowance to zero,
preferably within the same transaction.

This reduces exposure from unused or stale allowances, in addition to the
controls Rialto applies on its side.

### What should I do if the quote returns `issues`?

If `issues.balance` is present, do not execute the swap. If `issues.allowance`
is present for allowance settlement, approve the returned spender before
execution.

## Safety checks

Before executing a quote, liquidators should still check:

* expected profit after gas
* `min_buy_amount`
* route freshness
* slippage tolerance
* token balances after liquidation
* allowance reset after execution, for allowance settlement
* whether the returned transaction still simulates successfully

Quotes depend on live liquidity and may become stale quickly. Request a fresh
quote close to execution time.
