# Preventing Re-use of EIP-712 Signatures in NFT Private Sales

In this section, we will explore a vulnerability related to **EIP-712 signatures** in the context of **NFT private sales**. The main issue is that signatures used in private sales can be reused in future transactions, leading to potential exploits where a buyer can re-purchase the same NFT without the seller's knowledge, potentially at a lower price if the value of the NFT has increased.

***

#### Overview of the Vulnerability

The EIP-712 standard allows off-chain message signing in a structured format, providing cryptographic verification when an operation is executed on-chain. In the context of an NFT private sale, a seller signs a message off-chain, which the buyer uses to purchase the NFT via a contract function, such as `buyFromPrivateSaleFor`.

The key issue here arises from the ability to **re-use the same EIP-712 signature** across multiple transactions. If the NFT is sold and then bought back by the original seller, the buyer can reuse the previously signed message to acquire the NFT again. Since the contract does not track the usage of signatures, there is no way to prevent the buyer from executing the same signature and acquiring the NFT without authorization.

***

#### How the Exploit Works

Here’s an example of how this vulnerability can be exploited:

1. **Initial Sale**: Joe, the original owner of an NFT, sells the NFT to Rachel via a private sale using an EIP-712 signature. Rachel completes the purchase using the signed message.
2. **Re-acquisition**: Later, Joe buys back the NFT, regaining ownership.
3. **Re-use of Signature**: Rachel still holds the original signature from the first private sale. Since the contract does not prevent re-use, Rachel can call the `buyFromPrivateSaleFor` function again with the same signature, purchasing the NFT once more, potentially at a lower price.

This issue becomes more problematic if the NFT has risen in value. Rachel could use the original purchase price to acquire the now more valuable NFT.

***

#### Impact of the Vulnerability

* **Unintended Transfers**: The original buyer can exploit the re-used signature to re-purchase the NFT without the seller's consent.
* **Loss of Value**: The seller could lose an NFT that has increased in value without receiving fair compensation, as the buyer can re-purchase it at the original sale price.
* **No Check on Re-use**: The primary issue lies in the fact that the contract does not maintain any state to check whether a signature has been used before.

***

#### Mitigation Strategy: Using Nonces to Prevent Reuse

One of the most effective ways to prevent the reuse of signatures is to introduce **nonces**. A nonce is a unique value tied to a specific transaction or user, and by including it in the EIP-712 signature, you can ensure that the signature is used only once. Once a signature is processed, the nonce is incremented or marked as used, preventing future use of the same signature.

Here’s how to mitigate this vulnerability by incorporating nonces:

1.  **Add Nonce Tracking**: Implement a mapping in your contract to track the nonce for each user. This ensures that every new transaction requires a new signature with an updated nonce.

    ```solidity
    solidityCopy codemapping(address => uint256) public nonces;
    ```
2.  **Include Nonce in EIP-712 Signature**: When generating the EIP-712 signature, include the user's current nonce as part of the signed message.

    ```solidity
    bytes32 structHash = keccak256(abi.encode(
        keccak256("PrivateSale(address buyer,uint256 tokenId,uint256 price,uint256 nonce)"),
        buyer,
        tokenId,
        price,
        nonces[seller]
    ));
    ```
3.  **Validate and Increment Nonce**: In the `buyFromPrivateSaleFor` function, check that the nonce is correct, and after the signature is used, increment the nonce to prevent re-use.

    ```solidity
    function buyFromPrivateSaleFor(
        address seller,
        uint256 tokenId,
        uint256 price,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) public payable {
        // Check the nonce and validate the signature
        bytes32 structHash = keccak256(abi.encode(
            keccak256("PrivateSale(address buyer,uint256 tokenId,uint256 price,uint256 nonce)"),
            msg.sender,
            tokenId,
            price,
            nonces[seller]
        ));
        
        // Verify the signature
        bytes32 digest = keccak256(abi.encodePacked(
            "\x19\x01",
            domainSeparator,
            structHash
        ));
        address recoveredAddress = ecrecover(digest, v, r, s);
        require(recoveredAddress == seller, "Invalid signature");

        // Process the sale
        // Transfer the NFT and funds

        // Increment the nonce
        nonces[seller]++;
    }
    ```

***

#### Benefits of Using Nonces

* **Prevents Signature Reuse**: Once a nonce is used, it cannot be reused, ensuring that signatures are one-time use only.
* **Protects Sellers**: Even if the buyer retains a valid signature, they cannot use it again after the sale is completed.
* **Enhances Security**: Nonces are a standard approach for securing off-chain signatures and ensuring transaction uniqueness.

***

#### Conclusion

In NFT private sales, it's crucial to prevent the re-use of EIP-712 signatures to avoid malicious actions where a buyer can re-purchase an NFT after the seller regains ownership. By introducing **nonces** into the signing process, you can effectively ensure that each transaction is unique and prevent the reuse of signatures. This approach not only secures the contract but also protects the integrity of private sales in the marketplace.
