Polymath
master
master
  • README
  • api
    • Proxy (Proxy.sol)
    • Base abstract contract to be extended by all STO modules (STO.sol)
    • OwnedUpgradeabilityProxy (OwnedUpgradeabilityProxy.sol)
    • Transfer Manager module for core transfer validation functionality (GeneralTransferManager.sol)
    • VotingCheckpointStorage.sol
    • PLCRVotingCheckpoint.sol
    • Factory for deploying VestingEscrowWallet module (VestingEscrowWalletFactory.sol)
    • Helper library use to compare or validate the semantic versions (VersionUtils.sol)
    • Interface to be implemented by all Wallet modules (Wallet.sol)
    • Factory for deploying CappedSTO module (CappedSTOFactory.sol)
    • Checkpoint module for issuing ERC20 dividends (ERC20DividendCheckpoint.sol)
    • Interface to be implemented by all Transfer Manager modules (ITransferManager.sol)
    • StableOracle.sol
    • VolumeRestrictionTM.sol
    • SecurityTokenRegistryProxy (SecurityTokenRegistryProxy.sol)
    • PreSaleSTO module Proxy (PreSaleSTOProxy.sol)
    • DataStoreProxy Proxy (DataStoreProxy.sol)
    • Proxy for deploying SecurityToken instances (STFactory.sol)
    • Ownable (IOwnable.sol)
    • Checkpoint module for issuing ether dividends (DividendCheckpoint.sol)
    • CountTransferManager module Proxy (BlacklistTransferManagerProxy.sol)
    • Security Token contract (mock) (MockSTGetter.sol)
    • Permission Manager module for core permissioning functionality (GeneralPermissionManager.sol)
    • Contract used to store layout for the CountTransferManager storage (CountTransferManagerStorage.sol)
    • DummySTO module Proxy (DummySTOProxy.sol)
    • Transfer Manager module for limiting percentage of token supply a single address can hold (Percentag
    • Helps contracts guard against reentrancy attacks. (ReentrancyGuard.sol)
    • Factory for deploying EtherDividendCheckpoint module (ScheduledCheckpointFactory.sol)
    • Interface that every module factory contract should implement (IModuleFactory.sol)
    • Factory for deploying GeneralTransferManager module (TrackedRedemptionFactory.sol)
    • SafeMath (SafeMath.sol)
    • USDTiered STO module Proxy (SecurityTokenProxy.sol)
    • USDTiered STO module Proxy (USDTieredSTOProxy.sol)
    • IOracle.sol
    • ManualApprovalTransferManager module Proxy (ManualApprovalTransferManagerProxy.sol)
    • Interface to be implemented by all permission manager modules (IPermissionManager.sol)
    • Factory for deploying PreSaleSTO module (PreSaleSTOFactory.sol)
    • MockPolyOracle.sol
    • Transfer Manager module for verifing transations with a signed message (SignedTransferManager.sol)
    • DataStoreFactory.sol
    • OraclizeAddrResolverI.sol
    • PolyTokenFaucet.sol
    • Registry contract for issuers to register their security tokens (MockModuleRegistry.sol)
    • VolumeRestrictionLib.sol
    • Contract used to store layout for the PercentageTransferManager storage (PercentageTransferManagerSt
    • Transfer Manager for limiting maximum number of token holders (CountTransferManager.sol)
    • ModuleRegistryProxy (ModuleRegistryProxy.sol)
    • Voting module for governance (WeightedVoteCheckpointProxy.sol)
    • Factory for deploying BlacklistTransferManager module (BlacklistTransferManagerFactory.sol)
    • Contract used to store layout for the GeneralPermissionManager storage (GeneralPermissionManagerStor
    • CountTransferManager module Proxy (LockUpTransferManagerProxy.sol)
    • Holds the storage variable for the DividendCheckpoint modules (i.e ERC20, Ether) (DividendCheckpoint
    • Factory for deploying DummySTO module (DummySTOFactory.sol)
    • IERC1644.sol
    • Core functionality for registry upgradability (PolymathRegistry.sol)
    • Utility contract to allow owner to retreive any ERC20 sent to the contract (ReclaimTokens.sol)
    • SecurityTokenMock.sol
    • Factory for deploying CappedSTO module (USDTieredSTOFactory.sol)
    • Factory for deploying ManualApprovalTransferManager module (ManualApprovalTransferManagerFactory.sol
    • IERC1643.sol
    • Transfer Manager module for core transfer validation functionality (EtherDividendCheckpointProxy.sol
    • solcChecker.sol
    • It holds the storage variables related to ERC20DividendCheckpoint module (ERC20DividendCheckpointSto
    • Interface for all security tokens (ISecurityToken.sol)
    • Base abstract contract to be implemented by all Transfer Manager modules (TransferManager.sol)
    • Storage layout for VolumeRestrictionTM (VolumeRestrictionTMStorage.sol)
    • Security Token contract (mock) (MockSecurityTokenLogic.sol)
    • Transfer Manager module for core transfer validation functionality (GeneralTransferManagerStorage.so
    • IERC1410.sol
    • VotingCheckpoint.sol
    • Factory for deploying WeightedVoteCheckpoint module (WeightedVoteCheckpointFactory.sol)
    • PLCRVotingCheckpointStorage.sol
    • IDataStore.sol
    • TestSTOFactory.sol
    • Ownable (Ownable.sol)
    • UpgradeabilityProxy (UpgradeabilityProxy.sol)
    • Mock Contract Not fit for production environment (MockFactory.sol)
    • Registry contract for issuers to register their security tokens (SecurityTokenRegistryMock.sol)
    • ICheckPermission.sol
    • Factory for deploying LockUpTransferManager module (LockUpTransferManagerFactory.sol)
    • Storage layout for the STO contract (STOStorage.sol)
    • Interface for the Polymath Security Token Registry contract (ISecurityTokenRegistry.sol)
    • Mock Contract Not fit for production environment (MockWrongTypeFactory.sol)
    • Transfer Manager module for core transfer validation functionality (KYCTransferManager.sol)
    • Factory for deploying EtherDividendCheckpoint module (EtherDividendCheckpointFactory.sol)
    • functionSigClash2.sol
    • Standard Interface of ERC1594 (IERC1594.sol)
    • TokenLib.sol
    • MakerDAOOracle.sol
    • Interface that any module contract should implement (Module.sol)
    • Interface that any module factory contract should implement (ModuleFactory.sol)
    • STGetter.sol
    • Interface to be implemented by upgradable token factories (IUpgradableTokenFactory.sol)
    • ERC20 interface (IERC20.sol)
    • KYCTransferManagerFactory.sol
    • Checkpoint module for issuing ether dividends (EtherDividendCheckpoint.sol)
    • functionSigClash1.sol
    • Wallet for core vesting escrow functionality (VestingEscrowWalletStorage.sol)
    • Interface for managing polymath feature switches (IFeatureRegistry.sol)
    • Encoder.sol
    • STRGetter.sol
    • OraclizeI.sol
    • Contract used to store layout for the CappedSTO storage (CappedSTOStorage.sol)
    • LockUpTransferManager.sol
    • Checkpoint module for token weighted vote (WeightedVoteCheckpoint.sol)
    • Registry contract to store registered modules (ModuleRegistry.sol)
    • Factory for deploying upgradable modules (UpgradableModuleFactory.sol)
    • Utility contract to allow pausing and unpausing of certain functions (Pausable.sol)
    • CountTransferManager module Proxy (CountTransferManagerProxy.sol)
    • Math (Math.sol)
    • IPolymathRegistry.sol
    • MockOracle.sol
    • Transfer Manager module for manually approving transactions between accounts (ManualApprovalTransfer
    • DecimalMath.sol
    • STO module for standard capped crowdsale (USDTieredSTO.sol)
    • Security Token contract (SecurityToken.sol)
    • PercentageTransferManager module Proxy (PercentageTransferManagerProxy.sol)
    • Interface to be implemented by all checkpoint modules (IBurn.sol)
    • Burn module for burning tokens and keeping track of burnt amounts (MockRedemptionManager.sol)
    • GeneralPermissionManager module Proxy (GeneralPermissionManagerProxy.sol)
    • STO module for sample implementation of a different crowdsale module (DummySTO.sol)
    • Factory for deploying CountTransferManager module (CountTransferManagerFactory.sol)
    • Interface to be implemented by all STO modules (ISTO.sol)
    • Data store contract that stores data for all the modules in a central contract. (DataStore.sol)
    • Transfer Manager module to automate blacklist and restrict transfers (BlacklistTransferManager.sol)
    • Contract used to store layout for the PreSaleSTO storage (PreSaleSTOStorage.sol)
    • Migrations.sol
    • Contract used to store layout for the CountTransferManager storage (BlacklistTransferManagerStorage.
    • STO module for private presales (PreSaleSTO.sol)
    • DataStoreStorage.sol
    • Storage layout for the ISTO contract (ISTOStorage.sol)
    • Registry contract for issuers to register their tickers and security tokens (SecurityTokenRegistry.s
    • Factory for deploying SignedTransferManager module (SignedTransferManagerFactory.sol)
    • Transfer Manager module for core transfer validation functionality (ERC20DividendCheckpointProxy.sol
    • Burn module for burning tokens and keeping track of burnt amounts (ScheduledCheckpoint.sol)
    • ERC20 interface (IPoly.sol)
    • Transfer Manager module for core transfer validation functionality (VolumeRestrictionTMProxy.sol)
    • Contract used to store layout for the DummySTO storage (DummySTOStorage.sol)
    • Burn module for burning tokens and keeping track of burnt amounts (TrackedRedemption.sol)
    • Interface that every module contract should implement (IModule.sol)
    • Contract used to store layout for the ManualApprovalTransferManager storage (ManualApprovalTransferM
    • Elliptic curve signature operations (ECDSA.sol)
    • Factory for deploying PercentageTransferManager module (PercentageTransferManagerFactory.sol)
    • Transfer Manager module for core transfer validation functionality (GeneralTransferManagerProxy.sol)
    • Utility contract for reusable code (Util.sol)
    • SecurityTokenStorage.sol
    • Contract used to store layout for the USDTieredSTO storage (USDTieredSTOStorage.sol)
    • Factory for deploying GeneralPermissionManager module (GeneralPermissionManagerFactory.sol)
    • Address.sol
    • StatusCodes.sol
    • Standard ERC20 token
    • Voting module for governance (PLCRVotingCheckpointProxy.sol)
    • CBOR.sol
    • Registry for managing polymath feature switches (FeatureRegistry.sol)
    • WeightedVoteCheckpointStorage.sol
    • Interface for the Polymath Module Registry contract (IModuleRegistry.sol)
    • Interface for security token proxy deployment (ISTFactory.sol)
    • Registry contract for issuers to register their security tokens (MockSTRGetter.sol)
    • Buffer.sol
    • BokkyPooBahsDateTimeLibrary.sol
    • Mock Contract Not fit for production environment (MockBurnFactory.sol)
    • Wallet for core vesting escrow functionality (LockUpTransferManagerStorage.sol)
    • Factory for deploying VolumeRestrictionTM module (VolumeRestrictionTMFactory.sol)
    • usingOraclize.sol
    • STO module for standard capped crowdsale (CappedSTO.sol)
    • Interface to MakerDAO Medianizer contract (IMedianizer.sol)
    • Interface to be implemented by all checkpoint modules (ICheckpoint.sol)
    • Factory for deploying ERC20DividendCheckpoint module (ERC20DividendCheckpointFactory.sol)
    • Factory for deploying GeneralTransferManager module (GeneralTransferManagerFactory.sol)
    • Escrow wallet module for vesting functionality (VestingEscrowWalletProxy.sol)
    • OZStorage.sol
    • Wallet for core vesting escrow functionality (VestingEscrowWallet.sol)
    • EternalStorage.sol
    • Factory for deploying PLCRVotingCheckpoint module (PLCRVotingCheckpointFactory.sol)
    • IVoting.sol
    • Transfer Manager for limiting maximum number of token holders (MockCountTransferManager.sol)
    • CappedSTO module Proxy (CappedSTOProxy.sol)
    • Storage for Module contract (ModuleStorage.sol)
  • wiki
    • Dividend-Module
    • Transfer-manager-results
    • General Permission Manager
    • Transfer-Feature
    • Voting-Checkpoint-Modules
    • USDTieredSTO
    • Contract-Manager
    • Vesting-Escrow-Wallet
    • General Transfer Manager
    • Permission-Manager
    • Dividends-Manager
    • Manual Approval Transfer Manager
    • Transfer-Ownership
    • Transfer-Manager
    • How-to-Use-the-Investor-Portal
    • Count Transfer Manager
    • VolumeRestrictionTransferManager
    • Time-Travel-(Contract-Testing)
    • Percentage Transfer Manager
    • Prerequisite-Instructions-for-Deploying-and-Setting-Up-the-Polymath-Contracts
    • How to Create and Launch an STO
    • Token-Manager
    • How to set up and use the POLY Faucet
    • Advanced PLCR Voting Checkpoint
    • Welcome to the Polymath Core Wiki
    • Capped STO
    • _Sidebar
    • CLI for Polymath-core
    • Lockup Transfer Manager
    • The-STO-Manager
    • Blacklist Transfer Manager (BTM)
  • misc
    • Multiple Transfer Managers
    • PolyOracle Encrypted URL
    • ethereum_status_codes
    • Flags List
    • Permissions List
Powered by GitBook
On this page
  • How it works
  • Key functionalities (as defined in the Smart Contract)
  • Initialization
  • Using the module
  • Transfer Verification
  • First Case :-
  • Second Case :-
  • Third Case :-
  • Fourth Case :-
  • Add Volume restriction
  • Modify Volume Restrictions
  • Remove Volume Restriction
  • Getters
  • Other functions
  • Special considerations / notes
  • Know Issues/bugs

Was this helpful?

  1. wiki

VolumeRestrictionTransferManager

Introduced in

3.0.0

Contract name

VolumeRestrictionTM.sol

Compatible Protocol Version

^3.0.0

Type

Transfer Manager Module

How it works

It is used to restrict the maximum volume of tokens being traded by any individual investor in a given period of time and it also restricts maximum transfers that should be across all the token holders associated. An issuer can also exempt any token holders by adding then into the exemption list to make them unaffected by this module.

Key functionalities (as defined in the Smart Contract)

Initialization

This module is initialized with no parameters. That means during the creation of this contract there’s no need to call any type of configure() function.

Using the module

Layout for the Individual restriction

Note - Below use-case only works when the Alice has only Individual restriction not Individual daily restriction (24 hrs rolling period).

UseCase: Issuer wants to restrict Alice’s transfers as per the volume of tokens. An issuer will do so with the following transaction.

Call the addIndividualRestriction() function with following data.

     address of Alice → 0xabc..
     allowedTokens → 10,000  (If `typeOfRestriction` is `Percentage` then allowedTokens will be in the % (w.r.t to totalSupply) with a multiplier of 10**16 . else it will be fixed amount of tokens with a multiplier of 10 ** 18)
     startTime → now
     rollingPeriodInDays → 5
     endTime → now + 12 days
     restrictionType → 0 . (Fixed restriction)

Now Alice starts trading with the following assumptions.

     Alice’s Address != 0x0 ,      
     paused = false ,     
     exemptionList[0xabc] = false

Day1: Alice tries to sell 1000 tokens

     amount = 1000    
     sumOfLastPeriod = 0    
        10000 >= 1000 + 0  ---- yes transaction processed  sumOfLastPeriod = 1000

Day 2: Alice tries to sell 5000 tokens

      amount = 5000
      sumOfLastPeriod = 1000
           10000 >= 5000 + 1000 . ----- yes tx processed sumOfLastPeriod = 6000

Day 3: No trading

Day 4: No trading

Day 5: Alice tries to sell 6000 tokens

      amount = 6000
      sumOfLastPeriod= 6000 
        10000 >= 6000 + 6000 ---- false tx failed   sumOfLastPeriod = 6000
    --------------- First rolling period ends ------------------

Day 6: Alice tries to sell 3000 tokens

       amount = 3000 
       sumOfLastPeriod = 6000 - 1000(amount sold on day 1) => 5000
           10000 >= 5000 + 3000 ---- true tx processed new sumOfLastPeriod = 8000

Day 7: No trading

Day 8: Alice tries to sell 4000 tokens

       amount = 4000  
       sumOfLastPeriod = 8000 - 5000(amount sold on day 2) - 0 (amount sold on day 3) => 3000 or (Day  4, 5,6,7, 8 trade sum which is 3000).
            10000 >= 4000 + 3000   — yes tx processed   sumOfLastPeriod = 7000
      continues ...

Transfer Verification

  • If _from address is 0x0 or present in the exemption list or paused variable is true then transfers will be unaffected by this module.

  • If _from address has any individual restriction, whether Individual or Individual daily or both. isDefault will be false in _restrictionCheck() function params. Otherwise, it will be true.

  • 4 cases related to _from address

    • _from has Individual Restriction

    • _from has 24 hrs Individual daily restriction

    • _from has both individual restriction and individual daily restriction

    • _from doesn’t have any Individual restriction. It falls into the default restriction. Whatever the default restriction will active that time will apply, whether default or default daily or both.

First Case :-

  • If _from has Individual restriction only & transaction time is between startTime and endTime of the restriction, then transaction will go through only when:

    • _amount is less than or equal to the _allowedAmount - sumOfLastPeriod, where _allowedAmount is the fixed number of tokens (allowedTokens) allowed to transact in a given rolling period when restriction type is Fixed . If not, then allowedAmount will be calculated at the tx processing time according to the current totalSupply of the ST. i.e _allowedAmount = (_restriction.allowedTokens.mul(ISecurityToken(securityToken).totalSupply())) / uint256(10) ** 18.

      sumOfLastPeriod will be the sum of the volume traded by the _from in last n days, where n is always less than or equal to the rollingPeriod. (given n will always be calculated after the startTime of the individual restriction ).

Second Case :-

  • If _from address has individual daily restriction & transaction time is between startTime and endTime of the restriction, then the transaction will go through only when:

    • _amount is less than or equal to the _allowedAmount - txSumOfDay, where _allowedAmount will be calculated the same as above but according to the individual daily volume restriction. While txSumOfDay is the amount traded till now within the 24 hrs span* . This amount is stored according to at the start time of 24 hrs i.e dailyLastTradedDayTime.

Third Case :-

  • If _from address has (individual daily restriction + individual restriction) & transaction time is between startTime and endTime of the restriction, then transaction will go through only when:

    • _amount is less than or equal to the _allowedAmount - sumOfLastPeriod (First case)

    • _amount is less than or equal to the _allowedAmount - txSumOfDay (Second Case)

      Both above condition should be true otherwise tx gets failed. #807.

Fourth Case :-

  • It works similar to any one of the first/second/third case. It depends upon which default restriction is active. The only difference between the above three and this is to use different storage variables to store the data.

Add Volume restriction

For Individual restriction for a given holder address.

   /**
    * @notice Use to add the new individual restriction for a given token holder
    * @param _holder Address of the token holder, whom restriction will be implied
    * @param _allowedTokens Amount of tokens allowed to be traded for a given address.
    * @param _startTime Unix timestamp at which restriction get into effect
    * @param _rollingPeriodInDays Rolling period in days (Minimum value should be 1 day)
    * @param _endTime Unix timestamp at which restriction effects will get the end.
    * @param _restrictionType Whether it will be `Fixed` (fixed no. of tokens allowed to transact)
    * or `Percentage` (tokens are calculated as per the totalSupply in the fly).
    */
    function addIndividualRestriction(
        address _holder,
        uint256 _allowedTokens,
        uint256 _startTime,
        uint256 _rollingPeriodInDays,
        uint256 _endTime,
        RestrictionType _restrictionType
    )
       public
       withPerm(ADMIN)

Require checks

  • individualRestriction[_holder].endTime < now it means if holder has no restriction or holder already has restriction but it is expired then it will allow the add new restriction otherwise tx get reverted.

  • _holder should not be a present in the exemption list.

  • _restrictionType could be 0 or 1. No other value allowed.

  • _rollingPeriodInDays always between [1, 365].

  • _restrictionType == 0 then _allowedTokens always greater then zero otherwise _allowedTokens should be non zero and value lies between (0, 100 _10*_16 ].

  • Difference of days between _startTime and _endTime should be >= _rollingPeriodInDays

  • If _startTime is 0 then it will takes current block timestamp + 1 as the startTime.

For multiple _holders (Similar require checks are applied to it):

   /**
    * @notice Use to add the new individual restriction for multiple token holders
    * @param _holders Array of the addresses of the token holders, whom restriction will be implied
    * @param _allowedTokens Array of the number of tokens allowed to be traded for a given address.
    * @param _startTimes Array of Unix timestamps at which restrictions get into effect
    * @param _rollingPeriodInDays Array of the rolling period in days (Minimum value should be 1 day)
    * @param _endTimes Array of Unix timestamps at which restriction effects will get the end.
    * @param _restrictionTypes Array of restriction types value whether it will be `Fixed` (fixed no. of tokens allowed to transact)
    * or `Percentage` (tokens are calculated as per the totalSupply in the fly).
    */
   function addIndividualRestrictionMulti(
       address[] memory _holders,
       uint256[] memory _allowedTokens,
       uint256[] memory _startTimes,
       uint256[] memory _rollingPeriodInDays,
       uint256[] memory _endTimes,
       RestrictionType[] memory _restrictionTypes
   )
       public

For Individual daily restriction:

   /**
    * @notice Use to add the new individual daily restriction for all token holder
    * @param _holder Address of the token holder, whom restriction will be implied
    * @param _allowedTokens Amount of tokens allowed to be traded for all token holder.
    * @param _startTime Unix timestamp at which restriction get into effect
    * @param _endTime Unix timestamp at which restriction effects will get the end.
    * @param _restrictionType Whether it will be `Fixed` (fixed no. of tokens allowed to transact)
    * or `Percentage` (tokens are calculated as per the totalSupply in the fly).
    */
   function addIndividualDailyRestriction(
       address _holder,
       uint256 _allowedTokens,
       uint256 _startTime,
       uint256 _endTime,
       RestrictionType _restrictionType
   )
       public
       withPerm(ADMIN)

Note: In Individual daily restriction _rollingPeriodInDays always hardcoded to 1.

Individual daily restriction for multiple holders:

   /**
    * @notice Use to add the new individual daily restriction for multiple token holders
    * @param _holders Array of the addresses of the token holders, whom restriction will be implied
    * @param _allowedTokens Array of the amount of tokens allowed to be traded for a given address.
    * @param _startTimes Array of Unix timestamps at which restrictions get into effect
    * @param _endTimes Array of Unix timestamps at which restriction effects will get the end.
    * @param _restrictionTypes Array of restriction types value whether it will be `Fixed` (fixed no. of tokens allowed to transact)
    * or `Percentage` (tokens are calculated as per the totalSupply in the fly).
    */
   function addIndividualDailyRestrictionMulti(
       address[] memory _holders,
       uint256[] memory _allowedTokens,
       uint256[] memory _startTimes,
       uint256[] memory _endTimes,
       RestrictionType[] memory _restrictionTypes
   )
       public

For Global restriction(same require check applies):

   /**
    * @notice Use to add the new default restriction for all token holder
    * @param _allowedTokens Amount of tokens allowed to be traded for all token holders.
    * @param _startTime Unix timestamp at which restriction get into effect
    * @param _rollingPeriodInDays Rolling period in days (Minimum value should be 1 day)
    * @param _endTime Unix timestamp at which restriction effects will get an end.
    * @param _restrictionType Whether it will be `Fixed` (fixed no. of tokens allowed to transact)
    * or `Percentage` (tokens are calculated as per the total supply in the fly).
    */
   function addDefaultRestriction(
       uint256 _allowedTokens,
       uint256 _startTime,
       uint256 _rollingPeriodInDays,
       uint256 _endTime,
       RestrictionType _restrictionType
   )
       external
       withPerm(ADMIN)

For default daily restriction:

   /**
    * @notice Use to add the new default daily restriction for all token holder
    * @param _allowedTokens Amount of tokens allowed to be traded for all token holders.
    * @param _startTime Unix timestamp at which restriction get into effect
    * @param _endTime Unix timestamp at which restriction effects will get an end.
    * @param _restrictionType Whether it will be `Fixed` (fixed no. of tokens allowed to transact)
    * or `Percentage` (tokens are calculated as per the totalSupply in the fly).
    */
   function addDefaultDailyRestriction(
       uint256 _allowedTokens,
       uint256 _startTime,
       uint256 _endTime,
       RestrictionType _restrictionType
   )
       external
       withPerm(ADMIN)

Note: Same require checks only one change that _rollingPeriodInDays values are by default 1.

Modify Volume Restrictions

For modifying the individual restriction **

   /**
    * @notice Use to modify the existing individual restriction for a given token holder
    * @param _holder Address of the token holder, whom restriction will be implied
    * @param _allowedTokens Amount of tokens allowed to be traded for a given address.
    * @param _startTime Unix timestamp at which restriction get into effect
    * @param _rollingPeriodInDays Rolling period in days (Minimum value should be 1 day)
    * @param _endTime Unix timestamp at which restriction effects will get the end.
    * @param _restrictionType Whether it will be `Fixed` (fixed no. of tokens allowed to transact)
    * or `Percentage` (tokens are calculated as per the totalSupply in the fly).
    */
   function modifyIndividualRestriction(
       address _holder,
       uint256 _allowedTokens,
       uint256 _startTime,
       uint256 _rollingPeriodInDays,
       uint256 _endTime,
       RestrictionType _restrictionType
   )
       public
       withPerm(ADMIN)

Note: It follows the same require checks as addxxx.. functions have.

For modifying multiple individual restrictions:

     function modifyIndividualRestrictionMulti(
       address[] memory _holders,
       uint256[] memory _allowedTokens,
       uint256[] memory _startTimes,
       uint256[] memory _rollingPeriodInDays,
       uint256[] memory _endTimes,
       RestrictionType[] memory _restrictionTypes  
     )
       public
       withPerm(ADMIN)

For modifying the individual daily restriction

   /**
    * @notice Use to modify the existing individual daily restriction for a given token holder
    * @dev Changing of startTime will affect the 24 hrs span. i.e if in earlier restriction days start with
    * morning and end on midnight while after the change day may start with afternoon and end with another day afternoon
    * @param _holder Address of the token holder, whom restriction will be implied
    * @param _allowedTokens Amount of tokens allowed to be traded for a given address.
    * @param _startTime Unix timestamp at which restriction get into effect
    * @param _endTime Unix timestamp at which restriction effects will get an end.
    * @param _restrictionType Whether it will be `Fixed` (fixed no. of tokens allowed to transact)
    * or `Percentage` (tokens are calculated as per the totalSupply in the fly).
    */
   function modifyIndividualDailyRestriction(
       address _holder,
       uint256 _allowedTokens,
       uint256 _startTime,
       uint256 _endTime,
       RestrictionType _restrictionType
   )
       public
       withPerm(ADMIN)

Modifying the Multiple daily restrictions

     function modifyIndividualDailyRestrictionMulti(
       address[] memory _holders,
       uint256[] memory _allowedTokens,
       uint256[] memory _startTimes,
       uint256[] memory _endTimes,
       RestrictionType[] memory _restrictionTypes  
     )
       public
       withPerm(ADMIN)

Modifying default restriction:

   /**
    * @notice Use to modify the global restriction for all token holder
    * @param _allowedTokens Amount of tokens allowed to be traded for all token holder.
    * @param _startTime Unix timestamp at which restriction get into effect
    * @param _rollingPeriodInDays Rolling period in days (Minimum value should be 1 day)
    * @param _endTime Unix timestamp at which restriction effects will gets end.
    * @param _restrictionType Whether it will be `Fixed` (fixed no. of tokens allowed to transact)
    * or `Percentage` (tokens are calculated as per the totalSupply in the fly).
    */
   function modifyDefaultRestriction(
       uint256 _allowedTokens,
       uint256 _startTime,
       uint256 _rollingPeriodInDays,
       uint256 _endTime,
       RestrictionType _restrictionType
   )
       external
       withPerm(ADMIN)

Modifying daily default restriction

   /**
    * @notice Use to modify the daily default restriction for all token holder
    * @dev Changing of startTime will affect the 24 hrs span. i.e if in earlier restriction days start with
    * morning and end on midnight while after the change day may start with afternoon and end with another day afternoon.
    * @param _allowedTokens Amount of tokens allowed to be traded for all token holder.
    * @param _startTime Unix timestamp at which restriction get into effect
    * @param _endTime Unix timestamp at which restriction effects will gets end.
    * @param _restrictionType Whether it will be `Fixed` (fixed no. of tokens allowed to transact)
    * or `Percentage` (tokens are calculated as per the totalSupply in the fly).
    */
   function modifyDefaultDailyRestriction(
       uint256 _allowedTokens,
       uint256 _startTime,
       uint256 _endTime,
       RestrictionType _restrictionType
   )
       external
       withPerm(ADMIN)

Remove Volume Restriction

Similar to addition or modification contract has the removeXX() or removeXXMulti() functions that will use to remove the individual, individual daily default, default daily restriction.

Getters

Provide the Individual bucket details for a given address.

   /**
    * @notice Use to get the bucket details for a given address
    * @param _user Address of the token holder for whom the bucket details has queried
    * @return uint256 lastTradedDayTime
    * @return uint256 sumOfLastPeriod
    * @return uint256 days covered
    * @return uint256 24h lastTradedDayTime
    * @return uint256 Timestamp at which last transaction get executed
    */
   function getIndividualBucketDetailsToUser(address _user) public view returns(uint256, uint256, uint256, uint256, uint256)

Provide the Default bucket details for a given address.

       /**
        * @notice Use to get the bucket details for a given address
        * @param _user Address of the token holder for whom the bucket details has queried
        * @return uint256 lastTradedDayTime
        * @return uint256 sumOfLastPeriod
        * @return uint256 days covered
        * @return uint256 24h lastTradedDayTime
        * @return uint256 Timestamp at which last transaction get executed
        */
       function getDefaultBucketDetailsToUser(address _user) public view returns(uint256, uint256, uint256, uint256, uint256)

Use to get the volume of token that is traded at a particular day for a given address

   /**
    * @notice Use to get the volume of token that being traded at a particular day (`_at` + 24 hours) for a given user
    * @param _user Address of the token holder
    * @param _at Timestamp
    */
   function getTotalTradedByUser(address _user, uint256 _at) external view returns(uint256)

Use to get the balance of the token holder for the given partition

   /**
    * @notice return the amount of tokens for a given user as per the partition
    * @param _partition Identifier
    * @param _tokenHolder Whom token amount need to query
    * @param _additionalBalance It is the `_value` that transfer during transfer/transferFrom function call
    */
    function getTokensByPartition(bytes32 _partition, address _tokenHolder, uint256 _additionalBalance) external view returns(uint256)
  • getExemptAddress() use to return the list of exempted addresses.

  • getIndividualRestriction(address _investor) use to return the individual restriction details for a given user.

  • getIndividualDailyRestriction(address _investor) use to return the individual daily restriction details for a given user.

  • getDefaultRestriction() use to return the default restriction details.

  • getDefaultDailyRestriction() use to return the default daily restriction details.

  • getRestrictionData() Provide the restriction details of all the restricted addresses

Other functions

Below function will be used to add/remove the wallet address from the exemption list.

   /**
    * @notice Add/Remove wallet address from the exempt list
    * @param _wallet Ethereum wallet/contract address that need to be exempted
    * @param _change Boolean value used to add (i.e true) or remove (i.e false) from the list
    */
    function changeExemptWalletList(address _wallet, bool _change) public withPerm(ADMIN)

Special considerations / notes

** modification only allowed when the former restriction startTime should be greater than the current timestamp.

  • 24hrs span will not be always morning to midnight of a day. It can be the afternoon of the day to the afternoon of the other day. It always depends on the start time of the Daily restriction.

Below internal function is used to mitigate the subtle edge case where user restriction type changes from default to an individual or vice versa.

 /**
 * @notice The function is used to check specific edge case where the user restriction type change from
 * default to an individual or vice versa. It will return true when the last transaction traded by the user
 * and the current txn timestamp lies on the same day.
 * NB - Instead of comparing the current day transaction amount, we are comparing the total amount traded
 * on the lastTradedDayTime that makes the restriction strict. The reason is not the availability of the amount
 * that transacted on the current day (because of bucket design).
 */
function _isValidAmountAfterRestrictionChanges(
    bool _isDefault,
    address _from,
    uint256 _amount,
    uint256 _sumOfLastPeriod,
    uint256 _allowedAmount
)
    internal
    view
    returns(bool)

Know Issues/bugs

All batch functions will hit the block gas limits if the array length is greater than 80(approx.).

PreviousCount Transfer ManagerNextTime-Travel-(Contract-Testing)

Last updated 5 years ago

Was this helpful?