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 3 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
20 changes: 20 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,19 @@ interface ISecurityToken {
uint256 _budget
) external;

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

/**
* @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 controllerTransfer(address _from, address _to, uint256 _value, bytes _data) external returns(bool);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's rename it to forceTransfer as it is a bit more evident what this does.


}
66 changes: 66 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 controllerFrozen;

// 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 LogControllerTransfer(address indexed _controller, address indexed _from, address indexed _to, uint256 _amount, bytes _data);
event LogFreezeController(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(!controllerFrozen);
_;
}

/**
* @notice Constructor
* @param _name Name of the SecurityToken
Expand Down Expand Up @@ -721,4 +741,50 @@ 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(!controllerFrozen);
emit LogSetController(controller, _controller);
controller = _controller;
}

/**
* @notice Permanently freeze controller functionality of this security token.
*/
function freezeController() external isEnabled("freezeControllerAllowed") onlyOwner {
pabloruiz55 marked this conversation as resolved.
Show resolved Hide resolved
require(!controllerFrozen);
controllerFrozen = true;
delete controller;
emit LogFreezeController(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 controllerTransfer(address _from, address _to, uint256 _value, bytes _data) public onlyController returns(bool) {
require(_value <= balances[_from]);
require(_to != address(0));

_adjustInvestorCount(_from, _to, _value);
_adjustBalanceCheckpoints(_from);
_adjustBalanceCheckpoints(_to);

// Consider passing setting to record change in state but not transfer check (could be a part of standard messaging module)
// require(verifyTransfer(_from, _to, _value), "Transfer is not valid");

balances[_from] = balances[_from].sub(_value);
balances[_to] = balances[_to].add(_value);

emit LogControllerTransfer(msg.sender, _from, _to, _value, _data);
emit Transfer(_from, _to, _value);
pabloruiz55 marked this conversation as resolved.
Show resolved Hide resolved
return true;
}

}
Loading