cyberia-token/scripts/setup-dao-governance.ts

import { ethers } from "hardhat";
import deployments from "../deployments.json";

async function main() {
  const network = "sepolia";
  const deployment = deployments.deployments[network];

  if (!deployment) {
    throw new Error(`No deployment found for network: ${network}`);
  }

  const [signer] = await ethers.getSigners();
  console.log("๐Ÿ” Connected wallet:", signer.address);
  console.log("");

  // Get addresses from environment
  const daoAddress = process.env.ARAGON_DAO_ADDRESS;
  const pluginAddress = process.env.CAP_GOVERNANCE_PLUGIN_ADDRESS;
  const capTokenAddress = deployment.proxyAddress;

  if (!daoAddress || !pluginAddress) {
    throw new Error("ARAGON_DAO_ADDRESS or CAP_GOVERNANCE_PLUGIN_ADDRESS not set in .env");
  }

  console.log("๐Ÿ“‹ Configuration:");
  console.log("โ”œโ”€ CAP Token:", capTokenAddress);
  console.log("โ”œโ”€ Aragon DAO:", daoAddress);
  console.log("โ””โ”€ Governance Plugin:", pluginAddress);
  console.log("");

  // Get CAP token contract
  const cap = await ethers.getContractAt("CAPToken", capTokenAddress);

  // =============================================================================
  // STEP 1: Check and Transfer Ownership
  // =============================================================================
  console.log("โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”");
  console.log("STEP 1: Transfer Token Ownership to DAO");
  console.log("โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”");

  const currentOwner = await cap.owner();
  console.log("Current owner:", currentOwner);
  console.log("Target DAO:", daoAddress);

  if (currentOwner.toLowerCase() === daoAddress.toLowerCase()) {
    console.log("โœ… DAO already owns the token!");
  } else if (currentOwner.toLowerCase() === signer.address.toLowerCase()) {
    console.log("");
    console.log("๐Ÿ”„ Transferring ownership to DAO...");
    const tx = await cap.transferOwnership(daoAddress);
    console.log("๐Ÿ“ค Transaction sent:", tx.hash);

    await tx.wait();
    console.log("โœ… Ownership transferred successfully!");

    // Verify
    const newOwner = await cap.owner();
    console.log("โœ… Verified new owner:", newOwner);
    console.log("");
    console.log("โš ๏ธ  IMPORTANT: All admin functions now require DAO governance!");
  } else {
    console.log("โŒ ERROR: You are not the current owner!");
    console.log(`   Current owner: ${currentOwner}`);
    console.log(`   Your address: ${signer.address}`);
    console.log("");
    console.log("โญ๏ธ  Skipping ownership transfer...");
  }

  console.log("");

  // =============================================================================
  // STEP 2: Delegate Voting Power
  // =============================================================================
  console.log("โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”");
  console.log("STEP 2: Activate Voting Power");
  console.log("โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”");

  // Check current delegation
  const currentDelegate = await cap.delegates(signer.address);
  console.log("Current delegate:", currentDelegate);

  if (currentDelegate.toLowerCase() === signer.address.toLowerCase()) {
    console.log("โœ… Voting power already activated (self-delegated)!");
  } else {
    console.log("");
    console.log("๐Ÿ—ณ๏ธ  Self-delegating to activate voting power...");
    const tx = await cap.delegate(signer.address);
    console.log("๐Ÿ“ค Transaction sent:", tx.hash);

    await tx.wait();
    console.log("โœ… Voting power activated!");
  }

  // Check voting power
  const balance = await cap.balanceOf(signer.address);
  const votes = await cap.getVotes(signer.address);

  console.log("");
  console.log("๐Ÿ“Š Your Voting Power:");
  console.log("โ”œโ”€ Balance:", ethers.formatEther(balance), "CAP");
  console.log("โ””โ”€ Votes:", ethers.formatEther(votes), "CAP");

  console.log("");

  // =============================================================================
  // STEP 3: Display Current Token State
  // =============================================================================
  console.log("โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”");
  console.log("STEP 3: Current Token State");
  console.log("โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”");

  const totalSupply = await cap.totalSupply();
  const owner = await cap.owner();
  const feeRecipient = await cap.feeRecipient();
  const transferTax = await cap.transferTaxBp();
  const sellTax = await cap.sellTaxBp();
  const buyTax = await cap.buyTaxBp();

  console.log("Token Information:");
  console.log("โ”œโ”€ Name:", await cap.name());
  console.log("โ”œโ”€ Symbol:", await cap.symbol());
  console.log("โ”œโ”€ Total Supply:", ethers.formatEther(totalSupply), "CAP");
  console.log("โ””โ”€ Decimals:", await cap.decimals());
  console.log("");
  console.log("Governance:");
  console.log("โ””โ”€ Owner (DAO):", owner);
  console.log("");
  console.log("Tax Configuration:");
  console.log("โ”œโ”€ Transfer Tax:", transferTax, "bp (", Number(transferTax) / 100, "%)");
  console.log("โ”œโ”€ Sell Tax:", sellTax, "bp (", Number(sellTax) / 100, "%)");
  console.log("โ””โ”€ Buy Tax:", buyTax, "bp (", Number(buyTax) / 100, "%)");
  console.log("");
  console.log("Fee Recipient:");
  console.log("โ””โ”€", feeRecipient);

  // Check for pending tax changes
  const pendingTimestamp = await cap.taxChangeTimestamp();
  if (pendingTimestamp > 0) {
    const pendingTransfer = await cap.pendingTransferTaxBp();
    const pendingSell = await cap.pendingSellTaxBp();
    const pendingBuy = await cap.pendingBuyTaxBp();

    console.log("");
    console.log("โณ Pending Tax Change:");
    console.log("โ”œโ”€ Transfer Tax:", pendingTransfer, "bp");
    console.log("โ”œโ”€ Sell Tax:", pendingSell, "bp");
    console.log("โ”œโ”€ Buy Tax:", pendingBuy, "bp");
    console.log("โ””โ”€ Ready at:", new Date(Number(pendingTimestamp) * 1000).toLocaleString());
  }

  console.log("");
  console.log("โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”");
  console.log("โœ… DAO Governance Setup Complete!");
  console.log("โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”");
  console.log("");
  console.log("๐ŸŽฏ Next Steps:");
  console.log("1. Visit your DAO:");
  console.log(`   https://app.aragon.org/#/daos/sepolia/${daoAddress}`);
  console.log("");
  console.log("2. Create your first proposal to test governance");
  console.log("");
  console.log("3. Other token holders should also delegate their voting power:");
  console.log("   npx hardhat run scripts/delegate-voting-power.ts --network sepolia");
  console.log("");
  console.log("๐Ÿ“š Documentation:");
  console.log("   - Governance Guide: docs/GOVERNANCE.md");
  console.log("   - Aragon Integration: docs/aragon-integration.md");
  console.log("");
}

main()
  .then(() => process.exit(0))
  .catch((error) => {
    console.error("\nโŒ Error:", error.message);
    process.exit(1);
  });

Neighbours