removing trailing whitespace

This commit is contained in:
Roy Blankman 2017-09-16 10:20:06 -04:00
parent 1737555b0d
commit 6d8bb497c8
45 changed files with 125 additions and 125 deletions

2
.gitignore vendored
View File

@ -6,4 +6,4 @@ build/
/coverage
coverage.json
allFiredEvents
scTopics
scTopics

View File

@ -2,4 +2,4 @@ module.exports = {
norpc: true,
testCommand: 'node --max-old-space-size=4096 ../node_modules/.bin/truffle test --network coverage',
skipFiles: ['lifecycle/Migrations.sol']
}
}

View File

@ -1 +1 @@
node_modules
node_modules

16
LICENSE
View File

@ -5,18 +5,18 @@ Copyright (c) 2016 Smart Contract Solutions, Inc.
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@ -5,7 +5,7 @@ Authored by Dennis Peterson and Peter Vessenes
# Introduction
Zeppelin requested that New Alchemy perform an audit of the contracts in their OpenZeppelin library. The OpenZeppelin contracts are a set of contracts intended to be a safe building block for a variety of uses by parties that may not be as sophisticated as the OpenZeppelin team. It is a design goal that the contracts be deployable safely and "as-is".
Zeppelin requested that New Alchemy perform an audit of the contracts in their OpenZeppelin library. The OpenZeppelin contracts are a set of contracts intended to be a safe building block for a variety of uses by parties that may not be as sophisticated as the OpenZeppelin team. It is a design goal that the contracts be deployable safely and "as-is".
The contracts are hosted at:
@ -22,9 +22,9 @@ The audit makes no statements or warrantees about utility of the code, safety of
# Executive Summary
Overall the OpenZeppelin codebase is of reasonably high quality -- it is clean, modular and follows best practices throughout.
Overall the OpenZeppelin codebase is of reasonably high quality -- it is clean, modular and follows best practices throughout.
It is still in flux as a codebase, and needs better documentation per file as to expected behavior and future plans. It probably needs more comprehensive and aggressive tests written by people less nice than the current OpenZeppelin team.
It is still in flux as a codebase, and needs better documentation per file as to expected behavior and future plans. It probably needs more comprehensive and aggressive tests written by people less nice than the current OpenZeppelin team.
We identified two critical errors and one moderate issue, and would not recommend this commit hash for public use until these bugs are remedied.
@ -34,12 +34,12 @@ The repository includes a set of Truffle unit tests, a requirement and best prac
## Big Picture: Is This A Worthwhile Project?
As soon as a developer touches OpenZeppelin contracts, they will modify something, leaving them in an un-audited state. We do not recommend developers deploy any unaudited code to the Blockchain if it will handle money, information or other things of value.
As soon as a developer touches OpenZeppelin contracts, they will modify something, leaving them in an un-audited state. We do not recommend developers deploy any unaudited code to the Blockchain if it will handle money, information or other things of value.
> "In accordance with Unix philosophy, Perl gives you enough rope to hang yourself"
> --Larry Wall
We think this is an incredibly worthwhile project -- aided by the high code quality. Creating a framework that can be easily extended helps increase the average code quality on the Blockchain by charting a course for developers and encouraging containment of modifications to certain sections.
We think this is an incredibly worthwhile project -- aided by the high code quality. Creating a framework that can be easily extended helps increase the average code quality on the Blockchain by charting a course for developers and encouraging containment of modifications to certain sections.
> "Rust: The language that makes you take the safety off before shooting yourself in the foot"
> -- (@mbrubeck)
@ -65,7 +65,7 @@ In general we prefer `throw` in our code audits, because it is simpler -- it's l
In the OpenZeppelin contracts, both styles are used in different parts of the codebase. `SimpleToken` transfers throw upon failure, while the full ERC20 token returns `false`. Some modifiers `throw`, others just wrap the function body in a conditional, effectively allowing the function to return false if the condition is not met.
We don't love this, and would usually recommend you stick with one style or the other throughout the codebase.
We don't love this, and would usually recommend you stick with one style or the other throughout the codebase.
In at least one case, these different techniques are combined cleverly (see the Multisig comments, line 65). As a set of contracts intended for general use, we recommend you either strive for more consistency or document explicit design criteria that govern which techniques are used where.
@ -77,19 +77,19 @@ Note that it may be impossible to use either one in all situations. For example,
CrowdsaleToken.sol has no provision for withdrawing the raised ether. We *strongly* recommend a standard `withdraw` function be added. There is no scenario in which someone should deploy this contract as is, whether for testing or live.
## Recursive Call in MultisigWallet
Line 45 of `MultisigWallet.sol` checks if the amount being sent by `execute` is under a daily limit.
Line 45 of `MultisigWallet.sol` checks if the amount being sent by `execute` is under a daily limit.
This function can only be called by the "Owner". As a first angle of attack, it's worth asking what will happen if the multisig wallet owners reset the daily limit by approving a call to `resetSpentToday`.
This function can only be called by the "Owner". As a first angle of attack, it's worth asking what will happen if the multisig wallet owners reset the daily limit by approving a call to `resetSpentToday`.
If a chain of calls can be constructed in which the owner confirms the `resetSpentToday` function and then withdraws through `execute` in a recursive call, the contract can be drained. In fact, this could be done without a recursive call, just through repeated `execute` calls alternating with the `confirm` calls.
We are still working through the confirmation protocol in `Shareable.sol`, but we are not convinced that this is impossible, in fact it looks possible. The flexibility any shared owner has in being able to revoke confirmation later is another worrisome angle of approach even if some simple patches are included.
We are still working through the confirmation protocol in `Shareable.sol`, but we are not convinced that this is impossible, in fact it looks possible. The flexibility any shared owner has in being able to revoke confirmation later is another worrisome angle of approach even if some simple patches are included.
This bug has a number of causes that need to be addressed:
1. `resetSpentToday` and `confirm` together do not limit the days on which the function can be called or (it appears) the number of times it can be called.
1. Once a call has been confirmed and `execute`d it appears that it can be re-executed. This is not good.
3. `confirmandCheck` doesn't seem to have logic about whether or not the function in question has been called.
1. `resetSpentToday` and `confirm` together do not limit the days on which the function can be called or (it appears) the number of times it can be called.
1. Once a call has been confirmed and `execute`d it appears that it can be re-executed. This is not good.
3. `confirmandCheck` doesn't seem to have logic about whether or not the function in question has been called.
4. Even if it did, `revoke` would need updates and logic to deal with revocation requests after a function call had been completed.
We do not recommend using the MultisigWallet until these issues are fixed.
@ -97,9 +97,9 @@ We do not recommend using the MultisigWallet until these issues are fixed.
# Moderate to Minor Issues
## PullPayment
PullPayment.sol needs some work. It has no explicit provision for cancelling a payment. This would be desirable in a number of scenarios; consider a payee losing their wallet, or giving a griefing address, or just an address that requires more than the default gas offered by `send`.
PullPayment.sol needs some work. It has no explicit provision for cancelling a payment. This would be desirable in a number of scenarios; consider a payee losing their wallet, or giving a griefing address, or just an address that requires more than the default gas offered by `send`.
`asyncSend` has no overflow checking. This is a bad plan. We recommend overflow and underflow checking at the layer closest to the data manipulation.
`asyncSend` has no overflow checking. This is a bad plan. We recommend overflow and underflow checking at the layer closest to the data manipulation.
`asyncSend` allows more balance to be queued up for sending than the contract holds. This is probably a bad idea, or at the very least should be called something different. If the intent is to allow this, it should have provisions for dealing with race conditions between competing `withdrawPayments` calls.
@ -107,7 +107,7 @@ It would be nice to see how many payments are pending. This would imply a bit of
## Shareable Contract
We do not believe the `Shareable.sol` contract is ready for primetime. It is missing functions, and as written may be vulnerable to a reordering attack -- an attack in which a miner or other party "racing" with a smart contract participant inserts their own information into a list or mapping.
We do not believe the `Shareable.sol` contract is ready for primetime. It is missing functions, and as written may be vulnerable to a reordering attack -- an attack in which a miner or other party "racing" with a smart contract participant inserts their own information into a list or mapping.
The confirmation and revocation code needs to be looked over with a very careful eye imagining extraordinarily bad behavior by shared owners before this contract can be called safe.
@ -129,7 +129,7 @@ I presume that the goal of this contract is to allow and annotate a migration to
### Pausable
We like these pauses! Note that these allow significant griefing potential by owners, and that this might not be obvious to participants in smart contracts using the OpenZeppelin framework. We would recommend that additional sample logic be added to for instance the TokenContract showing safer use of the pause and resume functions. In particular, we would recommend a timelock after which anyone could unpause the contract.
We like these pauses! Note that these allow significant griefing potential by owners, and that this might not be obvious to participants in smart contracts using the OpenZeppelin framework. We would recommend that additional sample logic be added to for instance the TokenContract showing safer use of the pause and resume functions. In particular, we would recommend a timelock after which anyone could unpause the contract.
The modifers use the pattern `if(bool){_;}`. This is fine for functions that return false upon failure, but could be problematic for functions expected to throw upon failure. See our comments above on standardizing on `throw` or `return(false)`.
@ -163,7 +163,7 @@ Line 34: "this contract only has six types of events"...actually only two.
Line 61: Why is `ownerIndex` keyed by addresses hashed to `uint`s? Why not use the addresses directly, so `ownerIndex` is less obscure, and so there's stronger typing?
Line 62: Do not love `++i) ... owners[2+ i]`. Makes me do math, which is not what I want to do. I want to not have to do math.
Line 62: Do not love `++i) ... owners[2+ i]`. Makes me do math, which is not what I want to do. I want to not have to do math.
There should probably be a function for adding a new operation, so the developer doesn't have to work directly with the internal data. (This would make the multisig contract even shorter.)
@ -171,7 +171,7 @@ There's a `revoke` function but not a `propose` function that we can see.
Beware reordering. If `propose` allows the user to choose a bytes string for their proposal, bad things(TM) will happen as currently written.
### Multisig
Just an interface. Note it allows changing an owner address, but not changing the number of owners. This is somewhat limiting but also simplifies implementation.
@ -184,9 +184,9 @@ Safe from reentrance attack since ether send is at the end, plus it uses `.send(
There's an argument to be made that `.call.value()` is a better option *if* you're sure that it will be done after all state updates, since `.send` will fail if the recipient has an expensive fallback function. However, in the context of a function meant to be embedded in other contracts, it's probably better to use `.send`. One possible compromise is to add a function which allows only the owner to send ether via `.call.value`.
If you don't use `call.value` you should implement a `cancel` function in case some value is pending here.
If you don't use `call.value` you should implement a `cancel` function in case some value is pending here.
Line 14:
Line 14:
Doesn't use safeAdd. Although it appears that payout amounts can only be increased, in fact the payer could lower the payout as much as desired via overflow. Also, the payer could add a large non-overflowing amount, causing the payment to exceed the contract balance and therefore fail when withdraw is attempted.
Recommendation: track the sum of non-withdrawn asyncSends, and don't allow a new one which exceeds the leftover balance. If it's ever desirable to make payments revocable, it should be done explicitly.
@ -195,7 +195,7 @@ Recommendation: track the sum of non-withdrawn asyncSends, and don't allow a new
### ERC20
Standard ERC20 interface only.
Standard ERC20 interface only.
There's a security hole in the standard, reported at Edcon: `approve` does not protect against race conditions and simply replaces the current value. An approved spender could wait for the owner to call `approve` again, then attempt to spend the old limit before the new limit is applied. If successful, this attacker could successfully spend the sum of both limits.
@ -208,11 +208,11 @@ https://drive.google.com/file/d/0ByMtMw2hul0EN3NCaVFHSFdxRzA/view
### ERC20Basic
Simpler interface skipping the Approve function. Note this departs from ERC20 in another way: transfer throws instead of returning false.
Simpler interface skipping the Approve function. Note this departs from ERC20 in another way: transfer throws instead of returning false.
### BasicToken
Uses `SafeSub` and `SafeMath`, so transfer `throw`s instead of returning false. This complies with ERC20Basic but not the actual ERC20 standard.
Uses `SafeSub` and `SafeMath`, so transfer `throw`s instead of returning false. This complies with ERC20Basic but not the actual ERC20 standard.
### StandardToken
@ -234,10 +234,10 @@ Note: an alternative pattern is a mint() function which is only callable from a
### VestedToken
Lines 23, 27:
Functions `transfer()` and `transferFrom()` have a modifier canTransfer which throws if not enough tokens are available. However, transfer() returns a boolean success. Inconsistent treatment of failure conditions may cause problems for other contracts using the token. (Note that transferableTokens() relies on safeSub(), so will also throw if there's insufficient balance.)
Lines 23, 27:
Functions `transfer()` and `transferFrom()` have a modifier canTransfer which throws if not enough tokens are available. However, transfer() returns a boolean success. Inconsistent treatment of failure conditions may cause problems for other contracts using the token. (Note that transferableTokens() relies on safeSub(), so will also throw if there's insufficient balance.)
Line 64:
Line 64:
Delete not actually necessary since the value is overwritten in the next line anyway.
## Root level
@ -255,7 +255,7 @@ The modifier `limitedDaily` calls `underLimit`, which both checks that the spend
Lines 4, 11:
Comment claims that `DayLimit` is multiowned, and Shareable is imported, but DayLimit does not actually inherit from Shareable. The intent may be for child contracts to inherit from Shareable (as Multisig does); in this case the import should be removed and the comment altered.
Line 46:
Line 46:
Manual overflow check instead of using safeAdd. Since this is called from a function that throws upon failure anyway, there's no real downside to using safeAdd.
### LimitBalance
@ -264,19 +264,19 @@ No issues.
### MultisigWallet
Lines 28, 76, 80:
Lines 28, 76, 80:
`kill`, `setDailyLimit`, and `resetSpentToday` only happen with multisig approval, and hashes for these actions are logged by Shareable. However, they should probably post their own events for easy reading.
Line 45:
Line 45:
This call to underLimit will reduce the daily limit, and then either throw or return 0. So in this case there's no danger that the limit will be reduced without the operation going through.
Line 65:
Line 65:
Shareable's onlyManyOwners will take the user's confirmation, and execute the function body if and only if enough users have confirmed. Whole thing throws if the send fails, which will roll back the confirmation. Confirm returns false if not enough have confirmed yet, true if the whole thing succeeds, and throws only in the exceptional circumstance that the designated transaction unexpectedly fails. Elegant design.
Line 68:
Line 68:
Throw here is good but note this function can fail either by returning false or by throwing.
Line 92:
Line 92:
A bit odd to split `clearPending()` between this contract and Shareable. However this does allow contracts inheriting from Shareable to use custom structs for pending transactions.

View File

@ -4,11 +4,11 @@ import '../token/MintableToken.sol';
import '../math/SafeMath.sol';
/**
* @title Crowdsale
* @title Crowdsale
* @dev Crowdsale is a base contract for managing a token crowdsale.
* Crowdsales have a start and end timestamps, where investors can make
* token purchases and the crowdsale will assign them tokens based
* on a token per ETH rate. Funds collected are forwarded to a wallet
* on a token per ETH rate. Funds collected are forwarded to a wallet
* as they arrive.
*/
contract Crowdsale {
@ -36,7 +36,7 @@ contract Crowdsale {
* @param beneficiary who got the tokens
* @param value weis paid for purchase
* @param amount amount of tokens purchased
*/
*/
event TokenPurchase(address indexed purchaser, address indexed beneficiary, uint256 value, uint256 amount);
@ -53,7 +53,7 @@ contract Crowdsale {
wallet = _wallet;
}
// creates the token to be sold.
// creates the token to be sold.
// override this method to have crowdsale of a specific mintable token.
function createTokenContract() internal returns (MintableToken) {
return new MintableToken();

View File

@ -7,7 +7,7 @@ import './Crowdsale.sol';
/**
* @title FinalizableCrowdsale
* @dev Extension of Crowsdale where an owner can do extra work
* after finishing.
* after finishing.
*/
contract FinalizableCrowdsale is Crowdsale, Ownable {
using SafeMath for uint256;
@ -26,7 +26,7 @@ contract FinalizableCrowdsale is Crowdsale, Ownable {
finalization();
Finalized();
isFinalized = true;
}

View File

@ -45,4 +45,4 @@ contract SampleCrowdsale is CappedCrowdsale, RefundableCrowdsale {
return new SampleCrowdsaleToken();
}
}
}

View File

@ -10,10 +10,10 @@ import "../ownership/Ownable.sol";
*/
contract Destructible is Ownable {
function Destructible() payable { }
function Destructible() payable { }
/**
* @dev Transfers the current balance to the owner and terminates the contract.
* @dev Transfers the current balance to the owner and terminates the contract.
*/
function destroy() onlyOwner {
selfdestruct(owner);

View File

@ -4,7 +4,7 @@ pragma solidity ^0.4.11;
import "../ownership/Ownable.sol";
import "../token/ERC20Basic.sol";
/**
/**
* @title TokenDestructible:
* @author Remco Bloemen <remco@2π.com>
* @dev Base contract that can be destroyed by owner. All funds in contract including
@ -12,9 +12,9 @@ import "../token/ERC20Basic.sol";
*/
contract TokenDestructible is Ownable {
function TokenDestructible() payable { }
function TokenDestructible() payable { }
/**
/**
* @notice Terminate contract and refund to owner
* @param tokens List of addresses of ERC20 or ERC20Basic token contracts to
refund.

View File

@ -4,7 +4,7 @@ import './Ownable.sol';
/**
* @title Contactable token
* @dev Basic version of a contactable contract, allowing the owner to provide a string with their
* @dev Basic version of a contactable contract, allowing the owner to provide a string with their
* contact information.
*/
contract Contactable is Ownable{

View File

@ -2,7 +2,7 @@ pragma solidity ^0.4.11;
import "./Ownable.sol";
/**
/**
* @title Contracts that should not own Contracts
* @author Remco Bloemen <remco@2π.com>
* @dev Should contracts (anything Ownable) end up being owned by this contract, it allows the owner

View File

@ -4,10 +4,10 @@ import "./HasNoEther.sol";
import "./HasNoTokens.sol";
import "./HasNoContracts.sol";
/**
/**
* @title Base contract for contracts that should not own things.
* @author Remco Bloemen <remco@2π.com>
* @dev Solves a class of errors where a contract accidentally becomes owner of Ether, Tokens or
* @dev Solves a class of errors where a contract accidentally becomes owner of Ether, Tokens or
* Owned contracts. See respective base contracts for details.
*/
contract NoOwner is HasNoEther, HasNoTokens, HasNoContracts {

View File

@ -36,7 +36,7 @@ contract Ownable {
* @param newOwner The address to transfer ownership to.
*/
function transferOwnership(address newOwner) onlyOwner {
require(newOwner != address(0));
require(newOwner != address(0));
OwnershipTransferred(owner, newOwner);
owner = newOwner;
}

View File

@ -7,7 +7,7 @@ import '../math/SafeMath.sol';
/**
* @title Basic token
* @dev Basic version of StandardToken, with no allowances.
* @dev Basic version of StandardToken, with no allowances.
*/
contract BasicToken is ERC20Basic {
using SafeMath for uint256;
@ -31,7 +31,7 @@ contract BasicToken is ERC20Basic {
/**
* @dev Gets the balance of the specified address.
* @param _owner The address to query the the balance of.
* @param _owner The address to query the the balance of.
* @return An uint256 representing the amount owned by the passed address.
*/
function balanceOf(address _owner) constant returns (uint256 balance) {

View File

@ -65,21 +65,21 @@ contract StandardToken is ERC20, BasicToken {
function allowance(address _owner, address _spender) constant returns (uint256 remaining) {
return allowed[_owner][_spender];
}
/**
* approve should be called when allowed[_spender] == 0. To increment
* allowed value is better to use this function to avoid 2 calls (and wait until
* allowed value is better to use this function to avoid 2 calls (and wait until
* the first transaction is mined)
* From MonolithDAO Token.sol
*/
function increaseApproval (address _spender, uint _addedValue)
function increaseApproval (address _spender, uint _addedValue)
returns (bool success) {
allowed[msg.sender][_spender] = allowed[msg.sender][_spender].add(_addedValue);
Approval(msg.sender, _spender, allowed[msg.sender][_spender]);
return true;
}
function decreaseApproval (address _spender, uint _subtractedValue)
function decreaseApproval (address _spender, uint _subtractedValue)
returns (bool success) {
uint oldValue = allowed[msg.sender][_spender];
if (_subtractedValue > oldValue) {

View File

@ -17,4 +17,4 @@ help:
# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
%: Makefile
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)

View File

@ -9,4 +9,4 @@ Returns the token balance of the passed address.
function transfer(address _to, uint _value) returns (bool success)
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
Transfers tokens from sender's account. Amount must not be greater than sender's balance.
Transfers tokens from sender's account. Amount must not be greater than sender's balance.

View File

@ -9,4 +9,4 @@ Interested in contributing to Zeppelin?
* Framework proposal and roadmap: https://medium.com/zeppelin-blog/zeppelin-framework-proposal-and-development-roadmap-fdfa9a3a32ab#.iain47pak
* Issue tracker: https://github.com/OpenZeppelin/zeppelin-solidity/issues
* Contribution guidelines: https://github.com/OpenZeppelin/zeppelin-solidity/blob/master/CONTRIBUTING.md
* Contribution guidelines: https://github.com/OpenZeppelin/zeppelin-solidity/blob/master/CONTRIBUTING.md

View File

@ -6,14 +6,14 @@
Welcome to Zeppelin-Solidity
=============================================
Zeppelin is a library for writing secure Smart Contracts on Ethereum.
Zeppelin is a library for writing secure Smart Contracts on Ethereum.
With Zeppelin, you can build distributed applications, protocols and organizations:
* using :doc:`contract-security-patterns`
* in the `Solidity language <https://solidity.readthedocs.io/en/develop/>`_.
The code is open-source, and `available on github <https://github.com/OpenZeppelin/zeppelin-solidity>`_.
The code is open-source, and `available on github <https://github.com/OpenZeppelin/zeppelin-solidity>`_.
.. toctree::
:maxdepth: 2
@ -24,7 +24,7 @@ The code is open-source, and `available on github <https://github.com/OpenZeppel
.. toctree::
:maxdepth: 2
:caption: Smart Contracts
ownable
Pausable
destructible
@ -41,7 +41,7 @@ The code is open-source, and `available on github <https://github.com/OpenZeppel
.. toctree::
:maxdepth: 2
:caption: Developer Resources
contract-security-patterns
developer-resources
license
license

View File

@ -13,4 +13,4 @@ Destroys the contract and sends funds back to the owner.
destroyAndSend(address _recipient) onlyOwner
"""""""""""""""""""
Destroys the contract and sends funds back to the _recepient.
Destroys the contract and sends funds back to the _recepient.

View File

@ -6,18 +6,18 @@ Copyright (c) 2016 Smart Contract Solutions, Inc.
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@ -13,4 +13,4 @@ Creates a new instance of the contract at the passed address.
setCompleted(uint completed) onlyOwner**
""""""""""""""""""""""""""""""""""""""""
Sets the last time that a migration was completed.
Sets the last time that a migration was completed.

View File

@ -24,4 +24,4 @@ Only runs if pause mechanism is activated.
unpause() onlyOwner whenPaused returns (bool)
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
Deactivates the pause mechanism.
Deactivates the pause mechanism.

View File

@ -21,4 +21,4 @@ Checks that b is not greater than a before subtracting.
add(uint256 a, uint256 b) internal returns (uint256)
"""""""""""""""""""""""""""""""""""""""""""""""""
Checks that the result is greater than both a and b.
Checks that the result is greater than both a and b.

View File

@ -23,4 +23,4 @@ Transfers tokens from an account that the sender is approved to transfer from. A
function transfer(address _to, uint _value) returns (bool success)
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
Transfers tokens from sender's account. Amount must not be greater than sender's balance.
Transfers tokens from sender's account. Amount must not be greater than sender's balance.

View File

@ -29,7 +29,7 @@ contract('BasicToken', function(accounts) {
assert.fail('should have thrown before');
} catch(error) {
assertJump(error);
}
}
});
it('should throw an error when trying to transfer to 0x0', async function() {

View File

@ -15,7 +15,7 @@ function awaitEvent(event, handler) {
function wrappedHandler(...args) {
Promise.resolve(handler(...args)).then(resolve).catch(reject);
}
event.watch(wrappedHandler);
});
}
@ -90,7 +90,7 @@ contract('Bounty', function(accounts) {
let reward = web3.toWei(1, 'ether');
let bounty = await InsecureTargetBounty.new();
let event = bounty.TargetCreated({});
let watcher = async function(err, result) {
event.stopWatching();
if (err) { throw err; }

View File

@ -12,7 +12,7 @@ require('chai')
const expect = require('chai').expect
contract('BurnableToken', function (accounts) {
let token
let token
let expectedTokenSupply = new BigNumber(999)
beforeEach(async function () {
@ -34,6 +34,6 @@ contract('BurnableToken', function (accounts) {
it('cannot burn more tokens than your balance', async function () {
await token.burn(2000, { from: accounts[0] })
.should.be.rejectedWith(EVMThrow)
.should.be.rejectedWith(EVMThrow)
})
})
})

View File

@ -115,31 +115,31 @@ contract('Crowdsale', function ([_, investor, wallet, purchaser]) {
beforeEach(async function() {
await increaseTimeTo(this.startTime)
})
it('should log purchase', async function () {
const {logs} = await this.crowdsale.buyTokens(investor, {value: value, from: purchaser})
const event = logs.find(e => e.event === 'TokenPurchase')
should.exist(event)
event.args.purchaser.should.equal(purchaser)
event.args.beneficiary.should.equal(investor)
event.args.value.should.be.bignumber.equal(value)
event.args.amount.should.be.bignumber.equal(expectedTokenAmount)
})
it('should increase totalSupply', async function () {
await this.crowdsale.buyTokens(investor, {value, from: purchaser})
const totalSupply = await this.token.totalSupply()
totalSupply.should.be.bignumber.equal(expectedTokenAmount)
})
it('should assign tokens to beneficiary', async function () {
await this.crowdsale.buyTokens(investor, {value, from: purchaser})
const balance = await this.token.balanceOf(investor)
balance.should.be.bignumber.equal(expectedTokenAmount)
})
it('should forward funds to wallet', async function () {
const pre = web3.eth.getBalance(wallet)
await this.crowdsale.buyTokens(investor, {value, from: purchaser})

View File

@ -31,7 +31,7 @@ contract('LimitBalance', function(accounts) {
assert.fail('should have thrown before');
} catch(error) {
assertJump(error);
}
}
});
it('should allow multiple sends below limit', async function() {
@ -55,7 +55,7 @@ contract('LimitBalance', function(accounts) {
assert.fail('should have thrown before');
} catch(error) {
assertJump(error);
}
}
});
});

View File

@ -32,7 +32,7 @@ contract('Mintable', function(accounts) {
let balance0 = await token.balanceOf(accounts[0]);
assert(balance0, 100);
let totalSupply = await token.totalSupply();
assert(totalSupply, 100);
})

View File

@ -45,4 +45,4 @@ contract('Ownable', function(accounts) {
}
});
});
});

View File

@ -53,7 +53,7 @@ contract('PausableToken', function(accounts) {
it('should throw an error trying to transfer while transactions are paused', async function() {
await token.pause();
try {
try {
await token.transfer(accounts[1], 100);
assert.fail('should have thrown before');
} catch (error) {
@ -63,11 +63,11 @@ contract('PausableToken', function(accounts) {
it('should throw an error trying to transfer from another account while transactions are paused', async function() {
await token.pause();
try {
try {
await token.transferFrom(accounts[0], accounts[1], 100);
assert.fail('should have thrown before');
} catch (error) {
assertJump(error);
}
});
})
})

View File

@ -3,11 +3,11 @@ var PullPaymentMock = artifacts.require("./helpers/PullPaymentMock.sol");
contract('PullPayment', function(accounts) {
let ppce;
let amount = 17*1e18;
beforeEach(async function() {
ppce = await PullPaymentMock.new({value: amount});
});
it("can't call asyncSend externally", async function() {
assert.isUndefined(ppce.asyncSend);
});

View File

@ -34,7 +34,7 @@ contract('Crowdsale', function ([owner, wallet, investor]) {
this.token = SampleCrowdsaleToken.at(await this.crowdsale.token());
});
it('should create crowdsale with correct parameters', async function () {
this.crowdsale.should.exist;
this.token.should.exist;

View File

@ -6,11 +6,11 @@ var StandardTokenMock = artifacts.require('./helpers/StandardTokenMock.sol');
contract('StandardToken', function(accounts) {
let token;
beforeEach(async function() {
token = await StandardTokenMock.new(accounts[0], 100);
});
it('should return the correct totalSupply after construction', async function() {
let totalSupply = await token.totalSupply();
@ -72,7 +72,7 @@ contract('StandardToken', function(accounts) {
describe('validating allowance updates to spender', function() {
let preApproved;
it('should start with zero', async function() {
preApproved = await token.allowance(accounts[0], accounts[1]);
assert.equal(preApproved, 0);

View File

@ -10,7 +10,7 @@ contract('TokenDestructible', function(accounts) {
beforeEach(async function() {
destructible = await TokenDestructible.new({fron: accounts[0], value: web3.toWei('10', 'ether')});
});
it('should send balance to owner after destruction', async function() {
let owner = await destructible.owner();
let initBalance = web3.eth.getBalance(owner);

View File

@ -9,4 +9,4 @@ contract BurnableTokenMock is BurnableToken {
totalSupply = initialBalance;
}
}
}

View File

@ -14,7 +14,7 @@ contract CappedCrowdsaleImpl is CappedCrowdsale {
uint256 _cap
)
Crowdsale(_startTime, _endTime, _rate, _wallet)
CappedCrowdsale(_cap)
CappedCrowdsale(_cap)
{
}

View File

@ -13,7 +13,7 @@ contract FinalizableCrowdsaleImpl is FinalizableCrowdsale {
address _wallet
)
Crowdsale(_startTime, _endTime, _rate, _wallet)
FinalizableCrowdsale()
FinalizableCrowdsale()
{
}

View File

@ -14,7 +14,7 @@ contract RefundableCrowdsaleImpl is RefundableCrowdsale {
uint256 _goal
)
Crowdsale(_startTime, _endTime, _rate, _wallet)
RefundableCrowdsale(_goal)
RefundableCrowdsale(_goal)
{
}

View File

@ -44,5 +44,5 @@ export const duration = {
hours: function(val) { return val * this.minutes(60) },
days: function(val) { return val * this.hours(24) },
weeks: function(val) { return val * this.days(7) },
years: function(val) { return val * this.days(365)}
};
years: function(val) { return val * this.days(365)}
};

View File

@ -2,7 +2,7 @@
module.exports = s => {
return new Promise((resolve, reject) => {
web3.currentProvider.sendAsync({
jsonrpc: '2.0',
jsonrpc: '2.0',
method: 'evm_increaseTime',
params: [s], // 60 seaconds, may need to be hex, I forget
id: new Date().getTime() // Id of the request; anything works, really

View File

@ -23,10 +23,10 @@ module.exports = {
},
coverage: {
host: "localhost",
network_id: "*",
port: 8555,
gas: 0xfffffffffff,
gasPrice: 0x01
network_id: "*",
port: 8555,
gas: 0xfffffffffff,
gasPrice: 0x01
}
}
};