controller.inflationManager() in practice can only be set once, so you can cache this value in the constructor of the StakerVault (require that it not empty address(0)).
controller.addressProvider() is set in the constructor, so you could cache this too to avoid gas consuming external calls.
I do not think this address(0) check is necessary here because the call to _controller.addressProvider() would have already reverted:
controller.inflationManager() in practice can only be set once, so you can cache this value in the constructor of the StakerVault (require that it not empty address(0)). controller.addressProvider() is set in the constructor, so you could cache this too to avoid gas consuming external calls.
Here you can just return the boolean condition:
Is the same as:
Consider having an extra function in StakerVault contract that groups these functions together to avoid repeated external calls:
There are some massive structs, e.g. ExecuteLocalVars. Gas efficiency can be achieved by tightly packing the struct. Struct variables are stored in 32 bytes each so you can group smaller types to occupy less storage. You can read more here: https://fravoll.github.io/solidity-patterns/tight_variable_packing.html or in the official documentation: https://docs.soliditylang.org/en/v0.4.21/miscellaneous.html
To optimize function unstakeAndRedeem for gas usage, I would refactor it to something like this: