1+ import { BigNumber } from "@ethersproject/bignumber" ;
2+ import { Contract } from "@ethersproject/contracts"
3+ import { parseEther } from "@ethersproject/units"
4+ import { expect } from "chai" ;
5+ import hre , { ethers , waffle } from "hardhat" ;
6+ import { AddressOne } from "../utils/constants" ;
7+ import { buildSafeTransaction , executeContractCallWithSigners , executeTxWithSigners , MetaTransaction } from "../utils/execution"
8+ import { buildMultiSendSafeTx } from "../utils/multisend" ;
9+
10+ interface TestSetup {
11+ migratedSafe : Contract ,
12+ mock : Contract ,
13+ multiSend : Contract
14+ }
15+
16+ export const verificationTests = ( setupTests : ( ) => Promise < TestSetup > ) => {
17+
18+ const [ user1 , user2 , user3 ] = waffle . provider . getWallets ( ) ;
19+
20+ describe ( "execTransaction" , async ( ) => {
21+ it ( 'should be able to transfer ETH' , async ( ) => {
22+ const { migratedSafe } = await setupTests ( )
23+ await user1 . sendTransaction ( { to : migratedSafe . address , value : parseEther ( "1" ) } )
24+ const nonce = await migratedSafe . nonce ( )
25+ const tx = buildSafeTransaction ( { to : user2 . address , value : parseEther ( "1" ) , nonce } )
26+
27+ const userBalance = await ethers . provider . getBalance ( user2 . address )
28+ await expect ( await ethers . provider . getBalance ( migratedSafe . address ) ) . to . be . deep . eq ( parseEther ( "1" ) )
29+
30+ await executeTxWithSigners ( migratedSafe , tx , [ user1 ] )
31+
32+ await expect ( await ethers . provider . getBalance ( user2 . address ) ) . to . be . deep . eq ( userBalance . add ( parseEther ( "1" ) ) )
33+ await expect ( await ethers . provider . getBalance ( migratedSafe . address ) ) . to . be . deep . eq ( parseEther ( "0" ) )
34+ } )
35+ } )
36+
37+ describe ( "addOwner" , async ( ) => {
38+ it ( 'should add owner and change treshold' , async ( ) => {
39+ const { migratedSafe } = await setupTests ( )
40+
41+ await expect (
42+ executeContractCallWithSigners ( migratedSafe , migratedSafe , "addOwnerWithThreshold" , [ user2 . address , 2 ] , [ user1 ] )
43+ ) . to . emit ( migratedSafe , "AddedOwner" ) . withArgs ( user2 . address ) . and . to . emit ( migratedSafe , "ChangedThreshold" )
44+
45+ await expect ( await migratedSafe . getThreshold ( ) ) . to . be . deep . eq ( BigNumber . from ( 2 ) )
46+ await expect ( await migratedSafe . getOwners ( ) ) . to . be . deep . equal ( [ user2 . address , user1 . address ] )
47+
48+ await expect (
49+ executeContractCallWithSigners ( migratedSafe , migratedSafe , "addOwnerWithThreshold" , [ user3 . address , 1 ] , [ user1 , user2 ] )
50+ ) . to . emit ( migratedSafe , "AddedOwner" ) . withArgs ( user3 . address ) . and . to . emit ( migratedSafe , "ChangedThreshold" )
51+
52+ await expect ( await migratedSafe . getThreshold ( ) ) . to . be . deep . eq ( BigNumber . from ( 1 ) )
53+ await expect ( await migratedSafe . getOwners ( ) ) . to . be . deep . equal ( [ user3 . address , user2 . address , user1 . address ] )
54+
55+ await expect ( await migratedSafe . isOwner ( user1 . address ) ) . to . be . true
56+ await expect ( await migratedSafe . isOwner ( user2 . address ) ) . to . be . true
57+ await expect ( await migratedSafe . isOwner ( user3 . address ) ) . to . be . true
58+ } )
59+ } )
60+
61+ describe ( "enableModule" , async ( ) => {
62+ it ( 'should enabled module and be able to use it' , async ( ) => {
63+ const { migratedSafe, mock } = await setupTests ( )
64+
65+ await expect (
66+ executeContractCallWithSigners ( migratedSafe , migratedSafe , "enableModule" , [ user2 . address ] , [ user1 ] )
67+ ) . to . emit ( migratedSafe , "EnabledModule" ) . withArgs ( user2 . address )
68+
69+ await expect ( await migratedSafe . isModuleEnabled ( user2 . address ) ) . to . be . true
70+ await expect ( await migratedSafe . getModulesPaginated ( AddressOne , 10 ) ) . to . be . deep . equal ( [ [ user2 . address ] , AddressOne ] )
71+
72+ const user2Safe = migratedSafe . connect ( user2 )
73+ await expect (
74+ user2Safe . execTransactionFromModule ( mock . address , 0 , "0xbaddad" , 0 )
75+ ) . to . emit ( migratedSafe , "ExecutionFromModuleSuccess" ) . withArgs ( user2 . address )
76+ expect ( await mock . callStatic . invocationCountForCalldata ( "0xbaddad" ) ) . to . be . deep . equals ( BigNumber . from ( 1 ) ) ;
77+ } )
78+ } )
79+
80+ describe ( "multiSend" , async ( ) => {
81+ it ( 'execute multisend via delegatecall' , async ( ) => {
82+ const { migratedSafe, mock, multiSend } = await setupTests ( )
83+
84+ await user1 . sendTransaction ( { to : migratedSafe . address , value : parseEther ( "1" ) } )
85+ const userBalance = await hre . ethers . provider . getBalance ( user2 . address )
86+ await expect ( await hre . ethers . provider . getBalance ( migratedSafe . address ) ) . to . be . deep . eq ( parseEther ( "1" ) )
87+
88+ const txs : MetaTransaction [ ] = [
89+ buildSafeTransaction ( { to : user2 . address , value : parseEther ( "1" ) , nonce : 0 } ) ,
90+ buildSafeTransaction ( { to : mock . address , data : "0xbaddad" , nonce : 0 } )
91+ ]
92+ const safeTx = buildMultiSendSafeTx ( multiSend , txs , await migratedSafe . nonce ( ) )
93+ await expect (
94+ executeTxWithSigners ( migratedSafe , safeTx , [ user1 ] )
95+ ) . to . emit ( migratedSafe , "ExecutionSuccess" )
96+
97+ await expect ( await hre . ethers . provider . getBalance ( migratedSafe . address ) ) . to . be . deep . eq ( parseEther ( "0" ) )
98+ await expect ( await hre . ethers . provider . getBalance ( user2 . address ) ) . to . be . deep . eq ( userBalance . add ( parseEther ( "1" ) ) )
99+ expect ( await mock . callStatic . invocationCountForCalldata ( "0xbaddad" ) ) . to . be . deep . equals ( BigNumber . from ( 1 ) ) ;
100+ } )
101+ } )
102+
103+ describe ( "fallbackHandler" , async ( ) => {
104+ it ( 'should be correctly set' , async ( ) => {
105+ const { migratedSafe, mock } = await setupTests ( )
106+ // Check fallback handler
107+ await expect (
108+ await ethers . provider . getStorageAt ( migratedSafe . address , "0x6c9a6c4a39284e37ed1cf53d337577d14212a4870fb976a4366c693b939918d5" )
109+ ) . to . be . eq ( "0x" + mock . address . toLowerCase ( ) . slice ( 2 ) . padStart ( 64 , "0" ) )
110+ } )
111+ } )
112+ }
0 commit comments