Skip to content

Instantly share code, notes, and snippets.

@apetresc
Last active March 28, 2023 05:44
Show Gist options
  • Save apetresc/caaf222c31b02354dbc11a333cdb688e to your computer and use it in GitHub Desktop.
Save apetresc/caaf222c31b02354dbc11a333cdb688e to your computer and use it in GitHub Desktop.
A script to automatically claim Crypto.org CRO staking rewards and re-stake them
#!/bin/bash -e
# redelegate-cro.sh is a script that automatically claims all your delegation
# rewards (across any number of validators) in a single transaction (assuming a
# minimum reward threshold is met, to avoid spurious transactions). The rewards
# are then automatically redelegated to the provided validator address, leaving
# behind at least a 0.005 CRO buffer to ensure there is always enough for
# regular transaction fees.
#
# The idea is that it is safe to run this script on a fixed cron schedule and
# feel confident that you are minimizing fees and maximizing APY.
#
# TODO: Currently, the delegation only happens to a single validator (although
# rewards are claimed from all). In future, you will be able to specify
# multiple <validator-address>es to evenly split the stake across multiple.
#
# REQUIREMENTS:
# - chain-maind
# - jq
#
# Updates will be posted to the gist at:
# https://gist.github.com/apetresc/caaf222c31b02354dbc11a333cdb688e
if [[ "$1" == "-h" || "$1" == "" || "$2" == "" ]]
then
echo "Usage: $0 <wallet-address> <validator-address> [-y]"
exit
fi
# Arguments
WALLET=$1
VALIDATOR=$2
YES=$3
# Global parameters
REWARDS_THRESHOLD=10
RPC_NODE="https://mainnet.crypto.org:26657"
CHAIN_ID="crypto-org-chain-mainnet-1"
echo "Wallet is: $WALLET"
BALANCE=$(chain-maind --chain-id $CHAIN_ID query bank balances $WALLET --node $RPC_NODE --output json | jq -r '.balances[] | select(.denom == "basecro") .amount')
echo "Balance is: $BALANCE"
REWARDS=$(chain-maind --chain-id $CHAIN_ID query distribution rewards $WALLET --node $RPC_NODE --output json)
REWARDS_AMOUNT=$(echo $REWARDS | jq -r '.total[] | select(.denom == "basecro") .amount|tonumber/100000000')
echo "There are $REWARDS_AMOUNT CRO rewards across $(echo $REWARDS | jq -r '.rewards | length') validators to be claimed."
if awk 'BEGIN {exit !('$REWARDS_AMOUNT' >= '$REWARDS_THRESHOLD')}'
then
echo "Claiming rewards..."
chain-maind --chain-id $CHAIN_ID tx distribution withdraw-all-rewards \
--from $WALLET \
--gas=auto --gas-prices=0.1basecro --gas-adjustment=1.2 \
--node $RPC_NODE $YES
NEW_BALANCE=$(chain-maind --chain-id $CHAIN_ID query bank balances $WALLET --node $RPC_NODE --output json | jq -r '.balances[] | select(.denom == "basecro") .amount')
while awk 'BEGIN {exit !('$NEW_BALANCE' <= '$BALANCE')}'
do
echo "Waiting for rewards to appear..."
NEW_BALANCE=$(chain-maind --chain-id $CHAIN_ID query bank balances $WALLET --node $RPC_NODE --output json | jq -r '.balances[] | select(.denom == "basecro") .amount')
done
BALANCE=$NEW_BALANCE
echo "New balance is: $BALANCE"
STAKING_AMOUNT=$(expr $BALANCE - 500000)
echo "Amount to stake: $STAKING_AMOUNT"
chain-maind --chain-id $CHAIN_ID tx staking delegate \
$VALIDATOR \
"${STAKING_AMOUNT}basecro" \
--from $WALLET \
--gas=auto --gas-prices=0.1basecro --gas-adjustment=1.2 \
--node $RPC_NODE $YES
echo "Done!"
else
echo "Need at least $REWARDS_THRESHOLD CRO to claim, skipping claim..."
fi
@jlavos
Copy link

jlavos commented Apr 16, 2021

got it working, ;), thanks.

@jcdmacleod
Copy link

Thank you for sharing this!

I get this error "Error: error unmarshalling: invalid character '<' looking for beginning of value" however the balance in the wallet I am testing with is below 10 CRO.

@jlavos
Copy link

jlavos commented Apr 18, 2021

I get that on some calls (e.g. 1st time I run the script it fails, if I run it right after it works), haven't figured out why yet.

@apetresc
Copy link
Author

@jcdmacleod Yeah, that's a normal error that just means the public RPC node we're using (one of Crypto.com's) rejected our query for whatever reason, presumably due to congestion. As @jlavos points out, retrying immediately afterwards will usually solve it.

I suppose I should just add a little retry logic directly in the script, thanks for the idea 👍

@geolectric
Copy link

Did the RPC_NODE change? I keep getting an error:

"Error: post failed: Post "https://mainnet.crypto.org:26657": dial tcp: lookup mainnet.crypto.org: no such host"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment