diff --git a/ES_docs/BountynBonusSetup_Readme.md b/ES_docs/BountynBonusSetup_Readme.md new file mode 100644 index 00000000..b9a2891a --- /dev/null +++ b/ES_docs/BountynBonusSetup_Readme.md @@ -0,0 +1,188 @@ +# Introduction + +This document details the configuration and execution of bounty / bonus reward mechanism provided by the Token Market ICO tools. + +# Setup + +Perform the following activities on the Token Market ICO docker instance. + +1. Install Dependencies for Token Market ICO Bounty/Bonus tools + +``` +pip3 install splinter +apt-get install curl libnss3 +``` + +2. Install Chrome Driver + +``` +CHROME_DRIVER_VERSION=`curl -sS chromedriver.storage.googleapis.com/LATEST_RELEASE` +wget http://chromedriver.storage.googleapis.com/$CHROME_DRIVER_VERSION/chromedriver_linux64.zip +unzip chromedriver_linux64.zip +mv chromedriver /usr/local/bin +``` + +3. Install Chrome + +``` +sudo curl -sS -o - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add +sudo echo "deb http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google-chrome.list +sudo apt-get -y update +sudo apt-get -y install google-chrome-stable +``` + +4. Token Market does not detect the parameter local as an acceptable chain value so configure the mainnet chain in populus.json to refer to your local geth instance. + +``` + "chains": { + "mainnet": { + "chain": { + "class": "populus.chain.external.ExternalChain" + }, + "contracts": { + "backends": { + "JSONFile": { + "$ref": "contracts.backends.JSONFile" + }, + "Memory": { + "$ref": "contracts.backends.Memory" + }, + "ProjectContracts": { + "$ref": "contracts.backends.ProjectContracts" + }, + "TestContracts": { + "$ref": "contracts.backends.TestContracts" + } + } + }, + "web3": { + "provider": { + "class": "web3.providers.rpc.HTTPProvider", + "settings": { + "endpoint_uri": "http://172.21.0.1:8545", + "request_kwargs": { + "timeout": 180 + } + } + } + } + }, +``` + +5. Create a CSV file for example distribute.csv consisting of the list of Bounty/Bonus recieving addresses. Example below. + +``` +address,amount +0x77cA2e7E9AA9f0494560Ed0EAcBE1B1B90F9fcb6,10 +0xCA5eA7C6124D5Ea18C45f4664edd88EE0838D405,10 +``` + +6. Unlock the wallet which owns the Token Contract on the geth console and use it to publish the Issuer Contract too. + +``` +web3.personal.unlockAccount(web3.eth.accounts[0], "PASSWORD",36000); +``` + +7. Comment out the below in ico/cmd/distributetokens.py so it does not try to browse etherscan for verification. + + +``` + #verify_contract( + # project=project, + # libraries={}, # TODO: Figure out how to pass around + # chain_name=chain_name, + # address=issuer.address, + # contract_name="Issuer", + # contract_filename=fname, + # constructor_args=const_args, + # # libraries=runtime_data["contracts"][name]["libraries"], + # browser_driver=browser_driver, + # compiler=solc_version) + # link = get_etherscan_link(chain_name, issuer.address) + + # print("Issuer verified contract is", link) +``` + +# Execution / Testing + +1. Execute the Bounty/Bonus Tools for the first time. This will create an Issuer Contract. + + +``` +python3.5 ico/cmd/distributetokens.py --chain="mainnet" --gas-price="50" --address="0x41f32F70119E9dEEaD9681d371207cAE0b2C16F6" --master-address="0x41f32F70119E9dEEaD9681d371207cAE0b2C16F6" --token 0xbf0De463A0C543ed8e3941b04E02D48954f85CD9 --csv-file crowdsales/distribute.csv + +Web3 provider is RPC connection http://172.21.0.1:8545 +Deployer account address is 0x41f32F70119E9dEEaD9681d371207cAE0b2C16F6 +Deployer account balance is 33073.48 ETH +Token is 0xbf0de463a0c543ed8e3941b04e02d48954f85cd9 +Total supply is 100000000000000000000000000000 +Upgrade master is 0x41f32f70119e9deead9681d371207cae0b2c16f6 +Deployer account token balance is 100000000000000000000000000000 +Token decimal places is 18 +Using gas price of 50.0 GWei +Deploying new issuer contract ['0x41f32F70119E9dEEaD9681d371207cAE0b2C16F6', '0x41f32F70119E9dEEaD9681d371207cAE0b2C16F6', '0xbf0de463a0c543ed8e3941b04e02d48954f85cd9'] transaction parameters {'gasPrice': 50000000000, 'from': '0x41f32F70119E9dEEaD9681d371207cAE0b2C16F6'} +Deployment transaction is 0x2669b66caf8c49199efcb222ae21febc7056a669db298d2193c46f73ae18a8f0 +Waiting contract to be deployed +Contract constructor arguments are 00000000000000000000000041f32f70119e9deead9681d371207cae0b2c16f600000000000000000000000041f32f70119e9deead9681d371207cae0b2c16f6000000000000000000000000bf0de463a0c543ed8e3941b04e02d48954f85cd9 +Issuer contract is 0xea96aba2431a3a6831c6f8c07bebd39878745afd +Currently issued 0 +Issuer allowance 0 +Please use Token.approve() to give some allowance for the issuer contract by master address. + +``` + +2. Use the Token.approve function via Ethereumwallet or Remix to set the Issuer Contract Address as a spender and the amount of Tokens it can give out. Ensure the address approving is same as the specified master-address and also has enough tokens in it to distribute + +3. Rerun the Contract again to Distribute bounties to the addresses specified in the distribute.csv file. Ensure you specify the --issuer-address in this run. + +``` +python3.5 ico/cmd/distributetokens.py --chain="mainnet" --gas-price="50" --address="0x41f32F70119E9dEEaD9681d371207cAE0b2C16F6" --master-address="0x41f32F70119E9dEEaD9681d371207cAE0b2C16F6" --token 0xbf0De463A0C543ed8e3941b04E02D48954f85CD9 --issuer-address="0xea96aba2431a3a6831c6f8c07bebd39878745afd" --csv-file crowdsales/distribute.csv + +Web3 provider is RPC connection http://172.21.0.1:8545 +Deployer account address is 0x41f32F70119E9dEEaD9681d371207cAE0b2C16F6 +Deployer account balance is 33160.48 ETH +Token is 0xbf0de463a0c543ed8e3941b04e02d48954f85cd9 +Total supply is 100000000000000000000000000000 +Upgrade master is 0x41f32f70119e9deead9681d371207cae0b2c16f6 +Deployer account token balance is 100000000000000000000000000000 +Token decimal places is 18 +Using gas price of 50.0 GWei +Reusing existing issuer contract +Issuer contract is 0xea96aba2431a3a6831c6f8c07bebd39878745afd +Currently issued 0 +Issuer allowance 1000000000000000000000000 +Reading data crowdsales/distribute.csv +Total rows 2 +Row 0 giving 10000000000000000000 to 0x77cA2e7E9AA9f0494560Ed0EAcBE1B1B90F9fcb6 issuer 0xea96aba2431a3a6831c6f8c07bebd39878745afd time passed 0.0026755332946777344 ETH passed 0.00 gas price 50.0 +Row 1 giving 10000000000000000000 to 0xCA5eA7C6124D5Ea18C45f4664edd88EE0838D405 issuer 0xea96aba2431a3a6831c6f8c07bebd39878745afd time passed 0.010854959487915039 ETH passed 0.00 gas price 50.0 +Deployment cost is -3.00 ETH +All done! Enjoy your decentralized future. +``` + +4. Rerun the Contract again to ensure that an accidental rerun will not redistribute bounties. + +``` +python3.5 ico/cmd/distributetokens.py --chain="mainnet" --gas-price="50" --address="0x41f32F70119E9dEEaD9681d371207cAE0b2C16F6" --master-address="0x41f32F70119E9dEEaD9681d371207cAE0b2C16F6" --token 0xbf0De463A0C543ed8e3941b04E02D48954f85CD9 --issuer-address="0xea96aba2431a3a6831c6f8c07bebd39878745afd" --csv-file crowdsales/distribute.csv + +Web3 provider is RPC connection http://172.21.0.1:8545 +Deployer account address is 0x41f32F70119E9dEEaD9681d371207cAE0b2C16F6 +Deployer account balance is 33199.48 ETH +Token is 0xbf0de463a0c543ed8e3941b04e02d48954f85cd9 +Total supply is 100000000000000000000000000000 +Upgrade master is 0x41f32f70119e9deead9681d371207cae0b2c16f6 +Deployer account token balance is 99999999980000000000000000000 +Token decimal places is 18 +Using gas price of 50.0 GWei +Reusing existing issuer contract +Issuer contract is 0xea96aba2431a3a6831c6f8c07bebd39878745afd +Currently issued 20000000000000000000 +Issuer allowance 999980000000000000000000 +Reading data crowdsales/distribute.csv +Total rows 2 +Row 0 giving 10000000000000000000 to 0x77cA2e7E9AA9f0494560Ed0EAcBE1B1B90F9fcb6 issuer 0xea96aba2431a3a6831c6f8c07bebd39878745afd time passed 0.0030736923217773438 ETH passed 0.00 gas price 50.0 +Already issued, skipping +Row 1 giving 10000000000000000000 to 0xCA5eA7C6124D5Ea18C45f4664edd88EE0838D405 issuer 0xea96aba2431a3a6831c6f8c07bebd39878745afd time passed 0.008187055587768555 ETH passed 0.00 gas price 50.0 +Already issued, skipping +Deployment cost is 0.00 ETH +All done! Enjoy your decentralized future. +``` diff --git a/ES_docs/DevSetup_Readme.md b/ES_docs/DevSetup_Readme.md new file mode 100644 index 00000000..613a645f --- /dev/null +++ b/ES_docs/DevSetup_Readme.md @@ -0,0 +1,274 @@ +# Introduction + +This document details the setup of an ethereum development environment required to execute and troubleshoot TokenMarket ICO contracts. + +It utilizes the following components + +- Token Market ICO Git Hub Repo (https://github.com/TokenMarketNet/ico.git) +- Open Zeppelin Git Hub Repo (https://github.com/OpenZeppelin/zeppelin-solidity.git) +- Geth v1.8.3 (https://gethstore.blob.core.windows.net/builds/geth-linux-amd64-1.8.3-329ac18e.tar.gz) +- Ethereum Wallet v0.10.0 (https://github.com/ethereum/mist/releases/download/v0.10.0/Ethereum-Wallet-linux64-0-10-0.zip) +- Docker CE (Community Edition) + +Optional used for Troubleshooting +- remix.ethereum.org +- Remixd + + +# Environment Setup + +1. Install Docker + +``` + +sudo apt-get update +sudo apt-get install apt-transport-https ca-certificates curl software-properties-common +curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - +sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" +sudo apt-get update +sudo apt-get install docker-ce +sudo apt-get install docker-compose +sudo systemctl enable docker +sudo systemctl start docker +docker --version +Docker version 18.03.0-ce, build 0520e24 + +``` + +2. Obtain Token Market & (Zeppelin) Repo + +``` +mkdir ~/Projects +cd ~/Projects +git clone --recursive https://github.com/TokenMarketNet/ico.git + +``` + +3. Extract Geth + +``` +cd ~/Projects +tar -zxvf geth-linux-amd64-1.8.3-329ac18e.tar.gz +cd geth-linux-amd64-1.8.3-329ac18e + +``` + +4. Now start geth with the below command. Note : rpc related parameters are included so geth allows connections from Remix and TokenMarket. + +``` +./geth --dev --datadir=/home/toor/.ethereum/private --rpcapi "personal,web3,eth,net,db,debug" --rpc --rpcaddr "0.0.0.0" --rpccorsdomain "*" console' + +``` + +5. Install and Configure Ethereum Wallet to connect to your local Instance. + +``` +cd ~/Projects +unzip Ethereum-Wallet-linux64-0-10-0.zip +mv linux-unpacked etherwallet0.10.0 +cd etherwallet0.10.0 +./ethereumwallet --rpc ~/.ethereum/private/geth.ipc +``` + +# Working with TokenMarket ICO platform + +1. Switch over to a new terminal and start TokenMarket ICO docker instance. + +``` +cd ~/Projects/ico +docker-compose up & +docker exec -it tkn /bin/bash +``` + +2. To have Token Market ICO utilize your Local Chain once logged into the token market docker instance edit /usr/src/app/populus.json and set the endpoint_uri to your default gateway and port 8545. Note the default GW using the below command in the docker instance. + +``` +ip route +default via 172.21.0.1 dev eth0 +172.21.0.0/16 dev eth0 proto kernel scope link src 172.21.0.3 +``` + +3. Edit /usr/src/app/populus.json and replace the configuration for the local chain with the following for it to point to your geth instance. + + +``` + "local": { + "chain": { + "class": "populus.chain.external.ExternalChain" + }, + "contracts": { + "backends": { + "JSONFile": { + "$ref": "contracts.backends.JSONFile" + }, + "Memory": { + "$ref": "contracts.backends.Memory" + }, + "ProjectContracts": { + "$ref": "contracts.backends.ProjectContracts" + }, + "TestContracts": { + "$ref": "contracts.backends.TestContracts" + } + } + }, + "web3": { + "provider": { + "class": "web3.providers.rpc.HTTPProvider", + "settings": { + "endpoint_uri": "http://172.21.0.1:8545", + "request_kwargs": { + "timeout": 180 + } + } + } + } + }, + + + ``` + +4. Configure the parameter for the chain in the .yml you will be using to refer to your local chain. + +``` +local-token: + chain: local +``` + +5. Unlock your wallet (Incase you have set password for the Primary DEV account). + +Switch to your geth console and enter the following command with your password to unlock your wallet for the account you will be publishing the contract with. (in this case accounts[0]) + +``` +web3.personal.unlockAccount(web3.eth.accounts[0], "PASSWORD"); +``` + + +6. Test publishing a contract using Token Market ICO tools. + +``` +python3 ico/cmd/deploycontracts.py --deployment-file crowdsales/crowdsale-token-example.yml --deployment-name local-token --address 0x41f32F70119E9dEEaD9681d371207cAE0b2C16F6 + +Web3 provider is RPC connection http://172.21.0.1:8545 +Owner address is 0x41f32F70119E9dEEaD9681d371207cAE0b2C16F6 +Owner balance is 33437.49 ETH +Starting CrowdsaleToken deployment, with arguments {'_symbol': 'MOO', '_mintable': False, '_decimals': 18, '_initialSupply': 100000000000000000000000000000, '_name': 'MooToken'} +CrowdsaleToken address is 0x1455c31b25fa6fb20aa38edf6b1a09534355321f +CrowdsaleToken constructor arguments payload is 0x00000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000001431e0fae6d7217caa00000000000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000084d6f6f546f6b656e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000034d4f4f0000000000000000000000000000000000000000000000000000000000 +CrowdsaleToken libraries are {'SafeMathLib': '0x00d085562309d6e13ffe646c11ad5875a58aee62'} +Writing partial report crowdsales/crowdsale-token-example.partial-report.yml +Performing post-deployment contract actions +Action: # By default, our crowdsale token tranfers work only on whitelisted address. +Action: # (To prevent shadow markets during the token sale). +Action: # In post-actions we make token transferable. +Action: # Make owner to be address / contract that controls the release +Action: confirm_tx(token.transact({"from": deploy_address}).setReleaseAgent(deploy_address)) +Action: # Unlock token transfers +Action: confirm_tx(token.transact({"from": deploy_address}).releaseTokenTransfer()) +Performing deployment verification +Verification: # Token is now transferable +Verification: assert token.call().released() +Verification: # We deployed using coinbase account +Verification: # assert deploy_address == web3.eth.accounts[0] +Verification: # Check that the owner got all initial balance +Verification: # assert token.call().balanceOf(deploy_address) == 100000000000*10**18 +Deployment cost is -33.00 ETH +All done! Enjoy your decentralized future. +``` + +7. Note the address of the Token Contract and add it in your Ethereum Wallet using the Watch Token Option. In order to obtain the contract ABI/JSON and interact with it you can use remix. + + +# Setting up remix + +Remix allows you to obtain contract ABI's, troubleshoot for errors, debug transactions and test deployin parameters which will help you build the .yml files required by TokenMarket ICO python tools. + +1. Install remixd + +``` +sudo npm install -g remixd --unsafe-perm=true --allow-root +``` + +2. Configure remixd contracts directory. + + NOTE : + - When using remix with contracts that refer to zeppelin/ a prefix of localhost/ needs to be added to the path so remix.ethereum.org does not look at the Browser cache for the files but instead browses via the localhost to this location.(Refer to Known Issue #2 below in order to know the solution to rectify this). + + - Also remixd does not support symbolic links. Hence configure remix as follows + + +``` +cp ~/Projects/ico/contracts ~projects/remix.tm_contracts +cp -r ~/Projects/ico/zeppelin ~/projects/remix.tm_contracts/zeppelin + +``` + +3. Start remixd + +``` +remixd -s /home/username/projects/remix.tm_contracts + +[WARN] Any application that runs on your computer can potentially read from and write to all files in the directory. +[WARN] Symbolinc links are not forwarded to Remix IDE + +setup notifications for /home/toor/Projects/remix.tm_contracts +Shared folder : /home/toor/Projects/remix.tm_contracts +Tue Apr 10 2018 08:36:26 GMT+1000 (AEST) Remixd is listening on 127.0.0.1:65520 +origin http://remix.ethereum.org +Tue Apr 10 2018 08:36:30 GMT+1000 (AEST) Connection accepted. +setup notifications for /home/toor/Projects/remix.tm_contracts + +``` + +4. Configure remix to use your local geth instance. + + - Browse to http://remix.ethereum.org + - In the Right Pane Click on Run Tab + - Under Environment Select Web3 + - Specify http://localhost:8545 + - Click on Settings Tab + - Select Enable Personal Mode (This will allow you to enter passwords when accessing your local instance to publish contracts) + + +5. Configure remix to use your local remixd instance. + +- Browse to http://remix.ethereum.org +- In the Top Left Corner click on the button that looks like 2 chain links +- Accept the popup shown for connecting to your local remixd instance + +Directory hosted via remixd will now be available as localhost. + +A really handy tutorial of remix exists here for working with remix http://remix.readthedocs.io/en/latest/#tutorial + +# Known Issues and Workarounds + +1. Solidity Compiler Version. + +Some of the solidity contracts in open zeppelin refer to different versions of solidity compiler and since only v0.4.17 is installed as part of the TokenMarket Docker ICO tools , these need to be replaced with v0.4.17. You can also use the following command under the zeppelin/contracts directory to do so + +``` +cd zeppelin/contracts +find . -type f -exec sed -i 's/0.4.18/0.4.17/g' {} \; +``` + +2. Using Remix with Contracts that use non local directory path + +When using remix with contracts that refer to zeppelin/ a prefix of localhost/ needs to be added to the path so remix.ethereum.org does not look at the Browser cache for the files but instead browses via the localhost to this location. + +So For example change the below in solidity contracts where present from + +``` +import "zeppelin/contracts/ownership/Ownable.sol"; +``` + +to + +``` +import "localhost/zeppelin/contracts/ownership/Ownable.sol"; +``` + +you can also use the following commands in the contracts directory + +``` +find . -type f -exec sed -i 's/zeppelin/localhost\/zeppelin/g' {} \; +``` diff --git a/ES_docs/Upgradeable_Token.md b/ES_docs/Upgradeable_Token.md new file mode 100644 index 00000000..86d75a2e --- /dev/null +++ b/ES_docs/Upgradeable_Token.md @@ -0,0 +1,146 @@ +## Introduction + +Every so often there are issues in code that requires fixing and while fixing code in traditional environments is straight forward , how does one fix code on an immutable non reversible ledger such as the blockchain ? + +In this session we look at how a token contract can be upgraded on ethereum, also while exploring this feature we will look into some of the other features of advance token contracts such as transfer locking and releasing. + + +## Pre-Requisites. + +1. Clone the following repo to obtain necessary sample contracts. + +``` +git clone https://github.com/dpnova/goldcoast-blockchain-meetup.git +``` + +2. Logon to https://remix.ethereum.org in your browser + +3. Open the Contracts from the Meetup_7/contracts directory + +NOTE : The contract's have been obtained from https://github.com/TokenMarketNet/ico and flattened for ease of use using https://github.com/BlockCatIO/solidity-flattener . Contract UpgradedToken_flat.sol is a copy of TestMigrationAgent.sol with modifications to the contract name. + +![](images/UT/3.png) + +## Deploy Initial token + +4. Click on the Contract BurnableCrowdsaleToken_flat.sol + +5. Click on the run tab and for Environment select Javascript VM. You can also choose Injected Web3 if you would like to use Metamask or web3 provider if you would like to interact with a custom chain such as a local geth or ganache node. + +![](images/UT/5.png) + +6. From Dropdown select BurnableCrowdsaleToken and expand the Deploy section by clickin the down arrow. + +![](images/UT/6.png) + +7. Enter the following parameters and click Transact + +_name : MyToken +_symbol : MT1 +_initialSupply : 1000000000000000000000000 NOTE : That is 24 X 0's , which makes it 1 Million tokens followed by 18 decimal places. +_decimals : 18 +_mintable : true + +![](images/UT/7.png) + +8. Your Token contract will be deployed and available for interaction under Deployed Contracts. Expand it and click on Can Upgrade , it should return false. Next click on getUpgradeState it should return 1 + +![](images/UT/8.png) + +NOTE : When tokens are initially created often token issuers might choose to lock the transfer of tokens untill a certain event such as Exchange Listing or product go live before allowing tokens to be transferred. So before we can do the below steps we need to ensure tokens are transferrable. +1 + +9. Copy the Token contract publisher account address by clickin the copy button next to account. + +10. Paste the address in SetReleaseAgent and click on SetReleaseAgent. + +![](images/UT/10.png) + +11. Click on releaseTokenTransfer. This will remove the Transfer locking on the tokens and now holders of the token can transfer the token's between each other. + +![](images/UT/11.png) + +12. Now click on getUpgradeState and it should return 2. + +13. Next we will publish the contract to which we want to upgrade the existing tokens to. + +## Deploy Token to be upgraded to. + +14. Click on UpgradedToken_flat.sol and click on the compile tabe and click Start to Compile. + +![](images/UT/14.png) + +15. Click on Run tab and from the dropdown select UpgradedToken + +![](images/UT/15.png) + +16. Copy the address of the previously published token. This needs to be provided as an input to our UpgradedToken contract so it can determine the total supply of the existing tokens in the contract to be upgraded. + +17. Paste it in the filed address_oldToken and click Deploy + +18. Expand the newly published UpgradedToken contract and click on OriginalSupply. This should match the TotalSupply of the previously published Token Contract. + +![](images/UT/18.png) + +## Upgrading the token. + +19. Copy the Address of the UpgradedToken contract and paste it in setUpgradeAgent function field for the BurnableCrowdsaleToken and click on setUpgradeAgent. + +NOTE : In case your contract functions cease to respond , this is a remix GUI bug. Note the contract address and reload it for interaction by specifying it as follows. + +![](images/UT/19.png) + + +20. Clickin on canUpgrade should now return true and getUpgradeState should return 3. Token holders can call the upgrade function now to Upgrade Tokens. + +![](images/UT/20.png) + +21. Enter the number of tokens you wish to upgrade and click on Upgrade. For example enter 50000000000000000000 as per below. + +![](images/UT/21.png) + +22. Click totalSupply for BurnableCrowdsaleToken it should show that the total number of tokens in supply for BurnableCrowdsaleToken has decreased by 50000000000000000000 + +![](images/UT/22.png) + +23. Click totalSupply for UpgradedToken and it will show 50000000000000000000 tokens in supply. The old tokens have been destroyed and an equvivalent number of new tokens have been issued. + +![](images/UT/23.png) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ES_docs/images/UT/10.png b/ES_docs/images/UT/10.png new file mode 100644 index 00000000..5377a28b Binary files /dev/null and b/ES_docs/images/UT/10.png differ diff --git a/ES_docs/images/UT/11.png b/ES_docs/images/UT/11.png new file mode 100644 index 00000000..d04dcc4f Binary files /dev/null and b/ES_docs/images/UT/11.png differ diff --git a/ES_docs/images/UT/14.png b/ES_docs/images/UT/14.png new file mode 100644 index 00000000..ff523f9f Binary files /dev/null and b/ES_docs/images/UT/14.png differ diff --git a/ES_docs/images/UT/15.png b/ES_docs/images/UT/15.png new file mode 100644 index 00000000..3801503d Binary files /dev/null and b/ES_docs/images/UT/15.png differ diff --git a/ES_docs/images/UT/18.png b/ES_docs/images/UT/18.png new file mode 100644 index 00000000..14f0adb0 Binary files /dev/null and b/ES_docs/images/UT/18.png differ diff --git a/ES_docs/images/UT/19.png b/ES_docs/images/UT/19.png new file mode 100644 index 00000000..4b6b6bf6 Binary files /dev/null and b/ES_docs/images/UT/19.png differ diff --git a/ES_docs/images/UT/20.png b/ES_docs/images/UT/20.png new file mode 100644 index 00000000..d98f0a3e Binary files /dev/null and b/ES_docs/images/UT/20.png differ diff --git a/ES_docs/images/UT/21.png b/ES_docs/images/UT/21.png new file mode 100644 index 00000000..1cd747e6 Binary files /dev/null and b/ES_docs/images/UT/21.png differ diff --git a/ES_docs/images/UT/22.png b/ES_docs/images/UT/22.png new file mode 100644 index 00000000..4c157404 Binary files /dev/null and b/ES_docs/images/UT/22.png differ diff --git a/ES_docs/images/UT/23.png b/ES_docs/images/UT/23.png new file mode 100644 index 00000000..b7b08eea Binary files /dev/null and b/ES_docs/images/UT/23.png differ diff --git a/ES_docs/images/UT/3.png b/ES_docs/images/UT/3.png new file mode 100644 index 00000000..da58efaa Binary files /dev/null and b/ES_docs/images/UT/3.png differ diff --git a/ES_docs/images/UT/5.png b/ES_docs/images/UT/5.png new file mode 100644 index 00000000..da61b060 Binary files /dev/null and b/ES_docs/images/UT/5.png differ diff --git a/ES_docs/images/UT/6.png b/ES_docs/images/UT/6.png new file mode 100644 index 00000000..740e1c54 Binary files /dev/null and b/ES_docs/images/UT/6.png differ diff --git a/ES_docs/images/UT/7.png b/ES_docs/images/UT/7.png new file mode 100644 index 00000000..6f330112 Binary files /dev/null and b/ES_docs/images/UT/7.png differ diff --git a/ES_docs/images/UT/8.png b/ES_docs/images/UT/8.png new file mode 100644 index 00000000..e4aef88a Binary files /dev/null and b/ES_docs/images/UT/8.png differ diff --git a/ES_docs/images/UT/NOTE.png b/ES_docs/images/UT/NOTE.png new file mode 100644 index 00000000..8869e415 Binary files /dev/null and b/ES_docs/images/UT/NOTE.png differ diff --git a/contracts/Crowdsale.sol b/contracts/Crowdsale.sol index ecec53e5..081d35c1 100644 --- a/contracts/Crowdsale.sol +++ b/contracts/Crowdsale.sol @@ -162,4 +162,11 @@ contract Crowdsale is CrowdsaleBase { InvestmentPolicyChanged(requireCustomerId, requiredSignedAddress, signerAddress); } + + /** Default function to allow for Sending Ether to contract and Recieving Tokens */ + + function () public payable { + invest(msg.sender); + } + } diff --git a/contracts/CrowdsaleBase.sol b/contracts/CrowdsaleBase.sol index 0bb8bf0e..00c6a668 100644 --- a/contracts/CrowdsaleBase.sol +++ b/contracts/CrowdsaleBase.sol @@ -10,7 +10,7 @@ import "./SafeMathLib.sol"; import "./FractionalERC20.sol"; import "./PricingStrategy.sol"; import "./FinalizeAgent.sol"; - +import "zeppelin/contracts/ownership/Whitelist.sol"; /** * Crowdsale state machine without buy functionality. @@ -21,7 +21,7 @@ import "./FinalizeAgent.sol"; * * For the default buy() implementation see Crowdsale.sol. */ -contract CrowdsaleBase is Haltable { +contract CrowdsaleBase is Haltable, Whitelist { /* Max investment count when we are still allowed to change the multisig address */ uint public MAX_INVESTMENTS_BEFORE_MULTISIG_CHANGE = 5; @@ -144,10 +144,11 @@ contract CrowdsaleBase is Haltable { /** * Don't expect to just send in money and get tokens. + * + * function() payable { + * throw; + * } */ - function() payable { - throw; - } /** * Make an investment. @@ -162,6 +163,18 @@ contract CrowdsaleBase is Haltable { */ function investInternal(address receiver, uint128 customerId) stopInEmergency internal returns(uint tokensBought) { + // Determine reciever address is Whitelisted or not. + // require(whitelist[msg.sender]); + // require(whitelist[receiver]); + + // Define address of a pre-deployed Whitelist Contract and call the whitelist function on the contract to verify msg.sender and receiver + Whitelist dc; + address contract_addr = 0x062e41d1037745dc203e8c1AAcA651B8d157Da96; + dc = Whitelist(contract_addr); + require (dc.whitelist(msg.sender)); + require (dc.whitelist(receiver)); + + // Determine if it's a good time to accept investment from this participant if(getState() == State.PreFunding) { // Are we whitelisted for early deposit @@ -177,7 +190,8 @@ contract CrowdsaleBase is Haltable { } uint weiAmount = msg.value; - + require(weiAmount >= minimumFundingGoal); + // Account presale sales separately, so that they do not count against pricing tranches uint tokenAmount = pricingStrategy.calculatePrice(weiAmount, weiRaised - presaleWeiRaised, tokensSold, msg.sender, token.decimals()); diff --git a/crowdsales/CRCM_TSE.yml b/crowdsales/CRCM_TSE.yml new file mode 100644 index 00000000..3615a34c --- /dev/null +++ b/crowdsales/CRCM_TSE.yml @@ -0,0 +1,183 @@ +# python3 ico/cmd/deploycontracts.py --deployment-file crowdsales/CRCM_TSE.yml --deployment-name CRCM-token --address 0x3A514B826d8235DfBFc7e67F9D7F6173E9C109Ed + +# This is the deployment-name parameter. +CRCM-token: + + # This is the chain name in populus.json + chain: mainnet + + # Use automated Chrome to verify all contracts on etherscan.io + verify_on_etherscan: no + browser_driver: chrome + + solc: + + # This is the Solidity version tag we verify on EtherScan. + version: v0.4.14+commit.c2215d46 + + + # We supply these to EtherScan as the solc settings we used to compile the contract. + # They must match values in populus.json compilication / backends section. + + optimizations: + optimizer: true + runs: 500 + + contracts: + + # These are the addresses of the multisig wallets . Ensure below is set to ES team's mainnet wallet 0x46cf3064b571bfb48367182764c5e5d2e02e3733 before deploying to mainnet + + team_multisig: + contract_name: MultiSigWallet + contract_file: GnosisWallet.sol + address: "0x46cf3064b571bfb48367182764c5e5d2e02e3733" + + # Token contract + + token: + contract_name: BurnableCrowdsaleToken + contract_file: BurnableCrowdsaleToken.sol + arguments: + _name: "Circum" + _symbol: "CRCM" + _initialSupply: 0 + _decimals: 18 + _mintable: true + + + # Pricing Strategy in Wei, which is the smallest unit of ether. 1 ETH = 10^18 Wei + # ETH priced at 600 USD, 85% bonus tier. Price per token 0.0015 USD + + pricing_strategy1: + contract_name: FlatPricing + contract_file: FlatPricing.sol + arguments: + _oneTokenInWei: 2500000000000 + + # Private Sale @ USD 0.0015 , 200000000 Tokens Minimum Buyin 83.33 ETH + + crowdsale1: + contract_name: MintedTokenCappedCrowdsale + contract_file: MintedTokenCappedCrowdsale.sol + arguments: + _token: "{{contracts.token.address}}" + _pricingStrategy: "{{contracts.pricing_strategy1.address}}" + _multisigWallet: "{{contracts.team_multisig.address}}" + _start: "{{ timestamp(datetime(2018, 7, 02, 00, 00)) }}" + _end: "{{ timestamp(datetime(2018, 8, 31, 23, 59)) }}" + _minimumFundingGoal: "{{ to_wei(83.33, 'ether') }}" + _maximumSellableTokens: "{{ to_wei(200000000, 'ether') }}" + + # ETH priced at 600 USD, 50% bonus tier. Price per token 0.005 USD + + pricing_strategy2: + contract_name: FlatPricing + contract_file: FlatPricing.sol + arguments: + _oneTokenInWei: 8333333333333 + + + # Private Sale @ USD 0.005 , 275000000 Tokens Tokens Minimum Buyin 83.33 ETH + + crowdsale2: + contract_name: MintedTokenCappedCrowdsale + contract_file: MintedTokenCappedCrowdsale.sol + arguments: + _token: "{{contracts.token.address}}" + _pricingStrategy: "{{contracts.pricing_strategy2.address}}" + _multisigWallet: "{{contracts.team_multisig.address}}" + _start: "{{ timestamp(datetime(2018, 7, 02, 00, 00)) }}" + _end: "{{ timestamp(datetime(2018, 8, 31, 23, 59)) }}" + _minimumFundingGoal: "{{ to_wei(83.33, 'ether') }}" + _maximumSellableTokens: "{{ to_wei(275000000, 'ether') }}" + + # ETH priced at 600 USD, 50% bonus tier. Price per token 0.005 USD + + pricing_strategy3: + contract_name: FlatPricing + contract_file: FlatPricing.sol + arguments: + _oneTokenInWei: 8333333333333 + + + # Internal Test Sale @ USD 0.005 , 50000 Tokens Tokens No Minimum Buyin Test + + crowdsale3: + contract_name: MintedTokenCappedCrowdsale + contract_file: MintedTokenCappedCrowdsale.sol + arguments: + _token: "{{contracts.token.address}}" + _pricingStrategy: "{{contracts.pricing_strategy3.address}}" + _multisigWallet: "{{contracts.team_multisig.address}}" + _start: "{{ timestamp(datetime(2018, 7, 02, 00, 00)) }}" + _end: "{{ timestamp(datetime(2018, 8, 31, 23, 59)) }}" + _minimumFundingGoal: 1 + _maximumSellableTokens: "{{ to_wei(50000, 'ether') }}" + + # Dont do anything after crowdsale ends. Bonus distribution and token release will be handled + + finalize_agent1: + contract_name: NullFinalizeAgent + contract_file: NullFinalizeAgent.sol + arguments: + _crowdsale: "{{contracts.crowdsale1.address}}" + + finalize_agent2: + contract_name: NullFinalizeAgent + contract_file: NullFinalizeAgent.sol + arguments: + _crowdsale: "{{contracts.crowdsale2.address}}" + + finalize_agent3: + contract_name: NullFinalizeAgent + contract_file: NullFinalizeAgent.sol + arguments: + _crowdsale: "{{contracts.crowdsale3.address}}" + + # Post-deployment actions to connect contracts together. + post_actions: | + + # Make sure crowdsale contract and these accounts can transfer tokens despite transfer lock up + token.transact({"from": deploy_address}).setTransferAgent(team_multisig.address, True) + token.transact({"from": deploy_address}).setTransferAgent(crowdsale1.address, True) + token.transact({"from": deploy_address}).setTransferAgent(crowdsale2.address, True) + token.transact({"from": deploy_address}).setTransferAgent(crowdsale3.address, True) + + # Owner can release the token transfer when they feel its time + token.transact({"from": deploy_address}).setReleaseAgent(team_multisig.address) + + # Do not do nothing at the end of the crowdsale + crowdsale1.transact({"from": deploy_address}).setFinalizeAgent(finalize_agent1.address) + crowdsale2.transact({"from": deploy_address}).setFinalizeAgent(finalize_agent2.address) + crowdsale3.transact({"from": deploy_address}).setFinalizeAgent(finalize_agent3.address) + + # Enable new token minting by a crowdsale contract + confirm_tx(token.transact({"from": deploy_address}).setMintAgent(crowdsale1.address, True)) + confirm_tx(token.transact({"from": deploy_address}).setMintAgent(crowdsale2.address, True)) + confirm_tx(token.transact({"from": deploy_address}).setMintAgent(crowdsale3.address, True)) + + # Do a test buy using a test address. (Ensure value is >= minimumFundingGoal) + crowdsale1.transact({"from": deploy_address, "value": to_wei("83.33", "ether")}).buy() + crowdsale2.transact({"from": deploy_address, "value": to_wei("83.33", "ether")}).buy() + crowdsale3.transact({"from": deploy_address, "value": to_wei("0.01", "ether")}).buy() + + # Set Crowdsale owner as team_multisig + crowdsale1.transact({"from": deploy_address}).transferOwnership(team_multisig.address) + crowdsale2.transact({"from": deploy_address}).transferOwnership(team_multisig.address) + crowdsale3.transact({"from": deploy_address}).transferOwnership(team_multisig.address) + + # Set token owner to team multisig + token.transact({"from": deploy_address}).transferOwnership(team_multisig.address) + token.transact({"from": deploy_address}).setUpgradeMaster(team_multisig.address) + + # Sanity check + verify_actions: | + + assert crowdsale1.call().owner() == team_multisig.address + assert crowdsale2.call().owner() == team_multisig.address + assert crowdsale3.call().owner() == team_multisig.address + assert token.call().owner() == team_multisig.address + assert finalize_agent1.call().isSane() + assert finalize_agent2.call().isSane() + assert finalize_agent3.call().isSane() + diff --git a/crowdsales/YPB_INTERNAL.yml b/crowdsales/YPB_INTERNAL.yml new file mode 100644 index 00000000..7a865845 --- /dev/null +++ b/crowdsales/YPB_INTERNAL.yml @@ -0,0 +1,113 @@ +# python3 ico/cmd/deploycontracts.py --deployment-file crowdsales/YPB_INTERNAL.yml --deployment-name YPB-token --address 0x3a514b826d8235dfbfc7e67f9d7f6173e9c109ed + +# This is the deployment-name parameter. +YPB-token: + + # This is the chain name in populus.json + chain: mainnet + + # Use automated Chrome to verify all contracts on etherscan.io + verify_on_etherscan: no + browser_driver: chrome + + solc: + + # This is the Solidity version tag we verify on EtherScan. + version: v0.4.14+commit.c2215d46 + + # + # We supply these to EtherScan as the solc settings we used to compile the contract. + # They must match values in populus.json compilication / backends section. + # + optimizations: + optimizer: true + runs: 500 + + contracts: + + # These are the addresses of the multisig wallets . + + team_multisig: + contract_name: MultiSigWallet + contract_file: GnosisWallet.sol + address: "0x46cf3064b571bfb48367182764c5e5d2e02e3733" + + # Token contract + + token: + contract_name: BurnableCrowdsaleToken + contract_file: BurnableCrowdsaleToken.sol + address: "0xabae4f83df4f4f79422c8f1e5953d75df39aa477" + # arguments: + # _name: "YPB" + # _symbol: "YPB" + # _initialSupply: 0 + # _decimals: 18 + # _mintable: true + + + # Pricing Strategy in Wei, which is the smallest unit of ether. 1 ETH = 10^18 Wei + # ETH priced at 800 USD, 50% bonus tier. Price per token 0.05 USD + + pricing_strategy: + contract_name: FlatPricing + contract_file: FlatPricing.sol + arguments: + _oneTokenInWei: 62500000000000 + + + # Private Sale. 8 Jun to 9 Aug 2018 + # _minimumFundingGoal is leveraged to also be the minimum contribution amount + + crowdsale: + contract_name: MintedTokenCappedCrowdsale + contract_file: MintedTokenCappedCrowdsale.sol + arguments: + _token: "{{contracts.token.address}}" + _pricingStrategy: "{{contracts.pricing_strategy.address}}" + _multisigWallet: "{{contracts.team_multisig.address}}" + _start: "{{ timestamp(datetime(2018, 6, 8, 00, 00)) }}" + _end: "{{ timestamp(datetime(2018, 8, 8, 23, 59)) }}" + _minimumFundingGoal: 1 + _maximumSellableTokens: "{{ to_wei(5000, 'ether') }}" + + finalize_agent: + contract_name: NullFinalizeAgent + contract_file: NullFinalizeAgent.sol + arguments: + _crowdsale: "{{contracts.crowdsale.address}}" + + # Post-deployment actions connect contracts together. + post_actions: | + + + # Make sure crowdsale contract and these accounts can transfer tokens despite transfer lock up + token.transact({"from": deploy_address}).setTransferAgent(team_multisig.address, True) + token.transact({"from": deploy_address}).setTransferAgent(crowdsale.address, True) + + # Do not do nothing at the end of the crowdsale + crowdsale.transact({"from": deploy_address}).setFinalizeAgent(finalize_agent.address) + + # Owner can release the token transfer when they feel its time + token.transact({"from": deploy_address}).setReleaseAgent(team_multisig.address) + + # Set token owner to team multisig + token.transact({"from": deploy_address}).transferOwnership(team_multisig.address) + token.transact({"from": deploy_address}).setUpgradeMaster(team_multisig.address) + + # Set Crowdsale owner to team multisig but not if you will be adding whitelist addresses later. + crowdsale.transact({"from": deploy_address}).transferOwnership(team_multisig.address) + + # Enable new token minting by a crowdsale contract (If deploy address does not own Token then do this step manually using remix/etherwallet) + confirm_tx(token.transact({"from": deploy_address}).setMintAgent(crowdsale.address, True)) + + # Do a test buy using a test address. + crowdsale.transact({"from": deploy_address, "value": to_wei("0.00001", "ether")}).buy() + + + # Sanity check + verify_actions: | + + # assert crowdsale.call().owner() == team_multisig.address + assert finalize_agent.call().isSane() + diff --git a/crowdsales/YPB_PRIVATE.yml b/crowdsales/YPB_PRIVATE.yml new file mode 100644 index 00000000..c9b50218 --- /dev/null +++ b/crowdsales/YPB_PRIVATE.yml @@ -0,0 +1,108 @@ +# python3 ico/cmd/deploycontracts.py --deployment-file crowdsales/YPB_PRIVATE.yml --deployment-name YPB-token --address 0x3a514b826d8235dfbfc7e67f9d7f6173e9c109ed + +# This is the deployment-name parameter. +YPB-token: + + # This is the chain name in populus.json + chain: mainnet + + # Use automated Chrome to verify all contracts on etherscan.io + verify_on_etherscan: no + browser_driver: chrome + + solc: + + # This is the Solidity version tag we verify on EtherScan. + version: v0.4.14+commit.c2215d46 + + # + # We supply these to EtherScan as the solc settings we used to compile the contract. + # They must match values in populus.json compilication / backends section. + # + optimizations: + optimizer: true + runs: 500 + + contracts: + + # These are the addresses of the multisig wallets . + + team_multisig: + contract_name: MultiSigWallet + contract_file: GnosisWallet.sol + address: "0x46cf3064b571bfb48367182764c5e5d2e02e3733" + + # Token contract + + token: + contract_name: BurnableCrowdsaleToken + contract_file: BurnableCrowdsaleToken.sol + arguments: + _name: "YPB" + _symbol: "YPB" + _initialSupply: 0 + _decimals: 18 + _mintable: true + + + # Pricing Strategy in Wei, which is the smallest unit of ether. 1 ETH = 10^18 Wei + # ETH priced at 800 USD, 50% bonus tier. Price per token 0.05 USD + + pricing_strategy: + contract_name: FlatPricing + contract_file: FlatPricing.sol + arguments: + _oneTokenInWei: 62500000000000 + + + # Private Sale. 8 Jun to 9 Aug 2018 + # _minimumFundingGoal is leveraged to also be the minimum contribution amount + + crowdsale: + contract_name: MintedTokenCappedCrowdsale + contract_file: MintedTokenCappedCrowdsale.sol + arguments: + _token: "{{contracts.token.address}}" + _pricingStrategy: "{{contracts.pricing_strategy.address}}" + _multisigWallet: "{{contracts.team_multisig.address}}" + _start: "{{ timestamp(datetime(2018, 6, 8, 00, 00)) }}" + _end: "{{ timestamp(datetime(2018, 8, 8, 23, 59)) }}" + _minimumFundingGoal: "{{ to_wei(62.5, 'ether') }}" + _maximumSellableTokens: "{{ to_wei(60000000, 'ether') }}" + + finalize_agent: + contract_name: NullFinalizeAgent + contract_file: NullFinalizeAgent.sol + arguments: + _crowdsale: "{{contracts.crowdsale.address}}" + + # Post-deployment actions to connect contracts together. + post_actions: | + + + # Make sure crowdsale contract and these accounts can transfer tokens despite transfer lock up + token.transact({"from": deploy_address}).setTransferAgent(team_multisig.address, True) + token.transact({"from": deploy_address}).setTransferAgent(crowdsale.address, True) + + # Do not do nothing at the end of the crowdsale + crowdsale.transact({"from": deploy_address}).setFinalizeAgent(finalize_agent.address) + + # Owner can release the token transfer when they feel its time + token.transact({"from": deploy_address}).setReleaseAgent(team_multisig.address) + + # Set Crowdsale owneer as team_multisig + crowdsale.transact({"from": deploy_address}).transferOwnership(team_multisig.address) + + # Enable new token minting by a crowdsale contract + confirm_tx(token.transact({"from": deploy_address}).setMintAgent(crowdsale.address, True)) + + # Do a test buy using a test address. (Ensure value is >= minimumFundingGoal) + # crowdsale.transact({"from": deploy_address, "value": to_wei("0.001", "ether")}).buy() + + + # Sanity check + verify_actions: | + + assert crowdsale.call().owner() == team_multisig.address + assert finalize_agent.call().isSane() + diff --git a/crowdsales/YPB_UPDATES.yml b/crowdsales/YPB_UPDATES.yml new file mode 100644 index 00000000..1de76850 --- /dev/null +++ b/crowdsales/YPB_UPDATES.yml @@ -0,0 +1,135 @@ +# python3 ico/cmd/deploycontracts.py --deployment-file crowdsales/YPB_UPDATES.yml --deployment-name YPB-token --address 0x3A514B826d8235DfBFc7e67F9D7F6173E9C109Ed + +# This is the deployment-name parameter. +YPB-token: + + # This is the chain name in populus.json + chain: mainnet + + # Use automated Chrome to verify all contracts on etherscan.io + verify_on_etherscan: no + browser_driver: chrome + + solc: + + # This is the Solidity version tag we verify on EtherScan. + version: v0.4.14+commit.c2215d46 + + # + # We supply these to EtherScan as the solc settings we used to compile the contract. + # They must match values in populus.json compilication / backends section. + # + optimizations: + optimizer: true + runs: 500 + + contracts: + + # These are the addresses of the multisig wallets . + + team_multisig: + contract_name: MultiSigWallet + contract_file: GnosisWallet.sol + address: "0x46cf3064b571bfb48367182764c5e5d2e02e3733" + + # Token contract ,using existing YPB Token address + + token: + contract_name: BurnableCrowdsaleToken + contract_file: BurnableCrowdsaleToken.sol + address: "0xabae4f83df4f4f79422c8f1e5953d75df39aa477" + # arguments: + # _name: "YPB" + # _symbol: "YPB" + # _initialSupply: 0 + # _decimals: 18 + # _mintable: true + + + # Pricing Strategy in Wei, which is the smallest unit of ether. 1 ETH = 10^18 Wei + # ETH priced at 600 USD, 50% bonus tier. Price per token 0.05 USD + + pricing_strategy: + contract_name: FlatPricing + contract_file: FlatPricing.sol + arguments: + _oneTokenInWei: 83333333333333 + + # Crowdsale Contracts Below. + # _minimumFundingGoal is leveraged to also be the minimum contribution amount + + # Internal Test Sale. 2 Jul to 31 Aug 2018 + + crowdsale1: + contract_name: MintedTokenCappedCrowdsale + contract_file: MintedTokenCappedCrowdsale.sol + arguments: + _token: "{{contracts.token.address}}" + _pricingStrategy: "{{contracts.pricing_strategy.address}}" + _multisigWallet: "{{contracts.team_multisig.address}}" + _start: "{{ timestamp(datetime(2018, 7, 02, 00, 00)) }}" + _end: "{{ timestamp(datetime(2018, 8, 31, 23, 59)) }}" + _minimumFundingGoal: 1 + _maximumSellableTokens: "{{ to_wei(5000, 'ether') }}" + + # Private Sale. 2 Jul to 31 Aug 2018 + + crowdsale2: + contract_name: MintedTokenCappedCrowdsale + contract_file: MintedTokenCappedCrowdsale.sol + arguments: + _token: "{{contracts.token.address}}" + _pricingStrategy: "{{contracts.pricing_strategy.address}}" + _multisigWallet: "{{contracts.team_multisig.address}}" + _start: "{{ timestamp(datetime(2018, 7, 02, 00, 00)) }}" + _end: "{{ timestamp(datetime(2018, 8, 31, 23, 59)) }}" + _minimumFundingGoal: "{{ to_wei(83.33, 'ether') }}" + _maximumSellableTokens: "{{ to_wei(60000000, 'ether') }}" + + + finalize_agent1: + contract_name: NullFinalizeAgent + contract_file: NullFinalizeAgent.sol + arguments: + _crowdsale: "{{contracts.crowdsale1.address}}" + + finalize_agent2: + contract_name: NullFinalizeAgent + contract_file: NullFinalizeAgent.sol + arguments: + _crowdsale: "{{contracts.crowdsale2.address}}" + + # Post-deployment actions connect contracts together. + post_actions: | + + + # Do nothing at the end of the crowdsale, i.e. releasing tokens & bonus distribution will be handled manually later. + crowdsale1.transact({"from": deploy_address}).setFinalizeAgent(finalize_agent1.address) + crowdsale2.transact({"from": deploy_address}).setFinalizeAgent(finalize_agent2.address) + + # Set Crowdsale owneer as team_multisig + crowdsale1.transact({"from": deploy_address}).transferOwnership(team_multisig.address) + crowdsale2.transact({"from": deploy_address}).transferOwnership(team_multisig.address) + + # Below transactions need to be done after token ownership is transferred to the deploy wallet via gnosis. + + # 1. Make sure crowdsale contract and these accounts can transfer tokens despite transfer lock up + token.transact({"from": deploy_address}).setTransferAgent(crowdsale1.address, True) + token.transact({"from": deploy_address}).setTransferAgent(crowdsale2.address, True) + + # 2. Enable new token minting by a crowdsale contract (If deploy address does not own Token then do this step manually using remix/etherwallet) + token.transact({"from": deploy_address}).setMintAgent(crowdsale1.address, True) + token.transact({"from": deploy_address}).setMintAgent(crowdsale2.address, True) + + # 3. Do a test buy using a test address. + crowdsale1.transact({"from": deploy_address, "value": to_wei("0.01", "ether")}).buy() + crowdsale2.transact({"from": deploy_address, "value": to_wei("83.33", "ether")}).buy() + + + # Sanity check + verify_actions: | + + assert crowdsale1.call().owner() == team_multisig.address + assert crowdsale2.call().owner() == team_multisig.address + assert finalize_agent1.call().isSane() + assert finalize_agent2.call().isSane() \ No newline at end of file diff --git a/crowdsales/allocated-token-sale-acceptance-test.yml b/crowdsales/allocated-token-sale-acceptance-test.yml deleted file mode 100644 index 1af80678..00000000 --- a/crowdsales/allocated-token-sale-acceptance-test.yml +++ /dev/null @@ -1,181 +0,0 @@ -# Used in test_deploy_acceptance.py, corresponding to allocated-token-sale-example.yml -# -# Please note that some numbers are slightly changed. -# - -testrpc: - - chain: testrpc - - # Use automated Chrome to verify all contracts on etherscan.io - verify_on_etherscan: no - browser_driver: chrome - - solc: - - # This is the Solidity version tag we verify on EtherScan. - # For available versions see - # https://kovan.etherscan.io/verifyContract2 - # - # See values in Compiler drop down. - # You can also get the local compiler version with: - # - # solc --version - # - # Note that for EtherScan you need to add letter "v" at the front of the version - # - # Note: You need to have correct optmization settings for the compiler - # in populus.json that matches what EtherScan is expecting. - # - version: v0.4.14+commit.c2215d46 - - # - # We supply these to EtherScan as the solc settings we used to compile the contract. - # They must match values in populus.json compilication / backends section. - # - optimizations: - optimizer: true - runs: 500 - - contracts: - # This is the address of the multisig wallet where the paymnts eventually land - team_multisig: - contract_name: MultiSigWallet - contract_file: GnosisWallet.sol - address: "0x40a05d4ce308bf600cb275d7a3e9113518f59c54" - # - # Token contract - # - # This contract represents ERC-20 token. - # It has transfer lock up functionality to prevent the token to be transferable - # until the ICO is over. - # - # We create the whole token supply upfront and no more token minting - # happens ever. - # - # Token has 18 decimals and supply of 1B tokens. - # - # Token supply is one billion tokens. - # - # Name and symbol are not set yet. They are set later. In - # the case of the deployment fails and we need redeploy - # we do not create unnecessary entries in token explorers. - # - token: - contract_name: BurnableCrowdsaleToken - contract_file: BurnableCrowdsaleToken.sol - arguments: - _name: "" - _symbol: "" - _initialSupply: "{{ 200000000*10**18 }}" - _decimals: 18 - _mintable: false - # - # Pricing strategy. - # - # We use ETH tranches. People who buy in in the first - # tranches get 20% and 10% bonus tokens. - # - pricing_strategy: - contract_name: EthTranchePricing - contract_file: EthTranchePricing.sol - arguments: - _tranches: - # 400 tokens per ETH - - 0 - - 2500000000000000 - - # 366 tokens per ETH - - "{{ to_wei('18750', 'ether') }}" - - 2727272727272730 - - # 333 tokens per ETH - - "{{ to_wei('39204.54545', 'ether') }}" - - 3000000000000000 - - # 333 tokens per ETH - - "{{ to_wei('62454.54545', 'ether') }}" - - 3000000000000000 - - - "{{ to_wei('9999999999', 'ether') }}" - - 0 - - # - # Crowdsale. - # - # We use allocated crowdsale as the whole token supply has been created beforehand. - # No minting. Later we use approve() to give tokens for this contract to be sold. - # - crowdsale: - contract_name: AllocatedCrowdsale - contract_file: AllocatedCrowdsale.sol - arguments: - _token: "{{contracts.token.address}}" - _pricingStrategy: "{{contracts.pricing_strategy.address}}" - _multisigWallet: "{{contracts.team_multisig.address}}" - _start: "{{ timestamp(datetime(2099, 7, 12, 13, 00)) }}" - _end: "{{ timestamp(datetime(2099, 7, 26, 13, 00)) }}" - _minimumFundingGoal: "{{ to_wei(1, 'ether') }}" - _beneficiary: "{{deploy_address}}" - # - # Because deploy_address controls whole supply, - # we do not create any supply dynamically, - # we do not need a finalizer. - # - finalize_agent: - contract_name: NullFinalizeAgent - contract_file: NullFinalizeAgent.sol - arguments: - _crowdsale: "{{contracts.crowdsale.address}}" - - # Post-deployment actions connect contracts together. - post_actions: | - - # Allow crowdsale contract to sell its token - token.transact({"from": deploy_address}).approve(crowdsale.address, 70000000*(10**18)) - - # Make sure crowdsale contract and these accounts - # can transfer tokens despite transfer lock up - token.transact({"from": deploy_address}).setTransferAgent(team_multisig.address, True) - token.transact({"from": deploy_address}).setTransferAgent(crowdsale.address, True) - token.transact({"from": deploy_address}).setTransferAgent(finalize_agent.address, True) - token.transact({"from": deploy_address}).setTransferAgent(deploy_address, True) - - # Do not do nothing at the end of the crowdsale - confirm_tx(crowdsale.transact({"from": deploy_address}).setFinalizeAgent(finalize_agent.address)) - - # Owner can release the token transfer when they fel its the time - confirm_tx(token.transact({"from": deploy_address}).setReleaseAgent(deploy_address)) - - # Set token upgrade master to team multisig to give the new token path - confirm_tx(token.transact({"from": deploy_address}).setUpgradeMaster(team_multisig.address)) - - # Allow test buys from these accounts before token sale begins. - # The latter one is a presale contract address. - # Presale contract (PreICOProxyBuyer) can move in funds - # and get tokens before the actual start time. - confirm_multiple_txs( \ - crowdsale.transact({"from": deploy_address}).setEarlyParicipantWhitelist(deploy_address, True), \ - crowdsale.transact({"from": deploy_address}).setEarlyParicipantWhitelist("0x6d997eDcA04282950416FA380d834f360fC36eBb", True) \ - ) - - # We set a special price, outside ETH tranches, for a presale contract - confirm_tx(pricing_strategy.transact({"from": deploy_address}).setPreicoAddress("0x6d997eDcA04282950416FA380d834f360fC36eBb", 2083333333333)) - - # Sanity check - verify_actions: | - assert token.call().owner().lower() == deploy_address.lower() - assert token.call().released() == False - assert crowdsale.call().owner().lower() == deploy_address.lower() - assert crowdsale.call().multisigWallet().lower() == team_multisig.address.lower() - assert finalize_agent.call().isSane() - assert crowdsale.call().getState() == CrowdsaleState.PreFunding # PreFunding for the final, as it is deployed pre-opening - - # Do a test buy using a test address. - # This ensures are variables are set and the - # funds flow in the multisig wallet. - confirm_tx(crowdsale.transact({"from": deploy_address, "value": to_wei("0.01", "ether")}).buy()) - - # As the last action, after successful deployment, set the right token symbol and name so that it shows in a blockchain explorer - confirm_tx(token.transact({"from": deploy_address}).setTokenInformation("MooToken", "MOO")) - diff --git a/crowdsales/allocated-token-sale-example.yml b/crowdsales/allocated-token-sale-example.yml deleted file mode 100644 index 6b4a9ff4..00000000 --- a/crowdsales/allocated-token-sale-example.yml +++ /dev/null @@ -1,209 +0,0 @@ -# This is an example for an allocated token sale example. -# -# Token supply is fixed and is created prior to sale. Then tokens are -# transfefred to sale participants by the token sale contract using -# EIP-20 approve() mechanism. -# -# -# To deploy this file -# -# deploy-contracts \ -# --address=[my deploy account address account on geth having some Kovan ETH] \ยจ -# --deployment-file=crowdsales/allocated-token-sale-example.yml \ -# --deployment-name=kovan -# - - - -# This is the deployment-name parameter. -# We can have multiple deployments in a single YAML file. -kovan: - - # This is the chain name in populus.json - # In the default configuration this Ethereum JSON-RPC in port 8547. - # Edit populus.json to change the port. - # You can run Parity as: - # parity \ - # --chain=kovan \ - # --unlock [My deploy account on Parity] \ - # --jsonrpc-port 8547 \ - # --password=password.txt - # - # password.txt must contain your Parity Kovan account unlock password - chain: kovan - - # Use automated Chrome to verify all contracts on etherscan.io - verify_on_etherscan: yes - browser_driver: chrome - - solc: - - # This is the Solidity version tag we verify on EtherScan. - # For available versions see - # https://kovan.etherscan.io/verifyContract2 - # - # See values in Compiler drop down. - # You can also get the local compiler version with: - # - # solc --version - # - # Note that for EtherScan you need to add letter "v" at the front of the version - # - # Note: You need to have correct optmization settings for the compiler - # in populus.json that matches what EtherScan is expecting. - # - version: v0.4.14+commit.c2215d46 - - # - # We supply these to EtherScan as the solc settings we used to compile the contract. - # They must match values in populus.json compilication / backends section. - # - optimizations: - optimizer: true - runs: 500 - - contracts: - # This is the address of the multisig wallet where the paymnts eventually land - team_multisig: - contract_name: MultiSigWallet - contract_file: GnosisWallet.sol - address: "0x40a05d4ce308bf600cb275d7a3e9113518f59c54" - # - # Token contract - # - # This contract represents ERC-20 token. - # It has transfer lock up functionality to prevent the token to be transferable - # until the ICO is over. - # - # We create the whole token supply upfront and no more token minting - # happens ever. - # - # Token has 18 decimals and supply of 1B tokens. - # - # Token supply is one billion tokens. - # - # Name and symbol are not set yet. They are set later. In - # the case of the deployment fails and we need redeploy - # we do not create unnecessary entries in token explorers. - # - token: - contract_name: BurnableCrowdsaleToken - contract_file: BurnableCrowdsaleToken.sol - arguments: - _name: "" - _symbol: "" - _initialSupply: "{{ 100000000000*10**18 }}" - _decimals: 18 - _mintable: false - # - # Pricing strategy. - # - # We use ETH tranches. People who buy in in the first - # tranches get 20% and 10% bonus tokens. - # - pricing_strategy: - contract_name: EthTranchePricing - contract_file: EthTranchePricing.sol - arguments: - _tranches: - # This trance starts instantly. - # How many weis one token costs. 20% bonus tier. - # Price is base_price / 1.2 - - 0 - - 2272727272727 - - # This trance starts when we have sold 45k worth of tokens. - # Token price is 10% bonus tokens (base price / 1.1) - - "{{ to_wei('45000.00', 'ether') }}" - - 2380952380952 - - # This is the base price that is effective until the token - # sale ends. - - "{{ to_wei('90000.00', 'ether') }}" - - 2500000000000 - - # Dummy milestone marker to mark the end - # of the array. - - "{{ to_wei('999999999999999', 'ether') }}" - - 0 - - - # - # Crowdsale. - # - # We use allocated crowdsale as the whole token supply has been created beforehand. - # No minting. Later we use approve() to give tokens for this contract to be sold. - # - crowdsale: - contract_name: AllocatedCrowdsale - contract_file: AllocatedCrowdsale.sol - arguments: - _token: "{{contracts.token.address}}" - _pricingStrategy: "{{contracts.pricing_strategy.address}}" - _multisigWallet: "{{contracts.team_multisig.address}}" - _start: "{{ timestamp(datetime(2099, 7, 12, 13, 00)) }}" - _end: "{{ timestamp(datetime(2099, 7, 26, 13, 00)) }}" - _minimumFundingGoal: "{{ to_wei(15000, 'ether') }}" - _beneficiary: "{{deploy_address}}" - # - # Because deploy_address controls whole supply, - # we do not create any supply dynamically, - # we do not need a finalizer. - # - finalize_agent: - contract_name: NullFinalizeAgent - contract_file: NullFinalizeAgent.sol - arguments: - _crowdsale: "{{contracts.crowdsale.address}}" - - # Post-deployment actions connect contracts together. - post_actions: | - - # Allow crowdsale contract to sell its token - token.transact({"from": deploy_address}).approve(crowdsale.address, 70000000000*10**18) - - # Make sure crowdsale contract and these accounts - # can transfer tokens despite transfer lock up - token.transact({"from": deploy_address}).setTransferAgent(team_multisig.address, True) - token.transact({"from": deploy_address}).setTransferAgent(crowdsale.address, True) - token.transact({"from": deploy_address}).setTransferAgent(finalize_agent.address, True) - token.transact({"from": deploy_address}).setTransferAgent(deploy_address, True) - - # Do not do nothing at the end of the crowdsale - confirm_tx(crowdsale.transact({"from": deploy_address}).setFinalizeAgent(finalize_agent.address)) - - # Owner can release the token transfer when they fel its the time - confirm_tx(token.transact({"from": deploy_address}).setReleaseAgent(deploy_address)) - - # Set token upgrade master to team multisig to give the new token path - confirm_tx(token.transact({"from": deploy_address}).setUpgradeMaster(team_multisig.address)) - - # Allow test buys from these accounts before token sale begins. - # The latter one is a presale contract address. - # Presale contract (PreICOProxyBuyer) can move in funds - # and get tokens before the actual start time. - confirm_multiple_txs( \ - crowdsale.transact({"from": deploy_address}).setEarlyParicipantWhitelist(deploy_address, True), \ - crowdsale.transact({"from": deploy_address}).setEarlyParicipantWhitelist("0x6d997eDcA04282950416FA380d834f360fC36eBb", True) \ - ) - - # We set a special price, outside ETH tranches, for a presale contract - confirm_tx(pricing_strategy.transact({"from": deploy_address}).setPreicoAddress("0x6d997eDcA04282950416FA380d834f360fC36eBb", 2083333333333)) - - # Sanity check - verify_actions: | - assert token.call().owner().lower() == deploy_address.lower() - assert token.call().released() == False - assert crowdsale.call().owner().lower() == deploy_address.lower() - assert crowdsale.call().multisigWallet().lower() == team_multisig.address.lower() - assert finalize_agent.call().isSane() - assert crowdsale.call().getState() == CrowdsaleState.PreFunding # PreFunding for the final, as it is deployed pre-opening - - # Do a test buy using a test address. - # This ensures are variables are set and the - # funds flow in the multisig wallet. - confirm_tx(crowdsale.transact({"from": deploy_address, "value": to_wei("0.01", "ether")}).buy()) - - # As the last action, after successful deployment, set the right token symbol and name so that it shows in a blockchain explorer - confirm_tx(token.transact({"from": deploy_address}).setTokenInformation("MooToken", "MOO")) - diff --git a/crowdsales/crowdsale-token-example-ganache.yml b/crowdsales/crowdsale-token-example-ganache.yml deleted file mode 100644 index becd8c79..00000000 --- a/crowdsales/crowdsale-token-example-ganache.yml +++ /dev/null @@ -1,73 +0,0 @@ -# This is an example for deploying a crowdsale compatible EIP-20 token on a private testnet. -# -# First start a transient local Ethereum chain using populus and geth: -# -# populus chain run local -# -# This will start a private chain running geth in port 8548. The -# first launch might be slow as it has to generate 1 GB DAG file. -# Leave populus + geth running on the background. -# -# Then in another terminal you can run a command to deploy this token script: -# -# deploy-contracts --address=coinbase --deployment-file=crowdsales/crowdsale-token-example.yml --deployment-name=local-token -# -# This will deploy a new token using the default coinbase account -# on the local chain. Running the command takes ~60 seconds. -# -# You can find it your coinbase account (account 0) by doing: -# -# geth attach http://localhost:8548 -# -# > eth.accounts -# ["0xce90d9e5024e97f3123999aae6a1c395bb3c2013"] -# - -# This is the deployment-name parameter. -# We can have multiple deployments in a single YAML file. -local-token: - - # This is the chain name in populus.json - chain: ganache - - # We cannot verify the contract on EtherScan, because EtherScan only supports public nets - verify_on_etherscan: no - - contracts: - - # This deploys CrowdsaleToken contract. - # This contract is a superset of EIP-20 token - # with added metadata, upgrade and release functionality. - token: - contract_name: CrowdsaleToken - contract_file: CrowdsaleToken.sol - arguments: - _name: "MooToken" - _symbol: "MOO" - _initialSupply: "{{ 100000000000*10**18 }}" - _decimals: 18 # Standardish decimals for EIP-20 tokens - _mintable: false - - # No special post-deployment transactions needed - post_actions: | - # By default, our crowdsale token tranfers work only on whitelisted address. - # (To prevent shadow markets during the token sale). - # In post-actions we make token transferable. - - # Make owner to be address / contract that controls the release - confirm_tx(token.transact({"from": deploy_address}).setReleaseAgent(deploy_address)) - - # Unlock token transfers - confirm_tx(token.transact({"from": deploy_address}).releaseTokenTransfer()) - - # Verify that we have correctly deployed the contract - verify_actions: | - - # Token is now transferable - assert token.call().released() - - # We deployed using coinbase account - assert deploy_address == web3.eth.accounts[0] - - # Check that the owner got all initial balance - assert token.call().balanceOf(deploy_address) == 100000000000*10**18 diff --git a/crowdsales/crowdsale-token-example.yml b/crowdsales/crowdsale-token-example.yml deleted file mode 100644 index 4770e12c..00000000 --- a/crowdsales/crowdsale-token-example.yml +++ /dev/null @@ -1,74 +0,0 @@ -# This is an example for deploying a crowdsale compatible EIP-20 token on a private testnet. -# -# First start a transient local Ethereum chain using populus and geth: -# -# populus chain run local -# -# This will start a private chain running geth in port 8548. The -# first launch might be slow as it has to generate 1 GB DAG file. -# Leave populus + geth running on the background. -# -# Then in another terminal you can run a command to deploy this token script: -# -# deploy-contracts --address=coinbase --deployment-file=crowdsales/crowdsale-token-example.yml --deployment-name=local-token -# -# This will deploy a new token using the default coinbase account -# on the local chain. Running the command takes ~60 seconds. -# -# You can find it your coinbase account (account 0) by doing: -# -# geth attach http://localhost:8548 -# -# > eth.accounts -# ["0xce90d9e5024e97f3123999aae6a1c395bb3c2013"] -# - -# This is the deployment-name parameter. -# We can have multiple deployments in a single YAML file. -local-token: - - # This is the chain name in populus.json - chain: local - - # We cannot verify the contract on EtherScan, because EtherScan only supports public nets - verify_on_etherscan: no - - contracts: - - # This deploys CrowdsaleToken contract. - # This contract is a superset of EIP-20 token - # with added metadata, upgrade and release functionality. - token: - contract_name: CrowdsaleToken - contract_file: CrowdsaleToken.sol - arguments: - _name: "MooToken" - _symbol: "MOO" - _initialSupply: "{{ 100000000000*10**18 }}" - _decimals: 18 # Standardish decimals for EIP-20 tokens - _mintable: false - - # No special post-deployment transactions needed - post_actions: | - # By default, our crowdsale token tranfers work only on whitelisted address. - # (To prevent shadow markets during the token sale). - # In post-actions we make token transferable. - - # Make owner to be address / contract that controls the release - confirm_tx(token.transact({"from": deploy_address}).setReleaseAgent(deploy_address)) - - # Unlock token transfers - confirm_tx(token.transact({"from": deploy_address}).releaseTokenTransfer()) - - # Verify that we have correctly deployed the contract - verify_actions: | - - # Token is now transferable - assert token.call().released() - - # We deployed using coinbase account - assert deploy_address == web3.eth.accounts[0] - - # Check that the owner got all initial balance - assert token.call().balanceOf(deploy_address) == 100000000000*10**18 - diff --git a/crowdsales/example.yml b/crowdsales/example.yml deleted file mode 100644 index 9f15f18f..00000000 --- a/crowdsales/example.yml +++ /dev/null @@ -1,193 +0,0 @@ -# A testnet deployment for the crowdsale contracts -testnet: - - # Chain we are connected to. - # Either "mainnet" or "ropsten". - # Affects Etherscan verification process only. - chain: ropsten - - # Do we perform deployed contract source code verification on etherscan.io service. - # This is a semi automatic process using a Firefox browser. - verify_on_etherscan: yes - - solc: - - # This is the Solidity version tag we verify on EtherScan. - # For available versions see - # https://kovan.etherscan.io/verifyContract2 - # - # See values in Compiler drop down. - # You can also get the local compiler version with: - # - # solc --version - # - # Note that for EtherScan you need to add letter "v" at the front of the version - # - # Note: You need to have correct optmization settings for the compiler - # in populus.json that matches what EtherScan is expecting. - # - version: v0.4.14+commit.c2215d46 - - # - # We supply these to EtherScan as the solc settings we used to compile the contract. - # They must match values in populus.json compilication / backends section. - # - optimizations: - optimizer: true - runs: 500 - - # - # Contracts section defines different smart contracts that - # are required to run the ICO. - # - contracts: - - # Team multisignature wallet. - # - # Replace with your predeployed multisignature wallet contract address. - # - # We assume this wallet has been deployed beforehand - # using wallet.gnosis.pm service and your team members - # have been set as the owners of this wallet. - # - # For testing purposes, e.g. on Kovan network, - # you can use any account on your geth / Parity here. - # - # Note: As the writing of this wallet.gnosis.pm service - # works only with mainnet. - # - team_multisig: - contract_name: MultiSigWallet - contract_file: GnosisWallet.sol - address: "0x40a05d4ce308bf600cb275d7a3e9113518f59c54" - # - # Pre-ICO fund collector - # - # Pre-ICO contract allows high volume investors to place their - # Pre-ICO has a minimum buy in defined as volume. - # Pre-ICO investments have a preferred pricing (see later). - # - # Pre-ICO owner (team multisig) can set the ICO contract address - # later, it does not have to be availalble at the start of the ICO. - # After the ICO contract is set, anyone can trigger the moving of funds - # to the ICO contract. - # - # If the actual ICO does not happen, the investors can claim refund - # after freezeEndsAt date. - # - preico: - contract_name: PresaleFundCollector - contract_file: PresaleFundCollector.sol - arguments: - _owner: "{{contracts.team_multisig.address}}" - # Set 30 days in the future from the moment of deployment - _freezeEndsAt: "{{ time() + 30*24*3600 }}" - _weiMinimumLimit: "{{ to_wei(750, 'ether') }}" - # - # Token contract - # - # This contract represents ERC-20 token. - # It has transfer lock up functionality to prevent the token to be transferable - # until the ICO is over. Furthermore it has dynamic minting supply, - # so that the crowdsale contract will create new tokens as investment arrives in. - # This way, there is no need for a separate burn stage at the end of the crowdsale, - # as we never create the exceeding supply. - # - # - token: - contract_name: CrowdsaleToken - contract_file: CrowdsaleToken.sol - arguments: - _name: Example-testnet - _symbol: EXA - _initialSupply: 0 - _decimals: 18 # Ethereum tokens are standardizing around 18 decimals - _mintable: true # Tokens will be dynamically created over the token sale - # - # Pricing strategy - # - # Pricing strategy defines the price of a token in the different stages of the crowdsale. - # Here we use milestone based pricing that has a different price for the token every week of the crowdale. - # - # We also give a preferred price for pre-ICO investors. - # - # - pricing_strategy: - contract_name: MilestonePricing - contract_file: MilestonePricing.sol - arguments: - _preicoPrice: "{{ to_wei('0.008', 'ether') }}" - _preicoContractAddress: "{{contracts.preico.address}}" - _milestones: - - 1492272000 - - "{{ to_wei('0.010', 'ether') }}" - - 1492876800 - - "{{ to_wei('0.011', 'ether') }}" - - 1493481600 - - "{{ to_wei('0.012', 'ether') }}" - - 1494691200 - - "{{ to_wei('0.013', 'ether') }}" - # - # Crowdsale - # - # This is the actual crowdsale contract. - # It will accept investments during the crowdsale time period. - # For each investments, it asks the pricing contract for the - # current price for this particular investor. - # - # - # - crowdsale: - contract_name: MintedTokenCappedCrowdsale - contract_file: MintedTokenCappedCrowdsale.sol - arguments: - _token: "{{contracts.token.address}}" - _pricingStrategy: "{{contracts.pricing_strategy.address}}" - _multisigWallet: "{{contracts.team_multisig.address}}" - _start: "{{ timestamp(datetime(2017, 4, 15, 16, 0)) }}" - _end: "{{ timestamp(datetime(2017, 4, 15, 16, 0)) + 30*24*3600 }}" - _minimumFundingGoal: 7500 - _maximumSellableTokens: 4000000 - # - # Finalize contract - # - # Finalize contract defines what happens at the end of the successful crowdsale. - # - # The bonus finalize agent we define here 1) makes tokens transferable by releasing - # the transfer restrictions 2) mints 25% new tokens for the team to be - # reserved for founders, bounties and such. These new tokens are deposited in the - # team multisig wallet. - # - finalize_agent: - contract_name: BonusFinalizeAgent - contract_file: BonusFinalizeAgent.sol - arguments: - _token: "{{contracts.token.address}}" - _crowdsale: "{{contracts.crowdsale.address}}" - _bonusBasePoints: 2500 - _teamMultisig: "{{contracts.team_multisig.address}}" - - # Post-deployment actions connect contracts together. - # They set ownership and allowed actions, so that contracts can interact - post_actions: | - # Enable new token minting by a crowdsale contract - token.transact({"from": deploy_address}).setMintAgent(crowdsale.address, True) - - # Set actions what happen at the end of the crodsale. - # Enable token mintint at the end of the crowdsale to create bonus pool, founder pool and such - token.transact({"from": deploy_address}).setMintAgent(finalize_agent.address, True) - crowdsale.transact({"from": deploy_address}).setFinalizeAgent(finalize_agent.address) - token.transact({"from": deploy_address}).setReleaseAgent(finalize_agent.address) - - # Set the team multisig address as the upgraade master for the token - token.transact({"from": deploy_address}).transferOwnership(team_multisig.address) - - # Make sure that everything we have deployed all contracts in good state - # and their internal state is sane - verify_actions: | - assert token.call().owner() == team_multisig.address - assert crowdsale.call().owner() == team_multisig.address - assert preico.call().owner() == team_multisig.address - assert finalize_agent.call().teamMultisig() == team_multisig.address - assert finalize_agent.call().isSane() - assert crowdsale.call().getState() == CrowdsaleState.PreFunding diff --git a/crowdsales/unit-test.yml b/crowdsales/unit-test.yml deleted file mode 100644 index ff6a6120..00000000 --- a/crowdsales/unit-test.yml +++ /dev/null @@ -1,201 +0,0 @@ -# A stressed out deployment script -unit_test: - - # Chain we are connected to. - # Either "mainnet" or "ropsten". - # Affects Etherscan verification process only. - chain: ropsten - # Do we perform deployed contract source code verification on etherscan.io service. - # This is a semi automatic process using a Firefox browser. - verify_on_etherscan: no - - solc: - - # This is the Solidity version tag we verify on EtherScan. - # For available versions see - # https://kovan.etherscan.io/verifyContract2 - # - # See values in Compiler drop down. - # You can also get the local compiler version with: - # - # solc --version - # - # Note that for EtherScan you need to add letter "v" at the front of the version - # - # Note: You need to have correct optmization settings for the compiler - # in populus.json that matches what EtherScan is expecting. - # - version: v0.4.14+commit.c2215d46 - - # - # We supply these to EtherScan as the solc settings we used to compile the contract. - # They must match values in populus.json compilication / backends section. - # - optimizations: - optimizer: true - runs: 500 - - # - # Contracts section defines different smart contracts that - # are required to run the ICO. - # - contracts: - - # Team multisignature wallet. - # - # This contract deploys the team multisignature wallet. - # One we use here is based one by Gavin Wood. - # - # Multiple escrow key holders are required to take action to move - # funds around. - # - # All crowdsale collected funds are deposited to the this multisig wallet in real time. - # - team_multisig: - contract_name: MultiSigWallet - contract_file: GnosisWallet.sol - address: "0x40a05d4ce308bf600cb275d7a3e9113518f59c54" - # - # Pre-ICO fund collector - # - # Pre-ICO contract allows high volume investors to place their - # Pre-ICO has a minimum buy in defined as volume. - # Pre-ICO investments have a preferred pricing (see later). - # - # Pre-ICO owner (team multisig) can set the ICO contract address - # later, it does not have to be availalble at the start of the ICO. - # After the ICO contract is set, anyone can trigger the moving of funds - # to the ICO contract. - # - # If the actual ICO does not happen, the investors can claim refund - # after freezeEndsAt date. - # - preico: - contract_name: PresaleFundCollector - contract_file: PresaleFundCollector.sol - arguments: - _owner: "{{contracts.team_multisig.address}}" - # Set 30 days in the future from the moment of deployment - _freezeEndsAt: "{{ time() + 30*24*3600 }}" - _weiMinimumLimit: "{{ to_wei(750, 'ether') }}" - # - # Token contract - # - # This contract represents ERC-20 token. - # It has transfer lock up functionality to prevent the token to be transferable - # until the ICO is over. Furthermore it has dynamic minting supply, - # so that the crowdsale contract will create new tokens as investment arrives in. - # This way, there is no need for a separate burn stage at the end of the crowdsale, - # as we never create the exceeding supply. - # - # - token: - contract_name: CrowdsaleToken - contract_file: CrowdsaleToken.sol - arguments: - _name: Example-testnet - _symbol: EXA - _initialSupply: 0 - _decimals: 0 - _mintable: True - # - # Pricing strategy - # - # Pricing strategy defines the price of a token in the different stages of the crowdsale. - # Here we use milestone based pricing that has a different price for the token every week of the crowdale. - # - # We also give a preferred price for pre-ICO investors. - # - # - pricing_strategy: - contract_name: MilestonePricing - contract_file: MilestonePricing.sol - arguments: - _milestones: - - 1492272000 - - "{{ to_wei('0.010', 'ether') }}" - - 1492876800 - - "{{ to_wei('0.011', 'ether') }}" - - 1493481600 - - "{{ to_wei('0.012', 'ether') }}" - - 1494691200 - - "{{ to_wei('0.013', 'ether') }}" - - 1494864000 - - 0 - # - # Crowdsale - # - # This is the actual crowdsale contract. - # It will accept investments during the crowdsale time period. - # For each investments, it asks the pricing contract for the - # current price for this particular investor. - # - # - # - crowdsale: - contract_name: MintedTokenCappedCrowdsale - contract_file: MintedTokenCappedCrowdsale.sol - arguments: - _token: "{{contracts.token.address}}" - _pricingStrategy: "{{contracts.pricing_strategy.address}}" - _multisigWallet: "{{contracts.team_multisig.address}}" - _start: "{{ timestamp(datetime(2017, 4, 15, 16, 0)) }}" - _end: "{{ timestamp(datetime(2017, 4, 15, 16, 0)) + 30*24*3600 }}" - _minimumFundingGoal: 7500 - _maximumSellableTokens: 4000000 - # - # Finalize contract - # - # Finalize contract defines what happens at the end of the successful crowdsale. - # - # The bonus finalize agent we define here 1) makes tokens transferable by releasing - # the transfer restrictions 2) mints 25% new tokens for the team to be - # reserved for founders, bounties and such. These new tokens are deposited in the - # team multisig wallet. - # - finalize_agent: - contract_name: BonusFinalizeAgent - contract_file: BonusFinalizeAgent.sol - arguments: - _token: "{{contracts.token.address}}" - _crowdsale: "{{contracts.crowdsale.address}}" - _bonusBasePoints: 2500 - _teamMultisig: "{{contracts.team_multisig.address}}" - - # Post-deployment actions connect contracts together. - # They set ownership and allowed actions, so that contracts can interact - post_actions: | - # Enable new token minting by a crowdsale contract - confirm_tx(token.transact({"from": deploy_address}).setMintAgent(crowdsale.address, True)) - - # Set actions what happen at the end of the crodsale. - # Enable token mintint at the end of the crowdsale to create bonus pool, founder pool and such - confirm_tx(token.transact({"from": deploy_address}).setMintAgent(finalize_agent.address, True)) - confirm_tx(crowdsale.transact({"from": deploy_address}).setFinalizeAgent(finalize_agent.address)) - confirm_tx(token.transact({"from": deploy_address}).setReleaseAgent(finalize_agent.address)) - - # Move ownership of all owned contracts to the team multisig address - confirm_tx(crowdsale.transact({"from": deploy_address}).transferOwnership(team_multisig.address)) - confirm_tx(token.transact({"from": deploy_address}).transferOwnership(team_multisig.address)) - - # Set token upgrade master - confirm_tx(token.transact({"from": deploy_address}).setUpgradeMaster(team_multisig.address)) - - # Set a pre-ICO address here - confirm_tx(pricing_strategy.transact({"from": deploy_address}).setPreicoAddress(preico.address, 123456)) - - # Make sure that everything we have deployed all contracts in good state - # and their internal state is sane - verify_actions: | - assert token.call().owner() == team_multisig.address, "Expected owner {}, got {}".format(token.call().owner(),team_multisig.address) - assert crowdsale.call().owner() == team_multisig.address - assert preico.call().owner() == team_multisig.address - assert token.call().owner() == team_multisig.address - assert token.call().upgradeMaster() == team_multisig.address - assert finalize_agent.call().teamMultisig() == team_multisig.address - assert finalize_agent.call().isSane() - assert crowdsale.call().getState() == CrowdsaleState.PreFunding - - # To be used with the deposit instructions for contributors - sig_data = crowdsale._prepare_transaction("buy") - print("Crowdsale.buy() data payload is", sig_data["data"]) diff --git a/docker-compose.yml b/docker-compose.yml index 49938691..ffc356fa 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,20 +1,5 @@ version: '2' services: - ganache: - image: trufflesuite/ganache-cli - container_name: ganache-cli - tty: true - ports: - - "4545:8545/tcp" - - "4546:8546/tcp" - - "50303:30303/tcp" - - "50303:30303/udp" - - "50304:30304/udp" - networks: - testnet: - ipv4_address: 172.21.0.2 - - tkn: build: context: . @@ -30,8 +15,8 @@ services: - "./zeppelin:/usr/src/app/zeppelin" - "./ico:/usr/src/app/ico" - "./populus.json:/usr/src/app/populus.json" - depends_on: - - "ganache" + - "/etc/timezone:/etc/timezone:ro" + - "/etc/localtime:/etc/localtime:ro" networks: testnet: diff --git a/ico/cmd/distributetokens.py b/ico/cmd/distributetokens.py index 5aaef30b..49b4fe04 100644 --- a/ico/cmd/distributetokens.py +++ b/ico/cmd/distributetokens.py @@ -112,21 +112,21 @@ def main(chain, address, token, csv_file, limit, start_from, issuer_address, add print("Contract constructor arguments are", const_args) chain_name = chain fname = "Issuer.sol" - browser_driver = "chrome" - verify_contract( - project=project, - libraries={}, # TODO: Figure out how to pass around - chain_name=chain_name, - address=issuer.address, - contract_name="Issuer", - contract_filename=fname, - constructor_args=const_args, + # browser_driver = "chrome" + # verify_contract( + # project=project, + # libraries={}, # TODO: Figure out how to pass around + # chain_name=chain_name, + # address=issuer.address, + # contract_name="Issuer", + # contract_filename=fname, + # constructor_args=const_args, # libraries=runtime_data["contracts"][name]["libraries"], - browser_driver=browser_driver, - compiler=solc_version) - link = get_etherscan_link(chain_name, issuer.address) + # browser_driver=browser_driver, + # compiler=solc_version) + # link = get_etherscan_link(chain_name, issuer.address) - print("Issuer verified contract is", link) + # print("Issuer verified contract is", link) else: print("Reusing existing issuer contract") issuer = Issuer(address=issuer_address) diff --git a/nano.save b/nano.save new file mode 100644 index 00000000..fd40910d --- /dev/null +++ b/nano.save @@ -0,0 +1,4 @@ + + + + diff --git a/populus.json b/populus.json index 8e3d0899..75abe6ee 100644 --- a/populus.json +++ b/populus.json @@ -24,9 +24,9 @@ "provider": { "class": "web3.providers.rpc.HTTPProvider", "settings": { - "endpoint_uri": "http://127.0.0.1:8545", + "endpoint_uri": "http://172.21.0.1:8545", "request_kwargs": { - "timeout": 180 + "timeout": 18000 } } } @@ -68,10 +68,7 @@ "local": { "chain": { - "class": "populus.chain.geth.LocalGethChain", - "settings": { - "rpc_port": "8548" - } + "class": "populus.chain.external.ExternalChain" }, "contracts": { "backends": { @@ -93,7 +90,7 @@ "provider": { "class": "web3.providers.rpc.HTTPProvider", "settings": { - "endpoint_uri": "http://127.0.0.1:8548", + "endpoint_uri": "http://172.21.0.1:8545", "request_kwargs": { "timeout": 180 } @@ -158,7 +155,7 @@ "provider": { "class": "web3.providers.rpc.HTTPProvider", "settings": { - "endpoint_uri": "http://127.0.0.1:8546", + "endpoint_uri": "http://172.21.0.1:8545", "request_kwargs": { "timeout": 180 }