- JustanAccountFactory:
0x1578f4A87243bA8413ee8F5acf2af29635ED09EC - JustanAccount:
0x2F107ca67d8D32eD8decEB5189b12093ce3E602F
Deployed on:
- Ethereum Mainnet + Sepolia
- Base Mainnet + Sepolia
- Optimism Mainnet + Sepolia
- Arbitrum One + Sepolia
The JustanAccount is a Solidity smart contract designed to enhance Ethereum account functionalities by integrating support for EIP-7702 and EIP-4337. These integrations enable features such as transaction batching, gas fee sponsorship, cross-chain owner synchronization, and advanced signature validation.
- Multi-Owner Support: Allows multiple owners to control the account, with flexible owner management including addition and removal of owners. This essentially allows the account to be used with advanced functionalities such as the JustaPermissionManager.sol.
- Flexible Owner Types: Supports both Ethereum addresses (20 bytes) and WebAuthn public keys (64 bytes), with architecture designed for future owner type expansion.
- WebAuthn Signature Support: Full support for WebAuthn authentication. Owners can be registered as 64-byte public key coordinates (x, y) and authenticate using modern web authentication standards.
- ECDSA Signature Validation: Traditional Ethereum signature support for both 64-byte and 65-byte ECDSA signatures.
- Transaction Batching: Allows the execution of multiple transactions in a single call, reducing overhead and improving efficiency.
- Cross-Chain Owner Synchronization: Enables replaying owner management operations across multiple chains with a single signature, ensuring consistent account configuration across all supported networks.
- Gas Sponsorship: Supports mechanisms for third parties to sponsor gas fees, enabling users to interact with the Ethereum network without holding ETH.
- EIP-7702 Delegation: Can be used as a delegated implementation for existing EOA wallets, enhancing them with smart contract capabilities.
- EIP-4337 Account Abstraction: Full compliance with account abstraction standards including UserOperation validation and EntryPoint integration.
- ERC-7739 Compliant Signature Validation: Implements advanced signature validation with ERC-7739 nested EIP-712 support, preventing signature replay attacks across accounts while maintaining readable typed data for wallet UIs.
- Signature Validation: Implements the
isValidSignaturefunction in compliance with EIP-1271 and ERC-7739, facilitating contract-based signature verification with replay protection. - Token Support: Built-in support for receiving ERC-721 and ERC-1155 tokens.
- Namespaced Storage: Uses ERC-7201 standard for collision-resistant storage layout, ensuring safe delegation usage.
The contract system consists of three main components:
The primary account contract that inherits from:
- BaseAccount (ERC-4337 compliance)
- Receiver (Solady's receive functionality)
- MultiOwnable (Multi-owner management)
- ERC1271 (Solady's ERC-1271 with ERC-7739 support)
- IERC165 (Interface support)
initializeFunction: Initializes the account with a set of initial owners. Can only be called once during account creation.validateUserOpFunction: Validates UserOperations for EIP-4337 compliance, with automatic detection of cross-chain operations based on function selector and nonce key.executeFunction: Executes a single transaction to a target address with specified value and data. Ensures that the caller is authorized (either the eoa through 7702, an account owner or the designated entry point).executeBatchFunction: Executes multiple transactions in a single call. If any transaction fails, the function reverts, indicating the index of the failed transaction.executeWithoutChainIdValidationFunction: Executes cross-chain replayable operations by calling whitelisted owner management functions. Requires REPLAYABLE_NONCE_KEY (9999) and validates each call against the approved selector list.getUserOpHashWithoutChainIdFunction: Computes the UserOperation hash similar to EntryPoint v0.8, but sets chain ID to 0, enabling signature replay across different chains.canSkipChainIdValidationFunction: Returns whether a given function selector is whitelisted for cross-chain execution (owner management functions only).entryPointFunction: Returns the entry point contract associated with this account, as required by EIP-4337.isValidSignatureFunction: Validates signatures according to EIP-1271 and ERC-7739, supporting both ECDSA and WebAuthn signature schemes with nested EIP-712 replay protection.supportsInterfaceFunction: Indicates support for various interfaces, including ERC165, IAccount, IERC1271, IERC1155Receiver, and IERC721Receiver._validateSignatureFunction: Internal EIP-4337 signature validation for UserOperations._erc1271IsValidSignatureNowCalldataFunction: Core signature validation logic supporting multiple signature types, handling both wrapped signatures (multi-owner) and unwrapped signatures (EIP-7702)._checkWebAuthnSignatureFunction: Validates WebAuthn signatures for a specific owner index._verifyWebAuthnSignatureFunction: Verifies individual WebAuthn signatures using Solady's WebAuthn library.
The contract supports multiple signature schemes:
-
ECDSA Signatures (64 or 65 bytes):
- Standard Ethereum signatures
- Validates against registered address owners
- Validates against the account address itself (for EIP-7702 delegation)
-
WebAuthn Signatures:
- Modern web authentication standard
- Supports Touch ID, Face ID, and hardware security keys
- Uses P-256 elliptic curve cryptography
- Validates against registered 64-byte public key coordinates
The contract implements ERC-7739 (Readable Typed Signatures for Smart Accounts) through Solady's ERC1271 base contract, providing:
-
Nested EIP-712 Support:
- Prevents signature replay attacks across different smart accounts
- Maintains readable typed data for wallet UIs
- Supports both TypedDataSign and PersonalSign workflows
-
Automatic Detection:
- Returns magic value
0x77390001when called with hash0x7739...7739 - Enables wallets to detect ERC-7739 support automatically
- Returns magic value
-
Security Features:
- Domain separator includes contract address and chain ID
- Defensive rehashing prevents cross-account signature reuse
- Compatible with existing EIP-712 wallet infrastructure
-
Workflow Support:
- TypedDataSign: For typed structured data with full EIP-712 compatibility
- PersonalSign: For personal messages with Ethereum signed message prefix
- RPC Validation: Special handling for off-chain signature validation
A separate contract that provides multi-owner functionality with:
- ERC-7201 Namespaced Storage: Prevents storage collisions using the storage slot 0x548403af3b7bfc881040446090ff025838396ebf051dc219a19859cf4ef8e800
- Flexible Owner Types: Stores owners as bytes to support both Ethereum addresses and WebAuthn public keys
- Index-based Management: Efficient owner tracking and removal using indices
addOwnerAddress(address owner): Adds a new Ethereum address as an owneraddOwnerPublicKey(bytes32 x, bytes32 y): Adds a new WebAuthn public key as an ownerremoveOwnerAtIndex(uint256 index, bytes calldata owner): Removes an owner at a specific index (requires multiple owners)removeLastOwner(uint256 index, bytes calldata owner): Removes the final owner (special case)isOwnerAddress(address account): Checks if an address is a registered ownerisOwnerPublicKey(bytes32 x, bytes32 y): Checks if a WebAuthn public key is a registered ownerisOwnerBytes(bytes memory account): Checks if bytes data represents a registered ownerownerAtIndex(uint256 index): Returns the owner data at a specific indexownerCount(): Returns the current number of active ownersnextOwnerIndex(): Returns the next index to be used for owner additionremovedOwnersCount(): Returns the number of owners that have been removed
A factory contract for deploying JustanAccount instances with deterministic addresses across chains:
- CREATE2 Deployment: Uses Solady's LibClone for deterministic ERC-1967 proxy deployment
- Cross-Chain Consistency: Same owners and nonce produce identical addresses on all chains
- Efficient Clones: Deploys minimal ERC-1967 proxies pointing to a single implementation contract
createAccount(bytes[] calldata owners, uint256 nonce): Deploys or returns an existing account at a deterministic address. If the account already exists, skips initialization and returns the existing instance.getAddress(bytes[] calldata owners, uint256 nonce): Computes the deterministic address where an account would be deployed for given owners and nonce, without deploying it.initCodeHash(): Returns the initialization code hash of the ERC-1967 proxy used for CREATE2 address computation.getImplementation(): Returns the JustanAccount implementation address used for all deployed proxies.
The factory uses keccak256(abi.encode(owners, nonce)) as the CREATE2 salt, ensuring:
- Identical addresses across all EVM chains for the same owners and nonce
- Multiple accounts possible for the same set of owners (by varying nonce)
- Predictable addresses before deployment for cross-chain setup
The contract implements a hierarchical authorization system:
-
Primary Authorization:
- EOA owner through EIP-7702 delegation (
msg.sender == address(this)) - EIP-4337 EntryPoint for UserOperations
- EOA owner through EIP-7702 delegation (
-
Secondary Authorization:
- Registered Ethereum address owners
- Registered WebAuthn public key owners
-
Signature Validation Priority:
- First attempts ECDSA signature validation (64/65 byte signatures)
- Falls back to WebAuthn signature validation for other signature formats
- Validates against all registered owners of the appropriate type
The contract uses ERC-7201 namespaced storage to prevent collisions:
// Storage slot: keccak256(abi.encode(uint256(keccak256("justanaccount.storage.MultiOwnable")) - 1)) & ~bytes32(uint256(0xff))
bytes32 private constant MULTI_OWNABLE_STORAGE_LOCATION = 0x548403af3b7bfc881040446090ff025838396ebf051dc219a19859cf4ef8e800;struct MultiOwnableStorage {
uint256 s_nextOwnerIndex; // Index for next owner addition
uint256 s_removedOwnersCount; // Track removed owners count
mapping(uint256 => bytes) s_ownerAtIndex; // Index to owner bytes mapping
mapping(bytes => bool) s_isOwner; // Owner existence mapping
}This implementation was influenced by and builds upon:
- Coinbase Smart Wallet: The multi-owner architecture and cross-chain design patterns were inspired by Coinbase's smart wallet implementation.
- Solady: Core cryptographic and utility libraries including WebAuthn verification, ECDSA signature handling, ERC-1271 with ERC-7739 support, and efficient cloning patterns.
- ERC-4337 Reference Implementation: Account abstraction standards and EntryPoint integration patterns.