solidity-security について
スマートコントラクトの開発者向けの Solidity セキュリティスキルです。脆弱性の予防、安全な開発パターン、テスト、監査準備を扱います。
主な機能
- 01Solidityのセキュリティベストプラクティス
- 02脆弱性の予防パターン
- 03セキュリティテストの例
- 04監査準備のガイド
- 05安全性を保つガス最適化
活用シーン
- 01コントラクトの脆弱性確認
- 02安全なDeFiプロトコルの構築
- 03リエントランシーやアクセス制御問題の予防
- 04専門監査に向けたコントラクト準備
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ wshobson/ agents --skill solidity-securityインストール後、Claude Code で/solidity-securityを入力して読み込まれたか確認します。
同梱ファイルreferences/details.md
詳細
Solidity セキュリティ
スマートコントラクトのセキュリティベストプラクティス、脆弱性の防止、および安全な Solidity 開発パターンを習得します。
このスキルを使用する場面
- 安全なスマートコントラクトを作成するとき
- 既存のコントラクトの脆弱性を監査するとき
- 安全な DeFi プロトコルを実装するとき
- リエントランシー、オーバーフロー、アクセス制御の問題を防ぐとき
- セキュリティを維持しながらガス使用量を最適化するとき
- プロの監査に向けてコントラクトを準備するとき
- 一般的な攻撃ベクトルを理解するとき
詳細なパターンと実例
詳細なパターンのドキュメントは references/details.md にあります。上記のナビゲーション層では不十分な場合に、そのファイルを参照してください。
セキュリティのテスト
// Hardhat test example
const { expect } = require("chai");
const { ethers } = require("hardhat");
describe("Security Tests", function () {
it("Should prevent reentrancy attack", async function () {
const [attacker] = await ethers.getSigners();
const VictimBank = await ethers.getContractFactory("SecureBank");
const bank = await VictimBank.deploy();
const Attacker = await ethers.getContractFactory("ReentrancyAttacker");
const attackerContract = await Attacker.deploy(bank.address);
// Deposit funds
await bank.deposit({ value: ethers.utils.parseEther("10") });
// Attempt reentrancy attack
await expect(
attackerContract.attack({ value: ethers.utils.parseEther("1") }),
).to.be.revertedWith("ReentrancyGuard: reentrant call");
});
it("Should prevent integer overflow", async function () {
const Token = await ethers.getContractFactory("SecureToken");
const token = await Token.deploy();
// Attempt overflow
await expect(token.transfer(attacker.address, ethers.constants.MaxUint256))
.to.be.reverted;
});
it("Should enforce access control", async function () {
const [owner, attacker] = await ethers.getSigners();
const Contract = await ethers.getContractFactory("SecureContract");
const contract = await Contract.deploy();
// Attempt unauthorized withdrawal
await expect(contract.connect(attacker).withdraw(100)).to.be.revertedWith(
"Ownable: caller is not the owner",
);
});
});
監査の準備
contract WellDocumentedContract {
/**
* @title Well Documented Contract
* @dev Example of proper documentation for audits
* @notice This contract handles user deposits and withdrawals
*/
/// @notice Mapping of user balances
mapping(address => uint256) public balances;
/**
* @dev Deposits ETH into the contract
* @notice Anyone can deposit funds
*/
function deposit() public payable {
require(msg.value > 0, "Must send ETH");
balances[msg.sender] += msg.value;
}
/**
* @dev Withdraws user's balance
* @notice Follows CEI pattern to prevent reentrancy
* @param amount Amount to withdraw in wei
*/
function withdraw(uint256 amount) public {
// CHECKS
require(amount <= balances[msg.sender], "Insufficient balance");
// EFFECTS
balances[msg.sender] -= amount;
// INTERACTIONS
(bool success, ) = msg.sender.call{value: amount}("");
require(success, "Transfer failed");
}
}
コメント
Markdown 対応