> For the complete documentation index, see [llms.txt](https://azoth.gitbook.io/azoth-tech-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://azoth.gitbook.io/azoth-tech-docs/smart-contracts/protocol-contracts.md).

# Protocol Contracts

[Git Source](https://github.com/narnona/Azoth-Contract/blob/c9566d1ec47c47ab29f27f1d908a7bca0993f09e/src/Azoth.sol)

**Inherits:**\
UUPSUpgradeable, Ownable2StepUpgradeable, PausableUpgradeable, IAzoth

## State Variables

### FEE\_DENOMINATOR

```solidity
uint256 private constant FEE_DENOMINATOR = 1_000_000;
```

### usdt

**Note:**\
oz-upgrades-unsafe-allow: state-variable-immutable

```solidity
address private immutable usdt;
```

### factory

**Note:**\
oz-upgrades-unsafe-allow: state-variable-immutable

```solidity
address public immutable factory;
```

### nftManager

**Note:**\
oz-upgrades-unsafe-allow: state-variable-immutable

```solidity
address public immutable nftManager;
```

### curvePoolManager

**Note:**\
oz-upgrades-unsafe-allow: state-variable-immutable

```solidity
address public immutable curvePoolManager;
```

### AzothStorageLocation

*keccak256(abi.encode(uint256(keccak256("AZOTH.storage.Azoth")) - 1)) & \~bytes32(uint256(0xff))*

```solidity
bytes32 private constant AzothStorageLocation = 0xd7401a6cf1440e8507caa1dba74ad41933fbb7724fa29b58c7f6cc5cd0696f00;
```

## Functions

### constructor

**Note:**\
oz-upgrades-unsafe-allow: constructor

```solidity
constructor(address _usdt, address _factory, address _nftManager, address _curvePoolManager);
```

### initialize

```solidity
function initialize(address _feeRecipient) public initializer;
```

### newRWA

This function enables the owner to add or support a new Real-World Asset (RWA). Specifically, the process involves the following steps: 1) Deployment of the wRWA contract; 2) Deployment of the vault contract; 3) Creation of a Curve liquidity pool;

*tip1: `_rwa`If it is not zero (no check for duplicate addition, manual attention is required)*

*tip2: `_feePercent`Must not exceed the denominator of the rate (1,000,000)*

*tip3: Trigger event `LOG_NewRWA(address indexed rwa, address wRWA, address rwaVault, address pool)`*

```solidity
function newRWA(
    address _rwa,
    string memory _nameWRWA,
    string memory _symbolWRWA,
    uint256 _feePercent,
    ICurve.DeployPoolParams calldata _params
) external onlyOwner whenNotPaused;
```

**Parameters**

| Name          | Type                      | Description                              |
| ------------- | ------------------------- | ---------------------------------------- |
| `_rwa`        | `address`                 | The address of RWA token                 |
| `_nameWRWA`   | `string`                  | The name of the wRWA token               |
| `_symbolWRWA` | `string`                  | The symbol of the wRWA token             |
| `_feePercent` | `uint256`                 | Transaction fee rate (eg: 450 => 0.045%) |
| `_params`     | `ICurve.DeployPoolParams` | Parameters for Curve Pool creation       |

### depositRWA

This function enables the owner to deposit $RWA tokens and set the mint price.\
It is utilized after the official subscription of RWA from the fund issue company, deposit RWA into the protocol for users to purchase.

*tip1: Both `_amount` and `_mintPrice` are not zero, and the RWA asset corresponding to `_wRWA` has been supported.*

*tip2: `_mintPrice`represents the price of RWA in terms of USDT, with a precision of 6. eg: if the value of 1 RWA is 1 USDT, then `_mintPrice` should be 1000000*

*tip3: The caller needs to approve `_amount`amount of RWA assets to this contract*

*tip4: Trigger event `LOG_DepositRWA(address indexed wRWA, uint256 amount, uint256 mintPrice)`*

```solidity
function depositRWA(address _wRWA, uint256 _amount, uint256 _mintPrice) external onlyOwner whenNotPaused;
```

**Parameters**

| Name         | Type      | Description                                                           |
| ------------ | --------- | --------------------------------------------------------------------- |
| `_wRWA`      | `address` | The wRWA token address corresponding to RWA assets                    |
| `_amount`    | `uint256` | The amount of $RWA deposited                                          |
| `_mintPrice` | `uint256` | The mint price (excluding fees, also known as the subscription price) |

### withdrawRWA

This function is used by the owner to redeem $RWA.\
It is applied to: officially redeem RWA to repay the fund issuers, or reduce the mintable amount of RWA.

*tip1: `_wRWA`The corresponding RWA assets have been paid； `_amountToRepay` and `_amountForOther` cannot both be 0*

*tip2: `_amountToRepay`cannot exceed the user's redemption amount，`_amountForOther`cannot exceed the remaining mintable amount of RWA*

*tip3: Trigger event `LOG_WithdrawRWA(address indexed wRWA, address to, uint256 amount)`*

```solidity
function withdrawRWA(address _wRWA, uint256 _amountToRepay, uint256 _amountForOther) external onlyOwner whenNotPaused;
```

**Parameters**

| Name              | Type      | Description                                                                              |
| ----------------- | --------- | ---------------------------------------------------------------------------------------- |
| `_wRWA`           | `address` | The address of the wRWA token corresponding to RWA assets                                |
| `_amountToRepay`  | `uint256` | The amount of $RWA redeemed for repaying the fund issuance company (redeemed from azoth) |
| `_amountForOther` | `uint256` | For other purposes (redeem from the vault)                                               |

### repayRWA

This function allows the owner to deposit USDT and set the redemption price.\
The function is applied as follows: After repaying the $RWA to the fund issuance company, USDT is deposited to be available for users' redemption.

*tip1: The RWA assets corresponding to `_wRWA` are supported, and both `_amount` and `_redeemPrice` are not zero*

*tip2: The caller needs to approve `_amount` amount of USDT to this contract*

*tip3: \_amount % \_redeemPrice == 0*

*tip4: Trigger event：`LOG_RepayRWA(address indexed wRWA, uint256 amount, uint256 redeemPrice, uint256 usdtAmount)`*

```solidity
function repayRWA(address _wRWA, uint256 _amount, uint256 _redeemPrice) external onlyOwner whenNotPaused;
```

**Parameters**

| Name           | Type      | Description                                                                 |
| -------------- | --------- | --------------------------------------------------------------------------- |
| `_wRWA`        | `address` | The address of the wRWA token corresponding to RWA assets                   |
| `_amount`      | `uint256` | The amount of RWA to be repaid                                              |
| `_redeemPrice` | `uint256` | Redemption price (This redemption price does not take into account the fee) |

### withdrawUSDT

This function is used by the owner to withdraw USDT.\
The function is applied to: the official withdrawal of USDT for repurchasing $RWA.<br>

*tip1: The RWA assets corresponding to `_wRWA` are supported, and `_amount` is not zero*<br>

*tip2: `LOG_WithdrawUSDT(address indexed wRWA, address to, uint256 amount)`*

```solidity
function withdrawUSDT(address _wRWA, uint256 _amount) external onlyOwner whenNotPaused;
```

**Parameters**

| Name      | Type      | Description                                                                    |
| --------- | --------- | ------------------------------------------------------------------------------ |
| `_wRWA`   | `address` | The address of the wRWA token corresponding to RWA assets                      |
| `_amount` | `uint256` | The amount of USDT to be redeemed (there is no limit on the withdrawal amount) |

### setFeeRecipientw

This function allows the Owner to designate the recipient of the transaction fee.

*tip1: `_newFeeRecipient`is not 0*

*tip2: Trigger event `LOG_NewFeeRecipient(address newFeeRecipient)`*

```solidity
function setFeeRecipient(address _newFeeRecipient) external onlyOwner whenNotPaused;
```

**Parameters**

| Name               | Type      | Description       |
| ------------------ | --------- | ----------------- |
| `_newFeeRecipient` | `address` | The new recipient |

### setFeePercent

This function is used by the Owner to set the fee rate for a certain RWA asset.

*tip1: The RWA assets corresponding to `_wRWA` are now supported*

*tip2: `_newFeePercent`must not exceed 1000000*

*tip3: Trigger event `LOG_NewFeePercent(address indexed wRWA, uint256 newFeePercent)`*

```solidity
function setFeePercent(address _wRWA, uint256 _newFeePercent) external onlyOwner whenNotPaused;
```

**Parameters**

| Name             | Type      | Description                                               |
| ---------------- | --------- | --------------------------------------------------------- |
| `_wRWA`          | `address` | The address of the wRWA token corresponding to RWA assets |
| `_newFeePercent` | `uint256` | The new recipient                                         |

### setWRWABlackList

This function is used by the Owner to set the blacklist for the wRWA tokens of RWA.\
Users on the blacklist cannot transfer the tokens (true -> false, false -> true).

*tip1: The RWA assets corresponding to `_wRWA` are now supported.*

```solidity
function setWRWABlackList(address _wRWA, address _user) external onlyOwner whenNotPaused;
```

**Parameters**

| Name    | Type      | Description                                               |
| ------- | --------- | --------------------------------------------------------- |
| `_wRWA` | `address` | The address of the wRWA token corresponding to RWA assets |
| `_user` | `address` | Set the addresses of the users                            |

### addLiquidity

The owner deposits USDT, mints $wRWA, and provides liquidity to the Curve Pool by supplying both USDT and $wRWA tokens.

```solidity
function addLiquidity(address _wRWA, uint256 _amount, uint256 _min_mint_amount)
    public
    onlyOwner
    whenNotPaused
    returns (uint256 lpAmount);
```

**Parameters**

| Name               | Type      | Description                                               |
| ------------------ | --------- | --------------------------------------------------------- |
| `_wRWA`            | `address` | The address of the wRWA token corresponding to RWA assets |
| `_amount`          | `uint256` | The amount of wRWA                                        |
| `_min_mint_amount` | `uint256` | The minimum amount of LP tokens to be obtained            |

**Returns**

| Name       | Type      | Description                       |
| ---------- | --------- | --------------------------------- |
| `lpAmount` | `uint256` | The amount of LP tokens obtained. |

### pendingRemoveLiquidity

This function is used to apply for liquidity removal (with a 7-day delay).*If 3 days have passed since the timestamp, the request is expired and must be renewed.*

```solidity
function pendingRemoveLiquidity(address _wRWA) public onlyOwner whenNotPaused;
```

**Parameters**

| Name    | Type      | Description                                               |
| ------- | --------- | --------------------------------------------------------- |
| `_wRWA` | `address` | The address of the wRWA token corresponding to RWA assets |

### removeLiquidity

This function is used to remove liquidity and save the obtained tokens in the vault.

```solidity
function removeLiquidity(address _wRWA, uint256 _lpAmount, uint256[2] memory _min_amount)
    public
    onlyOwner
    whenNotPaused
    returns (uint256[2] memory receivedToken);
```

**Parameters**

| Name          | Type         | Description                                               |
| ------------- | ------------ | --------------------------------------------------------- |
| `_wRWA`       | `address`    | The address of the wRWA token corresponding to RWA assets |
| `_lpAmount`   | `uint256`    | The amount of LP tokens used to remove liquidity          |
| `_min_amount` | `uint256[2]` | The minimum amount of each token to be obtained           |

**Returns**

| Name            | Type         | Description                              |
| --------------- | ------------ | ---------------------------------------- |
| `receivedToken` | `uint256[2]` | Return the amount of each token obtained |

### mint

Users use USDT to mint $wRWA

*Trigger event： `LOG_Mint(address indexed wRWA, address to, uint256 amount)`*

```solidity
function mint(address _wRWA, uint256 _amount) external whenNotPaused;
```

**Parameters**

| Name      | Type      | Description                                               |
| --------- | --------- | --------------------------------------------------------- |
| `_wRWA`   | `address` | The address of the wRWA token corresponding to RWA assets |
| `_amount` | `uint256` | The amount of minted $wRWA                                |

### requestRedeem

When a user deposits $wRWA and submits an application to redeem USDT,\
a corresponding NFT must be minted as a formal redemption voucher.

*`_amount`is not 0*

*Trigger event：`LOG_RequestRedeem(address indexed wRWA, uint256 amount)`*

```solidity
function requestRedeem(address _wRWA, uint256 _amount) external whenNotPaused;
```

**Parameters**

| Name      | Type      | Description                                               |
| --------- | --------- | --------------------------------------------------------- |
| `_wRWA`   | `address` | The address of the wRWA token corresponding to RWA assets |
| `_amount` | `uint256` | The amount of $wRWA applied for redemption                |

### withdrawRedeem

Users can redeem NFTs for USDT.

*Trigger event：`LOG_Withdraw(address indexed wRWA, uint256 nftId, address to, uint256 usdtAmount)`*

```solidity
function withdrawRedeem(uint256 _nftId) external whenNotPaused;
```

**Parameters**

| Name     | Type      | Description         |
| -------- | --------- | ------------------- |
| `_nftId` | `uint256` | The token ID of NFT |

### \_authorizeUpgrade

```solidity
function _authorizeUpgrade(address _newImplementation) internal override onlyOwner;
```

### pause

Suspend contract, only for administrators

```solidity
function pause() external onlyOwner;
```

### unpause

Resume contract suspension, only for administrators

```solidity
function unpause() external onlyOwner;
```

### \_getAzothStorage

```solidity
function _getAzothStorage() private pure returns (AzothStorage storage $);
```

### \_checkUintNotZero

```solidity
function _checkUintNotZero(uint256 _a) private pure;
```

### \_check2UintNotZero

```solidity
function _check2UintNotZero(uint256 _a, uint256 _b) private pure;
```

### \_checkRWAByVault

```solidity
function _checkRWAByVault(address _vault) private pure;
```

### \_checkAddressNotZero

```solidity
function _checkAddressNotZero(address _addr) private pure;
```

### getFeeRecipient

Get the address of the fee recipient

```solidity
function getFeeRecipient() external view returns (address);
```

**Returns**

| Name     | Type      | Description                      |
| -------- | --------- | -------------------------------- |
| `<none>` | `address` | the address of the fee recipient |

### getRWAInfo

Gather detailed information about RWA assets

*If the wRWA does not exist, return zero*

```solidity
function getRWAInfo(address _wRWA)
    external
    view
    returns (address vault, address rwa, uint256 mintPrice, uint256 redeemPrice, uint256 feePercent);
```

**Returns**

| Name          | Type      | Description                                            |
| ------------- | --------- | ------------------------------------------------------ |
| `vault`       | `address` | The vault address of this RWA asset                    |
| `rwa`         | `address` | The wrapped token address of this RWA asset            |
| `mintPrice`   | `uint256` | The minting price of this RWA asset (excluding fee)    |
| `redeemPrice` | `uint256` | The redemption price of this RWA asset (excluding fee) |
| `feePercent`  | `uint256` | The redemption price of this RWA asset (excluding fee) |

### getNFTRedeemInfo

Get the redemption information of NFTs.

*If the tokenId does not exist, return zero*

```solidity
function getNFTRedeemInfo(uint256 _tokenId) public view returns (address, uint256, uint256, uint256);
```

**Returns**

| Name     | Type      | Description                         |
| -------- | --------- | ----------------------------------- |
| `<none>` | `address` | The address of RWA assetRWA         |
| `<none>` | `uint256` | Redemption amount                   |
| `<none>` | `uint256` | Batch (Cycle) Index                 |
| `<none>` | `uint256` | The specific sequence of this batch |

### getRWARedeemInfo

Obtain redemption information for RWA assets

*If the wRWA does not exist, return zero*

```solidity
function getRWARedeemInfo(address _wRWA) public view returns (uint256[] memory, uint256, uint256, uint256, uint256);
```

**Returns**

| Name     | Type        | Description                                                                 |
| -------- | ----------- | --------------------------------------------------------------------------- |
| `<none>` | `uint256[]` | The amount of each batch                                                    |
| `<none>` | `uint256`   | The batch index assigned to the user's redemption application               |
| `<none>` | `uint256`   | The specific sequence of the redemption batch                               |
| `<none>` | `uint256`   | The index of the batches of redemptions that have been officially processed |
| `<none>` | `uint256`   | he specific sequence of the redemption batch                                |

### inWRWABlacklist

Check if the user is on the blacklist (users on the blacklist cannot transfer tokens).*If wRWA does not exist, return False*

```solidity
function inWRWABlacklist(address _wRWA, address _user) external view returns (bool);
```

**Parameters**

| Name    | Type      | Description                           |
| ------- | --------- | ------------------------------------- |
| `_wRWA` | `address` | The address of wRWA assets            |
| `_user` | `address` | The address of the user being queried |

**Returns**

| Name     | Type   | Description                               |
| -------- | ------ | ----------------------------------------- |
| `<none>` | `bool` | bool true -> The user is on the blacklist |

### getLpUnlockTimestamp

Check the timestamp when liquidity can be removed.\
If the timestamp is exceeded by 3 days, the request will be deemed expired, and a new application must be submitted.\
(0 indicates no removal application has been made)

*If wRWA does not exist, return 0*

```solidity
function getLpUnlockTimestamp(address _wRWA) external view returns (uint256);
```

**Parameters**

| Name    | Type      | Description         |
| ------- | --------- | ------------------- |
| `_wRWA` | `address` | The address of wRWA |

**Returns**

| Name     | Type      | Description |
| -------- | --------- | ----------- |
| `<none>` | `uint256` | Timestamp   |

### getCurvePool

Check the timestamp when liquidity can be removed.\
If the timestamp is exceeded by 3 days, the request will be deemed expired, and a new application must be submitted.\
(0 indicates no removal application has been made)

```solidity
function getCurvePool(address _wRWA) external view returns (address);
```

**Parameters**

| Name    | Type      | Description         |
| ------- | --------- | ------------------- |
| `_wRWA` | `address` | The address of wRWA |

**Returns**

| Name     | Type      | Description                       |
| -------- | --------- | --------------------------------- |
| `<none>` | `address` | The address of the liquidity pool |

## Structs

### AzothStorage

**Note:**\
storage-location: erc7201:AZOTH.storage.Azoth

```solidity
struct AzothStorage {
    address feeRecipient;
    mapping(address => address) rwaVault;
}
```

## other

Contract Update Function:

```solidity
function upgradeToAndCall(address newImplementation, bytes memory data) public payable virtual onlyProxy
```

### transferOwnership

For owners to transfer administrative privileges.\
Trigger event：`emit OwnershipTransferStarted(owner(), newOwner);`

```solidity
function transferOwnership(address newOwner) 
    public
    onlyOwner;
```

**Parameters**

| Name       | Type      | Description                                                   |
| ---------- | --------- | ------------------------------------------------------------- |
| `newOwner` | `address` | The address of the wRWA token corresponding to the RWA assets |

### acceptOwnership

The new administrator receives the authority/\
Trigger event：`emit OwnershipTransferred(oldOwner, newOwner);`

```solidity
function acceptOwnership() public;
```

<br>


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## 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, and the optional `goal` query parameter:

```
GET https://azoth.gitbook.io/azoth-tech-docs/smart-contracts/protocol-contracts.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

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.
