# Table of Contents - [Explainer | Doppler Docs](#explainer-doppler-docs) - [Treasury & governance | Doppler Docs](#treasury-governance-doppler-docs) - [Welcome | Doppler Docs](#welcome-doppler-docs) - [Airlock & modules | Doppler Docs](#airlock-modules-doppler-docs) - [Pure.st | Doppler Docs](#pure-st-doppler-docs) - [Quoter | Doppler Docs](#quoter-doppler-docs) - [Zora | Doppler Docs](#zora-doppler-docs) - [Fees & economics | Doppler Docs](#fees-economics-doppler-docs) - [Ohara | Doppler Docs](#ohara-doppler-docs) - [Security & bug bounties | Doppler Docs](#security-bug-bounties-doppler-docs) - [Implementation | Doppler Docs](#implementation-doppler-docs) - [Token | Doppler Docs](#token-doppler-docs) - [Factory | Doppler Docs](#factory-doppler-docs) - [Contract addresses | Doppler Docs](#contract-addresses-doppler-docs) --- # Explainer | Doppler Docs [PreviousWelcome](/) [NextImplementation](/how-it-works/implementation) Last updated 2 months ago 1 ### [](#tokens-get-created) Tokens get created Any application can permissonlessly create tokens from the Doppler smart contracts These tokens can be memecoins, RWAs, governance tokens β€” whatever your app focuses on 2 ### [](#onchain-dutch-auction-occurs) Onchain dutch auction occurs Tokens go through a price discovery period, fully onchain 3 ### [](#dynamic-bonding-curve-starts) Dynamic bonding curve starts Once a floor price is reached, tokens are available on a customized, dynamic bonding curve 4 ### [](#liquidity-moved-to-amm) Liquidity moved to AMM Once a specific value of tokens have been purchased or swapped, the tokens and LP positions automatically get migrated to Uniswap (v2 or v4), bootstrapping their initial liquidity 5 ### [](#complete) Complete This newly created token is freely swappable across all Uniswap supported interfaces and able to be utilized throughout your favorite applications or Ethereum DeFi protocols ### [](#design-principles) Design principles * **Capital efficiency** * Uniswap and Doppler are highly optimized to help tokens find their fair market price. * **MEV protecting** * Users are protected from sniping bots compared to other platforms due to the novel dynamics of the dutch auction based bonding curve, disrupting the dynamics of apeing in early. * **Programmability** * Doppler's smart contracts are fully onchain and composable with other programs. * We envision a large ecosystem and variety of mechanisms for token distribution & management, such as: vesting, airdrops, incentives, dao management, and more. * **EVM & DeFI native** * Automatically integrate your tokens into the latest & greatest Ethereum based DeFi protocols. * **Uniswap compatibility** * Tokens created on Doppler that reach their specific goals of liquidity will automatically get migrated to their own Uniswap v2 or Uniswap v4 pools and swappable from Uniswap supported interfaces. πŸŽ‰ --- # Treasury & governance | Doppler Docs [PreviousFees & economics](/how-it-works/fees-and-economics) [NextPure.st](/featured-users/pure.st) Last updated 4 days ago The Doppler Airlock comes out of the box with optional support for community managed treasuries, via the GovernanceFactory. These are currently implemented using industry standard contracts, specifically, , which was directly inspired by Compound Finance's Governor Bravo. Treasuries can be customized at the time of creation, including how much of a token gets allocated into the Treasury, how long it takes for a Treasury to unlock, or what the voting requirements are to move assets or take actions on behalf of the Treasury. ### [](#example-usage) Example usage Tokens created on Pure Markets have a community managed treasury that unlocks after 90 days. After the 90 days, any community member can propose an action to the contracts directly. Due to the usage of standard solutions like Open Zeppelin's Governor, third party websites and services like automatically support the token holder community's ability to vote on the proposed action. Community members would vote with weight proportionate to their token holdings. Refer to to view the open source Doppler Treasury & Governance implementation [Open Zeppelin's Governor](https://docs.openzeppelin.com/contracts/4.x/api/governance) [Tally.xyz](https://tally.xyz/) [GitHub](https://github.com/whetstoneresearch/doppler/blob/main/src/Governance.sol) --- # Welcome | Doppler Docs [NextExplainer](/how-it-works/publish-your-docs) Last updated 4 days ago Doppler is an Ethereum Virtual Machine (EVM) based token launchpad & liquidity bootstrapping protocol. It utilizes a new onchain mechanism we call a 'Dutch Auction Dynamic Bonding Curve' Which enables you to easily... 1 ### [](#create-arbitrary-assets) Create arbitrary assets Memecoins, RWAs, governance tokens, any arbitrary asset, can be created on Doppler 2 ### [](#enter-price-discovery) Enter price discovery Efficiently find the correct market driven price for these assets 3 ### [](#bootstrap-initial-liquidity) Bootstrap initial liquidity Build liquidity around the initial price and establish a marketplace for the assets 4 ### [](#plug-into-a-thriving-ecosystem) Plug into a thriving ecosystem Automatically connect your tokens & liquidity to the rich EVM DeFi & Uniswap ecosystems Token issuers and application developers no longer have to worry about the complicated, burdensome aspects of a token's lifecycle. From creation to issuance, price discovery to liquidity formation, distribution to ecosystem integrations - Doppler enables you to focus on building compelling, unique applications; not designing auctions, becoming MEV infrastructure experts, or grinding for distribution. ### [](#deployments) Deployments Doppler is currently deployed to Base, Unichain, and Ink, with others coming soon. , including testnet deployments to Arbitrum and Monad. ### [](#get-started) Get started #### [](#demo-app) Demo app Doppler has an open source demo application that targets Doppler v3. It is written in React, TypeScript and other familiar frameworks. The demo application is the easiest way to get familiar with what applications built ontop of the protocol look like. #### [](#sdk) SDK Doppler has an open source SDK that is written in TypeScript. It provides friendly and familiar interfaces for interacting with the onchain smart contracts. Additionally developers are able to interact with the smart contracts directly with their favorite toolchains. View the . πŸ”— [See the contract addresess](/resources/contract-addresses) [https://github.com/whetstoneresearch/doppler-v3-miniapp](https://github.com/whetstoneresearch/doppler-v3-miniapp) [SDK reference](/sdk-reference/factory) πŸ”— [https://github.com/whetstoneresearch/doppler-sdk/tree/main/packages/doppler-v3-sdk](https://github.com/whetstoneresearch/doppler-sdk/tree/main/packages/doppler-v3-sdk) --- # Airlock & modules | Doppler Docs [PreviousImplementation](/how-it-works/implementation) [NextFees & economics](/how-it-works/fees-and-economics) Last updated 4 days ago Airlock is what we refer to Doppler's implementation of a smart contract protocol facilitating the deployment of new tokens using a modular approach. Here's an overview of the components: [](#architecture) Architecture ----------------------------------- Different types of modules can be used to cover the several aspects of the token lifecycle: Module Role TokenFactory Deploys the tokens Bundler Enables purchasing at the time of creation, reducing MEV PoolInitializer Initializes a liquidity pool, for example on Uniswap V3 LiquidityMigrator Migrates liquidity from one pool to another GovernanceFactory Deploys governance and timelock contracts _Note: a "module" must be whitelisted before it can be used._ Refer to to view the open source Doppler Airlock implementation [GitHub](https://github.com/whetstoneresearch/doppler/blob/main/src/Airlock.sol) --- # Pure.st | Doppler Docs [PreviousTreasury & governance](/how-it-works/treasury-and-governance) [NextOhara](/featured-users/ohara) Last updated 1 month ago ### [](#description) Description was the first interface supporting Doppler, home to some of the most OG assets on . ### [](#features) Features #### [](#explore) Explore Explore memecoins across the entire Doppler ecosystem, regardless of what app they were created on. #### [](#create) Create Users can create memecoins on Doppler v3, or Doppler v4 (coming soon). ### [](#socials) Socials πŸ”— πŸ”— [Pure.st](https://pure.st) [Unichain](https://www.unichain.org/) [x.com/pure\_markets](https://x.com/pure_markets) [t.me/pure\_markets](https://t.me/pure_markets) --- # Quoter | Doppler Docs The Quoter provides price quoting functionality for both Uniswap V3 and V2 swaps. It enables simulation of exact input/output swaps without executing transactions, with proper decimal handling for amounts. [](#readquoter) ReadQuoter ------------------------------- Copy export class ReadQuoter { constructor( quoteV2Address: Address, univ2RouterAddress: Address, drift: Drift = createDrift() ) Methods: * **quoteExactInputV3** - Get price quote for exact input swap (Uniswap V3) Copy async quoteExactInputV3( params: FunctionArgs["params"] ): Promise> * **quoteExactOutputV3** - Get price quote for exact output swap (Uniswap V3) Copy async quoteExactOutputV3( params: FunctionArgs["params"] ): Promise> * **quoteExactInputV2** - Get price quote for exact input swap (Uniswap V2) Copy async quoteExactInputV2( params: FunctionArgs ): Promise> * **quoteExactOutputV2** - Get price quote for exact output swap (Uniswap V2) Copy async quoteExactOutputV2( params: FunctionArgs ): Promise> ### [](#contract-abis) Contract ABIs Copy export type QuoterV2ABI = typeof quoterV2Abi; export type UniswapV2Router02ABI = typeof uniswapV2Router02Abi; [](#example-usage) Example Usage ------------------------------------- Copy const quoter = new ReadQuoter("0xQuoterV2Address", "0xUniV2RouterAddress"); // V3 Exact Input Quote const v3InputQuote = await quoter.quoteExactInputV3({ tokenIn: "0x...", tokenOut: "0x...", amountIn: 1000000n, fee: 3000, sqrtPriceLimitX96: 0n, }); // V2 Exact Output Quote const v2OutputQuote = await quoter.quoteExactOutputV2({ amountOut: 500000n, path: ["0x...", "0x..."], to: "0x...", deadline: Math.floor(Date.now() / 1000) + 300, }); [PreviousToken](/sdk-reference/token) [NextContract addresses](/resources/contract-addresses) Last updated 2 months ago --- # Zora | Doppler Docs [PreviousOhara](/featured-users/ohara) [NextFactory](/sdk-reference/factory) Last updated 4 days ago ### [](#description) Description Zora is an onchain social network, where every post is a "content coin". ### [](#how-it-works) How it works Users can visit Zora, browse, and explore content from other Creators. They are able to create their own content on the platform, similar to traditional web2 social media applications. When creating a post, each post gets it's own unique, fungible token, created with the help Doppler's smart contracts. Other users can then collect their favorite content, and the creators earn fee's when doing so. ### [](#implementation-details) Implementation details Zora is using a custom implementation of Doppler that works with their existing smart contract protocol. A case study for the Zora Doppler integration is a work in progress. Check back soon! ### [](#socials) Socials πŸ”— πŸ”— [https://zora.co/](https://zora.co/) [https://x.com/zora](https://x.com/zora) --- # Fees & economics | Doppler Docs [PreviousAirlock & modules](/how-it-works/airlock-and-modules) [NextTreasury & governance](/how-it-works/treasury-and-governance) Last updated 2 months ago Doppler's smart contracts contain enshrined an in-protocol, enshrined fee system. Every time a token is created or swapped, fees are calculated & paid for by the users of Doppler. These fee's are paid for in $ETH. * Integrator Fee - up to 95% of LP fees * This fee is configurable by third party application integrators * This can be set between 0 - 95% of total LP fees earned * See more in the * Protocol Fee - 5% of LP fees * This fee is fixed at 5% of total LP fees earned It is expected that eventually in subsequent versions of the protocol other tokens may be utilized in order to pay for the protocol fees. This may dependent on the application/interface's parameterization, the token creator's preference, the network the contracts are deployed to, or other tbd configurations. [SDK reference](/sdk-reference/factory) --- # Ohara | Doppler Docs [PreviousPure.st](/featured-users/pure.st) [NextZora](/featured-users/zora) Last updated 26 days ago ### [](#description) Description From prompt to onchain app, is the simplest way to generate apps on . Save money and focus on what matters: your ideas. ### [](#how-it-works) How it works Once users are happy with the applications Ohara generated via their prompts, they can publish it alongside the creation of an App Coin (via Doppler), subject to the following implementation details. ### [](#implementation-details) Implementation details * 10% of the total token supply publisher of an application on Ohara * Subject to linear vesting ("unlocks") over 12 months * 3% of the total token supply treasury of an application that gets "remixed" on Ohara * Ohara.ai has the notion or concept of "remixing" an application * This means that an application which was originally created (or prompted) by a specific user was essentially "forked" often with slight changes. By default, Ohara gives 3% of the token supply of _remixed_ applications to the original application's creator. Implementation details are subject to change and provided for educational purposes only. Verify onchain. ### [](#socials) Socials πŸ‘‰ πŸ‘‰ πŸ”— πŸ”— [Ohara](https://ohara.ai/apps) [Base](https://www.base.org/) [discord.gg/ohara-ai](https://discord.gg/ohara-ai) [x.com/tryOharaAI](https://x.com/tryoharaai) --- # Security & bug bounties | Doppler Docs [PreviousContract addresses](/resources/contract-addresses) Last updated 4 days ago [](#audits) Audits ----------------------- Doppler has been audited multiple times by top teams. \- Nov. 2024 \- Nov. 204 Additionally, Doppler had a public audit contest done via Cantina. [](#bug-bounty-and-issues) Bug Bounty & Issues --------------------------------------------------- Doppler has an active bug bounty program being ran in collaboration with Cantina. Learn more & report bugs: Please follow best practices for responsible disclosure as there could be user funds at risk. ### [](#questions) Questions? Contact security@whetstone.cc πŸ”— πŸ”— πŸ”— [OpenZeppelin Audit](https://drive.google.com/drive/folders/1cgY4UDtQ9j2v1t4XvFBraJqNCUfrdFxq?dmr=1&ec=wgc-drive-globalnav-goto) [Certora Audit](https://drive.google.com/drive/folders/1cgY4UDtQ9j2v1t4XvFBraJqNCUfrdFxq?dmr=1&ec=wgc-drive-globalnav-goto) [Doppler Cantina Audit Contest](https://cantina.xyz/competitions/57b00aab-8f8b-4d62-9378-41b6460ce6aa) [https://cantina.xyz/bounties/2c7af549-c36c-4432-bae6-3f4b1fa6b217](https://cantina.xyz/bounties/2c7af549-c36c-4432-bae6-3f4b1fa6b217) --- # Implementation | Doppler Docs [PreviousExplainer](/how-it-works/publish-your-docs) [NextAirlock & modules](/how-it-works/airlock-and-modules) Last updated 2 months ago Doppler has both a Uniswap v3 and Uniswap v4 implementation. Initially, it will release with the v3 implementation due to the underlying protocols security, ecosystem support, and maturity. This documentation is a work in progress... We're working on it! Check back soon! ### [](#uniswap-v3-implementation-explainer) Uniswap v3 implementation - explainer 1. Applications send a message to the Doppler smart contracts to create a token,. This message can be formed entirely utilizing the doppler-sdk 2. The Doppler contracts create an ERC-20, a Uniswap v3 pool, a Uniswap v2 pool, and a Timelock. The code that facilitates this entire process is known as the 1. Each one of these pieces is created by a β€œmodule”, which is an interface into the Doppler Airlock to facilitate individual trading actions like the liquidity bootstrapping pool, token factory, migrator (moves to generalized AMM), or timelock. 3. A share of the tokens set by the Interface are sent immediately to the Uniswap v3 pool 1. The Uniswap v3 migrator contracts are designed to mitigate sniping by adjusting how liquidity is placed on the curve. There is no longer just one position. 1. The multiple positions determine the steepness of the curve. The steeper the curve, the more tokens are sold near the migration price of the curve. The modulation of this curve via market forces is supported in the Uniswap v4. 2. The max share of the entire token supply that can be sent is 50% and the minimum is 5% of the token supply. Whatever amount to send is determined by the Interface. 3. There is a poke function that migrates the tokens to the next step. 1. In the Uniswap v4 implementation, this is automatic, and we have other methodologies to make it automatic in the Uniswap v3 implementation. 4. Once a certain price is met, the asset token (like ETH/USDC/USDT) are sent back to the Airlock, which calls the migrator module 4. Once receiving ETH or whatever pre-specified token, the Airlock calls the migrator module. The module finds the most amount of LP tokens possible at the final price of the v3 pool. The migrator then utilizes whatever share of the tokens in the Airlock that it can, before sending the rest to the Timelock. 1. The Uniswap v2 shares are held by the Timelock, meaning that the share sold to the open market is not lost forever when burned. 2. The Timelock is gated for a time period of N, eg. 3 months, to ensure that users have time to trust the LP is locked 5. Bundled shares vest automatically, as does the integrator share and the Doppler share. ### [](#uniswap-v4-implementation) Uniswap v4 implementation The Uniswap v4 version of Doppler is exactly the same as the Uniswap v3 version for all the features mentioned above **EXCEPT** the liquidity bootstrapping step. #### [](#uniswap-v4-permissions) Uniswap v4 Permissions The Doppler Protocol makes use of 4 Uniswap v4 hook functions in its contract: * `afterInitialize` * Used to place initial liquidity positions * `beforeSwap` * Used to trigger rebalancing of the bonding curve if the Protocol has not yet rebalanced in the current epoch * `afterSwap` * Used to account the total amount of asset tokens sold, `totalTokensSold`, and the total amount of numeraire tokens received from asset sales, `totalProceeds` * The Protocol excludes the swap fee, consisting of the LP fee and the Uniswap Protocol fee, from the accounted amounts such that it doesn't reinvest LP fees or attempt to reinvest protocol fees taken by Uniswap v4 * `beforeAddLiquidity` * Used to trigger a revert if a user attempts to provide liquidity. This is necessary because the Protocol doesn't want any external liquidity providers beside itself. * External liquidity providers are blocked because it may result in a situation where the Doppler Protocol is unable to reset the underlying Uniswap v4 pool's accounting, creating accounting issues for the Protocol. As previously stated, the main difference of v4-Doppler vs. v3-Doppler is the modulation of the positions placed is dynamic when compared to the Uniswap v3 version. This is the dynamic part referred to in "dynamic bonding curves". ### [](#dynamic-dutch-auctions) Dynamic Dutch-auctions Curve Accumulation The Doppler Protocol rebalance its bonding curve according to token sales along a pre-defined schedule based on the number of tokens to sell, `numTokensToSell`, over the duration, `endingTime - startingTime`. This rebalance occurs immediately preceeding the first swap in every epoch, in the `beforeSwap` hook. If the hook doesn't have any swaps in a given epoch then the rebalance applies retroactively to all missed epochs. #### [](#max-dutch-auction) Max Dutch Auction If sales are behind schedule, the curve is reduced via a dutch auction mechanism according to the relative amount that the Protocol is behind schedule. The maximum amount to dutch auction the curve in a single epoch is computed as the `endingTick - startingTick` divided by the total number of epochs, `(endingTime - startingTime) / epochLength`. In the case that there was a net sold amount of zero or less, computed as `totalTokensSold - totalTokensSoldLastEpoch`, the Protocol utilizes a dutch auction to shift the curve by this maximum amount. #### [](#relative-dutch-auction) Relative Dutch Auction If the net sold amount is greater than zero, but the Protocol hasn't sold as many tokens as expected, computed as `percentage(elapsed time / duration) * numTokensToSell`, then the Protocol executes a dutch auction of the curve by the relative amount that it is undersold by multiplied by the maximum dutch auction amount, e.g. if the Protocol sold 80% of the expected amount, it undersold by 20% and thus will dutch auction by 20% of the maximum dutch auction amount. #### [](#oversold-case) Oversold Case If sales are ahead of schedule, i.e. `totalTokensSold` is greater than the expected amount sold, computed as `percentage(elapsed time / duration) * numTokensToSell`, the Protocol moves the curve upwards by the amount that it has oversold by. The Protocol computes this increase as the delta between the current tick and the expected tick, which is generally the upper tick of the upper slug, which represents the point at which the Protocol has sold the expected amount (See Liquidity Placement). #### [](#tickaccumulator) `tickAccumulator` ### [](#terminology-in-dynamic-bonding-curves-slugs) Terminology in Dynamic Bonding Curves (Slugs) Within the bonding curve, the Protocol places 3 different types of liquidity positions, aka slugs: * Lower slug * Positioned below the current price, allowing for all purchased asset tokens to be sold back into the curve * Upper slug * Positioned above the current price, allowing for asset tokens to be purchased, places enough tokens to reach the expected amount of tokens sold * Price discovery slug(s) * Positioned above the upper slug, places enough tokens in each slug to reach the expected amount sold in the next epoch * Hook creators can pick an arbitrary amount of price discovery slugs, up to a maximum amount #### [](#lower-slug) Lower Slug The lower slug is generally placed ranging from the global tickLower to the current tick. The Protocol places the total amount of proceeds from asset sales, `totalProceeds`, into the slug, allowing the users to sell their tokens back into the curve. The lower slug must have enough liquidity to support all tokens being sold back into the curve. Ocassionally, the Protocol may not have sufficient `totalProceeds` to support all tokens being sold back into the curve with the usual slug placement. In this case, it computes the average clearing price of the tokens, computed as `totalProceeds / totalTokensSold` and place the slug at the tick corresponding to that price with a minimally sized range, i.e. range size of `tickSpacing`. #### [](#upper-slug) Upper Slug The upper slug is generally placed between the current tick and a delta, computed as `epochLength / duration * gamma`. The Protocol supplies the delta between the expected amount of tokens sold, computed as `percentage(elapsed time / duration) * numTokensToSell`, and the actual `totalTokensSold`. In the case that `totalTokensSold` is greater than the expected amount of tokens sold, it skips the slug and instead simply set the ticks in storage both as the current tick. #### [](#price-discovery-slugs) Price Discovery Slugs The price discovery slugs are generally placed between the upper slug upper tick and the top the bonding curve, `tickUpper`. The hook creator determines at the time of deployment how many price discovery slugs should be placed. The Protocol places the slugs equidistant between the upper slug's upper tick and the `tickUpper`, contiguously. the Protocol supplies tokens in each slug according to the percentage time difference between epochs multiplied by the `numTokensToSell`. Since the Protocol is supplying amounts according to remaining epochs, if it runs out of future epochs to supply for, it stops placing slugs. In the last epoch there will be no price disovery slugs. If you're an onchain auction enjoyooor, we recommend reading the The v4 implementation is coming soon. See for supported deployments. For whichever of the above outcomes the Protocol has hit, it accumulates a tick delta to the `tickAccumulator`. This value is used to derive the current bonding curve at any given time. It is derived by the lowermost tick of the curve, `tickLower`, as the `startingTick + tickAccumulator`. Additionally, it derives the uppermost tick of the curve, `tickUpper`, as the `tickLower + gamma`. We can see how the `tickAccumulator` is accumulated in this , with the red line corresponding to the max dutch auction case, the orange line corresponding to the relative dutch auction case, and the green line corresponding to the oversold case. ["Doppler Airlock"](/how-it-works/airlock-and-modules) πŸ‘ˆ [Doppler Whitepaper](https://github.com/whetstoneresearch/docs/blob/main/whitepapers/doppler/Dutch_auction_Dynamic_Bonding_Curves.pdf) [contract addresses](/resources/contract-addresses) [graph](https://www.desmos.com/calculator/fjnd0mcpst) --- # Token | Doppler Docs ### [](#token-class-overview) Token Class Overview The `Token` class is a javascript class representation of a DERC20 token deployed by the airlock contract. It is responsible for serving information about the state of the token, and for performing various actions on Doppler tokens. ### [](#readderc20) ReadDerc20 Read operations for Doppler tokens. Copy const token = new ReadDerc20(address: Address, drift?: Drift); Methods: DERC20 tokens extend the ERC20 interface, and so have the following methods: * `getName(): Promise` * `getSymbol(): Promise` * `getDecimals(): Promise` * `getTokenURI(): Promise` * `getAllowance(owner: Address, spender: Address): Promise` * `getBalanceOf(account: Address): Promise` * `getTotalSupply(): Promise` In addition, DERC20 tokens have the following methods: * `getPool(): Promise
` * `getPool` returns the address of the Uniswap V2 pool that the DERC20 token is migrated to after the liquidity bootstrapping process is complete. * `getIsPoolUnlocked(): Promise` * `getIsPoolUnlocked` returns `true` if the Uniswap V2 pool is unlocked, and `false` otherwise. * `getVestingData(account: Address): Promise<{totalAmount: bigint, releasedAmount: bigint}>` * `getVestingData` returns the total amount of tokens that have been vested for a given account, and the amount of tokens that have been released to the account. * `getVestingDuration(): Promise` * `getVestingDuration` returns the duration of the vesting period for the token. * `getVestingStart(): Promise` * `getVestingStart` returns the start time of the vesting period for the token. * `getVestedTotalAmount(): Promise` * `getVestedTotalAmount` returns the total amount of tokens that have been vested for the token. * `getYearlyMintRate(): Promise` * `getYearlyMintRate` returns the yearly mint rate for the token. ### [](#readwritederc20) ReadWriteDerc20 Extends ReadDerc20 with basic write operations. Copy const token = new ReadWriteDerc20(address: Address, drift: Drift); Methods: * `approve(spender: Address, value: bigint): Promise` [PreviousFactory](/sdk-reference/factory) [NextQuoter](/sdk-reference/quoter) Last updated 2 months ago --- # Factory | Doppler Docs ### [](#factory-overview) Factory Overview The factory is the main entrypoint for interacting with and creating tokens on the Doppler protocol. It is responsible for deploying new tokens, parameterizing pools, migrating existing tokens, and serving information about the state of the protocol. #### [](#readfactory) ReadFactory Read-only operations for the Doppler factory. Copy const factory = new ReadFactory(address: Address, drift?: Drift); Methods: * `getModuleState(address: Address): Promise` * Returns the state of a module (NotWhitelisted, TokenFactory, GovernanceFactory, HookFactory, Migrator) * `getAssetData(asset: Address): Promise` * Returns information about a DERC20 token deployed by the airlock contract: Copy interface AssetData { numeraire: Address; timelock: Address; governance: Address; liquidityMigrator: Address; poolInitializer: Address; pool: Address; migrationPool: Address; numTokensToSell: bigint; totalSupply: bigint; integrator: Address; } * `getCreateEvents(): Promise` * `getMigrateEvents(): Promise` #### [](#readwritefactory) ReadWriteFactory Extends ReadFactory with write operations. The primary use case for the ReadWriteFactory is to encode the parameters for, simulate, and invoke the `create` method. Proper utilization of the ReadWriteFactory involves the following steps: 1. Initialize a new `ReadWriteFactory` with the factory (airlock) address and a drift client with both a public and wallet client attached. 2. Pass `CreateV3PoolParams` to the `encode` method in order to build the calldata for the `create` method. Note that the `saleConfig`, `v3PoolConfig`, and `governanceConfig` are optional and can be omitted. Omission of these parameters will use the default values for each respective config. The default values are exported from the `doppler-v3-sdk` package under `defaultSaleConfig`, `defaultV3PoolConfig`, and `defaultGovernanceConfig`, and `defaultVestingConfig`. These default configs can be modified to customize the token creation process, but modifications should be made with caution as they may break some of the algebraic invariants of the Doppler protocol. Copy export interface CreateV3PoolParams { integrator: Address; userAddress: Address; numeraire: Address; contracts: InitializerContractDependencies; tokenConfig: TokenConfig; saleConfig?: Partial; v3PoolConfig?: Partial; vestingConfig: VestingConfig | "default"; governanceConfig?: Partial; } public encode(params: CreateV3PoolParams): { createParams: CreateParams; v3PoolConfig: V3PoolConfig; } `encode` returns the following payload, which is used to simulate and invoke the `create` method: Copy interface CreateParams { initialSupply: bigint; numTokensToSell: bigint; numeraire: Address; tokenFactory: Address; tokenFactoryData: Hex; governanceFactory: Address; governanceFactoryData: Hex; poolInitializer: Address; poolInitializerData: Hex; liquidityMigrator: Address; liquidityMigratorData: Hex; integrator: Address; salt: Hex; } 1. Simulate the `create` method to ensure the parameters are correct Copy public async simulateCreate(params: CreateParams): Promise> **Note:** The `simulateCreate` method is a simulation of the `create` method and does not consume any gas. It is recommended to simulate the `create` method before invoking it in order to ensure that the parameters are correct and that the method will succeed. 1. Invoke the `create` method Copy public async create( params: CreateParams, options?: ContractWriteOptions & OnMinedParam ): Promise #### [](#pool-operations) Pool Operations **ReadUniswapV3Pool** Read operations for Doppler V3 pools. Copy const pool = new ReadUniswapV3Pool(address: Address, drift?: Drift); Methods: * `getMintEvents(): Promise` * `getBurnEvents(): Promise` * `getSwapEvents(): Promise` * `getSlot0(): Promise<{sqrtPriceX96: bigint, tick: number}>` * `getToken0(): Promise
` * `getToken1(): Promise
` * `getFee(): Promise` #### [](#event-types) Event Types **Factory Events** Copy interface CreateEvent { asset: Address; numeraire: Address; initializer: Address; poolOrHook: Address; } interface MigrateEvent { asset: Address; pool: Address; } **Pool Events** Copy interface MintEvent { owner: Address; tickLower: number; tickUpper: number; amount: bigint; amount0: bigint; amount1: bigint; } interface BurnEvent { owner: Address; tickLower: number; tickUpper: number; amount: bigint; amount0: bigint; amount1: bigint; } interface SwapEvent { sender: Address; recipient: Address; amount0: bigint; amount1: bigint; sqrtPriceX96: bigint; liquidity: bigint; tick: number; } #### [](#network-configuration) Network Configuration Copy const DOPPLER_V3_ADDRESSES: { [chainId: number]: DopplerV3Addresses }; Supported Networks: * Unichain Sepolia (chainId: 1301) * Unichain (chainId: 130) ### [](#doppler-v4-sdk-api-reference) Doppler v4 SDK API Reference Coming Soon! [PreviousZora](/featured-users/zora) [NextToken](/sdk-reference/token) Last updated 2 months ago --- # Contract addresses | Doppler Docs [PreviousQuoter](/sdk-reference/quoter) [NextSecurity & bug bounties](/resources/security-and-bug-bounties) Last updated 19 days ago Here are the networks that Doppler is officially deployed to: * Mainnets: Base, Unichain, Ink * Testnets: Unichain Sepolia, Base Sepolia, Ink Sepolia, Monad Testnet If there are contracts not reflected here but claiming to be instances of Doppler, they are not considered canonical. Use with caution. [](#mainnet-deployments) Mainnet Deployments ------------------------------------------------- ### [](#base) Base Contract Address Airlock TokenFactory UniswapV3Initializer GovernanceFactory UniswapV2Migrator Bundler ### [](#unichain) Unichain Contract Address Airlock TokenFactory UniswapV3Initializer GovernanceFactory UniswapV2Migrator Bundler ### [](#ink) Ink Contract Address Airlock TokenFactory UniswapV3Initializer GovernanceFactory UniswapV2Migrator Bundler [](#testnet-deployments) Testnet Deployments ------------------------------------------------- ### [](#unichain-sepolia) Unichain Sepolia Contract Address Airlock TokenFactory UniswapV3Initializer GovernanceFactory UniswapV2Migrator Bundler ### [](#ink-sepolia) Ink Sepolia Contract Address Airlock TokenFactory UniswapV3Initializer GovernanceFactory UniswapV2Migrator Bundler Not deployed ### [](#base-sepolia) Base Sepolia Contract Address Airlock TokenFactory UniswapV3Initializer GovernanceFactory UniswapV2Migrator Bundler ### [](#world-sepolia) World Sepolia Contract Address Airlock TokenFactory UniswapV3Initializer GovernanceFactory UniswapV2Migrator Bundler Not deployed ### [](#monad) Monad Contract Address Airlock TokenFactory UniswapV3Initializer GovernanceFactory UniswapV2Migrator Bundler Not deployed 🚨 [0x660eAaEdEBc968f8f3694354FA8EC0b4c5Ba8D12](https://basescan.org/address/0x660eAaEdEBc968f8f3694354FA8EC0b4c5Ba8D12) [0xFAafdE6a5b658684cC5eb0C5c2c755B00A246F45](https://basescan.org/address/0xFAafdE6a5b658684cC5eb0C5c2c755B00A246F45) [0xaA47D2977d622DBdFD33eeF6a8276727c52EB4e5](https://basescan.org/address/0xaA47D2977d622DBdFD33eeF6a8276727c52EB4e5) [0xb4deE32EB70A5E55f3D2d861F49Fb3D79f7a14d9](https://basescan.org/address/0xb4deE32EB70A5E55f3D2d861F49Fb3D79f7a14d9) [0x5F3bA43D44375286296Cb85F1EA2EBfa25dde731](https://basescan.org/address/0x5F3bA43D44375286296Cb85F1EA2EBfa25dde731) [0x136191B46478cAB023cbC01a36160C4Aad81677a](https://basescan.org/address/0x136191B46478cAB023cbC01a36160C4Aad81677a) [0x77EbfBAE15AD200758E9E2E61597c0B07d731254](https://unichain.blockscout.com/address/0x77EbfBAE15AD200758E9E2E61597c0B07d731254) [0x43d0D97EC9241A8F05A264f94B82A1d2E600f2B3](https://unichain.blockscout.com/address/0x43d0D97EC9241A8F05A264f94B82A1d2E600f2B3) [0x9F4e56be80f08ba1A2445645EFa6d231E27b43ec](https://unichain.blockscout.com/address/0x9F4e56be80f08ba1A2445645EFa6d231E27b43ec) [0x99C94B9Df930E1E21a4E4a2c105dBff21bF5c5aE](https://unichain.blockscout.com/address/0x99C94B9Df930E1E21a4E4a2c105dBff21bF5c5aE) [0xf6023127f6E937091D5B605680056A6D27524bad](https://unichain.blockscout.com/address/0xf6023127f6E937091D5B605680056A6D27524bad) [0x91231cDdD8d6C86Df602070a3081478e074b97b7](https://unichain.blockscout.com/address/0x91231cDdD8d6C86Df602070a3081478e074b97b7) [0x660eAaEdEBc968f8f3694354FA8EC0b4c5Ba8D12](https://explorer.inkonchain.com/address/0x660eAaEdEBc968f8f3694354FA8EC0b4c5Ba8D12) [0xFAafdE6a5b658684cC5eb0C5c2c755B00A246F45](https://explorer.inkonchain.com/address/0xFAafdE6a5b658684cC5eb0C5c2c755B00A246F45) [0xaA47D2977d622DBdFD33eeF6a8276727c52EB4e5](https://explorer.inkonchain.com/address/0xaA47D2977d622DBdFD33eeF6a8276727c52EB4e5) [0xb4deE32EB70A5E55f3D2d861F49Fb3D79f7a14d9](https://explorer.inkonchain.com/address/0xb4deE32EB70A5E55f3D2d861F49Fb3D79f7a14d9) [0x5F3bA43D44375286296Cb85F1EA2EBfa25dde731](https://explorer.inkonchain.com/address/0x5F3bA43D44375286296Cb85F1EA2EBfa25dde731) [0x136191B46478cAB023cbC01a36160C4Aad81677a](https://explorer.inkonchain.com/address/0x136191B46478cAB023cbC01a36160C4Aad81677a) [0x77EbfBAE15AD200758E9E2E61597c0B07d731254](https://unichain-sepolia.blockscout.com/address/0x77EbfBAE15AD200758E9E2E61597c0B07d731254) [0x43d0D97EC9241A8F05A264f94B82A1d2E600f2B3](https://unichain-sepolia.blockscout.com/address/0x43d0D97EC9241A8F05A264f94B82A1d2E600f2B3) [0x9F4e56be80f08ba1A2445645EFa6d231E27b43ec](https://unichain-sepolia.blockscout.com/address/0x9F4e56be80f08ba1A2445645EFa6d231E27b43ec) [0x99C94B9Df930E1E21a4E4a2c105dBff21bF5c5aE](https://unichain-sepolia.blockscout.com/address/0x99C94B9Df930E1E21a4E4a2c105dBff21bF5c5aE) [0xf6023127f6E937091D5B605680056A6D27524](https://unichain-sepolia.blockscout.com/address/0xf6023127f6E937091D5B605680056A6D27524bad) [0x63f8C8F9beFaab2FaCD7Ece0b0242f78B920Ee90](https://unichain-sepolia.blockscout.com/address/0x63f8C8F9beFaab2FaCD7Ece0b0242f78B920Ee90) [0x5CadB034267751a364dDD4d321C99E07A307f915](https://explorer-sepolia.inkonchain.com/address/0x5CadB034267751a364dDD4d321C99E07A307f915) [0x77EbfBAE15AD200758E9E2E61597c0B07d731254](https://explorer-sepolia.inkonchain.com/address/0x77EbfBAE15AD200758E9E2E61597c0B07d731254) [0x43d0D97EC9241A8F05A264f94B82A1d2E600f2B3](https://explorer-sepolia.inkonchain.com/address/0x43d0D97EC9241A8F05A264f94B82A1d2E600f2B3) [0x9F4e56be80f08ba1A2445645EFa6d231E27b43ec](https://explorer-sepolia.inkonchain.com/address/0x9F4e56be80f08ba1A2445645EFa6d231E27b43ec) [0x99C94B9Df930E1E21a4E4a2c105dBff21bF5c5aE](https://explorer-sepolia.inkonchain.com/address/0x99C94B9Df930E1E21a4E4a2c105dBff21bF5c5aE) [0xE0dC4012AC9C868F09c6e4b20d66ED46D6F258d0](https://base-sepolia.blockscout.com/address/0xE0dC4012AC9C868F09c6e4b20d66ED46D6F258d0) [0x4225C632b62622Bd7B0A3eC9745C0a866Ff94F6F](https://base-sepolia.blockscout.com/address/0x4225C632b62622Bd7B0A3eC9745C0a866Ff94F6F) [0x620e3fec244e913d73f2163623b62d02DB69638B](https://base-sepolia.blockscout.com/address/0x620e3fec244e913d73f2163623b62d02DB69638B) [0x3AD727ee0FBBb8Ee0920933FdB96F23fD56f1299](https://base-sepolia.blockscout.com/address/0x3AD727ee0FBBb8Ee0920933FdB96F23fD56f1299) [0xA3C847eAb58eAa9cbc215C785c9cfBc19CDABD5f](https://base-sepolia.blockscout.com/address/0xA3C847eAb58eAa9cbc215C785c9cfBc19CDABD5f) [0x82Ac010C67f70BACf7655cd8948a4AD92A173CAC](https://base-sepolia.blockscout.com/address/0x82Ac010C67f70BACf7655cd8948a4AD92A173CAC) [0x5F3bA43D44375286296Cb85F1EA2EBfa25dde731](https://worldchain-sepolia.explorer.alchemy.com/address/0x5F3bA43D44375286296Cb85F1EA2EBfa25dde731) [0x5FBe931dc4B923A7abe4c47aD68d5bF9Eda5B76D](https://worldchain-sepolia.explorer.alchemy.com/address/0x5FBe931dc4B923A7abe4c47aD68d5bF9Eda5B76D) [0x9916Ec1c1E0462F6F8f7514e414F06bf001Ac82A](https://worldchain-sepolia.explorer.alchemy.com/address/0x9916Ec1c1E0462F6F8f7514e414F06bf001Ac82A) [0x136191B46478cAB023cbC01a36160C4Aad81677a](https://worldchain-sepolia.explorer.alchemy.com/address/0x136191B46478cAB023cbC01a36160C4Aad81677a) [0x8b4C7DB9121FC885689C0A50D5a1429F15AEc2a0](https://worldchain-sepolia.explorer.alchemy.com/address/0x8b4C7DB9121FC885689C0A50D5a1429F15AEc2a0) [0x5F3bA43D44375286296Cb85F1EA2EBfa25dde731](https://testnet.monadexplorer.com/address/0x5F3bA43D44375286296Cb85F1EA2EBfa25dde731) [0x5FBe931dc4B923A7abe4c47aD68d5bF9Eda5B76D](https://testnet.monadexplorer.com/address/0x5FBe931dc4B923A7abe4c47aD68d5bF9Eda5B76D) [0x9916Ec1c1E0462F6F8f7514e414F06bf001Ac82A](https://testnet.monadexplorer.com/address/0x9916Ec1c1E0462F6F8f7514e414F06bf001Ac82A) [0x136191B46478cAB023cbC01a36160C4Aad81677a](https://testnet.monadexplorer.com/address/0x136191B46478cAB023cbC01a36160C4Aad81677a) [0x8b4C7DB9121FC885689C0A50D5a1429F15AEc2a0](https://testnet.monadexplorer.com/address/0x8b4C7DB9121FC885689C0A50D5a1429F15AEc2a0) ---