This document describes the WASM artifact integrity verification process for ACBU smart contracts. This is a critical security control to prevent supply chain attacks through WASM substitution.
Severity: Medium
Area: contracts/build
Affected Contracts: acbu_minting, acbu_burning, acbu_reserve_tracker
Risk: Integrity not verified; supply chain risk
The token WASM contract (soroban_token_contract.wasm) is imported by three critical contracts using the Soroban SDK's contractimport! macro. Without proper hash verification, an attacker could:
- Replace the WASM artifact with a malicious version
- Modify the artifact during build or deployment
- Inject unauthorized token operations (mint, burn, transfer)
- Compromise the entire ACBU ecosystem
Token WASM Hash: 8331ad752af7ff986f2b9497ac7383c57020bfc80ba19541f4142fc94d1348c1
This hash is pinned in two locations:
build.rs-EXPECTED_HASHconstant (verified at compile time)acbu_minting/src/lib.rs-contractimport!macro sha256 field
Note: acbu_burning and acbu_reserve_tracker interact with the token contract
via cross-contract call interfaces and do not embed the WASM directly, so they
do not carry a contractimport! sha256 pin.
File: build.rs
The Rust build script runs before compilation and:
- Verifies the WASM file exists
- Checks hash consistency across all contract imports
- Fails the build if any hash mismatches are detected
Behavior: Build fails immediately if integrity check fails
File: .github/workflows/verify-wasm-integrity.yml
GitHub Actions workflow runs on:
- Push to main/develop branches
- Pull requests affecting WASM or contract imports
- Changes to Cargo.lock
Verification Steps:
- Verify WASM artifact hash matches expected value
- Verify hash consistency across all three contracts
- Check for WASM modifications in git history
- Build all contracts with hash verification
- Verify all build artifacts are generated
- Upload artifacts for deployment verification
File: scripts/verify_wasm_hash.sh
Pre-deployment script that:
- Verifies WASM artifact integrity before deployment
- Fails fast if hash mismatches
- Provides clear error messages for remediation
Usage:
./scripts/verify_wasm_hash.shBefore building locally:
# Verify WASM integrity
bash scripts/verify_wasm_hash.sh
# Build contracts (build.rs will also verify)
cargo build --target wasm32-unknown-unknown --releaseThe GitHub Actions workflow automatically:
- Verifies WASM hash on every push/PR
- Builds all contracts with verification
- Uploads artifacts for audit trail
- Fails the build if any check fails
Before deploying to testnet/mainnet:
# Verify WASM integrity
bash scripts/verify_wasm_hash.sh
# Deploy contracts
./scripts/deploy_testnet.shIf the token contract is intentionally updated:
sha256sum soroban_token_contract.wasmbuild.rs — EXPECTED_HASH constant:
const EXPECTED_HASH: &str = "NEW_HASH_HERE";acbu_minting/src/lib.rs — contractimport! macro:
#[allow(dead_code)]
pub mod token_contract {
soroban_sdk::contractimport!(
file = "../soroban_token_contract.wasm",
sha256 = "NEW_HASH_HERE"
);
}Note: acbu_burning and acbu_reserve_tracker do not embed the WASM via
contractimport!, so no changes are needed in those contracts.
scripts/verify_wasm_hash.sh:
EXPECTED_HASH="NEW_HASH_HERE".github/workflows/verify-wasm-integrity.yml:
EXPECTED_HASH="NEW_HASH_HERE"Run the automated verification script before building:
# Automated script verifies hash across all contracts and fails fast on mismatch
./scripts/verify_wasm_hash.sh
# Build will also verify hashes via build.rs
cargo build --target wasm32-unknown-unknown --releaseCI will re-run the same checks automatically via .github/workflows/verify-wasm-integrity.yml on push/PR.
- Include the new WASM artifact
- Include all hash updates
- Document the reason for the update
- Require security review before merge
✅ Build fails if hash mismatches artifact
build.rsverifies hash consistency before compilation- CI/CD pipeline verifies WASM hash on every push/PR
- Deployment script verifies hash before deployment
✅ Hash is pinned and consistent
build.rsEXPECTED_HASH:8331ad752af7ff986f2b9497ac7383c57020bfc80ba19541f4142fc94d1348c1acbu_minting/src/lib.rscontractimport!sha256:8331ad752af7ff986f2b9497ac7383c57020bfc80ba19541f4142fc94d1348c1acbu_burningandacbu_reserve_trackerdo not usecontractimport!and are not affected
✅ Verification happens at multiple stages
- Build time:
build.rs - CI/CD: GitHub Actions workflow
- Pre-deployment:
verify_wasm_hash.sh
✅ Clear error messages for failures
- Explains the supply chain risk
- Provides remediation steps
- Prevents accidental deployment of compromised artifacts
- WASM Substitution Attacks: Prevents deployment of modified token contracts
- Build-Time Tampering: Detects changes to WASM artifact during build
- Repository Compromise: Catches unauthorized WASM modifications in git
- Deployment Errors: Prevents accidental deployment of wrong artifact version
- Source Code Compromise: If the WASM source is compromised, the hash will be updated accordingly
- Private Key Compromise: If deployment credentials are compromised, attacker can still deploy
- Network-Level Attacks: Does not protect against MITM attacks during deployment
- Soroban SDK Vulnerabilities: Does not protect against vulnerabilities in the SDK itself
This verification is one layer of defense. Additional security measures:
- Code Review: All WASM updates require security review
- Audit Trail: Git history tracks all WASM changes
- Access Control: Restrict who can merge WASM changes
- Deployment Authorization: Require approval for mainnet deployments
- Monitoring: Monitor contract behavior post-deployment
Cause: soroban_token_contract.wasm is missing from project root
Solution:
# Verify file exists
ls -la soroban_token_contract.wasm
# If missing, restore from git
git checkout soroban_token_contract.wasmCause: WASM artifact has been modified or replaced
Solution:
- Verify the source of the WASM file
- If intentionally updated, update all three contract imports with new hash
- Run verification script to confirm
Cause: Contract imports have inconsistent hashes
Solution:
- Ensure all three contracts use the same hash
- Run
cargo buildlocally to verify - Check git diff for hash inconsistencies