Skip to content

Commit 45993cb

Browse files
authored
Merge pull request #90 from PolymathNetwork/add_granularity
Add granularity to Security Tokens
2 parents 297b0d6 + d690113 commit 45993cb

16 files changed

+95
-19
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ All notable changes to this project will be documented in this file.
1414

1515
## Added
1616

17+
* generateSecurityToken in SecurityTokenRegistry takes an additional parameter specifying whether the token is divisible.
1718
* IModule contract takes the polyToken contract address as the constructor argument to wrapping all the factories with the polyToken contract address.
1819
* `takeFee()` new function introduced to extract the POLY token from the factory. It only be called by the owner of the factory.
1920
* Added ability for issuer to provide a signed piece of data to allow investors to whitelist themselves.

contracts/SecurityTokenRegistry.sol

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ contract SecurityTokenRegistry is Ownable, ISecurityTokenRegistry, Util {
3939
* @param _decimals Decimals value for token
4040
* @param _tokenDetails off-chain details of the token
4141
*/
42-
function generateSecurityToken(string _name, string _symbol, uint8 _decimals, bytes32 _tokenDetails) public {
42+
function generateSecurityToken(string _name, string _symbol, uint8 _decimals, bytes32 _tokenDetails, bool _divisible) public {
4343
require(bytes(_name).length > 0 && bytes(_symbol).length > 0, "Name and Symbol string length should be greater than 0");
4444
require(ITickerRegistry(tickerRegistry).checkValidity(_symbol, msg.sender, _name), "Trying to use non-valid symbol");
4545
string memory symbol = upper(_symbol);
@@ -48,7 +48,8 @@ contract SecurityTokenRegistry is Ownable, ISecurityTokenRegistry, Util {
4848
symbol,
4949
_decimals,
5050
_tokenDetails,
51-
msg.sender
51+
msg.sender,
52+
_divisible
5253
);
5354

5455
securityTokens[newSecurityTokenAddress] = SecurityTokenData(symbol, _tokenDetails);

contracts/interfaces/ISTProxy.sol

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,6 @@ pragma solidity ^0.4.23;
33

44
contract ISTProxy {
55

6-
function deployToken(string _name, string _symbol, uint8 _decimals, bytes32 _tokenDetails, address _issuer)
6+
function deployToken(string _name, string _symbol, uint8 _decimals, bytes32 _tokenDetails, address _issuer, bool _divisible)
77
public returns (address);
88
}

contracts/interfaces/ISecurityToken.sol

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ contract ISecurityToken is IST20, Ownable {
99
uint8 public constant PERMISSIONMANAGER_KEY = 1;
1010
uint8 public constant TRANSFERMANAGER_KEY = 2;
1111
uint8 public constant STO_KEY = 3;
12+
uint256 public granularity;
1213

1314
//TODO: Factor out more stuff here
1415
function checkPermission(address _delegate, address _module, bytes32 _perm) public view returns(bool);

contracts/interfaces/ISecurityTokenRegistry.sol

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,12 @@ contract ISecurityTokenRegistry {
2323

2424
/**
2525
* @dev Creates a new Security Token and saves it to the registry
26-
* @param _name Name of the token
26+
* @param _name Name of the token
2727
* @param _symbol Ticker symbol of the security token
2828
* @param _decimals Decimals value for token
2929
* @param _tokenDetails off-chain details of the token
3030
*/
31-
function generateSecurityToken(string _name, string _symbol, uint8 _decimals, bytes32 _tokenDetails) public;
31+
function generateSecurityToken(string _name, string _symbol, uint8 _decimals, bytes32 _tokenDetails, bool _divisible) public;
3232

3333
function setProtocolVersion(address _stVersionProxyAddress, bytes32 _version) public;
3434

contracts/tokens/STVersionProxy001.sol

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,13 @@ contract STVersionProxy001 is ISTProxy {
1919
* @dev deploys the token and adds default modules like permission manager and transfer manager.
2020
* Future versions of the proxy can attach different modules or pass some other paramters.
2121
*/
22-
function deployToken(string _name, string _symbol, uint8 _decimals, bytes32 _tokenDetails, address _issuer)
22+
function deployToken(string _name, string _symbol, uint8 _decimals, bytes32 _tokenDetails, address _issuer, bool _divisible)
2323
public returns (address) {
2424
address newSecurityTokenAddress = new SecurityToken(
2525
_name,
2626
_symbol,
2727
_decimals,
28+
_divisible ? 1 : uint256(10)**_decimals,
2829
_tokenDetails,
2930
msg.sender
3031
);

contracts/tokens/STVersionProxy002.sol

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,14 @@ contract STVersionProxy002 is ISTProxy {
1616
transferManagerFactory = _transferManagerFactory;
1717
}
1818

19-
function deployToken(string _name, string _symbol, uint8 _decimals, bytes32 _tokenDetails, address _issuer)
19+
function deployToken(string _name, string _symbol, uint8 _decimals, bytes32 _tokenDetails, address _issuer, bool _divisible)
2020
public returns (address)
2121
{
2222
address newSecurityTokenAddress = new SecurityTokenV2(
2323
_name,
2424
_symbol,
2525
_decimals,
26+
_divisible ? 1 : uint256(10)**_decimals,
2627
_tokenDetails,
2728
msg.sender
2829
);

contracts/tokens/SecurityToken.sol

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ contract SecurityToken is ISecurityToken, StandardToken, DetailedERC20 {
5252
uint256 _timestamp
5353
);
5454

55+
event LogGranularityChanged(uint256 _oldGranularity, uint256 _newGranularity);
5556
event LogModuleRemoved(uint8 indexed _type, address _module, uint256 _timestamp);
5657
event LogModuleBudgetChanged(uint8 indexed _moduleType, address _module, uint256 _budget);
5758
event Mint(address indexed to, uint256 amount);
@@ -71,10 +72,16 @@ contract SecurityToken is ISecurityToken, StandardToken, DetailedERC20 {
7172
_;
7273
}
7374

75+
modifier checkGranularity(uint256 _amount) {
76+
require(_amount.div(granularity).mul(granularity) == _amount, "Unable to modify token balances at this granularity");
77+
_;
78+
}
79+
7480
constructor (
7581
string _name,
7682
string _symbol,
7783
uint8 _decimals,
84+
uint256 _granularity,
7885
bytes32 _tokenDetails,
7986
address _securityTokenRegistry
8087
)
@@ -85,6 +92,7 @@ contract SecurityToken is ISecurityToken, StandardToken, DetailedERC20 {
8592
moduleRegistry = ISecurityTokenRegistry(_securityTokenRegistry).moduleRegistry();
8693
polyToken = ERC20(ISecurityTokenRegistry(_securityTokenRegistry).polyAddress());
8794
tokenDetails = _tokenDetails;
95+
granularity = _granularity;
8896
}
8997

9098
function addModule(
@@ -206,6 +214,15 @@ contract SecurityToken is ISecurityToken, StandardToken, DetailedERC20 {
206214
emit LogModuleBudgetChanged(_moduleType, modules[_moduleType][_moduleIndex].moduleAddress, _budget);
207215
}
208216

217+
/**
218+
* @dev allows owner to change token granularity
219+
*/
220+
function changeGranularity(uint256 _granularity) public onlyOwner {
221+
require(_granularity != 0, "Granularity can not be 0");
222+
emit LogGranularityChanged(granularity, _granularity);
223+
granularity = _granularity;
224+
}
225+
209226
/**
210227
* @dev Overloaded version of the transfer function
211228
*/
@@ -224,7 +241,7 @@ contract SecurityToken is ISecurityToken, StandardToken, DetailedERC20 {
224241

225242
// Permissions this to a TransferManager module, which has a key of 2
226243
// If no TransferManager return true
227-
function verifyTransfer(address _from, address _to, uint256 _amount) public view returns (bool success) {
244+
function verifyTransfer(address _from, address _to, uint256 _amount) public view checkGranularity(_amount) returns (bool success) {
228245
if (modules[TRANSFERMANAGER_KEY].length == 0) {
229246
return true;
230247
}
@@ -240,7 +257,7 @@ contract SecurityToken is ISecurityToken, StandardToken, DetailedERC20 {
240257
* @dev mints new tokens and assigns them to the target _investor.
241258
* Can only be called by the STO attached to the token (Or by the ST owner if there's no STO attached yet)
242259
*/
243-
function mint(address _investor, uint256 _amount) public onlyModule(STO_KEY, true) returns (bool success) {
260+
function mint(address _investor, uint256 _amount) public onlyModule(STO_KEY, true) checkGranularity(_amount) returns (bool success) {
244261
require(verifyTransfer(address(0), _investor, _amount), "Transfer is not valid");
245262
totalSupply_ = totalSupply_.add(_amount);
246263
balances[_investor] = balances[_investor].add(_amount);

contracts/tokens/SecurityTokenV2.sol

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ contract SecurityTokenV2 is SecurityToken {
1414
string _name,
1515
string _symbol,
1616
uint8 _decimals,
17+
uint256 _granularity,
1718
bytes32 _tokenDetails,
1819
address _securityTokenRegistry
1920
)
@@ -22,6 +23,7 @@ contract SecurityTokenV2 is SecurityToken {
2223
_name,
2324
_symbol,
2425
_decimals,
26+
_granularity,
2527
_tokenDetails,
2628
_securityTokenRegistry)
2729
{

test/Issuance.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,7 @@ contract('Issuance', accounts => {
235235
});
236236

237237
it("POLYMATH: Should generate the new security token with the same symbol as registered above", async () => {
238-
let tx = await I_SecurityTokenRegistry.generateSecurityToken(name, symbol, decimals, tokenDetails, { from: account_polymath });
238+
let tx = await I_SecurityTokenRegistry.generateSecurityToken(name, symbol, decimals, tokenDetails, false, { from: account_polymath });
239239

240240
// Verify the successful generation of the security token
241241
assert.equal(tx.logs[1].args._ticker, symbol, "SecurityToken doesn't get deployed");

0 commit comments

Comments
 (0)