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
  • Zero Addresses
  • Critical Addresses
  1. LEARN
  2. Introduction
  3. 3. Security Pitfalls & Best Practices

3.21 Addresses

Zero Addresses

The zero address in Ethereum and Solidity has a special consideration. Remember that Ethereum addresses are 20 bytes in length and, if all these bytes are zeros, then it's referred to as the zero address.

The zero address becomes significant, because state variables or local variables of address type have a default value of zero in Solidity. The zero address is also used as burn address because the private key corresponding to this zero address is not known, so any Ether or tokens that are sent to the zero address gets burnt or is inaccessible forever.

If addresses used for access control within the smart contracts end up being the zero address, such functions can't be invoked again because of the lack of knowledge of the private key, which might in the worst case ends up in such contract getting locked.

So the best practice is to perform input validation on all address parameters that are of address type to check that they are not the zero address.

This is a very commonly encountered security pitfall where address parameters of constructor setters or public external functions are not input validated to not be the zero address.

In the best case such scenarios only result in exceptional behavior at runtime, but in the worst case they could result in tokens getting burnt or the contract being locked.

Critical Addresses

Another security pitfall related to addresses is the aspect of changing values of critical addresses. Certain addresses within the context of the smart contract may be considered as critical. These may be special privileged roles such as the owner address, which has special access to certain functions for updating critical parameters or doing other administrative aspects related to the smart contract.

Or these could also be addresses of other smart contracts that are used within the context of the application. As you can imagine, there may be scenarios where such addresses would need to be changed, so for example the default owner of a contract could be the deployer of the contract and we may want to change this to another address later on.

Or, if the addresses correspond to other smart contracts, then we may want to change the value to another smart contract once we have updated it.

In such scenarios, the security pitfall is when this change is done in a single step, this may be using the Owned library from OpenZeppelin where there is a transfer ownership function provided that transfers the ownership from the existing owner to a new owner that is provided as a parameter.

This happens in a single step where the owner variable is updated to the new address provided. This single step change is prone to errors. If an incorrect address is used as a new address, then it may result in that contract getting locked forever. The reason for this is the address used may be an address for which we do not have the private key, so we can't sign any transactions from that address, which results in all the administrative functions or any of the address change functions being inaccessible.

Thereafter the mitigation here or the best practice is to move away from a single step change and to move to what is known as a two-step change.

Where the first step grants or approves a new address as being the owner or as being that changed address, the second step is a transaction from the new address that claims itself as being the new owner or as being the new address.

So this two-step change allows any errors that happen in the first step, where we grant or approve it to an incorrect address for which we do not have the key it allows us to recover from this mistake because the second transaction which claims itself as a new address can never be done if an incorrect address was used in the first step.

So this aspect of critical addresses being changed and allowing errors to be recovered by moving away from a single step to a two-step change is a critical aspect of mitigating the risk from incorrect address changes.

Previous3.20 Unary ExpressionsNext3.22 Assertions

Last updated 1 year ago

📚
🔏