@sablier/bob 1.0.1

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.
Files changed (42) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/LICENSE-BUSL.md +82 -0
  3. package/LICENSE-GPL.md +470 -0
  4. package/LICENSE.md +9 -0
  5. package/README.md +81 -0
  6. package/artifacts/BobVaultShare.json +936 -0
  7. package/artifacts/SablierBob.json +1683 -0
  8. package/artifacts/SablierEscrow.json +1316 -0
  9. package/artifacts/SablierLidoAdapter.json +1649 -0
  10. package/artifacts/erc20/IERC20.json +226 -0
  11. package/artifacts/interfaces/IBobVaultShare.json +393 -0
  12. package/artifacts/interfaces/ISablierBob.json +1171 -0
  13. package/artifacts/interfaces/ISablierEscrow.json +999 -0
  14. package/artifacts/interfaces/ISablierLidoAdapter.json +1141 -0
  15. package/artifacts/interfaces/external/ICurveStETHPool.json +128 -0
  16. package/artifacts/interfaces/external/ILidoWithdrawalQueue.json +209 -0
  17. package/artifacts/interfaces/external/IStETH.json +262 -0
  18. package/artifacts/interfaces/external/IWETH9.json +259 -0
  19. package/artifacts/interfaces/external/IWstETH.json +311 -0
  20. package/artifacts/libraries/Errors.json +868 -0
  21. package/package.json +68 -0
  22. package/src/BobVaultShare.sol +119 -0
  23. package/src/SablierBob.sol +543 -0
  24. package/src/SablierEscrow.sol +288 -0
  25. package/src/SablierLidoAdapter.sol +549 -0
  26. package/src/abstracts/SablierBobState.sol +156 -0
  27. package/src/abstracts/SablierEscrowState.sol +159 -0
  28. package/src/interfaces/IBobVaultShare.sol +51 -0
  29. package/src/interfaces/ISablierBob.sol +261 -0
  30. package/src/interfaces/ISablierBobAdapter.sol +157 -0
  31. package/src/interfaces/ISablierBobState.sol +74 -0
  32. package/src/interfaces/ISablierEscrow.sol +148 -0
  33. package/src/interfaces/ISablierEscrowState.sol +77 -0
  34. package/src/interfaces/ISablierLidoAdapter.sol +110 -0
  35. package/src/interfaces/external/ICurveStETHPool.sol +31 -0
  36. package/src/interfaces/external/ILidoWithdrawalQueue.sol +67 -0
  37. package/src/interfaces/external/IStETH.sol +18 -0
  38. package/src/interfaces/external/IWETH9.sol +19 -0
  39. package/src/interfaces/external/IWstETH.sol +32 -0
  40. package/src/libraries/Errors.sol +189 -0
  41. package/src/types/Bob.sol +49 -0
  42. package/src/types/Escrow.sol +49 -0
@@ -0,0 +1,128 @@
1
+ {
2
+ "abi": [
3
+ {
4
+ "type": "function",
5
+ "name": "exchange",
6
+ "inputs": [
7
+ { "name": "i", "type": "int128", "internalType": "int128" },
8
+ { "name": "j", "type": "int128", "internalType": "int128" },
9
+ { "name": "dx", "type": "uint256", "internalType": "uint256" },
10
+ { "name": "minDy", "type": "uint256", "internalType": "uint256" }
11
+ ],
12
+ "outputs": [{ "name": "dy", "type": "uint256", "internalType": "uint256" }],
13
+ "stateMutability": "payable"
14
+ },
15
+ {
16
+ "type": "function",
17
+ "name": "get_dy",
18
+ "inputs": [
19
+ { "name": "i", "type": "int128", "internalType": "int128" },
20
+ { "name": "j", "type": "int128", "internalType": "int128" },
21
+ { "name": "dx", "type": "uint256", "internalType": "uint256" }
22
+ ],
23
+ "outputs": [{ "name": "dy", "type": "uint256", "internalType": "uint256" }],
24
+ "stateMutability": "view"
25
+ }
26
+ ],
27
+ "bytecode": { "object": "0x", "sourceMap": "", "linkReferences": {} },
28
+ "deployedBytecode": { "object": "0x", "sourceMap": "", "linkReferences": {} },
29
+ "methodIdentifiers": {
30
+ "exchange(int128,int128,uint256,uint256)": "3df02124",
31
+ "get_dy(int128,int128,uint256)": "5e0d443f"
32
+ },
33
+ "rawMetadata": "{\"compiler\":{\"version\":\"0.8.29+commit.ab55807c\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"int128\",\"name\":\"i\",\"type\":\"int128\"},{\"internalType\":\"int128\",\"name\":\"j\",\"type\":\"int128\"},{\"internalType\":\"uint256\",\"name\":\"dx\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"minDy\",\"type\":\"uint256\"}],\"name\":\"exchange\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"dy\",\"type\":\"uint256\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"int128\",\"name\":\"i\",\"type\":\"int128\"},{\"internalType\":\"int128\",\"name\":\"j\",\"type\":\"int128\"},{\"internalType\":\"uint256\",\"name\":\"dx\",\"type\":\"uint256\"}],\"name\":\"get_dy\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"dy\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"details\":\"The pool has two tokens: ETH (index 0) and stETH (index 1).\",\"kind\":\"dev\",\"methods\":{\"exchange(int128,int128,uint256,uint256)\":{\"params\":{\"dx\":\"The amount of input coin to exchange.\",\"i\":\"The index of the input coin (0 = ETH, 1 = stETH).\",\"j\":\"The index of the output coin (0 = ETH, 1 = stETH).\",\"minDy\":\"The minimum amount of output coin to receive.\"},\"returns\":{\"dy\":\"The actual amount of output coin received.\"}},\"get_dy(int128,int128,uint256)\":{\"params\":{\"dx\":\"The amount of input coin.\",\"i\":\"The index of the input coin.\",\"j\":\"The index of the output coin.\"},\"returns\":{\"dy\":\"The expected amount of output coin.\"}}},\"title\":\"ICurveStETHPool\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"exchange(int128,int128,uint256,uint256)\":{\"notice\":\"Exchange between two tokens in the pool.\"},\"get_dy(int128,int128,uint256)\":{\"notice\":\"Get the amount of output coin for a given input.\"}},\"notice\":\"Minimal interface for the Curve stETH/ETH pool.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"src/interfaces/external/ICurveStETHPool.sol\":\"ICurveStETHPool\"},\"evmVersion\":\"shanghai\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":1000000},\"remappings\":[\":@arbitrum/=node_modules/@arbitrum/\",\":@chainlink/=node_modules/@chainlink/\",\":@eth-optimism/=node_modules/@eth-optimism/\",\":@offchainlabs/=node_modules/@offchainlabs/\",\":@openzeppelin/=node_modules/@openzeppelin/\",\":@prb/=node_modules/@prb/\",\":@sablier/=node_modules/@sablier/\",\":@scroll-tech/=node_modules/@scroll-tech/\",\":@zksync/=node_modules/@zksync/\",\":forge-std/=node_modules/forge-std/\"],\"viaIR\":true},\"sources\":{\"src/interfaces/external/ICurveStETHPool.sol\":{\"keccak256\":\"0x1f6c5033babea583b6fe58ad4800e65f0797c424d171aa9a12ee584712768381\",\"license\":\"GPL-3.0-or-later\",\"urls\":[\"bzz-raw://d3e62ad83e724f0e63455290e7c1cbec02de7575f959c2ec74e0687c2e7c21c6\",\"dweb:/ipfs/QmV3XSQh5yyLskAFgA8zFa2BqZEftp2rSBrxWqqyT4JXur\"]}},\"version\":1}",
34
+ "metadata": {
35
+ "compiler": { "version": "0.8.29+commit.ab55807c" },
36
+ "language": "Solidity",
37
+ "output": {
38
+ "abi": [
39
+ {
40
+ "inputs": [
41
+ { "internalType": "int128", "name": "i", "type": "int128" },
42
+ { "internalType": "int128", "name": "j", "type": "int128" },
43
+ { "internalType": "uint256", "name": "dx", "type": "uint256" },
44
+ { "internalType": "uint256", "name": "minDy", "type": "uint256" }
45
+ ],
46
+ "stateMutability": "payable",
47
+ "type": "function",
48
+ "name": "exchange",
49
+ "outputs": [{ "internalType": "uint256", "name": "dy", "type": "uint256" }]
50
+ },
51
+ {
52
+ "inputs": [
53
+ { "internalType": "int128", "name": "i", "type": "int128" },
54
+ { "internalType": "int128", "name": "j", "type": "int128" },
55
+ { "internalType": "uint256", "name": "dx", "type": "uint256" }
56
+ ],
57
+ "stateMutability": "view",
58
+ "type": "function",
59
+ "name": "get_dy",
60
+ "outputs": [{ "internalType": "uint256", "name": "dy", "type": "uint256" }]
61
+ }
62
+ ],
63
+ "devdoc": {
64
+ "kind": "dev",
65
+ "methods": {
66
+ "exchange(int128,int128,uint256,uint256)": {
67
+ "params": {
68
+ "dx": "The amount of input coin to exchange.",
69
+ "i": "The index of the input coin (0 = ETH, 1 = stETH).",
70
+ "j": "The index of the output coin (0 = ETH, 1 = stETH).",
71
+ "minDy": "The minimum amount of output coin to receive."
72
+ },
73
+ "returns": { "dy": "The actual amount of output coin received." }
74
+ },
75
+ "get_dy(int128,int128,uint256)": {
76
+ "params": {
77
+ "dx": "The amount of input coin.",
78
+ "i": "The index of the input coin.",
79
+ "j": "The index of the output coin."
80
+ },
81
+ "returns": { "dy": "The expected amount of output coin." }
82
+ }
83
+ },
84
+ "version": 1
85
+ },
86
+ "userdoc": {
87
+ "kind": "user",
88
+ "methods": {
89
+ "exchange(int128,int128,uint256,uint256)": { "notice": "Exchange between two tokens in the pool." },
90
+ "get_dy(int128,int128,uint256)": { "notice": "Get the amount of output coin for a given input." }
91
+ },
92
+ "version": 1
93
+ }
94
+ },
95
+ "settings": {
96
+ "remappings": [
97
+ "@arbitrum/=node_modules/@arbitrum/",
98
+ "@chainlink/=node_modules/@chainlink/",
99
+ "@eth-optimism/=node_modules/@eth-optimism/",
100
+ "@offchainlabs/=node_modules/@offchainlabs/",
101
+ "@openzeppelin/=node_modules/@openzeppelin/",
102
+ "@prb/=node_modules/@prb/",
103
+ "@sablier/=node_modules/@sablier/",
104
+ "@scroll-tech/=node_modules/@scroll-tech/",
105
+ "@zksync/=node_modules/@zksync/",
106
+ "forge-std/=node_modules/forge-std/"
107
+ ],
108
+ "optimizer": { "enabled": true, "runs": 1000000 },
109
+ "metadata": { "bytecodeHash": "ipfs" },
110
+ "compilationTarget": { "src/interfaces/external/ICurveStETHPool.sol": "ICurveStETHPool" },
111
+ "evmVersion": "shanghai",
112
+ "libraries": {},
113
+ "viaIR": true
114
+ },
115
+ "sources": {
116
+ "src/interfaces/external/ICurveStETHPool.sol": {
117
+ "keccak256": "0x1f6c5033babea583b6fe58ad4800e65f0797c424d171aa9a12ee584712768381",
118
+ "urls": [
119
+ "bzz-raw://d3e62ad83e724f0e63455290e7c1cbec02de7575f959c2ec74e0687c2e7c21c6",
120
+ "dweb:/ipfs/QmV3XSQh5yyLskAFgA8zFa2BqZEftp2rSBrxWqqyT4JXur"
121
+ ],
122
+ "license": "GPL-3.0-or-later"
123
+ }
124
+ },
125
+ "version": 1
126
+ },
127
+ "id": 93
128
+ }
@@ -0,0 +1,209 @@
1
+ {
2
+ "abi": [
3
+ {
4
+ "type": "function",
5
+ "name": "MAX_STETH_WITHDRAWAL_AMOUNT",
6
+ "inputs": [],
7
+ "outputs": [{ "name": "", "type": "uint256", "internalType": "uint256" }],
8
+ "stateMutability": "view"
9
+ },
10
+ {
11
+ "type": "function",
12
+ "name": "MIN_STETH_WITHDRAWAL_AMOUNT",
13
+ "inputs": [],
14
+ "outputs": [{ "name": "", "type": "uint256", "internalType": "uint256" }],
15
+ "stateMutability": "view"
16
+ },
17
+ {
18
+ "type": "function",
19
+ "name": "claimWithdrawals",
20
+ "inputs": [
21
+ { "name": "_requestIds", "type": "uint256[]", "internalType": "uint256[]" },
22
+ { "name": "_hints", "type": "uint256[]", "internalType": "uint256[]" }
23
+ ],
24
+ "outputs": [],
25
+ "stateMutability": "nonpayable"
26
+ },
27
+ {
28
+ "type": "function",
29
+ "name": "findCheckpointHints",
30
+ "inputs": [
31
+ { "name": "_requestIds", "type": "uint256[]", "internalType": "uint256[]" },
32
+ { "name": "_firstIndex", "type": "uint256", "internalType": "uint256" },
33
+ { "name": "_lastIndex", "type": "uint256", "internalType": "uint256" }
34
+ ],
35
+ "outputs": [{ "name": "hintIds", "type": "uint256[]", "internalType": "uint256[]" }],
36
+ "stateMutability": "view"
37
+ },
38
+ {
39
+ "type": "function",
40
+ "name": "getLastCheckpointIndex",
41
+ "inputs": [],
42
+ "outputs": [{ "name": "", "type": "uint256", "internalType": "uint256" }],
43
+ "stateMutability": "view"
44
+ },
45
+ {
46
+ "type": "function",
47
+ "name": "requestWithdrawals",
48
+ "inputs": [
49
+ { "name": "_amounts", "type": "uint256[]", "internalType": "uint256[]" },
50
+ { "name": "_owner", "type": "address", "internalType": "address" }
51
+ ],
52
+ "outputs": [{ "name": "requestIds", "type": "uint256[]", "internalType": "uint256[]" }],
53
+ "stateMutability": "nonpayable"
54
+ }
55
+ ],
56
+ "bytecode": { "object": "0x", "sourceMap": "", "linkReferences": {} },
57
+ "deployedBytecode": { "object": "0x", "sourceMap": "", "linkReferences": {} },
58
+ "methodIdentifiers": {
59
+ "MAX_STETH_WITHDRAWAL_AMOUNT()": "db2296cd",
60
+ "MIN_STETH_WITHDRAWAL_AMOUNT()": "0d25a957",
61
+ "claimWithdrawals(uint256[],uint256[])": "e3afe0a3",
62
+ "findCheckpointHints(uint256[],uint256,uint256)": "62abe3fa",
63
+ "getLastCheckpointIndex()": "526eae3e",
64
+ "requestWithdrawals(uint256[],address)": "d6681042"
65
+ },
66
+ "rawMetadata": "{\"compiler\":{\"version\":\"0.8.29+commit.ab55807c\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"MAX_STETH_WITHDRAWAL_AMOUNT\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MIN_STETH_WITHDRAWAL_AMOUNT\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"_requestIds\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"_hints\",\"type\":\"uint256[]\"}],\"name\":\"claimWithdrawals\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"_requestIds\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256\",\"name\":\"_firstIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_lastIndex\",\"type\":\"uint256\"}],\"name\":\"findCheckpointHints\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"hintIds\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLastCheckpointIndex\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"_amounts\",\"type\":\"uint256[]\"},{\"internalType\":\"address\",\"name\":\"_owner\",\"type\":\"address\"}],\"name\":\"requestWithdrawals\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"requestIds\",\"type\":\"uint256[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"details\":\"Used as a fallback unstaking path when the Curve pool is unavailable.\",\"kind\":\"dev\",\"methods\":{\"claimWithdrawals(uint256[],uint256[])\":{\"details\":\"Reverts if any of the following conditions are met: - `requestIds` and `hints` arrays length differs. - Any `requestId` or `hint` in arguments are not valid. - Any request is not finalized or already claimed. - `msg.sender` is not an owner of the requests.\",\"params\":{\"_hints\":\"Checkpoint hint for each ID. Can be obtained with `findCheckpointHints()`\",\"_requestIds\":\"Array of request IDs to claim.\"}},\"findCheckpointHints(uint256[],uint256,uint256)\":{\"details\":\"- Array of request IDs should be sorted. - `_firstIndex` should be greater than 0, because checkpoint list is 1-based array. - `_lastIndex` should be less than or equal to `getLastCheckpointIndex()`.\",\"params\":{\"_firstIndex\":\"Left boundary of the search range. Should be greater than 0.\",\"_lastIndex\":\"Right boundary of the search range. Should be less than or equal to `getLastCheckpointIndex()`.\",\"_requestIds\":\"IDs of the requests sorted in the ascending order to get hints for.\"},\"returns\":{\"hintIds\":\"Array of hints used to find required checkpoint for the request.\"}},\"requestWithdrawals(uint256[],address)\":{\"params\":{\"_amounts\":\"Array of stETH amount values. The standalone withdrawal request will be created for each item in the passed list.\",\"_owner\":\"Address that will be able to manage the created requests. If `address(0)` is passed, `msg.sender` will be used as owner.\"},\"returns\":{\"requestIds\":\"Array of the created withdrawal request IDs.\"}}},\"title\":\"ILidoWithdrawalQueue\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"MAX_STETH_WITHDRAWAL_AMOUNT()\":{\"notice\":\"Maximum amount of stETH that can be withdrawn in a single request.\"},\"MIN_STETH_WITHDRAWAL_AMOUNT()\":{\"notice\":\"Minimum amount of stETH that can be withdrawn in a single request.\"},\"claimWithdrawals(uint256[],uint256[])\":{\"notice\":\"Claim a batch of withdrawal requests if they are finalized sending locked ETH to the owner.\"},\"findCheckpointHints(uint256[],uint256,uint256)\":{\"notice\":\"Finds the list of hints for the given `_requestIds` searching among the checkpoints with indices in the range `[_firstIndex, _lastIndex]`.\"},\"getLastCheckpointIndex()\":{\"notice\":\"Length of the checkpoint array. Last possible value for the hint.\"},\"requestWithdrawals(uint256[],address)\":{\"notice\":\"Request the batch of stETH for withdrawal. Approvals for the passed amounts should be done before.\"}},\"notice\":\"Minimal interface for Lido's WithdrawalQueueERC721 contract.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"src/interfaces/external/ILidoWithdrawalQueue.sol\":\"ILidoWithdrawalQueue\"},\"evmVersion\":\"shanghai\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":1000000},\"remappings\":[\":@arbitrum/=node_modules/@arbitrum/\",\":@chainlink/=node_modules/@chainlink/\",\":@eth-optimism/=node_modules/@eth-optimism/\",\":@offchainlabs/=node_modules/@offchainlabs/\",\":@openzeppelin/=node_modules/@openzeppelin/\",\":@prb/=node_modules/@prb/\",\":@sablier/=node_modules/@sablier/\",\":@scroll-tech/=node_modules/@scroll-tech/\",\":@zksync/=node_modules/@zksync/\",\":forge-std/=node_modules/forge-std/\"],\"viaIR\":true},\"sources\":{\"src/interfaces/external/ILidoWithdrawalQueue.sol\":{\"keccak256\":\"0x8b1fcfb51121595be6f4f7873f9a45ba48cc837e2dcb33c32af37db8aa653a15\",\"license\":\"GPL-3.0-or-later\",\"urls\":[\"bzz-raw://c7871ed24493c750fd5ac17c3d3d19a7f481bd88ebd33d72fee53ac72f2537bd\",\"dweb:/ipfs/QmQdkMTBYFug8TGEUYiBxD7Db8CgLmxYep736bPUA5opYa\"]}},\"version\":1}",
67
+ "metadata": {
68
+ "compiler": { "version": "0.8.29+commit.ab55807c" },
69
+ "language": "Solidity",
70
+ "output": {
71
+ "abi": [
72
+ {
73
+ "inputs": [],
74
+ "stateMutability": "view",
75
+ "type": "function",
76
+ "name": "MAX_STETH_WITHDRAWAL_AMOUNT",
77
+ "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }]
78
+ },
79
+ {
80
+ "inputs": [],
81
+ "stateMutability": "view",
82
+ "type": "function",
83
+ "name": "MIN_STETH_WITHDRAWAL_AMOUNT",
84
+ "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }]
85
+ },
86
+ {
87
+ "inputs": [
88
+ { "internalType": "uint256[]", "name": "_requestIds", "type": "uint256[]" },
89
+ { "internalType": "uint256[]", "name": "_hints", "type": "uint256[]" }
90
+ ],
91
+ "stateMutability": "nonpayable",
92
+ "type": "function",
93
+ "name": "claimWithdrawals"
94
+ },
95
+ {
96
+ "inputs": [
97
+ { "internalType": "uint256[]", "name": "_requestIds", "type": "uint256[]" },
98
+ { "internalType": "uint256", "name": "_firstIndex", "type": "uint256" },
99
+ { "internalType": "uint256", "name": "_lastIndex", "type": "uint256" }
100
+ ],
101
+ "stateMutability": "view",
102
+ "type": "function",
103
+ "name": "findCheckpointHints",
104
+ "outputs": [{ "internalType": "uint256[]", "name": "hintIds", "type": "uint256[]" }]
105
+ },
106
+ {
107
+ "inputs": [],
108
+ "stateMutability": "view",
109
+ "type": "function",
110
+ "name": "getLastCheckpointIndex",
111
+ "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }]
112
+ },
113
+ {
114
+ "inputs": [
115
+ { "internalType": "uint256[]", "name": "_amounts", "type": "uint256[]" },
116
+ { "internalType": "address", "name": "_owner", "type": "address" }
117
+ ],
118
+ "stateMutability": "nonpayable",
119
+ "type": "function",
120
+ "name": "requestWithdrawals",
121
+ "outputs": [{ "internalType": "uint256[]", "name": "requestIds", "type": "uint256[]" }]
122
+ }
123
+ ],
124
+ "devdoc": {
125
+ "kind": "dev",
126
+ "methods": {
127
+ "claimWithdrawals(uint256[],uint256[])": {
128
+ "details": "Reverts if any of the following conditions are met: - `requestIds` and `hints` arrays length differs. - Any `requestId` or `hint` in arguments are not valid. - Any request is not finalized or already claimed. - `msg.sender` is not an owner of the requests.",
129
+ "params": {
130
+ "_hints": "Checkpoint hint for each ID. Can be obtained with `findCheckpointHints()`",
131
+ "_requestIds": "Array of request IDs to claim."
132
+ }
133
+ },
134
+ "findCheckpointHints(uint256[],uint256,uint256)": {
135
+ "details": "- Array of request IDs should be sorted. - `_firstIndex` should be greater than 0, because checkpoint list is 1-based array. - `_lastIndex` should be less than or equal to `getLastCheckpointIndex()`.",
136
+ "params": {
137
+ "_firstIndex": "Left boundary of the search range. Should be greater than 0.",
138
+ "_lastIndex": "Right boundary of the search range. Should be less than or equal to `getLastCheckpointIndex()`.",
139
+ "_requestIds": "IDs of the requests sorted in the ascending order to get hints for."
140
+ },
141
+ "returns": { "hintIds": "Array of hints used to find required checkpoint for the request." }
142
+ },
143
+ "requestWithdrawals(uint256[],address)": {
144
+ "params": {
145
+ "_amounts": "Array of stETH amount values. The standalone withdrawal request will be created for each item in the passed list.",
146
+ "_owner": "Address that will be able to manage the created requests. If `address(0)` is passed, `msg.sender` will be used as owner."
147
+ },
148
+ "returns": { "requestIds": "Array of the created withdrawal request IDs." }
149
+ }
150
+ },
151
+ "version": 1
152
+ },
153
+ "userdoc": {
154
+ "kind": "user",
155
+ "methods": {
156
+ "MAX_STETH_WITHDRAWAL_AMOUNT()": {
157
+ "notice": "Maximum amount of stETH that can be withdrawn in a single request."
158
+ },
159
+ "MIN_STETH_WITHDRAWAL_AMOUNT()": {
160
+ "notice": "Minimum amount of stETH that can be withdrawn in a single request."
161
+ },
162
+ "claimWithdrawals(uint256[],uint256[])": {
163
+ "notice": "Claim a batch of withdrawal requests if they are finalized sending locked ETH to the owner."
164
+ },
165
+ "findCheckpointHints(uint256[],uint256,uint256)": {
166
+ "notice": "Finds the list of hints for the given `_requestIds` searching among the checkpoints with indices in the range `[_firstIndex, _lastIndex]`."
167
+ },
168
+ "getLastCheckpointIndex()": { "notice": "Length of the checkpoint array. Last possible value for the hint." },
169
+ "requestWithdrawals(uint256[],address)": {
170
+ "notice": "Request the batch of stETH for withdrawal. Approvals for the passed amounts should be done before."
171
+ }
172
+ },
173
+ "version": 1
174
+ }
175
+ },
176
+ "settings": {
177
+ "remappings": [
178
+ "@arbitrum/=node_modules/@arbitrum/",
179
+ "@chainlink/=node_modules/@chainlink/",
180
+ "@eth-optimism/=node_modules/@eth-optimism/",
181
+ "@offchainlabs/=node_modules/@offchainlabs/",
182
+ "@openzeppelin/=node_modules/@openzeppelin/",
183
+ "@prb/=node_modules/@prb/",
184
+ "@sablier/=node_modules/@sablier/",
185
+ "@scroll-tech/=node_modules/@scroll-tech/",
186
+ "@zksync/=node_modules/@zksync/",
187
+ "forge-std/=node_modules/forge-std/"
188
+ ],
189
+ "optimizer": { "enabled": true, "runs": 1000000 },
190
+ "metadata": { "bytecodeHash": "ipfs" },
191
+ "compilationTarget": { "src/interfaces/external/ILidoWithdrawalQueue.sol": "ILidoWithdrawalQueue" },
192
+ "evmVersion": "shanghai",
193
+ "libraries": {},
194
+ "viaIR": true
195
+ },
196
+ "sources": {
197
+ "src/interfaces/external/ILidoWithdrawalQueue.sol": {
198
+ "keccak256": "0x8b1fcfb51121595be6f4f7873f9a45ba48cc837e2dcb33c32af37db8aa653a15",
199
+ "urls": [
200
+ "bzz-raw://c7871ed24493c750fd5ac17c3d3d19a7f481bd88ebd33d72fee53ac72f2537bd",
201
+ "dweb:/ipfs/QmQdkMTBYFug8TGEUYiBxD7Db8CgLmxYep736bPUA5opYa"
202
+ ],
203
+ "license": "GPL-3.0-or-later"
204
+ }
205
+ },
206
+ "version": 1
207
+ },
208
+ "id": 94
209
+ }
@@ -0,0 +1,262 @@
1
+ {
2
+ "abi": [
3
+ {
4
+ "type": "function",
5
+ "name": "allowance",
6
+ "inputs": [
7
+ { "name": "owner", "type": "address", "internalType": "address" },
8
+ { "name": "spender", "type": "address", "internalType": "address" }
9
+ ],
10
+ "outputs": [{ "name": "", "type": "uint256", "internalType": "uint256" }],
11
+ "stateMutability": "view"
12
+ },
13
+ {
14
+ "type": "function",
15
+ "name": "approve",
16
+ "inputs": [
17
+ { "name": "spender", "type": "address", "internalType": "address" },
18
+ { "name": "value", "type": "uint256", "internalType": "uint256" }
19
+ ],
20
+ "outputs": [{ "name": "", "type": "bool", "internalType": "bool" }],
21
+ "stateMutability": "nonpayable"
22
+ },
23
+ {
24
+ "type": "function",
25
+ "name": "balanceOf",
26
+ "inputs": [{ "name": "account", "type": "address", "internalType": "address" }],
27
+ "outputs": [{ "name": "", "type": "uint256", "internalType": "uint256" }],
28
+ "stateMutability": "view"
29
+ },
30
+ {
31
+ "type": "function",
32
+ "name": "submit",
33
+ "inputs": [{ "name": "referral", "type": "address", "internalType": "address" }],
34
+ "outputs": [{ "name": "amount", "type": "uint256", "internalType": "uint256" }],
35
+ "stateMutability": "payable"
36
+ },
37
+ {
38
+ "type": "function",
39
+ "name": "totalSupply",
40
+ "inputs": [],
41
+ "outputs": [{ "name": "", "type": "uint256", "internalType": "uint256" }],
42
+ "stateMutability": "view"
43
+ },
44
+ {
45
+ "type": "function",
46
+ "name": "transfer",
47
+ "inputs": [
48
+ { "name": "to", "type": "address", "internalType": "address" },
49
+ { "name": "value", "type": "uint256", "internalType": "uint256" }
50
+ ],
51
+ "outputs": [{ "name": "", "type": "bool", "internalType": "bool" }],
52
+ "stateMutability": "nonpayable"
53
+ },
54
+ {
55
+ "type": "function",
56
+ "name": "transferFrom",
57
+ "inputs": [
58
+ { "name": "from", "type": "address", "internalType": "address" },
59
+ { "name": "to", "type": "address", "internalType": "address" },
60
+ { "name": "value", "type": "uint256", "internalType": "uint256" }
61
+ ],
62
+ "outputs": [{ "name": "", "type": "bool", "internalType": "bool" }],
63
+ "stateMutability": "nonpayable"
64
+ },
65
+ {
66
+ "type": "event",
67
+ "name": "Approval",
68
+ "inputs": [
69
+ { "name": "owner", "type": "address", "indexed": true, "internalType": "address" },
70
+ { "name": "spender", "type": "address", "indexed": true, "internalType": "address" },
71
+ { "name": "value", "type": "uint256", "indexed": false, "internalType": "uint256" }
72
+ ],
73
+ "anonymous": false
74
+ },
75
+ {
76
+ "type": "event",
77
+ "name": "Transfer",
78
+ "inputs": [
79
+ { "name": "from", "type": "address", "indexed": true, "internalType": "address" },
80
+ { "name": "to", "type": "address", "indexed": true, "internalType": "address" },
81
+ { "name": "value", "type": "uint256", "indexed": false, "internalType": "uint256" }
82
+ ],
83
+ "anonymous": false
84
+ }
85
+ ],
86
+ "bytecode": { "object": "0x", "sourceMap": "", "linkReferences": {} },
87
+ "deployedBytecode": { "object": "0x", "sourceMap": "", "linkReferences": {} },
88
+ "methodIdentifiers": {
89
+ "allowance(address,address)": "dd62ed3e",
90
+ "approve(address,uint256)": "095ea7b3",
91
+ "balanceOf(address)": "70a08231",
92
+ "submit(address)": "a1903eab",
93
+ "totalSupply()": "18160ddd",
94
+ "transfer(address,uint256)": "a9059cbb",
95
+ "transferFrom(address,address,uint256)": "23b872dd"
96
+ },
97
+ "rawMetadata": "{\"compiler\":{\"version\":\"0.8.29+commit.ab55807c\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"referral\",\"type\":\"address\"}],\"name\":\"submit\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"events\":{\"Approval(address,address,uint256)\":{\"details\":\"Emitted when the allowance of a `spender` for an `owner` is set by a call to {approve}. `value` is the new allowance.\"},\"Transfer(address,address,uint256)\":{\"details\":\"Emitted when `value` tokens are moved from one account (`from`) to another (`to`). Note that `value` may be zero.\"}},\"kind\":\"dev\",\"methods\":{\"allowance(address,address)\":{\"details\":\"Returns the remaining number of tokens that `spender` will be allowed to spend on behalf of `owner` through {transferFrom}. This is zero by default. This value changes when {approve} or {transferFrom} are called.\"},\"approve(address,uint256)\":{\"details\":\"Sets a `value` amount of tokens as the allowance of `spender` over the caller's tokens. Returns a boolean value indicating whether the operation succeeded. IMPORTANT: Beware that changing an allowance with this method brings the risk that someone may use both the old and the new allowance by unfortunate transaction ordering. One possible solution to mitigate this race condition is to first reduce the spender's allowance to 0 and set the desired value afterwards: https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 Emits an {Approval} event.\"},\"balanceOf(address)\":{\"details\":\"Returns the value of tokens owned by `account`.\"},\"submit(address)\":{\"details\":\"The amount of stETH minted equals the amount of ETH sent.\",\"params\":{\"referral\":\"The referral address can be zero.\"},\"returns\":{\"amount\":\"The amount of stETH minted.\"}},\"totalSupply()\":{\"details\":\"Returns the value of tokens in existence.\"},\"transfer(address,uint256)\":{\"details\":\"Moves a `value` amount of tokens from the caller's account to `to`. Returns a boolean value indicating whether the operation succeeded. Emits a {Transfer} event.\"},\"transferFrom(address,address,uint256)\":{\"details\":\"Moves a `value` amount of tokens from `from` to `to` using the allowance mechanism. `value` is then deducted from the caller's allowance. Returns a boolean value indicating whether the operation succeeded. Emits a {Transfer} event.\"}},\"title\":\"IStETH\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"submit(address)\":{\"notice\":\"Send funds to the Lido pool with the optional referral parameter and mints stETH.\"}},\"notice\":\"Minimal interface for Lido's stETH.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"src/interfaces/external/IStETH.sol\":\"IStETH\"},\"evmVersion\":\"shanghai\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":1000000},\"remappings\":[\":@arbitrum/=node_modules/@arbitrum/\",\":@chainlink/=node_modules/@chainlink/\",\":@eth-optimism/=node_modules/@eth-optimism/\",\":@offchainlabs/=node_modules/@offchainlabs/\",\":@openzeppelin/=node_modules/@openzeppelin/\",\":@prb/=node_modules/@prb/\",\":@sablier/=node_modules/@sablier/\",\":@scroll-tech/=node_modules/@scroll-tech/\",\":@zksync/=node_modules/@zksync/\",\":forge-std/=node_modules/forge-std/\"],\"viaIR\":true},\"sources\":{\"node_modules/@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"keccak256\":\"0xe06a3f08a987af6ad2e1c1e774405d4fe08f1694b67517438b467cecf0da0ef7\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://df6f0c459663c9858b6cba2cda1d14a7d05a985bed6d2de72bd8e78c25ee79db\",\"dweb:/ipfs/QmeTTxZ7qVk9rjEv2R4CpCwdf8UMCcRqDNMvzNxHc3Fnn9\"]},\"src/interfaces/external/IStETH.sol\":{\"keccak256\":\"0x1532c07f36f20a076ed1415340ff8e3752520652b332bf3fb9b800c067409e68\",\"license\":\"GPL-3.0-or-later\",\"urls\":[\"bzz-raw://fe10fd2828e327d78a6ac076729090abd3d5d6ee50932e931168b73526c6e7c4\",\"dweb:/ipfs/QmVgpKCCRd7GN5aUi7JEaWGf1gFSoiMJbW2D9qzMFNxsYn\"]}},\"version\":1}",
98
+ "metadata": {
99
+ "compiler": { "version": "0.8.29+commit.ab55807c" },
100
+ "language": "Solidity",
101
+ "output": {
102
+ "abi": [
103
+ {
104
+ "inputs": [
105
+ { "internalType": "address", "name": "owner", "type": "address", "indexed": true },
106
+ { "internalType": "address", "name": "spender", "type": "address", "indexed": true },
107
+ { "internalType": "uint256", "name": "value", "type": "uint256", "indexed": false }
108
+ ],
109
+ "type": "event",
110
+ "name": "Approval",
111
+ "anonymous": false
112
+ },
113
+ {
114
+ "inputs": [
115
+ { "internalType": "address", "name": "from", "type": "address", "indexed": true },
116
+ { "internalType": "address", "name": "to", "type": "address", "indexed": true },
117
+ { "internalType": "uint256", "name": "value", "type": "uint256", "indexed": false }
118
+ ],
119
+ "type": "event",
120
+ "name": "Transfer",
121
+ "anonymous": false
122
+ },
123
+ {
124
+ "inputs": [
125
+ { "internalType": "address", "name": "owner", "type": "address" },
126
+ { "internalType": "address", "name": "spender", "type": "address" }
127
+ ],
128
+ "stateMutability": "view",
129
+ "type": "function",
130
+ "name": "allowance",
131
+ "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }]
132
+ },
133
+ {
134
+ "inputs": [
135
+ { "internalType": "address", "name": "spender", "type": "address" },
136
+ { "internalType": "uint256", "name": "value", "type": "uint256" }
137
+ ],
138
+ "stateMutability": "nonpayable",
139
+ "type": "function",
140
+ "name": "approve",
141
+ "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }]
142
+ },
143
+ {
144
+ "inputs": [{ "internalType": "address", "name": "account", "type": "address" }],
145
+ "stateMutability": "view",
146
+ "type": "function",
147
+ "name": "balanceOf",
148
+ "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }]
149
+ },
150
+ {
151
+ "inputs": [{ "internalType": "address", "name": "referral", "type": "address" }],
152
+ "stateMutability": "payable",
153
+ "type": "function",
154
+ "name": "submit",
155
+ "outputs": [{ "internalType": "uint256", "name": "amount", "type": "uint256" }]
156
+ },
157
+ {
158
+ "inputs": [],
159
+ "stateMutability": "view",
160
+ "type": "function",
161
+ "name": "totalSupply",
162
+ "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }]
163
+ },
164
+ {
165
+ "inputs": [
166
+ { "internalType": "address", "name": "to", "type": "address" },
167
+ { "internalType": "uint256", "name": "value", "type": "uint256" }
168
+ ],
169
+ "stateMutability": "nonpayable",
170
+ "type": "function",
171
+ "name": "transfer",
172
+ "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }]
173
+ },
174
+ {
175
+ "inputs": [
176
+ { "internalType": "address", "name": "from", "type": "address" },
177
+ { "internalType": "address", "name": "to", "type": "address" },
178
+ { "internalType": "uint256", "name": "value", "type": "uint256" }
179
+ ],
180
+ "stateMutability": "nonpayable",
181
+ "type": "function",
182
+ "name": "transferFrom",
183
+ "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }]
184
+ }
185
+ ],
186
+ "devdoc": {
187
+ "kind": "dev",
188
+ "methods": {
189
+ "allowance(address,address)": {
190
+ "details": "Returns the remaining number of tokens that `spender` will be allowed to spend on behalf of `owner` through {transferFrom}. This is zero by default. This value changes when {approve} or {transferFrom} are called."
191
+ },
192
+ "approve(address,uint256)": {
193
+ "details": "Sets a `value` amount of tokens as the allowance of `spender` over the caller's tokens. Returns a boolean value indicating whether the operation succeeded. IMPORTANT: Beware that changing an allowance with this method brings the risk that someone may use both the old and the new allowance by unfortunate transaction ordering. One possible solution to mitigate this race condition is to first reduce the spender's allowance to 0 and set the desired value afterwards: https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 Emits an {Approval} event."
194
+ },
195
+ "balanceOf(address)": { "details": "Returns the value of tokens owned by `account`." },
196
+ "submit(address)": {
197
+ "details": "The amount of stETH minted equals the amount of ETH sent.",
198
+ "params": { "referral": "The referral address can be zero." },
199
+ "returns": { "amount": "The amount of stETH minted." }
200
+ },
201
+ "totalSupply()": { "details": "Returns the value of tokens in existence." },
202
+ "transfer(address,uint256)": {
203
+ "details": "Moves a `value` amount of tokens from the caller's account to `to`. Returns a boolean value indicating whether the operation succeeded. Emits a {Transfer} event."
204
+ },
205
+ "transferFrom(address,address,uint256)": {
206
+ "details": "Moves a `value` amount of tokens from `from` to `to` using the allowance mechanism. `value` is then deducted from the caller's allowance. Returns a boolean value indicating whether the operation succeeded. Emits a {Transfer} event."
207
+ }
208
+ },
209
+ "version": 1
210
+ },
211
+ "userdoc": {
212
+ "kind": "user",
213
+ "methods": {
214
+ "submit(address)": {
215
+ "notice": "Send funds to the Lido pool with the optional referral parameter and mints stETH."
216
+ }
217
+ },
218
+ "version": 1
219
+ }
220
+ },
221
+ "settings": {
222
+ "remappings": [
223
+ "@arbitrum/=node_modules/@arbitrum/",
224
+ "@chainlink/=node_modules/@chainlink/",
225
+ "@eth-optimism/=node_modules/@eth-optimism/",
226
+ "@offchainlabs/=node_modules/@offchainlabs/",
227
+ "@openzeppelin/=node_modules/@openzeppelin/",
228
+ "@prb/=node_modules/@prb/",
229
+ "@sablier/=node_modules/@sablier/",
230
+ "@scroll-tech/=node_modules/@scroll-tech/",
231
+ "@zksync/=node_modules/@zksync/",
232
+ "forge-std/=node_modules/forge-std/"
233
+ ],
234
+ "optimizer": { "enabled": true, "runs": 1000000 },
235
+ "metadata": { "bytecodeHash": "ipfs" },
236
+ "compilationTarget": { "src/interfaces/external/IStETH.sol": "IStETH" },
237
+ "evmVersion": "shanghai",
238
+ "libraries": {},
239
+ "viaIR": true
240
+ },
241
+ "sources": {
242
+ "node_modules/@openzeppelin/contracts/token/ERC20/IERC20.sol": {
243
+ "keccak256": "0xe06a3f08a987af6ad2e1c1e774405d4fe08f1694b67517438b467cecf0da0ef7",
244
+ "urls": [
245
+ "bzz-raw://df6f0c459663c9858b6cba2cda1d14a7d05a985bed6d2de72bd8e78c25ee79db",
246
+ "dweb:/ipfs/QmeTTxZ7qVk9rjEv2R4CpCwdf8UMCcRqDNMvzNxHc3Fnn9"
247
+ ],
248
+ "license": "MIT"
249
+ },
250
+ "src/interfaces/external/IStETH.sol": {
251
+ "keccak256": "0x1532c07f36f20a076ed1415340ff8e3752520652b332bf3fb9b800c067409e68",
252
+ "urls": [
253
+ "bzz-raw://fe10fd2828e327d78a6ac076729090abd3d5d6ee50932e931168b73526c6e7c4",
254
+ "dweb:/ipfs/QmVgpKCCRd7GN5aUi7JEaWGf1gFSoiMJbW2D9qzMFNxsYn"
255
+ ],
256
+ "license": "GPL-3.0-or-later"
257
+ }
258
+ },
259
+ "version": 1
260
+ },
261
+ "id": 95
262
+ }