Low gas costs of precompiles lead to denial of service
Description
The Bn128Add
, Bn128Mul
, and Bn128Pairing
precompiles compute point addition, scalar multiplication, and pairing for the alt_bn128
elliptic curve, as specified in EIP-196↗ and EIP-197↗. They have significantly lower gas costs than specified either directly in those EIPs or in the subsequent EIP-1108↗ that reduces them.
The Blake2F
precompile, which computes a specified number of rounds of the Blake2
compression function, as specified in EIP-152↗, has a constant gas cost due to the constant-sized input description, when it should have a gas cost proportional to the number of rounds.
Impact
Having a low gas cost for precompiles that perform time-consuming computation allows smart contracts to perform a denial-of-service attack on nodes.
Recommendations
Increase the gas costs of the BN128 precompiles to match those specified in EIP-1108↗. The cost of Bn128Pairing
cannot be made to exactly match with LinearCostPrecompile
due to LinearCostPrecompile
declaring a cost of , while the specified gas cost is , where is the number of input bytes; however, it can be closely approximated.
impl LinearCostPrecompile for Bn128Add {
- const BASE: u64 = 15;
- const WORD: u64 = 3;
+ const BASE: u64 = 150;
+ const WORD: u64 = 0;
impl LinearCostPrecompile for Bn128Mul {
- const BASE: u64 = 15;
- const WORD: u64 = 3;
+ const BASE: u64 = 6000;
+ const WORD: u64 = 0;
impl LinearCostPrecompile for Bn128Pairing {
- const BASE: u64 = 15;
- const WORD: u64 = 3;
+ const BASE: u64 = 45000;
+ const WORD: u64 = 34000/(192/32);
The Blake2F
precompile's gas cost cannot be approximated with LinearCostPrecompile
due to having an input-dependent gas cost.
The gas costs of the Curve25519Add
and Curve25519ScalarMul
precompiles should likely be increased to match the costs of Bn128Add
and Bn128Mul
, respectively.
The gas cost of Ed25519Verify
should be increased to 2,000 to conform to EIP-665↗.
Remediation
This issue has been acknowledged by Sigma Assets GmbH, and fixes were implemented in the following commits: