Submitted by EV_om, also found by ArsenLupin
The StakingBase contract allows service owners to stake their service by transferring it to the contract via stake(). The services multisig address is set in the ServiceInfo struct at this point and cannot be modified afterward. When the owner wants to unstake the service via unstake(), the contract attempts to transfer any accumulated rewards to this multisig address:
However, the protocol is meant to support reward tokens which may have a blocklist and/or pausable functionality.
If the multisig address gets blocklisted by the reward token at some point after staking or the reward token pauses transfers, the _withdraw() call in unstake() will fail. As a result, the service owner will not be able to unstake their service and retrieve it.
If a services multisig address gets blocklisted by the reward token after the service is staked, the service owner will be permanently unable to unstake the service and retrieve it from the StakingBase contract. The service will be stuck.
If the reward token pauses transfers, the owner will not be able to unstake the service until transfers are unpaused.
Additionally, the owner will not be able to claim rewards either, since these are sent to the multisig.
Consider implementing functionality to update the multisig address. This address should ideally be updated via the service registry to ensure it is properly deployed (seeing as it must match a specific bytecode), after which it can be updated in the staking contract by pulling it from the registry.
Alternatively and to also address the pausing scenario, unstaking could be split into two separate steps - first retrieve the service NFT, then withdraw any available rewards. This way, blocklisting or pausing would not prevent retrieval of the NFT itself.
Token-Transfer
kupermind (Olas) acknowledged and commented:
Olas mitigated
Varun_05 (warden) commented:
