29342 - [SC - Insight] Lack of chainID validation allows reuse of sign...

Submitted on Mar 14th 2024 at 13:22:04 UTC by @azhar0406 for Boost | ZeroLend

Report ID: #29342

Report type: Smart Contract

Report severity: Insight

Target: https://explorer.zksync.io/address/0xe8178fF950Ea1B69a51cE961C542a4CC6Cb6e38E

Impacts:

  • Direct theft of any user funds, whether at-rest or in-motion, other than unclaimed yield

Description

Brief/Intro

The AToken.sol contract implements features aligned with EIP-2612, which extends the ERC-20 standard to include a permit function but fails to incorporate chainId in its permit validation, critical for differentiating network forks. This flaw enables permit reuse across chains (replay attacks) and forks, potentially leading to unauthorized fund access, especially if the contract is deployed at identical addresses on different networks. This elevates the risk of cross-chain exploits, undermining token security and user asset integrity.

Vulnerability Details

https://explorer.zksync.io/address/0xe8178fF950Ea1B69a51cE961C542a4CC6Cb6e38E#contract [AToken.sol] [line number 170]

bytes32 public constant PERMIT_TYPEHASH =
    keccak256('Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)');
...
  function permit(
    address owner,
    address spender,
    uint256 value,
    uint256 deadline,
    uint8 v,
    bytes32 r,
    bytes32 s
  ) external override {
    require(owner != address(0), Errors.ZERO_ADDRESS_NOT_VALID);
    //solium-disable-next-line
    require(block.timestamp <= deadline, Errors.INVALID_EXPIRATION);
    uint256 currentValidNonce = _nonces[owner];
    bytes32 digest = keccak256(
      abi.encodePacked(
        '\x19\x01',
        DOMAIN_SEPARATOR(),
        keccak256(abi.encode(PERMIT_TYPEHASH, owner, spender, value, currentValidNonce, deadline))
      )
    );
    require(owner == ecrecover(digest, v, r, s), Errors.INVALID_SIGNATURE);
    _nonces[owner] = currentValidNonce + 1;
    _approve(owner, spender, value);
  }

Atoken contract uses permit function to allows a third party to transmit a signature from a token holder that modifies the ERC20 allowance for a particular user. but in the PERMIT_TYPEHASH nor the permit function fails to incorporate chainId in its permit validation. Therefore it can lead to a signature replay attack if the same contract deployed in different chain with the same contract address or the current chain is forked. Because this permit function can not differentiate chains.

as per the official [EIP-2612] https://eips.ethereum.org/EIPS/eip-2612 implementation also chainId is a must. Check Attached Image

Impact Details

The absence of chainId validation can lead to direct theft of user funds across different blockchain forks, as the same approval could be exploited by malicious actors on parallel networks. Given the contract is deployed on the zkSync chain, users could lose assets if these signatures are replayed on forked versions of the chain, leading to critical financial implications.

Attack Vector 1

Bob has AToken in his wallet on the zkSync network. He permits Alice to spend tokens using the permit function. Because the contract doesn't validate chainId, Alice replays this permit on the Ethereum network, where AToken with the same contract address exists, draining Bob's funds on Ethereum.

Attack Vector 2

Bob again uses the permit feature for AToken on zkSync. Unaware, the same permit is exploited by Alice on a forked zkSync chain, leading to loss of Bob's tokens on both networks.

Attack Vector 3

Bob has a wallet holding AToken. Following a contentious EIP, the community splits post-hard fork, leaving a significant user base on the original chain. On the new chain, Bob issues a permit allowing Alice to spend tokens. Alice, exploiting the absence of chainId checks, replays this permit on the old chain, thus illicitly accessing and transferring Bob’s AToken.

References

https://solodit.xyz/issues/lack-of-chainid-trailofbits-yield-protocol-pdf [Vulnerability Detail - Lack of ChainID Validation]

Proof of Concept

SigUtils.sol

Last updated

Was this helpful?