> For the complete documentation index, see [llms.txt](https://docs.lumia.org/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.lumia.org/build/rwausd/rwausd-overcollateralizing.md).

# rwaUSD: Overcollateralizing

## Overcollateralizing Assets to Get rwaUSD

The user can get rwaUSD by overcollateralizing their LUMIA.&#x20;

This option is implemented through the **Lumia rwaUSD CDP Protocol**.

Lumia rwaUSD CDP is a decentralized lending protocol, extending the [3A Lending Protocol](https://docs.3adao.org/3a-protocol).&#x20;

It is customized for Lumia to enable LUMIA token holders to use their tokens as collateral for borrowing the rwaUSD stablecoin.&#x20;

Later on, we plan to whitelist and support different types of tokenized RWAs as collateral, with different collateralization ratios.

It works fairly simply: The user deposits whitelisted assets as collateral into a smart contract called vault, allowing them to mint and withdraw RWAs. In order to avoid liquidation, vaults must maintain a required [Health Factor](https://docs.3adao.org/3a-protocol/whitelisting-criteria/risk-sensitive-parameters) (HF) determined by our data-driven risk model.

The protocol is implemented as a set of smart contracts.

{% hint style="info" %}
See the [**source code in the GitHub repo**](https://github.com/LumiaUSD/Lending-protocol/tree/main).
{% endhint %}

## Smart Contracts&#x20;

The smart contracts implementing the protocol are:

* API3MarketPriceFeed ([0x58504c4eE9f9e9cf7b17988817fddFa9934E76d4](https://explorer.lumia.org/address/0x58504c4eE9f9e9cf7b17988817fddFa9934E76d4?tab=contract)) — Adapter; gets the latest WLUMIA price from the market, with a 24h price update threshold.
* AuctionManager ([0xCAE7cf522D37b05AF6038E6c98441A2F50154EA5](https://explorer.lumia.org/address/0xCAE7cf522D37b05AF6038E6c98441A2F50154EA5?tab=contract)) — Manages the auction where the liquidated user funds are sold to cover the user's debt.&#x20;
* LastResortLiquidation ([0x5D8153141ec1a4837437981dc5Da26436E88985D](https://explorer.lumia.org/address/0x5D8153141ec1a4837437981dc5Da26436E88985D?tab=contract)) — Manages collateral and bad debt distribution. \
  Initiates the liquidation process when the user's collateral goes under the min threshold to the amount of minted rwaUSD; this leads to selling the user's collateralized assets in an auction to cover the debt.
* LiquidationRouter ([0x7Ea6031dD3AF19D61772E2Ec2E2177dD958d8F78](https://explorer.lumia.org/address/0x7Ea6031dD3AF19D61772E2Ec2E2177dD958d8F78?tab=contract)) — Handles liquidation and redistribution of collaterals and debts in the system.
* Mintable Token Owner ([0x482EaBBA837170DaaE5De9AB288c5003EEC93C1a](https://explorer.lumia.org/address/0x482EaBBA837170DaaE5De9AB288c5003EEC93C1a?tab=contract)) — Implements the owner of the rwaUSD mintable token contract.
* OwnerProxy ([0xAF8164dEe8743B1D1Ec8130E15EE9Da70a79482d](https://explorer.lumia.org/address/0xAF8164dEe8743B1D1Ec8130E15EE9Da70a79482d?tab=contract)) — Allows the main owner to add fine-grained permissions to other operators (addresses).
* SmartVaultProxy ([0xdb6ee8d804Df3d93Ae92c02aB2fB377b5d9bA2B0](https://explorer.lumia.org/address/0xdb6ee8d804Df3d93Ae92c02aB2fB377b5d9bA2B0?tab=contract)) — Enables the execution of whitelisted methods authorized by the proxy owner across all smart vaults.
* Smart Vault Deployer ([0x25873c3d82dE1eD069B02feDA958eE9D3A5E69B4](https://explorer.lumia.org/address/0x25873c3d82dE1eD069B02feDA958eE9D3A5E69B4?tab=contract)) — Deploys new instances of the Vault contract.
* TokenToPriceFeed ([0x489d04f2AF0a423d4031Aa14a7De3677AEC5dfA0](https://explorer.lumia.org/address/0x489d04f2AF0a423d4031Aa14a7De3677AEC5dfA0?tab=contract)) — Gets the latest market price for a specified token. Controls price feed configurations.
* rwaUSD mintable token ([0xDf6b509693B431BD289CBC442F4B78ddaCb2A1E0](https://explorer.lumia.org/token/0xDf6b509693B431BD289CBC442F4B78ddaCb2A1E0?tab=contract)) — Burns/mints rwaUSD for the user.
* VaultBorrowRate ([0x64b8ddcFEd7b752A8BD18a2c1af22f9383C6bB33](https://explorer.lumia.org/address/0x64b8ddcFEd7b752A8BD18a2c1af22f9383C6bB33?tab=contract)) — Calculates the borrow rate for a specified Vault.
* VaultExtraSettings ([0x00e0117427F547cEc271558b60D1973DC6F51f81](https://explorer.lumia.org/address/0x00e0117427F547cEc271558b60D1973DC6F51f81?tab=contract)) — Manages extra settings for a Vault instance: maximum redeemable percentage, debt treshold, redemption fee kickback.
* VaultFactory ([0xF2C2691Ea8937f5Dbf07E6FF69F40d80AFD8789C](https://explorer.lumia.org/address/0xF2C2691Ea8937f5Dbf07E6FF69F40d80AFD8789C?tab=contract)) — Manages the creation, configuration, and operations of Vaults with collateral and borrowing functionality.
* VaultFactoryZapper ([0x8A4C3Bc98dB9A2c8a1DaEF7695ee57262446883C](https://explorer.lumia.org/address/0x8A4C3Bc98dB9A2c8a1DaEF7695ee57262446883C?tab=contract)) — Facilitates the creation of Vaults and manages their operations.
* VaultFactoryHelperV2 ([0x38ccdf424Bf32E6756C5b607c898A83A885B6915](https://explorer.lumia.org/address/0x38ccdf424Bf32E6756C5b607c898A83A885B6915?tab=contract)) — Provides various functions to retrieve information about vaults in a vault factory.
* WLUMIA token ([0xE891B5EE2F52E312038710b761EC165792AD25B1](https://explorer.lumia.org/token/0xE891B5EE2F52E312038710b761EC165792AD25B1?tab=contract)) — Burns/mints the wrapped LUMIA token for the user.

## Workflow

To better understand the interaction of smart contracts and the flow, rely on the [unit tests](https://github.com/LumiaUSD/Lending-protocol/blob/main/test/protocol.ts) showing the whole flow.

Also, the following diagrams refer to the unit test and outlines, in broader details, the workflow and interaction:<br>

<figure><img src="/files/gWteLnTumIYQ43HK9zWr" alt=""><figcaption><p>Workflow of getting rwaUSD via overcollateralization </p></figcaption></figure>

<div align="center"><figure><img src="/files/Xky5Kyojvm4eLHGf1ahc" alt="" width="563"><figcaption><p>Simplified interaction for overcollateralization</p></figcaption></figure></div>

## Contract Methods Requiring Owner Privileges

The following methods require owner privileges across the Lumia rwaUSD CDP Protocol.

### **AuctionManager**

Owner can configure core auction parameters.

#### Configuration Methods:

* `setVaultFactory(address _vaultFactory)`: Updates the vault factory address
* `setAuctionDuration(uint256 _auctionDuration)`: Sets the duration for auctions
* `setLowestHF(uint256 _lowestHF)`: Sets the lowest acceptable health factor

***

### **LastResortLiquidation**

Manages collateral and bad debt distribution.

#### Access Control:

* `addAllowed(address _allowed)`: Adds an address to the allowed operators list
* `removeAllowed(address _allowed)`: Removes an address from the allowed operators list

#### Collateral Management

* `withdrawCollateral(address _collateral, uint256 _amount, address _to)`: Withdraws collateral to specified address
* `distributeBadDebt(address _vault, uint256 _amount)`: Distributes bad debt to a specific vault

***

### TokenToPriceFeed

Controls price feed configurations.

#### Price Feed Management

* `setTokenPriceFeed(address _token, address _priceFeed, uint256 _mcr, uint256 _mlr, uint256 _borrowRate, uint256 _decimals)`:
  * Sets or updates price feed parameters for a token
  * Controls Minimal Collateral Ratio (MCR)
  * Sets Minimal Liquidation Ratio (MLR)
  * Defines borrowing rates
* `transferOwnership(address newOwner)`: Transfers ownership of the contract

***

### VaultFactory

Core configuration of the vault system.

#### System Parameters

* `setMaxTokensPerVault(uint256 _maxTokensPerVault)`: Maximum tokens allowed per vault
* `setPriceFeed(address _priceFeed)`: Updates the price feed contract address
* `setRedemptionRate(uint256 _redemptionRate)`: Sets the redemption fee rate
* `setBorrowRate(address _borrowRate)`: Sets the contract address for calculating borrow rates
* `setRedemptionHealthFactorLimit(uint256 _redemptionHealthFactorLimit)`: Sets minimum health factor for redemptions
* `setBorrowFeeRecipient(address _borrowFeeRecipient)`: Sets address receiving borrowing fees
* `setRedemptionFeeRecipient(address _redemptionFeeRecipient)`: Sets address receiving redemption fees
* `setDebtCeiling(uint256 _debtCeiling)`: Sets maximum total debt allowed in the system
* `setMaxDebtPerWindow(uint256 _maxDebtPerWindow)`: Sets maximum debt that can be taken in a time window
* `setDebtWindowSize(uint256 _debtWindowSize)`: Sets the size of the time window for debt limits
* `setCollateralCapacity(address _collateral, uint256 _capacity)`: Sets maximum amount of a specific collateral type
* `setLiquidationRouter(address _liquidationRouter)`: Updates the liquidation router address
* `setVaultDeployer(address _vaultDeployer)`: Sets the contract responsible for deploying new vaults

***

### VaultExtraSettings

Controls additional vault parameters.

#### Vault Parameters

* `setMaxRedeemablePercentage(uint256 _debtTreshold, uint256 _maxRedeemablePercentage)`: Sets maximum redeemable percentage and debt threshold
* `setRedemptionKickback(uint256 _redemptionKickback)`: Sets redemption fee kickback rate

***

### SmartVaultProxy

Manages permissions for smart vault operations.

#### Permission Management

* `addPermission(address targetAddress, bytes4 targetSignature)`: Whitelists method calls
* `removePermission(address targetAddress, bytes4 targetSignature)`: Removes whitelisted methods
* `setRewardFee(uint16 _newRewardFee)`: Sets reward fee percentage
* `setRewardCollector(address newRewardCollector)`: Updates reward collector address
* `transferOwnership(address newOwner)`: Transfers ownership of the contract

***

### OwnerProxy

Manages fine-grained permissions.

#### Permission Control

* `addPermission(address caller, address targetAddress, bytes4 targetSignature)`: Grants specific call permissions
* `removePermission(uint256 permissionHash)`: Revokes specific permissions
* `executeOwner(address target, string memory func, bytes memory data)`: Executes privileged calls

***

### MintableTokenOwner

Controls token minting privileges.

#### Token Management

* `transferTokenOwnership(address _newOwner)`: Transfers token ownership
* `addMinter(address _newMinter)`: Adds new minting privileges
* `revokeMinter(address _minter)`: Revokes minting privileges

***

### FeeRecipientManager

Manages fee distribution.

#### Fee Management

* `claimRewards(address[] tokenFrom, address[] tokenTo, bool[] stable, uint256 amountOutMin)`: Claims and swaps rewards
* `forceWithdraw(address[] tokenFrom, address to)`: Emergency withdrawal of tokens
* `setfeeReceiver(address _feeReceiver)`: Updates fee receiver address
* `setRouter(address _router)`: Updates the router contract address used for swaps

***

### StabilityPool

#### Configuration

* `setVaultFactory(address _vaultFactory)`: Updates the vault factory address
* `setA3AToken(address _a3aToken)`: Sets the A3A token address

***

### veA3AStaking

#### Slashing Configuration

* `setSlashingDuration(uint256 _round, uint256 _duration)`: Sets duration for a slashing round
* `setSlashingRate(uint256 _round, uint256 _rate)`: Sets rate for a slashing round
* `setSlashingReturnForStabilityPool(uint256 _slashingReturnForStabilityPool)`: Sets percentage of slashed tokens returned to stability pool
* `setStabilityPool(address _stabilityPool)`: Sets the stability pool address
* `setVaultFactory(address _vaultFactory)`: Updates the vault factory address
* `setFactory(address _factory)`: Sets the factory contract address
* `setStable(address _stable)`: Sets the stable token address
* `setA3aToken(address _a3aToken)`: Sets the A3A token address

***

### LiquidationRouter

#### Configuration

* `setVaultFactory(address _vaultFactory)`: Updates the vault factory address
* `setStabilityPool(address _stabilityPool)`: Sets the stability pool address
* `setAuctionManager(address _auctionManager)`: Sets the auction manager address
* `setLastResortLiquidation(address _lastResortLiquidation)`: Sets the last resort liquidation address

***

### Critical Considerations

1. **Ownership Transfer**
   * Most contracts inherit from OpenZeppelin's `Ownable`
   * Use `transferOwnership()` carefully as it transfers all privileges
   * Consider using multi-sig wallets for ownership
   * Every contract that inherits from Ownable includes a `transferOwnership(address newOwner)` method
   * This method should be used with extreme caution as it transfers complete control of the contract

***

### Understanding OwnerProxy

The OwnerProxy contract provides a way to delegate specific contract method permissions to different addresses. This allows for fine-grained access control beyond simple ownership.

#### How to Grant Permissions

1. **Adding Permissions** (Owner only)

   ```
   function addPermission(
       address caller,        // The address being granted permission
       address targetAddress, // The contract address containing the method
       bytes4 targetSignature // The method signature to allow
   )
   ```

   Example:

   ```
   // To allow an address to call setMaxTokensPerVault on VaultFactory:
   const methodSignature = 'setMaxTokensPerVault(uint256)';
   const encodedSignature = ethers.utils.id(methodSignature).slice(0, 10); // Get first 4 bytes
   await ownerProxy.addPermission(
     operatorAddress,
     vaultFactoryAddress,
     encodedSignature
   );
   ```
2. **Revoking Permissions** (Owner only)

   ```
   function removePermission(uint256 permissionHash)
   ```

#### Executing Methods

1. **For Whitelisted Operators**

   ```
   function execute(
       address target,      // Contract address
       string memory func,  // Function name with signature
       bytes memory data    // Encoded parameters
   )
   ```

   Example:

   ```
   // To call setMaxTokensPerVault(5):
   const data = ethers.utils.defaultAbiCoder.encode(['uint256'], [5]);
   await ownerProxy.execute(
     vaultFactoryAddress,
     'setMaxTokensPerVault(uint256)',
     data
   );
   ```
2. **For Owner Only**

   ```
   function executeOwner(
       address target,
       string memory func,
       bytes memory data
   )
   ```

   * Only the owner can call this method
   * No permission check is performed
   * Can execute any method on any contract

#### Permission Management

* Permissions are stored as hashes combining caller, target, and method signature
* Each permission must be explicitly granted
* Permissions can be revoked individually
* Owner can execute any method without needing explicit permission

#### Best Practices

1. **When Granting Permissions**
   * Verify the target contract address carefully
   * Double-check method signatures
   * Test permissions with small operations first
2. **When Executing Methods**
   * Verify encoded parameters before execution
   * Use helper functions to encode data correctly
   * Keep track of granted permissions
3. **Security Considerations**
   * Maintain a list of all granted permissions
   * Regularly audit active permissions
   * Remove unused permissions promptly
   * Consider using timelock for sensitive operations

## More Information

For more information, see the [**source code and more documented specific params in the GitHub repo**](https://github.com/LumiaUSD/Lending-protocol/tree/main).
