openzeppelin-solidity
Advanced tools
Comparing version 1.9.0 to 1.10.0
{ | ||
"name": "openzeppelin-solidity", | ||
"version": "1.9.0", | ||
"version": "1.10.0", | ||
"description": "Secure Smart Contract library for Solidity", | ||
@@ -59,7 +59,7 @@ "files": [ | ||
"ganache-cli": "6.1.0", | ||
"solidity-coverage": "^0.4.15", | ||
"solium": "^1.1.6", | ||
"truffle": "^4.1.5", | ||
"solidity-coverage": "^0.5.0", | ||
"solium": "^1.1.7", | ||
"truffle": "^4.1.8", | ||
"truffle-hdwallet-provider": "0.0.3" | ||
} | ||
} |
@@ -16,4 +16,8 @@ # OpenZeppelin Solidity | ||
OpenZeppelin integrates with [Truffle](https://github.com/ConsenSys/truffle), an Ethereum development environment. Please install Truffle and initialize your project with `truffle init`. | ||
OpenZeppelin integrates with [Truffle](https://github.com/ConsenSys/truffle) and [Embark](https://github.com/embark-framework/embark/). | ||
## Truffle | ||
To use with Truffle, first install it and initialize your project with `truffle init`. | ||
```sh | ||
@@ -25,4 +29,17 @@ npm install -g truffle | ||
To install the OpenZeppelin library, run the following in your Solidity project root directory: | ||
## Embark | ||
To use with Embark, first install it and initialize your project with `embark new MyApp`. | ||
```sh | ||
npm install -g embark | ||
embark new MyApp | ||
cd MyApp | ||
``` | ||
## Installing OpenZeppelin | ||
After installing either Framework, to install the OpenZeppelin library, run the following in your Solidity project root directory: | ||
```sh | ||
npm init -y | ||
@@ -44,3 +61,12 @@ npm install -E openzeppelin-solidity | ||
If you are using Embark, you can also import directly from github: | ||
```solidity | ||
import "github.com/OpenZeppelin/openzeppelin-solidity/contracts/ownership/Ownable.sol#v1.9.0"; | ||
contract MyContract is Ownable { | ||
... | ||
} | ||
``` | ||
## Security | ||
@@ -47,0 +73,0 @@ OpenZeppelin is meant to provide secure, tested and community-audited code, but please use common sense when doing anything that deals with real money! We take no responsibility for your implementation decisions and any security problem you might experience. |
@@ -0,1 +1,2 @@ | ||
import shouldBehaveLikeMintedCrowdsale from './MintedCrowdsale.behaviour'; | ||
import ether from '../helpers/ether'; | ||
@@ -5,23 +6,17 @@ | ||
const should = require('chai') | ||
.use(require('chai-as-promised')) | ||
.use(require('chai-bignumber')(BigNumber)) | ||
.should(); | ||
const MintedCrowdsale = artifacts.require('MintedCrowdsaleImpl'); | ||
const MintableToken = artifacts.require('MintableToken'); | ||
const RBACMintableToken = artifacts.require('RBACMintableToken'); | ||
contract('MintedCrowdsale', function ([_, investor, wallet, purchaser]) { | ||
const rate = new BigNumber(1000); | ||
const value = ether(42); | ||
const value = ether(5); | ||
const expectedTokenAmount = rate.mul(value); | ||
describe('using MintableToken', function () { | ||
beforeEach(async function () { | ||
this.token = await MintableToken.new(); | ||
this.crowdsale = await MintedCrowdsale.new(rate, wallet, this.token.address); | ||
await this.token.transferOwnership(this.crowdsale.address); | ||
}); | ||
beforeEach(async function () { | ||
this.token = await MintableToken.new(); | ||
this.crowdsale = await MintedCrowdsale.new(rate, wallet, this.token.address); | ||
await this.token.transferOwnership(this.crowdsale.address); | ||
}); | ||
describe('accepting payments', function () { | ||
it('should be token owner', async function () { | ||
@@ -32,32 +27,21 @@ const owner = await this.token.owner(); | ||
it('should accept payments', async function () { | ||
await this.crowdsale.send(value).should.be.fulfilled; | ||
await this.crowdsale.buyTokens(investor, { value: value, from: purchaser }).should.be.fulfilled; | ||
}); | ||
shouldBehaveLikeMintedCrowdsale([_, investor, wallet, purchaser], rate, value); | ||
}); | ||
describe('high-level purchase', function () { | ||
it('should log purchase', async function () { | ||
const { logs } = await this.crowdsale.sendTransaction({ value: value, from: investor }); | ||
const event = logs.find(e => e.event === 'TokenPurchase'); | ||
should.exist(event); | ||
event.args.purchaser.should.equal(investor); | ||
event.args.beneficiary.should.equal(investor); | ||
event.args.value.should.be.bignumber.equal(value); | ||
event.args.amount.should.be.bignumber.equal(expectedTokenAmount); | ||
describe('using RBACMintableToken', function () { | ||
const ROLE_MINTER = 'minter'; | ||
beforeEach(async function () { | ||
this.token = await RBACMintableToken.new(); | ||
this.crowdsale = await MintedCrowdsale.new(rate, wallet, this.token.address); | ||
await this.token.addMinter(this.crowdsale.address); | ||
}); | ||
it('should assign tokens to sender', async function () { | ||
await this.crowdsale.sendTransaction({ value: value, from: investor }); | ||
let balance = await this.token.balanceOf(investor); | ||
balance.should.be.bignumber.equal(expectedTokenAmount); | ||
it('should have minter role on token', async function () { | ||
const isMinter = await this.token.hasRole(this.crowdsale.address, ROLE_MINTER); | ||
isMinter.should.equal(true); | ||
}); | ||
it('should forward funds to wallet', async function () { | ||
const pre = web3.eth.getBalance(wallet); | ||
await this.crowdsale.sendTransaction({ value, from: investor }); | ||
const post = web3.eth.getBalance(wallet); | ||
post.minus(pre).should.be.bignumber.equal(value); | ||
}); | ||
shouldBehaveLikeMintedCrowdsale([_, investor, wallet, purchaser], rate, value); | ||
}); | ||
}); |
@@ -79,3 +79,3 @@ import ether from '../helpers/ether'; | ||
it('should reject payments after end', async function () { | ||
await increaseTimeTo(this.afterEnd); | ||
await increaseTimeTo(this.afterClosingTime); | ||
await this.crowdsale.send(ether(1)).should.be.rejectedWith(EVMRevert); | ||
@@ -82,0 +82,0 @@ await this.crowdsale.buyTokens(investor, { value: ether(1), from: investor }).should.be.rejectedWith(EVMRevert); |
@@ -0,37 +1,11 @@ | ||
import shouldBehaveLikeOwnable from './Ownable.behaviour'; | ||
import assertRevert from '../helpers/assertRevert'; | ||
const Ownable = artifacts.require('Ownable'); | ||
var Ownable = artifacts.require('Ownable'); | ||
contract('Ownable', function (accounts) { | ||
let ownable; | ||
beforeEach(async function () { | ||
ownable = await Ownable.new(); | ||
this.ownable = await Ownable.new(); | ||
}); | ||
it('should have an owner', async function () { | ||
let owner = await ownable.owner(); | ||
assert.isTrue(owner !== 0); | ||
}); | ||
it('changes owner after transfer', async function () { | ||
let other = accounts[1]; | ||
await ownable.transferOwnership(other); | ||
let owner = await ownable.owner(); | ||
assert.isTrue(owner === other); | ||
}); | ||
it('should prevent non-owners from transfering', async function () { | ||
const other = accounts[2]; | ||
const owner = await ownable.owner.call(); | ||
assert.isTrue(owner !== other); | ||
await assertRevert(ownable.transferOwnership(other, { from: other })); | ||
}); | ||
it('should guard ownership against stuck state', async function () { | ||
let originalOwner = await ownable.owner(); | ||
await assertRevert(ownable.transferOwnership(null, { from: originalOwner })); | ||
}); | ||
shouldBehaveLikeOwnable(accounts); | ||
}); |
@@ -47,7 +47,2 @@ import expectThrow from '../helpers/expectThrow'; | ||
it('should not announce WhitelistedAddressAdded event if address is already in the whitelist', async function () { | ||
const { logs } = await mock.addAddressToWhitelist(whitelistedAddress1, { from: owner }); | ||
logs.should.be.empty; | ||
}); | ||
it('should remove address from the whitelist', async function () { | ||
@@ -73,7 +68,2 @@ await expectEvent.inTransaction( | ||
it('should not announce WhitelistedAddressRemoved event if address is not in the whitelist', async function () { | ||
const { logs } = await mock.removeAddressFromWhitelist(whitelistedAddress1, { from: owner }); | ||
logs.should.be.empty; | ||
}); | ||
it('should allow whitelisted address to call #onlyWhitelistedCanDoThis', async () => { | ||
@@ -92,3 +82,3 @@ await mock.addAddressToWhitelist(whitelistedAddress1, { from: owner }); | ||
}); | ||
it('should not allow "anyone" to remove from the whitelist', async () => { | ||
@@ -99,3 +89,3 @@ await expectThrow( | ||
}); | ||
it('should not allow "anyone" to call #onlyWhitelistedCanDoThis', async () => { | ||
@@ -102,0 +92,0 @@ await expectThrow( |
@@ -1,5 +0,7 @@ | ||
import assertRevert from '../../helpers/assertRevert'; | ||
import shouldBehaveLikeMintableToken from './MintableToken.behaviour'; | ||
const MintableToken = artifacts.require('MintableToken'); | ||
contract('Mintable', function ([owner, anotherAccount]) { | ||
contract('MintableToken', function ([owner, anotherAccount]) { | ||
const minter = owner; | ||
beforeEach(async function () { | ||
@@ -9,130 +11,3 @@ this.token = await MintableToken.new({ from: owner }); | ||
describe('minting finished', function () { | ||
describe('when the token is not finished', function () { | ||
it('returns false', async function () { | ||
const mintingFinished = await this.token.mintingFinished(); | ||
assert.equal(mintingFinished, false); | ||
}); | ||
}); | ||
describe('when the token is finished', function () { | ||
beforeEach(async function () { | ||
await this.token.finishMinting({ from: owner }); | ||
}); | ||
it('returns true', async function () { | ||
const mintingFinished = await this.token.mintingFinished.call(); | ||
assert.equal(mintingFinished, true); | ||
}); | ||
}); | ||
}); | ||
describe('finish minting', function () { | ||
describe('when the sender is the token owner', function () { | ||
const from = owner; | ||
describe('when the token was not finished', function () { | ||
it('finishes token minting', async function () { | ||
await this.token.finishMinting({ from }); | ||
const mintingFinished = await this.token.mintingFinished(); | ||
assert.equal(mintingFinished, true); | ||
}); | ||
it('emits a mint finished event', async function () { | ||
const { logs } = await this.token.finishMinting({ from }); | ||
assert.equal(logs.length, 1); | ||
assert.equal(logs[0].event, 'MintFinished'); | ||
}); | ||
}); | ||
describe('when the token was already finished', function () { | ||
beforeEach(async function () { | ||
await this.token.finishMinting({ from }); | ||
}); | ||
it('reverts', async function () { | ||
await assertRevert(this.token.finishMinting({ from })); | ||
}); | ||
}); | ||
}); | ||
describe('when the sender is not the token owner', function () { | ||
const from = anotherAccount; | ||
describe('when the token was not finished', function () { | ||
it('reverts', async function () { | ||
await assertRevert(this.token.finishMinting({ from })); | ||
}); | ||
}); | ||
describe('when the token was already finished', function () { | ||
beforeEach(async function () { | ||
await this.token.finishMinting({ from: owner }); | ||
}); | ||
it('reverts', async function () { | ||
await assertRevert(this.token.finishMinting({ from })); | ||
}); | ||
}); | ||
}); | ||
}); | ||
describe('mint', function () { | ||
const amount = 100; | ||
describe('when the sender is the token owner', function () { | ||
const from = owner; | ||
describe('when the token was not finished', function () { | ||
it('mints the requested amount', async function () { | ||
await this.token.mint(owner, amount, { from }); | ||
const balance = await this.token.balanceOf(owner); | ||
assert.equal(balance, amount); | ||
}); | ||
it('emits a mint finished event', async function () { | ||
const { logs } = await this.token.mint(owner, amount, { from }); | ||
assert.equal(logs.length, 2); | ||
assert.equal(logs[0].event, 'Mint'); | ||
assert.equal(logs[0].args.to, owner); | ||
assert.equal(logs[0].args.amount, amount); | ||
assert.equal(logs[1].event, 'Transfer'); | ||
}); | ||
}); | ||
describe('when the token minting is finished', function () { | ||
beforeEach(async function () { | ||
await this.token.finishMinting({ from }); | ||
}); | ||
it('reverts', async function () { | ||
await assertRevert(this.token.mint(owner, amount, { from })); | ||
}); | ||
}); | ||
}); | ||
describe('when the sender is not the token owner', function () { | ||
const from = anotherAccount; | ||
describe('when the token was not finished', function () { | ||
it('reverts', async function () { | ||
await assertRevert(this.token.mint(owner, amount, { from })); | ||
}); | ||
}); | ||
describe('when the token was already finished', function () { | ||
beforeEach(async function () { | ||
await this.token.finishMinting({ from: owner }); | ||
}); | ||
it('reverts', async function () { | ||
await assertRevert(this.token.mint(owner, amount, { from })); | ||
}); | ||
}); | ||
}); | ||
}); | ||
shouldBehaveLikeMintableToken([owner, anotherAccount, minter]); | ||
}); |
@@ -1,2 +0,2 @@ | ||
import EVMThrow from '../../helpers/EVMThrow'; | ||
import EVMRevert from '../../helpers/EVMRevert'; | ||
@@ -15,11 +15,11 @@ require('chai') | ||
it('should throw on failed transfer', async function () { | ||
await this.helper.doFailingTransfer().should.be.rejectedWith(EVMThrow); | ||
await this.helper.doFailingTransfer().should.be.rejectedWith(EVMRevert); | ||
}); | ||
it('should throw on failed transferFrom', async function () { | ||
await this.helper.doFailingTransferFrom().should.be.rejectedWith(EVMThrow); | ||
await this.helper.doFailingTransferFrom().should.be.rejectedWith(EVMRevert); | ||
}); | ||
it('should throw on failed approve', async function () { | ||
await this.helper.doFailingApprove().should.be.rejectedWith(EVMThrow); | ||
await this.helper.doFailingApprove().should.be.rejectedWith(EVMRevert); | ||
}); | ||
@@ -26,0 +26,0 @@ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
321724
145
4741
91