# FW Tokens

{% hint style="info" %}
**Source:** `src/fira_bonding/StandardizedYield/FWBase.sol`, `src/fira_bonding/StandardizedYield/implementations/USDCFW.sol`
{% endhint %}

## FWBase

Abstract base that all FW tokens inherit. Extends `FiraERC20Permit`, `TokenHelper`, `BoringOwnableUpgradeable`, and `Pausable`.

### Deposit flow

1. Validate input token via `isValidTokenIn`
2. Transfer tokens in via `_transferIn`
3. Call `_deposit(tokenIn, amount)` — abstract, implemented by derived contracts
4. Mint FW shares to receiver
5. Check `minSharesOut` slippage guard

### Redeem flow

1. Validate output token via `isValidTokenOut`
2. Burn FW shares (or from `address(this)` if `burnFromInternalBalance`)
3. Call `_redeem(receiver, tokenOut, shares)` — abstract
4. Check `minTokenOut` slippage guard

### Pause controls

Three independent mechanisms: `depositsPaused`, `redemptionsPaused`, and global `pause()` (blocks all transfers).

## USDCFW

The production FW implementation. Wraps USDC and earns yield by deploying a portion into an ERC-4626 vault.

### State

* `yieldToken` — USDC address (immutable)
* `vault` — ERC-4626 vault (immutable)
* `idleAssets` / `vaultShares` — Tracked explicitly to prevent donation-based manipulation

### Exchange rate

```
exchangeRate = totalUnderlying / totalSupply
```

Where `totalUnderlying = idleAssets + vault.convertToAssets(vaultShares)`.

### Deposit

USDC deposits are added to `idleAssets`. Vault share deposits are converted to equivalent USDC. First deposit mints 1:1. The market is seeded on deployment to prevent ERC-4626 inflation attacks.

### Redeem

Draws from idle USDC first, then from the vault if needed, minimizing gas costs.

### Rehypothecation

`triggerRehypothecation()` (permissionless) and `forceRehypothecation()` (owner-only) rebalance between idle and vault based on the RehypothecationModule parameters.
