> ## 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.updatePolicy

> Binds a Policy Registry policy ID to a policy scope on a B20 token.

## Signature

```solidity IB20.sol theme={null}
function updatePolicy(bytes32 policyScope, uint64 newPolicyId) external;
```

| Field               | Value                          |
| ------------------- | ------------------------------ |
| Selector            | `0xadf9c4ea`                   |
| Canonical signature | `updatePolicy(bytes32,uint64)` |

## Description

Binds `newPolicyId` to `policyScope`. Takes effect immediately: the next operation that consults that scope calls `isAuthorized(newPolicyId, account)` on the Policy Registry. Emits `PolicyUpdated`.

Until a scope is updated it holds `0` (`ALWAYS_ALLOW`), so the check passes for every address.

## Parameters

| Parameter     | Description                                                                                                           |
| ------------- | --------------------------------------------------------------------------------------------------------------------- |
| `policyScope` | The scope slot to update. Must be a scope this token recognizes.                                                      |
| `newPolicyId` | The policy ID to assign. Must be a built-in sentinel (`ALWAYS_ALLOW`, `ALWAYS_BLOCK`) or an existing registry policy. |

## Reverts

| Error                                | Condition                                                                    |
| ------------------------------------ | ---------------------------------------------------------------------------- |
| `AccessControlUnauthorizedAccount`   | Caller does not hold `DEFAULT_ADMIN_ROLE`.                                   |
| `UnsupportedPolicyType(policyScope)` | `policyScope` is not a slot this token supports.                             |
| `PolicyNotFound(newPolicyId)`        | `newPolicyId` is not a built-in sentinel and does not exist in the registry. |

## Access Control

`DEFAULT_ADMIN_ROLE` gates this call. During token creation, `initCalls` may bind policies in the same transaction; those calls bypass the role gate.

## Policy Scopes

The recognized scopes and the accounts they check are:

| Scope                      | Checked account                                            | Denies when `isAuthorized` is |
| -------------------------- | ---------------------------------------------------------- | ----------------------------- |
| `TRANSFER_SENDER_POLICY`   | `from`                                                     | `false`                       |
| `TRANSFER_RECEIVER_POLICY` | `to`                                                       | `false`                       |
| `TRANSFER_EXECUTOR_POLICY` | `msg.sender` (on `transferFrom` when `msg.sender != from`) | `false`                       |
| `MINT_RECEIVER_POLICY`     | `to`                                                       | `false`                       |
| `SEIZE_EXEMPT_POLICY`      | `from`                                                     | `true`                        |
| `SEIZE_RECEIVER_POLICY`    | `to`                                                       | `false`                       |

Transfer scopes are skipped on factory `initCalls` transfers. `MINT_RECEIVER_POLICY` is always checked, including factory `initCalls` mints. `SEIZE_EXEMPT_POLICY` unset (`ALWAYS_ALLOW`) means no account is seizable.

## Example

```solidity Usage Example theme={null}
IB20(token).updatePolicy(B20Constants.TRANSFER_RECEIVER_POLICY, policyId);
```

The same policy ID can be bound to more than one scope and to more than one token. Updating membership in the registry policy is visible immediately on every scope and token that references it, no second `updatePolicy` call is needed.
