Code to reproduce
Contract address is: 0x772F9103F3c3Fb236ebC17Fed9c304EC283ae025
Code:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/security/Pausable.sol";
contract DiamondPigNips is ERC20, Pausable {
address private _owner;
uint256 public constant MAX_SUPPLY = 1000000 * (10 ** 18);
uint256 public constant LOCK_PERIOD = 48 hours;
mapping(address => uint256) private lockedUntil;
constructor() ERC20("Nip Cream", "Nips") {
_mint(msg.sender, MAX_SUPPLY);
_owner = msg.sender;
}
modifier onlyOwner() {
require(msg.sender == _owner, "Caller is not the owner");
_;
}
function transfer(address to, uint256 amount) public override whenNotPaused returns (bool) {
require(_isTransferAllowed(msg.sender, to), "Transfer is not allowed");
_setLock(to);
return super.transfer(to, amount);
}
function transferFrom(address from, address to, uint256 amount) public override whenNotPaused returns (bool) {
require(_isTransferAllowed(from, to), "Transfer is not allowed");
_setLock(to);
return super.transferFrom(from, to, amount);
}
function _setLock(address account) internal {
lockedUntil[account] = block.timestamp + LOCK_PERIOD;
}
function unlock(address account) external {
lockedUntil[account] = 0;
}
function pause() external whenNotPaused onlyOwner {
_pause();
}
function unpause() external whenPaused onlyOwner {
_unpause();
}
function withdrawFunds(uint256 amount) external onlyOwner {
uint256 contractBalance = address(this).balance;
require(contractBalance >= amount, "Insufficient balance");
payable(_owner).transfer(amount);
}
function _isTransferAllowed(address from, address to) internal view returns (bool) {
// Add your transfer restriction logic here and return true if the transfer is allowed
// Otherwise, return false
// For example, a simple restriction could be checking if both the sender and recipient are not locked
return (lockedUntil[from] <= block.timestamp) && (lockedUntil[to] <= block.timestamp);
}
receive() external payable {}
}