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.
1.1 Forking the Tutorial Repository:
Visit our Tutorial Repository 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 executingcd DownCastingError.
2.1 unsafeDownCasting.sol** Contract**

Here's a breakdown of the code:
The SPDX-License-Identifier specifies the license under which the contract is released. In this case, it's the MIT license.
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.The contract is named
unsafeDownCasting. It has a state variable namedLuckyNumberof typeuint, which will store the lucky number.The
setLuckyNumberfunction is a public function that takes auint256parameter namedamount. It is used to set the lucky number. Inside this function, theamountvalue is downcasted to auint8using theuint8(amount)syntax. This downcasting operation can lead to unexpected results if theamountvalue is greater than the maximum value ofuint8, which is 255. If theamountexceeds this value, only the least significant 8 bits will be stored in thenumbervariable, discarding any overflowed bits. This can result in a loss of data and incorrect behavior.The downcasted
numbervalue is then assigned to theLuckyNumberstate variable.The
getLuckyNumberfunction is a public view function that returns the current value of theLuckyNumbervariable. It allows other contracts or external entities to retrieve the lucky number without modifying the contract's state.
2.2 safeDownCasting.sol** Contract**

The contract imports the
SafeCastlibrary from the OpenZeppelin contracts. This library provides safe downcasting functionality.The
using SafeCast for uint256;statement allows the contract to use the SafeCast library for typeuint256.The
setLuckyNumberfunction is a public function that takes auint256parameter named_amount. It is used to set the lucky number. Inside this function, the_amountvalue is safely downcasted touint8using thetoUint8()function from the SafeCast library. If the_amountvalue is greater than the maximum value ofuint8, the downcast will revert, ensuring that only valid downcasts are performed. The resultinguint8value is then assigned to theLuckyNumberstate variable.
Let’s deploy these contracts and see the vulnerability in action.
3.1. Visit the BuildBear App. ( 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.

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

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".


Copy the BuildBear and Etherscan objects, and update the
hardhat.config.jsfile 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.

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.

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.

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.

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.


🎉 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 and LinkedIn. If you haven't already, we invite you to join our Telegram group by clicking here.
Github Repo : Buildbear 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 and create Your Private Testnet Now!
