As Philipp already wrote, there isn't one algorithm, but I think one could say there are a number of common algorithms with different characteristics, and you take advantage of those for different parts of game progression.
So if you want to ensure a player doesn't get an item too early, you make it dependent on a numeric (currency, in your example, but could also be a reputation, skillpoints level, xp points etc.) that they can only obtain at the desired point.
How do I ensure a numeric is only obtained at the desired point?
By handing out that kind of numeric only at predetermined points, maybe even only once, e.g. whenever the player first finishes a given level or mission, give them 10 skill points. Replays can reward a little of that numeric (say, 1), so that a player who is stuck on one level can e.g. skip that and re-play a few other missions to make up for that.
If you don't have any predetermined points (e.g. because your game is a PvP shooter without levels or story mode, just repeated play of the same maps), you usually reward the numeric on other significant events (like enemy kills) and make it increase exponentially, and/or depending on player and enemy level, to make it impractical to grind for with low-tier enemies, and to reward a low-level player who manages to take down a higher-level enemy.
How do I ensure a player advances only over a certain time?
Beyond that, you can select the powers, cool-downs and power levels of both opponents so the time taken for them equates to the amount of currency you want to dispense in a certain amount of time. E.g. in our shooter example, a player can only do a certain amount of damage in a certain time. You select their enemies' health levels so they can withstand that amount of damage for that long, then reward the desired amount of the numeric.
If that's not enough, you can always put an artificial cap on a numeric, like only awarding a certain amount within 24 hours, maybe hiding it behind a conversion (e.g. players earn iron ore, but the iron mongers take 1 day to process it into iron that you can actually give to the blacksmith to have your sword made).
In the end, you want a single number
What this generally ends up as is you get a bunch of conversion rates, where it all boils down to a common base numeric in the end, which is what measures progression, or rewards, or whatever. Examples for numerics can be abstract things like experience points, or "junk" loot drops that translate to currency directly, but also very concrete things like "successful damage dealt" that can be used to allot different percentages of a killed enemy's loot when several players take down the same enemy.
How do I make players get different gear for different purposes?
There can be separate groups of such base numerics. Often games work with one base numeric for common items, and different ones for endgame items. That way, you e.g. force players to actually play easy PvP content to unlock PvP gear needed for the harder PvP content.
So how do you make PvP gear different from PvE gear? Well, there are many ways. You could just make PvP reward armor/weapons that are so much stronger than PvE ones that you need them to avoid being taken out (works best if PvP is endgame-only). Some games have different "damage types" for different enemies. So PvP armor would just have a much higher resistance to PvE bullets than to PvP ones. This resistance could also take the shape of a buff that is simply applied to every player in PvE areas.
You can even monetize that, by e.g. making players have separate PvP and PvE armor, but offering armor that works in both places for money in your store. A good compromise between monetization and not making it unfair by offering something that couldn't be unlocked by playing. It's just a convenience (as long as a lower-level plater can't wear higher-level armor bought from the store until (s)he has leveled up).
How do I prevent higher-level players from going after low-level enemies?
As to your example: If you want to reward/punish players for fighting higher/lower level enemies, you'd want to change
<player level> * <enemy level> to something more like
min(<player level>,<enemy level>) * max(1,<enemy level> - <player level>) (I'm making this up on the spot, fiddle with it). The first part ensures that a low player doesn't suddenly get rewarded as high as a higher one, but a high player fighting a low-level enemy only gets rewards at that low level. The second part means you get a bonus for fighting up, but you don't ever lose points when fighting down. Or, depending on your numbers, it might be a better idea to calculate a malus for fighting down, just ensuring a minimum reward is still given in such cases.