Skip to content

Commit

Permalink
feat:sweep axelarcork module acct balances in end blocker (#270)
Browse files Browse the repository at this point in the history
* Sweep balances in axelarcork EndBlocker

* Fmt

* Comment

* Use GetSenderAccount method

* Fix syntax errors in abci.go

* Enable mod acc sends, fix community spend sender

* handle module send error in axelar community spend

* Working integration test for sweeping

* Make linter happy

* Improvements to ABCI logic

* Add test delay

---------

Co-authored-by: Eric Bolten <[email protected]>
  • Loading branch information
cbrit and EricBolten authored Jan 30, 2024
1 parent 32d2ecd commit 73e0166
Show file tree
Hide file tree
Showing 3 changed files with 96 additions and 1 deletion.
50 changes: 50 additions & 0 deletions integration_tests/axelarcork_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ import (
"cosmossdk.io/math"
"github.com/cosmos/cosmos-sdk/client"
sdk "github.com/cosmos/cosmos-sdk/types"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
distributiontypes "github.com/cosmos/cosmos-sdk/x/distribution/types"
govtypesv1beta1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1"
"github.com/ethereum/go-ethereum/common"
"github.com/golang/protobuf/proto" //nolint:staticcheck
Expand Down Expand Up @@ -456,6 +459,53 @@ func (s *IntegrationTestSuite) TestAxelarCork() {
chainConfigurationsResponse, err = axelarcorkQueryClient.QueryChainConfigurations(context.Background(), &types.QueryChainConfigurationsRequest{})
s.Require().NoError(err)
s.Require().Empty(chainConfigurationsResponse.Configurations)

//////////////////////////////////////////
// Test module account balance sweeping //
//////////////////////////////////////////

// Get the baseline balance of the distribution community pool, send funds to the axelarcork module account,
// verify they are received, and that the balance is zero on the next block.
s.T().Log("Querying distribution community pool balance")
distributionQueryClient := distributiontypes.NewQueryClient(orch0ClientCtx)
distributionCommunityPoolResponse, err := distributionQueryClient.CommunityPool(context.Background(), &distributiontypes.QueryCommunityPoolRequest{})
s.Require().NoError(err)
initialPool := distributionCommunityPoolResponse.Pool

// Send all of orchestrator's sweep denom and some usomm
s.T().Log("Querying orchestrator account balances")
bankQueryClient := banktypes.NewQueryClient(orch0ClientCtx)
orch0AccountResponse, err := bankQueryClient.AllBalances(context.Background(), &banktypes.QueryAllBalancesRequest{Address: orch0.address().String()})
s.Require().NoError(err)
orch0Balances := orch0AccountResponse.Balances
usommToSend := sdk.NewCoin(testDenom, math.NewInt(1000))
found, sweepDenomToSend := orch0Balances.Find(axelarSweepDenom)
s.Require().True(found, "orch0 doesn't have any sweep test denom funds")
orch0SweepFunds := sdk.Coins{
sweepDenomToSend,
usommToSend,
}

s.T().Log("Sending funds to axelarcork module account")
axelarcorkModuleAddress := authtypes.NewModuleAddress(types.ModuleName)
sendFundsToAxelarcorkMsg := banktypes.NewMsgSend(
orch0.address(),
axelarcorkModuleAddress,
orch0SweepFunds,
)
sendResponse, err := s.chain.sendMsgs(*orch0ClientCtx, sendFundsToAxelarcorkMsg)
s.Require().NoError(err)
s.Require().Zero(sendResponse.Code, "raw log: %s", sendResponse.RawLog)
s.T().Log("Verifying distribution community pool balances includes the swept funds")

// Short delay to ensure a new block is queried
time.Sleep(10 * time.Second)

// Verify fund appear in the community pool
distributionCommunityPoolResponse, err = distributionQueryClient.CommunityPool(context.Background(), &distributiontypes.QueryCommunityPoolRequest{})
s.Require().NoError(err)
poolAfterSweep := initialPool.Add(sdk.NewDecCoinsFromCoins(usommToSend)...).Add(sdk.NewDecCoinsFromCoins(sweepDenomToSend)...)
s.Require().Equal(poolAfterSweep, distributionCommunityPoolResponse.Pool)
})
}

Expand Down
20 changes: 19 additions & 1 deletion integration_tests/setup_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ HOqHGS8ApZcunRauDAIwRtgceZpkS92KuP3QOUotAH/nnCzp7X1lVzGOSTBRTVYJ
pohf4PJrfacqpi7PoXBk
-----END CERTIFICATE-----
`
axelarSweepDenom = "sweep"
)

var (
Expand Down Expand Up @@ -319,7 +320,19 @@ func (s *IntegrationTestSuite) initGenesis() {
Exponent: 0,
},
},
})
},
banktypes.Metadata{
Description: "Test token for sweeping",
Display: axelarSweepDenom,
Base: axelarSweepDenom,
Name: axelarSweepDenom,
DenomUnits: []*banktypes.DenomUnit{
{
Denom: axelarSweepDenom,
Exponent: 0,
},
},
})

// Set up auction module with some coins to auction off
balance := banktypes.Balance{
Expand All @@ -330,8 +343,13 @@ func (s *IntegrationTestSuite) initGenesis() {
Address: authtypes.NewModuleAddress(disttypes.ModuleName).String(),
Coins: sdk.NewCoins(sdk.NewCoin(params.BaseCoinUnit, sdk.NewInt(1000000000))),
}
orchSweepBalance := banktypes.Balance{
Address: s.chain.orchestrators[0].address().String(),
Coins: sdk.NewCoins(sdk.NewCoin(axelarSweepDenom, sdk.NewInt(2000000000))),
}
bankGenState.Balances = append(bankGenState.Balances, balance)
bankGenState.Balances = append(bankGenState.Balances, distBalance)
bankGenState.Balances = append(bankGenState.Balances, orchSweepBalance)

bz, err := cdc.MarshalJSON(&bankGenState)
s.Require().NoError(err)
Expand Down
27 changes: 27 additions & 0 deletions x/axelarcork/keeper/abci.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (

"github.com/ethereum/go-ethereum/common"

distributionTypes "github.com/cosmos/cosmos-sdk/x/distribution/types"
"github.com/peggyjv/sommelier/v7/x/axelarcork/types"

sdk "github.com/cosmos/cosmos-sdk/types"
Expand Down Expand Up @@ -54,4 +55,30 @@ func (k Keeper) EndBlocker(ctx sdk.Context) {

return false
})

// Sweep all axelarcork sender module account balances to the community pool. Because this account is the
// sender for transfers created by RelayCork calls, funds will not be returned to the caller if the IBC
// transfer fails or gas is refunded.
moduleAcct := k.GetSenderAccount(ctx)
balances := k.bankKeeper.GetAllBalances(ctx, moduleAcct.GetAddress())
balancesForPool := sdk.Coins{}

for _, b := range balances {
if b.Amount.IsPositive() {
balancesForPool.Add(b)
}
}

if balancesForPool.Len() == 0 {
return
}

if err := k.bankKeeper.SendCoinsFromModuleToModule(ctx, types.ModuleName, distributionTypes.ModuleName, balancesForPool); err != nil {
panic(err)
}

feePool := k.distributionKeeper.GetFeePool(ctx)
feePool.CommunityPool = feePool.CommunityPool.Add(sdk.NewDecCoinsFromCoins(balancesForPool...)...)

k.distributionKeeper.SetFeePool(ctx, feePool)
}

0 comments on commit 73e0166

Please sign in to comment.