You have to separate your concerns.
Generally speaking, tokens that are transferred are beyond your control. So, if you want to slash balances you should hold the staked tokens in your own contract and treat it as an internal accounting concern starting with deposit
and withdraw
functions and a structure to store your contract's liabilities:
mapping(address => unit) public playerTokenBalances;
In that simple pattern, tokens in your contract are "in play" and tokens withdrawn are safely in the hands of the holders - safe from the possibility of slashing penalties. There is no function you can write that will spend tokens in another wallet without consent.
It may be sufficient to conceptualize the reward system so that people will prefer to leave their token (claims) in your contract most of the time. And, since it's your contract, those balances would be subject to your rules.
If you find that insufficient for your use-case then the possibility exists to create a non-standard ERC20 token contract that implements some behind-the-scenes logic. ERC20 is, strictly speaking, a standard interface and a minimal set of behaviors that must be implemented but is not the limit of the functions that can exist or the logic that unfolds inside the contract.
Such a special implementation would have be very carefully considered, so it is usually best to prefer the first option.
Hope it helps.