Uniswap v3 periphery is the router and interface layer around the pool
🦄 🦄 🦄 Peripheral smart contracts for interacting with Uniswap v3
At a glance
- What is it?
- The v3-periphery repository holds the smart contracts that sit around the Uniswap V3 pools, including the routers, the base contracts and the shared libraries, published as the @uniswap/v3-periphery npm package together with the compiled artifacts. The pool mathematics itself lives in a separate core repository, and the split matters when you are integrating or forking.
- Who is it for?
- Adopt the Uniswap v3 periphery contracts when you are integrating with V3 and want the exact interfaces and bytecode that mainnet runs, rather than a reimplementation that drifts from the deployed versions. Do not treat it as the source of the pool logic, because that is in the separate core repository.
- Can I use it commercially?
- Yes, with conditions. GPL-2.0 is a copyleft licence: if you distribute software that includes it, you must release that software's source code under the same licence. Running it internally without distributing it does not trigger that obligation.
- Is it still maintained?
- Yes. The repository last received commits 2 days ago.
- What is it written in?
- Mainly TypeScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 25, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Periphery is the layer around the pool
This repository contains the periphery smart contracts for the Uniswap V3 Protocol, and for the lower level core contracts the readme points at the separate uniswap-v3-core repository.
That split is the whole architecture of the project and it is worth being precise about, because people often refer to Uniswap V3 as one thing. The core repository holds the pool itself, the concentrated liquidity positions and the pricing. The periphery holds everything a user or an integrator actually touches: the routers that take a swap instruction and turn it into pool calls, the base contracts the routers inherit from, the shared libraries, and the interfaces.
So if you are writing a bot that swaps, you are integrating with the periphery. If you are reading how a tick maps to a price, you are reading the core.
The implementation is TypeScript for the tests and tooling with Solidity for the contracts themselves, the licence is GPL-2.0-or-later, the package version is 1.4.4, and the last push was on 2026-10-14. The repository has no GitHub releases, so the versions that people depend on are the npm versions.
The topic tags also say what this is for, with automated-market-maker, bug-bounty, ethereum and smart-contracts among them, and a bug bounty programme that covers this repository under terms defined in a bug-bounty.md file.
The published package ships contracts and artifacts, and not much else
The files list in the package manifest is more informative than it looks, because it tells you exactly what a downstream project gets.
Three directories of Solidity are included, contracts/base, contracts/interfaces and contracts/libraries, along with the compiled artifacts under artifacts/contracts, matched as a glob over the JSON files. And then there are three exclusions, which are the interesting part. The debug JSON files are excluded with a negation, and so are the artifacts of the test contracts and the artifacts of the base contracts.
The base exclusion is the notable one. The base contracts are the abstract contracts the routers inherit from, and they are shipped as source in contracts/base but not as compiled artifacts, which keeps the published package from carrying a compiled version of code that is never deployed on its own. The test exclusion is more obvious, since test artifacts have no business in a dependency.
The result is a package that gives you the interfaces, the libraries, the deployable contracts and their bytecode, and nothing else. That is a well-shaped dependency for a Solidity project, because the artifacts are what you need to deploy and the interfaces are what you need to import, and the package is explicit about which is which.
Deploying locally from the published artifacts
The local deployment section tells you to install the npm package @uniswap/v3-periphery and import the bytecode from the artifacts directory, and it shows the shape of the import.
import {
abi as SWAP_ROUTER_ABI,
bytecode as SWAP_ROUTER_BYTECODE,
} from '@uniswap/v3-periphery/artifacts/contracts/SwapRouter.sol/SwapRouter.json'The stated reason is the important part. This will ensure that you are testing against the same bytecode that is deployed to mainnet and public testnets, and all Uniswap code will correctly interoperate with your local deployment.
That is a stronger guarantee than the one you get from compiling the contracts yourself, and it is the reason the package publishes artifacts at all. A fork of a router that is one compiler version behind the deployed one is a router that behaves differently in a way that is very hard to debug, because the difference is in the deployment rather than in the source. Reading the bytecode out of the published artifact removes that class of difference.
The cost is that the artifacts are pinned to the version of the package, so a project that wants a modified router has to compile its own and loses the guarantee.
Solidity interfaces for your own contracts
The other integration path is the interfaces, and it is the one most projects use.
import '@uniswap/v3-periphery/contracts/interfaces/ISwapRouter.sol';
contract MyContract {
ISwapRouter router;
function doSomethingWithSwapRouter() {
// router.exactInput(...);
}
}The interfaces are available for import into Solidity smart contracts through the npm artifact, and the commented call shows the shape of the use, which is the router's exactInput method.
The reason to import the interface rather than to declare your own is the same reason as the artifacts. A hand written interface drifts, and a drifted interface is a bug that compiles cleanly and then reverts on chain with a message that describes the failure rather than the cause. The interface in the package is the one the deployed router actually implements.
And the import path is worth noting, because it is an npm specifier rather than a relative path, which means the interfaces travel with the package rather than being vendored into your source tree.
Hardhat, Waffle and TypeChain for the tests
The development dependencies describe the test setup, and it is a conventional and well chosen one.
The scripts are two lines. The compile script runs hardhat compile, and the test script runs hardhat test.
Around that, the stack is ethers v5 with the Hardhat plugins for it and for Etherscan, hardhat-waffle for the assertions and the chain setup, and Waffle itself as a dependency. The test assertions are chai with mocha, and there is mocha-chai-jest-snapshot, which gives you snapshot testing of the contract behaviour. TypeChain with hardhat-typechain generates the TypeScript bindings from the compiled contracts, and there is ts-generator as well, which is how the type generation is wired to the build.
The linting is a Solidity linter, solhint, with the prettier plugin so that the Solidity formatting and the Solidity linting agree, and there is a separate prettier for the TypeScript. The configuration files at the top of the repository match, with a .solhint.json, a .prettierrc and a .prettierignore.
The node requirement is stated as 10 or newer in the engines field, and the TypeScript version is 3.7. That is an old TypeScript, and it is the version that was current when the periphery contracts were written, so it is a deliberate constraint rather than neglect.
The runtime dependencies point at the core contracts
There are five runtime dependencies, and each one is there for a reason.
The first is @openzeppelin/contracts at the version 3.4.2-solc-0.7, which is OpenZeppelin pinned to a specific release and to a Solidity 0.7 compiler line. That pairing is the important detail, because the OpenZeppelin contracts in 3.4.2 are written for that compiler and the periphery inherits from them.
Then there is @uniswap/v3-core at 1.0.0, which is the pool implementation the routers call into, and @uniswap/v2-core at 1.0.1, which the package depends on. The fourth is @uniswap/lib at 4.0.1-alpha, the shared library package, and the fifth is base64-sol at 1.0.1, a Solidity implementation of base64.
Depending on v2-core from a v3 periphery package is the kind of thing that surprises people, and it is worth understanding before you start reading the contracts,
The alpha suffix on @uniswap/lib is a reminder that the periphery is versioned against a moving dependency, and the version pins in the manifest mean an upgrade is a deliberate act.
Audits, deployment records and the bug bounty
The repository carries the material that matters for a contract that holds money, and the top level listing shows it.
There is an audits/ directory, a bug-bounty.md file that defines the terms of the programme that covers this repository, a deploys.md and a testnet-deploys.md, and a contracts/ directory with the Solidity itself, plus a test/ directory.
The deploys files are the ones most people do not know to look for and the ones that matter most in practice. For a protocol where the periphery contracts have been deployed to mainnet many times, the list of deployed addresses is what lets you check what you are actually interacting with, and the testnet deployments are what let you test against the same code without deploying your own.
The bug bounty is mentioned in the readme with a link to the terms file, and the topics list carries bug-bounty, which is a reasonable thing for a contracts repository to advertise.
Taken together with the version pinning and the published artifacts, the picture is of a project that takes deployment reproducibility seriously. The contracts, the bytecode that goes on chain, the addresses where it is deployed, the audits of the code and the terms for reporting a problem in it are all in the same repository, which is more than most projects of this kind assemble.
Editorial conclusion
Adopt the Uniswap v3 periphery contracts when you are integrating with V3 and want the exact interfaces and bytecode that mainnet runs, rather than a reimplementation that drifts from the deployed versions. Do not treat it as the source of the pool logic, because that is in the separate core repository. Verify first which package version you are depending on, since the published package pins artifacts to a particular build, and that your Solidity compiler version matches the OpenZeppelin release the contracts are written against, because the dependency is pinned to a specific solc 0.7 build.
Frequently asked questions
What is in the Uniswap v3-periphery repository?
The periphery smart contracts for the Uniswap V3 Protocol, which sit around the pools. The lower level core contracts are in the separate uniswap-v3-core repository, and the package is published as @uniswap/v3-periphery with the base contracts, interfaces, libraries and the compiled artifacts.
Why should I import the bytecode from the published artifacts?
So that you are testing against the same bytecode that is deployed to mainnet and public testnets, and so that all Uniswap code interoperates correctly with your local deployment, rather than with a build of the contracts you compiled yourself.
How do I use the Uniswap v3 periphery interfaces in my own contract?
Import them from the npm artifact with import '@uniswap/v3-periphery/contracts/interfaces/ISwapRouter.sol', which means the interface you compile against is the one the deployed router actually implements rather than a hand written copy.
Which dependencies does the Uniswap v3 periphery have?
OpenZeppelin contracts at 3.4.2-solc-0.7, @uniswap/lib at 4.0.1-alpha, @uniswap/v2-core at 1.0.1, @uniswap/v3-core at 1.0.0, and base64-sol at 1.0.1.
How are the Uniswap v3 periphery contracts tested?
With Hardhat, running hardhat compile and hardhat test, using Waffle and chai with mocha, mocha-chai-jest-snapshot for snapshots, and TypeChain to generate the TypeScript bindings from the compiled contracts.
What licence does the Uniswap v3 periphery use?
GPL-2.0-or-later, recorded in the package manifest and the LICENSE file at the root of the repository, and the repository is covered by the Uniswap V3 bug bounty programme whose terms are in bug-bounty.md.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/uniswap-v3-periphery)Was this useful?