diff --git a/contracts/OriumSftMarketplace.sol b/contracts/OriumSftMarketplace.sol index 623d0ba..a7de715 100644 --- a/contracts/OriumSftMarketplace.sol +++ b/contracts/OriumSftMarketplace.sol @@ -2,13 +2,13 @@ pragma solidity 0.8.9; -import { OwnableUpgradeable } from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; -import { Initializable } from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; -import { PausableUpgradeable } from "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol"; -import { IERC1155 } from "@openzeppelin/contracts/token/ERC1155/IERC1155.sol"; -import { IERC7589 } from "./interfaces/IERC7589.sol"; -import { LibOriumSftMarketplace, RentalOffer, RentalOfferLegacy, CommitAndGrantRoleParams } from "./libraries/LibOriumSftMarketplace.sol"; -import { IOriumMarketplaceRoyalties } from "./interfaces/IOriumMarketplaceRoyalties.sol"; +import { OwnableUpgradeable } from '@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol'; +import { Initializable } from '@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol'; +import { PausableUpgradeable } from '@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol'; +import { IERC1155 } from '@openzeppelin/contracts/token/ERC1155/IERC1155.sol'; +import { IERC7589 } from './interfaces/IERC7589.sol'; +import { LibOriumSftMarketplace, RentalOffer, CommitAndGrantRoleParams } from './libraries/LibOriumSftMarketplace.sol'; +import { IOriumMarketplaceRoyalties } from './interfaces/IOriumMarketplaceRoyalties.sol'; /** * @title Orium Marketplace - Marketplace for renting SFTs @@ -74,35 +74,6 @@ contract OriumSftMarketplace is Initializable, OwnableUpgradeable, PausableUpgra bytes[] rolesData ); - /** - * @param nonce The nonce of the rental offer - * @param tokenAddress The address of the contract of the SFT to rent - * @param tokenId The tokenId of the SFT to rent - * @param tokenAmount The amount of SFT to rent - * @param commitmentId The commitmentId of the SFT to rent - * @param lender The address of the user lending the SFT - * @param borrower The address of the user renting the SFT - * @param feeTokenAddress The address of the ERC20 token for rental fees - * @param feeAmountPerSecond The amount of fee per second - * @param deadline The deadline until when the rental offer is valid - * @param roles The array of roles to be assigned to the borrower - * @param rolesData The array of data for each role - */ - event RentalOfferCreated( - uint256 indexed nonce, - address indexed tokenAddress, - uint256 indexed tokenId, - uint256 tokenAmount, - uint256 commitmentId, - address lender, - address borrower, - address feeTokenAddress, - uint256 feeAmountPerSecond, - uint256 deadline, - bytes32[] roles, - bytes[] rolesData - ); - /** * @param lender The address of the lender * @param nonce The nonce of the rental offer @@ -149,60 +120,8 @@ contract OriumSftMarketplace is Initializable, OwnableUpgradeable, PausableUpgra * @dev To optimize for gas, only the offer hash is stored on-chain * @param _offer The rental offer struct. */ - function createRentalOffer(RentalOfferLegacy calldata _offer) external whenNotPaused { - RentalOffer memory _parsedOffer = RentalOffer({ - nonce: _offer.nonce, - tokenAddress: _offer.tokenAddress, - tokenId: _offer.tokenId, - tokenAmount: _offer.tokenAmount, - commitmentId: _offer.commitmentId, - lender: _offer.lender, - borrower: _offer.borrower, - feeTokenAddress: _offer.feeTokenAddress, - feeAmountPerSecond: _offer.feeAmountPerSecond, - deadline: _offer.deadline, - minDuration: 0, - roles: _offer.roles, - rolesData: _offer.rolesData - }); - uint256 _commitmentId = _createRentalOffer(_parsedOffer); - - emit RentalOfferCreated( - _offer.nonce, - _offer.tokenAddress, - _offer.tokenId, - _offer.tokenAmount, - _commitmentId, - _offer.lender, - _offer.borrower, - _offer.feeTokenAddress, - _offer.feeAmountPerSecond, - _offer.deadline, - _offer.roles, - _offer.rolesData - ); - } - - function createRentalOffer(RentalOffer calldata _offer) external whenNotPaused { - uint256 _commitmentId = _createRentalOffer(_offer); - emit RentalOfferCreated( - _offer.nonce, - _offer.tokenAddress, - _offer.tokenId, - _offer.tokenAmount, - _commitmentId, - _offer.lender, - _offer.borrower, - _offer.feeTokenAddress, - _offer.feeAmountPerSecond, - _offer.deadline, - _offer.minDuration, - _offer.roles, - _offer.rolesData - ); - } - function _createRentalOffer(RentalOffer memory _offer) internal returns (uint256) { + function createRentalOffer(RentalOffer memory _offer) external whenNotPaused { address _rolesRegistryAddress = IOriumMarketplaceRoyalties(oriumMarketplaceRoyalties).sftRolesRegistryOf( _offer.tokenAddress ); @@ -221,7 +140,21 @@ contract OriumSftMarketplace is Initializable, OwnableUpgradeable, PausableUpgra isCreated[LibOriumSftMarketplace.hashRentalOffer(_offer)] = true; commitmentIdToNonce[_rolesRegistryAddress][_offer.commitmentId] = _offer.nonce; - return _offer.commitmentId; + emit RentalOfferCreated( + _offer.nonce, + _offer.tokenAddress, + _offer.tokenId, + _offer.tokenAmount, + _offer.commitmentId, + _offer.lender, + _offer.borrower, + _offer.feeTokenAddress, + _offer.feeAmountPerSecond, + _offer.deadline, + _offer.minDuration, + _offer.roles, + _offer.rolesData + ); } /** @@ -232,28 +165,6 @@ contract OriumSftMarketplace is Initializable, OwnableUpgradeable, PausableUpgra */ function acceptRentalOffer(RentalOffer calldata _offer, uint64 _duration) external whenNotPaused { - _acceptRentalOffer(_offer, _duration); - } - - function acceptRentalOffer(RentalOfferLegacy calldata _offer, uint64 _duration) external whenNotPaused { - RentalOffer memory _parsedOffer = RentalOffer({ - nonce: _offer.nonce, - tokenAddress: _offer.tokenAddress, - tokenId: _offer.tokenId, - tokenAmount: _offer.tokenAmount, - commitmentId: _offer.commitmentId, - lender: _offer.lender, - borrower: _offer.borrower, - feeTokenAddress: _offer.feeTokenAddress, - feeAmountPerSecond: _offer.feeAmountPerSecond, - deadline: _offer.deadline, - minDuration: 0, - roles: _offer.roles, - rolesData: _offer.rolesData - }); - _acceptRentalOffer(_parsedOffer, _duration); - } - function _acceptRentalOffer(RentalOffer memory _offer, uint64 _duration) internal { bytes32 _offerHash = LibOriumSftMarketplace.hashRentalOffer(_offer); uint64 _expirationDate = uint64(block.timestamp + _duration); LibOriumSftMarketplace.validateAcceptRentalOffer( @@ -291,35 +202,13 @@ contract OriumSftMarketplace is Initializable, OwnableUpgradeable, PausableUpgra * @notice Cancels a rental offer. * @param _offer The rental offer struct. It should be the same as the one used to create the offer. */ - function cancelRentalOffer(RentalOffer calldata _offer) external whenNotPaused { - _cancelRentalOffer(_offer); - } - function cancelRentalOffer(RentalOfferLegacy calldata _offer) external whenNotPaused { - RentalOffer memory _parsedOffer = RentalOffer({ - nonce: _offer.nonce, - tokenAddress: _offer.tokenAddress, - tokenId: _offer.tokenId, - tokenAmount: _offer.tokenAmount, - commitmentId: _offer.commitmentId, - lender: _offer.lender, - borrower: _offer.borrower, - feeTokenAddress: _offer.feeTokenAddress, - feeAmountPerSecond: _offer.feeAmountPerSecond, - deadline: _offer.deadline, - minDuration: 0, - roles: _offer.roles, - rolesData: _offer.rolesData - }); - _cancelRentalOffer(_parsedOffer); - } - function _cancelRentalOffer(RentalOffer memory _offer) internal { bytes32 _offerHash = LibOriumSftMarketplace.hashRentalOffer(_offer); - require(isCreated[_offerHash], "OriumSftMarketplace: Offer not created"); - require(msg.sender == _offer.lender, "OriumSftMarketplace: Only lender can cancel a rental offer"); + require(isCreated[_offerHash], 'OriumSftMarketplace: Offer not created'); + require(msg.sender == _offer.lender, 'OriumSftMarketplace: Only lender can cancel a rental offer'); require( nonceDeadline[_offer.lender][_offer.nonce] > block.timestamp, - "OriumSftMarketplace: Nonce expired or not used yet" + 'OriumSftMarketplace: Nonce expired or not used yet' ); IERC7589 _rolesRegistry = IERC7589( @@ -328,7 +217,10 @@ contract OriumSftMarketplace is Initializable, OwnableUpgradeable, PausableUpgra // if There are no active rentals, release tokens (else, tokens will be released via `batchReleaseTokens`) // this is ok for single-role tokens, but tokens with multiple roles might revert if another non-revocable role exists // if token amount is 0, it means that the tokens were already released, trying to release it again would revert the transaction - if (rentals[_offerHash].expirationDate < block.timestamp && _rolesRegistry.tokenAmountOf(_offer.commitmentId) > 0) { + if ( + rentals[_offerHash].expirationDate < block.timestamp && + _rolesRegistry.tokenAmountOf(_offer.commitmentId) > 0 + ) { _rolesRegistry.releaseTokens(_offer.commitmentId); } @@ -342,38 +234,14 @@ contract OriumSftMarketplace is Initializable, OwnableUpgradeable, PausableUpgra * @dev Borrower needs to approve marketplace to revoke the roles. * @param _offer The rental offer struct. It should be the same as the one used to create the offer. */ - function endRental(RentalOffer calldata _offer) external whenNotPaused { - _endRental(_offer); - } - - function endRental(RentalOfferLegacy calldata _offer) external whenNotPaused { - RentalOffer memory _parsedOffer = RentalOffer({ - nonce: _offer.nonce, - tokenAddress: _offer.tokenAddress, - tokenId: _offer.tokenId, - tokenAmount: _offer.tokenAmount, - commitmentId: _offer.commitmentId, - lender: _offer.lender, - borrower: _offer.borrower, - feeTokenAddress: _offer.feeTokenAddress, - feeAmountPerSecond: _offer.feeAmountPerSecond, - deadline: _offer.deadline, - minDuration: 0, - roles: _offer.roles, - rolesData: _offer.rolesData - }); - _endRental(_parsedOffer); - } - - function _endRental(RentalOffer memory _offer) internal { bytes32 _offerHash = LibOriumSftMarketplace.hashRentalOffer(_offer); - require(isCreated[_offerHash], "OriumSftMarketplace: Offer not created"); - require(msg.sender == rentals[_offerHash].borrower, "OriumSftMarketplace: Only borrower can end a rental"); + require(isCreated[_offerHash], 'OriumSftMarketplace: Offer not created'); + require(msg.sender == rentals[_offerHash].borrower, 'OriumSftMarketplace: Only borrower can end a rental'); require( rentals[_offerHash].expirationDate > block.timestamp, - "OriumSftMarketplace: There are no active Rentals" + 'OriumSftMarketplace: There are no active Rentals' ); IERC7589 _rolesRegistry = IERC7589( @@ -460,7 +328,13 @@ contract OriumSftMarketplace is Initializable, OwnableUpgradeable, PausableUpgra address[] memory _grantees, address[] memory _tokenAddresses ) external whenNotPaused { - LibOriumSftMarketplace.batchRevokeRole(_commitmentIds, _roles, _grantees, _tokenAddresses, oriumMarketplaceRoyalties); + LibOriumSftMarketplace.batchRevokeRole( + _commitmentIds, + _roles, + _grantees, + _tokenAddresses, + oriumMarketplaceRoyalties + ); } /** ######### Internals ########### **/ @@ -470,16 +344,19 @@ contract OriumSftMarketplace is Initializable, OwnableUpgradeable, PausableUpgra */ function _validateCreateRentalOffer(RentalOffer memory _offer, address _rolesRegistryAddress) internal view { require( - IOriumMarketplaceRoyalties(oriumMarketplaceRoyalties).isTrustedFeeTokenAddressForToken(_offer.tokenAddress, _offer.feeTokenAddress), - "OriumSftMarketplace: tokenAddress is not trusted" + IOriumMarketplaceRoyalties(oriumMarketplaceRoyalties).isTrustedFeeTokenAddressForToken( + _offer.tokenAddress, + _offer.feeTokenAddress + ), + 'OriumSftMarketplace: tokenAddress is not trusted' ); require( _offer.deadline <= block.timestamp + IOriumMarketplaceRoyalties(oriumMarketplaceRoyalties).maxDuration() && _offer.deadline > block.timestamp, - "OriumSftMarketplace: Invalid deadline" + 'OriumSftMarketplace: Invalid deadline' ); LibOriumSftMarketplace.validateOffer(_offer); - require(nonceDeadline[_offer.lender][_offer.nonce] == 0, "OriumSftMarketplace: nonce already used"); + require(nonceDeadline[_offer.lender][_offer.nonce] == 0, 'OriumSftMarketplace: nonce already used'); if (_offer.commitmentId != 0) { uint256 _commitmentNonce = commitmentIdToNonce[_rolesRegistryAddress][_offer.commitmentId]; @@ -487,7 +364,7 @@ contract OriumSftMarketplace is Initializable, OwnableUpgradeable, PausableUpgra if (_commitmentNonce != 0) { require( nonceDeadline[_offer.lender][_commitmentNonce] < block.timestamp, - "OriumSftMarketplace: commitmentId is in an active rental offer" + 'OriumSftMarketplace: commitmentId is in an active rental offer' ); } @@ -502,7 +379,7 @@ contract OriumSftMarketplace is Initializable, OwnableUpgradeable, PausableUpgra } else { require( IERC1155(_offer.tokenAddress).balanceOf(msg.sender, _offer.tokenId) >= _offer.tokenAmount, - "OriumSftMarketplace: caller does not have enough balance for the token" + 'OriumSftMarketplace: caller does not have enough balance for the token' ); } } diff --git a/contracts/libraries/LibOriumSftMarketplace.sol b/contracts/libraries/LibOriumSftMarketplace.sol index 3dfd7a7..9acc682 100644 --- a/contracts/libraries/LibOriumSftMarketplace.sol +++ b/contracts/libraries/LibOriumSftMarketplace.sol @@ -23,22 +23,6 @@ struct RentalOffer { bytes[] rolesData; } -/// @dev Rental offer info. -struct RentalOfferLegacy { - address lender; - address borrower; - address tokenAddress; - uint256 tokenId; - uint256 tokenAmount; - address feeTokenAddress; - uint256 feeAmountPerSecond; - uint256 nonce; - uint256 commitmentId; - uint64 deadline; - bytes32[] roles; - bytes[] rolesData; -} - struct CommitAndGrantRoleParams { uint256 commitmentId; address tokenAddress;