The SablierFlow contract does not correctly handle tokens that are transferred directly to its address without using the designated contract functions. This oversight can lead to tokens being unintentionally locked within the contract or exposed to unauthorized access, posing a risk to users and the contract's integrity.
The SablierFlow contract manages token flows between senders and recipients through specific functions like create(). However, if tokens are sent directly to the contract address (bypassing these functions), the contract lacks mechanisms to handle or recover these tokens. This can result in:
Locked Tokens: Tokens remain in the contract with no way to retrieve them.
Security Risks: Accumulated tokens increase the attack surface for potential exploits.
Below is a test case demonstrating the vulnerability:
First add the following mint function into the tests/mocks/ERC20Mock.sol , the result looks like this:
Create tests/SablierFlowDirectTransferTest.t.sol , paste the following test code inside, and then run the test with command forge test --mt testDirectTransferImpact -vvvv
Setup Contracts and Accounts
Deploy the ERC20Mock token contract.
Deploy the MockNFTDescriptor.
Deploy the SablierFlow contract using the MockNFTDescriptor.
Mint 1,000,000 tokens to the sender.
Approve the SablierFlow contract to spend the sender's tokens.
Create a Flow
Start a token flow from sender to recipient using the create() function.
Direct Token Transfer
Simulate a direct transfer by minting tokens directly to the SablierFlow contract address.
Observe Contract State
Check the token balance of the SablierFlow contract.
Expected Result: The contract balance increases by directTransferAmount.
Verify that the sender's balance remains unchanged.
Expected Result: The sender still has 1,000,000 tokens.
Attempt Token Recovery
Try to recover the tokens using a non-existent recovery function, which will fail.Expected Result: Transaction reverts due to the absence of a recovery mechanism.
The contract does not account for tokens sent directly to its address without using the designated functions. There is no fallback function or mechanism to handle such transfers, leading to tokens being trapped within the contract.
User Funds at Risk: Users who mistakenly send tokens directly to the contract will lose access to those tokens.
Accumulation of Tokens: Over time, tokens could accumulate in the contract, increasing the risk if vulnerabilities are found.
Reputational Damage: The loss of user funds can lead to distrust in the contract and the platform.
Foundry: A smart contract development toolchain for writing and testing Solidity code.
Solidity Compiler: Version 0.8.0.
ERC20Mock Contract: Used to simulate token behavior in testing.
Implement a Recovery Mechanism: Add a function that allows an authorized account to withdraw tokens that are sent directly to the contract.
Reject Direct Transfers: Implement a receive() or fallback() function that reverts any direct token transfers.
Update Documentation: Clearly inform users not to send tokens directly to the contract address.
Enhance Testing: Include test cases that cover scenarios involving direct token transfers to the contract.
Security Audit: Perform a comprehensive security audit to identify and mitigate similar vulnerabilities.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.