Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat/synfutures connector #321

Open
wants to merge 12 commits into
base: development
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
"@pangolindex/sdk": "^1.1.0",
"@perp/sdk-curie": "^1.16.0",
"@sushiswap/sdk": "^5.0.0-canary.116",
"@synfutures/oyster-sdk": "^0.1.6",
"@taquito/rpc": "^17.0.0",
"@taquito/signer": "^17.0.0",
"@taquito/taquito": "^17.0.0",
Expand Down
89 changes: 69 additions & 20 deletions src/amm/amm.controllers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,13 +51,22 @@ import {
} from '../connectors/tinyman/tinyman.controllers';
import {
getPriceData as perpPriceData,
createTakerOrder,
createTakerOrder as perpCreateTakerOrder,
estimateGas as perpEstimateGas,
getPosition,
getAvailablePairs,
checkMarketStatus,
getAccountValue,
getPosition as perpGetPosition,
getAvailablePairs as perpGetAvailablePairs,
checkMarketStatus as perpCheckMarketStatus,
getAccountValue as perpGetAccountValue,
} from '../connectors/perp/perp.controllers';
import {
getPriceData as synfuturesPriceData,
createTakerOrder as synfuturesCreateTakerOrder,
estimateGas as synfuturesEstimateGas,
getPosition as synfuturesGetPosition,
getAvailablePairs as synfuturesGetAvailablePairs,
checkMarketStatus as synfuturesCheckMarketStatus,
getAccountValue as synfuturesGetAccountValue,
} from '../connectors/synfutures/synfutures.controllers';
import {
price as plentyPrice,
trade as plentyTrade,
Expand All @@ -78,6 +87,7 @@ import {
NetworkSelectionRequest,
Perpish,
RefAMMish,
SynFuturesish,
Tezosish,
Uniswapish,
UniswapLPish,
Expand All @@ -88,6 +98,7 @@ import { Plenty } from '../connectors/plenty/plenty';
import { QuipuSwap } from '../connectors/quipuswap/quipuswap';
import { Osmosis } from '../chains/osmosis/osmosis';
import { Carbonamm } from '../connectors/carbon/carbonAMM';
import { Perp } from '../connectors/perp/perp';

export async function price(req: PriceRequest): Promise<PriceResponse> {
const chain = await getInitializedChain<
Expand Down Expand Up @@ -266,83 +277,121 @@ export async function perpMarketPrices(
req: PriceRequest
): Promise<PerpPricesResponse> {
const chain = await getInitializedChain<Ethereumish>(req.chain, req.network);
const connector: Perpish = await getConnector<Perpish>(
const connector: Perpish | SynFuturesish = await getConnector<Perpish | SynFuturesish>(
req.chain,
req.network,
req.connector
);
return perpPriceData(chain, connector, req);

if (connector instanceof Perp) {
return perpPriceData(chain, <Perpish>connector, req);
} else {
return synfuturesPriceData(chain, <SynFuturesish>connector, req);
}
}

export async function perpOrder(
req: PerpCreateTakerRequest,
isOpen: boolean
): Promise<PerpCreateTakerResponse> {
const chain = await getInitializedChain<Ethereumish>(req.chain, req.network);
const connector: Perpish = await getConnector<Perpish>(
const connector: Perpish | SynFuturesish = await getConnector<Perpish | SynFuturesish>(
req.chain,
req.network,
req.connector,
req.address
);
return createTakerOrder(chain, connector, req, isOpen);

if (connector instanceof Perp) {
return perpCreateTakerOrder(chain, <Perpish>connector, req, isOpen);
} else {
return synfuturesCreateTakerOrder(chain, <SynFuturesish>connector, req, isOpen);
}
}

export async function perpPosition(
req: PerpPositionRequest
): Promise<PerpPositionResponse> {
const chain = await getInitializedChain<Ethereumish>(req.chain, req.network);
const connector: Perpish = await getConnector<Perpish>(
const connector: Perpish | SynFuturesish = await getConnector<Perpish | SynFuturesish>(
req.chain,
req.network,
req.connector,
req.address
);
return getPosition(chain, connector, req);

if (connector instanceof Perp) {
return perpGetPosition(chain, <Perpish>connector, req);
} else {
return synfuturesGetPosition(chain, <SynFuturesish>connector, req);
}
}

export async function perpBalance(
req: PerpBalanceRequest
): Promise<PerpBalanceResponse> {
const chain = await getInitializedChain(req.chain, req.network);
const connector: Perpish = <Perpish>(
await getConnector(req.chain, req.network, req.connector, req.address)
const connector: Perpish | SynFuturesish = await getConnector<Perpish | SynFuturesish>(
req.chain,
req.network,
req.connector,
req.address
);
return getAccountValue(chain, connector);

if (connector instanceof Perp) {
return perpGetAccountValue(chain, <Perpish>connector);
} else {
return synfuturesGetAccountValue(chain, <SynFuturesish>connector, req);
}
}

export async function perpPairs(
req: NetworkSelectionRequest
): Promise<PerpAvailablePairsResponse> {
const chain = await getInitializedChain<Ethereumish>(req.chain, req.network);
const connector: Perpish = await getConnector<Perpish>(
const connector: Perpish | SynFuturesish = await getConnector<Perpish | SynFuturesish>(
req.chain,
req.network,
req.connector
);
return getAvailablePairs(chain, connector);

if (connector instanceof Perp) {
return perpGetAvailablePairs(chain, <Perpish>connector);
} else {
return synfuturesGetAvailablePairs(chain, <SynFuturesish>connector);
}
}

export async function getMarketStatus(
req: PerpMarketRequest
): Promise<PerpMarketResponse> {
const chain = await getInitializedChain<Ethereumish>(req.chain, req.network);
const connector: Perpish = await getConnector<Perpish>(
const connector: Perpish | SynFuturesish = await getConnector<Perpish | SynFuturesish>(
req.chain,
req.network,
req.connector
);
return checkMarketStatus(chain, connector, req);

if (connector instanceof Perp) {
return perpCheckMarketStatus(chain, <Perpish>connector, req);
} else {
return synfuturesCheckMarketStatus(chain, <SynFuturesish>connector, req);
}
}

export async function estimatePerpGas(
req: NetworkSelectionRequest
): Promise<EstimateGasResponse> {
const chain = await getInitializedChain<Ethereumish>(req.chain, req.network);
const connector: Perpish = await getConnector<Perpish>(
const connector: Perpish | SynFuturesish = await getConnector<Perpish | SynFuturesish>(
req.chain,
req.network,
req.connector
);
return perpEstimateGas(chain, connector);

if (connector instanceof Perp) {
return perpEstimateGas(chain, <Perpish>connector);
} else {
return synfuturesEstimateGas(chain, <SynFuturesish>connector);
}
}
4 changes: 4 additions & 0 deletions src/amm/amm.requests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,7 @@ export interface PerpPricesResponse {
markPrice: string;
indexPrice: string;
indexTwapPrice: string;
fairPrice?: string;
}

export interface PerpMarketRequest extends NetworkSelectionRequest {
Expand All @@ -209,6 +210,7 @@ export interface PerpMarketResponse {

export interface PerpBalanceRequest extends NetworkSelectionRequest {
address: string;
quote?: string;
}

export interface PerpBalanceResponse {
Expand All @@ -228,6 +230,8 @@ export interface PerpPositionResponse extends PerpPosition {
latency: number;
base: string;
quote: string;
balance?: string;
liquidationPrice?: string;
}

export interface PerpAvailablePairsResponse {
Expand Down
8 changes: 8 additions & 0 deletions src/chains/ethereum/ethereum.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { EVMController } from './evm.controllers';

import { UniswapConfig } from '../../connectors/uniswap/uniswap.config';
import { Perp } from '../../connectors/perp/perp';
import { SynFutures } from '../../connectors/synfutures/synfutures';
import { SushiswapConfig } from '../../connectors/sushiswap/sushiswap.config';
import { OpenoceanConfig } from '../../connectors/openocean/openocean.config';
import { Curve } from '../../connectors/curve/curve';
Expand Down Expand Up @@ -208,6 +209,13 @@ export class Ethereum extends EthereumBase implements Ethereumish {
throw Error('Perp curie not ready');
}
spender = perp.perp.contracts.vault.address;
} else if (reqSpender === 'synfutures') {
const synfutures = SynFutures.getInstance(this.chainName, this._chain);
if (!synfutures.ready()) {
synfutures.init();
throw Error('Synfutures not ready');
}
spender = synfutures.synfutures.contracts.gate.address;
} else if (reqSpender === 'openocean') {
spender = OpenoceanConfig.config.routerAddress('ethereum', this._chain);
} else if (reqSpender === 'curve') {
Expand Down
15 changes: 8 additions & 7 deletions src/chains/ethereum/ethereum.validators.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ export const isAddress = (str: string): boolean => {
export const validateAddress: Validator = mkValidator(
'address',
invalidAddressError,
(val) => typeof val === 'string' && isAddress(val)
(val) => typeof val === 'string' && isAddress(val),
);

// given a request, look for a key called spender that is 'uniswap' or an Ethereum address
Expand All @@ -50,6 +50,7 @@ export const validateSpender: Validator = mkValidator(
typeof val === 'string' &&
(val === 'uniswap' ||
val === 'perp' ||
val === 'synfutures' ||
val === 'uniswapLP' ||
val === 'pangolin' ||
val === 'traderjoe' ||
Expand All @@ -64,7 +65,7 @@ export const validateSpender: Validator = mkValidator(
val === 'xsswap' ||
val === 'curve' ||
val === 'carbonamm' ||
isAddress(val))
isAddress(val)),
);

export const validateNonce: Validator = mkValidator(
Expand All @@ -73,33 +74,33 @@ export const validateNonce: Validator = mkValidator(
(val) =>
typeof val === 'undefined' ||
(typeof val === 'number' && val >= 0 && Number.isInteger(val)),
true
true,
);

export const validateMaxFeePerGas: Validator = mkValidator(
'maxFeePerGas',
invalidMaxFeePerGasError,
(val) => typeof val === 'string' && isNaturalNumberString(val),
true
true,
);

export const validateMaxPriorityFeePerGas: Validator = mkValidator(
'maxPriorityFeePerGas',
invalidMaxPriorityFeePerGasError,
(val) => typeof val === 'string' && isNaturalNumberString(val),
true
true,
);

export const validateChain: Validator = mkValidator(
'chain',
invalidChainError,
(val) => typeof val === 'string'
(val) => typeof val === 'string',
);

export const validateNetwork: Validator = mkValidator(
'network',
invalidNetworkError,
(val) => typeof val === 'string'
(val) => typeof val === 'string',
);

// request types and corresponding validators
Expand Down
7 changes: 7 additions & 0 deletions src/connectors/connectors.routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { MadMeerkatConfig } from './mad_meerkat/mad_meerkat.config';
import { OpenoceanConfig } from './openocean/openocean.config';
import { PangolinConfig } from './pangolin/pangolin.config';
import { PerpConfig } from './perp/perp.config';
import { SynFuturesConfig } from './synfutures/synfutures.config';
import { QuickswapConfig } from './quickswap/quickswap.config';
import { SushiswapConfig } from './sushiswap/sushiswap.config';
import { TraderjoeConfig } from './traderjoe/traderjoe.config';
Expand Down Expand Up @@ -72,6 +73,12 @@ export namespace ConnectorsRoutes {
chain_type: PerpConfig.config.chainType,
available_networks: PerpConfig.config.availableNetworks,
},
{
name: 'synfutures',
trading_type: SynFuturesConfig.config.tradingTypes,
chain_type: SynFuturesConfig.config.chainType,
available_networks: SynFuturesConfig.config.availableNetworks,
},
{
name: 'sushiswap',
trading_type: SushiswapConfig.config.tradingTypes,
Expand Down
19 changes: 19 additions & 0 deletions src/connectors/synfutures/synfutures.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { ConfigManagerV2 } from '../../services/config-manager-v2';
import { AvailableNetworks } from '../../services/config-manager-types';
export namespace SynFuturesConfig {
export interface NetworkConfig {
allowedSlippage: string;
ttl: number;
tradingTypes: Array<string>;
chainType: string;
availableNetworks: Array<AvailableNetworks>;
}

export const config: NetworkConfig = {
allowedSlippage: ConfigManagerV2.getInstance().get(`synfutures.allowedSlippage`),
ttl: ConfigManagerV2.getInstance().get(`synfutures.versions.ttl`),
tradingTypes: ['AMM_Perpetual'],
chainType: 'EVM',
availableNetworks: [{ chain: 'ethereum', networks: ['blast'] }],
};
}
Loading
Loading