Foreword: The security of smart contracts is one of the hottest topics in blockchain technology. All the existing smart contract systems have shown some types of loopholes, whether they are backed by the Ethereum Virtual Machine (EVM) or the EOS WASM Virtual Machine. These loopholes have caused huge losses for projects and users, and have called into question the security of blockchain technology.
Chapter 1: Introduction
In the previous three articles, we have introduced three types of security threats that may occur when developing smart contracts on Ontology: cross-contract call attack, force transaction failure attack, and storage injection attack. And we have given the solutions respectively. To better help smart contract developers avoid these security loopholes, we will keep collecting cases from the community. In the meanwhile, developers in the community can also discuss with us if they encounter other security threats when developing smart contracts on Ontology. Together, we will build a more secure smart contract system on Ontology.
In this article, a more common type of security threat — border attack, and its solution will be introduced. Before diving into it, please note that the Ontology smart contracts support positive and negative mathematical operations.
Within Ontology smart contracts, the maximum numerical value is MAX_, 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, which is 2²⁵⁵ while the minimum numerical value is MIN_ 0x8000000000000000000000000000000000000000000000000000000000000002, which is -(2²⁵⁵-1).
It is recommended that the developers do the right restraints and checks for the parameters passed into the contracts, otherwise, the potential loopholes may lead to an unexpected error, resulting in a serious attack.
Chapter 2: Border Attack
When developers are developing smart contracts, they usually need to pass the numerical value into the contracts as a parameter when invoking the contract. In most scenarios, the developers may only utilize the nonnegative numbers. If so, the developers should always remember to check and make sure the passed parameters will not surpass the border and is legal.
Let’s take ‘transfer()’ method as an example, included in a simple contract following the OEP-4 protocol.
Within the ‘transfer()’ method above, we have:
1. Checked the length of from_acct and to_acct to make sure they are legal as addresses.
2. Verified the signature of from_acct.
3. Made sure the amount being transferred is smaller than or equal to the balance of from_acct account.
4. Updated the balance of from_acct into fromBalance (the original balance of account being transferred out) — amount (the amount being transferred).
5. Updated the balance of to_acct into toBalance (the original balance of account being transferred in) + amount(the amount being transferred).
At first sight, the implementation and the logical flow are correct. Suppose we compile and deploy a smart contract according to the OEP-4 protocol based on the ‘transfer()’ method above, and the balance of from_acct and to_acct are both zero, then amazingly, we will notice that ‘transfer(from_acct, to_acct, -100)’ can be invoked successfully.
Afterward, we can invoke ‘balanceOf()’ by pre-execution to query the balance of from_acct and to_acct, the results are ‘64’ and ‘9c’. Through any type of sdk provided in https://dev-docs.ont.io/#/docs-en/SDKs/00-overview, we get ‘100’ and ‘-100’.
Even though the total supply within this OEP-4 smart contract does not change, from_acct does have 100 legal tokens. And That is what we really do not want to happen.
Chapter 3: Prevention of Border Attack
The way to avoid the border attack is to conduct a normative check of the boundary for the parameters passed into the contract, especially for the numerical parameters. Take asset type of smart contract as an example, we should strictly forbid passing in the negative value. And the above ‘transfer()’ method with loopholes can be implemented as below.
In addition to the five points mentioned above, we add the normative check of the boundary for ‘amount’ parameter to make sure it is nonnegative. In this way, we could avoid the potential border attack.
Since Ontology smart contracts support both positive and negative numerical value mathematical operations, we should do the normative check of the boundary based on the real application scenarios.
Furthermore, it should be noted that,
1. There is not overflow and underflow problems within Ontology smart contract system. When we do mathematical operations within contract, the contract (or VM) will raise exception once the variables are greater than MAX_ or less than MIN_.
2. Within contracts, no matter what types of parameters, it’s always good to do the meaningful normative checks (such as boundaries, length, etc). For instance, make sure the address type ‘account’ has a length of 20, which is ```assert(len(account) == 20)```, the integer type ‘amount’ is within the legal boundary, and the string type ‘str’ has the correct length.
Chapter 4: Afterword
We introduced the fourth type of smart contract security loophole on Ontology and its solution. So far, the smart contract security and loophole analysis series comes to a conclusion. We will still introduce any other loopholes we may encounter in the future. You can also help us build a more secure smart contract system on Ontology.