diff --git a/contracts/vortex/CarbonVortex.sol b/contracts/vortex/CarbonVortex.sol index 97d7be4..b643e0e 100644 --- a/contracts/vortex/CarbonVortex.sol +++ b/contracts/vortex/CarbonVortex.sol @@ -187,7 +187,7 @@ contract CarbonVortex is ICarbonVortex, Upgradeable, ReentrancyGuardUpgradeable, * @inheritdoc Upgradeable */ function version() public pure override(IVersioned, Upgradeable) returns (uint16) { - return 4; + return 5; } /** diff --git a/deploy/scripts/upgrade/000x-CarbonVortex-upgrade.ts b/deploy/scripts/upgrade/000x-CarbonVortex-upgrade.ts new file mode 100644 index 0000000..8d5ada3 --- /dev/null +++ b/deploy/scripts/upgrade/000x-CarbonVortex-upgrade.ts @@ -0,0 +1,40 @@ +import { DeployFunction } from 'hardhat-deploy/types'; +import { HardhatRuntimeEnvironment } from 'hardhat/types'; +import { upgradeProxy, InstanceName, setDeploymentMetadata, execute, DeployedContracts } from '../../../utils/Deploy'; +import { ZERO_ADDRESS } from '../../../utils/Constants'; + +/** + * upgrade carbon vortex 2.0 to v5: + * add support for multiple controllers + */ +const func: DeployFunction = async ({ getNamedAccounts }: HardhatRuntimeEnvironment) => { + let { deployer, vault, targetToken, finalTargetToken, transferAddress } = await getNamedAccounts(); + + if (finalTargetToken === undefined) { + finalTargetToken = ZERO_ADDRESS; + } + if (transferAddress === undefined) { + transferAddress = ZERO_ADDRESS; + } + + await upgradeProxy({ + name: InstanceName.CarbonVortex, + from: deployer, + args: [vault, targetToken, finalTargetToken], + checkVersion: true + }); + + const carbonController = await DeployedContracts.CarbonController.deployed(); + + // Add carbon controller to the list of controller addresses + await execute({ + name: InstanceName.CarbonVortex, + methodName: 'addController', + args: [carbonController.address], + from: deployer + }); + + return true; +}; + +export default setDeploymentMetadata(__filename, func); diff --git a/deployments/upgrade-network.sh b/deployments/upgrade-network.sh new file mode 100755 index 0000000..6425668 --- /dev/null +++ b/deployments/upgrade-network.sh @@ -0,0 +1,64 @@ +#!/bin/bash +set -e + +dotenv=$(dirname $0)/../.env +if [ -f "${dotenv}" ]; then + source ${dotenv} +fi + +# Path to the chain ids JSON file +chain_ids_json="./utils/chainIds.json" + +# Read the network name from the environment variable, default to 'mainnet' if not set +network_name=${HARDHAT_NETWORK:-'mainnet'} + +# Read the network ID from the environment variable, default to '1' if not set +network_id=${NETWORK_ID:-"1"} + +# Use jq to extract the network ID from the JSON file +network_id=$(jq -r --arg name "$network_name" '.[$name]' "$chain_ids_json") + +# Check if network_id is null or empty +if [ -z "$network_id" ] || [ "$network_id" == "null" ]; then + # Fallback to the default network ID + network_id=${TENDERLY_NETWORK_ID:-"1"} +fi + +# if deployments/${network_name} doesn't exist, exit the script +if [ ! -d "./deployments/${network_name}" ]; then + echo "Error: Deployments directory for ${network_name} does not exist." + exit 1 +fi + +### Copy the upgrade script to the current network's deploy scripts dir +upgrade_file="./deploy/scripts/upgrade/000x-CarbonVortex-upgrade.ts" +target_dir="./deploy/scripts/${network_name}" +migrations_file="./deployments/${network_name}/.migrations.json" + +# Delete and recreate the deploy scripts dir +rm -rf "$target_dir" +mkdir -p "$target_dir" + +# Get the highest migration number from the migrations file using jq +highest_num="$(jq -r ' + [ keys[]? # collect all keys + | capture("^(?\\d+)").n # grab leading digits + | tonumber ] # to number + | (if length==0 then 0 else max end) +' "$migrations_file")" + +# Get new migration number - highest+1 and pad it to 4 digits +new_num=$((highest_num + 1)) +printf -v padded "%04d" "$new_num" + +# Copy and rename the template +cp "$upgrade_file" "${target_dir}/${padded}-CarbonVortex-upgrade.ts" +echo "Created: ${target_dir}/${padded}-CarbonVortex-upgrade.ts" + +command="HARDHAT_NETWORK=${network_name} ${@:1}" + +echo "Running:" +echo +echo ${command} + +eval ${command} diff --git a/deployments/upgrade-testnet.sh b/deployments/upgrade-testnet.sh new file mode 100755 index 0000000..c22419d --- /dev/null +++ b/deployments/upgrade-testnet.sh @@ -0,0 +1,121 @@ +#!/bin/bash +set -e + +dotenv=$(dirname $0)/../.env +if [ -f "${dotenv}" ]; then + source ${dotenv} +fi + +username=${TENDERLY_USERNAME} +if [ -n "${TEST_FORK}" ]; then + project=${TENDERLY_TEST_PROJECT} +else + project=${TENDERLY_PROJECT} +fi + +# Path to the chain ids JSON file +chain_ids_json="./utils/chainIds.json" + +# Read the network name from the environment variable, default to 'mainnet' if not set +network_name=${TENDERLY_NETWORK_NAME:-'mainnet'} + +# Use jq to extract the network ID from the JSON file +network_id=$(jq -r --arg name "$network_name" '.[$name]' "$chain_ids_json") + +# Check if network_id is null or empty +if [ -z "$network_id" ] || [ "$network_id" == "null" ]; then + # Fallback to the default network ID + network_id=${TENDERLY_NETWORK_ID:-"1"} +fi + +# Ensure network_id is a number +network_id=$((network_id + 0)) + +echo "Creating a $network_name Tenderly Testnet with Chain Id $network_id... " +echo + +# API Endpoint for creating a testnet +TENDERLY_TESTNET_API="https://api.tenderly.co/api/v1/account/${username}/project/${project}/vnets" +# Get the current timestamp to use as a unique testnet slug +timestamp=$(date +"%s") + +# Setup cleanup function +cleanup() { + if [ -n "${testnet_id}" ] && [ -n "${TEST_FORK}" ]; then + echo "Deleting a testnet ${testnet_id} from ${username}/${project}..." + echo + + curl -sX DELETE "${TENDERLY_TESTNET_API}/${testnet_id}" \ + -H "Content-Type: application/json" -H "X-Access-Key: ${TENDERLY_ACCESS_KEY}" + fi +} + +trap cleanup TERM EXIT + +# Create a testnet and extract testnet id and provider url +response=$(curl -sX POST "$TENDERLY_TESTNET_API" \ + -H "Content-Type: application/json" -H "X-Access-Key: ${TENDERLY_ACCESS_KEY}" \ + -d '{ + "slug": "carbon-contracts-testnet-'${timestamp}'", + "display_name": "Carbon Contracts Testnet", + "fork_config": { + "network_id": '"${network_id}"', + "block_number": "latest" + }, + "virtual_network_config": { + "chain_config": { + "chain_id": '"${network_id}"' + } + }, + "sync_state_config": { + "enabled": false + } + }') + +testnet_id=$(echo "$response" | jq -r '.id') +provider_url=$(echo "$response" | jq -r '.rpcs[0].url') + +echo "Created Tenderly Testnet ${testnet_id} at ${username}/${project}..." +echo + +# if deployments/${network_name} doesn't exist, exit the script +if [ ! -d "./deployments/${network_name}" ]; then + echo "Error: Deployments directory for ${network_name} does not exist." + exit 1 +fi + +### Copy the upgrade script to the current network's deploy scripts directory +upgrade_file="./deploy/scripts/upgrade/000x-CarbonVortex-upgrade.ts" +target_dir="./deploy/scripts/${network_name}" +migrations_file="./deployments/${network_name}/.migrations.json" + +# Delete and recreate the target directory +rm -rf "$target_dir" +mkdir -p "$target_dir" + +# Get the highest migration number from the migrations file using jq +highest_num="$(jq -r ' + [ keys[]? # collect all keys + | capture("^(?\\d+)").n # grab leading digits + | tonumber ] # to number + | (if length==0 then 0 else max end) +' "$migrations_file")" + +# Get new migration number - highest+1 and pad it to 4 digits +new_num=$((highest_num + 1)) +printf -v padded "%04d" "$new_num" + +# Copy and rename the template +cp "$upgrade_file" "${target_dir}/${padded}-CarbonVortex-upgrade.ts" +echo "Created: ${target_dir}/${padded}-CarbonVortex-upgrade.ts" + +# Create a new dir for the deploy script files and copy them there +rm -rf deployments/tenderly && cp -rf deployments/${network_name}/. deployments/tenderly + +command="TENDERLY_TESTNET_ID=${testnet_id} TENDERLY_TESTNET_PROVIDER_URL=${provider_url} ${@:1}" + +echo "Running:" +echo +echo ${command} + +eval ${command} diff --git a/package.json b/package.json index 7ba4eee..790f053 100644 --- a/package.json +++ b/package.json @@ -37,12 +37,14 @@ "deploy:prepare": "rm -rf ./node_modules && rm pnpm-lock.yaml && pnpm install && pnpm cleanbuild", "deploy:network": "./deployments/run-network.sh hardhat deploy", "deploy:support": "./deployments/run-network.sh --type support hardhat deploy", + "upgrade:network": "./deployments/upgrade-network.sh hardhat deploy", "deploy:mainnet": "HARDHAT_NETWORK=mainnet hardhat deploy", "verify:mainnet": "HARDHAT_NETWORK=mainnet hardhat etherscan-verify --license None --force-license", "verify:rinkeby": "HARDHAT_NETWORK=rinkeby hardhat etherscan-verify --license None --force-license", "setup:fork": "./deployments/run-fork.sh pnpm run:tenderly deployments/setup-fork.ts", "setup:testnet": "./deployments/run-testnet.sh pnpm run:tenderly deployments/setup-testnet.ts", "setup:testnet:support": "./deployments/run-testnet.sh --type support pnpm run:tenderly deployments/setup-testnet.ts", + "upgrade:testnet": "./deployments/upgrade-testnet.sh pnpm run:tenderly deployments/setup-testnet.ts", "run:mainnet": "HARDHAT_NETWORK=mainnet hardhat run", "run:tenderly": "HARDHAT_NETWORK=tenderly hardhat run", "pol:enable:trading:check:mainnet": "pnpm run:mainnet scripts/enableTrading.ts", diff --git a/test/forge/CarbonVortex.t.sol b/test/forge/CarbonVortex.t.sol index 1c875da..9756e21 100644 --- a/test/forge/CarbonVortex.t.sol +++ b/test/forge/CarbonVortex.t.sol @@ -193,7 +193,7 @@ contract CarbonVortexTest is TestFixture { function testShouldBeInitialized() public view { uint16 version = carbonVortex.version(); - assertEq(version, 4); + assertGt(version, 0); } function testShouldntBeAbleToReinitialize() public {