Skip to content

Commit

Permalink
feat: emit events
Browse files Browse the repository at this point in the history
  • Loading branch information
CanvasL committed Aug 6, 2024
1 parent 0abc19f commit 88086b1
Show file tree
Hide file tree
Showing 12 changed files with 249 additions and 58 deletions.
File renamed without changes.
File renamed without changes.
128 changes: 109 additions & 19 deletions src/Marketplace.sol → contracts/Marketplace.sol
Original file line number Diff line number Diff line change
Expand Up @@ -53,22 +53,44 @@ contract Marketplace is IMarketplace, Ownable {
_feePoints = feePoints;
}

function getListingInfo(address accessToken, uint256 tokenId) external view returns (ListingInfo memory) {
/**
* @inheritdoc IMarketplace
*/
function getListingInfo(
address accessToken,
uint256 tokenId
) external view returns (ListingInfo memory) {
return _listings[accessToken][tokenId];
}

function getRentalInfo(address accessToken, uint256 tokenId, address tenant) external view returns (RentalInfo memory) {
/**
* @inheritdoc IMarketplace
*/
function getRentalInfo(
address accessToken,
uint256 tokenId,
address tenant
) external view returns (RentalInfo memory) {
return _rentals[accessToken][tokenId][tenant];
}

/**
* @inheritdoc IMarketplace
*/
function setFeePoints(uint256 feePoints) external onlyOwner {
_feePoints = feePoints;
}

/**
* @inheritdoc IMarketplace
*/
function setTreasury(address payable treasury) external onlyOwner {
_treasury = treasury;
}

/**
* @inheritdoc IMarketplace
*/
function addRentCurrencies(
address[] memory rentCurrencies
) external onlyOwner {
Expand All @@ -77,6 +99,9 @@ contract Marketplace is IMarketplace, Ownable {
}
}

/**
* @inheritdoc IMarketplace
*/
function removeRentCurrencies(
address[] memory rentCurrencies
) external onlyOwner {
Expand All @@ -85,11 +110,12 @@ contract Marketplace is IMarketplace, Ownable {
}
}

/**
* @inheritdoc IMarketplace
*/
function list(ListArgs memory args) public {
address accessToken = ACCESS_TOKEN_FACTORY.getAccessToken(
args.product
);
if(accessToken == address(0)) {
address accessToken = ACCESS_TOKEN_FACTORY.getAccessToken(args.product);
if (accessToken == address(0)) {
accessToken = ACCESS_TOKEN_FACTORY.createAccessToken(args.product);
}
require(
Expand All @@ -103,7 +129,8 @@ contract Marketplace is IMarketplace, Ownable {
"invalid maximum rental days"
);
require(
args.rentCurrency == NATIVE_TOKEN || supportedRentCurrencies[args.rentCurrency],
args.rentCurrency == NATIVE_TOKEN ||
supportedRentCurrencies[args.rentCurrency],
"unsupported rent currency"
);

Expand All @@ -122,28 +149,45 @@ contract Marketplace is IMarketplace, Ownable {
address(this),
args.tokenId
);

emit List(
msg.sender,
args.product,
accessToken,
args.tokenId,
args.minRentalDays,
args.maxRentalDays,
args.rentCurrency,
args.dailyRent,
args.rentRecipient
);
}

/**
* @inheritdoc IMarketplace
*/
function delist(DelistArgs memory args) public {
ListingInfo storage listing = _listings[args.accessToken][
args.tokenId
];
ListingInfo storage listing = _listings[args.accessToken][args.tokenId];
require(listing.owner == msg.sender, "not listing owner");
listing.status = ListingStatus.Delisted;

emit Delist(msg.sender, args.accessToken, args.tokenId);
}

/**
* @inheritdoc IMarketplace
*/
function relist(RelistArgs memory args) public {
ListingInfo storage listing = _listings[args.accessToken][
args.tokenId
];
ListingInfo storage listing = _listings[args.accessToken][args.tokenId];
require(listing.owner == msg.sender, "not listing owner");
require(args.minRentalDays > 0, "invalid minimum rental days");
require(
args.maxRentalDays >= args.minRentalDays,
"invalid maximum rental days"
);
require(
args.rentCurrency == NATIVE_TOKEN || supportedRentCurrencies[args.rentCurrency],
args.rentCurrency == NATIVE_TOKEN ||
supportedRentCurrencies[args.rentCurrency],
"unsupported rent currency"
);

Expand All @@ -153,8 +197,22 @@ contract Marketplace is IMarketplace, Ownable {
listing.dailyRent = args.dailyRent;
listing.rentRecipient = args.rentRecipient;
listing.status = ListingStatus.Listing;

emit Relist(
msg.sender,
args.accessToken,
args.tokenId,
args.minRentalDays,
args.maxRentalDays,
args.rentCurrency,
args.dailyRent,
args.rentRecipient
);
}

/**
* @inheritdoc IMarketplace
*/
function rent(RentArgs memory args) public payable {
require(
_rentals[args.accessToken][args.tokenId][args.tenant].status ==
Expand Down Expand Up @@ -190,12 +248,20 @@ contract Marketplace is IMarketplace, Ownable {
args.prepaidRent
);
// Mint access token to tenant
AccessToken(args.accessToken).mint(
AccessToken(args.accessToken).mint(args.tenant, args.tokenId);

emit Rent(
args.tenant,
args.tokenId
args.accessToken,
args.tokenId,
args.rentalDays,
args.prepaidRent
);
}

/**
* @inheritdoc IMarketplace
*/
function payRent(PayRentArgs memory args) public payable {
ListingInfo memory listing = _listings[args.accessToken][args.tokenId];
RentalInfo storage rental = _rentals[args.accessToken][args.tokenId][
Expand All @@ -209,8 +275,18 @@ contract Marketplace is IMarketplace, Ownable {

// Pay rent
_payRent(listing, rental, args.rent);

emit PayRent(
args.tenant,
args.accessToken,
args.tokenId,
args.rent
);
}

/**
* @inheritdoc IMarketplace
*/
function endLease(EndLeaseArgs memory args) public {
RentalInfo storage rental = _rentals[args.accessToken][args.tokenId][
args.tenant
Expand All @@ -227,12 +303,20 @@ contract Marketplace is IMarketplace, Ownable {
// Burn tenant's access token
AccessToken(args.accessToken).burn(args.tokenId);
rental.status = RentalStatus.EndedOrNotExist;

emit EndLease(
args.tenant,
args.accessToken,
args.tokenId,
msg.sender
);
}

/**
* @inheritdoc IMarketplace
*/
function withdraw(WithdrawArgs memory args) public {
ListingInfo storage listing = _listings[args.accessToken][
args.tokenId
];
ListingInfo storage listing = _listings[args.accessToken][args.tokenId];
require(listing.owner == msg.sender, "not listing owner");
require(
!AccessToken(args.accessToken).isExist(args.tokenId),
Expand All @@ -245,6 +329,12 @@ contract Marketplace is IMarketplace, Ownable {
listing.owner,
args.tokenId
);

emit Withdraw(
msg.sender,
args.accessToken,
args.tokenId
);
}

function _payRent(
Expand Down
40 changes: 40 additions & 0 deletions contracts/interfaces/IMarketplace.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;

import {IMarketplaceStructs} from "./IMarketplaceStructs.sol";
import {IMarketplaceEvents} from "./IMarketplaceEvents.sol";

interface IMarketplace is IMarketplaceStructs, IMarketplaceEvents {
function getListingInfo(
address accessToken,
uint256 tokenId
) external view returns (ListingInfo memory);

function getRentalInfo(
address accessToken,
uint256 tokenId,
address tenant
) external view returns (RentalInfo memory);

function setFeePoints(uint256 feePoints) external;

function setTreasury(address payable treasury) external;

function addRentCurrencies(address[] memory rentCurrencies) external;

function removeRentCurrencies(address[] memory rentCurrencies) external;

function list(ListArgs memory args) external;

function delist(DelistArgs memory args) external;

function relist(RelistArgs memory args) external;

function rent(RentArgs memory args) external payable;

function payRent(PayRentArgs memory args) external payable;

function endLease(EndLeaseArgs memory args) external;

function withdraw(WithdrawArgs memory args) external;
}
61 changes: 61 additions & 0 deletions contracts/interfaces/IMarketplaceEvents.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;

interface IMarketplaceEvents {
event List(
address indexed owner,
address indexed product,
address accessToken,
uint256 indexed tokenId,
uint256 minRentalDays,
uint256 maxRentalDays,
address rentCurrency,
uint256 dailyRent,
address rentRecipient
);

event Delist(
address indexed owner,
address indexed accessToken,
uint256 indexed tokenId
);

event Relist(
address indexed owner,
address indexed accessToken,
uint256 indexed tokenId,
uint256 minRentalDays,
uint256 maxRentalDays,
address rentCurrency,
uint256 dailyRent,
address rentRecipient
);

event Rent(
address indexed tenant,
address indexed accessToken,
uint256 indexed tokenId,
uint256 rentalDays,
uint256 prepaidRent
);

event PayRent(
address indexed tenant,
address indexed accessToken,
uint256 indexed tokenId,
uint256 rent
);

event EndLease(
address indexed tenant,
address indexed accessToken,
uint256 indexed tokenId,
address operator
);

event Withdraw(
address indexed owner,
address indexed accessToken,
uint256 indexed tokenId
);
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;

interface IMarketplace {
interface IMarketplaceStructs {
// Statuses of a listing. WithdrawnOrNotExist, which is 0, is effectively the same as never listed before.
enum ListingStatus {
WithdrawnOrNotExist,
Expand Down
File renamed without changes.
2 changes: 1 addition & 1 deletion foundry.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[profile.default]
src = "src"
src = "contracts"
out = "out"
libs = ["dependencies"]
auto_detect_remappings = true
Expand Down
4 changes: 2 additions & 2 deletions test/AccessToken.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
pragma solidity ^0.8.24;

import {Clones} from "@openzeppelin/contracts/proxy/Clones.sol";
import {AccessToken} from "../src/AccessToken.sol";
import {IProduct} from "../src/interfaces/IProduct.sol";
import {AccessToken} from "../contracts/AccessToken.sol";
import {IProduct} from "../contracts/interfaces/IProduct.sol";
import {MockProduct} from "./mocks/MockProduct.sol";
import "forge-std/src/Test.sol";

Expand Down
6 changes: 3 additions & 3 deletions test/AccessTokenFactory.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ pragma solidity ^0.8.24;

import {Clones} from "@openzeppelin/contracts/proxy/Clones.sol";
import {ERC721} from "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import {AccessTokenFactory} from "../src/AccessTokenFactory.sol";
import {AccessToken} from "../src/AccessToken.sol";
import {IProduct} from "../src/interfaces/IProduct.sol";
import {AccessTokenFactory} from "../contracts/AccessTokenFactory.sol";
import {AccessToken} from "../contracts/AccessToken.sol";
import {IProduct} from "../contracts/interfaces/IProduct.sol";
import {MockProduct} from "./mocks/MockProduct.sol";
import "forge-std/src/Test.sol";

Expand Down
Loading

0 comments on commit 88086b1

Please sign in to comment.