Skip to content

Latest commit

 

History

History
91 lines (59 loc) · 3.11 KB

File metadata and controls

91 lines (59 loc) · 3.11 KB

Melted Carrot Swan

Medium

VVVVCTokenDistributor is not fully compatible with EIP-712 due to incorrect array encoding

Summary

Let’s note that CLAIM_TYPEHASH uses two arrays address[] projectTokenProxyWallets, uint256[] tokenAmountsToClaim.

When validating a signature, these values are encoded as follows.

bytes32 digest = keccak256(
            abi.encodePacked(
                "\x19\x01",
                DOMAIN_SEPARATOR,
                keccak256(
                    abi.encode(
                        CLAIM_TYPEHASH,
                        _params.kycAddress,
                        _params.projectTokenAddress,
                        _params.projectTokenProxyWallets, //@audit this
                        _params.tokenAmountsToClaim, //@audit this
                        _params.nonce,
                        _params.deadline
                    )
                )
            )
        );

Now let's look at the EIP-712 specification and how it specifies to handle arrays.

The array values are encoded as the keccak256 hash of the concatenated encodeData of their contents (i.e. the encoding of SomeType[5] is identical to that of a struct containing five members of type SomeType).

It can be seen that the protocol incorrectly handles signature validation arrays, and therefore does not conform to the EIP-712 standard, which will cause signatures generated using libraries that conform to the standard to be invalid.

Root Cause

The code does not handle arrya correctly when creating a digest. It simply inserts arrays into abi.encode as if they were atomic types, but this is incorrect. Let's look at how EIP-712 spec requires non atomic type to be handled.

Link to this part of EIP-712 - Definition of encodeData

1)Dynamic Values

The dynamic values bytes and string are encoded as a keccak256 hash of their contents.

  1. Array Values

The array values are encoded as the keccak256 hash of the concatenated encodeData of their contents

Internal pre-conditions

External pre-conditions

Attack Path

There is no specific attack path, any library that creates signatures according to the EIP-712 specification will not pass validation in the contract due to incorrect validation.

Impact

2 impacts

  1. due to wrong type hash computation leading to wrong digest validation in the signature validator, the signatures might fail.
  2. breaking the EIP712 mentioned in readme where it strictly complains. The array types should not be used as atomic types

PoC

No response

Mitigation

Hash both of the arrays like this

function hashArray(uint256[] memory array) internal returns (bytes32) {
        bytes32[] memory hashedElements;

        for (uint256 i = 0; i < array.length; i++) {
            hashedElements[i] = keccak256(abi.encodePacked(array[i]));
        }

        return keccak256(abi.encodePacked(hashedElements));
    }