> As Izzy mentioned dozens of times: "Having an untouchable bond rebase is not sustainable at a scale". It is hard to argue against it, to be honest. Currently, this issue might be solved with in-protocol bonds. Given that in-protocol bonds are not feasible to implement within a year or so, an alternative approach is proposed.
> Reasoning from Max:
> Opening up the possibilities to scale requires some tech, incentivizing NO
> - to perform well (without a strive to perform at max level possible)
> - to leave / or be exited the module if acceptable level of performance is not achievable by particular NO
>
> While the first point is incentivized via performance threshold, the second point only triggers in case of worst-case scenario performance (turning off validator for 2+ month) and exiting via low validator balance
>
> Scalability of module requires more flexible way of managing NO set including those who perform good enough to maintain positive validator balance (which is achievable with Validator being online only for 40% of time) but not good enough to provide capital providers (stakers) reasonable amount of APR
> Inspired by the https://hackmd.io/@5wamg-wlRCCzGh0aoCqR0w/SJnxLSnp6
# Ejecting bad performers
It is proposed to keep [Simple Bond](https://hackmd.io/6Rp6ITGfT5uVIgktwk7S0w?view#Module-level-bond-aka-Simple-bond) and [CSM Performance Oracle](https://hackmd.io/QmMkXEjbR1e8IFgN-6yC_g?view#Performance-Oracle) with the single threshold as is and add another tool to ensure bad-performers ejection while keeping the amazing socialization and performance leeway features of CSM.
1. Bonds work as described in Simple Bond. Bond is stored in the form of stETH collateral and receives rebase as usual stETH.
2. CSM Performance Oracle distributes staking rewards as described in the CSM Arch doc with the single performance threshold.
3. **\[NEW\]** Validators performing below the performance threshold for 3 frames within 6 frames are ejected from the consensus layer using EIP-7002.
Let's dig deeper into the third point.
## Missed profit confiscation
One of the additional features to the ejection of the bad-performers is confiscation of the missed profits or bond rebase aqcuired during the frames with low performance.
There are several ways to calculate missed profits (performance tax):
- Dumb way. Сonstant value set by the DAO. It can be updated in case of significant network APR changes. Fine calculated as `oneFrameProfit * 3` or `oneFrameRebase * 3 * bondAmount` if confiscating only bond rebase;
- Smart way. Report the average network APR for each Performance Oracle frame. Use it for calculations as `32 ETH * avgAPR * 3 / 12`;
The exact option can be decided later.
It is crucial to note that performance tax is a suplementary tool. It can be used even without ejection. However. it is proposed to combine this two tools (ejection + performance tax)
## Bad performers with low CL balance
In the initial version of the CSM architecture document, it was proposed that CSM bot keeps track of the CL balances of the validators and eject those with the balance below some threshold. With the introduction of the strikes for CSM, tracking CL balance becomes redundant since the validator will most likely acquire 3 strikes earlier than dropping below the threshold in CL balance. It seems reasonable to remove the CL balance threshold and rely on the strikes system for the ejection of the bad-performing validators.
## Detailed algorithm
Once in a frame, CSM Performance Oracle delivers additional tree root with the information about "strikes" for the validators. Strike means that the validator was performing below the threshold in this frame. When updating this tree, CSM Performance, Oracle takes into account the previous values from the old tree. All strikes older than 6 months are dropped.
Once the number of strikes reaches 3 (3 strikes in 6 months), the permissionless method can trigger exit for the validator and confiscate performance tax + ejection tax from the Node Operator's bond.
Strikes tree leaves have a form of `{noID, validatorPubkey, [strikeTimestamps]}`.
Since Node Operator key indices might be changed in the new optimistic vetting approach (deleted key is swapped with the last key in the keys storage), it is required to provide the current key index in the Node Operator's storage to the permissionless method and check that the key in the leaf and the storage are identical.
``` solidity
function ejectBadPerformingValidator(uint64 noId, bytes32 proof, uint256 keyIndex) {
validatorKey = getNoKey(noId, keyIndex);
checkKey(proof, validatorKey);
checkProof(proof);
requestEjection(validatorKey);
confiscatePerfTax(noId);
confiscateEjectionTax(noId);
}
```
## Pros
- Bad performers are ejected to avoid unbonding and further impact on the protocol APR;
- Bad performers bond will be penalized for the missed profits;
- OK and semi-OK performers will not be affected;
- Feasible to implement;
## Cons
- It might not be great for the narrative. A thorough comms preparations are required;
- Yet another layer of the module complexity;
- It is still possible to perform under the threshold for 2 frames and than reset strikes counter to 0 by performing above the threshold for one frame;
## Possible edge cases
### Exiting earlier than getting the third strike
It is possible that the Node Operator will decide to exit his validator before getting a third strike. This will allow him to avoid performance tax confiscation. However, all direct losses will be confiscated, and no staking rewards will be distributed during frames with poor performance.
To overcome this issue it is proposed to account for the strikes during the validator exit reporting and confiscate performance tax for each strike.