Tag Info

19

Yep. Here's an example of uint overflow and underflow. contract C { // (2**256 - 1) + 1 = 0 function overflow() returns (uint256 _overflow) { uint256 max = 2**256 - 1; return max + 1; } // 0 - 1 = 2**256 - 1 function underflow() returns (uint256 _underflow) { uint256 min = 0; return min - 1; } } You ...

9

Yes, overflow is possible, and be especially careful when using var for example: In for (var i = 0; i < arrayName.length; i++) { ... }, the type of i will be uint8, because this is the smallest type that is required to hold the value 0. If the array has more than 255 elements, the loop will not terminate. Using uint i (256 bits) avoids the ...

8

x will be 9. Use this code and How to quickly test a Solidity function? contract C { function test() returns(uint) { uint8 x = 255; x += 10; return x; } } Decoded: uint256: 9

7

From the Solidity 0.8.0 Release Announcement about the exponentiation operator (**): We hope that we found a rather efficient implementation and would also appreciate your feedback about that! For many special cases, we actually implemented it using the exp opcode instead of our own implementation. More specifically, exponentiation operations that use a ...

6

Why did the execution not stop in the line 259 as the amount the hacker transferred was way higher than his balance? If the contract is called with the arguments batchTransfer([addressA,addressB],0x8000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000) line 257 becomes uint256 amount = 2 * 0x8000,0000,0000,0000,0000,0000,...

4

The reason behind this is that overflow checking is expensive. It would be bad for overall EVM performance and by extension bad for tx rate, node performance, etc. The way it is now, they are leaving it up to a higher level to decide, you can chose wether or not your program is slowed down for safety. Maybe in your particular case there is a much cheaper ...

4

Firstly, kudos to the OpenZeppelin safeMath library parts of which I've used in my code. Given that addition is commutative, it doesn't really matter which you use. The answer will either be equal or greater than both and so valid, or less than both, invalid. Say we have an uint3 (for simplicity but not a valid Solidity type) where overflow is mod 8: 1+7 =...

4

After posting the question, I realised I gave the answer myself. I simply have to check if both x and y are odd numbers and, if yes, add 1 to the result: function avg(uint256 x, uint256 y) external returns (uint256 result) { result = x / 2 + y / 2; if (x % 2 == 1 && y % 2 == 1) { result += 1; } } Update: I ended up optimising the ...

4

The problem is that javascript numbers do not have enough precision. Use web3.utils.toBN to wrap them in a BigNumber object const amount = web3.utils.toBN("1020000000000000000") const deposit = weth.methods.transferFrom(contract,wallet,amount).send({from:wallet}).then(console.log) Since they are ether amounts perhaps it is better to use web3.utils....

3

A bunch of examples to get away from the brain ache. I'm basically re-writing o0ragman0o's answer. If my answer makes sense, maybe accept his answer instead :) First example, with no overflow occurring: uint8 a = 255; uint8 b = 0; Then c = 255 + 0 which is 255. assert(c >= a); // SUCCESS as 255 is equal to a. Increase the value of b to create an ...

3

Because you have your decimals set to 18, you have to then divide by 1,000,000,000,000,000,000 (1 followed by 18 zeros) to get the integer-value of _totalSupply. 18 decimals is the standard for Ethereum. The smallest unit is referred to as a Wei. 1,000,000,000,000,000,000 wei are equal to 1 Ether. Here is a unit map. To simplify your contract you could set ...

3

Yes. You can drop it like it's hot. You very likely do not need it. SafeMath is now completely obsolete when compiling with solc >= 0.8.0, or are there still situations where it can be useful? Well, just because something seems useless doesn't mean it's actually useless or has no potential future use. Everything can be useful. Solidity 0.8.0 changelog: ...

2

Without attempting to prove that either way works completely reliably (would require more time and caffeine to be sure), I can say I tested the alternative, assert(c >= b && c >= a); and it causes a slightly higher gas cost in solc 0.4.10. It's a very small difference (12 gas) but it suggests a reason. Possibly the suggested code is the most ...

2

The issue is that this expression: return uint(2 ** (numSold/1000)); first evaluates 2 ** (numSold/1000), and deduces the resulting type from the type of numSold. So the truncation is happening before the value can ever be cast. The solution is to cast numSold to a uint first. i.e. return 2 ** uint(numSold/1000);

2

I think it's a totally arbitrary number for the sake of the example, probably because someone will need to call the mint function 1.157920892373162e+17 times to actually have an overflow (if they mint an amount just under 1e60). Plus, it doesn't take in account potential overflow if you transfer tokens to someone else, but again this snippet of code in the ...

2

The point is that if you write ‘260’ for b you are not writing uint8 as in your example, but at least uint9. This is not an overflow, but a wrong intended input, which maps in a normal input for the function. From the point of view of the function nothing happened. Any limited size uint representation is intended as limited to the representable universe ...

2

From https://programtheblockchain.com/posts/2018/04/27/avoiding-integer-overflows-safemath-isnt-enough/: Fixed-size integers have a range of values they can represent. For example, an 8-bit unsigned integer can store values between 0 and 255 (2^8-1). When the result of some arithmetic falls outside that supported range, an integer overflow occurs. On the ...

2

OK got it, will still leave it as a reference for other lost ones like me. A 256 bit number is really big, I decided to change it to an 8 bit unsigned integer to test. When I underflow it, we get 255 c: [ 255 ] Converting 255 to binary would give us 1111 1111 and to hex is FF. In conclusion, we can say that it is a two's complement of 0000 0001 to ...

2

Since soldity 0.4.16 there is a support for overflow checking: From the documentation : solc now include experimental support for automated overflow and assertion checking at compile-time using the SMT solver Z3

2

Solidity does not have any built-in protection from over/underflow. This means that if you hit the min or the max of a value (0 or 2^256-1 = 115792089237316195423570985008687907853269984665640564039457584007913129639935) then the value will "wrap" around and keep counting. Put the following code in Remix to test it out. pragma solidity ^0.5.16; contract ...

2

Tested the following code: pragma solidity ^0.5.0; contract Test { function iadd(int a, int b) public pure returns (int) {return a + b;} function uadd(uint a, uint b) public pure returns (uint) {return a + b;} } Using solc 0.5.13: solc --bin --abi --asm --output-dir=binaries Test.sol ...

2

I believe you mean the address of target, not the address of X (which is a smart contract). In the video you linked to, that variable is called x (lowercase). https://programtheblockchain.com/posts/2018/03/09/understanding-ethereum-smart-contract-storage/ may help you understand the layout of storage. array is the second state variable in the contract, so ...

2

If you have a smart contract in >=0.8.0, you do not need SafeMath anymore and you can ditch it from your imports.

2

The Solidity v0.8.0 Breaking Changes Docs also says Checks for overflow are very common, so we made them the default to increase readability of code, even if it comes at a slight increase of gas costs. And Checking the GitHub commits for SafeMath.sol I found this commit made on February 2021 were they added the comment: NOTE: SafeMath is no longer needed ...

2

One situation where the old SafeMath might be useful with solidity >=0.8.0 (which is what the original question is about) is to get a revert reason string while keeping an easy to read code (adding a small gas overhead at deployment): unchecked { balance.sub(value, "Balance too low"); } Which would be, without safemath, something a bit ...

1

totalSupply stores the current amount of minted tokens, not the maximum amount of tokens which can be minted. In order to restrict this amount, one needs to apply additional code (not part of the ERC20 standard). Otherwise, it is restricted only by the limitation of the underlying platform (i.e., the size of uint256).

1

That's a nasty way to do it and I don't think it's reliable. Use the SafeMath method. If a + b = c, then c must be more than a or an overflow has occured. From SafeMath: function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a); return c; } Hope it helps.

1

Argument numberA of a function sumNumbers has a data type uint256. Maximum value that numberA can store is 2^256-1. As numberA cannot store a number greater than 2^256-1 you are getting the error. As @smax correctly pointed out in javascript 2e10 is 20000000000. You should use bignumber.js for passing a value as an argument to a function.

1

Just change the type of your parameter to accept any uint so you prevent the overflow and you can do your assertion. contract parameterOverflows { uint8 public selectedCharacter; modifier onlyCharacter(uint _character) { require(_character <= 255); _; } function selectCharacter(uint _character) public onlyCharacter(...

1

I see that this line of code always returns true No, This is true unless it overflows. When unit overflow happens that's false. Here the unit used unit256 will have a max value of 2**256-1. This gist shows example of unit overflow and underflow. /* demonstrating uint overflow and underflow in ethereum solidity this is why you need guards like: ...

Only top voted, non community-wiki answers of a minimum length are eligible