# USD0a Reverse Gateway

### High-Level Overview <a href="#high-level-overview" id="high-level-overview"></a>

The ReverseGateway contract is a fully permissioned smart contract designed to manage intermediary treasury operations between the protocol's collateral treasury and external collateral services such as Superstate. The contract facilitates the conversion of USCC tokens (from Superstate) to USDC tokens (from Circle) through an order-based tracking system, enabling the protocol to rebalance treasury collaterals efficiently.

The main objective of the ReverseGateway contract is to provide a secure and controlled mechanism for interacting with external collateral services while maintaining USD0a price stability through the DebtUSCC token system. When the protocol needs to switch some USCC to USDC, the ReverseGateway manages these operations by tracking deposits and withdrawals through orders. Critically, the ReverseGateway mints DebtUSCC tokens when USCC is sent to Superstate to prevent USD0a price from decreasing while waiting for USDC, since USD0a price depends on the amount of collaterals in the treasury.

**Key Use Case**: The ReverseGateway is primarily used for treasury rebalancing operations in the opposite direction of the Gateway. For example, if the protocol wants to convert USCC to USDC, an authorized operator can deposit USCC through the ReverseGateway, which transfers the USCC to the Superstate contract. The ReverseGateway then mints DebtUSCC tokens (1:1 with the USCC amount) to maintain USD0a price stability. This is critical because USD0a price depends on the amount of collaterals in the treasury. Without minting DebtUSCC, the USD0a price would decrease when USCC is sent to Superstate (reducing treasury collateral) while waiting for USDC. By minting DebtUSCC, the protocol maintains the accounting balance, preventing USD0a price from decreasing during the conversion process. When USDC is received from Superstate, the operator can withdraw through the ReverseGateway, which burns the corresponding DebtUSCC tokens and transfers the USDC to the collateral treasury, replacing the debt token with actual collateral.

**Important Difference from Gateway**: Unlike the Gateway contract which allows multiple concurrent deposits, the ReverseGateway enforces a single deposit at a time policy. This is implemented through an `ongoingDeposit` flag that prevents new deposits while a previous deposit is still being processed. This design ensures that only one conversion operation is active at any given time, which is critical for maintaining consistent pricing of the DebtUSCC token. By allowing only one deposit at a time, the protocol ensures that all DebtUSCC tokens are minted at a consistent price point (captured via the USCC oracle roundId), preventing price inconsistencies that could arise from multiple concurrent deposits at different price points. Additionally, this constraint simplifies the withdrawal process and reduces complexity in managing multiple concurrent orders.

### Contract Summary <a href="#contract-summary" id="contract-summary"></a>

The contract provides the following main functions:

* **deposit**: Allows authorized users to deposit USCC tokens, transfer them to the Superstate contract, and create a tracking order. This function also mints DebtUSCC tokens (1:1 with USCC) to the collateral treasury to maintain USD0a price stability. Without this minting, the USD0a price would decrease because it depends on the amount of collaterals in the treasury, and USCC is temporarily reduced while waiting for USDC. The function captures the USCC oracle roundId at the time of deposit for price tracking purposes. **Only one deposit can be active at a time** - if an ongoing deposit exists, the function will revert.
* **withdraw**: Allows authorized users to withdraw USDC tokens by burning the corresponding DebtUSCC tokens for the last (most recent) order. The function accepts a `usdcAmount` parameter because the exact amount received from Superstate cannot be predicted. After processing the withdrawal, the `ongoingDeposit` flag is reset to false, allowing new deposits.
* **emergencyWithdraw**: Provides an emergency mechanism to recover tokens that may have been accidentally sent to the contract.
* **setSuperstateAddress**: Allows authorized users to update the Superstate contract address, enabling the protocol to adapt to contract upgrades or migrations.

The contract also includes utility functions such as `getOrder`, `getNextOrderId`, `superstate`, `collateralTreasury`, `usccOracle`, `usdcToken`, `usccToken`, and `debtUSCC` to retrieve order details and contract configuration.

The ReverseGateway uses an order-based system to track deposits and withdrawals. Each deposit creates an order that stores the USCC amount, active status, timestamp, and the USCC oracle roundId at the time of deposit. Orders are deactivated during withdrawal to prevent double-spending. The DebtUSCC token system ensures that USD0a price stability is maintained during collateral conversion operations. When USCC is sent to Superstate, the treasury temporarily loses collateral, which would cause USD0a price to decrease. By minting DebtUSCC tokens (1:1 with the USCC amount), the protocol maintains the accounting balance, preventing USD0a price from decreasing while waiting for USDC. When USDC is received and DebtUSCC is burned, the actual collateral replaces the debt token.

### Inherited Contracts <a href="#inherited-contracts" id="inherited-contracts"></a>

* **Initializable (OZ)**: Used to provide a safe and controlled way to initialize the contract's state variables. It ensures that the contract's initializer function can only be called once, preventing accidental or malicious reinitialization.
* **ReentrancyGuardUpgradeable (OZ)**: Used to protect against reentrancy attacks. It provides a modifier that can be applied to functions to prevent them from being called recursively or from being called from other functions that are also protected by the same guard.
* **PausableUpgradeable (OZ)**: Allows contract functionality to be paused by authorized accounts (PAUSING\_CONTRACTS\_ROLE to pause the contract and UNPAUSING\_CONTRACTS\_ROLE to unpause).

### Functionality Breakdown <a href="#functionality-breakdown" id="functionality-breakdown"></a>

The ReverseGateway contract's primary purpose is to facilitate treasury rebalancing operations by managing interactions with external collateral services in the reverse direction (USCC to USDC). The contract's functionality can be broken down into the following key components:

#### Order Creation (Deposit): <a href="#order-creation-deposit" id="order-creation-deposit"></a>

* Users with the `GATEWAY_DEPOSIT_ROLE` can create new orders by calling the `deposit` function and specifying the amount of USCC tokens to deposit.
* The contract validates that no ongoing deposit exists. If an `ongoingDeposit` flag is set to true, the function will revert with an `OngoingDeposit` error, ensuring only one deposit can be processed at a time.
* The contract captures the current USCC oracle roundId by calling `latestRoundData()` on the USCC oracle. This roundId is stored in the order for price tracking and audit purposes.
* The contract transfers the specified amount of USCC tokens from the caller directly to the Superstate contract (not to the ReverseGateway contract itself).
* The contract creates a new order with a unique order ID, storing the USCC amount, active status (set to true), the current block timestamp, and the captured oracle roundId.
* The contract mints DebtUSCC tokens (1:1 with the USCC amount) to the collateral treasury. The debt token maintains the accounting balance until USDC is received and replaces it.
* The order is assigned a unique order ID (starting from 1) and stored in the contract's orders mapping.
* The `ongoingDeposit` flag is set to true to prevent concurrent deposits.

#### Order Fulfillment (Withdraw): <a href="#order-fulfillment-withdraw" id="order-fulfillment-withdraw"></a>

* Users with the `GATEWAY_WITHDRAW_ROLE` can fulfill the most recent order by calling the `withdraw` function and specifying the amount of USDC tokens to withdraw.
* The contract automatically processes the last order (identified by `nextOrderId - 1`), ensuring that orders are fulfilled in a first-in-first-out manner.
* The contract validates that the last order is active and exists. If the order is not active, the function will revert with an `OrderNotActive` error.
* The contract deactivates the order (sets `active` to false) to prevent double-spending.
* The contract burns DebtUSCC tokens from the collateral treasury (1:1 with the order's USCC amount). This clears the protocol's obligation for the fulfilled order.
* The contract transfers the specified amount of USDC tokens from the ReverseGateway contract to the collateral treasury.
* The `ongoingDeposit` flag is set to false, allowing new deposits to be processed.
* **Important**: The `usdcAmount` parameter is provided by the caller because the exact amount of USDC received from Superstate cannot be predicted in advance. This allows the protocol to handle variable exchange rates, fees, or other factors that may affect the final amount received from external services.

#### DebtUSCC Accounting: <a href="#debtuscc-accounting" id="debtuscc-accounting"></a>

The ReverseGateway uses the DebtUSCC token system to maintain USD0a price stability during collateral conversion operations. When USCC is deposited and sent to Superstate, the treasury temporarily loses USCC collateral. Since USD0a price depends on the amount of collaterals in the treasury, this reduction would cause USD0a price to decrease. To prevent this, DebtUSCC tokens are minted (1:1 with the USCC amount) to maintain the accounting balance. This ensures that USD0a price remains stable while waiting for USDC from Superstate. When USDC is received and withdrawn, the corresponding DebtUSCC tokens are burned, and the actual USDC collateral replaces the debt token. This mechanism ensures that USD0a price stability is maintained throughout the entire conversion process, even when interacting with third-party services that may have processing delays.

#### Oracle Integration: <a href="#oracle-integration" id="oracle-integration"></a>

The ReverseGateway integrates with a USCC oracle (IAggregator) to capture price information at the time of deposit. During the deposit process, the contract calls `latestRoundData()` on the USCC oracle and stores the `roundId` in the order. This allows the protocol to track the USCC price at the time of deposit, which can be useful for auditing, price verification, and ensuring fair conversions. The oracle address is set during initialization and can be queried through the `usccOracle()` getter function.

#### External Integration: <a href="#external-integration" id="external-integration"></a>

The ReverseGateway integrates with the Superstate contract for USCC transfers and USDC redemptions. USCC (from Superstate) is transferred directly to the Superstate contract during deposits, and USDC is expected to be received from Superstate before withdrawals can be processed.

### Security Analysis <a href="#security-analysis" id="security-analysis"></a>

#### Method: deposit <a href="#method-deposit" id="method-deposit"></a>

This method allows authorized users to deposit USCC tokens, transfer them to the Superstate contract, create a tracking order, and mint DebtUSCC tokens to the collateral treasury.

**Function Description:**

* The function is protected against reentrancy attacks by using the `nonReentrant` modifier, ensuring that the function cannot be called recursively or from other functions that are also protected by the same guard.
* The function is protected by the `whenNotPaused` modifier, ensuring that deposits cannot be made when the contract is paused.
* Validates that the USCC amount is greater than zero.
* Validates that the caller has the `GATEWAY_DEPOSIT_ROLE` using role-based access control.
* **Validates that no ongoing deposit exists** by checking the `ongoingDeposit` flag. If an ongoing deposit is in progress, the function will revert with an `OngoingDeposit` error. This ensures only one deposit can be processed at a time.
* Sets the `ongoingDeposit` flag to true to prevent concurrent deposits.
* Sets the value of `orderId` to the current value of `$.nextOrderId` then increments by 1. Since it is initialized as 1, the first orderId will be one and so on.
* Captures the current USCC oracle roundId by calling `latestRoundData()` on the USCC oracle. This roundId is stored in the order for price tracking purposes.
* Creates a new `ReverseGatewayOrder` struct in storage using the order ID as key. The struct contains: the USCC amount, the active flag set to true, the current block timestamp, and the captured oracle roundId.
* Transfers the specified amount of USCC tokens from the caller directly to the Superstate contract (not to the ReverseGateway contract) using `safeTransferFrom` to ensure that the transfer is successful. If the transfer fails, the function will revert.
* Mints DebtUSCC tokens (1:1 with the USCC amount) to the collateral treasury. This is critical for maintaining USD0a price stability. Since USD0a price depends on the amount of collaterals in the treasury, and USCC is temporarily reduced while waiting for USDC from Superstate, minting DebtUSCC prevents the USD0a price from decreasing during the conversion process. The debt token maintains the accounting balance until USDC is received and replaces it.
* Emits a `Deposit` event, providing the caller address, order ID, and USCC amount for tracking.

#### Method: withdraw <a href="#method-withdraw" id="method-withdraw"></a>

This method allows authorized users to withdraw USDC tokens by burning the corresponding DebtUSCC tokens for the last (most recent) order and transferring USDC to the collateral treasury.

**Function Description:**

* The function is protected against reentrancy attacks by using the `nonReentrant` modifier.
* The function is protected by the `whenNotPaused` modifier, ensuring that withdrawals cannot be made when the contract is paused.
* Validates that the USDC amount is greater than zero.
* Validates that the caller has the `GATEWAY_WITHDRAW_ROLE` using role-based access control.
* Automatically selects the last order (identified by `$.nextOrderId - 1`) for processing. This ensures that orders are fulfilled in a first-in-first-out manner and simplifies the withdrawal process compared to the Gateway contract which processes multiple orders.
* Validates that the last order is active. If the order is not active or does not exist, the function will revert with an `OrderNotActive` error. This prevents any attempts to withdraw from invalid or already processed orders.
* Deactivates the order by setting the `active` flag to false in storage. This prevents double-spending and ensures that orders can only be processed once.
* Burns DebtUSCC tokens from the collateral treasury (1:1 with the order's USCC amount). This clears the protocol's obligation for the fulfilled order and ensures proper accounting.
* Transfers the specified amount of USDC tokens from the ReverseGateway contract to the collateral treasury using the `safeTransfer` function. This ensures that the transfer is successful. If the transfer fails, the function will revert.
* Sets the `ongoingDeposit` flag to false, allowing new deposits to be processed.
* **Important**: The `usdcAmount` parameter is provided by the caller because the exact amount of USDC received from Superstate cannot be predicted in advance. This allows the protocol to handle variable exchange rates, fees, or other factors that may affect the final amount received from external services.
* Emits a `Withdraw` event, providing the caller address, order ID (the last order), USCC amount from the order, and USDC amount for tracking.

#### Method: emergencyWithdraw <a href="#method-emergencywithdraw" id="method-emergencywithdraw"></a>

This method provides an emergency mechanism to recover tokens that may have been accidentally sent to the ReverseGateway contract.

**Function Description:**

* The function is protected against reentrancy attacks by using the `nonReentrant` modifier.
* Validates that the token address is not the zero address.
* Validates that the recipient address is not the zero address.
* Validates that the amount is greater than zero.
* Validates that the caller has the `EMERGENCY_WITHDRAW_ROLE` using role-based access control.
* Transfers the specified amount of tokens from the ReverseGateway contract to the recipient using the `safeTransfer` function. This ensures that the transfer is successful. If the transfer fails, the function will revert.
* Emits an `EmergencyWithdraw` event, providing the token address, amount, and recipient for tracking.

#### Method: setSuperstateAddress <a href="#method-setsuperstateaddress" id="method-setsuperstateaddress"></a>

This method allows authorized users to update the Superstate contract address, enabling the protocol to adapt to contract upgrades or migrations.

**Function Description:**

* Validates that the new Superstate address is not the zero address.
* Validates that the new Superstate address is different from the current address to prevent unnecessary state changes.
* Validates that the caller has the `GATEWAY_SUPERSTATE_SETTER_ROLE` using role-based access control.
* Updates the Superstate address in storage.
* Emits a `SuperstateUpdated` event, providing the old and new Superstate addresses for tracking.

### Getter Functions <a href="#getter-functions" id="getter-functions"></a>

* **getOrder**: Returns the details of a specific order including USCC amount, active status, timestamp, and the USCC oracle roundId captured at deposit time.
* **getNextOrderId**: Returns the next order ID that will be assigned.
* **superstate**: Returns the current Superstate contract address.
* **collateralTreasury**: Returns the current collateral treasury address.
* **usccOracle**: Returns the current USCC oracle contract address.
* **usdcToken**: Returns the current USDC token contract address.
* **usccToken**: Returns the current USCC token contract address.
* **debtUSCC**: Returns the current DebtUSCC token contract address.

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

* **CONTRACT\_REGISTRY\_ACCESS**: Address of the registry access contract.
* **CONTRACT\_TREASURY**: Address of the collateral treasury contract.
* **GATEWAY\_DEPOSIT\_ROLE**: Role identifier for depositing USCC and creating orders.
* **GATEWAY\_WITHDRAW\_ROLE**: Role identifier for withdrawing USDC and fulfilling orders.
* **EMERGENCY\_WITHDRAW\_ROLE**: Role identifier for emergency token recovery.
* **GATEWAY\_SUPERSTATE\_SETTER\_ROLE**: Role identifier for updating the Superstate address.
* **PAUSING\_CONTRACTS\_ROLE**: Role identifier for pausing contract operations.
* **UNPAUSING\_CONTRACTS\_ROLE**: Role identifier for unpausing contract operations.

### Safeguards Implementation <a href="#safeguards-implementation" id="safeguards-implementation"></a>

* **Pausability**: Allows pausing of contract functionality in emergencies. The contract can be paused by `PAUSING_CONTRACTS_ROLE` and unpaused by `UNPAUSING_CONTRACTS_ROLE`.
* **Reentrancy Protection**: Uses OpenZeppelin's ReentrancyGuard to prevent reentrancy attacks. All state-changing functions are protected with the `nonReentrant` modifier.
* **Access Control**: Restricts sensitive operations to authorized roles. Deposit operations require `GATEWAY_DEPOSIT_ROLE`, withdrawal operations require `GATEWAY_WITHDRAW_ROLE`, emergency withdrawals require `EMERGENCY_WITHDRAW_ROLE`, and Superstate address updates require `GATEWAY_SUPERSTATE_SETTER_ROLE`.
* **Amount Validation**: Validates that amounts are non-zero before processing operations.
* **Order Validation**: Validates that the last order is active before processing withdrawals, preventing attempts to process invalid or already processed orders.
* **Null Address Checks**: Validates that all addresses (registry, Superstate, tokens, oracle, recipient) are not the zero address before processing operations.
* **Order Deactivation**: Deactivates orders during withdrawal to prevent double-spending and ensure that orders can only be processed once.
* **Single Deposit Constraint**: Enforces that only one deposit can be active at a time through the `ongoingDeposit` flag. This prevents concurrent deposits, ensuring consistent DebtUSCC token pricing by maintaining a single price point for all outstanding debt tokens, and simplifies the withdrawal process.
* **SafeERC20**: Uses SafeERC20 for all token transfers to prevent failures from going unnoticed and to handle non-standard ERC20 implementations safely.
* **Storage Safety**: Uses ERC-7201 namespaced storage pattern (`ReverseGatewayStorageV0`) to prevent storage collisions during upgrades. The contract is upgradeable via UUPS proxy pattern.
* **Same Value Protection**: Prevents unnecessary state changes by validating that the new Superstate address is different from the current address before updating.
* **Oracle Integration**: Captures and stores the USCC oracle roundId at deposit time for price tracking and audit purposes, ensuring transparency in the conversion process.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://tech.usual.money/smart-contracts/protocol-contracts/usd0a/usd0a-reverse-gateway.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
