I have written the FarihaToken which is ERC20 standard complaint, the code is below:
contract FarihaToken is ERC20Interface{
using SafeMath for uint;
string public symbol;
string public name;
uint8 public decimals;
uint public _totalSupply;
mapping(address => uint) balances;
mapping(address => mapping(address => uint)) allowed;
// ------------------------------------------------------------------------
// Constructor
// ------------------------------------------------------------------------
function FarihaToken() public{
symbol = "FTC";
name = "Fariha Token";
decimals = 18;
_totalSupply = totalSupply();
balances[msg.sender] = _totalSupply;
Transfer(address(0),msg.sender,_totalSupply);
}
function totalSupply() public constant returns (uint){
return 1000000 * 10**uint(decimals);
}
// ------------------------------------------------------------------------
// Get the token balance for account `tokenOwner`
// ------------------------------------------------------------------------
function balanceOf(address tokenOwner) public constant returns (uint balance) {
return balances[tokenOwner];
}
// ------------------------------------------------------------------------
// Transfer the balance from token owner's account to `to` account
// - Owner's account must have sufficient balance to transfer
// - 0 value transfers are allowed
// ------------------------------------------------------------------------
function transfer(address to, uint tokens) public returns (bool success){
balances[msg.sender] = balances[msg.sender].sub(tokens);
balances[to] = balances[to].add(tokens);
Transfer(msg.sender,to,tokens);
return true;
}
// ------------------------------------------------------------------------
// Token owner can approve for `spender` to transferFrom(...) `tokens`
// from the token owner's account
//
// https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20-token-standard.md
// recommends that there are no checks for the approval double-spend attack
// as this should be implemented in user interfaces
// ------------------------------------------------------------------------
function approve(address spender, uint tokens) public returns (bool success){
allowed[msg.sender][spender] = tokens;
Approval(msg.sender,spender,tokens);
return true;
}
// ------------------------------------------------------------------------
// Transfer `tokens` from the `from` account to the `to` account
//
// The calling account must already have sufficient tokens approve(...)-d
// for spending from the `from` account and
// - From account must have sufficient balance to transfer
// - Spender must have sufficient allowance to transfer
// - 0 value transfers are allowed
// ------------------------------------------------------------------------
function transferFrom(address from, address to, uint tokens) public returns (bool success){
balances[from] = balances[from].sub(tokens);
allowed[from][to] = allowed[from][to].sub(tokens);
balances[to] = balances[to].add(tokens);
Transfer(msg.sender,to,tokens);
return true;
}
// ------------------------------------------------------------------------
// Returns the amount of tokens approved by the owner that can be
// transferred to the spender's account
// ------------------------------------------------------------------------
function allowance(address tokenOwner, address spender) public constant returns (uint remaining) {
return allowed[tokenOwner][spender];
}
}
contract PurchaseToken is FarihaToken{
// Accept ETH and return FTC
function() public payable {
var amount = msg.value/2 ;
require(balanceOf(this) >= amount);
transfer(msg.sender,amount);
}
}
Use case is that when some one sends 2 ethers it'll send back 1 token. I'm using truffle as dev framework, I'm newbie to this so I have some questions to ask if someone can help me with them:
I want to send ethers. How can I do that? which account to use? a
truffle command will be useful.
I want to make sure that the account that send ethers have received
tokens as well. Command would be useful.
Is there a way I can see my ethers in account using truffle ?
P.S: I tried running this on truffle but it reverts the action.
PurchaseToken.deployed().then(function(D){ff=D;});
ff.send(2)
Transfer of tokens means you will deduct the tokens from contract account and add these token to msg.sender.
Please go through the following contract which consists of the functionality-
https://github.com/ganeshdipdumbare/coin-with-whitelisting/blob/master/GCoinAdvance.sol
Related
I know I have to use nonReentrant modifier for this method, but I also know it's wont work can someone tell me what should I do to create a mechanism something like this with safe pattern?
function swapTokenToEvolve(uint256 _tokenAmount, uint256 _stageIndex)
public
checkStageTime(_stageIndex)
checkRemainingAmount(_tokenAmount, _stageIndex)
nonReentrant
returns (bool)
{
// get token price from stage ;
uint256 tokenPrice = salesStages[_stageIndex].price;
// how many tokens user will get;
uint256 stableTokenAmount = multiply(_tokenAmount, tokenPrice, decimal);
// transfer token from buyer to seller;
require(
IERC20(currencyToken).transferFrom(
owner(),
_msgSender(),
_tokenAmount
)
);
// transfer token from seller to user;
require(
IERC20(token).transferFrom(_msgSender(), owner(), stableTokenAmount)
);
salesStages[_stageIndex].liquidity = salesStages[_stageIndex]
.liquidity
.sub(_tokenAmount);
return true;
}
before any "transferFrom" you have to take approve from token owner, on the other hand to prevent "reentrancy" you have to change the variable before any external call, I suggest 2 steps:
1-get approve from the token owner before this function(because msg.sender checked in that) or if you want using in this function user ERC-20-permit
2-change your state variable line.salesStages[_stageIndex].liquidity = salesStages[_stageIndex] .liquidity .sub(_tokenAmount); before your external call.
The transferFrom method from ERC20 token is the following:
function transferFrom(
address from,
address to,
uint256 amount
) public virtual override returns (bool) {
address spender = _msgSender();
_spendAllowance(from, spender, amount);
_transfer(from, to, amount);
return true;
}
Where _spendAllowance requires the allowance to exists for the transfer amount:
function _spendAllowance(
address owner,
address spender,
uint256 amount
) internal virtual {
uint256 currentAllowance = allowance(owner, spender);
if (currentAllowance != type(uint256).max) {
require(currentAllowance >= amount, "ERC20: insufficient allowance");
unchecked {
_approve(owner, spender, currentAllowance - amount);
}
}
}
Therefore, you do not need to require the transferFrom. What you need to do is make sure the contract has enough allowance from both owner() (first transfer) and _msgSender() (second transfer).
I was following the tutorial of Chainlink docs at https://docs.chain.link/docs/advanced-tutorial/ to make an API call from my smart contract. However, I am still not able to understand the function setPublicChainlinkToken() that is being called in the constructor of APIConsumer.
I am trying to fetch the temperature of a city through the API call. But my contract gives an error in compilation saying:
APIConsumer hit a require or revert statement somewhere in its constructor
The above error is very generic and I am unable to understand what is the issue. Below is my contract code and the script which I am using to deploy it.
What params do I need to pass in the deploy script?
APIConsumer contract
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
import "#chainlink/contracts/src/v0.6/ChainlinkClient.sol";
/**
* THIS IS AN EXAMPLE CONTRACT WHICH USES HARDCODED VALUES FOR CLARITY.
* PLEASE DO NOT USE THIS CODE IN PRODUCTION.
*/
contract APIConsumer is ChainlinkClient {
using Chainlink for Chainlink.Request;
uint256 public temperature;
address private oracle;
bytes32 private jobId;
uint256 private fee;
constructor () public {
setPublicChainlinkToken(); // Do I need to pass any params for this?
// if (_link == address(0)) {
// setPublicChainlinkToken();
// } else {
// setChainlinkToken(_link);
// }
// setPublicChainlinkToken();
oracle = <oracle id>; // Removed oracle id and jobid values for post
jobId = <job id>;
fee = 0.1 * 10 ** 18; // 0.1 LINK (Varies by network and job)
}
/**
* Create a Chainlink request to retrieve API response, find the target
* data, then multiply by 1000000000000000000 (to remove decimal places from data).
*/
function requestVolumeData() public returns (bytes32 requestId)
{
Chainlink.Request memory request = buildChainlinkRequest(jobId, address(this), this.fulfill.selector);
// Set the URL to perform the GET request on
// "https://min-api.cryptocompare.com/data/pricemultifull?fsyms=ETH&tsyms=USD"
request.add("get", "http://api.weatherstack.com/current?access_key=7940b0c1136901badcb304724132b234&query=Mumbai");
// Set the path to find the desired data in the API response, where the response format is:
// {"RAW":
// {"ETH":
// {"USD":
// {
// "VOLUME24HOUR": xxx.xxx,
// }
// }
// }
// }
request.add("path", "current.temperature");
// Multiply the result by 1000000000000000000 to remove decimals
// int timesAmount = 10**18;
// request.addInt("times", timesAmount);
// Sends the request
return sendChainlinkRequestTo(oracle, request, fee);
}
/**
* Receive the response in the form of uint256
*/
function fulfill(bytes32 _requestId, uint256 _temperature) public recordChainlinkFulfillment(_requestId)
{
temperature = _temperature;
}
// function withdrawLink() external {} - Implement a withdraw function to avoid locking your LINK in the contract
}
Javascript Script To Deploy:
const APIConsumer = artifacts.require("APIConsumer");
module.exports = async (deployer, network, [defaultAccount]) => {
try {
await deployer.deploy(APIConsumer);
} catch (err) {
console.error(err);
}
};
setChainlinkToken is a function that tells the oracle contract what it should use to accept LINK payments. It points to an ERC677 token for the contracts to use.
You have to know what the LINK token address is to use this function.
The setPublicChainlinkToken() is a way to set the LINK token address without knowing it's address. There is an on-chain contract (on specific chains) that has a pointer to a "link token contract" registry that points to the address of the LINK token on different chains. So this function gets the address by looking at this lookup table, then calls the setChainlinkToken function with this address.
You're then getting the error you specified, because the oracle contract you're interacting with doesn't know what the address of the LINK token is.
// if (_link == address(0)) {
// setPublicChainlinkToken();
// } else {
// setChainlinkToken(_link);
// }
// setPublicChainlinkToken();
So i want to be able to buy/sell the token, but also have the ability for users to send eth to my contract wallet and receive my tokens in exchange. I believe i have the code ready for buyers and sellers to make a transaction together, dont think i have the pieces for someone to recieve tokens for sending me ethereum. I would like to make it so at the start people send me eth for a number of coins set at a base value
pragma solidity 0.4.22;
contract ERC20Basic {
string public constant name = "Community Token";
string public constant symbol = "COMM";
uint8 public constant decimals = 1;
event Approval(address indexed tokenOwner, address indexed spender, uint tokens);
event Transfer(address indexed from, address indexed to, uint tokens);
mapping(address => uint256) balances;
mapping(address => mapping (address => uint256)) allowed;
uint256 totalSupply_;
using SafeMath for uint256;
constructor(uint256 total) public {
totalSupply_ = total;
balances[msg.sender] = totalSupply_;
}
function totalSupply() public view returns (uint256) {
return totalSupply_;
}
function balanceOf(address tokenOwner) public view returns (uint) {
return balances[tokenOwner];
}
function transfer(address receiver, uint numTokens) public returns (bool) {
require(numTokens <= balances[msg.sender]);
balances[msg.sender] = balances[msg.sender].sub(numTokens);
balances[receiver] = balances[receiver].add(numTokens);
emit Transfer(msg.sender, receiver, numTokens);
return true;
}
function approve(address delegate, uint numTokens) public returns (bool) {
allowed[msg.sender][delegate] = numTokens;
emit Approval(msg.sender, delegate, numTokens);
return true;
}
function allowance(address owner, address delegate) public view returns (uint) {
return allowed[owner][delegate];
}
function transferFrom(address owner, address buyer, uint numTokens) public returns (bool) {
require(numTokens <= balances[owner]);
require(numTokens <= allowed[owner][msg.sender]);
balances[owner] = balances[owner].sub(numTokens);
allowed[owner][msg.sender] = allowed[owner][msg.sender].sub(numTokens);
balances[buyer] = balances[buyer].add(numTokens);
emit Transfer(owner, buyer, numTokens);
return true;
}
}
library SafeMath {
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;
}
}
A very basic example of buy and sell:
pragma solidity ^0.8;
contract ERC20Basic{
uint256 public constant tokenPrice = 5; // 1 token for 5 wei
function buy(uint256 _amount) external payable {
// e.g. the buyer wants 100 tokens, needs to send 500 wei
require(msg.value == _amount * tokenPrice, 'Need to send exact amount of wei');
/*
* sends the requested amount of tokens
* from this contract address
* to the buyer
*/
transfer(msg.sender, _amount);
}
function sell(uint256 _amount) external {
// decrement the token balance of the seller
balances[msg.sender] -= _amount;
increment the token balance of this contract
balances[address(this)] += _amount;
/*
* don't forget to emit the transfer event
* so that external apps can reflect the transfer
*/
emit Transfer(msg.sender, address(this), _amount);
// e.g. the user is selling 100 tokens, send them 500 wei
payable(msg.sender).transfer(amount * tokenPrice);
}
}
This will allow any user to buy or sell tokens from/to your contract. Your contract will need to own these tokens in order to sell them to the users. Also your contract will need to have enough ETH in order to buy back tokens from the users.
You can expand on this code to implement
a contract owner that is authorized to change the price
different prices for buy and sell
fees
min/max amounts (per one transaction, per user, per day, ...)
calculating the amount of tokens based on the msg.value (the user won't have to have the exact amount)
etc...
Note that my snippet is using Solidity 0.8 where integer overflow is prevented automatically. The question is using deprecated Solidity 0.4, so that you'd need to use SafeMath, check the value with require/assert or upgrade to Solidity 0.8 to reach the same result.
I have Crowdsale contract written on the basis of OpenZepelin Crowdsale.sol
my contract:
contract MoonShardToken is StandardToken, Ownable {
string public name = "MyContract";
uint8 public decimals = 18;
string public symbol = "My";
/// this constructor added as a test
constructor() public {
totalSupply_ = (36000000 * (10 ** 18));
balances[msg.sender] = totalSupply_;
}
}
my crowdsale is copy of OpenZepelin Crowdsale.sol, i deploy my contract with truffle, i can console.log in tests my rate: 200000000000000
TotalSupply of my tokens: 3.6e+25, all functions in tests from contract works correctly, but when i use function buyTokens whith massage value more then zero i become error VM Exception while processing transaction: revert;when msg.value is zero i become no errors, and event in func emited
this is function buyTokens:
function buyTokens(address _beneficiary) public payable {
uint256 weiAmount = msg.value;
// _preValidatePurchase(_beneficiary, weiAmount); this is function with required msg.value>0 was commented for test
uint256 tokens = _getTokenAmount(weiAmount);
weiRaised = weiRaised.add(weiAmount);
_processPurchase(_beneficiary, tokens);
emit TokenPurchase(
msg.sender,
_beneficiary,
weiAmount,
tokens
);
_forwardFunds();
}
in truffle tests i use this function as: await Crowdsale.buyTokens(wallet, {from: wallet, value: web3.toWei(0.0001, "ether")});
wallet is account(1) with token balance 0. i use ganache cli and all my accs have ether? simple transaction works correctly.
When attempting buyTokens, this function calls _getTokenAmount(weiAmount) which returns weiAmount.mul(_rate). Can you post your migrations file? It may be that _rate is not set properly during deployment.
This is our MEG-Token-Distribution 1.0. We need a help from someone.
Link for full code.
How we can make access for mint function (token owner is EggithCrowdsale)?
How we can change rate depend on msg.value (if > 20 ETH price another)?
contract EggithToken is MintableToken {
string public constant name = "EggithToken";
string public constant symbol = "MEG";
uint8 public constant decimals = 18;
}
contract EggithCrowdsale is Crowdsale {
function EggithCrowdsale(uint256 _startTime, uint256 _endTime, uint256 _rate, address _wallet)
Crowdsale(_startTime, _endTime, _rate, _wallet)
{
}
// creates the token to be sold.
// override this method to have crowdsale of a specific mintable token.
function createTokenContract() internal returns (MintableToken) {
return new EggithToken();
}
}
"How we can change rate depend on msg.value (if > 20 ETH price another)?"
uint public constant regularPrice = 100;
uint public constant moreThan20EthContributionPrice = 75;
function () payable {
//fallback function that is called when ETH is sent to contract
... some code ...
uint price = calculatePrice();
... some code ...
}
function calculatePrice() internal constant returns (uint) {
if (msg.value > 20 ether) return moreThan20EthContributionPrice;
return regularPrice;
}