# Crazy Math Result from OpenZeppelin

I was getting a "EVM error", so I commented out some code and backtracked to find the issue. I added my _feeAmount to an Emit, and getting a what seems to be a bizarre math answer on a simple math problem.

results displayed from Truffle Unit Test with console.log statements. Everything converted from WeiToEth.

``````event.feePercent =10
event.FeeAmount  =-18
event.amountGet  =2
event.amountGive =1
``````

FeeAmount should be 2 / 100 * 10 which should be .2 but I'm getting -18. No idea why it's negative.

``````import "openzeppelin-solidity/contracts/math/SafeMath.sol";
...

function _trade(uint _orderId, address _user, address _tokenGet,
uint _amountGet, address _tokenGive, uint _amountGive) internal {
// Fee paid by the user that fills the order, a.k.a. msg.sender.
// charge fees - paid by msg.sender - user filling the order
// taken from the amount he gets
uint _feeAmount = _amountGet.div(100).mul(feePercent);

// do the trade, _user created the order, msg.sender is filling the order
//tokens[_tokenGet][msg.sender] = tokens[_tokenGet][msg.sender].sub(_amountGet.add(_feeAmount));
/*
tokens[_tokenGet][_user] = tokens[_tokenGet][_user].add(_amountGet);

// send the fees to the feeAccount
tokens[_tokenGet][feeAccount] = tokens[_tokenGet][feeAccount].add(_feeAmount);

tokens[_tokenGive][_user] = tokens[_tokenGive][_user].sub(_amountGive);
tokens[_tokenGive][msg.sender] = tokens[_tokenGive][msg.sender].add(_amountGive);
*/

// emit trade event
emit Trade(_orderId, _user, _tokenGet, _amountGet, _tokenGive, _amountGive, _feeAmount,
feePercent, msg.sender, now);
}
``````

Truffle test code:

it('emits a "Trade" event', async () => { // this is why we needed the "result=" above; // "result" is what a subscriber would get subscribing to this event //console.log(result); console.log("Number of logs=" + result.logs.length)

``````const log = result.logs[0];
let event;
// get event from logs
event = log.args

console.log("event.feePercent =" + event.feePercent);
console.log("event.FeeAmount  ="  + WeiToEth(event.feeAmount))
console.log("event.amountGet  ="  + WeiToEth(event.amountGet))
console.log("event.amountGive ="  + WeiToEth(event.amountGive))
``````

Definition of Trade event:

``````  event Trade(
uint id,
address user,
address tokenGet,
uint amountGet,
address tokenGive,
uint amountGive,
uint feeAmount,
uint feePercent,
address userFill,
uint timestamp
);
``````

Helper function:

``````export const WeiToEth = (n) => {
return new web3.utils.BN(
web3.utils.fromWei(n.toString(),'ether')
)
}
``````

Definition of feePercent:

``````uint public feePercent;  // Fee percentage
``````

Everything in WEI:

``````event.feePercent =10
event.FeeAmount  =200000000000000000
event.amountGet  =2000000000000000000
event.amountGive =1000000000000000000
``````
• What is `.2`??? What variable type do you use for storing this value? Nov 6, 2019 at 20:35
• And how could you possibly be getting -18 when all your variables are `unsigned`??? What off-chain tool are you using in order to call this transaction and parse the returned value? If it's a programmatic tool (for example, web3.js), then what does your code look like? Nov 6, 2019 at 20:37
• What is your declaration of `event Trade`? Are we suppose to assume that you are passing `_feeAmount` in the correct place? Nov 6, 2019 at 20:39
• BTW, just so you know, `2 / 100 * 10 == (2 / 100) * 10 == 0 * 10 == 0`. Nov 6, 2019 at 20:40
• Added part of my truffle/js test code. In the contract, everything is in WEI, displaying in ETH to keep it simple. Nov 6, 2019 at 20:56

## 2 Answers

The immediate issue appears to be that you are expecting non-integer results from your equation when using integers in Solidity.

As other people have commented, in Solidity when dealing with integers, `2/100 = 0`

https://solidity.readthedocs.io/en/latest/types.html#division
In Solidity, division rounds towards zero.

Remix is great to quickly test contracts.

The following Test contract can be used in Remix (you can import from GitHub in Remix).

Note: You should only use code published in an official release of OpenZeppelin Contracts, the latest release is 2.4. When importing via GitHub on Remix you can specify the release tag, (otherwise you will get the latest code in the master branch).

``````pragma solidity ^0.5.0;

import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v2.4.0/contracts/math/SafeMath.sol";

contract Test {

using SafeMath for uint256;

function divide(uint256 a, uint256 b) public pure returns(uint256) {
return a / b;
}

function safeDivide(uint256 a, uint256 b) public pure returns(uint256) {
return a.div(b);
}
}
``````

If you have questions on using OpenZeppelin you can also ask in the Community Forum: https://forum.openzeppelin.com/

Disclosure: I am the Community Manager at OpenZeppelin

• Sorry, had nothing to do with OpenZeppelin, just had a big mistake in my WeiToEth helper function that made it look like the math was wrong. Nov 7, 2019 at 20:50

The actual problem had nothing to do with OpenZepllin, but I must admit that I didn't know about the know decimal limitations.

@GoodVibrations noted that if I displayed everything WEI, the math was correct (and I updated the question with those numbers). So it was converting WEI to a decimal that was the problem.

I had two helper routines in JavaScript that were messing up the result. Had the new web3.utils.BN() wrapper on both, but it should NOT be on the WeiToEth routine.

In my mind, I need the BigNumber when sending a value to the contract, but going from WeiToEth I don't need a big number at all.

``````export const EthToWei = (n) => {
return new web3.utils.BN(
web3.utils.toWei(n.toString(),'ether')
)
}

export const WeiToEth = (n) => {
return web3.utils.fromWei(n.toString(),'ether')
}
``````