Deployment Guide

Overview

This guide provides detailed instructions for deploying the Riskify protocol, including smart contracts, ML models, and monitoring infrastructure.

Prerequisites

1. Environment Setup

# Install development dependencies
npm install -g hardhat
npm install -g truffle
npm install -g ganache-cli

# Install Python dependencies
pip install -r requirements.txt

# Install monitoring tools
npm install -g pm2

2. Configuration Files

# config/deployment.yaml
network:
  mainnet:
    rpc_url: "https://mainnet.infura.io/v3/YOUR-PROJECT-ID"
    chain_id: 1
    gas_price_strategy: "medium"
  testnet:
    rpc_url: "https://goerli.infura.io/v3/YOUR-PROJECT-ID"
    chain_id: 5
    gas_price_strategy: "fast"

contracts:
  pool_factory:
    address: "0x..."
    constructor_args:
      admin: "0x..."
      fee_collector: "0x..."
  
  ml_optimizer:
    address: "0x..."
    constructor_args:
      model_registry: "0x..."
      update_interval: 3600

monitoring:
  grafana_url: "http://localhost:3000"
  prometheus_url: "http://localhost:9090"
  alert_webhook: "https://alerts.example.com/webhook"

Smart Contract Deployment

1. Contract Compilation

# Compile contracts
npx hardhat compile

# Run tests
npx hardhat test

# Generate deployment artifacts
npx hardhat run scripts/generate-deployment.js

2. Deployment Script

// scripts/deploy.ts
import { ethers } from "hardhat";
import { DeploymentConfig } from "../types";

async function main() {
    // Load configuration
    const config = loadConfig();
    
    // Deploy Pool Factory
    const PoolFactory = await ethers.getContractFactory("PoolFactory");
    const poolFactory = await PoolFactory.deploy(
        config.contracts.pool_factory.constructor_args.admin,
        config.contracts.pool_factory.constructor_args.fee_collector
    );
    await poolFactory.deployed();
    
    // Deploy ML Optimizer
    const MLOptimizer = await ethers.getContractFactory("MLOptimizer");
    const mlOptimizer = await MLOptimizer.deploy(
        config.contracts.ml_optimizer.constructor_args.model_registry,
        config.contracts.ml_optimizer.constructor_args.update_interval
    );
    await mlOptimizer.deployed();
    
    // Initialize contracts
    await initializeContracts(poolFactory, mlOptimizer);
    
    // Verify contracts
    await verifyContracts(poolFactory, mlOptimizer);
}

main()
    .then(() => process.exit(0))
    .catch(error => {
        console.error(error);
        process.exit(1);
    });

3. Contract Verification

// scripts/verify.ts
async function verifyContracts(
    poolFactory: Contract,
    mlOptimizer: Contract
) {
    // Verify Pool Factory
    await hre.run("verify:verify", {
        address: poolFactory.address,
        constructorArguments: [
            config.contracts.pool_factory.constructor_args.admin,
            config.contracts.pool_factory.constructor_args.fee_collector
        ],
    });
    
    // Verify ML Optimizer
    await hre.run("verify:verify", {
        address: mlOptimizer.address,
        constructorArguments: [
            config.contracts.ml_optimizer.constructor_args.model_registry,
            config.contracts.ml_optimizer.constructor_args.update_interval
        ],
    });
}

ML Model Deployment

1. Model Export

# scripts/export_model.py
from riskify.ml.models import RiskAssessmentModel
from riskify.ml.export import ModelExporter

def export_models():
    # Export risk assessment model
    risk_model = RiskAssessmentModel.load("models/risk_assessment.pt")
    exporter = ModelExporter()
    exporter.export_model(
        model=risk_model,
        path="models/risk_assessment.onnx"
    )
    
    # Export optimization model
    optimization_model = PoolOptimizationModel.load("models/optimization.pt")
    exporter.export_model(
        model=optimization_model,
        path="models/optimization.onnx"
    )

if __name__ == "__main__":
    export_models()

2. Model Registry Update

// scripts/update_registry.ts
async function updateModelRegistry() {
    const registry = await ethers.getContractAt(
        "ModelRegistry",
        config.contracts.model_registry.address
    );
    
    // Update risk assessment model
    await registry.updateModel(
        "risk_assessment",
        "ipfs://Qm...",  // IPFS hash of the model
        1,               // Version
        true            // Active
    );
    
    // Update optimization model
    await registry.updateModel(
        "optimization",
        "ipfs://Qm...",  // IPFS hash of the model
        1,               // Version
        true            // Active
    );
}

Monitoring Setup

1. Prometheus Configuration

# prometheus/prometheus.yml
global:
  scrape_interval: 15s
  evaluation_interval: 15s

scrape_configs:
  - job_name: 'riskify'
    static_configs:
      - targets: ['localhost:8080']
    metrics_path: '/metrics'

2. Grafana Dashboard

{
  "dashboard": {
    "id": null,
    "title": "Riskify Metrics",
    "panels": [
      {
        "title": "Pool TVL",
        "type": "graph",
        "datasource": "Prometheus",
        "targets": [
          {
            "expr": "riskify_pool_tvl",
            "legendFormat": "{{pool_id}}"
          }
        ]
      },
      {
        "title": "Risk Scores",
        "type": "graph",
        "datasource": "Prometheus",
        "targets": [
          {
            "expr": "riskify_risk_score",
            "legendFormat": "{{pool_id}}"
          }
        ]
      }
    ]
  }
}

3. Alert Rules

# prometheus/rules/alerts.yml
groups:
  - name: riskify
    rules:
      - alert: HighRiskScore
        expr: riskify_risk_score > 0.8
        for: 5m
        labels:
          severity: critical
        annotations:
          summary: High risk score detected
          
      - alert: LowTVL
        expr: riskify_pool_tvl < 1000
        for: 15m
        labels:
          severity: warning
        annotations:
          summary: Low TVL detected

Infrastructure Setup

1. Docker Compose

# docker-compose.yml
version: '3.8'

services:
  contracts:
    build:
      context: .
      dockerfile: Dockerfile.contracts
    environment:
      - NETWORK=mainnet
      - PRIVATE_KEY=${DEPLOYER_PRIVATE_KEY}
    volumes:
      - ./contracts:/app/contracts
      
  ml-service:
    build:
      context: .
      dockerfile: Dockerfile.ml
    environment:
      - MODEL_REGISTRY_ADDRESS=${MODEL_REGISTRY_ADDRESS}
    volumes:
      - ./models:/app/models
      
  monitoring:
    build:
      context: .
      dockerfile: Dockerfile.monitoring
    ports:
      - "3000:3000"  # Grafana
      - "9090:9090"  # Prometheus
    volumes:
      - ./prometheus:/etc/prometheus
      - ./grafana:/var/lib/grafana

2. Kubernetes Deployment

# k8s/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: riskify
spec:
  replicas: 3
  selector:
    matchLabels:
      app: riskify
  template:
    metadata:
      labels:
        app: riskify
    spec:
      containers:
      - name: contracts
        image: riskify/contracts:latest
        env:
        - name: NETWORK
          value: mainnet
          
      - name: ml-service
        image: riskify/ml:latest
        env:
        - name: MODEL_REGISTRY_ADDRESS
          valueFrom:
            configMapKeyRef:
              name: riskify-config
              key: model_registry_address
              
      - name: monitoring
        image: riskify/monitoring:latest
        ports:
        - containerPort: 3000
        - containerPort: 9090

Deployment Checklist

  1. Pre-deployment

    • Run full test suite
    • Audit contracts
    • Validate configurations
    • Check gas estimates
  2. Deployment

    • Deploy contracts
    • Verify on Etherscan
    • Export and register models
    • Set up monitoring
  3. Post-deployment

    • Validate contract states
    • Check model predictions
    • Verify monitoring alerts
    • Document addresses

Emergency Procedures

1. Contract Pause

async function pauseSystem() {
    const poolFactory = await ethers.getContractAt(
        "PoolFactory",
        config.contracts.pool_factory.address
    );
    
    await poolFactory.pause();
    console.log("System paused");
}

2. Model Fallback

async function enableFallbackModel() {
    const mlOptimizer = await ethers.getContractAt(
        "MLOptimizer",
        config.contracts.ml_optimizer.address
    );
    
    await mlOptimizer.enableFallback();
    console.log("Fallback model enabled");
}

Maintenance

1. Contract Upgrades

async function upgradeContract() {
    const proxyAdmin = await ethers.getContractAt(
        "ProxyAdmin",
        config.contracts.proxy_admin.address
    );
    
    const newImplementation = await deployNewImplementation();
    await proxyAdmin.upgrade(
        config.contracts.pool_factory.address,
        newImplementation.address
    );
}

2. Model Updates

async function updateModel() {
    const registry = await ethers.getContractAt(
        "ModelRegistry",
        config.contracts.model_registry.address
    );
    
    await registry.updateModel(
        "risk_assessment",
        "ipfs://Qm...",  // New model hash
        2,               // New version
        true            // Active
    );
}