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

# IB20.seizeWithMemo

> Moves tokens from a holder to a safekeeping account in a single admin call without changing totalSupply.

## Signature

```solidity IB20.sol theme={null}
function seizeWithMemo(address from, address to, uint256 amount, bytes32 memo) external;
```

| Field               | Value                                            |
| ------------------- | ------------------------------------------------ |
| Selector            | `0xf916d81b`                                     |
| Canonical signature | `seizeWithMemo(address,address,uint256,bytes32)` |

## Description

Moves `amount` from `from` to `to` in a single admin operation. `totalSupply` does not change. Emits, in order, `Transfer(from, to, amount)`, `Memo(caller, memo)`, and `Seized(caller, from, to, amount)`. A memo of `bytes32(0)` is permitted.

This is not a burn and not a mint. After the call, `to` is an ordinary holder and can transfer, burn, or hold the tokens.

Seize skips allowance and the transfer policies (`TRANSFER_SENDER_POLICY`, `TRANSFER_RECEIVER_POLICY`). It uses two dedicated policy scopes instead:

| Scope                   | Account | Passes when                                     |
| ----------------------- | ------- | ----------------------------------------------- |
| `SEIZE_EXEMPT_POLICY`   | `from`  | `isAuthorized` returns `false` (inverted check) |
| `SEIZE_RECEIVER_POLICY` | `to`    | `isAuthorized` returns `true`                   |

`SEIZE_EXEMPT_POLICY` is inverted: when the scope is unset (ID `0`, always-allow), every account is authorized and therefore no account is seizable. Attach a blocklist and add the holder to make them seizable.

`SEIZE_RECEIVER_POLICY` defaults to always-allow when unset, so an unconfigured token accepts any destination.

## Parameters

| Parameter | Type      | Description                                                                     |
| --------- | --------- | ------------------------------------------------------------------------------- |
| `from`    | `address` | Account whose balance is being seized. Must be non-zero and distinct from `to`. |
| `to`      | `address` | Destination for the seized balance. Must be non-zero and distinct from `from`.  |
| `amount`  | `uint256` | Amount to seize. Must not exceed `from`'s balance.                              |
| `memo`    | `bytes32` | Memo payload. `bytes32(0)` is allowed.                                          |

## Reverts

| Error                                                  | Condition                                                                                                |
| ------------------------------------------------------ | -------------------------------------------------------------------------------------------------------- |
| `ContractPaused(SEIZE)`                                | `SEIZE` is paused. Pausing `TRANSFER`, `MINT`, or `BURN` does not block seize.                           |
| `AccessControlUnauthorizedAccount(caller, SEIZE_ROLE)` | Caller does not hold `SEIZE_ROLE`.                                                                       |
| `InvalidReceiver(to)`                                  | `to` is `address(0)`, or `from == to`.                                                                   |
| `InvalidSender(from)`                                  | `from` is `address(0)`.                                                                                  |
| `AccountNotSeizable(from)`                             | `from` is authorized under `SEIZE_EXEMPT_POLICY` (scope unset, or holder not on the attached blocklist). |
| `PolicyForbids(SEIZE_RECEIVER_POLICY, policyId)`       | `to` is not authorized under `SEIZE_RECEIVER_POLICY`.                                                    |
| `InsufficientBalance(from, balance, amount)`           | `from`'s balance is below `amount`.                                                                      |

## Events

Emitted on success, in this order:

1. `Transfer(from, to, amount)`
2. `Memo(caller, memo)`
3. `Seized(caller, from, to, amount)`: topic0: `0xa9aec5d8b86e2fa2fd6ac3af62f2622e3dfdab1967d4cbbb56a5df7d74cb887c`

## Access Control

`SEIZE_ROLE` gates this function. The `SEIZE` pausable feature provides a second switch: a caller holding `SEIZE_ROLE` still cannot seize while `SEIZE` is paused.

## Example

```solidity Usage Example lines wrap expandable highlight={9,19} theme={null}
// Grant the seizer role
token.grantRole(token.SEIZE_ROLE(), seizer);

// Create a blocklist, add the holder, attach it to the holder scope
uint64 seizableId = POLICY_REGISTRY.createPolicy(policyAdmin, IPolicyRegistry.PolicyType.BLOCKLIST);
address[] memory holders = new address[](1);
holders[0] = alice;
POLICY_REGISTRY.updateBlocklist(seizableId, true, holders);
token.updatePolicy(token.SEIZE_EXEMPT_POLICY(), seizableId);

// Optionally restrict destinations
uint64 destId = POLICY_REGISTRY.createPolicy(policyAdmin, IPolicyRegistry.PolicyType.ALLOWLIST);
address[] memory dests = new address[](1);
dests[0] = treasury;
POLICY_REGISTRY.updateAllowlist(destId, true, dests);
token.updatePolicy(token.SEIZE_RECEIVER_POLICY(), destId);

// Execute the seize
token.seizeWithMemo(alice, treasury, amount, keccak256("court-order-123"));
```

<Note>
  `AccountNotSeizable` selector: `0x91dbbc8d`. This error fires when the holder scope is unset or the holder is not on the attached blocklist, not when the holder is on a transfer blocklist. Transfer and seize scopes are independent.
</Note>
