Skip to content

Commit

Permalink
feat: add simulated swap data to simulations (#147)
Browse files Browse the repository at this point in the history
- Add Swaps to Simulation output
- Refactor `Simulation` -> `ISimulation` to align better with rest of
the SDK
- Refactor Swap related types from `swap-common` -> `sdk-common` to
remove cyclic dependencies in simulation types

Note:
- `getSpotPrices` simplified to `getSpotPrice` in
#153

TODO:
- Write tests for simulation swaps (done in
#153)
- Update refinance strategy to handle swaps (current implementation is
based on assumptions that no longer hold following
ProtocolManager/Plugins/Pool work) (done in
#153)
  • Loading branch information
zerotucks authored and jakubswierczek committed Apr 8, 2024
1 parent 55d827a commit 388d71f
Show file tree
Hide file tree
Showing 69 changed files with 698 additions and 254 deletions.
8 changes: 4 additions & 4 deletions sdk/order-planner-common/src/implementation/OrderPlanner.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Order, type IPositionsManager } from '@summerfi/sdk-common/orders'
import { Simulation, SimulationType, steps } from '@summerfi/sdk-common/simulation'
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'
Expand All @@ -22,7 +22,7 @@ export class OrderPlanner implements IOrderPlanner {
async buildOrder(params: {
user: IUser
positionsManager: IPositionsManager
simulation: Simulation<SimulationType>
simulation: ISimulation<SimulationType>
actionBuildersMap: ActionBuildersMap
deployment: Deployment
swapManager: ISwapManager
Expand Down Expand Up @@ -75,12 +75,12 @@ export class OrderPlanner implements IOrderPlanner {
return actionBuildersMap[step.type] as ActionBuilder<T>
}

private _getStrategyName(simulation: Simulation<SimulationType>): string {
private _getStrategyName(simulation: ISimulation<SimulationType>): string {
return `${simulation.simulationType}${simulation.sourcePosition?.pool.protocol.name}${simulation.targetPosition?.pool.protocol.name}`
}

private _generateOrder(
simulation: Simulation<SimulationType>,
simulation: ISimulation<SimulationType>,
simulationCalls: ActionCall[],
positionsManager: IPositionsManager,
deployment: Deployment,
Expand Down
4 changes: 2 additions & 2 deletions sdk/order-planner-common/src/interfaces/IOrderPlanner.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Deployment } from '@summerfi/deployment-utils'
import { Order, type IPositionsManager } from '@summerfi/sdk-common/orders'
import { Simulation, SimulationType } from '@summerfi/sdk-common/simulation'
import { ISimulation, SimulationType } from '@summerfi/sdk-common/simulation'
import { ISwapManager } from '@summerfi/swap-common/interfaces'
import { Maybe } from '@summerfi/sdk-common/common'
import { IUser } from '@summerfi/sdk-common/user'
Expand All @@ -10,7 +10,7 @@ export interface IOrderPlanner {
buildOrder<T extends SimulationType>(params: {
user: IUser
positionsManager: IPositionsManager
simulation: Simulation<T>
simulation: ISimulation<T>
actionBuildersMap: ActionBuildersMap
deployment: Deployment
swapManager: ISwapManager
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { OrderPlanner } from '@summerfi/order-planner-common/implementation'
import { Order, type IPositionsManager } from '@summerfi/sdk-common/orders'
import { Simulation, SimulationType } from '@summerfi/sdk-common/simulation'
import { ISimulation, SimulationType } from '@summerfi/sdk-common/simulation'
import { IUser } from '@summerfi/sdk-common/user'
import { ChainInfo, Maybe } from '@summerfi/sdk-common/common'
import { DeploymentIndex } from '@summerfi/deployment-utils'
Expand Down Expand Up @@ -29,7 +29,7 @@ export class OrderPlannerService implements IOrderPlannerService {
async buildOrder(params: {
user: IUser
positionsManager: IPositionsManager
simulation: Simulation<SimulationType>
simulation: ISimulation<SimulationType>
swapManager: ISwapManager
protocolsRegistry: IProtocolPluginsRegistry
}): Promise<Maybe<Order>> {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Order, type IPositionsManager } from '@summerfi/sdk-common/orders'
import { Simulation, SimulationType } from '@summerfi/sdk-common/simulation'
import { ISimulation, SimulationType } from '@summerfi/sdk-common/simulation'
import { IUser } from '@summerfi/sdk-common/user'
import { Maybe } from '@summerfi/sdk-common/common'
import { ISwapManager } from '@summerfi/swap-common/interfaces'
Expand All @@ -9,7 +9,7 @@ export interface IOrderPlannerService {
buildOrder<T extends SimulationType>(params: {
user: IUser
positionsManager: IPositionsManager
simulation: Simulation<T>
simulation: ISimulation<T>
swapManager: ISwapManager
protocolsRegistry: IProtocolPluginsRegistry
}): Promise<Maybe<Order>>
Expand Down
7 changes: 6 additions & 1 deletion sdk/order-planner-service/tests/mocks/SwapManagerMock.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { Address, ChainInfo, Percentage, Token, TokenAmount } from '@summerfi/sdk-common/common'
import { ISwapManager } from '@summerfi/swap-common/interfaces'
import { QuoteData, SwapData } from '@summerfi/swap-common/types'
import { QuoteData, SwapData, SpotData } from '@summerfi/sdk-common/swap'

export class SwapManagerMock implements ISwapManager {
private _swapDataReturnValue: SwapData = {} as SwapData
private _quoteDataReturnValue: QuoteData = {} as QuoteData
private _spotDataReturnValue: SpotData = {} as SpotData

private _lastGetSwapDataExactInputParams:
| {
Expand Down Expand Up @@ -52,6 +53,10 @@ export class SwapManagerMock implements ISwapManager {
return this._quoteDataReturnValue
}

async getSpotPrices(params: { chainInfo: ChainInfo; tokens: Token[] }): Promise<SpotData> {
return this._spotDataReturnValue
}

get swapDataReturnValue(): SwapData {
return this._swapDataReturnValue
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
import { FlashloanProvider, Simulation, SimulationType } from '@summerfi/sdk-common/simulation'
import { DeploymentIndex } from '@summerfi/deployment-utils'
import { ISwapManager } from '@summerfi/swap-common/interfaces'
import { Address, AddressValue, ChainFamilyMap, ChainInfo } from '@summerfi/sdk-common/common'
import { IPositionsManager } from '@summerfi/sdk-common/orders'
import {
FlashloanAction,
ReturnFundsAction,
SetApprovalAction,
ReturnFundsAction,
} from '@summerfi/protocol-plugins/plugins/common'
import { FlashloanProvider, ISimulation, SimulationType } from '@summerfi/sdk-common/simulation'
import { DeploymentIndex } from '@summerfi/deployment-utils'
import { ISwapManager } from '@summerfi/swap-common/interfaces'
import { Address, AddressValue, ChainFamilyMap, ChainInfo } from '@summerfi/sdk-common/common'
import { ProtocolName } from '@summerfi/sdk-common/protocols'

import { IPositionsManager } from '@summerfi/sdk-common/orders'
import { SetupDeployments } from '../utils/SetupDeployments'
import { UserMock } from '../mocks/UserMock'
import { SwapManagerMock } from '../mocks/SwapManagerMock'
Expand All @@ -25,7 +24,6 @@ import {
import assert from 'assert'
import { IUser } from '@summerfi/sdk-common/user'
import {
IContractProvider,
IPriceService,
IProtocolPluginsRegistry,
ITokenService,
Expand Down Expand Up @@ -90,7 +88,7 @@ describe('Order Planner Service', () => {
const sourcePosition = getMakerPosition()
const targetPosition = getSparkPosition()

const refinanceSimulation: Simulation<SimulationType.Refinance> = getRefinanceSimulation({
const refinanceSimulation: ISimulation<SimulationType.Refinance> = getRefinanceSimulation({
sourcePosition,
targetPosition,
})
Expand All @@ -114,7 +112,7 @@ describe('Order Planner Service', () => {
const sourcePosition = getMakerPosition()
const targetPosition = getSparkPosition()

const refinanceSimulation: Simulation<SimulationType.Refinance> = getRefinanceSimulation({
const refinanceSimulation: ISimulation<SimulationType.Refinance> = getRefinanceSimulation({
sourcePosition,
targetPosition,
})
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {
FlashloanProvider,
Simulation,
ISimulation,
SimulationSteps,
SimulationType,
TokenTransferTargetType,
Expand All @@ -11,13 +11,14 @@ import { Position } from '@summerfi/sdk-common/common'
export function getRefinanceSimulation(params: {
sourcePosition: Position
targetPosition: Position
}): Simulation<SimulationType.Refinance> {
}): ISimulation<SimulationType.Refinance> {
const { sourcePosition, targetPosition } = params

return {
simulationType: SimulationType.Refinance,
sourcePosition: sourcePosition,
targetPosition: targetPosition,
swaps: [],
steps: [
{
name: 'Flashloan',
Expand Down
12 changes: 11 additions & 1 deletion sdk/protocol-plugins/tests/builders/SwapActionBuilder.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@ import {
AddressValue,
ChainFamilyMap,
ChainInfo,
Price,
Percentage,
Token,
TokenAmount,
} from '@summerfi/sdk-common/common'
import { SimulationSteps, steps } from '@summerfi/sdk-common/simulation'
import { SwapProviderType } from '@summerfi/swap-common/enums'
import { SwapProviderType } from '@summerfi/sdk-common/swap'

import { SetupBuilderReturnType, setupBuilderParams } from '../utils/SetupBuilderParams'
import { SwapActionBuilder } from '../../src/plugins/common/builders'
Expand Down Expand Up @@ -58,8 +59,17 @@ describe('Swap Action Builder', () => {
type: SimulationSteps.Swap,
name: 'SwapStep',
inputs: {
provider: SwapProviderType.OneInch,
routes: [],
fromTokenAmount: fromAmount,
toTokenAmount: toAmount,
prices: [
Price.createFrom({
value: '0',
quoteToken: fromAmount.token,
baseToken: toAmount.token,
}),
],
fee: fee,
slippage,
},
Expand Down
4 changes: 2 additions & 2 deletions sdk/sdk-client/src/implementation/User.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
Wallet,
} from '@summerfi/sdk-common/common'
import { IPositionsManager, Order } from '@summerfi/sdk-common/orders'
import { Simulation, SimulationType } from '@summerfi/sdk-common/simulation'
import { ISimulation, SimulationType } from '@summerfi/sdk-common/simulation'
import { IUserClient } from '../interfaces/IUserClient'
import { IRPCClient } from '../interfaces/IRPCClient'
import { RPCClientType } from '../rpc/SDKClient'
Expand Down Expand Up @@ -49,7 +49,7 @@ export class User extends IRPCClient implements IUserClient {

public async newOrder(params: {
positionsManager: IPositionsManager
simulation: Simulation<SimulationType>
simulation: ISimulation<SimulationType>
}): Promise<Maybe<Order>> {
return await this.rpcClient.orders.buildOrder.mutate({
user: {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { IRefinanceParameters } from '@summerfi/sdk-common/orders'
import { Simulation, SimulationType } from '@summerfi/sdk-common/simulation'
import { ISimulation, SimulationType } from '@summerfi/sdk-common/simulation'
import { RPCClientType } from '../../rpc/SDKClient'
import { IRPCClient } from '../../interfaces/IRPCClient'

Expand All @@ -10,7 +10,7 @@ export class RefinanceSimulationManager extends IRPCClient {

public async simulateRefinancePosition(
params: IRefinanceParameters,
): Promise<Simulation<SimulationType.Refinance>> {
): Promise<ISimulation<SimulationType.Refinance>> {
const refinanceParameters: IRefinanceParameters = {
position: {
positionId: params.position.positionId,
Expand Down
4 changes: 2 additions & 2 deletions sdk/sdk-client/src/interfaces/IUserClient.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Maybe, Position, PositionId } from '@summerfi/sdk-common/common'

import { Simulation, SimulationType } from '@summerfi/sdk-common/simulation'
import { ISimulation, SimulationType } from '@summerfi/sdk-common/simulation'
import { IUser } from '@summerfi/sdk-common/user'
import { Order } from '@summerfi/sdk-common/orders'
import { IProtocol } from '@summerfi/sdk-common/protocols'
Expand Down Expand Up @@ -39,5 +39,5 @@ export interface IUserClient extends IUser {
*
* @returns The new order created for the user
*/
newOrder(params: { simulation: Simulation<SimulationType> }): Promise<Maybe<Order>>
newOrder(params: { simulation: ISimulation<SimulationType> }): Promise<Maybe<Order>>
}
7 changes: 4 additions & 3 deletions sdk/sdk-client/tests/queries/newOrder.subtest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ import { IProtocol, PoolType, ProtocolName } from '@summerfi/sdk-common/protocol
import { SDKManager } from '../../src/implementation/SDKManager'
import { RPCClientType } from '../../src/rpc/SDKClient'
import { MakerLendingPool } from '@summerfi/protocol-plugins/plugins/maker'
import { Simulation, SimulationType } from '@summerfi/sdk-common/simulation'
import { SparkLendingPool } from '@summerfi/protocol-plugins/plugins/spark'
import { ISimulation, SimulationType } from '@summerfi/sdk-common/simulation'
import {
Address,
ChainFamilyMap,
Expand All @@ -17,7 +18,6 @@ import {
} from '@summerfi/sdk-common/common'
import { IPositionsManager, Order } from '@summerfi/sdk-common/orders'
import { User } from '../../src/implementation/User'
import { SparkLendingPool } from '@summerfi/protocol-plugins/plugins/spark'

export default async function simulateNewOrder() {
const chainInfo: ChainInfo = ChainFamilyMap.Ethereum.Mainnet
Expand Down Expand Up @@ -77,9 +77,10 @@ export default async function simulateNewOrder() {
baseCurrency: DAI,
} as SparkLendingPool

const simulation: Simulation<SimulationType.Refinance> = {
const simulation: ISimulation<SimulationType.Refinance> = {
simulationType: SimulationType.Refinance,
sourcePosition: prevPosition,
swaps: [],
targetPosition: {
positionId: PositionId.createFrom({ id: '1234567890' }),
debtAmount: TokenAmount.createFrom({ token: DAI, amount: '56.78' }),
Expand Down
7 changes: 4 additions & 3 deletions sdk/sdk-client/tests/queries/simulateRefinance.subtest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ import { IProtocol, PoolType, ProtocolName } from '@summerfi/sdk-common/protocol
import { SDKManager } from '../../src/implementation/SDKManager'
import { RPCClientType } from '../../src/rpc/SDKClient'
import { MakerLendingPool } from '@summerfi/protocol-plugins/plugins/maker'
import { Simulation, SimulationType } from '@summerfi/sdk-common/simulation'
import { SparkLendingPool } from '@summerfi/protocol-plugins/plugins/spark'
import { ISimulation, SimulationType } from '@summerfi/sdk-common/simulation'
import {
Address,
ChainFamilyMap,
Expand All @@ -15,22 +16,22 @@ import {
TokenAmount,
} from '@summerfi/sdk-common/common'
import { IRefinanceParameters } from '@summerfi/sdk-common/orders'
import { SparkLendingPool } from '@summerfi/protocol-plugins/plugins/spark'

export default async function simulateRefinanceTest() {
type SimulateRefinanceType = RPCClientType['simulation']['refinance']['query']
const simulateRefinance: SimulateRefinanceType = jest.fn(async (params) => {
return {
simulationType: SimulationType.Refinance,
sourcePosition: params.position,
swaps: [],
targetPosition: {
positionId: PositionId.createFrom({ id: '0987654321' }),
debtAmount: params.position.debtAmount,
collateralAmount: params.position.collateralAmount,
pool: params.targetPool,
},
steps: [],
} as Simulation<SimulationType.Refinance>
} as ISimulation<SimulationType.Refinance>
})

const rpcClient = {
Expand Down
5 changes: 5 additions & 0 deletions sdk/sdk-common/src/common/implementation/Price.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { IPrice } from '../interfaces/IPrice'
import { isToken } from '../interfaces/IToken'
import { BigNumber } from 'bignumber.js'
import { SerializationService } from '../../services/SerializationService'
import { CurrencySymbol } from '../enums/CurrencySymbol'
import { Token } from './Token'
Expand Down Expand Up @@ -32,6 +33,10 @@ export class Price implements IPrice {
return `${this.value} ${this.baseToken.symbol}/${this.quoteToken}`
}
}

public toBN(): BigNumber {
return new BigNumber(this.value)
}
}

SerializationService.registerClass(Price)
23 changes: 21 additions & 2 deletions sdk/sdk-common/src/common/implementation/TokenAmount.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { BigNumber } from 'bignumber.js'
import { Percentage } from './Percentage'
import { Token } from './Token'
import { SerializationService } from '../../services/SerializationService'
import { ITokenAmount } from '../interfaces/ITokenAmount'
Expand Down Expand Up @@ -60,14 +61,28 @@ export class TokenAmount implements ITokenAmount {
})
}

public multiply(multiplier: string | number): TokenAmount {
public multiply(multiplier: Percentage | string | number): TokenAmount {
if (multiplier instanceof Percentage) {
return new TokenAmount({
token: this.token,
amount: this.amountBN.times(multiplier.value).toString(),
})
}

return new TokenAmount({
token: this.token,
amount: this.amountBN.times(multiplier).toString(),
})
}

public divide(divisor: string | number): TokenAmount {
public divide(divisor: Percentage | string | number): TokenAmount {
if (divisor instanceof Percentage) {
return new TokenAmount({
token: this.token,
amount: this.amountBN.div(divisor.value).toString(),
})
}

return new TokenAmount({ token: this.token, amount: this.amountBN.div(divisor).toString() })
}

Expand All @@ -79,6 +94,10 @@ export class TokenAmount implements ITokenAmount {
return new BigNumber(this.amount).times(this._baseUnitFactor).toFixed(0)
}

public toBaseUnitAsBn(): BigNumber {
return new BigNumber(this.amount).times(this._baseUnitFactor)
}

public toBN(): BigNumber {
return new BigNumber(this.amount)
}
Expand Down
Loading

0 comments on commit 388d71f

Please sign in to comment.