Assessment reports>Omni Network>Discussion>The block.prevdao is completely biasable by the proposer

The block.prevdao is completely biasable by the proposer

As seen in the excerpt below, the block randao is the hash of all the transactions in the last block. While on-chain dApps should not rely on block.prevrandao, if any on-chain dApp does rely on block.prevrandao, an opportunistic proposer could brute-force a favorable randao value to extract value out of on-chain dApps that use it as source of randomness.

// startBuild triggers the building of a new execution payload on top of the current execution head.
// It returns the EngineAPI response which contains a status and payload ID.
func (k *Keeper) startBuild(ctx context.Context, appHash common.Hash, timestamp time.Time) (engine.ForkChoiceResponse, error) {
    ...
	attrs := &engine.PayloadAttributes{
		Timestamp:             ts,
		Random:                head.Hash(), // We use head block hash as randao.
		SuggestedFeeRecipient: k.feeRecProvider.LocalFeeRecipient(),
		Withdrawals:           []*etypes.Withdrawal{}, // Withdrawals not supported yet.
		BeaconRoot:            &appHash,
	}
    ...
	return resp, nil
}
Zellic © 2025Back to top ↑