'Solidity storing timestamp/value data thats easily accessible

I have an interesting use case that I can't seem to solve.

Problem: Tokens get X points per day. I want to freeze ERC721 tokens (they have IDs) for a certain period of time. During that time, they get 0 points per day.

I have the following to calculate points:

uint32 public constant SECONDS_IN_DAY = 1 days;
struct UserInfo {
  uint256 itemCount;
  uint256 pendingPoints;
  uint256 lastUpdate;
}

mapping(address => UserInfo) public userInfo;


function pending(address account) public view returns (uint256) {
  uint256 pendingPoints = userInfo[account].pendingPoints + (((block.timestamp - userInfo[account].lastUpdate) / SECONDS_IN_DAY) * (userInfo[account].itemCount));
  return pendingPoints;
}

modifier updatePoints(address account) {
  userInfo[account].pendingPoints = pending(account);
  userInfo[account].lastUpdate = block.timestamp;
  _;
}

The problem I can't figure out:

  1. How do I store when each token is freezed for how long so that I can accurately determine when to reduce points in the pending function.
  2. Do this in a gas efficient way.

I've thought about adding a mapping that holds a timestamp and the amount per day that gets reduced in UserInfo struct but then I would have no way to retrieve this information.

mapping(uint256 => uint256) perDayPointDeductions;

I'm at a loss. Any help would be appreciated.



Solution 1:[1]

Maybe something like snapshots or/and a chainlink keeper could be a reliable solution to this problem, and maybe you could check how some staking mechanism works since the problem you are facing is similar staking

Solution 2:[2]

I'm not sure if I understand the issue well, but in this case I would store the data offchain e.g. tools https://thegraph.com/en/

Where I would emit events in functions that would just store my data on TheGraph. From there I can then read this data and determine what happens to the tokens and when they will be frozen. (Gas Efficient)

But if you need to do this directly in the contract ( hence avoiding the offchain). I would go for https://docs.chain.link/docs/chainlink-keepers/introduction/

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 jhonny
Solution 2 DOBBYLABS