confirmingPublicKeyHash derived from wrong public key causes all key pair registrations to revert after inception
validateTransaction computes confirmingPublicKeyHash from unconfirmed.publicKey instead of confirming.publicKey, so the subsequent equality check is always false and every key pair registration reverts after the inception key.
Description
NOTE: this bug is fixed in
KeyLogRegistryUpgrade.sol, andKeyLogRegistry.solshould not be used in production!
In KeyLogRegistry.sol, validateTransaction computes the confirming
key's hash from the wrong public key:
// KeyLogRegistry.sol line 183-184address unconfirmedPublicKeyHash =getAddressFromPublicKey(unconfirmed.publicKey);address confirmingPublicKeyHash =getAddressFromPublicKey(unconfirmed.publicKey); // BUG: should be confirming.publicKey
Both hashes are derived from unconfirmed.publicKey. The subsequent check
at line 217:
require(getAddressFromPublicKey(confirming.publicKey) == confirmingPublicKeyHash, "Invalid confirmingPublicKey");
requires hash(confirming.publicKey) == hash(unconfirmed.publicKey), which
is always false for valid key pairs.
Vulnerable Scenario
- Deploy
KeyLogRegistrybehind a UUPS proxy. - Register key A via
registerKeyLog(inception), succeeds becauseisPair=falsereturns at line 214 before the buggy check at line 217 is reached. - Attempt key rotation by calling
registerKeyLogPair(keyB, keyC)where:- Key B is the next rotation key (
prevPublicKeyHash = hash(A)) - Key C is the confirming key (
prevPublicKeyHash = hash(B))
- Key B is the next rotation key (
validateTransactioncomputes:unconfirmedPublicKeyHash = hash(B)(line 183, correct)confirmingPublicKeyHash = hash(B)(line 184, BUG, should behash(C))
- Line 217 evaluates:
require(hash(C) == hash(B)), always false, reverts with"Invalid confirmingPublicKey". - Key chain is permanently stuck at inception. No rotation, wrap, or unwrap is possible.
Impact
- All
registerKeyLogPaircalls revert with"Invalid confirmingPublicKey". - No key rotation pairs can be registered, key chains are permanently stuck after inception.
- All wrap/unwrap operations that require pair registration are blocked.
- Bridge is non-functional for any operation requiring key pair rotation.
Recommendation
Fixed in KeyLogRegistryUpgrade.sol line 184:
address confirmingPublicKeyHash =getAddressFromPublicKey(confirming.publicKey); // FIXED
Resolution
YadaCoin, Confirmed.
Zealynx, Fixed.

