Skip to content

Commit

Permalink
feat: bump v0.27.0
Browse files Browse the repository at this point in the history
  • Loading branch information
Hokid committed Oct 27, 2018
1 parent 893ae9f commit 5ab5b30
Show file tree
Hide file tree
Showing 4 changed files with 120 additions and 5 deletions.
32 changes: 31 additions & 1 deletion contracts/crowdsale/W12Crowdsale.sol
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ contract W12Crowdsale is Versionable, IW12Crowdsale, Ownable, ReentrancyGuard {
event StagesUpdated();
event StageUpdated(uint index);
event MilestonesUpdated();
event CrowdsaleSetUpDone();
event UnsoldTokenReturned(address indexed owner, uint amount);

constructor (
Expand Down Expand Up @@ -204,6 +205,8 @@ contract W12Crowdsale is Versionable, IW12Crowdsale, Ownable, ReentrancyGuard {
);

paymentMethods.update(paymentMethodsList);

emit CrowdsaleSetUpDone();
}

/**
Expand Down Expand Up @@ -452,7 +455,7 @@ contract W12Crowdsale is Versionable, IW12Crowdsale, Ownable, ReentrancyGuard {
if (!found) return;

if (PurchaseProcessing.METHOD_ETH() != method) {
if (rates.getTokenAddress(method) == address(0)) {
if (!rates.isToken(method)) {
return;
}
}
Expand All @@ -473,6 +476,33 @@ contract W12Crowdsale is Versionable, IW12Crowdsale, Ownable, ReentrancyGuard {
);
}

function getInvoiceByTokenAmount(bytes32 method, uint tokenAmount) public view returns (uint[4]) {
(uint index, bool found) = getCurrentStageIndex();

if (!found) return;

if (PurchaseProcessing.METHOD_ETH() != method) {
if (!rates.isToken(method)) {
return;
}
}

return PurchaseProcessing.invoiceByTokenAmount(
method,
tokenAmount,
stages[index].discount,
stages[index].volumeBoundaries,
stages[index].volumeBonuses,
rates.get(method),
price,
uint(token.decimals()),
PurchaseProcessing.METHOD_ETH() == method
? 18
: uint(DetailedERC20(rates.getTokenAddress(method)).decimals()),
token.balanceOf(address(this))
);
}

function getFee(uint tokenAmount, uint cost) public view returns(uint[2]) {
return PurchaseProcessing.fee(tokenAmount, cost, serviceFee, WTokenSaleFeePercent);
}
Expand Down
89 changes: 87 additions & 2 deletions contracts/libs/PurchaseProcessing.sol
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,14 @@ library PurchaseProcessing {

function checkInvoiceInput(
bytes32 method,
uint paymentAmount,
uint amount,
uint methodUSDRate,
uint tokenUSDRate,
uint currentBalanceInTokens,
uint tokenDecimals,
uint methodDecimals
) internal pure returns(bool result) {
result = paymentAmount > 0
result = amount > 0
&& methodUSDRate > 0
&& tokenUSDRate > 0
&& currentBalanceInTokens >= 10 ** tokenDecimals;
Expand Down Expand Up @@ -130,6 +130,91 @@ library PurchaseProcessing {
result[3] = paymentAmount.sub(result[1]);
}

/**
* @notice Generate invoice by token amount
* @dev 1 USD = 10^8. In this case precision will be up to 10^8 decimals after point
* @param method Payment method
* @param tokenAmount Token amount
* @param discount Discount percent
* @param volumeBoundaries Volume boundaries to calculate bonus
* @param volumeBonuses List of bonuses bound to boundaries
* @param methodUSDRate Payment method rate in USD
* @param tokenUSDRate Token rate in USD
* @param tokenDecimals Token decimal
* @param methodDecimals Method decimal. N for token, 18 for ETH
* @param currentBalanceInTokens Current balance in tokens
* @return uint[4] result Invoice calculation result:
*
* [tokenAmount, cost, costUSD, change, actualTokenPriceUSD]
*
* [0] tokenAmount - amount of token to buy
* [1] cost - cost in method currency
* [2] costUSD cost in USD
* [3] actualTokenPriceUSD - actual token price in USD(with discount)
*/
function invoiceByTokenAmount(
bytes32 method,
uint tokenAmount,
uint discount,
uint[] volumeBoundaries,
uint[] volumeBonuses,
uint methodUSDRate,
uint tokenUSDRate,
uint tokenDecimals,
uint methodDecimals,
uint currentBalanceInTokens
)
internal view returns (uint[4] result)
{
require(checkInvoiceInput(
method,
tokenAmount,
methodUSDRate,
tokenUSDRate,
currentBalanceInTokens,
tokenDecimals,
methodDecimals
));

if (currentBalanceInTokens < tokenAmount) {
tokenAmount = currentBalanceInTokens;
}

// tokens
result[0] = tokenAmount;

// priceUSD
result[3] = discount > 0
? tokenUSDRate.percent(Percent.MAX() - discount)
: tokenUSDRate;

// costUSD
result[2] = Utils.safeConversionByRate(
tokenAmount,
tokenDecimals,
result[3]
);

// min costUSD = tokenUSDRate
require(result[2] >= tokenUSDRate);

uint bonus = getBonus(result[2], volumeBoundaries, volumeBonuses);

result[1] = Utils.safeReverseConversionByRate(
result[2],
methodDecimals,
methodUSDRate.safePercent(Percent.MAX().add(bonus))
);

// reset if cost is zero
if (result[1] == 0) {
result[0] = 0;
result[1] = 0;
result[2] = 0;
return;
}
}

function fee(uint tokenAmount, uint cost, uint tokenFee, uint purchaseFee) internal pure returns(uint[2] result) {
if (tokenFee > 0) result[0] = tokenAmount.safePercent(tokenFee);
if (purchaseFee > 0) result[1] = cost.safePercent(purchaseFee);
Expand Down
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "w12-product-contracts",
"version": "0.26.0",
"version": "0.27.0",
"description": "W12 is an open protocol for the creation of DAOs. The protocol consists of smart contract templates (no programming skills required), DAO governance and a decentralized oracles network that controls execution of the project roadmap and milestones.",
"keywords": [
"w12",
Expand Down

0 comments on commit 5ab5b30

Please sign in to comment.