sherlock-2025-06-symbiotic-relay-m06
[M-06] BlsBn254 is not available in certain chains due to hardcoded gas limit
Summary
체인별로 precompile의 가스 비용은 서로 다르게 설정될 수 있다. precompile을 호출할 때 하드코딩된 gas limit을 사용하므로 특정 체인에서 EcParing precompile이 항상 실패한다. 따라서 일부 체인에서 BlsBn254를 사용할 수 없다.
Keyword
precompile, gas limit, zksync, erc1108, cross chain
Vulnerability
SigBlsBn254.verify 에서는 BN254.safePairing를 호출할 때 하드코딩된 PAIRING_CHECK_GAS_LIMIT(120_000)를 이용한다. 이는 Ethereum의 EIP-1108에서 결정된 34000 * k + 45000 를 기준으로, k=2일때 필요한 EcParing 가스 비용을 계산한 것이다.
@> uint256 internal constant PAIRING_CHECK_GAS_LIMIT = 120_000;
function verify(
bytes memory keyBytes,
bytes memory message,
bytes memory signature,
bytes memory extraData
) internal view returns (bool) {
...
(bool success, bool result) = BN254.safePairing(
signatureG1.plus(keyG1.scalar_mul(alpha)),
BN254.negGeneratorG2(),
messageG1.plus(BN254.generatorG1().scalar_mul(alpha)),
keyG2,
@> PAIRING_CHECK_GAS_LIMIT
);
return success && result;
}
////////////////////////////
// BN254.safePairing
function safePairing(
G1Point memory a1,
G2Point memory a2,
G1Point memory b1,
G2Point memory b2,
@> uint256 pairingGas
) internal view returns (bool, bool) {
...
assembly {
@> success := staticcall(pairingGas, 8, input, mul(12, 0x20), out, 0x20)
}
...
}precompile 의 가스 비용은 변경되거나 체인별로 다를 수 있다. 예를 들어 ZKSync(배포되는 체인에 포함됨)는 May, 2025에 ZIP-11. V28 Precompile Upgrade 업그레이드에서 EcAdd, EcMul, EcPairing precompile을 업데이트하고 가스 비용을 변경하였다.
위 하드코드는 ZKSync에서 문제를 일으킨다. 다음은 ZKSync V28에서 업데이트된 EcPairing 코드이다. 가스 비용은 80000 * k 로 계산된다. k=2일 때 필요한 가스 비용은 160_000 으로 PAIRING_CHECK_GAS_LIMIT 보다 높다. 가스가 부족하면 EcParing 은 항상 실패하므로 ZKSync에서 BlsBn254 서명 확인은 항상 실패하게 된다.
function ECPAIRING_BASE_GAS_COST() -> ret {
ret := 0
}
function ECPAIRING_PAIR_GAS_COST() -> ret {
@> ret := 80000
}
function ecpairingGasCost(pairs) -> ret{
@> let gasPerPairs := mul(ECPAIRING_PAIR_GAS_COST(), pairs)
ret := add(ECPAIRING_BASE_GAS_COST(), gasPerPairs)
}Impact
일부 체인에서 BlsBn254 를 이용할 수 없음
Mitigation
Precompile을 호출하는 데 필요한 가스 비용은 미래에 얼마든지 변경될 수 있으며 체인마다 다를 수 있다. 따라서 PAIRING_CHECK_GAS_LIMIT 로 하드코딩하는 대신 관리자가 설정 가능한 변수를 이용해야 한다.
Memo
(오딧 당시) ZIP-11. V28 Precompile Upgrade 는 ZKSync 메인넷에만 확인할 수 있다(테스트넷에는 적용되지 않은 것 같다). 또한 foundry fork 테스트로도 재현할 수 없었다. (foundry-zksync를 이용해야 함)
tags: bughunting, symbiotic, smart contract, solidity, cross chain, restaking, severity medium, precompile, gas limit, gas, zksync, erc1108