@@ -27,15 +27,19 @@ export default class ForkEnvHelper {
2727 async send ( method : string , params : unknown [ ] ) {
2828 this . #request_id += 1
2929
30- return this . context . request . post ( this . url , {
31- data : JSON . stringify ( {
32- id : this . #request_id,
33- jsonrpc : "2.0" ,
34- method,
35- params,
36- } ) ,
37- headers : { "Content-Type" : "application/json" } ,
30+ const payload = JSON . stringify ( {
31+ id : this . #request_id,
32+ jsonrpc : "2.0" ,
33+ method,
34+ params,
3835 } )
36+
37+ return this . context . request
38+ . post ( this . url , {
39+ data : payload ,
40+ headers : { "Content-Type" : "application/json" } ,
41+ } )
42+ . then ( ( resp ) => resp . json ( ) )
3943 }
4044
4145 impersonateAccount ( addr : string ) {
@@ -52,25 +56,51 @@ export default class ForkEnvHelper {
5256 return this . send ( "hardhat_setBalance" , [ address , amount . toHexString ( ) ] )
5357 }
5458
59+ async getERC20Balance ( contract : string , address : string ) : Promise < BigNumber > {
60+ const iface = new Interface ( [
61+ "function balanceOf(address addr) view returns (uint256)" ,
62+ ] )
63+
64+ const amount = await this . send ( "eth_call" , [
65+ {
66+ to : contract ,
67+ data : iface . encodeFunctionData ( "balanceOf" , [ address ] ) ,
68+ } ,
69+ ] )
70+
71+ return iface . decodeFunctionResult ( "balanceOf" , amount . result ) [ 0 ]
72+ }
73+
74+ async emptyERC20Balance ( contract : string , address : string ) {
75+ const balance = await this . getERC20Balance ( contract , address )
76+ if ( balance . gt ( 0n ) ) {
77+ await this . impersonateAccount ( address )
78+ await this . transferERC20 ( contract , this . defaultAccounts [ 0 ] , balance )
79+ await this . stopImpersonating ( address )
80+ }
81+ }
82+
5583 transferERC20 (
5684 contract : string ,
5785 addressTo : string ,
58- amount : string ,
86+ amount : string | BigNumber | bigint ,
5987 decimals = 18 ,
6088 ) {
6189 if ( this . emulatedAccount === null ) {
6290 throw new Error ( "Must call impersonateAccount first" )
6391 }
6492
65- this . setBalance ( this . emulatedAccount , utils . parseUnits ( "10.0" ) )
66-
6793 const fragment = FunctionFragment . from ( "transfer(address to, uint amount)" )
6894
6995 const iface = new Interface ( [ fragment ] )
7096
71- const balance = utils . parseUnits ( amount , decimals )
97+ const transferValue =
98+ typeof amount === "string" ? utils . parseUnits ( amount , decimals ) : amount
7299
73- const data = iface . encodeFunctionData ( "transfer" , [ addressTo , balance ] )
100+ const data = iface . encodeFunctionData ( "transfer" , [
101+ addressTo ,
102+ transferValue ,
103+ ] )
74104
75105 return this . send ( "eth_sendTransaction" , [
76106 { from : this . emulatedAccount , to : contract , data } ,
0 commit comments