Add a vault to PostDeliveryCrowdsale. (#1721)

* Add a vault to PostDeliveryCrowdsale.

* Add changelog entry.

* Apply suggestions from code review

Co-Authored-By: nventuro <nicolas.venturo@gmail.com>

* Rename TokenVault.

* add solhint ignore directive
This commit is contained in:
Nicolás Venturo
2019-04-23 19:06:09 -03:00
committed by GitHub
parent 19c7414052
commit 97a9ca5681
2 changed files with 28 additions and 3 deletions

View File

@ -10,6 +10,9 @@
### Improvements: ### Improvements:
* Upgraded the minimum compiler version to v0.5.7: this prevents users from encountering compiler bugs that were fixed in this version. ([#1724](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1724)) * Upgraded the minimum compiler version to v0.5.7: this prevents users from encountering compiler bugs that were fixed in this version. ([#1724](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1724))
### Bugfixes:
* `PostDeliveryCrowdsale`: some validations where skipped when paired with other crowdsale flavors, such as `AllowanceCrowdsale`, or `MintableCrowdsale` and `ERC20Capped`, which could cause buyers to not be able to claim their purchased tokens. ([#1721](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1721))
## 2.2.0 (2019-03-14) ## 2.2.0 (2019-03-14)
### New features: ### New features:

View File

@ -2,6 +2,8 @@ pragma solidity ^0.5.7;
import "../validation/TimedCrowdsale.sol"; import "../validation/TimedCrowdsale.sol";
import "../../math/SafeMath.sol"; import "../../math/SafeMath.sol";
import "../../ownership/Secondary.sol";
import "../../token/ERC20/IERC20.sol";
/** /**
* @title PostDeliveryCrowdsale * @title PostDeliveryCrowdsale
@ -11,6 +13,11 @@ contract PostDeliveryCrowdsale is TimedCrowdsale {
using SafeMath for uint256; using SafeMath for uint256;
mapping(address => uint256) private _balances; mapping(address => uint256) private _balances;
__unstable__TokenVault private _vault;
constructor() public {
_vault = new __unstable__TokenVault();
}
/** /**
* @dev Withdraw tokens only after crowdsale ends. * @dev Withdraw tokens only after crowdsale ends.
@ -20,8 +27,9 @@ contract PostDeliveryCrowdsale is TimedCrowdsale {
require(hasClosed()); require(hasClosed());
uint256 amount = _balances[beneficiary]; uint256 amount = _balances[beneficiary];
require(amount > 0); require(amount > 0);
_balances[beneficiary] = 0; _balances[beneficiary] = 0;
_deliverTokens(beneficiary, amount); _vault.transfer(token(), beneficiary, amount);
} }
/** /**
@ -32,12 +40,26 @@ contract PostDeliveryCrowdsale is TimedCrowdsale {
} }
/** /**
* @dev Overrides parent by storing balances instead of issuing tokens right away. * @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 beneficiary Token purchaser
* @param tokenAmount Amount of tokens purchased * @param tokenAmount Amount of tokens purchased
*/ */
function _processPurchase(address beneficiary, uint256 tokenAmount) internal { function _processPurchase(address beneficiary, uint256 tokenAmount) internal {
_balances[beneficiary] = _balances[beneficiary].add(tokenAmount); _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);
} }
} }