Skip to content

Commit

Permalink
Merge pull request paraswap#657 from paraswap/feat/BACK-1528-etherfi
Browse files Browse the repository at this point in the history
Feat/back 1528 etherfi
  • Loading branch information
mwamedacen authored Apr 25, 2024
2 parents a64d283 + 4c05a3e commit ac24c10
Show file tree
Hide file tree
Showing 5 changed files with 193 additions and 1 deletion.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@paraswap/dex-lib",
"version": "2.48.3",
"version": "2.49.0",
"main": "build/index.js",
"types": "build/index.d.ts",
"repository": "https://github.com/paraswap/paraswap-dex-lib",
Expand Down
9 changes: 9 additions & 0 deletions src/abi/etherfi/eETHPool.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[
{
"inputs": [],
"name": "deposit",
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
"stateMutability": "payable",
"type": "function"
}
]
20 changes: 20 additions & 0 deletions src/abi/etherfi/weETH.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
[
{
"inputs": [
{ "internalType": "uint256", "name": "_eETHAmount", "type": "uint256" }
],
"name": "wrap",
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "uint256", "name": "_weETHAmount", "type": "uint256" }
],
"name": "unwrap",
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
"stateMutability": "nonpayable",
"type": "function"
}
]
161 changes: 161 additions & 0 deletions src/dex/etherfi.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
import { Interface, JsonFragment } from '@ethersproject/abi';
import { ETHER_ADDRESS, NULL_ADDRESS, SwapSide } from '../constants';
import { AdapterExchangeParam, Address, SimpleExchangeParam } from '../types';
import { IDexTxBuilder } from './idex';
import { SimpleExchange } from './simple-exchange';
import eETHPoolABI from '../abi/etherfi/eETHPool.json';
import weETHABI from '../abi/etherfi/weETH.json';
import { IDexHelper } from '../dex-helper';
import { isETHAddress } from '../utils';
import { assert } from 'ts-essentials';
import { WethFunctions } from './weth/types';

type EtherFiData = void;

type eETHPoolDepositParam = [];
type weETHWrap = [_eETHAmount: string];
type weETHUnwrap = [_weETHAmount: string];

type EtherFiParam = eETHPoolDepositParam | weETHWrap | weETHUnwrap;

enum EtherFiFunctions {
deposit = 'deposit',
wrap = 'wrap',
unwrap = 'unwrap',
}

const EtherFiConfig: Record<
number,
{ eETH: string; eETHPool: string; weETH: string }
> = {
1: {
eETH: '0x35fa164735182de50811e8e2e824cfb9b6118ac2',
eETHPool: '0x308861a430be4cce5502d0a12724771fc6daf216',
weETH: '0xcd5fe23c85820f7b72d0926fc9b05b43e359b7ee',
},
};

export class EtherFi
extends SimpleExchange
implements IDexTxBuilder<EtherFiData, EtherFiParam>
{
static dexKeys = ['etherfi'];

eETHPoolInterface: Interface;
weETHInterface: Interface;
needWrapNative = false;

eETH: string;
eETHPool: string;
weETH: string;

constructor(dexHelper: IDexHelper) {
super(dexHelper, 'etherfi');

this.eETHPoolInterface = new Interface(eETHPoolABI as JsonFragment[]);
this.weETHInterface = new Interface(weETHABI as JsonFragment[]);

this.eETH = EtherFiConfig[this.network].eETH.toLowerCase();
this.eETHPool = EtherFiConfig[this.network].eETHPool.toLowerCase();
this.weETH = EtherFiConfig[this.network].weETH.toLowerCase();
}

is_eETH = (token: string) => token.toLowerCase() === this.eETH;
is_weETH = (token: string) => token.toLowerCase() === this.weETH;

async getSimpleParam(
srcToken: string,
destToken: string,
srcAmount: string,
destAmount: string,
data: EtherFiData,
side: SwapSide,
): Promise<SimpleExchangeParam> {
const [Interface, swapCallee, swapFunction, swapFunctionParams] = ((): [
Interface,
Address,
EtherFiFunctions,
EtherFiParam,
] => {
if (this.is_weETH(destToken)) {
assert(this.is_eETH(srcToken), 'srcToken should be eETH');
return [
this.weETHInterface,
this.weETH,
EtherFiFunctions.wrap,
[srcAmount],
];
}

if (this.is_weETH(srcToken)) {
assert(this.is_eETH(destToken), 'destToken should be eETH');
return [
this.weETHInterface,
this.weETH,
EtherFiFunctions.unwrap,
[srcAmount],
];
}

if (this.is_eETH(destToken)) {
assert(
this.isWETH(srcToken) || isETHAddress(srcToken),
'srcToken should be (w)eth',
);
return [
this.eETHPoolInterface,
this.eETHPool,
EtherFiFunctions.deposit,
[],
];
}

throw new Error('LOGIC ERROR');
})();

const swapData = Interface.encodeFunctionData(
swapFunction,
swapFunctionParams,
);

// if src token is WETH, we need to withdraw from weth and pass eth value on call. For other cases, we need to approve and perform call
const isSrcTokenWeth = this.isWETH(srcToken);

return this.buildSimpleParamWithoutWETHConversion(
isSrcTokenWeth ? ETHER_ADDRESS : srcToken,
srcAmount,
destToken,
destAmount,
swapData,
swapCallee,
swapCallee,
'0',
isSrcTokenWeth
? {
callees: [this.dexHelper.config.data.wrappedNativeTokenAddress],
calldata: [
this.erc20Interface.encodeFunctionData(WethFunctions.withdraw, [
srcAmount,
]),
],
values: ['0'],
}
: undefined,
);
}

getAdapterParam(
srcToken: string,
destToken: string,
srcAmount: string,
destAmount: string,
data: EtherFiData,
side: SwapSide,
): AdapterExchangeParam {
return {
targetExchange: NULL_ADDRESS,
payload: '0x',
networkFee: '0',
};
}
}
2 changes: 2 additions & 0 deletions src/dex/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ import { Dexalot } from './dexalot/dexalot';
import { Smardex } from './smardex/smardex';
import { Wombat } from './wombat/wombat';
import { Swell } from './swell/swell';
import { EtherFi } from './etherfi';

const LegacyDexes = [
CurveV2,
Expand All @@ -108,6 +109,7 @@ const LegacyDexes = [
Jarvis,
Lido,
AugustusRFQOrder,
EtherFi,
];

const Dexes = [
Expand Down

0 comments on commit ac24c10

Please sign in to comment.