Transferring reward from `StakingToken` contract to service owner can revert when `stakingToken` is a token that has balance changes outside of transfers
Audit: 2024-05-olas-findings
Severity: MEDIUM

# Lines of code

https://github.com/code-423n4/2024-05-olas/blob/main/registries/contracts/staking/StakingBase.sol#L482-L511
https://github.com/code-423n4/2024-05-olas/blob/main/registries/contracts/staking/StakingBase.sol#L805-L872
https://github.com/code-423n4/2024-05-olas/blob/main/registries/contracts/staking/StakingToken.sol#L104-L111


# Vulnerability details

## Impact
Tokens that have balance changes outside of transfers need to be supported based on https://github.com/code-423n4/2024-05-olas?tab=readme-ov-file#erc20-token-behaviors-in-scope. When `stakingToken` is such token, its rebasing event can be triggered to make the `StakingToken` contract's balance of such token lower than before. If such rebasing event has been triggered, when the following `_claim` or `unstake` function, which further calls the `_withdraw` function below, is called, the `StakingToken` contract's balance of such token can be lower than the reward amount to be transferred from the `StakingToken` contract to the service owner; for instance, the reward can accumulate to equal `balance` but the `StakingToken` contract's balance of such token can become less than `balance` when such rebasing event has been triggered. In this case, executing `SafeTransferLib.safeTransfer(stakingToken, to, amount)` in the `_withdraw` function reverts, which causes the service owner to be unable to receive her or his deserved reward.

https://github.com/code-423n4/2024-05-olas/blob/main/registries/contracts/staking/StakingBase.sol#L482-L511
```solidity
    function _claim(uint256 serviceId, bool execCheckPoint) internal returns (uint256 reward) {
        ServiceInfo storage sInfo = mapServiceInfo[serviceId];
        ...
        // Get the claimed service data
        reward = sInfo.reward;
        ...
        // Transfer accumulated rewards to the service multisig
        // Note that the reentrancy is not possible since the reward is set to zero
        address multisig = sInfo.multisig;
        _withdraw(multisig, reward);
        ...
    }
```

https://github.com/code-423n4/2024-05-olas/blob/main/registries/contracts/staking/StakingBase.sol#L805-L872
```solidity
    function unstake(uint256 serviceId) external returns (uint256 reward) {
        ServiceInfo storage sInfo = mapServiceInfo[serviceId];
        ...
        // Get the unstaked service data
        reward = sInfo.reward;
        ...
        // Transfer accumulated rewards to the service multisig
        if (reward > 0) {
            _withdraw(multisig, reward);
        }
        ...
    }
```

https://github.com/code-423n4/2024-05-olas/blob/main/registries/contracts/staking/StakingToken.sol#L104-L111
```solidity
    function _withdraw(address to, uint256 amount) internal override {
        // Update the contract balance
        balance -= amount;

        SafeTransferLib.safeTransfer(stakingToken, to, amount);
        ...
    }
```

## Proof of Concept
The following steps can occur for the described scenario.
1. `stakingTok