However a malicious governor could optimistically call token.approve(maliciousActor, MAX_UINT) on tokens where an incentive is expected. maliciousActor could be any address, and could then transfer out incentive balance whenever an incentive is created.
Tools Used
Recommended Mitigation Steps
Replace arbitraryCall with more targeted behavior
Or
Inside arbitraryCall, block calls to approve and safeApprove by checking the function selector encoded in data
Handle
ScopeLift
Vulnerability details
Impact
Governor can drain incentive balance via
arbitraryCall
Proof of Concept
The Stream contract offers
createIncentive
https://github.com/code-423n4/2021-11-streaming/blob/main/Streaming/src/Locke.sol#L500 andclaimIncentive
https://github.com/code-423n4/2021-11-streaming/blob/main/Streaming/src/Locke.sol#L516 which is the way the contract "expects" incentives to go. Access to claiming incentives is limited to the stream creator after the stream ends.We assume the governor is untrusted, therefore we check to ensure the depositToken and rewardToken balances don't change. The contract also prevents against direct calls to incentive token contracts that have an incentive balance: L735 https://github.com/code-423n4/2021-11-streaming/blob/main/Streaming/src/Locke.sol#L735
However a malicious governor could optimistically call
token.approve(maliciousActor, MAX_UINT)
on tokens where an incentive is expected. maliciousActor could be any address, and could then transfer out incentive balance whenever an incentive is created.Tools Used
Recommended Mitigation Steps
Replace
arbitraryCall
with more targeted behaviorOr
Inside
arbitraryCall
, block calls toapprove
andsafeApprove
by checking the function selector encoded indata