interface IStableMaster {
	// Struct to handle all the parameters to manage the fees
	// related to a given collateral pool (associated to the stablecoin)
	struct MintBurnData {
		// Values of the thresholds to compute the minting fees
		// depending on HA hedge (scaled by `BASE_PARAMS`)
		uint64[] xFeeMint;
		// Values of the fees at thresholds (scaled by `BASE_PARAMS`)
		uint64[] yFeeMint;
		// Values of the thresholds to compute the burning fees
		// depending on HA hedge (scaled by `BASE_PARAMS`)
		uint64[] xFeeBurn;
		// Values of the fees at thresholds (scaled by `BASE_PARAMS`)
		uint64[] yFeeBurn;
		// Max proportion of collateral from users that can be covered by HAs
		// It is exactly the same as the parameter of the same name in `PerpetualManager`, whenever one is updated
		// the other changes accordingly
		uint64 targetHAHedge;
		// Minting fees correction set by the `FeeManager` contract: they are going to be multiplied
		// to the value of the fees computed using the hedge curve
		// Scaled by `BASE_PARAMS`
		uint64 bonusMalusMint;
		// Burning fees correction set by the `FeeManager` contract: they are going to be multiplied
		// to the value of the fees computed using the hedge curve
		// Scaled by `BASE_PARAMS`
		uint64 bonusMalusBurn;
		// Parameter used to limit the number of stablecoins that can be issued using the concerned collateral
		uint256 capOnStableMinted;
	}

	// Struct to handle all the variables and parameters to handle SLPs in the protocol
	// including the fraction of interests they receive or the fees to be distributed to
	// them
	struct SLPData {
		// Last timestamp at which the `sanRate` has been updated for SLPs
		uint256 lastBlockUpdated;
		// Fees accumulated from previous blocks and to be distributed to SLPs
		uint256 lockedInterests;
		// Max interests used to update the `sanRate` in a single block
		// Should be in collateral token base
		uint256 maxInterestsDistributed;
		// Amount of fees left aside for SLPs and that will be distributed
		// when the protocol is collateralized back again
		uint256 feesAside;
		// Part of the fees normally going to SLPs that is left aside
		// before the protocol is collateralized back again (depends on collateral ratio)
		// Updated by keepers and scaled by `BASE_PARAMS`
		uint64 slippageFee;
		// Portion of the fees from users minting and burning
		// that goes to SLPs (the rest goes to surplus)
		uint64 feesForSLPs;
		// Slippage factor that's applied to SLPs exiting (depends on collateral ratio)
		// If `slippage = BASE_PARAMS`, SLPs can get nothing, if `slippage = 0` they get their full claim
		// Updated by keepers and scaled by `BASE_PARAMS`
		uint64 slippage;
		// Portion of the interests from lending
		// that goes to SLPs (the rest goes to surplus)
		uint64 interestsForSLPs;
	}
	struct Collateral {
		// Interface for the token accepted by the underlying `PoolManager` contract
		IERC20 token;
		// Reference to the `SanToken` for the pool
		ISanToken sanToken;
		// Reference to the `PerpetualManager` for the pool
		IPerpetualManager perpetualManager;
		// Adress of the oracle for the change rate between
		// collateral and the corresponding stablecoin
		IOracle oracle;
		// Amount of collateral in the reserves that comes from users
		// converted in stablecoin value. Updated at minting and burning.
		// A `stocksUsers` of 10 for a collateral type means that overall the balance of the collateral from users
		// that minted/burnt stablecoins using this collateral is worth 10 of stablecoins
		uint256 stocksUsers;
		// Exchange rate between sanToken and collateral
		uint256 sanRate;
		// Base used in the collateral implementation (ERC20 decimal)
		uint256 collatBase;
		// Parameters for SLPs and update of the `sanRate`
		SLPData slpData;
		// All the fees parameters
		MintBurnData feeData;
	}

	/// @notice Lets a user send collateral to the system to mint stablecoins
	/// @param amount Amount of collateral sent
	/// @param user Address of the contract or the person to give the minted tokens to
	/// @param poolManager Address of the `PoolManager` of the required collateral
	/// @param minStableAmount Minimum amount of stablecoins the user wants to get with this transaction
	/// @dev The `poolManager` refers to the collateral that the user wants to send
	/// @dev `minStableAmount` serves as a slippage protection for users
	function mint(
		uint256 amount,
		address user,
		IPoolManager poolManager,
		uint256 minStableAmount
	) external;

	/// @notice Lets a user burn agTokens (stablecoins) and receive the collateral specified by the `poolManager`
	/// in exchange
	/// @param amount Amount of stable asset burnt
	/// @param burner Address from which the agTokens will be burnt
	/// @param dest Address where collateral is going to be sent
	/// @param poolManager Collateral type requested by the user burning
	/// @param minCollatAmount Minimum amount of collateral that the user wants to get with this transaction
	function burn(
		uint256 amount,
		address burner,
		address dest,
		IPoolManager poolManager,
		uint256 minCollatAmount
	) external;

	/// @notice Lets a SLP enter the protocol by sending collateral to the system in exchange of sanTokens
	/// @param user Address of the SLP to send sanTokens to
	/// @param amount Amount of collateral sent
	/// @param poolManager Address of the `PoolManager` of the required collateral: the corresponding collateral
	/// type is the one that is going to be sent by the user
	function deposit(
		uint256 amount,
		address user,
		IPoolManager poolManager
	) external;

	/// @notice Lets a SLP burn of sanTokens and receive the corresponding collateral back in exchange at the
	/// current exchange rate between sanTokens and collateral
	/// @param amount Amount of sanTokens burnt by the SLP
	/// @param burner Address that will burn its sanTokens
	/// @param dest Address that will receive the collateral
	/// @param poolManager Address of the `PoolManager` of the required collateral
	function withdraw(
		uint256 amount,
		address burner,
		address dest,
		IPoolManager poolManager
	) external;

	/// @return Collateral ratio for this stablecoin
	function getCollateralRatio() external view returns (uint256);

	function collateralMap(IPoolManager poolManager)
		external
		view
		returns (
			IERC20 token,
			ISanToken sanToken,
			IPerpetualManager perpetualManager,
			IOracle oracle,
			uint256 stocksUsers,
			uint256 sanRate,
			uint256 collatBase,
			SLPData memory slpData,
			MintBurnData memory feeData
		);
}
/// @notice Interface for `StableMaster`, the contract handling all the collateral types accepted for a given stablecoin
function mint(
	uint256 amount,
	address user,
	IPoolManager poolManager,
	uint256 minStableAmount
) external;

/// @notice Lets a user send collateral to the system to mint stablecoins
/// @param amount Amount of collateral sent
/// @param user Address of the contract or the person to give the minted tokens to
/// @param poolManager Address of the `PoolManager` of the required collateral
/// @param minStableAmount Minimum amount of stablecoins the user wants to get with this transaction
/// @dev The `poolManager` refers to the collateral that the user wants to send
/// @dev `minStableAmount` serves as a slippage protection for users