Skip to main content

LSP1 - Universal Receiver Delegate

Recommendation

To better understand this standard, it is well-advised first to check the origin standard LSP1-UniversalReceiver.

Introduction​

Once deployed, the code of a smart contract can not be changed. However, builders can decide how their smart contracts implement the universalReceiver(...) function. This standard allows any external smart contract to change relations from the main contract to change function behavior.

Therefore, it is advised not to hardcode how the smart contract should handle and react to specific calls inside the universalReceiver(...) function. Instead, it should delegate this functionality to another external contract. Developers could then customize such contracts to implement a specific logic that is changeable anytime via an upgrade.

What does this standard represent ?​

Specification​

recommendation

Smart contracts implementing the LSP1-UniversalReceiverDelegate standard SHOULD register the LSP1UniversalReceiverDelegate InterfaceId using ERC165. This way, other contracts can be aware that the contract supports the LSP1 standard.

This standard defines a contract called UniversalReceiverDelegate containing a single function named universalReceiverDelegate(...) that should be called by the universalReceiver(..) function with:

  • address caller: the address that initially called the universalReceiver(...) function.

  • uint256 value: the amount of value sent to the universalReceiver(...) function.

  • bytes32 typeId: the typeId passed to the universalReceiver(...) function.

  • bytes data: the data passed to the universalReceiver(...) function.

How Delegation works​

The address of the UniversalReceiverDelegate contract can be stored inside the storage of the contract delegating its universalReceiver(...) functionality. This allows the upgrade of the UniversalReceiverDelegate simply by changing the address (in storage) to another UniversalReceiverDelegate containing a new logic.

If the contract implementing the universalReceiver(..) supports ERC725Y Data key-value store, the address of the external contract MUST be set as a value for the LSP1UniversalReceiverDelegate data key shown below to enable the optional extension. This key-value pair will act as a reference, making this external contract upgradeable if required.

{
"name": "LSP1UniversalReceiverDelegate",
"key": "0x0cfc51aec37c55a4d0b1a65c6255c4bf2fbdf6277f3cc0730c45b828b6db8b47",
"keyType": "Singleton",
"valueType": "address",
"valueContent": "Address"
}

Check LSP2-ERC725YJSONSchema for more information about the JSON schema.

Implementations​

There are several implementations of the standard. The LSP1UniversalReceiverDelegateUP contract is one of them and is used as a delegate to the universalReceiver(...) function of UniversalProfile contract.

At the moment, this contract allows to:

Token transfer scenario​

One of the possible scenarios is a token transfer between Alice and Bob. Alice wants to transfer a token owned by her Universal Profile to the Universal Profile of her friend Bob.

1. It calls the transfer(...) function on the token contract through the KeyManager.

executing transfer function

2. The transfer(...) function on the token contract will directly trigger a hook that will call the universalReceiver(...) function on both sender and recipient Universal Profiles.

token contract hooks calling universalReceiver function

3. 3. If the UniversalReceiverDelegate contract is set, it will be called by the universalReceiver(...) function and will execute its custom logic.

universalReceiver function calling UniversalReceiverDelegate contract

4. The UniversalReceiverDelegate of Universal Profile allows the transfer and set LSP5-ReceivedAssets data keys on both Profiles through the KeyManager.

UniversalReceiverDelegate setting data keys on profile

References​