What would be a practical approach to implementing upgrade system

So I have 3 Scriptabe Objects: Player Stats, Weapon Stats and Weapon Ammo Stats. Each of them contain different types of values: float, bool, Vector3, int. In my game, whenever a player levels up, he can choose to upgrade his base stats, weapon stats or ammo, but I seem to struggle with finding the right approach to do this.

I tried creating a loop, for looping thourough Scrptable Object properties and making a Dictionary of property key and value something like this, but clearly this is not right:

public Dictionary<string, object> GetProperties()
		return GetType().GetProperties().ToDictionary(a => a.GetType().Name, a => a.GetValue(this));

Any help would be appreciated!

I would make them all inherit from an abstract base State class that has a virtual method for leveling up that you would override in your child classes so you can right different level up code for each. You could also use an interface for this.