Skip to content

Commit

Permalink
Add a vault to PostDeliveryCrowdsale. (#1721)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
nventuro authored Apr 23, 2019
1 parent 19c7414 commit 97a9ca5
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 2 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@
### 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))

### 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)

### New features:
Expand Down
26 changes: 24 additions & 2 deletions contracts/crowdsale/distribution/PostDeliveryCrowdsale.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ pragma solidity ^0.5.7;

import "../validation/TimedCrowdsale.sol";
import "../../math/SafeMath.sol";
import "../../ownership/Secondary.sol";
import "../../token/ERC20/IERC20.sol";

/**
* @title PostDeliveryCrowdsale
Expand All @@ -11,6 +13,11 @@ 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.
Expand All @@ -20,8 +27,9 @@ contract PostDeliveryCrowdsale is TimedCrowdsale {
require(hasClosed());
uint256 amount = _balances[beneficiary];
require(amount > 0);

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

/**
Expand All @@ -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 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);
}
}

0 comments on commit 97a9ca5

Please sign in to comment.