#47087 [SC-Insight] CollateralTypesFacet.sol::deprecateCollateralType allows to break CollateralTypes.sol::initialize invariant because it allows to deprecate all token collateral vaults leading to ...
Submitted on Jun 8th 2025 at 20:35:50 UTC by @hunter0xweb3 for Audit Comp | Flare | FAssets
Report ID: #47087
Report Type: Smart Contract
Report severity: Insight
Target: https://github.com/flare-foundation/fassets/blob/main/contracts/assetManager/facets/CollateralTypesFacet.sol
Impacts:
Description
Brief/Intro
CollateralTypesFacet.sol::deprecateCollateralType allows to break CollateralTypes.sol::initialize invariant because it allows to remove all token collateral vaults leading to all agents to be liquidated
Vulnerability Details
When protocol is initialized it calls contracts/assetManager/library/CollateralTypes.sol::initialize with data parameter. _data parameter should contain at least two tokens [0]: The first one should be a pool collateral token [1] and the rest [2] (at least one) vault collateral pools: contracts/assetManager/library/CollateralTypes.sol::initialize: https://github.com/flare-labs-ltd/fassets/blob/acb82a27b15c56ce9dfbb6dbbd76008da6753c26/contracts/assetManager/library/CollateralTypes.sol#L14-L19
function initialize(
CollateralType.Data[] memory _data
)
internal
{
@>[0] require(_data.length >= 2, "at least two collaterals required");
// initial pool collateral token
@>[1] require(_data[0].collateralClass == CollateralType.Class.POOL, "not a pool collateral at 0");
_add(_data[0]);
// ...
for (uint256 i = 1; i < _data.length; i++) {
@>[2] require(_data[i].collateralClass == CollateralType.Class.VAULT, "not a vault collateral");
So the protocol declares valid pool token and at least one collateral vault token for agent vault This collateral vault token function is for backing fassets minted If current collateral vault token is deprecated and vault doesnt switch vault collateral before token.isValid , then agent vault can be liquidated
CollateralTypes.sol::initialize ensures at least one vault collateral is enabled for agent vaults
However CollateralTypesFacet.sol::deprecateCollateralType allows to break this invariant allowing to deprecate all vault collateral tokens leaving agent vaults unable to SwitchVaultCollateral and becoming irremediably liquidatable: contracts/assetManager/library/CollateralTypes.sol::deprecate: https://github.com/flare-labs-ltd/fassets/blob/acb82a27b15c56ce9dfbb6dbbd76008da6753c26/contracts/assetManager/library/CollateralTypes.sol#L63-L75
function deprecate(
CollateralType.Class _collateralClass,
IERC20 _token,
uint256 _invalidationTimeSec
)
internal
{
AssetManagerSettings.Data storage settings = Globals.getSettings();
CollateralTypeInt.Data storage token = CollateralTypes.get(_collateralClass, _token);
//...
uint256 validUntil = block.timestamp + _invalidationTimeSec;
@> token.validUntil = validUntil.toUint64();
emit IAssetManagerEvents.CollateralTypeDeprecated(uint8(_collateralClass), address(_token), validUntil);
}
This is due to CollateralTypes.sol::deprecate doesnt check that at least another one valid vault collateral token is available before deprecating the token
Suggestion
Keep a global variable in state with current number of available vault collaterals tokens Increment this variable each time a new token is added with contracts/assetManager/library/CollateralTypes.sol::add Decrement this variable each time a token is deprecated with contracts/assetManager/library/CollateralTypes.sol::deprecate first checking (with this new variable) there is at least another vaul token to SwitchVaultCollateral
Impact Details
If all current collateral vault token are deprecated and vault wont have options to SwitchVaultCollateral and will become irremediably liquidatable
References
https://github.com/flare-labs-ltd/fassets/blob/acb82a27b15c56ce9dfbb6dbbd76008da6753c26/contracts/assetManager/library/CollateralTypes.sol#L14-L19 https://github.com/flare-labs-ltd/fassets/blob/acb82a27b15c56ce9dfbb6dbbd76008da6753c26/contracts/assetManager/library/CollateralTypes.sol#L63-L75
Proof of Concept
Proof of Concept
AgentVault is created with vault collateral token T All vault collateral tokens (including T) are deprecated with CollateralTypes.sol::deprecate AgentVault is unable to SwitchVaultCollateral and will be eventually liquidated
Was this helpful?