Skip to content
Open
Show file tree
Hide file tree
Changes from 15 commits
Commits
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
38 changes: 30 additions & 8 deletions sdks/universal-router-sdk/src/swapRouter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ export interface MigrateV3ToV4Options {
v4AddLiquidityOptions: V4AddLiquidityOptions
}

function isMint(options: V4AddLiquidityOptions): options is MintOptions {
return Object.keys(options).some((k) => k === 'recipient')
function isMigrate(options: V4AddLiquidityOptions): options is MintOptions {
return 'migrateOptions' in options && options.migrateOptions?.migrate === true
}

export abstract class SwapRouter {
Expand Down Expand Up @@ -87,6 +87,10 @@ export abstract class SwapRouter {
const v4PositionManagerAddress =
positionManagerOverride ?? CHAIN_TO_ADDRESSES_MAP[v4Pool.chainId as SupportedChainsType].v4PositionManagerAddress

const universalRouterAddress = UNIVERSAL_ROUTER_ADDRESS(
UniversalRouterVersion.V2_0,
options.inputPosition.pool.chainId as SupportedChainsType
)
// owner of the v3 nft must be the receiver of the v4 nft

// validate the parameters
Expand All @@ -110,8 +114,8 @@ export abstract class SwapRouter {
options.v3RemoveLiquidityOptions.collectOptions.recipient === v4PositionManagerAddress,
'RECIPIENT_NOT_POSITION_MANAGER'
)
invariant(isMint(options.v4AddLiquidityOptions), 'MINT_REQUIRED')
invariant(options.v4AddLiquidityOptions.migrate, 'MIGRATE_REQUIRED')
// Migration must be a mint operation, not an increase because the UR should not have permission to increase liquidity on a v4 position
invariant(isMigrate(options.v4AddLiquidityOptions), 'MIGRATE_REQUIRED')

const planner = new RoutePlanner()

Expand All @@ -132,10 +136,6 @@ export abstract class SwapRouter {
// add position permit to the universal router planner
if (options.v3RemoveLiquidityOptions.permit) {
// permit spender should be UR
const universalRouterAddress = UNIVERSAL_ROUTER_ADDRESS(
UniversalRouterVersion.V2_0,
options.inputPosition.pool.chainId as SupportedChainsType
)
invariant(universalRouterAddress == options.v3RemoveLiquidityOptions.permit.spender, 'INVALID_SPENDER')
// don't need to transfer it because v3posm uses isApprovedOrOwner()
encodeV3PositionPermit(planner, options.v3RemoveLiquidityOptions.permit, options.v3RemoveLiquidityOptions.tokenId)
Expand All @@ -162,6 +162,28 @@ export abstract class SwapRouter {
planner.addCommand(CommandType.V3_POSITION_MANAGER_CALL, [v3Call])
}

// if migrate options has a currency, require a batch permit
if (options.v4AddLiquidityOptions.migrateOptions?.neededCurrency) {
// need to permit the UR to spend your currency on permit2
if (options.v4AddLiquidityOptions.batchPermit) {
invariant(
options.v4AddLiquidityOptions.batchPermit.permitBatch.spender == universalRouterAddress,
'INVALID_SPENDER'
)
planner.addCommand(CommandType.PERMIT2_PERMIT_BATCH, [
Copy link
Contributor

Choose a reason for hiding this comment

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

its only ever going to be 1 currency i think? so using batch is unnecessary?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

permitBatch is already a param of v4AddLiquidityOptions so i figured i would just keep it instead of adding another one?

options.v4AddLiquidityOptions.batchPermit.permitBatch,
options.v4AddLiquidityOptions.batchPermit.signature,
])
}
planner.addCommand(CommandType.PERMIT2_TRANSFER_FROM, [
options.v4AddLiquidityOptions.migrateOptions.neededCurrency,
options.v3RemoveLiquidityOptions.collectOptions.recipient,
options.v4AddLiquidityOptions.migrateOptions.neededAmount,
])
// remove batchPermit so it doesn't get encoded again later
delete options.v4AddLiquidityOptions.batchPermit
}

// encode v4 mint
const v4AddParams = V4PositionManager.addCallParameters(options.outputPosition, options.v4AddLiquidityOptions)
// only modifyLiquidities can be called by the UniversalRouter
Expand Down
Loading
Loading