Skip to content

Create the contracts for the openLp, collectLp and closeLp#12

Open
junta wants to merge 17 commits into
mainfrom
fea/lp-agent
Open

Create the contracts for the openLp, collectLp and closeLp#12
junta wants to merge 17 commits into
mainfrom
fea/lp-agent

Conversation

@junta
Copy link
Copy Markdown
Collaborator

@junta junta commented May 22, 2026

Introduces RateHopperPositions.sol, a Gnosis Safe module that wraps the full lifecycle of
Uniswap V3 WETH/USDC LP positions in three external functions:

  • openLp(...) — splits the Safe's USDC, swaps half to WETH on the pinned SwapRouter02,
    mints a Uniswap V3 LP NFT on the Safe.
  • closeLp(...) — harvests accrued fees → decreaseLiquidity → collect principal → burn →
    swap the WETH leg back to USDC, all module-mediated. NFT stays on the Safe throughout.
  • collectLp(...) — mid-position fee harvest; skims feeCollectBps to treasury,
    forwards the rest to the Safe.

Supply/borrow on a lending protocol (e.g. Fluid) and debt repayment are not handled by
this contract — the user runs those as separate Safe transactions. This contract is strictly
the LP-leg helper.

- Added UNISWAP_V3_NPM_ADDRESS and UNISWAP_V3_SWAP_ROUTER_ADDRESS to contractAddresses.ts.
- Updated hardhat.config.ts to set the EVM version to "cancun".
- Added a new deploy script command for Rate Hopper positions in package.json.
- Enhanced IUniswapV3Pool interface documentation with additional slot0 details.
_quoteSwapAmountOutMin(address(USDC), address(WETH), halfUsdc, swapFee, slippageBps);
bytes memory swapData = abi.encodeWithSelector(
EXACT_INPUT_SINGLE_SELECTOR,
ExactInputSingleParams({
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

At the moment, use Uniswap v3 for swaps, as it's the same as in the frontend/backend implementation.
let me know if you want to use others like Paraswap aggregator here

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

okay maybe rename the contract to RatehopperUniV3Positions.sol in that case

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

renamed to RatehopperUniV3Positions

…ebtManager

- Replaced instances of ISafeDebtManager with IProtocolRegistry in RateHopperPositions contract.
- Updated constructor and related functions to accept and utilize the new registry parameter.
- Modified deployment scripts and tests to reflect the change from SafeDebtManager to ProtocolRegistry, ensuring correct address handling and functionality.
@junta junta changed the title [WIP] Create the contracts for the openLp, collectLp and closeLp Create the contracts for the openLp, collectLp and closeLp May 22, 2026
Comment thread contracts/RatehopperUniV3Positions.sol
Comment thread contracts/RatehopperUniV3Positions.sol Outdated
Comment thread contracts/RateHopperPositions.sol Outdated
Comment thread contracts/RateHopperPositions.sol Outdated
junta added 3 commits May 22, 2026 17:28
- Introduced performanceFeeBps to manage performance fees on net profits.
- Updated PositionOpened and PositionClosed events to include initial and current value parameters.
- Implemented setPerformanceFeeBps function for owner to update performance fee, with validation against MAX_FEE_BPS.
- Added rescueToken function to recover ERC20 tokens sent to the contract.
- Removed ISafeDebtManager interface as it is no longer used.
…ValueUsd6

- Added currentValueUsd6 parameter to FeesCollected event for better tracking of collected fees' USDC-equivalent value.
- Updated _collectLp function to calculate the USDC value of collected token0 based on the Uniswap V3 pool's spot price, improving fee management accuracy.
@rrrrrrrrhh
Copy link
Copy Markdown
Collaborator

rrrrrrrrhh commented May 24, 2026

  1. I'm seeing
amount0Min: 0
amount1Min: 0

being used in a few places, can you pass this in into the params, in the UI we can query the state and ensure to use that a buffer that's close to the current ratio. For openLp():

  • Add parameters such as amount0Min, amount1Min, and possibly minLiquidity.
  • Derive them off-chain from a quote and Safe-approved signed intent.
  • Revert if minted liquidity or used amounts fall below expectations.

For closeLp():

  • Add amount0Min and amount1Min for decreaseLiquidity.
  • Use user/operator-supplied or oracle-bounded minimums.

@rrrrrrrrhh
Copy link
Copy Markdown
Collaborator

Issue: can we introduce MAX_SLIPPAGE_BPS = 300 // 3% and then use this as a check on openLp(), closeLp() and _quoteSwapAmountOutMin() and revert if it's higher than this to protect users

junta added 7 commits May 25, 2026 12:01
- Added PROTOCOL_REGISTRY_ADDRESS to contractAddresses.ts for canonical Base deployments.
- Updated RateHopperPositions contract to include exitBps parameter in closeLp function, allowing for partial or full liquidity removal.
- Introduced error handling for invalid exitBps values.
- Modified DeployRateHopperPositions module to use PROTOCOL_REGISTRY_ADDRESS as a fallback for the registry parameter.
- Updated tests to accommodate new exitBps functionality and ensure proper error handling.
- Renamed RateHopperPositions to RatehopperUniV3Positions across relevant files for consistency.
- Updated deployment script to reflect the new contract name.
- Adjusted comments and references in contractAddresses.ts and related interfaces to align with the new naming convention.
- Removed the deprecated RateHopperPositions contract and its associated tests.
…minPoolLiquidity

- Replaced Ownable with AccessControl for enhanced role management.
- Added minPoolLiquidity state variable to enforce minimum liquidity requirements for pools.
- Updated constructor to accept initial admin and timelock addresses, ensuring proper role assignments.
- Modified deployment scripts and tests to reflect changes in constructor parameters and role management.
- Enhanced error handling for unauthorized access to setter functions.
- Added detailed description of the RatehopperUniV3Positions module in README.md, outlining its functionality for managing Uniswap V3 LP positions.
- Updated environment variables section to include new parameters for deploying RatehopperUniV3Positions, including performance fee settings and timelock configurations.
- Refactored DeployRatehopperUniV3Positions module to clarify the deployment process for TimelockController and RatehopperUniV3Positions, allowing for reuse of existing timelocks.
- Expanded test coverage for performance fee management via TimelockController, ensuring proper access control and execution flow.
…lidation

- Removed redundant comments and clarified existing ones in the RatehopperUniV3Positions contract.
- Introduced a new error, InvalidSwapAmountOutMin, to enforce non-zero swap amount requirements.
- Updated tests to ensure proper handling of swapAmountOutMin, including checks for zero values to prevent slippage protection bypass.
- Adjusted test cases to reflect changes in function parameters, enhancing overall test coverage.
…recovery

- Removed unnecessary comments and clarified existing ones in the RatehopperUniV3Positions contract.
- Updated the constructor documentation to specify the hardcoded token pair requirements for WETH and USDC.
- Added a new test case for the rescueERC721 function to ensure proper handling of misdirected NFTs, including checks for zero addresses and access control.
- Enhanced overall test coverage for the NFT recovery functionality.
…clarity

- Clarified comments in the RatehopperUniV3Positions contract to specify references to NonfungiblePositionManager (NPM).
- Updated function documentation to ensure consistency in terminology and improve understanding of the contract's operations.
- Enhanced integration tests to reflect the updated contract logic, ensuring proper end-to-end functionality for opening and closing LP-backed Fluid debt positions.
@junta
Copy link
Copy Markdown
Collaborator Author

junta commented May 27, 2026

For closeLp():

  • Add amount0Min and amount1Min for decreaseLiquidity.
  • Use user/operator-supplied or oracle-bounded minimums.

Issue: can we introduce MAX_SLIPPAGE_BPS = 300 // 3% and then use this as a check on openLp(), closeLp() and _quoteSwapAmountOutMin() and revert if it's higher than this to protect users

agreed

Implemented both of the above

junta and others added 5 commits May 29, 2026 09:57
…V3Positions, and SafeDebtManager contracts

- Introduced a new error, OnlyTimelock, to enforce access restrictions for critical operations.
- Added onlyTimelockCriticalRole modifier to ensure only the timelock can execute critical functions, enhancing security.
- Updated setProtocolHandler functions in LeveragedPosition and SafeDebtManager to utilize the new modifier.
- Enhanced RatehopperUniV3Positions to include an immutable timelock address, ensuring proper role management and access control.
- Updated tests to validate timelock access restrictions and ensure proper functionality of critical role assignments.
- Updated import paths for safeAddress in multiple test files to use the new safeTestContext module.
- Removed redundant export of safeAddress from debtSwapBySafe, ensuring cleaner module dependencies.
- Enhanced overall organization of test files for better maintainability.
- Integrated TimelockControllerModule into DeployAll and DeployRatehopperUniV3Positions modules for improved code reuse and consistency.
- Updated deployment logic to allow for shared timelock management, enhancing efficiency and reducing redundancy.
- Clarified documentation regarding timelock deployment options and environment variable usage for better understanding.
…rUniV3Positions

- Introduced minPositionLiquidity state variable to enforce a minimum liquidity floor for LP positions, preventing dust-sized positions.
- Added new events and errors to handle updates and validations related to minPositionLiquidity.
- Updated openLp and closeLp functions to include expectedSwapOut parameter, enhancing swap protection by tying slippage to actual expected outputs.
- Enhanced tests to validate the new minPositionLiquidity functionality and ensure proper error handling for related conditions.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants