Skip to content
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
2 changes: 1 addition & 1 deletion contracts/PolymathRegistry.sol
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ contract PolymathRegistry is ReclaimTokens {
*/
function getAddress(string calldata _nameKey) external view returns(address) {
bytes32 key = keccak256(bytes(_nameKey));
require(storedAddresses[key] != address(0), "Invalid address key");
require(storedAddresses[key] != address(0), "Invalid key");
return storedAddresses[key];
}

Expand Down
59 changes: 37 additions & 22 deletions contracts/SecurityTokenRegistry.sol
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import "./libraries/Util.sol";
import "./libraries/Encoder.sol";
import "./libraries/VersionUtils.sol";
import "./proxy/Proxy.sol";
import "./interfaces/IOracle.sol";
import "./libraries/DecimalMath.sol";

/**
* @title Registry contract for issuers to register their tickers and security tokens
Expand Down Expand Up @@ -74,6 +76,8 @@ contract SecurityTokenRegistry is EternalStorage, Proxy {
bytes32 constant POLYMATHREGISTRY = 0x90eeab7c36075577c7cc5ff366e389fefa8a18289b949bab3529ab4471139d4d;
bytes32 constant STRGETTER = 0x982f24b3bd80807ec3cb227ba152e15c07d66855fa8ae6ca536e689205c0e2e9;

string constant POLY_ORACLE = "PolyUsdOracle";

// Emit when network becomes paused
event Pause(uint256 _timestammp);
// Emit when network becomes unpaused
Expand All @@ -99,7 +103,8 @@ contract SecurityTokenRegistry is EternalStorage, Proxy {
uint256 _addedAt,
address _registrant,
bool _fromAdmin,
uint256 _registrationFee
uint256 _usdFee,
uint256 _polyFee
);
// Emit after ticker registration
event RegisterTicker(
Expand All @@ -109,7 +114,8 @@ contract SecurityTokenRegistry is EternalStorage, Proxy {
uint256 indexed _registrationDate,
uint256 indexed _expiryDate,
bool _fromAdmin,
uint256 _registrationFee
uint256 _usdFee,
uint256 _polyFee
);

/////////////////////////////
Expand Down Expand Up @@ -159,8 +165,8 @@ contract SecurityTokenRegistry is EternalStorage, Proxy {
* @notice Initializes instance of STR
* @param _polymathRegistry is the address of the Polymath Registry
* @param _STFactory is the address of the Proxy contract for Security Tokens
* @param _stLaunchFee is the fee in POLY required to launch a token
* @param _tickerRegFee is the fee in POLY required to register a ticker
* @param _stLaunchFee is the fee in USD required to launch a token
* @param _tickerRegFee is the fee in USD required to register a ticker
* @param _owner is the owner of the STR,
* @param _getterContract Contract address of the contract which consists getter functions.
*/
Expand Down Expand Up @@ -205,6 +211,19 @@ contract SecurityTokenRegistry is EternalStorage, Proxy {
set(POLYTOKEN, IPolymathRegistry(polymathRegistry).getAddress("PolyToken"));
}

/**
* @notice Converts USD fees into POLY amounts
*/
function _takeFee(bytes32 _feeType) internal returns (uint256, uint256){
address polymathRegistry = getAddressValue(POLYMATHREGISTRY);
uint256 polyRate = IOracle(IPolymathRegistry(polymathRegistry).getAddress(POLY_ORACLE)).getPrice();
uint256 usdFee = getUintValue(_feeType);
uint256 polyFee = DecimalMath.div(usdFee, polyRate);
if (polyFee > 0)
require(IERC20(getAddressValue(POLYTOKEN)).transferFrom(msg.sender, address(this), polyFee), "Insufficent allowance");
return (usdFee, polyFee);
}

/**
* @notice Set the getter contract address
* @param _getterContract Address of the contract
Expand Down Expand Up @@ -233,10 +252,8 @@ contract SecurityTokenRegistry is EternalStorage, Proxy {
function registerTicker(address _owner, string calldata _ticker, string calldata _tokenName) external whenNotPausedOrOwner {
require(_owner != address(0), "Owner should not be 0x");
require(bytes(_ticker).length > 0 && bytes(_ticker).length <= 10, "Ticker length range (0,10]");
// Attempt to charge the reg fee if it is > 0 POLY
uint256 tickerFee = getUintValue(TICKERREGFEE);
if (tickerFee > 0)
require(IERC20(getAddressValue(POLYTOKEN)).transferFrom(msg.sender, address(this), tickerFee), "Insufficent allowance");
// Attempt to charge the reg fee if it is > 0 USD
(uint256 _usdFee, uint256 _polyFee) = _takeFee(TICKERREGFEE);
string memory ticker = Util.upper(_ticker);
require(_tickerAvailable(ticker), "Ticker is reserved");
// Check whether ticker was previously registered (and expired)
Expand All @@ -245,7 +262,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, tickerFee);
_addTicker(_owner, ticker, _tokenName, now, now.add(getUintValue(EXPIRYLIMIT)), false, false, _usdFee, _polyFee);
}

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

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

function _tickerOwner(string memory _ticker) internal view returns(address) {
Expand Down Expand Up @@ -478,10 +496,7 @@ contract SecurityTokenRegistry is EternalStorage, Proxy {
require(_tickerOwner(ticker) == msg.sender, "Not authorised");
/*solium-disable-next-line security/no-block-members*/
require(getUintValue(Encoder.getKey("registeredTickers_expiryDate", ticker)) >= now, "Ticker gets expired");

uint256 launchFee = getUintValue(STLAUNCHFEE);
if (launchFee > 0)
require(IERC20(getAddressValue(POLYTOKEN)).transferFrom(msg.sender, address(this), launchFee), "Insufficient allowance");
(uint256 _usdFee, uint256 _polyFee) = _takeFee(STLAUNCHFEE);

address newSecurityTokenAddress = ISTFactory(getAddressValue(Encoder.getKey("protocolVersionST", getUintValue(Encoder.getKey("latestVersion"))))).deployToken(
_name,
Expand All @@ -497,7 +512,7 @@ contract SecurityTokenRegistry is EternalStorage, Proxy {
_storeSecurityTokenData(newSecurityTokenAddress, ticker, _tokenDetails, now);
set(Encoder.getKey("tickerToSecurityToken", ticker), newSecurityTokenAddress);
/*solium-disable-next-line security/no-block-members*/
emit NewSecurityToken(ticker, _name, newSecurityTokenAddress, msg.sender, now, msg.sender, false, launchFee);
emit NewSecurityToken(ticker, _name, newSecurityTokenAddress, msg.sender, now, msg.sender, false, _usdFee, _polyFee);
}

/**
Expand Down Expand Up @@ -535,7 +550,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(ticker, _name, _securityToken, _owner, _deployedAt, msg.sender, true, getUintValue(STLAUNCHFEE));
emit NewSecurityToken(ticker, _name, _securityToken, _owner, _deployedAt, msg.sender, true, uint256(0), uint256(0));
}

/**
Expand Down Expand Up @@ -594,8 +609,8 @@ contract SecurityTokenRegistry is EternalStorage, Proxy {
}

/**
* @notice Sets the ticker registration fee in POLY tokens. Only Polymath.
* @param _tickerRegFee is the registration fee in POLY tokens (base 18 decimals)
* @notice Sets the ticker registration fee in USD tokens. Only Polymath.
* @param _tickerRegFee is the registration fee in USD tokens (base 18 decimals)
*/
function changeTickerRegistrationFee(uint256 _tickerRegFee) external onlyOwner {
uint256 fee = getUintValue(TICKERREGFEE);
Expand All @@ -605,8 +620,8 @@ contract SecurityTokenRegistry is EternalStorage, Proxy {
}

/**
* @notice Sets the ticker registration fee in POLY tokens. Only Polymath.
* @param _stLaunchFee is the registration fee in POLY tokens (base 18 decimals)
* @notice Sets the ticker registration fee in USD tokens. Only Polymath.
* @param _stLaunchFee is the registration fee in USD tokens (base 18 decimals)
*/
function changeSecurityLaunchFee(uint256 _stLaunchFee) external onlyOwner {
uint256 fee = getUintValue(STLAUNCHFEE);
Expand Down
23 changes: 11 additions & 12 deletions contracts/interfaces/IModuleFactory.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@ pragma solidity ^0.5.0;
* @title Interface that every module factory contract should implement
*/
interface IModuleFactory {
event ChangeFactorySetupFee(uint256 _oldSetupCost, uint256 _newSetupCost, address _moduleFactory);
event ChangeFactoryUsageFee(uint256 _oldUsageCost, uint256 _newUsageCost, address _moduleFactory);
event ChangeFactorySubscriptionFee(uint256 _oldSubscriptionCost, uint256 _newMonthlySubscriptionCost, address _moduleFactory);
event ChangeSetupCost(uint256 _oldSetupCost, uint256 _newSetupCost);
event ChangeUsageCost(uint256 _oldUsageCost, uint256 _newUsageCost);
event GenerateModuleFromFactory(
address _module,
bytes32 indexed _moduleName,
address indexed _moduleFactory,
address _creator,
uint256 _setupCost,
uint256 _setupCostInPoly,
uint256 _timestamp
);
event ChangeSTVersionBound(string _boundType, uint8 _major, uint8 _minor, uint8 _patch);
Expand Down Expand Up @@ -44,19 +44,13 @@ interface IModuleFactory {
* @notice Used to change the setup fee
* @param _newSetupCost New setup fee
*/
function changeFactorySetupFee(uint256 _newSetupCost) external;
function changeSetupCost(uint256 _newSetupCost) external;

/**
* @notice Used to change the usage fee
* @param _newUsageCost New usage fee
*/
function changeFactoryUsageFee(uint256 _newUsageCost) external;

/**
* @notice Used to change the subscription fee
* @param _newSubscriptionCost New subscription fee
*/
function changeFactorySubscriptionFee(uint256 _newSubscriptionCost) external;
function changeUsageCost(uint256 _newUsageCost) external;

/**
* @notice Function use to change the lower and upper bound of the compatible version st
Expand All @@ -66,10 +60,15 @@ interface IModuleFactory {
function changeSTVersionBounds(string calldata _boundType, uint8[] calldata _newVersion) external;

/**
* @notice Get the setup cost of the module
* @notice Get the setup cost of the module in USD
*/
function getSetupCost() external view returns(uint256);

/**
* @notice Get the setup cost of the module
*/
function getSetupCostInPoly() external view returns (uint256);

/**
* @notice Used to get the lower bound
* @return Lower bound
Expand Down
19 changes: 10 additions & 9 deletions contracts/mocks/MockBurnFactory.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,20 @@ import "../modules/Experimental/Burn/TrackedRedemptionFactory.sol";
*/

contract MockBurnFactory is TrackedRedemptionFactory {

/**
* @notice Constructor
* @param _setupCost Setup cost of the module
* @param _usageCost Usage cost of the module
* @param _subscriptionCost Subscription cost of the module
* @param _polymathRegistry Address of the Polymath Registry
*/
constructor(
uint256 _setupCost,
uint256 _usageCost,
uint256 _subscriptionCost
)
public
TrackedRedemptionFactory(_setupCost, _usageCost, _subscriptionCost)
address _polymathRegistry
)
public
TrackedRedemptionFactory(_setupCost, _usageCost, _polymathRegistry)
{

}
Expand All @@ -31,15 +32,15 @@ contract MockBurnFactory is TrackedRedemptionFactory {
*/
function deploy(
bytes calldata /*_data*/
)
external
returns(address)
)
external
returns(address)
{
address polyToken = _takeFee();
//Check valid bytes - can only call module init function
MockRedemptionManager mockRedemptionManager = new MockRedemptionManager(msg.sender, polyToken);
/*solium-disable-next-line security/no-block-members*/
emit GenerateModuleFromFactory(address(mockRedemptionManager), getName(), address(this), msg.sender, setupCost, now);
emit GenerateModuleFromFactory(address(mockRedemptionManager), getName(), address(this), msg.sender, getSetupCost(), getSetupCostInPoly(), now);
return address(mockRedemptionManager);
}

Expand Down
12 changes: 6 additions & 6 deletions contracts/mocks/MockFactory.sol
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,17 @@ contract MockFactory is DummySTOFactory {
* @notice Constructor
* @param _setupCost Setup cost of the module
* @param _usageCost Usage cost of the module
* @param _subscriptionCost Subscription cost of the module
* @param _logicContract Contract address that contains the logic related to `description`
* @param _polymathRegistry Address of the Polymath Registry
*/
constructor(
uint256 _setupCost,
uint256 _usageCost,
uint256 _subscriptionCost,
address _logicContract
)
public
DummySTOFactory(_setupCost, _usageCost, _subscriptionCost, _logicContract)
address _logicContract,
address _polymathRegistry
)
public
DummySTOFactory(_setupCost, _usageCost, _logicContract, _polymathRegistry)
{
}

Expand Down
10 changes: 5 additions & 5 deletions contracts/mocks/MockWrongTypeFactory.sol
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,15 @@ contract MockWrongTypeFactory is MockBurnFactory {
* @notice Constructor
* @param _setupCost Setup cost of the module
* @param _usageCost Usage cost of the module
* @param _subscriptionCost Subscription cost of the module
* @param _polymathRegistry Address of the Polymath Registry
*/
constructor(
uint256 _setupCost,
uint256 _usageCost,
uint256 _subscriptionCost
)
public
MockBurnFactory(_setupCost, _usageCost, _subscriptionCost)
address _polymathRegistry
)
public
MockBurnFactory(_setupCost, _usageCost, _polymathRegistry)
{

}
Expand Down
12 changes: 6 additions & 6 deletions contracts/mocks/TestSTOFactory.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,17 @@ contract TestSTOFactory is DummySTOFactory {
* @notice Constructor
* @param _setupCost Setup cost of the module
* @param _usageCost Usage cost of the module
* @param _subscriptionCost Subscription cost of the module
* @param _logicContract Contract address that contains the logic related to `description`
* @param _polymathRegistry Address of the Polymath Registry
*/
constructor(
uint256 _setupCost,
uint256 _usageCost,
uint256 _subscriptionCost,
address _logicContract
)
public
DummySTOFactory(_setupCost, _usageCost, _subscriptionCost, _logicContract)
address _logicContract,
address _polymathRegistry
)
public
DummySTOFactory(_setupCost, _usageCost, _logicContract, _polymathRegistry)
{
version = "1.0.0";
name = "TestSTO";
Expand Down
10 changes: 5 additions & 5 deletions contracts/modules/Checkpoint/ERC20DividendCheckpointFactory.sol
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,17 @@ contract ERC20DividendCheckpointFactory is ModuleFactory {
* @notice Constructor
* @param _setupCost Setup cost of the module
* @param _usageCost Usage cost of the module
* @param _subscriptionCost Subscription cost of the module
* @param _logicContract Contract address that contains the logic related to `description`
* @param _polymathRegistry Address of the Polymath registry
*/
constructor(
uint256 _setupCost,
uint256 _usageCost,
uint256 _subscriptionCost,
address _logicContract
address _logicContract,
address _polymathRegistry
)
public
ModuleFactory(_setupCost, _usageCost, _subscriptionCost)
ModuleFactory(_setupCost, _usageCost, _polymathRegistry)
{
require(_logicContract != address(0), "Invalid logic contract");
version = "2.1.0";
Expand All @@ -51,7 +51,7 @@ contract ERC20DividendCheckpointFactory is ModuleFactory {
(success, ) = erc20DividendCheckpoint.call(_data);
require(success, "Unsuccessful call");
/*solium-disable-next-line security/no-block-members*/
emit GenerateModuleFromFactory(erc20DividendCheckpoint, getName(), address(this), msg.sender, setupCost, now);
emit GenerateModuleFromFactory(erc20DividendCheckpoint, getName(), address(this), msg.sender, getSetupCost(), getSetupCostInPoly(), now);
return erc20DividendCheckpoint;
}

Expand Down
Loading