I'm trying to write an extension of OpenZeppelin's CappedCrowdsale to allow for a hard cap in USD, as I think this is more human-readable than having everything in wei.
However, I'm having issues updating some of the inherited state variables (Crowdsale's rate
and CappedCrowdsale's cap
). I try to do this in the updateEthPrice
function, which I know is getting called because the ethPriceInDollars
variable gets updated correctly, but cap and rate
always return 1... (which is what they were initialized with)
At first I thought that maybe the inherited constructors were firing after the base constructor (and overriding whatever I set in the base constructor), but even if I call updateEthPrice
once the contract has been deployed, I'm still not seeing any changes to cap
and rate
Been banging my head on this all day, any help is appreciated!
pragma solidity ^0.4.19;
import "zeppelin-solidity/contracts/crowdsale/CappedCrowdsale.sol";
/**
* @title DollarCappedCrowdsale
* @author Gianni Settino
* @dev Extension of CappedCrowdsale with a cap in USD instead of wei.
* This means that Crowdsale's rate and CappedCrowdsale's cap now depend
* on ETH's USD price, which can be changed up until the start of the token sale.
*/
contract DollarCappedCrowdsale is CappedCrowdsale(1), Ownable {
uint256 public ethPriceInDollars;
uint256 public hardCapInDollars;
uint256 public tokenPriceInCents;
// @dev We temporarily init Crowdsale's rate and CappedCrowdsale's cap to 1.
// Reason: their "real" values are subsequently calculated in updateEthPrice()
function DollarCappedCrowdsale(
uint256 _startTime,
uint256 _endTime,
address _wallet,
uint256 _ethPriceInDollars,
uint256 _hardCapInDollars,
uint256 _tokenPriceInCents
)
public
Crowdsale(_startTime, _endTime, 1, _wallet)
{
require(_hardCapInDollars > 0);
require(_tokenPriceInCents > 0);
hardCapInDollars = _hardCapInDollars;
tokenPriceInCents = _tokenPriceInCents;
updateEthPrice(_ethPriceInDollars);
}
function updateEthPrice(uint256 _ethPriceInDollars) public onlyOwner {
require(now < startTime);
require(_ethPriceInDollars > 0);
ethPriceInDollars = _ethPriceInDollars;
cap = (hardCapInDollars / ethPriceInDollars).mul(1 ether);
rate = (ethPriceInDollars.mul(100)) / tokenPriceInCents;
}
}
cap = (hardCapInDollars / ethPriceInDollars).mul(1 ether)
, depending on the values the division will truncate and loss presicion, a alternative is to first multiplycap = hardCapInDollars.mul(1 ether) / ethPriceInDollars
.DollarCappedCrowdsale(START_TIME, START_TIME.add(LENGTH_IN_SEC), msg.sender, _ethPriceInDollars, HARD_CAP_IN_DOLLARS, TOKEN_PRICE_IN_CENTS)
where START_TIME = 1519603200, LENGTH_IN_SEC = 7 days, _ethPriceInDollars = 870 (passed when we deploy the contract), HARD_CAP_IN_DOLLARS = 40000000, and TOKEN_PRICE_IN_CENTS = 10