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.