Skip to content

Commit

Permalink
Merge pull request #667 from lukso-network/lsp1delegate
Browse files Browse the repository at this point in the history
LSP1Delegate: Use `universalReceiverDelegate` instead of `universalReceiver`
  • Loading branch information
CJ42 authored Oct 23, 2023
2 parents 289661d + 4fb17c8 commit 1dc988b
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 19 deletions.
20 changes: 7 additions & 13 deletions docs/guides/universal-receiver-delegate/create-custom-urd-1.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ pragma solidity ^0.8.11;
// interfaces
import { IERC725X } from "@erc725/smart-contracts/contracts/interfaces/IERC725X.sol";
import { ILSP1UniversalReceiver } from "@lukso/lsp-smart-contracts/contracts/LSP1UniversalReceiver/ILSP1UniversalReceiver.sol";
import { ILSP1UniversalReceiverDelegate } from "@lukso/lsp-smart-contracts/contracts/LSP1UniversalReceiver/ILSP1UniversalReceiverDelegate.sol";
import { ILSP7DigitalAsset } from "@lukso/lsp-smart-contracts/contracts/LSP7DigitalAsset/ILSP7DigitalAsset.sol";
// modules
Expand All @@ -107,7 +107,7 @@ import "@lukso/lsp-smart-contracts/contracts/LSP1UniversalReceiver/LSP1Errors.so
contract LSP1URDForwarderMethod1 is
ERC165,
ILSP1UniversalReceiver
ILSP1UniversalReceiverDelegate
{
// CHECK onlyOwner
Expand Down Expand Up @@ -162,14 +162,11 @@ contract LSP1URDForwarderMethod1 is
}
function universalReceiver(
address notifier,
uint256 value,
bytes32 typeId,
bytes memory data
) public payable virtual returns (bytes memory) {
// CHECK that we did not send any native tokens to the LSP1 Delegate, as it cannot transfer them back.
if (msg.value != 0) {
revert NativeTokensNotAccepted();
}
) public virtual returns (bytes memory) {
// CHECK that the caller is an ERC725Account (e.g: a UniversalProfile)
// by checking it supports the LSP0 interface
// by checking its interface support
Expand All @@ -182,9 +179,6 @@ contract LSP1URDForwarderMethod1 is
return "Caller is not a LSP0";
}
// GET the address of the notifier from the calldata (e.g., the LSP7 Token)
address notifier = address(bytes20(msg.data[msg.data.length - 52:]));
// CHECK that notifier is a contract with a `balanceOf` method
// and that msg.sender (the UP) has a positive balance
if (notifier.code.length > 0) {
Expand Down Expand Up @@ -238,7 +232,7 @@ contract LSP1URDForwarderMethod1 is
bytes4 interfaceId
) public view virtual override returns (bool) {
return
interfaceId == _INTERFACEID_LSP1 ||
interfaceId == _INTERFACEID_LSP1_DELEGATE ||
super.supportsInterface(interfaceId);
}
}
Expand Down Expand Up @@ -296,7 +290,7 @@ cp contracts/LSP1URDForwarderMethod1 contracts/LSP1URDForwarderMethod2.sol
// ...
contract LSP1URDForwarderMethod2 is
ERC165,
ILSP1UniversalReceiver
ILSP1UniversalReceiverDelegate
{
// ...
```
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,27 +29,29 @@ Therefore, it is advised not to hardcode how the smart contract should handle an

:::success recommendation

Smart contracts implementing the [LSP1-UniversalReceiverDelegate](#) standard SHOULD **register** the **[LSP1UniversalReceiver InterfaceId](../../contracts/interface-ids.md) using ERC165**. This way, other contracts can be aware that the contract supports the LSP1 standard.
Smart contracts implementing the [LSP1-UniversalReceiverDelegate](#) standard SHOULD **register** the **[LSP1UniversalReceiverDelegate InterfaceId](../../contracts/interface-ids.md) using ERC165**. This way, other contracts can be aware that the contract supports the LSP1-UniversalReceiverDelegate standard.

:::

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

- address `caller` is the address calling the `universalReceiver` function.

- uint256 `value` is 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.

> NB: It is possible to send extra calldata from the main `universalReceiver(..)` function to the `universalReceiver(..)` function on the UniversalReceiverDelegate.
### How Delegation works

Delegation in the context of smart contracts implementing the `universalReceiver(...)` function allows for flexibility in handling specific calls without hardcoding the logic within the primary contract. While the exact implementation of delegation is up to the individual contract, there are some common steps involved in the process.

1- Query the **UniversalReceiverDelegate** address: Typically, the address of the **UniversalReceiverDelegate** contract is stored in the primary contract's storage. When the `universalReceiver(...)` function is called, the address is retrieved to facilitate delegation.

2- Check for LSP1 support: Before making any calls to the UniversalReceiverDelegate contract, it's essential to ensure that the contract supports the LSP1 standard. This can be done by checking for the **LSP1UniversalReceiver InterfaceId** using ERC165.
2- Check for LSP1Delegate support: Before making any calls to the UniversalReceiverDelegate contract, it's essential to ensure that the contract supports the LSP1Delegate standard. This can be done by checking for the **LSP1UniversalReceiverDelegate InterfaceId** using ERC165.

3- Call the UniversalReceiverDelegate's `universalReceiver(..)` function: Once LSP1 support is confirmed, the primary contract's `universalReceiver(...)` function can delegate the call to the UniversalReceiverDelegate's `universalReceiver(...)` function. This allows the primary contract to utilize the logic implemented in the delegate contract.
3- Call the UniversalReceiverDelegate's `universalReceiverDelegate(..)` function: Once LSP1Delegate support is confirmed, the primary contract's `universalReceiver(...)` function can delegate the call to the UniversalReceiverDelegate's `universalReceiverDelegate(...)` function. This allows the primary contract to utilize the logic implemented in the delegate contract.

Delegation can be implemented in various ways, depending on the developer's requirements. Some possible delegation strategies include:

Expand Down

0 comments on commit 1dc988b

Please sign in to comment.