Skip to main content

🎯 FINAL DEPLOYMENT GUIDE WITH MULTISIG

EVERYTHING IS READY!

Your multisig 0x7d429eCbdcE5ff516D6e0a93299cbBa97203f2d3 will own all deployed strategies.


🚀 DEPLOYMENT COMMAND:

// Call this function (can be from any address - doesn't have to be the multisig):
DeploymentResult memory result = StrategyDeploymentBatcher(batcherAddress).batchDeployStrategies(
CREATOR_TOKEN, // Your creator token address
0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913, // USDC on Base
VAULT_ADDRESS, // Your CreatorOVault address
AJNA_FACTORY, // Ajna factory (or address(0) if not using)
3000, // 0.3% fee tier for V3 pool
SQRT_PRICE_X96, // Initial price (use calculateSqrtPrice for 99/1)
0x7d429eCbdcE5ff516D6e0a93299cbBa97203f2d3 // ⭐ YOUR MULTISIG
);

📊 WHAT GETS DEPLOYED:

┌─────────────────────────────────────────────────┐
│ 1. UNISWAP V3 POOL (if doesn't exist) │
│ CREATOR/USDC with 0.3% fee │
│ Initialized at 99/1 ratio │
└─────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────┐
│ 2. CHARM ALPHA VAULT │
│ Owner: Pending → Your Multisig │
│ LP management for V3 pool │
└─────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────┐
│ 3. CHARM ALPHA STRATEGY │
│ Owner: Your Multisig ✅ │
│ Rebalancer for Charm vault │
└─────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────┐
│ 4. CREATOR CHARM STRATEGY V2 │
│ Owner: Your Multisig ✅ │
│ Single-sided deposit handler │
└─────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────┐
│ 5. AJNA STRATEGY (if factory provided) │
│ Owner: Your Multisig ✅ │
│ Lending pool strategy │
└─────────────────────────────────────────────────┘

⚠️ IMPORTANT: ACCEPT GOVERNANCE

After deployment, you MUST call this FROM YOUR MULTISIG:

CharmAlphaVault(result.charmVault).acceptGovernance();

Who calls it: Your multisig 0x7d429eCbdcE5ff516D6e0a93299cbBa97203f2d3

When to call it: After deployment (no rush, vault works fine meanwhile)

What it does: Completes ownership transfer of CharmAlphaVault to your multisig


🔐 OWNERSHIP TABLE:

ContractOwner After DeploymentOwner After Accepting
CharmAlphaVault⚠️ Pending (multisig)✅ Multisig
CharmAlphaStrategy❌ Not deployedRebalance is embedded in CharmAlphaVaultDeploy
CreatorCharmStrategyV2✅ Multisig✅ Multisig
AjnaStrategy✅ Multisig✅ Multisig

Only CharmAlphaVault requires the extra acceptance step.


📋 STEP-BY-STEP CHECKLIST:

  • 1. Deploy StrategyDeploymentBatcher contract
  • 2. Get your CREATOR token address
  • 3. Get your CreatorOVault address
  • 4. Calculate sqrtPriceX96 for 99/1 ratio
  • 5. Call batchDeployStrategies() with multisig as owner
  • 6. Wait for transaction to confirm
  • 7. Parse StrategiesDeployed event for addresses
  • 8. From multisig: Call acceptGovernance() on CharmAlphaVault
  • 9. Verify ownership by calling .governance() on CharmAlphaVault
  • 10. Call vault.addStrategy() for each deployed strategy
  • 11. Test deposit flow
  • 12. Launch! 🚀

💡 EXAMPLE WITH ETHERS.JS:

// Step 1: Deploy all strategies
const batcher = new ethers.Contract(batcherAddress, batcherABI, signer);

const tx = await batcher.batchDeployStrategies(
creatorTokenAddress,
"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", // USDC
vaultAddress,
ajnaFactoryAddress, // or ethers.constants.AddressZero
3000,
sqrtPriceX96,
"0x7d429eCbdcE5ff516D6e0a93299cbBa97203f2d3" // Multisig
);

const receipt = await tx.wait();
console.log("✅ Strategies deployed!");

// Parse event to get addresses
const event = receipt.events.find(e => e.event === "StrategiesDeployed");
const {
v3Pool,
charmVault,
charmStrategy,
creatorCharmStrategy,
ajnaStrategy
} = event.args.result;

console.log("CharmAlphaVault:", charmVault);
console.log("CreatorCharmStrategyV2:", creatorCharmStrategy);
console.log("AjnaStrategy:", ajnaStrategy);

// Step 2: Accept governance FROM MULTISIG
// Using Safe SDK or direct multisig call:
const charmVaultContract = new ethers.Contract(
charmVault,
charmVaultABI,
multisigSigner // ⚠️ MUST be multisig signer
);

await charmVaultContract.acceptGovernance();
console.log("✅ Multisig now owns CharmAlphaVault!");

// Step 3: Verify ownership
const currentGovernance = await charmVaultContract.governance();
console.log("Current governance:", currentGovernance);
// Should print: 0x7d429eCbdcE5ff516D6e0a93299cbBa97203f2d3

🔢 CALCULATING sqrtPriceX96:

For a 99/1 CREATOR/USDC ratio (99% CREATOR, 1% USDC):

// If 1 CREATOR = $0.01 USDC (100 CREATOR per USDC)
const priceRatio = 100; // CREATOR per USDC
const sqrtPriceX96 = BigInt(Math.sqrt(priceRatio) * 2**96);

// For 18 decimal CREATOR and 6 decimal USDC:
const decimalAdjustment = 10n ** 6n; // 10^(18-6)/2 = 10^6
const adjustedSqrtPriceX96 = sqrtPriceX96 * decimalAdjustment;

console.log("sqrtPriceX96:", adjustedSqrtPriceX96.toString());

Or use this helper function:

// In Solidity (for testing):
function calculateSqrtPrice(
uint256 creatorPerUsdc
) public pure returns (uint160) {
// Simplified - use proper math library in production
uint256 sqrtPrice = sqrt(creatorPerUsdc * 1e6) * 2**96;
return uint160(sqrtPrice);
}

🛡️ SECURITY NOTES:

  1. Multisig is MUCH safer than EOA

    • Multiple signers required
    • No single point of failure
    • Transparent audit trail
  2. Verify all addresses before accepting governance

    • Check contract source code on BaseScan
    • Verify deployment parameters
    • Test on testnet first
  3. Test the accept flow

    • Make sure your multisig can call acceptGovernance()
    • Check that you have enough signers online
    • Practice on Base Sepolia testnet first
  4. Keep deployment addresses safe

    • Document all deployed addresses
    • Store in your multisig's address book
    • Share with all multisig signers

🎯 FINAL VERIFICATION:

After deployment, verify:

// 1. Check CharmAlphaVault governance (should be your multisig)
CharmAlphaVault(charmVault).governance()
// Should return: 0x7d429eCbdcE5ff516D6e0a93299cbBa97203f2d3 ✅

// 2. CharmAlphaStrategy is not deployed in the automated path (embedded).
// charmStrategy is expected to be address(0) in the StrategiesDeployed result.
// Should return: 0x7d429eCbdcE5ff516D6e0a93299cbBa97203f2d3 ✅

// 3. Check CreatorCharmStrategyV2 owner (should be your multisig)
CreatorCharmStrategyV2(creatorCharmStrategy).owner()
// Should return: 0x7d429eCbdcE5ff516D6e0a93299cbBa97203f2d3 ✅

// 4. Check AjnaStrategy owner (should be your multisig)
AjnaStrategy(ajnaStrategy).owner()
// Should return: 0x7d429eCbdcE5ff516D6e0a93299cbBa97203f2d3 ✅

🎉 YOU'RE READY TO DEPLOY!

Everything is configured for your multisig ownership.

Deployment is safe and secure! 🛡️

Good luck with your launch! 🚀