Transfer ERC20 token with Oraclize and Metamask - ethereum

I'm a beginner and I've been exploring ERC20 tokens. Since a couple of days I have been looking for a solution to this, but in vain.
The problem is the following. I am creating a contract, conforming to the ERC20 protocol. I want to add an extra functionality in the form of an oracle query.
I.e., I want to use a service like "Oraclize", to fetch some external data, return the result.
Depending on the result I would like to transfer some tokens or not.
1) The example token contract I've been working with is the following. It s the contract from CryptoPunks
(https://github.com/larvalabs/cryptopunks/blob/master/contracts/CryptoPunksMarket.sol):
pragma solidity ^0.4.18;
contract CryptoTokensMarket {
address owner;
string public standard = 'CryptoTokens';
string public name;
string public symbol;
uint8 public decimals;
uint256 public totalSupply;
uint public nextTokenIndexToAssign = 0;
bool public allTokensAssigned = false;
uint public tokensRemainingToAssign = 0;
//mapping (address => uint) public addressToTokenIndex;
mapping (uint => address) public tokenIndexToAddress;
/* This creates an array with all balances */
mapping (address => uint256) public balanceOf;
struct Offer {
bool isForSale;
uint tokenIndex;
address seller;
uint minValue; // in ether
address onlySellTo; // specify to sell only to a specific person
}
struct Bid {
bool hasBid;
uint tokenIndex;
address bidder;
uint value;
}
// A record of tokens that are offered for sale at a specific minimum value, and perhaps to a specific person
mapping (uint => Offer) public tokensOfferedForSale;
// A record of the highest token bid
mapping (uint => Bid) public tokenBids;
mapping (address => uint) public pendingWithdrawals;
event Assign(address indexed to, uint256 tokenIndex);
event Transfer(address indexed from, address indexed to, uint256 value);
event TokenTransfer(address indexed from, address indexed to, uint256 tokenIndex);
event TokenOffered(uint indexed tokenIndex, uint minValue, address indexed toAddress);
event TokenBidEntered(uint indexed tokenIndex, uint value, address indexed fromAddress);
event TokenBidWithdrawn(uint indexed tokenIndex, uint value, address indexed fromAddress);
event TokenBought(uint indexed tokenIndex, uint value, address indexed fromAddress, address indexed toAddress);
event TokenNoLongerForSale(uint indexed tokenIndex);
/* Initializes contract with initial supply tokens to the creator of the contract */
function CryptoTokensMarket() payable {
// balanceOf[msg.sender] = initialSupply; // Give the creator all initial tokens
owner = msg.sender;
totalSupply = 10000; // Update total supply
tokensRemainingToAssign = totalSupply;
name = "CRYPTOTokenS"; // Set the name for display purposes
symbol = "Ͼ"; // Set the symbol for display purposes
decimals = 0; // Amount of decimals for display purposes
}
function setInitialOwner(address to, uint tokenIndex) {
if (msg.sender != owner) revert();
if (allTokensAssigned) revert();
if (tokenIndex >= 10000) revert();
if (tokenIndexToAddress[tokenIndex] != to) {
if (tokenIndexToAddress[tokenIndex] != 0x0) {
balanceOf[tokenIndexToAddress[tokenIndex]]--;
} else {
tokensRemainingToAssign--;
}
tokenIndexToAddress[tokenIndex] = to;
balanceOf[to]++;
Assign(to, tokenIndex);
}
}
function setInitialOwners(address[] addresses, uint[] indices) {
if (msg.sender != owner) revert();
uint n = addresses.length;
for (uint i = 0; i < n; i++) {
setInitialOwner(addresses[i], indices[i]);
}
}
function allInitialOwnersAssigned() {
if (msg.sender != owner) revert();
allTokensAssigned = true;
}
function getToken(uint tokenIndex) {
if (!allTokensAssigned) revert();
if (tokensRemainingToAssign == 0) revert();
if (tokenIndexToAddress[tokenIndex] != 0x0) revert();
if (tokenIndex >= 10000) revert();
tokenIndexToAddress[tokenIndex] = msg.sender;
balanceOf[msg.sender]++;
tokensRemainingToAssign--;
Assign(msg.sender, tokenIndex);
}
// Transfer ownership of a token to another user without requiring payment
function transferToken(address to, uint tokenIndex) payable {
if (!allTokensAssigned) revert();
if (tokenIndexToAddress[tokenIndex] != msg.sender) revert();
if (tokenIndex >= 10000) revert();
if (tokensOfferedForSale[tokenIndex].isForSale) {
tokenNoLongerForSale(tokenIndex);
}
tokenIndexToAddress[tokenIndex] = to;
balanceOf[msg.sender]--;
balanceOf[to]++;
Transfer(msg.sender, to, 1);
TokenTransfer(msg.sender, to, tokenIndex);
// Check for the case where there is a bid from the new owner and refund it.
// Any other bid can stay in place.
Bid bid = tokenBids[tokenIndex];
if (bid.bidder == to) {
// Kill bid and refund value
pendingWithdrawals[to] += bid.value;
tokenBids[tokenIndex] = Bid(false, tokenIndex, 0x0, 0);
}
}
function tokenNoLongerForSale(uint tokenIndex) {
if (!allTokensAssigned) revert();
if (tokenIndexToAddress[tokenIndex] != msg.sender) revert();
if (tokenIndex >= 10000) revert();
tokensOfferedForSale[tokenIndex] = Offer(false, tokenIndex, msg.sender, 0, 0x0);
TokenNoLongerForSale(tokenIndex);
}
function offerTokenForSale(uint tokenIndex, uint minSalePriceInWei) {
if (!allTokensAssigned) revert();
if (tokenIndexToAddress[tokenIndex] != msg.sender) revert();
if (tokenIndex >= 10000) revert();
tokensOfferedForSale[tokenIndex] = Offer(true, tokenIndex, msg.sender, minSalePriceInWei, 0x0);
TokenOffered(tokenIndex, minSalePriceInWei, 0x0);
}
function offerTokenForSaleToAddress(uint tokenIndex, uint minSalePriceInWei, address toAddress) {
if (!allTokensAssigned) revert();
if (tokenIndexToAddress[tokenIndex] != msg.sender) revert();
if (tokenIndex >= 10000) revert();
tokensOfferedForSale[tokenIndex] = Offer(true, tokenIndex, msg.sender, minSalePriceInWei, toAddress);
TokenOffered(tokenIndex, minSalePriceInWei, toAddress);
}
function buyToken(uint tokenIndex) payable {
if (!allTokensAssigned) revert();
Offer offer = tokensOfferedForSale[tokenIndex];
if (tokenIndex >= 10000) revert();
if (!offer.isForSale) revert(); // token not actually for sale
if (offer.onlySellTo != 0x0 && offer.onlySellTo != msg.sender) revert(); // token not supposed to be sold to this user
if (msg.value < offer.minValue) revert(); // Didn't send enough ETH
if (offer.seller != tokenIndexToAddress[tokenIndex]) revert(); // Seller no longer owner of token
address seller = offer.seller;
tokenIndexToAddress[tokenIndex] = msg.sender;
balanceOf[seller]--;
balanceOf[msg.sender]++;
Transfer(seller, msg.sender, 1);
tokenNoLongerForSale(tokenIndex);
pendingWithdrawals[seller] += msg.value;
TokenBought(tokenIndex, msg.value, seller, msg.sender);
// Check for the case where there is a bid from the new owner and refund it.
// Any other bid can stay in place.
Bid bid = tokenBids[tokenIndex];
if (bid.bidder == msg.sender) {
// Kill bid and refund value
pendingWithdrawals[msg.sender] += bid.value;
tokenBids[tokenIndex] = Bid(false, tokenIndex, 0x0, 0);
}
}
function withdraw() payable {
if (!allTokensAssigned) revert();
uint amount = pendingWithdrawals[msg.sender];
// Remember to zero the pending refund before
// sending to prevent re-entrancy attacks
pendingWithdrawals[msg.sender] = 0;
msg.sender.transfer(amount);
}
function enterBidForToken(uint tokenIndex) payable {
if (tokenIndex >= 10000) revert();
if (!allTokensAssigned) revert();
if (tokenIndexToAddress[tokenIndex] == 0x0) revert();
if (tokenIndexToAddress[tokenIndex] == msg.sender) revert();
if (msg.value == 0) revert();
Bid existing = tokenBids[tokenIndex];
if (msg.value <= existing.value) revert();
if (existing.value > 0) {
// Refund the failing bid
pendingWithdrawals[existing.bidder] += existing.value;
}
tokenBids[tokenIndex] = Bid(true, tokenIndex, msg.sender, msg.value);
TokenBidEntered(tokenIndex, msg.value, msg.sender);
}
function acceptBidForToken(uint tokenIndex, uint minPrice) {
if (tokenIndex >= 10000) revert();
if (!allTokensAssigned) revert();
if (tokenIndexToAddress[tokenIndex] != msg.sender) revert();
address seller = msg.sender;
Bid bid = tokenBids[tokenIndex];
if (bid.value == 0) revert();
if (bid.value < minPrice) revert();
tokenIndexToAddress[tokenIndex] = bid.bidder;
balanceOf[seller]--;
balanceOf[bid.bidder]++;
Transfer(seller, bid.bidder, 1);
tokensOfferedForSale[tokenIndex] = Offer(false, tokenIndex, bid.bidder, 0, 0x0);
uint amount = bid.value;
tokenBids[tokenIndex] = Bid(false, tokenIndex, 0x0, 0);
pendingWithdrawals[seller] += amount;
TokenBought(tokenIndex, bid.value, seller, bid.bidder);
}
function withdrawBidForToken(uint tokenIndex) {
if (tokenIndex >= 10000) revert();
if (!allTokensAssigned) revert();
if (tokenIndexToAddress[tokenIndex] == 0x0) revert();
if (tokenIndexToAddress[tokenIndex] == msg.sender) revert();
Bid bid = tokenBids[tokenIndex];
if (bid.bidder != msg.sender) revert();
TokenBidWithdrawn(tokenIndex, bid.value, msg.sender);
uint amount = bid.value;
tokenBids[tokenIndex] = Bid(false, tokenIndex, 0x0, 0);
// Refund the bid money
msg.sender.transfer(amount);
}
}
2) Following the creation, I would like to fetch some data from Oraclize, and depending on the forex USD/GBP rate transfer a token or not.
The following code is from the Oraclize example contract:
import "github.com/oraclize/ethereum-api/oraclizeAPI.sol";
contract ExampleContract is usingOraclize {
string public EURGBP;
string public value = "0.88086";
event LogPriceUpdated(string price);
event LogNewOraclizeQuery(string description);
function ExampleContract() payable public{
updatePrice();
}
function __callback(bytes32 myid, string result) public {
if (msg.sender != oraclize_cbAddress()) revert();
EURGBP = result;
if (keccak256(result) != keccak256(value)) {
LogPriceUpdated(value);
}
else {
LogPriceUpdated(result);
}
}
function updatePrice() payable public{
if (oraclize_getPrice("URL") > this.balance) {
LogNewOraclizeQuery("Oraclize query was NOT sent, please add some ETH to cover for the query fee");
} else {
LogNewOraclizeQuery("Oraclize query was sent, standing by for the answer..");
oraclize_query("URL", "json(http://api.fixer.io/latest?symbols=USD,GBP).rates.GBP");
}
}
}
Based on my understanding, I could make the main token contract inherit from the oracle contract. And the main contract should inherit all the functions from the oracle token contract.
Oraclize is a paid service, so I should make the updatePrice() always payable, and put something like 1 ether on the upper right side of Remix IDE.
Problems are double:
a) In the Official Remix IDE (JS VM), while the token contract executes, the Oraclize contract fails with "reverting the contract to initial state" message. Is it related to Oracle being paid? Because I always put like 1 ether in the top right side of the IDE. But I don´t know how to address this exactly.
b) In the Remix fork that Oraclize has (https://dapps.oraclize.it/browser-solidity/) using JS VM too, it will execute the query but it fails executing the token, with an "Invalid op code" message for the "calls". So I can't even get the token symbol.
Questions:
1) Also, besides the IDE issues, my doubt resides, in how should I proceed in giving a token on the condition that for example the USD/GBP value is X.
I assume that I should use the getToken() function in the main contract, check if the exchange rate is x, and assign the token? How I could do this effectively?
2) Should I use one of the events implemented in the main token contract, or it has got nothing to do with it?

I'm not sure if I can address you design questions as it seems more like a business problem than a coding/design issue (or I may not be understanding the question). If getToken is your point of sale and you want to reject any requests when the exchange rate is too low, then just make that a condition you check with a require statement. However, I will note that from the technical standpoint, you can't read events in a Solidity contract. You can only listen for them in a client which will receive the event(s) when the transaction is successfully mined.
I can, however, address your IDE issues. The reason for the failures is oraclizeAPI is dependent on already deployed contracts. They have a modifier which sets up the internal network of the contract depending on which environment it's running:
function oraclize_setNetwork(uint8 networkID) internal returns(bool){
if (getCodeSize(0x1d3B2638a7cC9f2CB3D298A3DA7a90B67E5506ed)>0){ //mainnet
OAR = OraclizeAddrResolverI(0x1d3B2638a7cC9f2CB3D298A3DA7a90B67E5506ed);
oraclize_setNetworkName("eth_mainnet");
return true;
}
if (getCodeSize(0xc03A2615D5efaf5F49F60B7BB6583eaec212fdf1)>0){ //ropsten testnet
OAR = OraclizeAddrResolverI(0xc03A2615D5efaf5F49F60B7BB6583eaec212fdf1);
oraclize_setNetworkName("eth_ropsten3");
return true;
}
if (getCodeSize(0xB7A07BcF2Ba2f2703b24C0691b5278999C59AC7e)>0){ //kovan testnet
OAR = OraclizeAddrResolverI(0xB7A07BcF2Ba2f2703b24C0691b5278999C59AC7e);
oraclize_setNetworkName("eth_kovan");
return true;
}
if (getCodeSize(0x146500cfd35B22E4A392Fe0aDc06De1a1368Ed48)>0){ //rinkeby testnet
OAR = OraclizeAddrResolverI(0x146500cfd35B22E4A392Fe0aDc06De1a1368Ed48);
oraclize_setNetworkName("eth_rinkeby");
return true;
}
if (getCodeSize(0x6f485C8BF6fc43eA212E93BBF8ce046C7f1cb475)>0){ //ethereum-bridge
OAR = OraclizeAddrResolverI(0x6f485C8BF6fc43eA212E93BBF8ce046C7f1cb475);
return true;
}
if (getCodeSize(0x20e12A1F859B3FeaE5Fb2A0A32C18F5a65555bBF)>0){ //ether.camp ide
OAR = OraclizeAddrResolverI(0x20e12A1F859B3FeaE5Fb2A0A32C18F5a65555bBF);
return true;
}
if (getCodeSize(0x51efaF4c8B3C9AfBD5aB9F4bbC82784Ab6ef8fAA)>0){ //browser-solidity
OAR = OraclizeAddrResolverI(0x51efaF4c8B3C9AfBD5aB9F4bbC82784Ab6ef8fAA);
return true;
}
return false;
}
When you run your example contract in JS VM (which is it's own sandbox), it doesn't have access to those contracts and the call fails. It works if you switch environments to Ropsten/Rinkeby and connect through MetaMask.

Related

How protocol Fee in UniswapV2 works?

function _mintFee(uint112 _reserve0, uint112 _reserve1) private returns (bool feeOn) {
address feeTo = IUniswapV2Factory(factory).feeTo();
feeOn = feeTo != address(0);
uint _kLast = kLast; // gas savings
if (feeOn) {
if (_kLast != 0) {
uint rootK = Math.sqrt(uint(_reserve0).mul(_reserve1));
uint rootKLast = Math.sqrt(_kLast);
if (rootK > rootKLast) {
uint numerator = totalSupply.mul(rootK.sub(rootKLast));
uint denominator = rootK.mul(5).add(rootKLast);
uint liquidity = numerator / denominator;
if (liquidity > 0) _mint(feeTo, liquidity);
}
}
} else if (_kLast != 0) {
kLast = 0;
}
}
// this low-level function should be called from a contract which performs important safety checks
function mint(address to) external lock returns (uint liquidity) {
(uint112 _reserve0, uint112 _reserve1,) = getReserves(); // gas savings
uint balance0 = IERC20(token0).balanceOf(address(this));
uint balance1 = IERC20(token1).balanceOf(address(this));
uint amount0 = balance0.sub(_reserve0);
uint amount1 = balance1.sub(_reserve1);
bool feeOn = _mintFee(_reserve0, _reserve1);
uint _totalSupply = totalSupply; // gas savings, must be defined here since totalSupply can update in _mintFee
if (_totalSupply == 0) {
liquidity = Math.sqrt(amount0.mul(amount1)).sub(MINIMUM_LIQUIDITY);
_mint(address(0), MINIMUM_LIQUIDITY); // permanently lock the first MINIMUM_LIQUIDITY tokens
} else {
liquidity = Math.min(amount0.mul(_totalSupply) / _reserve0, amount1.mul(_totalSupply) / _reserve1);
}
require(liquidity > 0, 'UniswapV2: INSUFFICIENT_LIQUIDITY_MINTED');
_mint(to, liquidity);
_update(balance0, balance1, _reserve0, _reserve1);
if (feeOn) kLast = uint(reserve0).mul(reserve1); // reserve0 and reserve1 are up-to-date
emit Mint(msg.sender, amount0, amount1);
}
I've start to reading uniV2 codes and i faced this problem, imagine the feeTo has been set in factory contract, and the new pair has been created, for the first time we deposit the amount to the pair contract, now the feeOn is true and kLast is zero that mean
if (feeOn) {
if (_kLast != 0) {
this condition doesn't meet, so my question is for the first time that we create a pair and feeOn is true, Does protocol take its fee?
I've tried to test it, but the protocol didn't take its portion Lp tokens at the first addLiquidity.

Borrowing 1INCH tokens from dYdX

I'm new to dydx flashloans and im builidng a flashloan that should borrow 1INCH tokens but when i tested it on remix it gave an error saying that the token wasnt supported. Is my code wrong or i just cant borrow 1INCH tokens from dydx.
import "#uniswap/v2-periphery/contracts/interfaces/IUniswapV2Router02.sol";
import "#openzeppelin/contracts/token/ERC20/IERC20.sol";
interface Structs {
struct Val {
uint256 value;
}
enum ActionType {
Deposit, // supply tokens
Withdraw, // borrow tokens
Transfer, // transfer balance between accounts
Buy, // buy an amount of some token (externally)
Sell, // sell an amount of some token (externally)
Trade, // trade tokens against another account
Liquidate, // liquidate an undercollateralized or expiring account
Vaporize, // use excess tokens to zero-out a completely negative account
Call // send arbitrary data to an address
}
enum AssetDenomination {
Wei // the amount is denominated in wei
}
enum AssetReference {
Delta // the amount is given as a delta from the current value
}
struct AssetAmount {
bool sign; // true if positive
AssetDenomination denomination;
AssetReference ref;
uint256 value;
}
struct ActionArgs {
ActionType actionType;
uint256 accountId;
AssetAmount amount;
uint256 primaryMarketId;
uint256 secondaryMarketId;
address otherAddress;
uint256 otherAccountId;
bytes data;
}
struct Info {
address owner; // The address that owns the account
uint256 number; // A nonce that allows a single address to control many accounts
}
struct Wei {
bool sign; // true if positive
uint256 value;
}
}
abstract contract DyDxPool is Structs {
function getAccountWei(Info memory account, uint256 marketId)
public
view
virtual
returns (Wei memory);
function operate(Info[] memory, ActionArgs[] memory) public virtual;
}
contract DyDxFlashLoan is Structs {
DyDxPool pool = DyDxPool(0x1E0447b19BB6EcFdAe1e4AE1694b0C3659614e4e);
address public WETH = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;
mapping(address => uint256) public currencies;
constructor() {
currencies[WETH] = 1;
}
modifier onlyPool() {
require(
msg.sender == address(pool),
"FlashLoan: could be called by DyDx pool only"
);
_;
}
function tokenToMarketId(address token) public view returns (uint256) {
uint256 marketId = currencies[token];
require(marketId != 0, "FlashLoan: Unsupported token");
return marketId - 1;
}
// the DyDx will call `callFunction(address sender, Info memory accountInfo, bytes memory data) public` after during `operate` call
function flashloan(
address token,
uint256 amount,
bytes memory data
) internal {
IERC20(token).approve(address(pool), amount + 1);
Info[] memory infos = new Info[](1);
ActionArgs[] memory args = new ActionArgs[](3);
infos[0] = Info(address(this), 0);
AssetAmount memory wamt = AssetAmount(
false,
AssetDenomination.Wei,
AssetReference.Delta,
amount
);
ActionArgs memory withdraw;
withdraw.actionType = ActionType.Withdraw;
withdraw.accountId = 0;
withdraw.amount = wamt;
withdraw.primaryMarketId = tokenToMarketId(token);
withdraw.otherAddress = address(this);
args[0] = withdraw;
ActionArgs memory call;
call.actionType = ActionType.Call;
call.accountId = 0;
call.otherAddress = address(this);
call.data = data;
args[1] = call;
ActionArgs memory deposit;
AssetAmount memory damt = AssetAmount(
true,
AssetDenomination.Wei,
AssetReference.Delta,
amount + 1
);
deposit.actionType = ActionType.Deposit;
deposit.accountId = 0;
deposit.amount = damt;
deposit.primaryMarketId = tokenToMarketId(token);
deposit.otherAddress = address(this);
args[2] = deposit;
pool.operate(infos, args);
}
}
contract Arbitrage is DyDxFlashLoan {
IUniswapV2Router02 immutable uRouter;
IUniswapV2Router02 immutable sRouter;
address public owner;
constructor(address _uRouter, address _sRouter) {
uRouter = IUniswapV2Router02(_uRouter);
sRouter = IUniswapV2Router02(_sRouter);
owner = msg.sender;
}
function executeTrade(
address _tokenA,
uint _tokensFromFlashLoan,
address _tokenB,
bool _startOnUniswap
) external {
uint balanceBefore = IERC20(_tokenA).balanceOf(address(this));
bytes memory data = abi.encode(
_startOnUniswap,
_tokenA,
_tokenB,
_tokensFromFlashLoan,
balanceBefore
);
flashloan(_tokenA, _tokensFromFlashLoan, data);
}
function callFunction(
address,
Info calldata,
bytes calldata data
) external onlyPool {
(
bool _startOnUniswap,
address _tokenA,
address _tokenB,
uint256 _tokensFromFlashLoan,
uint256 balanceBefore
) = abi.decode(data, (bool, address, address, uint256, uint256));
uint balanceAfter = IERC20(_tokenA).balanceOf(address(this));
require(
balanceAfter - balanceBefore == _tokensFromFlashLoan,
"didnt receive flash loan"
);
address[] memory tokens;
if (_startOnUniswap == true) {
tokens[0] = _tokenA;
tokens[1] = _tokenB;
swapOnUniswap(_tokensFromFlashLoan, 0, tokens);
tokens[0] = _tokenB;
tokens[1] = _tokenA;
swapOnSushiswap(
IERC20(tokens[0]).balanceOf(address(this)),
0,
tokens
);
} else {
tokens[0] = _tokenA;
tokens[1] = _tokenB;
swapOnSushiswap(_tokensFromFlashLoan, 0, tokens);
tokens[0] = _tokenB;
tokens[1] = _tokenA;
swapOnUniswap(
IERC20(tokens[0]).balanceOf(address(this)),
0,
tokens
);
}
}
function swapOnUniswap(
uint _amountIn,
uint _amountOut,
address[] memory _path
) internal {
require(
IERC20(_path[0]).approve(address(uRouter), _amountIn),
"Uniswap failed the approval"
);
uRouter.swapExactTokensForTokens(
_amountIn,
_amountOut,
_path,
address(this),
(block.timestamp + 1200)
);
}
function swapOnSushiswap(
uint _amountIn,
uint _amountOut,
address[] memory _path
) internal {
require(
IERC20(_path[0]).approve(address(sRouter), _amountIn),
"Sushiswap failed the approval"
);
uRouter.swapExactTokensForTokens(
_amountIn,
_amountOut,
_path,
address(this),
(block.timestamp + 1200)
);
}
}```
I tried to look at dydx docs but i didnt find nothing that could help me

ERC1155 Sell/Buy NFT Solidity

My contract for ERC1155 marketplace to mint buy and sell the NFT.
The nft is getting minted , However the NFT is not showing in market place and not able to purchase. I am facing this error.I have also applied setApprovedforAll method while minting still no help.
Should create and execute market sales:
Error: VM Exception while processing transaction: reverted with reason string 'ERC1155: caller is not owner nor approved'
at NFT1155.balanceOf (#openzeppelin/contracts/token/ERC1155/ERC1155.sol:71)
at NFT1155.isApprovedForAll (#openzeppelin/contracts/token/ERC1155/ERC1155.sol:110)
at NFT1155.createMarketSale (contracts/NFT1155.sol:165)
at async HardhatNode._mineBlockWithPendingTxs (node_modules/hardhat/src/internal/hardhat-network/provider/node.ts:1772:23)
at async HardhatNode.mineBlock (node_modules/hardhat/src/internal/hardhat-network/provider/node.ts:466:16)
at async EthModule._sendTransactionAndReturnHash (node_modules/hardhat/src/internal/hardhat-network/provider/modules/eth.ts:1496:18)
at async HardhatNetworkProvider.request (node_modules/hardhat/src/internal/hardhat-network/provider/provider.ts:118:18)
at async EthersProviderWrapper.send (node_modules/#nomiclabs/hardhat-ethers/src/internal/ethers-provider-wrapper.ts:13:20)
My contract for ERC1155 marketplace to mint buy and sell the NFT.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.11;
import "#openzeppelin/contracts/token/ERC1155/ERC1155.sol";
import "#openzeppelin/contracts/access/Ownable.sol";
import "#openzeppelin/contracts/token/ERC1155/extensions/ERC1155Supply.sol";
import "#openzeppelin/contracts/utils/Counters.sol";
import "hardhat/console.sol";
contract NFT1155 is ERC1155, Ownable, ERC1155Supply {
//contract address goes here and id will be dynamic and will be passed in the _mint function calls
//example https://ipfs.io/ipfs/QmT51bbxTbSiYGcF2X39sG6DGYyAX2413A1sZfiACMgJGP?filename={id}.json
//if the if id 1 then https://ipfs.io/ipfs/QmT51bbxTbSiYGcF2X39sG6DGYyAX2413A1sZfiACMgJGP?filename=1.json will return the data that needs to be minted
constructor() ERC1155("") {}
mapping(uint256 => string) internal _tokenURIs;
mapping(uint256 => MarketItem) private idToMarketItem;
Counters.Counter private _itemsSold;
struct MarketItem {
uint256 tokenId;
address payable seller;
address payable owner;
uint256 price;
bool sold;
}
event MarketItemCreated(
uint256 indexed tokenId,
address seller,
address owner,
uint256 price,
bool sold
);
using Counters for Counters.Counter;
Counters.Counter private _tokenIds;
//To chnage the URL String after the contract is deployed
function setURI(string memory newuri) public onlyOwner {
_setURI(newuri);
}
function mintToken(
string memory tokenURI,
uint256 amount,
uint256 price
) public returns (uint256) {
uint256 newItemId = _tokenIds.current();
_mint(address(this), newItemId, amount, "");
_setTokenUri(newItemId, tokenURI);
//createMarketItem(newItemId, price, amount);
_tokenIds.increment();
return newItemId;
}
function createMarketItem(
uint256 tokenId,
uint256 price,
uint256 amount
) private {
require(price > 0, "Price must be at least 1 wei");
idToMarketItem[tokenId] = MarketItem(
tokenId,
payable(msg.sender),
payable(address(this)),
price,
false
);
setApprovalForAll(address(this), true);
safeTransferFrom(msg.sender, address(this), tokenId, amount, "");
emit MarketItemCreated(
tokenId,
msg.sender,
address(this),
price,
false
);
}
function onERC1155Received(
address _operator,
address _from,
uint256 _id,
uint256 _value,
bytes calldata _data
) external returns (bytes4) {
return
bytes4(
keccak256(
"onERC1155Received(address,address,uint256,uint256,bytes)"
)
);
}
function _setTokenUri(uint256 tokenId, string memory tokenURI) private {
_tokenURIs[tokenId] = tokenURI;
}
function mintBatch(
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
) public onlyOwner {
_mintBatch(to, ids, amounts, data);
}
// The following functions are overrides required by Solidity.
function _beforeTokenTransfer(
address operator,
address from,
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
) internal override(ERC1155, ERC1155Supply) {
super._beforeTokenTransfer(operator, from, to, ids, amounts, data);
}
/* allows someone to resell a token they have purchased */
function resellToken(
uint256 tokenId,
uint256 price,
uint256 amount
) public payable {
require(
idToMarketItem[tokenId].owner == msg.sender,
"Only item owner can perform this operation"
);
idToMarketItem[tokenId].sold = false;
idToMarketItem[tokenId].price = price;
idToMarketItem[tokenId].seller = payable(msg.sender);
idToMarketItem[tokenId].owner = payable(address(this));
_itemsSold.decrement();
safeTransferFrom(msg.sender, address(this), tokenId, amount, "");
}
/* Creates the sale of a marketplace item */
/* Transfers ownership of the item, as well as funds between parties */
function createMarketSale(uint256 tokenId, uint256 amount) public payable {
uint256 price = idToMarketItem[tokenId].price;
address seller = idToMarketItem[tokenId].seller;
console.log(
" ~ file: NFT1155.sol ~ line 147 ~ createMarketSale ~ price",
msg.value,
price
);
// require(
// msg.value == price,
// "Please submit the asking price in order to complete the purchase"
// );
idToMarketItem[tokenId].owner = payable(msg.sender);
idToMarketItem[tokenId].sold = true;
idToMarketItem[tokenId].seller = payable(address(0));
_itemsSold.increment();
safeTransferFrom(address(this), msg.sender, tokenId, amount, "");
setApprovalForAll(address(this), true);
// payable(owner).transfer(listingPrice);
payable(seller).transfer(msg.value);
}
/* Returns all unsold market items */
function fetchMarketItems() public view returns (MarketItem[] memory) {
uint256 itemCount = _tokenIds.current();
uint256 unsoldItemCount = _tokenIds.current() - _itemsSold.current();
uint256 currentIndex = 0;
MarketItem[] memory items = new MarketItem[](unsoldItemCount);
for (uint256 i = 0; i < itemCount; i++) {
if (idToMarketItem[i + 1].owner == address(this)) {
uint256 currentId = i + 1;
MarketItem storage currentItem = idToMarketItem[currentId];
items[currentIndex] = currentItem;
currentIndex += 1;
}
}
return items;
}
/* Returns only items that a user has purchased */
function fetchMyNFTs() public view returns (MarketItem[] memory) {
uint256 totalItemCount = _tokenIds.current();
uint256 itemCount = 0;
uint256 currentIndex = 0;
for (uint256 i = 0; i < totalItemCount; i++) {
if (idToMarketItem[i + 1].owner == msg.sender) {
itemCount += 1;
}
}
MarketItem[] memory items = new MarketItem[](itemCount);
for (uint256 i = 0; i < totalItemCount; i++) {
if (idToMarketItem[i + 1].owner == msg.sender) {
uint256 currentId = i + 1;
MarketItem storage currentItem = idToMarketItem[currentId];
items[currentIndex] = currentItem;
currentIndex += 1;
}
}
return items;
}
/* Returns only items a user has listed */
function fetchItemsListed() public view returns (MarketItem[] memory) {
uint256 totalItemCount = _tokenIds.current();
uint256 itemCount = 0;
uint256 currentIndex = 0;
for (uint256 i = 0; i < totalItemCount; i++) {
if (idToMarketItem[i + 1].seller == msg.sender) {
itemCount += 1;
}
}
MarketItem[] memory items = new MarketItem[](itemCount);
for (uint256 i = 0; i < totalItemCount; i++) {
if (idToMarketItem[i + 1].seller == msg.sender) {
uint256 currentId = i + 1;
MarketItem storage currentItem = idToMarketItem[currentId];
items[currentIndex] = currentItem;
currentIndex += 1;
}
}
return items;
}
}
The problem is that because of the way you are minting, you don't own the token, the contract does.
Since you don't own the token, it doesn't appear in marketplaces and you can't call approve or transfer because you are not the owner of the token.
Here is the culprit:
_mint(address(this), newItemId, amount, "");
You are minting to address(this) which is the address of the contract itself.
You'll need a way to send the token from the contract to whomever you want using a custom function, or the probably better solution, you can just mint to the address calling your mintToken function by doing:
_mint(msg.sender, newItemId, amount, "");
Best of luck!!
When You call safeTransferFrom, require statement is not passing
function safeTransferFrom(address from,address to,uint256 id,uint256 amount,bytes memory data
) public virtual override {
require(
from == _msgSender() || isApprovedForAll(from, _msgSender()),
"ERC1155: caller is not owner nor approved"
);
_safeTransferFrom(from, to, id, amount, data);
}
Most likely you are transferring a token from the account that does not own the token,
You are using safeTransferFrom which is a public function. Try using _safeTransferFrom.You should add a custom function users can call, and internally use _safeTransferFrom

My "Buy" function in smart contract file keep making error

This is my solidity file for NFT marketplace.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "#openzeppelin/contracts/token/ERC721/ERC721.sol";
import "#openzeppelin/contracts/access/Ownable.sol";
import "#openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
import "#openzeppelin/contracts/utils/Counters.sol";
contract NFT is ERC721URIStorage,Ownable {
using Counters for Counters.Counter;
Counters.Counter private _tokenIds;
address payable public _owner;
mapping(address => uint[]) public addressToTokenArray;
mapping(uint256 => bool) public forSale;
mapping(uint256 => uint256) public tokenIdToPrice;
event Minting(address _owner, uint256 _tokenId, uint256 _price);
event Purchase(address _seller, address _buyer, uint256 _price);
event Remove(uint256 _tokenId, uint[] beforeBuy, uint[] afterBuy);
constructor() ERC721("TeddyBear", "TEDDY") {
}
function mint(string memory _tokenURI, uint256 _price) public onlyOwner returns (bool)
{
_tokenIds.increment();
uint256 newItemId = _tokenIds.current();
tokenIdToPrice[newItemId] = _price;
if(addressToTokenArray[msg.sender].length !=1){
addressToTokenArray[msg.sender].push(newItemId);
}else{
addressToTokenArray[msg.sender] = [newItemId];
}
_mint(msg.sender, newItemId);
_setTokenURI(newItemId, _tokenURI);
emit Minting(msg.sender, newItemId, _price);
return true;
}
// 토큰의 주인이 판매 하는 함수
function sell(uint256 _tokenId, uint256 _price) external {
require(msg.sender == ownerOf(_tokenId), 'Not owner of this token');
require(_price > 0, 'Price zero');
tokenIdToPrice[_tokenId] = _price;
forSale[_tokenId] = true;
}
// 토큰의 주인이 판매를 취하하는 함수
function stopSell(uint256 _tokenId) external {
require(msg.sender == ownerOf(_tokenId), 'Not owner of this token');
forSale[_tokenId] = false;
}
// function remove(uint[] memory array, uint index) public pure returns(uint[] memory) {
// if (index >= array.length) return array;
// for (uint i = index; i<array.length-1; i++){
// array[i] = array[i+1];
// }
// delete array[array.length-1];
// return array;
// }
function buy(uint256 _tokenId, uint256 sendAmount) external payable {
uint256 price = tokenIdToPrice[_tokenId];
bool isOnSale = forSale[_tokenId];
require(isOnSale, 'This token is not for sale');
require(sendAmount == price, 'Incorrect value');
address seller = ownerOf(_tokenId);
require(seller == ownerOf(_tokenId), 'Seller and Owner is not same');
// uint[] memory beforeBuy = addressToTokenArray[seller];
// // for(uint i=0;i<addressToTokenArray[seller].length;i++){
// // if(_tokenId == addressToTokenArray[seller][i]){
// // remove(addressToTokenArray[seller],i);
// // }
// // }
// uint[] memory afterBuy = addressToTokenArray[seller];
// emit Remove(_tokenId, beforeBuy, afterBuy);
addressToTokenArray[msg.sender] = [_tokenId];
safeTransferFrom(seller, msg.sender, _tokenId);
forSale[_tokenId] = true;
payable(seller).transfer(sendAmount); // send the ETH to the seller
emit Purchase(seller, msg.sender, sendAmount);
}
function getPrice(uint256 _tokenId) public view returns (uint256){
uint256 price = tokenIdToPrice[_tokenId];
return price;
}
function isSale(uint256 _tokenId) public view returns (bool){
bool isOnSale = forSale[_tokenId];
return isOnSale;
}
function getMyTokenId() public view returns (uint[] memory){
uint[] memory myTokens = addressToTokenArray[msg.sender];
return myTokens;
}
}
Among functions up there, the buy function does not emit an error when I compile the .sol file, but after I deploy this contract and send transaction for "buy" function it keeps making this error.
I just want to know where I should fix it and if there is any better idea for other functions, feel free to let me know... many thanks
Most likely it is failing here:
safeTransferFrom(seller, msg.sender, _tokenId);
If you check the ERC721 contract, safeTransferFrom eventually calls this:
function _transfer(
address from,
address to,
uint256 tokenId
) internal virtual {
require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer from incorrect owner");
require(to != address(0), "ERC721: transfer to the zero address");
_beforeTokenTransfer(from, to, tokenId);
// ****** HERE IS THE ISSUE *****
_approve(address(0), tokenId);
_balances[from] -= 1;
_balances[to] += 1;
_owners[tokenId] = to;
emit Transfer(from, to, tokenId);
_afterTokenTransfer(from, to, tokenId);
}
If your contract is going to transfer a token on behalf of owner, owner has to approve first.
so from the seller's contract, this should be called:
function _approve(address to, uint256 tokenId) internal virtual {
_tokenApprovals[tokenId] = to;
emit Approval(ERC721.ownerOf(tokenId), to, tokenId);
}
tokenApprovals is a mapping that keeps track of which tokens can be transferred.
Debugging
in order to test which function call is causing error, place this requirement statement require(sendAmount == price, 'Incorrect value'); right before the function. and pass an incorrect value and you will get an error : 'Incorrect value'
Then put that require statement after the function, and pass a wrong value, if this require does send you error, you can be sure that function is causing the error

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);
}
}