Skip to content

Commit

Permalink
fix: Create Offers reverts
Browse files Browse the repository at this point in the history
  • Loading branch information
EDUARDO MELO DE SIQUEIRA authored and EDUARDO MELO DE SIQUEIRA committed Jun 17, 2024
1 parent 123ea0c commit 473e371
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 4 deletions.
17 changes: 14 additions & 3 deletions contracts/NftRentalMarketplace.sol
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ contract NftRentalMarketplace is Initializable, OwnableUpgradeable, PausableUpgr
* @dev To optimize for gas, only the offer hash is stored on-chain
* @param _offer The rental offer struct.
*/

function createRentalOffer(RentalOffer calldata _offer) external whenNotPaused {
LibNftRentalMarketplace.validateCreateRentalOfferParams(
oriumMarketplaceRoyalties,
Expand All @@ -118,7 +119,7 @@ contract NftRentalMarketplace is Initializable, OwnableUpgradeable, PausableUpgr
roleDeadline[_offer.roles[i]][_offer.tokenAddress][_offer.tokenId] < block.timestamp,
'NftRentalMarketplace: role still has an active offer'
);
roleDeadline[_offer.roles[i]][_offer.tokenAddress][_offer.tokenId] = _offer.deadline;
roleDeadline[_offer.roles[i]][_offer.tokenAddress][_offer.tokenId] = _offer.deadline - _offer.minDuration;
}

bytes32 _offerHash = LibNftRentalMarketplace.hashRentalOffer(_offer);
Expand Down Expand Up @@ -149,7 +150,6 @@ contract NftRentalMarketplace is Initializable, OwnableUpgradeable, PausableUpgr
function acceptRentalOffer(RentalOffer calldata _offer, uint64 _duration) external whenNotPaused {
bytes32 _offerHash = LibNftRentalMarketplace.hashRentalOffer(_offer);
uint64 _expirationDate = uint64(block.timestamp + _duration);

LibNftRentalMarketplace.validateAcceptRentalOfferParams(
_offer.borrower,
_offer.minDuration,
Expand Down Expand Up @@ -180,6 +180,12 @@ contract NftRentalMarketplace is Initializable, OwnableUpgradeable, PausableUpgr
_offer.rolesData
);

for (uint256 i = 0; i < _offer.roles.length; i++) {
if(_expirationDate > roleDeadline[_offer.roles[i]][_offer.tokenAddress][_offer.tokenId]) {
roleDeadline[_offer.roles[i]][_offer.tokenAddress][_offer.tokenId] = _expirationDate;
}
}

rentals[_offerHash] = Rental({ borrower: msg.sender, expirationDate: _expirationDate });

emit RentalStarted(_offer.lender, _offer.nonce, msg.sender, _expirationDate);
Expand Down Expand Up @@ -282,7 +288,12 @@ contract NftRentalMarketplace is Initializable, OwnableUpgradeable, PausableUpgr

nonceDeadline[msg.sender][_offer.nonce] = uint64(block.timestamp);
for (uint256 i = 0; i < _offer.roles.length; i++) {
roleDeadline[_offer.roles[i]][_offer.tokenAddress][_offer.tokenId] = uint64(block.timestamp);

if(rentals[_offerHash].expirationDate > uint64(block.timestamp)) {
roleDeadline[_offer.roles[i]][_offer.tokenAddress][_offer.tokenId] = rentals[_offerHash].expirationDate;
}else {
roleDeadline[_offer.roles[i]][_offer.tokenAddress][_offer.tokenId] = uint64(block.timestamp);
}
}
emit RentalOfferCancelled(_offer.lender, _offer.nonce);
}
Expand Down
44 changes: 43 additions & 1 deletion test/NftRentalMarketplace.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,15 @@ import { loadFixture, time } from '@nomicfoundation/hardhat-network-helpers'
import { expect } from 'chai'
import { toWei } from '../utils/bignumber'
import { GrantRoleParams, RentalOffer, RoyaltyInfo } from '../utils/types'
import { AddressZero, EMPTY_BYTES, ONE_DAY, ONE_HOUR, THREE_MONTHS } from '../utils/constants'
import {
AddressZero,
EMPTY_BYTES,
ONE_DAY,
ONE_HOUR,
THREE_MONTHS,
TWENTY_THREE_HOURS,
TEN_MINUTES,
} from '../utils/constants'
import { randomBytes } from 'crypto'
import { UNIQUE_ROLE, USER_ROLE } from '../utils/roles'
import {
Expand Down Expand Up @@ -163,6 +171,28 @@ describe('NftRentalMarketplace', () => {
rentalOffer.rolesData,
)
})
it('Should create more than one rental offer for the same role, if the (Deadline - minduration) is reached ', async () => {
rentalOffer.minDuration = TWENTY_THREE_HOURS
await marketplace.connect(lender).createRentalOffer(rentalOffer)
await time.increase(ONE_HOUR)
rentalOffer.deadline = Number(await time.latest()) + ONE_DAY
rentalOffer.nonce = `0x${randomBytes(32).toString('hex')}`
await expect(marketplace.connect(lender).createRentalOffer(rentalOffer))
.to.emit(marketplace, 'RentalOfferCreated')
.withArgs(
rentalOffer.nonce,
rentalOffer.tokenAddress,
rentalOffer.tokenId,
rentalOffer.lender,
rentalOffer.borrower,
rentalOffer.feeTokenAddress,
rentalOffer.feeAmountPerSecond,
rentalOffer.deadline,
rentalOffer.minDuration,
rentalOffer.roles,
rentalOffer.rolesData,
)
})
it('Should create rental offer if token is already deposited in rolesRegistry', async function () {
await mockERC721.connect(lender).approve(await rolesRegistry.getAddress(), tokenId)
await rolesRegistry.connect(lender).grantRole({
Expand Down Expand Up @@ -191,6 +221,7 @@ describe('NftRentalMarketplace', () => {
rentalOffer.rolesData,
)
})

it('Should NOT create a rental offer if contract is paused', async () => {
await marketplace.connect(operator).pause()
await expect(marketplace.connect(lender).createRentalOffer(rentalOffer)).to.be.revertedWith(
Expand Down Expand Up @@ -272,6 +303,17 @@ describe('NftRentalMarketplace', () => {
'NftRentalMarketplace: role still has an active offer',
)
})
it('Should NOT create more than one rental when the (Deadline - minduration) is not be reached. ', async () => {
rentalOffer.nonce = `0x${randomBytes(32).toString('hex')}`
rentalOffer.minDuration = TWENTY_THREE_HOURS
await marketplace.connect(lender).createRentalOffer(rentalOffer)
await time.increase(TEN_MINUTES)

rentalOffer.nonce = `0x${randomBytes(32).toString('hex')}`
await expect(marketplace.connect(lender).createRentalOffer(rentalOffer)).to.be.revertedWith(
'NftRentalMarketplace: role still has an active offer',
)
})
})
})

Expand Down
2 changes: 2 additions & 0 deletions utils/constants.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { ethers } from 'hardhat'

export const RolesRegistryAddress = '0xB2aD616e84e1eF7A9ED0fA3169AAF31Ee51EA824' // RolesRegistry has the same address on all networks
export const TEN_MINUTES = 10 * 60
export const ONE_DAY = 60 * 60 * 24
export const ONE_HOUR = 60 * 60
export const TWENTY_THREE_HOURS = 23 * 60 * 60
export const THREE_MONTHS = 60 * 60 * 24 * 30 * 3
export const EMPTY_BYTES = '0x'
export const MAX_PERCENTAGE = ethers.parseEther('100')
Expand Down

0 comments on commit 473e371

Please sign in to comment.