AtomicStackDeployer

0xd8c485f7011f05862fa352f909dac60bb29f0146

Verification
Verified
v0.8.26+commit.8a97fa7a
Type
Contract
4,515 bytes
ABI entries
13
5 read · 1 write
License
none

Contract information

Address
0xd8c485f7011f05862fa352f909dac60bb29f0146
Chain
Robinhood Chain (4663)
Compiler
v0.8.26+commit.8a97fa7a
Optimization
Enabled
Creation tx
0x28cb4201ba…b663918230

Token

Not a token

This contract does not expose ERC-20 metadata.

Read contract (5)

committedPlanHash()bytes32
executor()address
owner()address
resultHash()bytes32
used()bool

Events (1)

StackDeployed

ABI

[
  {
    "inputs": [
      {
        "internalType": "bytes32",
        "name": "planHash",
        "type": "bytes32"
      }
    ],
    "stateMutability": "nonpayable",
    "type": "constructor"
  },
  {
    "inputs": [
      {
        "internalType": "uint8",
        "name": "index",
        "type": "uint8"
      },
      {
        "internalType": "address",
        "name": "expected",
        "type": "address"
      },
      {
        "internalType": "address",
        "name": "actual",
        "type": "address"
      }
    ],
    "name": "AddressMismatch",
    "type": "error"
  },
  {
    "inputs": [],
    "name": "AlreadyUsed",
    "type": "error"
  },
  {
    "inputs": [
      {
        "internalType": "uint8",
        "name": "index",
        "type": "uint8"
      }
    ],
    "name": "DeploymentFailed",
    "type": "error"
  },
  {
    "inputs": [],
    "name": "HookDeploymentFailed",
    "type": "error"
  },
  {
    "inputs": [],
    "name": "PlanHashMismatch",
    "type": "error"
  },
  {
    "anonymous": false,
    "inputs": [
      {
        "indexed": true,
        "internalType": "bytes32",
        "name": "planHash",
        "type": "bytes32"
      },
      {
        "indexed": true,
        "internalType": "bytes32",
        "name": "resultHash",
        "type": "bytes32"
      },
      {
        "indexed": true,
        "internalType": "address",
        "name": "launchFactory",
        "type": "address"
      },
      {
        "indexed": false,
        "internalType": "address",
        "name": "executor",
        "type": "address"
      }
    ],
    "name": "StackDeployed",
    "type": "event"
  },
  {
    "inputs": [],
    "name": "committedPlanHash",
    "outputs": [
      {
        "internalType": "bytes32",
        "name": "",
        "type": "bytes32"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [
      {
        "components": [
          {
            "internalType": "bytes",
            "name": "graduationManagerInitCode",
            "type": "bytes"
          },
          {
            "internalType": "bytes",
            "name": "redemptionManagerInitCode",
            "type": "bytes"
          },
          {
            "internalType": "bytes",
            "name": "ladderManagerInitCode",
            "type": "bytes"
          },
          {
            "internalType": "bytes",
            "name": "create2DeployerInitCode",
            "type": "bytes"
          },
          {
            "internalType": "bytes",
            "name": "feeControllerInitCode",
            "type": "bytes"
          },
          {
            "internalType": "bytes",
            "name": "launchHookInitCode",
            "type": "bytes"
          },
          {
            "internalType": "bytes",
            "name": "launchRouterInitCode",
            "type": "bytes"
          },
          {
            "internalType": "bytes",
            "name": "earlyExitFeeModelInitCode",
            "type": "bytes"
          },
          {
            "internalType": "bytes",
            "name": "controllerImplementationInitCode",
            "type": "bytes"
          },
          {
            "internalType": "bytes",
            "name": "launchFactoryInitCode",
            "type": "bytes"
          },
          {
            "internalType": "bytes32",
            "name": "hookSalt",
            "type": "bytes32"
          },
          {
            "components": [
              {
                "internalType": "address",
                "name": "graduationManager",
                "type": "address"
              },
              {
                "internalType": "address",
                "name": "redemptionManager",
                "type": "address"
              },
              {
                "internalType": "address",
                "name": "ladderManager",
                "type": "address"
              },
              {
                "internalType": "address",
                "name": "create2Deployer",
                "type": "address"
              },
              {
                "internalType": "address",
                "name": "feeController",
                "type": "address"
              },
              {
                "internalType": "address",
                "name": "launchHook",
                "type": "address"
              },
              {
                "internalType": "address",
                "name": "launchRouter",
                "type": "address"
              },
              {
                "internalType": "address",
                "name": "earlyExitFeeModel",
                "type": "address"
              },
              {
                "internalType": "address",
                "name": "controllerImplementation",
                "type": "address"
              },
              {
                "internalType": "address",
                "name": "launchFactory",
                "type": "address"
              }
            ],
            "internalType": "struct AtomicStackDeployer.Addresses",
            "name": "expected",
            "type": "tuple"
          }
        ],
        "internalType": "struct AtomicStackDeployer.Plan",
        "name": "plan",
        "type": "tuple"
      }
    ],
    "name": "execute",
    "outputs": [
      {
        "components": [
          {
            "internalType": "address",
            "name": "graduationManager",
            "type": "address"
          },
          {
            "internalType": "address",
            "name": "redemptionManager",
            "type": "address"
          },
          {
            "internalType": "address",
            "name": "ladderManager",
            "type": "address"
          },
          {
            "internalType": "address",
            "name": "create2Deployer",
            "type": "address"
          },
          {
            "internalType": "address",
            "name": "feeController",
            "type": "address"
          },
          {
            "internalType": "address",
            "name": "launchHook",
            "type": "address"
          },
          {
            "internalType": "address",
            "name": "launchRouter",
            "type": "address"
          },
          {
            "internalType": "address",
            "name": "earlyExitFeeModel",
            "type": "address"
          },
          {
            "internalType": "address",
            "name": "controllerImplementation",
            "type": "address"
          },
          {
            "internalType": "address",
            "name": "launchFactory",
            "type": "address"
          }
        ],
        "internalType": "struct AtomicStackDeployer.Addresses",
        "name": "deployed",
        "type": "tuple"
      }
    ],
    "stateMutability": "nonpayable",
    "type": "function"
  },
  {
    "inputs": [],
    "name": "executor",
    "outputs": [
      {
        "internalType": "address",
        "name": "",
        "type": "address"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [],
    "name": "owner",
    "outputs": [
      {
        "internalType": "address",
        "name": "",
        "type": "address"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [],
    "name": "resultHash",
    "outputs": [
      {
        "internalType": "bytes32",
        "name": "",
        "type": "bytes32"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [],
    "name": "used",
    "outputs": [
      {
        "internalType": "bool",
        "name": "",
        "type": "bool"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  }
]

Source code

// SPDX-License-Identifier: MIT
pragma solidity 0.8.26;

interface ICreate2Deployer {
    function deployOnce(bytes32 salt, bytes calldata initCode) external returns (address deployed);
    function used() external view returns (bool);
}

interface IRegistryBootstrap {
    function configureRegistry(address registryAdmin) external;
}

interface IFeeControllerBootstrap {
    function configure(address registryAdmin, address hook) external;
}

/// @notice One-use atomic deployer for one immutable Rivers protocol stack.
/// @dev The owner commits to the exact plan hash at construction. Successful execution
///      is permissionless so a nonprivileged relayer can transport the large calldata
///      without a hardware-wallet QR. The relayer cannot alter the committed plan.
contract AtomicStackDeployer {
    struct Addresses {
        address graduationManager;
        address redemptionManager;
        address ladderManager;
        address create2Deployer;
        address feeController;
        address launchHook;
        address launchRouter;
        address earlyExitFeeModel;
        address controllerImplementation;
        address launchFactory;
    }

    struct Plan {
        bytes graduationManagerInitCode;
        bytes redemptionManagerInitCode;
        bytes ladderManagerInitCode;
        bytes create2DeployerInitCode;
        bytes feeControllerInitCode;
        bytes launchHookInitCode;
        bytes launchRouterInitCode;
        bytes earlyExitFeeModelInitCode;
        bytes controllerImplementationInitCode;
        bytes launchFactoryInitCode;
        bytes32 hookSalt;
        Addresses expected;
    }

    address public immutable owner;
    bytes32 public immutable committedPlanHash;
    bool public used;
    address public executor;
    bytes32 public resultHash;

    error AlreadyUsed();
    error PlanHashMismatch();
    error DeploymentFailed(uint8 index);
    error AddressMismatch(uint8 index, address expected, address actual);
    error HookDeploymentFailed();

    event StackDeployed(
        bytes32 indexed planHash, bytes32 indexed resultHash, address indexed launchFactory, address executor
    );

    constructor(bytes32 planHash) {
        owner = msg.sender;
        committedPlanHash = planHash;
    }

    function execute(Plan calldata plan) external returns (Addresses memory deployed) {
        if (used) revert AlreadyUsed();
        bytes32 planHash = keccak256(abi.encode(plan));
        if (planHash != committedPlanHash) revert PlanHashMismatch();
        used = true;

        deployed.graduationManager = _deploy(0, plan.graduationManagerInitCode, plan.expected.graduationManager);
        deployed.redemptionManager = _deploy(1, plan.redemptionManagerInitCode, plan.expected.redemptionManager);
        deployed.ladderManager = _deploy(2, plan.ladderManagerInitCode, plan.expected.ladderManager);
        deployed.create2Deployer = _deploy(3, plan.create2DeployerInitCode, plan.expected.create2Deployer);
        deployed.feeController = _deploy(4, plan.feeControllerInitCode, plan.expected.feeController);

        deployed.launchHook =
            ICreate2Deployer(deployed.create2Deployer).deployOnce(plan.hookSalt, plan.launchHookInitCode);
        if (
            deployed.launchHook != plan.expected.launchHook || deployed.launchHook.code.length == 0
                || !ICreate2Deployer(deployed.create2Deployer).used()
        ) revert HookDeploymentFailed();

        deployed.launchRouter = _deploy(5, plan.launchRouterInitCode, plan.expected.launchRouter);
        deployed.earlyExitFeeModel = _deploy(6, plan.earlyExitFeeModelInitCode, plan.expected.earlyExitFeeModel);
        deployed.controllerImplementation =
            _deploy(7, plan.controllerImplementationInitCode, plan.expected.controllerImplementation);
        deployed.launchFactory = _deploy(8, plan.launchFactoryInitCode, plan.expected.launchFactory);

        IRegistryBootstrap(deployed.launchHook).configureRegistry(deployed.launchFactory);
        IFeeControllerBootstrap(deployed.feeController).configure(deployed.launchFactory, deployed.launchHook);
        IRegistryBootstrap(deployed.launchRouter).configureRegistry(deployed.launchFactory);

        executor = msg.sender;
        resultHash = keccak256(abi.encode(deployed));
        emit StackDeployed(planHash, resultHash, deployed.launchFactory, msg.sender);
    }

    function _deploy(uint8 index, bytes calldata initCode, address expected) private returns (address deployed) {
        bytes memory code = initCode;
        assembly ("memory-safe") {
            deployed := create(0, add(code, 0x20), mload(code))
        }
        if (deployed == address(0) || deployed.code.length == 0) revert DeploymentFailed(index);
        if (deployed != expected) revert AddressMismatch(index, expected, deployed);
    }
}
Chain explorer5853msChain node87ms