🌏Core

Smart contracts providing TokenTable's core functionality.

TokenTable core smart contracts work together to provide our users with a complete experience. To best illustrate this, here is an example of the core user workflow which involves all core smart contracts.

Note: all time units are in seconds, including timestamps.

Context

Suppose a startup has fundraised, hired its core team, and uses TokenTable to distribute tokens to its investors and employees. Founders must create and enforce unlocking schedules for their investor/team tokens. Here is a step-by-step guide to accomplish this.

Suppose the unlocking schedule looks like the graph below:

x: time, y: percentage of tokens unlocked

Founder Workflow

1. Deploying a TokenTable Suite

Each startup or organization must deploy its own instance of TokenTable. After deployment, they can use the same instance over multiple unlocking schedules. To deploy, call deployTTSuite .

2. Creating a Preset Unlocking Schedule

A preset contains shared information across all stakeholders within the same unlocking schedule. For example, in the same fundraising round, all investors follow the same unlocking curves and claim intervals. To create a preset, call createPreset .

The input parameters to this function are fairly complex:

  • presetId can be set to whatever you want as long as it doesn't exist yet

  • linearStartTimestampsRelative records the start timestamp of the beginning of each linear segment. Cliff releases are treated as linears with a duration of 1 while cliff waiting periods are treated as linears with an unlocking percentage of 0%. In short, everything is a linear segment. Relative means the timestamp is relative to the start time, which isn't specified in the preset.

  • linearEndTimestampRelative is the end timestamp of the final linear segment.

  • linearBips is the number of basis points (bips) each linear segment unlocks. As mentioned above, cliff waiting periods unlock 0 bips. All bips should add up to the hardcoded BIPS_PRECISION variable, which is 10000.

  • numOfUnlocksForEachLinear is the number of unlocks within each linear segment. The minimum value is 1 or else the claim function will always revert. Use 1 for cliff waits and releases.

Here is what the input parameters look like for the unlocking graph above:

linearStartTimestampsRelative: [0, 10, 11, 30, 31, 40, 41, 60, 90]
linearEndTimestampRelative: 130
linearBips: [0, 1000, 0, 1000, 0, 2000, 0, 2000, 4000]
numOfUnlocksForEachLinear: [1, 1, 1, 1, 1, 1, 1, 3, 4]

Here are some more input parameters for different unlocking curves:

linearStartTimestampsRelative: [0,31536000], linearEndTimestamp: 31536001, linearBips: [0,10000], numOfUnlockerForEachLinear: [1,1]
linearStartTimestampsRelative: [0,1,7747200], linearEndTimestamp: 36604800, linearBips: [1300,1400,7300], numOfUnlockerForEachLinear: [1,1,56]
linearStartTimestampsRelative: [0,126230400], linearEndTimestamp: 126230401, linearBips: [10000,0], numOfUnlockerForEachLinear: [48,1]
linearStartTimestampsRelative: [0,1,2678400,5100278,7783778,7791562,5120954], linearEndTimestamp: 5126074, linearBips: [1600,200,3300,600,300,500,3500], numOfUnlockerForEachLinear: [1,1,2,3,3,8,2]

3. Creating an Actual Unlocking Schedule

After we create a preset, we can create an actual. An actual is based on a preset but contains information unique to a single token recipient, such as the total locked token amount and start time. To create an actual, call createActual .

An example of input parameters is as follows:

recipient: 0xd8da6bf26964af9d7eed9e03e53415d37aa96045
presetId: keccak256('seed')
startTimestampAbsolute: 1687263601
amountSkipped: 0
totalAmount: 10000
amountDepositingNow: 10000
  • recipient is the stakeholder's address.

  • presetId is the preset you intend to use (created in the previous step).

  • startTimestampAbsolute is the start time of this actual schedule. This is a standard UNIX timestamp and must be in the future. You can get the current timestamp here: https://www.unixtimestamp.com/

  • amountSkipped indicates how much unlocking this schedule has already done. This is only useful if you are migrating your unlocking system from a different platform. Setting this number allows you to continue the unlocking progress instead of starting over.

  • totalAmount is the total number of tokens to be unlocked.

  • amountDepositingNow is the number of tokens the caller (founder) wishes to deposit into the actual schedule at this time. Partial deposits are supported but will cause claiming to fail if the deposit is insufficient. You can deposit more later. In this example, we are depositing the full amount.

This function safely mints a FutureToken NFT to the recipient's address. The FutureToken determines where the unlocked tokens go to, not the recipient's address. Unlocked tokens are sent to the owner of the corresponding FutureToken and this token can be transferred to a different address by the original recipient.

The token ID (which is the actualId) of the minted FutureToken can be observed through an emitted event in the transaction receipt.

4. Depositing Funds into an Actual Unlocking Schedule

As mentioned previously, if the founder chooses to only deposit a partial amount into an actual unlocking schedule and the claimable amount is greater than the amount deposited, the claim action will revert. To prevent this, founders must proactively check the amount deposited is sufficient and top up accordingly by calling the functions unlockingScheduleActuals and deposit .

5. (Optional) Withdrawing Deposited Funds from an Actual Unlocking Schedule

If, for any reason, the founder would like to immediately deny a stakeholder from claiming (e.g. the stakeholder's wallet has been compromised, FutureToken is lost, etc.), they can withdraw their deposited funds by calling withdrawDeposit.

6. (Optional) Cancel an Actual Schedule

If, for any reason, the founder would like to immediately halt the progress of an actual unlocking schedule permanently, they can cancel the schedule by calling cancel. Any tokens that are deposited but still locked are refunded to the founder immediately.

Stakeholder Workflow

1. Adding FutureToken & TrackerToken to Wallet

By adding the project-specific FutureToken & TrackToken, the stakeholder can interact with their redemption NFT and view the current claimable token amount from the comfort of their own wallet without having to visit TokenTable's website.

2. Claiming Unlocked Tokens

Stakeholders have the option to either claim through TokenTable's website or by calling claim .

3. (Optional) Claiming Unlocked Tokens from a Cancelled Schedule

If, for any reason, the stakeholder's actual unlocking schedule was canceled, they can claim any leftover unlocked tokens by calling claimCancelledActual.

Last updated