Complete Solidity smart contract development - building, testing, gas optimization, and security scanning...
Comprehensive skill for EVM/Solidity smart contract development, combining build/test workflows, gas optimization, and security analysis.
.sol filesforge build
forge test
forge test -vvv # verbose
forge test --match-test "testSpecificFunction"
forge test --match-path test/SomeContract.t.sol
forge script script/Deploy.s.sol --broadcast --rpc-url $RPC_URL
forge buildforge test# Create baseline snapshot
forge snapshot --snap .gas-baseline
# Run gas report
forge test --gas-report
# Compare against baseline
forge snapshot --diff .gas-baseline
# Check specific function
forge test --match-test test_PlaceOrder --gas-report -vvv
# Storage layout analysis
forge inspect ContractName storage-layout --pretty
| Pattern | Savings | Example |
|---|---|---|
| Storage Packing | ~20,000 gas/slot | Combine uint128 + uint128 into single slot |
| Calldata vs Memory | ~60 gas/word | Use calldata for read-only arrays |
| Unchecked Math | ~40 gas/op | Use unchecked {} when overflow impossible |
| Cache Storage | ~100 gas/read | uint256 cached = storageVar; |
| Short-circuit | Variable | Put cheaper checks first in require |
| Avoid Zero Init | ~3 gas/var | Don't initialize to default values |
calldata for arraysunchecked incrementsassembly unless savings > 1000 gas# Full analysis
slither . --config-file slither.config.json
# Target specific contract
slither src/ContractName.sol
# Generate JSON report
slither . --json slither-report.json
# Run specific detector
slither . --detect reentrancy-eth
# Function summary
slither . --print function-summary
| Detector | Severity | Description |
|---|---|---|
reentrancy-eth |
HIGH | Reentrancy with ETH transfer |
reentrancy-no-eth |
HIGH | Reentrancy without ETH |
arbitrary-send-eth |
HIGH | Arbitrary ETH destination |
controlled-delegatecall |
HIGH | Delegatecall to user input |
suicidal |
HIGH | Selfdestruct with user control |
uninitialized-state |
HIGH | Uninitialized state variables |
// VULNERABLE
function withdraw() external {
uint256 amount = balances[msg.sender];
(bool success,) = msg.sender.call{value: amount}("");
balances[msg.sender] = 0; // State update AFTER external call
}
// FIXED
function withdraw() external nonReentrant {
uint256 amount = balances[msg.sender];
balances[msg.sender] = 0; // State update BEFORE external call
(bool success,) = msg.sender.call{value: amount}("");
}
// VULNERABLE
function setPrice(uint256 price) external {
currentPrice = price; // No access control
}
// FIXED
function setPrice(uint256 price) external onlyOwner {
currentPrice = price;
}
forge build compiles without warningsforge test passes with >80% coverage