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 = 0
0 < 2 && 0 < 7
7+1 = 0
0 < 2 && 0 < 7
Overflowed
0+7 = 7
7 > 0 && 7 >= 7
7+0 = 7
7 >= 7 && 7 > 0
-edit-
Aside from the question, I might add that I use this pattern in solidity 0.4.10 (or above) to separate side effects and validation rather than a more expensive function call.
uint _check = c; // where c is a variable being updated
c = a + b;
assert(c >= _check);
Use (type1,type2,...)
to represent structs.
For example, the fillOrder
function in 0x 2.0:
function fillOrder(
Order memory order,
uint256 takerAssetFillAmount,
bytes memory signature
)
public
returns (LibFillResults.FillResults memory fillResults);
struct Order {
address makerAddress; // Address that created the order.
address takerAddress; // Address that is allowed to fill the order. If set to 0, any address is allowed to fill the order.
address feeRecipientAddress; // Address that will recieve fees when order is filled.
address senderAddress; // Address that is allowed to call Exchange contract methods that affect this order. If set to 0, any address is allowed to call these methods.
uint256 makerAssetAmount; // Amount of makerAsset being offered by maker. Must be greater than 0.
uint256 takerAssetAmount; // Amount of takerAsset being bid on by maker. Must be greater than 0.
uint256 makerFee; // Amount of ZRX paid to feeRecipient by maker when order is filled. If set to 0, no transfer of ZRX from maker to feeRecipient will be attempted.
uint256 takerFee; // Amount of ZRX paid to feeRecipient by taker when order is filled. If set to 0, no transfer of ZRX from taker to feeRecipient will be attempted.
uint256 expirationTimeSeconds; // Timestamp in seconds at which order expires.
uint256 salt; // Arbitrary number to facilitate uniqueness of the order's hash.
bytes makerAssetData; // Encoded data that can be decoded by a specified proxy contract when transferring makerAsset. The last byte references the id of this proxy.
bytes takerAssetData; // Encoded data that can be decoded by a specified proxy contract when transferring takerAsset. The last byte references the id of this proxy.
}
The function selector is calculated using:
fillOrder((address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes),uint256,bytes)
This produces a keccak256 of: b4be83d519a652e54a6073d7e55643f575508112b09dcc74264b807477b576c5
, and the first 4 bytes are: b4be83d5
You can confirm this by looking at this tx which called fillOrder: https://etherscan.io/tx/0x4811b7492bd845a46a052b063f943c4760174e932cb171ca25a934de6e7e4da4
Best Answer
x
will be 9.Use this code and How to quickly test a Solidity function?