Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
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
19 changes: 18 additions & 1 deletion app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,9 @@ import (
ibckeeper "github.com/cosmos/ibc-go/v10/modules/core/keeper"

"github.com/peersyst/cbdc-node/docs"
"github.com/peersyst/cbdc-node/x/cbdc"
cbdckeeper "github.com/peersyst/cbdc-node/x/cbdc/keeper"
cbdctypes "github.com/peersyst/cbdc-node/x/cbdc/types"
poakeeper "github.com/peersyst/cbdc-node/x/poa/keeper"
poatypes "github.com/peersyst/cbdc-node/x/poa/types"

Expand Down Expand Up @@ -172,6 +175,7 @@ var (
ratelimittypes.ModuleName: nil,
feemarkettypes.ModuleName: nil,
poatypes.ModuleName: {authtypes.Minter, authtypes.Burner},
cbdctypes.ModuleName: {authtypes.Minter, authtypes.Burner},
}
)

Expand Down Expand Up @@ -247,7 +251,8 @@ type App struct {
Erc20Keeper erc20keeper.Keeper

// cbdc keepers
PoaKeeper poakeeper.Keeper
PoaKeeper poakeeper.Keeper
CbdcKeeper cbdckeeper.Keeper

// mm is the module manager
mm *module.Manager
Expand Down Expand Up @@ -471,6 +476,14 @@ func New(
authtypes.NewModuleAddress(govtypes.ModuleName).String(),
)

app.CbdcKeeper = *cbdckeeper.NewKeeper(
appCodec,
app.GetSubspace(cbdctypes.ModuleName),
Comment thread
aluque-peersyst marked this conversation as resolved.
app.BankKeeper,
authtypes.NewModuleAddress(govtypes.ModuleName).String(),
BaseDenom,
Comment thread
JordiParraCrespo marked this conversation as resolved.
)
Comment thread
JordiParraCrespo marked this conversation as resolved.

// Ethermint keepers

// Feemarket Keeper
Expand Down Expand Up @@ -683,6 +696,7 @@ func New(

// cbdc app modules
poa.NewAppModule(appCodec, app.PoaKeeper, app.BankKeeper, app.StakingKeeper, app.AccountKeeper, app.interfaceRegistry),
cbdc.NewAppModule(appCodec, app.CbdcKeeper, app.AccountKeeper, app.interfaceRegistry),
)

// BasicModuleManager defines the module BasicManager which is in charge of setting up basic,
Expand Down Expand Up @@ -769,6 +783,7 @@ func New(
// Evmos
erc20types.ModuleName,
poatypes.ModuleName,
cbdctypes.ModuleName,
crisistypes.ModuleName,
ratelimittypes.ModuleName,
}
Expand Down Expand Up @@ -1156,6 +1171,8 @@ func initParamsKeeper(appCodec codec.BinaryCodec, legacyAmino *codec.LegacyAmino
paramsKeeper.Subspace(feemarkettypes.ModuleName)
paramsKeeper.Subspace(erc20types.ModuleName)

paramsKeeper.Subspace(cbdctypes.ModuleName)

return paramsKeeper
}

Expand Down
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,8 @@ require (
github.com/btcsuite/btcd/btcutil v1.1.6 // indirect
github.com/btcsuite/btcd/chaincfg/chainhash v1.1.0 // indirect
github.com/bytedance/gopkg v0.1.3 // indirect
github.com/bytedance/sonic v1.14.2 // indirect
github.com/bytedance/sonic/loader v0.4.0 // indirect
github.com/bytedance/sonic v1.15.0 // indirect
github.com/bytedance/sonic/loader v0.5.0 // indirect
github.com/cenkalti/backoff/v4 v4.3.0 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/chzyer/readline v1.5.1 // indirect
Expand Down
4 changes: 4 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -763,8 +763,12 @@ github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1
github.com/bytedance/sonic v1.9.1/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U=
github.com/bytedance/sonic v1.14.2 h1:k1twIoe97C1DtYUo+fZQy865IuHia4PR5RPiuGPPIIE=
github.com/bytedance/sonic v1.14.2/go.mod h1:T80iDELeHiHKSc0C9tubFygiuXoGzrkjKzX2quAx980=
github.com/bytedance/sonic v1.15.0 h1:/PXeWFaR5ElNcVE84U0dOHjiMHQOwNIx3K4ymzh/uSE=
github.com/bytedance/sonic v1.15.0/go.mod h1:tFkWrPz0/CUCLEF4ri4UkHekCIcdnkqXw9VduqpJh0k=
github.com/bytedance/sonic/loader v0.4.0 h1:olZ7lEqcxtZygCK9EKYKADnpQoYkRQxaeY2NYzevs+o=
github.com/bytedance/sonic/loader v0.4.0/go.mod h1:AR4NYCk5DdzZizZ5djGqQ92eEhCCcdf5x77udYiSJRo=
github.com/bytedance/sonic/loader v0.5.0 h1:gXH3KVnatgY7loH5/TkeVyXPfESoqSBSBEiDd5VjlgE=
github.com/bytedance/sonic/loader v0.5.0/go.mod h1:AR4NYCk5DdzZizZ5djGqQ92eEhCCcdf5x77udYiSJRo=
github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ=
github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4=
github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
Expand Down
7 changes: 6 additions & 1 deletion local-node.sh
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ jq '.app_state["staking"]["params"]["bond_denom"]="apoa"' "$GENESIS" >"$TMP_GENE
jq '.app_state["staking"]["params"]["unbonding_time"]="60s"' "$GENESIS" >"$TMP_GENESIS" && mv "$TMP_GENESIS" "$GENESIS"
jq '.app_state["feemarket"]["params"]["base_fee"]="'${BASEFEE}'"' "$GENESIS" >"$TMP_GENESIS" && mv "$TMP_GENESIS" "$GENESIS"
jq '.app_state["feemarket"]["params"]["no_base_fee"]=true' "$GENESIS" >"$TMP_GENESIS" && mv "$TMP_GENESIS" "$GENESIS"
jq '.app_state["feemarket"]["params"]["min_gas_price"]="0.000000000000000000"' "$GENESIS" >"$TMP_GENESIS" && mv "$TMP_GENESIS" "$GENESIS"
Comment thread
aluque-peersyst marked this conversation as resolved.

jq '.app_state.bank.denom_metadata=[{"description":"XRP is the gas token","denom_units":[{"denom":"axrp"},{"denom":"xrp","exponent":18}],"base":"axrp","display":"xrp","name":"XRP","symbol":"XRP"}]' "$GENESIS" >"$TMP_GENESIS" && mv "$TMP_GENESIS" "$GENESIS"

Expand All @@ -59,11 +60,15 @@ jq '.app_state.erc20.token_pairs=[{contract_owner:1,erc20_address:"0xeeeeeeeeeee
jq '.app_state["slashing"]["params"]["slash_fraction_double_sign"]="0"' "$GENESIS" >"$TMP_GENESIS" && mv "$TMP_GENESIS" "$GENESIS"
jq '.app_state["slashing"]["params"]["slash_fraction_downtime"]="0"' "$GENESIS" >"$TMP_GENESIS" && mv "$TMP_GENESIS" "$GENESIS"

# the cbdc mint/burn owner is required (empty owner fails InitChain); use the dev key
CBDC_OWNER=$(bin/cbdcd --home "$HOMEDIR" keys show "$KEY_NAME" -a --keyring-backend "$KEYRING")
jq '.app_state["cbdc"]["params"]["owner"]="'${CBDC_OWNER}'"' "$GENESIS" >"$TMP_GENESIS" && mv "$TMP_GENESIS" "$GENESIS"

bin/cbdcd --home "$HOMEDIR" genesis add-genesis-account "$(bin/cbdcd --home "$HOMEDIR" keys show "$KEY_NAME" -a --keyring-backend "$KEYRING")" 1000000apoa,1000000000000000000000000000axrp --keyring-backend "$KEYRING"

bin/cbdcd --home "$HOMEDIR" genesis add-genesis-account "ethm1zrxl239wa6ad5xge3gs68rt98227xgnjq0xyw2" 1000000000000000000000000000axrp --keyring-backend "$KEYRING"

bin/cbdcd --home "$HOMEDIR" genesis gentx alice 1000000apoa --gas-prices ${BASEFEE}axrp --keyring-backend "$KEYRING" --chain-id "$CHAINID"
bin/cbdcd --home "$HOMEDIR" genesis gentx alice 1000000apoa --fees ${BASEFEE}axrp --gas 1000000 --keyring-backend "$KEYRING" --chain-id "$CHAINID"

bin/cbdcd --home "$HOMEDIR" genesis collect-gentxs

Expand Down
10 changes: 10 additions & 0 deletions proto/cbdc/genesis.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
syntax = "proto3";
package cbdc;

import "gogoproto/gogo.proto";
import "cbdc/params.proto";

option go_package = "github.com/peersyst/cbdc-node/x/cbdc/types";

// GenesisState defines the cbdc module's genesis state.
message GenesisState { Params params = 1 [ (gogoproto.nullable) = false ]; }
19 changes: 19 additions & 0 deletions proto/cbdc/params.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
syntax = "proto3";
package cbdc;

import "cosmos_proto/cosmos.proto";

option go_package = "github.com/peersyst/cbdc-node/x/cbdc/types";

// Params defines the parameters for the module.
message Params {
// owner is the address allowed to mint/burn CBDC tokens. It can be rotated
// on-chain via a governance MsgUpdateParams proposal.
string owner = 1 [ (cosmos_proto.scalar) = "cosmos.AddressString" ];
// issuance_paused, when true, stops both minting and burning. It is a
// gov-controlled emergency switch independent of the owner: only the gov
// authority can toggle it (via MsgUpdateParams), so mint/burn can be halted
// even if the owner key is compromised. It does not affect params updates or
// queries.
bool issuance_paused = 2;
}
25 changes: 25 additions & 0 deletions proto/cbdc/query.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
syntax = "proto3";
package cbdc;

import "gogoproto/gogo.proto";
import "google/api/annotations.proto";
import "cbdc/params.proto";

option go_package = "github.com/peersyst/cbdc-node/x/cbdc/types";

// Query defines the gRPC querier service.
service Query {
Comment thread
JordiParraCrespo marked this conversation as resolved.
// Parameters queries the parameters of the module.
rpc Params(QueryParamsRequest) returns (QueryParamsResponse) {
option (google.api.http).get = "/cbdc/cbdc/params";
}
}

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

// QueryParamsResponse is response type for the Query/Params RPC method.
message QueryParamsResponse {
// params holds all the parameters of this module.
Params params = 1 [ (gogoproto.nullable) = false ];
}
61 changes: 61 additions & 0 deletions proto/cbdc/tx.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
syntax = "proto3";
package cbdc;

import "gogoproto/gogo.proto";
import "cosmos_proto/cosmos.proto";
import "cosmos/msg/v1/msg.proto";
import "cosmos/base/v1beta1/coin.proto";
import "amino/amino.proto";
Comment thread
JordiParraCrespo marked this conversation as resolved.
import "cbdc/params.proto";

option go_package = "github.com/peersyst/cbdc-node/x/cbdc/types";

// Msg defines the Msg service.
service Msg {
Comment thread
aluque-peersyst marked this conversation as resolved.
option (cosmos.msg.v1.service) = true;

// Mints CBDC tokens and sends them to an address
rpc Mint(MsgMint) returns (MsgMintResponse);
// Burns CBDC tokens from an address
rpc Burn(MsgBurn) returns (MsgBurnResponse);
// Updates the module params. Only the governance authority can call it.
rpc UpdateParams(MsgUpdateParams) returns (MsgUpdateParamsResponse);
}

// MsgMint defines a message to mint CBDC tokens and send them to an address
message MsgMint {
Comment thread
aluque-peersyst marked this conversation as resolved.
option (cosmos.msg.v1.signer) = "owner";

string owner = 1 [ (cosmos_proto.scalar) = "cosmos.AddressString" ];
string address = 2 [ (cosmos_proto.scalar) = "cosmos.AddressString" ];
cosmos.base.v1beta1.Coin amount = 3
[ (gogoproto.nullable) = false, (amino.dont_omitempty) = true ];
}
// MsgMintResponse defines the response for minting CBDC tokens
message MsgMintResponse {}

// MsgBurn defines a message to burn CBDC tokens from an address
message MsgBurn {
option (cosmos.msg.v1.signer) = "owner";

string owner = 1 [ (cosmos_proto.scalar) = "cosmos.AddressString" ];
string address = 2 [ (cosmos_proto.scalar) = "cosmos.AddressString" ];
cosmos.base.v1beta1.Coin amount = 3
[ (gogoproto.nullable) = false, (amino.dont_omitempty) = true ];
}
// MsgBurnResponse defines the response for burning CBDC tokens
message MsgBurnResponse {}

// MsgUpdateParams defines a message to update the module params
message MsgUpdateParams {
option (cosmos.msg.v1.signer) = "authority";

// authority is the address that controls the module params (defaults to the
// gov module account)
string authority = 1 [ (cosmos_proto.scalar) = "cosmos.AddressString" ];
// params defines the module parameters to update
Params params = 2
[ (gogoproto.nullable) = false, (amino.dont_omitempty) = true ];
}
// MsgUpdateParamsResponse defines the response for updating the module params
message MsgUpdateParamsResponse {}
3 changes: 2 additions & 1 deletion scripts/mockgen.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ mockgen -source=x/poa/types/expected_keepers.go -package testutil -destination=x
mockgen -source=x/poa/testutil/tx.go -package testutil -destination=x/poa/testutil/tx_mock.go
mockgen -source=x/poa/testutil/keys.go -package testutil -destination=x/poa/testutil/keys_mock.go
mockgen -source=x/poa/testutil/expected_msg_server.go -package testutil -destination=x/poa/testutil/expected_msg_server_mock.go
mockgen -source=x/poa/testutil/staking_hooks.go -package testutil -destination=x/poa/testutil/staking_hooks_mock.go
mockgen -source=x/poa/testutil/staking_hooks.go -package testutil -destination=x/poa/testutil/staking_hooks_mock.go
mockgen -source=x/cbdc/types/expected_keepers.go -package testutil -destination=x/cbdc/testutil/expected_keepers_mock.go
11 changes: 11 additions & 0 deletions testutil/integration/cbdc/integration/setup.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import (

evmtypes "github.com/cosmos/evm/x/vm/types"
cbdccommon "github.com/peersyst/cbdc-node/testutil/integration/cbdc/common"
cbdctypes "github.com/peersyst/cbdc-node/x/cbdc/types"

"github.com/peersyst/cbdc-node/app"
)
Expand Down Expand Up @@ -427,6 +428,15 @@ func setDefaultErc20GenesisState(app *app.App, genesisState testutil.GenesisStat
return genesisState
}

// setDefaultCbdcGenesisState sets a valid mint/burn owner, since the module's
// default params leave it empty (which fails InitChain by design).
func setDefaultCbdcGenesisState(app *app.App, genesisState testutil.GenesisState) testutil.GenesisState {
cbdcGen := cbdctypes.DefaultGenesis()
cbdcGen.Params = cbdctypes.NewParams(authtypes.NewModuleAddress(govtypes.ModuleName).String(), false)
genesisState[cbdctypes.ModuleName] = app.AppCodec().MustMarshalJSON(cbdcGen)
return genesisState
}

// defaultAuthGenesisState sets the default genesis state
// for the testing setup
func newDefaultGenesisState(app *app.App, params defaultGenesisParams) testutil.GenesisState {
Expand All @@ -438,6 +448,7 @@ func newDefaultGenesisState(app *app.App, params defaultGenesisParams) testutil.
genesisState = setDefaultGovGenesisState(app, genesisState, params.gov)
genesisState = setDefaultSlashingGenesisState(app, genesisState, params.slashing)
genesisState = setDefaultErc20GenesisState(app, genesisState)
genesisState = setDefaultCbdcGenesisState(app, genesisState)

return genesisState
}
Expand Down
56 changes: 56 additions & 0 deletions x/cbdc/keeper/burn.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package keeper

import (
sdk "github.com/cosmos/cosmos-sdk/types"

"github.com/peersyst/cbdc-node/x/cbdc/types"
)

// burningAllowed performs all pre-flight gating for a burn, including the owner
// authorization check so the keeper cannot be burned from by any caller that
// bypasses the msg server. The address param is kept for symmetry with
// mintingAllowed and for future address-based gating.
func (k Keeper) burningAllowed(ctx sdk.Context, owner string, _ sdk.AccAddress, amount sdk.Coin) error {
params := k.GetParams(ctx)
if owner != params.Owner {
return types.ErrUnauthorized
}
if params.IssuancePaused {
return types.ErrIssuancePaused
}
if err := amount.Validate(); err != nil {
return err
}
if amount.Denom != k.cbdcDenom {
return types.ErrInvalidDenom
}
if !amount.IsPositive() {
return types.ErrInvalidAmount
}
return nil
}

func (k Keeper) BurnCoins(ctx sdk.Context, owner string, address sdk.AccAddress, amount sdk.Coin) error {
if err := k.burningAllowed(ctx, owner, address, amount); err != nil {
return err
}

coins := sdk.NewCoins(amount)
if err := k.bk.SendCoinsFromAccountToModule(ctx, address, types.ModuleName, coins); err != nil {
return err
}
if err := k.bk.BurnCoins(ctx, types.ModuleName, coins); err != nil {
return err
}

ctx.EventManager().EmitEvent(
sdk.NewEvent(
types.EventTypeBurn,
sdk.NewAttribute(types.AttributeOwner, owner),
sdk.NewAttribute(types.AttributeAddress, address.String()),
sdk.NewAttribute(types.AttributeAmount, amount.String()),
),
)

return nil
}
Loading
Loading