diff --git a/package.json b/package.json index 8ea810c..7f9eef2 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,7 @@ "typescript": "^5.7.3" }, "dependencies": { - "@cowprotocol/cow-sdk": "6.0.0-RC.42", + "@cowprotocol/cow-sdk": "6.0.0-RC.47", "@cowprotocol/app-data": "3.0.0-rc.1", "@cowprotocol/contracts": "^1.7.0", "axios": "^1.7.9", diff --git a/src/index.ts b/src/index.ts index 0c8aa4a..6ee52ce 100644 --- a/src/index.ts +++ b/src/index.ts @@ -35,6 +35,7 @@ import { run as getTradingQuote } from "./scripts/trading/getQuote"; import { run as getAcrossBridgingId } from "./scripts/bridging/getAcrossBridgingId"; import { run as getEthFlowId } from "./scripts/ethflow/getEthFlowId"; import { run as minimalAppData } from "./scripts/app-data/minimalAppData"; +import { run as collateralSwapAave } from "./scripts/flash-loans/collateralSwapAave"; dotenv.config(); @@ -42,6 +43,7 @@ dotenv.config(); const JOBS: (() => Promise)[] = [ // approveTokenSepolia, // Required to approve the token before trading // getQuoteAndPostOrder, // Simplest way to integrate! + // getQuoteAndPostOrderNative, // // swapWithPk, // swapSell, @@ -64,7 +66,7 @@ const JOBS: (() => Promise)[] = [ // nativeSell, // FIXME: Throws error creating the eth flow order. Doesn't recognize 'gas' property - I believe expects 'gasLimit') // // approveTokenMainnet, - getQuoteAndPostOrderMainnet, + // getQuoteAndPostOrderMainnet, // swapAndBridgeUsingOmnibridge, // swapAndBridgeUsingXdaiBridge, // @@ -83,6 +85,7 @@ const JOBS: (() => Promise)[] = [ // getAcrossBridgingId, // getEthFlowId, // minimalAppData, + collateralSwapAave, ]; async function main() { diff --git a/src/scripts/bridging/swapAndBridgeSdk.ts b/src/scripts/bridging/swapAndBridgeSdk.ts index 60dd34f..a06afa1 100644 --- a/src/scripts/bridging/swapAndBridgeSdk.ts +++ b/src/scripts/bridging/swapAndBridgeSdk.ts @@ -122,7 +122,7 @@ export async function run() { } // Post the order - const orderId = await quote.postSwapOrderFromQuote(); + const { orderId } = await quote.postSwapOrderFromQuote(); // Print the order creation console.log( diff --git a/src/scripts/flash-loans/abi/OrderHelperAbi.ts b/src/scripts/flash-loans/abi/OrderHelperAbi.ts new file mode 100644 index 0000000..a60d0ea --- /dev/null +++ b/src/scripts/flash-loans/abi/OrderHelperAbi.ts @@ -0,0 +1,156 @@ +export const orderHelperAbi = [ + { + type: "function", + name: "AAVE_LENDING_POOL", + inputs: [], + outputs: [{ name: "", type: "address", internalType: "address" }], + stateMutability: "view", + }, + { + type: "function", + name: "SETTLEMENT", + inputs: [], + outputs: [{ name: "", type: "address", internalType: "address" }], + stateMutability: "view", + }, + { + type: "function", + name: "appData", + inputs: [], + outputs: [{ name: "", type: "bytes32", internalType: "bytes32" }], + stateMutability: "view", + }, + { + type: "function", + name: "borrower", + inputs: [], + outputs: [{ name: "", type: "address", internalType: "address" }], + stateMutability: "view", + }, + { + type: "function", + name: "initialize", + inputs: [ + { name: "_owner", type: "address", internalType: "address" }, + { name: "_borrower", type: "address", internalType: "address" }, + { + name: "_oldCollateral", + type: "address", + internalType: "address", + }, + { + name: "_oldCollateralAmount", + type: "uint256", + internalType: "uint256", + }, + { + name: "_newCollateral", + type: "address", + internalType: "address", + }, + { + name: "_minSupplyAmount", + type: "uint256", + internalType: "uint256", + }, + { name: "_validTo", type: "uint32", internalType: "uint32" }, + { name: "_appData", type: "bytes32", internalType: "bytes32" }, + ], + outputs: [], + stateMutability: "nonpayable", + }, + { + type: "function", + name: "isValidSignature", + inputs: [ + { name: "_orderHash", type: "bytes32", internalType: "bytes32" }, + { name: "_signature", type: "bytes", internalType: "bytes" }, + ], + outputs: [{ name: "", type: "bytes4", internalType: "bytes4" }], + stateMutability: "view", + }, + { + type: "function", + name: "minSupplyAmount", + inputs: [], + outputs: [{ name: "", type: "uint256", internalType: "uint256" }], + stateMutability: "view", + }, + { + type: "function", + name: "newCollateral", + inputs: [], + outputs: [{ name: "", type: "address", internalType: "contract IERC20" }], + stateMutability: "view", + }, + { + type: "function", + name: "oldCollateral", + inputs: [], + outputs: [{ name: "", type: "address", internalType: "contract IERC20" }], + stateMutability: "view", + }, + { + type: "function", + name: "oldCollateralAmount", + inputs: [], + outputs: [{ name: "", type: "uint256", internalType: "uint256" }], + stateMutability: "view", + }, + { + type: "function", + name: "owner", + inputs: [], + outputs: [{ name: "", type: "address", internalType: "address" }], + stateMutability: "view", + }, + { + type: "function", + name: "swapCollateral", + inputs: [], + outputs: [], + stateMutability: "nonpayable", + }, + { + type: "function", + name: "validTo", + inputs: [], + outputs: [{ name: "", type: "uint32", internalType: "uint32" }], + stateMutability: "view", + }, + { + type: "event", + name: "Initialized", + inputs: [ + { + name: "version", + type: "uint64", + indexed: false, + internalType: "uint64", + }, + ], + anonymous: false, + }, + { type: "error", name: "AppDataDoesNotMatch", inputs: [] }, + { type: "error", name: "BadBuyToken", inputs: [] }, + { type: "error", name: "BadParameters", inputs: [] }, + { type: "error", name: "BadReceiver", inputs: [] }, + { type: "error", name: "BadSellAmount", inputs: [] }, + { type: "error", name: "BadSellToken", inputs: [] }, + { type: "error", name: "FeeIsNotZero", inputs: [] }, + { type: "error", name: "InvalidInitialization", inputs: [] }, + { type: "error", name: "NoPartiallyFillable", inputs: [] }, + { type: "error", name: "NotEnoughBuyAmount", inputs: [] }, + { type: "error", name: "NotEnoughSupplyAmount", inputs: [] }, + { type: "error", name: "NotInitializing", inputs: [] }, + { type: "error", name: "NotLongerValid", inputs: [] }, + { type: "error", name: "NotSellOrder", inputs: [] }, + { type: "error", name: "OnlyBalanceERC20", inputs: [] }, + { type: "error", name: "OrderDoesNotMatchMessageHash", inputs: [] }, + { + type: "error", + name: "SafeERC20FailedOperation", + inputs: [{ name: "token", type: "address", internalType: "address" }], + }, + { type: "error", name: "WrongValidTo", inputs: [] }, +]; diff --git a/src/scripts/flash-loans/abi/OrderHelperFactoryAbi.ts b/src/scripts/flash-loans/abi/OrderHelperFactoryAbi.ts new file mode 100644 index 0000000..fabab55 --- /dev/null +++ b/src/scripts/flash-loans/abi/OrderHelperFactoryAbi.ts @@ -0,0 +1,112 @@ +export const orderHelperFactoryAbi = [ + { + type: "constructor", + inputs: [ + { + name: "_helperImplementation", + type: "address", + internalType: "address", + }, + ], + stateMutability: "nonpayable", + }, + { + type: "function", + name: "deployOrderHelper", + inputs: [ + { name: "_owner", type: "address", internalType: "address" }, + { name: "_borrower", type: "address", internalType: "address" }, + { + name: "_oldCollateral", + type: "address", + internalType: "address", + }, + { + name: "_oldCollateralAmount", + type: "uint256", + internalType: "uint256", + }, + { + name: "_newCollateral", + type: "address", + internalType: "address", + }, + { + name: "_minSupplyAmount", + type: "uint256", + internalType: "uint256", + }, + { name: "_validTo", type: "uint32", internalType: "uint32" }, + ], + outputs: [ + { + name: "orderHelperAddress", + type: "address", + internalType: "address", + }, + ], + stateMutability: "nonpayable", + }, + { + type: "function", + name: "getOrderHelperAddress", + inputs: [ + { name: "_owner", type: "address", internalType: "address" }, + { name: "_borrower", type: "address", internalType: "address" }, + { + name: "_oldCollateral", + type: "address", + internalType: "address", + }, + { + name: "_oldCollateralAmount", + type: "uint256", + internalType: "uint256", + }, + { + name: "_newCollateral", + type: "address", + internalType: "address", + }, + { + name: "_minSupplyAmount", + type: "uint256", + internalType: "uint256", + }, + { name: "_validTo", type: "uint32", internalType: "uint32" }, + ], + outputs: [ + { + name: "orderHelperAddress", + type: "address", + internalType: "address", + }, + ], + stateMutability: "view", + }, + { + type: "event", + name: "NewOrderHelper", + inputs: [ + { + name: "helper", + type: "address", + indexed: true, + internalType: "address", + }, + ], + anonymous: false, + }, + { type: "error", name: "ContractAlreadyDeployed", inputs: [] }, + { type: "error", name: "FailedDeployment", inputs: [] }, + { + type: "error", + name: "InsufficientBalance", + inputs: [ + { name: "balance", type: "uint256", internalType: "uint256" }, + { name: "needed", type: "uint256", internalType: "uint256" }, + ], + }, + { type: "error", name: "InvalidImplementationContract", inputs: [] }, + { type: "error", name: "OrderHelperDeploymentFailed", inputs: [] }, +] as const; diff --git a/src/scripts/flash-loans/collateralSwapAave.ts b/src/scripts/flash-loans/collateralSwapAave.ts new file mode 100644 index 0000000..b581911 --- /dev/null +++ b/src/scripts/flash-loans/collateralSwapAave.ts @@ -0,0 +1,400 @@ +import { sepolia, APP_CODE } from "../../const"; + +import { + SupportedChainId, + OrderKind, + TradeParameters, + TradingSdk, + SigningScheme, + WithPartialTraderParams, + SwapAdvancedSettings, +} from "@cowprotocol/cow-sdk"; +import { ethers, providers } from "ethers"; +import { confirm, getRpcProvider, getWallet, printQuote } from "../../utils"; +import { getErc20Contract } from "../../contracts/erc20"; +import { latest } from "@cowprotocol/app-data"; +import { orderHelperFactoryAbi } from "./abi/OrderHelperFactoryAbi"; +import { orderHelperAbi } from "./abi/OrderHelperAbi"; + +// To setup an account to test this script: +// 1. Create a test account (PK to use in the script) +// 2. Go to https://app.aave.com, enable sepolia (in the gear icon on the top right), and supply sepolia ETH +// Example: https://sepolia.etherscan.io/tx/0x7cf4f7853963292ff7819d4a5cd5e31c55e7f679e49237c93315b47029486698 +// 3. Borrow some GHO +// Example: https://sepolia.etherscan.io/tx/0xb470bbf7e98d1b4cad7fa79e97b64e295bb2e077f0e91f9220d39c48f339641c +// 4. Add the private key and the RPC URL to the `.env` file: +// ```ini +// RPC_URL_11155111=your-rpc +// PRIVATE_KEY=your-pk +// ``` + +const TOKENS = { + oldUnderlying: "0xc558dbdd856501fcd9aaf1e62eae57a9f0629a3c", // WETH + oldCollateral: "0x5b071b590a59395fe4025a0ccc1fcc931aac1830", // aETHWeth + debt: "0xc4bf5cbdabe595361438f8c6a187bdc330539c60", // GHO + newUnderlying: "0x94a9d9ac8a22534e3faca9f4e7f2e2cf85d5e4c8", // USDC + newCollateral: "0x16dA4541aD1807f4443d92D26044C1147406EB80", // aUSDC +} as const; + +const AAVE_POOL_ADDRESS = "0x6Ae43d3271ff6888e7Fc43Fd7321a503ff738951"; // See https://search.onaave.com/?q=sepolia +const COW_AAVE_BORROWER = "0x7d9C4DeE56933151Bc5C909cfe09DEf0d315CB4A"; // See https://github.com/cowprotocol/flash-loan-router/blob/main/networks.json +const COW_AAVE_HELPER_FACTORY = "0xe7De9F737135AEE2d154D1b6b23414C1bf115109"; // https://sepolia.etherscan.io/address/0xe7De9F737135AEE2d154D1b6b23414C1bf115109#code +const DEFAULT_GAS_LIMIT = "1000000"; // FIXME: This should not be necessary, it should estimate correctly! + +const CHAIN_ID = SupportedChainId.SEPOLIA; + +export async function run() { + const wallet = await getWallet(CHAIN_ID); + const trader = wallet.address; + + console.log(`Trader ${trader}`); + + // Initialize the SDK with the wallet + const sdk = new TradingSdk({ + chainId: CHAIN_ID, + signer: wallet, // Use a signer + appCode: APP_CODE, + }); + + // Get some info about the assets + const { + oldUnderlingBalance, + oldUnderlyingSymbol, + oldUnderlyingDecimals, + oldUnderlyingBalanceFormatted, + newUnderlyingSymbol, + newUnderlyingDecimals, + } = await getAssetsInfo({ wallet, trader }); + + // Define trade parameters + console.log( + `Get quote for selling ${oldUnderlyingBalanceFormatted} ${oldUnderlyingSymbol} for ${newUnderlyingSymbol}` + ); + + // Get the order details + const { parameters, advancedSettings, helperContract } = + await getOrderDetails({ + trader, + oldUnderlingBalance, + oldUnderlyingDecimals, + newUnderlyingDecimals, + wallet, + }); + + // Post the 1271 order (including the flash-loan hint and the pre-hook) + // TODO: I believe the SDK doesn't handle very well 1271 orders, we might need to use another specific method to pass also the signature either in the quote, or at the time of posting the order. + // TODO: The signature should contain the order, so it can be decoded: `GPv2Order.Data memory _order = abi.decode(_signature, (GPv2Order.Data));`. . Keep in mind the signature will be simpler in a future implementation, because we don't need all the order data (most of them are already constants in the contract) + const { quoteResults, postSwapOrderFromQuote } = await sdk.getQuote( + parameters, + advancedSettings + ); + + // Print the quote + printQuote(quoteResults); + const buyAmount = quoteResults.amountsAndCosts.afterSlippage.buyAmount; + + // Ask for confirmation before posting the order + const confirmed = await confirm( + `You will get at least ${buyAmount} COW. ok?` + ); + if (confirmed) { + // User allows to transfer the old collateral to the helper contract + await approveOldCollateral({ + wallet, + trader, + helperContract, + oldUnderlingBalance, + oldUnderlyingDecimals, + oldUnderlyingSymbol, + }); + + // Post the order + const { orderId } = await postSwapOrderFromQuote(); + + console.log( + `Order created, id: https://explorer.cow.fi/sepolia/orders/${orderId}?tab=overview` + ); + } +} + +async function approveOldCollateral(params: { + wallet: ethers.Wallet; + trader: string; + helperContract: string; + oldUnderlingBalance: ethers.BigNumberish; + oldUnderlyingDecimals: number; + oldUnderlyingSymbol: string; +}) { + const { + wallet, + trader, + helperContract, + oldUnderlingBalance, + oldUnderlyingDecimals, + oldUnderlyingSymbol, + } = params; + + // Approve the helper contract to spend the old collateral + const oldCollateral = await getErc20Contract(TOKENS.oldCollateral, wallet); + + // Get the allowance for the helper contract + const allowance = await oldCollateral.allowance(trader, helperContract); + const allowanceFormatted = ethers.utils.formatUnits( + allowance, + oldUnderlyingDecimals + ); + console.log( + `Allowance for the helper contract: ${allowanceFormatted} ${oldUnderlyingSymbol}` + ); + + if (allowance < oldUnderlingBalance) { + console.log( + "Alright! First make sure the helper contract has an approval (we could use permit pre-hook instead too)" + ); + + const tx = await oldCollateral.approve(helperContract, oldUnderlingBalance); + await tx.wait(); + } else { + console.log("The helper contract has enough allowance to post the order"); + } +} + +async function getAssetsInfo(params: { + wallet: ethers.Wallet; + trader: string; +}) { + const { wallet, trader } = params; + + // Get ERC20 balance for oldUnderlying using ethersjs + const oldUnderlying = await getErc20Contract(TOKENS.oldUnderlying, wallet); + const oldCollateral = await getErc20Contract(TOKENS.oldCollateral, wallet); + const [oldUnderlyingSymbol, oldUnderlyingDecimals, oldUnderlingBalance] = + await Promise.all([ + oldUnderlying.symbol(), + oldUnderlying.decimals(), + oldCollateral.balanceOf(trader), + ]); + const oldUnderlyingBalanceFormatted = ethers.utils.formatUnits( + oldUnderlingBalance, + oldUnderlyingDecimals + ); + + console.log( + `Old underlying balance as collateral: ${oldUnderlyingBalanceFormatted} ${oldUnderlyingSymbol}` + ); + + const newUnderlying = await getErc20Contract(TOKENS.newUnderlying, wallet); + const [newUnderlyingSymbol, newUnderlyingDecimals] = await Promise.all([ + newUnderlying.symbol(), + newUnderlying.decimals(), + ]); + + return { + // Old underlying info + oldUnderlingBalance, + oldUnderlyingSymbol, + oldUnderlyingDecimals, + oldUnderlyingBalanceFormatted, + + // New underlying info + newUnderlyingSymbol, + newUnderlyingDecimals, + }; +} + +async function getHelperDeploymentPreHook(params: { + trader: string; + oldUnderlingBalance: ethers.BigNumberish; + minReceivedAmount: string; + validFor: number; + orderHelperFactory: ethers.Contract; + wallet: ethers.Wallet; +}): Promise<{ + helperContract: string; + helperContractDeploymentHook: latest.CoWHook; +}> { + const { + trader, + oldUnderlingBalance, + minReceivedAmount, + validFor, + orderHelperFactory, + wallet, + } = params; + + const orderHelperParams = [ + trader, // owner + AAVE_POOL_ADDRESS, // borrower + TOKENS.oldCollateral, + oldUnderlingBalance, + TOKENS.newCollateral, + minReceivedAmount, + validFor, + ]; + + console.log("Get helper contract", orderHelperParams); + const helperContract: string = await orderHelperFactory.getOrderHelperAddress( + ...orderHelperParams + ); + // TODO: We might want to use this function to save one RPC call + // const helperContract = predictDeterministicAddress({ + // implementation, + // salt: getSalt(orderHelperParams), + // factoryAddress: COW_AAVE_COLLATERAL_SWAP_HELPER_FACTORY, + // }); + + // Prepare deployment of the helper contract + const deployOrderHelperData = orderHelperFactory.interface.encodeFunctionData( + "deployOrderHelper", + orderHelperParams + ); + console.log("deployOrderHelperData", deployOrderHelperData); + + const gasEstimate = await wallet + .estimateGas({ + to: COW_AAVE_HELPER_FACTORY, + data: deployOrderHelperData, + value: ethers.constants.Zero, + }) + .catch((error) => { + console.error("error estimating gas", error); + console.log("Check the call", { + to: COW_AAVE_HELPER_FACTORY, + data: deployOrderHelperData, + }); + return DEFAULT_GAS_LIMIT; + }); + console.log("gasEstimate", gasEstimate); + + const helperContractDeploymentHook: latest.CoWHook = { + target: COW_AAVE_HELPER_FACTORY, + callData: deployOrderHelperData, + gasLimit: gasEstimate.toString(), + dappId: "cow-sdk-scripts://flash-loans/collateralSwapAave", + }; + + return { + helperContract, + helperContractDeploymentHook, + }; +} + +function getCollateralSwapPostHook(params: { + helperContract: string; +}): latest.CoWHook { + const { helperContract } = params; + + // Get the helper contract + const helperContractInstance = new ethers.Contract( + helperContract, + orderHelperAbi + ); + + const collateralSwapHook: latest.CoWHook = { + target: helperContract, + callData: + helperContractInstance.interface.encodeFunctionData("swapCollateral"), + gasLimit: DEFAULT_GAS_LIMIT, // TODO: Estimate gas + dappId: "cow-sdk-scripts://flash-loans/collateralSwapAave", + }; + + return collateralSwapHook; +} + +async function getOrderDetails(props: { + trader: string; + oldUnderlingBalance: ethers.BigNumberish; + oldUnderlyingDecimals: number; + newUnderlyingDecimals: number; + wallet: ethers.Wallet; +}): Promise<{ + parameters: WithPartialTraderParams; + advancedSettings?: SwapAdvancedSettings; + helperContract: string; +}> { + const { + trader, + oldUnderlingBalance, + oldUnderlyingDecimals, + newUnderlyingDecimals, + wallet, + } = props; + + // validFor is based on block.timestamp + const rpc = await getRpcProvider(CHAIN_ID); + const block = await rpc.getBlock("latest"); + const validFor = block.timestamp + 60 * 5; // 5 minutes from now + + // Get the minimum receive + const minReceivedAmount = "1"; // 1 Wei. Technically I would need to ask for a quote. Its a bit tricky, because we would need to ask for a quote with the helper contract as owner. Could be possible with a dirty trick (find an user with balance for the oldUnderlying and ask for a quote to dump it for the newUnderlying). For simplicity, I start hardcoding to 1 web. + + + // Ger factory contract instance + const orderHelperFactory = new ethers.Contract( + COW_AAVE_HELPER_FACTORY, + orderHelperFactoryAbi, + wallet + ); + + // Get the hook to deploy the helper contract + const { helperContractDeploymentHook, helperContract } = + await getHelperDeploymentPreHook({ + trader, + oldUnderlingBalance, + minReceivedAmount, + validFor, + orderHelperFactory, + wallet, + }); + + // Get the hook to swap the collateral + const collateralSwapHook = getCollateralSwapPostHook({ helperContract }); + const orderValidFor = validFor - block.timestamp; + + const parameters: TradeParameters = { + kind: OrderKind.SELL, + amount: oldUnderlingBalance.toString(), // All underlying balance + sellToken: TOKENS.oldUnderlying, + sellTokenDecimals: oldUnderlyingDecimals, + buyToken: TOKENS.newUnderlying, + buyTokenDecimals: newUnderlyingDecimals, + + partiallyFillable: false, + owner: helperContract as `0x${string}`, + receiver: helperContract, + validFor: orderValidFor, + }; + console.log("Trade parameters", parameters); + + // Flash loan + const flashLoanHint = { + lender: AAVE_POOL_ADDRESS, + borrower: COW_AAVE_BORROWER, + token: TOKENS.oldUnderlying, + amount: oldUnderlingBalance, + }; + console.log("flashLoanHint", flashLoanHint); + + const advancedSettings: SwapAdvancedSettings = { + additionalParams: { + signingScheme: SigningScheme.EIP1271, + }, + appData: { + appCode: APP_CODE, + metadata: { + // @ts-ignore The flash-loan hint is still not added officially to https://github.com/cowprotocol/app-data + flashLoan: flashLoanHint, + hooks: { + pre: [helperContractDeploymentHook], + post: [collateralSwapHook], + }, + }, + }, + }; + + return { + parameters, + advancedSettings, + helperContract, + }; +} diff --git a/src/utils.ts b/src/utils.ts index bfb42c3..32d4eff 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -125,3 +125,29 @@ export function getExplorerUrl(chainId: SupportedChainId, txHash: string) { throw new Error(`Unsupported Explorer for chainId ${chainId}`); } + +export function predictDeterministicAddress(params: { + implementation: string; + salt: string; + factoryAddress: string; +}): string { + const { implementation, salt, factoryAddress } = params; + // EIP-1167 minimal proxy creation code + const creationCode = + "0x3d602d80600a3d3981f3363d3d373d3d3d363d73" + + implementation.slice(2) + + "5af43d82803e903d91602b57fd5bf3"; + + // CREATE2 formula: keccak256(0xff ++ address ++ salt ++ keccak256(creationCode)) + const initCodeHash = ethers.utils.keccak256(creationCode); + + const packed = ethers.utils.solidityPack( + ["bytes1", "address", "bytes32", "bytes32"], + ["0xff", factoryAddress, salt, initCodeHash] + ); + + const hash = ethers.utils.keccak256(packed); + + // Return last 20 bytes (40 characters) as address + return ethers.utils.getAddress("0x" + hash.slice(-40)); +} diff --git a/yarn.lock b/yarn.lock index 9aa616c..0acaf7e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -37,10 +37,10 @@ json-stringify-deterministic "^1.0.8" multiformats "^9.6.4" -"@cowprotocol/app-data@^3.0.0": - version "3.0.0" - resolved "https://registry.yarnpkg.com/@cowprotocol/app-data/-/app-data-3.0.0.tgz#e5e7676ee8884c5348553883d0e65562c2f09e66" - integrity sha512-EyNoyoq3VnVIzvylLdn4Q1r0tU7HOikkjXzYY9PXJ/DUfj9gka7lOyNK7Ot8En2eUYTl3DNAle9RP7kt2sEpeg== +"@cowprotocol/app-data@^3.1.0": + version "3.1.0" + resolved "https://registry.yarnpkg.com/@cowprotocol/app-data/-/app-data-3.1.0.tgz#2ba5ec7d958b2510f17b08c7e18e05157032c4da" + integrity sha512-hdIWp6fGz/vx3gdoJgwd8Dx8rYAblpZEBiXss5mNzgF/LBb21VVhF075sDl9oxyesKuJayKjgiAgaFiZYVgblA== dependencies: ajv "^8.11.0" cross-fetch "^3.1.5" @@ -58,12 +58,12 @@ resolved "https://registry.yarnpkg.com/@cowprotocol/contracts/-/contracts-1.8.0.tgz#daffbd9846231c11a74b15a186bb754627e420b0" integrity sha512-rMEHo1UBB6k4kRoWejHZNGggg6IBVt7vAd8x0FhEvjxhbq3zlAex61f9HpAcDExJNuvfwwDjsOc/7UGztCzhSw== -"@cowprotocol/cow-sdk@6.0.0-RC.42": - version "6.0.0-RC.42" - resolved "https://registry.yarnpkg.com/@cowprotocol/cow-sdk/-/cow-sdk-6.0.0-RC.42.tgz#8ce000a1e9c6c3c1f70d336e62b8a1f363bbdd68" - integrity sha512-COskvWpwrzgjDRzI/X0WErK1UENbjXGJTaave4Fh/SrINN5I+1bJsiRJQVN72d9vq8VwM7rENjJG1+GzmaTs0A== +"@cowprotocol/cow-sdk@6.0.0-RC.47": + version "6.0.0-RC.47" + resolved "https://registry.yarnpkg.com/@cowprotocol/cow-sdk/-/cow-sdk-6.0.0-RC.47.tgz#45e993e2d96c49de375d948ad5d51c2623734afd" + integrity sha512-ilatk1z2MGa50huTezzknWXpxISQHE2XTsv5C08l529q7ZzPVlnbBpdVuilJrDp8hbBEFD4fuLy+tCESZLRk3w== dependencies: - "@cowprotocol/app-data" "^3.0.0" + "@cowprotocol/app-data" "^3.1.0" "@cowprotocol/contracts" "^1.8.0" "@ethersproject/abstract-signer" "^5.8.0" "@openzeppelin/merkle-tree" "^1.0.8"