Git Product home page Git Product logo

polymath-core's Introduction

Build Status Coverage Status Gitter Telegram Greenkeeper badge

Polymath logo

Polymath Core

The Polymath Core smart contracts provide a system for launching regulatory-compliant securities tokens on a decentralized blockchain. This particular repository is the implementation of a system that allows for the creation of ST-20-compatible tokens. This system has a modular design that promotes a variety of pluggable components for various types of issuances, legal requirements, and offering processes.

Introduction to Security Tokens

What is a Security token?

A Security Token shares many of the characteristics of both fungible (erc20) and non-fungible tokens (erc721). Security tokens are designed to represent complete or fractional ownership interests in assets and/or entities. While utility tokens have no limitations on who can send or receive the token, security tokens are subject to many restrictions based on identity, jurisdiction and asset category.

Security Tokens Vs. Utility Tokens?

The concept of utility tokens is fairly well understood in the blockchain space today. Utility tokens represent access to a network, and your token purchase represents the ability to buy goods or services from that network- Think of when you purchase a arcade token to allow you to play an arcade game machine. Utility tokens give you that same type of access to a product or service. On the other hand, security tokens represent complete or fractional ownership in an asset (such as shares in a company, a real-estate asset, artwork, etc). Such as having a stake in a company, real estate, or intellectual property can all be represented by security tokens. Security tokens offer the benefit of bringing significant transparency over traditional paper shares through the use of the blockchain and its associated public ledger. Security token structure, distribution, or changes that could affect investors are now accessible to all via the blockchain.

ST-20 Interface Overview

Description

An ST-20 token is an Ethereum-based token implemented on top of the ERC-20 protocol that adds the ability for tokens to control transfers based on specific rules. ST-20 tokens rely on Transfer Managers to determine the ruleset the token should apply in order to allow or deny a transfer, be it between the issuer and investors, in a peer to peer exchange, or a transaction with an exchange.

How it works

ST-20 tokens must implement a verifyTransfer method which will be called when attempting to execute a transfer or transferFrom method. The verifyTransfer method will determine whether that transaction can be completed or not. The implementation of verifyTransfer can take many forms, but the default approach is a whitelist controlled by the GeneralTransferManager.

The ST-20 Interface

contract IST20 {

    // off-chain hash
    bytes32 public tokenDetails;

    //transfer, transferFrom must respect the result of verifyTransfer
    function verifyTransfer(address _from, address _to, uint256 _amount) view public returns (bool success);

    //used to create tokens
    function mint(address _investor, uint256 _amount) public returns (bool success);
}

The Polymath Core Architecture

The diagram below depicts a high-level view of the various modules, registries, and contracts implemented within Polymath Core 2.0.0:

Polymath Core architecture

Components

Polymath Registries

Security Token Registry (STR) - This registry tells us which tokens and tickers have been registered to it. This allows us to prevent people from reserving the same ticker as another issuer as well checking for inputs such as making sure it is a maximum of 10 characters and what the expiry date is on the respective ticker. Right now, if you reserve a ticker it last for 60 days. After it expires someone else can go ahead and reserve it or they you can re-register it.

With the 2.0.0 Core Release, when you deploy a token you do it through the ST registry and it keeps a record of which tokens have been registered within it.

The Module Registry - This registry keeps a record of all the different module factories.

The Features Registry - A registry of features that we may enable in the future but right now only Polymath has control of the features. Later, Polymath can easily turn access on and off.

To be clear, each module has its own factory which is in charge of deploying an instance of that module for the issuers token.

There are General factories which every token uses (if wanted). It works by sending the token to the factory where it asks for an instance of that said module and the token will add an instance of that module to itself. This allows for each token to have its unique modules associated with it. All of this is created through the factories and the module registry keeps a records of all the different modules factories that are registered.

As of now, Polymath is the only one that can add or register a module factory to the module registry. Polymath submits the modules to the registry, however, we are exploring different approaches to open up development to other parties such as potentially working with external developers to provide services to issuers through modules.

Polymath has 3 main registries

  1. Security Token Registry
  2. Features Registry
  3. Module Registry

The Polymath Registry holds the addresses of the 3 registries above.

As of the 2.0.0 release, we have built it out so that the Module and Security Token Registry are upgradeable. This means that down the road if there is something in the logic that we need to change, we can do that without having to re-deploy the whole thing again. All we need to do is update it.

Modules

Security Token (ST-20): The SecurityToken is an implementation of the ST-20 protocol that allows the addition of different modules to control its behavior. Different modules can be attached to a SecurityToken.

We have a ST-20 token which is an Ethereum-based token implemented on top of the ERC-20 protocol that adds the ability for tokens to control transfers based on specific rules. ST-20 tokens rely on Transfer Managers to determine the ruleset the token should apply in order to allow or deny a transfer, be it between the issuer and investors, in a peer to peer exchange, or a transaction with an exchange.

To simplify, it breaks down to having a base token that gives the issuer the ability to add functionality through modules.

Example

We have modules that can deal with transfer management. Restricting transfers through a whitelist or just restricting a transfer between addresses that could make an account go over a specified limit or you can limit the amount of a token holders or you can even limit transfers to prevent dumping of tokens by having a lockup period for token holders.

The Polymath Modules

TransferManager modules: These control the logic behind transfers and how they are allowed or disallowed. By default, the ST (Security Token) gets a GeneralTransferManager module attached in order to determine if transfers should be allowed based on a whitelist approach.

The GeneralTransferManager behaves differently depending who is trying to transfer the tokens. a) In an offering setting (investors buying tokens from the issuer) the investor's address should be present on an internal whitelist managed by the issuer within the GeneralTransferManager.

b) In a peer to peer transfer, restrictions apply based on real-life lockups that are enforced on-chain. For example, if a particular holder has a 1-year sale restriction for the token, the transaction will fail until that year passes.

Security Token Offering (STO) modules: A SecurityToken can be attached to one (and only one) STO module that will dictate the logic of how those tokens will be sold/distributed. An STO is the equivalent to the Crowdsale contracts often found present in traditional ICOs.

Permission Manager modules: These modules manage permissions on different aspects of the issuance process. The issuer can use this module to manage permissions and designate administrators on his token. For example, the issuer might give a KYC firm permissions to add investors to the whitelist.

Checkpoint Modules These modules allow the issuer to define checkpoints at which token balances and the total supply of a token can be consistently queried. This functionality is useful for dividend payment mechanisms and on-chain governance, both of which need to be able to determine token balances consistently as of a specified point in time.

Burn Modules These modules allow issuers or investors to burn or redeem their tokens in exchange of another token which can be on chain or offchain.

With the Core 2.0.0 Release, Polymath has also introduced the USDTieredSTO. This new STO module allows a security token to be issued in return for investment (security token offering) in various currencies (ETH, POLY & a USD stable coin). The price of tokens is denominated in USD and the STO allows multiple tiers with different price points to be defined. Discounts for investments made in POLY can also be defined.

CLI and CLI Documentation Wiki:

The CLI is for users that want to easily walkthrough all the details of an STO issuance. The CLI documentation is located on our Github Wiki.

You can easily navigate through it with the sidebar directory in order to run the CLI and set up and test the following:

  1. Prerequisite Instructions / Deploy and setup the Polymath contracts
  2. Launch the CLI on Ganache
  3. Use the Faucet to get POLY
  4. Deploy a token + Launch a USDTieredSTO
  5. Whitelist investors
  6. Work with the Dividends module
  7. Using other CLI features

Setting up Polymath Core

Mainnet

v3.0.0

V3 Audit Report by Consensys Diligence: https://github.com/PolymathNetwork/polymath-audit-report-2019-04

Contract Address
SecurityTokenRegistry (Data Store): 0x240f9f86b1465bf1b8eb29bc88cbf65573dfdd97
SecurityTokenRegistry (Logic): 0x92274793a65a0de42bb4bf19b393930863877630
ModuleRegistry (Data Store): 0x4566d68ea96fc2213f2446f0dd0f482146cee96d
ModuleRegistry (Logic): 0x7550fe3308ba534b44e94c83cd08b7e3c5b96db5
Polymath Registry: 0xdfabf3e4793cd30affb47ab6fa4cf4eef26bbc27
Feature Registry: 0xa3eacb03622bf1513880892b7270d965f693ffb5
ETHOracle: 0x60055e9a93aae267da5a052e95846fa9469c0e7a
POLYOracle: 0x52cb4616E191Ff664B0bff247469ce7b74579D1B
General Transfer Manager Factory: 0x5fafcfc0afd80d2f95133170172b045024ca8fd1
General Permission Manager Factory: 0xeb4c8c9d71cbe60ca0e688e4e70c5ab22abb72a4
CappedSTOFactory: 0x7c64e9cfc397db2da3213a172d783f1b9c30d7ef
USDTieredSTO Factory: 0x80ae6e1b6dc661d21ee1680bd5ff919f0400f17d
ERC20 Dividends Checkpoint Factory: 0x550fc7d520f596bfdf75dca4d9f5f3c0c6020212
Count Transfer Manager Factory: 0xA8e0a4E7f0cdECF43AFbA0360B6f64412Df2e6B0
Percentage Transfer Manager Factory: 0x5732ee7ef44dc5ab7b7cbac8ada5268c96895ca5
Manual Approval Transfer Manager Factory: 0x156389b30ae9e5ca8ec9e55ff529738480e42214

v2.0.0

Contract Address
SecurityTokenRegistry (Proxy): 0x240f9f86b1465bf1b8eb29bc88cbf65573dfdd97
ModuleRegistry (Proxy): 0x4566d68ea96fc2213f2446f0dd0f482146cee96d
Polymath Registry: 0xdfabf3e4793cd30affb47ab6fa4cf4eef26bbc27
Feature Registry: 0xa3eacb03622bf1513880892b7270d965f693ffb5
ETHOracle: 0x60055e9a93aae267da5a052e95846fa9469c0e7a
POLYOracle: 0x52cb4616E191Ff664B0bff247469ce7b74579D1B
General Transfer Manager Factory: 0xdc95598ef2bbfdb66d02d5f3eea98ea39fbc8b26
General Permission Manager Factory: 0xf0aa1856360277c60052d6095c5b787b01388cdd
CappedSTOFactory: 0x77d89663e8819023a87bfe2bc9baaa6922c0e57c
USDTieredSTO Factory: 0x5a3a30bddae1f857a19b1aed93b5cdb3c3da809a
EthDividendsCheckpointFactory: 0x968c74c52f15b2de323eca8c677f6c9266bfefd6
ERC20 Dividends Checkpoint Factory: 0x82f9f1ab41bacb1433c79492e54bf13bccd7f9ae
Count Transfer Manager Factory: 0xd9fd7e34d6e2c47a69e02131cf8554d52c3445d5
Percentage Transfer Manager Factory: 0xe6267a9c0a227d21c95b782b1bd32bb41fc3b43b
Manual Approval Transfer Manager Factory (2.0.1): 0x6af2afad53cb334e62b90ddbdcf3a086f654c298

New SecurityTokenRegistry (2.0.1): 0x538136ed73011a766bf0a126a27300c3a7a2e6a6 (fixed bug with getTickersByOwner())

New ModuleRegistry (2.0.1): 0xbc18f144ccf87f2d98e6fa0661799fcdc3170119 (fixed bug with missing transferOwnership function)

New ManualApprovalTransferManager 0x6af2afad53cb334e62b90ddbdcf3a086f654c298 (Fixed 0x0 from bug)

KOVAN

v3.0.0

Contract Address
SecurityTokenRegistry (Data Store): 0x91110c2f67e2881a8540417be9eadf5bc9f2f248
SecurityTokenRegistry (Logic): 0x71A4F01F6Dee751eEDc6E16FD25AC45b46e1b0d9
ModuleRegistry (Data Store): 0xde6d19d7a68d453244227b6ccc5d8e6c2314627a
ModuleRegistry (Logic): 0xC5203791C9d46161B378deaDa89A1D5B67Ba23e3
Polymath Registry: 0x5b215a7d39ee305ad28da29bf2f0425c6c2a00b3
Feature Registry: 0x8967a7cfc4b455398be2356cd05cd43b7a39697e
ETHOracle: 0xCE5551FC9d43E9D2CC255139169FC889352405C8
POLYOracle: 0x461d98EF2A0c7Ac1416EF065840fF5d4C946206C
General Transfer Manager Factory: 0x5D92B852c31C0dd3409285339051c7594eaE198e
General Permission Manager Factory: 0x559a15fa038c3FB84e993BE06235E7D9A0D1cB7d
CappedSTOFactory: 0x7CEa4A1Eced1a035A6BD5e673454f6Bc8c98b20E
USDTieredSTO Factory: 0x0C260C11B46827E9d96F9a5C7DDbb66907e2b0F3
ERC20 Dividends Checkpoint Factory: 0xE74A013FbE7B6EF5F3b4B45Ce4745dCBA3197856
Count Transfer Manager Factory: 0xbA6893CfdDdEc76dB8a4d8f833a81F456fB64e2c
Percentage Transfer Manager Factory: 0x127dcA5040f5B943100D4c4154fA4F7744e9482D
Manual Approval Transfer Manager Factory: 0xFcd05Ab2B494577AbE0a4549b2FBec6e1bce32C9

v2.0.0

New Kovan PolyTokenFaucet: 0xb347b9f5b56b431b2cf4e1d90a5995f7519ca792

Contract Address
SecurityTokenRegistry (Proxy): 0x91110c2f67e2881a8540417be9eadf5bc9f2f248
ModuleRegistry (Proxy): 0xde6d19d7a68d453244227b6ccc5d8e6c2314627a
Polymath Registry: 0x5b215a7d39ee305ad28da29bf2f0425c6c2a00b3
Feature Registry: 0x8967a7cfc4b455398be2356cd05cd43b7a39697e
ETHOracle: 0x14542627196c7dab26eb11ffd8a407ffc476de76
POLYOracle: 0x461d98EF2A0c7Ac1416EF065840fF5d4C946206C
General Transfer Manager Factory: 0x650e9507e983077d6f822472a7dcc37626d55c7f
General Permission Manager Factory: 0xbf0bd6305b523ce055baa6dfaa9676d6b9e6090b
CappedSTOFactory: 0x01510b2c03296473f883c12d0723f0a46aa67f13
USDTieredSTO Factory: 0x8b9743e6129f7b7cca04e3611b5c8cd9b1d11e90
ERC20 Dividends Checkpoint Factory: 0x4369751df5bcb2f12f1790f525ef212a622b9c60
Count Transfer Manager Factory: 0xc7cf0c1ddc85c18672951f9bfeb7163ecc8f0e2f
Percentage Transfer Manager Factory: 0xfea5fcb254bcb4ada0f86903ff822d6372325cb1
Manual Approval Transfer Manager Factory: 0x9faa79e2ccf0eb49aa6ebde1795ad2e951ce78f8

New ManualApprovalTransferManager 0x9faa79e2ccf0eb49aa6ebde1795ad2e951ce78f8 (Fixed 0x0 from bug)

Package version requirements for your machine:

  • node v8.x.x or v9.x.x
  • npm v6.x.x or newer
  • Yarn v1.3 or newer
  • Homebrew v1.6.7 (for macOS)
  • Truffle v4.1.11 (core: 4.1.11)
  • Solidity v0.4.24 (solc-js)
  • Ganache CLI v6.1.3 (ganache-core: 2.1.2) or newer

Setup

The smart contracts are written in Solidity and tested/deployed using Truffle version 4.1.0. The new version of Truffle doesn't require testrpc to be installed separately so you can just run the following:

# Install Truffle package globally:
$ npm install --global truffle

# (Only for windows) set up build tools for node-gyp by running below command in powershell:
$ npm install --global --production windows-build-tools

# Install local node dependencies:
$ yarn

Testing

To test the code simply run:

# on *nix systems
$ npm run test

# on windows systems
$ npm run wintest

Extending Polymath Core

  1. Deploy ModuleRegistry. ModuleRegistry keeps track of all available modules that add new functionalities to Polymath-based security tokens.

  2. Deploy GeneralTransferManagerFactory. This module allows the use of a general TransferManager for newly issued security tokens. The General Transfer Manager gives STs the ability to have their transfers restricted by using an on-chain whitelist.

  3. Add the GeneralTransferManagerFactory module to ModuleRegistry by calling ModuleRegistry.registerModule().

  4. Deploy TickerRegistry. This contract handles the registration of unique token symbols. Issuers first have to claim their token symbol through the TickerRegistry. If it's available they will be able to deploy a ST with the same symbol for a set number of days before the registration expires.

  5. Deploy SecurityTokenRegistry. This contract is responsible for deploying new Security Tokens. STs should always be deployed by using the SecurityTokenRegistry.

Deploying Security Token Offerings (Network Admin Only)

Security Token Offerings (STOs) grant STs the ability to be distributed in an initial offering. Polymath offers a few out-of-the-box STO models for issuers to select from and, as the platform evolves, 3rd party developers will be able to create their own offerings and make them available to the network.

As an example, we've included a CappedSTO and CappedSTOFactory contracts.

In order to create a new STO, developers first have to create an STO Factory contract which will be responsible for instantiating STOs as Issuers select them. Each STO Factory has an STO contract attached to it, which will be instantiated for each Security Token that wants to use that particular STO.

To make an STO available for Issuers, first, deploy the STO Factory and take note of its address. Then, call moduleRegistry.registerModule(STO Factory address);

Once the STO Factory has been registered to the Module Registry, issuers will be able to see it on the Polymath dApp and they will be able to add it as a module of the ST.

Note that while anyone can register an STO Factory, only those "approved" by Polymath will be enabled to be attached by the general community. An STO Factory not yet approved by Polymath may only be used by it's author.

Code Styleguide

The polymath-core repo follows the Solidity style guide.

Links

polymath-core's People

Contributors

adamdossa avatar comeonbuddy avatar cpstl avatar davekaj avatar dependabot[bot] avatar dev1644 avatar f-obrien avatar glitch003 avatar greenkeeper[bot] avatar housemobile avatar jeanlucmongrain avatar kostind avatar maxsam4 avatar pabloruiz55 avatar polydocs avatar remon-nashid avatar sajclarke avatar satyamakgec avatar satyamsb avatar shuffledex avatar sweggersen avatar victorvicente 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  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

polymath-core's Issues

Allowing the issuer to "delete" token and start again

Say issuer has ticker and token ZZZ. They make a mistake at some point and they want to start over and still use ZZZ.

In a typical ICO scenario, they would just forget about the token they had and create a new one.

Here, it's a bit more tricky as they would have to "delete" the reservation on the ticker and on the ST Registries.

Does it make sense to support this feature?

Review the getModuleByName logic

Names for modules are not unique. We need to figure out a different way of doing this or at least enforcing module name uniqueness

Registry upgrading

  • All registry upgrades (STR, TR & MR) will be done in-place using a proxy / delegate call pattern.
  • This means that anyone using these contracts (e.g. SecurityToken or Modules) has no control over whether they get the upgrade or not.
  • As a result of this, any dependencies on these contracts are subject to breaking (i.e. if Polymath self-destructs the contract), which implies no existing functionality should have any dependencies on the registry contracts.
  • AFAICT this is true for all of our modules and security token. The security token has a dependency on the module registry for adding new modules, but this is fine as it doesn't contravene the aims above which relate to existing functionality, not new modules.
  • Registries do have interdependencies (e.g. module registry depends on STR, STR depends on TR), so when upgrading registries we'll need to make sure they are upgraded in a consistent manner.

Exchanges: Additional whitelist for handling exchanges?

If we are to support exchanges, we need to have a separate whitelist (or the ability for exchanges to add addresses to the original whitelist) so exchanges can add addresses to enable them to withdraw tokens acquired through the exchange.

Add log to modifyWhitelist to keep a record on who added an address to the whitelist

We should keep track of who added someone to the whitelist, specially since there could be several delegates and if there's a problem with an address added the issuer should be able to know who added it.

 function modifyWhitelist(address _investor, uint256 _time) public onlyOwnerOrDelegates {
        //Passing a _time == 0 into this function, is equivalent to removing the _investor from the whitelist
        whitelist[_investor] = _time;
    }

Validate token symbol capitalization

If a symbol is entered as "POLY" or "poly" they will be considered different symbols.
It shouldn't matter if the symbol is entered in capital letters or not. They should be the same symbol.
Let's convert to uppercase (or lowercase) strings entered as symbol.

CountTransferManager may cause invalid transfers to be allowed

function verifyTransfer(address _from, address _to, uint256 /* _amount */) public view returns(Result) {
        if (!paused) {
            if (maxHolderCount < ISecurityToken(securityToken).investorCount()) {
                // Allow transfers to existing maxHolders
                if (ISecurityToken(securityToken).balanceOf(_to) != 0) {
                    return Result.VALID;
                }
                return Result.INVALID;
            }
            return Result.NA;
        }
        return Result.NA;
    }

Since

                if (ISecurityToken(securityToken).balanceOf(_to) != 0) {
                    return Result.VALID;
                }

returns VALID, this could enable a transfer even if _from/_to are not in the GTM's whitelist since the GTM does not ever return Result.INVALID

Separate Permissions from Delegates (V2)

Delegates

3rd party entities (marketing, legal, consulting, developer etc.) can be added as Delegates to a token in return for a POLY fee. There is no obvious way to enforce that all parties collaborating on an issuance (issuer, legal, marketing etc.) use this approach, but if they want to be “officially” attached to the Security Token then they would need to go through the Polymath ecosystem and we can oversee that sensible fees are levied. Interacting through the Polymath ecosystem also allows Delegates to build reputation on the platform which has intrinsic value.

Questions:

  1. Perhaps we should consider changing the current GeneralDelegateManager module to a PermissionManager module and build out Delegates separately with a DelegateRegistry and Reputation for each Delegate etc. similar to the ModuleRegistry? We can try and think of a way to push this to after the V1 release.

I think permissions and “delegates” are separate things. I think we should change the name of GeneralDelegateManager to GeneralPermissionManager.

I think Delegates should be similar to Modules perhaps instead (so they have a Reputation & Cost).

POLY Wallet / Escrow (V2)

Attached to each token, this contract holds all balances for POLY and allows incumbents to collect their fees as well as serving for the vault for POLY raise.​

transferTickerOwnership functionality

TickerRegistry: 2- While I can register a ticker on behalf of someone else by entering their address instead of mine, I can not transfer ownership of the ticker. If we registered the tickers under our own account, then we would have to be the ones deploying their token and only then we would be able to transfer ownership of the ST.

removeModule could potentially bypass repleaceability

Say we added 5 modules to the ST, the last one being not replaceable.
removeModule "deletes" a module by replacing it with the last one and then eliminating the last one.

So, if we were to remove module 3, now the last module is number 4, which is replaceable.

Don't know if it is a big deal though.

Review: Polymath being able to create ST/STO on behalf of an issuer

Under our current version, would it be possible for PM to register symbol, deploy token, add ourselves as delegate, cede ownership of token to them and still have us attach STO and add investors from a csv file to the whitelist?

Wondering if we can issue the ST/STO on behalf of some of the first issuers.
What would be the steps involved?

STR holds the owner of a ST, but this could change over time

ST's are ownable, so the current owner may choose to change the owner to a new address. If this happens then the owner held in the STR for a ST would become stale.

It may be better for the STR to just call ST(securityToken).owner() to get the ST owner rather than holding a duplicated reference.

Polymath-Core Bug Bounty Program

Polymath-Core Bug Bounty

Polymath wishes to operate this bug bounty program in order to upkeep the utmost of trust and security in our solidity contracts. The developer community is invited to understand and pick-apart our open source "Polymath-core" code base.

We are supplying the following rewards structure:

  • 8 ETH for Critical severity bugs
  • 5 ETH for High severity bugs
  • 3 ETH for Medium severity bugs
  • 1 ETH for Low severity bugs

It is highly advised to read through the following links for context and architecture information: Our Whitepaper, Release of the core code base, Blog: Intro to Polymath-Core architecture, and Blog: Deeper into the architecture

Scope and Architecture Explanation

We are solely interested in having our core solidity contracts audited for bugs. Below, we explain which files from our repository are "in scope" and briefly what each of them does.

TAGGED RELEASE VERSION v1.0.0 ONLY - We ONLY want code reviewed at this snapshot of the codebase. This is at commit d913d00. We do not want to completely discourage you from notifying us of bugs in newer releases, but there is no guarentee we will give awards.

  • /contracts/TickerRegistry.sol
    • Users should be able to register a token symbol to it. Only unique symbols allowed. After a pre-set time the symbol becomes available again if the user didn't deploy the actual token.
  • /contracts/SecurityTokenRegistry.sol
    • Deploys SecurityToken instances (through a "Proxy" mechanism). Only allows tokens whose symbols have been previously registered in TickerRegistry under the user's account. Has a versioning mechanism that changes which version of the SecurityToken would be deployed.
  • /contracts/tokens/STVersionProxy001.sol
    • Proxy contract for version 1 of the SecurityToken. The SecurityTokenRegistry initially points to this one, which deploys the SecurityToken V1. Later on, SecurityTokenRegistry would be changed to point to STVersionProxy002 which would deploy a SecurityTokenV2 with added features.
  • /contracts/tokens/SecurityToken.sol
    • Inherits from IST20 interface which is an ERC20 contract with a verifyTransfer() function added to it. Modules can be attached to it to extend its functionality. Should work exactly as ERC20 tokens, save for the transfer restrictions applied to it.
  • /contracts/ModuleRegistry.sol
    • Repository for registered modules. For modules to be used by SecurityToken, they first need to be added to the registry and approved by Polymath owner. (The author of the module may also use it for their own SecurityToken, but for it to be available to anyone, the author has to get Polymath to verify it first).
  • /contracts/modules/*/*ManagerFactory.sol
    • Factories are the ones registered to the ModuleRegistry and when a SecurityToken has a module attached, the corresponding Factory will instantiate its corresponding module. Module Factories hold the general module information and reputation.
    • Note: * = wildcard; There are multiple directories and files with *ManagerFactory.sol files in them
  • /contracts/modules/TransferManager/GeneralTransferManager.sol
    • Has an internal whitelist and it's verifyTransfer() method is called by SecurityToken to decide if the token transfer is allowed. If the tokens are to be transferred from the initial issuance, the requirement for verifyTransfer is that the token buyer is on the whitelist. If we are talking about a transfer between two whitelisted addresses, both should be on the whitelist and their sell/purchase lockups must have ended.
  • /contracts/modules/TransferManager/ExchangeTransferManager.sol
    • A transfer manager module that is in control of an exchange. They can add addresses to the whitelist and verifyTransfer should succeed as long as one of the involved parties is the exchange and the other party is in this whitelist.
  • /contracts/modules/PermissionManager/GeneralPermissionManager.sol
    • Handles delegation of permissions to other accounts. For example, owner can set permissions over the GeneralTransferManager to some other account so that they can modify the whitelist on the owner's behalf. This might come in useful for 3rd party KYC or handlers businesses that watch-over and help with the entire process.
  • /contracts/modules/STO/CappedSTO.sol
    • STOs (Security Token Offerings) are the equivalent to crowdsale contracts in ICOs. The CappedSTO is one simple example of how it would be construed. We need to make sure the STO works as intended and that there is no vulnerabilities that allow an attacker to drain funds, DoS it, etc.

Bug Examples

Compensation / Classification

We will utilize the OWASP risk rating model to assist us in classifying and awarding bounties. We also define the various levels in terms of Polymath technologies below.

owasp

  • Critical severity bugs - 10 ETH:
    • Bugs that enable an arbitrary attacker to steal POLY from any of the contracts or actors of the platform. Bugs that enable an arbitrary attacker to steal Security Tokens created through Polymath Core from any of the contracts or actors of the platform.
  • High severity bugs - 6 ETH:
    • Bugs that would render the Polymath Core protocol unusable and/or make Security Tokens issued through Polymath Core vulnerable to attacks.
  • Medium severity bugs - 3 ETH:
    • Bugs that break specified or reasonably assumed protocol invariants that do not enable an arbitrary attacker to steal anything without action on the part of the user whose assets / funds are stolen, but enable certain parties to obtain funds or assets in unexpected ways.
  • Low severity bugs - 1 ETH:
    • Bugs that break specified or reasonably assumed protocol invariants but do not have a financial incentive for anyone and do not significantly impair contract functionality or could easily be avoided during protocol use.

Submission Process

  1. Create a new/seperate github issue on the polymath-core repository.
  2. Your submission must include the following details:
    • Description of the location and potential impact of the vulnerability
    • Observed behavior
    • Expected behavior
    • How to replicate - A detailed description of the steps required to reproduce the vulnerability – POC scripts, steps taken, and screenshots will all be helpful
  3. The Polymath team will respond to reported bugs within 72 to 96 hours from the time of submission. We will review each report and remain responsible for deciding the severity of each bug submitted. High quality, easy to read reports can be rewarded extra for the sake of making communication easier for both parties.
  4. Payouts on bugs will come through either:
    • gitcoin platform (we can send as a 'tip' to your github acct name) or
    • via an ETH address that you directly supply to us in the issues comments

You may (optionally) use gitcoin's system to 'grab' this issue which lets us know your intention to work on it. Many people can. However, you should still make sure to follow the instructions above. Gitcoin allows you get paid ETH through your github tag (you wont have to give us an ETH address).

Most of the rules on https://bounty.ethereum.org apply:

  • First come, first serve.
  • Issues that have already been submitted by another user or are already known to the Polymath team are not eligible for bounty rewards. (Make sure that the issue has not been previously submitted or fixed in other commits)
  • Public disclosure of an actively exploitable vulnerability makes it ineligible for a bounty.
  • Determinations of eligibility, rewards and all terms related to an award are at the sole and final discretion of the Polymath team.

Responsible Disclosure

  • Don’t make the details of any actively exploitable vulnerability you find public until after we have confirmed to you that it’s fine to do so. You can create an issue with a generalized title, explaining that you wish to speak further in private.
  • Do not try to actively exploit any security issue you find

Questions

Clarification questions can come here in this issue's discussion thread.

`useModule` does not properly check that caller is a SecurityToken

useModule calls getSecurityTokenData in the SecurityTokenRegistrar, which in turn checks the owner of the referenced security token address. However, this call will succeed provided the referenced security token address has an owner variable, even if the address is not actually a security token.

A better option would be to check that the address is in the STR registry, but this is not possible for modules deployed via the STVersionProxy*.sol contracts as they add modules before the token has been added to the STR registry.

Security Token Upgrading

  • I don't think we should be looking to facilitate upgrading in place for security tokens for a host of reasons (gives issuers too much power / ability to screw up).
  • It would however be quite nice to allow an issuer to create a new token as a clone from a previous one, which should be possible given the checkpoint functionality. This means that if an issuer wants to upgrade to a later version of the security token they can do, carrying over existing balances (similar to the clone behaviour of MiniMe). This would need some thought as to the exact mechanics of how this would work.

Review Module upgrading system

Say we have one of our modules, the TransferManagerModule (and factory).

We want to release a V2 of it for some reason (detected a bug or adding new feature).

We don't want people to be able to use V1 of TransferManagerModule anymore. But we don;t want existing tokens using that module to break if they don't want to replace it.

What mechanism do we have now to deprecate an old module without breaking existing tokens?

Module Upgrading

Do we need something beyond what we already have? What is the downside to this approach:

  • deploy new CappedSTOFactory contract with updated logic.
  • un-verify the previous CappedSTOFactory contract in the module registry
  • verify the new CappedSTOFactory in the module registry
  • in the dApp change over to the new CappedSTOFactory address
    At this point, the only CappedSTO that users will be able to add to their token is the new version (they can't add the old version as it was deployed by Polymath, so address won't match issuer address).
    Any existing tokens w/ capped STOs attached should not be affected.
    Module names are not unique (someone else could register a CappedSTOFactory with the same tags & names in the module registry), only their addresses are, so I don't think it is a problem having two CappedSTOs in the module registry, provided only one of them is verified.
    We should add an additional function in the module registry to allow module owners to remove their modules from the registry if they wish to, but we don't need to rely on this happening.
    NB - if we change the way we manage modules as per @stephane meeting then this may need to be reviewed.

Questions:

  • Is it reasonable to "not allow" modules to have any dependencies on the STR? There may be use-cases where this it is useful for a module to have a view of the overall security token registries (e.g. to look up other tokens owned by the same issuer).
  • We could have a "DataFeed" module type of which the oracles would be one example of. This would allow us to charge for data feeds if we wanted to. We would need to decide whether every e.g. POLYUSD data feed used the same source (i.e. as it works today) or whether everyone get's their own oracle that they need to maintain (I'm not a fan of this).

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.