0

I would like to create a ERC20 token with an expiration date to represent for example a ticket or a gift card. I've created a contract which overrides the open-zeppelin ERC20 contract methods.

pragma solidity ^0.4.24;

import "../node_modules/openzeppelin- solidity/contracts/token/ERC20/ERC20.sol";  
import "../node_modules/openzeppelin-solidity/contracts/token/ERC20/ERC20Detailed.sol";
import "../node_modules/openzeppelin-solidity/contracts/token/ERC20/ERC20Mintable.sol";
import "../node_modules/openzeppelin-solidity/contracts/token/ERC20/ERC20Burnable.sol";
import "../node_modules/openzeppelin-solidity/contracts/token/ERC20/IERC20.sol";


/**  
* @title EventToken is a basic ERC20 Token  
*/  
contract EventToken is ERC20, ERC20Detailed, ERC20Mintable, ERC20Burnable {

uint256 ticketExpiryDateTimestamp;

constructor(
    uint256 _initialSupply,
    string memory _name,
    string memory _symbol,
    uint8 _decimals,
    uint256 _ticketExpiryDateTimestamp
    )  
        ERC20Detailed(_name, _symbol, _decimals)
        ERC20Mintable()
        ERC20Burnable()
        ERC20()
        public
{
    mint(msg.sender, _initialSupply);
    ticketExpiryDateTimestamp = _ticketExpiryDateTimestamp;
}

function totalSupply() public view returns(uint256) {
    if(now > ticketExpiryDateTimestamp) {
        return 0;
    } else {
        return ERC20.totalSupply();
    }
}

function balanceOf(address owner) public view returns (uint256) {
    if(now > ticketExpiryDateTimestamp) {
        return 0;
    } else {
        return ERC20.balanceOf(owner);
    }
}

function allowance(address owner, address spender) public view returns(uint256) {
    if(now > ticketExpiryDateTimestamp) {
        return 0;
    } else {
        return ERC20.allowance(owner, spender);
    }
}

function transfer(address to, uint256 value) public returns(bool) {
    if(now > ticketExpiryDateTimestamp) {
        return false;
    } else {
        return ERC20.transfer(to, value);
    }
}

function approve(address spender, uint256 value) public returns (bool) {
    if(now > ticketExpiryDateTimestamp) {
        return false;
    } else {
        return ERC20.approve(spender, value);
    }
}

function transferFrom(address from, address to, uint256 value) public returns(bool) {
    if(now > ticketExpiryDateTimestamp) {
        return false;
    } else {
        return ERC20.transferFrom(from, to, value);
    }
}
}

It's how I did the override of the ERC20 standard. It's the way how I deploy it:

var EventToken = artifacts.require("./EventToken.sol");

const tokenCode = "TCK";
const tokenFullName = "TicketToken";
const initialSupply = "100";
const decimals = "0";
const epochTimeSeconds = Date.now() / 100;
const expireAfterSeconds = 60 * 2;
const expiryDate = epochTimeSeconds + expireAfterSeconds;

module.exports = function(deployer) {
 deployer.deploy(
 EventToken,
 initialSupply,
 tokenFullName,
 tokenCode,
 decimals,
 expiryDate
 );
};

After the deployment I see my tokens on metamask but after two minutes they are still there. I would like to know how to implement the logic of an expiration of an ERC20 token or how to fix my code to do so. Thanks in advantage

  • 1
    I think you want Date.now() / 1000. – user19510 Dec 11 '18 at 15:02
  • I would be suspicious of the ticketExpiryDateTimeStamp computed outside. Consider passing in uint durationInSeconds and then setting ticketExpiryDateTimeStamp = now + durationInSeconds; Also keep in mind the timeStamp isn't perfect. – Rob Hitchens Dec 11 '18 at 15:05
  • Thank you Rob Hitchens, when I generate the expiration date inside the contract it works thanks. – Marcello Bardus Dec 11 '18 at 15:12
1

Use block.timestamp to get the current time. When a user tries to transfer tokens check if it is expired or not.

require(block.timestamp < ticketExpiryDateTimestamp);

For custom expiration store ticketExpiryDateTimestamp for each user in a mapping.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.