diff --git a/.gitignore b/.gitignore index 29d52ea2..e3768675 100644 --- a/.gitignore +++ b/.gitignore @@ -75,6 +75,7 @@ registrar.json # Crowdsale definitions crowdsales/*.yml +crowdsales/*.py *.csv # Customer test cases diff --git a/ico/cmd/deploycontracts.py b/ico/cmd/deploycontracts.py index 7cc28ed0..0677a396 100644 --- a/ico/cmd/deploycontracts.py +++ b/ico/cmd/deploycontracts.py @@ -4,7 +4,7 @@ from populus import Project from ico.deploy import deploy_crowdsale_from_file - +from ico.git import git_sanitycheck @click.command() @click.option('--deployment-name', nargs=1, default="mainnet", help='YAML section name we are deploying. Usual options include "mainnet" or "kovan"', required=True) @@ -27,6 +27,8 @@ def main(deployment_file, deployment_name, address): * https://github.com/TokenMarketNet/ico/blob/master/crowdsales/example.yml """ + git_sanitycheck() + project = Project() deploy_crowdsale_from_file(project, deployment_file, deployment_name, address) print("All done! Enjoy your decentralized future.") diff --git a/ico/cmd/distributetokens.py b/ico/cmd/distributetokens.py index e863f686..186a620e 100644 --- a/ico/cmd/distributetokens.py +++ b/ico/cmd/distributetokens.py @@ -30,7 +30,8 @@ @click.option('--issuer-address', nargs=1, help='The address of the issuer contract - leave out for the first run to deploy a new issuer contract', required=False, default=None) @click.option('--master-address', nargs=1, help='The team multisig wallet address that does StandardToken.approve() for the issuer contract', required=False, default=None) @click.option('--allow-zero/--no-allow-zero', default=False, help='Stops the script if a zero amount row is encountered') -def main(chain, address, token, csv_file, limit, start_from, issuer_address, address_column, amount_column, allow_zero, master_address): +@click.option('--gas-price', nargs=1, help='Gas price for a transaction in Gweis', default=30) +def main(chain, address, token, csv_file, limit, start_from, issuer_address, address_column, amount_column, allow_zero, master_address, gas_price): """Distribute tokens to centrally issued crowdsale participant or bounty program participants. Reads in distribution data as CSV. Then uses Issuer contract to distribute tokens. @@ -77,7 +78,7 @@ def main(chain, address, token, csv_file, limit, start_from, issuer_address, add decimal_multiplier = 10**decimals - transaction = {"from": address} + transaction = {"from": address, "gasPrice": gas_price * 1000000000} Issuer = c.provider.get_base_contract_factory('Issuer') if not issuer_address: @@ -170,7 +171,7 @@ def main(chain, address, token, csv_file, limit, start_from, issuer_address, add transaction = { "from": address, - "gasPrice": int(web3.eth.gasPrice * 1.5) + "gasPrice": gas_price * 1000000000 } tokens = int(tokens) diff --git a/ico/deploy.py b/ico/deploy.py index 92c40620..aa28d306 100644 --- a/ico/deploy.py +++ b/ico/deploy.py @@ -286,5 +286,3 @@ def deploy_crowdsale_from_file(project: Project, yaml_filename: str, deployment_ with project.get_chain(chain_name) as chain: web3 = chain.web3 return _deploy_contracts(project, chain, web3, yaml_filename, chain_data, deploy_address) - - diff --git a/ico/etherscan.py b/ico/etherscan.py index 34e5c698..f3f03744 100644 --- a/ico/etherscan.py +++ b/ico/etherscan.py @@ -21,7 +21,7 @@ def _fill_in_textarea_value(browser, splinter_elem, value): -def verify_contract(project: Project, chain_name: str, address: str, contract_name, contract_filename: str, constructor_args: str, libraries: dict, optimization=True, optimizer_runs=200, compiler: str="v0.4.8+commit.60cc1668", browser_driver="chrome") -> str: +def verify_contract(project: Project, chain_name: str, address: str, contract_name, contract_filename: str, constructor_args: str, libraries: dict, optimization=True, optimizer_runs=200, compiler: str="v0.4.15+commit.bbb8e64f", browser_driver="chrome") -> str: """Semi-automated contract verified on Etherscan. Uses a web browser + Selenium auto fill to verify contracts. diff --git a/ico/git.py b/ico/git.py new file mode 100644 index 00000000..9da3f737 --- /dev/null +++ b/ico/git.py @@ -0,0 +1,41 @@ +from git import Repo +import os +import time + +join = os.path.join +repo = Repo(os.getcwd()) +assert not repo.bare + +repo.config_reader() + +def git_sanitycheck(): + git_ismaster() + git_isold() + git_isdirty() + +def git_isdirty(): + if repo.is_dirty(): + raise RuntimeError("The repository is not committed, won't continue. Please commit.") + + return + +def git_ismaster(): + # User can override git_isold checking for a week + if ((float(os.getenv("ICO_DEPLOY_ANYWAY", 0)) + 604800) > time.time()): + return True + + if (repo.active_branch.commit != repo.heads.master.commit): + raise RuntimeError("This branch is not 'master'. Please switch to master, or use the following command to postpone this check for a week:\nexport ICO_DEPLOY_ANYWAY=" + str(time.time())) + +def git_isold(): + git_root = repo.git.rev_parse("--show-toplevel") + latest_pull = os.stat(git_root + "/.git/FETCH_HEAD").st_mtime + deadline = latest_pull + 604800 # One week from latest commit + + if (time.time() > deadline): + raise RuntimeError("You haven't pulled for a week. Please do git pull.") + else: + return + +def git_current_commit(): + return repo.active_branch.commit diff --git a/ico/importexpand.py b/ico/importexpand.py index f9d2ccf7..9f191ed3 100644 --- a/ico/importexpand.py +++ b/ico/importexpand.py @@ -3,6 +3,7 @@ Mainly need for EtherScan verification service. """ import os +from ico.git import git_current_commit from typing import Tuple from populus import Project @@ -83,4 +84,6 @@ def expand_contract_imports(project: Project, contract_filename: str) -> Tuple[s :return: Tuple[final expanded source, set of processed filenames] """ exp = Expander(project) - return exp.expand_file(contract_filename), exp.processed_imports + commitline = "// (C) 2017 TokenMarket Ltd. (https://github.com/TokenMarketNet/ico/blob/master/LICENSE.txt) Commit: " + str(git_current_commit()) + "\n" + + return commitline + exp.expand_file(contract_filename), exp.processed_imports diff --git a/requirements.txt b/requirements.txt index 689735ff..45945698 100644 --- a/requirements.txt +++ b/requirements.txt @@ -10,6 +10,7 @@ eth-testrpc==1.3.0 ethereum==1.6.1 ethereum-abi-utils==0.4.0 ethereum-utils==0.3.2 +gitpython==2.1.7 idna==2.5 Jinja2==2.9.6 json-rpc==1.10.3