From 2f8e27df60f414edbd609ad4ffc61131bc0666c6 Mon Sep 17 00:00:00 2001 From: sampocs Date: Wed, 20 Mar 2024 23:42:56 -0500 Subject: [PATCH] rebate integration tests (#1152) --- deps/osmosis | 2 +- dockernet/config/ica_host.json | 2 + .../scripts/community-pool-staking/README.md | 12 +++ .../community-pool-staking/add_trade_route.sh | 27 +++++- .../scripts/community-pool-staking/rebate.sh | 9 ++ .../scripts/community-pool-staking/trade.sh | 25 +++++ dockernet/src/create_logs.sh | 92 ++++++++++--------- dockernet/src/init_chain.sh | 2 +- dockernet/src/register_host.sh | 7 +- dockernet/start_network.sh | 2 + .../icqcallbacks_withdrawal_reward_balance.go | 2 +- x/stakeibc/keeper/reward_converter.go | 12 +-- 12 files changed, 138 insertions(+), 56 deletions(-) create mode 100644 dockernet/scripts/community-pool-staking/rebate.sh create mode 100644 dockernet/scripts/community-pool-staking/trade.sh diff --git a/deps/osmosis b/deps/osmosis index 3e2c326301..30532bd83e 160000 --- a/deps/osmosis +++ b/deps/osmosis @@ -1 +1 @@ -Subproject commit 3e2c326301aff138214c1d25630edb360459c0fd +Subproject commit 30532bd83ebac4e8985fb9d4ead91bc2722810fb diff --git a/dockernet/config/ica_host.json b/dockernet/config/ica_host.json index 0017667db7..3ca3c342f8 100644 --- a/dockernet/config/ica_host.json +++ b/dockernet/config/ica_host.json @@ -19,6 +19,8 @@ "/cosmos.distribution.v1beta1.MsgWithdrawDelegatorReward", "/cosmos.distribution.v1beta1.MsgSetWithdrawAddress", "/cosmos.distribution.v1beta1.MsgFundCommunityPool", + "/cosmos.authz.v1beta1.MsgGrant", + "/cosmos.authz.v1beta1.MsgRevoke", "/ibc.applications.transfer.v1.MsgTransfer", "/cosmwasm.wasm.v1.MsgExecuteContract", "/cosmwasm.wasm.v1.MsgInstantiateContract", diff --git a/dockernet/scripts/community-pool-staking/README.md b/dockernet/scripts/community-pool-staking/README.md index 95b2beae21..3bf8a1b9e3 100644 --- a/dockernet/scripts/community-pool-staking/README.md +++ b/dockernet/scripts/community-pool-staking/README.md @@ -45,7 +45,19 @@ bash dockernet/scripts/community-pool-staking/create_pool.sh ```bash bash dockernet/scripts/community-pool-staking/add_trade_route.sh ``` +* Liquid stake to create TVL +```bash +bash dockernet/scripts/community-pool-staking/stake.sh +``` * Finally, test the reinvestment flow by sending USDC to the withdrawal address. View `logs/balances.log` to watch the funds traverse the different accounts ```bash bash dockernet/scripts/community-pool-staking/reinvest.sh ``` +* To register a rebate, run the following script. +```bash +bash dockernet/scripts/community-pool-staking/rebate.sh +``` +* Then trigger reinvestment again. This time, you should notice USDC goes straight from the withdrawal account to the relevant community pool account. For Gaia, this account is the standard community pool, and for dYdX, the account is the community pool treasury. +```bash +bash dockernet/scripts/community-pool-staking/reinvest.sh +``` \ No newline at end of file diff --git a/dockernet/scripts/community-pool-staking/add_trade_route.sh b/dockernet/scripts/community-pool-staking/add_trade_route.sh index 173b7a9647..0b9b02ca87 100644 --- a/dockernet/scripts/community-pool-staking/add_trade_route.sh +++ b/dockernet/scripts/community-pool-staking/add_trade_route.sh @@ -5,8 +5,10 @@ source ${SCRIPT_DIR}/../../config.sh HOST_CHAIN=$REWARD_CONVERTER_HOST_ZONE HOST_VAL_ADDRESS=$(${HOST_CHAIN}_ADDRESS) -HOST_CHAIN_ID=$(GET_VAR_VALUE ${HOST_CHAIN}_CHAIN_ID) -HOST_DENOM=$(GET_VAR_VALUE ${HOST_CHAIN}_DENOM) +HOST_MAIN_CMD=$(GET_VAR_VALUE ${HOST_CHAIN}_MAIN_CMD) +HOST_CHAIN_ID=$(GET_VAR_VALUE ${HOST_CHAIN}_CHAIN_ID) +HOST_VAL_PREFIX=$(GET_VAR_VALUE ${HOST_CHAIN}_VAL_PREFIX) +HOST_DENOM=$(GET_VAR_VALUE ${HOST_CHAIN}_DENOM) GAS="--gas-prices 0.1ustrd --gas auto --gas-adjustment 1.3" @@ -21,6 +23,10 @@ host_to_noble_client=$(GET_CLIENT_ID_FROM_CHAIN_ID $HOST_CHAIN NOBLE) host_to_noble_connection=$(GET_CONNECTION_ID_FROM_CLIENT_ID $HOST_CHAIN $host_to_noble_client) host_to_noble_channel=$(GET_TRANSFER_CHANNEL_ID_FROM_CONNECTION_ID $HOST_CHAIN $host_to_noble_connection) +host_to_osmo_client=$(GET_CLIENT_ID_FROM_CHAIN_ID $HOST_CHAIN OSMO) +host_to_osmo_connection=$(GET_CONNECTION_ID_FROM_CLIENT_ID $HOST_CHAIN $host_to_osmo_client) +host_to_osmo_channel=$(GET_TRANSFER_CHANNEL_ID_FROM_CONNECTION_ID $HOST_CHAIN $host_to_osmo_connection) + noble_to_host_client=$(GET_CLIENT_ID_FROM_CHAIN_ID NOBLE $HOST_CHAIN) noble_to_host_connection=$(GET_CONNECTION_ID_FROM_CLIENT_ID NOBLE $noble_to_host_client) noble_to_host_channel=$(GET_TRANSFER_CHANNEL_ID_FROM_CONNECTION_ID NOBLE $noble_to_host_connection) @@ -60,11 +66,26 @@ echo " Client: $osmo_to_host_client" echo " Connection: $osmo_to_host_connection" echo " Transfer Channel: $osmo_to_host_channel" -echo -e "\nTransferring $USDC_DENOM to $HOST_DENOM to create ibc denom..." +echo -e "\n$HOST_CHAIN -> OSMO:" +echo " Client: $host_to_osmo_client" +echo " Connection: $host_to_osmo_connection" +echo " Transfer Channel: $host_to_osmo_channel" + +echo -e "\nTransferring $USDC_DENOM to $HOST_CHAIN to create ibc denom..." $NOBLE_MAIN_CMD tx ibc-transfer transfer transfer $noble_to_host_channel $HOST_VAL_ADDRESS 10000${USDC_DENOM} \ --from ${NOBLE_VAL_PREFIX}1 -y | TRIM_TX sleep 15 +echo -e "\nTransferring $USDC_DENOM to OSMO to create ibc denom..." +$NOBLE_MAIN_CMD tx ibc-transfer transfer transfer $noble_to_osmo_channel $(OSMO_ADDRESS) 10000${USDC_DENOM} \ + --from ${NOBLE_VAL_PREFIX}1 -y | TRIM_TX +sleep 15 + +echo -e "\nTransferring $HOST_DENOM to OSMO to create ibc denom..." +$HOST_MAIN_CMD tx ibc-transfer transfer transfer $host_to_osmo_channel $(OSMO_ADDRESS) 10000000${HOST_DENOM} \ + --from ${HOST_VAL_PREFIX}1 -y | TRIM_TX +sleep 15 + echo -e "\nDetermining IBC Denoms..." usdc_denom_on_host=$(GET_IBC_DENOM $HOST_CHAIN_ID $host_to_noble_channel $USDC_DENOM) usdc_denom_on_osmo=$(GET_IBC_DENOM OSMO $osmo_to_noble_channel $USDC_DENOM) diff --git a/dockernet/scripts/community-pool-staking/rebate.sh b/dockernet/scripts/community-pool-staking/rebate.sh new file mode 100644 index 0000000000..1bfad1c96f --- /dev/null +++ b/dockernet/scripts/community-pool-staking/rebate.sh @@ -0,0 +1,9 @@ +#!/bin/bash +set -eu +SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) +source ${SCRIPT_DIR}/../../config.sh + +HOST_CHAIN=$REWARD_CONVERTER_HOST_ZONE +HOST_CHAIN_ID=$(GET_VAR_VALUE ${HOST_CHAIN}_CHAIN_ID) + +$STRIDE_MAIN_CMD tx stakeibc set-rebate $HOST_CHAIN_ID 0.25 100000 --from admin -y \ No newline at end of file diff --git a/dockernet/scripts/community-pool-staking/trade.sh b/dockernet/scripts/community-pool-staking/trade.sh new file mode 100644 index 0000000000..2996dce7c6 --- /dev/null +++ b/dockernet/scripts/community-pool-staking/trade.sh @@ -0,0 +1,25 @@ +#!/bin/bash +set -eu +SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) +source ${SCRIPT_DIR}/../../config.sh + +TRADE_AMOUNT=997500 + +trade_account=$($STRIDE_MAIN_CMD q stakeibc list-trade-routes | grep trade_account -A 3 | grep address | awk '{print $2}') +host_denom_on_trade=$($STRIDE_MAIN_CMD q stakeibc list-trade-routes | grep host_denom_on_trade | awk '{print $2}') +reward_denom_on_trade=$($STRIDE_MAIN_CMD q stakeibc list-trade-routes | grep reward_denom_on_trade | awk '{print $2}') + +echo "Granting authz permissions..." +$STRIDE_MAIN_CMD tx stakeibc toggle-trade-controller $OSMO_CHAIN_ID grant $(OSMO_ADDRESS) --from admin -y +sleep 15 + +tx_file=${STATE}/${OSMO_NODE_PREFIX}1/swap_tx.json +$OSMO_MAIN_CMD tx gamm swap-exact-amount-in ${TRADE_AMOUNT}${reward_denom_on_trade} 1 \ + --swap-route-pool-ids 1 --swap-route-denoms $host_denom_on_trade \ + --from $trade_account --generate-only > $tx_file +sleep 5 + +echo "Executing swap through authz..." +$OSMO_MAIN_CMD tx authz exec $tx_file --from ${OSMO_VAL_PREFIX}1 -y | TRIM_TX +sleep 1 +rm -f $tx_file \ No newline at end of file diff --git a/dockernet/src/create_logs.sh b/dockernet/src/create_logs.sh index 0c22c43282..f89d62ec52 100755 --- a/dockernet/src/create_logs.sh +++ b/dockernet/src/create_logs.sh @@ -88,53 +88,57 @@ while true; do print_header "TRADE ROUTES" $state $STRIDE_MAIN_CMD q stakeibc list-trade-routes >> $state - print_separator "STAKETIA" $state - - print_header "HOST ZONE" $state - $STRIDE_MAIN_CMD q staketia host-zone >> $state - print_header "DELEGATION RECORDS" $state - $STRIDE_MAIN_CMD q staketia delegation-records >> $state - print_header "UNBONDING RECORDS" $state - $STRIDE_MAIN_CMD q staketia unbonding-records >> $state - print_header "REDEMPTION RECORDS" $state - $STRIDE_MAIN_CMD q staketia redemption-records >> $state - print_header "SLASH RECORDS" $state - $STRIDE_MAIN_CMD q staketia slash-records >> $state + host_chain="${HOST_CHAINS[0]}" + if [[ "$host_chain" == "GAIA" ]]; then + print_separator "STAKETIA" $state + + print_header "HOST ZONE" $state + $STRIDE_MAIN_CMD q staketia host-zone >> $state + print_header "DELEGATION RECORDS" $state + $STRIDE_MAIN_CMD q staketia delegation-records >> $state + print_header "UNBONDING RECORDS" $state + $STRIDE_MAIN_CMD q staketia unbonding-records >> $state + print_header "REDEMPTION RECORDS" $state + $STRIDE_MAIN_CMD q staketia redemption-records >> $state + print_header "SLASH RECORDS" $state + $STRIDE_MAIN_CMD q staketia slash-records >> $state + fi # Log stride stakeibc balances print_separator "VALIDATORS" $balances - host_chain="${HOST_CHAINS[0]}" host_val_address="$(${host_chain}_ADDRESS)" host_cmd=$(GET_VAR_VALUE ${host_chain}_MAIN_CMD) print_stride_balance $(STRIDE_ADDRESS) "STRIDE" print_host_balance $host_chain $host_val_address $host_chain - # Log stride staketia balances - print_separator "STAKETIA STRIDE" $balances - - deposit_address=$($STRIDE_MAIN_CMD keys show -a deposit) - redemption_address=$($STRIDE_MAIN_CMD keys show -a redemption) - claim_address=$($STRIDE_MAIN_CMD keys show -a claim) - fee_address=$($STRIDE_MAIN_CMD q auth module-account staketia_fee_address | grep "address:" | awk '{print $2}') - - print_stride_balance $deposit_address "DEPOSIT" - print_stride_balance $redemption_address "REDEMPTION" - print_stride_balance $claim_address "CLAIM" - print_stride_balance $fee_address "FEE" - - # Log staketia balance on host chain - print_separator "STAKETIA HOST" $balances - print_host_balance "$host_chain" $DELEGATION_ADDRESS "DELEGATION CONTROLLER" - print_host_balance "$host_chain" $REWARD_ADDRESS "REWARD CONTROLLER" - - # Log staketia delegations/undelegations - print_separator "STAKETIA STAKING" $balances - delegation_address=$($STRIDE_MAIN_CMD q staketia host-zone | grep "delegation_address" | awk '{print $2}') - - print_header "DELEGATIONS $host_chain" $balances - $host_cmd q staking delegations $delegation_address | grep -vE "pagination|total|next_key" >> $balances - print_header "UNBONDING-DELEGATIONS $host_chain" $balances - $host_cmd q staking unbonding-delegations $delegation_address | grep -vE "pagination|total|next_key" >> $balances + if [[ "$host_chain" == "GAIA" ]]; then + # Log stride staketia balances + print_separator "STAKETIA STRIDE" $balances + + deposit_address=$($STRIDE_MAIN_CMD keys show -a deposit) + redemption_address=$($STRIDE_MAIN_CMD keys show -a redemption) + claim_address=$($STRIDE_MAIN_CMD keys show -a claim) + fee_address=$($STRIDE_MAIN_CMD q auth module-account staketia_fee_address | grep "address:" | awk '{print $2}') + + print_stride_balance $deposit_address "DEPOSIT" + print_stride_balance $redemption_address "REDEMPTION" + print_stride_balance $claim_address "CLAIM" + print_stride_balance $fee_address "FEE" + + # Log staketia balance on host chain + print_separator "STAKETIA HOST" $balances + print_host_balance "$host_chain" $DELEGATION_ADDRESS "DELEGATION CONTROLLER" + print_host_balance "$host_chain" $REWARD_ADDRESS "REWARD CONTROLLER" + + # Log staketia delegations/undelegations + print_separator "STAKETIA STAKING" $balances + delegation_address=$($STRIDE_MAIN_CMD q staketia host-zone | grep "delegation_address" | awk '{print $2}') + + print_header "DELEGATIONS $host_chain" $balances + $host_cmd q staking delegations $delegation_address | grep -vE "pagination|total|next_key" >> $balances + print_header "UNBONDING-DELEGATIONS $host_chain" $balances + $host_cmd q staking unbonding-delegations $delegation_address | grep -vE "pagination|total|next_key" >> $balances + fi # Log stride channels print_separator "STRIDE" $channels @@ -184,21 +188,25 @@ while true; do print_stride_balance $community_pool_stake_address "COMMUNITY POOL STAKE HOLDING ACCT BALANCE" print_stride_balance $community_pool_redeem_address "COMMUNITY POOL REDEEM HOLDING ACCT BALANCE" + community_pool_treasury=$($STRIDE_MAIN_CMD q stakeibc show-host-zone $HOST_CHAIN_ID | grep community_pool_treasury | awk '{print $2}' | tr -d '"') + if [[ "$community_pool_treasury" != "" ]]; then + print_host_balance $chain $community_pool_treasury "COMMUNITY POOL TREASURY ADDRESS" + fi + # Log host channels print_separator "$chain" $channels $HOST_MAIN_CMD q ibc channel channels | grep -E "channel_id|port|state" >> $channels || true done - TRADE_ICA_ADDR=$($STRIDE_MAIN_CMD q stakeibc list-trade-routes | grep trade_account -A 2 | grep address | awk '{print $2}') if [[ "$TRADE_ICA_ADDR" == "$OSMO_ADDRESS_PREFIX"* ]]; then - print_header "TRADE ACCT BALANCE" >> $balances + print_header "TRADE ACCT BALANCE" $balances $OSMO_MAIN_CMD q bank balances $TRADE_ICA_ADDR >> $balances fi for chain in ${ACCESSORY_CHAINS[@]:-}; do ACCESSORY_MAIN_CMD=$(GET_VAR_VALUE ${chain}_MAIN_CMD) - print_header "========================== $chain =============================" >> $channels + print_header "========================== $chain =============================" $channels $ACCESSORY_MAIN_CMD q ibc channel channels | grep -E "channel_id|port|state" >> $channels || true done diff --git a/dockernet/src/init_chain.sh b/dockernet/src/init_chain.sh index a11210b906..44dd9def80 100644 --- a/dockernet/src/init_chain.sh +++ b/dockernet/src/init_chain.sh @@ -335,7 +335,7 @@ if [[ "$CHAIN" != "STRIDE" && "$CHAIN" != "HOST" ]]; then fi # wipe out the persistent peers for the main node (these are incorrectly autogenerated for each validator during collect-gentxs) -sed -i -E "s|persistent_peers = .*|persistent_peers = \"\"|g" $MAIN_CONFIG +sed -i -E "s|^persistent_peers = .*|persistent_peers = \"\"|g" $MAIN_CONFIG # update chain-specific genesis settings if [ "$CHAIN" == "STRIDE" ]; then diff --git a/dockernet/src/register_host.sh b/dockernet/src/register_host.sh index 6ef5f11da9..fc7252ddc4 100644 --- a/dockernet/src/register_host.sh +++ b/dockernet/src/register_host.sh @@ -23,9 +23,14 @@ if [[ "$CHAIN" == "GAIA" ]]; then LSM_ENABLED="true" fi +COMMUNITY_POOL_TREASURY_ADDRESS="" +if [[ "$CHAIN" == "DYDX" ]]; then + COMMUNITY_POOL_TREASURY_ADDRESS="--community-pool-treasury-address dydx15ztc7xy42tn2ukkc0qjthkucw9ac63pgp70urn" +fi + echo "$CHAIN - Registering host zone..." $STRIDE_MAIN_CMD tx stakeibc register-host-zone \ - $CONNECTION $HOST_DENOM $ADDRESS_PREFIX $IBC_DENOM $CHANNEL 1 $LSM_ENABLED \ + $CONNECTION $HOST_DENOM $ADDRESS_PREFIX $IBC_DENOM $CHANNEL 1 $LSM_ENABLED $COMMUNITY_POOL_TREASURY_ADDRESS \ --gas 1000000 --from $STRIDE_ADMIN_ACCT --home $DOCKERNET_HOME/state/stride1 -y | TRIM_TX sleep 10 diff --git a/dockernet/start_network.sh b/dockernet/start_network.sh index 831b5137ec..9cd6c36093 100755 --- a/dockernet/start_network.sh +++ b/dockernet/start_network.sh @@ -57,6 +57,8 @@ done # Start each chain, create the transfer channels and start the relayers +# For dydx, sleep before and after the relayers are setup to get it some time to startup +# since it's a computationally expensive chain bash $SRC/start_chain.sh bash $SRC/start_relayers.sh diff --git a/x/stakeibc/keeper/icqcallbacks_withdrawal_reward_balance.go b/x/stakeibc/keeper/icqcallbacks_withdrawal_reward_balance.go index 0fdbf05e04..fb66c69078 100644 --- a/x/stakeibc/keeper/icqcallbacks_withdrawal_reward_balance.go +++ b/x/stakeibc/keeper/icqcallbacks_withdrawal_reward_balance.go @@ -67,7 +67,7 @@ func WithdrawalRewardBalanceCallback(k Keeper, ctx sdk.Context, args []byte, que // If there's a rebate portion, fund the community pool with that amount if rebateAmount.GT(sdkmath.ZeroInt()) { - rebateToken := sdk.NewCoin(tradeRouteCallback.RewardDenom, rebateAmount) + rebateToken := sdk.NewCoin(tradeRoute.RewardDenomOnHostZone, rebateAmount) if err := k.FundCommunityPool(ctx, hostZone, rebateToken, types.ICAAccountType_WITHDRAWAL); err != nil { return errorsmod.Wrapf(err, "unable to submit fund community pool ICA") } diff --git a/x/stakeibc/keeper/reward_converter.go b/x/stakeibc/keeper/reward_converter.go index 78b1a8418a..554278dbdb 100644 --- a/x/stakeibc/keeper/reward_converter.go +++ b/x/stakeibc/keeper/reward_converter.go @@ -197,7 +197,9 @@ func (k Keeper) BuildTradeAuthzMsg( switch permissionChange { case types.AuthzPermissionChange_GRANT: authorization := authz.NewGenericAuthorization(swapMsgTypeUrl) - grant, err := authz.NewGrant(ctx.BlockTime(), authorization, nil) + expiration := ctx.BlockTime().Add(time.Hour * 24 * 365 * 100) // 100 years + + grant, err := authz.NewGrant(ctx.BlockTime(), authorization, &expiration) if err != nil { return nil, errorsmod.Wrapf(err, "unable to build grant struct") } @@ -206,12 +208,14 @@ func (k Keeper) BuildTradeAuthzMsg( Grantee: grantee, Grant: grant, }} + case types.AuthzPermissionChange_REVOKE: authzMsg = []proto.Message{&authz.MsgRevoke{ Granter: tradeRoute.TradeAccount.Address, Grantee: grantee, MsgTypeUrl: swapMsgTypeUrl, }} + default: return nil, errors.New("invalid permission change") } @@ -296,12 +300,6 @@ func (k Keeper) TransferRewardTokensHostToTrade(ctx sdk.Context, amount sdkmath. return nil } - // Similarly, if there's no price on the trade route yet, don't initiate the transfer because - // we know the swap will not be submitted - if route.TradeConfig.SwapPrice.IsZero() { - return nil - } - // Build the PFM transfer message from host to trade zone msg, err := k.BuildHostToTradeTransferMsg(ctx, amount, route) if err != nil {