Welcome to the new Provenance Blockchain developer documentation portal!
logo
The Sanction Module allows management of a list of sanctioned accounts that are prevented from sending or spending any funds. It injects a restriction into the x/bank module to enforce these sanctions.

Quickstart

The Provenance Blockchain sanction module provides comprehensive client interfaces through gRPC, CLI, and REST endpoints for managing and querying sanction functionality. Users can interact with the module using gRPC for direct protocol communication, command-line interface tools for transaction management through governance proposals and sanction status queries with convenient aliases and pagination support, and REST endpoints for HTTP-based access to all sanction query operations including individual account sanction checks, sanctioned address listings, temporary entry queries, and parameter retrieval with standard pagination capabilities.

gRPC

A user can interact with and query the x/sanction module using gRPC.
For details see Queries.

CLI

The gRPC transaction and query endpoints are made available through CLI helpers.

Transactions

The transaction endpoints are only for use with governance proposals. As such, the CLI's tx gov commands can be used to interact with them.

Queries

Each of these commands facilitates running a gRPC query. Standard query flags are available unless otherwise noted.

IsSanctioned

shell
$ simd query sanction is-sanctioned --help Check if an address is sanctioned. Examples: $ simd query sanction is-sanctioned cosmos1v4uxzmtsd3j4zat9wfu5zerywgc47h6luruvdf $ simd query sanction is cosmos1v4uxzmtsd3j4zat9wfu5zerywgc47h6luruvdf $ simd query sanction check cosmos1v4uxzmtsd3j4zat9wfu5zerywgc47h6luruvdf Usage: simd query sanction is-sanctioned <address> [flags] Aliases: is-sanctioned, is, check, is-sanction

SanctionedAddresses

shell
$ simd query sanction sanctioned-addresses --help List all the sanctioned addresses. Examples: $ simd query sanction sanctioned-addresses $ simd query sanction addresses $ simd query sanction all Usage: simd query sanction sanctioned-addresses [flags] Aliases: sanctioned-addresses, addresses, all
Standard pagination flags are also available for this command.

TemporaryEntries

shell
simd query sanction temporary-entries --help List all temporarily sanctioned/unsanctioned addresses. If an address is provided, only temporary entries for that address are returned. Otherwise, all temporary entries are returned. Examples: $ simd query sanction temporary-entries $ simd query sanction temporary-entries cosmos1v4uxzmtsd3j4zat9wfu5zerywgc47h6luruvdf $ simd query sanction temp-entries $ simd query sanction temp-entries cosmos1v4uxzmtsd3j4zat9wfu5zerywgc47h6luruvdf $ simd query sanction temp $ simd query sanction temp cosmos1v4uxzmtsd3j4zat9wfu5zerywgc47h6luruvdf Usage: simd query sanction temporary-entries [<address>] [flags] Aliases: temporary-entries, temp-entries, temp
Standard pagination flags are also available for this command.

Params

shell
$ simd query sanction params --help Get the sanction module params. Example: $ simd query sanction params Usage: simd query sanction params [flags]

REST

Each of the sanction gRPC query endpoints is also available through one or more REST endpoints.
Name
URL
IsSanctioned
/cosmos/sanction/v1beta1/check/{address}
SanctionedAddresses
/cosmos/sanction/v1beta1/all
TemporaryEntries - all
/cosmos/sanction/v1beta1/temp
TemporaryEntries - specific
/cosmos/sanction/v1beta1/temp?address={address}
Params
/cosmos/sanction/v1beta1/params
For SanctionedAddresses and TemporaryEntries, pagination parameters can be provided using the standard pagination query parameters.

Concepts

The Provenance Blockchain sanction module provides governance-controlled mechanisms for freezing accounts by preventing fund removal while allowing incoming transfers, implementing both permanent sanctions through governance proposals and immediate temporary sanctions triggered by deposit thresholds that take effect before voting concludes. The system supports complex interactions between multiple proposals with different sanction and unsanction messages, includes protections for unsanctionable addresses like fee collectors, and uses configurable parameters to control immediate sanction thresholds, with temporary sanctions being resolved when governance proposals conclude and permanent sanctions remaining until explicitly removed through unsanction proposals.

Sanctioned Account

An account becomes sanctioned when a governance proposal is passed with a MsgSanction in it containing the account's address.
When an account is sanctioned, funds cannot be removed from it. The funds cannot be sent to another account. They cannot be spent either (e.g. on Tx fees).
Funds can be sent to a sanctioned account, but would then be immediately frozen in that account.
Sanctioning is enforced as a restriction injected into the x/bank send keeper and prevents removal of funds from an account. A sanctioned account is otherwise unchanged.
When an attempt is made to remove funds from a sanctioned account, an error is returned indicating that the account is sanctioned.

Immediate Temporary Sanctions

Immediate Temporary Sanctions (sometimes called just "immediate sanctions" or "temporary sanctions") are possible. They happen when a MsgSanction governance proposal has a large enough deposit. They also happen if a deposit is added after proposal submittal that puts the proposal's total deposit over the threshold.
This deposit threshold is managed as a module parameter: ImmediateSanctionMinDeposit.
  • If zero or empty, immediate sanctions are not possible
  • If set to the governance proposal minimum deposit or less (not recommended), all MsgSanction governance proposals put to a vote will create immediate temporary sanctions
  • If set to more than the governance proposal minimum deposit (this is recommended), it's possible to submit a MsgSanction proposal without the sanctions being immediate
Immediate temporary sanctions are associated with both the governance proposal and address in question. They expire once the governance proposal is resolved (e.g. the voting period ends). If the proposal passes, permanent sanctions are enacted and any temporary entries for each address are removed. If the proposal does not pass, any temporary entries associated with that proposal are removed.
Note: The phrase "permanent sanction" is used in here as a counterpart to "temporary sanction". It is "permanent" only in the sense that it isn't temporary. It is not "permanent" in the sense that it is possible to be undone (e.g. with a MsgUnsanction).

Unsanctioning

A MsgUnsanction can be used in a governance proposal to unsanction accounts. Once an account is unsanctioned, it can again send or spend its funds.

Immediate Temporary Unsanctions

Similar to immediate temporary sanctions, these are created when a MsgUnsanction proposal has a large enough deposit (either initially or later).
This deposit threshold is managed as a module parameter: ImmediateUnsanctionMinDeposit.
  • If zero or empty, immediate unsanctions are not possible
  • If set to the governance proposal minimum deposit or less (not recommended), all MsgUnsanction governance proposals put to a vote will create immediate temporary unsanctions
  • If set to more than the governance proposal minimum deposit (this is recommended), it's possible to submit a MsgUnsanction proposal without the unsanctions being immediate
Immediate temporary unsanctions are associated with both the governance proposal and address in question. They expire once the governance proposal is resolved (e.g. the voting period ends). If the proposal passes, permanent sanctions are removed and any temporary entries for each address are removed. If the proposal does not pass, any temporary entries associated with that proposal are removed.

Unsanctionable Addresses

When creating the sanction keeper, a list of addresses of unsanctionable accounts can be provided.
An attempt to sanction or enact an immediate temporary sanction on an address in that list results in the error: "address cannot be sanctioned".
An example of an account that should not be sanctionable is the fee collector.

Params

The x/sanction module has some params that can be defined in state.
  • ImmediateSanctionMinDeposit is the minimum deposit required for immediate temporary sanctions to be enacted for addresses in a MsgSanction
  • ImmediateUnsanctionMinDeposit is the minimum deposit required for immediate temporary unsanctions to be enacted for addresses in a MsgUnsanction
If not defined in state, the following variables are used (defined in x/sanction/sanction.go):
  • DefaultImmediateSanctionMinDeposit
  • DefaultImmediateUnsanctionMinDeposit
By default, those have a value of nil which makes it impossible to enact immediate temporary sanctions or unsanctions. They are public, though, so consuming chains can change them as desired.
The default variables are only used if the state entry does not exist. If the entry exists, but is empty, that empty value is used.
It is recommended that both of these minimum deposits be significantly larger than the governance proposal minimum deposit. This is to prevent malicious use of immediate temporary sanctions or unsanctions.

Complex Interactions

It's possible to end up with some complex interactions due to multiple MsgSanction and MsgUnsanction messages with large enough deposits for temporary effects. In a general sense, the last one takes precedence.

Conflicting Messages in a Proposal

When a proposal has multiple messages, they are processed in the order they are listed in the proposal. So if a governance proposal contains both a MsgSanction and MsgUnsanction, and one or more addresses are listed in both, then, the last message they're in takes precedence.
For example, say a proposal has, a MsgSanction for accounts A, B, and C, then a MsgUnsanction for accounts B, C, and D. And the proposal has enough of a deposit for both immediate sanctions and unsanctions. There will be 4 temporary entries: account A will have a temporary sanction; and B, C, and D will have temporary unsanctions. If the proposal passes, a permanent sanction will be placed on A, and accounts B, C, and D will have their sanctions removed.
If a proposal contains both a MsgSanction and MsgUnsanction and the total deposit is enough for immediate temporary entries of one type, but not the other, the temporary entries are enacted for the one, but not the other. If later, more deposit is added so there's enough for both, the others will then be enacted too.

Conflicting Governance Proposals

If multiple governance proposals have immediate temporary effects, the effect from the proposal with the largest id takes precedence. Voting period start and end times/heights are not taken into account, only the proposal id.
For example, let's say proposal 3 has a MsgSanction for accounts A, B, and C; and proposal 5 has a MsgUnsanction for accounts B, C, and D. Both have large enough deposits for immediate effects. There will be six temporary entries, A+3, B+3, C+3, B+5, C+5, and D+5. But the temporary entries for accounts B and C from prop 3 are ignored because of their prop 5 entries. In effect, account A will have a temporary sanction; and accounts, B, C, and D will have temporary unsanctions.
Scenarios:
  • Prop 3 passes while prop 5 is still being voted on: All temporary entries for accounts A, B, and C are removed, and those accounts are permanently sanctioned. The only temporary entry left will be an unsanction for account D.
  • Prop 3 does not pass while prop 5 is still being voted on: The temporary sanction entries for accounts A, B, and C are removed leaving temporary unsanction entries for B, C, and D. No permanent sanctions are enacted.
  • Prop 5 passes while prop 3 is still being voted on: All temporary entries for accounts B, C, and D are removed and permanent sanctions are also removed for those accounts. The only temporary entry left will be a sanction on account A.
  • Prop 5 does not pass while prop 3 is still being voted on: The temporary unsanction entries for accounts B, C, and D are removed leaving temporary sanction entries for A, B, and C. If accounts B, C, or D were previously permanently sanctioned, those sanctions remain.

State

The Provenance Blockchain sanction module uses a structured key/value storage system to manage sanction-related data, including module parameters for controlling immediate sanction thresholds stored as SDK coins, sanctioned account records that track permanent sanctions with simple binary flags, temporary entries that associate governance proposal IDs with specific sanction or un-sanction actions on addresses, and corresponding temporary index records that enable efficient cleanup and lookup operations when proposals are resolved or accounts are permanently sanctioned or unsanctioned.

Params

Each param field is stored in its own record with this format:
plain text
0x00 | []byte(<param name>) -> []byte(<param value>)
Param Field
<param name>
<param value> format
ImmediateSanctionMinDeposit
immediate_sanction_min_deposit
sdk.Coins.String()
ImmediateUnsanctionMinDeposit
immediate_unsanction_min_deposit
sdk.Coins.String()

Sanctioned Accounts

When an account is sanctioned, the following record is made:
plain text
0x01 | len([]byte(<account address>)) | []byte(<account address>) -> 0x01
When an account is unsanctioned, that record is deleted.

Temporary Entries

Immediate temporary sanctions and/or unsanctions are enacted by creating the following record:
plain text
0x02 | len([]byte(<account address>)) | []byte(<account address>) | [8]byte(<gov prop id>) -> byte(<value>)
Entry type
<value>
Sanction
0x01
Unsanction
0x00
When an account is sanctioned or unsanctioned, all temporary entry records for the address are removed. If a proposal does not pass, all temporary entry records for that proposal are removed.

Temporary Index

When a temporary entry is created, the following index record is also created:
plain text
0x03 | [8]byte(<gov prop id>) | len([]byte(<account address>)) | []byte(<account address>) -> byte(<value>)
The same <value> is used as the correlated temporary entry.
Temporary index records are removed when their correlated temporary entry record is removed.

Messages

The Provenance Blockchain sanction module provides governance-controlled message services for managing account sanctions through three primary message types: MsgSanction for requesting account sanctions with deposit-triggered immediate temporary sanctions and permanent sanctions upon proposal passage, MsgUnsanction for requesting account unsanctions with similar immediate temporary effects and permanent sanction removal, and MsgUpdateParams for updating module parameters through governance proposals. All messages require proper authority validation and include comprehensive error handling for invalid addresses, unsanctionable accounts, and parameter validation, with temporary sanctions expiring at governance proposal completion regardless of voting outcome.

MsgSanction

A user can request that accounts be sanctioned by submitting a governance proposal containing a MsgSanction. It contains the list of addresses of accounts to be sanctioned and the authority able to do it.
protobuf
// Source: https://github.com/provenance-io/provenance/blob/v1.19.0/proto/cosmos/sanction/v1beta1/tx.proto#L22-L32 message MsgSanction { option (cosmos.msg.v1.signer) = "authority"; // The list of addresses to sanction. repeated string addresses = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"]; // The authority able to sanction accounts. string authority = 2 [(cosmos_proto.scalar) = "cosmos.AddressString"]; }
If the proposal ever has enough total deposit (defined in params), immediate temporary sanctions are issued for each address. Temporary sanctions expire at the completion of the governance proposal regardless of outcome.
If the proposal passes, permanent sanctions are enacted for each address and temporary entries for each address are removed. Otherwise, any temporary entries associated with the governance proposal are removed.

Expected Failures

It is expected to fail if:
  • The authority provided does not equal the authority defined for the x/sanction module's keeper. This is most often the address of the x/gov module's account
  • Any addresses are not valid bech32 encoded address strings
  • Any addresses are unsanctionable

MsgUnsanction

A user can request that accounts be unsanctioned by submitting a governance proposal containing a MsgUnsanction. It contains the list of addresses of accounts to be unsanctioned and the authority able to do it.
protobuf
// Source: https://github.com/provenance-io/provenance/blob/v1.19.0/proto/cosmos/sanction/v1beta1/tx.proto#L37-L47 message MsgUnsanction { option (cosmos.msg.v1.signer) = "authority"; // The list of addresses to unsanction. repeated string addresses = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"]; // The authority able to unsanction accounts. string authority = 2 [(cosmos_proto.scalar) = "cosmos.AddressString"]; }
If the proposal ever has enough total deposit (defined in params), immediate temporary unsanctions are issued for each address. Temporary unsanctions expire at the completion of the governance proposal regardless of outcome.
If the proposal passes, permanent sanctions are removed for each address and temporary entries for each address are also removed. Otherwise, any temporary entries associated with the governance proposal are removed.

Expected Failures

It is expected to fail if:
  • The authority provided does not equal the authority defined for the x/sanction module's keeper. This is most often the address of the x/gov module's account
  • Any addresses are not valid bech32 encoded address strings

MsgUpdateParams

The sanction module params can be updated by submitting a governance proposal containing a MsgUpdateParams. It contains the desired new params and the authority able to update them.
protobuf
// Source: https://github.com/provenance-io/provenance/blob/v1.19.0/proto/cosmos/sanction/v1beta1/tx.proto#L52-L62 message MsgUpdateParams { option (cosmos.msg.v1.signer) = "authority"; // The new parameters for the sanction module. Params params = 1; // The authority able to update params. string authority = 2 [(cosmos_proto.scalar) = "cosmos.AddressString"]; }
If params is null, they will be deleted from state, reverting them to their code-defined defaults.
If a field in params is null or empty, the record in state will reflect that.

Expected Failures

It is expected to fail if:
  • The authority provided does not equal the authority defined for the x/sanction module's keeper. This is most often the address of the x/gov module's account
  • Any params are invalid

Events

The Provenance Blockchain sanction module emits five distinct events to track the complete lifecycle of sanction operations: EventAddressSanctioned and EventAddressUnsanctioned for permanent sanction and unsanction actions, EventTempAddressSanctioned and EventTempAddressUnsanctioned for immediate temporary sanction operations triggered by governance proposal deposits, and EventParamsUpdated for module parameter changes. These events provide comprehensive visibility into both permanent and temporary sanction state changes, enabling applications to track account restrictions and monitor governance-driven sanction management activities throughout the proposal and execution process.

EventAddressSanctioned

This event is emitted when an account is sanctioned.
@Type: /cosmos.sanction.v1beta1.EventAddressSanctioned
Attribute Key
Attribute Value
address
{bech32 string of sanctioned account}

EventAddressUnsanctioned

This event is emitted when an account is unsanctioned.
@Type: /cosmos.sanction.v1beta1.EventAddressUnsanctioned
Attribute Key
Attribute Value
address
{bech32 string of unsanctioned account}

EventTempAddressSanctioned

This event is emitted when a temporary sanction is placed on an account.
@Type: /cosmos.sanction.v1beta1.EventTempAddressSanctioned
Attribute Key
Attribute Value
address
{bech32 string of sanctioned account}

EventTempAddressUnsanctioned

This event is emitted when a temporary unsanction is placed on an account.
@Type: /cosmos.sanction.v1beta1.EventTempAddressUnsanctioned
Attribute Key
Attribute Value
address
{bech32 string of unsanctioned account}

EventParamsUpdated

This event is emitted when the x/sanction module's params are updated.
@Type: /cosmos.sanction.v1beta1.EventParamsUpdated
Attribute Key
Attribute Value
(none)

Queries

The Provenance Blockchain sanction module provides a comprehensive query service for inspecting sanction status and managing sanction-related data across the network. The query service includes endpoints for checking individual account sanction status, retrieving lists of all sanctioned addresses with pagination support, querying temporary sanction and unsanction entries associated with governance proposals, and accessing module parameters that control immediate sanction thresholds, enabling applications to monitor and manage account restrictions throughout the governance-driven sanction lifecycle.

IsSanctioned

Checks if an account has been sanctioned.
HTTP Endpoint: GET /cosmos/sanction/v1beta1/check/{address}
Request: QueryIsSanctionedRequestResponse: QueryIsSanctionedResponse

QueryIsSanctionedRequest

protobuf
// Source: https://github.com/provenance-io/provenance // QueryIsSanctionedRequest defines the RPC request for checking if an account is sanctioned. message QueryIsSanctionedRequest { string address = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"]; }

QueryIsSanctionedResponse

protobuf
// Source: https://github.com/provenance-io/provenance // QueryIsSanctionedResponse defines the RPC response of an IsSanctioned query. message QueryIsSanctionedResponse { // is_sanctioned is true if the address is sanctioned. bool is_sanctioned = 1; }

SanctionedAddresses

Returns a list of sanctioned addresses.
HTTP Endpoint: GET /cosmos/sanction/v1beta1/all
Request: QuerySanctionedAddressesRequestResponse: QuerySanctionedAddressesResponse

QuerySanctionedAddressesRequest

protobuf
// Source: https://github.com/provenance-io/provenance // QuerySanctionedAddressesRequest defines the RPC request for listing sanctioned accounts. message QuerySanctionedAddressesRequest { // pagination defines an optional pagination for the request. cosmos.base.query.v1beta1.PageRequest pagination = 99; }

QuerySanctionedAddressesResponse

protobuf
// Source: https://github.com/provenance-io/provenance // QuerySanctionedAddressesResponse defines the RPC response of a SanctionedAddresses query. message QuerySanctionedAddressesResponse { // addresses is the list of sanctioned account addresses. repeated string addresses = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"]; // pagination defines the pagination in the response. cosmos.base.query.v1beta1.PageResponse pagination = 99; }

TemporaryEntries

Returns temporary sanction/unsanction info.
HTTP Endpoint: GET /cosmos/sanction/v1beta1/temp
Request: QueryTemporaryEntriesRequestResponse: QueryTemporaryEntriesResponse

QueryTemporaryEntriesRequest

protobuf
// Source: https://github.com/provenance-io/provenance // QueryTemporaryEntriesRequest defines the RPC request for listing temporary sanction/unsanction entries. message QueryTemporaryEntriesRequest { // address is an optional address to restrict results to. string address = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"]; // pagination defines an optional pagination for the request. cosmos.base.query.v1beta1.PageRequest pagination = 99; }

QueryTemporaryEntriesResponse

protobuf
// Source: https://github.com/provenance-io/provenance // QueryTemporaryEntriesResponse defines the RPC response of a TemporaryEntries query. message QueryTemporaryEntriesResponse { repeated TemporaryEntry entries = 1; // pagination defines the pagination in the response. cosmos.base.query.v1beta1.PageResponse pagination = 99; }

Params

Returns the sanction module's params.
HTTP Endpoint: GET /cosmos/sanction/v1beta1/params
Request: QueryParamsRequestResponse: QueryParamsResponse

QueryParamsRequest

protobuf
// Source: https://github.com/provenance-io/provenance // QueryParamsRequest defines the RPC request for getting the sanction module params. message QueryParamsRequest {}

QueryParamsResponse

protobuf
// Source: https://github.com/provenance-io/provenance // QueryParamsResponse defines the RPC response of a Params query. message QueryParamsResponse { // params are the sanction module parameters. Params params = 1; }
protobuf
// Example Query Service Definition // Source: https://github.com/provenance-io/provenance service Query { // IsSanctioned checks if an account has been sanctioned. rpc IsSanctioned(QueryIsSanctionedRequest) returns (QueryIsSanctionedResponse) { option (google.api.http).get = "/cosmos/sanction/v1beta1/check/{address}"; } // SanctionedAddresses returns a list of sanctioned addresses. rpc SanctionedAddresses(QuerySanctionedAddressesRequest) returns (QuerySanctionedAddressesResponse) { option (google.api.http).get = "/cosmos/sanction/v1beta1/all"; } // TemporaryEntries returns temporary sanction/unsanction info. rpc TemporaryEntries(QueryTemporaryEntriesRequest) returns (QueryTemporaryEntriesResponse) { option (google.api.http).get = "/cosmos/sanction/v1beta1/temp"; } // Params returns the sanction module's params. rpc Params(QueryParamsRequest) returns (QueryParamsResponse) { option (google.api.http).get = "/cosmos/sanction/v1beta1/params"; } }

Params

No param restrictions exist for the sanction module.