Skip to content

Commit

Permalink
sequentially test 4 segments of an updated bounties contract in _isBo…
Browse files Browse the repository at this point in the history
…untyContractValid
  • Loading branch information
topocount committed Jul 14, 2019
1 parent e44aba7 commit c79afa7
Show file tree
Hide file tree
Showing 5 changed files with 102 additions and 48 deletions.
56 changes: 29 additions & 27 deletions apps/projects/contracts/Projects.sol
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
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/EtherTokenConstant.sol";

Expand Down Expand Up @@ -93,26 +92,14 @@ interface Bounties {
) external;
}

interface Relayer {
function metaFulfillBounty(
bytes _signature,
uint _bountyId,
address[] _fulfillers,
string _data,
uint256 _nonce
) external;
}

interface ERC20Token {
function approve(address _spender, uint256 _value) external returns (bool success);
function transfer(address to, uint tokens) external returns (bool success);
}


contract Projects is AragonApp, DepositableStorage {
using SafeMath for uint256;
Bounties public bounties;
Relayer public relayer;
BountySettings public settings;
Vault public vault;
// Auth roles
Expand Down Expand Up @@ -148,8 +135,6 @@ contract Projects is AragonApp, DepositableStorage {
uint256 bountyDeadline;
address bountyCurrency;
address bountyAllocator;
//address metaTxRelayer; TODO: Implement this interface
//address bountyArbiter;
}

struct Repo {
Expand Down Expand Up @@ -204,9 +189,6 @@ contract Projects is AragonApp, DepositableStorage {
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 BountyCode(bytes id);
event BountyHash(bytes32 id);
event BountySize(uint256 size);

////////////////
// Constructor
Expand All @@ -220,6 +202,9 @@ contract Projects is AragonApp, DepositableStorage {
setDepositable(true);

require(isContract(_vault), ERROR_PROJECTS_VAULT_NOT_CONTRACT);
require(isContract(_bountiesAddr), ERROR_STANDARD_BOUNTIES_NOT_CONTRACT);
// We need to discuss whether or not we want to implement this here instead:
//require(_isBountiesContractValid(_bountiesAddr), ERROR_STANDARD_BOUNTIES_NOT_CONTRACT);

vault = _vault;

Expand Down Expand Up @@ -255,6 +240,7 @@ contract Projects is AragonApp, DepositableStorage {
) external auth(CHANGE_SETTINGS_ROLE)
{
require(_expMultipliers.length == _expLevels.length, "experience level arrays lengths must match");
require(_isBountiesContractValid(_bountyAllocator), ERROR_STANDARD_BOUNTIES_NOT_CONTRACT);
settings.expLevels.length = 0;
settings.expMultipliers.length = 0;
for (uint i = 0; i < _expLevels.length; i++) {
Expand Down Expand Up @@ -712,23 +698,39 @@ contract Projects is AragonApp, DepositableStorage {
/**
* @dev checks the hashed contract code to ensure it matches the provided hash
*/
function _isBountiesContractValid(address _bountyRegistry) public returns(bool) {
function _isBountiesContractValid(address _bountyRegistry) internal returns(bool) {
if (_bountyRegistry == address(0)) {
return false;
}
if (_bountyRegistry == settings.bountyAllocator) {
return true;
}
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);
uint256 segments = 4;
uint256 segmentLength = size / segments;
bytes memory registryCode = new bytes(segmentLength);
bytes32[4] memory validRegistryHashes = [
bytes32(0xfc91efaeeeb7f0cc43f01b8cead464905b5f118e67d9f1308414d24785ae16d1),
bytes32(0xb5d9f74367256d83b058680a66f63782846105d68b8fb68340ce76c9237a3f0b),
bytes32(0x0f23f2b2b348e8fd656abc681cef6230496c5d117d288b898c8e6edf6476bce0),
bytes32(0x4096b2d76eb15fdbbd8e6ab3e7cabb4bfff876bf242c0731d6187fc76c21c52f)
];
for (uint256 i = 0; i < segments; i++) {

assembly{ extcodecopy(_bountyRegistry,add(0x20,registryCode),div(mul(i,segmentLength),segments),segmentLength) }
if (validRegistryHashes[i] != keccak256(registryCode)) {
return false;
}
}
//bytes memory registryCode = new bytes(size / 2);
//assembly{ extcodecopy(_bountyRegistry,add(0x20,registryCode),div(size,2),div(size,2)) }
//bytes32 validRegistryHash = 0xf1d821748591de88239c2e66e956de5b732c5202ff72c44c879add9cf56aecc1;
//return validRegistryHash == keccak256(registryCode);
return true;
}

/**
Expand Down
80 changes: 67 additions & 13 deletions apps/projects/test/projects.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -167,8 +167,10 @@ contract('Projects App', accounts => {
{ from: root }
)

// Deploy test Bounties contract
// Create mock Bounties contract object
// This address is generated using the seed phrase in the test command
bounties = { address: '0x72D1Ae1D6C8f3dd444b3D95bAd554Be483082e40'.toLowerCase() }
alternateBounties = { address: '0xDAaA2f5fbF606dEfa793984bd3615c909B1a3C93'.toLowerCase() }
vaultBase = await Vault.new()
const vaultReceipt = await dao.newAppInstance('0x5678', vaultBase.address, '0x', false, { from: root })
vault = Vault.at(vaultReceipt.logs.filter(l => l.event == 'NewAppProxy')[0].args.proxy)
Expand All @@ -194,17 +196,21 @@ contract('Projects App', accounts => {
)
})
})

it('will not initialize with invalid bounties address', async () =>{
return assertRevert(async () => {
await app.initialize(
ZERO_ADDR,
vault.address,
)
})
})
})
context('post-initialization', () => {
beforeEach(async () =>{
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 Expand Up @@ -1118,7 +1124,6 @@ contract('Projects App', accounts => {
336, // bountyDeadline
ZERO_ADDR, // bountyCurrency
bounties.address // bountyAllocator
//0x0000000000000000000000000000000000000000 //bountyArbiter
)
})
})
Expand All @@ -1136,7 +1141,6 @@ contract('Projects App', accounts => {
336, // bountyDeadline
ZERO_ADDR, // bountyCurrency
bounties.address // bountyAllocator
//0x0000000000000000000000000000000000000000 //bountyArbiter
)

response = await app.getSettings()
Expand Down Expand Up @@ -1171,11 +1175,61 @@ contract('Projects App', accounts => {
bounties.address,
'StandardBounties Contract address incorrect'
)
//assert.strictEqual(
// response[5],
// '0x0000000000000000000000000000000000000000',
// 'arbiter incorrect'
//)
})

it('cannot update bounties contract with a 0x0 address', async () => {
return assertRevert( async () => {
await app.changeBountySettings(
[ 100, 300, 500, 1000 ], // xp multipliers
[
// Experience Levels
web3.fromAscii('Beginner'),
web3.fromAscii('Intermediate'),
web3.fromAscii('Advanced'),
web3.fromAscii('Expert'),
],
1, // baseRate
336, // bountyDeadline
ZERO_ADDR, // bountyCurrency
0 // bountyAllocator
)
})
})

it('cannot update bounties contract with contract of invalid size', async () => {
return assertRevert( async () => {
await app.changeBountySettings(
[ 100, 300, 500, 1000 ], // xp multipliers
[
// Experience Levels
web3.fromAscii('Beginner'),
web3.fromAscii('Intermediate'),
web3.fromAscii('Advanced'),
web3.fromAscii('Expert'),
],
1, // baseRate
336, // bountyDeadline
ZERO_ADDR, // bountyCurrency
app.address // bountyAllocator
)
})
})

it('can update bounties contract with a new valid contract instance', async () => {
await app.changeBountySettings(
[ 100, 300, 500, 1000 ], // xp multipliers
[
// Experience Levels
web3.fromAscii('Beginner'),
web3.fromAscii('Intermediate'),
web3.fromAscii('Advanced'),
web3.fromAscii('Expert'),
],
1, // baseRate
336, // bountyDeadline
ZERO_ADDR, // bountyCurrency
alternateBounties.address // bountyAllocator
)
})
})

Expand Down
4 changes: 3 additions & 1 deletion apps/projects/utils/coverage-prep.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@ sleep 5
IFS=$'\n'
cd ../../shared/integrations/StandardBounties
BOUNT_ADDR=($(./node_modules/.bin/truffle migrate --network coverage | grep "^0x[[:alnum:]]\{40\}"))
echo "Bounties Addresses: ${BOUNT_ADDR[*]}"
BOUNT_ADDR=($(./node_modules/.bin/truffle migrate --network coverage | grep "^0x[[:alnum:]]\{40\}"))
echo "Alternate Bounties Addresses: ${BOUNT_ADDR[*]}"
#./node_modules/.bin/truffle version
#./node_modules/.bin/truffle migrate --network coverage
cd ../../../apps/projects
unset IFS
echo "Bounties Addresses: ${BOUNT_ADDR[*]}"
#BOUNT_ADDR=${BOUNT_ADDR[*]} truffle test --network rpc
4 changes: 3 additions & 1 deletion apps/projects/utils/test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@ sleep 5
IFS=$'\n'
cd ../../shared/integrations/StandardBounties
BOUNT_ADDR=($(./node_modules/.bin/truffle migrate --network development | grep "^0x[[:alnum:]]\{40\}"))
echo "Bounties Addresses: ${BOUNT_ADDR[*]}"
BOUNT_ADDR=($(./node_modules/.bin/truffle migrate --network development | grep "^0x[[:alnum:]]\{40\}"))
echo "Alternate Bounties Addresses: ${BOUNT_ADDR[*]}"
#./node_modules/.bin/truffle version
#./node_modules/.bin/truffle migrate --network development
cd ../../../apps/projects
unset IFS
echo "Bounties Addresses: ${BOUNT_ADDR[*]}"
BOUNT_ADDR=${BOUNT_ADDR[*]} truffle test --network rpc
Original file line number Diff line number Diff line change
@@ -1,15 +1,9 @@
const StandardBounties = artifacts.require("../contacts/StandardBounties.sol");
const BountiesMetaTxRelayer = artifacts.require("../contracts/BountiesMetaTxRelayer.sol")

module.exports = function(deployer) {
console.log('test')
deployer.deploy(StandardBounties)
.then(instance => {
console.log(instance.address )
return instance.address
})
.then( bountiesAddress =>
deployer.deploy(BountiesMetaTxRelayer, bountiesAddress)
.then(instance => console.log(instance.address ))
)
};

0 comments on commit c79afa7

Please sign in to comment.