// SPDX-License-Identifier: MIT pragma solidity ^0.8.24; import {IERC20Minimal} from "./interfaces/IERC20Minimal.sol"; import {IStankV3PositionManager} from "./interfaces/IStankV3.sol"; import {LaunchRewardVault} from "./LaunchRewardVault.sol"; import {HolderRewardsDistributor} from "./HolderRewardsDistributor.sol"; import {PermanentLiquidityLocker} from "./PermanentLiquidityLocker.sol"; /// @title STANK Component Deployer (PancakeSwap V3) /// @notice Factory-bound helper that deterministically deploys each launch's vault, holder pool, and /// permanent locker, keeping the launch factory's runtime bytecode within the EIP-170 limit. contract StankComponentDeployer { address public immutable factory; struct DeployParams { address launchToken; address pairedAsset; address token0; address token1; address protocolTreasury; /// @notice Recipient of the creator reward share (the launcher, or a creator-chosen address). address rewardRecipient; uint24 poolFee; int24 tickLower; int24 tickUpper; uint16 creatorRewardBps; uint16 holderRewardBps; } error NotFactory(); error ZeroAddress(); constructor(address factory_) { if (factory_ == address(0)) revert ZeroAddress(); factory = factory_; } /// @notice Deploys and atomically wires immutable launch-specific components. function deploy(bytes32 baseSalt, DeployParams calldata params, IStankV3PositionManager positionManager) external returns (HolderRewardsDistributor holderRewards, LaunchRewardVault rewardVault, PermanentLiquidityLocker locker) { if (msg.sender != factory) revert NotFactory(); holderRewards = new HolderRewardsDistributor{salt: keccak256(abi.encode(baseSalt, "HOLDER_REWARDS"))}( IERC20Minimal(params.launchToken), IERC20Minimal(params.pairedAsset), address(this) ); rewardVault = new LaunchRewardVault{salt: keccak256(abi.encode(baseSalt, "REWARD_VAULT"))}( params.pairedAsset, params.protocolTreasury, params.rewardRecipient, address(holderRewards), params.creatorRewardBps, params.holderRewardBps ); holderRewards.bindRewardVault(rewardVault); locker = new PermanentLiquidityLocker{salt: keccak256(abi.encode(baseSalt, "PERMANENT_LOCKER"))}( positionManager, rewardVault, PermanentLiquidityLocker.LockerConfig({ factory: factory, launchToken: params.launchToken, pairedAsset: params.pairedAsset, token0: params.token0, token1: params.token1, poolFee: params.poolFee, tickLower: params.tickLower, tickUpper: params.tickUpper }) ); } }