start	end	text
0	4860	My talk on Modeling Systemic Threat Using Mainnet Fork.
5020	12660	And so, next one, who am I? I'm Martinet Li, a Research Engineer
12660	18620	slash Security Auditor from QuantStamp. And since last year, I reviewed a lot of projects,
18620	23640	especially in the DeFi space, as this particular space is booming.
24060	29980	But I was also involved in some reviews on, you know, base layer chains.
30000	36380	Like Eth2, Prism Implementation, and AvaLabs as well.
36420	40800	And the girl beside me, that's my daughter, just by the way.
40800	45520	And next one. So, what this presentation is about,
45520	49760	I kind of want to be more like a light talk and perhaps interactive,
49760	53340	so feel free to just shoot me any questions in between.
53380	59080	But basically, what I wanted to share today is kind of the status quo on testing.
59080	64020	From an auditor's point of view, and mainly focusing on composability.
64600	68380	As projects integrate with others more closely,
68380	74580	how are people right now testing their projects? And what I believe would be beneficial.
75160	79220	I will also introduce my personal project on trying to improve testing
79220	84920	with two simple examples here. So, next one.
85720	90520	So, the main challenge here is the composability.
90520	95020	So, what is composability? It is a feature of design wherein
95020	98840	the various components of a system can be easily connected
98840	104280	to form any number of satisfying results. That's from MakerDAO.
104280	108560	And although blockchain projects have always been composable,
108560	111380	you know, like it's always open API, right?
111380	115380	Its power was really unleashed by the DeFi space,
115380	123280	and especially the standardization of these token interfaces like ERC-20, ERC-721.
124300	130160	In the beginning, we see most of projects focusing just building on their own ecosystem,
130400	133220	pretty much independent from other projects.
133220	138500	They issue these tokens just hoping other to use, maybe to trade.
138500	145040	You know, but then with the use of these standardized interfaces,
145040	148600	it allows like other projects to leverage like what,
148600	151340	well, it allows projects to leverage one another, right?
151340	155500	Kind of like Lego. So, that's the term money Lego.
155920	161920	And easily connecting them together to create like so many different kinds of functionalities.
161920	164820	Of course, exchanges are the first one, you know,
164820	168480	just aggregates just using the interface and then sell them.
168500	173940	They're just using the token, not really the internal functionality, right?
174380	178560	Another piece which is important to this composability,
178560	184880	which not necessarily fits into like this money Lego thing is the Oracle part.
184880	192240	Oracle feeds us like maybe real world data and then allows us to use them on chain.
192240	197660	So, it is also like an important piece in this composability, I would say.
198220	199860	So, next one.
201800	205580	So, composability is certainly a blessing.
205580	208680	So, we see that there are so many interesting projects
208680	212860	in the past few years that emerges from here, right?
212860	215500	Pulled together as one example,
215500	220400	it builds like no loss lottery on top of the compound protocol, right?
220520	225200	So, as time goes by, like projects tend to grow more complex.
225200	230280	One of the prime example recently would be the Yearn protocol, right?
230280	238180	That helps user yield farming by putting together like Curve, AVI, Compound, MStable,
238180	240980	and a lot of other protocols, right?
240980	245440	I would say it's one of the amazing projects that full of creativity
245440	249980	and demonstrate what can be done with this composability.
251120	252800	Now, next.
253600	258860	However, this composability is also a curse, right?
258860	263300	So, we have already witnessed several attacks and one systematic failure
263910	266660	that affected the whole DeFi community.
266660	271840	And I'll just like bring up a simple example here, which is the first BZX attack,
271840	278740	which involves a DYDX, Compound, BZX, Kyber, and Uniswap, right?
278740	285600	It uses the DYDX, a flagship ability, and then borrow WBTC from Compound,
286280	293740	uses BZX as a platform to short ETH in favor of WBTC.
293740	299940	And in turn, because internally like Kyber and Uniswap was used in the BZX,
299940	305480	it drove up the price of WBTC and Uniswap.
305480	311580	And then the hacker was able to just dump the WBTC and profit from there.
311580	317400	So, you see like this complexity is also opens a lot of like,
317400	320980	you know, different kinds of attack. That's for one.
320980	322660	And next.
324760	328980	And we also see like in the black Thursday, right?
329260	334200	Not sure if the graph is visible, but we probably all know,
334200	335320	they grew up for 30%.
336740	344520	At the same time, so MakerDAO price did not update for a while.
344520	346420	So they do have like Oracle.
346420	351820	But during that time, the gas price was extremely high.
351880	357920	And thus the price was not able to update in real time.
357920	362620	And when it updated, it triggered like a massive liquidation.
363210	366220	In turn, this is one of the reasons why like,
366220	370420	there are so many collateral were auctioned off for zero.
370980	377440	So, part of this is because of the Oracle issue here.
378140	379320	So, next.
381160	387040	So, I would say composability is almost like a nightmare for developers.
387040	393920	Repeatedly see this issue, like causes a lot of troubles for developers,
393920	397900	especially when it comes to testing the project, right?
397900	400920	Like, how should the developer ensure the project
400920	404260	that they interface with are working as expected?
404580	408880	And then how, like, this is already hard, right?
408880	413740	And so, I don't really see anyone like testing extreme scenarios,
413740	417300	like the ones that we would mention above.
418220	420660	So, let's go on to the next.
422280	426980	So, the status quo on testing, kind of doing a review.
427600	431380	What we see as auditors, typically, you know,
431380	434360	if they have tests, they have unit tests,
434360	438160	they have functional tests, like for internal protocol.
438780	444500	But when it comes to testing the integration points with other projects,
444500	448180	what we see, you know, some variety there.
448300	452900	For the simple ones, if the external project is really simple,
452900	457920	then you can deploy the external projects locally, you know, just in the ganache.
457920	460300	This is possible when it's small, right?
460300	466020	But it's impossible if the external project is complicated.
466020	470880	Just imagine, like, you're deploying the whole MakerDAO system.
470880	472860	Well, that's going to be a nightmare.
473820	474740	Next.
475280	482140	And so, there's the second option, which is mocking the external protocol, right?
482140	486020	A developer has to understand what the external contract would do
486020	488160	and mock the behavior accordingly.
489200	494920	Oftentimes, developers will simplify these logic to, you know,
494920	500940	to not really implement everything in the protocol, but just the behavior.
500940	507300	And so, there are possible discrepancies between the mocked contract and the real behavior.
507300	510800	And that actually presents a potential risk.
511340	516640	Now, next on, we have testing on testnet, right?
516640	521120	If you're interfacing with just one project, it kind of works.
521120	525980	Although, it's still tedious to get all the test tokens, testnet tokens, and, like, Ether.
525980	527900	You need the faucet for that.
528020	532120	But if you're building a project that interfaces with different projects,
532120	538040	then you can see on the right-hand side, like, this is how, you know,
538040	540440	projects on the testnet would look like.
540440	543620	Like, MakerDAO, they probably have their own testnet.
543620	549900	But for sure, I know Aave and Compound, they use, like, different dymocks on the testnet.
549900	554940	And so, if you're testing, if you are writing a project
554940	560020	that interfaces with both Aave and Compound and want to use dye in between,
560020	566920	this is simply different, you know, from the structure in mainnet.
567140	569000	Now, next.
569960	575060	Ah, well, here we have testing on mainnet.
575060	578060	And needless to say, this is super costly.
578420	585100	Typically, it only allows functional and high-level manual testing, you know.
585100	592140	And so, among all these, I would say the most common ones are mocking.
592940	598120	But testing on testnet do exist, but typically done, like, not very extensively.
599000	603740	Because developers, like, oftentimes find, you know,
603740	608700	fetching those resources very, very troublesome, right?
608700	615480	And so, I have personally seen projects that did both the mock and testing on testnet.
615480	619720	So that's, you know, they are, you can see that they're trying their best,
619720	622320	but still missed to test the profit sharing.
622320	628500	Because that requires some understanding of the underlying protocol
628500	630300	and how they would behave.
630300	632280	So they missed that in the mock.
632860	639060	And then on the testnet, because it was kind of like one-shot testing,
639060	644380	it doesn't really wait for the time and wait for the profit to accrue.
644380	647300	So, like, they missed the profit sharing part.
647400	650420	And we were able to locate that issue, luckily.
651080	657620	After that, I sort of see this as this lack of testing facility
657620	661700	that helps, you know, testing, like, composability thing
662760	666660	is a huge security issue for the whole ecosystem.
667940	668920	Next.
671120	674940	And so, with the standard tool, actually, I do,
674940	679260	there are one option that I would say it's quite nice.
680420	684340	I do recommend, like, testing under this mainnet fork.
684340	687600	And Ganache provides this fork option,
688620	695240	which, surprisingly, I haven't seen any project uses this to test external library.
695700	701120	And that's probably because of my side note right there.
701420	704720	The fork does have some bug.
705280	708440	You know, when you use Uniswap, you probably,
710320	715680	you'll face some weird re-entrancy error, like reverts,
715680	718800	but you never did a re-entrancy there.
719040	723140	So, but there is a pull request, but I don't think a lot of people know that.
723140	726740	I think that's probably one of the reasons that this is not used.
726740	733920	But if this is used and fixed, then I see this is actually pretty nice.
734520	738420	Projects interconnect with each other the same way as mainnet,
738420	740360	because it's the mainnet fork.
740360	744020	There's, of course, no cost, because it's a local Ganache.
744140	749820	And then huge amount of ethers when starting up the local blockchain, as always.
750500	755160	And, you know, Ganache also allows you to sign transaction as other accounts.
755160	759120	So you can be the whale, you know, anytime.
759120	761120	So this is already pretty nice.
761830	762610	Next.
763480	772220	So with this, we can already start to model a systemic threat, which is the whale, right?
772220	779620	For example, to be a die whale here, well, you can use an unlock account.
780060	788300	You find some die whale on the mainnet and, you know, just write his address down,
789060	793560	unlock his address on your local Ganache and use that to test.
793600	794800	So that's good.
794800	800560	The downside is that, well, if the whale just transfers his die to other places,
800560	803780	then, you know, this test doesn't work anymore.
803780	806280	You need to find another die whale.
806660	812180	So, you know, not really reliable as test, I would say.
813500	819380	The other two paths that you can do is that you can, of course, mint die on MakerDAO.
819380	824560	However, that requires you to, you know, you already have that huge amount of ethers,
824560	826360	so you can definitely do that, right?
826360	834020	But you have to know how to open vault, lock up collateral and use that to mint die.
834040	839120	But in the end, what you really want is just increasing your balance in the die.
839120	842700	You know, it's pretty tedious and going through all that.
842700	844860	And same for buying die on DEX.
844860	851240	If you want to do that, you need to know Uniswap's interface, perhaps, and how to interact with them.
851520	856360	So it's not as convenient.
857000	858160	So, next.
860720	864800	Yeah, and still, like, some risk remains very hard to model.
865470	871840	Like, if modeling a risk involves changing the price feed on MakerDAO or Uniswap v2,
871840	873780	that may be a problem.
873940	882280	And then, let's say, if you want to model what would happen on your platform or your smart
882280	888840	contract when you experience an oracle attack, like, for example, you're using Uniswap and
888840	893520	you're also using Chainlink as your oracle.
893520	901120	What would happen if there is a mismatch on my protocol, right?
901120	902620	Can I model that?
903180	907760	And then, you know, seeing the BZX attack, that's pretty sophisticated.
908180	912600	It might be very hard to come up with that sort of scenarios.
912600	921640	And so, one thing that you might want to do is just assume that there could be a mismatch in
921640	924040	the oracle price, then what would happen, right?
924040	925420	That's much easier.
925420	931960	But in this mainnet fork, you cannot do that because you still have to follow all the blockchain
931960	933060	rules, right?
933060	939140	And in general, if modeling requires, like, changing a variable that is not directly settable
939140	942580	by an externally owned account, this is challenging.
943480	953240	So, the question, next one, is what if we could ignore code as law, you know, on the local
953240	953860	blockchain?
953860	960380	And what if, like, can we change the storage directly without any permission?
960820	962180	Next one.
963500	970320	So, I kind of went on this direction and digged into the ganache because since this is the
970320	975240	testing environment that most of the people are using, I decided to dig into this one and
975240	977580	see if this can be accomplished.
977680	983820	And so, ganache itself, it kind of looks like this, you know, like the related part.
983820	990540	It has WS server, HTTP server, and it connects to this get API module that it has internally.
990540	998400	This get API module controls the state manager, and it's supported by a VM, which is the
998400	1000980	Ethereum JS VM.
1001600	1004980	So, next.
1007120	1013800	And so, within this ganache, this state manager, you know, within this VM, then I found that
1013800	1022120	in the VM state manager, there's actually a free function that is very useful for us, which is
1022120	1025440	the put account, put contract code, put contract storage.
1025440	1033920	By using these, essentially, you can directly modify the storage and the state of the local
1033920	1035040	ganache.
1035140	1043820	So, what typically was done is that you still go through ganache and send transaction to ganache.
1043820	1052880	So, what I tried to do was to open up a backdoor, if you may, and say that, hey, I don't want
1052880	1054620	to verify my transaction.
1054620	1058620	I just directly want to modify my storage right there.
1058880	1064100	So, that's the root of my project.
1064100	1066160	And so, next one.
1067640	1073240	So, after some development, like, this is my project, which I call Godmode for Test.
1073240	1075920	It basically consists of three parts.
1076220	1080920	The project itself is still in, like, very early stage and still needs a lot of work.
1080920	1088800	It already works, and I personally use it for development, especially when it's come to
1088800	1090560	DeFi projects.
1090560	1094500	So, what I built consists of three pieces.
1094500	1098520	The first one is this ganache core.
1098520	1104680	So, this modified ganache core allows us to ignore the blockchain log and just directly
1104680	1107900	modify the storage, as previously stated.
1107900	1115140	And then, on top of that, I created a wrapper JavaScript library that you can integrate
1115140	1117100	into the Truffle framework.
1117120	1125520	So, you know, all the familiar tools that we use and leverage the Solidity contract as
1125520	1126900	sort of an API.
1126900	1132260	I think it's easier to understand how to modify the storage of the blockchain.
1132820	1135680	And there's some set of precompiled contracts.
1136560	1140800	So, what the precompiled contracts would do...
1141260	1141920	next, please...
1143500	1150740	is, you know, I want to provide some easy-to-set-up scenarios for the developers.
1150740	1158260	For example, to mint Dai, you don't have to think about finding that whale and, you know,
1158260	1162580	worry about the whale will transfer it away and the test won't work anymore, or worry
1162580	1168580	about all the vault, you know, all the original mint Dai process.
1168580	1177000	Now, what you need to do is just call this function call and then it will give Bob, you
1177000	1180140	know, 10,000 Dai, which is great.
1180740	1181900	Next.
1184060	1186820	And in a more general sense...
1187580	1194020	So, this is a general API that I provide that you can basically craft...
1195960	1200720	use this to modify, like, arbitrary contract storage.
1200720	1206920	And so, it might not be very clear just by seeing this.
1206920	1210100	And so, I'll demonstrate a few examples.
1210960	1215660	I'm happy that I have had the backup of, like, kind of all the screenshots.
1216380	1218320	And so, yeah, we'll...
1218320	1219540	I kind of...
1219540	1224100	I will kind of walk you through, like, all the screenshots on doing these things.
1224660	1225960	So, yeah.
1225960	1227980	So, next one.
1228140	1236000	So, we'll go through, like, the first example, which is using that general API and use it
1236000	1242780	to mint Dai, you know, like, the one that I already had in the library.
1242780	1245640	But right now, I just wanted to show you how this could be done.
1245660	1253360	And so, the first step would be you go and find Dai's source code and mainnet address.
1253360	1256620	And, of course, both are available on Etherscan.
1256620	1259320	So, you go there, copy it down.
1259320	1265100	I'm assuming that we're using, like, Truffle project framework here.
1265100	1270140	So, we just store the Dai source code under the contracts folder.
1270780	1271900	Next one.
1275000	1282360	And so, the following step is we clone that Dai contract, you know, rename it.
1282360	1286960	So, now we would have, like, let's say two contracts.
1286960	1287940	One is Dai.
1287940	1291260	Let's say the other one is called gmDai.
1292500	1296080	And we modify the mint function.
1296080	1299140	So, how we modify it, it's really simple.
1299140	1305980	The reason that we cannot mint Dai is it was authorized.
1305980	1307880	Like, it is controlled.
1308600	1315420	There's a requirement statement that prevents us from going in, which is this modifier auth, right?
1315420	1319540	So, what we can do is just to remove that auth.
1319540	1325380	And that allows anyone to call this mint.
1325380	1330040	So, you know, that's essentially how it's done.
1330180	1330940	Next.
1334080	1340460	And so, in the normal test, and this is how we would write it.
1340740	1348280	So, we have, we would require both artifacts, include both artifacts into the test,
1348280	1350540	which is the Dai and gmDai.
1350540	1357500	So, you recognize gmDai is the one that we just modified and removed the modifier, right?
1358160	1365200	And, you know, and like all other stuff are pretty much just set up, basic setup,
1365200	1371600	like, you know, talking to the Godmode Ganache and all that.
1371600	1379080	But the real essential part is the part that I, you know, had with the red square or rectangle,
1379080	1381740	whatever, that's the executeAs.
1381740	1387580	So, what you do here is actually you're executing the Dai contract.
1387580	1391960	So, you see this Dai contract is just like two lines above.
1391960	1395860	It's, it was like a way to Dai at this address.
1395860	1400880	And that's the address of the main net Dai address, right?
1400880	1411440	And so, I execute this Dai contract as if it is the modified contract.
1411740	1418800	So, I'm actually just executing, you can think of it that this way.
1418800	1423560	So, I am modifying the storage of Dai contract.
1423560	1431840	But according to the rules set by this gmDai artifact or contract.
1431840	1438760	And so, here, essentially, I'm just calling mint from the gmDai contract.
1438760	1442600	Then I say, give Alice this amount of Dai.
1442740	1445140	And the next line is assertion.
1445280	1450160	And so, this is, yeah, this is basically how it works.
1451420	1452760	Next one.
1455360	1459400	Now, so, that's the, that's just minting Dai.
1459400	1465060	And so, as a second example, I'll show you how to modify to make a DAO price feed.
1465060	1473500	Now, this is an essential step for modeling this systemic threat, like, you know,
1473500	1476260	oracle attacks and all of that.
1476260	1487460	Because what you want to do is to have, like, maybe two oracles report different values, right?
1487460	1492100	So, you want to read and perhaps change to make one of the oracles price feed.
1492100	1493980	Here, I chose my DAO.
1493980	1499360	And, of course, you just Google and find out where the maker DAO is getting their price.
1500300	1505160	And so, this is the address that I found on their page.
1505200	1510540	And then you just go to that ether scan the same way we did as Dai.
1510540	1512540	And then copy the source code.
1513400	1514680	Next one.
1517590	1522270	Yeah, and, you know, this is still a little bit technical.
1522270	1525970	You have to understand kind of how it works.
1525970	1529070	But luckily, most of the oracles are pretty simple.
1529070	1531590	They're basically reporting what they have.
1531590	1533310	Maybe they have something else.
1533310	1538790	Like, in this maker DAO price feed, this OSM module is their oracle.
1538790	1542870	I think it's oracle security module or something like that.
1543210	1546870	So, OSM module basically has an example.
1546870	1549770	Hey, OSM peak is getting the current value.
1549770	1552670	Or OSM read is getting the current value or fail.
1552670	1556330	And so, you go and look at the source code of OSM.
1556330	1564290	And you find out that, ah, it is actually returning the value from this curr.val, right?
1564290	1568210	So, this is where the current value is storing.
1568990	1574590	And so, what we want to do is basically just read this one.
1574590	1580190	And, you know, and perhaps modify it.
1580190	1588590	And so, the reason I say read is that if you later take a look at the OSM contract,
1588590	1591470	you see, well, you see right here, actually.
1591470	1594330	There's a modifier called tall.
1594330	1602510	And that prevents any user, like, external contracts from using, from reading the value here.
1602510	1609450	But if we want to just use, just inspect this value, we can actually do that.
1610290	1611170	But, okay.
1611170	1612450	So, next one.
1616560	1622660	And so, yeah, kind of same way we did on the die to GM die.
1622660	1632520	So, we modify the clone OSM module, add these two functions and event.
1632520	1641100	The reason I do event is that, unfortunately, right now, it doesn't read.
1641440	1648880	So, this execute as cannot just read a function.
1648880	1651500	You know, like, it will always do a state change.
1651500	1655960	So, if you do a view function, then it will revert on that.
1655960	1657960	So, this is kind of a workaround.
1657960	1661740	But nevertheless, you can still get the value this way.
1661740	1667440	And then, the next one is pretty simple, which is just setting that current value.
1667440	1667540	Right?
1667540	1672300	So, set curve val and curve dot val equals to the new value that we have.
1672860	1674060	Next one.
1676620	1683760	And so, with this, you know, we can just write test to check the behavior.
1684700	1692920	Similar way as we would say that this OSM contract is the OSM at, you know,
1692920	1699840	the original address that this contract were placed.
1699980	1706580	And then, the next two lines, this transaction, weird transaction thing is reading from the logs.
1706580	1708560	Basically, reading from the events.
1708560	1713640	And then, reading the current value out of that event.
1715160	1719960	So, in the middle, there's this await got node execute.
1719960	1721980	So, here, again, it's the same thing.
1721980	1728300	We're executing this OSM contract as our modified contract.
1728300	1734160	And now, you see that this set curve val is a function that we added.
1734160	1737820	It's not anywhere in the original contract.
1737820	1740000	And we just added that part.
1740000	1746160	But now, this modified ganache will be able to run this thing.
1746320	1753080	And then, it will just set the curve that val into this new function.
1753080	1754100	Oh, sorry, value.
1754660	1759980	And I just printed out, print the value again to see what's there.
1761560	1763000	Next one.
1764420	1767860	So, now, yeah, this is kind of the result.
1767860	1778080	You'll see that the original value is this, basically, 387 USD, right?
1778080	1783880	And then, I just set it to some number that I just thought set there.
1784120	1789340	So, now, you are able to change the make and dial price feed with this thing.
1791980	1794140	Yeah, so, next one.
1795620	1803440	So, some downside of this tool is that mainnet fork can be buggy for the ganache.
1803900	1808800	So, the fix that I have there in the side node is not official.
1809740	1813120	So, you know, sometimes, there are some bugs there.
1813220	1819980	And the second one, you kind of already saw that we cannot create view function and return
1819980	1821460	properly yet.
1821460	1822900	So, I'm still working on that.
1824880	1828300	And, of course, this is a local ganache.
1828300	1832320	So, you cannot simulate how others would behave.
1832320	1840740	You know, it's not like a simulation that you can see all, like, with this new values,
1840740	1845620	how are people going to behave with the new incentive and stuff, right?
1845620	1848380	So, you're alone in this local blockchain.
1848380	1851600	That's kind of an inherent limitation here.
1852540	1859440	And fourth is this arbitrary modify storage is sometimes too powerful.
1859440	1865400	Because, you know, it can get you to state that are just not possible to reach.
1866140	1873480	So, you have to be careful about and thinking about what kind of scenarios you want to craft.
1873480	1875420	And if that is a reasonable scenario.
1875420	1884960	Because before this tool, you have to think of ways to get to a state.
1884960	1886910	And then you can start testing.
1887420	1891420	Now, with this tool, you can get to any state directly.
1891420	1896070	But whether that state makes sense or not, that's another question.
1896460	1901560	So, that's another problem that we have to take care and think about.
1901820	1902670	Yeah.
1903420	1905400	And so, next one.
1907400	1916980	Kind of a conclusion is that DeFi composability is currently both a blessing and a curse.
1917100	1924980	I hope that with more testing facilities, we can turn it into a pure bliss.
1925680	1934880	And as of right now, as I've said, I don't see a lot of testing on even the integration side.
1934880	1940200	Let alone testing extreme scenarios to prevent systemic threats.
1941320	1948220	Like, you know, I've really never seen people testing how systems would react
1948220	1953200	if an Oracle attack is to happen, you know, modeling these different threats.
1953260	1953780	Right?
1953780	1957720	But this is mainly because there's no...
1958520	1962240	Well, there are not a lot of tools that support this.
1962300	1963260	Right?
1963260	1967840	And so, I believe there's still a lot of space to improve in testing.
1967840	1971260	Especially in terms of this composability thing.
1971900	1974620	And I think we need...
1975500	1977960	This presentation is almost like...
1978840	1984080	I would treat it like an open invitation for everyone to kind of work on this area.
1984420	1989700	I believe we need to work together to help secure all these blockchain projects
1990180	1994780	and make this, you know, make the testing facilities better
1994780	1999060	and make the composability not a headache anymore.
1999320	2000060	Yeah.
2000060	2001320	And that's it.
2001320	2003480	Thank you for your time.
2003480	2004640	Great presentation.
2011830	2012990	All right.
2012990	2014910	Any questions?
2018410	2020110	Ah, I see.
2020110	2027150	Are there limitations between forking mainnet from full versus archive nodes?
2027150	2031530	Ah, it depends.
2031530	2039350	So, I actually just used Infura, not even the full node.
2039350	2042130	Oh, Infura is the full node, right?
2042130	2044550	Yeah, but I've just been using Infura.
2044550	2052670	And if you just care about how it's going to react at its current stage, I think that's fine.
2053390	2057770	After like 30 minutes, then your test would start failing,
2057770	2062910	and it will say that, hey, you know, you don't have access to archive nodes.
2063790	2066180	Then that would start failing.
2067390	2074530	But, you know, just for the purpose of doing unit tests on mainnet fork,
2074530	2076330	especially for the integration part,
2076330	2081590	I think you don't really need an archive node, to be honest.
2082080	2091040	Yeah, no problem.
2091040	2092220	My pleasure.
2094200	2103460	Ah, yes, let me paste my GitHub repository into the chat.
2103860	2111520	I have to warn everyone that this is like a very, very, you know, initial work.
2111520	2114060	It works, but it's very ugly.
2114860	2119760	I'm not particularly proud about the code quality,
2119760	2124240	but I am pretty happy about the result that it can get me, though.
2124240	2126160	So I'm happy to share.
2135400	2138760	All right, any other questions?
2138780	2140360	Thank you, Miko.
2153150	2154650	Thank you.
2154650	2156230	Thank you.
2156230	2159450	Do we have other questions, like in Twitch?
