@raac/rpc 1.1.0-beta.71 → 1.1.0-beta.73
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/dist/configs/chains/8453.json +11 -11
- package/dist/scripts/analyze_transfers.js +2 -2
- package/dist/scripts/calculate_portfolio.js +1 -1
- package/dist/scripts/index.js +82 -61
- package/dist/scripts/liquidation.js +176 -0
- package/dist/scripts/run_analysis.js +2 -2
- package/dist/scripts/users.js +9 -8
- package/dist/test.js +323 -0
- package/dist/types/scripts/liquidation.d.ts +1 -0
- package/dist/types/test.d.ts +1 -0
- package/package.json +1 -1
|
@@ -57,7 +57,7 @@
|
|
|
57
57
|
"rwavault": {
|
|
58
58
|
"id": "rwavault",
|
|
59
59
|
"name": "RWA Vault",
|
|
60
|
-
"contract": "
|
|
60
|
+
"contract": "0xc6e7DF5E7b4f2A278906862b61205850344D4e7d"
|
|
61
61
|
},
|
|
62
62
|
"complianceregistry": {
|
|
63
63
|
"id": "complianceregistry",
|
|
@@ -67,7 +67,7 @@
|
|
|
67
67
|
"rwaindextokencollector": {
|
|
68
68
|
"id": "rwaindextokencollector",
|
|
69
69
|
"name": "RWA Index Token Collector",
|
|
70
|
-
"contract": "
|
|
70
|
+
"contract": "0x3Aa5ebB10DC797CAC828524e59A333d0A371443c"
|
|
71
71
|
},
|
|
72
72
|
"raactokencollector": {
|
|
73
73
|
"id": "raactokencollector",
|
|
@@ -89,12 +89,12 @@
|
|
|
89
89
|
"stabilitypool": {
|
|
90
90
|
"id": "stabilitypool",
|
|
91
91
|
"name": "Stability Pool",
|
|
92
|
-
"contract": "
|
|
92
|
+
"contract": "0x9A9f2CCfdE556A7E9Ff0848998Aa4a0CFD8863AE"
|
|
93
93
|
},
|
|
94
94
|
"lendingpool": {
|
|
95
95
|
"id": "lendingpool",
|
|
96
96
|
"name": "Lending Pool",
|
|
97
|
-
"contract": "
|
|
97
|
+
"contract": "0x0DCd1Bf9A1b36cE34237eEaFef220932846BCD82"
|
|
98
98
|
}
|
|
99
99
|
},
|
|
100
100
|
"nfts": {
|
|
@@ -127,7 +127,7 @@
|
|
|
127
127
|
"id": "detoken",
|
|
128
128
|
"name": "DEToken",
|
|
129
129
|
"decimals": 18,
|
|
130
|
-
"contract": "
|
|
130
|
+
"contract": "0x9A676e781A523b5d0C0e43731313A708CB607508"
|
|
131
131
|
},
|
|
132
132
|
"raactoken": {
|
|
133
133
|
"id": "raactoken",
|
|
@@ -151,7 +151,7 @@
|
|
|
151
151
|
"id": "rwaindextoken",
|
|
152
152
|
"name": "Index Token",
|
|
153
153
|
"decimals": 18,
|
|
154
|
-
"contract": "
|
|
154
|
+
"contract": "0x68B1D87F95878fE05B998F19b66F4baba5De1aed"
|
|
155
155
|
},
|
|
156
156
|
"complianceregistry": {
|
|
157
157
|
"id": "complianceregistry",
|
|
@@ -163,7 +163,7 @@
|
|
|
163
163
|
"id": "rwaindextokencollector",
|
|
164
164
|
"name": "RWA Index Token Collector",
|
|
165
165
|
"decimals": 18,
|
|
166
|
-
"contract": "
|
|
166
|
+
"contract": "0x3Aa5ebB10DC797CAC828524e59A333d0A371443c"
|
|
167
167
|
},
|
|
168
168
|
"raactokencollector": {
|
|
169
169
|
"id": "raactokencollector",
|
|
@@ -177,13 +177,13 @@
|
|
|
177
177
|
"raacnftadapter": {
|
|
178
178
|
"id": "raacnftadapter",
|
|
179
179
|
"name": "RAAC NFT Adapter",
|
|
180
|
-
"contract": "
|
|
180
|
+
"contract": "0x7a2088a1bFc9d81c55368AE168C2C02570cB814F",
|
|
181
181
|
"type": "ERC721"
|
|
182
182
|
},
|
|
183
183
|
"rwaindextokenadapter": {
|
|
184
184
|
"id": "rwaindextokenadapter",
|
|
185
185
|
"name": "RWA Index Token",
|
|
186
|
-
"contract": "
|
|
186
|
+
"contract": "0x4A679253410272dd5232B3Ff7cF5dbB88f295319",
|
|
187
187
|
"type": "ERC20"
|
|
188
188
|
}
|
|
189
189
|
},
|
|
@@ -191,13 +191,13 @@
|
|
|
191
191
|
"raacnftadapter": {
|
|
192
192
|
"id": "raacnftadapter",
|
|
193
193
|
"name": "RAAC NFT Adapter",
|
|
194
|
-
"contract": "
|
|
194
|
+
"contract": "0x322813Fd9A801c5507c9de605d63CEA4f2CE6c44",
|
|
195
195
|
"type": "ERC721"
|
|
196
196
|
},
|
|
197
197
|
"crvusdadapter": {
|
|
198
198
|
"id": "crvusdadapter",
|
|
199
199
|
"name": "CRVUSD Adapter",
|
|
200
|
-
"contract": "
|
|
200
|
+
"contract": "0x4ed7c70F96B99c776995fB64377f0d4aB3B0e1C1",
|
|
201
201
|
"type": "ERC20"
|
|
202
202
|
}
|
|
203
203
|
}
|
|
@@ -41,8 +41,8 @@ const fs = __importStar(require("fs"));
|
|
|
41
41
|
const csv_parser_1 = __importDefault(require("csv-parser"));
|
|
42
42
|
const RPC_URL = 'https://eth-sepolia.g.alchemy.com/v2/GRu4-s8cjabOCnh-3ZFzapF-MwUcURV_';
|
|
43
43
|
const provider = new ethers_1.ethers.JsonRpcProvider(RPC_URL);
|
|
44
|
-
const TOKEN_CONTRACT_ADDRESS = '
|
|
45
|
-
const START_BLOCK =
|
|
44
|
+
const TOKEN_CONTRACT_ADDRESS = '0x990c1Aa9162d2c5B51378F86420f1752874e034B';
|
|
45
|
+
const START_BLOCK = 9000000;
|
|
46
46
|
const END_BLOCK = 'latest';
|
|
47
47
|
const BLOCK_RANGE_LIMIT = 500;
|
|
48
48
|
// User to exclude from all calculations
|
|
@@ -111,7 +111,7 @@ async function main() {
|
|
|
111
111
|
// Parse token balances
|
|
112
112
|
const rTokenValue = parseFloat(user.rTokenBalance) || 0;
|
|
113
113
|
const deTokenValue = parseFloat(user.deTokenBalance) || 0;
|
|
114
|
-
const iraacValue = (parseFloat(user.iraacBalance) || 0)
|
|
114
|
+
const iraacValue = (parseFloat(user.iraacBalance) || 0); // Apply 0.97 multiplier to iRAAC balance
|
|
115
115
|
const tokenValue = parseFloat(user.tokenBalance) || 0;
|
|
116
116
|
// Calculate NFT total value
|
|
117
117
|
const { totalValue: nftTotalValue, details: nftDetails } = calculateTotalNftValue(user.nftData);
|
package/dist/scripts/index.js
CHANGED
|
@@ -11,7 +11,7 @@ const contracts_1 = require("../utils/contracts");
|
|
|
11
11
|
const artifacts_1 = require("../utils/artifacts");
|
|
12
12
|
const _helpers_1 = require("../pools/rwaVault/_helpers");
|
|
13
13
|
const ethers5_1 = require("ethers5");
|
|
14
|
-
const chainId =
|
|
14
|
+
const chainId = 8453;
|
|
15
15
|
const config = chains_1.default[chainId];
|
|
16
16
|
const TEST_MNEMONIC = process.env.TEST_MNEMONIC;
|
|
17
17
|
const TEST_PRIVATE_KEY = process.env.TEST_PRIVATE_KEY;
|
|
@@ -72,13 +72,48 @@ async function setup() {
|
|
|
72
72
|
const RWAVaultAddress = (0, contracts_1.getContractAddress)(chainId, "rwavault");
|
|
73
73
|
const RWAVaultABI = (0, artifacts_1.getABI)("rwavault");
|
|
74
74
|
const RWAVaultContract = new ethers_1.ethers.Contract(RWAVaultAddress, RWAVaultABI, signer);
|
|
75
|
+
// const newPrices = [];
|
|
76
|
+
// for (let i = 1; i < 21; i++) {
|
|
77
|
+
// const latestPriceRaw = (await housePriceContract.getLatestPrice(i))[0];
|
|
78
|
+
// const price = Number(ethers.formatEther(latestPriceRaw));
|
|
79
|
+
// // Randomly decide to decrease by 10 or increase by 30%
|
|
80
|
+
// let newPrice;
|
|
81
|
+
// if (Math.random() > 0.5) {
|
|
82
|
+
// // Increase by a random percentage up to 30%
|
|
83
|
+
// const increasePercent = Math.random() * 0.3; // 0% to 30%
|
|
84
|
+
// newPrice = price * (1 + increasePercent);
|
|
85
|
+
// } else {
|
|
86
|
+
// // Decrease by a random percentage up to 10%
|
|
87
|
+
// const decreasePercent = Math.random() * 0.2; // 0% to 10%
|
|
88
|
+
// newPrice = price * (1 - decreasePercent);
|
|
89
|
+
// if (newPrice < 0) newPrice = 0;
|
|
90
|
+
// }
|
|
91
|
+
// newPrices.push({
|
|
92
|
+
// id: i,
|
|
93
|
+
// oldPrice: price,
|
|
94
|
+
// newPrice: ethers.parseEther(newPrice.toString())
|
|
95
|
+
// });
|
|
96
|
+
// }
|
|
97
|
+
// const tokens = new Array(20).fill(0).map((_, e) => BigInt(e +1))
|
|
98
|
+
// console.log(tokens, tokens.length)
|
|
99
|
+
// const prices = newPrices.map(e => e.newPrice)
|
|
100
|
+
// await (await housePriceContract.setHousePrices(tokens, prices)).wait()
|
|
101
|
+
// return;
|
|
102
|
+
// await (await StabilityPoolContract.setWithdrawTimelockDuration(1 * 60)).wait();
|
|
103
|
+
// return;
|
|
75
104
|
// const secretsReference = await encryptSecrets(chainId, {
|
|
76
105
|
// apiKey: process.env.FRED_API_KEY as string,
|
|
77
106
|
// }, "encryptedFunctionsPrimeRateSecrets.json", signerV5);
|
|
78
107
|
// console.log(secretsReference);
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
108
|
+
// const decimals = ["function decimals() external view returns (uint8)"];
|
|
109
|
+
// const DebtTokenContract = new ethers.Contract(
|
|
110
|
+
// "0xa4F93e2d2AFd4658e638a26dCE189acFd542fC0E",
|
|
111
|
+
// decimals,
|
|
112
|
+
// )
|
|
113
|
+
// console.log(await DebtTokenContract.decimals())
|
|
114
|
+
// return;
|
|
115
|
+
// await (await raacNFTContract.setAllowMinting(true)).wait();
|
|
116
|
+
// await (await raacNFTContract.setPriceStalenessThreshold(7 * 24 * 60 * 60)).wait();
|
|
82
117
|
// return;
|
|
83
118
|
// await (await raacNFTContract.setAllowMinting(true)).wait();
|
|
84
119
|
// return;
|
|
@@ -105,57 +140,11 @@ async function setup() {
|
|
|
105
140
|
// console.log(tx);
|
|
106
141
|
// let tx = await StabilityPoolContract.setLiquidationVaultTokenSplit(2_50, 2_50, 90_00, 5_00)
|
|
107
142
|
// await tx.wait();
|
|
108
|
-
|
|
109
|
-
//
|
|
110
|
-
//
|
|
111
|
-
const MockLiquidityPoolAddress = "0x455Ad6413DeeD5A2B3AC9dc8826e5a58A8c5181D";
|
|
112
|
-
const MockLiquidityPoolABI = ["function add_liquidity(uint256[2] amounts, uint256 min_mint_amount, address receiver) external"];
|
|
113
|
-
const MockLiquidityPoolContract = new ethers_1.ethers.Contract(MockLiquidityPoolAddress, MockLiquidityPoolABI, signer);
|
|
114
|
-
// mint 10 million in crvusd
|
|
115
|
-
console.log("Minting 10 million in crvusd");
|
|
116
|
-
// await rpc.wallet.assets.mintAsset(chainId, "crvusd", 10000000n, signer.address, signer)
|
|
117
|
-
// deposit 5 million in the RWA Vault
|
|
118
|
-
console.log("Depositing 5 million in the RWA Vault");
|
|
119
|
-
// await rpc.wallet.assets.approveAsset(chainId, "crvusd", await rpc.pools.rwaVault.getAdapterAddress(chainId, "crvusdadapter").address, "5000000", signer);
|
|
120
|
-
const d1 = new ethers_1.ethers.AbiCoder().encode(["uint256"], [ethers_1.ethers.parseEther("5000000")]);
|
|
121
|
-
await rpc.pools.rwaVault.depositToRWAVault(chainId, "crvusdadapter", d1, signer.address, "0", signer);
|
|
122
|
-
// deposit 5 million in the Mock Liquidity Pool
|
|
123
|
-
console.log("Depositing 5 million in the Mock Liquidity Pool");
|
|
124
|
-
await rpc.wallet.assets.approveAsset(chainId, "crvusd", MockLiquidityPoolAddress, "5000000", signer);
|
|
125
|
-
const indextokenBalance = (await rpc.wallet.assets.getBalance(chainId, "rwaindextoken", signer.address, provider)).balance;
|
|
126
|
-
await rpc.wallet.assets.approveAsset(chainId, "rwaindextoken", MockLiquidityPoolAddress, indextokenBalance, signer);
|
|
127
|
-
await (await MockLiquidityPoolContract.add_liquidity([ethers_1.ethers.parseEther("5000000"), ethers_1.ethers.parseEther(indextokenBalance.toString())], 0, signer.address)).wait();
|
|
128
|
-
// check the liquidity in the pools
|
|
129
|
-
console.log("Checking the liquidity in the pools");
|
|
130
|
-
const liquidity = await MockLiquidityPoolContract.getTotalLiquidity(await rpc.contracts.getContractAddress(chainId, "rwaindextoken"));
|
|
131
|
-
console.log("Liquidity in the Mock Liquidity Pool", liquidity);
|
|
132
|
-
// mint the current user 5 million irAAC
|
|
133
|
-
console.log("Minting 5 million irAAC");
|
|
134
|
-
await rpc.wallet.assets.approveAsset(chainId, "crvusd", await rpc.pools.rwaVault.getAdapterAddress(chainId, "crvusdadapter").address, "5000000", signer);
|
|
135
|
-
const data = new ethers_1.ethers.AbiCoder().encode(["uint256"], [ethers_1.ethers.parseEther("5000000")]);
|
|
136
|
-
await rpc.pools.rwaVault.depositToRWAVault(chainId, "crvusdadapter", data, signer.address, "0", signer);
|
|
137
|
-
return;
|
|
138
|
-
/// END OF ADD FUNDS IN THE MOCK LIQUIDITY POOL
|
|
139
|
-
// // // send myself some CRVUSD
|
|
140
|
-
// await rpc.wallet.assets.mintAsset(
|
|
141
|
-
// chainId,
|
|
142
|
-
// "crvusd",
|
|
143
|
-
// 10000000n,
|
|
144
|
-
// signer.address,
|
|
145
|
-
// signer
|
|
146
|
-
// );
|
|
147
|
-
// set the base uri to instruxi data gateway
|
|
143
|
+
await (await RWAVaultContract.registerDepositableAdapter("0x322813Fd9A801c5507c9de605d63CEA4f2CE6c44")).wait();
|
|
144
|
+
// // console.log(await rpc.wallet.assets.getBalance(chainId, "rwaindextoken", signer.address, provider))
|
|
145
|
+
// // set the base uri to instruxi data gateway
|
|
148
146
|
await rpc.nfts.setBaseUri(chainId, "http://3.86.253.54:3000/v1/properties/", signer);
|
|
149
|
-
|
|
150
|
-
// if (chainId === 11155111) {
|
|
151
|
-
// await RWAVaultContract.setVRFConsumer("0x244dC85807D947B2c590DEb1A340B818d5CD59B9")
|
|
152
|
-
// }
|
|
153
|
-
// // @ts-ignore
|
|
154
|
-
// if (chainId !== 8453) {
|
|
155
|
-
// return;
|
|
156
|
-
// }
|
|
157
|
-
// // // set the oracle address of the RAACHousePrice. TEmporarily simulating that I AM THE ORACLE
|
|
158
|
-
// await rpc.contracts.housePrices.setOracle(chainId, signer.address, signer);
|
|
147
|
+
await rpc.contracts.housePrices.setOracle(chainId, signer.address, signer);
|
|
159
148
|
const countTokens = 100;
|
|
160
149
|
// // // // Generate 10 house prices between 100K and 2M
|
|
161
150
|
const housePrices = [];
|
|
@@ -163,12 +152,12 @@ async function setup() {
|
|
|
163
152
|
const price = Math.floor(Math.random() * (2000000 - 100000) + 100000);
|
|
164
153
|
housePrices.push(ethers_1.ethers.parseEther(price.toString()));
|
|
165
154
|
}
|
|
166
|
-
// //
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
155
|
+
// // Mint the new properties
|
|
156
|
+
for (let i = 1; i <= 5; i++) {
|
|
157
|
+
const tx = await raacNFTContract.minterMint(signer.address, i);
|
|
158
|
+
await tx.wait();
|
|
159
|
+
console.log("Minted NFT", i);
|
|
160
|
+
}
|
|
172
161
|
const tokenIds = new Array(countTokens).fill(0).map((_, i) => BigInt(i + 1));
|
|
173
162
|
await (await housePriceContract.setHousePrices(tokenIds, housePrices)).wait();
|
|
174
163
|
// // set house prices
|
|
@@ -274,7 +263,39 @@ const fulfillRequest = async () => {
|
|
|
274
263
|
const redemptionToken = await rwaVaultContract.getNextRandomNFT();
|
|
275
264
|
console.log("Redemption token", redemptionToken);
|
|
276
265
|
};
|
|
277
|
-
|
|
266
|
+
const blacklist = async () => {
|
|
267
|
+
const rpc = new RPCLibrary_1.default();
|
|
268
|
+
const provider = await getProvider();
|
|
269
|
+
const signer = await createWallet(TEST_MNEMONIC, provider);
|
|
270
|
+
const users = [
|
|
271
|
+
"0x44cc55fd4672b529f4c930d1cffadd71071fbd14",
|
|
272
|
+
"0x6c91d4a3935dcd7912d56c4809b683bf06924d2d",
|
|
273
|
+
"0x9b02685b84cd7d9deb322e9443dcdbc875d9526a",
|
|
274
|
+
"0x8e26d167ec9991bebf2e44278064270764acc5eb",
|
|
275
|
+
"0xc998661079962ef4e6c55d77802e23c86a2e3de6",
|
|
276
|
+
"0x42098837ff07c975b2ca52ddb43bf4a1be4c5db0",
|
|
277
|
+
"0x95b8ccdf5a3314dc2ec529cb01bd4a195e6c9e42",
|
|
278
|
+
"0xf55bda6a8a1b84cd2c9c1d9cde9bba6b6f395066",
|
|
279
|
+
];
|
|
280
|
+
// filter the users that are already blacklsited
|
|
281
|
+
const ComplianceRegistryAddress = (0, contracts_1.getContractAddress)(chainId, "complianceregistry");
|
|
282
|
+
const ComplianceRegistryABI = (0, artifacts_1.getABI)("complianceregistry");
|
|
283
|
+
const ComplianceRegistryContract = new ethers_1.ethers.Contract(ComplianceRegistryAddress, ComplianceRegistryABI, signer);
|
|
284
|
+
console.log(ComplianceRegistryContract);
|
|
285
|
+
const toBlacklist = new Set();
|
|
286
|
+
for (const i in users) {
|
|
287
|
+
const user = users[i];
|
|
288
|
+
const isBlacklisted = await ComplianceRegistryContract.isBlacklisted(user);
|
|
289
|
+
console.log(user, isBlacklisted);
|
|
290
|
+
if (!isBlacklisted && !toBlacklist.has(user)) {
|
|
291
|
+
toBlacklist.add(user);
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
const arr = new Array(...toBlacklist);
|
|
295
|
+
await (await ComplianceRegistryContract.blacklistBatch(arr)).wait();
|
|
296
|
+
};
|
|
297
|
+
// blacklist()
|
|
298
|
+
// execute();
|
|
278
299
|
setup();
|
|
279
300
|
// fulfillRequest();
|
|
280
301
|
// setup();
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const ethers_1 = require("ethers");
|
|
7
|
+
const chains_1 = __importDefault(require("../configs/chains"));
|
|
8
|
+
//node --env-file=../.env -r ts-node/register ./test.ts
|
|
9
|
+
const RPCLibrary_1 = __importDefault(require("../RPCLibrary"));
|
|
10
|
+
const contracts_1 = require("../utils/contracts");
|
|
11
|
+
const artifacts_1 = require("../utils/artifacts");
|
|
12
|
+
const chainId = 8453;
|
|
13
|
+
const config = chains_1.default[chainId];
|
|
14
|
+
const TEST_MNEMONIC = process.env.TEST_MNEMONIC;
|
|
15
|
+
const TEST_PRIVATE_KEY = process.env.TEST_PRIVATE_KEY;
|
|
16
|
+
async function getProvider() {
|
|
17
|
+
return new ethers_1.ethers.JsonRpcProvider(config.rpcs[0]);
|
|
18
|
+
}
|
|
19
|
+
async function createWallet(mnemonic, provider) {
|
|
20
|
+
// @ts-ignore
|
|
21
|
+
if (chainId === 8453) {
|
|
22
|
+
const wallet = ethers_1.ethers.Wallet.fromPhrase(mnemonic, provider);
|
|
23
|
+
console.info(`[${chainId}]: Loaded wallet from mnemonic: ${wallet.address}`);
|
|
24
|
+
// the signer is the wallet
|
|
25
|
+
return wallet;
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
// load from private key
|
|
29
|
+
const wallet = new ethers_1.ethers.Wallet(TEST_PRIVATE_KEY, provider);
|
|
30
|
+
console.info(`[${chainId}]: Loaded wallet from private key: ${wallet.address}`);
|
|
31
|
+
return wallet;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
async function getPosition(adapter, user, data) {
|
|
35
|
+
const rpc = new RPCLibrary_1.default();
|
|
36
|
+
const provider = await getProvider();
|
|
37
|
+
const signer = await createWallet(TEST_MNEMONIC, provider);
|
|
38
|
+
// const rpc = new RPCLibrary();
|
|
39
|
+
rpc.address = signer.address;
|
|
40
|
+
rpc.provider = provider;
|
|
41
|
+
rpc.chainId = chainId;
|
|
42
|
+
const lendingPoolAddress = (0, contracts_1.getContractAddress)(chainId, "lendingpool");
|
|
43
|
+
const lendingPoolABI = (0, artifacts_1.getABI)("lendingpool");
|
|
44
|
+
const lendingPoolContract = new ethers_1.ethers.Contract(lendingPoolAddress, lendingPoolABI, signer);
|
|
45
|
+
const adapterAddress = rpc.pools.lendingPool.getAdapterAddress(chainId, adapter).address;
|
|
46
|
+
console.log(await lendingPoolContract.getPositionView(adapterAddress, user, data));
|
|
47
|
+
}
|
|
48
|
+
async function setupLiquidityPool() {
|
|
49
|
+
const rpc = new RPCLibrary_1.default();
|
|
50
|
+
const provider = await getProvider();
|
|
51
|
+
const signer = await createWallet(TEST_MNEMONIC, provider);
|
|
52
|
+
// const rpc = new RPCLibrary();
|
|
53
|
+
rpc.address = signer.address;
|
|
54
|
+
rpc.provider = provider;
|
|
55
|
+
rpc.chainId = chainId;
|
|
56
|
+
const MockLiquidityPoolAddress = "0x9E545E3C0baAB3E08CdfD552C960A1050f373042";
|
|
57
|
+
const MockLiquidityPoolABI = [
|
|
58
|
+
"function add_liquidity(uint256[2] amounts, uint256 min_mint_amount, address receiver) external",
|
|
59
|
+
];
|
|
60
|
+
const MockLiquidityPoolContract = new ethers_1.ethers.Contract(MockLiquidityPoolAddress, MockLiquidityPoolABI, signer);
|
|
61
|
+
// mint 10 million in crvusd
|
|
62
|
+
console.log("Minting 100 million in crvusd");
|
|
63
|
+
await rpc.wallet.assets.mintAsset(chainId, "crvusd", 200000000n, signer.address, signer);
|
|
64
|
+
// deposit 5 million in the RWA Vault
|
|
65
|
+
console.log("Depositing 5 million in the RWA Vault");
|
|
66
|
+
await rpc.wallet.assets.approveAsset(chainId, "crvusd", await rpc.pools.rwaVault.getAdapterAddress(chainId, "crvusdadapter")
|
|
67
|
+
.address, "100000000", signer);
|
|
68
|
+
const d1 = new ethers_1.ethers.AbiCoder().encode(["uint256"], [ethers_1.ethers.parseEther("100000000")]);
|
|
69
|
+
await rpc.pools.rwaVault.depositToRWAVault(chainId, "crvusdadapter", d1, signer.address, "0", signer);
|
|
70
|
+
// deposit 5 million in the Mock Liquidity Pool
|
|
71
|
+
console.log("Depositing 5 million in the Mock Liquidity Pool");
|
|
72
|
+
await rpc.wallet.assets.approveAsset(chainId, "crvusd", MockLiquidityPoolAddress, "100000000", signer);
|
|
73
|
+
const indextokenBalance = (await rpc.wallet.assets.getBalance(chainId, "rwaindextoken", signer.address, provider)).balance;
|
|
74
|
+
await rpc.wallet.assets.approveAsset(chainId, "rwaindextoken", MockLiquidityPoolAddress, indextokenBalance, signer);
|
|
75
|
+
await (await MockLiquidityPoolContract.add_liquidity([
|
|
76
|
+
ethers_1.ethers.parseEther("100000000"),
|
|
77
|
+
ethers_1.ethers.parseEther(indextokenBalance.toString()),
|
|
78
|
+
], 0, signer.address)).wait();
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
async function setupLendingPool() {
|
|
82
|
+
const rpc = new RPCLibrary_1.default();
|
|
83
|
+
const provider = await getProvider();
|
|
84
|
+
const signer = await createWallet(TEST_MNEMONIC, provider);
|
|
85
|
+
// const rpc = new RPCLibrary();
|
|
86
|
+
rpc.address = signer.address;
|
|
87
|
+
rpc.provider = provider;
|
|
88
|
+
rpc.chainId = chainId;
|
|
89
|
+
const lendingPoolAddress = (0, contracts_1.getContractAddress)(chainId, "lendingpool");
|
|
90
|
+
const lendingPoolABI = (0, artifacts_1.getABI)("lendingpool");
|
|
91
|
+
const lendingPoolContract = new ethers_1.ethers.Contract(lendingPoolAddress, lendingPoolABI, signer);
|
|
92
|
+
const StabilityPoolAddress = (0, contracts_1.getContractAddress)(chainId, "stabilitypool");
|
|
93
|
+
const StabilityPoolABI = (0, artifacts_1.getABI)("stabilitypool");
|
|
94
|
+
const StabilityPoolContract = new ethers_1.ethers.Contract(StabilityPoolAddress, StabilityPoolABI, signer);
|
|
95
|
+
await rpc.wallet.assets.mintAsset(chainId, "crvusd", 2000000n, signer.address, signer);
|
|
96
|
+
await rpc.wallet.assets.approveAsset(chainId, "crvusd", lendingPoolAddress, "2000000", signer);
|
|
97
|
+
await rpc.pools.lendingPool.depositToLendingPool(chainId, "2000000", signer);
|
|
98
|
+
await rpc.wallet.assets.approveAsset(chainId, "rtoken", StabilityPoolAddress, "2000000", signer);
|
|
99
|
+
await rpc.pools.stabilityPool.depositToStabilityPool(chainId, "2000000", signer);
|
|
100
|
+
console.log("Deposited to stability pool.");
|
|
101
|
+
}
|
|
102
|
+
async function initiateLiquidation(adapter, user, data) {
|
|
103
|
+
const rpc = new RPCLibrary_1.default();
|
|
104
|
+
const provider = await getProvider();
|
|
105
|
+
const signer = await createWallet(TEST_MNEMONIC, provider);
|
|
106
|
+
// const rpc = new RPCLibrary();
|
|
107
|
+
rpc.address = signer.address;
|
|
108
|
+
rpc.provider = provider;
|
|
109
|
+
rpc.chainId = chainId;
|
|
110
|
+
const lendingPoolAddress = (0, contracts_1.getContractAddress)(chainId, "lendingpool");
|
|
111
|
+
const lendingPoolABI = (0, artifacts_1.getABI)("lendingpool");
|
|
112
|
+
const lendingPoolContract = new ethers_1.ethers.Contract(lendingPoolAddress, lendingPoolABI, signer);
|
|
113
|
+
const adapterAddress = rpc.pools.lendingPool.getAdapterAddress(chainId, adapter).address;
|
|
114
|
+
await await lendingPoolContract.initiateLiquidation(adapterAddress, user, data);
|
|
115
|
+
console.log("Liquidation initiated");
|
|
116
|
+
}
|
|
117
|
+
async function liquidate(pooladapter, vaultadapter, user, data) {
|
|
118
|
+
const rpc = new RPCLibrary_1.default();
|
|
119
|
+
const provider = await getProvider();
|
|
120
|
+
const signer = await createWallet(TEST_MNEMONIC, provider);
|
|
121
|
+
// const rpc = new RPCLibrary();
|
|
122
|
+
rpc.address = signer.address;
|
|
123
|
+
rpc.provider = provider;
|
|
124
|
+
rpc.chainId = chainId;
|
|
125
|
+
const StabilityPoolAddress = (0, contracts_1.getContractAddress)(chainId, "stabilitypool");
|
|
126
|
+
const StabilityPoolABI = (0, artifacts_1.getABI)("stabilitypool");
|
|
127
|
+
const StabilityPoolContract = new ethers_1.ethers.Contract(StabilityPoolAddress, StabilityPoolABI, signer);
|
|
128
|
+
const adapterAddress = rpc.pools.lendingPool.getAdapterAddress(chainId, pooladapter).address;
|
|
129
|
+
const vaultAddress = rpc.pools.rwaVault.getAdapterAddress(chainId, vaultadapter).address;
|
|
130
|
+
await await StabilityPoolContract.liquidateBorrower(adapterAddress, vaultAddress, user, data, 0);
|
|
131
|
+
console.log("Position liquidated.");
|
|
132
|
+
}
|
|
133
|
+
const updateNFTPrice = async (tokenId, price) => {
|
|
134
|
+
const provider = await getProvider();
|
|
135
|
+
const signer = await createWallet(TEST_MNEMONIC, provider);
|
|
136
|
+
const rpc = new RPCLibrary_1.default();
|
|
137
|
+
rpc.address = signer.address;
|
|
138
|
+
rpc.provider = provider;
|
|
139
|
+
rpc.chainId = chainId;
|
|
140
|
+
const housePriceAddress = (0, contracts_1.getContractAddress)(chainId, "raachouseprices");
|
|
141
|
+
const housePriceABI = (0, artifacts_1.getABI)("raachouseprices");
|
|
142
|
+
const housePriceContract = new ethers_1.ethers.Contract(housePriceAddress, housePriceABI, signer);
|
|
143
|
+
let tx;
|
|
144
|
+
tx = await housePriceContract.setHousePrice(tokenId, ethers_1.ethers.parseEther(price));
|
|
145
|
+
await tx.wait();
|
|
146
|
+
console.log(await rpc.nfts.getHousePrice(chainId, parseInt(tokenId), provider));
|
|
147
|
+
};
|
|
148
|
+
// Borrow: 50K out of 100K collateral
|
|
149
|
+
/**
|
|
150
|
+
*
|
|
151
|
+
* 1. First time after deployment of smart contracts, run `setupLiquidityPool` and `setupLendingPool
|
|
152
|
+
* 2. Query the position with `getPosition` -> index 3 tells if position is under liquidation or not. index 2 tells the health factor. if less than 10e18, liquidate.
|
|
153
|
+
* 3. Update the price to make the position liquidable
|
|
154
|
+
* 4. Initiate the liquidation
|
|
155
|
+
* 5. Liquidate
|
|
156
|
+
*/
|
|
157
|
+
setupLiquidityPool();
|
|
158
|
+
// setupLendingPool();
|
|
159
|
+
// updateNFTPrice("1", "760000");
|
|
160
|
+
// getPosition(
|
|
161
|
+
// "raacnftadapter",
|
|
162
|
+
// "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266",
|
|
163
|
+
// new ethers.AbiCoder().encode(["uint256"], ["1"])
|
|
164
|
+
// );
|
|
165
|
+
// initiateLiquidation(
|
|
166
|
+
// "raacnftadapter",
|
|
167
|
+
// "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266",
|
|
168
|
+
// new ethers.AbiCoder().encode(["uint256"], ["1"])
|
|
169
|
+
// );
|
|
170
|
+
// liquidate(
|
|
171
|
+
// "raacnftadapter",
|
|
172
|
+
// "raacnftadapter",
|
|
173
|
+
// "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266",
|
|
174
|
+
// new ethers.AbiCoder().encode(["uint256"], ["1"])
|
|
175
|
+
// );
|
|
176
|
+
// npx ts-node-dev --transpile-only --env-file=.env scripts/liquidation.ts
|
|
@@ -72,8 +72,8 @@ async function main() {
|
|
|
72
72
|
throw new Error('user_balances.csv was not created by users.ts');
|
|
73
73
|
}
|
|
74
74
|
// Step 2: Run analyze_transfers.ts to analyze EOA transfers
|
|
75
|
-
console.log('\n🔄 Step 2: Analyzing EOA transfers...');
|
|
76
|
-
await runScript('analyze_transfers.ts');
|
|
75
|
+
// console.log('\n🔄 Step 2: Analyzing EOA transfers...');
|
|
76
|
+
// await runScript('analyze_transfers.ts');
|
|
77
77
|
// Step 3: Run calculate_portfolio.ts to calculate total portfolio values
|
|
78
78
|
console.log('\n💰 Step 3: Calculating portfolio values...');
|
|
79
79
|
await runScript('calculate_portfolio.ts');
|
package/dist/scripts/users.js
CHANGED
|
@@ -35,17 +35,17 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
36
|
const ethers_1 = require("ethers");
|
|
37
37
|
const fs = __importStar(require("fs"));
|
|
38
|
-
const RPC_URL = 'https://eth-sepolia.
|
|
38
|
+
const RPC_URL = 'https://eth-sepolia.api.onfinality.io/rpc?apikey=8fe121c5-8961-4321-be50-6fd272c487d1'; // Replace with actual RPC
|
|
39
39
|
const provider = new ethers_1.ethers.JsonRpcProvider(RPC_URL);
|
|
40
|
-
const TOKEN_CONTRACT_ADDRESS = '
|
|
41
|
-
const NFT_CONTRACT_ADDRESS = '
|
|
42
|
-
const ORACLE_CONTRACT_ADDRESS = '
|
|
43
|
-
const R_TOKEN_ADDRESS = '
|
|
44
|
-
const DE_TOKEN_ADDRESS = '
|
|
45
|
-
const IRAAC_TOKEN_ADDRESS = '
|
|
40
|
+
const TOKEN_CONTRACT_ADDRESS = '0x990c1Aa9162d2c5B51378F86420f1752874e034B'; // ERC20 token contract
|
|
41
|
+
const NFT_CONTRACT_ADDRESS = '0x7421e594B65414d1b3eb5b798bc7bEeB2f834b6F'; // Add your ERC721 contract address here
|
|
42
|
+
const ORACLE_CONTRACT_ADDRESS = '0x5B2b86931846A66C178725CFd8fCae4bf2A08617'; // Add your oracle contract address here
|
|
43
|
+
const R_TOKEN_ADDRESS = '0x062a641EF54810B321f123487fFf083cadB50989';
|
|
44
|
+
const DE_TOKEN_ADDRESS = '0xE9594c6923a909528336009f0Ab916d72d28478e';
|
|
45
|
+
const IRAAC_TOKEN_ADDRESS = '0x531b322933ebc65b4A139a11139534A3872bEB1a';
|
|
46
46
|
// User to exclude from all calculations
|
|
47
47
|
const EXCLUDED_USER = '0x7FaE0737292cD3B7Dc9067AA30a67C42c205015c'.toLowerCase();
|
|
48
|
-
const START_BLOCK =
|
|
48
|
+
const START_BLOCK = 9022468;
|
|
49
49
|
const END_BLOCK = 'latest';
|
|
50
50
|
const BLOCK_RANGE_LIMIT = 500; // RPC limit for eth_getLogs
|
|
51
51
|
const ERC20_ABI = [
|
|
@@ -146,6 +146,7 @@ async function queryLogsInChunks(contract, filter, startBlock, endBlock) {
|
|
|
146
146
|
throw error;
|
|
147
147
|
}
|
|
148
148
|
}
|
|
149
|
+
// await new Promise(resolve => setTimeout(resolve, 100));
|
|
149
150
|
currentBlock = chunkEndBlock + 1;
|
|
150
151
|
}
|
|
151
152
|
return logs;
|
package/dist/test.js
ADDED
|
@@ -0,0 +1,323 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// scan-eoa-transfers.js
|
|
3
|
+
// Scans an ERC-20 for EOA<->EOA transfers and flags users who took part.
|
|
4
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
5
|
+
const ethers_1 = require("ethers");
|
|
6
|
+
// -----------------------------
|
|
7
|
+
// CONFIGURATION (edit these)
|
|
8
|
+
// -----------------------------
|
|
9
|
+
const RPC_URL = "https://eth-sepolia.api.onfinality.io/rpc?apikey=8fe121c5-8961-4321-be50-6fd272c487d1"; // <-- paste your RPC
|
|
10
|
+
const TOKEN = "0x990c1Aa9162d2c5B51378F86420f1752874e034B"; // ERC20 address
|
|
11
|
+
const USERS = [
|
|
12
|
+
"0xaa8feb682a1f1bb2ec11fc7678c2a0e5ce7191d5",
|
|
13
|
+
"0xdead86a4423ebf01fdd3e241f83a8c7815da175a",
|
|
14
|
+
"0x33b8ffddc13ee90ccd347743137712b889f14cba",
|
|
15
|
+
"0xccbe9d8e6a2f4260f675c3dcdeb83ee04125d7ae",
|
|
16
|
+
"0x44cc55fd4672b529f4c930d1cffadd71071fbd14",
|
|
17
|
+
"0x9d7a5e8bfff5eab6368ecd2d447090cce01b4332",
|
|
18
|
+
"0x2e2214e2b075cd95014924b023863a4876f128f6",
|
|
19
|
+
"0xbfad07b9c590ae5fe8a1d2cb0af32448fa6c661e",
|
|
20
|
+
"0xdb46916abac222b2d2ff9fe170e673ad76f8b424",
|
|
21
|
+
"0x5297314f612af413e15077be7ceeee2b14568b4d",
|
|
22
|
+
"0x10994e2f51ea345d1e12ab1911a994c86e66dfb3",
|
|
23
|
+
"0x6c91d4a3935dcd7912d56c4809b683bf06924d2d",
|
|
24
|
+
"0x9b02685b84cd7d9deb322e9443dcdbc875d9526a",
|
|
25
|
+
"0xa243b41d244686a31b2e3253a8d03571f31034b8",
|
|
26
|
+
"0x8e26d167ec9991bebf2e44278064270764acc5eb",
|
|
27
|
+
"0x6080557fcfcfb099d02eeb46301a1fc1ca1270ec",
|
|
28
|
+
"0xa0fe7f20c86ba9d9c51e9024fe27bf6665df5ba9",
|
|
29
|
+
"0xc998661079962ef4e6c55d77802e23c86a2e3de6",
|
|
30
|
+
"0x68aea74ba55bf03ee93c95552838cadcf7b68f48",
|
|
31
|
+
"0xe711c9edd895dac4ac3b39e3c4348681f2ac19b8",
|
|
32
|
+
"0xf10c0768ebd3deca476d9eacbf03ed471ff3e5e7",
|
|
33
|
+
"0x727c3ae2c043a83bb64bc020a5c12380fa06fdad",
|
|
34
|
+
"0x9bf8e700a85778d5785657a088a9f00813f52574",
|
|
35
|
+
"0x3451a7d35e7fe3238206f3916fa484312a27508a",
|
|
36
|
+
"0x9eb2ae4870f801923ee092fc751f910e2c901c08",
|
|
37
|
+
"0x9037155800d06ee9d730ee4bf8d003c683afb505",
|
|
38
|
+
"0xdfc0b33187a103926533eed12086130927b9c7bd",
|
|
39
|
+
"0xeab65c22d648dda0351d1d1f05ca1682040b27a9",
|
|
40
|
+
"0x13bc02b0ef6015bfd19bc33db75f90599b5213d6",
|
|
41
|
+
"0xe78f5838c82245269590b12ff7286e55bcc83344",
|
|
42
|
+
"0xb39c8ac9a5c6c9eff41ae0b78aab9057278b5ba1",
|
|
43
|
+
"0xfdda07db0d43ba809914434b538219863e48f745",
|
|
44
|
+
"0x21b507bbf8ae3db652a7986555a1e19374d81dc5",
|
|
45
|
+
"0xf60c306c0c7cd8d4f13f401135a7cf9ee2b8e058",
|
|
46
|
+
"0xe867fe1bb11f6eef08452ff1bb53ced14b04b608",
|
|
47
|
+
"0x31b349b3e5193047c7f1a4bf55a3462e7876d29b",
|
|
48
|
+
"0x8b7340b81b663dc37f2c77471ae3f33014e5ad2f",
|
|
49
|
+
"0x1b3e1a37989263dabf5481d90be15abdcf2b73db",
|
|
50
|
+
"0xf41aee99d6d44e2de458bc44c8036fa434f28a85",
|
|
51
|
+
"0x7286f61a10ae0d947afbb77dfd728d719ec6bbd5",
|
|
52
|
+
"0x3fdc6f8749b6755785b1897fccf67877a666ba5a",
|
|
53
|
+
"0xae0968128bf0cd8fa5a3f74f829db55ccc81d003",
|
|
54
|
+
"0xb6562eb83ed59947eef93b766a072ab43d1171b7",
|
|
55
|
+
"0x1ba77ed03ed2e0e1e7f270251a4edec4b8241880",
|
|
56
|
+
"0x5c98baf16bdea49d467d7c0e08cad275d90cd887",
|
|
57
|
+
"0x801fc65ce4681a883d60941e7f30c78e7847e818",
|
|
58
|
+
"0x42098837ff07c975b2ca52ddb43bf4a1be4c5db0",
|
|
59
|
+
"0x00b2b949eb4f89451ec68aa28c55c387bc8437a7",
|
|
60
|
+
"0x4f8172e4ffc05325221a74b842e921f8a8a9e42c",
|
|
61
|
+
"0x64a3997b07b983d49a3b76c03630ea5b22a8c910",
|
|
62
|
+
"0x796f8c9e403e507d244b258988c7eb47e239a6e1",
|
|
63
|
+
"0x95b8ccdf5a3314dc2ec529cb01bd4a195e6c9e42",
|
|
64
|
+
"0xa7b0fd5281ab305cc6f5d2fe31860e09d40c416f",
|
|
65
|
+
"0x8e19a226813dfeef60159b09f8547ec4a2bd53e5",
|
|
66
|
+
"0xbaa0737866472b100f8c18a2c7c8d5342be678b9",
|
|
67
|
+
"0xf55bda6a8a1b84cd2c9c1d9cde9bba6b6f395066",
|
|
68
|
+
"0xac3b87cd02021dae75d75abe350d607a2e147e31",
|
|
69
|
+
"0xb6bf4b0036e1204d7635b0baf6a188711a5ce764",
|
|
70
|
+
"0xa31459e924801e2f094f89176e59f92d243dd557",
|
|
71
|
+
"0x52ff2d74140b264e6e4c214afc1890dafea8fb31",
|
|
72
|
+
"0x48fa6ff72fdf908c98eb2de0633360d6545553b1",
|
|
73
|
+
"0x72f4a5da0ecb178e44d20f0a4c7ca05191d2e1d4",
|
|
74
|
+
"0xe8707973a0c02b0db771b90fa42dd76c936df7d1",
|
|
75
|
+
"0xdb7298defc414204ced0cf678a19285183e98582",
|
|
76
|
+
"0xb03b334be9847789a234a9383cb0a74ef8e7d9d9",
|
|
77
|
+
"0xcea3405cf4d35b7dfd2ed7b344f44c7d19697ca2",
|
|
78
|
+
"0x65ed98fec403bdce02b9d6312bf552bd6c9dc274",
|
|
79
|
+
"0x4913470e2861e7c01d447df22375704ed2d1ca94",
|
|
80
|
+
"0x0fd212aef31734b65852700f61e307017ce85249",
|
|
81
|
+
"0xefc61b4d4da8f01c3fa2bf5b03f2702978fae4e8",
|
|
82
|
+
"0x709e9a950e2dca08d3848ca00e99630d4651e978",
|
|
83
|
+
"0xcf00d3f119dcd3070455995b90b6c08f0afce1ae",
|
|
84
|
+
"0x82a5794ee454e97fd2922d0072604f31c689baf4",
|
|
85
|
+
"0x8ea1d07a960045d51bc03766ca179e6704a39165",
|
|
86
|
+
"0x358c90cce8f355d5eded44b953b8ec053028cd2a",
|
|
87
|
+
"0x11f23e7875cc409f36d43c652ac8f4eda674ddc6",
|
|
88
|
+
"0x4ebf54c6949c0eda2a7f27f4c3a0b9992ca8d312",
|
|
89
|
+
"0x4863df12ab6bfd9aa60dfe44c8c55332a5984d19",
|
|
90
|
+
"0xf11cbae7e9fb03ff63f9a329e9cdf31895e0235f",
|
|
91
|
+
"0xd00866c6494ce790f98ac540e130063bc89906bb",
|
|
92
|
+
"0xd0f3b5b3df8cfc7c679702adeccc7d43444b4c8b",
|
|
93
|
+
"0xc556faead7fb1e5730a56bdc2517e10674106577",
|
|
94
|
+
"0x8b66758512bdcc9233f2d936908c360e4a60c30a",
|
|
95
|
+
"0x6e1732843d514ec263de45900b82bc92a7b5e3b8",
|
|
96
|
+
"0x3942d819ab4eb6b72bc054b4848ca1faf5857999",
|
|
97
|
+
"0x9cc7743adca797957cdfa1c3e917bd641f1f4cdb",
|
|
98
|
+
"0xb9fde73e0f06206f1374edce095b4f62f8cd1ca7",
|
|
99
|
+
"0xe36d3aa06f8b2c687411f18ccda75048125e7856",
|
|
100
|
+
"0xaff8cdee16c26485f9f4591fcaafd47aeff0cc9f",
|
|
101
|
+
"0x76f17c90bf1372bbecdaa7a06f12a7005cf0a9e2",
|
|
102
|
+
"0xad4b3eb841c43e1ec9cba909a52173c21c5ca48c",
|
|
103
|
+
"0x7d17a1532ab7122a7b9024c17deb0580d28c419c",
|
|
104
|
+
"0x10902978eb652ebe15bb987199bb99f9b634734d",
|
|
105
|
+
"0x2125f4632c5fb406311e30c923a59fe4fc314e96",
|
|
106
|
+
"0xef5b8335e830087903e0145e9893909deb1177a9",
|
|
107
|
+
"0x44e63a76a408a5cf38df5ed5496a202fed552ef1",
|
|
108
|
+
"0x3ed3b18865e96309f582dc76aa72c184fdfd4a4e",
|
|
109
|
+
"0xf075f1b6e428d8a34866614d484da9c37fb8f76c",
|
|
110
|
+
"0x123440df8a9e6e42a496c70a95e2ab736bfe2269",
|
|
111
|
+
"0xf5d1bf94027c776a69b014093496f6d7cc4393f8",
|
|
112
|
+
"0x897c418581bcb66b6d2f148bf339eedf36f57cdc",
|
|
113
|
+
"0x19851266d569533a489cf22cb3ee592889a99737",
|
|
114
|
+
"0x5a4f8e730a34b81dbf25947d8cea4e652190234c",
|
|
115
|
+
"0x14ca0be44d0c6955d41da3fdda60572db7e672ee",
|
|
116
|
+
"0xc98bce63913c180f876f32f1372696792ca81399",
|
|
117
|
+
"0x196f15c4f8237389528bc26aee8a250d877e4c18",
|
|
118
|
+
"0x63aaef804849d01cfebbd86141d5833adad0082b",
|
|
119
|
+
"0x9872a26f6ca7f0563c799ad618587165961a7e91",
|
|
120
|
+
"0xd2932f4cb29cfe5c6b8e5d372d428e94dd28f9a0",
|
|
121
|
+
"0x68462e70b2597e0770d39c7193be4b27775798db",
|
|
122
|
+
"0xe5fde66a48f59cbe98ec64332f6e1f9968a21abf",
|
|
123
|
+
"0x8e6ab83637bf7aa95bb48e1ab4e7b1cb2d7bd5c2",
|
|
124
|
+
"0xb1e3ad90056843cfd2edec03de4c45c90bc9833b",
|
|
125
|
+
"0xcb6dfa7c5f904293b26098b6b3adb2fdaec749f6",
|
|
126
|
+
"0x3383af6e395e3ef92f511514a3a0adac8a078f2c",
|
|
127
|
+
"0xeabce6bcd916db43013d5fb063c29ec648f2abec",
|
|
128
|
+
"0x647cf01ca89c24c219fb0796411cd27634b5355f",
|
|
129
|
+
"0xae6e14c2fe77498179245ff079eb32a3e661b3e3",
|
|
130
|
+
"0x5b0adcd0798e83168545d12429690ee4366266bc",
|
|
131
|
+
"0xc99cefda3cc4ed61e60c6a66358fbbd042b4d575",
|
|
132
|
+
"0xa637eb0f0eb6543055b90b1d59c7550fbfb96867",
|
|
133
|
+
"0x4bb46b1b4e7cb73e279ad0a33b6b410d3d1f5012",
|
|
134
|
+
"0xbc5d52091deff0a7b863db2bf87749688d6bc5cd",
|
|
135
|
+
"0xa2dc5bfbec6fa84c4277e96c4aefbdf040ded318",
|
|
136
|
+
"0xe2a8592528eb12bae2bd39fbc246ba7b02f52dec",
|
|
137
|
+
"0x5abe5465b76a818280b3353930bfcc46300dafae",
|
|
138
|
+
"0xc6d03cb1c5b443d6bcc9d8416ae4aa4554e163a6",
|
|
139
|
+
"0x20a42e58d5d65f83b3511dbf480855e529424156",
|
|
140
|
+
"0x80757ec666148c7806cc34959b2c65b580a09eb0",
|
|
141
|
+
"0x6f8348b951943fa0a2a6065067eb2bd6180c244d",
|
|
142
|
+
"0x37f1f895efafdfd2cf065aba31fc2413c808fed7",
|
|
143
|
+
"0x99cd061cc8bef4ebb3034db5203987b82489b37d",
|
|
144
|
+
"0x32aa1693495d4d1885a196c8cd0a3be1bc6268dd",
|
|
145
|
+
"0x9d2482fd4cb034d803cde0e7252e5a02a9cab869",
|
|
146
|
+
"0xa318753ac1492fb095900c0719ec6b8cc1c4d950",
|
|
147
|
+
"0xa51a6af3cc7763aab6d4c1ce502121e518c485f4",
|
|
148
|
+
"0x2aad9ed56ed6b7b28128d3f5e8ae0a5e60bee047",
|
|
149
|
+
"0x808ff374b7a5e5c6afab8d9a9aa3de2ae731dc50",
|
|
150
|
+
"0x2d45dde25b79f8cd2b87eb0c655b47e286215db6",
|
|
151
|
+
"0x341bdbc6e74b5ad7605ae5d32aaf0930cd609e98",
|
|
152
|
+
"0x891baf086668e931009ba74d50db9025e6fcd841",
|
|
153
|
+
"0x1e19737ca8287c3e5bd918cbb2f213800ddcbbcb",
|
|
154
|
+
"0xb327ed592e8fa46779f4c6db6f058276447d2232",
|
|
155
|
+
"0x833e2d8c50395f949be6349156f807b0fab8e89f",
|
|
156
|
+
"0xb3afe7aa10f8a1f344ecea5b4c48a56a789df69c",
|
|
157
|
+
"0x4fb6976c5acd768e57abc700e58296eaafa4b20e",
|
|
158
|
+
"0xbcf278559ac161d385502472ee22e8c399673e60",
|
|
159
|
+
"0xbcf278559ac161d385502472ee22e8c399673e60",
|
|
160
|
+
"0x4b3d5d3e0f529e93da18d92be5c2346722d880d5",
|
|
161
|
+
"0xd87e84fd6fee50559439dfe59cca1103d567cc5a",
|
|
162
|
+
"0xe3f5145e1673e0e534a890e864f2d2f6189acebb",
|
|
163
|
+
"0x67bf221988e76adf22b33baec3e5df20d2d73a9d",
|
|
164
|
+
"0x08fccc76b092cb178d720739b8df565af653d4bd",
|
|
165
|
+
"0xf166935ef8ed03fbd00d33b1631cfa0a9a7421aa",
|
|
166
|
+
"0xa81ba780dfd7649047cd32429f33cb54d8962957",
|
|
167
|
+
"0x6e1d7dd6e9157deae96f6409dcbb1729a9d821e1",
|
|
168
|
+
"0x683895f9b6f6e587102d8eb7aaa3c07b507ef005",
|
|
169
|
+
"0xe8931946e8dd28af50dcb33c68e605cd96029750",
|
|
170
|
+
"0xc29e8d2e5fde00dccc080ce8ccfd4808477d0421",
|
|
171
|
+
"0x24caf788d3668581627dc7eca8f50d08b2ecd200",
|
|
172
|
+
"0xe132d1f6543b951c362f2c69a3ec89521b03a8da",
|
|
173
|
+
"0x8210a5f09e1d891c20fee08b5a1699f3029e30d3",
|
|
174
|
+
"0xe6d0e8cc99e75467e9454d50627970f847e571d7",
|
|
175
|
+
"0x0fc86e9ed2668359959ad2af55e5baa549f6ca52",
|
|
176
|
+
"0x7c81901309443b6b5d854836ce2231475883c4af",
|
|
177
|
+
"0x663fdb8d9d293a1178800ac83a1037ae5e81a026",
|
|
178
|
+
"0xe5e1cc1a8e4f13d9041c335f34b5773d75453cfd",
|
|
179
|
+
"0x28ba7be1c233e4ffb5922bac375ec0da5ec3d379",
|
|
180
|
+
"0xe21c24e87fb04641d7da88ea5c2000097d247cf9",
|
|
181
|
+
"0x52e611353ddf63f75c4462c97db873eeb48adeb6",
|
|
182
|
+
"0x57f5bb09f95a99054e3d2dbf599e5560d6d47bef",
|
|
183
|
+
"0xd42cbdf0e27b853fabc1c23b8278f8d62a729748",
|
|
184
|
+
"0xc0c495fc4afdc2aef35ec377ba380268a60a1c39",
|
|
185
|
+
"0x65571f681c51d4f803b901e8f4d8ad11dfa8db02",
|
|
186
|
+
"0x456323e8e04cfcca3e078e624c9115f013fec787",
|
|
187
|
+
"0x80ad59cf8fe66c7b01054fe2afba37eb6efcc99b",
|
|
188
|
+
"0x0a72da0f5b4432e40e518528107ddab26ec2d806",
|
|
189
|
+
"0x9d44ac26afce1428f26a04009c89d576e72967f4",
|
|
190
|
+
"0xbdd1e4fd2aad993eb5954dd6dff6824e43763f5e",
|
|
191
|
+
"0xa6ef34c6cd494dbf4d9ad8ad30963552a5fbbffe",
|
|
192
|
+
"0xd9ee988a898464d848b57ae32fd8cce0991ba24f",
|
|
193
|
+
"0x3a23d1eadd8eb1c74a6ccb5d6e4562db0778a8df",
|
|
194
|
+
"0xd7eab2b829844e842064ffd2df37bee5cf23286a",
|
|
195
|
+
"0x6f50efe6885d3057718d48ae6d694651e15ea069",
|
|
196
|
+
"0x9e92f056b1ed6dc12cbe726f2b17f21a908a8382",
|
|
197
|
+
"0xbbb514f18b8bdc7ea394e744efefebc46c4218f8",
|
|
198
|
+
"0xe173d190b2174a5371fa53b7a6c59ef1ef2b9d19",
|
|
199
|
+
"0xd42f264dcc55123b78332b3ef327243af346425f",
|
|
200
|
+
"0xe11236f53d71a90dcee83b70d880753c753c8621",
|
|
201
|
+
"0x2b671d7ef258d53dc5098f219d8880fa2fa8df60",
|
|
202
|
+
"0x183f246b0daf3bb43f42fef532b2cd99a2c2877c",
|
|
203
|
+
"0xac6d9220e99d9d229b411d8889d1bd1c4c88ff6b",
|
|
204
|
+
"0x82fa32993fff3bc87777136d28935b9e89a6195d",
|
|
205
|
+
"0x7cb2558debffcbd14a3fd57b257ab2ba304f71a5",
|
|
206
|
+
"0xe5046c63230deba2e8bc98e2c6d2903dfdde8702",
|
|
207
|
+
"0xf1166e5994ded6e9496fc27eb4f88b18d94885cd",
|
|
208
|
+
"0x840a3923d2ce0e7264f84da4aa5ca34527dfde55",
|
|
209
|
+
"0x7d2f93966e13a014f18f0e0103bb3d0bf164ff82",
|
|
210
|
+
"0x1cd1761285b7fde395e8636a89a3971460549fb1",
|
|
211
|
+
"0x3d71d9fbf9f45dc0a03a7354281e7de05fc7187e"
|
|
212
|
+
];
|
|
213
|
+
const START_BLOCK = 9111100;
|
|
214
|
+
const END_BLOCK = 9145047;
|
|
215
|
+
const BATCH_SIZE = 400; // must be <= 500 for Alchemy
|
|
216
|
+
// -----------------------------
|
|
217
|
+
const provider = new ethers_1.JsonRpcProvider(RPC_URL);
|
|
218
|
+
// Minimal ERC-20 ABI
|
|
219
|
+
const ERC20_IFACE = new ethers_1.Interface([
|
|
220
|
+
"event Transfer(address indexed from, address indexed to, uint256 value)"
|
|
221
|
+
]);
|
|
222
|
+
const TRANSFER_TOPIC = ERC20_IFACE.getEvent("Transfer").topicHash;
|
|
223
|
+
const userList = USERS.map((a) => (0, ethers_1.getAddress)(a));
|
|
224
|
+
const usersSet = new Set(userList.map((a) => a.toLowerCase()));
|
|
225
|
+
const codeCache = new Map(); // addrLower -> "0x" or bytecode
|
|
226
|
+
async function isEOA(addr) {
|
|
227
|
+
const key = addr.toLowerCase();
|
|
228
|
+
if (codeCache.has(key))
|
|
229
|
+
return codeCache.get(key) === "0x";
|
|
230
|
+
const code = await provider.getCode(addr);
|
|
231
|
+
codeCache.set(key, code);
|
|
232
|
+
return code === "0x";
|
|
233
|
+
}
|
|
234
|
+
function* blockBatches(start, end, size) {
|
|
235
|
+
let from = start;
|
|
236
|
+
while (from <= end) {
|
|
237
|
+
const to = Math.min(from + size - 1, end);
|
|
238
|
+
yield [from, to];
|
|
239
|
+
from = to + 1;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
function sleep(ms) {
|
|
243
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
244
|
+
}
|
|
245
|
+
async function main() {
|
|
246
|
+
const token = (0, ethers_1.getAddress)(TOKEN);
|
|
247
|
+
const flagged = new Set();
|
|
248
|
+
const flaggedTxs = {}; // user -> array of tx hashes
|
|
249
|
+
for (const [fromBlock, toBlock] of blockBatches(START_BLOCK, END_BLOCK, BATCH_SIZE)) {
|
|
250
|
+
const logs = await provider.getLogs({
|
|
251
|
+
address: token,
|
|
252
|
+
fromBlock,
|
|
253
|
+
toBlock,
|
|
254
|
+
topics: [TRANSFER_TOPIC],
|
|
255
|
+
});
|
|
256
|
+
console.log(`Scanned blocks ${fromBlock} → ${toBlock}, found ${logs.length} logs`);
|
|
257
|
+
const candidates = new Set();
|
|
258
|
+
const decoded = [];
|
|
259
|
+
for (const log of logs) {
|
|
260
|
+
try {
|
|
261
|
+
const parsed = ERC20_IFACE.parseLog(log);
|
|
262
|
+
const from = (0, ethers_1.getAddress)(parsed.args.from);
|
|
263
|
+
const to = (0, ethers_1.getAddress)(parsed.args.to);
|
|
264
|
+
// skip minting (from == zero address)
|
|
265
|
+
if (from.toLowerCase() === ethers_1.ZeroAddress.toLowerCase())
|
|
266
|
+
continue;
|
|
267
|
+
if (usersSet.has(from.toLowerCase()) || usersSet.has(to.toLowerCase())) {
|
|
268
|
+
decoded.push({ from, to, txHash: log.transactionHash });
|
|
269
|
+
candidates.add(from.toLowerCase());
|
|
270
|
+
candidates.add(to.toLowerCase());
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
catch {
|
|
274
|
+
// skip
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
// Preload contract codes
|
|
278
|
+
await Promise.all(Array.from(candidates).map(async (addrLower) => {
|
|
279
|
+
if (!codeCache.has(addrLower)) {
|
|
280
|
+
const code = await provider.getCode(addrLower);
|
|
281
|
+
codeCache.set(addrLower, code);
|
|
282
|
+
}
|
|
283
|
+
}));
|
|
284
|
+
for (const { from, to, txHash } of decoded) {
|
|
285
|
+
const eoaFrom = codeCache.get(from.toLowerCase()) === "0x";
|
|
286
|
+
const eoaTo = codeCache.get(to.toLowerCase()) === "0x";
|
|
287
|
+
if (eoaFrom && eoaTo) {
|
|
288
|
+
// Always flag FROM
|
|
289
|
+
flagged.add(from.toLowerCase());
|
|
290
|
+
flaggedTxs[from.toLowerCase()] = flaggedTxs[from.toLowerCase()] || [];
|
|
291
|
+
flaggedTxs[from.toLowerCase()].push(txHash);
|
|
292
|
+
// Always flag TO
|
|
293
|
+
flagged.add(to.toLowerCase());
|
|
294
|
+
flaggedTxs[to.toLowerCase()] = flaggedTxs[to.toLowerCase()] || [];
|
|
295
|
+
flaggedTxs[to.toLowerCase()].push(txHash);
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
// throttle
|
|
299
|
+
await sleep(200);
|
|
300
|
+
}
|
|
301
|
+
if (flagged.size === 0) {
|
|
302
|
+
console.log("No users had an EOA<->EOA transfer (ignoring minting).");
|
|
303
|
+
return;
|
|
304
|
+
}
|
|
305
|
+
const flaggedChecksum = userList.filter((u) => flagged.has(u.toLowerCase()));
|
|
306
|
+
console.log("Flagged addresses (copy-paste ready):");
|
|
307
|
+
for (const u of flaggedChecksum) {
|
|
308
|
+
console.log(`"${u.toLowerCase()}",`);
|
|
309
|
+
}
|
|
310
|
+
console.log("\nSummary with example transactions:");
|
|
311
|
+
for (const u of flaggedChecksum) {
|
|
312
|
+
const txs = flaggedTxs[u.toLowerCase()] || [];
|
|
313
|
+
console.log(`User: ${u}`);
|
|
314
|
+
console.log(` Example tx: ${txs[0]}`);
|
|
315
|
+
if (txs.length > 1) {
|
|
316
|
+
console.log(` (+${txs.length - 1} more txs)`);
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
main().catch((e) => {
|
|
321
|
+
console.error(e);
|
|
322
|
+
process.exit(1);
|
|
323
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|