Top Related Projects
OpenZeppelin Contracts is a library for secure smart contract development.
A guide to smart contract security best practices
Comprehensive list of known attack vectors and common anti-patterns
node of the decentralized oracle network, bridging on and off-chain computation
Quick Overview
The "crytic/not-so-smart-contracts" repository is a collection of common Ethereum smart contract vulnerabilities. It serves as an educational resource for developers and security researchers, showcasing various security issues in Solidity contracts along with explanations and potential fixes.
Pros
- Provides real-world examples of smart contract vulnerabilities
- Includes detailed explanations and potential fixes for each vulnerability
- Serves as a valuable learning resource for Ethereum developers
- Regularly updated with new vulnerabilities and best practices
Cons
- May not cover all possible vulnerabilities in smart contracts
- Some examples might become outdated as Solidity and Ethereum evolve
- Requires a basic understanding of Solidity and smart contract development
- Not a comprehensive security solution on its own
Code Examples
- Reentrancy vulnerability:
contract Vulnerable {
mapping(address => uint) public balances;
function withdraw() public {
uint bal = balances[msg.sender];
require(bal > 0);
(bool sent, ) = msg.sender.call{value: bal}("");
require(sent, "Failed to send Ether");
balances[msg.sender] = 0;
}
}
This code demonstrates a reentrancy vulnerability where an attacker can repeatedly call the withdraw
function before the balance is updated.
- Integer overflow:
contract Overflow {
mapping(address => uint8) public balances;
function transfer(address _to, uint8 _amount) public {
balances[msg.sender] -= _amount;
balances[_to] += _amount;
}
}
This example shows an integer overflow vulnerability where the balance can wrap around due to the use of uint8
.
- Unprotected self-destruct:
contract Destroyable {
function destroy() public {
selfdestruct(payable(msg.sender));
}
}
This code demonstrates an unprotected selfdestruct
function that allows anyone to destroy the contract and send its balance to themselves.
Getting Started
To explore the vulnerabilities:
- Clone the repository:
git clone https://github.com/crytic/not-so-smart-contracts.git
- Navigate to the desired vulnerability folder.
- Read the README.md file for an explanation of the vulnerability.
- Review the vulnerable and fixed contract examples in the Solidity files.
- Use a development environment like Remix or Truffle to deploy and test the contracts.
Competitor Comparisons
OpenZeppelin Contracts is a library for secure smart contract development.
Pros of openzeppelin-contracts
- Comprehensive library of secure, audited smart contract components
- Actively maintained with regular updates and improvements
- Extensive documentation and community support
Cons of openzeppelin-contracts
- Larger codebase may increase gas costs for deployment
- Learning curve for developers new to the library
- May include unnecessary features for simpler projects
Code Comparison
openzeppelin-contracts:
contract ERC20 is Context, IERC20, IERC20Metadata {
mapping(address => uint256) private _balances;
mapping(address => mapping(address => uint256)) private _allowances;
uint256 private _totalSupply;
string private _name;
string private _symbol;
not-so-smart-contracts:
contract VulnerableToken {
mapping(address => uint) public balances;
uint public totalSupply;
function transfer(address to, uint amount) public {
balances[msg.sender] -= amount;
balances[to] += amount;
}
The openzeppelin-contracts example showcases a more robust and secure implementation of an ERC20 token, while the not-so-smart-contracts example demonstrates a vulnerable token contract for educational purposes.
A guide to smart contract security best practices
Pros of smart-contract-best-practices
- Comprehensive coverage of best practices and security considerations
- Regular updates and contributions from the community
- Includes practical examples and code snippets
Cons of smart-contract-best-practices
- Can be overwhelming for beginners due to the extensive information
- Lacks a structured learning path or progression
- Some sections may require prior knowledge of smart contract development
Code Comparison
smart-contract-best-practices:
function transfer(address to, uint256 amount) public {
require(balances[msg.sender] >= amount, "Insufficient balance");
balances[msg.sender] -= amount;
balances[to] += amount;
emit Transfer(msg.sender, to, amount);
}
not-so-smart-contracts:
function transfer(address to, uint256 amount) public {
balances[msg.sender] -= amount;
balances[to] += amount;
emit Transfer(msg.sender, to, amount);
}
The smart-contract-best-practices example includes a balance check, demonstrating better security practices, while the not-so-smart-contracts example lacks this check, potentially allowing underflow vulnerabilities.
Comprehensive list of known attack vectors and common anti-patterns
Pros of solidity-security-blog
- More comprehensive coverage of security topics, including detailed explanations and examples
- Regular updates and contributions from the community
- Includes practical mitigation strategies for each vulnerability
Cons of solidity-security-blog
- Less structured organization compared to not-so-smart-contracts
- Fewer ready-to-use code snippets for testing and demonstration
- May be overwhelming for beginners due to the depth of information
Code Comparison
not-so-smart-contracts:
function withdraw() public {
uint256 amount = balances[msg.sender];
(bool success, ) = msg.sender.call.value(amount)("");
require(success);
balances[msg.sender] = 0;
}
solidity-security-blog:
function withdraw() public {
uint256 amount = balances[msg.sender];
balances[msg.sender] = 0;
(bool success, ) = msg.sender.call.value(amount)("");
require(success, "Transfer failed.");
}
Both repositories provide valuable resources for Solidity developers interested in smart contract security. not-so-smart-contracts offers a more structured approach with specific vulnerability examples, while solidity-security-blog provides in-depth explanations and community-driven content. The code comparison shows a subtle difference in the order of operations, highlighting the importance of following best practices to prevent reentrancy attacks.
node of the decentralized oracle network, bridging on and off-chain computation
Pros of Chainlink
- Actively maintained and widely adopted in the blockchain industry
- Comprehensive documentation and extensive ecosystem support
- Provides real-world data integration and off-chain computation capabilities
Cons of Chainlink
- More complex codebase with a steeper learning curve
- Requires understanding of oracle networks and decentralized data feeds
- Higher resource requirements for deployment and maintenance
Code Comparison
Chainlink (price feed example):
import "@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol";
contract PriceConsumerV3 {
AggregatorV3Interface internal priceFeed;
constructor() {
priceFeed = AggregatorV3Interface(0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419);
}
}
Not-so-smart-contracts (vulnerable code example):
contract Vulnerable {
mapping(address => uint) public balances;
function withdraw() public {
uint amount = balances[msg.sender];
(bool success, ) = msg.sender.call{value: amount}("");
require(success);
balances[msg.sender] = 0;
}
}
Not-so-smart-contracts focuses on showcasing vulnerable smart contract patterns, while Chainlink provides robust infrastructure for building secure and interconnected smart contracts.
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual CopilotREADME
No-so-smart-contracts is now in building-secure-contracts (see https://secure-contracts.com/)
(Not So) Smart Contracts
This repository contains examples of common Ethereum smart contract vulnerabilities, including code from real smart contracts. Use Not So Smart Contracts to learn about EVM and Solidity vulnerabilities, as a reference when performing security reviews, and as a benchmark for security and analysis tools.
Features
Each Not So Smart Contract includes a standard set of information:
- Description of the unique vulnerability type
- Attack scenarios to exploit the vulnerability
- Recommendations to eliminate or mitigate the vulnerability
- Real-world contracts that exhibit the flaw
- References to third-party resources with more information
Bonus! We have also included a repository and analysis of several honeypots.
Vulnerabilities
Not So Smart Contract | Description |
---|---|
Bad randomness | Contract attempts to get on-chain randomness, which can be manipulated by users |
Denial of Service | Attacker stalls contract execution by failing in strategic way |
Forced Ether Reception | Contracts can be forced to receive Ether |
Incorrect Interface | Implementation uses different function signatures than interface |
Integer Overflow | Arithmetic in Solidity (or EVM) is not safe by default |
Race Condition | Transactions can be frontrun on the blockchain |
Reentrancy | Calling external contracts gives them control over execution |
Unchecked External Call | Some Solidity operations silently fail |
Unprotected Function | Failure to use function modifier allows attacker to manipulate contract |
Variable Shadowing | Local variable name is identical to one in outer scope |
Wrong Constructor Name | Anyone can become owner of contract due to missing constructor |
Credits
These examples are developed and maintained by Trail of Bits. Contributions are encouraged and are covered under our bounty program.
If you have questions, problems, or just want to learn more, then join the #ethereum channel on the Empire Hacking Slack or contact us directly.
Top Related Projects
OpenZeppelin Contracts is a library for secure smart contract development.
A guide to smart contract security best practices
Comprehensive list of known attack vectors and common anti-patterns
node of the decentralized oracle network, bridging on and off-chain computation
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual Copilot