sherlock-audit / 2024-06-allora-judging

0 stars 0 forks source link

imsrybr0 - Attacker can slow down / halt the chain by queuing multiple stake removals or delegate stake removals #56

Open sherlock-admin4 opened 2 months ago

sherlock-admin4 commented 2 months ago

imsrybr0

High

Attacker can slow down / halt the chain by queuing multiple stake removals or delegate stake removals

Summary

Attacker can slow down / halt the chain by queuing multiple stake removals or delegate stake removals.

Vulnerability Detail

All stake removals and delegate stake removals for a given block are processed in the EndBlocker in a loop.

Since there is no minimum restriction on the stake amount, an attacker can either :

Impact

Slow down / halt the chain.

Code Snippet

EndBlocker

func EndBlocker(ctx context.Context, am AppModule) error {
    sdkCtx := sdk.UnwrapSDKContext(ctx)
    blockHeight := sdkCtx.BlockHeight()
    sdkCtx.Logger().Debug(
        fmt.Sprintf("\n ---------------- Emissions EndBlock %d ------------------- \n",
            blockHeight))

    // Remove Stakers that have been wanting to unstake this block. They no longer get paid rewards
    RemoveStakes(sdkCtx, blockHeight, am.keeper) // <===== Audit
    RemoveDelegateStakes(sdkCtx, blockHeight, am.keeper) // <===== Audit

    // ...
}

RemoveStakes

func RemoveStakes(
    sdkCtx sdk.Context,
    currentBlock int64,
    k emissionskeeper.Keeper,
) {
    removals, err := k.GetStakeRemovalsForBlock(sdkCtx, currentBlock)  // <===== Audit
    if err != nil {
        sdkCtx.Logger().Error(fmt.Sprintf(
            "Unable to get stake removals for block %d, skipping removing stakes: %v",
            currentBlock,
            err,
        ))
        return
    }
    for _, stakeRemoval := range removals {  // <===== Audit
        // ...
    }
}

RemoveDelegateStakes

func RemoveDelegateStakes(
    sdkCtx sdk.Context,
    currentBlock int64,
    k emissionskeeper.Keeper,
) {
    removals, err := k.GetDelegateStakeRemovalsForBlock(sdkCtx, currentBlock)  // <===== Audit
    if err != nil {
        sdkCtx.Logger().Error(
            fmt.Sprintf(
                "Unable to get stake removals for block %d, skipping removing stakes: %v",
                currentBlock,
                err,
            ))
        return
    }
    for _, stakeRemoval := range removals {  // <===== Audit
        // ...
    }
}

Tool used

Manual Review

Recommendation

Process stake removals and delegate stake removals that reached maturity in batches with a predefined size over multiple blocks.

sherlock-admin2 commented 1 month ago

The protocol team fixed this issue in the following PRs/commits: https://github.com/allora-network/allora-chain/pull/469