├── .gitmodules ├── README.md ├── gitbook.yaml.example ├── script ├── compileBook.py ├── luaFilters │ └── codeblock_filter.lua ├── templates │ └── secureumBookTemplate.tex └── texfiles │ ├── 1.10_Transactions_Properties_and_Components.tex │ ├── 1.11_Contract_Creation.tex │ ├── 1.12_Transactions_Messages_and_Blockchain.tex │ ├── 1.13_EVM_in_Depth.tex │ ├── 1.14_Transaction_Reverts_and_Data.tex │ ├── 1.15_Block_Explorer.tex │ ├── 1.16_Mainnet_and_Testnets.tex │ ├── 1.17_EIPs_and_ERCs.tex │ ├── 1.18_Legal_Aspects_in_web3.tex │ ├── 1.19_Security_in_web3.tex │ ├── 1.1_Ethereum_Concept.tex │ ├── 1.20_web2_timescales_vs_web3_timescales.tex │ ├── 1.21_Test_in_Prod_SSLDC_vs_Audits.tex │ ├── 1.2_Properties_of_the_Ethereum_Infrastructure.tex │ ├── 1.3_Ethereum_vs_Bitcoin.tex │ ├── 1.4_Ethereum_core_components.tex │ ├── 1.5_Gas_Metering_Solving_the_Halting_Problem.tex │ ├── 1.6_web2_vs_web3_The_Paradigm_Shift.tex │ ├── 1.7_Decentralization.tex │ ├── 1.8_Cryptography_Digital_Signature_and_Keys.tex │ ├── 1.9_Ethereum_State_and_Account_Types.tex │ ├── 1_Ethereum_Basics.tex │ ├── 2.10_Solidity_Typing.tex │ ├── 2.11_Solidity_Variables.tex │ ├── 2.12_Address_Type.tex │ ├── 2.13_Conversions.tex │ ├── 2.14_Keywords_and_Shorthand_Operators.tex │ ├── 2.15_Solidity_Units.tex │ ├── 2.16_Block_and_Transaction_Properties.tex │ ├── 2.17_ABI_Encoding_and_Decoding.tex │ ├── 2.18_Error_Handling.tex │ ├── 2.19_Mathematical_and_Cryptographic_Functions.tex │ ├── 2.1_Solidity_Influence_Features_and_Layout.tex │ ├── 2.20_Control_Structures.tex │ ├── 2.21_Style_and_Conventions.tex │ ├── 2.22_Inheritance.tex │ ├── 2.23_EVM_Storage.tex │ ├── 2.24_EVM_Memory.tex │ ├── 2.25_Inline_Assembly.tex │ ├── 2.26_Solidity_Version_Changes.tex │ ├── 2.27_Security_Checks.tex │ ├── 2.28_Open_Zeppelin_Libraries.tex │ ├── 2.29_DAppSys_Libraries.tex │ ├── 2.2_SPDX_and_Pragmas.tex │ ├── 2.30_Important_Protocols.tex │ ├── 2.3_Imports.tex │ ├── 2.4_Comments_and_Natspec.tex │ ├── 2.5_Smart_Contracts.tex │ ├── 2.6_State_Variables_Definition_Visibility_and_Mutability.tex │ ├── 2.7_Data_Location.tex │ ├── 2.8_Functions.tex │ ├── 2.9_Events.tex │ ├── 2_Solidity.tex │ ├── 3.10_Transaction_Order_Dependence.tex │ ├── 3.11_ecrecover.tex │ ├── 3.12_Unexpected_returns.tex │ ├── 3.13_Ether_Accounting.tex │ ├── 3.14_Transaction_Checks.tex │ ├── 3.15_Delete_Mappings.tex │ ├── 3.16_State_Modification.tex │ ├── 3.17_Shadowing_and_Pre_Declaration.tex │ ├── 3.18_Gas_and_Costs.tex │ ├── 3.19_Events.tex │ ├── 3.1_Solidity_Versions.tex │ ├── 3.20_Typographical_Errors.tex │ ├── 3.21_Addresses.tex │ ├── 3.22_Assertions.tex │ ├── 3.23_Keywords.tex │ ├── 3.24_Visibility.tex │ ├── 3.25_Inheritance.tex │ ├── 3.26_Reference_Parameters.tex │ ├── 3.27_Arbitrary_Jumps.tex │ ├── 3.28_Hash_Collisions_and_Byte_Level_Issues.tex │ ├── 3.29_Unicode_RTLO.tex │ ├── 3.2_Access_Control.tex │ ├── 3.30_Variables.tex │ ├── 3.31_Pointers.tex │ ├── 3.32_Out_of_range_Enum.tex │ ├── 3.33_Dead_Code_and_Redundant_Statements.tex │ ├── 3.34_Compiler_Bugs.tex │ ├── 3.35_Proxy_Pitfalls.tex │ ├── 3.36_Token_Pitfalls.tex │ ├── 3.37_Special_Tokens_Pitfalls.tex │ ├── 3.38_Guarded_Launch_Pitfalls.tex │ ├── 3.39_System_Pitfalls.tex │ ├── 3.3_Modifiers.tex │ ├── 3.40_Access_Control_Pitfalls.tex │ ├── 3.41_Testing_Unused_and_Redundant_Code.tex │ ├── 3.42_Handling_Ether.tex │ ├── 3.43_Application_Logic_Pitfalls.tex │ ├── 3.44_Saltzer_and_Schroeders_Design_Principles.tex │ ├── 3.4_Constructor.tex │ ├── 3.5_Delegatecall.tex │ ├── 3.6_Reentrancy.tex │ ├── 3.7_Private_Data.tex │ ├── 3.8_PRNG_and_Time.tex │ ├── 3.9_Math_and_Logic.tex │ ├── 3_Security_Pitfalls_and_Best_Practices.tex │ ├── 4.1_Audit.tex │ ├── 4.2_Analysis_Techniques.tex │ ├── 4.3_Specification_Documentation_and_Testing.tex │ ├── 4.4_False_Positives_and_Negatives.tex │ ├── 4.5_Security_Tools.tex │ ├── 4.6_Audit_Process.tex │ ├── 4_Audit_Techniques_and_Tools.tex │ ├── 5.1_Criticals.tex │ ├── 5.2_Highs.tex │ ├── 5.3_Mediums.tex │ ├── 5.4_Lows.tex │ ├── 5.5_Informationals.tex │ ├── 5_Audit_Findings.tex │ └── secureumBootcamp.tex ├── secureumBootcamp.pdf └── src ├── README.md ├── SUMMARY.md ├── care ├── README.md └── reports.md ├── ctfs ├── README.md ├── a-maze-x-paris.md ├── a-maze-x-stanford.md └── a-maze-x.md ├── img ├── A-MAZE-X-Maison-de-la-Chimie.png ├── A-MAZE-X-Stanford.png ├── Merkle_Tree (1).png ├── Merkle_Tree.png ├── Patricia_Tree.png ├── amazeXlogo.png └── secureum-banner.png ├── learn ├── 1.Ethereum_Basics │ ├── 1.10_Transactions_Properties_and_Components.md │ ├── 1.11_Contract_Creation.md │ ├── 1.12_Transactions_Messages_and_Blockchain.md │ ├── 1.13_EVM_in_Depth.md │ ├── 1.14_Transaction_Reverts_and_Data.md │ ├── 1.15_Block_Explorer.md │ ├── 1.16_Mainnet_and_Testnets.md │ ├── 1.17_EIPs_and_ERCs.md │ ├── 1.18_Legal_Aspects_in_web3.md │ ├── 1.19_Security_in_web3.md │ ├── 1.1_Ethereum_Concept.md │ ├── 1.20_web2_timescales_vs_web3_timescales.md │ ├── 1.21_Test_in_Prod_SSLDC_vs_Audits.md │ ├── 1.2_Properties_of_the_Ethereum_Infrastructure.md │ ├── 1.3_Ethereum_vs_Bitcoin.md │ ├── 1.4_Ethereum_core_components.md │ ├── 1.5_Gas_Metering_Solving_the_Halting_Problem.md │ ├── 1.6_web2_vs_web3_The_Paradigm_Shift.md │ ├── 1.7_Decentralization.md │ ├── 1.8_Cryptography_Digital_Signature_and_Keys.md │ ├── 1.9_Ethereum_State_and_Account_Types.md │ ├── 1_Ethereum_Basics.md │ └── Summary_101_Keypoints.md ├── 2.Solidity │ ├── 2.10_Solidity_Typing.md │ ├── 2.11_Solidity_Variables.md │ ├── 2.12_Address_Type.md │ ├── 2.13_Conversions.md │ ├── 2.14_Keywords_and_Shorthand_Operators.md │ ├── 2.15_Solidity_Units.md │ ├── 2.16_Block_and_Transaction_Properties.md │ ├── 2.17_ABI_Encoding_and_Decoding.md │ ├── 2.18_Error_Handling.md │ ├── 2.19_Mathematical_and_Cryptographic_Functions.md │ ├── 2.1_Solidity_Influence_Features_and_Layout.md │ ├── 2.20_Control_Structures.md │ ├── 2.21_Style_and_Conventions.md │ ├── 2.22_Inheritance.md │ ├── 2.23_EVM_Storage.md │ ├── 2.24_EVM_Memory.md │ ├── 2.25_Inline_Assembly.md │ ├── 2.26_Solidity_Version_Changes.md │ ├── 2.27_Security_Checks.md │ ├── 2.28_Open_Zeppelin_Libraries.md │ ├── 2.29_DAppSys_Libraries.md │ ├── 2.2_SPDX_and_Pragmas.md │ ├── 2.30_Important_Protocols.md │ ├── 2.3_Imports.md │ ├── 2.4_Comments_and_Natspec.md │ ├── 2.5_Smart_Contracts.md │ ├── 2.6_State_Variables_Definition_Visibility_and_Mutability.md │ ├── 2.7_Data_Location.md │ ├── 2.8_Functions.md │ ├── 2.9_Events.md │ ├── 2_Solidity.md │ └── Summary_201_Keypoints.md ├── 3.Security_Pitfalls_and_Best_Practices │ ├── 3.10_Transaction_Order_Dependence.md │ ├── 3.11_ecrecover.md │ ├── 3.12_Unexpected_returns.md │ ├── 3.13_Ether_Accounting.md │ ├── 3.14_Transaction_Checks.md │ ├── 3.15_Delete_Mappings.md │ ├── 3.16_State_Modification.md │ ├── 3.17_Shadowing_and_Pre_Declaration.md │ ├── 3.18_Gas_and_Costs.md │ ├── 3.19_Events.md │ ├── 3.1_Solidity_Versions.md │ ├── 3.20_Typographical_Errors.md │ ├── 3.21_Addresses.md │ ├── 3.22_Assertions.md │ ├── 3.23_Keywords.md │ ├── 3.24_Visibility.md │ ├── 3.25_Inheritance.md │ ├── 3.26_Reference_Parameters.md │ ├── 3.27_Arbitrary_Jumps.md │ ├── 3.28_Hash_Collisions_and_Byte_Level_Issues.md │ ├── 3.29_Unicode_RTLO.md │ ├── 3.2_Access_Control.md │ ├── 3.30_Variables.md │ ├── 3.31_Pointers.md │ ├── 3.32_Out_of_range_Enum.md │ ├── 3.33_Dead_Code_and_Redundant_Statements.md │ ├── 3.34_Compiler_Bugs.md │ ├── 3.35_Proxy_Pitfalls.md │ ├── 3.36_Token_Pitfalls.md │ ├── 3.37_Special_Tokens_Pitfalls.md │ ├── 3.38_Guarded_Launch_Pitfalls.md │ ├── 3.39_System_Pitfalls.md │ ├── 3.3_Modifiers.md │ ├── 3.40_Access_Control_Pitfalls.md │ ├── 3.41_Testing_Unused_and_Redundant_Code.md │ ├── 3.42_Handling_Ether.md │ ├── 3.43_Application_Logic_Pitfalls.md │ ├── 3.44_Saltzer_and_Schroeders_Design_Principles.md │ ├── 3.4_Constructor.md │ ├── 3.5_Delegatecall.md │ ├── 3.6_Reentrancy.md │ ├── 3.7_Private_Data.md │ ├── 3.8_PRNG_and_Time.md │ ├── 3.9_Math_and_Logic.md │ ├── 3_Security_Pitfalls_and_Best_Practices.md │ └── Summary_201_Keypoints.md ├── 4.Audit_Techniques_and_Tools │ ├── 4.1_Audit.md │ ├── 4.2_Analysis_Techniques.md │ ├── 4.3_Specification_Documentation_and_Testing.md │ ├── 4.4_False_Positives_and_Negatives.md │ ├── 4.5_Security_Tools.md │ ├── 4.6_Audit_Process.md │ ├── 4_Audit_Techniques_and_Tools.md │ └── Summary_101_Keypoints.md ├── 5.Audit_Findings │ ├── 5.1_Criticals.md │ ├── 5.2_Highs.md │ ├── 5.3_Mediums.md │ ├── 5.4_Lows.md │ ├── 5.5_Informationals.md │ ├── 5_Audit_Findings.md │ └── Summary_201_Keypoints.md └── README.md └── secureum_bootcamp ├── history.md └── participate.md /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "src/care/CARE"] 2 | path = src/care/CARE 3 | url = git@github.com:secureum/CARE.git 4 | [submodule "script/solidity-latex-highlighting"] 5 | path = script/solidity-latex-highlighting 6 | url = git@github.com:s-tikhomirov/solidity-latex-highlighting.git 7 | [submodule "src/ctfs/AMAZEX-DSS-PARIS"] 8 | path = src/ctfs/AMAZEX-DSS-PARIS 9 | url = git@github.com:secureum/AMAZEX-DSS-PARIS.git 10 | [submodule "src/ctfs/DeFi-Security-Summit-Stanford"] 11 | path = src/ctfs/DeFi-Security-Summit-Stanford 12 | url = https://github.com/secureum/DeFi-Security-Summit-Stanford 13 | [submodule "src/ctfs/secureum-a-maze-x-challenges"] 14 | path = src/ctfs/secureum-a-maze-x-challenges 15 | url = https://github.com/secureum/secureum-a-maze-x-challenges 16 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## [📖 Secureum Book](https://secureum.gitbook.io/secureum-book) 2 | 3 | The idea is to imitate the fantastic work of the **[Foundry Book](https://github.com/foundry-rs/book)**. 4 | 5 | > *Imitation is the sincerest form of flattery* 6 | 7 | For now (and until all the information is laid out properly), contributions and acknowledgements will be done manually. 8 | 9 | ### Contributing 10 | 11 | To contribute, please to so with issues and pull requests. There is tons of content that can be added, and a lot of contents that is yet to be polished. 12 | 13 | ### Contributors 14 | 15 | *(For now this will consist of an unnumbered list. The idea is to follow the [`all-contributors`](https://github.com/all-contributors/all-contributors) specification)* 16 | 17 | - [Secureum](https://twitter.com/TheSecureum) *(original content on substack)* 18 | - [Rajeev](https://twitter.com/0xRajeev) *(Secureum founder)* 19 | - [Luksgrin](https://twitter.com/luksgrin) *(Secureum book editor, Activate x Wormhole a-MAZE-X designer & DeFi Security 101 Stanford a-MAZE-X designer)* 20 | - [Deivitto](https://twitter.com/deivitto) *(Secureum book editor & Activate x Wormhole a-MAZE-X designer)* 21 | - [0x4non](https://twitter.com/eugenioclrc) *(Activate x Wormhole a-MAZE-X designer & DeFi Security 101 Stanford a-MAZE-X designer)* 22 | - [PPrieditis](https://twitter.com/pprieditis) *(Activate x Wormhole a-MAZE-X designer)* 23 | - [NFTMerchant](https://twitter.com/nftmerchant) *(Activate x Wormhole a-MAZE-X designer)* 24 | - [Patrickd](https://twitter.com/patrick_de) *(Fantastic [Secureum RACEs writeups](https://ventral.digital/) that have to be included in this book at some point & a-MAZE-X feedback)* 25 | - [0xTaysama](https://twitter.com/0xTaylor_) *(Fantastic [Secureum mind map](https://github.com/x676f64/secureum-mind_map) that has to be included in this book at some point)* 26 | - D-Squared *(Fantastic [Secureum YouTube Playlist](https://www.youtube.com/@d-squared70))* 27 | -------------------------------------------------------------------------------- /gitbook.yaml.example: -------------------------------------------------------------------------------- 1 | root: ./ 2 | 3 | structure: 4 | readme: README.md 5 | summary: SUMMARY.md 6 | 7 | redirects: 8 | previous/page: new-folder/page.md 9 | -------------------------------------------------------------------------------- /script/luaFilters/codeblock_filter.lua: -------------------------------------------------------------------------------- 1 | function CodeBlock(elem) 2 | local latexCode = "\\begin{lstlisting}[language=Solidity,numbers=none]\n" .. elem.text .. "\n\\end{lstlisting}" 3 | return pandoc.RawBlock("latex", latexCode) 4 | end 5 | 6 | return { 7 | { 8 | CodeBlock = CodeBlock 9 | } 10 | } -------------------------------------------------------------------------------- /script/templates/secureumBookTemplate.tex: -------------------------------------------------------------------------------- 1 | \documentclass[a4paper,12pt]{book} 2 | 3 | \usepackage[normalem]{ulem} 4 | \usepackage{amsmath} 5 | \usepackage{hyperref} 6 | \usepackage{graphicx} 7 | \usepackage{longtable} 8 | \usepackage{booktabs} 9 | 10 | % \usepackage{listings} % Already included in solidity-highlighting.tex 11 | \input{solidity-latex-highlighting/solidity-highlighting.tex} 12 | 13 | \providecommand{\tightlist}{\relax} 14 | \newcommand{\stkout}[1]{\ifmmode\text{\sout{\ensuremath{#1}}}\else\sout{#1}\fi} 15 | \setlength{\parskip}{8pt plus 1pt minus 1pt} 16 | \setlength{\parindent}{0pt} 17 | 18 | \hypersetup{ 19 | colorlinks=true, 20 | linkcolor=black, 21 | filecolor=magenta, 22 | urlcolor=blue, 23 | pdftitle={The Secureum Bootcamp Book} 24 | } 25 | 26 | \setcounter{tocdepth}{1} 27 | \begin{document} 28 | \title{The Secureum Bootcamp Book} 29 | \tableofcontents 30 | %%%ELLIPSIS%%% 31 | \end{document} -------------------------------------------------------------------------------- /script/texfiles/1.11_Contract_Creation.tex: -------------------------------------------------------------------------------- 1 | \section{Contract Creation}\label{contract-creation} 2 | 3 | We mentioned that a transaction can result in contract creation. 4 | 5 | The creation transaction is a special one because it's sent to a special 6 | destination address called ``\emph{the zero address}'' (\texttt{0x0} 7 | address), which is an address that has zero in all its bits. This zero 8 | address is treated in a special maner within Ethereum, and it becomes 9 | critical to some of the smart contract security properties. 10 | 11 | It contains a data payload which represents the byte code of the 12 | contract that is being created, and it may also contain an optional 13 | Ether amount in the value field, in which case the new contract that is 14 | being created, will have a starting balance equal to this Ether value. 15 | -------------------------------------------------------------------------------- /script/texfiles/1.15_Block_Explorer.tex: -------------------------------------------------------------------------------- 1 | \section{Block Explorer}\label{block-explorer} 2 | 3 | If we want to take a look at what has happened in the past in terms of 4 | the transactions on Ethereum, the contracts that they interacted with, 5 | then the application that allows us to look at all this data is what is 6 | known as a block explorer: it lets us \textbf{explore the various blocks 7 | and their contents on the blockchain}. 8 | 9 | It's implemented as an application, a web portal if you will, and it 10 | gives us real-time on-chain data about all the transactions, the blocks, 11 | the Gas and everything that we have discussed so far. All this rich 12 | information is available in a transparent manner on the blockchain and 13 | can be accessed by everyone via this block explorer application. 14 | 15 | In the case of Ethereum we have several block explorers. The most 16 | popular one is \href{https://etherscan.io/}{Etherscan}. We also have 17 | \href{https://etherchain.org/}{Etherchain}, 18 | \href{https://ethplorer.io/}{Ethplorer}, 19 | \href{https://blockchair.com/}{Blockchair} or 20 | \href{https://blockscout.com/}{Blockscout}. 21 | -------------------------------------------------------------------------------- /script/texfiles/1.16_Mainnet_and_Testnets.tex: -------------------------------------------------------------------------------- 1 | \section{Mainnet and Testnets}\label{mainnet-and-testnets} 2 | 3 | Mainnet refers to the main Ethereum network. There is a distinction 4 | because there also exist several testnets. These testnets are test 5 | Ethereum networks where protocol and smart contract developers can test 6 | their protocol upgrades and smart contracts prior to final deployment in 7 | mainnet. 8 | 9 | While mainnet uses real Ether, testnets use what is known as 10 | ``\emph{test Ether}'\,', so that you can simulate the Gas, the transfer 11 | of value and so on\ldots{} These test Ether can be obtained from 12 | faucets. 13 | 14 | Some of the popular Ethereum testnets are \textbf{Goerli} (a proof of 15 | authority testnet that allows one to look at a lot of the Ethereum 16 | concepts and test them as if they are happening on mainnet). This 17 | particular testnet works across all the clients.It's called proof of 18 | authority because there are a small number of nodes that are allowed to 19 | create the blocks and validate them. After the Ropsten testnet reached a 20 | Terminal Total Difficulty (TTD) of $5\times 10^{16}$, the Goerli 21 | testnet transitioned to a proof-of-stake consensus mechanism to mimic 22 | Ethereum mainnet. 23 | 24 | Then we have the \textbf{Kovan} testnet, which is again a proof of 25 | authority testnet specifically for those running OpenEthereum clients. 26 | 27 | There is also the \textbf{Sepolia} Testnet. Sepolia was a 28 | proof-of-authority testnet created in October 2021. Similarly to Goerli, 29 | after the Ropsten testnet reached a Terminal Total Difficulty (TTD) of 30 | $5\times 10^{16}$, the Sepolia testnet transitioned to a 31 | proof-of-stake consensus mechanism. Sepolia was designed to simulate 32 | harsh network conditions, and has shorter block times, which enable 33 | faster transaction confirmation times and feedback for developers. 34 | Compared to other testnets like Goerli, Sepolia's total number of 35 | testnet tokens is uncapped, which means it is less likely that 36 | developers using Sepolia will face testnet token scarcity like Goerli. 37 | 38 | As you can see, these testnets are also evolving, new ones are being 39 | added over time trying to make it as easy as possible for the developers 40 | to simulate the real mainnet Ethereum blockchain and all its 41 | dependencies. This again becomes very critical to security because 42 | \textbf{testing is fundamental}: if you do not test, or if the testing 43 | environment is not very similar to the production environment, then the 44 | assumptions (the dependencies and other aspects that are tested) will be 45 | very different from what happens when you deploy the contract, which 46 | could end up causing a lot of security issues. 47 | 48 | \subsection{Deprecated testnets}\label{deprecated-testnets} 49 | 50 | Testnets are also removed over time. Some of the deprecated testnets are 51 | 52 | \begin{itemize} 53 | \tightlist 54 | \item 55 | \textbf{Rinkeby} testnet. It was a proof of authority based testnet 56 | which was specifically for the Geth clients. It shut down in 2023. 57 | \item 58 | \textbf{Ropsten} testnet. It was a proof of work testnet. It shut down 59 | at the end of 2022. 60 | \end{itemize} 61 | -------------------------------------------------------------------------------- /script/texfiles/1.17_EIPs_and_ERCs.tex: -------------------------------------------------------------------------------- 1 | \section{EIPs \& ERCs}\label{eips-ercs} 2 | 3 | \subsection{EIPs}\label{eips} 4 | 5 | EIP stands for \textbf{Ethereum Improvement Proposal}: proposals put 6 | forward by researchers, developers and/or community members in the 7 | Ethereum ecosystem to make changes to different aspects of the Ethereum 8 | protocol. 9 | 10 | There's a very well defined specific process for EIP from the time 11 | somebody proposes one to the way it is discussed, debated, voted upon 12 | and finally made it into a standard or a specification. 13 | 14 | Depending on the different layers of the Ethereum protocol, the proposal 15 | targetting these could be either addressing the core aspects of the 16 | protocol, the networking aspects, the interface or some of the token 17 | standards. 18 | 19 | \subsection{ERCs}\label{ercs} 20 | 21 | ERC stands for \textbf{Ethereum Request for Comments}. It has (sort of) 22 | become the used term for token standards. For example you have probably 23 | heard about ERC20 token standard or ERC721 token standard and so 24 | on\ldots{} These are being created as part of the EIP process. 25 | 26 | There are also some meta and informational EIPs that don't address the 27 | protocol as such, but that address some of the governance aspects of 28 | this whole ecosystem, the process and so on\ldots{} They also address 29 | some of the informational aspects of how these standards and 30 | specifications are written and distributed within the community. 31 | -------------------------------------------------------------------------------- /script/texfiles/1.18_Legal_Aspects_in_web3.tex: -------------------------------------------------------------------------------- 1 | \section{Legal Aspects in web3: Pseudonymity \& 2 | DAOs}\label{legal-aspects-in-web3-pseudonymity-daos} 3 | 4 | When it comes to legal and regulatury aspects of \textbf{who is 5 | responsible}, \textbf{what} are they responsible for \textbf{if 6 | something goes wrong}, everything changes dramatically in the web3 space 7 | compared to web2. 8 | 9 | One of the things is the \textbf{pseudonymity} or \textbf{who} is the 10 | team behind a particular project. There is an increasing trend towards 11 | some of the people involved in the projects being pseudonymous. This 12 | could be because of the regulatory uncertainty regarding 13 | cryptocurrencies (or crypto space in general), or also be because of the 14 | legal implications thereof. 15 | 16 | This changes the way we think about reputation and trustworthiness when 17 | it comes to applications, projects or products. It also affects the 18 | legal or social accountability when it comes to projects: who is 19 | responsible, who is accountable if the team is pseudonymous, how do you 20 | even know what what they're doing with the project, with the governance 21 | and so on\ldots{} There's this concept of trusting software and not 22 | wetware, which is great but there are still social processes where 23 | people are involved to a great extent around building the project, 24 | rolling it out and the governance of the projects that has a huge 25 | implication towards the security posture. 26 | 27 | \subsection{DAOs}\label{daos} 28 | 29 | \textbf{DAO}s (\textbf{Decentralized Autonomous Organizations}) stem 30 | from the trust minimization and censorship resistance aspects of web3. 31 | Their objective is to minimize the role and the influence of centralized 32 | parties, or a few privileged individuals, in the life cycle of the 33 | projects. This means that the project ultimately evolves or aspires to 34 | be governed by a DAO, which can be comprised of a \textbf{community of 35 | token holders for that particular project}. They make voting based 36 | decisions on how the project treasury should be spent, what the protocol 37 | changes should be and, in some of the cases, all these are decided 38 | on-chain and affected on-chain as well. 39 | 40 | While this reduces the centralized points of wetware failure, as we call 41 | it, it also slows down decision making on a lot of the security critical 42 | aspects: imagine if there were vulnerabilities to be found in a deployed 43 | contract, and somebody had to create a fix and deploy the fix. If that 44 | had to go through a DAO for the decision making, you would have to give 45 | a certain amount of time for the token holders to vote for that 46 | decision. 47 | 48 | A centralized party entity in the web2 space can make this decision 49 | immediately, unilaterally and deploy that fix in a few hours, if not 50 | less. In web3 (i.e.~DAOs), the decision making is decentralized and has 51 | that downside. 52 | -------------------------------------------------------------------------------- /script/texfiles/1.20_web2_timescales_vs_web3_timescales.tex: -------------------------------------------------------------------------------- 1 | \section{web2 Timescales vs.~web3 2 | timescales}\label{web2-timescales-vs.-web3-timescales} 3 | 4 | The timescale of innovation in web2, although it is seemingly fast 5 | (exponential in some ways: smartphones in just 15 years, PCs, Moore's 6 | law\ldots), those timescales are really long when you compare that to 7 | the compressed timescales of innovation that happen in the web3 world 8 | and specifically Ethereum, which again is driven by a lot of these 9 | interrelated concepts we talked about: everything being open source by 10 | design, composable, permissionless and borderless. Plus combine that 11 | with the mechanism design where a lot of this is incentivized by 12 | tokenomics. 13 | 14 | As a side effect, unfortunately, security has in some sense taken a back 15 | seat: it hasn't been really thought of as much as it should be in the 16 | design and development of a lot of these smart contracts (and hence, the 17 | applications they support). This was what contributed to a lot of the 18 | vulnerabilities we have seen within smart contracts or web3 19 | applications, which led to exploits causing losses of millions or tens 20 | of millions of dollars overnight in a fraction of a second within a few 21 | transactions. 22 | 23 | And remember this is all irreversible: all these aspects of pseudonymous 24 | teams in some cases, the presenting threat model, the use of keys, the 25 | use of tokens, the lack of any centralized third party that can reverse 26 | the negative side effects of some of these exploits\ldots{} All these 27 | interrelated concepts affect the security aspects of Ethereum and web3 28 | in general. 29 | -------------------------------------------------------------------------------- /script/texfiles/1.3_Ethereum_vs_Bitcoin.tex: -------------------------------------------------------------------------------- 1 | \section{Ethereum vs.~Bitcoin}\label{ethereum-vs.-bitcoin} 2 | 3 | \begin{itemize} 4 | \item 5 | \textbf{How does Ethereum compare to bitcoin as a blockchain?}\\ 6 | 7 | \textbf{Bitcoin} (the blockchain) came about in 2008/2009 and it 8 | focused by design on the ownership of Bitcoin (the cryptocurrency). 9 | The consensus of the blockchain (all the operations, states, state 10 | transitions\ldots) exclusively focuses on the \textbf{ownership of 11 | these coins}, and nothing else. So all these state transitions track 12 | the transfer of Bitcoin (cryptocurrency) and, in the case of the 13 | Bitcoin blockchain, they're referred to as \textbf{UTXO}s (Unspent 14 | Transaction Outputs).\\ 15 | 16 | Compared to that, the \textbf{Ethereum} blockchain by design focuses 17 | on general purpose states (states that do not only focus on the 18 | ownership of Ether but anything that can be encoded with the EVM 19 | general purpose programming language). So we are looking at a general 20 | purpose blockchain that can encodes arbitrary states and arbitrary 21 | rules for the state transitions, which tracks not only the state of 22 | Ether cryptocurrency ownership on the platform but the state of the 23 | different smart contracts as transactions interact with them.\\ 24 | 25 | \textbf{That is the key difference between Ethereum and Bitcoin: 26 | Bitcoin is UTXO based and Ethereum is state based (or account 27 | based)}.\\ 28 | \item 29 | \textbf{How does the programming language on Ethereum compare to 30 | what's available on Bitcoin?} 31 | 32 | \textbf{Bitcoin} has what is known as \texttt{bitcoin\ script}: it is 33 | a \textbf{scripting language} (so it's intentionally and by design 34 | limited) that allows an evaluation of spending conditions that yield 35 | \texttt{true} or \texttt{false} boolean outputs, which is what is 36 | required for Bitcoin (and what it's supposed to do).\\ 37 | 38 | But when you look at \textbf{Ethereum}, it supports a virtual machine 39 | known as \textbf{Ethereum Virtual Machine} (EVM), and by design it is 40 | meant to be a \textbf{general purpose programming language}. Remember 41 | it's \textbf{Turing complete} (which is a key differentiating feature 42 | of Ethereum's expressiveness power when compared to Bitcoin). 43 | \end{itemize} 44 | -------------------------------------------------------------------------------- /script/texfiles/1.7_Decentralization.tex: -------------------------------------------------------------------------------- 1 | \section{Decentralization}\label{decentralization} 2 | 3 | \begin{itemize} 4 | \tightlist 5 | \item 6 | \textbf{What does decentralization really mean?} 7 | \end{itemize} 8 | 9 | This term is used very casually although it has huge implications to how 10 | we think about security, even for smart contracts. There is a definition 11 | put forth by Vitalik in his article on decentralization. There are three 12 | types of decentralization: 13 | 14 | \begin{itemize} 15 | \item 16 | \textbf{Architectural decentralization}: it refers to the hardware 17 | (the physical computers); who runs them, owns them, who is managing 18 | them, who can start them and stop them. This can be done in a 19 | decentralized fashion or not. 20 | \item 21 | \textbf{Political decentralization}: it refers to the people behind 22 | the hardware or what is commonly referred to as ``\emph{wet ware}''. 23 | Who are the individuals or the organizations who control the hardware 24 | or the infrastructure? Is it just one individual or is it a group of 25 | individuals? Are the colluding or are they independent and 26 | decentralized? 27 | \item 28 | \textbf{Logical decentralization}: it refers to the software: used to 29 | build out the applications (the framework itself, the Ethereum code, 30 | the protocol itself, the data structures in it, the smart contracts or 31 | any other software that runs in that stack). Is that decentralized? Is 32 | it a monolithic entity that cannot be split apart and used in a 33 | decentralized fashion? 34 | \end{itemize} 35 | 36 | All of these have security implications. 37 | -------------------------------------------------------------------------------- /script/texfiles/1.9_Ethereum_State_and_Account_Types.tex: -------------------------------------------------------------------------------- 1 | \section{Ethereum State \& Account 2 | Types}\label{ethereum-state-account-types} 3 | 4 | Ethereum state is a mapping from the address of the Ethereum accounts to 5 | the state contained within it as a data structure. It is implemented as 6 | a \textbf{Modified Merkle-Patricia Tree}: a combination of a Merkle tree 7 | and a Patricia tree with some changes that are specific to Ethereum. 8 | 9 | Each of the Ethereum accounts has a unique 20 byte address associated 10 | with it, which is used by accounts to ``talk to each other''. Addresses 11 | are critical to how messaging works within the Ethereum protocol and how 12 | the accounts engage in transfer of value or information, since accounts 13 | need to be able to refer to each other using their addresses. 14 | 15 | In addition, accounts have four fields: 16 | 17 | \begin{itemize} 18 | \tightlist 19 | \item 20 | \texttt{nonce}: a counter that's used to make sure that each 21 | transaction can only be processed once used to prevent replay attacks. 22 | \item 23 | \texttt{balance}: a number representing the amount of Ether that the 24 | account has at any point in time. 25 | \item 26 | \texttt{code}: the smart contract code (absent in Externally Owned 27 | Accounts). 28 | \item 29 | \texttt{storage}: the associated smart contract storage (absent in 30 | Externally Owned Accounts). 31 | \end{itemize} 32 | 33 | \subsection{Account types}\label{account-types} 34 | 35 | Ethereum has two account types: 36 | 37 | \begin{itemize} 38 | \item 39 | \textbf{Externally Owned Account (EOA)}: it is an account that is 40 | controlled by a private key.\\ 41 | 42 | Anyone who has a private key can create a digital signature that can 43 | be used to control the Ether that is present in an EOA. These 44 | signatures can be used to sign transactions from the EOA, which in 45 | turn can trigger messages from the EOA to other accounts.\\ 46 | 47 | These messages can result in a transfer of value or they can trigger 48 | smart contracts. An EOA does not have any associated code or storage. 49 | \item 50 | \textbf{Contract account}: it is an account that is controlled by the 51 | code that is contained within that account.\\ 52 | 53 | Unlike EOAs, contract accounts have an associated smart contract code 54 | and storage. Whenever the contract account receives a message, it 55 | triggers the code present and accesses any internal storage associated 56 | with it. When the code runs it can send messages to other accounts or 57 | even create new contracts. 58 | \end{itemize} 59 | 60 | In this sense, smart contracts can be thought of autonomous agents as 61 | they're always present in the execution environment of the Ethereum 62 | blockchain. They're always ready to be triggered by a transaction or a 63 | message that is sent to them. 64 | 65 | Through their contract account they have access to the Ether balance and 66 | the contract storage. The execution of the code results in manipulation 67 | of this balance and the contract storage. 68 | -------------------------------------------------------------------------------- /script/texfiles/1_Ethereum_Basics.tex: -------------------------------------------------------------------------------- 1 | \chapter{Ethereum 101}\label{ethereum-101} 2 | 3 | This section is a high level overview of what Ethereum is. It is based 4 | on the following content: 5 | 6 | \begin{itemize} 7 | \tightlist 8 | \item 9 | \href{https://secureum.substack.com/p/ethereum-101}{\textbf{Secureum's 10 | Ethereum 101 keypoints}} 11 | \item 12 | \textbf{Secureum's Ethereum 101} YouTube videos: 13 | 14 | \begin{itemize} 15 | \tightlist 16 | \item 17 | \href{https://www.youtube.com/watch?v=44qhIBMGMoM}{Block 1} 18 | \item 19 | \href{https://www.youtube.com/watch?v=zIeBfuXxuWs}{Block 2} 20 | \item 21 | \href{https://www.youtube.com/watch?v=ltvTIr4K63s}{Block 3} 22 | \item 23 | \href{https://www.youtube.com/watch?v=MFoxW07ICKs}{Block 4} 24 | \item 25 | \href{https://www.youtube.com/watch?v=I-TjCtjDs1M}{Block 5} 26 | \end{itemize} 27 | \item 28 | \textbf{Mastering Ethereum Book} 29 | \end{itemize} 30 | -------------------------------------------------------------------------------- /script/texfiles/2.10_Solidity_Typing.tex: -------------------------------------------------------------------------------- 1 | \section{\texorpdfstring{\texttt{Solidity} 2 | Typing}{Solidity Typing}}\label{solidity-typing} 3 | 4 | \texttt{Solidity} is a \textbf{statically typed} language, which means 5 | that the type of the variables used within the contracts written in 6 | \texttt{Solidity} needs to be specified in the code explicitly at 7 | compile time. This applies both to state variables and local variables. 8 | 9 | Statically typed languages perform what is known as \textbf{compile time 10 | type checking} according to the language rules. So when variables of 11 | different types are assigned to each other at compile time, the language 12 | can enforce that the types are used correctly across all these 13 | assignments and usages. Many of the programming languages that you may 14 | be familiar with such as \texttt{C}, \texttt{C++}, \texttt{Java}, 15 | \texttt{Rust}, \texttt{Go} or \texttt{Scala} are statically typed 16 | languages. From a security perspective, the type checking is a critical 17 | part and helps in improving the security of the contracts. 18 | 19 | \subsection{Types}\label{types} 20 | 21 | \texttt{Solidity} has two categories of types: 22 | 23 | \begin{itemize} 24 | \tightlist 25 | \item 26 | \textbf{value}: they're always passed by value, which means that 27 | whenever they are used as function arguments or in assignments of 28 | expressions, they are always copied from one location to the other. 29 | \item 30 | \textbf{reference}: they can be modified via multiple names all of 31 | which point to or reference the same underlying variable (i.e.~the 32 | same memory address; this is easier to understand when it is thought 33 | like the concept of pointers). 34 | \end{itemize} 35 | 36 | From a security perspective you can imagine that this becomes important 37 | because it affects which state is being updated and what those 38 | transitions are in the states as affected by the transactions. 39 | 40 | \subsubsection{Value Types}\label{value-types} 41 | 42 | As discussed value type is one of the two types in \texttt{Solidity} 43 | where variables of these value types are passed by value (which means 44 | they are copied when used as function arguments or in assignments of 45 | expressions). 46 | 47 | There are different value types in \texttt{Solidity}: booleans, 48 | integers, fixed point numbers, address, contract, fixed size byte 49 | arrays, literals, enums and functions themselves. 50 | 51 | From a security perspective, value types can be thought of as being 52 | somewhat safer because a copy of that variable is made so that the 53 | original value of the original state itself is not modified 54 | accidentally. But then one should also check that any assumptions around 55 | the persistence of the values is being considered properly, so this will 56 | become clearer once we talk about the reference types and once we look 57 | at some of the security aspects. 58 | 59 | \subsubsection{Reference Types}\label{reference-types} 60 | 61 | In contrast to value types, reference types are passed by reference: 62 | there can be multiple names for the variable, all pointing to the same 63 | underlying variable state. There are 3 reference types in 64 | \texttt{Solidity}: \textbf{arrays}, \textbf{structs} and 65 | \textbf{mappings}. 66 | 67 | From a security perspective, reference types can perhaps be considered a 68 | little more riskier than value types because now you have multiple names 69 | pointing to the same underlying variable, which could, in some 70 | situations, lead to unintentional modification of the underlying state. 71 | -------------------------------------------------------------------------------- /script/texfiles/2.15_Solidity_Units.tex: -------------------------------------------------------------------------------- 1 | \section{\texorpdfstring{\texttt{Solidity} 2 | Units}{Solidity Units}}\label{solidity-units} 3 | 4 | \subsection{Ether Units}\label{ether-units} 5 | 6 | Ether is $18$ decimals, the smallest unit is a wei. There are various 7 | names given for different numbers of weis: $1$ gwei $= 10^9$ wei, 8 | $1$ Ether $= 10^{18}$. 9 | 10 | In the case of the \texttt{Solidity} types, a literal number can be 11 | given a suffix of a wei, or a gwei (gigawei) or an Ether. These are used 12 | to specify sub denominations of Ether, as we see here, which are used 13 | when contracts want to manipulate different denominations of Ether in 14 | the context of the logic. 15 | 16 | \subsection{Time Units}\label{time-units} 17 | 18 | As you can imagine contracts might want to work with different notions 19 | of time for various types of logic that they want to encode. 20 | \texttt{Solidity} supports different suffixes that represent time, and 21 | these can be applied to literal numbers and these suffixes are: 22 | \texttt{seconds}, \texttt{minutes}, \texttt{hours}, \texttt{days} and 23 | \texttt{weeks}. 24 | 25 | The base unit for time is \texttt{seconds}, so literally when 1 is used 26 | it is the same as representing \texttt{1\ seconds}. The suffixes cannot 27 | be directly applied onto variables, so if you want to apply time units 28 | to certain variables, then one needs to multiply that variable with that 29 | time unit. 30 | 31 | So as an example shown, if we have a \texttt{daysafter} variable and we 32 | wanted to represent the number of days then we have to proceed like 33 | follows 34 | 35 | \begin{lstlisting}[language=Solidity,numbers=none] 36 | daysafter * 1 days 37 | \end{lstlisting} 38 | 39 | That is the only way how Solidity allows one to use these units with 40 | variables. 41 | -------------------------------------------------------------------------------- /script/texfiles/2.17_ABI_Encoding_and_Decoding.tex: -------------------------------------------------------------------------------- 1 | \section{ABI Encoding/Decoding}\label{abi-encodingdecoding} 2 | 3 | \texttt{Solidity} supports multiple functions in these categories. The 4 | obvious ones are the \texttt{abi.encode()} and \texttt{abi.decode()} 5 | functions that take arguments and encode them or decode them, 6 | specifically with respect to the ABI. 7 | 8 | There are also functions that encode with the function selector 9 | (\texttt{abi.encodeWithSelector()}) or with the signature 10 | (\texttt{abi.encodeWithSignature()}), and finally there is 11 | \texttt{abi.encodePacked()} which takes the arguments and performs the 12 | encoding in a packed fashion ( there's no padding applied between the 13 | arguments supplied). 14 | 15 | For this reason the packed encoding can be ambiguous. This is something 16 | that affects security when you're considering these functions, 17 | specifically this \texttt{abi.encodePacked()} function. 18 | -------------------------------------------------------------------------------- /script/texfiles/2.19_Mathematical_and_Cryptographic_Functions.tex: -------------------------------------------------------------------------------- 1 | \section{Mathematical \& Cryptographic 2 | Functions}\label{mathematical-cryptographic-functions} 3 | 4 | Solidity supports the addition and multiplication operations with 5 | modulus: \texttt{addmod()} and \texttt{mulmod()}. 6 | 7 | It obviously supports the Keccak-256 hashing function that is 8 | fundamental to Ethereum and used extensively within Ethereum and smart 9 | contracts themselves. 10 | 11 | It also supports the standardized SHA-256 algorithm (related to 12 | Keccak-256), but the standardized version, it further supports one of 13 | the older hashing function, the ripe message digest 14 | \texttt{ripemd160(bytes\ memory)} for historical reasons. 15 | 16 | Finally it supports what is known as the \texttt{ecrecover} primitive. 17 | This is the elliptic curve recover function that takes in the hash of a 18 | message as an argument along with the signature components, the ECDSA 19 | signature components of \texttt{v}, \texttt{r} and \texttt{s}. 20 | \texttt{ecrecover} takes in these arguments and returns the address (or 21 | recovers the address) associated with the public key from the elliptic 22 | curve signature that is specified in the parameters. This is used in 23 | various smart contracts and it is used for different types of logic 24 | within them. 25 | 26 | \subsection{\texorpdfstring{\texttt{ecrecover} 27 | Malleability}{ecrecover Malleability}}\label{ecrecover-malleability} 28 | 29 | \texttt{ecrecover} is susceptible to malleability, or in other words 30 | \textbf{non-uniqueness}. In the context of signatures this means that a 31 | valid signature, can be converted into \textbf{a second valid signature 32 | without requiring knowledge of the private key} to generate those 33 | signatures. 34 | 35 | This, depending on how signatures are used within the contract logic, 36 | can result in replay attacks, where the second valid signature can be 37 | used by the user or even by the attacker to bypass the contract logic 38 | that is using these signatures. 39 | 40 | The reason for this malleability is the math behind how elliptic curve 41 | cryptography works, so the signature components of \texttt{v}, 42 | \texttt{r} and \texttt{s}. The \texttt{s} value can either be in the 43 | lower order range or in the higher order range, and \texttt{ecrecover} 44 | does not prevent the \texttt{s} value from being in one of these two 45 | ranges. This is what allows the malleability. 46 | 47 | If the smart contract logic using \texttt{ecrecover} requires the 48 | signatures to be unique, then currently the best practice is to use the 49 | ECDSA wrapper from OpenZeppelin, that enforces the \texttt{s} value to 50 | be in the lower range (it forces there to be a single valid signature 51 | for these signature components). 52 | -------------------------------------------------------------------------------- /script/texfiles/2.1_Solidity_Influence_Features_and_Layout.tex: -------------------------------------------------------------------------------- 1 | \section{Solidity: Influence, Features \& 2 | Layout}\label{solidity-influence-features-layout} 3 | 4 | \texttt{Solidity} is a \textbf{high level language} specifically 5 | designed for writing smart contracts on Ethereum. It was proposed in 6 | 2014 by Gavin Wood and was later developed (and continues to be 7 | developed) by the Ethereum Foundation team led by Dr.~Christian 8 | Reitwiessner, Alex Beregszsaszi and others. 9 | 10 | It targets the underlying EVM and is mainly influenced by \texttt{C++} 11 | (a lot of the syntax and object oriented programming), a bit from 12 | \texttt{Python} (the use of modifiers, multiple inheritance, C3 13 | linearization and the use of the \texttt{super} keyword) and some of the 14 | early motivation was also from \texttt{Javascript} (things like function 15 | level scoping or the use of \texttt{var} keyword, although those 16 | influences have significantly been reduced since version 17 | \texttt{0.4.0}). 18 | 19 | One of the few alternatives to \texttt{Solidity} is \texttt{Vyper}: it's 20 | a language that is mostly based on \texttt{Python} and has just started 21 | to catch up with some of the high profile projects on Ethereum. However, 22 | to a great extent, due to the maturity of the language and the tool 23 | chains built around it, \texttt{Solidity} is by far the most widely 24 | used, so it becomes critical that in order to evaluate security of smart 25 | contracts we understand the syntax semantics, the pitfalls and various 26 | other aspects related to it. 27 | 28 | \texttt{Solidity} is known as a ``\emph{curly bracket language}'' (it 29 | means that curly brackets are used to group together statements within a 30 | particular scope), it is also an object oriented language (so there 31 | exitsts the use of inheritance), statically typed (which means that the 32 | types of variables defined are static and defined at compile time), 33 | there is code modularity in the form of libraries and there are also 34 | user defined types. 35 | 36 | All these characteristics make \texttt{Solidity} a fully featured high 37 | level language that allows the definition of complex logic in smart 38 | contracts to leverage all the underlying features of the EVM. 39 | 40 | \begin{itemize} 41 | \item 42 | \textbf{So, how does the physical layout of a smart contract written 43 | in \texttt{Solidity} look like?} 44 | 45 | This is important to the readability aspect of the file and the 46 | maintainability aspect of the smart contract in the context of the the 47 | project itself.\\ 48 | 49 | A \texttt{Solidity} source file can contain an arbitrary number of 50 | various directives and primitives. These include the \texttt{pragma} 51 | and the \texttt{import} directives, the declarations of structs, enums 52 | and contract definitions. Every contract can itself contain 53 | structures, enums, state variables, events, errors, modifiers, 54 | constructor and various functions that define the various 55 | functionalities that are implemented by the smart contract. 56 | \end{itemize} 57 | 58 | This physical layout is something that is specific to the syntax of 59 | \texttt{Solidity}. When it comes to helping with the readability or the 60 | maintainability, it is prime to layout all the components in the order 61 | mentioned. 62 | 63 | This is something that you will commonly see when you evaluate smart 64 | contracts in \texttt{Solidity}. There might be cases where some of these 65 | are out of order from what is considered as best practice, but it's 66 | still something to keep in mind. 67 | -------------------------------------------------------------------------------- /script/texfiles/2.20_Control_Structures.tex: -------------------------------------------------------------------------------- 1 | \section{Control Structures}\label{control-structures} 2 | 3 | These are fundamental to any programming language because there is a 4 | control flow to the sequence of instructions specified in the high-level 5 | language that get translated into machine code by the compiler. 6 | 7 | In the case of \texttt{Solidity}, the control structures supported are 8 | \texttt{if}, \texttt{else}, \texttt{while}, \texttt{do}, \texttt{for}, 9 | \texttt{break}, \texttt{continue} and \texttt{return}. These are very 10 | similar to the ones found in any programming language. Although are some 11 | differences in \texttt{Solidity}: paranthesis for example cannot be 12 | omitted for conditionals that some of the other languages support, 13 | however curly braces can be omitted around single statement bodies for 14 | such conditionals. 15 | 16 | Also note that there is no type conversion from a non-boolean to a 17 | boolean type. As an example, \texttt{if(1)} is not allowed in 18 | \texttt{Solidity} because 1 is not convertible to the boolean 19 | \texttt{true}, which is supported by some of the other languages. 20 | 21 | So control structures play a critical role in the security analysis of 22 | smart contracts whether you're doing a manual review or whether you're 23 | writing a tool to pass the \texttt{Solidity} smart contract. These are 24 | some things to be understood really well because that's how control 25 | flows, and any analysis depends critically on making sure that the 26 | control flow is accurately followed and representative of what really 27 | happens at runtime. 28 | -------------------------------------------------------------------------------- /script/texfiles/2.3_Imports.tex: -------------------------------------------------------------------------------- 1 | \section{Imports}\label{imports} 2 | 3 | These \texttt{import} statements are similar to \texttt{Javascript}, 4 | where the format is 5 | 6 | \begin{lstlisting}[language=Solidity,numbers=none] 7 | import ; 8 | \end{lstlisting} 9 | 10 | They help to modularize your code: split what might become a large 11 | monolithic code base into multiple components (modules) and import them 12 | wherever they are required. 13 | 14 | This helps developers to reuse code and, again, not only it affects the 15 | readability of code (compare a piece of monolithic code that is hundreds 16 | or thousands of lines versus modular code, where they're separated out 17 | into independent self-contained modules and used only when required), it 18 | also has implications to security and optimization as well. 19 | -------------------------------------------------------------------------------- /script/texfiles/2.4_Comments_and_Natspec.tex: -------------------------------------------------------------------------------- 1 | \section{Comments \& NatSpec}\label{comments-natspec} 2 | 3 | \texttt{Solidity} supports single line comments and multiline comments 4 | as shown here 5 | 6 | \begin{lstlisting}[language=Solidity,numbers=none] 7 | // This is a single line comment 8 | /* This is a 9 | multiline 10 | comment */ 11 | \end{lstlisting} 12 | 13 | Comments are recommended to be used as inline documentation of what the 14 | contracts are supposed to do, what the functions, variables, 15 | expressions, various control and data flow expected to do as per the 16 | specification and what is really implemented. They can also be used to 17 | specify certain assumptions that the developer is making in the 18 | implementation and they can also represent some of the invariants that 19 | need to be maintained. 20 | 21 | Comments become a critical part of documentation that is included or 22 | encapsulated within the code itself, affect the readability of the code 23 | to a great extent and maintainability. In fact, comments become critical 24 | when we start talking about evaluating the security of smart contracts: 25 | comments give a lot of vital clues as to what the developer intended to 26 | implement or just information related to the various syntax or the 27 | semantics itself. 28 | 29 | \texttt{Solidity} also supports a special type of comment called 30 | \textbf{NatSpec} which stands for \textbf{Ethereum Natural Language 31 | Specification Format}. These are specialized comments that are specific 32 | to \texttt{Solidity} and \texttt{Ethereum}. They are written as follows 33 | 34 | \begin{lstlisting}[language=Solidity,numbers=none] 35 | /// This is a single line NatSpec comment 36 | /** This is a 37 | multi line NatSpec comment */ 38 | \end{lstlisting} 39 | 40 | and are located directly above the function declaration or statements 41 | that are relevant to the \textbf{NatSpec}. These NatSpec comments come 42 | in many different types: there are many different tags such as 43 | 44 | \begin{itemize} 45 | \tightlist 46 | \item 47 | \textbf{\texttt{@title}}: describes the contract or the interface. 48 | \item 49 | \textbf{\texttt{@author}}: specifies the developer (i.e.~who is 50 | authoring the contract). 51 | \item 52 | \textbf{\texttt{@notice}}: explains to an end user what the contract 53 | or function does. 54 | \item 55 | \textbf{\texttt{@dev}}: directed towards the developer for any extra 56 | implementation related details. 57 | \end{itemize} 58 | 59 | There are also specific tags related to function parameters 60 | (\texttt{@param}), the return variable (\texttt{@return}) and so 61 | on\ldots{} These NatSpec comments are meant to automatically generate 62 | \texttt{JSON} documentation for both developers as well as users and 63 | provide a lot of valuable information that the developer intended for 64 | all these various aspects of parameters, returns, contracts and so 65 | on\ldots{} They also form an important piece of the toolset that helps 66 | evaluate smart contract security. 67 | -------------------------------------------------------------------------------- /script/texfiles/2.5_Smart_Contracts.tex: -------------------------------------------------------------------------------- 1 | \section{Smart Contracts}\label{smart-contracts} 2 | 3 | Smart contracts (or simply contracts) are fundamental to what Ethereum 4 | is all about. Conceptually, contracts are very similar to the concept of 5 | classes in object oriented programming and that's because they 6 | encapsulate a state in the form of variables, and logic that allow to 7 | modify that state in the form of functions. 8 | 9 | These contracts can inherit from other contracts, they can interact with 10 | other contracts and support a very rich environment where one can 11 | specify different types of interactions between these components. 12 | 13 | Contracts contain different components, including structures, enums, 14 | state variables, events, errors, modifiers, constructor and various 15 | functions. Some of these concepts should be familiar from other 16 | programming languages, but there are also some very Ethereum specific 17 | aspects, such as those related to state variables or events, or 18 | something that's specific to \texttt{Solidity} in the case of modifiers. 19 | 20 | Contracts can come in different types: they could be either 21 | \textbf{vanilla contracts}, \textbf{libraries} or even 22 | \textbf{interfaces}. 23 | -------------------------------------------------------------------------------- /script/texfiles/2.7_Data_Location.tex: -------------------------------------------------------------------------------- 1 | \section{Data Location}\label{data-location} 2 | 3 | We talked about value types and reference types. Reference types, which 4 | consist of structs, arrays and mappings in \texttt{Solidity} allow for a 5 | specification of their data location. This is an additional annotation 6 | and it indicates where that reference type variable is stored. 7 | 8 | There are three locations: \textbf{memory}, \textbf{storage} and 9 | \textbf{calle data}. Remember that these are 3 of the 4 locations that 10 | the EVM supports besides the stack. These data location affects the 11 | lifetime or the scope and persistence of the variables stored in those 12 | locations. 13 | 14 | \begin{itemize} 15 | \item 16 | \textbf{Memory} indicates that the lifetime is limited to that 17 | external function call. 18 | \item 19 | \textbf{Storage} indicates that the lifetime extends to that whole 20 | contract and this is also the location where state variables are 21 | stored. 22 | \item 23 | \textbf{Call data} is a non-modifiable and non-persistent area where 24 | function arguments are stored. This is required for parameters of 25 | external functions but can also be used for other variables.\\ 26 | 27 | This data location annotation impacts the scope of the variables that 28 | use this lotation. From a security perspective this affects the 29 | persistence of those variables. 30 | \end{itemize} 31 | 32 | \subsection{Assignments}\label{assignments} 33 | 34 | \textbf{The data location annotation} we just talked about not only 35 | \textbf{affects the persistency of those variables}, the scope in which 36 | they are relevant, but it also affects what are known as 37 | \textbf{assignment semantics}. 38 | 39 | In the context of \texttt{Solidity}, what this means is that during an 40 | assignment, using such variables is a copy of that variable being 41 | created? Or is simply a reference being created to the existing 42 | variable? 43 | 44 | In \texttt{Solidity}, storage to memory assignments always create an 45 | independent copy. Memory to memory assignments only create references. 46 | Similarly storage to storage assignments only create a reference. All 47 | other variants, create a copy. 48 | 49 | From a security perspective how this impacts the semantics is: if a copy 50 | were to be created because of these assignment rules, then any 51 | modifications to the copy affect only the copy and not the original 52 | variable from where it was copied. 53 | 54 | On the other hand, if a reference was created, in the case of memory to 55 | memory assignments or storage to storage assignments, then the new 56 | variable modifications to that affect the original variable because both 57 | of them are just different names pointing to the same underlying 58 | variable data (the same memory address on the machine). 59 | 60 | So this becomes important when you analyze programs and notice what the 61 | data locations are for those reference types, because there's a big 62 | difference if modifications are being made to the copy versus a 63 | reference. 64 | -------------------------------------------------------------------------------- /script/texfiles/2.9_Events.tex: -------------------------------------------------------------------------------- 1 | \section{Events}\label{events} 2 | 3 | Events are an abstraction that are built on top of the EVM's logging 4 | functionality. Emitting events cause the arguments that are supplied to 5 | them to be stored in what is known as the transactions log. This log is 6 | a special data structure in the blockchain associated with the address 7 | of the specific contract that created the event. This log stays there as 8 | long as that block is accessible. 9 | 10 | The log and its event data are not accessible from within the contracts, 11 | not even from the contract that created them. This is an interesting 12 | fact of logs in EVM: they're meant to be accessed off-chain and this is 13 | allowed using \textbf{RPC}s (\textbf{Remote Procedure Calls}). So 14 | applications, off-chain interfaces or monitoring tools can subscribe and 15 | listen to these events through the RPC interface of an Ethereum client. 16 | 17 | From a security perspective, these events play a very significant role 18 | when it comes to auditing and logging for off-chain tools to know what 19 | the state of a contract is and monitor the state along with all the 20 | transitions that happen due to the transactions. 21 | 22 | \subsection{Indexed Parameters in 23 | Events}\label{indexed-parameters-in-events} 24 | 25 | Up to three parameters of every event can be specified as being indexed 26 | by using the \texttt{indexed} keyword. This causes those parameters to 27 | be stored in a special data structure known as topics instead of the 28 | data part of the log. Putting parameters into the topics part allows one 29 | to search and filter those topics in a very optimal manner. 30 | 31 | Parameters are commonly part of some of the specifications such as the 32 | \texttt{ERC20} token standard, and the events in that standard. These 33 | indexed parameters use a little more gas than the non-indexed one but 34 | they allow for faster search and query. 35 | 36 | \subsection{Event Emission}\label{event-emission} 37 | 38 | Events are triggered by using the \texttt{emit} keyword. Every contract 39 | would declare a certain set of events as relevant, and within the 40 | contract functions, wherever these events need to be created and stored 41 | in the log, they would be done so by using the \texttt{emit} keyword. An 42 | example would look like this 43 | 44 | \begin{lstlisting}[language=Solidity,numbers=none] 45 | emit Deposit(msg.sender, _id, msg.value); 46 | \end{lstlisting} 47 | 48 | for the above example, let's say that we have a deposit event as part of 49 | a particular contract, and we have specific parts of functions where we 50 | would want to create this event and store them in the log. 51 | 52 | So, following the example above, we specify the event plus the arguments 53 | that are required according to the parameters of the event. These look 54 | in some way very similar to a function call, where the event corresponds 55 | to the function and the arguments that are supplied to it correspond to 56 | the event parameters. 57 | 58 | From a security perspective, it's critical for the contract and for the 59 | developers to emit the correct event and to use the correct parameters 60 | that are required by that event. 61 | 62 | This is something that is sometimes missed or not paid attention to 63 | because it's harder to be tested perhaps, and not critical to the 64 | control flow of the contract. 65 | 66 | But the only way for off-chain entities, any kind of user interfaces or 67 | monitoring tools to keep track of the contract state and the transitions 68 | is by looking at these event parameters stored in the logs. 69 | -------------------------------------------------------------------------------- /script/texfiles/2_Solidity.tex: -------------------------------------------------------------------------------- 1 | \chapter{🌀 2. Solidity}\label{solidity} 2 | 3 | As mentioned in the previous chapter, \texttt{Solidity} is currently the 4 | most popular programming language used to develop smart contracts. In 5 | fact, it is so commonly used and there are so few alternatives to 6 | high-level languages on Ethereum, that it has become a fundamental 7 | pillar to smart contracts on Ethereum and therefore their security. 8 | 9 | This section is a high level overview of the \texttt{Solidity} EVM smart 10 | contract programming language. It is based on the following content: 11 | 12 | \begin{itemize} 13 | \tightlist 14 | \item 15 | \href{https://secureum.substack.com/p/solidity-101}{\textbf{Secureum's 16 | Solidity 101 keypoints}} 17 | \item 18 | \href{https://secureum.substack.com/p/solidity-201}{\textbf{Secureum's 19 | Solidity 201 keypoints}} 20 | \item 21 | \textbf{Secureum's Solidity 101} YouTube videos: 22 | 23 | \begin{itemize} 24 | \tightlist 25 | \item 26 | \href{https://www.youtube.com/watch?v=5eLqFac5Tkg}{Block 1} 27 | \item 28 | \href{https://www.youtube.com/watch?v=TCl1IcGl_3I}{Block 2} 29 | \item 30 | \href{https://www.youtube.com/watch?v=6VIJpze1jbU}{Block 3} 31 | \item 32 | \href{https://www.youtube.com/watch?v=WgU7KKKomMk}{Block 4} 33 | \item 34 | \href{https://www.youtube.com/watch?v=_oN7XuyhoZA}{Block 5} 35 | \end{itemize} 36 | \item 37 | \textbf{Secureum's Solidity 201} YouTube videos: 38 | 39 | \begin{itemize} 40 | \tightlist 41 | \item 42 | \href{https://www.youtube.com/watch?v=3bFgsmsQXrE}{Block 1} 43 | \item 44 | \href{https://www.youtube.com/watch?v=TqMIbouwePE}{Block 2} 45 | \item 46 | \href{https://www.youtube.com/watch?v=C0zBhTgppLQ}{Block 3} 47 | \item 48 | \href{https://www.youtube.com/watch?v=L_9Fk6HRwpU}{Block 4} 49 | \item 50 | \href{https://www.youtube.com/watch?v=0kx8M4u5980}{Block 5} 51 | \end{itemize} 52 | \item 53 | \href{https://docs.soliditylang.org/en/latest/}{\textbf{\texttt{Solidity} 54 | language docs}} 55 | \end{itemize} 56 | -------------------------------------------------------------------------------- /script/texfiles/3.11_ecrecover.tex: -------------------------------------------------------------------------------- 1 | \section{\texorpdfstring{\texttt{ecrecover}}{ecrecover}}\label{ecrecover} 2 | 3 | This security pitfall is related to the use of the \texttt{ecrecover} 4 | primitive in EVM and supported by \texttt{Solidity}. 5 | 6 | The specific pitfall is that it is susceptible to what is known as 7 | signature malleability or non-unique signatures. Remember that elliptic 8 | curve signatures in Ethereum have three components \texttt{v}, 9 | \texttt{r} and \texttt{s}. The \texttt{ecrecover} function takes in a 10 | message hash the signature associated with that message hash and returns 11 | the Ethereum address that corresponds to the private key that was used 12 | to create that signature. 13 | 14 | In the context of this pitfall, if an attacker has access to one of 15 | these signatures, then they can create a second valid signature without 16 | having access to the private key to generate that signature. 17 | 18 | This is because of the specific range that the \texttt{s} value or the 19 | \texttt{s} component of that signature can be in it can be in an upper 20 | range or a lower range and both ranges are allowed by this primitive 21 | which results in the malleability. 22 | 23 | This depending on the logic of the smart contract, the context in which 24 | it is using these signatures can result in replay attacks, so the 25 | mitigation is to check that the \texttt{s} component is only in the 26 | lower range and not in the higher range, this mitigation is enforced in 27 | OpenZeppelin's \texttt{ECDSA} library which is the recommended best 28 | practice. 29 | -------------------------------------------------------------------------------- /script/texfiles/3.14_Transaction_Checks.tex: -------------------------------------------------------------------------------- 1 | \section{Transaction Checks}\label{transaction-checks} 2 | 3 | \subsection{\texorpdfstring{\texttt{tx.origin}}{tx.origin}}\label{tx.origin} 4 | 5 | The use of \texttt{tx.origin} is considered dangerous in certain 6 | situations within smart contracts. Remember that in the context of 7 | Ethereum, \texttt{tx.origin} gives the address of the externally owned 8 | account that originated the transaction. 9 | 10 | If the \texttt{tx.origin} address is used for authorization, then it can 11 | be abused by attackers to launch replay attacks by coming in between the 12 | user and the smart contract of concern. 13 | 14 | This is sometimes known as ``\emph{man in the middle replay attack}'' 15 | (or MITM as an abbreviation) because the attacker comes in between the 16 | user and the contract, captures the transaction and later replaces it. 17 | Because the smart contract uses \texttt{tx.origin}, it fails to 18 | recognize that this transaction actually was originated from the 19 | attacker in the middle. 20 | 21 | So in this case the recommended best practice for smart contracts using 22 | authorization is to use \texttt{msg.sender} instead of 23 | \texttt{tx.origin}, because \texttt{msg.sender} would give the address 24 | of the most recent or the closest entity. So in this case, if there is a 25 | man in the middle attacker, then \texttt{msg.sender} would give the 26 | address of the attacker and not that of the authorized user pointed to 27 | by \texttt{tx.origin}. 28 | 29 | \subsection{Contract Check}\label{contract-check} 30 | 31 | There may be situations where a particular smart contract may want to 32 | know, if the transaction or the call made to it is coming from a 33 | contract account or an externally owned account. 34 | 35 | There are two popular ways for determining that: 36 | 37 | \begin{enumerate} 38 | \def\labelenumi{\arabic{enumi}.} 39 | \tightlist 40 | \item 41 | Checking if the code size of the account of the originating 42 | transaction is greater than zero and if this is not zero, it means 43 | that that account has code and therefore is a contract account. 44 | \item 45 | Checking if the \texttt{msg.sender} is the same as the 46 | \texttt{tx.origin} and, if it is, then it means that the 47 | \texttt{msg.sender} is an externally owned account. 48 | \end{enumerate} 49 | 50 | Remember that \texttt{tx.origin} can only be an externally owned account 51 | in Ethereum as of now. 52 | 53 | So these two techniques have pros and cons and depending on the specific 54 | application it may make more sense to use one over the other. 55 | 56 | There are risks associated and implications thereof of either of these 57 | two approaches particularly with the code size approach the risk is 58 | that, if this check is made while a contract is still being constructed 59 | within the constructor the code size will still be zero for that account 60 | so, if we determine based on that aspect that this is an externally 61 | owned account, then it would be a wrong assumption. 62 | -------------------------------------------------------------------------------- /script/texfiles/3.15_Delete_Mappings.tex: -------------------------------------------------------------------------------- 1 | \section{\texorpdfstring{\texttt{delete} 2 | Mappings}{delete Mappings}}\label{delete-mappings} 3 | 4 | The next security pitfall is related to the concept of the 5 | \texttt{delete} primitive and \texttt{Solidity} and how it applies to 6 | mappings. If there is a struct data structure in a smart contract that 7 | contains a mapping as one of its fields, then deleting that structure 8 | would \texttt{delete} all the fields of the struct, but the mapping 9 | field itself would remain intact, so this is one of the 10 | \texttt{Solidity}'s behaviors that needs to be kept in mind. 11 | 12 | That can have unintended consequences, if the developer assumes that the 13 | mapping field within the struct also got deleted and reinitialized to 14 | its default values. 15 | 16 | The best practice is to use an alternative approach such as considering 17 | the data structure that is meant to be deleted as being logged to 18 | prevent future logic from using the data structure or the mapping fields 19 | within that data structure. 20 | -------------------------------------------------------------------------------- /script/texfiles/3.16_State_Modification.tex: -------------------------------------------------------------------------------- 1 | \section{State Modification}\label{state-modification} 2 | 3 | Contract state modifications made in functions whose mutability is 4 | declared as \texttt{view} or \texttt{pure} will revert in contracts 5 | compiled with \texttt{Solidity} version greater than or equal to 6 | \texttt{0.5.0}. 7 | 8 | This is because this compiler version started using the 9 | \texttt{STATICCALL} opcode for such functions, this instruction leads to 10 | a revert, if that particular function modifies the contract state. 11 | 12 | So when analyzing the security aspects of contracts it's good to pay 13 | attention to the mutability of the functions to see, if they are 14 | \texttt{view} or \texttt{pure}, but they actually modify the contract 15 | state in which case they would lead to reverts at runtime. 16 | -------------------------------------------------------------------------------- /script/texfiles/3.17_Shadowing_and_Pre_Declaration.tex: -------------------------------------------------------------------------------- 1 | \section{Shadowing and 2 | Pre-declaration}\label{shadowing-and-pre-declaration} 3 | 4 | \subsection{Shadowing}\label{shadowing} 5 | 6 | Shadowing of built-in \texttt{Solidity} variables was a concern in some 7 | of the older \texttt{Solidity} versions. Built-in variables such as 8 | \texttt{now}, \texttt{assert} and some others could be shadowed by other 9 | variables, functions or modifiers in the contract to override their 10 | behavior. 11 | 12 | This as you can imagine is dangerous and could lead to many unexpected 13 | behavior and therefore this Shadowing was disallowed in later 14 | \texttt{Solidity} versions. 15 | 16 | Similar to the Shadowing of built-in variables the older versions of 17 | \texttt{Solidity} also allowed state variable shadowing. 18 | 19 | This meant that the right contracts could have state variables that had 20 | the same name as some of their base contracts. You can imagine that the 21 | base variables and shadowed variables with the same names could be 22 | confusing even for the developer and they could end up using or 23 | modifying the wrong variable from the base contracts. 24 | 25 | This dangerous and unexpected consequences was recognized, so 26 | \texttt{Solidity} compiler \texttt{0.6.0} disallowed Shadowing of state 27 | variables. 28 | 29 | \subsection{Pre-declaration}\label{pre-declaration} 30 | 31 | Earlier versions of \texttt{Solidity} allowed the use of local variables 32 | even before they were declared. 33 | 34 | These variables could be declared later or they could have been declared 35 | in another scope. This led to undefined behavior as you may expect. 36 | 37 | \texttt{Solidity} version \texttt{0.5.0} and beyond change this, to 38 | implement the popular C99-style scoping rules where variables can only 39 | be used after they have been declared and only in the same or nested 40 | scopes. 41 | -------------------------------------------------------------------------------- /script/texfiles/3.19_Events.tex: -------------------------------------------------------------------------------- 1 | \section{Events}\label{events} 2 | 3 | Events should be emitted within smart contracts for all critical 4 | operations. Emission of events that are missing for such critical 5 | operations is a security concern. 6 | 7 | The reason for this is because it affects off-chain monitoring remember 8 | that events emitted from smart contracts end up storing the parameters 9 | of such events in the log part of the blockchain. 10 | 11 | These logs either the topics part or the data part can be queried by 12 | off-chain monitoring tools or off-chain interfaces to understand what is 13 | happening in the smart contracts. This is an easier way to understand 14 | the state of the smart contracts without having to query the contracts 15 | themselves. 16 | 17 | These events become very important from a transparency and user 18 | experience perspective. So the best practice is to recommend the 19 | addition of events in all places within the smart contracts where 20 | critical operations are happening, these could be updates to critical 21 | parameters from the smart contract applications perspective this could 22 | be operations that are being done only by the owner or privileged roles 23 | within the smart contract. So in all such cases events should be emitted 24 | to allow transparency and a better user experience. 25 | 26 | \subsection{Event Parameters}\label{event-parameters} 27 | 28 | Having talked about events, let's now focus on the event parameters. 29 | Event parameters not being indexed may be a concern in certain 30 | situations. 31 | 32 | Remember that event parameters may be considered as either indexed or 33 | not depending on the use of the \texttt{indexed} keyword. This results 34 | in those parameters being stored either in the topics part of the log or 35 | the data part of the log. Being stored in the topics part of the log 36 | allows for those parameters to be accessed or queried faster due to the 37 | use of the bloom filter. If they're stored in the data part, then it 38 | results in a much slower access. 39 | 40 | There are certain parameters for certain events that are required to be 41 | indexed as per specifications. let's take the \texttt{ERC20} token 42 | standard for example: it has transfer and approval events that require 43 | some of their parameters to be indexed. 44 | 45 | Not doing it will result in the off-chain tools that are looking for 46 | such index events to be confused or thrown off track. 47 | 48 | So the best practice here is to add the \texttt{indexed} keyword to 49 | critical parameters in an event. Especially if the specification 50 | requires them to be in text, this comes at cost of some additional Gas 51 | usage, but allows for faster query. 52 | 53 | \subsection{Event Signatures}\label{event-signatures} 54 | 55 | The concern here was that of incorrect event signature in libraries. The 56 | reason for this happening was because, if events used in libraries had 57 | parameters of contract types, then because of a compiler bug, the actual 58 | contract name was used to generate the signature hash instead of using 59 | their address type. 60 | 61 | This resulted in a wrong hash for such events being used in the logs. 62 | The mitigation here was to fix the compiler bug which happened in 63 | version \texttt{0.5.8} where the address type was used instead of using 64 | the contract name incorrectly. 65 | -------------------------------------------------------------------------------- /script/texfiles/3.20_Typographical_Errors.tex: -------------------------------------------------------------------------------- 1 | \section{Typographical Errors}\label{typographical-errors} 2 | 3 | \subsection{Unary Expressions}\label{unary-expressions} 4 | 5 | Unary expressions are where an operator is used on a single operand as 6 | opposed to two operands, in which case it would be a binary expression. 7 | Such unary expressions are susceptible to typographical errors by 8 | developers. 9 | 10 | For example let's take a look at the scenario where there's a variable 11 | \texttt{x}. The developer wants to increment it by one, so the way to do 12 | that is to say \texttt{x\ +=\ 1} which effectively is 13 | \texttt{x\ =\ x\ \ +\ 1}. But if the developer interchanges the order of 14 | \texttt{+} and \texttt{=} and instead uses \texttt{x\ =\ +1}, then this 15 | would result in re-initializing the value of \texttt{x} to \texttt{+1}. 16 | The reason for this is that \texttt{+\ 1} is a unary expression whose 17 | value is \texttt{1} and \texttt{x} would get initialized to that value. 18 | 19 | As you can imagine such typographical errors are likely to be made by 20 | developers it's very easy to make these switching the order and, if they 21 | are considered as valid by the compiler, then it's very hard to notice 22 | such errors both by the developer as well as by the security auditor. 23 | 24 | So in order to prevent some of the most common usages that result in 25 | such typographical errors the unary \texttt{+} was deprecated as of 26 | compiler \texttt{Solidity} version \texttt{0.5.0}. 27 | 28 | \subsection{Long Number Literals}\label{long-number-literals} 29 | 30 | There is a security risk in the use of long number literals within 31 | \texttt{Solidity} contracts. These number literals may require many 32 | digits to represent their high values (as constants) or many decimal 33 | digits of precision, which as you can imagine is error prone. 34 | 35 | For example, if one were to define a variable representing Ether, then 36 | it would need to be assigned a number literal that has 18 zeros to 37 | represent the 18 decimals of precision. 38 | 39 | So the developer may accidentally use an extra zero or miss a zero in 40 | which case the Ether precision is different, thus the logic using this 41 | variable will be broken. 42 | 43 | The best practice here is to use the Ether or time suffixes supported by 44 | \texttt{Solidity} as applicable or to use the Scientific Notation which 45 | is also supported by \texttt{Solidity}. 46 | -------------------------------------------------------------------------------- /script/texfiles/3.22_Assertions.tex: -------------------------------------------------------------------------------- 1 | \section{Assertions}\label{assertions} 2 | 3 | \subsection{\texorpdfstring{\texttt{assert()}}{assert()}}\label{assert} 4 | 5 | This security best practice is related to the use of \texttt{assert}s 6 | within smart contracts. \texttt{assert()} should be used only to check 7 | or verify program invariants within the smart contracts. They should not 8 | be used to make any state changes within their predicates and they 9 | should also not be used to validate any user inputs. 10 | 11 | The reason for this is because, if any state changes are made as the 12 | side-effects of the predicates within asserts, then those could be 13 | missed both by developers during maintenance or when they are trying to 14 | do any testing. 15 | 16 | They could also be missed by auditors because these state changes are 17 | not expected to happen within a search and similarly, asserts should not 18 | be used to validate user inputs because that should be done using 19 | \texttt{require()} statements. 20 | 21 | As a general rule we do not expect to see any failures from asserts 22 | during normal contract functioning and therefore these best practices 23 | become very relevant. 24 | 25 | \subsection{\texorpdfstring{\texttt{assert()} 26 | vs.~\texttt{require()}}{assert() vs.~require()}}\label{assert-vs.-require} 27 | 28 | This best practice is related to the use of \texttt{assert()} versus 29 | \texttt{require()} and the specific conditions in which they should be 30 | used. 31 | 32 | These two aspects are related, but they have different usages. 33 | 34 | \texttt{assert}s should be used to check or verify invariants where 35 | these invariants are expected to be held during normal contract 36 | functioning, so we do not expect any of these asserts to fail during the 37 | contract execution and any failures are critical \texttt{panic} errors 38 | that need to be caught and dealt with in a very serious manner. 39 | 40 | On the other hand \texttt{require()} is meant to be used for input 41 | validation of arguments that are supplied by users to various public or 42 | external functions where we do expect failures to happen because the 43 | user provided values may be the zero address in some cases or maybe 44 | values that are out-of-range or do not make sense from the smart 45 | contracts perspective. 46 | 47 | So this difference is something to be kept in mind, the best practice is 48 | to use \texttt{assert()} or \texttt{require()} appropriately as the 49 | situation demands. This had a more significant impact until 50 | \texttt{Solidity} compiler version \texttt{0.8.0}. Until then, 51 | \texttt{require()} used the \texttt{REVERT} opcode which refunded the 52 | remaining Gas and failure, whereas \texttt{assert} used the 53 | \texttt{INVALID} opcode which consumed all the supplied Gas. 54 | 55 | So until that version the usage of \texttt{assert()} or 56 | \texttt{require()} incorrectly, would result in different Gas semantics. 57 | This is because in one situation the remaining Gas would be refunded, 58 | whereas in the other case all of it would be consumed. 59 | 60 | So this affected user experience as well, but this has changed since 61 | version \texttt{0.8.0} where both \texttt{require()} and 62 | \texttt{assert()} use the \texttt{REVERT} opcode and refund all the 63 | remaining Gas on failures. 64 | -------------------------------------------------------------------------------- /script/texfiles/3.23_Keywords.tex: -------------------------------------------------------------------------------- 1 | \section{Keywords}\label{keywords} 2 | 3 | This security best practice is related to the use of duplicated keywords 4 | in \texttt{Solidity} over the different compiler versions. 5 | 6 | Different keywords have been deprecated to favor one over the other, so 7 | for example \texttt{msg.gas} has been deprecated to favor 8 | \texttt{msg.gasLeft}, \texttt{throw} has been deprecated to favor the 9 | use of \texttt{revert}, \texttt{sha3} for \texttt{keccak-256}, 10 | \texttt{callcode} for \texttt{delegatecall}, \texttt{constant} Keyword 11 | for \texttt{view}, the \texttt{var} Keyword for using the actual type 12 | name instead. 13 | 14 | So all such deprecated keywords they start initially as compiler 15 | warnings where the compiler wants us not to use these keywords and over 16 | the future versions these warnings could be converted into compiler 17 | errors in which case the compilation fails. 18 | 19 | So the best practice here is to simply avoid the use of deprecated 20 | keywords even if they are compiling warnings, because these warnings can 21 | become errors in the future compiler versions. 22 | -------------------------------------------------------------------------------- /script/texfiles/3.24_Visibility.tex: -------------------------------------------------------------------------------- 1 | \section{Visibility}\label{visibility} 2 | 3 | Remember that functions in \texttt{Solidity} have the notion of 4 | visibility where they could be either \texttt{public}, 5 | \texttt{external}, \texttt{internal} or \texttt{private}, this affects 6 | which users can call these functions. 7 | 8 | So \texttt{public} and \texttt{external} functions are callable by 9 | anyone depending on the access control that is enforced on top of that, 10 | whereas \texttt{internal} and \texttt{private} can be called only from 11 | within the contracts or the derived contracts. 12 | 13 | Until \texttt{Solidity} version \texttt{0.5.0} this visibility specifier 14 | was optional and they defaulted to \texttt{public}. This aspect led to 15 | vulnerabilities where the developer forgot to mention or specify the 16 | visibility in which case it became public by default and resulted in 17 | malicious users being able to call these functions and make unauthorized 18 | state changes completely unexpected by the developer or the smart 19 | partner. 20 | 21 | So this optional specification of function visibility defaulting to 22 | \texttt{public} visibility was removed as of \texttt{Solidity} version 23 | \texttt{0.5.2}, so this was a big change when it came to increasing the 24 | security of smart contracts and since that version function visibility 25 | is required to be specified explicitly for every function. 26 | 27 | \subsection{Public Functions}\label{public-functions} 28 | 29 | Remember that \texttt{Solidity} has the notion of visibility for 30 | functions, there are four visibility specifiers: \texttt{internal}, 31 | \texttt{private}, \texttt{public} and \texttt{external}. \texttt{public} 32 | functions consume more Gas than \texttt{external} functions. 33 | 34 | The reason for this is because the arguments of \texttt{public} 35 | functions need to be copied from thecall data component of the EVM to 36 | the memory component. This copying produces more bytecode for such 37 | \texttt{public} functions which therefore consumes more Gas. 38 | 39 | This copying is not required for \texttt{external} functions where their 40 | arguments can be left behind in the calldata component of the EVM. This 41 | key difference leads to \texttt{public} functions consuming more Gas 42 | than \texttt{external} functions in \texttt{Solidity}. 43 | 44 | So if there are functions in the contract that are never called from 45 | within the contracts themselves, then such functions should be declared 46 | with \texttt{external} visibility and not \texttt{public} visibility, 47 | which leads to better Gas efficiency. 48 | -------------------------------------------------------------------------------- /script/texfiles/3.25_Inheritance.tex: -------------------------------------------------------------------------------- 1 | \section{Inheritance}\label{inheritance} 2 | 3 | Contracts that inherit from multiple contracts should be careful about 4 | the inheritance order because, if more than one such base contract 5 | defines an identical function, then the particular function 6 | implementation that gets included in the derived contract depends on 7 | this inheritance order. 8 | 9 | The best practice is for this inheritance order to be from the more 10 | general implementation to the more specific implementation. 11 | 12 | Another security pitfall related to inheritance is that of missing 13 | inheritance where a particular contract within an application might 14 | appear to inherit from another interface in that project or another 15 | abstract contract without actually doing so. 16 | 17 | And it might appear, because of the contract name that is similar to the 18 | abstract contract or the interface name or also because of the functions 19 | that are defined within this contract their names the parameter types 20 | and, so on. 21 | 22 | This appearance might give the notion that it is inheriting without 23 | actually inheriting. This affects not only the readability and 24 | maintainability aspects for the project team, but it also affects the 25 | auditability because the security reviewer might look at this contract 26 | and assume certain aspects, thinking that it's inheriting from the 27 | similarly named interface or abstract contract whereas in fact it does 28 | not do so. 29 | 30 | So the best practice here, is to make sure that the inheritance is done 31 | appropriately and, if there are similarly named contracts where they do 32 | not actually inherit from each other, then the name should be changed. 33 | But if they are in fact meant to be inherited, then specifying that 34 | inheritance will help. 35 | -------------------------------------------------------------------------------- /script/texfiles/3.26_Reference_Parameters.tex: -------------------------------------------------------------------------------- 1 | \section{Reference Parameters}\label{reference-parameters} 2 | 3 | Remember that \texttt{Solidity} has value types and reference types. 4 | This security pitfall is related to the use of reference types in 5 | function parameters when structs, arrays or mappings, which are the 6 | reference types, are passed as arguments to a function. 7 | 8 | They may be passed by value or they may be passed by reference. This 9 | difference is dictated by the use of either the \texttt{memory} or the 10 | \texttt{storage} keyword that specifies their data location. This was 11 | optional before \texttt{Solidity} version \texttt{0.5.0}, but since that 12 | version it is required to be specified explicitly. 13 | 14 | This difference is critical from a security perspective, because passing 15 | by value, if you remember, makes a copy, so any changes to the copy does 16 | not affect the original value. But passing by reference, creates a 17 | pointer to the original variable, so any changes to the passed value is 18 | actually modifying the original variable itself. 19 | 20 | This, if not treated properly could lead to unexpected changes and 21 | modifications of the original variable or a copy which could have very 22 | different behavior and impact for the smart contract logic. 23 | -------------------------------------------------------------------------------- /script/texfiles/3.27_Arbitrary_Jumps.tex: -------------------------------------------------------------------------------- 1 | \section{Arbitrary Jumps}\label{arbitrary-jumps} 2 | 3 | Arbitrary jumps are possible within \texttt{Solidity}. \texttt{Solidity} 4 | supports many different types, one of which is a function type. These 5 | function type variables are not frequently encountered, but if they are, 6 | they can are mainly found within assembly code in making arbitrary 7 | manipulations to variables of these types. In that case, they could be 8 | used to change the control flow to switch to an arbitrary location in 9 | the code. This is something to be paid attention to and from a 10 | development perspective something to be avoided. 11 | 12 | Assembly in general is very tricky to use and it bypasses many security 13 | aspects of \texttt{Solidity} such as type safety, so it's best to avoid 14 | the use of assembly if possible and definitely to avoid the use of 15 | function type variables and making arbitrary changes to it. This is 16 | because that could result in changes to control flow that is unexpected 17 | by the developers or the smart contract auditors. 18 | -------------------------------------------------------------------------------- /script/texfiles/3.29_Unicode_RTLO.tex: -------------------------------------------------------------------------------- 1 | \section{Unicode RTLO}\label{unicode-rtlo} 2 | 3 | There is a security pitfall that arises because of the use of the 4 | Unicode Right-to-Left-Override control character (\texttt{U+202E}) in 5 | \texttt{Solidity} smart contracts causes the text to be rendered from 6 | right to left instead of the usual left to right. 7 | 8 | This reverse rendering confuses the users as well as the security 9 | reviewers from understanding what the real intent is of that particular 10 | snippet of the smart contract. 11 | 12 | The best practice here is to ensure that such confusing Unicode 13 | characters (the RTLO control character) is not used within smart 14 | contracts at all. 15 | -------------------------------------------------------------------------------- /script/texfiles/3.31_Pointers.tex: -------------------------------------------------------------------------------- 1 | \section{Pointers}\label{pointers} 2 | 3 | \subsection{Storage Pointers}\label{storage-pointers} 4 | 5 | There is a security pitfall related to the use of uninitialized storage 6 | pointers. Local storage variables that are uninitialized can point to 7 | unexpected storage locations within the contract. 8 | 9 | This can lead to developers unintentionally modifying the contract 10 | state, which can lead to serious vulnerabilities. Given that this is so 11 | error-prone, \texttt{Solidity} compiler \texttt{0.5.0} started 12 | disallowing such pointers. 13 | 14 | \subsection{Function Pointers}\label{function-pointers} 15 | 16 | There was a security risk in using uninitialized function pointers 17 | within constructors of contracts because of a compiler bug that resulted 18 | in unexpected behavior. 19 | 20 | This compiler bug was present in \texttt{Solidity} versions 21 | \texttt{0.4.5} to \texttt{0.4.26} and \texttt{0.5.0} to \texttt{0.5.7} 22 | and has since been fixed. 23 | -------------------------------------------------------------------------------- /script/texfiles/3.32_Out_of_range_Enum.tex: -------------------------------------------------------------------------------- 1 | \section{Out-of-range Enum}\label{out-of-range-enum} 2 | 3 | Older versions of \texttt{Solidity} produced unexpected behavior with 4 | out-of-range enums. For example we had \texttt{enum\ E\{a\}} (with a 5 | single member \texttt{a}) as shown here, then \texttt{E(1)} is 6 | out-of-range because, remember, indexing of \texttt{enum} members begins 7 | with 0. 8 | 9 | So \texttt{E(1)} here is out-of-range because there's a single mapper. 10 | This out-of-range \texttt{enum} produced unexpected behavior in 11 | \texttt{Solidity\ \textless{}\ 0.4.5}. This was due to a compiler bug 12 | which has since been fixed. 13 | 14 | The best practice until the fix was applied was to check the use of 15 | \texttt{enums} to make sure they are not out-of-range. 16 | -------------------------------------------------------------------------------- /script/texfiles/3.3_Modifiers.tex: -------------------------------------------------------------------------------- 1 | \section{Modifiers}\label{modifiers} 2 | 3 | \subsection{Side-effects in Modifiers}\label{side-effects-in-modifiers} 4 | 5 | Modifiers in \texttt{Solidity} smart contracts are typically used to 6 | implement different kinds of security checks (for example access control 7 | checks), or accounting checks on fund balances and so on. Such modifiers 8 | should not have any side-effects, they should not be making any state 9 | changes to the contract or external calls to other contracts. 10 | 11 | The reason for that is any such side-effects made by the modifiers, may 12 | go unnoticed both by the developers as well as the smart contract 13 | security auditors evaluating the security of these contracts. 14 | 15 | They go unnoticed not only because developers and auditors assume that 16 | modifiers don't make side-effects, but also because the modified code is 17 | typically declared in a different location from the function 18 | implementation itself. Remember that the best practice is for the 19 | modifiers to be declared in the beginning of the contract and function 20 | implementations in the later part of the contract. 21 | 22 | So as a security check, one should make sure that modifiers declared in 23 | contract should not have any side-effects and they should be only 24 | enforcing checks on different aspects of the contract. 25 | 26 | \subsection{Incorrect Modifiers}\label{incorrect-modifiers} 27 | 28 | Incorrect modifiers are a security risk. Modifiers should not only 29 | implement the correct access control or accounting checks as relevant to 30 | the smart contract logic, but they should also execute the code in 31 | ``\texttt{\_}'' or revert along all the control flow paths within that 32 | modifier. Remember that in the context of \texttt{Solidity}, 33 | ``\texttt{\_}'' inlines the function code on which the modifier is 34 | applied. 35 | 36 | So, if this does not happen along any particular control flow path 37 | within the modifier, then the default value for that function is return. 38 | 39 | This may be unexpected from the context of the caller who called this 40 | function on which this modifier is applied, so the security check is to 41 | make sure that all the control flow paths within the modifier either 42 | execute ``\texttt{\_}'' or revert. 43 | -------------------------------------------------------------------------------- /script/texfiles/3.41_Testing_Unused_and_Redundant_Code.tex: -------------------------------------------------------------------------------- 1 | \section{Testing, Unused and Redundant 2 | Code}\label{testing-unused-and-redundant-code} 3 | 4 | \subsection{Testing}\label{testing} 5 | 6 | Software testing or validation is a fundamental software engineering 7 | practice that is a critical contributor to improved security. Testing 8 | validates whether the system implementation meets the requirements as 9 | detailed by the specification. Unit tests, functional tests, integration 10 | and end-to-end tests should have been performed to achieve good test 11 | coverage across the entire code base. 12 | 13 | \begin{itemize} 14 | \tightlist 15 | \item 16 | Changes introduced with any revisions should be validated with 17 | regression tests. 18 | \item 19 | Smoke testing indicates at a high level if the functionality works or 20 | not. 21 | \item 22 | Stress testing validates extreme scenarios with borderline cases to 23 | check if those have been considered correctly. 24 | \item 25 | Performance and security specific testing validates those aspects 26 | respectively. 27 | \end{itemize} 28 | 29 | Any code or parameterization used specifically for testing should be 30 | removed from production code, which in smart contracts may apply 31 | differently to testnets vs.~mainnet. Leaving test parameters or 32 | configurations behind may accidentally allow their usage resulting in 33 | unexpected maintenance behavior or serious vulnerabilities, so overall 34 | we need to ensure that sufficient levels of testing have been performed 35 | across all these different categories we just mentioned. 36 | 37 | \subsection{Unused Code}\label{unused-code} 38 | 39 | Unused constructs may negatively impact security. This applies to any 40 | unused reports, inherited contracts, functions, parameters, variables, 41 | modifiers, events or return values; all of which should be removed or 42 | used appropriately after careful evaluation. 43 | 44 | Removing will not only reduce Gas costs, but also improve readability 45 | and maintainability of the code. Unused constructs may also be 46 | indicative of missing logic that may be a security concern, if that 47 | logic were to have implemented security related functionality, so one 48 | needs to either remove or use such unused constructs. 49 | 50 | \subsection{Redundant Code}\label{redundant-code} 51 | 52 | Redundant constructs are also concerned. These are a kind of constructs 53 | that are not required either because there are equivalent constructs 54 | that implement the same functionality or because they are not relevant 55 | anymore. Such redundant code and comments can be confusing and should be 56 | removed or changed appropriately after careful evaluation. 57 | 58 | Similar to unused constructs, removing redundant constructs will not 59 | only reduce Gas costs but also improve readability and maintainability 60 | of the code. If redundant constructs are indicative of missing or 61 | incorrect logic, then they may be a security concern, if such logic were 62 | to have implemented security related functionality. So one needs to 63 | either remove such redundant constructs or make them relevant by adding 64 | or changing the corresponding logic. 65 | -------------------------------------------------------------------------------- /script/texfiles/3.42_Handling_Ether.tex: -------------------------------------------------------------------------------- 1 | \section{Handling Ether}\label{handling-ether} 2 | 3 | Let's now talk about another fundamental aspect of smart contracts and 4 | Ethereum which is the way they handle Ether. Contracts that accept, 5 | manage or transfer Ether should take care of several things. 6 | 7 | \begin{itemize} 8 | \tightlist 9 | \item 10 | They should ensure that functions handling Ether are using 11 | \texttt{msg.value} appropriately, remember that \texttt{msg.value} is 12 | a global variable in the context of a transaction which, for example 13 | when used or accounted multiple times (say inside loops) have led to 14 | critical vulnerabilities. 15 | \item 16 | They should ensure that logic that depends on Ether value accounts for 17 | either less or more Ether set via \texttt{payable} functions. 18 | \item 19 | Logic that depends on contract Ether balance, accounts for the 20 | different direct or indirect ways of receiving Ether such as 21 | \texttt{coinbase} transaction or \texttt{selfDestruct} recipient that 22 | we have discussed earlier. 23 | \item 24 | Logic that handles withdrawal balance and transfers does so correctly 25 | in any accounting logic. 26 | \item 27 | Transfers should be reentrancy safe. 28 | \item 29 | Ether can't accidentally get locked within a contract. 30 | \end{itemize} 31 | 32 | Functions handling Ether should also be checked extra carefully for 33 | access control input validation and error handling all these various 34 | aspects of Ether handling should be reviewed for correctness. 35 | -------------------------------------------------------------------------------- /script/texfiles/3.4_Constructor.tex: -------------------------------------------------------------------------------- 1 | \section{Constructor}\label{constructor} 2 | 3 | \subsection{Constructor Names}\label{constructor-names} 4 | 5 | Constructor names in \texttt{Solidity} have had security implications 6 | historically. If you go back all the way to \texttt{Solidity} compiler 7 | version \texttt{0.4.22}, the versions prior to that one required the use 8 | of the contract name as the name of the constructor. And between that 9 | version and \texttt{0.5.0} one could either use the contract name as a 10 | constructor or use the \texttt{constructor} keyword itself. It was only 11 | after \texttt{0.5.0} that \texttt{Solidity} forced the use of the 12 | \texttt{constructor} keyword for constructors. 13 | 14 | So this flexibility, the use of the contract name as the constructor 15 | name, has historically caused bugs, where the contact name was 16 | misspelled which led to that function not being the constructor, but a 17 | regular function. 18 | 19 | Also the flexibility between allowing both the old style and the new 20 | style constructor names caused security issues, because there was a 21 | precedence that was followed, if both of them existed. So this 22 | constructor naming confusion has been a historical source of bugs and 23 | \texttt{Solidity} smart contracts, although \textbf{it is not a concern 24 | anymore}. 25 | 26 | \subsection{Void Constructor}\label{void-constructor} 27 | 28 | There's a security concern related to ``\emph{void constructors}''. What 29 | this means is that if a contract derives from other contracts, then it 30 | makes calls to the constructors of base contracts assuming they're 31 | implemented, but if in fact they are not, then this assumption leads to 32 | security implications. 33 | 34 | So the best practice for derived contracts is to check if the base 35 | constructor is actually implemented and remove the call to that 36 | constructor, if it is not implemented at all. 37 | 38 | \subsection{Constructor Call Value}\label{constructor-call-value} 39 | 40 | This security pitfall is related to the checks for any value sent in 41 | contact creation transactions triggering the constructor. 42 | 43 | Typically, if a constructor is not explicitly payable and there is an 44 | Ether value that is sent in a contract creation transaction that 45 | triggers such a constructor, then the constructor reverts that 46 | transaction. 47 | 48 | However, because of a compiler bug, if contract did not have an explicit 49 | constructor but had a base contract that did define a constructor, then 50 | in those cases, it was possible to send Ether value in a contract 51 | creation transaction, that would not cause that revert to happen. This 52 | compiler bug was present all the way from version \texttt{0.4.5} to 53 | version \texttt{0.6.8}, and thus \textbf{is not an issue anymore}. 54 | -------------------------------------------------------------------------------- /script/texfiles/3.5_Delegatecall.tex: -------------------------------------------------------------------------------- 1 | \section{\texorpdfstring{\texttt{delegatecall}}{delegatecall}}\label{delegatecall} 2 | 3 | The security pitfall is related to the use of \texttt{delegatecall} in 4 | contracts where the \texttt{delegatecall} may be made to an address that 5 | is user controlled. Remember that in the case of \texttt{delegatecall}s, 6 | the calling contract makes a \texttt{delegatecall} to a called contract, 7 | where the called contract executes its logic on the state of the calling 8 | contract. 9 | 10 | So, if the address of the called contract is user controlled, then the 11 | user may accidentally or maliciously make this \texttt{delegatecall} to 12 | a malicious contract, that can make unauthorized modifications to the 13 | state of the calling contract. 14 | 15 | Therefore, \texttt{delegatecall}s should be used with extreme care in 16 | contracts. All precautions should be used to ensure that the destination 17 | addresses for such \texttt{delegatecall}s are trusted. 18 | -------------------------------------------------------------------------------- /script/texfiles/3.7_Private_Data.tex: -------------------------------------------------------------------------------- 1 | \section{Private Data}\label{private-data} 2 | 3 | This security pitfall is related to the notion of what is private data 4 | on a blockchain or the privacy of on-chain data. 5 | 6 | Remember that state variables and \texttt{Solidity} have a function 7 | visibility specifier. By making this specified a \texttt{private}, such 8 | private state variables can't be read only by other smart contracts on 9 | the blockchain, this does not mean that they can't be read at all. 10 | 11 | We don't have to believe that they are considered private in a 12 | confidentiality perspective because the state of such variables and 13 | contracts and transactions in general on the blockchain can be read by 14 | anyone on the chain itself or via off-chain interfaces by querying the 15 | mempools for transactions or by querying the contract state itself to 16 | look at what values such private variables contain. 17 | 18 | This effectively means that, \textbf{there is no notion of data being 19 | private on the blockchain} and any such data for confidentiality reasons 20 | that needs to be private should be encrypted and stored off-chain. 21 | -------------------------------------------------------------------------------- /script/texfiles/3.8_PRNG_and_Time.tex: -------------------------------------------------------------------------------- 1 | \section{PRNG and Time}\label{prng-and-time} 2 | 3 | \subsection{PRNG}\label{prng} 4 | 5 | This security pitfall is related to pseudo-random number generation on 6 | the blockchain within smart contracts applications that require such 7 | random numbers. 8 | 9 | Remember that these values could be influenced to a certain extent by 10 | miners who are mining the blocks that contain these values. So if the 11 | stakes in those applications using these as sources of randomness is 12 | high, then such actors could use their influence to a certain extent to 13 | gain advantage. 14 | 15 | So this is a risk from randomness that needs to be paid attention to 16 | something to be aware of and, if the stakes are high for the 17 | applications where you desire a much better source of randomness then, 18 | there are some alternatives such as the verifiable random function 19 | provided by Chainlink. 20 | 21 | \subsection{Time}\label{time} 22 | 23 | Similar to randomness, the notion of getting the time on-chain is also 24 | tricky. Often smart contracts resort to using \texttt{block.timestamp} 25 | or \texttt{block.number} as sources for inferring the time within the 26 | application's logic. 27 | 28 | Again, what needs to be paid attention to is that this notion of time 29 | can be influenced to a certain extent by the miners. There are issues 30 | with synchronization across the different blockchain nodes and there are 31 | also aspects of the block times that change by a certain degree over 32 | time. 33 | 34 | This is again a risk that needs to be paid attention to and, there are 35 | some alternatives to this using the concept of Oracles. 36 | -------------------------------------------------------------------------------- /script/texfiles/3_Security_Pitfalls_and_Best_Practices.tex: -------------------------------------------------------------------------------- 1 | \chapter{🔏 3. Security Pitfalls \& Best 2 | Practices}\label{security-pitfalls-best-practices} 3 | 4 | In this section we will be discussing commonly encountered pitfalls and 5 | recommended best practices related to Ethereum smart contract security. 6 | It is based on the following content: 7 | 8 | \begin{itemize} 9 | \tightlist 10 | \item 11 | \href{https://secureum.substack.com/p/security-pitfalls-and-best-practices-101}{\textbf{Secureum's 12 | Security Pitfalls and Best Practices 101 keypoints}} 13 | \item 14 | \href{https://secureum.substack.com/p/security-pitfalls-and-best-practices-201}{\textbf{Secureum's 15 | Security Pitfalls and Best Practices 201 keypoints}} 16 | \item 17 | \textbf{Secureum's Security Pitfalls and Best Practices 101} YouTube 18 | videos: 19 | 20 | \begin{itemize} 21 | \tightlist 22 | \item 23 | \href{https://www.youtube.com/watch?v=OOzyoaYIw2k}{Block 1} 24 | \item 25 | \href{https://www.youtube.com/watch?v=fgXuHaZDenU}{Block 2} 26 | \item 27 | \href{https://www.youtube.com/watch?v=YVewx1xVROE}{Block 3} 28 | \item 29 | \href{https://www.youtube.com/watch?v=byA3MLLiKMM}{Block 4} 30 | \item 31 | \href{https://www.youtube.com/watch?v=vyWLO5Dlg50}{Block 5} 32 | \end{itemize} 33 | \item 34 | \textbf{Secureum's Security Pitfalls and Best Practices 201} YouTube 35 | videos: 36 | 37 | \begin{itemize} 38 | \tightlist 39 | \item 40 | \href{https://www.youtube.com/watch?v=WGM1SF8twmw}{Block 1} 41 | \item 42 | \href{https://www.youtube.com/watch?v=HqHo1jKUnmU}{Block 2} 43 | \item 44 | \href{https://www.youtube.com/watch?v=pXoEIjHupXk}{Block 3} 45 | \item 46 | \href{https://www.youtube.com/watch?v=IVbEIbIpWUY}{Block 4} 47 | \item 48 | \href{https://www.youtube.com/watch?v=QSsfkmcdbPw}{Block 5} 49 | \end{itemize} 50 | \end{itemize} 51 | -------------------------------------------------------------------------------- /script/texfiles/4.4_False_Positives_and_Negatives.tex: -------------------------------------------------------------------------------- 1 | \section{False Positives \& Negatives}\label{false-positives-negatives} 2 | 3 | Let's now talk about the concept of false positives and false negatives, 4 | which are critical to understand in the context of smart contract audits 5 | or security. 6 | 7 | \subsection{False Positives}\label{false-positives} 8 | 9 | False positives are findings which flag the presence of vulnerabilities, 10 | but which in fact are not vulnerabilities. They could arise due to 11 | incorrect assumptions or simplifications in analysis which do not 12 | correctly consider all the factors required for the actual presence of 13 | vulnerabilities. 14 | 15 | False positives require further manual analysis on findings to 16 | investigate if they are indeed false positives or if they are true 17 | positives. A high number of false positives increases the manual effort 18 | required in verification and also lowers the confidence in the accuracy 19 | of findings from the earlier automated analysis. 20 | 21 | On the flip side, true positives might sometimes be incorrectly 22 | classified as false positives, which leads to the vulnerabilities behind 23 | those findings being ignored and left behind in the code instead of 24 | being fixed, and may end up getting exploited later. 25 | 26 | \subsection{False Negatives}\label{false-negatives} 27 | 28 | On the other hand false negatives are missed findings that should have 29 | indicated the presence of vulnerabilities, but which are in fact not 30 | reported at all. Such false negatives again could be due to incorrect 31 | assumptions or inaccuracies in analysis which did not correctly consider 32 | the minimum factors required for the actual presence of vulnerabilities. 33 | 34 | False negatives, per definition, are not reported or even realized 35 | unless a different analysis reveals their presence, or the 36 | vulnerabilities are realized when they're exploited. A high number of 37 | false negatives lowers the confidence in the effectiveness of the 38 | earlier manual or automated analysis. In contrast, true negatives are 39 | findings that are analyzed and dismissed which are in fact not 40 | vulnerabilities 41 | 42 | So these concepts of true positives, false positives, true negatives and 43 | false negatives come up often in smart contract auditing and in security 44 | in general, and therefore this terminology (the distinction between 45 | these types) should be well understood. 46 | -------------------------------------------------------------------------------- /script/texfiles/4_Audit_Techniques_and_Tools.tex: -------------------------------------------------------------------------------- 1 | \chapter{Audit Techniques \& Tools}\label{audit-techniques-tools} 2 | 3 | In this chapter we will cover the various technical and non-technical 4 | aspects of smart contact auditing, starting with the high level view of 5 | what are audits (the entire context around it). Then we'll review the 6 | widely used tools in this space developed by teams from Trail of Bits, 7 | Consensus Diligence and others. We will cover high level aspects of 8 | these tools without getting too much into their operational or technical 9 | details which is out of scope.If you want to learn more about these 10 | tools, it is highly encouraged to install them and experiment with them. 11 | 12 | Finally we will review the audit process and the various aspects that 13 | one will need to understand to become a smart contact security auditor. 14 | 15 | It is based on the following content: 16 | 17 | \begin{itemize} 18 | \tightlist 19 | \item 20 | \href{https://secureum.substack.com/p/audit-techniques-and-tools-101}{\textbf{Secureum's 21 | Audit Techniques \& Tools 101 keypoints}} 22 | \item 23 | \textbf{Secureum's Audit Techniques \& Tools 101} YouTube videos: 24 | 25 | \begin{itemize} 26 | \tightlist 27 | \item 28 | \href{https://www.youtube.com/watch?v=M0C7z3TE5Go}{Block 1} 29 | \item 30 | \href{https://www.youtube.com/watch?v=QstpNY1IuqM}{Block 2} 31 | \item 32 | \href{https://www.youtube.com/watch?v=QmD2bJUe140}{Block 3} 33 | \item 34 | \href{https://www.youtube.com/watch?v=jZ81ebDJVe0}{Block 4} 35 | \item 36 | \href{https://www.youtube.com/watch?v=dgITqd3mkDk}{Block 5} 37 | \end{itemize} 38 | \end{itemize} 39 | -------------------------------------------------------------------------------- /script/texfiles/5_Audit_Findings.tex: -------------------------------------------------------------------------------- 1 | \chapter{Audit Findings}\label{audit-findings} 2 | 3 | In this chapter, we will review findings from public audit reports of 4 | leading audit firms to get a sense for the kinds of issues reported 5 | during audits and their suggestive fixes or recommendations. The 6 | severity of these findings spans a wide spectrum (they may go from 7 | medium severity to high and critical, which are of the highest concern 8 | as they could have led to loss of funds or significantly affected 9 | execution, if they had not been detected and fixed during audits; or 10 | also be low severity, informational and best practice guidelines). 11 | 12 | We will only be able to touch upon key aspects of these findings. The 13 | reason is that these findings require a lot of context from the deepest 14 | details of the protocol implementations, which is certainly out of 15 | scope. This research will need to be done by interested bootcamp 16 | participants in their own time, by reviewing the audit reports and their 17 | corresponding protocol codebases to whatever depth possible. 18 | 19 | For each finding, we will review the vulnerability category, its finding 20 | summary and the proposed recommendation while relating some of these 21 | aspects to our learnings from the earlier chapters. 22 | 23 | It is based on the following content: 24 | 25 | \begin{itemize} 26 | \tightlist 27 | \item 28 | \href{https://secureum.substack.com/p/audit-findings-101}{\textbf{Secureum's 29 | Audit Findings 101 keypoints}} 30 | \item 31 | \href{https://secureum.substack.com/p/audit-findings-201}{\textbf{Secureum's 32 | Audit Findings 201 keypoints}} 33 | \item 34 | \textbf{Secureum's Audit Findings 101} YouTube videos: 35 | 36 | \begin{itemize} 37 | \tightlist 38 | \item 39 | \href{https://www.youtube.com/watch?v=SromSImIpHE}{Block 1} 40 | \item 41 | \href{https://www.youtube.com/watch?v=KLBi3Uyg0dY}{Block 2} 42 | \item 43 | \href{https://www.youtube.com/watch?v=RUyED_6mkqg}{Block 3} 44 | \item 45 | \href{https://www.youtube.com/watch?v=D1Uz0NvrqeU}{Block 4} 46 | \item 47 | \href{https://www.youtube.com/watch?v=GX8Z0kRRi_I}{Block 5} 48 | \end{itemize} 49 | \item 50 | \textbf{Secureum's Audit Findings 201} YouTube videos: 51 | 52 | \begin{itemize} 53 | \tightlist 54 | \item 55 | \href{https://www.youtube.com/watch?v=IXm6JAprhuw}{Block 1} 56 | \item 57 | \href{https://www.youtube.com/watch?v=yphqu2N35X4}{Block 2} 58 | \item 59 | \href{https://www.youtube.com/watch?v=zAzNDwu23UI}{Block 3} 60 | \item 61 | \href{https://www.youtube.com/watch?v=poxzr4-srn0}{Block 4} 62 | \item 63 | \href{https://www.youtube.com/watch?v=0J7KI4WGd0Q}{Block 5} 64 | \end{itemize} 65 | \end{itemize} 66 | -------------------------------------------------------------------------------- /secureumBootcamp.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secureum/Secureum-Book/0b99c94848baa99dfc1e226c01a94289958574ec/secureumBootcamp.pdf -------------------------------------------------------------------------------- /src/README.md: -------------------------------------------------------------------------------- 1 | # 🛡 Secureum Bootcamp 2 | 3 | ![Secureum Bootcamp](img/secureum-banner.png) 4 | 5 | ## Mission 6 | 7 | Secureum's mission is scaling security on the Ethereum ecosystem by acting on Ethereum's "_Layer zero_": the community, by providing education on smart contract security and best practices. 8 | 9 | 10 | 11 | ### Why? 12 | 13 | Let's think about the ethereum ecosystem: there are billions of dollars of value, circulating on thousands of protocols, which are audited by hundreds of experts. So there’s clearly a bottleneck in security: **there are insufficient experts to properly cover all the protocols in the ecosystem**. 14 | 15 | This fact is reflected in the losses due to security issues in many DeFi projects. 16 | 17 | 18 | 19 | Currently, Secureum hosts the Epoch ∞ Bootcamp, which is an **ongoing bootcamp** where participants study Secureum's "`LEARN`" content at their own pace, and when ready, once a month they can sign up for a Secureum "`RACE`" to test their learnings. 20 | 21 | Top scoring participants are invited to "`CARE`"s, to work side by side with one of Secureum’s collaborators. 22 | 23 | It is completely free and online. For more details, `join the Secureum Discord server` or navigate to [🙌 Participate](secureum\_bootcamp/secureum\_bootcamp/participate.md). 24 | 25 | #### Pages 26 | 27 | **🙌 Participate** 28 | 29 | {% content-ref url="secureum_bootcamp/participate.md" %} 30 | [participate.md](secureum\_bootcamp/participate.md) 31 | {% endcontent-ref %} 32 | 33 | **📜 History** 34 | 35 | {% content-ref url="secureum_bootcamp/history.md" %} 36 | [history.md](secureum\_bootcamp/history.md) 37 | {% endcontent-ref %} 38 | 39 | **📚 LEARN** 40 | 41 | {% content-ref url="learn/1.Ethereum_Basics/1_Ethereum_Basics.md" %} 42 | [1\_Ethereum\_Basics.md](learn/1.Ethereum\_Basics/1\_Ethereum\_Basics.md) 43 | {% endcontent-ref %} 44 | 45 | {% content-ref url="learn/2.Solidity/2_Solidity.md" %} 46 | [2\_Solidity.md](learn/2.Solidity/2\_Solidity.md) 47 | {% endcontent-ref %} 48 | 49 | {% content-ref url="learn/3.Security_Pitfalls_and_Best_Practices/3_Security_Pitfalls_and_Best_Practices.md" %} 50 | [3\_Security\_Pitfalls\_and\_Best\_Practices.md](learn/3.Security\_Pitfalls\_and\_Best\_Practices/3\_Security\_Pitfalls\_and\_Best\_Practices.md) 51 | {% endcontent-ref %} 52 | 53 | {% content-ref url="learn/4.Audit_Techniques_and_Tools/4_Audit_Techniques_and_Tools.md" %} 54 | [4\_Audit\_Techniques\_and\_Tools.md](learn/4.Audit\_Techniques\_and\_Tools/4\_Audit\_Techniques\_and\_Tools.md) 55 | {% endcontent-ref %} 56 | 57 | {% content-ref url="learn/5.Audit_Findings/5_Audit_Findings.md" %} 58 | [5\_Audit\_Findings.md](learn/5.Audit\_Findings/5\_Audit\_Findings.md) 59 | {% endcontent-ref %} 60 | 61 | **🌱 CARE** 62 | 63 | {% content-ref url="care/README.md" %} 64 | [CARE](care/README.md) 65 | {% endcontent-ref %} 66 | 67 | **🚩 CTFs** 68 | 69 | {% content-ref url="ctfs/README.md" %} 70 | [A-MAZE-X CTFs](ctfs/README.md) 71 | {% endcontent-ref %} 72 | -------------------------------------------------------------------------------- /src/care/README.md: -------------------------------------------------------------------------------- 1 | # CARE 2 | CARE stands for "Comprehensive Audit Readiness Evaluation." CARE is not a replacement for a security audit, but is intended to happen before an audit so that protocol code becomes ready for future audit(s) to get a better security outcome from the process. 3 | 4 | CARE reviews protocol code mainly for common security pitfalls and best-practices as related to smart contracts written in Solidity specifically for Ethereum blockchain or associated Layer-2 protocols. The pitfalls & best-practices are evaluated from (but not limited to) Secureum’s Security Pitfalls & Best Practices [101](https://secureum.substack.com/p/security-pitfalls-and-best-practices-101) and [201](https://secureum.substack.com/p/security-pitfalls-and-best-practices-201). 5 | 6 | CARE aims to help identify such common pitfalls & best-practices so that they can be fixed before audit(s). This improves protocol's risk posture earlier in the design & development lifecycle and enables future audit(s) to focus more on deeper/harder application-specific and economic vulnerabilities. CARE helps smart contract security "shift-left" which is widely regarded as significantly improving security posture and outcome. 7 | 8 | CARE reviews are performed by "CAREtakers" which includes a Secureum representative (who has a proven track-record of smart contract security expertise/experience) along with invited participants who are top-performing members of the Secureum community and aspiring smart contract security experts. They are invited based on their performance in Secureum RACEs. 9 | -------------------------------------------------------------------------------- /src/care/reports.md: -------------------------------------------------------------------------------- 1 | # CARE Reports 2 | 3 | These are the reports of the CAREs conducted by Secureum. 4 | _(You can also find them in the [Secureum CARE repository](https://github.com/secureum/CARE))_ 5 | 6 | ## December 2021 7 | 8 | - [Primitive](https://github.com/secureum/CARE/blob/main/Primitive-12-2021.pdf) 9 | - [Sherlock](https://github.com/secureum/CARE/blob/main/Sherlock-12-2021.pdf) 10 | - [Sushi](https://github.com/secureum/CARE/blob/main/Sushi-12-2021.pdf) 11 | - [Tracer](https://github.com/secureum/CARE/blob/main/Tracer-12-2021.pdf) 12 | -------------------------------------------------------------------------------- /src/ctfs/README.md: -------------------------------------------------------------------------------- 1 | # Secureum A-MAZE-X CTFs 2 | 3 | A-MAZE-X are a series of CTFs that are designed to help participants learn about smart contract security and the Ethereum ecosystem. 4 | 5 | These CTFs consisted of a series of smart contracts written where the participants had to find vulnerabilities in the contracts and exploit them to get the flag. The participants were given some background information regarding common smart contract vulnerabilities and a set of hints to help them complete the challenges. 6 | 7 | For now, there exist 3 A-MAZE-X Workshops: 8 | 1. [Secureum A-MAZE-X]() held as part of the [Activate X Wormhole Hackathon](https://www.activate.build/miami) held at [Miami Dade College](https://www.mdc.edu/), Florida, USA on 18-22 May 2021. 9 | 2. [Secureum A-MAZE-X Stanford](https://github.com/secureum/DeFi-Security-Summit-Stanford) held as part of the DeFi Security 101 pre-course for [DeFi Security Summit 2023](https://defisecuritysummit.org/defi-security-101/) held at [Stanford University](https://www.stanford.edu/), California, USA on 26-29 August 2022. 10 | 3. [Secureum A-MAZE-X Maison de la Chimie](https://github.com/secureum/AMAZEX-DSS-PARIS) held as part of the DeFi Security 101 pre-course for [DeFi Security Summit 2023](https://defisecuritysummit.org/defi-security-101/) held at [Foundation Maison de la Chimie](https://maisondelachimie.com/), Paris, France on 2-5 September 2023. 11 | 12 |
13 | A-MAZE-X Sections 14 | 15 |
-------------------------------------------------------------------------------- /src/img/A-MAZE-X-Maison-de-la-Chimie.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secureum/Secureum-Book/0b99c94848baa99dfc1e226c01a94289958574ec/src/img/A-MAZE-X-Maison-de-la-Chimie.png -------------------------------------------------------------------------------- /src/img/A-MAZE-X-Stanford.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secureum/Secureum-Book/0b99c94848baa99dfc1e226c01a94289958574ec/src/img/A-MAZE-X-Stanford.png -------------------------------------------------------------------------------- /src/img/Merkle_Tree (1).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secureum/Secureum-Book/0b99c94848baa99dfc1e226c01a94289958574ec/src/img/Merkle_Tree (1).png -------------------------------------------------------------------------------- /src/img/Merkle_Tree.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secureum/Secureum-Book/0b99c94848baa99dfc1e226c01a94289958574ec/src/img/Merkle_Tree.png -------------------------------------------------------------------------------- /src/img/Patricia_Tree.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secureum/Secureum-Book/0b99c94848baa99dfc1e226c01a94289958574ec/src/img/Patricia_Tree.png -------------------------------------------------------------------------------- /src/img/amazeXlogo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secureum/Secureum-Book/0b99c94848baa99dfc1e226c01a94289958574ec/src/img/amazeXlogo.png -------------------------------------------------------------------------------- /src/img/secureum-banner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secureum/Secureum-Book/0b99c94848baa99dfc1e226c01a94289958574ec/src/img/secureum-banner.png -------------------------------------------------------------------------------- /src/learn/1.Ethereum_Basics/1.11_Contract_Creation.md: -------------------------------------------------------------------------------- 1 | # Contract Creation 2 | 3 | We mentioned that a transaction can result in contract creation. 4 | 5 | The creation transaction is a special one because it's sent to a special destination address called "_the zero address_" (`0x0` address), which is an address that has zero in all its bits. This zero address is treated in a special maner within Ethereum, and it becomes critical to some of the smart contract security properties. 6 | 7 | It contains a data payload which represents the byte code of the contract that is being created, and it may also contain an optional Ether amount in the value field, in which case the new contract that is being created, will have a starting balance equal to this Ether value. -------------------------------------------------------------------------------- /src/learn/1.Ethereum_Basics/1.14_Transaction_Reverts_and_Data.md: -------------------------------------------------------------------------------- 1 | # Transaction Reverts & Data 2 | 3 | ## Reverts 4 | 5 | A transaction can revert for different exceptional conditions: 6 | 7 | * The transaction could run out of Gas depending on how much was supplied as part of it and what that transaction actually needs when it is executing. 8 | * The transaction could also revert because of invalid instructions that are encountered as part of executing the smart contract. 9 | 10 | When the transaction gets reverted, all the state changes made in the context of the EVM so far from all the previous instructions in the contract are discarded, and the original state before the transaction started executing is restored. It is as if the transaction never executed from the perspective of the EVM state. 11 | 12 | ## Data 13 | 14 | Recall that the data field within a transaction is relevant when the recipient of said transaction is a contract account. In that case, the transaction data contains two components: 15 | 16 | * It has to specify the function of that contract that is being invoked and... 17 | * If that function requires any arguments, then it needs to specify those as well 18 | 19 | All this is encoded according to the **Application Binary Interface (ABI)**: it's the contract's interface that's specified in a standard way, so that contracts can interact with each other. This is critical for contracts to interact both from outside the blockchain (when a transaction is triggered targeting a destination contract) but also for messages that are sent between two or more contracts within the EVM context. 20 | 21 | These interface functions that are specified as part of the ABI are strongly typed, are known at compilation time and they are static: the types of the function parameters are well known at compile time and they cannot change, because if they did, then what is specified as part of the contract call during execution will not reflect to what the destination contract requires in terms of the function encoding, or in terms of the arguments that are supplied. 22 | 23 | * So, **how does a callee contract specify the function to be invoked on the destination contract**?\ 24 | 25 | 26 | It does that through the **function selector**. The way that it is specified is by taking the function signature (of the function that needs to be invoked), running that through a Keccak-256 hash and taking the first four bytes of the output hash. 27 | * How is this function signature calculated from the function declaration?\ 28 | 29 | 30 | The function name is taken and appended with the parenthesized list of the parameter types that it accepts. These parameter types are specified one after another, with the comma being the delimiter.\ 31 | 32 | 33 | Note that there are no spaces used (this is something that is enforced as part of the ABI and it's a standard, because if different contracts use different notations for function signatures, then you can imagine that when a transaction triggers a contract and sends the function selector, the receiving contract will not know which function to execute).\ 34 | 35 | 36 | So everyone has to know what the format is. This allows the EVM to function in a very deterministic manner.\ 37 | 38 | 39 | Besides the function selector we have the function arguments that are also part of the transaction data (like we just discussed). These are encoded as well immediately following the four bytes of function selector: they span from the fifth byte onwards and go on depending on the number of arguments that the particular function needs. 40 | -------------------------------------------------------------------------------- /src/learn/1.Ethereum_Basics/1.15_Block_Explorer.md: -------------------------------------------------------------------------------- 1 | # Block Explorer 2 | If we want to take a look at what has happened in the past in terms of the transactions on Ethereum, the contracts that they interacted with, then the application that allows us to look at all this data is what is known as a block explorer: it lets us **explore the various blocks and their contents on the blockchain**. 3 | 4 | It's implemented as an application, a web portal if you will, and it gives us real-time on-chain data about all the transactions, the blocks, the Gas and everything that we have discussed so far. All this rich information is available in a transparent manner on the blockchain and can be accessed by everyone via this block explorer application. 5 | 6 | In the case of Ethereum we have several block explorers. The most popular one is [Etherscan](https://etherscan.io/). 7 | We also have [Etherchain](https://etherchain.org/), [Ethplorer](https://ethplorer.io/), [Blockchair](https://blockchair.com/) or [Blockscout](https://blockscout.com/). -------------------------------------------------------------------------------- /src/learn/1.Ethereum_Basics/1.16_Mainnet_and_Testnets.md: -------------------------------------------------------------------------------- 1 | # Mainnet and Testnets 2 | 3 | Mainnet refers to the main Ethereum network. There is a distinction because there also exist several testnets. These testnets are test Ethereum networks where protocol and smart contract developers can test their protocol upgrades and smart contracts prior to final deployment in mainnet. 4 | 5 | While mainnet uses real Ether, testnets use what is known as "_test Ether_'', so that you can simulate the Gas, the transfer of value and so on... These test Ether can be obtained from faucets. 6 | 7 | Some of the popular Ethereum testnets are **Goerli** (a proof of authority testnet that allows one to look at a lot of the Ethereum concepts and test them as if they are happening on mainnet). This particular testnet works across all the clients.It's called proof of authority because there are a small number of nodes that are allowed to create the blocks and validate them. After the Ropsten testnet reached a Terminal Total Difficulty (TTD) of $$5\times 10^{16}$$, the Goerli testnet transitioned to a proof-of-stake consensus mechanism to mimic Ethereum mainnet. 8 | 9 | Then we have the **Kovan** testnet, which is again a proof of authority testnet specifically for those running OpenEthereum clients. 10 | 11 | There is also the **Sepolia** Testnet. Sepolia was a proof-of-authority testnet created in October 2021. Similarly to Goerli, after the Ropsten testnet reached a Terminal Total Difficulty (TTD) of $$5\times 10^{16}$$, the Sepolia testnet transitioned to a proof-of-stake consensus mechanism. Sepolia was designed to simulate harsh network conditions, and has shorter block times, which enable faster transaction confirmation times and feedback for developers. Compared to other testnets like Goerli, Sepolia's total number of testnet tokens is uncapped, which means it is less likely that developers using Sepolia will face testnet token scarcity like Goerli. 12 | 13 | As you can see, these testnets are also evolving, new ones are being added over time trying to make it as easy as possible for the developers to simulate the real mainnet Ethereum blockchain and all its dependencies. This again becomes very critical to security because **testing is fundamental**: if you do not test, or if the testing environment is not very similar to the production environment, then the assumptions (the dependencies and other aspects that are tested) will be very different from what happens when you deploy the contract, which could end up causing a lot of security issues. 14 | 15 | ## Deprecated testnets 16 | 17 | Testnets are also removed over time. Some of the deprecated testnets are 18 | 19 | - **Rinkeby** testnet. It was a proof of authority based testnet which was specifically for the Geth clients. It shut down in 2023. 20 | - **Ropsten** testnet. It was a proof of work testnet. It shut down at the end of 2022. 21 | 22 | -------------------------------------------------------------------------------- /src/learn/1.Ethereum_Basics/1.17_EIPs_and_ERCs.md: -------------------------------------------------------------------------------- 1 | # EIPs & ERCs 2 | 3 | ## EIPs 4 | 5 | EIP stands for **Ethereum Improvement Proposal**: proposals put forward by researchers, developers and/or community members in the Ethereum ecosystem to make changes to different aspects of the Ethereum protocol. 6 | 7 | There's a very well defined specific process for EIP from the time somebody proposes one to the way it is discussed, debated, voted upon and finally made it into a standard or a specification. 8 | 9 | Depending on the different layers of the Ethereum protocol, the proposal targetting these could be either addressing the core aspects of the protocol, the networking aspects, the interface or some of the token standards. 10 | 11 | ## ERCs 12 | 13 | ERC stands for **Ethereum Request for Comments**. It has (sort of) become the used term for token standards. For example you have probably heard about ERC20 token standard or ERC721 token standard and so on... These are being created as part of the EIP process. 14 | 15 | There are also some meta and informational EIPs that don't address the protocol as such, but that address some of the governance aspects of this whole ecosystem, the process and so on... They also address some of the informational aspects of how these standards and specifications are written and distributed within the community. -------------------------------------------------------------------------------- /src/learn/1.Ethereum_Basics/1.18_Legal_Aspects_in_web3.md: -------------------------------------------------------------------------------- 1 | # Legal Aspects in web3: Pseudonymity & DAOs 2 | 3 | When it comes to legal and regulatury aspects of **who is responsible**, **what** are they responsible for **if something goes wrong**, everything changes dramatically in the web3 space compared to web2. 4 | 5 | One of the things is the **pseudonymity** or **who** is the team behind a particular project. There is an increasing trend towards some of the people involved in the projects being pseudonymous. This could be because of the regulatory uncertainty regarding cryptocurrencies (or crypto space in general), or also be because of the legal implications thereof. 6 | 7 | This changes the way we think about reputation and trustworthiness when it comes to applications, projects or products. It also affects the legal or social accountability when it comes to projects: who is responsible, who is accountable if the team is pseudonymous, how do you even know what what they're doing with the project, with the governance and so on... There's this concept of trusting software and not wetware, which is great but there are still social processes where people are involved to a great extent around building the project, rolling it out and the governance of the projects that has a huge implication towards the security posture. 8 | 9 | ## DAOs 10 | 11 | **DAO**s (**Decentralized Autonomous Organizations**) stem from the trust minimization and censorship resistance aspects of web3. Their objective is to minimize the role and the influence of centralized parties, or a few privileged individuals, in the life cycle of the projects. This means that the project ultimately evolves or aspires to be governed by a DAO, which can be comprised of a **community of token holders for that particular project**. They make voting based decisions on how the project treasury should be spent, what the protocol changes should be and, in some of the cases, all these are decided on-chain and affected on-chain as well. 12 | 13 | While this reduces the centralized points of wetware failure, as we call it, it also slows down decision making on a lot of the security critical aspects: imagine if there were vulnerabilities to be found in a deployed contract, and somebody had to create a fix and deploy the fix. If that had to go through a DAO for the decision making, you would have to give a certain amount of time for the token holders to vote for that decision. 14 | 15 | A centralized party entity in the web2 space can make this decision immediately, unilaterally and deploy that fix in a few hours, if not less. In web3 (i.e. DAOs), the decision making is decentralized and has that downside. -------------------------------------------------------------------------------- /src/learn/1.Ethereum_Basics/1.20_web2_timescales_vs_web3_timescales.md: -------------------------------------------------------------------------------- 1 | # web2 Timescales vs. web3 timescales 2 | 3 | The timescale of innovation in web2, although it is seemingly fast (exponential in some ways: smartphones in just 15 years, PCs, Moore's law...), those timescales are really long when you compare that to the compressed timescales of innovation that happen in the web3 world and specifically Ethereum, which again is driven by a lot of these interrelated concepts we talked about: everything being open source by design, composable, permissionless and borderless. Plus combine that with the mechanism design where a lot of this is incentivized by tokenomics. 4 | 5 | As a side effect, unfortunately, security has in some sense taken a back seat: it hasn't been really thought of as much as it should be in the design and development of a lot of these smart contracts (and hence, the applications they support). This was what contributed to a lot of the vulnerabilities we have seen within smart contracts or web3 applications, which led to exploits causing losses of millions or tens of millions of dollars overnight in a fraction of a second within a few transactions. 6 | 7 | And remember this is all irreversible: all these aspects of pseudonymous teams in some cases, the presenting threat model, the use of keys, the use of tokens, the lack of any centralized third party that can reverse the negative side effects of some of these exploits... All these interrelated concepts affect the security aspects of Ethereum and web3 in general. -------------------------------------------------------------------------------- /src/learn/1.Ethereum_Basics/1.3_Ethereum_vs_Bitcoin.md: -------------------------------------------------------------------------------- 1 | # Ethereum vs. Bitcoin 2 | 3 | * **How does Ethereum compare to bitcoin as a blockchain?**\ 4 | 5 | 6 | **Bitcoin** (the blockchain) came about in 2008/2009 and it focused by design on the ownership of Bitcoin (the cryptocurrency). The consensus of the blockchain (all the operations, states, state transitions...) exclusively focuses on the **ownership of these coins**, and nothing else. So all these state transitions track the transfer of Bitcoin (cryptocurrency) and, in the case of the Bitcoin blockchain, they're referred to as **UTXO**s (Unspent Transaction Outputs).\ 7 | 8 | 9 | Compared to that, the **Ethereum** blockchain by design focuses on general purpose states (states that do not only focus on the ownership of Ether but anything that can be encoded with the EVM general purpose programming language). So we are looking at a general purpose blockchain that can encodes arbitrary states and arbitrary rules for the state transitions, which tracks not only the state of Ether cryptocurrency ownership on the platform but the state of the different smart contracts as transactions interact with them.\ 10 | 11 | 12 | **That is the key difference between Ethereum and Bitcoin: Bitcoin is UTXO based and Ethereum is state based (or account based)**.\ 13 | 14 | * **How does the programming language on Ethereum compare to what's available on Bitcoin?** 15 | 16 | **Bitcoin** has what is known as `bitcoin script`: it is a **scripting language** (so it's intentionally and by design limited) that allows an evaluation of spending conditions that yield `true` or `false` boolean outputs, which is what is required for Bitcoin (and what it's supposed to do).\ 17 | 18 | 19 | But when you look at **Ethereum**, it supports a virtual machine known as **Ethereum Virtual Machine** (EVM), and by design it is meant to be a **general purpose programming language**. Remember it's **Turing complete** (which is a key differentiating feature of Ethereum's expressiveness power when compared to Bitcoin). 20 | -------------------------------------------------------------------------------- /src/learn/1.Ethereum_Basics/1.7_Decentralization.md: -------------------------------------------------------------------------------- 1 | # Decentralization 2 | 3 | - **What does decentralization really mean?** 4 | 5 | This term is used very casually although it has huge implications to how we think about security, even for smart contracts. There is a definition put forth by Vitalik in his article on decentralization. There are three types of decentralization: 6 | 7 | * **Architectural decentralization**: it refers to the hardware (the physical computers); who runs them, owns them, who is managing them, who can start them and stop them. This can be done in a decentralized fashion or not. 8 | * **Political decentralization**: it refers to the people behind the hardware or what is commonly referred to as "_wet ware_". Who are the individuals or the organizations who control the hardware or the infrastructure? Is it just one individual or is it a group of individuals? Are the colluding or are they independent and decentralized? 9 | 10 | * **Logical decentralization**: it refers to the software: used to build out the applications (the framework itself, the Ethereum code, the protocol itself, the data structures in it, the smart contracts or any other software that runs in that stack). Is that decentralized? Is it a monolithic entity that cannot be split apart and used in a decentralized fashion? 11 | 12 | All of these have security implications. -------------------------------------------------------------------------------- /src/learn/1.Ethereum_Basics/1.9_Ethereum_State_and_Account_Types.md: -------------------------------------------------------------------------------- 1 | # Ethereum State & Account Types 2 | 3 | Ethereum state is a mapping from the address of the Ethereum accounts to the state contained within it as a data structure. It is implemented as a **Modified Merkle-Patricia Tree**: a combination of a Merkle tree and a Patricia tree with some changes that are specific to Ethereum. 4 | 5 | Each of the Ethereum accounts has a unique 20 byte address associated with it, which is used by accounts to "talk to each other". Addresses are critical to how messaging works within the Ethereum protocol and how the accounts engage in transfer of value or information, since accounts need to be able to refer to each other using their addresses. 6 | 7 | In addition, accounts have four fields: 8 | 9 | * `nonce`: a counter that's used to make sure that each transaction can only be processed once used to prevent replay attacks. 10 | * `balance`: a number representing the amount of Ether that the account has at any point in time. 11 | * `code`: the smart contract code (absent in Externally Owned Accounts). 12 | * `storage`: the associated smart contract storage (absent in Externally Owned Accounts). 13 | 14 | ## Account types 15 | 16 | Ethereum has two account types: 17 | 18 | * **Externally Owned Account (EOA)**: it is an account that is controlled by a private key.\ 19 | 20 | 21 | Anyone who has a private key can create a digital signature that can be used to control the Ether that is present in an EOA. These signatures can be used to sign transactions from the EOA, which in turn can trigger messages from the EOA to other accounts.\ 22 | 23 | 24 | These messages can result in a transfer of value or they can trigger smart contracts. An EOA does not have any associated code or storage. 25 | * **Contract account**: it is an account that is controlled by the code that is contained within that account.\ 26 | 27 | 28 | Unlike EOAs, contract accounts have an associated smart contract code and storage. Whenever the contract account receives a message, it triggers the code present and accesses any internal storage associated with it. When the code runs it can send messages to other accounts or even create new contracts. 29 | 30 | In this sense, smart contracts can be thought of autonomous agents as they're always present in the execution environment of the Ethereum blockchain. They're always ready to be triggered by a transaction or a message that is sent to them. 31 | 32 | Through their contract account they have access to the Ether balance and the contract storage. The execution of the code results in manipulation of this balance and the contract storage. 33 | -------------------------------------------------------------------------------- /src/learn/1.Ethereum_Basics/1_Ethereum_Basics.md: -------------------------------------------------------------------------------- 1 | # 🔷 1. Ethereum Basics 2 | 3 | This section is a high level overview of what Ethereum is. It is based on the following content: 4 | 5 | * [**Secureum's Ethereum 101 keypoints**](https://secureum.substack.com/p/ethereum-101) 6 | * **Secureum's Ethereum 101** YouTube videos: 7 | * [Block 1](https://www.youtube.com/watch?v=44qhIBMGMoM) 8 | * [Block 2](https://www.youtube.com/watch?v=zIeBfuXxuWs) 9 | * [Block 3](https://www.youtube.com/watch?v=ltvTIr4K63s) 10 | * [Block 4](https://www.youtube.com/watch?v=MFoxW07ICKs) 11 | * [Block 5](https://www.youtube.com/watch?v=I-TjCtjDs1M) 12 | * **Mastering Ethereum Book** 13 | -------------------------------------------------------------------------------- /src/learn/2.Solidity/2.10_Solidity_Typing.md: -------------------------------------------------------------------------------- 1 | # `Solidity` Typing 2 | 3 | `Solidity` is a **statically typed** language, which means that the type of the variables used within the contracts written in `Solidity` needs to be specified in the code explicitly at compile time. This applies both to state variables and local variables. 4 | 5 | Statically typed languages perform what is known as **compile time type checking** according to the language rules. So when variables of different types are assigned to each other at compile time, the language can enforce that the types are used correctly across all these assignments and usages. Many of the programming languages that you may be familiar with such as `C`, `C++`, `Java`, `Rust`, `Go` or `Scala` are statically typed languages. From a security perspective, the type checking is a critical part and helps in improving the security of the contracts. 6 | 7 | ## Types 8 | `Solidity` has two categories of types: 9 | 10 | - **value**: they're always passed by value, which means that whenever they are used as function arguments or in assignments of expressions, they are always copied from one location to the other. 11 | - **reference**: they can be modified via multiple names all of which point to or reference the same underlying variable (i.e. the same memory address; this is easier to understand when it is thought like the concept of pointers). 12 | 13 | From a security perspective you can imagine that this becomes important because it affects which state is being updated and what those transitions are in the states as affected by the transactions. 14 | 15 | ### Value Types 16 | 17 | As discussed value type is one of the two types in `Solidity` where variables of these value types are passed by value (which means they are copied when used as function arguments or in assignments of expressions). 18 | 19 | There are different value types in `Solidity`: booleans, integers, fixed point numbers, address, contract, fixed size byte arrays, literals, enums and functions themselves. 20 | 21 | From a security perspective, value types can be thought of as being somewhat safer because a copy of that variable is made so that the original value of the original state itself is not modified accidentally. But then one should also check that any assumptions around the persistence of the values is being considered properly, so this will become clearer once we talk about the reference types and once we look at some of the security aspects. 22 | 23 | ### Reference Types 24 | 25 | In contrast to value types, reference types are passed by reference: there can be multiple names for the variable, all pointing to the same underlying variable state. There are 3 reference types in `Solidity`: **arrays**, **structs** and **mappings**. 26 | 27 | From a security perspective, reference types can perhaps be considered a little more riskier than value types because now you have multiple names pointing to the same underlying variable, which could, in some situations, lead to unintentional modification of the underlying state. -------------------------------------------------------------------------------- /src/learn/2.Solidity/2.13_Conversions.md: -------------------------------------------------------------------------------- 1 | # Conversions 2 | 3 | Every programming language that supports different types supports the concept of conversions, where variables of different types can be converted between each other. Conversions have been mentioned earlier, here we will dive deep into them. There are two types of these conversions. 4 | 5 | 6 | ## Implicit Conversions 7 | 8 | These conversions happen **implicitly**: the conversion is applied by the compiler itself. These typically happen where that conversion makes sense semantically and there is no information that is lost, so this is a very safe conversion applied by the compiler. Such conversions happen during assignments of variables when variables are passed as arguments to functions, and the parameter types of those functions are of a different type than the arguments applied (and in other contexts as well). 9 | 10 | Examples of implicit conversions in the case of `Solidity` are converting a `uint8` to `uint16` or `uint128` to `uint256` and so on, where the resulting type is bigger in the sense of the storage supported than the type that is being converted from. 11 | 12 | So `uint16` has 16 bits that can safely store `uint8`. However exceptions to implicit conversions are converting from signed integers to unsigned integers, and that doesn't make semantic sense because unsigned integers cannot hold or represent negative values. 13 | 14 | ## Explicit Conversions 15 | The flip side of implicit conversion are **explicit** conversions, where the type conversions are explicitly applied by the developers themselves and not by the compiler. The reason for that is the compiler cannot deduce or prove the type safety of such conversions and they may result in an unexpected behavior. 16 | 17 | There are various rules to such explicit conversions: in the case of integers when they are converted to a smaller type, the higher order bits are cut off when they are converted to a larger type they are padded on the left with the higher order end. 18 | 19 | So these apply for example when a `uint8` is converted to `uint16` the padding happens on to the left and when a `uint16` is converted to `uint8`, the higher order bits are cut off. Similarly for fixed size bytes, the `bytes` arrays or `bytes1` all the way to `bytes32`, converting to a smaller type cuts off bytes to the right and converting to a larger type will pad bytes to the right. 20 | 21 | So these rules are something that the developer has to pay attention to when forcing explicit conversions and if not done right, they could really result in undefined unexpected behavior, because the values underlying variables are chopped off in an unexpected fashion. 22 | 23 | ## Literals Conversions 24 | 25 | There are various rules that apply to these conversions. Decimals and hexadecimal number literals can be converted implicitly to any integer type that's large enough to represent it without getting it truncated. However decimal number literals cannot be implicitly converted to fixed size byte arrays. 26 | 27 | Hexadecimal number literals can be converted to fixed size byte arrays but only if the number of hex digits fits the size of the bytes type exactly, although there are some exceptions to this. As well string literals and hex string literals can be implicitly converted to fixed size bite arrays, but only if the number of characters matches the size of the `bytes` type. 28 | 29 | So these are various `Solidity` rules that need to be considered while converting literals and again it's something that you might encounter while analyzing smart contracts. 30 | -------------------------------------------------------------------------------- /src/learn/2.Solidity/2.14_Keywords_and_Shorthand_Operators.md: -------------------------------------------------------------------------------- 1 | # Keywords and Shorthand Operators 2 | 3 | ## Shorthand Operators 4 | 5 | These are concise notations of slightly longer expressions as shown here 6 | 7 | | Long expression | Shorthand notation | 8 | |-----------------|--------------------| 9 | | `a = a + e` | `a += e` | 10 | | `a = a - e` | `a -= e` | 11 | | `a = a*e` | `a *= e` | 12 | | `a = a/e` | `a /= e` | 13 | | `a = a%e` | `a %= e` | 14 | | `a = a\|e` | `a \|= e` | 15 | | `a = a&e` | `a &= e` | 16 | | `a = a^e` | `a ^= e` | 17 | 18 | Basically it consists on simplifying the expression of increments and decrements, where the result of the expression the value of a after the increment or decrement has been performed. 19 | 20 | ## Delete 21 | 22 | The `delete` keyword that can be used within smart contracts to reclaim the underlying storage of a variable when it is no longer required in in that context of the contract. Applying this keyword on a variable `a`, of a particular type, assigns the initial value for that type to `a`. 23 | 24 | So if it is applied on integers, then the value of that variable is set to 0, for arrays it assigns a length of 0. For dynamic arrays and for static arrays the length remains the same but all the elements are set to their initial value. 25 | 26 | `delete A[x]` where `A` is an array and `x` specifies a particular index, deletes the item at that index of that array and leaves all the other elements and even the length of that array intact. 27 | 28 | For structs, `delete` assigns a `struct` with all the members reset to their initial values. Delete has no effect on mappings, this is an exception that has to be paid attention to. So if you `delete` a struct which in turn has a mapping as one of its fields, then `delete` will reset all the members of that struct that are not mappings and will also recurse into each of those members unless they are mappings. But if you want to `delete` a particular `key` of that `mapping` then that is possible. 29 | 30 | ## Reserved Keywords 31 | 32 | These are keywords in `Solidity` that are reserved for future use, so they are not currently used by any of the syntax that is supported. These may be used for any anticipated new syntactic features within `Solidity`. 33 | 34 | There are many such reserved keywords, some of them are: `after`, `alias`, `apply`, `auto`, `case`, `null`, etc... 35 | 36 | You can imagine why these could potentially be reserved: because they all have a specific significance in the context of programming languages (especially object-oriented programming languages). `Solidity` anticipates that it may support features that may end up using these reserved keywords. 37 | 38 | An example of a keyword that was reserved earlier is `unchecked`, which is now used as of version `0.8.0` for declaring any block within `Solidity` as being unchecked for arithmetic overflow and underflow checks. So we can assume that some of these reserved keywords might be supported in future `Solidity` versions for different features. -------------------------------------------------------------------------------- /src/learn/2.Solidity/2.15_Solidity_Units.md: -------------------------------------------------------------------------------- 1 | # `Solidity` Units 2 | 3 | ## Ether Units 4 | 5 | Ether is $$18$$ decimals, the smallest unit is a wei. There are various names given for different numbers of weis: $$1$$ gwei $$= 10^9$$ wei, $$1$$ Ether $$= 10^{18}$$. 6 | 7 | In the case of the `Solidity` types, a literal number can be given a suffix of a wei, or a gwei (gigawei) or an Ether. These are used to specify sub denominations of Ether, as we see here, which are used when contracts want to manipulate different denominations of Ether in the context of the logic. 8 | 9 | ## Time Units 10 | 11 | As you can imagine contracts might want to work with different notions of time for various types of logic that they want to encode. `Solidity` supports different suffixes that represent time, and these can be applied to literal numbers and these suffixes are: `seconds`, `minutes`, `hours`, `days` and `weeks`. 12 | 13 | The base unit for time is `seconds`, so literally when 1 is used it is the same as representing `1 seconds`. The suffixes cannot be directly applied onto variables, so if you want to apply time units to certain variables, then one needs to multiply that variable with that time unit. 14 | 15 | So as an example shown, if we have a `daysafter` variable and we wanted to represent the number of days then we have to proceed like follows 16 | 17 | ```solidity 18 | daysafter * 1 days 19 | ``` 20 | 21 | That is the only way how Solidity allows one to use these units with variables. -------------------------------------------------------------------------------- /src/learn/2.Solidity/2.16_Block_and_Transaction_Properties.md: -------------------------------------------------------------------------------- 1 | # Block & Transaction Properties 2 | 3 | `Solidity` allows accessing various block and transaction properties within smart contracts. These allow developers to perform interesting logic that are dependent on different aspects of the current block or the transaction. 4 | 5 | ## Block 6 | 7 | In the case of `block`, we have the following members: 8 | 9 | - **`blockhash`**: gives the hash of the specified block, but only works for the most recent 256 ones, otherwise it returns zero. 10 | - **`chain id`**: gives the current id of the chain that this is executing on. 11 | - **`number`**: gives the sequence number of the block within the blockchain. 12 | - **`timestamp`**: gives the number of seconds since the unix epoch. 13 | - **`coinbase`**: it is controlled by the miner and gives the beneficiary address where the block rewards and transaction fees go to. 14 | - **`difficulty`**: block's difficulty related to the proof of work. 15 | - **`gaslimit`**: Gas limit for the block. 16 | 17 | ### Randomness Source 18 | 19 | **The block timestamp and block hash that we just discussed are not good sources of randomness**, that's because both these values can be influenced by the miners mining the blocks to some degree. The only aspects of timestamps that are guaranteed, is that the **current blocks timestamp must be strictly larger than the timestamp of the last block** and the other guarantee is that **it will be somewhere between the timestamps of two consecutive blocks in the canonical blockchain**. Therefore smart contract developers should not rely on either the block timestamp or the block hash as a source of good randomness. 20 | 21 | ### Message and Transaction 22 | 23 | There are also fields related to the message (`msg`): 24 | 25 | - **`value`**: represents the amount of Ether that was sent as part of the transaction. 26 | - **`data`**: gives access to the complete call data sent in this transaction. 27 | - **`sender`**: gives the sender of the current call or message. 28 | - **`signature`**: gives the function identifier or the first four bytes of the call data representing the function selector that we talked about earlier. 29 | 30 | The thing to be kept in mind is that every external call made, changes the `sender`. Every external call made can also change the `value`. 31 | 32 | So if we have three contracts `A`, `B` and `C` where `A` calls `B` and `B` calls `C`, in the context of the contract `B` the `msg.sender` is `A`, but in the context of the contract `C` the `msg.sender` is contract `b` and not `a`. 33 | 34 | These aspects should be kept in mind when analyzing the security of smart contract because the developers could have made incorrect assumptions about some of these that could result in security issues. 35 | 36 | Then there are transaction (`tx`) components: 37 | - **`gasprice`**: the Gas price used in the transaction. There is an interesting `Solidity` native function called **`gasleft()`** which returns the amount of Gas left in the transaction after all the computation so far.- **`origin`**: gives the sender of the transaction, representing the EOA. 38 | 39 | -------------------------------------------------------------------------------- /src/learn/2.Solidity/2.17_ABI_Encoding_and_Decoding.md: -------------------------------------------------------------------------------- 1 | # ABI Encoding/Decoding 2 | 3 | `Solidity` supports multiple functions in these categories. The obvious ones are the `abi.encode()` and `abi.decode()` functions that take arguments and encode them or decode them, specifically with respect to the ABI. 4 | 5 | There are also functions that encode with the function selector (`abi.encodeWithSelector()`) or with the signature (`abi.encodeWithSignature()`), and finally there is `abi.encodePacked()` which takes the arguments and performs the encoding in a packed fashion ( there's no padding applied between the arguments supplied). 6 | 7 | For this reason the packed encoding can be ambiguous. This is something that affects security when you're considering these functions, specifically this `abi.encodePacked()` function. -------------------------------------------------------------------------------- /src/learn/2.Solidity/2.19_Mathematical_and_Cryptographic_Functions.md: -------------------------------------------------------------------------------- 1 | # Mathematical & Cryptographic Functions 2 | 3 | Solidity supports the addition and multiplication operations with modulus: `addmod()` and `mulmod()`. 4 | 5 | It obviously supports the Keccak-256 hashing function that is fundamental to Ethereum and used extensively within Ethereum and smart contracts themselves. 6 | 7 | It also supports the standardized SHA-256 algorithm (related to Keccak-256), but the standardized version, it further supports one of the older hashing function, the ripe message digest `ripemd160(bytes memory)` for historical reasons. 8 | 9 | Finally it supports what is known as the `ecrecover` primitive. This is the elliptic curve recover function that takes in the hash of a message as an argument along with the signature components, the ECDSA signature components of `v`, `r` and `s`. `ecrecover` takes in these arguments and returns the address (or recovers the address) associated with the public key from the elliptic curve signature that is specified in the parameters. This is used in various smart contracts and it is used for different types of logic within them. 10 | 11 | ## `ecrecover` Malleability 12 | 13 | `ecrecover` is susceptible to malleability, or in other words **non-uniqueness**. In the context of signatures this means that a valid signature, can be converted into **a second valid signature without requiring knowledge of the private key** to generate those signatures. 14 | 15 | This, depending on how signatures are used within the contract logic, can result in replay attacks, where the second valid signature can be used by the user or even by the attacker to bypass the contract logic that is using these signatures. 16 | 17 | The reason for this malleability is the math behind how elliptic curve cryptography works, so the signature components of `v`, `r` and `s`. The `s` value can either be in the lower order range or in the higher order range, and `ecrecover` does not prevent the `s` value from being in one of these two ranges. This is what allows the malleability. 18 | 19 | If the smart contract logic using `ecrecover` requires the signatures to be unique, then currently the best practice is to use the ECDSA wrapper from OpenZeppelin, that enforces the `s` value to be in the lower range (it forces there to be a single valid signature for these signature components). -------------------------------------------------------------------------------- /src/learn/2.Solidity/2.1_Solidity_Influence_Features_and_Layout.md: -------------------------------------------------------------------------------- 1 | # Solidity: Influence, Features & Layout 2 | 3 | `Solidity` is a **high level language** specifically designed for writing smart contracts on Ethereum. It was proposed in 2014 by Gavin Wood and was later developed (and continues to be developed) by the Ethereum Foundation team led by Dr. Christian Reitwiessner, Alex Beregszsaszi and others. 4 | 5 | It targets the underlying EVM and is mainly influenced by `C++` (a lot of the syntax and object oriented programming), a bit from `Python` (the use of modifiers, multiple inheritance, C3 linearization and the use of the `super` keyword) and some of the early motivation was also from `Javascript` (things like function level scoping or the use of `var` keyword, although those influences have significantly been reduced since version `0.4.0`). 6 | 7 | One of the few alternatives to `Solidity` is `Vyper`: it's a language that is mostly based on `Python` and has just started to catch up with some of the high profile projects on Ethereum. However, to a great extent, due to the maturity of the language and the tool chains built around it, `Solidity` is by far the most widely used, so it becomes critical that in order to evaluate security of smart contracts we understand the syntax semantics, the pitfalls and various other aspects related to it. 8 | 9 | `Solidity` is known as a "_curly bracket language_" (it means that curly brackets are used to group together statements within a particular scope), it is also an object oriented language (so there exitsts the use of inheritance), statically typed (which means that the types of variables defined are static and defined at compile time), there is code modularity in the form of libraries and there are also user defined types. 10 | 11 | All these characteristics make `Solidity` a fully featured high level language that allows the definition of complex logic in smart contracts to leverage all the underlying features of the EVM. 12 | 13 | * **So, how does the physical layout of a smart contract written in `Solidity` look like?** 14 | 15 | This is important to the readability aspect of the file and the maintainability aspect of the smart contract in the context of the the project itself.\ 16 | 17 | 18 | A `Solidity` source file can contain an arbitrary number of various directives and primitives. These include the `pragma` and the `import` directives, the declarations of structs, enums and contract definitions. Every contract can itself contain structures, enums, state variables, events, errors, modifiers, constructor and various functions that define the various functionalities that are implemented by the smart contract. 19 | 20 | This physical layout is something that is specific to the syntax of `Solidity`. When it comes to helping with the readability or the maintainability, it is prime to layout all the components in the order mentioned. 21 | 22 | This is something that you will commonly see when you evaluate smart contracts in `Solidity`. There might be cases where some of these are out of order from what is considered as best practice, but it's still something to keep in mind. 23 | -------------------------------------------------------------------------------- /src/learn/2.Solidity/2.20_Control_Structures.md: -------------------------------------------------------------------------------- 1 | # Control Structures 2 | 3 | These are fundamental to any programming language because there is a control flow to the sequence of instructions specified in the high-level language that get translated into machine code by the compiler. 4 | 5 | In the case of `Solidity`, the control structures supported are `if`, `else`, `while`, `do`, `for`, `break`, `continue` and `return`. These are very similar to the ones found in any programming language. Although are some differences in `Solidity`: paranthesis for example cannot be omitted for conditionals that some of the other languages support, however curly braces can be omitted around single statement bodies for such conditionals. 6 | 7 | Also note that there is no type conversion from a non-boolean to a boolean type. As an example, `if(1)` is not allowed in `Solidity` because 1 is not convertible to the boolean `true`, which is supported by some of the other languages. 8 | 9 | So control structures play a critical role in the security analysis of smart contracts whether you're doing a manual review or whether you're writing a tool to pass the `Solidity` smart contract. These are some things to be understood really well because that's how control flows, and any analysis depends critically on making sure that the control flow is accurately followed and representative of what really happens at runtime. -------------------------------------------------------------------------------- /src/learn/2.Solidity/2.25_Inline_Assembly.md: -------------------------------------------------------------------------------- 1 | # Inline Assembly 2 | 3 | Inline assembly is a way to access the EVM features directly at a low level, and from a security perspective this is important because it bypasses some of the safety features provided by `Solidity` at a high level language. 4 | 5 | Type safety is one such aspect, so if a developer is manipulating in inline assembly, then the corresponding code does not enjoy the type safety benefits provided by the `Solidity` compiler. The language used by solution for inline assembly is called `Yul`. This is somewhat of a recent feature. 6 | 7 | There have been a lot of developments in the inline assembly support by `Solidity` in the most recent versions. This sees constant updates. As you look at the most recent versions of `Solidity`, an inline assembly block is marked using the keyword `assembly{...}`. The inline assembly code is placed within the curly braces, and is specified in `Yul`. 8 | 9 | ## Assembly Access 10 | 11 | `Yul` supports assembly access to various features such as the external variables, functions and libraries. Local variables of value type are directly usable in inline assembly, and local variables that refer to memory or calldata evaluate to the variable address and not the value itself, effectively serving as a reference. 12 | 13 | For local storage variables or state variables that are also allocated in the storage, a single `Yul` identifier is not sufficient, because remember that storage has a concept of packing, where multiple variables can share the same storage slot and therefore their address is in two parts: it refers to the slot and the offset within the slot. 14 | 15 | Assignments are possible to assembly language variables which allow rich manipulation of these variables within inline assembly. One should take care when manipulating in this aassembly language: one should remember that variables that point to memory or storage changed the pointer itself and not the data and, there are many other rules and restrictions as you can imagine when it comes to manipulating all these aspects within assembly as supported by `Yul`. 16 | 17 | ## `Yul` Syntax 18 | 19 | `Yul` supports literals and calls. there are variable declarations that are possible in the form of `let x : 7` which declares a new variable `x` and assigns an initial value of `7` to it. 20 | 21 | There are scoping blocks that are supported by `Yul`, so that multiple blocks can be considered within the assembly blocks. There is rich control flow that is supported using, `if`, `switch` and `for`. 22 | 23 | There are also function definitions that are supported by `Yul`, so that within inline assembly you can have multiple functions that help you modularize code. 24 | 25 | Take a look at the developments in the `Yul` language as supported by `Solidity`, this is happening at a great speed: there are a lot of features being added to provide a lot of richness and expressiveness by the `Yul` language for developers who want to code directly in assembly, but like mentioned before from a security perspective this becomes even more critical than programming in `Solidity` itself because inline assembly is typically considered as very close to the underlying virtual machine. 26 | 27 | So in this case, very close to the EVM and, if the internals of the EVM layout and all the nuances with respect to that are not paid attention to, then coding directly in `Yul` in `Solidity`'s assembly language might result in some serious bugs where the manipulations are not done correctly and corruption happens or maybe even vulnerabilities. -------------------------------------------------------------------------------- /src/learn/2.Solidity/2.3_Imports.md: -------------------------------------------------------------------------------- 1 | # Imports 2 | 3 | These `import` statements are similar to `Javascript`, where the format is 4 | 5 | ```solidity 6 | import ; 7 | ``` 8 | 9 | They help to modularize your code: split what might become a large monolithic code base into multiple components (modules) and import them wherever they are required. 10 | 11 | This helps developers to reuse code and, again, not only it affects the readability of code (compare a piece of monolithic code that is hundreds or thousands of lines versus modular code, where they're separated out into independent self-contained modules and used only when required), it also has implications to security and optimization as well. -------------------------------------------------------------------------------- /src/learn/2.Solidity/2.4_Comments_and_Natspec.md: -------------------------------------------------------------------------------- 1 | # Comments & NatSpec 2 | 3 | `Solidity` supports single line comments and multiline comments as shown here 4 | 5 | ```solidity 6 | // This is a single line comment 7 | /* This is a 8 | multiline 9 | comment */ 10 | ``` 11 | 12 | Comments are recommended to be used as inline documentation of what the contracts are supposed to do, what the functions, variables, expressions, various control and data flow expected to do as per the specification and what is really implemented. They can also be used to specify certain assumptions that the developer is making in the implementation and they can also represent some of the invariants that need to be maintained. 13 | 14 | Comments become a critical part of documentation that is included or encapsulated within the code itself, affect the readability of the code to a great extent and maintainability. In fact, comments become critical when we start talking about evaluating the security of smart contracts: comments give a lot of vital clues as to what the developer intended to implement or just information related to the various syntax or the semantics itself. 15 | 16 | `Solidity` also supports a special type of comment called **NatSpec** which stands for **Ethereum Natural Language Specification Format**. These are specialized comments that are specific to `Solidity` and `Ethereum`. They are written as follows 17 | 18 | ```solidity 19 | /// This is a single line NatSpec comment 20 | /** This is a 21 | multi line NatSpec comment */ 22 | ``` 23 | 24 | and are located directly above the function declaration or statements that are relevant to the **NatSpec**. These NatSpec comments come in many different types: there are many different tags such as 25 | 26 | - **`@title`**: describes the contract or the interface. 27 | - **`@author`**: specifies the developer (i.e. who is authoring the contract). 28 | - **`@notice`**: explains to an end user what the contract or function does. 29 | - **`@dev`**: directed towards the developer for any extra implementation related details. 30 | 31 | There are also specific tags related to function parameters (`@param`), the return variable (`@return`) and so on... These NatSpec comments are meant to automatically generate `JSON` documentation for both developers as well as users and provide a lot of valuable information that the developer intended for all these various aspects of parameters, returns, contracts and so on... They also form an important piece of the toolset that helps evaluate smart contract security. -------------------------------------------------------------------------------- /src/learn/2.Solidity/2.5_Smart_Contracts.md: -------------------------------------------------------------------------------- 1 | # Smart Contracts 2 | 3 | Smart contracts (or simply contracts) are fundamental to what Ethereum is all about. Conceptually, contracts are very similar to the concept of classes in object oriented programming and that's because they encapsulate a state in the form of variables, and logic that allow to modify that state in the form of functions. 4 | 5 | These contracts can inherit from other contracts, they can interact with other contracts and support a very rich environment where one can specify different types of interactions between these components. 6 | 7 | Contracts contain different components, including structures, enums, state variables, events, errors, modifiers, constructor and various functions. Some of these concepts should be familiar from other programming languages, but there are also some very Ethereum specific aspects, such as those related to state variables or events, or something that's specific to `Solidity` in the case of modifiers. 8 | 9 | Contracts can come in different types: they could be either **vanilla contracts**, **libraries** or even **interfaces**. -------------------------------------------------------------------------------- /src/learn/2.Solidity/2.7_Data_Location.md: -------------------------------------------------------------------------------- 1 | # Data Location 2 | 3 | We talked about value types and reference types. Reference types, which consist of structs, arrays and mappings in `Solidity` allow for a specification of their data location. This is an additional annotation and it indicates where that reference type variable is stored. 4 | 5 | There are three locations: **memory**, **storage** and **calle data**. Remember that these are 3 of the 4 locations that the EVM supports besides the stack. These data location affects the lifetime or the scope and persistence of the variables stored in those locations. 6 | 7 | * **Memory** indicates that the lifetime is limited to that external function call. 8 | * **Storage** indicates that the lifetime extends to that whole contract and this is also the location where state variables are stored. 9 | * **Call data** is a non-modifiable and non-persistent area where function arguments are stored. This is required for parameters of external functions but can also be used for other variables.\ 10 | 11 | 12 | This data location annotation impacts the scope of the variables that use this lotation. From a security perspective this affects the persistence of those variables. 13 | 14 | ## Assignments 15 | 16 | **The data location annotation** we just talked about not only **affects the persistency of those variables**, the scope in which they are relevant, but it also affects what are known as **assignment semantics**. 17 | 18 | In the context of `Solidity`, what this means is that during an assignment, using such variables is a copy of that variable being created? Or is simply a reference being created to the existing variable? 19 | 20 | In `Solidity`, storage to memory assignments always create an independent copy. Memory to memory assignments only create references. Similarly storage to storage assignments only create a reference. All other variants, create a copy. 21 | 22 | From a security perspective how this impacts the semantics is: if a copy were to be created because of these assignment rules, then any modifications to the copy affect only the copy and not the original variable from where it was copied. 23 | 24 | On the other hand, if a reference was created, in the case of memory to memory assignments or storage to storage assignments, then the new variable modifications to that affect the original variable because both of them are just different names pointing to the same underlying variable data (the same memory address on the machine). 25 | 26 | So this becomes important when you analyze programs and notice what the data locations are for those reference types, because there's a big difference if modifications are being made to the copy versus a reference. 27 | -------------------------------------------------------------------------------- /src/learn/2.Solidity/2.9_Events.md: -------------------------------------------------------------------------------- 1 | # Events 2 | 3 | Events are an abstraction that are built on top of the EVM's logging functionality. Emitting events cause the arguments that are supplied to them to be stored in what is known as the transactions log. This log is a special data structure in the blockchain associated with the address of the specific contract that created the event. This log stays there as long as that block is accessible. 4 | 5 | The log and its event data are not accessible from within the contracts, not even from the contract that created them. This is an interesting fact of logs in EVM: they're meant to be accessed off-chain and this is allowed using **RPC**s (**Remote Procedure Calls**). So applications, off-chain interfaces or monitoring tools can subscribe and listen to these events through the RPC interface of an Ethereum client. 6 | 7 | From a security perspective, these events play a very significant role when it comes to auditing and logging for off-chain tools to know what the state of a contract is and monitor the state along with all the transitions that happen due to the transactions. 8 | 9 | ## Indexed Parameters in Events 10 | 11 | Up to three parameters of every event can be specified as being indexed by using the `indexed` keyword. This causes those parameters to be stored in a special data structure known as topics instead of the data part of the log. Putting parameters into the topics part allows one to search and filter those topics in a very optimal manner. 12 | 13 | Parameters are commonly part of some of the specifications such as the `ERC20` token standard, and the events in that standard. These indexed parameters use a little more gas than the non-indexed one but they allow for faster search and query. 14 | 15 | ## Event Emission 16 | 17 | Events are triggered by using the `emit` keyword. Every contract would declare a certain set of events as relevant, and within the contract functions, wherever these events need to be created and stored in the log, they would be done so by using the `emit` keyword. An example would look like this 18 | 19 | ```solidity 20 | emit Deposit(msg.sender, _id, msg.value); 21 | ``` 22 | 23 | for the above example, let's say that we have a deposit event as part of a particular contract, and we have specific parts of functions where we would want to create this event and store them in the log. 24 | 25 | So, following the example above, we specify the event plus the arguments that are required according to the parameters of the event. These look in some way very similar to a function call, where the event corresponds to the function and the arguments that are supplied to it correspond to the event parameters. 26 | 27 | From a security perspective, it's critical for the contract and for the developers to emit the correct event and to use the correct parameters that are required by that event. 28 | 29 | This is something that is sometimes missed or not paid attention to because it's harder to be tested perhaps, and not critical to the control flow of the contract. 30 | 31 | But the only way for off-chain entities, any kind of user interfaces or monitoring tools to keep track of the contract state and the transitions is by looking at these event parameters stored in the logs. -------------------------------------------------------------------------------- /src/learn/2.Solidity/2_Solidity.md: -------------------------------------------------------------------------------- 1 | # 🌀 2. Solidity 2 | 3 | As mentioned in the previous chapter, `Solidity` is currently the most popular programming language used to develop smart contracts. In fact, it is so commonly used and there are so few alternatives to high-level languages on Ethereum, that it has become a fundamental pillar to smart contracts on Ethereum and therefore their security. 4 | 5 | This section is a high level overview of the `Solidity` EVM smart contract programming language. It is based on the following content: 6 | 7 | * [**Secureum's Solidity 101 keypoints**](https://secureum.substack.com/p/solidity-101) 8 | * [**Secureum's Solidity 201 keypoints**](https://secureum.substack.com/p/solidity-201) 9 | * **Secureum's Solidity 101** YouTube videos: 10 | * [Block 1](https://www.youtube.com/watch?v=5eLqFac5Tkg) 11 | * [Block 2](https://www.youtube.com/watch?v=TCl1IcGl\_3I) 12 | * [Block 3](https://www.youtube.com/watch?v=6VIJpze1jbU) 13 | * [Block 4](https://www.youtube.com/watch?v=WgU7KKKomMk) 14 | * [Block 5](https://www.youtube.com/watch?v=\_oN7XuyhoZA) 15 | * **Secureum's Solidity 201** YouTube videos: 16 | * [Block 1](https://www.youtube.com/watch?v=3bFgsmsQXrE) 17 | * [Block 2](https://www.youtube.com/watch?v=TqMIbouwePE) 18 | * [Block 3](https://www.youtube.com/watch?v=C0zBhTgppLQ) 19 | * [Block 4](https://www.youtube.com/watch?v=L\_9Fk6HRwpU) 20 | * [Block 5](https://www.youtube.com/watch?v=0kx8M4u5980) 21 | * [**`Solidity` language docs**](https://docs.soliditylang.org/en/latest/) 22 | -------------------------------------------------------------------------------- /src/learn/3.Security_Pitfalls_and_Best_Practices/3.10_Transaction_Order_Dependence.md: -------------------------------------------------------------------------------- 1 | # Transaction Order Dependence 2 | 3 | This security pitfall is related to **transaction order dependence** (TOD for short). Remember that in Ethereum transactions submitted by users sit in a data structure known as the `mempool` and get picked by the different miners for inclusion within blocks. 4 | 5 | The specific transactions that are picked, the specific order of those transactions included within the blocks depends on multiple factors and specifically the Gas Price of those transactions itself. 6 | 7 | So from an attacker's perspective one can monitor the `mempool` for interesting transactions that may be exploited by submitting transactions with a Gas Price appropriately chosen, so that the attackers transaction either executes right before or right after the interesting transaction. This is typically known as **Front-running** and **Back-running** and may lead to what are known as **Sandwich Attacks**. 8 | 9 | All these aspects are related to assumptions being made on the transaction being included in a specific order by the minor within a block. 10 | 11 | So from a security perspective logic within smart contracts should be evaluated to check, if transactions triggering that logic can be front run or background to exploit any aspect of it. 12 | 13 | ## ERC20 `approve()` Race Condition 14 | 15 | A classic example of transaction order dependence is the `approve()` functionality in the popular `ERC20` token standard. Remember that the `ERC20` token standard has the notion of an owner of a certain balance of those tokens and there's also the notion of a spender which is a different address that the owner of tokens can approve for a certain allowance amount which the spender is, then allowed to transfer. 16 | 17 | Let's take an example to see how the race condition works. Let's say that I am the owner of a certain number of tokens of an `ERC20` contract and I want to approve a particular spender with 100 tokens of allowance, so I go ahead and do that with an `approve(100)` transaction and later I change my mind and I want to reduce the allowance of the spender from 100 to 50. 18 | 19 | So I submit a second approve 50 transaction and, if that spender happens to be malicious or untrustworthy and monitors the `mempool` for this approval transaction, they would see that I'm reducing their approval to 50 by noticing the `approve(50)` transaction. 20 | 21 | In that case they can front run the reduction of approval transaction with a transaction that they send that spends the earlier approved hundred tokens. So that goes through first because of Front-running and when my `approve(50)` transaction goes through that, would give the spender an allowance of 50. 22 | 23 | Now the spender would further go ahead and spend those 50 tokens as well, so effectively instead of allowing the spender to spend only 50 tokens I have let them spend 150 tokens of mine, this is made possible because of transaction order dependence or Front-running. 24 | 25 | The mitigation to this the best practice recommended is to not use the `ERC20` `approve()` that is susceptible to this race-condition, but to instead use the `increaseAllowance()`, the `decreaseAllowance()` functions that are supported by such contracts. -------------------------------------------------------------------------------- /src/learn/3.Security_Pitfalls_and_Best_Practices/3.11_ecrecover.md: -------------------------------------------------------------------------------- 1 | # `ecrecover` 2 | 3 | This security pitfall is related to the use of the `ecrecover` primitive in EVM and supported by `Solidity`. 4 | 5 | The specific pitfall is that it is susceptible to what is known as signature malleability or non-unique signatures. Remember that elliptic curve signatures in Ethereum have three components `v`, `r` and `s`. The `ecrecover` function takes in a message hash the signature associated with that message hash and returns the Ethereum address that corresponds to the private key that was used to create that signature. 6 | 7 | In the context of this pitfall, if an attacker has access to one of these signatures, then they can create a second valid signature without having access to the private key to generate that signature. 8 | 9 | This is because of the specific range that the `s` value or the `s` component of that signature can be in it can be in an upper range or a lower range and both ranges are allowed by this primitive which results in the malleability. 10 | 11 | This depending on the logic of the smart contract, the context in which it is using these signatures can result in replay attacks, so the mitigation is to check that the `s` component is only in the lower range and not in the higher range, this mitigation is enforced in OpenZeppelin's `ECDSA` library which is the recommended best practice. -------------------------------------------------------------------------------- /src/learn/3.Security_Pitfalls_and_Best_Practices/3.13_Ether_Accounting.md: -------------------------------------------------------------------------------- 1 | # Ether Accounting 2 | 3 | ## Contract Balance 4 | 5 | This security pitfall is related to the Ether balance of a smart contract and how that can change unexpectedly outside the assumptions made by the developer. 6 | 7 | Remember that smart contracts can be created to begin with a specific Ether balance. Also there are also functions within the smart contract that can be specified as being payable, which means that they can receive Ether via message value. 8 | 9 | These two ways can be anticipated by the developer to change the Ether balance of the contract. But there are also other ways in which the Ether balance of the contract can change. 10 | 11 | One such way is the use of `coinbase` transactions. These are the beneficiary addresses used in the block headers where the miner typically specifies the address to which the block rewards and all the transaction Gas fees should go to. That `coinbase` address could point to a specific smart contract where all the rewards, the Gas fees go to, if that block is successfully included in the blockchain. 12 | 13 | The other unexpected way could be via the `selfdestruct` primitive where, if a particular smart contract is specified as the recipient address of `selfdestruct()`, then upon that executing the balance of the contract being destructed would be transferred to the specified recipient contract. 14 | 15 | So these two ways the `coinbase` and `selfdestruct` although very unusual and unexpected could in theory change the Ether balance of any smart contract, this could be well outside the assumptions made by the developer or the team behind the smart contract. 16 | 17 | So what this means is that, if the application logic implemented by a smart contract makes assumptions on the balance of Ether in this contract and how that can change, then those assumptions could become invalid because of these extreme situations in which it can be changed. So this is something to be paid attention to while analyzing the security for contract from the perspective of the Ether balance that it holds. 18 | 19 | ## `fallback` vs. `receive` 20 | 21 | This security consideration is related to the use of `fallback` and `receive` functions within a smart contract. 22 | 23 | Remember from our discussion in the `Solidity` modules, there are differences between these two functions, there are some similarities. These are related to the visibility, the mutability and **the way that Ether transfers are handled by these two different functions**. 24 | 25 | So from a security perspective, if these functions are used in a contract, then one should check that the assumptions are valid and if not, what are the implications thereof. 26 | 27 | ## Locked Ether 28 | 29 | Locked Ether refers to the situation where the contract has an Ether balance that gets locked because Ether can be sent to that contract via `payable` functions, but there's no way for users to withdraw that Ether from that contract (the contract contains no functionality to withdraw Ether). 30 | 31 | The obvious solutions are to remove the `payable` attributes from functions to prevent Ether from being deposited via them or adding withdrawal capabilities to the smart contract. The simple situations for this particular pitfall can be easily recognized and fixed. But also, there could be complex scenarios where the contract can be taken to a particular state (either accidentally or maliciously) where the Ether or the token balance of the contract gets locked and can't be withdrawn. -------------------------------------------------------------------------------- /src/learn/3.Security_Pitfalls_and_Best_Practices/3.14_Transaction_Checks.md: -------------------------------------------------------------------------------- 1 | # Transaction Checks 2 | 3 | ## `tx.origin` 4 | 5 | The use of `tx.origin` is considered dangerous in certain situations within smart contracts. Remember that in the context of Ethereum, `tx.origin` gives the address of the externally owned account that originated the transaction. 6 | 7 | If the `tx.origin` address is used for authorization, then it can be abused by attackers to launch replay attacks by coming in between the user and the smart contract of concern. 8 | 9 | This is sometimes known as "_man in the middle replay attack_" (or MITM as an abbreviation) because the attacker comes in between the user and the contract, captures the transaction and later replaces it. Because the smart contract uses `tx.origin`, it fails to recognize that this transaction actually was originated from the attacker in the middle. 10 | 11 | So in this case the recommended best practice for smart contracts using authorization is to use `msg.sender` instead of `tx.origin`, because `msg.sender` would give the address of the most recent or the closest entity. So in this case, if there is a man in the middle attacker, then `msg.sender` would give the address of the attacker and not that of the authorized user pointed to by `tx.origin`. 12 | 13 | ## Contract Check 14 | 15 | There may be situations where a particular smart contract may want to know, if the transaction or the call made to it is coming from a contract account or an externally owned account. 16 | 17 | There are two popular ways for determining that: 18 | 19 | 1. Checking if the code size of the account of the originating transaction is greater than zero and if this is not zero, it means that that account has code and therefore is a contract account. 20 | 2. Checking if the `msg.sender` is the same as the `tx.origin` and, if it is, then it means that the `msg.sender` is an externally owned account. 21 | 22 | Remember that `tx.origin` can only be an externally owned account in Ethereum as of now. 23 | 24 | So these two techniques have pros and cons and depending on the specific application it may make more sense to use one over the other. 25 | 26 | There are risks associated and implications thereof of either of these two approaches particularly with the code size approach the risk is that, if this check is made while a contract is still being constructed within the constructor the code size will still be zero for that account so, if we determine based on that aspect that this is an externally owned account, then it would be a wrong assumption. -------------------------------------------------------------------------------- /src/learn/3.Security_Pitfalls_and_Best_Practices/3.15_Delete_Mappings.md: -------------------------------------------------------------------------------- 1 | # `delete` Mappings 2 | 3 | The next security pitfall is related to the concept of the `delete` primitive and `Solidity` and how it applies to mappings. If there is a struct data structure in a smart contract that contains a mapping as one of its fields, then deleting that structure would `delete` all the fields of the struct, but the mapping field itself would remain intact, so this is one of the `Solidity`'s behaviors that needs to be kept in mind. 4 | 5 | That can have unintended consequences, if the developer assumes that the mapping field within the struct also got deleted and reinitialized to its default values. 6 | 7 | The best practice is to use an alternative approach such as considering the data structure that is meant to be deleted as being logged to prevent future logic from using the data structure or the mapping fields within that data structure. -------------------------------------------------------------------------------- /src/learn/3.Security_Pitfalls_and_Best_Practices/3.16_State_Modification.md: -------------------------------------------------------------------------------- 1 | # State Modification 2 | 3 | Contract state modifications made in functions whose mutability is declared as `view` or `pure` will revert in contracts compiled with `Solidity` version greater than or equal to `0.5.0`. 4 | 5 | This is because this compiler version started using the `STATICCALL` opcode for such functions, this instruction leads to a revert, if that particular function modifies the contract state. 6 | 7 | So when analyzing the security aspects of contracts it's good to pay attention to the mutability of the functions to see, if they are `view` or `pure`, but they actually modify the contract state in which case they would lead to reverts at runtime. -------------------------------------------------------------------------------- /src/learn/3.Security_Pitfalls_and_Best_Practices/3.17_Shadowing_and_Pre_Declaration.md: -------------------------------------------------------------------------------- 1 | # Shadowing and Pre-declaration 2 | 3 | ## Shadowing 4 | 5 | Shadowing of built-in `Solidity` variables was a concern in some of the older `Solidity` versions. Built-in variables such as `now`, `assert` and some others could be shadowed by other variables, functions or modifiers in the contract to override their behavior. 6 | 7 | This as you can imagine is dangerous and could lead to many unexpected behavior and therefore this Shadowing was disallowed in later `Solidity` versions. 8 | 9 | Similar to the Shadowing of built-in variables the older versions of `Solidity` also allowed state variable shadowing. 10 | 11 | This meant that the right contracts could have state variables that had the same name as some of their base contracts. You can imagine that the base variables and shadowed variables with the same names could be confusing even for the developer and they could end up using or modifying the wrong variable from the base contracts. 12 | 13 | This dangerous and unexpected consequences was recognized, so `Solidity` compiler `0.6.0` disallowed Shadowing of state variables. 14 | 15 | ## Pre-declaration 16 | 17 | Earlier versions of `Solidity` allowed the use of local variables even before they were declared. 18 | 19 | These variables could be declared later or they could have been declared in another scope. This led to undefined behavior as you may expect. 20 | 21 | `Solidity` version `0.5.0` and beyond change this, to implement the popular C99-style scoping rules where variables can only be used after they have been declared and only in the same or nested scopes. -------------------------------------------------------------------------------- /src/learn/3.Security_Pitfalls_and_Best_Practices/3.19_Events.md: -------------------------------------------------------------------------------- 1 | # Events 2 | 3 | Events should be emitted within smart contracts for all critical operations. Emission of events that are missing for such critical operations is a security concern. 4 | 5 | The reason for this is because it affects off-chain monitoring remember that events emitted from smart contracts end up storing the parameters of such events in the log part of the blockchain. 6 | 7 | These logs either the topics part or the data part can be queried by off-chain monitoring tools or off-chain interfaces to understand what is happening in the smart contracts. This is an easier way to understand the state of the smart contracts without having to query the contracts themselves. 8 | 9 | These events become very important from a transparency and user experience perspective. So the best practice is to recommend the addition of events in all places within the smart contracts where critical operations are happening, these could be updates to critical parameters from the smart contract applications perspective this could be operations that are being done only by the owner or privileged roles within the smart contract. So in all such cases events should be emitted to allow transparency and a better user experience. 10 | 11 | ## Event Parameters 12 | 13 | Having talked about events, let's now focus on the event parameters. Event parameters not being indexed may be a concern in certain situations. 14 | 15 | Remember that event parameters may be considered as either indexed or not depending on the use of the `indexed` keyword. This results in those parameters being stored either in the topics part of the log or the data part of the log. Being stored in the topics part of the log allows for those parameters to be accessed or queried faster due to the use of the bloom filter. If they're stored in the data part, then it results in a much slower access. 16 | 17 | There are certain parameters for certain events that are required to be indexed as per specifications. let's take the `ERC20` token standard for example: it has transfer and approval events that require some of their parameters to be indexed. 18 | 19 | Not doing it will result in the off-chain tools that are looking for such index events to be confused or thrown off track. 20 | 21 | So the best practice here is to add the `indexed` keyword to critical parameters in an event. Especially if the specification requires them to be in text, this comes at cost of some additional Gas usage, but allows for faster query. 22 | 23 | ## Event Signatures 24 | 25 | The concern here was that of incorrect event signature in libraries. The reason for this happening was because, if events used in libraries had parameters of contract types, then because of a compiler bug, the actual contract name was used to generate the signature hash instead of using their address type. 26 | 27 | This resulted in a wrong hash for such events being used in the logs. The mitigation here was to fix the compiler bug which happened in version `0.5.8` where the address type was used instead of using the contract name incorrectly. -------------------------------------------------------------------------------- /src/learn/3.Security_Pitfalls_and_Best_Practices/3.20_Typographical_Errors.md: -------------------------------------------------------------------------------- 1 | # Typographical Errors 2 | 3 | ## Unary Expressions 4 | 5 | Unary expressions are where an operator is used on a single operand as opposed to two operands, in which case it would be a binary expression. Such unary expressions are susceptible to typographical errors by developers. 6 | 7 | For example let's take a look at the scenario where there's a variable `x`. The developer wants to increment it by one, so the way to do that is to say `x += 1` which effectively is `x = x + 1`. But if the developer interchanges the order of `+` and `=` and instead uses `x = +1`, then this would result in re-initializing the value of `x` to `+1`. The reason for this is that `+ 1` is a unary expression whose value is `1` and `x` would get initialized to that value. 8 | 9 | As you can imagine such typographical errors are likely to be made by developers it's very easy to make these switching the order and, if they are considered as valid by the compiler, then it's very hard to notice such errors both by the developer as well as by the security auditor. 10 | 11 | So in order to prevent some of the most common usages that result in such typographical errors the unary `+` was deprecated as of compiler `Solidity` version `0.5.0`. 12 | 13 | ## Long Number Literals 14 | 15 | There is a security risk in the use of long number literals within `Solidity` contracts. These number literals may require many digits to represent their high values (as constants) or many decimal digits of precision, which as you can imagine is error prone. 16 | 17 | For example, if one were to define a variable representing Ether, then it would need to be assigned a number literal that has 18 zeros to represent the 18 decimals of precision. 18 | 19 | So the developer may accidentally use an extra zero or miss a zero in which case the Ether precision is different, thus the logic using this variable will be broken. 20 | 21 | The best practice here is to use the Ether or time suffixes supported by `Solidity` as applicable or to use the Scientific Notation which is also supported by `Solidity`. -------------------------------------------------------------------------------- /src/learn/3.Security_Pitfalls_and_Best_Practices/3.22_Assertions.md: -------------------------------------------------------------------------------- 1 | # Assertions 2 | 3 | ## `assert()` 4 | 5 | This security best practice is related to the use of `assert`s within smart contracts. `assert()` should be used only to check or verify program invariants within the smart contracts. They should not be used to make any state changes within their predicates and they should also not be used to validate any user inputs. 6 | 7 | The reason for this is because, if any state changes are made as the side-effects of the predicates within asserts, then those could be missed both by developers during maintenance or when they are trying to do any testing. 8 | 9 | They could also be missed by auditors because these state changes are not expected to happen within a search and similarly, asserts should not be used to validate user inputs because that should be done using `require()` statements. 10 | 11 | As a general rule we do not expect to see any failures from asserts during normal contract functioning and therefore these best practices become very relevant. 12 | 13 | ## `assert()` vs. `require()` 14 | 15 | This best practice is related to the use of `assert()` versus `require()` and the specific conditions in which they should be used. 16 | 17 | These two aspects are related, but they have different usages. 18 | 19 | `assert`s should be used to check or verify invariants where these invariants are expected to be held during normal contract functioning, so we do not expect any of these asserts to fail during the contract execution and any failures are critical `panic` errors that need to be caught and dealt with in a very serious manner. 20 | 21 | On the other hand `require()` is meant to be used for input validation of arguments that are supplied by users to various public or external functions where we do expect failures to happen because the user provided values may be the zero address in some cases or maybe values that are out-of-range or do not make sense from the smart contracts perspective. 22 | 23 | So this difference is something to be kept in mind, the best practice is to use `assert()` or `require()` appropriately as the situation demands. This had a more significant impact until `Solidity` compiler version `0.8.0`. Until then, `require()` used the `REVERT` opcode which refunded the remaining Gas and failure, whereas `assert` used the `INVALID` opcode which consumed all the supplied Gas. 24 | 25 | So until that version the usage of `assert()` or `require()` incorrectly, would result in different Gas semantics. This is because in one situation the remaining Gas would be refunded, whereas in the other case all of it would be consumed. 26 | 27 | So this affected user experience as well, but this has changed since version `0.8.0` where both `require()` and `assert()` use the `REVERT` opcode and refund all the remaining Gas on failures. -------------------------------------------------------------------------------- /src/learn/3.Security_Pitfalls_and_Best_Practices/3.23_Keywords.md: -------------------------------------------------------------------------------- 1 | # Keywords 2 | 3 | This security best practice is related to the use of duplicated keywords in `Solidity` over the different compiler versions. 4 | 5 | Different keywords have been deprecated to favor one over the other, so for example `msg.gas` has been deprecated to favor `msg.gasLeft`, `throw` has been deprecated to favor the use of `revert`, `sha3` for `keccak-256`, `callcode` for `delegatecall`, `constant` Keyword for `view`, the `var` Keyword for using the actual type name instead. 6 | 7 | So all such deprecated keywords they start initially as compiler warnings where the compiler wants us not to use these keywords and over the future versions these warnings could be converted into compiler errors in which case the compilation fails. 8 | 9 | So the best practice here is to simply avoid the use of deprecated keywords even if they are compiling warnings, because these warnings can become errors in the future compiler versions. -------------------------------------------------------------------------------- /src/learn/3.Security_Pitfalls_and_Best_Practices/3.24_Visibility.md: -------------------------------------------------------------------------------- 1 | # Visibility 2 | 3 | Remember that functions in `Solidity` have the notion of visibility where they could be either `public`, `external`, `internal` or `private`, this affects which users can call these functions. 4 | 5 | So `public` and `external` functions are callable by anyone depending on the access control that is enforced on top of that, whereas `internal` and `private` can be called only from within the contracts or the derived contracts. 6 | 7 | Until `Solidity` version `0.5.0` this visibility specifier was optional and they defaulted to `public`. This aspect led to vulnerabilities where the developer forgot to mention or specify the visibility in which case it became public by default and resulted in malicious users being able to call these functions and make unauthorized state changes completely unexpected by the developer or the smart partner. 8 | 9 | So this optional specification of function visibility defaulting to `public` visibility was removed as of `Solidity` version `0.5.2`, so this was a big change when it came to increasing the security of smart contracts and since that version function visibility is required to be specified explicitly for every function. 10 | 11 | ## Public Functions 12 | 13 | Remember that `Solidity` has the notion of visibility for functions, there are four visibility specifiers: `internal`, `private`, `public` and `external`. `public` functions consume more Gas than `external` functions. 14 | 15 | The reason for this is because the arguments of `public` functions need to be copied from thecall data component of the EVM to the memory component. This copying produces more bytecode for such `public` functions which therefore consumes more Gas. 16 | 17 | This copying is not required for `external` functions where their arguments can be left behind in the calldata component of the EVM. This key difference leads to `public` functions consuming more Gas than `external` functions in `Solidity`. 18 | 19 | So if there are functions in the contract that are never called from within the contracts themselves, then such functions should be declared with `external` visibility and not `public` visibility, which leads to better Gas efficiency. -------------------------------------------------------------------------------- /src/learn/3.Security_Pitfalls_and_Best_Practices/3.25_Inheritance.md: -------------------------------------------------------------------------------- 1 | # Inheritance 2 | 3 | Contracts that inherit from multiple contracts should be careful about the inheritance order because, if more than one such base contract defines an identical function, then the particular function implementation that gets included in the derived contract depends on this inheritance order. 4 | 5 | The best practice is for this inheritance order to be from the more general implementation to the more specific implementation. 6 | 7 | Another security pitfall related to inheritance is that of missing inheritance where a particular contract within an application might appear to inherit from another interface in that project or another abstract contract without actually doing so. 8 | 9 | And it might appear, because of the contract name that is similar to the abstract contract or the interface name or also because of the functions that are defined within this contract their names the parameter types and, so on. 10 | 11 | This appearance might give the notion that it is inheriting without actually inheriting. This affects not only the readability and maintainability aspects for the project team, but it also affects the auditability because the security reviewer might look at this contract and assume certain aspects, thinking that it's inheriting from the similarly named interface or abstract contract whereas in fact it does not do so. 12 | 13 | So the best practice here, is to make sure that the inheritance is done appropriately and, if there are similarly named contracts where they do not actually inherit from each other, then the name should be changed. But if they are in fact meant to be inherited, then specifying that inheritance will help. -------------------------------------------------------------------------------- /src/learn/3.Security_Pitfalls_and_Best_Practices/3.26_Reference_Parameters.md: -------------------------------------------------------------------------------- 1 | # Reference Parameters 2 | 3 | Remember that `Solidity` has value types and reference types. This security pitfall is related to the use of reference types in function parameters when structs, arrays or mappings, which are the reference types, are passed as arguments to a function. 4 | 5 | They may be passed by value or they may be passed by reference. This difference is dictated by the use of either the `memory` or the `storage` keyword that specifies their data location. This was optional before `Solidity` version `0.5.0`, but since that version it is required to be specified explicitly. 6 | 7 | This difference is critical from a security perspective, because passing by value, if you remember, makes a copy, so any changes to the copy does not affect the original value. But passing by reference, creates a pointer to the original variable, so any changes to the passed value is actually modifying the original variable itself. 8 | 9 | This, if not treated properly could lead to unexpected changes and modifications of the original variable or a copy which could have very different behavior and impact for the smart contract logic. 10 | -------------------------------------------------------------------------------- /src/learn/3.Security_Pitfalls_and_Best_Practices/3.27_Arbitrary_Jumps.md: -------------------------------------------------------------------------------- 1 | # Arbitrary Jumps 2 | 3 | Arbitrary jumps are possible within `Solidity`. `Solidity` supports many different types, one of which is a function type. These function type variables are not frequently encountered, but if they are, they can are mainly found within assembly code in making arbitrary manipulations to variables of these types. In that case, they could be used to change the control flow to switch to an arbitrary location in the code. This is something to be paid attention to and from a development perspective something to be avoided. 4 | 5 | Assembly in general is very tricky to use and it bypasses many security aspects of `Solidity` such as type safety, so it's best to avoid the use of assembly if possible and definitely to avoid the use of function type variables and making arbitrary changes to it. This is because that could result in changes to control flow that is unexpected by the developers or the smart contract auditors. 6 | -------------------------------------------------------------------------------- /src/learn/3.Security_Pitfalls_and_Best_Practices/3.29_Unicode_RTLO.md: -------------------------------------------------------------------------------- 1 | # Unicode RTLO 2 | 3 | There is a security pitfall that arises because of the use of the Unicode Right-to-Left-Override control character (`U+202E`) in `Solidity` smart contracts causes the text to be rendered from right to left instead of the usual left to right. 4 | 5 | This reverse rendering confuses the users as well as the security reviewers from understanding what the real intent is of that particular snippet of the smart contract. 6 | 7 | The best practice here is to ensure that such confusing Unicode characters (the RTLO control character) is not used within smart contracts at all. -------------------------------------------------------------------------------- /src/learn/3.Security_Pitfalls_and_Best_Practices/3.31_Pointers.md: -------------------------------------------------------------------------------- 1 | # Pointers 2 | 3 | ## Storage Pointers 4 | 5 | There is a security pitfall related to the use of uninitialized storage pointers. Local storage variables that are uninitialized can point to unexpected storage locations within the contract. 6 | 7 | This can lead to developers unintentionally modifying the contract state, which can lead to serious vulnerabilities. Given that this is so error-prone, `Solidity` compiler `0.5.0` started disallowing such pointers. 8 | 9 | ## Function Pointers 10 | 11 | There was a security risk in using uninitialized function pointers within constructors of contracts because of a compiler bug that resulted in unexpected behavior. 12 | 13 | This compiler bug was present in `Solidity` versions `0.4.5` to `0.4.26` and `0.5.0` to `0.5.7` and has since been fixed. -------------------------------------------------------------------------------- /src/learn/3.Security_Pitfalls_and_Best_Practices/3.32_Out_of_range_Enum.md: -------------------------------------------------------------------------------- 1 | # Out-of-range Enum 2 | 3 | Older versions of `Solidity` produced unexpected behavior with out-of-range enums. For example we had `enum E{a}` (with a single member `a`) as shown here, then `E(1)` is out-of-range because, remember, indexing of `enum` members begins with 0. 4 | 5 | So `E(1)` here is out-of-range because there's a single mapper. This out-of-range `enum` produced unexpected behavior in `Solidity < 0.4.5`. This was due to a compiler bug which has since been fixed. 6 | 7 | The best practice until the fix was applied was to check the use of `enums` to make sure they are not out-of-range. -------------------------------------------------------------------------------- /src/learn/3.Security_Pitfalls_and_Best_Practices/3.3_Modifiers.md: -------------------------------------------------------------------------------- 1 | # Modifiers 2 | 3 | ## Side-effects in Modifiers 4 | 5 | Modifiers in `Solidity` smart contracts are typically used to implement different kinds of security checks (for example access control checks), or accounting checks on fund balances and so on. Such modifiers should not have any side-effects, they should not be making any state changes to the contract or external calls to other contracts. 6 | 7 | The reason for that is any such side-effects made by the modifiers, may go unnoticed both by the developers as well as the smart contract security auditors evaluating the security of these contracts. 8 | 9 | They go unnoticed not only because developers and auditors assume that modifiers don't make side-effects, but also because the modified code is typically declared in a different location from the function implementation itself. Remember that the best practice is for the modifiers to be declared in the beginning of the contract and function implementations in the later part of the contract. 10 | 11 | So as a security check, one should make sure that modifiers declared in contract should not have any side-effects and they should be only enforcing checks on different aspects of the contract. 12 | 13 | ## Incorrect Modifiers 14 | 15 | Incorrect modifiers are a security risk. Modifiers should not only implement the correct access control or accounting checks as relevant to the smart contract logic, but they should also execute the code in "`_`" or revert along all the control flow paths within that modifier. Remember that in the context of `Solidity`, "`_`" inlines the function code on which the modifier is applied. 16 | 17 | So, if this does not happen along any particular control flow path within the modifier, then the default value for that function is return. 18 | 19 | This may be unexpected from the context of the caller who called this function on which this modifier is applied, so the security check is to make sure that all the control flow paths within the modifier either execute "`_`" or revert. -------------------------------------------------------------------------------- /src/learn/3.Security_Pitfalls_and_Best_Practices/3.41_Testing_Unused_and_Redundant_Code.md: -------------------------------------------------------------------------------- 1 | # Testing, Unused and Redundant Code 2 | 3 | ## Testing 4 | Software testing or validation is a fundamental software engineering practice that is a critical contributor to improved security. Testing validates whether the system implementation meets the requirements as detailed by the specification. Unit tests, functional tests, integration and end-to-end tests should have been performed to achieve good test coverage across the entire code base. 5 | 6 | - Changes introduced with any revisions should be validated with regression tests. 7 | - Smoke testing indicates at a high level if the functionality works or not. 8 | - Stress testing validates extreme scenarios with borderline cases to check if those have been considered correctly. 9 | - Performance and security specific testing validates those aspects respectively. 10 | 11 | Any code or parameterization used specifically for testing should be removed from production code, which in smart contracts may apply differently to testnets vs. mainnet. Leaving test parameters or configurations behind may accidentally allow their usage resulting in unexpected maintenance behavior or serious vulnerabilities, so overall we need to ensure that sufficient levels of testing have been performed across all these different categories we just mentioned. 12 | 13 | ## Unused Code 14 | 15 | Unused constructs may negatively impact security. This applies to any unused reports, inherited contracts, functions, parameters, variables, modifiers, events or return values; all of which should be removed or used appropriately after careful evaluation. 16 | 17 | Removing will not only reduce Gas costs, but also improve readability and maintainability of the code. Unused constructs may also be indicative of missing logic that may be a security concern, if that logic were to have implemented security related functionality, so one needs to either remove or use such unused constructs. 18 | 19 | ## Redundant Code 20 | 21 | Redundant constructs are also concerned. These are a kind of constructs that are not required either because there are equivalent constructs that implement the same functionality or because they are not relevant anymore. Such redundant code and comments can be confusing and should be removed or changed appropriately after careful evaluation. 22 | 23 | Similar to unused constructs, removing redundant constructs will not only reduce Gas costs but also improve readability and maintainability of the code. If redundant constructs are indicative of missing or incorrect logic, then they may be a security concern, if such logic were to have implemented security related functionality. So one needs to either remove such redundant constructs or make them relevant by adding or changing the corresponding logic. -------------------------------------------------------------------------------- /src/learn/3.Security_Pitfalls_and_Best_Practices/3.42_Handling_Ether.md: -------------------------------------------------------------------------------- 1 | # Handling Ether 2 | 3 | Let's now talk about another fundamental aspect of smart contracts and Ethereum which is the way they handle Ether. Contracts that accept, manage or transfer Ether should take care of several things. 4 | 5 | - They should ensure that functions handling Ether are using `msg.value` appropriately, remember that `msg.value` is a global variable in the context of a transaction which, for example when used or accounted multiple times (say inside loops) have led to critical vulnerabilities. 6 | - They should ensure that logic that depends on Ether value accounts for either less or more Ether set via `payable` functions. 7 | - Logic that depends on contract Ether balance, accounts for the different direct or indirect ways of receiving Ether such as `coinbase` transaction or `selfDestruct` recipient that we have discussed earlier. 8 | - Logic that handles withdrawal balance and transfers does so correctly in any accounting logic. 9 | - Transfers should be reentrancy safe. 10 | - Ether can't accidentally get locked within a contract. 11 | 12 | Functions handling Ether should also be checked extra carefully for access control input validation and error handling all these various aspects of Ether handling should be reviewed for correctness. -------------------------------------------------------------------------------- /src/learn/3.Security_Pitfalls_and_Best_Practices/3.4_Constructor.md: -------------------------------------------------------------------------------- 1 | # Constructor 2 | 3 | ## Constructor Names 4 | 5 | Constructor names in `Solidity` have had security implications historically. If you go back all the way to `Solidity` compiler version `0.4.22`, the versions prior to that one required the use of the contract name as the name of the constructor. And between that version and `0.5.0` one could either use the contract name as a constructor or use the `constructor` keyword itself. It was only after `0.5.0` that `Solidity` forced the use of the `constructor` keyword for constructors. 6 | 7 | So this flexibility, the use of the contract name as the constructor name, has historically caused bugs, where the contact name was misspelled which led to that function not being the constructor, but a regular function. 8 | 9 | Also the flexibility between allowing both the old style and the new style constructor names caused security issues, because there was a precedence that was followed, if both of them existed. So this constructor naming confusion has been a historical source of bugs and `Solidity` smart contracts, although **it is not a concern anymore**. 10 | 11 | ## Void Constructor 12 | 13 | There's a security concern related to "_void constructors_". What this means is that if a contract derives from other contracts, then it makes calls to the constructors of base contracts assuming they're implemented, but if in fact they are not, then this assumption leads to security implications. 14 | 15 | So the best practice for derived contracts is to check if the base constructor is actually implemented and remove the call to that constructor, if it is not implemented at all. 16 | 17 | ## Constructor Call Value 18 | 19 | This security pitfall is related to the checks for any value sent in contact creation transactions triggering the constructor. 20 | 21 | Typically, if a constructor is not explicitly payable and there is an Ether value that is sent in a contract creation transaction that triggers such a constructor, then the constructor reverts that transaction. 22 | 23 | However, because of a compiler bug, if contract did not have an explicit constructor but had a base contract that did define a constructor, then in those cases, it was possible to send Ether value in a contract creation transaction, that would not cause that revert to happen. This compiler bug was present all the way from version `0.4.5` to version `0.6.8`, and thus **is not an issue anymore**. -------------------------------------------------------------------------------- /src/learn/3.Security_Pitfalls_and_Best_Practices/3.5_Delegatecall.md: -------------------------------------------------------------------------------- 1 | # `delegatecall` 2 | 3 | The security pitfall is related to the use of `delegatecall` in contracts where the `delegatecall` may be made to an address that is user controlled. Remember that in the case of `delegatecall`s, the calling contract makes a `delegatecall` to a called contract, where the called contract executes its logic on the state of the calling contract. 4 | 5 | So, if the address of the called contract is user controlled, then the user may accidentally or maliciously make this `delegatecall` to a malicious contract, that can make unauthorized modifications to the state of the calling contract. 6 | 7 | Therefore, `delegatecall`s should be used with extreme care in contracts. All precautions should be used to ensure that the destination addresses for such `delegatecall`s are trusted. -------------------------------------------------------------------------------- /src/learn/3.Security_Pitfalls_and_Best_Practices/3.7_Private_Data.md: -------------------------------------------------------------------------------- 1 | # Private Data 2 | 3 | This security pitfall is related to the notion of what is private data on a blockchain or the privacy of on-chain data. 4 | 5 | Remember that state variables and `Solidity` have a function visibility specifier. By making this specified a `private`, such private state variables can't be read only by other smart contracts on the blockchain, this does not mean that they can't be read at all. 6 | 7 | We don't have to believe that they are considered private in a confidentiality perspective because the state of such variables and contracts and transactions in general on the blockchain can be read by anyone on the chain itself or via off-chain interfaces by querying the mempools for transactions or by querying the contract state itself to look at what values such private variables contain. 8 | 9 | This effectively means that, **there is no notion of data being private on the blockchain** and any such data for confidentiality reasons that needs to be private should be encrypted and stored off-chain. -------------------------------------------------------------------------------- /src/learn/3.Security_Pitfalls_and_Best_Practices/3.8_PRNG_and_Time.md: -------------------------------------------------------------------------------- 1 | # PRNG and Time 2 | 3 | ## PRNG 4 | 5 | This security pitfall is related to pseudo-random number generation on the blockchain within smart contracts applications that require such random numbers. 6 | 7 | Remember that these values could be influenced to a certain extent by miners who are mining the blocks that contain these values. So if the stakes in those applications using these as sources of randomness is high, then such actors could use their influence to a certain extent to gain advantage. 8 | 9 | So this is a risk from randomness that needs to be paid attention to something to be aware of and, if the stakes are high for the applications where you desire a much better source of randomness then, there are some alternatives such as the verifiable random function provided by Chainlink. 10 | 11 | ## Time 12 | 13 | Similar to randomness, the notion of getting the time on-chain is also tricky. Often smart contracts resort to using `block.timestamp` or `block.number` as sources for inferring the time within the application's logic. 14 | 15 | Again, what needs to be paid attention to is that this notion of time can be influenced to a certain extent by the miners. There are issues with synchronization across the different blockchain nodes and there are also aspects of the block times that change by a certain degree over time. 16 | 17 | This is again a risk that needs to be paid attention to and, there are some alternatives to this using the concept of Oracles. -------------------------------------------------------------------------------- /src/learn/3.Security_Pitfalls_and_Best_Practices/3_Security_Pitfalls_and_Best_Practices.md: -------------------------------------------------------------------------------- 1 | # 🔏 3. Security Pitfalls & Best Practices 2 | 3 | In this section we will be discussing commonly encountered pitfalls and recommended best practices related to Ethereum smart contract security. It is based on the following content: 4 | 5 | * [**Secureum's Security Pitfalls and Best Practices 101 keypoints**](https://secureum.substack.com/p/security-pitfalls-and-best-practices-101) 6 | * [**Secureum's Security Pitfalls and Best Practices 201 keypoints**](https://secureum.substack.com/p/security-pitfalls-and-best-practices-201) 7 | * **Secureum's Security Pitfalls and Best Practices 101** YouTube videos: 8 | * [Block 1](https://www.youtube.com/watch?v=OOzyoaYIw2k) 9 | * [Block 2](https://www.youtube.com/watch?v=fgXuHaZDenU) 10 | * [Block 3](https://www.youtube.com/watch?v=YVewx1xVROE) 11 | * [Block 4](https://www.youtube.com/watch?v=byA3MLLiKMM) 12 | * [Block 5](https://www.youtube.com/watch?v=vyWLO5Dlg50) 13 | * **Secureum's Security Pitfalls and Best Practices 201** YouTube videos: 14 | * [Block 1](https://www.youtube.com/watch?v=WGM1SF8twmw) 15 | * [Block 2](https://www.youtube.com/watch?v=HqHo1jKUnmU) 16 | * [Block 3](https://www.youtube.com/watch?v=pXoEIjHupXk) 17 | * [Block 4](https://www.youtube.com/watch?v=IVbEIbIpWUY) 18 | * [Block 5](https://www.youtube.com/watch?v=QSsfkmcdbPw) 19 | -------------------------------------------------------------------------------- /src/learn/4.Audit_Techniques_and_Tools/4.4_False_Positives_and_Negatives.md: -------------------------------------------------------------------------------- 1 | # False Positives & Negatives 2 | 3 | Let's now talk about the concept of false positives and false negatives, which are critical to understand in the context of smart contract audits or security. 4 | 5 | ## False Positives 6 | 7 | False positives are findings which flag the presence of vulnerabilities, but which in fact are not vulnerabilities. They could arise due to incorrect assumptions or simplifications in analysis which do not correctly consider all the factors required for the actual presence of vulnerabilities. 8 | 9 | False positives require further manual analysis on findings to investigate if they are indeed false positives or if they are true positives. A high number of false positives increases the manual effort required in verification and also lowers the confidence in the accuracy of findings from the earlier automated analysis. 10 | 11 | On the flip side, true positives might sometimes be incorrectly classified as false positives, which leads to the vulnerabilities behind those findings being ignored and left behind in the code instead of being fixed, and may end up getting exploited later. 12 | 13 | ## False Negatives 14 | 15 | On the other hand false negatives are missed findings that should have indicated the presence of vulnerabilities, but which are in fact not reported at all. Such false negatives again could be due to incorrect assumptions or inaccuracies in analysis which did not correctly consider the minimum factors required for the actual presence of vulnerabilities. 16 | 17 | False negatives, per definition, are not reported or even realized unless a different analysis reveals their presence, or the vulnerabilities are realized when they're exploited. A high number of false negatives lowers the confidence in the effectiveness of the earlier manual or automated analysis. In contrast, true negatives are findings that are analyzed and dismissed which are in fact not vulnerabilities 18 | 19 | So these concepts of true positives, false positives, true negatives and false negatives come up often in smart contract auditing and in security in general, and therefore this terminology (the distinction between these types) should be well understood. -------------------------------------------------------------------------------- /src/learn/4.Audit_Techniques_and_Tools/4_Audit_Techniques_and_Tools.md: -------------------------------------------------------------------------------- 1 | # 🗜 4. Audit Techniques & Tools 2 | 3 | In this chapter we will cover the various technical and non-technical aspects of smart contact auditing, starting with the high level view of what are audits (the entire context around it). Then we'll review the widely used tools in this space developed by teams from Trail of Bits, Consensus Diligence and others. We will cover high level aspects of these tools without getting too much into their operational or technical details which is out of scope.If you want to learn more about these tools, it is highly encouraged to install them and experiment with them. 4 | 5 | Finally we will review the audit process and the various aspects that one will need to understand to become a smart contact security auditor. 6 | 7 | It is based on the following content: 8 | 9 | * [**Secureum's Audit Techniques & Tools 101 keypoints**](https://secureum.substack.com/p/audit-techniques-and-tools-101) 10 | * **Secureum's Audit Techniques & Tools 101** YouTube videos: 11 | * [Block 1](https://www.youtube.com/watch?v=M0C7z3TE5Go) 12 | * [Block 2](https://www.youtube.com/watch?v=QstpNY1IuqM) 13 | * [Block 3](https://www.youtube.com/watch?v=QmD2bJUe140) 14 | * [Block 4](https://www.youtube.com/watch?v=jZ81ebDJVe0) 15 | * [Block 5](https://www.youtube.com/watch?v=dgITqd3mkDk) 16 | -------------------------------------------------------------------------------- /src/learn/5.Audit_Findings/5_Audit_Findings.md: -------------------------------------------------------------------------------- 1 | # ☝ 5. Audit Findings 2 | 3 | In this chapter, we will review findings from public audit reports of leading audit firms to get a sense for the kinds of issues reported during audits and their suggestive fixes or recommendations. The severity of these findings spans a wide spectrum (they may go from medium severity to high and critical, which are of the highest concern as they could have led to loss of funds or significantly affected execution, if they had not been detected and fixed during audits; or also be low severity, informational and best practice guidelines). 4 | 5 | We will only be able to touch upon key aspects of these findings. The reason is that these findings require a lot of context from the deepest details of the protocol implementations, which is certainly out of scope. This research will need to be done by interested bootcamp participants in their own time, by reviewing the audit reports and their corresponding protocol codebases to whatever depth possible. 6 | 7 | For each finding, we will review the vulnerability category, its finding summary and the proposed recommendation while relating some of these aspects to our learnings from the earlier chapters. 8 | 9 | It is based on the following content: 10 | 11 | * [**Secureum's Audit Findings 101 keypoints**](https://secureum.substack.com/p/audit-findings-101) 12 | * [**Secureum's Audit Findings 201 keypoints**](https://secureum.substack.com/p/audit-findings-201) 13 | * **Secureum's Audit Findings 101** YouTube videos: 14 | * [Block 1](https://www.youtube.com/watch?v=SromSImIpHE) 15 | * [Block 2](https://www.youtube.com/watch?v=KLBi3Uyg0dY) 16 | * [Block 3](https://www.youtube.com/watch?v=RUyED\_6mkqg) 17 | * [Block 4](https://www.youtube.com/watch?v=D1Uz0NvrqeU) 18 | * [Block 5](https://www.youtube.com/watch?v=GX8Z0kRRi\_I) 19 | * **Secureum's Audit Findings 201** YouTube videos: 20 | * [Block 1](https://www.youtube.com/watch?v=IXm6JAprhuw) 21 | * [Block 2](https://www.youtube.com/watch?v=yphqu2N35X4) 22 | * [Block 3](https://www.youtube.com/watch?v=zAzNDwu23UI) 23 | * [Block 4](https://www.youtube.com/watch?v=poxzr4-srn0) 24 | * [Block 5](https://www.youtube.com/watch?v=0J7KI4WGd0Q) 25 | -------------------------------------------------------------------------------- /src/learn/README.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | This site contains all the Secureum learning material and it is thought to be a "_living document_" that is going to be updated epriodically to be up-to-date with the most recent advancements in Ethereum. 4 | 5 | 6 | 7 | > ⚠️ **Disclaimer** 8 | > 9 | > This write-up is community driven! If in doubt of the veracity of the information found within this book, please refer to the original source materials: 10 | > 11 | > * [**Secureum's substack**](https://secureum.substack.com/) 12 | > * [**Secureum's YouTube Channel**](https://www.youtube.com/@SecureumVideos) 13 | > * [**Mastering Ethereum Book**](https://github.com/ethereumbook/ethereumbook) 14 | 15 | 16 | 17 | > 📖 **Contributing** 18 | > 19 | > You can contribute to this book on [GitHub](https://github.com/luksgrin/secureum\_book). 20 | --------------------------------------------------------------------------------