#45517 [SC-Insight] Partial Documentation for Self-Close Exit Fee Handling and Redemption Workflow in 'CollateralPool.sol'
Submitted on May 16th 2025 at 00:33:39 UTC by @rusalka711 for Audit Comp | Flare | FAssets
Report ID: #45517
Report Type: Smart Contract
Report severity: Insight
Target: https://github.com/flare-foundation/fassets/blob/main/contracts/assetManager/implementation/CollateralPool.sol
Impacts:
Description
Brief/Intro
The _selfCloseExitTo
and fAssetRequiredForSelfCloseExit
functions lack critical explanations of their redemption logic, fee lifecycle management, and parameter constraints. Missing documentation increases the risk of user errors during self-close exits and complicates protocol maintenance.
Vulnerability Details
A. Undocumented Parameters
_redeemToCollateral
:No explanation of when/why to use direct collateral redemption vs. standard chain redemption.
_redeemerUnderlyingAddress
:Missing examples (e.g., BTC/XRP address formats) and validation requirements.
_executor
:Unclear role (e.g., receives fees for manual redemptions on non-smart contract chains).
B. Fee Lifecycle Ambiguity
Fee Debt Conversion:
freeFAssetFeeShare -= spentFreeFAssetFeeShare; debtFAssetFeeShare += spentFreeFAssetFeeShare;
No context on how this affects future fee withdrawals or user balances.
Allowance Checks:
require(fAsset.allowance(...) >= ..., "f-asset allowance too small");
Fails to specify that
transferFee
is paid by the user, not the contract.
C. Collateral Ratio Logic
_getFAssetRequiredToNotSpoilCR
:No documentation of its formula or impact on pool solvency.
Agent Redemption Limits:
Undefined consequences of
maxAgentRedemption < requiredFAssets
(e.g., partial exits).
D. Event Emissions
IncompleteSelfCloseExit
:No explanation of when/why this event is emitted.
Exited
Parameters:Undocumented fields (e.g.,
spentFAssetFees
vs.requiredFAssets
).
Impact Details
Category: Documentation Improvements Insight
Impact Analysis:
No Direct Exploit: The code operates correctly as written.
Operational Risks:
Insufficient Allowances: Users may underestimate
transferFee
, causing transaction reverts.Collateral Misconfigurations: Misunderstanding
_redeemToCollateral
could lead to failed redemptions.Accounting Errors: Poorly tracked fee debt may cause incorrect user balance calculations.
References
Code File:
CollateralPool.sol
(Lines 312–412).Key Functions:
_selfCloseExitTo
fAssetRequiredForSelfCloseExit
Critical Parameters:
_redeemToCollateral
_redeemerUnderlyingAddress
_executor
Proof of Concept
Proof of Concept
1. _selfCloseExitTo
Function Documentation
_selfCloseExitTo
Function DocumentationLocation: Insert above the _selfCloseExitTo
function.
Code:
/**
* @notice Executes a self-close exit, redeeming pool tokens while preserving collateral ratios.
* @param _tokenShare Pool tokens to liquidate (must be ≤ caller's balance).
* @param _redeemToCollateral If true, bypasses lot size checks for direct collateral redemption.
* @param _recipient Receives withdrawn NAT and FAsset fees.
* @param _redeemerUnderlyingAddress Valid underlying chain address (e.g., BTC: bc1q..., XRP: r...).
* @param _executor Address paid via `msg.value` to execute redemptions on non-smart contract chains.
* @dev
* - **Collateral Checks**: Post-exit balances must meet `MIN_TOKEN_SUPPLY_AFTER_EXIT`/`MIN_NAT_BALANCE_AFTER_EXIT`.
* - **Agent Limits**: If `requiredFAssets > maxAgentRedemption`, reduces `_tokenShare` and `natShare` to stay within limits.
* - **Fees**: Uses the caller’s FAsset fees first. Additional FAssets are transferred (caller covers fees).
* - **Reentrancy**: Guarded by `nonReentrant` modifier.
*/
// slither-disable-next-line reentrancy-eth // guarded by nonReentrant
function _selfCloseExitTo(...) private {
// ... (existing code)
}
2. fAssetRequiredForSelfCloseExit
Function Documentation
fAssetRequiredForSelfCloseExit
Function DocumentationLocation: Insert above the fAssetRequiredForSelfCloseExit
function.
Code:
/**
* @notice Computes FAssets needed for a self-close exit after deducting the user's available fees.
* @param _tokenAmountWei Pool tokens to exit (in wei).
* @return FAssets required to preserve collateral ratio.
* @dev
* - **Formula**: `requiredFAssets = max(0, (poolCR * (poolNatBalance - natWei)) / assetPrice - feeBalance)`.
* - **Edge Case**: Returns 0 if user’s fees cover the full requirement.
*/
function fAssetRequiredForSelfCloseExit(...) external view returns (uint256) {
// ... (existing code)
}
3. Inline Comment for _redeemerUnderlyingAddress
_redeemerUnderlyingAddress
Location: Insert above the _redeemerUnderlyingAddress
parameter usage (inside _selfCloseExitTo
).
Code:
// For non-collateral redemptions: Provide a valid underlying chain address (e.g., BTC: bc1q..., XRP: r...).
string memory _redeemerUnderlyingAddress,
4. Event Emission Comment
Location: Insert above the emit IncompleteSelfCloseExit
line.
Code:
// Emitted when agent's redemption capacity is exceeded, forcing partial exit.
emit IncompleteSelfCloseExit(_tokenShare, requiredFAssets);
5. Parameter Validation Comment
Location: Insert above the requiredFAssets < assetManager.lotSize()
check.
Code:
// Direct collateral redemption bypasses lot size checks. Use for small amounts.
if (requiredFAssets < assetManager.lotSize() || _redeemToCollateral) {
// ... (existing code)
}
Summary of Changes
_selfCloseExitTo
NatSpec for parameters, collateral checks, agent limits, and fee logic.
fAssetRequiredForSelfCloseExit
Formula explanation and edge-case handling.
_redeemerUnderlyingAddress
Example address formats for clarity.
IncompleteSelfCloseExit
Context for partial exits due to agent limits.
requiredFAssets
check
Clarifies _redeemToCollateral
usage for small amounts.
Result
These comments:
Prevent User Errors: Clarify redemption paths, fee allowances, and address formats.
Improve Auditability: Document formulas and edge cases for critical logic.
Enhance Maintainability: Explain parameter interactions and event triggers.
Was this helpful?