March 8th, 2023
Smart contracts commonly include functionality that makes certain assumptions about the validity of user-provided input. If these assumptions are violated, then the smart contract may be vulnerable to exploitation.
Precondition checks can be used to ensure that assumptions are met before certain functionality executes. A failure to properly use them is a common smart contract vulnerability.
Precondition checks are designed to ensure that a particular operation is valid before a smart contract executes it. In Solidity, they are commonly implemented using require statements, which will cause a transaction to fail if the specified condition is not met.
For example, a smart contract might include a withdrawal function that allows a user to extract the value that they have deposited within the contract. Before executing a withdrawal request, a smart contract should have precondition checks to verify that it is valid, including verifying that the withdrawal amount is less than the balance in the user’s account.
Precondition checks are vital to the correct operation of a smart contract. Two of the ways that precondition checks can leave a contract vulnerable are if they are missing or incorrect.
Precondition checks can’t protect a smart contract against malicious transactions if they don’t exist. One common smart contract vulnerability is failing to implement precondition checks or overlooking a required check.
For example, consider a DeFi project that allows a user to deposit value into the contract and take out loans using that deposit as collateral. When a user makes a withdrawal request, the contract may validate that the requested withdrawal amount is less than the amount that the user deposited. However, if the contract fails to check if that deposit has been used as collateral for a loan, an attacker can drain value from the contract by taking out a loan and then withdrawing the deposited assets used as collateral for that loan.
The other potential risk with precondition checks is that they are incorrect. If a smart contract includes precondition checks, but these checks validate the wrong things, then the contract may still be vulnerable to attack.
For example, a smart contract may be designed to accept deposits of tokens and mint a new token in exchange. The smart contract may include code to validate that a certain number of tokens has been deposited. However, if the precondition checks don’t validate that the right type of token is deposited, an attacker may be able to mint tokens and steal value by depositing a much less valuable token into the contract.
In March 2022, an attacker took advantage of flaws in precondition validation in Fantasm Finance’s smart contracts. The smart contract included code intended to ensure that users trying to mint XFTM tokens deposited FTM tokens.
However, the code checked the wrong values when validating the deposit. This allowed the attacker to deposit FSM tokens instead of FTM ones, minting XFTM while spending a fraction of their value. As a result, the attacker was able to steal $2.6 million from the protocol.
Errors in precondition checks are typically caused by errors in business logic validation. While the code may be free of errors, it may not implement the intended functionality and logical validation.
Smart contract security audits include business logic validation and can help ensure that a smart contract includes the precondition checks that it needs to be secure. To learn more about securing your smart contracts, reach out to our smart contract auditors.