Skip to content
Adam Dossa edited this page Apr 5, 2018 · 15 revisions

Polymath Protocol

ST20 standard (interfaces/IST20.sol)

The ST20 interface builds on top of the ERC20 standard to provide a new standard for security tokens. It provides one additional method, which can be used on-chain for other contracts to check whether a specific token transfer (or transferFrom) transaction is allowed:

function verifyTransfer(address _from, address _to, uint256 _amount) public view returns (bool success);

A token which implements this standard must provide an implementation of this function, which always returns either true or false, and does not throw. Furthermore the transfer and transferFrom functions must respect the outcome of this function, and only succeed if this function returns true. Note that a transfer or transferFrom call may still throw or return false if verifyTransfer returns true, but if verifyTransferreturnsfalse`, they must not succeed.

As an example, a ST20 token which only allows transfers between known addresses, should return false unless the transfer is between know addresses, otherwise it should return true.

This allows other contracts to check whether a token transfer is valid before actually executing the transfer.

The standard also requires every token to implement a mint function that is used to issue the token:

function mint(address _investor, uint256 _amount) public returns (bool success);

SecurityToken (contracts/tokens/SecurityToken.sol)

This is the first Polymath implementation of an ST20 token. It fulfils the ST20 standard, and provides some additional functionality on top of this standard.

This contract allows delegation of certain types of functionality (permissions, transfer restrictions and fund raising) to modules that can be attached to the SecurityToken contract.

Future versions of SecurityToken will provide other types of module functionality (e.g. governance, dividends, reporting) in a similar fashion.

Modules

A module is a contract that encapsulates a self-contained piece of functionality related to a Polymath security token.

Every module must be created via a factory contract, that conforms to interfaces/IModuleFactory.sol. Module Factories provide certain basic information about the modules which they create, and are attached to a SecurityToken and are also responsible for instantiating and initialising their associated modules.

Module Factories are registered in the ModuleRegistry by their creators.

IModuleFactory provides an interface to provide this standardised information and deployment functionality.

getType

function getType() public view returns(uint8);

This should return the type of module. Currently defined types are:

uint8 public constant PERMISSIONMANAGER_KEY = 1;
uint8 public constant TRANSFERMANAGER_KEY = 2;
uint8 public constant STO_KEY = 3;

which will be extended in future versions.

Description of Module

The module factory provides several helper functions for UIs to understand the details of a given module:

function getName() public view returns(bytes32);
function getDescription() public view returns(string);
function getTitle() public view returns(string);
function getInstructions() public view returns (string);

Cost

Each module can have an associated charge in POLY that is levied by the module factory, and paid by the SecurityToken in order to attach the module to a security token.

The basic Polymath provided modules have a 0 cost, but third parties are free to charge POLY to attach their modules.

The function:

function getCost() public view returns(uint256);

should return the cost to attach a module.

Deployment

In order to create a module, and attach it to a SecurityToken, the module factory must implement a deploy function which takes initialisation arguments, and returns the address of the newly created module:

function deploy(bytes _data) external returns(address);

The initialisation arguments are provided as a generic bytes _data. This data defines both the initialisation function in the newly created module, and the arguments to this function. As an example, an STO module may have an initialisation function configure, which takes a uint256 _startTime parameter. In this instance, the first part of _data is the function signature (e.g. bytes4(keccak256("configure(uint256)"))) and this is then followed by the _startTime value.

The module factory should use the getSig function to check that the provided _data matches the named initialisation function and signature before using the low-level call method to call it.

Adding Modules

A module is added to a SecurityToken by calling the function:

    function addModule(
        address _moduleFactory,
        bytes _data,
        uint256 _maxCost,
        uint256 _budget,
        bool _replaceable
    )

This function can only be called by the SecurityToken owner. In addition to the already discussed parameters, the function can specify an ongoing budget for the module. This can be used to pay on-going charges, such as KYC'ing individual investors.

It is possible to add up to 10 modules of the same type (e.g. up to ten separate TransferManager modules). How these modules are used is determined by the SecurityToken implementation. For example TransferManager modules are used to determine the result of verifyTransfer in SecurityToken.

Clone this wiki locally