Coder Social home page Coder Social logo

consensys / universaltoken Goto Github PK

View Code? Open in Web Editor NEW
337.0 23.0 184.0 21.31 MB

Implementation of Universal Token for Assets and Payments

License: Apache License 2.0

JavaScript 74.01% Makefile 0.07% Solidity 25.92%
ethereum erc1400 sto security erc20 universal token finance asset codefi

universaltoken's Introduction

Codefi

Overview of the repo

Introduction

Never heard of tokenization

--> See introduction here.

Never hear of Universal Token for Assets and Payments

--> See webinar recording here.

--> See blog article here.

Blockchain technology and more specifically the emergence of "programmable" tokens have opened a world of new possibilities for financial assets: the creation of digital assets. Digital assets are financial assets, which have been "tokenized". This means each asset is represented by a token on the blockchain.

As introduced by the token taxonomy framework, there are 3 main categories of tokens:

  • Fungible tokens: Fungible tokens are all identical and cannot be distinguished from each other. Each individual token is essentially interchangeable, like US dollars, company shares, or ounces of gold. This is probably the simplest and most common category of tokens.
  • Non-fungible tokens: A non-fungible token is unique. Non-fungible tokens (NFTs) are used to create verifiable digital scarcity, as well as representing asset ownership of things like real estate, luxury goods, works of art, or collectible objects in video games (CryptoKitties is an early example). Essentially, NFTs are used for items which require a unique digital fingerprint.
  • Hybrid tokens: Hybrid tokens are a mix of both. Each token belongs to a class (sometimes also called category/partition/tranche). Inside a given class, all tokens are the same: they are fungible. But tokens from different classes can be distinguished from each other: they are non-fungible. By combining both advantages of fungibility and non-fungibility, hybrid tokens often appear as a relevant way to represent financial assets.

Picture8

Token standards have emerged in the Ethereum community.

ERC20 is the most basic and most adopted token standard. It can be seen as the "axiom of fungible token standards" and is compatible with the majority of existing tools and platforms.

ERC1400 is a hybrid token standard precisely designed for the use case of tokenized financial assets:

  • By being ERC20 retrocompatible, it remains compatible with the majority of existing tools and platforms.
  • By being partially-fungible (hybrid token), it allows to represent different classes of assets, perform more evolved token actions (lock tokens, collateralize tokens, etc.), which is essential in the context of corporate actions.
  • By offering the possibility to attach data to transfers, strong control over token transfers, based on granular certificate checks can be setup by issuers.

The following repository contains the ERC1400 implementation used by the Codefi Assets platform.

Why do we need a Universal Token for Assets and Payments?

Picture10

When we started developing the token, we knew that the future would sit at the intersection of traditional finance and decentralized finance. Our ambition was to find a way to create a bridge between both worlds. But as of today, those 2 have very different characteristics:

  • DeCentralised finance is still reserved mainly for crypto-friendly investors, and has difficulties attracting more traditional ones
  • Traditional finance still requires strong control capabilities over issued assets, while DeFi fosters more on simplicity of access and processes automation
  • Finally the first one relies on trust in the law, and financial institutions, while the latter relies on trust in the code

Now the question is:

  • How do we reconcile those 2 worlds?
  • How do we increase the diversity and the volume of assets in the DeFi world?
  • How can we release traditional assets in the DeFi economy, in order to benefit from the advantages it provides?

Picture11

The future looks like this. A world where DeFi automation mechanisms are extended to traditional assets, while remaining compliant with existing regulatory constraints.

Of course this can not happen in one day, and Codefi’s mission is to make the transition painless. We want to SMOOTHLY introduce traditional investors to the world of DeFi, without ignoring requirements of the existing system.

Today, DeFi is still reserved for “early adopters”. Accepting the constraints of the existing system (strong issuer or regulator control capabilities, legal agreements, investor verification, etc.) is the only way to convince the “early majority” to adopt a new mindset.

Building upon the existing system is the only way to increase adoption.

What are the main challenges to overcome?

Picture12

4 major requirements to overcome, to make the CeFi <> DeFi convergence a reality are the following:

  • Adapted control mechanisms: it’s a legal requirement for asset issuers in traditional finance to be empowered with strong control capabilities over issued assets
  • Permanent reliability of investor registry: asset issuers are accountable for maintaining a reliable investor registry
  • Certainty of execution for delivery-vs-payment: delivery-vs-payment operations on the secondary market, need to be the result of mechanisms that can not fail
  • Interoperability with the Ethereum ecosystem: all those requirements need to be taken into account while remaining compatible with the Ethereum ecosystem and more specifically with the DeFi tools

We’ll now deep dive into those 4 requirements to see what essential features a universal token for assets and payments shall offer.

Interoperability with the Ethereum ecosystem

Picture13

ERC20 interface

One of the things that Ethereum has done best is its token standards. The whole Ethereum community has reached consensus on those standards. A rich ecosystem of tools and platforms has emerged. The most well-known token standard is called ERC20: it is an interface for fungible tokens.

Its “transfer” and “balanceOf” functions are now pre-requisites to be compatible with wallets and key custody solutions, like Metamask of Ledger hardware wallets.

Its “allowance” and “transferFrom” functions are important for interoperability with other smart contracts. Airswap p2p trading plaform uses those functions to execute delivery-vs-payment operations.

Possibility to escrow tokens

Another important aspect for interoperability is the possibility to escrow tokens.

Escrow a token means accepting a smart contract to be the owner of the token (instead of a human person). Token escrow mechanisms are used by lots of DeFi smart contract:

  • Lending contracts like Compound need escrows to store collateralized tokens
  • Decentralized exchanges like Uniswap or derivatives platforms like Synthetix need escrows to create liquidity pools

In the end, an ERC20 interface + the possibility to escrow tokens are mandatory to be compatible with the Ethereum ecosystem.

Control Mechanisms

Second major topic for assets and payments is control mechanisms.

Picture14

When building financial instruments, controlling who has access to a specific instrument is paramount. Every asset distribution, or asset transfer needs to be controlled by the issuer of the asset. There are two main solution that we’ve implemented.

  • Certificates generated off-chain: a certificate is a signed hash of the transaction parameters. A new certificate needs to be created for every new transfer. This offers very strong control capabilities. But unfortunately, it is not compatible with the ERC20 interface, thus making things more complex when it comes towards interoperability with the Ethereum ecosystem.
  • List of validated investors stored on-chain: the token smart contract just consults this list every time it needs to perform a transfer. In the future, we can envision a world where such global allowlists will be curated by consortiums of financial institutions or even regulators themselves, but today, those don’t exist. This method lacks flexibility since an Ethereum transaction is required everytime we need to modify the list. But the good thing is, it allows to use the ERC20 transfer function, thus making it interoperable with the Ethereum ecosystem.

Picture15

In traditional finance, correct maintenance of a registry is the responsibility of very large institutions, like central security depositories, transfer agent or even issuers themselves in some cases. These institutions must retain full control over the registry. When the token is configured to be “controllable”, it provides the issuer with the capability to force token transfers, token creation, or destruction.

It is not the case in DeFi, where no one but the token holder can decide to transfer a token. This is seen by some as a really powerful feature, moving trust at the core of a protocol rather than in a public or private authority.

Both setups, controllable or not, can be adapted, depending on the use case, and the “renounceControl” function allows to switch from one setup to the other.

Reliability of investor registry

Picture16

When moving traditional securities on a public blockchain network, a fundamental principle needs to be respected: the created ownership registry shall at all time, reflect the beneficial holder of the assets.

Problem is, when this requirement is not compatible with the escrow mechanism. Indeed, on the right of this picture, when Joe escrow’s 4 token in an escrow contract, the owner of the token is the escrow contract and not Joe. This makes it complicated, or even sometimes impossible to know, that Joe is the beneficial owner of the assets. We lose the one essential feature of the blockchain as registry maintenance tool.

Initially, the reason why we need to send tokens to an escrow, is to lock them and make sure they CAN'T be spent.

Token holds, that you can see on the left of the image, are an alternative to escrows, allowing to lock tokens while keeping them in the wallet of the investor. The good point with token holds is they preserve the investor registry, and ensure at any time we know who is the beneficial owner of the asset.

Token holds are also very useful when it comes to distributing dividends to investors, in proportion to the amount of token they own, because we’re sure the investor registry is reliable.

Certainty of Execution for Delivery-vs-Payment

Picture17

Delivery-vs-payment is an operation that consists in exchanging token representing cash against tokens representing assets. Delivery-vs-payment is a very powerful blockchain use case, as it can be done without middleman, but with certainty of execution.

Allowances and escrows

In today’s DeFi, most DvP use cases either rely on allowances or escrows in order to manage token exchanges. Both allowances and escrows are not optimal:

  • Allowance mechanisms don’t provide certainty of execution for delivery vs payment (since the allowance doesn’t prevent the user for spending his tokens for something else after he has created a trade order)
  • Escrow mechanisms do provide certainty of execution, but as described above, escrows do not preserve the accuracy of the registry (since the escrow contract becomes the owner of the tokens, instead of the investor).

Token holds

Since allowances and escrows are not optimal, we’ve decided to use holds. A hold, similarly to an allowance, is an authorization created by the token holder, to allow someone else to transfer his tokens on his behalf. But a hold goes further than an allowance, by forbidding the holder to spend the tokens for something else, once the hold is created. The tokens are like locked on his own account.

Delivery-vs-payment based on token holds combines both:

  • The advantage of the escrow, that tokens can not be spent for something else before the trade execution
  • The advantage of the allowance, that preserves a reliable token registry

HTLC (Hash Time Locked Contract)

Moreover, token holds are compatible with HTLC mechanism. HTLC is a useful mechanism (description will be added soon) that allows to manage cases where atomic delivery-vs-payment can not be performed:

  • Either when the cash token and asset tokens are on 2 different blockchain networks
  • Or when the cash token and asset tokens are private smart contracts (privacy groups, or zkAssets)

What shall the Universal Token for Assets and Payments look like?

With all requirements detailed above in mind, here’s and overview of the universal token for assets and payments.

Picture18

As belonging to the hybrid token category, it benefits from both:

  • Advantages of fungibility
  • Advantages of non-fungibility

It combines all requirements listed in this presentation:

  • For control mechanisms, it offers a module for certificate checks and a module for allowlist checks + it offers the possibility to force transfers
  • For reliability of investor registry, it provides a module to create token holds
  • For certainty of delivery-vs-payment execution, it includes token holds for atomic Swaps, and HTLC mechanism for non-atomic Swaps
  • For interoperability, it offers an ERC20 interface

The features can be turned ON and OFF during the token’s lifecycle.

We believe this modular approach offers enough flexibility to satisfy both traditional stakeholders and crypto-friendly publics, in order to make the DeFi <> CeFi convergence a reality.

Picture19

The hybrid structure of the token even allows, to setup different modules for the different classes of the token:

  • some classes can be setup for traditional finance, by being controllable, and including the certificate module
  • other classes can be setup for decentralized finance, and rely on an allowlist module

Tokens can switch from a token class to another, with an on-ramp/off-ramp mechanism.

Moving tokens from a class to another allows to easily change how they are controlled.

This means the token allows to operate on both CeFi and DeFi at the same time:

  • Rigth now, financial instruments can be issued with a setup adapted to the current regulatory context
  • Later, the setup can be gradually adapted for Decentralized Finance when the regulation becomes clearer

Picture20

In conclusion, universal token is modular, evolutive, and can be adapted to multiple use cases, thus making it a relevant standard to achieve unification of 2 worlds.

The possibility to turn features on and off at any time, allows to transition from CeFi to DeFi while keeping the same token.

The evolution of the law will allow traditional finance to slowly migrate towards more “decentralized” setups. On the other hand, DeFi tools’ interface will evolve to become compatible with a higher number of standards (by supporting token holds, certificates, etc.).

What is Codefi Assets?

Codefi Assets is an advanced institutional technology platform for issuance and management of tokenized financial assets, powered by the Ethereum blockchain. Codefi Assets is a product created by ConsenSys.

https://codefi.consensys.net/codefiassets

A platform for financial asset issuance & management

The current capital market still needs to overcome a few pain points:

  • Today, it is cumbersome and costly to issue an asset.
  • Once issued, the assets are mainly reserved for high-ticket investors.
  • Finally, those assets are not easily tradeable, which strongly limits the secondary market possibilities.

With Codefi Assets, we want to tokenize the capital market to tackle those pain points. In the new system, we imagine:

  • An asset issuance will be faster, simpler but also cheaper than today.
  • This reduction of costs will allow us to onboard smaller ticket investors.
  • Globally, the tokenization removes constraints for more liquid and frictionless asset transfers, while keeping a strong control over the market, thus liberating the secondary market.

Video demo of an asset issuance platform based on Codefi Assets technology

CodefiVideo

Link to video: https://www.youtube.com/watch?v=EWneY6Q_0ag&feature=youtu.be&ab_channel=MatthieuBouchaud

Quick overview of token standards (ERC20, ERC1400)

Picture1 Picture2 Picture3 Picture4

Description of ERC1400 standard

ERC1400 introduces new concepts on top of ERC20 token standard:

  • Granular transfer controls: Possibility to perform granular controls on the transfers with a system of certificates (injected in the additional data field of the transfer method)
  • Controllers: Empowerment of controllers with the ability to send tokens on behalf of other addresses (e.g. force transfer).
  • Partionned tokens (partial-fungibility): Every ERC1400 token can be partitioned. The partition of a token, can be seen as the state of a token. It is well adapted for representing, classes of assets, performing corporate actions, etc.
  • Document management: Possibility to bind tokens to hashes of legal documents, thus making the link between a blockchain transaction and the real world.

Optionally, the following features can also be added:

  • Hooks: Possibility for token senders/recipients to setup hooks, e.g. automated actions executed everytime they send/receive tokens, thanks to ERC1820.
  • Upgradeability: Use of ERC1820(eips.ethereum.org/EIPS/eip-1820) as central contract registry to follow smart contract migrations.

Focus on ERC1400 implementation choices

This implementation has been developed based on EIP-spec interface defined by the security token roundtable.

We've performed a few updates compared to the original submission, mainly to fit with business requirements + to save gas cost of contract deployment.

Choices made to fit with business requirements

  • Introduction of sender/recipient hooks (IERC1400TokensRecipient, IERC1400TokensSender). Those are inspired by ERC777 hooks, but they have been updated in order to support partitions, in order to become ERC1400-compliant.
  • Modification of view functions ('canTransferByPartition', 'canOperatorTransferByPartition') as consequence of our certificate design choice: the view functions need to have the exact same parameters as 'transferByPartition' and 'operatorTransferByPartition' in order to be in measure to confirm the certificate's validity.
  • Introduction of validator hook (IERC1400TokensValidator), to manage updates of the transfer validation policy across time (certificate, allowlist, blocklist, lock-up periods, investor caps, pauseability, etc.), thanks an upgradeable module.
  • Extension of ERC20's allowance feature to support partitions, in order to become ERC1400-compliant. This is particularly important for secondary market and delivery-vs-payment.
  • Possibility to migrate contract, and register new address in ERC1820 central registry, for smart contract upgradeability.

Choices made to save gas cost of contract deployment

  • Removal of controller functions ('controllerTransfer' and 'controllerRedeem') and events ('ControllerTransfer' and 'ControllerRedemption') to save gas cost of contract deployment. Those controller functionalities have been included in 'operatorTransferByPartition' and 'operatorRedeemByPartition' functions instead.
  • Export of 'canTransferByPartition' and 'canOperatorTransferByPartition' in optional checker hook IERC1400TokensChecker as those functions take a lot of place, although they are not essential, as the result they return can be deduced by calling other view functions of the contract.

NB: The original submission with discussion can be found at: github.com/ethereum/EIPs/issues/1411.

Interfaces

ERC1400 interface

The IERC1400 interface of this implementation is the following:

interface IERC1400 /*is IERC20*/ { // Interfaces can currently not inherit interfaces, but IERC1400 shall include IERC20

  // ****************** Document Management *******************
  function getDocument(bytes32 name) external view returns (string memory, bytes32);
  function setDocument(bytes32 name, string calldata uri, bytes32 documentHash) external;

  // ******************* Token Information ********************
  function balanceOfByPartition(bytes32 partition, address tokenHolder) external view returns (uint256);
  function partitionsOf(address tokenHolder) external view returns (bytes32[] memory);

  // *********************** Transfers ************************
  function transferWithData(address to, uint256 value, bytes calldata data) external;
  function transferFromWithData(address from, address to, uint256 value, bytes calldata data) external;

  // *************** Partition Token Transfers ****************
  function transferByPartition(bytes32 partition, address to, uint256 value, bytes calldata data) external returns (bytes32);
  function operatorTransferByPartition(bytes32 partition, address from, address to, uint256 value, bytes calldata data, bytes calldata operatorData) external returns (bytes32);

  // ****************** Controller Operation ******************
  function isControllable() external view returns (bool);
  // function controllerTransfer(address from, address to, uint256 value, bytes calldata data, bytes calldata operatorData) external; // removed because same action can be achieved with "operatorTransferByPartition"
  // function controllerRedeem(address tokenHolder, uint256 value, bytes calldata data, bytes calldata operatorData) external; // removed because same action can be achieved with "operatorRedeemByPartition"

  // ****************** Operator Management *******************
  function authorizeOperator(address operator) external;
  function revokeOperator(address operator) external;
  function authorizeOperatorByPartition(bytes32 partition, address operator) external;
  function revokeOperatorByPartition(bytes32 partition, address operator) external;

  // ****************** Operator Information ******************
  function isOperator(address operator, address tokenHolder) external view returns (bool);
  function isOperatorForPartition(bytes32 partition, address operator, address tokenHolder) external view returns (bool);

  // ********************* Token Issuance *********************
  function isIssuable() external view returns (bool);
  function issue(address tokenHolder, uint256 value, bytes calldata data) external;
  function issueByPartition(bytes32 partition, address tokenHolder, uint256 value, bytes calldata data) external;

  // ******************** Token Redemption ********************
  function redeem(uint256 value, bytes calldata data) external;
  function redeemFrom(address tokenHolder, uint256 value, bytes calldata data) external;
  function redeemByPartition(bytes32 partition, uint256 value, bytes calldata data) external;
  function operatorRedeemByPartition(bytes32 partition, address tokenHolder, uint256 value, bytes calldata operatorData) external;

  // ******************* Transfer Validity ********************
  // We use different transfer validity functions because those described in the interface don't allow to verify the certificate's validity.
  // Indeed, verifying the ecrtificate's validity requires to keeps the function's arguments in the exact same order as the transfer function.
  //
  // function canTransfer(address to, uint256 value, bytes calldata data) external view returns (byte, bytes32);
  // function canTransferFrom(address from, address to, uint256 value, bytes calldata data) external view returns (byte, bytes32);
  // function canTransferByPartition(address from, address to, bytes32 partition, uint256 value, bytes calldata data) external view returns (byte, bytes32, bytes32);    

  // ******************* Controller Events ********************
  // We don't use this event as we don't use "controllerTransfer"
  //   event ControllerTransfer(
  //       address controller,
  //       address indexed from,
  //       address indexed to,
  //       uint256 value,
  //       bytes data,
  //       bytes operatorData
  //   );
  //
  // We don't use this event as we don't use "controllerRedeem"
  //   event ControllerRedemption(
  //       address controller,
  //       address indexed tokenHolder,
  //       uint256 value,
  //       bytes data,
  //       bytes operatorData
  //   );

  // ******************** Document Events *********************
  event Document(bytes32 indexed name, string uri, bytes32 documentHash);

  // ******************** Transfer Events *********************
  event TransferByPartition(
      bytes32 indexed fromPartition,
      address operator,
      address indexed from,
      address indexed to,
      uint256 value,
      bytes data,
      bytes operatorData
  );

  event ChangedPartition(
      bytes32 indexed fromPartition,
      bytes32 indexed toPartition,
      uint256 value
  );

  // ******************** Operator Events *********************
  event AuthorizedOperator(address indexed operator, address indexed tokenHolder);
  event RevokedOperator(address indexed operator, address indexed tokenHolder);
  event AuthorizedOperatorByPartition(bytes32 indexed partition, address indexed operator, address indexed tokenHolder);
  event RevokedOperatorByPartition(bytes32 indexed partition, address indexed operator, address indexed tokenHolder);

  // ************** Issuance / Redemption Events **************
  event Issued(address indexed operator, address indexed to, uint256 value, bytes data);
  event Redeemed(address indexed operator, address indexed from, uint256 value, bytes data);
  event IssuedByPartition(bytes32 indexed partition, address indexed operator, address indexed to, uint256 value, bytes data, bytes operatorData);
  event RedeemedByPartition(bytes32 indexed partition, address indexed operator, address indexed from, uint256 value, bytes operatorData);

}

ERC1066 interface for reason codes

To improve the token holder experience, canTransfer MUST return a reason byte code on success or failure based on the ERC1066 application-specific status codes specified below. An implementation can also return arbitrary data as a bytes32 to provide additional information not captured by the reason code.

 * Code	Reason
 * 0x50	transfer failure
 * 0x51	transfer success
 * 0x52	insufficient balance
 * 0x53	insufficient allowance
 * 0x54	transfers halted (contract paused)
 * 0x55	funds locked (lockup period)
 * 0x56	invalid sender
 * 0x57	invalid receiver
 * 0x58	invalid operator (transfer agent)
 * 0x59	
 * 0x5a	
 * 0x5b	
 * 0x5a	
 * 0x5b	
 * 0x5c	
 * 0x5d	
 * 0x5e	
 * 0x5f	token meta or info

Quick start: How to test the contract?

Prerequisites: please make sure you installed "yarn" on your environment.

$ brew install yarn
$ brew install nvm

Test the smart contract, by running the following commands:

$ git clone https://github.com/ConsenSys/UniversalToken.git
$ cd UniversalToken
$ nvm use
$ yarn
$ yarn coverage

How to deploy the contract on a blockchain network?

Step1: Define Ethereum wallet and Ethereum network to use in ".env" file

A few environment variables need to be specified. Those can be added to a ".env" file: a template of it can be generated with the following command:

$ yarn env

The ".env" template contains the following variables:

MNEMONIC - Ethereum wallets which will be used by the webservice to sign the transactions - [MANDATORY] (see section "How to get a MNEMONIC?" in appendix)

INFURA_API_KEY - Key to access an Ethereum node via Infura service (for connection to mainnet or ropsten network) - [OPTIONAL - Only required if NETWORK = mainnet/ropsten] (see section "How to get an INFURA_API_KEY?" in appendix)

Step2: Deploy contract

Deploy contract on ganache

In case ganache is not installed:

$ yarn global add ganache-cli

Then launch ganache:

$ ganache-cli -p 7545

In a different console, deploy the contract by running the migration script:

$ yarn truffle migrate

Deploy contract on ropsten

Deploy the contract by running the migration script:

$ yarn truffle migrate --network ropsten

APPENDIX

How to get a MNEMONIC?

1.Find a MNEMONIC

There are 2 options to get MNEMONIC:

  • Either generate 12 random words on https://iancoleman.io/bip39/ (BIP39 Mnemonic).
  • Or get the MNEMONIC generated by ganache with the following command:
$ ganache-cli

The second option is recommended for development purposes since the wallets associated to the MNEMONIC will be pre-loaded with ETH for tests on ganache.

2.Load the wallet associated to the MNEMONIC with ether

If you've used ganache to generate your MNEMONIC and you only want to perform tests on ganache, you have nothing to do. The accounts are already loaded with 100 ETH.

For all other networks than ganache, you have to send ether to the accounts associated to the MNEMONIC:

How to get an INFURA_API_KEY?

INFURA_API_KEY can be generated by creating an account on https://infura.io/

universaltoken's People

Contributors

andreataglia avatar bmulocher avatar cleanunicorn avatar cryptotavares avatar ecp4224 avatar francescomiliani avatar gauthierpetetin avatar github-actions[bot] avatar izzygomez avatar jeamick avatar julien-marchand avatar kriys94 avatar magicking avatar naddison36 avatar nmvalera avatar onigiri-x avatar shane-t avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

universaltoken's Issues

Deploy on a private network with gasPrice set to 0 ?

Hi!

I'm trying to deploy all the contracts from your repo on a private network (IBFT2), where the gas price is set to 0, but I'm unable to deploy the ERC1400

At first, I needed to change the 2_erc1820_registry.js because the rawTx in the file was built presuming that the gas price is NOT 0 ( pasted the rawTx in here to decode: https://www.ethereumdecoder.com/)

So I built my own custom rawTx with these parameters:

const deployerAddress = '0xF90aCf91BdAB539aAC3093E5C5b207b562354401';

module.exports = async function (deployer, network, accounts) {
  if (network == "test") return; // test maintains own contracts

  // await web3.eth.sendTransaction({
  //   from: accounts[0], to: deployerAddress, value: web3.utils.toWei('0.1'),
  // });

  var rawTx;
  await web3.eth.signTransaction(
    {
      from: "0xF90aCf91BdAB539aAC3093E5C5b207b562354401",
      gas: 0,
      gasLimit: "0x0c3500",
    }
  ).then((result) => {
    console.log("Signed Transaction result: \n");
    console.log(result);
    rawTx = result.raw;
  });

  await web3.eth.sendSignedTransaction(rawTx).then((res) => {
    console.log("Res send signed: \n");
    console.log(res);
    console.log('\n   > ERC1820 deployment: Success -->', res.contractAddress);
  }).catch((err) => {
    // eslint-disable-next-line no-useless-escape
    if (err.message.search(/the tx doesn\'t have the correct nonce|Nonce too low/g) >= 0) {
      console.log('\n   > ERC1820 deployment: Invalid nonce, probably already deployed');
    } else {
      console.log('\n   > ERC1820 deployment: Unknown error', err);
    }
  });


};

With this code I'm able to deploy the ERC1820 on ganache and my private network where the gasPrice is set to 0

However, I have an issue deploying the next contract, ie ERC1400
On ganache, the error is Method eth_signTransaction not supported
And on my private network, the error is different: "ERC1400" hit an invalid opcode while deploying

My custom ERC1820 doesn't seem to be the problem because I have no issue deploying the custom ERC1820 and the other contracts to rinkeby or kovan (which by the way shouldn't be working since the gasPrice is NOT 0)

I'm deploying with truffle

Do you have any idea how I can solve this issue ?

Thanks

Contract code size over limit (24576 bytes)

Error while trying to deploy using remix

Error

Contract creation initialization returns data with length of more than 24576 bytes. The deployment will likely fails.
More info: eip-170

Is it possible to refactor the code to allow independently deploying the smaller contracts & referencing them in the parent contract using their interface?

Deploy the ERC1820 on a private network

Hi!

I'm trying to deploy all the contracts from your repo on a private network (IBFT2), where the gas price is set to 0, but I'm unable to deploy the ERC1820

Since there is no gas fee in my network, I changed the rawTx to fit my needs, but when I deploy the contract with truffle, the contract address returned is Null

Do you have any idea how I can solve this issue ?

Thanks

Questions about transferring between partitions

I am trying to deploy a set of UniversalToken contracts.
When I tried to use Golang to write a program to complete the contract interaction, I encountered some problems.
try to solve it myself, but I can’t solve any problem.

1.Why can only operators transfer between partitions?

2.When I failed to transfer tokens between partitions, I think there may be a problem with the parameters I passed in.
I assume that the contract has 3 partitions, namely A B C.
I want to transfer token from B partition to A partition.

`instance,_ := contract.NewCTCA(common.HexToAddress("0x7f74e35A58230C8Bc304eF5Ed7581F1F70bfEea8"),client)

fromPartition := [32]byte{}
copy(fromPartition[:],("B")) 

tx,err := instance.OperatorTransferByPartition(auth,fromPartition,fromAddress,common.HexToAddress(""),big.NewInt(1000000000000000000),[]byte("A"),[]byte("A"));`

The above code executes the hash: 0x9719370a7720f7346cc3007c662383cdfddffdfdfb0f3fd93cac4e3fca1ca9a6
The result of the execution is successful, but the token is not transferred from partition A to partition B.

0x7f74e35A58230C8Bc304eF5Ed7581F1F70bfEea8 This is the contract I deployed on the Ropsten test network.

Is there a good demo for my reference?

Deploying "ERC1400ERC20": ran out of gas

"ERC1400ERC20" ran out of gas (using a value you set in your network config or deployment parameters.)
   * Block limit:  0x201c061
   * Gas sent:     6721975

Hi is there someone who knows the possible cause of the error of truffle migrate?

After googling I enabled optimizer of solc in truffle-config.js, but still doesn't work.

compilers: {
    solc: {
       optimizer: {
         enabled: true,
         runs: 200
       }
    }

ERC-1400 doesn't exist

This proposal was never merged as an actual EIP. See https://eips.ethereum.org/EIPS/eip-1400 (or the lack thereof).

I recommend not depending on the behavior of this project, as it is NOT standardized.

If you are technically inclined, feel free to reach out to me, and I'd be happy to walk you through the process of creating and moving an EIP to Final.

Erc1400 contract deployment using web3j

Hi,I tried to deploy erc1400 contract in ropsten testnetwork.I successfully connected with ropsten testnet but when i tried to deploy the contract using web3j ,it shows "Zero length biginteger" error.
But the error is in the input parameter(certificate signer parameter denoted as "s") that i send it to the constructor during deployment.
Screenshot from 2020-01-29 12-41-39

Error while fetching yarn package

Expected Behavior

I would expect the yarn command to install all required packages for the project.

Current Behavior

What's happening is that as soon as I execute the yarn command, the following error is thrown:
error An unexpected error occurred: "https://npm.eu-west-3.codefi.network/bs58check/-/bs58check-2.1.2.tgz: Request failed "404 Not Found"".

Your Environment

I am currently using yarn v1.22.4, npm 6.14.9 and node v12.18.0, and I am trying to execute the yarn command on Windows 10.

yarn install fails when using node version > 10

I tried node 12.x, 13.x on windows and mac, build fails for all those combinations at
node-gyp rebuild

node version 10.x works fine (it worked for me with 10.18.0 on windows)

Please add this to the readme, could save time for someone.

Question: Looking at the redeem operations, are there concerns with a token holder burning their own tokens?

Hi there,

I am trying to follow the code and I see all the redeem operations eventually call _callSenderExtension and _callTokenExtension which make the calls tokensToTransfer and tokensToValidate respectively.

Is the design ment to make use of the userExtension and implement tokensToTransfer to stop user's from burning their own tokens?

I looked into tokensToValidate and it doesn't look like it would prevent this case.

npm install on windows fails (solcpiler)

Windows users cant just npm i because of solcpiler.

> [email protected] prepack C:\Users\xxx\AppData\Roaming\npm-cache\_cacache\tmp\git-clone-a30f7271
> npm run test


> [email protected] test C:\Users\xxx\AppData\Roaming\npm-cache\_cacache\tmp\git-clone-a30f7271
> npm run build && mocha --harmony


> [email protected] build C:\Users\xxx\AppData\Roaming\npm-cache\_cacache\tmp\git-clone-a30f7271
> npm run clean && npm run build:sol


> [email protected] clean C:\Users\xxx\AppData\Roaming\npm-cache\_cacache\tmp\git-clone-a30f7271
> rm -rf build artifacts


> [email protected] build:sol C:\Users\xxx\AppData\Roaming\npm-cache\_cacache\tmp\git-clone-a30f7271
> solcpiler -i './contracts/*.sol' --solc-version="v0.4.24+commit.e67f0147" --output-artifacts-dir artifacts --insert-file-names imports

'solcpiler' is not recognized as an internal or external command,

Maybe cleraify to use Yarn :)

Link to "token taxonomy framework" is broken

The link in the README.md to "token taxonomy framework" is broken.

Expected Behavior

I click the link, it takes me to the URL

The suggested fix would be to check to see if the assets is in a public repo or has the correct URL path.

Current Behavior

The link is clicked, and github returns a 404 error.

Steps to Reproduce (for bugs)

  1. Click the link
  2. Go to website that does not 404

IERC1400TokensSender in ERC1820 Registry

In ERC1400Raw.sol there is an instantiation of IERC1400TokensSender by calling ERC1820Client.interfaceAddr().

address senderImplementation;
senderImplementation = interfaceAddr(from, ERC1400_TOKENS_SENDER);
if (senderImplementation != address(0)) {
    IERC1400TokensSender(senderImplementation).tokensToTransfer(msg.sig, partition, operator, from, to, value, data, operatorData);
}

In order to make this work, I suppose there should be a registration of ERC1400_TOKENS_SENDER to ERC1820 somewhere, by calling ERC1820Client.setInterfaceImplementation(ERC1400_TOKENS_SENDER, {address of contract}), but I could not find similar code in the repo.

Is there anything wrong with my understanding? Thanks.

Question regarding usage of ERC1400HoldableToken, DVP, DVPHoldableLockable

Hi,

Great work with UniversalToken. I need some guidance.

Im working with a project which build a captable for norwegian business registry. Board directors will be able to migrate their business to this captable. Other official public service providers in norway are also looking into something similiar.

We are currently trying to minimize logic from the code running on servers into smart contracts.

Many of these things are new to me and would be very grateful to be pointed in a direction regarding my question:

With the usage of ERC1400, how can I create something this flow:

  1. tokenOwner call transferByPartition to transfer token of some partition to a recipient
  2. funds are held because recipient is not approved by boardDirector (controller or operator)
  3. boardDirector approves and tokens are unheld and transferred to recipient

I tried to use DVP.sol, but then I was only able to escrow the tokens. But I need to know who is the owner of the tokens while they are escrowed because of legal question. Therefor I tried to use ERC1400HoldableToken.sol. This is done here in this repo. Look there for test cases and implementation.

The issue there is that I want to enforce that ONLY boardDirector can be the rotary, but ERC1400TokensValidator.sol let the caller to holdFrom set whoever they want as a notary.

Any idea of how I could solve this?

Asbjørn

ERC721

ERC721Tocken.sol is giving compilation error
TypeError: Function has override specified but does not override anything.
--> contracts/tokens/ERC721Token.sol:59:22:
|
59 | ) internal virtual override(ERC721, ERC721Enumerable, ERC721Pausable) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

TypeError: Invalid contracts specified in override list: "ERC721", "ERC721Enumerable" and "ERC721Pausable".
--> contracts/tokens/ERC721Token.sol:59:22:
|
59 | ) internal virtual override(ERC721, ERC721Enumerable, ERC721Pausable) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Note: This contract:
--> @openzeppelin/contracts/token/ERC721/ERC721.sol:19:1:
|
19 | contract ERC721 is Context, ERC165, IERC721, IERC721Metadata {
| ^ (Relevant source part starts here and spans across multiple lines).
Note: This contract:
--> @openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol:14:1:
|
14 | abstract contract ERC721Enumerable is ERC721, IERC721Enumerable {
| ^ (Relevant source part starts here and spans across multiple lines).
Note: This contract:
--> @openzeppelin/contracts/token/ERC721/extensions/ERC721Pausable.sol:22:1:
|
22 | abstract contract ERC721Pausable is ERC721, Pausable {
| ^ (Relevant source part starts here and spans across multiple lines).

TypeError: Derived contract must override function "_beforeTokenTransfer". Two or more base classes define function with same name and parameter types.
--> contracts/tokens/ERC721Token.sol:15:1:
|
15 | contract ERC721Token is Ownable, ER ... lementer, AccessControlEnumerable {
| ^ (Relevant source part starts here and spans across multiple lines).
Note: Definition in "ERC721":
--> @openzeppelin/contracts/token/ERC721/ERC721.sol:467:5:
|
467 | function _beforeTokenTransfer(
| ^ (Relevant source part starts here and spans across multiple lines).
Note: Definition in "ERC721Enumerable":
--> @openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol:60:5:
|
60 | function _beforeTokenTransfer(
| ^ (Relevant source part starts here and spans across multiple lines).
Note: Definition in "ERC721Pausable":
--> @openzeppelin/contracts/token/ERC721/extensions/ERC721Pausable.sol:30:5:
|
30 | function _beforeTokenTransfer(
| ^ (Relevant source part starts here and spans across multiple lines).

Error HH600: Compilation failed

For more info go to https://hardhat.org/HH600 or run Hardhat with --show-stack-traces
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! [email protected] compile: npx hardhat compile
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the [email protected] compile script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR! /home/sajal-garg-ion/.npm/_logs/2023-05-04T06_30_11_896Z-debug.log
sajal-garg-ion@AS-3Q5V9V3-L:/mnt/c/Sajal/Blockchain/lseg-dmi-poc$ npm run compile

[email protected] compile /mnt/c/Sajal/Blockchain/lseg-dmi-poc
npx hardhat compile

ParserError: Unexpected trailing comma in parameter list.
--> contracts/tokens/ERC721Token.sol:59:23:
|
59 | uint256 tokenId2,
| ^

Error HH600: Compilation failed

For more info go to https://hardhat.org/HH600 or run Hardhat with --show-stack-traces
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! [email protected] compile: npx hardhat compile
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the [email protected] compile script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:

Expected Behavior

No Compilation error

We fixed it by fixing overridden function

Current Behavior

Possible Solution

We fixed it by fixing overridden function

Steps to Reproduce (for bugs)

Context

Your Environment

  • Version used:
  • Environment name and version (e.g. node 12 on macos):
  • Server type and version:
  • Operating System and version:
  • Link to your project:

Multiple token issuance

Hi there! Hope you guys are doing well.

I am writing to you about multiple token issuance. I have been playing with that. I wrote a little module which calls issueByPartition multiple times. Obviously this is necessary because I am not going to call 100 times issueByPartition, I want to call 1 transaction call to issue for 100 investors.

    function issueByPartitionMultiple(bytes32[] calldata partitions,
        address[] calldata tokenHolders,
        uint256[] calldata values,
        bytes calldata data)
    external
    withControllerPermission //checks controller permission on contract, modifier works on other calls.
    {
        require(partitions.length == tokenHolders.length, "Check array lengths");
        require(partitions.length == values.length, "Check array lengths");
        for (uint i=0; i < partitions.length; i++) {
            IERC1400(address(securityToken))
            .issueByPartition(partitions[i], tokenHolders[i], values[i], data);
        }
    }

How have you guys solved this issue?

About ERC1400 Example Code , What is the role of "Controllers"

In ERC1400Raw.sol

address[] internal _controllers;

What does this definition mean? What can Contollers do ?

In contrast to Controllers, Operator can "operatorRedeemByPartition()" and "operatorTransferByPartition" !

What is the difference between the two?

About Implimenting Partitions in ConsenSys's ERC1400

I read all smart contracts file in this ERC1400 example And the slides(Slide deck presenting ERC1400 features:) provided in ConsenSys.

The slide explains that partitions represent Asset state and Asset class in hex. But in ERC1400 Example partitions has only 3 state. And I have not understood how to write partitions representing different assets state and class in hex in details.

Has anyone concrete example codes?

Help with DVP vs DVPHoldable

Hi there,
Victor here, looking for some advise on the DVP contracts.

Basically in the project we are looking to use ERC20Holdable and do swaps for ERC1400

I think I can achieve this using DVP.sol normal

But I noticed the DVPHoldable contract, and was left a little confused. What is the difference between them? Are they used together? If I create a request trade in the DVP contract, are the tokens on escrow/hold ? Or do I need to use both the DVP to setup the trade and the DVPHoldableLockable to lock up the tokens until it is executed? Tokens are only ever transferred on execute it seems.

Thanks!

Cannot deploy on Quorum network

Hello everyone, now i have tried to deploy universal token to quorum network. But when i migrate smart contract code to network, i met error:


Deploying 'ERC1400'
transaction hash: 0x9246571b007675f90644869b1654d78898d0f32398676e15ad2809712a61b054

Error: *** Deployment Failed ***

"ERC1400" received a generic error from Geth that
can be caused by hitting revert in a contract constructor or running out of gas.

  • Returned error: gas required exceeds allowance (90000000) or always failing transaction.
  • Try: + using the '--dry-run' option to reproduce this failure with clearer errors.
    + verifying that your gas is adequate for this deployment."

Do anyone have met this error ? And how i can fix to deploy Universal token in quorum network ? Thanks in advance !

Environment

  • Version used: Truffle v5.1.49 (core: 5.1.49)
  • Environment: Quorum, Node v10.15.3, Solidity - 0.5.10 (solc-js), Web3.js v1.2.1
  • Server type and version:
  • Operating System and version: Mac OS 11

Clarification on Certificate Signing

Hi there Consensys team,

After having read the source code for this project I think I understand the basic use. What I didn’t follow however is Certificate Signing. Reading source code and the description, it is more than clear for me that this feature Can be toggled on or off, that there is a list of certificate signers, etc. I checked the tests and found the strings that denote signed certificates.

But I got a bit lost with the part about creating the certificate string, and the certificate controller mock. Is the intention for the developer to fork the code and replace with their own certificate controller solidity code? Or do you have a seperate sol file?

Is there perhaps an example of how someone (holding the wallet corresponding to the certificate issuer) Can use web3 to sign some method and parameter data to generate the certificate data String?

All the best
Victor

Escrow model

Hi there,

Looking for some help/suggestions around escrow of tokens.

Right now, we have a model where we keep track of tokens in centralized database during a "fundraising round"

We are not using DVP tool right now, because it introduces extra gas cost and the tokens must be minted first before using it. DVP looks useful for secondary trading, but this is primary issuance. And because a fundraising round there is a scenario where an investor requests a refund, or where soft cap is not reached and the sale is cancelled - we don't want to waste gas cost on a cancelled fundraising round. Also using DVP seems to require that the tokens are minted beforehand, this effecting the cap table of already existing tokens.

So, looking for a suggestion on how to do an initial "escrow" of tokens before they are distributed. Right now we are leaning towards an IBFT network hosted by Hyperledger Besu, where we would have a 1400 contract that just has "escrowed tokens". When the fundraising round completes- the tokens are burned on one network and minted on main network.

Thanks
Victor

Deployment on Ropsten doesn't work

This is on master.
Running:

$ truffle migrate --network ropsten

Compiling .\contracts\CertificateController\CertificateController.sol...
Compiling .\contracts\ERC1400.sol...
Compiling .\contracts\IERC1400.sol...
Compiling .\contracts\mocks\CertificateControllerMock.sol...
Compiling .\contracts\token\ERC1400Partition\ERC1400Partition.sol...
Compiling .\contracts\token\ERC1400Partition\IERC1400Partition.sol...
Compiling .\contracts\token\ERC1400Raw\ERC1400Raw.sol...
Compiling .\contracts\token\ERC1400Raw\ERC1400RawIssuable.sol...
Compiling .\contracts\token\ERC1400Raw\IERC1400Raw.sol...
Compiling .\contracts\token\ERC1400Raw\IERC1400TokensChecker.sol...
Compiling .\contracts\token\ERC1400Raw\IERC1400TokensRecipient.sol...
Compiling .\contracts\token\ERC1400Raw\IERC1400TokensSender.sol...
Compiling .\contracts\token\ERC1400Raw\IERC1400TokensValidator.sol...
Compiling .\contracts\token\ERC1820\ERC1820Implementer.sol...
Compiling .\contracts\tokenExtension\roles\BlacklistAdminRole.sol...
Compiling .\contracts\tokenExtension\roles\BlacklistedRole.sol...
Writing artifacts to .\build\contracts

⚠️  Important ⚠️
If you're using an HDWalletProvider, it must be Web3 1.0 enabled or your migration will hang.


Migrations dry-run (simulation)
===============================
> Network name:    'ropsten-fork'
> Network id:      3
> Block gas limit: 8000029


1_initial_migration.js
======================
Account to load with ETH:  0xC6***.....

   Deploying 'Migrations'
   ----------------------
Error:  *** Deployment Failed ***

"Migrations" hit an invalid opcode while deploying. Try:
   * Verifying that your constructor params satisfy all assert conditions.
   * Verifying your constructor code doesn't access an array out of bounds.
   * Adding reason strings to your assert statements.

    at ...\node_modules\truffle\build\webpack:\packages\truffle-deployer\src\deployment.js:364:1
Truffle v5.0.1 (core: 5.0.1)
Node v10.15.3

Not sure how to proceed with this. I am using a valid infura key as env variable. I think it has something to do with truffle and hdwallet provider? Please advise me how to fix this.

I have been able to use this on localhost ganache-cli so far, even adding my own contract migrations

Correct way to restrict transfer by partition

I am trying to create a token to represent a financial instrument that is semi-fungible, whereby tokens are fungible within tranches that each have specific restrictions.

From looking at the code, I can see that there is a function called transferByPartition which in turn calls a function named _callTokenExtension.

The _callTokenExtension function retrieves the address of the ERC1400TokensChecker contract that contains the business validation logic, by calling the function interfaceAddr on the ERC1820Client contract, which in turn looks up the address of this contract in the ERC1820Registry contract.

Once the contract has retrieved the address of the ERC1400TokensChecker contract from the ERC1820Registry contract, it calls the tokenToValidate function. This function then applies various require statements which check partition granularity, certificates, holds, allow-lists etc.

My question is this: where would I incorporate custom functionality such as partition expiry dates for example?

I can't see anywhere that I can call a custom contract containing bespoke logic for my specific business use case.

Blockscout cannot verify contracts from UniversalToken repository

Hello,

I'm trying to deploy contracts from your repo on a private network (ibft2) . I would like to use Blocskout to verify them. However, the it doesn't accept the contrats because of the many warnings that are produced during deployment.
Is there a way to avoid this problem?

Regards,

Run test failed on develop branch

Expected Behavior

I would expect the yarn coverage command to run all unit tests for the project.

Current Behavior

Failed to compile on run yarn coverage

I also found it has already occurred here: https://github.com/ConsenSys/UniversalToken/runs/5073650653?check_suite_focus=true

Steps to Reproduce (for bugs)

  1. Git checkout develop branch commit 0d0e8361da86f7e0c5890940510049737506616c
  2. Run yarn
  3. Run yarn coverage
  4. See message bellow:
> Using Truffle library from local node_modules.

> server:            http://127.0.0.1:8555
> truffle:           v5.4.5
> ganache-core:      v2.13.0
> solidity-coverage: v0.8.0-beta.0

Network Info
============
> id:      *
> port:    8555
> network: coverage


Instrumenting for coverage...
=============================

> certificate/ERC1400HoldableCertificateToken.sol
> ERC1400.sol
> erc1820/ERC1820Client.sol
> erc1820/ERC1820Implementer.sol
> erc1820/ERC1820Registry.sol
> ERC20Extendable.sol
> extensions/allowblock/allow/AllowExtension.sol
> extensions/allowblock/allow/IAllowlistedAdminRole.sol
> extensions/allowblock/allow/IAllowlistedRole.sol
> extensions/allowblock/block/BlockExtension.sol
> extensions/allowblock/block/IBlocklistedAdminRole.sol
> extensions/allowblock/block/IBlocklistedRole.sol
> extensions/ERC20/certificates/CertificateLib.sol
> extensions/ERC20/certificates/CertificateValidatorExtension.sol
> extensions/ERC20/certificates/ICertificateValidator.sol
> extensions/ERC20/ERC20Extension.sol
> extensions/ERC20/holds/HoldExtension.sol
> extensions/ExtensionBase.sol
> extensions/ExtensionStorage.sol
> extensions/IExtension.sol
> extensions/IExtensionMetadata.sol
> extensions/IExtensionStorage.sol
> extensions/pausable/IPausable.sol
> extensions/pausable/PauseExtension.sol
> extensions/TokenExtension.sol
> extensions/tokenExtensions/ERC1400TokensChecker.sol
> extensions/tokenExtensions/ERC1400TokensValidator.sol
> extensions/tokenExtensions/IERC1400TokensChecker.sol
> extensions/tokenExtensions/IERC1400TokensValidator.sol
> extensions/userExtensions/IERC1400TokensRecipient.sol
> extensions/userExtensions/IERC1400TokensSender.sol
> helpers/Errors.sol
> IERC1400.sol
> interface/HoldStatusCode.sol
> interface/IERC1643.sol
> interface/IERC1820Implementer.sol
> interface/IERC20HoldableToken.sol
> interface/IHoldableERC1400TokenExtension.sol
> mocks/AllowlistMock.sol
> mocks/BlocklistMock.sol
> mocks/CertificateSignerMock.sol
> mocks/Clock.sol
> mocks/ERC1400TokensRecipientMock.sol
> mocks/ERC1400TokensSenderMock.sol
> mocks/ERC1400TokensValidatorMock.sol
> mocks/ERC20LogicMock.sol
> mocks/FakeERC1400Mock.sol
> mocks/MinterRoleMock.sol
> mocks/PauserMock.sol
> proxy/context/ProxyContext.sol
> roles/AllowlistAdminRole.sol
> roles/AllowlistedRole.sol
> roles/BlocklistAdminRole.sol
> roles/BlocklistedRole.sol
> roles/CertificateSignerRole.sol
> roles/MinterRole.sol
> roles/PauserRole.sol
> roles/Roles.sol
> roles/RolesBase.sol
> tokens/ERC1400HoldableToken.sol
> tokens/ERC20/logic/ERC20Logic.sol
> tokens/ERC20/logic/IERC20Logic.sol
> tokens/ERC20/proxy/ERC20Proxy.sol
> tokens/ERC20/proxy/IERC20Proxy.sol
> tokens/ERC20/storage/ERC20Storage.sol
> tokens/ERC20HoldableToken.sol
> tokens/ERC721/logic/ERC721Logic.sol
> tokens/ERC721/logic/IERC721Logic.sol
> tokens/ERC721/proxy/ERC721Proxy.sol
> tokens/ERC721/proxy/IERC721Proxy.sol
> tokens/ERC721/storage/ERC721Storage.sol
> tokens/extension/ExtendableBase.sol
> tokens/extension/ExtendableHooks.sol
> tokens/extension/ExtendableRouter.sol
> tokens/extension/ExtensionLib.sol
> tokens/extension/IExtensionStorage.sol
> tokens/IToken.sol
> tokens/ITokenLogic.sol
> tokens/roles/ITokenRoles.sol
> tokens/roles/TokenRoles.sol
> tokens/storage/TokenStorage.sol
> tools/BatchBalanceReader.sol
> tools/BatchReader.sol
> tools/BatchTokenIssuer.sol
> tools/DomainAware.sol
> tools/DVPHoldableLockable.sol
> tools/Pausable.sol
> tools/Swaps.sol

Coverage skipped for:
=====================

> Migrations.sol
> tokens/ERC20Token.sol
> tokens/ERC721Token.sol
> tools/FundIssuer.sol

Compiling your contracts...
===========================
> Compiling ./.coverage_contracts/ERC1400.sol
> Compiling ./.coverage_contracts/ERC20Extendable.sol
> Compiling ./.coverage_contracts/IERC1400.sol
> Compiling ./.coverage_contracts/Migrations.sol
> Compiling ./.coverage_contracts/certificate/ERC1400HoldableCertificateToken.sol
> Compiling ./.coverage_contracts/erc1820/ERC1820Client.sol
> Compiling ./.coverage_contracts/erc1820/ERC1820Implementer.sol
> Compiling ./.coverage_contracts/erc1820/ERC1820Registry.sol
> Compiling ./.coverage_contracts/extensions/ERC20/ERC20Extension.sol
> Compiling ./.coverage_contracts/extensions/ERC20/certificates/CertificateLib.sol
> Compiling ./.coverage_contracts/extensions/ERC20/certificates/CertificateValidatorExtension.sol
> Compiling ./.coverage_contracts/extensions/ERC20/certificates/ICertificateValidator.sol
> Compiling ./.coverage_contracts/extensions/ERC20/holds/HoldExtension.sol
> Compiling ./.coverage_contracts/extensions/ExtensionBase.sol
> Compiling ./.coverage_contracts/extensions/ExtensionStorage.sol
> Compiling ./.coverage_contracts/extensions/IExtension.sol
> Compiling ./.coverage_contracts/extensions/IExtensionMetadata.sol
> Compiling ./.coverage_contracts/extensions/IExtensionStorage.sol
> Compiling ./.coverage_contracts/extensions/TokenExtension.sol
> Compiling ./.coverage_contracts/extensions/allowblock/allow/AllowExtension.sol
> Compiling ./.coverage_contracts/extensions/allowblock/allow/IAllowlistedAdminRole.sol
> Compiling ./.coverage_contracts/extensions/allowblock/allow/IAllowlistedRole.sol
> Compiling ./.coverage_contracts/extensions/allowblock/block/BlockExtension.sol
> Compiling ./.coverage_contracts/extensions/allowblock/block/IBlocklistedAdminRole.sol
> Compiling ./.coverage_contracts/extensions/allowblock/block/IBlocklistedRole.sol
> Compiling ./.coverage_contracts/extensions/pausable/IPausable.sol
> Compiling ./.coverage_contracts/extensions/pausable/PauseExtension.sol
> Compiling ./.coverage_contracts/extensions/tokenExtensions/ERC1400TokensChecker.sol
> Compiling ./.coverage_contracts/extensions/tokenExtensions/ERC1400TokensValidator.sol
> Compiling ./.coverage_contracts/extensions/tokenExtensions/IERC1400TokensChecker.sol
> Compiling ./.coverage_contracts/extensions/tokenExtensions/IERC1400TokensValidator.sol
> Compiling ./.coverage_contracts/extensions/userExtensions/IERC1400TokensRecipient.sol
> Compiling ./.coverage_contracts/extensions/userExtensions/IERC1400TokensSender.sol
> Compiling ./.coverage_contracts/helpers/Errors.sol
> Compiling ./.coverage_contracts/interface/HoldStatusCode.sol
> Compiling ./.coverage_contracts/interface/IERC1643.sol
> Compiling ./.coverage_contracts/interface/IERC1820Implementer.sol
> Compiling ./.coverage_contracts/interface/IERC20HoldableToken.sol
> Compiling ./.coverage_contracts/interface/IHoldableERC1400TokenExtension.sol
> Compiling ./.coverage_contracts/mocks/AllowlistMock.sol
> Compiling ./.coverage_contracts/mocks/BlocklistMock.sol
> Compiling ./.coverage_contracts/mocks/CertificateSignerMock.sol
> Compiling ./.coverage_contracts/mocks/Clock.sol
> Compiling ./.coverage_contracts/mocks/ERC1400TokensRecipientMock.sol
> Compiling ./.coverage_contracts/mocks/ERC1400TokensSenderMock.sol
> Compiling ./.coverage_contracts/mocks/ERC1400TokensValidatorMock.sol
> Compiling ./.coverage_contracts/mocks/ERC20LogicMock.sol
> Compiling ./.coverage_contracts/mocks/FakeERC1400Mock.sol
> Compiling ./.coverage_contracts/mocks/MinterRoleMock.sol
> Compiling ./.coverage_contracts/mocks/PauserMock.sol
> Compiling ./.coverage_contracts/proxy/context/ProxyContext.sol
> Compiling ./.coverage_contracts/roles/AllowlistAdminRole.sol
> Compiling ./.coverage_contracts/roles/AllowlistedRole.sol
> Compiling ./.coverage_contracts/roles/BlocklistAdminRole.sol
> Compiling ./.coverage_contracts/roles/BlocklistedRole.sol
> Compiling ./.coverage_contracts/roles/CertificateSignerRole.sol
> Compiling ./.coverage_contracts/roles/MinterRole.sol
> Compiling ./.coverage_contracts/roles/PauserRole.sol
> Compiling ./.coverage_contracts/roles/Roles.sol
> Compiling ./.coverage_contracts/roles/RolesBase.sol
> Compiling ./.coverage_contracts/tokens/ERC1400HoldableToken.sol
> Compiling ./.coverage_contracts/tokens/ERC20/logic/ERC20Logic.sol
> Compiling ./.coverage_contracts/tokens/ERC20/logic/IERC20Logic.sol
> Compiling ./.coverage_contracts/tokens/ERC20/proxy/ERC20Proxy.sol
> Compiling ./.coverage_contracts/tokens/ERC20/proxy/IERC20Proxy.sol
> Compiling ./.coverage_contracts/tokens/ERC20/storage/ERC20Storage.sol
> Compiling ./.coverage_contracts/tokens/ERC20HoldableToken.sol
> Compiling ./.coverage_contracts/tokens/ERC20Token.sol
> Compiling ./.coverage_contracts/tokens/ERC721/logic/ERC721Logic.sol
> Compiling ./.coverage_contracts/tokens/ERC721/logic/IERC721Logic.sol
> Compiling ./.coverage_contracts/tokens/ERC721/proxy/ERC721Proxy.sol
> Compiling ./.coverage_contracts/tokens/ERC721/proxy/IERC721Proxy.sol
> Compiling ./.coverage_contracts/tokens/ERC721/storage/ERC721Storage.sol
> Compiling ./.coverage_contracts/tokens/ERC721Token.sol
> Compiling ./.coverage_contracts/tokens/IToken.sol
> Compiling ./.coverage_contracts/tokens/ITokenLogic.sol
> Compiling ./.coverage_contracts/tokens/extension/ExtendableBase.sol
> Compiling ./.coverage_contracts/tokens/extension/ExtendableHooks.sol
> Compiling ./.coverage_contracts/tokens/extension/ExtendableRouter.sol
> Compiling ./.coverage_contracts/tokens/extension/ExtensionLib.sol
> Compiling ./.coverage_contracts/tokens/extension/IExtensionStorage.sol
> Compiling ./.coverage_contracts/tokens/roles/ITokenRoles.sol
> Compiling ./.coverage_contracts/tokens/roles/TokenRoles.sol
> Compiling ./.coverage_contracts/tokens/storage/TokenStorage.sol
> Compiling ./.coverage_contracts/tools/BatchBalanceReader.sol
> Compiling ./.coverage_contracts/tools/BatchReader.sol
> Compiling ./.coverage_contracts/tools/BatchTokenIssuer.sol
> Compiling ./.coverage_contracts/tools/DVPHoldableLockable.sol
> Compiling ./.coverage_contracts/tools/DomainAware.sol
> Compiling ./.coverage_contracts/tools/FundIssuer.sol
> Compiling ./.coverage_contracts/tools/Pausable.sol
> Compiling ./.coverage_contracts/tools/Swaps.sol
> Compiling @openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol
> Compiling @openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol
> Compiling @openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol
> Compiling @openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol
> Compiling @openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol
> Compiling @openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol
> Compiling @openzeppelin/contracts/access/AccessControl.sol
> Compiling @openzeppelin/contracts/access/AccessControlEnumerable.sol
> Compiling @openzeppelin/contracts/access/Ownable.sol
> Compiling @openzeppelin/contracts/security/Pausable.sol
> Compiling @openzeppelin/contracts/token/ERC20/ERC20.sol
> Compiling @openzeppelin/contracts/token/ERC20/IERC20.sol
> Compiling @openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol
> Compiling @openzeppelin/contracts/token/ERC20/extensions/ERC20Pausable.sol
> Compiling @openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol
> Compiling @openzeppelin/contracts/token/ERC721/ERC721.sol
> Compiling @openzeppelin/contracts/token/ERC721/IERC721.sol
> Compiling @openzeppelin/contracts/token/ERC721/IERC721Receiver.sol
> Compiling @openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol
> Compiling @openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol
> Compiling @openzeppelin/contracts/token/ERC721/extensions/ERC721Pausable.sol
> Compiling @openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol
> Compiling @openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol
> Compiling @openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol
> Compiling @openzeppelin/contracts/utils/Address.sol
> Compiling @openzeppelin/contracts/utils/Context.sol
> Compiling @openzeppelin/contracts/utils/StorageSlot.sol
> Compiling @openzeppelin/contracts/utils/Strings.sol
> Compiling @openzeppelin/contracts/utils/introspection/ERC165.sol
> Compiling @openzeppelin/contracts/utils/introspection/IERC165.sol
> Compiling @openzeppelin/contracts/utils/introspection/IERC1820Registry.sol
> Compiling @openzeppelin/contracts/utils/math/SafeMath.sol
> Compiling @openzeppelin/contracts/utils/structs/EnumerableSet.sol

> Compilation warnings encountered:
> solidity-coverage cleaning up, shutting down ganache server
CompileError: DeclarationError: Undeclared identifier.
  --> project:/.coverage_contracts/extensions/allowblock/allow/IAllowlistedRole.sol:13:34:
   |
13 |     modifier onlyNotAllowlisted {c_4caff5b6(0x2539255495eaa41b); /* function */ 
   |                                  ^^^^^^^^^^

,DeclarationError: Undeclared identifier.
  --> project:/.coverage_contracts/extensions/allowblock/allow/IAllowlistedRole.sol:15:1:
   |
15 | c_4caff5b6(0x9c64e4b9363b57f7); /* line */ 
   | ^^^^^^^^^^

,DeclarationError: Undeclared identifier.
  --> project:/.coverage_contracts/extensions/allowblock/allow/IAllowlistedRole.sol:16:9:
   |
16 |         c_4caff5b6(0x114e33d4b02a9e86); /* requirePre */ 
   |         ^^^^^^^^^^

,DeclarationError: Undeclared identifier.
  --> project:/.coverage_contracts/extensions/allowblock/allow/IAllowlistedRole.sol:17:1:
   |
17 | c_4caff5b6(0xa5e3feb41a7de57e); /* statement */ 
   | ^^^^^^^^^^

,DeclarationError: Undeclared identifier.
  --> project:/.coverage_contracts/extensions/allowblock/allow/IAllowlistedRole.sol:18:67:
   |
18 | require(!this.isAllowlisted(msg.sender), "Already on allow list");c_4caff5b6(0xa75e44aa57cd7b43); /* requirePost */ 
   |                                                                   ^^^^^^^^^^

,DeclarationError: Undeclared identifier.
  --> project:/.coverage_contracts/extensions/allowblock/allow/IAllowlistedRole.sol:20:1:
   |
20 | c_4caff5b6(0x2187e7c426e4fd7b); /* line */ 
   | ^^^^^^^^^^

,DeclarationError: Undeclared identifier.
  --> project:/.coverage_contracts/extensions/allowblock/allow/IAllowlistedRole.sol:24:31:
   |
24 |     modifier onlyAllowlisted {c_4caff5b6(0x82f1846bbd955412); /* function */ 
   |                               ^^^^^^^^^^

,DeclarationError: Undeclared identifier.
  --> project:/.coverage_contracts/extensions/allowblock/allow/IAllowlistedRole.sol:26:1:
   |
26 | c_4caff5b6(0xbf16a09dcacf8304); /* line */ 
   | ^^^^^^^^^^

,DeclarationError: Undeclared identifier.
  --> project:/.coverage_contracts/extensions/allowblock/allow/IAllowlistedRole.sol:27:9:
   |
27 |         c_4caff5b6(0x444900d84b8ab208); /* requirePre */ 
   |         ^^^^^^^^^^

,DeclarationError: Undeclared identifier.
  --> project:/.coverage_contracts/extensions/allowblock/allow/IAllowlistedRole.sol:28:1:
   |
28 | c_4caff5b6(0xe7b7451a17c46d89); /* statement */ 
   | ^^^^^^^^^^

,DeclarationError: Undeclared identifier.
  --> project:/.coverage_contracts/extensions/allowblock/allow/IAllowlistedRole.sol:29:62:
   |
29 | require(this.isAllowlisted(msg.sender), "Not on allow list");c_4caff5b6(0x7cd4822056842710); /* requirePost */ 
   |                                                              ^^^^^^^^^^

,DeclarationError: Undeclared identifier.
  --> project:/.coverage_contracts/extensions/allowblock/allow/IAllowlistedRole.sol:31:1:
   |
31 | c_4caff5b6(0xa1f1fd6a27bb0699); /* line */ 
   | ^^^^^^^^^^

Compilation failed. See above.
    at run (/Users/username/code/ERC1400/node_modules/truffle/build/webpack:/packages/compile-solidity/run.js:62:1)
    at Object.sourcesWithDependencies (/Users/username/code/ERC1400/node_modules/truffle/build/webpack:/packages/compile-solidity/index.js:150:1)
    at all (/Users/username/code/ERC1400/node_modules/truffle/build/webpack:/packages/compile-solidity/index.js:81:1)
    at /Users/username/code/ERC1400/node_modules/truffle/build/webpack:/packages/workflow-compile/legacy/index.js:98:31
    at async Promise.all (index 0)
    at Object.compile (/Users/username/code/ERC1400/node_modules/truffle/build/webpack:/packages/workflow-compile/legacy/index.js:50:1)
    at plugin (/Users/username/code/ERC1400/node_modules/solidity-coverage/plugins/truffle.plugin.js:113:5)
Truffle v5.4.5 (core: 5.4.5)
Node v12.18.4
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.