Skip to content

fix(FLOW-8): Ensure FlowYieldVaultsRequests recovers stray ERC20 tokens #78

Open
m-Peter wants to merge 2 commits intomainfrom
mpeter/FLOW-8-ensure-no-stray-tokens-or-funds
Open

fix(FLOW-8): Ensure FlowYieldVaultsRequests recovers stray ERC20 tokens #78
m-Peter wants to merge 2 commits intomainfrom
mpeter/FLOW-8-ensure-no-stray-tokens-or-funds

Conversation

@m-Peter
Copy link
Copy Markdown
Collaborator

@m-Peter m-Peter commented Mar 24, 2026

Closes: #23

Removed the special receive() Solidity function:

/// @notice Allows contract to receive native $FLOW
receive() external payable {}

to avoid accidental native FLOW token transfers to the contract, as it is not necessary for the contract's operation.

Introduced a new recoverTokens(to, tokenAddress, amount) Solidity function which allows only the contract's owner, to recover any ERC20 tokens through accidental user transfers.

Added some more unit tests, to verify that all 3 payable functions (createYieldVault / depositToYieldVault / completeProcessing), cannot receive any non-supported ERC20 tokens. All tokens transferred to these functions, are claimable by the users, even in the case of failures.

@m-Peter m-Peter self-assigned this Mar 24, 2026
@m-Peter m-Peter added Low Low severity security finding ⎈ QuantStamp QuantStamp audit finding labels Mar 24, 2026
@m-Peter m-Peter force-pushed the mpeter/FLOW-8-ensure-no-stray-tokens-or-funds branch 2 times, most recently from 98da128 to 114e7c2 Compare March 24, 2026 20:13
@m-Peter m-Peter force-pushed the mpeter/FLOW-8-ensure-no-stray-tokens-or-funds branch from 114e7c2 to b64cdfa Compare March 25, 2026 11:01
@m-Peter m-Peter marked this pull request as ready for review March 25, 2026 11:08
@claude
Copy link
Copy Markdown

claude bot commented Mar 25, 2026

Review: fix(FLOW-8) - ERC20 token recovery + receive() removal

Reviewed the totalAccountedBalance invariant, all ERC20 token flow paths, and the recoverTokens excess-guard logic. No material issues found.

Invariant verification

totalAccountedBalance[token] is incremented/decremented at exactly the right sites:

  • _validateDeposit (ERC20 escrow in): += amount
  • _startProcessingInternal (ERC20 out to COA): -= amount
  • completeProcessing failure (ERC20 re-enters from COA): += amount
  • _transferFunds (ERC20 out to user via claimRefund): -= amount
  • cancelRequest / _dropRequestsInternal: no change (funds stay in contract, just re-categorised to claimableRefunds)
  • recoverTokens: no change (correct - excess was never accounted for)

The invariant totalAccountedBalance[token] == sum(pendingUserBalances) + sum(claimableRefunds) holds across all paths.

receive() removal

Without receive() or fallback(), the only ways native FLOW can enter the contract are the three explicit payable functions (createYieldVault, depositToYieldVault, completeProcessing). Accidental bare-transfers of native FLOW now revert. The COA refund path for native FLOW goes through completeProcessing{value: amount}(...), which remains payable - no regression there.

recoverTokens correctness

The excess guard is correct and cannot be manipulated to drain accounted user funds. The ternary prevents underflow if fee-on-transfer tokens ever caused totalAccountedBalance > contractBalance. nonReentrant covers malicious ERC20 callbacks during safeTransfer.

Minor nits (no, action required)

  • InvalidRecoveryUserAddress fires for both to == address(0) and to == address(this). Slightly misleading for the self-transfer guard, but the behaviour is correct.
  • No test exercises WFLOW as the stray token, but MockDAI tests are structurally equivalent. Coverage is adequate.

Overall: accounting is sound, tests are thorough, and the design cleanly prevents both accidental native-FLOW trapping and owner theft of legitimate user funds.

@m-Peter m-Peter requested review from liobrasil and nvdtf March 25, 2026 11:13
@m-Peter m-Peter force-pushed the mpeter/FLOW-8-ensure-no-stray-tokens-or-funds branch from fd2b844 to 5511ef8 Compare March 25, 2026 15:53
@m-Peter m-Peter changed the title fix(FLOW-8): Ensure FlowYieldVaultsRequests accepts no stray tokens or native funds fix(FLOW-8): Ensure FlowYieldVaultsRequests recovers stray ERC20 tokens Mar 25, 2026
@m-Peter m-Peter force-pushed the mpeter/FLOW-8-ensure-no-stray-tokens-or-funds branch from 5511ef8 to 0822768 Compare March 25, 2026 16:49
@m-Peter m-Peter force-pushed the mpeter/FLOW-8-ensure-no-stray-tokens-or-funds branch from 0822768 to 969de34 Compare March 27, 2026 13:43
@m-Peter m-Peter force-pushed the mpeter/FLOW-8-ensure-no-stray-tokens-or-funds branch from 969de34 to 29f7b18 Compare March 27, 2026 14:09
@m-Peter m-Peter force-pushed the mpeter/FLOW-8-ensure-no-stray-tokens-or-funds branch from 29f7b18 to cd11a7f Compare March 27, 2026 14:21
@m-Peter m-Peter force-pushed the mpeter/FLOW-8-ensure-no-stray-tokens-or-funds branch from cd11a7f to f89ac6a Compare March 27, 2026 14:46
@m-Peter m-Peter force-pushed the mpeter/FLOW-8-ensure-no-stray-tokens-or-funds branch from f89ac6a to 21c186d Compare March 27, 2026 15:07
@m-Peter m-Peter force-pushed the mpeter/FLOW-8-ensure-no-stray-tokens-or-funds branch from 21c186d to 224f740 Compare March 27, 2026 15:23
@m-Peter m-Peter force-pushed the mpeter/FLOW-8-ensure-no-stray-tokens-or-funds branch from 224f740 to cb12b0c Compare March 27, 2026 15:35
@m-Peter m-Peter force-pushed the mpeter/FLOW-8-ensure-no-stray-tokens-or-funds branch from cb12b0c to d141e8b Compare March 27, 2026 15:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Low Low severity security finding ⎈ QuantStamp QuantStamp audit finding

Projects

None yet

Development

Successfully merging this pull request may close these issues.

FLOW-8: No Recovery Mechanism for Stray Tokens or Native Funds

1 participant