FlashLoan logic do not control the end result of transferring tokens out and back in.
There is fungible tokens which includes any exotic types of behavior, for example, reporting a successful transfer, but not performing internal accounting update for any reason.
Impact
Some fungible tokens (including not imposing any fee on transfers) may not return the whole amount back, but will report successful safeTransferFrom(), i.e. up to the whole balance of PT contract for such IBT token can be stolen.
This can take place in a situation when a popular token was upgraded and the consequences of the internal logic change weren't fully understood by wide market initially and most depositors remained in PT contract, then someone calls a flash loan as a griefing attack that will result in the token freezing the balancer of the pool. Or it was understood, but the griefer was quicker.
Now there is no control of the resulting balance, and any token that successfully performs safeTransferFrom, but for any reason withholds an update of token internal accounting, can successfully steal the whole balance of ibt in PT contract. This can be initiated by an attacker unrelated to token itself as griefing.
As many core token contracts are upgradable, such behaviour can be not in place right now, but can be introduced in the future.
Tools Used
Manual Review
Recommended Mitigation Steps
Consider adding a balance control check to ensure that flash loan invariant remains: record contract balance before receiver_.onFlashLoan(...) callback and record it after repay the debt + fee, require that resulting token balance ends up being not less than initial.
Lines of code
https://github.com/code-423n4/2024-02-spectra/blob/main/src/tokens/PrincipalToken.sol#L609-L631
Vulnerability details
Summary
FlashLoan logic do not control the end result of transferring tokens out and back in. There is fungible tokens which includes any exotic types of behavior, for example, reporting a successful transfer, but not performing internal accounting update for any reason.
Impact
Some fungible tokens (including not imposing any fee on transfers) may not return the whole amount back, but will report successful safeTransferFrom(), i.e. up to the whole balance of PT contract for such IBT token can be stolen.
This can take place in a situation when a popular token was upgraded and the consequences of the internal logic change weren't fully understood by wide market initially and most depositors remained in PT contract, then someone calls a flash loan as a griefing attack that will result in the token freezing the balancer of the pool. Or it was understood, but the griefer was quicker.
Proof of Concept
https://github.com/code-423n4/2024-02-spectra/blob/main/src/tokens/PrincipalToken.sol#L609-L631
Now there is no control of the resulting balance, and any token that successfully performs safeTransferFrom, but for any reason withholds an update of token internal accounting, can successfully steal the whole balance of ibt in PT contract. This can be initiated by an attacker unrelated to token itself as griefing.
As many core token contracts are upgradable, such behaviour can be not in place right now, but can be introduced in the future.
Tools Used
Manual Review
Recommended Mitigation Steps
Consider adding a balance control check to ensure that flash loan invariant remains: record contract balance before receiver_.onFlashLoan(...) callback and record it after repay the debt + fee, require that resulting token balance ends up being not less than initial.
Assessed type
Token-Transfer