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
9 changes: 5 additions & 4 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,9 @@
# The maintainer defaults to MANAGEMENT_DAO_ADDRESS from the active
# just-foundry network config; override it here for a non-standard maintainer.
# MANAGEMENT_DAO_ADDRESS=
RELEASE_METADATA_URI=
BUILD_METADATA_URI=
# RELEASE_METADATA_URI="ipfs://QmSfiCe5sCkrbA7gw6xriqCVx8iR1C2eAqL1iWYp9HbDAV"
# BUILD_METADATA_URI="ipfs://QmZuSnnzNFA9Zw2Vzb1KgaxCqox5uzYBR3UUhbef3FoUzy"

# Optional: a random subdomain is used if empty
# PLUGIN_ENS_SUBDOMAIN=
# Optional. If empty, ENS registration is skipped — the repo is still deployed
# and registered on the PluginRepoRegistry, it just has no ENS name.
PLUGIN_ENS_SUBDOMAIN=cross-chain-controller
1 change: 1 addition & 0 deletions .vars.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ keys:
- DEPLOYER_KEY
- ETHERSCAN_API_KEY
- RPC_URL # optional override: the public RPC from the network file
# - PINATA_JWT
# - REFUND_ADDRESS # optional: burner wallet refund target

# Profiles are keyed by network name — just switch <network> activates the matching profile.
Expand Down
24 changes: 24 additions & 0 deletions justfile
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,27 @@ test-fork *args:
BUILD_PARAMS=$(just resolve-build-params) || exit 1
$FORGE test $BUILD_PARAMS -vvv \
--match-path 'test/e2e/fork/*' {{ args }}

# Deploy the full CCIP lane on Arbitrum Sepolia + Base Sepolia in one run.
# `script/testnet/Test_Deploy.s.sol` forks both chains internally, so this
# bypasses the active just-foundry network. Needs ARBITRUM_SEPOLIA_RPC,
# BASE_SEPOLIA_RPC and DEPLOYER_KEY in `.env`. Contracts are not verified —
# use `forge verify-contract` per chain if you need it.
[group('script')]
deploy-testnet *args:
#!/usr/bin/env bash
set -euo pipefail
[ -f .env ] && set -a && source .env && set +a
for v in DEPLOYER_KEY ARBITRUM_SEPOLIA_RPC BASE_SEPOLIA_RPC; do
if [ -z "${!v:-}" ]; then
echo "$v must be set (in .env or the environment)."
exit 1
fi
done
source {{ JUST_LIB }}
mkdir -p logs
LOG="logs/Test_Deploy-$(date +%y-%m-%d-%H-%M).log"
CMD=(forge script script/testnet/Test_Deploy.s.sol:Test_Deploy \
--sig "run()" --broadcast --multi -vvv {{ args }})
run_logged "$LOG" "${CMD[@]}"
echo "Log: $LOG"
24 changes: 15 additions & 9 deletions script/CreateRepo.sol
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,13 @@ import { CrossChainController } from "@src/CrossChainController.sol";
/// @title CreateRepo
/// @notice Deploys `CrossChainControllerSetup` inside PluginRepoFactory
contract CreateRepo is Script {
/// @dev Pinned metadata for the initial build; update whenever a new
/// metadata JSON is re-pinned. Sources live in
/// `src/{release,build}-metadata.json`; pin them with `just ipfs-pin`.
/// Overridable via `RELEASE_METADATA_URI` / `BUILD_METADATA_URI` in `.env`.
string internal constant DEFAULT_RELEASE_METADATA_URI = "ipfs://QmSfiCe5sCkrbA7gw6xriqCVx8iR1C2eAqL1iWYp9HbDAV";
string internal constant DEFAULT_BUILD_METADATA_URI = "ipfs://QmZuSnnzNFA9Zw2Vzb1KgaxCqox5uzYBR3UUhbef3FoUzy";

address deployer;
string pluginEnsSubdomain;
address managementDao;
Expand Down Expand Up @@ -48,22 +55,19 @@ contract CreateRepo is Script {
pluginRepoFactory = PluginRepoFactory(vm.envAddress("PLUGIN_REPO_FACTORY_ADDRESS"));
vm.label(address(pluginRepoFactory), "PluginRepoFactory");

// Read the rest of environment variables
// Optional: an empty subdomain skips ENS registration entirely. The
// repo is still deployed and registered on the `PluginRepoRegistry`,
// it just has no ENS name.
pluginEnsSubdomain = vm.envOr("PLUGIN_ENS_SUBDOMAIN", string(""));

// Using a random subdomain if empty
if (bytes(pluginEnsSubdomain).length == 0) {
pluginEnsSubdomain = string.concat("cross-chain-controller", vm.toString(block.timestamp));
}

// The Aragon management DAO becomes the repo maintainer.
// `MANAGEMENT_DAO_ADDRESS` is supplied by the active just-foundry
// network config; override in `.env` for a non-standard maintainer.
managementDao = vm.envAddress("MANAGEMENT_DAO_ADDRESS");
vm.label(managementDao, "Maintainer");

releaseMetadataUri = vm.envOr("RELEASE_METADATA_URI", bytes(" "));
buildMetadataUri = vm.envOr("BUILD_METADATA_URI", bytes(" "));
releaseMetadataUri = vm.envOr("RELEASE_METADATA_URI", bytes(DEFAULT_RELEASE_METADATA_URI));
buildMetadataUri = vm.envOr("BUILD_METADATA_URI", bytes(DEFAULT_BUILD_METADATA_URI));
}

function run() public broadcast {
Expand All @@ -79,6 +83,8 @@ contract CreateRepo is Script {
console.log("- PluginSetup: ", pluginSetup);
console.log("- Implementation: ", IPluginSetup(pluginSetup).implementation());
console.log("- Maintainer (Management DAO): ", managementDao);
console.log("- ENS subdomain: ", pluginEnsSubdomain);
console.log(
"- ENS subdomain: ", bytes(pluginEnsSubdomain).length == 0 ? "(none)" : pluginEnsSubdomain
);
}
}
33 changes: 33 additions & 0 deletions src/metadata/build-metadata.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
{
"ui": {},
"change": "Initial build.",
"pluginSetup": {
"prepareInstallation": {
"description": "The information required for the installation of build 1.",
"inputs": [
{
"name": "executor",
"type": "address",
"internalType": "address",
"description": "The executor that inbound cross-chain payloads run on. Pass address(0) to have the setup deploy a dedicated Executor owned by the plugin. Pass the DAO itself to keep execution on the DAO (the setup will grant EXECUTE_PERMISSION on the DAO to the plugin). Any other contract is taken as-is: the DAO must separately authorize the plugin to call `execute` on it, or the receive path cannot execute."
},
{
"name": "guardian",
"type": "address",
"internalType": "address",
"description": "An address granted PAUSE_PERMISSION only, so it can freeze the message paths (forward / receive / retry) but not reopen them. Pass address(0) for none."
},
{
"name": "minFailedMessageGas",
"type": "uint256",
"internalType": "uint256",
"description": "Gas the controller withholds so a failed inbound message can always be recorded as Delivered and stay retryable/cancellable. 45000 is a good default; 0 disables the reserve."
}
]
},
"prepareUninstallation": {
"description": "No input is required for the uninstallation.",
"inputs": []
}
}
}
5 changes: 5 additions & 0 deletions src/metadata/release-metadata.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"name": "Cross-Chain Controller",
"description": "An Aragon OSx plugin that lets a DAO execute Action[] payloads on another chain via a bridge adapter.",
"images": {}
}