@paraswap/dex-lib 3.6.3 → 3.6.4-transmuter.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/abi/Redstone.json +739 -0
- package/build/abi/aavev3stata/Factory.json +128 -0
- package/build/abi/aavev3stata/Token.json +735 -0
- package/build/abi/angle-transmuter/MorphoOracle.json +193 -0
- package/build/abi/angle-transmuter/MorphoVault.json +2506 -0
- package/build/abi/angle-transmuter/Pyth.json +1534 -0
- package/build/abi/angle-transmuter/Transmuter.json +1711 -0
- package/build/abi/angle-transmuter/TransmuterSidechain.json +1798 -0
- package/build/abi/idle-dao/idle-cdo-factory.json +38 -0
- package/build/abi/idle-dao/idle-cdo.json +1245 -0
- package/build/dex/aave-v1/aave-v1.d.ts +2 -1
- package/build/dex/aave-v1/aave-v1.js +22 -0
- package/build/dex/aave-v1/aave-v1.js.map +1 -1
- package/build/dex/aave-v3-stata/aave-v3-stata.d.ts +40 -0
- package/build/dex/aave-v3-stata/aave-v3-stata.js +309 -0
- package/build/dex/aave-v3-stata/aave-v3-stata.js.map +1 -0
- package/build/dex/aave-v3-stata/config.d.ts +4 -0
- package/build/dex/aave-v3-stata/config.js +46 -0
- package/build/dex/aave-v3-stata/config.js.map +1 -0
- package/build/dex/aave-v3-stata/tokens.d.ts +9 -0
- package/build/dex/aave-v3-stata/tokens.js +37 -0
- package/build/dex/aave-v3-stata/tokens.js.map +1 -0
- package/build/dex/aave-v3-stata/types.d.ts +42 -0
- package/build/dex/aave-v3-stata/types.js +18 -0
- package/build/dex/aave-v3-stata/types.js.map +1 -0
- package/build/dex/aave-v3-stata/utils.d.ts +4 -0
- package/build/dex/aave-v3-stata/utils.js +67 -0
- package/build/dex/aave-v3-stata/utils.js.map +1 -0
- package/build/dex/angle-transmuter/angle-transmuter-pool.d.ts +61 -0
- package/build/dex/angle-transmuter/angle-transmuter-pool.js +419 -0
- package/build/dex/angle-transmuter/angle-transmuter-pool.js.map +1 -0
- package/build/dex/angle-transmuter/angle-transmuter.d.ts +60 -0
- package/build/dex/angle-transmuter/angle-transmuter.js +282 -0
- package/build/dex/angle-transmuter/angle-transmuter.js.map +1 -0
- package/build/dex/angle-transmuter/backedOracle.d.ts +19 -0
- package/build/dex/angle-transmuter/backedOracle.js +56 -0
- package/build/dex/angle-transmuter/backedOracle.js.map +1 -0
- package/build/dex/angle-transmuter/config.d.ts +4 -0
- package/build/dex/angle-transmuter/config.js +50 -0
- package/build/dex/angle-transmuter/config.js.map +1 -0
- package/build/dex/angle-transmuter/constants.d.ts +9 -0
- package/build/dex/angle-transmuter/constants.js +136 -0
- package/build/dex/angle-transmuter/constants.js.map +1 -0
- package/build/dex/angle-transmuter/morphoOracle.d.ts +42 -0
- package/build/dex/angle-transmuter/morphoOracle.js +179 -0
- package/build/dex/angle-transmuter/morphoOracle.js.map +1 -0
- package/build/dex/angle-transmuter/morphoVault.d.ts +20 -0
- package/build/dex/angle-transmuter/morphoVault.js +84 -0
- package/build/dex/angle-transmuter/morphoVault.js.map +1 -0
- package/build/dex/angle-transmuter/pyth.d.ts +19 -0
- package/build/dex/angle-transmuter/pyth.js +70 -0
- package/build/dex/angle-transmuter/pyth.js.map +1 -0
- package/build/dex/angle-transmuter/redstone.d.ts +20 -0
- package/build/dex/angle-transmuter/redstone.js +73 -0
- package/build/dex/angle-transmuter/redstone.js.map +1 -0
- package/build/dex/angle-transmuter/transmuter.d.ts +55 -0
- package/build/dex/angle-transmuter/transmuter.js +398 -0
- package/build/dex/angle-transmuter/transmuter.js.map +1 -0
- package/build/dex/angle-transmuter/types.d.ts +189 -0
- package/build/dex/angle-transmuter/types.js +33 -0
- package/build/dex/angle-transmuter/types.js.map +1 -0
- package/build/dex/angle-transmuter/utils.d.ts +9 -0
- package/build/dex/angle-transmuter/utils.js +257 -0
- package/build/dex/angle-transmuter/utils.js.map +1 -0
- package/build/dex/idle-dao/config.d.ts +6 -0
- package/build/dex/idle-dao/config.js +297 -0
- package/build/dex/idle-dao/config.js.map +1 -0
- package/build/dex/idle-dao/idle-dao-pool.d.ts +56 -0
- package/build/dex/idle-dao/idle-dao-pool.js +176 -0
- package/build/dex/idle-dao/idle-dao-pool.js.map +1 -0
- package/build/dex/idle-dao/idle-dao-pooling-pool.d.ts +16 -0
- package/build/dex/idle-dao/idle-dao-pooling-pool.js +57 -0
- package/build/dex/idle-dao/idle-dao-pooling-pool.js.map +1 -0
- package/build/dex/idle-dao/idle-dao.d.ts +41 -0
- package/build/dex/idle-dao/idle-dao.js +238 -0
- package/build/dex/idle-dao/idle-dao.js.map +1 -0
- package/build/dex/idle-dao/scripts.d.ts +9 -0
- package/build/dex/idle-dao/scripts.js +552 -0
- package/build/dex/idle-dao/scripts.js.map +1 -0
- package/build/dex/idle-dao/tokens.d.ts +9 -0
- package/build/dex/idle-dao/tokens.js +65 -0
- package/build/dex/idle-dao/tokens.js.map +1 -0
- package/build/dex/idle-dao/types.d.ts +34 -0
- package/build/dex/idle-dao/types.js +11 -0
- package/build/dex/idle-dao/types.js.map +1 -0
- package/build/dex/idle-dao/utils.d.ts +8 -0
- package/build/dex/idle-dao/utils.js +146 -0
- package/build/dex/idle-dao/utils.js.map +1 -0
- package/build/dex/index.js +2 -0
- package/build/dex/index.js.map +1 -1
- package/build/dex/maverick-v2/maverick-v2.js +1 -1
- package/build/dex/maverick-v2/maverick-v2.js.map +1 -1
- package/build/dex/maverick-v2/types.d.ts +1 -1
- package/build/dex/platypus/platypus.d.ts +2 -1
- package/build/dex/platypus/platypus.js +31 -0
- package/build/dex/platypus/platypus.js.map +1 -1
- package/build/dex/swaap-v1/swaap-v1.d.ts +2 -1
- package/build/dex/swaap-v1/swaap-v1.js +10 -0
- package/build/dex/swaap-v1/swaap-v1.js.map +1 -1
- package/build/lib/chainlink.d.ts +2 -0
- package/build/lib/chainlink.js +9 -0
- package/build/lib/chainlink.js.map +1 -1
- package/build/utils.d.ts +1 -1
- package/package.json +1 -1
- package/src/abi/Redstone.json +739 -0
- package/src/abi/angle-transmuter/ChainlinkAccessControlledOffchainAggregator.json +1246 -0
- package/src/abi/angle-transmuter/ChainlinkEACAggregatorProxy.json +509 -0
- package/src/abi/angle-transmuter/Getters.json +568 -0
- package/src/abi/angle-transmuter/MorphoOracle.json +193 -0
- package/src/abi/angle-transmuter/MorphoVault.json +2506 -0
- package/src/abi/angle-transmuter/Pyth.json +1534 -0
- package/src/abi/angle-transmuter/Swapper.json +329 -0
- package/src/abi/angle-transmuter/Transmuter.json +1711 -0
- package/src/abi/angle-transmuter/TransmuterSidechain.json +1798 -0
- package/src/dex/angle-transmuter/angle-transmuter-e2e.test.ts +156 -0
- package/src/dex/angle-transmuter/angle-transmuter-events.test.ts +365 -0
- package/src/dex/angle-transmuter/angle-transmuter-integration.test.ts +384 -0
- package/src/dex/angle-transmuter/angle-transmuter-pool.ts +856 -0
- package/src/dex/angle-transmuter/angle-transmuter.ts +443 -0
- package/src/dex/angle-transmuter/backedOracle.ts +91 -0
- package/src/dex/angle-transmuter/config.ts +50 -0
- package/src/dex/angle-transmuter/constants.ts +138 -0
- package/src/dex/angle-transmuter/morphoOracle.ts +335 -0
- package/src/dex/angle-transmuter/morphoVault.ts +134 -0
- package/src/dex/angle-transmuter/pyth.ts +105 -0
- package/src/dex/angle-transmuter/redstone.ts +114 -0
- package/src/dex/angle-transmuter/transmuter.ts +619 -0
- package/src/dex/angle-transmuter/types.ts +203 -0
- package/src/dex/angle-transmuter/utils.ts +358 -0
- package/src/dex/index.ts +2 -0
- package/src/dex/maverick-v2/maverick-v2.ts +1 -1
- package/src/dex/maverick-v2/types.ts +1 -1
- package/src/lib/chainlink.ts +15 -0
- package/tests/constants-e2e.ts +50 -5
- package/build/dex/bProtocol.d.ts +0 -18
- package/build/dex/bProtocol.js +0 -39
- package/build/dex/bProtocol.js.map +0 -1
- package/build/dex/bancor.d.ts +0 -26
- package/build/dex/bancor.js +0 -58
- package/build/dex/bancor.js.map +0 -1
- package/build/dex/compound.d.ts +0 -18
- package/build/dex/compound.js +0 -46
- package/build/dex/compound.js.map +0 -1
- package/build/dex/curve-v2.d.ts +0 -58
- package/build/dex/curve-v2.js +0 -180
- package/build/dex/curve-v2.js.map +0 -1
- package/build/dex/dodo-v1.d.ts +0 -33
- package/build/dex/dodo-v1.js +0 -63
- package/build/dex/dodo-v1.js.map +0 -1
- package/build/dex/etherfi/etherfi.d.ts +0 -26
- package/build/dex/etherfi/etherfi.js +0 -96
- package/build/dex/etherfi/etherfi.js.map +0 -1
- package/build/dex/lido.d.ts +0 -19
- package/build/dex/lido.js +0 -42
- package/build/dex/lido.js.map +0 -1
- package/build/dex/onebit.d.ts +0 -25
- package/build/dex/onebit.js +0 -42
- package/build/dex/onebit.js.map +0 -1
- package/build/dex/sdai/config.d.ts +0 -11
- package/build/dex/sdai/config.js +0 -21
- package/build/dex/sdai/config.js.map +0 -1
- package/build/dex/sdai/constants.d.ts +0 -2
- package/build/dex/sdai/constants.js +0 -6
- package/build/dex/sdai/constants.js.map +0 -1
- package/build/dex/sdai/scripts/validate-state.d.ts +0 -1
- package/build/dex/sdai/scripts/validate-state.js +0 -102
- package/build/dex/sdai/scripts/validate-state.js.map +0 -1
- package/build/dex/sdai/sdai-pool.d.ts +0 -16
- package/build/dex/sdai/sdai-pool.js +0 -85
- package/build/dex/sdai/sdai-pool.js.map +0 -1
- package/build/dex/sdai/sdai.d.ts +0 -51
- package/build/dex/sdai/sdai.js +0 -172
- package/build/dex/sdai/sdai.js.map +0 -1
- package/build/dex/sdai/types.d.ts +0 -21
- package/build/dex/sdai/types.js +0 -11
- package/build/dex/sdai/types.js.map +0 -1
- package/build/dex/sdai/utils.d.ts +0 -4
- package/build/dex/sdai/utils.js +0 -39
- package/build/dex/sdai/utils.js.map +0 -1
- package/build/dex/smoothy.d.ts +0 -26
- package/build/dex/smoothy.js +0 -48
- package/build/dex/smoothy.js.map +0 -1
- package/build/dex/stable-pool.d.ts +0 -28
- package/build/dex/stable-pool.js +0 -62
- package/build/dex/stable-pool.js.map +0 -1
- package/build/dex/trader-joe-v2.1.d.ts +0 -43
- package/build/dex/trader-joe-v2.1.js +0 -79
- package/build/dex/trader-joe-v2.1.js.map +0 -1
|
@@ -0,0 +1,443 @@
|
|
|
1
|
+
import { AsyncOrSync } from 'ts-essentials';
|
|
2
|
+
import {
|
|
3
|
+
Token,
|
|
4
|
+
Address,
|
|
5
|
+
ExchangePrices,
|
|
6
|
+
PoolPrices,
|
|
7
|
+
AdapterExchangeParam,
|
|
8
|
+
SimpleExchangeParam,
|
|
9
|
+
PoolLiquidity,
|
|
10
|
+
Logger,
|
|
11
|
+
NumberAsString,
|
|
12
|
+
DexExchangeParam,
|
|
13
|
+
} from '../../types';
|
|
14
|
+
import { SwapSide, Network } from '../../constants';
|
|
15
|
+
import * as CALLDATA_GAS_COST from '../../calldata-gas-cost';
|
|
16
|
+
import { getDexKeysWithNetwork } from '../../utils';
|
|
17
|
+
import { Context, IDex } from '../../dex/idex';
|
|
18
|
+
import { IDexHelper } from '../../dex-helper/idex-helper';
|
|
19
|
+
import { AngleTransmuterData, DexParams } from './types';
|
|
20
|
+
import { SimpleExchange } from '../simple-exchange';
|
|
21
|
+
import { AngleTransmuterConfig, Adapters } from './config';
|
|
22
|
+
import { AngleTransmuterEventPool } from './angle-transmuter-pool';
|
|
23
|
+
import { Interface, formatUnits, parseUnits } from 'ethers/lib/utils';
|
|
24
|
+
import { TransmuterSubscriber } from './transmuter';
|
|
25
|
+
import ERC20ABI from '../../abi/erc20.json';
|
|
26
|
+
|
|
27
|
+
const TransmuterGasCost = 0;
|
|
28
|
+
|
|
29
|
+
export class AngleTransmuter
|
|
30
|
+
extends SimpleExchange
|
|
31
|
+
implements IDex<AngleTransmuterData>
|
|
32
|
+
{
|
|
33
|
+
protected eventPools: { [key: string]: AngleTransmuterEventPool } = {};
|
|
34
|
+
protected supportedTokensMap: {
|
|
35
|
+
[key: string]: { [address: string]: boolean };
|
|
36
|
+
} = {};
|
|
37
|
+
protected supportedTokens: { [key: string]: Token[] } = {};
|
|
38
|
+
protected transmuterUSDLiquidity: { [key: string]: number } = {};
|
|
39
|
+
stablecoinList: string[];
|
|
40
|
+
|
|
41
|
+
public static erc20Interface = new Interface(ERC20ABI);
|
|
42
|
+
|
|
43
|
+
readonly hasConstantPriceLargeAmounts = false;
|
|
44
|
+
readonly needWrapNative = true;
|
|
45
|
+
|
|
46
|
+
readonly isFeeOnTransferSupported = false;
|
|
47
|
+
|
|
48
|
+
public static dexKeysWithNetwork: { key: string; networks: Network[] }[] =
|
|
49
|
+
getDexKeysWithNetwork(AngleTransmuterConfig);
|
|
50
|
+
|
|
51
|
+
logger: Logger;
|
|
52
|
+
|
|
53
|
+
constructor(
|
|
54
|
+
readonly network: Network,
|
|
55
|
+
readonly dexKey: string,
|
|
56
|
+
readonly dexHelper: IDexHelper,
|
|
57
|
+
protected adapters = Adapters[network] || {},
|
|
58
|
+
protected params: DexParams = AngleTransmuterConfig[dexKey][network],
|
|
59
|
+
) {
|
|
60
|
+
super(dexHelper, dexKey);
|
|
61
|
+
this.logger = dexHelper.getLogger(dexKey);
|
|
62
|
+
this.stablecoinList = Object.keys(params);
|
|
63
|
+
this.stablecoinList.forEach(stablecoin => {
|
|
64
|
+
this.supportedTokensMap[stablecoin] = {};
|
|
65
|
+
this.supportedTokens[stablecoin] = [];
|
|
66
|
+
this.transmuterUSDLiquidity[stablecoin] = 0;
|
|
67
|
+
});
|
|
68
|
+
this.stablecoinList.forEach(stablecoin => {
|
|
69
|
+
this.supportedTokensMap[stablecoin][
|
|
70
|
+
params[stablecoin as keyof DexParams]!.stablecoin.address.toLowerCase()
|
|
71
|
+
] = true;
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// Initialize pricing is called once in the start of
|
|
76
|
+
// pricing service. It is intended to setup the integration
|
|
77
|
+
// for pricing requests. It is optional for a DEX to
|
|
78
|
+
// implement this function
|
|
79
|
+
async initializePricing(blockNumber: number) {
|
|
80
|
+
for (const stablecoin of this.stablecoinList) {
|
|
81
|
+
const config = await AngleTransmuterEventPool.getConfig(
|
|
82
|
+
this.params[stablecoin as keyof DexParams]!,
|
|
83
|
+
blockNumber,
|
|
84
|
+
this.dexHelper.multiContract,
|
|
85
|
+
);
|
|
86
|
+
config.collaterals.forEach(
|
|
87
|
+
(token: Address) =>
|
|
88
|
+
(this.supportedTokensMap[stablecoin][token.toLowerCase()] = true),
|
|
89
|
+
);
|
|
90
|
+
this.eventPools[stablecoin] = new AngleTransmuterEventPool(
|
|
91
|
+
this.dexKey,
|
|
92
|
+
this.network,
|
|
93
|
+
this.dexHelper,
|
|
94
|
+
this.logger,
|
|
95
|
+
config,
|
|
96
|
+
);
|
|
97
|
+
await this.eventPools[stablecoin].initialize(blockNumber);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// Returns the list of contract adapters (name and index)
|
|
102
|
+
// for a buy/sell. Return null if there are no adapters.
|
|
103
|
+
getAdapters(side: SwapSide): { name: string; index: number }[] | null {
|
|
104
|
+
return this.adapters[side] ? this.adapters[side] : null;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// Returns list of pool identifiers that can be used
|
|
108
|
+
// for a given swap. poolIdentifiers must be unique
|
|
109
|
+
// across DEXes. It is recommended to use
|
|
110
|
+
// ${dexKey}_${poolAddress} as a poolIdentifier
|
|
111
|
+
async getPoolIdentifiers(
|
|
112
|
+
srcToken: Token,
|
|
113
|
+
destToken: Token,
|
|
114
|
+
side: SwapSide,
|
|
115
|
+
blockNumber: number,
|
|
116
|
+
): Promise<string[]> {
|
|
117
|
+
const knownInfo = this._knownAddress(srcToken, destToken);
|
|
118
|
+
if (!knownInfo.known) return [];
|
|
119
|
+
return [`${this.dexKey}_${knownInfo.agToken!.toLowerCase()}`];
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// Returns pool prices for amounts.
|
|
123
|
+
// If limitPools is defined only pools in limitPools
|
|
124
|
+
// should be used. If limitPools is undefined then
|
|
125
|
+
// any pools can be used.
|
|
126
|
+
async getPricesVolume(
|
|
127
|
+
srcToken: Token,
|
|
128
|
+
destToken: Token,
|
|
129
|
+
amounts: bigint[],
|
|
130
|
+
side: SwapSide,
|
|
131
|
+
blockNumber: number,
|
|
132
|
+
limitPools?: string[],
|
|
133
|
+
): Promise<null | ExchangePrices<AngleTransmuterData>> {
|
|
134
|
+
const knownInfo = this._knownAddress(srcToken, destToken);
|
|
135
|
+
const pool = `${this.dexKey}_${knownInfo.agToken!.toLowerCase()}`;
|
|
136
|
+
if (
|
|
137
|
+
!knownInfo.known ||
|
|
138
|
+
(limitPools && limitPools.length > 0 && !limitPools.includes(pool))
|
|
139
|
+
)
|
|
140
|
+
return null;
|
|
141
|
+
|
|
142
|
+
const fiat = knownInfo.fiatName! as keyof DexParams;
|
|
143
|
+
const preProcessDecimals =
|
|
144
|
+
side === SwapSide.SELL ? srcToken.decimals : destToken.decimals;
|
|
145
|
+
const postProcessDecimals =
|
|
146
|
+
side === SwapSide.SELL ? destToken.decimals : srcToken.decimals;
|
|
147
|
+
const unitVolume = 1;
|
|
148
|
+
const amountsFloat = amounts.map(amount =>
|
|
149
|
+
Number.parseFloat(formatUnits(amount.toString(), preProcessDecimals)),
|
|
150
|
+
);
|
|
151
|
+
|
|
152
|
+
const prices = await this.eventPools[fiat]!.getAmountOut(
|
|
153
|
+
srcToken.address,
|
|
154
|
+
destToken.address,
|
|
155
|
+
side,
|
|
156
|
+
[unitVolume, ...amountsFloat],
|
|
157
|
+
blockNumber,
|
|
158
|
+
);
|
|
159
|
+
|
|
160
|
+
if (!prices) return null;
|
|
161
|
+
|
|
162
|
+
const pricesBigInt = prices.map(price =>
|
|
163
|
+
BigInt(
|
|
164
|
+
parseUnits(
|
|
165
|
+
price.toFixed(postProcessDecimals).toString(),
|
|
166
|
+
postProcessDecimals,
|
|
167
|
+
).toString(),
|
|
168
|
+
),
|
|
169
|
+
);
|
|
170
|
+
|
|
171
|
+
return [
|
|
172
|
+
{
|
|
173
|
+
prices: pricesBigInt.slice(1),
|
|
174
|
+
unit: pricesBigInt[0],
|
|
175
|
+
gasCost: TransmuterGasCost,
|
|
176
|
+
exchange: this.dexKey,
|
|
177
|
+
data: { exchange: this.params[fiat]!.transmuter },
|
|
178
|
+
poolAddresses: [this.params[fiat]!.transmuter],
|
|
179
|
+
},
|
|
180
|
+
];
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// Returns estimated gas cost of calldata for this DEX in multiSwap
|
|
184
|
+
getCalldataGasCost(
|
|
185
|
+
poolPrices: PoolPrices<AngleTransmuterData>,
|
|
186
|
+
): number | number[] {
|
|
187
|
+
return CALLDATA_GAS_COST.DEX_NO_PAYLOAD;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
// Encode params required by the exchange adapter
|
|
191
|
+
// Used for multiSwap, buy & megaSwap
|
|
192
|
+
// Hint: abiCoder.encodeParameter() could be useful
|
|
193
|
+
getAdapterParam(
|
|
194
|
+
srcToken: string,
|
|
195
|
+
destToken: string,
|
|
196
|
+
srcAmount: string,
|
|
197
|
+
destAmount: string,
|
|
198
|
+
data: AngleTransmuterData,
|
|
199
|
+
side: SwapSide,
|
|
200
|
+
): AdapterExchangeParam {
|
|
201
|
+
const { exchange } = data;
|
|
202
|
+
|
|
203
|
+
// Encode here the payload for adapter
|
|
204
|
+
const payload = '';
|
|
205
|
+
|
|
206
|
+
return {
|
|
207
|
+
targetExchange: exchange,
|
|
208
|
+
payload,
|
|
209
|
+
networkFee: '0',
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
// Encode call data used by simpleSwap like routers
|
|
214
|
+
// Used for simpleSwap & simpleBuy
|
|
215
|
+
// Hint: this.buildSimpleParamWithoutWETHConversion
|
|
216
|
+
// could be useful
|
|
217
|
+
async getSimpleParam(
|
|
218
|
+
srcToken: string,
|
|
219
|
+
destToken: string,
|
|
220
|
+
srcAmount: string,
|
|
221
|
+
destAmount: string,
|
|
222
|
+
data: AngleTransmuterData,
|
|
223
|
+
side: SwapSide,
|
|
224
|
+
): Promise<SimpleExchangeParam> {
|
|
225
|
+
const { exchange } = data;
|
|
226
|
+
|
|
227
|
+
// Encode here the transaction arguments
|
|
228
|
+
const swapData =
|
|
229
|
+
TransmuterSubscriber.transmuterCrosschainInterface.encodeFunctionData(
|
|
230
|
+
side === SwapSide.SELL ? 'swapExactInput' : 'swapExactOutput',
|
|
231
|
+
[
|
|
232
|
+
side === SwapSide.SELL ? srcAmount : destAmount,
|
|
233
|
+
side === SwapSide.SELL ? destAmount : srcAmount,
|
|
234
|
+
srcToken,
|
|
235
|
+
destToken,
|
|
236
|
+
this.augustusAddress,
|
|
237
|
+
0, // TODO no deadline?
|
|
238
|
+
],
|
|
239
|
+
);
|
|
240
|
+
|
|
241
|
+
return this.buildSimpleParamWithoutWETHConversion(
|
|
242
|
+
srcToken,
|
|
243
|
+
srcAmount,
|
|
244
|
+
destToken,
|
|
245
|
+
destAmount,
|
|
246
|
+
swapData,
|
|
247
|
+
exchange,
|
|
248
|
+
);
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
getDexParam(
|
|
252
|
+
srcToken: Address,
|
|
253
|
+
destToken: Address,
|
|
254
|
+
srcAmount: NumberAsString,
|
|
255
|
+
destAmount: NumberAsString,
|
|
256
|
+
recipient: Address,
|
|
257
|
+
data: AngleTransmuterData,
|
|
258
|
+
side: SwapSide,
|
|
259
|
+
_: Context,
|
|
260
|
+
executorAddress: Address,
|
|
261
|
+
): DexExchangeParam {
|
|
262
|
+
const { exchange } = data;
|
|
263
|
+
|
|
264
|
+
// Encode here the transaction arguments
|
|
265
|
+
const swapData =
|
|
266
|
+
TransmuterSubscriber.transmuterCrosschainInterface.encodeFunctionData(
|
|
267
|
+
side === SwapSide.SELL ? 'swapExactInput' : 'swapExactOutput',
|
|
268
|
+
[
|
|
269
|
+
side === SwapSide.SELL ? srcAmount : destAmount,
|
|
270
|
+
side === SwapSide.SELL ? destAmount : srcAmount,
|
|
271
|
+
srcToken,
|
|
272
|
+
destToken,
|
|
273
|
+
recipient,
|
|
274
|
+
0,
|
|
275
|
+
],
|
|
276
|
+
);
|
|
277
|
+
|
|
278
|
+
return {
|
|
279
|
+
needWrapNative: this.needWrapNative,
|
|
280
|
+
dexFuncHasRecipient: true,
|
|
281
|
+
exchangeData: swapData,
|
|
282
|
+
targetExchange: exchange,
|
|
283
|
+
returnAmountPos: undefined,
|
|
284
|
+
};
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
// This is called once before getTopPoolsForToken is
|
|
288
|
+
// called for multiple tokens. This can be helpful to
|
|
289
|
+
// update common state required for calculating
|
|
290
|
+
// getTopPoolsForToken. It is optional for a DEX
|
|
291
|
+
// to implement this
|
|
292
|
+
async updatePoolState(): Promise<void> {
|
|
293
|
+
for (const stablecoin of this.stablecoinList) {
|
|
294
|
+
const fiat = stablecoin as keyof DexParams;
|
|
295
|
+
const paramFiat = this.params[fiat]!;
|
|
296
|
+
|
|
297
|
+
if (!this.supportedTokens.length) {
|
|
298
|
+
let tokenAddresses = await AngleTransmuterEventPool.getCollateralsList(
|
|
299
|
+
paramFiat.transmuter,
|
|
300
|
+
'latest',
|
|
301
|
+
this.dexHelper.multiContract,
|
|
302
|
+
);
|
|
303
|
+
tokenAddresses = tokenAddresses.concat([paramFiat.stablecoin.address]);
|
|
304
|
+
|
|
305
|
+
const decimalsCallData =
|
|
306
|
+
AngleTransmuter.erc20Interface.encodeFunctionData('decimals');
|
|
307
|
+
const tokenBalanceMultiCall = tokenAddresses.map(t => ({
|
|
308
|
+
target: t,
|
|
309
|
+
callData: decimalsCallData,
|
|
310
|
+
}));
|
|
311
|
+
const res = (
|
|
312
|
+
await this.dexHelper.multiContract.methods
|
|
313
|
+
.aggregate(tokenBalanceMultiCall)
|
|
314
|
+
.call()
|
|
315
|
+
).returnData;
|
|
316
|
+
|
|
317
|
+
const tokenDecimals = res.map((r: any) =>
|
|
318
|
+
Number.parseInt(
|
|
319
|
+
AngleTransmuter.erc20Interface
|
|
320
|
+
.decodeFunctionResult('decimals', r)[0]
|
|
321
|
+
.toString(),
|
|
322
|
+
),
|
|
323
|
+
);
|
|
324
|
+
|
|
325
|
+
this.supportedTokens[fiat] = tokenAddresses.map((t, i) => ({
|
|
326
|
+
address: t,
|
|
327
|
+
decimals: tokenDecimals[i],
|
|
328
|
+
}));
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
// Only work if there are no managers
|
|
332
|
+
const erc20BalanceCalldata =
|
|
333
|
+
AngleTransmuter.erc20Interface.encodeFunctionData('balanceOf', [
|
|
334
|
+
paramFiat.transmuter,
|
|
335
|
+
]);
|
|
336
|
+
const tokenBalanceMultiCall = this.supportedTokens[fiat].map(t => ({
|
|
337
|
+
target: t.address,
|
|
338
|
+
callData: erc20BalanceCalldata,
|
|
339
|
+
}));
|
|
340
|
+
const res = (
|
|
341
|
+
await this.dexHelper.multiContract.methods
|
|
342
|
+
.aggregate(tokenBalanceMultiCall)
|
|
343
|
+
.call()
|
|
344
|
+
).returnData;
|
|
345
|
+
const tokenBalances = res.map((r: any) =>
|
|
346
|
+
BigInt(
|
|
347
|
+
AngleTransmuter.erc20Interface
|
|
348
|
+
.decodeFunctionResult('balanceOf', r)[0]
|
|
349
|
+
.toString(),
|
|
350
|
+
),
|
|
351
|
+
);
|
|
352
|
+
|
|
353
|
+
// TODO bC3M price not detected
|
|
354
|
+
const tokenBalancesUSD = await Promise.all(
|
|
355
|
+
this.supportedTokens[fiat].map((t, i) =>
|
|
356
|
+
this.dexHelper.getTokenUSDPrice(t, tokenBalances[i]),
|
|
357
|
+
),
|
|
358
|
+
);
|
|
359
|
+
this.transmuterUSDLiquidity[fiat] = tokenBalancesUSD.reduce(
|
|
360
|
+
(sum: number, curr: number) => sum + curr,
|
|
361
|
+
);
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
// Returns list of top pools based on liquidity. Max
|
|
366
|
+
// limit number pools should be returned.
|
|
367
|
+
async getTopPoolsForToken(
|
|
368
|
+
tokenAddress: Address,
|
|
369
|
+
limit: number,
|
|
370
|
+
): Promise<PoolLiquidity[]> {
|
|
371
|
+
for (const stablecoin of this.stablecoinList) {
|
|
372
|
+
const fiat = stablecoin as keyof DexParams;
|
|
373
|
+
const paramFiat = this.params[fiat]!;
|
|
374
|
+
|
|
375
|
+
// If not this stable let's check another one
|
|
376
|
+
if (
|
|
377
|
+
!this.supportedTokens[fiat].some(
|
|
378
|
+
t => t.address.toLowerCase() === tokenAddress.toLowerCase(),
|
|
379
|
+
)
|
|
380
|
+
)
|
|
381
|
+
continue;
|
|
382
|
+
|
|
383
|
+
const connectorTokens =
|
|
384
|
+
tokenAddress === paramFiat.stablecoin.address
|
|
385
|
+
? this.supportedTokens[fiat].filter(
|
|
386
|
+
token =>
|
|
387
|
+
token.address.toLowerCase() !==
|
|
388
|
+
paramFiat.stablecoin.address.toLowerCase(),
|
|
389
|
+
)
|
|
390
|
+
: [paramFiat.stablecoin];
|
|
391
|
+
|
|
392
|
+
return [
|
|
393
|
+
{
|
|
394
|
+
exchange: this.dexKey,
|
|
395
|
+
address: paramFiat.transmuter,
|
|
396
|
+
connectorTokens: connectorTokens.slice(0, limit),
|
|
397
|
+
// liquidity is potentially infinite if swapping for agXXX, otherwise at most reserves value
|
|
398
|
+
liquidityUSD:
|
|
399
|
+
tokenAddress === paramFiat.stablecoin.address
|
|
400
|
+
? this.transmuterUSDLiquidity[fiat]
|
|
401
|
+
: 1e9,
|
|
402
|
+
},
|
|
403
|
+
];
|
|
404
|
+
}
|
|
405
|
+
return [];
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
// This is optional function in case if your implementation has acquired any resources
|
|
409
|
+
// you need to release for graceful shutdown. For example, it may be any interval timer
|
|
410
|
+
releaseResources(): AsyncOrSync<void> {}
|
|
411
|
+
|
|
412
|
+
_knownAddress(
|
|
413
|
+
srcToken: Token,
|
|
414
|
+
destToken: Token,
|
|
415
|
+
): { known: boolean; agToken: string | null; fiatName: string | null } {
|
|
416
|
+
const srcAddress = this.dexHelper.config
|
|
417
|
+
.wrapETH(srcToken)
|
|
418
|
+
.address.toLowerCase();
|
|
419
|
+
const destAddress = this.dexHelper.config
|
|
420
|
+
.wrapETH(destToken)
|
|
421
|
+
.address.toLowerCase();
|
|
422
|
+
|
|
423
|
+
for (const stablecoin of this.stablecoinList) {
|
|
424
|
+
const fiat = stablecoin as keyof DexParams;
|
|
425
|
+
const paramFiat = this.params[fiat]!;
|
|
426
|
+
if (
|
|
427
|
+
srcAddress !== destAddress &&
|
|
428
|
+
this.supportedTokensMap[stablecoin][srcAddress] &&
|
|
429
|
+
this.supportedTokensMap[stablecoin][destAddress] &&
|
|
430
|
+
// check that at least one of the tokens is EURA
|
|
431
|
+
(srcAddress === paramFiat.stablecoin.address.toLowerCase() ||
|
|
432
|
+
destAddress === paramFiat.stablecoin.address.toLowerCase())
|
|
433
|
+
) {
|
|
434
|
+
return {
|
|
435
|
+
known: true,
|
|
436
|
+
agToken: paramFiat.stablecoin.address.toLowerCase(),
|
|
437
|
+
fiatName: stablecoin,
|
|
438
|
+
};
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
return { known: false, agToken: null, fiatName: null };
|
|
442
|
+
}
|
|
443
|
+
}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { DeepReadonly } from 'ts-essentials';
|
|
2
|
+
import { PartialEventSubscriber } from '../../composed-event-subscriber';
|
|
3
|
+
import {
|
|
4
|
+
Address,
|
|
5
|
+
BlockHeader,
|
|
6
|
+
Log,
|
|
7
|
+
Logger,
|
|
8
|
+
MultiCallInput,
|
|
9
|
+
MultiCallOutput,
|
|
10
|
+
} from '../../types';
|
|
11
|
+
import { Lens } from '../../lens';
|
|
12
|
+
import { Interface } from '@ethersproject/abi';
|
|
13
|
+
import ProxyABI from '../../abi/chainlink.json';
|
|
14
|
+
import { ChainLinkState } from '../../lib/chainlink';
|
|
15
|
+
|
|
16
|
+
export class BackedSubscriber<State> extends PartialEventSubscriber<
|
|
17
|
+
State,
|
|
18
|
+
ChainLinkState
|
|
19
|
+
> {
|
|
20
|
+
static readonly proxyInterface = new Interface(ProxyABI);
|
|
21
|
+
static readonly ANSWER_UPDATED_TOPIC =
|
|
22
|
+
BackedSubscriber.proxyInterface.getEventTopic('AnswerUpdated');
|
|
23
|
+
|
|
24
|
+
constructor(
|
|
25
|
+
private proxy: Address,
|
|
26
|
+
private aggregator: Address,
|
|
27
|
+
lens: Lens<DeepReadonly<State>, DeepReadonly<ChainLinkState>>,
|
|
28
|
+
logger: Logger,
|
|
29
|
+
) {
|
|
30
|
+
super([aggregator], lens, logger);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
static getReadDecimal(proxy: Address): MultiCallInput {
|
|
34
|
+
return {
|
|
35
|
+
target: proxy,
|
|
36
|
+
callData: BackedSubscriber.proxyInterface.encodeFunctionData('decimals'),
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
static readDecimals(multicallOutput: MultiCallOutput): Address {
|
|
41
|
+
return BackedSubscriber.proxyInterface.decodeFunctionResult(
|
|
42
|
+
'decimals',
|
|
43
|
+
multicallOutput,
|
|
44
|
+
)[0];
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
public processLog(
|
|
48
|
+
state: DeepReadonly<ChainLinkState>,
|
|
49
|
+
log: Readonly<Log>,
|
|
50
|
+
blockHeader: Readonly<BlockHeader>,
|
|
51
|
+
): DeepReadonly<ChainLinkState> | null {
|
|
52
|
+
if (log.topics[0] !== BackedSubscriber.ANSWER_UPDATED_TOPIC) return null; // Ignore other events
|
|
53
|
+
const decoded = BackedSubscriber.proxyInterface.decodeEventLog(
|
|
54
|
+
'AnswerUpdated',
|
|
55
|
+
log.data,
|
|
56
|
+
log.topics,
|
|
57
|
+
);
|
|
58
|
+
return {
|
|
59
|
+
answer: BigInt(decoded.current.toString()),
|
|
60
|
+
timestamp: BigInt(decoded.updatedAt.toString()),
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
public getGenerateStateMultiCallInputs(): MultiCallInput[] {
|
|
65
|
+
return [
|
|
66
|
+
{
|
|
67
|
+
target: this.proxy,
|
|
68
|
+
callData:
|
|
69
|
+
BackedSubscriber.proxyInterface.encodeFunctionData('latestRoundData'),
|
|
70
|
+
},
|
|
71
|
+
];
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
public generateState(
|
|
75
|
+
multicallOutputs: MultiCallOutput[],
|
|
76
|
+
blockNumber?: number | 'latest',
|
|
77
|
+
): DeepReadonly<ChainLinkState> {
|
|
78
|
+
const decoded = BackedSubscriber.proxyInterface.decodeFunctionResult(
|
|
79
|
+
'latestRoundData',
|
|
80
|
+
multicallOutputs[0],
|
|
81
|
+
);
|
|
82
|
+
return {
|
|
83
|
+
answer: BigInt(decoded.answer.toString()),
|
|
84
|
+
timestamp: BigInt(decoded.updatedAt.toString()),
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
public getLatestRoundData(state: DeepReadonly<State>): bigint {
|
|
89
|
+
return this.lens.get()(state).answer;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { DexParams } from './types';
|
|
2
|
+
import { DexConfigMap, AdapterMappings } from '../../types';
|
|
3
|
+
import { Network, SwapSide } from '../../constants';
|
|
4
|
+
|
|
5
|
+
export const AngleTransmuterConfig: DexConfigMap<DexParams> = {
|
|
6
|
+
AngleTransmuter: {
|
|
7
|
+
[Network.MAINNET]: {
|
|
8
|
+
EUR: {
|
|
9
|
+
stablecoin: {
|
|
10
|
+
address: '0x1a7e4e63778B4f12a199C062f3eFdD288afCBce8',
|
|
11
|
+
decimals: 18,
|
|
12
|
+
},
|
|
13
|
+
transmuter: '0x00253582b2a3FE112feEC532221d9708c64cEFAb',
|
|
14
|
+
pyth: '0x4305FB66699C3B2702D4d05CF36551390A4c69C6',
|
|
15
|
+
},
|
|
16
|
+
USD: {
|
|
17
|
+
stablecoin: {
|
|
18
|
+
address: '0x0000206329b97DB379d5E1Bf586BbDB969C63274',
|
|
19
|
+
decimals: 18,
|
|
20
|
+
},
|
|
21
|
+
transmuter: '0x222222fD79264BBE280b4986F6FEfBC3524d0137',
|
|
22
|
+
pyth: '0x4305FB66699C3B2702D4d05CF36551390A4c69C6',
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
[Network.ARBITRUM]: {
|
|
26
|
+
USD: {
|
|
27
|
+
stablecoin: {
|
|
28
|
+
address: '0x0000206329b97DB379d5E1Bf586BbDB969C63274',
|
|
29
|
+
decimals: 18,
|
|
30
|
+
},
|
|
31
|
+
transmuter: '0xD253b62108d1831aEd298Fc2434A5A8e4E418053',
|
|
32
|
+
pyth: '0xff1a0f4744e8582DF1aE09D5611b887B6a12925C',
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
[Network.BASE]: {
|
|
36
|
+
USD: {
|
|
37
|
+
stablecoin: {
|
|
38
|
+
address: '0x0000206329b97DB379d5E1Bf586BbDB969C63274',
|
|
39
|
+
decimals: 18,
|
|
40
|
+
},
|
|
41
|
+
transmuter: '0x222222880e079445Df703c0604706E71a538Fd4f',
|
|
42
|
+
pyth: '0x8250f4aF4B972684F7b336503E2D6dFeDeB1487a',
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
export const Adapters: Record<number, AdapterMappings> = {
|
|
49
|
+
[Network.MAINNET]: { [SwapSide.SELL]: [{ name: '', index: 0 }] },
|
|
50
|
+
};
|