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

Feature/stakedrop #7

Merged
merged 18 commits into from
Dec 23, 2024
Merged
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
4 changes: 3 additions & 1 deletion app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -697,14 +697,16 @@ func New(
app.TokenFactoryKeeper = tokenfactorykeeper.NewKeeper(
appCodec,
app.keys[tokenfactorytypes.StoreKey],
runtime.NewKVStoreService(keys[tokenfactorytypes.StoreKey]),
app.AccountKeeper,
app.BankKeeper,
app.DistrKeeper,
tokenFactoryCapabilities,
authtypes.FeeCollectorName,
authtypes.NewModuleAddress(govtypes.ModuleName).String(),
)

tfOpts := tokenbindings.RegisterCustomPlugins(&app.BankKeeper, &app.TokenFactoryKeeper)
tfOpts := tokenbindings.RegisterCustomPlugins(app.GRPCQueryRouter(), appCodec, &app.BankKeeper, &app.TokenFactoryKeeper, &app.LiquidityKeeper)
wasmOpts = append(wasmOpts, tfOpts...)

wasmDir := filepath.Join(homePath, "data")
Expand Down
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ require (
require (
cosmossdk.io/api v0.7.5
cosmossdk.io/client/v2 v2.0.0-beta.1
cosmossdk.io/collections v0.4.0
cosmossdk.io/core v0.11.1
cosmossdk.io/errors v1.0.1
cosmossdk.io/log v1.4.1
Expand All @@ -45,7 +46,7 @@ require (
cosmossdk.io/x/nft v0.1.1
cosmossdk.io/x/tx v0.13.4
cosmossdk.io/x/upgrade v0.1.4
github.com/Victor118/liquidity v1.7.1
github.com/Victor118/liquidity v1.7.7
github.com/cometbft/cometbft v0.38.11
github.com/cosmos/cosmos-db v1.0.2
github.com/cosmos/ibc-apps/modules/ibc-hooks/v8 v8.0.0-20240808203856-57803750a140
Expand All @@ -60,7 +61,6 @@ require (
cloud.google.com/go/compute/metadata v0.3.0 // indirect
cloud.google.com/go/iam v1.1.6 // indirect
cloud.google.com/go/storage v1.38.0 // indirect
cosmossdk.io/collections v0.4.0 // indirect
cosmossdk.io/depinject v1.0.0 // indirect
filippo.io/edwards25519 v1.0.0 // indirect
github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -240,8 +240,8 @@ github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
github.com/Victor118/liquidity v1.7.1 h1:SMMUciOFAPVo/o0PDKpMiZ7CKYGO24QTLe/FLSfujsc=
github.com/Victor118/liquidity v1.7.1/go.mod h1:RRGlMTp7z3AKiwbsc9pu4g0hn/UpEyuCrtp3fmzHlGI=
github.com/Victor118/liquidity v1.7.7 h1:sHW4qR2FxJiM9P7ReKCOL3IZHDM+bx+OVWuWAbZ5+Fg=
github.com/Victor118/liquidity v1.7.7/go.mod h1:RRGlMTp7z3AKiwbsc9pu4g0hn/UpEyuCrtp3fmzHlGI=
github.com/VividCortex/gohistogram v1.0.0 h1:6+hBz+qvs0JOrrNhhmR7lFxo5sINxBCGXrdtl/UvroE=
github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g=
github.com/adlio/schema v1.3.3 h1:oBJn8I02PyTB466pZO1UZEn1TV5XLlifBSyMrmHl/1I=
Expand Down
6 changes: 6 additions & 0 deletions proto/osmosis/tokenfactory/v1beta1/params.proto
Original file line number Diff line number Diff line change
Expand Up @@ -52,4 +52,10 @@ message Params {
];

repeated string free_mint_whitelist_addresses = 5;

cosmos.base.v1beta1.Coin stakedrop_charge_per_block = 6 [
(gogoproto.moretags) = "yaml:\"stakedrop_charge_per_block\"",
(gogoproto.nullable) = false
];

}
43 changes: 43 additions & 0 deletions proto/osmosis/tokenfactory/v1beta1/query.proto
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ import "gogoproto/gogo.proto";
import "google/api/annotations.proto";
import "cosmos/base/query/v1beta1/pagination.proto";
import "osmosis/tokenfactory/v1beta1/authorityMetadata.proto";
import "osmosis/tokenfactory/v1beta1/stakedrop.proto";
import "osmosis/tokenfactory/v1beta1/params.proto";
import "amino/amino.proto";

option go_package = "github.com/ChihuahuaChain/chihuahua/x/tokenfactory/types";

Expand All @@ -32,6 +34,18 @@ service Query {
option (google.api.http).get =
"/osmosis/tokenfactory/v1beta1/denoms_from_creator/{creator}";
}

rpc StakeDrops(QueryStakeDropsRequest)
returns (QueryStakeDropsResponse) {
option (google.api.http).get =
"/osmosis/tokenfactory/v1beta1/stakedrops";
}

rpc StakeDropsFromDenom(QueryStakeDropFromDenomRequest)
returns (QueryStakeDropFromDenomResponse) {
option (google.api.http).get =
"/osmosis/tokenfactory/v1beta1/stakedrops_from_denom/{denom}";
}
}

// QueryParamsRequest is the request type for the Query/Params RPC method.
Expand Down Expand Up @@ -69,3 +83,32 @@ message QueryDenomsFromCreatorRequest {
message QueryDenomsFromCreatorResponse {
repeated string denoms = 1 [ (gogoproto.moretags) = "yaml:\"denoms\"" ];
}

// QueryDenomsMetadataRequest is the request type for the Query/DenomsMetadata RPC method.
message QueryStakeDropsRequest {
// pagination defines an optional pagination for the request.
cosmos.base.query.v1beta1.PageRequest pagination = 1;
}

// QueryDenomsMetadataResponse is the response type for the Query/DenomsMetadata RPC
// method.
message QueryStakeDropsResponse {
// metadata provides the client information for all the registered tokens.
repeated Stakedrop stakedrops = 1 [(gogoproto.nullable) = false, (amino.dont_omitempty) = true];

// pagination defines the pagination in the response.
cosmos.base.query.v1beta1.PageResponse pagination = 2;
}

// QueryDenomsFromCreatorRequest defines the request structure for the
// DenomsFromCreator gRPC query.
message QueryStakeDropFromDenomRequest {
string denom = 1 [ (gogoproto.moretags) = "yaml:\"denom\"" ];
}

// QueryDenomsFromCreatorRequest defines the response structure for the
// DenomsFromCreator gRPC query.
message QueryStakeDropFromDenomResponse {
repeated Stakedrop stakedrops = 1 [(gogoproto.nullable) = false, (amino.dont_omitempty) = true];
}

23 changes: 23 additions & 0 deletions proto/osmosis/tokenfactory/v1beta1/stakedrop.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
syntax = "proto3";
package osmosis.tokenfactory.v1beta1;

import "gogoproto/gogo.proto";
import "cosmos/base/v1beta1/coin.proto";

option go_package = "github.com/ChihuahuaChain/chihuahua/x/tokenfactory/types";


message Stakedrop {

cosmos.base.v1beta1.Coin amount = 1 [
(gogoproto.moretags) = "yaml:\"amount\"",
(gogoproto.nullable) = false
];
cosmos.base.v1beta1.Coin amount_per_block = 2 [
(gogoproto.moretags) = "yaml:\"amount\"",
(gogoproto.nullable) = false
];

int64 start_block = 3;
int64 end_block = 4;
}
19 changes: 19 additions & 0 deletions proto/osmosis/tokenfactory/v1beta1/tx.proto
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ option go_package = "github.com/ChihuahuaChain/chihuahua/x/tokenfactory/types";
// Msg defines the tokefactory module's gRPC message service.
service Msg {
rpc CreateDenom(MsgCreateDenom) returns (MsgCreateDenomResponse);
rpc CreateStakeDrop(MsgCreateStakeDrop) returns (MsgCreateStakeDropResponse);
rpc Mint(MsgMint) returns (MsgMintResponse);
rpc Burn(MsgBurn) returns (MsgBurnResponse);
rpc ChangeAdmin(MsgChangeAdmin) returns (MsgChangeAdminResponse);
Expand Down Expand Up @@ -50,6 +51,24 @@ message MsgCreateDenomResponse {
string new_token_denom = 1
[ (gogoproto.moretags) = "yaml:\"new_token_denom\"" ];
}
// It allows the creator (sender) of a denom to launch a stakedrop to chain delegators
//between block 'startBlock' and 'endBlock'
message MsgCreateStakeDrop {
option (cosmos.msg.v1.signer) = "sender";

string sender = 1 [ (gogoproto.moretags) = "yaml:\"sender\"" ];
//amount to stakedrop
cosmos.base.v1beta1.Coin amount = 2 [
(gogoproto.moretags) = "yaml:\"amount\"",
(gogoproto.nullable) = false
];

int64 start_block = 3;
int64 end_block = 4;
}

message MsgCreateStakeDropResponse {}


// MsgMint is the sdk.Msg type for allowing an admin account to mint
// more of a token. For now, we only support minting to the sender account
Expand Down
85 changes: 85 additions & 0 deletions x/tokenfactory/abci.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
package tokenfactory

import (
"cosmossdk.io/collections"
"cosmossdk.io/math"
"github.com/ChihuahuaChain/chihuahua/app/params"
"github.com/ChihuahuaChain/chihuahua/x/tokenfactory/keeper"
"github.com/ChihuahuaChain/chihuahua/x/tokenfactory/types"
"github.com/cosmos/cosmos-sdk/telemetry"
sdk "github.com/cosmos/cosmos-sdk/types"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
)

// BeginBlocker
func BeginBlocker(ctx sdk.Context, k keeper.Keeper, bankKeeper types.BankKeeper) error {
defer telemetry.ModuleMeasureSince(types.ModuleName, ctx.BlockTime(), telemetry.MetricKeyEndBlocker)

rng := collections.NewPrefixUntilPairRange[uint64, uint64](uint64(ctx.BlockHeight()))
iter, err := k.ActiveStakedrop.Iterate(ctx, rng)

if err != nil {

return err
}
defer iter.Close()

coinsToSend := sdk.NewCoins()
nativeCoinToSend := sdk.NewCoin(params.BondDenom, math.NewInt(0))

for ; iter.Valid(); iter.Next() {
stakeDrop, err := iter.KeyValue()
if err != nil {

return err
}

if ctx.BlockHeight() >= stakeDrop.Value.StartBlock && ctx.BlockHeight() < (stakeDrop.Value.EndBlock) {
if stakeDrop.Value.Amount.Denom == params.BondDenom {
nativeCoinToSend = nativeCoinToSend.Add(stakeDrop.Value.AmountPerBlock)
} else {
coinsToSend = coinsToSend.Add(stakeDrop.Value.AmountPerBlock)
}

} else if ctx.BlockHeight() == stakeDrop.Value.EndBlock {
restAmount := stakeDrop.Value.Amount.Amount.Sub(stakeDrop.Value.AmountPerBlock.Amount.Mul(math.NewInt(stakeDrop.Value.EndBlock - stakeDrop.Value.StartBlock)))
if stakeDrop.Value.Amount.Denom == params.BondDenom {
nativeCoinToSend = nativeCoinToSend.Add(sdk.NewCoin(stakeDrop.Value.Amount.Denom, restAmount))
} else {
coinsToSend = coinsToSend.Add(sdk.NewCoin(stakeDrop.Value.Amount.Denom, restAmount))
}

} else if ctx.BlockHeight() > stakeDrop.Value.EndBlock {
err = k.ActiveStakedrop.Remove(ctx, stakeDrop.Key)
if err != nil {

ctx.Logger().Error("failed to remove stakedrop", "error", err)
}
}
}
if !coinsToSend.Empty() {
err = bankKeeper.MintCoins(ctx, types.ModuleName, coinsToSend)
if err != nil {
return err
}
err = bankKeeper.SendCoinsFromModuleToModule(ctx, types.ModuleName, k.FeeCollectorName, sdk.NewCoins(coinsToSend...))
if err != nil {
return err
}
}
if nativeCoinToSend.Amount.IsPositive() {
spendableAmount := bankKeeper.GetBalance(ctx, authtypes.NewModuleAddress(types.ModuleName), params.BondDenom)
if spendableAmount.IsLT(nativeCoinToSend) {
nativeCoinToSend = spendableAmount
}
if nativeCoinToSend.IsPositive() {
err = bankKeeper.SendCoinsFromModuleToModule(ctx, types.ModuleName, k.FeeCollectorName, sdk.NewCoins(nativeCoinToSend))
if err != nil {
return err
}
}

}

return nil
}
Loading
Loading