There are a few changes that I'd make.
First, I'd get rid of the QA sign-off on dev before cutting a release branch. I'd look at methods to instill a culture of developer-led testing (especially if that means developing automated tests) on your trunk. Of course, this doesn't mean that your testers shouldn't be using the trunk deployed to the development environment - they can be practicing any manual test cases or doing exploratory testing and giving feedback.
Second, if you haven't, I'd look at automating the end-to-end testing done in the UAT environment, at least from a regression standpoint. You may want to do some manual testing, especially of an exploratory nature, in UAT, but you want to reduce the burden of manual testing, especially as the system increases in complexity.
It may not matter much, but I would recommend fixing defects in the release branch and merging back into the trunk. You could also cherry-pick or rebase or some other method, as well. But I've found that going from release branch to development branch is more intuitive.
Once you have a sign off on the release, apply a tag. You can either get the state of the code back into trunk and deploy the tag in the trunk or you can deploy the head of the release branch. Both are the same thing.
If you have multiple UAT in progress at once, then you may need multiple environments. However, you're also introducing complexity around a defect found in UAT2 that also impacts UAT1 and managing getting the fixes synchronized. I'd want to understand what makes UAT take so long and what can be done to get an accepted system into production faster to reduce parallel UATs.