Lockup Transfer Manager

Introduced in

v3.0.0

Contract name

LockupTransferManager.sol

Compatible ST Protocol version range

^3.0.0

Type

Transfer Manager Module

How it works

This module is used to limit the volume of tokens to be transacted by the affiliate/investors. That helps in avoiding the material impact on the SecurityToken prices. In other words, it assigns a lockup on the tokens of the affiliates/investors (mainly large amount of percentage of token holders) and only allows them to transact a certain amount of tokens within a given time period.

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 Module

Step -1 : Add the LockupType first by using addNewLockUpType() with following parameters

  _lockupAmount → Lockup amount  = 100,000
  _startTime → Start Time of the lockup = now
  _lockUpPeriodSeconds . → Number of seconds lockup will remain active = 4 years(~ 4 * 365 * 24 * 3600).
  _releaseFrequencySeconds → Number of seconds after which a tranche of tokens will be released (This is a recurring process) = 1 year (~ 1 * 365 * 24 * 3600)
  _lockupName → Name of the lockup (Should be unique) = “a_lockup”

Step -2 : Assign “a_lockup” to Alice using the addLockUpByName() with following parameters

Day 1: Alice tries to sell 100 tokens

Day 250: Alice tries to sell 10,000 tokens

Day 731: Alice tries to sell 40,000 tokens

continues ...

If Alice has multiple lockups then totalRemainingLockedAmount will be calculated by looping all active lockups of Alice. The locked amounts for each lockup will be summed together.

Transfer Verification

  • If _from address has been added to the lockups mapping (i.e restricted address in terms of token volume ) then executeTransfer function performs a check to calculate the permitted or allowed volume of tokens to transact.

  • Transaction is allowed only when the total remaining locked amount is less than equal to the amount remain after the transaction ((currentBalance.sub(_amount)) >= totalRemainingLockedAmount) (#460 - #462). While the total remaining locked amount is the aggregation of the remaining locked amounts per lockups for a given address (i.e _from).

  • Lockup restrictions enter in effect as soon as a user is added to them. However, the vesting schedule (release of tokens) starts from _startTime.

  • If investor/affiliate doesn’t transact the total allowed volume of tokens of a particular period then the remaining amount of tokens will be added into the allowed quota of the following period.

  • If _from address is the issuance address ( i.e address(0) ) then executeTransfer will ignored. That means the minting of tokens is not affected by the LockupVolumeRestrictionTM. (#89)

Add lockup type

Note: 1. Tokens are locked as soon as the Lockup is created, but only start vesting from _startTime. 2. _releaseFrequencySeconds can be set to a number greater than _lockUpPeriodSeconds to disable vesting release cycles (all tokens will be released together when restriction ends).

For Batch transaction-

Assign the lockup to an investor/affiliate using the lockup type*

For a particular user-

Note: It is not possible to add an investor to an already started lockup (i.e lockup startTime < now).

For batch transaction

Note: addLockUpByNameMulti() will hit the block gas limit if the no. of addresses is more than 80 - 90 (It is an approximate figure not tested).

Create a new lockup for an investor/affiliate

It works similarly to adding the lockupType first and assign the lockup type to a given address. For batch transaction-

Remove the Lockup restriction of a particular investor/affiliate

An investor/affiliate can have more than one lockup restriction. So for removing a particular lockup restriction, we need to pass the lockupName and the address of the investor/affiliate (whose lockup restriction needs to be removed).

For Batch functions

Remove LockupType in a transaction

Lockup type can only be removed when a given type doesn’t have any associated address with it.

For batch transaction -

Note: removeLockUpTypeMulti() will hit the block gas limit if the no. of addresses is more than 75 (It is an approximate figure not tested).

Modify a lockup type

Like other functions, the issuer or the designated delegate having ADMIN permissions can modify the lockup restriction of a particular investor/affiliate with the help of -

For a batch transaction -

Note: modifyLockUpTypeMulti() will hit the block gas limit if the no. of addresses is more than 75 (It is an approximate figure not tested).

Getters

  • getLockUp(bytes32 _lockUpName) use to get the details of a particular lockup for a given lockup name.

  • getLockedTokenToUser(address _userAddress) use to get the total locked tokens for a given user. It will loop to all lockups for a given address and return sum of locked tokens per lockups.

  • getListOfAddresses(bytes32 _lockupName) use to get the list of the users of a lockup type.

  • getAllLockups() use to get the all lockups created by the issuer till now.

  • getLockupsNamesToUser(address _user) use to get the list of the lockups for a given user.

  • getTokensByPartition(bytes32 _partition, address _tokenHolder, uint256 _additionalBalance) use to get balance of the tokenHolder for a given partition.

  • getAllLockupData() use to get the details of all the lockupTypes.

Last updated

Was this helpful?