Using Truffle, I am trying to deploy the following contract:
pragma solidity ^0.4.13;
contract ERC20Events {
event Approval(address indexed src, address indexed guy, uint wad);
event Transfer(address indexed src, address indexed dst, uint wad);
}
contract ERC20 is ERC20Events {
function totalSupply() public view returns (uint);
function balanceOf(address guy) public view returns (uint);
function allowance(address src, address guy) public view returns (uint);
function approve(address guy, uint wad) public returns (bool);
function transfer(address dst, uint wad) public returns (bool);
function transferFrom(
address src, address dst, uint wad
) public returns (bool);
}
contract TimedChest {
/** The address allowed to do withdraws */
address public withdrawer;
/** Owner / creator of the contract */
address public owner;
/** Address of the token we're time-locking */
ERC20 public token;
// CryptoHuntToken public token;
// StandardToken public token;
/** Times at which specific amount becomes available */
uint[] public releaseTimes;
/** List of amounts which can be withdrawn after a specific timestamp */
uint[] public amounts;
modifier onlyAfter(uint _time) {
require(now >= _time);
_;
}
modifier onlyBy(address _account) {
require(msg.sender == _account);
_;
}
function changeOwner(address _newOwner) public onlyBy(owner) {
owner = _newOwner;
}
function TimedChest(uint[] _releaseDelays, uint[] _amounts, address _withdrawer, address _tokenAddress) public {
owner = msg.sender;
require (address(_tokenAddress) != 0x0);
require (address(_withdrawer) != 0x0);
require (_releaseDelays.length == _amounts.length && _releaseDelays.length > 0);
for (uint8 i = 0; i < _releaseDelays.length; i++) {
require(_releaseDelays[i] > now);
require(_amounts[i] > 0);
if (i == 0) {
releaseTimes[i] = now + _releaseDelays[i];
} else {
releaseTimes[i] = releaseTimes[i-1] + _releaseDelays[i];
}
}
releaseTimes = _releaseDelays;
amounts = _amounts;
withdrawer = _withdrawer;
token = ERC20(_tokenAddress);
// token = CryptoHuntToken(_tokenAddress);
// token = StandardToken(_tokenAddress);
}
function withdraw() onlyBy(withdrawer) external {
uint256 amount = token.balanceOf(this);
require (amount > 0);
for (uint8 i = 0; i < releaseTimes.length; i++) {
if (releaseTimes[i] < now && amounts[i] > 0) {
token.transfer(withdrawer, amounts[i]);
}
}
}
function withdrawAll() onlyBy(owner) external {
uint256 amount = token.balanceOf(this);
require (amount > 0);
token.transfer(owner, amount);
}
}
This should allow an initial list of release delays and amounts to be specified on deployment, along with sending any ERC20 token to this contract and a withdrawer. The withdrawer can call withdraw after specific time has elapsed and withdraw the allocated amount for that timeframe. It's like periodic vesting for any pre-deployed token.
I'm getting the error:
Error encountered, bailing. Network state unknown. Review successful transactions manually.
Error: The contract code couldn't be stored, please check your gas amount.
After searching far and wide, I've tested many theories - deploying an abstract contract is a problem (to test this, I changed all ERC20 interface methods to stubs, replacing ;
with {}
, gas limit is the problem, truffle version is the problem (tried downgrading) to no avail.
What could be the problem, or where can I find out a more specific error message?
Edit:
It would appear constructors are not very fond of loops. Moving loops out of there made it work. I'm investigating further to get to the bottom of this specific error and find out why it's occurring.