Secureum Book
  • 🛡️Secureum Bootcamp
    • 🛡️Secureum Bootcamp
    • 🙌Participate
    • 📜History
  • 📚LEARN
    • Introduction
      • 🔷1. Ethereum Basics
        • 1.1 Ethereum: Concept, Infrastructure & Purpose
        • 1.2 Properties of the Ethereum Infrastructure
        • 1.3 Ethereum vs. Bitcoin
        • 1.4 Ethereum Core Components
        • 1.5 Gas Metering: Solving the Halting Problem
        • 1.6 web2 vs. web3: The Paradigm Shift
        • 1.7 Decentralization
        • 1.8 Cryptography, Digital Signature & Keys
        • 1.9 Ethereum State & Account Types
        • 1.10 Transactions: Properties & Components
        • 1.11 Contract Creation
        • 1.12 Transactions, Messages & Blockchain
        • 1.13 EVM (Ethereum Virtual Machine) in Depth
        • 1.14 Transaction Reverts & Data
        • 1.15 Block Explorer
        • 1.16 Mainnet & Testnets
        • 1.17 ERCs & EIPs
        • 1.18 Legal Aspects in web3: Pseudonymity & DAOs
        • 1.19 Security in web3
        • 1.20 web2 Timescales vs. web3 Timescales
        • 1.21 Test-in-Prod. SSLDC vs. Audits
        • Summary: 101 Keypoints
      • 🌀2. Solidity
        • 2.1 Solidity: Influence, Features & Layout
        • 2.2 SPDX & Pragmas
        • 2.3 Imports
        • 2.4 Comments & NatSpec
        • 2.5 Smart Contracts
        • 2.6 State Variables: Definition, Visibility & Mutability
        • 2.7 Data Location
        • 2.8 Functions
        • 2.9 Events
        • 2.10 Solidity Typing
        • 2.11 Solidity Variables
        • 2.12 Address Type
        • 2.13 Conversions
        • 2.14 Keywords & Shorthand Operators
        • 2.15 Solidity Units
        • 2.16 Block & Transaction Properties
        • 2.17 ABI Encoding & Decoding
        • 2.18 Error Handling
        • 2.19 Mathematical & Cryptographic Functions
        • 2.20 Control Structures
        • 2.21 Style & Conventions
        • 2.22 Inheritance
        • 2.23 EVM Storage
        • 2.24 EVM Memory
        • 2.25 Inline Assembly
        • 2.26 Solidity Version Changes
        • 2.27 Security Checks
        • 2.28 OpenZeppelin Libraries
        • 2.29 DAppSys Libraries
        • 2.30 Important Protocols
        • Summary: 201 Keypoints
      • 🔏3. Security Pitfalls & Best Practices
        • 3.1 Solidity Versions
        • 3.2 Access Control
        • 3.3 Modifiers
        • 3.4 Constructor
        • 3.5 Delegatecall
        • 3.6 Reentrancy
        • 3.7 Private Data
        • 3.8 PRNG & Time
        • 3.9 Math & Logic
        • 3.10 Transaction Order Dependence
        • 3.11 ecrecover
        • 3.12 Unexpected Returns
        • 3.13 Ether Accounting
        • 3.14 Transaction Checks
        • 3.15 Delete Mappings
        • 3.16 State Modification
        • 3.17 Shadowing & Pre-declaration
        • 3.18 Gas & Costs
        • 3.19 Events
        • 3.20 Unary Expressions
        • 3.21 Addresses
        • 3.22 Assertions
        • 3.23 Keywords
        • 3.24 Visibility
        • 3.25 Inheritance
        • 3.26 Reference Parameters
        • 3.27 Arbitrary Jumps
        • 3.28 Hash Collisions & Byte Level Issues
        • 3.29 Unicode RTLO
        • 3.30 Variables
        • 3.31 Pointers
        • 3.32 Out-of-range Enum
        • 3.33 Dead Code & Redundant Statements
        • 3.34 Compiler Bugs
        • 3.35 Proxy Pitfalls
        • 3.36 Token Pitfalls
        • 3.37 Special Token Pitfalls
        • 3.38 Guarded Launch Pitfalls
        • 3.39 System Pitfalls
        • 3.40 Access Control Pitfalls
        • 3.41 Testing, Unused & Redundand Code
        • 3.42 Handling Ether
        • 3.43 Application Logic Pitfalls
        • 3.44 Saltzer & Schroeder's Design Principles
        • Summary: 201 Keypoints
      • 🗜️4. Audit Techniques & Tools
        • 4.1 Audit
        • 4.2 Analysis Techniques
        • 4.3 Specification, Documentation & Testing
        • 4.4 False Positives & Negatives
        • 4.5 Security Tools
        • 4.6 Audit Process
        • Summary: 101 Keypoints
      • ☝️5. Audit Findings
        • 5.1 Criticals
        • 5.2 Highs
        • 5.3 Mediums
        • 5.4 Lows
        • 5.5 Informationals
        • Summary: 201 Keypoints
  • 🌱CARE
    • CARE
      • CARE Reports
  • 🚩CTFs
    • A-MAZE-X CTFs
      • Secureum A-MAZE-X
      • Secureum A-MAZE-X Stanford
      • Secureum A-MAZE-X Maison de la Chimie Paris
Powered by GitBook
On this page
  • Hash Collisions
  • Dirty Bits
  • Incorrect Shifts
  • Assembly
  1. LEARN
  2. Introduction
  3. 3. Security Pitfalls & Best Practices

3.28 Hash Collisions & Byte Level Issues

Hash Collisions

Hash collisions are possible in certain scenarios where the abi.encodePacked() primitive, is used with multiple variable length arguments.

This happens because this primitive does not zero pad the arguments, and it also does not save any length information for those arguments. As a result, this packed encoding could lead to collisions in certain scenarios, which you can imagine can affect the security of the smart contract.

The best practice here is to avoid the use of the abi.encodePacked() primitive where possible and use the abi.encode() primitive instead.

In scenarios where it can't be avoided, one should at least make sure that only one variable length argument is used in this parameter and certainly, users who can reach this primitive via function calls should not be allowed to write to the parameters used and tainted to force collisions from happening.

Dirty Bits

There is a security risk from Dirty High Order Bits in Solidity. Remember that the EVM word size is 256 bits or 32 bytes, and there are multiple types in Solidity whose size is less than 32 bytes. Using variables of such types may result in their higher order bits containing dirty values.

What this means is that they may contain values from previous writes to those bits, that have not been cleared or zeroed out. Such Dirty Order Bits are not a concern for variable operations because the compiler is aware of these Dirty Bits and takes care to make sure that they do not affect the values of variables.

By the way, if those variables end up getting used or passed around as message data, then that may result in them having the different values and causing malleability or non-uniqueness. This is a risk that needs to be kept in mind when looking at contracts that have variables of such types.

Incorrect Shifts

There is a security pitfall related to the use of incorrect shifts in Solidity assembly specifically.

Solidity assembly supports three different Shift operations:

  1. Shift left shl().

  2. Shift right shr()

  3. Shift arithmetic right sar()

all of which take two operands x and y. These operations shift the y operand by x bits and not the other way around.

This can be confusing, understandably the developer may have used these two operands interchangeably in which case the shift operation do something completely different from what the developer anticipated. This is something that needs to be checked when looking at Shift operations in Solidity assembly.

Assembly

The use of assembly in Solidity itself is considered as a security risk because assembly bypasses multiple security checks such as type safety, that is enforced by Solidity.

Developers end up using Solidity Assembly to make the operations more optimized and efficient from a Gas perspective, but on the flip side this is very error-prone because the assembly language Yul, is very different from Solidity itself and requires much greater understanding of the syntax and semantics of that assembly language.

So the use of Solidity assembly not only affects readability and maintainability, but also the auditability, because the auditors themselves might not be aware of the Yul language: the syntax and semantics.

All these aspects result in the recommended best practice of trying to avoid Solidity assembly as much as possible or, if absolutely required, then the developers and the security review should double-check to make sure that they have been used appropriately in the context of the smart contracts.

Previous3.27 Arbitrary JumpsNext3.29 Unicode RTLO

Last updated 1 year ago

📚
🔏