Skip to content

Increased STR compatibility #640

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 16 commits into from
Apr 15, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 9 additions & 19 deletions contracts/STRGetter.sol
Original file line number Diff line number Diff line change
Expand Up @@ -201,15 +201,13 @@ contract STRGetter is EternalStorage {
* @return address is the issuer of the security Token.
* @return string is the details of the security token.
* @return uint256 is the timestamp at which security Token was deployed.
* @return version of the securityToken
*/
function getSecurityTokenData(address _securityToken) external view returns (string memory, address, string memory, uint256, uint8[] memory) {
function getSecurityTokenData(address _securityToken) external view returns (string memory, address, string memory, uint256) {
return (
getStringValue(Encoder.getKey("securityTokens_ticker", _securityToken)),
IOwnable(_securityToken).owner(),
getStringValue(Encoder.getKey("securityTokens_tokenDetails", _securityToken)),
getUintValue(Encoder.getKey("securityTokens_deployedAt", _securityToken)),
ISecurityToken(_securityToken).getVersion()
getUintValue(Encoder.getKey("securityTokens_deployedAt", _securityToken))
);
}

Expand All @@ -221,26 +219,18 @@ contract STRGetter is EternalStorage {
}

/**
* @notice Gets Protocol version
*/
function getLatestProtocolVersion() public view returns(uint8[] memory) {
return VersionUtils.unpack(uint24(getUintValue(Encoder.getKey("latestVersion"))));
}

/**
* @notice Gets the security token launch fee
* @return Fee amount
* @notice Returns the STFactory Address of a particular version
* @param _protocolVersion Packed protocol version
*/
function getSecurityTokenLaunchFee() public view returns(uint256) {
return getUintValue(STLAUNCHFEE);
function getSTFactoryAddressOfVersion(uint256 _protocolVersion) public view returns(address) {
return getAddressValue(Encoder.getKey("protocolVersionST", _protocolVersion));
}

/**
* @notice Gets the ticker registration fee
* @return Fee amount
* @notice Gets Protocol version
*/
function getTickerRegistrationFee() public view returns(uint256) {
return getUintValue(TICKERREGFEE);
function getLatestProtocolVersion() public view returns(uint8[] memory) {
return VersionUtils.unpack(uint24(getUintValue(Encoder.getKey("latestVersion"))));
}

/**
Expand Down
97 changes: 75 additions & 22 deletions contracts/SecurityTokenRegistry.sol
Original file line number Diff line number Diff line change
Expand Up @@ -100,8 +100,8 @@ contract SecurityTokenRegistry is EternalStorage, Proxy {
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
// Emit when ownership of the ticker gets changed
event ChangeTickerOwnership(string _ticker, address indexed _oldOwner, address indexed _newOwner);
// Emit at the time of launching a new security token
event NewSecurityToken(
// Emit at the time of launching a new security token of version 3.0+
event NewSecurityTokenCreated(
string _ticker,
string _name,
address indexed _securityTokenAddress,
Expand All @@ -113,16 +113,29 @@ contract SecurityTokenRegistry is EternalStorage, Proxy {
uint256 _polyFee,
uint256 _protocolVersion
);
// Emit at the time of launching a new security token v2.0.
// _registrationFee is in poly
event NewSecurityToken(
string _ticker,
string _name,
address indexed _securityTokenAddress,
address indexed _owner,
uint256 _addedAt,
address _registrant,
bool _fromAdmin,
uint256 _registrationFee
);
// Emit after ticker registration
// _registrationFee is in poly
// fee in usd is not being emitted to maintain backwards compatibility
event RegisterTicker(
address indexed _owner,
string _ticker,
string _name,
uint256 indexed _registrationDate,
uint256 indexed _expiryDate,
bool _fromAdmin,
uint256 _usdFee,
uint256 _polyFee
uint256 _registrationFee
);
// Emit at when issuer refreshes exisiting token
event SecurityTokenRefreshed(
Expand Down Expand Up @@ -255,6 +268,22 @@ contract SecurityTokenRegistry is EternalStorage, Proxy {
}
}

/**
* @notice Gets the security token launch fee
* @return Fee amount
*/
function getSecurityTokenLaunchFee() public returns(uint256 polyFee) {
(, polyFee) = getFees(STLAUNCHFEE);
}

/**
* @notice Gets the ticker registration fee
* @return Fee amount
*/
function getTickerRegistrationFee() public returns(uint256 polyFee) {
(, polyFee) = getFees(TICKERREGFEE);
}

/**
* @notice Set the getter contract address
* @param _getterContract Address of the contract
Expand Down Expand Up @@ -284,7 +313,7 @@ contract SecurityTokenRegistry is EternalStorage, Proxy {
require(_owner != address(0), "Bad address");
require(bytes(_ticker).length > 0 && bytes(_ticker).length <= 10, "Bad ticker");
// Attempt to charge the reg fee if it is > 0 USD
(uint256 _usdFee, uint256 _polyFee) = _takeFee(TICKERREGFEE);
(, uint256 _polyFee) = _takeFee(TICKERREGFEE);
string memory ticker = Util.upper(_ticker);
require(_tickerAvailable(ticker), "Ticker reserved");
// Check whether ticker was previously registered (and expired)
Expand All @@ -293,7 +322,7 @@ contract SecurityTokenRegistry is EternalStorage, Proxy {
_deleteTickerOwnership(previousOwner, ticker);
}
/*solium-disable-next-line security/no-block-members*/
_addTicker(_owner, ticker, _tokenName, now, now.add(getUintValue(EXPIRYLIMIT)), false, false, _usdFee, _polyFee);
_addTicker(_owner, ticker, _tokenName, now, now.add(getUintValue(EXPIRYLIMIT)), false, false, _polyFee);
}

/**
Expand All @@ -307,14 +336,13 @@ contract SecurityTokenRegistry is EternalStorage, Proxy {
uint256 _expiryDate,
bool _status,
bool _fromAdmin,
uint256 _usdFee,
uint256 _polyFee
)
internal
{
_setTickerOwnership(_owner, _ticker);
_storeTickerDetails(_ticker, _owner, _registrationDate, _expiryDate, _tokenName, _status);
emit RegisterTicker(_owner, _ticker, _tokenName, _registrationDate, _expiryDate, _fromAdmin, _usdFee, _polyFee);
emit RegisterTicker(_owner, _ticker, _tokenName, _registrationDate, _expiryDate, _fromAdmin, _polyFee);
}

/**
Expand Down Expand Up @@ -370,7 +398,7 @@ contract SecurityTokenRegistry is EternalStorage, Proxy {
if (_status) {
require(getAddressValue(Encoder.getKey("tickerToSecurityToken", _ticker)) != address(0), "Not registered");
}
_addTicker(_owner, _ticker, _tokenName, _registrationDate, _expiryDate, _status, true, uint256(0), uint256(0));
_addTicker(_owner, _ticker, _tokenName, _registrationDate, _expiryDate, _status, true, uint256(0));
}

function _tickerOwner(string memory _ticker) internal view returns(address) {
Expand Down Expand Up @@ -503,6 +531,25 @@ contract SecurityTokenRegistry is EternalStorage, Proxy {
// Security Token Management
/////////////////////////////

/**
* @notice Deploys an instance of a new Security Token of version 2.0 and records it to the registry
* @dev this function is for backwards compatibilty with 2.0 dApp.
* @param _name is the name of the token
* @param _ticker is the ticker symbol of the security token
* @param _tokenDetails is the off-chain details of the token
* @param _divisible is whether or not the token is divisible
*/
function generateSecurityToken(
string calldata _name,
string calldata _ticker,
string calldata _tokenDetails,
bool _divisible
)
external
{
generateNewSecurityToken(_name, _ticker, _tokenDetails, _divisible, msg.sender, VersionUtils.pack(2, 0, 0));
}

/**
* @notice Deploys an instance of a new Security Token and records it to the registry
* @param _name is the name of the token
Expand All @@ -514,7 +561,7 @@ contract SecurityTokenRegistry is EternalStorage, Proxy {
* - `_protocolVersion` is the packed value of uin8[3] array (it will be calculated offchain)
* - if _protocolVersion == 0 then latest version of securityToken will be generated
*/
function generateSecurityToken(
function generateNewSecurityToken(
string memory _name,
string memory _ticker,
string memory _tokenDetails,
Expand All @@ -525,26 +572,32 @@ contract SecurityTokenRegistry is EternalStorage, Proxy {
public
whenNotPausedOrOwner
{
uint256 protocolVersion = _protocolVersion;
require(bytes(_name).length > 0 && bytes(_ticker).length > 0, "Bad ticker");
require(_treasuryWallet != address(0), "0x0 not allowed");
if (_protocolVersion == 0) {
protocolVersion = getUintValue(LATEST_VERSION);
_protocolVersion = getUintValue(LATEST_VERSION);
}
require(protocolVersion != uint256(0), "Invalid version");
string memory ticker = Util.upper(_ticker);
bytes32 statusKey = Encoder.getKey("registeredTickers_status", ticker);
_ticker = Util.upper(_ticker);
bytes32 statusKey = Encoder.getKey("registeredTickers_status", _ticker);
require(!getBoolValue(statusKey), "Already deployed");
set(statusKey, true);
require(_tickerOwner(ticker) == msg.sender, "Not authorised");
address issuer = msg.sender;
require(_tickerOwner(_ticker) == issuer, "Not authorised");
/*solium-disable-next-line security/no-block-members*/
require(getUintValue(Encoder.getKey("registeredTickers_expiryDate", ticker)) >= now, "Ticker expired");
require(getUintValue(Encoder.getKey("registeredTickers_expiryDate", _ticker)) >= now, "Ticker expired");
(uint256 _usdFee, uint256 _polyFee) = _takeFee(STLAUNCHFEE);
address newSecurityTokenAddress =
_deployToken(_name, ticker, _tokenDetails, msg.sender, _divisible, _treasuryWallet, protocolVersion);
emit NewSecurityToken(
_ticker, _name, newSecurityTokenAddress, msg.sender, now, msg.sender, false, _usdFee, _polyFee, protocolVersion
);
_deployToken(_name, _ticker, _tokenDetails, issuer, _divisible, _treasuryWallet, _protocolVersion);
if (_protocolVersion == VersionUtils.pack(2, 0, 0)) {
// For backwards compatibilty. Should be removed with an update when we disable st 2.0 generation.
emit NewSecurityToken(
_ticker, _name, newSecurityTokenAddress, issuer, now, issuer, false, _polyFee
);
} else {
emit NewSecurityTokenCreated(
_ticker, _name, newSecurityTokenAddress, issuer, now, issuer, false, _usdFee, _polyFee, _protocolVersion
);
}
}

/**
Expand Down Expand Up @@ -644,7 +697,7 @@ contract SecurityTokenRegistry is EternalStorage, Proxy {
set(Encoder.getKey("tickerToSecurityToken", ticker), _securityToken);
_modifyTicker(_owner, ticker, _name, registrationTime, expiryTime, true);
_storeSecurityTokenData(_securityToken, ticker, _tokenDetails, _deployedAt);
emit NewSecurityToken(
emit NewSecurityTokenCreated(
ticker, _name, _securityToken, _owner, _deployedAt, msg.sender, true, uint256(0), uint256(0), 0
);
}
Expand Down
22 changes: 11 additions & 11 deletions test/b_capped_sto.js
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ contract("CappedSTO", async (accounts) => {
let foo = await STFactory.at(t);
console.log(await foo.polymathRegistry.call());

let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, treasury_wallet, 0, { from: token_owner });
let tx = await I_STRProxied.generateNewSecurityToken(name, symbol, tokenDetails, false, treasury_wallet, 0, { from: token_owner });

// Verify the successful generation of the security token
assert.equal(tx.logs[1].args._ticker, symbol, "SecurityToken doesn't get deployed");
Expand All @@ -197,7 +197,7 @@ contract("CappedSTO", async (accounts) => {
assert.equal(web3.utils.hexToString(log.args._name), "GeneralTransferManager");
});

it("Should intialize the auto attached modules", async () => {
it("Should initialize the auto attached modules", async () => {
let moduleData = (await stGetter_eth.getModulesByType(transferManagerKey))[0];
I_GeneralTransferManager = await GeneralTransferManager.at(moduleData);
});
Expand Down Expand Up @@ -633,14 +633,14 @@ contract("CappedSTO", async (accounts) => {
await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner });

await catchRevert(
I_STRProxied.generateSecurityToken(P_name, P_symbol, P_tokenDetails, false, "0x0000000000000000000000000000000000000000", 0, { from: token_owner })
I_STRProxied.generateNewSecurityToken(P_name, P_symbol, P_tokenDetails, false, "0x0000000000000000000000000000000000000000", 0, { from: token_owner })
);
});

it("POLY: Should generate the new security token with the same symbol as registered above", async () => {
await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner });

let tx = await I_STRProxied.generateSecurityToken(P_name, P_symbol, P_tokenDetails, false, treasury_wallet, 0, { from: token_owner });
let tx = await I_STRProxied.generateNewSecurityToken(P_name, P_symbol, P_tokenDetails, false, treasury_wallet, 0, { from: token_owner });

// Verify the successful generation of the security token
assert.equal(tx.logs[1].args._ticker, P_symbol, "SecurityToken doesn't get deployed");
Expand All @@ -656,7 +656,7 @@ contract("CappedSTO", async (accounts) => {
assert.equal(web3.utils.hexToString(log.args._name), "GeneralTransferManager");
});

it("POLY: Should intialize the auto attached modules", async () => {
it("POLY: Should initialize the auto attached modules", async () => {
let moduleData = (await stGetter_poly.getModulesByType(transferManagerKey))[0];
I_GeneralTransferManager = await GeneralTransferManager.at(moduleData);
});
Expand Down Expand Up @@ -847,11 +847,11 @@ contract("CappedSTO", async (accounts) => {
describe("Pricing Test cases for Module Factory", async () => {
it("Should return correct price when price is in poly", async () => {
let newFactory = await CappedSTOFactory.new(
new BN(1000),
new BN(1000),
I_CappedSTO_Array_POLY[0].address,
I_PolymathRegistry.address,
true,
new BN(1000),
new BN(1000),
I_CappedSTO_Array_POLY[0].address,
I_PolymathRegistry.address,
true,
{ from: account_polymath }
);
assert.equal((await newFactory.setupCostInPoly.call()).toString(), (new BN(1000)).toString());
Expand All @@ -860,7 +860,7 @@ contract("CappedSTO", async (accounts) => {
assert.equal((await newFactory.usageCost()).toString(), (new BN(1000)).toString());
});
});

describe("Check that we can reclaim ETH and ERC20 tokens from an STO", async () => {
//xxx
it("should attach a dummy STO", async () => {
Expand Down
4 changes: 2 additions & 2 deletions test/c_checkpoints.js
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ contract("Checkpoints", async function(accounts) {

it("Should generate the new security token with the same symbol as registered above", async () => {
await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner });
let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, token_owner, 0, { from: token_owner });
let tx = await I_STRProxied.generateNewSecurityToken(name, symbol, tokenDetails, false, token_owner, 0, { from: token_owner });

// Verify the successful generation of the security token
assert.equal(tx.logs[1].args._ticker, symbol.toUpperCase(), "SecurityToken doesn't get deployed");
Expand All @@ -144,7 +144,7 @@ contract("Checkpoints", async function(accounts) {
await I_SecurityToken.setController(account_controller, {from: token_owner});
})

it("Should intialize the auto attached modules", async () => {
it("Should initialize the auto attached modules", async () => {
let moduleData = (await stGetter.getModulesByType(2))[0];
I_GeneralTransferManager = await GeneralTransferManager.at(moduleData);
});
Expand Down
8 changes: 4 additions & 4 deletions test/d_count_transfer_manager.js
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ contract("CountTransferManager", async (accounts) => {
it("Should generate the new security token with the same symbol as registered above", async () => {
await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner });

let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, token_owner, 0, { from: token_owner });
let tx = await I_STRProxied.generateNewSecurityToken(name, symbol, tokenDetails, false, token_owner, 0, { from: token_owner });
// Verify the successful generation of the security token
assert.equal(tx.logs[1].args._ticker, symbol.toUpperCase(), "SecurityToken doesn't get deployed");

Expand All @@ -157,7 +157,7 @@ contract("CountTransferManager", async (accounts) => {
assert.equal(web3.utils.toAscii(log.args._name).replace(/\u0000/g, ""), "GeneralTransferManager");
});

it("Should intialize the auto attached modules", async () => {
it("Should initialize the auto attached modules", async () => {
let moduleData = (await stGetter.getModulesByType(2))[0];
I_GeneralTransferManager = await GeneralTransferManager.at(moduleData);
});
Expand Down Expand Up @@ -365,7 +365,7 @@ contract("CountTransferManager", async (accounts) => {

await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner });

let tx2 = await I_STRProxied.generateSecurityToken(name, symbol2, tokenDetails, false, token_owner, 0, { from: token_owner });
let tx2 = await I_STRProxied.generateNewSecurityToken(name, symbol2, tokenDetails, false, token_owner, 0, { from: token_owner });

I_SecurityToken2 = await SecurityToken.at(tx2.logs[1].args._securityTokenAddress);
stGetter2 = await STGetter.at(I_SecurityToken2.address);
Expand Down Expand Up @@ -428,7 +428,7 @@ contract("CountTransferManager", async (accounts) => {
assert.equal((await I_SecurityToken2.balanceOf(account_investor1)).toString(), new BN(web3.utils.toWei("1", "ether")).toString());
});

it("Should intialize the auto attached modules", async () => {
it("Should initialize the auto attached modules", async () => {
let moduleData = (await stGetter2.getModulesByType(2))[0];
I_GeneralTransferManager2 = await GeneralTransferManager.at(moduleData);
});
Expand Down
Loading