The badge client (badges/classes/oauth2/client) overrides a number of the core client's methods (lib/classes/oauth2/client). We're now seeing situations (like seen in MDL-71119) where fixes made to core's client aren't being seen by the badge code, since it's so heavily overridden. A lot of code is being duplicated right now too and in many cases now, unnecessarily.
Core's client provides DB token storage for access and refresh tokens, automatic refresh token exchange (since MDL-59510) among other core functions like token upgrade and exchange. There should now be fewer reasons for badges to override the respective methods.
The badge client does require extra params during it's auth request (i.e. during upgrade_token calls). We should, however, be able to facilitate this in the core client by allowing the upgrade_token() method to take in an optional param, $params, allowing clients to pass in extra params they need.
Badges would also need to be updated to refer to the core token storage locations (e.g. the access_token and refresh_token tables in core) instead of storing these tokens in a badge table of its own.
This way, once badges uses the core client for most calls, any changes made to core in future will trickle down nicely to badges.