Skip to content
254 changes: 254 additions & 0 deletions ERCS/erc-8245.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,254 @@
---
eip: 8245
title: Permissioned Vault Registrar
description: Interface for registering investor-bound protocol vaults under shared compliance identities via EIP-712 signed authorization.
author: Miguel Schneider (@MiguelSchneider)
discussions-to: https://ethereum-magicians.org/t/erc-8245-permissioned-vault-registrar-interface/27627
status: Draft
type: Standards Track
category: ERC
created: 2026-01-30
requires: 20, 712, 1271
---
## Abstract

This ERC introduces a companion contract interface ("Vault Registrar") for permissioned [ERC-20] ecosystems. The interface enables third-party protocols to register investor-bound vault contracts under the investor's compliance identity, using explicit, revocable authorization granted by the investor via [EIP-712] signed permissions.

The ERC is additive to [ERC-20], does not modify the [ERC-20] interface, and intentionally leaves identity and compliance logic implementation-defined.

## Motivation

Many permissioned [ERC-20] tokens (e.g. regulated real-world assets) must maintain investor-level ownership attribution for regulatory compliance, lifecycle events, and corporate actions.

Common DeFi patterns — such as pooled contracts — aggregate balances across investors and obscure beneficial ownership. A widely adopted alternative is investor-bound vaults: protocols deploy a dedicated vault contract per investor, the vault holds and manages the permissioned token on the investor's behalf, and ownership attribution remains tied to the investor.

Today, authorizing such vaults requires bespoke, issuer-specific flows, forcing protocols to implement custom integrations for each permissioned token ecosystem. This ERC standardizes the integration surface between protocols and permissioned-token ecosystems.

## Specification

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 and RFC 8174.

### Overview

A Vault Registrar is a standalone companion contract that permissioned [ERC-20] ecosystems MAY expose. It acts as a policy-enforcing registry. Before registering a vault under an investor's identity, it verifies:

1. The operator (protocol) is authorized.
2. A valid investor permission exists (via [EIP-712] signed authorization).
3. Compliance rules are satisfied.

The high-level flow is as follows:

1. An investor signs an [EIP-712] authorization message granting a protocol permission to register vaults under their identity.
2. The protocol deploys a vault contract for the investor.
3. The protocol calls the Vault Registrar, presenting the signed authorization.
4. The registrar verifies the authorization and compliance rules.
5. If all checks pass, the vault is registered under the investor's identity.

### [EIP-712] Authorization

Vault authorization MUST be explicitly granted by the investor and MUST be revocable. The investor signs a structured [EIP-712] message authorizing a specific operator to register vaults under their identity.

**Domain:**

```
name = "VaultRegistrar"
version = "1"
chainId = <deployment chain>
verifyingContract = <VaultRegistrar address>
```

**Struct:**

```
RegisterVault(
address investor,
address operator,
address token,
uint256 nonce,
uint256 deadline
)
```

**Type hash:**

```
REGISTER_VAULT_TYPEHASH = keccak256(
"RegisterVault(address investor,address operator,address token,uint256 nonce,uint256 deadline)"
)
```

Investors can invalidate all previously granted permissions to an operator on-chain via `invalidateOperatorPermission`, which increments the nonce and renders any outstanding signatures void.

### Interface

```solidity
interface IERC_VaultRegistrar {

/// @notice Emitted when a vault is successfully registered under an investor's identity.
event VaultRegistered(
address indexed investor,
address indexed vault,
address token,
string investorId,
address indexed sender
);

/// @notice Emitted when a vault registration is revoked.
event VaultUnregistered(
address indexed investor,
address indexed vault,
address token,
string investorId,
address indexed sender
);

/// @notice Emitted when an investor invalidates all outstanding permissions for an operator.
event OperatorPermissionInvalidated(
address indexed investor,
address indexed operator,
uint256 newNonce
);

/// @notice Register a vault under an investor's identity.
/// @dev The caller (operator) MUST present a valid EIP-712 signed authorization from the
/// investor. Implementations MUST revert if the authorization is missing, invalid,
/// or revoked, or if compliance checks fail. Intended to be called by authorized
/// protocol contracts as part of an atomic transaction.
/// @param vaultAddress The vault contract address to register.
/// @param investorWalletAddress The investor's wallet address that signed the authorization.
/// @param deadline Unix timestamp after which the signature is invalid.
/// @param signature EIP-712 signed permission from the investor. Supports both
/// EOA (ECDSA) and smart contract wallets (ERC-1271).
function registerVault(
address vaultAddress,
address investorWalletAddress,
uint256 deadline,
bytes calldata signature
) external;

/// @notice Check whether a vault is registered for a given investor.
/// @param vaultAddress The vault contract address.
/// @param investorWalletAddress The investor's wallet address.
/// @return True if the vault is currently registered under the investor's identity.
function isRegistered(
address vaultAddress,
address investorWalletAddress
) external view returns (bool);

/// @notice Revoke the registration of a vault.
/// @param vaultAddress The vault contract address.
/// @param investorWalletAddress The investor's wallet address.
function unregisterVault(
address vaultAddress,
address investorWalletAddress
) external;

/// @notice The permissioned ERC-20 token this registrar serves.
/// @return The token contract address.
function token() external view returns (address);

/// @notice Returns the current nonce for an investor-operator pair.
/// Used to construct and verify EIP-712 authorization signatures.
/// @param investor The investor's wallet address.
/// @param operator The operator (protocol) address.
/// @return The current nonce value.
function operatorNonce(
address investor,
address operator
) external view returns (uint256);

/// @notice Invalidates all EIP-712 signatures previously granted by the caller to an operator.
/// Increments the nonce for the caller-operator pair, rendering any outstanding
/// signatures void.
/// @param operator The operator address whose permissions are being invalidated.
function invalidateOperatorPermission(address operator) external;
}
```

### Behavior Requirements

- `registerVault` MUST revert if the provided signature is invalid, expired, or has been revoked via `invalidateOperatorPermission`.
- `registerVault` MUST revert if implementation-defined compliance checks fail.
- `unregisterVault` MUST emit a `VaultUnregistered` event upon success.
- `registerVault` MUST emit a `VaultRegistered` event upon success.
- `invalidateOperatorPermission` MUST increment the nonce and MUST emit `OperatorPermissionInvalidated`.
- Revocation MUST be enforced synchronously — a revoked authorization MUST NOT be usable in any subsequent call.

## Rationale

### Standalone Companion Interface

This ERC is designed as a standalone contract interface rather than an [ERC-20] extension for the following reasons:

- Many permissioned tokens cannot be upgraded to add new methods.
- Compliance logic is often externalized for regulatory or operational reasons.
- Protocols prefer a predictable "call this contract during the flow" pattern.
- The design avoids imposing identity semantics on token contracts.

The registrar acts as an adapter between protocols and permissioned [ERC-20] ecosystems.

### [EIP-712] Signed Authorization

The choice to require explicit [EIP-712] investor authorization rather than implicit protocol trust provides three key properties:

**Clear user consent.** The authorization message makes the permission explicit and user-visible. Investors cryptographically authorize vault creation rather than implicitly trusting protocol flows.

**Revocable permissions.** Investors can revoke authorization by invalidating the operator nonce. This aligns with familiar wallet-based permission patterns.

**Protocol lifecycle flexibility.** Many real integrations involve collateral management strategies where new vaults may need to be created over time — for example, collateral rebalancing, leverage loops, liquidation protection, or strategy upgrades. The signed authorization allows those vaults to be created without requiring the investor to manually re-authorize every step.

### Relationship to [ERC-4626] and [ERC-7575]

While this proposal involves vault contracts, it is orthogonal to [ERC-4626] and [ERC-7575]. This ERC does not define vault accounting or asset semantics. It focuses exclusively on standardizing authorization of investor-bound vault addresses in permissioned [ERC-20] ecosystems.

### Non-Goals

This proposal explicitly does not attempt to:

- Standardize identity models, KYC, or accreditation logic.
- Define how investor identities are represented or stored.
- Replace or subsume [ERC-3643] or other permissioned token standards.
- Mandate specific compliance checks or policies.
- Define vault accounting, asset semantics, or identity models.

All compliance semantics remain implementation-defined.

## Backwards Compatibility

This ERC introduces a new standalone interface and has no backwards compatibility issues with [ERC-20] or any existing standard. Permissioned token contracts may adopt the Vault Registrar pattern without modifying their [ERC-20] interface.

This ERC is compatible with:

- [ERC-20]
- [ERC-3643] and custom permissioned token implementations
- [ERC-1271] (smart contract wallet signatures)
- Regulated [ERC-20] tokens, permissioned vault protocols, collateral and lending systems, and looping strategies

## Reference Implementation

A reference implementation is available at `https://github.com/securitize-io/bc-vault-registrar/tree/feature/BC-1833`

## Security Considerations

**Operator authorization scope.** Implementations SHOULD restrict which callers may invoke `registerVault`. Vault authorization SHOULD be treated as equivalent to investor authorization, as a registered vault will be able to hold and operate permissioned tokens on the investor's behalf.

**[EIP-712] signature validation.** Signatures MUST be validated against the correct domain separator and struct hash. Implementations MUST support both ECDSA (EOA) and [ERC-1271] (smart contract wallet) signatures. Replay protection is provided by the nonce mechanism; implementations MUST verify the nonce matches the current value for the investor-operator pair.

**Deadline enforcement.** Implementations MUST reject signatures with a `deadline` in the past. The `deadline` field MUST be checked against `block.timestamp`.

**Revocation synchronicity.** Revocation via `invalidateOperatorPermission` MUST take effect immediately. A revoked authorization MUST NOT be accepted in any subsequent `registerVault` call within the same block or thereafter.

**Reentrancy.** Implementations SHOULD follow the checks-effects-interactions pattern. `registerVault` is intended to be called within complex protocol flows; implementations should be safe against reentrancy attacks.

**Denial of service.** Implementations SHOULD ensure that `registerVault` cannot be griefed by an adversary racing to invalidate an investor's nonce. Callers SHOULD construct transactions to minimize the window between signature issuance and on-chain submission.

## Copyright

Copyright and related rights waived via [CC0](../LICENSE.md).

[ERC-20]: ./eip-20.md
[EIP-712]: ./eip-712.md
[ERC-1271]: ./eip-1271.md
[ERC-4626]: ./eip-4626.md
[ERC-7575]: ./eip-7575.md
[ERC-3643]: ./eip-3643.md
Loading