Skip to content

Commit

Permalink
Hydro DAO deployment scripts (#230)
Browse files Browse the repository at this point in the history
* Hydro DAO deployment scripts

* parametrize "only_members_execute" and use mainnet default values in config

* parametrize image and banner
  • Loading branch information
dusan-maksimovic authored Feb 19, 2025
1 parent bfd7316 commit 6363e8c
Show file tree
Hide file tree
Showing 4 changed files with 136 additions and 1 deletion.
5 changes: 4 additions & 1 deletion tools/deployment/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,7 @@ These scripts are used in two places:
### Shell scripts
- `store_instantiate.sh` sends transactions to store the codes from the `artifacts` directory to the specified blockchain. Then it uses stored codes to instantiate Hydro and Tribute smart contracts. It relies on a JSON configuration file that is passed to it. It populates and exports two environment variables: `HYDRO_CONTRACT_ADDRESS` and `TRIBUTE_CONTRACT_ADDRESS`.
- `populate_contracts.sh` sends transactions to create proposals in the Hydro smart contract, and to add tributes for those proposals in the Tribute smart contract. It relies on `HYDRO_CONTRACT_ADDRESS` and `TRIBUTE_CONTRACT_ADDRESS` being previously set by the `store_instantiate.sh` script.
- `setup_on_mainnet.sh` executes previous two scripts by providing `config_mainnet.json` configuration that will result in smart contracts being set up on the Neutron mainnet. Prerequisite for running this script is to have the `neutrond` binary in your `PATH` and to import mnemonic that has enough NTRN tokens on the Neutron mainnet. If this mnemonic is for a different address than the one in `config_mainnet.json` file, then the configuration file needs to be adjusted as well.
- `setup_on_mainnet.sh` executes previous two scripts by providing `config_mainnet.json` configuration that will result in smart contracts being set up on the Neutron mainnet. Prerequisite for running this script is to have the `neutrond` binary in your `PATH` and to import mnemonic that has enough NTRN tokens on the Neutron mainnet. If this mnemonic is for a different address than the one in `config_mainnet.json` file, then the configuration file needs to be adjusted as well.
- `setup_on_testnet.sh` does the same as `setup_on_mainnet.sh`, just on Neutron pion-1 testnet.
- `daodao_hydro_setup.sh` will instantiate DAO DAO set of contracts on Neutron mainnet. Instantiated DAO will use the specified Hydro contract as its voting power module. Make sure to adjust the configuration file `tools/deployment/config_daodao_mainnet.json` before running the script. Usage example:
`bash tools/deployment/daodao_hydro_setup.sh "tools/deployment/config_daodao_mainnet.json"`
14 changes: 14 additions & 0 deletions tools/deployment/config_daodao_mainnet.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"dao_name": "Hydro Governance",
"dao_description": "Hydro governance is a decentralized decision-making system that allows Hydro participants to take part in the management & evolution of the protocol. It operates through on-chain voting, where Hydro-locked ATOM holders vote on governance proposals that impact the protocol's parameters, upgrades, and treasury management.",
"dao_voting_adapter_code_id": "3144",
"hydro_contract_address": "neutron13w6sagl4clacx4c8drhuwfl20cesn3pnllhf37e65ls8zwf6gcgq93t2lp",
"proposal_submission_approver": "neutron1w7f40hgfc505a2wnjsl5pg35yl8qpawv48w5yekax4xj2m43j09s5fa44f",
"allowed_proposal_submitter": "",
"uusdc_deposit_amount": "50000000",
"max_voting_period": "345600",
"quorum_percent": "0.1",
"only_members_execute": "false",
"image_url": "ipfs://QmNsj6WYt3WpyWT6jMG71uhZNj2UwnZn7S3B595RYZ1qyd",
"banner": "ipfs://QmScf4q2hADFBcTPBsGsuhvCUmFnVrz6DXdZUXB45KkYBu"
}
97 changes: 97 additions & 0 deletions tools/deployment/daodao_hydro_setup.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
#!/bin/bash

if [ "$#" -ne 1 ]; then
echo "Usage: $0 DAO_DEPLOYMENT_CONFIG_PATH"
exit 1
fi

NEUTRON_BINARY="neutrond"
CONFIG_FILE="tools/deployment/config_mainnet.json"

NEUTRON_CHAIN_ID=$(jq -r '.chain_id' $CONFIG_FILE)
NEUTRON_NODE=$(jq -r '.neutron_rpc_node' $CONFIG_FILE)
TX_SENDER_WALLET=$(jq -r '.tx_sender_wallet' $CONFIG_FILE)
TX_SENDER_ADDRESS=$($NEUTRON_BINARY keys show $TX_SENDER_WALLET --keyring-backend test | grep "address:" | sed 's/.*address: //')

NEUTRON_CHAIN_ID_FLAG="--chain-id $NEUTRON_CHAIN_ID"
KEYRING_TEST_FLAG="--keyring-backend test"
TX_FLAG="--gas auto --gas-adjustment 1.3"
NEUTRON_NODE_FLAG="--node $NEUTRON_NODE"
NEUTRON_TX_FLAGS="$TX_FLAG --gas-prices 0.0053untrn --chain-id $NEUTRON_CHAIN_ID $NEUTRON_NODE_FLAG $KEYRING_TEST_FLAG -y"

DAO_DEPLOYMENT_CONFIG_PATH="$1"
DAO_NAME=$(jq -r '.dao_name' $DAO_DEPLOYMENT_CONFIG_PATH)
DAO_DESCRIPTION=$(jq -r '.dao_description' $DAO_DEPLOYMENT_CONFIG_PATH)
DAO_VOTING_ADAPTER_CODE_ID=$(jq -r '.dao_voting_adapter_code_id' $DAO_DEPLOYMENT_CONFIG_PATH)
HYDRO_CONTRACT_ADDRESS=$(jq -r '.hydro_contract_address' $DAO_DEPLOYMENT_CONFIG_PATH)
PROPOSAL_SUBMISSION_APPROVER=$(jq -r '.proposal_submission_approver' $DAO_DEPLOYMENT_CONFIG_PATH)
ALLOWED_PROPOSAL_SUBMITTER=$(jq -r '.allowed_proposal_submitter' $DAO_DEPLOYMENT_CONFIG_PATH)
UUSDC_DEPOSIT_AMOUNT=$(jq -r '.uusdc_deposit_amount' $DAO_DEPLOYMENT_CONFIG_PATH)
MAX_VOTING_PERIOD=$(jq -r '.max_voting_period' $DAO_DEPLOYMENT_CONFIG_PATH)
QUORUM_PERCENT=$(jq -r '.quorum_percent' $DAO_DEPLOYMENT_CONFIG_PATH)
ONLY_MEMBERS_EXECUTE=$(jq -r '.only_members_execute' $DAO_DEPLOYMENT_CONFIG_PATH)
IMAGE_URL=$(jq -r '.image_url' $DAO_DEPLOYMENT_CONFIG_PATH)
BANNER=$(jq -r '.banner' $DAO_DEPLOYMENT_CONFIG_PATH)

# https://github.com/DA0-DA0/dao-dao-ui/blob/development/packages/utils/constants/codeIds.json
DAO_CORE_CODE_ID="2346"
DAO_PROPOSAL_SINGLE_CODE_ID="2353"
DAO_PREPROPOSE_APPROVAL_SINGLE_CODE_ID="2348"

DAO_VOTING_ADAPTER_INIT_MSG='{"hydro_contract":"'$HYDRO_CONTRACT_ADDRESS'"}'
echo 'DAO Voting Adapter init msg:' $DAO_VOTING_ADAPTER_INIT_MSG
echo ""
DAO_VOTING_ADAPTER_INIT_MSG=$(echo -n $DAO_VOTING_ADAPTER_INIT_MSG | base64 | tr -d '[:space:]')

VOTING_MODULE_INSTANTIATE_INFO='{"code_id":'$DAO_VOTING_ADAPTER_CODE_ID',"funds":[],"label":"Hydro DAO Voting Adapter","msg":"'$DAO_VOTING_ADAPTER_INIT_MSG'"}'

if [ -z "$ALLOWED_PROPOSAL_SUBMITTER" ]; then
SUBMISSION_POLICY='{"anyone": {"denylist": []}}'
else
SUBMISSION_POLICY='{"specific": {"dao_members": false,"allowlist": ["'$ALLOWED_PROPOSAL_SUBMITTER'"],"denylist": []}}'
fi

if [ -z "$UUSDC_DEPOSIT_AMOUNT" ]; then
DEPOSIT_INFO='null'
else
DEPOSIT_INFO='{"denom": {"token": {"denom": {"native": "ibc/B559A80D62249C8AA07A380E2A2BEA6E5CA9A6F079C912C3A9E9B494105E4F81"}}}, "amount": "'$UUSDC_DEPOSIT_AMOUNT'", "refund_policy": "only_passed"}'
fi

if [ -z "$IMAGE_URL" ]; then
IMAGE_URL='null'
else
IMAGE_URL='"'$IMAGE_URL'"'
fi

if [ -z "$BANNER" ]; then
INITIAL_ITEMS='null'
else
INITIAL_ITEMS='[{"key": "banner", "value": "'$BANNER'"}]'
fi

PRE_PROPOSE_APPROVAL_INIT_MSG='{"deposit_info": '$DEPOSIT_INFO',"submission_policy": '$SUBMISSION_POLICY', "extension": { "approver": "'$PROPOSAL_SUBMISSION_APPROVER'"}}'
echo "DAO Pre-propose approval init msg:" $PRE_PROPOSE_APPROVAL_INIT_MSG
echo ""
PRE_PROPOSE_APPROVAL_INIT_MSG=$(echo -n $PRE_PROPOSE_APPROVAL_INIT_MSG | base64 | tr -d '[:space:]')

PRE_PROPOSE_MODULE_INSTANTIATE_INFO='{"module_may_propose": {"info": {"admin": {"core_module": {}}, "code_id": '$DAO_PREPROPOSE_APPROVAL_SINGLE_CODE_ID', "label": "Hydro pre-propose-single with Approver", "msg": "'$PRE_PROPOSE_APPROVAL_INIT_MSG'", "funds": []}}}'
DAO_PROPOSAL_SINGLE_INIT_MSG='{"threshold": {"threshold_quorum": {"quorum": {"percent": "'$QUORUM_PERCENT'"}, "threshold": {"majority": {}}}}, "max_voting_period":{"time":'$MAX_VOTING_PERIOD'}, "only_members_execute": '$ONLY_MEMBERS_EXECUTE', "allow_revoting":false, "close_proposal_on_execution_failure":true, "pre_propose_info":'$PRE_PROPOSE_MODULE_INSTANTIATE_INFO'}'
echo 'DAO Proposal Single init msg:' $DAO_PROPOSAL_SINGLE_INIT_MSG
echo ""
DAO_PROPOSAL_SINGLE_INIT_MSG=$(echo -n $DAO_PROPOSAL_SINGLE_INIT_MSG | base64 | tr -d '[:space:]')

PROPOSAL_MODULE_INSTANTIATE_INFO='{"code_id":'$DAO_PROPOSAL_SINGLE_CODE_ID', "funds":[], "label":"Hydro DAO proposal-single", "msg":"'$DAO_PROPOSAL_SINGLE_INIT_MSG'"}'

INIT_DAODAO='{"name":"'$DAO_NAME'", "description":"'$DAO_DESCRIPTION'", "image_url": '$IMAGE_URL', "initial_items": '$INITIAL_ITEMS', "automatically_add_cw20s":false, "automatically_add_cw721s":false, "voting_module_instantiate_info":'$VOTING_MODULE_INSTANTIATE_INFO',"proposal_modules_instantiate_info":['$PROPOSAL_MODULE_INSTANTIATE_INFO']}'
echo 'DAO Core init msg:' $INIT_DAODAO
echo ""

echo 'Instantiating Hydro DAO...'
$NEUTRON_BINARY tx wasm instantiate $DAO_CORE_CODE_ID "$INIT_DAODAO" --admin $TX_SENDER_ADDRESS --label "'$DAO_NAME'" --from $TX_SENDER_WALLET $NEUTRON_TX_FLAGS --output json &> ./instantiate_hydro_dao_res.json
sleep 10

INSTANTIATE_HYDRO_DAO_TX_HASH=$(grep -o '{.*}' ./instantiate_hydro_dao_res.json | jq -r '.txhash')
$NEUTRON_BINARY q tx $INSTANTIATE_HYDRO_DAO_TX_HASH $NEUTRON_NODE_FLAG --output json &> ./instantiate_hydro_dao_tx.json
HYDRO_DAO_CONTRACT_ADDRESS=$(jq -r '[.events[] | select(.type == "instantiate") | .attributes[] | select(.key == "_contract_address") | .value] | .[0]' ./instantiate_hydro_dao_tx.json)

echo 'Hydro DAO successfully instantiated: https://daodao.zone/dao/'$HYDRO_DAO_CONTRACT_ADDRESS'/home'
21 changes: 21 additions & 0 deletions tools/deployment/store_instantiate.sh
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,11 @@ IS_IN_PILOT_MODE=true
MAX_DEPLOYMENT_DURATION=3
HYDRO_WASM_PATH="./artifacts/hydro.wasm"
TRIBUTE_WASM_PATH="./artifacts/tribute.wasm"
DAO_VOTING_ADAPTER_WASM_PATH="./artifacts/dao_voting_adapter.wasm"

HYDRO_CODE_ID=""
TRIBUTE_CODE_ID=""
DAO_VOTING_ADAPTER_CODE_ID=""

HYDRO_SC_LABEL="Hydro"
TRIBUTE_SC_LABEL="Tribute"
Expand Down Expand Up @@ -80,6 +82,23 @@ store_tribute() {
TRIBUTE_CODE_ID=$(jq -r '.events[] | select(.type == "store_code") | .attributes[] | select(.key == "code_id") | .value' ./store_tribute_tx.json)
}

store_dao_voting_adapter() {
error_handler() {
echo "Content of store_dao_voting_adapter_res.json:"
cat ./store_dao_voting_adapter_res.json
}
trap error_handler ERR

echo 'Storing dao_voting_adapter wasm...'

$NEUTRON_BINARY tx wasm store $DAO_VOTING_ADAPTER_WASM_PATH --from $TX_SENDER_WALLET $NEUTRON_TX_FLAGS --output json &> ./store_dao_voting_adapter_res.json
sleep 10

STORE_DAO_VOTING_ADAPTER_TX_HASH=$(grep -o '{.*}' ./store_dao_voting_adapter_res.json | jq -r '.txhash')
$NEUTRON_BINARY q tx $STORE_DAO_VOTING_ADAPTER_TX_HASH $NEUTRON_NODE_FLAG --output json &> ./store_dao_voting_adapter_tx.json
DAO_VOTING_ADAPTER_CODE_ID=$(jq -r '.events[] | select(.type == "store_code") | .attributes[] | select(.key == "code_id") | .value' ./store_dao_voting_adapter_tx.json)
}

instantiate_hydro() {
error_handler() {
echo "Content of instantiate_hydro_res.json:"
Expand Down Expand Up @@ -127,9 +146,11 @@ instantiate_tribute() {

store_hydro
store_tribute
store_dao_voting_adapter

echo 'Hydro code ID:' $HYDRO_CODE_ID
echo 'Tribute code ID:' $TRIBUTE_CODE_ID
echo 'DAO Voting Adapter code ID:' $DAO_VOTING_ADAPTER_CODE_ID

instantiate_hydro
instantiate_tribute
Expand Down

0 comments on commit 6363e8c

Please sign in to comment.