Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 58 additions & 0 deletions script/trading/seaport16/DeployConduitController.s.sol

Large diffs are not rendered by default.

52 changes: 52 additions & 0 deletions script/trading/seaport16/DeployImmutableSeaport.s.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// Copyright (c) Immutable Pty Ltd 2018 - 2025
// SPDX-License-Identifier: Apache-2
pragma solidity 0.8.24;

import {console} from "forge-std/console.sol";
import {Script} from "forge-std/Script.sol";
import {ImmutableSeaport} from "../../../contracts/trading/seaport16/ImmutableSeaport.sol";
import {AccessControlledDeployer} from "../../../contracts/deployer/AccessControlledDeployer.sol";
import {IDeployer} from "@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IDeployer.sol";

/**
* @title DeployImmutableSeaport
* @notice This script deploys the ImmutableSeaport contract via CREATE2.
* @dev This script assumes that the ConduitController contract has already been deployed.
*/
contract DeployImmutableSeaport is Script {
address private constant accessControlledDeployerAddress = 0x0B5B1d92259b13D516cCd5a6E63d7D94Ea2A4836;
address private constant create2DeployerAddress = 0x9df760a54b3B00cC8B3d70A37d45fa97cCfdb4Db;
address private constant conduitControllerAddress = 0x00000000F9490004C11Cef243f5400493c00Ad63;
address private constant immutableSeaportAddress = 0xbE737Cf2C122F83d1610C1224f7B99ca9d0E09f6;
bytes32 private constant immutableSeaportDeploymentSalt = keccak256(abi.encodePacked("immutable-seaport16"));
address private constant seaportInitialOwner = 0xdDA0d9448Ebe3eA43aFecE5Fa6401F5795c19333; // Immutable Deployer

function run() external {
AccessControlledDeployer deployer = AccessControlledDeployer(accessControlledDeployerAddress);
IDeployer create2Deployer = IDeployer(create2DeployerAddress);

// Check supplied immutableSeaportAddress matches the expected address based on current creationCode
bytes memory immutableSeaportDeploymentBytecode = abi.encodePacked(
type(ImmutableSeaport).creationCode,
abi.encode(conduitControllerAddress, seaportInitialOwner)
);
address expectedImmutableSeaportAddress = create2Deployer.deployedAddress(immutableSeaportDeploymentBytecode, accessControlledDeployerAddress, immutableSeaportDeploymentSalt);
console.log("Expected ImmutableSeaport address: %s", expectedImmutableSeaportAddress);
require(expectedImmutableSeaportAddress == immutableSeaportAddress, "Expected ImmutableSeaport address mismatch");

vm.startBroadcast();

// Deploy ImmutableSeaport if it doesn't already exist
if (immutableSeaportAddress.code.length == 0) {
console.log("Deploying ImmutableSeaport");
address deployedImmutableSeaportAddress = deployer.deploy(create2Deployer, immutableSeaportDeploymentBytecode, immutableSeaportDeploymentSalt);
require(deployedImmutableSeaportAddress == immutableSeaportAddress, "Deployed ImmutableSeaport address mismatch");
} else {
console.log("Skipping ImmutableSeaport, already exists");
}

vm.stopBroadcast();
}
}

// forge script script/trading/seaport16/DeployImmutableSeaport.s.sol --rpc-url "https://rpc.testnet.immutable.com" -vvvv --priority-gas-price 10000000000 --with-gas-price 11000000000 --private-key=xx
65 changes: 65 additions & 0 deletions script/trading/seaport16/DeployImmutableSignedZoneV3.s.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
// Copyright (c) Immutable Pty Ltd 2018 - 2025
// SPDX-License-Identifier: Apache-2
pragma solidity 0.8.24;

import {console} from "forge-std/console.sol";
import {Script} from "forge-std/Script.sol";
import {ImmutableSeaport} from "../../../contracts/trading/seaport16/ImmutableSeaport.sol";
import {ImmutableSignedZoneV3} from "../../../contracts/trading/seaport16/zones/immutable-signed-zone/v3/ImmutableSignedZoneV3.sol";
import {AccessControlledDeployer} from "../../../contracts/deployer/AccessControlledDeployer.sol";
import {IDeployer} from "@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IDeployer.sol";

/**
* @title DeployImmutableSignedZoneV3
* @notice This script deploys the ImmutableSignedZoneV3 contract via CREATE2.
* @dev This script assumes that the ImmutableSeaport contract has already been deployed.
*/
contract DeployImmutableSignedZoneV3 is Script {
address private constant accessControlledDeployerAddress = 0x0B5B1d92259b13D516cCd5a6E63d7D94Ea2A4836;
address private constant create2DeployerAddress = 0x9df760a54b3B00cC8B3d70A37d45fa97cCfdb4Db;
address private constant conduitControllerAddress = 0x00000000F9490004C11Cef243f5400493c00Ad63;
address private constant immutableSeaportAddress = 0xbE737Cf2C122F83d1610C1224f7B99ca9d0E09f6;
bytes32 private constant immutableSeaportDeploymentSalt = keccak256(abi.encodePacked("immutable-seaport16"));
address private constant zoneAddress = 0x18C12fb9c4f6165196c895aDF84230828A85B247;
bytes32 private constant zoneDeploymentSalt = keccak256(abi.encodePacked("immutable-signed-zone-v3"));
address private constant seaportInitialOwner = 0xdDA0d9448Ebe3eA43aFecE5Fa6401F5795c19333; // Immutable Deployer
address private constant zoneInitialOwner = 0xdDA0d9448Ebe3eA43aFecE5Fa6401F5795c19333; // Immutable Deployer

function run() external {
AccessControlledDeployer deployer = AccessControlledDeployer(accessControlledDeployerAddress);
IDeployer create2Deployer = IDeployer(create2DeployerAddress);

// Check supplied immutableSeaportAddress matches the expected address based on current creationCode
bytes memory immutableSeaportDeploymentBytecode = abi.encodePacked(
type(ImmutableSeaport).creationCode,
abi.encode(conduitControllerAddress, seaportInitialOwner)
);
address expectedImmutableSeaportAddress = create2Deployer.deployedAddress(immutableSeaportDeploymentBytecode, accessControlledDeployerAddress, immutableSeaportDeploymentSalt);
console.log("Expected ImmutableSeaport address: %s", expectedImmutableSeaportAddress);
require(expectedImmutableSeaportAddress == immutableSeaportAddress, "Expected ImmutableSeaport address mismatch");

// Check supplied zoneAddress matches the expected address based on current creationCode
bytes memory zoneDeploymentBytecode = abi.encodePacked(
type(ImmutableSignedZoneV3).creationCode,
abi.encode("ImmutableSignedZone", immutableSeaportAddress, "", "", zoneInitialOwner)
);
address expectedZoneAddress = create2Deployer.deployedAddress(zoneDeploymentBytecode, accessControlledDeployerAddress, zoneDeploymentSalt);
console.log("Expected ImmutableSignedZoneV3 address: %s", expectedZoneAddress);
require(expectedZoneAddress == zoneAddress, "Expected ImmutableSignedZoneV3 address mismatch");

vm.startBroadcast();

// Deploy zone if it doesn't already exist
if (zoneAddress.code.length == 0) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this come earlier? given the above code might be a bit moot if this contract is already deployed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The code above serves as a sanity check to prevent accidental deployment AND accidental skipping deployment (e.g. if the zone code changes but we forget to update the expected address constant).

console.log("Deploying ImmutableSignedZoneV3");
address deployedZoneAddress = deployer.deploy(create2Deployer, zoneDeploymentBytecode, zoneDeploymentSalt);
require(deployedZoneAddress == zoneAddress, "Deployed ImmutableSignedZoneV3 address mismatch");
} else {
console.log("Skipping ImmutableSignedZoneV3, already exists");
}

vm.stopBroadcast();
}
}

// forge script script/trading/seaport16/DeployImmutableSignedZoneV3.s.sol --rpc-url "https://rpc.testnet.immutable.com" -vvvv --priority-gas-price 10000000000 --with-gas-price 11000000000 --private-key=xx
20 changes: 20 additions & 0 deletions script/trading/seaport16/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Seaport Deployment Scripts

This directory contains scripts for deploying a set of contracts required to support a Seaport 1.6 trading system. It assumes a ledger wallet is used.

## Environment Variables

The following environment variables must be specified for all scripts. They can be supplied vai the environment or a `.env` file.

* `DRY_RUN`: `true` or `false`.
* `IMMUTABLE_NETWORK`: Must be `mainnet` for Immutable zkEVM Mainnet or `testnet` for Testnet.
* `HD_PATH`: Hierarchical Deterministic path for the ledger wallet. Should of the form `HD_PATH="m/44'/60'/0'/0/0"`.
* `BLOCKSCOUT_APIKEY`: API key for verifying contracts on Blockscout. The key for use with Immutable zkEVM Mainnet will be different to the one used for Testnet. API keys for Immtuable zkEVM Mainnet can be obtained in the [block explorer](https://explorer.immutable.com/account/api-key).

## Deployment

Deploy via the following command:

`./script/trading/seaport16/deploy.sh <CONTRACT_TO_DEPLOY>`

where `CONTRACT_TO_DEPLOY` is one of `ConduitController`, `ImmutableSeaport` or `ImmutableSignedZoneV3`.
104 changes: 104 additions & 0 deletions script/trading/seaport16/deploy.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
#!/bin/bash

# Load the .env file if it exists
if [ -f .env ]
then
set -a; source .env; set +a
fi

if [ -z "${DRY_RUN}" ]; then
echo "Error: DRY_RUN variable is not set"
exit 1
fi

if [[ "$DRY_RUN" == "true" ]]; then
echo "Dry run mode"
elif [[ "$DRY_RUN" == "false" ]]; then
echo "Broadcast mode"
else
echo "Error: DRY_RUN must be either true or false"
exit 1
fi

if [ -z "${IMMUTABLE_NETWORK}" ]; then
echo "Error: IMMUTABLE_NETWORK variable is not set"
exit 1
fi

if [[ "$IMMUTABLE_NETWORK" == "mainnet" ]]; then
echo Immutable zkEVM Mainnet Configuration
IMMUTABLE_RPC=https://rpc.immutable.com
BLOCKSCOUT_URI=https://explorer.immutable.com/api?
elif [[ "$IMMUTABLE_NETWORK" == "testnet" ]]; then
echo Immutable zkEVM Testnet Configuration
IMMUTABLE_RPC=https://rpc.testnet.immutable.com
BLOCKSCOUT_URI=https://explorer.testnet.immutable.com/api?
else
echo "Error: IMMUTABLE_NETWORK must be either mainnet or testnet"
exit 1
fi

if [ -z "${HD_PATH}" ]; then
echo "Error: HD_PATH environment variable is not set"
exit 1
fi

if [ -z "${BLOCKSCOUT_APIKEY}" ]; then
echo "Error: BLOCKSCOUT_APIKEY environment variable is not set"
exit 1
fi

# Check if an argument was provided
if [ -z "$1" ]; then
echo "Error: No argument provided."
echo "Usage: $0 <ConduitController|ImmutableSeaport|ImmutableSignedZoneV3>"
exit 1
fi

contract_to_deploy="$1"
if [[ "$contract_to_deploy" == "ConduitController" ]]; then
script=script/trading/seaport16/DeployConduitController.s.sol
elif [[ "$contract_to_deploy" == "ImmutableSeaport" ]]; then
script=script/trading/seaport16/DeployImmutableSeaport.s.sol
elif [[ "$contract_to_deploy" == "ImmutableSignedZoneV3" ]]; then
script=script/trading/seaport16/DeployImmutableSignedZoneV3.s.sol
else
echo "Error: contract to deploy must be either ConduitController, ImmutableSeaport or ImmutableSignedZoneV3"
exit 1
fi

echo "Configuration"
echo " DRY_RUN: $DRY_RUN"
echo " IMMUTABLE_RPC: $IMMUTABLE_RPC"
echo " BLOCKSCOUT_URI: $BLOCKSCOUT_URI"
echo " BLOCKSCOUT_APIKEY: $BLOCKSCOUT_APIKEY"
echo " Script to execute: $script"

# NOTE WELL ---------------------------------------------
# Add resume option if the script fails part way through:
# --resume \
# To record the transactions but not execute them, remove the --broadcast line.
# NOTE WELL ---------------------------------------------
if [[ "$DRY_RUN" == "true" ]]; then
forge script \
--rpc-url $IMMUTABLE_RPC \
--priority-gas-price 10000000000 \
--with-gas-price 10000000100 \
-vvvv \
--ledger \
--hd-paths "$HD_PATH" \
$script
else
forge script \
--rpc-url $IMMUTABLE_RPC \
--priority-gas-price 10000000000 \
--with-gas-price 10000000100 \
-vvvv \
--broadcast \
--verify \
--verifier blockscout \
--verifier-url $BLOCKSCOUT_URI$BLOCKSCOUT_APIKEY \
--ledger \
--hd-paths "$HD_PATH" \
$script
fi
Loading