sherlock-audit / 2024-05-aleo-judging

0 stars 0 forks source link

knight110001 - The unbond function should distinguish between calls made by the Validator and the Delegator when removing a validator. #16

Closed sherlock-admin3 closed 1 week ago

sherlock-admin3 commented 2 weeks ago

knight110001

Medium

The unbond function should distinguish between calls made by the Validator and the Delegator when removing a validator.

Summary

The unbond function should distinguish between calls made by the Validator and the Delegator when removing a validator.

Vulnerability Detail

https://github.com/sherlock-audit/2024-05-aleo/blob/main/snarkVM/synthesizer/program/src/resources/credits.aleo#L600

The unbond function should distinguish whether it is called by the Validator or the Delegator when removing_validator. If it is called by the Validator, the current processing flow is fine. The funds of the Validator's Delegator need to be put into the unbond to ensure a height of 360 before continuing the bond_validator. However, if this function is called by an ordinary staker, the remove_validator can be removed, but once new Delegator funds come in, the Validator can bond_validator in time

Impact

There should be a difference between remove_validator caused by validator and staker calling unbond

Code Snippet

   /* Unbonding */

    // Retrieve or initialize the unbonding state.
    get.or_use unbonding[r5.validator] r4 into r45;
    // Increment the unbond amount by the full bonded amount.
    // Note: If the addition overflows, reject the transition.
    add r30.microcredits r45.microcredits into r46;
    // Construct the updated unbond state.
    cast r46 r3 into r47 as unbond_state;
    // Store the new unbonding state.
    set r47 into unbonding[r5.validator];

Tool used

Manual Review yes

Recommendation

When the caller is not a Validator, remove_validator should not be executed https://github.com/sherlock-audit/2024-05-aleo/blob/main/snarkVM/synthesizer/program/src/resources/credits.aleo#L600-605

evanmarshall commented 1 week ago

This isn't true. A validator can only be in the committee with 10M credits bonded to them. If that amount comes from a delegator and that delegator unbonds, the validator should be removed from the committee and not able to immediately rebond.

If a validator wants to guarantee that no delegator can unbond them, they need 10M credits and to call bond_validator to ensure no delegator can put them below the 10M threshold.