# Copyright 2017 OmiseGO Pte Ltd # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. import json import pytest from os import urandom from ethereum.tester import TransactionFailed from constants import BATCH_SIZE, DEAD, OMGTOKEN_CONTRACT_ABI, OMGTOKEN_CONTRACT_BYTECODE from utils import deploy_or_at LARGEST_AMOUNT = 322019907388210865601235 # largest amount for our setup @pytest.fixture() def token(chain): contract_class = chain.web3.eth.contract(abi=json.loads(OMGTOKEN_CONTRACT_ABI), bytecode=OMGTOKEN_CONTRACT_BYTECODE) return deploy_or_at(chain.web3, contract_class, None) @pytest.fixture() def airdropper(chain): ret, _ = chain.provider.get_or_deploy_contract('Airdropper') return ret @pytest.fixture() def minted_and_credited(token, airdropper, chain, accounts): txn_hash = token.transact().mint(accounts[0], BATCH_SIZE * LARGEST_AMOUNT) chain.wait.for_receipt(txn_hash) txn_hash = token.transact().transfer(airdropper.address, BATCH_SIZE * LARGEST_AMOUNT) chain.wait.for_receipt(txn_hash) def test_flow(token, airdropper, chain, accounts, minted_and_credited): txn_hash = airdropper.transact().multisend(token.address, accounts[1:2], [10]) chain.wait.for_receipt(txn_hash) # return to owner remainder = token.call().balanceOf(airdropper.address) txn_hash = airdropper.transact().multisend(token.address, [accounts[0]], [remainder]) chain.wait.for_receipt(txn_hash) assert token.call().balanceOf(accounts[0]) == BATCH_SIZE * LARGEST_AMOUNT - 10 assert token.call().balanceOf(accounts[1]) == 10 assert token.call().balanceOf(airdropper.address) == 0 def test_logs_on_multisend_sanity_check(token, airdropper, chain, accounts, minted_and_credited): filter = token.on('Transfer') filter.get() # flush events from setup txn_hash = airdropper.transact().multisend(token.address, accounts[1:3], [10, 20]) chain.wait.for_receipt(txn_hash) logs = filter.get() assert len(logs) == 2 def test_ownership(token, airdropper, accounts, minted_and_credited): with pytest.raises(TransactionFailed): airdropper.transact({'from': accounts[1]}).multisend(token.address, accounts[1:2], [10]) with pytest.raises(TransactionFailed): airdropper.transact({'from': accounts[1]}).transferOwnership(accounts[1]) # now make sure owner can do what non-owner shouldnt owner = airdropper.call().owner() assert owner == accounts[0] airdropper.transact({'from': owner}).multisend(token.address, accounts[1:2], [10]) airdropper.transact({'from': owner}).transferOwnership(accounts[1]) # new owner can act now airdropper.transact({'from': accounts[1]}).multisend(token.address, accounts[1:2], [10]) airdropper.transact({'from': accounts[1]}).transferOwnership(DEAD) # end state assert token.call().balanceOf(accounts[1]) == 20 def test_list_processing_and_cost(token, airdropper, chain, minted_and_credited): beneficiaries = [urandom(20) for _ in xrange(BATCH_SIZE)] txn_hash = airdropper.transact().multisend(token.address, beneficiaries, [LARGEST_AMOUNT] * len(beneficiaries)) peracc = chain.web3.eth.getTransactionReceipt(txn_hash)['gasUsed'] / len(beneficiaries) for account in beneficiaries: assert token.call().balanceOf(account) == LARGEST_AMOUNT assert peracc <= 33000 # golden number