# Smart Contract Architecture

<figure><img src="https://2554447728-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F1KSTkRlEw1XexgySFans%2Fuploads%2FmaUPt4pFqqh3GdurEw7V%2FAqua%20smart%20contract%20architecture%20(1).jpg?alt=media&#x26;token=500936f3-c8b8-4dfa-8af3-bfeff39726be" alt=""><figcaption></figcaption></figure>

Aqua is a liquidity providing system for RFQ providers built on top of the Compound v2 model and existing Native RFQ system (check README on repo root). It consists of the following contracts:

1. `AquaVault` contract holds user assets and serves as the treasury for a `NativePool` instance. It inherits the `Comptroller` contract from Compound v2.
2. A list of LP token contracts `AquaLpToken` that allows liquidity providers to deposit assets to the vault, mint interest earning LP tokens derived from borrowers and RFQ provider open position fees. It inherits `CErc20` (which inherits `CToken` contract) from Compound v2.

### Workflow

#### liquidity provider: mint, redeem, borrow, repay, liquidate

1. It has the exact functionalities as Compound
2. Liquidity providers interact with LP token contracts to mint, redeem, borrow and repay with the difference being the underlying asset is held by `AquaVault` instead of the LP token contracts.
3. The interest accrual mechanism for liquidity provider operations are exactly the same as Compound.
4. When there are unhealthy borrowing positions, the liquidate function in AquaVault is open to anyone to claim the collateral by repaying the debt.
5. Special Note: Besides major tokens, Aqua powers altcoin trading. For major tokens with reliable oracle prices, the LP token operates exactly like Compound with full functionality. For altcoins, liquidity providers can deposit assets and mint the LP tokens. The asset can then be used by RFQ providers to fill the swap and LPs can earn fees. However, a liquidity provider cannot borrow altcoins and LP tokens of altcoins cannot serve as collateral.

#### RFQ providers: trade

1. The RFQ provider's address would be added to the NativePool as a valid signer for RFQ.
2. When a swapper sends a swap request to Native off-chain API, Native checks with the RFQ providers for their quote and if they want the order to be filled with Aqua liquidity. The RFQ providers then return the respective quote and signature that will be verified on-chain by `NativePool`.
3. Native’s off-chain system verifies the quote and generates the signature to approve borrowing from Aqua. The signature would be verified on-chain in `AquaVault`.
4. Native’s API returns the quote containing the 2 signatures (1 from RFQ provider & 1 from Native) to the swapper allowing the swapper to call the `NativeRouter` to execute their trade.
5. `NativeRouter` processes the call-data and calls `NativePool` for swapping. `NativePool` will verify the signature of the RFQ provider, and transfer the tokens from `AquaVault` to the swapper. A callback is also sent to `NativeRouter` to transfer tokens from swapper to `AquaVault`.
6. At the end of the transaction lifecycle, `NativePool` sends a callback to `AquaVault` to account for the position change for the RFQ provider. Tokens transferred from `AquaVault` to swapper would be a short position and tokens transferred into `AquaVault` would be a long position. All live positions for the RFQ provider are recorded on-chain.
7. `AquaVault` calls the 2 LP tokens involved to update the variable `netSwapBorrow`. For long positions, the borrow amount decreases (could be negative) and the inverse for short positions. The update of the borrow amounts would cancel out the change in the actual asset resulting in no change in the exchange rate before and after the trade.

#### admin: epoch update

1. Native admin has the right to update the RFQ providers' open positions by the fees calculated off-chain.
2. After the update, the `netSwapBorrow` of each LP token contract should increase, and the exchange rate for LP token increases.

#### RFQ providers: settle

1. RFQ providers can permissionlessly call the repay function of AquaVault to close short positions. The contract transfers assets from the RFQ provider to the vault and updates the positions.
2. For a settlement request that requires claiming long positions, the RFQ provider needs to call Native’s API with the settlement proposal (amount of short positions to repay & amount of long positions to claim). Native’s off-chain system would validate the settlement proposal and return a signature.
3. The RFQ provider then calls the `settle` function of `AquaVault` to execute the settlement.

#### RFQ providers: collateral and liquidate

1. RFQ providers can put in collateral to obtain borrowing credit. They can mint LP tokens and call `addCollateral` in `AquaVault` to stake the LP tokens for collateral.
2. When RFQ providers want to remove collateral, they call Native’s off-chain API. Native’s systems validate the withdrawal amount to ensure that the removal would bring the RFQ provider’s position into default before returning a signature to allow collateral withdrawal.
3. A whitelist of liquidators can liquidate the RFQ provider's unhealthy positions. However a signature from Native’s off-chain API is required to do so.
