In this case, a team of ~100 all had access to everyone's projects. So rather than being stuck with the demands of a single client, everyone got to work overtime whenever they wanted, and not when they didn't.
We simply let the team bill to multiple contracts. The contract & dev managers were responsible for authorizing the time and ensuring it was necessary/suitable/etc.
A typical T&M contract considers something around 1920 billable hours per year an FTE. 40 hrs a week, 4 weeks of vacation/sick time/etc per year. The typical way to manage those contracts at scale is hire one person per 1920 hours on a contract, then that person works exclusively on that contract.
We didn't allocate one person to a single contract, but fractions of a person - based on how much we estimated any given contract would need a certain set of skills:
"Joe's 20% on Project X and 80% on Y. Valerie's 100% on Y. Bill's 80% on Y and 20% on Z."
Of course, those are just estimates and nothing ever goes to plan - and it's always hard to hire enough good people. As a result, there were always opportunities for folks to do more work - either on their primary contract(s) or supporting another.
It makes the contract management harder, but it provides meaningful benefits to both the team and the clients.
By under resourcing the operation, employees were guaranteed to earn 'overtime' if they wanted it. However implication is that you would be happy putting in 50-60 hours.
You're taking a too narrow a view of it. We never committed anyone to 50-60 hours, that's unsustainable. But by _allowing_ it and building a system to manage it, you let folks work what they want and still meet the client needs.
Without that flexibility, what happens is what OP describes - folks work more than 40 because you need to / want to, but you don't get compensated for it.