diff --git a/.gitignore b/.gitignore index 99d4553b..a95aaae7 100644 --- a/.gitignore +++ b/.gitignore @@ -4,5 +4,7 @@ target *.DS_Store *.ENV *.lock +*.env +!*/.sample.env *types/* */contracts.json diff --git a/contracts/active-pool-contract/src/main.sw b/contracts/active-pool-contract/src/main.sw index 8f18d538..4ec4207d 100644 --- a/contracts/active-pool-contract/src/main.sw +++ b/contracts/active-pool-contract/src/main.sw @@ -1,5 +1,10 @@ contract; - +// The Active Pool holds the collateral assets and USDF debt (but not USDF tokens) for all active troves. +// +// When a trove is liquidated, its collateral assets and USDF debt are transferred from the Active Pool +// to either the Stability Pool, the Default Pool, or both, depending on the liquidation conditions. +// +// This contract supports multiple collateral assets, each managed separately. use libraries::active_pool_interface::ActivePool; use std::{ asset::transfer, @@ -11,17 +16,17 @@ use std::{ msg_amount, }, hash::Hash, - logging::log, }; + storage { borrow_operations_contract: Identity = Identity::Address(Address::zero()), stability_pool_contract: Identity = Identity::Address(Address::zero()), default_pool_contract: ContractId = ContractId::zero(), protocol_manager_contract: Identity = Identity::Address(Address::zero()), - asset_amount: StorageMap = StorageMap:: {}, - usdf_debt_amount: StorageMap = StorageMap:: {}, - valid_asset_ids: StorageMap = StorageMap:: {}, - valid_trove_managers: StorageMap = StorageMap:: {}, + asset_amount: StorageMap = StorageMap:: {}, // Asset amount in the active pool + usdf_debt_amount: StorageMap = StorageMap:: {}, // USDF debt in the active pool + valid_asset_ids: StorageMap = StorageMap:: {}, // Valid asset ids + valid_trove_managers: StorageMap = StorageMap:: {}, // Valid trove managers, one for each asset managed is_initialized: bool = false, } impl ActivePool for Contract { @@ -36,7 +41,7 @@ impl ActivePool for Contract { storage .is_initialized .read() == false, - "Already initialized", + "Active Pool: Already initialized", ); storage.borrow_operations_contract.write(borrow_operations); storage.stability_pool_contract.write(stability_pool); @@ -75,18 +80,21 @@ impl ActivePool for Contract { storage.asset_amount.insert(asset_id, new_amount); transfer(address, asset_id, amount); } + // Increase the USDF debt for a given asset #[storage(read, write)] fn increase_usdf_debt(amount: u64, asset_id: AssetId) { require_caller_is_bo_or_tm(); let new_debt = storage.usdf_debt_amount.get(asset_id).try_read().unwrap_or(0) + amount; storage.usdf_debt_amount.insert(asset_id, new_debt); } + // Decrease the USDF debt for a given asset #[storage(read, write)] fn decrease_usdf_debt(amount: u64, asset_id: AssetId) { require_caller_is_bo_or_tm_or_sp_or_pm(); let new_debt = storage.usdf_debt_amount.get(asset_id).read() - amount; storage.usdf_debt_amount.insert(asset_id, new_debt); } + // Send the collateral asset to the Default Pool #[storage(read, write)] fn send_asset_to_default_pool(amount: u64, asset_id: AssetId) { require_caller_is_bo_or_tm_or_sp_or_pm(); diff --git a/contracts/borrow-operations-contract/src/data_structures.sw b/contracts/borrow-operations-contract/src/data_structures.sw index 563a3cc6..350db590 100644 --- a/contracts/borrow-operations-contract/src/data_structures.sw +++ b/contracts/borrow-operations-contract/src/data_structures.sw @@ -1,5 +1,10 @@ library; +pub struct AssetContracts { + pub trove_manager: ContractId, + pub oracle: ContractId, +} + pub struct LocalVariables_OpenTrove { pub price: u64, pub usdf_fee: u64, @@ -11,11 +16,6 @@ pub struct LocalVariables_OpenTrove { pub array_index: u64, } -pub struct AssetContracts { - pub trove_manager: ContractId, - pub oracle: ContractId, -} - impl LocalVariables_OpenTrove { pub fn new() -> Self { LocalVariables_OpenTrove { diff --git a/contracts/borrow-operations-contract/src/main.sw b/contracts/borrow-operations-contract/src/main.sw index 680af36d..9abbd238 100644 --- a/contracts/borrow-operations-contract/src/main.sw +++ b/contracts/borrow-operations-contract/src/main.sw @@ -1,9 +1,18 @@ contract; +// This contract, BorrowOperations, manages borrowing operations for the USDF stablecoin system. +// It handles opening and adjusting troves, which are collateralized debt positions. +// The contract interacts with various other components of the system +// +// Key functionalities include: +// - Opening new troves +// - Adjusting existing troves (adding/removing collateral, borrowing/repaying USDF) +// - Closing troves +// - Managing multiple collateral asset types +// - Enforcing system parameters and stability conditions mod data_structures; use ::data_structures::{AssetContracts, LocalVariables_AdjustTrove, LocalVariables_OpenTrove}; - use libraries::trove_manager_interface::data_structures::Status; use libraries::active_pool_interface::ActivePool; use libraries::token_interface::Token; @@ -85,6 +94,7 @@ impl BorrowOperations for Contract { .insert(asset_contract, asset_contracts); } // --- Borrower Trove Operations --- + // Open a new trove by borrowing USDF #[storage(read, write), payable] fn open_trove(usdf_amount: u64, upper_hint: Identity, lower_hint: Identity) { require_valid_asset_id(); @@ -127,6 +137,7 @@ impl BorrowOperations for Contract { asset_contract, ); } + // Add collateral to an existing trove #[storage(read, write), payable] fn add_coll(upper_hint: Identity, lower_hint: Identity) { require_valid_asset_id(); @@ -142,6 +153,7 @@ impl BorrowOperations for Contract { msg_asset_id(), ); } + // Withdraw collateral from an existing trove #[storage(read, write)] fn withdraw_coll( amount: u64, @@ -161,6 +173,7 @@ impl BorrowOperations for Contract { asset_contract, ); } + // Withdraw USDF from an existing trove #[storage(read, write)] fn withdraw_usdf( amount: u64, @@ -180,6 +193,7 @@ impl BorrowOperations for Contract { asset_contract, ); } + // Repay USDF for an existing trove #[storage(read, write), payable] fn repay_usdf( upper_hint: Identity, @@ -199,6 +213,7 @@ impl BorrowOperations for Contract { asset_contract, ); } + // Close an existing trove #[storage(read, write), payable] fn close_trove(asset_contract: AssetId) { let asset_contracts_cache = storage.asset_contracts.get(asset_contract).read(); @@ -233,6 +248,7 @@ impl BorrowOperations for Contract { transfer(borrower, storage.usdf_asset_id.read(), excess_usdf_returned); } } + // Claim collateral from liquidations #[storage(read)] fn claim_collateral(asset: AssetId) { let coll_surplus = abi(CollSurplusPool, storage.coll_surplus_pool_contract.read().bits()); @@ -243,6 +259,9 @@ impl BorrowOperations for Contract { return storage.usdf_asset_id.read(); } } + +// --- Internal Functions --- + #[storage(read)] fn internal_trigger_borrowing_fee( usdf_amount: u64, diff --git a/contracts/borrow-operations-contract/tests/failure.rs b/contracts/borrow-operations-contract/tests/failure.rs index c5476e85..56b2f191 100644 --- a/contracts/borrow-operations-contract/tests/failure.rs +++ b/contracts/borrow-operations-contract/tests/failure.rs @@ -52,8 +52,8 @@ async fn fails_open_two_troves_of_same_coll_type() { &contracts.active_pool, col_amount, debt_amount, - Identity::Address([0; 32].into()), - Identity::Address([0; 32].into()), + Identity::Address(Address::zeroed()), + Identity::Address(Address::zeroed()), ) .await .unwrap(); @@ -71,8 +71,8 @@ async fn fails_open_two_troves_of_same_coll_type() { &contracts.active_pool, col_amount, debt_amount, - Identity::Address([0; 32].into()), - Identity::Address([0; 32].into()), + Identity::Address(Address::zeroed()), + Identity::Address(Address::zeroed()), ) .await .is_err(); @@ -211,8 +211,8 @@ async fn fails_open_trove_under_minimum_collateral_ratio() { &contracts.active_pool, coll_amount, debt_amount, - Identity::Address([0; 32].into()), - Identity::Address([0; 32].into()), + Identity::Address(Address::zeroed()), + Identity::Address(Address::zeroed()), ) .await .is_err(); @@ -257,8 +257,8 @@ async fn fails_open_trove_under_min_usdf_required() { &contracts.active_pool, coll_amount, debt_amount, - Identity::Address([0; 32].into()), - Identity::Address([0; 32].into()), + Identity::Address(Address::zeroed()), + Identity::Address(Address::zeroed()), ) .await .is_err(); @@ -303,8 +303,8 @@ async fn fails_reduce_debt_under_min_usdf_required() { &contracts.active_pool, coll_amount, debt_amount, - Identity::Address([0; 32].into()), - Identity::Address([0; 32].into()), + Identity::Address(Address::zeroed()), + Identity::Address(Address::zeroed()), ) .await .unwrap(); @@ -323,8 +323,8 @@ async fn fails_reduce_debt_under_min_usdf_required() { &contracts.asset_contracts[0].trove_manager, &contracts.active_pool, 300 * PRECISION, - Identity::Address([0; 32].into()), - Identity::Address([0; 32].into()), + Identity::Address(Address::zeroed()), + Identity::Address(Address::zeroed()), ) .await .is_err(); @@ -370,8 +370,8 @@ async fn fails_decrease_collateral_under_mcr() { &contracts.active_pool, coll_amount, debt_amount, - Identity::Address([0; 32].into()), - Identity::Address([0; 32].into()), + Identity::Address(Address::zeroed()), + Identity::Address(Address::zeroed()), ) .await .unwrap(); @@ -386,8 +386,8 @@ async fn fails_decrease_collateral_under_mcr() { &contracts.asset_contracts[0].trove_manager, &contracts.active_pool, 600 * PRECISION, - Identity::Address([0; 32].into()), - Identity::Address([0; 32].into()), + Identity::Address(Address::zeroed()), + Identity::Address(Address::zeroed()), ) .await .is_err(); @@ -448,8 +448,8 @@ async fn fails_incorrect_token_as_collateral_or_repayment() { &contracts.active_pool, 1_200 * PRECISION, 600 * PRECISION, - Identity::Address([0; 32].into()), - Identity::Address([0; 32].into()), + Identity::Address(Address::zeroed()), + Identity::Address(Address::zeroed()), ) .await .is_err(); @@ -473,8 +473,8 @@ async fn fails_incorrect_token_as_collateral_or_repayment() { &contracts.active_pool, 1_200 * PRECISION, 600 * PRECISION, - Identity::Address([0; 32].into()), - Identity::Address([0; 32].into()), + Identity::Address(Address::zeroed()), + Identity::Address(Address::zeroed()), ) .await .unwrap(); @@ -490,8 +490,8 @@ async fn fails_incorrect_token_as_collateral_or_repayment() { &contracts.asset_contracts[0].trove_manager, &contracts.active_pool, 1 * PRECISION, - Identity::Address([0; 32].into()), - Identity::Address([0; 32].into()), + Identity::Address(Address::zeroed()), + Identity::Address(Address::zeroed()), ) .await .is_err(); @@ -531,8 +531,8 @@ async fn fails_incorrect_token_as_collateral_or_repayment() { &contracts.asset_contracts[0].trove_manager, &contracts.active_pool, 1 * PRECISION, - Identity::Address([0; 32].into()), - Identity::Address([0; 32].into()), + Identity::Address(Address::zeroed()), + Identity::Address(Address::zeroed()), ) .await .is_err(); diff --git a/contracts/borrow-operations-contract/tests/success.rs b/contracts/borrow-operations-contract/tests/success.rs index 23890ea1..46f8d4f4 100644 --- a/contracts/borrow-operations-contract/tests/success.rs +++ b/contracts/borrow-operations-contract/tests/success.rs @@ -53,8 +53,8 @@ async fn proper_creating_trove() { &contracts.active_pool, deposit_amount, borrow_amount, - Identity::Address([0; 32].into()), - Identity::Address([0; 32].into()), + Identity::Address(Address::zeroed()), + Identity::Address(Address::zeroed()), ) .await .unwrap(); @@ -205,8 +205,8 @@ async fn proper_increase_collateral() { &contracts.active_pool, deposit_amount, borrow_amount, - Identity::Address([0; 32].into()), - Identity::Address([0; 32].into()), + Identity::Address(Address::zeroed()), + Identity::Address(Address::zeroed()), ) .await .unwrap(); @@ -222,8 +222,8 @@ async fn proper_increase_collateral() { &contracts.asset_contracts[0].trove_manager, &contracts.active_pool, deposit_amount, - Identity::Address([0; 32].into()), - Identity::Address([0; 32].into()), + Identity::Address(Address::zeroed()), + Identity::Address(Address::zeroed()), ) .await .unwrap(); @@ -358,8 +358,8 @@ async fn proper_decrease_collateral() { &contracts.active_pool, deposit_amount, borrow_amount, - Identity::Address([0; 32].into()), - Identity::Address([0; 32].into()), + Identity::Address(Address::zeroed()), + Identity::Address(Address::zeroed()), ) .await; @@ -375,8 +375,8 @@ async fn proper_decrease_collateral() { &contracts.asset_contracts[0].trove_manager, &contracts.active_pool, withdraw_amount, - Identity::Address([0; 32].into()), - Identity::Address([0; 32].into()), + Identity::Address(Address::zeroed()), + Identity::Address(Address::zeroed()), ) .await .unwrap(); @@ -531,8 +531,8 @@ async fn proper_increase_debt() { &contracts.active_pool, deposit_amount, borrow_amount, - Identity::Address([0; 32].into()), - Identity::Address([0; 32].into()), + Identity::Address(Address::zeroed()), + Identity::Address(Address::zeroed()), ) .await .unwrap(); @@ -549,8 +549,8 @@ async fn proper_increase_debt() { &contracts.asset_contracts[0].trove_manager, &contracts.active_pool, 200 * PRECISION, - Identity::Address([0; 32].into()), - Identity::Address([0; 32].into()), + Identity::Address(Address::zeroed()), + Identity::Address(Address::zeroed()), ) .await; @@ -699,8 +699,8 @@ async fn proper_decrease_debt() { &contracts.active_pool, deposit_amount, borrow_amount, - Identity::Address([0; 32].into()), - Identity::Address([0; 32].into()), + Identity::Address(Address::zeroed()), + Identity::Address(Address::zeroed()), ) .await .unwrap(); @@ -717,8 +717,8 @@ async fn proper_decrease_debt() { &contracts.asset_contracts[0].trove_manager, &contracts.active_pool, repay_amount, - Identity::Address([0; 32].into()), - Identity::Address([0; 32].into()), + Identity::Address(Address::zeroed()), + Identity::Address(Address::zeroed()), ) .await .unwrap(); @@ -890,8 +890,8 @@ async fn proper_open_multiple_troves() { &contracts.active_pool, deposit_amount1, borrow_amount1, - Identity::Address([0; 32].into()), - Identity::Address([0; 32].into()), + Identity::Address(Address::zeroed()), + Identity::Address(Address::zeroed()), ) .await .unwrap(); @@ -911,8 +911,8 @@ async fn proper_open_multiple_troves() { &contracts.active_pool, deposit_amount2, borrow_amount2, - Identity::Address([0; 32].into()), - Identity::Address([0; 32].into()), + Identity::Address(Address::zeroed()), + Identity::Address(Address::zeroed()), ) .await .unwrap(); @@ -1039,8 +1039,8 @@ async fn proper_close_trove() { &contracts.active_pool, deposit_amount1, borrow_amount1, - Identity::Address([0; 32].into()), - Identity::Address([0; 32].into()), + Identity::Address(Address::zeroed()), + Identity::Address(Address::zeroed()), ) .await .unwrap(); @@ -1076,8 +1076,8 @@ async fn proper_close_trove() { &contracts.active_pool, deposit_amount2, borrow_amount2, - Identity::Address([0; 32].into()), - Identity::Address([0; 32].into()), + Identity::Address(Address::zeroed()), + Identity::Address(Address::zeroed()), ) .await .unwrap(); @@ -1171,8 +1171,8 @@ async fn proper_close_trove() { &contracts.active_pool, 2000 * PRECISION, 1000 * PRECISION, - Identity::Address([0; 32].into()), - Identity::Address([0; 32].into()), + Identity::Address(Address::zeroed()), + Identity::Address(Address::zeroed()), ) .await .unwrap(); @@ -1217,8 +1217,8 @@ async fn proper_creating_trove_with_2nd_asset() { &contracts.active_pool, deposit_amount1, borrow_amount1, - Identity::Address([0; 32].into()), - Identity::Address([0; 32].into()), + Identity::Address(Address::zeroed()), + Identity::Address(Address::zeroed()), ) .await .unwrap(); @@ -1374,8 +1374,8 @@ async fn proper_creating_trove_with_2nd_asset() { &contracts.active_pool, deposit_amount2, borrow_amount2, - Identity::Address([0; 32].into()), - Identity::Address([0; 32].into()), + Identity::Address(Address::zeroed()), + Identity::Address(Address::zeroed()), ) .await .unwrap(); @@ -1395,8 +1395,8 @@ async fn proper_creating_trove_with_2nd_asset() { &contracts.active_pool, deposit_amount1, borrow_amount1, - Identity::Address([0; 32].into()), - Identity::Address([0; 32].into()), + Identity::Address(Address::zeroed()), + Identity::Address(Address::zeroed()), ) .await .unwrap(); diff --git a/contracts/community-issuance-contract/src/main.sw b/contracts/community-issuance-contract/src/main.sw index 19758c2f..81ecb6e0 100644 --- a/contracts/community-issuance-contract/src/main.sw +++ b/contracts/community-issuance-contract/src/main.sw @@ -1,4 +1,19 @@ contract; +// This contract, CommunityIssuance, manages the issuance of FPT (Fluid Protocol Token) to the Stability Pool. +// It controls the distribution of FPT over time, implementing a decay function for token release. +// +// Key functionalities include: +// - Initializing the contract with necessary parameters +// - Calculating and issuing FPT based on time elapsed since deployment +// - Managing the transition of rewards distribution from an initial rapid issuance to a more gradual long-term rate +// - Interfacing with the Stability Pool to send FPT +// - Providing admin functions for contract management +// +// The contract uses a mathematical model to determine token issuance, ensuring a controlled +// and predictable distribution of FPT to incentivize participation in the Stability Pool. +// It also handles the transition period between different issuance rates, allowing for +// a smooth change in the token distribution strategy over time. + mod utils; diff --git a/contracts/community-issuance-contract/tests/harness.rs b/contracts/community-issuance-contract/tests/harness.rs index 692a9d78..209b1b26 100644 --- a/contracts/community-issuance-contract/tests/harness.rs +++ b/contracts/community-issuance-contract/tests/harness.rs @@ -75,8 +75,8 @@ async fn test_emissions() { &contracts.active_pool, 1_200 * PRECISION, 600 * PRECISION, - Identity::Address([0; 32].into()), - Identity::Address([0; 32].into()), + Identity::Address(Address::zeroed()), + Identity::Address(Address::zeroed()), ) .await .unwrap(); @@ -205,8 +205,8 @@ async fn test_admin_start_rewards_increase_transition() { &contracts.active_pool, 1_200 * PRECISION, 600 * PRECISION, - Identity::Address([0; 32].into()), - Identity::Address([0; 32].into()), + Identity::Address(Address::zeroed()), + Identity::Address(Address::zeroed()), ) .await .unwrap(); @@ -325,8 +325,8 @@ async fn test_public_start_rewards_increase_transition_after_deadline() { &contracts.active_pool, 1_200 * PRECISION, 600 * PRECISION, - Identity::Address([0; 32].into()), - Identity::Address([0; 32].into()), + Identity::Address(Address::zeroed()), + Identity::Address(Address::zeroed()), ) .await .unwrap(); @@ -476,8 +476,8 @@ async fn test_emissions_multiple_deposits() { &contracts.active_pool, 1_200 * PRECISION, 600 * PRECISION, - Identity::Address([0; 32].into()), - Identity::Address([0; 32].into()), + Identity::Address(Address::zeroed()), + Identity::Address(Address::zeroed()), ) .await .unwrap(); @@ -495,8 +495,8 @@ async fn test_emissions_multiple_deposits() { &contracts.active_pool, 1_200 * PRECISION, 600 * PRECISION, - Identity::Address([0; 32].into()), - Identity::Address([0; 32].into()), + Identity::Address(Address::zeroed()), + Identity::Address(Address::zeroed()), ) .await .unwrap(); @@ -514,8 +514,8 @@ async fn test_emissions_multiple_deposits() { &contracts.active_pool, 1_200 * PRECISION, 600 * PRECISION, - Identity::Address([0; 32].into()), - Identity::Address([0; 32].into()), + Identity::Address(Address::zeroed()), + Identity::Address(Address::zeroed()), ) .await .unwrap(); diff --git a/contracts/default-pool-contract/src/main.sw b/contracts/default-pool-contract/src/main.sw index f28b4cc3..e5416a98 100644 --- a/contracts/default-pool-contract/src/main.sw +++ b/contracts/default-pool-contract/src/main.sw @@ -1,4 +1,9 @@ contract; +// The Default Pool holds the Asset and USDF debt (but not USDF tokens) from liquidations that have been redistributed +// to active troves but not yet "applied", i.e. not yet recorded on a recipient active trove's struct. +// +// When a trove makes an operation that applies its pending Asset and USDF debt, its pending Asset and USDF debt is moved +// from the Default Pool to the Active Pool. use libraries::default_pool_interface::DefaultPool; use libraries::active_pool_interface::ActivePool; diff --git a/contracts/fpt-staking-contract/tests/success.rs b/contracts/fpt-staking-contract/tests/success.rs index ca3cc341..7873cf06 100644 --- a/contracts/fpt-staking-contract/tests/success.rs +++ b/contracts/fpt-staking-contract/tests/success.rs @@ -174,8 +174,8 @@ async fn proper_staking_multiple_positions() { &contracts.active_pool, 40_000 * PRECISION, 20_000 * PRECISION, - Identity::Address([0; 32].into()), - Identity::Address([0; 32].into()), + Identity::Address(Address::zeroed()), + Identity::Address(Address::zeroed()), ) .await .unwrap(); diff --git a/contracts/fpt-token-contract/src/main.sw b/contracts/fpt-token-contract/src/main.sw index 87539792..cb3a4cc3 100644 --- a/contracts/fpt-token-contract/src/main.sw +++ b/contracts/fpt-token-contract/src/main.sw @@ -1,4 +1,16 @@ contract; +// This contract, FPTToken, implements the Fluid Protocol Token (FPT) functionality. +// FPT is the native token of the Fluid Protocol +// +// Key functionalities include: +// - Minting and distributing the initial supply of FPT tokens +// - Managing token transfers and approvals +// - Interfacing with the Vesting and Community Issuance contracts +// +// The contract follows the SRC-20 standard for native assets on the Fuel network, +// ensuring compatibility with the broader ecosystem. It manages a fixed total supply +// of 100 million FPT tokens, distributed between the Vesting contract and the +// Community Issuance contract upon initialization. use libraries::fpt_token_interface::FPTToken; use libraries::fluid_math::{DECIMAL_PRECISION, get_default_asset_id, ZERO_B256,}; @@ -25,12 +37,12 @@ storage { is_initialized: bool = false, default_asset: AssetId = AssetId::zero(), } - -// import fluid math decinals here +// Using https://docs.fuel.network/docs/sway-standards/src-20-native-asset/ as reference +// import fluid math decimals here pub const TOTAL_SUPPLY: u64 = 100_000_000; impl FPTToken for Contract { ////////////////////////////////////// - // Owner methods + // Initialization method ////////////////////////////////////// #[storage(read, write)] fn initialize( @@ -47,7 +59,6 @@ impl FPTToken for Contract { storage .community_issuance_contract .write(community_issuance_contract); - // storage.config.write(config); mint_to( Identity::ContractId(vesting_contract), ZERO_B256, diff --git a/contracts/hint-helper-contract/src/main.sw b/contracts/hint-helper-contract/src/main.sw index 357da6be..def98fc6 100644 --- a/contracts/hint-helper-contract/src/main.sw +++ b/contracts/hint-helper-contract/src/main.sw @@ -1,5 +1,13 @@ contract; - +// This contract, HintHelper, provides approximate hinting functionality for the system. +// It is used to find a trove with a nominal ICR closest to a given target ICR (cr). +// The hint is found by simulating a random walk through the trove list. +// +// Key functionalities include: +// - Initializing the contract with the SortedTroves contract ID +// - Providing a function to get an approximate hint for the closest trove +// - Using a random seed to ensure different hints for different inputs +// // To the auditor: This contract is not used in the system. It is only used for querying the system. use libraries::trove_manager_interface::TroveManager; diff --git a/contracts/mock-pyth-contract/src/main.sw b/contracts/mock-pyth-contract/src/main.sw index 73160d5c..164e60dc 100644 --- a/contracts/mock-pyth-contract/src/main.sw +++ b/contracts/mock-pyth-contract/src/main.sw @@ -1,4 +1,13 @@ contract; +// This contract, MockPyth, is a mock implementation of the Pyth oracle interface. +// It is used for testing and simulation purposes within the Fluid Protocol. +// +// Key functionalities include: +// - Simulating price feeds for testing purposes +// - Providing a mock interface for interacting with the Pyth oracle +// - Ensuring compatibility with the Pyth oracle interface for testing +// +// To the auditor: This contract is not used in the system. It is only used for testing. use libraries::oracle_interface::{PythCore, PythError, PythPrice, PythPriceFeed, PythPriceFeedId}; use std::{block::timestamp, hash::Hash}; diff --git a/contracts/mock-redstone-contract/src/main.sw b/contracts/mock-redstone-contract/src/main.sw index 7d13aa8c..89d91a3a 100644 --- a/contracts/mock-redstone-contract/src/main.sw +++ b/contracts/mock-redstone-contract/src/main.sw @@ -1,4 +1,13 @@ contract; +// This contract, MockRedstone, is a mock implementation of the Redstone oracle interface. +// It is used for testing and simulation purposes within the Fluid Protocol. +// +// Key functionalities include: +// - Simulating price feeds for testing purposes +// - Providing a mock interface for interacting with the Redstone oracle +// - Ensuring compatibility with the Redstone oracle interface for testing +// +// To the auditor: This contract is not used in the system. It is only used for testing. use libraries::oracle_interface::RedstoneCore; use std::hash::Hash; diff --git a/contracts/multi-trove-getter-contract/src/main.sw b/contracts/multi-trove-getter-contract/src/main.sw index 45503f66..2f39d309 100644 --- a/contracts/multi-trove-getter-contract/src/main.sw +++ b/contracts/multi-trove-getter-contract/src/main.sw @@ -1,5 +1,7 @@ contract; - +// This contract, MultiTroveGetter, is used to retrieve multiple troves from the SortedTroves contract. +// It is used for querying the system. +// // To the auditor: This contract is not used in the system. It is only used for querying the system. use libraries::trove_manager_interface::TroveManager; diff --git a/contracts/oracle-contract/src/main.sw b/contracts/oracle-contract/src/main.sw index a42defe8..e3cad1fe 100644 --- a/contracts/oracle-contract/src/main.sw +++ b/contracts/oracle-contract/src/main.sw @@ -1,4 +1,19 @@ contract; +// This contract, Oracle, serves as an interface to query asset prices from either Pyth or Redstone oracles. +// +// Key functionalities include: +// - Providing a unified interface to fetch price data from different oracle sources +// - Converting price data from different precisions to a standardized format +// - Implementing safeguards against potential precision issues +// - Prioritizing price sources based on availability and recency +// +// Price Priority: +// 1. Pyth Oracle: The contract first attempts to fetch the price from the Pyth oracle. +// 2. Redstone Oracle: If the Pyth price is unavailable or outdated, the contract falls back to the Redstone oracle. +// +// This prioritization ensures that the most reliable and recent price data is used, +// enhancing the overall stability and accuracy of the Fluid Protocol. + use libraries::{ fluid_math::convert_precision, diff --git a/contracts/protocol-manager-contract/Forc.toml b/contracts/protocol-manager-contract/Forc.toml index 5a367150..d2f31183 100644 --- a/contracts/protocol-manager-contract/Forc.toml +++ b/contracts/protocol-manager-contract/Forc.toml @@ -6,3 +6,5 @@ name = "protocol-manager-contract" [dependencies] libraries = { path = "../../libraries" } +standards = { git = "https://github.com/FuelLabs/sway-standards", tag = "v0.6.0" } +sway_libs = { git = "https://github.com/FuelLabs/sway-libs", tag = "v0.23.1" } diff --git a/contracts/protocol-manager-contract/src/main.sw b/contracts/protocol-manager-contract/src/main.sw index 41e26a28..804bbdef 100644 --- a/contracts/protocol-manager-contract/src/main.sw +++ b/contracts/protocol-manager-contract/src/main.sw @@ -1,5 +1,12 @@ contract; - +// This contract, ProtocolManager, is responsible for managing the overall protocol operations. +// It acts as a central coordinator for various critical contracts and interfaces within the system. +// +// Key functionalities include: +// - Initializing the protocol by registering asset contracts and setting up necessary connections +// - Administering the ownership and access control mechanisms +// - Facilitating the redemption process for users +// - Interfacing with the Stability Pool for FPT issuance mod data_structures; use ::data_structures::{AssetContracts, AssetInfo, RedemptionTotals}; use libraries::stability_pool_interface::StabilityPool; @@ -15,6 +22,8 @@ use libraries::protocol_manager_interface::ProtocolManager; use libraries::usdf_token_interface::USDFToken; use libraries::fpt_staking_interface::FPTStaking; use libraries::fluid_math::*; +use sway_libs::ownership::*; +use standards::src5::*; use std::{ asset::transfer, auth::msg_sender, @@ -25,10 +34,11 @@ use std::{ msg_amount, }, hash::*, + logging::log, storage::storage_vec::*, }; storage { - admin: Identity = Identity::Address(Address::zero()), + owner: State = State::Uninitialized, borrow_operations_contract: ContractId = ContractId::zero(), fpt_staking_contract: ContractId = ContractId::zero(), usdf_token_contract: ContractId = ContractId::zero(), @@ -52,7 +62,7 @@ impl ProtocolManager for Contract { default_pool: ContractId, active_pool: ContractId, sorted_troves: ContractId, - admin: Identity, + initial_owner: Identity, ) { require( storage @@ -60,7 +70,7 @@ impl ProtocolManager for Contract { .read() == false, "ProtocolManager: Already initialized", ); - storage.admin.write(admin); + initialize_ownership(initial_owner); storage.borrow_operations_contract.write(borrow_operations); storage.fpt_staking_contract.write(fpt_staking); storage.stability_pool_contract.write(stability_pool); @@ -77,7 +87,7 @@ impl ProtocolManager for Contract { trove_manager: ContractId, oracle: ContractId, ) { - require_is_admin(); + only_owner(); let stability_pool = abi(StabilityPool, storage.stability_pool_contract.read().bits()); let borrow_operations = abi(BorrowOperations, storage.borrow_operations_contract.read().bits()); let usdf_token = abi(USDFToken, storage.usdf_token_contract.read().bits()); @@ -108,8 +118,14 @@ impl ProtocolManager for Contract { } #[storage(read, write)] fn renounce_admin() { - require_is_admin(); - storage.admin.write(null_identity_address()); + only_owner(); + storage + .owner + .write(State::Initialized(Identity::Address(Address::zero()))); + } + #[storage(read)] + fn owner() -> State { + storage.owner.read() } #[storage(read), payable] fn redeem_collateral( @@ -224,18 +240,13 @@ impl ProtocolManager for Contract { } // --- Helper functions --- #[storage(read)] -fn require_is_admin() { - let caller = msg_sender().unwrap(); - let admin = storage.admin.read(); - require(caller == admin, "ProtocolManager: Caller is not admin"); -} -#[storage(read)] fn require_valid_usdf_id() { require( msg_asset_id() == get_default_asset_id(storage.usdf_token_contract.read()), "ProtocolManager: Invalid asset being transfered", ); } + #[storage(read)] fn get_all_assets_info() -> AssetInfo { let mut assets: Vec = Vec::new(); @@ -285,7 +296,7 @@ fn get_all_assets_info() -> AssetInfo { current_crs: current_crs, } } -// TODO write comments +// Find the borrower with the lowest collateral ratio fn find_min_borrower(current_borrowers: Vec, current_crs: Vec) -> (Identity, u64) { let mut min_borrower = current_borrowers.get(0).unwrap(); let mut min_cr = current_crs.get(0).unwrap(); diff --git a/contracts/protocol-manager-contract/tests/success_redemptions.rs b/contracts/protocol-manager-contract/tests/success_redemptions.rs index 933bff44..92aba62a 100644 --- a/contracts/protocol-manager-contract/tests/success_redemptions.rs +++ b/contracts/protocol-manager-contract/tests/success_redemptions.rs @@ -74,8 +74,8 @@ async fn proper_redemption_from_partially_closed() { &contracts.active_pool, 10_000 * PRECISION, 5_000 * PRECISION, - Identity::Address([0; 32].into()), - Identity::Address([0; 32].into()), + Identity::Address(Address::zeroed()), + Identity::Address(Address::zeroed()), ) .await .unwrap(); @@ -98,8 +98,8 @@ async fn proper_redemption_from_partially_closed() { &contracts.active_pool, 9_000 * PRECISION, 5_000 * PRECISION, - Identity::Address([0; 32].into()), - Identity::Address([0; 32].into()), + Identity::Address(Address::zeroed()), + Identity::Address(Address::zeroed()), ) .await .unwrap(); @@ -122,8 +122,8 @@ async fn proper_redemption_from_partially_closed() { &contracts.active_pool, 8_000 * PRECISION, 5_000 * PRECISION, - Identity::Address([0; 32].into()), - Identity::Address([0; 32].into()), + Identity::Address(Address::zeroed()), + Identity::Address(Address::zeroed()), ) .await .unwrap(); @@ -290,8 +290,8 @@ async fn proper_redemption_with_a_trove_closed_fully() { &contracts.active_pool, coll1, debt1, - Identity::Address([0; 32].into()), - Identity::Address([0; 32].into()), + Identity::Address(Address::zeroed()), + Identity::Address(Address::zeroed()), ) .await .unwrap(); @@ -316,8 +316,8 @@ async fn proper_redemption_with_a_trove_closed_fully() { &contracts.active_pool, coll2, debt2, - Identity::Address([0; 32].into()), - Identity::Address([0; 32].into()), + Identity::Address(Address::zeroed()), + Identity::Address(Address::zeroed()), ) .await .unwrap(); @@ -342,8 +342,8 @@ async fn proper_redemption_with_a_trove_closed_fully() { &contracts.active_pool, coll3, debt3, - Identity::Address([0; 32].into()), - Identity::Address([0; 32].into()), + Identity::Address(Address::zeroed()), + Identity::Address(Address::zeroed()), ) .await .unwrap(); diff --git a/contracts/sorted-troves-contract/tests/functions/sort.rs b/contracts/sorted-troves-contract/tests/functions/sort.rs index e52ea21f..8a25fd0d 100644 --- a/contracts/sorted-troves-contract/tests/functions/sort.rs +++ b/contracts/sorted-troves-contract/tests/functions/sort.rs @@ -11,7 +11,7 @@ use test_utils::interfaces::sorted_troves::sorted_troves_abi; async fn proper_initialization() { let (sorted_troves, trove_manager, _wallet, _wallet2, _) = setup(Some(4)).await; let max_size: u64 = 1000; - let asset: AssetId = AssetId::from([0; 32]); + let asset: AssetId = AssetId::zeroed(); // Increment the counter let _ = initialize_st_and_tm(&sorted_troves, &trove_manager, max_size, asset).await; @@ -30,7 +30,7 @@ async fn proper_initialization() { assert_eq!(result_size.value, 0); let first = sorted_troves_abi::get_first(&sorted_troves, asset).await; - assert_eq!(first.value, Identity::Address([0; 32].into())); + assert_eq!(first.value, Identity::Address(Address::zeroed())); let last = sorted_troves .methods() @@ -38,14 +38,14 @@ async fn proper_initialization() { .call() .await .unwrap(); - assert_eq!(last.value, Identity::Address([0; 32].into())); + assert_eq!(last.value, Identity::Address(Address::zeroed())); } #[tokio::test] async fn proper_head_and_tails_after_insert() { let (sorted_troves, trove_manager, wallet, wallet2, _) = setup(Some(4)).await; let max_size: u64 = 1000; - let asset: AssetId = AssetId::from([0; 32]); + let asset: AssetId = AssetId::zeroed(); // Increment the counter let _ = initialize_st_and_tm(&sorted_troves, &trove_manager, max_size, asset.into()).await; @@ -66,8 +66,8 @@ async fn proper_head_and_tails_after_insert() { .methods() .find_insert_position( 100, - Identity::Address([0; 32].into()), - Identity::Address([0; 32].into()), + Identity::Address(Address::zeroed()), + Identity::Address(Address::zeroed()), asset.into(), ) .with_contracts(&[&trove_manager]) @@ -79,8 +79,8 @@ async fn proper_head_and_tails_after_insert() { assert_eq!( result.value, ( - Identity::Address([0; 32].into()), - Identity::Address([0; 32].into()) + Identity::Address(Address::zeroed()), + Identity::Address(Address::zeroed()) ), "Empty list should return 0, 0 placements" ); @@ -90,8 +90,8 @@ async fn proper_head_and_tails_after_insert() { &sorted_troves, Identity::Address(wallet.address().into()), 100, - Identity::Address([0; 32].into()), - Identity::Address([0; 32].into()), + Identity::Address(Address::zeroed()), + Identity::Address(Address::zeroed()), asset.into(), ) .await; @@ -127,8 +127,8 @@ async fn proper_head_and_tails_after_insert() { &sorted_troves, Identity::Address(wallet2.address().into()), 200, - Identity::Address([0; 32].into()), - Identity::Address([0; 32].into()), + Identity::Address(Address::zeroed()), + Identity::Address(Address::zeroed()), asset.into(), ) .await; @@ -168,8 +168,8 @@ async fn proper_head_and_tails_after_insert() { &sorted_troves, Identity::ContractId(trove_manager.contract_id().into()), 300, - Identity::Address([0; 32].into()), - Identity::Address([0; 32].into()), + Identity::Address(Address::zeroed()), + Identity::Address(Address::zeroed()), asset.into(), ) .await; @@ -209,8 +209,8 @@ async fn proper_head_and_tails_after_insert() { &sorted_troves, Identity::ContractId(sorted_troves.contract_id().into()), 150, - Identity::Address([0; 32].into()), - Identity::Address([0; 32].into()), + Identity::Address(Address::zeroed()), + Identity::Address(Address::zeroed()), asset, ) .await; @@ -250,7 +250,7 @@ async fn proper_head_and_tails_after_insert() { async fn proper_node_neighbors() { let (sorted_troves, trove_manager, wallet, wallet2, _) = setup(Some(4)).await; let max_size: u64 = 1000; - let asset = AssetId::from([0; 32]); + let asset: AssetId = AssetId::zeroed(); // Increment the counter let _ = initialize_st_and_tm(&sorted_troves, &trove_manager, max_size, asset).await; @@ -259,8 +259,8 @@ async fn proper_node_neighbors() { &sorted_troves, Identity::Address(wallet.address().into()), 100, - Identity::Address([0; 32].into()), - Identity::Address([0; 32].into()), + Identity::Address(Address::zeroed()), + Identity::Address(Address::zeroed()), asset, ) .await; @@ -271,8 +271,8 @@ async fn proper_node_neighbors() { let _ = assert_neighbors( &sorted_troves, Identity::Address(wallet.address().into()), - Identity::Address([0; 32].into()), - Identity::Address([0; 32].into()), + Identity::Address(Address::zeroed()), + Identity::Address(Address::zeroed()), asset, ) .await; @@ -282,8 +282,8 @@ async fn proper_node_neighbors() { &sorted_troves, Identity::Address(wallet2.address().into()), 200, - Identity::Address([0; 32].into()), - Identity::Address([0; 32].into()), + Identity::Address(Address::zeroed()), + Identity::Address(Address::zeroed()), asset, ) .await; @@ -294,7 +294,7 @@ async fn proper_node_neighbors() { let _ = assert_neighbors( &sorted_troves, Identity::Address(wallet2.address().into()), - Identity::Address([0; 32].into()), + Identity::Address(Address::zeroed()), Identity::Address(wallet2.address().into()), asset, ); @@ -304,8 +304,8 @@ async fn proper_node_neighbors() { &sorted_troves, Identity::ContractId(trove_manager.contract_id().into()), 300, - Identity::Address([0; 32].into()), - Identity::Address([0; 32].into()), + Identity::Address(Address::zeroed()), + Identity::Address(Address::zeroed()), asset, ) .await; @@ -316,7 +316,7 @@ async fn proper_node_neighbors() { let _ = assert_neighbors( &sorted_troves, Identity::ContractId(trove_manager.contract_id().into()), - Identity::Address([0; 32].into()), + Identity::Address(Address::zeroed()), Identity::Address(wallet2.address().into()), asset, ); @@ -326,8 +326,8 @@ async fn proper_node_neighbors() { &sorted_troves, Identity::ContractId(sorted_troves.contract_id().into()), 150, - Identity::Address([0; 32].into()), - Identity::Address([0; 32].into()), + Identity::Address(Address::zeroed()), + Identity::Address(Address::zeroed()), asset, ) .await; @@ -348,7 +348,7 @@ async fn proper_node_neighbors() { async fn proper_insertion_of_random_nodes() { let max_size: u64 = 10; let (sorted_troves, trove_manager, _wallet, _, _) = setup(Some(4)).await; - let asset = AssetId::from([0; 32]); + let asset = AssetId::zeroed(); let _ = initialize_st_and_tm(&sorted_troves, &trove_manager, max_size, asset).await; @@ -363,7 +363,7 @@ async fn proper_insertion_of_random_nodes() { async fn proper_hint_gas_usage() { let max_size: u64 = 20; let (sorted_troves, trove_manager, _wallet, _, _) = setup(Some(4)).await; - let asset = AssetId::from([0; 32]); + let asset = AssetId::zeroed(); let _ = initialize_st_and_tm(&sorted_troves, &trove_manager, max_size, asset).await; @@ -405,7 +405,7 @@ async fn proper_hint_gas_usage() { Identity::Address(random_addr_2.into()), inbetween_num2, vals[8].0.clone(), - Identity::Address([0; 32].into()), + Identity::Address(Address::zeroed()), asset, ) .await; @@ -425,7 +425,7 @@ async fn proper_hint_gas_usage() { &sorted_troves, Identity::Address(random_addr_3.into()), inbetween_num3, - Identity::Address([0; 32].into()), + Identity::Address(Address::zeroed()), vals[12].0.clone(), asset, ) @@ -446,7 +446,7 @@ async fn proper_hint_gas_usage() { async fn proper_removal() { let max_size: u64 = 10; let (sorted_troves, trove_manager, _wallet, _, _) = setup(Some(4)).await; - let asset = AssetId::from([0; 32]); + let asset = AssetId::zeroed(); let _ = initialize_st_and_tm(&sorted_troves, &trove_manager, max_size, asset).await; let (mut nodes, _) = diff --git a/contracts/sorted-troves-contract/tests/utils/sorted_troves.rs b/contracts/sorted-troves-contract/tests/utils/sorted_troves.rs index ca1bf4b8..9f1a8bbe 100644 --- a/contracts/sorted-troves-contract/tests/utils/sorted_troves.rs +++ b/contracts/sorted-troves-contract/tests/utils/sorted_troves.rs @@ -5,7 +5,10 @@ use test_utils::interfaces::sorted_troves::sorted_troves_abi; use test_utils::interfaces::sorted_troves::SortedTroves; pub mod sorted_troves_utils { - use fuels::{prelude::WalletUnlocked, types::AssetId}; + use fuels::{ + prelude::WalletUnlocked, + types::{Address, AssetId}, + }; use rand::{self, Rng}; use crate::utils::setup::{get_nominal_icr, set_nominal_icr_and_insert}; @@ -44,7 +47,7 @@ pub mod sorted_troves_utils { .await .value; - while next.clone() != Identity::Address([0; 32].into()) { + while next.clone() != Identity::Address(Address::zeroed()) { let current_icr = get_nominal_icr(trove_manager, current.clone()).await.value; let next_icr = get_nominal_icr(trove_manager, next.clone()).await.value; @@ -86,7 +89,7 @@ pub mod sorted_troves_utils { .await .value; - while prev.clone() != Identity::Address([0; 32].into()) { + while prev.clone() != Identity::Address(Address::zeroed()) { let current_icr = get_nominal_icr(trove_manager, current.clone()).await.value; let prev_icr = get_nominal_icr(trove_manager, prev.clone()).await.value; @@ -130,8 +133,8 @@ pub mod sorted_troves_utils { &sorted_troves, Identity::Address(random_address.into()), random_number, - Identity::Address([0; 32].into()), - Identity::Address([0; 32].into()), + Identity::Address(Address::zeroed()), + Identity::Address(Address::zeroed()), asset, ) .await diff --git a/contracts/stability-pool-contract/tests/functions/failure.rs b/contracts/stability-pool-contract/tests/functions/failure.rs index ea22bfce..f61f33e0 100644 --- a/contracts/stability-pool-contract/tests/functions/failure.rs +++ b/contracts/stability-pool-contract/tests/functions/failure.rs @@ -16,7 +16,7 @@ async fn fails_fake_usdf_deposit() { usdf_token_abi::initialize( &fake_usdf, - ContractId::new([0; 32]), + ContractId::zeroed(), Identity::Address(admin.address().into()), Identity::Address(admin.address().into()), ) @@ -55,19 +55,19 @@ async fn fails_unauthorized() { stability_pool_abi::initialize( &stability_pool_attacker, - ContractId::new([0; 32].into()), - ContractId::new([0; 32].into()), - ContractId::new([0; 32].into()), - ContractId::new([0; 32].into()), + ContractId::zeroed(), + ContractId::zeroed(), + ContractId::zeroed(), + ContractId::zeroed(), ) .await .expect_err("Able to initialize stability pool with unauthorized address"); stability_pool_abi::add_asset( &stability_pool_attacker, - ContractId::new([0; 32].into()), - [0; 32].into(), - ContractId::new([0; 32].into()), + ContractId::zeroed(), + AssetId::zeroed(), + ContractId::zeroed(), ) .await .expect_err("Able to add asset with unauthorized address"); diff --git a/contracts/stability-pool-contract/tests/functions/success.rs b/contracts/stability-pool-contract/tests/functions/success.rs index 6fd99491..a8f3e8b2 100644 --- a/contracts/stability-pool-contract/tests/functions/success.rs +++ b/contracts/stability-pool-contract/tests/functions/success.rs @@ -61,8 +61,8 @@ async fn proper_stability_deposit() { &contracts.active_pool, 1_200 * PRECISION, 600 * PRECISION, - Identity::Address([0; 32].into()), - Identity::Address([0; 32].into()), + Identity::Address(Address::zeroed()), + Identity::Address(Address::zeroed()), ) .await .unwrap(); @@ -140,8 +140,8 @@ async fn proper_stability_widthdrawl() { &contracts.active_pool, 1_200 * PRECISION, 600 * PRECISION, - Identity::Address([0; 32].into()), - Identity::Address([0; 32].into()), + Identity::Address(Address::zeroed()), + Identity::Address(Address::zeroed()), ) .await .unwrap(); @@ -241,8 +241,8 @@ async fn proper_one_sp_depositor_position() { &contracts.active_pool, 6_000 * PRECISION, 3_000 * PRECISION, - Identity::Address([0; 32].into()), - Identity::Address([0; 32].into()), + Identity::Address(Address::zeroed()), + Identity::Address(Address::zeroed()), ) .await .unwrap(); @@ -265,8 +265,8 @@ async fn proper_one_sp_depositor_position() { &contracts.active_pool, 1_100 * PRECISION, 1_000 * PRECISION, - Identity::Address([0; 32].into()), - Identity::Address([0; 32].into()), + Identity::Address(Address::zeroed()), + Identity::Address(Address::zeroed()), ) .await .unwrap(); @@ -302,8 +302,8 @@ async fn proper_one_sp_depositor_position() { &contracts.coll_surplus_pool, &contracts.usdf, Identity::Address(liquidated_wallet.address().into()), - Identity::Address([0; 32].into()), - Identity::Address([0; 32].into()), + Identity::Address(Address::zeroed()), + Identity::Address(Address::zeroed()), ) .await .unwrap(); @@ -437,8 +437,8 @@ async fn proper_many_depositors_distribution() { &contracts.active_pool, 6_000 * PRECISION, 3_000 * PRECISION, - Identity::Address([0; 32].into()), - Identity::Address([0; 32].into()), + Identity::Address(Address::zeroed()), + Identity::Address(Address::zeroed()), ) .await .unwrap(); @@ -461,8 +461,8 @@ async fn proper_many_depositors_distribution() { &contracts.active_pool, 1_100 * PRECISION, 1_000 * PRECISION, - Identity::Address([0; 32].into()), - Identity::Address([0; 32].into()), + Identity::Address(Address::zeroed()), + Identity::Address(Address::zeroed()), ) .await .unwrap(); @@ -554,8 +554,8 @@ async fn proper_many_depositors_distribution() { &contracts.coll_surplus_pool, &contracts.usdf, Identity::Address(liquidated_wallet.address().into()), - Identity::Address([0; 32].into()), - Identity::Address([0; 32].into()), + Identity::Address(Address::zeroed()), + Identity::Address(Address::zeroed()), ) .await .unwrap(); @@ -660,8 +660,8 @@ async fn proper_no_reward_when_depositing_and_rewards_already_distributed() { &contracts.active_pool, 6_000 * PRECISION, 3_000 * PRECISION, - Identity::Address([0; 32].into()), - Identity::Address([0; 32].into()), + Identity::Address(Address::zeroed()), + Identity::Address(Address::zeroed()), ) .await .unwrap(); @@ -684,8 +684,8 @@ async fn proper_no_reward_when_depositing_and_rewards_already_distributed() { &contracts.active_pool, 1_100 * PRECISION, 1_000 * PRECISION, - Identity::Address([0; 32].into()), - Identity::Address([0; 32].into()), + Identity::Address(Address::zeroed()), + Identity::Address(Address::zeroed()), ) .await .unwrap(); @@ -727,8 +727,8 @@ async fn proper_no_reward_when_depositing_and_rewards_already_distributed() { &contracts.coll_surplus_pool, &contracts.usdf, Identity::Address(liquidated_wallet.address().into()), - Identity::Address([0; 32].into()), - Identity::Address([0; 32].into()), + Identity::Address(Address::zeroed()), + Identity::Address(Address::zeroed()), ) .await .unwrap(); @@ -885,8 +885,8 @@ async fn proper_one_sp_depositor_position_multiple_assets() { &contracts.coll_surplus_pool, &contracts.usdf, Identity::Address(liquidated_wallet.address().into()), - Identity::Address([0; 32].into()), - Identity::Address([0; 32].into()), + Identity::Address(Address::zeroed()), + Identity::Address(Address::zeroed()), ) .await .unwrap(); @@ -904,8 +904,8 @@ async fn proper_one_sp_depositor_position_multiple_assets() { &contracts.coll_surplus_pool, &contracts.usdf, Identity::Address(liquidated_wallet.address().into()), - Identity::Address([0; 32].into()), - Identity::Address([0; 32].into()), + Identity::Address(Address::zeroed()), + Identity::Address(Address::zeroed()), ) .await .unwrap(); @@ -1092,8 +1092,8 @@ async fn proper_one_sp_depositor_position_new_asset_onboarded_midway() { &contracts.coll_surplus_pool, &contracts.usdf, Identity::Address(liquidated_wallet.address().into()), - Identity::Address([0; 32].into()), - Identity::Address([0; 32].into()), + Identity::Address(Address::zeroed()), + Identity::Address(Address::zeroed()), ) .await .unwrap(); @@ -1172,8 +1172,8 @@ async fn proper_one_sp_depositor_position_new_asset_onboarded_midway() { &contracts.coll_surplus_pool, &contracts.usdf, Identity::Address(liquidated_wallet.address().into()), - Identity::Address([0; 32].into()), - Identity::Address([0; 32].into()), + Identity::Address(Address::zeroed()), + Identity::Address(Address::zeroed()), ) .await .unwrap(); diff --git a/contracts/trove-manager-contract/src/data_structures.sw b/contracts/trove-manager-contract/src/data_structures.sw index f7d72b68..1e75c27b 100644 --- a/contracts/trove-manager-contract/src/data_structures.sw +++ b/contracts/trove-manager-contract/src/data_structures.sw @@ -47,7 +47,7 @@ impl LocalVariablesLiquidationSequence { remaining_usdf_in_stability_pool: 0, i: 0, icr: 0, - borrower: Identity::Address(Address::from(0x0000000000000000000000000000000000000000000000000000000000000000)), + borrower: Identity::Address(Address::zero()), } } } diff --git a/contracts/trove-manager-contract/src/main.sw b/contracts/trove-manager-contract/src/main.sw index 28f9d77c..7ce646bb 100644 --- a/contracts/trove-manager-contract/src/main.sw +++ b/contracts/trove-manager-contract/src/main.sw @@ -1,5 +1,7 @@ contract; - +// The TroveManager contract is responsible for managing the troves in the system. +// It handles the creation, modification, and deletion of troves, as well as the distribution of rewards to trove owners. +// It also interfaces with other core contracts like StabilityPool, ActivePool, and DefaultPool. mod data_structures; mod utils; diff --git a/contracts/trove-manager-contract/tests/failure.rs b/contracts/trove-manager-contract/tests/failure.rs index b1a435da..44745e3d 100644 --- a/contracts/trove-manager-contract/tests/failure.rs +++ b/contracts/trove-manager-contract/tests/failure.rs @@ -1,4 +1,4 @@ -use fuels::types::Identity; +use fuels::types::{Address, Identity}; use test_utils::{ data_structures::PRECISION, interfaces::{ @@ -50,8 +50,8 @@ async fn fails_to_liquidate_trove_not_under_mcr() { &contracts.active_pool, 1_100 * PRECISION, 1_000 * PRECISION, - Identity::Address([0; 32].into()), - Identity::Address([0; 32].into()), + Identity::Address(Address::zeroed()), + Identity::Address(Address::zeroed()), ) .await .unwrap(); @@ -69,8 +69,8 @@ async fn fails_to_liquidate_trove_not_under_mcr() { &contracts.coll_surplus_pool, &contracts.usdf, Identity::Address(wallet1.address().into()), - Identity::Address([0; 32].into()), - Identity::Address([0; 32].into()), + Identity::Address(Address::zeroed()), + Identity::Address(Address::zeroed()), ) .await .expect_err("Improper liquidation of trove not below MCR"); diff --git a/contracts/trove-manager-contract/tests/success_batch_liquidations.rs b/contracts/trove-manager-contract/tests/success_batch_liquidations.rs index b3594543..fd82cb12 100644 --- a/contracts/trove-manager-contract/tests/success_batch_liquidations.rs +++ b/contracts/trove-manager-contract/tests/success_batch_liquidations.rs @@ -114,8 +114,8 @@ async fn proper_batch_liquidations_enough_usdf_in_sp() { Identity::Address(liquidated_wallet.address().into()), Identity::Address(liquidated_wallet2.address().into()), ], - Identity::Address([0; 32].into()), - Identity::Address([0; 32].into()), + Identity::Address(Address::zeroed()), + Identity::Address(Address::zeroed()), ) .await .unwrap(); diff --git a/contracts/trove-manager-contract/tests/success_full_liquidations.rs b/contracts/trove-manager-contract/tests/success_full_liquidations.rs index afb4c7ed..15c4d208 100644 --- a/contracts/trove-manager-contract/tests/success_full_liquidations.rs +++ b/contracts/trove-manager-contract/tests/success_full_liquidations.rs @@ -75,8 +75,8 @@ async fn proper_full_liquidation_enough_usdf_in_sp() { &contracts.active_pool, asset_deposit_to_be_liquidated, usdf_deposit_to_be_liquidated, - Identity::Address([0; 32].into()), - Identity::Address([0; 32].into()), + Identity::Address(Address::zeroed()), + Identity::Address(Address::zeroed()), ) .await .unwrap(); @@ -95,8 +95,8 @@ async fn proper_full_liquidation_enough_usdf_in_sp() { &contracts.active_pool, 10_000 * PRECISION, 5_000 * PRECISION, - Identity::Address([0; 32].into()), - Identity::Address([0; 32].into()), + Identity::Address(Address::zeroed()), + Identity::Address(Address::zeroed()), ) .await .unwrap(); @@ -138,8 +138,8 @@ async fn proper_full_liquidation_enough_usdf_in_sp() { &contracts.coll_surplus_pool, &contracts.usdf, Identity::Address(liquidated_wallet.address().into()), - Identity::Address([0; 32].into()), - Identity::Address([0; 32].into()), + Identity::Address(Address::zeroed()), + Identity::Address(Address::zeroed()), ) .await .unwrap(); @@ -338,8 +338,8 @@ async fn proper_full_liquidation_partial_usdf_in_sp() { &contracts.active_pool, 1_100 * PRECISION, 1_000 * PRECISION, - Identity::Address([0; 32].into()), - Identity::Address([0; 32].into()), + Identity::Address(Address::zeroed()), + Identity::Address(Address::zeroed()), ) .await .unwrap(); @@ -358,8 +358,8 @@ async fn proper_full_liquidation_partial_usdf_in_sp() { &contracts.active_pool, 10_000 * PRECISION, 5_000 * PRECISION, - Identity::Address([0; 32].into()), - Identity::Address([0; 32].into()), + Identity::Address(Address::zeroed()), + Identity::Address(Address::zeroed()), ) .await .unwrap(); @@ -378,8 +378,8 @@ async fn proper_full_liquidation_partial_usdf_in_sp() { &contracts.active_pool, 30_000 * PRECISION, 15_000 * PRECISION, - Identity::Address([0; 32].into()), - Identity::Address([0; 32].into()), + Identity::Address(Address::zeroed()), + Identity::Address(Address::zeroed()), ) .await .unwrap(); @@ -421,8 +421,8 @@ async fn proper_full_liquidation_partial_usdf_in_sp() { &contracts.coll_surplus_pool, &contracts.usdf, Identity::Address(liquidated_wallet.address().into()), - Identity::Address([0; 32].into()), - Identity::Address([0; 32].into()), + Identity::Address(Address::zeroed()), + Identity::Address(Address::zeroed()), ) .await .unwrap(); @@ -653,8 +653,8 @@ async fn proper_full_liquidation_empty_sp() { &contracts.active_pool, 1_100 * PRECISION, 1_000 * PRECISION, - Identity::Address([0; 32].into()), - Identity::Address([0; 32].into()), + Identity::Address(Address::zeroed()), + Identity::Address(Address::zeroed()), ) .await .unwrap(); @@ -673,8 +673,8 @@ async fn proper_full_liquidation_empty_sp() { &contracts.active_pool, 10_000 * PRECISION, 5_000 * PRECISION, - Identity::Address([0; 32].into()), - Identity::Address([0; 32].into()), + Identity::Address(Address::zeroed()), + Identity::Address(Address::zeroed()), ) .await .unwrap(); @@ -693,8 +693,8 @@ async fn proper_full_liquidation_empty_sp() { &contracts.active_pool, 30_000 * PRECISION, 15_000 * PRECISION, - Identity::Address([0; 32].into()), - Identity::Address([0; 32].into()), + Identity::Address(Address::zeroed()), + Identity::Address(Address::zeroed()), ) .await .unwrap(); @@ -720,8 +720,8 @@ async fn proper_full_liquidation_empty_sp() { &contracts.coll_surplus_pool, &contracts.usdf, Identity::Address(liquidated_wallet.address().into()), - Identity::Address([0; 32].into()), - Identity::Address([0; 32].into()), + Identity::Address(Address::zeroed()), + Identity::Address(Address::zeroed()), ) .await .unwrap(); diff --git a/contracts/trove-manager-contract/tests/success_partial_liquidations.rs b/contracts/trove-manager-contract/tests/success_partial_liquidations.rs index 4f2e72c2..6b60dbc9 100644 --- a/contracts/trove-manager-contract/tests/success_partial_liquidations.rs +++ b/contracts/trove-manager-contract/tests/success_partial_liquidations.rs @@ -71,8 +71,8 @@ async fn proper_partial_liquidation_enough_usdf_in_sp() { &contracts.active_pool, 12_000 * PRECISION, 10_100 * PRECISION, - Identity::Address([0; 32].into()), - Identity::Address([0; 32].into()), + Identity::Address(Address::zeroed()), + Identity::Address(Address::zeroed()), ) .await .unwrap(); @@ -91,8 +91,8 @@ async fn proper_partial_liquidation_enough_usdf_in_sp() { &contracts.active_pool, 20_000 * PRECISION, 15_000 * PRECISION, - Identity::Address([0; 32].into()), - Identity::Address([0; 32].into()), + Identity::Address(Address::zeroed()), + Identity::Address(Address::zeroed()), ) .await .unwrap(); @@ -133,8 +133,8 @@ async fn proper_partial_liquidation_enough_usdf_in_sp() { &contracts.coll_surplus_pool, &contracts.usdf, Identity::Address(wallet1.address().into()), - Identity::Address([0; 32].into()), - Identity::Address([0; 32].into()), + Identity::Address(Address::zeroed()), + Identity::Address(Address::zeroed()), ) .await .unwrap(); @@ -294,8 +294,8 @@ async fn proper_partial_liquidation_partial_usdf_in_sp() { &contracts.active_pool, starting_col, starting_debt, - Identity::Address([0; 32].into()), - Identity::Address([0; 32].into()), + Identity::Address(Address::zeroed()), + Identity::Address(Address::zeroed()), ) .await .unwrap(); @@ -314,8 +314,8 @@ async fn proper_partial_liquidation_partial_usdf_in_sp() { &contracts.active_pool, 10_000 * PRECISION, 5_000 * PRECISION, - Identity::Address([0; 32].into()), - Identity::Address([0; 32].into()), + Identity::Address(Address::zeroed()), + Identity::Address(Address::zeroed()), ) .await .unwrap(); @@ -334,8 +334,8 @@ async fn proper_partial_liquidation_partial_usdf_in_sp() { &contracts.active_pool, 30_000 * PRECISION, 15_000 * PRECISION, - Identity::Address([0; 32].into()), - Identity::Address([0; 32].into()), + Identity::Address(Address::zeroed()), + Identity::Address(Address::zeroed()), ) .await .unwrap(); @@ -377,8 +377,8 @@ async fn proper_partial_liquidation_partial_usdf_in_sp() { &contracts.coll_surplus_pool, &contracts.usdf, Identity::Address(liquidated_wallet.address().into()), - Identity::Address([0; 32].into()), - Identity::Address([0; 32].into()), + Identity::Address(Address::zeroed()), + Identity::Address(Address::zeroed()), ) .await .unwrap(); @@ -655,8 +655,8 @@ async fn proper_partial_liquidation_empty_sp() { &contracts.active_pool, starting_col, starting_debt, - Identity::Address([0; 32].into()), - Identity::Address([0; 32].into()), + Identity::Address(Address::zeroed()), + Identity::Address(Address::zeroed()), ) .await .unwrap(); @@ -675,8 +675,8 @@ async fn proper_partial_liquidation_empty_sp() { &contracts.active_pool, 10_000 * PRECISION, 5_000 * PRECISION, - Identity::Address([0; 32].into()), - Identity::Address([0; 32].into()), + Identity::Address(Address::zeroed()), + Identity::Address(Address::zeroed()), ) .await .unwrap(); @@ -695,8 +695,8 @@ async fn proper_partial_liquidation_empty_sp() { &contracts.active_pool, 30_000 * PRECISION, 15_000 * PRECISION, - Identity::Address([0; 32].into()), - Identity::Address([0; 32].into()), + Identity::Address(Address::zeroed()), + Identity::Address(Address::zeroed()), ) .await .unwrap(); @@ -722,8 +722,8 @@ async fn proper_partial_liquidation_empty_sp() { &contracts.coll_surplus_pool, &contracts.usdf, Identity::Address(liquidated_wallet.address().into()), - Identity::Address([0; 32].into()), - Identity::Address([0; 32].into()), + Identity::Address(Address::zeroed()), + Identity::Address(Address::zeroed()), ) .await .unwrap(); diff --git a/contracts/usdf-token-contract/src/main.sw b/contracts/usdf-token-contract/src/main.sw index a9aa7a2d..2a514df9 100644 --- a/contracts/usdf-token-contract/src/main.sw +++ b/contracts/usdf-token-contract/src/main.sw @@ -1,5 +1,6 @@ contract; - +// The USDFToken contract is responsible for managing the issuance and transfer of USDF tokens in the system. +// It is used by the Stability Pool, Borrower Operations, and Trove Managers. use libraries::usdf_token_interface::USDFToken; use libraries::fluid_math::{get_default_asset_id, ZERO_B256}; use std::{ @@ -24,7 +25,7 @@ use std::{ string::String, }; storage { - trove_managers: StorageVec = StorageVec {}, + valid_trove_managers: StorageMap = StorageMap:: {}, protocol_manager: ContractId = ContractId::zero(), stability_pool: Identity = Identity::Address(Address::zero()), borrower_operations: Identity = Identity::Address(Address::zero()), @@ -32,10 +33,10 @@ storage { total_supply: u64 = 0, is_initialized: bool = false, } - +// Using https://docs.fuel.network/docs/sway-standards/src-20-native-asset/ as reference impl USDFToken for Contract { ////////////////////////////////////// - // Owner methods + // Initialization method ////////////////////////////////////// #[storage(read, write)] fn initialize( @@ -77,7 +78,9 @@ impl USDFToken for Contract { #[storage(read, write)] fn add_trove_manager(trove_manager: ContractId) { require_caller_is_protocol_manager(); - storage.trove_managers.push(trove_manager); + storage + .valid_trove_managers + .insert(Identity::ContractId(trove_manager), true); } ////////////////////////////////////// // SRC-20 Read-Only methods @@ -122,7 +125,7 @@ fn require_caller_is_protocol_manager() { require( msg_sender() .unwrap() == Identity::ContractId(storage.protocol_manager.read()), - "NotAuthorized", + "USDFToken: NotAuthorized", ); } #[storage(read)] @@ -132,27 +135,23 @@ fn require_caller_is_borrower_operations() { .unwrap() == storage .borrower_operations .read(), - "NotAuthorized", + "USDFToken: NotAuthorized", ); } #[storage(read)] fn require_caller_is_bo_or_tm_or_sp_or_pm() { let sender = msg_sender().unwrap(); let protocol_manager_id = Identity::ContractId(storage.protocol_manager.read()); - let mut i = 0; - while i < storage.trove_managers.len() { - let manager = Identity::ContractId(storage.trove_managers.get(i).unwrap().read()); - if manager == sender { - return - } - i += 1; - } + + // Check if the sender is a valid trove manager + let is_valid_trove_manager = storage.valid_trove_managers.get(sender).try_read().unwrap_or(false); + require( sender == storage .borrower_operations .read() || sender == storage .stability_pool - .read() || sender == protocol_manager_id, + .read() || sender == protocol_manager_id || is_valid_trove_manager, "USDFToken: NotAuthorized", ); } diff --git a/contracts/vesting-contract/src/utils.sw b/contracts/vesting-contract/src/utils.sw index 589c7374..f3e8fbc6 100644 --- a/contracts/vesting-contract/src/utils.sw +++ b/contracts/vesting-contract/src/utils.sw @@ -34,14 +34,13 @@ pub fn is_valid_vesting_schedule(vesting_schedule: VestingSchedule) -> bool { } #[test] fn test_redeemable_calculations() { - let ZERO_B256 = 0x0000000000000000000000000000000000000000000000000000000000000000; let mut vesting_schedule = VestingSchedule { cliff_timestamp: 100, cliff_amount: 100, end_timestamp: 200, total_amount: 1000, claimed_amount: 0, - recipient: Identity::Address(Address::from(ZERO_B256)), + recipient: Identity::Address(Address::zero()), }; // Before cliff assert(calculate_redeemable_amount(0, vesting_schedule) == 0); @@ -54,7 +53,7 @@ fn test_redeemable_calculations() { end_timestamp: 200, total_amount: 1000, claimed_amount: 100, - recipient: Identity::Address(Address::from(ZERO_B256)), + recipient: Identity::Address(Address::zero()), }; assert(calculate_redeemable_amount(150, vesting_schedule) == 450); // At the end of the vesting period with 650 claimed @@ -64,7 +63,7 @@ fn test_redeemable_calculations() { end_timestamp: 200, total_amount: 1000, claimed_amount: 650, - recipient: Identity::Address(Address::from(ZERO_B256)), + recipient: Identity::Address(Address::zero()), }; assert(calculate_redeemable_amount(200, vesting_schedule) == 350); // After the end of the vesting period with 1000 claimed @@ -74,7 +73,7 @@ fn test_redeemable_calculations() { end_timestamp: 200, total_amount: 1000, claimed_amount: 1000, - recipient: Identity::Address(Address::from(ZERO_B256)), + recipient: Identity::Address(Address::zero()), }; assert(calculate_redeemable_amount(300, vesting_schedule) == 0); } diff --git a/deploy-scripts/Cargo.toml b/deploy-scripts/Cargo.toml index 4c9b7d78..cad07e1b 100644 --- a/deploy-scripts/Cargo.toml +++ b/deploy-scripts/Cargo.toml @@ -6,14 +6,14 @@ edition = "2021" license = "Apache-2.0" [dependencies] -dotenv = "0.15.0" +dotenv = { workspace = true } fuels = { workspace = true } -futures = "0.3.17" -pbr = "1.1.1" -serde = { version = "1.0.92", features = ["derive"] } -serde_json = "1.0.92" +futures = { workspace = true } +pbr = { workspace = true } +serde = { workspace = true } +serde_json = { workspace = true } test-utils = { path = "../test-utils" } -tokio = { version = "1.21.0", features = ["rt", "macros"] } +tokio = { workspace = true } [lib] doctest = false diff --git a/deploy-scripts/.SAMPLE_ENV b/deploy-scripts/env.sample similarity index 54% rename from deploy-scripts/.SAMPLE_ENV rename to deploy-scripts/env.sample index 2866748c..6350fcea 100644 --- a/deploy-scripts/.SAMPLE_ENV +++ b/deploy-scripts/env.sample @@ -1,2 +1,2 @@ SECRET="your secret mnemonic" -RPC="beta-4.fuel.network" \ No newline at end of file +RPC="beta-5.fuel.network" \ No newline at end of file diff --git a/libraries/Forc.toml b/libraries/Forc.toml index 65a04544..759b0875 100644 --- a/libraries/Forc.toml +++ b/libraries/Forc.toml @@ -3,3 +3,6 @@ authors = ["hydrogen-labs"] entry = "interface.sw" license = "Apache-2.0" name = "libraries" + +[dependencies] +standards = { git = "https://github.com/FuelLabs/sway-standards", tag = "v0.6.0" } diff --git a/libraries/src/fluid_math.sw b/libraries/src/fluid_math.sw index 20911659..8726acf9 100644 --- a/libraries/src/fluid_math.sw +++ b/libraries/src/fluid_math.sw @@ -151,11 +151,11 @@ pub fn dec_pow(base: u64, _minutes: u64) -> U128 { } pub fn null_identity_address() -> Identity { - return Identity::Address(Address::from(ZERO_B256)) + return Identity::Address(Address::zero()) } pub fn null_contract() -> ContractId { - return ContractId::from(ZERO_B256) + return ContractId::zero() } #[test] diff --git a/libraries/src/protocol_manager_interface.sw b/libraries/src/protocol_manager_interface.sw index b010f484..7f7744e1 100644 --- a/libraries/src/protocol_manager_interface.sw +++ b/libraries/src/protocol_manager_interface.sw @@ -1,5 +1,6 @@ library; +use standards::src5::State; abi ProtocolManager { #[storage(read, write)] fn initialize( @@ -13,17 +14,14 @@ abi ProtocolManager { sorted_troves: ContractId, admin: Identity, ); - #[storage(read, write)] fn register_asset( asset_address: AssetId, trove_manager: ContractId, oracle: ContractId, ); - #[storage(read, write)] fn renounce_admin(); - #[storage(read), payable] fn redeem_collateral( max_itterations: u64, @@ -31,4 +29,6 @@ abi ProtocolManager { upper_partial_hint: Identity, lower_partial_hint: Identity, ); + #[storage(read)] + fn owner() -> State; } diff --git a/test-utils/src/interfaces/borrow_operations.rs b/test-utils/src/interfaces/borrow_operations.rs index 1457b146..7b4323be 100644 --- a/test-utils/src/interfaces/borrow_operations.rs +++ b/test-utils/src/interfaces/borrow_operations.rs @@ -365,7 +365,7 @@ pub mod borrow_operations_abi { pub mod borrow_operations_utils { use fuels::prelude::{Account, WalletUnlocked}; - use fuels::types::Identity; + use fuels::types::{Address, Identity}; use super::*; use crate::interfaces::active_pool; @@ -408,8 +408,8 @@ pub mod borrow_operations_utils { &active_pool, amount, usdf_amount, - Identity::Address([0; 32].into()), - Identity::Address([0; 32].into()), + Identity::Address(Address::zeroed()), + Identity::Address(Address::zeroed()), ) .await .unwrap(); diff --git a/test-utils/src/interfaces/protocol_manager.rs b/test-utils/src/interfaces/protocol_manager.rs index 1569c799..65fef7dc 100644 --- a/test-utils/src/interfaces/protocol_manager.rs +++ b/test-utils/src/interfaces/protocol_manager.rs @@ -19,7 +19,7 @@ pub mod protocol_manager_abi { use crate::setup::common::AssetContracts; use fuels::prelude::{Account, CallParameters, ContractDependency}; use fuels::types::transaction_builders::VariableOutputPolicy; - use fuels::types::AssetId; + use fuels::types::{Address, AssetId}; use fuels::{ prelude::{ContractId, TxPolicies}, types::Identity, @@ -144,8 +144,8 @@ pub mod protocol_manager_abi { .redeem_collateral( max_iterations, partial_redemption_hint, - upper_partial_hint.unwrap_or(Identity::Address([0; 32].into())), - lower_partial_hint.unwrap_or(Identity::Address([0; 32].into())), + upper_partial_hint.unwrap_or(Identity::Address(Address::zeroed())), + lower_partial_hint.unwrap_or(Identity::Address(Address::zeroed())), ) .with_tx_policies(tx_params) .call_params(call_params) @@ -156,4 +156,19 @@ pub mod protocol_manager_abi { .await .unwrap() } + + pub async fn owner(protocol_manager: &ProtocolManager) -> CallResponse { + let tx_params = TxPolicies::default() + .with_tip(1) + .with_witness_limit(2000000) + .with_script_gas_limit(2000000); + + protocol_manager + .methods() + .owner() + .with_tx_policies(tx_params) + .call() + .await + .unwrap() + } }