---
name: solidity-3e50be31bb28
description: Expert Solidity smart contract assistance covering EVM, OpenZeppelin, ERC-20/721/1155, and reentrancy guards. Use when developing Ethereum contracts, DeFi protocols, NFT systems, or Web3 dApps.
---

# Solidity

Solidity is an object-oriented, high-level language for implementing smart contracts on the Ethereum Virtual Machine (EVM), featuring strict typing and gas-optimized storage patterns.

## When to Use

- **Ethereum & EVM Smart Contract Development**: Building decentralized protocols on Ethereum, Arbitrum, Optimism, Polygon, and Base.
- **DeFi Financial Protocols**: Automated market makers (AMMs), lending pools, yield aggregators, and staking vaults.
- **Token Standards & Digital Assets**: Implementing ERC-20 fungible tokens, ERC-721/ERC-1155 non-fungible tokens, and ERC-4337 smart accounts.
- **On-Chain Governance & DAOs**: Implementing multisigs, timelocks, and decentralized voting mechanisms.

## Quick Start

```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

contract SimpleStorage {
    uint256 private storedData;
    event DataChanged(uint256 newValue);

    function set(uint256 x) public {
        storedData = x;
        emit DataChanged(x);
    }

    function get() public view returns (uint256) {
        return storedData;
    }
}
```

## Core Concepts

### Secure ERC-20 Vault with OpenZeppelin & Custom Errors

Gas-optimized token vault with reentrancy protection and custom error revert reasons:

```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;

import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "@openzeppelin/contracts/utils/ReentrancyGuard.sol";
import "@openzeppelin/contracts/access/Ownable2Step.sol";

error ZeroDepositAmount();
error InsufficientBalance(uint256 available, uint256 requested);

contract TokenVault is ReentrancyGuard, Ownable2Step {
    using SafeERC20 for IERC20;

    IERC20 public immutable token;
    mapping(address => uint256) public userBalances;

    event Deposited(address indexed user, uint256 amount);
    event Withdrawn(address indexed user, uint256 amount);

    constructor(IERC20 _token) Ownable2Step(msg.sender) {
        token = _token;
    }

    function deposit(uint256 amount) external nonReentrant {
        if (amount == 0) revert ZeroDepositAmount();
        userBalances[msg.sender] += amount;
        token.safeTransferFrom(msg.sender, address(this), amount);
        emit Deposited(msg.sender, amount);
    }

    function withdraw(uint256 amount) external nonReentrant {
        uint256 balance = userBalances[msg.sender];
        if (amount > balance) revert InsufficientBalance(balance, amount);
        userBalances[msg.sender] = balance - amount;
        token.safeTransfer(msg.sender, amount);
        emit Withdrawn(msg.sender, amount);
    }
}
```

### Storage, Memory & Calldata Gas Layout

Understanding the EVM data locations to minimize transaction execution costs:

```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;

contract StorageLayout {
    // Storage variables packed into 32-byte slots
    struct UserProfile {
        uint128 balance; // slot 0 (16 bytes)
        uint64 lastLogin; // slot 0 (8 bytes)
        uint64 flags;     // slot 0 (8 bytes) - total 32 bytes packed
        address owner;    // slot 1 (20 bytes)
    }

    mapping(uint256 => UserProfile) public profiles;

    // Use 'calldata' for read-only external array arguments to avoid memory copying
    function batchCheckFlags(bytes32[] calldata hashes) external view returns (bool) {
        for (uint256 i = 0; i < hashes.length; ++i) {
            if (hashes[i] == bytes32(0)) return false;
        }
        return true;
    }
}
```

### Checks-Effects-Interactions & Upgradeability (UUPS)

Preventing reentrancy vulnerabilities and managing proxy upgrades:

```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;

import "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";

contract VaultV1 is Initializable, OwnableUpgradeable, UUPSUpgradeable {
    uint256 public totalYield;

    /// @custom:oz-upgrades-unsafe-allow constructor
    constructor() {
        _disableInitializers();
    }

    function initialize(address initialOwner) public initializer {
        __Ownable_init(initialOwner);
        __UUPSUpgradeable_init();
    }

    function _authorizeUpgrade(address newImplementation) internal override onlyOwner {}
}
```

## Common Patterns

### Checks-Effects-Interactions Pattern (Reentrancy Prevention)

**Problem**: External calls made before internal state updates allow recursive reentrancy attacks draining contract funds.

**Solution**:
Update contract state before making external ether transfers:

```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

contract Vault {
    mapping(address => uint256) public balances;

    function withdraw() external {
        // 1. Checks
        uint256 amount = balances[msg.sender];
        require(amount > 0, "Insufficient balance");

        // 2. Effects
        balances[msg.sender] = 0;

        // 3. Interactions
        (bool success, ) = msg.sender.call{value: amount}("");
        require(success, "Transfer failed");
    }
}
```

## Best Practices

**Do**:

- Use Solidity `^0.8.24` or higher with native arithmetic overflow protection and custom errors (`error MyError()`) instead of string `require` messages.
- Always adhere to the Checks-Effects-Interactions (CEI) pattern and apply `ReentrancyGuard` to all state-changing transfer functions.
- Test smart contracts rigorously with Foundry (`forge test`, fuzzing, and invariant testing) and formal verification tools.
- Use OpenZeppelin's `SafeERC20` wrapper to prevent silent transfer failures from non-standard ERC-20 tokens.

**Don't**:

- Use `tx.origin` for authorization; always use `msg.sender` to defend against phishing and proxy attacks.
- Rely on `block.timestamp` or `block.number` for random number generation; integrate Chainlink VRF.
- Deploy unverified or unaudited contracts to production mainnets.

## Troubleshooting

| Error                                        | Cause                                                               | Solution                                                                       |
| :------------------------------------------- | :------------------------------------------------------------------ | :----------------------------------------------------------------------------- |
| `Transaction reverted: function call failed` | `require` condition evaluated to false or gas limit exceeded.       | Check revert reason in block explorer or run test with Hardhat/Foundry traces. |
| `Error: Gas estimation failed`               | Transaction will inevitably revert under current contract state.    | Verify caller account permissions, allowance, and input parameters.            |
| `Compiler version mismatch`                  | `pragma solidity` declaration incompatible with local solc version. | Update compiler version in `hardhat.config.js` or `foundry.toml`.              |

## References

- [Solidity Documentation](https://docs.soliditylang.org/)


---
Source attribution: G1Joshi
Original project: https://github.com/G1Joshi/Agent-Skills/blob/6a74cf03a8a86dc7d993ead3091b41123dbd0181/skills/languages/solidity/SKILL.md
License: MIT
License information: https://opensource.org/license/mit
Original upstream instructions; downloaded from Dave AI.

## Upstream license notice

MIT License

Copyright (c) 2026 G1Joshi

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.



# Dave AI resource metadata

Creator / publisher: G1Joshi
Original project: https://github.com/G1Joshi/Agent-Skills/blob/6a74cf03a8a86dc7d993ead3091b41123dbd0181/skills/languages/solidity/SKILL.md
Attribution basis: Source repository record

Fields of work: Development & Engineering, Product Management
Roles: Backend Developer, Data Engineer, Growth Product Manager, ML / AI Engineer, Product Manager
Specialties: Backend
Tools: Foundry
Country applicability: Country not specified
Classification basis: Source catalog labels
Instruction SHA-256: 06a076fdf864a9b52bfe7feb50a5d8d12ec4809e29e2f009b98f7a82867893cd
