Suppose I have:

function func(uint256 x) external {

I would like to test this function via web3.js, with the maximum possible value of x.

In a Truffle test, I have noticed that I can simply call func(-1).

My Truffle version is 4.1.15, which relies on Web3 v0.20.6.

I'm not sure who's in charge of this conversion (whether it's Truffle or Web3), but I would like to know if this a guaranteed behavior as far as web3.js states.

In the documentation of web3.js v1.x there is web3.utils.toTwosComplement(number), which implies to me that such conversion is not guaranteed (but must be performed explicitly using this function).

However, my Truffle version relies on the previous Web3 version, so I am unable to know for sure.

Any idea?

Side note: I know I can use web3.toBigNumber(2).pow(256).minus(1), but I'd rather use the -1 option, which is cleaner IMO.

3 Answers 3


I'm unsure if web3 truffle do some magic of their own but I'd guess no, because they don't need to interpret the values themselves. Anyway, if you test this in Remix you will also see that it wraps around (flips to the other end of the min/max) (https://en.wikipedia.org/wiki/Integer_overflow).

So it's a Solidity feature (and actually quite common in programming languages). As the minimum value for uint (uint256) is 0 and maximum is 2^256-1 (https://ethereum.stackexchange.com/a/58985/31933) and it wraps around, one less than the minimum value becomes the maximum value. The effect is the same if you input 2^256 - you get 0. So even if input -1 looks a bit strange, it's syntaxically correct, compiles just fine and produces the right output.

This is one of the main reasons we have stuff like SafeMath which prevents such wraps in on-chain transactions (and also underflow and overflow).

Simple contract to test this:

pragma solidity ^0.5.1;

contract Test {
    event Logger(uint log);
    function doit(uint myint) public {
        emit Logger(myint);
  • 2
    Thank you. One side note: there's no overflow or underflow here, just a wrap-around (though I guess it's a matter of terminology). In any case, SafeMath has nothing to do with my use-case, as I'm merely sending the value from the off-chain to the on-chain (while SafeMath is designated for detecting overflows and underflows as a result of an arithmetic operation executed in the on-chain). Commented Feb 20, 2019 at 21:34

The original workaround web3.toBigNumber(2).pow(256).minus(1) is no longer working for newer versions of web3.

To pass in -1, try using web3.utils.toBN(2).pow(web3.utils.toBN(256)).sub(web3.utils.toBN(1));

  • The "original workaround" works fine on Truffle 4.x, as stated in the question! Commented Jul 8, 2020 at 7:25
  • Updated to specify it is a solution for anyone running newer versions of web3.
    – kue
    Commented Jul 9, 2020 at 8:25
  • So you're basically just explaining how to port from BigNumber to BN. This is a general issue which is unrelated to the actual question. Commented Jul 9, 2020 at 8:37
  • Just trying to save people some time. Yes, it's just some method changes. My answer is how you currently pass '-1' to a solidity function which takes a 'uint256' argument as input.
    – kue
    Commented Jul 10, 2020 at 2:59

This has nothing related to Solidity, but to the external layer of javascript aimed to interface it to the world.

Solidity function simply see 0xfff...fff as argument when called and do not know (neither is interested in knowing) how you generated that bit pattern

This feature cannot be guaranteed stable, neither in JavaScript, because it is a mistake, but as a matter of fact it will be there practically forever, because to manage properly this particularity requires to low level check every time you are using the minus operator for the type (uint/int) and to throw if uint is used and the value should be under zero... (or to use different ‘minus’ low level implementation for int vs. uint): too much work to pay at every use of the minus operator in the program!

Very few languages in the world do check for type overflow/underflow both at compile time and at runtime!

  • I agree with the first statement (haven't read the rest yet), and in fact I thought that I should mention it in a comment on the other answer. It's purely a web3 issue (and my question also relies on this assumption). Commented Feb 21, 2019 at 8:17
  • I understand this, I know your background, but the answer is there to help casual readers as well
    – Rick Park
    Commented Feb 21, 2019 at 8:19
  • I don't agree with This feature cannot be guaranteed stable, neither in JavaScript, because it is a mistake, however. Even though Javascript doesn't know anything about types, web3.js itself knows the prototype of the solidity function, and can therefore implement an appropriate handling for negative values passed to it (a handling similar to that of native languages, where all that matter is "the bits"). Commented Feb 21, 2019 at 8:20
  • Yes, but with a relatively heavy overload on every ‘minus’ call... as I tried to explain :)
    – Rick Park
    Commented Feb 21, 2019 at 8:22
  • @goodvibration BTW what you are saying is exactly the motivation to tag it as “behavior that cannot guaranteed stable”, indeed you find out easily how to correct it and, then, how to slash it out. So it is not stable...
    – Rick Park
    Commented Feb 21, 2019 at 8:45

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.