@godzillaba/mutest 1.0.0
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/.devcontainer/Dockerfile +117 -0
- package/.devcontainer/devcontainer.json +62 -0
- package/.devcontainer/init-firewall.sh +118 -0
- package/.github/workflows/test.yml +38 -0
- package/.gitmodules +3 -0
- package/CLAUDE.md +39 -0
- package/README.md +33 -0
- package/foundry.lock +8 -0
- package/foundry.toml +6 -0
- package/index.ts +97 -0
- package/lib/forge-std/.gitattributes +1 -0
- package/lib/forge-std/.github/CODEOWNERS +1 -0
- package/lib/forge-std/.github/dependabot.yml +6 -0
- package/lib/forge-std/.github/workflows/ci.yml +125 -0
- package/lib/forge-std/.github/workflows/sync.yml +36 -0
- package/lib/forge-std/CONTRIBUTING.md +193 -0
- package/lib/forge-std/LICENSE-APACHE +203 -0
- package/lib/forge-std/LICENSE-MIT +25 -0
- package/lib/forge-std/README.md +314 -0
- package/lib/forge-std/RELEASE_CHECKLIST.md +12 -0
- package/lib/forge-std/foundry.toml +18 -0
- package/lib/forge-std/package.json +16 -0
- package/lib/forge-std/scripts/vm.py +636 -0
- package/lib/forge-std/src/Base.sol +48 -0
- package/lib/forge-std/src/Config.sol +60 -0
- package/lib/forge-std/src/LibVariable.sol +477 -0
- package/lib/forge-std/src/Script.sol +28 -0
- package/lib/forge-std/src/StdAssertions.sol +779 -0
- package/lib/forge-std/src/StdChains.sol +303 -0
- package/lib/forge-std/src/StdCheats.sol +825 -0
- package/lib/forge-std/src/StdConfig.sol +632 -0
- package/lib/forge-std/src/StdConstants.sol +30 -0
- package/lib/forge-std/src/StdError.sol +15 -0
- package/lib/forge-std/src/StdInvariant.sol +140 -0
- package/lib/forge-std/src/StdJson.sol +275 -0
- package/lib/forge-std/src/StdMath.sol +47 -0
- package/lib/forge-std/src/StdStorage.sol +475 -0
- package/lib/forge-std/src/StdStyle.sol +333 -0
- package/lib/forge-std/src/StdToml.sol +275 -0
- package/lib/forge-std/src/StdUtils.sol +200 -0
- package/lib/forge-std/src/Test.sol +32 -0
- package/lib/forge-std/src/Vm.sol +2533 -0
- package/lib/forge-std/src/console.sol +1551 -0
- package/lib/forge-std/src/console2.sol +4 -0
- package/lib/forge-std/src/interfaces/IERC1155.sol +105 -0
- package/lib/forge-std/src/interfaces/IERC165.sol +12 -0
- package/lib/forge-std/src/interfaces/IERC20.sol +43 -0
- package/lib/forge-std/src/interfaces/IERC4626.sol +190 -0
- package/lib/forge-std/src/interfaces/IERC6909.sol +72 -0
- package/lib/forge-std/src/interfaces/IERC721.sol +164 -0
- package/lib/forge-std/src/interfaces/IERC7540.sol +144 -0
- package/lib/forge-std/src/interfaces/IERC7575.sol +241 -0
- package/lib/forge-std/src/interfaces/IMulticall3.sol +68 -0
- package/lib/forge-std/src/safeconsole.sol +13248 -0
- package/lib/forge-std/test/CommonBase.t.sol +44 -0
- package/lib/forge-std/test/Config.t.sol +381 -0
- package/lib/forge-std/test/LibVariable.t.sol +452 -0
- package/lib/forge-std/test/StdAssertions.t.sol +141 -0
- package/lib/forge-std/test/StdChains.t.sol +227 -0
- package/lib/forge-std/test/StdCheats.t.sol +638 -0
- package/lib/forge-std/test/StdConstants.t.sol +38 -0
- package/lib/forge-std/test/StdError.t.sol +119 -0
- package/lib/forge-std/test/StdJson.t.sol +49 -0
- package/lib/forge-std/test/StdMath.t.sol +202 -0
- package/lib/forge-std/test/StdStorage.t.sol +485 -0
- package/lib/forge-std/test/StdStyle.t.sol +110 -0
- package/lib/forge-std/test/StdToml.t.sol +49 -0
- package/lib/forge-std/test/StdUtils.t.sol +342 -0
- package/lib/forge-std/test/Vm.t.sol +18 -0
- package/lib/forge-std/test/compilation/CompilationScript.sol +8 -0
- package/lib/forge-std/test/compilation/CompilationScriptBase.sol +8 -0
- package/lib/forge-std/test/compilation/CompilationTest.sol +8 -0
- package/lib/forge-std/test/compilation/CompilationTestBase.sol +8 -0
- package/lib/forge-std/test/fixtures/broadcast.log.json +187 -0
- package/lib/forge-std/test/fixtures/config.toml +81 -0
- package/lib/forge-std/test/fixtures/test.json +8 -0
- package/lib/forge-std/test/fixtures/test.toml +6 -0
- package/package.json +10 -0
- package/script/Counter.s.sol +19 -0
- package/src/Counter.sol +14 -0
- package/test/Counter.t.sol +24 -0
|
@@ -0,0 +1,314 @@
|
|
|
1
|
+
# Forge Standard Library • [](https://github.com/foundry-rs/forge-std/actions/workflows/ci.yml)
|
|
2
|
+
|
|
3
|
+
Forge Standard Library is a collection of helpful contracts and libraries for use with [Forge and Foundry](https://github.com/foundry-rs/foundry). It leverages Forge's cheatcodes to make writing tests easier and faster, while improving the UX of cheatcodes.
|
|
4
|
+
|
|
5
|
+
**Learn how to use Forge-Std with the [📖 Foundry Book (Forge-Std Guide)](https://getfoundry.sh/reference/forge-std/overview/).**
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
forge install foundry-rs/forge-std
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Contracts
|
|
14
|
+
|
|
15
|
+
### stdError
|
|
16
|
+
|
|
17
|
+
This is a helper contract for errors and reverts. In Forge, this contract is particularly helpful for the `expectRevert` cheatcode, as it provides all compiler built-in errors.
|
|
18
|
+
|
|
19
|
+
See the contract itself for all error codes.
|
|
20
|
+
|
|
21
|
+
#### Example usage
|
|
22
|
+
|
|
23
|
+
```solidity
|
|
24
|
+
|
|
25
|
+
import "forge-std/Test.sol";
|
|
26
|
+
|
|
27
|
+
contract TestContract is Test {
|
|
28
|
+
ErrorsTest test;
|
|
29
|
+
|
|
30
|
+
function setUp() public {
|
|
31
|
+
test = new ErrorsTest();
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function testExpectArithmetic() public {
|
|
35
|
+
vm.expectRevert(stdError.arithmeticError);
|
|
36
|
+
test.arithmeticError(10);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
contract ErrorsTest {
|
|
41
|
+
function arithmeticError(uint256 a) public {
|
|
42
|
+
a = a - 100;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### stdStorage
|
|
48
|
+
|
|
49
|
+
This is a rather large contract due to all of the overloading to make the UX decent. Primarily, it is a wrapper around the `record` and `accesses` cheatcodes. It can _always_ find and write the storage slot(s) associated with a particular variable without knowing the storage layout. By default, writing to packed storage variables is not supported and will throw an error. However, you can enable packed slot support by calling `enable_packed_slots()` before using `find()` or `checked_write()`.
|
|
50
|
+
|
|
51
|
+
This works by recording all `SLOAD`s and `SSTORE`s during a function call. If there is a single slot read or written to, it immediately returns the slot. Otherwise, behind the scenes, we iterate through and check each one (assuming the user passed in a `depth` parameter). If the variable is a struct, you can pass in a `depth` parameter which is basically the field depth.
|
|
52
|
+
|
|
53
|
+
I.e.:
|
|
54
|
+
|
|
55
|
+
```solidity
|
|
56
|
+
struct T {
|
|
57
|
+
// depth 0
|
|
58
|
+
uint256 a;
|
|
59
|
+
// depth 1
|
|
60
|
+
uint256 b;
|
|
61
|
+
}
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
#### Example usage
|
|
65
|
+
|
|
66
|
+
```solidity
|
|
67
|
+
import "forge-std/Test.sol";
|
|
68
|
+
|
|
69
|
+
contract TestContract is Test {
|
|
70
|
+
using stdStorage for StdStorage;
|
|
71
|
+
|
|
72
|
+
Storage test;
|
|
73
|
+
|
|
74
|
+
function setUp() public {
|
|
75
|
+
test = new Storage();
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function testFindExists() public {
|
|
79
|
+
// Let's say we want to find the slot for the public
|
|
80
|
+
// variable `exists`. We just pass in the function selector
|
|
81
|
+
// to the `find` command
|
|
82
|
+
uint256 slot = stdstore.target(address(test)).sig("exists()").find();
|
|
83
|
+
assertEq(slot, 0);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function testWriteExists() public {
|
|
87
|
+
// Let's say we want to write to the slot for the public
|
|
88
|
+
// variable `exists`. We just pass in the function selector
|
|
89
|
+
// to the `checked_write` command
|
|
90
|
+
stdstore.target(address(test)).sig("exists()").checked_write(100);
|
|
91
|
+
assertEq(test.exists(), 100);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// It supports arbitrary storage layouts, like assembly-based storage locations
|
|
95
|
+
function testFindHidden() public {
|
|
96
|
+
// `hidden` is a random hash of bytes; iterating through slots would
|
|
97
|
+
// not find it. Our mechanism does
|
|
98
|
+
// Also, you can use the selector instead of a string
|
|
99
|
+
uint256 slot = stdstore.target(address(test)).sig(test.hidden.selector).find();
|
|
100
|
+
assertEq(slot, uint256(keccak256("my.random.var")));
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// If targeting a mapping, you have to pass in the keys necessary to perform the find
|
|
104
|
+
// i.e.:
|
|
105
|
+
function testFindMapping() public {
|
|
106
|
+
uint256 slot = stdstore
|
|
107
|
+
.target(address(test))
|
|
108
|
+
.sig(test.map_addr.selector)
|
|
109
|
+
.with_key(address(this))
|
|
110
|
+
.find();
|
|
111
|
+
// in the `Storage` constructor, we wrote that this address' value was 1 in the map
|
|
112
|
+
// so when we load the slot, we expect it to be 1
|
|
113
|
+
assertEq(uint(vm.load(address(test), bytes32(slot))), 1);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// If the target is a struct, you can specify the field depth:
|
|
117
|
+
function testFindStruct() public {
|
|
118
|
+
// NOTE: see the depth parameter - 0 means 0th field, 1 means 1st field, etc.
|
|
119
|
+
uint256 slot_for_a_field = stdstore
|
|
120
|
+
.target(address(test))
|
|
121
|
+
.sig(test.basicStruct.selector)
|
|
122
|
+
.depth(0)
|
|
123
|
+
.find();
|
|
124
|
+
|
|
125
|
+
uint256 slot_for_b_field = stdstore
|
|
126
|
+
.target(address(test))
|
|
127
|
+
.sig(test.basicStruct.selector)
|
|
128
|
+
.depth(1)
|
|
129
|
+
.find();
|
|
130
|
+
|
|
131
|
+
assertEq(uint(vm.load(address(test), bytes32(slot_for_a_field))), 1);
|
|
132
|
+
assertEq(uint(vm.load(address(test), bytes32(slot_for_b_field))), 2);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// A complex storage contract
|
|
137
|
+
contract Storage {
|
|
138
|
+
struct UnpackedStruct {
|
|
139
|
+
uint256 a;
|
|
140
|
+
uint256 b;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
constructor() {
|
|
144
|
+
map_addr[msg.sender] = 1;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
uint256 public exists = 1;
|
|
148
|
+
mapping(address => uint256) public map_addr;
|
|
149
|
+
// mapping(address => Packed) public map_packed;
|
|
150
|
+
mapping(address => UnpackedStruct) public map_struct;
|
|
151
|
+
mapping(address => mapping(address => uint256)) public deep_map;
|
|
152
|
+
mapping(address => mapping(address => UnpackedStruct)) public deep_map_struct;
|
|
153
|
+
UnpackedStruct public basicStruct = UnpackedStruct({
|
|
154
|
+
a: 1,
|
|
155
|
+
b: 2
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
function hidden() public view returns (bytes32 t) {
|
|
159
|
+
// an extremely hidden storage slot
|
|
160
|
+
bytes32 slot = keccak256("my.random.var");
|
|
161
|
+
assembly {
|
|
162
|
+
t := sload(slot)
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
### stdCheats
|
|
169
|
+
|
|
170
|
+
This is a wrapper around miscellaneous cheatcodes that need wrappers to be more dev-friendly. It includes functions for pranking, dealing with ETH and tokens, deploying contracts, creating test addresses, time manipulation, and fuzzing helpers. In general, users may expect ETH to be put into an address with `prank`, but this is not the case for safety reasons. Explicitly, this `hoax` function should only be used for addresses that have expected balances as it will get overwritten. If an address already has ETH, you should just use `prank`. If you want to change that balance explicitly, just use `deal`. If you want to do both, `hoax` is also right for you.
|
|
171
|
+
|
|
172
|
+
#### Example usage:
|
|
173
|
+
|
|
174
|
+
```solidity
|
|
175
|
+
|
|
176
|
+
// SPDX-License-Identifier: MIT OR Apache-2.0
|
|
177
|
+
pragma solidity ^0.8.0;
|
|
178
|
+
|
|
179
|
+
import "forge-std/Test.sol";
|
|
180
|
+
|
|
181
|
+
// Inherit the stdCheats
|
|
182
|
+
contract StdCheatsTest is Test {
|
|
183
|
+
Bar test;
|
|
184
|
+
function setUp() public {
|
|
185
|
+
test = new Bar();
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
function testHoax() public {
|
|
189
|
+
// we call `hoax`, which gives the target address
|
|
190
|
+
// eth and then calls `prank`
|
|
191
|
+
hoax(address(1337));
|
|
192
|
+
test.bar{value: 100}(address(1337));
|
|
193
|
+
|
|
194
|
+
// overloaded to allow you to specify how much eth to
|
|
195
|
+
// initialize the address with
|
|
196
|
+
hoax(address(1337), 1);
|
|
197
|
+
test.bar{value: 1}(address(1337));
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
function testStartHoax() public {
|
|
201
|
+
// we call `startHoax`, which gives the target address
|
|
202
|
+
// eth and then calls `startPrank`
|
|
203
|
+
//
|
|
204
|
+
// it is also overloaded so that you can specify an eth amount
|
|
205
|
+
startHoax(address(1337));
|
|
206
|
+
test.bar{value: 100}(address(1337));
|
|
207
|
+
test.bar{value: 100}(address(1337));
|
|
208
|
+
vm.stopPrank();
|
|
209
|
+
test.bar(address(this));
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
contract Bar {
|
|
214
|
+
function bar(address expectedSender) public payable {
|
|
215
|
+
require(msg.sender == expectedSender, "!prank");
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
### Std Assertions
|
|
221
|
+
|
|
222
|
+
Provides comprehensive assertion functions for testing, including equality checks (assertEq, assertNotEq), comparisons (assertLt, assertGt, assertLe, assertGe), approximate equality (assertApproxEqAbs, assertApproxEqRel), and boolean assertions (assertTrue, assertFalse). All assertions support multiple data types and optional custom error messages.
|
|
223
|
+
|
|
224
|
+
### StdConfig
|
|
225
|
+
|
|
226
|
+
This is a contract that parses a TOML configuration file and loads its variables into storage, automatically casting them on deployment. It assumes a TOML structure where top-level keys represent chain IDs or aliases. Under each chain key, variables are organized by type in separate sub-tables like `[<chain>.<type>]`, where type must be: `bool`, `address`, `bytes32`, `uint`, `int`, `string`, or `bytes`.
|
|
227
|
+
|
|
228
|
+
#### Example usage
|
|
229
|
+
|
|
230
|
+
```solidity
|
|
231
|
+
|
|
232
|
+
// SPDX-License-Identifier: MIT OR Apache-2.0
|
|
233
|
+
pragma solidity ^0.8.13;
|
|
234
|
+
|
|
235
|
+
import "forge-std/Script.sol";
|
|
236
|
+
import "forge-std/StdConfig.sol";
|
|
237
|
+
|
|
238
|
+
contract MyScript is Script {
|
|
239
|
+
StdConfig config;
|
|
240
|
+
|
|
241
|
+
function run() public {
|
|
242
|
+
// Load config (set writeToFile=true only in scripts to persist changes)
|
|
243
|
+
config = new StdConfig("config.toml", false);
|
|
244
|
+
|
|
245
|
+
// Get values for the current chain
|
|
246
|
+
uint256 myNumber = config.get("important_number").toUint256();
|
|
247
|
+
address weth = config.get("weth").toAddress();
|
|
248
|
+
address[] memory admins = config.get("whitelisted_admins").toAddressArray();
|
|
249
|
+
|
|
250
|
+
// Get values for a specific chain
|
|
251
|
+
bool isLive = config.get(1, "is_live").toBool();
|
|
252
|
+
|
|
253
|
+
// Check if a key exists
|
|
254
|
+
if (config.exists("optional_param")) {
|
|
255
|
+
// ...
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
// Get RPC URL for current or specific chain
|
|
259
|
+
string memory rpc = config.getRpcUrl();
|
|
260
|
+
string memory mainnetRpc = config.getRpcUrl(1);
|
|
261
|
+
|
|
262
|
+
// Get all configured chain IDs
|
|
263
|
+
uint256[] memory chainIds = config.getChainIds();
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
See the contract itself for supported TOML format and all available methods.
|
|
269
|
+
|
|
270
|
+
### `console.log`
|
|
271
|
+
|
|
272
|
+
Usage follows the same format as [Hardhat](https://hardhat.org/hardhat-network/reference/#console-log).
|
|
273
|
+
It's recommended to use `console2.sol` as shown below, as this will show the decoded logs in Forge traces.
|
|
274
|
+
|
|
275
|
+
```solidity
|
|
276
|
+
// import it indirectly via Test.sol
|
|
277
|
+
import "forge-std/Test.sol";
|
|
278
|
+
// or directly import it
|
|
279
|
+
import "forge-std/console2.sol";
|
|
280
|
+
...
|
|
281
|
+
console2.log(someValue);
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
If you need compatibility with Hardhat, you must use the standard `console.sol` instead.
|
|
285
|
+
Due to a bug in `console.sol`, logs that use `uint256` or `int256` types will not be properly decoded in Forge traces.
|
|
286
|
+
|
|
287
|
+
```solidity
|
|
288
|
+
// import it indirectly via Test.sol
|
|
289
|
+
import "forge-std/Test.sol";
|
|
290
|
+
// or directly import it
|
|
291
|
+
import "forge-std/console.sol";
|
|
292
|
+
...
|
|
293
|
+
console.log(someValue);
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
## Contributing
|
|
297
|
+
|
|
298
|
+
See our [contributing guidelines](./CONTRIBUTING.md).
|
|
299
|
+
|
|
300
|
+
## Getting Help
|
|
301
|
+
|
|
302
|
+
First, see if the answer to your question can be found in [book](https://getfoundry.sh/).
|
|
303
|
+
|
|
304
|
+
If the answer is not there:
|
|
305
|
+
|
|
306
|
+
- Join the [support Telegram](https://t.me/foundry_support) to get help, or
|
|
307
|
+
- Open a [discussion](https://github.com/foundry-rs/foundry/discussions/new/choose) with your question, or
|
|
308
|
+
- Open an issue with [the bug](https://github.com/foundry-rs/foundry/issues/new/choose)
|
|
309
|
+
|
|
310
|
+
If you want to contribute, or follow along with contributor discussion, you can use our [main telegram](https://t.me/foundry_rs) to chat with us about the development of Foundry!
|
|
311
|
+
|
|
312
|
+
## License
|
|
313
|
+
|
|
314
|
+
Forge Standard Library is offered under either [MIT](LICENSE-MIT) or [Apache 2.0](LICENSE-APACHE) license.
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# Release checklist
|
|
2
|
+
|
|
3
|
+
This checklist is meant to be used as a guide for the `forge-std` release process.
|
|
4
|
+
|
|
5
|
+
## Steps
|
|
6
|
+
|
|
7
|
+
- [ ] Update the version number in `package.json`
|
|
8
|
+
- [ ] Open and merge a PR with the version bump
|
|
9
|
+
- [ ] Tag the merged commit with the version number: `git tag v<X.Y.Z>`
|
|
10
|
+
- [ ] Push the tag to the repository: `git push --tags`
|
|
11
|
+
- [ ] Create a new GitHub release with the automatically generated changelog and the name set to `v<X.Y.Z>`
|
|
12
|
+
- [ ] Add `## Featured Changes` section to the top of the release notes
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
[profile.default]
|
|
2
|
+
fs_permissions = [{ access = "read-write", path = "./" }]
|
|
3
|
+
optimizer = true
|
|
4
|
+
optimizer_runs = 200
|
|
5
|
+
|
|
6
|
+
# A list of solidity error codes to ignore.
|
|
7
|
+
# 3860 = init-code-size
|
|
8
|
+
ignored_error_codes = [3860]
|
|
9
|
+
|
|
10
|
+
[rpc_endpoints]
|
|
11
|
+
# The RPC URLs are modified versions of the default for testing initialization.
|
|
12
|
+
mainnet = "https://ethereum.reth.rs/rpc"
|
|
13
|
+
optimism_sepolia = "https://sepolia.optimism.io/" # Adds a trailing slash.
|
|
14
|
+
arbitrum_one_sepolia = "https://sepolia-rollup.arbitrum.io/rpc/" # Adds a trailing slash.
|
|
15
|
+
needs_undefined_env_var = "${UNDEFINED_RPC_URL_PLACEHOLDER}"
|
|
16
|
+
|
|
17
|
+
[lint]
|
|
18
|
+
lint_on_build = false
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "forge-std",
|
|
3
|
+
"version": "1.15.0",
|
|
4
|
+
"description": "Forge Standard Library is a collection of helpful contracts and libraries for use with Forge and Foundry.",
|
|
5
|
+
"homepage": "https://book.getfoundry.sh/forge/forge-std",
|
|
6
|
+
"bugs": "https://github.com/foundry-rs/forge-std/issues",
|
|
7
|
+
"license": "(Apache-2.0 OR MIT)",
|
|
8
|
+
"author": "Contributors to Forge Standard Library",
|
|
9
|
+
"files": [
|
|
10
|
+
"src/**/*"
|
|
11
|
+
],
|
|
12
|
+
"repository": {
|
|
13
|
+
"type": "git",
|
|
14
|
+
"url": "https://github.com/foundry-rs/forge-std.git"
|
|
15
|
+
}
|
|
16
|
+
}
|