Skip to content

UserProxyFactoryV4 deploys one UserProxyV4 clone for each user. It uses OpenZeppelin’s EIP-1167 minimal-clone pattern and CREATE2, so a client can compute a user’s proxy address before the proxy exists.

The factory is ownerless. Its implementation is immutable and created in the constructor. The factory stores only the proxyOf mapping; it has no administrator, pause switch, or upgrade path.

Call predictProxy(user) with the user’s address. The factory derives the deterministic salt as:

keccak256(abi.encode("AgentSwap.UserProxy.v4", user))

The result is the address produced by the factory’s deterministic clone deployment for that user. It can be pinned in client state or approvals before a deployment transaction is sent.

The prediction is tied to the canonical factory, its immutable implementation, and the user address. A client should derive the address from the factory rather than accept an arbitrary proxy address.

Call deploy(user) from any account. The factory:

  1. Rejects user == address(0) with ZeroAddress.
  2. Reads proxyOf[user].
  3. If an address is already stored, returns it without deploying another clone.
  4. Otherwise deploys the deterministic clone, calls init(user), stores the result, emits ProxyDeployed, and returns the proxy address.

The caller does not become the owner. init(user) sets the proxy owner to user, and the factory calls it during deployment. The proxy rejects a second initialization with AlreadyInitialized.

deploy(user) is idempotent after the first successful deployment. Repeated calls for the same user return the address in proxyOf[user] and do not deploy or initialize a second proxy. The address returned by predictProxy(user) is therefore the address clients should expect from deploy(user) for the canonical factory.

Function Purpose
predictProxy(address user) Return the deterministic proxy address without deploying.
deploy(address user) Deploy and initialize the user’s clone, or return the stored address.
implementation() Return the immutable UserProxyV4 implementation address.
proxyOf(address user) Read the stored proxy address for a user.

The proxy’s init(address) entry point is called as part of deployment. It is not a second factory deployment mechanism.

Successful first deployment emits:

ProxyDeployed(address indexed user, address indexed proxy)

There is no factory owner to transfer, renounce, or use to change routing policy. Agent policy is stored in each proxy and is controlled by that proxy’s owner. See agent delegation.

The verified User Proxy deployment is documented for Base 8453, Arbitrum One 42161, and Robinhood Chain 4663. It is not a deployment on BNB Smart Chain 56. That chain distinction is specific to the User Proxy; the Intents address table is a separate reference and must not be copied here.

See proxy addresses and ABI for the deployment addresses and selectors.

A client can call predictProxy(user) first, use that address for the user’s proxy setup, and call deploy(user) when the clone should exist. It can then read proxyOf(user) to confirm the factory’s stored mapping. The factory does not require the caller to be the user.