Lesson 4 - Signed-integer

Introduction

In this lesson, we will learn the importance of using the correct type for your smart contracts, specifically when to use unsigned integer vs. signed integer.

Prerequisites

To be able to understand and complete this lesson, we believe that the minimum requirement should be the completion of Lesson 1 - Getting Started. If you desire to be even more prepared please have a look at the official website of ink!.

Objectives and Outcomes

In this lesson you will learn:

  • How a vulnerability can be introduced by using an inappropriate data type,

  • How to exploit this vulnerability,

  • How to fix the vulnerability.

Exercise

Vulnerable Smart contract

Alice and Bob want to be able to trade tokens in a smart contract. They deploy the ink! smart contract below on Aleph Zero that manages the tokens. The smart contract stores the total number of tokens in the variable total_supply and individual token balances for Alice and Bob are stored in the mapping balances.

Unfortunately, Alice and Bob did not follow the security guidelines and their smart contract contains a vulnerability.

Can you determine where in the code the vulnerability occurs?

==- Hint Examine the transfer function parameters. What are the logical boundaries of each parameter value? How are they declared? ==- Answer amount is declared as an unsigned integer, even though token amounts should all be positive. ==-

Can you think about a way to exploit this vulnerability? You may download the contract here, deploy it on Aleph Zero testnet, and try to attack it.

Did you succeed? Congratulations! If not, see the exploit below.

==- Exploit The transfer function can be called with a negative token amount. This allows an attacker to send a negative amount of tokens to another user. Effectively, this sends tokens from the victim to the attacker.

The exploit is demonstrated in the test code below:

==-

Simulated attack

==- Reveal Attack To simulate this attack you will need two founded accounts, so please watch https://youtu.be/TiihJ_Ax14U if you do not know how to do it.

then copy paste the code above into the lib.rs file

The test outputs should look like that

Build and Deploy to Testnet

using Cargo Contract Command line(results may vary)

Copy Smart Contract Address from the above output, address will be different from this example

Should be 10100

should be -100

Using Contracts-UI from substrate.io

Go to https://contracts-ui.substrate.io/

Add New Contract

Upload money.contract from the target/ink directory and click next

Set the supply to 10000 and click next

Click Upload and Instantiate

Send Message totalSupply

Total supply is set to 10000

Balance of contract constructer is 10000

Balance of other account is 0

Account justinTest sends -5000 to Account just2

Account justinTest now has a balance of 15000 which is greater than the total supply

Account just2 has a balance of -5000

Total supply is 10000 even though justinTest has a balance of 15000 ==-

Secure Solution

Now we discovered the problem and it consequences, let's talk about the secure way of developing the smart contract.

Any idea? let's look at the solution!

==- Solution Simply replace the signed integer with an unsigned or verified that the transfer done is bigger than 0 ==-

You can find in the table below a secure way to implement the smart contract desired by Bob and Alice.

==- Reveal Secure Implementation

==- If you want can verify that this new source code secures the smart contract by replaying the attack over that has been done above.

Question

If you are up to the challenge, see if you know the answer to this question:

True or false: While working with integer, the only question that needs to be asked is if we required negative integer to decide which type of integer we need? ==- Answers False. No, while working with integer, we also need to ask ourselves if the maximum integer that could appear in your smart contract. For example, this would help us to decide between using a u8 and u32. ==-

Last updated

Was this helpful?