├── .babelrc ├── .gitignore ├── .travis.yml ├── README.md ├── contracts ├── example │ ├── ExampleReceiver.sol │ └── ExampleToken.sol ├── implementation │ ├── Standard223Receiver.sol │ └── Standard223Token.sol ├── interface │ ├── ERC223.sol │ └── ERC223Receiver.sol └── misc │ └── Migrations.sol ├── installed_contracts └── zeppelin │ ├── contracts │ ├── Bounty.sol │ ├── DayLimit.sol │ ├── LimitBalance.sol │ ├── MultisigWallet.sol │ ├── SafeMath.sol │ ├── lifecycle │ │ ├── Killable.sol │ │ ├── Migrations.sol │ │ └── Pausable.sol │ ├── ownership │ │ ├── Claimable.sol │ │ ├── Contactable.sol │ │ ├── DelayedClaimable.sol │ │ ├── Multisig.sol │ │ ├── Ownable.sol │ │ └── Shareable.sol │ ├── payment │ │ └── PullPayment.sol │ └── token │ │ ├── BasicToken.sol │ │ ├── CrowdsaleToken.sol │ │ ├── ERC20.sol │ │ ├── ERC20Basic.sol │ │ ├── SimpleToken.sol │ │ ├── StandardToken.sol │ │ └── VestedToken.sol │ ├── ethpm.json │ ├── lock.json │ └── lock.uri ├── migrations └── 1_initial_migration.js ├── package.json ├── test.sh ├── test ├── ReceiverTest.sol ├── StandardToken.js └── helpers │ ├── ReceiverMock.sol │ ├── StandardTokenMock.sol │ └── assertJump.js └── truffle.js /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["es2015", "stage-2", "stage-3"] 3 | } 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | build/ 3 | .DS_Store/ 4 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | dist: trusty 2 | sudo: false 3 | group: beta 4 | language: node_js 5 | node_js: 6 | - "6" 7 | before_install: 8 | - npm install truffle -g 9 | - npm i -g ethereumjs-testrpc 10 | script: 11 | - testrpc > /dev/null & 12 | - truffle test 13 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ERC23 [![Build Status](https://img.shields.io/travis/AragonOne/ERC23.svg?branch=master&style=flat-square)](https://travis-ci.org/AragonOne/ERC23) 2 | 3 | ERC23 is a superset of the [ERC20](https://github.com/ethereum/EIPs/issues/20) token standard. It is a step forward towards economic abstraction at the application/contract level allowing the use of tokens as first class value transfer assets in smart contract development. It is also a more safe standard as it doesn't allow token transfers to contracts that don't support token receiving and handling. 4 | 5 | [See EIP discussion](https://github.com/ethereum/EIPs/issues/223) 6 | 7 | ```solidity 8 | // interfaces/ERC23.sol 9 | 10 | contract ERC23 is ERC20 { 11 | function transfer(address to, uint value, bytes data) returns (bool ok); 12 | function transferFrom(address from, address to, uint value, bytes data) returns (bool ok); 13 | } 14 | ``` 15 | 16 | ### API 17 | 18 | ERC23 requires contract to implement the `ERC23Receiver` interface in order to receive tokens. If a user tries to send ERC23 tokens to a non-receiver contract the function will throw in the same way that it would if you sent ether to a contract without the called function being `payable`. 19 | 20 | An example of the high-level API for a receiver contract is: 21 | 22 | ```solidity 23 | contract ExampleReceiver is StandardReceiver { 24 | function foo() tokenPayable { 25 | LogTokenPayable(tkn.addr, tkn.sender, tkn.value); 26 | } 27 | 28 | function () tokenPayable { 29 | LogTokenPayable(tkn.addr, tkn.sender, tkn.value); 30 | } 31 | 32 | event LogTokenPayable(address token, address sender, uint value); 33 | } 34 | ``` 35 | 36 | Where functions that have the `tokenPayable` can only be called via a token fallback and inside the functions you have access to the `tkn` struct that tries to mimic the `msg` struct used for ether calls. 37 | 38 | The function `foo()` will be called when a user transfers ERC23 tokens to the receiver address. 39 | 40 | ```solidity 41 | // 0xc2985578 is the identifier for function foo. Sending it in the data parameter of a tx will result in the function being called. 42 | 43 | erc23.transfer(receiverAddress, 10, 0xc2985578) 44 | ``` 45 | 46 | What happens under the hood is that the ERC23 token will detect it is sending tokens to a contract address, and after setting the correct balances it will call the `tokenFallback` function on the receiver with the specified data. `StandardReceiver` will set the correct values for the `tkn` variables and then perform a `delegatecall` to itself with the specified data, this will result in the call to the desired function in the contract. 47 | 48 | The current `tkn` values are: 49 | 50 | - `tkn.sender` the original `msg.sender` to the token contract, the address originating the token transfer. 51 | - For user originated transfers sender will be equal to `tx.origin` 52 | - For contract originated transfers, `tx.origin` will be the user that made the transaction to that contract. 53 | 54 | - `tkn.origin` the origin address from whose balance the tokens are sent 55 | - For `transfer()`, it will be the same as `tkn.sender` 56 | - For `transferFrom()`, it will be the address that created the allowance in the token contract 57 | 58 | - `tkn.value` the amount of tokens sent 59 | - `tkn.data` arbitrary data sent with the token transfer. Simulates ether `tx.data`. 60 | - `tkn.sig` the first 4 bytes of `tx.data` that determine what function is called. 61 | 62 | ### Current implementation 63 | 64 | This repo's contracts are separated in 3 parts: 65 | 66 | - [Interfaces](/contracts/interface): The standard itself. The minimal common API ERC23 tokens and receivers to interact with each other. 67 | - [Proposed implementations](/contracts/implementation): A first approach as to how this could be implemented. In case of the [token](/contracts/implementation/Standard23Token.sol), it is built on top of heavily tested and used [Zeppelin's](http://openzeppelin.org) Standard Token, and then adds the specific ERC23 features on top. The [receiver](/contracts/implementation/StandardReceiver.sol) implementation is kept at the bare minimum for setting the `tkn` values and dispatching the call to the correct function. 68 | - [Examples](/contracts/example): A dummy token and receiver to see the API in action. 69 | 70 | ### The main goals of developing ERC23 token standard were: 71 | 1. Accidentally lost tokens inside contracts: there are two different ways to transfer ERC20 tokens depending on is the receiver address a contract or a wallet address. You should call `transfer` to send tokens to a wallet address or call `approve` on token contract then `transferFrom` on receiver contract to send tokens to contract. Accidentally call of `transfer` function to a contract address will cause a loss of tokens inside receiver contract where tokens will never be accessibe. 72 | 2. Inability of handling incoming token transactions: ERC20 token transaction is a call of `transfer` function inside token contract. ERC20 token contract is not notifying receiver that transaction occurs. Also there is no way to handle incoming token transactions on contract and no way to reject any non-supported tokens. 73 | 3. ERC20 token transaction between wallet address and contract is a couple of two different transactions in fact: You should call `approve` on token contract and then call `transferFrom` on another contract when you want to deposit your tokens intor it. 74 | 4. Ether transactions and token transactions behave different: one of the goals of developing ERC23 was to make token transactions similar to Ether transactions to avoid users mistakes when transferring tokens and make interaction with token transactions easier for contract developers. 75 | 76 | ### ERC23 advantages. 77 | 1. Provides a possibility to avoid accidentally lost tokens inside contracts that are not designed to work with sent tokens. 78 | 2. Allows users to send their tokens anywhere with one function `transfer`. No difference between is the receiver a contract or not. No need to learn how token contract is working for regular user to send tokens. 79 | 3. Allows contract developers to handle incoming token transactions. 80 | 4. ERC23 `transfer` to contract consumes 2 times less gas than ERC20 `approve` and `transferFrom` at receiver contract. 81 | 5. Allows to deposit tokens intor contract with a single transaction. Prevents extra blockchain bloating. 82 | 6. Makes token transactions similar to Ether transactions. 83 | 84 | ERC23 tokens are backwards compatible with ERC20 tokens. It means that ERC23 supports every ERC20 functional and contracts or services working with ERC20 tokens will work with ERC23 tokens correctly. 85 | ERC23 tokens should be sent by calling `transfer` function on token contract with no difference is receiver a contract or a wallet address. If the receiver is a wallet ERC23 token transfer will be same to ERC20 transfer. If the receiver is a contract ERC23 token contract will try to call `tokenFallback` function on receiver contract. If there is no `tokenFallback` function on receiver contract transaction will fail. `tokenFallback` function is analogue of `fallback` function for Ether transactions. It can be used to handle incoming transactions. There is a way to attach `bytes _data` to token transaction similar to `_data` attached to Ether transactions. It will pass through token contract and will be handled by `tokenFallback` function on receiver contract. There is also a way to call `transfer` function on ERC23 token contract with no data argument or using ERC20 ABI with no data on `transfer` function. In this case `_data` will be empty bytes array. 86 | 87 | ERC23 EIP https://github.com/ethereum/EIPs/issues/223 88 | ERC20 EIP https://github.com/ethereum/EIPs/issues/20 89 | 90 | ### Lost tokens held by contracts 91 | There is already a number of tokens held by token contracts themselves. This tokens will not be accessible as there is no function to withdraw them from contract. 92 | 93 | 43071 GNT in Golem contract ~ $1000: 94 | https://etherscan.io/token/Golem?a=0xa74476443119a942de498590fe1f2454d7d4ac0d 95 | 96 | 103 REP in Augur contract ~ $600: 97 | https://etherscan.io/token/REP?a=0x48c80f1f4d53d5951e5d5438b54cba84f29f32a5 98 | 99 | 777 DGD in Digix DAO contract ~ $7500: 100 | https://etherscan.io/token/0xe0b7927c4af23765cb51314a0e0521a9645f0e2a?a=0xe0b7927c4af23765cb51314a0e0521a9645f0e2a 101 | 102 | 10100 1ST in FirstBlood contract ~ $883: 103 | https://etherscan.io/token/FirstBlood?a=0xaf30d2a7e90d7dc361c8c4585e9bb7d2f6f15bc7 104 | -------------------------------------------------------------------------------- /contracts/example/ExampleReceiver.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.8; 2 | 3 | import "../implementation/Standard223Receiver.sol"; 4 | 5 | contract ExampleReceiver is Standard223Receiver { 6 | function foo(/*uint i*/) tokenPayable { 7 | LogTokenPayable(1, tkn.addr, tkn.sender, tkn.value); 8 | } 9 | 10 | function () tokenPayable { 11 | LogTokenPayable(0, tkn.addr, tkn.sender, tkn.value); 12 | } 13 | 14 | function supportsToken(address token) returns (bool) { 15 | return true; 16 | } 17 | 18 | event LogTokenPayable(uint i, address token, address sender, uint value); 19 | } 20 | -------------------------------------------------------------------------------- /contracts/example/ExampleToken.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.8; 2 | 3 | import "../implementation/Standard223Token.sol"; 4 | 5 | contract ExampleToken is Standard223Token { 6 | function ExampleToken(uint initialBalance) { 7 | balances[msg.sender] = initialBalance; 8 | totalSupply = initialBalance; 9 | // Ideally call token fallback here too 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /contracts/implementation/Standard223Receiver.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.8; 2 | 3 | /* ERC223 additions to ERC20 */ 4 | 5 | import "../interface/ERC223Receiver.sol"; 6 | 7 | contract Standard223Receiver is ERC223Receiver { 8 | Tkn tkn; 9 | 10 | struct Tkn { 11 | address addr; 12 | address sender; 13 | address origin; 14 | uint256 value; 15 | bytes data; 16 | bytes4 sig; 17 | } 18 | 19 | function tokenFallback(address _sender, address _origin, uint _value, bytes _data) returns (bool ok) { 20 | if (!supportsToken(msg.sender)) return false; 21 | 22 | // Problem: This will do a sstore which is expensive gas wise. Find a way to keep it in memory. 23 | tkn = Tkn(msg.sender, _sender, _origin, _value, _data, getSig(_data)); 24 | __isTokenFallback = true; 25 | if (!address(this).delegatecall(_data)) return false; 26 | 27 | // avoid doing an overwrite to .token, which would be more expensive 28 | // makes accessing .tkn values outside tokenPayable functions unsafe 29 | __isTokenFallback = false; 30 | 31 | return true; 32 | } 33 | 34 | function getSig(bytes _data) private returns (bytes4 sig) { 35 | uint l = _data.length < 4 ? _data.length : 4; 36 | for (uint i = 0; i < l; i++) { 37 | sig = bytes4(uint(sig) + uint(_data[i]) * (2 ** (8 * (l - 1 - i)))); 38 | } 39 | } 40 | 41 | bool __isTokenFallback; 42 | 43 | modifier tokenPayable { 44 | if (!__isTokenFallback) throw; 45 | _; 46 | } 47 | 48 | function supportsToken(address token) returns (bool); 49 | } 50 | -------------------------------------------------------------------------------- /contracts/implementation/Standard223Token.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.8; 2 | 3 | /* ERC223 additions to ERC20 */ 4 | 5 | import "../interface/ERC223.sol"; 6 | import "../interface/ERC223Receiver.sol"; 7 | 8 | import "zeppelin/token/StandardToken.sol"; 9 | 10 | contract Standard223Token is ERC223, StandardToken { 11 | //function that is called when a user or another contract wants to transfer funds 12 | function transfer(address _to, uint _value, bytes _data) returns (bool success) { 13 | //filtering if the target is a contract with bytecode inside it 14 | if (!super.transfer(_to, _value)) throw; // do a normal token transfer 15 | if (isContract(_to)) return contractFallback(msg.sender, _to, _value, _data); 16 | return true; 17 | } 18 | 19 | function transferFrom(address _from, address _to, uint _value, bytes _data) returns (bool success) { 20 | if (!super.transferFrom(_from, _to, _value)) throw; // do a normal token transfer 21 | if (isContract(_to)) return contractFallback(_from, _to, _value, _data); 22 | return true; 23 | } 24 | 25 | function transfer(address _to, uint _value) returns (bool success) { 26 | return transfer(_to, _value, new bytes(0)); 27 | } 28 | 29 | function transferFrom(address _from, address _to, uint _value) returns (bool success) { 30 | return transferFrom(_from, _to, _value, new bytes(0)); 31 | } 32 | 33 | //function that is called when transaction target is a contract 34 | function contractFallback(address _origin, address _to, uint _value, bytes _data) private returns (bool success) { 35 | ERC223Receiver reciever = ERC223Receiver(_to); 36 | return reciever.tokenFallback(msg.sender, _origin, _value, _data); 37 | } 38 | 39 | //assemble the given address bytecode. If bytecode exists then the _addr is a contract. 40 | function isContract(address _addr) private returns (bool is_contract) { 41 | // retrieve the size of the code on target address, this needs assembly 42 | uint length; 43 | assembly { length := extcodesize(_addr) } 44 | return length > 0; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /contracts/interface/ERC223.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.8; 2 | 3 | /* 4 | ERC223 additions to ERC20 5 | 6 | Interface wise is ERC20 + data paramenter to transfer and transferFrom. 7 | */ 8 | 9 | import "zeppelin/token/ERC20.sol"; 10 | 11 | contract ERC223 is ERC20 { 12 | function transfer(address to, uint value, bytes data) returns (bool ok); 13 | function transferFrom(address from, address to, uint value, bytes data) returns (bool ok); 14 | } 15 | -------------------------------------------------------------------------------- /contracts/interface/ERC223Receiver.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.8; 2 | 3 | /* 4 | Base class contracts willing to accept ERC223 token transfers must conform to. 5 | 6 | Sender: msg.sender to the token contract, the address originating the token transfer. 7 | - For user originated transfers sender will be equal to tx.origin 8 | - For contract originated transfers, tx.origin will be the user that made the tx that produced the transfer. 9 | Origin: the origin address from whose balance the tokens are sent 10 | - For transfer(), origin = msg.sender 11 | - For transferFrom() origin = _from to token contract 12 | Value is the amount of tokens sent 13 | Data is arbitrary data sent with the token transfer. Simulates ether tx.data 14 | 15 | From, origin and value shouldn't be trusted unless the token contract is trusted. 16 | If sender == tx.origin, it is safe to trust it regardless of the token. 17 | */ 18 | 19 | contract ERC223Receiver { 20 | function tokenFallback(address _sender, address _origin, uint _value, bytes _data) returns (bool ok); 21 | } 22 | -------------------------------------------------------------------------------- /contracts/misc/Migrations.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.8; 2 | 3 | contract Migrations { 4 | address public owner; 5 | uint public last_completed_migration; 6 | 7 | modifier restricted() { 8 | if (msg.sender == owner) _; 9 | } 10 | 11 | function Migrations() { 12 | owner = msg.sender; 13 | } 14 | 15 | function setCompleted(uint completed) restricted { 16 | last_completed_migration = completed; 17 | } 18 | 19 | function upgrade(address new_address) restricted { 20 | Migrations upgraded = Migrations(new_address); 21 | upgraded.setCompleted(last_completed_migration); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /installed_contracts/zeppelin/contracts/Bounty.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.8; 2 | 3 | 4 | import './payment/PullPayment.sol'; 5 | import './lifecycle/Killable.sol'; 6 | 7 | 8 | /* 9 | * Bounty 10 | * 11 | * This bounty will pay out to a researcher if they break invariant logic of the contract. 12 | */ 13 | contract Bounty is PullPayment, Killable { 14 | bool public claimed; 15 | mapping(address => address) public researchers; 16 | 17 | event TargetCreated(address createdAddress); 18 | 19 | function() payable { 20 | if (claimed) { 21 | throw; 22 | } 23 | } 24 | 25 | function createTarget() returns(Target) { 26 | Target target = Target(deployContract()); 27 | researchers[target] = msg.sender; 28 | TargetCreated(target); 29 | return target; 30 | } 31 | 32 | function deployContract() internal returns(address); 33 | 34 | function claim(Target target) { 35 | address researcher = researchers[target]; 36 | if (researcher == 0) { 37 | throw; 38 | } 39 | // Check Target contract invariants 40 | if (target.checkInvariant()) { 41 | throw; 42 | } 43 | asyncSend(researcher, this.balance); 44 | claimed = true; 45 | } 46 | 47 | } 48 | 49 | 50 | /* 51 | * Target 52 | * 53 | * Your main contract should inherit from this class and implement the checkInvariant method. This is a function that should check everything your contract assumes to be true all the time. If this function returns false, it means your contract was broken in some way and is in an inconsistent state. This is what security researchers will try to acomplish when trying to get the bounty. 54 | */ 55 | contract Target { 56 | function checkInvariant() returns(bool); 57 | } 58 | 59 | -------------------------------------------------------------------------------- /installed_contracts/zeppelin/contracts/DayLimit.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.8; 2 | 3 | 4 | import './ownership/Shareable.sol'; 5 | 6 | 7 | /* 8 | * DayLimit 9 | * 10 | * inheritable "property" contract that enables methods to be protected by placing a linear limit (specifiable) 11 | * on a particular resource per calendar day. is multiowned to allow the limit to be altered. resource that method 12 | * uses is specified in the modifier. 13 | */ 14 | contract DayLimit { 15 | 16 | uint public dailyLimit; 17 | uint public spentToday; 18 | uint public lastDay; 19 | 20 | 21 | function DayLimit(uint _limit) { 22 | dailyLimit = _limit; 23 | lastDay = today(); 24 | } 25 | 26 | // sets the daily limit. doesn't alter the amount already spent today 27 | function _setDailyLimit(uint _newLimit) internal { 28 | dailyLimit = _newLimit; 29 | } 30 | 31 | // resets the amount already spent today. 32 | function _resetSpentToday() internal { 33 | spentToday = 0; 34 | } 35 | 36 | // checks to see if there is at least `_value` left from the daily limit today. if there is, subtracts it and 37 | // returns true. otherwise just returns false. 38 | function underLimit(uint _value) internal returns (bool) { 39 | // reset the spend limit if we're on a different day to last time. 40 | if (today() > lastDay) { 41 | spentToday = 0; 42 | lastDay = today(); 43 | } 44 | // check to see if there's enough left - if so, subtract and return true. 45 | // overflow protection // dailyLimit check 46 | if (spentToday + _value >= spentToday && spentToday + _value <= dailyLimit) { 47 | spentToday += _value; 48 | return true; 49 | } 50 | return false; 51 | } 52 | 53 | // determines today's index. 54 | function today() private constant returns (uint) { 55 | return now / 1 days; 56 | } 57 | 58 | 59 | // simple modifier for daily limit. 60 | modifier limitedDaily(uint _value) { 61 | if (!underLimit(_value)) { 62 | throw; 63 | } 64 | _; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /installed_contracts/zeppelin/contracts/LimitBalance.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.8; 2 | 3 | 4 | /** 5 | * LimitBalance 6 | * Simple contract to limit the balance of child contract. 7 | * Note this doesn't prevent other contracts to send funds 8 | * by using selfdestruct(address); 9 | * See: https://github.com/ConsenSys/smart-contract-best-practices#remember-that-ether-can-be-forcibly-sent-to-an-account 10 | */ 11 | contract LimitBalance { 12 | 13 | uint public limit; 14 | 15 | function LimitBalance(uint _limit) { 16 | limit = _limit; 17 | } 18 | 19 | modifier limitedPayable() { 20 | if (this.balance > limit) { 21 | throw; 22 | } 23 | _; 24 | 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /installed_contracts/zeppelin/contracts/MultisigWallet.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.8; 2 | 3 | 4 | import "./ownership/Multisig.sol"; 5 | import "./ownership/Shareable.sol"; 6 | import "./DayLimit.sol"; 7 | 8 | 9 | /* 10 | * MultisigWallet 11 | * usage: 12 | * bytes32 h = Wallet(w).from(oneOwner).execute(to, value, data); 13 | * Wallet(w).from(anotherOwner).confirm(h); 14 | */ 15 | contract MultisigWallet is Multisig, Shareable, DayLimit { 16 | 17 | struct Transaction { 18 | address to; 19 | uint value; 20 | bytes data; 21 | } 22 | 23 | function MultisigWallet(address[] _owners, uint _required, uint _daylimit) 24 | Shareable(_owners, _required) 25 | DayLimit(_daylimit) { } 26 | 27 | // kills the contract sending everything to `_to`. 28 | function kill(address _to) onlymanyowners(sha3(msg.data)) external { 29 | suicide(_to); 30 | } 31 | 32 | // gets called when no other function matches 33 | function() payable { 34 | // just being sent some cash? 35 | if (msg.value > 0) 36 | Deposit(msg.sender, msg.value); 37 | } 38 | 39 | // Outside-visible transact entry point. Executes transaction immediately if below daily spend limit. 40 | // If not, goes into multisig process. We provide a hash on return to allow the sender to provide 41 | // shortcuts for the other confirmations (allowing them to avoid replicating the _to, _value 42 | // and _data arguments). They still get the option of using them if they want, anyways. 43 | function execute(address _to, uint _value, bytes _data) external onlyOwner returns (bytes32 _r) { 44 | // first, take the opportunity to check that we're under the daily limit. 45 | if (underLimit(_value)) { 46 | SingleTransact(msg.sender, _value, _to, _data); 47 | // yes - just execute the call. 48 | if (!_to.call.value(_value)(_data)) { 49 | throw; 50 | } 51 | return 0; 52 | } 53 | // determine our operation hash. 54 | _r = sha3(msg.data, block.number); 55 | if (!confirm(_r) && txs[_r].to == 0) { 56 | txs[_r].to = _to; 57 | txs[_r].value = _value; 58 | txs[_r].data = _data; 59 | ConfirmationNeeded(_r, msg.sender, _value, _to, _data); 60 | } 61 | } 62 | 63 | // confirm a transaction through just the hash. we use the previous transactions map, txs, in order 64 | // to determine the body of the transaction from the hash provided. 65 | function confirm(bytes32 _h) onlymanyowners(_h) returns (bool) { 66 | if (txs[_h].to != 0) { 67 | if (!txs[_h].to.call.value(txs[_h].value)(txs[_h].data)) { 68 | throw; 69 | } 70 | MultiTransact(msg.sender, _h, txs[_h].value, txs[_h].to, txs[_h].data); 71 | delete txs[_h]; 72 | return true; 73 | } 74 | } 75 | 76 | function setDailyLimit(uint _newLimit) onlymanyowners(sha3(msg.data)) external { 77 | _setDailyLimit(_newLimit); 78 | } 79 | 80 | function resetSpentToday() onlymanyowners(sha3(msg.data)) external { 81 | _resetSpentToday(); 82 | } 83 | 84 | 85 | // INTERNAL METHODS 86 | 87 | function clearPending() internal { 88 | uint length = pendingsIndex.length; 89 | for (uint i = 0; i < length; ++i) { 90 | delete txs[pendingsIndex[i]]; 91 | } 92 | super.clearPending(); 93 | } 94 | 95 | 96 | // FIELDS 97 | 98 | // pending transactions we have at present. 99 | mapping (bytes32 => Transaction) txs; 100 | } 101 | -------------------------------------------------------------------------------- /installed_contracts/zeppelin/contracts/SafeMath.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.8; 2 | 3 | 4 | /** 5 | * Math operations with safety checks 6 | */ 7 | contract SafeMath { 8 | function safeMul(uint a, uint b) internal returns (uint) { 9 | uint c = a * b; 10 | assert(a == 0 || c / a == b); 11 | return c; 12 | } 13 | 14 | function safeDiv(uint a, uint b) internal returns (uint) { 15 | assert(b > 0); 16 | uint c = a / b; 17 | assert(a == b * c + a % b); 18 | return c; 19 | } 20 | 21 | function safeSub(uint a, uint b) internal returns (uint) { 22 | assert(b <= a); 23 | return a - b; 24 | } 25 | 26 | function safeAdd(uint a, uint b) internal returns (uint) { 27 | uint c = a + b; 28 | assert(c>=a && c>=b); 29 | return c; 30 | } 31 | 32 | function max64(uint64 a, uint64 b) internal constant returns (uint64) { 33 | return a >= b ? a : b; 34 | } 35 | 36 | function min64(uint64 a, uint64 b) internal constant returns (uint64) { 37 | return a < b ? a : b; 38 | } 39 | 40 | function max256(uint256 a, uint256 b) internal constant returns (uint256) { 41 | return a >= b ? a : b; 42 | } 43 | 44 | function min256(uint256 a, uint256 b) internal constant returns (uint256) { 45 | return a < b ? a : b; 46 | } 47 | 48 | function assert(bool assertion) internal { 49 | if (!assertion) { 50 | throw; 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /installed_contracts/zeppelin/contracts/lifecycle/Killable.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.8; 2 | 3 | 4 | import "../ownership/Ownable.sol"; 5 | 6 | 7 | /* 8 | * Killable 9 | * Base contract that can be killed by owner. All funds in contract will be sent to the owner. 10 | */ 11 | contract Killable is Ownable { 12 | function kill() onlyOwner { 13 | selfdestruct(owner); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /installed_contracts/zeppelin/contracts/lifecycle/Migrations.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.8; 2 | 3 | 4 | import '../ownership/Ownable.sol'; 5 | 6 | 7 | contract Migrations is Ownable { 8 | uint public lastCompletedMigration; 9 | 10 | function setCompleted(uint completed) onlyOwner { 11 | lastCompletedMigration = completed; 12 | } 13 | 14 | function upgrade(address newAddress) onlyOwner { 15 | Migrations upgraded = Migrations(newAddress); 16 | upgraded.setCompleted(lastCompletedMigration); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /installed_contracts/zeppelin/contracts/lifecycle/Pausable.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.8; 2 | 3 | 4 | import "../ownership/Ownable.sol"; 5 | 6 | 7 | /* 8 | * Pausable 9 | * Abstract contract that allows children to implement an 10 | * emergency stop mechanism. 11 | */ 12 | contract Pausable is Ownable { 13 | bool public stopped; 14 | 15 | modifier stopInEmergency { 16 | if (!stopped) { 17 | _; 18 | } 19 | } 20 | 21 | modifier onlyInEmergency { 22 | if (stopped) { 23 | _; 24 | } 25 | } 26 | 27 | // called by the owner on emergency, triggers stopped state 28 | function emergencyStop() external onlyOwner { 29 | stopped = true; 30 | } 31 | 32 | // called by the owner on end of emergency, returns to normal state 33 | function release() external onlyOwner onlyInEmergency { 34 | stopped = false; 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /installed_contracts/zeppelin/contracts/ownership/Claimable.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.0; 2 | 3 | 4 | import './Ownable.sol'; 5 | 6 | 7 | /* 8 | * Claimable 9 | * 10 | * Extension for the Ownable contract, where the ownership needs to be claimed. This allows the new owner to accept the transfer. 11 | */ 12 | contract Claimable is Ownable { 13 | address public pendingOwner; 14 | 15 | modifier onlyPendingOwner() { 16 | if (msg.sender != pendingOwner) { 17 | throw; 18 | } 19 | _; 20 | } 21 | 22 | function transferOwnership(address newOwner) onlyOwner { 23 | pendingOwner = newOwner; 24 | } 25 | 26 | function claimOwnership() onlyPendingOwner { 27 | owner = pendingOwner; 28 | pendingOwner = 0x0; 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /installed_contracts/zeppelin/contracts/ownership/Contactable.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.0; 2 | 3 | import './Ownable.sol'; 4 | /* 5 | * Contactable token 6 | * Basic version of a contactable contract 7 | */ 8 | contract Contactable is Ownable{ 9 | 10 | string public contactInformation; 11 | 12 | function setContactInformation(string info) onlyOwner{ 13 | contactInformation = info; 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /installed_contracts/zeppelin/contracts/ownership/DelayedClaimable.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.8; 2 | 3 | 4 | import './Ownable.sol'; 5 | import './Claimable.sol'; 6 | 7 | 8 | /* 9 | * DelayedClaimable 10 | * Extension for the Claimable contract, where the ownership needs to be claimed before/after certain block number 11 | */ 12 | contract DelayedClaimable is Ownable, Claimable { 13 | 14 | uint public end; 15 | uint public start; 16 | 17 | function setLimits(uint _start, uint _end) onlyOwner { 18 | if (_start > _end) 19 | throw; 20 | end = _end; 21 | start = _start; 22 | } 23 | 24 | function claimOwnership() onlyPendingOwner { 25 | if ((block.number > end) || (block.number < start)) 26 | throw; 27 | owner = pendingOwner; 28 | pendingOwner = 0x0; 29 | end = 0; 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /installed_contracts/zeppelin/contracts/ownership/Multisig.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.8; 2 | 3 | 4 | /* 5 | * Multisig 6 | * Interface contract for multisig proxy contracts; see below for docs. 7 | */ 8 | contract Multisig { 9 | // EVENTS 10 | 11 | // logged events: 12 | // Funds has arrived into the wallet (record how much). 13 | event Deposit(address _from, uint value); 14 | // Single transaction going out of the wallet (record who signed for it, how much, and to whom it's going). 15 | event SingleTransact(address owner, uint value, address to, bytes data); 16 | // Multi-sig transaction going out of the wallet (record who signed for it last, the operation hash, how much, and to whom it's going). 17 | event MultiTransact(address owner, bytes32 operation, uint value, address to, bytes data); 18 | // Confirmation still needed for a transaction. 19 | event ConfirmationNeeded(bytes32 operation, address initiator, uint value, address to, bytes data); 20 | 21 | 22 | // FUNCTIONS 23 | 24 | // TODO: document 25 | function changeOwner(address _from, address _to) external; 26 | function execute(address _to, uint _value, bytes _data) external returns (bytes32); 27 | function confirm(bytes32 _h) returns (bool); 28 | } 29 | 30 | -------------------------------------------------------------------------------- /installed_contracts/zeppelin/contracts/ownership/Ownable.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.8; 2 | 3 | 4 | /* 5 | * Ownable 6 | * 7 | * Base contract with an owner. 8 | * Provides onlyOwner modifier, which prevents function from running if it is called by anyone other than the owner. 9 | */ 10 | contract Ownable { 11 | address public owner; 12 | 13 | function Ownable() { 14 | owner = msg.sender; 15 | } 16 | 17 | modifier onlyOwner() { 18 | if (msg.sender != owner) { 19 | throw; 20 | } 21 | _; 22 | } 23 | 24 | function transferOwnership(address newOwner) onlyOwner { 25 | if (newOwner != address(0)) { 26 | owner = newOwner; 27 | } 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /installed_contracts/zeppelin/contracts/ownership/Shareable.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.8; 2 | 3 | 4 | /* 5 | * Shareable 6 | * 7 | * Based on https://github.com/ethereum/dapp-bin/blob/master/wallet/wallet.sol 8 | * 9 | * inheritable "property" contract that enables methods to be protected by requiring the acquiescence of either a single, or, crucially, each of a number of, designated owners. 10 | * 11 | * usage: 12 | * use modifiers onlyowner (just own owned) or onlymanyowners(hash), whereby the same hash must be provided by some number (specified in constructor) of the set of owners (specified in the constructor) before the interior is executed. 13 | */ 14 | contract Shareable { 15 | // struct for the status of a pending operation. 16 | struct PendingState { 17 | uint yetNeeded; 18 | uint ownersDone; 19 | uint index; 20 | } 21 | 22 | // the number of owners that must confirm the same operation before it is run. 23 | uint public required; 24 | 25 | // list of owners 26 | uint[256] owners; 27 | // index on the list of owners to allow reverse lookup 28 | mapping(uint => uint) ownerIndex; 29 | // the ongoing operations. 30 | mapping(bytes32 => PendingState) pendings; 31 | bytes32[] pendingsIndex; 32 | 33 | 34 | // this contract only has six types of events: it can accept a confirmation, in which case 35 | // we record owner and operation (hash) alongside it. 36 | event Confirmation(address owner, bytes32 operation); 37 | event Revoke(address owner, bytes32 operation); 38 | 39 | 40 | // simple single-sig function modifier. 41 | modifier onlyOwner { 42 | if (!isOwner(msg.sender)) { 43 | throw; 44 | } 45 | _; 46 | } 47 | 48 | // multi-sig function modifier: the operation must have an intrinsic hash in order 49 | // that later attempts can be realised as the same underlying operation and 50 | // thus count as confirmations. 51 | modifier onlymanyowners(bytes32 _operation) { 52 | if (confirmAndCheck(_operation)) { 53 | _; 54 | } 55 | } 56 | 57 | // constructor is given number of sigs required to do protected "onlymanyowners" transactions 58 | // as well as the selection of addresses capable of confirming them. 59 | function Shareable(address[] _owners, uint _required) { 60 | owners[1] = uint(msg.sender); 61 | ownerIndex[uint(msg.sender)] = 1; 62 | for (uint i = 0; i < _owners.length; ++i) { 63 | owners[2 + i] = uint(_owners[i]); 64 | ownerIndex[uint(_owners[i])] = 2 + i; 65 | } 66 | required = _required; 67 | } 68 | 69 | // Revokes a prior confirmation of the given operation 70 | function revoke(bytes32 _operation) external { 71 | uint index = ownerIndex[uint(msg.sender)]; 72 | // make sure they're an owner 73 | if (index == 0) { 74 | return; 75 | } 76 | uint ownerIndexBit = 2**index; 77 | var pending = pendings[_operation]; 78 | if (pending.ownersDone & ownerIndexBit > 0) { 79 | pending.yetNeeded++; 80 | pending.ownersDone -= ownerIndexBit; 81 | Revoke(msg.sender, _operation); 82 | } 83 | } 84 | 85 | // Gets an owner by 0-indexed position (using numOwners as the count) 86 | function getOwner(uint ownerIndex) external constant returns (address) { 87 | return address(owners[ownerIndex + 1]); 88 | } 89 | 90 | function isOwner(address _addr) constant returns (bool) { 91 | return ownerIndex[uint(_addr)] > 0; 92 | } 93 | 94 | function hasConfirmed(bytes32 _operation, address _owner) constant returns (bool) { 95 | var pending = pendings[_operation]; 96 | uint index = ownerIndex[uint(_owner)]; 97 | 98 | // make sure they're an owner 99 | if (index == 0) { 100 | return false; 101 | } 102 | 103 | // determine the bit to set for this owner. 104 | uint ownerIndexBit = 2**index; 105 | return !(pending.ownersDone & ownerIndexBit == 0); 106 | } 107 | 108 | function confirmAndCheck(bytes32 _operation) internal returns (bool) { 109 | // determine what index the present sender is: 110 | uint index = ownerIndex[uint(msg.sender)]; 111 | // make sure they're an owner 112 | if (index == 0) { 113 | return; 114 | } 115 | 116 | var pending = pendings[_operation]; 117 | // if we're not yet working on this operation, switch over and reset the confirmation status. 118 | if (pending.yetNeeded == 0) { 119 | // reset count of confirmations needed. 120 | pending.yetNeeded = required; 121 | // reset which owners have confirmed (none) - set our bitmap to 0. 122 | pending.ownersDone = 0; 123 | pending.index = pendingsIndex.length++; 124 | pendingsIndex[pending.index] = _operation; 125 | } 126 | // determine the bit to set for this owner. 127 | uint ownerIndexBit = 2**index; 128 | // make sure we (the message sender) haven't confirmed this operation previously. 129 | if (pending.ownersDone & ownerIndexBit == 0) { 130 | Confirmation(msg.sender, _operation); 131 | // ok - check if count is enough to go ahead. 132 | if (pending.yetNeeded <= 1) { 133 | // enough confirmations: reset and run interior. 134 | delete pendingsIndex[pendings[_operation].index]; 135 | delete pendings[_operation]; 136 | return true; 137 | } else { 138 | // not enough: record that this owner in particular confirmed. 139 | pending.yetNeeded--; 140 | pending.ownersDone |= ownerIndexBit; 141 | } 142 | } 143 | } 144 | 145 | function clearPending() internal { 146 | uint length = pendingsIndex.length; 147 | for (uint i = 0; i < length; ++i) { 148 | if (pendingsIndex[i] != 0) { 149 | delete pendings[pendingsIndex[i]]; 150 | } 151 | } 152 | delete pendingsIndex; 153 | } 154 | 155 | } 156 | -------------------------------------------------------------------------------- /installed_contracts/zeppelin/contracts/payment/PullPayment.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.8; 2 | 3 | 4 | /* 5 | * PullPayment 6 | * Base contract supporting async send for pull payments. 7 | * Inherit from this contract and use asyncSend instead of send. 8 | */ 9 | contract PullPayment { 10 | mapping(address => uint) public payments; 11 | 12 | // store sent amount as credit to be pulled, called by payer 13 | function asyncSend(address dest, uint amount) internal { 14 | payments[dest] += amount; 15 | } 16 | 17 | // withdraw accumulated balance, called by payee 18 | function withdrawPayments() { 19 | address payee = msg.sender; 20 | uint payment = payments[payee]; 21 | 22 | if (payment == 0) { 23 | throw; 24 | } 25 | 26 | if (this.balance < payment) { 27 | throw; 28 | } 29 | 30 | payments[payee] = 0; 31 | 32 | if (!payee.send(payment)) { 33 | throw; 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /installed_contracts/zeppelin/contracts/token/BasicToken.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.8; 2 | 3 | 4 | import './ERC20Basic.sol'; 5 | import '../SafeMath.sol'; 6 | 7 | 8 | /* 9 | * Basic token 10 | * Basic version of StandardToken, with no allowances 11 | */ 12 | contract BasicToken is ERC20Basic, SafeMath { 13 | 14 | mapping(address => uint) balances; 15 | 16 | function transfer(address _to, uint _value) { 17 | balances[msg.sender] = safeSub(balances[msg.sender], _value); 18 | balances[_to] = safeAdd(balances[_to], _value); 19 | Transfer(msg.sender, _to, _value); 20 | } 21 | 22 | function balanceOf(address _owner) constant returns (uint balance) { 23 | return balances[_owner]; 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /installed_contracts/zeppelin/contracts/token/CrowdsaleToken.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.8; 2 | 3 | 4 | import "./StandardToken.sol"; 5 | 6 | 7 | /* 8 | * CrowdsaleToken 9 | * 10 | * Simple ERC20 Token example, with crowdsale token creation 11 | */ 12 | contract CrowdsaleToken is StandardToken { 13 | 14 | string public name = "CrowdsaleToken"; 15 | string public symbol = "CRW"; 16 | uint public decimals = 18; 17 | 18 | // 1 ether = 500 example tokens 19 | uint PRICE = 500; 20 | 21 | function () payable { 22 | createTokens(msg.sender); 23 | } 24 | 25 | function createTokens(address recipient) payable { 26 | if (msg.value == 0) { 27 | throw; 28 | } 29 | 30 | uint tokens = safeMul(msg.value, getPrice()); 31 | 32 | totalSupply = safeAdd(totalSupply, tokens); 33 | balances[recipient] = safeAdd(balances[recipient], tokens); 34 | } 35 | 36 | // replace this with any other price function 37 | function getPrice() constant returns (uint result) { 38 | return PRICE; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /installed_contracts/zeppelin/contracts/token/ERC20.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.8; 2 | 3 | 4 | /* 5 | * ERC20 interface 6 | * see https://github.com/ethereum/EIPs/issues/20 7 | */ 8 | contract ERC20 { 9 | uint public totalSupply; 10 | function balanceOf(address who) constant returns (uint); 11 | function allowance(address owner, address spender) constant returns (uint); 12 | 13 | function transfer(address to, uint value) returns (bool ok); 14 | function transferFrom(address from, address to, uint value) returns (bool ok); 15 | function approve(address spender, uint value) returns (bool ok); 16 | event Transfer(address indexed from, address indexed to, uint value); 17 | event Approval(address indexed owner, address indexed spender, uint value); 18 | } 19 | -------------------------------------------------------------------------------- /installed_contracts/zeppelin/contracts/token/ERC20Basic.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.8; 2 | 3 | 4 | /* 5 | * ERC20Basic 6 | * Simpler version of ERC20 interface 7 | * see https://github.com/ethereum/EIPs/issues/20 8 | */ 9 | contract ERC20Basic { 10 | uint public totalSupply; 11 | function balanceOf(address who) constant returns (uint); 12 | function transfer(address to, uint value); 13 | event Transfer(address indexed from, address indexed to, uint value); 14 | } 15 | -------------------------------------------------------------------------------- /installed_contracts/zeppelin/contracts/token/SimpleToken.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.8; 2 | 3 | 4 | import "./StandardToken.sol"; 5 | 6 | 7 | /* 8 | * SimpleToken 9 | * 10 | * Very simple ERC20 Token example, where all tokens are pre-assigned 11 | * to the creator. Note they can later distribute these tokens 12 | * as they wish using `transfer` and other `StandardToken` functions. 13 | */ 14 | contract SimpleToken is StandardToken { 15 | 16 | string public name = "SimpleToken"; 17 | string public symbol = "SIM"; 18 | uint public decimals = 18; 19 | uint public INITIAL_SUPPLY = 10000; 20 | 21 | function SimpleToken() { 22 | totalSupply = INITIAL_SUPPLY; 23 | balances[msg.sender] = INITIAL_SUPPLY; 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /installed_contracts/zeppelin/contracts/token/StandardToken.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.8; 2 | 3 | 4 | import './ERC20.sol'; 5 | import '../SafeMath.sol'; 6 | 7 | 8 | /** 9 | * Standard ERC20 token 10 | * 11 | * https://github.com/ethereum/EIPs/issues/20 12 | * Based on code by FirstBlood: 13 | * https://github.com/Firstbloodio/token/blob/master/smart_contract/FirstBloodToken.sol 14 | */ 15 | contract StandardToken is ERC20, SafeMath { 16 | 17 | mapping(address => uint) balances; 18 | mapping (address => mapping (address => uint)) allowed; 19 | 20 | function transfer(address _to, uint _value) returns (bool success) { 21 | balances[msg.sender] = safeSub(balances[msg.sender], _value); 22 | balances[_to] = safeAdd(balances[_to], _value); 23 | Transfer(msg.sender, _to, _value); 24 | return true; 25 | } 26 | 27 | function transferFrom(address _from, address _to, uint _value) returns (bool success) { 28 | var _allowance = allowed[_from][msg.sender]; 29 | 30 | // Check is not needed because safeSub(_allowance, _value) will already throw if this condition is not met 31 | // if (_value > _allowance) throw; 32 | 33 | balances[_to] = safeAdd(balances[_to], _value); 34 | balances[_from] = safeSub(balances[_from], _value); 35 | allowed[_from][msg.sender] = safeSub(_allowance, _value); 36 | Transfer(_from, _to, _value); 37 | return true; 38 | } 39 | 40 | function balanceOf(address _owner) constant returns (uint balance) { 41 | return balances[_owner]; 42 | } 43 | 44 | function approve(address _spender, uint _value) returns (bool success) { 45 | allowed[msg.sender][_spender] = _value; 46 | Approval(msg.sender, _spender, _value); 47 | return true; 48 | } 49 | 50 | function allowance(address _owner, address _spender) constant returns (uint remaining) { 51 | return allowed[_owner][_spender]; 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /installed_contracts/zeppelin/contracts/token/VestedToken.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.8; 2 | 3 | 4 | import "./StandardToken.sol"; 5 | 6 | 7 | contract VestedToken is StandardToken { 8 | struct TokenGrant { 9 | address granter; 10 | uint256 value; 11 | uint64 cliff; 12 | uint64 vesting; 13 | uint64 start; 14 | } 15 | 16 | mapping (address => TokenGrant[]) public grants; 17 | 18 | modifier canTransfer(address _sender, uint _value) { 19 | if (_value > transferableTokens(_sender, uint64(now))) throw; 20 | _; 21 | } 22 | 23 | function transfer(address _to, uint _value) canTransfer(msg.sender, _value) returns (bool success) { 24 | return super.transfer(_to, _value); 25 | } 26 | 27 | function transferFrom(address _from, address _to, uint _value) canTransfer(_from, _value) returns (bool success) { 28 | return super.transferFrom(_from, _to, _value); 29 | } 30 | 31 | function grantVestedTokens( 32 | address _to, 33 | uint256 _value, 34 | uint64 _start, 35 | uint64 _cliff, 36 | uint64 _vesting) { 37 | 38 | if (_cliff < _start) { 39 | throw; 40 | } 41 | if (_vesting < _start) { 42 | throw; 43 | } 44 | if (_vesting < _cliff) { 45 | throw; 46 | } 47 | 48 | 49 | TokenGrant memory grant = TokenGrant(msg.sender, _value, _cliff, _vesting, _start); 50 | grants[_to].push(grant); 51 | 52 | transfer(_to, _value); 53 | } 54 | 55 | function revokeTokenGrant(address _holder, uint _grantId) { 56 | TokenGrant grant = grants[_holder][_grantId]; 57 | 58 | if (grant.granter != msg.sender) { 59 | throw; 60 | } 61 | uint256 nonVested = nonVestedTokens(grant, uint64(now)); 62 | 63 | // remove grant from array 64 | delete grants[_holder][_grantId]; 65 | grants[_holder][_grantId] = grants[_holder][grants[_holder].length - 1]; 66 | grants[_holder].length -= 1; 67 | 68 | balances[msg.sender] = safeAdd(balances[msg.sender], nonVested); 69 | balances[_holder] = safeSub(balances[_holder], nonVested); 70 | Transfer(_holder, msg.sender, nonVested); 71 | } 72 | 73 | function tokenGrantsCount(address _holder) constant returns (uint index) { 74 | return grants[_holder].length; 75 | } 76 | 77 | function tokenGrant(address _holder, uint _grantId) constant returns (address granter, uint256 value, uint256 vested, uint64 start, uint64 cliff, uint64 vesting) { 78 | TokenGrant grant = grants[_holder][_grantId]; 79 | 80 | granter = grant.granter; 81 | value = grant.value; 82 | start = grant.start; 83 | cliff = grant.cliff; 84 | vesting = grant.vesting; 85 | 86 | vested = vestedTokens(grant, uint64(now)); 87 | } 88 | 89 | function vestedTokens(TokenGrant grant, uint64 time) private constant returns (uint256) { 90 | return calculateVestedTokens( 91 | grant.value, 92 | uint256(time), 93 | uint256(grant.start), 94 | uint256(grant.cliff), 95 | uint256(grant.vesting) 96 | ); 97 | } 98 | 99 | function calculateVestedTokens( 100 | uint256 tokens, 101 | uint256 time, 102 | uint256 start, 103 | uint256 cliff, 104 | uint256 vesting) constant returns (uint256 vestedTokens) 105 | { 106 | 107 | if (time < cliff) { 108 | return 0; 109 | } 110 | if (time > vesting) { 111 | return tokens; 112 | } 113 | 114 | uint256 cliffTokens = safeDiv(safeMul(tokens, safeSub(cliff, start)), safeSub(vesting, start)); 115 | vestedTokens = cliffTokens; 116 | 117 | uint256 vestingTokens = safeSub(tokens, cliffTokens); 118 | 119 | vestedTokens = safeAdd(vestedTokens, safeDiv(safeMul(vestingTokens, safeSub(time, cliff)), safeSub(vesting, start))); 120 | } 121 | 122 | function nonVestedTokens(TokenGrant grant, uint64 time) private constant returns (uint256) { 123 | return safeSub(grant.value, vestedTokens(grant, time)); 124 | } 125 | 126 | function lastTokenIsTransferableDate(address holder) constant public returns (uint64 date) { 127 | date = uint64(now); 128 | uint256 grantIndex = grants[holder].length; 129 | for (uint256 i = 0; i < grantIndex; i++) { 130 | date = max64(grants[holder][i].vesting, date); 131 | } 132 | } 133 | 134 | function transferableTokens(address holder, uint64 time) constant public returns (uint256 nonVested) { 135 | uint256 grantIndex = grants[holder].length; 136 | 137 | for (uint256 i = 0; i < grantIndex; i++) { 138 | nonVested = safeAdd(nonVested, nonVestedTokens(grants[holder][i], time)); 139 | } 140 | 141 | return safeSub(balances[holder], nonVested); 142 | } 143 | } 144 | -------------------------------------------------------------------------------- /installed_contracts/zeppelin/ethpm.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "Manuel Araoz " 4 | ], 5 | "license": "MIT", 6 | "description": "Secure Smart Contract library for Solidity", 7 | "keywords": [ 8 | "solidity", 9 | "ethereum", 10 | "smart", 11 | "contracts", 12 | "security", 13 | "zeppelin" 14 | ], 15 | "links": {}, 16 | "sources": [ 17 | "./contracts/Bounty.sol", 18 | "./contracts/DayLimit.sol", 19 | "./contracts/LimitBalance.sol", 20 | "./contracts/MultisigWallet.sol", 21 | "./contracts/SafeMath.sol", 22 | "./contracts/lifecycle/Killable.sol", 23 | "./contracts/lifecycle/Migrations.sol", 24 | "./contracts/lifecycle/Pausable.sol", 25 | "./contracts/ownership/Claimable.sol", 26 | "./contracts/ownership/Contactable.sol", 27 | "./contracts/ownership/DelayedClaimable.sol", 28 | "./contracts/ownership/Multisig.sol", 29 | "./contracts/ownership/Ownable.sol", 30 | "./contracts/ownership/Shareable.sol", 31 | "./contracts/payment/PullPayment.sol", 32 | "./contracts/token/BasicToken.sol", 33 | "./contracts/token/CrowdsaleToken.sol", 34 | "./contracts/token/ERC20.sol", 35 | "./contracts/token/ERC20Basic.sol", 36 | "./contracts/token/SimpleToken.sol", 37 | "./contracts/token/StandardToken.sol", 38 | "./contracts/token/VestedToken.sol" 39 | ], 40 | "dependencies": {}, 41 | "manifest_version": 1, 42 | "package_name": "zeppelin", 43 | "version": "1.0.4" 44 | } -------------------------------------------------------------------------------- /installed_contracts/zeppelin/lock.json: -------------------------------------------------------------------------------- 1 | {"lockfile_version":"1","package_name":"zeppelin","meta":{"authors":["Manuel Araoz "],"license":"MIT","description":"Secure Smart Contract library for Solidity","keywords":["solidity","ethereum","smart","contracts","security","zeppelin"],"links":{}},"version":"1.0.4","contract_types":{"DayLimit":{"contract_name":"DayLimit","bytecode":"0x6060604052346100005760405160208061012983398101604052515b600081905561003564010000000061009c61003f82021704565b6002555b50610049565b6201518042045b90565b60d2806100576000396000f300606060405263ffffffff60e060020a60003504166367eeba0c811460365780636b0c932d146052578063f059cf2b14606e575b6000565b346000576040608a565b60408051918252519081900360200190f35b3460005760406090565b60408051918252519081900360200190f35b3460005760406096565b60408051918252519081900360200190f35b60005481565b60025481565b60015481565b6201518042045b905600a165627a7a72305820af92a751cebb5f8a04a8f050b843843b633c44e637475fb307e9da4e0f9ba8e90029","abi":[{"constant":true,"inputs":[],"name":"dailyLimit","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"lastDay","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"spentToday","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"inputs":[{"name":"_limit","type":"uint256"}],"payable":false,"type":"constructor"}]},"LimitBalance":{"contract_name":"LimitBalance","bytecode":"0x6060604052346000576040516020806100a083398101604052515b60008190555b505b6070806100306000396000f300606060405263ffffffff60e060020a600035041663a4d66daf81146022575b6000565b34600057602c603e565b60408051918252519081900360200190f35b600054815600a165627a7a723058203a5b44ce7ea45f11bbe0b7aef3f08d3f12d57e3974e85f2c122dfc69638722da0029","abi":[{"constant":true,"inputs":[],"name":"limit","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"inputs":[{"name":"_limit","type":"uint256"}],"payable":false,"type":"constructor"}]},"MultisigWallet":{"contract_name":"MultisigWallet","abi":[{"constant":true,"inputs":[{"name":"_addr","type":"address"}],"name":"isOwner","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":false,"inputs":[],"name":"resetSpentToday","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"dailyLimit","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"lastDay","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_h","type":"bytes32"}],"name":"confirm","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_newLimit","type":"uint256"}],"name":"setDailyLimit","outputs":[],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_value","type":"uint256"},{"name":"_data","type":"bytes"}],"name":"execute","outputs":[{"name":"_r","type":"bytes32"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_operation","type":"bytes32"}],"name":"revoke","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"_operation","type":"bytes32"},{"name":"_owner","type":"address"}],"name":"hasConfirmed","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"ownerIndex","type":"uint256"}],"name":"getOwner","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"}],"name":"kill","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"required","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"}],"name":"changeOwner","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"spentToday","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"inputs":[{"name":"_owners","type":"address[]"},{"name":"_required","type":"uint256"},{"name":"_daylimit","type":"uint256"}],"payable":false,"type":"constructor"},{"payable":true,"type":"fallback"},{"anonymous":false,"inputs":[{"indexed":false,"name":"owner","type":"address"},{"indexed":false,"name":"operation","type":"bytes32"}],"name":"Confirmation","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"owner","type":"address"},{"indexed":false,"name":"operation","type":"bytes32"}],"name":"Revoke","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_from","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"owner","type":"address"},{"indexed":false,"name":"value","type":"uint256"},{"indexed":false,"name":"to","type":"address"},{"indexed":false,"name":"data","type":"bytes"}],"name":"SingleTransact","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"owner","type":"address"},{"indexed":false,"name":"operation","type":"bytes32"},{"indexed":false,"name":"value","type":"uint256"},{"indexed":false,"name":"to","type":"address"},{"indexed":false,"name":"data","type":"bytes"}],"name":"MultiTransact","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"operation","type":"bytes32"},{"indexed":false,"name":"initiator","type":"address"},{"indexed":false,"name":"value","type":"uint256"},{"indexed":false,"name":"to","type":"address"},{"indexed":false,"name":"data","type":"bytes"}],"name":"ConfirmationNeeded","type":"event"}]},"Bounty":{"contract_name":"Bounty","abi":[{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"researchers","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"target","type":"address"}],"name":"claim","outputs":[],"payable":false,"type":"function"},{"constant":false,"inputs":[],"name":"kill","outputs":[],"payable":false,"type":"function"},{"constant":false,"inputs":[],"name":"withdrawPayments","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"constant":false,"inputs":[],"name":"createTarget","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"payments","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"claimed","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"type":"function"},{"payable":true,"type":"fallback"},{"anonymous":false,"inputs":[{"indexed":false,"name":"createdAddress","type":"address"}],"name":"TargetCreated","type":"event"}]},"Target":{"contract_name":"Target","abi":[{"constant":false,"inputs":[],"name":"checkInvariant","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"}]},"SafeMath":{"contract_name":"SafeMath","bytecode":"0x6060604052346000575b60358060166000396000f30060606040525b60005600a165627a7a723058209c738e1e5b188cfa1f8ef54a8048f46de631fdbc670990690d9416755eee53fe0029","abi":[]},"Killable":{"contract_name":"Killable","bytecode":"0x60606040525b60008054600160a060020a03191633600160a060020a03161790555b5b61014c806100316000396000f300606060405263ffffffff60e060020a60003504166341c0e1b5811461003a5780638da5cb5b14610049578063f2fde38b14610072575b610000565b346100005761004761008d565b005b34610000576100566100b9565b60408051600160a060020a039092168252519081900360200190f35b3461000057610047600160a060020a03600435166100c8565b005b60005433600160a060020a039081169116146100a857610000565b600054600160a060020a0316ff5b5b565b600054600160a060020a031681565b60005433600160a060020a039081169116146100e357610000565b600160a060020a0381161561011b576000805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0383161790555b5b5b505600a165627a7a7230582051ab692e3d4665017b504f074df8b5ce268c5282b0fc57084169dd66c09e8acc0029","abi":[{"constant":false,"inputs":[],"name":"kill","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"type":"function"}]},"Migrations":{"contract_name":"Migrations","bytecode":"0x60606040525b60008054600160a060020a03191633600160a060020a03161790555b5b610214806100316000396000f300606060405263ffffffff60e060020a6000350416630900f01081146100505780638da5cb5b1461006b578063f2fde38b14610094578063fbdbad3c146100af578063fdacd576146100ce575b610000565b3461000057610069600160a060020a03600435166100e0565b005b3461000057610078610156565b60408051600160a060020a039092168252519081900360200190f35b3461000057610069600160a060020a0360043516610165565b005b34610000576100bc6101bd565b60408051918252519081900360200190f35b34610000576100696004356101c3565b005b6000805433600160a060020a039081169116146100fc57610000565b81905080600160a060020a031663fdacd5766001546040518263ffffffff1660e060020a02815260040180828152602001915050600060405180830381600087803b156100005760325a03f115610000575050505b5b5050565b600054600160a060020a031681565b60005433600160a060020a0390811691161461018057610000565b600160a060020a038116156101b8576000805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0383161790555b5b5b50565b60015481565b60005433600160a060020a039081169116146101de57610000565b60018190555b5b505600a165627a7a72305820c4cc5127f514026e5140957c723c1866ff467cb2a2824df850b8a9d4dccc1c650029","abi":[{"constant":false,"inputs":[{"name":"newAddress","type":"address"}],"name":"upgrade","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"lastCompletedMigration","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"completed","type":"uint256"}],"name":"setCompleted","outputs":[],"payable":false,"type":"function"}]},"Pausable":{"contract_name":"Pausable","bytecode":"0x60606040525b60008054600160a060020a03191633600160a060020a03161790555b5b61020a806100316000396000f300606060405263ffffffff60e060020a60003504166363a599a4811461005057806375f12b211461005f57806386d1a69f146100805780638da5cb5b1461008f578063f2fde38b146100b8575b610000565b346100005761005d6100d3565b005b346100005761006c610116565b604080519115158252519081900360200190f35b346100005761005d610126565b005b346100005761009c610177565b60408051600160a060020a039092168252519081900360200190f35b346100005761005d600160a060020a0360043516610186565b005b60005433600160a060020a039081169116146100ee57610000565b6000805474ff0000000000000000000000000000000000000000191660a060020a1790555b5b565b60005460a060020a900460ff1681565b60005433600160a060020a0390811691161461014157610000565b60005460a060020a900460ff1615610113576000805474ff0000000000000000000000000000000000000000191690555b5b5b5b565b600054600160a060020a031681565b60005433600160a060020a039081169116146101a157610000565b600160a060020a038116156101d9576000805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0383161790555b5b5b505600a165627a7a7230582051a39a49a584355f3268d911815cb4c6381f1cfbe6dcb24e4f279e4a61ab74030029","abi":[{"constant":false,"inputs":[],"name":"emergencyStop","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"stopped","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":false,"inputs":[],"name":"release","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"type":"function"}]},"PullPayment":{"contract_name":"PullPayment","bytecode":"0x606060405234610000575b610118806100196000396000f300606060405263ffffffff60e060020a6000350416636103d70b8114602c578063e2982c21146038575b6000565b3460005760366060565b005b34600057604e600160a060020a036004351660da565b60408051918252519081900360200190f35b33600160a060020a0381166000908152602081905260409020548015156084576000565b8030600160a060020a03163110156099576000565b600160a060020a0382166000818152602081905260408082208290555183156108fc0291849190818181858888f19350505050151560d5576000565b5b5050565b600060208190529081526040902054815600a165627a7a72305820c017f7fa25a090e0fa4092a0dcf3fba8a595534d0b15d0b14a06caccb19bff830029","abi":[{"constant":false,"inputs":[],"name":"withdrawPayments","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"payments","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"}]},"Contactable":{"contract_name":"Contactable","bytecode":"0x60606040525b60008054600160a060020a03191633600160a060020a03161790555b5b610347806100316000396000f300606060405263ffffffff60e060020a60003504166336f7ab5e81146100455780638da5cb5b146100d2578063b967a52e146100fb578063f2fde38b14610150575b610000565b346100005761005261016b565b604080516020808252835181830152835191928392908301918501908083838215610098575b80518252602083111561009857601f199092019160209182019101610078565b505050905090810190601f1680156100c45780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34610000576100df6101f8565b60408051600160a060020a039092168252519081900360200190f35b346100005761014e600480803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284375094965061020795505050505050565b005b346100005761014e600160a060020a03600435166102c3565b005b60018054604080516020600284861615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156101f05780601f106101c5576101008083540402835291602001916101f0565b820191906000526020600020905b8154815290600101906020018083116101d357829003601f168201915b505050505081565b600054600160a060020a031681565b60005433600160a060020a0390811691161461022257610000565b8060019080519060200190828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061026e57805160ff191683800117855561029b565b8280016001018555821561029b579182015b8281111561029b578251825591602001919060010190610280565b5b506102bc9291505b808211156102b857600081556001016102a4565b5090565b50505b5b50565b60005433600160a060020a039081169116146102de57610000565b600160a060020a038116156102bf576000805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0383161790555b5b5b505600a165627a7a723058204112f92e8a96ac7265951c50d239abee4f3858bbf3e6c8ad37f211050a5d7f000029","abi":[{"constant":true,"inputs":[],"name":"contactInformation","outputs":[{"name":"","type":"string"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"info","type":"string"}],"name":"setContactInformation","outputs":[],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"type":"function"}]},"Claimable":{"contract_name":"Claimable","bytecode":"0x60606040525b60008054600160a060020a03191633600160a060020a03161790555b5b6101a4806100316000396000f300606060405263ffffffff60e060020a6000350416634e71e0c881146100455780638da5cb5b14610054578063e30c39781461007d578063f2fde38b146100a6575b610000565b34610000576100526100c1565b005b3461000057610061610112565b60408051600160a060020a039092168252519081900360200190f35b3461000057610061610121565b60408051600160a060020a039092168252519081900360200190f35b3461000057610052600160a060020a0360043516610130565b005b60015433600160a060020a039081169116146100dc57610000565b600180546000805473ffffffffffffffffffffffffffffffffffffffff19908116600160a060020a038416179091551690555b5b565b600054600160a060020a031681565b600154600160a060020a031681565b60005433600160a060020a0390811691161461014b57610000565b6001805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0383161790555b5b505600a165627a7a72305820be915b7ef672a3786065fb166cae8942971cc9b78d057079e318dc3beaf2caf00029","abi":[{"constant":false,"inputs":[],"name":"claimOwnership","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"pendingOwner","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"type":"function"}]},"DelayedClaimable":{"contract_name":"DelayedClaimable","bytecode":"0x60606040525b60008054600160a060020a03191633600160a060020a03161790555b5b610282806100316000396000f300606060405236156100675763ffffffff60e060020a6000350416634e71e0c8811461006c5780638da5cb5b1461007b578063be9a6555146100a4578063c4590d3f146100c3578063e30c3978146100d8578063efbe1c1c14610101578063f2fde38b14610120575b610000565b346100005761007961013b565b005b34610000576100886101ac565b60408051600160a060020a039092168252519081900360200190f35b34610000576100b16101bb565b60408051918252519081900360200190f35b34610000576100796004356024356101c1565b005b34610000576100886101f9565b60408051600160a060020a039092168252519081900360200190f35b34610000576100b1610208565b60408051918252519081900360200190f35b3461000057610079600160a060020a036004351661020e565b005b60015433600160a060020a0390811691161461015657610000565b600254431180610167575060035443105b1561017157610000565b600180546000805473ffffffffffffffffffffffffffffffffffffffff19908116600160a060020a0384161782559091169091556002555b5b565b600054600160a060020a031681565b60035481565b60005433600160a060020a039081169116146101dc57610000565b808211156101e957610000565b600281905560038290555b5b5050565b600154600160a060020a031681565b60025481565b60005433600160a060020a0390811691161461022957610000565b6001805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0383161790555b5b505600a165627a7a72305820f9571ddb02378aff5e4c3fe6f809e73a2f15d295d49ddc6604c70b5e2464e2d40029","abi":[{"constant":false,"inputs":[],"name":"claimOwnership","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"start","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_start","type":"uint256"},{"name":"_end","type":"uint256"}],"name":"setLimits","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"pendingOwner","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"end","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"type":"function"}]},"Multisig":{"contract_name":"Multisig","abi":[{"constant":false,"inputs":[{"name":"_h","type":"bytes32"}],"name":"confirm","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_value","type":"uint256"},{"name":"_data","type":"bytes"}],"name":"execute","outputs":[{"name":"","type":"bytes32"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"}],"name":"changeOwner","outputs":[],"payable":false,"type":"function"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_from","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"owner","type":"address"},{"indexed":false,"name":"value","type":"uint256"},{"indexed":false,"name":"to","type":"address"},{"indexed":false,"name":"data","type":"bytes"}],"name":"SingleTransact","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"owner","type":"address"},{"indexed":false,"name":"operation","type":"bytes32"},{"indexed":false,"name":"value","type":"uint256"},{"indexed":false,"name":"to","type":"address"},{"indexed":false,"name":"data","type":"bytes"}],"name":"MultiTransact","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"operation","type":"bytes32"},{"indexed":false,"name":"initiator","type":"address"},{"indexed":false,"name":"value","type":"uint256"},{"indexed":false,"name":"to","type":"address"},{"indexed":false,"name":"data","type":"bytes"}],"name":"ConfirmationNeeded","type":"event"}]},"Ownable":{"contract_name":"Ownable","bytecode":"0x606060405234610000575b60008054600160a060020a03191633600160a060020a03161790555b5b60fa806100356000396000f300606060405263ffffffff60e060020a6000350416638da5cb5b8114602c578063f2fde38b146052575b6000565b346000576036606a565b60408051600160a060020a039092168252519081900360200190f35b346000576068600160a060020a03600435166079565b005b600054600160a060020a031681565b60005433600160a060020a039081169116146092576000565b600160a060020a0381161560c9576000805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0383161790555b5b5b505600a165627a7a7230582012c103608a96de98da02560514aadbfed18f42b57ebfecc4f1da76c51217c1870029","abi":[{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"type":"function"},{"inputs":[],"payable":false,"type":"constructor"}]},"Shareable":{"contract_name":"Shareable","bytecode":"0x6060604052346100005760405161037038038061037083398101604052805160208201519101905b600033600160a060020a03166002825b505550600160a060020a033316600090815261010160205260408120600190555b82518110156100da57828181518110156100005790602001906020020151600160a060020a0316600182600201610100811015610000570160005b5081905550806002016101016000858481518110156100005790602001906020020151600160a060020a03168152602001908152602001600020819055505b600101610058565b60008290555b5050505b61027d806100f36000396000f300606060405263ffffffff60e060020a6000350416632f54bf6e8114610050578063b75c7dc61461007d578063c2cf73261461008f578063c41a360a146100bf578063dc8452cd146100eb575b610000565b3461000057610069600160a060020a036004351661010a565b604080519115158252519081900360200190f35b346100005761008d60043561012b565b005b3461000057610069600435600160a060020a03602435166101d6565b604080519115158252519081900360200190f35b34610000576100cf60043561022b565b60408051600160a060020a039092168252519081900360200190f35b34610000576100f861024b565b60408051918252519081900360200190f35b600160a060020a03811660009081526101016020526040812054115b919050565b600160a060020a033316600090815261010160205260408120549080821515610153576101cf565b50506000828152610102602052604081206001810154600284900a9290831611156101cf5780546001908101825581018054839003905560408051600160a060020a03331681526020810186905281517fc7fb647e59b18047309aa15aad418e5d7ca96d173ad704f1031a2c3d7591734b929181900390910190a15b5b50505050565b600082815261010260209081526040808320600160a060020a03851684526101019092528220548281151561020e5760009350610222565b8160020a9050808360010154166000141593505b50505092915050565b6000600182600101610100811015610000570160005b505490505b919050565b600054815600a165627a7a7230582037eda0b13a780f1fd1f715acc4735016e5f3d5bd9a83920934894c87b156a8300029","abi":[{"constant":true,"inputs":[{"name":"_addr","type":"address"}],"name":"isOwner","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_operation","type":"bytes32"}],"name":"revoke","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"_operation","type":"bytes32"},{"name":"_owner","type":"address"}],"name":"hasConfirmed","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"ownerIndex","type":"uint256"}],"name":"getOwner","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"required","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"inputs":[{"name":"_owners","type":"address[]"},{"name":"_required","type":"uint256"}],"payable":false,"type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"name":"owner","type":"address"},{"indexed":false,"name":"operation","type":"bytes32"}],"name":"Confirmation","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"owner","type":"address"},{"indexed":false,"name":"operation","type":"bytes32"}],"name":"Revoke","type":"event"}]},"BasicToken":{"contract_name":"BasicToken","bytecode":"0x606060405234610000575b6101f3806100196000396000f300606060405263ffffffff60e060020a60003504166318160ddd811461003a57806370a0823114610059578063a9059cbb14610084575b610000565b34610000576100476100a2565b60408051918252519081900360200190f35b3461000057610047600160a060020a03600435166100a8565b60408051918252519081900360200190f35b34610000576100a0600160a060020a03600435166024356100c7565b005b60005481565b600160a060020a0381166000908152600160205260409020545b919050565b600160a060020a0333166000908152600160205260409020546100ea9082610176565b600160a060020a033381166000908152600160205260408082209390935590841681522054610119908261018f565b600160a060020a038084166000818152600160209081526040918290209490945580518581529051919333909316927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a35b5050565b6000610184838311156101b7565b508082035b92915050565b60008282016101ac8482108015906101a75750838210155b6101b7565b8091505b5092915050565b8015156101c357610000565b5b505600a165627a7a723058205915901f41e2c0f7724085a2b208cd44095d7a1d60211a9c0d9d311c6d2626af0029","abi":[{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"}],"name":"balanceOf","outputs":[{"name":"balance","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transfer","outputs":[],"payable":false,"type":"function"},{"anonymous":false,"inputs":[{"indexed":true,"name":"from","type":"address"},{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Transfer","type":"event"}]},"CrowdsaleToken":{"contract_name":"CrowdsaleToken","bytecode":"0x60a0604052600e60608190527f43726f776473616c65546f6b656e00000000000000000000000000000000000060809081526003805460008290527f43726f776473616c65546f6b656e00000000000000000000000000000000001c825590927fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b602060026001851615610100026000190190941693909304601f01929092048201929091906100d7565b828001600101855582156100d7579182015b828111156100d75782518255916020019190600101906100bc565b5b506100f89291505b808211156100f457600081556001016100e0565b5090565b50506040805180820190915260038082527f435257000000000000000000000000000000000000000000000000000000000060209283019081526004805460008290528251600660ff1990911617825590937f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b60026001841615610100026000190190931692909204601f0104810192916101bb565b828001600101855582156101bb579182015b828111156101bb5782518255916020019190600101906101a0565b5b506101dc9291505b808211156100f457600081556001016100e0565b5090565b505060126005556101f460065534610000575b6107da806101fe6000396000f300606060405236156100935763ffffffff60e060020a60003504166306fdde0381146100a5578063095ea7b31461013257806318160ddd1461016257806323b872dd14610181578063313ce567146101b757806370a08231146101d657806395d89b411461020157806398d5fdca1461028e578063a9059cbb146102ad578063cedbbeee146102dd578063dd62ed3e146102f3575b6100a35b6100a033610324565b5b565b005b34610000576100b2610394565b6040805160208082528351818301528351919283929083019185019080838382156100f8575b8051825260208311156100f857601f1990920191602091820191016100d8565b505050905090810190601f1680156101245780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b346100005761014e600160a060020a0360043516602435610422565b604080519115158252519081900360200190f35b346100005761016f61048d565b60408051918252519081900360200190f35b346100005761014e600160a060020a0360043581169060243516604435610493565b604080519115158252519081900360200190f35b346100005761016f610596565b60408051918252519081900360200190f35b346100005761016f600160a060020a036004351661059c565b60408051918252519081900360200190f35b34610000576100b26105bb565b6040805160208082528351818301528351919283929083019185019080838382156100f8575b8051825260208311156100f857601f1990920191602091820191016100d8565b505050905090810190601f1680156101245780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b346100005761016f610649565b60408051918252519081900360200190f35b346100005761014e600160a060020a0360043516602435610650565b604080519115158252519081900360200190f35b6100a3600160a060020a0360043516610324565b005b346100005761016f600160a060020a0360043581169060243516610704565b60408051918252519081900360200190f35b600034151561033257610000565b6103433461033e610649565b610731565b90506103516000548261075d565b6000908155600160a060020a038316815260016020526040902054610376908261075d565b600160a060020a0383166000908152600160205260409020555b5050565b6003805460408051602060026001851615610100026000190190941693909304601f8101849004840282018401909252818152929183018282801561041a5780601f106103ef5761010080835404028352916020019161041a565b820191906000526020600020905b8154815290600101906020018083116103fd57829003601f168201915b505050505081565b600160a060020a03338116600081815260026020908152604080832094871680845294825280832086905580518681529051929493927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925929181900390910190a35060015b92915050565b60005481565b600160a060020a0380841660009081526002602090815260408083203385168452825280832054938616835260019091528120549091906104d4908461075d565b600160a060020a0380861660009081526001602052604080822093909355908716815220546105039084610785565b600160a060020a0386166000908152600160205260409020556105268184610785565b600160a060020a038087166000818152600260209081526040808320338616845282529182902094909455805187815290519288169391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929181900390910190a3600191505b509392505050565b60055481565b600160a060020a0381166000908152600160205260409020545b919050565b6004805460408051602060026001851615610100026000190190941693909304601f8101849004840282018401909252818152929183018282801561041a5780601f106103ef5761010080835404028352916020019161041a565b820191906000526020600020905b8154815290600101906020018083116103fd57829003601f168201915b505050505081565b6006545b90565b600160a060020a0333166000908152600160205260408120546106739083610785565b600160a060020a0333811660009081526001602052604080822093909355908516815220546106a2908361075d565b600160a060020a038085166000818152600160209081526040918290209490945580518681529051919333909316927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a35060015b92915050565b600160a060020a038083166000908152600260209081526040808320938516835292905220545b92915050565b600082820261075284158061074d575083858381156100005704145b61079e565b8091505b5092915050565b600082820161075284821080159061074d5750838210155b61079e565b8091505b5092915050565b60006107938383111561079e565b508082035b92915050565b8015156107aa57610000565b5b505600a165627a7a72305820364449c6b837343efc9ac6235f9212e7da22ece6c9c559d5296a5024f3cf3b910029","abi":[{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_spender","type":"address"},{"name":"_value","type":"uint256"}],"name":"approve","outputs":[{"name":"success","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"success","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"}],"name":"balanceOf","outputs":[{"name":"balance","type":"uint256"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"getPrice","outputs":[{"name":"result","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transfer","outputs":[{"name":"success","type":"bool"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"recipient","type":"address"}],"name":"createTokens","outputs":[],"payable":true,"type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"},{"name":"_spender","type":"address"}],"name":"allowance","outputs":[{"name":"remaining","type":"uint256"}],"payable":false,"type":"function"},{"payable":true,"type":"fallback"},{"anonymous":false,"inputs":[{"indexed":true,"name":"from","type":"address"},{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"owner","type":"address"},{"indexed":true,"name":"spender","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Approval","type":"event"}]},"ERC20":{"contract_name":"ERC20","abi":[{"constant":false,"inputs":[{"name":"spender","type":"address"},{"name":"value","type":"uint256"}],"name":"approve","outputs":[{"name":"ok","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"from","type":"address"},{"name":"to","type":"address"},{"name":"value","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"ok","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"who","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"to","type":"address"},{"name":"value","type":"uint256"}],"name":"transfer","outputs":[{"name":"ok","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"owner","type":"address"},{"name":"spender","type":"address"}],"name":"allowance","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"anonymous":false,"inputs":[{"indexed":true,"name":"from","type":"address"},{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"owner","type":"address"},{"indexed":true,"name":"spender","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Approval","type":"event"}]},"ERC20Basic":{"contract_name":"ERC20Basic","abi":[{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"who","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"to","type":"address"},{"name":"value","type":"uint256"}],"name":"transfer","outputs":[],"payable":false,"type":"function"},{"anonymous":false,"inputs":[{"indexed":true,"name":"from","type":"address"},{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Transfer","type":"event"}]},"SimpleToken":{"contract_name":"SimpleToken","bytecode":"0x60a0604052600b60608190527f53696d706c65546f6b656e00000000000000000000000000000000000000000060809081526003805460008290527f53696d706c65546f6b656e000000000000000000000000000000000000000016825590927fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b602060026001851615610100026000190190941693909304601f01929092048201929091906100d7565b828001600101855582156100d7579182015b828111156100d75782518255916020019190600101906100bc565b5b506100f89291505b808211156100f457600081556001016100e0565b5090565b50506040805180820190915260038082527f53494d000000000000000000000000000000000000000000000000000000000060209283019081526004805460008290528251600660ff1990911617825590937f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b60026001841615610100026000190190931692909204601f0104810192916101bb565b828001600101855582156101bb579182015b828111156101bb5782518255916020019190600101906101a0565b5b506101dc9291505b808211156100f457600081556001016100e0565b5090565b5050601260055561271060065534610000575b6006546000818155600160a060020a0333168152600160205260409020555b5b61070f8061021e6000396000f300606060405236156100885763ffffffff60e060020a60003504166306fdde03811461008d578063095ea7b31461011a57806318160ddd1461014a57806323b872dd146101695780632ff2e9dc1461019f578063313ce567146101be57806370a08231146101dd57806395d89b4114610208578063a9059cbb14610295578063dd62ed3e146102c5575b610000565b346100005761009a6102f6565b6040805160208082528351818301528351919283929083019185019080838382156100e0575b8051825260208311156100e057601f1990920191602091820191016100c0565b505050905090810190601f16801561010c5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3461000057610136600160a060020a0360043516602435610384565b604080519115158252519081900360200190f35b34610000576101576103ef565b60408051918252519081900360200190f35b3461000057610136600160a060020a03600435811690602435166044356103f5565b604080519115158252519081900360200190f35b34610000576101576104f8565b60408051918252519081900360200190f35b34610000576101576104fe565b60408051918252519081900360200190f35b3461000057610157600160a060020a0360043516610504565b60408051918252519081900360200190f35b346100005761009a610523565b6040805160208082528351818301528351919283929083019185019080838382156100e0575b8051825260208311156100e057601f1990920191602091820191016100c0565b505050905090810190601f16801561010c5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3461000057610136600160a060020a03600435166024356105b1565b604080519115158252519081900360200190f35b3461000057610157600160a060020a0360043581169060243516610665565b60408051918252519081900360200190f35b6003805460408051602060026001851615610100026000190190941693909304601f8101849004840282018401909252818152929183018282801561037c5780601f106103515761010080835404028352916020019161037c565b820191906000526020600020905b81548152906001019060200180831161035f57829003601f168201915b505050505081565b600160a060020a03338116600081815260026020908152604080832094871680845294825280832086905580518681529051929493927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925929181900390910190a35060015b92915050565b60005481565b600160a060020a0380841660009081526002602090815260408083203385168452825280832054938616835260019091528120549091906104369084610692565b600160a060020a03808616600090815260016020526040808220939093559087168152205461046590846106ba565b600160a060020a03861660009081526001602052604090205561048881846106ba565b600160a060020a038087166000818152600260209081526040808320338616845282529182902094909455805187815290519288169391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929181900390910190a3600191505b509392505050565b60065481565b60055481565b600160a060020a0381166000908152600160205260409020545b919050565b6004805460408051602060026001851615610100026000190190941693909304601f8101849004840282018401909252818152929183018282801561037c5780601f106103515761010080835404028352916020019161037c565b820191906000526020600020905b81548152906001019060200180831161035f57829003601f168201915b505050505081565b600160a060020a0333166000908152600160205260408120546105d490836106ba565b600160a060020a0333811660009081526001602052604080822093909355908516815220546106039083610692565b600160a060020a038085166000818152600160209081526040918290209490945580518681529051919333909316927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a35060015b92915050565b600160a060020a038083166000908152600260209081526040808320938516835292905220545b92915050565b60008282016106af8482108015906106aa5750838210155b6106d3565b8091505b5092915050565b60006106c8838311156106d3565b508082035b92915050565b8015156106df57610000565b5b505600a165627a7a723058202ee84497f6e30ff7a6215ba1d3201c6bd9fd24e235c2d527087c7fa2d781c4d80029","abi":[{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_spender","type":"address"},{"name":"_value","type":"uint256"}],"name":"approve","outputs":[{"name":"success","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"success","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"INITIAL_SUPPLY","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"}],"name":"balanceOf","outputs":[{"name":"balance","type":"uint256"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transfer","outputs":[{"name":"success","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"},{"name":"_spender","type":"address"}],"name":"allowance","outputs":[{"name":"remaining","type":"uint256"}],"payable":false,"type":"function"},{"inputs":[],"payable":false,"type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"name":"from","type":"address"},{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"owner","type":"address"},{"indexed":true,"name":"spender","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Approval","type":"event"}]},"StandardToken":{"contract_name":"StandardToken","bytecode":"0x606060405234610000575b610463806100196000396000f3006060604052361561005c5763ffffffff60e060020a600035041663095ea7b3811461006157806318160ddd1461009157806323b872dd146100b057806370a08231146100e6578063a9059cbb14610111578063dd62ed3e14610141575b610000565b346100005761007d600160a060020a0360043516602435610172565b604080519115158252519081900360200190f35b346100005761009e6101dd565b60408051918252519081900360200190f35b346100005761007d600160a060020a03600435811690602435166044356101e3565b604080519115158252519081900360200190f35b346100005761009e600160a060020a03600435166102e6565b60408051918252519081900360200190f35b346100005761007d600160a060020a0360043516602435610305565b604080519115158252519081900360200190f35b346100005761009e600160a060020a03600435811690602435166103b9565b60408051918252519081900360200190f35b600160a060020a03338116600081815260026020908152604080832094871680845294825280832086905580518681529051929493927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925929181900390910190a35060015b92915050565b60005481565b600160a060020a03808416600090815260026020908152604080832033851684528252808320549386168352600190915281205490919061022490846103e6565b600160a060020a038086166000908152600160205260408082209390935590871681522054610253908461040e565b600160a060020a038616600090815260016020526040902055610276818461040e565b600160a060020a038087166000818152600260209081526040808320338616845282529182902094909455805187815290519288169391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929181900390910190a3600191505b509392505050565b600160a060020a0381166000908152600160205260409020545b919050565b600160a060020a033316600090815260016020526040812054610328908361040e565b600160a060020a03338116600090815260016020526040808220939093559085168152205461035790836103e6565b600160a060020a038085166000818152600160209081526040918290209490945580518681529051919333909316927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a35060015b92915050565b600160a060020a038083166000908152600260209081526040808320938516835292905220545b92915050565b60008282016104038482108015906103fe5750838210155b610427565b8091505b5092915050565b600061041c83831115610427565b508082035b92915050565b80151561043357610000565b5b505600a165627a7a72305820c9dd1fc2c3f3415d7ae214300fc70e3423670b54cea1e62e8134524537dc3e160029","abi":[{"constant":false,"inputs":[{"name":"_spender","type":"address"},{"name":"_value","type":"uint256"}],"name":"approve","outputs":[{"name":"success","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"success","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"}],"name":"balanceOf","outputs":[{"name":"balance","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transfer","outputs":[{"name":"success","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"},{"name":"_spender","type":"address"}],"name":"allowance","outputs":[{"name":"remaining","type":"uint256"}],"payable":false,"type":"function"},{"anonymous":false,"inputs":[{"indexed":true,"name":"from","type":"address"},{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"owner","type":"address"},{"indexed":true,"name":"spender","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Approval","type":"event"}]},"VestedToken":{"contract_name":"VestedToken","bytecode":"0x606060405234610000575b6110ff806100196000396000f300606060405236156100b35763ffffffff60e060020a600035041662e1986d81146100b857806302a72a4c146100ef578063095ea7b31461011a57806318160ddd1461014a57806323b872dd146101695780632c71e60a1461019f578063600e85b7146101fd5780636c182e991461026257806370a0823114610298578063a9059cbb146102c3578063d347c205146102f3578063dd62ed3e1461032b578063df3c211b1461035c578063eb944e4c1461038a575b610000565b34610000576100ed600160a060020a036004351660243567ffffffffffffffff604435811690606435811690608435166103a8565b005b3461000057610108600160a060020a03600435166105b9565b60408051918252519081900360200190f35b3461000057610136600160a060020a03600435166024356105d8565b604080519115158252519081900360200190f35b3461000057610108610643565b60408051918252519081900360200190f35b3461000057610136600160a060020a0360043581169060243516604435610649565b604080519115158252519081900360200190f35b34610000576101bb600160a060020a036004351660243561067b565b60408051600160a060020a039096168652602086019490945267ffffffffffffffff928316858501529082166060850152166080830152519081900360a00190f35b3461000057610219600160a060020a03600435166024356106e5565b60408051600160a060020a03909716875260208701959095528585019390935267ffffffffffffffff9182166060860152811660808501521660a0830152519081900360c00190f35b346100005761027b600160a060020a03600435166107ba565b6040805167ffffffffffffffff9092168252519081900360200190f35b3461000057610108600160a060020a0360043516610846565b60408051918252519081900360200190f35b3461000057610136600160a060020a0360043516602435610865565b604080519115158252519081900360200190f35b3461000057610108600160a060020a036004351667ffffffffffffffff60243516610895565b60408051918252519081900360200190f35b3461000057610108600160a060020a0360043581169060243516610999565b60408051918252519081900360200190f35b34610000576101086004356024356044356064356084356109c6565b60408051918252519081900360200190f35b34610000576100ed600160a060020a0360043516602435610a5f565b005b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff84811690841610156103ed57610000565b8367ffffffffffffffff168267ffffffffffffffff16101561040e57610000565b8267ffffffffffffffff168267ffffffffffffffff16101561042f57610000565b506040805160a081018252600160a060020a033381168252602080830188905267ffffffffffffffff80871684860152858116606085015287166080840152908816600090815260039091529190912080546001810180835582818380158290116104ea576003028160030283600052602060002091820191016104ea91905b808211156104e6578054600160a060020a031916815560006001820155600281018054600160c060020a03191690556003016104af565b5090565b5b505050916000526020600020906003020160005b5082518154600160a060020a031916600160a060020a03909116178155602083015160018201556040830151600290910180546060850151608086015167ffffffffffffffff1990921667ffffffffffffffff948516176fffffffffffffffff00000000000000001916604060020a918516919091021777ffffffffffffffff000000000000000000000000000000001916608060020a9390911692909202919091179055506105af8686610865565b505b505050505050565b600160a060020a0381166000908152600360205260409020545b919050565b600160a060020a03338116600081815260026020908152604080832094871680845294825280832086905580518681529051929493927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925929181900390910190a35060015b92915050565b60005481565b600083826106578242610895565b81111561066357610000565b61066e868686610dc1565b92505b5b50509392505050565b600360205281600052604060002081815481101561000057906000526020600020906003020160005b5080546001820154600290920154600160a060020a03909116935090915067ffffffffffffffff80821691604060020a8104821691608060020a9091041685565b6000600060006000600060006000600360008a600160a060020a0316600160a060020a0316815260200190815260200160002088815481101561000057906000526020600020906003020160005b508054600182015460028301546040805160a081018252600160a060020a039094168085526020850184905267ffffffffffffffff808416928601839052604060020a8404811660608701819052608060020a9094041660808601819052909c50929a5091975090955093509091506107ac9042610ec4565b94505b509295509295509295565b600160a060020a03811660009081526003602052604081205442915b8181101561083e57600160a060020a038416600090815260036020526040902080546108339190839081101561000057906000526020600020906003020160005b5060020154604060020a900467ffffffffffffffff1684610f14565b92505b6001016107d6565b5b5050919050565b600160a060020a0381166000908152600160205260409020545b919050565b600033826108738242610895565b81111561087f57610000565b6108898585610f43565b92505b5b505092915050565b600160a060020a038216600090815260036020526040812054815b8181101561096b576109608361095b6003600089600160a060020a0316600160a060020a0316815260200190815260200160002084815481101561000057906000526020600020906003020160005b506040805160a0810182528254600160a060020a031681526001830154602082015260029092015467ffffffffffffffff80821692840192909252604060020a810482166060840152608060020a900416608082015287610ff7565b611019565b92505b6001016108b0565b600160a060020a0385166000908152600160205260409020546108899084611041565b92505b505092915050565b600160a060020a038083166000908152600260209081526040808320938516835292905220545b92915050565b600060006000848710156109dd5760009250610a54565b838711156109ed57879250610a54565b610a12610a03896109fe888a611041565b61105a565b610a0d8689611041565b611086565b9150819250610a218883611041565b9050610a518361095b610a3d846109fe8c8b611041565b61105a565b610a0d888b611041565b611086565b611019565b92505b505095945050505050565b600160a060020a03821660009081526003602052604081208054829190849081101561000057906000526020600020906003020160005b50805490925033600160a060020a03908116911614610ab457610000565b6040805160a0810182528354600160a060020a0316815260018401546020820152600284015467ffffffffffffffff80821693830193909352604060020a810483166060830152608060020a90049091166080820152610b149042610ff7565b600160a060020a0385166000908152600360205260409020805491925090849081101561000057906000526020600020906003020160005b508054600160a060020a031916815560006001820181905560029091018054600160c060020a0319169055600160a060020a0385168152600360205260409020805460001981019081101561000057906000526020600020906003020160005b50600160a060020a03851660009081526003602052604090208054859081101561000057906000526020600020906003020160005b5081548154600160a060020a031916600160a060020a03918216178255600180840154908301556002928301805493909201805467ffffffffffffffff191667ffffffffffffffff948516178082558354604060020a908190048616026fffffffffffffffff000000000000000019909116178082559254608060020a9081900490941690930277ffffffffffffffff0000000000000000000000000000000019909216919091179091558416600090815260036020526040902080546000198101808355919082908015829011610d0957600302816003028360005260206000209182019101610d0991905b808211156104e6578054600160a060020a031916815560006001820155600281018054600160c060020a03191690556003016104af565b5090565b5b505050600160a060020a033316600090815260016020526040902054610d31915082611019565b600160a060020a033381166000908152600160205260408082209390935590861681522054610d609082611041565b600160a060020a038086166000818152600160209081526040918290209490945580518581529051339093169391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929181900390910190a35b50505050565b600160a060020a038084166000908152600260209081526040808320338516845282528083205493861683526001909152812054909190610e029084611019565b600160a060020a038086166000908152600160205260408082209390935590871681522054610e319084611041565b600160a060020a038616600090815260016020526040902055610e548184611041565b600160a060020a038087166000818152600260209081526040808320338616845282529182902094909455805187815290519288169391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929181900390910190a3600191505b509392505050565b6000610f0b83602001518367ffffffffffffffff16856080015167ffffffffffffffff16866040015167ffffffffffffffff16876060015167ffffffffffffffff166109c6565b90505b92915050565b60008167ffffffffffffffff168367ffffffffffffffff161015610f385781610f0b565b825b90505b92915050565b600160a060020a033316600090815260016020526040812054610f669083611041565b600160a060020a033381166000908152600160205260408082209390935590851681522054610f959083611019565b600160a060020a038085166000818152600160209081526040918290209490945580518681529051919333909316927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a35060015b92915050565b6000610f0b836020015161100b8585610ec4565b611041565b90505b92915050565b60008282016110368482108015906110315750838210155b6110c3565b8091505b5092915050565b600061104f838311156110c3565b508082035b92915050565b6000828202611036841580611031575083858381156100005704145b6110c3565b8091505b5092915050565b60006000611096600084116110c3565b82848115610000570490506110368385811561000057068285020185146110c3565b8091505b5092915050565b8015156110cf57610000565b5b505600a165627a7a72305820c45efc3607ba7648b29c688c9499d2ca68bcf32a88396a48cd937cc83ef1e1ff0029","abi":[{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_value","type":"uint256"},{"name":"_start","type":"uint64"},{"name":"_cliff","type":"uint64"},{"name":"_vesting","type":"uint64"}],"name":"grantVestedTokens","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"_holder","type":"address"}],"name":"tokenGrantsCount","outputs":[{"name":"index","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_spender","type":"address"},{"name":"_value","type":"uint256"}],"name":"approve","outputs":[{"name":"success","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"success","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"},{"name":"","type":"uint256"}],"name":"grants","outputs":[{"name":"granter","type":"address"},{"name":"value","type":"uint256"},{"name":"cliff","type":"uint64"},{"name":"vesting","type":"uint64"},{"name":"start","type":"uint64"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"_holder","type":"address"},{"name":"_grantId","type":"uint256"}],"name":"tokenGrant","outputs":[{"name":"granter","type":"address"},{"name":"value","type":"uint256"},{"name":"vested","type":"uint256"},{"name":"start","type":"uint64"},{"name":"cliff","type":"uint64"},{"name":"vesting","type":"uint64"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"holder","type":"address"}],"name":"lastTokenIsTransferableDate","outputs":[{"name":"date","type":"uint64"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"}],"name":"balanceOf","outputs":[{"name":"balance","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transfer","outputs":[{"name":"success","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"holder","type":"address"},{"name":"time","type":"uint64"}],"name":"transferableTokens","outputs":[{"name":"nonVested","type":"uint256"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"},{"name":"_spender","type":"address"}],"name":"allowance","outputs":[{"name":"remaining","type":"uint256"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"tokens","type":"uint256"},{"name":"time","type":"uint256"},{"name":"start","type":"uint256"},{"name":"cliff","type":"uint256"},{"name":"vesting","type":"uint256"}],"name":"calculateVestedTokens","outputs":[{"name":"vestedTokens","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_holder","type":"address"},{"name":"_grantId","type":"uint256"}],"name":"revokeTokenGrant","outputs":[],"payable":false,"type":"function"},{"anonymous":false,"inputs":[{"indexed":true,"name":"from","type":"address"},{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"owner","type":"address"},{"indexed":true,"name":"spender","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Approval","type":"event"}]}},"deployments":{},"sources":{"./contracts/Bounty.sol":"ipfs://QmYt6ZfD1VNmKp85TeteEcsgaxHzP2gTSKupHxHMVgcHYb","./contracts/DayLimit.sol":"ipfs://QmexsaiGwyqruHyQic2KzWQDgZAFv4qB3MArgahW4WDjbT","./contracts/LimitBalance.sol":"ipfs://QmNjUFMzELfeVGEfvUZyzeRejmgiUnQYMNKfvNrkWm9Ao6","./contracts/MultisigWallet.sol":"ipfs://QmdNBzE44sDjTTaYzx6hUZypTBzcQProoBKF7DhhBLUbct","./contracts/SafeMath.sol":"ipfs://QmZKiNfFJRAd8K41pfAQxfY13kXjHCTv4Do2XgxTmY3muR","./contracts/lifecycle/Killable.sol":"ipfs://QmakG7GAR7hssgL7Csf83jbCB3FpKGGgLR4U9YmNn1C6cQ","./contracts/lifecycle/Migrations.sol":"ipfs://QmT7pw3vVMsD5mEiSyDkF7N9CrJ6HYSnwbfKS2yohSCecM","./contracts/lifecycle/Pausable.sol":"ipfs://QmPrzzPryn9JUNK4SJjX38JXvaYkq1KVjoV1FGHKwW1W4Z","./contracts/ownership/Claimable.sol":"ipfs://QmdbysHy6wocC8z5FuVA8hmVeGV32kbQSLKfNE8uNSA8DC","./contracts/ownership/Contactable.sol":"ipfs://QmRtSm3QhpVy9txT7YivY9ysgktzT4gxdjmTechhAsw3zD","./contracts/ownership/DelayedClaimable.sol":"ipfs://QmfY8nVBokMFTpfZ7crg2N3xnUM7ZhBDEL4M3idPGmmpMo","./contracts/ownership/Multisig.sol":"ipfs://QmbSumFuK281AdeekRHMUo8UcfmwowHSLNzKU7ykjBVoop","./contracts/ownership/Ownable.sol":"ipfs://QmYDvUXHxVbDRzG9r7Eb5dfLUeSftTt4UZ2r1JzGVkCbaH","./contracts/ownership/Shareable.sol":"ipfs://QmScDRoiu4MqVguqwTEqA45rRXQR1q9ogbeX2kLYgbj5DY","./contracts/payment/PullPayment.sol":"ipfs://QmSUtQXokkw7D6ona6KL8iJhC8yve5KPwhgMM4Li9EG1Kx","./contracts/token/BasicToken.sol":"ipfs://QmVMMpdu5E3x81n6jV64maioTkqCPaUXsXGX1qEaTJJkZn","./contracts/token/CrowdsaleToken.sol":"ipfs://QmWKR6vV3vvhWMffsqQFfz5BkqTaezZXixVeiBfp8SDhPw","./contracts/token/ERC20.sol":"ipfs://QmTuf7A4WiwiJSiZost1z9wF8QfWP5L6kNwMeUb7rUHqZ9","./contracts/token/ERC20Basic.sol":"ipfs://QmZz2HeBciA5B5ftsH2CZTtRpoDFvEmcWHVTSnp74cwcCf","./contracts/token/SimpleToken.sol":"ipfs://QmWJHRZa6pcg8rc6JQ7qhVWiCCKM4pAL2G3ZwFr2cvQeMe","./contracts/token/StandardToken.sol":"ipfs://QmWXbwiDHmrkF2RNNs2446z6KexhL4iyBDBHmWjvMSEBGs","./contracts/token/VestedToken.sol":"ipfs://QmNWLfTYi9J7H4mw68NoKjgDsWLA9SguowUSRJxTZ5bWB6"},"build_dependencies":{}} -------------------------------------------------------------------------------- /installed_contracts/zeppelin/lock.uri: -------------------------------------------------------------------------------- 1 | ipfs://Qmas6SZ4tXFfcrxSobqmETkGSzNzPEoqfmTztksKT3oY19 -------------------------------------------------------------------------------- /migrations/1_initial_migration.js: -------------------------------------------------------------------------------- 1 | var Migrations = artifacts.require("./Migrations.sol"); 2 | 3 | module.exports = function(deployer) { 4 | deployer.deploy(Migrations); 5 | }; 6 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "erc23", 3 | "version": "0.1.0", 4 | "description": "ERC23 token standard", 5 | "main": "truffle.js", 6 | "scripts": { 7 | "test": "./test.sh" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "https://github.com/AragonOne/ERC23.git" 12 | }, 13 | "license": "MIT", 14 | "bugs": { 15 | "url": "https://github.com/AragonOne/ERC23/issues" 16 | }, 17 | "homepage": "https://github.com/AragonOne/ERC23", 18 | "devDependencies": { 19 | "babel-polyfill": "^6.26.0", 20 | "babel-preset-es2015": "^6.18.0", 21 | "babel-preset-stage-2": "^6.18.0", 22 | "babel-preset-stage-3": "^6.17.0", 23 | "babel-register": "^6.23.0", 24 | "ethereumjs-testrpc": "^4.1.3", 25 | "truffle": "^3.4.11" 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /test.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | output=$(nc -z localhost 8545; echo $?) 4 | [ $output -eq "0" ] && trpc_running=true 5 | if [ ! $trpc_running ]; then 6 | echo "Starting our own testrpc node instance" 7 | testrpc > /dev/null & 8 | trpc_pid=$! 9 | fi 10 | ./node_modules/truffle/cli.js test 11 | if [ ! $trpc_running ]; then 12 | kill -9 $trpc_pid 13 | fi 14 | -------------------------------------------------------------------------------- /test/ReceiverTest.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.8; 2 | 3 | import "truffle/Assert.sol"; 4 | import "../contracts/example/ExampleToken.sol"; 5 | import "./helpers/ReceiverMock.sol"; 6 | 7 | contract ReceiverTest { 8 | ExampleToken token; 9 | ReceiverMock receiver; 10 | 11 | function beforeEach() { 12 | token = new ExampleToken(100); 13 | receiver = new ReceiverMock(); 14 | } 15 | 16 | function testFallbackIsCalledOnTransfer() { 17 | token.transfer(receiver, 10); 18 | 19 | Assert.equal(receiver.tokenAddr(), token, 'Token address should be correct'); 20 | Assert.equal(receiver.tokenSender(), this, 'Sender should be correct'); 21 | Assert.equal(receiver.sentValue(), 10, 'Value should be correct'); 22 | } 23 | 24 | function testCorrectFunctionIsCalledOnTransfer() { 25 | bytes memory data = new bytes(4); // foo() is 0xc2985578 26 | data[0] = 0xc2; data[1] = 0x98; data[2] = 0x55; data[3] = 0x78; 27 | 28 | token.transfer(receiver, 20, data); 29 | 30 | Assert.equal(receiver.tokenSig(), bytes4(0xc2985578), 'Sig should be correct'); 31 | Assert.isTrue(receiver.calledFoo(), 'Should have called foo'); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /test/StandardToken.js: -------------------------------------------------------------------------------- 1 | // Zeppelin tests for ERC20 StandardToken. Run against Standard23Token to check full backwards compatibility. 2 | 3 | const assertJump = require('./helpers/assertJump'); 4 | var StandardTokenMock = artifacts.require("./helpers/StandardTokenMock.sol"); 5 | 6 | contract('Standard223Token', function(accounts) { 7 | 8 | it("should return the correct totalSupply after construction", async function() { 9 | let token = await StandardTokenMock.new(accounts[0], 100); 10 | let totalSupply = await token.totalSupply(); 11 | 12 | assert.equal(totalSupply, 100); 13 | }) 14 | 15 | it("should return the correct allowance amount after approval", async function() { 16 | let token = await StandardTokenMock.new(); 17 | let approve = await token.approve(accounts[1], 100); 18 | let allowance = await token.allowance(accounts[0], accounts[1]); 19 | 20 | assert.equal(allowance, 100); 21 | }); 22 | 23 | it("should return correct balances after transfer", async function() { 24 | let token = await StandardTokenMock.new(accounts[0], 100); 25 | let transfer = await token.transfer(accounts[1], 100); 26 | let balance0 = await token.balanceOf(accounts[0]); 27 | assert.equal(balance0, 0); 28 | 29 | let balance1 = await token.balanceOf(accounts[1]); 30 | assert.equal(balance1, 100); 31 | }); 32 | 33 | it("should throw an error when trying to transfer more than balance", async function() { 34 | let token = await StandardTokenMock.new(accounts[0], 100); 35 | try { 36 | let transfer = await token.transfer(accounts[1], 101); 37 | } catch(error) { 38 | return assertJump(error); 39 | } 40 | assert.fail('should have thrown before'); 41 | }); 42 | 43 | it("should return correct balances after transfering from another account", async function() { 44 | let token = await StandardTokenMock.new(accounts[0], 100); 45 | let approve = await token.approve(accounts[1], 100); 46 | let transferFrom = await token.transferFrom(accounts[0], accounts[2], 100, {from: accounts[1]}); 47 | 48 | let balance0 = await token.balanceOf(accounts[0]); 49 | assert.equal(balance0, 0); 50 | 51 | let balance1 = await token.balanceOf(accounts[2]); 52 | assert.equal(balance1, 100); 53 | 54 | let balance2 = await token.balanceOf(accounts[1]); 55 | assert.equal(balance2, 0); 56 | }); 57 | 58 | it("should throw an error when trying to transfer more than allowed", async function() { 59 | let token = await StandardTokenMock.new(); 60 | let approve = await token.approve(accounts[1], 99); 61 | try { 62 | let transfer = await token.transferFrom(accounts[0], accounts[2], 100, {from: accounts[1]}); 63 | } catch (error) { 64 | return assertJump(error); 65 | } 66 | assert.fail('should have thrown before'); 67 | }); 68 | 69 | }); 70 | -------------------------------------------------------------------------------- /test/helpers/ReceiverMock.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.8; 2 | 3 | import "../../contracts/example/ExampleReceiver.sol"; 4 | 5 | contract ReceiverMock is ExampleReceiver { 6 | uint public sentValue; 7 | address public tokenAddr; 8 | address public tokenSender; 9 | bool public calledFoo; 10 | 11 | bytes public tokenData; 12 | bytes4 public tokenSig; 13 | 14 | function foo() tokenPayable { 15 | saveTokenValues(); 16 | calledFoo = true; 17 | } 18 | 19 | function () tokenPayable { 20 | saveTokenValues(); 21 | } 22 | 23 | function saveTokenValues() private { 24 | tokenAddr = tkn.addr; 25 | tokenSender = tkn.sender; 26 | sentValue = tkn.value; 27 | tokenSig = tkn.sig; 28 | tokenData = tkn.data; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /test/helpers/StandardTokenMock.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.8; 2 | 3 | 4 | import '../../contracts/implementation/Standard223Token.sol'; 5 | 6 | // mock class using Standard223Token 7 | contract StandardTokenMock is Standard223Token { 8 | function StandardTokenMock(address initialAccount, uint initialBalance) { 9 | balances[initialAccount] = initialBalance; 10 | totalSupply = initialBalance; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /test/helpers/assertJump.js: -------------------------------------------------------------------------------- 1 | module.exports = function(error) { 2 | assert.isAbove(error.message.search('VM Exception while processing transaction: invalid opcode'), -1, 'Invalid opcode (revert) error must be returned'); 3 | } 4 | -------------------------------------------------------------------------------- /truffle.js: -------------------------------------------------------------------------------- 1 | require('babel-register'); 2 | require('babel-polyfill'); 3 | 4 | module.exports = { 5 | networks: { 6 | development: { 7 | network_id: 15, 8 | host: 'localhost', 9 | port: 8545, 10 | }, 11 | kovan: { 12 | network_id: 42, 13 | host: 'localhost', 14 | port: 8545, 15 | gas: 4700000, 16 | from: '0x0031EDb4846BAb2EDEdd7f724E58C50762a45Cb2', 17 | }, 18 | ropsten: { 19 | network_id: 3, 20 | host: 'localhost', 21 | port: 8545, 22 | from: '0xfcea9c5d4967956d4b209f6b1e9d2162ce96149b', 23 | }, 24 | landing: { 25 | network_id: 1234, 26 | host: 'eth-rpc.aragon.one', 27 | port: 80, 28 | }, 29 | development46: { 30 | network_id: 15, 31 | host: 'localhost', 32 | port: 8546, 33 | }, 34 | }, 35 | build: {}, 36 | } 37 | --------------------------------------------------------------------------------