How to deal with overflow for uint64 expiry?

Hey guys,

I changed my subdomain registrar to allow users to register subdomains in years instead of months. In particular, I changed this line:
duration = duration * 31 days;
to this:
duration = duration * 365 days;

uint64 is not able to store this value more than one year.

How do you recommend making changes? I tried changing all the expiry variables to uint256 in my registrar and the base registrar, but errors were thrown in the base registrar.

Any help would be appreciated.

Thanks!

Have you tried converting to seconds rather than days?

Yep, still doesn’t work. Here’s the contract with seconds: 0x76A2aF4A2BfeDf6dd844f5D07905015Bbc4290d4

Here’s the contract with 365 days:
https://goerli.etherscan.io/address/0x41Fe90BC4c3b2474A4348Dc0F53F01E6bAC5A08C

If you want your duration input to be in terms of years, then you could just reduce that from a uint64 to like a uint16 or something.

And then you would not set duration = duration * 365 days, you would declare a local uint64 for the durationSeconds, and then durationSeconds = duration * 365 days.

1 Like

And then do what with the durationSeconds? how do I use it outside the function?

This is the function right now:

function register(
        bytes32 parentNode,
        string calldata label,
        address newOwner,
        address resolver,
        uint16 fuses,
        uint16 duration,
        bytes[] calldata records
    ) public payable {
        require(names[parentNode].available, "parent name is not available for subdomains");
        uint256 fee = duration * getRegistrationFee();
        require(msg.value >= fee, "msg value does not meet the price");
        require(!names[parentNode].subdomainMinted[label], "this subdomain has been minted");
        require(isValidLabel(label), "Label must be a number between 1 and 999");
        
        uint64 durationInSeconds = duration * 365 days;

        (, , uint64 parentExpiry) = wrapper.getData(uint256(parentNode));
        require(parentExpiry - uint64(block.timestamp) > duration, "duration exceeds limit");
        
        string memory readableName = names[parentNode].readableName;

        _register(
            parentNode,
            label,
            newOwner,
            resolver,
            fuses,
            uint64(block.timestamp) + duration,
            records
        );
        names[parentNode].balance += msg.value;
        names[parentNode].subdomainMinted[label] = true;

        emit SubleetRegistered(newOwner, label, parentNode, duration, readableName, fee);
    }
1 Like

You would pass that into the _register function, like uint64(block.timestamp) + durationInSeconds. Also make sure to update your other duration check there.

1 Like

Still not working (maybe it’s not an overflow issue?). It works with 1 year though.

Here’s where the contract is with the changes you recommended:

https://goerli.etherscan.io/address/0x32CA59C5A335D9983DB67b520a6Ea3a5377b899E#writeContract

What’s not working? I see you successfully registered 286.bigb0ss.eth with that contract, you passed in 1 for the duration, and the expiry was set to 1 year from now.

It’s not working for more than 1 year. So if I set duration as 2 or more it doesn’t work.

That’s because you can’t register a subname for longer than the parent expiry. So it is tripping your “duration exceeds limit” check.

Your parent name expires on June 29th, 2024.

4 Likes

Thanks!

1 Like