UniswapV3Factory
0xca8152ab363dc2f23bb30f6c6c2678028e7cf30a
Verification
Verified
v0.7.6+commit.7338295f
Type
Contract
1,979 bytes
ABI entries
15
6 read · 4 write
License
none
Contract information
- Address
- 0xca8152ab363dc2f23bb30f6c6c2678028e7cf30a
- Chain
- Robinhood Chain (4663)
- Compiler
- v0.7.6+commit.7338295f
- Optimization
- Enabled
- Creator
- 0xDf769057eB…0DFe49a6A2
- Creation tx
- 0x8befecb2cf…f0b9790b84
Token
Not a token
This contract does not expose ERC-20 metadata.
Read contract (6)
feeAmountTickSpacing(uint24) → int24
getPool(address, address, uint24) → address
owner() → address
poolImplementation() → address
treasury() → address
treasuryFeeBps() → uint16
Events (4)
FeeAmountEnabledOwnerChangedPoolCreatedTreasuryChanged
ABI
[
{
"inputs": [],
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "uint24",
"name": "fee",
"type": "uint24"
},
{
"indexed": true,
"internalType": "int24",
"name": "tickSpacing",
"type": "int24"
}
],
"name": "FeeAmountEnabled",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "oldOwner",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "newOwner",
"type": "address"
}
],
"name": "OwnerChanged",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "token0",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "token1",
"type": "address"
},
{
"indexed": true,
"internalType": "uint24",
"name": "fee",
"type": "uint24"
},
{
"indexed": false,
"internalType": "int24",
"name": "tickSpacing",
"type": "int24"
},
{
"indexed": false,
"internalType": "address",
"name": "pool",
"type": "address"
}
],
"name": "PoolCreated",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "treasury",
"type": "address"
},
{
"indexed": false,
"internalType": "uint16",
"name": "treasuryFeeBps",
"type": "uint16"
}
],
"name": "TreasuryChanged",
"type": "event"
},
{
"inputs": [
{
"internalType": "address",
"name": "tokenA",
"type": "address"
},
{
"internalType": "address",
"name": "tokenB",
"type": "address"
},
{
"internalType": "uint24",
"name": "fee",
"type": "uint24"
}
],
"name": "createPool",
"outputs": [
{
"internalType": "address",
"name": "pool",
"type": "address"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint24",
"name": "fee",
"type": "uint24"
},
{
"internalType": "int24",
"name": "tickSpacing",
"type": "int24"
}
],
"name": "enableFeeAmount",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint24",
"name": "",
"type": "uint24"
}
],
"name": "feeAmountTickSpacing",
"outputs": [
{
"internalType": "int24",
"name": "",
"type": "int24"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "",
"type": "address"
},
{
"internalType": "address",
"name": "",
"type": "address"
},
{
"internalType": "uint24",
"name": "",
"type": "uint24"
}
],
"name": "getPool",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "owner",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "poolImplementation",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "_owner",
"type": "address"
}
],
"name": "setOwner",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "_treasury",
"type": "address"
},
{
"internalType": "uint16",
"name": "_treasuryFeeBps",
"type": "uint16"
}
],
"name": "setTreasury",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "treasury",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "treasuryFeeBps",
"outputs": [
{
"internalType": "uint16",
"name": "",
"type": "uint16"
}
],
"stateMutability": "view",
"type": "function"
}
]Source code
// SPDX-License-Identifier: BUSL-1.1
pragma solidity =0.7.6;
import './interfaces/IUniswapV3Factory.sol';
import '@openzeppelin/contracts/proxy/Clones.sol';
import './UniswapV3Pool.sol';
/// @title Canonical Uniswap V3 factory
/// @notice Deploys Uniswap V3 pools and manages ownership and control over pool protocol fees
/// @dev Pools are deployed as EIP-1167 minimal proxies (clones) of a single pool implementation.
/// This keeps the factory far below the EIP-170 contract size limit, which the original
/// pool-embedded-in-factory layout exceeds once the flat-fee accounting is added
contract UniswapV3Factory is IUniswapV3Factory {
/// @inheritdoc IUniswapV3Factory
address public override owner;
// The pool implementation that every pool clone delegates to
address public immutable poolImplementation;
/// @inheritdoc IUniswapV3Factory
mapping(uint24 => int24) public override feeAmountTickSpacing;
/// @inheritdoc IUniswapV3Factory
mapping(address => mapping(address => mapping(uint24 => address))) public override getPool;
/// @inheritdoc IUniswapV3Factory
address public override treasury;
/// @inheritdoc IUniswapV3Factory
uint16 public override treasuryFeeBps;
constructor() {
owner = msg.sender;
emit OwnerChanged(address(0), msg.sender);
treasury = msg.sender;
treasuryFeeBps = 2000;
emit TreasuryChanged(msg.sender, 2000);
poolImplementation = address(new UniswapV3Pool());
}
/// @inheritdoc IUniswapV3Factory
function createPool(
address tokenA,
address tokenB,
uint24 fee
) external override 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 = Clones.cloneDeterministic(poolImplementation, keccak256(abi.encode(token0, token1, fee)));
UniswapV3Pool(pool).initializeParams(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);
}
/// @inheritdoc IUniswapV3Factory
function setTreasury(address _treasury, uint16 _treasuryFeeBps) external override {
require(msg.sender == owner);
require(_treasury != address(0));
// treasury share of each flat swap fee is capped at 50%
require(_treasuryFeeBps <= 5000);
treasury = _treasury;
treasuryFeeBps = _treasuryFeeBps;
emit TreasuryChanged(_treasury, _treasuryFeeBps);
}
}
Chain explorer5086msChain node84ms