Smart Contract Architecture
Last updated
Last updated
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:
AquaVault
contract holds user assets and serves as the treasury for a NativePool
instance. It inherits the Comptroller
contract from Compound v2.
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.
It has the exact functionalities as Compound
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.
The interest accrual mechanism for liquidity provider operations are exactly the same as Compound.
When there are unhealthy borrowing positions, the liquidate function in AquaVault is open to anyone to claim the collateral by repaying the debt.
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.
The RFQ provider's address would be added to the NativePool as a valid signer for RFQ.
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
.
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
.
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.
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
.
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.
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.
Native admin has the right to update the RFQ providers' open positions by the fees calculated off-chain.
After the update, the netSwapBorrow
of each LP token contract should increase, and the exchange rate for LP token increases.
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.
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.
The RFQ provider then calls the settle
function of AquaVault
to execute the settlement.
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.
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.
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.