The Smart Contract Weakness Classification and Test Cases (SWC) Registry is a set of Web3 vulnerabilities to avoid when writing smart contracts. It may seem daunting to understand every issue so I’ll do my best to demystify every issue and explain each vulnerability with real-world examples. This write-up is intended for those who are just starting out in solidity development and smart contract auditing.
SWC-110: Assert Violation
There are three ways to check validity in solidity - revert(), assert() and require(). In this write-up, I will be focusing on assert() and how to look out for assert violation in the contract.
What is assert()?
Summary
References
What is assert()?
Imagine you're a bank teller, and you have a rule that you must check a customer's ID before allowing them to make a withdrawal. If a customer comes in and tries to make a withdrawal without showing their ID, you would "assert" that they must show their ID first, and refuse to allow the transaction to proceed.
Now, suppose a customer comes in and shows you an ID that has been clearly tampered with, with the photo and name mismatched or illegible. If you allow the transaction to proceed without checking more carefully, you could be allowing a fraudulent transaction to occur. This would be an "assert violation" of the rule that you must check IDs, because you have allowed a transaction to proceed even though the required condition (valid ID) has not been met.
In Solidity, the assert() statement is used to check for conditions that should never be false. If the condition evaluates to false, the assert() statement will trigger an exception, causing the transaction to revert.
Take a look at this contract:
The function run() in the AssertMinimal contract is set to public. In the function, assert() is automatically set to false, so run() will never execute, which is a clear indication of assert() violation. Remember, assert must return true in order for the function to execute properly.
Let’s take a look at another contract:
In this code, function setX() sets the value of a public variable ‘x’, but first checks that the ‘value’ argument is not zero using an assert() statement. If a user calls setX and passes in 0, the assert() statement will fail and trigger an exception, causing the transaction to revert. This is because setting ‘x’ to zero is not allowed according to the contract’s logic, and indicates a violation of the assert() statement. It is important to know why x cannot be set to zero, otherwise, it is an underlying bug and must be fixed.
Assert() violations occur when a critical condition that should never be false has been violated, indicating a potential flaw in the contract’s logic or state. It’s important to carefully investigate and resolve assert() violations in order to ensure the integrity and security of the contract as properly functioning code should never reach a failing assert statement. If the exception is indeed caused by unexpected behavior of the code, fix the underlying bug(s) that allow the assertion to be violated.
Summary
Check for any way assert() can be violated in the function
References
https://swcregistry.io/docs/SWC-110
Thank you for reading! If you have any questions or clarifications, do reach out to @cryptostaker22 on Twitter or cryptostaker#1621 on Discord. Have a great week ahead!