Skip to content

fix: add access control to set_risk_tier + initialize admin#54

Closed
woydarko wants to merge 1 commit into
mericcintosun:mainfrom
woydarko:fix/set-risk-tier-access-control
Closed

fix: add access control to set_risk_tier + initialize admin#54
woydarko wants to merge 1 commit into
mericcintosun:mainfrom
woydarko:fix/set-risk-tier-access-control

Conversation

@woydarko

Copy link
Copy Markdown
Contributor

Summary

Fixes #50

set_risk_tier had no authorization check — any address could overwrite any user's risk score, making the on-chain credit score trivially manipulable and blocking mainnet deployment (v1.1 roadmap).

Changes

risk_score/src/lib.rs

Added initialize(admin)

  • Sets a trusted admin address once on-chain
  • Panics with "already initialized" if called again
  • Admin address is stored in instance storage under DataKey::Admin

Added get_admin()

  • Returns the current admin address, or None if not yet initialized

Fixed set_risk_tier — now takes a caller parameter and enforces:

  • Contract must be initialized (panics with "contract not initialized — call initialize() first" if not)
  • caller must be the admin OR the user themselves — both require require_auth()
  • Any other caller panics with "unauthorized: caller must be admin or the user themselves"

Fixed update_chosen_tier

  • Added user.require_auth() so only the user themselves can change their chosen tier

risk_score/Cargo.toml

  • Added [dev-dependencies] with soroban-sdk = { version = "22.0.8", features = ["testutils"] } to enable Address::generate in tests

Tests (20 passed, 0 failed)

New auth tests added:

  • test_initialize_sets_admin — admin is correctly stored
  • test_initialize_twice_panics — double initialization rejected
  • test_admin_can_set_risk_tier_for_any_user — admin can set scores for others
  • test_user_can_set_own_risk_tier — user can set their own score
  • test_third_party_cannot_set_risk_tier — attacker cannot overwrite victim's score
  • test_set_risk_tier_requires_initialization — uninitialized contract rejects calls

All 14 existing tests adapted to new signature and passing.

test result: ok. 20 passed; 0 failed

Fixes mericcintosun#50

## Problem
set_risk_tier had no authorization check — any address could overwrite
any user's risk score, making the on-chain credit score trivially
manipulable and blocking mainnet deployment.

## Changes

### risk_score/src/lib.rs
- Added DataKey enum with Admin variant for typed storage
- Added initialize(admin) — sets trusted admin once, panics if called again
- Added get_admin() — returns current admin address
- set_risk_tier now takes a caller parameter and enforces:
  - Contract must be initialized (panics with clear message if not)
  - caller must be admin OR the user themselves
  - Unauthorized callers panic with 'unauthorized'
- update_chosen_tier now calls user.require_auth() for self-service updates

### risk_score/Cargo.toml
- Added dev-dependencies with soroban-sdk testutils feature for tests

### Tests (20 tests, 0 failed)
New auth tests:
- test_initialize_sets_admin
- test_initialize_twice_panics
- test_admin_can_set_risk_tier_for_any_user
- test_user_can_set_own_risk_tier
- test_third_party_cannot_set_risk_tier (should panic)
- test_set_risk_tier_requires_initialization (should panic)

All 14 existing tests adapted to new signature and passing.
@vercel

vercel Bot commented Apr 18, 2026

Copy link
Copy Markdown

@woydarko is attempting to deploy a commit to the mericcintosun Team on Vercel.

A member of the Team first needs to authorize it.

@mericcintosun

Copy link
Copy Markdown
Owner

Thanks! Closing as superseded by #74. This PR changes set_risk_tier to a 5-arg signature without updating the frontend, which would break the deployed client. #74 keeps the existing ABI, so no lockstep deploy is needed. 🙏

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.

[Security] set_risk_tier has no access control — any address can overwrite any user's score

2 participants