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

Add off-chain signing ability #84

Merged
merged 8 commits into from
Apr 24, 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
4 changes: 2 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,15 @@ All notable changes to this project will be documented in this file.

* IModule contract takes the polyToken contract address as the constructor argument to wrapping all the factories with the polyToken contract address.
* `takeFee()` new function introduced to extract the POLY token from the factory. It only be called by the owner of the factory.

* Added ability for issuer to provide a signed piece of data to allow investors to whitelist themselves.

***

[__0.3.1__](https://www.npmjs.com/package/polymath-core?activeTab=readme) __06-04-18__

## Added
* Add `emit` keyword to emit the events.
* Two new variable is added at the time of registeration of ticker. `swarmHash` represents the off-chain data storage location on IPFS and `owner` It reperesent the ethereum address of the owner.
* Two new variable is added at the time of registration of ticker. `swarmHash` represents the off-chain data storage location on IPFS and `owner` It reperesent the ethereum address of the owner.
* `LogRegisterTicker` emits two more variable called `_swarmHash` and `_owner`.
* Two events are added in `GeneralPermissionManager` contract to facilitate the notifications for the UI end.
__`LogChangePermission`__ :Emit when permissions to a delegate get changed.
Expand Down
4 changes: 2 additions & 2 deletions contracts/Migrations.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@ pragma solidity ^0.4.23;
contract Migrations {

address public owner;

uint public lastCompletedMigration;

modifier restricted() {
require(msg.sender == owner);
_;
}

constructor() public {
function Migrations() public {
owner = msg.sender;
}

Expand Down
10 changes: 5 additions & 5 deletions contracts/interfaces/IModule.sol
Original file line number Diff line number Diff line change
Expand Up @@ -27,29 +27,29 @@ contract IModule {
modifier withPerm(bytes32 _perm) {
bool isOwner = msg.sender == ISecurityToken(securityToken).owner();
bool isFactory = msg.sender == factory;
require(isOwner||isFactory||ISecurityToken(securityToken).checkPermission(msg.sender, address(this), _perm));
require(isOwner||isFactory||ISecurityToken(securityToken).checkPermission(msg.sender, address(this), _perm), "Permission check failed");
_;
}

modifier onlyOwner {
require(msg.sender == ISecurityToken(securityToken).owner());
require(msg.sender == ISecurityToken(securityToken).owner(), "Sender is not owner");
_;
}

modifier onlyFactory {
require(msg.sender == factory);
require(msg.sender == factory, "Sender is not factory");
_;
}

modifier onlyFactoryOwner {
require(msg.sender == IModuleFactory(factory).owner());
require(msg.sender == IModuleFactory(factory).owner(), "Sender is not factory owner");
_;
}

function getPermissions() public view returns(bytes32[]);

function takeFee(uint256 _amount) public withPerm(FEE_ADMIN) returns(bool) {
require(polyToken.transferFrom(address(this), IModuleFactory(factory).owner(), _amount));
require(polyToken.transferFrom(address(this), IModuleFactory(factory).owner(), _amount), "Unable to take fee");
return true;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ contract GeneralPermissionManager is IPermissionManager {
withPerm(CHANGE_PERMISSION)
returns(bool)
{
require(delegateDetails[_delegate] != bytes32(0));
require(delegateDetails[_delegate] != bytes32(0), "Delegate details not set");
perms[_module][_delegate][_perm] = _valid;
emit LogChangePermission(_delegate, _module, _perm, _valid, now);
return true;
Expand Down
41 changes: 39 additions & 2 deletions contracts/modules/TransferManager/GeneralTransferManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ contract GeneralTransferManager is ITransferManager {
//Address from which issuances come
address public issuanceAddress = address(0);

//Address which can sign whitelist changes
address public signingAddress = address(0);

bytes32 public constant WHITELIST = "WHITELIST";
bytes32 public constant FLAGS = "FLAGS";

Expand All @@ -42,6 +45,7 @@ contract GeneralTransferManager is ITransferManager {
event LogAllowAllTransfers(bool _allowAllTransfers);
event LogAllowAllWhitelistTransfers(bool _allowAllWhitelistTransfers);
event LogAllowAllWhitelistIssuances(bool _allowAllWhitelistIssuances);
event LogChangeSigningAddress(address _signingAddress);

event LogModifyWhitelist(
address _investor,
Expand All @@ -66,6 +70,11 @@ contract GeneralTransferManager is ITransferManager {
emit LogChangeIssuanceAddress(_issuanceAddress);
}

function changeSigningAddress(address _signingAddress) public withPerm(FLAGS) {
signingAddress = _signingAddress;
emit LogChangeSigningAddress(_signingAddress);
}

function changeAllowAllTransfers(bool _allowAllTransfers) public withPerm(FLAGS) {
allowAllTransfers = _allowAllTransfers;
emit LogAllowAllTransfers(_allowAllTransfers);
Expand Down Expand Up @@ -123,13 +132,41 @@ contract GeneralTransferManager is ITransferManager {
uint256[] _fromTimes,
uint256[] _toTimes
) public withPerm(WHITELIST) {
require(_investors.length == _fromTimes.length);
require(_fromTimes.length == _toTimes.length);
require(_investors.length == _fromTimes.length, "Mismatched input lengths");
require(_fromTimes.length == _toTimes.length, "Mismatched input lengths");
for (uint256 i = 0; i < _investors.length; i++) {
modifyWhitelist(_investors[i], _fromTimes[i], _toTimes[i]);
}
}

/**
* @dev adds or removes addresses from the whitelist - can be called by anyone with a valid signature
* @param _investor is the address to whitelist
* @param _fromTime is the moment when the sale lockup period ends and the investor can freely sell his tokens
* @param _toTime is the moment when the purchase lockup period ends and the investor can freely purchase tokens from others
* @param _validFrom is the time that this signature is valid from
* @param _validTo is the time that this signature is valid until
* @param _v issuer signature
* @param _r issuer signature
* @param _s issuer signature
*/
function modifyWhitelistSigned(address _investor, uint256 _fromTime, uint256 _toTime, uint256 _validFrom, uint256 _validTo, uint8 _v, bytes32 _r, bytes32 _s) public {
require(_validFrom <= now, "ValidFrom is too early");
require(_validTo >= now, "ValidTo is too late");
bytes32 hash = keccak256(this, _investor, _fromTime, _toTime, _validFrom, _validTo);
checkSig(hash, _v, _r, _s);
//Passing a _time == 0 into this function, is equivalent to removing the _investor from the whitelist
whitelist[_investor] = TimeRestriction(_fromTime, _toTime);
emit LogModifyWhitelist(_investor, now, msg.sender, _fromTime, _toTime);
}

function checkSig(bytes32 _hash, uint8 _v, bytes32 _r, bytes32 _s) internal view {
//Check that the signature is valid
//sig should be signing - _investor, _fromTime & _toTime and be signed by the issuer address
address signer = ecrecover(keccak256("\x19Ethereum Signed Message:\n32", _hash), _v, _r, _s);
require(signer == ISecurityToken(securityToken).owner() || signer == signingAddress, "Incorrect signer");
}

function getPermissions() public view returns(bytes32[]) {
bytes32[] memory allPermissions = new bytes32[](2);
allPermissions[0] = WHITELIST;
Expand Down
10 changes: 5 additions & 5 deletions contracts/tokens/SecurityToken.sol
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,9 @@ contract SecurityToken is ISecurityToken, StandardToken, DetailedERC20 {
isModuleType = isModuleType || (modules[_moduleType][i].moduleAddress == msg.sender);
}
if (_fallback && !isModuleType) {
require(msg.sender == owner);
require(msg.sender == owner, "Sender is not owner");
} else {
require(isModuleType);
require(isModuleType, "Sender is not correct module type");
}
_;
}
Expand Down Expand Up @@ -200,9 +200,9 @@ contract SecurityToken is ISecurityToken, StandardToken, DetailedERC20 {
* @dev allows owner to approve more POLY to one of the modules
*/
function changeModuleBudget(uint8 _moduleType, uint8 _moduleIndex, uint256 _budget) public onlyOwner {
require(_moduleType != 0);
require(_moduleIndex < modules[_moduleType].length);
require(polyToken.approve(modules[_moduleType][_moduleIndex].moduleAddress, _budget));
require(_moduleType != 0, "Module type cannot be zero");
require(_moduleIndex < modules[_moduleType].length, "Incorrrect module index");
require(polyToken.approve(modules[_moduleType][_moduleIndex].moduleAddress, _budget), "Insufficient balance to approve");
emit LogModuleBudgetChanged(_moduleType, modules[_moduleType][_moduleIndex].moduleAddress, _budget);
}

Expand Down
74 changes: 67 additions & 7 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
"babel-preset-stage-3": "6.24.1",
"babel-register": "6.26.0",
"bignumber.js": "^6.0.0",
"ethers": "^3.0.15",
"readline-sync": "^1.4.9",
"truffle-contract": "^3.0.4",
"truffle-hdwallet-provider-privkey": "^0.1.0",
Expand All @@ -68,7 +69,7 @@
"ganache-cli": "^6.1.0",
"sol-merger": "^0.1.2",
"solium": "^1.1.6",
"truffle": "^4.1.5",
"truffle": "^4.1.7",
"truffle-wallet-provider": "0.0.5"
}
}
Loading