👮
Contract Cops
  • Mastering Ethereum Book
    • What is ethereum?
    • Tokens
    • Oracles
    • Decenralized Applications(DApps)
    • The Ethereum virtual machine
    • Ethereum basics
    • Ethereum clients
    • Cryptography
    • Wallets
    • Transactions
    • Chapter 7 - Smart Contracts & Solidity
    • Side Notes
      • Tokens
      • Smart Contracts and Solidity
  • Cryptography
    • Ethereum Cryptography - Cheatsheet
    • Assymetric vs symmetric cryptography
    • ECDSA vs RSA
    • Elliptic curves and ECDSA
    • Sha-256 Example
    • Sha-256
    • What are the different steps in SHA-256?
  • Ethereum Blocks
    • Block Headers
  • Learning Solidity
    • Storage vs memory
    • Upgradeable contracts
      • Proxy pattern in smart contracts
  • PoS
    • Proof of stake
  • PoW
    • PoW
  • Tokens
    • ERC-1155
    • ERC20
  • Cryptonomics
    • Automated market makers
    • Collateral Tokens
    • Collateralized Stablecoin
    • Fiat currency
    • Liquidity pool
    • Open Position: Meaning and Risk in Trading
    • Slippage
    • Spot price
  • Common Attack Vectors
    • Checking access control
    • Access control issues on critical functions
    • Account Existence Check for low level calls
    • Account Existence Check
    • Common attacks with contract/EOA addresses
    • Arithmetic under/overflow
    • Assert Attack
    • Assert require revert
    • Assert Violation
    • Bad Interface DOS
    • Bad pragma and compiler
    • Block Timestamp Manipulation
    • Bypassing contract check
    • Code With No Effects
    • Code size check vulnerability
    • Constructors with Care
    • Default Visibilities
    • Delegatecall
    • Delegatecall
    • Denial of Service (DoS)
    • DoS with block gas limit
    • Entropy Illusion
    • External contract referencing
    • Flash Loan Attack
    • Floating Point and Precision
    • Function selector abuse
    • Function selector abuse
    • Smart contract gas griefing
    • Hash collision parameters
    • Hash Collisions With Multiple Variable Length Arguments
    • Imprecise arithmetic
    • Improper Array Deletion
    • Incorrect array deletion
    • Incorrect interface
    • Insufficient Gas Griefing
    • Loop through long arrays
    • Message call with hardcoded gas amount
    • Not enough gas for ether transfer
    • Precision Loss in Calculations
    • Oracle Manipulation
    • Public Burn Function
    • Read-only reentrancy
    • Race Conditions/Front Running
    • Reentrancy Attacks
    • Reentrancy
    • Requirement Violation
    • Right-To-Left-Override control character (U+202E)
    • Shadowing State Variables
    • Short Address / Parameter attack
    • Signature Malleability
    • Signature Replay
    • Transaction Order Dependence
    • Tx.Origin Authentication
    • Unchecked CALL Return Values
    • Unexpected ether
    • Uninitialized Storage Pointers
    • Unsafe Ownership Transfer
  • EIP's
    • EIP155
    • EIP55
  • PoW
    • Ethash
    • Scrypt - RFC 7914
  • Questions for self evaluation
    • Questions 23/04/2023 (Nr: 84)
    • Usability guide for questions
  • Frequently asked questions
    • What is the difference between transaction and message?
    • What is the use of a interface or function without implementation?
  • UsefulResources
Powered by GitBook
On this page
  • Preventative measuresAddresses linked to an EOA can't be checked whether they exist or not (all addresses on Ethereum already "exist"). One measure that can be taken is asking the user to send a signed transaction on-chain to verify that there is indeed a private key assigned with the address. This can then be stored in a simple mapping, namely:mapping(address => bool) verifiedUser;Addresses linked to a contract account, however, can be checked and validated whether the adddress has any bytecode associated with it. This can be seen with the example below:What this snippet of code represents is a simple inline assembly section that checks whether the length of the bytecode of a given address is bigger than 0. This way, before sending a transaction, we can succesfully predict whether the address is a contract address or not.
  • Preventative measuresIn order to prevent unexpected logic execution or the loss of ether/data, low level call functions should always be checked for their return values. Addresses can't be succesfully predicted whether they are actually linked to an existing account, except for the workaround with checking bytecode for a smart contract account.Important: Do not use the EXTCODESIZE modifier to check whether an address is of an EOA or Contract addressLet's take a loot at the following bad example of what a modifier might look like:We can see that the purpose of this is to check whether the size is bigger than zero. We then assume that if it is, it's a contract account and if it isnt - it should be an EOA.As you might have already noticed, this is really bad practice, as the modifier does not take into account that all addresses are pre-determined.
  1. Common Attack Vectors

Account Existence Check

In Solidity, call, delegatecall and staticcall all use an address to access a function/send ether to an external account.

Their first return value for these functions is a boolean (whether or not it was succesfull), and the second return is the data, returned by the function call.

  • Important note: Any 20 byte hash is considered a valid address. The EVM/Ethereum does not do any checks on whether a given sequence of bytes is a valid address. Therefore, this means that call(), delegatecall() and staticcall() will all return true, even for an address that doesn't have any account associated with it.

Note: staticcall(), unlike call and delegatecall, does not change the state of a contract. This means that any function invocation that changes the state will be thrown and the transaction will revert.

Preventative measuresAddresses linked to an EOA can't be checked whether they exist or not (all addresses on Ethereum already "exist"). One measure that can be taken is asking the user to send a signed transaction on-chain to verify that there is indeed a private key assigned with the address. This can then be stored in a simple mapping, namely:mapping(address => bool) verifiedUser;Addresses linked to a contract account, however, can be checked and validated whether the adddress has any bytecode associated with it. This can be seen with the example below:What this snippet of code represents is a simple inline assembly section that checks whether the length of the bytecode of a given address is bigger than 0. This way, before sending a transaction, we can succesfully predict whether the address is a contract address or not.

Preventative measuresIn order to prevent unexpected logic execution or the loss of ether/data, low level call functions should always be checked for their return values. Addresses can't be succesfully predicted whether they are actually linked to an existing account, except for the workaround with checking bytecode for a smart contract account.Important: Do not use the EXTCODESIZE modifier to check whether an address is of an EOA or Contract addressLet's take a loot at the following bad example of what a modifier might look like:We can see that the purpose of this is to check whether the size is bigger than zero. We then assume that if it is, it's a contract account and if it isnt - it should be an EOA.As you might have already noticed, this is really bad practice, as the modifier does not take into account that all addresses are pre-determined.

PreviousAccount Existence Check for low level callsNextCommon attacks with contract/EOA addresses

Last updated 2 years ago