> For the complete documentation index, see [llms.txt](https://city-protocol.gitbook.io/docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://city-protocol.gitbook.io/docs/security/security-and-risk/contract-security.md).

# Contract security

The Curated Vault contract surface, role separation, settlement, limits and monitoring in technical detail.

City Protocol's vault infrastructure separates the standard user-facing vault flows from the control plane that governs settlement, pricing, access policy, fees, strategy allocation and registry discovery. Integrators build against familiar vault interfaces, while contract-enforced controls cover permissions, accounting, valuation inputs, emergency response and monitoring.

The primary security invariant is that no single operational action silently changes user economics. Deposits, redemptions, fee accrual, NAV updates and strategy movement are either bounded by contract checks or recorded through structured state and events, so that indexers, monitoring systems, auditors, operators and product teams can independently verify the live system.

## Contract surface

The main technical surface includes `Base7540Vault`, `FullyAsyncVault`, `SyncDepositAsyncRedeemVault`, `AsyncDepositVault`, `AsyncRedeemVault`, `SettlementModule`, `PricingModule`, `ReportOracle`, `AccessController`, `AuthorizationPolicy`, `WhitelistPolicy`, `BlacklistPolicy`, `FeeManager`, `StrategyManager` and `VaultRegistry`.

Together, these modules cover ERC-4626 share accounting, ERC-7540 asynchronous request flows, ERC-7575 share discovery, policy checks, pause checks, limit checks, settlement snapshots, NAV consumption, fee math, strategy controls, oracle reporting and canonical vault discovery.

## Role separation

City Protocol uses OpenZeppelin `AccessControl`, so sensitive permissions are assigned by function and by contract. Vault roles cover default administration, settlement, pricing, access policy management, emergency pause, unpause, fee management and protocol fee management.

* **Strategy manager roles:** Separate roles cover strategy configuration, allocation, execution, verifier management, pause and unpause.
* **Oracle roles:** Separate roles cover reporter membership, quorum and freshness policy.

{% hint style="info" %}
The split limits the reach of any single role: a settlement operator cannot update access policy, a pricing operator cannot allocate capital, and a strategy executor cannot change debt caps.
{% endhint %}

Deployment scripts assign administration to the deployer at first, and operational setup transfers sensitive roles to a multisig or the timelock. City Protocol includes an OpenZeppelin `TimelockController` deployment path with a configurable delay, proposer and administrator, an optional open executor and deployment metadata. The default delay is 24 hours, with longer delays available for high-impact actions. The vault contracts are not proxy-upgradeable, so change management runs through role-governed configuration, manager replacement, oracle replacement, strategy policy and registry state.

## Access control

Vaults run in `Open` mode or `Policy` mode. In policy mode, user-facing flows call `validateAccess` or `validateAccessPair`, which lets the policy update state, consume nonces or verify signatures, and read-only previews use `canAccess`. Policy modules include allowlists, denylists and EIP-712 signed authorization. A signed authorization binds the call data, the vault, the account, a nonce, an expiration block, the chain identifier and the verifying contract domain; successful validation increments the nonce, which prevents replay.

## Deposit and redemption settlement

Asynchronous deposits and redemptions are epoch-based. All user-facing and administrative actions are atomic transactions: a deposit, redemption, settlement or strategy execution either passes all checks or reverts as a whole, so there are no partial deposits, partially priced redemptions, partially minted shares or partially executed strategy calls.

<figure><img src="https://3297077862-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FJxNp2waFk6hg1G4lEQZu%2Fuploads%2FUvjFD3dvaNSTfqyzyqYq%2Ffig-deposit-lifecycle.png?alt=media" alt="Deposit lifecycle from request to claim"><figcaption><p>Deposit lifecycle. Assets enter the vault on request, the epoch is priced from an eligible oracle report, and shares are minted for the controller to claim.</p></figcaption></figure>

A deposit request transfers assets into the vault and records the controller and the epoch. Once the epoch can close, the vault consumes an eligible oracle report, snapshots the report identifier, price, fees, protocol split and timestamp, mints shares to the vault and makes them claimable.

<figure><img src="https://3297077862-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FJxNp2waFk6hg1G4lEQZu%2Fuploads%2FtAb8SyBOpQKK47GZszCy%2Ffig-redemption-lifecycle.png?alt=media" alt="Redemption lifecycle from request to claim and burn"><figcaption><p>Redemption lifecycle. Shares are reserved on request, the epoch is priced, idle assets are verified, and claimed shares are burned.</p></figcaption></figure>

A redemption request transfers shares into the vault and records the controller and the epoch. The vault prices the epoch using an eligible oracle report, verifies that idle assets are sufficient, makes the assets claimable and burns the claimed shares. Later NAV reports, fee changes or strategy events do not alter economics that have already settled.

## Pause, limits, fees and capacity

Pause controls are layered across the global vault, deposits, redemptions, share transfers, strategy allocation and strategy execution. Pause and unpause roles are separate, so emergency response can be fast while resumption requires review.

<figure><img src="https://3297077862-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FJxNp2waFk6hg1G4lEQZu%2Fuploads%2F2LcsZtKu9yesiRI2HeKk%2Ffig-limits-v21.png?alt=media" alt="Limit parameters and fee rules enforced at contract level, with fees snapshot into settled epochs"><figcaption><p>Hard caps and limits are enforced at contract level, and fees are snapshot into each settled epoch.</p></figcaption></figure>

* **Limits:** `LimitModule` enforces `maxTotalAssets`, `maxPendingDepositAssets`, `minDepositAssets` and `minRedeemShares`.
* **Fee caps:** `FeeManager` enforces hard caps on the entry, exit, performance and management fees, and after initialization the entry and exit fees can only decrease. Each curator sets its vault's fees within those caps.
* **Fee snapshots:** Deposit epochs snapshot the entry fee and protocol split, and redemption epochs snapshot the exit fee and protocol split. Management and performance fees accrue through vault-controlled calls, and performance fees use a high-water mark on assets per share.

## Strategy and custody controls

Strategy execution is separated from the vault. The vault can allocate idle assets to a configured `StrategyManager`, and the manager enforces strategy allowlists, strategy kind validation, adapter `vault()` and `asset()` binding, per-strategy debt caps, total strategy debt caps, allocation pause, execution pause, allowed call targets, allowed selectors, return-value validation and vault balance-delta validation.

Execution is curated and bounded. A whitelisted strategy executes approved actions within caps, and the whitelist confers no right to take or redirect vault assets. Claimable redemption assets are excluded from `availableIdleAssetsForStrategy`, and asynchronous deposit assets are excluded from strategy availability until settlement. Adapter calls require an allowed strategy, an onchain adapter kind, an approved target and an approved selector, and any failure reverts the entire transaction.

## Share transfer, rescue and registry

Vault shares use ERC-20 semantics with 18-decimal share precision. Ordinary investor-to-investor transfers can be disabled through `shareTransferEnabled`, which supports permissioned products where secondary transfer must be restricted. The restricted `rescueToken` path can recover unrelated tokens sent to the vault by mistake, and it cannot rescue the underlying vault asset; the recipient must be nonzero and the caller must hold `DEFAULT_ADMIN_ROLE`.

`VaultRegistry` is the canonical discovery registry. It records the vault address, underlying asset, strategy manager, report oracle, vault type, name, symbol and active flag. Registration and metadata refresh require `REGISTRAR_ROLE`, and registration validates that the strategy manager is bound to the same vault and asset.

## Transparency, testing and boundaries

Core contracts expose roles, pause flags, access mode and policy, limits, oracle state, active NAV, epoch state, fee state, strategy state and registry state. Monitoring covers role changes, reporter changes, quorum updates, NAV updates, epoch close, price and settle events, pause events, fee changes, strategy policy updates, registry changes, and unexpected changes in idle strategy availability, claimable redemptions, pending deposits or cached NAV.

<figure><img src="https://3297077862-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FJxNp2waFk6hg1G4lEQZu%2Fuploads%2F9ohBg3enuyFilkKz48TA%2Ffig-monitoring.png?alt=media" alt="Contract state and events indexed through the vault registry for monitoring"><figcaption><p>Registry records, roles, NAV, epochs, fees and strategy state support independent monitoring.</p></figcaption></figure>

Foundry tests cover deployment wiring, access control, authorization-based access, pause behaviour, limits, fees, pricing and settlement, strategy allocation and execution policy, accounting invariants, registry behaviour, fully asynchronous vault behaviour and synchronous-deposit, asynchronous-redemption vault behaviour. The standard verification commands are:

```bash
forge build
forge test
forge fmt
```

Before production deployment, each product is checked for multisig or timelock role transfer, deployer role handling, oracle reporter and quorum policy, `maxReportAge`, `maxNavPriceDeviationBps`, fee disclosures, strategy allowlists and caps, pause and unpause separation, registry records and block explorer source verification.

{% hint style="warning" %}
City Protocol's contracts enforce onchain permissions, accounting, price-consumption rules and strategy execution constraints. Offchain NAV components and offchain strategy valuations still require operational controls, reporter separation, review workflows, metadata hashes, multisig or timelock governance, independent monitoring and product-specific valuation procedures.
{% endhint %}
