-
Notifications
You must be signed in to change notification settings - Fork 160
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
Single Trade Volume Restriction #262
Closed
subramanianv
wants to merge
36
commits into
PolymathNetwork:development-1.5.0
from
subramanianv:singleTradeVolumeRestriction
Closed
Changes from 4 commits
Commits
Show all changes
36 commits
Select commit
Hold shift + click to select a range
a48ae40
Initial Setup
subramanianv 90c9c54
deploy function
subramanianv 62f4d6c
Implement VerfyTransfer Function and also Permissions
subramanianv b1e882a
Fix lookup errors
subramanianv f6b9c7a
Single Trade Volume Tests WIP
subramanianv c7f5012
Complete tests
subramanianv 939d0c0
Update comments
subramanianv 5f5f416
Merge branch 'development-1.5.0' of https://github.com/PolymathNetwor…
subramanianv 4e1010f
change implementation according to development-1.5 branch
subramanianv c87b5c2
Tests refactored
subramanianv 889db0e
Added multi functions
subramanianv f399728
added comments for singletradevolumeRestrictionFactory
subramanianv 74fe6ed
Add token info script
adamdossa bb2d279
Merge pull request #282 from PolymathNetwork/token-info-script
pabloruiz55 a233e46
Added more tests
subramanianv 2f2b19d
More tests
subramanianv 6738b00
Changes from the review and more tests
subramanianv 8aa2560
More tests
subramanianv 47c82fd
More tests
subramanianv 1814326
Merge branch 'development-1.5.0' of https://github.com/PolymathNetwor…
subramanianv d823228
Changes after the merge
subramanianv 7a56664
Changes from the review
subramanianv 1e46254
Merge https://github.com/PolymathNetwork/polymath-core into singleTra…
subramanianv 8c344e3
Merge branch 'development-1.5.0' of https://github.com/PolymathNetwor…
subramanianv 6b328dc
Add tests
subramanianv 477a858
Merge branch 'development-1.5.0' of https://github.com/PolymathNetwor…
subramanianv 09015da
Changes from the review
subramanianv c6722fd
Deleted tokeninfo.js
subramanianv b2c717d
Merge branch 'development-1.5.0' into singleTradeVolumeRestriction
adamdossa 9da57ab
Update 2_deploy_contracts.js
adamdossa d30f0fb
Merge branch 'development-1.5.0' into singleTradeVolumeRestriction
pabloruiz55 77b3410
Update SingleTradeVolumeRestrictionManager.sol
adamdossa 786d705
Update 2_deploy_contracts.js
adamdossa 149f56d
Update w_single_trade_volume_restriction.js
adamdossa 28c3315
minor fixes
SatyamSB 61f268d
Merge branch 'development-1.5.0' into singleTradeVolumeRestriction
adamdossa File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
111 changes: 111 additions & 0 deletions
111
contracts/modules/TransferManager/SingleTradeVolumeRestrictionManager.sol
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
pragma solidity ^0.4.24; | ||
import "./ITransferManager.sol"; | ||
|
||
///////////////////// | ||
// Module permissions | ||
///////////////////// | ||
// Owner ADMIN | ||
// changeGlobalLimit X X | ||
// addExemptWallet X X | ||
// removeExemptWallet X X | ||
// setTransferLimitForWallet X X | ||
// removeTransferLimitForWallet X X | ||
|
||
contract SingleTradeVolumeRestrictionManager is ITransferManager { | ||
using SafeMath for uint256; | ||
|
||
bool public globalTransferLimitInPercentage; | ||
|
||
uint256 public globalTransferLimit; | ||
|
||
mapping(address=>bool) public exemptWallets; | ||
|
||
mapping(address => bool) public specialTransferLimitWallets; | ||
|
||
mapping(address => uint) public specialTransferLimits; | ||
|
||
bytes32 constant public ADMIN = "ADMIN"; | ||
|
||
constructor(address _securityToken, address _polyAddress) public | ||
IModule(_securityToken, _polyAddress) | ||
{ | ||
|
||
} | ||
|
||
function verifyTransfer(address _from, address _to, uint256 _amount, bool /* _isTransfer */) public returns(Result) { | ||
bool validTransfer; | ||
|
||
if(paused) { | ||
return Result.NA; | ||
} | ||
|
||
if(exemptWallets[_from]) return Result.NA; | ||
|
||
if(specialTransferLimitWallets[_from]) { | ||
if(globalTransferLimitInPercentage) { | ||
validTransfer = (_amount.mul(100).div(ISecurityToken(securityToken).totalSupply())) <= specialTransferLimits[_from]; | ||
} else { | ||
validTransfer = _amount <= specialTransferLimits[_from]; | ||
} | ||
} else { | ||
if(globalTransferLimitInPercentage) { | ||
validTransfer = (_amount.mul(100).div(ISecurityToken(securityToken).totalSupply())) <= globalTransferLimit; | ||
} else { | ||
validTransfer = _amount <= globalTransferLimit; | ||
} | ||
} | ||
|
||
if(validTransfer) return Result.NA; | ||
return Result.INVALID; | ||
} | ||
|
||
function configure(bool _globalTransferLimitInPercentage, uint256 _globalTransferLimit) public onlyFactory { | ||
globalTransferLimitInPercentage = _globalTransferLimitInPercentage; | ||
changeGlobalLimit(_globalTransferLimit); | ||
} | ||
|
||
function changeGlobalLimit(uint256 _newGlobalTransferLimit) public withPerm(ADMIN) { | ||
if(globalTransferLimitInPercentage) { | ||
require(_newGlobalTransferLimit <= 100); | ||
} | ||
globalTransferLimit = _newGlobalTransferLimit; | ||
} | ||
|
||
function addExemptWallet(address _walletAddress) public withPerm(ADMIN) { | ||
require(_walletAddress != address(0)); | ||
exemptWallets[_walletAddress] = true; | ||
} | ||
|
||
function removeExemptWallet(address _walletAddress) public withPerm(ADMIN) { | ||
require(_walletAddress != address(0)); | ||
exemptWallets[_walletAddress] = false; | ||
} | ||
|
||
function setTransferLimitForWallet(address _walletAddress, uint _transferLimit) public withPerm(ADMIN) { | ||
if(globalTransferLimitInPercentage) { | ||
require(_transferLimit <= 100); | ||
} | ||
specialTransferLimitWallets[_walletAddress] = true; | ||
specialTransferLimits[_walletAddress] = _transferLimit; | ||
} | ||
|
||
function removeTransferLimitForWallet(address _walletAddress) public withPerm(ADMIN) { | ||
require(specialTransferLimitWallets[_walletAddress]); | ||
specialTransferLimitWallets[_walletAddress] = false; | ||
specialTransferLimits[_walletAddress] = 0; | ||
} | ||
|
||
/** | ||
* @notice This function returns the signature of configure function | ||
*/ | ||
function getInitFunction() public pure returns (bytes4) { | ||
return bytes4(keccak256("configure(bool, uint256)")); | ||
} | ||
|
||
// TO IMPLEMENT | ||
function getPermissions() public view returns(bytes32[]) { | ||
bytes32[] memory allPermissions = new bytes32[](1); | ||
allPermissions[0] = ADMIN; | ||
return allPermissions; | ||
} | ||
} |
80 changes: 80 additions & 0 deletions
80
contracts/modules/TransferManager/SingleTradeVolumeRestrictionManagerFactory.sol
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
pragma solidity ^0.4.24; | ||
|
||
import "../../interfaces/IModuleFactory.sol"; | ||
import "./SingleTradeVolumeRestrictionManager.sol"; | ||
contract SingleTradeVolumeRestrictionFactory is IModuleFactory { | ||
|
||
/** | ||
* @notice Constructor | ||
* @param _polyAddress Address of the polytoken | ||
* @param _setupCost Setup cost of the module | ||
* @param _usageCost Usage cost of the module | ||
* @param _subscriptionCost Subscription cost of the module | ||
*/ | ||
constructor(address _polyAddress, uint256 _setupCost, uint256 _usageCost, uint256 _subscriptionCost) public | ||
IModuleFactory(_polyAddress, _setupCost, _usageCost, _subscriptionCost) | ||
{ | ||
|
||
} | ||
|
||
/** | ||
* @notice used to launch the Module with the help of factory | ||
* @return address Contract address of the Module | ||
*/ | ||
function deploy(bytes _data) external returns(address) { | ||
if (setupCost > 0) | ||
require(polyToken.transferFrom(msg.sender, owner, setupCost), "Failed transferFrom because of sufficent Allowance is not provided"); | ||
SingleTradeVolumeRestrictionManager singleTradeVolumeRestrictionManager = new SingleTradeVolumeRestrictionManager(msg.sender, address(polyToken)); | ||
require(getSig(_data) == singleTradeVolumeRestrictionManager.getInitFunction(), "Provided data is not valid"); | ||
require(address(singleTradeVolumeRestrictionManager).call(_data), "Un-successfull call"); | ||
emit LogGenerateModuleFromFactory(address(singleTradeVolumeRestrictionManager), getName(), address(this), msg.sender, now); | ||
return address(singleTradeVolumeRestrictionManager); | ||
} | ||
|
||
/** | ||
* @notice Type of the Module factory | ||
*/ | ||
function getType() public view returns(uint8) { | ||
return 2; | ||
} | ||
|
||
/** | ||
* @notice Get the name of the Module | ||
*/ | ||
function getName() public view returns(bytes32) { | ||
return "SingleTradeVolumeRestriction"; | ||
} | ||
|
||
/** | ||
* @notice Get the description of the Module | ||
*/ | ||
function getDescription() public view returns(string) { | ||
return "Imposes volume restriction on a single trade"; | ||
} | ||
|
||
/** | ||
* @notice Get the title of the Module | ||
*/ | ||
function getTitle() public view returns(string) { | ||
return "Single Trade Volume Restriction"; | ||
} | ||
|
||
/** | ||
* @notice Get the Instructions that help to use the module | ||
*/ | ||
function getInstructions() public view returns(string) { | ||
return "Allows an issuer to impose volume restriction on a single trade"; | ||
} | ||
|
||
/** | ||
* @notice Get the tags related to the module factory | ||
*/ | ||
function getTags() public view returns(bytes32[]) { | ||
bytes32[] memory availableTags = new bytes32[](3); | ||
availableTags[0] = "Single Trade"; | ||
availableTags[1] = "Transfer"; | ||
availableTags[2] = "Volume"; | ||
return availableTags; | ||
} | ||
|
||
} |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Error in the calculation. You are giving the margin of 0.9 %. Suppose if the left size has the 15.7% and right side have the 15 % value then it still gets
true
instead offalse
.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@satyamakgec I don't fully understand your comment. Is your comment because of this warning from the solidity docs ?
Division on integer literals used to truncate in earlier versions, but it will now convert into a rational number, i.e. 5 / 2 is not equal to 2, but to 2.5.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also From PercentageTransferManager
if(newBalance.mul(10**uint256(ISecurityToken(securityToken).decimals())).div(ISecurityToken(securityToken).totalSupply()) > maxHolderPercentage) { return Result.INVALID; }
Shouldn't newBalance be multipled by 10^18 explicitly instead of 10^decimals as maxHolderPercentage is multipled by (10^18/100) ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think so because by default securitytoken have 18 decimals so in case of
PercentageTransferManager
it always give you the value right percentage calculation.But in your case you are doing this
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@satyamakgec Thanks for the reply. The first case, which I haven't implemented is missing a multiplication by 10^18. it should be
(a* 10^d * 10^18)/(b* 10^d) <= c* 10^16
. I will implement this formula/calculation.In the
PercentageTransferManager
- the math should be (x* 10^d * 10^18) / y* 10^d > (z * 10^18)/100. The multiplication should be explicitly done by 10^18. I think this would work for security token of any decimals, not just tokens with 18 decimals