I wrote a Money-saving smart contract where users deposit ETH and define the amount of time they want to keep that ETH in the contract, EX: USER X deposits 2ETH for one year, they can only withdraw their ETH after that period.
But solidity linter keeps telling me that I should not rely on block.timestamp
to make decisions.
This is the Saving
struct I'm using to map every address to a balance and endTime:
struct Saving {
uint256 balance;
uint256 endTime;
}
Here is my function modifier where I require the withdrawal time to be greater than the endTime I stored at the deposit moment:
modifier onlyValidTimeWithdraw() {
require(
block.timestamp > balances[msg.sender].endTime,
"You cannot withdraw yet"
);
_;
}
This is the message I get through the linter.
After doing some research I found that I should not have time-dependent conditions in my contract since miners can manipulate timestamps, but I did not find any alternative to this.
Miners can manipulate block timestamp to an extent of approx. few seconds, which is enough to affect business logic depending on a second-level precision.
function betLottery() external {
// the block.timestamp can be affected by a miner
// and they can submit their own winning transaction
if (block.timestamp % 2 == 0) {
win();
}
}
But since your logic depends on much longer period, I'd simply ignore or suppress the warning.
Or if it fits your usecase, you can validate against the block number, which most linters allow.
struct Saving {
uint256 balance;
uint256 endBlock;
}
require(
block.number > balances[msg.sender].endBlock,
"You cannot withdraw yet"
);