Allows users to stake a specified token, and in return, they can earn rewards in another specified token. There are several functions to handle staking, withdrawing, and claiming rewards, and these functions update the rewards earned by users based on the amount of time their tokens have been staked