Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
O
openzeppelin-contracts-upgradeable
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
俞永鹏
openzeppelin-contracts-upgradeable
Commits
19de09af
Commit
19de09af
authored
Oct 09, 2018
by
Nicolás Venturo
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'master' into storage-slots
parents
932a39f5
6956b935
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
0 additions
and
241 deletions
+0
-241
BreakInvariantBounty.sol
contracts/drafts/BreakInvariantBounty.sol
+0
-98
BreakInvariantBountyMock.sol
contracts/mocks/BreakInvariantBountyMock.sol
+0
-33
BreakInvariantBounty.test.js
test/drafts/BreakInvariantBounty.test.js
+0
-110
No files found.
contracts/drafts/BreakInvariantBounty.sol
deleted
100644 → 0
View file @
932a39f5
pragma solidity ^0.4.24;
import "../Initializable.sol";
import "../payment/PullPayment.sol";
import "../ownership/Ownable.sol";
/**
* @title BreakInvariantBounty
* @dev This bounty will pay out to a researcher if they break invariant logic of the contract.
*/
contract BreakInvariantBounty is Initializable, PullPayment, Ownable {
bool private _claimed;
mapping(address => address) private _researchers;
event TargetCreated(address createdAddress);
function initialize(address sender) public initializer {
PullPayment.initialize();
Ownable.initialize(sender);
}
/**
* @dev Fallback function allowing the contract to receive funds, if they haven't already been claimed.
*/
function() external payable {
require(!_claimed);
}
/**
* @dev Determine if the bounty was claimed.
* @return true if the bounty was claimed, false otherwise.
*/
function claimed() public view returns(bool) {
return _claimed;
}
/**
* @dev Create and deploy the target contract (extension of Target contract), and sets the
* msg.sender as a researcher
* @return A target contract
*/
function createTarget() public returns(Target) {
Target target = Target(_deployContract());
_researchers[target] = msg.sender;
emit TargetCreated(target);
return target;
}
/**
* @dev Transfers the contract funds to the researcher that proved the contract is broken.
* @param target contract
*/
function claim(Target target) public {
require(!_claimed);
address researcher = _researchers[target];
require(researcher != address(0));
// Check Target contract invariants
require(!target.checkInvariant());
_asyncTransfer(researcher, address(this).balance);
_claimed = true;
}
/**
* @dev Transfers the current balance to the owner and terminates the contract.
*/
function destroy() public onlyOwner {
selfdestruct(owner());
}
/**
* @dev Internal function to deploy the target contract.
* @return A target contract address
*/
function _deployContract() internal returns(address);
uint256[50] private ______gap;
}
/**
* @title Target
* @dev Your main contract should inherit from this class and implement the checkInvariant method.
*/
contract Target {
/**
* @dev Checks all values a contract assumes to be true all the time. If this function returns
* false, the contract is broken in some way and is in an inconsistent state.
* In order to win the bounty, security researchers will try to cause this broken state.
* @return True if all invariant values are correct, false otherwise.
*/
function checkInvariant() public returns(bool);
uint256[50] private ______gap;
}
contracts/mocks/BreakInvariantBountyMock.sol
deleted
100644 → 0
View file @
932a39f5
pragma solidity ^0.4.24;
// When this line is split, truffle parsing fails.
// See: https://github.com/ethereum/solidity/issues/4871
// solium-disable-next-line max-len
import {BreakInvariantBounty, Target} from "../drafts/BreakInvariantBounty.sol";
contract TargetMock is Target {
bool private exploited;
function exploitVulnerability() public {
exploited = true;
}
function checkInvariant() public returns (bool) {
if (exploited) {
return false;
}
return true;
}
}
contract BreakInvariantBountyMock is BreakInvariantBounty {
constructor() public {
BreakInvariantBounty.initialize(msg.sender);
}
function _deployContract() internal returns (address) {
return new TargetMock();
}
}
test/drafts/BreakInvariantBounty.test.js
deleted
100644 → 0
View file @
932a39f5
const
{
ethGetBalance
,
ethSendTransaction
}
=
require
(
'../helpers/web3'
);
const
expectEvent
=
require
(
'../helpers/expectEvent'
);
const
{
assertRevert
}
=
require
(
'../helpers/assertRevert'
);
const
BreakInvariantBountyMock
=
artifacts
.
require
(
'BreakInvariantBountyMock'
);
const
TargetMock
=
artifacts
.
require
(
'TargetMock'
);
require
(
'chai'
)
.
use
(
require
(
'chai-bignumber'
)(
web3
.
BigNumber
))
.
should
();
const
reward
=
new
web3
.
BigNumber
(
web3
.
toWei
(
1
,
'ether'
));
contract
(
'BreakInvariantBounty'
,
function
([
_
,
owner
,
researcher
,
anyone
,
nonTarget
])
{
beforeEach
(
async
function
()
{
this
.
bounty
=
await
BreakInvariantBountyMock
.
new
({
from
:
owner
});
});
it
(
'can set reward'
,
async
function
()
{
await
ethSendTransaction
({
from
:
owner
,
to
:
this
.
bounty
.
address
,
value
:
reward
});
(
await
ethGetBalance
(
this
.
bounty
.
address
)).
should
.
be
.
bignumber
.
equal
(
reward
);
});
context
(
'with reward'
,
function
()
{
beforeEach
(
async
function
()
{
await
ethSendTransaction
({
from
:
owner
,
to
:
this
.
bounty
.
address
,
value
:
reward
});
});
describe
(
'destroy'
,
function
()
{
it
(
'returns all balance to the owner'
,
async
function
()
{
const
ownerPreBalance
=
await
ethGetBalance
(
owner
);
await
this
.
bounty
.
destroy
({
from
:
owner
,
gasPrice
:
0
});
const
ownerPostBalance
=
await
ethGetBalance
(
owner
);
(
await
ethGetBalance
(
this
.
bounty
.
address
)).
should
.
be
.
bignumber
.
equal
(
0
);
ownerPostBalance
.
sub
(
ownerPreBalance
).
should
.
be
.
bignumber
.
equal
(
reward
);
});
it
(
'reverts when called by anyone'
,
async
function
()
{
await
assertRevert
(
this
.
bounty
.
destroy
({
from
:
anyone
}));
});
});
describe
(
'claim'
,
function
()
{
it
(
'is initially unclaimed'
,
async
function
()
{
(
await
this
.
bounty
.
claimed
()).
should
.
equal
(
false
);
});
it
(
'can create claimable target'
,
async
function
()
{
const
{
logs
}
=
await
this
.
bounty
.
createTarget
({
from
:
researcher
});
expectEvent
.
inLogs
(
logs
,
'TargetCreated'
);
});
context
(
'with target'
,
async
function
()
{
beforeEach
(
async
function
()
{
const
{
logs
}
=
await
this
.
bounty
.
createTarget
({
from
:
researcher
});
const
event
=
expectEvent
.
inLogs
(
logs
,
'TargetCreated'
);
this
.
target
=
TargetMock
.
at
(
event
.
args
.
createdAddress
);
});
context
(
'before exploiting vulnerability'
,
async
function
()
{
it
(
'reverts when claiming reward'
,
async
function
()
{
await
assertRevert
(
this
.
bounty
.
claim
(
this
.
target
.
address
,
{
from
:
researcher
}));
});
});
context
(
'after exploiting vulnerability'
,
async
function
()
{
beforeEach
(
async
function
()
{
await
this
.
target
.
exploitVulnerability
({
from
:
researcher
});
});
it
(
'sends the reward to the researcher'
,
async
function
()
{
await
this
.
bounty
.
claim
(
this
.
target
.
address
,
{
from
:
anyone
});
const
researcherPreBalance
=
await
ethGetBalance
(
researcher
);
await
this
.
bounty
.
withdrawPayments
(
researcher
);
const
researcherPostBalance
=
await
ethGetBalance
(
researcher
);
researcherPostBalance
.
sub
(
researcherPreBalance
).
should
.
be
.
bignumber
.
equal
(
reward
);
(
await
ethGetBalance
(
this
.
bounty
.
address
)).
should
.
be
.
bignumber
.
equal
(
0
);
});
context
(
'after claiming'
,
async
function
()
{
beforeEach
(
async
function
()
{
await
this
.
bounty
.
claim
(
this
.
target
.
address
,
{
from
:
researcher
});
});
it
(
'is claimed'
,
async
function
()
{
(
await
this
.
bounty
.
claimed
()).
should
.
equal
(
true
);
});
it
(
'no longer accepts rewards'
,
async
function
()
{
await
assertRevert
(
ethSendTransaction
({
from
:
owner
,
to
:
this
.
bounty
.
address
,
value
:
reward
}));
});
it
(
'reverts when reclaimed'
,
async
function
()
{
await
assertRevert
(
this
.
bounty
.
claim
(
this
.
target
.
address
,
{
from
:
researcher
}));
});
});
});
});
context
(
'with non-target'
,
function
()
{
it
(
'reverts when claiming reward'
,
async
function
()
{
await
assertRevert
(
this
.
bounty
.
claim
(
nonTarget
,
{
from
:
researcher
}));
});
});
});
});
});
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment