Griefing (e.g. no profit motive for an attacker, but damage to the users or the protocol)
Contract fails to deliver promised returns, but doesn't lose value
Description
Fluid Bug Report
Inaccurate Check Leading to Debt Miscalculation
Overview
An edge case arises during reward application where a user's pending_usdf is not added to their debt due to an oversight. This miscalculation enables users to withdraw funds without accounting for the additional debt, potentially shifting the burden onto other protocol participants or causing minor fluctuations in the value of USDF due to inaccurate collateral backing.
Deep Dive
The issue stems from the internal_has_pending_rewards function, which verifies changes in the l_asset value but overlooks updates to the l_usdf value. Consequently, in scenarios where l_usdf changes while l_asset remains unchanged, the function erroneously returns false. This prevents the internal_apply_pending_rewards function from updating the pending rewards accurately.
How does l_usdf change without l_asset? The internal_redistribute_debt_and_coll function updates these values based on the latest liquidation data. Here's the critical implementation:
In cases where usdf_reward_per_unit_staked != 0 but asset_reward_per_unit_staked == 0, l_usdf is updated independently. This disparity can occur due to:
Significant price differences between the asset and USDF.
High total_stakes values combined with a higher USDF price compared to the asset.
Growth in last_usdf_error_redistribution.
During this interim period, pending rewards might need adjustment due to events such as liquidations, withdrawals, or redemptions.
Impact
The issue self-corrects once internal_redistribute_debt_and_coll is called again, updating l_asset. However, during the lag:
Users can perform actions (e.g., withdrawals) at a lower debt than intended.
Accumulated inaccuracies in the debt-to-collateral ratio can destabilize the USDF price if enough users act during this window.
Proposed Solution
Modify internal_has_pending_rewards to also evaluate changes in l_usdf: