From ed44ce861fb2f0934ea126006f838d54708a3161 Mon Sep 17 00:00:00 2001 From: Roberto Cano <3525807+robercano@users.noreply.github.com> Date: Wed, 3 Apr 2024 15:37:49 +0200 Subject: [PATCH 01/24] feat: add position created event --- .../src/config/Config.ts | 2 + .../common/actions/PositionCreatedAction.ts | 31 ++++++ .../src/plugins/common/actions/index.ts | 1 + .../builders/PositionCreatedActionBuilder.ts | 20 ++++ .../src/plugins/common/builders/index.ts | 1 + .../src/plugins/maker/types/MakerPoolId.ts | 8 +- .../actions/PositionCreatedAction.spec.ts | 97 +++++++++++++++++++ sdk/sdk-common/src/simulation/Enums.ts | 7 ++ sdk/sdk-common/src/simulation/Steps.ts | 12 ++- sdk/sdk-e2e/tests/refinanceMakerSpark.test.ts | 28 +++++- .../reducer/newPositionEventReducer.ts | 15 +++ .../simulator-engine/reducer/stateReducers.ts | 2 + .../stepProcessor/newPositionEvent.ts | 11 +++ .../stepProcessor/stepOutputProcessors.ts | 2 + .../implementation/strategies/Refinance.ts | 23 +++++ .../src/interfaces/simulation.ts | 9 +- sdk/simulator-service/src/types/Types.ts | 8 ++ sdk/simulator-service/tests/simulator.test.ts | 19 +++- 18 files changed, 278 insertions(+), 18 deletions(-) create mode 100644 sdk/protocol-plugins/src/plugins/common/actions/PositionCreatedAction.ts create mode 100644 sdk/protocol-plugins/src/plugins/common/builders/PositionCreatedActionBuilder.ts create mode 100644 sdk/protocol-plugins/tests/actions/PositionCreatedAction.spec.ts create mode 100644 sdk/simulator-service/src/implementation/simulator-engine/reducer/newPositionEventReducer.ts create mode 100644 sdk/simulator-service/src/implementation/simulator-engine/stepProcessor/newPositionEvent.ts create mode 100644 sdk/simulator-service/src/types/Types.ts diff --git a/sdk/order-planner-service/src/config/Config.ts b/sdk/order-planner-service/src/config/Config.ts index d27177a395..03657eb3cc 100644 --- a/sdk/order-planner-service/src/config/Config.ts +++ b/sdk/order-planner-service/src/config/Config.ts @@ -4,6 +4,7 @@ import { DepositBorrowActionBuilder, FlashloanActionBuilder, PaybackWithdrawActionBuilder, + PositionCreatedActionBuilder, PullTokenActionBuilder, RepayFlashloanActionBuilder, ReturnFundsActionBuilder, @@ -18,4 +19,5 @@ export const ActionBuildersConfig: ActionBuildersMap = { [SimulationSteps.DepositBorrow]: DepositBorrowActionBuilder, [SimulationSteps.PaybackWithdraw]: PaybackWithdrawActionBuilder, [SimulationSteps.ReturnFunds]: ReturnFundsActionBuilder, + [SimulationSteps.NewPositionEvent]: PositionCreatedActionBuilder, } diff --git a/sdk/protocol-plugins/src/plugins/common/actions/PositionCreatedAction.ts b/sdk/protocol-plugins/src/plugins/common/actions/PositionCreatedAction.ts new file mode 100644 index 0000000000..5bbe4d3ddb --- /dev/null +++ b/sdk/protocol-plugins/src/plugins/common/actions/PositionCreatedAction.ts @@ -0,0 +1,31 @@ +import { ActionCall, BaseAction, InputSlotsMapping } from '@summerfi/protocol-plugins-common' +import { Position } from '@summerfi/sdk-common/common' +import { PositionType } from '@summerfi/sdk-common/simulation' + +export class PositionCreatedAction extends BaseAction { + public readonly config = { + name: 'PositionCreated', + version: 0, + parametersAbi: + '(string protocol, string positionType, address collateralToken, address debtToken)', + storageInputs: [], + storageOutputs: [], + } as const + + public encodeCall( + params: { position: Position; positionType: PositionType }, + paramsMapping?: InputSlotsMapping, + ): ActionCall { + return this._encodeCall({ + arguments: [ + { + protocol: params.position.pool.protocol.name, + positionType: params.positionType, + collateralToken: params.position.collateralAmount.token.address.value, + debtToken: params.position.debtAmount.token.address.value, + }, + ], + mapping: paramsMapping, + }) + } +} diff --git a/sdk/protocol-plugins/src/plugins/common/actions/index.ts b/sdk/protocol-plugins/src/plugins/common/actions/index.ts index 31831ac2eb..d996f9a68b 100644 --- a/sdk/protocol-plugins/src/plugins/common/actions/index.ts +++ b/sdk/protocol-plugins/src/plugins/common/actions/index.ts @@ -4,3 +4,4 @@ export { ReturnFundsAction } from './ReturnFundsAction' export { SendTokenAction } from './SendTokenAction' export { SetApprovalAction } from './SetApprovalAction' export { SwapAction } from './SwapAction' +export { PositionCreatedAction } from './PositionCreatedAction' diff --git a/sdk/protocol-plugins/src/plugins/common/builders/PositionCreatedActionBuilder.ts b/sdk/protocol-plugins/src/plugins/common/builders/PositionCreatedActionBuilder.ts new file mode 100644 index 0000000000..1372bea7ad --- /dev/null +++ b/sdk/protocol-plugins/src/plugins/common/builders/PositionCreatedActionBuilder.ts @@ -0,0 +1,20 @@ +import { steps } from '@summerfi/sdk-common/simulation' +import { ActionBuilder } from '@summerfi/protocol-plugins-common' +import { PositionCreatedAction } from '../actions/PositionCreatedAction' + +export const PositionCreatedActionBuilder: ActionBuilder = async ( + params, +): Promise => { + const { context, step } = params + + context.addActionCall({ + step: step, + action: new PositionCreatedAction(), + arguments: { + position: step.inputs.position, + positionType: step.inputs.positionType, + }, + connectedInputs: {}, + connectedOutputs: {}, + }) +} diff --git a/sdk/protocol-plugins/src/plugins/common/builders/index.ts b/sdk/protocol-plugins/src/plugins/common/builders/index.ts index 7667aca905..e2d8f5d9bc 100644 --- a/sdk/protocol-plugins/src/plugins/common/builders/index.ts +++ b/sdk/protocol-plugins/src/plugins/common/builders/index.ts @@ -9,3 +9,4 @@ export { } from './RepayFlashloanActionBuilder' export { ReturnFundsActionBuilder } from './ReturnFundsActionBuilder' export { SwapActionBuilder } from './SwapActionBuilder' +export { PositionCreatedActionBuilder } from './PositionCreatedActionBuilder' diff --git a/sdk/protocol-plugins/src/plugins/maker/types/MakerPoolId.ts b/sdk/protocol-plugins/src/plugins/maker/types/MakerPoolId.ts index 44dd35b377..2220ec6d28 100644 --- a/sdk/protocol-plugins/src/plugins/maker/types/MakerPoolId.ts +++ b/sdk/protocol-plugins/src/plugins/maker/types/MakerPoolId.ts @@ -1,12 +1,8 @@ -import { ChainInfo } from '@summerfi/sdk-common/common' -import { IPoolId, ProtocolName, isPoolId } from '@summerfi/sdk-common/protocols' +import { IPoolId, IProtocol, ProtocolName, isPoolId } from '@summerfi/sdk-common/protocols' import { ILKType } from '../enums/ILKType' export interface MakerPoolId extends IPoolId { - protocol: { - name: ProtocolName.Maker - chainInfo: ChainInfo - } + protocol: IProtocol ilkType: ILKType // TODO: vaultId does not belong in the poolId vaultId: string diff --git a/sdk/protocol-plugins/tests/actions/PositionCreatedAction.spec.ts b/sdk/protocol-plugins/tests/actions/PositionCreatedAction.spec.ts new file mode 100644 index 0000000000..389128e7b6 --- /dev/null +++ b/sdk/protocol-plugins/tests/actions/PositionCreatedAction.spec.ts @@ -0,0 +1,97 @@ +import { Address, Position, Token, TokenAmount } from '@summerfi/sdk-common/common' +import { decodeActionCalldata, getTargetHash } from '@summerfi/testing-utils' +import { PositionCreatedAction } from '../../src/plugins/common/actions/PositionCreatedAction' +import { IProtocol, PoolType, ProtocolName } from '@summerfi/sdk-common/protocols' +import { MakerPoolId } from '../../src/plugins/maker/types/MakerPoolId' +import { ILKType } from '../../src/plugins/maker' +import { PositionType } from '@summerfi/sdk-common/simulation' + +describe('PositionCreated Action', () => { + const action = new PositionCreatedAction() + const contractNameWithVersion = `${action.config.name}` + + const DAI = Token.createFrom({ + chainInfo: { + name: 'Mainnet', + chainId: 1, + }, + address: Address.createFromEthereum({ value: '0x6B175474E89094C44Da98b954EedeAC495271d0F' }), + decimals: 18, + name: 'Dai Stablecoin', + symbol: 'DAI', + }) + + const WETH = Token.createFrom({ + chainInfo: { + name: 'Mainnet', + chainId: 1, + }, + address: Address.createFromEthereum({ value: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2' }), + decimals: 18, + name: 'Wrapped Ether', + symbol: 'WETH', + }) + + const protocol: IProtocol = { + name: ProtocolName.Spark, + chainInfo: { + name: 'Mainnet', + chainId: 1, + }, + } + + const position = Position.createFrom({ + positionId: { + id: '0x123', + }, + pool: { + type: PoolType.Lending, + protocol: protocol, + poolId: { + protocol: protocol, + vaultId: '0x123', + ilkType: ILKType.ETH_A, + } as MakerPoolId, + }, + debtAmount: TokenAmount.createFrom({ + token: DAI, + amount: '100', + }), + collateralAmount: TokenAmount.createFrom({ + token: WETH, + amount: '100', + }), + }) + + it('should return the versioned name', () => { + expect(action.getVersionedName()).toBe(contractNameWithVersion) + }) + + it('should encode calls', async () => { + const call = action.encodeCall( + { + position: position, + positionType: PositionType.Refinance, + }, + [8, 9, 1, 3], + ) + + expect(call.targetHash).toBe(getTargetHash(action)) + + const actionDecodedArgs = decodeActionCalldata({ + action, + calldata: call.callData, + }) + + expect(actionDecodedArgs).toBeDefined() + expect(actionDecodedArgs?.args).toEqual([ + { + protocol: protocol.name, + positionType: PositionType.Refinance, + collateralToken: WETH.address.value, + debtToken: DAI.address.value, + }, + ]) + expect(actionDecodedArgs?.mapping).toEqual([8, 9, 1, 3]) + }) +}) diff --git a/sdk/sdk-common/src/simulation/Enums.ts b/sdk/sdk-common/src/simulation/Enums.ts index 9f6dab6096..025ffdf366 100644 --- a/sdk/sdk-common/src/simulation/Enums.ts +++ b/sdk/sdk-common/src/simulation/Enums.ts @@ -17,6 +17,7 @@ export enum SimulationSteps { PullToken = 'PullToken', ReturnFunds = 'ReturnFunds', RepayFlashloan = 'RepayFlashloan', + NewPositionEvent = 'NewPositionEvent', } export enum FlashloanProvider { @@ -28,3 +29,9 @@ export enum TokenTransferTargetType { PositionsManager = 1, StrategyExecutor = 0, } + +export enum PositionType { + Borrow = 'Borrow', + Multiply = 'Multiply', + Refinance = 'Refinance', +} diff --git a/sdk/sdk-common/src/simulation/Steps.ts b/sdk/sdk-common/src/simulation/Steps.ts index 1f45edfb53..e41a80c632 100644 --- a/sdk/sdk-common/src/simulation/Steps.ts +++ b/sdk/sdk-common/src/simulation/Steps.ts @@ -2,7 +2,7 @@ import { Percentage } from '../common/implementation/Percentage' import { Position } from '../common/implementation/Position' import { Token } from '../common/implementation/Token' import { TokenAmount } from '../common/implementation/TokenAmount' -import { FlashloanProvider, SimulationSteps, TokenTransferTargetType } from './Enums' +import { FlashloanProvider, PositionType, SimulationSteps, TokenTransferTargetType } from './Enums' import { ReferenceableField, ValueReference } from './ValueReference' export interface Step { @@ -79,6 +79,15 @@ export interface RepayFlashloan } > {} +export interface NewPositionEvent + extends Step< + SimulationSteps.NewPositionEvent, + { + position: Position + positionType: PositionType + } + > {} + export type Steps = | FlashloanStep | PullTokenStep @@ -87,3 +96,4 @@ export type Steps = | SwapStep | ReturnFunds | RepayFlashloan + | NewPositionEvent diff --git a/sdk/sdk-e2e/tests/refinanceMakerSpark.test.ts b/sdk/sdk-e2e/tests/refinanceMakerSpark.test.ts index ab788f5f64..8e96f3950e 100644 --- a/sdk/sdk-e2e/tests/refinanceMakerSpark.test.ts +++ b/sdk/sdk-e2e/tests/refinanceMakerSpark.test.ts @@ -14,7 +14,7 @@ import { ProtocolName, isLendingPool } from '@summerfi/sdk-common/protocols' import { makeSDK, type Chain, type User, Protocol } from '@summerfi/sdk-client' import { TokenSymbol } from '@summerfi/sdk-common/common/enums' import { IPositionsManager, IRefinanceParameters, Order } from '@summerfi/sdk-common/orders' -import { Simulation, SimulationType } from '@summerfi/sdk-common/simulation' +import { PositionType, Simulation, SimulationType } from '@summerfi/sdk-common/simulation' import { TransactionUtils } from './utils/TransactionUtils' import { decodeActionCalldata, @@ -31,6 +31,7 @@ import { FlashloanAction, SendTokenAction, SetApprovalAction, + PositionCreatedAction, } from '@summerfi/protocol-plugins/plugins/common' import { ILKType, @@ -48,9 +49,9 @@ import { jest.setTimeout(300000) const SDKAPiUrl = 'https://zmjmtfsocb.execute-api.us-east-1.amazonaws.com/api/sdk' -const TenderlyForkUrl = 'https://rpc.tenderly.co/fork/47a20a20-3aa1-4d21-afd7-6a230b12a0cc' +const TenderlyForkUrl = 'https://rpc.tenderly.co/fork/6bc5cd6d-e504-43aa-bea9-82f6b745239f' -describe.skip('Refinance Maker Spark | SDK', () => { +describe('Refinance Maker Spark | SDK', () => { it('should allow refinance Maker -> Spark with same pair', async () => { // SDK const sdk = makeSDK({ apiURL: SDKAPiUrl }) @@ -173,7 +174,7 @@ describe.skip('Refinance Maker Spark | SDK', () => { expect(refinanceSimulation.sourcePosition?.positionId).toEqual(makerPosition.positionId) expect(refinanceSimulation.targetPosition.pool.poolId).toEqual(sparkPool.poolId) - expect(refinanceSimulation.steps.length).toBe(4) + expect(refinanceSimulation.steps.length).toBe(5) const refinanceOrder: Maybe = await user.newOrder({ positionsManager: { @@ -218,7 +219,7 @@ describe.skip('Refinance Maker Spark | SDK', () => { assert(strategyExecutorParams, 'Cannot decode Strategy Executor calldata') expect(strategyExecutorParams.strategyName).toEqual(strategyName) - expect(strategyExecutorParams.actionCalls.length).toEqual(1) + expect(strategyExecutorParams.actionCalls.length).toEqual(2) // Decode Flashloan action const flashloanParams = decodeActionCalldata({ @@ -342,6 +343,23 @@ describe.skip('Refinance Maker Spark | SDK', () => { expect(sendTokenAction.args[0].to).toBe(strategyExecutorAddress.value) expect(sendTokenAction.args[0].amount).toBe(BigInt(flashloanAmount.toBaseUnit())) + // Decode Position Created event action + const positionCreatedParams = decodeActionCalldata({ + action: new PositionCreatedAction(), + calldata: strategyExecutorParams.actionCalls[1].callData, + }) + + assert(positionCreatedParams, 'Cannot decode Position Created action calldata') + + expect(positionCreatedParams.args[0].protocol).toBe(targetPosition.pool.protocol.name) + expect(positionCreatedParams.args[0].positionType).toBe(PositionType.Refinance) + expect(positionCreatedParams.args[0].collateralToken).toBe( + targetPosition.collateralAmount.token.address.value, + ) + expect(positionCreatedParams.args[0].debtToken).toBe( + targetPosition.debtAmount.token.address.value, + ) + // Send transaction console.log('Sending transaction...') diff --git a/sdk/simulator-service/src/implementation/simulator-engine/reducer/newPositionEventReducer.ts b/sdk/simulator-service/src/implementation/simulator-engine/reducer/newPositionEventReducer.ts new file mode 100644 index 0000000000..e616c916f2 --- /dev/null +++ b/sdk/simulator-service/src/implementation/simulator-engine/reducer/newPositionEventReducer.ts @@ -0,0 +1,15 @@ +import { steps } from '@summerfi/sdk-common/simulation' +import { SimulationState } from '../../../interfaces/simulation' + +export function newPositionEventReducer( + step: steps.NewPositionEvent, + state: SimulationState, +): SimulationState { + return { + ...state, + steps: { + ...state.steps, + [step.name]: step, + }, + } +} diff --git a/sdk/simulator-service/src/implementation/simulator-engine/reducer/stateReducers.ts b/sdk/simulator-service/src/implementation/simulator-engine/reducer/stateReducers.ts index 3630f2b75a..3c7eaa5c26 100644 --- a/sdk/simulator-service/src/implementation/simulator-engine/reducer/stateReducers.ts +++ b/sdk/simulator-service/src/implementation/simulator-engine/reducer/stateReducers.ts @@ -8,6 +8,7 @@ import { swapReducer } from './swapReducer' import { returnFundsReducer } from './returnFundsReducer' import { repayFlashloanReducer } from './repayFlashloanReducer' import { pullTokenReducer } from './pullTokenReducer' +import { newPositionEventReducer } from './newPositionEventReducer' const stateReducers: StateReducers = { [SimulationSteps.Flashloan]: flashloanReducer, @@ -17,6 +18,7 @@ const stateReducers: StateReducers = { [SimulationSteps.ReturnFunds]: returnFundsReducer, [SimulationSteps.RepayFlashloan]: repayFlashloanReducer, [SimulationSteps.PullToken]: pullTokenReducer, + [SimulationSteps.NewPositionEvent]: newPositionEventReducer, } export function stateReducer(step: steps.Steps, state: SimulationState): SimulationState { diff --git a/sdk/simulator-service/src/implementation/simulator-engine/stepProcessor/newPositionEvent.ts b/sdk/simulator-service/src/implementation/simulator-engine/stepProcessor/newPositionEvent.ts new file mode 100644 index 0000000000..8817014f6f --- /dev/null +++ b/sdk/simulator-service/src/implementation/simulator-engine/stepProcessor/newPositionEvent.ts @@ -0,0 +1,11 @@ +import { steps } from '@summerfi/sdk-common/simulation' +import type { StepOutputProcessor } from '../../../interfaces/steps' + +export const newPositionEventProcessor: StepOutputProcessor = async ( + step, +) => { + return { + ...step, + outputs: undefined, + } +} diff --git a/sdk/simulator-service/src/implementation/simulator-engine/stepProcessor/stepOutputProcessors.ts b/sdk/simulator-service/src/implementation/simulator-engine/stepProcessor/stepOutputProcessors.ts index 9637a00dff..9f16f2bf39 100644 --- a/sdk/simulator-service/src/implementation/simulator-engine/stepProcessor/stepOutputProcessors.ts +++ b/sdk/simulator-service/src/implementation/simulator-engine/stepProcessor/stepOutputProcessors.ts @@ -11,6 +11,7 @@ import { paybackWithdrawOutputProcessor } from './paybackWithdrawOutputProcessor import { swapOutputProcessor } from './swapOutputProcessor' import { returnFundsOutputProcessor } from './returnFundsOutputProcessor' import { repayFlashloanOutputProcessor } from './repayFlashloanOutputProcessor' +import { newPositionEventProcessor } from './newPositionEvent' const stepOutputProcessors: StepOutputProcessors = { [SimulationSteps.Flashloan]: flashloanOutputProcessor, @@ -20,6 +21,7 @@ const stepOutputProcessors: StepOutputProcessors = { [SimulationSteps.ReturnFunds]: returnFundsOutputProcessor, [SimulationSteps.RepayFlashloan]: repayFlashloanOutputProcessor, [SimulationSteps.PullToken]: pullTokenOutputProcessor, + [SimulationSteps.NewPositionEvent]: newPositionEventProcessor, } export async function processStepOutput(step: StepsWithoutOutputs): Promise { diff --git a/sdk/simulator-service/src/implementation/strategies/Refinance.ts b/sdk/simulator-service/src/implementation/strategies/Refinance.ts index 92c3874067..297903c849 100644 --- a/sdk/simulator-service/src/implementation/strategies/Refinance.ts +++ b/sdk/simulator-service/src/implementation/strategies/Refinance.ts @@ -1,5 +1,6 @@ import { FlashloanProvider, + PositionType, Simulation, SimulationSteps, SimulationType, @@ -31,6 +32,10 @@ export const refinanceStrategy = makeStrategy([ step: SimulationSteps.RepayFlashloan, optional: false, }, + { + step: SimulationSteps.NewPositionEvent, + optional: false, + }, ]) // TODO move those interfaces to more appropriate place @@ -111,6 +116,24 @@ export async function refinaceLendingToLending( amount: flashloanAmount, }, })) + .next(async (ctx) => { + // TODO: we should have a way to get the target position more easily and realiably, + const targetPosition = Object.values(ctx.state.positions).find( + (p) => p.pool.protocol === targetPool.protocol, + ) + if (!targetPosition) { + throw new Error('Target position not found') + } + + return { + name: 'NewPositionEvent', + type: SimulationSteps.NewPositionEvent, + inputs: { + position: targetPosition, + positionType: PositionType.Refinance, + }, + } + }) .run() // TODO: I think simulation should return the simulation position as a preperty targetPosition for easy discoverability diff --git a/sdk/simulator-service/src/interfaces/simulation.ts b/sdk/simulator-service/src/interfaces/simulation.ts index 3346eaceae..b602cbb6aa 100644 --- a/sdk/simulator-service/src/interfaces/simulation.ts +++ b/sdk/simulator-service/src/interfaces/simulation.ts @@ -1,8 +1,7 @@ -import type { steps } from '@summerfi/sdk-common/simulation' -import type { TokenAmount, Position } from '@summerfi/sdk-common/common' +import { BalancesRecord, PositionsRecord, StepsRecord } from '../types/Types' export interface SimulationState { - balances: Record - positions: Record - steps: Record + balances: BalancesRecord + positions: PositionsRecord + steps: StepsRecord } diff --git a/sdk/simulator-service/src/types/Types.ts b/sdk/simulator-service/src/types/Types.ts new file mode 100644 index 0000000000..3404d06936 --- /dev/null +++ b/sdk/simulator-service/src/types/Types.ts @@ -0,0 +1,8 @@ +import { AddressValue, Position, TokenAmount } from '@summerfi/sdk-common/common' +import { steps } from '@summerfi/sdk-common/simulation' + +export type StepName = string + +export type BalancesRecord = Record +export type PositionsRecord = Record +export type StepsRecord = Record diff --git a/sdk/simulator-service/tests/simulator.test.ts b/sdk/simulator-service/tests/simulator.test.ts index c58d9a5add..db581567e5 100644 --- a/sdk/simulator-service/tests/simulator.test.ts +++ b/sdk/simulator-service/tests/simulator.test.ts @@ -1,6 +1,12 @@ import { Percentage } from '@summerfi/sdk-common/common' import { refinaceLendingToLending } from '../src/implementation/strategies' -import { Simulation, SimulationSteps, SimulationType } from '@summerfi/sdk-common/simulation' +import { + PositionType, + Simulation, + SimulationSteps, + SimulationType, + steps, +} from '@summerfi/sdk-common/simulation' import { otherTestCollateral, otherTestDebt, @@ -9,6 +15,7 @@ import { testTargetLendingPoolRequiredSwaps, } from './mocks/testSourcePosition' import { mockRefinanceContext } from './mocks/contextMock' +import assert from 'assert' describe('Refinance', () => { describe('to the position with the same collateral and debt (no swaps)', () => { @@ -54,6 +61,16 @@ describe('Refinance', () => { expect(targetPosition.positionId).toBeDefined() }) + + it('should include a new position event step', async () => { + const newPositionStep = simulation.steps.find( + (step) => step.type === SimulationSteps.NewPositionEvent, + ) as steps.NewPositionEvent + + assert(newPositionStep, 'New position event step not found') + expect(newPositionStep.inputs.position).toEqual(simulation.targetPosition) + expect(newPositionStep.inputs.positionType).toEqual(PositionType.Refinance) + }) }) describe.skip('to the position with the different collateral and debt (with swaps)', () => { From 25ba44dcf4d6ffc026a8da48cd4089528cfafb1d Mon Sep 17 00:00:00 2001 From: Roberto Cano <3525807+robercano@users.noreply.github.com> Date: Wed, 3 Apr 2024 17:30:45 +0200 Subject: [PATCH 02/24] feat: re-add refinance same pair simulation --- sdk/sdk-e2e/tests/refinanceMakerSpark.test.ts | 4 +- .../src/handlers/getRefinanceSimulation.ts | 4 +- .../reducer/newPositionEventReducer.ts | 6 +- .../src/implementation/utils/BalanceUtils.ts | 15 +-- .../strategies/{refinance => common}/Types.ts | 0 .../src/strategies/common/index.ts | 1 + sdk/simulator-service/src/strategies/index.ts | 4 +- .../src/strategies/refinance/index.ts | 3 - .../RefinanceLendingToLendingAnyPair.ts} | 8 +- .../Strategy.ts | 2 +- .../src/strategies/refinanceAnyPair/index.ts | 2 + .../RefinanceLendingToLendingSamePair.ts | 122 ++++++++++++++++++ .../strategies/refinanceSamePair/Strategy.ts | 25 ++++ .../src/strategies/refinanceSamePair/index.ts | 2 + sdk/simulator-service/tests/simulator.test.ts | 9 +- .../oneinch/OneInchSwapProvider.ts | 2 +- 16 files changed, 180 insertions(+), 29 deletions(-) rename sdk/simulator-service/src/strategies/{refinance => common}/Types.ts (100%) create mode 100644 sdk/simulator-service/src/strategies/common/index.ts delete mode 100644 sdk/simulator-service/src/strategies/refinance/index.ts rename sdk/simulator-service/src/strategies/{refinance/RefinanceLendingToLending.ts => refinanceAnyPair/RefinanceLendingToLendingAnyPair.ts} (95%) rename sdk/simulator-service/src/strategies/{refinance => refinanceAnyPair}/Strategy.ts (92%) create mode 100644 sdk/simulator-service/src/strategies/refinanceAnyPair/index.ts create mode 100644 sdk/simulator-service/src/strategies/refinanceSamePair/RefinanceLendingToLendingSamePair.ts create mode 100644 sdk/simulator-service/src/strategies/refinanceSamePair/Strategy.ts create mode 100644 sdk/simulator-service/src/strategies/refinanceSamePair/index.ts diff --git a/sdk/sdk-e2e/tests/refinanceMakerSpark.test.ts b/sdk/sdk-e2e/tests/refinanceMakerSpark.test.ts index 289146f1e5..5502270d4e 100644 --- a/sdk/sdk-e2e/tests/refinanceMakerSpark.test.ts +++ b/sdk/sdk-e2e/tests/refinanceMakerSpark.test.ts @@ -49,9 +49,9 @@ import { jest.setTimeout(300000) const SDKAPiUrl = 'https://zmjmtfsocb.execute-api.us-east-1.amazonaws.com/api/sdk' -const TenderlyForkUrl = 'https://rpc.tenderly.co/fork/6bc5cd6d-e504-43aa-bea9-82f6b745239f' +const TenderlyForkUrl = 'https://rpc.tenderly.co/fork/a1520da1-6f8c-426a-b34a-0904b1a934bc' -describe.skip('Refinance Maker Spark | SDK', () => { +describe('Refinance Maker Spark | SDK', () => { it('should allow refinance Maker -> Spark with same pair', async () => { // SDK const sdk = makeSDK({ apiURL: SDKAPiUrl }) diff --git a/sdk/sdk-server/src/handlers/getRefinanceSimulation.ts b/sdk/sdk-server/src/handlers/getRefinanceSimulation.ts index 21a8f49a4b..0c763d1ab6 100644 --- a/sdk/sdk-server/src/handlers/getRefinanceSimulation.ts +++ b/sdk/sdk-server/src/handlers/getRefinanceSimulation.ts @@ -2,7 +2,7 @@ import { z } from 'zod' import { Percentage } from '@summerfi/sdk-common/common' import type { ISimulation, SimulationType } from '@summerfi/sdk-common/simulation' import { - refinanceLendingToLending, + refinanceLendingToLendingSamePair, type IRefinanceDependencies, } from '@summerfi/simulator-service/strategies' import type { IRefinanceParameters } from '@summerfi/sdk-common/orders' @@ -22,5 +22,5 @@ export const getRefinanceSimulation = publicProcedure getSummerFee: () => Percentage.createFrom({ value: 0 }), } - return await refinanceLendingToLending(args, dependencies) + return await refinanceLendingToLendingSamePair(args, dependencies) }) diff --git a/sdk/simulator-service/src/implementation/simulator-engine/reducer/newPositionEventReducer.ts b/sdk/simulator-service/src/implementation/simulator-engine/reducer/newPositionEventReducer.ts index e616c916f2..9606b40429 100644 --- a/sdk/simulator-service/src/implementation/simulator-engine/reducer/newPositionEventReducer.ts +++ b/sdk/simulator-service/src/implementation/simulator-engine/reducer/newPositionEventReducer.ts @@ -1,10 +1,10 @@ import { steps } from '@summerfi/sdk-common/simulation' -import { SimulationState } from '../../../interfaces/simulation' +import { ISimulationState } from '../../../interfaces/simulation' export function newPositionEventReducer( step: steps.NewPositionEvent, - state: SimulationState, -): SimulationState { + state: ISimulationState, +): ISimulationState { return { ...state, steps: { diff --git a/sdk/simulator-service/src/implementation/utils/BalanceUtils.ts b/sdk/simulator-service/src/implementation/utils/BalanceUtils.ts index 6a80c95fd9..c87d075227 100644 --- a/sdk/simulator-service/src/implementation/utils/BalanceUtils.ts +++ b/sdk/simulator-service/src/implementation/utils/BalanceUtils.ts @@ -1,13 +1,13 @@ import { TokenAmount, type Token } from '@summerfi/sdk-common/common' +import { BalancesRecord } from '../../types/Types' -export function getTokenBalance(token: Token, balances: Record): TokenAmount { +// TODO: This should be transformed into a proper class, as we are passing the balances record +// TODO: to each call +export function getTokenBalance(token: Token, balances: BalancesRecord): TokenAmount { return balances[token.address.value] || TokenAmount.createFrom({ amount: '0', token }) } -export function addBalance( - amount: TokenAmount, - balance: Record, -): Record { +export function addBalance(amount: TokenAmount, balance: BalancesRecord): BalancesRecord { return { ...balance, [amount.token.address.value]: balance[amount.token.address.value] @@ -16,10 +16,7 @@ export function addBalance( } } -export function subtractBalance( - amount: TokenAmount, - balance: Record, -): Record { +export function subtractBalance(amount: TokenAmount, balance: BalancesRecord): BalancesRecord { return { ...balance, [amount.token.address.value]: balance[amount.token.address.value] diff --git a/sdk/simulator-service/src/strategies/refinance/Types.ts b/sdk/simulator-service/src/strategies/common/Types.ts similarity index 100% rename from sdk/simulator-service/src/strategies/refinance/Types.ts rename to sdk/simulator-service/src/strategies/common/Types.ts diff --git a/sdk/simulator-service/src/strategies/common/index.ts b/sdk/simulator-service/src/strategies/common/index.ts new file mode 100644 index 0000000000..cf701220bd --- /dev/null +++ b/sdk/simulator-service/src/strategies/common/index.ts @@ -0,0 +1 @@ +export * from './Types' diff --git a/sdk/simulator-service/src/strategies/index.ts b/sdk/simulator-service/src/strategies/index.ts index 0ee38d8f24..3c006d5c2d 100644 --- a/sdk/simulator-service/src/strategies/index.ts +++ b/sdk/simulator-service/src/strategies/index.ts @@ -1 +1,3 @@ -export * from './refinance' +export * from './refinanceSamePair' +export * from './refinanceAnyPair' +export * from './common' diff --git a/sdk/simulator-service/src/strategies/refinance/index.ts b/sdk/simulator-service/src/strategies/refinance/index.ts deleted file mode 100644 index 3b6c974181..0000000000 --- a/sdk/simulator-service/src/strategies/refinance/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export * from './RefinanceLendingToLending' -export * from './Strategy' -export * from './Types' diff --git a/sdk/simulator-service/src/strategies/refinance/RefinanceLendingToLending.ts b/sdk/simulator-service/src/strategies/refinanceAnyPair/RefinanceLendingToLendingAnyPair.ts similarity index 95% rename from sdk/simulator-service/src/strategies/refinance/RefinanceLendingToLending.ts rename to sdk/simulator-service/src/strategies/refinanceAnyPair/RefinanceLendingToLendingAnyPair.ts index c98e9c56db..8868d473b1 100644 --- a/sdk/simulator-service/src/strategies/refinance/RefinanceLendingToLending.ts +++ b/sdk/simulator-service/src/strategies/refinanceAnyPair/RefinanceLendingToLendingAnyPair.ts @@ -12,10 +12,10 @@ import { newEmptyPositionFromPool } from '@summerfi/sdk-common/common/utils' import { IRefinanceParameters } from '@summerfi/sdk-common/orders' import { isLendingPool } from '@summerfi/sdk-common/protocols' import { getReferencedValue } from '../../implementation/utils' -import { refinanceLendingToLendingStrategy } from './Strategy' -import { type IRefinanceDependencies } from './Types' +import { refinanceLendingToLendingAnyPairStrategy } from './Strategy' +import { type IRefinanceDependencies } from '../common/Types' -export async function refinanceLendingToLending( +export async function refinanceLendingToLendingAnyPair( args: IRefinanceParameters, dependencies: IRefinanceDependencies, ): Promise> { @@ -33,7 +33,7 @@ export async function refinanceLendingToLending( const FLASHLOAN_MARGIN = 1.001 const flashloanAmount = position.debtAmount.multiply(FLASHLOAN_MARGIN) - const simulator = Simulator.create(refinanceLendingToLendingStrategy) + const simulator = Simulator.create(refinanceLendingToLendingAnyPairStrategy) const targetTokenConfig = targetPool.collaterals.get({ token: position.collateralAmount.token }) if (!targetTokenConfig) { diff --git a/sdk/simulator-service/src/strategies/refinance/Strategy.ts b/sdk/simulator-service/src/strategies/refinanceAnyPair/Strategy.ts similarity index 92% rename from sdk/simulator-service/src/strategies/refinance/Strategy.ts rename to sdk/simulator-service/src/strategies/refinanceAnyPair/Strategy.ts index 051076fb7e..c0887bd188 100644 --- a/sdk/simulator-service/src/strategies/refinance/Strategy.ts +++ b/sdk/simulator-service/src/strategies/refinanceAnyPair/Strategy.ts @@ -1,7 +1,7 @@ import { SimulationSteps } from '@summerfi/sdk-common/simulation' import { makeStrategy } from '../../implementation/utils' -export const refinanceLendingToLendingStrategy = makeStrategy([ +export const refinanceLendingToLendingAnyPairStrategy = makeStrategy([ { step: SimulationSteps.Flashloan, optional: false, diff --git a/sdk/simulator-service/src/strategies/refinanceAnyPair/index.ts b/sdk/simulator-service/src/strategies/refinanceAnyPair/index.ts new file mode 100644 index 0000000000..6ea863f32a --- /dev/null +++ b/sdk/simulator-service/src/strategies/refinanceAnyPair/index.ts @@ -0,0 +1,2 @@ +export * from './RefinanceLendingToLendingAnyPair' +export * from './Strategy' diff --git a/sdk/simulator-service/src/strategies/refinanceSamePair/RefinanceLendingToLendingSamePair.ts b/sdk/simulator-service/src/strategies/refinanceSamePair/RefinanceLendingToLendingSamePair.ts new file mode 100644 index 0000000000..2df3aa3089 --- /dev/null +++ b/sdk/simulator-service/src/strategies/refinanceSamePair/RefinanceLendingToLendingSamePair.ts @@ -0,0 +1,122 @@ +import { + FlashloanProvider, + ISimulation, + PositionType, + SimulationSteps, + SimulationType, + TokenTransferTargetType, +} from '@summerfi/sdk-common/simulation' +import { Simulator } from '../../implementation/simulator-engine' +import { Position, TokenAmount } from '@summerfi/sdk-common/common' +import { newEmptyPositionFromPool } from '@summerfi/sdk-common/common/utils' +import { IRefinanceParameters } from '@summerfi/sdk-common/orders' +import { isLendingPool } from '@summerfi/sdk-common/protocols' +import { refinanceLendingToLendingSamePairStrategy } from './Strategy' +import { type IRefinanceDependencies } from '../common/Types' + +export async function refinanceLendingToLendingSamePair( + args: IRefinanceParameters, + dependencies: IRefinanceDependencies, +): Promise> { + // args validation + if (!isLendingPool(args.targetPool)) { + throw new Error('Target pool is not a lending pool') + } + + const position = Position.createFrom(args.position) + const targetPool = await dependencies.protocolManager.getPool(args.targetPool.poolId) + + if (!isLendingPool(targetPool)) { + throw new Error('Target pool is not a lending pool') + } + + const FLASHLOAN_MARGIN = 1.001 + const flashloanAmount = position.debtAmount.multiply(FLASHLOAN_MARGIN) + const simulator = Simulator.create(refinanceLendingToLendingSamePairStrategy) + + const targetTokenConfig = targetPool.collaterals.get({ token: position.collateralAmount.token }) + if (!targetTokenConfig) { + throw new Error('Target token not found in pool') + } + + // TODO: read debt amount from chain (special step: ReadDebtAmount) + // TODO: the swap quote should also include the summer fee, in this case we need to know when we are taking the fee, + // before or after the swap, it influences actual call to oneInch api + const simulation = await simulator + .next(async () => ({ + name: 'Flashloan', + type: SimulationSteps.Flashloan, + inputs: { + amount: flashloanAmount, + provider: FlashloanProvider.Maker, + }, + })) + .next(async () => ({ + name: 'PaybackWithdrawFromSource', + type: SimulationSteps.PaybackWithdraw, + inputs: { + paybackAmount: TokenAmount.createFrom({ + amount: Number.MAX_SAFE_INTEGER.toString(), + token: position.debtAmount.token, + }), + withdrawAmount: position.collateralAmount, + position: position, + }, + })) + .next(async (ctx) => ({ + name: 'DepositBorrowToTarget', + type: SimulationSteps.DepositBorrow, + inputs: { + depositAmount: ctx.getReference(['PaybackWithdrawFromSource', 'withdrawAmount']), + borrowAmount: position.debtAmount, // TODO figure the debt amount + position: newEmptyPositionFromPool( + targetPool, + position.debtAmount.token, + position.collateralAmount.token, + ), + borrowTargetType: TokenTransferTargetType.PositionsManager, + }, + })) + .next(async () => ({ + name: 'RepayFlashloan', + type: SimulationSteps.RepayFlashloan, + inputs: { + amount: flashloanAmount, + }, + })) + .next(async (ctx) => { + // TODO: we should have a way to get the target position more easily and realiably, + const targetPosition = Object.values(ctx.state.positions).find( + (p) => p.pool.protocol === targetPool.protocol, + ) + if (!targetPosition) { + throw new Error('Target position not found') + } + + return { + name: 'NewPositionEvent', + type: SimulationSteps.NewPositionEvent, + inputs: { + position: targetPosition, + positionType: PositionType.Refinance, + }, + } + }) + .run() + + const targetPosition = Object.values(simulation.positions).find( + (p) => p.pool.protocol === targetPool.protocol, + ) + + if (!targetPosition) { + throw new Error('Target position not found') + } + + return { + simulationType: SimulationType.Refinance, + sourcePosition: position, + targetPosition, + swaps: Object.values(simulation.swaps), + steps: Object.values(simulation.steps), + } as ISimulation +} diff --git a/sdk/simulator-service/src/strategies/refinanceSamePair/Strategy.ts b/sdk/simulator-service/src/strategies/refinanceSamePair/Strategy.ts new file mode 100644 index 0000000000..4b8d6c9896 --- /dev/null +++ b/sdk/simulator-service/src/strategies/refinanceSamePair/Strategy.ts @@ -0,0 +1,25 @@ +import { SimulationSteps } from '@summerfi/sdk-common/simulation' +import { makeStrategy } from '../../implementation/utils' + +export const refinanceLendingToLendingSamePairStrategy = makeStrategy([ + { + step: SimulationSteps.Flashloan, + optional: false, + }, + { + step: SimulationSteps.PaybackWithdraw, + optional: false, + }, + { + step: SimulationSteps.DepositBorrow, + optional: false, + }, + { + step: SimulationSteps.RepayFlashloan, + optional: false, + }, + { + step: SimulationSteps.NewPositionEvent, + optional: false, + }, +]) diff --git a/sdk/simulator-service/src/strategies/refinanceSamePair/index.ts b/sdk/simulator-service/src/strategies/refinanceSamePair/index.ts new file mode 100644 index 0000000000..df1f26236a --- /dev/null +++ b/sdk/simulator-service/src/strategies/refinanceSamePair/index.ts @@ -0,0 +1,2 @@ +export * from './RefinanceLendingToLendingSamePair' +export * from './Strategy' diff --git a/sdk/simulator-service/tests/simulator.test.ts b/sdk/simulator-service/tests/simulator.test.ts index 3f2b576954..5c224b6697 100644 --- a/sdk/simulator-service/tests/simulator.test.ts +++ b/sdk/simulator-service/tests/simulator.test.ts @@ -6,7 +6,10 @@ import { SimulationType, steps, } from '@summerfi/sdk-common/simulation' -import { refinanceLendingToLending } from '../src/strategies' +import { + refinanceLendingToLendingAnyPair, + refinanceLendingToLendingSamePair, +} from '../src/strategies' import { otherTestCollateral, otherTestDebt, @@ -21,7 +24,7 @@ describe('Refinance', () => { describe('to the position with the same collateral and debt (no swaps)', () => { let simulation: ISimulation beforeAll(async () => { - simulation = await refinanceLendingToLending( + simulation = await refinanceLendingToLendingSamePair( { position: testSourcePosition, targetPool: testTargetLendingPool, @@ -76,7 +79,7 @@ describe('Refinance', () => { describe.skip('to the position with the different collateral and debt (with swaps)', () => { let simulation: ISimulation beforeAll(async () => { - simulation = await refinanceLendingToLending( + simulation = await refinanceLendingToLendingAnyPair( { position: testSourcePosition, targetPool: testTargetLendingPoolRequiredSwaps, diff --git a/sdk/swap-service/src/implementation/oneinch/OneInchSwapProvider.ts b/sdk/swap-service/src/implementation/oneinch/OneInchSwapProvider.ts index 13441caaed..50f9e1b49b 100644 --- a/sdk/swap-service/src/implementation/oneinch/OneInchSwapProvider.ts +++ b/sdk/swap-service/src/implementation/oneinch/OneInchSwapProvider.ts @@ -103,7 +103,7 @@ export class OneInchSwapProvider implements ISwapProvider { if (!(response.status === 200 && response.statusText === 'OK')) { throw new Error( - `Error performing 1inch swap quote request ${swapUrl}: ${await response.body}`, + `Error [${response.statusText}] performing 1inch swap quote request ${swapUrl}: ${JSON.stringify(await response.body)}`, ) } From 5e407832babfdaa2bdf899b843c59f6b954b47de Mon Sep 17 00:00:00 2001 From: Roberto Cano <3525807+robercano@users.noreply.github.com> Date: Wed, 3 Apr 2024 17:39:46 +0200 Subject: [PATCH 03/24] chore: disable refinance test --- sdk/sdk-e2e/tests/refinanceMakerSpark.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sdk/sdk-e2e/tests/refinanceMakerSpark.test.ts b/sdk/sdk-e2e/tests/refinanceMakerSpark.test.ts index 5502270d4e..5868134dae 100644 --- a/sdk/sdk-e2e/tests/refinanceMakerSpark.test.ts +++ b/sdk/sdk-e2e/tests/refinanceMakerSpark.test.ts @@ -49,9 +49,9 @@ import { jest.setTimeout(300000) const SDKAPiUrl = 'https://zmjmtfsocb.execute-api.us-east-1.amazonaws.com/api/sdk' -const TenderlyForkUrl = 'https://rpc.tenderly.co/fork/a1520da1-6f8c-426a-b34a-0904b1a934bc' +const TenderlyForkUrl = 'https://rpc.tenderly.co/fork/50e01944-8635-4d67-9569-004d72113328' -describe('Refinance Maker Spark | SDK', () => { +describe.skip('Refinance Maker Spark | SDK', () => { it('should allow refinance Maker -> Spark with same pair', async () => { // SDK const sdk = makeSDK({ apiURL: SDKAPiUrl }) From 07147b5f8308d7f137bb58acdbf3814c12be0014 Mon Sep 17 00:00:00 2001 From: Roberto Cano <3525807+robercano@users.noreply.github.com> Date: Wed, 3 Apr 2024 18:10:23 +0200 Subject: [PATCH 04/24] fix: refinance swap parameters --- .../refinanceAnyPair/RefinanceLendingToLendingAnyPair.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sdk/simulator-service/src/strategies/refinanceAnyPair/RefinanceLendingToLendingAnyPair.ts b/sdk/simulator-service/src/strategies/refinanceAnyPair/RefinanceLendingToLendingAnyPair.ts index 8868d473b1..d7d0a327b4 100644 --- a/sdk/simulator-service/src/strategies/refinanceAnyPair/RefinanceLendingToLendingAnyPair.ts +++ b/sdk/simulator-service/src/strategies/refinanceAnyPair/RefinanceLendingToLendingAnyPair.ts @@ -78,11 +78,11 @@ export async function refinanceLendingToLendingAnyPair( chainInfo: position.pool.protocol.chainInfo, // TODO: Properly implement swaps fromAmount: position.collateralAmount, - toToken: collateralConfig!.token, + toToken: debtConfig!.token, })), ...(await dependencies.swapManager.getSpotPrices({ chainInfo: position.pool.protocol.chainInfo, - tokens: [collateralConfig!.token, collateralConfig!.token], + tokens: [collateralConfig!.token, debtConfig!.token], })), slippage: Percentage.createFrom({ value: args.slippage.value }), fee: dependencies.getSummerFee(), @@ -113,7 +113,7 @@ export async function refinanceLendingToLendingAnyPair( fromAmount: getReferencedValue( ctx.getReference(['DepositBorrowToTarget', 'borrowAmount']), ), - toToken: debtConfig!.token, + toToken: collateralConfig!.token, })), ...(await dependencies.swapManager.getSpotPrices({ chainInfo: args.position.pool.protocol.chainInfo, From 74980fd3fd6e365688340b84ff5ce79cd2346d97 Mon Sep 17 00:00:00 2001 From: Roberto Cano <3525807+robercano@users.noreply.github.com> Date: Wed, 3 Apr 2024 18:26:36 +0200 Subject: [PATCH 05/24] fix: constructor visibility --- sdk/sdk-common/src/common/implementation/Position.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/sdk-common/src/common/implementation/Position.ts b/sdk/sdk-common/src/common/implementation/Position.ts index 342b4a34df..246469fd44 100644 --- a/sdk/sdk-common/src/common/implementation/Position.ts +++ b/sdk/sdk-common/src/common/implementation/Position.ts @@ -12,7 +12,7 @@ export class Position implements IPosition { readonly collateralAmount: TokenAmount readonly pool: IPool - constructor(params: IPosition) { + private constructor(params: IPosition) { this.positionId = params.positionId this.debtAmount = TokenAmount.createFrom(params.debtAmount) this.collateralAmount = TokenAmount.createFrom(params.collateralAmount) From 3be54fe6095e73fb1576870839666bec28711962 Mon Sep 17 00:00:00 2001 From: Damian Paszkowski Date: Thu, 4 Apr 2024 16:50:04 +0200 Subject: [PATCH 06/24] feat: implement import simulation --- .../interfaces/importing/ExternalPosition.ts | 17 ++++++++-- sdk/sdk-common/src/simulation/Enums.ts | 1 + sdk/sdk-common/src/simulation/Steps.ts | 4 +++ .../simulator-engine/reducer/importReducer.ts | 10 ++++++ .../simulator-engine/reducer/stateReducers.ts | 2 ++ .../stepProcessor/importPositionProcessor.ts | 9 +++++ .../stepProcessor/stepOutputProcessors.ts | 2 ++ .../src/strategies/import/ImportPosition.ts | 34 +++++++++++++++++++ .../src/strategies/import/Strategy.ts | 9 +++++ 9 files changed, 86 insertions(+), 2 deletions(-) create mode 100644 sdk/simulator-service/src/implementation/simulator-engine/reducer/importReducer.ts create mode 100644 sdk/simulator-service/src/implementation/simulator-engine/stepProcessor/importPositionProcessor.ts create mode 100644 sdk/simulator-service/src/strategies/import/ImportPosition.ts create mode 100644 sdk/simulator-service/src/strategies/import/Strategy.ts diff --git a/sdk/sdk-common/src/orders/interfaces/importing/ExternalPosition.ts b/sdk/sdk-common/src/orders/interfaces/importing/ExternalPosition.ts index 790d44bf73..e711a97aee 100644 --- a/sdk/sdk-common/src/orders/interfaces/importing/ExternalPosition.ts +++ b/sdk/sdk-common/src/orders/interfaces/importing/ExternalPosition.ts @@ -1,8 +1,21 @@ +import { Address, Position } from "src/common"; + +export enum ExternalPositionType { + WALLET = 'WALLET', + DS_PROXY = 'DS_PROXY', + } + +export interface ExternalPositionId { + type: ExternalPositionType + address: Address +} + /** * @interface ExternalPosition * @description Position existing in another service. This will be specialized into the IDs for the * different services. */ -export interface ExternalPosition { - // Empty on purpose +export interface ExternalPosition { + position: Position + externalId: ExternalPositionId } diff --git a/sdk/sdk-common/src/simulation/Enums.ts b/sdk/sdk-common/src/simulation/Enums.ts index 9f6dab6096..482fdb218c 100644 --- a/sdk/sdk-common/src/simulation/Enums.ts +++ b/sdk/sdk-common/src/simulation/Enums.ts @@ -17,6 +17,7 @@ export enum SimulationSteps { PullToken = 'PullToken', ReturnFunds = 'ReturnFunds', RepayFlashloan = 'RepayFlashloan', + Import = 'Import', } export enum FlashloanProvider { diff --git a/sdk/sdk-common/src/simulation/Steps.ts b/sdk/sdk-common/src/simulation/Steps.ts index e6e74941b1..58ee30abbc 100644 --- a/sdk/sdk-common/src/simulation/Steps.ts +++ b/sdk/sdk-common/src/simulation/Steps.ts @@ -6,6 +6,7 @@ import { TokenAmount } from '../common/implementation/TokenAmount' import { FlashloanProvider, SimulationSteps, TokenTransferTargetType } from './Enums' import { SwapProviderType, SwapRoute } from '../swap' import { ReferenceableField, ValueReference } from './ValueReference' +import { ExternalPosition } from 'src/orders' export interface Step { type: T @@ -84,6 +85,8 @@ export interface RepayFlashloan } > {} +export interface ImportStep extends Step {} + export type Steps = | FlashloanStep | PullTokenStep @@ -92,3 +95,4 @@ export type Steps = | SwapStep | ReturnFunds | RepayFlashloan + | ImportStep diff --git a/sdk/simulator-service/src/implementation/simulator-engine/reducer/importReducer.ts b/sdk/simulator-service/src/implementation/simulator-engine/reducer/importReducer.ts new file mode 100644 index 0000000000..4dc7578821 --- /dev/null +++ b/sdk/simulator-service/src/implementation/simulator-engine/reducer/importReducer.ts @@ -0,0 +1,10 @@ +import { steps } from '@summerfi/sdk-common/simulation' +import { addBalance } from '../../utils' +import { ISimulationState } from '../../../interfaces/simulation' + +export function importReducer( + _step: steps.ImportStep, + state: ISimulationState, +): ISimulationState { + return state +} diff --git a/sdk/simulator-service/src/implementation/simulator-engine/reducer/stateReducers.ts b/sdk/simulator-service/src/implementation/simulator-engine/reducer/stateReducers.ts index d88692759b..3872c977a1 100644 --- a/sdk/simulator-service/src/implementation/simulator-engine/reducer/stateReducers.ts +++ b/sdk/simulator-service/src/implementation/simulator-engine/reducer/stateReducers.ts @@ -8,6 +8,7 @@ import { swapReducer } from './swapReducer' import { returnFundsReducer } from './returnFundsReducer' import { repayFlashloanReducer } from './repayFlashloanReducer' import { pullTokenReducer } from './pullTokenReducer' +import { importReducer } from './importReducer' const stateReducers: StateReducers = { [SimulationSteps.Flashloan]: flashloanReducer, @@ -17,6 +18,7 @@ const stateReducers: StateReducers = { [SimulationSteps.ReturnFunds]: returnFundsReducer, [SimulationSteps.RepayFlashloan]: repayFlashloanReducer, [SimulationSteps.PullToken]: pullTokenReducer, + [SimulationSteps.Import]: importReducer, } export function stateReducer(step: steps.Steps, state: ISimulationState): ISimulationState { diff --git a/sdk/simulator-service/src/implementation/simulator-engine/stepProcessor/importPositionProcessor.ts b/sdk/simulator-service/src/implementation/simulator-engine/stepProcessor/importPositionProcessor.ts new file mode 100644 index 0000000000..3f31e7bb4b --- /dev/null +++ b/sdk/simulator-service/src/implementation/simulator-engine/stepProcessor/importPositionProcessor.ts @@ -0,0 +1,9 @@ +import { steps } from '@summerfi/sdk-common/simulation' +import type { StepOutputProcessor } from '../../../interfaces/steps' + +export const importPositionProcessor: StepOutputProcessor = async (step) => { + return { + ...step, + outputs: undefined, + } +} diff --git a/sdk/simulator-service/src/implementation/simulator-engine/stepProcessor/stepOutputProcessors.ts b/sdk/simulator-service/src/implementation/simulator-engine/stepProcessor/stepOutputProcessors.ts index 9637a00dff..ba740a706e 100644 --- a/sdk/simulator-service/src/implementation/simulator-engine/stepProcessor/stepOutputProcessors.ts +++ b/sdk/simulator-service/src/implementation/simulator-engine/stepProcessor/stepOutputProcessors.ts @@ -11,6 +11,7 @@ import { paybackWithdrawOutputProcessor } from './paybackWithdrawOutputProcessor import { swapOutputProcessor } from './swapOutputProcessor' import { returnFundsOutputProcessor } from './returnFundsOutputProcessor' import { repayFlashloanOutputProcessor } from './repayFlashloanOutputProcessor' +import { importPositionProcessor } from './importPositionProcessor' const stepOutputProcessors: StepOutputProcessors = { [SimulationSteps.Flashloan]: flashloanOutputProcessor, @@ -20,6 +21,7 @@ const stepOutputProcessors: StepOutputProcessors = { [SimulationSteps.ReturnFunds]: returnFundsOutputProcessor, [SimulationSteps.RepayFlashloan]: repayFlashloanOutputProcessor, [SimulationSteps.PullToken]: pullTokenOutputProcessor, + [SimulationSteps.Import]: importPositionProcessor, } export async function processStepOutput(step: StepsWithoutOutputs): Promise { diff --git a/sdk/simulator-service/src/strategies/import/ImportPosition.ts b/sdk/simulator-service/src/strategies/import/ImportPosition.ts new file mode 100644 index 0000000000..1104a64a7b --- /dev/null +++ b/sdk/simulator-service/src/strategies/import/ImportPosition.ts @@ -0,0 +1,34 @@ +import { + ISimulation, + SimulationSteps, + SimulationType, +} from '@summerfi/sdk-common/simulation' +import { Simulator } from '../../implementation/simulator-engine' +import { ImportPositionParameters } from '@summerfi/sdk-common/orders' +import { importPositionStrategy } from './Strategy' + + +export async function importPosition( + args: ImportPositionParameters, + dependencies: {}, +): Promise> { + const simulator = Simulator.create(importPositionStrategy) + + const simulation = await simulator + .next(async () => ({ + name: 'Import', + type: SimulationSteps.Import, + inputs: { + externalPosition: args.externalPosition, + }, + })) + .run() + + return { + simulationType: SimulationType.ImportPosition, + sourcePosition: args.externalPosition.position, + targetPosition: args.externalPosition.position, + swaps: Object.values(simulation.swaps), + steps: Object.values(simulation.steps), + } as ISimulation +} diff --git a/sdk/simulator-service/src/strategies/import/Strategy.ts b/sdk/simulator-service/src/strategies/import/Strategy.ts new file mode 100644 index 0000000000..5c08399787 --- /dev/null +++ b/sdk/simulator-service/src/strategies/import/Strategy.ts @@ -0,0 +1,9 @@ +import { SimulationSteps } from '@summerfi/sdk-common/simulation' +import { makeStrategy } from '../../implementation/utils' + +export const importPositionStrategy = makeStrategy([ + { + step: SimulationSteps.Import, + optional: false, + }, +]) From d1ccd3cafd6d15df3fcc36608d4080bcee871546 Mon Sep 17 00:00:00 2001 From: Roberto Cano <3525807+robercano@users.noreply.github.com> Date: Thu, 4 Apr 2024 17:19:09 +0200 Subject: [PATCH 07/24] feat: add position type to Position --- .../tests/utils/MakerSourcePosition.ts | 4 +++- .../tests/utils/SparkTargetPosition.ts | 4 +++- .../tests/ExecutionStorageMapper.spec.ts | 4 +++- .../tests/StepBuilderContext.spec.ts | 4 +++- .../common/actions/PositionCreatedAction.ts | 8 ++------ .../builders/PositionCreatedActionBuilder.ts | 1 - .../tests/actions/PositionCreatedAction.spec.ts | 7 +++---- .../builders/DepositBorrowActionBuilder.spec.ts | 4 +++- .../PaybackWithdrawActionBuilder.spec.ts | 4 +++- sdk/sdk-common/src/common/enums/PositionType.ts | 4 ++++ sdk/sdk-common/src/common/enums/index.ts | 1 + .../src/common/implementation/Position.ts | 5 ++++- .../src/common/interfaces/IPosition.ts | 2 ++ sdk/sdk-common/src/common/utils/PositionUtils.ts | 16 +++++++++++----- sdk/sdk-common/src/simulation/Enums.ts | 6 ------ sdk/sdk-common/src/simulation/Steps.ts | 3 +-- sdk/sdk-e2e/tests/refinanceMakerSpark.test.ts | 6 ++++-- .../RefinanceLendingToLendingAnyPair.ts | 2 -- .../RefinanceLendingToLendingSamePair.ts | 2 -- sdk/simulator-service/tests/simulator.test.ts | 2 -- 20 files changed, 50 insertions(+), 39 deletions(-) create mode 100644 sdk/sdk-common/src/common/enums/PositionType.ts diff --git a/sdk/order-planner-service/tests/utils/MakerSourcePosition.ts b/sdk/order-planner-service/tests/utils/MakerSourcePosition.ts index ddc14574fa..54d3d932a2 100644 --- a/sdk/order-planner-service/tests/utils/MakerSourcePosition.ts +++ b/sdk/order-planner-service/tests/utils/MakerSourcePosition.ts @@ -9,6 +9,7 @@ import { } from '@summerfi/sdk-common/common' import { PoolType, ProtocolName } from '@summerfi/sdk-common/protocols' import { ILKType, MakerPoolId } from '@summerfi/protocol-plugins/plugins/maker' +import { PositionType } from '@summerfi/sdk-common/common' export function getMakerPosition(): Position { const chainInfo: ChainInfo = ChainFamilyMap.Ethereum.Mainnet @@ -56,7 +57,8 @@ export function getMakerPosition(): Position { poolId, } - const position = new Position({ + const position = Position.createFrom({ + type: PositionType.Multiply, positionId: PositionId.createFrom({ id: 'makerPosition' }), debtAmount, collateralAmount, diff --git a/sdk/order-planner-service/tests/utils/SparkTargetPosition.ts b/sdk/order-planner-service/tests/utils/SparkTargetPosition.ts index 0fbb9d068c..c46d5c3ed1 100644 --- a/sdk/order-planner-service/tests/utils/SparkTargetPosition.ts +++ b/sdk/order-planner-service/tests/utils/SparkTargetPosition.ts @@ -6,6 +6,7 @@ import { ChainInfo, Position, PositionId, + PositionType, Token, TokenAmount, } from '@summerfi/sdk-common/common' @@ -56,7 +57,8 @@ export function getSparkPosition(): Position { poolId, } - const position = new Position({ + const position = Position.createFrom({ + type: PositionType.Multiply, positionId: PositionId.createFrom({ id: 'sparkPosition' }), debtAmount, collateralAmount, diff --git a/sdk/protocol-plugins-common/tests/ExecutionStorageMapper.spec.ts b/sdk/protocol-plugins-common/tests/ExecutionStorageMapper.spec.ts index 56d2650e69..2d3a85ed2b 100644 --- a/sdk/protocol-plugins-common/tests/ExecutionStorageMapper.spec.ts +++ b/sdk/protocol-plugins-common/tests/ExecutionStorageMapper.spec.ts @@ -6,6 +6,7 @@ import { ChainInfo, Position, PositionId, + PositionType, Token, TokenAmount, } from '@summerfi/sdk-common/common' @@ -78,7 +79,8 @@ describe('Execution Storage Mapper', () => { poolId, } - const position = new Position({ + const position = Position.createFrom({ + type: PositionType.Multiply, positionId: PositionId.createFrom({ id: 'someposition' }), debtAmount: borrowAmount, collateralAmount: depositAmount, diff --git a/sdk/protocol-plugins-common/tests/StepBuilderContext.spec.ts b/sdk/protocol-plugins-common/tests/StepBuilderContext.spec.ts index 5aab163057..16d3364e1b 100644 --- a/sdk/protocol-plugins-common/tests/StepBuilderContext.spec.ts +++ b/sdk/protocol-plugins-common/tests/StepBuilderContext.spec.ts @@ -4,6 +4,7 @@ import { ChainInfo, Position, PositionId, + PositionType, Token, TokenAmount, } from '@summerfi/sdk-common/common' @@ -87,7 +88,8 @@ describe('Step Builder Context', () => { poolId, } - const position = new Position({ + const position = Position.createFrom({ + type: PositionType.Multiply, positionId: PositionId.createFrom({ id: 'someposition' }), debtAmount: borrowAmount, collateralAmount: depositAmount, diff --git a/sdk/protocol-plugins/src/plugins/common/actions/PositionCreatedAction.ts b/sdk/protocol-plugins/src/plugins/common/actions/PositionCreatedAction.ts index 5bbe4d3ddb..7d10271d3f 100644 --- a/sdk/protocol-plugins/src/plugins/common/actions/PositionCreatedAction.ts +++ b/sdk/protocol-plugins/src/plugins/common/actions/PositionCreatedAction.ts @@ -1,6 +1,5 @@ import { ActionCall, BaseAction, InputSlotsMapping } from '@summerfi/protocol-plugins-common' import { Position } from '@summerfi/sdk-common/common' -import { PositionType } from '@summerfi/sdk-common/simulation' export class PositionCreatedAction extends BaseAction { public readonly config = { @@ -12,15 +11,12 @@ export class PositionCreatedAction extends BaseAction { storageOutputs: [], } as const - public encodeCall( - params: { position: Position; positionType: PositionType }, - paramsMapping?: InputSlotsMapping, - ): ActionCall { + public encodeCall(params: { position: Position }, paramsMapping?: InputSlotsMapping): ActionCall { return this._encodeCall({ arguments: [ { protocol: params.position.pool.protocol.name, - positionType: params.positionType, + positionType: params.position.type, collateralToken: params.position.collateralAmount.token.address.value, debtToken: params.position.debtAmount.token.address.value, }, diff --git a/sdk/protocol-plugins/src/plugins/common/builders/PositionCreatedActionBuilder.ts b/sdk/protocol-plugins/src/plugins/common/builders/PositionCreatedActionBuilder.ts index 1372bea7ad..5505dafbfc 100644 --- a/sdk/protocol-plugins/src/plugins/common/builders/PositionCreatedActionBuilder.ts +++ b/sdk/protocol-plugins/src/plugins/common/builders/PositionCreatedActionBuilder.ts @@ -12,7 +12,6 @@ export const PositionCreatedActionBuilder: ActionBuilder action: new PositionCreatedAction(), arguments: { position: step.inputs.position, - positionType: step.inputs.positionType, }, connectedInputs: {}, connectedOutputs: {}, diff --git a/sdk/protocol-plugins/tests/actions/PositionCreatedAction.spec.ts b/sdk/protocol-plugins/tests/actions/PositionCreatedAction.spec.ts index 389128e7b6..5e2e6a6b98 100644 --- a/sdk/protocol-plugins/tests/actions/PositionCreatedAction.spec.ts +++ b/sdk/protocol-plugins/tests/actions/PositionCreatedAction.spec.ts @@ -1,10 +1,9 @@ -import { Address, Position, Token, TokenAmount } from '@summerfi/sdk-common/common' +import { Address, Position, Token, TokenAmount, PositionType } from '@summerfi/sdk-common/common' import { decodeActionCalldata, getTargetHash } from '@summerfi/testing-utils' import { PositionCreatedAction } from '../../src/plugins/common/actions/PositionCreatedAction' import { IProtocol, PoolType, ProtocolName } from '@summerfi/sdk-common/protocols' import { MakerPoolId } from '../../src/plugins/maker/types/MakerPoolId' import { ILKType } from '../../src/plugins/maker' -import { PositionType } from '@summerfi/sdk-common/simulation' describe('PositionCreated Action', () => { const action = new PositionCreatedAction() @@ -41,6 +40,7 @@ describe('PositionCreated Action', () => { } const position = Position.createFrom({ + type: PositionType.Multiply, positionId: { id: '0x123', }, @@ -71,7 +71,6 @@ describe('PositionCreated Action', () => { const call = action.encodeCall( { position: position, - positionType: PositionType.Refinance, }, [8, 9, 1, 3], ) @@ -87,7 +86,7 @@ describe('PositionCreated Action', () => { expect(actionDecodedArgs?.args).toEqual([ { protocol: protocol.name, - positionType: PositionType.Refinance, + positionType: position.type, collateralToken: WETH.address.value, debtToken: DAI.address.value, }, diff --git a/sdk/protocol-plugins/tests/builders/DepositBorrowActionBuilder.spec.ts b/sdk/protocol-plugins/tests/builders/DepositBorrowActionBuilder.spec.ts index d5c68613b9..fa6b846340 100644 --- a/sdk/protocol-plugins/tests/builders/DepositBorrowActionBuilder.spec.ts +++ b/sdk/protocol-plugins/tests/builders/DepositBorrowActionBuilder.spec.ts @@ -4,6 +4,7 @@ import { ChainInfo, Position, PositionId, + PositionType, Token, TokenAmount, } from '@summerfi/sdk-common/common' @@ -65,7 +66,8 @@ describe('Deposit Borrow Action Builder', () => { poolId, } - const position = new Position({ + const position = Position.createFrom({ + type: PositionType.Multiply, positionId: PositionId.createFrom({ id: 'someposition' }), debtAmount: borrowAmount, collateralAmount: depositAmount, diff --git a/sdk/protocol-plugins/tests/builders/PaybackWithdrawActionBuilder.spec.ts b/sdk/protocol-plugins/tests/builders/PaybackWithdrawActionBuilder.spec.ts index 341323a109..afe11cdb6e 100644 --- a/sdk/protocol-plugins/tests/builders/PaybackWithdrawActionBuilder.spec.ts +++ b/sdk/protocol-plugins/tests/builders/PaybackWithdrawActionBuilder.spec.ts @@ -4,6 +4,7 @@ import { ChainInfo, Position, PositionId, + PositionType, Token, TokenAmount, } from '@summerfi/sdk-common/common' @@ -65,7 +66,8 @@ describe('Payback Withdraw Action Builder', () => { poolId, } - const position = new Position({ + const position = Position.createFrom({ + type: PositionType.Multiply, positionId: PositionId.createFrom({ id: 'someposition' }), debtAmount: withdrawAmount, collateralAmount: paybackAmount, diff --git a/sdk/sdk-common/src/common/enums/PositionType.ts b/sdk/sdk-common/src/common/enums/PositionType.ts new file mode 100644 index 0000000000..3d5d712b15 --- /dev/null +++ b/sdk/sdk-common/src/common/enums/PositionType.ts @@ -0,0 +1,4 @@ +export enum PositionType { + Borrow = 'Borrow', + Multiply = 'Multiply', +} diff --git a/sdk/sdk-common/src/common/enums/index.ts b/sdk/sdk-common/src/common/enums/index.ts index 3e8ca3f03e..ebdbbc0659 100644 --- a/sdk/sdk-common/src/common/enums/index.ts +++ b/sdk/sdk-common/src/common/enums/index.ts @@ -9,3 +9,4 @@ export { EthereumChainNames, OptimismChainNames, } from './ChainNames' +export { PositionType } from './PositionType' diff --git a/sdk/sdk-common/src/common/implementation/Position.ts b/sdk/sdk-common/src/common/implementation/Position.ts index 342b4a34df..744b9f773f 100644 --- a/sdk/sdk-common/src/common/implementation/Position.ts +++ b/sdk/sdk-common/src/common/implementation/Position.ts @@ -4,15 +4,18 @@ import { SerializationService } from '../../services/SerializationService' import { PositionId } from './PositionId' import { RiskRatio } from './RiskRatio' import { TokenAmount } from './TokenAmount' +import { PositionType } from '../enums/PositionType' // we should add assests prop instead of the amounts export class Position implements IPosition { + readonly type: PositionType readonly positionId: PositionId readonly debtAmount: TokenAmount readonly collateralAmount: TokenAmount readonly pool: IPool - constructor(params: IPosition) { + private constructor(params: IPosition) { + this.type = params.type this.positionId = params.positionId this.debtAmount = TokenAmount.createFrom(params.debtAmount) this.collateralAmount = TokenAmount.createFrom(params.collateralAmount) diff --git a/sdk/sdk-common/src/common/interfaces/IPosition.ts b/sdk/sdk-common/src/common/interfaces/IPosition.ts index bfec7badc1..8048d1e3c2 100644 --- a/sdk/sdk-common/src/common/interfaces/IPosition.ts +++ b/sdk/sdk-common/src/common/interfaces/IPosition.ts @@ -1,8 +1,10 @@ import { IPool } from '../../protocols/interfaces/IPool' +import { PositionType } from '../enums/PositionType' import { PositionId } from '../implementation/PositionId' import { ITokenAmount } from './ITokenAmount' export interface IPosition { + readonly type: PositionType readonly positionId: PositionId readonly debtAmount: ITokenAmount readonly collateralAmount: ITokenAmount diff --git a/sdk/sdk-common/src/common/utils/PositionUtils.ts b/sdk/sdk-common/src/common/utils/PositionUtils.ts index d6500ba641..63d4be51d6 100644 --- a/sdk/sdk-common/src/common/utils/PositionUtils.ts +++ b/sdk/sdk-common/src/common/utils/PositionUtils.ts @@ -2,6 +2,7 @@ import { LendingPool } from '../../protocols/implementation/LendingPool' import { TokenAmount } from '../implementation/TokenAmount' import { Position } from '../implementation/Position' import { Token } from '../implementation/Token' +import { PositionType } from '../enums/PositionType' export function newEmptyPositionFromPool( pool: LendingPool, @@ -18,7 +19,8 @@ export function newEmptyPositionFromPool( throw new Error('Collateral token not supported by pool') } - return new Position({ + return Position.createFrom({ + type: PositionType.Multiply, positionId: { id: 'newEmptyPositionFromPool', }, @@ -29,7 +31,8 @@ export function newEmptyPositionFromPool( } export function depositToPosition(position: Position, amount: TokenAmount): Position { - return new Position({ + return Position.createFrom({ + type: PositionType.Multiply, positionId: position.positionId, debtAmount: position.debtAmount, collateralAmount: position.collateralAmount.add(amount), @@ -38,7 +41,8 @@ export function depositToPosition(position: Position, amount: TokenAmount): Posi } export function withdrawFromPosition(position: Position, amount: TokenAmount): Position { - return new Position({ + return Position.createFrom({ + type: PositionType.Multiply, positionId: position.positionId, debtAmount: position.debtAmount, collateralAmount: position.collateralAmount.subtract(amount), @@ -47,7 +51,8 @@ export function withdrawFromPosition(position: Position, amount: TokenAmount): P } export function borrowFromPosition(position: Position, amount: TokenAmount): Position { - return new Position({ + return Position.createFrom({ + type: PositionType.Multiply, positionId: position.positionId, debtAmount: position.debtAmount.add(amount), collateralAmount: position.collateralAmount, @@ -56,7 +61,8 @@ export function borrowFromPosition(position: Position, amount: TokenAmount): Pos } export function repayPositionDebt(position: Position, amount: TokenAmount): Position { - return new Position({ + return Position.createFrom({ + type: PositionType.Multiply, positionId: position.positionId, debtAmount: position.debtAmount.subtract(amount), collateralAmount: position.collateralAmount, diff --git a/sdk/sdk-common/src/simulation/Enums.ts b/sdk/sdk-common/src/simulation/Enums.ts index 025ffdf366..f98b48921e 100644 --- a/sdk/sdk-common/src/simulation/Enums.ts +++ b/sdk/sdk-common/src/simulation/Enums.ts @@ -29,9 +29,3 @@ export enum TokenTransferTargetType { PositionsManager = 1, StrategyExecutor = 0, } - -export enum PositionType { - Borrow = 'Borrow', - Multiply = 'Multiply', - Refinance = 'Refinance', -} diff --git a/sdk/sdk-common/src/simulation/Steps.ts b/sdk/sdk-common/src/simulation/Steps.ts index 7f7dfcfa54..7fa8a9360a 100644 --- a/sdk/sdk-common/src/simulation/Steps.ts +++ b/sdk/sdk-common/src/simulation/Steps.ts @@ -3,7 +3,7 @@ import { Price } from '../common/implementation/Price' import { Position } from '../common/implementation/Position' import { Token } from '../common/implementation/Token' import { TokenAmount } from '../common/implementation/TokenAmount' -import { FlashloanProvider, PositionType, SimulationSteps, TokenTransferTargetType } from './Enums' +import { FlashloanProvider, SimulationSteps, TokenTransferTargetType } from './Enums' import { SwapProviderType, SwapRoute } from '../swap' import { ReferenceableField, ValueReference } from './ValueReference' @@ -89,7 +89,6 @@ export interface NewPositionEvent SimulationSteps.NewPositionEvent, { position: Position - positionType: PositionType } > {} diff --git a/sdk/sdk-e2e/tests/refinanceMakerSpark.test.ts b/sdk/sdk-e2e/tests/refinanceMakerSpark.test.ts index 5868134dae..0ff5b3415c 100644 --- a/sdk/sdk-e2e/tests/refinanceMakerSpark.test.ts +++ b/sdk/sdk-e2e/tests/refinanceMakerSpark.test.ts @@ -8,13 +8,14 @@ import { type Maybe, ChainFamilyMap, AddressValue, + PositionType, } from '@summerfi/sdk-common/common' import { ProtocolName, isLendingPool } from '@summerfi/sdk-common/protocols' import { makeSDK, type Chain, type User, Protocol } from '@summerfi/sdk-client' import { TokenSymbol } from '@summerfi/sdk-common/common/enums' import { IPositionsManager, IRefinanceParameters, Order } from '@summerfi/sdk-common/orders' -import { ISimulation, SimulationType, PositionType } from '@summerfi/sdk-common/simulation' +import { ISimulation, SimulationType } from '@summerfi/sdk-common/simulation' import { TransactionUtils } from './utils/TransactionUtils' import { decodeActionCalldata, @@ -122,6 +123,7 @@ describe.skip('Refinance Maker Spark | SDK', () => { // Source position const makerPosition: Position = Position.createFrom({ + type: PositionType.Multiply, positionId: PositionId.createFrom({ id: '31646' }), debtAmount: TokenAmount.createFromBaseUnit({ token: DAI, @@ -352,7 +354,7 @@ describe.skip('Refinance Maker Spark | SDK', () => { assert(positionCreatedParams, 'Cannot decode Position Created action calldata') expect(positionCreatedParams.args[0].protocol).toBe(targetPosition.pool.protocol.name) - expect(positionCreatedParams.args[0].positionType).toBe(PositionType.Refinance) + expect(positionCreatedParams.args[0].positionType).toBe(sourcePosition.type) expect(positionCreatedParams.args[0].collateralToken).toBe( targetPosition.collateralAmount.token.address.value, ) diff --git a/sdk/simulator-service/src/strategies/refinanceAnyPair/RefinanceLendingToLendingAnyPair.ts b/sdk/simulator-service/src/strategies/refinanceAnyPair/RefinanceLendingToLendingAnyPair.ts index 8868d473b1..167ce53859 100644 --- a/sdk/simulator-service/src/strategies/refinanceAnyPair/RefinanceLendingToLendingAnyPair.ts +++ b/sdk/simulator-service/src/strategies/refinanceAnyPair/RefinanceLendingToLendingAnyPair.ts @@ -1,7 +1,6 @@ import { FlashloanProvider, ISimulation, - PositionType, SimulationSteps, SimulationType, TokenTransferTargetType, @@ -145,7 +144,6 @@ export async function refinanceLendingToLendingAnyPair( type: SimulationSteps.NewPositionEvent, inputs: { position: targetPosition, - positionType: PositionType.Refinance, }, } }) diff --git a/sdk/simulator-service/src/strategies/refinanceSamePair/RefinanceLendingToLendingSamePair.ts b/sdk/simulator-service/src/strategies/refinanceSamePair/RefinanceLendingToLendingSamePair.ts index 2df3aa3089..a6c40dd887 100644 --- a/sdk/simulator-service/src/strategies/refinanceSamePair/RefinanceLendingToLendingSamePair.ts +++ b/sdk/simulator-service/src/strategies/refinanceSamePair/RefinanceLendingToLendingSamePair.ts @@ -1,7 +1,6 @@ import { FlashloanProvider, ISimulation, - PositionType, SimulationSteps, SimulationType, TokenTransferTargetType, @@ -98,7 +97,6 @@ export async function refinanceLendingToLendingSamePair( type: SimulationSteps.NewPositionEvent, inputs: { position: targetPosition, - positionType: PositionType.Refinance, }, } }) diff --git a/sdk/simulator-service/tests/simulator.test.ts b/sdk/simulator-service/tests/simulator.test.ts index 5c224b6697..85cc48d922 100644 --- a/sdk/simulator-service/tests/simulator.test.ts +++ b/sdk/simulator-service/tests/simulator.test.ts @@ -1,6 +1,5 @@ import { Percentage } from '@summerfi/sdk-common/common' import { - PositionType, ISimulation, SimulationSteps, SimulationType, @@ -72,7 +71,6 @@ describe('Refinance', () => { assert(newPositionStep, 'New position event step not found') expect(newPositionStep.inputs.position).toEqual(simulation.targetPosition) - expect(newPositionStep.inputs.positionType).toEqual(PositionType.Refinance) }) }) From 024d2bf4f973df3b8668aac12d2116289c2a2686 Mon Sep 17 00:00:00 2001 From: Roberto Cano <3525807+robercano@users.noreply.github.com> Date: Thu, 4 Apr 2024 17:22:01 +0200 Subject: [PATCH 08/24] fix: missing refactor for position type --- .../src/implementation/simulations/RefinanceSimulationManager.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/sdk/sdk-client/src/implementation/simulations/RefinanceSimulationManager.ts b/sdk/sdk-client/src/implementation/simulations/RefinanceSimulationManager.ts index c81f61c734..f35e014f39 100644 --- a/sdk/sdk-client/src/implementation/simulations/RefinanceSimulationManager.ts +++ b/sdk/sdk-client/src/implementation/simulations/RefinanceSimulationManager.ts @@ -13,6 +13,7 @@ export class RefinanceSimulationManager extends IRPCClient { ): Promise> { const refinanceParameters: IRefinanceParameters = { position: { + type: params.position.type, positionId: params.position.positionId, debtAmount: params.position.debtAmount, collateralAmount: params.position.collateralAmount, From 6f54222c153a65f4712f8a6013cb28a70ea197b5 Mon Sep 17 00:00:00 2001 From: Roberto Cano <3525807+robercano@users.noreply.github.com> Date: Thu, 4 Apr 2024 17:40:18 +0200 Subject: [PATCH 09/24] fix: broken cicheck --- sdk/sdk-client/tests/queries/newOrder.subtest.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sdk/sdk-client/tests/queries/newOrder.subtest.ts b/sdk/sdk-client/tests/queries/newOrder.subtest.ts index 61a147a1a3..8132bc43ff 100644 --- a/sdk/sdk-client/tests/queries/newOrder.subtest.ts +++ b/sdk/sdk-client/tests/queries/newOrder.subtest.ts @@ -12,6 +12,7 @@ import { Percentage, Position, PositionId, + PositionType, RiskRatio, Token, TokenAmount, @@ -56,6 +57,7 @@ export default async function simulateNewOrder() { } as MakerLendingPool const prevPosition: Position = { + type: PositionType.Multiply, pool: pool, debtAmount: TokenAmount.createFrom({ token: DAI, amount: '56.78' }), collateralAmount: TokenAmount.createFrom({ token: WETH, amount: '105.98' }), @@ -82,6 +84,7 @@ export default async function simulateNewOrder() { sourcePosition: prevPosition, swaps: [], targetPosition: { + type: PositionType.Multiply, positionId: PositionId.createFrom({ id: '1234567890' }), debtAmount: TokenAmount.createFrom({ token: DAI, amount: '56.78' }), collateralAmount: TokenAmount.createFrom({ token: WETH, amount: '105.98' }), From 86c621a61b848c383114dc5d835f787973130c93 Mon Sep 17 00:00:00 2001 From: Roberto Cano <3525807+robercano@users.noreply.github.com> Date: Thu, 4 Apr 2024 17:40:28 +0200 Subject: [PATCH 10/24] chore: add format to turbo cicheck --- package.json | 2 +- turbo.json | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index b0735fbb73..5975cee78f 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,7 @@ "test": "turbo run test --cache-dir=.turbo", "test:integration": "turbo run test:integration --cache-dir=.turbo", "check-circular": "turbo run check-circular --cache-dir=.turbo", - "cicheck": "turbo run cicheck --cache-dir=.turbo && pnpm format", + "cicheck": "turbo run cicheck --cache-dir=.turbo", "sst:dev": "sst dev", "sst:build": "sst build", "sst:deploy:staging": "sst deploy --stage staging", diff --git a/turbo.json b/turbo.json index eaf1f90a64..eaff06d6a7 100644 --- a/turbo.json +++ b/turbo.json @@ -54,11 +54,14 @@ "lint": { "dependsOn": ["prebuild", "build", "^lint"] }, + "format": { + "dependsOn": ["prebuild", "build", "^format"] + }, "check-circular": { "dependsOn": ["prebuild", "build", "^check-circular"] }, "cicheck": { - "dependsOn": ["prebuild", "build", "test", "lint", "check-circular"] + "dependsOn": ["prebuild", "build", "test", "lint", "check-circular", "format"] }, "deploy:staging": { "dependsOn": ["cicheck", "^deploy:staging"] From e059ab1c7912b4a11938e7987c7cd8cc087e5506 Mon Sep 17 00:00:00 2001 From: Roberto Cano <3525807+robercano@users.noreply.github.com> Date: Thu, 4 Apr 2024 17:51:47 +0200 Subject: [PATCH 11/24] fix: cicheck --- sdk/sdk-client/tests/queries/simulateRefinance.subtest.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sdk/sdk-client/tests/queries/simulateRefinance.subtest.ts b/sdk/sdk-client/tests/queries/simulateRefinance.subtest.ts index 5dc1f70ebc..53771e63cf 100644 --- a/sdk/sdk-client/tests/queries/simulateRefinance.subtest.ts +++ b/sdk/sdk-client/tests/queries/simulateRefinance.subtest.ts @@ -11,6 +11,7 @@ import { Percentage, Position, PositionId, + PositionType, RiskRatio, Token, TokenAmount, @@ -25,6 +26,7 @@ export default async function simulateRefinanceTest() { sourcePosition: params.position, swaps: [], targetPosition: { + type: params.position.type, positionId: PositionId.createFrom({ id: '0987654321' }), debtAmount: params.position.debtAmount, collateralAmount: params.position.collateralAmount, @@ -82,6 +84,7 @@ export default async function simulateRefinanceTest() { } as MakerLendingPool const prevPosition: Position = { + type: PositionType.Multiply, pool: pool, debtAmount: TokenAmount.createFrom({ token: DAI, amount: '56.78' }), collateralAmount: TokenAmount.createFrom({ token: WETH, amount: '105.98' }), From e39429180bdab040a611815d3d2c6bd530c04749 Mon Sep 17 00:00:00 2001 From: Roberto Cano <3525807+robercano@users.noreply.github.com> Date: Fri, 12 Apr 2024 09:50:24 +0200 Subject: [PATCH 12/24] wip: add maker import to maker plugin --- .../src/implementation/OrderPlanner.ts | 49 ++++++++++--------- .../src/interfaces/IOrderPlanner.ts | 19 +++---- .../src/utils/GenerateStrategyName.ts | 5 ++ .../scripts/encodeMakerGive.ts | 10 +++- .../src/config/Config.ts | 2 + sdk/order-planner-service/tsconfig.json | 7 ++- .../src/context/StepBuilderContext.ts | 10 ++++ .../src/interfaces/IProtocolPlugin.ts | 7 +++ .../src/interfaces/IProtocolPluginContext.ts | 3 +- .../src/interfaces/IStepBuilderContext.ts | 4 ++ .../src/implementation/BaseProtocolPlugin.ts | 7 +++ .../implementation/AAVEv3ProtocolPlugin.ts | 10 ++++ .../builders/DepositBorrowActionBuilder.ts | 20 ++------ .../builders/ImportPositionActionBuilder.ts | 14 ++++++ .../builders/PaybackWithdrawActionBuilder.ts | 20 ++------ .../builders/PositionCreatedActionBuilder.ts | 2 +- .../builders/RepayFlashloanActionBuilder.ts | 4 +- .../builders/ReturnFundsActionBuilder.ts | 2 +- .../src/plugins/common/builders/index.ts | 1 + .../common/constants/AaveV3LikeConstants.ts | 1 + .../MakerImportPositionActionBuilder.ts | 33 +++++++++++++ .../implementation/MakerProtocolPlugin.ts | 42 ++++++++++++++++ .../src/plugins/maker/index.ts | 1 + .../maker/types/MakerExternalPosition.ts | 18 +++++++ .../src/plugins/maker}/utils/MakerGive.ts | 17 ++++--- .../src/plugins/maker/utils/index.ts | 2 + .../implementation/SparkProtocolPlugin.ts | 10 ++++ .../utils/DelegateToProtocolActionBuilder.ts | 23 +++++++++ .../RepayFlashloanActionBuilder.spec.ts | 4 +- .../builders/ReturnFundsActionBuilder.spec.ts | 2 +- .../src/common/interfaces/IPosition.ts | 12 +++++ .../interfaces/importing/ExternalPosition.ts | 8 --- .../interfaces/importing/IExternalPosition.ts | 40 +++++++++++++++ .../importing/ImportPositionParameters.ts | 4 +- .../src/orders/interfaces/importing/index.ts | 2 +- sdk/sdk-common/src/simulation/Enums.ts | 1 + sdk/sdk-common/src/simulation/Steps.ts | 17 ++++--- sdk/sdk-e2e/tests/refinanceMakerSpark.test.ts | 4 +- .../reducer/newPositionEventReducer.ts | 2 +- .../reducer/repayFlashloanReducer.ts | 2 +- .../reducer/returnFundsReducer.ts | 2 +- .../simulator-engine/reducer/stateReducers.ts | 1 + .../stepProcessor/newPositionEvent.ts | 2 +- .../repayFlashloanOutputProcessor.ts | 2 +- .../returnFundsOutputProcessor.ts | 4 +- 45 files changed, 346 insertions(+), 106 deletions(-) create mode 100644 sdk/order-planner-common/src/utils/GenerateStrategyName.ts create mode 100644 sdk/protocol-plugins/src/plugins/common/builders/ImportPositionActionBuilder.ts create mode 100644 sdk/protocol-plugins/src/plugins/maker/builders/MakerImportPositionActionBuilder.ts create mode 100644 sdk/protocol-plugins/src/plugins/maker/types/MakerExternalPosition.ts rename sdk/{order-planner-service/src => protocol-plugins/src/plugins/maker}/utils/MakerGive.ts (71%) create mode 100644 sdk/protocol-plugins/src/plugins/maker/utils/index.ts create mode 100644 sdk/protocol-plugins/src/plugins/utils/DelegateToProtocolActionBuilder.ts delete mode 100644 sdk/sdk-common/src/orders/interfaces/importing/ExternalPosition.ts create mode 100644 sdk/sdk-common/src/orders/interfaces/importing/IExternalPosition.ts diff --git a/sdk/order-planner-common/src/implementation/OrderPlanner.ts b/sdk/order-planner-common/src/implementation/OrderPlanner.ts index e94a582b5d..c5ad99526c 100644 --- a/sdk/order-planner-common/src/implementation/OrderPlanner.ts +++ b/sdk/order-planner-common/src/implementation/OrderPlanner.ts @@ -1,33 +1,23 @@ -import { Order, type IPositionsManager } from '@summerfi/sdk-common/orders' +import { Order, type IPositionsManager, TransactionInfo } from '@summerfi/sdk-common/orders' import { ISimulation, SimulationType, steps } from '@summerfi/sdk-common/simulation' import { Deployment } from '@summerfi/deployment-utils' import { Address, Maybe } from '@summerfi/sdk-common/common' import { HexData } from '@summerfi/sdk-common/common/aliases' -import { ISwapManager } from '@summerfi/swap-common/interfaces' -import { IUser } from '@summerfi/sdk-common/user' import { ActionBuilder, ActionBuildersMap, ActionCall, - IProtocolPluginsRegistry, IStepBuilderContext, StepBuilderContext, } from '@summerfi/protocol-plugins-common' -import { IOrderPlanner } from '../interfaces/IOrderPlanner' +import { IOrderPlanner, OrderPlannerParams } from '../interfaces/IOrderPlanner' import { encodeStrategy } from '../utils/EncodeStrategy' export class OrderPlanner implements IOrderPlanner { + // TODO: receive it as parameter in the constructor private readonly ExecutorContractName = 'OperationExecutor' - async buildOrder(params: { - user: IUser - positionsManager: IPositionsManager - simulation: ISimulation - actionBuildersMap: ActionBuildersMap - deployment: Deployment - swapManager: ISwapManager - protocolsRegistry: IProtocolPluginsRegistry - }): Promise> { + async buildOrder(params: OrderPlannerParams): Promise> { const { user, positionsManager, @@ -43,7 +33,7 @@ export class OrderPlanner implements IOrderPlanner { context.startSubContext() for (const step of simulation.steps) { - const stepBuilder = this.getActionBuilder(actionBuildersMap, step) + const stepBuilder = this._getActionBuilder(actionBuildersMap, step) if (!stepBuilder) { throw new Error(`No step builder found for step type ${step.type}`) } @@ -65,10 +55,18 @@ export class OrderPlanner implements IOrderPlanner { throw new Error('Mismatched nested calls levels, probably a missing endSubContext call') } - return this._generateOrder(simulation, callsBatch, positionsManager, deployment) + const preRequisiteTransactions = context.transactions + + return this._generateOrder({ + simulation, + preRequisiteTransactions, + simulationCalls: callsBatch, + positionsManager, + deployment, + }) } - private getActionBuilder( + private _getActionBuilder( actionBuildersMap: ActionBuildersMap, step: T, ): Maybe> { @@ -79,12 +77,16 @@ export class OrderPlanner implements IOrderPlanner { return `${simulation.simulationType}${simulation.sourcePosition?.pool.protocol.name}${simulation.targetPosition?.pool.protocol.name}` } - private _generateOrder( - simulation: ISimulation, - simulationCalls: ActionCall[], - positionsManager: IPositionsManager, - deployment: Deployment, - ): Order { + private _generateOrder(params: { + simulation: ISimulation + preRequisiteTransactions: TransactionInfo[] + simulationCalls: ActionCall[] + positionsManager: IPositionsManager + deployment: Deployment + }): Order { + const { simulation, preRequisiteTransactions, simulationCalls, positionsManager, deployment } = + params + const executorInfo = deployment.contracts[this.ExecutorContractName] if (!executorInfo) { throw new Error(`Executor contract ${this.ExecutorContractName} not found in deployment`) @@ -101,6 +103,7 @@ export class OrderPlanner implements IOrderPlanner { return { simulation: simulation, transactions: [ + ...preRequisiteTransactions, { transaction: { target: positionsManager.address, diff --git a/sdk/order-planner-common/src/interfaces/IOrderPlanner.ts b/sdk/order-planner-common/src/interfaces/IOrderPlanner.ts index 928b9faf02..83aa31ec57 100644 --- a/sdk/order-planner-common/src/interfaces/IOrderPlanner.ts +++ b/sdk/order-planner-common/src/interfaces/IOrderPlanner.ts @@ -6,14 +6,15 @@ import { Maybe } from '@summerfi/sdk-common/common' import { IUser } from '@summerfi/sdk-common/user' import { ActionBuildersMap, IProtocolPluginsRegistry } from '@summerfi/protocol-plugins-common' +export type OrderPlannerParams = { + user: IUser + positionsManager: IPositionsManager + simulation: ISimulation + actionBuildersMap: ActionBuildersMap + deployment: Deployment + swapManager: ISwapManager + protocolsRegistry: IProtocolPluginsRegistry +} export interface IOrderPlanner { - buildOrder(params: { - user: IUser - positionsManager: IPositionsManager - simulation: ISimulation - actionBuildersMap: ActionBuildersMap - deployment: Deployment - swapManager: ISwapManager - protocolsRegistry: IProtocolPluginsRegistry - }): Promise> + buildOrder(params: OrderPlannerParams): Promise> } diff --git a/sdk/order-planner-common/src/utils/GenerateStrategyName.ts b/sdk/order-planner-common/src/utils/GenerateStrategyName.ts new file mode 100644 index 0000000000..24a8f2319a --- /dev/null +++ b/sdk/order-planner-common/src/utils/GenerateStrategyName.ts @@ -0,0 +1,5 @@ +import { ISimulation, SimulationType } from '@summerfi/sdk-common/simulation' + +export function generateStrategyName(simulation: ISimulation): string { + return `${simulation.simulationType}${simulation.sourcePosition?.pool.protocol.name}${simulation.targetPosition?.pool.protocol.name}` +} diff --git a/sdk/order-planner-service/scripts/encodeMakerGive.ts b/sdk/order-planner-service/scripts/encodeMakerGive.ts index dcc848ceaf..98767321cc 100644 --- a/sdk/order-planner-service/scripts/encodeMakerGive.ts +++ b/sdk/order-planner-service/scripts/encodeMakerGive.ts @@ -1,4 +1,5 @@ -import { encodeMakerGiveThroughProxyActions } from '../src/utils/MakerGive' +import { encodeMakerGiveThroughProxyActions } from '@summerfi/protocol-plugins/plugins/maker' + import yargs from 'yargs/yargs' import { Hex } from 'viem' @@ -37,7 +38,12 @@ async function main() { console.log(`CDP ID: ${cdpId}`) console.log(`To: ${to}\n`) - const result = encodeMakerGiveThroughProxyActions({ makerProxyActions, cdpManager, cdpId, to }) + const result = encodeMakerGiveThroughProxyActions({ + makerProxyActionsAddress: makerProxyActions, + cdpManagerAddress: cdpManager, + cdpId, + giveToAddress: to, + }) console.log(`[Full transaction Calldata]`) console.log(`${result.transactionCalldata}\n`) diff --git a/sdk/order-planner-service/src/config/Config.ts b/sdk/order-planner-service/src/config/Config.ts index 03657eb3cc..de09eb7909 100644 --- a/sdk/order-planner-service/src/config/Config.ts +++ b/sdk/order-planner-service/src/config/Config.ts @@ -3,6 +3,7 @@ import { ActionBuildersMap } from '@summerfi/protocol-plugins-common' import { DepositBorrowActionBuilder, FlashloanActionBuilder, + ImportPositionActionBuilder, PaybackWithdrawActionBuilder, PositionCreatedActionBuilder, PullTokenActionBuilder, @@ -20,4 +21,5 @@ export const ActionBuildersConfig: ActionBuildersMap = { [SimulationSteps.PaybackWithdraw]: PaybackWithdrawActionBuilder, [SimulationSteps.ReturnFunds]: ReturnFundsActionBuilder, [SimulationSteps.NewPositionEvent]: PositionCreatedActionBuilder, + [SimulationSteps.Import]: ImportPositionActionBuilder, } diff --git a/sdk/order-planner-service/tsconfig.json b/sdk/order-planner-service/tsconfig.json index f778098c74..8a502b00cb 100644 --- a/sdk/order-planner-service/tsconfig.json +++ b/sdk/order-planner-service/tsconfig.json @@ -5,6 +5,11 @@ "outDir": "dist", "baseUrl": "." }, - "include": ["src/**/*.ts", "tests/**/*.ts", "scripts/**/*.ts"], + "include": [ + "src/**/*.ts", + "tests/**/*.ts", + "scripts/**/*.ts", + "../protocol-plugins/src/plugins/maker/utils/MakerGive.ts" + ], "exclude": ["node_modules"] } diff --git a/sdk/protocol-plugins-common/src/context/StepBuilderContext.ts b/sdk/protocol-plugins-common/src/context/StepBuilderContext.ts index 37b2059bf4..7955d006e7 100644 --- a/sdk/protocol-plugins-common/src/context/StepBuilderContext.ts +++ b/sdk/protocol-plugins-common/src/context/StepBuilderContext.ts @@ -6,11 +6,17 @@ import { IStepBuilderContext } from '../interfaces/IStepBuilderContext' import { ActionCallBatch } from '../actions/Types' import { ActionCallsStack } from './ActionCallsStack' import { ExecutionStorageMapper } from './ExecutionStorageMapper' +import { TransactionInfo } from '@summerfi/sdk-common/orders' export class StepBuilderContext implements IStepBuilderContext { + private _transactions: TransactionInfo[] = [] private _calls: ActionCallsStack = new ActionCallsStack() private _storage: ExecutionStorageMapper = new ExecutionStorageMapper() + public addTransaction(params: { transaction: TransactionInfo }): void { + this._transactions.push(params.transaction) + } + public addActionCall(params: { step: Step action: Action @@ -43,4 +49,8 @@ export class StepBuilderContext implements IStepBuilderContext { public get subContextLevels(): number { return this._calls.subContextLevels } + + public get transactions(): TransactionInfo[] { + return this._transactions + } } diff --git a/sdk/protocol-plugins-common/src/interfaces/IProtocolPlugin.ts b/sdk/protocol-plugins-common/src/interfaces/IProtocolPlugin.ts index 4b0ba7ce51..30de60f111 100644 --- a/sdk/protocol-plugins-common/src/interfaces/IProtocolPlugin.ts +++ b/sdk/protocol-plugins-common/src/interfaces/IProtocolPlugin.ts @@ -4,6 +4,8 @@ import { type IProtocolPluginContext } from './IProtocolPluginContext' import { IPositionId } from './IPositionId' import { steps } from '@summerfi/sdk-common/simulation' import { ActionBuilder, ActionBuildersMap } from '../types/StepBuilderTypes' +import { IUser } from '@summerfi/sdk-common/user' +import { IExternalPosition, IPositionsManager, TransactionInfo } from '@summerfi/sdk-common/orders' export interface IProtocolPlugin { protocolName: ProtocolName @@ -17,4 +19,9 @@ export interface IProtocolPlugin { getPool: (poolId: IPoolId) => Promise getPosition: (positionId: IPositionId) => Promise getActionBuilder(step: StepType): Maybe> + getImportPositionTransaction: (params: { + user: IUser + position: IExternalPosition + positionsManager: IPositionsManager + }) => Promise> } diff --git a/sdk/protocol-plugins-common/src/interfaces/IProtocolPluginContext.ts b/sdk/protocol-plugins-common/src/interfaces/IProtocolPluginContext.ts index 166205b5ad..85429a4621 100644 --- a/sdk/protocol-plugins-common/src/interfaces/IProtocolPluginContext.ts +++ b/sdk/protocol-plugins-common/src/interfaces/IProtocolPluginContext.ts @@ -1,10 +1,11 @@ import { PublicClient } from 'viem' import { IPriceService } from './IPriceService' import { ITokenService } from './ITokenService' -// import { IContractProvider } from './IContractProvider' +import { Deployment } from '@summerfi/deployment-utils' export interface IProtocolPluginContext { provider: PublicClient tokenService: ITokenService priceService: IPriceService + deployment: Deployment } diff --git a/sdk/protocol-plugins-common/src/interfaces/IStepBuilderContext.ts b/sdk/protocol-plugins-common/src/interfaces/IStepBuilderContext.ts index 07a4fdd9be..aca9ab9ad0 100644 --- a/sdk/protocol-plugins-common/src/interfaces/IStepBuilderContext.ts +++ b/sdk/protocol-plugins-common/src/interfaces/IStepBuilderContext.ts @@ -3,8 +3,11 @@ import { ActionCallBatch } from '../actions/Types' import { steps } from '@summerfi/sdk-common/simulation' import { Maybe } from '@summerfi/sdk-common/common' import { StorageInputsMapType, StorageOutputsMapType } from '../types/ActionStorageTypes' +import { TransactionInfo } from '@summerfi/sdk-common/orders' export interface IStepBuilderContext { + addTransaction(params: { transaction: TransactionInfo }): void + addActionCall(params: { step: Step action: Action @@ -21,4 +24,5 @@ export interface IStepBuilderContext { } get subContextLevels(): number + get transactions(): TransactionInfo[] } diff --git a/sdk/protocol-plugins/src/implementation/BaseProtocolPlugin.ts b/sdk/protocol-plugins/src/implementation/BaseProtocolPlugin.ts index d12dc7b724..d253817d55 100644 --- a/sdk/protocol-plugins/src/implementation/BaseProtocolPlugin.ts +++ b/sdk/protocol-plugins/src/implementation/BaseProtocolPlugin.ts @@ -6,8 +6,10 @@ import { IProtocolPluginContext, } from '@summerfi/protocol-plugins-common' import { ChainInfo, Maybe, IPosition } from '@summerfi/sdk-common/common' +import { IExternalPosition, IPositionsManager, TransactionInfo } from '@summerfi/sdk-common/orders' import { IPoolId, ProtocolName, IPool } from '@summerfi/sdk-common/protocols' import { steps } from '@summerfi/sdk-common/simulation' +import { IUser } from '@summerfi/sdk-common/user' import { z } from 'zod' /** @@ -39,6 +41,11 @@ export abstract class BaseProtocolPlugin implements IProtocolPlugin { abstract getPool(poolId: unknown): Promise abstract getPosition(positionId: IPositionId): Promise + abstract getImportPositionTransaction(params: { + user: IUser + position: IExternalPosition + positionsManager: IPositionsManager + }): Promise> getActionBuilder(step: T): Maybe> { return this.stepBuilders[step.type] as ActionBuilder diff --git a/sdk/protocol-plugins/src/plugins/aave-v3/implementation/AAVEv3ProtocolPlugin.ts b/sdk/protocol-plugins/src/plugins/aave-v3/implementation/AAVEv3ProtocolPlugin.ts index f532b7eb66..600ba90ac1 100644 --- a/sdk/protocol-plugins/src/plugins/aave-v3/implementation/AAVEv3ProtocolPlugin.ts +++ b/sdk/protocol-plugins/src/plugins/aave-v3/implementation/AAVEv3ProtocolPlugin.ts @@ -41,6 +41,8 @@ import { import { AaveV3ContractNames } from '@summerfi/deployment-types' import { EmodeType } from '../../common/enums/EmodeType' import { AaveV3PoolId } from '../types/AaveV3PoolId' +import { IUser } from '@summerfi/sdk-common/user' +import { IExternalPosition, IPositionsManager, TransactionInfo } from '@summerfi/sdk-common/orders' type AssetsList = ReturnType type Asset = Awaited extends (infer U)[] ? U : never @@ -130,6 +132,14 @@ export class AaveV3ProtocolPlugin extends BaseProtocolPlugin { throw new Error(`Not implemented ${positionId}`) } + async getImportPositionTransaction(params: { + user: IUser + position: IExternalPosition + positionsManager: IPositionsManager + }): Promise> { + throw new Error(`Not implemented ${params}`) + } + private getContractDef(contractName: K): AaveV3AddressAbiMap[K] { // TODO: Need to be driven by ChainId in future const map: AaveV3AddressAbiMap = { diff --git a/sdk/protocol-plugins/src/plugins/common/builders/DepositBorrowActionBuilder.ts b/sdk/protocol-plugins/src/plugins/common/builders/DepositBorrowActionBuilder.ts index 9abbb99c42..560b27ec8f 100644 --- a/sdk/protocol-plugins/src/plugins/common/builders/DepositBorrowActionBuilder.ts +++ b/sdk/protocol-plugins/src/plugins/common/builders/DepositBorrowActionBuilder.ts @@ -1,22 +1,12 @@ import { ActionBuilder } from '@summerfi/protocol-plugins-common' import { steps } from '@summerfi/sdk-common/simulation' +import { delegateToProtocolActionBuilder } from '../../utils/DelegateToProtocolActionBuilder' export const DepositBorrowActionBuilder: ActionBuilder = async ( params, ): Promise => { - const { step, protocolsRegistry } = params - - const protocol = step.inputs.position.pool.protocol - - const plugin = protocolsRegistry.getPlugin({ protocolName: protocol.name }) - if (!plugin) { - throw new Error(`No protocol plugin found for protocol ${protocol.name}`) - } - - const builder = plugin.getActionBuilder(params.step) - if (!builder) { - throw new Error(`No action builder found for protocol ${protocol.name}`) - } - - builder(params) + delegateToProtocolActionBuilder({ + protocolName: params.step.inputs.position.pool.protocol.name, + actionBuilderParams: params, + }) } diff --git a/sdk/protocol-plugins/src/plugins/common/builders/ImportPositionActionBuilder.ts b/sdk/protocol-plugins/src/plugins/common/builders/ImportPositionActionBuilder.ts new file mode 100644 index 0000000000..47de30864e --- /dev/null +++ b/sdk/protocol-plugins/src/plugins/common/builders/ImportPositionActionBuilder.ts @@ -0,0 +1,14 @@ +import { ActionBuilder } from '@summerfi/protocol-plugins-common' +import { steps } from '@summerfi/sdk-common/simulation' +import { delegateToProtocolActionBuilder } from '../../utils/DelegateToProtocolActionBuilder' + +export const ImportPositionActionBuilder: ActionBuilder = async ( + params, +): Promise => { + const externalPosition = params.step.inputs.externalPosition + + delegateToProtocolActionBuilder({ + protocolName: externalPosition.position.pool.protocol.name, + actionBuilderParams: params, + }) +} diff --git a/sdk/protocol-plugins/src/plugins/common/builders/PaybackWithdrawActionBuilder.ts b/sdk/protocol-plugins/src/plugins/common/builders/PaybackWithdrawActionBuilder.ts index 9a2c6cc06a..5b4a62956e 100644 --- a/sdk/protocol-plugins/src/plugins/common/builders/PaybackWithdrawActionBuilder.ts +++ b/sdk/protocol-plugins/src/plugins/common/builders/PaybackWithdrawActionBuilder.ts @@ -1,22 +1,12 @@ import { ActionBuilder } from '@summerfi/protocol-plugins-common' import { steps } from '@summerfi/sdk-common/simulation' +import { delegateToProtocolActionBuilder } from '../../utils/DelegateToProtocolActionBuilder' export const PaybackWithdrawActionBuilder: ActionBuilder = async ( params, ): Promise => { - const { step, protocolsRegistry } = params - - const protocol = step.inputs.position.pool.protocol - - const plugin = protocolsRegistry.getPlugin({ protocolName: protocol.name }) - if (!plugin) { - throw new Error(`No protocol plugin found for protocol ${protocol.name}`) - } - - const builder = plugin.getActionBuilder(params.step) - if (!builder) { - throw new Error(`No action builder found for protocol ${protocol.name}`) - } - - builder(params) + delegateToProtocolActionBuilder({ + protocolName: params.step.inputs.position.pool.protocol.name, + actionBuilderParams: params, + }) } diff --git a/sdk/protocol-plugins/src/plugins/common/builders/PositionCreatedActionBuilder.ts b/sdk/protocol-plugins/src/plugins/common/builders/PositionCreatedActionBuilder.ts index 5505dafbfc..4bcff20413 100644 --- a/sdk/protocol-plugins/src/plugins/common/builders/PositionCreatedActionBuilder.ts +++ b/sdk/protocol-plugins/src/plugins/common/builders/PositionCreatedActionBuilder.ts @@ -2,7 +2,7 @@ import { steps } from '@summerfi/sdk-common/simulation' import { ActionBuilder } from '@summerfi/protocol-plugins-common' import { PositionCreatedAction } from '../actions/PositionCreatedAction' -export const PositionCreatedActionBuilder: ActionBuilder = async ( +export const PositionCreatedActionBuilder: ActionBuilder = async ( params, ): Promise => { const { context, step } = params diff --git a/sdk/protocol-plugins/src/plugins/common/builders/RepayFlashloanActionBuilder.ts b/sdk/protocol-plugins/src/plugins/common/builders/RepayFlashloanActionBuilder.ts index 3b8cb6cbb6..e9ef174331 100644 --- a/sdk/protocol-plugins/src/plugins/common/builders/RepayFlashloanActionBuilder.ts +++ b/sdk/protocol-plugins/src/plugins/common/builders/RepayFlashloanActionBuilder.ts @@ -13,8 +13,8 @@ export const FlashloanProviderMap: Record = { [FlashloanProvider.Balancer]: 1, } -export const RepayFlashloanActionBuilder: ActionBuilder = async ( - params: ActionBuilderParams, +export const RepayFlashloanActionBuilder: ActionBuilder = async ( + params: ActionBuilderParams, ): Promise => { const { context, step, deployment } = params diff --git a/sdk/protocol-plugins/src/plugins/common/builders/ReturnFundsActionBuilder.ts b/sdk/protocol-plugins/src/plugins/common/builders/ReturnFundsActionBuilder.ts index f429eecf76..4e69f45b54 100644 --- a/sdk/protocol-plugins/src/plugins/common/builders/ReturnFundsActionBuilder.ts +++ b/sdk/protocol-plugins/src/plugins/common/builders/ReturnFundsActionBuilder.ts @@ -2,7 +2,7 @@ import { steps } from '@summerfi/sdk-common/simulation' import { ActionBuilder } from '@summerfi/protocol-plugins-common' import { ReturnFundsAction } from '../actions/ReturnFundsAction' -export const ReturnFundsActionBuilder: ActionBuilder = async ( +export const ReturnFundsActionBuilder: ActionBuilder = async ( params, ): Promise => { const { context, step } = params diff --git a/sdk/protocol-plugins/src/plugins/common/builders/index.ts b/sdk/protocol-plugins/src/plugins/common/builders/index.ts index e2d8f5d9bc..0f1b4ae370 100644 --- a/sdk/protocol-plugins/src/plugins/common/builders/index.ts +++ b/sdk/protocol-plugins/src/plugins/common/builders/index.ts @@ -10,3 +10,4 @@ export { export { ReturnFundsActionBuilder } from './ReturnFundsActionBuilder' export { SwapActionBuilder } from './SwapActionBuilder' export { PositionCreatedActionBuilder } from './PositionCreatedActionBuilder' +export { ImportPositionActionBuilder } from './ImportPositionActionBuilder' diff --git a/sdk/protocol-plugins/src/plugins/common/constants/AaveV3LikeConstants.ts b/sdk/protocol-plugins/src/plugins/common/constants/AaveV3LikeConstants.ts index dce64290d8..cae7a5f6a5 100644 --- a/sdk/protocol-plugins/src/plugins/common/constants/AaveV3LikeConstants.ts +++ b/sdk/protocol-plugins/src/plugins/common/constants/AaveV3LikeConstants.ts @@ -1,3 +1,4 @@ +// TODO: is this the correct place for these constants? Seem to be Maker specific export const PRECISION = { WAD: 18, RAY: 27, diff --git a/sdk/protocol-plugins/src/plugins/maker/builders/MakerImportPositionActionBuilder.ts b/sdk/protocol-plugins/src/plugins/maker/builders/MakerImportPositionActionBuilder.ts new file mode 100644 index 0000000000..5b2250c6be --- /dev/null +++ b/sdk/protocol-plugins/src/plugins/maker/builders/MakerImportPositionActionBuilder.ts @@ -0,0 +1,33 @@ +import { steps } from '@summerfi/sdk-common/simulation' +import { ActionNames } from '@summerfi/deployment-types' +import { ActionBuilder } from '@summerfi/protocol-plugins-common' +import { isMakerPoolId } from '../types/MakerPoolId' +import { ProtocolName } from '@summerfi/sdk-common/protocols' +export const MakerPaybackWithdrawActionList: ActionNames[] = ['MakerPayback', 'MakerWithdraw'] + +export const MakerImportPositionActionBuilder: ActionBuilder = async ( + params, +): Promise => { + const { protocolsRegistry, step, user, context, positionsManager } = params + + if (!isMakerPoolId(step.inputs.externalPosition.position.pool.poolId)) { + throw new Error('Maker: Invalid pool id') + } + + const makerPlugin = protocolsRegistry.getPlugin({ protocolName: ProtocolName.Maker }) + if (!makerPlugin) { + throw new Error('Maker plugin not found') + } + + const importPositionTransaction = await makerPlugin.getImportPositionTransaction({ + user: user, + position: step.inputs.externalPosition, + positionsManager: positionsManager, + }) + + if (!importPositionTransaction) { + throw new Error('Maker: Import position transaction not found') + } + + context.addTransaction({ transaction: importPositionTransaction }) +} diff --git a/sdk/protocol-plugins/src/plugins/maker/implementation/MakerProtocolPlugin.ts b/sdk/protocol-plugins/src/plugins/maker/implementation/MakerProtocolPlugin.ts index 9bf8b16ad9..0afd7cb27e 100644 --- a/sdk/protocol-plugins/src/plugins/maker/implementation/MakerProtocolPlugin.ts +++ b/sdk/protocol-plugins/src/plugins/maker/implementation/MakerProtocolPlugin.ts @@ -10,6 +10,8 @@ import { ChainId, ChainFamilyName, valuesOfChainFamilyMap, + Maybe, + AddressValue, } from '@summerfi/sdk-common/common' import { PoolType, ProtocolName } from '@summerfi/sdk-common/protocols' import { SimulationSteps } from '@summerfi/sdk-common/simulation' @@ -40,8 +42,15 @@ import { } from '@summerfi/protocol-plugins-common' import { ILKType } from '../enums/ILKType' import { MakerPoolId } from '../types/MakerPoolId' +import { IUser } from '@summerfi/sdk-common/user' +import { IPositionsManager, TransactionInfo } from '@summerfi/sdk-common/orders' +import { encodeMakerGiveThroughProxyActions } from '../utils/MakerGive' +import { MakerExternalPosition, isMakerExternalPosition } from '../types/MakerExternalPosition' export class MakerProtocolPlugin extends BaseProtocolPlugin { + readonly CdpManagerContractName = 'CdpManager' + readonly DssProxyActionsContractName = 'DssProxyActions' + readonly protocolName = ProtocolName.Maker readonly supportedChains = valuesOfChainFamilyMap([ChainFamilyName.Ethereum]) readonly makerPoolIdSchema = z.object({ @@ -213,6 +222,39 @@ export class MakerProtocolPlugin extends BaseProtocolPlugin { throw new Error('Not implemented') } + async getImportPositionTransaction(params: { + user: IUser + position: MakerExternalPosition + positionsManager: IPositionsManager + }): Promise> { + if (!isMakerExternalPosition(params.position)) { + throw new Error('Invalid Maker external position') + } + + const cdpManagerAddress = this.context.deployment.dependencies[this.CdpManagerContractName] + .address as AddressValue + + const dssProxyActionsAddress = this.context.deployment.dependencies[ + this.DssProxyActionsContractName + ].address as AddressValue + + const result = encodeMakerGiveThroughProxyActions({ + cdpManagerAddress: cdpManagerAddress, + makerProxyActionsAddress: dssProxyActionsAddress, + giveToAddress: params.positionsManager.address.value, + cdpId: params.position.vaultId, + }) + + return { + description: 'Import Maker position', + transaction: { + calldata: result.transactionCalldata, + target: params.position.dsProxyAddress, + value: '0', + }, + } + } + private getContractDef( contractName: K, ): MakerAddressAbiMap[K] { diff --git a/sdk/protocol-plugins/src/plugins/maker/index.ts b/sdk/protocol-plugins/src/plugins/maker/index.ts index 714dd2968e..37d070da95 100644 --- a/sdk/protocol-plugins/src/plugins/maker/index.ts +++ b/sdk/protocol-plugins/src/plugins/maker/index.ts @@ -4,3 +4,4 @@ export * from './builders' export * from './actions' export * from './types' export * from './enums' +export * from './utils' diff --git a/sdk/protocol-plugins/src/plugins/maker/types/MakerExternalPosition.ts b/sdk/protocol-plugins/src/plugins/maker/types/MakerExternalPosition.ts new file mode 100644 index 0000000000..e90b019e3b --- /dev/null +++ b/sdk/protocol-plugins/src/plugins/maker/types/MakerExternalPosition.ts @@ -0,0 +1,18 @@ +import { Address } from '@summerfi/sdk-common/common' +import { IExternalPosition } from '@summerfi/sdk-common/orders' +import { isExternalPosition } from 'node_modules/@summerfi/sdk-common/src/orders/interfaces/importing/IExternalPosition' + +export interface MakerExternalPosition extends IExternalPosition { + dsProxyAddress: Address + vaultId: string +} + +export function isMakerExternalPosition( + maybePosition: unknown, +): maybePosition is MakerExternalPosition { + return ( + isExternalPosition(maybePosition) && + 'vaultId' in maybePosition && + 'dsProxyAddress' in maybePosition + ) +} diff --git a/sdk/order-planner-service/src/utils/MakerGive.ts b/sdk/protocol-plugins/src/plugins/maker/utils/MakerGive.ts similarity index 71% rename from sdk/order-planner-service/src/utils/MakerGive.ts rename to sdk/protocol-plugins/src/plugins/maker/utils/MakerGive.ts index 0d5ec22e89..dfbdde580a 100644 --- a/sdk/order-planner-service/src/utils/MakerGive.ts +++ b/sdk/protocol-plugins/src/plugins/maker/utils/MakerGive.ts @@ -1,16 +1,17 @@ +import { AddressValue } from '@summerfi/sdk-common/common' import { Hex, encodeFunctionData, parseAbi } from 'viem' export function encodeMakerProxyActionsGive(params: { - cdpManager: Hex + cdpManagerAddress: AddressValue cdpId: string - to: Hex + giveToAddress: AddressValue }): Hex { const abi = parseAbi(['function give(address cdpManager, uint256 cdpId, address to)']) return encodeFunctionData({ abi, functionName: 'give', - args: [params.cdpManager, BigInt(params.cdpId), params.to], + args: [params.cdpManagerAddress, BigInt(params.cdpId), params.giveToAddress], }) } @@ -25,10 +26,10 @@ export function encodeDsProxyExecute(params: { target: Hex; callData: Hex }): He } export function encodeMakerGiveThroughProxyActions(params: { - makerProxyActions: Hex - cdpManager: Hex + makerProxyActionsAddress: AddressValue + cdpManagerAddress: AddressValue cdpId: string - to: Hex + giveToAddress: AddressValue }): { transactionCalldata: Hex dsProxyParameters: { @@ -38,14 +39,14 @@ export function encodeMakerGiveThroughProxyActions(params: { } { const makerGiveCalldata = encodeMakerProxyActionsGive(params) const transactionCalldata = encodeDsProxyExecute({ - target: params.makerProxyActions, + target: params.makerProxyActionsAddress, callData: makerGiveCalldata, }) return { transactionCalldata, dsProxyParameters: { - target: params.makerProxyActions, + target: params.makerProxyActionsAddress, callData: makerGiveCalldata, }, } diff --git a/sdk/protocol-plugins/src/plugins/maker/utils/index.ts b/sdk/protocol-plugins/src/plugins/maker/utils/index.ts new file mode 100644 index 0000000000..98683ff9e2 --- /dev/null +++ b/sdk/protocol-plugins/src/plugins/maker/utils/index.ts @@ -0,0 +1,2 @@ +export * from './MakerGive' +export * from './AmountUtils' diff --git a/sdk/protocol-plugins/src/plugins/spark/implementation/SparkProtocolPlugin.ts b/sdk/protocol-plugins/src/plugins/spark/implementation/SparkProtocolPlugin.ts index 5c14fc4cdc..f1cf0cb2e8 100644 --- a/sdk/protocol-plugins/src/plugins/spark/implementation/SparkProtocolPlugin.ts +++ b/sdk/protocol-plugins/src/plugins/spark/implementation/SparkProtocolPlugin.ts @@ -46,6 +46,8 @@ import { import { SparkAddressAbiMap } from '../types/SparkAddressAbiMap' import { EmodeType } from '../../common/enums/EmodeType' import { SparkPoolId } from '../types/SparkPoolId' +import { IUser } from '@summerfi/sdk-common/user' +import { IExternalPosition, IPositionsManager, TransactionInfo } from '@summerfi/sdk-common/orders' type AssetsList = ReturnType type Asset = Awaited extends (infer U)[] ? U : never @@ -133,6 +135,14 @@ export class SparkProtocolPlugin extends BaseProtocolPlugin { throw new Error(`Not implemented ${positionId}`) } + async getImportPositionTransaction(params: { + user: IUser + position: IExternalPosition + positionsManager: IPositionsManager + }): Promise> { + throw new Error(`Not implemented ${params}`) + } + private getContractDef(contractName: K): SparkAddressAbiMap[K] { const map: SparkAddressAbiMap = { Oracle: { diff --git a/sdk/protocol-plugins/src/plugins/utils/DelegateToProtocolActionBuilder.ts b/sdk/protocol-plugins/src/plugins/utils/DelegateToProtocolActionBuilder.ts new file mode 100644 index 0000000000..f845d378da --- /dev/null +++ b/sdk/protocol-plugins/src/plugins/utils/DelegateToProtocolActionBuilder.ts @@ -0,0 +1,23 @@ +import { ActionBuilderParams, FilterStep } from '@summerfi/protocol-plugins-common' +import { ProtocolName } from '@summerfi/sdk-common/protocols' +import { SimulationSteps, steps } from '@summerfi/sdk-common/simulation' + +export function delegateToProtocolActionBuilder(params: { + protocolName: ProtocolName + actionBuilderParams: ActionBuilderParams> +}) { + const { protocolName } = params + const { protocolsRegistry } = params.actionBuilderParams + + const plugin = protocolsRegistry.getPlugin({ protocolName }) + if (!plugin) { + throw new Error(`No protocol plugin found for protocol ${protocolName}`) + } + + const builder = plugin.getActionBuilder(params.actionBuilderParams.step) + if (!builder) { + throw new Error(`No action builder found for protocol ${protocolName}`) + } + + builder(params.actionBuilderParams) +} diff --git a/sdk/protocol-plugins/tests/builders/RepayFlashloanActionBuilder.spec.ts b/sdk/protocol-plugins/tests/builders/RepayFlashloanActionBuilder.spec.ts index 614d73c989..19f66fb928 100644 --- a/sdk/protocol-plugins/tests/builders/RepayFlashloanActionBuilder.spec.ts +++ b/sdk/protocol-plugins/tests/builders/RepayFlashloanActionBuilder.spec.ts @@ -59,7 +59,7 @@ describe('Payback Flashloan Action Builder', () => { }) it('should fail if there is no custom data from flashloan step', async () => { - const repayFlashloanStep: steps.RepayFlashloan = { + const repayFlashloanStep: steps.RepayFlashloanStep = { type: SimulationSteps.RepayFlashloan, name: 'RepayFlashloanStep', inputs: { @@ -106,7 +106,7 @@ describe('Payback Flashloan Action Builder', () => { outputs: undefined, } - const repayFlashloanStep: steps.RepayFlashloan = { + const repayFlashloanStep: steps.RepayFlashloanStep = { type: SimulationSteps.RepayFlashloan, name: 'RepayFlashloanStep', inputs: { diff --git a/sdk/protocol-plugins/tests/builders/ReturnFundsActionBuilder.spec.ts b/sdk/protocol-plugins/tests/builders/ReturnFundsActionBuilder.spec.ts index f57a10acd7..22095e8e15 100644 --- a/sdk/protocol-plugins/tests/builders/ReturnFundsActionBuilder.spec.ts +++ b/sdk/protocol-plugins/tests/builders/ReturnFundsActionBuilder.spec.ts @@ -26,7 +26,7 @@ describe('Return Funds Action Builder', () => { it('should encode the action calldata correctly', async () => { const builderParams = setupBuilderParams({ chainInfo: ChainFamilyMap.Ethereum.Mainnet }) - const derivedStep: steps.ReturnFunds = { + const derivedStep: steps.ReturnFundsStep = { type: SimulationSteps.ReturnFunds, name: 'ReturnFundsStep', inputs: { diff --git a/sdk/sdk-common/src/common/interfaces/IPosition.ts b/sdk/sdk-common/src/common/interfaces/IPosition.ts index 8048d1e3c2..2080808b0c 100644 --- a/sdk/sdk-common/src/common/interfaces/IPosition.ts +++ b/sdk/sdk-common/src/common/interfaces/IPosition.ts @@ -10,3 +10,15 @@ export interface IPosition { readonly collateralAmount: ITokenAmount readonly pool: IPool } + +export function isPosition(maybePosition: unknown): maybePosition is IPosition { + return ( + typeof maybePosition === 'object' && + maybePosition !== null && + 'type' in maybePosition && + 'positionId' in maybePosition && + 'debtAmount' in maybePosition && + 'collateralAmount' in maybePosition && + 'pool' in maybePosition + ) +} diff --git a/sdk/sdk-common/src/orders/interfaces/importing/ExternalPosition.ts b/sdk/sdk-common/src/orders/interfaces/importing/ExternalPosition.ts deleted file mode 100644 index 790d44bf73..0000000000 --- a/sdk/sdk-common/src/orders/interfaces/importing/ExternalPosition.ts +++ /dev/null @@ -1,8 +0,0 @@ -/** - * @interface ExternalPosition - * @description Position existing in another service. This will be specialized into the IDs for the - * different services. - */ -export interface ExternalPosition { - // Empty on purpose -} diff --git a/sdk/sdk-common/src/orders/interfaces/importing/IExternalPosition.ts b/sdk/sdk-common/src/orders/interfaces/importing/IExternalPosition.ts new file mode 100644 index 0000000000..3794aa0d69 --- /dev/null +++ b/sdk/sdk-common/src/orders/interfaces/importing/IExternalPosition.ts @@ -0,0 +1,40 @@ +import { isPosition } from '../../../common' +import { Address } from '../../../common/implementation/Address' +import { Position } from '../../../common/implementation/Position' + +export enum ExternalPositionType { + WALLET = 'WALLET', + DS_PROXY = 'DS_PROXY', +} + +export interface IExternalPositionId { + type: ExternalPositionType + address: Address +} + +export function isExternalPositionId(maybeId: unknown): maybeId is IExternalPositionId { + return ( + typeof maybeId === 'object' && maybeId !== null && 'type' in maybeId && 'address' in maybeId + ) +} + +/** + * @interface IExternalPosition + * @description Position existing in another service. This will be specialized into the IDs for the + * different services. + */ +export interface IExternalPosition { + position: Position + externalId: IExternalPositionId +} + +export function isExternalPosition(maybePosition: unknown): maybePosition is IExternalPosition { + return ( + typeof maybePosition === 'object' && + maybePosition !== null && + 'position' in maybePosition && + isPosition(maybePosition.position) && + 'externalId' in maybePosition && + isExternalPositionId(maybePosition.externalId) + ) +} diff --git a/sdk/sdk-common/src/orders/interfaces/importing/ImportPositionParameters.ts b/sdk/sdk-common/src/orders/interfaces/importing/ImportPositionParameters.ts index 4d20baf7db..c449c0f147 100644 --- a/sdk/sdk-common/src/orders/interfaces/importing/ImportPositionParameters.ts +++ b/sdk/sdk-common/src/orders/interfaces/importing/ImportPositionParameters.ts @@ -1,4 +1,4 @@ -import { ExternalPosition } from './ExternalPosition' +import { IExternalPosition } from './IExternalPosition' /** * @interface ImportPositionParameters @@ -6,5 +6,5 @@ import { ExternalPosition } from './ExternalPosition' */ export interface ImportPositionParameters { /** External position to be imported */ - externalPosition: ExternalPosition + externalPosition: IExternalPosition } diff --git a/sdk/sdk-common/src/orders/interfaces/importing/index.ts b/sdk/sdk-common/src/orders/interfaces/importing/index.ts index b08d6f2bcb..12092ffae7 100644 --- a/sdk/sdk-common/src/orders/interfaces/importing/index.ts +++ b/sdk/sdk-common/src/orders/interfaces/importing/index.ts @@ -1,3 +1,3 @@ -export type { ExternalPosition } from './ExternalPosition' +export type { IExternalPosition } from './IExternalPosition' export type { ImportPositionParameters } from './ImportPositionParameters' export type { ImportPositionSimulation } from './ImportPositionSimulation' diff --git a/sdk/sdk-common/src/simulation/Enums.ts b/sdk/sdk-common/src/simulation/Enums.ts index f98b48921e..0b5a233485 100644 --- a/sdk/sdk-common/src/simulation/Enums.ts +++ b/sdk/sdk-common/src/simulation/Enums.ts @@ -18,6 +18,7 @@ export enum SimulationSteps { ReturnFunds = 'ReturnFunds', RepayFlashloan = 'RepayFlashloan', NewPositionEvent = 'NewPositionEvent', + Import = 'Import', } export enum FlashloanProvider { diff --git a/sdk/sdk-common/src/simulation/Steps.ts b/sdk/sdk-common/src/simulation/Steps.ts index 7fa8a9360a..712b0598ea 100644 --- a/sdk/sdk-common/src/simulation/Steps.ts +++ b/sdk/sdk-common/src/simulation/Steps.ts @@ -6,6 +6,7 @@ import { TokenAmount } from '../common/implementation/TokenAmount' import { FlashloanProvider, SimulationSteps, TokenTransferTargetType } from './Enums' import { SwapProviderType, SwapRoute } from '../swap' import { ReferenceableField, ValueReference } from './ValueReference' +import { IExternalPosition } from '../orders/interfaces/importing/IExternalPosition' export interface Step { type: T @@ -74,9 +75,9 @@ export interface SwapStep } > {} -export interface ReturnFunds extends Step {} +export interface ReturnFundsStep extends Step {} -export interface RepayFlashloan +export interface RepayFlashloanStep extends Step< SimulationSteps.RepayFlashloan, { @@ -84,7 +85,7 @@ export interface RepayFlashloan } > {} -export interface NewPositionEvent +export interface NewPositionEventStep extends Step< SimulationSteps.NewPositionEvent, { @@ -92,12 +93,16 @@ export interface NewPositionEvent } > {} +export interface ImportStep + extends Step {} + export type Steps = | FlashloanStep | PullTokenStep | DepositBorrowStep | PaybackWithdrawStep | SwapStep - | ReturnFunds - | RepayFlashloan - | NewPositionEvent + | ReturnFundsStep + | RepayFlashloanStep + | NewPositionEventStep + | ImportStep diff --git a/sdk/sdk-e2e/tests/refinanceMakerSpark.test.ts b/sdk/sdk-e2e/tests/refinanceMakerSpark.test.ts index 0ff5b3415c..5269c196fa 100644 --- a/sdk/sdk-e2e/tests/refinanceMakerSpark.test.ts +++ b/sdk/sdk-e2e/tests/refinanceMakerSpark.test.ts @@ -50,9 +50,9 @@ import { jest.setTimeout(300000) const SDKAPiUrl = 'https://zmjmtfsocb.execute-api.us-east-1.amazonaws.com/api/sdk' -const TenderlyForkUrl = 'https://rpc.tenderly.co/fork/50e01944-8635-4d67-9569-004d72113328' +const TenderlyForkUrl = 'https://rpc.tenderly.co/fork/82118352-dec5-442a-b03b-e5cc84533f0e' -describe.skip('Refinance Maker Spark | SDK', () => { +describe('Refinance Maker Spark | SDK', () => { it('should allow refinance Maker -> Spark with same pair', async () => { // SDK const sdk = makeSDK({ apiURL: SDKAPiUrl }) diff --git a/sdk/simulator-service/src/implementation/simulator-engine/reducer/newPositionEventReducer.ts b/sdk/simulator-service/src/implementation/simulator-engine/reducer/newPositionEventReducer.ts index 9606b40429..84df627a03 100644 --- a/sdk/simulator-service/src/implementation/simulator-engine/reducer/newPositionEventReducer.ts +++ b/sdk/simulator-service/src/implementation/simulator-engine/reducer/newPositionEventReducer.ts @@ -2,7 +2,7 @@ import { steps } from '@summerfi/sdk-common/simulation' import { ISimulationState } from '../../../interfaces/simulation' export function newPositionEventReducer( - step: steps.NewPositionEvent, + step: steps.NewPositionEventStep, state: ISimulationState, ): ISimulationState { return { diff --git a/sdk/simulator-service/src/implementation/simulator-engine/reducer/repayFlashloanReducer.ts b/sdk/simulator-service/src/implementation/simulator-engine/reducer/repayFlashloanReducer.ts index 5ce116fe7c..70a196865d 100644 --- a/sdk/simulator-service/src/implementation/simulator-engine/reducer/repayFlashloanReducer.ts +++ b/sdk/simulator-service/src/implementation/simulator-engine/reducer/repayFlashloanReducer.ts @@ -3,7 +3,7 @@ import { subtractBalance } from '../../utils' import { ISimulationState } from '../../../interfaces/simulation' export function repayFlashloanReducer( - step: steps.RepayFlashloan, + step: steps.RepayFlashloanStep, state: ISimulationState, ): ISimulationState { return { diff --git a/sdk/simulator-service/src/implementation/simulator-engine/reducer/returnFundsReducer.ts b/sdk/simulator-service/src/implementation/simulator-engine/reducer/returnFundsReducer.ts index 75166b5328..c37f52b471 100644 --- a/sdk/simulator-service/src/implementation/simulator-engine/reducer/returnFundsReducer.ts +++ b/sdk/simulator-service/src/implementation/simulator-engine/reducer/returnFundsReducer.ts @@ -3,7 +3,7 @@ import { getTokenBalance, subtractBalance } from '../../utils' import { ISimulationState } from '../../../interfaces/simulation' export function returnFundsReducer( - step: steps.ReturnFunds, + step: steps.ReturnFundsStep, state: ISimulationState, ): ISimulationState { return { diff --git a/sdk/simulator-service/src/implementation/simulator-engine/reducer/stateReducers.ts b/sdk/simulator-service/src/implementation/simulator-engine/reducer/stateReducers.ts index 34a60bb046..f8ec6eb997 100644 --- a/sdk/simulator-service/src/implementation/simulator-engine/reducer/stateReducers.ts +++ b/sdk/simulator-service/src/implementation/simulator-engine/reducer/stateReducers.ts @@ -19,6 +19,7 @@ const stateReducers: StateReducers = { [SimulationSteps.RepayFlashloan]: repayFlashloanReducer, [SimulationSteps.PullToken]: pullTokenReducer, [SimulationSteps.NewPositionEvent]: newPositionEventReducer, + [SimulationSteps.Import]: newPositionEventReducer, } export function stateReducer(step: steps.Steps, state: ISimulationState): ISimulationState { diff --git a/sdk/simulator-service/src/implementation/simulator-engine/stepProcessor/newPositionEvent.ts b/sdk/simulator-service/src/implementation/simulator-engine/stepProcessor/newPositionEvent.ts index 8817014f6f..5d9e9b2965 100644 --- a/sdk/simulator-service/src/implementation/simulator-engine/stepProcessor/newPositionEvent.ts +++ b/sdk/simulator-service/src/implementation/simulator-engine/stepProcessor/newPositionEvent.ts @@ -1,7 +1,7 @@ import { steps } from '@summerfi/sdk-common/simulation' import type { StepOutputProcessor } from '../../../interfaces/steps' -export const newPositionEventProcessor: StepOutputProcessor = async ( +export const newPositionEventProcessor: StepOutputProcessor = async ( step, ) => { return { diff --git a/sdk/simulator-service/src/implementation/simulator-engine/stepProcessor/repayFlashloanOutputProcessor.ts b/sdk/simulator-service/src/implementation/simulator-engine/stepProcessor/repayFlashloanOutputProcessor.ts index c30d413336..7807dd7b0c 100644 --- a/sdk/simulator-service/src/implementation/simulator-engine/stepProcessor/repayFlashloanOutputProcessor.ts +++ b/sdk/simulator-service/src/implementation/simulator-engine/stepProcessor/repayFlashloanOutputProcessor.ts @@ -1,7 +1,7 @@ import { steps } from '@summerfi/sdk-common/simulation' import type { StepOutputProcessor } from '../../../interfaces/steps' -export const repayFlashloanOutputProcessor: StepOutputProcessor = async ( +export const repayFlashloanOutputProcessor: StepOutputProcessor = async ( step, ) => { return { diff --git a/sdk/simulator-service/src/implementation/simulator-engine/stepProcessor/returnFundsOutputProcessor.ts b/sdk/simulator-service/src/implementation/simulator-engine/stepProcessor/returnFundsOutputProcessor.ts index c6abff1cfe..d0aa7ed22d 100644 --- a/sdk/simulator-service/src/implementation/simulator-engine/stepProcessor/returnFundsOutputProcessor.ts +++ b/sdk/simulator-service/src/implementation/simulator-engine/stepProcessor/returnFundsOutputProcessor.ts @@ -1,7 +1,9 @@ import { steps } from '@summerfi/sdk-common/simulation' import type { StepOutputProcessor } from '../../../interfaces/steps' -export const returnFundsOutputProcessor: StepOutputProcessor = async (step) => { +export const returnFundsOutputProcessor: StepOutputProcessor = async ( + step, +) => { return { ...step, outputs: undefined, From c7cf2e089fb5b5ece3c21a7e48b8cf22302c7d10 Mon Sep 17 00:00:00 2001 From: Roberto Cano <3525807+robercano@users.noreply.github.com> Date: Fri, 12 Apr 2024 10:51:44 +0200 Subject: [PATCH 13/24] fix: tests --- .../tests/service/OrderPlannerService.spec.ts | 2 ++ .../RefinanceSimulation.ts | 4 ++-- .../tests/ProtocolManager.spec.ts | 4 ++++ sdk/protocol-manager-service/tsconfig.json | 3 ++- .../tsconfig.test.json | 3 ++- .../src/interfaces/IProtocolPluginContext.ts | 4 ++-- .../tests/ExecutionStorageMapper.spec.ts | 2 +- .../src/implementation/BaseProtocolPlugin.ts | 8 +++++++- .../implementation/ProtocolPluginsRegistry.ts | 11 +++++++++-- .../implementation/AAVEv3ProtocolPlugin.ts | 2 +- .../implementation/MakerProtocolPlugin.ts | 19 +++++++++++-------- .../maker/types/MakerExternalPosition.ts | 3 +-- .../implementation/SparkProtocolPlugin.ts | 2 +- .../utils/CreateProtocolPluginContext.ts | 3 ++- .../src/orders/interfaces/importing/index.ts | 2 +- sdk/sdk-e2e/tests/refinanceMakerSpark.test.ts | 2 +- sdk/sdk-server/src/context/Context.ts | 4 +++- .../context/CreateProtocolPluginsRegistry.ts | 9 ++++++++- sdk/simulator-service/tests/simulator.test.ts | 2 +- 19 files changed, 61 insertions(+), 28 deletions(-) diff --git a/sdk/order-planner-service/tests/service/OrderPlannerService.spec.ts b/sdk/order-planner-service/tests/service/OrderPlannerService.spec.ts index 752dacf451..3e9edf51c3 100644 --- a/sdk/order-planner-service/tests/service/OrderPlannerService.spec.ts +++ b/sdk/order-planner-service/tests/service/OrderPlannerService.spec.ts @@ -70,7 +70,9 @@ describe('Order Planner Service', () => { provider: undefined as unknown as PublicClient, tokenService: undefined as unknown as ITokenService, priceService: undefined as unknown as IPriceService, + deployments: deploymentsIndex, }, + deploymentConfigTag: 'standard', }) orderPlannerService = new OrderPlannerService({ diff --git a/sdk/order-planner-service/tests/utils/RefinanceSimulation/RefinanceSimulation.ts b/sdk/order-planner-service/tests/utils/RefinanceSimulation/RefinanceSimulation.ts index eae3cbcdb0..39ed8cfd09 100644 --- a/sdk/order-planner-service/tests/utils/RefinanceSimulation/RefinanceSimulation.ts +++ b/sdk/order-planner-service/tests/utils/RefinanceSimulation/RefinanceSimulation.ts @@ -65,7 +65,7 @@ export function getRefinanceSimulation(params: { amount: sourcePosition.debtAmount, }, outputs: undefined, - } as steps.RepayFlashloan, + } as steps.RepayFlashloanStep, { name: 'ReturnFunds', type: SimulationSteps.ReturnFunds, @@ -73,7 +73,7 @@ export function getRefinanceSimulation(params: { token: sourcePosition.debtAmount.token, }, outputs: undefined, - } as steps.ReturnFunds, + } as steps.ReturnFundsStep, ], } } diff --git a/sdk/protocol-manager-service/tests/ProtocolManager.spec.ts b/sdk/protocol-manager-service/tests/ProtocolManager.spec.ts index 615444e62e..70431bcc69 100644 --- a/sdk/protocol-manager-service/tests/ProtocolManager.spec.ts +++ b/sdk/protocol-manager-service/tests/ProtocolManager.spec.ts @@ -15,6 +15,7 @@ import { PriceService, ProtocolPluginsRegistry, } from '@summerfi/protocol-plugins/implementation' +import { DeploymentIndex } from '@summerfi/deployment-utils' describe('Protocol Manager', () => { let ctx: IProtocolManagerContext @@ -31,6 +32,7 @@ describe('Protocol Manager', () => { pluginsRegistry = new ProtocolPluginsRegistry({ plugins: mockPlugins, context: ctx, + deploymentConfigTag: 'standard', }) protocolManager = new ProtocolManager({ pluginsRegistry }) }) @@ -71,6 +73,7 @@ describe('Protocol Manager', () => { const pluginsRegistry = new ProtocolPluginsRegistry({ plugins: mockPlugins, context: ctx, + deploymentConfigTag: 'standard', }) protocolManager = new ProtocolManager({ pluginsRegistry }) @@ -140,5 +143,6 @@ async function createProtocolManagerContext(): Promise provider, tokenService: new TokenService(), priceService: new PriceService(provider), + deployments: {} as DeploymentIndex, } } diff --git a/sdk/protocol-manager-service/tsconfig.json b/sdk/protocol-manager-service/tsconfig.json index 4553169f3a..21e449c7cc 100644 --- a/sdk/protocol-manager-service/tsconfig.json +++ b/sdk/protocol-manager-service/tsconfig.json @@ -5,7 +5,8 @@ "outDir": "dist", "baseUrl": ".", "paths": { - "@summerfi/protocol-plugins/*": ["node_modules/@summerfi/protocol-plugins/src/*"] + "@summerfi/protocol-plugins/*": ["node_modules/@summerfi/protocol-plugins/src/*"], + "@summerfi/deployment-utils": ["../../packages/deployment-utils/src/index.ts"] } }, "include": ["src/**/*.ts", "tests/**/*.ts"], diff --git a/sdk/protocol-manager-service/tsconfig.test.json b/sdk/protocol-manager-service/tsconfig.test.json index f50352d855..82cafa533c 100644 --- a/sdk/protocol-manager-service/tsconfig.test.json +++ b/sdk/protocol-manager-service/tsconfig.test.json @@ -11,7 +11,8 @@ "@summerfi/order-planner-common/*": ["node_modules/@summerfi/order-planner-common/src/*"], "@summerfi/protocol-plugins-common": [ "node_modules/@summerfi/protocol-plugins-common/src/index.ts" - ] + ], + "@summerfi/deployment-utils": ["../../packages/deployment-utils/src/index.ts"] } }, "include": ["src/**/*.ts"], diff --git a/sdk/protocol-plugins-common/src/interfaces/IProtocolPluginContext.ts b/sdk/protocol-plugins-common/src/interfaces/IProtocolPluginContext.ts index 85429a4621..ca108bdb96 100644 --- a/sdk/protocol-plugins-common/src/interfaces/IProtocolPluginContext.ts +++ b/sdk/protocol-plugins-common/src/interfaces/IProtocolPluginContext.ts @@ -1,11 +1,11 @@ import { PublicClient } from 'viem' import { IPriceService } from './IPriceService' import { ITokenService } from './ITokenService' -import { Deployment } from '@summerfi/deployment-utils' +import { DeploymentIndex } from '@summerfi/deployment-utils' export interface IProtocolPluginContext { provider: PublicClient tokenService: ITokenService priceService: IPriceService - deployment: Deployment + deployments: DeploymentIndex } diff --git a/sdk/protocol-plugins-common/tests/ExecutionStorageMapper.spec.ts b/sdk/protocol-plugins-common/tests/ExecutionStorageMapper.spec.ts index 2d3a85ed2b..3724c6cb41 100644 --- a/sdk/protocol-plugins-common/tests/ExecutionStorageMapper.spec.ts +++ b/sdk/protocol-plugins-common/tests/ExecutionStorageMapper.spec.ts @@ -417,7 +417,7 @@ describe('Execution Storage Mapper', () => { }) it('should use default value if step has no outputs defined', () => { - const derivedStep: steps.ReturnFunds = { + const derivedStep: steps.ReturnFundsStep = { type: SimulationSteps.ReturnFunds, name: 'ReturnFunds', inputs: { diff --git a/sdk/protocol-plugins/src/implementation/BaseProtocolPlugin.ts b/sdk/protocol-plugins/src/implementation/BaseProtocolPlugin.ts index d253817d55..2db9ee7dc1 100644 --- a/sdk/protocol-plugins/src/implementation/BaseProtocolPlugin.ts +++ b/sdk/protocol-plugins/src/implementation/BaseProtocolPlugin.ts @@ -26,9 +26,11 @@ export abstract class BaseProtocolPlugin implements IProtocolPlugin { /** These properties are initialized in the constructor */ readonly context: IProtocolPluginContext + readonly deploymentConfigTag: string - protected constructor(params: { context: IProtocolPluginContext }) { + protected constructor(params: { context: IProtocolPluginContext; deploymentConfigTag?: string }) { this.context = params.context + this.deploymentConfigTag = params.deploymentConfigTag ?? 'standard' } // Short alias for the context @@ -58,4 +60,8 @@ export abstract class BaseProtocolPlugin implements IProtocolPlugin { const { success } = schema.safeParse(candidate) return success } + + protected _getDeploymentKey(chainInfo: ChainInfo): string { + return `${chainInfo.name}.${this.deploymentConfigTag}` + } } diff --git a/sdk/protocol-plugins/src/implementation/ProtocolPluginsRegistry.ts b/sdk/protocol-plugins/src/implementation/ProtocolPluginsRegistry.ts index cc248a7ca5..06e2d14c9e 100644 --- a/sdk/protocol-plugins/src/implementation/ProtocolPluginsRegistry.ts +++ b/sdk/protocol-plugins/src/implementation/ProtocolPluginsRegistry.ts @@ -8,6 +8,7 @@ import { Maybe } from '@summerfi/sdk-common/common' export type ProtocolPluginConstructor = new (params: { context: IProtocolPluginContext + deploymentConfigTag: string }) => IProtocolPlugin export type ProtocolPluginsRecordType = Partial> @@ -15,10 +16,16 @@ export type ProtocolPluginsRecordType = Partial { @@ -26,6 +33,6 @@ export class ProtocolPluginsRegistry implements IProtocolPluginsRegistry { if (!Plugin) { return } - return new Plugin({ context: this.context }) + return new Plugin({ context: this.context, deploymentConfigTag: this.deploymentConfigTag }) } } diff --git a/sdk/protocol-plugins/src/plugins/aave-v3/implementation/AAVEv3ProtocolPlugin.ts b/sdk/protocol-plugins/src/plugins/aave-v3/implementation/AAVEv3ProtocolPlugin.ts index 600ba90ac1..49aa446c21 100644 --- a/sdk/protocol-plugins/src/plugins/aave-v3/implementation/AAVEv3ProtocolPlugin.ts +++ b/sdk/protocol-plugins/src/plugins/aave-v3/implementation/AAVEv3ProtocolPlugin.ts @@ -71,7 +71,7 @@ export class AaveV3ProtocolPlugin extends BaseProtocolPlugin { emodeType: z.nativeEnum(EmodeType), }) - constructor(params: { context: IProtocolPluginContext }) { + constructor(params: { context: IProtocolPluginContext; deploymentConfigTag?: string }) { super(params) } diff --git a/sdk/protocol-plugins/src/plugins/maker/implementation/MakerProtocolPlugin.ts b/sdk/protocol-plugins/src/plugins/maker/implementation/MakerProtocolPlugin.ts index 0afd7cb27e..ff8e9fd76e 100644 --- a/sdk/protocol-plugins/src/plugins/maker/implementation/MakerProtocolPlugin.ts +++ b/sdk/protocol-plugins/src/plugins/maker/implementation/MakerProtocolPlugin.ts @@ -43,9 +43,9 @@ import { import { ILKType } from '../enums/ILKType' import { MakerPoolId } from '../types/MakerPoolId' import { IUser } from '@summerfi/sdk-common/user' -import { IPositionsManager, TransactionInfo } from '@summerfi/sdk-common/orders' +import { IExternalPosition, IPositionsManager, TransactionInfo } from '@summerfi/sdk-common/orders' import { encodeMakerGiveThroughProxyActions } from '../utils/MakerGive' -import { MakerExternalPosition, isMakerExternalPosition } from '../types/MakerExternalPosition' +import { isMakerExternalPosition } from '../types/MakerExternalPosition' export class MakerProtocolPlugin extends BaseProtocolPlugin { readonly CdpManagerContractName = 'CdpManager' @@ -72,7 +72,7 @@ export class MakerProtocolPlugin extends BaseProtocolPlugin { [SimulationSteps.PaybackWithdraw]: MakerPaybackWithdrawActionBuilder, } - constructor(params: { context: IProtocolPluginContext }) { + constructor(params: { context: IProtocolPluginContext; deploymentConfigTag?: string }) { super(params) } @@ -224,19 +224,22 @@ export class MakerProtocolPlugin extends BaseProtocolPlugin { async getImportPositionTransaction(params: { user: IUser - position: MakerExternalPosition + position: IExternalPosition positionsManager: IPositionsManager }): Promise> { if (!isMakerExternalPosition(params.position)) { throw new Error('Invalid Maker external position') } - const cdpManagerAddress = this.context.deployment.dependencies[this.CdpManagerContractName] + const { deployments } = this.ctx + const deploymentKey = this._getDeploymentKey(params.user.chainInfo) + const deployment = deployments[deploymentKey] + + const cdpManagerAddress = deployment.dependencies[this.CdpManagerContractName] .address as AddressValue - const dssProxyActionsAddress = this.context.deployment.dependencies[ - this.DssProxyActionsContractName - ].address as AddressValue + const dssProxyActionsAddress = deployment.dependencies[this.DssProxyActionsContractName] + .address as AddressValue const result = encodeMakerGiveThroughProxyActions({ cdpManagerAddress: cdpManagerAddress, diff --git a/sdk/protocol-plugins/src/plugins/maker/types/MakerExternalPosition.ts b/sdk/protocol-plugins/src/plugins/maker/types/MakerExternalPosition.ts index e90b019e3b..1cca386558 100644 --- a/sdk/protocol-plugins/src/plugins/maker/types/MakerExternalPosition.ts +++ b/sdk/protocol-plugins/src/plugins/maker/types/MakerExternalPosition.ts @@ -1,6 +1,5 @@ import { Address } from '@summerfi/sdk-common/common' -import { IExternalPosition } from '@summerfi/sdk-common/orders' -import { isExternalPosition } from 'node_modules/@summerfi/sdk-common/src/orders/interfaces/importing/IExternalPosition' +import { IExternalPosition, isExternalPosition } from '@summerfi/sdk-common/orders' export interface MakerExternalPosition extends IExternalPosition { dsProxyAddress: Address diff --git a/sdk/protocol-plugins/src/plugins/spark/implementation/SparkProtocolPlugin.ts b/sdk/protocol-plugins/src/plugins/spark/implementation/SparkProtocolPlugin.ts index f1cf0cb2e8..2e7b0854b1 100644 --- a/sdk/protocol-plugins/src/plugins/spark/implementation/SparkProtocolPlugin.ts +++ b/sdk/protocol-plugins/src/plugins/spark/implementation/SparkProtocolPlugin.ts @@ -74,7 +74,7 @@ export class SparkProtocolPlugin extends BaseProtocolPlugin { [SimulationSteps.DepositBorrow]: SparkDepositBorrowActionBuilder, } - constructor(params: { context: IProtocolPluginContext }) { + constructor(params: { context: IProtocolPluginContext; deploymentConfigTag?: string }) { super(params) } diff --git a/sdk/protocol-plugins/tests/utils/CreateProtocolPluginContext.ts b/sdk/protocol-plugins/tests/utils/CreateProtocolPluginContext.ts index ffa3b60c3b..65292efebe 100644 --- a/sdk/protocol-plugins/tests/utils/CreateProtocolPluginContext.ts +++ b/sdk/protocol-plugins/tests/utils/CreateProtocolPluginContext.ts @@ -1,8 +1,8 @@ import { IProtocolPluginContext } from '@summerfi/protocol-plugins-common' import { createPublicClient, http, PublicClient } from 'viem' import { mainnet } from 'viem/chains' -// import { MockContractProvider } from '../../src/mocks/mockContractProvider' import { TokenService, PriceService } from '../../src/implementation' +import { SetupDeployments } from './SetupDeployments' export async function createProtocolPluginContext( __ctxOverrides?: Partial, @@ -20,6 +20,7 @@ export async function createProtocolPluginContext( provider, tokenService: new TokenService(), priceService: new PriceService(provider), + deployments: SetupDeployments(), } if (__ctxOverrides) { diff --git a/sdk/sdk-common/src/orders/interfaces/importing/index.ts b/sdk/sdk-common/src/orders/interfaces/importing/index.ts index 12092ffae7..de16592b4a 100644 --- a/sdk/sdk-common/src/orders/interfaces/importing/index.ts +++ b/sdk/sdk-common/src/orders/interfaces/importing/index.ts @@ -1,3 +1,3 @@ -export type { IExternalPosition } from './IExternalPosition' +export { type IExternalPosition, isExternalPosition } from './IExternalPosition' export type { ImportPositionParameters } from './ImportPositionParameters' export type { ImportPositionSimulation } from './ImportPositionSimulation' diff --git a/sdk/sdk-e2e/tests/refinanceMakerSpark.test.ts b/sdk/sdk-e2e/tests/refinanceMakerSpark.test.ts index ed29fd7651..6739688ffd 100644 --- a/sdk/sdk-e2e/tests/refinanceMakerSpark.test.ts +++ b/sdk/sdk-e2e/tests/refinanceMakerSpark.test.ts @@ -53,7 +53,7 @@ jest.setTimeout(300000) const SDKAPiUrl = 'https://zmjmtfsocb.execute-api.us-east-1.amazonaws.com/api/sdk' const TenderlyForkUrl = 'https://rpc.tenderly.co/fork/50e01944-8635-4d67-9569-004d72113328' -describe('Refinance Maker Spark | SDK', () => { +describe.skip('Refinance Maker Spark | SDK', () => { it('should allow refinance Maker -> Spark with same pair', async () => { // SDK const sdk = makeSDK({ apiURL: SDKAPiUrl }) diff --git a/sdk/sdk-server/src/context/Context.ts b/sdk/sdk-server/src/context/Context.ts index fed6ec67d1..89034c2a3f 100644 --- a/sdk/sdk-server/src/context/Context.ts +++ b/sdk/sdk-server/src/context/Context.ts @@ -29,7 +29,9 @@ export const createSDKContext = (opts: ContextOptions): SDKAppContext => { const configProvider = new ConfigurationProvider() const orderPlannerService = new OrderPlannerService({ deployments }) const swapManager = SwapManagerFactory.newSwapManager({ configProvider }) - const protocolsRegistry = createProtocolsPluginsRegistry() + const protocolsRegistry = createProtocolsPluginsRegistry({ + deployments, + }) const protocolManager = new ProtocolManager({ pluginsRegistry: protocolsRegistry }) return { diff --git a/sdk/sdk-server/src/context/CreateProtocolPluginsRegistry.ts b/sdk/sdk-server/src/context/CreateProtocolPluginsRegistry.ts index 591c9adcb5..291ef68b47 100644 --- a/sdk/sdk-server/src/context/CreateProtocolPluginsRegistry.ts +++ b/sdk/sdk-server/src/context/CreateProtocolPluginsRegistry.ts @@ -12,6 +12,7 @@ import { IProtocolPluginsRegistry } from '@summerfi/protocol-plugins-common' import { ProtocolName } from '@summerfi/sdk-common/protocols' import { createPublicClient, http } from 'viem' import { mainnet } from 'viem/chains' +import { DeploymentIndex } from '@summerfi/deployment-utils' const ProtocolPlugins: ProtocolPluginsRecordType = { [ProtocolName.Maker]: MakerProtocolPlugin, @@ -19,7 +20,11 @@ const ProtocolPlugins: ProtocolPluginsRecordType = { [ProtocolName.AAVEv3]: AaveV3ProtocolPlugin, } -export function createProtocolsPluginsRegistry(): IProtocolPluginsRegistry { +export function createProtocolsPluginsRegistry(params: { + deployments: DeploymentIndex +}): IProtocolPluginsRegistry { + const { deployments } = params + const provider = createPublicClient({ batch: { multicall: true, @@ -37,6 +42,8 @@ export function createProtocolsPluginsRegistry(): IProtocolPluginsRegistry { provider, tokenService, priceService, + deployments, }, + deploymentConfigTag: 'standard', }) } diff --git a/sdk/simulator-service/tests/simulator.test.ts b/sdk/simulator-service/tests/simulator.test.ts index ac211a1de8..05ec078b2b 100644 --- a/sdk/simulator-service/tests/simulator.test.ts +++ b/sdk/simulator-service/tests/simulator.test.ts @@ -75,7 +75,7 @@ describe('Refinance', () => { it('should include a new position event step', async () => { const newPositionStep = simulation.steps.find( (step) => step.type === SimulationSteps.NewPositionEvent, - ) as steps.NewPositionEvent + ) as steps.NewPositionEventStep assert(newPositionStep, 'New position event step not found') expect(newPositionStep.inputs.position).toEqual(simulation.targetPosition) From ffa855d7a8a0d5829d52a378ea059898ad696d98 Mon Sep 17 00:00:00 2001 From: Damian Paszkowski Date: Fri, 12 Apr 2024 11:19:12 +0200 Subject: [PATCH 14/24] feat: rpc query --- sdk/sdk-server/src/SDKAppRouter.ts | 3 ++- .../src/handlers/getImportSimulation.ts | 17 +++++++++++++++++ .../src/strategies/import/ImportPosition.ts | 1 - .../src/strategies/import/index.ts | 2 ++ sdk/simulator-service/src/strategies/index.ts | 1 + 5 files changed, 22 insertions(+), 2 deletions(-) create mode 100644 sdk/sdk-server/src/handlers/getImportSimulation.ts create mode 100644 sdk/simulator-service/src/strategies/import/index.ts diff --git a/sdk/sdk-server/src/SDKAppRouter.ts b/sdk/sdk-server/src/SDKAppRouter.ts index cc9c8c0268..4312ef2610 100644 --- a/sdk/sdk-server/src/SDKAppRouter.ts +++ b/sdk/sdk-server/src/SDKAppRouter.ts @@ -6,6 +6,7 @@ import { getToken } from './handlers/getToken' import { getSwapDataExactInput } from './handlers/getSwapData' import { getSwapQuoteExactInput } from './handlers/getSwapQuote' import { router } from './TRPC' +import { getImportSimulation } from './handlers/getImportSimulation' /** * Server @@ -14,7 +15,7 @@ export const sdkAppRouter = router({ getPosition: getPosition, getPool: getPool, getToken: getToken, - simulation: { refinance: getRefinanceSimulation }, + simulation: { refinance: getRefinanceSimulation, import: getImportSimulation }, orders: { buildOrder: buildOrder, }, diff --git a/sdk/sdk-server/src/handlers/getImportSimulation.ts b/sdk/sdk-server/src/handlers/getImportSimulation.ts new file mode 100644 index 0000000000..22e9a19cf2 --- /dev/null +++ b/sdk/sdk-server/src/handlers/getImportSimulation.ts @@ -0,0 +1,17 @@ +import { z } from 'zod' +import type { ISimulation, SimulationType } from '@summerfi/sdk-common/simulation' +import { + importPosition, +} from '@summerfi/simulator-service/strategies' +import type { ImportPositionParameters } from '@summerfi/sdk-common/orders' +import { publicProcedure } from '../TRPC' + +const inputSchema = z.custom((parameters) => parameters !== undefined) + +export const getImportSimulation = publicProcedure + .input(inputSchema) + .query(async (opts): Promise> => { + const args: ImportPositionParameters = opts.input + + return await importPosition(args) + }) diff --git a/sdk/simulator-service/src/strategies/import/ImportPosition.ts b/sdk/simulator-service/src/strategies/import/ImportPosition.ts index 1104a64a7b..92b05d1c71 100644 --- a/sdk/simulator-service/src/strategies/import/ImportPosition.ts +++ b/sdk/simulator-service/src/strategies/import/ImportPosition.ts @@ -10,7 +10,6 @@ import { importPositionStrategy } from './Strategy' export async function importPosition( args: ImportPositionParameters, - dependencies: {}, ): Promise> { const simulator = Simulator.create(importPositionStrategy) diff --git a/sdk/simulator-service/src/strategies/import/index.ts b/sdk/simulator-service/src/strategies/import/index.ts new file mode 100644 index 0000000000..636dfb8c40 --- /dev/null +++ b/sdk/simulator-service/src/strategies/import/index.ts @@ -0,0 +1,2 @@ +export * from './ImportPosition' +export * from './Strategy' \ No newline at end of file diff --git a/sdk/simulator-service/src/strategies/index.ts b/sdk/simulator-service/src/strategies/index.ts index 3c006d5c2d..4b30d66ff3 100644 --- a/sdk/simulator-service/src/strategies/index.ts +++ b/sdk/simulator-service/src/strategies/index.ts @@ -1,3 +1,4 @@ export * from './refinanceSamePair' export * from './refinanceAnyPair' export * from './common' +export * from './import' From cb3079dc71cc8b0169b310ebc46ce5d8cd79b617 Mon Sep 17 00:00:00 2001 From: Roberto Cano <3525807+robercano@users.noreply.github.com> Date: Fri, 12 Apr 2024 11:38:45 +0200 Subject: [PATCH 15/24] fix: build --- .../simulator-engine/reducer/importReducer.ts | 6 +----- .../src/strategies/import/ImportPosition.ts | 8 +------- 2 files changed, 2 insertions(+), 12 deletions(-) diff --git a/sdk/simulator-service/src/implementation/simulator-engine/reducer/importReducer.ts b/sdk/simulator-service/src/implementation/simulator-engine/reducer/importReducer.ts index 4dc7578821..793f7a61e9 100644 --- a/sdk/simulator-service/src/implementation/simulator-engine/reducer/importReducer.ts +++ b/sdk/simulator-service/src/implementation/simulator-engine/reducer/importReducer.ts @@ -1,10 +1,6 @@ import { steps } from '@summerfi/sdk-common/simulation' -import { addBalance } from '../../utils' import { ISimulationState } from '../../../interfaces/simulation' -export function importReducer( - _step: steps.ImportStep, - state: ISimulationState, -): ISimulationState { +export function importReducer(_step: steps.ImportStep, state: ISimulationState): ISimulationState { return state } diff --git a/sdk/simulator-service/src/strategies/import/ImportPosition.ts b/sdk/simulator-service/src/strategies/import/ImportPosition.ts index 1104a64a7b..05dae4ff7d 100644 --- a/sdk/simulator-service/src/strategies/import/ImportPosition.ts +++ b/sdk/simulator-service/src/strategies/import/ImportPosition.ts @@ -1,16 +1,10 @@ -import { - ISimulation, - SimulationSteps, - SimulationType, -} from '@summerfi/sdk-common/simulation' +import { ISimulation, SimulationSteps, SimulationType } from '@summerfi/sdk-common/simulation' import { Simulator } from '../../implementation/simulator-engine' import { ImportPositionParameters } from '@summerfi/sdk-common/orders' import { importPositionStrategy } from './Strategy' - export async function importPosition( args: ImportPositionParameters, - dependencies: {}, ): Promise> { const simulator = Simulator.create(importPositionStrategy) From eaa80561af4e70d91e1e2fa76b8d4731bb339a82 Mon Sep 17 00:00:00 2001 From: Damian Paszkowski Date: Fri, 12 Apr 2024 11:42:27 +0200 Subject: [PATCH 16/24] chore: format and fix --- sdk/order-planner-service/src/config/Config.ts | 9 +++++++-- .../src/orders/interfaces/common/Order.ts | 2 +- .../interfaces/importing/ExternalPosition.ts | 16 ++++++++-------- sdk/sdk-common/src/simulation/Steps.ts | 5 +++-- .../src/handlers/getImportSimulation.ts | 4 +--- .../simulator-engine/reducer/importReducer.ts | 6 +----- .../src/strategies/import/ImportPosition.ts | 7 +------ .../src/strategies/import/index.ts | 2 +- 8 files changed, 23 insertions(+), 28 deletions(-) diff --git a/sdk/order-planner-service/src/config/Config.ts b/sdk/order-planner-service/src/config/Config.ts index 03657eb3cc..0b92bcf4c0 100644 --- a/sdk/order-planner-service/src/config/Config.ts +++ b/sdk/order-planner-service/src/config/Config.ts @@ -1,5 +1,5 @@ -import { SimulationSteps } from '@summerfi/sdk-common/simulation' -import { ActionBuildersMap } from '@summerfi/protocol-plugins-common' +import { SimulationSteps, steps } from '@summerfi/sdk-common/simulation' +import { ActionBuilder, ActionBuildersMap } from '@summerfi/protocol-plugins-common' import { DepositBorrowActionBuilder, FlashloanActionBuilder, @@ -11,6 +11,10 @@ import { SwapActionBuilder, } from '@summerfi/protocol-plugins/plugins/common' +const ActionBuilderNotImplemented: ActionBuilder = () => { + throw new Error('Action builder Import not implemented') +} + export const ActionBuildersConfig: ActionBuildersMap = { [SimulationSteps.PullToken]: PullTokenActionBuilder, [SimulationSteps.Flashloan]: FlashloanActionBuilder, @@ -20,4 +24,5 @@ export const ActionBuildersConfig: ActionBuildersMap = { [SimulationSteps.PaybackWithdraw]: PaybackWithdrawActionBuilder, [SimulationSteps.ReturnFunds]: ReturnFundsActionBuilder, [SimulationSteps.NewPositionEvent]: PositionCreatedActionBuilder, + [SimulationSteps.Import]: ActionBuilderNotImplemented, } diff --git a/sdk/sdk-common/src/orders/interfaces/common/Order.ts b/sdk/sdk-common/src/orders/interfaces/common/Order.ts index 6d65289066..1d55ac4075 100644 --- a/sdk/sdk-common/src/orders/interfaces/common/Order.ts +++ b/sdk/sdk-common/src/orders/interfaces/common/Order.ts @@ -1,4 +1,4 @@ -import { ISimulation } from '../../../simulation' +import { ISimulation } from '../../../simulation/Simulation' import { SimulationType } from '../../../simulation/Enums' import { TransactionInfo } from './TransactionInfo' diff --git a/sdk/sdk-common/src/orders/interfaces/importing/ExternalPosition.ts b/sdk/sdk-common/src/orders/interfaces/importing/ExternalPosition.ts index e711a97aee..3595f79805 100644 --- a/sdk/sdk-common/src/orders/interfaces/importing/ExternalPosition.ts +++ b/sdk/sdk-common/src/orders/interfaces/importing/ExternalPosition.ts @@ -1,13 +1,13 @@ -import { Address, Position } from "src/common"; +import { Address, Position } from '../../../common' export enum ExternalPositionType { - WALLET = 'WALLET', - DS_PROXY = 'DS_PROXY', - } - + WALLET = 'WALLET', + DS_PROXY = 'DS_PROXY', +} + export interface ExternalPositionId { - type: ExternalPositionType - address: Address + type: ExternalPositionType + address: Address } /** @@ -15,7 +15,7 @@ export interface ExternalPositionId { * @description Position existing in another service. This will be specialized into the IDs for the * different services. */ -export interface ExternalPosition { +export interface ExternalPosition { position: Position externalId: ExternalPositionId } diff --git a/sdk/sdk-common/src/simulation/Steps.ts b/sdk/sdk-common/src/simulation/Steps.ts index d7ca503a3f..4b3457587b 100644 --- a/sdk/sdk-common/src/simulation/Steps.ts +++ b/sdk/sdk-common/src/simulation/Steps.ts @@ -6,7 +6,7 @@ import { TokenAmount } from '../common/implementation/TokenAmount' import { FlashloanProvider, SimulationSteps, TokenTransferTargetType } from './Enums' import { SwapProviderType, SwapRoute } from '../swap' import { ReferenceableField, ValueReference } from './ValueReference' -import { ExternalPosition } from 'src/orders' +import { ExternalPosition } from '../orders' export interface Step { type: T @@ -85,7 +85,8 @@ export interface RepayFlashloan } > {} -export interface ImportStep extends Step {} +export interface ImportStep + extends Step {} export interface NewPositionEvent extends Step< SimulationSteps.NewPositionEvent, diff --git a/sdk/sdk-server/src/handlers/getImportSimulation.ts b/sdk/sdk-server/src/handlers/getImportSimulation.ts index 22e9a19cf2..a7a875ebe2 100644 --- a/sdk/sdk-server/src/handlers/getImportSimulation.ts +++ b/sdk/sdk-server/src/handlers/getImportSimulation.ts @@ -1,8 +1,6 @@ import { z } from 'zod' import type { ISimulation, SimulationType } from '@summerfi/sdk-common/simulation' -import { - importPosition, -} from '@summerfi/simulator-service/strategies' +import { importPosition } from '@summerfi/simulator-service/strategies' import type { ImportPositionParameters } from '@summerfi/sdk-common/orders' import { publicProcedure } from '../TRPC' diff --git a/sdk/simulator-service/src/implementation/simulator-engine/reducer/importReducer.ts b/sdk/simulator-service/src/implementation/simulator-engine/reducer/importReducer.ts index 4dc7578821..793f7a61e9 100644 --- a/sdk/simulator-service/src/implementation/simulator-engine/reducer/importReducer.ts +++ b/sdk/simulator-service/src/implementation/simulator-engine/reducer/importReducer.ts @@ -1,10 +1,6 @@ import { steps } from '@summerfi/sdk-common/simulation' -import { addBalance } from '../../utils' import { ISimulationState } from '../../../interfaces/simulation' -export function importReducer( - _step: steps.ImportStep, - state: ISimulationState, -): ISimulationState { +export function importReducer(_step: steps.ImportStep, state: ISimulationState): ISimulationState { return state } diff --git a/sdk/simulator-service/src/strategies/import/ImportPosition.ts b/sdk/simulator-service/src/strategies/import/ImportPosition.ts index 92b05d1c71..05dae4ff7d 100644 --- a/sdk/simulator-service/src/strategies/import/ImportPosition.ts +++ b/sdk/simulator-service/src/strategies/import/ImportPosition.ts @@ -1,13 +1,8 @@ -import { - ISimulation, - SimulationSteps, - SimulationType, -} from '@summerfi/sdk-common/simulation' +import { ISimulation, SimulationSteps, SimulationType } from '@summerfi/sdk-common/simulation' import { Simulator } from '../../implementation/simulator-engine' import { ImportPositionParameters } from '@summerfi/sdk-common/orders' import { importPositionStrategy } from './Strategy' - export async function importPosition( args: ImportPositionParameters, ): Promise> { diff --git a/sdk/simulator-service/src/strategies/import/index.ts b/sdk/simulator-service/src/strategies/import/index.ts index 636dfb8c40..b009e308cc 100644 --- a/sdk/simulator-service/src/strategies/import/index.ts +++ b/sdk/simulator-service/src/strategies/import/index.ts @@ -1,2 +1,2 @@ export * from './ImportPosition' -export * from './Strategy' \ No newline at end of file +export * from './Strategy' From ae48ec63636a4f73534312f0dee319aad46a0360 Mon Sep 17 00:00:00 2001 From: Damian Paszkowski Date: Fri, 12 Apr 2024 12:32:49 +0200 Subject: [PATCH 17/24] chore: changes names --- .../src/orders/interfaces/importing/ExternalPosition.ts | 8 ++++---- .../interfaces/importing/ImportPositionParameters.ts | 6 +++--- sdk/sdk-common/src/orders/interfaces/importing/index.ts | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/sdk/sdk-common/src/orders/interfaces/importing/ExternalPosition.ts b/sdk/sdk-common/src/orders/interfaces/importing/ExternalPosition.ts index 3595f79805..347c0d8819 100644 --- a/sdk/sdk-common/src/orders/interfaces/importing/ExternalPosition.ts +++ b/sdk/sdk-common/src/orders/interfaces/importing/ExternalPosition.ts @@ -1,4 +1,4 @@ -import { Address, Position } from '../../../common' +import { Address, IPosition } from '../../../common' export enum ExternalPositionType { WALLET = 'WALLET', @@ -11,11 +11,11 @@ export interface ExternalPositionId { } /** - * @interface ExternalPosition + * @interface IExternalPosition * @description Position existing in another service. This will be specialized into the IDs for the * different services. */ -export interface ExternalPosition { - position: Position +export interface IExternalPosition { + position: IPosition externalId: ExternalPositionId } diff --git a/sdk/sdk-common/src/orders/interfaces/importing/ImportPositionParameters.ts b/sdk/sdk-common/src/orders/interfaces/importing/ImportPositionParameters.ts index 4d20baf7db..8c6f09aaea 100644 --- a/sdk/sdk-common/src/orders/interfaces/importing/ImportPositionParameters.ts +++ b/sdk/sdk-common/src/orders/interfaces/importing/ImportPositionParameters.ts @@ -1,10 +1,10 @@ -import { ExternalPosition } from './ExternalPosition' +import { IExternalPosition } from './ExternalPosition' /** * @interface ImportPositionParameters * @description Parameters used to import a position from another service */ -export interface ImportPositionParameters { +export interface IImportPositionParameters { /** External position to be imported */ - externalPosition: ExternalPosition + externalPosition: IExternalPosition } diff --git a/sdk/sdk-common/src/orders/interfaces/importing/index.ts b/sdk/sdk-common/src/orders/interfaces/importing/index.ts index b08d6f2bcb..78f27a4439 100644 --- a/sdk/sdk-common/src/orders/interfaces/importing/index.ts +++ b/sdk/sdk-common/src/orders/interfaces/importing/index.ts @@ -1,3 +1,3 @@ -export type { ExternalPosition } from './ExternalPosition' -export type { ImportPositionParameters } from './ImportPositionParameters' +export type { IExternalPosition as ExternalPosition } from './ExternalPosition' +export type { IImportPositionParameters as ImportPositionParameters } from './ImportPositionParameters' export type { ImportPositionSimulation } from './ImportPositionSimulation' From 157b297452089ce35da9f04e7d9a10c8d7e36546 Mon Sep 17 00:00:00 2001 From: Roberto Cano <3525807+robercano@users.noreply.github.com> Date: Fri, 12 Apr 2024 14:46:51 +0200 Subject: [PATCH 18/24] wip: test import simulation --- .../simulations/ImportingSimulationManager.ts | 36 ++++ .../simulations/SimulationManager.ts | 4 +- .../interfaces/importing/IExternalPosition.ts | 5 +- ...meters.ts => IImportPositionParameters.ts} | 4 +- .../src/orders/interfaces/importing/index.ts | 8 +- .../refinance/RefinanceParameters.ts | 21 --- .../tests/importExternalPosition.test.ts | 177 ++++++++++++++++++ .../src/handlers/getImportSimulation.ts | 10 +- .../src/strategies/import/ImportPosition.ts | 5 +- .../src/implementation/SwapManagerFactory.ts | 2 +- 10 files changed, 234 insertions(+), 38 deletions(-) create mode 100644 sdk/sdk-client/src/implementation/simulations/ImportingSimulationManager.ts rename sdk/sdk-common/src/orders/interfaces/importing/{ImportPositionParameters.ts => IImportPositionParameters.ts} (72%) delete mode 100644 sdk/sdk-common/src/orders/interfaces/refinance/RefinanceParameters.ts create mode 100644 sdk/sdk-e2e/tests/importExternalPosition.test.ts diff --git a/sdk/sdk-client/src/implementation/simulations/ImportingSimulationManager.ts b/sdk/sdk-client/src/implementation/simulations/ImportingSimulationManager.ts new file mode 100644 index 0000000000..276f673b50 --- /dev/null +++ b/sdk/sdk-client/src/implementation/simulations/ImportingSimulationManager.ts @@ -0,0 +1,36 @@ +import { IImportPositionParameters } from '@summerfi/sdk-common/orders' +import { ISimulation, SimulationType } from '@summerfi/sdk-common/simulation' +import { RPCClientType } from '../../rpc/SDKClient' +import { IRPCClient } from '../../interfaces/IRPCClient' + +export class ImportingSimulationManager extends IRPCClient { + constructor(params: { rpcClient: RPCClientType }) { + super(params) + } + + public async simulateImportPosition( + params: IImportPositionParameters, + ): Promise> { + const importPositionParameters: IImportPositionParameters = { + externalPosition: { + position: { + type: params.externalPosition.position.type, + positionId: params.externalPosition.position.positionId, + debtAmount: params.externalPosition.position.debtAmount, + collateralAmount: params.externalPosition.position.collateralAmount, + pool: { + poolId: params.externalPosition.position.pool.poolId, + protocol: params.externalPosition.position.pool.protocol, + type: params.externalPosition.position.pool.type, + }, + }, + externalId: { + type: params.externalPosition.externalId.type, + address: params.externalPosition.externalId.address, + }, + }, + } + + return this.rpcClient.simulation.import.query(importPositionParameters) + } +} diff --git a/sdk/sdk-client/src/implementation/simulations/SimulationManager.ts b/sdk/sdk-client/src/implementation/simulations/SimulationManager.ts index 852ee7e960..bcdc156cbd 100644 --- a/sdk/sdk-client/src/implementation/simulations/SimulationManager.ts +++ b/sdk/sdk-client/src/implementation/simulations/SimulationManager.ts @@ -1,14 +1,16 @@ import { RPCClientType } from '../../rpc/SDKClient' +import { ImportingSimulationManager } from './ImportingSimulationManager' import { RefinanceSimulationManager } from './RefinanceSimulationManager' export class SimulationManager { public readonly finance: undefined public readonly refinance: RefinanceSimulationManager public readonly automation: undefined - public readonly importing: undefined + public readonly importing: ImportingSimulationManager public readonly migration: undefined public constructor(params: { rpcClient: RPCClientType }) { this.refinance = new RefinanceSimulationManager(params) + this.importing = new ImportingSimulationManager(params) } } diff --git a/sdk/sdk-common/src/orders/interfaces/importing/IExternalPosition.ts b/sdk/sdk-common/src/orders/interfaces/importing/IExternalPosition.ts index 3794aa0d69..d2f1b23c9e 100644 --- a/sdk/sdk-common/src/orders/interfaces/importing/IExternalPosition.ts +++ b/sdk/sdk-common/src/orders/interfaces/importing/IExternalPosition.ts @@ -1,6 +1,5 @@ -import { isPosition } from '../../../common' +import { IPosition, isPosition } from '../../../common' import { Address } from '../../../common/implementation/Address' -import { Position } from '../../../common/implementation/Position' export enum ExternalPositionType { WALLET = 'WALLET', @@ -24,7 +23,7 @@ export function isExternalPositionId(maybeId: unknown): maybeId is IExternalPosi * different services. */ export interface IExternalPosition { - position: Position + position: IPosition externalId: IExternalPositionId } diff --git a/sdk/sdk-common/src/orders/interfaces/importing/ImportPositionParameters.ts b/sdk/sdk-common/src/orders/interfaces/importing/IImportPositionParameters.ts similarity index 72% rename from sdk/sdk-common/src/orders/interfaces/importing/ImportPositionParameters.ts rename to sdk/sdk-common/src/orders/interfaces/importing/IImportPositionParameters.ts index c449c0f147..04c4a0e434 100644 --- a/sdk/sdk-common/src/orders/interfaces/importing/ImportPositionParameters.ts +++ b/sdk/sdk-common/src/orders/interfaces/importing/IImportPositionParameters.ts @@ -1,10 +1,10 @@ import { IExternalPosition } from './IExternalPosition' /** - * @interface ImportPositionParameters + * @interface IImportPositionParameters * @description Parameters used to import a position from another service */ -export interface ImportPositionParameters { +export interface IImportPositionParameters { /** External position to be imported */ externalPosition: IExternalPosition } diff --git a/sdk/sdk-common/src/orders/interfaces/importing/index.ts b/sdk/sdk-common/src/orders/interfaces/importing/index.ts index de16592b4a..54d3472696 100644 --- a/sdk/sdk-common/src/orders/interfaces/importing/index.ts +++ b/sdk/sdk-common/src/orders/interfaces/importing/index.ts @@ -1,3 +1,7 @@ -export { type IExternalPosition, isExternalPosition } from './IExternalPosition' -export type { ImportPositionParameters } from './ImportPositionParameters' +export { + type IExternalPosition, + isExternalPosition, + ExternalPositionType, +} from './IExternalPosition' +export type { IImportPositionParameters } from './IImportPositionParameters' export type { ImportPositionSimulation } from './ImportPositionSimulation' diff --git a/sdk/sdk-common/src/orders/interfaces/refinance/RefinanceParameters.ts b/sdk/sdk-common/src/orders/interfaces/refinance/RefinanceParameters.ts deleted file mode 100644 index 6ec48f0eb3..0000000000 --- a/sdk/sdk-common/src/orders/interfaces/refinance/RefinanceParameters.ts +++ /dev/null @@ -1,21 +0,0 @@ -import type { Percentage } from '../../../common/implementation/Percentage' -import type { Position } from '../../../common/implementation/Position' -// import type { Address } from '../../../common/implementation/Address' -import type { LendingPool } from '../../../protocols/implementation/LendingPool' - -/** - * @interface RefinanceParameters - * @description Parameters used to refinance a position - */ -export interface RefinanceParameters { - position: Position - targetPool: LendingPool - // TODO: Implement means of determining if a swap is required. Follow-up PR - // targetCollateral: Address - // targetDebt: Address - slippage: Percentage -} - -export function isRefinanceParameters(parameters: unknown): parameters is RefinanceParameters { - return typeof parameters === 'object' && parameters !== null && 'slippage' in parameters -} diff --git a/sdk/sdk-e2e/tests/importExternalPosition.test.ts b/sdk/sdk-e2e/tests/importExternalPosition.test.ts new file mode 100644 index 0000000000..46d45a19f4 --- /dev/null +++ b/sdk/sdk-e2e/tests/importExternalPosition.test.ts @@ -0,0 +1,177 @@ +import { + PositionId, + Token, + TokenAmount, + Position, + Address, + type Maybe, + ChainFamilyMap, + AddressValue, + PositionType, +} from '@summerfi/sdk-common/common' + +import { ProtocolName, isLendingPool } from '@summerfi/sdk-common/protocols' +import { makeSDK, type Chain, type User } from '@summerfi/sdk-client' +import { TokenSymbol } from '@summerfi/sdk-common/common/enums' +import { + ExternalPositionType, + IImportPositionParameters, + IPositionsManager, + Order, +} from '@summerfi/sdk-common/orders' +import { ISimulation, SimulationSteps, SimulationType } from '@summerfi/sdk-common/simulation' +import { Deployments } from '@summerfi/core-contracts' +import { DeploymentIndex } from '@summerfi/deployment-utils' + +import assert from 'assert' +import { ILKType, MakerPoolId } from '@summerfi/protocol-plugins/plugins/maker' + +jest.setTimeout(300000) + +const SDKAPiUrl = 'https://zmjmtfsocb.execute-api.us-east-1.amazonaws.com/api/sdk' +const TenderlyForkUrl = + 'https://virtual.mainnet.rpc.tenderly.co/75405d76-cb49-41c4-8624-e47966ee7969' + +describe('Import Maker Position | SDK', () => { + it('should allow refinance Maker -> Spark with same pair', async () => { + // SDK + const sdk = makeSDK({ apiURL: SDKAPiUrl }) + + // Chain + const chain: Maybe = await sdk.chains.getChain({ + chainInfo: ChainFamilyMap.Ethereum.Mainnet, + }) + + assert(chain, 'Chain not found') + + // Deployment + const deploymentName = `${chain.chainInfo.name}.standard` + const deployments = Deployments as DeploymentIndex + const deployment = deployments[deploymentName] + + // Strategy Executor + const strategyExecutorAddress = Address.createFromEthereum({ + value: deployment.contracts.OperationExecutor.address as AddressValue, + }) + + // User + const walletAddress = Address.createFromEthereum({ + value: '0xbEf4befb4F230F43905313077e3824d7386E09F8', + }) + const user: User = await sdk.users.getUser({ + chainInfo: chain.chainInfo, + walletAddress: walletAddress, + }) + expect(user).toBeDefined() + expect(user.wallet.address).toEqual(walletAddress) + expect(user.chainInfo).toEqual(chain.chainInfo) + + // Positions Manager + const positionsManager: IPositionsManager = { + address: Address.createFromEthereum({ + value: '0x551Eb8395093fDE4B9eeF017C93593a3C7a75138', + }), + } + + // Tokens + const WETH: Maybe = await chain.tokens.getTokenBySymbol({ symbol: TokenSymbol.WETH }) + assert(WETH, 'WETH not found') + + const DAI: Maybe = await chain.tokens.getTokenBySymbol({ symbol: TokenSymbol.DAI }) + assert(DAI, 'DAI not found') + + const maker = await chain.protocols.getProtocol({ name: ProtocolName.Maker }) + assert(maker, 'Maker protocol not found') + + const makerPoolId: MakerPoolId = { + protocol: { + name: ProtocolName.Maker, + chainInfo: chain.chainInfo, + }, + ilkType: ILKType.ETH_C, + vaultId: '31646', + } + + const makerPool = await maker.getPool({ + poolId: makerPoolId, + }) + assert(makerPool, 'Maker pool not found') + + if (!isLendingPool(makerPool)) { + assert(false, 'Maker pool type is not lending') + } + + // Source position + const makerPosition: Position = Position.createFrom({ + type: PositionType.Multiply, + positionId: PositionId.createFrom({ id: '31646' }), + debtAmount: TokenAmount.createFromBaseUnit({ + token: DAI, + amount: '3717915731044925295249', + }), + collateralAmount: TokenAmount.createFromBaseUnit({ + token: WETH, + amount: '2127004370346054622', + }), + pool: makerPool, + }) + + const importPositionSimulation: ISimulation = + await sdk.simulator.importing.simulateImportPosition({ + externalPosition: { + position: makerPosition, + externalId: { + type: ExternalPositionType.DS_PROXY, + address: Address.createFromEthereum({ + value: '0x6c7ed10997873b59c2b2d9449d9106fe1dd85784', + }), + }, + }, + } as IImportPositionParameters) + + console.log('importPositionSimulation', JSON.stringify(importPositionSimulation, null, 2)) + expect(importPositionSimulation).toBeDefined() + + expect(importPositionSimulation.simulationType).toEqual(SimulationType.ImportPosition) + assert(importPositionSimulation.sourcePosition, 'Source position not found') + expect(importPositionSimulation.steps.length).toBe(1) + expect(importPositionSimulation.steps[0].type).toBe(SimulationSteps.Import) + + const importPositionOrder: Maybe = await user.newOrder({ + positionsManager: { + address: Address.createFromEthereum({ + value: '0x551Eb8395093fDE4B9eeF017C93593a3C7a75138', + }), + }, + simulation: importPositionSimulation, + }) + + assert(importPositionOrder, 'Order not found') + + expect(importPositionOrder.simulation.simulationType).toEqual( + importPositionSimulation.simulationType, + ) + assert(importPositionOrder.simulation.sourcePosition, 'Source position not found') + + expect(importPositionOrder.simulation.sourcePosition.positionId).toEqual( + importPositionSimulation.sourcePosition?.positionId, + ) + + expect(importPositionOrder.transactions.length).toEqual(1) + + // Send transaction + // console.log('Sending transaction...') + + // const privateKey = process.env.DEPLOYER_PRIVATE_KEY as Hex + // const transactionUtils = new TransactionUtils({ + // rpcUrl: TenderlyForkUrl, + // walletPrivateKey: privateKey, + // }) + + // const receipt = await transactionUtils.sendTransaction({ + // transaction: importPositionOrder.transactions[0].transaction, + // }) + + // console.log('Transaction sent:', receipt) + }) +}) diff --git a/sdk/sdk-server/src/handlers/getImportSimulation.ts b/sdk/sdk-server/src/handlers/getImportSimulation.ts index 22e9a19cf2..b1245f58d8 100644 --- a/sdk/sdk-server/src/handlers/getImportSimulation.ts +++ b/sdk/sdk-server/src/handlers/getImportSimulation.ts @@ -1,17 +1,15 @@ import { z } from 'zod' import type { ISimulation, SimulationType } from '@summerfi/sdk-common/simulation' -import { - importPosition, -} from '@summerfi/simulator-service/strategies' -import type { ImportPositionParameters } from '@summerfi/sdk-common/orders' +import { importPosition } from '@summerfi/simulator-service/strategies' +import type { IImportPositionParameters } from '@summerfi/sdk-common/orders' import { publicProcedure } from '../TRPC' -const inputSchema = z.custom((parameters) => parameters !== undefined) +const inputSchema = z.custom((parameters) => parameters !== undefined) export const getImportSimulation = publicProcedure .input(inputSchema) .query(async (opts): Promise> => { - const args: ImportPositionParameters = opts.input + const args: IImportPositionParameters = opts.input return await importPosition(args) }) diff --git a/sdk/simulator-service/src/strategies/import/ImportPosition.ts b/sdk/simulator-service/src/strategies/import/ImportPosition.ts index 05dae4ff7d..25c1c571ec 100644 --- a/sdk/simulator-service/src/strategies/import/ImportPosition.ts +++ b/sdk/simulator-service/src/strategies/import/ImportPosition.ts @@ -1,10 +1,10 @@ import { ISimulation, SimulationSteps, SimulationType } from '@summerfi/sdk-common/simulation' import { Simulator } from '../../implementation/simulator-engine' -import { ImportPositionParameters } from '@summerfi/sdk-common/orders' +import { IImportPositionParameters } from '@summerfi/sdk-common/orders' import { importPositionStrategy } from './Strategy' export async function importPosition( - args: ImportPositionParameters, + args: IImportPositionParameters, ): Promise> { const simulator = Simulator.create(importPositionStrategy) @@ -18,6 +18,7 @@ export async function importPosition( })) .run() + console.log('simulation', JSON.stringify(simulation, null, 2)) return { simulationType: SimulationType.ImportPosition, sourcePosition: args.externalPosition.position, diff --git a/sdk/swap-service/src/implementation/SwapManagerFactory.ts b/sdk/swap-service/src/implementation/SwapManagerFactory.ts index 079975a6ae..d2fe64729b 100644 --- a/sdk/swap-service/src/implementation/SwapManagerFactory.ts +++ b/sdk/swap-service/src/implementation/SwapManagerFactory.ts @@ -46,7 +46,7 @@ export class SwapManagerFactory { !allowedSwapProtocols || !chainIds ) { - throw new Error('OneInch configuration is missing') + //throw new Error('OneInch configuration is missing') } return { From dcd0f2d5d0ff53aa06b78ee719ae10a5ebf290ce Mon Sep 17 00:00:00 2001 From: Roberto Cano <3525807+robercano@users.noreply.github.com> Date: Fri, 12 Apr 2024 15:49:59 +0200 Subject: [PATCH 19/24] test: add Maker import test --- .../src/implementation/OrderPlanner.ts | 23 +++++++-------- .../src/utils/EncodeStrategy.ts | 21 ++++++++++++-- .../src/interfaces/IProtocolPlugin.ts | 2 +- .../src/implementation/BaseProtocolPlugin.ts | 2 +- .../implementation/AAVEv3ProtocolPlugin.ts | 2 +- .../MakerImportPositionActionBuilder.ts | 2 +- .../implementation/MakerProtocolPlugin.ts | 28 +++++++++++++------ .../maker/types/MakerExternalPosition.ts | 17 ----------- .../implementation/SparkProtocolPlugin.ts | 2 +- .../tests/importExternalPosition.test.ts | 24 ++++++++-------- .../simulator-engine/reducer/importReducer.ts | 10 +++++-- .../src/strategies/import/ImportPosition.ts | 1 - 12 files changed, 74 insertions(+), 60 deletions(-) delete mode 100644 sdk/protocol-plugins/src/plugins/maker/types/MakerExternalPosition.ts diff --git a/sdk/order-planner-common/src/implementation/OrderPlanner.ts b/sdk/order-planner-common/src/implementation/OrderPlanner.ts index c5ad99526c..d1615af173 100644 --- a/sdk/order-planner-common/src/implementation/OrderPlanner.ts +++ b/sdk/order-planner-common/src/implementation/OrderPlanner.ts @@ -94,25 +94,22 @@ export class OrderPlanner implements IOrderPlanner { const executorAddress = Address.createFromEthereum({ value: executorInfo.address as HexData }) const strategyName = this._getStrategyName(simulation) - const calldata = encodeStrategy({ + const strategyExecutorTransaction = encodeStrategy({ strategyName: strategyName, strategyExecutor: executorAddress, + positionsManager: positionsManager, actions: simulationCalls, }) + const transactions = [...preRequisiteTransactions] + + if (strategyExecutorTransaction) { + transactions.push(strategyExecutorTransaction) + } + return { - simulation: simulation, - transactions: [ - ...preRequisiteTransactions, - { - transaction: { - target: positionsManager.address, - calldata: calldata, - value: '0', - }, - description: 'Strategy execution', - }, - ], + simulation, + transactions, } } } diff --git a/sdk/order-planner-common/src/utils/EncodeStrategy.ts b/sdk/order-planner-common/src/utils/EncodeStrategy.ts index 98fe47fa7f..3d1a9cd9ed 100644 --- a/sdk/order-planner-common/src/utils/EncodeStrategy.ts +++ b/sdk/order-planner-common/src/utils/EncodeStrategy.ts @@ -1,5 +1,6 @@ import { ActionCall } from '@summerfi/protocol-plugins-common' -import { Address, HexData } from '@summerfi/sdk-common/common' +import { Address, HexData, Maybe } from '@summerfi/sdk-common/common' +import { IPositionsManager, TransactionInfo } from '@summerfi/sdk-common/orders' import { encodeFunctionData, parseAbi } from 'viem' type SkippableActionCall = ActionCall & { @@ -42,14 +43,28 @@ export function encodeForPositionsManager(params: { target: Address; data: HexDa export function encodeStrategy(params: { strategyName: string strategyExecutor: Address + positionsManager: IPositionsManager actions: ActionCall[] -}): HexData { +}): Maybe { const { strategyName, strategyExecutor, actions } = params + if (actions.length == 0) { + return undefined + } + const executorData = encodeForExecutor({ strategyName, actions }) - return encodeForPositionsManager({ + const calldata = encodeForPositionsManager({ target: strategyExecutor, data: executorData, }) + + return { + transaction: { + target: params.positionsManager.address, + calldata: calldata, + value: '0', + }, + description: 'Strategy execution', + } } diff --git a/sdk/protocol-plugins-common/src/interfaces/IProtocolPlugin.ts b/sdk/protocol-plugins-common/src/interfaces/IProtocolPlugin.ts index 30de60f111..926c474f0a 100644 --- a/sdk/protocol-plugins-common/src/interfaces/IProtocolPlugin.ts +++ b/sdk/protocol-plugins-common/src/interfaces/IProtocolPlugin.ts @@ -21,7 +21,7 @@ export interface IProtocolPlugin { getActionBuilder(step: StepType): Maybe> getImportPositionTransaction: (params: { user: IUser - position: IExternalPosition + externalPosition: IExternalPosition positionsManager: IPositionsManager }) => Promise> } diff --git a/sdk/protocol-plugins/src/implementation/BaseProtocolPlugin.ts b/sdk/protocol-plugins/src/implementation/BaseProtocolPlugin.ts index 2db9ee7dc1..c3da14790a 100644 --- a/sdk/protocol-plugins/src/implementation/BaseProtocolPlugin.ts +++ b/sdk/protocol-plugins/src/implementation/BaseProtocolPlugin.ts @@ -45,7 +45,7 @@ export abstract class BaseProtocolPlugin implements IProtocolPlugin { abstract getPosition(positionId: IPositionId): Promise abstract getImportPositionTransaction(params: { user: IUser - position: IExternalPosition + externalPosition: IExternalPosition positionsManager: IPositionsManager }): Promise> diff --git a/sdk/protocol-plugins/src/plugins/aave-v3/implementation/AAVEv3ProtocolPlugin.ts b/sdk/protocol-plugins/src/plugins/aave-v3/implementation/AAVEv3ProtocolPlugin.ts index 49aa446c21..9ec7dbcdc7 100644 --- a/sdk/protocol-plugins/src/plugins/aave-v3/implementation/AAVEv3ProtocolPlugin.ts +++ b/sdk/protocol-plugins/src/plugins/aave-v3/implementation/AAVEv3ProtocolPlugin.ts @@ -134,7 +134,7 @@ export class AaveV3ProtocolPlugin extends BaseProtocolPlugin { async getImportPositionTransaction(params: { user: IUser - position: IExternalPosition + externalPosition: IExternalPosition positionsManager: IPositionsManager }): Promise> { throw new Error(`Not implemented ${params}`) diff --git a/sdk/protocol-plugins/src/plugins/maker/builders/MakerImportPositionActionBuilder.ts b/sdk/protocol-plugins/src/plugins/maker/builders/MakerImportPositionActionBuilder.ts index 5b2250c6be..3e972847a5 100644 --- a/sdk/protocol-plugins/src/plugins/maker/builders/MakerImportPositionActionBuilder.ts +++ b/sdk/protocol-plugins/src/plugins/maker/builders/MakerImportPositionActionBuilder.ts @@ -21,7 +21,7 @@ export const MakerImportPositionActionBuilder: ActionBuilder = const importPositionTransaction = await makerPlugin.getImportPositionTransaction({ user: user, - position: step.inputs.externalPosition, + externalPosition: step.inputs.externalPosition, positionsManager: positionsManager, }) diff --git a/sdk/protocol-plugins/src/plugins/maker/implementation/MakerProtocolPlugin.ts b/sdk/protocol-plugins/src/plugins/maker/implementation/MakerProtocolPlugin.ts index ff8e9fd76e..f7ff78a0de 100644 --- a/sdk/protocol-plugins/src/plugins/maker/implementation/MakerProtocolPlugin.ts +++ b/sdk/protocol-plugins/src/plugins/maker/implementation/MakerProtocolPlugin.ts @@ -41,11 +41,16 @@ import { IProtocolPluginContext, } from '@summerfi/protocol-plugins-common' import { ILKType } from '../enums/ILKType' -import { MakerPoolId } from '../types/MakerPoolId' +import { MakerPoolId, isMakerPoolId } from '../types/MakerPoolId' import { IUser } from '@summerfi/sdk-common/user' -import { IExternalPosition, IPositionsManager, TransactionInfo } from '@summerfi/sdk-common/orders' +import { + ExternalPositionType, + IExternalPosition, + IPositionsManager, + TransactionInfo, +} from '@summerfi/sdk-common/orders' import { encodeMakerGiveThroughProxyActions } from '../utils/MakerGive' -import { isMakerExternalPosition } from '../types/MakerExternalPosition' +import { MakerImportPositionActionBuilder } from '../builders/MakerImportPositionActionBuilder' export class MakerProtocolPlugin extends BaseProtocolPlugin { readonly CdpManagerContractName = 'CdpManager' @@ -70,6 +75,7 @@ export class MakerProtocolPlugin extends BaseProtocolPlugin { }) readonly stepBuilders: Partial = { [SimulationSteps.PaybackWithdraw]: MakerPaybackWithdrawActionBuilder, + [SimulationSteps.Import]: MakerImportPositionActionBuilder, } constructor(params: { context: IProtocolPluginContext; deploymentConfigTag?: string }) { @@ -224,11 +230,17 @@ export class MakerProtocolPlugin extends BaseProtocolPlugin { async getImportPositionTransaction(params: { user: IUser - position: IExternalPosition + externalPosition: IExternalPosition positionsManager: IPositionsManager }): Promise> { - if (!isMakerExternalPosition(params.position)) { - throw new Error('Invalid Maker external position') + if (!isMakerPoolId(params.externalPosition.position.pool.poolId)) { + throw new Error('Invalid Maker pool ID') + } + + if (params.externalPosition.externalId.type !== ExternalPositionType.DS_PROXY) { + throw new Error( + `External position (${params.externalPosition.externalId.type}) type not supported`, + ) } const { deployments } = this.ctx @@ -245,14 +257,14 @@ export class MakerProtocolPlugin extends BaseProtocolPlugin { cdpManagerAddress: cdpManagerAddress, makerProxyActionsAddress: dssProxyActionsAddress, giveToAddress: params.positionsManager.address.value, - cdpId: params.position.vaultId, + cdpId: params.externalPosition.position.pool.poolId.vaultId, }) return { description: 'Import Maker position', transaction: { calldata: result.transactionCalldata, - target: params.position.dsProxyAddress, + target: params.externalPosition.externalId.address, value: '0', }, } diff --git a/sdk/protocol-plugins/src/plugins/maker/types/MakerExternalPosition.ts b/sdk/protocol-plugins/src/plugins/maker/types/MakerExternalPosition.ts deleted file mode 100644 index 1cca386558..0000000000 --- a/sdk/protocol-plugins/src/plugins/maker/types/MakerExternalPosition.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { Address } from '@summerfi/sdk-common/common' -import { IExternalPosition, isExternalPosition } from '@summerfi/sdk-common/orders' - -export interface MakerExternalPosition extends IExternalPosition { - dsProxyAddress: Address - vaultId: string -} - -export function isMakerExternalPosition( - maybePosition: unknown, -): maybePosition is MakerExternalPosition { - return ( - isExternalPosition(maybePosition) && - 'vaultId' in maybePosition && - 'dsProxyAddress' in maybePosition - ) -} diff --git a/sdk/protocol-plugins/src/plugins/spark/implementation/SparkProtocolPlugin.ts b/sdk/protocol-plugins/src/plugins/spark/implementation/SparkProtocolPlugin.ts index 2e7b0854b1..8c8d0ec4aa 100644 --- a/sdk/protocol-plugins/src/plugins/spark/implementation/SparkProtocolPlugin.ts +++ b/sdk/protocol-plugins/src/plugins/spark/implementation/SparkProtocolPlugin.ts @@ -137,7 +137,7 @@ export class SparkProtocolPlugin extends BaseProtocolPlugin { async getImportPositionTransaction(params: { user: IUser - position: IExternalPosition + externalPosition: IExternalPosition positionsManager: IPositionsManager }): Promise> { throw new Error(`Not implemented ${params}`) diff --git a/sdk/sdk-e2e/tests/importExternalPosition.test.ts b/sdk/sdk-e2e/tests/importExternalPosition.test.ts index 46d45a19f4..e1dfe4c064 100644 --- a/sdk/sdk-e2e/tests/importExternalPosition.test.ts +++ b/sdk/sdk-e2e/tests/importExternalPosition.test.ts @@ -25,6 +25,8 @@ import { DeploymentIndex } from '@summerfi/deployment-utils' import assert from 'assert' import { ILKType, MakerPoolId } from '@summerfi/protocol-plugins/plugins/maker' +import { Hex } from 'viem' +import { TransactionUtils } from './utils/TransactionUtils' jest.setTimeout(300000) @@ -129,7 +131,6 @@ describe('Import Maker Position | SDK', () => { }, } as IImportPositionParameters) - console.log('importPositionSimulation', JSON.stringify(importPositionSimulation, null, 2)) expect(importPositionSimulation).toBeDefined() expect(importPositionSimulation.simulationType).toEqual(SimulationType.ImportPosition) @@ -159,19 +160,20 @@ describe('Import Maker Position | SDK', () => { expect(importPositionOrder.transactions.length).toEqual(1) + console.log('Import Position Order:', JSON.stringify(importPositionOrder.transactions[0])) // Send transaction - // console.log('Sending transaction...') + console.log('Sending transaction...') - // const privateKey = process.env.DEPLOYER_PRIVATE_KEY as Hex - // const transactionUtils = new TransactionUtils({ - // rpcUrl: TenderlyForkUrl, - // walletPrivateKey: privateKey, - // }) + const privateKey = process.env.DEPLOYER_PRIVATE_KEY as Hex + const transactionUtils = new TransactionUtils({ + rpcUrl: TenderlyForkUrl, + walletPrivateKey: privateKey, + }) - // const receipt = await transactionUtils.sendTransaction({ - // transaction: importPositionOrder.transactions[0].transaction, - // }) + const receipt = await transactionUtils.sendTransaction({ + transaction: importPositionOrder.transactions[0].transaction, + }) - // console.log('Transaction sent:', receipt) + console.log('Transaction sent:', receipt) }) }) diff --git a/sdk/simulator-service/src/implementation/simulator-engine/reducer/importReducer.ts b/sdk/simulator-service/src/implementation/simulator-engine/reducer/importReducer.ts index 793f7a61e9..78c5a18b3f 100644 --- a/sdk/simulator-service/src/implementation/simulator-engine/reducer/importReducer.ts +++ b/sdk/simulator-service/src/implementation/simulator-engine/reducer/importReducer.ts @@ -1,6 +1,12 @@ import { steps } from '@summerfi/sdk-common/simulation' import { ISimulationState } from '../../../interfaces/simulation' -export function importReducer(_step: steps.ImportStep, state: ISimulationState): ISimulationState { - return state +export function importReducer(step: steps.ImportStep, state: ISimulationState): ISimulationState { + return { + ...state, + steps: { + ...state.steps, + [step.name]: step, + }, + } } diff --git a/sdk/simulator-service/src/strategies/import/ImportPosition.ts b/sdk/simulator-service/src/strategies/import/ImportPosition.ts index 25c1c571ec..23b431b6f6 100644 --- a/sdk/simulator-service/src/strategies/import/ImportPosition.ts +++ b/sdk/simulator-service/src/strategies/import/ImportPosition.ts @@ -18,7 +18,6 @@ export async function importPosition( })) .run() - console.log('simulation', JSON.stringify(simulation, null, 2)) return { simulationType: SimulationType.ImportPosition, sourcePosition: args.externalPosition.position, From 65da45a7b23e9518689f5e5425472906a720d0b6 Mon Sep 17 00:00:00 2001 From: Roberto Cano <3525807+robercano@users.noreply.github.com> Date: Fri, 12 Apr 2024 15:52:07 +0200 Subject: [PATCH 20/24] chore: update fork URL --- sdk/sdk-e2e/tests/importExternalPosition.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/sdk-e2e/tests/importExternalPosition.test.ts b/sdk/sdk-e2e/tests/importExternalPosition.test.ts index e1dfe4c064..a596501034 100644 --- a/sdk/sdk-e2e/tests/importExternalPosition.test.ts +++ b/sdk/sdk-e2e/tests/importExternalPosition.test.ts @@ -32,7 +32,7 @@ jest.setTimeout(300000) const SDKAPiUrl = 'https://zmjmtfsocb.execute-api.us-east-1.amazonaws.com/api/sdk' const TenderlyForkUrl = - 'https://virtual.mainnet.rpc.tenderly.co/75405d76-cb49-41c4-8624-e47966ee7969' + 'https://virtual.mainnet.rpc.tenderly.co/c9231728-8442-4c98-80a0-7fbdca928099' describe('Import Maker Position | SDK', () => { it('should allow refinance Maker -> Spark with same pair', async () => { From 8717648550b70179ccbb48914630bb7c9738e4e6 Mon Sep 17 00:00:00 2001 From: Roberto Cano <3525807+robercano@users.noreply.github.com> Date: Fri, 12 Apr 2024 15:53:12 +0200 Subject: [PATCH 21/24] chore: cleanup test --- .../tests/importExternalPosition.test.ts | 27 +------------------ 1 file changed, 1 insertion(+), 26 deletions(-) diff --git a/sdk/sdk-e2e/tests/importExternalPosition.test.ts b/sdk/sdk-e2e/tests/importExternalPosition.test.ts index a596501034..e6fd0a8800 100644 --- a/sdk/sdk-e2e/tests/importExternalPosition.test.ts +++ b/sdk/sdk-e2e/tests/importExternalPosition.test.ts @@ -6,22 +6,14 @@ import { Address, type Maybe, ChainFamilyMap, - AddressValue, PositionType, } from '@summerfi/sdk-common/common' import { ProtocolName, isLendingPool } from '@summerfi/sdk-common/protocols' import { makeSDK, type Chain, type User } from '@summerfi/sdk-client' import { TokenSymbol } from '@summerfi/sdk-common/common/enums' -import { - ExternalPositionType, - IImportPositionParameters, - IPositionsManager, - Order, -} from '@summerfi/sdk-common/orders' +import { ExternalPositionType, IImportPositionParameters, Order } from '@summerfi/sdk-common/orders' import { ISimulation, SimulationSteps, SimulationType } from '@summerfi/sdk-common/simulation' -import { Deployments } from '@summerfi/core-contracts' -import { DeploymentIndex } from '@summerfi/deployment-utils' import assert from 'assert' import { ILKType, MakerPoolId } from '@summerfi/protocol-plugins/plugins/maker' @@ -46,16 +38,6 @@ describe('Import Maker Position | SDK', () => { assert(chain, 'Chain not found') - // Deployment - const deploymentName = `${chain.chainInfo.name}.standard` - const deployments = Deployments as DeploymentIndex - const deployment = deployments[deploymentName] - - // Strategy Executor - const strategyExecutorAddress = Address.createFromEthereum({ - value: deployment.contracts.OperationExecutor.address as AddressValue, - }) - // User const walletAddress = Address.createFromEthereum({ value: '0xbEf4befb4F230F43905313077e3824d7386E09F8', @@ -68,13 +50,6 @@ describe('Import Maker Position | SDK', () => { expect(user.wallet.address).toEqual(walletAddress) expect(user.chainInfo).toEqual(chain.chainInfo) - // Positions Manager - const positionsManager: IPositionsManager = { - address: Address.createFromEthereum({ - value: '0x551Eb8395093fDE4B9eeF017C93593a3C7a75138', - }), - } - // Tokens const WETH: Maybe = await chain.tokens.getTokenBySymbol({ symbol: TokenSymbol.WETH }) assert(WETH, 'WETH not found') From 59856faa38912a57313d6c782255a327f1673c87 Mon Sep 17 00:00:00 2001 From: Roberto Cano <3525807+robercano@users.noreply.github.com> Date: Fri, 12 Apr 2024 17:28:53 +0200 Subject: [PATCH 22/24] test: maker import + maker refinance --- sdk/.env.template | 11 ++- .../implementation/ConfigurationProvider.ts | 1 + ...on.test.ts => importMakerPosition.test.ts} | 4 +- ...efinanceMakerSparkAlreadyImported.test.ts} | 5 +- .../src/implementation/SwapManagerFactory.ts | 76 +++++++++++++------ stacks/sdk.ts | 16 +++- turbo.json | 3 + 7 files changed, 85 insertions(+), 31 deletions(-) rename sdk/sdk-e2e/tests/{importExternalPosition.test.ts => importMakerPosition.test.ts} (97%) rename sdk/sdk-e2e/tests/{refinanceMakerSpark.test.ts => refinanceMakerSparkAlreadyImported.test.ts} (98%) diff --git a/sdk/.env.template b/sdk/.env.template index 85fd8cf22c..178ebe1b70 100644 --- a/sdk/.env.template +++ b/sdk/.env.template @@ -11,4 +11,13 @@ ONE_INCH_API_URL='https://api-oasis.1inch.io' ONE_INCH_ALLOWED_SWAP_PROTOCOLS='UNISWAP_V3,PMM1,PMM2,PMM3,PMM4,UNISWAP_V2,SUSHI,CURVE,CURVE_V2,PSM,WSTETH,BALANCER,BALANCER_V2,BALANCER_V2_WRAPPER,ST_ETH,WETH,ROCKET_POOL' # ChainIDs where 1Inch swaps are allowed (comma separated) -ONE_INCH_SWAP_CHAIN_IDS='1' \ No newline at end of file +ONE_INCH_SWAP_CHAIN_IDS='1' + +# 1Inch API spot URL +ONE_INCH_API_SPOT_URL='' + +# 1Inch API spot version, like v1.0 +ONE_INCH_API_SPOT_VERSION='v1.0' + +# 1Inch API spot key +ONE_INCH_API_SPOT_KEY='' diff --git a/sdk/configuration-provider/src/implementation/ConfigurationProvider.ts b/sdk/configuration-provider/src/implementation/ConfigurationProvider.ts index 1be11333a3..87434b475b 100644 --- a/sdk/configuration-provider/src/implementation/ConfigurationProvider.ts +++ b/sdk/configuration-provider/src/implementation/ConfigurationProvider.ts @@ -3,6 +3,7 @@ import { IConfigurationProvider } from '../interfaces/IConfigurationProvider' import { ConfigItem } from '../types/ConfigItem' import { ConfigKey } from '../types/ConfigKey' +// NOTICE: remember to add new config keys to the SDKs .env.template file as well const CONFIG_KEYS: ConfigKey[] = [ 'ONE_INCH_API_VERSION', 'ONE_INCH_API_KEY', diff --git a/sdk/sdk-e2e/tests/importExternalPosition.test.ts b/sdk/sdk-e2e/tests/importMakerPosition.test.ts similarity index 97% rename from sdk/sdk-e2e/tests/importExternalPosition.test.ts rename to sdk/sdk-e2e/tests/importMakerPosition.test.ts index e6fd0a8800..0f29ffacbc 100644 --- a/sdk/sdk-e2e/tests/importExternalPosition.test.ts +++ b/sdk/sdk-e2e/tests/importMakerPosition.test.ts @@ -24,9 +24,9 @@ jest.setTimeout(300000) const SDKAPiUrl = 'https://zmjmtfsocb.execute-api.us-east-1.amazonaws.com/api/sdk' const TenderlyForkUrl = - 'https://virtual.mainnet.rpc.tenderly.co/c9231728-8442-4c98-80a0-7fbdca928099' + 'https://virtual.mainnet.rpc.tenderly.co/d4cb5af8-8015-4342-b95d-26e5b05a6525' -describe('Import Maker Position | SDK', () => { +describe.skip('Import Maker Position | SDK', () => { it('should allow refinance Maker -> Spark with same pair', async () => { // SDK const sdk = makeSDK({ apiURL: SDKAPiUrl }) diff --git a/sdk/sdk-e2e/tests/refinanceMakerSpark.test.ts b/sdk/sdk-e2e/tests/refinanceMakerSparkAlreadyImported.test.ts similarity index 98% rename from sdk/sdk-e2e/tests/refinanceMakerSpark.test.ts rename to sdk/sdk-e2e/tests/refinanceMakerSparkAlreadyImported.test.ts index 6739688ffd..1ccd4752ec 100644 --- a/sdk/sdk-e2e/tests/refinanceMakerSpark.test.ts +++ b/sdk/sdk-e2e/tests/refinanceMakerSparkAlreadyImported.test.ts @@ -51,9 +51,10 @@ import { jest.setTimeout(300000) const SDKAPiUrl = 'https://zmjmtfsocb.execute-api.us-east-1.amazonaws.com/api/sdk' -const TenderlyForkUrl = 'https://rpc.tenderly.co/fork/50e01944-8635-4d67-9569-004d72113328' +const TenderlyForkUrl = + 'https://virtual.mainnet.rpc.tenderly.co/d4cb5af8-8015-4342-b95d-26e5b05a6525' -describe.skip('Refinance Maker Spark | SDK', () => { +describe('Refinance Maker Spark | SDK', () => { it('should allow refinance Maker -> Spark with same pair', async () => { // SDK const sdk = makeSDK({ apiURL: SDKAPiUrl }) diff --git a/sdk/swap-service/src/implementation/SwapManagerFactory.ts b/sdk/swap-service/src/implementation/SwapManagerFactory.ts index d2fe64729b..3314fa4360 100644 --- a/sdk/swap-service/src/implementation/SwapManagerFactory.ts +++ b/sdk/swap-service/src/implementation/SwapManagerFactory.ts @@ -24,42 +24,68 @@ export class SwapManagerFactory { config: OneInchSwapProviderConfig chainIds: ChainId[] } { - const apiUrl = configProvider.getConfigurationItem({ name: 'ONE_INCH_API_URL' }) - const apiKey = configProvider.getConfigurationItem({ name: 'ONE_INCH_API_KEY' }) - const version = configProvider.getConfigurationItem({ name: 'ONE_INCH_API_VERSION' }) - const allowedSwapProtocols = configProvider.getConfigurationItem({ + const ONE_INCH_API_URL = configProvider.getConfigurationItem({ name: 'ONE_INCH_API_URL' }) + const ONE_INCH_API_KEY = configProvider.getConfigurationItem({ name: 'ONE_INCH_API_KEY' }) + const ONE_INCH_API_VERSION = configProvider.getConfigurationItem({ + name: 'ONE_INCH_API_VERSION', + }) + const ONE_INCH_ALLOWED_SWAP_PROTOCOLS = configProvider.getConfigurationItem({ name: 'ONE_INCH_ALLOWED_SWAP_PROTOCOLS', }) - const chainIds = configProvider.getConfigurationItem({ name: 'ONE_INCH_SWAP_CHAIN_IDS' }) + const ONE_INCH_SWAP_CHAIN_IDS = configProvider.getConfigurationItem({ + name: 'ONE_INCH_SWAP_CHAIN_IDS', + }) - const apiSpotUrl = configProvider.getConfigurationItem({ name: 'ONE_INCH_API_SPOT_URL' }) - const spotVersion = configProvider.getConfigurationItem({ name: 'ONE_INCH_API_SPOT_VERSION' }) - const apiSpotKey = configProvider.getConfigurationItem({ name: 'ONE_INCH_API_SPOT_KEY' }) + const ONE_INCH_API_SPOT_URL = configProvider.getConfigurationItem({ + name: 'ONE_INCH_API_SPOT_URL', + }) + const ONE_INCH_API_SPOT_VERSION = configProvider.getConfigurationItem({ + name: 'ONE_INCH_API_SPOT_VERSION', + }) + const ONE_INCH_API_SPOT_KEY = configProvider.getConfigurationItem({ + name: 'ONE_INCH_API_SPOT_KEY', + }) if ( - !apiSpotUrl || - !apiSpotKey || - !apiUrl || - !apiKey || - !version || - !spotVersion || - !allowedSwapProtocols || - !chainIds + !ONE_INCH_API_SPOT_URL || + !ONE_INCH_API_SPOT_KEY || + !ONE_INCH_API_URL || + !ONE_INCH_API_KEY || + !ONE_INCH_API_VERSION || + !ONE_INCH_API_SPOT_VERSION || + !ONE_INCH_ALLOWED_SWAP_PROTOCOLS || + !ONE_INCH_SWAP_CHAIN_IDS ) { - //throw new Error('OneInch configuration is missing') + throw new Error( + 'OneInch configuration is missing: ' + + JSON.stringify( + Object.entries({ + ONE_INCH_API_URL, + ONE_INCH_API_KEY, + ONE_INCH_API_VERSION, + ONE_INCH_API_SPOT_URL, + ONE_INCH_API_SPOT_KEY, + ONE_INCH_API_SPOT_VERSION, + ONE_INCH_ALLOWED_SWAP_PROTOCOLS, + ONE_INCH_SWAP_CHAIN_IDS, + }), + null, + 2, + ), + ) } return { config: { - apiUrl: apiUrl, - apiKey: apiKey, - version: version, - apiSpotUrl: apiSpotUrl, - apiSpotKey: apiSpotKey, - spotVersion: spotVersion, - allowedSwapProtocols: allowedSwapProtocols.split(','), + apiUrl: ONE_INCH_API_URL, + apiKey: ONE_INCH_API_KEY, + version: ONE_INCH_API_VERSION, + apiSpotUrl: ONE_INCH_API_SPOT_URL, + apiSpotKey: ONE_INCH_API_SPOT_KEY, + spotVersion: ONE_INCH_API_SPOT_VERSION, + allowedSwapProtocols: ONE_INCH_ALLOWED_SWAP_PROTOCOLS.split(','), }, - chainIds: chainIds.split(',').map((id: string) => parseInt(id)), + chainIds: ONE_INCH_SWAP_CHAIN_IDS.split(',').map((id: string) => parseInt(id)), } } } diff --git a/stacks/sdk.ts b/stacks/sdk.ts index 124e2ccbdc..dbe1100702 100644 --- a/stacks/sdk.ts +++ b/stacks/sdk.ts @@ -8,6 +8,9 @@ const { ONE_INCH_API_URL, ONE_INCH_ALLOWED_SWAP_PROTOCOLS, ONE_INCH_SWAP_CHAIN_IDS, + ONE_INCH_API_SPOT_URL, + ONE_INCH_API_SPOT_VERSION, + ONE_INCH_API_SPOT_KEY, } = process.env export function addSdkConfig({ stack, api }: StackContext & { api: Api }) { @@ -16,7 +19,10 @@ export function addSdkConfig({ stack, api }: StackContext & { api: Api }) { !ONE_INCH_API_VERSION || !ONE_INCH_API_URL || !ONE_INCH_ALLOWED_SWAP_PROTOCOLS || - !ONE_INCH_SWAP_CHAIN_IDS + !ONE_INCH_SWAP_CHAIN_IDS || + !ONE_INCH_API_SPOT_URL || + !ONE_INCH_API_SPOT_VERSION || + !ONE_INCH_API_SPOT_KEY ) { throw new Error( 'OneInch configuration env variables are missing: ' + @@ -27,7 +33,12 @@ export function addSdkConfig({ stack, api }: StackContext & { api: Api }) { ONE_INCH_API_URL, ONE_INCH_ALLOWED_SWAP_PROTOCOLS, ONE_INCH_SWAP_CHAIN_IDS, + ONE_INCH_API_SPOT_URL, + ONE_INCH_API_SPOT_VERSION, + ONE_INCH_API_SPOT_KEY, }), + null, + 2, ), ) } @@ -42,6 +53,9 @@ export function addSdkConfig({ stack, api }: StackContext & { api: Api }) { ONE_INCH_API_URL, ONE_INCH_ALLOWED_SWAP_PROTOCOLS, ONE_INCH_SWAP_CHAIN_IDS, + ONE_INCH_API_SPOT_URL, + ONE_INCH_API_SPOT_VERSION, + ONE_INCH_API_SPOT_KEY, }, }) diff --git a/turbo.json b/turbo.json index eaff06d6a7..e2d9b06c75 100644 --- a/turbo.json +++ b/turbo.json @@ -29,6 +29,9 @@ "ONE_INCH_API_URL", "ONE_INCH_ALLOWED_SWAP_PROTOCOLS", "ONE_INCH_SWAP_CHAIN_IDS", + "ONE_INCH_API_SPOT_URL", + "ONE_INCH_API_SPOT_VERSION", + "ONE_INCH_API_SPOT_KEY", "SDK_API_URL", "MAINNET_RPC_URL" ], From 8ffeecd53b97a4c18fa66697a0a6611d09fbeae8 Mon Sep 17 00:00:00 2001 From: Roberto Cano <3525807+robercano@users.noreply.github.com> Date: Fri, 12 Apr 2024 17:39:13 +0200 Subject: [PATCH 23/24] fix: tests --- .../tests/EncodeStrategy.spec.ts | 14 ++++++++++++-- .../refinanceMakerSparkAlreadyImported.test.ts | 2 +- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/sdk/order-planner-common/tests/EncodeStrategy.spec.ts b/sdk/order-planner-common/tests/EncodeStrategy.spec.ts index 05ae978e59..c957026616 100644 --- a/sdk/order-planner-common/tests/EncodeStrategy.spec.ts +++ b/sdk/order-planner-common/tests/EncodeStrategy.spec.ts @@ -8,6 +8,7 @@ import { decodeStrategyExecutorCalldata, } from '@summerfi/testing-utils' import assert from 'assert' +import { IPositionsManager } from '@summerfi/sdk-common/orders' class DerivedAction extends BaseAction { public readonly config = { @@ -51,14 +52,23 @@ describe.only('Encode Strategy', () => { }) it('should encode calls for operation executor', () => { - const calldata = encodeStrategy({ + const positionsManager: IPositionsManager = { + address: Address.createFromEthereum({ + value: '0x5e81A7515f956aB642eb698821a449fe8fE7498B', + }), + } + + const transactionInfo = encodeStrategy({ strategyName: 'SomeStrategyName', strategyExecutor: strategyExecutorAddress, + positionsManager: positionsManager, actions: [actionCall, otherActionCall], }) + assert(transactionInfo, 'Cannot encode strategy') + const positionsManagerParams = decodePositionsManagerCalldata({ - calldata: calldata, + calldata: transactionInfo.transaction.calldata, }) assert(positionsManagerParams, 'Cannot decode Positions Manager calldata') diff --git a/sdk/sdk-e2e/tests/refinanceMakerSparkAlreadyImported.test.ts b/sdk/sdk-e2e/tests/refinanceMakerSparkAlreadyImported.test.ts index 1ccd4752ec..28b3bcadea 100644 --- a/sdk/sdk-e2e/tests/refinanceMakerSparkAlreadyImported.test.ts +++ b/sdk/sdk-e2e/tests/refinanceMakerSparkAlreadyImported.test.ts @@ -54,7 +54,7 @@ const SDKAPiUrl = 'https://zmjmtfsocb.execute-api.us-east-1.amazonaws.com/api/sd const TenderlyForkUrl = 'https://virtual.mainnet.rpc.tenderly.co/d4cb5af8-8015-4342-b95d-26e5b05a6525' -describe('Refinance Maker Spark | SDK', () => { +describe.skip('Refinance Maker Spark | SDK', () => { it('should allow refinance Maker -> Spark with same pair', async () => { // SDK const sdk = makeSDK({ apiURL: SDKAPiUrl }) From 69e5feabf16158838f833d4cca5df33b692f05b3 Mon Sep 17 00:00:00 2001 From: Roberto Cano <3525807+robercano@users.noreply.github.com> Date: Tue, 16 Apr 2024 16:42:09 +0200 Subject: [PATCH 24/24] fix: any pair simulation --- .../common/constants/AaveV3LikeConstants.ts | 1 - .../src/common/implementation/Address.ts | 2 +- .../RefinanceLendingToLendingAnyPair.ts | 15 ++++++----- .../oneinch/OneInchSwapProvider.ts | 26 +++++++++++-------- .../src/implementation/oneinch/types.ts | 5 ++++ 5 files changed, 29 insertions(+), 20 deletions(-) diff --git a/sdk/protocol-plugins/src/plugins/common/constants/AaveV3LikeConstants.ts b/sdk/protocol-plugins/src/plugins/common/constants/AaveV3LikeConstants.ts index cae7a5f6a5..dce64290d8 100644 --- a/sdk/protocol-plugins/src/plugins/common/constants/AaveV3LikeConstants.ts +++ b/sdk/protocol-plugins/src/plugins/common/constants/AaveV3LikeConstants.ts @@ -1,4 +1,3 @@ -// TODO: is this the correct place for these constants? Seem to be Maker specific export const PRECISION = { WAD: 18, RAY: 27, diff --git a/sdk/sdk-common/src/common/implementation/Address.ts b/sdk/sdk-common/src/common/implementation/Address.ts index 3cfb737270..1a06d81fd9 100644 --- a/sdk/sdk-common/src/common/implementation/Address.ts +++ b/sdk/sdk-common/src/common/implementation/Address.ts @@ -46,7 +46,7 @@ export class Address implements IAddress { } equals(address: Address): boolean { - return this.value === address.value + return this.value.toLowerCase() === address.value.toLowerCase() } toString(): string { diff --git a/sdk/simulator-service/src/strategies/refinanceAnyPair/RefinanceLendingToLendingAnyPair.ts b/sdk/simulator-service/src/strategies/refinanceAnyPair/RefinanceLendingToLendingAnyPair.ts index 654af23403..ae8dc540db 100644 --- a/sdk/simulator-service/src/strategies/refinanceAnyPair/RefinanceLendingToLendingAnyPair.ts +++ b/sdk/simulator-service/src/strategies/refinanceAnyPair/RefinanceLendingToLendingAnyPair.ts @@ -5,13 +5,13 @@ import { SimulationSteps, SimulationType, TokenTransferTargetType, + getValueFromReference, } from '@summerfi/sdk-common/simulation' import { Simulator } from '../../implementation/simulator-engine' import { Position, TokenAmount, Percentage, Price } from '@summerfi/sdk-common/common' import { newEmptyPositionFromPool } from '@summerfi/sdk-common/common/utils' import { IRefinanceParameters } from '@summerfi/sdk-common/orders' import { isLendingPool } from '@summerfi/sdk-common/protocols' -import { getReferencedValue } from '../../implementation/utils' import { refinanceLendingToLendingAnyPairStrategy } from './Strategy' import { type IRefinanceDependencies } from '../common/Types' @@ -149,12 +149,13 @@ export async function refinanceLendingToLendingAnyPair( ...(await dependencies.swapManager.getSwapQuoteExactInput({ chainInfo: args.sourcePosition.pool.protocol.chainInfo, fromAmount: subtractPercentage( - getReferencedValue(ctx.getReference(['DepositBorrowToTarget', 'borrowAmount'])), + // TODO: this should have better semantics. There was a bug where `getReferencedValue` was used instead of `getValueFromReference`, the names are too similar + getValueFromReference(ctx.getReference(['DepositBorrowToTarget', 'borrowAmount'])), Percentage.createFrom({ value: debtSwapSummerFee.value, }), ), - toToken: targetDebtConfig.token, + toToken: flashloanAmount.token, })), spotPrice: debtSpotPrice, slippage: Percentage.createFrom({ value: args.slippage.value }), @@ -229,13 +230,13 @@ export async function refinanceLendingToLendingAnyPair( * * We also need to factor in Summer fees ahead of time */ -async function calculateBorrowAmount(params: { +function calculateBorrowAmount(params: { isDebtSwapSkipped: boolean prevDebtAmount: TokenAmount debtSpotPrice: Price slippage: Percentage summerFee: Percentage -}) { +}): TokenAmount { const { isDebtSwapSkipped, prevDebtAmount, debtSpotPrice, slippage, summerFee } = params /** @@ -261,7 +262,7 @@ async function calculateBorrowAmount(params: { * More generally we'd write this as * (sourcePositionDebt * targetDebtQuotedInSourceDebtPrice / (one - slippage)) / (one - summer fee) = borrowAmount */ - const borrowAmount = prevDebtAmount.multiply(debtSpotPrice.toString()) + const borrowAmount = prevDebtAmount.multiply(debtSpotPrice.value) const borrowAmountAdjustedForSlippage = subtractPercentage( borrowAmount, Percentage.createFrom({ @@ -276,7 +277,7 @@ async function calculateBorrowAmount(params: { ) return TokenAmount.createFrom({ - amount: borrowAmountAdjustedForSlippageAndSummerFee.toString(), + amount: borrowAmountAdjustedForSlippageAndSummerFee.amount, token: debtSpotPrice.baseToken, }) } diff --git a/sdk/swap-service/src/implementation/oneinch/OneInchSwapProvider.ts b/sdk/swap-service/src/implementation/oneinch/OneInchSwapProvider.ts index c1c0daf813..edaffce8e2 100644 --- a/sdk/swap-service/src/implementation/oneinch/OneInchSwapProvider.ts +++ b/sdk/swap-service/src/implementation/oneinch/OneInchSwapProvider.ts @@ -10,6 +10,8 @@ import { OneInchAuthHeader, OneInchAuthHeaderKey, OneInchQuoteResponse, + OneInchSpotAuthHeader, + OneInchSpotAuthHeaderKey, OneInchSpotResponse, OneInchSwapProviderConfig, OneInchSwapResponse, @@ -124,7 +126,7 @@ export class OneInchSwapProvider implements ISwapProvider { if (!(response.status === 200 && response.statusText === 'OK')) { throw new Error( - `Error [${response.statusText}] performing 1inch swap quote request ${swapUrl}: ${JSON.stringify(await response.body)}`, + `Error [${response.statusText}] performing 1inch swap quote request ${swapUrl}`, ) } @@ -168,25 +170,26 @@ export class OneInchSwapProvider implements ISwapProvider { if (!(response.status === 200 && response.statusText === 'OK')) { throw new Error( - `Error performing 1inch spot price request ${spotUrl}: ${await response.body}`, + `Error performing 1inch spot price request ${spotUrl}: ${JSON.stringify(await response.statusText)}`, ) } const responseData = (await response.json()) as OneInchSpotResponse + const baseToken = params.baseToken const quoteToken = params.quoteToken const prices = Object.entries(responseData).map(([address, price]) => { - const isBaseToken = params.baseToken.address.equals( + const isBaseToken = baseToken.address.equals( Address.createFromEthereum({ value: address as AddressValue }), ) return Price.createFrom({ value: price.toString(), - baseToken: isBaseToken ? params.baseToken : quoteToken, + baseToken: isBaseToken ? baseToken : quoteToken, quoteToken: quoteCurrencySymbol, }) }) const baseTokenPriceQuotedInCurrencySymbol = prices.find((p) => - p.baseToken.address.equals(params.baseToken.address), + p.baseToken.address.equals(baseToken.address), ) const quoteTokenPriceQuoteInCurrencySymbol = prices.find((p) => p.baseToken.address.equals(quoteToken.address), @@ -203,16 +206,17 @@ export class OneInchSwapProvider implements ISwapProvider { .toBN() .div(quoteTokenPriceQuoteInCurrencySymbol.toBN()) .toString(), - baseToken: params.baseToken, + baseToken: baseToken, quoteToken: quoteToken, }), } } else { const quoteCurrency = params.quoteToken ?? CurrencySymbol.USD + const baseToken = params.baseToken const spotUrl = this._formatOneInchSpotUrl({ chainInfo: params.chainInfo, - tokenAddresses: [params.baseToken.address], - quoteCurrency: params.quoteToken ?? CurrencySymbol.USD, + tokenAddresses: [baseToken.address], + quoteCurrency: quoteCurrency, }) const response = await fetch(spotUrl, { @@ -233,7 +237,7 @@ export class OneInchSwapProvider implements ISwapProvider { provider: SwapProviderType.OneInch, price: Price.createFrom({ value: price.toString(), - baseToken: params.baseToken, + baseToken: baseToken, quoteToken: quoteCurrency, }), } @@ -244,8 +248,8 @@ export class OneInchSwapProvider implements ISwapProvider { return { [OneInchAuthHeaderKey]: this._apiKey } } - private _getOneInchSpotAuthHeader(): OneInchAuthHeader { - return { [OneInchAuthHeaderKey]: this._apiSpotKey } + private _getOneInchSpotAuthHeader(): OneInchSpotAuthHeader { + return { [OneInchSpotAuthHeaderKey]: `Bearer ${this._apiSpotKey}` } } private _formatOneInchSwapUrl(params: { diff --git a/sdk/swap-service/src/implementation/oneinch/types.ts b/sdk/swap-service/src/implementation/oneinch/types.ts index c21078a13f..b317b19f10 100644 --- a/sdk/swap-service/src/implementation/oneinch/types.ts +++ b/sdk/swap-service/src/implementation/oneinch/types.ts @@ -1,4 +1,5 @@ export const OneInchAuthHeaderKey = 'auth-key' +export const OneInchSpotAuthHeaderKey = 'Authorization' export type OneInchAuthHeader = { [OneInchAuthHeaderKey]: string @@ -30,6 +31,10 @@ export interface OneInchSwapResponse extends OneInchBaseResponse { } } +export type OneInchSpotAuthHeader = { + [OneInchSpotAuthHeaderKey]: string +} + export type OneInchSpotResponse = Record export interface OneInchQuoteResponse extends OneInchBaseResponse {