0

I have a timelock on an ERC20 contract, from year 0 to 9, it works until year 4, but from year 5 onwards it reverts. It fails both on minting and checking (Using 52 seconds intead of weeks for testing):

constructor() ERC20("Coin", "C") {        
    deploymentTime = block.timestamp;        
} 

function checkMintDate(uint8 year) public view returns (uint256){
    return deploymentTime + 52 seconds * year;
} 

function mint(uint8 year) public onlyOwner {        
    require (year <= 9, "cannot claim for more than 10 years");
    require(block.timestamp >= deploymentTime + 52 seconds * year, "Not that year yet");        
    require(!yearClaimed[year], "you already claimed that year");
    yearClaimed[year] = true;
    _mint(msg.sender, yearlyMintAmount);
} 

When deployed to the testnet, remix gives this data, which is the overflow one:

"code": "3", "message": "execution reverted", "output": "0x4e487b710000000000000000000000000000000000000000000000000000000000000011"

Any ideas?, thanks!

4
  • If I change the "seconds" sufix to "years", the checkMintDate function passes with all the numbers, and returns the correct unix dates. But it keeps failing with "seconds", wtf... Nov 11, 2022 at 15:42
  • It s normal it s conversion problem: 52 weeks = 1 year, 31536000 seconds = 1year But I m sure you get it And to help you to understand why it s passing in "seconds" with different value of "Year". Then you must consider : 52 seconds * year as minutes (rounded) And so, to pass the test with year = 5, you just have to wait more than 5 minutes
    – Aurel
    Nov 11, 2022 at 15:59
  • I wait for more than 5 minutes, and it gives the overflow error on remix, the block explorer gives even less information. But it doesn't give the failed required statement of "Not that year yet". mumbai.polygonscan.com/tx/… Nov 11, 2022 at 16:09
  • Maybe it is a Polygon bug?, I'll deploy to other testnet later today. Nov 11, 2022 at 16:20

2 Answers 2

0

So on the first analyse, you didnt convert correctly in year

function checkMintDate(uint8 year) public view returns (uint256){
return deploymentTime + 52 weeks * year;} 

and for the require the same:

require(block.timestamp >= deploymentTime + 52 weeks * year, "Not that year yet");   

For the error : 0x11: If an arithmetic operation results in underflow or overflow outside of an unchecked { ... } block.

So it s a type conversion issue Uint8 max value is 256 but 5*52 is over 260.

To solve the problem: the best practice is to send the parameter in uint256, it's costing less gas and avoid this error.

If not just then cast : ....52 seconds * uint256(year)...

1
  • I know that for year it should be 52 weeks, but, I'm testing with 52 seconds, and it fails from year 5 onwards. This is not the final state of the contract, I won't use seconds on livenet, but I want to understand why it fails with seconds. Nov 11, 2022 at 16:04
0

Resolved in another forum, had to change year to uint256:

https://forum.openzeppelin.com/t/dont-understand-this-overflow-in-my-timelock/33075/4

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.