> ## Documentation Index
> Fetch the complete documentation index at: https://sidiorresearchlabs.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Computable Token Machine (CTM)

> Revolutionary token standard where tokens are fully-fledged execution environments

## Overview

The Computable Token Machine is a revolutionary token standard that combines ERC-20 functionality with the Diamond Standard (EIP-2535). Each CTM is both a standard token AND a modular execution environment capable of running its own applications, managing state, and evolving over time.

> [!NOTE]
>
> **Beyond value, beyond utility—tokens that think.**

> [card] EIP-2535 Diamond
>
> Modular architecture

> [card] Modular Programs
>
> Infinite extensibility

> [card] On-Chain Autonomy
>
> Self-executing logic

## Live Contract

> [card] Deployed CTM
>
> **Address:** `0x477A9f214c947e6D81b9d32b6b1883F4a4ffFb24`
>
> [View on PaxScan →](https://paxscan.io/address/0x477A9f214c947e6D81b9d32b6b1883F4a4ffFb24)

## What is CTM?

The Computable Token Machine is a revolutionary token standard that combines ERC-20 functionality with the Diamond Standard (EIP-2535). Each CTM is both a standard token AND a modular execution environment capable of running its own applications, managing state, and evolving over time.

## Key Features

> [accordion] Infinite Extensibility
>
> Add new features and applications to your token after deployment. Your token evolves with your needs.

> [accordion] Shared State
>
> All Programs share the same storage context. Programs can read and interact with each other seamlessly.

> [accordion] Gas Efficiency
>
> Modular Programs optimize gas usage and bypass EVM contract size limits.

> [accordion] On-Chain Autonomy
>
> Create complex on-chain agents that manage assets and execute tasks based on rich internal state.

## Core Concepts

### Two Personalities

CTM acts as both a token and a machine:

> [tab] The Token
>
> On the outside, a CTM behaves like any standard ERC-20 token. It can be:
>
> * Held in wallets
> * Traded on exchanges
> * Used in DeFi protocols
> * Transferred between addresses
>
> No special handling required - it's just a token!

> [tab] The Machine
>
> Internally, the CTM acts as a proxy that routes function calls to various logic contracts called "Programs" (or Facets). These Programs can be:
>
> * Added without redeployment
> * Replaced to fix bugs or add features
> * Removed when no longer needed
> * Composed together for complex behavior
>
> All while maintaining the same contract address!

### Programs (Facets)

Programs are stateless Solidity contracts that contain the logic executed by the CTM. Each Program manages its own state within a unique storage slot to prevent collisions.

**Example Programs:**

* Voting and Governance
* Staking and Rewards
* DEX Integration
* NFT Minting
* Custom Game Logic
* Automated Trading
* On-chain AI Agents

### Diamond Standard (EIP-2535)

CTM is built on the Diamond Standard, which allows a single contract to use multiple logic contracts (facets/programs). This pattern enables:

* ✅ Unlimited contract size
* ✅ Upgradability
* ✅ Modular functionality
* ✅ Single address persistence

## Quick Start

**1. Clone Repository**

```bash theme={null}
npm i @paxeer-foundation/ctm-contracts
# Or clone directly:
git clone https://github.com/Paxeer-Network/Pax-v3-coreCTM.git
cd Pax-v3-coreCTM
npm install
```

**2. Configure Network**

Add HyperPaxeer details to `hardhat.config.js`:

```javascript hardhat.config.js theme={null}
networks: {
  paxeer: {
    url: "https://public-rpc.paxeer.app/rpc",
    chainId: 125,
    accounts: [process.env.PRIVATE_KEY]
    // HyperPaxeer mainnet
  }
}
```

**3. Deploy**

```bash theme={null}
npx hardhat run scripts/deploy.js --network paxeer
```

This deploys:

* TokenVM.sol (the main proxy contract)
* DiamondCutFacet (for adding/removing Programs)
* DiamondLoupeFacet (for inspecting installed Programs)
* OwnershipFacet (access control)
* ERC20Facet (token functionality)

## Creating Programs

### Program Structure

Programs must be stateless and manage state within a unique storage slot to prevent collisions.

```solidity VotingProgram.sol theme={null}
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

import {ERC20Facet} from "./ERC20Facet.sol";

contract VotingProgram {
    
    struct VotingStorage {
        mapping(uint256 => string) proposals;
        mapping(uint256 => mapping(address => uint256)) votes;
        uint256 proposalCount;
    }

    bytes32 constant VOTING_STORAGE_POSITION = 
        keccak256("ctm.program.storage.voting");

    function votingStorage() internal pure 
        returns (VotingStorage storage vs) 
    {
        bytes32 position = VOTING_STORAGE_POSITION;
        assembly {
            vs.slot := position
        }
    }

    function createProposal(string calldata _description) external {
        VotingStorage storage vs = votingStorage();
        vs.proposalCount++;
        vs.proposals[vs.proposalCount] = _description;
    }

    function vote(uint256 _proposalId) external {
        uint256 voterBalance = ERC20Facet(address(this))
            .balanceOf(msg.sender);
        require(voterBalance > 0, "Must hold tokens");

        VotingStorage storage vs = votingStorage();
        vs.votes[_proposalId][msg.sender] = voterBalance;
    }
    
    function getProposal(uint256 _proposalId) 
        external view returns (string memory) 
    {
        VotingStorage storage vs = votingStorage();
        return vs.proposals[_proposalId];
    }
    
    function getVotes(uint256 _proposalId, address _voter) 
        external view returns (uint256) 
    {
        VotingStorage storage vs = votingStorage();
        return vs.votes[_proposalId][_voter];
    }
}
```

### Adding Programs to CTM

Use the `diamondCut` function to register new Programs:

```javascript theme={null}
const diamondCut = await ethers.getContractAt('IDiamondCut', ctmAddress);

await diamondCut.diamondCut(
  [{
    facetAddress: votingProgramAddress,
    action: FacetCutAction.Add, // 0 = Add, 1 = Replace, 2 = Remove
    functionSelectors: getSelectors(votingProgram)
  }],
  ethers.constants.AddressZero,
  '0x'
);
```

### Helper Function for Selectors

```javascript theme={null}
function getSelectors(contract) {
  const signatures = Object.keys(contract.interface.functions);
  const selectors = signatures.reduce((acc, val) => {
    if (val !== 'init(bytes)') {
      acc.push(contract.interface.getSighash(val));
    }
    return acc;
  }, []);
  return selectors;
}
```

## Program Best Practices

> [accordion] 1. Unique Storage Slots
>
> Always use keccak256 hashes for storage positions to avoid collisions:
>
> ```solidity theme={null}
> bytes32 constant STORAGE_POSITION = keccak256("ctm.program.storage.myprogram");
> ```
>
> Never use regular state variables at the contract level!

> [accordion] 2. Stateless Logic
>
> Programs should not hold funds or use constructors that set state:
>
> ❌ **Wrong:**
>
> ```solidity theme={null}
> contract MyProgram {
>     uint256 public count = 0; // Don't do this!
>
>     constructor() {
>         count = 10; // Don't do this!
>     }
> }
> ```
>
> ✅ **Correct:**
>
> ```solidity theme={null}
> contract MyProgram {
>     bytes32 constant STORAGE_POSITION = keccak256("ctm.myprogram");
>
>     struct MyStorage {
>         uint256 count;
>     }
>
>     function myStorage() internal pure returns (MyStorage storage ms) {
>         bytes32 position = STORAGE_POSITION;
>         assembly { ms.slot := position }
>     }
> }
> ```

> [accordion] 3. Access Control
>
> Protect diamondCut with ownership or governance controls:
>
> ```solidity theme={null}
> modifier onlyOwner() {
>     require(msg.sender == owner(), "Not authorized");
>     _;
> }
> ```
>
> Only authorized addresses should be able to add/remove Programs.

> [accordion] 4. Inter-Program Communication
>
> Programs can call each other using address(this) and shared storage:
>
> ```solidity theme={null}
> // Calling another program's function
> uint256 balance = ERC20Facet(address(this)).balanceOf(user);
>
> // Reading shared storage (if designed that way)
> bytes32 sharedPosition = keccak256("ctm.shared.data");
> ```

## Security Considerations

> [!WARNING]
>
> **Critical Security Points:**
>
> 1. **Storage Layout:** Never use standard global state variables. Always use the diamond storage pattern with unique keccak256 slots.
>
> 2. **Access Control:** The `diamondCut` function is extremely powerful. Ensure it's protected by robust ownership or governance control.
>
> 3. **Stateless Logic:** Programs are logic contracts and should not hold funds or have constructors that set state.
>
> 4. **Testing:** Thoroughly test all Programs before deployment. Once added to a CTM, they have access to the token's storage and capabilities.

## Auditing Checklist

Before deploying CTM or adding new Programs:

* [ ] Storage slots use unique keccak256 hashes
* [ ] No global state variables in Programs
* [ ] Access control properly configured
* [ ] Programs don't hold funds directly
* [ ] All Programs thoroughly tested
* [ ] diamondCut function is protected
* [ ] Inter-program interactions tested
* [ ] Gas optimization reviewed
* [ ] Security audit completed (for production)

## Advanced Examples

### Staking Program

```solidity theme={null}
contract StakingProgram {
    struct StakingStorage {
        mapping(address => uint256) stakedAmount;
        mapping(address => uint256) stakingTimestamp;
        uint256 rewardRate; // rewards per second
    }

    bytes32 constant STAKING_STORAGE = keccak256("ctm.program.staking");

    function stakingStorage() internal pure 
        returns (StakingStorage storage ss) 
    {
        bytes32 position = STAKING_STORAGE;
        assembly { ss.slot := position }
    }

    function stake(uint256 amount) external {
        ERC20Facet token = ERC20Facet(address(this));
        require(token.transferFrom(msg.sender, address(this), amount), "Transfer failed");
        
        StakingStorage storage ss = stakingStorage();
        ss.stakedAmount[msg.sender] += amount;
        ss.stakingTimestamp[msg.sender] = block.timestamp;
    }

    function unstake(uint256 amount) external {
        StakingStorage storage ss = stakingStorage();
        require(ss.stakedAmount[msg.sender] >= amount, "Insufficient stake");
        
        uint256 rewards = calculateRewards(msg.sender);
        ss.stakedAmount[msg.sender] -= amount;
        
        ERC20Facet token = ERC20Facet(address(this));
        require(token.transfer(msg.sender, amount + rewards), "Transfer failed");
    }

    function calculateRewards(address user) public view returns (uint256) {
        StakingStorage storage ss = stakingStorage();
        uint256 timeStaked = block.timestamp - ss.stakingTimestamp[user];
        return ss.stakedAmount[user] * ss.rewardRate * timeStaked / 1e18;
    }
}
```

### Governance Program

```solidity theme={null}
contract GovernanceProgram {
    struct GovernanceStorage {
        mapping(uint256 => Proposal) proposals;
        uint256 proposalCount;
        uint256 votingPeriod;
    }

    struct Proposal {
        string description;
        uint256 forVotes;
        uint256 againstVotes;
        uint256 endTime;
        bool executed;
    }

    bytes32 constant GOVERNANCE_STORAGE = keccak256("ctm.program.governance");

    function governanceStorage() internal pure 
        returns (GovernanceStorage storage gs) 
    {
        bytes32 position = GOVERNANCE_STORAGE;
        assembly { gs.slot := position }
    }

    function propose(string calldata description) external returns (uint256) {
        GovernanceStorage storage gs = governanceStorage();
        gs.proposalCount++;
        
        gs.proposals[gs.proposalCount] = Proposal({
            description: description,
            forVotes: 0,
            againstVotes: 0,
            endTime: block.timestamp + gs.votingPeriod,
            executed: false
        });
        
        return gs.proposalCount;
    }

    function vote(uint256 proposalId, bool support) external {
        GovernanceStorage storage gs = governanceStorage();
        Proposal storage proposal = gs.proposals[proposalId];
        
        require(block.timestamp < proposal.endTime, "Voting ended");
        
        uint256 weight = ERC20Facet(address(this)).balanceOf(msg.sender);
        
        if (support) {
            proposal.forVotes += weight;
        } else {
            proposal.againstVotes += weight;
        }
    }
}
```

## Resources

> [card] [GitHub Repository](https://github.com/Paxeer-Network/Pax-v3-coreCTM)
>
> View source code and examples

> [card] [Live Contract](https://paxscan.io/address/0x477A9f214c947e6D81b9d32b6b1883F4a4ffFb24)
>
> Explore on PaxScan

> [card] [EIP-2535 Specification](https://eips.ethereum.org/EIPS/eip-2535)
>
> Learn about Diamond Standard

> [card] [Developer Community](https://paxeer.app/developers)
>
> Join other CTM developers

## Next Steps

> [card] [Deploy Your First CTM](#quick-start)
>
> Follow the deployment guide

> [card] [Create Custom Programs](#creating-programs)
>
> Build your own logic modules

> [card] [Smart Contracts Guide](https://sidiorresearchlabs.mintlify.site/contracts.md)
>
> General contract deployment

> [card] [Configuration](https://sidiorresearchlabs.mintlify.site/configuration.md)
>
> Set up your development environment


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.