Skip to content

Optimized div rounding up with require #455

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .github/workflows/fuzz-testing.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ jobs:
- OracleEchidnaTest
- BitMathEchidnaTest
- LowGasSafeMathEchidnaTest
- UnsafeMathEchidnaTest
- FullMathEchidnaTest

steps:
Expand Down
1 change: 0 additions & 1 deletion .github/workflows/mythx.yml
Original file line number Diff line number Diff line change
Expand Up @@ -61,5 +61,4 @@ jobs:
contracts/test/OracleEchidnaTest.sol --include OracleEchidnaTest \
contracts/test/BitMathEchidnaTest.sol --include BitMathEchidnaTest \
contracts/test/LowGasSafeMathEchidnaTest.sol --include LowGasSafeMathEchidnaTest \
contracts/test/UnsafeMathEchidnaTest.sol --include UnsafeMathEchidnaTest \
contracts/test/FullMathEchidnaTest.sol --include FullMathEchidnaTest
12 changes: 12 additions & 0 deletions contracts/libraries/LowGasSafeMath.sol
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,16 @@ library LowGasSafeMath {
function sub(int256 x, int256 y) internal pure returns (int256 z) {
require((z = x - y) <= x == (y >= 0));
}

/// @notice Returns ceil(x / y)
/// @dev Throws if y == 0
/// @param x The dividend
/// @param y The divisor
/// @return z The quotient, ceil(x / y)
function divRoundingUp(uint256 x, uint256 y) internal pure returns (uint256 z) {
require(y > 0);
assembly {
z := add(div(x, y), gt(mod(x, y), 0))
}
}
}
7 changes: 3 additions & 4 deletions contracts/libraries/SqrtPriceMath.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import './LowGasSafeMath.sol';
import './SafeCast.sol';

import './FullMath.sol';
import './UnsafeMath.sol';
import './FixedPoint96.sol';

/// @title Functions based on Q64.96 sqrt price and liquidity
Expand Down Expand Up @@ -44,7 +43,7 @@ library SqrtPriceMath {
return uint160(FullMath.mulDivRoundingUp(numerator1, sqrtPX96, denominator));
}

return uint160(UnsafeMath.divRoundingUp(numerator1, (numerator1 / sqrtPX96).add(amount)));
return uint160(LowGasSafeMath.divRoundingUp(numerator1, (numerator1 / sqrtPX96).add(amount)));
} else {
uint256 product;
// if the product overflows, we know the denominator underflows
Expand Down Expand Up @@ -86,7 +85,7 @@ library SqrtPriceMath {
uint256 quotient =
(
amount <= type(uint160).max
? UnsafeMath.divRoundingUp(amount << FixedPoint96.RESOLUTION, liquidity)
? LowGasSafeMath.divRoundingUp(amount << FixedPoint96.RESOLUTION, liquidity)
: FullMath.mulDivRoundingUp(amount, FixedPoint96.Q96, liquidity)
);

Expand Down Expand Up @@ -163,7 +162,7 @@ library SqrtPriceMath {

return
roundUp
? UnsafeMath.divRoundingUp(
? LowGasSafeMath.divRoundingUp(
FullMath.mulDivRoundingUp(numerator1, numerator2, sqrtRatioBX96),
sqrtRatioAX96
)
Expand Down
16 changes: 0 additions & 16 deletions contracts/libraries/UnsafeMath.sol

This file was deleted.

10 changes: 10 additions & 0 deletions contracts/test/LowGasSafeMathEchidnaTest.sol
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,14 @@ contract LowGasSafeMathEchidnaTest {
assert(z == x - y);
assert(y < 0 ? z > x : z <= x);
}

function checkDivRoundingUp(uint256 x, uint256 d) external pure {
uint256 z = LowGasSafeMath.divRoundingUp(x, d);
uint256 diff = z - (x / d);
if (x % d == 0) {
assert(diff == 0);
} else {
assert(diff == 1);
}
}
}
17 changes: 0 additions & 17 deletions contracts/test/UnsafeMathEchidnaTest.sol

This file was deleted.

6 changes: 3 additions & 3 deletions test/__snapshots__/SqrtPriceMath.spec.ts.snap
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`SqrtPriceMath #getAmount0Delta gas cost for amount0 where roundUp = true 1`] = `657`;
exports[`SqrtPriceMath #getAmount0Delta gas cost for amount0 where roundUp = true 1`] = `612`;

exports[`SqrtPriceMath #getAmount0Delta gas cost for amount0 where roundUp = true 2`] = `452`;

exports[`SqrtPriceMath #getAmount1Delta gas cost for amount0 where roundUp = false 1`] = `452`;

exports[`SqrtPriceMath #getAmount1Delta gas cost for amount0 where roundUp = true 1`] = `657`;
exports[`SqrtPriceMath #getAmount1Delta gas cost for amount0 where roundUp = true 1`] = `612`;

exports[`SqrtPriceMath #getNextSqrtPriceFromInput zeroForOne = false gas 1`] = `536`;

exports[`SqrtPriceMath #getNextSqrtPriceFromInput zeroForOne = true gas 1`] = `753`;

exports[`SqrtPriceMath #getNextSqrtPriceFromOutput zeroForOne = false gas 1`] = `848`;

exports[`SqrtPriceMath #getNextSqrtPriceFromOutput zeroForOne = true gas 1`] = `514`;
exports[`SqrtPriceMath #getNextSqrtPriceFromOutput zeroForOne = true gas 1`] = `469`;
8 changes: 4 additions & 4 deletions test/__snapshots__/SwapMath.spec.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ exports[`SwapMath #computeSwapStep gas swap one for zero exact out capped 1`] =

exports[`SwapMath #computeSwapStep gas swap one for zero exact out partial 1`] = `2776`;

exports[`SwapMath #computeSwapStep gas swap zero for one exact in capped 1`] = `2151`;
exports[`SwapMath #computeSwapStep gas swap zero for one exact in capped 1`] = `2106`;

exports[`SwapMath #computeSwapStep gas swap zero for one exact in partial 1`] = `3200`;
exports[`SwapMath #computeSwapStep gas swap zero for one exact in partial 1`] = `3110`;

exports[`SwapMath #computeSwapStep gas swap zero for one exact out capped 1`] = `1903`;
exports[`SwapMath #computeSwapStep gas swap zero for one exact out capped 1`] = `1858`;

exports[`SwapMath #computeSwapStep gas swap zero for one exact out partial 1`] = `3200`;
exports[`SwapMath #computeSwapStep gas swap zero for one exact out partial 1`] = `3110`;
6 changes: 3 additions & 3 deletions test/__snapshots__/UniswapV3Factory.spec.ts.snap
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`UniswapV3Factory #createPool gas 1`] = `4515505`;
exports[`UniswapV3Factory #createPool gas 1`] = `4510882`;

exports[`UniswapV3Factory factory bytecode size 1`] = `24345`;
exports[`UniswapV3Factory factory bytecode size 1`] = `24322`;

exports[`UniswapV3Factory pool bytecode size 1`] = `21922`;
exports[`UniswapV3Factory pool bytecode size 1`] = `21899`;
76 changes: 38 additions & 38 deletions test/__snapshots__/UniswapV3Pool.gas.spec.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -30,21 +30,21 @@ exports[`UniswapV3Pool gas tests fee is off #increaseObservationCardinalityNext

exports[`UniswapV3Pool gas tests fee is off #increaseObservationCardinalityNext no op 1`] = `28277`;

exports[`UniswapV3Pool gas tests fee is off #mint above current price add to position after some time passes 1`] = `108096`;
exports[`UniswapV3Pool gas tests fee is off #mint above current price add to position after some time passes 1`] = `108051`;

exports[`UniswapV3Pool gas tests fee is off #mint above current price add to position existing 1`] = `108096`;
exports[`UniswapV3Pool gas tests fee is off #mint above current price add to position existing 1`] = `108051`;

exports[`UniswapV3Pool gas tests fee is off #mint above current price new position mint first in range 1`] = `176478`;
exports[`UniswapV3Pool gas tests fee is off #mint above current price new position mint first in range 1`] = `176433`;

exports[`UniswapV3Pool gas tests fee is off #mint above current price second position in same range 1`] = `123096`;
exports[`UniswapV3Pool gas tests fee is off #mint above current price second position in same range 1`] = `123051`;

exports[`UniswapV3Pool gas tests fee is off #mint around current price add to position after some time passes 1`] = `159795`;
exports[`UniswapV3Pool gas tests fee is off #mint around current price add to position after some time passes 1`] = `159750`;

exports[`UniswapV3Pool gas tests fee is off #mint around current price add to position existing 1`] = `148987`;
exports[`UniswapV3Pool gas tests fee is off #mint around current price add to position existing 1`] = `148942`;

exports[`UniswapV3Pool gas tests fee is off #mint around current price new position mint first in range 1`] = `308610`;
exports[`UniswapV3Pool gas tests fee is off #mint around current price new position mint first in range 1`] = `308565`;

exports[`UniswapV3Pool gas tests fee is off #mint around current price second position in same range 1`] = `163987`;
exports[`UniswapV3Pool gas tests fee is off #mint around current price second position in same range 1`] = `163942`;

exports[`UniswapV3Pool gas tests fee is off #mint below current price add to position after some time passes 1`] = `108641`;

Expand All @@ -56,27 +56,27 @@ exports[`UniswapV3Pool gas tests fee is off #mint below current price second pos

exports[`UniswapV3Pool gas tests fee is off #poke best case 1`] = `42584`;

exports[`UniswapV3Pool gas tests fee is off #swapExact0For1 first swap in block moves tick, no initialized crossings 1`] = `118475`;
exports[`UniswapV3Pool gas tests fee is off #swapExact0For1 first swap in block moves tick, no initialized crossings 1`] = `118340`;

exports[`UniswapV3Pool gas tests fee is off #swapExact0For1 first swap in block with no tick movement 1`] = `104442`;
exports[`UniswapV3Pool gas tests fee is off #swapExact0For1 first swap in block with no tick movement 1`] = `104352`;

exports[`UniswapV3Pool gas tests fee is off #swapExact0For1 first swap in block, large swap crossing a single initialized tick 1`] = `120839`;
exports[`UniswapV3Pool gas tests fee is off #swapExact0For1 first swap in block, large swap crossing a single initialized tick 1`] = `120659`;

exports[`UniswapV3Pool gas tests fee is off #swapExact0For1 first swap in block, large swap crossing several initialized ticks 1`] = `136510`;
exports[`UniswapV3Pool gas tests fee is off #swapExact0For1 first swap in block, large swap crossing several initialized ticks 1`] = `136195`;

exports[`UniswapV3Pool gas tests fee is off #swapExact0For1 first swap in block, large swap, no initialized crossings 1`] = `130580`;
exports[`UniswapV3Pool gas tests fee is off #swapExact0For1 first swap in block, large swap, no initialized crossings 1`] = `130355`;

exports[`UniswapV3Pool gas tests fee is off #swapExact0For1 large swap crossing several initialized ticks after some time passes (seconds outside is set) 1`] = `151510`;
exports[`UniswapV3Pool gas tests fee is off #swapExact0For1 large swap crossing several initialized ticks after some time passes (seconds outside is set) 1`] = `151195`;

exports[`UniswapV3Pool gas tests fee is off #swapExact0For1 large swap crossing several initialized ticks second time after some time passes 1`] = `211510`;
exports[`UniswapV3Pool gas tests fee is off #swapExact0For1 large swap crossing several initialized ticks second time after some time passes 1`] = `211195`;

exports[`UniswapV3Pool gas tests fee is off #swapExact0For1 second swap in block moves tick, no initialized crossings 1`] = `118475`;
exports[`UniswapV3Pool gas tests fee is off #swapExact0For1 second swap in block moves tick, no initialized crossings 1`] = `118340`;

exports[`UniswapV3Pool gas tests fee is off #swapExact0For1 second swap in block with no tick movement 1`] = `104553`;
exports[`UniswapV3Pool gas tests fee is off #swapExact0For1 second swap in block with no tick movement 1`] = `104463`;

exports[`UniswapV3Pool gas tests fee is off #swapExact0For1 second swap in block, large swap crossing a single initialized tick 1`] = `108447`;
exports[`UniswapV3Pool gas tests fee is off #swapExact0For1 second swap in block, large swap crossing a single initialized tick 1`] = `108312`;

exports[`UniswapV3Pool gas tests fee is off #swapExact0For1 second swap in block, large swap crossing several initialized ticks 1`] = `124097`;
exports[`UniswapV3Pool gas tests fee is off #swapExact0For1 second swap in block, large swap crossing several initialized ticks 1`] = `123827`;

exports[`UniswapV3Pool gas tests fee is on #burn above current price burn entire position after some time passes 1`] = `56987`;

Expand Down Expand Up @@ -108,21 +108,21 @@ exports[`UniswapV3Pool gas tests fee is on #increaseObservationCardinalityNext g

exports[`UniswapV3Pool gas tests fee is on #increaseObservationCardinalityNext no op 1`] = `28277`;

exports[`UniswapV3Pool gas tests fee is on #mint above current price add to position after some time passes 1`] = `108096`;
exports[`UniswapV3Pool gas tests fee is on #mint above current price add to position after some time passes 1`] = `108051`;

exports[`UniswapV3Pool gas tests fee is on #mint above current price add to position existing 1`] = `108096`;
exports[`UniswapV3Pool gas tests fee is on #mint above current price add to position existing 1`] = `108051`;

exports[`UniswapV3Pool gas tests fee is on #mint above current price new position mint first in range 1`] = `176478`;
exports[`UniswapV3Pool gas tests fee is on #mint above current price new position mint first in range 1`] = `176433`;

exports[`UniswapV3Pool gas tests fee is on #mint above current price second position in same range 1`] = `123096`;
exports[`UniswapV3Pool gas tests fee is on #mint above current price second position in same range 1`] = `123051`;

exports[`UniswapV3Pool gas tests fee is on #mint around current price add to position after some time passes 1`] = `159795`;
exports[`UniswapV3Pool gas tests fee is on #mint around current price add to position after some time passes 1`] = `159750`;

exports[`UniswapV3Pool gas tests fee is on #mint around current price add to position existing 1`] = `148987`;
exports[`UniswapV3Pool gas tests fee is on #mint around current price add to position existing 1`] = `148942`;

exports[`UniswapV3Pool gas tests fee is on #mint around current price new position mint first in range 1`] = `308610`;
exports[`UniswapV3Pool gas tests fee is on #mint around current price new position mint first in range 1`] = `308565`;

exports[`UniswapV3Pool gas tests fee is on #mint around current price second position in same range 1`] = `163987`;
exports[`UniswapV3Pool gas tests fee is on #mint around current price second position in same range 1`] = `163942`;

exports[`UniswapV3Pool gas tests fee is on #mint below current price add to position after some time passes 1`] = `108641`;

Expand All @@ -134,24 +134,24 @@ exports[`UniswapV3Pool gas tests fee is on #mint below current price second posi

exports[`UniswapV3Pool gas tests fee is on #poke best case 1`] = `42584`;

exports[`UniswapV3Pool gas tests fee is on #swapExact0For1 first swap in block moves tick, no initialized crossings 1`] = `124662`;
exports[`UniswapV3Pool gas tests fee is on #swapExact0For1 first swap in block moves tick, no initialized crossings 1`] = `124527`;

exports[`UniswapV3Pool gas tests fee is on #swapExact0For1 first swap in block with no tick movement 1`] = `110482`;
exports[`UniswapV3Pool gas tests fee is on #swapExact0For1 first swap in block with no tick movement 1`] = `110392`;

exports[`UniswapV3Pool gas tests fee is on #swapExact0For1 first swap in block, large swap crossing a single initialized tick 1`] = `127173`;
exports[`UniswapV3Pool gas tests fee is on #swapExact0For1 first swap in block, large swap crossing a single initialized tick 1`] = `126993`;

exports[`UniswapV3Pool gas tests fee is on #swapExact0For1 first swap in block, large swap crossing several initialized ticks 1`] = `143285`;
exports[`UniswapV3Pool gas tests fee is on #swapExact0For1 first swap in block, large swap crossing several initialized ticks 1`] = `142970`;

exports[`UniswapV3Pool gas tests fee is on #swapExact0For1 first swap in block, large swap, no initialized crossings 1`] = `137061`;
exports[`UniswapV3Pool gas tests fee is on #swapExact0For1 first swap in block, large swap, no initialized crossings 1`] = `136836`;

exports[`UniswapV3Pool gas tests fee is on #swapExact0For1 large swap crossing several initialized ticks after some time passes (seconds outside is set) 1`] = `158285`;
exports[`UniswapV3Pool gas tests fee is on #swapExact0For1 large swap crossing several initialized ticks after some time passes (seconds outside is set) 1`] = `157970`;

exports[`UniswapV3Pool gas tests fee is on #swapExact0For1 large swap crossing several initialized ticks second time after some time passes 1`] = `218285`;
exports[`UniswapV3Pool gas tests fee is on #swapExact0For1 large swap crossing several initialized ticks second time after some time passes 1`] = `217970`;

exports[`UniswapV3Pool gas tests fee is on #swapExact0For1 second swap in block moves tick, no initialized crossings 1`] = `124662`;
exports[`UniswapV3Pool gas tests fee is on #swapExact0For1 second swap in block moves tick, no initialized crossings 1`] = `124527`;

exports[`UniswapV3Pool gas tests fee is on #swapExact0For1 second swap in block with no tick movement 1`] = `110593`;
exports[`UniswapV3Pool gas tests fee is on #swapExact0For1 second swap in block with no tick movement 1`] = `110503`;

exports[`UniswapV3Pool gas tests fee is on #swapExact0For1 second swap in block, large swap crossing a single initialized tick 1`] = `114634`;
exports[`UniswapV3Pool gas tests fee is on #swapExact0For1 second swap in block, large swap crossing a single initialized tick 1`] = `114499`;

exports[`UniswapV3Pool gas tests fee is on #swapExact0For1 second swap in block, large swap crossing several initialized ticks 1`] = `130725`;
exports[`UniswapV3Pool gas tests fee is on #swapExact0For1 second swap in block, large swap crossing several initialized ticks 1`] = `130455`;