Skip to content

Commit

Permalink
Add 0.8 migration (#278)
Browse files Browse the repository at this point in the history
* feat: upgrade contracts to solidity 0.8

* feat: continue with 0.8 migration

- Remove audits
- Remove NFTDescriptor stuff because couldn't easily work through
  a weird assembly stacktoodeep issue. I think it has to do with
  ABIcoderv2

* fix: package.json

* fix: tests for 0.8 migration

* fix: clean up comment

* feat: upgrade to 0.8.15

* fix: bump version

* Fix code style issues with Prettier

* fix: improve gas for liquidityamounts

* Fix code style issues with Prettier

* fix: review comments

- add back nft descriptor tests
- remove xits
- improve ticklens gas

* Fix code style issues with Prettier

Co-authored-by: Lint Action <[email protected]>
  • Loading branch information
marktoda and lint-action authored Jul 5, 2022
1 parent 22a7ead commit b325bb0
Show file tree
Hide file tree
Showing 87 changed files with 4,171 additions and 2,550 deletions.
1 change: 1 addition & 0 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ on:
push:
branches:
- main
- 0.8
pull_request:

jobs:
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ on:
push:
branches:
- main
- 0.8
pull_request:

jobs:
Expand Down
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@ artifacts/
cache/
crytic-export/
node_modules/
typechain/
typechain/
foundry-out/
Binary file removed audits/abdk/audit.pdf
Binary file not shown.
27 changes: 13 additions & 14 deletions contracts/NonfungiblePositionManager.sol
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity =0.7.6;
pragma solidity =0.8.15;
pragma abicoder v2;

import '@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol';
Expand Down Expand Up @@ -159,11 +159,10 @@ contract NonfungiblePositionManager is
(, uint256 feeGrowthInside0LastX128, uint256 feeGrowthInside1LastX128, , ) = pool.positions(positionKey);

// idempotent set
uint80 poolId =
cachePoolKey(
address(pool),
PoolAddress.PoolKey({token0: params.token0, token1: params.token1, fee: params.fee})
);
uint80 poolId = cachePoolKey(
address(pool),
PoolAddress.PoolKey({token0: params.token0, token1: params.token1, fee: params.fee})
);

_positions[tokenId] = Position({
nonce: 0,
Expand Down Expand Up @@ -192,7 +191,7 @@ contract NonfungiblePositionManager is
}

// save bytecode by removing implementation of unused method
function baseURI() public pure override returns (string memory) {}
function baseURI() public pure returns (string memory) {}

/// @inheritdoc INonfungiblePositionManager
function increaseLiquidity(IncreaseLiquidityParams calldata params)
Expand Down Expand Up @@ -328,8 +327,9 @@ contract NonfungiblePositionManager is
// trigger an update of the position fees owed and fee growth snapshots if it has any liquidity
if (position.liquidity > 0) {
pool.burn(position.tickLower, position.tickUpper, 0);
(, uint256 feeGrowthInside0LastX128, uint256 feeGrowthInside1LastX128, , ) =
pool.positions(PositionKey.compute(address(this), position.tickLower, position.tickUpper));
(, uint256 feeGrowthInside0LastX128, uint256 feeGrowthInside1LastX128, , ) = pool.positions(
PositionKey.compute(address(this), position.tickLower, position.tickUpper)
);

tokensOwed0 += uint128(
FullMath.mulDiv(
Expand All @@ -351,11 +351,10 @@ contract NonfungiblePositionManager is
}

// compute the arguments to give to the pool#collect method
(uint128 amount0Collect, uint128 amount1Collect) =
(
params.amount0Max > tokensOwed0 ? tokensOwed0 : params.amount0Max,
params.amount1Max > tokensOwed1 ? tokensOwed1 : params.amount1Max
);
(uint128 amount0Collect, uint128 amount1Collect) = (
params.amount0Max > tokensOwed0 ? tokensOwed0 : params.amount0Max,
params.amount1Max > tokensOwed1 ? tokensOwed1 : params.amount1Max
);

// the actual amounts collected are returned
(amount0, amount1) = pool.collect(
Expand Down
21 changes: 10 additions & 11 deletions contracts/NonfungibleTokenPositionDescriptor.sol
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity =0.7.6;
pragma solidity =0.8.15;
pragma abicoder v2;

import '@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol';
import '@uniswap/lib/contracts/libraries/SafeERC20Namer.sol';

import './libraries/SafeERC20Namer.sol';
import './libraries/ChainId.sol';
import './interfaces/INonfungiblePositionManager.sol';
import './interfaces/INonfungibleTokenPositionDescriptor.sol';
Expand Down Expand Up @@ -51,16 +51,15 @@ contract NonfungibleTokenPositionDescriptor is INonfungibleTokenPositionDescript
override
returns (string memory)
{
(, , address token0, address token1, uint24 fee, int24 tickLower, int24 tickUpper, , , , , ) =
positionManager.positions(tokenId);
(, , address token0, address token1, uint24 fee, int24 tickLower, int24 tickUpper, , , , , ) = positionManager
.positions(tokenId);

IUniswapV3Pool pool =
IUniswapV3Pool(
PoolAddress.computeAddress(
positionManager.factory(),
PoolAddress.PoolKey({token0: token0, token1: token1, fee: fee})
)
);
IUniswapV3Pool pool = IUniswapV3Pool(
PoolAddress.computeAddress(
positionManager.factory(),
PoolAddress.PoolKey({token0: token0, token1: token1, fee: fee})
)
);

bool _flipRatio = flipRatio(token0, token1, ChainId.get());
address quoteTokenAddress = !_flipRatio ? token1 : token0;
Expand Down
47 changes: 22 additions & 25 deletions contracts/SwapRouter.sol
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity =0.7.6;
pragma solidity =0.8.15;
pragma abicoder v2;

import '@uniswap/v3-core/contracts/libraries/SafeCast.sol';
Expand Down Expand Up @@ -64,10 +64,9 @@ contract SwapRouter is
(address tokenIn, address tokenOut, uint24 fee) = data.path.decodeFirstPool();
CallbackValidation.verifyCallback(factory, tokenIn, tokenOut, fee);

(bool isExactInput, uint256 amountToPay) =
amount0Delta > 0
? (tokenIn < tokenOut, uint256(amount0Delta))
: (tokenOut < tokenIn, uint256(amount1Delta));
(bool isExactInput, uint256 amountToPay) = amount0Delta > 0
? (tokenIn < tokenOut, uint256(amount0Delta))
: (tokenOut < tokenIn, uint256(amount1Delta));
if (isExactInput) {
pay(tokenIn, data.payer, msg.sender, amountToPay);
} else {
Expand Down Expand Up @@ -97,16 +96,15 @@ contract SwapRouter is

bool zeroForOne = tokenIn < tokenOut;

(int256 amount0, int256 amount1) =
getPool(tokenIn, tokenOut, fee).swap(
recipient,
zeroForOne,
amountIn.toInt256(),
sqrtPriceLimitX96 == 0
? (zeroForOne ? TickMath.MIN_SQRT_RATIO + 1 : TickMath.MAX_SQRT_RATIO - 1)
: sqrtPriceLimitX96,
abi.encode(data)
);
(int256 amount0, int256 amount1) = getPool(tokenIn, tokenOut, fee).swap(
recipient,
zeroForOne,
amountIn.toInt256(),
sqrtPriceLimitX96 == 0
? (zeroForOne ? TickMath.MIN_SQRT_RATIO + 1 : TickMath.MAX_SQRT_RATIO - 1)
: sqrtPriceLimitX96,
abi.encode(data)
);

return uint256(-(zeroForOne ? amount1 : amount0));
}
Expand Down Expand Up @@ -179,16 +177,15 @@ contract SwapRouter is

bool zeroForOne = tokenIn < tokenOut;

(int256 amount0Delta, int256 amount1Delta) =
getPool(tokenIn, tokenOut, fee).swap(
recipient,
zeroForOne,
-amountOut.toInt256(),
sqrtPriceLimitX96 == 0
? (zeroForOne ? TickMath.MIN_SQRT_RATIO + 1 : TickMath.MAX_SQRT_RATIO - 1)
: sqrtPriceLimitX96,
abi.encode(data)
);
(int256 amount0Delta, int256 amount1Delta) = getPool(tokenIn, tokenOut, fee).swap(
recipient,
zeroForOne,
-amountOut.toInt256(),
sqrtPriceLimitX96 == 0
? (zeroForOne ? TickMath.MIN_SQRT_RATIO + 1 : TickMath.MAX_SQRT_RATIO - 1)
: sqrtPriceLimitX96,
abi.encode(data)
);

uint256 amountOutReceived;
(amountIn, amountOutReceived) = zeroForOne
Expand Down
40 changes: 18 additions & 22 deletions contracts/V3Migrator.sol
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity =0.7.6;
pragma solidity =0.8.15;
pragma abicoder v2;

import '@uniswap/v3-core/contracts/libraries/LowGasSafeMath.sol';
import '@uniswap/v2-core/contracts/interfaces/IUniswapV2Pair.sol';

import './interfaces/INonfungiblePositionManager.sol';
Expand All @@ -18,8 +17,6 @@ import './base/PoolInitializer.sol';

/// @title Uniswap V3 Migrator
contract V3Migrator is IV3Migrator, PeripheryImmutableState, PoolInitializer, Multicall, SelfPermit {
using LowGasSafeMath for uint256;

address public immutable nonfungiblePositionManager;

constructor(
Expand All @@ -43,30 +40,29 @@ contract V3Migrator is IV3Migrator, PeripheryImmutableState, PoolInitializer, Mu
(uint256 amount0V2, uint256 amount1V2) = IUniswapV2Pair(params.pair).burn(address(this));

// calculate the amounts to migrate to v3
uint256 amount0V2ToMigrate = amount0V2.mul(params.percentageToMigrate) / 100;
uint256 amount1V2ToMigrate = amount1V2.mul(params.percentageToMigrate) / 100;
uint256 amount0V2ToMigrate = (amount0V2 * params.percentageToMigrate) / 100;
uint256 amount1V2ToMigrate = (amount1V2 * params.percentageToMigrate) / 100;

// approve the position manager up to the maximum token amounts
TransferHelper.safeApprove(params.token0, nonfungiblePositionManager, amount0V2ToMigrate);
TransferHelper.safeApprove(params.token1, nonfungiblePositionManager, amount1V2ToMigrate);

// mint v3 position
(, , uint256 amount0V3, uint256 amount1V3) =
INonfungiblePositionManager(nonfungiblePositionManager).mint(
INonfungiblePositionManager.MintParams({
token0: params.token0,
token1: params.token1,
fee: params.fee,
tickLower: params.tickLower,
tickUpper: params.tickUpper,
amount0Desired: amount0V2ToMigrate,
amount1Desired: amount1V2ToMigrate,
amount0Min: params.amount0Min,
amount1Min: params.amount1Min,
recipient: params.recipient,
deadline: params.deadline
})
);
(, , uint256 amount0V3, uint256 amount1V3) = INonfungiblePositionManager(nonfungiblePositionManager).mint(
INonfungiblePositionManager.MintParams({
token0: params.token0,
token1: params.token1,
fee: params.fee,
tickLower: params.tickLower,
tickUpper: params.tickUpper,
amount0Desired: amount0V2ToMigrate,
amount1Desired: amount1V2ToMigrate,
amount0Min: params.amount0Min,
amount1Min: params.amount1Min,
recipient: params.recipient,
deadline: params.deadline
})
);

// if necessary, clear allowance and refund dust
if (amount0V3 < amount0V2) {
Expand Down
2 changes: 1 addition & 1 deletion contracts/base/BlockTimestamp.sol
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity =0.7.6;
pragma solidity =0.8.15;

/// @title Function for getting block timestamp
/// @dev Base contract that is overridden for tests
Expand Down
21 changes: 10 additions & 11 deletions contracts/base/ERC721Permit.sol
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity =0.7.6;
pragma solidity =0.8.15;

import '@openzeppelin/contracts/token/ERC721/ERC721.sol';
import '@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol';
import '@openzeppelin/contracts/utils/Address.sol';

import '../libraries/ChainId.sol';
Expand All @@ -11,7 +11,7 @@ import './BlockTimestamp.sol';

/// @title ERC721 with permit
/// @notice Nonfungible tokens that support an approve via signature, i.e. permit
abstract contract ERC721Permit is BlockTimestamp, ERC721, IERC721Permit {
abstract contract ERC721Permit is BlockTimestamp, ERC721Enumerable, IERC721Permit {
/// @dev Gets the current nonce for a token ID and then increments it, returning the original value
function _getAndIncrementNonce(uint256 tokenId) internal virtual returns (uint256);

Expand Down Expand Up @@ -62,14 +62,13 @@ abstract contract ERC721Permit is BlockTimestamp, ERC721, IERC721Permit {
) external payable override {
require(_blockTimestamp() <= deadline, 'Permit expired');

bytes32 digest =
keccak256(
abi.encodePacked(
'\x19\x01',
DOMAIN_SEPARATOR(),
keccak256(abi.encode(PERMIT_TYPEHASH, spender, tokenId, _getAndIncrementNonce(tokenId), deadline))
)
);
bytes32 digest = keccak256(
abi.encodePacked(
'\x19\x01',
DOMAIN_SEPARATOR(),
keccak256(abi.encode(PERMIT_TYPEHASH, spender, tokenId, _getAndIncrementNonce(tokenId), deadline))
)
);
address owner = ownerOf(tokenId);
require(spender != owner, 'ERC721Permit: approval to current owner');

Expand Down
9 changes: 6 additions & 3 deletions contracts/base/LiquidityManagement.sol
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity =0.7.6;
pragma solidity =0.8.15;
pragma abicoder v2;

import '@uniswap/v3-core/contracts/interfaces/IUniswapV3Factory.sol';
Expand Down Expand Up @@ -57,8 +57,11 @@ abstract contract LiquidityManagement is IUniswapV3MintCallback, PeripheryImmuta
IUniswapV3Pool pool
)
{
PoolAddress.PoolKey memory poolKey =
PoolAddress.PoolKey({token0: params.token0, token1: params.token1, fee: params.fee});
PoolAddress.PoolKey memory poolKey = PoolAddress.PoolKey({
token0: params.token0,
token1: params.token1,
fee: params.fee
});

pool = IUniswapV3Pool(PoolAddress.computeAddress(factory, poolKey));

Expand Down
2 changes: 1 addition & 1 deletion contracts/base/Multicall.sol
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity =0.7.6;
pragma solidity =0.8.15;
pragma abicoder v2;

import '../interfaces/IMulticall.sol';
Expand Down
2 changes: 1 addition & 1 deletion contracts/base/PeripheryImmutableState.sol
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity =0.7.6;
pragma solidity =0.8.15;

import '../interfaces/IPeripheryImmutableState.sol';

Expand Down
7 changes: 2 additions & 5 deletions contracts/base/PeripheryPaymentsWithFee.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
pragma solidity >=0.7.5;

import '@openzeppelin/contracts/token/ERC20/IERC20.sol';
import '@uniswap/v3-core/contracts/libraries/LowGasSafeMath.sol';

import './PeripheryPayments.sol';
import '../interfaces/IPeripheryPaymentsWithFee.sol';
Expand All @@ -11,8 +10,6 @@ import '../interfaces/external/IWETH9.sol';
import '../libraries/TransferHelper.sol';

abstract contract PeripheryPaymentsWithFee is PeripheryPayments, IPeripheryPaymentsWithFee {
using LowGasSafeMath for uint256;

/// @inheritdoc IPeripheryPaymentsWithFee
function unwrapWETH9WithFee(
uint256 amountMinimum,
Expand All @@ -27,7 +24,7 @@ abstract contract PeripheryPaymentsWithFee is PeripheryPayments, IPeripheryPayme

if (balanceWETH9 > 0) {
IWETH9(WETH9).withdraw(balanceWETH9);
uint256 feeAmount = balanceWETH9.mul(feeBips) / 10_000;
uint256 feeAmount = (balanceWETH9 * feeBips) / 10_000;
if (feeAmount > 0) TransferHelper.safeTransferETH(feeRecipient, feeAmount);
TransferHelper.safeTransferETH(recipient, balanceWETH9 - feeAmount);
}
Expand All @@ -47,7 +44,7 @@ abstract contract PeripheryPaymentsWithFee is PeripheryPayments, IPeripheryPayme
require(balanceToken >= amountMinimum, 'Insufficient token');

if (balanceToken > 0) {
uint256 feeAmount = balanceToken.mul(feeBips) / 10_000;
uint256 feeAmount = (balanceToken * feeBips) / 10_000;
if (feeAmount > 0) TransferHelper.safeTransfer(token, feeRecipient, feeAmount);
TransferHelper.safeTransfer(token, recipient, balanceToken - feeAmount);
}
Expand Down
2 changes: 1 addition & 1 deletion contracts/base/PeripheryValidation.sol
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity =0.7.6;
pragma solidity =0.8.15;

import './BlockTimestamp.sol';

Expand Down
2 changes: 1 addition & 1 deletion contracts/base/PoolInitializer.sol
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity =0.7.6;
pragma solidity =0.8.15;

import '@uniswap/v3-core/contracts/interfaces/IUniswapV3Factory.sol';
import '@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol';
Expand Down
Loading

0 comments on commit b325bb0

Please sign in to comment.