TLaaS (LEX) — CI/CD Pipeline: Automating Compilation, Testing & Deployment

1. Purpose

Establish a cryptographically verifiable, reproducible CI/CD pipeline for TLaaS (LEX) smart contracts, DApp, and supporting services. The pipeline must provide: deterministic builds, automated unit/integration/fuzz testing, formal checks, supply-chain security (SLSA) attestations, staged deployments (local → testnet → staging → mainnet), governance‑aware approvals, and post‑deploy monitoring hooks. Integrations include TLAAS (DLA) validation gates and DAL governance signals to gate production rollouts.

2. Architectural Overview

  • Source Control: GitHub (repo:
  • CI Runners: GitHub Actions + self‑hosted runners for private networks.
  • Build System: Hardhat (contracts), Node/PNPM (DApp), Docker for deterministic packaging.
  • Security Tooling: Slither, Mythril, Echidna, Foundry fuzz, Semgrep, npm‑audit.
  • Supply Chain: Sigstore/Cosign for image & artifact signing; SLSA provenance.
  • Secrets: GitHub OIDC to cloud KMS (AWS KMS / GCP KMS) + repository environments for staged secrets.
  • Environments:
  • Approvals: DAL‑backed governance check before

3. Deterministic Build Configuration

  • Solc: Pin exact compiler (
  • Node: Pin Node (e.g.,
  • Docker: Build in container to eliminate host variance; export SBOM.

hardhat.config.ts (excerpt)

import "@nomicfoundation/hardhat-toolbox";
import "@openzeppelin/hardhat-upgrades";
import { HardhatUserConfig } from "hardhat/config";

const config: HardhatUserConfig = {
  solidity: {
    version: "0.8.24",
    settings: {
      optimizer: { enabled: true, runs: 20000 },
      metadata: { bytecodeHash: "ipfs" }
    }
  },
  networks: {
    hardhat: { forking: { url: process.env.MAINNET_RPC ?? "", blockNumber: 19700000 } },
    sepolia: { url: process.env.SEPOLIA_RPC!, accounts: [process.env.DEPLOYER!] },
    mainnet: { url: process.env.MAINNET_RPC!, accounts: [process.env.DEPLOYER!] }
  },
  etherscan: { apiKey: { mainnet: process.env.ETHERSCAN!, sepolia: process.env.ETHERSCAN! } },
  mocha: { timeout: 120000 }
};
export default config;

4. Repository Policies

  • CODEOWNERS: Enforce reviews from
  • Conventional Commits + semantic‑release for versions/tags.
  • Branch Protection: Required checks (lint, test, fuzz, slither) and signed commits.
  • DCO: Developer Certificate of Origin.

.github/CODEOWNERS

/contracts/*   @protocol-team @security-team
/deploy/*      @protocol-team @devops
/scripts/*     @protocol-team @devops

5. CI Workflow (GitHub Actions)

.github/workflows/ci.yml

name: CI
on:
  pull_request:
    branches: [ develop, main ]
  push:
    branches: [ develop ]
permissions:
  contents: read
  id-token: write
  attestations: write
jobs:
  build-test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with: { node-version: '20', cache: 'pnpm' }
      - uses: pnpm/action-setup@v4
        with: { version: 9 }
      - name: Install deps
        run: pnpm i --frozen-lockfile
      - name: Compile
        run: pnpm hardhat compile
      - name: Lint (solhint, eslint)
        run: pnpm lint
      - name: Unit tests
        run: pnpm test
      - name: Coverage
        run: pnpm hardhat coverage --testfiles "test/**/*.ts"
      - name: Slither static analysis
        uses: crytic/[email protected]
        with:
          slither-config: .slither.json
      - name: Echidna fuzz (smoke)
        run: |
          docker run --rm -v $PWD:/src trailofbits/eth-security-toolbox:latest \
            bash -lc "echidna-test . --contract LicenseMarketplace --config echidna.yml || true"
      - name: SBOM (syft)
        run: |
          curl -sSfL https://raw.githubusercontent.com/anchore/syft/main/install.sh | sh -s -- -b . v1.5.0
          ./syft packages dir:. -o spdx-json > sbom.spdx.json
      - name: Attest build (SLSA)
        uses: slsa-framework/[email protected]
        with:
          base64-subjects: true

Static Analysis Configs

  • .slither.json

6. CD Workflow (Staged Deployments)

.github/workflows/cd.yml

name: CD
on:
  workflow_dispatch:
    inputs:
      network:
        description: 'testnet|staging|mainnet'
        required: true
        default: 'testnet'
  push:
    branches: [ main ]
permissions:
  contents: read
  id-token: write
  deployments: write
  attestations: write
jobs:
  deploy:
    runs-on: ubuntu-latest
    environment: ${{ github.event.inputs.network || 'staging' }}
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with: { node-version: '20', cache: 'pnpm' }
      - uses: pnpm/action-setup@v4
        with: { version: 9 }
      - name: Install deps
        run: pnpm i --frozen-lockfile
      - name: Build
        run: pnpm hardhat compile
      - name: DAL governance gate (mainnet)
        if: ${{ inputs.network == 'mainnet' }}
        run: node scripts/check-dal-approval.js --proposal ${{ secrets.DAL_PROPOSAL_ID }}
      - name: Deploy
        run: pnpm ts-node deploy/01_orchestrator.ts --network ${{ inputs.network }}
      - name: Verify on explorer
        run: pnpm hardhat verify --network ${{ inputs.network }} $(cat ./artifacts/addresses/${{ inputs.network }}/PaymentOrchestrator.json | jq -r .address)
      - name: Generate release notes
        uses: softprops/action-gh-release@v2
        with:
          tag_name: v${{ github.run_number }}
          name: TLaaS LEX Release ${{ github.run_number }}
          draft: false
          prerelease: ${{ inputs.network != 'mainnet' }}

Environment Protections

  • staging
  • mainnet

7. Deployment Scripts (TypeScript)

deploy/01_orchestrator.ts

import { ethers } from "hardhat";
import fs from "fs";
async function main() {
  const [deployer] = await ethers.getSigners();
  const Orchestrator = await ethers.getContractFactory("PaymentOrchestrator");
  const orchestrator = await Orchestrator.deploy(
    process.env.WETH!, process.env.TREASURY!, process.env.ROUTER!, process.env.COMPLIANCE!, process.env.FX!, process.env.FEEMODULE!
  );
  await orchestrator.waitForDeployment();
  const addr = await orchestrator.getAddress();
  console.log("PaymentOrchestrator:", addr);
  fs.mkdirSync(`artifacts/addresses/${process.env.NETWORK}`, { recursive: true });
  fs.writeFileSync(`artifacts/addresses/${process.env.NETWORK}/PaymentOrchestrator.json`, JSON.stringify({ address: addr }, null, 2));
}
main().catch((e) => { console.error(e); process.exit(1); });

scripts/check-dal-approval.js (DAL Gate)

const { getDalApproval } = require('./dal-client');
(async () => {
  const proposalId = process.argv.pop();
  const ok = await getDalApproval(proposalId);
  if (!ok) { console.error('DAL approval missing'); process.exit(1); }
  console.log('DAL approval verified');
})();

8. Security Gates & Policies

  • Upgradeable Safety: Use OpenZeppelin Upgrades plugin; require
  • Timelocks: Production admin actions pass through timelock + Safe.
  • Kill Switch: Emergency pause via multi‑sig + DAL signal; monitored by alerting.
  • Key Rotation: Quarterly rotation for deployer and relayers; attest via audit log.

Storage Layout Check (hardhat)

pnpm hardhat storage:verify --contract contracts/PaymentOrchestrator.sol:PaymentOrchestrator

9. Formal & Fuzz Testing

  • Echidna: invariants (no asset loss; escrow invariant; reentrancy‑free routes).
  • Foundry: property tests with randomization, mainnet‑fork shadow tests.
  • Mythril: symbolic execution for reentrancy, tx‑ordering issues.
  • Slither: detectors + custom detectors for DAL/TLAAS hooks.

foundry.toml

[profile.default]
src = 'contracts'
out = 'out'
libs = ['lib']
optimizer = true
optimizer_runs = 20000

Echidna Invariant (snippet)

contract Invariants {
  PaymentOrchestrator internal p;
  function echidna_no_unexpected_sweep() public view returns (bool) {
    // treasury balance must increase or stay the same after payments
    return true; // implement delta tracking in harness
  }
}

10. Supply-Chain Security & Provenance

  • SBOM: Generate SPDX JSON via Syft; store with release assets.
  • Provenance Attestations: SLSA v1.0 builder with OIDC identity; cosign sign images and artifacts.
  • Dependency Pinning: exact versions in
  • Rebuild Verification: Nightly job recompiles and byte‑compares deployed artifact hashes.

cosign (example)

cosign sign-blob --key $KMS_KEY artifacts/addresses/mainnet/PaymentOrchestrator.json
cosign verify-blob --key $KMS_PUB artifacts/addresses/mainnet/PaymentOrchestrator.json --signature sig.cosign

11. Observability & Post-Deploy Checks

  • On-chain Health: scrape events (
  • Dashboards: Grafana + Prometheus for indexer nodes; Blocknative/Alchemy alerts for tx failures.
  • Anomaly Detection: Trigger alerts for abnormal fee splits, DAL freezes, or validator slashes.
  • Runbooks: Incident response playbooks bound to pager rotations.

12. Governance-Linked Release Management

  • Release Tags: include DAL proposal id and EIP‑712 domain salt in release notes.
  • Changelog: auto‑generated conventional commits.
  • Upgrade Plan: announce timelock ETA; provide storage layout diff; attach audit deltas.

13. Local Developer UX (Makefile)

.PHONY: init test fuzz fork deploy-staging
init: ; pnpm i --frozen-lockfile && pnpm hardhat compile
fork: ; pnpm hardhat node --fork $(MAINNET_RPC)
test: ; pnpm hardhat test
fuzz: ; forge test -vvv
deploy-staging: ; NETWORK=staging pnpm ts-node deploy/01_orchestrator.ts

14. Compliance & Legal Artifacts

  • Attestation Bundle: attach SBOM, audit reports, prover logs to each release.
  • Jurisdiction Maps: include compiled rule tables used by fee/renewal modules.
  • Data Retention: retain CI logs and artifacts for 7 years (configurable) for auditability.

15. Acceptance Criteria

  • Reproducible builds (byte‑equal) across runners.
  • 95%+ unit coverage, passing fuzz/property tests.
  • No critical Slither/Mythril findings; medium findings triaged.
  • DAL approval enforced for
  • Post‑deploy verification and event heartbeat green for 24h.

Next Article: Proxy Upgradability Patterns — Delegate‑Call Proxies for Contract Upgrades

Was this article helpful?

TLaaS (DLA) — Purpose, Scope & Economic Model
TLaaS (LEX) — Compliance & Audit Logging: Building Automated Event Logging and AI Fraud Detection