Open code423n4 opened 2 years ago
The _isWrappedFCash(component)
should make sure that these calls are only executed on valid wrappedfCash instances deployed from the configured factory.
The issue does not outline a practical scenario / test case where this issue would actually arise. If it did the manager could probably still remove / redeem the component either via this module, or one of the other Trade modules.
However I'll have to look into this if I can find a scenario where this would actually arise. I will also consider making this redeem step optional, but I will have to think more about this as this might introduce other more serious issues.
@jeffywu Do you see any scenario where the redemption of a matured fCash position might fail in this context`?
EDIT: Just noticed that https://github.com/code-423n4/2022-06-notional-coop-findings/issues/226 mentions (among others) the scenario of USDC tokens being blocked which I guess is unlikely but outside of our control. This makes me think we might want to make the redemption of matured tokens during issuance / redemption optional.
Changed label from acknowledged to confirmed, since on second thought I think we likely want to adpot some kind of mitigation strategy for this. However still tentative / unclear which strategy we want to adopt.
Lines of code
https://github.com/code-423n4/2022-06-notional-coop/blob/6f8c325f604e2576e2fe257b6b57892ca181509a/index-coop-notional-trade-module/contracts/protocol/modules/v1/NotionalTradeModule.sol#L309 https://github.com/code-423n4/2022-06-notional-coop/blob/6f8c325f604e2576e2fe257b6b57892ca181509a/index-coop-notional-trade-module/contracts/protocol/modules/v1/NotionalTradeModule.sol#L385
Vulnerability details
Proof-of-Concept
Whenever a setToken is issued or redeemed, the
moduleIssueHook
andmoduleRedeemHook
will be triggered. These two hooks will in turn call the_redeemMaturedPositions
function to ensure that no matured fCash positions remain in the Set by redeeming any matured fCash position.https://github.com/code-423n4/2022-06-notional-coop/blob/6f8c325f604e2576e2fe257b6b57892ca181509a/index-coop-notional-trade-module/contracts/protocol/modules/v1/NotionalTradeModule.sol#L309
The
_redeemMaturedPositions
will loop through all its fCash positions and attempts to redeem any fCash position that has already matured. However, if one of the fCash redemptions fails, it will cause the entire function to revert. If this happens, no one could purchase or redeem the setToken becausemoduleIssueHook
andmodileRedeemHook
hooks will revert every single time. Thus, the setToken issuance and redemption will stop working entirely and this setToken can be considered "bricked".https://github.com/code-423n4/2022-06-notional-coop/blob/6f8c325f604e2576e2fe257b6b57892ca181509a/index-coop-notional-trade-module/contracts/protocol/modules/v1/NotionalTradeModule.sol#L385
Impact
User will not be able to purchase or redeem the setToken. User's fund will stuck in the SetToken Contract. Unable to remove matured fCash positions from SetToken and update positions of its asset token.
Recommended Mitigation Steps
This is a problem commonly encountered whenever a method of a smart contract calls another contract – you cannot rely on the other contract to work 100% of the time, and it is dangerous to assume that the external call will always be successful.
It is recommended to:
Consider alternate method of updating the asset position so that the SetToken's core functions (e.g. issuance and redemption) will not be locked if one of the matured fCash redemptions fails.
Evaluate if
_redeemMaturedPositions
really need to be called during SetToken's issuance and redemption. If not, consider removing them from the hooks, so that any issue or revert within_redeemMaturedPositions
won't cause the SetToken's issuance and redemption functions to stop working entirely.Consider implementing additional function to give manager/user an option to specify a list of matured fCash positions to redeem instead of forcing them to redeem all matured fCash positions at one go.