Skip to content

Latest commit

 

History

History
61 lines (41 loc) · 3.35 KB

086.md

File metadata and controls

61 lines (41 loc) · 3.35 KB

Mysterious Onyx Butterfly

Medium

Reentrancy Vulnerability in createStream Function Due to External Call Before State Update

Summary

The external call to ethRecipient before updating critical state variables in the createStream function can lead to a reentrancy attack on the StreamEscrow contract. This allows an attacker controlling ethRecipient to re-enter the contract and manipulate its state before it's properly updated, causing potential financial loss and inconsistent state for the protocol.

Root Cause

In createStream function, within the createStream function, the contract makes an external call to ethRecipient via sendETHToTreasury(remainder); before updating the critical state variables ethStreamedPerTick and streams[nounId]. This sequence allows for a reentrancy vulnerability because the state remains unmodified during the external call. While this current implementation may not be immediately vulnerable due to the trusted nature of ethRecipient, relying solely on trust assumptions can be risky. By following best practices—such as updating state before external calls, using reentrancy guards, and carefully controlling the ability to change critical addresses—we can enhance the security and robustness of this contract.

Internal pre-conditions

Attacker Control Over ethRecipient: The attacker manages to set ethRecipient to an address they control by exploiting the DAO's governance process. Allowed to Create Streams: The attacker's address is included in the allowedToCreateStream mapping. Ownership or Approval of a Noun Token: The attacker owns or is approved for a Noun token (nounId). State Not Updated Before External Call: The createStream function updates critical state variables after making the external call to ethRecipient.

External pre-conditions

Compromised Governance Process: The DAO's governance mechanism allows the attacker to set ethRecipient to an address they control without proper safeguards.

Attack Path

Manipulate ethRecipient: The attacker uses the DAO's governance process to set ethRecipient to an address they control. Prepare for Stream Creation: The attacker ensures they are in the allowedToCreateStream mapping and owns or is approved for a Noun token. Initiate createStream: The attacker calls the createStream function with a valid nounId and streamLengthInTicks, sending the required ETH. Trigger External Call: Inside createStream, the contract calls sendETHToTreasury(remainder); before updating the state. Re-enter Contract: The attacker's malicious ethRecipient contract's fallback function is invoked, allowing them to re-enter the createStream function. Exploit Unupdated State: Since the state hasn't been updated, the attacker bypasses the require(!isStreamActive(nounId), "stream active"); check. Manipulate Contract State: The attacker creates additional streams or manipulates state variables, leading to inconsistencies or unauthorized fund access.

Impact

The attacker can create multiple streams for the same Noun token or manipulate ethStreamedPerTick, leading to unauthorized withdrawals or draining of funds. The protocol and its users suffer potential financial losses and the contract's state becomes inconsistent.

PoC

No response

Mitigation

No response