Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/airlock (WIP) #53

Merged
merged 141 commits into from
Nov 4, 2024
Merged
Show file tree
Hide file tree
Changes from 75 commits
Commits
Show all changes
141 commits
Select commit Hold shift + click to select a range
8131f40
forge install: solady
clemlak Sep 11, 2024
ada4347
build: add Solady remapping
clemlak Sep 11, 2024
3aabf45
feat: add DERC20
clemlak Sep 11, 2024
02e2193
feat: add TokenFactory
clemlak Sep 11, 2024
5ec5d1f
feat: change token name to DERC20
clemlak Sep 11, 2024
52eca8b
feat: add Airlock contract
clemlak Sep 11, 2024
6288a83
feat: add setFactoryState
clemlak Sep 11, 2024
632a5c8
feat: add stageLiquidity function to Airlock
clemlak Sep 11, 2024
0286c57
feat: add TokenState enum
clemlak Sep 11, 2024
32789c5
feat: add a mapping to track the hook of each deployed token
clemlak Sep 11, 2024
9f6c08d
chore: add comment about stageLiquidity
clemlak Sep 11, 2024
842bac0
feat: call PoolManager in stageLiquidity
clemlak Sep 11, 2024
f71f2c0
chore: add TODOs
clemlak Sep 12, 2024
b2171ed
feat: update create, add Token struct
clemlak Sep 12, 2024
41b6bdb
feat: rename liquidityFactory to hook, tokenAddress to token
clemlak Sep 12, 2024
11e413f
chore: add initialization sequence diagram to README
clemlak Sep 13, 2024
a21169b
feat: add wip migrate function
clemlak Sep 13, 2024
9f7f061
feat: add IMigrator
clemlak Sep 16, 2024
470bef0
feat: add UniswapV2Migrator
clemlak Sep 16, 2024
17e887e
build: add Open Zeppelin remapping
clemlak Sep 26, 2024
561765d
feat: use Open Zeppelin ERC20 instead of Solady
clemlak Sep 26, 2024
5cd302b
build: remove Solady
clemlak Sep 26, 2024
9d8b90b
feat: use Open Zeppelin Ownable contract
clemlak Sep 26, 2024
21f3826
feat: inherit from ERC20Votes
clemlak Sep 26, 2024
9e14a6b
feat: add fee on transfer
clemlak Sep 26, 2024
ca00fab
feat: add minting start date, inherit Ownable
clemlak Sep 26, 2024
199f8c8
chore: update DERC20 TODO list
clemlak Sep 26, 2024
e137c82
feat: add ERC20Permit
clemlak Sep 26, 2024
7bf27ee
feat: override clock and clock mode in DERC20
clemlak Sep 27, 2024
24e85fc
feat: add basic Governor contract
clemlak Sep 27, 2024
233e8de
chore: rename to Governance, remove unused imports
clemlak Sep 27, 2024
0429375
feat: update TokenFactory
clemlak Sep 27, 2024
85fea52
feat: add GovernanceFactory
clemlak Sep 27, 2024
11308ef
feat: add IHookFactory
clemlak Sep 27, 2024
11855d3
feat: add DopplerFactory
clemlak Sep 27, 2024
ea1e4ab
feat: add IGovernanceFactory
clemlak Sep 27, 2024
ec1af55
feat: inherit from IGovernanceFactory
clemlak Sep 27, 2024
3d69808
feat: add ITokenFactory
clemlak Sep 27, 2024
7e989ca
feat: add default parameters to ITokenFactory
clemlak Sep 27, 2024
f479a3a
feat: inherit ITokenFactory
clemlak Sep 27, 2024
c3bbf30
feat: add token default parameter
clemlak Sep 27, 2024
6d34d56
feat: change create parameters, use new factory patterns
clemlak Sep 27, 2024
74992ea
feat: add name parameter
clemlak Sep 27, 2024
aa87065
feat: add name parameter to IGovernanceFactory
clemlak Sep 27, 2024
c1d1672
feat: pass name parameter to Governance
clemlak Sep 27, 2024
c1ca9ae
feat: store recipients and amounts, pass name to Governance factory
clemlak Sep 27, 2024
9819956
feat: add HookMiner library
clemlak Sep 27, 2024
1185d47
feat: use HookMiner to get Hook address, deploy using create2
clemlak Sep 30, 2024
d166531
feat: add predict to IHookFactory
clemlak Sep 30, 2024
fcdd062
feat: add predict to DopplerFactory
clemlak Sep 30, 2024
0a4fc0c
feat: use HookFactory predict to deploy the hook at the correct address
clemlak Sep 30, 2024
3a507ae
test: add AirlockTest
clemlak Sep 30, 2024
a5c404b
feat: set minimum sqrt price
clemlak Oct 2, 2024
ca3df6f
test: add test_Airlock_create
clemlak Oct 2, 2024
16a1ef2
feat: change default HookFactory parameters
clemlak Oct 2, 2024
4ffeaaf
feat: update DopplerFactory with new parameters
clemlak Oct 2, 2024
57d4e41
feat: change create parameters, add non-ETH support, fix pool init
clemlak Oct 2, 2024
04ab1b9
test: fix create test
clemlak Oct 2, 2024
bce7f4c
feat: append Governance to Governance contract name
clemlak Oct 2, 2024
b8bec22
feat: grant roles in GovernanceFactory
clemlak Oct 2, 2024
c45fa02
feat: transfer ownership of the token to governance
clemlak Oct 2, 2024
a590f60
test: add balance checks
clemlak Oct 2, 2024
1484adb
chore: add TODO tests
clemlak Oct 2, 2024
e39a918
Merge branch 'main' into feat/airlock
clemlak Oct 25, 2024
880aac8
build: remove remappings from foundry.toml (already present in remapp…
clemlak Oct 25, 2024
bae1935
chore: fix imports
clemlak Oct 25, 2024
bbbe325
feat: rename totalSupply to initialSupply
clemlak Oct 25, 2024
4043a99
chore: clean up Open Zeppelin remappings and fix imports
clemlak Oct 25, 2024
cfbb426
feat: remove poolKey from constructor, move tick spacing checks to be…
clemlak Oct 25, 2024
eedbb0a
chore: rename totalSupply to initialSupply
clemlak Oct 25, 2024
9c0830f
feat: add missing Doppler constructor params
clemlak Oct 25, 2024
b14a2e5
feat: remove FoT
clemlak Oct 25, 2024
859101f
test: remove poolKey constructor parameter
clemlak Oct 25, 2024
3231b1a
feat: return address instead of TimelockController type
clemlak Oct 25, 2024
ff2ea28
chore: rename TokenData type and getTokenData mapping
clemlak Oct 25, 2024
f550358
feat: update Governance and ERC20 voting token following OZ examples
clemlak Oct 28, 2024
2a08414
feat: add new params to migrate in IMigrator
clemlak Oct 29, 2024
95daaaf
feat: add IHook interface with migrate function
clemlak Oct 29, 2024
1523381
feat: add migrate to UniswapV2Migrator
clemlak Oct 29, 2024
8654a00
feat: update create function in GovernanceFactory
clemlak Oct 29, 2024
3426fad
feat: add migrate function in Doppler
clemlak Oct 29, 2024
8ae52f6
feat: implement migrate function, add Migrate event, add new params t…
clemlak Oct 29, 2024
7f85209
chore: add NatSpec to ITokenFactory
clemlak Oct 29, 2024
0924ea9
feat: change FactoryState to ModuleState, update event and related fu…
clemlak Oct 29, 2024
cfa5676
feat: add team allocation distribution
clemlak Oct 29, 2024
8162f9b
feat: add liquidity returned parameter to migrate function
clemlak Oct 29, 2024
691656c
feat: add ETH case in migrate, transfer LP tokens to recipient
clemlak Oct 29, 2024
77e0cc8
feat: pass timelock address as LP tokens recipient
clemlak Oct 29, 2024
9b247f4
chore: add dust tokens case TODO comment
clemlak Oct 29, 2024
caa5836
test: add Airlock test file
clemlak Oct 29, 2024
3869fde
test: delete previous Airlock test file
clemlak Oct 29, 2024
7010d5f
test: update Airlock test setup
clemlak Oct 29, 2024
a139ed6
test: add test_setModuleState_EmitsEvent
clemlak Oct 29, 2024
41ddda5
test: add test_setModuleState_RevertsWhenSenderNotOwner
clemlak Oct 29, 2024
8c0f28e
feat: use module types instead of address
clemlak Oct 29, 2024
c3a1b81
test: add constants
clemlak Oct 29, 2024
f8cafe7
feat: flip beforeInitialize bool
clemlak Oct 30, 2024
b21b395
feat: add isInitialized boolean
clemlak Oct 30, 2024
b1c0a36
chore: fix typo in initialSupply
clemlak Oct 30, 2024
f56da8e
test: add AirlockMiner
clemlak Oct 30, 2024
7057a57
feat: delete HookMiner
clemlak Oct 30, 2024
4121091
feat: add salt param to ITokenFactory create function
clemlak Oct 30, 2024
540f65a
feat: delete predict in IHookFactory, clean up create params
clemlak Oct 30, 2024
0125203
feat: add salt to TokenFactory create function
clemlak Oct 30, 2024
959e623
feat: remove predict function from DopplerFactory, clean up create fu…
clemlak Oct 30, 2024
47f78d2
feat: remove parameters from create function in IHookFactory
clemlak Oct 30, 2024
6098e67
feat: clean up create function parameters in DopplerFactory
clemlak Oct 30, 2024
f200990
feat: rename migrate function parameters in IMigrator
clemlak Oct 30, 2024
6e11efd
feat: refactor migrate function in UniswapV2Migrator
clemlak Oct 30, 2024
e0977d2
feat: refactor TokenData, create function and migrate function in Air…
clemlak Oct 30, 2024
d653deb
chore: delete unused IHooks import in Airlock contract
clemlak Oct 30, 2024
57d751d
test: turn mine into free function, add computeCreate2Address function
clemlak Oct 31, 2024
4b5a453
feat: rename migrate function returned parameters
clemlak Oct 31, 2024
e0ef9ca
feat: add missing numPDSlugs param, add deployer param
clemlak Oct 31, 2024
1eef929
test: update Airlock create test and base test file
clemlak Oct 31, 2024
b34b6a9
test: remove recipient and owner from MineParams, fix token init hash…
clemlak Oct 31, 2024
b7e4fd4
test: fix test_create_Deploys test
clemlak Oct 31, 2024
dde5675
test: use initialSupply for token init hash
clemlak Oct 31, 2024
f5e3744
feat: check initialSupply and numTokensToSell in Airlock
clemlak Oct 31, 2024
96feb40
test: add internal _create function in Airlock tests
clemlak Oct 31, 2024
b59592b
test: add test_create_RevertsIfWrongTokenFactory
clemlak Oct 31, 2024
0af001c
test: add test_create_RevertsIfWrongGovernanceFactory
clemlak Oct 31, 2024
f627fd8
test: add test_create_RevertsIfWrongHookFactory
clemlak Oct 31, 2024
fe9b520
test: add test_create_RevertsIfWrongMigrator
clemlak Oct 31, 2024
96526b2
test: add test_create_RevertsIfWrongInitialSupply
clemlak Oct 31, 2024
7e0d115
feat: add ArrayLengthsMismatch error and related check
clemlak Oct 31, 2024
df39733
test: add _getDefaultMineParams, refactor _create, add test_create_Mi…
clemlak Nov 1, 2024
d605fb3
chore: add Airlock README
clemlak Nov 1, 2024
fa55916
feat: implement migrate function
clemlak Nov 1, 2024
ef6f2f7
test: update CallbackData test
clemlak Nov 1, 2024
8ac5c2f
feat: fix ETH pair creation in UniswapV2Migrator
clemlak Nov 1, 2024
8e47c10
feat: remove ERC20 transfer when token0 is ETH
clemlak Nov 1, 2024
633eb7e
test: add migrate test
clemlak Nov 1, 2024
05ee04f
Merge branch 'main' into feat/airlock
clemlak Nov 4, 2024
33df61a
fix: add back some missing code after resolving conflicts
clemlak Nov 4, 2024
3c82ea0
test: skip broken tests
clemlak Nov 4, 2024
a3641d6
test: skip maxProceeds test
clemlak Nov 4, 2024
8864fe7
test: fix test_create_MintsTokens
clemlak Nov 4, 2024
e8e9b9e
feat: add Create event
clemlak Nov 4, 2024
c8e2d99
feat: add airlock immutable variable, fix migrate function condition
clemlak Nov 4, 2024
6a13852
fix: remove duplicate transfer
clemlak Nov 4, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions remappings.txt
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
v4-core/=lib/v4-periphery/lib/v4-core/
solady/=lib/solady/src/
@ensdomains/=lib/v4-core/node_modules/@ensdomains/
@openzeppelin/=lib/v4-core/lib/openzeppelin-contracts/
@openzeppelin/contracts/=lib/v4-core/lib/openzeppelin-contracts/contracts/
@openzeppelin/=lib/v4-core/lib/openzeppelin-contracts/contracts/
@uniswap/v4-core/=lib/v4-periphery/lib/v4-core/
ds-test/=lib/v4-core/lib/forge-std/lib/ds-test/src/
erc4626-tests/=lib/v4-core/lib/openzeppelin-contracts/lib/erc4626-tests/
forge-gas-snapshot/=lib/v4-core/lib/forge-gas-snapshot/src/
forge-std/=lib/forge-std/src/
hardhat/=lib/v4-core/node_modules/hardhat/
openzeppelin-contracts/=lib/v4-core/lib/openzeppelin-contracts/
permit2/=lib/v4-periphery/lib/permit2/
solmate/=lib/v4-core/lib/solmate/
v4-periphery/=lib/v4-periphery/
142 changes: 142 additions & 0 deletions src/Airlock.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.13;

import {IPoolManager, PoolKey, Currency, IHooks, TickMath} from "v4-core/src/PoolManager.sol";
import {Ownable} from "@openzeppelin/access/Ownable.sol";
import {ERC20} from "@openzeppelin/token/ERC20/ERC20.sol";
import {ITokenFactory} from "src/interfaces/ITokenFactory.sol";
import {IGovernanceFactory} from "src/interfaces/IGovernanceFactory.sol";
import {IHookFactory} from "src/interfaces/IHookFactory.sol";

enum FactoryState {
NotWhitelisted,
TokenFactory,
GovernanceFactory,
HookFactory
}

error WrongFactoryState();

struct TokenData {
address governance;
address hook;
address[] recipients;
uint256[] amounts;
}

event Create(address asset, address indexed numeraire, address governance, address hook);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does it make sense to include the poolId here? Wondering how an interface will get from a asset address to poolId and find the appropriate pool.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If poolId is included, probably need to include in TokenData above as well.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's add it 👌


contract Airlock is Ownable {
IPoolManager public immutable poolManager;

mapping(address => FactoryState) public getFactoryState;
mapping(address token => TokenData) public getTokenData;

constructor(IPoolManager poolManager_) Ownable(msg.sender) {
poolManager = poolManager_;
}

/**
* TODO:
* - Creating a token should incur fees (platform and frontend fees)
*
* @param tokenFactory Address of the factory contract deploying the ERC20 token
* @param governanceFactory Address of the factory contract deploying the governance
* @param hookFactory Address of the factory contract deploying the Uniswap v4 hook
*/
function create(
string memory name,
string memory symbol,
uint256 initialSupply,
uint256 minimumProceeds,
uint256 maximumProceeds,
uint256 startingTime,
uint256 endingTime,
int24 minTick,
int24 maxTick,
uint256 epochLength,
int24 gamma,
address numeraire,
address owner,
address tokenFactory,
bytes memory tokenData,
address governanceFactory,
bytes memory governanceData,
address hookFactory,
bytes memory hookData,
address[] memory recipients,
uint256[] memory amounts
) external returns (address, address, address) {
require(getFactoryState[tokenFactory] == FactoryState.TokenFactory, WrongFactoryState());
require(getFactoryState[governanceFactory] == FactoryState.GovernanceFactory, WrongFactoryState());
require(getFactoryState[hookFactory] == FactoryState.HookFactory, WrongFactoryState());

address token =
ITokenFactory(tokenFactory).create(name, symbol, initialSupply, address(this), address(this), tokenData);

bool isToken0 = token < numeraire ? true : false;

// FIXME: We might want to double compare the minted / predicted addresses?
(address predictedHook, bytes32 salt) = IHookFactory(hookFactory).predict(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should be called offchain and salt passed in as a param?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a bit tricky because we don't know all the constructor parameters at first (for example isToken0 because we haven't deployed the asset token yet). However deploying the token first and then mining the salt offchain will make us lose the atomicity of the transaction.

poolManager,
initialSupply,
minimumProceeds,
maximumProceeds,
startingTime,
endingTime,
isToken0 ? minTick : maxTick,
isToken0 ? maxTick : minTick,
epochLength,
gamma,
isToken0,
hookData
);
address hook = IHookFactory(hookFactory).create(
poolManager,
initialSupply,
minimumProceeds,
maximumProceeds,
startingTime,
endingTime,
isToken0 ? minTick : maxTick,
isToken0 ? maxTick : minTick,
epochLength,
gamma,
isToken0,
hookData,
salt
);
ERC20(token).transfer(hook, initialSupply);

(address governance, address timeLock) =
IGovernanceFactory(governanceFactory).create(name, token, governanceData);
// FIXME: I think the Timelock should be the owner of the token contract?
Ownable(token).transferOwnership(timeLock);

getTokenData[token] = TokenData({governance: governance, hook: hook, recipients: recipients, amounts: amounts});

PoolKey memory key = PoolKey({
currency0: Currency.wrap(isToken0 ? token : numeraire),
currency1: Currency.wrap(isToken0 ? numeraire : token),
fee: 0, // TODO: Do we want users to have the ability to set the fee?
tickSpacing: 60, // TODO: Do we want users to have the ability to set the tickSpacing?
hooks: IHooks(hook)
});

poolManager.initialize(key, TickMath.getSqrtPriceAtTick(isToken0 ? minTick : maxTick), new bytes(0));

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

emit Create(...)?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah we haven't really added the events yet. If you have feedback for events that are helpful from a ux pov would you mind adding them to the sdk doc/making a quick issue? I can also help build context here if needed.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added to #95

return (token, governance, hook);
}

/**
* TODO: This function will be callable later by the hook contract itself, in order to move the liquidity
* from the Uniswap v4 pool to a v2 pool. The flow would be something like:
* 1) Enough tokens were sold to trigger the migration
* 2) Hook contract will remove its positions
*/
function migrate() external {}

function setFactoryState(address factory, FactoryState state) external onlyOwner {
getFactoryState[factory] = state;
}
}
50 changes: 50 additions & 0 deletions src/DERC20.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.13;

import {ERC20} from "@openzeppelin/token/ERC20/ERC20.sol";
import {ERC20Votes} from "@openzeppelin/token/ERC20/extensions/ERC20Votes.sol";
import {EIP712} from "@openzeppelin/utils/cryptography/EIP712.sol";
import {Ownable} from "@openzeppelin/access/Ownable.sol";
import {ERC20Permit} from "@openzeppelin/token/ERC20/extensions/ERC20Permit.sol";
import {Nonces} from "@openzeppelin/utils/Nonces.sol";

/**
* TODO:
* - Add mint cap: bounded annual max inflation which can only go down
*/
error MintingNotStartedYet();

contract DERC20 is ERC20Votes, ERC20Permit, Ownable {
uint256 public immutable mintStartDate;
uint256 public immutable yearlyMintCap;

constructor(string memory name_, string memory symbol_, uint256 totalSupply_, address recipient, address owner_)
ERC20(name_, symbol_)
ERC20Permit(name_)
Ownable(owner_)
{
_mint(recipient, totalSupply_);
mintStartDate = block.timestamp + 365 days;
}

function mint(address to, uint256 value) external onlyOwner {
require(block.timestamp >= mintStartDate, MintingNotStartedYet());
_mint(to, value);
}

function clock() public view override returns (uint48) {
return uint48(block.timestamp);
}

function CLOCK_MODE() public pure override returns (string memory) {
return "mode=timestamp";
}

function nonces(address owner) public view virtual override(ERC20Permit, Nonces) returns (uint256) {
return super.nonces(owner);
}

function _update(address from, address to, uint256 value) internal virtual override(ERC20, ERC20Votes) {
super._update(from, to, value);
}
}
25 changes: 17 additions & 8 deletions src/Doppler.sol
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,6 @@ contract Doppler is BaseHook {

constructor(
IPoolManager _poolManager,
PoolKey memory _poolKey,
uint256 _numTokensToSell,
uint256 _minimumProceeds,
uint256 _maximumProceeds,
Expand All @@ -101,8 +100,6 @@ contract Doppler is BaseHook {
if (_isToken0 && _startingTick <= _endingTick) revert InvalidTickRange();
if (!_isToken0 && _startingTick >= _endingTick) revert InvalidTickRange();
}
// Enforce maximum tick spacing
if (_poolKey.tickSpacing > MAX_TICK_SPACING) revert InvalidTickSpacing();

/* Time checks */
uint256 timeDelta = _endingTime - _startingTime;
Expand All @@ -117,11 +114,6 @@ contract Doppler is BaseHook {
// _endingTime - startingTime must be divisible by epochLength
if (timeDelta % _epochLength != 0) revert InvalidEpochLength();

/* Gamma checks */
// Enforce that the total tick delta is divisible by the total number of epochs
// Enforce that gamma is divisible by tick spacing
if (_gamma % _poolKey.tickSpacing != 0) revert InvalidGamma();

/* Num price discovery slug checks */
if (_numPDSlugs == 0) revert InvalidNumPDSlugs();
if (_numPDSlugs > MAX_PRICE_DISCOVERY_SLUGS) revert InvalidNumPDSlugs();
Expand All @@ -142,6 +134,23 @@ contract Doppler is BaseHook {
numPDSlugs = _numPDSlugs;
}

function beforeInitialize(address, PoolKey calldata key, uint160, bytes calldata)
external
view
override
returns (bytes4)
{
// Enforce maximum tick spacing
if (key.tickSpacing > MAX_TICK_SPACING) revert InvalidTickSpacing();

/* Gamma checks */
// Enforce that the total tick delta is divisible by the total number of epochs
// Enforce that gamma is divisible by tick spacing
if (gamma % key.tickSpacing != 0) revert InvalidGamma();

return BaseHook.beforeInitialize.selector;
}

/// @notice Called by poolManager following initialization, used to place initial liquidity slugs
/// @param sender The address that called poolManager.initialize
/// @param key The pool key
Expand Down
80 changes: 80 additions & 0 deletions src/DopplerFactory.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
/// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.13;

import {IPoolManager} from "v4-core/src/interfaces/IPoolManager.sol";
import {Hooks} from "v4-core/src/libraries/Hooks.sol";
import {IHookFactory} from "src/interfaces/IHookFactory.sol";
import {Doppler} from "src/Doppler.sol";
import {HookMiner} from "src/HookMiner.sol";

contract DopplerFactory is IHookFactory {
function create(
IPoolManager poolManager,
uint256 numTokensToSell,
uint256 startingTime,
uint256 endingTime,
uint256 minimumProceeds,
uint256 maximumProceeds,
int24 startingTick,
int24 endingTick,
uint256 epochLength,
int24 gamma,
bool isToken0,
bytes memory,
bytes32 salt
) external returns (address) {
return address(
new Doppler{salt: salt}(
poolManager,
numTokensToSell,
startingTime,
endingTime,
minimumProceeds,
maximumProceeds,
startingTick,
endingTick,
epochLength,
gamma,
isToken0,
3 // numPDSlugs
)
);
}

function predict(
IPoolManager poolManager,
uint256 numTokensToSell,
uint256 startingTime,
uint256 endingTime,
uint256 minimumProceeds,
uint256 maximumProceeds,
int24 startingTick,
int24 endingTick,
uint256 epochLength,
int24 gamma,
bool isToken0,
bytes memory
) public view returns (address hookAddress, bytes32 salt) {
(hookAddress, salt) = HookMiner.find(
address(this),
uint160(
Hooks.BEFORE_INITIALIZE_FLAG | Hooks.AFTER_INITIALIZE_FLAG | Hooks.BEFORE_ADD_LIQUIDITY_FLAG
| Hooks.BEFORE_SWAP_FLAG | Hooks.AFTER_SWAP_FLAG
),
type(Doppler).creationCode,
abi.encode(
poolManager,
numTokensToSell,
startingTime,
endingTime,
minimumProceeds,
maximumProceeds,
startingTick,
endingTick,
epochLength,
gamma,
isToken0
)
);
}
}
Loading
Loading