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
CharmAlphaVaultPending (multisig)Multisig
CharmAlphaStrategyNot deployedRebalance is embedded in CharmAlphaVaultDeploy
CreatorCharmStrategyMultisigMultisig
AjnaStrategyMultisigMultisig

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("CreatorCharmStrategy:", 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 CreatorCharmStrategy owner (should be your multisig)
CreatorCharmStrategy(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!