Agent RulesAgent Rules
Builder
Options
Browse all rules by language and framework
Templates
Pre-built rule sets ready to use
Popular Rules
Top community-ranked rules leaderboard
GuidesAnalyzePricingContact
Builder
OptionsTemplatesPopular Rules
GuidesAnalyzePricingContact

Product

  • Builder
  • Templates
  • Browse Rules
  • My Library

Learn

  • What are AI Agent Rules?
  • Guides
  • FAQ
  • About

Resources

  • Terms
  • Privacy Policy
  • Pricing
  • Contact
  • DMCA Policy

Support

Help keep this project free.

Agent RulesAgent Rules Builder
© 2026 Aurora Algorithm Inc.
Back to Templates

Solidity + Ethereum

Rules for Ethereum smart contract development covering security, gas optimization, and testing.

soliditySolidity/hardhatHardhat
solidity
ethereum
smart-contracts
hardhat
web3
Customize in Builder

Details

Language
soliditySolidity
Framework
hardhatHardhat

Rules Content

AGENTS.md
Edit in Builder

Solidity Ethereum Agent Rules

Project Context

You are developing Ethereum smart contracts with Solidity 0.8+. Contracts handle real value — correctness and security are non-negotiable. Use OpenZeppelin for standard patterns and Hardhat for testing and deployment.

Code Style

- Pin the compiler version: `pragma solidity 0.8.24;` — avoid floating pragmas like `^0.8.0`.
- Follow Solidity naming: contracts `PascalCase`, functions and variables `camelCase`, constants `UPPER_SNAKE_CASE`, events `PascalCase`.
- Order contract members: type declarations → state variables → events → errors → modifiers → constructor → external → public → internal → private.
- Write NatSpec comments (`///` or `/** */`) for every public/external function, event, error, and state variable.
- Use custom errors instead of revert strings: `error InsufficientBalance(uint256 available, uint256 required)` — they cost less gas and carry structured data.
- Keep contracts under 300 lines; extract reusable logic into libraries and base contracts.
- Use `immutable` for values set once in the constructor; use `constant` for compile-time known values.

Security: Checks-Effects-Interactions

- Always follow the CEI pattern: perform all `require`/`revert` checks first, update state second, make external calls last.
- Use `ReentrancyGuard.nonReentrant` from OpenZeppelin on every function that transfers ETH or calls external contracts.
- Use `SafeERC20` from OpenZeppelin for all ERC20 token transfers to handle non-standard return values.
- Never use `tx.origin` for authentication — use `msg.sender` exclusively.
- Validate all external inputs: check for zero addresses, zero amounts, array length mismatches.
- Use access control on every state-changing function: `onlyOwner`, `onlyRole(MINTER_ROLE)`, or custom modifiers.
- Be aware of front-running: use commit-reveal schemes or time-locks for sensitive operations (auctions, randomness).
- Set explicit upper bounds on loops: never iterate over user-controlled or unbounded arrays in a single transaction.

Access Control

- Use OpenZeppelin `AccessControl` for role-based permissions: `grantRole(MINTER_ROLE, address)`.
- Define granular roles: `MINTER_ROLE`, `PAUSER_ROLE`, `UPGRADER_ROLE`, `TREASURY_ROLE`.
- Use a timelocked multisig (Safe + Timelock) for admin roles in production.
- Implement `Pausable` on contracts handling user funds for emergency stops.
- Emit events on every role grant/revoke — on-chain auditability matters.

Upgradeable Contracts

- Use UUPS proxy pattern over TransparentProxy for lower per-call gas cost.
- Use `initializer` modifier in place of constructors for upgradeable contracts.
- Call `_disableInitializers()` in the implementation constructor to prevent direct initialization.
- Use structured storage slots (EIP-7201) to prevent storage collisions across upgrades.
- Test every upgrade path: deploy V1, upgrade to V2, verify state is preserved and new logic is correct.

Gas Optimization

- Pack storage variables: group `uint128 a; uint128 b;` into one 32-byte slot rather than two.
- Use `calldata` for function parameters that are only read, not modified.
- Cache storage reads in local memory variables when a storage variable is accessed multiple times in a function.
- Use `unchecked { ++i; }` in loop increments after validating the operation cannot overflow.
- Use mappings over arrays for lookups; use `EnumerableSet` only when enumeration is genuinely required.
- Use `bytes32` instead of `string` for fixed-length identifiers.
- Minimize event data — only index fields used for off-chain filtering; log only what indexers need.

Events & Errors

- Emit events for every state change external systems need to track: transfers, role changes, parameter updates.
- Index up to 3 fields per event for efficient filtering: addresses, IDs, topics — not large value fields.
- Define errors at the interface level so callers can decode them without the full implementation ABI.
- Name events in past tense: `Deposited`, `Withdrawn`, `OwnershipTransferred`, `ConfigUpdated`.
- Include both old and new values in update events: `event PriceUpdated(uint256 oldPrice, uint256 newPrice)`.

Testing

- Write unit tests in TypeScript with Hardhat, ethers.js, and Chai — test every public and external function.
- Test all revert conditions: unauthorized calls, invalid inputs, paused state, reentrancy attempts.
- Use `loadFixture` from `@nomicfoundation/hardhat-network-helpers` for efficient snapshot/restore between tests.
- Write fuzz tests with Foundry (`forge test`) or Echidna for mathematical invariants and boundary conditions.
- Measure gas with `hardhat-gas-reporter` — set gas budgets per function and fail CI if exceeded.
- Target 100% branch coverage on security-critical contracts: access control, fund handling, state transitions.
- Fork mainnet state for integration tests: `--fork-url $MAINNET_RPC_URL` to test against real deployed protocols.

Deployment & Verification

- Write deterministic deployment scripts in TypeScript — verify constructor arguments match expected values.
- Deploy to testnets (Sepolia, Holesky) first; run the full test suite against the testnet deployment.
- Verify contracts on Etherscan immediately post-deployment using `hardhat-verify`.
- Store deployment addresses, transaction hashes, and ABIs in version-controlled JSON files per network.
- Use Safe multisig for all contract ownership and admin roles in production — no single EOA owner.
- Complete a security audit before mainnet deployment for any contract handling user funds.