diff --git a/README.md b/README.md index e3fc76cf9..31c26a582 100644 --- a/README.md +++ b/README.md @@ -471,6 +471,8 @@ startStatusCheck(deltaAuction.id); For more Delta protocol usage, and **Crosschain Delta Orders**, refer to [DELTA.md](./docs/DELTA.md) +For **External Delta Orders** (orders that delegate token handling to an external handler contract, enabling complex DeFi strategies like Aave collateral/debt swaps), refer to [EXTERNAL_ORDERS.md](./docs/EXTERNAL_ORDERS.md) + ------------ ### Market Swap handling diff --git a/docs/EXTERNAL_ORDERS.md b/docs/EXTERNAL_ORDERS.md new file mode 100644 index 000000000..f9cf20cf0 --- /dev/null +++ b/docs/EXTERNAL_ORDERS.md @@ -0,0 +1,217 @@ +## External Delta Orders + +External orders delegate token handling to an external **handler** contract, enabling complex DeFi strategies that go beyond simple token swaps. The handler manages the actual token logic (e.g. Aave flash loan + collateral/debt swap), while the Delta protocol handles the auction, settlement, and signature verification. + +### Handler Contract + +The handler contract must be deployed by the integrator and implement the `IExternalProtocolHandler` interface: + +```solidity +interface IExternalProtocolHandler { + function execute( + address user, + address tokenIn, + uint256 amountIn, + address tokenOut, + uint256 amountOut, + bytes calldata data + ) external; +} +``` + +The `data` field carries protocol-specific parameters (e.g. an Aave operation type). A reference implementation is the [Aave handler deployed on Ethereum](https://etherscan.io/address/0xb4a2c36668cf8b19fe08f263e3685a5e16e82912#code). + +### Key Differences from Standard Delta Orders + +| Feature | Standard Order | External Order | +|---|---|---| +| `beneficiary` field | yes | no (output goes to owner) | +| `bridge` field | yes | no | +| `handler` field | no | yes (required) | +| `data` field | no | yes (required) | +| Cross-chain support | yes | no | + + +--- + +### 1. Construct an SDK object + +```ts +const account = userAddress; +const deltaSDK = constructSimpleSDK( + { chainId: 1, axios }, // Ethereum + { + ethersProviderOrSigner: signer, + EthersContract: ethers.Contract, + account, + } +); +// for usage with different web3 provider libraries refer to the main README +``` + +### 2. Request prices for a Token pair + +```ts +const USDC = '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48'; +const WETH = '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2'; +const AAVE_HANDLER = '0xb4a2c36668cf8b19fe08f263e3685a5e16e82912'; +const amount = ethers.utils.parseUnits('1', 6).toString(); // 1 USDC + +const deltaPrice = await deltaSDK.getDeltaPrice({ + srcToken: USDC, + destToken: WETH, + amount, + userAddress: account, + srcDecimals: 6, + destDecimals: 18, + side: SwapSide.SELL, +}); +``` + +### 3. Perform any prerequisites required by the handler + +Each handler may have its own prerequisites (token approvals, delegation, position setup, etc.). Refer to your handler's documentation for details. + +For example, the [Aave handler](https://etherscan.io/address/0xb4a2c36668cf8b19fe08f263e3685a5e16e82912#code) requires aToken approval before a collateral swap: + +```ts +const aUSDC = new ethers.Contract(USDC, ['function approve(address,uint256)'], signer); +await aUSDC.approve(AAVE_HANDLER, amount); +``` + +### 4. Build, sign, and submit the External Order + +#### Using `submitExternalDeltaOrder` (recommended) + +The simplest approach — builds, signs, and posts the order in one call: + +```ts +const deltaAuction = await deltaSDK.submitExternalDeltaOrder({ + deltaPrice, + owner: account, + handler: AAVE_HANDLER, // your deployed handler contract + data: '0x0000000000000000000000000000000000000000000000000000000000000000', // protocol-specific bytes + srcToken: USDC, + destToken: WETH, + srcAmount: amount, + slippage: 50, // 0.5% in bps +}); +``` + +#### Using individual steps + +For more control, you can build, sign, and post separately: + +```ts +const signableOrderData = await deltaSDK.buildExternalDeltaOrder({ + deltaPrice, + owner: account, + handler: AAVE_HANDLER, + data: '0x0000000000000000000000000000000000000000000000000000000000000000', + srcToken: USDC, + destToken: WETH, + srcAmount: amount, + slippage: 50, // 0.5% in bps +}); + +const signature = await deltaSDK.signExternalDeltaOrder(signableOrderData); + +const deltaAuction = await deltaSDK.postExternalDeltaOrder({ + order: signableOrderData.data, + signature, +}); +``` + +### 5. Wait for execution + +```ts +const intervalId = setInterval(async () => { + const auction = await deltaSDK.getDeltaOrderById(deltaAuction.id); + console.log('Status:', auction.status); + + if (auction.status === 'EXECUTED' || auction.status === 'FAILED') { + clearInterval(intervalId); + } +}, 3000); +``` + +### 6. Query External Orders + +```ts +// fetch a specific external order +const order = await deltaSDK.getDeltaOrderById(orderId); + +// list external orders only +const orders = await deltaSDK.getDeltaOrders({ + owner: account, + onChainOrderType: 'ExternalOrder', +}); +``` + +--- + +## Specifying Amounts + +There are two ways to specify amounts: + +**With `slippage` (recommended)** — the SDK computes the slippage-adjusted amount from `deltaPrice` automatically: + +```ts +// SELL: provide srcAmount + slippage → destAmount auto-computed +await deltaSDK.buildExternalDeltaOrder({ + // ... + srcAmount: amount, + slippage: 50, // 0.5% in bps +}); + +// BUY: provide destAmount + slippage → srcAmount auto-computed +await deltaSDK.buildExternalDeltaOrder({ + // ... + destAmount: amount, + slippage: 50, +}); +``` + +**With explicit amounts** — you compute both amounts yourself: + +```ts +await deltaSDK.buildExternalDeltaOrder({ + // ... + srcAmount: amount, + destAmount: destAmountAfterSlippage, + side: SwapSide.SELL, // or SwapSide.BUY +}); +``` + +--- + +## Pre-signing External Orders + +For smart contract wallets or other cases where EIP-712 signatures are not available, you can pre-sign an external order on-chain: + +```ts +const signableOrderData = await deltaSDK.buildExternalDeltaOrder({ + deltaPrice, + owner: account, + handler: AAVE_HANDLER, + data: '0x0000000000000000000000000000000000000000000000000000000000000000', + srcToken: USDC, + destToken: WETH, + srcAmount: amount, + slippage: 50, +}); + +// on-chain pre-sign transaction +const tx = await deltaSDK.preSignExternalDeltaOrder(signableOrderData); +await tx.wait(); + +// post with empty signature +const deltaAuction = await deltaSDK.postExternalDeltaOrder({ + order: signableOrderData.data, + signature: '0x', +}); +``` + +--- + +#### A more detailed example can be found in [examples/externalDelta](../src/examples/externalDelta.ts) diff --git a/package.json b/package.json index 973f827f6..a1e1be5e2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@velora-dex/sdk", - "version": "9.3.6", + "version": "9.4.0", "main": "dist/index.js", "module": "dist/sdk.esm.js", "typings": "dist/index.d.ts", diff --git a/src/examples/delta.ts b/src/examples/delta.ts index e886b4797..208e4d948 100644 --- a/src/examples/delta.ts +++ b/src/examples/delta.ts @@ -14,10 +14,13 @@ const fetcher = constructAxiosFetcher(axios); const provider = ethers.getDefaultProvider(1); const signer = Wallet.createRandom().connect(provider); const account = signer.address; -const contractCaller = constructEthersContractCaller({ - ethersProviderOrSigner: provider, - EthersContract: ethers.Contract, -}); +const contractCaller = constructEthersContractCaller( + { + ethersProviderOrSigner: provider, + EthersContract: ethers.Contract, + }, + account +); // type AdaptersFunctions & ApproveTokenFunctions const deltaSDK = constructPartialSDK( @@ -51,14 +54,6 @@ async function simpleDeltaFlow() { const tx = await deltaSDK.approveTokenForDelta(amount, DAI_TOKEN); await tx.wait(); - const slippagePercent = 0.5; - const destAmountAfterSlippage = BigInt( - // get rid of exponential notation - - +(+deltaPrice.destAmount * (1 - slippagePercent / 100)).toFixed(0) - // get rid of decimals - ).toString(10); - const deltaAuction = await deltaSDK.submitDeltaOrder({ deltaPrice, owner: account, @@ -67,7 +62,7 @@ async function simpleDeltaFlow() { srcToken: DAI_TOKEN, destToken: USDC_TOKEN, srcAmount: amount, - destAmount: destAmountAfterSlippage, // minimum acceptable destAmount + slippage: 50, // 50 bps = 0.5% slippage, destAmount auto-computed from deltaPrice }); // poll if necessary @@ -92,12 +87,6 @@ async function manualDeltaFlow() { const tx = await deltaSDK.approveTokenForDelta(amount, DAI_TOKEN); await tx.wait(); - const slippagePercent = 0.5; - const destAmountAfterSlippage = ( - +deltaPrice.destAmount * - (1 - slippagePercent / 100) - ).toString(10); - const signableOrderData = await deltaSDK.buildDeltaOrder({ deltaPrice, owner: account, @@ -106,7 +95,7 @@ async function manualDeltaFlow() { srcToken: DAI_TOKEN, destToken: USDC_TOKEN, srcAmount: amount, - destAmount: destAmountAfterSlippage, // minimum acceptable destAmount + slippage: 50, // 50 bps = 0.5% slippage, destAmount auto-computed from deltaPrice }); const signature = await deltaSDK.signDeltaOrder(signableOrderData); diff --git a/src/examples/externalDelta.ts b/src/examples/externalDelta.ts new file mode 100644 index 000000000..6144d5b4f --- /dev/null +++ b/src/examples/externalDelta.ts @@ -0,0 +1,162 @@ +/* eslint-disable @typescript-eslint/no-unused-vars */ +import axios from 'axios'; +import { ethers, Wallet } from 'ethersV5'; +import { + constructPartialSDK, + constructEthersContractCaller, + constructAxiosFetcher, + constructAllDeltaOrdersHandlers, + SwapSide, +} from '..'; +import { startStatusCheck } from './helpers/delta'; + +const fetcher = constructAxiosFetcher(axios); + +const provider = ethers.getDefaultProvider(1); // Ethereum +const signer = Wallet.createRandom().connect(provider); +const account = signer.address; +const contractCaller = constructEthersContractCaller( + { + ethersProviderOrSigner: signer, + EthersContract: ethers.Contract, + }, + account +); + +const deltaSDK = constructPartialSDK( + { + chainId: 1, // Ethereum + fetcher, + contractCaller, + }, + constructAllDeltaOrdersHandlers +); + +// Ethereum tokens +const USDC = '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48'; +const WETH = '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2'; + +// Aave external handler on Ethereum (https://etherscan.io/address/0xb4a2c36668cf8b19fe08f263e3685a5e16e82912#code) +// The handler contract is provided by the integrator and must implement IExternalProtocolHandler. +// Different handlers serve different purposes and may have different prerequisites +// (e.g. token approvals, credit delegation, position setup). +const AAVE_HANDLER = '0xb4a2c36668cf8b19fe08f263e3685a5e16e82912'; + +// Aave-specific order types passed as `data` field. +// The `data` encoding is handler-specific — each handler defines its own format. +const AaveOrderTypes = { + COLLATERAL_SWAP: + '0x0000000000000000000000000000000000000000000000000000000000000000', + DEBT_SWAP: + '0x0000000000000000000000000000000000000000000000000000000000000001', + REPAY_WITH_COLLATERAL: + '0x0000000000000000000000000000000000000000000000000000000000000002', +}; + +// Aave Collateral Swap: swap one collateral asset for another (SELL side) +// Prerequisites: user must approve the source aToken to the handler +async function collateralSwapFlow() { + const amount = ethers.utils.parseUnits('1', 6).toString(); // 1 USDC + + const deltaPrice = await deltaSDK.getDeltaPrice({ + srcToken: USDC, + destToken: WETH, + amount, + userAddress: account, + srcDecimals: 6, + destDecimals: 18, + side: SwapSide.SELL, + }); + + const signableOrderData = await deltaSDK.buildExternalDeltaOrder({ + deltaPrice, + owner: account, + handler: AAVE_HANDLER, + data: AaveOrderTypes.COLLATERAL_SWAP, + srcToken: USDC, + destToken: WETH, + srcAmount: amount, + slippage: 50, // 0.5% slippage in bps + }); + + const signature = await deltaSDK.signExternalDeltaOrder(signableOrderData); + + const deltaAuction = await deltaSDK.postExternalDeltaOrder({ + order: signableOrderData.data, + signature, + }); + + startStatusCheck(() => deltaSDK.getDeltaOrderById(deltaAuction.id)); +} + +// Aave Debt Swap: swap one debt for another (BUY side) +// Prerequisites: user must grant borrowAllowance on the source variable debt token to the handler +async function debtSwapFlow() { + const debtAmount = ethers.utils.parseUnits('1', 6).toString(); // amount of debt to swap + + const deltaPrice = await deltaSDK.getDeltaPrice({ + srcToken: USDC, + destToken: WETH, + amount: debtAmount, + userAddress: account, + srcDecimals: 6, + destDecimals: 18, + side: SwapSide.BUY, + }); + + const signableOrderData = await deltaSDK.buildExternalDeltaOrder({ + deltaPrice, + owner: account, + handler: AAVE_HANDLER, + data: AaveOrderTypes.DEBT_SWAP, + srcToken: USDC, + destToken: WETH, + destAmount: debtAmount, + slippage: 50, // 0.5% slippage in bps + }); + + const signature = await deltaSDK.signExternalDeltaOrder(signableOrderData); + + const deltaAuction = await deltaSDK.postExternalDeltaOrder({ + order: signableOrderData.data, + signature, + }); + + startStatusCheck(() => deltaSDK.getDeltaOrderById(deltaAuction.id)); +} + +// Aave Repay with Collateral: use collateral to repay debt (BUY side) +// Prerequisites: user must approve the source aToken to the handler +async function repayWithCollateralFlow() { + const collateralAmount = ethers.utils.parseUnits('1', 6).toString(); + + const deltaPrice = await deltaSDK.getDeltaPrice({ + srcToken: USDC, + destToken: WETH, + amount: collateralAmount, + userAddress: account, + srcDecimals: 6, + destDecimals: 18, + side: SwapSide.BUY, + }); + + const signableOrderData = await deltaSDK.buildExternalDeltaOrder({ + deltaPrice, + owner: account, + handler: AAVE_HANDLER, + data: AaveOrderTypes.REPAY_WITH_COLLATERAL, + srcToken: USDC, + destToken: WETH, + destAmount: collateralAmount, + slippage: 50, // 0.5% slippage in bps + }); + + const signature = await deltaSDK.signExternalDeltaOrder(signableOrderData); + + const deltaAuction = await deltaSDK.postExternalDeltaOrder({ + order: signableOrderData.data, + signature, + }); + + startStatusCheck(() => deltaSDK.getDeltaOrderById(deltaAuction.id)); +} diff --git a/src/examples/helpers/delta.ts b/src/examples/helpers/delta.ts index a2972df17..0c1247380 100644 --- a/src/examples/helpers/delta.ts +++ b/src/examples/helpers/delta.ts @@ -1,20 +1,24 @@ -import { DeltaAuction, DeltaOrderFromAPI } from '../..'; +import { DeltaAuction } from '../..'; function isExecutedDeltaAuction( - auction: Omit, + auction: DeltaAuction, waitForCrosschain = true // only consider executed when destChain work is done ) { if (auction.status !== 'EXECUTED') return false; // crosschain Order is executed on destChain if bridgeStatus is filled - if (waitForCrosschain && auction.order.bridge.destinationChainId !== 0) { + if ( + waitForCrosschain && + auction.onChainOrderType === 'Order' && + auction.order.bridge.destinationChainId !== 0 + ) { return auction.bridgeStatus === 'filled'; } return true; } -type GetDeltaOrderFn = () => Promise; +type GetDeltaOrderFn = () => Promise; function fetchOrderPeriodically(getDeltaOrder: GetDeltaOrderFn) { const intervalId = setInterval(async () => { diff --git a/src/index.ts b/src/index.ts index d9b56e883..3fbd2b73a 100644 --- a/src/index.ts +++ b/src/index.ts @@ -144,17 +144,18 @@ import type { BridgeMetadata, BridgeStatus, Bridge, + ExternalDeltaOrder, + OnChainOrderType, + SwapSideUnion, } from './methods/delta/helpers/types'; import { BuildDeltaOrderDataParams, BuildDeltaOrderFunctions, constructBuildDeltaOrder, SignableDeltaOrderData, - SwapSideUnion, } from './methods/delta/buildDeltaOrder'; import { constructPostDeltaOrder, - DeltaOrderApiResponse, PostDeltaOrderFunctions, PostDeltaOrderParams, } from './methods/delta/postDeltaOrder'; @@ -203,6 +204,26 @@ import { IsTokenSupportedInDeltaFunctions, } from './methods/delta/isTokenSupportedInDelta'; +import { + constructBuildExternalDeltaOrder, + BuildExternalDeltaOrderFunctions, + BuildExternalDeltaOrderParams, +} from './methods/delta/buildExternalDeltaOrder'; +import type { SignableExternalOrderData } from './methods/delta/helpers/buildExternalOrderData'; +import { + constructSignExternalDeltaOrder, + SignExternalDeltaOrderFunctions, +} from './methods/delta/signExternalDeltaOrder'; +import { + constructPostExternalDeltaOrder, + PostExternalDeltaOrderFunctions, + PostExternalDeltaOrderParams, +} from './methods/delta/postExternalDeltaOrder'; +import { + constructPreSignExternalDeltaOrder, + PreSignExternalDeltaOrderFunctions, +} from './methods/delta/preSignExternalDeltaOrder'; + import { constructGetQuote, GetQuoteFunctions, @@ -235,8 +256,10 @@ export { export { constructAllDeltaOrdersHandlers, constructSubmitDeltaOrder, + constructSubmitExternalDeltaOrder, DeltaOrderHandlers, SubmitDeltaOrderParams, + SubmitExternalDeltaOrderParams, } from './methods/delta'; export type { @@ -309,6 +332,11 @@ export { constructCancelDeltaOrder, constructDeltaTokenModule, constructApproveTokenForDelta, + // External Delta methods + constructBuildExternalDeltaOrder, + constructSignExternalDeltaOrder, + constructPostExternalDeltaOrder, + constructPreSignExternalDeltaOrder, // Quote methods constructGetQuote, // different helpers @@ -382,7 +410,6 @@ export type { DeltaAuction, DeltaAuctionStatus, DeltaOrderFilterByStatus, - DeltaOrderApiResponse, DeltaOrderFromAPI, // bridge part of DeltaOrder BridgeMetadata, @@ -407,6 +434,16 @@ export type { CancelAndWithdrawDeltaOrderParams, DepositNativeAndPreSignParams, DepositNativeAndPreSignDeltaOrderParams, + // External Delta types + ExternalDeltaOrder, + OnChainOrderType, + SignableExternalOrderData, + BuildExternalDeltaOrderParams, + BuildExternalDeltaOrderFunctions, + SignExternalDeltaOrderFunctions, + PostExternalDeltaOrderFunctions, + PostExternalDeltaOrderParams, + PreSignExternalDeltaOrderFunctions, // types for Quote methods GetQuoteFunctions, QuoteParams, diff --git a/src/methods/delta/buildDeltaOrder.ts b/src/methods/delta/buildDeltaOrder.ts index ff287644f..c84479cf5 100644 --- a/src/methods/delta/buildDeltaOrder.ts +++ b/src/methods/delta/buildDeltaOrder.ts @@ -1,8 +1,4 @@ -import type { - ConstructFetchInput, - EnumerateLiteral, - RequestParameters, -} from '../../types'; +import type { ConstructFetchInput, RequestParameters } from '../../types'; import { constructGetDeltaContract } from './getDeltaContract'; import type { BridgePrice } from './getDeltaPrice'; import { constructGetPartnerFee } from './getPartnerFee'; @@ -11,15 +7,13 @@ import { type BuildDeltaOrderDataInput, type SignableDeltaOrderData, } from './helpers/buildDeltaOrderData'; +import type { AmountsWithSlippage } from './helpers/types'; import { SwapSideToOrderKind } from './helpers/types'; -import { SwapSide } from '../../constants'; +import { resolvePartnerFee, resolveAmounts } from './helpers/misc'; import type { MarkOptional } from 'ts-essentials'; -import { ZERO_ADDRESS } from '../common/orders/buildOrderData'; export type { SignableDeltaOrderData } from './helpers/buildDeltaOrderData'; -export type SwapSideUnion = EnumerateLiteral; - -export type BuildDeltaOrderDataParams = { +type BuildDeltaOrderDataParamsBase = { /** @description The address of the order owner */ owner: string; /** @description The address of the order beneficiary */ @@ -28,10 +22,6 @@ export type BuildDeltaOrderDataParams = { srcToken: string; // lowercase /** @description The address of the dest token. For Crosschain Order - destination token on the destination chain */ destToken: string; // lowercase - /** @description The amount of src token to swap */ - srcAmount: string; // wei - /** @description The minimum amount of dest token to receive */ - destAmount: string; // wei, deltaPrice.destAmount - slippage /** @description The deadline for the order */ deadline?: number; // seconds /** @description The nonce of the order */ @@ -68,12 +58,13 @@ export type BuildDeltaOrderDataParams = { /** @description A boolean indicating whether the surplus should be capped. True by default */ capSurplus?: boolean; - /** @description The side of the order. Default is SELL */ - side?: SwapSideUnion; /** @description Metadata for the order, hex string */ metadata?: string; }; +export type BuildDeltaOrderDataParams = BuildDeltaOrderDataParamsBase & + AmountsWithSlippage; + type BuildDeltaOrder = ( buildOrderParams: BuildDeltaOrderDataParams, requestParams?: RequestParameters @@ -100,50 +91,11 @@ export const constructBuildDeltaOrder = ( throw new Error(`Delta is not available on chain ${chainId}`); } - ////// Partner logic ////// - - // externally supplied partner fee data takes precedence - let partnerAddress = options.partnerAddress; - let partnerFeeBps = - options.partnerFeeBps ?? - (options.deltaPrice.partnerFee - ? options.deltaPrice.partnerFee * 100 - : undefined); - let partnerTakesSurplus = options.partnerTakesSurplus; - - // if fee given, takeSurplus is ignored - const feeOrTakeSurplusSupplied = - partnerFeeBps !== undefined || partnerTakesSurplus !== undefined; - - if (partnerAddress === undefined || feeOrTakeSurplusSupplied) { - const partner = options.partner || options.deltaPrice.partner; - if (!partner) { - // if no partner given in options or deltaPrice, default partnerAddress to zero, - // unless supplied explicitly - partnerAddress = partnerAddress ?? ZERO_ADDRESS; - } else { - const partnerFeeResponse = await getPartnerFee( - { partner }, - requestParams - ); - - partnerAddress = partnerAddress ?? partnerFeeResponse.partnerAddress; - // deltaPrice.partnerFee and partnerFeeResponse.partnerFee should be the same, but give priority to externally provided - partnerFeeBps = partnerFeeBps ?? partnerFeeResponse.partnerFee; - partnerTakesSurplus = - partnerTakesSurplus ?? partnerFeeResponse.takeSurplus; - } - } - - partnerFeeBps = partnerFeeBps ?? 0; - partnerTakesSurplus = partnerTakesSurplus ?? false; - - const swapSide = options.side ?? SwapSide.SELL; + const { partnerAddress, partnerFeeBps, partnerTakesSurplus } = + await resolvePartnerFee(options, getPartnerFee, requestParams); - const expectedAmount = - swapSide === SwapSide.SELL - ? options.deltaPrice.destAmount - : options.deltaPrice.srcAmount; + const { srcAmount, destAmount, expectedAmount, swapSide } = + resolveAmounts(options); const input: BuildDeltaOrderDataInput = { owner: options.owner, @@ -152,8 +104,8 @@ export const constructBuildDeltaOrder = ( // for some cases of WETH->ETH crosschain swaps, the destToken is changed to WETH or ETH, // this is already reflected in deltaPrice destToken: options.deltaPrice.destToken, - srcAmount: options.srcAmount, - destAmount: options.destAmount, + srcAmount, + destAmount, expectedAmount, deadline: options.deadline, nonce: options.nonce?.toString(10), diff --git a/src/methods/delta/buildExternalDeltaOrder.ts b/src/methods/delta/buildExternalDeltaOrder.ts new file mode 100644 index 000000000..693571b66 --- /dev/null +++ b/src/methods/delta/buildExternalDeltaOrder.ts @@ -0,0 +1,124 @@ +import type { ConstructFetchInput, RequestParameters } from '../../types'; +import { constructGetDeltaContract } from './getDeltaContract'; +import type { DeltaPrice } from './getDeltaPrice'; +import { constructGetPartnerFee } from './getPartnerFee'; +import { + buildExternalOrderSignableData, + type BuildExternalOrderDataInput, + type SignableExternalOrderData, +} from './helpers/buildExternalOrderData'; +import type { AmountsWithSlippage } from './helpers/types'; +import { SwapSideToOrderKind } from './helpers/types'; +import type { MarkOptional } from 'ts-essentials'; +import { resolvePartnerFee, resolveAmounts } from './helpers/misc'; +export type { SignableExternalOrderData } from './helpers/buildExternalOrderData'; + +type BuildExternalDeltaOrderParamsBase = { + /** @description The address of the order owner */ + owner: string; + /** @description The address of the external handler contract */ + handler: string; + /** @description Protocol-specific encoded bytes for the external handler */ + data: string; + /** @description The address of the src token */ + srcToken: string; + /** @description The address of the dest token */ + destToken: string; + /** @description The deadline for the order */ + deadline?: number; + /** @description The nonce of the order */ + nonce?: number | string; + /** @description Optional permit signature for the src token */ + permit?: string; + /** @description Partner string */ + partner?: string; + /** @description partner fee in basis points (bps), 50bps=0.5% */ + partnerFeeBps?: number; + /** @description partner address */ + partnerAddress?: string; + /** @description take surplus */ + partnerTakesSurplus?: boolean; + /** @description A boolean indicating whether the surplus should be capped. True by default */ + capSurplus?: boolean; + /** @description Metadata for the order, hex string */ + metadata?: string; + + /** @description price response received from /delta/prices (getDeltaPrice method) */ + deltaPrice: MarkOptional< + Pick< + DeltaPrice, + 'destAmount' | 'partner' | 'partnerFee' | 'destToken' | 'srcAmount' + >, + 'partner' | 'partnerFee' + >; +}; + +export type BuildExternalDeltaOrderParams = BuildExternalDeltaOrderParamsBase & + AmountsWithSlippage; + +type BuildExternalDeltaOrder = ( + buildOrderParams: BuildExternalDeltaOrderParams, + requestParams?: RequestParameters +) => Promise; + +export type BuildExternalDeltaOrderFunctions = { + /** @description Build External Orders to be posted to Delta API for execution */ + buildExternalDeltaOrder: BuildExternalDeltaOrder; +}; + +export const constructBuildExternalDeltaOrder = ( + options: ConstructFetchInput +): BuildExternalDeltaOrderFunctions => { + const { chainId } = options; + + // cached internally + const { getDeltaContract } = constructGetDeltaContract(options); + // cached internally for `partner` + const { getPartnerFee } = constructGetPartnerFee(options); + + const buildExternalDeltaOrder: BuildExternalDeltaOrder = async ( + options, + requestParams + ) => { + const ParaswapDelta = await getDeltaContract(requestParams); + if (!ParaswapDelta) { + throw new Error(`Delta is not available on chain ${chainId}`); + } + + const { partnerAddress, partnerFeeBps, partnerTakesSurplus } = + await resolvePartnerFee(options, getPartnerFee, requestParams); + + const { srcAmount, destAmount, expectedAmount, swapSide } = + resolveAmounts(options); + + const input: BuildExternalOrderDataInput = { + owner: options.owner, + handler: options.handler, + srcToken: options.srcToken, + destToken: options.deltaPrice.destToken, + srcAmount, + destAmount, + expectedAmount, + deadline: options.deadline, + nonce: options.nonce?.toString(10), + permit: options.permit, + kind: SwapSideToOrderKind[swapSide], + metadata: options.metadata, + data: options.data, + + chainId, + paraswapDeltaAddress: ParaswapDelta, + partnerAddress, + partnerTakesSurplus, + partnerFeeBps, + + capSurplus: options.capSurplus, + }; + + return buildExternalOrderSignableData(input); + }; + + return { + buildExternalDeltaOrder, + }; +}; diff --git a/src/methods/delta/getDeltaOrders.ts b/src/methods/delta/getDeltaOrders.ts index 3c9c41461..412a1362e 100644 --- a/src/methods/delta/getDeltaOrders.ts +++ b/src/methods/delta/getDeltaOrders.ts @@ -5,9 +5,14 @@ import type { ConstructFetchInput, RequestParameters, } from '../../types'; -import type { DeltaAuction, DeltaAuctionStatus } from './helpers/types'; +import type { + DeltaAuction, + DeltaAuctionStatus, + OnChainOrderType, +} from './helpers/types'; -export type DeltaOrderFromAPI = Omit; +/** @deprecated Use DeltaAuction directly */ +export type DeltaOrderFromAPI = DeltaAuction; export type DeltaOrderFilterByStatus = | DeltaAuctionStatus @@ -20,14 +25,14 @@ export type DeltaOrderFilterByStatus = type GetDeltaOrderById = ( orderId: string, requestParams?: RequestParameters -) => Promise; +) => Promise; type GetDeltaOrderByHash = ( orderHash: string, requestParams?: RequestParameters -) => Promise; +) => Promise; -type OrdersFilter = { +type OrdersFilter = { /** @description Order.owner to fetch Delta Order for */ userAddress: Address; /** @description Pagination option, page. Default 1 */ @@ -48,16 +53,23 @@ type OrdersFilter = { status?: DeltaOrderFilterByStatus[]; /** @description Filter by type. MARKET, LIMIT. Orders with both types are returned if not specified */ type?: 'MARKET' | 'LIMIT'; + /** @description Filter by on-chain order type. Order, ExternalOrder. Orders of all types are returned if not specified */ + onChainOrderType?: T; }; type OrderFiltersQuery = Omit & { chainId?: string; status?: string; }; -type GetDeltaOrders = ( - options: OrdersFilter, - requestParams?: RequestParameters -) => Promise; +type GetDeltaOrders = { + ( + options: OrdersFilter & { onChainOrderType: T }, + requestParams?: RequestParameters + ): Promise[]>; + (options: OrdersFilter, requestParams?: RequestParameters): Promise< + DeltaAuction[] + >; +}; type GetRequiredBalanceParams = { userAddress: Address; @@ -89,7 +101,7 @@ export const constructGetDeltaOrders = ({ ) => { const fetchURL = `${baseUrl}/${orderId}` as const; - const order = await fetcher({ + const order = await fetcher({ url: fetchURL, method: 'GET', requestParams, @@ -104,7 +116,7 @@ export const constructGetDeltaOrders = ({ ) => { const fetchURL = `${baseUrl}/hash/${orderHash}` as const; - const order = await fetcher({ + const order = await fetcher({ url: fetchURL, method: 'GET', requestParams, @@ -113,7 +125,12 @@ export const constructGetDeltaOrders = ({ return order; }; - const getDeltaOrders: GetDeltaOrders = async (options, requestParams) => { + const getDeltaOrders: GetDeltaOrders = async < + T extends OnChainOrderType = OnChainOrderType + >( + options: OrdersFilter, + requestParams?: RequestParameters + ) => { const chainIdString = options.chainId?.join(','); const statusString = options.status?.join(','); @@ -122,13 +139,14 @@ export const constructGetDeltaOrders = ({ page: options.page, limit: options.limit, type: options.type, + onChainOrderType: options.onChainOrderType, chainId: chainIdString, status: statusString, }); const fetchURL = `${baseUrl}${search}` as const; - const orders = await fetcher({ + const orders = await fetcher[]>({ url: fetchURL, method: 'GET', requestParams, diff --git a/src/methods/delta/helpers/abi.ts b/src/methods/delta/helpers/abi.ts new file mode 100644 index 000000000..6b3108919 --- /dev/null +++ b/src/methods/delta/helpers/abi.ts @@ -0,0 +1,20 @@ +export const PreSignatureModuleAbi = [ + { + inputs: [ + { + internalType: 'bytes32', + name: 'orderHash', + type: 'bytes32', + }, + { + internalType: 'bool', + name: 'preSigned', + type: 'bool', + }, + ], + name: 'setPreSignature', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, +] as const; diff --git a/src/methods/delta/helpers/buildDeltaOrderData.ts b/src/methods/delta/helpers/buildDeltaOrderData.ts index c8bfb2673..3913c3e70 100644 --- a/src/methods/delta/helpers/buildDeltaOrderData.ts +++ b/src/methods/delta/helpers/buildDeltaOrderData.ts @@ -1,6 +1,7 @@ import { MarkOptional } from 'ts-essentials'; -import { Domain, ZERO_ADDRESS } from '../../common/orders/buildOrderData'; +import { Domain } from '../../common/orders/buildOrderData'; import { Bridge, DeltaAuctionOrder } from './types'; +import { DELTA_DEFAULT_EXPIRY, producePartnerAndFee } from './misc'; // Order(address owner,address beneficiary,address srcToken,address destToken,uint256 srcAmount,uint256 destAmount,uint256 deadline,uint256 nonce,bytes permit, bridge Bridge)"; const SWAP_ORDER_EIP_712_TYPES = { @@ -64,7 +65,7 @@ export function produceDeltaOrderTypedData({ chainId, paraswapDeltaAddress, }: SignDeltaOrderInput): SignableDeltaOrderData { - const typedData = { + return { types: { Order: SWAP_ORDER_EIP_712_TYPES.Order, Bridge: SWAP_ORDER_EIP_712_TYPES.Bridge, @@ -77,8 +78,6 @@ export function produceDeltaOrderTypedData({ }, data: orderInput, }; - - return typedData; } export type DeltaOrderDataInput = MarkOptional< @@ -99,9 +98,6 @@ export type BuildDeltaOrderDataInput = MarkOptional< bridge: Bridge; }; -// default deadline = 1 hour for now (may be changed later) -export const DELTA_DEFAULT_EXPIRY = 60 * 60; // seconds - export function buildDeltaSignableOrderData({ owner, beneficiary = owner, @@ -157,31 +153,3 @@ export function buildDeltaSignableOrderData({ paraswapDeltaAddress, }); } - -type ProducePartnerAndFeeInput = { - partnerFeeBps: number; - partnerAddress: string; - partnerTakesSurplus: boolean; - capSurplus: boolean; -}; - -// fee and address are encoded together -function producePartnerAndFee({ - partnerFeeBps, - partnerAddress, - partnerTakesSurplus, - capSurplus, -}: ProducePartnerAndFeeInput): string { - const capSurplusShifted = BigInt(capSurplus) << BigInt(9); - if (partnerAddress === ZERO_ADDRESS) { - return capSurplusShifted.toString(10); - } else { - const partnerAndFee = - (BigInt(partnerAddress) << BigInt(96)) | - BigInt(partnerFeeBps.toFixed(0)) | - (BigInt(partnerTakesSurplus) << BigInt(8)) | - capSurplusShifted; - - return partnerAndFee.toString(10); - } -} diff --git a/src/methods/delta/helpers/buildExternalOrderData.ts b/src/methods/delta/helpers/buildExternalOrderData.ts new file mode 100644 index 000000000..75d70a321 --- /dev/null +++ b/src/methods/delta/helpers/buildExternalOrderData.ts @@ -0,0 +1,129 @@ +import { MarkOptional } from 'ts-essentials'; +import { Domain } from '../../common/orders/buildOrderData'; +import { ExternalDeltaOrder } from './types'; +import { DELTA_DEFAULT_EXPIRY, producePartnerAndFee } from './misc'; + +const EXTERNAL_ORDER_EIP_712_TYPES = { + ExternalOrder: [ + { name: 'owner', type: 'address' }, + { name: 'handler', type: 'address' }, + { name: 'srcToken', type: 'address' }, + { name: 'destToken', type: 'address' }, + { name: 'srcAmount', type: 'uint256' }, + { name: 'destAmount', type: 'uint256' }, + { name: 'expectedAmount', type: 'uint256' }, + { name: 'deadline', type: 'uint256' }, + { name: 'kind', type: 'uint8' }, + { name: 'nonce', type: 'uint256' }, + { name: 'partnerAndFee', type: 'uint256' }, + { name: 'permit', type: 'bytes' }, + { name: 'metadata', type: 'bytes' }, + { name: 'data', type: 'bytes' }, + ], +}; + +export type SignableExternalOrderData = { + types: { + ExternalOrder: typeof EXTERNAL_ORDER_EIP_712_TYPES.ExternalOrder; + }; + domain: Domain; + data: ExternalDeltaOrder; +}; + +type SignExternalOrderInput = { + orderInput: ExternalDeltaOrder; + paraswapDeltaAddress: string; + chainId: number; +}; + +export function produceExternalOrderTypedData({ + orderInput, + chainId, + paraswapDeltaAddress, +}: SignExternalOrderInput): SignableExternalOrderData { + return { + types: { + ExternalOrder: EXTERNAL_ORDER_EIP_712_TYPES.ExternalOrder, + }, + domain: { + name: 'Portikus', + version: '2.0.0', + chainId, + verifyingContract: paraswapDeltaAddress, + }, + data: orderInput, + }; +} + +export type ExternalOrderDataInput = MarkOptional< + Omit, + 'deadline' | 'nonce' | 'permit' +>; + +export type BuildExternalOrderDataInput = MarkOptional< + ExternalOrderDataInput, + 'metadata' +> & { + partnerAddress: string; + paraswapDeltaAddress: string; + partnerFeeBps: number; + partnerTakesSurplus?: boolean; + capSurplus?: boolean; + chainId: number; +}; + +export function buildExternalOrderSignableData({ + owner, + handler, + + srcToken, + destToken, + srcAmount, + destAmount, + expectedAmount, + + deadline = Math.floor(Date.now() / 1000 + DELTA_DEFAULT_EXPIRY), + nonce = Date.now().toString(10), + + permit = '0x', + + kind, + metadata = '0x', + data, + + partnerAddress, + partnerFeeBps, + partnerTakesSurplus = false, + capSurplus = true, + + chainId, + paraswapDeltaAddress, +}: BuildExternalOrderDataInput): SignableExternalOrderData { + const orderInput: ExternalDeltaOrder = { + owner, + handler, + srcToken, + destToken, + srcAmount, + destAmount, + expectedAmount, + deadline, + nonce, + permit, + partnerAndFee: producePartnerAndFee({ + partnerFeeBps, + partnerAddress, + partnerTakesSurplus, + capSurplus, + }), + kind, + metadata, + data, + }; + + return produceExternalOrderTypedData({ + orderInput, + chainId, + paraswapDeltaAddress, + }); +} diff --git a/src/methods/delta/helpers/misc.ts b/src/methods/delta/helpers/misc.ts index 472bb7f45..dc0660c63 100644 --- a/src/methods/delta/helpers/misc.ts +++ b/src/methods/delta/helpers/misc.ts @@ -1,4 +1,179 @@ +import { ZERO_ADDRESS } from '../../common/orders/buildOrderData'; import type { SignableDeltaOrderData } from './buildDeltaOrderData'; +import type { SignableExternalOrderData } from './buildExternalOrderData'; +import type { GetPartnerFeeFunctions } from '../getPartnerFee'; +import type { RequestParameters } from '../../../types'; +import type { AmountsWithSlippage, SwapSideUnion } from './types'; +import { SwapSide } from '../../../constants'; +import { assert } from 'ts-essentials'; + +// default deadline = 10 min +export const DELTA_DEFAULT_EXPIRY = 10 * 60; // seconds + +type ProducePartnerAndFeeInput = { + partnerFeeBps: number; + partnerAddress: string; + partnerTakesSurplus: boolean; + capSurplus: boolean; +}; + +// fee and address are encoded together +export function producePartnerAndFee({ + partnerFeeBps, + partnerAddress, + partnerTakesSurplus, + capSurplus, +}: ProducePartnerAndFeeInput): string { + const capSurplusShifted = BigInt(capSurplus) << BigInt(9); + if (partnerAddress === ZERO_ADDRESS) { + return capSurplusShifted.toString(10); + } else { + const partnerAndFee = + (BigInt(partnerAddress) << BigInt(96)) | + BigInt(partnerFeeBps.toFixed(0)) | + (BigInt(partnerTakesSurplus) << BigInt(8)) | + capSurplusShifted; + + return partnerAndFee.toString(10); + } +} + +type ApplySlippageInput = { + amount: string; + slippageBps: number; + increase: boolean; +}; + +function applySlippage({ + amount, + slippageBps, + increase, +}: ApplySlippageInput): string { + assert( + Number.isInteger(slippageBps) && slippageBps >= 0 && slippageBps <= 10_000, + 'slippageBps must be an integer between 0 and 10_000' + ); + + const BPS_BASE = 10_000n; + const amt = BigInt(amount); + const bps = BigInt(slippageBps); + + return increase + ? ((amt * (BPS_BASE + bps)) / BPS_BASE).toString(10) + : ((amt * (BPS_BASE - bps)) / BPS_BASE).toString(10); +} + +export type ResolvePartnerFeeInput = { + partnerAddress?: string; + partnerFeeBps?: number; + partnerTakesSurplus?: boolean; + partner?: string; + deltaPrice: { partner?: string; partnerFee?: number }; +}; + +export type ResolvedPartnerFee = { + partnerAddress: string; + partnerFeeBps: number; + partnerTakesSurplus: boolean; +}; + +export async function resolvePartnerFee( + options: ResolvePartnerFeeInput, + getPartnerFee: GetPartnerFeeFunctions['getPartnerFee'], + requestParams?: RequestParameters +): Promise { + // externally supplied partner fee data takes precedence + let partnerAddress = options.partnerAddress; + let partnerFeeBps = + options.partnerFeeBps ?? + (options.deltaPrice.partnerFee + ? options.deltaPrice.partnerFee * 100 + : undefined); + let partnerTakesSurplus = options.partnerTakesSurplus; + + // if fee given, takeSurplus is ignored + const feeOrTakeSurplusSupplied = + partnerFeeBps !== undefined || partnerTakesSurplus !== undefined; + + if (partnerAddress === undefined || feeOrTakeSurplusSupplied) { + const partner = options.partner || options.deltaPrice.partner; + if (!partner) { + // if no partner given in options or deltaPrice, default partnerAddress to zero, + // unless supplied explicitly + partnerAddress = partnerAddress ?? ZERO_ADDRESS; + } else { + const partnerFeeResponse = await getPartnerFee( + { partner }, + requestParams + ); + + partnerAddress = partnerAddress ?? partnerFeeResponse.partnerAddress; + // deltaPrice.partnerFee and partnerFeeResponse.partnerFee should be the same, but give priority to externally provided + partnerFeeBps = partnerFeeBps ?? partnerFeeResponse.partnerFee * 100; + partnerTakesSurplus = + partnerTakesSurplus ?? partnerFeeResponse.takeSurplus; + } + } + + return { + partnerAddress: partnerAddress!, + partnerFeeBps: partnerFeeBps ?? 0, + partnerTakesSurplus: partnerTakesSurplus ?? false, + }; +} + +export type ResolveAmountsInput = AmountsWithSlippage & { + deltaPrice: { destAmount: string; srcAmount: string }; +}; + +export type ResolvedAmounts = { + srcAmount: string; + destAmount: string; + expectedAmount: string; + swapSide: SwapSideUnion; +}; + +export function resolveAmounts(options: ResolveAmountsInput): ResolvedAmounts { + let srcAmount: string; + let destAmount: string; + + const swapSide: SwapSideUnion = + options.slippage !== undefined + ? options.srcAmount !== undefined + ? SwapSide.SELL + : SwapSide.BUY + : options.side ?? SwapSide.SELL; + + if (options.slippage !== undefined) { + if (options.srcAmount !== undefined) { + // SELL with slippage: destAmount auto-computed + srcAmount = options.srcAmount; + destAmount = applySlippage({ + amount: options.deltaPrice.destAmount, + slippageBps: options.slippage, + increase: false, + }); + } else { + // BUY with slippage: srcAmount auto-computed + destAmount = options.destAmount; + srcAmount = applySlippage({ + amount: options.deltaPrice.srcAmount, + slippageBps: options.slippage, + increase: true, + }); + } + } else { + srcAmount = options.srcAmount; + destAmount = options.destAmount; + } + + const expectedAmount = + swapSide === SwapSide.SELL + ? options.deltaPrice.destAmount + : options.deltaPrice.srcAmount; + + return { srcAmount, destAmount, expectedAmount, swapSide }; +} export function sanitizeDeltaOrderData({ owner, @@ -34,3 +209,38 @@ export function sanitizeDeltaOrderData({ metadata, }; } + +export function sanitizeExternalOrderData({ + owner, + handler, + srcToken, + destToken, + srcAmount, + destAmount, + expectedAmount, + deadline, + nonce, + permit, + partnerAndFee, + kind, + metadata, + data, +}: SignableExternalOrderData['data'] & + Record): SignableExternalOrderData['data'] { + return { + owner, + handler, + srcToken, + destToken, + srcAmount, + destAmount, + expectedAmount, + deadline, + nonce, + permit, + partnerAndFee, + kind, + metadata, + data, + }; +} diff --git a/src/methods/delta/helpers/types.ts b/src/methods/delta/helpers/types.ts index 1037249d3..2221e447f 100644 --- a/src/methods/delta/helpers/types.ts +++ b/src/methods/delta/helpers/types.ts @@ -1,5 +1,44 @@ +import type { EnumerateLiteral } from '../../../types'; import { SwapSide } from '../../../constants'; +export type SwapSideUnion = EnumerateLiteral; + +/** @description SELL with slippage: srcAmount provided, destAmount auto-computed from deltaPrice.destAmount */ +export type AmountsSellSlippage = { + /** @description Slippage in basis points (bps). 10000 = 100%, 50 = 0.5% */ + slippage: number; + /** @description The amount of src token to swap */ + srcAmount: string; + destAmount?: never; + /** @description The side of the order */ + side?: 'SELL'; +}; +/** @description BUY with slippage: destAmount provided, srcAmount auto-computed from deltaPrice.srcAmount */ +export type AmountsBuySlippage = { + /** @description Slippage in basis points (bps). 10000 = 100%, 50 = 0.5% */ + slippage: number; + /** @description The minimum amount of dest token to receive */ + destAmount: string; + srcAmount?: never; + /** @description The side of the order */ + side?: 'BUY'; +}; +/** @description Explicit amounts, no slippage (backward-compatible) */ +export type AmountsExplicit = { + slippage?: never; + /** @description The amount of src token to swap */ + srcAmount: string; + /** @description The minimum amount of dest token to receive */ + destAmount: string; + /** @description The side of the order. Default is SELL */ + side?: SwapSideUnion; +}; + +export type AmountsWithSlippage = + | AmountsSellSlippage + | AmountsBuySlippage + | AmountsExplicit; + enum OrderKind { Sell = 0, Buy = 1, @@ -52,6 +91,37 @@ export type Bridge = { protocolData: string; // Hex string }; +export type ExternalDeltaOrder = { + /** @description The address of the order owner */ + owner: string; + /** @description The address of the external handler contract */ + handler: string; + /** @description The address of the src token */ + srcToken: string; + /** @description The address of the dest token */ + destToken: string; + /** @description The amount of src token to swap */ + srcAmount: string; + /** @description The minimum amount of dest token to receive */ + destAmount: string; + /** @description The expected amount of token to receive */ + expectedAmount: string; + /** @description The kind of the order */ + kind: OrderKind; + /** @description Metadata for the order, hex string */ + metadata: string; + /** @description The deadline for the order */ + deadline: number; + /** @description The nonce of the order */ + nonce: string; + /** @description Optional permit signature for the src token */ + permit: string; + /** @description Encoded partner address, fee bps, and flags for the order */ + partnerAndFee: string; + /** @description Protocol-specific encoded bytes for the external handler */ + data: string; +}; + export type DeltaAuctionStatus = | 'NOT_STARTED' | 'AWAITING_PRE_SIGNATURE' @@ -92,13 +162,16 @@ type DeltaAuctionTransaction = { auctionId: string; }; -export type DeltaAuction = { +export type OnChainOrderMap = { + Order: DeltaAuctionOrder; + ExternalOrder: ExternalDeltaOrder; +}; + +type DeltaAuctionBase = { id: string; deltaVersion: string; // 1.0 or 2.0 currently user: string; - signature: string; status: DeltaAuctionStatus; - order: DeltaAuctionOrder; orderHash: string | null; // not available on old Orders only transactions: DeltaAuctionTransaction[]; chainId: number; @@ -115,13 +188,17 @@ export type DeltaAuction = { bridgeMetadata: BridgeMetadata | null; bridgeStatus: BridgeStatus | null; - // @TODO only returned after POST Order so far - // orderVersion: string; // "2.0.0" - // deltaGasOverhead: number; - - type: 'MARKET' | 'LIMIT'; // @TODO when available in API for individual /order/:hash|:id + type: 'MARKET' | 'LIMIT'; }; +export type DeltaAuction = + T extends T + ? DeltaAuctionBase & { + onChainOrderType: T; + order: OnChainOrderMap[T]; + } + : never; + export type BridgeMetadata = { /** @description The amount that user should expect to get */ outputAmount: string; @@ -138,6 +215,8 @@ export type BridgeMetadata = { // refunded is basically failed export type BridgeStatus = 'pending' | 'filled' | 'expired' | 'refunded'; +export type OnChainOrderType = 'Order' | 'ExternalOrder'; + //// available on BridgePrice //// type BridgeQuoteFee = { diff --git a/src/methods/delta/index.ts b/src/methods/delta/index.ts index f925e037d..27d42bdf2 100644 --- a/src/methods/delta/index.ts +++ b/src/methods/delta/index.ts @@ -1,4 +1,5 @@ import type { ConstructProviderFetchInput } from '../../types'; +import type { DeltaAuction } from './helpers/types'; import { BuildDeltaOrderDataParams, BuildDeltaOrderFunctions, @@ -6,7 +7,6 @@ import { } from './buildDeltaOrder'; import { constructPostDeltaOrder, - DeltaOrderApiResponse, DeltaOrderToPost, PostDeltaOrderFunctions, } from './postDeltaOrder'; @@ -54,6 +54,23 @@ import { DeltaTokenModuleFunctions, constructDeltaTokenModule, } from './deltaTokenModule'; +import { + BuildExternalDeltaOrderParams, + BuildExternalDeltaOrderFunctions, + constructBuildExternalDeltaOrder, +} from './buildExternalDeltaOrder'; +import { + constructSignExternalDeltaOrder, + SignExternalDeltaOrderFunctions, +} from './signExternalDeltaOrder'; +import { + constructPostExternalDeltaOrder, + PostExternalDeltaOrderFunctions, +} from './postExternalDeltaOrder'; +import { + constructPreSignExternalDeltaOrder, + PreSignExternalDeltaOrderFunctions, +} from './preSignExternalDeltaOrder'; export type SubmitDeltaOrderParams = BuildDeltaOrderDataParams & { /** @description designates the Order as being able to be partially filled, as opposed to fill-or-kill */ @@ -65,7 +82,7 @@ export type SubmitDeltaOrderParams = BuildDeltaOrderDataParams & { type SubmitDeltaOrder = ( orderParams: SubmitDeltaOrderParams -) => Promise; +) => Promise>; export type SubmitDeltaOrderFuncs = { submitDeltaOrder: SubmitDeltaOrder; @@ -101,6 +118,51 @@ export const constructSubmitDeltaOrder = ( return { submitDeltaOrder }; }; +export type SubmitExternalDeltaOrderParams = BuildExternalDeltaOrderParams & { + /** @description designates the Order as being able to be partially filled, as opposed to fill-or-kill */ + partiallyFillable?: boolean; + /** @description Referrer address */ + referrerAddress?: string; +} & Pick; + +type SubmitExternalDeltaOrder = ( + orderParams: SubmitExternalDeltaOrderParams +) => Promise>; + +export type SubmitExternalDeltaOrderFuncs = { + submitExternalDeltaOrder: SubmitExternalDeltaOrder; +}; + +export const constructSubmitExternalDeltaOrder = ( + options: ConstructProviderFetchInput +): SubmitExternalDeltaOrderFuncs => { + const { buildExternalDeltaOrder } = constructBuildExternalDeltaOrder(options); + const { signExternalDeltaOrder } = constructSignExternalDeltaOrder(options); + const { postExternalDeltaOrder } = constructPostExternalDeltaOrder(options); + + const submitExternalDeltaOrder: SubmitExternalDeltaOrder = async ( + orderParams + ) => { + const orderData = await buildExternalDeltaOrder(orderParams); + const signature = await signExternalDeltaOrder(orderData); + + const response = await postExternalDeltaOrder({ + signature, + partner: orderParams.partner, + order: orderData.data, + partiallyFillable: orderParams.partiallyFillable, + referrerAddress: orderParams.referrerAddress, + type: orderParams.type, + includeAgents: orderParams.includeAgents, + excludeAgents: orderParams.excludeAgents, + }); + + return response; + }; + + return { submitExternalDeltaOrder }; +}; + export type DeltaOrderHandlers = SubmitDeltaOrderFuncs & ApproveTokenForDeltaFunctions & BuildDeltaOrderFunctions & @@ -114,7 +176,12 @@ export type DeltaOrderHandlers = SubmitDeltaOrderFuncs & SignDeltaOrderFunctions & PreSignDeltaOrderFunctions & CancelDeltaOrderFunctions & - DeltaTokenModuleFunctions; + DeltaTokenModuleFunctions & + SubmitExternalDeltaOrderFuncs & + BuildExternalDeltaOrderFunctions & + SignExternalDeltaOrderFunctions & + PostExternalDeltaOrderFunctions & + PreSignExternalDeltaOrderFunctions; /** @description construct SDK with every Delta Order-related method, fetching from API and Order signing */ export const constructAllDeltaOrdersHandlers = ( @@ -144,6 +211,13 @@ export const constructAllDeltaOrdersHandlers = ( const deltaTokenModule = constructDeltaTokenModule(options); + const externalDeltaOrdersSubmit = constructSubmitExternalDeltaOrder(options); + const externalDeltaOrdersBuild = constructBuildExternalDeltaOrder(options); + const externalDeltaOrdersSign = constructSignExternalDeltaOrder(options); + const externalDeltaOrdersPost = constructPostExternalDeltaOrder(options); + const externalDeltaOrdersPreSign = + constructPreSignExternalDeltaOrder(options); + return { ...deltaOrdersGetters, ...deltaOrdersContractGetter, @@ -159,5 +233,10 @@ export const constructAllDeltaOrdersHandlers = ( ...deltaOrdersPost, ...deltaOrdersCancel, ...deltaTokenModule, + ...externalDeltaOrdersSubmit, + ...externalDeltaOrdersBuild, + ...externalDeltaOrdersSign, + ...externalDeltaOrdersPost, + ...externalDeltaOrdersPreSign, }; }; diff --git a/src/methods/delta/postDeltaOrder.ts b/src/methods/delta/postDeltaOrder.ts index b98a5bb0e..3956a32c5 100644 --- a/src/methods/delta/postDeltaOrder.ts +++ b/src/methods/delta/postDeltaOrder.ts @@ -1,14 +1,18 @@ import { API_URL } from '../../constants'; import { constructSearchString } from '../../helpers/misc'; import type { ConstructFetchInput, RequestParameters } from '../../types'; -import { DeltaAuctionOrder, DeltaAuction } from './helpers/types'; +import type { + DeltaAuction, + OnChainOrderMap, + OnChainOrderType, +} from './helpers/types'; -export type DeltaOrderToPost = { +export type DeltaOrderToPost = { /** @description Partner string */ partner?: string; /** @description Referrer address */ referrerAddress?: string; - order: DeltaAuctionOrder; + order: OnChainOrderMap[T]; /** @description Signature of the order from order.owner address. EOA signatures must be submitted in ERC-2098 Compact Representation. */ signature: string; chainId: number; @@ -26,16 +30,10 @@ export type PostDeltaOrderParams = Omit & { degenMode?: boolean; }; -export type DeltaOrderApiResponse = Omit & { - orderVersion: string; // "2.0.0" - deltaGasOverhead: number; // @TODO may be removed - type: 'MARKET' | 'LIMIT'; -}; - type PostDeltaOrder = ( postData: PostDeltaOrderParams, requestParams?: RequestParameters -) => Promise; +) => Promise>; export type PostDeltaOrderFunctions = { postDeltaOrder: PostDeltaOrder; @@ -57,7 +55,7 @@ export const constructPostDeltaOrder = ({ }); const fetchURL = `${postOrderUrl}/${search}` as const; - return fetcher({ + return fetcher>({ url: fetchURL, method: 'POST', data: deltaOrderToPost, diff --git a/src/methods/delta/postExternalDeltaOrder.ts b/src/methods/delta/postExternalDeltaOrder.ts new file mode 100644 index 000000000..e3257d6d2 --- /dev/null +++ b/src/methods/delta/postExternalDeltaOrder.ts @@ -0,0 +1,45 @@ +import { API_URL } from '../../constants'; +import type { ConstructFetchInput, RequestParameters } from '../../types'; +import type { DeltaAuction } from './helpers/types'; +import type { DeltaOrderToPost } from './postDeltaOrder'; + +export type PostExternalDeltaOrderParams = Omit< + DeltaOrderToPost<'ExternalOrder'>, + 'chainId' +>; + +type PostExternalDeltaOrder = ( + postData: PostExternalDeltaOrderParams, + requestParams?: RequestParameters +) => Promise>; + +export type PostExternalDeltaOrderFunctions = { + postExternalDeltaOrder: PostExternalDeltaOrder; +}; + +export const constructPostExternalDeltaOrder = ({ + apiURL = API_URL, + chainId, + fetcher, +}: ConstructFetchInput): PostExternalDeltaOrderFunctions => { + const postOrderUrl = `${apiURL}/delta/orders` as const; + + const postExternalDeltaOrder: PostExternalDeltaOrder = ( + postData, + requestParams + ) => { + const deltaOrderToPost: DeltaOrderToPost<'ExternalOrder'> = { + ...postData, + chainId, + }; + + return fetcher>({ + url: postOrderUrl, + method: 'POST', + data: deltaOrderToPost, + requestParams, + }); + }; + + return { postExternalDeltaOrder }; +}; diff --git a/src/methods/delta/preSignDeltaOrder.ts b/src/methods/delta/preSignDeltaOrder.ts index 8109ea9cb..ab511dbe6 100644 --- a/src/methods/delta/preSignDeltaOrder.ts +++ b/src/methods/delta/preSignDeltaOrder.ts @@ -9,6 +9,7 @@ import { SignableDeltaOrderData, } from './helpers/buildDeltaOrderData'; import { sanitizeDeltaOrderData } from './helpers/misc'; +import { PreSignatureModuleAbi } from './helpers/abi'; import type { ExtractAbiMethodNames } from '../../helpers/misc'; import { findPrimaryType } from '../../helpers/providers/helpers'; import { constructGetDeltaContract } from './getDeltaContract'; @@ -42,27 +43,6 @@ export type PreSignDeltaOrderFunctions = { preSignDeltaOrder: PreSignDeltaOrder; }; -const PreSignatureModuleAbi = [ - { - inputs: [ - { - internalType: 'bytes32', - name: 'orderHash', - type: 'bytes32', - }, - { - internalType: 'bool', - name: 'preSigned', - type: 'bool', - }, - ], - name: 'setPreSignature', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, -] as const; - type AvailableMethods = ExtractAbiMethodNames; // returns whatever `contractCaller` returns diff --git a/src/methods/delta/preSignExternalDeltaOrder.ts b/src/methods/delta/preSignExternalDeltaOrder.ts new file mode 100644 index 000000000..4095aa2a9 --- /dev/null +++ b/src/methods/delta/preSignExternalDeltaOrder.ts @@ -0,0 +1,141 @@ +import { hashTypedData } from 'viem/utils'; +import type { + ConstructProviderFetchInput, + RequestParameters, + TxSendOverrides, +} from '../../types'; +import { + produceExternalOrderTypedData, + SignableExternalOrderData, +} from './helpers/buildExternalOrderData'; +import { sanitizeExternalOrderData } from './helpers/misc'; +import { PreSignatureModuleAbi } from './helpers/abi'; +import type { ExtractAbiMethodNames } from '../../helpers/misc'; +import { findPrimaryType } from '../../helpers/providers/helpers'; +import { constructGetDeltaContract } from './getDeltaContract'; +import type { ExternalDeltaOrder } from './helpers/types'; + +type HashExternalDeltaOrderTypedData = ( + signableOrderData: SignableExternalOrderData +) => string; + +type HashExternalDeltaOrder = ( + orderData: ExternalDeltaOrder, + requestParams?: RequestParameters +) => Promise; + +export type SetExternalDeltaOrderPreSignature = ( + orderHash: string, + overrides?: TxSendOverrides, + requestParams?: RequestParameters +) => Promise; + +export type PreSignExternalDeltaOrder = ( + signableOrderData: SignableExternalOrderData, + overrides?: TxSendOverrides, + requestParams?: RequestParameters +) => Promise; + +export type PreSignExternalDeltaOrderFunctions = { + hashExternalDeltaOrderTypedData: HashExternalDeltaOrderTypedData; + hashExternalDeltaOrder: HashExternalDeltaOrder; + setExternalDeltaOrderPreSignature: SetExternalDeltaOrderPreSignature; + preSignExternalDeltaOrder: PreSignExternalDeltaOrder; +}; + +type AvailableMethods = ExtractAbiMethodNames; + +// returns whatever `contractCaller` returns +// to allow for better versatility +export const constructPreSignExternalDeltaOrder = ( + options: ConstructProviderFetchInput +): PreSignExternalDeltaOrderFunctions => { + const hashExternalDeltaOrderTypedData: HashExternalDeltaOrderTypedData = ( + typedData + ) => { + // types allow to pass OrderData & extra_stuff, but tx will break like that + const typedDataOnly: SignableExternalOrderData = { + ...typedData, + data: sanitizeExternalOrderData(typedData.data), + }; + + const orderHash = produceExternalOrderHash(typedDataOnly); + + return orderHash; + }; + // cached internally + const { getDeltaContract } = constructGetDeltaContract(options); + + const hashExternalDeltaOrder: HashExternalDeltaOrder = async ( + orderData, + requestParams + ) => { + const ParaswapDelta = await getDeltaContract(requestParams); + if (!ParaswapDelta) { + throw new Error(`Delta is not available on chain ${options.chainId}`); + } + + const typedData = produceExternalOrderTypedData({ + orderInput: orderData, + chainId: options.chainId, + paraswapDeltaAddress: ParaswapDelta, + }); + return hashExternalDeltaOrderTypedData(typedData); + }; + + const setExternalDeltaOrderPreSignature: SetExternalDeltaOrderPreSignature< + T + > = async (orderHash, overrides = {}, requestParams) => { + const ParaswapDelta = await getDeltaContract(requestParams); + if (!ParaswapDelta) { + throw new Error(`Delta is not available on chain ${options.chainId}`); + } + + const res = await options.contractCaller.transactCall({ + address: ParaswapDelta, + abi: PreSignatureModuleAbi, + contractMethod: 'setPreSignature', + args: [orderHash, true], + overrides, + }); + + return res; + }; + + const preSignExternalDeltaOrder: PreSignExternalDeltaOrder = async ( + signableOrderData, + overrides = {}, + requestParams + ) => { + const orderHash = hashExternalDeltaOrderTypedData(signableOrderData); + const res = await setExternalDeltaOrderPreSignature( + orderHash, + overrides, + requestParams + ); + return res; + }; + + return { + hashExternalDeltaOrderTypedData, + hashExternalDeltaOrder, + setExternalDeltaOrderPreSignature, + preSignExternalDeltaOrder, + }; +}; + +export function produceExternalOrderHash( + typedData: SignableExternalOrderData +): string { + return hashTypedData({ + domain: { + name: typedData.domain.name, + version: typedData.domain.version, + chainId: typedData.domain.chainId, + verifyingContract: typedData.domain.verifyingContract as `0x${string}`, + }, + types: typedData.types, + primaryType: findPrimaryType(typedData.types), + message: typedData.data, + }); +} diff --git a/src/methods/delta/signExternalDeltaOrder.ts b/src/methods/delta/signExternalDeltaOrder.ts new file mode 100644 index 000000000..2fc4d6e11 --- /dev/null +++ b/src/methods/delta/signExternalDeltaOrder.ts @@ -0,0 +1,35 @@ +import type { ConstructProviderFetchInput } from '../../types'; +import { SignableExternalOrderData } from './helpers/buildExternalOrderData'; +import { sanitizeExternalOrderData } from './helpers/misc'; + +type SignExternalDeltaOrder = ( + signableOrderData: SignableExternalOrderData +) => Promise; + +export type SignExternalDeltaOrderFunctions = { + signExternalDeltaOrder: SignExternalDeltaOrder; +}; + +// returns whatever `contractCaller` returns +// to allow for better versatility +export const constructSignExternalDeltaOrder = ( + options: Pick< + ConstructProviderFetchInput, + 'contractCaller' + > +): SignExternalDeltaOrderFunctions => { + const signExternalDeltaOrder: SignExternalDeltaOrder = async (typedData) => { + // types allow to pass OrderData & extra_stuff, but tx will break like that + const typedDataOnly: SignableExternalOrderData = { + ...typedData, + data: sanitizeExternalOrderData(typedData.data), + }; + const signature = await options.contractCaller.signTypedDataCall( + typedDataOnly + ); + + return signature; + }; + + return { signExternalDeltaOrder }; +}; diff --git a/src/methods/limitOrders/approveForOrder.ts b/src/methods/limitOrders/approveForOrder.ts index f1da4ba6c..95584b2dd 100644 --- a/src/methods/limitOrders/approveForOrder.ts +++ b/src/methods/limitOrders/approveForOrder.ts @@ -3,6 +3,7 @@ import { ApproveToken, approveTokenMethodFactory } from '../../helpers/approve'; import { constructApproveToken } from '../swap/approve'; import { constructGetSpender } from '../swap/spender'; +/** @deprecated Limit Orders are deprecated and will be removed in a future version. */ export type ApproveTokenForLimitOrderFunctions = { /** @description approving AugustusRFQ as spender for makerAsset */ approveMakerTokenForLimitOrder: ApproveToken; @@ -14,6 +15,7 @@ export type ApproveTokenForLimitOrderFunctions = { // returns whatever `contractCaller` returns // to allow for better versatility +/** @deprecated Limit Orders are deprecated and will be removed in a future version. */ export const constructApproveTokenForLimitOrder = ( options: ConstructProviderFetchInput ): ApproveTokenForLimitOrderFunctions => { diff --git a/src/methods/limitOrders/buildOrder.ts b/src/methods/limitOrders/buildOrder.ts index 9469bc46e..fe3eefb49 100644 --- a/src/methods/limitOrders/buildOrder.ts +++ b/src/methods/limitOrders/buildOrder.ts @@ -8,6 +8,7 @@ import { } from './helpers/buildOrderData'; export * from './helpers/buildOrderData'; +/** @deprecated Limit Orders are deprecated and will be removed in a future version. */ export type BuildLimitOrderInput = Omit< BuildOrderDataInput, 'chainId' | 'verifyingContract' | 'AugustusAddress' | 'AppVersion' @@ -18,11 +19,13 @@ type BuildLimitOrder = ( requestParams?: RequestParameters ) => Promise; +/** @deprecated Limit Orders are deprecated and will be removed in a future version. */ export type BuildLimitOrderFunctions = { /** @description Build Orders that will be excuted through AugustusSwapper */ buildLimitOrder: BuildLimitOrder; }; +/** @deprecated Limit Orders are deprecated and will be removed in a future version. */ export const constructBuildLimitOrder = ( options: ConstructFetchInput ): BuildLimitOrderFunctions => { diff --git a/src/methods/limitOrders/cancelOrder.ts b/src/methods/limitOrders/cancelOrder.ts index 8e7b02cb7..65dbe3eec 100644 --- a/src/methods/limitOrders/cancelOrder.ts +++ b/src/methods/limitOrders/cancelOrder.ts @@ -18,6 +18,7 @@ export type CancelOrderBulk = ( requestParams?: RequestParameters ) => Promise; +/** @deprecated Limit Orders are deprecated and will be removed in a future version. */ export type CancelLimitOrderFunctions = { cancelLimitOrder: CancelOrder; cancelLimitOrderBulk: CancelOrderBulk; @@ -57,6 +58,7 @@ type AvailableMethods = ExtractAbiMethodNames; // returns whatever `contractCaller` returns // to allow for better versatility +/** @deprecated Limit Orders are deprecated and will be removed in a future version. */ export const constructCancelLimitOrder = ( options: ConstructProviderFetchInput ): CancelLimitOrderFunctions => { diff --git a/src/methods/limitOrders/fillOrderDirectly.ts b/src/methods/limitOrders/fillOrderDirectly.ts index 729409fc0..177f30adb 100644 --- a/src/methods/limitOrders/fillOrderDirectly.ts +++ b/src/methods/limitOrders/fillOrderDirectly.ts @@ -12,6 +12,7 @@ import { encodeEIP_2612PermitFunctionInput, } from '../common/orders/encoding'; +/** @deprecated Limit Orders are deprecated and will be removed in a future version. */ export type FillOrderDirectlyFunctions = { fillOrderDirectly: FillOrderDirectly; }; @@ -204,6 +205,7 @@ type FillOrderMethods = ExtractAbiMethodNames; // returns whatever `contractCaller` returns // to allow for better versatility +/** @deprecated Limit Orders are deprecated and will be removed in a future version. */ export function constructFillOrderDirectly( options: ConstructProviderFetchInput ): FillOrderDirectlyFunctions { diff --git a/src/methods/limitOrders/getOrders.ts b/src/methods/limitOrders/getOrders.ts index d0896ced3..b59db93c4 100644 --- a/src/methods/limitOrders/getOrders.ts +++ b/src/methods/limitOrders/getOrders.ts @@ -52,6 +52,7 @@ type GetRequiredBalance = ( requestParams?: RequestParameters ) => Promise>; +/** @deprecated Limit Orders are deprecated and will be removed in a future version. */ export type GetLimitOrdersFunctions = { getLimitOrders: GetLimitOrders; getLimitOrderByHash: GetLimitOrderByHash; @@ -67,6 +68,7 @@ export type GetLimitOrdersFunctions = { getRequiredBalance: GetRequiredBalance; }; +/** @deprecated Limit Orders are deprecated and will be removed in a future version. */ export const constructGetLimitOrders = ({ apiURL = API_URL, chainId, diff --git a/src/methods/limitOrders/getOrdersContract.ts b/src/methods/limitOrders/getOrdersContract.ts index 310dd4d7a..ae7c32018 100644 --- a/src/methods/limitOrders/getOrdersContract.ts +++ b/src/methods/limitOrders/getOrdersContract.ts @@ -1,11 +1,13 @@ import type { ConstructFetchInput } from '../../types'; import { constructGetSpender, GetSpender } from '../swap/spender'; +/** @deprecated Limit Orders are deprecated and will be removed in a future version. */ export type GetLimitOrdersContractFunctions = { getLimitOrdersContract: GetSpender; getTokenTransferProxy: GetSpender; }; +/** @deprecated Limit Orders are deprecated and will be removed in a future version. */ export const constructGetLimitOrdersContract = ( options: ConstructFetchInput ): GetLimitOrdersContractFunctions => { diff --git a/src/methods/limitOrders/index.ts b/src/methods/limitOrders/index.ts index 5c62cb3b0..624860c48 100644 --- a/src/methods/limitOrders/index.ts +++ b/src/methods/limitOrders/index.ts @@ -45,11 +45,13 @@ type SubmitP2POrder = ( requestParams?: RequestParameters ) => Promise; +/** @deprecated Limit Orders are deprecated and will be removed in a future version. */ export type SubmitLimitOrderFuncs = { submitLimitOrder: SubmitLimitOrder; submitP2POrder: SubmitP2POrder; }; +/** @deprecated Limit Orders are deprecated and will be removed in a future version. */ export const constructSubmitLimitOrder = ( options: ConstructProviderFetchInput ): SubmitLimitOrderFuncs => { @@ -106,6 +108,7 @@ export const constructSubmitLimitOrder = ( return { submitLimitOrder, submitP2POrder }; }; +/** @deprecated Limit Orders are deprecated and will be removed in a future version. */ export type LimitOrderHandlers = SubmitLimitOrderFuncs & BuildLimitOrderFunctions & SignLimitOrderFunctions & @@ -117,7 +120,10 @@ export type LimitOrderHandlers = SubmitLimitOrderFuncs & ApproveTokenForLimitOrderFunctions & FillOrderDirectlyFunctions; -/** @description construct SDK with every LimitOrders-related method, fetching from API and contract calls */ +/** + * @description construct SDK with every LimitOrders-related method, fetching from API and contract calls + * @deprecated Limit Orders are deprecated and will be removed in a future version. + */ export const constructAllLimitOrdersHandlers = ( options: ConstructProviderFetchInput< TxResponse, diff --git a/src/methods/limitOrders/postOrder.ts b/src/methods/limitOrders/postOrder.ts index f52f47619..1ef8b973d 100644 --- a/src/methods/limitOrders/postOrder.ts +++ b/src/methods/limitOrders/postOrder.ts @@ -13,11 +13,13 @@ type PostLimitOrder = ( requestParams?: RequestParameters ) => Promise; +/** @deprecated Limit Orders are deprecated and will be removed in a future version. */ export type PostLimitOrderFunctions = { postLimitOrder: PostLimitOrder; postP2POrder: PostLimitOrder; }; +/** @deprecated Limit Orders are deprecated and will be removed in a future version. */ export const constructPostLimitOrder = ({ apiURL = API_URL, chainId, diff --git a/src/methods/limitOrders/signOrder.ts b/src/methods/limitOrders/signOrder.ts index ff94ef959..c66e999be 100644 --- a/src/methods/limitOrders/signOrder.ts +++ b/src/methods/limitOrders/signOrder.ts @@ -2,12 +2,14 @@ import type { ConstructProviderFetchInput } from '../../types'; import type { SignableOrderData } from './buildOrder'; import { sanitizeOrderData } from './helpers/misc'; +/** @deprecated Limit Orders are deprecated and will be removed in a future version. */ export type SignLimitOrderFunctions = { signLimitOrder: (signableOrderData: SignableOrderData) => Promise; }; // returns whatever `contractCaller` returns // to allow for better versatility +/** @deprecated Limit Orders are deprecated and will be removed in a future version. */ export const constructSignLimitOrder = ( options: Pick< ConstructProviderFetchInput, diff --git a/src/methods/limitOrders/transaction.ts b/src/methods/limitOrders/transaction.ts index 5ca90bc95..99f9c759a 100644 --- a/src/methods/limitOrders/transaction.ts +++ b/src/methods/limitOrders/transaction.ts @@ -44,6 +44,7 @@ type BuildLimitOrdersTx = ( requestParams?: RequestParameters ) => Promise; +/** @deprecated Limit Orders are deprecated and will be removed in a future version. */ export type BuildLimitOrdersTxFunctions = { getLimitOrdersRate: GetLimitOrdersRate; buildLimitOrderTx: BuildLimitOrdersTx; @@ -57,6 +58,7 @@ type GetLimitOrdersRate = ( requestParams?: RequestParameters ) => Promise; +/** @deprecated Limit Orders are deprecated and will be removed in a future version. */ export const constructBuildLimitOrderTx = ({ apiURL = API_URL, version = DEFAULT_VERSION, diff --git a/src/methods/nftOrders/approveForOrder.ts b/src/methods/nftOrders/approveForOrder.ts index ab7fc8661..a1b75664c 100644 --- a/src/methods/nftOrders/approveForOrder.ts +++ b/src/methods/nftOrders/approveForOrder.ts @@ -15,6 +15,7 @@ type ApproveNFT = ( requestParams?: RequestParameters ) => Promise; +/** @deprecated NFT Orders are deprecated and will be removed in a future version. */ export type ApproveTokenForNFTOrderFunctions = { /** @description approving AugustusSwapper as spender for takerAsset (ERC20) for Limit Orders that will be executed through it */ approveERC20ForNFTOrder: ApproveToken; @@ -47,6 +48,7 @@ type ApprovalMethods = ExtractAbiMethodNames; // returns whatever `contractCaller` returns // to allow for better versatility +/** @deprecated NFT Orders are deprecated and will be removed in a future version. */ export const constructApproveTokenForNFTOrder = ( options: ConstructProviderFetchInput ): ApproveTokenForNFTOrderFunctions => { diff --git a/src/methods/nftOrders/buildOrder.ts b/src/methods/nftOrders/buildOrder.ts index fa58fd2f5..07127bbfb 100644 --- a/src/methods/nftOrders/buildOrder.ts +++ b/src/methods/nftOrders/buildOrder.ts @@ -7,6 +7,7 @@ import { } from './helpers/buildOrderData'; export * from './helpers/buildOrderData'; +/** @deprecated NFT Orders are deprecated and will be removed in a future version. */ export type BuildNFTOrderInput = Omit< BuildNFTOrderDataInput, 'chainId' | 'verifyingContract' | 'AugustusAddress' @@ -17,11 +18,13 @@ type BuildNFTOrder = ( requestParams?: RequestParameters ) => Promise; +/** @deprecated NFT Orders are deprecated and will be removed in a future version. */ export type BuildNFTOrderFunctions = { /** @description Build Orders that will be excuted through AugustusSwapper */ buildNFTOrder: BuildNFTOrder; }; +/** @deprecated NFT Orders are deprecated and will be removed in a future version. */ export const constructBuildNFTOrder = ( options: ConstructFetchInput ): BuildNFTOrderFunctions => { diff --git a/src/methods/nftOrders/cancelOrder.ts b/src/methods/nftOrders/cancelOrder.ts index b67601c0b..ef70de7f7 100644 --- a/src/methods/nftOrders/cancelOrder.ts +++ b/src/methods/nftOrders/cancelOrder.ts @@ -5,12 +5,14 @@ import { constructCancelLimitOrder, } from '../limitOrders/cancelOrder'; +/** @deprecated NFT Orders are deprecated and will be removed in a future version. */ export type CancelNFTOrderFunctions = { cancelNFTOrder: CancelOrder; cancelNFTOrderBulk: CancelOrderBulk; }; // should work the same as for LimitOrders +/** @deprecated NFT Orders are deprecated and will be removed in a future version. */ export const constructCancelNFTOrder = ( options: ConstructProviderFetchInput ): CancelNFTOrderFunctions => { diff --git a/src/methods/nftOrders/getOrders.ts b/src/methods/nftOrders/getOrders.ts index 7fe2bcf6c..f207821ad 100644 --- a/src/methods/nftOrders/getOrders.ts +++ b/src/methods/nftOrders/getOrders.ts @@ -28,11 +28,13 @@ type GetNFTOrders = ( requestParams?: RequestParameters ) => Promise; +/** @deprecated NFT Orders are deprecated and will be removed in a future version. */ export type GetNFTOrdersFunctions = { getNFTOrders: GetNFTOrders; getNFTOrderByHash: GetNFTOrderByHash; }; +/** @deprecated NFT Orders are deprecated and will be removed in a future version. */ export const constructGetNFTOrders = ({ apiURL = API_URL, chainId, diff --git a/src/methods/nftOrders/getOrdersContract.ts b/src/methods/nftOrders/getOrdersContract.ts index a848f1e63..dab457f81 100644 --- a/src/methods/nftOrders/getOrdersContract.ts +++ b/src/methods/nftOrders/getOrdersContract.ts @@ -1,12 +1,14 @@ import type { ConstructFetchInput } from '../../types'; import { constructGetSpender, GetSpender } from '../swap/spender'; +/** @deprecated NFT Orders are deprecated and will be removed in a future version. */ export type GetNFTOrdersContractFunctions = { getNFTOrdersContract: GetSpender; getTokenTransferProxy: GetSpender; }; // should work the same as LimitOrders +/** @deprecated NFT Orders are deprecated and will be removed in a future version. */ export const constructGetNFTOrdersContract = ( options: ConstructFetchInput ): GetNFTOrdersContractFunctions => { diff --git a/src/methods/nftOrders/helpers/misc.ts b/src/methods/nftOrders/helpers/misc.ts index 1b5b86907..8a74e06c4 100644 --- a/src/methods/nftOrders/helpers/misc.ts +++ b/src/methods/nftOrders/helpers/misc.ts @@ -18,6 +18,7 @@ import { // ERC721 = 2, // } +/** @deprecated NFT Orders are deprecated and will be removed in a future version. */ export const AssetType = { ERC20: 0, ERC1155: 1, diff --git a/src/methods/nftOrders/index.ts b/src/methods/nftOrders/index.ts index e3666d83b..796e3d045 100644 --- a/src/methods/nftOrders/index.ts +++ b/src/methods/nftOrders/index.ts @@ -34,11 +34,13 @@ type SubmitNFTOrder = ( requestParams?: RequestParameters ) => Promise; +/** @deprecated NFT Orders are deprecated and will be removed in a future version. */ export type SubmitNFTOrderFuncs = { submitNFTOrder: SubmitNFTOrder; submitP2POrder: SubmitNFTOrder; }; +/** @deprecated NFT Orders are deprecated and will be removed in a future version. */ export const constructSubmitNFTOrder = ( options: ConstructProviderFetchInput ): SubmitNFTOrderFuncs => { @@ -95,6 +97,7 @@ export const constructSubmitNFTOrder = ( return { submitNFTOrder, submitP2POrder }; }; +/** @deprecated NFT Orders are deprecated and will be removed in a future version. */ export type NFTOrderHandlers = SubmitNFTOrderFuncs & BuildNFTOrderFunctions & SignNFTOrderFunctions & @@ -105,7 +108,10 @@ export type NFTOrderHandlers = SubmitNFTOrderFuncs & CancelNFTOrderFunctions & ApproveTokenForNFTOrderFunctions; -/** @description construct SDK with every NFTOrders-related method, fetching from API and contract calls */ +/** + * @description construct SDK with every NFTOrders-related method, fetching from API and contract calls + * @deprecated NFT Orders are deprecated and will be removed in a future version. + */ export const constructAllNFTOrdersHandlers = ( options: ConstructProviderFetchInput< TxResponse, diff --git a/src/methods/nftOrders/postOrder.ts b/src/methods/nftOrders/postOrder.ts index a4deb5db9..8f2c899bf 100644 --- a/src/methods/nftOrders/postOrder.ts +++ b/src/methods/nftOrders/postOrder.ts @@ -13,11 +13,13 @@ type PostNFTOrder = ( requestParams?: RequestParameters ) => Promise; +/** @deprecated NFT Orders are deprecated and will be removed in a future version. */ export type PostNFTOrderFunctions = { postNFTLimitOrder: PostNFTOrder; postNFTP2POrder: PostNFTOrder; }; +/** @deprecated NFT Orders are deprecated and will be removed in a future version. */ export const constructPostNFTOrder = ({ apiURL = API_URL, chainId, diff --git a/src/methods/nftOrders/signOrder.ts b/src/methods/nftOrders/signOrder.ts index 364207b94..714c628a9 100644 --- a/src/methods/nftOrders/signOrder.ts +++ b/src/methods/nftOrders/signOrder.ts @@ -2,12 +2,14 @@ import type { ConstructProviderFetchInput } from '../../types'; import type { SignableNFTOrderData } from './buildOrder'; import { sanitizeOrderData } from './helpers/misc'; +/** @deprecated NFT Orders are deprecated and will be removed in a future version. */ export type SignNFTOrderFunctions = { signNFTOrder: (signableOrderData: SignableNFTOrderData) => Promise; }; // returns whatever `contractCaller` returns // to allow for better versatility +/** @deprecated NFT Orders are deprecated and will be removed in a future version. */ export const constructSignNFTOrder = ( options: Pick< ConstructProviderFetchInput, diff --git a/src/methods/nftOrders/transaction.ts b/src/methods/nftOrders/transaction.ts index 3088c3c98..4cb8c43a2 100644 --- a/src/methods/nftOrders/transaction.ts +++ b/src/methods/nftOrders/transaction.ts @@ -43,6 +43,7 @@ type BuildNFTOrdersTx = ( requestParams?: RequestParameters ) => Promise; +/** @deprecated NFT Orders are deprecated and will be removed in a future version. */ export type BuildNFTOrdersTxFunctions = { getNFTOrdersRate: GetNFTOrdersRate; buildNFTOrderTx: BuildNFTOrdersTx; @@ -56,6 +57,7 @@ type GetNFTOrdersRate = ( requestParams?: RequestParameters ) => Promise; +/** @deprecated NFT Orders are deprecated and will be removed in a future version. */ export const constructBuildNFTOrderTx = ({ apiURL = API_URL, version = DEFAULT_VERSION, diff --git a/src/sdk/full.ts b/src/sdk/full.ts index 4f5b8666d..e6d2dde54 100644 --- a/src/sdk/full.ts +++ b/src/sdk/full.ts @@ -21,7 +21,9 @@ import { API_URL, DEFAULT_VERSION } from '../constants'; export type AllSDKMethods = { swap: SwapSDKMethods; + /** @deprecated Limit Orders are deprecated and will be removed in a future version. */ limitOrders: LimitOrderHandlers; + /** @deprecated NFT Orders are deprecated and will be removed in a future version. */ nftOrders: NFTOrderHandlers; delta: DeltaOrderHandlers; quote: GetQuoteFunctions; diff --git a/src/sdk/partial.ts b/src/sdk/partial.ts index 437e95dd9..29e6f7baa 100644 --- a/src/sdk/partial.ts +++ b/src/sdk/partial.ts @@ -13,6 +13,7 @@ import type { ApproveTokenForNFTOrderFunctions } from '../methods/nftOrders/appr import type { FillOrderDirectlyFunctions } from '../methods/limitOrders/fillOrderDirectly'; import type { ApproveTokenForDeltaFunctions } from '../methods/delta/approveForDelta'; import type { PreSignDeltaOrderFunctions } from '../methods/delta/preSignDeltaOrder'; +import type { PreSignExternalDeltaOrderFunctions } from '../methods/delta/preSignExternalDeltaOrder'; import type { DeltaTokenModuleFunctions } from '../methods/delta/deltaTokenModule'; import { API_URL, DEFAULT_VERSION } from '../constants'; @@ -54,6 +55,7 @@ type InferWithTxResponse< ApproveTokenForNFTOrderFunctions, ApproveTokenForDeltaFunctions, PreSignDeltaOrderFunctions, + PreSignExternalDeltaOrderFunctions, DeltaTokenModuleFunctions ] // then merge IntersectionOfReturns with them recursively diff --git a/src/sdk/simple.ts b/src/sdk/simple.ts index 9fe76ac88..8d16a1860 100644 --- a/src/sdk/simple.ts +++ b/src/sdk/simple.ts @@ -145,12 +145,14 @@ export type SwapFetchMethods = GetBalancesFunctions & GetRateFunctions & GetSwapTxFunctions; +/** @deprecated Limit Orders are deprecated and will be removed in a future version. */ export type LimitOrdersFetchMethods = GetLimitOrdersContractFunctions & GetLimitOrdersFunctions & BuildLimitOrderFunctions & PostLimitOrderFunctions & BuildLimitOrdersTxFunctions; +/** @deprecated NFT Orders are deprecated and will be removed in a future version. */ export type NFTOrdersFetchMethods = GetNFTOrdersContractFunctions & GetNFTOrdersFunctions & BuildNFTOrderFunctions & @@ -168,7 +170,9 @@ export type DeltaFetchMethods = BuildDeltaOrderFunctions & export type SimpleFetchSDK = { swap: SwapFetchMethods; + /** @deprecated Limit Orders are deprecated and will be removed in a future version. */ limitOrders: LimitOrdersFetchMethods; + /** @deprecated NFT Orders are deprecated and will be removed in a future version. */ nftOrders: NFTOrdersFetchMethods; delta: DeltaFetchMethods; quote: QuoteFetchMethods; @@ -178,7 +182,9 @@ export type QuoteFetchMethods = GetQuoteFunctions; export type SimpleSDK = { swap: SwapSDKMethods; + /** @deprecated Limit Orders are deprecated and will be removed in a future version. */ limitOrders: LimitOrderHandlers; + /** @deprecated NFT Orders are deprecated and will be removed in a future version. */ nftOrders: NFTOrderHandlers; delta: DeltaOrderHandlers; quote: QuoteFetchMethods; diff --git a/tests/__snapshots__/delta.test.ts.snap b/tests/__snapshots__/delta.test.ts.snap index 8f203e3a8..4c36b4de1 100644 --- a/tests/__snapshots__/delta.test.ts.snap +++ b/tests/__snapshots__/delta.test.ts.snap @@ -126,6 +126,7 @@ exports[`Delta:methods Get Delta Order by Id and Hash 1`] = ` "expiresAt": "2025-04-18T15:03:33.000Z", "id": "7ec0dc82-98ad-4501-9f46-03e31e51098f", "includeAgents": null, + "onChainOrderType": "Order", "order": { "beneficiary": "0x0ddc793680ff4f5793849c8c6992be1695cbe72a", "bridge": { @@ -195,6 +196,7 @@ exports[`Delta:methods Get Delta Orders for user 1`] = ` "expiresAt": "2024-10-10T17:17:47.000Z", "id": "8515cce6-c7c6-486b-9f1e-5702f204edd6", "includeAgents": null, + "onChainOrderType": "Order", "order": { "beneficiary": "0x76176c2971300217e9f48e3dd4e40591500b96ff", "bridge": { @@ -259,6 +261,7 @@ exports[`Delta:methods Get Delta Orders for user 1`] = ` "expiresAt": "2024-10-09T17:52:08.000Z", "id": "7696f983-4f0d-4bb0-b591-61957abf74de", "includeAgents": null, + "onChainOrderType": "Order", "order": { "beneficiary": "0x76176c2971300217e9f48e3dd4e40591500b96ff", "bridge": { diff --git a/tests/__snapshots__/limitOrders.test.ts.snap b/tests/__snapshots__/limitOrders.test.ts.snap deleted file mode 100644 index 1452e4c93..000000000 --- a/tests/__snapshots__/limitOrders.test.ts.snap +++ /dev/null @@ -1,260 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Limit Orders Build_Swap+LO_Tx 1`] = ` -{ - "bestRoute": [ - { - "percent": 100, - "swaps": [ - { - "destDecimals": 18, - "destToken": "0x0d8775f648430679a709e98d2b0cb6250d2887ef", - "srcDecimals": 18, - "srcToken": "0x6b175474e89094c44da98b954eedeac495271d0f", - "swapExchanges": [ - { - "data": { - "factory": "0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f", - "feeFactor": 10000, - "gasUSD": "---", - "initCode": "0x96e8ac4277198ff8b6f785478aa9a39f403cb768dd02cbee326c3e7da348845f", - "path": [ - "0x6b175474e89094c44da98b954eedeac495271d0f", - "0x0d8775f648430679a709e98d2b0cb6250d2887ef", - ], - "pools": [ - { - "address": "0x6929abD7931D0243777d3CD147fE863646A752ba", - "direction": false, - "fee": 30, - }, - ], - "router": "0xF9234CB08edb93c0d4a4d4c70cC3FfD070e78e07", - }, - "destAmount": "6000000000000000000", - "exchange": "UniswapV2", - "percent": 100, - "poolAddresses": [ - "0x6929abD7931D0243777d3CD147fE863646A752ba", - ], - "poolIdentifiers": [ - "uniswapv2_0x0d8775f648430679a709e98d2b0cb6250d2887ef_0x6b175474e89094c44da98b954eedeac495271d0f", - ], - "srcAmount": "---", - }, - ], - }, - ], - }, - ], - "blockNumber": NaN, - "contractAddress": "0xDEF171Fe48CF0115B1d80b88dc8eAB59176FEe57", - "contractMethod": "simpleBuy", - "destAmount": "6000000000000000000", - "destDecimals": 18, - "destToken": "0x0d8775f648430679a709e98d2b0cb6250d2887ef", - "destUSD": "---", - "gasCost": "---", - "gasCostUSD": "---", - "hmac": "---", - "maxImpactReached": false, - "network": 1, - "partner": "anon", - "partnerFee": 0, - "side": "BUY", - "srcAmount": "---", - "srcDecimals": 18, - "srcToken": "0x6b175474e89094c44da98b954eedeac495271d0f", - "srcUSD": "---", - "tokenTransferProxy": "0x216b4b4ba9f3e719726886d34a177484278bfcae", - "version": "5", -} -`; - -exports[`Limit Orders buildLimitOrder p2p: P2P_Order_Data_Snapshot 1`] = ` -{ - "data": { - "expiry": 1766188800, - "maker": "0xaC39b311DCEb2A4b2f5d8461c1cdaF756F4F7Ae9", - "makerAmount": "1000000000000000000", - "makerAsset": "0x6b175474e89094c44da98b954eedeac495271d0f", - "nonceAndMeta": "2693234308085732315020447542820174961101890254772", - "taker": "0xDEF171Fe48CF0115B1d80b88dc8eAB59176FEe57", - "takerAmount": "8000000000000000000", - "takerAsset": "0x2b591e99afe9f32eaa6214f7b7629768c40eeb39", - }, - "domain": { - "chainId": 1, - "name": "AUGUSTUS RFQ", - "verifyingContract": "0xe92b586627ccA7a83dC919cc7127196d70f55a06", - "version": "1", - }, - "types": { - "Order": [ - { - "name": "nonceAndMeta", - "type": "uint256", - }, - { - "name": "expiry", - "type": "uint128", - }, - { - "name": "makerAsset", - "type": "address", - }, - { - "name": "takerAsset", - "type": "address", - }, - { - "name": "maker", - "type": "address", - }, - { - "name": "taker", - "type": "address", - }, - { - "name": "makerAmount", - "type": "uint256", - }, - { - "name": "takerAmount", - "type": "uint256", - }, - ], - }, -} -`; - -exports[`Limit Orders buildLimitOrder: Order_Data_Snapshot 1`] = ` -{ - "data": { - "expiry": 1766188800, - "maker": "0xaC39b311DCEb2A4b2f5d8461c1cdaF756F4F7Ae9", - "makerAmount": "1000000000000000000", - "makerAsset": "0x6b175474e89094c44da98b954eedeac495271d0f", - "nonceAndMeta": "1461501637330902918203684832716283019655932542976", - "taker": "0x0000000000000000000000000000000000000000", - "takerAmount": "8000000000000000000", - "takerAsset": "0x2b591e99afe9f32eaa6214f7b7629768c40eeb39", - }, - "domain": { - "chainId": 1, - "name": "AUGUSTUS RFQ", - "verifyingContract": "0xe92b586627ccA7a83dC919cc7127196d70f55a06", - "version": "1", - }, - "types": { - "Order": [ - { - "name": "nonceAndMeta", - "type": "uint256", - }, - { - "name": "expiry", - "type": "uint128", - }, - { - "name": "makerAsset", - "type": "address", - }, - { - "name": "takerAsset", - "type": "address", - }, - { - "name": "maker", - "type": "address", - }, - { - "name": "taker", - "type": "address", - }, - { - "name": "makerAmount", - "type": "uint256", - }, - { - "name": "takerAmount", - "type": "uint256", - }, - ], - }, -} -`; - -exports[`Limit Orders getLimitOrders 1`] = ` -[ - { - "chainId": 137, - "createdAt": 1661185927, - "expiry": 0, - "fillableBalance": "10000000000000000", - "isFillOrKill": false, - "maker": "0x05182e579fdfcf69e4390c3411d8fea1fb6467cf", - "makerAmount": "10000000000000000", - "makerAsset": "0x0d500b1d8e8ef31e21c99d1db9a6444d3adf1270", - "makerBalance": "10000000000000000", - "nonceAndMeta": "11606055776319970719498565483696350838927613089159547657501278208", - "orderHash": "0xfd076127e9fe40c5acf2efd03f8dd0cf2412fe277013d241c95a5da3eb64d5f8", - "permitMakerAsset": null, - "state": "CANCELLED", - "swappableBalance": "10000000000000000", - "taker": "0xdef171fe48cf0115b1d80b88dc8eab59176fee57", - "takerAmount": "7960150000000000", - "takerAsset": "0x8f3cf7ad23cd3cadbd9735aff958023239c6a063", - "takerFromMeta": "0x0000000000000000000000000000000000000000", - "transactionHash": "0xf403c6c4b625f055c206b377b8b4296e017e66071e8bd652df18cb344f69f8ae", - "type": "LIMIT", - "updatedAt": 1661186323, - }, - { - "chainId": 137, - "createdAt": 1661102635, - "expiry": 0, - "fillableBalance": "27806", - "isFillOrKill": false, - "maker": "0x05182e579fdfcf69e4390c3411d8fea1fb6467cf", - "makerAmount": "1000000", - "makerAsset": "0x2791bca1f2de4661ed88a30c99a7a9449aa84174", - "makerBalance": "27806", - "nonceAndMeta": "5138925241883764339325856218512467102197816820790096695352360960", - "orderHash": "0xef9fdf84be98cc70c05dbfe62af88412c1231f3025d3c829cf93b29f578a66fd", - "permitMakerAsset": null, - "state": "CANCELLED", - "swappableBalance": "27806", - "taker": "0xdef171fe48cf0115b1d80b88dc8eab59176fee57", - "takerAmount": "999800000000000000", - "takerAsset": "0x8f3cf7ad23cd3cadbd9735aff958023239c6a063", - "takerFromMeta": "0x0000000000000000000000000000000000000000", - "transactionHash": "0x235aaa8472de0a724ea09daee5f2ed57d4365753d521008bcd9550d83a4461c7", - "type": "LIMIT", - "updatedAt": 1661162748, - }, - { - "chainId": 137, - "createdAt": 1661102624, - "expiry": 0, - "fillableBalance": "1000000000000000000", - "isFillOrKill": false, - "maker": "0x05182e579fdfcf69e4390c3411d8fea1fb6467cf", - "makerAmount": "1000000000000000000", - "makerAsset": "0x8f3cf7ad23cd3cadbd9735aff958023239c6a063", - "makerBalance": "1000000000000000000", - "nonceAndMeta": "3760348195635624801084706457448060906520635007281149607661273088", - "orderHash": "0x005c10e295af191364c7b47df72c0ca71b75b8f827231b352c4199ae109d4234", - "permitMakerAsset": null, - "state": "CANCELLED", - "swappableBalance": "1000000000000000000", - "taker": "0xdef171fe48cf0115b1d80b88dc8eab59176fee57", - "takerAmount": "1000230", - "takerAsset": "0x2791bca1f2de4661ed88a30c99a7a9449aa84174", - "takerFromMeta": "0x0000000000000000000000000000000000000000", - "transactionHash": "0x235aaa8472de0a724ea09daee5f2ed57d4365753d521008bcd9550d83a4461c7", - "type": "LIMIT", - "updatedAt": 1661162748, - }, -] -`; diff --git a/tests/__snapshots__/nftOrders.test.ts.snap b/tests/__snapshots__/nftOrders.test.ts.snap deleted file mode 100644 index 269086d6c..000000000 --- a/tests/__snapshots__/nftOrders.test.ts.snap +++ /dev/null @@ -1,135 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`NFT Orders buildNFTOrder p2p: P2P_Order_Data_Snapshot 1`] = ` -{ - "data": { - "expiry": 1766188800, - "maker": "0xaC39b311DCEb2A4b2f5d8461c1cdaF756F4F7Ae9", - "makerAmount": "1000000000000000000", - "makerAsset": "2072883924162524385437572631638126955675586600207", - "makerAssetId": "9982", - "nonceAndMeta": "2693234308085732315020447542820174961101890254772", - "taker": "0xDEF171Fe48CF0115B1d80b88dc8eAB59176FEe57", - "takerAmount": "8000000000000000000", - "takerAsset": "454839140962945226527790820083642630354574802003", - "takerAssetId": "0", - }, - "domain": { - "chainId": 1, - "name": "AUGUSTUS RFQ", - "verifyingContract": "0xe92b586627ccA7a83dC919cc7127196d70f55a06", - "version": "1", - }, - "types": { - "OrderNFT": [ - { - "name": "nonceAndMeta", - "type": "uint256", - }, - { - "name": "expiry", - "type": "uint128", - }, - { - "name": "makerAsset", - "type": "uint256", - }, - { - "name": "makerAssetId", - "type": "uint256", - }, - { - "name": "takerAsset", - "type": "uint256", - }, - { - "name": "takerAssetId", - "type": "uint256", - }, - { - "name": "maker", - "type": "address", - }, - { - "name": "taker", - "type": "address", - }, - { - "name": "makerAmount", - "type": "uint256", - }, - { - "name": "takerAmount", - "type": "uint256", - }, - ], - }, -} -`; - -exports[`NFT Orders buildNFTOrder: Order_Data_Snapshot 1`] = ` -{ - "data": { - "expiry": 1766188800, - "maker": "0xaC39b311DCEb2A4b2f5d8461c1cdaF756F4F7Ae9", - "makerAmount": "1000000000000000000", - "makerAsset": "2072883924162524385437572631638126955675586600207", - "makerAssetId": "9982", - "nonceAndMeta": "1461501637330902918203684832716283019655932542976", - "taker": "0xDEF171Fe48CF0115B1d80b88dc8eAB59176FEe57", - "takerAmount": "8000000000000000000", - "takerAsset": "454839140962945226527790820083642630354574802003", - "takerAssetId": "0", - }, - "domain": { - "chainId": 1, - "name": "AUGUSTUS RFQ", - "verifyingContract": "0xe92b586627ccA7a83dC919cc7127196d70f55a06", - "version": "1", - }, - "types": { - "OrderNFT": [ - { - "name": "nonceAndMeta", - "type": "uint256", - }, - { - "name": "expiry", - "type": "uint128", - }, - { - "name": "makerAsset", - "type": "uint256", - }, - { - "name": "makerAssetId", - "type": "uint256", - }, - { - "name": "takerAsset", - "type": "uint256", - }, - { - "name": "takerAssetId", - "type": "uint256", - }, - { - "name": "maker", - "type": "address", - }, - { - "name": "taker", - "type": "address", - }, - { - "name": "makerAmount", - "type": "uint256", - }, - { - "name": "takerAmount", - "type": "uint256", - }, - ], - }, -} -`; diff --git a/tests/__snapshots__/partialSdk.test.ts.snap b/tests/__snapshots__/partialSdk.test.ts.snap index 5436c2207..c57342cc0 100644 --- a/tests/__snapshots__/partialSdk.test.ts.snap +++ b/tests/__snapshots__/partialSdk.test.ts.snap @@ -1,44 +1,5 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`Partial SDK: fetching methods: axiosFetcher Get_Adapters: Get_Adapters 1`] = ` -[ - "CurveV2", - "Lido", - "EtherFi", - "CurveV1", - "BalancerV1", - "BalancerV2", - "UniswapV2", - "DefiSwap", - "SushiSwap", - "ShibaSwap", - "Verse", - "UniswapV3", - "SushiSwapV3", - "PancakeSwapV2", - "PancakeswapV3", - "AaveV3", - "AaveV3Lido", - "Weth", - "PolygonMigrator", - "Synapse", - "Synthetix", - "CurveV1Factory", - "CurveV1StableNg", - "wstETH", - "Hashflow", - "MaverickV1", - "SwaapV2", - "AngleStakedStableUSD", - "AngleStakedStableEUR", - "SolidlyV3", - "Swell", - "Spark", - "sUSDS", - "AugustusRFQ", -] -`; - exports[`Partial SDK: fetching methods: axiosFetcher Get_Contracts: axiosFetcher 1`] = ` { "AugustusRFQ": "0xe92b586627ccA7a83dC919cc7127196d70f55a06", @@ -77,7 +38,7 @@ exports[`Partial SDK: fetching methods: axiosFetcher Get_SwapTxData: Get_SwapTxD ], "blockNumber": "dynamic_number", "contractAddress": "0xDEF171Fe48CF0115B1d80b88dc8eAB59176FEe57", - "contractMethod": "swapOnUniswapV2Fork", + "contractMethod": "simpleSwap", "destAmount": "dynamic_number", "destDecimals": 18, "destToken": "0x6b175474e89094c44da98b954eedeac495271d0f", @@ -88,7 +49,7 @@ exports[`Partial SDK: fetching methods: axiosFetcher Get_SwapTxData: Get_SwapTxD "maxImpactReached": false, "network": 1, "partner": "anon", - "partnerFee": 0, + "partnerFee": NaN, "side": "SELL", "srcAmount": "1000000000000000000", "srcDecimals": 18, @@ -110,45 +71,6 @@ exports[`Partial SDK: fetching methods: axiosFetcher Get_SwapTxData: Get_SwapTxD } `; -exports[`Partial SDK: fetching methods: fetchFetcher Get_Adapters: Get_Adapters 1`] = ` -[ - "CurveV2", - "Lido", - "EtherFi", - "CurveV1", - "BalancerV1", - "BalancerV2", - "UniswapV2", - "DefiSwap", - "SushiSwap", - "ShibaSwap", - "Verse", - "UniswapV3", - "SushiSwapV3", - "PancakeSwapV2", - "PancakeswapV3", - "AaveV3", - "AaveV3Lido", - "Weth", - "PolygonMigrator", - "Synapse", - "Synthetix", - "CurveV1Factory", - "CurveV1StableNg", - "wstETH", - "Hashflow", - "MaverickV1", - "SwaapV2", - "AngleStakedStableUSD", - "AngleStakedStableEUR", - "SolidlyV3", - "Swell", - "Spark", - "sUSDS", - "AugustusRFQ", -] -`; - exports[`Partial SDK: fetching methods: fetchFetcher Get_Contracts: fetchFetcher 1`] = ` { "AugustusRFQ": "0xe92b586627ccA7a83dC919cc7127196d70f55a06", @@ -187,7 +109,7 @@ exports[`Partial SDK: fetching methods: fetchFetcher Get_SwapTxData: Get_SwapTxD ], "blockNumber": "dynamic_number", "contractAddress": "0xDEF171Fe48CF0115B1d80b88dc8eAB59176FEe57", - "contractMethod": "swapOnUniswapV2Fork", + "contractMethod": "simpleSwap", "destAmount": "dynamic_number", "destDecimals": 18, "destToken": "0x6b175474e89094c44da98b954eedeac495271d0f", @@ -198,7 +120,7 @@ exports[`Partial SDK: fetching methods: fetchFetcher Get_SwapTxData: Get_SwapTxD "maxImpactReached": false, "network": 1, "partner": "anon", - "partnerFee": 0, + "partnerFee": NaN, "side": "SELL", "srcAmount": "1000000000000000000", "srcDecimals": 18, diff --git a/tests/__snapshots__/quote.test.ts.snap b/tests/__snapshots__/quote.test.ts.snap index 3bd09f1e7..a0aad6176 100644 --- a/tests/__snapshots__/quote.test.ts.snap +++ b/tests/__snapshots__/quote.test.ts.snap @@ -39,9 +39,9 @@ exports[`Quote:methods Get Fallback Market Quote for all 2`] = ` "maxImpactReached": false, "network": 1, "partner": "anon", - "partnerFee": 0, + "partnerFee": NaN, "side": "SELL", - "srcAmount": "100000", + "srcAmount": "10000", "srcDecimals": 6, "srcToken": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48", "srcUSD": "dynamic_number", diff --git a/tests/__snapshots__/simpleSdk.test.ts.snap b/tests/__snapshots__/simpleSdk.test.ts.snap index 9b5741de5..536b2716c 100644 --- a/tests/__snapshots__/simpleSdk.test.ts.snap +++ b/tests/__snapshots__/simpleSdk.test.ts.snap @@ -1,77 +1,5 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`Simple SDK: fetcher made with: axios Get_Adapters: Get_Adapters 1`] = ` -[ - "CurveV2", - "Lido", - "EtherFi", - "Bebop", - "CurveV1", - "BalancerV1", - "BalancerV2", - "BalancerV3", - "UniswapV2", - "DefiSwap", - "SushiSwap", - "ShibaSwap", - "Verse", - "UniswapV3", - "SushiSwapV3", - "UniswapV4", - "PancakeSwapV2", - "PancakeswapV3", - "AaveV3", - "AaveV3Lido", - "Weth", - "PolygonMigrator", - "Synapse", - "Synthetix", - "CurveV1Factory", - "CurveV1StableNg", - "wstETH", - "wUSDL", - "sUSDe", - "stcUSD", - "Hashflow", - "Native", - "MaverickV1", - "MaverickV2", - "SwaapV2", - "AngleTransmuter", - "AngleStakedStableUSD", - "AngleStakedStableEUR", - "SolidlyV3", - "Swell", - "Spark", - "sUSDS", - "AaveV3Stata", - "AaveV3StataV2", - "OSwap", - "FxProtocolRusd", - "AaveGsm", - "LitePsm", - "UsualBond", - "StkGHO", - "DaiUsds", - "MkrSky", - "FluidDex", - "FluidDexLite", - "UsdcUsualUSDC", - "UsualUSDCUsd0", - "UsualMWrappedM", - "MWrappedM", - "WrappedMM", - "UsualMUsd0", - "UsualPP", - "Ekubo", - "MiroMigrator", - "AaveV3Pendle", - "RingV2", - "Cap", - "AugustusRFQ", -] -`; - exports[`Simple SDK: fetcher made with: axios Get_SwapTxData: Get_SwapTxData::priceRoute 1`] = ` { "bestRoute": [ @@ -111,7 +39,7 @@ exports[`Simple SDK: fetcher made with: axios Get_SwapTxData: Get_SwapTxData::pr "maxImpactReached": false, "network": 1, "partner": "anon", - "partnerFee": 0, + "partnerFee": NaN, "side": "SELL", "srcAmount": "1000000000000000000", "srcDecimals": 18, @@ -133,78 +61,6 @@ exports[`Simple SDK: fetcher made with: axios Get_SwapTxData: Get_SwapTxData::tx } `; -exports[`Simple SDK: fetcher made with: fetch Get_Adapters: Get_Adapters 1`] = ` -[ - "CurveV2", - "Lido", - "EtherFi", - "Bebop", - "CurveV1", - "BalancerV1", - "BalancerV2", - "BalancerV3", - "UniswapV2", - "DefiSwap", - "SushiSwap", - "ShibaSwap", - "Verse", - "UniswapV3", - "SushiSwapV3", - "UniswapV4", - "PancakeSwapV2", - "PancakeswapV3", - "AaveV3", - "AaveV3Lido", - "Weth", - "PolygonMigrator", - "Synapse", - "Synthetix", - "CurveV1Factory", - "CurveV1StableNg", - "wstETH", - "wUSDL", - "sUSDe", - "stcUSD", - "Hashflow", - "Native", - "MaverickV1", - "MaverickV2", - "SwaapV2", - "AngleTransmuter", - "AngleStakedStableUSD", - "AngleStakedStableEUR", - "SolidlyV3", - "Swell", - "Spark", - "sUSDS", - "AaveV3Stata", - "AaveV3StataV2", - "OSwap", - "FxProtocolRusd", - "AaveGsm", - "LitePsm", - "UsualBond", - "StkGHO", - "DaiUsds", - "MkrSky", - "FluidDex", - "FluidDexLite", - "UsdcUsualUSDC", - "UsualUSDCUsd0", - "UsualMWrappedM", - "MWrappedM", - "WrappedMM", - "UsualMUsd0", - "UsualPP", - "Ekubo", - "MiroMigrator", - "AaveV3Pendle", - "RingV2", - "Cap", - "AugustusRFQ", -] -`; - exports[`Simple SDK: fetcher made with: fetch Get_SwapTxData: Get_SwapTxData::priceRoute 1`] = ` { "bestRoute": [ @@ -244,7 +100,7 @@ exports[`Simple SDK: fetcher made with: fetch Get_SwapTxData: Get_SwapTxData::pr "maxImpactReached": false, "network": 1, "partner": "anon", - "partnerFee": 0, + "partnerFee": NaN, "side": "SELL", "srcAmount": "1000000000000000000", "srcDecimals": 18, diff --git a/tests/abi/ERC20Mintable.json b/tests/abi/ERC20Mintable.json deleted file mode 100644 index 727d244bb..000000000 --- a/tests/abi/ERC20Mintable.json +++ /dev/null @@ -1,389 +0,0 @@ -[ - { - "inputs": [ - { - "internalType": "string", - "name": "name", - "type": "string" - }, - { - "internalType": "string", - "name": "symbol", - "type": "string" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "spender", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "value", - "type": "uint256" - } - ], - "name": "Approval", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "previousOwner", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "newOwner", - "type": "address" - } - ], - "name": "OwnershipTransferred", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "value", - "type": "uint256" - } - ], - "name": "Transfer", - "type": "event" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "internalType": "address", - "name": "spender", - "type": "address" - } - ], - "name": "allowance", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "spender", - "type": "address" - }, - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "name": "approve", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "account", - "type": "address" - } - ], - "name": "balanceOf", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "account", - "type": "address" - }, - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "name": "burn", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "decimals", - "outputs": [ - { - "internalType": "uint8", - "name": "", - "type": "uint8" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "spender", - "type": "address" - }, - { - "internalType": "uint256", - "name": "subtractedValue", - "type": "uint256" - } - ], - "name": "decreaseAllowance", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "getChainId", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "spender", - "type": "address" - }, - { - "internalType": "uint256", - "name": "addedValue", - "type": "uint256" - } - ], - "name": "increaseAllowance", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "account", - "type": "address" - }, - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "name": "mint", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "name", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "owner", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "renounceOwnership", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "symbol", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "totalSupply", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "recipient", - "type": "address" - }, - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "name": "transfer", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "sender", - "type": "address" - }, - { - "internalType": "address", - "name": "recipient", - "type": "address" - }, - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "name": "transferFrom", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "newOwner", - "type": "address" - } - ], - "name": "transferOwnership", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - } -] \ No newline at end of file diff --git a/tests/abi/ERC721Mintable.json b/tests/abi/ERC721Mintable.json deleted file mode 100644 index 6aed7ab68..000000000 --- a/tests/abi/ERC721Mintable.json +++ /dev/null @@ -1,739 +0,0 @@ -[ - { - "inputs": [], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "approved", - "type": "address" - }, - { - "indexed": true, - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - } - ], - "name": "Approval", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "operator", - "type": "address" - }, - { - "indexed": false, - "internalType": "bool", - "name": "approved", - "type": "bool" - } - ], - "name": "ApprovalForAll", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "account", - "type": "address" - } - ], - "name": "Paused", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "bytes32", - "name": "role", - "type": "bytes32" - }, - { - "indexed": true, - "internalType": "bytes32", - "name": "previousAdminRole", - "type": "bytes32" - }, - { - "indexed": true, - "internalType": "bytes32", - "name": "newAdminRole", - "type": "bytes32" - } - ], - "name": "RoleAdminChanged", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "bytes32", - "name": "role", - "type": "bytes32" - }, - { - "indexed": true, - "internalType": "address", - "name": "account", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "sender", - "type": "address" - } - ], - "name": "RoleGranted", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "bytes32", - "name": "role", - "type": "bytes32" - }, - { - "indexed": true, - "internalType": "address", - "name": "account", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "sender", - "type": "address" - } - ], - "name": "RoleRevoked", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "indexed": true, - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - } - ], - "name": "Transfer", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "account", - "type": "address" - } - ], - "name": "Unpaused", - "type": "event" - }, - { - "inputs": [], - "name": "DEFAULT_ADMIN_ROLE", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "MINTER_ROLE", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "PAUSER_ROLE", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - } - ], - "name": "approve", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "owner", - "type": "address" - } - ], - "name": "balanceOf", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - } - ], - "name": "burn", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - } - ], - "name": "getApproved", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "role", - "type": "bytes32" - } - ], - "name": "getRoleAdmin", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "role", - "type": "bytes32" - }, - { - "internalType": "uint256", - "name": "index", - "type": "uint256" - } - ], - "name": "getRoleMember", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "role", - "type": "bytes32" - } - ], - "name": "getRoleMemberCount", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "role", - "type": "bytes32" - }, - { - "internalType": "address", - "name": "account", - "type": "address" - } - ], - "name": "grantRole", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "role", - "type": "bytes32" - }, - { - "internalType": "address", - "name": "account", - "type": "address" - } - ], - "name": "hasRole", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "internalType": "address", - "name": "operator", - "type": "address" - } - ], - "name": "isApprovedForAll", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "lastMintedTokenId", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "to", - "type": "address" - } - ], - "name": "mint", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "name", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - } - ], - "name": "ownerOf", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "pause", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "paused", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "role", - "type": "bytes32" - }, - { - "internalType": "address", - "name": "account", - "type": "address" - } - ], - "name": "renounceRole", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "role", - "type": "bytes32" - }, - { - "internalType": "address", - "name": "account", - "type": "address" - } - ], - "name": "revokeRole", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - } - ], - "name": "safeTransferFrom", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "data", - "type": "bytes" - } - ], - "name": "safeTransferFrom", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "operator", - "type": "address" - }, - { - "internalType": "bool", - "name": "approved", - "type": "bool" - } - ], - "name": "setApprovalForAll", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes4", - "name": "interfaceId", - "type": "bytes4" - } - ], - "name": "supportsInterface", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "symbol", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "index", - "type": "uint256" - } - ], - "name": "tokenByIndex", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "internalType": "uint256", - "name": "index", - "type": "uint256" - } - ], - "name": "tokenOfOwnerByIndex", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - } - ], - "name": "tokenURI", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "totalSupply", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - } - ], - "name": "transferFrom", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "unpause", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - } - ] \ No newline at end of file diff --git a/tests/bytecode/ERC20Mintable.json b/tests/bytecode/ERC20Mintable.json deleted file mode 100644 index c14d2eda6..000000000 --- a/tests/bytecode/ERC20Mintable.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "bytecode": "0x60806040523480156200001157600080fd5b506040516200159538038062001595833981016040819052620000349162000251565b8151829082906200004d906003906020850190620000de565b50805162000063906004906020840190620000de565b505050620000806200007a6200008860201b60201c565b6200008c565b5050620002f8565b3390565b600580546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b828054620000ec90620002bb565b90600052602060002090601f0160209004810192826200011057600085556200015b565b82601f106200012b57805160ff19168380011785556200015b565b828001600101855582156200015b579182015b828111156200015b5782518255916020019190600101906200013e565b50620001699291506200016d565b5090565b5b808211156200016957600081556001016200016e565b634e487b7160e01b600052604160045260246000fd5b600082601f830112620001ac57600080fd5b81516001600160401b0380821115620001c957620001c962000184565b604051601f8301601f19908116603f01168101908282118183101715620001f457620001f462000184565b816040528381526020925086838588010111156200021157600080fd5b600091505b8382101562000235578582018301518183018401529082019062000216565b83821115620002475760008385830101525b9695505050505050565b600080604083850312156200026557600080fd5b82516001600160401b03808211156200027d57600080fd5b6200028b868387016200019a565b93506020850151915080821115620002a257600080fd5b50620002b1858286016200019a565b9150509250929050565b600181811c90821680620002d057607f821691505b60208210811415620002f257634e487b7160e01b600052602260045260246000fd5b50919050565b61128d80620003086000396000f3fe608060405234801561001057600080fd5b506004361061011b5760003560e01c806370a08231116100b25780639dc29fac11610081578063a9059cbb11610066578063a9059cbb14610257578063dd62ed3e1461026a578063f2fde38b146102b057600080fd5b80639dc29fac14610231578063a457c2d71461024457600080fd5b806370a08231146101c3578063715018a6146101f95780638da5cb5b1461020157806395d89b411461022957600080fd5b8063313ce567116100ee578063313ce567146101865780633408e47014610195578063395093511461019b57806340c10f19146101ae57600080fd5b806306fdde0314610120578063095ea7b31461013e57806318160ddd1461016157806323b872dd14610173575b600080fd5b6101286102c3565b604051610135919061104e565b60405180910390f35b61015161014c3660046110ea565b610355565b6040519015158152602001610135565b6002545b604051908152602001610135565b610151610181366004611114565b61036b565b60405160128152602001610135565b46610165565b6101516101a93660046110ea565b610456565b6101c16101bc3660046110ea565b61049f565b005b6101656101d1366004611150565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205490565b6101c161052e565b60055460405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610135565b6101286105bb565b6101c161023f3660046110ea565b6105ca565b6101516102523660046110ea565b610655565b6101516102653660046110ea565b61072d565b610165610278366004611172565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260016020908152604080832093909416825291909152205490565b6101c16102be366004611150565b61073a565b6060600380546102d2906111a5565b80601f01602080910402602001604051908101604052809291908181526020018280546102fe906111a5565b801561034b5780601f106103205761010080835404028352916020019161034b565b820191906000526020600020905b81548152906001019060200180831161032e57829003601f168201915b5050505050905090565b600061036233848461086a565b50600192915050565b6000610378848484610a1e565b73ffffffffffffffffffffffffffffffffffffffff841660009081526001602090815260408083203384529091529020548281101561043e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206160448201527f6c6c6f77616e636500000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b61044b853385840361086a565b506001949350505050565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff87168452909152812054909161036291859061049a908690611228565b61086a565b60055473ffffffffffffffffffffffffffffffffffffffff163314610520576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610435565b61052a8282610cd2565b5050565b60055473ffffffffffffffffffffffffffffffffffffffff1633146105af576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610435565b6105b96000610df2565b565b6060600480546102d2906111a5565b60055473ffffffffffffffffffffffffffffffffffffffff16331461064b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610435565b61052a8282610e69565b33600090815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff8616845290915281205482811015610716576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f0000000000000000000000000000000000000000000000000000006064820152608401610435565b610723338585840361086a565b5060019392505050565b6000610362338484610a1e565b60055473ffffffffffffffffffffffffffffffffffffffff1633146107bb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610435565b73ffffffffffffffffffffffffffffffffffffffff811661085e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610435565b61086781610df2565b50565b73ffffffffffffffffffffffffffffffffffffffff831661090c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152608401610435565b73ffffffffffffffffffffffffffffffffffffffff82166109af576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f73730000000000000000000000000000000000000000000000000000000000006064820152608401610435565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff8316610ac1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f64726573730000000000000000000000000000000000000000000000000000006064820152608401610435565b73ffffffffffffffffffffffffffffffffffffffff8216610b64576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f65737300000000000000000000000000000000000000000000000000000000006064820152608401610435565b73ffffffffffffffffffffffffffffffffffffffff831660009081526020819052604090205481811015610c1a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e636500000000000000000000000000000000000000000000000000006064820152608401610435565b73ffffffffffffffffffffffffffffffffffffffff808516600090815260208190526040808220858503905591851681529081208054849290610c5e908490611228565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051610cc491815260200190565b60405180910390a350505050565b73ffffffffffffffffffffffffffffffffffffffff8216610d4f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610435565b8060026000828254610d619190611228565b909155505073ffffffffffffffffffffffffffffffffffffffff821660009081526020819052604081208054839290610d9b908490611228565b909155505060405181815273ffffffffffffffffffffffffffffffffffffffff8316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b6005805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b73ffffffffffffffffffffffffffffffffffffffff8216610f0c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f73000000000000000000000000000000000000000000000000000000000000006064820152608401610435565b73ffffffffffffffffffffffffffffffffffffffff821660009081526020819052604090205481811015610fc2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f63650000000000000000000000000000000000000000000000000000000000006064820152608401610435565b73ffffffffffffffffffffffffffffffffffffffff83166000908152602081905260408120838303905560028054849290610ffe908490611240565b909155505060405182815260009073ffffffffffffffffffffffffffffffffffffffff8516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602001610a11565b600060208083528351808285015260005b8181101561107b5785810183015185820160400152820161105f565b8181111561108d576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146110e557600080fd5b919050565b600080604083850312156110fd57600080fd5b611106836110c1565b946020939093013593505050565b60008060006060848603121561112957600080fd5b611132846110c1565b9250611140602085016110c1565b9150604084013590509250925092565b60006020828403121561116257600080fd5b61116b826110c1565b9392505050565b6000806040838503121561118557600080fd5b61118e836110c1565b915061119c602084016110c1565b90509250929050565b600181811c908216806111b957607f821691505b602082108114156111f3577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000821982111561123b5761123b6111f9565b500190565b600082821015611252576112526111f9565b50039056fea26469706673582212201439c2b0174e2f59095762092f404c30b65417eddd0e968162c84e524e01459c64736f6c634300080a0033" -} diff --git a/tests/bytecode/ERC721Mintable.json b/tests/bytecode/ERC721Mintable.json deleted file mode 100644 index fdcfa759d..000000000 --- a/tests/bytecode/ERC721Mintable.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "bytecode": "60806040523480156200001157600080fd5b5060405180604001604052806007815260200166135bd8dad3919560ca1b81525060405180604001604052806007815260200166135bd8dad3919560ca1b8152506040518060400160405280601581526020017f68747470733a2f2f6d6f636b2d6e66742e636f6d2f000000000000000000000081525082828160029080519060200190620000a2929190620002e8565b508051620000b8906003906020840190620002e8565b5050600c805460ff19169055508051620000da90600e906020840190620002e8565b50620000e860003362000138565b6200010360008051602062002c738339815191523362000138565b6200012f7f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a3362000138565b505050620003cb565b62000144828262000148565b5050565b6200015f82826200018b60201b62000e9b1760201c565b60008281526001602090815260409091206200018691839062000f1f62000213821b17901c565b505050565b62000197828262000233565b62000144576000828152602081815260408083206001600160a01b03851684529091529020805460ff19166001179055620001cf3390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b60006200022a836001600160a01b0384166200026d565b90505b92915050565b600060008051602062002c7383398151915283141562000256575060016200022d565b6200022a8383620002bf60201b62000f341760201c565b6000818152600183016020526040812054620002b6575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556200022d565b5060006200022d565b6000918252602082815260408084206001600160a01b0393909316845291905290205460ff1690565b828054620002f6906200038e565b90600052602060002090601f0160209004810192826200031a576000855562000365565b82601f106200033557805160ff191683800117855562000365565b8280016001018555821562000365579182015b828111156200036557825182559160200191906001019062000348565b506200037392915062000377565b5090565b5b8082111562000373576000815560010162000378565b600181811c90821680620003a357607f821691505b60208210811415620003c557634e487b7160e01b600052602260045260246000fd5b50919050565b61289880620003db6000396000f3fe608060405234801561001057600080fd5b50600436106101f05760003560e01c80636508b10a1161010f578063a22cb465116100a2578063d539139311610071578063d53913931461040b578063d547741f14610432578063e63ab1e914610445578063e985e9c51461046c57600080fd5b8063a22cb465146103bf578063b88d4fde146103d2578063c87b56dd146103e5578063ca15c873146103f857600080fd5b80639010d07c116100de5780639010d07c1461038957806391d148541461039c57806395d89b41146103af578063a217fddf146103b757600080fd5b80636508b10a146103525780636a6278421461035b57806370a082311461036e5780638456cb591461038157600080fd5b80632f745c591161018757806342966c681161015657806342966c681461030e5780634f6ccce7146103215780635c975abb146103345780636352211e1461033f57600080fd5b80632f745c59146102cd57806336568abe146102e05780633f4ba83a146102f357806342842e0e146102fb57600080fd5b806318160ddd116101c357806318160ddd1461027257806323b872dd14610284578063248a9ca3146102975780632f2ff15d146102ba57600080fd5b806301ffc9a7146101f557806306fdde031461021d578063081812fc14610232578063095ea7b31461025d575b600080fd5b61020861020336600461233a565b6104a8565b60405190151581526020015b60405180910390f35b6102256104b9565b60405161021491906123af565b6102456102403660046123c2565b61054b565b6040516001600160a01b039091168152602001610214565b61027061026b3660046123f7565b610572565b005b600a545b604051908152602001610214565b610270610292366004612421565b6106a9565b6102766102a53660046123c2565b60009081526020819052604090206001015490565b6102706102c836600461245d565b610731565b6102766102db3660046123f7565b610756565b6102706102ee36600461245d565b6107fe565b61027061088a565b610270610309366004612421565b610932565b61027061031c3660046123c2565b61094d565b61027661032f3660046123c2565b6109d4565b600c5460ff16610208565b61024561034d3660046123c2565b610a78565b610276600f5481565b610270610369366004612489565b610add565b61027661037c366004612489565b610b99565b610270610c33565b6102456103973660046124a4565b610cd7565b6102086103aa36600461245d565b610cf6565b610225610d51565b610276600081565b6102706103cd3660046124c6565b610d60565b6102706103e0366004612518565b610d6b565b6102256103f33660046123c2565b610df9565b6102766104063660046123c2565b610e5f565b6102767f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a681565b61027061044036600461245d565b610e76565b6102767f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a81565b61020861047a3660046125f4565b6001600160a01b03918216600090815260076020908152604080832093909416825291909152205460ff1690565b60006104b382610f5d565b92915050565b6060600280546104c89061261e565b80601f01602080910402602001604051908101604052809291908181526020018280546104f49061261e565b80156105415780601f1061051657610100808354040283529160200191610541565b820191906000526020600020905b81548152906001019060200180831161052457829003601f168201915b5050505050905090565b600061055682610f9b565b506000908152600660205260409020546001600160a01b031690565b600061057d82610a78565b9050806001600160a01b0316836001600160a01b0316141561060c5760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560448201527f720000000000000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b336001600160a01b03821614806106285750610628813361047a565b61069a5760405162461bcd60e51b815260206004820152603e60248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60448201527f6b656e206f776e6572206e6f7220617070726f76656420666f7220616c6c00006064820152608401610603565b6106a48383610fff565b505050565b6106b4335b8261107a565b6107265760405162461bcd60e51b815260206004820152602e60248201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560448201527f72206e6f7220617070726f7665640000000000000000000000000000000000006064820152608401610603565b6106a48383836110f9565b60008281526020819052604090206001015461074c816112de565b6106a483836112e8565b600061076183610b99565b82106107d55760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201527f74206f6620626f756e64730000000000000000000000000000000000000000006064820152608401610603565b506001600160a01b03919091166000908152600860209081526040808320938352929052205490565b6001600160a01b038116331461087c5760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201527f20726f6c657320666f722073656c6600000000000000000000000000000000006064820152608401610603565b610886828261130a565b5050565b6108b47f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a33610cf6565b610928576040805162461bcd60e51b81526020600482015260248101919091527f4552433732315072657365744d696e7465725061757365724175746f49643a2060448201527f6d75737420686176652070617573657220726f6c6520746f20756e70617573656064820152608401610603565b61093061132c565b565b6106a483838360405180602001604052806000815250610d6b565b610956336106ae565b6109c85760405162461bcd60e51b815260206004820152602e60248201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560448201527f72206e6f7220617070726f7665640000000000000000000000000000000000006064820152608401610603565b6109d18161137e565b50565b60006109df600a5490565b8210610a535760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201527f7574206f6620626f756e647300000000000000000000000000000000000000006064820152608401610603565b600a8281548110610a6657610a66612659565b90600052602060002001549050919050565b6000818152600460205260408120546001600160a01b0316806104b35760405162461bcd60e51b815260206004820152601860248201527f4552433732313a20696e76616c696420746f6b656e20494400000000000000006044820152606401610603565b610b077f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a633610cf6565b610b795760405162461bcd60e51b815260206004820152603d60248201527f4552433732315072657365744d696e7465725061757365724175746f49643a2060448201527f6d7573742068617665206d696e74657220726f6c6520746f206d696e740000006064820152608401610603565b610b8b81610b86600d5490565b611432565b6109d1600d80546001019055565b60006001600160a01b038216610c175760405162461bcd60e51b815260206004820152602960248201527f4552433732313a2061646472657373207a65726f206973206e6f74206120766160448201527f6c6964206f776e657200000000000000000000000000000000000000000000006064820152608401610603565b506001600160a01b031660009081526005602052604090205490565b610c5d7f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a33610cf6565b610ccf5760405162461bcd60e51b815260206004820152603e60248201527f4552433732315072657365744d696e7465725061757365724175746f49643a2060448201527f6d75737420686176652070617573657220726f6c6520746f20706175736500006064820152608401610603565b610930611442565b6000828152600160205260408120610cef908361147f565b9392505050565b60007f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a6831415610d28575060016104b3565b6000838152602081815260408083206001600160a01b038616845290915290205460ff16610cef565b6060600380546104c89061261e565b61088633838361148b565b610d75338361107a565b610de75760405162461bcd60e51b815260206004820152602e60248201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560448201527f72206e6f7220617070726f7665640000000000000000000000000000000000006064820152608401610603565b610df38484848461155a565b50505050565b6060610e0482610f9b565b6000610e0e6115e3565b90506000815111610e2e5760405180602001604052806000815250610cef565b80610e38846115f2565b604051602001610e4992919061266f565b6040516020818303038152906040529392505050565b60008181526001602052604081206104b390611724565b600082815260208190526040902060010154610e91816112de565b6106a4838361130a565b610ea58282610cf6565b610886576000828152602081815260408083206001600160a01b03851684529091529020805460ff19166001179055610edb3390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6000610cef836001600160a01b03841661172e565b6000918252602082815260408084206001600160a01b0393909316845291905290205460ff1690565b60006001600160e01b031982167f780e9d630000000000000000000000000000000000000000000000000000000014806104b357506104b38261177d565b6000818152600460205260409020546001600160a01b03166109d15760405162461bcd60e51b815260206004820152601860248201527f4552433732313a20696e76616c696420746f6b656e20494400000000000000006044820152606401610603565b6000818152600660205260409020805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b038416908117909155819061104182610a78565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b60008061108683610a78565b9050806001600160a01b0316846001600160a01b031614806110cd57506001600160a01b0380821660009081526007602090815260408083209388168352929052205460ff165b806110f15750836001600160a01b03166110e68461054b565b6001600160a01b0316145b949350505050565b826001600160a01b031661110c82610a78565b6001600160a01b0316146111885760405162461bcd60e51b815260206004820152602560248201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060448201527f6f776e65720000000000000000000000000000000000000000000000000000006064820152608401610603565b6001600160a01b0382166112035760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152608401610603565b61120e8383836117ef565b611219600082610fff565b6001600160a01b03831660009081526005602052604081208054600192906112429084906126b4565b90915550506001600160a01b03821660009081526005602052604081208054600192906112709084906126cb565b9091555050600081815260046020526040808220805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b6109d181336117fa565b6112f28282610e9b565b60008281526001602052604090206106a49082610f1f565b611314828261185e565b60008281526001602052604090206106a490826118c3565b6113346118d8565b600c805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b600061138982610a78565b9050611397816000846117ef565b6113a2600083610fff565b6001600160a01b03811660009081526005602052604081208054600192906113cb9084906126b4565b9091555050600082815260046020526040808220805473ffffffffffffffffffffffffffffffffffffffff19169055518391906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b61143c828261192a565b600f5550565b61144a611a85565b600c805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586113613390565b6000610cef8383611ad8565b816001600160a01b0316836001600160a01b031614156114ed5760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610603565b6001600160a01b03838116600081815260076020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b6115658484846110f9565b61157184848484611b02565b610df35760405162461bcd60e51b815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527f63656976657220696d706c656d656e74657200000000000000000000000000006064820152608401610603565b6060600e80546104c89061261e565b60608161163257505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b811561165c5780611646816126e3565b91506116559050600a83612714565b9150611636565b60008167ffffffffffffffff81111561167757611677612502565b6040519080825280601f01601f1916602001820160405280156116a1576020820181803683370190505b5090505b84156110f1576116b66001836126b4565b91506116c3600a86612728565b6116ce9060306126cb565b60f81b8183815181106116e3576116e3612659565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535061171d600a86612714565b94506116a5565b60006104b3825490565b6000818152600183016020526040812054611775575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556104b3565b5060006104b3565b60006001600160e01b031982167f80ac58cd0000000000000000000000000000000000000000000000000000000014806117e057506001600160e01b031982167f5b5e139f00000000000000000000000000000000000000000000000000000000145b806104b357506104b382611c97565b6106a4838383611cd5565b6118048282610cf6565b6108865761181c816001600160a01b03166014611d59565b611827836020611d59565b60405160200161183892919061273c565b60408051601f198184030181529082905262461bcd60e51b8252610603916004016123af565b6118688282610cf6565b15610886576000828152602081815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b6000610cef836001600160a01b038416611f82565b600c5460ff166109305760405162461bcd60e51b815260206004820152601460248201527f5061757361626c653a206e6f74207061757365640000000000000000000000006044820152606401610603565b6001600160a01b0382166119805760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610603565b6000818152600460205260409020546001600160a01b0316156119e55760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610603565b6119f1600083836117ef565b6001600160a01b0382166000908152600560205260408120805460019290611a1a9084906126cb565b9091555050600081815260046020526040808220805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b600c5460ff16156109305760405162461bcd60e51b815260206004820152601060248201527f5061757361626c653a20706175736564000000000000000000000000000000006044820152606401610603565b6000826000018281548110611aef57611aef612659565b9060005260206000200154905092915050565b60006001600160a01b0384163b15611c8c576040517f150b7a020000000000000000000000000000000000000000000000000000000081526001600160a01b0385169063150b7a0290611b5f9033908990889088906004016127bd565b602060405180830381600087803b158015611b7957600080fd5b505af1925050508015611ba9575060408051601f3d908101601f19168201909252611ba6918101906127f9565b60015b611c59573d808015611bd7576040519150601f19603f3d011682016040523d82523d6000602084013e611bdc565b606091505b508051611c515760405162461bcd60e51b815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527f63656976657220696d706c656d656e74657200000000000000000000000000006064820152608401610603565b805181602001fd5b6001600160e01b0319167f150b7a02000000000000000000000000000000000000000000000000000000001490506110f1565b506001949350505050565b60006001600160e01b031982167f5a05180f0000000000000000000000000000000000000000000000000000000014806104b357506104b382612075565b611ce08383836120dc565b600c5460ff16156106a45760405162461bcd60e51b815260206004820152602b60248201527f4552433732315061757361626c653a20746f6b656e207472616e73666572207760448201527f68696c65207061757365640000000000000000000000000000000000000000006064820152608401610603565b60606000611d68836002612816565b611d739060026126cb565b67ffffffffffffffff811115611d8b57611d8b612502565b6040519080825280601f01601f191660200182016040528015611db5576020820181803683370190505b5090507f300000000000000000000000000000000000000000000000000000000000000081600081518110611dec57611dec612659565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f780000000000000000000000000000000000000000000000000000000000000081600181518110611e4f57611e4f612659565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506000611e8b846002612816565b611e969060016126cb565b90505b6001811115611f33577f303132333435363738396162636465660000000000000000000000000000000085600f1660108110611ed757611ed7612659565b1a60f81b828281518110611eed57611eed612659565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060049490941c93611f2c81612835565b9050611e99565b508315610cef5760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610603565b6000818152600183016020526040812054801561206b576000611fa66001836126b4565b8554909150600090611fba906001906126b4565b905081811461201f576000866000018281548110611fda57611fda612659565b9060005260206000200154905080876000018481548110611ffd57611ffd612659565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806120305761203061284c565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506104b3565b60009150506104b3565b60006001600160e01b031982167f7965db0b0000000000000000000000000000000000000000000000000000000014806104b357507f01ffc9a7000000000000000000000000000000000000000000000000000000006001600160e01b03198316146104b3565b6001600160a01b0383166121375761213281600a80546000838152600b60205260408120829055600182018355919091527fc65a7bb8d6351c1cf70c95a316cc6a92839c986682d98bc35f958f4883f9d2a80155565b61215a565b816001600160a01b0316836001600160a01b03161461215a5761215a8382612194565b6001600160a01b038216612171576106a481612231565b826001600160a01b0316826001600160a01b0316146106a4576106a482826122e0565b600060016121a184610b99565b6121ab91906126b4565b6000838152600960205260409020549091508082146121fe576001600160a01b03841660009081526008602090815260408083208584528252808320548484528184208190558352600990915290208190555b5060009182526009602090815260408084208490556001600160a01b039094168352600881528383209183525290812055565b600a54600090612243906001906126b4565b6000838152600b6020526040812054600a805493945090928490811061226b5761226b612659565b9060005260206000200154905080600a838154811061228c5761228c612659565b6000918252602080832090910192909255828152600b9091526040808220849055858252812055600a8054806122c4576122c461284c565b6001900381819060005260206000200160009055905550505050565b60006122eb83610b99565b6001600160a01b039093166000908152600860209081526040808320868452825280832085905593825260099052919091209190915550565b6001600160e01b0319811681146109d157600080fd5b60006020828403121561234c57600080fd5b8135610cef81612324565b60005b8381101561237257818101518382015260200161235a565b83811115610df35750506000910152565b6000815180845261239b816020860160208601612357565b601f01601f19169290920160200192915050565b602081526000610cef6020830184612383565b6000602082840312156123d457600080fd5b5035919050565b80356001600160a01b03811681146123f257600080fd5b919050565b6000806040838503121561240a57600080fd5b612413836123db565b946020939093013593505050565b60008060006060848603121561243657600080fd5b61243f846123db565b925061244d602085016123db565b9150604084013590509250925092565b6000806040838503121561247057600080fd5b82359150612480602084016123db565b90509250929050565b60006020828403121561249b57600080fd5b610cef826123db565b600080604083850312156124b757600080fd5b50508035926020909101359150565b600080604083850312156124d957600080fd5b6124e2836123db565b9150602083013580151581146124f757600080fd5b809150509250929050565b634e487b7160e01b600052604160045260246000fd5b6000806000806080858703121561252e57600080fd5b612537856123db565b9350612545602086016123db565b925060408501359150606085013567ffffffffffffffff8082111561256957600080fd5b818701915087601f83011261257d57600080fd5b81358181111561258f5761258f612502565b604051601f8201601f19908116603f011681019083821181831017156125b7576125b7612502565b816040528281528a60208487010111156125d057600080fd5b82602086016020830137600060208483010152809550505050505092959194509250565b6000806040838503121561260757600080fd5b612610836123db565b9150612480602084016123db565b600181811c9082168061263257607f821691505b6020821081141561265357634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052603260045260246000fd5b60008351612681818460208801612357565b835190830190612695818360208801612357565b01949350505050565b634e487b7160e01b600052601160045260246000fd5b6000828210156126c6576126c661269e565b500390565b600082198211156126de576126de61269e565b500190565b60006000198214156126f7576126f761269e565b5060010190565b634e487b7160e01b600052601260045260246000fd5b600082612723576127236126fe565b500490565b600082612737576127376126fe565b500690565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000815260008351612774816017850160208801612357565b7f206973206d697373696e6720726f6c652000000000000000000000000000000060179184019182015283516127b1816028840160208801612357565b01602801949350505050565b60006001600160a01b038087168352808616602084015250836040830152608060608301526127ef6080830184612383565b9695505050505050565b60006020828403121561280b57600080fd5b8151610cef81612324565b60008160001904831182151516156128305761283061269e565b500290565b6000816128445761284461269e565b506000190190565b634e487b7160e01b600052603160045260246000fdfea2646970667358221220f351d36c33202224bf232d4ac4e744c08038a910932e1c7c32285aa888f7767464736f6c634300080900339f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a6" -} \ No newline at end of file diff --git a/tests/delta.test.ts b/tests/delta.test.ts index 101328a6d..bd7a7b8f2 100644 --- a/tests/delta.test.ts +++ b/tests/delta.test.ts @@ -234,22 +234,6 @@ describe('Delta:methods', () => { expect(staticDeltaPrice).toMatchSnapshot(); }); - test('breaks for srcToken=ETH', async () => { - const getDeltaPrice = () => - deltaSDK.getDeltaPrice({ - srcToken: ETH_ADDRESS, - destToken: destToken, - amount: srcAmount, - userAddress: senderAddress, - srcDecimals: 18, - destDecimals: 18, - }); - - await expect(getDeltaPrice()).rejects.toThrowErrorMatchingInlineSnapshot( - `"SourceEth: ETH as source token is not supported"` - ); - }); - describe('Get Delta Price Crosschain', () => { const destChainId = 10; const ETH = '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE'; @@ -563,6 +547,109 @@ describe('Delta:methods', () => { expect(staticSignableOrderData).toMatchSnapshot(); }); + test('Build Delta Order with slippage (SELL)', async () => { + const sampleDeltaPrice: DeltaPrice = { + destAmount: '3163263721766488892666', + destAmountBeforeFee: '3194635547945152526200', + receivedDestAmount: '3163263721766488892666', + destToken: '0x6b175474e89094c44da98b954eedeac495271d0f', + destUSD: '3166.4269854931', + receivedDestUSD: '3166.4269854931', + destUSDBeforeFee: '3197.8301834931', + gasCost: '347788', + gasCostBeforeFee: '124240', + gasCostUSD: '31.403198', + gasCostUSDBeforeFee: '11.218137', + partner: 'anon', + partnerFee: 0, + srcAmount: '1000000000000000000', + srcToken: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', + srcUSD: '3191.5500000000', + hmac: '1234aeb', + bridge: { + protocolSelector: '0x00000000', + destinationChainId: 0, + outputToken: ZERO_ADDRESS, + scalingFactor: 0, + protocolData: '0x', + }, + }; + + const slippageBps = 50; // 50 bps = 0.5% + const BPS_BASE = BigInt(10_000); + const expectedDestAmount = ( + (BigInt(sampleDeltaPrice.destAmount) * (BPS_BASE - BigInt(slippageBps))) / + BPS_BASE + ).toString(10); + + const amount = '1000000000000000000'; + + const signableOrderData = await deltaSDK.buildDeltaOrder({ + deltaPrice: sampleDeltaPrice, + owner: senderAddress, + srcToken: WETH, + destToken: DAI, + srcAmount: amount, + slippage: slippageBps, + partnerAddress: ZERO_ADDRESS, + }); + + expect(signableOrderData.data.srcAmount).toEqual(amount); + expect(signableOrderData.data.destAmount).toEqual(expectedDestAmount); + }); + + test('Build Delta Order with slippage (BUY)', async () => { + const sampleDeltaPrice: DeltaPrice = { + destAmount: '3163263721766488892666', + destAmountBeforeFee: '3194635547945152526200', + receivedDestAmount: '3163263721766488892666', + destToken: '0x6b175474e89094c44da98b954eedeac495271d0f', + destUSD: '3166.4269854931', + receivedDestUSD: '3166.4269854931', + destUSDBeforeFee: '3197.8301834931', + gasCost: '347788', + gasCostBeforeFee: '124240', + gasCostUSD: '31.403198', + gasCostUSDBeforeFee: '11.218137', + partner: 'anon', + partnerFee: 0, + srcAmount: '1000000000000000000', + srcToken: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', + srcUSD: '3191.5500000000', + hmac: '1234aeb', + bridge: { + protocolSelector: '0x00000000', + destinationChainId: 0, + outputToken: ZERO_ADDRESS, + scalingFactor: 0, + protocolData: '0x', + }, + }; + + const slippageBps = 50; // 50 bps = 0.5% + const destAmount = '3163263721766488892666'; + + const BPS_BASE = BigInt(10_000); + const expectedSrcAmount = ( + (BigInt(sampleDeltaPrice.srcAmount) * (BPS_BASE + BigInt(slippageBps))) / + BPS_BASE + ).toString(10); + + const signableOrderData = await deltaSDK.buildDeltaOrder({ + deltaPrice: sampleDeltaPrice, + owner: senderAddress, + srcToken: WETH, + destToken: DAI, + destAmount, + slippage: slippageBps, + side: 'BUY', + partnerAddress: ZERO_ADDRESS, + }); + + expect(signableOrderData.data.destAmount).toEqual(destAmount); + expect(signableOrderData.data.srcAmount).toEqual(expectedSrcAmount); + }); + let signature = ''; test.each([ @@ -799,7 +886,7 @@ describe('Delta:methods', () => { expect(mockFetch).toHaveBeenLastCalledWith({ data: { ...input, chainId: dummySDK.chainId }, method: 'POST', - url: `${dummySDK.apiURL}/delta/orders`, + url: `${dummySDK.apiURL}/delta/orders/`, }); }); diff --git a/tests/helpers/index.ts b/tests/helpers/index.ts deleted file mode 100644 index efdeee82b..000000000 --- a/tests/helpers/index.ts +++ /dev/null @@ -1,98 +0,0 @@ -import BigNumber from 'bignumber.js'; -import { ethers } from 'ethersV5'; -import { SwapSide } from '@paraswap/core'; -import { - constructSimpleSDK, - FetcherOptions, - ProviderOptions, -} from '../../src/sdk/simple'; -import erc20abi from '../abi/ERC20.json'; - -const ETH = '0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee'; -const referrer = 'sdk-test'; - -type BuyErc20TokenForEthInput = { - fetcherOptions: FetcherOptions; - providerOptions: ProviderOptions; - amount: string; - tokenAddress: string; - signer: ethers.Wallet; - chainId: number; - ethersProvider: ethers.providers.JsonRpcProvider; - srcDecimals?: number; - destDecimals?: number; -}; - -type BuyErc20TokenForEthReturn = { - balance: string; -}; -export async function buyErc20TokenForEth({ - fetcherOptions, - providerOptions, - tokenAddress, - amount, - signer, - chainId, - ethersProvider, - srcDecimals = 18, - destDecimals = 18, -}: BuyErc20TokenForEthInput): Promise { - const _sdk = constructSimpleSDK( - { chainId, ...fetcherOptions }, - providerOptions - ); - - const priceRoute = await _sdk.swap.getRate({ - srcDecimals, - destDecimals, - srcToken: ETH, - destToken: tokenAddress, - amount, - userAddress: signer.address, - side: SwapSide.BUY, - }); - - const srcAmount = new BigNumber(priceRoute.srcAmount).times(1.1).toFixed(0); - - const txParams = await _sdk.swap.buildTx( - { - srcDecimals, - destDecimals, - srcToken: ETH, - srcAmount, - destToken: tokenAddress, - destAmount: amount, - priceRoute, - userAddress: signer.address, - partner: referrer, - }, - { ignoreChecks: true } - ); - - const transaction = { - ...txParams, - gasPrice: - txParams.gasPrice && '0x' + new BigNumber(txParams.gasPrice).toString(16), - maxFeePerGas: - txParams.maxFeePerGas && - '0x' + new BigNumber(txParams.maxFeePerGas).toString(16), - maxPriorityFeePerGas: - txParams.maxPriorityFeePerGas && - '0x' + new BigNumber(txParams.maxPriorityFeePerGas).toString(16), - gasLimit: '0x' + new BigNumber(5000000).toString(16), - value: '0x' + new BigNumber(txParams.value).toString(16), - }; - - const toContract = new ethers.Contract( - tokenAddress, - erc20abi, - ethersProvider - ); - - const txr = await signer.sendTransaction(transaction); - await txr.wait(1); - - const afterBalance = await toContract.balanceOf(signer.address); - - return { balance: afterBalance.toString() }; -} diff --git a/tests/limitOrders.test.ts b/tests/limitOrders.test.ts deleted file mode 100644 index 76e036a1c..000000000 --- a/tests/limitOrders.test.ts +++ /dev/null @@ -1,2084 +0,0 @@ -import * as dotenv from 'dotenv'; -import Web3 from 'web3'; -import type { TransactionReceipt as Web3TransactionReceipt } from 'web3'; -import { BigNumber as BigNumberEthers, Contract, ethers } from 'ethersV5'; -import { ethers as ethersV6 } from 'ethers'; -import { hexValue, hexZeroPad } from '@ethersproject/bytes'; -import axios from 'axios'; -import { - constructPartialSDK, - constructBuildLimitOrder, - BuildLimitOrderFunctions, - constructSignLimitOrder, - SignLimitOrderFunctions, - constructCancelLimitOrder, - CancelLimitOrderFunctions, - constructEthersV5ContractCaller, - constructEthersV6ContractCaller, - SDKConfig, - ConstructProviderFetchInput, - constructAxiosFetcher, - ApproveTokenForLimitOrderFunctions, - constructApproveTokenForLimitOrder, - constructGetLimitOrdersContract, - GetLimitOrdersContractFunctions, - SignableOrderData, - constructPostLimitOrder, - PostLimitOrderFunctions, - LimitOrderToSend, - GetLimitOrdersFunctions, - constructGetLimitOrders, - Web3UnpromiEvent, - constructWeb3ContractCaller, - GetSpenderFunctions, - constructGetSpender, - BuildLimitOrdersTxFunctions, - constructBuildLimitOrderTx, - BuildTxFunctions, - constructBuildTx, - constructFillOrderDirectly, -} from '../src'; -import BigNumber from 'bignumber.js'; - -import ERC20MinableABI from './abi/ERC20Mintable.json'; -import { bytecode as ERC20MintableBytecode } from './bytecode/ERC20Mintable.json'; -import AugustusRFQAbi from './abi/AugustusRFQ.json'; -import { bytecode as AugustusRFQBytecode } from './bytecode/AugustusRFQ.json'; - -import type { BuildLimitOrderInput } from '../src/methods/limitOrders/buildOrder'; -import { assert } from 'ts-essentials'; -import { ZERO_ADDRESS } from '../src/methods/common/orders/buildOrderData'; -import { buyErc20TokenForEth } from './helpers'; -import { HardhatProvider, setupFork } from './helpers/hardhat'; - -dotenv.config(); - -jest.setTimeout(30 * 1000); - -const referrer = 'sdk-test'; - -const DAI = '0x6b175474e89094c44da98b954eedeac495271d0f'; -const HEX = '0x2b591e99afe9f32eaa6214f7b7629768c40eeb39'; -const WETH = '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2'; -const BAT = '0x0d8775f648430679a709e98d2b0cb6250d2887ef'; -const USDC = '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48'; - -// const DUMMY_ADDRESS_FOR_TESTING_ORDERS = -// '0xb9A079479A7b0F4E7F398F7ED3946bE6d9a40E79'; - -const chainId = 1; - -const srcToken = DAI; -const destToken = HEX; - -const TEST_MNEMONIC = - 'radar blur cabbage chef fix engine embark joy scheme fiction master release'; -//0xaC39b311DCEb2A4b2f5d8461c1cdaF756F4F7Ae9 -const walletV5Stable = ethers.Wallet.fromMnemonic(TEST_MNEMONIC); -//0xD7c0Cd9e7d2701c710D64Fc492C7086679BdF7b4 -const walletV5Stable2 = ethers.Wallet.fromMnemonic( - TEST_MNEMONIC, - "m/44'/60'/0'/0/1" -); - -// if test against tenderly fork, make sure accounts have enough ETH and zero nonce -const tenderlyForkUrl = process.env.TENDERLY_FORK_URL; -const ethersV5Provider = tenderlyForkUrl - ? new ethers.providers.JsonRpcProvider(tenderlyForkUrl) - : new ethers.providers.Web3Provider(HardhatProvider as any); - -const signerV5 = walletV5Stable.connect(ethersV5Provider); -const senderAddress = signerV5.address; - -const maker = signerV5; -const takerV5 = walletV5Stable2.connect(ethersV5Provider); - -const walletV6Stable = ethersV6.HDNodeWallet.fromPhrase(TEST_MNEMONIC); -const walletV6Stable2 = ethersV6.HDNodeWallet.fromPhrase( - TEST_MNEMONIC, - undefined, - "m/44'/60'/0'/0/1" -); - -const ethersV6Provider = new ethersV6.BrowserProvider(HardhatProvider); - -const signerV6 = walletV6Stable.connect(ethersV6Provider); -const takerV6 = walletV6Stable2.connect(ethersV6Provider); - -const axiosFetcher = constructAxiosFetcher(axios); - -const ethersV5ContractCaller = constructEthersV5ContractCaller( - { - ethersProviderOrSigner: signerV5, - EthersContract: ethers.Contract, - }, - senderAddress -); -const takerEthersV5ContractCaller = constructEthersV5ContractCaller( - { - ethersProviderOrSigner: takerV5, - EthersContract: ethers.Contract, - }, - walletV5Stable2.address -); - -const ethersV6ContractCaller = constructEthersV6ContractCaller( - { - ethersV6ProviderOrSigner: signerV6, - EthersV6Contract: ethersV6.Contract, - }, - senderAddress -); -const takerEthersV6ContractCaller = constructEthersV6ContractCaller( - { - ethersV6ProviderOrSigner: takerV6, - EthersV6Contract: ethersV6.Contract, - }, - walletV6Stable2.address -); - -const web3provider = new Web3(HardhatProvider as any); - -const web3ContractCaller = constructWeb3ContractCaller( - web3provider, - senderAddress -); -const takerWeb3ContractCaller = constructWeb3ContractCaller( - web3provider, - walletV5Stable2.address -); - -const ERC20MintableFactory = new ethers.ContractFactory( - ERC20MinableABI, - ERC20MintableBytecode, - signerV5 -); - -const AugustusRFQFactory = new ethers.ContractFactory( - AugustusRFQAbi, - AugustusRFQBytecode, - signerV5 -); - -const expectTxParamsScheme = expect.objectContaining({ - from: expect.any(String), - to: expect.any(String), - value: expect.any(String), - data: expect.any(String), - gasPrice: expect.any(String), - chainId: expect.any(Number), -}); - -describe('Limit Orders', () => { - let sdk: BuildLimitOrderFunctions & - SignLimitOrderFunctions & - GetLimitOrdersContractFunctions & - PostLimitOrderFunctions & - GetLimitOrdersFunctions & - CancelLimitOrderFunctions & - ApproveTokenForLimitOrderFunctions & - GetSpenderFunctions & - BuildLimitOrdersTxFunctions & - BuildTxFunctions; - - type MinEthersV5SDK = BuildLimitOrderFunctions & - SignLimitOrderFunctions & - CancelLimitOrderFunctions & - ApproveTokenForLimitOrderFunctions; - type MinTakerEthersV5SDK = BuildLimitOrdersTxFunctions & - ApproveTokenForLimitOrderFunctions; - - type MinEthersV6SDK = BuildLimitOrderFunctions & - SignLimitOrderFunctions & - CancelLimitOrderFunctions & - ApproveTokenForLimitOrderFunctions; - type MinTakerEthersV6SDK = BuildLimitOrdersTxFunctions & - ApproveTokenForLimitOrderFunctions; - - type MinWeb3SDK = BuildLimitOrderFunctions & - SignLimitOrderFunctions & - CancelLimitOrderFunctions & - ApproveTokenForLimitOrderFunctions; - type MinTakerWeb3SDK = ApproveTokenForLimitOrderFunctions; - - type EthersV5CancelOrderConstructor = ( - options: ConstructProviderFetchInput< - ethers.ContractTransaction, - 'transactCall' - > - ) => CancelLimitOrderFunctions; - type EthersV5ApproveTokenForLimitOrderConstructor = ( - options: ConstructProviderFetchInput< - ethers.ContractTransaction, - 'transactCall' - > - ) => ApproveTokenForLimitOrderFunctions; - - type EthersV6CancelOrderConstructor = ( - options: ConstructProviderFetchInput< - ethersV6.ContractTransactionResponse, - 'transactCall' - > - ) => CancelLimitOrderFunctions; - type EthersV6ApproveTokenForLimitOrderConstructor = ( - options: ConstructProviderFetchInput< - ethersV6.ContractTransactionResponse, - 'transactCall' - > - ) => ApproveTokenForLimitOrderFunctions; - - type Web3CancelOrderConstructor = ( - options: ConstructProviderFetchInput - ) => CancelLimitOrderFunctions; - type Web3ApproveTokenForLimitOrderConstructor = ( - options: ConstructProviderFetchInput - ) => ApproveTokenForLimitOrderFunctions; - - const ethersV5SDK: MinEthersV5SDK = constructPartialSDK< - SDKConfig, - [ - typeof constructBuildLimitOrder, - typeof constructSignLimitOrder, - EthersV5CancelOrderConstructor, - EthersV5ApproveTokenForLimitOrderConstructor - ] - >( - { - chainId, - contractCaller: ethersV5ContractCaller, - fetcher: axiosFetcher, - apiURL: process.env.API_URL, - version: '5', - }, - constructBuildLimitOrder, - constructSignLimitOrder, - constructCancelLimitOrder, - constructApproveTokenForLimitOrder - ); - - const takerEthersV5SDK: MinTakerEthersV5SDK = constructPartialSDK< - SDKConfig, - [ - EthersV5ApproveTokenForLimitOrderConstructor, - typeof constructBuildLimitOrderTx - ] - >( - { - chainId, - contractCaller: takerEthersV5ContractCaller, - fetcher: axiosFetcher, - apiURL: process.env.API_URL, - version: '5', - }, - constructApproveTokenForLimitOrder, - constructBuildLimitOrderTx - ); - - const ethersV6SDK: MinEthersV6SDK = constructPartialSDK< - SDKConfig, - [ - typeof constructBuildLimitOrder, - typeof constructSignLimitOrder, - EthersV6CancelOrderConstructor, - EthersV6ApproveTokenForLimitOrderConstructor - ] - >( - { - chainId, - contractCaller: ethersV6ContractCaller, - fetcher: axiosFetcher, - apiURL: process.env.API_URL, - version: '5', - }, - constructBuildLimitOrder, - constructSignLimitOrder, - constructCancelLimitOrder, - constructApproveTokenForLimitOrder - ); - - const takerEthersV6SDK: MinTakerEthersV6SDK = constructPartialSDK< - SDKConfig, - [ - EthersV6ApproveTokenForLimitOrderConstructor, - typeof constructBuildLimitOrderTx - ] - >( - { - chainId, - contractCaller: takerEthersV6ContractCaller, - fetcher: axiosFetcher, - apiURL: process.env.API_URL, - version: '5', - }, - constructApproveTokenForLimitOrder, - constructBuildLimitOrderTx - ); - - const web3SDK: MinWeb3SDK = constructPartialSDK< - SDKConfig, - [ - typeof constructBuildLimitOrder, - typeof constructSignLimitOrder, - Web3CancelOrderConstructor, - Web3ApproveTokenForLimitOrderConstructor - ] - >( - { - chainId, - contractCaller: web3ContractCaller, - fetcher: axiosFetcher, - apiURL: process.env.API_URL, - version: '5', - }, - constructBuildLimitOrder, - constructSignLimitOrder, - constructCancelLimitOrder, - constructApproveTokenForLimitOrder - ); - - const takerWeb3SDK: MinTakerWeb3SDK = constructPartialSDK< - SDKConfig, - [Web3ApproveTokenForLimitOrderConstructor] - >( - { - chainId, - contractCaller: takerWeb3ContractCaller, - fetcher: axiosFetcher, - apiURL: process.env.API_URL, - version: '5', - }, - - constructApproveTokenForLimitOrder - ); - - const txSDKs = [ - { lib: 'ethersV5', sdk: ethersV5SDK, takerSDK: takerEthersV5SDK }, - { lib: 'ethersV6', sdk: ethersV6SDK, takerSDK: takerEthersV6SDK }, - { lib: 'web3', sdk: web3SDK, takerSDK: takerWeb3SDK }, - ] as const; - - let orderInput: BuildLimitOrderInput; - // UTC format - const orderExpiry = Math.floor(new Date('2025-12-20').getTime() / 1000); - - let AugustusRFQ: Contract; - - // let initialChainId2verifyingContract = { ...chainId2verifyingContract }; - - beforeAll(async () => { - await setupFork({ - accounts: [ - { balance: 80e18, address: walletV5Stable.address }, - { balance: 80e18, address: walletV5Stable2.address }, - ], - }); - - orderInput = { - nonce: 1, - expiry: orderExpiry, - makerAsset: srcToken, - takerAsset: destToken, - makerAmount: (1e18).toString(10), - takerAmount: (8e18).toString(10), - maker: senderAddress, - }; - - sdk = constructPartialSDK< - SDKConfig, - [ - typeof constructBuildLimitOrder, - typeof constructSignLimitOrder, - typeof constructGetLimitOrdersContract, - typeof constructPostLimitOrder, - typeof constructGetLimitOrders, - EthersV5CancelOrderConstructor, - EthersV5ApproveTokenForLimitOrderConstructor, - typeof constructGetSpender, - typeof constructBuildLimitOrderTx, - typeof constructBuildTx - ] - >( - { - chainId, - contractCaller: ethersV5ContractCaller, - fetcher: axiosFetcher, - apiURL: process.env.API_URL, - version: '5', - }, - constructBuildLimitOrder, - constructSignLimitOrder, - constructGetLimitOrdersContract, - constructPostLimitOrder, - constructGetLimitOrders, - constructCancelLimitOrder, - constructApproveTokenForLimitOrder, - constructGetSpender, - constructBuildLimitOrderTx, - constructBuildTx - ); - - AugustusRFQ = AugustusRFQFactory.attach(await sdk.getLimitOrdersContract()); - // AugustusRFQ = await AugustusRFQFactory.deploy(); - // await AugustusRFQ.deployTransaction.wait(); - }); - - // takes care of `there are asynchronous operations that weren't stopped in your tests` - // @TODO check if still needed after there are tx tests - // afterAll(async () => { - // Object.assign(chainId2verifyingContract, initialChainId2verifyingContract); - // }); - - test('getLimitOrdersContract', async () => { - const augustusRFQAddress = await sdk.getLimitOrdersContract(); - - expect(augustusRFQAddress).toMatchInlineSnapshot( - `"0xe92b586627ccA7a83dC919cc7127196d70f55a06"` - ); - }); - - test('buildLimitOrder', async () => { - const signableOrderData = await sdk.buildLimitOrder(orderInput); - - // taker address that would be checked as part of nonceAndMeta in Augustus - const takerFromMeta = deriveTakerFromNonceAndTaker( - signableOrderData.data.nonceAndMeta - ); - - // taker in nonceAndTaker = Zero - expect(takerFromMeta).toBe(ZERO_ADDRESS); - - // not P2P order? taker = Zero - expect(signableOrderData.data.taker.toLowerCase()).toBe(ZERO_ADDRESS); - - expect(signableOrderData.data.maker).toBe(senderAddress); - expect(signableOrderData.data.expiry).toBe(orderExpiry); - - expect(signableOrderData).toMatchSnapshot('Order_Data_Snapshot'); - }); - - test('buildLimitOrder p2p', async () => { - const p2pOrderInput = { - ...orderInput, - taker: takerV5.address, - }; - const signableOrderData = await sdk.buildLimitOrder({ - ...orderInput, - taker: takerV5.address, - }); - - // taker address that would be checked as part of nonceAndMeta in Augustus - const metaAddress = deriveTakerFromNonceAndTaker( - signableOrderData.data.nonceAndMeta - ); - - // taker in nonceAndTaker = p2pOrderInput.taker - expect(metaAddress.toLowerCase()).toBe(p2pOrderInput.taker.toLowerCase()); - - const AugustusAddress = await sdk.getAugustusSwapper(); - // taker in AugustusRFQ = Augustus - expect(signableOrderData.data.taker.toLowerCase()).toBe( - AugustusAddress.toLowerCase() - ); - - expect(signableOrderData.data.maker).toBe(senderAddress); - expect(signableOrderData.data.expiry).toBe(orderExpiry); - - expect(signableOrderData).toMatchSnapshot('P2P_Order_Data_Snapshot'); - }); - - test('Build_LO_Tx', async () => { - // swap WETH -> BAT, then fill BAT (takerAsset) for WETH (makerAsset) - // 0.01 WETH - const makerAmount = (0.01e18).toString(10); - // for 6 BAT - const takerAmount = (6e18).toString(10); - - const order = { - nonce: 99, - expiry: orderExpiry, - maker: maker.address, - makerAsset: WETH, - makerAmount, - takerAsset: BAT, - takerAmount, - }; - - const signableOrderData = await sdk.buildLimitOrder(order); - - const signature = await sdk.signLimitOrder(signableOrderData); - - const orderWithSignature = { ...signableOrderData.data, signature }; - - const swapAndLOPayload = await sdk.buildLimitOrderTx( - { - srcDecimals: 18, - destDecimals: 18, - userAddress: senderAddress, - partner: referrer, - orders: [orderWithSignature], - }, - { ignoreChecks: true } - ); - - expect(swapAndLOPayload).toEqual(expectTxParamsScheme); - expect({ - from: swapAndLOPayload.from, - to: swapAndLOPayload.to, - value: swapAndLOPayload.value, - chainId: swapAndLOPayload.chainId, - // data & gasPrice vary from run to run - }).toMatchInlineSnapshot(` - { - "chainId": 1, - "from": "0xaC39b311DCEb2A4b2f5d8461c1cdaF756F4F7Ae9", - "to": "0xdef171fe48cf0115b1d80b88dc8eab59176fee57", - "value": "0", - } - `); - }); - - test.skip(`fillLimitOrder through Augustus`, async () => { - // 0.01 WETH - const makerAmount = (0.01e18).toString(10); - // for 6 BAT - const takerAmount = (6e18).toString(10); - - // get some WETH onto maker wallet - const maker = new ethers.Wallet( - walletV5Stable.privateKey, - ethersV5Provider - ); - const { balance: wethBalance } = await buyErc20TokenForEth({ - fetcherOptions: { axios }, - tokenAddress: WETH, - amount: makerAmount, - signer: maker, - providerOptions: { - ethersProviderOrSigner: maker, - EthersContract: ethers.Contract, - account: maker.address, - }, - chainId, - ethersProvider: ethersV5Provider, - }); - - // for some reason BUY WETH may result into greater amount, unlike BUY other ERC20 - expect(new BigNumber(wethBalance).gt(makerAmount)).toBeTruthy(); - - // get some BAT onto the taker wallet - const taker = new ethers.Wallet( - walletV5Stable2.privateKey, - ethersV5Provider - ); - const { balance: batBalance } = await buyErc20TokenForEth({ - fetcherOptions: { axios }, - tokenAddress: BAT, - amount: takerAmount, - signer: taker, - providerOptions: { - ethersProviderOrSigner: taker, - EthersContract: ethers.Contract, - account: taker.address, - }, - chainId, - ethersProvider: ethersV5Provider, - }); - - expect(new BigNumber(batBalance).gte(takerAmount)).toBeTruthy(); - - const makerEthersContractCaller = constructEthersV5ContractCaller( - { - ethersProviderOrSigner: maker, - EthersContract: ethers.Contract, - }, - maker.address - ); - const takerEthersContractCaller = constructEthersV5ContractCaller( - { - ethersProviderOrSigner: taker, - EthersContract: ethers.Contract, - }, - taker.address - ); - - const makerSDK = constructPartialSDK( - { - chainId, - contractCaller: makerEthersContractCaller, - fetcher: axiosFetcher, - apiURL: process.env.API_URL, - version: '5', - }, - constructBuildLimitOrder, - constructSignLimitOrder, - constructApproveTokenForLimitOrder - ); - - const takerSDK = constructPartialSDK( - { - chainId, - contractCaller: takerEthersContractCaller, - fetcher: axiosFetcher, - apiURL: process.env.API_URL, - version: '5', - }, - constructBuildLimitOrder, - constructSignLimitOrder, - constructApproveTokenForLimitOrder, - constructBuildLimitOrderTx - ); - - const order = { - nonce: 999, - expiry: orderExpiry, - maker: maker.address, - makerAsset: WETH, - makerAmount, - takerAsset: BAT, - takerAmount, - taker: taker.address, - }; - - const signableOrderData = await makerSDK.buildLimitOrder(order); - - const signature = await makerSDK.signLimitOrder(signableOrderData); - - const WETH_Token = ERC20MintableFactory.attach(WETH); - const BAT_Token = ERC20MintableFactory.attach(BAT); - - const makerToken1InitBalance: BigNumberEthers = await WETH_Token.balanceOf( - maker.address - ); - const takerToken1InitBalance: BigNumberEthers = await WETH_Token.balanceOf( - taker.address - ); - const makerToken2InitBalance: BigNumberEthers = await BAT_Token.balanceOf( - maker.address - ); - const takerToken2InitBalance: BigNumberEthers = await BAT_Token.balanceOf( - taker.address - ); - - // without SDK - // await WETH_Token.connect(maker).approve(AugustusRFQ.address, makerAmount); - - // withSDK - const approveForMakerTx = await makerSDK.approveMakerTokenForLimitOrder( - makerAmount, - WETH_Token.address - ); - - await awaitTx(approveForMakerTx); - - // without SDK - // await BAT_Token.connect(taker).approve(AugustusSwapper.address, takerAmount); - - // withSDK - const approveForTakerTx = await takerSDK.approveTakerTokenForLimitOrder( - takerAmount, - BAT_Token.address - ); - await awaitTx(approveForTakerTx); - - const orderWithSignature = { ...signableOrderData.data, signature }; - - // taker address that would be checked as part of nonceAndMeta in Augustus - const metaAddress = deriveTakerFromNonceAndTaker( - signableOrderData.data.nonceAndMeta - ); - - // taker in nonceAndTaker = p2pOrderInput.taker - expect(metaAddress.toLowerCase()).toBe(taker.address.toLowerCase()); - - const { gas: payloadGas, ...LOPayloadTxParams } = - await takerSDK.buildLimitOrderTx( - { - srcDecimals: 18, - destDecimals: 18, - userAddress: taker.address, - partner: referrer, - orders: [orderWithSignature], - }, - // ignore checks as otherwise would throw "not enough BAT balance" - { ignoreChecks: true } - ); - - const transaction = { - ...LOPayloadTxParams, - gasPrice: - LOPayloadTxParams.gasPrice && - '0x' + new BigNumber(LOPayloadTxParams.gasPrice).toString(16), - maxFeePerGas: - LOPayloadTxParams.maxFeePerGas && - '0x' + new BigNumber(LOPayloadTxParams.maxFeePerGas).toString(16), - maxPriorityFeePerGas: - LOPayloadTxParams.maxPriorityFeePerGas && - '0x' + - new BigNumber(LOPayloadTxParams.maxPriorityFeePerGas).toString(16), - gasLimit: '0x' + new BigNumber(payloadGas || 5000000).toString(16), - value: '0x' + new BigNumber(LOPayloadTxParams.value).toString(16), - }; - - const takerFillsOrderTx = await taker.sendTransaction(transaction); - - await awaitTx(takerFillsOrderTx); - - const makerToken1AfterBalance: BigNumberEthers = await WETH_Token.balanceOf( - maker.address - ); - const takerToken1AfterBalance: BigNumberEthers = await WETH_Token.balanceOf( - taker.address - ); - const makerToken2AfterBalance: BigNumberEthers = await BAT_Token.balanceOf( - maker.address - ); - const takerToken2AfterBalance: BigNumberEthers = await BAT_Token.balanceOf( - taker.address - ); - - expect( - new BigNumber(makerToken1AfterBalance.toString()).toString(10) - ).toEqual( - new BigNumber(makerToken1InitBalance.toString()) - .minus(makerAmount) - .toString(10) - ); - expect( - new BigNumber(takerToken1AfterBalance.toString()).toString(10) - ).toEqual( - new BigNumber(takerToken1InitBalance.toString()) - .plus(makerAmount) - .toString(10) - ); - expect( - new BigNumber(makerToken2AfterBalance.toString()).toString(10) - ).toEqual( - new BigNumber(makerToken2InitBalance.toString()) - .plus(takerAmount) - .toString(10) - ); - expect( - new BigNumber(takerToken2AfterBalance.toString()).toString(10) - ).toEqual( - new BigNumber(takerToken2InitBalance.toString()) - .minus(takerAmount) - .toString(10) - ); - }); - - test.skip(`fill LimitOrder+Swap through Augustus`, async () => { - // swap DAI -> BAT, then fill BAT (takerAsset) for WETH (makerAsset) Order - - // 0.01 WETH - const makerAmount = (0.01e18).toString(10); - // for 6 BAT - const takerAmount = (6e18).toString(10); - - // get some WETH onto maker account - const maker = new ethers.Wallet( - walletV5Stable.privateKey, - ethersV5Provider - ); - const { balance: wethBalance } = await buyErc20TokenForEth({ - fetcherOptions: { axios }, - tokenAddress: WETH, - amount: makerAmount, - signer: maker, - providerOptions: { - ethersProviderOrSigner: maker, - EthersContract: ethers.Contract, - account: maker.address, - }, - chainId, - ethersProvider: ethersV5Provider, - }); - - // for some reason BUY WETH may result into greater amount, unlike BUY other ERC20 - expect(new BigNumber(wethBalance).gt(makerAmount)).toBeTruthy(); - - // get some DAI onto taker account - const taker = new ethers.Wallet( - walletV5Stable2.privateKey, - ethersV5Provider - ); - const { balance: daiBalance } = await buyErc20TokenForEth({ - fetcherOptions: { axios }, - tokenAddress: DAI, - amount: takerAmount, - signer: taker, - providerOptions: { - ethersProviderOrSigner: taker, - EthersContract: ethers.Contract, - account: taker.address, - }, - chainId, - ethersProvider: ethersV5Provider, - }); - - expect(new BigNumber(daiBalance).gte(takerAmount)).toBeTruthy(); - - const order = { - nonce: 998, - expiry: orderExpiry, - maker: maker.address, - makerAsset: WETH, - makerAmount, - takerAsset: BAT, - takerAmount, - taker: taker.address, - }; - - const makerEthersContractCaller = constructEthersV5ContractCaller( - { - ethersProviderOrSigner: maker, - EthersContract: ethers.Contract, - }, - maker.address - ); - const takerEthersContractCaller = constructEthersV5ContractCaller( - { - ethersProviderOrSigner: taker, - EthersContract: ethers.Contract, - }, - taker.address - ); - - const makerSDK = constructPartialSDK( - { - chainId, - contractCaller: makerEthersContractCaller, - fetcher: axiosFetcher, - apiURL: process.env.API_URL, - version: '5', - }, - constructBuildLimitOrder, - constructSignLimitOrder, - constructApproveTokenForLimitOrder - ); - - const takerSDK = constructPartialSDK( - { - chainId, - contractCaller: takerEthersContractCaller, - fetcher: axiosFetcher, - apiURL: process.env.API_URL, - version: '5', - }, - constructBuildLimitOrder, - constructSignLimitOrder, - constructApproveTokenForLimitOrder, - constructBuildLimitOrderTx, - constructGetSpender - ); - - const signableOrderData = await makerSDK.buildLimitOrder(order); - - const signature = await makerSDK.signLimitOrder(signableOrderData); - - const WETH_Token = ERC20MintableFactory.attach(WETH); - const BAT_Token = ERC20MintableFactory.attach(BAT); - const DAI_Token = ERC20MintableFactory.attach(DAI); - - const makerToken1InitBalance: BigNumberEthers = await WETH_Token.balanceOf( - maker.address - ); - const takerToken1InitBalance: BigNumberEthers = await WETH_Token.balanceOf( - taker.address - ); - const makerToken2InitBalance: BigNumberEthers = await BAT_Token.balanceOf( - maker.address - ); - const takerToken2InitBalance: BigNumberEthers = await BAT_Token.balanceOf( - taker.address - ); - - // without SDK - // await WETH_Token.connect(maker).approve(AugustusRFQ.address, makerAmount); - - // withSDK - const approveForMakerTx = await makerSDK.approveMakerTokenForLimitOrder( - makerAmount, - WETH_Token.address - ); - - await awaitTx(approveForMakerTx); - - // without SDK - // await DAI_Token.connect(taker).approve(AugustusSwapper.address, takerAmount); - - // withSDK - const approveForTakerTx = await takerSDK.approveTakerTokenForLimitOrder( - takerAmount, - DAI_Token.address - ); - await awaitTx(approveForTakerTx); - - const orderWithSignature = { ...signableOrderData.data, signature }; - - // taker address that would be checked as part of nonceAndMeta in Augustus - const metaAddress = deriveTakerFromNonceAndTaker( - signableOrderData.data.nonceAndMeta - ); - - // taker in nonceAndTaker = p2pOrderInput.taker - expect(metaAddress.toLowerCase()).toBe(taker.address.toLowerCase()); - - const priceRoute = await takerSDK.getLimitOrdersRate( - { - srcToken: DAI, - srcDecimals: 18, - destDecimals: 18, - destToken: BAT, - userAddress: taker.address, - }, - [order] - ); - - const swapAndLOPayloadTxParams = await takerSDK.buildSwapAndLimitOrderTx( - { - priceRoute, - userAddress: taker.address, - partner: referrer, - orders: [orderWithSignature], - }, - { ignoreChecks: true } - ); - - const transaction = { - ...swapAndLOPayloadTxParams, - gasPrice: - swapAndLOPayloadTxParams.gasPrice && - '0x' + new BigNumber(swapAndLOPayloadTxParams.gasPrice).toString(16), - maxFeePerGas: - swapAndLOPayloadTxParams.maxFeePerGas && - '0x' + - new BigNumber(swapAndLOPayloadTxParams.maxFeePerGas).toString(16), - maxPriorityFeePerGas: - swapAndLOPayloadTxParams.maxPriorityFeePerGas && - '0x' + - new BigNumber(swapAndLOPayloadTxParams.maxPriorityFeePerGas).toString( - 16 - ), - gasLimit: '0x' + new BigNumber(5000000).toString(16), - value: '0x' + new BigNumber(swapAndLOPayloadTxParams.value).toString(16), - }; - - const augustusTakerTokenBalanceBeforeSwap: BigNumberEthers = - await BAT_Token.balanceOf(await takerSDK.getAugustusSwapper()); - - const takerFillsOrderTx = await taker.sendTransaction(transaction); - - await awaitTx(takerFillsOrderTx); - - const makerToken1AfterBalance: BigNumberEthers = await WETH_Token.balanceOf( - maker.address - ); - const takerToken1AfterBalance: BigNumberEthers = await WETH_Token.balanceOf( - taker.address - ); - const makerToken2AfterBalance: BigNumberEthers = await BAT_Token.balanceOf( - maker.address - ); - const takerToken2AfterBalance: BigNumberEthers = await BAT_Token.balanceOf( - taker.address - ); - - expect( - new BigNumber(makerToken1AfterBalance.toString()).toString(10) - ).toEqual( - new BigNumber(makerToken1InitBalance.toString()) - .minus(makerAmount) - .toString(10) - ); - expect( - new BigNumber(takerToken1AfterBalance.toString()).toString(10) - ).toEqual( - new BigNumber(takerToken1InitBalance.toString()) - .plus(makerAmount) - .toString(10) - ); - expect( - new BigNumber(makerToken2AfterBalance.toString()).toString(10) - ).toEqual( - new BigNumber(makerToken2InitBalance.toString()) - .plus(takerAmount) - .toString(10) - ); - expect( - new BigNumber(takerToken2AfterBalance.toString()) - .plus(augustusTakerTokenBalanceBeforeSwap.toString()) // if augustus contained some dust, it'll be transferred to the taker in the result of a swap - .toString(10) - ).toEqual( - new BigNumber(takerToken2InitBalance.toString()) // initial balance - .plus(priceRoute.destAmount) // + swapped destAmount - .minus(takerAmount) // - given to fill the order - .toString(10) - ); - }); - - test('Build_Swap+LO_Tx', async () => { - // swap DAI -> BAT, then fill BAT (takerAsset) for WETH (makerAsset) - - // 0.01 WETH - const makerAmount = (0.01e18).toString(10); - // for 6 BAT - const takerAmount = (6e18).toString(10); - - const order = { - nonce: 99, - expiry: orderExpiry, - maker: maker.address, - makerAsset: WETH, - makerAmount, - takerAsset: BAT, - takerAmount, - }; - - // token to get after SWAP must be the takerAsset to allow to fill Order - const destToken = order.takerAsset; - // token to swap for destToken prior to filling Order - const srcToken = DAI; - - const signableOrderData = await sdk.buildLimitOrder(order); - - const signature = await sdk.signLimitOrder(signableOrderData); - - const priceRoute = await sdk.getLimitOrdersRate( - { - srcToken, - destToken, - userAddress: senderAddress, - options: { includeDEXS: ['UniswapV2'] }, - }, - [order] - ); - - const stablePriceRouteMatch: typeof priceRoute = { - ...priceRoute, - blockNumber: NaN, // will change with time - srcAmount: '---', //will change based on srcToken/destToken rate - hmac: '---', // will change with any other change - destUSD: '---', - gasCost: '---', - gasCostUSD: '---', - srcUSD: '---', - bestRoute: priceRoute.bestRoute.map((route) => ({ - ...route, - swaps: route.swaps.map((swap) => ({ - ...swap, - swapExchanges: swap.swapExchanges.map((exchange) => ({ - ...exchange, - data: { - ...exchange.data, - gasUSD: '---', - }, - srcAmount: '---', //will change based on srcToken/destToken rate - })), - })), - })), - }; - - // @CONSIDER this may change - expect(stablePriceRouteMatch).toMatchSnapshot(); - - const swapTxPayload = await sdk.buildTx( - { - srcToken, - destToken, - srcAmount: priceRoute.srcAmount, - destAmount: priceRoute.destAmount, - priceRoute, - userAddress: senderAddress, - partner: referrer, - }, - { ignoreChecks: true } - ); - - expect(swapTxPayload).toEqual(expectTxParamsScheme); - - expect({ - from: swapTxPayload.from, - to: swapTxPayload.to, - value: swapTxPayload.value, - chainId: swapTxPayload.chainId, - // data & gasPrice vary from run to run - }).toMatchInlineSnapshot(` - { - "chainId": 1, - "from": "0xaC39b311DCEb2A4b2f5d8461c1cdaF756F4F7Ae9", - "to": "0xDEF171Fe48CF0115B1d80b88dc8eAB59176FEe57", - "value": "0", - } - `); - - const swappableOrder = { ...signableOrderData.data, signature }; - - const swapAndLOPayload = await sdk.buildSwapAndLimitOrderTx( - { - priceRoute, - userAddress: senderAddress, - partner: referrer, - orders: [swappableOrder], - }, - { ignoreChecks: true } - ); - - expect(swapAndLOPayload).toEqual(expectTxParamsScheme); - expect({ - from: swapAndLOPayload.from, - to: swapAndLOPayload.to, - value: swapAndLOPayload.value, - chainId: swapAndLOPayload.chainId, - // data & gasPrice vary from run to run - }).toMatchInlineSnapshot(` - { - "chainId": 1, - "from": "0xaC39b311DCEb2A4b2f5d8461c1cdaF756F4F7Ae9", - "to": "0xDEF171Fe48CF0115B1d80b88dc8eAB59176FEe57", - "value": "0", - } - `); - }); - - describe.each(txSDKs)( - 'ethereum lib tests: $lib', - ({ lib, sdk, takerSDK }) => { - test(`signLimitOrder with ${lib}`, async () => { - const signableOrderData = await sdk.buildLimitOrder(orderInput); - - const signature = await sdk.signLimitOrder(signableOrderData); - expect(signature).toMatchInlineSnapshot( - `"0x18b022691daab1d8a3486aab5a006f2e98932b1c2fe4f04726c766e7a4e6d4935cbbf6d03ef945f23bef5cf4e250086f14581b1b8097f6c3ffd62653c8b2454b1b"` - ); - - const presumedOrderHash = calculateOrderHash(signableOrderData); - - expect( - ethers.utils.recoverAddress(presumedOrderHash, signature) - ).toEqual(senderAddress); - }); - - let libDependentNumber = 1; - - test(`cancelLimitOrder with ${lib}`, async () => { - // bytes32 - const randomOrderHash = `0x${libDependentNumber++}000000000000000000000000000000000000000000000000000000000000000`; - - const tx = await sdk.cancelLimitOrder(randomOrderHash); - await awaitTx(tx); - - const orderStatus: BigNumberEthers = await AugustusRFQ.remaining( - senderAddress, - randomOrderHash - ); - expect(orderStatus.toNumber()).toEqual(1); - }); - - test(`cancelLimitOrder Bulk with ${lib}`, async () => { - // bytes32[] - const randomOrderHashes = [ - `0x20${libDependentNumber++}0000000000000000000000000000000000000000000000000000000000000`, - `0x30${libDependentNumber++}0000000000000000000000000000000000000000000000000000000000000`, - ]; - - const tx = await sdk.cancelLimitOrderBulk(randomOrderHashes); - await awaitTx(tx); - - const orderStatus0 = await AugustusRFQ.remaining( - senderAddress, - randomOrderHashes[0] - ); - const orderStatus1 = await AugustusRFQ.remaining( - senderAddress, - randomOrderHashes[1] - ); - - expect(orderStatus0.toNumber()).toEqual(1); - expect(orderStatus1.toNumber()).toEqual(1); - }); - } - ); - - test('getLimitOrders', async () => { - const sdk = constructPartialSDK( - { - chainId: 137, - fetcher: axiosFetcher, - apiURL: process.env.API_URL, - version: '5', - }, - constructGetLimitOrders - ); - const account = '0x05182E579FDfCf69E4390c3411D8FeA1fb6467cf'; - const knownOrderHashes = [ - '0xfd076127e9fe40c5acf2efd03f8dd0cf2412fe277013d241c95a5da3eb64d5f8', - '0xef9fdf84be98cc70c05dbfe62af88412c1231f3025d3c829cf93b29f578a66fd', - '0x005c10e295af191364c7b47df72c0ca71b75b8f827231b352c4199ae109d4234', - ]; - - const { orders } = await sdk.getLimitOrders({ - maker: account, - type: 'LIMIT', - }); - - const knownOrders = orders.filter((order) => - knownOrderHashes.includes(order.orderHash.toLowerCase()) - ); - - assert( - knownOrders.length > 0, - `order must exist for orderHashes ${knownOrderHashes.join(', ')}` - ); - - // EXPIRED | CANCELLED order won't change - expect(knownOrders).toMatchSnapshot(); - }); - - test.skip('postLimitOrder', async () => { - // @TODO breaks with 'maker' doesn't have sufficient balance for this limit order - // because of API balance check - // need to use a fixed address through a PK - const signableOrderData = await sdk.buildLimitOrder({ - ...orderInput, - nonce: 2, - }); - - const signature = await sdk.signLimitOrder(signableOrderData); - // expect(signature).toMatchInlineSnapshot( - // `"0x3aa58967f07b7752c8220191ebd80e9e00f95212b2e9f3ee61f9e92ebbeeffab397833627056ade28ae2726d59534a30ee3099731aa1b41176e7e7bb0f8b28e71b"` - // ); - - const orderWithSignature: LimitOrderToSend = { - ...signableOrderData.data, - signature, - }; - - const newOrder = await sdk.postLimitOrder(orderWithSignature); - - const recoveredAddress = ethers.utils.recoverAddress( - newOrder.orderHash, - signature - ); - - expect(recoveredAddress).toEqual(senderAddress); - - // expect(newOrder).toMatchSnapshot('Order_from_API_Snapshot'); - }); - - test.skip(`fill OTC Order directly`, async () => { - // 0.01 WETH - const makerAmount = (0.01e18).toString(10); - // for 6 BAT - const takerAmount = (6e18).toString(10); - - // get some WETH onto maker wallet - const maker = new ethers.Wallet( - walletV5Stable.privateKey, - ethersV5Provider - ); - const { balance: wethBalance } = await buyErc20TokenForEth({ - fetcherOptions: { axios }, - tokenAddress: WETH, - amount: makerAmount, - signer: maker, - providerOptions: { - ethersProviderOrSigner: maker, - EthersContract: ethers.Contract, - account: maker.address, - }, - chainId, - ethersProvider: ethersV5Provider, - }); - - // for some reason BUY WETH may result into greater amount, unlike BUY other ERC20 - expect(new BigNumber(wethBalance).gt(makerAmount)).toBeTruthy(); - - // get some BAT onto the taker wallet - const taker = new ethers.Wallet( - walletV5Stable2.privateKey, - ethersV5Provider - ); - const { balance: batBalance } = await buyErc20TokenForEth({ - fetcherOptions: { axios }, - tokenAddress: BAT, - amount: takerAmount, - signer: taker, - providerOptions: { - ethersProviderOrSigner: taker, - EthersContract: ethers.Contract, - account: taker.address, - }, - chainId, - ethersProvider: ethersV5Provider, - }); - - expect(new BigNumber(batBalance).gte(takerAmount)).toBeTruthy(); - - const makerEthersContractCaller = constructEthersV5ContractCaller( - { - ethersProviderOrSigner: maker, - EthersContract: ethers.Contract, - }, - maker.address - ); - const takerEthersContractCaller = constructEthersV5ContractCaller( - { - ethersProviderOrSigner: taker, - EthersContract: ethers.Contract, - }, - taker.address - ); - - const makerSDK = constructPartialSDK( - { - chainId, - contractCaller: makerEthersContractCaller, - fetcher: axiosFetcher, - apiURL: process.env.API_URL, - version: '6.2', - }, - constructBuildLimitOrder, - constructSignLimitOrder, - constructApproveTokenForLimitOrder - ); - - const takerSDK = constructPartialSDK( - { - chainId, - contractCaller: takerEthersContractCaller, - fetcher: axiosFetcher, - apiURL: process.env.API_URL, - version: '6.2', // direct Order filling is supported on v6 only - }, - constructBuildLimitOrder, - constructSignLimitOrder, - constructApproveTokenForLimitOrder, - constructBuildLimitOrderTx, - constructFillOrderDirectly - ); - - const order = { - nonce: 9991, - expiry: orderExpiry, - maker: maker.address, - makerAsset: WETH, - makerAmount, - takerAsset: BAT, - takerAmount, - taker: taker.address, - }; - - const signableOrderData = await makerSDK.buildLimitOrder(order); - - const signature = await makerSDK.signLimitOrder(signableOrderData); - - const WETH_Token = ERC20MintableFactory.attach(WETH); - const BAT_Token = ERC20MintableFactory.attach(BAT); - - const makerToken1InitBalance: BigNumberEthers = await WETH_Token.balanceOf( - maker.address - ); - const takerToken1InitBalance: BigNumberEthers = await WETH_Token.balanceOf( - taker.address - ); - const makerToken2InitBalance: BigNumberEthers = await BAT_Token.balanceOf( - maker.address - ); - const takerToken2InitBalance: BigNumberEthers = await BAT_Token.balanceOf( - taker.address - ); - - // without SDK - // await WETH_Token.connect(maker).approve(AugustusRFQ.address, makerAmount); - - // withSDK - const approveForMakerTx = await makerSDK.approveMakerTokenForLimitOrder( - makerAmount, - WETH_Token.address - ); - - await awaitTx(approveForMakerTx); - - // without SDK - // await BAT_Token.connect(taker).approve(AugustusRFQ.address, takerAmount); - - // withSDK - const approveForTakerTx = - await takerSDK.approveTakerTokenForFillingP2POrderDirectly( - takerAmount, - BAT_Token.address - ); - await awaitTx(approveForTakerTx); - - const orderWithSignature = { ...signableOrderData.data, signature }; - - // taker address that would be checked as part of nonceAndMeta in Augustus - const metaAddress = deriveTakerFromNonceAndTaker( - signableOrderData.data.nonceAndMeta - ); - - // taker in nonceAndTaker = p2pOrderInput.taker - expect(metaAddress.toLowerCase()).toBe(taker.address.toLowerCase()); - // taker = p2pOrderInput.taker - expect(orderWithSignature.taker.toLowerCase()).toBe( - taker.address.toLowerCase() - ); - - const takerFillsOrderTx = await takerSDK.fillOrderDirectly({ - order: orderWithSignature, - signature: orderWithSignature.signature, - }); - - await awaitTx(takerFillsOrderTx); - - const makerToken1AfterBalance: BigNumberEthers = await WETH_Token.balanceOf( - maker.address - ); - const takerToken1AfterBalance: BigNumberEthers = await WETH_Token.balanceOf( - taker.address - ); - const makerToken2AfterBalance: BigNumberEthers = await BAT_Token.balanceOf( - maker.address - ); - const takerToken2AfterBalance: BigNumberEthers = await BAT_Token.balanceOf( - taker.address - ); - - expect( - new BigNumber(makerToken1AfterBalance.toString()).toString(10) - ).toEqual( - new BigNumber(makerToken1InitBalance.toString()) - .minus(makerAmount) - .toString(10) - ); - expect( - new BigNumber(takerToken1AfterBalance.toString()).toString(10) - ).toEqual( - new BigNumber(takerToken1InitBalance.toString()) - .plus(makerAmount) - .toString(10) - ); - expect( - new BigNumber(makerToken2AfterBalance.toString()).toString(10) - ).toEqual( - new BigNumber(makerToken2InitBalance.toString()) - .plus(takerAmount) - .toString(10) - ); - expect( - new BigNumber(takerToken2AfterBalance.toString()).toString(10) - ).toEqual( - new BigNumber(takerToken2InitBalance.toString()) - .minus(takerAmount) - .toString(10) - ); - }); - - test.skip(`fill OTC Order directly with Taker Permit1`, async () => { - // 0.01 WETH - const makerAmount = (0.01e18).toString(10); - // for 60 USDC - const takerAmount = (60e6).toString(10); - - // get some WETH onto maker wallet - const maker = new ethers.Wallet( - walletV5Stable.privateKey, - ethersV5Provider - ); - const { balance: wethBalance } = await buyErc20TokenForEth({ - fetcherOptions: { axios }, - tokenAddress: WETH, - amount: makerAmount, - signer: maker, - providerOptions: { - ethersProviderOrSigner: maker, - EthersContract: ethers.Contract, - account: maker.address, - }, - chainId, - ethersProvider: ethersV5Provider, - }); - - // for some reason BUY WETH may result into greater amount, unlike BUY other ERC20 - expect(new BigNumber(wethBalance).gt(makerAmount)).toBeTruthy(); - - // get some USDC onto the taker wallet - const taker = new ethers.Wallet( - walletV5Stable2.privateKey, - ethersV5Provider - ); - const { balance: usdcBalance } = await buyErc20TokenForEth({ - fetcherOptions: { axios }, - tokenAddress: USDC, - destDecimals: 6, - amount: takerAmount, - signer: taker, - providerOptions: { - ethersProviderOrSigner: taker, - EthersContract: ethers.Contract, - account: taker.address, - }, - chainId, - ethersProvider: ethersV5Provider, - }); - - expect(new BigNumber(usdcBalance).gte(takerAmount)).toBeTruthy(); - - const makerEthersContractCaller = constructEthersV5ContractCaller( - { - ethersProviderOrSigner: maker, - EthersContract: ethers.Contract, - }, - maker.address - ); - const takerEthersContractCaller = constructEthersV5ContractCaller( - { - ethersProviderOrSigner: taker, - EthersContract: ethers.Contract, - }, - taker.address - ); - - const makerSDK = constructPartialSDK( - { - chainId, - contractCaller: makerEthersContractCaller, - fetcher: axiosFetcher, - apiURL: process.env.API_URL, - version: '6.2', - }, - constructBuildLimitOrder, - constructSignLimitOrder, - constructApproveTokenForLimitOrder - ); - - const takerSDK = constructPartialSDK( - { - chainId, - contractCaller: takerEthersContractCaller, - fetcher: axiosFetcher, - apiURL: process.env.API_URL, - version: '6.2', // direct Order filling is supported on v6 only - }, - constructBuildLimitOrder, - constructSignLimitOrder, - constructApproveTokenForLimitOrder, - constructBuildLimitOrderTx, - constructFillOrderDirectly - ); - - const order = { - nonce: 9992, - expiry: orderExpiry, - maker: maker.address, - makerAsset: WETH, - makerAmount, - takerAsset: USDC, - takerAmount, - taker: taker.address, - }; - - const signableOrderData = await makerSDK.buildLimitOrder(order); - - const signature = await makerSDK.signLimitOrder(signableOrderData); - - const WETH_Token = ERC20MintableFactory.attach(WETH); - const USDC_Token = ERC20MintableFactory.attach(USDC); - - const makerToken1InitBalance: BigNumberEthers = await WETH_Token.balanceOf( - maker.address - ); - const takerToken1InitBalance: BigNumberEthers = await WETH_Token.balanceOf( - taker.address - ); - const makerToken2InitBalance: BigNumberEthers = await USDC_Token.balanceOf( - maker.address - ); - const takerToken2InitBalance: BigNumberEthers = await USDC_Token.balanceOf( - taker.address - ); - - // without SDK - // await WETH_Token.connect(maker).approve(AugustusRFQ.address, makerAmount); - - // withSDK - const approveForMakerTx = await makerSDK.approveMakerTokenForLimitOrder( - makerAmount, - WETH_Token.address - ); - - await awaitTx(approveForMakerTx); - - const orderWithSignature = { ...signableOrderData.data, signature }; - - // taker address that would be checked as part of nonceAndMeta in Augustus - const metaAddress = deriveTakerFromNonceAndTaker( - signableOrderData.data.nonceAndMeta - ); - - // taker in nonceAndTaker = p2pOrderInput.taker - expect(metaAddress.toLowerCase()).toBe(taker.address.toLowerCase()); - // taker = p2pOrderInput.taker - expect(orderWithSignature.taker.toLowerCase()).toBe( - taker.address.toLowerCase() - ); - - const AugustusRFQAddress = await sdk.getLimitOrdersContract(); - - const permitDeadline = Math.ceil((Date.now() + 1000 * 60 * 60) / 1000); - - const takerPermitSignature = await signPermit1({ - signer: taker, - user: taker.address, - spender: AugustusRFQAddress, - tokenName: 'USD Coin', - tokenAddress: USDC, - version: '2', - chainId, - amount: takerAmount, - nonce: 0, - deadline: permitDeadline, - }); - - const takerFillsOrderTx = await takerSDK.fillOrderDirectly({ - order: orderWithSignature, - signature: orderWithSignature.signature, - takerPermit: { - signature: takerPermitSignature, - deadline: permitDeadline, - }, - }); - - await awaitTx(takerFillsOrderTx); - - const makerToken1AfterBalance: BigNumberEthers = await WETH_Token.balanceOf( - maker.address - ); - const takerToken1AfterBalance: BigNumberEthers = await WETH_Token.balanceOf( - taker.address - ); - const makerToken2AfterBalance: BigNumberEthers = await USDC_Token.balanceOf( - maker.address - ); - const takerToken2AfterBalance: BigNumberEthers = await USDC_Token.balanceOf( - taker.address - ); - - expect( - new BigNumber(makerToken1AfterBalance.toString()).toString(10) - ).toEqual( - new BigNumber(makerToken1InitBalance.toString()) - .minus(makerAmount) - .toString(10) - ); - expect( - new BigNumber(takerToken1AfterBalance.toString()).toString(10) - ).toEqual( - new BigNumber(takerToken1InitBalance.toString()) - .plus(makerAmount) - .toString(10) - ); - expect( - new BigNumber(makerToken2AfterBalance.toString()).toString(10) - ).toEqual( - new BigNumber(makerToken2InitBalance.toString()) - .plus(takerAmount) - .toString(10) - ); - expect( - new BigNumber(takerToken2AfterBalance.toString()).toString(10) - ).toEqual( - new BigNumber(takerToken2InitBalance.toString()) - .minus(takerAmount) - .toString(10) - ); - }); - - test.skip(`fill OTC Order directly with Taker DAI Permit`, async () => { - // 0.01 WETH - const makerAmount = (0.01e18).toString(10); - // for 60 DAI - const takerAmount = (60e18).toString(10); - - // get some WETH onto maker wallet - const maker = new ethers.Wallet( - walletV5Stable.privateKey, - ethersV5Provider - ); - const { balance: wethBalance } = await buyErc20TokenForEth({ - fetcherOptions: { axios }, - tokenAddress: WETH, - amount: makerAmount, - signer: maker, - providerOptions: { - ethersProviderOrSigner: maker, - EthersContract: ethers.Contract, - account: maker.address, - }, - chainId, - ethersProvider: ethersV5Provider, - }); - - // for some reason BUY WETH may result into greater amount, unlike BUY other ERC20 - expect(new BigNumber(wethBalance).gt(makerAmount)).toBeTruthy(); - - // get some USDC onto the taker wallet - const taker = new ethers.Wallet( - walletV5Stable2.privateKey, - ethersV5Provider - ); - const { balance: daiBalance } = await buyErc20TokenForEth({ - fetcherOptions: { axios }, - tokenAddress: DAI, - amount: takerAmount, - signer: taker, - providerOptions: { - ethersProviderOrSigner: taker, - EthersContract: ethers.Contract, - account: taker.address, - }, - chainId, - ethersProvider: ethersV5Provider, - }); - - expect(new BigNumber(daiBalance).gte(takerAmount)).toBeTruthy(); - - const makerEthersContractCaller = constructEthersV5ContractCaller( - { - ethersProviderOrSigner: maker, - EthersContract: ethers.Contract, - }, - maker.address - ); - const takerEthersContractCaller = constructEthersV5ContractCaller( - { - ethersProviderOrSigner: taker, - EthersContract: ethers.Contract, - }, - taker.address - ); - - const makerSDK = constructPartialSDK( - { - chainId, - contractCaller: makerEthersContractCaller, - fetcher: axiosFetcher, - apiURL: process.env.API_URL, - version: '6.2', - }, - constructBuildLimitOrder, - constructSignLimitOrder, - constructApproveTokenForLimitOrder - ); - - const takerSDK = constructPartialSDK( - { - chainId, - contractCaller: takerEthersContractCaller, - fetcher: axiosFetcher, - apiURL: process.env.API_URL, - version: '6.2', // direct Order filling is supported on v6 only - }, - constructBuildLimitOrder, - constructSignLimitOrder, - constructApproveTokenForLimitOrder, - constructBuildLimitOrderTx, - constructFillOrderDirectly - ); - - const order = { - nonce: 9993, - expiry: orderExpiry, - maker: maker.address, - makerAsset: WETH, - makerAmount, - takerAsset: DAI, - takerAmount, - taker: taker.address, - }; - - const signableOrderData = await makerSDK.buildLimitOrder(order); - - const signature = await makerSDK.signLimitOrder(signableOrderData); - - const WETH_Token = ERC20MintableFactory.attach(WETH); - const DAI_Token = ERC20MintableFactory.attach(DAI); - - const makerToken1InitBalance: BigNumberEthers = await WETH_Token.balanceOf( - maker.address - ); - const takerToken1InitBalance: BigNumberEthers = await WETH_Token.balanceOf( - taker.address - ); - const makerToken2InitBalance: BigNumberEthers = await DAI_Token.balanceOf( - maker.address - ); - const takerToken2InitBalance: BigNumberEthers = await DAI_Token.balanceOf( - taker.address - ); - - // without SDK - // await WETH_Token.connect(maker).approve(AugustusRFQ.address, makerAmount); - - // withSDK - const approveForMakerTx = await makerSDK.approveMakerTokenForLimitOrder( - makerAmount, - WETH_Token.address - ); - - await awaitTx(approveForMakerTx); - - const orderWithSignature = { ...signableOrderData.data, signature }; - - // taker address that would be checked as part of nonceAndMeta in Augustus - const metaAddress = deriveTakerFromNonceAndTaker( - signableOrderData.data.nonceAndMeta - ); - - // taker in nonceAndTaker = p2pOrderInput.taker - expect(metaAddress.toLowerCase()).toBe(taker.address.toLowerCase()); - // taker = p2pOrderInput.taker - expect(orderWithSignature.taker.toLowerCase()).toBe( - taker.address.toLowerCase() - ); - - const AugustusRFQAddress = await sdk.getLimitOrdersContract(); - - const permitExpiry = Math.ceil((Date.now() + 1000 * 60 * 60) / 1000); - - const takerPermitSignature = await signDaiPermit({ - signer: taker, - user: taker.address, - spender: AugustusRFQAddress, - tokenName: 'Dai Stablecoin', - tokenAddress: DAI, - version: '1', - chainId, - amount: takerAmount, - nonce: 0, - expiry: permitExpiry, - }); - - const takerFillsOrderTx = await takerSDK.fillOrderDirectly({ - order: orderWithSignature, - signature: orderWithSignature.signature, - takerPermit: { - isDaiPermit: true, - signature: takerPermitSignature, - expiry: permitExpiry, - nonce: 0, - }, - }); - - await awaitTx(takerFillsOrderTx); - - const makerToken1AfterBalance: BigNumberEthers = await WETH_Token.balanceOf( - maker.address - ); - const takerToken1AfterBalance: BigNumberEthers = await WETH_Token.balanceOf( - taker.address - ); - const makerToken2AfterBalance: BigNumberEthers = await DAI_Token.balanceOf( - maker.address - ); - const takerToken2AfterBalance: BigNumberEthers = await DAI_Token.balanceOf( - taker.address - ); - - expect( - new BigNumber(makerToken1AfterBalance.toString()).toString(10) - ).toEqual( - new BigNumber(makerToken1InitBalance.toString()) - .minus(makerAmount) - .toString(10) - ); - expect( - new BigNumber(takerToken1AfterBalance.toString()).toString(10) - ).toEqual( - new BigNumber(takerToken1InitBalance.toString()) - .plus(makerAmount) - .toString(10) - ); - expect( - new BigNumber(makerToken2AfterBalance.toString()).toString(10) - ).toEqual( - new BigNumber(makerToken2InitBalance.toString()) - .plus(takerAmount) - .toString(10) - ); - expect( - new BigNumber(takerToken2AfterBalance.toString()).toString(10) - ).toEqual( - new BigNumber(takerToken2InitBalance.toString()) - .minus(takerAmount) - .toString(10) - ); - }); -}); - -function calculateOrderHash({ - domain, - types, - data, -}: SignableOrderData): string { - return ethers.utils._TypedDataEncoder.hash(domain, types, data); -} - -async function awaitTx( - tx: { wait(): Promise } | Web3UnpromiEvent -): Promise { - if ('wait' in tx) { - await tx.wait(); - - return; - } - - await new Promise((resolve, reject) => { - tx.once('receipt', resolve); - tx.once('error', reject); - }); -} - -function deriveTakerFromNonceAndTaker(nonceAndMeta: string): string { - return hexZeroPad( - hexValue(BigInt(nonceAndMeta) & ((BigInt(1) << BigInt(160)) - BigInt(1))), - 20 - ); -} - -type SignPermit1Input = { - signer: ethers.providers.JsonRpcSigner | ethers.Wallet; - user: string; - spender: string; - tokenName: string; - tokenAddress: string; - version: string; - chainId: number; - amount: string; - nonce: number; - deadline: number; -}; - -async function signPermit1({ - signer, - user, - spender, - tokenAddress, - tokenName, - version, - chainId, - amount, - nonce, - deadline, -}: SignPermit1Input) { - const domain = { - name: tokenName, - version, - chainId, - verifyingContract: tokenAddress, - }; - - const types = { - Permit: [ - { - name: 'owner', - type: 'address', - }, - { - name: 'spender', - type: 'address', - }, - { - name: 'value', - type: 'uint256', - }, - { - name: 'nonce', - type: 'uint256', - }, - { - name: 'deadline', - type: 'uint256', - }, - ], - }; - - const message = { - owner: user, - spender, - value: amount, - nonce, - deadline, - }; - - const signature = await signer._signTypedData(domain, types, message); - - return signature; -} - -type SignDAIPermitInput = { - signer: ethers.providers.JsonRpcSigner | ethers.Wallet; - user: string; - spender: string; - tokenName: string; - tokenAddress: string; - version: string; - chainId: number; - amount: string; - nonce: number; - expiry: number; -}; - -async function signDaiPermit({ - signer, - user, - spender, - tokenName, - tokenAddress, - version, - chainId, - nonce, - expiry, -}: SignDAIPermitInput) { - const domain = { - name: tokenName, - verifyingContract: tokenAddress, - chainId, - version, - }; - const types = { - Permit: [ - { - name: 'holder', - type: 'address', - }, - { - name: 'spender', - type: 'address', - }, - { - name: 'nonce', - type: 'uint256', - }, - { - name: 'expiry', - type: 'uint256', - }, - { - name: 'allowed', - type: 'bool', - }, - ], - }; - - const message = { - holder: user, - spender, - allowed: true, - nonce, - expiry, - }; - const signature = await signer._signTypedData(domain, types, message); - - return signature; -} diff --git a/tests/nftOrders.test.ts b/tests/nftOrders.test.ts deleted file mode 100644 index 9c71c56fe..000000000 --- a/tests/nftOrders.test.ts +++ /dev/null @@ -1,1527 +0,0 @@ -import * as dotenv from 'dotenv'; -import Web3 from 'web3'; -import type { TransactionReceipt as Web3TransactionReceipt } from 'web3'; -import { BigNumber as BigNumberEthers, Contract, ethers } from 'ethersV5'; -import { ethers as ethersV6 } from 'ethers'; -import { hexValue, hexZeroPad } from '@ethersproject/bytes'; -import axios from 'axios'; -import { - constructPartialSDK, - constructBuildNFTOrder, - BuildNFTOrderFunctions, - constructSignNFTOrder, - SignNFTOrderFunctions, - constructCancelNFTOrder, - CancelNFTOrderFunctions, - constructEthersV5ContractCaller, - constructEthersV6ContractCaller, - SDKConfig, - ConstructProviderFetchInput, - constructAxiosFetcher, - ApproveTokenForNFTOrderFunctions, - constructApproveTokenForNFTOrder, - constructGetNFTOrdersContract, - GetNFTOrdersContractFunctions, - constructPostNFTOrder, - PostNFTOrderFunctions, - NFTOrderToSend, - GetNFTOrdersFunctions, - constructGetNFTOrders, - Web3UnpromiEvent, - constructWeb3ContractCaller, - GetSpenderFunctions, - constructGetSpender, - BuildNFTOrdersTxFunctions, - constructBuildNFTOrderTx, - BuildTxFunctions, - constructBuildTx, - AssetType, -} from '../src'; -import BigNumber from 'bignumber.js'; - -import ERC20MinableABI from './abi/ERC20Mintable.json'; -import ERC721MintableABI from './abi/ERC721Mintable.json'; -import { bytecode as ERC20MintableBytecode } from './bytecode/ERC20Mintable.json'; -import { bytecode as ERC721MintableBytecode } from './bytecode/ERC721Mintable.json'; -import AugustusRFQAbi from './abi/AugustusRFQ.json'; -import { bytecode as AugustusRFQBytecode } from './bytecode/AugustusRFQ.json'; - -import { - BuildNFTOrderInput, - SignableNFTOrderData, -} from '../src/methods/nftOrders/buildOrder'; -import { assert } from 'ts-essentials'; -import { ZERO_ADDRESS } from '../src/methods/common/orders/buildOrderData'; -import { buyErc20TokenForEth } from './helpers'; -import { HardhatProvider, setupFork } from './helpers/hardhat'; - -dotenv.config(); - -jest.setTimeout(60 * 1000); - -declare let process: any; - -const referrer = 'sdk-test'; - -// const ETH = '0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee'; -const DAI = '0x6B175474E89094C44Da98b954EedeAC495271d0F'; -const BUSD = '0x4fabb145d64652a948d72533023f6e7a623c7c53'; -const COMP = '0xc00e94cb662c3520282e6f5717214004a7f26888'; -const AAVE = '0x7fc66500c84a76ad7e9c93437bfc5ac33e2ddae9'; -const MAKER = '0x9f8f72aa9304c8b593d555f12ef6589cc3a579a2'; - -// const DUMMY_ADDRESS_FOR_TESTING_ORDERS = -// '0xb9A079479A7b0F4E7F398F7ED3946bE6d9a40E79'; - -const chainId = process.env.CHAIN_ID || 1; -const srcToken = DAI; -const destToken = BUSD; - -const TEST_MNEMONIC = - 'radar blur cabbage chef fix engine embark joy scheme fiction master release'; - -//0xaC39b311DCEb2A4b2f5d8461c1cdaF756F4F7Ae9 -const walletV5Stable = ethers.Wallet.fromMnemonic(TEST_MNEMONIC); -//0xD7c0Cd9e7d2701c710D64Fc492C7086679BdF7b4 -const walletV5Stable2 = ethers.Wallet.fromMnemonic( - TEST_MNEMONIC, - "m/44'/60'/0'/0/1" -); - -// if test against tenderly fork, make sure accounts have enough ETH and zero nonce -const tenderlyForkUrl = process.env.TENDERLY_FORK_URL; -const ethersV5Provider = tenderlyForkUrl - ? new ethers.providers.JsonRpcProvider(tenderlyForkUrl) - : new ethers.providers.Web3Provider(HardhatProvider as any); - -const signerV5 = walletV5Stable.connect(ethersV5Provider); -const senderAddress = signerV5.address; - -const takerV5 = walletV5Stable2.connect(ethersV5Provider); - -const walletV6Stable = ethersV6.HDNodeWallet.fromPhrase(TEST_MNEMONIC); -const walletV6Stable2 = ethersV6.HDNodeWallet.fromPhrase( - TEST_MNEMONIC, - undefined, - "m/44'/60'/0'/0/1" -); - -const ethersV6Provider = new ethersV6.BrowserProvider(HardhatProvider); - -const signerV6 = walletV6Stable.connect(ethersV6Provider); -const takerV6 = walletV6Stable2.connect(ethersV6Provider); - -const axiosFetcher = constructAxiosFetcher(axios); - -const ethersV5ContractCaller = constructEthersV5ContractCaller( - { - ethersProviderOrSigner: signerV5, - EthersContract: ethers.Contract, - }, - senderAddress -); -const takerEthersV5ContractCaller = constructEthersV5ContractCaller( - { - ethersProviderOrSigner: takerV5, - EthersContract: ethers.Contract, - }, - walletV5Stable2.address -); - -const ethersV6ContractCaller = constructEthersV6ContractCaller( - { - ethersV6ProviderOrSigner: signerV6, - EthersV6Contract: ethersV6.Contract, - }, - senderAddress -); -const takerEthersV6ContractCaller = constructEthersV6ContractCaller( - { - ethersV6ProviderOrSigner: takerV6, - EthersV6Contract: ethersV6.Contract, - }, - walletV6Stable2.address -); - -const web3provider = new Web3(HardhatProvider as any); - -const web3ContractCaller = constructWeb3ContractCaller( - web3provider, - senderAddress -); -const takerWeb3ContractCaller = constructWeb3ContractCaller( - web3provider, - walletV5Stable2.address -); - -const ERC20MintableFactory = new ethers.ContractFactory( - ERC20MinableABI, - ERC20MintableBytecode, - signerV5 -); - -const ERC721MintableFactory = new ethers.ContractFactory( - ERC721MintableABI, - ERC721MintableBytecode, - signerV5 -); - -const AugustusRFQFactory = new ethers.ContractFactory( - AugustusRFQAbi, - AugustusRFQBytecode, - signerV5 -); - -const expectTxParamsScheme = expect.objectContaining({ - from: expect.any(String), - to: expect.any(String), - value: expect.any(String), - data: expect.any(String), - gasPrice: expect.any(String), - chainId: expect.any(Number), -}); - -describe('NFT Orders', () => { - let sdk: BuildNFTOrderFunctions & - SignNFTOrderFunctions & - GetNFTOrdersContractFunctions & - PostNFTOrderFunctions & - GetNFTOrdersFunctions & - CancelNFTOrderFunctions & - ApproveTokenForNFTOrderFunctions & - GetSpenderFunctions & - BuildNFTOrdersTxFunctions & - BuildTxFunctions; - - type MinEthersV5SDK = BuildNFTOrderFunctions & - SignNFTOrderFunctions & - CancelNFTOrderFunctions & - ApproveTokenForNFTOrderFunctions; - type MinTakerEthersV5SDK = BuildNFTOrdersTxFunctions & - ApproveTokenForNFTOrderFunctions; - - type MinEthersV6SDK = BuildNFTOrderFunctions & - SignNFTOrderFunctions & - CancelNFTOrderFunctions & - ApproveTokenForNFTOrderFunctions; - type MinTakerEthersV6SDK = BuildNFTOrdersTxFunctions & - ApproveTokenForNFTOrderFunctions; - - type MinWeb3SDK = BuildNFTOrderFunctions & - SignNFTOrderFunctions & - CancelNFTOrderFunctions & - ApproveTokenForNFTOrderFunctions; - type MinTakerWeb3SDK = ApproveTokenForNFTOrderFunctions; - - type EthersV5CancelOrderConstructor = ( - options: ConstructProviderFetchInput< - ethers.ContractTransaction, - 'transactCall' - > - ) => CancelNFTOrderFunctions; - type EthersV5ApproveTokenForNFTOrderConstructor = ( - options: ConstructProviderFetchInput< - ethers.ContractTransaction, - 'transactCall' - > - ) => ApproveTokenForNFTOrderFunctions; - - type EthersV6CancelOrderConstructor = ( - options: ConstructProviderFetchInput< - ethersV6.ContractTransactionResponse, - 'transactCall' - > - ) => CancelNFTOrderFunctions; - type EthersV6ApproveTokenForNFTOrderConstructor = ( - options: ConstructProviderFetchInput< - ethersV6.ContractTransactionResponse, - 'transactCall' - > - ) => ApproveTokenForNFTOrderFunctions; - - type Web3CancelOrderConstructor = ( - options: ConstructProviderFetchInput - ) => CancelNFTOrderFunctions; - type Web3ApproveTokenForNFTOrderConstructor = ( - options: ConstructProviderFetchInput - ) => ApproveTokenForNFTOrderFunctions; - - const ethersV5SDK: MinEthersV5SDK = constructPartialSDK< - SDKConfig, - [ - typeof constructBuildNFTOrder, - typeof constructSignNFTOrder, - EthersV5CancelOrderConstructor, - EthersV5ApproveTokenForNFTOrderConstructor - ] - >( - { - chainId, - contractCaller: ethersV5ContractCaller, - fetcher: axiosFetcher, - apiURL: process.env.API_URL, - version: '5', - }, - constructBuildNFTOrder, - constructSignNFTOrder, - constructCancelNFTOrder, - constructApproveTokenForNFTOrder - ); - - const takerEthersV5SDK: MinTakerEthersV5SDK = constructPartialSDK< - SDKConfig, - [ - EthersV5ApproveTokenForNFTOrderConstructor, - typeof constructBuildNFTOrderTx - ] - >( - { - chainId, - contractCaller: takerEthersV5ContractCaller, - fetcher: axiosFetcher, - apiURL: process.env.API_URL, - version: '5', - }, - constructApproveTokenForNFTOrder, - constructBuildNFTOrderTx - ); - - const ethersV6SDK: MinEthersV6SDK = constructPartialSDK< - SDKConfig, - [ - typeof constructBuildNFTOrder, - typeof constructSignNFTOrder, - EthersV6CancelOrderConstructor, - EthersV6ApproveTokenForNFTOrderConstructor - ] - >( - { - chainId, - contractCaller: ethersV6ContractCaller, - fetcher: axiosFetcher, - apiURL: process.env.API_URL, - version: '5', - }, - constructBuildNFTOrder, - constructSignNFTOrder, - constructCancelNFTOrder, - constructApproveTokenForNFTOrder - ); - - const takerEthersV6SDK: MinTakerEthersV6SDK = constructPartialSDK< - SDKConfig, - [ - EthersV6ApproveTokenForNFTOrderConstructor, - typeof constructBuildNFTOrderTx - ] - >( - { - chainId, - contractCaller: takerEthersV6ContractCaller, - fetcher: axiosFetcher, - apiURL: process.env.API_URL, - version: '5', - }, - constructApproveTokenForNFTOrder, - constructBuildNFTOrderTx - ); - - const web3SDK: MinWeb3SDK = constructPartialSDK< - SDKConfig, - [ - typeof constructBuildNFTOrder, - typeof constructSignNFTOrder, - Web3CancelOrderConstructor, - Web3ApproveTokenForNFTOrderConstructor - ] - >( - { - chainId, - contractCaller: web3ContractCaller, - fetcher: axiosFetcher, - apiURL: process.env.API_URL, - version: '5', - }, - constructBuildNFTOrder, - constructSignNFTOrder, - constructCancelNFTOrder, - constructApproveTokenForNFTOrder - ); - - const takerWeb3SDK: MinTakerWeb3SDK = constructPartialSDK< - SDKConfig, - [Web3ApproveTokenForNFTOrderConstructor] - >( - { - chainId, - contractCaller: takerWeb3ContractCaller, - fetcher: axiosFetcher, - apiURL: process.env.API_URL, - version: '5', - }, - - constructApproveTokenForNFTOrder - ); - - const txSDKs = [ - { lib: 'ethersV5', sdk: ethersV5SDK, takerSDK: takerEthersV5SDK }, - { lib: 'ethersV6', sdk: ethersV6SDK, takerSDK: takerEthersV6SDK }, - { lib: 'web3', sdk: web3SDK, takerSDK: takerWeb3SDK }, - ] as const; - - let orderInput: BuildNFTOrderInput; - // UTC format - const orderExpiry = Math.floor(new Date('2025-12-20').getTime() / 1000); - - let erc20Token1: Contract; - let erc20Token2: Contract; - let erc721Token1: Contract; - let erc721Token2: Contract; - let erc721Token3: Contract; - let erc721Token4: Contract; - - let AugustusRFQ: Contract; - - // let initialChainId2verifyingContract = { ...chainId2verifyingContract }; - - beforeAll(async () => { - await setupFork({ - accounts: [ - { balance: 1000e18, address: walletV5Stable.address }, - { balance: 1000e18, address: walletV5Stable2.address }, - ], - }); - - orderInput = { - nonce: 1, - expiry: orderExpiry, - makerAsset: srcToken, - takerAsset: destToken, - makerAmount: (1e18).toString(10), - takerAmount: (8e18).toString(10), - maker: senderAddress, - makerAssetType: AssetType.ERC1155, - takerAssetType: AssetType.ERC20, - makerAssetId: '9982', - }; - - erc20Token1 = await ERC20MintableFactory.deploy( - 'ERC20Token1', - 'ERC20Token1' - ); - await erc20Token1.deployTransaction.wait(); - - erc20Token2 = await ERC20MintableFactory.deploy( - 'ERC20Token2', - 'ERC20Token2' - ); - await erc20Token2.deployTransaction.wait(); - - await erc20Token1.mint(walletV5Stable.address, (60e18).toString(10)); - await erc20Token1.mint(walletV5Stable2.address, (60e18).toString(10)); - await erc20Token2.mint(walletV5Stable.address, (60e18).toString(10)); - await erc20Token2.mint(walletV5Stable2.address, (60e18).toString(10)); - - erc721Token1 = await ERC721MintableFactory.deploy(); - await erc721Token1.deployTransaction.wait(); - - erc721Token2 = await ERC721MintableFactory.deploy(); - await erc721Token2.deployTransaction.wait(); - - erc721Token3 = await ERC721MintableFactory.deploy(); - await erc721Token3.deployTransaction.wait(); - - erc721Token4 = await ERC721MintableFactory.deploy(); - await erc721Token4.deployTransaction.wait(); - - sdk = constructPartialSDK< - SDKConfig, - [ - typeof constructBuildNFTOrder, - typeof constructSignNFTOrder, - typeof constructGetNFTOrdersContract, - typeof constructPostNFTOrder, - typeof constructGetNFTOrders, - EthersV5CancelOrderConstructor, - EthersV5ApproveTokenForNFTOrderConstructor, - typeof constructGetSpender, - typeof constructBuildNFTOrderTx, - typeof constructBuildTx - ] - >( - { - chainId, - contractCaller: ethersV5ContractCaller, - fetcher: axiosFetcher, - apiURL: process.env.API_URL, - version: '5', - }, - constructBuildNFTOrder, - constructSignNFTOrder, - constructGetNFTOrdersContract, - constructPostNFTOrder, - constructGetNFTOrders, - constructCancelNFTOrder, - constructApproveTokenForNFTOrder, - constructGetSpender, - constructBuildNFTOrderTx, - constructBuildTx - ); - - AugustusRFQ = AugustusRFQFactory.attach(await sdk.getNFTOrdersContract()); - // AugustusRFQ = await AugustusRFQFactory.deploy(); - // await AugustusRFQ.deployTransaction.wait(); - }); - - // takes care of `there are asynchronous operations that weren't stopped in your tests` - // @TODO check if still needed after there are tx tests - // afterAll(async () => { - // Object.assign(chainId2verifyingContract, initialChainId2verifyingContract); - // }); - - test('getNFTOrdersContract', async () => { - const augustusRFQAddress = await sdk.getNFTOrdersContract(); - - expect(augustusRFQAddress).toMatchInlineSnapshot( - `"0xe92b586627ccA7a83dC919cc7127196d70f55a06"` - ); - }); - - // API returns 504 - test.skip('get NFT order by hash', async () => { - const knownOrderHash = - '0xec8018729db146d5bb20f313028ee765f6737deb4f859cd92c66f371bdb34aad'; - const sdk = constructPartialSDK( - { - chainId, - fetcher: axiosFetcher, - apiURL: process.env.API_URL, - version: '5', - }, - constructGetNFTOrders - ); - - const order = await sdk.getNFTOrderByHash(knownOrderHash); - expect(order).toMatchInlineSnapshot(` - { - "chainId": 137, - "createdAt": 1658989256, - "expiry": 1658992856, - "fillableBalance": "0", - "maker": "0x112f39ea2ccff2d088086590d11cd9f092954f77", - "makerAmount": "1", - "makerAsset": "0x235be10a7fb69727b4a907b0a957a716c7c14c13", - "makerAssetId": "2", - "makerAssetType": 1, - "nonceAndMeta": "20622990137246266303598744434210481256286975629423071997844118496006", - "orderHash": "0xec8018729db146d5bb20f313028ee765f6737deb4f859cd92c66f371bdb34aad", - "permitMakerAsset": null, - "signature": "0x028a2b4dbb6695c46ec432cac2952575c047f55b7e87be7cc5b28e6951200a8d4cbdb82d1a1a2506d59eba979e16c2c25e815d25a5bb840646881797f8d251941c", - "state": "FULFILLED", - "taker": "0xdef171fe48cf0115b1d80b88dc8eab59176fee57", - "takerAmount": "1000", - "takerAsset": "0x2791bca1f2de4661ed88a30c99a7a9449aa84174", - "takerAssetId": "0", - "takerAssetType": 0, - "takerFromMeta": "0x7ba594df3161729bf2e68a9d0a11dceb57a2e306", - "transactionHash": "0x44ff478136d857d620a7704d19083e0ff8f24021d9612fb8a0b6bcb9558ffcd3", - "type": "P2P", - } - `); - }); - - test('buildNFTOrder', async () => { - const signableOrderData = await sdk.buildNFTOrder(orderInput); - - // taker address that would be checked as part of nonceAndMeta in Augustus - const metaAddress = deriveTakerFromNonceAndTaker( - signableOrderData.data.nonceAndMeta - ); - - // taker in nonceAndTaker = Zero - expect(metaAddress).toBe(ZERO_ADDRESS); - - const AugustusAddress = await sdk.getAugustusSwapper(); - // taker in AugustusRFQ = Augustus - expect(signableOrderData.data.taker.toLowerCase()).toBe( - AugustusAddress.toLowerCase() - ); - - expect(signableOrderData.data.maker).toBe(senderAddress); - expect(signableOrderData.data.expiry).toBe(orderExpiry); - - expect(signableOrderData).toMatchSnapshot('Order_Data_Snapshot'); - }); - - test('buildNFTOrder p2p', async () => { - const p2pOrderInput = { - ...orderInput, - taker: takerV5.address, - }; - const signableOrderData = await sdk.buildNFTOrder({ - ...orderInput, - taker: takerV5.address, - }); - - // taker address that would be checked as part of nonceAndMeta in Augustus - const metaAddress = deriveTakerFromNonceAndTaker( - signableOrderData.data.nonceAndMeta - ); - - // taker in nonceAndTaker = p2pOrderInput.taker - expect(metaAddress.toLowerCase()).toBe(p2pOrderInput.taker.toLowerCase()); - - const AugustusAddress = await sdk.getAugustusSwapper(); - // taker in AugustusRFQ = Augustus - expect(signableOrderData.data.taker.toLowerCase()).toBe( - AugustusAddress.toLowerCase() - ); - - expect(signableOrderData.data.maker).toBe(senderAddress); - expect(signableOrderData.data.expiry).toBe(orderExpiry); - - expect(signableOrderData).toMatchSnapshot('P2P_Order_Data_Snapshot'); - }); - - test('Build_NFT_Tx', async () => { - const maker = walletV5Stable.connect(ethersV5Provider); - const makerEthersContractCaller = constructEthersV5ContractCaller( - { - ethersProviderOrSigner: maker, - EthersContract: ethers.Contract, - }, - maker.address - ); - - const sdk = constructPartialSDK( - { - chainId, - fetcher: axiosFetcher, - apiURL: process.env.API_URL, - contractCaller: makerEthersContractCaller, - version: '5', - }, - constructBuildNFTOrder, - constructSignNFTOrder, - constructBuildNFTOrderTx - ); - - // swap NFT -> BAT, then fill BAT (takerAsset) for NFT (makerAsset) - - // 1 NFT - const makerAmount = '1'; - // for 6 DAI - const takerAmount = (6e18).toString(10); - - const nftContract = new ethers.Contract( - erc721Token1.address, - ERC721MintableABI, - maker - ); - - await nftContract.mint(maker.address); - const afterMintLastId = (await nftContract.lastMintedTokenId()).toString(); - - const order = { - nonce: 99, - expiry: orderExpiry, - maker: maker.address, - makerAsset: erc721Token1.address, - makerAmount, - takerAsset: DAI, - takerAmount, - makerAssetType: AssetType.ERC721, - takerAssetType: AssetType.ERC20, - makerAssetId: afterMintLastId, - }; - - const signableOrderData = await sdk.buildNFTOrder(order); - - const signature = await sdk.signNFTOrder(signableOrderData); - - const orderWithSignature = { - ...order, // providers makerAssetType & takerAssetType, necessary for encoding makerAsset & takerAsset as uint (if got order by hash from API) - ...signableOrderData.data, // provides actual order data necessary for the contract - signature, // necessary for execution in the contract - // extra stuff will be removed before POSTing to /transaction - }; - - const swapAndNFTPayload = await sdk.buildNFTOrderTx( - { - srcDecimals: 18, - userAddress: senderAddress, - partner: referrer, - orders: [orderWithSignature], - }, - { ignoreChecks: true } - ); - - expect(swapAndNFTPayload).toEqual(expectTxParamsScheme); - expect({ - from: swapAndNFTPayload.from, - to: swapAndNFTPayload.to, - value: swapAndNFTPayload.value, - chainId: swapAndNFTPayload.chainId, - // data & gasPrice vary from run to run - }).toMatchInlineSnapshot(` - { - "chainId": 1, - "from": "0xaC39b311DCEb2A4b2f5d8461c1cdaF756F4F7Ae9", - "to": "0xdef171fe48cf0115b1d80b88dc8eab59176fee57", - "value": "0", - } - `); - }); - - test.skip(`fillNFTOrder through Augustus`, async () => { - // 1 NFT - const makerAmount = (1).toString(10); - // for 6 COMP - const takerAmount = (6e18).toString(10); - - const maker = walletV5Stable.connect(ethersV5Provider); - - const nftContract = new ethers.Contract( - erc721Token2.address, - ERC721MintableABI, - maker - ); - - await (await nftContract.mint(maker.address)).wait(); - const afterMintLastId = (await nftContract.lastMintedTokenId()).toString(); - - const taker = walletV5Stable2.connect(ethersV5Provider); - - //more to account for rogue Insufficient Balance errors - const buyAmount = new BigNumber(takerAmount).multipliedBy(2).toString(10); - - const { balance: compBalance } = await buyErc20TokenForEth({ - fetcherOptions: { axios }, - tokenAddress: COMP, - amount: buyAmount, - signer: taker, - providerOptions: { - ethersProviderOrSigner: taker, - EthersContract: ethers.Contract, - account: taker.address, - }, - chainId, - ethersProvider: ethersV5Provider, - }); - - expect(new BigNumber(compBalance).gte(takerAmount)).toBeTruthy(); - const makerEthersContractCaller = constructEthersV5ContractCaller( - { - ethersProviderOrSigner: maker, - EthersContract: ethers.Contract, - }, - maker.address - ); - const takerEthersContractCaller = constructEthersV5ContractCaller( - { - ethersProviderOrSigner: taker, - EthersContract: ethers.Contract, - }, - taker.address - ); - - const makerSDK = constructPartialSDK( - { - chainId, - contractCaller: makerEthersContractCaller, - fetcher: axiosFetcher, - apiURL: process.env.API_URL, - version: '5', - }, - constructBuildNFTOrder, - constructSignNFTOrder, - constructApproveTokenForNFTOrder - ); - - const takerSDK = constructPartialSDK( - { - chainId, - contractCaller: takerEthersContractCaller, - fetcher: axiosFetcher, - apiURL: process.env.API_URL, - version: '5', - }, - constructBuildNFTOrder, - constructSignNFTOrder, - constructApproveTokenForNFTOrder, - constructBuildNFTOrderTx, - constructGetSpender - ); - - const order: BuildNFTOrderInput = { - nonce: 999, - expiry: orderExpiry, - maker: maker.address, - makerAsset: erc721Token2.address, - makerAmount, - takerAsset: COMP, - takerAmount, - taker: taker.address, - makerAssetType: AssetType.ERC721, - takerAssetType: AssetType.ERC20, - makerAssetId: afterMintLastId, - }; - - const signableOrderData = await makerSDK.buildNFTOrder(order); - - const signature = await makerSDK.signNFTOrder(signableOrderData); - - const NFT_Token = erc20Token1.attach(erc721Token2.address); - const COMP_Token = erc20Token1.attach(COMP); - - const makerTokenNFTInitBalance: BigNumberEthers = await NFT_Token.balanceOf( - maker.address - ); - const takerTokenNFTInitBalance: BigNumberEthers = await NFT_Token.balanceOf( - taker.address - ); - const makerTokenERC20InitBalance: BigNumberEthers = - await COMP_Token.balanceOf(maker.address); - const takerTokenERC20InitBalance: BigNumberEthers = - await COMP_Token.balanceOf(taker.address); - - // without SDK - // await NFT_Token.connect(maker).approve(AugustusRFQ.address, makerAmount); - - // withSDK - const approveForMakerTx = await makerSDK.approveNFTForNFTOrder( - NFT_Token.address - ); - - await awaitTx(approveForMakerTx); - - // without SDK - // await BAT_Token.connect(taker).approve(AugustusSwapper.address, takerAmount); - - // withSDK - const approveForTakerTx = await takerSDK.approveERC20ForNFTOrder( - takerAmount, - COMP_Token.address - ); - await awaitTx(approveForTakerTx); - - const orderWithSignature = { - ...order, // providers makerAssetType & takerAssetType, necessary for encoding makerAsset & takerAsset as uint (if got order by hash from API) - ...signableOrderData.data, // provides actual order data necessary for the contract - signature, // necessary for execution in the contract - }; - - // taker address that would be checked as part of nonceAndMeta in Augustus - const metaAddress = deriveTakerFromNonceAndTaker( - signableOrderData.data.nonceAndMeta - ); - - // taker in nonceAndTaker = Zero - expect(metaAddress.toLowerCase()).toBe(taker.address.toLowerCase()); - - expect(orderWithSignature).toMatchInlineSnapshot(` - { - "expiry": 1766188800, - "maker": "0xaC39b311DCEb2A4b2f5d8461c1cdaF756F4F7Ae9", - "makerAmount": "1", - "makerAsset": "3211709136765895079141554841316046831806317204026", - "makerAssetId": "0", - "makerAssetType": 2, - "nonce": 999, - "nonceAndMeta": "1461271868364326844682297910593670628577722568144820", - "signature": "0x1666851b5f1a9ecd8723e83b0f57998172482075d9c8a5525d6de13818eebcd875fd2488bf91ebd2cffe2e8e2ff61d619435836cfd48c302d29eabb6078e4abc1b", - "taker": "0xDEF171Fe48CF0115B1d80b88dc8eAB59176FEe57", - "takerAmount": "6000000000000000000", - "takerAsset": "1096451400262405796991039590211805051831004063880", - "takerAssetId": "0", - "takerAssetType": 0, - } - `); - - const { gas: payloadGas, ...NFTPayloadTxParams } = - await takerSDK.buildNFTOrderTx( - { - srcDecimals: 18, - userAddress: taker.address, - partner: referrer, - orders: [orderWithSignature], - }, - // ignore checks as otherwise would throw "not enough balance" - { ignoreChecks: true } - ); - - const transaction: ethers.providers.TransactionRequest = { - ...NFTPayloadTxParams, - gasPrice: - NFTPayloadTxParams.gasPrice && - '0x' + new BigNumber(NFTPayloadTxParams.gasPrice).toString(16), - maxFeePerGas: - NFTPayloadTxParams.maxFeePerGas && - '0x' + new BigNumber(NFTPayloadTxParams.maxFeePerGas).toString(16), - maxPriorityFeePerGas: - NFTPayloadTxParams.maxPriorityFeePerGas && - '0x' + - new BigNumber(NFTPayloadTxParams.maxPriorityFeePerGas).toString(16), - gasLimit: '0x' + new BigNumber(payloadGas || 5000000).toString(16), - value: '0x' + new BigNumber(NFTPayloadTxParams.value).toString(16), - }; - - const augustusTakerTokenBalanceBeforeSwap: BigNumberEthers = - await COMP_Token.balanceOf(await takerSDK.getAugustusSwapper()); - - const takerFillsOrderTx = await taker.sendTransaction(transaction); - - await awaitTx(takerFillsOrderTx); - - const makerTokenNFTAfterBalance: BigNumberEthers = - await NFT_Token.balanceOf(maker.address); - const takerTokenNFTAfterBalance: BigNumberEthers = - await NFT_Token.balanceOf(taker.address); - const makerTokenERC20AfterBalance: BigNumberEthers = - await COMP_Token.balanceOf(maker.address); - const takerTokenERC20AfterBalance: BigNumberEthers = - await COMP_Token.balanceOf(taker.address); - - expect( - new BigNumber(makerTokenNFTAfterBalance.toString()).toString(10) - ).toEqual( - new BigNumber(makerTokenNFTInitBalance.toString()) - .minus(makerAmount) - .toString(10) - ); - expect( - new BigNumber(takerTokenNFTAfterBalance.toString()).toString(10) - ).toEqual( - new BigNumber(takerTokenNFTInitBalance.toString()) - .plus(makerAmount) - .toString(10) - ); - expect( - new BigNumber(makerTokenERC20AfterBalance.toString()).toString(10) - ).toEqual( - new BigNumber(makerTokenERC20InitBalance.toString()) - .plus(takerAmount) - .toString(10) - ); - - const takerAmountAfter = new BigNumber( - takerTokenERC20InitBalance.toString() - ) - .minus(takerAmount) - .toString(10); - const AugustusAmountAfter = new BigNumber( - takerTokenERC20AfterBalance.toString() - ) - .minus(augustusTakerTokenBalanceBeforeSwap.toString()) - .toString(10); - - // if augustus contained some dust, it'll be transferred to the taker in the result of a swap, - // except 1 wei may be left over - expect([ - takerAmountAfter, - new BigNumber(takerAmountAfter).minus(1).toString(10), - ]).toContain(AugustusAmountAfter); - }); - - // old Augustus contract - test.skip(`fill NFTOrder+Swap through Augustus`, async () => { - // swap AAVE -> MAKER, then fill MAKER (takerAsset) for NFT (makerAsset) Order - - // 1 NFT - const makerAmount = '1'; - // for 6 MAKER - const takerAmount = (6e18).toString(10); - - // mint NFT for maker - const maker = walletV5Stable.connect(ethersV5Provider); - - const nftContract = new ethers.Contract( - erc721Token4.address, - ERC721MintableABI, - maker - ); - - await (await nftContract.mint(maker.address)).wait(); - const afterMintLastId = (await nftContract.lastMintedTokenId()).toString(); - - // buy some AAVE for taker - const taker = walletV5Stable2.connect(ethersV5Provider); - - const order = { - nonce: 998, - expiry: orderExpiry, - maker: maker.address, - makerAsset: erc721Token4.address, - makerAmount, - takerAsset: MAKER, - takerAmount, - taker: taker.address, - makerAssetType: AssetType.ERC721, - takerAssetType: AssetType.ERC20, - makerAssetId: afterMintLastId, - }; - - const makerEthersContractCaller = constructEthersV5ContractCaller( - { - ethersProviderOrSigner: maker, - EthersContract: ethers.Contract, - }, - maker.address - ); - const takerEthersContractCaller = constructEthersV5ContractCaller( - { - ethersProviderOrSigner: taker, - EthersContract: ethers.Contract, - }, - taker.address - ); - - const makerSDK = constructPartialSDK( - { - chainId, - contractCaller: makerEthersContractCaller, - fetcher: axiosFetcher, - apiURL: process.env.API_URL, - version: '5', - }, - constructBuildNFTOrder, - constructSignNFTOrder, - constructApproveTokenForNFTOrder - ); - - const takerSDK = constructPartialSDK( - { - chainId, - contractCaller: takerEthersContractCaller, - fetcher: axiosFetcher, - apiURL: process.env.API_URL, - version: '5', - }, - constructBuildNFTOrder, - constructSignNFTOrder, - constructApproveTokenForNFTOrder, - constructBuildNFTOrderTx - ); - - const signableOrderData = await makerSDK.buildNFTOrder(order); - - const signature = await makerSDK.signNFTOrder(signableOrderData); - - const NFT_Token = erc20Token1.attach(erc721Token4.address); - const MAKER_Token = erc20Token1.attach(MAKER); - const AAVE_Token = erc20Token1.attach(AAVE); - - // without SDK - // await NFT_Token.connect(maker).approve(AugustusRFQ.address, makerAmount); - - // withSDK - const approveForMakerTx = await makerSDK.approveNFTForNFTOrder( - NFT_Token.address - ); - - await awaitTx(approveForMakerTx); - - const orderWithSignature = { - ...order, // providers makerAssetType & takerAssetType, necessary for encoding makerAsset & takerAsset as uint (if got order by hash from API) - ...signableOrderData.data, // provides actual order data necessary for the contract - signature, // necessary for execution in the contract - }; - - // taker address that would be checked as part of nonceAndMeta in Augustus - const metaAddress = deriveTakerFromNonceAndTaker( - signableOrderData.data.nonceAndMeta - ); - - // taker in nonceAndTaker = Zero - expect(metaAddress.toLowerCase()).toBe(taker.address.toLowerCase()); - - const priceRoute = await takerSDK.getNFTOrdersRate( - { - srcToken: AAVE, - destToken: MAKER, - userAddress: taker.address, - }, - [order] - ); - - //more to account for rogue Insufficient Balance errors - const buyAmount = new BigNumber(priceRoute.srcAmount) - .multipliedBy(2) - .toString(10); - - await buyErc20TokenForEth({ - fetcherOptions: { axios }, - tokenAddress: AAVE, - amount: buyAmount, - signer: taker, - providerOptions: { - ethersProviderOrSigner: taker, - EthersContract: ethers.Contract, - account: taker.address, - }, - chainId, - ethersProvider: ethersV5Provider, - }); - - const makerTokenNFTInitBalance: BigNumberEthers = await NFT_Token.balanceOf( - maker.address - ); - const takerTokenNFTInitBalance: BigNumberEthers = await NFT_Token.balanceOf( - taker.address - ); - const makerERC20TokenInitBalance: BigNumberEthers = - await MAKER_Token.balanceOf(maker.address); - const taker3rdTokenInitBalance: BigNumberEthers = - await AAVE_Token.balanceOf(taker.address); - - // without SDK - // await DAI_Token.connect(taker).approve(AugustusSwapper.address, takerAmount); - - // withSDK - const approveForTakerTx = await takerSDK.approveERC20ForNFTOrder( - buyAmount, - AAVE_Token.address - ); - await awaitTx(approveForTakerTx); - - const swapAndNFTPayloadTxParams = await takerSDK.buildSwapAndNFTOrderTx( - { - priceRoute, - userAddress: taker.address, - partner: referrer, - orders: [orderWithSignature], - }, - { ignoreChecks: true } - ); - - const transaction = { - ...swapAndNFTPayloadTxParams, - gasPrice: - swapAndNFTPayloadTxParams.gasPrice && - '0x' + new BigNumber(swapAndNFTPayloadTxParams.gasPrice).toString(16), - maxFeePerGas: - swapAndNFTPayloadTxParams.maxFeePerGas && - '0x' + - new BigNumber(swapAndNFTPayloadTxParams.maxFeePerGas).toString(16), - maxPriorityFeePerGas: - swapAndNFTPayloadTxParams.maxPriorityFeePerGas && - '0x' + - new BigNumber( - swapAndNFTPayloadTxParams.maxPriorityFeePerGas - ).toString(16), - gasLimit: '0x' + new BigNumber(5000000).toString(16), - value: '0x' + new BigNumber(swapAndNFTPayloadTxParams.value).toString(16), - }; - - try { - const takerFillsOrderTx = await taker.sendTransaction(transaction); - await awaitTx(takerFillsOrderTx); - } catch (error: any) { - // allow for hard-to-anticipate errors unrelated to tests - expect(error.message).toContain('External call failed'); - return; - } - - const makerTokenNFTAfterBalance: BigNumberEthers = - await NFT_Token.balanceOf(maker.address); - const takerTokenNFTAfterBalance: BigNumberEthers = - await NFT_Token.balanceOf(taker.address); - const makerERC20TokenAfterBalance: BigNumberEthers = - await MAKER_Token.balanceOf(maker.address); - const taker3rdTokenAfterBalance: BigNumberEthers = - await AAVE_Token.balanceOf(taker.address); - - expect( - new BigNumber(makerTokenNFTAfterBalance.toString()).toString(10) - ).toEqual( - new BigNumber(makerTokenNFTInitBalance.toString()) - .minus(makerAmount) - .toString(10) - ); - expect( - new BigNumber(takerTokenNFTAfterBalance.toString()).toString(10) - ).toEqual( - new BigNumber(takerTokenNFTInitBalance.toString()) - .plus(makerAmount) - .toString(10) - ); - expect( - new BigNumber(makerERC20TokenAfterBalance.toString()).toString(10) - ).toEqual( - new BigNumber(makerERC20TokenInitBalance.toString()) - .plus(takerAmount) - .toString(10) - ); - expect(BigInt(taker3rdTokenAfterBalance.toString())).toBeLessThan( - BigInt(taker3rdTokenInitBalance.toString()) // can't calculate how much less precisely, because of slippage - ); - }); - - test('Build_Swap+NFT_Tx', async () => { - // swap DAI -> BUSD, then fill BUSD (takerAsset) for NFT (makerAsset) - - // 1 NFT - const makerAmount = (1).toString(10); - // for 6 BUSD - const takerAmount = (6e18).toString(10); - - const maker = walletV5Stable.connect(ethersV5Provider); - const nftContract = new ethers.Contract( - erc721Token3.address, - ERC721MintableABI, - maker - ); - - await (await nftContract.mint(maker.address)).wait(); - const afterMintLastId = (await nftContract.lastMintedTokenId()).toString(); - - const order = { - nonce: 99, - expiry: orderExpiry, - maker: maker.address, - makerAsset: erc721Token3.address, - makerAmount, - takerAsset: BUSD, - takerAmount, - makerAssetType: AssetType.ERC721, - takerAssetType: AssetType.ERC20, - makerAssetId: afterMintLastId, - }; - - // token to get after SWAP must be the takerAsset to allow to fill Order - const destToken = order.takerAsset; - // token to swap for destToken prior to filling Order - const srcToken = DAI; - - const signableOrderData = await sdk.buildNFTOrder(order); - - const signature = await sdk.signNFTOrder(signableOrderData); - - const priceRoute = await sdk.getNFTOrdersRate( - { - srcToken, - destToken, - userAddress: senderAddress, - }, - [order] - ); - - const stablePriceRouteMatch: typeof priceRoute = { - ...priceRoute, - partnerFee: NaN, // dynamic number, can change slightly depending on API config - blockNumber: NaN, // will change with time - srcAmount: '---', //will change based on srcToken/destToken rate - hmac: '---', // will change with any other change - srcUSD: '---', - destUSD: '---', - gasCostUSD: '---', - gasCost: '---', // unstable, varies based on whether it's UniswapV2 or UniswapV3 at the time of writing - bestRoute: priceRoute.bestRoute.map((route) => ({ - ...route, - swaps: route.swaps.map((swap) => ({ - ...swap, - swapExchanges: swap.swapExchanges.map((exchange) => ({ - ...exchange, - data: { - ...exchange.data, - path: '---', // stablilze test because of variable path. - pools: '---', - factory: '---', - feeFactor: '---', - initCode: '---', - gasUSD: '---', - }, - exchange: '---', // unstable, sometimes it's UniswapV2, other times UniswapV3 - poolAddresses: ['---'], - poolIdentifiers: ['---'], - srcAmount: '---', //will change based on srcToken/destToken rate - })), - })), - })), - }; - - // @CONSIDER this may change - expect(stablePriceRouteMatch).toMatchInlineSnapshot(` - { - "bestRoute": [ - { - "percent": 100, - "swaps": [ - { - "destDecimals": 18, - "destToken": "0x4fabb145d64652a948d72533023f6e7a623c7c53", - "srcDecimals": 18, - "srcToken": "0x6b175474e89094c44da98b954eedeac495271d0f", - "swapExchanges": [ - { - "data": { - "factory": "---", - "feeFactor": "---", - "gasUSD": "---", - "initCode": "---", - "path": "---", - "pools": "---", - }, - "destAmount": "6000000000000000000", - "exchange": "---", - "percent": 100, - "poolAddresses": [ - "---", - ], - "poolIdentifiers": [ - "---", - ], - "srcAmount": "---", - }, - ], - }, - ], - }, - ], - "blockNumber": NaN, - "contractAddress": "0xDEF171Fe48CF0115B1d80b88dc8eAB59176FEe57", - "contractMethod": "simpleBuy", - "destAmount": "6000000000000000000", - "destDecimals": 18, - "destToken": "0x4fabb145d64652a948d72533023f6e7a623c7c53", - "destUSD": "---", - "gasCost": "---", - "gasCostUSD": "---", - "hmac": "---", - "maxImpactReached": false, - "network": 1, - "partner": "anon", - "partnerFee": NaN, - "side": "BUY", - "srcAmount": "---", - "srcDecimals": 18, - "srcToken": "0x6b175474e89094c44da98b954eedeac495271d0f", - "srcUSD": "---", - "tokenTransferProxy": "0x216b4b4ba9f3e719726886d34a177484278bfcae", - "version": "5", - } - `); - - const swapTxPayload = await sdk.buildTx( - { - srcToken, - destToken, - srcAmount: priceRoute.srcAmount, - destAmount: priceRoute.destAmount, - priceRoute, - userAddress: senderAddress, - partner: referrer, - }, - { ignoreChecks: true } - ); - - expect(swapTxPayload).toEqual(expectTxParamsScheme); - - expect({ - from: swapTxPayload.from, - to: swapTxPayload.to, - value: swapTxPayload.value, - chainId: swapTxPayload.chainId, - // data & gasPrice vary from run to run - }).toMatchInlineSnapshot(` - { - "chainId": 1, - "from": "0xaC39b311DCEb2A4b2f5d8461c1cdaF756F4F7Ae9", - "to": "0xDEF171Fe48CF0115B1d80b88dc8eAB59176FEe57", - "value": "0", - } - `); - - const swappableOrder = { - ...order, // providers makerAssetType & takerAssetType, necessary for encoding makerAsset & takerAsset as uint (if got order by hash from API) - ...signableOrderData.data, // provides actual order data necessary for the contract - signature, // necessary for execution in the contract - }; - - const swapAndNFTPayload = await sdk.buildSwapAndNFTOrderTx( - { - priceRoute, - userAddress: senderAddress, - partner: referrer, - orders: [swappableOrder], - }, - { ignoreChecks: true } - ); - - expect(swapAndNFTPayload).toEqual(expectTxParamsScheme); - expect({ - from: swapAndNFTPayload.from, - to: swapAndNFTPayload.to, - value: swapAndNFTPayload.value, - chainId: swapAndNFTPayload.chainId, - // data & gasPrice vary from run to run - }).toMatchInlineSnapshot(` - { - "chainId": 1, - "from": "0xaC39b311DCEb2A4b2f5d8461c1cdaF756F4F7Ae9", - "to": "0xDEF171Fe48CF0115B1d80b88dc8eAB59176FEe57", - "value": "0", - } - `); - }); - - describe.each(txSDKs)( - 'ethereum lib tests: $lib', - ({ lib, sdk, takerSDK }) => { - test(`signNFTOrder with ${lib}`, async () => { - const signableOrderData = await sdk.buildNFTOrder(orderInput); - - const signature = await sdk.signNFTOrder(signableOrderData); - expect(signature).toMatchInlineSnapshot( - `"0x72143ce3bc801dac394838d88d3acd39afce1999dee0ffff11bc4c69b5a2d76c02862144eb45a0f6033a3b04f5174c4eb0dbc2ebf0daa2af52528ed1ca12ae281b"` - ); - - const presumedOrderHash = calculateOrderHash(signableOrderData); - - expect( - ethers.utils.recoverAddress(presumedOrderHash, signature) - ).toEqual(senderAddress); - }); - - let libDependentNumber = 1; - - test(`cancelNFTOrder with ${lib}`, async () => { - // bytes32 - const randomOrderHash = `0x${libDependentNumber++}000000000000000000000000000000000000000000000000000000000000000`; - - const tx = await sdk.cancelNFTOrder(randomOrderHash); - await awaitTx(tx); - - const orderStatus: BigNumberEthers = await AugustusRFQ.remaining( - senderAddress, - randomOrderHash - ); - expect(orderStatus.toNumber()).toEqual(1); - }); - - test(`cancelNFTOrder Bulk with ${lib}`, async () => { - // bytes32[] - const randomOrderHashes = [ - `0x20${libDependentNumber++}0000000000000000000000000000000000000000000000000000000000000`, - `0x30${libDependentNumber++}0000000000000000000000000000000000000000000000000000000000000`, - ]; - - const tx = await sdk.cancelNFTOrderBulk(randomOrderHashes); - await awaitTx(tx); - - const orderStatus0 = await AugustusRFQ.remaining( - senderAddress, - randomOrderHashes[0] - ); - const orderStatus1 = await AugustusRFQ.remaining( - senderAddress, - randomOrderHashes[1] - ); - - expect(orderStatus0.toNumber()).toEqual(1); - expect(orderStatus1.toNumber()).toEqual(1); - }); - } - ); - - test.skip('getNFTOrders', async () => { - const account = '0x112f39ea2ccff2d088086590d11cd9f092954f77'; - const orderHash = - '0x6b3906698abedb72c2954b2ea39006e4be779b12eb9e72a1b8dba8dbd2ba975b'; - - const { orders } = await sdk.getNFTOrders({ - maker: account, - type: 'LIMIT', - }); - - const order = orders.find( - (order) => order.orderHash.toLowerCase() === orderHash - ); - - assert(order, `order must exist for orderHash ${orderHash}`); - - expect(order.state).toEqual('EXPIRED'); - - // EXPIRED order won't change - expect(order).toMatchInlineSnapshot(` - Object { - "chainId": 3, - "createdAt": 1652430671, - "expiry": 0, - "maker": "0x05182e579fdfcf69e4390c3411d8fea1fb6467cf", - "makerAmount": "10000000000000000000", - "makerAsset": "0xad6d458402f60fd3bd25163575031acdce07538d", - "makerBalance": "10000000000000000000", - "nonceAndMeta": "8209317000076433728076072485312968185294986748283703458703343616", - "orderHash": "0x6b3906698abedb72c2954b2ea39006e4be779b12eb9e72a1b8dba8dbd2ba975b", - "permitMakerAsset": null, - "signature": "0x5df9b6f3abaef67993e57e94ab2ed9e58a4c709fb03f0cf23117c0ed8a4b46097c515c2b055d2a5a1c373513faaa618ae3873e167c129128bb0b28a8be5f980e1b", - "state": "EXPIRED", - "taker": "0x0000000000000000000000000000000000000000", - "takerAmount": "1000000000000000000", - "takerAsset": "0xc778417e063141139fce010982780140aa0cd5ab", - } - `); - }); - - test.skip('postNFTOrder', async () => { - // @TODO breaks with 'maker' doesn't have sufficient balance for this NFT order - // because of API balance check - // need to use a fixed address through a PK - const signableOrderData = await sdk.buildNFTOrder({ - ...orderInput, - nonce: 2, - }); - - const signature = await sdk.signNFTOrder(signableOrderData); - // expect(signature).toMatchInlineSnapshot( - // `"0x3aa58967f07b7752c8220191ebd80e9e00f95212b2e9f3ee61f9e92ebbeeffab397833627056ade28ae2726d59534a30ee3099731aa1b41176e7e7bb0f8b28e71b"` - // ); - - const orderWithSignature: NFTOrderToSend = { - ...signableOrderData.data, - signature, - }; - - const newOrder = await sdk.postNFTLimitOrder(orderWithSignature); - - const recoveredAddress = ethers.utils.recoverAddress( - newOrder.orderHash, - signature - ); - - expect(recoveredAddress).toEqual(senderAddress); - - // expect(newOrder).toMatchSnapshot('Order_from_API_Snapshot'); - }); -}); - -function calculateOrderHash({ - domain, - types, - data, -}: SignableNFTOrderData): string { - return ethers.utils._TypedDataEncoder.hash(domain, types, data); -} - -async function awaitTx( - tx: { wait(): Promise } | Web3UnpromiEvent -): Promise { - if ('wait' in tx) { - await tx.wait(); - - return; - } - - await new Promise((resolve, reject) => { - tx.once('receipt', resolve); - tx.once('error', reject); - }); -} - -function deriveTakerFromNonceAndTaker(nonceAndMeta: string): string { - return hexZeroPad( - hexValue(BigInt(nonceAndMeta) & ((BigInt(1) << BigInt(160)) - BigInt(1))), - 20 - ); -} diff --git a/tests/partialSdk.test.ts b/tests/partialSdk.test.ts index 73e4a786b..a61c81738 100644 --- a/tests/partialSdk.test.ts +++ b/tests/partialSdk.test.ts @@ -130,7 +130,7 @@ describe.each([ }); sdk = constructPartialSDK( - { chainId, fetcher, version: '5' }, + { chainId, fetcher, apiURL: process.env.API_URL, version: '5' }, constructGetBalances, constructGetAdapters, constructGetTokens, @@ -230,7 +230,7 @@ describe.each([ slippage: 500, options: { includeDEXS: ['UniswapV2'], - includeContractMethods: ['swapExactAmountIn'], // more stable results + includeContractMethods: ['simpleSwap'], // more stable results }, }); @@ -254,6 +254,7 @@ describe.each([ const priceRouteStable = { ...priceRoute, + partnerFee: NaN, // dynamic number gasCost: 'dynamic_number', gasCostUSD: 'dynamic_number', hmac: 'dynamic_string', @@ -306,7 +307,17 @@ describe.each([ test('Get_Adapters', async () => { const adapters = await sdk.getAdapters(); - expect(adapters).toMatchSnapshot('Get_Adapters'); + expect(adapters.length).toBeGreaterThan(15); + expect(adapters).toEqual( + expect.arrayContaining([ + 'UniswapV2', + 'UniswapV3', + 'SushiSwap', + 'CurveV2', + 'BalancerV2', + 'AugustusRFQ', + ]) + ); }); test('Build_Tx', async () => { @@ -486,7 +497,13 @@ describe.each([ SDKConfig, [ApproveConstructor, typeof constructGetSpender] >( - { chainId, fetcher, contractCaller, version: '5' }, + { + chainId, + fetcher, + contractCaller, + apiURL: process.env.API_URL, + version: '5', + }, constructApproveToken, constructGetSpender ); diff --git a/tests/quote.test.ts b/tests/quote.test.ts index 8ebe88a16..1758dd572 100644 --- a/tests/quote.test.ts +++ b/tests/quote.test.ts @@ -30,7 +30,8 @@ describe('Quote:methods', () => { constructGetQuote ); - const amount = '100000000000'; // 100000 USDC, + const amount = '100000000000'; // 100000 USDC + const tooSmallAmount = '10000'; // 0.01 USDC test('Get Quote for delta', async () => { const quote = await quoteSDK.getQuote({ @@ -101,7 +102,7 @@ describe('Quote:methods', () => { const quotePromise = quoteSDK.getQuote({ srcToken: USDC, destToken: ETH, - amount: (+amount / 1e6).toFixed(0), + amount: tooSmallAmount, srcDecimals: 6, destDecimals: 18, mode: 'delta', @@ -130,34 +131,6 @@ describe('Quote:methods', () => { ]).toContainEqual({ details, errorType }); }); - test('Fail to Get Quote for delta with Native Token', async () => { - const quotePromise = quoteSDK.getQuote({ - srcToken: ETH, - destToken: USDC, - amount, - srcDecimals: 18, - destDecimals: 6, - mode: 'delta', - side: 'SELL', - }); - - await expect(quotePromise).rejects.toThrowErrorMatchingInlineSnapshot( - `"SourceEth"` - ); - - const error = await quotePromise.catch((e) => e); - - assert(isFetcherError(error), 'Error should be a FetchError'); - const { details, errorType } = error.response?.data; - - expect({ details, errorType }).toMatchInlineSnapshot(` - { - "details": "ETH as source token is not supported", - "errorType": "SourceEth", - } - `); - }); - test('Get Quote for delta for BUY', async () => { const quote = await quoteSDK.getQuote({ srcToken: USDC, @@ -174,6 +147,7 @@ describe('Quote:methods', () => { const staticDeltaPrice: typeof quote.delta = { ...quote.delta, + partnerFee: NaN, // dynamic number hmac: 'dynamic_string', destAmount: 'dynamic_number', destAmountBeforeFee: 'dynamic_number', @@ -215,7 +189,7 @@ describe('Quote:methods', () => { "gasCostUSDBeforeFee": "dynamic_number", "hmac": "dynamic_string", "partner": "anon", - "partnerFee": 0, + "partnerFee": NaN, "receivedDestAmount": "dynamic_number", "receivedDestUSD": "dynamic_number", "srcAmount": "dynamic_number", @@ -336,7 +310,7 @@ describe('Quote:methods', () => { const quote = await quoteSDK.getQuote({ srcToken: USDC, destToken: ETH, - amount: (1e5).toString(), + amount: tooSmallAmount, srcDecimals: 6, destDecimals: 18, mode: 'all', @@ -372,6 +346,7 @@ describe('Quote:methods', () => { const priceRouteStable = { ...priceRoute, + partnerFee: NaN, // dynamic number gasCost: 'dynamic_number', gasCostUSD: 'dynamic_number', hmac: 'dynamic_string', diff --git a/tests/simpleSdk.test.ts b/tests/simpleSdk.test.ts index df077d639..e1495383b 100644 --- a/tests/simpleSdk.test.ts +++ b/tests/simpleSdk.test.ts @@ -58,7 +58,12 @@ describe.each([ beforeAll(async () => { await setupFork({ accounts: [{ address: senderAddress, balance: 8e18 }] }); - sdk = constructSimpleSDK({ chainId, ...fetcherOptions, version: '6.2' }); + sdk = constructSimpleSDK({ + chainId, + ...fetcherOptions, + apiURL: process.env.API_URL, + version: '6.2', + }); }); test('getBalance', async () => { try { @@ -174,6 +179,7 @@ describe.each([ const priceRouteStable = { ...priceRoute, + partnerFee: NaN, // dynamic number gasCost: 'dynamic_number', gasCostUSD: 'dynamic_number', hmac: 'dynamic_string', @@ -215,7 +221,18 @@ describe.each([ test('Get_Adapters', async () => { const adapters = await sdk.swap.getAdapters(); - expect(adapters).toMatchSnapshot('Get_Adapters'); + + expect(adapters.length).toBeGreaterThan(15); + expect(adapters).toEqual( + expect.arrayContaining([ + 'UniswapV2', + 'UniswapV3', + 'SushiSwap', + 'CurveV2', + 'BalancerV2', + 'AugustusRFQ', + ]) + ); }); test('Build_Tx', async () => { @@ -384,7 +401,12 @@ describe.each([ beforeAll(() => { sdk = constructSimpleSDK( - { chainId, ...fetcherOptions, version: '5' }, + { + chainId, + ...fetcherOptions, + apiURL: process.env.API_URL, + version: '5', + }, providerOptions ); }); diff --git a/tests/viem.test.ts b/tests/viem.test.ts index 6dfc09a73..6f22982e5 100644 --- a/tests/viem.test.ts +++ b/tests/viem.test.ts @@ -85,6 +85,7 @@ describe('SDK with viem: contract calling methods', () => { { chainId, axios, + apiURL: process.env.API_URL, version: '6.2', }, { @@ -98,6 +99,7 @@ describe('SDK with viem: contract calling methods', () => { { chainId, axios, + apiURL: process.env.API_URL, version: '6.2', }, {