Era

ZKsync
FoundryLayer 2
500,000 USDC
View results
Submission Details
Severity: low
Valid

Signers cannot manually invalidate already issued signatures in various contracts

Summary

Once a signature is issued, the signer has no means to manually invalidate it, other than executing a transaction associated with a signature (which will increment the nonce through the _useNonce function). This can lead to issues in cases where the signature holder is compromised, the signer has made a mistake, or they simply wish to invalidate an existing signature, as there are no means available for the signer to revoke the signature.

Vulnerability Details

The permit signatures in ZkTokenV1.sol and ZkTokenV2.sol offers the signer the option to create a EIP-712 signature which can be used for vote delegation. This handles the signature nonce through the _useNonce function

function initialize(address _admin, address _mintReceiver, uint256 _mintAmount) external initializer {
__ERC20_init("ZKsync", "ZK");
> __ERC20Permit_init("ZKsync");

The same can be observed in L2WrappedBaseToken which offers a permit functionality, which also relies on openzeppelin's ERC20PermitUpgradeable.sol and subsequently, the _useNonce

function initializeV3(
string calldata name_,
string calldata symbol_,
address _l2Bridge,
address _l1Address,
bytes32 _baseTokenAssetId
) external reinitializer(3) {
if (_l2Bridge == address(0)) {
revert ZeroAddress();
}
if (_l1Address == address(0)) {
revert ZeroAddress();
}
if (_baseTokenAssetId == bytes32(0)) {
revert ZeroAddress();
}
l2Bridge = _l2Bridge;
l1Address = _l1Address;
nativeTokenVault = L2_NATIVE_TOKEN_VAULT_ADDR;
baseTokenAssetId = _baseTokenAssetId;
// Set decoded values for name and symbol.
__ERC20_init_unchained(name_, symbol_);
// Set the name for EIP-712 signature.
> __ERC20Permit_init(name_);
emit Initialize(name_, symbol_, 18);
}

The contracts however offer no method that allows the owner to invalidate its nonce since the _useNonce function is internal and cannot be directly accessed.

Similar finding from Cyfrin team.

Impact

As a result, signatures cannot be cancelled before their expiry, even if its needed to be.

Tools Used

Manual Review.

Recommendations

Introduce an external function like IncreaseNonce that will query _useNonce on behalf of msg.sender. A similar mechanism can be found in ZkMerkleDistributor.sol - https://github.com/Cyfrin/2024-10-zksync/blob/cfc1251de29379a9548eeff1eea3c78267288356/zk-governance/l2-contracts/src/ZkMerkleDistributor.sol#L277

Updates

Lead Judging Commences

inallhonesty Lead Judge 5 months ago
Submission Judgement Published
Validated
Assigned finding tags:

Signers cannot manually invalidate already issued signatures in various contracts

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.