# Default RWA Underlying

> Markdown export of the Gearbox Protocol documentation page for agents and retrieval systems.

Canonical page: https://docs.gearbox.finance/developers/default-rwa-underlying
Source file: content/developers/default-rwa-underlying.mdx
Section router: https://docs.gearbox.finance/developers/llms.txt
Section full export: https://docs.gearbox.finance/developers/llms-full.txt

[`DefaultRWAUnderlying`](https://github.com/Gearbox-protocol/periphery-v3/blob/main/contracts/rwa/DefaultRWAUnderlying.sol) is a 1:1 ERC-4626 wrapper used as the underlying token of a Gearbox RWA pool. It connects the pool to borrower-level compliance controls without applying those controls to ordinary liquidity providers.

## Purpose

RWA markets may need to freeze a borrower's Credit Account while preserving normal pool operations for LPs. `DefaultRWAUnderlying` provides the token-level enforcement point for that boundary.

The wrapper exists primarily to block token movements involving a frozen Credit Account, including movements used during liquidation. Other operations on a frozen Credit Account are blocked by the configured RWA factory.

It does not represent the borrower's RWA collateral. For example, Securitize DS tokens are held on the borrowing side of the market, while LPs interact with USDC, `DefaultRWAUnderlying`, and Gearbox pool shares.

## ERC-4626 behavior

The wrapper uses the standard ERC-4626 interface:

- `deposit` and `mint` wrap USDC;
- `withdraw` and `redeem` return USDC; and
- conversions between USDC and wrapper shares are fixed at 1:1.

```solidity
uint256 wrapperShares = rwaUnderlying.previewDeposit(usdcAmount);
uint256 usdcOut = rwaUnderlying.previewRedeem(wrapperShares);
```

The Gearbox pool has a separate exchange rate between `DefaultRWAUnderlying` and pool shares. See [RWA Pool Deposits and Withdrawals](https://docs.gearbox.finance/developers/rwa-pool-integration) for the complete integration flow.

## Freeze scope

Before a wrapper-token transfer, `DefaultRWAUnderlying` checks both the sender and recipient against its configured RWA factory. The transfer reverts only if an address is both:

1. a Credit Account registered by that factory; and
2. marked as frozen by the factory.

This check is applied to the transfer's `from` and `to` addresses. See [`_beforeTokenTransfer` and `_revertIfFrozenCreditAccount`](https://github.com/Gearbox-protocol/periphery-v3/blob/2a63cf27b458c9c3b7824086da32f9dd6ee73613/contracts/rwa/DefaultRWAUnderlying.sol#L62-L70) in the implementation.

## Freeze authority and storage

`DefaultRWAUnderlying` does not define a freezer role and does not store frozen addresses. It stores only an immutable reference to its configured RWA factory.

In the Securitize implementation, [`SecuritizeRWAFactory`](https://github.com/Gearbox-protocol/periphery-v3/blob/main/contracts/rwa/SecuritizeRWAFactory.sol) inherits `Ownable2Step`. Its constructor receives a `securitizeAdmin` address and sets that address as the initial factory owner. The active factory owner is the only address authorized to call:

- `setCreditAccountFrozenStatus` for one Credit Account;
- `setAllCreditAccountsFrozenStatus(investor, frozen)` for all accounts belonging to an investor; or
- `setAllCreditAccountsFrozenStatus(creditManager, investor, frozen)` for an investor's accounts in one Credit Manager.

Ownership can subsequently be transferred through the factory's two-step ownership process. There is no separately assigned freezer role.

The state is stored in the factory's Credit Account mapping:

```solidity
mapping(address creditAccount => CreditAccountInfo) internal _creditAccountInfo;

struct CreditAccountInfo {
    address wallet;
    address investor;
    bool frozen;
}
```

The relevant storage and authority boundary is:

| Item | Contract | Location |
|---|---|---|
| Active freeze authority | `SecuritizeRWAFactory` | inherited `owner()` state |
| Frozen status | `SecuritizeRWAFactory` | `_creditAccountInfo[creditAccount].frozen` |
| Factory used for checks | `DefaultRWAUnderlying` | immutable `_FACTORY` reference |

When wrapper tokens move, `DefaultRWAUnderlying` calls `isCreditAccount(account)` and `isFrozen(account)` on that factory. It does not copy the frozen status into its own storage.

## LPs do not require KYC

An ordinary LP address and the Gearbox pool are not registered borrower Credit Accounts. Consequently, the additional logic in `DefaultRWAUnderlying`:

- does not create an LP allowlist;
- does not require LP identity registration or KYC; and
- does not provide a mechanism for marking an arbitrary LP address as frozen.

LPs use the standard ERC-4626 deposit and redemption methods. Borrower compliance is handled separately at the Credit Account level.


This boundary applies to the additional freeze logic in `DefaultRWAUnderlying`. It does not remove controls or risks that exist outside the wrapper, such as issuer-level controls in USDC, a paused Gearbox pool, or insufficient pool liquidity for an immediate withdrawal.


## Contract relationships

An integration can verify the wrapper and pool relationship onchain:

```solidity
require(rwaUnderlying.asset() == usdcAddress, "RWA underlying asset is not USDC");
require(rwaUnderlying.getFactory() == rwaFactoryAddress, "Unexpected RWA factory");
require(pool.asset() == address(rwaUnderlying), "Unexpected pool underlying");
```

The factory controls borrower Credit Account registration and frozen status. The wrapper only reads that state when enforcing transfers; it does not maintain a separate freeze list.

## See also

- [RWA Pool Deposits and Withdrawals](https://docs.gearbox.finance/developers/rwa-pool-integration)
- [`DefaultRWAUnderlying.sol`](https://github.com/Gearbox-protocol/periphery-v3/blob/main/contracts/rwa/DefaultRWAUnderlying.sol)
- [`IRWAUnderlying.sol`](https://github.com/Gearbox-protocol/periphery-v3/blob/main/contracts/interfaces/base/IRWAUnderlying.sol)
- [`IRWAFactory.sol`](https://github.com/Gearbox-protocol/periphery-v3/blob/main/contracts/interfaces/base/IRWAFactory.sol)
