> For the complete documentation index, see [llms.txt](https://docs.aera.finance/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.aera.finance/the-protocol/core/provisionerv2.md).

# ProvisionerV2

**Inherits:** IProvisionerV2, Auth2Step, ReentrancyGuardTransient

Entry and exit point for {MultiDepositorVault}. Handles all deposits and redemptions Uses {IPriceAndFeeCalculator} to convert between tokens and vault units. Supports both sync and async deposits; only async redeems. Manages deposit caps, refund timeouts, and request replay protection. All assets must flow through this contract to enter or exit the vault. Sync deposits are processed instantly, but stay refundable for a period of time. Async requests can either be solved by authorized solvers, going through the vault, or directly by anyone willing to pay units (for deposits) or tokens (for redeems), pocketing the solver tip, always paid in tokens

### Constants <a href="#constants" id="constants"></a>

#### RELEVANT\_AMOUNT\_SLOT <a href="#relevant_amount_slot" id="relevant_amount_slot"></a>

ERC7201-compliant transient storage slot for the relevant amount

Equal to keccak256(abi.encode(uint256(keccak256(“aera.provisioner.relevantAmount”)) - 1)) & \~bytes32(uint256(0xff))

```solidity
bytes32 internal constant RELEVANT_AMOUNT_SLOT = 0x35763d55300b221a73cb498654a5b850852575e97ef00a6947ad36dc59da0d00
```

#### PRICE\_FEE\_CALCULATOR <a href="#price_fee_calculator" id="price_fee_calculator"></a>

The price and fee calculator contract

```solidity
IPriceAndFeeCalculatorV2 public immutable PRICE_FEE_CALCULATOR
```

#### MULTI\_DEPOSITOR\_VAULT <a href="#multi_depositor_vault" id="multi_depositor_vault"></a>

The multi depositor vault contract

```solidity
address public immutable MULTI_DEPOSITOR_VAULT
```

#### SOLVING\_GATE\_ENABLED <a href="#solving_gate_enabled" id="solving_gate_enabled"></a>

Whether this provisioner supports solving status gating

```solidity
bool public immutable SOLVING_GATE_ENABLED
```

### State Variables <a href="#state-variables" id="state-variables"></a>

#### tokensDetails <a href="#tokensdetails" id="tokensdetails"></a>

Mapping of token to token details

```solidity
mapping(IERC20 token => TokenDetailsV2 details) public tokensDetails
```

#### depositCap <a href="#depositcap" id="depositcap"></a>

Maximum total value of deposits in numeraire terms

```solidity
uint224 public depositCap
```

#### depositRefundTimeout <a href="#depositrefundtimeout" id="depositrefundtimeout"></a>

Time period in seconds during which sync deposits can be refunded

```solidity
uint32 public depositRefundTimeout
```

#### syncDepositHashes <a href="#syncdeposithashes" id="syncdeposithashes"></a>

Mapping of active sync deposit hashes

True if a sync deposit is active with the hashed parameters

```solidity
mapping(bytes32 syncDepositHash => bool exists) public syncDepositHashes
```

#### asyncRequestHashes <a href="#asyncrequesthashes" id="asyncrequesthashes"></a>

Mapping of async request hash to its existence (deposits and redeems share one domain)

True if request exists, false if it was refunded or solved Collision between deposit and redeem hashes is impossible because the hash includes RequestType

```solidity
mapping(bytes32 asyncRequestHash => bool exists) public asyncRequestHashes
```

#### userUnitsRefundableUntil <a href="#userunitsrefundableuntil" id="userunitsrefundableuntil"></a>

Mapping of user address to timestamp until which their units are locked

```solidity
mapping(address user => uint256 unitsLockedUntil) public userUnitsRefundableUntil
```

#### \_syncRedeemMaxPriceAge <a href="#syncredeemmaxpriceage" id="syncredeemmaxpriceage"></a>

Maximum allowed vault price age for sync redeems (seconds)

```solidity
uint24 internal _syncRedeemMaxPriceAge
```

#### \_syncRedeemRelativeCapBps <a href="#syncredeemrelativecapbps" id="syncredeemrelativecapbps"></a>

Relative cap in bps of epoch-start vault value for sync redeems

```solidity
uint16 internal _syncRedeemRelativeCapBps
```

#### \_syncRedeemMaxDynamicPremiumBps <a href="#syncredeemmaxdynamicpremiumbps" id="syncredeemmaxdynamicpremiumbps"></a>

Maximum global dynamic premium in bps for sync redeems

```solidity
uint16 internal _syncRedeemMaxDynamicPremiumBps
```

#### \_syncRedeemEpochTimestamp <a href="#syncredeemepochtimestamp" id="syncredeemepochtimestamp"></a>

Timestamp of the current sync redeem epoch (from PFC vault state)

```solidity
uint32 internal _syncRedeemEpochTimestamp
```

#### \_syncRedeemAbsoluteCapNumeraire <a href="#syncredeemabsolutecapnumeraire" id="syncredeemabsolutecapnumeraire"></a>

Absolute cap in numeraire per epoch for sync redeems

```solidity
uint80 internal _syncRedeemAbsoluteCapNumeraire
```

#### \_syncRedeemEpochRedeemedNumeraire <a href="#syncredeemepochredeemednumeraire" id="syncredeemepochredeemednumeraire"></a>

Numeraire amount redeemed globally so far in the current sync redeem epoch

```solidity
uint80 internal _syncRedeemEpochRedeemedNumeraire
```

#### \_depositCancellationsEnabled <a href="#depositcancellationsenabled" id="depositcancellationsenabled"></a>

Whether user-initiated deposit request cancellations are enabled

```solidity
bool internal _depositCancellationsEnabled
```

#### \_redeemCancellationsEnabled <a href="#redeemcancellationsenabled" id="redeemcancellationsenabled"></a>

Whether user-initiated redeem request cancellations are enabled

```solidity
bool internal _redeemCancellationsEnabled
```

#### \_redeemCancellationCapNumeraire <a href="#redeemcancellationcapnumeraire" id="redeemcancellationcapnumeraire"></a>

Maximum redeem request size eligible for user self-cancellation, in numeraire

```solidity
uint80 internal _redeemCancellationCapNumeraire
```

#### \_depositCancellationFeeNumeraire <a href="#depositcancellationfeenumeraire" id="depositcancellationfeenumeraire"></a>

Fixed deposit cancellation fee for self-cancels before deadline, in numeraire

```solidity
uint80 internal _depositCancellationFeeNumeraire
```

#### \_redeemCancellationFeeNumeraire <a href="#redeemcancellationfeenumeraire" id="redeemcancellationfeenumeraire"></a>

Fixed redeem cancellation fee for self-cancels before deadline, in numeraire

```solidity
uint80 internal _redeemCancellationFeeNumeraire
```

#### \_redeemCancellationDynamicFeeCapNumeraire <a href="#redeemcancellationdynamicfeecapnumeraire" id="redeemcancellationdynamicfeecapnumeraire"></a>

Dynamic redeem cancellation fee cap for self-cancels before deadline, in numeraire

```solidity
uint80 internal _redeemCancellationDynamicFeeCapNumeraire
```

#### depositReceiverApprovals <a href="#depositreceiverapprovals" id="depositreceiverapprovals"></a>

Whether a receiver has approved a depositor to deposit on their behalf

```solidity
mapping(address receiver => mapping(address depositor => bool approved)) public depositReceiverApprovals
```

#### solvingGate <a href="#solvinggate" id="solvinggate"></a>

Returns the current solving gate address

```solidity
address public solvingGate
```

### Functions <a href="#functions" id="functions"></a>

#### anyoneButVault <a href="#anyonebutvault" id="anyonebutvault"></a>

Ensures the caller is not the vault

```solidity
modifier anyoneButVault() ;
```

#### solvingNotPaused <a href="#solvingnotpaused" id="solvingnotpaused"></a>

Reverts if the solving gate is set and reports that solving is paused

```solidity
modifier solvingNotPaused(IERC20 token) ;
```

**Parameters**

| Name    | Type     | Description                  |
| ------- | -------- | ---------------------------- |
| `token` | `IERC20` | The ERC20 token being solved |

#### constructor <a href="#constructor" id="constructor"></a>

```solidity
constructor(
    IPriceAndFeeCalculatorV2 priceAndFeeCalculator,
    address multiDepositorVault,
    bool solvingGateEnabled,
    address owner_,
    Authority authority_
) Auth2Step(owner_, authority_);
```

#### deposit <a href="#deposit" id="deposit"></a>

Deposit tokens directly into the vault

Caller must be the receiver or approved by the receiver via {setDepositReceiverApproval}

```solidity
function deposit(IERC20 token, uint256 tokensIn, uint256 minUnitsOut, address receiver)
    external
    nonReentrant
    anyoneButVault
    solvingNotPaused(token)
    returns (uint256 unitsOut);
```

**Parameters**

| Name          | Type      | Description                          |
| ------------- | --------- | ------------------------------------ |
| `token`       | `IERC20`  | The token to deposit                 |
| `tokensIn`    | `uint256` | The amount of tokens to deposit      |
| `minUnitsOut` | `uint256` | The minimum amount of units expected |
| `receiver`    | `address` | The address that receives units      |

**Returns**

| Name       | Type      | Description                                 |
| ---------- | --------- | ------------------------------------------- |
| `unitsOut` | `uint256` | The amount of shares minted to the receiver |

#### mint <a href="#mint" id="mint"></a>

Mint exact amount of units by depositing required tokens

Caller must be the receiver or approved by the receiver via {setDepositReceiverApproval}

```solidity
function mint(IERC20 token, uint256 unitsOut, uint256 maxTokensIn, address receiver)
    external
    nonReentrant
    anyoneButVault
    solvingNotPaused(token)
    returns (uint256 tokensIn);
```

**Parameters**

| Name          | Type      | Description                                 |
| ------------- | --------- | ------------------------------------------- |
| `token`       | `IERC20`  | The token to deposit                        |
| `unitsOut`    | `uint256` | The exact amount of units to mint           |
| `maxTokensIn` | `uint256` | Maximum amount of tokens willing to deposit |
| `receiver`    | `address` | The address that receives units             |

**Returns**

| Name       | Type      | Description                                            |
| ---------- | --------- | ------------------------------------------------------ |
| `tokensIn` | `uint256` | The amount of tokens used to mint the requested shares |

#### refundDeposit <a href="#refunddeposit" id="refunddeposit"></a>

Refund a deposit within the refund period

```solidity
function refundDeposit(
    address sender,
    address receiver,
    IERC20 token,
    uint256 tokenAmount,
    uint256 unitsAmount,
    uint256 refundableUntil
) external requiresAuth;
```

**Parameters**

| Name              | Type      | Description                              |
| ----------------- | --------- | ---------------------------------------- |
| `sender`          | `address` | The original depositor                   |
| `receiver`        | `address` | The address whose units are reclaimed    |
| `token`           | `IERC20`  | The deposited token                      |
| `tokenAmount`     | `uint256` | The amount of tokens deposited           |
| `unitsAmount`     | `uint256` | The amount of units minted               |
| `refundableUntil` | `uint256` | Timestamp until which refund is possible |

#### requestDeposit <a href="#requestdeposit" id="requestdeposit"></a>

Create a new deposit request to be solved by solvers

```solidity
function requestDeposit(
    IERC20 token,
    uint256 tokensIn,
    uint256 minUnitsOut,
    uint256 solverTip,
    uint256 deadline,
    uint256 maxPriceAge,
    bool isFixedPrice
) external returns (bytes32 depositHash);
```

**Parameters**

| Name           | Type      | Description                                   |
| -------------- | --------- | --------------------------------------------- |
| `token`        | `IERC20`  | The token to deposit                          |
| `tokensIn`     | `uint256` | The amount of tokens to deposit               |
| `minUnitsOut`  | `uint256` | The minimum amount of units expected          |
| `solverTip`    | `uint256` | The tip offered to the solver                 |
| `deadline`     | `uint256` | Timestamp until which the request is valid    |
| `maxPriceAge`  | `uint256` | Maximum age of price data that solver can use |
| `isFixedPrice` | `bool`    | Whether the request is a fixed price request  |

**Returns**

| Name          | Type      | Description                                          |
| ------------- | --------- | ---------------------------------------------------- |
| `depositHash` | `bytes32` | requestHash The hash identifying the created request |

#### requestRedeem <a href="#requestredeem" id="requestredeem"></a>

Create a new redeem request to be solved by solvers

```solidity
function requestRedeem(
    IERC20 token,
    uint256 unitsIn,
    uint256 minTokensOut,
    uint256 solverTip,
    uint256 deadline,
    uint256 maxPriceAge,
    bool isFixedPrice
) external returns (bytes32 redeemHash);
```

**Parameters**

| Name           | Type      | Description                                   |
| -------------- | --------- | --------------------------------------------- |
| `token`        | `IERC20`  | The token to receive                          |
| `unitsIn`      | `uint256` | The amount of units to redeem                 |
| `minTokensOut` | `uint256` | The minimum amount of tokens expected         |
| `solverTip`    | `uint256` | The tip offered to the solver                 |
| `deadline`     | `uint256` | Timestamp until which the request is valid    |
| `maxPriceAge`  | `uint256` | Maximum age of price data that solver can use |
| `isFixedPrice` | `bool`    | Whether the request is a fixed price request  |

**Returns**

| Name         | Type      | Description                                          |
| ------------ | --------- | ---------------------------------------------------- |
| `redeemHash` | `bytes32` | requestHash The hash identifying the created request |

#### refundRequest <a href="#refundrequest" id="refundrequest"></a>

Refund an expired deposit or redeem request

```solidity
function refundRequest(IERC20 token, RequestV2 calldata request) external nonReentrant;
```

**Parameters**

| Name      | Type        | Description                       |
| --------- | ----------- | --------------------------------- |
| `token`   | `IERC20`    | The token involved in the request |
| `request` | `RequestV2` | The request to refund             |

#### cancelRequest <a href="#cancelrequest" id="cancelrequest"></a>

Cancel an async deposit or redeem request

```solidity
function cancelRequest(IERC20 token, RequestV2 calldata request) external nonReentrant;
```

**Parameters**

| Name      | Type        | Description                       |
| --------- | ----------- | --------------------------------- |
| `token`   | `IERC20`    | The token involved in the request |
| `request` | `RequestV2` | The request to cancel             |

#### solveRequestsVault <a href="#solverequestsvault" id="solverequestsvault"></a>

Solve multiple requests using vault’s liquidity, with optional pre/post-solve guardian submissions for automatic fund movement

MUST revert if preSolveSubmitData is non-empty and vault.submit reverts

```solidity
function solveRequestsVault(
    IERC20 token,
    RequestV2[] calldata requests,
    bytes calldata preSolveSubmitData,
    bytes calldata postSolveSubmitData
) external requiresAuth nonReentrant solvingNotPaused(token);
```

**Parameters**

| Name                  | Type          | Description                                                                                                                                                               |
| --------------------- | ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `token`               | `IERC20`      | The token for which to solve requests                                                                                                                                     |
| `requests`            | `RequestV2[]` | Array of requests to solve                                                                                                                                                |
| `preSolveSubmitData`  | `bytes`       | Encoded operations to submit before solving (e.g., pull funds from yield source). If non-empty, calls vault.submit and reverts if it fails If empty, skipped              |
| `postSolveSubmitData` | `bytes`       | Encoded operations to submit after solving (e.g., push funds to yield source). If non-empty, calls vault.submit via try/catch - failures are swallowed. If empty, skipped |

#### solveRequestsDirect <a href="#solverequestsdirect" id="solverequestsdirect"></a>

Solve multiple requests using solver’s own liquidity

Does not check the solving gate because direct solves are peer-to-peer and never touch the vault’s enter/exit flow, so they have no impact on underlying fund accounting The PFC vault-pause check still applies as the full-freeze mechanism

```solidity
function solveRequestsDirect(IERC20 token, RequestV2[] calldata requests) external nonReentrant;
```

**Parameters**

| Name       | Type          | Description                           |
| ---------- | ------------- | ------------------------------------- |
| `token`    | `IERC20`      | The token for which to solve requests |
| `requests` | `RequestV2[]` | Array of requests to solve            |

#### setDepositDetails <a href="#setdepositdetails" id="setdepositdetails"></a>

Update deposit parameters

```solidity
function setDepositDetails(uint224 depositCap_, uint32 depositRefundTimeout_) external requiresAuth;
```

**Parameters**

| Name                    | Type      | Description                                   |
| ----------------------- | --------- | --------------------------------------------- |
| `depositCap_`           | `uint224` | New maximum total value that can be deposited |
| `depositRefundTimeout_` | `uint32`  | New time window for deposit refunds           |

#### setCancellationDetails <a href="#setcancellationdetails" id="setcancellationdetails"></a>

Sets cancellation toggles and enabled-side fee configuration

If a deposit/redeem cancellation is disabled, params related to it must be 0

```solidity
function setCancellationDetails(
    bool depositCancellationsEnabled,
    bool redeemCancellationsEnabled,
    uint80 depositCancellationFeeNumeraire,
    uint80 redeemCancellationFeeNumeraire,
    uint80 redeemCancellationDynamicFeeCapNumeraire,
    uint80 redeemCancellationCapNumeraire
) external requiresAuth;
```

**Parameters**

| Name                                       | Type     | Description                                                     |
| ------------------------------------------ | -------- | --------------------------------------------------------------- |
| `depositCancellationsEnabled`              | `bool`   | Whether user-initiated deposit requests can be cancelled        |
| `redeemCancellationsEnabled`               | `bool`   | Whether user-initiated redeem requests can be cancelled         |
| `depositCancellationFeeNumeraire`          | `uint80` | Fixed deposit cancellation fee, in numeraire                    |
| `redeemCancellationFeeNumeraire`           | `uint80` | Fixed redeem cancellation fee, in numeraire                     |
| `redeemCancellationDynamicFeeCapNumeraire` | `uint80` | Dynamic redeem cancellation fee cap, in numeraire               |
| `redeemCancellationCapNumeraire`           | `uint80` | Maximum redeem request size users can self-cancel, in numeraire |

#### setTokenDetails <a href="#settokendetails" id="settokendetails"></a>

Update token parameters including push/pull funds SSTORE2 pointers

Admin must create SSTORE2 pointers externally before calling this function

```solidity
function setTokenDetails(IERC20 token, TokenDetailsV2 calldata details) external requiresAuth;
```

**Parameters**

| Name      | Type             | Description                                                                                                                                            |
| --------- | ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `token`   | `IERC20`         | The token to update                                                                                                                                    |
| `details` | `TokenDetailsV2` | The full token details struct. `pushFundsSubmitDataPointer` and `pullFundsSubmitDataPointer` must be valid SSTORE2 pointers or `address(0)` to disable |

#### removeToken <a href="#removetoken" id="removetoken"></a>

Removes token from provisioner

```solidity
function removeToken(IERC20 token) external requiresAuth;
```

**Parameters**

| Name    | Type     | Description             |
| ------- | -------- | ----------------------- |
| `token` | `IERC20` | The token to be removed |

#### setSyncRedeemDetails <a href="#setsyncredeemdetails" id="setsyncredeemdetails"></a>

Sets global sync redeem risk parameters

Only callable by authorized addresses. All parameters must be non-zero

```solidity
function setSyncRedeemDetails(
    uint24 maxPriceAge,
    uint16 relativeCapBps,
    uint80 absoluteCapNumeraire,
    uint16 maxDynamicPremiumBps
) external requiresAuth;
```

**Parameters**

| Name                   | Type     | Description                                        |
| ---------------------- | -------- | -------------------------------------------------- |
| `maxPriceAge`          | `uint24` | Maximum allowed vault price age (seconds)          |
| `relativeCapBps`       | `uint16` | Relative cap in bps of epoch-start TVL (numeraire) |
| `absoluteCapNumeraire` | `uint80` | Absolute cap in numeraire per epoch                |
| `maxDynamicPremiumBps` | `uint16` | Maximum global dynamic premium in bps              |

#### setDepositReceiverApproval <a href="#setdepositreceiverapproval" id="setdepositreceiverapproval"></a>

Approve or revoke a depositor’s permission to deposit on behalf of the caller

```solidity
function setDepositReceiverApproval(address depositor, bool approved) external;
```

**Parameters**

| Name        | Type      | Description                                                |
| ----------- | --------- | ---------------------------------------------------------- |
| `depositor` | `address` | The address to approve or revoke                           |
| `approved`  | `bool`    | Whether the depositor is approved to deposit to the caller |

#### setSolvingGate <a href="#setsolvinggate" id="setsolvinggate"></a>

Sets the solving gate contract that controls when solving is allowed

MUST only be callable by authorized addresses

```solidity
function setSolvingGate(address solvingGate_) external requiresAuth;
```

**Parameters**

| Name           | Type      | Description                                                                          |
| -------------- | --------- | ------------------------------------------------------------------------------------ |
| `solvingGate_` | `address` | The new solving gate address. Use address(0) to disable gating (solving always open) |

#### redeem <a href="#redeem" id="redeem"></a>

Synchronously redeem units for tokens using latest active price

Sync redeem must be enabled for token, vault must be active, and price must be fresh

```solidity
function redeem(IERC20 token, uint256 unitsIn, uint256 minTokensOut, address receiver)
    external
    anyoneButVault
    nonReentrant
    solvingNotPaused(token)
    returns (uint256 tokensOut);
```

**Parameters**

| Name           | Type      | Description                     |
| -------------- | --------- | ------------------------------- |
| `token`        | `IERC20`  | Token to receive                |
| `unitsIn`      | `uint256` | Units to redeem                 |
| `minTokensOut` | `uint256` | Minimum acceptable token output |
| `receiver`     | `address` | Address receiving output tokens |

**Returns**

| Name        | Type      | Description                          |
| ----------- | --------- | ------------------------------------ |
| `tokensOut` | `uint256` | Actual token amount sent to receiver |

#### withdraw <a href="#withdraw" id="withdraw"></a>

Synchronously withdraw exact tokens using latest active price

Sync redeem must be enabled for token, vault must be active, and price must be fresh

```solidity
function withdraw(IERC20 token, uint256 tokensOut, uint256 maxUnitsIn, address receiver)
    external
    anyoneButVault
    nonReentrant
    solvingNotPaused(token)
    returns (uint256 unitsIn);
```

**Parameters**

| Name         | Type      | Description                      |
| ------------ | --------- | -------------------------------- |
| `token`      | `IERC20`  | Token to receive                 |
| `tokensOut`  | `uint256` | Exact token output requested     |
| `maxUnitsIn` | `uint256` | Maximum acceptable units to burn |
| `receiver`   | `address` | Address receiving output tokens  |

**Returns**

| Name      | Type      | Description         |
| --------- | --------- | ------------------- |
| `unitsIn` | `uint256` | Actual units burned |

#### getSyncRedeemEpochState <a href="#getsyncredeemepochstate" id="getsyncredeemepochstate"></a>

Returns current global sync redeem epoch state

MUST NOT revert; returns view-consistent epoch state (if PFC is paused, returns zero TVL and zero cap for the current epoch) (if PFC timestamp differs from stored, shows fresh epoch with 0 redeemed)

```solidity
function getSyncRedeemEpochState()
    external
    view
    returns (
        uint256 epochTimestamp,
        uint256 epochStartTvlNumeraire,
        uint256 epochRedeemedNumeraire,
        uint256 epochCapNumeraire
    );
```

**Returns**

| Name                     | Type      | Description                                                |
| ------------------------ | --------- | ---------------------------------------------------------- |
| `epochTimestamp`         | `uint256` | Current anchor epoch timestamp from PFC                    |
| `epochStartTvlNumeraire` | `uint256` | Epoch-start TVL in numeraire                               |
| `epochRedeemedNumeraire` | `uint256` | Numeraire amount redeemed globally so far in current epoch |
| `epochCapNumeraire`      | `uint256` | Effective current epoch cap in numeraire                   |

#### getSyncRedeemDetails <a href="#getsyncredeemdetails" id="getsyncredeemdetails"></a>

Returns all sync redeem configuration and epoch state

```solidity
function getSyncRedeemDetails() external view returns (uint24, uint16, uint16, uint32, uint80, uint80);
```

**Returns**

| Name     | Type     | Description                                                                                       |
| -------- | -------- | ------------------------------------------------------------------------------------------------- |
| `<none>` | `uint24` | maxPriceAge Maximum allowed vault price age for sync redeems (seconds)                            |
| `<none>` | `uint16` | relativeCapBps Relative cap in bps of epoch-start TVL for sync redeems                            |
| `<none>` | `uint16` | maxDynamicPremiumBps Maximum global dynamic premium in bps for sync redeems                       |
| `<none>` | `uint32` | epochTimestamp Timestamp of the current sync redeem epoch (from PFC vault state)                  |
| `<none>` | `uint80` | absoluteCapNumeraire Absolute cap in numeraire per epoch for sync redeems                         |
| `<none>` | `uint80` | epochRedeemedNumeraire Numeraire amount redeemed globally so far in the current sync redeem epoch |

#### getRelevantAmount <a href="#getrelevantamount" id="getrelevantamount"></a>

Read an amount relevant for current submit operation from transient storage

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

**Returns**

| Name     | Type      | Description       |
| -------- | --------- | ----------------- |
| `<none>` | `uint256` | The stored amount |

#### maxDeposit <a href="#maxdeposit" id="maxdeposit"></a>

Return maximum amount that can still be deposited

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

**Returns**

| Name     | Type      | Description                          |
| -------- | --------- | ------------------------------------ |
| `<none>` | `uint256` | Amount of deposit capacity remaining |

#### previewCancellationFeeNumeraire <a href="#previewcancellationfeenumeraire" id="previewcancellationfeenumeraire"></a>

Preview the cancellation fee for a request in numeraire terms

No guard checks (enable flags, cap, deadline) — those revert in cancelRequest

```solidity
function previewCancellationFeeNumeraire(RequestV2 calldata request) external view returns (uint256);
```

**Parameters**

| Name      | Type        | Description                                     |
| --------- | ----------- | ----------------------------------------------- |
| `request` | `RequestV2` | The request to preview the cancellation fee for |

**Returns**

| Name     | Type      | Description                       |
| -------- | --------- | --------------------------------- |
| `<none>` | `uint256` | The cancellation fee in numeraire |

#### getCancellationDetails <a href="#getcancellationdetails" id="getcancellationdetails"></a>

Returns cancellation toggles and fee configuration

```solidity
function getCancellationDetails() external view returns (bool, bool, uint80, uint80, uint80, uint80);
```

**Returns**

| Name     | Type     | Description                                                                                    |
| -------- | -------- | ---------------------------------------------------------------------------------------------- |
| `<none>` | `bool`   | depositCancellationsEnabled Whether user-initiated deposit request cancellations are enabled   |
| `<none>` | `bool`   | redeemCancellationsEnabled Whether user-initiated redeem request cancellations are enabled     |
| `<none>` | `uint80` | depositCancellationFeeNumeraire Fixed deposit cancellation fee, in numeraire                   |
| `<none>` | `uint80` | redeemCancellationFeeNumeraire Fixed redeem cancellation fee, in numeraire                     |
| `<none>` | `uint80` | redeemCancellationDynamicFeeCapNumeraire Dynamic redeem cancellation fee cap, in numeraire     |
| `<none>` | `uint80` | redeemCancellationCapNumeraire Maximum redeem request size users can self-cancel, in numeraire |

#### areUserUnitsLocked <a href="#areuserunitslocked" id="areuserunitslocked"></a>

Check if a user’s units are currently locked

```solidity
function areUserUnitsLocked(address user) external view returns (bool);
```

**Parameters**

| Name   | Type      | Description          |
| ------ | --------- | -------------------- |
| `user` | `address` | The address to check |

**Returns**

| Name     | Type   | Description                                      |
| -------- | ------ | ------------------------------------------------ |
| `<none>` | `bool` | True if user’s units are locked, false otherwise |

#### getDepositHash <a href="#getdeposithash" id="getdeposithash"></a>

Computes the hash for a sync deposit

```solidity
function getDepositHash(
    address user,
    address receiver,
    IERC20 token,
    uint256 tokenAmount,
    uint256 unitsAmount,
    uint256 refundableUntil
) external pure returns (bytes32);
```

**Parameters**

| Name              | Type      | Description                                         |
| ----------------- | --------- | --------------------------------------------------- |
| `user`            | `address` | The address making the deposit                      |
| `receiver`        | `address` | The address receiving units from the deposit        |
| `token`           | `IERC20`  | The token being deposited                           |
| `tokenAmount`     | `uint256` | The amount of tokens to deposit                     |
| `unitsAmount`     | `uint256` | Minimum amount of units to receive                  |
| `refundableUntil` | `uint256` | The timestamp until which the deposit is refundable |

**Returns**

| Name     | Type      | Description             |
| -------- | --------- | ----------------------- |
| `<none>` | `bytes32` | The hash of the deposit |

#### getRequestHash <a href="#getrequesthash" id="getrequesthash"></a>

Computes the hash for a request

```solidity
function getRequestHash(IERC20 token, RequestV2 calldata request) external pure returns (bytes32);
```

**Parameters**

| Name      | Type        | Description              |
| --------- | ----------- | ------------------------ |
| `token`   | `IERC20`    | The token in the request |
| `request` | `RequestV2` | The request to hash      |

**Returns**

| Name     | Type      | Description             |
| -------- | --------- | ----------------------- |
| `<none>` | `bytes32` | The hash of the request |

#### version <a href="#version" id="version"></a>

Returns the semantic version string for this contract surface

```solidity
function version() external pure returns (string memory);
```

**Returns**

| Name     | Type     | Description                 |
| -------- | -------- | --------------------------- |
| `<none>` | `string` | The semantic version string |

#### requestDeposit <a href="#requestdeposit-1" id="requestdeposit-1"></a>

Create a new deposit request to be solved by solvers

```solidity
function requestDeposit(
    IERC20 token,
    uint256 tokensIn,
    uint256 minUnitsOut,
    uint256 solverTip,
    uint256 deadline,
    uint256 maxPriceAge,
    bool isFixedPrice,
    address receiver
) public anyoneButVault returns (bytes32 depositHash);
```

**Parameters**

| Name           | Type      | Description                                   |
| -------------- | --------- | --------------------------------------------- |
| `token`        | `IERC20`  | The token to deposit                          |
| `tokensIn`     | `uint256` | The amount of tokens to deposit               |
| `minUnitsOut`  | `uint256` | The minimum amount of units expected          |
| `solverTip`    | `uint256` | The tip offered to the solver                 |
| `deadline`     | `uint256` | Timestamp until which the request is valid    |
| `maxPriceAge`  | `uint256` | Maximum age of price data that solver can use |
| `isFixedPrice` | `bool`    | Whether the request is a fixed price request  |
| `receiver`     | `address` | The address that receives units when solved   |

**Returns**

| Name          | Type      | Description                                        |
| ------------- | --------- | -------------------------------------------------- |
| `depositHash` | `bytes32` | depositRequestHash The hash of the deposit request |

#### requestRedeem <a href="#requestredeem-1" id="requestredeem-1"></a>

Create a new redeem request to be solved by solvers

```solidity
function requestRedeem(
    IERC20 token,
    uint256 unitsIn,
    uint256 minTokensOut,
    uint256 solverTip,
    uint256 deadline,
    uint256 maxPriceAge,
    bool isFixedPrice,
    address receiver
) public anyoneButVault returns (bytes32 redeemHash);
```

**Parameters**

| Name           | Type      | Description                                   |
| -------------- | --------- | --------------------------------------------- |
| `token`        | `IERC20`  | The token to receive                          |
| `unitsIn`      | `uint256` | The amount of units to redeem                 |
| `minTokensOut` | `uint256` | The minimum amount of tokens expected         |
| `solverTip`    | `uint256` | The tip offered to the solver                 |
| `deadline`     | `uint256` | Timestamp until which the request is valid    |
| `maxPriceAge`  | `uint256` | Maximum age of price data that solver can use |
| `isFixedPrice` | `bool`    | Whether the request is a fixed price request  |
| `receiver`     | `address` | The address that receives tokens when solved  |

**Returns**

| Name         | Type      | Description                                      |
| ------------ | --------- | ------------------------------------------------ |
| `redeemHash` | `bytes32` | redeemRequestHash The hash of the redeem request |

#### \_solveRequestsVault <a href="#solverequestsvault" id="solverequestsvault"></a>

Internal solve logic shared by both solveRequestsVault overloads

```solidity
function _solveRequestsVault(IERC20 token, RequestV2[] calldata requests) internal;
```

**Parameters**

| Name       | Type          | Description                           |
| ---------- | ------------- | ------------------------------------- |
| `token`    | `IERC20`      | The token for which to solve requests |
| `requests` | `RequestV2[]` | Array of requests to solve            |

#### \_pullFundsIfNeeded <a href="#pullfundsifneeded" id="pullfundsifneeded"></a>

Pull funds from yield source if vault idle balance is insufficient

```solidity
function _pullFundsIfNeeded(IERC20 token, uint256 tokensOut) internal;
```

**Parameters**

| Name        | Type      | Description                                |
| ----------- | --------- | ------------------------------------------ |
| `token`     | `IERC20`  | The redeem token                           |
| `tokensOut` | `uint256` | The amount of tokens needed for the redeem |

#### \_pushFundsIfConfigured <a href="#pushfundsifconfigured" id="pushfundsifconfigured"></a>

Push deposited funds to yield source if configured

```solidity
function _pushFundsIfConfigured(TokenDetailsV2 storage tokenDetails, uint256 tokensIn) internal;
```

**Parameters**

| Name           | Type             | Description                         |
| -------------- | ---------------- | ----------------------------------- |
| `tokenDetails` | `TokenDetailsV2` | The token details storage reference |
| `tokensIn`     | `uint256`        | The amount of tokens deposited      |

#### \_storeAmount <a href="#storeamount" id="storeamount"></a>

Store a uint256 amount in transient storage

```solidity
function _storeAmount(uint256 amount) internal;
```

**Parameters**

| Name     | Type      | Description         |
| -------- | --------- | ------------------- |
| `amount` | `uint256` | The amount to store |

#### \_syncDeposit <a href="#syncdeposit" id="syncdeposit"></a>

Handles a synchronous deposit, records the deposit hash, and enters the vault

Reverts if the deposit hash already exists. Sets the refundable period for the user

```solidity
function _syncDeposit(IERC20 token, uint256 tokenAmount, uint256 unitAmount, address receiver) internal;
```

**Parameters**

| Name          | Type      | Description                                    |
| ------------- | --------- | ---------------------------------------------- |
| `token`       | `IERC20`  | The ERC20 token to deposit                     |
| `tokenAmount` | `uint256` | The amount of tokens to deposit                |
| `unitAmount`  | `uint256` | The amount of vault units to mint for the user |
| `receiver`    | `address` | The address receiving the minted units         |

#### \_syncRedeem <a href="#syncredeem" id="syncredeem"></a>

Executes a synchronous redeem: rolls epoch, checks epoch cap, exits vault, and emits event

```solidity
function _syncRedeem(
    IERC20 token,
    uint256 tokensOut,
    uint256 unitsIn,
    address receiver,
    uint256 epochRedeemNumeraire,
    uint256 priceTimestamp
) internal;
```

**Parameters**

| Name                   | Type      | Description                                                                        |
| ---------------------- | --------- | ---------------------------------------------------------------------------------- |
| `token`                | `IERC20`  | The ERC20 token to receive                                                         |
| `tokensOut`            | `uint256` | The amount of tokens to send to the receiver                                       |
| `unitsIn`              | `uint256` | The amount of vault units to burn from the caller                                  |
| `receiver`             | `address` | The address to receive the tokens                                                  |
| `epochRedeemNumeraire` | `uint256` | The pre-computed numeraire value of this redeem for epoch cap accounting           |
| `priceTimestamp`       | `uint256` | The PFC anchor timestamp captured in \_prepareSyncRedeem (used for epoch rollover) |

#### \_solveDepositVaultAutoPrice <a href="#solvedepositvaultautoprice" id="solvedepositvaultautoprice"></a>

Solves an async deposit request for the vault, transferring tokens or refunding as needed

* Returns 0 if any of:
* price age is too high, emits PriceAgeExceeded
* request hash is not set, emits InvalidRequestHash
* units out is less than min required, emits AmountBoundExceeded
* deposit cap would be exceeded, emits DepositCapExceeded
* If deadline not passed, processes deposit and emits DepositSolved
* If deadline passed, refunds and emits DepositRefunded
* Always unsets hash after processing

```solidity
function _solveDepositVaultAutoPrice(
    IERC20 token,
    uint256 depositMultiplier,
    RequestV2 calldata request,
    uint256 priceAge,
    uint256 index
) internal returns (uint256 solverTip);
```

**Parameters**

| Name                | Type        | Description                                                            |
| ------------------- | ----------- | ---------------------------------------------------------------------- |
| `token`             | `IERC20`    | The ERC20 token being deposited                                        |
| `depositMultiplier` | `uint256`   | The multiplier (in BPS) applied to the deposit for premium calculation |
| `request`           | `RequestV2` | The deposit request struct containing all user parameters              |
| `priceAge`          | `uint256`   | The age of the price data used for conversion                          |
| `index`             | `uint256`   | The index of the request in the given solving batch                    |

**Returns**

| Name        | Type      | Description                                              |
| ----------- | --------- | -------------------------------------------------------- |
| `solverTip` | `uint256` | The tip amount paid to the solver, or 0 if not processed |

#### \_solveDepositVaultFixedPrice <a href="#solvedepositvaultfixedprice" id="solvedepositvaultfixedprice"></a>

Solves a fixed price deposit request for the vault, transferring tokens or refunding as needed

User gets exactly min units out, but may over‑fund, the difference is paid to the solver as a tip

* Returns 0 if any of:
* price age is too high, emits PriceAgeExceeded
* request hash is not set, emits InvalidRequestHash
* tokens needed exceed the maximum allowed, emits AmountBoundExceeded
* deposit cap would be exceeded, emits DepositCapExceeded
* If deadline not passed, processes deposit and emits DepositSolved
* If deadline passed, refunds and emits DepositRefunded
* Always unsets hash after processing

```solidity
function _solveDepositVaultFixedPrice(
    IERC20 token,
    uint256 depositMultiplier,
    RequestV2 calldata request,
    uint256 priceAge,
    uint256 index
) internal returns (uint256 solverTip);
```

**Parameters**

| Name                | Type        | Description                                                            |
| ------------------- | ----------- | ---------------------------------------------------------------------- |
| `token`             | `IERC20`    | The ERC20 token being deposited                                        |
| `depositMultiplier` | `uint256`   | The multiplier (in BPS) applied to the deposit for premium calculation |
| `request`           | `RequestV2` | The deposit request struct containing all user parameters              |
| `priceAge`          | `uint256`   | The age of the price data used for conversion                          |
| `index`             | `uint256`   | The index of the request in the given solving batch                    |

**Returns**

| Name        | Type      | Description                                              |
| ----------- | --------- | -------------------------------------------------------- |
| `solverTip` | `uint256` | The tip amount paid to the solver, or 0 if not processed |

#### \_solveRedeemVaultAutoPrice <a href="#solveredeemvaultautoprice" id="solveredeemvaultautoprice"></a>

Solves an async redeem request for the vault, transferring tokens or refunding as needed

* Returns 0 if any of:
* price age is too high, emits PriceAgeExceeded
* request hash is not set, emits InvalidRequestHash
* token out after premium is less than min required, emits AmountBoundExceeded
* If deadline not passed, processes redeem and emits RedeemSolved
* If deadline passed, refunds and emits RedeemRefunded
* Always unsets hash after processing

```solidity
function _solveRedeemVaultAutoPrice(
    IERC20 token,
    uint256 redeemMultiplier,
    RequestV2 calldata request,
    uint256 priceAge,
    uint256 index
) internal returns (uint256 solverTip);
```

**Parameters**

| Name               | Type        | Description                                                           |
| ------------------ | ----------- | --------------------------------------------------------------------- |
| `token`            | `IERC20`    | The ERC20 token being redeemed                                        |
| `redeemMultiplier` | `uint256`   | The multiplier (in BPS) applied to the redeem for premium calculation |
| `request`          | `RequestV2` | The redeem request struct containing all user parameters              |
| `priceAge`         | `uint256`   | The age of the price data used for conversion                         |
| `index`            | `uint256`   | The index of the request in the given solving batch                   |

**Returns**

| Name        | Type      | Description                                              |
| ----------- | --------- | -------------------------------------------------------- |
| `solverTip` | `uint256` | The tip amount paid to the solver, or 0 if not processed |

#### \_solveRedeemVaultFixedPrice <a href="#solveredeemvaultfixedprice" id="solveredeemvaultfixedprice"></a>

Solves a fixed price redeem request for the vault, transferring tokens or refunding as needed

User gets exactly min tokens out, but may under‑fund, the difference is paid to the solver as a tip

* Returns 0 if any of:
* price age is too high, emits PriceAgeExceeded
* request hash is not set, emits InvalidRequestHash
* If deadline not passed, processes redeem and emits RedeemSolved
* If deadline passed, refunds and emits RedeemRefunded
* Always unsets hash after processing

```solidity
function _solveRedeemVaultFixedPrice(
    IERC20 token,
    uint256 redeemMultiplier,
    RequestV2 calldata request,
    uint256 priceAge,
    uint256 index
) internal returns (uint256 solverTip);
```

**Parameters**

| Name               | Type        | Description                                                           |
| ------------------ | ----------- | --------------------------------------------------------------------- |
| `token`            | `IERC20`    | The ERC20 token being redeemed                                        |
| `redeemMultiplier` | `uint256`   | The multiplier (in BPS) applied to the redeem for premium calculation |
| `request`          | `RequestV2` | The redeem request struct containing all user parameters              |
| `priceAge`         | `uint256`   | The age of the price data used for conversion                         |
| `index`            | `uint256`   | The index of the request in the given solving batch                   |

**Returns**

| Name        | Type      | Description                                              |
| ----------- | --------- | -------------------------------------------------------- |
| `solverTip` | `uint256` | The tip amount paid to the solver, or 0 if not processed |

#### \_solveRequestDirect <a href="#solverequestdirect" id="solverequestdirect"></a>

Solves a direct request (deposit or redeem), transferring tokens and units between users

* Returns early if request hash is not set, emits InvalidRequestHash
* If deadline not passed, transfers units and tokens, emits DepositSolved/RedeemSolved
* If deadline passed, refunds escrowed asset, emits DepositRefunded/RedeemRefunded
* Always unsets hash after processing

```solidity
function _solveRequestDirect(IERC20 token, RequestV2 calldata request) internal;
```

**Parameters**

| Name      | Type        | Description                                       |
| --------- | ----------- | ------------------------------------------------- |
| `token`   | `IERC20`    | The ERC20 token involved in the request           |
| `request` | `RequestV2` | The request struct containing all user parameters |

#### \_clearHashAndTransferRefund <a href="#clearhashandtransferrefund" id="clearhashandtransferrefund"></a>

Clears request hash, emits refund event, and transfers amount with requester fallback

```solidity
function _clearHashAndTransferRefund(
    IERC20 token,
    RequestV2 calldata request,
    address requester,
    uint256 amount,
    IERC20 transferToken
) internal;
```

**Parameters**

| Name            | Type        | Description                                                                 |
| --------------- | ----------- | --------------------------------------------------------------------------- |
| `token`         | `IERC20`    | The token used to derive the request hash                                   |
| `request`       | `RequestV2` | The request to clear                                                        |
| `requester`     | `address`   | The fallback recipient when transfer to request.receiver fails              |
| `amount`        | `uint256`   | The amount to transfer to the receiver (or requester on fallback)           |
| `transferToken` | `IERC20`    | The token to transfer (deposit token for deposits, vault units for redeems) |

#### \_transferWithFallback <a href="#transferwithfallback" id="transferwithfallback"></a>

Transfers amount to receiver and falls back to requester if receiver transfer fails

```solidity
function _transferWithFallback(IERC20 token, address requester, address receiver, uint256 amount) internal;
```

**Parameters**

| Name        | Type      | Description                                              |
| ----------- | --------- | -------------------------------------------------------- |
| `token`     | `IERC20`  | The ERC20 token being transferred                        |
| `requester` | `address` | The original requester address used as fallback receiver |
| `receiver`  | `address` | The intended receiver from the request                   |
| `amount`    | `uint256` | The amount of tokens to transfer                         |

#### \_guardPriceAge <a href="#guardpriceage" id="guardpriceage"></a>

Checks if the price age exceeds the maximum allowed and emits an event if so

```solidity
function _guardPriceAge(uint256 priceAge, uint256 maxPriceAge, uint256 index) internal returns (bool);
```

**Parameters**

| Name          | Type      | Description                                                          |
| ------------- | --------- | -------------------------------------------------------------------- |
| `priceAge`    | `uint256` | The difference between when price was measured and submitted onchain |
| `maxPriceAge` | `uint256` | The maximum allowed price age                                        |
| `index`       | `uint256` | The index of the request in the given solving batch                  |

**Returns**

| Name     | Type   | Description                                    |
| -------- | ------ | ---------------------------------------------- |
| `<none>` | `bool` | True if price age is too high, false otherwise |

#### \_guardInvalidRequestHash <a href="#guardinvalidrequesthash" id="guardinvalidrequesthash"></a>

Checks if the request hash exists and emits an event if not

```solidity
function _guardInvalidRequestHash(bytes32 requestHash) internal returns (bool);
```

**Parameters**

| Name          | Type      | Description      |
| ------------- | --------- | ---------------- |
| `requestHash` | `bytes32` | The request hash |

**Returns**

| Name     | Type   | Description                                  |
| -------- | ------ | -------------------------------------------- |
| `<none>` | `bool` | True if hash does not exist, false otherwise |

#### \_guardInsufficientTokensForTip <a href="#guardinsufficienttokensfortip" id="guardinsufficienttokensfortip"></a>

Checks if there are enough tokens for the solver tip and emits an event if not

```solidity
function _guardInsufficientTokensForTip(uint256 tokens, uint256 solverTip, uint256 index) internal returns (bool);
```

**Parameters**

| Name        | Type      | Description                                         |
| ----------- | --------- | --------------------------------------------------- |
| `tokens`    | `uint256` | The number of tokens                                |
| `solverTip` | `uint256` | The solver tip amount                               |
| `index`     | `uint256` | The index of the request in the given solving batch |

**Returns**

| Name     | Type   | Description                                        |
| -------- | ------ | -------------------------------------------------- |
| `<none>` | `bool` | True if not enough tokens for tip, false otherwise |

#### \_guardAmountBound <a href="#guardamountbound" id="guardamountbound"></a>

Checks if the amount is less than the bound and emits an event if so

```solidity
function _guardAmountBound(uint256 amount, uint256 bound, uint256 index) internal returns (bool);
```

**Parameters**

| Name     | Type      | Description                                         |
| -------- | --------- | --------------------------------------------------- |
| `amount` | `uint256` | The actual amount                                   |
| `bound`  | `uint256` | The minimum required amount                         |
| `index`  | `uint256` | The index of the request in the given solving batch |

**Returns**

| Name     | Type   | Description                                        |
| -------- | ------ | -------------------------------------------------- |
| `<none>` | `bool` | True if amount is less than bound, false otherwise |

#### \_guardDepositCapExceeded <a href="#guarddepositcapexceeded" id="guarddepositcapexceeded"></a>

Checks if the deposit cap would be exceeded and emits an event if so

```solidity
function _guardDepositCapExceeded(uint256 totalUnits, uint256 index) internal returns (bool);
```

**Parameters**

| Name         | Type      | Description                                         |
| ------------ | --------- | --------------------------------------------------- |
| `totalUnits` | `uint256` | The total units after deposit                       |
| `index`      | `uint256` | The index of the request in the given solving batch |

**Returns**

| Name     | Type   | Description                                            |
| -------- | ------ | ------------------------------------------------------ |
| `<none>` | `bool` | True if deposit cap would be exceeded, false otherwise |

#### \_rollEpochIfNeeded <a href="#rollepochifneeded" id="rollepochifneeded"></a>

Rolls the sync redeem epoch if the PFC timestamp has changed

```solidity
function _rollEpochIfNeeded(uint256 pfcTimestamp) internal returns (uint256 epochRedeemedNumeraire_);
```

**Parameters**

| Name           | Type      | Description                           |
| -------------- | --------- | ------------------------------------- |
| `pfcTimestamp` | `uint256` | The current PFC vault state timestamp |

**Returns**

| Name                      | Type      | Description                                                                   |
| ------------------------- | --------- | ----------------------------------------------------------------------------- |
| `epochRedeemedNumeraire_` | `uint256` | The epoch redeemed numeraire after potential roll (avoids subsequent SSLOADs) |

#### \_requireEpochCapNotExceeded <a href="#requireepochcapnotexceeded" id="requireepochcapnotexceeded"></a>

Checks that the sync redeem epoch cap is not exceeded and tracks the redemption

```solidity
function _requireEpochCapNotExceeded(
    uint256 epochRedeemNumeraire,
    uint256 epochCapNumeraire,
    uint256 epochRedeemedNumeraire
) internal;
```

**Parameters**

| Name                     | Type      | Description                                                                           |
| ------------------------ | --------- | ------------------------------------------------------------------------------------- |
| `epochRedeemNumeraire`   | `uint256` | The pre-computed numeraire value of this redeem for epoch cap accounting              |
| `epochCapNumeraire`      | `uint256` | The effective epoch cap in numeraire                                                  |
| `epochRedeemedNumeraire` | `uint256` | The numeraire already redeemed in the current epoch (cached from \_rollEpochIfNeeded) |

#### \_requireValidReceiver <a href="#requirevalidreceiver" id="requirevalidreceiver"></a>

Reverts if the caller is not the receiver and the receiver has not approved the caller

```solidity
function _requireValidReceiver(address receiver) internal view;
```

**Parameters**

| Name       | Type      | Description             |
| ---------- | --------- | ----------------------- |
| `receiver` | `address` | The address to validate |

#### \_checkSolvingNotPaused <a href="#checksolvingnotpaused" id="checksolvingnotpaused"></a>

Reverts if the solving gate is set and reports that solving is paused

```solidity
function _checkSolvingNotPaused(IERC20 token) internal view;
```

**Parameters**

| Name    | Type     | Description                  |
| ------- | -------- | ---------------------------- |
| `token` | `IERC20` | The ERC20 token being solved |

#### \_checkCallerNotVault <a href="#checkcallernotvault" id="checkcallernotvault"></a>

Reverts if the caller is the vault

```solidity
function _checkCallerNotVault() internal view;
```

#### \_validateRequest <a href="#validaterequest" id="validaterequest"></a>

Validates common request parameters shared by requestDeposit and requestRedeem

```solidity
function _validateRequest(address receiver, uint256 solverTip, uint256 deadline, bool isFixedPrice) internal view;
```

**Parameters**

| Name           | Type      | Description                                        |
| -------------- | --------- | -------------------------------------------------- |
| `receiver`     | `address` | The address receiving funds when request is solved |
| `solverTip`    | `uint256` | The tip offered to the solver                      |
| `deadline`     | `uint256` | Timestamp until which the request is valid         |
| `isFixedPrice` | `bool`    | Whether the request is a fixed price request       |

#### \_computeDepositCancellationFeeTokens <a href="#computedepositcancellationfeetokens" id="computedepositcancellationfeetokens"></a>

Computes the pre-deadline deposit cancellation fee in request token terms

Oracle quoting floors and does not support rounding control, so a non-zero numeraire fee can round to zero request tokens for low-value cancellation fees

```solidity
function _computeDepositCancellationFeeTokens(IERC20 token) internal view returns (uint256 feeTokens);
```

**Parameters**

| Name    | Type     | Description   |
| ------- | -------- | ------------- |
| `token` | `IERC20` | Request token |

**Returns**

| Name        | Type      | Description                       |
| ----------- | --------- | --------------------------------- |
| `feeTokens` | `uint256` | Fee amount in request token terms |

#### \_computeRedeemCancellationFeeNumeraire <a href="#computeredeemcancellationfeenumeraire" id="computeredeemcancellationfeenumeraire"></a>

Computes the pre-deadline redeem cancellation fee in numeraire

```solidity
function _computeRedeemCancellationFeeNumeraire(uint256 requestNumeraire)
    internal
    view
    returns (uint256 feeNumeraire);
```

**Parameters**

| Name               | Type      | Description                      |
| ------------------ | --------- | -------------------------------- |
| `requestNumeraire` | `uint256` | Redeem request size in numeraire |

**Returns**

| Name           | Type      | Description             |
| -------------- | --------- | ----------------------- |
| `feeNumeraire` | `uint256` | Fee amount in numeraire |

#### \_computeRedeemCancellationFeeUnits <a href="#computeredeemcancellationfeeunits" id="computeredeemcancellationfeeunits"></a>

Computes the pre-deadline redeem cancellation fee in escrowed vault units

```solidity
function _computeRedeemCancellationFeeUnits(uint256 requestNumeraire) internal view returns (uint256 feeUnits);
```

**Parameters**

| Name               | Type      | Description                      |
| ------------------ | --------- | -------------------------------- |
| `requestNumeraire` | `uint256` | Redeem request size in numeraire |

**Returns**

| Name       | Type      | Description         |
| ---------- | --------- | ------------------- |
| `feeUnits` | `uint256` | Fee amount in units |

#### \_requireSyncDepositsEnabled <a href="#requiresyncdepositsenabled" id="requiresyncdepositsenabled"></a>

Reverts if sync deposits are not enabled for the token

```solidity
function _requireSyncDepositsEnabled(IERC20 token) internal view returns (TokenDetailsV2 storage tokenDetails);
```

**Parameters**

| Name    | Type     | Description              |
| ------- | -------- | ------------------------ |
| `token` | `IERC20` | The ERC20 token to check |

**Returns**

| Name           | Type             | Description                         |
| -------------- | ---------------- | ----------------------------------- |
| `tokenDetails` | `TokenDetailsV2` | The token details storage reference |

#### \_requireSyncRedeemsEnabled <a href="#requiresyncredeemsenabled" id="requiresyncredeemsenabled"></a>

Reverts if sync redeems are not enabled for the token

```solidity
function _requireSyncRedeemsEnabled(IERC20 token) internal view returns (TokenDetailsV2 storage tokenDetails);
```

**Parameters**

| Name    | Type     | Description              |
| ------- | -------- | ------------------------ |
| `token` | `IERC20` | The ERC20 token to check |

**Returns**

| Name           | Type             | Description                         |
| -------------- | ---------------- | ----------------------------------- |
| `tokenDetails` | `TokenDetailsV2` | The token details storage reference |

#### \_requireDepositCapNotExceeded <a href="#requiredepositcapnotexceeded" id="requiredepositcapnotexceeded"></a>

Reverts if deposit cap would be exceeded by adding units

```solidity
function _requireDepositCapNotExceeded(uint256 units) internal view;
```

**Parameters**

| Name    | Type      | Description                |
| ------- | --------- | -------------------------- |
| `units` | `uint256` | The number of units to add |

#### \_isDepositCapExceeded <a href="#isdepositcapexceeded" id="isdepositcapexceeded"></a>

Checks if deposit cap would be exceeded by adding units

```solidity
function _isDepositCapExceeded(uint256 units) internal view returns (bool);
```

**Parameters**

| Name    | Type      | Description                |
| ------- | --------- | -------------------------- |
| `units` | `uint256` | The number of units to add |

**Returns**

| Name     | Type   | Description                                            |
| -------- | ------ | ------------------------------------------------------ |
| `<none>` | `bool` | True if deposit cap would be exceeded, false otherwise |

#### \_tokensToUnitsFloorIfActive <a href="#tokenstounitsfloorifactive" id="tokenstounitsfloorifactive"></a>

Converts token amount to units, applying multiplier and flooring

```solidity
function _tokensToUnitsFloorIfActive(IERC20 token, uint256 tokens, uint256 multiplier)
    internal
    view
    returns (uint256);
```

**Parameters**

| Name         | Type      | Description             |
| ------------ | --------- | ----------------------- |
| `token`      | `IERC20`  | The ERC20 token         |
| `tokens`     | `uint256` | The amount of tokens    |
| `multiplier` | `uint256` | The multiplier to apply |

**Returns**

| Name     | Type      | Description                   |
| -------- | --------- | ----------------------------- |
| `<none>` | `uint256` | The resulting units (floored) |

#### \_tokensToUnitsCeilIfActive <a href="#tokenstounitsceilifactive" id="tokenstounitsceilifactive"></a>

Converts token amount to units, reversing multiplier and ceiling

```solidity
function _tokensToUnitsCeilIfActive(IERC20 token, uint256 tokens, uint256 multiplier)
    internal
    view
    returns (uint256);
```

**Parameters**

| Name         | Type      | Description               |
| ------------ | --------- | ------------------------- |
| `token`      | `IERC20`  | The ERC20 token           |
| `tokens`     | `uint256` | The amount of tokens      |
| `multiplier` | `uint256` | The multiplier to reverse |

**Returns**

| Name     | Type      | Description                  |
| -------- | --------- | ---------------------------- |
| `<none>` | `uint256` | The resulting units (ceiled) |

#### \_unitsToTokensFloorIfActive <a href="#unitstotokensfloorifactive" id="unitstotokensfloorifactive"></a>

Converts units to token amount, applying multiplier and flooring

```solidity
function _unitsToTokensFloorIfActive(IERC20 token, uint256 units, uint256 multiplier)
    internal
    view
    returns (uint256);
```

**Parameters**

| Name         | Type      | Description             |
| ------------ | --------- | ----------------------- |
| `token`      | `IERC20`  | The ERC20 token         |
| `units`      | `uint256` | The amount of units     |
| `multiplier` | `uint256` | The multiplier to apply |

**Returns**

| Name     | Type      | Description                          |
| -------- | --------- | ------------------------------------ |
| `<none>` | `uint256` | The resulting token amount (floored) |

#### \_unitsToTokensCeilIfActive <a href="#unitstotokensceilifactive" id="unitstotokensceilifactive"></a>

Converts units to token amount, applying multiplier and ceiling

```solidity
function _unitsToTokensCeilIfActive(IERC20 token, uint256 units, uint256 multiplier)
    internal
    view
    returns (uint256);
```

**Parameters**

| Name         | Type      | Description             |
| ------------ | --------- | ----------------------- |
| `token`      | `IERC20`  | The ERC20 token         |
| `units`      | `uint256` | The amount of units     |
| `multiplier` | `uint256` | The multiplier to apply |

**Returns**

| Name     | Type      | Description                         |
| -------- | --------- | ----------------------------------- |
| `<none>` | `uint256` | The resulting token amount (ceiled) |

#### \_computeEpochCap <a href="#computeepochcap" id="computeepochcap"></a>

Computes the effective epoch cap in numeraire

```solidity
function _computeEpochCap() internal view returns (uint256 epochCapNumeraire, uint256 epochStartTvlNumeraire);
```

**Returns**

| Name                     | Type      | Description                                            |
| ------------------------ | --------- | ------------------------------------------------------ |
| `epochCapNumeraire`      | `uint256` | The effective epoch cap (min of relative and absolute) |
| `epochStartTvlNumeraire` | `uint256` | The epoch-start TVL in numeraire                       |

#### \_computeDynamicPremiumBps <a href="#computedynamicpremiumbps" id="computedynamicpremiumbps"></a>

Computes the global dynamic redeem premium in bps based on price staleness

Returns 0 when maxDynamicPremiumBps is 0 (dynamic premium disabled) Callers enforce priceAge <= syncRedeemMaxPriceAge via require, so dynamicPremiumBps <= maxDynamic Division safety: syncRedeemMaxPriceAge > 0 is enforced by setSyncRedeemDetails

```solidity
function _computeDynamicPremiumBps(uint256 priceAge) internal view returns (uint256 dynamicPremiumBps);
```

**Parameters**

| Name       | Type      | Description                      |
| ---------- | --------- | -------------------------------- |
| `priceAge` | `uint256` | The current price age in seconds |

**Returns**

| Name                | Type      | Description                         |
| ------------------- | --------- | ----------------------------------- |
| `dynamicPremiumBps` | `uint256` | The computed dynamic premium in bps |

#### \_prepareSyncRedeem <a href="#preparesyncredeem" id="preparesyncredeem"></a>

Fetches the anchor timestamp, validates price age, and derives the effective multiplier

```solidity
function _prepareSyncRedeem(uint256 syncRedeemMultiplier)
    internal
    view
    returns (uint256 effectiveMultiplier, uint256 priceTimestamp);
```

**Parameters**

| Name                   | Type      | Description                                            |
| ---------------------- | --------- | ------------------------------------------------------ |
| `syncRedeemMultiplier` | `uint256` | The base sync redeem multiplier for the token (in BPS) |

**Returns**

| Name                  | Type      | Description                                                       |
| --------------------- | --------- | ----------------------------------------------------------------- |
| `effectiveMultiplier` | `uint256` | The multiplier after dynamic premium adjustment                   |
| `priceTimestamp`      | `uint256` | The PFC anchor timestamp (consumed downstream for epoch rollover) |

#### \_getRequestType <a href="#getrequesttype" id="getrequesttype"></a>

Returns the request type based on whether the request is a deposit or redeem and fixed or auto price

```solidity
function _getRequestType(bool isFixedPrice, bool isDeposit) internal pure returns (RequestType);
```

**Parameters**

| Name           | Type   | Description                                               |
| -------------- | ------ | --------------------------------------------------------- |
| `isFixedPrice` | `bool` | Whether the request is a fixed price request              |
| `isDeposit`    | `bool` | Whether the request is a deposit (true) or redeem (false) |

**Returns**

| Name     | Type          | Description               |
| -------- | ------------- | ------------------------- |
| `<none>` | `RequestType` | The computed request type |

#### \_requireValidMultiplier <a href="#requirevalidmultiplier" id="requirevalidmultiplier"></a>

Reverts if a multiplier is outside \[MIN\_MULTIPLIER, ONE\_IN\_BPS]

```solidity
function _requireValidMultiplier(uint256 multiplier) internal pure;
```

**Parameters**

| Name         | Type      | Description                |
| ------------ | --------- | -------------------------- |
| `multiplier` | `uint256` | The multiplier to validate |

#### \_validateNonZeroAmounts <a href="#validatenonzeroamounts" id="validatenonzeroamounts"></a>

Reverts if either the units or tokens amount is zero

```solidity
function _validateNonZeroAmounts(uint256 units, uint256 tokens) internal pure;
```

**Parameters**

| Name     | Type      | Description                   |
| -------- | --------- | ----------------------------- |
| `units`  | `uint256` | The units amount to validate  |
| `tokens` | `uint256` | The tokens amount to validate |

#### \_getDepositHash <a href="#getdeposithash" id="getdeposithash"></a>

Get the hash of a deposit

Since refundableUntil is block.timestamp + depositRefundTimeout (which is subject to change), it’s theoretically possible to have a hash collision, but the probability is negligible and we optimize for the common case

```solidity
function _getDepositHash(
    address sender,
    address receiver,
    IERC20 token,
    uint256 tokenAmount,
    uint256 unitsAmount,
    uint256 refundableUntil
) internal pure returns (bytes32);
```

**Parameters**

| Name              | Type      | Description                                        |
| ----------------- | --------- | -------------------------------------------------- |
| `sender`          | `address` | The user who made the deposit                      |
| `receiver`        | `address` | The user that receives units from the deposit      |
| `token`           | `IERC20`  | The token that was deposited                       |
| `tokenAmount`     | `uint256` | The amount of tokens deposited                     |
| `unitsAmount`     | `uint256` | The amount of units received                       |
| `refundableUntil` | `uint256` | The timestamp at which the deposit can be refunded |

**Returns**

| Name     | Type      | Description             |
| -------- | --------- | ----------------------- |
| `<none>` | `bytes32` | The hash of the deposit |

#### \_getRequestHashParams <a href="#getrequesthashparams" id="getrequesthashparams"></a>

Get the hash of a request from parameters

```solidity
function _getRequestHashParams(
    IERC20 token,
    address user,
    address receiver,
    RequestType requestType,
    uint256 tokens,
    uint256 units,
    uint256 solverTip,
    uint256 deadline,
    uint256 maxPriceAge
) internal pure returns (bytes32);
```

**Parameters**

| Name          | Type          | Description                                         |
| ------------- | ------------- | --------------------------------------------------- |
| `token`       | `IERC20`      | The token that was deposited or redeemed            |
| `user`        | `address`     | The user who made the request                       |
| `receiver`    | `address`     | The user that receives funds when request is solved |
| `requestType` | `RequestType` | The type of request                                 |
| `tokens`      | `uint256`     | The amount of tokens in the request                 |
| `units`       | `uint256`     | The amount of units in the request                  |
| `solverTip`   | `uint256`     | The tip paid to the solver                          |
| `deadline`    | `uint256`     | The deadline of the request                         |
| `maxPriceAge` | `uint256`     | The maximum age of the price data                   |

**Returns**

| Name     | Type      | Description             |
| -------- | --------- | ----------------------- |
| `<none>` | `bytes32` | The hash of the request |

#### \_getRequestHash <a href="#getrequesthash" id="getrequesthash"></a>

Get the hash of a request

```solidity
function _getRequestHash(IERC20 token, RequestV2 calldata request) internal pure returns (bytes32);
```

**Parameters**

| Name      | Type        | Description                              |
| --------- | ----------- | ---------------------------------------- |
| `token`   | `IERC20`    | The token that was deposited or redeemed |
| `request` | `RequestV2` | The request to get the hash of           |

**Returns**

| Name     | Type      | Description             |
| -------- | --------- | ----------------------- |
| `<none>` | `bytes32` | The hash of the request |

#### \_isRequestTypeDeposit <a href="#isrequesttypedeposit" id="isrequesttypedeposit"></a>

Returns true if the request type is a deposit

```solidity
function _isRequestTypeDeposit(RequestType requestType) internal pure returns (bool);
```

**Parameters**

| Name          | Type          | Description      |
| ------------- | ------------- | ---------------- |
| `requestType` | `RequestType` | The request type |

**Returns**

| Name     | Type   | Description                      |
| -------- | ------ | -------------------------------- |
| `<none>` | `bool` | True if deposit, false otherwise |

#### \_isRequestTypeAutoPrice <a href="#isrequesttypeautoprice" id="isrequesttypeautoprice"></a>

Returns true if the request type is fixed price

```solidity
function _isRequestTypeAutoPrice(RequestType requestType) internal pure returns (bool);
```

**Parameters**

| Name          | Type          | Description      |
| ------------- | ------------- | ---------------- |
| `requestType` | `RequestType` | The request type |

**Returns**

| Name     | Type   | Description                          |
| -------- | ------ | ------------------------------------ |
| `<none>` | `bool` | True if fixed price, false otherwise |
