-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add Uniswap v3-core & v3-periphery contracts
- Loading branch information
1 parent
9218a74
commit 0656e7f
Showing
92 changed files
with
8,632 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
@fdk/=lib/foundry-deployment-kit/script/ | ||
@contract-libs/=lib/foundry-deployment-kit/lib/contract-libs/src/ | ||
forge-std/=lib/foundry-deployment-kit/lib/forge-std/src/ | ||
@solady/=lib/foundry-deployment-kit/lib/solady/src/ | ||
@openzeppelin/contracts/=lib/foundry-deployment-kit/lib/openzeppelin-contracts/contracts/ | ||
@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/ | ||
@uniswap/lib/contracts/=lib/solidity-lib/contracts/ | ||
base64-sol/=lib/base64/ | ||
@uniswap/v2-core/contracts=lib/v2-core/contracts/ | ||
@uniswap/v3-core/contracts/=src/core |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
// SPDX-License-Identifier: BUSL-1.1 | ||
pragma solidity =0.7.6; | ||
|
||
/// @title Prevents delegatecall to a contract | ||
/// @notice Base contract that provides a modifier for preventing delegatecall to methods in a child contract | ||
abstract contract NoDelegateCall { | ||
/// @dev The original address of this contract | ||
address private immutable original; | ||
|
||
constructor() { | ||
// Immutables are computed in the init code of the contract, and then inlined into the deployed bytecode. | ||
// In other words, this variable won't change when it's checked at runtime. | ||
original = address(this); | ||
} | ||
|
||
/// @dev Private method is used instead of inlining into modifier because modifiers are copied into each method, | ||
/// and the use of immutable means the address bytes are copied in every place the modifier is used. | ||
function checkNotDelegateCall() private view { | ||
require(address(this) == original); | ||
} | ||
|
||
/// @notice Prevents delegatecall into the modified method | ||
modifier noDelegateCall() { | ||
checkNotDelegateCall(); | ||
_; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
// SPDX-License-Identifier: BUSL-1.1 | ||
pragma solidity =0.7.6; | ||
|
||
import './interfaces/IUniswapV3Factory.sol'; | ||
|
||
import './UniswapV3PoolDeployer.sol'; | ||
import './NoDelegateCall.sol'; | ||
|
||
import './UniswapV3Pool.sol'; | ||
|
||
/// @title Canonical Uniswap V3 factory | ||
/// @notice Deploys Uniswap V3 pools and manages ownership and control over pool protocol fees | ||
contract UniswapV3Factory is IUniswapV3Factory, UniswapV3PoolDeployer, NoDelegateCall { | ||
/// @inheritdoc IUniswapV3Factory | ||
address public override owner; | ||
|
||
/// @inheritdoc IUniswapV3Factory | ||
mapping(uint24 => int24) public override feeAmountTickSpacing; | ||
/// @inheritdoc IUniswapV3Factory | ||
mapping(address => mapping(address => mapping(uint24 => address))) public override getPool; | ||
|
||
constructor() { | ||
owner = msg.sender; | ||
emit OwnerChanged(address(0), msg.sender); | ||
|
||
feeAmountTickSpacing[500] = 10; | ||
emit FeeAmountEnabled(500, 10); | ||
feeAmountTickSpacing[3000] = 60; | ||
emit FeeAmountEnabled(3000, 60); | ||
feeAmountTickSpacing[10000] = 200; | ||
emit FeeAmountEnabled(10000, 200); | ||
} | ||
|
||
/// @inheritdoc IUniswapV3Factory | ||
function createPool( | ||
address tokenA, | ||
address tokenB, | ||
uint24 fee | ||
) external override noDelegateCall returns (address pool) { | ||
require(tokenA != tokenB); | ||
(address token0, address token1) = tokenA < tokenB ? (tokenA, tokenB) : (tokenB, tokenA); | ||
require(token0 != address(0)); | ||
int24 tickSpacing = feeAmountTickSpacing[fee]; | ||
require(tickSpacing != 0); | ||
require(getPool[token0][token1][fee] == address(0)); | ||
pool = deploy(address(this), token0, token1, fee, tickSpacing); | ||
getPool[token0][token1][fee] = pool; | ||
// populate mapping in the reverse direction, deliberate choice to avoid the cost of comparing addresses | ||
getPool[token1][token0][fee] = pool; | ||
emit PoolCreated(token0, token1, fee, tickSpacing, pool); | ||
} | ||
|
||
/// @inheritdoc IUniswapV3Factory | ||
function setOwner(address _owner) external override { | ||
require(msg.sender == owner); | ||
emit OwnerChanged(owner, _owner); | ||
owner = _owner; | ||
} | ||
|
||
/// @inheritdoc IUniswapV3Factory | ||
function enableFeeAmount(uint24 fee, int24 tickSpacing) public override { | ||
require(msg.sender == owner); | ||
require(fee < 1000000); | ||
// tick spacing is capped at 16384 to prevent the situation where tickSpacing is so large that | ||
// TickBitmap#nextInitializedTickWithinOneWord overflows int24 container from a valid tick | ||
// 16384 ticks represents a >5x price change with ticks of 1 bips | ||
require(tickSpacing > 0 && tickSpacing < 16384); | ||
require(feeAmountTickSpacing[fee] == 0); | ||
|
||
feeAmountTickSpacing[fee] = tickSpacing; | ||
emit FeeAmountEnabled(fee, tickSpacing); | ||
} | ||
} |
Oops, something went wrong.