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

x/tokenfactory create denom fee #1435

Merged
merged 6 commits into from
May 6, 2022
Merged
Show file tree
Hide file tree
Changes from 4 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
2 changes: 2 additions & 0 deletions app/keepers/keepers.go
Original file line number Diff line number Diff line change
Expand Up @@ -313,8 +313,10 @@ func (appKeepers *AppKeepers) InitNormalKeepers(
tokenFactoryKeeper := tokenfactorykeeper.NewKeeper(
appCodec,
appKeepers.keys[tokenfactorytypes.StoreKey],
appKeepers.GetSubspace(tokenfactorytypes.ModuleName),
appKeepers.AccountKeeper,
appKeepers.BankKeeper.WithMintCoinsRestriction(tokenfactorytypes.NewTokenFactoryDenomMintCoinsRestriction()),
appKeepers.DistrKeeper,
)
appKeepers.TokenFactoryKeeper = &tokenFactoryKeeper

Expand Down
99 changes: 99 additions & 0 deletions docs/core/proto-docs.md
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,8 @@
- [MsgBeginUnlockingAll](#osmosis.lockup.MsgBeginUnlockingAll)
- [MsgBeginUnlockingAllResponse](#osmosis.lockup.MsgBeginUnlockingAllResponse)
- [MsgBeginUnlockingResponse](#osmosis.lockup.MsgBeginUnlockingResponse)
- [MsgExtendLockup](#osmosis.lockup.MsgExtendLockup)
- [MsgExtendLockupResponse](#osmosis.lockup.MsgExtendLockupResponse)
- [MsgLockTokens](#osmosis.lockup.MsgLockTokens)
- [MsgLockTokensResponse](#osmosis.lockup.MsgLockTokensResponse)

Expand Down Expand Up @@ -280,6 +282,9 @@
- [osmosis/tokenfactory/v1beta1/authorityMetadata.proto](#osmosis/tokenfactory/v1beta1/authorityMetadata.proto)
- [DenomAuthorityMetadata](#osmosis.tokenfactory.v1beta1.DenomAuthorityMetadata)

- [osmosis/tokenfactory/v1beta1/params.proto](#osmosis/tokenfactory/v1beta1/params.proto)
- [Params](#osmosis.tokenfactory.v1beta1.Params)

- [osmosis/tokenfactory/v1beta1/genesis.proto](#osmosis/tokenfactory/v1beta1/genesis.proto)
- [GenesisDenom](#osmosis.tokenfactory.v1beta1.GenesisDenom)
- [GenesisState](#osmosis.tokenfactory.v1beta1.GenesisState)
Expand All @@ -289,6 +294,8 @@
- [QueryDenomAuthorityMetadataResponse](#osmosis.tokenfactory.v1beta1.QueryDenomAuthorityMetadataResponse)
- [QueryDenomsFromCreatorRequest](#osmosis.tokenfactory.v1beta1.QueryDenomsFromCreatorRequest)
- [QueryDenomsFromCreatorResponse](#osmosis.tokenfactory.v1beta1.QueryDenomsFromCreatorResponse)
- [QueryParamsRequest](#osmosis.tokenfactory.v1beta1.QueryParamsRequest)
- [QueryParamsResponse](#osmosis.tokenfactory.v1beta1.QueryParamsResponse)

- [Query](#osmosis.tokenfactory.v1beta1.Query)

Expand Down Expand Up @@ -2423,6 +2430,39 @@ Query defines the gRPC querier service.



<a name="osmosis.lockup.MsgExtendLockup"></a>

### MsgExtendLockup
MsgExtendLockup extends the existing lockup's duration.
The new duration is longer than the original.


| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| `owner` | [string](#string) | | |
| `ID` | [uint64](#uint64) | | |
| `duration` | [google.protobuf.Duration](#google.protobuf.Duration) | | duration to be set. fails if lower than the current duration, or is unlocking |






<a name="osmosis.lockup.MsgExtendLockupResponse"></a>

### MsgExtendLockupResponse



| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| `success` | [bool](#bool) | | |






<a name="osmosis.lockup.MsgLockTokens"></a>

### MsgLockTokens
Expand Down Expand Up @@ -2471,6 +2511,7 @@ Msg defines the Msg service.
| `LockTokens` | [MsgLockTokens](#osmosis.lockup.MsgLockTokens) | [MsgLockTokensResponse](#osmosis.lockup.MsgLockTokensResponse) | LockTokens lock tokens | |
| `BeginUnlockingAll` | [MsgBeginUnlockingAll](#osmosis.lockup.MsgBeginUnlockingAll) | [MsgBeginUnlockingAllResponse](#osmosis.lockup.MsgBeginUnlockingAllResponse) | BeginUnlockingAll begin unlocking all tokens | |
| `BeginUnlocking` | [MsgBeginUnlocking](#osmosis.lockup.MsgBeginUnlocking) | [MsgBeginUnlockingResponse](#osmosis.lockup.MsgBeginUnlockingResponse) | MsgBeginUnlocking begins unlocking tokens by lock ID | |
| `ExtendLockup` | [MsgExtendLockup](#osmosis.lockup.MsgExtendLockup) | [MsgExtendLockupResponse](#osmosis.lockup.MsgExtendLockupResponse) | MsgEditLockup edits the existing lockups by lock ID | |

<!-- end services -->

Expand Down Expand Up @@ -3942,6 +3983,37 @@ permission, but is planned to be extended to the future.



<!-- end messages -->

<!-- end enums -->

<!-- end HasExtensions -->

<!-- end services -->



<a name="osmosis/tokenfactory/v1beta1/params.proto"></a>
<p align="right"><a href="#top">Top</a></p>

## osmosis/tokenfactory/v1beta1/params.proto



<a name="osmosis.tokenfactory.v1beta1.Params"></a>

### Params
Params holds parameters for the tokenfactory module


| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| `denom_creation_fee` | [cosmos.base.v1beta1.Coin](#cosmos.base.v1beta1.Coin) | repeated | |





<!-- end messages -->

<!-- end enums -->
Expand Down Expand Up @@ -3983,6 +4055,7 @@ GenesisState defines the tokenfactory module's genesis state.

| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| `params` | [Params](#osmosis.tokenfactory.v1beta1.Params) | | params defines the paramaters of the module. |
| `factory_denoms` | [GenesisDenom](#osmosis.tokenfactory.v1beta1.GenesisDenom) | repeated | |


Expand Down Expand Up @@ -4065,6 +4138,31 @@ GenesisState defines the tokenfactory module's genesis state.




<a name="osmosis.tokenfactory.v1beta1.QueryParamsRequest"></a>

### QueryParamsRequest
QueryParamsRequest is the request type for the Query/Params RPC method.






<a name="osmosis.tokenfactory.v1beta1.QueryParamsResponse"></a>

### QueryParamsResponse
QueryParamsResponse is the response type for the Query/Params RPC method.


| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| `params` | [Params](#osmosis.tokenfactory.v1beta1.Params) | | params defines the parameters of the module. |





<!-- end messages -->

<!-- end enums -->
Expand All @@ -4079,6 +4177,7 @@ Query defines the gRPC querier service.

| Method Name | Request Type | Response Type | Description | HTTP Verb | Endpoint |
| ----------- | ------------ | ------------- | ------------| ------- | -------- |
| `Params` | [QueryParamsRequest](#osmosis.tokenfactory.v1beta1.QueryParamsRequest) | [QueryParamsResponse](#osmosis.tokenfactory.v1beta1.QueryParamsResponse) | Params returns the total set of minting parameters. | GET|/osmosis/tokenfactory/v1beta1/params|
| `DenomAuthorityMetadata` | [QueryDenomAuthorityMetadataRequest](#osmosis.tokenfactory.v1beta1.QueryDenomAuthorityMetadataRequest) | [QueryDenomAuthorityMetadataResponse](#osmosis.tokenfactory.v1beta1.QueryDenomAuthorityMetadataResponse) | | GET|/osmosis/tokenfactory/v1beta1/denoms/{denom}/authority_metadata|
| `DenomsFromCreator` | [QueryDenomsFromCreatorRequest](#osmosis.tokenfactory.v1beta1.QueryDenomsFromCreatorRequest) | [QueryDenomsFromCreatorResponse](#osmosis.tokenfactory.v1beta1.QueryDenomsFromCreatorResponse) | | GET|/osmosis/tokenfactory/v1beta1/denoms_from_creator/{creator}|

Expand Down
5 changes: 3 additions & 2 deletions proto/osmosis/lockup/tx.proto
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,13 @@ message MsgBeginUnlocking {
message MsgBeginUnlockingResponse { bool success = 1; }

// MsgExtendLockup extends the existing lockup's duration.
// The new duration is longer than the original.
// The new duration is longer than the original.
message MsgExtendLockup {
string owner = 1 [ (gogoproto.moretags) = "yaml:\"owner\"" ];
uint64 ID = 2;

// duration to be set. fails if lower than the current duration, or is unlocking
// duration to be set. fails if lower than the current duration, or is
// unlocking
google.protobuf.Duration duration = 3 [
(gogoproto.nullable) = false,
(gogoproto.stdduration) = true,
Expand Down
6 changes: 4 additions & 2 deletions proto/osmosis/tokenfactory/v1beta1/genesis.proto
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,16 @@ package osmosis.tokenfactory.v1beta1;

import "gogoproto/gogo.proto";
import "osmosis/tokenfactory/v1beta1/authorityMetadata.proto";
import "osmosis/tokenfactory/v1beta1/params.proto";

option go_package = "github.com/osmosis-labs/osmosis/v7/x/tokenfactory/types";

// GenesisState defines the tokenfactory module's genesis state.
message GenesisState {
option (gogoproto.equal) = true;
// params defines the paramaters of the module.
Params params = 1 [ (gogoproto.nullable) = false ];

repeated GenesisDenom factory_denoms = 1 [
repeated GenesisDenom factory_denoms = 2 [
(gogoproto.moretags) = "yaml:\"factory_denoms\"",
(gogoproto.nullable) = false
];
Expand Down
18 changes: 18 additions & 0 deletions proto/osmosis/tokenfactory/v1beta1/params.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
syntax = "proto3";
package osmosis.tokenfactory.v1beta1;

import "gogoproto/gogo.proto";
import "osmosis/tokenfactory/v1beta1/authorityMetadata.proto";
import "cosmos_proto/cosmos.proto";
import "cosmos/base/v1beta1/coin.proto";

option go_package = "github.com/osmosis-labs/osmosis/v7/x/tokenfactory/types";

// Params holds parameters for the tokenfactory module
message Params {
repeated cosmos.base.v1beta1.Coin denom_creation_fee = 1 [
(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins",
(gogoproto.moretags) = "yaml:\"denom_creation_fee\"",
(gogoproto.nullable) = false
];
}
15 changes: 15 additions & 0 deletions proto/osmosis/tokenfactory/v1beta1/query.proto
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,17 @@ 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/params.proto";

option go_package = "github.com/osmosis-labs/osmosis/v7/x/tokenfactory/types";

// Query defines the gRPC querier service.
service Query {
// Params returns the total set of minting parameters.
rpc Params(QueryParamsRequest) returns (QueryParamsResponse) {
option (google.api.http).get = "/osmosis/tokenfactory/v1beta1/params";
}

rpc DenomAuthorityMetadata(QueryDenomAuthorityMetadataRequest)
returns (QueryDenomAuthorityMetadataResponse) {
option (google.api.http).get =
Expand All @@ -23,6 +29,15 @@ service Query {
}
}

// QueryParamsRequest is the request type for the Query/Params RPC method.
message QueryParamsRequest {}

// QueryParamsResponse is the response type for the Query/Params RPC method.
message QueryParamsResponse {
// params defines the parameters of the module.
Params params = 1 [ (gogoproto.nullable) = false ];
}

message QueryDenomAuthorityMetadataRequest {
string denom = 1 [ (gogoproto.moretags) = "yaml:\"denom\"" ];
}
Expand Down
5 changes: 4 additions & 1 deletion x/lockup/types/tx.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions x/tokenfactory/genesis.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import (
func InitGenesis(ctx sdk.Context, k keeper.Keeper, genState types.GenesisState) {
k.CreateModuleAccount(ctx)

k.SetParams(ctx, genState.Params)

for _, genDenom := range genState.GetFactoryDenoms() {
creator, nonce, err := types.DeconstructDenom(genDenom.GetDenom())
if err != nil {
Expand Down Expand Up @@ -49,5 +51,6 @@ func ExportGenesis(ctx sdk.Context, k keeper.Keeper) *types.GenesisState {

return &types.GenesisState{
FactoryDenoms: genDenoms,
Params: k.GetParams(ctx),
}
}
40 changes: 19 additions & 21 deletions x/tokenfactory/keeper/admins_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,13 @@ import (
func (suite *KeeperTestSuite) TestAdminMsgs() {
suite.SetupTest()

addr1 := sdk.AccAddress([]byte("addr1---------------"))
addr2 := sdk.AccAddress([]byte("addr2---------------"))
addr0bal := int64(0)
addr1bal := int64(0)
addr2bal := int64(0)

msgServer := keeper.NewMsgServerImpl(*suite.App.TokenFactoryKeeper)

// Create a denom
res, err := msgServer.CreateDenom(sdk.WrapSDKContext(suite.Ctx), types.NewMsgCreateDenom(addr1.String(), "bitcoin"))
res, err := msgServer.CreateDenom(sdk.WrapSDKContext(suite.Ctx), types.NewMsgCreateDenom(suite.TestAccs[0].String(), "bitcoin"))
suite.Require().NoError(err)
denom := res.GetNewTokenDenom()

Expand All @@ -27,46 +25,46 @@ func (suite *KeeperTestSuite) TestAdminMsgs() {
Denom: res.GetNewTokenDenom(),
})
suite.Require().NoError(err)
suite.Require().Equal(addr1.String(), queryRes.AuthorityMetadata.Admin)
suite.Require().Equal(suite.TestAccs[0].String(), queryRes.AuthorityMetadata.Admin)

// Test minting to admins own account
_, err = msgServer.Mint(sdk.WrapSDKContext(suite.Ctx), types.NewMsgMint(addr1.String(), sdk.NewInt64Coin(denom, 10)))
addr1bal += 10
_, err = msgServer.Mint(sdk.WrapSDKContext(suite.Ctx), types.NewMsgMint(suite.TestAccs[0].String(), sdk.NewInt64Coin(denom, 10)))
addr0bal += 10
suite.Require().NoError(err)
suite.Require().True(suite.App.BankKeeper.GetBalance(suite.Ctx, addr1, denom).Amount.Int64() == addr1bal, suite.App.BankKeeper.GetBalance(suite.Ctx, addr1, denom))
suite.Require().True(suite.App.BankKeeper.GetBalance(suite.Ctx, suite.TestAccs[0], denom).Amount.Int64() == addr0bal, suite.App.BankKeeper.GetBalance(suite.Ctx, suite.TestAccs[0], denom))

// // Test force transferring
// _, err = msgServer.ForceTransfer(sdk.WrapSDKContext(suite.Ctx), types.NewMsgForceTransfer(addr1.String(), sdk.NewInt64Coin(denom, 5), addr2.String(), addr1.String()))
// _, err = msgServer.ForceTransfer(sdk.WrapSDKContext(suite.Ctx), types.NewMsgForceTransfer(suite.TestAccs[0].String(), sdk.NewInt64Coin(denom, 5), suite.TestAccs[1].String(), suite.TestAccs[0].String()))
// suite.Require().NoError(err)
// suite.Require().True(suite.App.BankKeeper.GetBalance(suite.Ctx, addr1, denom).IsEqual(sdk.NewInt64Coin(denom, 15)))
// suite.Require().True(suite.App.BankKeeper.GetBalance(suite.Ctx, addr2, denom).IsEqual(sdk.NewInt64Coin(denom, 5)))
// suite.Require().True(suite.App.BankKeeper.GetBalance(suite.Ctx, suite.TestAccs[0], denom).IsEqual(sdk.NewInt64Coin(denom, 15)))
// suite.Require().True(suite.App.BankKeeper.GetBalance(suite.Ctx, suite.TestAccs[1], denom).IsEqual(sdk.NewInt64Coin(denom, 5)))

// Test burning from own account
_, err = msgServer.Burn(sdk.WrapSDKContext(suite.Ctx), types.NewMsgBurn(addr1.String(), sdk.NewInt64Coin(denom, 5)))
addr1bal -= 5
_, err = msgServer.Burn(sdk.WrapSDKContext(suite.Ctx), types.NewMsgBurn(suite.TestAccs[0].String(), sdk.NewInt64Coin(denom, 5)))
addr0bal -= 5
suite.Require().NoError(err)
suite.Require().True(suite.App.BankKeeper.GetBalance(suite.Ctx, addr2, denom).Amount.Int64() == addr2bal)
suite.Require().True(suite.App.BankKeeper.GetBalance(suite.Ctx, suite.TestAccs[1], denom).Amount.Int64() == addr1bal)

// Test Change Admin
_, err = msgServer.ChangeAdmin(sdk.WrapSDKContext(suite.Ctx), types.NewMsgChangeAdmin(addr1.String(), denom, addr2.String()))
_, err = msgServer.ChangeAdmin(sdk.WrapSDKContext(suite.Ctx), types.NewMsgChangeAdmin(suite.TestAccs[0].String(), denom, suite.TestAccs[1].String()))
queryRes, err = suite.queryClient.DenomAuthorityMetadata(suite.Ctx.Context(), &types.QueryDenomAuthorityMetadataRequest{
Denom: res.GetNewTokenDenom(),
})
suite.Require().NoError(err)
suite.Require().Equal(addr2.String(), queryRes.AuthorityMetadata.Admin)
suite.Require().Equal(suite.TestAccs[1].String(), queryRes.AuthorityMetadata.Admin)

// Make sure old admin can no longer do actions
_, err = msgServer.Burn(sdk.WrapSDKContext(suite.Ctx), types.NewMsgBurn(addr1.String(), sdk.NewInt64Coin(denom, 5)))
_, err = msgServer.Burn(sdk.WrapSDKContext(suite.Ctx), types.NewMsgBurn(suite.TestAccs[0].String(), sdk.NewInt64Coin(denom, 5)))
suite.Require().Error(err)

// Make sure the new admin works
_, err = msgServer.Mint(sdk.WrapSDKContext(suite.Ctx), types.NewMsgMint(addr2.String(), sdk.NewInt64Coin(denom, 5)))
addr2bal += 5
_, err = msgServer.Mint(sdk.WrapSDKContext(suite.Ctx), types.NewMsgMint(suite.TestAccs[1].String(), sdk.NewInt64Coin(denom, 5)))
addr1bal += 5
suite.Require().NoError(err)
suite.Require().True(suite.App.BankKeeper.GetBalance(suite.Ctx, addr2, denom).Amount.Int64() == addr2bal)
suite.Require().True(suite.App.BankKeeper.GetBalance(suite.Ctx, suite.TestAccs[1], denom).Amount.Int64() == addr1bal)

// Try setting admin to empty
_, err = msgServer.ChangeAdmin(sdk.WrapSDKContext(suite.Ctx), types.NewMsgChangeAdmin(addr2.String(), denom, ""))
_, err = msgServer.ChangeAdmin(sdk.WrapSDKContext(suite.Ctx), types.NewMsgChangeAdmin(suite.TestAccs[1].String(), denom, ""))
suite.Require().NoError(err)
queryRes, err = suite.queryClient.DenomAuthorityMetadata(suite.Ctx.Context(), &types.QueryDenomAuthorityMetadataRequest{
Denom: res.GetNewTokenDenom(),
Expand Down
10 changes: 10 additions & 0 deletions x/tokenfactory/keeper/createdenom.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,16 @@ import (

// ConvertToBaseToken converts a fee amount in a whitelisted fee token to the base fee token amount
func (k Keeper) CreateDenom(ctx sdk.Context, creatorAddr string, denomNonce string) (newTokenDenom string, err error) {
// Send creation fee to community pool
creationFee := k.GetParams(ctx).DenomCreationFee
accAddr, err := sdk.AccAddressFromBech32(creatorAddr)
if err != nil {
return "", err
}
if err := k.distrKeeper.FundCommunityPool(ctx, creationFee, accAddr); err != nil {
return "", err
}

denom, err := types.GetTokenDenom(creatorAddr, denomNonce)
if err != nil {
return "", err
Expand Down
Loading