diff --git a/contracts/OriumSftMarketplace.sol b/contracts/OriumSftMarketplace.sol index 9834c6c..434e4d2 100644 --- a/contracts/OriumSftMarketplace.sol +++ b/contracts/OriumSftMarketplace.sol @@ -138,7 +138,7 @@ contract OriumSftMarketplace is Initializable, OwnableUpgradeable, PausableUpgra _offer.lender, _offer.tokenId, _offer.tokenAmount - ); + ); } nonceDeadline[msg.sender][_offer.nonce] = _offer.deadline; @@ -224,7 +224,7 @@ contract OriumSftMarketplace is Initializable, OwnableUpgradeable, PausableUpgra IOriumMarketplaceRoyalties(oriumMarketplaceRoyalties).sftRolesRegistryOf(_offer.tokenAddress) ); - if(_offer.tokenAddress == aavegotchiWearableAddress) { + if (_offer.tokenAddress == aavegotchiWearableAddress) { _rolesRegistryLegacy.releaseTokens(_offer.commitmentId); } else { _rolesRegistry.unlockTokens(_offer.commitmentId); @@ -283,7 +283,7 @@ contract OriumSftMarketplace is Initializable, OwnableUpgradeable, PausableUpgra address _rolesRegistryAddress = IOriumMarketplaceRoyalties(oriumMarketplaceRoyalties).sftRolesRegistryOf( _params[i].tokenAddress ); - + uint256 _validCommitmentId = _params[i].commitmentId; if (_params[i].commitmentId == 0) { _validCommitmentId = _commitOrLockTokens( @@ -306,9 +306,7 @@ contract OriumSftMarketplace is Initializable, OwnableUpgradeable, PausableUpgra ); } - _grantRole( - _params[i].tokenAddress, - _rolesRegistryAddress, + IERC7589(_rolesRegistryAddress).grantRole( _validCommitmentId, _params[i].role, _params[i].grantee, @@ -342,7 +340,6 @@ contract OriumSftMarketplace is Initializable, OwnableUpgradeable, PausableUpgra ); } - /** ######### Internals ########### **/ /** @@ -361,61 +358,9 @@ contract OriumSftMarketplace is Initializable, OwnableUpgradeable, PausableUpgra uint256 _tokenAmount ) internal returns (uint256) { if (_tokenAddress == aavegotchiWearableAddress) { - return IERC7589Legacy(_rolesRegistryAddress).commitTokens( - _lender, - _tokenAddress, - _tokenId, - _tokenAmount - ); - } else { - return IERC7589(_rolesRegistryAddress).lockTokens( - _lender, - _tokenAddress, - _tokenId, - _tokenAmount - ); - } - } - - /** - * @dev Validates if is wearable address to use current or legacy grantRole. - * @param _tokenAddress The address of the contract of the SFT to rent. - * @param _rolesRegistryAddress The rental offer struct. - * @param _commitmentId The commitmentId of the SFT to rent. - * @param _role role to be assigned to the borrower. - * @param _grantee recipient. - * @param _expirationDate expiration date of role. - * @param _revocable role is recovable. - * @param _data data struct to send others informations. - */ - function _grantRole( - address _tokenAddress, - address _rolesRegistryAddress, - uint256 _commitmentId, - bytes32 _role, - address _grantee, - uint64 _expirationDate, - bool _revocable, - bytes memory _data - ) internal { - if (_tokenAddress == aavegotchiWearableAddress) { - IERC7589Legacy(_rolesRegistryAddress).grantRole( - _commitmentId, - _role, - _grantee, - _expirationDate, - _revocable, - _data - ); + return IERC7589Legacy(_rolesRegistryAddress).commitTokens(_lender, _tokenAddress, _tokenId, _tokenAmount); } else { - IERC7589(_rolesRegistryAddress).grantRole( - _commitmentId, - _role, - _grantee, - _expirationDate, - _revocable, - _data - ); + return IERC7589(_rolesRegistryAddress).lockTokens(_lender, _tokenAddress, _tokenId, _tokenAmount); } } @@ -523,8 +468,6 @@ contract OriumSftMarketplace is Initializable, OwnableUpgradeable, PausableUpgra emit RentalOfferCancelled(_offer.lender, _offer.nonce); } - - /** ============================ Core Functions ================================== **/ /** ######### Setters ########### **/ @@ -553,6 +496,5 @@ contract OriumSftMarketplace is Initializable, OwnableUpgradeable, PausableUpgra function setOriumMarketplaceRoyalties(address _oriumMarketplaceRoyalties) external onlyOwner { oriumMarketplaceRoyalties = _oriumMarketplaceRoyalties; } - /** ######### Getters ########### **/ } diff --git a/contracts/libraries/LibOriumSftMarketplace.sol b/contracts/libraries/LibOriumSftMarketplace.sol index 99413d7..4a171fe 100644 --- a/contracts/libraries/LibOriumSftMarketplace.sol +++ b/contracts/libraries/LibOriumSftMarketplace.sol @@ -101,22 +101,39 @@ library LibOriumSftMarketplace { address _rolesRegistryAddress ) external view { IERC7589 _rolesRegistry = IERC7589(_rolesRegistryAddress); - require( - _rolesRegistry.tokenAmountOf(_commitmentId) == _tokenAmount, - "OriumSftMarketplace: tokenAmount provided does not match commitment's tokenAmount" - ); - require( - _rolesRegistry.ownerOf(_commitmentId) == _expectedGrantor, - 'OriumSftMarketplace: expected grantor does not match the grantor of the commitmentId' - ); - require( - _rolesRegistry.tokenAddressOf(_commitmentId) == _tokenAddress, - "OriumSftMarketplace: tokenAddress provided does not match commitment's tokenAddress" - ); - require( - _rolesRegistry.tokenIdOf(_commitmentId) == _tokenId, - "OriumSftMarketplace: tokenId provided does not match commitment's tokenId" - ); + IERC7589Legacy _rolesRegistryLegacy = IERC7589Legacy(_rolesRegistryAddress); + + if (_tokenAddress == aavegotchiWearableAddress) { + require( + _rolesRegistryLegacy.grantorOf(_commitmentId) == _expectedGrantor, + 'OriumSftMarketplace: expected grantor does not match the grantor of the commitmentId' + ); + require( + _rolesRegistryLegacy.tokenAmountOf(_commitmentId) == _tokenAmount, + "OriumSftMarketplace: tokenAmount provided does not match commitment's tokenAmount" + ); + require( + _rolesRegistryLegacy.tokenIdOf(_commitmentId) == _tokenId, + "OriumSftMarketplace: tokenId provided does not match commitment's tokenId" + ); + } else { + require( + _rolesRegistry.tokenAmountOf(_commitmentId) == _tokenAmount, + "OriumSftMarketplace: tokenAmount provided does not match commitment's tokenAmount" + ); + require( + _rolesRegistry.ownerOf(_commitmentId) == _expectedGrantor, + 'OriumSftMarketplace: expected grantor does not match the grantor of the commitmentId' + ); + require( + _rolesRegistry.tokenAddressOf(_commitmentId) == _tokenAddress, + "OriumSftMarketplace: tokenAddress provided does not match commitment's tokenAddress" + ); + require( + _rolesRegistry.tokenIdOf(_commitmentId) == _tokenId, + "OriumSftMarketplace: tokenId provided does not match commitment's tokenId" + ); + } } /** @@ -249,17 +266,28 @@ library LibOriumSftMarketplace { IERC7589Legacy(_rolesRegistryAddress).grantorOf(_commitmentIds[i]) == msg.sender, "OriumSftMarketplace: sender is not the commitment's grantor or grantee Legacy" ); + require( + IERC7589Legacy(_rolesRegistryAddress).roleExpirationDate( + _commitmentIds[i], + _roles[i], + _grantees[i] + ) > block.timestamp, + 'OriumSftMarketplace: role is expired' + ); require( IERC7589Legacy(_rolesRegistryAddress).isRoleRevocable(_commitmentIds[i], _roles[i], _grantees[i]), 'OriumSftMarketplace: role is not revocable Legacy' ); - IERC7589Legacy(_rolesRegistryAddress).revokeRole(_commitmentIds[i], _roles[i], _grantees[i]); } else { require( msg.sender == _grantees[i] || IERC7589(_rolesRegistryAddress).ownerOf(_commitmentIds[i]) == msg.sender, "OriumSftMarketplace: sender is not the commitment's grantor or grantee" ); + require( + IERC7589(_rolesRegistryAddress).roleExpirationDate(_commitmentIds[i], _roles[i]) > block.timestamp, + 'OriumSftMarketplace: role is expired' + ); require( IERC7589(_rolesRegistryAddress).isRoleRevocable(_commitmentIds[i], _roles[i]), 'OriumSftMarketplace: role is not revocable' @@ -268,8 +296,8 @@ library LibOriumSftMarketplace { IERC7589(_rolesRegistryAddress).tokenAddressOf(_commitmentIds[i]) == _tokenAddresses[i], "OriumSftMarketplace: tokenAddress provided does not match commitment's tokenAddress" ); - IERC7589(_rolesRegistryAddress).revokeRole(_commitmentIds[i], _roles[i], _grantees[i]); } + IERC7589(_rolesRegistryAddress).revokeRole(_commitmentIds[i], _roles[i], _grantees[i]); } } diff --git a/contracts/mocks/ISftRolesRegistryLegacy.sol b/contracts/mocks/ISftRolesRegistryLegacy.sol deleted file mode 100644 index a52f060..0000000 --- a/contracts/mocks/ISftRolesRegistryLegacy.sol +++ /dev/null @@ -1,182 +0,0 @@ -// SPDX-License-Identifier: CC0-1.0 - -pragma solidity 0.8.9; - -import { IERC165 } from '@openzeppelin/contracts/utils/introspection/IERC165.sol'; - -interface ISftRolesRegistryLegacy is IERC165 { - struct RoleAssignment { - address grantee; - uint64 expirationDate; - bool revocable; - bytes data; - } - - struct Commitment { - address grantor; - address tokenAddress; - uint256 tokenId; - uint256 tokenAmount; - } - - /** Events **/ - - /// @notice Emitted when tokens are committed (deposited or frozen). - /// @param _grantor The owner of the SFTs. - /// @param _commitmentId The identifier of the commitment created. - /// @param _tokenAddress The token address. - /// @param _tokenId The token identifier. - /// @param _tokenAmount The token amount. - event TokensCommitted( - address indexed _grantor, - uint256 indexed _commitmentId, - address indexed _tokenAddress, - uint256 _tokenId, - uint256 _tokenAmount - ); - - /// @notice Emitted when a role is granted. - /// @param _commitmentId The commitment identifier. - /// @param _role The role identifier. - /// @param _grantee The recipient the role. - /// @param _expirationDate The expiration date of the role. - /// @param _revocable Whether the role is revocable or not. - /// @param _data Any additional data about the role. - event RoleGranted( - uint256 indexed _commitmentId, - bytes32 indexed _role, - address indexed _grantee, - uint64 _expirationDate, - bool _revocable, - bytes _data - ); - - /// @notice Emitted when a role is revoked. - /// @param _commitmentId The commitment identifier. - /// @param _role The role identifier. - /// @param _grantee The recipient of the role revocation. - event RoleRevoked(uint256 indexed _commitmentId, bytes32 indexed _role, address indexed _grantee); - - /// @notice Emitted when a user releases tokens from a commitment. - /// @param _commitmentId The commitment identifier. - event TokensReleased(uint256 indexed _commitmentId); - - /// @notice Emitted when a user is approved to manage roles on behalf of another user. - /// @param _tokenAddress The token address. - /// @param _operator The user approved to grant and revoke roles. - /// @param _isApproved The approval status. - event RoleApprovalForAll(address indexed _tokenAddress, address indexed _operator, bool _isApproved); - - /** External Functions **/ - - /// @notice Commits tokens (deposits on a contract or freezes balance). - /// @param _grantor The owner of the SFTs. - /// @param _tokenAddress The token address. - /// @param _tokenId The token identifier. - /// @param _tokenAmount The token amount. - /// @return commitmentId_ The unique identifier of the commitment created. - function commitTokens( - address _grantor, - address _tokenAddress, - uint256 _tokenId, - uint256 _tokenAmount - ) external returns (uint256 commitmentId_); - - /// @notice Grants a role to `_grantee`. - /// @param _commitmentId The identifier of the commitment. - /// @param _role The role identifier. - /// @param _grantee The recipient the role. - /// @param _expirationDate The expiration date of the role. - /// @param _revocable Whether the role is revocable or not. - /// @param _data Any additional data about the role. - function grantRole( - uint256 _commitmentId, - bytes32 _role, - address _grantee, - uint64 _expirationDate, - bool _revocable, - bytes calldata _data - ) external; - - /// @notice Revokes a role. - /// @param _commitmentId The commitment identifier. - /// @param _role The role identifier. - /// @param _grantee The recipient of the role revocation. - function revokeRole(uint256 _commitmentId, bytes32 _role, address _grantee) external; - - /// @notice Releases tokens back to grantor. - /// @param _commitmentId The commitment identifier. - function releaseTokens(uint256 _commitmentId) external; - - /// @notice Approves operator to grant and revoke roles on behalf of another user. - /// @param _tokenAddress The token address. - /// @param _operator The user approved to grant and revoke roles. - /// @param _approved The approval status. - function setRoleApprovalForAll(address _tokenAddress, address _operator, bool _approved) external; - - /** View Functions **/ - - /// @notice Returns the owner of the commitment (grantor). - /// @param _commitmentId The commitment identifier. - /// @return grantor_ The commitment owner. - function grantorOf(uint256 _commitmentId) external view returns (address grantor_); - - /// @notice Returns the address of the token committed. - /// @param _commitmentId The commitment identifier. - /// @return tokenAddress_ The token address. - function tokenAddressOf(uint256 _commitmentId) external view returns (address tokenAddress_); - - /// @notice Returns the identifier of the token committed. - /// @param _commitmentId The commitment identifier. - /// @return tokenId_ The token identifier. - function tokenIdOf(uint256 _commitmentId) external view returns (uint256 tokenId_); - - /// @notice Returns the amount of tokens committed. - /// @param _commitmentId The commitment identifier. - /// @return tokenAmount_ The token amount. - function tokenAmountOf(uint256 _commitmentId) external view returns (uint256 tokenAmount_); - - /// @notice Returns the custom data of a role assignment. - /// @param _commitmentId The commitment identifier. - /// @param _role The role identifier. - /// @param _grantee The recipient the role. - /// @return data_ The custom data. - function roleData( - uint256 _commitmentId, - bytes32 _role, - address _grantee - ) external view returns (bytes memory data_); - - /// @notice Returns the expiration date of a role assignment. - /// @param _commitmentId The commitment identifier. - /// @param _role The role identifier. - /// @param _grantee The recipient the role. - /// @return expirationDate_ The expiration date. - function roleExpirationDate( - uint256 _commitmentId, - bytes32 _role, - address _grantee - ) external view returns (uint64 expirationDate_); - - /// @notice Returns the expiration date of a role assignment. - /// @param _commitmentId The commitment identifier. - /// @param _role The role identifier. - /// @param _grantee The recipient the role. - /// @return revocable_ Whether the role is revocable or not. - function isRoleRevocable( - uint256 _commitmentId, - bytes32 _role, - address _grantee - ) external view returns (bool revocable_); - - /// @notice Checks if the grantor approved the operator for all SFTs. - /// @param _tokenAddress The token address. - /// @param _grantor The user that approved the operator. - /// @param _operator The user that can grant and revoke roles. - /// @return isApproved_ Whether the operator is approved or not. - function isRoleApprovedForAll( - address _tokenAddress, - address _grantor, - address _operator - ) external view returns (bool isApproved_); -} \ No newline at end of file diff --git a/contracts/mocks/SftRolesRegistrySingleRoleLegacy.sol b/contracts/mocks/SftRolesRegistrySingleRoleLegacy.sol index 791f311..9880a8b 100644 --- a/contracts/mocks/SftRolesRegistrySingleRoleLegacy.sol +++ b/contracts/mocks/SftRolesRegistrySingleRoleLegacy.sol @@ -2,7 +2,7 @@ pragma solidity 0.8.9; -import { ISftRolesRegistryLegacy } from './ISftRolesRegistryLegacy.sol'; +import { IERC7589Legacy } from '../interfaces/IERC7589Legacy.sol'; import { IERC165 } from '@openzeppelin/contracts/utils/introspection/IERC165.sol'; import { IERC1155 } from '@openzeppelin/contracts/token/ERC1155/IERC1155.sol'; import { IERC1155Receiver } from '@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol'; @@ -10,7 +10,7 @@ import { ERC1155Holder, ERC1155Receiver } from '@openzeppelin/contracts/token/ER import { ERC165Checker } from '@openzeppelin/contracts/utils/introspection/ERC165Checker.sol'; // Semi-fungible token (SFT) registry with only one role (UNIQUE_ROLE) -contract SftRolesRegistrySingleRoleLegacy is ISftRolesRegistryLegacy, ERC1155Holder { +contract SftRolesRegistrySingleRoleLegacy is IERC7589Legacy, ERC1155Holder { bytes32 public constant UNIQUE_ROLE = keccak256('UNIQUE_ROLE'); uint256 public commitmentCount; @@ -171,7 +171,7 @@ contract SftRolesRegistrySingleRoleLegacy is ISftRolesRegistryLegacy, ERC1155Hol bytes4 interfaceId ) public view virtual override(ERC1155Receiver, IERC165) returns (bool) { return - interfaceId == type(ISftRolesRegistryLegacy).interfaceId || + interfaceId == type(IERC7589Legacy).interfaceId || interfaceId == type(IERC1155Receiver).interfaceId; }