Solidity, but explained like a system

Contracts atlas

Each card represents a contract file: what it does, which roles touch it, what can go wrong, and how it connects to the rest of ParadoxNet. Scroll, filter, and open the source inline.

19 files Search by role, function, or name Inline, read-only Solidity
Category
Perspective

ContributorRegistry

ContributorRegistry.sol
localhost: not deployed
Reputation & Contributors

Tracks contributor identity, activity, and reputation scores for paradox discovery and validation.

DISPUTE_ROLEREGISTRY_ADMIN_ROLESCORER_ROLE ContributorsGovernanceOps / PM @oz: AccessControl.sol
  • Stores a canonical profile per contributor, including reputation, contribution score, validation score, and metadata URI.
  • Separates powers via admin, scorer, and dispute roles so that scoring, listing, and arbitration can be delegated cleanly.
  • Acts as the on-chain backbone for deciding who can propose, validate, and get rewarded for paradox-related work.
  • If scorer or dispute roles are misused, contributor reputation can be distorted and downstream incentives break.
  • Any off-chain payout, staking, or governance weight that trusts this registry inherits its errors and biases.
Roles: 3 constants Events: 6 Functions: 9
Deep dive & Solidity source Key roles · functions · read-only code

Key interfaces

  • Roles: DISPUTE_ROLE, REGISTRY_ADMIN_ROLE, SCORER_ROLE
  • Top functions: adjustReputation, bumpValidationScore, getContributions, getContributor, registerContributor, setActive, setMetaURI, slashOnFalseParadox
  • Top events: ContributorMetaUpdated, ContributorRegistered, ContributorScoreUpdated, ContributorSlashed, ContributorStatus, ParadoxSubmitted

Solidity source

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

import "@openzeppelin/contracts/access/AccessControl.sol";

contract ContributorRegistry is AccessControl {
    bytes32 public constant REGISTRY_ADMIN_ROLE = keccak256("REGISTRY_ADMIN_ROLE");
    bytes32 public constant SCORER_ROLE         = keccak256("SCORER_ROLE");
    bytes32 public constant DISPUTE_ROLE        = keccak256("DISPUTE_ROLE");

    struct Contributor {
        bool active;
        uint256 reputation;
        uint256 contribScore;
        uint256 validationScore;
        string metaURI;
    }

    struct ParadoxRef {
        uint256 paradoxId;    // tokenId din ParadoxToken
        bytes32 contentHash;  // hash al paradoxului
        uint256 timestamp;
    }

    mapping(address => Contributor) public contributors;
    mapping(address => ParadoxRef[]) public contributions;
    mapping(uint256 => address) public paradoxAuthor; // paradoxId -> contributor

    event ContributorRegistered(address indexed account, string metaURI);
    event ContributorStatus(address indexed account, bool active);
    event ContributorMetaUpdated(address indexed account, string metaURI);
    event ContributorScoreUpdated(address indexed account, string field, uint256 newValue);
    event ParadoxSubmitted(address indexed account, uint256 indexed paradoxId, bytes32 contentHash);
    event ContributorSlashed(address indexed account, uint256 penalty, string reason);

    constructor(address admin) {
        require(admin != address(0), "admin=0");
        _grantRole(DEFAULT_ADMIN_ROLE, admin);
        _grantRole(REGISTRY_ADMIN_ROLE, admin);
        _grantRole(SCORER_ROLE, admin);
        _grantRole(DISPUTE_ROLE, admin);
    }

    function registerContributor(address account, string calldata metaURI)
        external
        onlyRole(REGISTRY_ADMIN_ROLE)
    {
        require(account != address(0), "account=0");
        Contributor storage c = contributors[account];
        require(!c.active, "already active");
        c.active = true;
        c.metaURI = metaURI;

        emit ContributorRegistered(account, metaURI);
        emit ContributorStatus(account, true);
    }

    function setActive(address account, bool active)
        external
        onlyRole(REGISTRY_ADMIN_ROLE)
    {
        contributors[account].active = active;
        emit ContributorStatus(account, active);
    }

    function setMetaURI(address account, string calldata metaURI)
        external
        onlyRole(REGISTRY_ADMIN_ROLE)
    {
        contributors[account].metaURI = metaURI;
        emit ContributorMetaUpdated(account, metaURI);
    }

    /// @notice Leagă un paradox (tokenId + hash) de un contributor.
    function submitParadoxRef(
        address account,
        uint256 paradoxId,
        bytes32 contentHash
    ) external onlyRole(SCORER_ROLE) {
        require(contributors[account].active, "not active");

        contributions[account].push(
            ParadoxRef({
                paradoxId: paradoxId,
                contentHash: contentHash,
                timestamp: block.timestamp
            })
        );
        paradoxAuthor[paradoxId] = account;

        contributors[account].contribScore += 1;
        emit ParadoxSubmitted(account, paradoxId, contentHash);
        emit ContributorScoreUpdated(account, "contribScore", contributors[account].contribScore);
    }

    /// @notice Adjustare reputație +/- (include slashing).
    function adjustReputation(address account, int256 delta)
        external
        onlyRole(SCORER_ROLE)
    {
        Contributor storage c = contributors[account];
        uint256 old = c.reputation;

        if (delta > 0) {
            c.reputation = old + uint256(delta);
        } else if (delta < 0) {
            uint256 absDelta = uint256(-delta);
            c.reputation = absDelta >= old ? 0 : old - absDelta;
        }

        emit ContributorScoreUpdated(account, "reputation", c.reputation);
    }

    function bumpValidationScore(address account, uint256 delta)
        external
        onlyRole(SCORER_ROLE)
    {
        Contributor storage c = contributors[account];
        c.validationScore += delta;
        emit ContributorScoreUpdated(account, "validationScore", c.validationScore);
    }

    /// @notice Slashing explicit pentru paradoxuri false (controlat de DAO / Dispute).
    function slashOnFalseParadox(address account, uint256 penalty, string calldata reason)
        external
        onlyRole(DISPUTE_ROLE)
    {
        Contributor storage c = contributors[account];
        uint256 old = c.reputation;
        c.reputation = penalty >= old ? 0 : old - penalty;

        emit ContributorSlashed(account, penalty, reason);
        emit ContributorScoreUpdated(account, "reputation", c.reputation);
    }

    function getContributor(address account) external view returns (Contributor memory) {
        return contributors[account];
    }

    function getContributions(address account) external view returns (ParadoxRef[] memory) {
        return contributions[account];
    }
}

DAOGovernor

DAOGovernor.sol
localhost: not deployed
Governance Core

Canonical DAO governor wired to the voting token and timelock for parameter and treasury changes.

GovernanceInvestorRisk & Compliance @oz: Governor.sol@oz: TimelockController.sol@oz: GovernorCountingSimple.sol
  • Wraps OpenZeppelin Governor modules into a single contract that controls protocol upgrades and parameter changes.
  • Hooks into an ERC20Votes-style token and a TimelockController to enforce voting periods, quorums, and execution delays.
  • Defines the proposal lifecycle that every other contract ultimately depends on for configuration changes.
  • Misconfigured voting delays, periods, or quorum fractions can make governance either deadlocked or easily captured.
  • Any contract wired as a timelock target inherits the security of this governor and its voting token.
Roles: 0 constants Events: 0 Functions: 10
Deep dive & Solidity source Key roles · functions · read-only code

Key interfaces

  • Roles:
  • Top functions: _cancel, _execute, _executor, proposalThreshold, propose, quorum, state, supportsInterface
  • Top events:

Solidity source

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

import "@openzeppelin/contracts/governance/Governor.sol";
import "@openzeppelin/contracts/governance/extensions/GovernorSettings.sol";
import "@openzeppelin/contracts/governance/extensions/GovernorCountingSimple.sol";
import "@openzeppelin/contracts/governance/extensions/GovernorVotes.sol";
import "@openzeppelin/contracts/governance/extensions/GovernorVotesQuorumFraction.sol";
import "@openzeppelin/contracts/governance/extensions/GovernorTimelockControl.sol";
import "@openzeppelin/contracts/interfaces/IERC5805.sol";
import "@openzeppelin/contracts/governance/TimelockController.sol";

contract DAOGovernor is
    Governor,
    GovernorSettings,
    GovernorCountingSimple,
    GovernorVotes,
    GovernorVotesQuorumFraction,
    GovernorTimelockControl
{
    constructor(
        string memory name_,
        IERC5805 token_,              // ERC20Votes (IVotes + IERC6372)
        TimelockController timelock_, // Timelock controller
        uint256 votingDelay_,         // blocks or seconds (depending on clock mode)
        uint256 votingPeriod_,        // blocks or seconds (depending on clock mode)
        uint256 proposalThreshold_,   // token units
        uint256 quorumFraction_       // percent (e.g. 4 = 4%)
    )
        Governor(name_)
        GovernorSettings(votingDelay_, votingPeriod_, proposalThreshold_)
        GovernorVotes(token_)
        GovernorVotesQuorumFraction(quorumFraction_)
        GovernorTimelockControl(timelock_)
    {}

    // --- Overrides cerute de Solidity (multiple inheritance) ---

    function votingDelay()
        public
        view
        override(IGovernor, GovernorSettings)
        returns (uint256)
    {
        return super.votingDelay();
    }

    function votingPeriod()
        public
        view
        override(IGovernor, GovernorSettings)
        returns (uint256)
    {
        return super.votingPeriod();
    }

    function quorum(uint256 timepoint)
        public
        view
        override(IGovernor, GovernorVotesQuorumFraction)
        returns (uint256)
    {
        return super.quorum(timepoint);
    }

    function state(uint256 proposalId)
        public
        view
        override(Governor, GovernorTimelockControl)
        returns (ProposalState)
    {
        return super.state(proposalId);
    }

    function propose(
        address[] memory targets,
        uint256[] memory values,
        bytes[] memory calldatas,
        string memory description
    )
        public
        override(Governor, IGovernor)
        returns (uint256)
    {
        return super.propose(targets, values, calldatas, description);
    }

    function proposalThreshold()
        public
        view
        override(Governor, GovernorSettings)
        returns (uint256)
    {
        return super.proposalThreshold();
    }

    function _execute(
        uint256 proposalId,
        address[] memory targets,
        uint256[] memory values,
        bytes[] memory calldatas,
        bytes32 descriptionHash
    )
        internal
        override(Governor, GovernorTimelockControl)
    {
        super._execute(proposalId, targets, values, calldatas, descriptionHash);
    }

    function _cancel(
        address[] memory targets,
        uint256[] memory values,
        bytes[] memory calldatas,
        bytes32 descriptionHash
    )
        internal
        override(Governor, GovernorTimelockControl)
        returns (uint256)
    {
        return super._cancel(targets, values, calldatas, descriptionHash);
    }

    function _executor()
        internal
        view
        override(Governor, GovernorTimelockControl)
        returns (address)
    {
        return super._executor();
    }

    function supportsInterface(bytes4 interfaceId)
        public
        view
        override(Governor, GovernorTimelockControl)
        returns (bool)
    {
        return super.supportsInterface(interfaceId);
    }
}

DisputeResolution

DisputeResolution.sol
localhost: not deployed
Safety & Disputes

On-chain dispute engine for paradox tokens: freeze, revoke, and record evidence with clear roles.

ARBITRATOR_ROLEGOVERNANCE_ROLE GovernanceContributorsRisk & Compliance @oz: AccessControl.sol
  • Allows authorized arbitrators to open disputes tied to specific paradox tokens, collect evidence, and decide outcomes.
  • Can freeze token metadata and call back into the paradox token to revoke it when a dispute is upheld.
  • Keeps a structured audit trail of who opened the dispute, what evidence was submitted, and how it was resolved.
  • If arbitrator or governance roles are compromised, valid paradox tokens can be frozen or revoked arbitrarily.
  • Poorly defined dispute policies off-chain can turn this contract into a censorship or overreach tool.
Roles: 2 constants Events: 4 Functions: 7
Deep dive & Solidity source Key roles · functions · read-only code

Key interfaces

  • Roles: ARBITRATOR_ROLE, GOVERNANCE_ROLE
  • Top functions: adjudicate, applyOutcome, fileDispute, freezeMetadata, openDispute, revokeOnDispute, submitEvidence
  • Top events: DisputeOpened, DisputeResolved, EvidenceSubmitted, OutcomeApplied

Solidity source

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

import "@openzeppelin/contracts/access/AccessControl.sol";

interface IParadoxTokenForDisputes {
    function revokeOnDispute(uint256 tokenId, string calldata reason) external;
    function freezeMetadata(uint256 tokenId) external;
}

contract DisputeResolution is AccessControl {
    bytes32 public constant ARBITRATOR_ROLE = keccak256("ARBITRATOR_ROLE");
    bytes32 public constant GOVERNANCE_ROLE = keccak256("GOVERNANCE_ROLE");

    enum DisputeStatus { None, Open, EvidenceSubmitted, Resolved }

    struct Dispute {
        uint256 id;
        address raisedBy;
        uint256 targetTokenId;
        string  reason;
        bytes32 evidenceHash;
        string  evidenceURI;
        DisputeStatus status;
        bool upheld;
        bool outcomeApplied;
    }

    IParadoxTokenForDisputes public immutable paradoxToken;
    uint256 public nextDisputeId;
    mapping(uint256 => Dispute) public disputes;

    event DisputeOpened(
        uint256 indexed id,
        address indexed raisedBy,
        uint256 indexed targetTokenId,
        string reason
    );
    event EvidenceSubmitted(uint256 indexed id, bytes32 evidenceHash, string evidenceURI);
    event DisputeResolved(uint256 indexed id, bool upheld, string resolutionNote);
    event OutcomeApplied(uint256 indexed id, uint256 indexed tokenId, bool upheld);

    constructor(address admin, address paradoxToken_) {
        require(admin != address(0), "admin=0");
        require(paradoxToken_ != address(0), "token=0");

        _grantRole(DEFAULT_ADMIN_ROLE, admin);
        _grantRole(ARBITRATOR_ROLE, admin);
        _grantRole(GOVERNANCE_ROLE, admin);

        paradoxToken = IParadoxTokenForDisputes(paradoxToken_);
    }

    /// @notice Numele cerut explicit în specificație.
    function fileDispute(uint256 targetTokenId, string calldata reason)
        public
        returns (uint256)
    {
        uint256 id = ++nextDisputeId;

        disputes[id] = Dispute({
            id: id,
            raisedBy: msg.sender,
            targetTokenId: targetTokenId,
            reason: reason,
            evidenceHash: bytes32(0),
            evidenceURI: "",
            status: DisputeStatus.Open,
            upheld: false,
            outcomeApplied: false
        });

        emit DisputeOpened(id, msg.sender, targetTokenId, reason);
        return id;
    }

    /// @notice Alias compatibil cu numele vechi (openDispute -> fileDispute).
    function openDispute(uint256 targetTokenId, string calldata reason)
        external
        returns (uint256)
    {
        return fileDispute(targetTokenId, reason);
    }

    /// @notice submitEvidence + hash, aliniat cu standardul de evidență.
    function submitEvidence(
        uint256 id,
        bytes32 evidenceHash,
        string calldata evidenceURI
    ) external {
        Dispute storage d = disputes[id];
        require(d.status == DisputeStatus.Open, "bad status");
        require(
            d.raisedBy == msg.sender || hasRole(GOVERNANCE_ROLE, msg.sender),
            "not authorized"
        );

        d.evidenceHash = evidenceHash;
        d.evidenceURI  = evidenceURI;
        d.status       = DisputeStatus.EvidenceSubmitted;

        emit EvidenceSubmitted(id, evidenceHash, evidenceURI);
    }

    /// @notice Adjudicare efectuată de arbitru (DAO / comitet).
    function adjudicate(
        uint256 id,
        bool upheld,
        string calldata resolutionNote
    ) external onlyRole(ARBITRATOR_ROLE) {
        Dispute storage d = disputes[id];
        require(d.status == DisputeStatus.EvidenceSubmitted, "bad status");

        d.status = DisputeStatus.Resolved;
        d.upheld = upheld;

        emit DisputeResolved(id, upheld, resolutionNote);
    }

    /// @notice Aplică outcome-ul pe ParadoxToken (revoke/freeze).
    function applyOutcome(uint256 id) external onlyRole(GOVERNANCE_ROLE) {
        Dispute storage d = disputes[id];
        require(d.status == DisputeStatus.Resolved, "not resolved");
        require(!d.outcomeApplied, "already applied");

        d.outcomeApplied = true;

        if (d.upheld) {
            paradoxToken.revokeOnDispute(d.targetTokenId, d.reason);
        } else {
            // păstrăm paradoxul dar înghețăm metadata pentru trasabilitate
            paradoxToken.freezeMetadata(d.targetTokenId);
        }

        emit OutcomeApplied(id, d.targetTokenId, d.upheld);
    }
}

DocsHashRegistry

DocsHashRegistry.sol
localhost: not deployed
Registries & Anchors

Anchors document hashes and URIs on-chain so off-chain CSV/JSON paradox data can be verified.

REGISTRAR_ROLE Infra / DevOpsResearch / DataGovernance @oz: AccessControl.sol
  • Stores a mapping from document IDs to doc hash, URI, timestamp, and registrar address.
  • Emits an anchoring event so external systems can watch for new datasets or updated documentation.
  • Provides a lightweight, gas-efficient registry that other contracts (like ParadoxNFT) can trust for document integrity.
  • If registrar keys are compromised, malicious or incorrect documents can be anchored as if they were valid.
  • The registry proves file integrity, not economic soundness—garbage in, garbage out still applies.
Roles: 1 constants Events: 1 Functions: 2
Deep dive & Solidity source Key roles · functions · read-only code

Key interfaces

  • Roles: REGISTRAR_ROLE
  • Top functions: anchor, get
  • Top events: DocAnchored

Solidity source

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

// Registry pentru hash-uri de documente (CSV/JSON) + event pentru verificare publică.
import "@openzeppelin/contracts/access/AccessControl.sol";

contract DocsHashRegistry is AccessControl {
    bytes32 public constant REGISTRAR_ROLE = keccak256("REGISTRAR_ROLE");

    struct DocMeta {
        bytes32 docHash;     // keccak256(file bytes)
        string uri;          // ipfs://... sau https://...
        uint256 timestamp;   // block.timestamp
        address registrar;   // cine a înregistrat
    }

    // docId: hash al (uri) sau al (conținutului)
    mapping(bytes32 => DocMeta) public docs;

    event DocAnchored(bytes32 indexed docId, bytes32 indexed docHash, string uri, address indexed registrar);

    constructor() {
        _grantRole(DEFAULT_ADMIN_ROLE, msg.sender);
        _grantRole(REGISTRAR_ROLE, msg.sender);
    }

    function anchor(bytes32 docId, bytes32 docHash, string calldata uri) external onlyRole(REGISTRAR_ROLE) {
        require(docs[docId].timestamp == 0, "doc exists");
        docs[docId] = DocMeta({docHash: docHash, uri: uri, timestamp: block.timestamp, registrar: msg.sender});
        emit DocAnchored(docId, docHash, uri, msg.sender);
    }

    function get(bytes32 docId) external view returns (DocMeta memory) {
        return docs[docId];
    }
}

ParadoxVotes (v1) / GovernanceRules

GovernanceRules.sol
localhost: not deployed
Governance Tokens

First-generation ParadoxVotes implementation with a fixed large initial supply and role-based minting.

MINTER_ROLE GovernanceInvestor @oz: AccessControl.sol@oz: ERC20Votes.sol
  • Implements an ERC20Votes-compatible token with AccessControl for minting and admin operations.
  • Mints a large initial supply on deployment to the admin, representing the early distribution design.
  • Useful as a legacy baseline for how voting power was modelled before newer iterations.
  • Large initial supply concentrated in a single address can lead to governance capture if not distributed safely.
  • If used in production alongside newer tokens, tokenomics and voting power can become confusing.
Roles: 1 constants Events: 0 Functions: 1
Deep dive & Solidity source Key roles · functions · read-only code

Key interfaces

  • Roles: MINTER_ROLE
  • Top functions: mint
  • Top events:

Solidity source

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

import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Votes.sol";
import "@openzeppelin/contracts/access/AccessControl.sol";

contract ParadoxVotes is ERC20Votes, AccessControl {
    bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");

    constructor(
        string memory name_,
        string memory symbol_
    )
        ERC20(name_, symbol_)
        ERC20Permit(name_)
    {
        _grantRole(DEFAULT_ADMIN_ROLE, msg.sender);
        _grantRole(MINTER_ROLE, msg.sender);

        // initial supply: 10 billion tokens
        _mint(msg.sender, 10_000_000_000 * 1e18);
    }

    /// role-based minting
    function mint(address to, uint256 amount)
        external
        onlyRole(MINTER_ROLE)
    {
        _mint(to, amount);
    }
}

GovernanceToken

GovernanceToken.sol
localhost: not deployed
Governance Core

Production-grade governance token (ERC20Votes) with pausability and role-based minting.

MINTER_ROLEPAUSER_ROLE GovernanceInvestorRisk & Compliance @oz: AccessControl.sol@oz: ERC20.sol@oz: ERC20Pausable.sol
  • Extends ERC20Votes with AccessControl roles for minting and pausing transfers in emergency scenarios.
  • Supports EIP-2612 permits so signatures can move voting power without on-chain approval transactions.
  • Designed to be the main liquid governance or utility token backing the DAO and its voting system.
  • Overuse of the pause function can harm liquidity and trust if not governed transparently.
  • Minting rights must be tightly controlled; inflation directly dilutes voting power and token value.
Roles: 2 constants Events: 0 Functions: 8
Deep dive & Solidity source Key roles · functions · read-only code

Key interfaces

  • Roles: MINTER_ROLE, PAUSER_ROLE
  • Top functions: _afterTokenTransfer, _beforeTokenTransfer, _burn, _mint, mint, pause, supportsInterface, unpause
  • Top events:

Solidity source

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

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Pausable.sol";
import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Permit.sol";
import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Votes.sol";
import "@openzeppelin/contracts/access/AccessControl.sol";

contract GovernanceToken is ERC20, ERC20Pausable, ERC20Permit, ERC20Votes, AccessControl {
    bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");
    bytes32 public constant PAUSER_ROLE = keccak256("PAUSER_ROLE");

    constructor(
        address admin,
        uint256 initialSupply
    )
        ERC20("GovernanceToken", "GOV")
        ERC20Permit("GovernanceToken")
    {
        _grantRole(DEFAULT_ADMIN_ROLE, admin);
        _grantRole(MINTER_ROLE, admin);
        _grantRole(PAUSER_ROLE, admin);

        if (initialSupply > 0) {
            _mint(admin, initialSupply);
        }
    }

    // --- public API ---

    function pause() external onlyRole(PAUSER_ROLE) {
        _pause();
    }

    function unpause() external onlyRole(PAUSER_ROLE) {
        _unpause();
    }

    function mint(address to, uint256 amount) external onlyRole(MINTER_ROLE) {
        _mint(to, amount);
    }

    // --- overrides necesare pentru multiple inheritance ---

    // Pausable vs ERC20
    function _beforeTokenTransfer(address from, address to, uint256 amount)
        internal
        override(ERC20, ERC20Pausable)
    {
        super._beforeTokenTransfer(from, to, amount);
    }

    // Votes vs ERC20
    function _afterTokenTransfer(address from, address to, uint256 amount)
        internal
        override(ERC20, ERC20Votes)
    {
        super._afterTokenTransfer(from, to, amount);
    }

    function _mint(address to, uint256 amount)
        internal
        override(ERC20, ERC20Votes)
    {
        super._mint(to, amount);
    }

    function _burn(address from, uint256 amount)
        internal
        override(ERC20, ERC20Votes)
    {
        super._burn(from, amount);
    }

    // AccessControl vs ERC20Votes vs ERC20Permit
    function supportsInterface(bytes4 interfaceId)
        public
        view
        override(AccessControl)
        returns (bool)
    {
        return super.supportsInterface(interfaceId);
    }
}

IndexHashRegistry

IndexHashRegistry.sol
localhost: not deployed
Indexes & Signals

Immutable log of index snapshot hashes for verifiable off-chain index exports.

INDEX_PUBLISHER_ROLE Research / DataGovernanceInfra / DevOps @oz: AccessControl.sol
  • Records the keccak256 hash, timestamp, and version for each published index snapshot.
  • Restricts publishing to accounts with an INDEX_PUBLISHER_ROLE to avoid spam or conflicting anchors.
  • Lets anyone later recompute the hash of a CSV/JSON export and verify it against the on-chain anchor.
  • If publishers upload incorrect hashes or mislabel snapshots, verification will succeed on the wrong data.
  • Versioning rules are not enforced economically; operators must follow operational discipline off-chain.
Roles: 1 constants Events: 1 Functions: 2
Deep dive & Solidity source Key roles · functions · read-only code

Key interfaces

  • Roles: INDEX_PUBLISHER_ROLE
  • Top functions: getAnchor, publishIndex
  • Top events: IndexAnchored

Solidity source

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

import "@openzeppelin/contracts/access/AccessControl.sol";

/// @title IndexHashRegistry
/// @notice Simple on-chain registry for ParadoxNet index snapshots.
///         Stores a keccak256 hash for each index version so that
///         off-chain CSV/JSON exports can be verified on-chain.
contract IndexHashRegistry is AccessControl {
    bytes32 public constant INDEX_PUBLISHER_ROLE = keccak256("INDEX_PUBLISHER_ROLE");

    struct IndexAnchor {
        uint256 version;
        uint256 timestamp;
        bytes32 snapshotHash;
    }

    // version => anchor
    mapping(uint256 => IndexAnchor) private _anchors;

    event IndexAnchored(
        uint256 indexed version,
        uint256 indexed timestamp,
        bytes32 indexed snapshotHash,
        address publisher
    );

    constructor(address admin, address initialPublisher) {
        require(admin != address(0), "IndexHashRegistry: admin is zero");
        _grantRole(DEFAULT_ADMIN_ROLE, admin);

        if (initialPublisher != address(0)) {
            _grantRole(INDEX_PUBLISHER_ROLE, initialPublisher);
        }
    }

    /// @notice Publish or update the hash for an index version.
    /// @dev Only accounts with INDEX_PUBLISHER_ROLE may call this.
    function publishIndex(
        uint256 version,
        uint256 timestamp,
        bytes32 snapshotHash
    ) external onlyRole(INDEX_PUBLISHER_ROLE) {
        require(version != 0, "IndexHashRegistry: version is zero");
        require(timestamp != 0, "IndexHashRegistry: timestamp is zero");
        require(snapshotHash != bytes32(0), "IndexHashRegistry: hash is zero");

        _anchors[version] = IndexAnchor({
            version: version,
            timestamp: timestamp,
            snapshotHash: snapshotHash
        });

        emit IndexAnchored(version, timestamp, snapshotHash, msg.sender);
    }

    /// @notice Get the stored anchor for a given version.
    function getAnchor(uint256 version) external view returns (IndexAnchor memory) {
        return _anchors[version];
    }
}

IndexParams

IndexParams.sol
localhost: not deployed
Indexes & Signals

Configurable parameters for each paradox index: weights, scores, and thresholds.

GOVERNANCE_ROLE GovernanceResearch / Data @oz: AccessControl.sol
  • Stores per-index parameter bundles (weighting, domainScore, threshold, version, updatedAt).
  • Limits writes to a GOVERNANCE_ROLE so only governance-approved processes can tune index parameters.
  • Acts as the canonical place to read current index weights when pricing or rebalancing products.
  • Bad parameter updates can silently skew index behaviour and downstream products without breaking anything on-chain.
  • Governance needs off-chain procedures for proposing, simulating, and reviewing parameter changes.
Roles: 1 constants Events: 1 Functions: 3
Deep dive & Solidity source Key roles · functions · read-only code

Key interfaces

  • Roles: GOVERNANCE_ROLE
  • Top functions: getParams, setParams, setWeights
  • Top events: WeightsUpdated

Solidity source

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

import "@openzeppelin/contracts/access/AccessControl.sol";

contract IndexParams is AccessControl {
    bytes32 public constant GOVERNANCE_ROLE = keccak256("GOVERNANCE_ROLE");

    struct Params {
        uint256 weighting;
        uint256 domainScore;
        uint256 threshold;
        uint64  version;
        uint64  updatedAt;
    }

    mapping(bytes32 => Params) private _indexParams;

    event WeightsUpdated(
        bytes32 indexed indexKey,
        uint64  version,
        uint256 weighting,
        uint256 domainScore,
        uint256 threshold
    );

    constructor(address admin) {
        require(admin != address(0), "admin=0");
        _grantRole(DEFAULT_ADMIN_ROLE, admin);
        _grantRole(GOVERNANCE_ROLE, admin);
    }

    /// @notice Funcția principală: setează/actualizează parametrii indexului.
    function setWeights(
        bytes32 indexKey,
        uint256 weighting,
        uint256 domainScore,
        uint256 threshold
    ) public onlyRole(GOVERNANCE_ROLE) {
        require(weighting <= 10_000, "Invalid weighting");
        require(domainScore <= 10_000, "Invalid domainScore");

        Params storage p = _indexParams[indexKey];
        p.weighting   = weighting;
        p.domainScore = domainScore;
        p.threshold   = threshold;
        unchecked {
            p.version += 1;
        }
        p.updatedAt  = uint64(block.timestamp);

        emit WeightsUpdated(indexKey, p.version, weighting, domainScore, threshold);
    }

    /// @notice Alias păstrat pentru compatibilitate cu cod/teste vechi.
    function setParams(
        bytes32 indexKey,
        uint256 weighting,
        uint256 domainScore,
        uint256 threshold
    ) external {
        setWeights(indexKey, weighting, domainScore, threshold);
    }

    function getParams(bytes32 indexKey) external view returns (Params memory) {
        return _indexParams[indexKey];
    }
}

LegacyGovernanceToken

LegacyGovernanceToken.sol
localhost: not deployed
Legacy & Migration

Earlier governance token design without on-chain voting snapshots.

MINTER_ROLEPAUSER_ROLE GovernanceRisk & Compliance @oz: AccessControl.sol@oz: ERC20.sol@oz: ERC20Pausable.sol
  • Implements an ERC20 with pausability and permits but without ERC20Votes voting snapshot logic.
  • Keeps AccessControl roles for minting and pausing, mirroring the structure of the newer governance token.
  • Intended for migration scenarios or backwards-compatibility with older deployments.
  • Because it lacks ERC20Votes, voting power must be computed externally if this token remains in use.
  • Running multiple token generations in parallel increases operational and UX complexity.
Roles: 2 constants Events: 0 Functions: 5
Deep dive & Solidity source Key roles · functions · read-only code

Key interfaces

  • Roles: MINTER_ROLE, PAUSER_ROLE
  • Top functions: _beforeTokenTransfer, mint, pause, supportsInterface, unpause
  • Top events:

Solidity source

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

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Pausable.sol";
import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Permit.sol";
import "@openzeppelin/contracts/access/AccessControl.sol";

/// @title LegacyGovernanceToken
/// @notice ERC20 cu roluri, pausabil și permit (EIP-2612), fără voting snapshots
contract LegacyGovernanceToken is ERC20, ERC20Pausable, ERC20Permit, AccessControl {
    bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");
    bytes32 public constant PAUSER_ROLE = keccak256("PAUSER_ROLE");

    constructor(
        string memory name_,
        string memory symbol_,
        address admin,
        uint256 initialSupply
    )
        ERC20(name_, symbol_)
        ERC20Permit(name_)
    {
        _grantRole(DEFAULT_ADMIN_ROLE, admin);
        _grantRole(MINTER_ROLE, admin);
        _grantRole(PAUSER_ROLE, admin);

        if (initialSupply > 0) {
            _mint(admin, initialSupply);
        }
    }

    // --- public API ---

    function mint(address to, uint256 amount) external onlyRole(MINTER_ROLE) {
        _mint(to, amount);
    }

    function pause() external onlyRole(PAUSER_ROLE) {
        _pause();
    }

    function unpause() external onlyRole(PAUSER_ROLE) {
        _unpause();
    }

    // --- overrides necesare pentru multiple inheritance ---

    // Rezolvă conflictul de hook între ERC20 și ERC20Pausable
    function _beforeTokenTransfer(address from, address to, uint256 amount)
        internal
        override(ERC20, ERC20Pausable)
    {
        super._beforeTokenTransfer(from, to, amount);
    }

    // AccessControl interface resolution
    function supportsInterface(bytes4 interfaceId)
        public
        view
        override(AccessControl)
        returns (bool)
    {
        return super.supportsInterface(interfaceId);
    }
}

MockDocsRegistry

MockDocsRegistry.sol
localhost: not deployed
Testing & Mocks

Test-only docs registry implementing the interface expected by ParadoxNFT.

Protocol Dev
  • Provides an in-memory mapping from docId to doc metadata, similar to DocsHashRegistry.
  • Implements the minimal docs(...) view function required by ParadoxNFT for unit tests.
  • Designed strictly for local development and testing, not for production deployment.
  • Deploying this mock on production by mistake would bypass access control and anchoring guarantees.
  • Mocks should live in test environments only; treat any mainnet instance as compromised.
Roles: 0 constants Events: 0 Functions: 2
Deep dive & Solidity source Key roles · functions · read-only code

Key interfaces

  • Roles:
  • Top functions: docs, setDoc
  • Top events:

Solidity source

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

/// @dev Minimal on-chain docs registry used only for tests.
///      Mirrors the IDocsHashRegistry.docs interface expected by ParadoxNFT.
contract MockDocsRegistry {
    struct Doc {
        bytes32 docHash;
        string uri;
        uint256 timestamp;
        address registrar;
    }

    mapping(bytes32 => Doc) private _docs;

    function setDoc(
        bytes32 docId,
        bytes32 docHash,
        string calldata uri,
        uint256 timestamp,
        address registrar
    ) external {
        _docs[docId] = Doc({
            docHash: docHash,
            uri: uri,
            timestamp: timestamp,
            registrar: registrar
        });
    }

    function docs(bytes32 docId)
        external
        view
        returns (
            bytes32 docHash,
            string memory uri,
            uint256 timestamp,
            address registrar
        )
    {
        Doc storage d = _docs[docId];
        return (d.docHash, d.uri, d.timestamp, d.registrar);
    }
}

MockWarrants

MockWarrants.sol
localhost: not deployed
Testing & Mocks

Test-only warrants mock exposing a simple canMint(address) view.

Protocol Dev
  • Allows tests to toggle whether a given address is allowed to mint paradox NFTs.
  • Implements the exact canMint interface expected by the main Warrants or ParadoxNFT contract.
  • Useful for simulating different minting policies without touching production logic.
  • If wired into production ParadoxNFT deployments, minting constraints collapse to a boolean mapping.
  • As with all mocks, it must never be treated as a real entitlement system for value-bearing assets.
Roles: 0 constants Events: 0 Functions: 2
Deep dive & Solidity source Key roles · functions · read-only code

Key interfaces

  • Roles:
  • Top functions: canMint, setCanMint
  • Top events:

Solidity source

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

/// @dev Minimal warrants mock used only in tests for ParadoxNFT.
///      Exposes the canMint(address) view used by the main contract.
contract MockWarrants {
    mapping(address => bool) private _canMint;

    function setCanMint(address account, bool value) external {
        _canMint[account] = value;
    }

    function canMint(address account) external view returns (bool) {
        return _canMint[account];
    }
}

ParadoxNFT

ParadoxNFT.sol
localhost: not deployed
Paradox Assets & NFTs

Main ERC-721 for paradoxes, gated by warrants, scores, and document anchors.

MINTER_ROLE ContributorsGovernanceInvestor @oz: AccessControl.sol@oz: ERC721URIStorage.sol
  • Mints paradox NFTs only when a warrant exists and (optionally) scoring or epoch constraints are satisfied.
  • Integrates with DocsHashRegistry to ensure each minted token points to an anchored document hash and URI.
  • Tracks epochs, caps, and minimum scores so that paradox minting follows transparent rules.
  • Any bug in warrant checks or docs verification can let invalid paradoxes be minted as official assets.
  • Economic value quickly concentrates here; thorough audits and simulation are mandatory before mainnet.
Roles: 1 constants Events: 1 Functions: 8
Deep dive & Solidity source Key roles · functions · read-only code

Key interfaces

  • Roles: MINTER_ROLE
  • Top functions: canMint, docs, mint, setEpoch, setMinScore, setRegistry, setWarrants, supportsInterface
  • Top events: Minted

Solidity source

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

// ERC-721 pentru paradoxuri: mint condiționat de warrants și (optional) prag de scor.
// Integrează DocsHashRegistry pentru verificare publică.

import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
import "@openzeppelin/contracts/access/AccessControl.sol";

interface IWarrants {
    function canMint(address account) external view returns (bool);
}

interface IDocsHashRegistry {
    function docs(bytes32 docId) external view returns (
        bytes32 docHash,
        string memory uri,
        uint256 timestamp,
        address registrar
    );
}

contract ParadoxNFT is ERC721URIStorage, AccessControl {
    bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");

    uint256 public totalMinted;
    uint256 public currentEpoch;
    mapping(uint256 => uint256) public epochCap;
    mapping(uint256 => uint256) public epochMinted;

    // scor agregat 0..1000
    uint256 public minScore;
    IWarrants public warrants;
    IDocsHashRegistry public registry;

    event Minted(
        uint256 indexed tokenId,
        uint256 indexed epoch,
        bytes32 indexed docId,
        bytes32 docHash,
        uint256 score,
        string title,
        string status
    );

    constructor(
        string memory name_,
        string memory symbol_,
        uint256 initialEpoch_,
        uint256 initialEpochCap_,
        uint256 minScore_,
        address warrants_,
        address registry_
    ) ERC721(name_, symbol_) {
        require(initialEpochCap_ > 0, "epochCap=0");
        require(warrants_ != address(0), "warrants=0");
        require(registry_ != address(0), "registry=0");

        currentEpoch = initialEpoch_;
        epochCap[currentEpoch] = initialEpochCap_;
        minScore = minScore_;
        warrants = IWarrants(warrants_);
        registry = IDocsHashRegistry(registry_);

        _grantRole(DEFAULT_ADMIN_ROLE, msg.sender);
        _grantRole(MINTER_ROLE, msg.sender);
    }

    function setEpoch(uint256 epoch, uint256 cap)
        external
        onlyRole(DEFAULT_ADMIN_ROLE)
    {
        require(cap > 0, "cap=0");
        currentEpoch = epoch;
        epochCap[epoch] = cap;
    }

    function setMinScore(uint256 newMinScore)
        external
        onlyRole(DEFAULT_ADMIN_ROLE)
    {
        minScore = newMinScore;
    }

    function setWarrants(address newWarrants)
        external
        onlyRole(DEFAULT_ADMIN_ROLE)
    {
        require(newWarrants != address(0), "warrants=0");
        warrants = IWarrants(newWarrants);
    }

    function setRegistry(address newRegistry)
        external
        onlyRole(DEFAULT_ADMIN_ROLE)
    {
        require(newRegistry != address(0), "registry=0");
        registry = IDocsHashRegistry(newRegistry);
    }

    /// tokenURI: deja compus off-chain (IPFS/HTTP), conține titlu/scor/hash/status
    function mint(
        address to,
        string memory tokenURI_,
        bytes32 docId,
        bytes32 docHashExpected,
        uint256 score,
        string memory title,
        string memory status
    )
        external
        onlyRole(MINTER_ROLE)
        returns (uint256 tokenId)
    {
        require(to != address(0), "to=0");
        require(epochCap[currentEpoch] > 0, "epochCap=0");
        require(epochMinted[currentEpoch] < epochCap[currentEpoch], "epoch cap");
        require(address(warrants) != address(0), "warrants unset");
        require(address(registry) != address(0), "registry unset");
        require(warrants.canMint(msg.sender), "no warrant");

        if (minScore > 0) {
            require(score >= minScore, "score<min");
        }

        // verifică doc în registry
        (bytes32 regHash, , uint256 ts, ) = registry.docs(docId);
        require(ts != 0, "doc missing");
        require(regHash == docHashExpected, "doc hash mismatch");

        tokenId = ++totalMinted;
        epochMinted[currentEpoch] += 1;

        _safeMint(to, tokenId);
        _setTokenURI(tokenId, tokenURI_);

        emit Minted(tokenId, currentEpoch, docId, regHash, score, title, status);
    }

    // --- multiple inheritance fix (ERC721URIStorage + AccessControl) ---

    function supportsInterface(bytes4 interfaceId)
        public
        view
        virtual
        override(ERC721URIStorage, AccessControl)
        returns (bool)
    {
        return super.supportsInterface(interfaceId);
    }
}

ParadoxOracleBridge

ParadoxOracleBridge.sol
localhost: not deployed
Oracles & Bridges

Minimal oracle bridge accepting signed off-chain results and emitting on-chain events.

ORACLE_ROLE Infra / DevOpsResearch / DataGovernance @oz: AccessControl.sol
  • Gives ORACLE_ROLE holders the ability to submit docId/docHash/URI tuples as signed oracle outputs.
  • Emits an OracleSubmit event which can be consumed by off-chain listeners or downstream registries.
  • Designed to be extendable to full oracle networks (e.g. Chainlink/CCIP) without changing the core flow.
  • Oracle key compromise means attackers can publish arbitrary hashes and URIs as if they were valid inputs.
  • The contract itself does not verify signatures or economic guarantees; that logic must live around it.
Roles: 1 constants Events: 1 Functions: 1
Deep dive & Solidity source Key roles · functions · read-only code

Key interfaces

  • Roles: ORACLE_ROLE
  • Top functions: submit
  • Top events: OracleSubmit

Solidity source

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

// Bridge/oracol minimal: acceptă semnături off-chain (AI/service) pentru ancorare.
// În MVP, doar validează un semnatar autorizat. Extensibil la Chainlink/CCIP.

import "@openzeppelin/contracts/access/AccessControl.sol";

contract ParadoxOracleBridge is AccessControl {
    bytes32 public constant ORACLE_ROLE = keccak256("ORACLE_ROLE");

    event OracleSubmit(bytes32 indexed docId, bytes32 indexed docHash, string uri, address indexed oracle);

    constructor() {
        _grantRole(DEFAULT_ADMIN_ROLE, msg.sender);
        _grantRole(ORACLE_ROLE, msg.sender);
    }

    function submit(bytes32 docId, bytes32 docHash, string calldata uri) external onlyRole(ORACLE_ROLE) {
        emit OracleSubmit(docId, docHash, uri, msg.sender);
        // Integrarea cu DocsHashRegistry se face off-chain sau prin orchestrator (script) care ascultă acest eveniment.
    }
}

ParadoxStaking

ParadoxStaking.sol
localhost: not deployed
Reputation & Contributors

Linear staking pool for an ERC-20 token, used to align contributors and long-term holders.

ContributorsInvestorGovernance @oz: AccessControl.sol@oz: IERC20.sol
  • Lets users stake an ERC-20 token and earn rewards at a configurable tokens-per-second rate.
  • Tracks per-user reward accrual and total supply, exposing standard stake, withdraw, and claim functions.
  • Uses AccessControl to restrict who can adjust reward rates or other sensitive parameters.
  • Incorrect reward rates or update logic can either leak tokens or underpay contributors.
  • Staking pools become honeypots; they require careful review of math, time units, and edge cases.
Roles: 0 constants Events: 3 Functions: 4
Deep dive & Solidity source Key roles · functions · read-only code

Key interfaces

  • Roles:
  • Top functions: getReward, setRewardRate, stake, withdraw
  • Top events: RewardPaid, Staked, Withdrawn

Solidity source

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

// Staking simplu ERC-20: depui tokenul, acumulezi recompense lineare.
// MVP: fără slashing, fără boost. Ajustează după nevoie.

import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/access/AccessControl.sol";

contract ParadoxStaking is AccessControl {
    IERC20 public immutable stakingToken;
    uint256 public rewardRatePerSec; // tokens/sec (setat de admin)
    uint256 public lastUpdate;
    uint256 public rewardPerTokenStored;

    mapping(address => uint256) public userRewardPerTokenPaid;
    mapping(address => uint256) public rewards;
    mapping(address => uint256) public balances;
    uint256 public totalSupply;

    event Staked(address indexed user, uint256 amount);
    event Withdrawn(address indexed user, uint256 amount);
    event RewardPaid(address indexed user, uint256 reward);

    constructor(address token_) {
        require(token_ != address(0), "token=0");
        stakingToken = IERC20(token_);
        _grantRole(DEFAULT_ADMIN_ROLE, msg.sender);
        lastUpdate = block.timestamp;
    }

    modifier updateReward(address account) {
        uint256 elapsed = block.timestamp - lastUpdate;
        if (elapsed > 0 && totalSupply > 0) {
            rewardPerTokenStored += (elapsed * rewardRatePerSec * 1e18) / totalSupply;
        }
        lastUpdate = block.timestamp;
        if (account != address(0)) {
            rewards[account] += ((balances[account] * (rewardPerTokenStored - userRewardPerTokenPaid[account])) / 1e18);
            userRewardPerTokenPaid[account] = rewardPerTokenStored;
        }
        _;
    }

    function setRewardRate(uint256 rate) external onlyRole(DEFAULT_ADMIN_ROLE) {
        rewardRatePerSec = rate;
    }

    function stake(uint256 amount) external updateReward(msg.sender) {
        require(amount > 0, "amount=0");
        stakingToken.transferFrom(msg.sender, address(this), amount);
        balances[msg.sender] += amount;
        totalSupply += amount;
        emit Staked(msg.sender, amount);
    }

    function withdraw(uint256 amount) external updateReward(msg.sender) {
        require(amount > 0 && amount <= balances[msg.sender], "invalid");
        balances[msg.sender] -= amount;
        totalSupply -= amount;
        stakingToken.transfer(msg.sender, amount);
        emit Withdrawn(msg.sender, amount);
    }

    function getReward() external updateReward(msg.sender) {
        uint256 reward = rewards[msg.sender];
        rewards[msg.sender] = 0;
        require(reward > 0, "no reward");
        stakingToken.transfer(msg.sender, reward);
        emit RewardPaid(msg.sender, reward);
    }
}

ParadoxTimelock

ParadoxTimelock.sol
localhost: not deployed
Governance Core

Timelock controller ensuring governance decisions respect a minimum delay.

GovernanceRisk & Compliance @oz: TimelockController.sol
  • Wraps OpenZeppelin TimelockController with Paradox-specific deployment parameters.
  • Enforces a delay between successful governance votes and actual execution of queued operations.
  • Separates proposer, executor, and admin addresses to keep the governance surface small and auditable.
  • Misconfigured roles can let a single key both propose and execute changes, bypassing checks and balances.
  • Too short a delay reduces the community’s ability to react; too long makes governance feel unresponsive.
Roles: 0 constants Events: 0 Functions: 0
Deep dive & Solidity source Key roles · functions · read-only code

Key interfaces

  • Roles:
  • Top functions:
  • Top events:

Solidity source

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

import "@openzeppelin/contracts/governance/TimelockController.sol";

contract ParadoxTimelock is TimelockController {
    constructor(
        uint256 minDelay,
        address[] memory proposers,
        address[] memory executors,
        address admin
    )
        TimelockController(minDelay, proposers, executors, admin)
    {}
}

ParadoxToken

ParadoxToken.sol
localhost: not deployed
Paradox Assets & NFTs

Early ERC-721 implementation for paradox tokens with rich role-based access control.

DISPUTE_RESOLVER_ROLEGRAPH_ROLEMETADATA_ROLEMINTER_ROLEPAUSER_ROLEVALIDATOR_ROLE ContributorsGovernanceProtocol Dev @oz: AccessControl.sol@oz: ERC721.sol@oz: ERC721Pausable.sol
  • Extends ERC721 with metadata storage, pausability, and roles for minting, metadata updates, and validation.
  • Integrates roles for validators, dispute resolvers, and graph updaters to keep token state consistent.
  • Intended as a flexible token layer for experimentation before ParadoxNFT hardened the minting pipeline.
  • Extra roles and functions expand the attack surface if not governed strictly.
  • Running multiple paradox token standards in parallel complicates markets and analytics.
Roles: 6 constants Events: 5 Functions: 14
Deep dive & Solidity source Key roles · functions · read-only code

Key interfaces

  • Roles: DISPUTE_RESOLVER_ROLE, GRAPH_ROLE, METADATA_ROLE, MINTER_ROLE, PAUSER_ROLE, VALIDATOR_ROLE
  • Top functions: _baseURI, _beforeTokenTransfer, _burn, freezeMetadata, getParadoxMeta, linkGraphNode, mintParadox, pause
  • Top events: GraphNodeLinked, MetadataFrozen, ParadoxMinted, ParadoxRevoked, ValidationStatusUpdated

Solidity source

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

import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Pausable.sol";
import "@openzeppelin/contracts/access/AccessControl.sol";

contract ParadoxToken is ERC721, ERC721URIStorage, ERC721Pausable, AccessControl {
    bytes32 public constant MINTER_ROLE            = keccak256("MINTER_ROLE");
    bytes32 public constant METADATA_ROLE          = keccak256("METADATA_ROLE");
    bytes32 public constant VALIDATOR_ROLE         = keccak256("VALIDATOR_ROLE");
    bytes32 public constant GRAPH_ROLE             = keccak256("GRAPH_ROLE");
    bytes32 public constant DISPUTE_RESOLVER_ROLE  = keccak256("DISPUTE_RESOLVER_ROLE");
    bytes32 public constant PAUSER_ROLE            = keccak256("PAUSER_ROLE");

    uint256 private _tokenIdCounter;
    string private _baseTokenURI;

    /// @notice Statusul de validare pe care îl controlează pipeline-ul + DAO.
    enum ValidationStatus {
        Unset,
        Pending,
        Validated,
        Rejected,
        Revoked
    }

    /// @notice Metadata minimă on-chain conform specificației.
    struct ParadoxMeta {
        bytes32 contentHash;      // hash al conținutului paradoxului (Keccak/SHA-256)
        ValidationStatus status;  // starea de validare
        bytes32 graphNodeId;      // ID în epistemic graph (DKG/Wikibase)
        bool frozen;              // dacă metadata mai poate fi mutată
    }

    mapping(uint256 => ParadoxMeta) private _paradoxMeta;

    event ParadoxMinted(uint256 indexed tokenId, address indexed to, bytes32 indexed contentHash);
    event ValidationStatusUpdated(uint256 indexed tokenId, ValidationStatus status);
    event GraphNodeLinked(uint256 indexed tokenId, bytes32 graphNodeId);
    event MetadataFrozen(uint256 indexed tokenId);
    event ParadoxRevoked(uint256 indexed tokenId, string reason);

    constructor(
        string memory name_,
        string memory symbol_,
        address admin_
    ) ERC721(name_, symbol_) {
        require(admin_ != address(0), "admin=0");

        _grantRole(DEFAULT_ADMIN_ROLE, admin_);
        _grantRole(MINTER_ROLE, admin_);
        _grantRole(METADATA_ROLE, admin_);
        _grantRole(VALIDATOR_ROLE, admin_);
        _grantRole(GRAPH_ROLE, admin_);
        _grantRole(DISPUTE_RESOLVER_ROLE, admin_);
        _grantRole(PAUSER_ROLE, admin_);
    }

    // --- config ---

    function _baseURI() internal view override returns (string memory) {
        return _baseTokenURI;
    }

    function setBaseURI(string calldata newBaseURI) external onlyRole(METADATA_ROLE) {
        _baseTokenURI = newBaseURI;
    }

    // --- funcțiile cheie din specificație ---

    /// @notice Mint paradox conform specificației (minimal metadata + hash pointer).
    function mintParadox(
        address to,
        string calldata uri,
        bytes32 contentHash
    ) external onlyRole(MINTER_ROLE) returns (uint256) {
        require(to != address(0), "to=0");
        require(contentHash != bytes32(0), "hash=0");

        uint256 tokenId = ++_tokenIdCounter;
        _safeMint(to, tokenId);
        _setTokenURI(tokenId, uri);

        ParadoxMeta storage meta = _paradoxMeta[tokenId];
        meta.contentHash = contentHash;
        meta.status = ValidationStatus.Pending;

        emit ParadoxMinted(tokenId, to, contentHash);
        return tokenId;
    }

    function setValidationStatus(uint256 tokenId, ValidationStatus status)
        external
        onlyRole(VALIDATOR_ROLE)
    {
        require(_exists(tokenId), "nonexistent");
        ParadoxMeta storage meta = _paradoxMeta[tokenId];
        require(!meta.frozen, "frozen");
        meta.status = status;
        emit ValidationStatusUpdated(tokenId, status);
    }

    function linkGraphNode(uint256 tokenId, bytes32 graphNodeId)
        external
        onlyRole(GRAPH_ROLE)
    {
        require(_exists(tokenId), "nonexistent");
        ParadoxMeta storage meta = _paradoxMeta[tokenId];
        require(!meta.frozen, "frozen");
        meta.graphNodeId = graphNodeId;
        emit GraphNodeLinked(tokenId, graphNodeId);
    }

    function freezeMetadata(uint256 tokenId)
        external
        onlyRole(METADATA_ROLE)
    {
        require(_exists(tokenId), "nonexistent");
        ParadoxMeta storage meta = _paradoxMeta[tokenId];
        require(!meta.frozen, "already");
        meta.frozen = true;
        emit MetadataFrozen(tokenId);
    }

    /// @notice Folosită de DisputeResolution pentru a revoca un paradox disputat.
    function revokeOnDispute(uint256 tokenId, string calldata reason)
        external
        onlyRole(DISPUTE_RESOLVER_ROLE)
    {
        require(_exists(tokenId), "nonexistent");
        ParadoxMeta storage meta = _paradoxMeta[tokenId];
        meta.status = ValidationStatus.Revoked;
        meta.frozen = true;
        emit ParadoxRevoked(tokenId, reason);
        emit ValidationStatusUpdated(tokenId, ValidationStatus.Revoked);
        emit MetadataFrozen(tokenId);
    }

    function getParadoxMeta(uint256 tokenId) external view returns (ParadoxMeta memory) {
        require(_exists(tokenId), "nonexistent");
        return _paradoxMeta[tokenId];
    }

    // --- pausability ---

    function pause() external onlyRole(PAUSER_ROLE) {
        _pause();
    }

    function unpause() external onlyRole(PAUSER_ROLE) {
        _unpause();
    }

    // --- overrides multiple inheritance ---

    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 tokenId,
        uint256 batchSize
    ) internal override(ERC721, ERC721Pausable) {
        super._beforeTokenTransfer(from, to, tokenId, batchSize);
    }

    function _burn(uint256 tokenId)
        internal
        override(ERC721, ERC721URIStorage)
    {
        super._burn(tokenId);
        delete _paradoxMeta[tokenId];
    }

    function tokenURI(uint256 tokenId)
        public
        view
        override(ERC721, ERC721URIStorage)
        returns (string memory)
    {
        return super.tokenURI(tokenId);
    }

    function supportsInterface(bytes4 interfaceId)
        public
        view
        override(ERC721, ERC721URIStorage, AccessControl)
        returns (bool)
    {
        return super.supportsInterface(interfaceId);
    }
}

ParadoxVotes

ParadoxVotes.sol
localhost: not deployed
Governance Core

Refined ParadoxVotes governance token with explicit initialSupply and mint role.

MINTER_ROLE GovernanceInvestor @oz: AccessControl.sol@oz: ERC20Votes.sol
  • Implements ERC20Votes with AccessControl and configurable initial supply minted to the deployer.
  • Separates the MINTER_ROLE from DEFAULT_ADMIN_ROLE so minting can be delegated or later revoked.
  • Designed as a clean, auditable base for long-term governance tokenomics.
  • As with any governance token, poor distribution or uncontrolled minting leads to vote concentration.
  • Token upgrades and migrations must consider how snapshots and voting history are preserved.
Roles: 1 constants Events: 0 Functions: 4
Deep dive & Solidity source Key roles · functions · read-only code

Key interfaces

  • Roles: MINTER_ROLE
  • Top functions: _afterTokenTransfer, _burn, _mint, mint
  • Top events:

Solidity source

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

import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Votes.sol";
import "@openzeppelin/contracts/access/AccessControl.sol";

/// @title ParadoxVotes
/// @notice Governance token with voting power and role-based minting
contract ParadoxVotes is ERC20Votes, AccessControl {
    /// @dev Role identifier for accounts allowed to mint new tokens
    bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");

    /// @param name_ Token name (e.g. "Paradox Governance")
    /// @param symbol_ Token symbol (e.g. "PGOV")
    /// @param initialSupply Initial supply minted to deployer (in wei units)
    constructor(
        string memory name_,
        string memory symbol_,
        uint256 initialSupply
    )
        ERC20(name_, symbol_)
        ERC20Permit(name_)
    {
        // Grant deployer admin and minter rights
        _grantRole(DEFAULT_ADMIN_ROLE, msg.sender);
        _grantRole(MINTER_ROLE, msg.sender);

        // Mint initial supply to deployer
        if (initialSupply > 0) {
            _mint(msg.sender, initialSupply);
        }
    }

    /// @notice Mint new tokens to a specified address
    /// @dev Only accounts with MINTER_ROLE can call this
    /// @param to Recipient address
    /// @param amount Amount of tokens to mint (in wei units)
    function mint(address to, uint256 amount)
        external
        onlyRole(MINTER_ROLE)
    {
        _mint(to, amount);
    }

    // --- Required overrides for ERC20Votes ---

    function _afterTokenTransfer(address from, address to, uint256 amount)
        internal
        override(ERC20Votes)
    {
        super._afterTokenTransfer(from, to, amount);
    }

    function _mint(address to, uint256 amount)
        internal
        override(ERC20Votes)
    {
        super._mint(to, amount);
    }

    function _burn(address from, uint256 amount)
        internal
        override(ERC20Votes)
    {
        super._burn(from, amount);
    }
}

Warrants

Warrants.sol
localhost: not deployed
Tokens & Rights

On-chain warrants representing the right to receive governance tokens later (TGE + vesting).

GOVERNANCE_ROLEISSUER_ROLE ContributorsInvestorGovernance @oz: AccessControl.sol
  • Issues, tracks, and exercises warrant positions that entitle holders to claim governance tokens.
  • Supports a simple TGE (token generation event) switch to control when warrants become exercisable.
  • Integrates with a token minter interface so exercising a warrant mints real tokens to the beneficiary.
  • Incorrect warrant configuration or issuer role abuse can over-mint governance tokens.
  • Mis-handled expiries and invalidations can leave dust positions or unfairly locked value.
Roles: 2 constants Events: 4 Functions: 7
Deep dive & Solidity source Key roles · functions · read-only code

Key interfaces

  • Roles: GOVERNANCE_ROLE, ISSUER_ROLE
  • Top functions: claimOnTGE, configureTGE, exerciseWarrant, grantWarrant, invalidateWarrant, issueWarrant, mint
  • Top events: TGEConfigured, WarrantExercised, WarrantGranted, WarrantInvalidated

Solidity source

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

import "@openzeppelin/contracts/access/AccessControl.sol";

/// @notice Interfață minimă pentru tokenul de governance/utilitate.
interface ITokenMinter {
    function mint(address to, uint256 amount) external;
}

contract Warrants is AccessControl {
    bytes32 public constant ISSUER_ROLE    = keccak256("ISSUER_ROLE");
    bytes32 public constant GOVERNANCE_ROLE = keccak256("GOVERNANCE_ROLE");

    enum WarrantStatus { None, Issued, Exercised, Invalidated }

    struct Warrant {
        uint256 id;
        address beneficiary;
        uint256 amount;
        uint256 expiry;
        WarrantStatus status;
        string metaURI;
    }

    ITokenMinter public immutable token;

    mapping(uint256 => Warrant) public warrants;
    uint256 public nextWarrantId;

    bool public tgeActive;
    uint256 public tgeTimestamp;

    event WarrantGranted(
        uint256 indexed id,
        address indexed beneficiary,
        uint256 amount,
        uint256 expiry,
        string metaURI
    );
    event WarrantExercised(uint256 indexed id, address indexed beneficiary, uint256 amount);
    event WarrantInvalidated(uint256 indexed id, string reason);
    event TGEConfigured(bool active, uint256 timestamp);

    constructor(address admin, address token_) {
        require(admin != address(0), "admin=0");
        require(token_ != address(0), "token=0");

        _grantRole(DEFAULT_ADMIN_ROLE, admin);
        _grantRole(ISSUER_ROLE, admin);
        _grantRole(GOVERNANCE_ROLE, admin);

        token = ITokenMinter(token_);
    }

    /// @notice grantWarrant conform specificației (issue către investitori).
    function grantWarrant(
        address beneficiary,
        uint256 amount,
        uint256 expiry,
        string calldata metaURI
    ) public onlyRole(ISSUER_ROLE) returns (uint256) {
        require(beneficiary != address(0), "beneficiary=0");
        require(amount > 0, "amount=0");
        require(expiry > block.timestamp, "expiry<=now");

        uint256 id = ++nextWarrantId;
        warrants[id] = Warrant({
            id: id,
            beneficiary: beneficiary,
            amount: amount,
            expiry: expiry,
            status: WarrantStatus.Issued,
            metaURI: metaURI
        });

        emit WarrantGranted(id, beneficiary, amount, expiry, metaURI);
        return id;
    }

    /// @notice Alias compatibil cu numele vechi (issueWarrant -> grantWarrant).
    function issueWarrant(
        address beneficiary,
        uint256 amount,
        uint256 expiry,
        string calldata metaURI
    ) external returns (uint256) {
        return grantWarrant(beneficiary, amount, expiry, metaURI);
    }

    /// @notice Configurare TGE (activare + timestamp de referință).
    function configureTGE(bool active, uint256 timestamp)
        external
        onlyRole(GOVERNANCE_ROLE)
    {
        if (active) {
            require(timestamp <= block.timestamp, "timestamp in future");
        }
        tgeActive    = active;
        tgeTimestamp = timestamp;

        emit TGEConfigured(active, timestamp);
    }

    /// @notice claimOnTGE — conversie warrant -> mint tokens după TGE.
    function claimOnTGE(uint256 id) public {
        Warrant storage w = warrants[id];
        require(w.status == WarrantStatus.Issued, "not issuable");
        require(tgeActive, "TGE not active");
        require(block.timestamp >= tgeTimestamp, "before TGE");
        require(block.timestamp <= w.expiry, "expired");
        require(msg.sender == w.beneficiary, "not beneficiary");

        w.status = WarrantStatus.Exercised;
        token.mint(w.beneficiary, w.amount);

        emit WarrantExercised(id, w.beneficiary, w.amount);
    }

    /// @notice Alias compatibil cu fluxul vechi (exerciseWarrant -> claimOnTGE).
    function exerciseWarrant(uint256 id) external {
        claimOnTGE(id);
    }

    function invalidateWarrant(uint256 id, string calldata reason)
        external
        onlyRole(GOVERNANCE_ROLE)
    {
        Warrant storage w = warrants[id];
        require(w.status == WarrantStatus.Issued, "invalid status");

        w.status = WarrantStatus.Invalidated;
        emit WarrantInvalidated(id, reason);
    }
}

ZKAdapters

ZKAdapters.sol
localhost: not deployed
Oracles & ZK

ZK-friendly adapter contract for vote and validation proofs with nullifier protection.

PROVER_ROLE GovernanceResearch / DataInfra / DevOps @oz: AccessControl.sol
  • Provides a PROVER_ROLE-gated entrypoint where off-chain ZK systems can submit verified vote proofs.
  • Tracks used nullifiers on-chain to prevent double-voting or replay of the same proof.
  • Emits structured events for vote, validation, and attestation proofs to feed analytics and audits.
  • If proof systems are weak or compromised, on-chain adapters will happily accept bad attestations.
  • Nullifier management must stay consistent with off-chain circuits; mismatches break anonymity guarantees.
Roles: 1 constants Events: 3 Functions: 3
Deep dive & Solidity source Key roles · functions · read-only code

Key interfaces

  • Roles: PROVER_ROLE
  • Top functions: recordAttestation, verifyValidationProof, verifyVoteProof
  • Top events: AttestationRecorded, ValidationProofVerified, VoteProofVerified

Solidity source

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

import "@openzeppelin/contracts/access/AccessControl.sol";

contract ZKAdapters is AccessControl {
    bytes32 public constant PROVER_ROLE = keccak256("PROVER_ROLE");

    mapping(bytes32 => bool) public usedNullifiers;

    event VoteProofVerified(
        bytes32 indexed proposalId,
        address indexed voter,
        uint8   support,
        uint256 weight,
        bytes32 nullifier
    );

    event ValidationProofVerified(
        uint256 indexed paradoxId,
        address indexed validator,
        bool    isValid,
        bytes32 nullifier
    );

    event AttestationRecorded(
        bytes32 indexed subject,
        bytes32 indexed attestationHash,
        address indexed attestor
    );

    constructor(address admin) {
        _grantRole(DEFAULT_ADMIN_ROLE, admin);
        _grantRole(PROVER_ROLE, admin);
    }

    function verifyVoteProof(
        bytes32 proposalId,
        address voter,
        uint8   support,
        uint256 weight,
        bytes32 nullifier,
        bytes calldata /* proof */
    ) external onlyRole(PROVER_ROLE) {
        require(!usedNullifiers[nullifier], "nullifier used");
        usedNullifiers[nullifier] = true;
        emit VoteProofVerified(proposalId, voter, support, weight, nullifier);
    }

    function verifyValidationProof(
        uint256 paradoxId,
        address validator,
        bool    isValid,
        bytes32 nullifier,
        bytes calldata /* proof */
    ) external onlyRole(PROVER_ROLE) {
        require(!usedNullifiers[nullifier], "nullifier used");
        usedNullifiers[nullifier] = true;
        emit ValidationProofVerified(paradoxId, validator, isValid, nullifier);
    }

    function recordAttestation(
        bytes32 subject,
        bytes32 attestationHash
    ) external onlyRole(PROVER_ROLE) {
        emit AttestationRecorded(subject, attestationHash, msg.sender);
    }
}