Introduction
In Solidity, smart contracts can interact with Ether in several ways. One is by receiving it directly and another way is by being called with non-matching data. Solidity provides two special functions — “receive()” and “fallback()” — to manage these interactions. As a result, this guide will deliver these functions, how they work, and scenarios that could result in vulnerabilities such as Denial of Service (DoS) attacks.
The “receive()” Function
The “receive()” function is a special function in Solidity triggered when a smart contract receives Ether without any accompanying data. Its sole purpose is to handle Ether transfers. If a contract does not have a “receive()” function, the fallback function will handle Ether transfers.
![](https://cdn.prod.website-files.com/64215e127d1ff32f211b42d7/66fd742cd8a5021ec9f69e59_AD_4nXd6t94E6jrSbT4z9gEAi8q3SXMk1cpdNR5sMsxEI7xRZdrJQEm_wMH2xZRZ6MG9_DaJcdaS1qQ4-xJeN9_Z9LD-KabJcn3Xyy0BdKwKto5AubUWc5k_fiTLiylRmt-MK0hhFjSUJOSHyoG_T9P8MJtnZtZAdIE5X2I-APxZG8wJnCuVLLdhbw.png)
The “fallback()” Function
The “fallback()” function is another special function in Solidity. It is designed to handle cases when the contract is called with unrecognized data. This way, it either accepts or rejects them. Also, the function comes in handy when Ether is sent without a matching function, but the “receive()” function is absent.
![](https://cdn.prod.website-files.com/64215e127d1ff32f211b42d7/66fd742b6c3039720fd513db_AD_4nXeBb0caEbiNiE2xPoVsEqmzezyK9zjowVPLgqNt8t8iTFGovpcv-1pCCX-EqGkT8m2m5mY0LyqHdsBvNB7AlglLeITgA8H-xDQodVtAOqHqy2JIs3kX4MMrlAG99l0m3e8tqtPFEdPAzXjDQRonVUJjrC701yf1k8SjKsv4lN88Jskd8Lrw1dg.png)
Handling Unrecognized Calls with “fallback()”
The “fallback()” function can serve as a catch-all for unrecognized calls. That is, contracts can be designed to either accept these calls or deny them based on specific conditions. For example, if no function matches the data sent to the contract, the fallback function could either log the event or revert the transaction.
![](https://cdn.prod.website-files.com/64215e127d1ff32f211b42d7/66fd742b89ccc920c4794940_AD_4nXdhqfAUuKQQMbrcjf6I2Bpps0ybd2meu_359tNxQUAzRYn70mPMsppq1lTBoDiuvkMYMJUo2H4TrBpi11ZYRsgdP56C5py9ujEDy1XE7YgFjTNPNBxHadq0voi9WIo3vQ2rnZrPyxnAhN9KnT9flE750SU_avDRr0YDpuujV568joFjcO2tUmA.png)
Rejecting Ether Transfers Using “receive()” and “fallback()”
In some cases, smart contracts may want to reject Ether transfers. This can be useful when the contract needs to enforce certain conditions. Examples of such conditions are rejecting Ether after a balance limit is reached or denying unauthorized transfers. Using the “revert()” statement within the “receive()” or “fallback()” functions, contracts can effectively reject incoming Ether transfers.
Denial of Service (DoS) via Failed Refunds
One vulnerability associated with the “fallback()” function is its potential to trigger Denial of Service (DoS) attacks via failed refunds. Consider a scenario where a contract attempts to refund Ether to a user after completing an operation. If the receiving contract’s fallback function is manipulated to reject the refund, it will cause the transaction to fail, effectively freezing the contract's ability to process further transactions.
Scenario Example
A good example is when a contract performs an action that refunds Ether to users. The receiving contract's fallback function is programmed to revert the transaction, rejecting the refund. The refund fails, leading to a DoS attack, as the contract becomes unable to complete further operations due to the unprocessed refund.
Conclusion
Both the “receive()” and “fallback()” functions are useful in managing Ether transfers and handling unrecognised function calls in Solidity. However, they can also open up vulnerabilities like DoS attacks, especially in cases involving refunds or unrecognized function calls. That is why they must be properly used to ensure the security and stability of smart contracts.
FAQs
1. What is the “receive()” function in Solidity?
The `receive()` function is a special function used to handle Ether transfers when no data accompanies the transaction.
2. What is the “fallback()” function in Solidity?
The “fallback()” function handles transactions with unrecognized function signatures or transfers of Ether when the “receive()” function is not present.
3. Can I reject Ether transfers to my contract?
Yes, you can reject Ether transfers using the “revert()” statement in either the “receive()” or “fallback()” functions.
4. What is a DoS attack via failed refunds?
A DoS (Denial of Service) attack via failed refunds occurs when a contract fails to refund Ether to another contract because the receiving contract’s fallback function is programmed to reject the transaction.
5. What should I use: “receive()” or “fallback()”?
Use “receive()” if your contract is specifically designed to receive Ether. If your contract may receive data or unrecognised function calls, consider using “fallback()” in addition to “receive()”.