Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: send to arkeo-reserve when claim period ends #317

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ Contains bug fixes.
Contains all the PRs that improved the code without changing the behaviors.
-->

### Added
- Move funds from claim to liquidity reserve when airdrop ends

# v1.0.5-Prerelease
### Added
- Arkeo testnet validator addresses to airdrop
Expand Down
38 changes: 38 additions & 0 deletions x/claim/keeper/claim.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package keeper

import (
"context"
"strings"

sdkerror "cosmossdk.io/errors"
Expand All @@ -14,6 +15,32 @@ import (
"github.com/arkeonetwork/arkeo/x/claim/types"
)

// Key for tracking if end of airdrop transfer has occurred
var MoveClaimTokensKey = []byte("MoveClaimTokens")

// EndBlocker is called at the end of every block
func (k Keeper) EndBlocker(ctx context.Context) {
sdkCtx := sdk.UnwrapSDKContext(ctx)
store := sdkCtx.KVStore(k.storeKey)

// Check if we've already done the transfer
if store.Has(MoveClaimTokensKey) {
return
}

params := k.GetParams(sdkCtx)
// Check if we've passed the end of the airdrop
if sdkCtx.BlockTime().After(params.AirdropStartTime.Add(params.DurationUntilDecay).Add(params.DurationOfDecay)) {
err := k.TransferRemainingToReserve(sdkCtx)
if err != nil {
k.Logger(ctx).Error("failed to transfer remaining tokens to reserve", "error", err)
return
}

store.Set(MoveClaimTokensKey, []byte{1})
}
}

// SetClaimRecord sets a claim record for an address in store
func (k Keeper) SetClaimRecord(ctx sdk.Context, claimRecord types.ClaimRecord) error {
// validate address if valid based on chain
Expand Down Expand Up @@ -169,6 +196,17 @@ func (k Keeper) GetClaimableAmountForAction(ctx sdk.Context, addr string, action
return claimableCoin, nil
}

// TransferRemainingToReserve transfers remaining funds to the reserve module when airdrop period ends
func (k Keeper) TransferRemainingToReserve(ctx sdk.Context) error {
remainingAmount := k.GetModuleAccountBalance(ctx)

if remainingAmount.IsZero() {
return nil
}

return k.bankKeeper.SendCoinsFromModuleToModule(ctx, types.ModuleName, "arkeo-reserve", sdk.NewCoins(remainingAmount))
}

// GetModuleAccountBalance gets the airdrop coin balance of module account
func (k Keeper) GetModuleAccountAddress(ctx sdk.Context) sdk.AccAddress {
return k.accountKeeper.GetModuleAddress(types.ModuleName)
Expand Down
41 changes: 41 additions & 0 deletions x/claim/keeper/claim_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package keeper_test

import (
"testing"
"time"

testkeeper "github.com/arkeonetwork/arkeo/testutil/keeper"
"github.com/arkeonetwork/arkeo/testutil/utils"
Expand Down Expand Up @@ -357,3 +358,43 @@ func TestClaimDecay(t *testing.T) {
balanceAfter3 := keepers.BankKeeper.GetBalance(sdkCtx, addrArkeo3, types.DefaultClaimDenom)
require.Equal(t, balanceAfter3.Sub(balanceBefore3), sdk.NewInt64Coin(types.DefaultClaimDenom, 0))
}

func TestEndBlockerTransferToReserve(t *testing.T) {
reserveModuleName := "arkeo-reserve"
_, keepers, ctx := setupMsgServer(t)
sdkCtx := sdk.UnwrapSDKContext(ctx)

// Setup initial claim module balance
initialModuleBalance := sdk.NewInt64Coin(types.DefaultClaimDenom, 1000)
err := keepers.BankKeeper.MintCoins(sdkCtx, types.ModuleName, sdk.NewCoins(initialModuleBalance))
require.NoError(t, err)

// Verify initial balances
claimModuleBalance := keepers.BankKeeper.GetBalance(sdkCtx, keepers.ClaimKeeper.GetModuleAccountAddress(sdkCtx), types.DefaultClaimDenom)
require.Equal(t, initialModuleBalance, claimModuleBalance)

reserveModuleBalance := keepers.BankKeeper.GetBalance(sdkCtx, keepers.AccountKeeper.GetModuleAddress(reserveModuleName), types.DefaultClaimDenom)
require.True(t, reserveModuleBalance.IsZero())

// Set time to after airdrop end
params := keepers.ClaimKeeper.GetParams(sdkCtx)
sdkCtx = sdkCtx.WithBlockTime(params.AirdropStartTime.Add(params.DurationUntilDecay).Add(params.DurationOfDecay).Add(time.Second))

// Trigger end blocker
keepers.ClaimKeeper.EndBlocker(sdkCtx)

// Verify balances after transfer
claimModuleBalanceAfter := keepers.BankKeeper.GetBalance(sdkCtx, keepers.ClaimKeeper.GetModuleAccountAddress(sdkCtx), types.DefaultClaimDenom)
require.True(t, claimModuleBalanceAfter.IsZero())

reserveModuleBalanceAfter := keepers.BankKeeper.GetBalance(sdkCtx, keepers.AccountKeeper.GetModuleAddress(reserveModuleName), types.DefaultClaimDenom)
require.Equal(t, initialModuleBalance, reserveModuleBalanceAfter)

// Verify that running EndBlocker again doesn't transfer more tokens
err = keepers.BankKeeper.MintCoins(sdkCtx, types.ModuleName, sdk.NewCoins(initialModuleBalance)) // add more coins to claim module account
require.NoError(t, err)

keepers.ClaimKeeper.EndBlocker(sdkCtx)
reserveModuleBalanceFinal := keepers.BankKeeper.GetBalance(sdkCtx, keepers.AccountKeeper.GetModuleAddress(reserveModuleName), types.DefaultClaimDenom)
require.Equal(t, initialModuleBalance, reserveModuleBalanceFinal)
}
3 changes: 2 additions & 1 deletion x/claim/module.go
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,8 @@ func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec) json.Raw
func (AppModule) ConsensusVersion() uint64 { return 1 }

// EndBlock contains the logic that is automatically triggered at the end of each block
func (am AppModule) EndBlock(_ context.Context) ([]abci.ValidatorUpdate, error) {
func (am AppModule) EndBlock(ctx context.Context) ([]abci.ValidatorUpdate, error) {
am.keeper.EndBlocker(ctx)
return []abci.ValidatorUpdate{}, nil
}

Expand Down
Loading