One of the tokens supported by this project is USDC, which is an upgradeable contract, and the code specifically casts addresses to IERC20Upgradeable rather than to IERC20, so the intention is for the code to support upgrades. If USDC ever upgrades to have a fee-on-transfer, rebasing behavior, or some other non-standard behavior, the contracts in this project will break, locking user funds in the state that they were before the upgrade.
Proof of Concept
For example, if an upgrade starts fee-on-transfer behavior, this function will revert, because it assumes _amount is available once claimeWithdraw() has happened, which will not be the case if a fee is charged:
Lines of code
https://github.com/code-423n4/2022-06-yieldy/blob/524f3b83522125fb7d4677fa7a7e5ba5a2c0fe67/src/contracts/LiquidityReserve.sol#L188-L209
Vulnerability details
Impact
One of the tokens supported by this project is USDC, which is an upgradeable contract, and the code specifically casts addresses to
IERC20Upgradeable
rather than toIERC20
, so the intention is for the code to support upgrades. If USDC ever upgrades to have a fee-on-transfer, rebasing behavior, or some other non-standard behavior, the contracts in this project will break, locking user funds in the state that they were before the upgrade.Proof of Concept
For example, if an upgrade starts fee-on-transfer behavior, this function will revert, because it assumes
_amount
is available onceclaimeWithdraw()
has happened, which will not be the case if a fee is charged:https://github.com/code-423n4/2022-06-yieldy/blob/524f3b83522125fb7d4677fa7a7e5ba5a2c0fe67/src/contracts/LiquidityReserve.sol#L188-L209
There are a lot of other examples where the balances aren't checked
Tools Used
Code inspection
Recommended Mitigation Steps
Measure balances before and after transfers, and use the difference as the amount rather than the stated amount.