Security audit for Token Distribution ICO - blockchain

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

Related

swap 2 erc20 with each other at one method between 2 different user. -- Reentrancy guard problem

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 try to deploy a contract on rinkeby testnet with some eth but there is an error occurred

The error I face in remix is Gas estimation errored with the following message (see below). The transaction execution will likely fail. Do you want to force sending?
execution reverted even if I have enough money to create a contract
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
// Get the latest ETH/USD price from chainlink price feed
import "#chainlink/contracts/src/v0.6/interfaces/AggregatorV3Interface.sol";
contract FundMe {
// safe math library check uint256 for integer overflows
//mapping to store which address depositeded how much ETH
mapping(address => uint256) public addressToAmountFunded;
// array of addresses who deposited
address[] public funders;
//address of the owner (who deployed the contract)
address public owner;
constructor() public {
owner = msg.sender;
}
function fund() public payable {
// 18 digit number to be compared with donated amount
uint256 minimumUSD = 50 * 10 ** 18;
//is the donated amount less than 50USD?
require(getConversionRate(msg.value) >= minimumUSD, "You need to spend more ETH!");
//if not, add to mapping and funders array
addressToAmountFunded[msg.sender] += msg.value;
funders.push(msg.sender);
}
function getVersion() public view returns (uint256){
AggregatorV3Interface priceFeed = AggregatorV3Interface(0x9326BFA02ADD2366b30bacB125260Af641031331);
return priceFeed.version();
}
function getPrice() public view returns(uint256){
AggregatorV3Interface priceFeed = AggregatorV3Interface(0x9326BFA02ADD2366b30bacB125260Af641031331);
(,int256 answer,,,) = priceFeed.latestRoundData();
// ETH/USD rate in 18 digit
return uint256(answer * 10000000000);
}
function getConversionRate(uint256 ethAmount) public view returns (uint256){
uint256 ethPrice = getPrice();
uint256 ethAmountInUsd = (ethPrice * ethAmount) / 1000000000000000000;
// the actual ETH/USD conversation rate, after adjusting the extra 0s.
return ethAmountInUsd;
}
}
1)try downgrading your compiler version to 0.5
if that does not work try this
2)In remix try to increase your gas limit to probably 8000000
You need a receve/fallback function to send ETH to a contract. Try to add these to your contract code:
receive() external payable {
// React to receiving ether
}

I want to make a time based transaction in smart contract

I am creating smart contract for lottery system and I want to make a time based transaction like a certain amount of players are added into the array then a time stamp should run and on specific time which I will declare should send the amount to the winner,
This is the part where I am stuck, I am trying to enter into the lottery from this this function and when conditions met I want to transfer the amount through the same function cause I want to automate the winner function:
function enter() public payable{
require(msg.value > 1 wei);
players.push(msg.sender);
if(players.length==10){
start = block.timestamp;
}
if(block.timestamp>= start+totalTime){
uint index = random()% players.length;
players[index].transfer(this.balance);
dead[index].transfer((this.balance*2)/100);
winner = players[index];
players = new address[](0);
}
This is my complete code:
pragma solidity ^0.4.26;
contract Lottery{
address public manager;
address[] public players;
address [0x000000000000000000000000000000000000dead] private dead;
address public winner;
uint start;
uint end;
uint totalTime=50;
constructor()public {
manager = msg.sender;
}
function enter() public payable{
require(msg.value > 1 wei);
players.push(msg.sender);
if(players.length==10){
start = block.timestamp;
}
if(block.timestamp>= start+totalTime){
uint index = random()% players.length;
players[index].transfer(this.balance);
dead[index].transfer((this.balance*2)/100);
winner = players[index];
players = new address[](0);
}
}
function random() private view returns (uint){
return uint(keccak256(block.difficulty,now,players));
}
function getBalance() public view returns(uint){
return address(this).balance;
}
function getPlayers() public view returns (address[]){
return players;
}
function getWinner() public view returns (address){
return winner;
}
function getTime() public view returns (uint){
return end-block.timestamp;
}
}
You can't, someone has to call the function and pay the gas fees, what you can do is having an script that listen for events and every time someone "enters" in the lottery and check if already reached the desired amount and then calls the function to get the winner, also you can't have any logic outside a function in solidity, using block difficulty and timestamp as a source of randomness if you are planing to deploy to production is better to use chainlink

Implementing buying and selling in Solidity

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.

Solidity : Getting error as Member “balance” not found or not visible after argument-dependent lookup

I am trying to write a Decentralization App to buy a concert ticket. For some reason, the part owner.transfer(this.balance) keeps giving me error. Also since solidity has too many version, I can't find a the best for mine. please help me in this. Thank you
Erro Message
Getting error as Member “balance” not found or not visible after argument-dependent lookup. Use address(this).balance to access address owner.transfer(this.balance)
Solidity Code
pragma solidity 0.6.6;
contract Event {
address owner;
uint public tickets;
string public description;
string public website;
uint constant price = 0.01 ether;
mapping (address => uint) public purchasers;
constructor(uint t, string memory _description, string memory _webstite) public {
owner = msg.sender;
description = _description;
website = _webstite;
tickets = t;
}
// function () payable {
// buyTickets(1);
// }
function buyTickets(uint amount) public payable {
if (msg.value != (amount * price) || amount > tickets) {
revert();
}
purchasers[msg.sender] += amount;
tickets -= amount;
if (tickets == 0) {
owner.transfer(this.balance);
}
}
function refund(uint numTickets) public {
if (purchasers[msg.sender] < numTickets) {
revert();
}
msg.sender.transfer(numTickets * price);
purchasers[msg.sender] -= numTickets;
tickets += numTickets;
}
}
After I change it to owner.transfer(address(this).balance);, it gave me another error.
[vm] from: 0x5b3...eddc4to: Event.buyTickets(uint256) 0xd91...39138value: 0 weidata: 0x2f3...00001logs: 0hash: 0x030...bbdf1
status 0x0 Transaction mined but execution failed
transaction hash 0x03045aab3f5d40ebeef4eacedf50ce506edfc2b75c279652839fd74f8e9bbdf1
from 0x5b38da6a701c568545dcfcb03fcb875f56beddc4
to Event.buyTickets(uint256) 0xd9145cce52d386f254917e481eb44e9943f39138
gas 3000000 gas
transaction cost 21760 gas
execution cost 296 gas
hash 0x03045aab3f5d40ebeef4eacedf50ce506edfc2b75c279652839fd74f8e9bbdf1
input 0x2f3...00001
decoded input { "uint256 amount": { "_hex": "0x01" } }
decoded output {}
logs []
value 0 wei
transact to Event.buyTickets errored: VM error: revert. revert The transaction has been reverted to the initial state. Note: The called function should be payable if you send value and the value you send should be less than your current balance. Debug the transaction to get more information.
transfer is only able for payable address.
try as follows.
address payable owner;
...
owner.transfer(address(this).balance);