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

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.

Related

Transaction is getting reverted in the `refundToInsurer()` function call

The deployment of InsuranceProvider is working fine and the calling of newContract() with the required parameters is successfully creating/deploying the InsuranceConsumer contract. Even, the payOutContract() is working correctly in terms of transferring the ETH balance from the InsuranceConsumer to the client's wallet.
The issue is with the refundToInsurer() function, as it's expected to transfer the ETH balance from the InsuranceConsumer to the insurer's wallet, but it's transaction is getting failed/reverted.
Here's the code:
SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;
import "#chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol";
contract InsuranceProvider {
address payable public insurer;
AggregatorV3Interface internal priceFeed;
modifier onlyOwner() {
require(insurer == msg.sender, "Only Insurance provider can do this");
_;
}
constructor() payable {
priceFeed = AggregatorV3Interface(
0xD4a33860578De61DBAbDc8BFdb98FD742fA7028e
);
insurer = payable(msg.sender);
}
function newContract(
address payable _client,
uint256 _premium,
uint256 _payoutValue
) public payable onlyOwner returns (address) {
//create contract, send payout amount so contract is fully funded plus a small buffer
InsuranceConsumer i = (new InsuranceConsumer){
value: ((_payoutValue * 1 ether) / (uint256(getLatestPrice())))
}(_client, _premium, _payoutValue);
return address(i);
}
function getLatestPrice() public view returns (int256) {
(, int256 price, , uint256 timeStamp, ) = priceFeed.latestRoundData();
// If the round is not complete yet, timestamp is 0
require(timeStamp > 0, "Round not complete");
return price;
}
function payOutContract(address _contract) public {
InsuranceConsumer i = InsuranceConsumer(_contract);
// Transfer agreed amount to client
i.payOutContract();
}
function refundToInsurer(address _contract) public onlyOwner {
InsuranceConsumer i = InsuranceConsumer(_contract);
// Transfer back the amount to insurer
i.refundToInsurer();
}
}
contract InsuranceConsumer {
AggregatorV3Interface internal priceFeed;
address payable public insurer;
address payable client;
uint256 startDate;
uint256 premium;
uint256 payoutValue;
constructor(
address payable _client,
uint256 _premium,
uint256 _payoutValue
) payable {
//set ETH/USD Price Feed
priceFeed = AggregatorV3Interface(
0xD4a33860578De61DBAbDc8BFdb98FD742fA7028e
);
//first ensure insurer has fully funded the contract
require(
msg.value >= _payoutValue / uint256(getLatestPrice()),
"Not enough funds sent to contract"
);
//now initialize values for the contract
insurer = payable(msg.sender);
client = _client;
startDate = block.timestamp; //contract will be effective immediately on creation
premium = _premium;
payoutValue = _payoutValue;
}
function payOutContract() public {
//Transfer agreed amount to client
client.transfer(address(this).balance);
}
function refundToInsurer() public {
// Transfer back the amount to insurer
insurer.transfer(address(this).balance);
}
function getLatestPrice() public view returns (int256) {
(, int256 price, , uint256 timeStamp, ) = priceFeed.latestRoundData();
// If the round is not complete yet, timestamp is 0
require(timeStamp > 0, "Round not complete");
return price;
}
}
Can anyone please help by pointing out the logical mistake that I'm doing in the refundToInsurer() function ?
As, we're creating the InsuranceConsumer using the newContract() function of InsuranceProvider. Therefore, the msg.sender of the InsuranceConsumer is going to be the InsuranceProvider itself, not the insurer's wallet.
So, when we're calling the refundInsurer() of InsuranceConsumer via InsuranceProvider, then it's doing:
insurer.transfer(address(this).balance);
It means to transfer the available ETH in the InsuranceConsumer to the InsuranceProvider (not the insurer's wallet), and since InsuranceProvider is not expected to be a receiver, that's why it's reverting the transaction.
So, the corrected code will be:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;
import "#chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol";
contract InsuranceProvider {
address payable public insurer;
AggregatorV3Interface internal priceFeed;
modifier onlyOwner() {
require(insurer == msg.sender, "Only Insurance provider can do this");
_;
}
constructor() payable {
priceFeed = AggregatorV3Interface(
0xD4a33860578De61DBAbDc8BFdb98FD742fA7028e
);
insurer = payable(msg.sender);
}
function newContract(
address payable _client,
uint256 _premium,
uint256 _payoutValue
) public payable onlyOwner returns (address) {
//create contract, send payout amount so contract is fully funded plus a small buffer
InsuranceConsumer i = (new InsuranceConsumer){
value: ((_payoutValue * 1 ether) / (uint256(getLatestPrice())))
}(_client, _premium, _payoutValue);
return address(i);
}
function getLatestPrice() public view returns (int256) {
(, int256 price, , uint256 timeStamp, ) = priceFeed.latestRoundData();
// If the round is not complete yet, timestamp is 0
require(timeStamp > 0, "Round not complete");
return price;
}
function payOutContract(address _contract) public onlyOwner {
// Transfer agreed amount to client
InsuranceConsumer i = InsuranceConsumer(_contract);
i.payOutContract();
}
function refundToInsurer(address _contract) public onlyOwner {
// Transfer back the amount to insurer
InsuranceConsumer i = InsuranceConsumer(_contract);
i.refundToInsurer(insurer);
}
}
contract InsuranceConsumer {
AggregatorV3Interface internal priceFeed;
address payable public insurer;
address payable client;
uint256 startDate;
uint256 premium;
uint256 payoutValue;
constructor(
address payable _client,
uint256 _premium,
uint256 _payoutValue
) payable {
//set ETH/USD Price Feed
priceFeed = AggregatorV3Interface(
0xD4a33860578De61DBAbDc8BFdb98FD742fA7028e
);
//first ensure insurer has fully funded the contract
require(
msg.value >= _payoutValue / uint256(getLatestPrice()),
"Not enough funds sent to contract"
);
//now initialize values for the contract
insurer = payable(msg.sender);
client = _client;
startDate = block.timestamp; //contract will be effective immediately on creation
premium = _premium;
payoutValue = _payoutValue;
}
function payOutContract() public {
//Transfer agreed amount to client
client.transfer(address(this).balance);
}
function refundToInsurer(address payable _insurer) public {
// Transfer back the amount to insurer
_insurer.transfer(address(this).balance);
}
function getLatestPrice() public view returns (int256) {
(, int256 price, , uint256 timeStamp, ) = priceFeed.latestRoundData();
// If the round is not complete yet, timestamp is 0
require(timeStamp > 0, "Round not complete");
return price;
}
}
Now, while calling the refundInsurer(), we're explicitly passing the insurer as the parameter, and it's taking the value of msg.sender from InsuranceProvider, so the msg.sender is going to be the insurer's wallet (with which the InsuranceProvider is being deployed) in this case.
And now, when we're calling the refundInsurer() of InsuranceConsumer via InsuranceProvider, then it's doing:
_insurer.transfer(address(this).balance);
It means to transfer the available ETH in the InsuranceConsumer to the insurer's wallet. So, the transaction will be successful resulting in the withdrawal of the funds from the InsuranceConsumer to the insurer's wallet.

"Not Enough Fund" when doing buying token transaction in Solidity with Remix IDE

I am completely new to this blockchain world so I want to try learn it. While I am following a tutorial to create a simple ERC-1155 contract to mint a token and set its price. When I am trying to run the buyToken function from another address, it keeps saying "Not Enough Fund". When I debug the msg.value value is 0, even though I have 100 ethers balance on each of my address. When I change the amount of token to 0, it works successfully. What should I need to do to be able to do the transaction?
Log
This is my contract that I have modified on:
// Contract based on https://docs.openzeppelin.com/contracts/4.x/erc1155
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "#openzeppelin/contracts/token/ERC1155/ERC1155.sol";
/**
* #title NFTMinter
* #dev NFT Contract Minter
* #custom:dev-run-script ./scripts/deploy_with_ethers.ts
*/
contract NFTMinter is ERC1155 {
constructor() ERC1155("https://raw.githubusercontent.com/noopmood/TutorialNFTInGo/main/metadata/{id}.json") payable {}
// Define the mapping of addresses to balances
mapping(address => mapping(uint256 => uint256)) public _balances;
// Define the mapping of address to tokenIds owned
mapping(address => uint256[]) public _tokenIds;
// Define the mapping of tokenId to price
mapping(uint256 => uint256) public tokenPrice;
// Define the sender to address payable type
address payable public sender;
struct Token {
uint256 tokenId;
uint256 balance;
}
function mintCaller(uint256 tokenId, uint256 amount) public {
_mint(msg.sender, tokenId, amount, "");
}
// Mints new tokens and sets the price for each token.
function mintAddress(uint256 tokenId, uint256 amount, address addr, uint256 price) public{
_mint(addr, tokenId, amount, "");
// Update the balance of the recipient
_balances[addr][tokenId] += amount;
// Add the tokenId to the address
_tokenIds[addr].push(tokenId);
// Set the price of the token
tokenPrice[tokenId] = price;
}
// Get all tokenIds from its owner address
function getTokenIdsByAddress(address addr) public view returns (uint[] memory) {
return _tokenIds[addr];
}
// Get the balance / amount of the tokenId
function getTokenByIdAndAddress(address addr, uint256 tokenId) public view returns (Token memory) {
Token memory result;
result.tokenId = tokenId;
result.balance = _balances[addr][tokenId];
return result;
}
// Get the tokenIds along with its corresponding balances/amount
function getAllTokenByAddress(address holder) public view returns (Token[] memory) {
Token[] memory result = new Token[](_tokenIds[holder].length);
for (uint i = 0; i < _tokenIds[holder].length; i++) {
result[i].tokenId = _tokenIds[holder][i];
result[i].balance = _balances[holder][_tokenIds[holder][i]];
}
return result;
}
// Transfers the tokens from one address to another.
function transfer(address addr, uint256 tokenId, uint256 amount) public {
require(_balances[msg.sender][tokenId] >= amount, "Not enough balance");
// Transfer the token
_safeTransferFrom(msg.sender, addr, tokenId, amount, "");
// Update the sender's balance
_balances[msg.sender][tokenId] -= amount;
// Update the recipient's balance
_balances[addr][tokenId] += amount;
}
// Allows a buyer to purchase a token by sending the required amount to the contract and updating the balance of the buyer.
function buyToken(uint256 tokenId, uint256 amount) public payable {
require(msg.value >= amount * tokenPrice[tokenId], "Not enough funds");
// Deduct the amount from the buyer
sender = payable(msg.sender);
sender.transfer(amount * tokenPrice[tokenId]);
// Transfer the token to the buyer
_safeTransferFrom(address(0), msg.sender, tokenId, amount, "");
// Update the buyer's balance
_balances[msg.sender][tokenId] += amount;
}
}
On what the step to reproduce this:
Deploy the contract with value, for me I pass 20 Ether
Run the mintAddress function by passing, tokenId: 1, amount: 10, price: 10, address: the address an account
Run the transfer function by passing address: the address of account you want to transfer the token into, tokenId: 1, amount: 10
Change the account in upper part to the address you use in transfer function
Run buyToken function, tokenId: 1, amount: 10
It will said Not Enough Fund
buyToken
What I have tried so far:
I read in another post, that I should deploy the contract with the value in it. But it still doesn't work
I have checked that the balance of my account in remix have 100 ethers, but when I try to doing the buy token with it, it still said 'Not Enough Fund'
What I am expecting:
To be able to buy the token with the price that has been set when minting the token.
Your error is failing from here:
// require is like if statement. if condition does not satisfied, it shows the passed message
require(msg.value >= amount * tokenPrice[tokenId], "Not enough funds")
When a user sends funds alongside the transaction, not as an function argument, solidity will catch it with msg.value. Looks like you are not sending any value alongside the transaction or not sending enough funds. in Remix IDE
you need to pass the necessary value in the above red borderd box

How fix TypeError and DeclarationError with ChainLink Solidity smart contract?

I have created a smart contract which return to each user the amount deposited + a certain amount if the price of ETH decreases during the lock period. I have two problems with the last part of the code.
The first one concerns mapping the price of ethereum at the moment the user makes the deposit. I have tried several solutions but none of them seem to work. The problem arises on line 64 mapping(uint => uint) ethPrice;. Console returns:
DeclarationError: Identifier already declared.
--> oracle.sol:65:5:
|
65 | mapping(uint => uint) ethPrice;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Note: The previous declaration is here:
--> oracle.sol:63:5:
|
63 | uint public ethPrice = 0;
| ^^^^^^^^^^^^^^^^^^^^^^^^
The second is found on line no. 91. msg.sender.transfer(amountToWithdraw); with the transfer function. The console continues to return the following error despite the fact that the address of each user is defined as payable in the previous functions. Console returns:
TypeError: "send" and "transfer" are only available for objects of type "address payable", not "address".
--> oracle.sol:97:9:
|
97 | msg.sender.transfer(amountToWithdraw);
| ^^^^^^^^^^^^^^^^^^^
These two problems severely invalidate the smart contract and are holding up the completion of coding the latest functions. I have contacted several people and looked in forums concerning programming on solidity but no one seems to have an answer to my problem.
I hope that my question can be answered by the community and can help any other person trying to use ChainLink with Solidity in the future. I am happy to listen to any advice on the matter.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.6;
import "#chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol";
// EACAggregatorProxy is used for chainlink oracle
interface EACAggregatorProxy {
function latestAnswer() external view returns (int256);
}
contract oracleLink {
// Address dev
address public dev;
// Dev's public deposit amount
uint public devDeposit;
// Array dev's public amount
uint[] public devDeposits;
// List each user and amount
address[] public users;
uint[] public totalDeposited;
// Mapping user's deposit
mapping(address => uint) balances;
// Deployer = dev & Dev deposit function
function deployerIsDeveloper() public payable {
dev = msg.sender;
devDeposit = msg.value;
devDeposits.push(devDeposit);
}
// User's address
address user;
// Amount's address
uint amountDeposit;
// Deadline time
uint256 deadline;
// Amount's each user
uint256 lockAmount = lockAmounts[msg.sender];
// Mapping of deposit for each user
mapping(address => uint) lockAmounts;
// Timestamp for each user
uint256 startTime = startTimes[block.timestamp];
// Mapping timestamp for each user
mapping(uint => uint) startTimes;
// Kovan ETH/USD oracle address
address public chainLinkETHUSDAddress = 0x9326BFA02ADD2366b30bacB125260Af641031331;
// ethPrice
uint public ethPrice = 0;
uint256 price = ethPrice;
mapping(uint => uint) ethPrice;
// Deposit function for each user
function deposit(uint256 numberOfSeconds) public payable {
lockAmounts[msg.sender] = msg.value;
startTimes[block.timestamp] = block.timestamp;
user = msg.sender;
amountDeposit = msg.value;
users.push(user);
totalDeposited.push(amountDeposit);
deadline = block.timestamp + (numberOfSeconds * 1 seconds);
int256 chainLinkEthPrice = EACAggregatorProxy(chainLinkETHUSDAddress).latestAnswer();
ethPrice = uint(chainLinkEthPrice / 100000000);
//return ethPrice = price;
//price.push(ethPrice);
}
// Withdraw function for each user
function withdraw() public payable {
require(block.timestamp >= deadline);
uint amountToWithdraw = lockAmounts[msg.sender];
lockAmounts[msg.sender] = 0;
msg.sender.transfer(amountToWithdraw);
}
}
For the first issue, Solidity compiler said that you declared two variables with the identifier. In details in your case, you give ethPrice for mapping and uint variable. To solve this issue, try to change one of these names in this way:
uint256 price = ethPrice;
mapping(uint => uint) mappingEthPrice;
Second issue refers that msg.sender keyword doesn't cast automatically with address payable and to solve it you can use payable() function that allows you convert an address to address payable.
In your smart contract you must to change in this way:
payable(msg.sender).transfer(amountToWithdraw);
This should be your smart contract fixed:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.6;
import "#chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol";
// EACAggregatorProxy is used for chainlink oracle
interface EACAggregatorProxy {
function latestAnswer() external view returns (int256);
}
contract oracleLink {
// Address dev
address public dev;
// Dev's public deposit amount
uint public devDeposit;
// Array dev's public amount
uint[] public devDeposits;
// List each user and amount
address[] public users;
uint[] public totalDeposited;
// Mapping user's deposit
mapping(address => uint) balances;
// Deployer = dev & Dev deposit function
function deployerIsDeveloper() public payable {
dev = msg.sender;
devDeposit = msg.value;
devDeposits.push(devDeposit);
}
// User's address
address user;
// Amount's address
uint amountDeposit;
// Deadline time
uint256 deadline;
// Amount's each user
uint256 lockAmount = lockAmounts[msg.sender];
// Mapping of deposit for each user
mapping(address => uint) lockAmounts;
// Timestamp for each user
uint256 startTime = startTimes[block.timestamp];
// Mapping timestamp for each user
mapping(uint => uint) startTimes;
// Kovan ETH/USD oracle address
address public chainLinkETHUSDAddress = 0x9326BFA02ADD2366b30bacB125260Af641031331;
// ethPrice
uint public ethPrice = 0;
uint256 price = ethPrice;
mapping(uint => uint) mappingEthPrice;
// Deposit function for each user
function deposit(uint256 numberOfSeconds) public payable {
lockAmounts[msg.sender] = msg.value;
startTimes[block.timestamp] = block.timestamp;
user = msg.sender;
amountDeposit = msg.value;
users.push(user);
totalDeposited.push(amountDeposit);
deadline = block.timestamp + (numberOfSeconds * 1 seconds);
int256 chainLinkEthPrice = EACAggregatorProxy(chainLinkETHUSDAddress).latestAnswer();
ethPrice = uint(chainLinkEthPrice / 100000000);
//return ethPrice = price;
//price.push(ethPrice);
}
// Withdraw function for each user
function withdraw() public payable {
require(block.timestamp >= deadline);
uint amountToWithdraw = lockAmounts[msg.sender];
lockAmounts[msg.sender] = 0;
payable(msg.sender).transfer(amountToWithdraw);
}
}

Check which tokens came to the contract

Solidity. How do I check which tokens were sent to the contract? How do I check the USDT token?
contract DEX {
event Bought(uint256 amount);
event Sold(uint256 amount);
IERC20 public token;
constructor() public {
token = new ERC20Basic();
}
function buy() payable public {
uint256 amountTobuy = msg.value;
uint256 dexBalance = token.balanceOf(address(this));
require(amountTobuy > 0, "You need to send some Ether");
require(amountTobuy <= dexBalance, "Not enough tokens in the reserve");
token.transfer(msg.sender, amountTobuy);
emit Bought(amountTobuy);
}
function sell(uint256 amount) public {
require(amount > 0, "You need to sell at least some tokens");
uint256 allowance = token.allowance(msg.sender, address(this));
require(allowance >= amount, "Check the token allowance");
token.transferFrom(msg.sender, address(this), amount);
msg.sender.transfer(amount);
emit Sold(amount);
}
}
You're looking for the balanceOf function, you could use OpenZepplin's implementation of this as well.
uint balance = token.balanceOf(account);
For each token you want to check, you'll need the tokens address too. So for USDT, you'd need the token address of USDT. Then you could do something like (nodejs syntax):
pragma solidity ^0.6.0;
import "#openzeppelin/contracts/token/ERC20/IERC20.sol";
contract GetBalance{
constructor() public {
}
function getBalanceOfToken(address _USDT_ADDRESS) public returns (uint){
usdt = IERC20(_USDT_ADDRESS);
uint balance = usdt.balanceOf(address(this));
return balance;
}
}

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!