Skip to content

fix(settlement): validate governance fee config shape - #667

Open
Hikmaholadele wants to merge 4 commits into
Betta-Pay:mainfrom
Hikmaholadele:fix/issue-483-governance-fee-config-validation
Open

fix(settlement): validate governance fee config shape#667
Hikmaholadele wants to merge 4 commits into
Betta-Pay:mainfrom
Hikmaholadele:fix/issue-483-governance-fee-config-validation

Conversation

@Hikmaholadele

Copy link
Copy Markdown
Contributor

Closes #483
Summary

Safely validates the governance fee configuration before deserialization, preventing malformed configurations from causing opaque host/Wasm errors.

  • Requires exactly 2 governance fee configuration fields.
  • Rejects malformed configurations with GovernanceCallFailed.
  • Adds regression coverage for a short/1-field configuration.
  • Preserves valid configuration and bootstrap behavior.

Tests: cargo test --workspace — all tests pass.

Closes #483

Closes Betta-Pay#483

Safely validate the governance fee configuration before accessing its
fields. Previously, `read_governance_fee_rule` and
`validate_fee_against_governance` used
`try_invoke_contract::<Option<GovFeeConfig>, SettlementError>`, which
triggers host-side `map_unpack_to_slice` deserialisation. If the
governance contract returns a struct with a different shape (e.g. 1 field
instead of 2), the host panics with an opaque "escalating error to
panic" rather than the typed `GovernanceCallFailed` error.

The fix introduces `try_read_governance_fee_config`, which:
1. Receives a raw `Val` from `try_invoke_contract::<Val>` (no host-side
   deserialisation).
2. Validates the map structure: exactly 2 fields, both present, both `u32`.
3. Returns `Some(GovFeeConfig)` for valid configs, `None` for Void, or
   panics with `GovernanceCallFailed` for malformed shapes.

Both `read_governance_fee_rule` and `validate_fee_against_governance` now
route through this helper. Existing behavior for valid 2-field
configurations and no-config (bootstrap fallback) is preserved.

cargo test -p settlement_contract — 108 passed, 0 failed (governance
error tests: 7 passed, including 3 new malformed-config regression tests).
@drips-wave

drips-wave Bot commented Aug 26, 2026

Copy link
Copy Markdown

@Hikmaholadele Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

Remove the `try_update_governance` assertion from
`real_auth_tests::fee_anchor_and_system_param_writes_require_real_authorization`.

The `GovernanceContract` no longer has an `update_governance` method (it was
replaced by `upgrade` and `transfer_admin`), so the generated client does not
expose `try_update_governance`. This pre-existing stale reference caused a
compilation failure on every workspace build.

The remaining three assertions (`try_set_fee_config`, `try_upsert_anchor`,
`try_update_system_param`) still verify that governance writes require real
authorization.

Closes Betta-Pay#483

🤖 Generated with Codebuff
Co-Authored-By: Codebuff <noreply@codebuff.com>
@Hikmaholadele

Copy link
Copy Markdown
Contributor Author

Hi, this workflow is currently waiting for maintainer approval. Could you please approve it so the workflow can proceed? Thank you.

Hikmaholadele and others added 2 commits August 31, 2026 09:06
Fix compilation errors caused by API changes merged from main:
- Add missing deployer parameter to all init() calls in tests
- Add executor parameter to execute() calls in timelock tests
- Fix variable references (_admins -> admins) in schedule collision tests
- Import GovernanceContract/GovernanceContractClient from governance_contract
- Add missing Symbol/FromVal imports for test event assertions
- Fix set_fee_config to use governance_contract::FeeConfig type
- Remove unused imports and prefix unused variables with underscore
- Use IntoVal for Symbol conversion in storage.rs
- Replace assert_eq! with assert! for literal bool comparison
- Apply cargo fmt formatting across workspace

🤖 Generated with Codebuff
Co-Authored-By: Codebuff <noreply@codebuff.com>
@Hikmaholadele

Copy link
Copy Markdown
Contributor Author

This workflow is currently awaiting maintainer approval. Could you please approve it so the workflow can proceed? Thank you.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

validate_fee_against_governance assumes a 2-field tuple and silently skips ceilings on a 1-field config

1 participant