-
Notifications
You must be signed in to change notification settings - Fork 14
Expand file tree
/
Copy pathetherfiQueue.test.js
More file actions
104 lines (90 loc) · 3.51 KB
/
Copy pathetherfiQueue.test.js
File metadata and controls
104 lines (90 loc) · 3.51 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
const assert = require("assert");
const { AbiCoder, Contract, id, parseUnits } = require("ethers");
const {
etherFiRequestStatuses,
selectClaimableEtherFiRequests,
splitEtherFiWithdrawAmount,
} = require("../../src/js/tasks/etherfiQueue");
const coder = AbiCoder.defaultAbiCoder();
const selector = (signature) => id(signature).slice(0, 10);
const run = async () => {
// Ether.fi rejects individual withdrawal requests above 1,000 eETH.
assert.deepStrictEqual(splitEtherFiWithdrawAmount(parseUnits("1000")), [
parseUnits("1000"),
]);
assert.deepStrictEqual(splitEtherFiWithdrawAmount(parseUnits("1971.5")), [
parseUnits("1000"),
parseUnits("971.5"),
]);
assert.deepStrictEqual(splitEtherFiWithdrawAmount(parseUnits("2000")), [
parseUnits("1000"),
parseUnits("1000"),
]);
// weETH uses the adapter-provided share amount equivalent to 1,000 eETH.
assert.deepStrictEqual(
splitEtherFiWithdrawAmount(parseUnits("1800"), parseUnits("950")),
[parseUnits("950"), parseUnits("850")],
);
// Pure filter: finalized AND still valid on-chain is the only claimable state.
{
const statuses = [
// Already claimed: the NFT is burnt so isValid is false even though
// EtherFi still reports isFinalized true. Regression for the recurring
// "ERC721: invalid token ID" failure (mainnet request 80636).
{ requestId: 80636, isFinalized: true, isValid: false },
// Requested but not yet finalized: valid but can't be claimed yet.
{ requestId: 80648, isFinalized: false, isValid: true },
// Genuinely claimable.
{ requestId: 80641, isFinalized: true, isValid: true },
];
assert.deepStrictEqual(selectClaimableEtherFiRequests(statuses), [80641]);
}
// End-to-end status read + filter against a mock WithdrawRequestNFT, proving
// the stale request 80636 that wedged autoClaimEtherFiWithdraw is dropped.
{
const selectors = {
isFinalized: selector("isFinalized(uint256)"),
getRequest: selector("getRequest(uint256)"),
};
const requestId = (data) => BigInt(`0x${data.slice(10)}`).toString();
// isFinalized mirrors lastFinalizedRequestId: true for ids <= 80647.
const finalizedById = { 80636: true, 80641: true, 80648: false };
// isValid is false for the already-claimed/burnt 80636.
const validById = { 80636: false, 80641: true, 80648: true };
const runner = {
call: async (tx) => {
const fn = tx.data.slice(0, 10);
const key = requestId(tx.data);
if (fn === selectors.isFinalized) {
return coder.encode(["bool"], [finalizedById[key]]);
}
if (fn === selectors.getRequest) {
return coder.encode(
["tuple(uint96,uint96,bool,uint32)"],
[[0n, 0n, validById[key], 0]],
);
}
throw new Error(`unexpected selector ${tx.data}`);
},
};
const withdrawalNFT = new Contract(
"0x7d5706f6ef3F89B3951E23e557CDFBC3239D4E2c",
[
"function isFinalized(uint256 requestId) view returns (bool)",
"function getRequest(uint256 requestId) view returns (tuple(uint96 amountOfEEth, uint96 shareOfEEth, bool isValid, uint32 feeGwei))",
],
runner,
);
const statuses = await etherFiRequestStatuses(
withdrawalNFT,
[80636, 80641, 80648],
);
assert.deepStrictEqual(selectClaimableEtherFiRequests(statuses), [80641]);
}
};
run()
.then(() => console.log("etherfiQueue tests passed"))
.catch((error) => {
console.error(error);
process.exitCode = 1;
});