# Integer Downcasting Vulnerability: Demonstration and Effective Fix

By [BuildBear](https://paragraph.com/@buildbear-3) · 2023-07-25

---

In Solidity versions 0.8 and above, overflow and underflow checking is enabled by default. However, this checking does not apply to conversions between integer types, including data-type conversions.

As a result, conversions can lead to overflow without triggering a revert.

Allow us to demonstrate this issue:

To assist you in getting started promptly, we have already prepared a repository showcasing this vulnerability. Let's begin by making a copy of the repository.

### **Step 1: Cloning the Tutorial Repo**

1.1 Forking the Tutorial Repository:

*   Visit our [**Tutorial Repository**](https://github.com/BuildBearLabs/Tutorials) and click the "Fork" button to duplicate the repository into your own account. Please wait until the forking process is complete before proceeding.
    

1.2 Cloning the repository locally:

*   Go to your forked repository on GitHub.
    
*   Click the "Code" button and copy the URL provided (either HTTPS or SSH).
    
*   Open your terminal or Git Bash.
    
*   Navigate to the directory where you want to place the cloned repository.
    
*   Use the following command to clone the repository:
    

    git clone <paste the copied URL here>
    

*   Wait for the cloning process to finish. Once completed, you should see a new directory with the repository's name in the chosen directory.
    
*   To access the cloned repository, use the command `cd <Name of the cloned Repo>`, and then navigate to the DownCastingError folder by executing `cd DownCastingError`.
    

### **Step 2: Let's walk through the contracts.**

2.1 `unsafeDownCasting.sol`\*\* Contract\*\*

![carbon (17) (1).png](https://storage.googleapis.com/papyrus_images/e7f5a070042dbbc99e3c208258dc0dbfeccbda38ccc34227142cc090f5dd8c51.png)

carbon (17) (1).png

Here's a breakdown of the code:

1.  The SPDX-License-Identifier specifies the license under which the contract is released. In this case, it's the MIT license.
    
2.  The `pragma solidity ^0.8.15;` statement defines the version of the Solidity compiler that should be used. This contract requires Solidity version 0.8.15 or higher.
    
3.  The contract is named `unsafeDownCasting`. It has a state variable named `LuckyNumber` of type `uint`, which will store the lucky number.
    
4.  The `setLuckyNumber` function is a public function that takes a `uint256` parameter named `amount`. It is used to set the lucky number. Inside this function, the `amount` value is downcasted to a `uint8` using the `uint8(amount)` syntax. This downcasting operation can lead to unexpected results if the `amount` value is greater than the maximum value of `uint8`, which is 255. If the `amount` exceeds this value, only the least significant 8 bits will be stored in the `number` variable, discarding any overflowed bits. This can result in a loss of data and incorrect behavior.
    
5.  The downcasted `number` value is then assigned to the `LuckyNumber` state variable.
    
6.  The `getLuckyNumber` function is a public view function that returns the current value of the `LuckyNumber` variable. It allows other contracts or external entities to retrieve the lucky number without modifying the contract's state.
    

2.2 `safeDownCasting.sol`\*\* Contract\*\*

![carbon (18) (1).png](https://storage.googleapis.com/papyrus_images/6bdb3f6aa5a9ed859de5a6204aff5aa9f7216373f422a5f4393adc4bc46b9377.png)

carbon (18) (1).png

1.  The contract imports the `SafeCast` library from the OpenZeppelin contracts. This library provides safe downcasting functionality.
    
2.  The `using SafeCast for uint256;` statement allows the contract to use the SafeCast library for type `uint256`.
    
3.  The `setLuckyNumber` function is a public function that takes a `uint256` parameter named `_amount`. It is used to set the lucky number. Inside this function, the `_amount` value is safely downcasted to `uint8` using the `toUint8()` function from the SafeCast library. If the `_amount` value is greater than the maximum value of `uint8`, the downcast will revert, ensuring that only valid downcasts are performed. The resulting `uint8` value is then assigned to the `LuckyNumber` state variable.
    

Let’s deploy these contracts and see the vulnerability in action.

### **Step 3: Setting up the Infrastructure for Deploying the Smart Contract**

3.1. Visit the [**BuildBear App**](https://buildbear.io/). ( Well we can deploy this contract on the local Hardhat node, But we will be Using BuildBear, you can understand the Reason by the end of this Tutorial).

3.2. Create your Private Testnet. You have the option to either fork from the Mainnets or create a new testnet from scratch, using Mainnet as the base. Forking from the Ethereum Mainnet allows us to conveniently utilize existing NFTs and tokens.

![Untitled (16).png](https://storage.googleapis.com/papyrus_images/60c0161824717d19c21c39401de2b36d274cb203544e64835b4ddd85b4f7ea18.png)

Untitled (16).png

3.3. Add your Private Testnet to your MetaMask wallet by using the “Add to Metamask” button:

![Untitled (17).png](https://storage.googleapis.com/papyrus_images/6463756d1fce4b350a66d9836f8ecf446f1aa992106e9190a1f313a8c8aa055c.png)

Untitled (17).png

### **Step 4: Deploying the Smart Contract**

To begin, execute the following command to install the necessary packages:

4.1 Update the `hardhat.config.js` file:

*   Go to your Dashboard and click on "verify contract".
    

![Untitled (18).png](https://storage.googleapis.com/papyrus_images/025eb700cd8be04188d08dbcb9b29215b4057d8770ac84fef69666e6db152e0f.png)

Untitled (18).png

![Untitled (19).png](https://storage.googleapis.com/papyrus_images/d954ca2069163ff8c8c465b3c3cccce6090e7448dd70925d8829ddf6677b2ea0.png)

Untitled (19).png

*   Copy the BuildBear and Etherscan objects, and update the `hardhat.config.js` file with the new values.
    

4.2 To deploy the `safeDownCasting.sol` and `unsafeDownCasting.sol`  smart contracts run the following command: `npx hardhat deploy`. This will execute the deployment scripts located in the `deploy` folder and save the deployment details, including the ABI and Contract address, in the `deployments` folder.

![Untitled (81).png](https://storage.googleapis.com/papyrus_images/5ebfbf735d184868e210ddc3da6ad7a8803c7a8dc98b296490b71d46ecf10a39.png)

Untitled (81).png

4.3 Testing the Vulnerability

As we are using BuildBear, we can conveniently interact with the contracts directly from the explorer, eliminating the need to write a script.

Click on "Open Faucet" on the dashboard and connect your wallet to mint Native tokens. With BuildBear, we have our own Faucet, so we don't have to bug tokens as we do when we use public Testnests.

Click on the link provided in the terminal of the `unsafeDownCasting` contract. You will be taken to the Contract page. Proceed to the "Write Contract" section.

![Untitled (82).png](https://storage.googleapis.com/papyrus_images/e97a2e6c0d186ac7cba788fccc62ccac41bff6432003b328550a0a957f69acba.png)

Untitled (82).png

Click on "Connect to Web3". Now the explorer is connected to your wallet. Enter any number larger than 255 and click on "Write" to sign the transaction on MetaMask.

![Untitled (83).png](https://storage.googleapis.com/papyrus_images/82a078c36613e8312dc6af4b3f61e0da2778477ef46694dc2394cf1672e290ef.png)

Untitled (83).png

Now move to the "Read Contract" section. You will notice that the lucky number is 44. Since the maximum value that can be represented by a `uint8` is 255, the downcast operation causes an overflow. In Solidity, when an overflow occurs during an arithmetic operation, the value "wraps around" and starts from the minimum value of the data type. In this case, the least significant 8 bits of 300 (which is 44 in binary) will be stored in the `number` variable.

As a result, the `LuckyNumber` state variable will be assigned the value of 44.

![Untitled (84).png](https://storage.googleapis.com/papyrus_images/88186d9bc49b5acad0b23c00bcbd6c51f88bc40aa40ee81f8ebc21d4aa6611c5.png)

Untitled (84).png

4.4 Testing the Contract with SafeCast Library.

Now move to the explorer page of the safeDownCasting Contract from the link proved in the Terminal, Connect the wallet and enter 300 and click on write, as you can see the Transaction has failed. Click on “View Transaction”, As you can see the Transaction has failed with reason `SafeCast: value doesn't fit in 8 bits,` this is because the SafeCast function is checking whether the integer is less than uint8 before converting it to uint8.

![Untitled (85).png](https://storage.googleapis.com/papyrus_images/908c5c915e1e6eb0832810dcc925129e18b5327334d8b6a002e084897814dce3.png)

Untitled (85).png

![Untitled (86).png](https://storage.googleapis.com/papyrus_images/fe0be252a3e95192423e3d0715892e83ade0e44a6707b078e71aa0c7d8f68969.png)

Untitled (86).png

🎉 We have successfully mitigated the DownCasting Vulnerability using the SafeCast library from the OpenZeppelin contracts.

If you support our efforts, please follow us on [**Twitter**](https://twitter.com/_BuildBear) and [**LinkedIn**](https://www.linkedin.com/company/build-bear/). If you haven't already, we invite you to join our Telegram group by clicking [**here**](https://t.me/+6mjOnBFUR9xjN2U1).

Github Repo : [Buildbear Tutorials](https://github.com/BuildBearLabs/Tutorials)

**_About BuildBear:_**

BuildBear offers developers a convenient platform to create a customized Private Testnet network for testing their DApps. With the ability to fork EVM chains, developers can create a private network tailored to their needs.

> Use [BuildBear.io](http://buildbear.io/) and create Your Private Testnet Now!

---

*Originally published on [BuildBear](https://paragraph.com/@buildbear-3/integer-downcasting-vulnerability-demonstration-and-effective-fix)*
