1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465 |
- pragma solidity ^0.5.0;
- import "../validation/TimedCrowdsale.sol";
- import "../../math/SafeMath.sol";
- import "../../ownership/Secondary.sol";
- import "../../token/ERC20/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);
- }
- }
|