def test_call_empty_target(msig, usrs, anyone): value = 100 tx_value = 150 action = Action(CallType.CALL, C.ADDRESS_EMPTY, C.ZERO_ADDRESS, 3000, value, '0xabababab') signAndExecute(msig, usrs, action, {'value': tx_value}) assert web3.eth.getBalance(C.ADDRESS_EMPTY) == value assert msig.balance() == tx_value - value
def test_fail_unmatched_value(msig, usrs): value = 100 action = Action(CallType.DELEGATECALL, C.ADDRESS_EMPTY, C.ZERO_ADDRESS, 3000, value, C.EMPTY_BYTES) with brownie.reverts(): signAndExecute(msig, usrs, action) with brownie.reverts(): signAndExecute(msig, usrs, action, {'value': value + 1})
def test_non_sequential_signers(deployer, usrs, usr_ids): threshold = len(usrs) - 1 action = Action(CallType.CALL) signers = usrs.copy() signers.pop(threshold // 2) (msig, _) = utils.new_msig(deployer, threshold, usr_ids) signAndExecute(msig, signers[:threshold], action) assert msig.nonce() == 1
def test_call_value_no_callvalue(msig, usrs, anyone): bal0 = 1000 value = 200 action = Action(CallType.CALL, C.ADDRESS_EMPTY, C.ZERO_ADDRESS, 3000, value) anyone.transfer(msig.address, amount=bal0) signAndExecute(msig, usrs, action) assert web3.eth.getBalance(C.ADDRESS_EMPTY) == value assert msig.balance() == bal0 - value
def test_benchmark_gnosis(deployer, usr_ids, usrs): threshold = C.THRESHOLD action = Action(CallType.CALL, C.ADDRESS_EMPTY, C.ZERO_ADDRESS, 2300, 100, C.EMPTY_BYTES) # deploy Safe and Minisig (msig, msig_deploy_gas) = utils.new_msig(deployer, threshold, usr_ids) (safe, safe_deploy_gas) = gnosis.new_safe(deployer, threshold, usr_ids) # give each contract initial balance deployer.transfer(msig.address, amount=action.value) deployer.transfer(safe.address, amount=action.value) deployer.transfer(action.target, amount=1) # ensure account is non-empty target_bal0 = web3.eth.getBalance(action.target) # Execute transactions signers = usrs[:threshold] msig_exec_tx = utils.signAndExecute(msig, signers, action) safe_exec_tx = gnosis.signAndExecute(safe, signers, action) assert web3.eth.getBalance(action.target) - target_bal0 == 2 * action.value print('\nGnosis Safe') summarize('DEPLOYMENT', 'GnosisSafe', safe_deploy_gas, msig_deploy_gas) summarize('EXCEUTION', 'GnosisSafe', safe_exec_tx.gas_used, msig_exec_tx.gas_used)
def test_benchmark_silent_cicero(deployer, usr_ids, usrs): threshold = C.THRESHOLD action = Action(CallType.CALL, C.ADDRESS_EMPTY, C.ZERO_ADDRESS, 100000, 100, C.EMPTY_BYTES) # deploy Yul Wallet and Minisig (msig, msig_deploy_gas) = utils.new_msig(deployer, threshold, usr_ids) (yul_wallet, yul_deploy_gas) = silent_cicero.new_yul_wallet(deployer, threshold, usr_ids) # Yul Wallet can only delegatecall, so we need a helper contract to actually send funds yul_helper = brownie.YulWalletHelper.deploy({'from': deployer}) # give each contract initial balance deployer.transfer(msig.address, amount=action.value) deployer.transfer(yul_wallet.address, amount=action.value) deployer.transfer(action.target, amount=1) # ensure account is non-empty target_bal0 = web3.eth.getBalance(action.target) # Execute transactions signers = usrs[:threshold] msig_exec_tx = utils.signAndExecute(msig, signers, action) yul_exec_tx = silent_cicero.signAndExecute(yul_wallet, yul_helper, signers, action) assert web3.eth.getBalance(action.target) - target_bal0 == 2 * action.value print('\nSilent Cicero\'s Yul Multisig') summarize('DEPLOYMENT', 'Yul Wallet', yul_deploy_gas, msig_deploy_gas) summarize('EXCEUTION', 'Yul Wallet', yul_exec_tx.gas_used, msig_exec_tx.gas_used)
def test_dcall_empty(msig, mock, usrs): action = Action(CallType.DELEGATECALL, mock.address, C.ZERO_ADDRESS, 3000, 0, C.EMPTY_BYTES) tx = signAndExecute(msig, usrs, action) call = utils.last_call_log(tx.logs, mock.abi) assert msig.nonce() == 1 assert call['src'] == tx.sender assert checksum(call['context']) == msig.address assert call['gas'] <= action.gas assert call['val'] == action.value assert call['data'] == action.data
def test_call_empty(msig, mock, usrs): action = Action(CallType.CALL, mock.address, C.ZERO_ADDRESS, 3000, 0, C.EMPTY_BYTES) tx = signAndExecute(msig, usrs, action) executed = tx.events[-1] assert msig.nonce() == 1 assert executed['src'] == msig.address assert executed['context'] == action.target assert executed['gas'] <= action.gas assert executed['val'] == action.value assert executed['data'] == action.data
def test_dcal_value_and_data(msig, mock, usrs): value = 100 action = Action(CallType.DELEGATECALL, mock.address, C.ZERO_ADDRESS, 4000, value, '0xdeadbeef') tx = signAndExecute(msig, usrs, action, {'value': value}) call = utils.last_call_log(tx.logs, mock.abi) assert msig.balance() == value assert msig.nonce() == 1 assert call['src'] == tx.sender assert checksum(call['context']) == msig.address assert call['gas'] <= action.gas assert call['val'] == action.value assert call['data'] == action.data
def test_call_value_and_data(msig, mock, usrs): action = Action(CallType.CALL, mock.address, C.ZERO_ADDRESS, 3000, 1, '0xabababab') tx_value = 10 tx = signAndExecute(msig, usrs, action, {'value': tx_value}) call = tx.events[-1] assert msig.nonce() == 1 assert call['src'] == msig.address assert call['context'] == action.target assert call['gas'] <= action.gas + 2300 assert call['val'] == action.value assert call['data'] == action.data assert msig.balance() == tx_value - action.value
def test_last_threshold_signers(deployer, usrs, usr_ids): threshold = len(usrs) - 1 action = Action(CallType.CALL) (msig, _) = utils.new_msig(deployer, threshold, usr_ids) signAndExecute(msig, usrs[-threshold:], action) assert msig.nonce() == 1
def test_repeat_signer(msig, usrs): signers = usrs.copy() signers.insert(1, signers[0]) action = Action(CallType.CALL) with brownie.reverts(): signAndExecute(msig, signers, action)
def test_two_calls(msig, usrs): signAndExecute(msig, usrs, Action(CallType.CALL)) signAndExecute(msig, usrs, Action(CallType.CALL)) assert msig.nonce() == 2
def test_fail_bad_signer(msig, usrs, any_signers): bad_usrs = usrs.copy() bad_usrs[C.THRESHOLD - 1] = any_signers[0] with brownie.reverts(): signAndExecute(msig, bad_usrs, Action(CallType.CALL))
def test_fail_insufficient_sigs(msig, usrs): action = Action(CallType.CALL) with brownie.reverts(): signAndExecute(msig, usrs[0:C.THRESHOLD - 1], action)
def test_fail_wrong_source(msig, deployer, anyone, usrs): action = Action(CallType.CALL, C.ZERO_ADDRESS, deployer.address) with brownie.reverts(): signAndExecute(msig, usrs, action, {'from': anyone})
def test_with_source(msig, deployer, usrs): action = Action(CallType.CALL, C.ZERO_ADDRESS, deployer.address) signAndExecute(msig, usrs, action, {'from': deployer})
def test_fail_bad_calltype(msig, usrs): with brownie.reverts(): signAndExecute(msig, usrs, Action(CallType.INVALID))
def test_dcall_empty_target(msig, usrs): action = Action(CallType.DELEGATECALL, C.ADDRESS_EMPTY, C.ZERO_ADDRESS, 3000, 0, '0xdeadbeefab') signAndExecute(msig, usrs, action) assert msig.nonce() == 1