memoscan
← all memos

Memo 0x72d330ac…3e00c2 on Ethereum

# RRC-54: 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 ```solidity // 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.