Skip to content

Commit

Permalink
Removing unused imports and U256 commented code
Browse files Browse the repository at this point in the history
  • Loading branch information
diyahir committed Sep 9, 2024
1 parent 66c8506 commit 4fa8080
Show file tree
Hide file tree
Showing 9 changed files with 40 additions and 200 deletions.
81 changes: 38 additions & 43 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,29 +1,39 @@
# Fluid Protocol

## [`Good Sway Contract Reference`](https://github.com/FuelLabs/sway-applications/tree/master/AMM/project)
Fluid is a decentralized protocol that allows holders of certain Assets to obtain maximum liquidity against
their collateral without paying interest. After locking up their assets as collateral in a smart contract and
creating an individual position called a "trove", the user can get instant liquidity by minting USDF,
a USD-pegged stablecoin. Each trove is required to be collateralized at a minimum of 130%. Any
owner of USDF can redeem their stablecoins for the underlying collateral at any time. The redemption
mechanism along with algorithmically adjusted fees guarantee a minimum stablecoin value of USD 1.

An unprecedented liquidation mechanism based on incentivized stability deposits and a redistribution
cycle from riskier to safer troves provides stability at a much lower collateral ratio than current
systems. Stability is maintained via economically-driven user interactions and arbitrage, rather
than by active governance or monetary interventions.

## Contracts

The source code for each contract is in the [`contracts/`](contracts/)
directory.

| Name | Description | Status |
| ----------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- | -------------------------- |
| [`protocol-manager`](contracts/protocol-manager-contract) | Proxy for adding new assets as collateral, and manages USDF redemptions, ownership to be renounced after milestones reached | $$\color{green}{85/100}$$ |
| [`borrow-operations`](contracts/borrow-operations-contract) | Interface with which users manager their troves | $$\color{green}{90/100}$$ |
| [`stability-pool`](contracts/stability-pool-contract) | Manages $USDF desposits to liquidate user troves | $$\color{green}{90/100}$$ |
| [`USDF-token`](contracts/usdf-token-contract) | Token Contract for authorizing minting,burning of $USDF | $$\color{green}{90/100}$$ |
| [`active-pool`](contracts/active-pool-contract) | Central place for holding collateral from Active Troves | $$\color{green}{90/100}$$ |
| [`default-pool`](contracts/default-pool-contract) | Central place for holding 'unapplied' rewards from liquidation redistributions | $$\color{green}{90/100}$$ |
| [`coll-surplus-pool`](contracts/coll-surplus-pool-contract) | Central place for holding exess assets from either a redemption or a full liquidation | $$\color{orange}{80/100}$$ |
| [`sorted-troves`](contracts/sorted-troves-contract) | Manages location of troves in the Linked list format | $$\color{green}{90/100}$$ |
| Name | Description |
| ----------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- |
| [`protocol-manager`](contracts/protocol-manager-contract) | Proxy for adding new assets as collateral, and manages USDF redemptions, ownership to be renounced after milestones reached |
| [`borrow-operations`](contracts/borrow-operations-contract) | Interface with which users manager their troves |
| [`stability-pool`](contracts/stability-pool-contract) | Manages $USDF desposits to liquidate user troves |
| [`USDF-token`](contracts/usdf-token-contract) | Token Contract for authorizing minting,burning of $USDF |
| [`active-pool`](contracts/active-pool-contract) | Central place for holding collateral from Active Troves |
| [`default-pool`](contracts/default-pool-contract) | Central place for holding 'unapplied' rewards from liquidation redistributions |
| [`coll-surplus-pool`](contracts/coll-surplus-pool-contract) | Central place for holding exess assets from either a redemption or a full liquidation |
| [`sorted-troves`](contracts/sorted-troves-contract) | Manages location of troves in the Linked list format |
| Asset Specific Contracts |
| [`token`](contracts/token-contract) | FRC-20 to use in local tests made by Sway Gang | $$\color{green}{90/100}$$ |
| [`oracle`](contracts/oracle-contract) | Oracle for on-chain data | $$\color{orange}{60/100}$$ |
| [`trove-manager`](contracts/trove-manager-contract) | Manages liquidations, redemptions, and user troves in the Linked list format | $$\color{orange}{85/100}$$ |
| [`token`](contracts/token-contract) | FRC-20 to use in local tests made by Sway Gang |
| [`oracle`](contracts/oracle-contract) | Oracle for on-chain data |
| [`trove-manager`](contracts/trove-manager-contract) | Manages liquidations, redemptions, and user troves in the Linked list format |
| FPT Contracts |
| [`FPT-vesting`](contracts/vesting-contract) | Manages $FPT vesting schedules | $$\color{green}{85/100}$$ |
| [`FPT-staking`](contracts/staking-contract) | Manages $FPT staking emissions from fee collection | $$\color{green}{90/100}$$ |
| [`FPT-vesting`](contracts/vesting-contract) | Manages $FPT vesting schedules |
| [`FPT-staking`](contracts/staking-contract) | Manages $FPT staking emissions from fee collection |

## Build + Test Contracts

Expand All @@ -35,42 +45,27 @@ sh build-and-test.sh

## Functionality

- [x] Create Trove and Recieve $USDF
- [x] Add more collateral to trove
- [x] Add more debt to trove
- [x] Repay trove debt
- [x] Reduce collateral from trove
- [x] Close Trove
- [x] Liquidate Troves
- [x] Stability Pool
- [x] Multiple assets (Fuel, stFuel)
- [x] Fees
- [x] Redeem Collateral w/ USDF
- [x] Stake FPT
- Create Trove and Recieve $USDF
- Add more collateral to trove
- Add more debt to trove
- Repay trove debt
- Reduce collateral from trove
- Close Trove
- Liquidate Troves
- Stability Pool
- Multiple assets (Fuel, stFuel)
- Fees
- Redeem Collateral w/ USDF
- Stake FPT

## License

MIT License (see `/LICENSE`)

# Fluid: Decentralized Borrowing Protocol

Fluid is a decentralized protocol that allows holders of certain Assets to obtain maximum liquidity against
their collateral without paying interest. After locking up their assets as collateral in a smart contract and
creating an individual position called a "trove", the user can get instant liquidity by minting USDF,
a USD-pegged stablecoin. Each trove is required to be collateralized at a minimum of 130%. Any
owner of USDF can redeem their stablecoins for the underlying collateral at any time. The redemption
mechanism along with algorithmically adjusted fees guarantee a minimum stablecoin value of USD 1.

An unprecedented liquidation mechanism based on incentivized stability deposits and a redistribution
cycle from riskier to safer troves provides stability at a much lower collateral ratio than current
systems. Stability is maintained via economically-driven user interactions and arbitrage, rather
than by active governance or monetary interventions.

## More information

Visit [Fluid.org](https://www.Fluid.org) to find out more and join the discussion.


## Disclaimer

The content of this readme document (“Readme”) is of purely informational nature. In particular, none of the content of the Readme shall be understood as advice provided by Fluid AG, any Fluid Project Team member or other contributor to the Readme, nor does any of these persons warrant the actuality and accuracy of the Readme.
Expand Down
1 change: 0 additions & 1 deletion contracts/borrow-operations-contract/src/main.sw
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ use std::{
msg_amount,
},
hash::*,
logging::log,
};
storage {
asset_contracts: StorageMap<AssetId, AssetContracts> = StorageMap::<AssetId, AssetContracts> {},
Expand Down
1 change: 0 additions & 1 deletion contracts/community-issuance-contract/src/main.sw
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ use std::{
balance_of,
msg_amount,
},
u128::U128,
};

const ONE_WEEK_IN_SECONDS: u64 = 604_800;
Expand Down
1 change: 0 additions & 1 deletion contracts/fpt-staking-contract/src/main.sw
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ use std::{
},
hash::Hash,
storage::storage_vec::*,
u128::U128,
};
storage {
valid_assets: StorageVec<AssetId> = StorageVec {},
Expand Down
1 change: 0 additions & 1 deletion contracts/multi-trove-getter-contract/src/main.sw
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ use std::{
msg_amount,
},
hash::Hasher,
logging::log,
};

storage {}
Expand Down
1 change: 0 additions & 1 deletion contracts/protocol-manager-contract/src/main.sw
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ use std::{
msg_amount,
},
hash::*,
logging::log,
storage::storage_vec::*,
};
storage {
Expand Down
32 changes: 1 addition & 31 deletions contracts/trove-manager-contract/src/utils.sw
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@ library;
use ::data_structures::{LiquidatedTroveValsInner, LiquidationTotals, LiquidationValues};

use libraries::fluid_math::*;
use std::{logging::log, u128::U128};

use std::u128::U128;
pub fn calculate_liqudated_trove_values(
coll: u64,
debt: u64,
Expand All @@ -23,12 +22,9 @@ pub fn calculate_liqudated_trove_values(
let trove_debt_denominator: U128 = U128::from_u64(POST_COLLATERAL_RATIO - ONE - STABILITY_POOL_FEE);
let trove_debt_to_repay = (trove_debt_numerator / trove_debt_denominator).as_u64().unwrap();
let trove_debt_to_repay = fm_min(trove_debt_to_repay, debt);

let mut trove_coll_liquidated = fm_multiply_ratio(trove_debt_to_repay, ONE + STABILITY_POOL_FEE, price);

if debt - trove_debt_to_repay < MIN_NET_DEBT {
trove_coll_liquidated = fm_multiply_ratio(debt, ONE + STABILITY_POOL_FEE, price);

return LiquidatedTroveValsInner {
trove_coll_liquidated: fm_min(trove_coll_liquidated, coll),
trove_debt_to_repay: debt,
Expand All @@ -41,19 +37,16 @@ pub fn calculate_liqudated_trove_values(
is_partial_liquidation: true,
}
}

pub fn get_offset_and_redistribution_vals(
coll: u64,
debt: u64,
usdf_in_stab_pool: u64,
price: u64,
) -> LiquidationValues {
let mut vars: LiquidationValues = LiquidationValues::default();

vars.entire_trove_coll = coll;
vars.entire_trove_debt = debt;
let liquidated_position_vals = calculate_liqudated_trove_values(coll, debt, price);

if (liquidated_position_vals.is_partial_liquidation) {
vars.is_partial_liquidation = true;
vars.remaining_trove_coll = coll - liquidated_position_vals.trove_coll_liquidated;
Expand All @@ -62,11 +55,9 @@ pub fn get_offset_and_redistribution_vals(
// if full liquidation then some of the collateral is left over
vars.coll_surplus = coll - liquidated_position_vals.trove_coll_liquidated;
}

// 0.5% of the liquidated collateral is used to compensate the liquidator for gas
vars.coll_gas_compensation = liquidated_position_vals.trove_coll_liquidated / 200;
let pending_liquidated_col = liquidated_position_vals.trove_coll_liquidated - vars.coll_gas_compensation;

if (usdf_in_stab_pool > 0) {
// If the Stability Pool doesnt have enough USDF to offset the entire debt, offset as much as possible
vars.debt_to_offset = fm_min(
Expand All @@ -88,10 +79,8 @@ pub fn get_offset_and_redistribution_vals(
vars.debt_to_redistribute = liquidated_position_vals.trove_debt_to_repay;
vars.coll_to_redistribute = pending_liquidated_col;
}

return vars;
}

pub fn add_liquidation_vals_to_totals(
old_totals: LiquidationTotals,
vals: LiquidationValues,
Expand All @@ -107,21 +96,18 @@ pub fn add_liquidation_vals_to_totals(
new_totals.total_coll_surplus += vals.coll_surplus;
return new_totals;
}

#[test]
fn test_calculate_liqudated_trove_values() {
// Full liquidation
let starting_coll = 550 * DECIMAL_PRECISION;
let starting_debt = 500 * DECIMAL_PRECISION;
let price = DECIMAL_PRECISION;
let liquidation_vals = calculate_liqudated_trove_values(starting_coll, starting_debt, price);

// Value of debt + 5% stability fee
let coll_liquidated = U128::from_u64(starting_debt) * U128::from_u64(ONE + STABILITY_POOL_FEE) / U128::from_u64(price);
assert(liquidation_vals.trove_coll_liquidated == coll_liquidated.as_u64().unwrap());
assert(liquidation_vals.trove_debt_to_repay == starting_debt);
assert(liquidation_vals.is_partial_liquidation == false);

// Partial liquidation
// Test passes but runs into sway issue of 'TransactionScriptLength'
// let starting_coll = 12_000 * DECIMAL_PRECISION;
Expand All @@ -132,19 +118,16 @@ fn test_calculate_liqudated_trove_values() {
// let pcr = fm_compute_cr(ending_coll, ending_debt, price);
// assert_within_percent_tolerance(pcr, POST_COLLATERAL_RATIO, DECIMAL_PRECISION / 100);
}

#[test]
fn test_calculate_liqudated_trove_values_bad_debt() {
// Full liquidation bad debt
let starting_coll = 900 * DECIMAL_PRECISION;
let starting_debt = 1_000 * DECIMAL_PRECISION;
let liquidation_vals = calculate_liqudated_trove_values(starting_coll, starting_debt, 1_000_000_000);

assert(liquidation_vals.trove_coll_liquidated == starting_coll);
assert(liquidation_vals.trove_debt_to_repay == starting_debt);
assert(liquidation_vals.is_partial_liquidation == false);
}

#[test]
fn test_get_offset_and_redistribution_vals_full_liquidation_empty_pool() {
// Full liquidation, Empty Stability Pool
Expand All @@ -154,7 +137,6 @@ fn test_get_offset_and_redistribution_vals_full_liquidation_empty_pool() {
let liquidation_vals = get_offset_and_redistribution_vals(starting_coll, starting_debt, 0, price);
let coll_liquidated = fm_multiply_ratio(starting_debt, ONE + STABILITY_POOL_FEE, price);
let coll_gas_compensation = coll_liquidated / 200;

assert(liquidation_vals.entire_trove_coll == starting_coll);
assert(liquidation_vals.entire_trove_debt == starting_debt);
assert(liquidation_vals.is_partial_liquidation == false);
Expand All @@ -170,7 +152,6 @@ fn test_get_offset_and_redistribution_vals_full_liquidation_empty_pool() {
);
assert(liquidation_vals.coll_gas_compensation == coll_gas_compensation);
}

#[test]
fn test_get_offset_and_redistribution_vals_full_liquidation_enough_pool() {
// Full liquidation, Stability Pool has enough USDF to offset the entire debt
Expand All @@ -181,7 +162,6 @@ fn test_get_offset_and_redistribution_vals_full_liquidation_enough_pool() {
let liquidation_vals = get_offset_and_redistribution_vals(starting_coll, starting_debt, amount_in_pool, price);
let coll_liquidated = fm_multiply_ratio(starting_debt, ONE + STABILITY_POOL_FEE, price);
let coll_gas_compensation = coll_liquidated / 200;

assert(liquidation_vals.entire_trove_coll == starting_coll);
assert(liquidation_vals.entire_trove_debt == starting_debt);
assert(liquidation_vals.is_partial_liquidation == false);
Expand All @@ -197,7 +177,6 @@ fn test_get_offset_and_redistribution_vals_full_liquidation_enough_pool() {
);
assert(liquidation_vals.coll_gas_compensation == coll_gas_compensation);
}

#[test]
fn test_get_offset_and_redistribution_vals_full_liquidation_partial_pool() {
// Full liquidation, Stability Pool doesn't have enough USDF to offset the entire debt
Expand All @@ -208,7 +187,6 @@ fn test_get_offset_and_redistribution_vals_full_liquidation_partial_pool() {
let liquidation_vals = get_offset_and_redistribution_vals(starting_coll, starting_debt, amount_in_pool, price);
let coll_liquidated = fm_multiply_ratio(starting_debt, ONE + STABILITY_POOL_FEE, price);
let coll_gas_compensation = coll_liquidated / 200;

assert(liquidation_vals.entire_trove_coll == starting_coll);
assert(liquidation_vals.entire_trove_debt == starting_debt);
assert(liquidation_vals.is_partial_liquidation == false);
Expand All @@ -226,15 +204,13 @@ fn test_get_offset_and_redistribution_vals_full_liquidation_partial_pool() {
.coll_to_redistribute == 550 * DECIMAL_PRECISION - coll_gas_compensation / 2,
);
}

#[test]
fn test_get_offset_and_redistribution_vals_partial_liquidation_empty_pool() {
// Partial liquidation, Empty Stability Pool
let starting_coll = 12_000 * DECIMAL_PRECISION;
let starting_debt = 10_000 * DECIMAL_PRECISION;
let price = DECIMAL_PRECISION;
let liquidation_vals = get_offset_and_redistribution_vals(starting_coll, starting_debt, 0, price);

let icr = fm_compute_cr(
liquidation_vals
.remaining_trove_coll,
Expand All @@ -261,7 +237,6 @@ fn test_get_offset_and_redistribution_vals_partial_liquidation_empty_pool() {
.coll_gas_compensation,
);
}

#[test]
fn test_get_offset_and_redistribution_vals_partial_liquidation_enough_pool() {
// Partial liquidation, Stability Pool has enough USDF to offset the entire debt
Expand All @@ -277,7 +252,6 @@ fn test_get_offset_and_redistribution_vals_partial_liquidation_enough_pool() {
.remaining_trove_debt,
price,
);

assert(liquidation_vals.entire_trove_coll == starting_coll);
assert(liquidation_vals.entire_trove_debt == starting_debt);
assert(liquidation_vals.is_partial_liquidation == true);
Expand All @@ -297,15 +271,13 @@ fn test_get_offset_and_redistribution_vals_partial_liquidation_enough_pool() {
assert(liquidation_vals.coll_to_redistribute == 0);
assert_within_percent_tolerance(icr, POST_COLLATERAL_RATIO, DECIMAL_PRECISION / 100);
}

#[test]
fn test_get_offset_and_redistribution_vals_partial_liquidation_partial_pool() {
// Partial liquidation, Stability Pool doesn't have enough USDF to offset the entire debt
let starting_coll = 12_000 * DECIMAL_PRECISION;
let starting_debt = 10_000 * DECIMAL_PRECISION;
let total_usdf = 1_000 * DECIMAL_PRECISION;
let price = DECIMAL_PRECISION;

let liquidation_vals = get_offset_and_redistribution_vals(starting_coll, starting_debt, total_usdf, price);
let icr = fm_compute_cr(
liquidation_vals
Expand All @@ -315,9 +287,7 @@ fn test_get_offset_and_redistribution_vals_partial_liquidation_partial_pool() {
price,
);
let coll_removed = starting_coll - liquidation_vals.remaining_trove_coll - liquidation_vals.coll_gas_compensation;

let expected_coll_to_send_to_sp = U128::from_u64(total_usdf) * U128::from_u64(coll_removed) / U128::from_u64(starting_debt - liquidation_vals.remaining_trove_debt);

assert(liquidation_vals.entire_trove_coll == starting_coll);
assert(liquidation_vals.entire_trove_debt == starting_debt);
assert(liquidation_vals.is_partial_liquidation == true);
Expand Down
Loading

0 comments on commit 4fa8080

Please sign in to comment.