> For the complete documentation index, see [llms.txt](https://docs.curvance.com/app/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.curvance.com/app/developer-docs/protocol-managers/protocolmanagerdeployment.md).

# ProtocolManagerDeployment

### Overview

`ProtocolManagerDeployment` is a standalone deployment-phase manager for PMD market setup. It atomically lists a two-token isolated market, seeds the cToken dead-share reserves, pauses minting on both tokens, writes both token configs, and records a one-time mint-unpause allowance for that market.

The contract does not inherit `ProtocolManager` because it does not need period-limit tracking or a managed-address registry. Its surface is intentionally small: deploy a market, consume the one-time mint unpause, or revoke that unpause allowance.

### Core Architecture

<table><thead><tr><th width="201">Item</th><th width="250">Getter</th><th>Purpose</th></tr></thead><tbody><tr><td>Central registry</td><td><code>centralRegistry()</code></td><td>Used to validate market-manager registration and market-permission callers.</td></tr><tr><td>Deployment owner</td><td><code>owner()</code></td><td>Address authorized to call <code>deployMarket()</code> and <code>unpauseMarket()</code>.</td></tr><tr><td>Reserve amount</td><td><code>BASE_UNDERLYING_RESERVE()</code></td><td><code>77777</code> raw units of each underlying asset, matching the cToken initialization reserve.</td></tr><tr><td>Pending unpause state</td><td><code>pendingUnpause(address)</code></td><td>One-time mint-unpause allowance keyed by market manager.</td></tr></tbody></table>

The deployed `ProtocolManagerDeployment` contract must have market permissions in `CentralRegistry` before it can call `listTokens()`, `setMintPaused()`, or `updateTokenConfig()` on `MarketManagerIsolated`.

### Deployment Flow

`deployMarket()` performs this sequence:

1. Checks that `msg.sender == owner`.
2. Checks that `config0.cToken == token0` and `config1.cToken == token1`.
3. Checks that `centralRegistry.isMarketManager(marketManager)` is true.
4. Reads each cToken's underlying asset through `ICToken.asset()`.
5. Rejects the call if either underlying address has no code.
6. Pulls `77777` raw units of each underlying from the caller.
7. Approves each cToken to spend its corresponding reserve amount.
8. Calls `MarketManagerIsolated.listTokens(token0, token1)`.
9. Pauses minting on both listed tokens.
10. Calls `updateTokenConfig()` for both token configs.
11. Sets `pendingUnpause[marketManager] = true`.

The reserve transfer happens before listing so `listTokens()` can call each cToken's `initializeDeposits()` path and pull the reserve from `ProtocolManagerDeployment`.

### Token Config Shape

`deployMarket()` accepts two `MarketManagerIsolated.TokenConfig` structs. The field order is:

```solidity
struct TokenConfig {
    address cToken;
    uint256 collRatio;
    uint256 collReqSoft;
    uint256 collReqHard;
    uint256 liqIncBase;
    uint256 liqIncHard;
    uint256 liqIncMin;
    uint256 liqIncMax;
    uint256 closeFactorBase;
    uint256 closeFactorMin;
    uint256 closeFactorMax;
    uint256 collateralCap;
    uint256 debtCap;
}
```

`ProtocolManagerDeployment` only checks the `cToken` address matches the explicit token argument. The full token-config validation is enforced by `MarketManagerIsolated.updateTokenConfig()`.

### One-Time Mint Unpause

`unpauseMarket()` consumes `pendingUnpause[marketManager]`, reads the market's listed tokens with `queryTokensListed()`, and calls `setMintPaused(token, false)` for every listed token.

This unpause is intentionally narrow:

* It only affects mint pause flags.
* It does not change collateralization, borrow, liquidation, redeem, or transfer pause flags.
* It can only be used while `pendingUnpause[marketManager]` is true.
* A second `unpauseMarket()` call for the same allowance reverts with `ProtocolManagerDeployment__NoPendingUnpause()`.

`revokeUnpause()` deletes the pending allowance without changing any market pause flags. It is callable by the deployment owner or by any address with market permissions, and it is idempotent.

### Deployment Scripts

`script/deployment/DeployProtocolManager_Deployment.s.sol` deploys this manager:

```solidity
function run(
    address registry,
    address ownerAddress
) external;
```

The script emits `ContractDeployed(address(pm), "ProtocolManagerDeployment")` through the shared deployment recorder.

After deployment, grant the new contract market permissions before using it:

```solidity
CentralRegistry.addMarketPermissions(protocolManagerDeployment);
```

`script/deployment/RevokeProtocolManagerDeploymentUnpause.s.sol` clears a pending allowance:

```solidity
function run(
    address protocolManagerDeployment,
    address marketManager
) external;
```

### Events and Errors

`ProtocolManagerDeployment` does not define custom events. Downstream calls emit market events such as `TokenListed`, `TokenActionPaused`, and `TokenConfigUpdated`.

| Error                                               | Meaning                                                                                                                            |
| --------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- |
| `ProtocolManagerDeployment__Unauthorized()`         | Caller is not authorized for the requested operation.                                                                              |
| `ProtocolManagerDeployment__ParametersAreInvalid()` | Constructor owner is zero, token config does not match token argument, market is unregistered, or an underlying asset has no code. |
| `ProtocolManagerDeployment__NoPendingUnpause()`     | `unpauseMarket()` was called without an active pending allowance.                                                                  |

### Integration Considerations

* The owner must approve `ProtocolManagerDeployment` for `77777` raw units of each underlying asset before calling `deployMarket()`.
* The target market manager must already be registered in `CentralRegistry`.
* The manager contract must already have market permissions.
* Expect minting to be paused immediately after `deployMarket()`.
* Use `pendingUnpause(marketManager)` to check whether the one-time mint unpause is still available.
* Use `revokeUnpause()` to clear stale allowances before relying on another actor's pause state.
* Do not treat `unpauseMarket()` as a general unpause tool. It only unpauses minting on the market's listed tokens.

### Callable Functions

#### Constructor

```solidity
constructor(ICentralRegistry cr, address _owner);
```

Validates the central registry, rejects a zero owner, and stores both immutable values.

#### Reads

```solidity
function BASE_UNDERLYING_RESERVE() external view returns (uint256);

function centralRegistry() external view returns (ICentralRegistry);

function owner() external view returns (address);

function pendingUnpause(address marketManager) external view returns (bool);
```

Use these reads to inspect the deployment authority, reserve requirement, registry, and pending mint-unpause state.

#### Market Deployment

```solidity
function deployMarket(
    address marketManager,
    address token0,
    address token1,
    MarketManagerIsolated.TokenConfig memory config0,
    MarketManagerIsolated.TokenConfig memory config1
) external;
```

Lists the two cTokens, initializes the cToken reserve deposits, pauses minting for both tokens, writes both token configs, and records a pending one-time mint unpause.

#### Mint Unpause

```solidity
function unpauseMarket(address marketManager) external;
```

Consumes the pending allowance for `marketManager` and unpauses minting for every token returned by `queryTokensListed()`.

#### Allowance Revocation

```solidity
function revokeUnpause(address marketManager) external;
```

Deletes the pending allowance for `marketManager`. The caller must be the owner or have market permissions in `CentralRegistry`.
