Upgradeability of collateral assets opens up the doors to reentrancy vulnerabilities #52
Labels
2 (Med Risk)
Assets not at direct risk, but function/availability of the protocol could be impacted or leak value
bug
Something isn't working
edited-by-warden
primary issue
Highest quality submission among a set of duplicates
🤖_64_group
AI based duplicate group recommendation
sponsor disputed
Sponsor cannot duplicate the issue, or otherwise disagrees this is an issue
sufficient quality report
This report is of sufficient quality
unsatisfactory
does not satisfy C4 submission criteria; not eligible for awards
Lines of code
https://github.com/code-423n4/2024-07-reserve/blob/3f133997e186465f4904553b0f8e86ecb7bbacbf/contracts/p1/RToken.sol#L148-L154
https://github.com/code-423n4/2024-07-reserve/blob/3f133997e186465f4904553b0f8e86ecb7bbacbf/contracts/p1/RToken.sol#L214-L224
Vulnerability details
This issue revisits reentrancy concerns that were raised in previous audits of the protocol (Issue #297, Issue #347, Issue #95, Issue #304). While the protocol team initially decided to mitigate these concerns by not supporting ERC-777 assets, this approach does not work if the protocol aims to be secure against arbitrary upgrades of collateral assets as per the in-scope ERC-20 behaviours.
The referenced findings remain largely relevant to the current version of the protocol. The
RToken
contract, for instance, is vulnerable to reentrancy via external token call in the functionsissue()
/issueTo()
andredeem()
/redeemTo()
. These functions interact with multiple ERC20 tokens that make up the collateral basket.If any of the tokens in the basket were to implement transfer hooks through an upgrade, an attacker could exploit this vulnerability to reenter the protocol in an inconsistent state.
For example, in the
RToken.issue()
function:If an attacker obtained control flow on any of the
transferFrom()
calls to the erc20s, they could call back into the protocol before all transfers are complete, allowing them to steal funds as per the findings referenced above.Impact
Theft of funds
Proof of Concept
RToken.issue()
with a large amounttokensToSend
hook is triggeredBackingManager.manageTokens()
manageTokens()
sees an inconsistent state whereRToken.basketsNeeded
has been updated but not all collateral has been transferredmanageTokens()
, potentially allowing the attacker to extract excess collateralTools Used
Manual review
Recommended Mitigation Steps
As pointed out by the sponsor in this comment, the multi-contract architecture of the protocol would require a global reentrancy mutex to fully protect against this class of vulnerabilities. Nevertheless, reentrancy protection at the contract level may prove sufficient for many such instances.
Assessed type
Upgradable
The text was updated successfully, but these errors were encountered: