Skip to content

Commit 630fc0f

Browse files
committed
refactor: proxy and calldata
1 parent de7e0f7 commit 630fc0f

5 files changed

Lines changed: 90 additions & 25 deletions

File tree

contracts/pol/LiquidityManagerCore.sol

Lines changed: 56 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ error ZeroAddress();
2121
/// @dev Zero value when it has to be different from zero.
2222
error ZeroValue();
2323

24+
/// @dev The contract is already initialized.
25+
error AlreadyInitialized();
26+
2427
/// @dev Value overflow.
2528
/// @param provided Overflow value.
2629
/// @param max Maximum possible value.
@@ -41,11 +44,24 @@ error RangeBounds(int24 low, int24 center, int24 high);
4144
error ReentrancyGuard();
4245

4346
interface INeighborhoodScanner {
47+
/// @dev Optimizes liquidity amounts by widening up provided ticks using binary search + neighborhood search.
48+
/// @notice 1. Adjusts extreme boundaries, if required.
49+
/// 2. Looks for correct boundaries and adjusts tick spacings accordingly.
50+
/// 3. Fixes one of ticks and executed binary + neighborhood search if scan option is true.
51+
/// Ensures non-zero intermediate for amount0 formula without linear loops.
52+
/// @param sqrtP Center sqrt price.
53+
/// @param ticks Ticks array.
54+
/// @param tickSpacing Tick spacing.
55+
/// @param initialAmounts Initial amounts array.
56+
/// @param scan True if binary and neighborhood ticks search for optimal liquidity is requested, false otherwise.
57+
/// @return loHi Optimized ticks.
58+
/// @return liquidity Corresponding liquidity.
59+
/// @return amountsDesired Corresponding desired amounts.
4460
function optimizeLiquidityAmounts(
45-
uint160 centerSqrtPriceX96,
61+
uint160 sqrtP,
4662
int24[] memory ticks,
4763
int24 tickSpacing,
48-
uint256[] memory balances,
64+
uint256[] memory initialAmounts,
4965
bool scan
5066
) external pure returns (int24[] memory loHi, uint128 liquidity, uint256[] memory amountsDesired);
5167
}
@@ -57,6 +73,7 @@ interface INeighborhoodScanner {
5773
abstract contract LiquidityManagerCore is ERC721TokenReceiver {
5874
event OwnerUpdated(address indexed owner);
5975
event ImplementationUpdated(address indexed implementation);
76+
event MaxSlippageUpdated(uint256 maxSlippage);
6077
event ConvertedToV3(address indexed pool, uint256 indexed positionId, address[] tokens, uint256[] amounts, uint256 liquidiy, bool scan);
6178
event RangesChanged(address indexed pool, uint256 indexed positionId, address[] tokens, uint256[] amounts, uint256 liquidiy, bool scan);
6279
event UtilityAmountsManaged(address indexed olas, address indexed token, uint256 olasAmount, uint256 tokenAmount, bool olasBurnOrTransfer);
@@ -114,39 +131,30 @@ abstract contract LiquidityManagerCore is ERC721TokenReceiver {
114131
/// @param _positionManagerV3 Uniswap V3 position manager address.
115132
/// @param _neighborhoodScanner Neighborhood ticks scanner.
116133
/// @param _observationCardinality Observation cardinality for fresh pools.
117-
/// @param _maxSlippage Max slippage for operations.
118134
constructor(
119135
address _olas,
120136
address _treasury,
121137
address _positionManagerV3,
122138
address _neighborhoodScanner,
123-
uint16 _observationCardinality,
124-
uint16 _maxSlippage
139+
uint16 _observationCardinality
125140
) {
126-
owner = msg.sender;
127-
128141
// Check for zero addresses
129142
if (_olas == address(0) || _treasury == address(0) || _positionManagerV3 == address(0) ||
130143
_neighborhoodScanner == address(0))
131144
{
132145
revert ZeroAddress();
133146
}
134147

135-
// Check for zero values
136-
if (_maxSlippage == 0 || _observationCardinality == 0) {
148+
// Check for zero value
149+
if (_observationCardinality == 0) {
137150
revert ZeroValue();
138151
}
139-
// Check for max value
140-
if (_maxSlippage > MAX_BPS) {
141-
revert Overflow(_maxSlippage, MAX_BPS);
142-
}
143152

144153
olas = _olas;
145154
treasury = _treasury;
146155
positionManagerV3 = _positionManagerV3;
147156
neighborhoodScanner = _neighborhoodScanner;
148157
observationCardinality = _observationCardinality;
149-
maxSlippage = _maxSlippage;
150158

151159
// Get V3 factory address
152160
factoryV3 = IUniswapV3(positionManagerV3).factory();
@@ -475,8 +483,24 @@ abstract contract LiquidityManagerCore is ERC721TokenReceiver {
475483
}
476484

477485
/// @dev Initialization function.
478-
function initialize() external {
486+
/// @param _maxSlippage Max slippage for operations.
487+
function initialize(uint16 _maxSlippage) external {
488+
if (owner != address(0)) {
489+
revert AlreadyInitialized();
490+
}
491+
492+
// Check for zero value
493+
if (_maxSlippage == 0) {
494+
revert ZeroValue();
495+
}
496+
// Check for max value
497+
if (_maxSlippage > MAX_BPS) {
498+
revert Overflow(_maxSlippage, MAX_BPS);
499+
}
479500

501+
maxSlippage = _maxSlippage;
502+
503+
owner = msg.sender;
480504
}
481505

482506
/// @dev Changes the owner address.
@@ -517,6 +541,23 @@ abstract contract LiquidityManagerCore is ERC721TokenReceiver {
517541
emit ImplementationUpdated(implementation);
518542
}
519543

544+
/// @dev Changes max slippage value.
545+
/// @param newMaxSlippage New max slippage value.
546+
function changeMaxSlippage(uint16 newMaxSlippage) external {
547+
// Check for the contract ownership
548+
if (msg.sender != owner) {
549+
revert OwnerOnly(msg.sender, owner);
550+
}
551+
552+
// Check for zero value
553+
if (newMaxSlippage == 0) {
554+
revert ZeroValue();
555+
}
556+
557+
maxSlippage = newMaxSlippage;
558+
emit MaxSlippageUpdated(newMaxSlippage);
559+
}
560+
520561
/// @dev Converts token amounts to V3 liquidity: from balances, or from V2 liquidity, or both.
521562
/// @param tokens Token addresses.
522563
/// @param v2Pool V2 pool hash / address.

contracts/pol/LiquidityManagerETH.sol

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,6 @@ contract LiquidityManagerETH is LiquidityManagerCore {
133133
/// @param _positionManagerV3 Uniswap V3 position manager address.
134134
/// @param _neighborhoodScanner Neighborhood ticks scanner.
135135
/// @param _observationCardinality Observation cardinality for fresh pools.
136-
/// @param _maxSlippage Max slippage for operations.
137136
/// @param _oracleV2 V2 pool related oracle address.
138137
/// @param _routerV2 Uniswap V2 Router address.
139138
constructor(
@@ -142,10 +141,9 @@ contract LiquidityManagerETH is LiquidityManagerCore {
142141
address _positionManagerV3,
143142
address _neighborhoodScanner,
144143
uint16 _observationCardinality,
145-
uint16 _maxSlippage,
146144
address _oracleV2,
147145
address _routerV2
148-
) LiquidityManagerCore(_olas, _treasury, _positionManagerV3, _neighborhoodScanner, _observationCardinality, _maxSlippage)
146+
) LiquidityManagerCore(_olas, _treasury, _positionManagerV3, _neighborhoodScanner, _observationCardinality)
149147
{
150148
// Check for zero addresses
151149
if (_oracleV2 == address(0) || _routerV2 == address(0)) {

contracts/pol/LiquidityManagerOptimism.sol

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,6 @@ contract LiquidityManagerOptimism is LiquidityManagerCore {
191191
/// @param _positionManagerV3 Uniswap V3 position manager address.
192192
/// @param _neighborhoodScanner Neighborhood ticks scanner.
193193
/// @param _observationCardinality Observation cardinality for fresh pools.
194-
/// @param _maxSlippage Max slippage for operations.
195194
/// @param _oracleV2 V2 pool related oracle address.
196195
/// @param _balancerVault Balancer vault address.
197196
/// @param _bridge2Burner Bridge to Burner address.
@@ -201,11 +200,10 @@ contract LiquidityManagerOptimism is LiquidityManagerCore {
201200
address _positionManagerV3,
202201
address _neighborhoodScanner,
203202
uint16 _observationCardinality,
204-
uint16 _maxSlippage,
205203
address _oracleV2,
206204
address _balancerVault,
207205
address _bridge2Burner
208-
) LiquidityManagerCore(_olas, _treasury, _positionManagerV3, _neighborhoodScanner, _observationCardinality, _maxSlippage)
206+
) LiquidityManagerCore(_olas, _treasury, _positionManagerV3, _neighborhoodScanner, _observationCardinality)
209207
{
210208
// Check for zero address
211209
if (_oracleV2 == address(0) || _balancerVault == address(0) || _bridge2Burner == address(0)) {

test/LiquidityManagerBase.t.sol

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import {Test, console} from "forge-std/Test.sol";
44
import {Utils} from "./utils/Utils.sol";
55
import {FixedPointMathLib} from "../lib/solmate/src/utils/FixedPointMathLib.sol";
66
import {LiquidityManagerOptimism} from "../contracts/pol/LiquidityManagerOptimism.sol";
7+
import {LiquidityManagerProxy} from "../contracts/proxies/LiquidityManagerProxy.sol";
78
import {NeighborhoodScanner} from "../contracts/pol/NeighborhoodScanner.sol";
89
import {BalancerPriceOracle} from "../contracts/oracles/BalancerPriceOracle.sol";
910
import {IToken} from "../contracts/interfaces/IToken.sol";
@@ -111,15 +112,28 @@ contract BaseSetup is Test {
111112
dev = users[1];
112113
vm.label(dev, "Developer");
113114

115+
// Deploy V2 oracle
114116
oracleV2 = new BalancerPriceOracle(OLAS, WETH, uint256(maxSlippage / 100), minUpdateTimePeriod, BALANCER_VAULT,
115117
POOL_V2_BYTES32);
116118

117119
// Advance some time such that oracle has a time difference between last updated price
118120
vm.warp(block.timestamp + 100);
119121

122+
// Deploy neighborhood scanner
120123
neighborhoodScanner = new NeighborhoodScanner();
121-
liquidityManager = new LiquidityManagerOptimism(OLAS, TIMELOCK, POSITION_MANAGER_V3, address(neighborhoodScanner),
122-
observationCardinality, maxSlippage, address(oracleV2), BALANCER_VAULT, TIMELOCK);
124+
125+
// Deploy LiquidityManagerOptimism implementation
126+
LiquidityManagerOptimism liquidityManagerImplementation = new LiquidityManagerOptimism(OLAS, TIMELOCK,
127+
POSITION_MANAGER_V3, address(neighborhoodScanner), observationCardinality, address(oracleV2),
128+
BALANCER_VAULT, TIMELOCK);
129+
130+
// Deploy LiquidityManagerProxy
131+
bytes memory initPayload = abi.encodeWithSignature("initialize(uint16)", maxSlippage);
132+
LiquidityManagerProxy liquidityManagerProxy =
133+
new LiquidityManagerProxy(address(liquidityManagerImplementation), initPayload);
134+
135+
// Wrap proxy into implementation
136+
liquidityManager = LiquidityManagerOptimism(address(liquidityManagerProxy));
123137

124138
// Get pool total supply
125139
uint256 totalSupply = IToken(POOL_V2).totalSupply();

test/LiquidityManagerETH.t.sol

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import {Test, console} from "forge-std/Test.sol";
44
import {Utils} from "./utils/Utils.sol";
55
import {FixedPointMathLib} from "../lib/solmate/src/utils/FixedPointMathLib.sol";
66
import {LiquidityManagerETH} from "../contracts/pol/LiquidityManagerETH.sol";
7+
import {LiquidityManagerProxy} from "../contracts/proxies/LiquidityManagerProxy.sol";
78
import {NeighborhoodScanner} from "../contracts/pol/NeighborhoodScanner.sol";
89
import {UniswapPriceOracle} from "../contracts/oracles/UniswapPriceOracle.sol";
910
import {IToken} from "../contracts/interfaces/IToken.sol";
@@ -73,10 +74,23 @@ contract BaseSetup is Test {
7374
dev = users[1];
7475
vm.label(dev, "Developer");
7576

77+
// Deploy V2 oracle
7678
oracleV2 = new UniswapPriceOracle(WETH, uint256(maxSlippage / 100), PAIR_V2);
79+
80+
// Deploy neighborhood scanner
7781
neighborhoodScanner = new NeighborhoodScanner();
78-
liquidityManager = new LiquidityManagerETH(OLAS, TIMELOCK, POSITION_MANAGER_V3, address(neighborhoodScanner),
79-
observationCardinality, maxSlippage, address(oracleV2), ROUTER_V2);
82+
83+
// Deploy LiquidityManagerETH implementation
84+
LiquidityManagerETH liquidityManagerImplementation = new LiquidityManagerETH(OLAS, TIMELOCK, POSITION_MANAGER_V3,
85+
address(neighborhoodScanner), observationCardinality, address(oracleV2), ROUTER_V2);
86+
87+
// Deploy LiquidityManagerProxy
88+
bytes memory initPayload = abi.encodeWithSignature("initialize(uint16)", maxSlippage);
89+
LiquidityManagerProxy liquidityManagerProxy =
90+
new LiquidityManagerProxy(address(liquidityManagerImplementation), initPayload);
91+
92+
// Wrap proxy into implementation
93+
liquidityManager = LiquidityManagerETH(address(liquidityManagerProxy));
8094

8195
// Get V2 pool balance
8296
uint256 v2Liquidity = IToken(PAIR_V2).balanceOf(TREASURY);

0 commit comments

Comments
 (0)