AgentStack
SKILL verified MIT Self-run

Solidity Deploy

skill-comeonoliver-skillshub-solidity-deploy · by ComeOnOliver

[AUTO-INVOKE] MUST be invoked BEFORE deploying contracts or writing deployment scripts (*.s.sol). Covers pre-flight checks, forge script commands, post-deployment validation, and verification. Trigger: any task involving forge script, contract deployment, or block explorer verification.

No reviews yet
0 installs
16 views
0.0% view→install

Install

$ agentstack add skill-comeonoliver-skillshub-solidity-deploy

✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets Used
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

Are you the author of Solidity Deploy? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

Deployment Workflow

Language Rule

  • Always respond in the same language the user is using. If the user asks in Chinese, respond in Chinese. If in English, respond in English.

Pre-deployment Checklist (all must pass)

| Step | Command / Action | |------|-----------------| | Format code | forge fmt | | Run all tests | forge test — zero failures required | | Check gas report | forge test --gas-report — review critical functions | | Verify config | Manually check config/*.json parameters | | Dry-run | forge script --fork-url -vvvv (no --broadcast) | | Check balance | cast balance --rpc-url — sufficient gas? | | Gas limit set | Deployment command must include --gas-limit |

Deployment Decision Rules

| Situation | Rule | |-----------|------| | Default deployment | No --verify — contracts are not verified on block explorers by default | | User requests verification | Add --verify and --etherscan-api-key to the command | | Post-deploy verification | Use forge verify-contract as a separate step | | Multi-chain deploy | Separate scripts per chain, never batch multiple chains in one script | | Proxy deployment | Deploy implementation first, then proxy — verify both separately | | Upgradeable contract | Use OpenZeppelin Upgrades Plugin (see below) — never hand-roll proxy deployment |

Post-deployment Operations (all required)

  1. Update addresses in config/*.json and deployments/latest.env
  2. Test critical functions: cast call to verify on-chain state is correct
  3. Record changes in docs/CHANGELOG.md
  4. Submit PR with deployment transaction hash link
  5. If verification needed, run forge verify-contract separately

Key Security Rule

  • Never pass private keys directly in commands. Use Foundry Keystore (cast wallet import) to manage keys securely.
  • Never include --broadcast in templates. The user must explicitly add it when ready to deploy.

Command Templates

# Dry-run (simulation only, no on-chain execution)
forge script script/Deploy.s.sol:DeployScript \
  --rpc-url  \
  --gas-limit 5000000 \
  -vvvv

# When user is ready to deploy, instruct them to add:
#   --account  --broadcast

# Verify existing contract separately
forge verify-contract   \
  --chain-id  \
  --etherscan-api-key  \
  --constructor-args $(cast abi-encode "constructor(address)" )

# Quick on-chain read test after deployment
cast call  "functionName()" --rpc-url 

Upgradeable Contract Deployment (OpenZeppelin Upgrades Plugin)

For any upgradeable contract (UUPS, Transparent, Beacon), use the OpenZeppelin Foundry Upgrades Plugin instead of hand-rolling proxy deployment scripts.

Why Use the Plugin

| Manual Approach | With Plugin | |---|---| | ~30 lines: deploy impl → deploy proxy → encode initializer → wire up | 1 line: Upgrades.deployUUPSProxy(...) | | ~20 lines: deploy new impl → validate storage → upgrade proxy | 1 line: Upgrades.upgradeProxy(...) | | Storage layout compatibility: check by eye | Auto-checked, incompatible layouts are rejected | | Forgot _disableInitializers()? No warning | Auto-validated |

Installation

forge install OpenZeppelin/openzeppelin-foundry-upgrades
forge install OpenZeppelin/openzeppelin-contracts-upgradeable

Add to remappings.txt:

@openzeppelin/contracts/=lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/
@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/

Deploy Script Template (UUPS)

// script/Deploy.s.sol
import {Script, console} from "forge-std/Script.sol";
import {Upgrades} from "openzeppelin-foundry-upgrades/Upgrades.sol";
import {MyContract} from "../src/MyContract.sol";

contract DeployScript is Script {
    function run() public {
        vm.startBroadcast();

        // One line: deploys impl + proxy + calls initialize
        address proxy = Upgrades.deployUUPSProxy(
            "MyContract.sol",
            abi.encodeCall(MyContract.initialize, (msg.sender))
        );

        console.log("Proxy:", proxy);
        console.log("Impl:", Upgrades.getImplementationAddress(proxy));

        vm.stopBroadcast();
    }
}

Upgrade Script Template

// script/Upgrade.s.sol
import {Script, console} from "forge-std/Script.sol";
import {Upgrades} from "openzeppelin-foundry-upgrades/Upgrades.sol";

contract UpgradeScript is Script {
    function run() public {
        address proxy = vm.envAddress("PROXY_ADDRESS");
        vm.startBroadcast();

        // One line: validates storage layout + deploys new impl + upgrades proxy
        Upgrades.upgradeProxy(proxy, "MyContractV2.sol", "");

        console.log("Upgraded. New impl:", Upgrades.getImplementationAddress(proxy));

        vm.stopBroadcast();
    }
}

Add @custom:oz-upgrades-from MyContract annotation to V2 contract for automatic reference:

/// @custom:oz-upgrades-from MyContract
contract MyContractV2 is Initializable, OwnableUpgradeable, UUPSUpgradeable {
    // ...
}

Commands

# Deploy proxy (dry-run) — --ffi is required for storage layout checks
forge script script/Deploy.s.sol --rpc-url  --ffi -vvvv

# Deploy proxy (broadcast)
forge script script/Deploy.s.sol --rpc-url  --ffi --account  --broadcast

# Upgrade proxy (dry-run)
PROXY_ADDRESS=0x... forge script script/Upgrade.s.sol --rpc-url  --ffi -vvvv

# Upgrade proxy (broadcast)
PROXY_ADDRESS=0x... forge script script/Upgrade.s.sol --rpc-url  --ffi --account  --broadcast

# Validate upgrade without deploying (useful for CI)
# Use Upgrades.validateUpgrade("MyContractV2.sol", opts) in a test

Plugin API Quick Reference

| Function | Purpose | |---|---| | Upgrades.deployUUPSProxy(contract, data) | Deploy UUPS proxy + impl + initialize | | Upgrades.deployTransparentProxy(contract, admin, data) | Deploy Transparent proxy + impl + initialize | | Upgrades.upgradeProxy(proxy, newContract, data) | Validate + deploy new impl + upgrade | | Upgrades.validateUpgrade(contract, opts) | Validate only, no deploy (for CI/tests) | | Upgrades.getImplementationAddress(proxy) | Get current implementation address | | Upgrades.prepareUpgrade(contract, opts) | Validate + deploy new impl, return address (for multisig) |

Key Rules

  • Always use --ffi flag — the plugin needs it for storage layout validation
  • Always add --sender for upgrades — must match proxy owner, otherwise OwnableUnauthorizedAccount
  • Use Upgrades in scripts, UnsafeUpgrades only in testsUnsafeUpgrades skips all safety checks
  • Keep V1 source code in project when upgrading — plugin needs it for storage comparison. Or use @custom:oz-upgrades-from annotation
  • Never hand-roll proxy deployment when this plugin is available — the storage layout check alone prevents critical bugs

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet — be the first.

Versions

  • v0.1.0 Imported from the upstream source.