@@ -46,27 +46,29 @@ For Foundry projects, add this line to your `remappings.txt`:
4646import "forge-std/Test.sol";
4747import "@pythnetwork/entropy-sdk-solidity/MockEntropy.sol";
4848import "@pythnetwork/entropy-sdk-solidity/IEntropyConsumer.sol";
49+
4950```
5051
5152### 2. Set Up MockEntropy in Your Test
5253
5354``` solidity copy
5455contract MyEntropyTest is Test {
55- MockEntropy public entropy;
56- MyEntropyConsumer public consumer;
57- address public provider;
58-
59- function setUp() public {
60- // Use any address as the provider
61- provider = address(0x1234);
62-
63- // Deploy MockEntropy with the provider address
64- entropy = new MockEntropy(provider);
65-
66- // Deploy your consumer contract
67- consumer = new MyEntropyConsumer(address(entropy));
68- }
56+ MockEntropy public entropy;
57+ MyEntropyConsumer public consumer;
58+ address public provider;
59+
60+ function setUp() public {
61+ // Use any address as the provider
62+ provider = address(0x1234);
63+
64+ // Deploy MockEntropy with the provider address
65+ entropy = new MockEntropy(provider);
66+
67+ // Deploy your consumer contract
68+ consumer = new MyEntropyConsumer(address(entropy));
69+ }
6970}
71+
7072```
7173
7274### 3. Request and Reveal Pattern
@@ -75,17 +77,18 @@ The basic testing pattern involves requesting a random number, then manually rev
7577
7678``` solidity copy
7779function testBasicRandomNumber() public {
78- // Request a random number
79- uint64 sequenceNumber = consumer.requestRandomNumber();
80-
81- // Manually reveal with your chosen random value
82- bytes32 randomNumber = bytes32(uint256(42));
83- entropy.mockReveal(provider, sequenceNumber, randomNumber);
84-
85- // Verify the callback was triggered with the correct value
86- assertEq(consumer.lastRandomNumber(), randomNumber);
87- assertEq(consumer.lastSequenceNumber(), sequenceNumber);
80+ // Request a random number
81+ uint64 sequenceNumber = consumer.requestRandomNumber();
82+
83+ // Manually reveal with your chosen random value
84+ bytes32 randomNumber = bytes32(uint256(42));
85+ entropy.mockReveal(provider, sequenceNumber, randomNumber);
86+
87+ // Verify the callback was triggered with the correct value
88+ assertEq(consumer.lastRandomNumber(), randomNumber);
89+ assertEq(consumer.lastSequenceNumber(), sequenceNumber);
8890}
91+
8992```
9093
9194The ` mockReveal() ` method signature is:
@@ -108,25 +111,26 @@ Test that your contract handles asynchronous callbacks correctly by revealing re
108111
109112``` solidity copy
110113function testOutOfOrderReveals() public {
111- // Request multiple random numbers
112- uint64 seq1 = consumer.requestRandomNumber();
113- uint64 seq2 = consumer.requestRandomNumber();
114- uint64 seq3 = consumer.requestRandomNumber();
115-
116- // Reveal in different order: 2, 3, then 1
117- bytes32 random2 = bytes32(uint256(200));
118- bytes32 random3 = bytes32(uint256(300));
119- bytes32 random1 = bytes32(uint256(100));
120-
121- entropy.mockReveal(provider, seq2, random2);
122- assertEq(consumer.lastRandomNumber(), random2);
123-
124- entropy.mockReveal(provider, seq3, random3);
125- assertEq(consumer.lastRandomNumber(), random3);
126-
127- entropy.mockReveal(provider, seq1, random1);
128- assertEq(consumer.lastRandomNumber(), random1);
114+ // Request multiple random numbers
115+ uint64 seq1 = consumer.requestRandomNumber();
116+ uint64 seq2 = consumer.requestRandomNumber();
117+ uint64 seq3 = consumer.requestRandomNumber();
118+
119+ // Reveal in different order: 2, 3, then 1
120+ bytes32 random2 = bytes32(uint256(200));
121+ bytes32 random3 = bytes32(uint256(300));
122+ bytes32 random1 = bytes32(uint256(100));
123+
124+ entropy.mockReveal(provider, seq2, random2);
125+ assertEq(consumer.lastRandomNumber(), random2);
126+
127+ entropy.mockReveal(provider, seq3, random3);
128+ assertEq(consumer.lastRandomNumber(), random3);
129+
130+ entropy.mockReveal(provider, seq1, random1);
131+ assertEq(consumer.lastRandomNumber(), random1);
129132}
133+
130134```
131135
132136This pattern ensures your contract correctly handles callbacks arriving in any order.
@@ -137,29 +141,30 @@ Test your contract with different providers to ensure provider-specific logic wo
137141
138142``` solidity copy
139143function testMultipleProviders() public {
140- address provider1 = address(0x1111);
141- address provider2 = address(0x2222);
142-
143- // Request from different providers
144- uint64 seq1 = consumer.requestFromProvider(provider1, 100000);
145- uint64 seq2 = consumer.requestFromProvider(provider2, 100000);
146-
147- // Each provider has independent sequence numbers
148- assertEq(seq1, 1);
149- assertEq(seq2, 1);
150-
151- // Reveal from each provider
152- bytes32 random1 = bytes32(uint256(111));
153- bytes32 random2 = bytes32(uint256(222));
154-
155- entropy.mockReveal(provider1, seq1, random1);
156- assertEq(consumer.lastRandomNumber(), random1);
157- assertEq(consumer.lastProvider(), provider1);
158-
159- entropy.mockReveal(provider2, seq2, random2);
160- assertEq(consumer.lastRandomNumber(), random2);
161- assertEq(consumer.lastProvider(), provider2);
144+ address provider1 = address(0x1111);
145+ address provider2 = address(0x2222);
146+
147+ // Request from different providers
148+ uint64 seq1 = consumer.requestFromProvider(provider1, 100000);
149+ uint64 seq2 = consumer.requestFromProvider(provider2, 100000);
150+
151+ // Each provider has independent sequence numbers
152+ assertEq(seq1, 1);
153+ assertEq(seq2, 1);
154+
155+ // Reveal from each provider
156+ bytes32 random1 = bytes32(uint256(111));
157+ bytes32 random2 = bytes32(uint256(222));
158+
159+ entropy.mockReveal(provider1, seq1, random1);
160+ assertEq(consumer.lastRandomNumber(), random1);
161+ assertEq(consumer.lastProvider(), provider1);
162+
163+ entropy.mockReveal(provider2, seq2, random2);
164+ assertEq(consumer.lastRandomNumber(), random2);
165+ assertEq(consumer.lastProvider(), provider2);
162166}
167+
163168```
164169
165170### Pattern 3: Testing Gas Limit Configuration
@@ -168,24 +173,27 @@ While MockEntropy doesn't enforce gas limits, you can verify that your contract
168173
169174``` solidity copy
170175function testGasLimitStorage() public {
171- uint32 customGasLimit = 200000;
172-
173- // Request with custom gas limit
174- uint64 seq = consumer.requestWithGasLimit(customGasLimit);
175-
176- // Verify gas limit was stored correctly
177- EntropyStructsV2.Request memory req = entropy.getRequestV2(provider, seq);
178- assertEq(req.gasLimit10k, 20); // 200000 / 10000 = 20
179-
180- // Reveal works normally
181- bytes32 randomNumber = bytes32(uint256(999));
182- entropy.mockReveal(provider, seq, randomNumber);
183- assertEq(consumer.lastRandomNumber(), randomNumber);
176+ uint32 customGasLimit = 200000;
177+
178+ // Request with custom gas limit
179+ uint64 seq = consumer.requestWithGasLimit(customGasLimit);
180+
181+ // Verify gas limit was stored correctly
182+ EntropyStructsV2.Request memory req = entropy.getRequestV2(provider, seq);
183+ assertEq(req.gasLimit10k, 20); // 200000 / 10000 = 20
184+
185+ // Reveal works normally
186+ bytes32 randomNumber = bytes32(uint256(999));
187+ entropy.mockReveal(provider, seq, randomNumber);
188+ assertEq(consumer.lastRandomNumber(), randomNumber);
184189}
190+
185191```
186192
187193<Callout type = " warning" emoji = " ⚠️" >
188- MockEntropy does not enforce gas limits on callbacks. Make sure to test with the real Entropy contract on a testnet before deploying to production to verify your callback stays within gas limits.
194+ MockEntropy does not enforce gas limits on callbacks. Make sure to test with
195+ the real Entropy contract on a testnet before deploying to production to
196+ verify your callback stays within gas limits.
189197</Callout >
190198
191199### Pattern 4: Deterministic Testing with Specific Values
@@ -194,22 +202,23 @@ Use deterministic random values to create reproducible tests and cover edge case
194202
195203``` solidity copy
196204function testEdgeCaseRandomValues() public {
197- // Test with zero
198- uint64 seq1 = consumer.requestRandomNumber();
199- entropy.mockReveal(provider, seq1, bytes32(0));
200- assertEq(consumer.lastRandomNumber(), bytes32(0));
201-
202- // Test with maximum value
203- uint64 seq2 = consumer.requestRandomNumber();
204- entropy.mockReveal(provider, seq2, bytes32(type(uint256).max));
205- assertEq(consumer.lastRandomNumber(), bytes32(type(uint256).max));
206-
207- // Test with hash-based values
208- uint64 seq3 = consumer.requestRandomNumber();
209- bytes32 hashValue = keccak256("deterministic test value");
210- entropy.mockReveal(provider, seq3, hashValue);
211- assertEq(consumer.lastRandomNumber(), hashValue);
205+ // Test with zero
206+ uint64 seq1 = consumer.requestRandomNumber();
207+ entropy.mockReveal(provider, seq1, bytes32(0));
208+ assertEq(consumer.lastRandomNumber(), bytes32(0));
209+
210+ // Test with maximum value
211+ uint64 seq2 = consumer.requestRandomNumber();
212+ entropy.mockReveal(provider, seq2, bytes32(type(uint256).max));
213+ assertEq(consumer.lastRandomNumber(), bytes32(type(uint256).max));
214+
215+ // Test with hash-based values
216+ uint64 seq3 = consumer.requestRandomNumber();
217+ bytes32 hashValue = keccak256("deterministic test value");
218+ entropy.mockReveal(provider, seq3, hashValue);
219+ assertEq(consumer.lastRandomNumber(), hashValue);
212220}
221+
213222```
214223
215224This approach ensures your contract handles all possible random values correctly.
@@ -235,7 +244,9 @@ You don't need to send native tokens with your requests during testing.
235244MockEntropy stores gas limits but does ** not** enforce them on callbacks. Your callback can use any amount of gas during testing.
236245
237246<Callout type = " warning" emoji = " ⚠️" >
238- Always test on a testnet with the real Entropy contract to verify your callback respects gas limits. A callback that works in MockEntropy tests may fail in production if it exceeds the gas limit.
247+ Always test on a testnet with the real Entropy contract to verify your
248+ callback respects gas limits. A callback that works in MockEntropy tests may
249+ fail in production if it exceeds the gas limit.
239250</Callout >
240251
241252### 3. Synchronous Callbacks
@@ -249,6 +260,7 @@ You decide exactly what random number is revealed and when. The real Entropy con
249260### 5. Simplified Provider Setup
250261
251262Providers in MockEntropy are just addresses with default configuration:
263+
252264- Default fee: 1 wei (not enforced)
253265- Default gas limit: 100,000
254266- Sequence numbers start at 1
@@ -281,17 +293,18 @@ Even though MockEntropy doesn't enforce limits, measure your callback's gas usag
281293
282294``` solidity copy
283295function testCallbackGasUsage() public {
284- uint64 seq = consumer.requestRandomNumber();
285-
286- uint256 gasBefore = gasleft();
287- entropy.mockReveal(provider, seq, bytes32(uint256(42)));
288- uint256 gasUsed = gasBefore - gasleft();
289-
290- console.log("Callback gas used:", gasUsed);
291-
292- // Ensure it's within your target gas limit
293- assertTrue(gasUsed < 100000, "Callback uses too much gas");
296+ uint64 seq = consumer.requestRandomNumber();
297+
298+ uint256 gasBefore = gasleft();
299+ entropy.mockReveal(provider, seq, bytes32(uint256(42)));
300+ uint256 gasUsed = gasBefore - gasleft();
301+
302+ console.log("Callback gas used:", gasUsed);
303+
304+ // Ensure it's within your target gas limit
305+ assertTrue(gasUsed < 100000, "Callback uses too much gas");
294306}
307+
295308```
296309
297310### 3. Always Test on Testnet
0 commit comments