Skip to content
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

Forced Transfer #253

Merged
merged 6 commits into from
Sep 16, 2018
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
1 change: 1 addition & 0 deletions contracts/FeatureRegistry.sol
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ contract FeatureRegistry is IFeatureRegistry, ReclaimTokens {

/**
* @notice change a feature status
* @dev feature status is set to false by default
* @param _nameKey is the key for the feature status mapping
* @param _newStatus is the new feature status
*/
Expand Down
25 changes: 25 additions & 0 deletions contracts/interfaces/ISecurityToken.sol
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,11 @@ interface ISecurityToken {
*/
function freezeMinting() external;

/**
* @notice Permanently freeze controller functionality of this security token.
*/
function freezeController() external;

/**
* @notice mints new tokens and assigns them to the target investors.
* Can only be called by the STO attached to the token or by the Issuer (Security Token contract owner)
Expand Down Expand Up @@ -196,4 +201,24 @@ interface ISecurityToken {
uint256 _budget
) external;

/**
* @notice Use by the issuer to set the controller addresses
* @param _controller address of the controller
*/
function setController(address _controller) external;

/**
* @notice Use by a controller to execute a forced transfer
* @param _from address from which to take tokens
* @param _to address where to send tokens
* @param _value amount of tokens to transfer
* @param _data data attached to the transfer by controller to emit in event
*/
function forceTransfer(address _from, address _to, uint256 _value, bytes _data) external returns(bool);

/**
* @notice Use by the issuer to permanently disable controller functionality
* @dev enabled via feature switch "disableControllerAllowed"
*/
function disableController() external;
}
65 changes: 65 additions & 0 deletions contracts/tokens/SecurityToken.sol
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,12 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr
// Use to permanently halt all minting
bool public mintingFrozen;

// Use to permanently halt controller actions
bool public controllerDisabled;

// address whitelisted by issuer as controller
address public controller;

struct ModuleData {
bytes32 name;
address moduleAddress;
Expand Down Expand Up @@ -110,6 +116,11 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr
event Minted(address indexed to, uint256 amount);
event Burnt(address indexed _burner, uint256 _value);

// Events to log controller actions
event LogSetController(address indexed _oldController, address indexed _newController);
event LogForceTransfer(address indexed _controller, address indexed _from, address indexed _to, uint256 _amount, bool _verifyTransfer, bytes _data);
event LogDisableController(uint256 _timestamp);

// Require msg.sender to be the specified module type
modifier onlyModule(uint8 _moduleType) {
bool isModuleType = false;
Expand Down Expand Up @@ -145,6 +156,15 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr
_;
}

/**
* @notice Revert if called by account which is not a controller
*/
modifier onlyController() {
require(msg.sender == controller);
require(!controllerDisabled);
_;
}

/**
* @notice Constructor
* @param _name Name of the SecurityToken
Expand Down Expand Up @@ -174,6 +194,7 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr
transferFunctions[bytes4(keccak256("transferFrom(address,address,uint256)"))] = true;
transferFunctions[bytes4(keccak256("mint(address,uint256)"))] = true;
transferFunctions[bytes4(keccak256("burn(uint256)"))] = true;
transferFunctions[bytes4(keccak256("forceTransfer(address,address,uint256,bytes)"))] = true;
}

/**
Expand Down Expand Up @@ -721,4 +742,48 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr
return _getValueAt(checkpointBalances[_investor], _checkpointId, balanceOf(_investor));
}

/**
* @notice Use by the issuer ot set the controller addresses
* @param _controller address of the controller
*/
function setController(address _controller) public onlyOwner {
require(!controllerDisabled);
emit LogSetController(controller, _controller);
controller = _controller;
}

/**
* @notice Use by the issuer to permanently disable controller functionality
* @dev enabled via feature switch "disableControllerAllowed"
*/
function disableController() external isEnabled("disableControllerAllowed") onlyOwner {
require(!controllerDisabled);
controllerDisabled = true;
delete controller;
emit LogDisableController(now);
}

/**
* @notice Use by a controller to execute a foced transfer
* @param _from address from which to take tokens
* @param _to address where to send tokens
* @param _value amount of tokens to transfer
* @param _data data attached to the transfer by controller to emit in event
*/
function forceTransfer(address _from, address _to, uint256 _value, bytes _data) public onlyController returns(bool) {
_adjustInvestorCount(_from, _to, _value);
bool verified = verifyTransfer(_from, _to, _value);
_adjustBalanceCheckpoints(_from);
_adjustBalanceCheckpoints(_to);

require(_to != address(0));
require(_value <= balances[_from]);
balances[_from] = balances[_from].sub(_value);
balances[_to] = balances[_to].add(_value);

emit LogForceTransfer(msg.sender, _from, _to, _value, verified, _data);
emit Transfer(_from, _to, _value);
return true;
}

}
Loading