From 20016cfac8e0d5443dfcb6561733a38b00951fe4 Mon Sep 17 00:00:00 2001 From: sakulstra Date: Mon, 22 Mar 2021 20:46:11 +0100 Subject: [PATCH 1/8] feat: paraswap feat: add initial paraswap integration fix: use test deployment fix: add some logging info fix: remove valiation debug: print network fix: fml fix: use paraswap --- contracts/ISwapCollateralParaswap.sol | 42 +++ src/tx-builder/config/v2/addresses.ts | 2 +- .../IParaSwapLiquiditySwapAdapter.d.ts | 259 ++++++++++++++++++ .../IParaSwapLiquiditySwapAdapter__factory.ts | 99 +++++++ src/tx-builder/contract-types/index.ts | 2 + ...ter.ts => LiquiditySwapAdapterParaswap.ts} | 2 +- ...ter.ts => LiquiditySwapAdapterParaswap.ts} | 33 ++- src/tx-builder/services/v2/LendingPool.ts | 116 +++++--- .../types/LendingPoolMethodTypes.ts | 4 +- ...iquiditySwapAdapterParaswapMethodTypes.ts} | 5 +- src/tx-builder/v2.ts | 4 +- 11 files changed, 518 insertions(+), 50 deletions(-) create mode 100644 contracts/ISwapCollateralParaswap.sol create mode 100644 src/tx-builder/contract-types/IParaSwapLiquiditySwapAdapter.d.ts create mode 100644 src/tx-builder/contract-types/factories/IParaSwapLiquiditySwapAdapter__factory.ts rename src/tx-builder/interfaces/{LiquiditySwapAdapter.ts => LiquiditySwapAdapterParaswap.ts} (90%) rename src/tx-builder/services/{LiquiditySwapAdapter.ts => LiquiditySwapAdapterParaswap.ts} (74%) rename src/tx-builder/types/{LiquiditySwapAdapterMethodTypes.ts => LiquiditySwapAdapterParaswapMethodTypes.ts} (71%) diff --git a/contracts/ISwapCollateralParaswap.sol b/contracts/ISwapCollateralParaswap.sol new file mode 100644 index 00000000..c36c8733 --- /dev/null +++ b/contracts/ISwapCollateralParaswap.sol @@ -0,0 +1,42 @@ +// SPDX-License-Identifier: agpl-3.0 +pragma solidity 0.6.12; +pragma experimental ABIEncoderV2; + +/** + * @title ParaSwapLiquiditySwapAdapter + * @notice Adapter to swap liquidity using ParaSwap. + * @author Jason Raymond Bell + */ +interface IParaSwapLiquiditySwapAdapter { + struct PermitSignature { + uint256 amount; + uint256 deadline; + uint8 v; + bytes32 r; + bytes32 s; + } + + /** + * @dev Swaps an amount of an asset to another and deposits the new asset amount on behalf of the user without using a flash loan. + * This method can be used when the temporary transfer of the collateral asset to this contract does not affect the user position. + * The user should give this contract allowance to pull the ATokens in order to withdraw the underlying asset and perform the swap. + * @param assetToSwapFrom Address of the underlying asset to be swapped from + * @param assetToSwapTo Address of the underlying asset to be swapped to and deposited + * @param amountToSwap Amount to be swapped, or maximum amount when swapping all balance + * @param minAmountToReceive Minimum amount to be received from the swap + * @param swapAllBalanceOffset Set to offset of fromAmount in Augustus calldata if wanting to swap all balance, otherwise 0 + * @param swapCalldata Calldata for ParaSwap's AugustusSwapper contract + * @param augustus Address of ParaSwap's AugustusSwapper contract + * @param permitParams Struct containing the permit signatures, set to all zeroes if not used + */ + function swapAndDeposit( + address assetToSwapFrom, + address assetToSwapTo, + uint256 amountToSwap, + uint256 minAmountToReceive, + uint256 swapAllBalanceOffset, + bytes calldata swapCalldata, + address augustus, + PermitSignature calldata permitParams + ) external; +} diff --git a/src/tx-builder/config/v2/addresses.ts b/src/tx-builder/config/v2/addresses.ts index 169ebe50..a2790853 100644 --- a/src/tx-builder/config/v2/addresses.ts +++ b/src/tx-builder/config/v2/addresses.ts @@ -37,7 +37,7 @@ export const commonContractAddressBetweenMarketsV2: CommonConfigType = { LEND_TO_AAVE_MIGRATOR: '0x317625234562b1526ea2fac4030ea499c5291de4', WETH_GATEWAY: '0xcc9a0B7c43DC2a5F023Bb9b738E45B0Ef6B06E04', FAUCET: '', - SWAP_COLLATERAL_ADAPTER: '0x63a3f444e97d14e671e7ee323c4234c8095e3516', + SWAP_COLLATERAL_ADAPTER: '0xc91864a5a1e2f52addfb69e31b89a3b7783733c3', REPAY_WITH_COLLATERAL_ADAPTER: '0x498c5431eb517101582988fbb36431ddaac8f4b1', FLASHLIQUIDATION: '0xE377fB98512D7b04827e56BC84e1838804a8019D', INCENTIVES_CONTROLLER: '0xd784927Ff2f95ba542BfC824c8a8a98F3495f6b5', diff --git a/src/tx-builder/contract-types/IParaSwapLiquiditySwapAdapter.d.ts b/src/tx-builder/contract-types/IParaSwapLiquiditySwapAdapter.d.ts new file mode 100644 index 00000000..0fc5fe82 --- /dev/null +++ b/src/tx-builder/contract-types/IParaSwapLiquiditySwapAdapter.d.ts @@ -0,0 +1,259 @@ +/* Autogenerated file. Do not edit manually. */ +/* tslint:disable */ +/* eslint-disable */ + +import { + ethers, + EventFilter, + Signer, + BigNumber, + BigNumberish, + PopulatedTransaction, +} from "ethers"; +import { + Contract, + ContractTransaction, + Overrides, + CallOverrides, +} from "@ethersproject/contracts"; +import { BytesLike } from "@ethersproject/bytes"; +import { Listener, Provider } from "@ethersproject/providers"; +import { FunctionFragment, EventFragment, Result } from "@ethersproject/abi"; + +interface IParaSwapLiquiditySwapAdapterInterface + extends ethers.utils.Interface { + functions: { + "swapAndDeposit(address,address,uint256,uint256,uint256,bytes,address,tuple)": FunctionFragment; + }; + + encodeFunctionData( + functionFragment: "swapAndDeposit", + values: [ + string, + string, + BigNumberish, + BigNumberish, + BigNumberish, + BytesLike, + string, + { + amount: BigNumberish; + deadline: BigNumberish; + v: BigNumberish; + r: BytesLike; + s: BytesLike; + } + ] + ): string; + + decodeFunctionResult( + functionFragment: "swapAndDeposit", + data: BytesLike + ): Result; + + events: {}; +} + +export class IParaSwapLiquiditySwapAdapter extends Contract { + connect(signerOrProvider: Signer | Provider | string): this; + attach(addressOrName: string): this; + deployed(): Promise; + + on(event: EventFilter | string, listener: Listener): this; + once(event: EventFilter | string, listener: Listener): this; + addListener(eventName: EventFilter | string, listener: Listener): this; + removeAllListeners(eventName: EventFilter | string): this; + removeListener(eventName: any, listener: Listener): this; + + interface: IParaSwapLiquiditySwapAdapterInterface; + + functions: { + swapAndDeposit( + assetToSwapFrom: string, + assetToSwapTo: string, + amountToSwap: BigNumberish, + minAmountToReceive: BigNumberish, + swapAllBalanceOffset: BigNumberish, + swapCalldata: BytesLike, + augustus: string, + permitParams: { + amount: BigNumberish; + deadline: BigNumberish; + v: BigNumberish; + r: BytesLike; + s: BytesLike; + }, + overrides?: Overrides + ): Promise; + + "swapAndDeposit(address,address,uint256,uint256,uint256,bytes,address,(uint256,uint256,uint8,bytes32,bytes32))"( + assetToSwapFrom: string, + assetToSwapTo: string, + amountToSwap: BigNumberish, + minAmountToReceive: BigNumberish, + swapAllBalanceOffset: BigNumberish, + swapCalldata: BytesLike, + augustus: string, + permitParams: { + amount: BigNumberish; + deadline: BigNumberish; + v: BigNumberish; + r: BytesLike; + s: BytesLike; + }, + overrides?: Overrides + ): Promise; + }; + + swapAndDeposit( + assetToSwapFrom: string, + assetToSwapTo: string, + amountToSwap: BigNumberish, + minAmountToReceive: BigNumberish, + swapAllBalanceOffset: BigNumberish, + swapCalldata: BytesLike, + augustus: string, + permitParams: { + amount: BigNumberish; + deadline: BigNumberish; + v: BigNumberish; + r: BytesLike; + s: BytesLike; + }, + overrides?: Overrides + ): Promise; + + "swapAndDeposit(address,address,uint256,uint256,uint256,bytes,address,(uint256,uint256,uint8,bytes32,bytes32))"( + assetToSwapFrom: string, + assetToSwapTo: string, + amountToSwap: BigNumberish, + minAmountToReceive: BigNumberish, + swapAllBalanceOffset: BigNumberish, + swapCalldata: BytesLike, + augustus: string, + permitParams: { + amount: BigNumberish; + deadline: BigNumberish; + v: BigNumberish; + r: BytesLike; + s: BytesLike; + }, + overrides?: Overrides + ): Promise; + + callStatic: { + swapAndDeposit( + assetToSwapFrom: string, + assetToSwapTo: string, + amountToSwap: BigNumberish, + minAmountToReceive: BigNumberish, + swapAllBalanceOffset: BigNumberish, + swapCalldata: BytesLike, + augustus: string, + permitParams: { + amount: BigNumberish; + deadline: BigNumberish; + v: BigNumberish; + r: BytesLike; + s: BytesLike; + }, + overrides?: CallOverrides + ): Promise; + + "swapAndDeposit(address,address,uint256,uint256,uint256,bytes,address,(uint256,uint256,uint8,bytes32,bytes32))"( + assetToSwapFrom: string, + assetToSwapTo: string, + amountToSwap: BigNumberish, + minAmountToReceive: BigNumberish, + swapAllBalanceOffset: BigNumberish, + swapCalldata: BytesLike, + augustus: string, + permitParams: { + amount: BigNumberish; + deadline: BigNumberish; + v: BigNumberish; + r: BytesLike; + s: BytesLike; + }, + overrides?: CallOverrides + ): Promise; + }; + + filters: {}; + + estimateGas: { + swapAndDeposit( + assetToSwapFrom: string, + assetToSwapTo: string, + amountToSwap: BigNumberish, + minAmountToReceive: BigNumberish, + swapAllBalanceOffset: BigNumberish, + swapCalldata: BytesLike, + augustus: string, + permitParams: { + amount: BigNumberish; + deadline: BigNumberish; + v: BigNumberish; + r: BytesLike; + s: BytesLike; + }, + overrides?: Overrides + ): Promise; + + "swapAndDeposit(address,address,uint256,uint256,uint256,bytes,address,(uint256,uint256,uint8,bytes32,bytes32))"( + assetToSwapFrom: string, + assetToSwapTo: string, + amountToSwap: BigNumberish, + minAmountToReceive: BigNumberish, + swapAllBalanceOffset: BigNumberish, + swapCalldata: BytesLike, + augustus: string, + permitParams: { + amount: BigNumberish; + deadline: BigNumberish; + v: BigNumberish; + r: BytesLike; + s: BytesLike; + }, + overrides?: Overrides + ): Promise; + }; + + populateTransaction: { + swapAndDeposit( + assetToSwapFrom: string, + assetToSwapTo: string, + amountToSwap: BigNumberish, + minAmountToReceive: BigNumberish, + swapAllBalanceOffset: BigNumberish, + swapCalldata: BytesLike, + augustus: string, + permitParams: { + amount: BigNumberish; + deadline: BigNumberish; + v: BigNumberish; + r: BytesLike; + s: BytesLike; + }, + overrides?: Overrides + ): Promise; + + "swapAndDeposit(address,address,uint256,uint256,uint256,bytes,address,(uint256,uint256,uint8,bytes32,bytes32))"( + assetToSwapFrom: string, + assetToSwapTo: string, + amountToSwap: BigNumberish, + minAmountToReceive: BigNumberish, + swapAllBalanceOffset: BigNumberish, + swapCalldata: BytesLike, + augustus: string, + permitParams: { + amount: BigNumberish; + deadline: BigNumberish; + v: BigNumberish; + r: BytesLike; + s: BytesLike; + }, + overrides?: Overrides + ): Promise; + }; +} diff --git a/src/tx-builder/contract-types/factories/IParaSwapLiquiditySwapAdapter__factory.ts b/src/tx-builder/contract-types/factories/IParaSwapLiquiditySwapAdapter__factory.ts new file mode 100644 index 00000000..081c7c41 --- /dev/null +++ b/src/tx-builder/contract-types/factories/IParaSwapLiquiditySwapAdapter__factory.ts @@ -0,0 +1,99 @@ +/* Autogenerated file. Do not edit manually. */ +/* tslint:disable */ +/* eslint-disable */ + +import { Contract, Signer } from "ethers"; +import { Provider } from "@ethersproject/providers"; + +import type { IParaSwapLiquiditySwapAdapter } from "../IParaSwapLiquiditySwapAdapter"; + +export class IParaSwapLiquiditySwapAdapter__factory { + static connect( + address: string, + signerOrProvider: Signer | Provider + ): IParaSwapLiquiditySwapAdapter { + return new Contract( + address, + _abi, + signerOrProvider + ) as IParaSwapLiquiditySwapAdapter; + } +} + +const _abi = [ + { + inputs: [ + { + internalType: "address", + name: "assetToSwapFrom", + type: "address", + }, + { + internalType: "address", + name: "assetToSwapTo", + type: "address", + }, + { + internalType: "uint256", + name: "amountToSwap", + type: "uint256", + }, + { + internalType: "uint256", + name: "minAmountToReceive", + type: "uint256", + }, + { + internalType: "uint256", + name: "swapAllBalanceOffset", + type: "uint256", + }, + { + internalType: "bytes", + name: "swapCalldata", + type: "bytes", + }, + { + internalType: "address", + name: "augustus", + type: "address", + }, + { + components: [ + { + internalType: "uint256", + name: "amount", + type: "uint256", + }, + { + internalType: "uint256", + name: "deadline", + type: "uint256", + }, + { + internalType: "uint8", + name: "v", + type: "uint8", + }, + { + internalType: "bytes32", + name: "r", + type: "bytes32", + }, + { + internalType: "bytes32", + name: "s", + type: "bytes32", + }, + ], + internalType: "struct IParaSwapLiquiditySwapAdapter.PermitSignature", + name: "permitParams", + type: "tuple", + }, + ], + name: "swapAndDeposit", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, +]; diff --git a/src/tx-builder/contract-types/index.ts b/src/tx-builder/contract-types/index.ts index 8a2abb00..2ac47a54 100644 --- a/src/tx-builder/contract-types/index.ts +++ b/src/tx-builder/contract-types/index.ts @@ -20,6 +20,7 @@ export type { IProposalValidator } from "./IProposalValidator"; export type { IRepayWithCollateral } from "./IRepayWithCollateral"; export type { IStakedToken } from "./IStakedToken"; export type { ISwapCollateral } from "./ISwapCollateral"; +export type { IParaSwapLiquiditySwapAdapter } from "./IParaSwapLiquiditySwapAdapter"; export type { ISynthetix } from "./ISynthetix"; export type { IWETHGateway } from "./IWETHGateway"; @@ -42,5 +43,6 @@ export { IProposalValidator__factory } from "./factories/IProposalValidator__fac export { IRepayWithCollateral__factory } from "./factories/IRepayWithCollateral__factory"; export { IStakedToken__factory } from "./factories/IStakedToken__factory"; export { ISwapCollateral__factory } from "./factories/ISwapCollateral__factory"; +export { IParaSwapLiquiditySwapAdapter__factory } from "./factories/IParaSwapLiquiditySwapAdapter__factory"; export { ISynthetix__factory } from "./factories/ISynthetix__factory"; export { IWETHGateway__factory } from "./factories/IWETHGateway__factory"; diff --git a/src/tx-builder/interfaces/LiquiditySwapAdapter.ts b/src/tx-builder/interfaces/LiquiditySwapAdapterParaswap.ts similarity index 90% rename from src/tx-builder/interfaces/LiquiditySwapAdapter.ts rename to src/tx-builder/interfaces/LiquiditySwapAdapterParaswap.ts index 9a31ec0a..28f638f8 100644 --- a/src/tx-builder/interfaces/LiquiditySwapAdapter.ts +++ b/src/tx-builder/interfaces/LiquiditySwapAdapterParaswap.ts @@ -1,5 +1,5 @@ import { EthereumTransactionTypeExtended } from '../types'; -import { SwapAndDepositMethodType } from '../types/LiquiditySwapAdapterMethodTypes'; +import { SwapAndDepositMethodType } from '../types/LiquiditySwapAdapterParaswapMethodTypes'; export default interface LiquiditySwapAdapterInterface { swapAndDeposit: ( diff --git a/src/tx-builder/services/LiquiditySwapAdapter.ts b/src/tx-builder/services/LiquiditySwapAdapterParaswap.ts similarity index 74% rename from src/tx-builder/services/LiquiditySwapAdapter.ts rename to src/tx-builder/services/LiquiditySwapAdapterParaswap.ts index eb4b42bf..26ca77a8 100644 --- a/src/tx-builder/services/LiquiditySwapAdapter.ts +++ b/src/tx-builder/services/LiquiditySwapAdapterParaswap.ts @@ -1,25 +1,29 @@ import { commonContractAddressBetweenMarketsV2 } from '../config'; -import { ISwapCollateral__factory, ISwapCollateral } from '../contract-types'; -import LiquiditySwapAdapterInterface from '../interfaces/LiquiditySwapAdapter'; +import { + IParaSwapLiquiditySwapAdapter__factory, + IParaSwapLiquiditySwapAdapter, +} from '../contract-types'; +import LiquiditySwapAdapterInterface from '../interfaces/LiquiditySwapAdapterParaswap'; import { Configuration, eEthereumTxType, EthereumTransactionTypeExtended, transactionType, } from '../types'; -import { SwapAndDepositMethodType } from '../types/LiquiditySwapAdapterMethodTypes'; +import { SwapAndDepositMethodType } from '../types/LiquiditySwapAdapterParaswapMethodTypes'; import { LiquiditySwapValidator } from '../validators/methodValidators'; import { IsEthAddress, IsPositiveAmount } from '../validators/paramValidators'; import BaseService from './BaseService'; export default class LiquiditySwapAdapterService - extends BaseService + extends BaseService implements LiquiditySwapAdapterInterface { readonly liquiditySwapAdapterAddress: string; constructor(config: Configuration) { - super(config, ISwapCollateral__factory); + super(config, IParaSwapLiquiditySwapAdapter__factory); + console.log('nw', this.config.network); const { SWAP_COLLATERAL_ADAPTER } = commonContractAddressBetweenMarketsV2[ this.config.network ]; @@ -31,6 +35,7 @@ export default class LiquiditySwapAdapterService @IsEthAddress('user') @IsEthAddress('assetToSwapFrom') @IsEthAddress('assetToSwapTo') + @IsEthAddress('augustus') @IsPositiveAmount('amountToSwap') @IsPositiveAmount('minAmountToReceive') { @@ -40,7 +45,9 @@ export default class LiquiditySwapAdapterService amountToSwap, minAmountToReceive, permitParams, - useEthPath, + augustus, + swapCallData, + swapAll, }: SwapAndDepositMethodType ): EthereumTransactionTypeExtended { const liquiditySwapContract = this.getContractInstance( @@ -50,12 +57,14 @@ export default class LiquiditySwapAdapterService const txCallback: () => Promise = this.generateTxCallback({ rawTxMethod: () => liquiditySwapContract.populateTransaction.swapAndDeposit( - [assetToSwapFrom], - [assetToSwapTo], - [amountToSwap], - [minAmountToReceive], - [permitParams], - [useEthPath || false] + assetToSwapFrom, + assetToSwapTo, + amountToSwap, + minAmountToReceive, + swapAll ? 4 + 2 * 32 : 0, + swapCallData, + augustus, + permitParams ), from: user, }); diff --git a/src/tx-builder/services/v2/LendingPool.ts b/src/tx-builder/services/v2/LendingPool.ts index c9c9c896..bc0db28f 100644 --- a/src/tx-builder/services/v2/LendingPool.ts +++ b/src/tx-builder/services/v2/LendingPool.ts @@ -1,4 +1,4 @@ -import { BigNumber, constants, utils } from 'ethers'; +import { BigNumber, constants, utils, BigNumberish, BytesLike } from 'ethers'; import { API_ETH_MOCK_ADDRESS, commonContractAddressBetweenMarketsV2, @@ -21,6 +21,7 @@ import { TokenMetadataType, transactionType, tStringDecimalUnits, + tEthereumAddress, } from '../../types'; import { getTxValue, parseNumber } from '../../utils/parsings'; import { LPValidator } from '../../validators/methodValidators'; @@ -42,10 +43,42 @@ import { IsPositiveAmount, IsPositiveOrMinusOneAmount, } from '../../validators/paramValidators'; -import LiquiditySwapAdapterInterface from '../../interfaces/LiquiditySwapAdapter'; +import LiquiditySwapAdapterInterface from '../../interfaces/LiquiditySwapAdapterParaswap'; import RepayWithCollateralAdapterInterface from '../../interfaces/RepayWithCollateralAdapter'; import BaseService from '../BaseService'; +const buildParaSwapLiquiditySwapParams = ( + assetToSwapTo: tEthereumAddress, + minAmountToReceive: BigNumberish, + swapAllBalanceOffset: BigNumberish, + swapCalldata: string | Buffer | BytesLike, + augustus: tEthereumAddress, + permitAmount: BigNumberish, + deadline: BigNumberish, + v: BigNumberish, + r: string | Buffer | BytesLike, + s: string | Buffer | BytesLike +) => { + return utils.defaultAbiCoder.encode( + [ + 'address', + 'uint256', + 'uint256', + 'bytes', + 'address', + 'tuple(uint256,uint256,uint8,bytes32,bytes32)', + ], + [ + assetToSwapTo, + minAmountToReceive, + swapAllBalanceOffset, + swapCalldata, + augustus, + [permitAmount, deadline, v, r, s], + ] + ); +}; + export default class LendingPool extends BaseService implements LendingPoolInterface { @@ -531,6 +564,7 @@ export default class LendingPool @IsEthAddress('fromAToken') @IsEthAddress('toAsset') @IsEthAddress('onBehalfOf') + @IsEthAddress('augustus') @IsPositiveAmount('fromAmount') @IsPositiveAmount('toAmount') { @@ -546,9 +580,26 @@ export default class LendingPool swapAll, onBehalfOf, referralCode, - useEthPath, + augustus, + swapCallData, }: LPSwapCollateral ): Promise { + console.log('inParams', { + user, + flash, + fromAsset, + fromAToken, + toAsset, + fromAmount, + toAmount, + maxSlippage, + permitSignature, + swapAll, + onBehalfOf, + referralCode, + augustus, + swapCallData, + }); const txs: EthereumTransactionTypeExtended[] = []; const permitParams = permitSignature || { @@ -601,6 +652,20 @@ export default class LendingPool this.lendingPoolAddress ); + const params = buildParaSwapLiquiditySwapParams( + toAsset, + amountSlippageConverted, + swapAll ? 4 + 2 * 32 : 0, + swapCallData, + augustus, + permitParams.amount, + permitParams.deadline, + permitParams.v, + permitParams.r, + permitParams.s + ); + console.log('ParaSwapLiquiditySwapParams', params); + if (flash) { const FLASHLOAN_PREMIUM_TOTAL: BigNumber = await lendingPoolContract.FLASHLOAN_PREMIUM_TOTAL(); const convertedAmountNoFees: string = BigNumber.from(convertedAmount) @@ -621,31 +686,6 @@ export default class LendingPool tokenDecimals ); - const params: string = utils.defaultAbiCoder.encode( - [ - 'address[]', - 'uint256[]', - 'bool[]', - 'uint256[]', - 'uint256[]', - 'uint8[]', - 'bytes32[]', - 'bytes32[]', - 'bool[]', - ], - [ - [toAsset], - [amountSlippageConverted], - [swapAll], - [permitParams.amount], - [permitParams.deadline], - [permitParams.v], - [permitParams.r], - [permitParams.s], - [useEthPath || false], - ] - ); - const txCallback: () => Promise = this.generateTxCallback( { rawTxMethod: () => @@ -674,18 +714,30 @@ export default class LendingPool return txs; } + console.log('swapAndDepositParams', { + user, + assetToSwapFrom: fromAsset, + assetToSwapTo: toAsset, + amountToSwap: convertedAmount, + minAmountToReceive: amountSlippageConverted, + swapAll, + swapCallData, + augustus, + permitParams, + }); + // Direct call to swap and deposit const swapAndDepositTx: EthereumTransactionTypeExtended = await this.liquiditySwapAdapterService.swapAndDeposit( { user, assetToSwapFrom: fromAsset, assetToSwapTo: toAsset, - amountToSwap: swapAll - ? constants.MaxUint256.toString() - : convertedAmount, + amountToSwap: convertedAmount, minAmountToReceive: amountSlippageConverted, + swapAll, + swapCallData, + augustus, permitParams, - useEthPath, } ); diff --git a/src/tx-builder/types/LendingPoolMethodTypes.ts b/src/tx-builder/types/LendingPoolMethodTypes.ts index 52629e35..46806345 100644 --- a/src/tx-builder/types/LendingPoolMethodTypes.ts +++ b/src/tx-builder/types/LendingPoolMethodTypes.ts @@ -1,3 +1,4 @@ +import { BytesLike } from 'ethers'; import { tEthereumAddress, tStringCurrencyUnits, @@ -69,7 +70,8 @@ export type LPSwapCollateral = { swapAll: boolean; onBehalfOf?: tEthereumAddress; referralCode?: string; - useEthPath?: boolean; + augustus: tEthereumAddress; + swapCallData: BytesLike; }; export type LPRepayWithCollateral = { diff --git a/src/tx-builder/types/LiquiditySwapAdapterMethodTypes.ts b/src/tx-builder/types/LiquiditySwapAdapterParaswapMethodTypes.ts similarity index 71% rename from src/tx-builder/types/LiquiditySwapAdapterMethodTypes.ts rename to src/tx-builder/types/LiquiditySwapAdapterParaswapMethodTypes.ts index 924e8a6c..7cd82394 100644 --- a/src/tx-builder/types/LiquiditySwapAdapterMethodTypes.ts +++ b/src/tx-builder/types/LiquiditySwapAdapterParaswapMethodTypes.ts @@ -1,3 +1,4 @@ +import { BytesLike } from 'ethers'; import { PermitSignature, tEthereumAddress } from '.'; export type SwapAndDepositMethodType = { @@ -7,5 +8,7 @@ export type SwapAndDepositMethodType = { amountToSwap: string; minAmountToReceive: string; permitParams: PermitSignature; - useEthPath?: boolean; + swapCallData: BytesLike; + augustus: tEthereumAddress; + swapAll: boolean; }; diff --git a/src/tx-builder/v2.ts b/src/tx-builder/v2.ts index 0d1a1752..aa1d71c3 100644 --- a/src/tx-builder/v2.ts +++ b/src/tx-builder/v2.ts @@ -8,8 +8,8 @@ import WETHGatewayInterface from './interfaces/WETHGateway'; import WETHGatewayService from './services/WETHGateway'; import BaseDebtTokenInterface from './interfaces/BaseDebtToken'; import BaseDebtToken from './services/BaseDebtToken'; -import LiquiditySwapAdapterService from './services/LiquiditySwapAdapter'; -import LiquiditySwapAdapterInterface from './interfaces/LiquiditySwapAdapter'; +import LiquiditySwapAdapterService from './services/LiquiditySwapAdapterParaswap'; +import LiquiditySwapAdapterInterface from './interfaces/LiquiditySwapAdapterParaswap'; import RepayWithCollateralAdapterService from './services/RepayWithCollateralAdapter'; import RepayWithCollateralAdapterInterface from './interfaces/RepayWithCollateralAdapter'; import AaveGovernanceV2Interface from './interfaces/v2/AaveGovernanceV2'; From f8d8fe3e8b503fb15bfa4e5a91287b0b70bc0f6d Mon Sep 17 00:00:00 2001 From: sakulstra Date: Fri, 2 Apr 2021 11:01:56 +0200 Subject: [PATCH 2/8] fix: proper offset fix: reuse function for offset fix: remove import --- .../services/LiquiditySwapAdapterParaswap.ts | 14 +++++++++++-- src/tx-builder/services/v2/LendingPool.ts | 21 ++++--------------- 2 files changed, 16 insertions(+), 19 deletions(-) diff --git a/src/tx-builder/services/LiquiditySwapAdapterParaswap.ts b/src/tx-builder/services/LiquiditySwapAdapterParaswap.ts index 26ca77a8..f670b25b 100644 --- a/src/tx-builder/services/LiquiditySwapAdapterParaswap.ts +++ b/src/tx-builder/services/LiquiditySwapAdapterParaswap.ts @@ -15,6 +15,15 @@ import { LiquiditySwapValidator } from '../validators/methodValidators'; import { IsEthAddress, IsPositiveAmount } from '../validators/paramValidators'; import BaseService from './BaseService'; +export function augustusFromAmountOffsetFromCalldata(calldata: string) { + switch (calldata.slice(0, 10)) { + case '0xda8567c8': // Augustus V3 multiSwap + return 4 + 32 + 2 * 32; + default: + throw new Error('Unrecognized function selector for Augustus'); + } +} + export default class LiquiditySwapAdapterService extends BaseService implements LiquiditySwapAdapterInterface { @@ -23,7 +32,6 @@ export default class LiquiditySwapAdapterService constructor(config: Configuration) { super(config, IParaSwapLiquiditySwapAdapter__factory); - console.log('nw', this.config.network); const { SWAP_COLLATERAL_ADAPTER } = commonContractAddressBetweenMarketsV2[ this.config.network ]; @@ -61,7 +69,9 @@ export default class LiquiditySwapAdapterService assetToSwapTo, amountToSwap, minAmountToReceive, - swapAll ? 4 + 2 * 32 : 0, + swapAll + ? augustusFromAmountOffsetFromCalldata(swapCallData as string) + : 0, swapCallData, augustus, permitParams diff --git a/src/tx-builder/services/v2/LendingPool.ts b/src/tx-builder/services/v2/LendingPool.ts index bc0db28f..ca5b276a 100644 --- a/src/tx-builder/services/v2/LendingPool.ts +++ b/src/tx-builder/services/v2/LendingPool.ts @@ -46,6 +46,7 @@ import { import LiquiditySwapAdapterInterface from '../../interfaces/LiquiditySwapAdapterParaswap'; import RepayWithCollateralAdapterInterface from '../../interfaces/RepayWithCollateralAdapter'; import BaseService from '../BaseService'; +import { augustusFromAmountOffsetFromCalldata } from '../LiquiditySwapAdapterParaswap'; const buildParaSwapLiquiditySwapParams = ( assetToSwapTo: tEthereumAddress, @@ -584,22 +585,6 @@ export default class LendingPool swapCallData, }: LPSwapCollateral ): Promise { - console.log('inParams', { - user, - flash, - fromAsset, - fromAToken, - toAsset, - fromAmount, - toAmount, - maxSlippage, - permitSignature, - swapAll, - onBehalfOf, - referralCode, - augustus, - swapCallData, - }); const txs: EthereumTransactionTypeExtended[] = []; const permitParams = permitSignature || { @@ -655,7 +640,9 @@ export default class LendingPool const params = buildParaSwapLiquiditySwapParams( toAsset, amountSlippageConverted, - swapAll ? 4 + 2 * 32 : 0, + swapAll + ? augustusFromAmountOffsetFromCalldata(swapCallData as string) + : 0, swapCallData, augustus, permitParams.amount, From a32d22010ae775cc546b8b20aeb261f108de7aee Mon Sep 17 00:00:00 2001 From: sakulstra Date: Fri, 2 Apr 2021 11:27:02 +0200 Subject: [PATCH 3/8] fix: remove the log --- src/tx-builder/services/v2/LendingPool.ts | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/src/tx-builder/services/v2/LendingPool.ts b/src/tx-builder/services/v2/LendingPool.ts index ca5b276a..f81ec8f8 100644 --- a/src/tx-builder/services/v2/LendingPool.ts +++ b/src/tx-builder/services/v2/LendingPool.ts @@ -651,7 +651,6 @@ export default class LendingPool permitParams.r, permitParams.s ); - console.log('ParaSwapLiquiditySwapParams', params); if (flash) { const FLASHLOAN_PREMIUM_TOTAL: BigNumber = await lendingPoolContract.FLASHLOAN_PREMIUM_TOTAL(); @@ -701,18 +700,6 @@ export default class LendingPool return txs; } - console.log('swapAndDepositParams', { - user, - assetToSwapFrom: fromAsset, - assetToSwapTo: toAsset, - amountToSwap: convertedAmount, - minAmountToReceive: amountSlippageConverted, - swapAll, - swapCallData, - augustus, - permitParams, - }); - // Direct call to swap and deposit const swapAndDepositTx: EthereumTransactionTypeExtended = await this.liquiditySwapAdapterService.swapAndDeposit( { From ec2bfc96eb616b357f99b3fd064d568e6812bccd Mon Sep 17 00:00:00 2001 From: sakulstra Date: Tue, 6 Apr 2021 10:29:52 +0200 Subject: [PATCH 4/8] fix: add log --- src/tx-builder/services/v2/LendingPool.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tx-builder/services/v2/LendingPool.ts b/src/tx-builder/services/v2/LendingPool.ts index f81ec8f8..eeec6e68 100644 --- a/src/tx-builder/services/v2/LendingPool.ts +++ b/src/tx-builder/services/v2/LendingPool.ts @@ -130,6 +130,7 @@ export default class LendingPool { user, reserve, amount, onBehalfOf, referralCode }: LPDepositParamsType ): Promise { if (reserve.toLowerCase() === API_ETH_MOCK_ADDRESS.toLowerCase()) { + console.log(this.lendingPoolAddress, this.market); return this.wethGatewayService.depositETH({ lendingPool: this.lendingPoolAddress, user, From 90ce71d11dc91218cff62831f500593e8e516723 Mon Sep 17 00:00:00 2001 From: sakulstra Date: Wed, 7 Apr 2021 23:44:36 +0200 Subject: [PATCH 5/8] fix: remove console.log --- src/tx-builder/services/v2/LendingPool.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/tx-builder/services/v2/LendingPool.ts b/src/tx-builder/services/v2/LendingPool.ts index eeec6e68..f81ec8f8 100644 --- a/src/tx-builder/services/v2/LendingPool.ts +++ b/src/tx-builder/services/v2/LendingPool.ts @@ -130,7 +130,6 @@ export default class LendingPool { user, reserve, amount, onBehalfOf, referralCode }: LPDepositParamsType ): Promise { if (reserve.toLowerCase() === API_ETH_MOCK_ADDRESS.toLowerCase()) { - console.log(this.lendingPoolAddress, this.market); return this.wethGatewayService.depositETH({ lendingPool: this.lendingPoolAddress, user, From 65805ab638874dd0d3d72736d340f06dfcb0d471 Mon Sep 17 00:00:00 2001 From: sakulstra Date: Thu, 15 Apr 2021 11:57:54 +0200 Subject: [PATCH 6/8] fix: alter interface --- src/tx-builder/services/v2/LendingPool.ts | 12 +++--------- src/tx-builder/types/LendingPoolMethodTypes.ts | 3 +-- 2 files changed, 4 insertions(+), 11 deletions(-) diff --git a/src/tx-builder/services/v2/LendingPool.ts b/src/tx-builder/services/v2/LendingPool.ts index f81ec8f8..3b45ccca 100644 --- a/src/tx-builder/services/v2/LendingPool.ts +++ b/src/tx-builder/services/v2/LendingPool.ts @@ -567,7 +567,7 @@ export default class LendingPool @IsEthAddress('onBehalfOf') @IsEthAddress('augustus') @IsPositiveAmount('fromAmount') - @IsPositiveAmount('toAmount') + @IsPositiveAmount('minToAmount') { user, flash, @@ -575,8 +575,7 @@ export default class LendingPool fromAToken, toAsset, fromAmount, - toAmount, - maxSlippage, + minToAmount, permitSignature, swapAll, onBehalfOf, @@ -623,13 +622,8 @@ export default class LendingPool const tokenToDecimals: number = await this.erc20Service.decimalsOf(toAsset); - const amountSlippage = ( - Number(toAmount) - - (Number(toAmount) * Number(maxSlippage)) / 100 - ).toString(); - const amountSlippageConverted: string = parseNumber( - amountSlippage, + minToAmount, tokenToDecimals ); diff --git a/src/tx-builder/types/LendingPoolMethodTypes.ts b/src/tx-builder/types/LendingPoolMethodTypes.ts index 46806345..00fe7d85 100644 --- a/src/tx-builder/types/LendingPoolMethodTypes.ts +++ b/src/tx-builder/types/LendingPoolMethodTypes.ts @@ -64,8 +64,7 @@ export type LPSwapCollateral = { fromAToken: tEthereumAddress; toAsset: tEthereumAddress; // List of the addresses of the reserve to be swapped to and deposited fromAmount: tStringCurrencyUnits; // List of amounts to be swapped. If the amount exceeds the balance, the total balance is used for the swap - toAmount: tStringCurrencyUnits; - maxSlippage: string; + minToAmount: tStringCurrencyUnits; permitSignature?: PermitSignature; swapAll: boolean; onBehalfOf?: tEthereumAddress; From f0cd194e74ac59e16e0fd2fd501028e9fdfb476e Mon Sep 17 00:00:00 2001 From: sakulstra Date: Mon, 19 Apr 2021 19:54:24 +0200 Subject: [PATCH 7/8] fix: updadte offsets --- src/tx-builder/services/LiquiditySwapAdapterParaswap.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/tx-builder/services/LiquiditySwapAdapterParaswap.ts b/src/tx-builder/services/LiquiditySwapAdapterParaswap.ts index f670b25b..9c39021d 100644 --- a/src/tx-builder/services/LiquiditySwapAdapterParaswap.ts +++ b/src/tx-builder/services/LiquiditySwapAdapterParaswap.ts @@ -19,6 +19,14 @@ export function augustusFromAmountOffsetFromCalldata(calldata: string) { switch (calldata.slice(0, 10)) { case '0xda8567c8': // Augustus V3 multiSwap return 4 + 32 + 2 * 32; + case '0x58b9d179': // Augustus V4 swapOnUniswap + return 4; + case '0x0863b7ac': // Augustus V4 swapOnUniswapFork + return 4 + 2 * 32; + case '0x8f00eccb': // Augustus V4 multiSwap + return 4 + 32 + 32; + case '0xec1d21dd': // Augustus V4 megaSwap + return 4 + 32 + 32; default: throw new Error('Unrecognized function selector for Augustus'); } From 5986936e5debb70658d1408d5a4f08e008692e0d Mon Sep 17 00:00:00 2001 From: sakulstra Date: Wed, 16 Jun 2021 09:31:14 +0200 Subject: [PATCH 8/8] fix: update address for audit --- src/tx-builder/config/v2/addresses.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tx-builder/config/v2/addresses.ts b/src/tx-builder/config/v2/addresses.ts index a2790853..463e1d93 100644 --- a/src/tx-builder/config/v2/addresses.ts +++ b/src/tx-builder/config/v2/addresses.ts @@ -37,7 +37,7 @@ export const commonContractAddressBetweenMarketsV2: CommonConfigType = { LEND_TO_AAVE_MIGRATOR: '0x317625234562b1526ea2fac4030ea499c5291de4', WETH_GATEWAY: '0xcc9a0B7c43DC2a5F023Bb9b738E45B0Ef6B06E04', FAUCET: '', - SWAP_COLLATERAL_ADAPTER: '0xc91864a5a1e2f52addfb69e31b89a3b7783733c3', + SWAP_COLLATERAL_ADAPTER: '0x135896DE8421be2ec868E0b811006171D9df802A', REPAY_WITH_COLLATERAL_ADAPTER: '0x498c5431eb517101582988fbb36431ddaac8f4b1', FLASHLIQUIDATION: '0xE377fB98512D7b04827e56BC84e1838804a8019D', INCENTIVES_CONTROLLER: '0xd784927Ff2f95ba542BfC824c8a8a98F3495f6b5',