Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
KyrylR committed Jul 12, 2024
0 parents commit c27ed48
Show file tree
Hide file tree
Showing 54 changed files with 26,757 additions and 0 deletions.
11 changes: 11 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[*]
charset = utf-8
end_of_line = lf
indent_style = space
insert_final_newline = true
[*ts]
indent_size = 2
max_line_length = 120
[*.sol]
indent_size = 4
max_line_length = 99
24 changes: 24 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Deployer private key
PRIVATE_KEY=YOUR PRIVATE KEY

# RPC Endpoints
INFURA_KEY=INFURA PROJECT ID
DEV_RPC_ENDPOINT=ENDPOINT WITH PORT

# Additional keys
ETHERSCAN_KEY=ETHERSCAN API KEY
BSCSCAN_KEY=BSCSCAN API KEY
COINMARKETCAP_KEY=COINMARKETCAP API KEY

# Token Factory init config path
CONFIG_FILE_PATH=FULL PATH TO THE CONFIG JSON

# Available targets: 'ethers-v5', 'truffle-v5' and 'web3-v1'
# By default 'ethers-v5'
TYPECHAIN_TARGET=TYPECHAIN TARGET

# Vault
VAULT_ENDPOINT=ENDPOINT WITH PORT TO VAULT SERVER
VAULT_TOKEN=VAULT PRIVATE TOKEN
VAULT_FETCH_CONFIG_PATH=FULL PATH ON VAULT TO FETCH THE CORE CONFIG
VAULT_UPLOAD_CONFIG_PATH=FULL PATH ON VAULT TO SAVE CONFIG FOR GRAPH
30 changes: 30 additions & 0 deletions .github/ISSUE_TEMPLATE/bug-report.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
name: Bug Report
description: File a bug report
labels: ['bug']
assignees:
-
body:
- type: markdown
attributes:
value: Thanks for taking the time to fill out this bug report!
- type: input
id: version
attributes:
label: "Project version"
placeholder: "1.2.3"
validations:
required: true
- type: textarea
id: what-happened
attributes:
label: What happened?
description: A brief description of what happened and what you expected to happen
validations:
required: true
- type: textarea
id: reproduction-steps
attributes:
label: "Minimal reproduction steps"
description: "The minimal steps needed to reproduce the bug"
validations:
required: true
13 changes: 13 additions & 0 deletions .github/ISSUE_TEMPLATE/feature-request.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
name: Feature request
description: Suggest a new feature
labels: ['feature']
assignees:
-
body:
- type: textarea
id: feature-description
attributes:
label: "Describe the feature"
description: "A description of what you would like to see in the project"
validations:
required: true
4 changes: 4 additions & 0 deletions .github/ISSUE_TEMPLATE/other-issue.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
name: Other issue
about: Other kind of issue
---
16 changes: 16 additions & 0 deletions .github/actions/setup/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
name: setup

description: setup

runs:
using: composite
steps:
- name: Setup node
uses: actions/setup-node@v3
with:
node-version: "18.x"
cache: npm

- name: Install packages
run: npm install
shell: bash
23 changes: 23 additions & 0 deletions .github/workflows/checks.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
name: "checks"

on:
push:
branches:
- main
pull_request:
branches:
- main
- dev

jobs:
test:
runs-on: ubuntu-latest
steps:
- name: Checkout the repository
uses: actions/checkout@v3

- name: Setup
uses: ./.github/actions/setup

- name: Run tests
run: npm run test
13 changes: 13 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
node_modules
.env
.DS_Store

# Hardhat files
cache
artifacts
coverage.json
coverage

# Typechain generated files
generated-types
generated-markups
4 changes: 4 additions & 0 deletions .husky/pre-commit
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"

npm run lint-fix && git add -u
21 changes: 21 additions & 0 deletions .prettierrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"overrides": [
{
"files": "*.sol",
"options": {
"printWidth": 99,
"tabWidth": 4,
"useTabs": false,
"singleQuote": false,
"bracketSpacing": false
}
},
{
"files": "*.ts",
"options": {
"printWidth": 120,
"tabWidth": 2
}
}
]
}
4 changes: 4 additions & 0 deletions .solcover.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
module.exports = {
skipFiles: ["interfaces/", "mock/"],
configureYulOptimizer: true,
};
18 changes: 18 additions & 0 deletions .solhint.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"extends": "solhint:recommended",
"plugins": ["prettier"],
"rules": {
"reentrancy": "error",
"prettier/prettier": "warn",
"modifier-name-mixedcase": "off",
"func-name-mixedcase": "off",
"no-empty-blocks": "warn",
"func-visibility": "warn",
"max-states-count": "warn",
"not-rely-on-time": "warn",
"compiler-version": "off",
"gas-custom-errors": "off",
"var-name-mixedcase": "off",
"reason-string": "off"
}
}
28 changes: 28 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Token factory contract for TokenE

This repository represents the token factory module smart contracts part of the operating system.

## What

This is a token factory module to enable deployment of `TERC20` and `TERC721` tokens on TokenE. The module integrates with the TokenE core through NPM. The module provides special reviewable requests that deploy tokens if accepted and uses `MasterAccessManagement` contract to control access.

It consists of 4 main contract:

1. `TokenFactory`
2. `TokenRegistry`
3. `TERC20`
4. `TERC721`

The `TokenFactory` and `TokenRegistry` work in pair as a beacon proxy factory & registry. More about this pattern can be found [here](https://github.com/dl-solidity-library/dev-modules/tree/master/contracts/contracts-registry/pools).

The `TERC20` token is a custom `ERC20` token with permissioned access to mint, burn, receive, and spend tokens.

The `TERC721` token is a custom `ERC721` token with permissioned access to mint, burn, receive, and spend tokens, which also comes with extended token URI capabilities.

## Integration

This module is currently not supposed to be integrated with.

## License

The TokenE core is released under the custom License. Please take a look to understand the limitations.
149 changes: 149 additions & 0 deletions contracts/factory/TokenFactory.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.17;

import {Strings} from "@openzeppelin/contracts/utils/Strings.sol";

import {AbstractPoolFactory} from "@solarity/solidity-lib/contracts-registry/pools/pool-factory/AbstractPoolFactory.sol";

import {ReviewableRequests} from "@tokene/core-contracts/core/ReviewableRequests.sol";
import {MasterContractsRegistry} from "@tokene/core-contracts/core/MasterContractsRegistry.sol";
import {MasterAccessManagement} from "@tokene/core-contracts/core/MasterAccessManagement.sol";

import {ITERC20} from "../interfaces/tokens/ITERC20.sol";
import {ITERC721} from "../interfaces/tokens/ITERC721.sol";
import {ITokenFactory} from "../interfaces/factory/ITokenFactory.sol";

import {TERC20} from "../tokens/TERC20.sol";
import {TERC721} from "../tokens/TERC721.sol";
import {TokenRegistry} from "./TokenRegistry.sol";

/**
* @notice The TokenFactory contract which is a part of the token factory TokenE module. It is used to request the deployment of
* TERC20 and TERC721 tokens via the ReviewableRequests core contract. Deploys beacon proxies.
*
* The access control is realized via MasterAccessManagement.
*/
contract TokenFactory is ITokenFactory, AbstractPoolFactory {
using Strings for uint256;

string public constant CREATE_PERMISSION = "CREATE";
string public constant EXECUTE_PERMISSION = "EXECUTE";

string public constant TOKEN_FACTORY_RESOURCE = "TOKEN_FACTORY_RESOURCE";

string public constant TOKEN_REGISTRY_DEP = "TOKEN_REGISTRY";

MasterAccessManagement internal _masterAccess;
ReviewableRequests internal _reviewableRequests;
TokenRegistry internal _tokenRegistry;

modifier onlyCreatePermission() {
_requirePermission(CREATE_PERMISSION);
_;
}

modifier onlyExecutePermission() {
_requirePermission(EXECUTE_PERMISSION);
_;
}

/**
* @notice The function to set dependencies
* @dev Access: the injector address
* @param registryAddress_ the ContractsRegistry address
* @param data_ empty additional data
*/
function setDependencies(address registryAddress_, bytes memory data_) public override {
super.setDependencies(registryAddress_, data_);

MasterContractsRegistry registry_ = MasterContractsRegistry(registryAddress_);

_masterAccess = MasterAccessManagement(registry_.getMasterAccessManagement());
_reviewableRequests = ReviewableRequests(registry_.getReviewableRequests());
_tokenRegistry = TokenRegistry(registry_.getContract(TOKEN_REGISTRY_DEP));
}

/**
* @inheritdoc ITokenFactory
*/
function requestTERC20(
ITERC20.ConstructorParams calldata params_,
string calldata description_
) external override onlyCreatePermission {
bytes memory data_ = abi.encodeWithSelector(this.deployTERC20.selector, params_);

_reviewableRequests.createRequest(address(this), data_, "", "TERC20", description_);
}

/**
* @inheritdoc ITokenFactory
*/
function deployTERC20(
ITERC20.ConstructorParams calldata params_
) external override onlyExecutePermission {
string memory tokenType_ = _tokenRegistry.TERC20_NAME();

address tokenProxy_ = _deploy(address(_tokenRegistry), tokenType_);

string memory tokenResource_ = _getTokenResource(tokenType_, tokenProxy_);

TERC20(tokenProxy_).__TERC20_init(params_, tokenResource_);

_register(address(_tokenRegistry), tokenType_, tokenProxy_);
_injectDependencies(address(_tokenRegistry), tokenProxy_);

emit DeployedTERC20(tokenProxy_, params_);
}

/**
* @inheritdoc ITokenFactory
*/
function requestTERC721(
ITERC721.ConstructorParams calldata params_,
string calldata description_
) external override onlyCreatePermission {
bytes memory data_ = abi.encodeWithSelector(this.deployTERC721.selector, params_);

_reviewableRequests.createRequest(address(this), data_, "", "TERC721", description_);
}

/**
* @inheritdoc ITokenFactory
*/
function deployTERC721(
ITERC721.ConstructorParams calldata params_
) external override onlyExecutePermission {
string memory tokenType_ = _tokenRegistry.TERC721_NAME();

address tokenProxy_ = _deploy(address(_tokenRegistry), tokenType_);

string memory tokenResource_ = _getTokenResource(tokenType_, tokenProxy_);

TERC721(tokenProxy_).__TERC721_init(params_, tokenResource_);

_register(address(_tokenRegistry), tokenType_, tokenProxy_);
_injectDependencies(address(_tokenRegistry), tokenProxy_);

emit DeployedTERC721(tokenProxy_, params_);
}

/**
* @notice The internal function to calculate the resource of the deployed tokens
*/
function _getTokenResource(
string memory tokenType_,
address tokenProxy_
) internal pure returns (string memory) {
return string.concat(tokenType_, ":", uint256(uint160(tokenProxy_)).toHexString(20));
}

/**
* @notice The internal function to optimize the bytecode for the permission check
*/
function _requirePermission(string memory permission_) internal view {
require(
_masterAccess.hasPermission(msg.sender, TOKEN_FACTORY_RESOURCE, permission_),
"TokenFactory: access denied"
);
}
}
Loading

0 comments on commit c27ed48

Please sign in to comment.