3

I have a smart contract with 0.15 Ether = 1 Token So when user send 0.15 Ether it's fine he receive 1 Token, but if he sent 1 Ether normally should receive 6.66 Token, but the contract sent only 6 Tokens ?

Same case with any decimal number AA.BC it send alwayse A and ignore any number after commas.

USED FUNCTION:

    uint amount = msg.value;

    uint tokentosend = amount / price;
    tokenReward.transfer(msg.sender, tokentosend);

Can you please help ?

1
  • In first place, this obviously comes from making variable tokentosend an integer. Please provide some more information on the context and why you took this decision. If function transfer requires an integer variable you will not be able to send fractional values.
    – gisdev_p
    Nov 19, 2017 at 8:04

3 Answers 3

2

The reason for this is that variable tokentosend is an integer. Therefore it will neglect the fractional part of the result of the division.

If you have to work with integers, you could change the unit of the tokens. As an example, if you work with millitokens, such that 1000 millitokens = 1 token, you would transfer 6660 millitokens instead of 6.66 tokens. This is in principle the same as Ethereum does, which actually works in wei with 1e18 wei = 1 Ether, even though we usually think in Ether.

Note, however, since you calculate the number of tokens from an Ether value, you would run into the issue with decimal values even if you used millitokens. To avoid the issue you need to work with the smallest unit your token value can take. This depends on the smallest unit of the Ether value, which is 1 wei, and the conversion factor.

1

This is the intended behavior. The uint type that you use to hold the result of the division can only hold integers. Any remainder will be discarded.

Besides, solidity does not yet implement the float type.

A work-around would be to use the modulo operator (%) to check that the amount of ether sent can be converted cleanly to an integer number of tokens, using your convertion ratio. If thats the case, you can proceed with the rest of your instructions, otherwise throw an exception and stop the execution.

0

Yes It's working , thank you guys (I did just added : (amount * 1000) / price) and it works. But my token is 3 Decimals on test network, and anyone can change decimals for now ...

Is that also possible on Main network ? Anyone will add my token address can update decimals number ? or it's only possible in the Test Network ?

3
  • 1
    Sure, main net runs on the same code as the test nets, so you will have the same behaviour.
    – gisdev_p
    Nov 19, 2017 at 21:17
  • Really, so now my Token is ruining on 3 decimals (ex: 5.123) What If I send 1 Token to an Address then he switched Decimals to 0 ? He will get 1000 Token Instead ? If Yes, is this a security issue ? how can I solve it ? Nov 19, 2017 at 22:19
  • 1
    He cannot switch because the contract defines the number of decimals. If someone deploys the contract (with same or other decimal settings), it will be a different adress and he will create a new token, but not change the value of your token.
    – gisdev_p
    Nov 19, 2017 at 22:28

Your Answer

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

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