Skip to main content

Universal Profile

The UniversalProfile.sol smart contract is a combination of two LSP standards:

The LSP3 Profile Metadata enables to give a "face" to the smart contract based account, making it distinguishable and unique from others Universal Profiles.

A UniversalProfile as a smart contract can be used as a blockchain-based account by humans, machines, organizations, or even other smart contracts.

Functionalities & Behaviour

A UniversalProfile has all the basic functionalities of an Externally Owned Account (EOA), as well as the following functions that give the contract additional features:

All ownable functions such as execute(..), executeBatch(..), setData(..), setDataBatch(..), transferOwnership(..), and renounceOwnership(..) can be called by the owner

The contract also includes the LSP20-CallVerification at its core. Meaning if the contract is owned by another contract, LSP20 enables to interact with the contract directly without having to resolve through its owner first. This allows seamless integrations with other contracts, protocols and dApps, as the contract can be called directly, making the developer experience easier.

To illustrate, if another address than the owner calls the execute(..) function, the account contract will:

  1. Forward the call to the owner.
  2. The execution of the function will only continue if the owner returns the LSP20 MAGIC VALUE, indicating that the caller is allowed to execute the function.

The magic value can also determine if there should be any post-execution check on the owner. This same behavior applies to other ownable functions as well.

The structure allows the account to have a more dynamic and adaptable approach for managing function execution logic, using the LSP20-CallVerification standard.


An LSP0ERC725Account has the functionalities of LSP17Extendable built-in. This allows extending its behavior with functions it does not support natively in its interface.

However, calls to the fallback function will revert if no extension is registered for the function selector that was called.


The only exception is the 0x00000000 function selector, which returns in order to allow the Universal Profile to act similarly to an EOA, and receive "graffiti" data (when receiving native tokens or not) without executing anything else.


If your Universal Profile calls an extension to perform some security check, verification or validation, you should not rely on the extension to revert to ensure the validation failed, but check the bytes returned by the extension through _fallbackLSP17Extendable.


Be aware of phantom functions for functions in extensions with the 0x00000000 selector.

For example, a contract might perform some kind of validation in an extension (e.g: checking for permissions), and expect the function to revert if the user is not authorized.

However, since the function's selector is 0x00000000 and the LSP0 account doesn't have this extension registered, the fallback function will return instead of reverting, giving the contract the impression that the user is authorized.

See _fallbackLSP17Extendable for more details.

In such case, make sure to double that an extension is registered first for the 0x00000000 selector via _getExtension.

Adding metadata

Unlike private keys and EOAs that cannot hold any metadata, a UniversalProfile is a blockchain based account that can have any info attached to it.

You can do so using the setData(bytes32,bytes) and setDataBatch(bytes32[],bytes[]) functions to add, update or delete any metadata in your Universal Profile.

Updating your LSP3Profile metadata.

The LSP3Profile data key has a special meaning. It enables you to edit your profile details