How to use TokenTimelock with a contract as beneficiary and release token?


I use TokenTimelock to lock tokens for a specific amount of time (my code can be found here)

But in my usecase the beneficiary is not a normal account, it is a Vesting Contract which will make the token in it with other business rules releasable after the TokenTimelock has expired and was released into the Vesting contract.

What I am doing so far in a test is:

  this.vesting = await;
  await this.vesting.initialize(owner);
  await this.vesting.addBeneficiaries([vestor1, vestor2], [93, 7], {from: owner});

In my TokenSale-Contract a function can receive this contracts address this way:

function assignTeamVesting(address teamVesting) public  {
    require(teamVesting != address(0));

    _teamVesting = teamVesting;
    emit TeamVestingAssigned(_teamVesting);

When timelocking of tokens comes into the game, this code is used:

    TokenTimelock timeLock = new TokenTimelock();
    timeLock.initialize(_token, _teamVesting, releaseTime );

The address of _teamVesting is the beneficiary for TokenTimelock.

However, there seems to be no way to release the tokens as the owner is a contract and not a simple account. Or am I wrong here?

I have tried out:

const tx = await tokenLock.release({from: this.vesting.address});

which will throw Returned error: sender account not recognized

Any ideas available?

(The root cause of having a TokenTimelock AND another TeamVesting contract on top of this is that Team tokens first are locked for 12 month and then only 10% per month can be transfered to team members)

1 Like

Hm… One idea could be to build a single contract which is a combination of TokenTimelocks timelocking-logic and on top of this the other logic of the TeamVesting-contract directly inside.

The logic of the TeamVesting contact is just that only 10% per month of all token can be released per beneficiary. Therefor I had encapsulated this logic inside a separate contract because I thought, I can put this contract then as beneficiary into TokenTimelock, which seems to not work.

1 Like

FInally it seems to work.

I was confused who is allowed to call the release-method in this case and found another confusing answer on stackoverflow.

1 Like

Glad you are all sorted now. You can mark your reply as the solution. :smile:

1 Like

Not really :slight_smile: My final solution was a different approach, which works in the tests, but doesnt cover any posts of mine before. And even it works in the tests, I am still unsure if this will really work this way. Tomorrow I want to do real tests on rinkeby.

I am also not sure, if the permissions are working as expected. Having fear of open doors

1 Like

Testing testing testing :smile:. Code coverage can be useful too.

Also once you are satisfied with all your testing locally and on testnets, then it is on to external audits.

Exactly. Unfortunately, solidity-coverage fails on my machine in general. But I think I have a big coverage because this is the only thing, I rely on by myself :slight_smile:

Btw, are you available for Auditing? I would recommend you then to my client with which you can talk about your rates and make hopefully a contract

1 Like

Hi @itinance

Regards a security audit then I suggest contacting Zeppelin. (I am biased but Zeppelin have always been at the top of my list of security auditors since I got into the space in 2017).

For test coverage, I suggest that you create a new topic in the #support category for solidity-coverage and we can see if the community can help get this working.