| name | solidity |
| description | Solidity smart contract development with Foundry. Covers writing, testing, security, deployment, and upgrades. Triggers on .sol files, contract, pragma solidity, forge. |
| triggers | \.sol, \bcontract\b, solidity, pragma solidity, forge, foundry, hardhat |
MCPSearch({ query: "select:mcp__plugin_devtools_octocode__githubSearchCode" })
MCPSearch({ query: "select:mcp__plugin_devtools_context7__query-docs" })
// OpenZeppelin contracts
mcp__octocode__githubSearchCode({
keywordsToSearch: ["Ownable", "AccessControl", "Pausable"],
owner: "OpenZeppelin",
repo: "openzeppelin-contracts",
path: "contracts/access",
mainResearchGoal: "Find OpenZeppelin access control patterns",
researchGoal: "Get current Ownable and AccessControl implementations",
reasoning: "Need verified security patterns",
});
// Foundry testing
mcp__context7__query_docs({
libraryId: "/foundry-rs/book",
query: "How do I use forge test with fuzz and invariant testing?",
});
Note: Context7 v2 uses server-side filtering. Use descriptive natural language queries.
// SPDX-License-Identifier: MIT
pragma solidity 0.8.28;
import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol";
/// @title MyContract
/// @notice Brief description
contract MyContract is Ownable {
// Events
event ActionPerformed(address indexed actor, uint256 amount);
// Errors
error InsufficientBalance(uint256 required, uint256 available);
// State variables
uint256 private _totalAmount;
// Constructor
constructor() Ownable(msg.sender) {}
/// @notice Performs an action
/// @param amount The amount to process
function performAction(uint256 amount) external {
// Checks
if (amount > _totalAmount) {
revert InsufficientBalance(amount, _totalAmount);
}
// Effects
_totalAmount -= amount;
// Interactions
emit ActionPerformed(msg.sender, amount);
}
}
Always order operations as:
- Checks - Validate inputs and state
- Effects - Update contract state
- Interactions - External calls and events
function transfer(address to, uint256 amount) external {
// 1. Checks
require(balances[msg.sender] >= amount, "Insufficient");
// 2. Effects
balances[msg.sender] -= amount;
balances[to] += amount;
// 3. Interactions
emit Transfer(msg.sender, to, amount);
}
Required:
- NatSpec on all
externalfunctions - Events for all state changes
- CEI pattern for external calls
- 50-slot storage gap in upgradeables
_disableInitializers()in implementation constructorssuper.hookName()FIRST in hook overrides
Naming: Contracts=PascalCase, functions=camelCase, constants=SCREAMING_SNAKE, events=PastTense, errors=NounPhrase, private=_underscore
- No reentrancy vulnerabilities (CEI pattern)
- Access control on sensitive functions
- Integer overflow/underflow handled (Solidity 0.8+)
- No unchecked external calls
- Events emitted for state changes
- Storage gaps for upgradeable contracts
- OctoCode searched for OpenZeppelin patterns
- NatSpec on external functions
- CEI pattern followed
- Events for state changes
- Tests pass with good coverage