Skip to content

Commit 7559261

Browse files
committed
feat: dup protocol smart-contracts
1 parent 7c1a3d8 commit 7559261

File tree

97 files changed

+8699
-61
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

97 files changed

+8699
-61
lines changed

lib/base64

Submodule base64 updated 1 file

lib/openzeppelin-contracts

lib/v2-core

remappings.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
ds-test/=lib/forge-std/lib/ds-test/src/
2+
forge-std/=lib/forge-std/src/
3+
@uniswap/v3-core/contracts/=src/v3-core/
4+
@openzeppelin/=lib/openzeppelin-contracts/
5+
@uniswap/lib/=lib/solidity-lib/
6+
@uniswap/v2-core/=lib/v2-core/
7+
base64-sol/=lib/base64/

script/Counter.s.sol

Lines changed: 0 additions & 19 deletions
This file was deleted.

src/Counter.sol

Lines changed: 0 additions & 14 deletions
This file was deleted.

src/v3-core/NoDelegateCall.sol

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// SPDX-License-Identifier: BUSL-1.1
2+
pragma solidity =0.7.6;
3+
4+
/// @title Prevents delegatecall to a contract
5+
/// @notice Base contract that provides a modifier for preventing delegatecall to methods in a child contract
6+
abstract contract NoDelegateCall {
7+
/// @dev The original address of this contract
8+
address private immutable original;
9+
10+
constructor() {
11+
// Immutables are computed in the init code of the contract, and then inlined into the deployed bytecode.
12+
// In other words, this variable won't change when it's checked at runtime.
13+
original = address(this);
14+
}
15+
16+
/// @dev Private method is used instead of inlining into modifier because modifiers are copied into each method,
17+
/// and the use of immutable means the address bytes are copied in every place the modifier is used.
18+
function checkNotDelegateCall() private view {
19+
require(address(this) == original);
20+
}
21+
22+
/// @notice Prevents delegatecall into the modified method
23+
modifier noDelegateCall() {
24+
checkNotDelegateCall();
25+
_;
26+
}
27+
}

src/v3-core/UniswapV3Factory.sol

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
// SPDX-License-Identifier: BUSL-1.1
2+
pragma solidity =0.7.6;
3+
4+
import './interfaces/IUniswapV3Factory.sol';
5+
6+
import './UniswapV3PoolDeployer.sol';
7+
import './NoDelegateCall.sol';
8+
9+
import './UniswapV3Pool.sol';
10+
11+
/// @title Canonical Uniswap V3 factory
12+
/// @notice Deploys Uniswap V3 pools and manages ownership and control over pool protocol fees
13+
contract UniswapV3Factory is IUniswapV3Factory, UniswapV3PoolDeployer, NoDelegateCall {
14+
/// @inheritdoc IUniswapV3Factory
15+
address public override owner;
16+
17+
/// @inheritdoc IUniswapV3Factory
18+
mapping(uint24 => int24) public override feeAmountTickSpacing;
19+
/// @inheritdoc IUniswapV3Factory
20+
mapping(address => mapping(address => mapping(uint24 => address))) public override getPool;
21+
22+
constructor() {
23+
owner = msg.sender;
24+
emit OwnerChanged(address(0), msg.sender);
25+
26+
feeAmountTickSpacing[500] = 10;
27+
emit FeeAmountEnabled(500, 10);
28+
feeAmountTickSpacing[3000] = 60;
29+
emit FeeAmountEnabled(3000, 60);
30+
feeAmountTickSpacing[10000] = 200;
31+
emit FeeAmountEnabled(10000, 200);
32+
}
33+
34+
/// @inheritdoc IUniswapV3Factory
35+
function createPool(
36+
address tokenA,
37+
address tokenB,
38+
uint24 fee
39+
) external override noDelegateCall returns (address pool) {
40+
require(tokenA != tokenB);
41+
(address token0, address token1) = tokenA < tokenB ? (tokenA, tokenB) : (tokenB, tokenA);
42+
require(token0 != address(0));
43+
int24 tickSpacing = feeAmountTickSpacing[fee];
44+
require(tickSpacing != 0);
45+
require(getPool[token0][token1][fee] == address(0));
46+
pool = deploy(address(this), token0, token1, fee, tickSpacing);
47+
getPool[token0][token1][fee] = pool;
48+
// populate mapping in the reverse direction, deliberate choice to avoid the cost of comparing addresses
49+
getPool[token1][token0][fee] = pool;
50+
emit PoolCreated(token0, token1, fee, tickSpacing, pool);
51+
}
52+
53+
/// @inheritdoc IUniswapV3Factory
54+
function setOwner(address _owner) external override {
55+
require(msg.sender == owner);
56+
emit OwnerChanged(owner, _owner);
57+
owner = _owner;
58+
}
59+
60+
/// @inheritdoc IUniswapV3Factory
61+
function enableFeeAmount(uint24 fee, int24 tickSpacing) public override {
62+
require(msg.sender == owner);
63+
require(fee < 1000000);
64+
// tick spacing is capped at 16384 to prevent the situation where tickSpacing is so large that
65+
// TickBitmap#nextInitializedTickWithinOneWord overflows int24 container from a valid tick
66+
// 16384 ticks represents a >5x price change with ticks of 1 bips
67+
require(tickSpacing > 0 && tickSpacing < 16384);
68+
require(feeAmountTickSpacing[fee] == 0);
69+
70+
feeAmountTickSpacing[fee] = tickSpacing;
71+
emit FeeAmountEnabled(fee, tickSpacing);
72+
}
73+
}

0 commit comments

Comments
 (0)