How to add a uint T in constructor that will be a time constant inside my smart contract? - ethereum

I need a time constant to calculate timestamps for deposit, withdrawal, and reward sub-pools. this time constant called T will start from contract deployment and will not be specific to one address/user. I.e rewards(R) are divided into 3 sub-pools: R1 = 20% available after 2T has passed since contract deployment, R2 = 30% available after 3T has passed since contract deployment, R3= 50% available after 4T has passed since contract deployment. I need this variable to be in minutes, for example, sender inputs 3 I want the time between each timestamp to be 3, like deposit in the first T, withdrawal after 3T. How to set it in minutes?
Here is the state variable
uint256 public T;
Here is the constructor
constructor(address stakingToken, address rewardsToken, uint256 timeConstant) {
s_stakingToken = IERC20(stakingToken);
s_rewardsToken = IERC20(rewardsToken);
initialTime = block.timestamp;
T = timeConstant;
}
My full code
error TransferFailed();
error NeedsMoreThanZero();
contract Staking is ReentrancyGuard {
IERC20 public s_rewardsToken;
IERC20 public s_stakingToken;
// This is the reward token per seco
nd
// Which will be multiplied by the tokens the user staked divided by the total
// This ensures a steady reward rate of the platform
// So the more users stake, the less for everyone who is staking.
uint256 public constant REWARD_RATE = 100;
uint256 public s_lastUpdateTime;
uint256 public s_rewardPerTokenStored;
//uint256 public constant T = 3;
uint256 public initialTime;
uint256 public T;
mapping(address => uint256) public s_userRewardPerTokenPaid;
mapping(address => uint256) public s_rewards;
uint256 private s_totalSupply;
mapping(address => uint256) public s_balances; // someones address => how much he staked
event Staked(address indexed user, uint256 indexed amount);
event WithdrewStake(address indexed user, uint256 indexed amount);
event RewardsClaimed(address indexed user, uint256 indexed amount);
constructor(address stakingToken, address rewardsToken, uint256 timeConstant) {
s_stakingToken = IERC20(stakingToken);
s_rewardsToken = IERC20(rewardsToken);
initialTime = block.timestamp;
T = timeConstant;
}
/**
* #notice How much reward a token gets based on how long it's been in and during which "snapshots"
*/
function rewardPerToken() public view returns (uint256) {
if (s_totalSupply == 0) {
return s_rewardPerTokenStored;
}
return
s_rewardPerTokenStored +
(((block.timestamp - s_lastUpdateTime) * REWARD_RATE * 1e18) / s_totalSupply);
}
/**
* #notice How much reward a user has earned
*/
function earned(address account) public view returns (uint256) {
uint256 nowTime = block.timestamp-initialTime;
require(nowTime > 2*T);
if (nowTime > 2*T && nowTime <= 3*T) {
return
((((s_balances[account] * (rewardPerToken() - s_userRewardPerTokenPaid[account])) /
1e18) + s_rewards[account]) / 5 );
} else if
(nowTime > 3*T && nowTime <= 4*T) {
return
((((s_balances[account] * (rewardPerToken() - s_userRewardPerTokenPaid[account])) /
1e18) + s_rewards[account]) / 2 );
} else {
return
(((s_balances[account] * (rewardPerToken() - s_userRewardPerTokenPaid[account])) /
1e18) + s_rewards[account]);
}
}
/**
* #notice Deposit tokens into this contract
* #param amount | How much to stake
*/
function stake(uint256 amount)
external
updateReward(msg.sender)
nonReentrant
moreThanZero(amount)
{
//from T0 to T deposit is available
uint256 nowTime = block.timestamp-initialTime; // time between deployment of contract and now.
require(nowTime < T);
s_totalSupply += amount;
// increasing how much they are staking for how much they staked each time.
s_balances[msg.sender] += amount;
emit Staked(msg.sender, amount);
// sending an amount of token from an address to this contract
bool success = s_stakingToken.transferFrom(msg.sender, address(this), amount);
// if not successfully sent, return an error.
// using the below code instead of "require(success, "Failed")" reduces gas fees, since it doesn't output a string.
if (!success) {
revert TransferFailed(); // revert resets everything done in a failed transaction.
}
}
/**
* #notice Withdraw tokens from this contract
* #param amount | How much to withdraw
*/
function withdraw(uint256 amount) external updateReward(msg.sender) nonReentrant {
// from 2T the user can reward his tokens
uint256 nowTime = block.timestamp-initialTime; // time between deployment of contract and now.
require(nowTime > 2* T);
s_totalSupply -= amount;
s_balances[msg.sender] -= amount;
emit WithdrewStake(msg.sender, amount);
// transfer: send tokens from contract back to msg.sender.
bool success = s_stakingToken.transfer(msg.sender, amount);
if (!success) {
revert TransferFailed(); // revert resets everything done in a failed transaction.
}
}
/**
* #notice User claims their tokens
*/
function claimReward() external updateReward(msg.sender) nonReentrant {
uint256 reward = s_rewards[msg.sender];
s_rewards[msg.sender] = 0;
emit RewardsClaimed(msg.sender, reward);
bool success = s_rewardsToken.transfer(msg.sender, reward);
if (!success) {
revert TransferFailed(); // revert resets everything done in a failed transaction.
}
}
/********************/
/* Modifiers Functions */
/********************/
modifier updateReward(address account) {
s_rewardPerTokenStored = rewardPerToken();
s_lastUpdateTime = block.timestamp;
s_rewards[account] = earned(account);
s_userRewardPerTokenPaid[account] = s_rewardPerTokenStored;
_;
}
modifier moreThanZero(uint256 amount) {
if (amount == 0) {
revert NeedsMoreThanZero();
}
_;
}
/********************/
/* Getter Functions */
/********************/
// Ideally, we'd have getter functions for all our s_ variables we want exposed, and set them all to private.
// But, for the purpose of this demo, we've left them public for simplicity.
function getStaked(address account) public view returns (uint256) {
return s_balances[account];
}
}

Firstly maintain a map for storing the time for each user. Then make functions like depositTimeSet , withdrawalTimeSet for storing different time for different user. While despositing update the variable and while withdraw check the time has exceed or not.
struct Users {
uint dipositTime;
uint withDrawTime;
uint lastDepositTime;
}
mapping(address => Users ) users;
function depositeTimeSet(uint t) {
users[msg.sender].dipositTime = t minutes;
withdrawalTimeSet(t);
}
function withdrawalTimeSet(uint t) {
users[msg.sender].withDrawTime = 3 * t minutes
}
function deposite() {
transferFrom(msg.sender,address(this));
depositeTimeSet(3); // considering sender send 3
users[msg.sender].lastDepositTime = now;
}
function withdraw() {
if(
now > users[msg.sender].lastDepositTime +
users[msg.sender].withDrawTime,"too early for withdraw
request"
)
transferFrom(address(this),msg.sender);
}
You can see THIS one might be helpful
You can see THIS resource for time unit in solidity

Related

How to send correctly ETH from the manager's deposit to user if an event occurs?

I have this smart contract that I am trying to test. The manager deposits a certain amount of ether. Users can use the vault to earn extra ethers by locking own ether. Users deposit the amount of ether they want (ex 0.10 ETH) and set the seconds for locking. When users deposit, the price of ethereum is recorded via chainlink. If at the end of the locking period the price of ethereum is less than 2000$ the user receives the amount of locked ETH (0.10 ETH) + 2x (0.20ETH) the amount of locked ethers. The extra ethers are taken from the manager's deposit.
The code seems to work fine and the console returns no errors. I am testing the smart contract on the Kovan network. The problem is encountered when the user tries to withdraw the ethereums. When he withdraws, only the deposited ones are returned without the extra ethers being added.
I am new to Solidity so I appreciate any criticism or advice. If there is something already existing similar to what I am trying to create please let me know.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.6;
import "#chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol";
interface EACAggregatorProxy {
function latestAnswer() external view returns (int256);
}
contract oracleLink {
address public manager;
uint256 public managerDeposit;
uint256[] public managerDeposits;
constructor() payable {
manager = msg.sender;
managerDeposit = msg.value;
managerDeposits.push(managerDeposit);
}
function depositVault() public payable {
require(msg.sender == manager);
}
address public user;
uint256 public userContribution;
uint256 public userCount;
uint256 deadline;
uint256 lockAmount = lockAmounts[msg.sender];
mapping(address => uint) lockAmounts;
uint256 startTime = startTimes[block.timestamp];
mapping(uint => uint) startTimes;
address public chainLinkETHUSDAddress = 0x9326BFA02ADD2366b30bacB125260Af641031331;
uint public ethPrice = 0;
uint256 public price = ethPrice;
function deposit(uint256 numberOfSeconds) public payable {
lockAmounts[msg.sender] = msg.value;
startTimes[block.timestamp] = block.timestamp;
user = msg.sender;
userContribution = msg.value;
userCount++;
deadline = block.timestamp + (numberOfSeconds * 1 seconds);
int256 chainLinkEthPrice = EACAggregatorProxy(chainLinkETHUSDAddress).latestAnswer();
ethPrice = uint(chainLinkEthPrice / 100000000);
}
function withdraw() public payable {
if (ethPrice <= 2000) {
uint256 toWithdraw = lockAmounts[msg.sender];
uint256 amountOfToken = toWithdraw * 2;
payable(manager).transfer(amountOfToken);
}
require(block.timestamp >= deadline);
uint256 amountToWithdraw = lockAmounts[msg.sender];
lockAmounts[msg.sender] = 0;
payable(msg.sender).transfer(amountToWithdraw);
}
}
So the one thing that I noticed is that when you try to send the additional ETH to the recipient's address you're actually trying to send it back to the manager and not the recipient. Also note that you should avoid using the transfer method and use the call method instead: call{value: amount}("") should now be used for transferring ether (Do not use send or transfer.) as of May 2021.
So your withdraw method should look something like this instead:
function withdraw() public payable {
address recipient = msg.sender;
uint256 additionalToken;
if (ethPrice <= 2000) {
additionalToken = lockAmounts[msg.sender] * 2;
}
require(block.timestamp >= deadline);
uint256 amountToWithdraw = lockAmounts[msg.sender] + additionalToken;
lockAmounts[msg.sender] = 0;
(bool success, ) = payable(recipient).call{value: amountToWithdraw}("");
require(success, "Transfer failed.");
}
Hopefully this helps.

I am not being able to understand the constructor function of the given smart contracts

In the smart contract code below, there is a function being executed inside the constructor function. Can anyone please explain what is happening in the constructor?
pragma solidity 0.8.7;
import "../interfaces/IAbstractRewards.sol";
import "#openzeppelin/contracts/utils/math/SafeCast.sol";
/**
* #dev Based on: https://github.com/indexed-finance/dividends/blob/master/contracts/base/AbstractDividends.sol
* Renamed dividends to rewards.
* #dev (OLD) Many functions in this contract were taken from this repository:
* https://github.com/atpar/funds-distribution-token/blob/master/contracts/FundsDistributionToken.sol
* which is an example implementation of ERC 2222, the draft for which can be found at
* https://github.com/atpar/funds-distribution-token/blob/master/EIP-DRAFT.md
*
* This contract has been substantially modified from the original and does not comply with ERC 2222.
* Many functions were renamed as "rewards" rather than "funds" and the core functionality was separated
* into this abstract contract which can be inherited by anything tracking ownership of reward shares.
*/
abstract contract AbstractRewards is IAbstractRewards {
using SafeCast for uint128;
using SafeCast for uint256;
using SafeCast for int256;
/* ======== Constants ======== */
uint128 public constant POINTS_MULTIPLIER = type(uint128).max;
/* ======== Internal Function References ======== */
function(address) view returns (uint256) private immutable getSharesOf;
function() view returns (uint256) private immutable getTotalShares;
/* ======== Storage ======== */
uint256 public pointsPerShare;
mapping(address => int256) public pointsCorrection;
mapping(address => uint256) public withdrawnRewards;
constructor(
function(address) view returns (uint256) getSharesOf_,
function() view returns (uint256) getTotalShares_
) {
getSharesOf = getSharesOf_;
getTotalShares = getTotalShares_;
}
/* ======== Public View Functions ======== */
/**
* #dev Returns the total amount of rewards a given address is able to withdraw.
* #param _account Address of a reward recipient
* #return A uint256 representing the rewards `account` can withdraw
*/
function withdrawableRewardsOf(address _account) public view override returns (uint256) {
return cumulativeRewardsOf(_account) - withdrawnRewards[_account];
}
/**
* #notice View the amount of rewards that an address has withdrawn.
* #param _account The address of a token holder.
* #return The amount of rewards that `account` has withdrawn.
*/
function withdrawnRewardsOf(address _account) public view override returns (uint256) {
return withdrawnRewards[_account];
}
/**
* #notice View the amount of rewards that an address has earned in total.
* #dev accumulativeFundsOf(account) = withdrawableRewardsOf(account) + withdrawnRewardsOf(account)
* = (pointsPerShare * balanceOf(account) + pointsCorrection[account]) / POINTS_MULTIPLIER
* #param _account The address of a token holder.
* #return The amount of rewards that `account` has earned in total.
*/
function cumulativeRewardsOf(address _account) public view override returns (uint256) {
return ((pointsPerShare * getSharesOf(_account)).toInt256() + pointsCorrection[_account]).toUint256() / POINTS_MULTIPLIER;
}
/* ======== Dividend Utility Functions ======== */
/**
* #notice Distributes rewards to token holders.
* #dev It reverts if the total shares is 0.
* It emits the `RewardsDistributed` event if the amount to distribute is greater than 0.
* About undistributed rewards:
* In each distribution, there is a small amount which does not get distributed,
* which is `(amount * POINTS_MULTIPLIER) % totalShares()`.
* With a well-chosen `POINTS_MULTIPLIER`, the amount of funds that are not getting
* distributed in a distribution can be less than 1 (base unit).
*/
function _distributeRewards(uint256 _amount) internal {
uint256 shares = getTotalShares();
require(shares > 0, "AbstractRewards._distributeRewards: total share supply is zero");
if (_amount > 0) {
pointsPerShare = pointsPerShare + (_amount * POINTS_MULTIPLIER / shares);
emit RewardsDistributed(msg.sender, _amount);
}
}
/**
* #notice Prepares collection of owed rewards
* #dev It emits a `RewardsWithdrawn` event if the amount of withdrawn rewards is
* greater than 0.
*/
function _prepareCollect(address _account) internal returns (uint256) {
uint256 _withdrawableDividend = withdrawableRewardsOf(_account);
if (_withdrawableDividend > 0) {
withdrawnRewards[_account] = withdrawnRewards[_account] + _withdrawableDividend;
emit RewardsWithdrawn(_account, _withdrawableDividend);
}
return _withdrawableDividend;
}
function _correctPointsForTransfer(address _from, address _to, uint256 _shares) internal {
int256 _magCorrection = (pointsPerShare * _shares).toInt256();
pointsCorrection[_from] = pointsCorrection[_from] + _magCorrection;
pointsCorrection[_to] = pointsCorrection[_to] - _magCorrection;
}
/**
* #dev Increases or decreases the points correction for `account` by
* `shares*pointsPerShare`.
*/
function _correctPoints(address _account, int256 _shares) internal {
pointsCorrection[_account] = pointsCorrection[_account] + (_shares * (int256(pointsPerShare)));
}
}
Now, in the smart contract below (BasePool), it inherits the above AbstractRewards smart contract. In the constructor of the BasePool contract how is balanceOf and totalSupply being passed to the AbstractRewards contract?
abstract contract BasePool is ERC20Votes, AbstractRewards, IBasePool, TokenSaver {
using SafeERC20 for IERC20;
using SafeCast for uint256;
using SafeCast for int256;
IERC20 public immutable depositToken;
IERC20 public immutable rewardToken;
ITimeLockPool public immutable escrowPool;
uint256 public immutable escrowPortion; // how much is escrowed 1e18 == 100%
uint256 public immutable escrowDuration; // escrow duration in seconds
event RewardsClaimed(address indexed _from, address indexed _receiver, uint256 _escrowedAmount, uint256 _nonEscrowedAmount);
constructor(
string memory _name,
string memory _symbol,
address _depositToken,
address _rewardToken,
address _escrowPool,
uint256 _escrowPortion,
uint256 _escrowDuration
) ERC20Permit(_name) ERC20(_name, _symbol) AbstractRewards(balanceOf, totalSupply) {
require(_escrowPortion <= 1e18, "BasePool.constructor: Cannot escrow more than 100%");
require(_depositToken != address(0), "BasePool.constructor: Deposit token must be set");
depositToken = IERC20(_depositToken);
rewardToken = IERC20(_rewardToken);
escrowPool = ITimeLockPool(_escrowPool);
escrowPortion = _escrowPortion;
escrowDuration = _escrowDuration;
if(_rewardToken != address(0) && _escrowPool != address(0)) {
IERC20(_rewardToken).safeApprove(_escrowPool, type(uint256).max);
}
}
function _mint(address _account, uint256 _amount) internal virtual override {
super._mint(_account, _amount);
_correctPoints(_account, -(_amount.toInt256()));
}
function _burn(address _account, uint256 _amount) internal virtual override {
super._burn(_account, _amount);
_correctPoints(_account, _amount.toInt256());
}
function _transfer(address _from, address _to, uint256 _value) internal virtual override {
super._transfer(_from, _to, _value);
_correctPointsForTransfer(_from, _to, _value);
}
function distributeRewards(uint256 _amount) external override {
rewardToken.safeTransferFrom(_msgSender(), address(this), _amount);
_distributeRewards(_amount);
}
function claimRewards(address _receiver) external {
uint256 rewardAmount = _prepareCollect(_msgSender());
uint256 escrowedRewardAmount = rewardAmount * escrowPortion / 1e18;
uint256 nonEscrowedRewardAmount = rewardAmount - escrowedRewardAmount;
if(escrowedRewardAmount != 0 && address(escrowPool) != address(0)) {
escrowPool.deposit(escrowedRewardAmount, escrowDuration, _receiver);
}
// ignore dust
if(nonEscrowedRewardAmount > 1) {
rewardToken.safeTransfer(_receiver, nonEscrowedRewardAmount);
}
emit RewardsClaimed(_msgSender(), _receiver, escrowedRewardAmount, nonEscrowedRewardAmount);
}
}
Constructor is a function to run at first, when smart contract is deploied and call.
If constructor has a prameter, you have to set them.
And if prameter include other smart contract's addresses, it have to be deploied before.

Retrieve stuck ether on smart contract

Is there any way to recover ether that is stuck in a smart contract?
refundMoney() method was supposed to call only after everything is finalized but because someone has transferred some ether amount from an exchange wallet and we had to refund that. Now the weiRaised variable is showing more value than the smart contract currently have.
Here is the live contract deployed with source code
https://etherscan.io/address/0x7ff0b2afa427507a50ed4f82231b2b8a972fdff1
pragma solidity ^0.4.19;
contract Ownable {
address public owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
constructor() public { owner = msg.sender; }
modifier onlyOwner() {
address sender = msg.sender;
address _owner = owner;
require(msg.sender == _owner);
_;
}
function transferOwnership(address newOwner) onlyOwner public {
require(newOwner != address(0));
emit OwnershipTransferred(owner, newOwner);
owner = newOwner;
}
}
library SafeMath {
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a * b;
assert(a == 0 || c / a == b);
return c;
}
function div(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a / b;
// assert(a == b * c + a % b); // There is no case in which this doesn't hold
return c;
}
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
assert(b <= a);
return a - b;
}
function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b;
assert(c >= a);
return c;
}
}
contract ERC20Basic {
uint256 public totalSupply;
function balanceOf(address who) public constant returns (uint256);
function transfer(address to, uint256 value) public returns (bool);
event Transfer(address indexed from, address indexed to, uint256 value);
}
/**
* #title ERC20 interface
* #dev see https://github.com/ethereum/EIPs/issues/20
*/
contract ERC20 is ERC20Basic {
function allowance(address owner, address spender) public constant returns (uint256);
function transferFrom(address from, address to, uint256 value) public returns (bool);
function approve(address spender, uint256 value) public returns (bool);
event Approval(address indexed owner, address indexed spender, uint256 value);
}
contract BasicToken is ERC20Basic {
using SafeMath for uint256;
mapping(address => uint256) balances;
/**
* #dev transfer token for a specified address
* #param _to The address to transfer to.
* #param _value The amount to be transferred.
*/
function transfer(address _to, uint256 _value) public returns (bool) {
require(_to != address(0));
// SafeMath.sub will throw if there is not enough balance.
balances[msg.sender] = balances[msg.sender].sub(_value);
balances[_to] = balances[_to].add(_value);
emit Transfer(msg.sender, _to, _value);
return true;
}
/**
* #dev Gets the balance of the specified address.
* #param _owner The address to query the the balance of.
* #return An uint256 representing the amount owned by the passed address.
*/
function balanceOf(address _owner) public constant returns (uint256 balance) {
return balances[_owner];
}
}
/**
* #title Standard ERC20 token
*
* #dev Implementation of the basic standard token.
* #dev https://github.com/ethereum/EIPs/issues/20
* #dev Based on code by FirstBlood: https://github.com/Firstbloodio/token/blob/master/smart_contract/FirstBloodToken.sol
*/
contract StandardToken is ERC20, BasicToken {
mapping (address => mapping (address => uint256)) allowed;
/**
* #dev Transfer tokens from one address to another
* #param _from address The address which you want to send tokens from
* #param _to address The address which you want to transfer to
* #param _value uint256 the amount of tokens to be transferred
*/
function transferFrom(address _from, address _to, uint256 _value) public returns (bool) {
require(_to != address(0));
uint256 _allowance = allowed[_from][msg.sender];
balances[_from] = balances[_from].sub(_value);
balances[_to] = balances[_to].add(_value);
allowed[_from][msg.sender] = _allowance.sub(_value);
emit Transfer(_from, _to, _value);
return true;
}
/**
* #dev Approve the passed address to spend the specified amount of tokens on behalf of msg.sender.
*
* Beware that changing an allowance with this method brings the risk that someone may use both the old
* and the new allowance by unfortunate transaction ordering. One possible solution to mitigate this
* race condition is to first reduce the spender's allowance to 0 and set the desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
* #param _spender The address which will spend the funds.
* #param _value The amount of tokens to be spent.
*/
function approve(address _spender, uint256 _value) public returns (bool) {
allowed[msg.sender][_spender] = _value;
emit Approval(msg.sender, _spender, _value);
return true;
}
/**
* #dev Function to check the amount of tokens that an owner allowed to a spender.
* #param _owner address The address which owns the funds.
* #param _spender address The address which will spend the funds.
* #return A uint256 specifying the amount of tokens still available for the spender.
*/
function allowance(address _owner, address _spender) public constant returns (uint256 remaining) {
return allowed[_owner][_spender];
}
/**
* approve should be called when allowed[_spender] == 0. To increment
* allowed value is better to use this function to avoid 2 calls (and wait until
* the first transaction is mined)
* From MonolithDAO Token.sol
*/
function increaseApproval (address _spender, uint _addedValue) public returns (bool success) {
allowed[msg.sender][_spender] = allowed[msg.sender][_spender].add(_addedValue);
emit Approval(msg.sender, _spender, allowed[msg.sender][_spender]);
return true;
}
function decreaseApproval (address _spender, uint _subtractedValue) public returns (bool success) {
uint oldValue = allowed[msg.sender][_spender];
if (_subtractedValue > oldValue) {
allowed[msg.sender][_spender] = 0;
} else {
allowed[msg.sender][_spender] = oldValue.sub(_subtractedValue);
}
emit Approval(msg.sender, _spender, allowed[msg.sender][_spender]);
return true;
}
}
contract MintableToken is StandardToken, Ownable {
event Mint(address indexed to, uint256 amount);
event MintFinished();
bool public mintingFinished = false;
modifier canMint() {
require(!mintingFinished);
_;
}
/**
* #dev Function to mint tokens
* #param _to The address that will receive the minted tokens.
* #param _amount The amount of tokens to mint.
* #return A boolean that indicates if the operation was successful.
*/
function mint(address _to, uint256 _amount) onlyOwner canMint public returns (bool) {
totalSupply = totalSupply.add(_amount);
balances[_to] = balances[_to].add(_amount);
emit Mint(_to, _amount);
emit Transfer(0x0, _to, _amount);
return true;
}
/**
* #dev Function to mint tokens
* #param _to The address that will receive the minted tokens.
* #param _amount The amount of tokens to mint.
* #return A boolean that indicates if the operation was successful.
*/
function mintFinalize(address _to, uint256 _amount) onlyOwner canMint public returns (bool) {
totalSupply = totalSupply.add(_amount);
balances[_to] = balances[_to].add(_amount);
emit Mint(_to, _amount);
emit Transfer(0x0, _to, _amount);
return true;
}
/**
* #dev Function to stop minting new tokens.
* #return True if the operation was successful.
*/
function finishMinting() onlyOwner public returns (bool) {
mintingFinished = true;
emit MintFinished();
return true;
}
}
/**
* #title SwordToken
* #dev Sword ERC20 Token that can be minted.
* It is meant to be used in Sword crowdsale contract.
*/
contract SwordToken is MintableToken {
string public constant name = "Sword Coin";
string public constant symbol = "SWDC";
uint8 public constant decimals = 18;
function getTotalSupply() view public returns (uint256) {
return totalSupply;
}
function transfer(address _to, uint256 _value) public returns (bool) {
super.transfer(_to, _value);
}
}
contract KycContractInterface {
function isAddressVerified(address _address) public view returns (bool);
}
contract KycContract is Ownable {
mapping (address => bool) verifiedAddresses;
function isAddressVerified(address _address) public view returns (bool) {
return verifiedAddresses[_address];
}
function addAddress(address _newAddress) public onlyOwner {
require(!verifiedAddresses[_newAddress]);
verifiedAddresses[_newAddress] = true;
}
function removeAddress(address _oldAddress) public onlyOwner {
require(verifiedAddresses[_oldAddress]);
verifiedAddresses[_oldAddress] = false;
}
function batchAddAddresses(address[] _addresses) public onlyOwner {
for (uint cnt = 0; cnt < _addresses.length; cnt++) {
assert(!verifiedAddresses[_addresses[cnt]]);
verifiedAddresses[_addresses[cnt]] = true;
}
}
}
/**
* #title SwordCrowdsale
* #dev This is Sword's crowdsale contract.
*/
contract SwordCrowdsale is Ownable {
using SafeMath for uint256;
// start and end timestamps where investments are allowed (both inclusive)
uint256 public startTime;
uint256 public endTime;
// amount of raised money in wei
uint256 public weiRaised;
uint256 public limitDateSale; // end date in units
bool public isSoftCapHit = false;
bool public isStarted = false;
bool public isFinalized = false;
struct ContributorData {
uint256 contributionAmount;
uint256 tokensIssued;
}
address[] public tokenSendFailures;
mapping(address => ContributorData) public contributorList;
mapping(uint => address) contributorIndexes;
uint nextContributorIndex;
constructor() public {}
function init(uint256 _totalTokens, uint256 _tokensForCrowdsale, address _wallet,
uint256 _etherInUSD, address _tokenAddress, uint256 _softCapInEthers, uint256 _hardCapInEthers,
uint _saleDurationInDays, address _kycAddress, uint bonus) onlyOwner public {
setTotalTokens(_totalTokens);
setTokensForCrowdSale(_tokensForCrowdsale);
setWallet(_wallet);
setRate(_etherInUSD);
setTokenAddress(_tokenAddress);
setSoftCap(_softCapInEthers);
setHardCap(_hardCapInEthers);
setSaleDuration(_saleDurationInDays);
setKycAddress(_kycAddress);
setSaleBonus(bonus);
kyc = KycContract(_kycAddress);
start(); // starting the crowdsale
}
/**
* #dev Must be called to start the crowdsale
*/
function start() onlyOwner public {
require(!isStarted);
require(!hasStarted());
require(wallet != address(0));
require(tokenAddress != address(0));
require(kycAddress != address(0));
require(rate != 0);
require(saleDuration != 0);
require(totalTokens != 0);
require(tokensForCrowdSale != 0);
require(softCap != 0);
require(hardCap != 0);
starting();
emit SwordStarted();
isStarted = true;
}
uint256 public totalTokens = 0;
function setTotalTokens(uint256 _totalTokens) onlyOwner public {
totalTokens = _totalTokens * (10 ** 18); // Total 1 billion tokens, 75 percent will be sold
}
uint256 public tokensForCrowdSale = 0;
function setTokensForCrowdSale(uint256 _tokensForCrowdsale) onlyOwner public {
tokensForCrowdSale = _tokensForCrowdsale * (10 ** 18); // Total 1 billion tokens, 75 percent will be sold
}
// address where funds are collected
address public wallet = 0x0;
function setWallet(address _wallet) onlyOwner public {
wallet = _wallet;
}
uint256 public rate = 0;
function setRate(uint256 _etherInUSD) public onlyOwner{
rate = (5 * (10**18) / 100) / _etherInUSD;
}
// The token being sold
SwordToken public token;
address tokenAddress = 0x0;
function setTokenAddress(address _tokenAddress) public onlyOwner {
tokenAddress = _tokenAddress; // to check if token address is provided at start
token = SwordToken(_tokenAddress);
}
uint256 public softCap = 0;
function setSoftCap(uint256 _softCap) onlyOwner public {
softCap = _softCap * (10 ** 18);
}
uint256 public hardCap = 0;
function setHardCap(uint256 _hardCap) onlyOwner public {
hardCap = _hardCap * (10 ** 18);
}
// sale period (includes holidays)
uint public saleDuration = 0; // in days ex: 60.
function setSaleDuration(uint _saleDurationInDays) onlyOwner public {
saleDuration = _saleDurationInDays;
limitDateSale = startTime + (saleDuration * 1 days);
endTime = limitDateSale;
}
address kycAddress = 0x0;
function setKycAddress(address _kycAddress) onlyOwner public {
kycAddress = _kycAddress;
}
uint public saleBonus = 0; // ex. 10
function setSaleBonus(uint bonus) public onlyOwner{
saleBonus = bonus;
}
bool public isKYCRequiredToReceiveFunds = true; // whether Kyc is required to receive funds.
function setKYCRequiredToReceiveFunds(bool IS_KYCRequiredToReceiveFunds) public onlyOwner{
isKYCRequiredToReceiveFunds = IS_KYCRequiredToReceiveFunds;
}
bool public isKYCRequiredToSendTokens = true; // whether Kyc is required to send tokens.
function setKYCRequiredToSendTokens(bool IS_KYCRequiredToSendTokens) public onlyOwner{
isKYCRequiredToSendTokens = IS_KYCRequiredToSendTokens;
}
// fallback function can be used to buy tokens
function () public payable {
buyTokens(msg.sender);
}
KycContract public kyc;
function transferKycOwnerShip(address _address) onlyOwner public {
kyc.transferOwnership(_address);
}
function transferTokenOwnership(address _address) onlyOwner public {
token.transferOwnership(_address);
}
/**
* release Tokens
*/
function releaseAllTokens() onlyOwner public {
for(uint i=0; i < nextContributorIndex; i++) {
address addressToSendTo = contributorIndexes[i]; // address of user
releaseTokens(addressToSendTo);
}
}
/**
* release Tokens of an individual address
*/
function releaseTokens(address _contributerAddress) onlyOwner public {
if(isKYCRequiredToSendTokens){
if(KycContractInterface(kycAddress).isAddressVerified(_contributerAddress)){ // if kyc needs to be checked at release time
release(_contributerAddress);
}
} else {
release(_contributerAddress);
}
}
function release(address _contributerAddress) internal {
if(contributorList[_contributerAddress].tokensIssued > 0) {
if(token.mint(_contributerAddress, contributorList[_contributerAddress].tokensIssued)) { // tokens sent successfully
contributorList[_contributerAddress].tokensIssued = 0;
contributorList[_contributerAddress].contributionAmount = 0;
} else { // token sending failed, has to be processed manually
tokenSendFailures.push(_contributerAddress);
}
}
}
function tokenSendFailuresCount() public view returns (uint) {
return tokenSendFailures.length;
}
function buyTokens(address beneficiary) public payable {
require(beneficiary != address(0));
require(validPurchase());
if(isKYCRequiredToReceiveFunds){
require(KycContractInterface(kycAddress).isAddressVerified(msg.sender));
}
uint256 weiAmount = msg.value;
// calculate token amount to be created
uint256 tokens = computeTokens(weiAmount);
require(isWithinTokenAllocLimit(tokens));
// update state - Add to eth raised
weiRaised = weiRaised.add(weiAmount);
if (contributorList[beneficiary].contributionAmount == 0) { // if its a new contributor, add him and increase index
contributorIndexes[nextContributorIndex] = beneficiary;
nextContributorIndex += 1;
}
contributorList[beneficiary].contributionAmount += weiAmount;
contributorList[beneficiary].tokensIssued += tokens;
emit SwordTokenPurchase(msg.sender, beneficiary, weiAmount, tokens);
handleFunds();
}
/**
* event for token purchase logging
* #param purchaser who paid for the tokens
* #param beneficiary who got the tokens
* #param value weis paid for purchase
* #param amount amount of tokens purchased
*/
event SwordTokenPurchase(address indexed purchaser, address indexed beneficiary, uint256 value, uint256 amount);
function investorCount() constant public returns(uint) {
return nextContributorIndex;
}
// #return true if crowdsale event has started
function hasStarted() public constant returns (bool) {
return (startTime != 0 && now > startTime);
}
// send ether to the fund collection wallet
function forwardFunds() internal {
wallet.transfer(msg.value);
}
// send ether to the fund collection wallet
function forwardAllRaisedFunds() internal {
wallet.transfer(weiRaised);
}
function isWithinSaleTimeLimit() internal view returns (bool) {
return now <= limitDateSale;
}
function isWithinSaleLimit(uint256 _tokens) internal view returns (bool) {
return token.getTotalSupply().add(_tokens) <= tokensForCrowdSale;
}
function computeTokens(uint256 weiAmount) view internal returns (uint256) {
uint256 appliedBonus = 0;
if (isWithinSaleTimeLimit()) {
appliedBonus = saleBonus;
}
return (weiAmount.div(rate) + (weiAmount.div(rate).mul(appliedBonus).div(100))) * (10 ** 18);
}
function isWithinTokenAllocLimit(uint256 _tokens) view internal returns (bool) {
return (isWithinSaleTimeLimit() && isWithinSaleLimit(_tokens));
}
function didSoftCapReached() internal returns (bool) {
if(weiRaised >= softCap){
isSoftCapHit = true; // setting the flag that soft cap is hit and all funds should be sent directly to wallet from now on.
} else {
isSoftCapHit = false;
}
return isSoftCapHit;
}
// overriding SwordBaseCrowdsale#validPurchase to add extra cap logic
// #return true if investors can buy at the moment
function validPurchase() internal constant returns (bool) {
bool withinCap = weiRaised.add(msg.value) <= hardCap;
bool withinPeriod = now >= startTime && now <= endTime;
bool nonZeroPurchase = msg.value != 0;
return (withinPeriod && nonZeroPurchase) && withinCap && isWithinSaleTimeLimit();
}
// overriding Crowdsale#hasEnded to add cap logic
// #return true if crowdsale event has ended
function hasEnded() public constant returns (bool) {
bool capReached = weiRaised >= hardCap;
return (endTime != 0 && now > endTime) || capReached;
}
event SwordStarted();
event SwordFinalized();
/**
* #dev Must be called after crowdsale ends, to do some extra finalization
* work. Calls the contract's finalization function.
*/
function finalize() onlyOwner public {
require(!isFinalized);
// require(hasEnded());
finalization();
emit SwordFinalized();
isFinalized = true;
}
function starting() internal {
startTime = now;
limitDateSale = startTime + (saleDuration * 1 days);
endTime = limitDateSale;
}
function finalization() internal {
uint256 remainingTokens = totalTokens.sub(token.getTotalSupply());
token.mintFinalize(wallet, remainingTokens);
forwardAllRaisedFunds();
}
// overridden
function handleFunds() internal {
if(isSoftCapHit){ // if soft cap is reached, start transferring funds immediately to wallet
forwardFunds();
} else {
if(didSoftCapReached()){
forwardAllRaisedFunds();
}
}
}
modifier afterDeadline() { if (hasEnded() || isFinalized) _; } // a modifier to tell token sale ended
/**
* auto refund Tokens
*/
function refundAllMoney() onlyOwner public {
for(uint i=0; i < nextContributorIndex; i++) {
address addressToSendTo = contributorIndexes[i];
refundMoney(addressToSendTo);
}
}
/**
* refund Tokens of a single address
*/
function refundMoney(address _address) onlyOwner public {
uint amount = contributorList[_address].contributionAmount;
if (amount > 0 && _address.send(amount)) { // user got money back
contributorList[_address].contributionAmount = 0;
contributorList[_address].tokensIssued = 0;
}
}
}
It appears that your refundMoney() implementation has a bug, and doesn't decrease the weiRaised value. This means that once you issue a refund, you can no longer use forwardAllRaisedFunds() to drain the contract.
The somewhat good news (for the person who asked for the refund) is that this isn't their fault. Your bug would be triggered even in the regular course of action after you hit the softcap, since funds after the softcap are forwarded automatically, but are still added to weiRaised. There is no scenario in which you would have been able to access all the funds, unless you did not issue a refund and raised less money than the softcap.
The ether in this contract is effectively stuck. You will still be able to receive any funds after the softcap is hit, but funds under the softcap can never be retrieved.

why can't transfer token in the GetReward function in eqzip crowdsale?

The following is my contract after I deploy eqcoin contract and eqzip contract I have tried use account2 send ether to eqzip contract then the beneficiary can get the ether but when the crowdsale finished. I tried use account2 execute the GetReward function to get the reward but after I execute the GetReward function account2 didn't get the token why?
Could you please review my source code and tell me what's wrong with my contract?Thank you!
Eqcoin contract:
pragma solidity ^0.4.21;
interface tokenRecipient { function receiveApproval(address _from, uint256 _value, address _token, bytes _extraData) external; }
contract Eqcoin {
// Public variables of the token
// string public constant whitePaperForEqcoin = "The total supply of eqcoin is 100000 which corresponds to 1% of Eqzip stock,\
// 0.01% of Eqcoin stock and 10% of Lostk stock...\
// The decimals of Eqcoin is 18...\
// ";
string public name = "eqcoin";
string public symbol = "eqc";
uint8 public decimals = 18;
// 18 decimals is the strongly suggested default, avoid changing it
uint256 public totalSupply;
// This creates an array with all balances
mapping (address => uint256) public balanceOf;
mapping (address => mapping (address => uint256)) public allowance;
// The owner's address
// address private owner;
// This generates a public event on the blockchain that will notify clients
event Transfer(address indexed from, address indexed to, uint256 value);
// This notifies clients about the amount burnt
event Burn(address indexed from, uint256 value);
// The following is test stub comment when release
// string public ownerAddress;
event Log(string log, address _address, uint256 value);
/**
* Constructor function
*
* Initializes contract with initial supply tokens to the creator of the contract
*/
function Eqcoin(uint256 initialSupply,
string tokenName,
string tokenSymbol) public {
totalSupply = initialSupply * 10 ** uint256(decimals); // Update total supply with the decimal amount
balanceOf[msg.sender] = totalSupply; // Give the creator all initial tokens
// owner = msg.sender; // Set the owner
// ownerAddress = toAsciiString(msg.sender);
name = tokenName;
symbol = tokenSymbol;
}
/**
* Internal transfer, only can be called by this contract
*/
function _transfer(address _from, address _to, uint _value) internal {
emit Log("_transfer", _to, _value);
// Prevent transfer to 0x0 address. Use burn() instead
require(_to != 0x0);
// Check if the sender has enough
require(balanceOf[_from] >= _value);
// Check for overflows
require(balanceOf[_to] + _value >= balanceOf[_to]);
// Save this for an assertion in the future
uint previousBalances = balanceOf[_from] + balanceOf[_to];
// Subtract from the sender
balanceOf[_from] -= _value;
// Add the same to the recipient
balanceOf[_to] += _value;
emit Transfer(_from, _to, _value);
// Asserts are used to use static analysis to find bugs in your code. They should never fail
assert(balanceOf[_from] + balanceOf[_to] == previousBalances);
}
/**
* Transfer tokens
*
* Send `_value` tokens to `_to` from your account
*
* #param _to The address of the recipient
* #param _value the amount to send
*/
function transfer(address _to, uint256 _value) public {
emit Log("transfer", msg.sender, _value);
_transfer(msg.sender, _to, _value);
}
/**
* Transfer tokens from other address
*
* Send `_value` tokens to `_to` on behalf of `_from`
*
* #param _from The address of the sender
* #param _to The address of the recipient
* #param _value the amount to send
*/
function transferFrom(address _from, address _to, uint256 _value) public returns (bool success) {
require(_value <= allowance[_from][msg.sender]); // Check allowance
allowance[_from][msg.sender] -= _value;
_transfer(_from, _to, _value);
return true;
}
/**
* Set allowance for other address
*
* Allows `_spender` to spend no more than `_value` tokens on your behalf
*
* #param _spender The address authorized to spend
* #param _value the max amount they can spend
*/
function approve(address _spender, uint256 _value) public
returns (bool success) {
allowance[msg.sender][_spender] = _value;
return true;
}
/**
* Set allowance for other address and notify
*
* Allows `_spender` to spend no more than `_value` tokens on your behalf, and then ping the contract about it
*
* #param _spender The address authorized to spend
* #param _value the max amount they can spend
* #param _extraData some extra information to send to the approved contract
*/
function approveAndCall(address _spender, uint256 _value, bytes _extraData)
public
returns (bool success) {
tokenRecipient spender = tokenRecipient(_spender);
if (approve(_spender, _value)) {
spender.receiveApproval(msg.sender, _value, this, _extraData);
return true;
}
}
// /**
// * Destroy tokens
// *
// * Remove `_value` tokens from the system irreversibly
// *
// * #param _value the amount of money to burn
// */
// function burn(uint256 _value) public returns (bool success) {
// if(balanceOf[msg.sender] < _value){
// return;
// }
// balanceOf[msg.sender] -= _value; // Subtract from the sender
// if(msg.sender == owner){
// totalSupply -= _value; // Updates totalSupply
// }
// emit Burn(msg.sender, _value);
// return true;
// }
/**
* Destroy tokens
*
* Remove `_value` tokens from the system irreversibly
*
* #param _value the amount of money to burn
*/
function burn(uint256 _value) public returns (bool success) {
require(balanceOf[msg.sender] >= _value); // Check if the sender has enough
balanceOf[msg.sender] -= _value; // Subtract from the sender
totalSupply -= _value; // Updates totalSupply
emit Burn(msg.sender, _value);
return true;
}
/**
* Destroy tokens from other account
*
* Remove `_value` tokens from the system irreversibly on behalf of `_from`.
*
* #param _from the address of the sender
* #param _value the amount of money to burn
*/
function burnFrom(address _from, uint256 _value) public returns (bool success) {
require(balanceOf[_from] >= _value); // Check if the targeted balance is enough
require(_value <= allowance[_from][msg.sender]); // Check allowance
balanceOf[_from] -= _value; // Subtract from the targeted balance
allowance[_from][msg.sender] -= _value; // Subtract from the sender's allowance
totalSupply -= _value; // Update totalSupply
emit Burn(_from, _value);
return true;
}
function getTotalSupply() public constant returns (uint256 _totalSupply){
return totalSupply;
}
// function getOwner() public constant returns(address _address){
// return owner;
// }
// the following is test stub comment when release
// function toAsciiString(address x) internal pure returns (string) {
// bytes memory s = new bytes(40);
// for (uint i = 0; i < 20; i++) {
// byte b = byte(uint8(uint(x) / (2**(8*(19 - i)))));
// byte hi = byte(uint8(b) / 16);
// byte lo = byte(uint8(b) - 16 * uint8(hi));
// s[2*i] = char(hi);
// s[2*i+1] = char(lo);
// }
// return string(s);
// }
// function char(byte b) internal pure returns (byte c) {
// if (b < 10) return byte(uint8(b) + 0x30);
// else return byte(uint8(b) + 0x57);
// }
}
Eqzip crowdsale contract:
pragma solidity ^0.4.21;
interface token {
function transfer(address receiver, uint amount) external;
function getTotalSupply() external returns (uint256 _totalSupply);
// function getOwner() external returns(address _address);
}
contract EqzipCrowdsale {
string public constant whitePaperForEqzip = "The total supply of eqcoin is 100000 which corresponds to: \n\
1. 1% of Eqzip stock. \n\
2. 0.01% of Eqcoin stock. \n\
3. 10% of Lostk stock. \n\
4. Get the EQC corresponding to the price of eqcoin ico. \n\
5. If the Ether from one person's investment is greater than or equal to 333, \
hope life offers one cloned resurrection place (only 3 places, take the top 3). \n\
6. Hired Hope Media to provide Growth Hacker, product design, and business architecture design for Ethereum. \n\
7. Prior to joining eqzip work, under the same conditions to participate in the next round of financing eqzip. \n\
The decimals of Eqcoin is 18... \n\
owner: Xun Wang \n\
wechat: nju20006 \n\
email: 10509759#qq.com \n\
URL: www.eqzip.com www.eqzip.cn www.lostk.com www.lostk.cn github.com/eqzip/eqcoin github.com/eqzip/lostk \n\
";
// The owner's address
address public owner;
// This generates a public event on the blockchain that will notify clients
event Transfer(address indexed from, address indexed to, uint256 value);
// This notifies clients about the amount burnt
event Burn(string reason, uint256 value);
uint public fundingGoal;
uint public amountRaised;
uint public funderNumbers;
uint public deadline;
struct BalanceOfFounder{
uint256 _ether;
bool isSentToken;
}
// This creates an array with all balances of eqcoin, ether and if have sent token
mapping(address => BalanceOfFounder) public balanceOfEther;
token public tokenReward;
address public beneficiary;
bool burnedUnsaleToken = false;
event GoalReached(address recipient, uint totalAmountRaised);
// Milestone
string public milestone;
// Total supply
uint256 public totalSupply;
event Log(string log, address _address, uint256 value);
/**
* Constructor function
*
* Setup the owner
*/
function EqzipCrowdsale(
address ifSuccessfulSendTo,
uint fundingGoalInEthers,
uint durationInMinutes,
address addressOfTokenUsedAsReward
) public {
// For Eqzip crowdsale
beneficiary = ifSuccessfulSendTo;
fundingGoal = fundingGoalInEthers * 1 ether;
deadline = now + durationInMinutes * 1 minutes;
tokenReward = token(addressOfTokenUsedAsReward);
totalSupply = tokenReward.getTotalSupply();
owner = msg.sender;
emit Log("cons", owner, 0);
// emit Log("cons", tokenReward.getOwner(), 1);
}
/**
* Fallback function
*
* The function without name is the default function that is called whenever anyone sends funds to a contract
*/
function () beforeDeadline public payable {
balanceOfEther[msg.sender]._ether += msg.value;
balanceOfEther[msg.sender].isSentToken = false;
amountRaised += msg.value;
beneficiary.transfer(msg.value);
emit GoalReached(msg.sender, msg.value);
}
modifier afterDeadline() { if (now > deadline) _; }
modifier beforeDeadline() { if (now <= deadline) _; }
function getReward() afterDeadline public {
emit Log("getReward", owner, 0);
// require(!balanceOfEther[msg.sender].isSentToken);
// save investment value
// uint256 amount = balanceOfEther[msg.sender]._ether;
emit Log("getReward after require", msg.sender, 1);
// because have sent the token to founder so set isSentToken to true to void get multiply reward
balanceOfEther[msg.sender].isSentToken = true;
// if amount raised less than founding goal then burn un sold token and reduce the total supply
// if((amountRaised < fundingGoal) && !burnedUnsaleToken){
// burnedUnsaleToken = true;
// // totalSupply = (totalSupply*amountRaised)/fundingGoal;
// // balanceOf[owner] = totalSupply;
// // emit Burn("Token not sold out all the sold value is", totalSupply);
// }
if(amountRaised < fundingGoal && !burnedUnsaleToken){
burnedUnsaleToken = true;
totalSupply = (totalSupply*amountRaised)/fundingGoal;
emit Burn("Token not sold out all the sold value is", totalSupply);
}
emit Log("getReward tokenReward.transfer", msg.sender, 2);
tokenReward.transfer(msg.sender, (balanceOfEther[msg.sender]._ether*totalSupply)/amountRaised);
emit Log("getReward after tokenReward.transfer", msg.sender, 3);
// _transfer(owner, msg.sender, (amount*totalSupply)/amountRaised);
}
function getBalanceOfEther(address _address) public payable returns(uint256) {
emit Log("getBalanceOfEther", _address, balanceOfEther[_address]._ether);
return balanceOfEther[_address]._ether;
}
function updateMilestone(string str) public {
emit Log("updateMilestone", msg.sender, 0);
milestone = strConcat(milestone, "\n", toAsciiString(msg.sender), "\n", str);
}
function strConcat(string _a, string _b, string _c, string _d, string _e) internal pure returns (string){
bytes memory _ba = bytes(_a);
bytes memory _bb = bytes(_b);
bytes memory _bc = bytes(_c);
bytes memory _bd = bytes(_d);
bytes memory _be = bytes(_e);
string memory abcde = new string(_ba.length + _bb.length + _bc.length + _bd.length + _be.length);
bytes memory babcde = bytes(abcde);
uint k = 0;
for (uint i = 0; i < _ba.length; i++) babcde[k++] = _ba[i];
for (i = 0; i < _bb.length; i++) babcde[k++] = _bb[i];
for (i = 0; i < _bc.length; i++) babcde[k++] = _bc[i];
for (i = 0; i < _bd.length; i++) babcde[k++] = _bd[i];
for (i = 0; i < _be.length; i++) babcde[k++] = _be[i];
return string(babcde);
}
function toAsciiString(address x) internal pure returns (string) {
bytes memory s = new bytes(40);
for (uint i = 0; i < 20; i++) {
byte b = byte(uint8(uint(x) / (2**(8*(19 - i)))));
byte hi = byte(uint8(b) / 16);
byte lo = byte(uint8(b) - 16 * uint8(hi));
s[2*i] = char(hi);
s[2*i+1] = char(lo);
}
return string(s);
}
function char(byte b) internal pure returns (byte c) {
if (b < 10) return byte(uint8(b) + 0x30);
else return byte(uint8(b) + 0x57);
}
}

Ethereum, crowdsale returns 0.00 tokens to the wallet

I'm trying to set up a basic crowdsale at ethereum testnet and the solidity code I'm using is the basic examples found at
https://ethereum.org/crowdsale#the-code
with steps followed as described in that guide.
The issue first was that the ethereum wallet doesn't accept the code as is to compile due to the first line:
contract token { function transfer(address receiver, uint amount){ } }
Specifically, its function returns a warning of an unused local variable and won't compile. Is there a way around this other than defining empty variables inside the function?
The second issue is after it's deployed with the modification as mentioned above, it works. But when it sends tokens to the wallet that sent the ether, the amount is always locked at 0.00 tokens.
FULL CODE:
pragma solidity ^0.4.2;
contract token { function transfer(address receiver, uint amount){ receiver; amount; } }
contract Crowdsale {
address public beneficiary;
uint public fundingGoal; uint public amountRaised; uint public deadline; uint public price;
token public tokenReward;
mapping(address => uint256) public balanceOf;
bool fundingGoalReached = false;
event GoalReached(address beneficiary, uint amountRaised);
event FundTransfer(address backer, uint amount, bool isContribution);
bool crowdsaleClosed = false;
/* data structure to hold information about campaign contributors */
/* at initialization, setup the owner */
function Crowdsale(
address ifSuccessfulSendTo,
uint fundingGoalInEthers,
uint durationInMinutes,
uint etherCostOfEachToken,
token addressOfTokenUsedAsReward
) {
beneficiary = ifSuccessfulSendTo;
fundingGoal = fundingGoalInEthers * 1 ether;
deadline = now + durationInMinutes * 1 minutes;
price = etherCostOfEachToken * 1 ether;
tokenReward = token(addressOfTokenUsedAsReward);
}
/* The function without a name is the default function that is called whenever anyone sends funds to a contract */
function () payable {
if (crowdsaleClosed) throw;
uint amount = msg.value;
balanceOf[msg.sender] = amount;
amountRaised += amount;
tokenReward.transfer(msg.sender, amount / price);
FundTransfer(msg.sender, amount, true);
}
modifier afterDeadline() { if (now >= deadline) _; }
/* checks if the goal or time limit has been reached and ends the campaign */
function checkGoalReached() afterDeadline {
if (amountRaised >= fundingGoal){
fundingGoalReached = true;
GoalReached(beneficiary, amountRaised);
}
crowdsaleClosed = true;
}
function safeWithdrawal() afterDeadline {
if (!fundingGoalReached) {
uint amount = balanceOf[msg.sender];
balanceOf[msg.sender] = 0;
if (amount > 0) {
if (msg.sender.send(amount)) {
FundTransfer(msg.sender, amount, false);
} else {
balanceOf[msg.sender] = amount;
}
}
}
if (fundingGoalReached && beneficiary == msg.sender) {
if (beneficiary.send(amountRaised)) {
FundTransfer(beneficiary, amountRaised, false);
} else {
//If we fail to send the funds to beneficiary, unlock funders balance
fundingGoalReached = false;
}
}
}
}
EDIT: I forgot to mention the steps leading to this point aka Token creation / shareholder association work with the code as is provided in the guide.
I came across the same issue. I solved it by actually defining the transfer function as the example from ethereum.org provides an empty one.
I replaced this:
contract token { function transfer(address receiver, uint amount){ } }
By this:
contract token {
event Transfer(address indexed from, address indexed to, uint256 value);
function transfer(address _to, uint256 _value) {
if (_to == 0x0) throw;
Transfer(msg.sender, _to, _value);
}
}
For your second problem, do you actually have a confirmation that the token created were actually sent? How many ether did you send to the crowd-sale contract? It seems that you are using two decimals for your token and if you defined "Ether cost of each token" of 5 like in the example, you shouldn't send less than 0.05 ether to the crowd-sale contract.
Hope it helps!