Skip to content

33. Cyfrin Updraft: Foundry Deployment and Scripts

This external Cyfrin Updraft path teaches the professional way to ship a contract: reproducible, scripted deployment instead of one-off terminal commands. You’ll write a Foundry deploy script, move network-specific values into a HelperConfig so the same code deploys to a local Anvil chain or a public testnet, deploy mocks locally when a real dependency doesn’t exist, add interaction scripts and integration tests, and wrap it all in a Makefile. The recurring security rule threaded through it — never put a real private key in source, shell history, docs, or an AI prompt — is exactly the discipline your capstone deployment needs. The outline, code anatomy, and command flow below are a standalone guide; adapt the final “Capstone Application” steps to your Vendor or DEX.

Watch on Updraft

  • Create a deployment contract in script/DeployFundMe.s.sol.
  • Inherit from Foundry’s Script contract.
  • Use run() as the script entry point.
  • Wrap transactions with vm.startBroadcast() and vm.stopBroadcast().
  • Return the deployed contract so tests and other scripts can reuse it.

Key idea: a script makes deployment logic executable, testable, and repeatable instead of leaving it as a terminal-only command.

2. Refactoring Tests for Deployment Consistency · 7 min

Section titled “2. Refactoring Tests for Deployment Consistency · 7 min”

Watch on Updraft

  • Import the deployment script into the test suite.
  • Deploy the contract in setUp() through the same path used outside tests.
  • Remove differences between test deployment and real deployment.
  • Identify hardcoded external contract addresses that prevent local execution.

Key idea: tests should exercise the same constructor configuration and deployment path used by the application.

3. HelperConfig and Mock Price Feeds · 13 min

Section titled “3. HelperConfig and Mock Price Feeds · 13 min”

Watch on Updraft

  • Store network-specific addresses in a dedicated configuration contract.
  • Select configuration with block.chainid.
  • Use a real dependency address on a supported testnet.
  • Deploy a mock dependency when running against a blank local Anvil chain.
  • Pass the selected dependency into the application constructor.

Key idea: deployment scripts should choose dependencies by network without changing application source code.

4. Idempotent Local Mock Deployment · 8 min

Section titled “4. Idempotent Local Mock Deployment · 8 min”

Watch part one · Watch part two

  • Move mock creation into the configuration workflow.
  • Check for address(0) before deploying a new mock.
  • Reuse an existing local configuration when one is already available.
  • Avoid deploying duplicate dependencies each time configuration is read.

Key idea: an idempotent script can run repeatedly without creating unnecessary or inconsistent infrastructure.

5. Interaction Scripts and Integration Tests · 15 min

Section titled “5. Interaction Scripts and Integration Tests · 15 min”

Watch on Updraft

  • Create Interactions.s.sol with separate scripts for application actions.
  • Resolve the most recent deployment with foundry-devops.
  • Broadcast state-changing calls such as funding and withdrawal.
  • Separate unit tests from integration tests.
  • Test an end-to-end sequence that deploys, interacts, and checks final balances.
  • Understand why Foundry FFI requires special caution when enabled.

Key idea: interaction scripts are reusable operational clients for a deployed contract, while integration tests verify that those operations work together.

6. Automating Commands with a Makefile · 8 min

Section titled “6. Automating Commands with a Makefile · 8 min”

Watch on Updraft

  • Replace long, error-prone commands with named targets.
  • Add shortcuts for build, test, local deployment, and testnet deployment.
  • Load RPC and explorer configuration from environment variables.
  • Combine deployment, broadcast, and contract verification in a repeatable command.
  • Keep network-specific values out of committed source files.

Key idea: the Makefile becomes the documented command interface for the project’s common development and deployment operations.

Watch on Updraft

Explore conditional tests and deployment behavior across EVM and zkSync environments. This is optional for the course capstone unless zkSync is the selected deployment target.

Open the GitHub lesson

Review repository initialization, .gitignore, secret exclusion, and project publishing. The important security rule is to verify that .env, keystores, private keys, RPC credentials, and generated sensitive cache data are not committed.

Use this structure as a reading guide rather than code to paste without review:

import {Script} from "forge-std/Script.sol";
import {MyContract} from "../src/MyContract.sol";
contract DeployMyContract is Script {
function run() external returns (MyContract deployed) {
vm.startBroadcast();
deployed = new MyContract();
vm.stopBroadcast();
}
}

The script has four responsibilities:

  1. Import the contract and Foundry scripting tools.
  2. Resolve network-specific constructor inputs.
  3. Broadcast only the transactions that must be sent onchain.
  4. Return or record the deployed address for later interactions.
Terminal window
# Build and test before deployment
forge build
forge test
# Simulate the script without sending transactions
forge script script/DeployMyContract.s.sol:DeployMyContract --rpc-url "$RPC_URL"
# Broadcast only after reviewing the simulation
forge script script/DeployMyContract.s.sol:DeployMyContract \
--rpc-url "$RPC_URL" \
--account "$FOUNDRY_ACCOUNT" \
--sender "$DEPLOYER_ADDRESS" \
--broadcast

Use a Foundry keystore account or another secure signer workflow. Do not place a real private key in source files, shell history, documentation, or AI prompts.

  • The difference between script simulation and --broadcast.
  • Why run() is the standard Foundry script entry point.
  • Where deployment receipts and broadcast artifacts are stored.
  • How block.chainid selects network configuration.
  • When a local mock should replace a live external dependency.
  • How interaction scripts locate and call a deployed contract.
  • Why deployment, interaction, and integration testing are separate concerns.
  • How automation reduces manual errors without replacing transaction review.

Adapt the sequence to the Vendor or DEX project:

  1. Create one deployment script for the selected capstone contract.
  2. Move token, oracle, or network addresses into a configuration layer.
  3. Add local mocks only for dependencies that do not exist on Anvil.
  4. Create at least one interaction script for a core workflow such as buying, selling, adding liquidity, or swapping.
  5. Run unit and integration tests before any broadcast.
  6. Simulate the deployment, inspect the trace, and then deploy to the selected testnet.
  7. Record the contract address, chain ID, deployment transaction, constructor arguments, and verification status in the README.

Cyfrin Updraft: Foundry Fundamentals

Course segment: Foundry Fund Me, with a focus on reproducible deployment and interaction workflows.

Open Foundry Fundamentals on Updraft

This lesson is a curated path through several videos in the Foundry Fund Me section. The recommended core sequence is approximately 54 minutes. Course titles and durations were reviewed against Updraft in July 2026.

Module 5: Capstone.