Skip to content

Commit

Permalink
Merge branch 'develop' into returnedStatus
Browse files Browse the repository at this point in the history
  • Loading branch information
CJ42 authored Oct 13, 2023
2 parents 79e2ccd + dab41a1 commit 7b9ba05
Show file tree
Hide file tree
Showing 52 changed files with 1,011 additions and 713 deletions.
1 change: 1 addition & 0 deletions constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ export const INTERFACE_IDS = {
ERC725Y: '0x629aa694',
LSP0ERC725Account: '0x24871b3d',
LSP1UniversalReceiver: '0x6bb56a14',
LSP1UniversalReceiverDelegate: '0xa245bbda',
LSP6KeyManager: '0xe7424397',
LSP7DigitalAsset: '0x05519512',
LSP8IdentifiableDigitalAsset: '0x1ae9ba1f',
Expand Down
43 changes: 21 additions & 22 deletions contracts/LSP0ERC725Account/LSP0ERC725AccountCore.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ import {
ILSP1UniversalReceiver
} from "../LSP1UniversalReceiver/ILSP1UniversalReceiver.sol";

import {
ILSP1UniversalReceiverDelegate as ILSP1Delegate
} from "../LSP1UniversalReceiver/ILSP1UniversalReceiverDelegate.sol";

// libraries
import {BytesLib} from "solidity-bytes-utils/contracts/BytesLib.sol";
import {ECDSA} from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol";
Expand Down Expand Up @@ -42,6 +46,7 @@ import {
} from "./LSP0Constants.sol";
import {
_INTERFACEID_LSP1,
_INTERFACEID_LSP1_DELEGATE,
_LSP1_UNIVERSAL_RECEIVER_DELEGATE_PREFIX,
_LSP1_UNIVERSAL_RECEIVER_DELEGATE_KEY
} from "../LSP1UniversalReceiver/LSP1Constants.sol";
Expand Down Expand Up @@ -427,23 +432,20 @@ abstract contract LSP0ERC725AccountCore is
bytes memory resultDefaultDelegate;

if (lsp1DelegateValue.length >= 20) {
address universalReceiverDelegate = address(
bytes20(lsp1DelegateValue)
);
address lsp1Delegate = address(bytes20(lsp1DelegateValue));

// Checking LSP1 InterfaceId support
if (
universalReceiverDelegate.supportsERC165InterfaceUnchecked(
_INTERFACEID_LSP1
lsp1Delegate.supportsERC165InterfaceUnchecked(
_INTERFACEID_LSP1_DELEGATE
)
) {
// calling {universalReceiver} function on URD appending the caller and the value sent
resultDefaultDelegate = universalReceiverDelegate
.callUniversalReceiverWithCallerInfos(
typeId,
receivedData,
resultDefaultDelegate = ILSP1Delegate(lsp1Delegate)
.universalReceiverDelegate(
msg.sender,
msg.value
msg.value,
typeId,
receivedData
);
}
}
Expand All @@ -459,23 +461,20 @@ abstract contract LSP0ERC725AccountCore is
bytes memory resultTypeIdDelegate;

if (lsp1TypeIdDelegateValue.length >= 20) {
address universalReceiverDelegate = address(
bytes20(lsp1TypeIdDelegateValue)
);
address lsp1Delegate = address(bytes20(lsp1TypeIdDelegateValue));

// Checking LSP1 InterfaceId support
if (
universalReceiverDelegate.supportsERC165InterfaceUnchecked(
_INTERFACEID_LSP1
lsp1Delegate.supportsERC165InterfaceUnchecked(
_INTERFACEID_LSP1_DELEGATE
)
) {
// calling {universalReceiver} function on URD appending the caller and the value sent
resultTypeIdDelegate = universalReceiverDelegate
.callUniversalReceiverWithCallerInfos(
typeId,
receivedData,
resultTypeIdDelegate = ILSP1Delegate(lsp1Delegate)
.universalReceiverDelegate(
msg.sender,
msg.value
msg.value,
typeId,
receivedData
);
}
}
Expand Down
1 change: 0 additions & 1 deletion contracts/LSP1UniversalReceiver/ILSP1UniversalReceiver.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ pragma solidity ^0.8.4;
interface ILSP1UniversalReceiver {
/**
* @dev Emitted when the {universalReceiver} function was called with a specific `typeId` and some `receivedData`
s
* @notice Address `from` called the `universalReceiver(...)` function while sending `value` LYX. Notification type (typeId): `typeId` - Data received: `receivedData`.
*
* @param from The address of the EOA or smart contract that called the {universalReceiver(...)} function.
Expand Down
24 changes: 24 additions & 0 deletions contracts/LSP1UniversalReceiver/ILSP1UniversalReceiverDelegate.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.4;

/**
* @title Interface of the LSP1 - Universal Receiver Delegate standard.
* @dev This interface allows contracts implementing the LSP1UniversalReceiver function to delegate the reaction logic to another contract or account. By doing so, the main logic doesn't need to reside within the `universalReceiver` function itself, offering modularity and flexibility.
*/
interface ILSP1UniversalReceiverDelegate {
/**
* @dev A delegate function that reacts to calls forwarded from the `universalReceiver(..)` function. This allows for modular handling of the logic based on the `typeId` and `data` provided by the initial caller.
* @notice Reacted on received notification forwarded from `universalReceiver` with `typeId` & `data`.
*
* @param sender The address of the EOA or smart contract that initially called the `universalReceiver` function.
* @param value The amount sent by the `sender` to the `universalReceiver` function.
* @param typeId The hash of a specific standard or a hook.
* @param data The arbitrary data received with the initial call to `universalReceiver`.
*/
function universalReceiverDelegate(
address sender,
uint256 value,
bytes32 typeId,
bytes memory data
) external returns (bytes memory);
}
1 change: 1 addition & 0 deletions contracts/LSP1UniversalReceiver/LSP1Constants.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ pragma solidity ^0.8.4;

// --- ERC165 interface ids
bytes4 constant _INTERFACEID_LSP1 = 0x6bb56a14;
bytes4 constant _INTERFACEID_LSP1_DELEGATE = 0xa245bbda;

// --- ERC725Y Data Keys

Expand Down
6 changes: 0 additions & 6 deletions contracts/LSP1UniversalReceiver/LSP1Errors.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,3 @@ pragma solidity ^0.8.4;
* @param caller The address of the EOA
*/
error CannotRegisterEOAsAsAssets(address caller);

/**
* @dev Reverts when the {universalReceiver} function in the LSP1 Universal Receiver Delegate contract is called while sending some native tokens along the call (`msg.value` different than `0`)
* @notice Cannot send native tokens to {universalReceiver(...)} function of the delegated contract.
*/
error NativeTokensNotAccepted();
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ pragma solidity ^0.8.4;
import {
IERC725Y
} from "@erc725/smart-contracts/contracts/interfaces/IERC725Y.sol";
import {ILSP1UniversalReceiver} from "../ILSP1UniversalReceiver.sol";
import {
ILSP1UniversalReceiverDelegate
} from "../ILSP1UniversalReceiverDelegate.sol";
import {ILSP7DigitalAsset} from "../../LSP7DigitalAsset/ILSP7DigitalAsset.sol";

// modules
Expand All @@ -19,7 +21,7 @@ import {LSP5Utils} from "../../LSP5ReceivedAssets/LSP5Utils.sol";
import {LSP10Utils} from "../../LSP10ReceivedVaults/LSP10Utils.sol";

// constants
import {_INTERFACEID_LSP1} from "../LSP1Constants.sol";
import {_INTERFACEID_LSP1_DELEGATE} from "../LSP1Constants.sol";
import {
_TYPEID_LSP7_TOKENSSENDER,
_TYPEID_LSP7_TOKENSRECIPIENT,
Expand All @@ -36,10 +38,7 @@ import {
} from "../../LSP9Vault/LSP9Constants.sol";

// errors
import {
NativeTokensNotAccepted,
CannotRegisterEOAsAsAssets
} from "../LSP1Errors.sol";
import {CannotRegisterEOAsAsAssets} from "../LSP1Errors.sol";

/**
* @title Implementation of a UniversalReceiverDelegate for the [LSP-0-ERC725Account]
Expand All @@ -53,7 +52,10 @@ import {
* - Writes the data keys representing the owned vaults from type [LSP-9-Vault] into your account storage, and removes them when transferring ownership to other accounts according to the [LSP-10-ReceivedVaults] Standard.
*
*/
contract LSP1UniversalReceiverDelegateUP is ERC165, ILSP1UniversalReceiver {
contract LSP1UniversalReceiverDelegateUP is
ERC165,
ILSP1UniversalReceiverDelegate
{
using ERC165Checker for address;

/**
Expand All @@ -76,17 +78,12 @@ contract LSP1UniversalReceiverDelegateUP is ERC165, ILSP1UniversalReceiver {
* @param typeId Unique identifier for a specific notification.
* @return The result of the reaction for `typeId`.
*/
function universalReceiver(
function universalReceiverDelegate(
address notifier,
uint256 /*value*/,
bytes32 typeId,
bytes memory /* data */
) public payable virtual override 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();
}

address notifier = address(bytes20(msg.data[msg.data.length - 52:]));

) public virtual override returns (bytes memory) {
// The notifier is supposed to be either the LSP7 or LSP8 or LSP9 contract
// If it's EOA we revert to avoid registering the EOA as asset or vault (spam protection)
// solhint-disable-next-line avoid-tx-origin
Expand Down Expand Up @@ -271,7 +268,7 @@ contract LSP1UniversalReceiverDelegateUP is ERC165, ILSP1UniversalReceiver {
bytes4 interfaceId
) public view virtual override returns (bool) {
return
interfaceId == _INTERFACEID_LSP1 ||
interfaceId == _INTERFACEID_LSP1_DELEGATE ||
super.supportsInterface(interfaceId);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ pragma solidity ^0.8.4;
import {
IERC725Y
} from "@erc725/smart-contracts/contracts/interfaces/IERC725Y.sol";
import {ILSP1UniversalReceiver} from "../ILSP1UniversalReceiver.sol";
import {
ILSP1UniversalReceiverDelegate
} from "../ILSP1UniversalReceiverDelegate.sol";
import {ILSP7DigitalAsset} from "../../LSP7DigitalAsset/ILSP7DigitalAsset.sol";

// modules
Expand All @@ -15,7 +17,7 @@ import {ERC165} from "@openzeppelin/contracts/utils/introspection/ERC165.sol";
import {LSP5Utils} from "../../LSP5ReceivedAssets/LSP5Utils.sol";

// constants
import {_INTERFACEID_LSP1} from "../LSP1Constants.sol";
import {_INTERFACEID_LSP1_DELEGATE} from "../LSP1Constants.sol";
import {
_TYPEID_LSP7_TOKENSSENDER,
_TYPEID_LSP7_TOKENSRECIPIENT,
Expand All @@ -28,10 +30,7 @@ import {
} from "../../LSP8IdentifiableDigitalAsset/LSP8Constants.sol";

// errors
import {
CannotRegisterEOAsAsAssets,
NativeTokensNotAccepted
} from "../LSP1Errors.sol";
import {CannotRegisterEOAsAsAssets} from "../LSP1Errors.sol";

/**
* @title Implementation of a UniversalReceiverDelegate for the [LSP9Vault]
Expand All @@ -43,9 +42,12 @@ import {
*
* - Writes the data keys representing assets received from type [LSP-7-DigitalAsset] and [LSP-8-IdentifiableDigitalAsset] into the account storage, and removes them when the balance is zero according to the [LSP-5-ReceivedAssets] Standard.
*/
contract LSP1UniversalReceiverDelegateVault is ERC165, ILSP1UniversalReceiver {
contract LSP1UniversalReceiverDelegateVault is
ERC165,
ILSP1UniversalReceiverDelegate
{
/**
* @inheritdoc ILSP1UniversalReceiver
* @inheritdoc ILSP1UniversalReceiverDelegate
* @dev Handles two cases:
*
* Writes the received [LSP-7-DigitalAsset] or [LSP-8-IdentifiableDigitalAsset] assets into the vault storage according to the [LSP-5-ReceivedAssets] standard.
Expand All @@ -60,17 +62,12 @@ contract LSP1UniversalReceiverDelegateVault is ERC165, ILSP1UniversalReceiver {
* @param typeId Unique identifier for a specific notification.
* @return The result of the reaction for `typeId`.
*/
function universalReceiver(
function universalReceiverDelegate(
address notifier,
uint256 /*value*/,
bytes32 typeId,
bytes memory /* data */
) public payable virtual override 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();
}

address notifier = address(bytes20(msg.data[msg.data.length - 52:]));

) public virtual override returns (bytes memory) {
// The notifier is supposed to be either the LSP7 or LSP8 contract
// If it's EOA we revert to avoid registering the EOA as asset (spam protection)
// solhint-disable-next-line avoid-tx-origin
Expand Down Expand Up @@ -201,7 +198,7 @@ contract LSP1UniversalReceiverDelegateVault is ERC165, ILSP1UniversalReceiver {
bytes4 interfaceId
) public view virtual override returns (bool) {
return
interfaceId == _INTERFACEID_LSP1 ||
interfaceId == _INTERFACEID_LSP1_DELEGATE ||
super.supportsInterface(interfaceId);
}
}
41 changes: 0 additions & 41 deletions contracts/LSP1UniversalReceiver/LSP1Utils.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
pragma solidity ^0.8.4;

// libraries
import {Address} from "@openzeppelin/contracts/utils/Address.sol";
import {
ERC165Checker
} from "@openzeppelin/contracts/utils/introspection/ERC165Checker.sol";
Expand Down Expand Up @@ -49,46 +48,6 @@ library LSP1Utils {
}
}

/**
* @dev Call a LSP1UniversalReceiverDelegate contract at `universalReceiverDelegate` address and append `msgSender` and `msgValue`
* as additional informations in the calldata.
*
* @param universalReceiverDelegate The address of the LSP1UniversalReceiverDelegate to delegate the `universalReceiver` function to.
* @param typeId A `bytes32` typeId.
* @param receivedData The data sent initially to the `universalReceiver` function.
* @param msgSender The address that initially called the `universalReceiver` function.
* @param msgValue The amount of native token received initially by the `universalReceiver` function.
*
* @return The data returned by the LSP1UniversalReceiverDelegate contract.
*/
function callUniversalReceiverWithCallerInfos(
address universalReceiverDelegate,
bytes32 typeId,
bytes calldata receivedData,
address msgSender,
uint256 msgValue
) internal returns (bytes memory) {
bytes memory callData = abi.encodePacked(
abi.encodeWithSelector(
ILSP1.universalReceiver.selector,
typeId,
receivedData
),
msgSender,
msgValue
);

(bool success, bytes memory result) = universalReceiverDelegate.call(
callData
);
Address.verifyCallResult(
success,
result,
"Call to universalReceiver failed"
);
return result.length != 0 ? abi.decode(result, (bytes)) : result;
}

/**
* @notice Retrieving the value stored under the ERC725Y data key `LSP1UniversalReceiverDelegate`.
*
Expand Down
28 changes: 0 additions & 28 deletions contracts/LSP2ERC725YJSONSchema/LSP2Utils.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,6 @@ import {
IERC725Y
} from "@erc725/smart-contracts/contracts/interfaces/IERC725Y.sol";

// libraries
import {BytesLib} from "solidity-bytes-utils/contracts/BytesLib.sol";

/**
* @title LSP2 Utility library.
* @author Jean Cavallera <CJ42>, Yamen Merhi <YamenMerhi>, Daniel Afteni <B00ste>
Expand All @@ -17,8 +14,6 @@ import {BytesLib} from "solidity-bytes-utils/contracts/BytesLib.sol";
* Based on LSP2 ERC725Y JSON Schema standard.
*/
library LSP2Utils {
using BytesLib for bytes;

/**
* @dev Generates a data key of keyType Singleton by hashing the string `keyName`. As:
*
Expand Down Expand Up @@ -285,29 +280,6 @@ library LSP2Utils {
return abi.encodePacked(bytes4(hashFunctionDigest), jsonDigest, url);
}

/**
* @dev Verify if `data` is an abi-encoded array.
*
* @param data The bytes value to verify.
*
* @return `true` if the `data` represents an abi-encoded array, `false` otherwise.
*/
function isEncodedArray(bytes memory data) internal pure returns (bool) {
uint256 nbOfBytes = data.length;

// there must be at least 32 x length bytes after offset
uint256 offset = uint256(bytes32(data));
if (nbOfBytes < offset + 32) return false;
uint256 arrayLength = data.toUint256(offset);

// 32 bytes word (= offset)
// + 32 bytes word (= array length)
// + remaining bytes that make each element of the array
if (nbOfBytes < (offset + 32 + (arrayLength * 32))) return false;

return true;
}

/**
* @dev Verify if `data` is a valid array of value encoded as a `CompactBytesArray` according to the LSP2 `CompactBytesArray` valueType specification.
*
Expand Down
Loading

0 comments on commit 7b9ba05

Please sign in to comment.