user approves token x to stream contract (approval amount is type(uint256).max)
user calls createIncentive(token x, someAmount)
incentives[x] = someAmount
creator calls claimIncentive(token x)
incentives[x] = 0
governance can arbitraryCall with data as ERC20(token x).transferFrom(victim, self)
since user had provided max approval and require(incentives[who] == 0, "inc"); check passes
governance can drain anyone's balance who incentivezed stream with high approval. (techically remaining approval > 0)
max approval is very common since one does not want to approve many times due to high gas fees.
Tools Used
Manual Review
Recommended Mitigation Steps
add a mapping to keep track of whether incentive of particular token was claimed by creator and set it to true. In arbitraryCall, that mapping[who] should be false proving nobody has incentivised that token before.
Handle
hack3r-0m
Vulnerability details
Impact
https://github.com/code-423n4/2021-11-streaming/blob/main/Streaming/src/Locke.sol#L733-L751
max approval is very common since one does not want to approve many times due to high gas fees.
Tools Used
Manual Review
Recommended Mitigation Steps
add a mapping to keep track of whether incentive of particular token was claimed by creator and set it to true. In arbitraryCall, that mapping[who] should be false proving nobody has incentivised that token before.