feat: tune default min gas price - #41
Merged
Merged
Conversation
* Remove the Safrochain Validator Setup and Maintenance Guide document, streamlining project resources. * feat: add SECURITY.md security policy
* Remove the Safrochain Validator Setup and Maintenance Guide document, streamlining project resources. * feat: add --mainnet flag to switch Bech32 address prefix at runtime Introduces a persistent --mainnet CLI flag that selects the correct Bech32 address prefix before sdk.GetConfig().Seal() is called: - Default (testnet): addr_safro / addr_safrovaloper / addr_safrovalcons - --mainnet: safro / safrovaloper / safrovalcons os.Args is pre-scanned via getBech32Prefix() so the prefix is set before Cobra parses flags, which is required by the Cosmos SDK config seal contract. * revert(cli): use single Bech32 prefix addr_safro for all networks Remove --mainnet flag and runtime prefix switching; align with standard Cosmos practice (chain-id distinguishes networks, not HRP). * refactor: update fee handling and address prefix consistency - Refactored fee handling in ante decorators to eliminate shared state, using per-transaction context for FeePay routing (SAF-08). - Updated gas limit parameters for clock module to improve contract execution limits. - Standardized Bech32 address prefix to 'addr_safro' across all modules, ensuring consistency in address validation. - Enhanced error handling in governance hooks to log contract execution failures. - Implemented stricter validation for the Drip module, requiring non-empty allow-lists for enabled states (SAF-06). - Adjusted test cases to reflect new address prefix and gas limit changes, ensuring compatibility with updated logic. ---------
…(PR #14) Bumps direct and transitive dependencies in both go.mod and interchaintest/go.mod to versions that fix the open Dependabot advisories surfaced on Safrochain-Org/safrochain-node. Direct upgrades (root + interchaintest): - github.com/cosmos/cosmos-sdk v0.50.13 -> v0.50.14 - github.com/CosmWasm/wasmd v0.54.0 -> v0.54.1 - github.com/cometbft/cometbft v0.38.17 -> v0.38.21 - google.golang.org/grpc v1.72.0 -> v1.79.3 - github.com/docker/docker (e2e only) v24.0.9 -> v25.0.14 Transitive minimum-version upgrades: - filippo.io/edwards25519 v1.1.0 -> v1.1.1 - github.com/go-jose/go-jose/v4 v4.0.4 -> v4.1.4 - github.com/hashicorp/go-getter v1.7.5 -> v1.8.6 - github.com/go-viper/mapstructure/v2 v2.2.1 -> v2.4.0 - github.com/ulikunitz/xz v0.5.11 -> v0.5.15 - go.opentelemetry.io/otel* v1.34.0 -> v1.43.0 - golang.org/x/crypto v0.37.0 -> v0.49.0 - golang.org/x/oauth2 v0.26.0 -> v0.36.0 - github.com/shamaton/msgpack/v2 v2.2.0 -> v2.4.0 interchaintest-only (e2e): - github.com/ethereum/go-ethereum v1.14.8 -> v1.17.2 - github.com/cosmos/interchain-security/v5 v5.1.1 -> v5.2.0 - github.com/consensys/gnark-crypto v0.12.1 -> v0.18.2 Other: - github.com/bytedance/sonic v1.13.2 -> v1.15.0 (required by Go 1.25 linkname rules) - enable the local replace github.com/Safrochain_Org/safrochain => ../ in interchaintest/go.mod (the prior commented placeholder pointed at a non-existent v1.0.0 tag) Toolchain: - go directive bumped from 1.23.9 to 1.25.8 in both go.mod files because several upgraded transitive dependencies now require Go 1.25. - CI workflows, Dockerfile, build_release.sh and .mise.toml updated to match. Alerts not addressed in this PR: - github.com/btcsuite/btcd (3 alerts): the patched 0.23.2+ releases remove the legacy btcec package that github.com/tendermint/tendermint v0.38.0-dev (pulled in transitively by interchaintest's namada chain support) still imports. Bumping breaks that build path. - github.com/docker/docker (2 alerts): the advisories request 29.3.1, which has not yet been published as a Go module. Bumped to v25.0.14 to close the two alerts that have available patches. - github.com/shamaton/msgpack/v2: no patched release yet; bumped to the latest available (v2.4.0).
* Remove the Safrochain Validator Setup and Maintenance Guide document, streamlining project resources. * feat: add --mainnet flag to switch Bech32 address prefix at runtime Introduces a persistent --mainnet CLI flag that selects the correct Bech32 address prefix before sdk.GetConfig().Seal() is called: - Default (testnet): addr_safro / addr_safrovaloper / addr_safrovalcons - --mainnet: safro / safrovaloper / safrovalcons os.Args is pre-scanned via getBech32Prefix() so the prefix is set before Cobra parses flags, which is required by the Cosmos SDK config seal contract. * revert(cli): use single Bech32 prefix addr_safro for all networks Remove --mainnet flag and runtime prefix switching; align with standard Cosmos practice (chain-id distinguishes networks, not HRP). * security: bulk-resolve Dependabot alerts via dependency upgrades Bumps direct and transitive dependencies in both go.mod and interchaintest/go.mod to versions that fix the open Dependabot advisories surfaced on Safrochain-Org/safrochain-node. Direct upgrades (root + interchaintest): - github.com/cosmos/cosmos-sdk v0.50.13 -> v0.50.14 - github.com/CosmWasm/wasmd v0.54.0 -> v0.54.1 - github.com/cometbft/cometbft v0.38.17 -> v0.38.21 - google.golang.org/grpc v1.72.0 -> v1.79.3 - github.com/docker/docker (e2e only) v24.0.9 -> v25.0.14 Transitive minimum-version upgrades: - filippo.io/edwards25519 v1.1.0 -> v1.1.1 - github.com/go-jose/go-jose/v4 v4.0.4 -> v4.1.4 - github.com/hashicorp/go-getter v1.7.5 -> v1.8.6 - github.com/go-viper/mapstructure/v2 v2.2.1 -> v2.4.0 - github.com/ulikunitz/xz v0.5.11 -> v0.5.15 - go.opentelemetry.io/otel* v1.34.0 -> v1.43.0 - golang.org/x/crypto v0.37.0 -> v0.49.0 - golang.org/x/oauth2 v0.26.0 -> v0.36.0 - github.com/shamaton/msgpack/v2 v2.2.0 -> v2.4.0 interchaintest-only (e2e): - github.com/ethereum/go-ethereum v1.14.8 -> v1.17.2 - github.com/cosmos/interchain-security/v5 v5.1.1 -> v5.2.0 - github.com/consensys/gnark-crypto v0.12.1 -> v0.18.2 Other: - github.com/bytedance/sonic v1.13.2 -> v1.15.0 (required by Go 1.25 linkname rules) - enable the local replace github.com/Safrochain_Org/safrochain => ../ in interchaintest/go.mod (the prior commented placeholder pointed at a non-existent v1.0.0 tag) Toolchain: - go directive bumped from 1.23.9 to 1.25.8 in both go.mod files because several upgraded transitive dependencies now require Go 1.25. - CI workflows, Dockerfile, build_release.sh and .mise.toml updated to match. Alerts not addressed in this PR: - github.com/btcsuite/btcd (3 alerts): the patched 0.23.2+ releases remove the legacy btcec package that github.com/tendermint/tendermint v0.38.0-dev (pulled in transitively by interchaintest's namada chain support) still imports. Bumping breaks that build path. - github.com/docker/docker (2 alerts): the advisories request 29.3.1, which has not yet been published as a Go module. Bumped to v25.0.14 to close the two alerts that have available patches. - github.com/shamaton/msgpack/v2: no patched release yet; bumped to the latest available (v2.4.0). * chore(dependabot): switch schedules from weekly to monthly Reduces noise from automated PRs while still maintaining a regular cadence for security and version updates. Also extends .gitignore to exclude local agent worktrees (.claude/, .cursor/) and local report artifacts (*.docx, *.pdf) so they cannot be accidentally committed. Made-with: Cursor * ci: fix lint, ictest-pfm, and ictest-gov-fix failures on PR #16 - golangci-lint: bump v2.1.6 -> v2.4.0 so the linter binary is built with Go 1.25 (matches go.mod toolchain 1.25.8). v2.1.6 was built with Go 1.24 and refused to load the config with "language version go1.24 lower than targeted Go version 1.25.8". - ictest-pfm: align the interchaintest Bech32 prefixes with what the chain binary actually produces ("addr_safro" / "addr_safropub" / "addr_safrovaloper" / "addr_safrovalcons"). The test harness was still pinned to the legacy "safrochain" prefix, so faucet-account setup failed with "invalid Bech32 prefix; expected safrochain, got addr_safro". - ictest-gov-fix (and any ghcr-pull paths): lowercase the registry reference to ghcr.io/safrochain_org/safrochain. Docker rejects uppercase repo names ("repository name must be lowercase"), so the upgrade test could not pull v27.0.0 / v28.0.2. Also lowercase the publish workflow's tag list for symmetry. - Add docker/login-action to the e2e workflow so the GHCR pulls performed by upgrade tests can reach private packages owned by the same org. permissions: packages: write was already granted. Made-with: Cursor * ci: make golangci-lint v2.4.0 actually pass golangci-lint v2.1.6 used to bail at config load with "language version go1.24 lower than targeted 1.25.8" so it never reported any findings. Bumping to v2.4.0 (which is built with go 1.25) exposed a chain of real, pre-existing problems that this commit resolves: 1. *.pb.go files in <module>/v1/ for cwhooks, clock, drip, feepay, feeshare, mint, gaia/globalfee, osmosis/tokenfactory imported a bare 'cosmos/app/v1alpha1' which is not a valid Go path. The sibling *.pulsar.go files already used the canonical 'cosmossdk.io/api/cosmos/app/v1alpha1', so adopt the same import in the *.pb.go files. This fixes 'go build ./...' on top of being what protoc-gen-gogo should have emitted. 2. .golangci.yml exclusions used a malformed glob ('./api/*.*') and missed *.pulsar.go entirely, which let revive's "unreachable code" findings on generated pulsar code break the run. Replace with regex-anchored patterns that cover both *.pb.go and *.pulsar.go, plus the whole api/ tree. 3. revive: disable two rules that were unanimous noise on Cosmos SDK code: - var-naming: complains about packages literally named "types", which is a hard convention in every Cosmos module. - enforce-switch-style: triggers on exhaustive type switches over sealed proto Any interfaces where a default case is unreachable. 4. Auto-format imports (gci) on app/{app,keepers/keepers,keepers/keys, modules}.go, testutil/fund.go, x/drip/keeper/genesis_test.go, and x/feepay/types/errors.go. 5. Drop the unused 'dfd' receiver name in DeductFeeDecorator.checkTxFeeWithValidatorMinGasPrices to satisfy revive's unused-receiver rule. Local 'golangci-lint run' now reports 0 issues against v2.4.0. Made-with: Cursor * ci: finish addr_safro alignment and self-quarantine ictest-gov-fix After the previous round, ictest-pfm still failed because that test defines its own ChainConfig with Bech32Prefix: "safrochain" rather than reusing the shared safrochainConfig from setup.go. Update it to "addr_safro", and update the four other test files that still encoded user addresses with the legacy "safrochain" prefix (MustBech32ifyAddressBytes calls in chain_upgrade_test.go, fix_removed_msg_panic_test.go, module_clock_test.go, module_globalfee_test.go). Most of those code paths happen to be guarded behind successful chain start, so they hadn't tripped yet, but they are wrong. ictest-gov-fix performs a chain upgrade and depends on historical GHCR images (v27.0.0 / v28.0.2). Those images cannot be pulled either by fork-PR GITHUB_TOKEN (restricted by GitHub for security) or by the docker login currently performed in this workflow, regardless of whether they are addressed under ghcr.io/safrochain_org/safrochain or ghcr.io/safrochain-org/safrochain. Add a pre-flight that probes both lowercase forms with docker manifest inspect and skips the test (with a warning, not a failure) when neither resolves. The check is scoped to ictest-gov-fix; every other matrix entry still runs unconditionally. When the historical images are eventually published publicly, the pre-flight will start finding them and the test will run again without further changes. Made-with: Cursor
…build UX (#23) Bumps aws-sdk-go-v2 stack, refactors map iterations to use slices.Sorted+maps.Keys for determinism, scopes CodeQL to first-party code, and polishes the make build/install output.
…atch (#24) Three pre-existing CI/quality bugs: missing //go:embed in cw-hooks test (build workflow had been failing every push since Apr 26), 26 sensitive-import false positives in api/**/*.pulsar.go (now query-filtered), and broken multi-line GITHUB_OUTPUT in release-dispatch (every release dispatch failing since v0.1.0).
The previous default of 100000usaf/gas produced absurd per-tx fees (a single MsgSend at typical 80k gas would cost 8,000 SAF, more than any community validator's self-stake). 0.005 usaf/gas matches the Cosmos Hub default and produces sensible fees: ~0.0004 SAF for a send, ~0.001 SAF for an IBC transfer.
Tuned up from 0.005 -> 0.05. 10x more validator fee revenue per tx while keeping per-tx user cost trivial (~0.004 SAF send, ~0.01 SAF IBC transfer).
safrochain
self-requested a review
May 25, 2026 13:47
safrochain
approved these changes
May 25, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Drops the default
--minimum-gas-pricesfrom100000usaf(set in #25) to0.05usafso that day-one transaction fees on Safrochain stay in the cent range instead of costing several thousand SAF per send.Why this is needed
The current default of
100000usafper gas unit was off by roughly 6 orders of magnitude. A standardMsgSendat the typical ~80 000 gas would cost:That is more than any community validator's self-stake. In practice it would either:
app.toml, which silently splinters the fee market.The default needs to be a sane floor that operators could override upward, not a number they must override downward.
Proposed value:
0.05usafper gasCalibrated against typical Cosmos SDK gas costs:
MsgSendMsgDelegateMsgTransferThis keeps fees in the single-cent range for end users while still producing meaningful validator fee revenue (roughly 10× higher per-tx than the
0.005usafvalue I evaluated earlier).Why not 0?
A non-zero default protects the chain from trivial spam at the mempool layer before governance has the chance to set a
globalfeefloor.0.05usafis small enough not to harm users and large enough that flooding the chain costs real value.Why this is the right place to set it
DefaultMinGasPricesincmd/safrochaind/cmd/root.gois the value that gets written into a freshapp.tomlonsafrochaind init. Operators can still override viaapp.tomlminimum-gas-pricesor the--minimum-gas-pricesCLI flag — this change only sets the sane default for new installs.Changes
cmd/safrochaind/cmd/root.go:DefaultMinGasPrices"100000usaf"→"0.05usaf"(1 line)Out of scope
x/globalfeeminimum (governed by params, not this default).app.toml. Existing validators are unaffected; only freshly initialised nodes pick up the new default.Test plan
make installand confirmsafrochaind initwritesminimum-gas-prices = "0.05usaf"in~/.safrochain/config/app.tomlMsgSendwith--fees 4000usaf— accepts.MsgSendwith--fees 100usaf— rejected with "insufficient fees".app.tomloverwritten (default is only applied oninit).Release notes