Co-Working Space Access Token Contract
// Co-Working Space Access Token Contract : Built By DAO V 0.01.0
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.28;
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
import "@openzeppelin/contracts/access/AccessControl.sol";
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
import "@openzeppelin/contracts/utils/Counters.sol";
contract CoWorkingSpaceAccessToken is ERC721URIStorage, AccessControl, ReentrancyGuard {
using Counters for Counters.Counter;
Counters.Counter private _tokenIdCounter;
bytes32 public constant ADMIN_ROLE = keccak256("ADMIN_ROLE");
bytes32 public constant SPACE_MANAGER_ROLE = keccak256("SPACE_MANAGER_ROLE");
bytes32 public constant UMBRELLA_CONTRACT_ROLE = keccak256("UMBRELLA_CONTRACT_ROLE");
// Metadata for co-working space access
struct SpaceAccessDetails {
uint256 expirationTimestamp; // Expiration time for the token (daily, weekly, monthly use)
bool isRenewable; // Whether the token can be renewed for continued access
}
// Mapping from token ID to co-working space access details
mapping(uint256 => SpaceAccessDetails) public spaceAccessDetails;
// Events
event CoWorkingAccessTokenMinted(address indexed to, uint256 tokenId, bool isRenewable, uint256 expiration);
event CoWorkingAccessTokenBurned(uint256 tokenId);
// Instead of a constructor, using an initialize function to allow deployment by the umbrella contract
/**
* @dev Initialize the Co-Working Space Access Token Contract.
* @param name The name of the token (e.g., "DAO CoWorking Space Token").
* @param symbol The symbol of the token (e.g., "DCS").
* @param umbrellaContract The address of the umbrella contract deploying this instance.
* Note: Ensure these variables are set properly during deployment for specific needs.
*/
function initialize(string memory name, string memory symbol, address umbrellaContract) external {
require(hasRole(UMBRELLA_CONTRACT_ROLE, _msgSender()), "Caller is not the umbrella contract");
_setupRole(DEFAULT_ADMIN_ROLE, umbrellaContract);
_setupRole(ADMIN_ROLE, umbrellaContract);
_setupRole(SPACE_MANAGER_ROLE, umbrellaContract);
_tokenIdCounter.increment(); // Start token IDs at 1
// Setting up ERC721 name and symbol
_name = name;
_symbol = symbol;
}
/**
* @dev Mint a new Co-Working Space Access Token.
* Only an address with the SPACE_MANAGER_ROLE can mint new tokens.
* @param to The address that will receive the minted token.
* @param isRenewable Indicates whether the token can be renewed for future access.
* @param duration The duration in seconds for which the token is valid (e.g., daily, weekly, or monthly).
* Note: Ensure to adjust "duration" based on the user's access needs when deploying.
*/
function mintSpaceAccessToken(address to, bool isRenewable, uint256 duration) external onlyRole(SPACE_MANAGER_ROLE) nonReentrant {
// Verify that the contract was approved by the umbrella contract before minting
require(hasRole(UMBRELLA_CONTRACT_ROLE, _msgSender()), "Contract must be approved by umbrella contract");
uint256 tokenId = _tokenIdCounter.current();
_safeMint(to, tokenId);
// Set URI for metadata (to be replaced with actual URI)
_setTokenURI(tokenId, "https://metadata.uri/for/CoWorkingAccessToken"); // TODO: Replace with actual metadata URI for the specific co-working space
// Set co-working space access details
uint256 expirationTimestamp = block.timestamp + duration;
spaceAccessDetails[tokenId] = SpaceAccessDetails({
expirationTimestamp: expirationTimestamp,
isRenewable: isRenewable
});
_tokenIdCounter.increment();
emit CoWorkingAccessTokenMinted(to, tokenId, isRenewable, expirationTimestamp);
}
/**
* @dev Burn a Co-Working Space Access Token.
* Only the token owner or an admin can burn the token.
* @param tokenId The ID of the token to be burned.
* Note: Ensure token holders are aware of the conditions under which tokens may be burned.
*/
function burnSpaceAccessToken(uint256 tokenId) external nonReentrant {
require(_isApprovedOrOwner(_msgSender(), tokenId) || hasRole(ADMIN_ROLE, _msgSender()), "Unauthorized to burn");
_burn(tokenId);
delete spaceAccessDetails[tokenId];
emit CoWorkingAccessTokenBurned(tokenId);
}
/**
* @dev Check if a token is still valid.
* Tokens expire based on their duration (e.g., daily, weekly, or monthly).
* @param tokenId The ID of the token to check.
* @return True if the token is still valid, false otherwise.
* Note: Useful for determining co-working space entry eligibility.
*/
function isTokenValid(uint256 tokenId) external view returns (bool) {
require(_exists(tokenId), "Token does not exist");
return block.timestamp <= spaceAccessDetails[tokenId].expirationTimestamp;
}
/**
* @dev Override transfer function to prevent transfers of co-working space access tokens.
* Co-working access tokens are non-transferable.
* @param from Address from which token is being transferred.
* @param to Address to which token is being transferred.
* @param tokenId ID of the token being transferred.
* Note: Space tokens are non-transferable to maintain strict access control.
*/
function _transfer(address from, address to, uint256 tokenId) internal pure override {
revert("Co-Working Access Tokens are non-transferable");
}
}
/*
Key Features:
- **Co-Working Space Access Token Contract**: Manages tokens for access to DAO-managed co-working spaces.
- **Umbrella Contract Integration**: This contract is intended to be deployed and initialized by the **Umbrella Access Token Contract**.
- **Role-Based Access Control**: Uses role-based control with ADMIN_ROLE, SPACE_MANAGER_ROLE, and UMBRELLA_CONTRACT_ROLE to manage minting, burning, and overall contract administration.
- **Minting and Burning Mechanisms**: Only space managers can mint tokens, while only the token owner or admins can burn them.
- **Renewable vs. Non-Renewable**: Tokens can be issued as either **renewable** or **non-renewable** based on user needs for co-working access.
- **Non-Transferable**: Co-working space access tokens cannot be transferred between users, maintaining strict control over access.
- **Validity Checks**: Includes functionality to determine if a token is still valid based on its expiration.
- **Security Features**: Implements ReentrancyGuard to prevent reentrancy attacks, adding another layer of security to mint and burn processes.
- **Deployment Considerations**: The following variables should be set during deployment:
- **name** and **symbol** during `initialize()` for token identification.
- **duration** parameter in `mintSpaceAccessToken()` to match the user's access duration needs.
- **metadata URI** in `_setTokenURI()` to provide accurate details for the co-working space access.
*/
Last updated