0

I have written a function to lock some amount of tokens. If user lock tokens then by calling this function then token will be locked for 180 days. One of the important logic I wanted to implement is I want when user call that function by passing the token amount to be locked, in this time of 180 days the user will automatically get 1% of total locked token every day for 180 days, automatically, without any interaction the 1% amount of token will be deposited to their wallet. I wrote the function like this:

function chooseToBeLocked(uint256 _amount) public {
    require(_amount >= 200);
    require(isUser[msg.sender], 'Need to be a user');
    require(over200[msg.sender]);
    lockedOrUnlocked[msg.sender] = Status.locked;
    amountLockedByAddress[msg.sender] = _amount;
    canTransfer[msg.sender] = CanTransfer.no;
    lockTime = block.timestamp + 180 days;
    timeWhenLocked[msg.sender] = lockTime;
    uint256 recordDays = block.timestamp;
    for (uint256 i = 1; i <= 180; i++) {
      require(block.timestamp == recordDays + 1 days);
      recordDays = block.timestamp;
      IERC20Upgradeable(agm).transferFrom(address(this), msg.sender, (amountLockedByAddress[msg.sender]) / 100);
    }
  }

Did i code right??

2
  • No...sorry to say but this is an awful thing you wrote. What you want is not possible in the way you described it. This is an unnecessary for-loop that just eats gas... research "linear vesting curves". There's a library by OpenZeppelin if I'm not mistaken. Also do invest in a smart-contract audit for your project, you seem to be a beginner...
    – Ape Toshi
    Commented Jun 5, 2023 at 15:41
  • The logic of transfering 1 token per day to an account for 180 days -- linear vesting curves will help me to implement it??
    – Hacek
    Commented Jun 5, 2023 at 16:26

1 Answer 1

1

The only way I can think of for this to work automatically without having any transaction go onchain each day for the user would be if you are only locking a token you have created, where the lock mechanism is implemented inside the token contract.

You would then need to override balanceOf, and have conditional logic for a user's balance dependent on how much of the locked tokens have been unlocked. Then whenever someone calls balanceOf as a view function from off chain, they will see the user's balance updated with the 1% per day of the unlocked tokens.

Unfortunately, if you want to use some already existing token that you have not created, like USDC or DAI, I do not think this feature is possible. However if this mechanism is intended to be implemented on a token you are deploying, is should indeed be possible by modifying the code of the ERC20 you are deploying as stated above.

Also, you would not implement this behavior with a for loop in that case, but rather you would have some logic dependent on block.timestamp inside the balanceOf logic of your erc20.

Also, you should conceptually read up a bit on how transactions work when you send them on chain. When you send a transaction to the blockchain, it can only execute once, and that instant in the for that block. If you want to do other things later in time, you(or some user) needs to launch another transaction to the blockchain at that time, to begin execution. So as such, you can either have passive changes based on things like block.timestamp, or active state changes when someone calls into the blockchain. You can't like set events to execute at later points in time in a smart contract. The closest thing you can get to that is offering some 3rd party an economic incentive to start the transaction at that time, but even then you should keep in mind that you might not be able to always rely on that third party.

1
  • Upvoted your answer. But moderators on comments basically only have a Delete or Decline option, and we can't even contact you. Moderators seldomly Delete, and what you flagged doesn't appear to meet the threshold to get deleted. What you did was correct, posting an answer instead of trying to debate in comments. Thank you!
    – eth
    Commented Jun 10, 2023 at 1:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.