# Complicated ERC20 Arithmetic

I'm trying to compose a formula in Solidity that has a combination of unsigned integers, signed and exponents, however having a hard time figuring out how to do so.

The formula would look something like `f(x)=15-2^(-0.1x+3.5)` where 15, -0.1 and 3.5 are constants, and x is a uint256 with an ERC20 Token Balance (with 18 decimals).

The function signature has to be something like `function calculate(uint256 price) public view returns (uint256)`

I've looked at using OpenZeppelin SafeCast, ABDKMath64x64 and other libraries, but whatever I've tried has failed.

Basically if you check that `price` is smaller than max_int256, you can cast it into a signed number and work from there.

Your token is probably using some precision, i.e. has decimal set to 18, so price received is an int that represents a 18 precision real number.

All you have to do is convert your numbers to the same precision level (multiply by 1e18) and do the rest as usual.

``````    uint256 constant DECIMALS = 18;

function calculate(uint256 _price) public pure returns (uint256) {
require(_price < 0x8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, "input too big");
int256 price = int256(_price);
int256 power = 1e18*0.1 * price + 1e18*3.5;
int256 y = 15 - 2 ^ power;
return uint256(y);
}
``````

Make sure you use solidity `^0.8.0` or alternatively use SafeMath library to avoid arithmetic overflow issues.

• I was under the impression exponentiation is done using ** rather than ^ and can only be done using uint256. I've tried following your code by doing this instead: `uint256 y = 15 - 2 ** uint256(power);` but that "Transaction reverted without a reason string". The input I'm trying is 1e18 May 4, 2022 at 15:01