Can you loop TokenTimelock.sol and block.timestamp?

Hi! I'm wondering if you can use a while loop with TokenTimelock.sol and block.timestamp. If I'm understanding this correctly, TokenTimelock will let you lock tokens for a certain amount of time, and block.timestamp can give you the current time, and also let you execute functions at a certain period of time after that timestamp. Basically, what I'm trying to do is have a transaction of some tokens locked up for a period of time (using block.timestamp to get the current time that transaction was requested, so that people can't try to receive their tokens before their time comes), and after x amount of time, the user can get their tokens, and then I can repeat this function until something happens to break it. Like this:

function holdTokens(uint256 amount, address recipient) {
    while transfer pending:
        get block.timestamp
        if current time <= block.timestamp, "It's too early to get your tokens"
        if current time <= block.timestamp + x:
        release tokens;

I know my code is probably not formatted correctly but I'm just trying to get my point across. Also, there will be more to the while loop but I don't want to give too much of my project away. Is there a way I can do this? Thanks. :grinning_face_with_smiling_eyes:

Instead of looping, just use a second variable for the second condition.

if(block.timestamp >= target && second condition) {
    release token
} else {
    lock token

Hi, I am not sure why you want to use while, could it be if transfer pending?

I want to use a while loop because I'd be sending a certain amount of tokens to an address every time a user wants to do so, BUT they can only do this so many times, because there'll be an event that happens to break the loop (which is why I thought while would be best). Again, I don't want to give too much of my project away right now, so I hope my questions/replies aren't too vauge.

This could be useful, except that that else statement may not help me. When the user wants his or her tokens, they will be locked for a period of time but ultimately released. I don't want the tokens locked forever. Is that code saying if the block.timestamp for the target meets the right conditions, the tokens will be released, otherwise they'll be locked forever? If so, how could I tell the contract to know that the block.timestamp is good?

So why do not you just transfer tokens to this contract, and then set the release time.
For example, transfer 10,000 token to a contract, set an internal, maybe 100 seconds, distribute rate is 20, and the start time(assume it is 50s), so when user claims token, he/she can get

canClaimAmount = (block.timestamp - startTime) / internalTime * rate

OK! So would I have to do something like this?


With the _from field being the contract holding all the tokens, and the _to field being whoever wants to buy the token?

And then some kind of way (because I don't know how I would code this) set a timer for when the tokens would be released? Because I don't just want the user/address to receive their tokens in small chunks over time, I want them to be able to get their tokens all at once, BUT they have to wait for some time before they can get them. So, for example, there would be a claim function, button, whatever you want to call it, for the user to get their tokens, but because there would be a timer, that button would be grayed out until the time is up. Then they could claim, and I would like to be able to repeat this process if the user chose to do so. Is that something that TokenTimelock.sol can do?

If you want to use the trasferFrom, I think the steps should be: 1) Account_A calls token.approve(contract, amount), and then in the contract, it can use the transferFrom 2) User call the function that contains transferFrom to get token. the parameters should be

from: Account_A
to: User_address
value: Can/_get_amount

Yes, it can meet some of your requirements, but for all of your requirements, I think you should modify the contract.

I'm not quite sure I understand your use case so please correct me if I'm wrong. Based on my understanding, it seems like if a user wants to withdraw? their tokens, they need to wait X amount of time.

If that's the case, you just need have a variable (mapping?) target to track when the tokens are unlocked and whenever the user tries to withdraw, it just needs to ensure that the current block.timestamp >= target.

I added a second condition because I thought you wanted to "repeat this function until something happens to break it."

I added a second condition because I thought you wanted to "repeat this function until something happens to break it."

I do! But yesterday, I took a moment to truly understand what I'm trying to do, and now I want the user to be able to withdraw their tokens at once (actually, it doesn't matter whether they have to wait for their tokens or they get them all at once). But the catch is that once they claim their tokens, if they wanted to claim some again (I'll say this again, I'm not giving you the full details of my project, I'm sure you can understand), they can't just keep clicking the button over and over. They will have to wait AT LEAST 24 hours to claim some tokens again. And, I thought a while loop would be best because of how the user is going to claim the tokens.

Basically I'm trying to make a PoW token. I wish I could tell you what all I'm trying to do, since I know this can sound a bit confusing, but I don't want someone to copy my idea before I even finish. Sorry!

So the simplest way to do this is have a variable track either a block number or timestamp (let's call this the target). User can only withdraw if the current block.number / block.timestamp >= target. Before the end of the withdraw / transfer function, update the target to a new target (maybe like 1 day delay or something) so that the user can only withdraw after waiting at least 1 day.

Hmm, that sounds interesting. I appreciate all the help!

Execution of a function needs to be fully contained in one block. So a while loop for 24 hours is absolutely impossible. It would also cost tons of money. The right thing to do is have the user come back again after 24 hours to trigger a new request.

1 Like

The right thing to do is have the user come back again after 24 hours to trigger a new request.

OK! Is that something I can loop? Or how would I even go about doing that? I'm sorry if these questions seem a little silly, I'm a newbie in Solidity. :smiley:

This should not be done in Solidity. You should ask the user with a message in whatever UI they're using, that they should come back in 24 hours and send the transaction again.

Thanks for your help, @frangio (and also @Skyge and @STYJ)! A trigger would be something like an HTML button prompting MetaMask to pop up (using web3.js), right?

1 Like

Yes a button that sends a transaction.

OK. Thank you for your help, sir!