Trying to Create the Crowdsale Contract

Hello,
I tried to write the solidity using the openzeppelin library but I am finding it difficult to move forward with the steps I am a bit of confused with the contract.
It would be great if someone assists me...

:1234: Code to reproduce

pragma solidity 0.5.5;

import "./Crowdsale.sol";

contract CryptoCrowdsale is Crowdsale, PostDeliveryCrowdsale {
    constructor(
        uint rate,
        address payable wallet,
        IERC20 token,
        uint openingTime, 
        uint closingTime
    )   Crowdsale(rate, wallet, token) 
        PostDeliveryCrowdsale() 
        TimedCrowdsale(openingTime, closingTime)
        
        public {} 
        
}

:computer: Environment

Remix

It seems like you followed this documentation: Crowdsales - OpenZeppelin Docs, so what error did you encounter?

And there is a tutorial for the crowdsale contract, you can have a look: Simple ERC20 Crowdsale | OpenZeppelin Community

Thanks For your precious time,
I am facing issue like how the user will buy token in remix its not buying token and it throws an error saying alert when I open metamask.
I am triying to deploy this on Polygon.

So could you please share all of your source code?

Ya Sure,
Directly share it here or other modes i have to share?

If there are not any sensitive things, you can just share at there.

Thanks again for your time

Token Contract

pragma solidity ^0.5.0;

import "./ERC20.sol";
import "./ERC20Detailed.sol";
import "./Context.sol";
import "./IERC20.sol";
import "./SafeMath.sol";


contract DemoToken is Context, ERC20, ERC20Detailed {
    constructor (
        string memory name,
        string memory symbol,
        uint256 initialSupply
        
    ) public ERC20Detailed(name, symbol, 18) {
        _mint(_msgSender(), initialSupply);
    }
}

Crowdsale Contract

pragma solidity ^0.5.0;

import "./SafeMath.sol";
import "./Crowdsale.sol";

/**
 * @title TimedCrowdsale
 * @dev Crowdsale accepting contributions only within a time frame.
 */
contract TimedCrowdsale is Crowdsale {
    using SafeMath for uint256;

    uint256 private _openingTime;
    uint256 private _closingTime;

    /**
     * Event for crowdsale extending
     * @param newClosingTime new closing time
     * @param prevClosingTime old closing time
     */
    event TimedCrowdsaleExtended(uint256 prevClosingTime, uint256 newClosingTime);

    /**
     * @dev Reverts if not in crowdsale time range.
     */
    modifier onlyWhileOpen {
        require(isOpen(), "TimedCrowdsale: not open");
        _;
    }

    /**
     * @dev Constructor, takes crowdsale opening and closing times.
     * @param openingTime Crowdsale opening time
     * @param closingTime Crowdsale closing time
     */
    constructor (uint256 openingTime, uint256 closingTime) public {
        // solhint-disable-next-line not-rely-on-time
        require(openingTime >= block.timestamp, "TimedCrowdsale: opening time is before current time");
        // solhint-disable-next-line max-line-length
        require(closingTime > openingTime, "TimedCrowdsale: opening time is not before closing time");

        _openingTime = openingTime;
        _closingTime = closingTime;
    }

    /**
     * @return the crowdsale opening time.
     */
    function openingTime() public view returns (uint256) {
        return _openingTime;
    }

    /**
     * @return the crowdsale closing time.
     */
    function closingTime() public view returns (uint256) {
        return _closingTime;
    }

    /**
     * @return true if the crowdsale is open, false otherwise.
     */
    function isOpen() public view returns (bool) {
        // solhint-disable-next-line not-rely-on-time
        return block.timestamp >= _openingTime && block.timestamp <= _closingTime;
    }

    /**
     * @dev Checks whether the period in which the crowdsale is open has already elapsed.
     * @return Whether crowdsale period has elapsed
     */
    function hasClosed() public view returns (bool) {
        // solhint-disable-next-line not-rely-on-time
        return block.timestamp > _closingTime;
    }

    /**
     * @dev Extend parent behavior requiring to be within contributing period.
     * @param beneficiary Token purchaser
     * @param weiAmount Amount of wei contributed
     */
    function _preValidatePurchase(address beneficiary, uint256 weiAmount) internal onlyWhileOpen view {
        super._preValidatePurchase(beneficiary, weiAmount);
    }

    /**
     * @dev Extend crowdsale.
     * @param newClosingTime Crowdsale closing time
     */
    function _extendTime(uint256 newClosingTime) internal {
        require(!hasClosed(), "TimedCrowdsale: already closed");
        // solhint-disable-next-line max-line-length
        require(newClosingTime > _closingTime, "TimedCrowdsale: new closing time is before current closing time");

        emit TimedCrowdsaleExtended(_closingTime, newClosingTime);
        _closingTime = newClosingTime;
    }
}

pragma solidity ^0.5.0;

import "./SafeMath.sol";
import "./Secondary.sol";
import "./IERC20.sol";

/**
 * @title PostDeliveryCrowdsale
 * @dev Crowdsale that locks tokens from withdrawal until it ends.
 */
contract PostDeliveryCrowdsale is TimedCrowdsale {
    using SafeMath for uint256;

    mapping(address => uint256) private _balances;
    __unstable__TokenVault private _vault;

    constructor() public {
        _vault = new __unstable__TokenVault();
    }

    /**
     * @dev Withdraw tokens only after crowdsale ends.
     * @param beneficiary Whose tokens will be withdrawn.
     */
    function withdrawTokens(address beneficiary) public {
        require(hasClosed(), "PostDeliveryCrowdsale: not closed");
        uint256 amount = _balances[beneficiary];
        require(amount > 0, "PostDeliveryCrowdsale: beneficiary is not due any tokens");

        _balances[beneficiary] = 0;
        _vault.transfer(token(), beneficiary, amount);
    }

    /**
     * @return the balance of an account.
     */
    function balanceOf(address account) public view returns (uint256) {
        return _balances[account];
    }

    /**
     * @dev Overrides parent by storing due balances, and delivering tokens to the vault instead of the end user. This
     * ensures that the tokens will be available by the time they are withdrawn (which may not be the case if
     * `_deliverTokens` was called later).
     * @param beneficiary Token purchaser
     * @param tokenAmount Amount of tokens purchased
     */
    function _processPurchase(address beneficiary, uint256 tokenAmount) internal {
        _balances[beneficiary] = _balances[beneficiary].add(tokenAmount);
        _deliverTokens(address(_vault), tokenAmount);
    }
}

/**
 * @title __unstable__TokenVault
 * @dev Similar to an Escrow for tokens, this contract allows its primary account to spend its tokens as it sees fit.
 * This contract is an internal helper for PostDeliveryCrowdsale, and should not be used outside of this context.
 */
// solhint-disable-next-line contract-name-camelcase
contract __unstable__TokenVault is Secondary {
    function transfer(IERC20 token, address to, uint256 amount) public onlyPrimary {
        token.transfer(to, amount);
    }
}
pragma solidity 0.5.5;

import "./Crowdsale.sol";

contract DemoCrowdsale is Crowdsale, PostDeliveryCrowdsale {
    constructor(
        uint rate,
        address payable wallet,
        IERC20 token,
        uint openingTime, 
        uint closingTime
    )   Crowdsale(rate, wallet, token) 
        PostDeliveryCrowdsale() 
        TimedCrowdsale(openingTime, closingTime)
        
        public {} 
        
}

Perhaps stating the obvious -- it's not mintable, so tokens have to be sent to the crowdsale contract for it to "work".

The new Metamask will not allow you to confirm sends it knows cannot be completed. It used to send and you'd get the revert error, now the "next" button stays grayed out. It's a feature, not a flaw...

1 Like