@paraswap/dex-lib 3.8.36 → 3.8.37
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/sdai/SavingsUSDS.abi.json +720 -0
- package/build/dex/index.js +2 -0
- package/build/dex/index.js.map +1 -1
- package/build/dex/usual-bond/usual-bond.js +7 -9
- package/build/dex/usual-bond/usual-bond.js.map +1 -1
- package/package.json +1 -1
- package/src/abi/usual-bond/usd0pp.abi.json +867 -0
- package/src/dex/index.ts +2 -0
- package/src/dex/usual-bond/config.ts +12 -0
- package/src/dex/usual-bond/types.ts +10 -0
- package/src/dex/usual-bond/usual-bond-e2e.test.ts +80 -0
- package/src/dex/usual-bond/usual-bond-integration.test.ts +144 -0
- package/src/dex/usual-bond/usual-bond.ts +208 -0
- package/tests/constants-e2e.ts +12 -0
package/src/dex/index.ts
CHANGED
|
@@ -88,6 +88,7 @@ import { ConcentratorArusd } from './concentrator-arusd/concentrator-arusd';
|
|
|
88
88
|
import { FxProtocolRusd } from './fx-protocol-rusd/fx-protocol-rusd';
|
|
89
89
|
import { AaveGsm } from './aave-gsm/aave-gsm';
|
|
90
90
|
import { LitePsm } from './lite-psm/lite-psm';
|
|
91
|
+
import { UsualBond } from './usual-bond/usual-bond';
|
|
91
92
|
import { StkGHO } from './stkgho/stkgho';
|
|
92
93
|
import { SkyConverter } from './sky-converter/sky-converter';
|
|
93
94
|
|
|
@@ -173,6 +174,7 @@ const Dexes = [
|
|
|
173
174
|
FxProtocolRusd,
|
|
174
175
|
AaveGsm,
|
|
175
176
|
LitePsm,
|
|
177
|
+
UsualBond,
|
|
176
178
|
StkGHO,
|
|
177
179
|
SkyConverter,
|
|
178
180
|
];
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { DexParams } from './types';
|
|
2
|
+
import { DexConfigMap } from '../../types';
|
|
3
|
+
import { Network } from '../../constants';
|
|
4
|
+
|
|
5
|
+
export const UsualBondConfig: DexConfigMap<DexParams> = {
|
|
6
|
+
UsualBond: {
|
|
7
|
+
[Network.MAINNET]: {
|
|
8
|
+
usd0Address: '0x73A15FeD60Bf67631dC6cd7Bc5B6e8da8190aCF5',
|
|
9
|
+
usd0ppAddress: '0x35D8949372D46B7a3D5A56006AE77B215fc69bC0',
|
|
10
|
+
},
|
|
11
|
+
},
|
|
12
|
+
};
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/* eslint-disable no-console */
|
|
2
|
+
import dotenv from 'dotenv';
|
|
3
|
+
dotenv.config();
|
|
4
|
+
|
|
5
|
+
import { testE2E } from '../../../tests/utils-e2e';
|
|
6
|
+
import {
|
|
7
|
+
Tokens,
|
|
8
|
+
Holders,
|
|
9
|
+
NativeTokenSymbols,
|
|
10
|
+
} from '../../../tests/constants-e2e';
|
|
11
|
+
import { Network, ContractMethod, SwapSide } from '../../constants';
|
|
12
|
+
import { StaticJsonRpcProvider } from '@ethersproject/providers';
|
|
13
|
+
import { generateConfig } from '../../config';
|
|
14
|
+
|
|
15
|
+
function testForNetwork(
|
|
16
|
+
network: Network,
|
|
17
|
+
dexKey: string,
|
|
18
|
+
tokenASymbol: string,
|
|
19
|
+
tokenBSymbol: string,
|
|
20
|
+
tokenAAmount: string,
|
|
21
|
+
tokenBAmount: string,
|
|
22
|
+
) {
|
|
23
|
+
const provider = new StaticJsonRpcProvider(
|
|
24
|
+
generateConfig(network).privateHttpProvider,
|
|
25
|
+
network,
|
|
26
|
+
);
|
|
27
|
+
const tokens = Tokens[network];
|
|
28
|
+
const holders = Holders[network];
|
|
29
|
+
|
|
30
|
+
const sideToContractMethods = new Map([
|
|
31
|
+
[SwapSide.SELL, [ContractMethod.swapExactAmountIn]],
|
|
32
|
+
]);
|
|
33
|
+
|
|
34
|
+
describe(`${network}`, () => {
|
|
35
|
+
sideToContractMethods.forEach((contractMethods, side) =>
|
|
36
|
+
describe(`${side}`, () => {
|
|
37
|
+
contractMethods.forEach((contractMethod: ContractMethod) => {
|
|
38
|
+
describe(`${contractMethod}`, () => {
|
|
39
|
+
it(`${tokenASymbol} -> ${tokenBSymbol}`, async () => {
|
|
40
|
+
await testE2E(
|
|
41
|
+
tokens[tokenASymbol],
|
|
42
|
+
tokens[tokenBSymbol],
|
|
43
|
+
holders[tokenASymbol],
|
|
44
|
+
side === SwapSide.SELL ? tokenAAmount : tokenBAmount,
|
|
45
|
+
side,
|
|
46
|
+
dexKey,
|
|
47
|
+
contractMethod,
|
|
48
|
+
network,
|
|
49
|
+
provider,
|
|
50
|
+
);
|
|
51
|
+
});
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
}),
|
|
55
|
+
);
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
describe('UsualBond E2E', () => {
|
|
60
|
+
const dexKey = 'UsualBond';
|
|
61
|
+
|
|
62
|
+
describe('Mainnet', () => {
|
|
63
|
+
const network = Network.MAINNET;
|
|
64
|
+
|
|
65
|
+
const tokenASymbol: string = 'USD0';
|
|
66
|
+
const tokenBSymbol: string = 'USD0++';
|
|
67
|
+
|
|
68
|
+
const tokenAAmount: string = '100000';
|
|
69
|
+
const tokenBAmount: string = '100000';
|
|
70
|
+
|
|
71
|
+
testForNetwork(
|
|
72
|
+
network,
|
|
73
|
+
dexKey,
|
|
74
|
+
tokenASymbol,
|
|
75
|
+
tokenBSymbol,
|
|
76
|
+
tokenAAmount,
|
|
77
|
+
tokenBAmount,
|
|
78
|
+
);
|
|
79
|
+
});
|
|
80
|
+
});
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
/* eslint-disable no-console */
|
|
2
|
+
import dotenv from 'dotenv';
|
|
3
|
+
dotenv.config();
|
|
4
|
+
|
|
5
|
+
import { Interface } from '@ethersproject/abi';
|
|
6
|
+
import { DummyDexHelper } from '../../dex-helper/index';
|
|
7
|
+
import { Network, SwapSide } from '../../constants';
|
|
8
|
+
import { BI_POWS } from '../../bigint-constants';
|
|
9
|
+
import { UsualBond } from './usual-bond';
|
|
10
|
+
import {
|
|
11
|
+
checkPoolPrices,
|
|
12
|
+
checkConstantPoolPrices,
|
|
13
|
+
checkPoolsLiquidity,
|
|
14
|
+
} from '../../../tests/utils';
|
|
15
|
+
import { Tokens } from '../../../tests/constants-e2e';
|
|
16
|
+
|
|
17
|
+
async function testPricingOnNetwork(
|
|
18
|
+
usualBond: UsualBond,
|
|
19
|
+
network: Network,
|
|
20
|
+
dexKey: string,
|
|
21
|
+
blockNumber: number,
|
|
22
|
+
srcTokenAddress: string,
|
|
23
|
+
destTokenAddress: string,
|
|
24
|
+
side: SwapSide,
|
|
25
|
+
amounts: bigint[],
|
|
26
|
+
funcNameToCheck: string,
|
|
27
|
+
) {
|
|
28
|
+
const networkTokens = Tokens[network];
|
|
29
|
+
|
|
30
|
+
console.log(amounts);
|
|
31
|
+
|
|
32
|
+
const pools = await usualBond.getPoolIdentifiers(
|
|
33
|
+
networkTokens['USD0'],
|
|
34
|
+
networkTokens['USD0++'],
|
|
35
|
+
side,
|
|
36
|
+
blockNumber,
|
|
37
|
+
);
|
|
38
|
+
console.log(`${'USD0'} <> ${'USD0++'} Pool Identifiers: `, pools);
|
|
39
|
+
|
|
40
|
+
expect(pools.length).toBeGreaterThan(0);
|
|
41
|
+
|
|
42
|
+
const poolPrices = await usualBond.getPricesVolume(
|
|
43
|
+
networkTokens['USD0'],
|
|
44
|
+
networkTokens['USD0++'],
|
|
45
|
+
amounts,
|
|
46
|
+
side,
|
|
47
|
+
blockNumber,
|
|
48
|
+
pools,
|
|
49
|
+
);
|
|
50
|
+
console.log(`${'USD0'} <> ${'USD0++'} Pool Prices: `, poolPrices);
|
|
51
|
+
|
|
52
|
+
expect(poolPrices).not.toBeNull();
|
|
53
|
+
if (usualBond.hasConstantPriceLargeAmounts) {
|
|
54
|
+
checkConstantPoolPrices(poolPrices!, amounts, dexKey);
|
|
55
|
+
} else {
|
|
56
|
+
checkPoolPrices(poolPrices!, amounts, side, dexKey);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Check if onchain pricing equals to calculated ones
|
|
60
|
+
checkPoolPrices(poolPrices!, amounts, side, dexKey);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
describe('UsualBond', function () {
|
|
64
|
+
const dexKey = 'UsualBond';
|
|
65
|
+
let blockNumber: number;
|
|
66
|
+
let usualBond: UsualBond;
|
|
67
|
+
|
|
68
|
+
describe('Mainnet', () => {
|
|
69
|
+
const network = Network.MAINNET;
|
|
70
|
+
const dexHelper = new DummyDexHelper(network);
|
|
71
|
+
|
|
72
|
+
// Don't forget to update relevant tokens in constant-e2e.ts
|
|
73
|
+
|
|
74
|
+
const amountsForSell = [
|
|
75
|
+
0n,
|
|
76
|
+
1n * BI_POWS[18],
|
|
77
|
+
2n * BI_POWS[18],
|
|
78
|
+
3n * BI_POWS[18],
|
|
79
|
+
4n * BI_POWS[18],
|
|
80
|
+
5n * BI_POWS[18],
|
|
81
|
+
6n * BI_POWS[18],
|
|
82
|
+
7n * BI_POWS[18],
|
|
83
|
+
8n * BI_POWS[18],
|
|
84
|
+
9n * BI_POWS[18],
|
|
85
|
+
10n * BI_POWS[18],
|
|
86
|
+
];
|
|
87
|
+
|
|
88
|
+
beforeAll(async () => {
|
|
89
|
+
blockNumber = await dexHelper.web3Provider.eth.getBlockNumber();
|
|
90
|
+
usualBond = new UsualBond(network, dexKey, dexHelper);
|
|
91
|
+
if (usualBond.initializePricing) {
|
|
92
|
+
await usualBond.initializePricing(blockNumber);
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
it('getPoolIdentifiers and getPricesVolume SELL', async function () {
|
|
97
|
+
await testPricingOnNetwork(
|
|
98
|
+
usualBond,
|
|
99
|
+
network,
|
|
100
|
+
dexKey,
|
|
101
|
+
blockNumber,
|
|
102
|
+
'USD0',
|
|
103
|
+
'USD0++',
|
|
104
|
+
SwapSide.SELL,
|
|
105
|
+
amountsForSell,
|
|
106
|
+
'',
|
|
107
|
+
);
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
it('getTopPoolsForToken: USD0', async function () {
|
|
111
|
+
const tokenA = Tokens[network]['USD0'];
|
|
112
|
+
const dexHelper = new DummyDexHelper(network);
|
|
113
|
+
const usualBond = new UsualBond(network, dexKey, dexHelper);
|
|
114
|
+
|
|
115
|
+
const poolLiquidity = await usualBond.getTopPoolsForToken(
|
|
116
|
+
tokenA.address,
|
|
117
|
+
10,
|
|
118
|
+
);
|
|
119
|
+
console.log(
|
|
120
|
+
`${tokenA.symbol} Top Pools:`,
|
|
121
|
+
JSON.stringify(poolLiquidity, null, 2),
|
|
122
|
+
);
|
|
123
|
+
|
|
124
|
+
checkPoolsLiquidity(poolLiquidity, tokenA.address, dexKey);
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
it('getTopPoolsForToken: USD0++', async function () {
|
|
128
|
+
const tokenA = Tokens[network]['USD0++'];
|
|
129
|
+
const dexHelper = new DummyDexHelper(network);
|
|
130
|
+
const usualBond = new UsualBond(network, dexKey, dexHelper);
|
|
131
|
+
|
|
132
|
+
const poolLiquidity = await usualBond.getTopPoolsForToken(
|
|
133
|
+
tokenA.address,
|
|
134
|
+
10,
|
|
135
|
+
);
|
|
136
|
+
console.log(
|
|
137
|
+
`${tokenA.symbol} Top Pools:`,
|
|
138
|
+
JSON.stringify(poolLiquidity, null, 2),
|
|
139
|
+
);
|
|
140
|
+
|
|
141
|
+
checkPoolsLiquidity(poolLiquidity, tokenA.address, dexKey);
|
|
142
|
+
});
|
|
143
|
+
});
|
|
144
|
+
});
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Token,
|
|
3
|
+
Address,
|
|
4
|
+
ExchangePrices,
|
|
5
|
+
PoolPrices,
|
|
6
|
+
AdapterExchangeParam,
|
|
7
|
+
Logger,
|
|
8
|
+
NumberAsString,
|
|
9
|
+
DexExchangeParam,
|
|
10
|
+
PoolLiquidity,
|
|
11
|
+
} from '../../types';
|
|
12
|
+
import { SwapSide, Network } from '../../constants';
|
|
13
|
+
import * as CALLDATA_GAS_COST from '../../calldata-gas-cost';
|
|
14
|
+
import { getDexKeysWithNetwork } from '../../utils';
|
|
15
|
+
import { IDex } from '../idex';
|
|
16
|
+
import { IDexHelper } from '../../dex-helper/idex-helper';
|
|
17
|
+
import { UsualBondData, DexParams } from './types';
|
|
18
|
+
import { SimpleExchange } from '../simple-exchange';
|
|
19
|
+
import { UsualBondConfig } from './config';
|
|
20
|
+
import { Interface, JsonFragment } from '@ethersproject/abi';
|
|
21
|
+
import USD0PP_ABI from '../../abi/usual-bond/usd0pp.abi.json';
|
|
22
|
+
import { BI_POWS } from '../../bigint-constants';
|
|
23
|
+
|
|
24
|
+
export class UsualBond extends SimpleExchange implements IDex<UsualBondData> {
|
|
25
|
+
protected config: DexParams;
|
|
26
|
+
|
|
27
|
+
readonly hasConstantPriceLargeAmounts = true;
|
|
28
|
+
readonly needWrapNative = false;
|
|
29
|
+
readonly isFeeOnTransferSupported = false;
|
|
30
|
+
|
|
31
|
+
public static dexKeysWithNetwork: { key: string; networks: Network[] }[] =
|
|
32
|
+
getDexKeysWithNetwork(UsualBondConfig);
|
|
33
|
+
|
|
34
|
+
usd0ppIface: Interface;
|
|
35
|
+
logger: Logger;
|
|
36
|
+
|
|
37
|
+
constructor(
|
|
38
|
+
readonly network: Network,
|
|
39
|
+
readonly dexKey: string,
|
|
40
|
+
readonly dexHelper: IDexHelper,
|
|
41
|
+
) {
|
|
42
|
+
super(dexHelper, dexKey);
|
|
43
|
+
const config = UsualBondConfig[dexKey][network];
|
|
44
|
+
this.usd0ppIface = new Interface(USD0PP_ABI as JsonFragment[]);
|
|
45
|
+
this.config = {
|
|
46
|
+
usd0Address: config.usd0Address.toLowerCase(),
|
|
47
|
+
usd0ppAddress: config.usd0ppAddress.toLowerCase(),
|
|
48
|
+
};
|
|
49
|
+
this.logger = dexHelper.getLogger(dexKey);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
async initializePricing(blockNumber: number) {
|
|
53
|
+
// No initialization needed for constant price
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
getConfig() {
|
|
57
|
+
return this.config;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
is_usd0(token: string) {
|
|
61
|
+
return token.toLowerCase() === this.config.usd0Address.toLowerCase();
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
is_usd0pp(token: string) {
|
|
65
|
+
return token.toLowerCase() === this.config.usd0ppAddress.toLowerCase();
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
is_usd0_swap_token(srcToken: string, destToken: string) {
|
|
69
|
+
return this.is_usd0(srcToken) && this.is_usd0pp(destToken);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
getAdapters() {
|
|
73
|
+
return null;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
async getPoolIdentifiers(
|
|
77
|
+
srcToken: Token,
|
|
78
|
+
destToken: Token,
|
|
79
|
+
side: SwapSide,
|
|
80
|
+
blockNumber: number,
|
|
81
|
+
): Promise<string[]> {
|
|
82
|
+
if (!srcToken || !destToken) {
|
|
83
|
+
this.logger.error('Source or destination token is undefined');
|
|
84
|
+
return [];
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const srcTokenAddress = srcToken.address?.toLowerCase();
|
|
88
|
+
const destTokenAddress = destToken.address?.toLowerCase();
|
|
89
|
+
|
|
90
|
+
if (!srcTokenAddress || !destTokenAddress) {
|
|
91
|
+
this.logger.error('Source or destination token address is undefined');
|
|
92
|
+
return [];
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
if (this.is_usd0_swap_token(srcTokenAddress, destTokenAddress)) {
|
|
96
|
+
return [`${this.dexKey}_${this.config.usd0ppAddress}`];
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
return [];
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
async getPricesVolume(
|
|
103
|
+
srcToken: Token,
|
|
104
|
+
destToken: Token,
|
|
105
|
+
amounts: bigint[],
|
|
106
|
+
side: SwapSide,
|
|
107
|
+
blockNumber: number,
|
|
108
|
+
limitPools?: string[],
|
|
109
|
+
): Promise<null | ExchangePrices<UsualBondData>> {
|
|
110
|
+
if (side === SwapSide.BUY) {
|
|
111
|
+
return null;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
const isUSD0SwapToken = this.is_usd0_swap_token(
|
|
115
|
+
srcToken.address,
|
|
116
|
+
destToken.address,
|
|
117
|
+
);
|
|
118
|
+
|
|
119
|
+
if (!isUSD0SwapToken) {
|
|
120
|
+
return null;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
const unitOut = BI_POWS[18]; // 1:1 swap
|
|
124
|
+
const amountsOut = amounts; // 1:1 swap, so output amounts are the same as input
|
|
125
|
+
|
|
126
|
+
return [
|
|
127
|
+
{
|
|
128
|
+
unit: unitOut,
|
|
129
|
+
prices: amountsOut,
|
|
130
|
+
data: {},
|
|
131
|
+
poolAddresses: [this.config.usd0ppAddress],
|
|
132
|
+
exchange: this.dexKey,
|
|
133
|
+
gasCost: 70000,
|
|
134
|
+
poolIdentifier: this.dexKey,
|
|
135
|
+
},
|
|
136
|
+
];
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
getCalldataGasCost(poolPrices: PoolPrices<UsualBondData>): number | number[] {
|
|
140
|
+
return CALLDATA_GAS_COST.DEX_NO_PAYLOAD;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
getAdapterParam(
|
|
144
|
+
srcToken: string,
|
|
145
|
+
destToken: string,
|
|
146
|
+
srcAmount: string,
|
|
147
|
+
destAmount: string,
|
|
148
|
+
data: UsualBondData,
|
|
149
|
+
side: SwapSide,
|
|
150
|
+
): AdapterExchangeParam {
|
|
151
|
+
const payload = '0x';
|
|
152
|
+
|
|
153
|
+
return {
|
|
154
|
+
targetExchange: this.config.usd0ppAddress,
|
|
155
|
+
payload,
|
|
156
|
+
networkFee: '0',
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
async getDexParam(
|
|
161
|
+
srcToken: Address,
|
|
162
|
+
destToken: Address,
|
|
163
|
+
srcAmount: NumberAsString,
|
|
164
|
+
destAmount: NumberAsString,
|
|
165
|
+
recipient: Address,
|
|
166
|
+
data: UsualBondData,
|
|
167
|
+
side: SwapSide,
|
|
168
|
+
): Promise<DexExchangeParam> {
|
|
169
|
+
if (this.is_usd0(srcToken) && this.is_usd0pp(destToken)) {
|
|
170
|
+
const exchangeData = this.usd0ppIface.encodeFunctionData('mint', [
|
|
171
|
+
srcAmount,
|
|
172
|
+
]);
|
|
173
|
+
|
|
174
|
+
return {
|
|
175
|
+
needWrapNative: false,
|
|
176
|
+
dexFuncHasRecipient: false,
|
|
177
|
+
exchangeData,
|
|
178
|
+
targetExchange: this.config.usd0ppAddress,
|
|
179
|
+
returnAmountPos: undefined,
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
throw new Error('LOGIC ERROR');
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
async getTopPoolsForToken(
|
|
186
|
+
tokenAddress: Address,
|
|
187
|
+
limit: number,
|
|
188
|
+
): Promise<PoolLiquidity[]> {
|
|
189
|
+
const isUsd0 = this.is_usd0(tokenAddress);
|
|
190
|
+
if (!isUsd0 && !this.is_usd0pp(tokenAddress)) return [];
|
|
191
|
+
|
|
192
|
+
return [
|
|
193
|
+
{
|
|
194
|
+
exchange: this.dexKey,
|
|
195
|
+
address: this.config.usd0ppAddress,
|
|
196
|
+
connectorTokens: [
|
|
197
|
+
{
|
|
198
|
+
decimals: 18,
|
|
199
|
+
address: isUsd0
|
|
200
|
+
? this.config.usd0ppAddress
|
|
201
|
+
: this.config.usd0Address,
|
|
202
|
+
},
|
|
203
|
+
],
|
|
204
|
+
liquidityUSD: 1000000000, // Just returning a big number so this DEX will be preferred
|
|
205
|
+
},
|
|
206
|
+
];
|
|
207
|
+
}
|
|
208
|
+
}
|
package/tests/constants-e2e.ts
CHANGED
|
@@ -523,6 +523,16 @@ export const Tokens: {
|
|
|
523
523
|
address: '0x07D1718fF05a8C53C8F05aDAEd57C0d672945f9a',
|
|
524
524
|
decimals: 18,
|
|
525
525
|
},
|
|
526
|
+
USD0: {
|
|
527
|
+
address: '0x73A15FeD60Bf67631dC6cd7Bc5B6e8da8190aCF5',
|
|
528
|
+
decimals: 18,
|
|
529
|
+
symbol: 'USD0',
|
|
530
|
+
},
|
|
531
|
+
'USD0++': {
|
|
532
|
+
address: '0x35D8949372D46B7a3D5A56006AE77B215fc69bC0',
|
|
533
|
+
decimals: 18,
|
|
534
|
+
symbol: 'USD0++',
|
|
535
|
+
},
|
|
526
536
|
},
|
|
527
537
|
[Network.POLYGON]: {
|
|
528
538
|
jGBP: {
|
|
@@ -1606,6 +1616,8 @@ export const Holders: {
|
|
|
1606
1616
|
weETH: '0x267ed5f71EE47D3E45Bb1569Aa37889a2d10f91e',
|
|
1607
1617
|
rUSD: '0xEC2eda1C4F981E468ABF62424a10B69B738b498E',
|
|
1608
1618
|
arUSD: '0xeFc24206053a452e2299BF3b8f964512b041Db4C',
|
|
1619
|
+
USD0: '0x6A5d5Af0E266a24648a9d7E8D388EAEc7AbD8433',
|
|
1620
|
+
'USD0++': '0x2227b6806339906707b43F36a1f07B52FF7Fa776',
|
|
1609
1621
|
},
|
|
1610
1622
|
[Network.POLYGON]: {
|
|
1611
1623
|
jGBP: '0x02aa0B826c7BA6386DdBE04C0a8715A1c0A16B24',
|