# bUSD0 (formerly USD0++)

## High-Level Overview

This smart contract manages a bond financial instrument for the UsualDAO ecosystem. It provides functionality for minting, transferring, and unstaking the liquid token. The contract complies with ERC20 standards and allows users to deposit USD0 into bUSD0 or acquire it on the secondary market.

bUSD0 (Bond USD0) represents USD0 stablecoin locked until June 11, 2028. It remains transferable during this period, earning USUAL incentives and maturity yield. Users receive 1 USD0 for 1 bUSD0 at maturity. For early redemption, users need an equivalent amount of rt-USD0 - received at mint - which unlocks bUSD0 back into USD0 at a 1:1 rate anytime. Additionally, early redemption below peg can be made at a DAO set price floor.

### **Minting bUSD0 (formerly USD0++)**

Users can stake their USD0 to convert them into bUSD0 (formerly USD0++). The issuance of bUSD0 (formerly USD0++) follows a 1:1 ratio with the staked USD0. Once staked, the assets remain immobilized for the maturity period of the bUSD0 (formerly USD0++) liquid stake, ensuring stability and predictability.

**Staking and Issuance**

* **Locking USD0**: Users stake their USD0 to mint bUSD0 (formerly USD0++).
* **1:1 Issuance**: bUSD0 (formerly USD0++) is issued on a 1:1 basis with the locked USD0.
* **Locked Duration**: Assets are locked for the maturity period of the bUSD0 (formerly USD0++) liquid staking token.
* **Locking USD0**: Users deposit their USD0 to mint bUSD0 (formerly USD0++).
* **1:1 Issuance**: Both bUSD0 (formerly USD0++) and rt-bUSD0 are issued on a 1:1 basis with the deposited USD0.
  * **Dual Token System**:
    * **bUSD0 (formerly USD0++)**: The bond asset token, transferable and composable.
    * **rt-bUSD0**: The redemption token asset, required alongside bUSD0 to reconstruct the bond back to USD0.
* **Locked Duration**: Assets are locked for the maturity period of the USD0++.

**Reconstructing Bonds**

Users can reconstruct (destroy) their bonds by burning both bUSD0 (formerly USD0++) and rt-bUSD0 tokens together to receive the underlying USD0 back. This process requires equal amounts of both tokens and can be done at any time before maturity.

* **Reconstruction Process**: Users burn equal amounts of bUSD0 (formerly USD0++) and rt-bUSD0 tokens to receive USD0 at a 1:1 ratio.
* **Token Requirements**: Both bUSD0 (formerly USD0++) and rt-bUSD0 tokens must be present in equal amounts to reconstruct the bond.

### Floor Price Mechanism

bUSD0 (formerly USD0++) includes a floor price mechanism, allowing users to unstake their bUSD0 (formerly USD0++) for USD0 at a guaranteed minimum rate.

* `updateFloorPrice(uint256 newFloorPrice)`: Allows authorized admins to update the floor price. Only callable by the `FLOOR_PRICE_UPDATER_ROLE` role.
* `unlockUsd0ppFloorPrice(uint256 usd0ppAmount)`: Allows users to unstake their bUSD0 (formerly USD0++) at the current floor price.

### USUAL Fee Mechanism

bUSD0 (formerly USD0++) includes an early redemption mechanism that allows users to unlock their bUSD0 (formerly USD0++) before maturity by transferring USUAL tokens. The amount of USUAL required for redemption is dynamically calculated based on several factors:

#### Key Functions

* `unlockUSD0ppWithUsual(uint256 usd0ppAmount, uint256 maxUsualAmount)`: Allows users to redeem bUSD0 (formerly USD0++) by transferring USUAL tokens
* `unlockUSD0ppWithUsualWithPermit(...)`: Same as above but includes permit functionality for gasless approvals
* `calculateRequiredUsual(uint256 usd0ppAmount)`: Calculates the amount of USUAL needed to redeem a given amount of bUSD0 (formerly USD0++)
* `sweepFees()` : Callable only by the `FEE_SWEEPER_ROLE` and transfers the accumulated USUAL fees to the distribution module

#### Calculation Factors

The required USUAL amount is determined by:

1. Base Distribution Rate: Amount of USUAL distributed per bUSD0 (formerly USD0++) per day
2. Duration Cost: Adjusts cost based on time window
3. Net Outflows: Considers weekly redemption volume

#### Parameters (Configurable by governance)

* `usualDistributionPerUsd0pp`: Base USUAL distribution rate (per bUSD0, formerly USD0++)
* `durationCostFactor`: Multiplier for time-based cost adjustment
* `targetRedemptionRate`: Target weekly redemption rate (in basis points of total supply)

#### Example Flow

1. User calls `calculateRequiredUsual()` to determine USUAL cost
2. User approves USUAL spend (or uses permit)
3. User calls `unlockUSD0ppWithUsual()` with desired bUSD0 (formerly USD0++) amount and maximum USUAL willing to transfer
4. Contract receive portion of USUAL, increment `accumulatedFees` variable, and returns USD0 to user

The mechanism helps maintain protocol stability by adjusting costs based on redemption volume and ensuring controlled unwinding of bUSD0 (formerly USD0++) positions.

### Peg Maintainer

* `unwrapPegMaintainer(uint256 amount)`: Allows peg maintainers to unwrap liquid staking tokens at any time. Only callable by the `PEG_MAINTAINER_ROLE` role.

### Early Unlock Period

The contract includes functionality for a temporary early unlock period, allowing users to unwrap their liquid staking tokens before the full maturity period under certain conditions. This is a temporary mechanism specifically related to the airdrop

* `setupEarlyUnlockPeriod(uint256 bondEarlyUnlockStart, uint256 bondEarlyUnlockEnd)`: Sets up the early unlock period. Only callable by the `EARLY_BOND_UNLOCK_ROLE` role.
* `temporaryOneToOneExitUnwrap(uint256 amountToUnwrap)`: Allows users to unwrap their bonds during the early unlock period. This voids any USUAL airdrop that they are entitled to
* `allocateEarlyUnlockBalance(address[] calldata addressesToAllocateTo, uint256[] calldata balancesToAllocate)`: Allocates early unlock balances to specific addresses that have accumulated potential airdrop rewards. Only callable by the `EARLY_BOND_UNLOCK_ROLE` role.

### **Regulatory Compliance**

The contract includes a blacklist feature to ensure regulatory compliance. Sanctioned addresses are prevented from interacting with the contract and are kept up to date.

### **Functionality Breakdown**

The contract flow begins with the initialization of liquid staking token parameters and related registry and token information. Liquid staking tokens can be minted, transferred, and unstaked. The contract also allows for emergency withdrawals of the underlying token.

### **Functions Description**

#### **Public/External Functions (non-view / non-pure)**

* `pause()`: Pauses all token transfer operations; callable only by the `PAUSING_CONTRACTS_ROLE`.
* `unpause()`: Resumes all token transfer operations; callable only by the `DEFAULT_ADMIN_ROLE`.
* `setupEarlyUnlockPeriod(uint256 bondEarlyUnlockStart, uint256 bondEarlyUnlockEnd)`: Sets up the early unlock period. Only callable by the `EARLY_BOND_UNLOCK_ROLE` role.
* `mint(uint256 amountUsd0)`: Mints new bonds by locking the specified amount of collateral token.
* `mint(uint256 amountUsd0, address bAssetRecipient, address rAssetRecipient)`: Mints new bonds by locking the specified amount of collateral token. bUSD0 (formerly USD0++) tokens are sent to `bAssetRecipient` and rt-bUSD0 tokens are sent to `rAssetRecipient`, both in a 1:1 ratio with the locked USD0.
* `mintWithPermit(uint256 amountUsd0, uint256 deadline, uint8 v, bytes32 r, bytes32 s)`: Mints new bonds with a permit signature.
* `unwrap()`: Unwraps the bonds and transfers the underlying collateral token to the user.
* `temporaryOneToOneExitUnwrap(uint256 amountToUnwrap)`: Allows users to unwrap their bonds during the early unlock period.
* `allocateEarlyUnlockBalance(address[] calldata addressesToAllocateTo, uint256[] calldata balancesToAllocate)`: Allocates early unlock balances to specific addresses. Only callable by the `EARLY_BOND_UNLOCK_ROLE` role.
* `unwrapPegMaintainer(uint256 amount)`: Allows peg maintainers to unwrap bonds at any time. Only callable by the `PEG_MAINTAINER_ROLE` role.
* `triggerPARMechanismCurvepool(uint256 parUsd0Amount, uint256 minimumPARMechanismGainedAmount)`: Triggers the PAR mechanism in the Curve pool.
* `emergencyWithdraw(address safeAccount)`: Allows for the emergency withdrawal of the underlying collateral token.
* `updateFloorPrice(uint256 newFloorPrice)`: Allows authorized users to update the floor price. Only callable by the `FLOOR_PRICE_UPDATER_ROLE` role.
* `unlockUsd0ppFloorPrice(uint256 usd0ppAmount)`: Allows users to unlock their bUSD0 (formerly USD0++) at the current floor price.
* `transfer(address recipient, uint256 amount)`: Transfers bonds from the sender to the recipient.
* `transferFrom(address sender, address recipient, uint256 amount)`: Transfers bonds from the sender to the recipient on behalf of the sender.

#### View Functions

* `totalBondTimes()`: Returns the total staking duration.
* `getBondEarlyUnlockDisabled(address user)`: Checks if early unlock is disabled for a user.
* `getStartTime()`: Returns the start time of the staking period.
* `getEndTime()`: Returns the end time of the staking period.
* `getFloorPrice()`: Returns the current floor price.
* `getTemporaryUnlockStartTime()`: Returns the start time of the temporary unstaking period.
* `getTemporaryUnlockEndTime()`: Returns the end time of the temporary unstaking period.
* `getAllocationEarlyUnlock(address addressToCheck)`: Returns the early unstaking allocation for an address.
* `getAccumulatedFees()`: Returns the amount of accumulated fees in USUAL of the contract.


---

# 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/token-contracts/usd0++.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.
