Frontrunning validator freeze to withdraw tokens
Covalent implements a freeze mechanism to disable malicious Validators, this allows the protocol to block all interactions with a validator when he behaves maliciously. Covalent also implements a timelock to ensure tokens are only withdraw after a certain amount of time. After the cooldown ends, tokens can always be withdrawn.\\nFollowing problem arise now: because the tokens can always be withdrawn, a malicious Validator can listen for a potential "freeze" transaction in the mempool, front run this transaction to unstake his tokens and withdraw them after the cooldown end.\\nAlmost every action on the Operational Staking contract checks if the validator is frozen or not:\\n```\\n require(!v.frozen, "Validator is frozen");\\n```\\n\\nThe methods transferUnstakedOut() and recoverUnstaking() are both not checking for this, making the unstake transaction front runnable. Here are the only checks of transferUnstakedOut():\\n```\\nrequire(validatorId < validatorsN, "Invalid validator");\\n        require(_validators[validatorId].unstakings[msg.sender].length > unstakingId, "Unstaking does not exist");\\n        Unstaking storage us = _validators[validatorId].unstakings[msg.sender][unstakingId];\\n        require(us.amount >= amount, "Unstaking has less tokens");\\n```\\n\\nThis makes following attack possible:\\nValidator cheats and gets rewarded fees.\\nProtocol notices the misbehavior and initiates a Freeze transaction\\nValidator sees the transaction and starts a unstake() transaction with higher gas.\\nValidator gets frozen, but the unstaking is already done\\nValidator waits for cooldown and withdraws tokens.\\nNow the validator has gained unfairly obtained tokens and withdrawn his stake.
Implement a check if validator is frozen on `transferUnstakedOut()` and `recoverUnstaking()`, and revert transaction if true.\\nIf freezing all unstakings is undesirable (e.g. not freezing honest unstakes), the sponsor may consider storing the unstake timestamp as well:\\nStore the unstaking block number for each unstake.\\nFreeze the validator from a certain past block only, only unstakings that occur from that block onwards will get frozen.
Malicious validators can front run freeze to withdraw tokens.
```\\n require(!v.frozen, "Validator is frozen");\\n```\\n