Skip to content

[A23-6] [LOW] LibFlow.flow reentrancy surface needs per-path tests #309

@thedavidmeister

Description

@thedavidmeister

Description

LibFlow.flow is documented (src/lib/LibFlow.sol:137) as DOES NOT prevent reentrancy attacks — the caller's responsibility. The only concrete caller is Flow.flow (src/concrete/Flow.sol:147), which has nonReentrant. The reentrancy surface has four entry points, each able to call back into the same flow contract during a transfer:

  1. interpreterStore.set — external call to an arbitrary store contract chosen by the flow deployer. A malicious store could re-enter flow.flow(...) from inside set.
  2. ERC721 safeTransferFrom — invokes onERC721Received on a contract recipient. A malicious recipient could re-enter from the hook.
  3. ERC1155 safeTransferFrom — invokes onERC1155Received (and onERC1155BatchReceived) on a contract recipient. Same pattern.
  4. ERC20 safeTransfer / safeTransferFrom — non-reentrant for compliant ERC20s, but ERC777 (which presents an ERC20 interface) invokes tokensToSend on the sender and tokensReceived on the recipient via the ERC1820 registry.

Path 4 is covered by testFlowReentrancyGuardFiresOnTokenCallback in #446 (MaliciousReenteringToken.transferFrom re-enters flow.flow). Paths 1–3 are uncovered.

Required tests

For each of paths 1–3, deploy a minimal helper contract whose callback re-enters flow.flow(...) and assert that the inner call reverts with "ReentrancyGuard: reentrant call" (OZ ReentrancyGuardUpgradeable v4 string).

  • MaliciousReenteringStore — implements IInterpreterStoreV2.set to re-enter on each call. Assert revert when the flow's store is set to this address and the evaluable returns non-empty kvs.
  • MaliciousReenteringERC721Recipient — implements IERC721Receiver.onERC721Received to re-enter. Assert revert when an ERC721 transfer targets this address.
  • MaliciousReenteringERC1155Recipient — implements IERC1155Receiver.onERC1155Received to re-enter. Assert revert when an ERC1155 transfer targets this address.

Each new helper goes in test/concrete/ per project convention. Mutation-test by removing nonReentrant from Flow.flow and confirming each test fails.

Severity

LOW — the reentrancy guard exists and PR #446 demonstrates it works for one path. The remaining three paths are part of the same attack surface and should be locked down equally.

Metadata

Metadata

Labels

auditAudit findinglowSeverity: lowpass1Audit Pass 1: Security

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions