Open code423n4 opened 1 year ago
GalloDaSballo marked the issue as primary issue
CodeSandwich marked the issue as sponsor confirmed
[confirm] Great job! This is a critical protocol breaker.
The Warden has shown a way to trick the contract into disbursing out funds without the upfront payment.
Because this shows a way to steal the principal, I agree with High Severity
GalloDaSballo marked the issue as selected for report
Lines of code
https://github.com/code-423n4/2023-01-drips/blob/main/src/Drips.sol#L425-L430
Vulnerability details
Impact
By creating a drip that ends after the current cycle but before its creation time and immediately removing it, the sender doesn't have to put in any assets but the receiver can still squeeze this drip.
By setting a receiver that the sender controls, the sender can drain arbitrary asset from the contract.
Proof of Concept
Let the cycle length be 10 seconds. By i-th second I mean the i-th second of the cycle. At the 5th second, sender creates a drip that starts at 0th second and lasts for 2 seconds. At the 6th second, sender removes this drip.
https://github.com/code-423n4/2023-01-drips/blob/main/src/Drips.sol#L569 Since the drip ends before it was created, the dripped amount is 0, so the sender can retrieve their full balance.
https://github.com/code-423n4/2023-01-drips/blob/main/src/Drips.sol#L425-L430 https://github.com/code-423n4/2023-01-drips/blob/main/src/Drips.sol#L490-L496 Now the receiver squeezes from this drip. SqueezeStartCap = _currCycleStart() = 0th second, squeezeEndCap = 6th second, so the receiver can still squeeze out the full amount even though the sender has withdrawn all of his balance.
Please add the following test to DripsHub.t.sol. It verifies that the sender has retrieved all of his assets but the receiver can still squeeze.
Tools Used
VSCode, Foundry
Recommended Mitigation Steps
https://github.com/code-423n4/2023-01-drips/blob/main/src/Drips.sol#L426 One potential solution is to add an additional check after this line. Something along the lines of:
if (squeezeStartCap < drips.updateTime) squeezeStartCap = drips.updateTime;