Low-level calls:
http://address.call{},
address.delegatecall{},
address.staticcall{},
and address.send())
offer more flexibility and control over the interaction process but come with significant risks if not managed carefully. When low-level calls interact with other contracts without properly handling potential failures or exceptions, it could disastrously expose the contract to vulnerability like reentrancy.
Failure to Check Return Value
When using these calls, it's essential to handle the returned success flag properly to ensure that any failures are detected and managed appropriately.
Low-level calls in Solidity do not throw exceptions. Instead, they return false if they encounter an exception, while high-level Solidity contract calls will automatically throw an exception when they encounter an error. If the return value of a low-level call is not checked, the execution may resume even if the function call fails, leading to unexpected behavior and potential vulnerabilities. Attackers can exploit this by causing calls to fail intentionally.
http://address.call{},
address.delegatecall{},
address.staticcall{},
and address.send())
offer more flexibility and control over the interaction process but come with significant risks if not managed carefully. When low-level calls interact with other contracts without properly handling potential failures or exceptions, it could disastrously expose the contract to vulnerability like reentrancy.
Failure to Check Return Value
When using these calls, it's essential to handle the returned success flag properly to ensure that any failures are detected and managed appropriately.
Low-level calls in Solidity do not throw exceptions. Instead, they return false if they encounter an exception, while high-level Solidity contract calls will automatically throw an exception when they encounter an error. If the return value of a low-level call is not checked, the execution may resume even if the function call fails, leading to unexpected behavior and potential vulnerabilities. Attackers can exploit this by causing calls to fail intentionally.
The Behaviour Of A Successful Low-Level Call To A Non-Existent Contract
When a high-level call is made to a non-existent contract (i.e., an address that does not contain a contract), Solidity automatically reverts the transaction. This behavior is due to the use of the EXTCODESIZE opcode, which checks if the target address contains code. If the address does not contain code(s), the call reverts immediately.
On the other hand, low-level calls do not perform this existence check. Therefore, if a low-level call is made to a non-existent contract, the call itself does not revert; instead, it returns false for the success flag. This behavior allows the transaction to proceed, and this can lead to loss of funds and/or an invalid contract state.