RRC-XX: Rarible ExchangeV2 Account Abstraction Support

Author: Vadim Fadeev - Rarible
Reviewer: Anna Riabokon - Rari Foundation


1. Abstract

This proposal upgrades the Rarible ExchangeV2 order validation logic to fully support Account Abstraction (AA) and smart contract wallets while remaining backward compatible with existing EOAs and signatures.

The new implementation:

  • Uses EIP-712 typed data ("Exchange", "2") for deterministic order hashing.
  • Adds robust EIP-1271 signature verification for contract-based accounts (AA wallets, Safes, etc.).
  • Retains standard ECDSA validation for EOAs.
  • Avoids incorrect assumptions based on EXTCODESIZE: AA wallets are contracts and therefore have non-zero code size, but must still be treated as valid signers when compliant with EIP-1271.

This change is implemented via an upgrade of the ExchangeV2 order validation component and executed on-chain through Tally’s executable proposal mechanism.


2. Motivation

2.1 Account Abstraction Compatibility

Modern users increasingly interact through smart contract wallets / AA accounts (e.g. Safe, AA frameworks, modular wallets). These are deployed as contracts, so EXTCODESIZE (and equivalents) returns non-zero, even when they function as primary user wallets.

Legacy patterns that interpret “contract = invalid user” or require EXTCODESIZE == 0 for signature validity break AA flows.

This upgrade:

  • Explicitly supports contract-based accounts as order makers.
  • Verifies their signatures using EIP-1271 (isValidSignature) instead of rejecting or misclassifying them.
  • Ensures AA users can seamlessly create, sign, and execute orders on Rarible Protocol.

2.2 Security & Correctness

  • Uses structured EIP-712 hashing via EIP712Upgradeable for robust domain separation.
  • Separates EOAs and contracts using standard introspection, but does not rely on EXTCODESIZE == 0 as a trust signal.
  • Prevents false negatives for valid AA wallets and reduces attack surface caused by ad hoc signature handling.

2.3 Ecosystem Alignment

  • Aligns Rarible ExchangeV2 with ecosystem standards around:
    • EIP-1271 for contract wallet signatures.
    • Account abstraction–friendly infra across major wallets and bundlers.
  • Simplifies integrations for partners that already support AA and contract wallets.

3. Rationale

The Rarible Protocol must remain compatible with:

  • EOAs signing EIP-712 orders.
  • Smart contract wallets implementing EIP-1271.
  • Future AA patterns that standardize contract-based authentication.

The proposed model:

  • Uses a single canonical EIP-712 hash (LibOrder.hash + _hashTypedDataV4) as the message to verify.
  • For contracts: calls isValidSignature and expects the magic value 0x1626ba7e.
  • For EOAs: uses ECDSA recovery and strict equality to order.maker.
  • Ensures order.maker != address(0) on all accepted paths.
  • Does not assume that non-zero code size implies invalidity; instead, it implies EIP-1271 verification is required.

This keeps the design simple, auditable, and compatible with both existing users and AA-native flows.


4. Specifications

4.1 Validation Logic (High-Level)

Given order (LibOrder.Order) and signature:

  1. Compute:
    • hash = LibOrder.hash(order)
    • typedHash = _hashTypedDataV4(hash)
  2. If order.salt == 0 and order.maker != address(0):
    • Require msg.sender == order.maker.
    • No off-chain signature check required (gas-efficient path).
  3. Otherwise, if msg.sender != order.maker:
    • If order.maker is a contract:
      • Call IERC1271(order.maker).isValidSignature(typedHash, signature).
      • Require returned value equals 0x1626ba7e (MAGICVALUE).
      • If the call reverts or returns anything else, revert with a clear error.
    • If order.maker is not a contract:
      • Recover signer from typedHash using ECDSA.
      • Require recovered signer equals order.maker.
  4. In all valid flows:
    • Require order.maker != address(0).
  5. Maintain storage gap for upgradeable compatibility.

4.2 Reference Implementation Snippet

// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;

import "./libraries/LibOrder.sol";
import "@rarible/lib-signature/contracts/IERC1271.sol";
import "@rarible/lib-signature/contracts/LibSignature.sol";
import "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/drafts/EIP712Upgradeable.sol";

abstract contract OrderValidator is Initializable, ContextUpgradeable, EIP712Upgradeable {
    using LibSignature for bytes32;
    using AddressUpgradeable for address;

    bytes4 constant internal MAGICVALUE = 0x1626ba7e;

    function __OrderValidator_init_unchained() internal initializer {
        __EIP712_init_unchained("Exchange", "2");
    }

    function validate(LibOrder.Order memory order, bytes memory signature) internal view {
        if (order.salt == 0) {
            if (order.maker != address(0)) {
                require(_msgSender() == order.maker, "maker is not tx sender");
            }
        } else {
            if (_msgSender() != order.maker) {
                bytes32 hash = LibOrder.hash(order);
                bytes32 typedHash = _hashTypedDataV4(hash);

                if (order.maker.isContract()) {
                    bool isValid = false;

                    // AA / smart contract wallet: EIP-1271
                    try IERC1271(order.maker).isValidSignature(typedHash, signature) returns (bytes4 result) {
                        isValid = (result == MAGICVALUE);
                    } catch {
                        isValid = false;
                    }

                    require(isValid, "contract order signature verification error");
                    require(order.maker != address(0), "no maker");
                } else {
                    // EOA: ECDSA
                    address signer = typedHash.recover(signature);
                    require(signer == order.maker, "order signature verification error");
                    require(order.maker != address(0), "no maker");
                }
            }
        }
    }

    uint256[50] private __gap;
}

Note: For AA wallets and smart contract wallets, EXTCODESIZE(order.maker) (or order.maker.code.length) is non-zero, which is expected and supported. These accounts are validated exclusively via EIP-1271, not rejected because they are contracts.


5. Steps to Implement

  1. Specification & Feedback
    • Publish this proposal to the RARI DAO forum for comments from the community, wallet teams, and integrators.
  2. Testing & Audit
    • Extend test suite to cover:
      • EOAs with valid/invalid signatures.
      • EIP-1271-compliant wallets (e.g. Safe).
      • AA flows where maker is a contract with non-zero code size.
    • Optionally commission an external review focused on the new validation path.
  3. On-Chain Proposal
    • Deploy an upgrade contract or use existing upgrade mechanisms.
    • Create a Tally proposal with executable calldata to:
      • Upgrade ExchangeV2 implementation to the new OrderValidator logic.
  4. Governance Process
    • Voting period (~5 days, per DAO rules).
    • Cooldown/veto period (~2 days), if applicable.
  5. Execution
    • Upon approval, execute the upgrade via Tally.
    • New validation logic becomes effective for all new orders.
    • Communicate upgrade details to integrators and ecosystem partners.

6. Summary

This proposal upgrades Rarible ExchangeV2 to be Account Abstraction–ready by:

  • Supporting EIP-1271 signatures for smart contract wallets.
  • Preserving EOA support via ECDSA + EIP-712.
  • Correctly handling the fact that AA wallets are contracts with non-zero EXTCODESIZE, and must be validated via contract-based logic instead of being implicitly disqualified.

The change is minimal in scope, high in impact, and fully aligned with the evolving Ethereum wallet landscape, ensuring Rarible remains a secure, modern, and AA-compatible protocol.

6 Likes

I’m 100% in favor of this proposal.

2 Likes

I’m very positive about this proposal, looks like a valuable upgrade!

1 Like

Great work @forexus! a solid step to keep Rarible technically current and easier to integrate with the broader Ethereum wallet ecosystem, aligning ExchangeV2 with modern standards (EIP-1271 + EIP-712).

2 Likes

RM y’all

100% to move foward with this. It’s essential to evolve alongside the ecosystem, as technologies like Account Abstraction represent the future of wallets and user interaction in Web3. Adapting ensures compatibility, security, and keeps Rarible aligned with the natural evolution of Ethereum and its community.

2 Likes

Thank you @ifelsedeveloper and @Anria or presenting this to the DAO for review. I fully support this needed proposal and look forward to voting on this soon.

2 Likes

Thank you so much for this needed upgrade, I support the intent of this proposal. I also do have a question about the Implementation Steps section, specifically regarding how the DAO ensures a smooth transition for third-party integrators.

Since the on-chain upgrade of ExchangeV2 will involve new contract implementation logic (potentially affecting the verifyingContract domain separator for EIP-712 orders), a sudden change could risk disrupting existing trading functionality for other marketplaces, NFT aggregators, and custom dApps who are built on top of the Rarible protocol using the ExchangeV2 contracts.

Can you elaborate on the specific communication and readiness plan to mitigate this risk? Specifically:

  1. What measures will be put in place to ensure developers and integrators are prepared for the upgrade? And what is the guaranteed minimum lead time (i.e. 7 days) between the technical deployment details (such as the new implementation address and finalized EIP-712 struct data) being posted and the actual execution of the Tally proposal?

  2. How will the technical specifics be documented for developers? Is it possible to create a technical documentation page or blog post, specifically outlining the new verifyingContract address and any minor changes to the order hash generation, to be posted during the voting process of this proposal on Tally, to provide developers an understanding of the changes?

2 Likes

Thanks for sharing this. The upgrade feels needed because more people are using smart contract wallets now, and the old checks sometimes get in their way. Making the system read both regular signatures and contract-based ones without breaking anything for existing users strikes me as a sensible move. It keeps things simple for traders while opening the door for newer wallet setups. I’m in support of this.

3 Likes

I support 100% of this upgrade.

2 Likes

Hi, many thanks for asking
We have tested all orders functionality on base with the new AA support logic
https://etherscan.io/address/0xa669f302574B7E6B1Dd065956Ac1d0A9275d3782#code#F59#L1
Please check etherscan link function name validate.
In the new solidity version fix is simple and we can check AA permissions for the address without try/catch. In the old one it is quite complex, we had to update other chains asap because we detected a lot of orders are failing due to the 7702

2 Likes