Access Token Umbrella Contract

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.28;

import "@openzeppelin/contracts/access/AccessControl.sol";
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
import "@openzeppelin/contracts/utils/Counters.sol";
import "@openzeppelin/contracts/proxy/Clones.sol";

interface IAccessTokenSubContract {
    function initialize(string memory _name, string memory _symbol, address _admin, uint256 _duration, uint8 _tokenType) external;
}

contract UmbrellaAccessTokenContract is AccessControl, ReentrancyGuard {
    using Counters for Counters.Counter;
    Counters.Counter private _subContractCounter;

    bytes32 public constant ADMIN_ROLE = keccak256("ADMIN_ROLE");
    bytes32 public constant REVIEWER_ROLE = keccak256("REVIEWER_ROLE");

    address public immutable subContractTemplate;

    struct SubContractInfo {
        address contractAddress;
        string name;
        uint256 createdAt;
        uint8 tokenType; // 0 = Gym, 1 = Event, 2 = Seminar, etc.
        bool approved;
    }

    mapping(uint256 => SubContractInfo) public subContracts;
    mapping(address => bool) public existingSubContracts;

    event SubContractCreated(uint256 indexed subContractId, address contractAddress, string name, uint8 tokenType);
    event SubContractApproved(uint256 indexed subContractId, address contractAddress);

    error Unauthorized();
    error SubContractAlreadyApproved(uint256 subContractId);
    error InvalidSubContractAddress(address contractAddress);

    constructor(address _subContractTemplate) {
        require(_subContractTemplate != address(0), "Invalid template address");
        subContractTemplate = _subContractTemplate;
        _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);
        _setupRole(ADMIN_ROLE, msg.sender);
    }

    /**
     * @dev Create a new Access Token sub-contract using a clone of the template.
     * Only an address with the ADMIN_ROLE can initiate this process.
     * @param name The name of the sub-contract token (e.g., "Gym Access Token").
     * @param symbol The symbol of the sub-contract token (e.g., "GYM").
     * @param duration The duration for which access tokens issued by this sub-contract will be valid.
     * @param tokenType The type of the token (e.g., 0 for Gym, 1 for Event, etc.).
     */
    function createSubContract(string memory name, string memory symbol, uint256 duration, uint8 tokenType) external onlyRole(ADMIN_ROLE) nonReentrant {
        address clone = Clones.clone(subContractTemplate);
        IAccessTokenSubContract(clone).initialize(name, symbol, msg.sender, duration, tokenType);

        uint256 subContractId = _subContractCounter.current();
        subContracts[subContractId] = SubContractInfo({
            contractAddress: clone,
            name: name,
            createdAt: block.timestamp,
            tokenType: tokenType,
            approved: false
        });

        existingSubContracts[clone] = true;
        _subContractCounter.increment();
        emit SubContractCreated(subContractId, clone, name, tokenType);
    }

    /**
     * @dev Approve a newly created Access Token sub-contract.
     * Only an address with the REVIEWER_ROLE can approve a sub-contract.
     * @param subContractId The ID of the sub-contract to approve.
     */
    function approveSubContract(uint256 subContractId) external onlyRole(REVIEWER_ROLE) nonReentrant {
        SubContractInfo storage subContract = subContracts[subContractId];
        if (subContract.approved) {
            revert SubContractAlreadyApproved(subContractId);
        }
        subContract.approved = true;
        emit SubContractApproved(subContractId, subContract.contractAddress);
    }

    /**
     * @dev Check if a sub-contract has been approved and is valid.
     * @param subContractAddress The address of the sub-contract to verify.
     * @return True if the sub-contract is approved and valid, otherwise false.
     */
    function isSubContractApproved(address subContractAddress) external view returns (bool) {
        if (!existingSubContracts[subContractAddress]) {
            revert InvalidSubContractAddress(subContractAddress);
        }
        for (uint256 i = 0; i < _subContractCounter.current(); i++) {
            if (subContracts[i].contractAddress == subContractAddress) {
                return subContracts[i].approved;
            }
        }
        return false;
    }
}

/*
 Key Features:
 - **Umbrella Contract**: Central contract that manages the creation and approval of all access token sub-contracts.
 - **Role-Based Access Control**: Admins can create sub-contracts; reviewers are responsible for approving them.
 - **Sub-Contract Creation**: Uses OpenZeppelin's Clones library to create lightweight copies of a sub-contract template.
 - **Approval Process**: Each new sub-contract must be reviewed and approved by an authorized reviewer before becoming operational.
 - **Scalable Framework**: The umbrella contract allows consistent implementation of new access tokens while keeping flexibility for different access types.
 - **Notification Hooks**: Events are in place to help integrate off-chain notifications for contract creation and approval status changes in the future.
*/

Umbrella Access Token Contract

The Umbrella Access Token Contract is a foundational component of the Built By DAO ecosystem designed to manage the creation, customization, and deployment of various Access Token Sub-Contracts. This contract serves as the central authority for defining, approving, and managing access tokens that grant specific permissions within the DAO, such as entry to community amenities, events, and more. The umbrella contract ensures all sub-contracts are consistent with the broader community standards, while still offering the flexibility to customize tokens for diverse use cases.

Key Objectives and Features

Centralized Management of Access Token Sub-Contracts

  • The Umbrella Access Token Contract provides a unified framework for creating and managing multiple Access Token Sub-Contracts. Each sub-contract corresponds to a specific type of access—such as gym passes, event tickets, or seminar registrations—allowing the DAO to issue permissions in a controlled and efficient manner.

  • By employing an umbrella approach, the contract ensures that all sub-contracts are aligned with the community’s standards while also reducing redundancy and ensuring a scalable approach to creating new access types.

Role-Based Access Control

  • The contract utilizes role-based access control with two primary roles: Administrators and Reviewers.

    • Administrators are responsible for creating sub-contracts and inputting specific configurations such as token names, symbols, and access duration.

    • Reviewers are tasked with approving new sub-contracts, ensuring they meet community standards and adhere to the DAO's access policies.

  • This role separation allows for a layered approach to control, where creation and approval are handled by different sets of users, ensuring that only vetted and community-approved sub-contracts are deployed.

Sub-Contract Creation Using Clones

  • The Umbrella Access Token Contract employs OpenZeppelin's Clones library to create lightweight, gas-efficient copies of a template sub-contract. This makes the system highly scalable and cost-effective, as deploying each sub-contract is significantly less resource-intensive than creating new contracts from scratch.

  • Each sub-contract clone is customizable based on the access type. For instance, administrators can configure contracts to issue tokens with specific features such as one-time access or multi-use passes. The customization options ensure that each sub-contract can accommodate the unique requirements of different community amenities or events.

Approval Process for New Sub-Contracts

  • Once a new sub-contract is created, it must be reviewed and approved by a user with the REVIEWER_ROLE. This two-step process—creation by administrators followed by approval by reviewers—ensures that every new access token is scrutinized for compliance with DAO standards before it becomes operational.

  • This mechanism not only helps maintain a high standard for issued access tokens but also provides accountability and oversight in the creation of new token types.

Sub-Contract Details and Use Cases

  • The Access Token Sub-Contracts created by the umbrella contract are responsible for managing the issuance, validity, and expiration of specific access tokens. Each sub-contract can have distinct attributes such as:

    • Access Duration: Defines how long the token is valid, for instance, 24 hours for a gym pass or the duration of a concert for event tickets.

    • Type-Specific Permissions: Each sub-contract can specify particular features, such as whether tokens can be transferred, renewed, or used multiple times.

  • Examples of sub-contracts include:

    • Gym Access Token Sub-Contract: Issues tokens that provide access to the DAO gym facilities, configurable to include restricted hours or continuous access depending on the holder's membership.

    • Event Access Token Sub-Contract: Issues tokens for one-time or recurring events, such as concerts, seminars, or exclusive meetups. Event-specific attributes can be configured, such as single-entry or multi-event passes.

Scalability and Uniformity

  • The umbrella contract enforces uniformity by providing a framework within which all sub-contracts operate. This means that while sub-contracts can be customized for individual needs, they must adhere to standardized practices—such as requiring review and approval before becoming active.

  • This uniformity ensures that all access tokens, regardless of their type, provide a similar user experience and are compatible with the broader ecosystem. At the same time, scalability is achieved through the use of clones, which allows new sub-contracts to be created efficiently without incurring the high costs of deploying entirely new contracts each time.

Future Governance and Transition

  • Currently, the Umbrella Access Token Contract is managed by specific administrators with the REVIEWER_ROLE handling approvals. However, the contract has been designed to eventually transition to DAO governance, where members holding specific governance NFTs can vote on the creation and approval of sub-contracts.

  • This transition will ensure that as the DAO grows, members have more direct influence over which types of access tokens are issued and the specific use cases they address.

Summary of Contract Flow

  • Creation: An administrator uses the umbrella contract to create a new Access Token Sub-Contract, defining its name, symbol, duration, and type.

  • Approval: A reviewer must then approve the sub-contract to activate it for use. Without approval, the sub-contract cannot issue tokens, ensuring quality control.

  • Issuance and Management: Once approved, the sub-contract issues access tokens to eligible users, who can use them for entry to amenities, events, or services as defined by the sub-contract.

Use Cases for Access Token Sub-Contracts

Below is a list of potential Access Token Sub-Contracts that could be created under the umbrella contract. Each sub-contract serves a distinct purpose and can be linked to the relevant cloned contract for more details:

Gym Access Token Sub-Contract

  • Provides access to gym facilities, either for one-time entry, restricted hours, or continuous membership-based access.

  • Issues tokens for one-time or recurring events, such as concerts, seminars, or community meetups. Supports both single-use and multi-use passes.

Seminar Access Token Sub-Contract

  • Provides entry to educational seminars or training sessions, which could be recurring or single-session based.

  • Grants access to DAO-managed co-working spaces. Tokens could provide access for daily, weekly, or monthly use depending on the member's needs.

Exclusive Investor Event Access Sub-Contract

  • Issues tokens exclusively for investor-level NFT holders, granting them access to exclusive events, meetings, or briefings.

Residential Amenity Access Token Sub-Contract

  • Grants temporary or continuous access to residential amenities, such as a pool, lounge area, or shared kitchen facilities.

Voting Participation Access Token Sub-Contract

  • Allows access to DAO governance voting sessions, specifically for members who qualify for limited-time governance access without permanent governance NFTs.

Workshop or Skill Training Access Token Sub-Contract

  • Issues tokens to members who wish to participate in skills workshops or training programs, such as carpentry, coding, or other community-driven training events.

Guest Pass Access Token Sub-Contract

  • Provides limited-time guest passes for members to invite non-members to specific amenities or events.

Community Festival Access Token Sub-Contract

  • Issues tokens for community-driven festivals, celebrations, or gatherings, allowing for a variety of participation levels, such as general admission or VIP access.

Benefits to the DAO Community

The Umbrella Access Token Contract streamlines the management of access across various aspects of the DAO's activities, from shared amenities to exclusive events. It provides a secure, scalable, and efficient method for issuing access tokens that are aligned with the DAO’s values and community standards. The use of role-based control, template cloning, and an approval process helps balance the need for flexibility in token issuance with the overarching need for accountability and governance, ultimately ensuring that every issued access token is fit for purpose and contributes to the healthy growth of the community.

Last updated

Logo

© Built By DAO Holdings LLC