
At its core, read-onlyreentrancy is a misleading return value from a view-only function due to anunupdated state. It occurs in smart contracts where external functions arebeing invoked whenever the contract is in an unupdated state and the viewfunctions, which are supposed to read the state, return values based on theold, unupdated state.
This can lead to inaccurateor false information being displayed, even though no actual state change ortransaction occurs as a result of calling these view functions.
This issue can arise inscenarios where there's a risk of reentrancy in a contract, particularly whenexternal functions are executed. Even if the primary function that alters thestate is safeguarded against reentrancy attacks, with a ReentrancyGuard, amalicious actor can still exploit the contract by reentering through aview-only function. This exploitation results in the view function returningdata that inaccurately reflects the contract's current state.
Consider a simple stakingcontract where users can deposit a staking token and earn rewards. When a userdeposits, the pool is updated and the pending reward is calculated andtransferred out. However, if the rewardDebt (the variable tracking how much rewardhas been accounted for each user) isn't updated before the transfer, there's awindow for exploitation. The function itself is guarded with a ReentrancyGuard.
A malicious user could callthe getPendingRewards function right after receiving the pending rewards butbefore the rewardDebt is updated. This would result in getPendingRewardsshowing the old reward amount, even though it has already been transferred out.The user sees an inflated reward value that doesn't truly reflect their pendingrewards after the deposit.
The key to preventingread-only reentrancy lies in adhering to the well-established"checks-effects-interactions" pattern in smart contract development.In a separate post i will describe this pattern in detail.
As always, if that helpedyou, please RT.