Skip to content

Commit

Permalink
utilize extcodecopy to hash external contract
Browse files Browse the repository at this point in the history
  • Loading branch information
topocount committed Jul 12, 2019
1 parent 6f897d8 commit e44aba7
Show file tree
Hide file tree
Showing 7 changed files with 60 additions and 52 deletions.
2 changes: 0 additions & 2 deletions apps/address-book/contracts/test/TestImports.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@ import "@tps/test-helpers/contracts/factory/EVMScriptRegistryFactory.sol";

import "@tps/test-helpers/contracts/lib/misc/Migrations.sol";
import "@aragon/apps-shared-minime/contracts/MiniMeToken.sol";
import "@tps/test-helpers/contracts/lib/bounties/StandardBounties.sol";
import "@tps/test-helpers/contracts/lib/bounties/BountiesEvents.sol";

// You might think this file is a bit odd, but let me explain.
// We only use some contracts in our tests, which means Truffle
Expand Down
7 changes: 3 additions & 4 deletions apps/address-book/test/Spoof.sol
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
pragma solidity ^0.4.24;

import "@tps/test-helpers/contracts/factory/EVMScriptRegistryFactory.sol";
import "@tps/test-helpers/contracts/factory/DAOFactory.sol";
import "@tps/test-helpers/contracts/acl/ACL.sol";
import "@aragon/apps-shared-minime/contracts/MiniMeToken.sol";
import "@tps/test-helpers/contracts/lib/bounties/StandardBounties.sol";
import "@tps/test-helpers/contracts/lib/bounties/BountiesEvents.sol";

// You might think this file is a bit odd, but let me explain.
// We only use the MiniMeToken contract in our tests, which
Expand All @@ -24,4 +23,4 @@ import "@aragon/apps-shared-minime/contracts/MiniMeToken.sol";

contract Spoof { // solium-disable-line no-empty-blocks
// ...
}
}
2 changes: 2 additions & 0 deletions apps/planning-suite-kit/contracts/PlanningKit.sol
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,8 @@ contract PlanningKit is KitBase {

// Projects permissions:
acl.createPermission(root, projects, projects.FUND_ISSUES_ROLE(), voting);
acl.createPermission(root, projects, projects.FUND_OPEN_ISSUES_ROLE(), voting);
acl.createPermission(root, projects, projects.UPDATE_BOUNTIES_ROLE(), voting);
acl.createPermission(root, projects, projects.REMOVE_ISSUES_ROLE(), voting);
acl.createPermission(voting, projects, projects.ADD_REPO_ROLE(), voting);
acl.createPermission(voting, projects, projects.CHANGE_SETTINGS_ROLE(), voting);
Expand Down
91 changes: 48 additions & 43 deletions apps/projects/contracts/Projects.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@ pragma solidity ^0.4.24;
import "@aragon/os/contracts/apps/AragonApp.sol";
import "@aragon/os/contracts/lib/math/SafeMath.sol";
import "@aragon/apps-vault/contracts/Vault.sol";
import "@aragon/os/contracts/common/IsContract.sol";

import "@aragon/os/contracts/common/EtherTokenConstant.sol";

/*******************************************************************************
Copyright 2018, That Planning Suite
Expand Down Expand Up @@ -110,14 +109,12 @@ interface ERC20Token {
}


contract Projects is IsContract, AragonApp, DepositableStorage {
contract Projects is AragonApp, DepositableStorage {
using SafeMath for uint256;
Bounties public bounties;
Relayer public relayer;
BountySettings public settings;
Vault public vault;
//holds all work submissions
WorkSubmission[] workSubmissions;
// Auth roles
bytes32 public constant FUND_ISSUES_ROLE = keccak256("FUND_ISSUES_ROLE");
bytes32 public constant REMOVE_ISSUES_ROLE = keccak256("REMOVE_ISSUES_ROLE");
Expand All @@ -130,7 +127,7 @@ contract Projects is IsContract, AragonApp, DepositableStorage {
bytes32 public constant FUND_OPEN_ISSUES_ROLE = keccak256("FUND_OPEN_ISSUES_ROLE");
bytes32 public constant UPDATE_BOUNTIES_ROLE = keccak256("UPDATE_BOUNTIES_ROLE");

string private constant ERROR_VAULT_NOT_CONTRACT = "PROJECTS_VAULT_NOT_CONTRACT";
string private constant ERROR_PROJECTS_VAULT_NOT_CONTRACT = "PROJECTS_VAULT_NOT_CONTRACT";
string private constant ERROR_STANDARD_BOUNTIES_NOT_CONTRACT = "STANDARD_BOUNTIES_NOT_CONTRACT";
string private constant ERROR_LENGTH_EXCEEDED = "LENGTH_EXCEEDED";
string private constant ERROR_LENGTH_MISMATCH = "LENGTH_MISMATCH";
Expand Down Expand Up @@ -160,14 +157,6 @@ contract Projects is IsContract, AragonApp, DepositableStorage {
uint index;
}


struct WorkSubmission {
SubmissionStatus status;
string submissionHash; //IPFS hash of the Pull Request
uint256 fulfillmentId; // Standard Bounties Fulfillment ID
address submitter;
}

struct AssignmentRequest {
SubmissionStatus status;
string requestHash; //IPFS hash of the application data
Expand All @@ -189,7 +178,6 @@ contract Projects is IsContract, AragonApp, DepositableStorage {
//uint256 submissionQty;
uint256[] submissionIndices;
mapping(address => AssignmentRequest) assignmentRequests;
//mapping(address => WorkSubmission) workSubmissions;
}

// Fired when a repository is added to the registry.
Expand All @@ -210,29 +198,28 @@ contract Projects is IsContract, AragonApp, DepositableStorage {
event AssignmentRequested(bytes32 indexed repoId, uint256 issueNumber);
// Fired when Task Manager approves assignment request
event AssignmentApproved(address applicant, bytes32 indexed repoId, uint256 issueNumber);
// Fired when a user submits work towards an issue
event WorkSubmitted(bytes32 repoId, uint256 issueNumber);
// Fired when a reviewer accepts accepts a submission
event SubmissionAccepted(uint256 submissionNumber, bytes32 repoId, uint256 issueNumber);
// Fired when a reviewer rejects a submission
event SubmissionRejected(uint256 submissionNumber, bytes32 repoId, uint256 issueNumber);
// Fired when a bounty is opened up to work submissions from anyone
event AwaitingSubmissions(bytes32 repoId, uint256 issueNumber);
event BountyTest(uint256 id);
event BountyCode(bytes id);
event BountyHash(bytes32 id);
event BountySize(uint256 size);

////////////////
// Constructor
////////////////
function initialize(
address _bountiesAddr,
//address _relayer, TODO: Implement this
Vault _vault
) external onlyInit // solium-disable-line visibility-first
{
initialized();
setDepositable(true);

require(isContract(_vault), ERROR_VAULT_NOT_CONTRACT);
require(isContract(_vault), ERROR_PROJECTS_VAULT_NOT_CONTRACT);

vault = _vault;

Expand All @@ -245,9 +232,8 @@ contract Projects is IsContract, AragonApp, DepositableStorage {
_changeBountySettings(
100, // baseRate
336, // bountyDeadline
address(0), // default bounty currency inits to zero
ETH, // default bounty currency inits to ETH
_bountiesAddr // bountyAllocator
//0x0000000000000000000000000000000000000000 //bountyArbiter
);
}

Expand Down Expand Up @@ -344,7 +330,7 @@ contract Projects is IsContract, AragonApp, DepositableStorage {
///////////////////////
/**
* @notice Add repository to the Projects app
* @param _repoId id of the repo to be aadded
* @param _repoId id of the repo to be added
* @return index for the added repo at the registry
*/
function addRepo(
Expand Down Expand Up @@ -427,7 +413,7 @@ contract Projects is IsContract, AragonApp, DepositableStorage {
) external auth(REVIEW_APPLICATION_ROLE)
{
Issue storage issue = repos[_repoId].issues[_issueNumber];
require(issue.assignee != 0xffffffffffffffffffffffffffffffffffffffff, "ISSUE_OPEN");
require(issue.assignee != address(-1), "ISSUE_OPEN");
require(issue.assignmentRequests[_requestor].exists == true, "User has not applied for this issue");
issue.assignee = _requestor;
issue.assignmentRequests[_requestor].requestHash = _updatedApplication;
Expand Down Expand Up @@ -476,20 +462,16 @@ contract Projects is IsContract, AragonApp, DepositableStorage {
_tokenAmounts
);
issue.fulfilled = true;
bounties.performAction(
address(this),
issue.standardBountyId,
_updatedSubmissionHash
);
emit SubmissionAccepted(_submissionNumber, _repoId, _issueNumber);
} else {
bounties.performAction(
address(this),
issue.standardBountyId,
_updatedSubmissionHash
);
emit SubmissionRejected(_submissionNumber, _repoId, _issueNumber);
}

bounties.performAction(
address(this),
issue.standardBountyId,
_updatedSubmissionHash
);
}

/**
Expand Down Expand Up @@ -727,6 +709,28 @@ contract Projects is IsContract, AragonApp, DepositableStorage {
// Internal functions
///////////////////////

/**
* @dev checks the hashed contract code to ensure it matches the provided hash
*/
function _isBountiesContractValid(address _bountyRegistry) public returns(bool) {
if (_bountyRegistry == address(0)) {
return false;
}
uint256 size;
assembly { size := extcodesize(_bountyRegistry) }
if (size != 23375) {
return false;
}
bytes memory registryCode = new bytes(size);
assembly{ extcodecopy(_bountyRegistry,add(0x20,registryCode),0,size) }
bytes32 validRegistryHash = 0x6b4e1d628daf631858f6b98fe7a46bc39a5519bcb11b151a53ab7248b3a6381f;
emit BountyCode(registryCode);
emit BountyHash(keccak256(registryCode));
emit BountyHash(validRegistryHash);
emit BountySize(size);
return validRegistryHash == keccak256(registryCode);
}

/**
* @notice update bounty setting values
* @dev _changeBountySettings(): update app settings by changing contract setting state
Expand Down Expand Up @@ -762,9 +766,10 @@ contract Projects is IsContract, AragonApp, DepositableStorage {

/**
* @notice passes provided info to the linked Standard Bounties contract
* @dev _issueBounty(): There are two forms of the issueAndContribute call.
* The first is used if an ERC20 token is the bounty currency
* The second is used if ETH is the bounty currency
* @dev _issueBounty(): There are three forms of the contribute call.
* The first is used if ETH from the user is used as the bounty contribution
* The second is used if ETH from the vault is the bounty currency
* The third is used if an ERC20 token from the vault is the bounty currency
*/
function _issueBounty(
string _ipfsHash,
Expand All @@ -777,10 +782,10 @@ contract Projects is IsContract, AragonApp, DepositableStorage {
require(_tokenType != 721, "No ERC 721");
uint256 registryTokenType;
if (_tokenType == 0) {
require(_tokenContract == address(0));
require(_tokenContract == ETH);
registryTokenType = _tokenType;
} else if (_tokenType == 1) {
require(_tokenContract == address(0));
require(_tokenContract == ETH);
registryTokenType = 0;
} else {
registryTokenType = _tokenType;
Expand Down Expand Up @@ -845,9 +850,9 @@ contract Projects is IsContract, AragonApp, DepositableStorage {
_tokenContract,
_bountySize,
999,
address(0),
ETH,
_standardBountyId,
address(0),
ETH,
emptyAddressArray,
//address(0),
//0,
Expand Down Expand Up @@ -878,6 +883,7 @@ contract Projects is IsContract, AragonApp, DepositableStorage {
Issue storage issue = repos[_repoId].issues[_issueNumber];
require(issue.hasBounty, ERROR_BOUNTY_REMOVED);
require(!issue.fulfilled, ERROR_BOUNTY_FULFILLED);
issue.hasBounty = false;
uint256[] memory originalAmount = new uint256[](1);
originalAmount[0] = issue.bountySize;
bounties.drainBounty(
Expand All @@ -887,7 +893,6 @@ contract Projects is IsContract, AragonApp, DepositableStorage {
originalAmount
);
_returnValueToVault(originalAmount[0], issue.tokenContract);
issue.hasBounty = false;
issue.bountySize = 0;
bounties.changeDeadline(
address(this),
Expand All @@ -903,7 +908,7 @@ contract Projects is IsContract, AragonApp, DepositableStorage {
}

function _returnValueToVault(uint256 _amount, address _token) internal {
if (_token == address(0))
if (_token == ETH)
vault.deposit.value(_amount)(_token, _amount);
else {
ERC20Token(_token).approve(vault, _amount);
Expand Down
4 changes: 2 additions & 2 deletions apps/projects/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
"sync-assets": "copy-aragon-ui-assets -n aragon-ui ./dist && npm run copy-public-assets",
"test:gas": "GAS_REPORTER=true npm test",
"test": "TRUFFLE_TEST=true npm run ganache-cli:test",
"test:truffle": "./utils/test.sh"
"test:truffle": "./utils/test.sh"
},
"dependencies": {
"@aragon/api": "1.1.0",
Expand All @@ -41,8 +41,8 @@
"graphql": "^14.0.2",
"graphql-request": "^1.8.2",
"graphql-tag": "^2.10.0",
"marked": "0.6.1",
"ipfs-http-client": "29.1.0",
"marked": "^0.6.1",
"prop-types": "^15.7.2",
"react": "^16.8.6",
"react-apollo": "^2.3.2",
Expand Down
5 changes: 5 additions & 0 deletions apps/projects/test/projects.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,11 @@ contract('Projects App', accounts => {
await app.initialize(bounties.address, vault.address)
})

it.only('checks bounty contract', async () => {
await app._isBountiesContractValid(bounties.address)
assert(false)
})

context('creating and retrieving repos and bounties', () => {
let repoId

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
// solium-disable
pragma solidity 0.5.0;
pragma experimental ABIEncoderV2;

Expand Down

0 comments on commit e44aba7

Please sign in to comment.