# Overflow and Underflow Vulnerabilities in Cairo 

By [Oxorio](https://paragraph.com/@oxorio-2) · 2024-08-20

---

Intro
-----

In this article, we will explore one of the most common categories of vulnerabilities in the Cairo language: overflow and underflow. By comparing the approaches of two Cairo versions, 0.x and 1.0, to addressing this issue, we will analyze how each of them handles this vulnerability.

Cairo Evolution
---------------

In 2020, StarkWare introduced Cairo 0, a fully functional programming language for creating verifiable computations. Originating as an assembly language, Cairo gradually evolved, expanding its capabilities.

Initially, Cairo 0.x required developers to have a deep understanding of cryptographic primitives and architecture, making it challenging to learn. With the advent of Cairo 1, the situation has changed. The language became more abstract, allowing developers to focus on code logic rather than the intricacies of the architecture.

Cairo 1 delivers high performance through the Rust virtual machine and enhances program security through the ability to create verifiable computations.

Overflow & Underflow Vulnerability
----------------------------------

In Cairo, overflow and underflow issues can arise during arithmetic operations involving `felt` elements (the fundamental data type). These issues occur when the result of the operation falls outside the valid range.

### Cairo 0.x

Felt elements are essentially integers, but with some unique properties. They wrap around within a specific range determined by a large prime number (P). The range of valid values for a felt is from 0 to P-1, where `P` is a prime number that is 252 bits long (`felt252`).

Overflow occurs when the result is greater than or equal to `P`. Similar to overflow, underflow arises when the result of an arithmetic operation on felt elements is less than `0`.

This implies that if you add two numbers and the result exceeds this maximum value, Cairo will wrap the result back into the range rather than throwing an error. This behavior can lead to unexpected results:

        fn overflow_felt252() -> felt252 {
            // Assign max felt252 value = 2^251 + 17 * 2^192
            let max: felt252 = 3618502788666131106986593281521497120414687020801267626233049500247285301248 + 17 * 6277101735386680763835789423207666416102355444464034512896;
            max + 3
        }
    
        fn underflow_felt252() -> felt252 {
            let min: felt252 = 0;
            // Assign max felt252 value = 2^251 + 17 * 2^192
            let substract = (3618502788666131106986593281521497120414687020801267626233049500247285301248 + 17 * 6277101735386680763835789423207666416102355444464034512896);
            min - substract
        }
    

As a result, we will get the wrong values:

![Source: https://book.starknet.io/ch02-13-04-security-considerations.html#4-handling-overflow-and-underflow-in-smart-contracts](https://storage.googleapis.com/papyrus_images/f4138a8c14991b7c0ceccebecc1fef7992ec80ae94dd016c20d6baa630a6fd88.png)

Source: https://book.starknet.io/ch02-13-04-security-considerations.html#4-handling-overflow-and-underflow-in-smart-contracts

### Cairo 1.0

Cairo 1.0 introduces built-in support for secure integer types, such as `u128` and `u256`, which automatically handle overflows and underflows. By utilizing these types, transactions will be rolled back if an overflow is detected, preventing erroneous outcomes.

**An example of using the** `u128` data type to handle overflow and underflow:

        fn overflow_u128() -> u128 {
            let max: u128 = 0xffffffffffffffffffffffffffffffff_u128; // Assign max u128 value
            (max + 3_u128
        }
    
        fn underflow_u128() -> u128 {
            let min: u128 = 0_u128;
            min - 3_u128
        }
    

If an overflow or underflow occurs, the transaction will be reverted with a corresponding failure reason:

![Source: https://book.starknet.io/ch02-13-04-security-considerations.html#recommendation-3](https://storage.googleapis.com/papyrus_images/f18ffd5d6f6828a2f93060757a7f42d3fbe7cae1511c31e80d984af3ca7ee804.png)

Source: https://book.starknet.io/ch02-13-04-security-considerations.html#recommendation-3

*   _Failure reasons for u128_:
    
    *   `0x753132385f616464204f766572666c6f77=u128_add Overflow`
        
    *   `0x753132385f737562204f766572666c6f77=u128_sub Overflow`
        

**Similarly, the** `u256` data type can be used to handle overflow and underflow:

        fn overflow_u256() -> u256 {
            let max_u128: u128 = 0xffffffffffffffffffffffffffffffff_u128;
            let max: u256 = u256 { low: max_u128, high: max_u128 }; // Assign max u256 value
            let three: u256 = u256 { low: 3_u128, high: 0_u128 }; // Assign 3 value
            max + three
        }
    
        fn underflow_u256() -> u256 {
            let min: u256 = u256 { low: 0_u128, high: 0_u128 }; // Assign 0 value
            let three: u256 = u256 { low: 3_u128, high: 0_u128 }; // Assign 3 value
            min - three
        }
    

Executing these functions will cause the transaction to return if an overflow is detected:

![Source: https://book.starknet.io/ch02-13-04-security-considerations.html#recommendation-3](https://storage.googleapis.com/papyrus_images/8a237c2723a8b0101958bf237d2f339c52606e67c18070c4d482911e5885595b.png)

Source: https://book.starknet.io/ch02-13-04-security-considerations.html#recommendation-3

*   _Failure reasons for u256_:
    
    *   `0x753235365f616464204f766572666c6f77=u256_add Overflow`
        
    *   `0x753235365f737562204f766572666c6f77=u256_sub Overflow`
        

Security Recommendations
------------------------

As Cairo is a relatively new language, adopting well-established practices can significantly enhance code quality and security:

1.  OpenZeppelin Contracts for Cairo [https://github.com/OpenZeppelin/cairo-contracts](https://github.com/OpenZeppelin/cairo-contracts)
    
2.  Static-analyzer tool for Starknet smart contracts [https://github.com/crytic/caracal](https://github.com/crytic/caracal)
    
3.  Compile smart contracts with a newer version of the Cairo compiler.
    
4.  Keep your code regularly updated to avoid potential vulnerabilities.
    

### More great resources:

1.  Cairo 1 Workshop [https://github.com/starknet-edu/starknet-cairo-101](https://github.com/starknet-edu/starknet-cairo-101)
    
2.  List of Starknet security resources, tools, CTFs etc. [https://github.com/amanusk/awesome-starknet-security?tab=readme-ov-file](https://github.com/amanusk/awesome-starknet-security?tab=readme-ov-file)
    

Conclusion
----------

The transition from Cairo 0 to Cairo 1.0 marked a significant simplification of the language and the introduction of important security features, making it more reliable and user-friendly. However, creating Cairo-contracts still requires deep Cairo knowledge and a serious approach to security auditing.

**Stay Connected with OXORIO**
==============================

> Staying updated with the latest in blockchain security is crucial. We invite you to follow OXORIO on [LinkedIn](https://www.linkedin.com/company/oxorio) and [Twitter](https://x.com/0xorio) for insights and updates. Additionally, visit our website at [oxor.io](https://oxor.io/) for detailed information about our services and how we can assist in securing your blockchain projects.

---

*Originally published on [Oxorio](https://paragraph.com/@oxorio-2/overflow-and-underflow-vulnerabilities-in-cairo)*
