Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
8ad57a3
Migrated to OZ v5
KyrylR Mar 24, 2025
bed7a53
integrated with new versions of solarity and openzeppelin
aritkulova Mar 26, 2025
9812e15
updated package-lock
aritkulova Mar 26, 2025
c382599
switched to custom errors
aritkulova Mar 27, 2025
23ace8e
cleaned up
aritkulova Mar 27, 2025
1118e7f
refactored error naming
aritkulova Mar 27, 2025
764dc9a
renamed claimTopicKey to contextKey, claimTopic to handleTopic
aritkulova Mar 31, 2025
c9fe3e0
fixed typos
aritkulova Apr 2, 2025
b73bba0
fixed inits in example
aritkulova Apr 2, 2025
58c7181
returned accidentally missing part
aritkulova Apr 2, 2025
aac0246
updated examples folder
aritkulova Apr 4, 2025
8d8d53d
Added erc721 (#7)
aritkulova Apr 8, 2025
554b25e
fixed typos
aritkulova Apr 8, 2025
cbfa65d
created IAssetF interface for Context and common errors
aritkulova Apr 8, 2025
29e3462
added onlyInitializing to init functions
aritkulova Apr 8, 2025
54539df
updated minimal solidity version to ^0.8.21
aritkulova Apr 9, 2025
e3fb73f
added storage buckets to the modules
aritkulova Apr 9, 2025
4f42e86
updated the architecture diagram
aritkulova Apr 9, 2025
8d67588
updated version to 0.3.0
aritkulova Apr 9, 2025
93fd17f
added tokenURI to NFTF
aritkulova Apr 11, 2025
759f311
updated diagram to capture ERC20 and ERC721
aritkulova Apr 11, 2025
383263f
updated dependency
aritkulova Apr 14, 2025
c7aaa95
fixed diagram
aritkulova Apr 15, 2025
3bccb9f
few fixes
Arvolear Apr 16, 2025
bede6ef
moved TokenF and NFTF contracts from core folder
aritkulova Apr 16, 2025
ce475a0
updated diagram
aritkulova Apr 16, 2025
3442b57
calldata -> memory in public functions
aritkulova Apr 16, 2025
04e3b12
TransferLimitsModule -> ERC20TransferLimitsModule
aritkulova Apr 16, 2025
4829b56
EquityNFT -> LandNFT
aritkulova Apr 16, 2025
f3d61ec
added ERC721TransferLimitsModule
aritkulova Apr 17, 2025
dfc5a46
added LandERC721TransferLimitsModule to examples
aritkulova Apr 17, 2025
af81d51
added INFTF to supported interfaces
aritkulova Apr 17, 2025
d6b676a
updated scripts
aritkulova Apr 17, 2025
8ecf012
added AbstractAssetF contract
aritkulova Apr 18, 2025
798f81e
order consistency fix
aritkulova Apr 18, 2025
8d39297
fixed ERC721TransferLimitsModule formula
aritkulova Apr 18, 2025
9bddc87
cleaned up ERC721TransferLimitsModule test
aritkulova Apr 18, 2025
6b1dead
review fix
aritkulova Apr 20, 2025
80fa17b
updated diagram
aritkulova Apr 20, 2025
5797088
fix
aritkulova Apr 20, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 0 additions & 11 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,12 +1 @@
# Deployer private key
PRIVATE_KEY=YOUR PRIVATE KEY

# RPC Endpoints
INFURA_KEY=INFURA PROJECT ID

# Additional keys
ETHERSCAN_KEY=ETHERSCAN API KEY
BSCSCAN_KEY=BSCSCAN API KEY
POLYGONSCAN_KEY=POLYGONSCAN API KEY
AVALANCHE_KEY=AVALANCHE API KEY
COINMARKETCAP_KEY=COINMARKETCAP API KEY
4 changes: 3 additions & 1 deletion .solhint.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
"func-visibility": "off",
"max-states-count": "off",
"not-rely-on-time": "off",
"compiler-version": "off"
"compiler-version": "off",
"func-name-mixedcase": "off",
"no-inline-assembly": "off"
}
}
33 changes: 22 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,29 @@

Bring Real World Assets (RWA) on-chain via flexible tokenization framework - TokenF.

!["TokenF Architecture"](https://github.com/dl-tokenf/core-contracts/assets/47551140/9e912d07-bc4d-407d-bf25-859e0da40f32)
TokenF and NFTF architecture:

!["AssetF Architecture"](https://github.com/user-attachments/assets/5594c199-db9b-4aa3-b16a-5b464621311c)

Built with [Solarity](https://github.com/dl-solarity), [OpenZeppelin](https://github.com/OpenZeppelin/openzeppelin-contracts), and aspiration to perfection.

Built with [Solarity](https://github.com/dl-solarity), [Openzeppelin](https://github.com/OpenZeppelin/openzeppelin-contracts), and aspiration to perfection.

## Application

TokenF is an on-chain framework that enables development, management, and deployment of permissioned ERC-20-compatible assets on EVM networks. TokenF enables custom rules to be configured for RWA tokens, providing flexible KYC/AML and regulatory compliance checks for the users to abide during interaction with the smart contracts.
TokenF is an on-chain framework that enables development, management, and deployment of permissioned ERC-20-compatible and ERC-721-compatible assets on EVM networks. TokenF enables custom rules to be configured for RWA tokens, providing flexible KYC/AML and regulatory compliance checks for the users to abide during interaction with the smart contracts.

TokenF is built with certain levels of abstraction in mind:
TokenF is built with certain levels of abstraction in mind:

- ERC-2535 Diamond beating heart that allows extensibility and upgradeability.
- Support of custom compliance modules to be plugged in the TokenF core.
- Rich configuration of check/hooks/behavior with imagination being the only limit.

| **What TokenF Is ✅** | **What TokenF Is Not ❌** |
| :-----------------------------------------: | :------------------------------: |
| On-chain tokenization framework | Fullstack tokenization framework |
| Smart contracts to configure RWA behavior | RWA launchpad/RWA consulting set |
| Reimagined and enhanced ERC-3643 alternative | Yet another ERC-3643 copy |
| **What TokenF Is ✅** | **What TokenF Is Not ❌** |
| :-----------------------------------------: | :---------------------------------: |
| On-chain tokenization framework | Fullstack tokenization framework |
| Smart contracts to configure RWA behavior | RWA launchpad/RWA consulting set |
| Built from scratch ERC-3643 alternative | Yet another ERC-3643 copy |
| Support of both ERC-20 and ERC-721 standards | Currently does not support ERC-1155 |

> [!NOTE]
> TokenF is at the early stage of development, many breaking changes are foreseen.
Expand All @@ -41,13 +45,20 @@ npm install @tokenf/contracts
You will then be able to start using TokenF:

```solidity
pragma solidity ^0.8.20;
pragma solidity ^0.8.21;

import {TokenF} from "@tokenf/contracts/core/TokenF.sol";
import {TokenF} from "@tokenf/contracts/TokenF.sol";
import {NFTF} from "@tokenf/contracts/NFTF.sol";

contract EquityToken is TokenF {
. . .
}

// or

contract LandNft is NFTF {
. . .
}
```

> [!TIP]
Expand Down
82 changes: 82 additions & 0 deletions contracts/AbstractAssetF.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.21;

import {Diamond} from "@solarity/solidity-lib/diamond/Diamond.sol";

import {IAssetF} from "./interfaces/IAssetF.sol";
import {IKYCCompliance} from "./interfaces/core/IKYCCompliance.sol";
import {IRegulatoryCompliance} from "./interfaces/core/IRegulatoryCompliance.sol";

import {AgentAccessControl} from "./core/AgentAccessControl.sol";
import {RegulatoryComplianceStorage} from "./storages/core/RegulatoryComplianceStorage.sol";
import {KYCComplianceStorage} from "./storages/core/KYCComplianceStorage.sol";

abstract contract AbstractAssetF is IAssetF, Diamond, AgentAccessControl {
bytes4 public constant RECOVERY_SELECTOR = this.recovery.selector;

function __AbstractAssetF_init(
address regulatoryCompliance_,
address kycCompliance_,
bytes memory initRegulatory_,
bytes memory initKYC_
) internal virtual onlyInitializing {
bytes4[] memory rComplianceSelectors_ = new bytes4[](6);
rComplianceSelectors_[0] = IRegulatoryCompliance.addRegulatoryModules.selector;
rComplianceSelectors_[1] = IRegulatoryCompliance.removeRegulatoryModules.selector;
rComplianceSelectors_[2] = IRegulatoryCompliance.transferred.selector;
rComplianceSelectors_[3] = IRegulatoryCompliance.canTransfer.selector;
rComplianceSelectors_[4] = RegulatoryComplianceStorage.getRegulatoryModules.selector;
rComplianceSelectors_[5] = RegulatoryComplianceStorage.getRegulatoryModulesCount.selector;

bytes4[] memory kycComplianceSelectors_ = new bytes4[](5);
kycComplianceSelectors_[0] = IKYCCompliance.addKYCModules.selector;
kycComplianceSelectors_[1] = IKYCCompliance.removeKYCModules.selector;
kycComplianceSelectors_[2] = IKYCCompliance.isKYCed.selector;
kycComplianceSelectors_[3] = KYCComplianceStorage.getKYCModules.selector;
kycComplianceSelectors_[4] = KYCComplianceStorage.getKYCModulesCount.selector;

Facet[] memory facets_ = new Facet[](2);
facets_[0] = Facet(regulatoryCompliance_, FacetAction.Add, rComplianceSelectors_);
facets_[1] = Facet(kycCompliance_, FacetAction.Add, kycComplianceSelectors_);

_diamondCut(facets_, address(0), "");
_diamondCut(new Facet[](0), regulatoryCompliance_, initRegulatory_);
_diamondCut(new Facet[](0), kycCompliance_, initKYC_);
}

/// @inheritdoc IAssetF
function diamondCut(
Facet[] memory modules_
) public virtual override onlyRole(_diamondCutRole()) {
diamondCut(modules_, address(0), "");
}

/// @inheritdoc IAssetF
function diamondCut(
Facet[] memory modules_,
address initModule_,
bytes memory initData_
) public virtual override onlyRole(_diamondCutRole()) {
_diamondCut(modules_, initModule_, initData_);
}

function _mintRole() internal view virtual returns (bytes32) {
return AGENT_ROLE;
}

function _burnRole() internal view virtual returns (bytes32) {
return AGENT_ROLE;
}

function _forcedTransferRole() internal view virtual returns (bytes32) {
return AGENT_ROLE;
}

function _recoveryRole() internal view virtual returns (bytes32) {
return AGENT_ROLE;
}

function _diamondCutRole() internal view virtual returns (bytes32) {
return AGENT_ROLE;
}
}
Loading