I have a smart contract to sell and buy my ERC20 token . My each token is 0.0168 ETH and I charge a fee for both buying and selling. I am using remix to check my contract and is deployed in polygon testnet. I have deployed my contract and was able to buy and sell but when I buy 1 token I get 0.000000000000000001 in my wallet and its the same with selling.

when I deploy I use tokenPrice as 16800000000000000 and my feePercent as 3. What am I doing wrong?

My contract:

// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;

import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/release-v4.5/contracts/token/ERC20/IERC20.sol";

contract TokenSale {
    address public admin;
    IERC20 public token;
    uint256 public tokenPrice;
    uint256 public tokensSold;
    uint256 public feePercent;
    address public feeAddress;

    event Sell(address indexed _buyer, uint256 _amount);

    constructor(IERC20 _token, uint256 _tokenPrice,uint256 _feePercent,address _feeAddress) {
        admin = msg.sender;
        token = _token;
        tokenPrice = _tokenPrice;
        feePercent = _feePercent;
        feeAddress = _feeAddress;

    function buyTokens(uint256 _numberOfTokens) public payable {
        uint256 pricePerToken = tokenPrice;
        uint256 totalFee = (_numberOfTokens * feePercent)/100;
        uint256 totalAmount = (_numberOfTokens-totalFee)* pricePerToken;

        require(msg.value >= totalAmount, "Invalid amount of ether sent");
        require(token.balanceOf(address(this)) >= _numberOfTokens, "Insufficient tokens in contract");
        require(token.transfer(msg.sender, _numberOfTokens-totalFee), "Token transfer failed");
        require(token.transfer(feeAddress, totalFee),"Token transfer failed");
        tokensSold += _numberOfTokens;
        emit Sell(msg.sender, _numberOfTokens);
    function sellTokens(uint256 _numberOfTokens) public payable{
        uint256 pricePerToken = tokenPrice;
        uint256 totalFee = (_numberOfTokens * feePercent)/100;
        uint256 totalAmount = (_numberOfTokens - totalFee) * pricePerToken;
        require(token.balanceOf(msg.sender) >= _numberOfTokens, "Insufficient tokens balance");
        require(address(this).balance >= totalAmount, "Contract has insufficient ether balance");
        require(token.transferFrom(msg.sender, address(this), _numberOfTokens), "Token transfer failed");
        require(token.transfer(feeAddress, totalFee), "Token transfer failed");

        tokensSold += _numberOfTokens - totalFee;
        emit Sell(msg.sender, _numberOfTokens - totalFee);

    function endSale() public payable{
        require(msg.sender == admin, "Only admin can end sale");
        require(token.transfer(admin, token.balanceOf(address(this))), "Token transfer failed");

My token contract:

// SPDX-License-Identifier: MIT
pragma solidity  ^0.8.17;

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/access/Ownable.sol";

contract TokenTest is ERC20, Ownable {
    mapping(address => uint256) ownedTokens;
    constructor() ERC20("GuCC", "GUC") {
        uint256 initialSupply = 100*10**18;
        _mint(msg.sender, initialSupply);


3 Answers 3


You need to make sure you consider the number of decimals in your token. By default, it is 18 decimals in most open source implementations. If you want one token and youre interacting on say etherscan, you need to submit buyTokens with _numberOfTokens = 1000000000000000000.

Also, to properly calculate numbers of tokens bought, you need to consider that eth itself has 18 decimals. So the formula should be numberOfTokens * 1e18 / pricePerToken.


You can deploy your smart contract by using a development environment such as Ethereum, Remix, or Truffle. You will then need to provide the correct inputs, such as parameters and variables, to make sure the contract is configured correctly.


I decide to use this technique. This is what I was told to try by a friend, and I suggest you do the same. Smart contracts can be deployed in a straightforward manner. To get started with contracts, you must convert their source code into bytecode, which is the language understood by the Ethereum Virtual Machine (EVM). Once the bytecode is ready, a transaction can be sent to the network to deploy it to the blockchain. Finally, you'll need to give the contract the information it needs, such as the sender's address, the amount of Ether, and any other parameters it specifies. When all of the necessary information is provided, the contract can be activated and put into use.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.