Skip to content

Commit

Permalink
Done
Browse files Browse the repository at this point in the history
  • Loading branch information
odd-amphora committed Nov 28, 2021
1 parent 82df543 commit bc6bbc0
Show file tree
Hide file tree
Showing 7 changed files with 89 additions and 65 deletions.
1 change: 1 addition & 0 deletions contracts/JBDirectory.sol
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,7 @@ contract JBDirectory is IJBDirectory, JBOperatable {
@param _projectId The ID of the project to set a new controller for.
@param _controller The new controller to set.
*/
// TODO(odd-amphora): Revisit access pattern with allowlist.
function setControllerOf(uint256 _projectId, IJBController _controller)
external
override
Expand Down
11 changes: 6 additions & 5 deletions test/helpers/utils.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { BigNumber } from '@ethersproject/bignumber';
import { ethers, network } from 'hardhat';

export function makePackedPermissions(permissionIndexes) {
Expand All @@ -7,16 +8,16 @@ export function makePackedPermissions(permissionIndexes) {
);
}

export async function impersonateAccount(address) {
export async function impersonateAccount(
address,
balance = BigNumber.from('0x1000000000000000000000'),
) {
await network.provider.request({
method: 'hardhat_impersonateAccount',
params: [address],
});

await network.provider.send('hardhat_setBalance', [
address,
'0x1000000000000000000000', // TODO(odd-amphora): This could be configurable.
]);
await network.provider.send('hardhat_setBalance', [address, balance.toHexString()]);

return await ethers.getSigner(address);
}
36 changes: 21 additions & 15 deletions test/jb_directory/is_terminal_delegate_of.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,7 @@ describe('JBDirectory::isTerminalDelegateOf(...)', function () {
});

async function setup() {
let [deployer, ...addrs] = await ethers.getSigners();
let caller = addrs[1];
let [deployer, projectOwner, ...addrs] = await ethers.getSigners();

let mockJbOperatorStore = await deployMockContract(deployer, jbOperatoreStore.abi);
let mockJbProjects = await deployMockContract(deployer, jbProjects.abi);
Expand All @@ -32,27 +31,32 @@ describe('JBDirectory::isTerminalDelegateOf(...)', function () {
mockJbProjects.address,
);

let terminal1 = await deployMockContract(caller, jbTerminal.abi);
let terminal2 = await deployMockContract(caller, jbTerminal.abi);
let terminal1 = await deployMockContract(projectOwner, jbTerminal.abi);
let terminal2 = await deployMockContract(projectOwner, jbTerminal.abi);

let terminal1Delegate = ethers.Wallet.createRandom().address;
await terminal1.mock.delegate.returns(terminal1Delegate);

let terminal2Delegate = ethers.Wallet.createRandom().address;
await terminal2.mock.delegate.returns(terminal2Delegate);

await mockJbProjects.mock.ownerOf.withArgs(PROJECT_ID).returns(caller.address);
await mockJbProjects.mock.ownerOf.withArgs(PROJECT_ID).returns(projectOwner.address);
await mockJbOperatorStore.mock.hasPermission
.withArgs(caller.address, caller.address, PROJECT_ID, ADD_TERMINALS_PERMISSION_INDEX)
.withArgs(
projectOwner.address,
projectOwner.address,
PROJECT_ID,
ADD_TERMINALS_PERMISSION_INDEX,
)
.returns(true);

// Add a few terminals
await jbDirectory
.connect(caller)
.connect(projectOwner)
.addTerminalsOf(PROJECT_ID, [terminal1.address, terminal2.address]);

return {
caller,
projectOwner,
deployer,
addrs,
jbDirectory,
Expand All @@ -64,22 +68,24 @@ describe('JBDirectory::isTerminalDelegateOf(...)', function () {
}

it('Should return false if no delegate is set', async function () {
const { caller, jbDirectory } = await setup();
const { projectOwner, jbDirectory } = await setup();

expect(
await jbDirectory
.connect(caller)
.connect(projectOwner)
.isTerminalDelegateOf(PROJECT_ID, ethers.Wallet.createRandom().address),
).to.be.false;
});

it('Should return true if delegate is set', async function () {
const { caller, jbDirectory, terminal1Delegate, terminal2Delegate } = await setup();
const { projectOwner, jbDirectory, terminal1Delegate, terminal2Delegate } = await setup();

expect(await jbDirectory.connect(caller).isTerminalDelegateOf(PROJECT_ID, terminal1Delegate)).to
.be.true;
expect(
await jbDirectory.connect(projectOwner).isTerminalDelegateOf(PROJECT_ID, terminal1Delegate),
).to.be.true;

expect(await jbDirectory.connect(caller).isTerminalDelegateOf(PROJECT_ID, terminal2Delegate)).to
.be.true;
expect(
await jbDirectory.connect(projectOwner).isTerminalDelegateOf(PROJECT_ID, terminal2Delegate),
).to.be.true;
});
});
40 changes: 23 additions & 17 deletions test/jb_directory/is_terminal_of.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,7 @@ describe('JBDirectory::isTerminalOf(...)', function () {
});

async function setup() {
let [deployer, ...addrs] = await ethers.getSigners();
let caller = addrs[1];
let [deployer, projectOwner, ...addrs] = await ethers.getSigners();

let mockJbOperatorStore = await deployMockContract(deployer, jbOperatoreStore.abi);
let mockJbProjects = await deployMockContract(deployer, jbProjects.abi);
Expand All @@ -32,47 +31,54 @@ describe('JBDirectory::isTerminalOf(...)', function () {
mockJbProjects.address,
);

let terminal1 = await deployMockContract(caller, jbTerminal.abi);
let terminal2 = await deployMockContract(caller, jbTerminal.abi);
let terminal1 = await deployMockContract(projectOwner, jbTerminal.abi);
let terminal2 = await deployMockContract(projectOwner, jbTerminal.abi);

await mockJbProjects.mock.ownerOf.withArgs(PROJECT_ID).returns(caller.address);
await mockJbProjects.mock.ownerOf.withArgs(PROJECT_ID).returns(projectOwner.address);
await mockJbOperatorStore.mock.hasPermission
.withArgs(caller.address, caller.address, PROJECT_ID, ADD_TERMINALS_PERMISSION_INDEX)
.withArgs(
projectOwner.address,
projectOwner.address,
PROJECT_ID,
ADD_TERMINALS_PERMISSION_INDEX,
)
.returns(true);

// Add a few terminals
await jbDirectory
.connect(caller)
.connect(projectOwner)
.addTerminalsOf(PROJECT_ID, [terminal1.address, terminal2.address]);

return { caller, deployer, addrs, jbDirectory, terminal1, terminal2 };
return { projectOwner, deployer, addrs, jbDirectory, terminal1, terminal2 };
}

it('Returns true if the terminal belongs to the project', async function () {
const { caller, jbDirectory, terminal1, terminal2 } = await setup();
const { projectOwner, jbDirectory, terminal1, terminal2 } = await setup();

expect(await jbDirectory.connect(caller).isTerminalOf(PROJECT_ID, terminal1.address)).to.be
.true;
expect(await jbDirectory.connect(projectOwner).isTerminalOf(PROJECT_ID, terminal1.address)).to
.be.true;

expect(await jbDirectory.connect(caller).isTerminalOf(PROJECT_ID, terminal2.address)).to.be
.true;
expect(await jbDirectory.connect(projectOwner).isTerminalOf(PROJECT_ID, terminal2.address)).to
.be.true;
});

it(`Returns false if the terminal doesn't belong to the project`, async function () {
const { caller, jbDirectory } = await setup();
const { projectOwner, jbDirectory } = await setup();

expect(
await jbDirectory
.connect(caller)
.connect(projectOwner)
.isTerminalOf(PROJECT_ID, ethers.Wallet.createRandom().address),
).to.be.false;
});

it(`Returns false if the project does not exist`, async function () {
const { caller, jbDirectory } = await setup();
const { projectOwner, jbDirectory } = await setup();

expect(
await jbDirectory.connect(caller).isTerminalOf(123, ethers.Wallet.createRandom().address),
await jbDirectory
.connect(projectOwner)
.isTerminalOf(123, ethers.Wallet.createRandom().address),
).to.be.false;
});
});
37 changes: 23 additions & 14 deletions test/jb_directory/primary_terminal_of.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,7 @@ describe('JBDirectory::primaryTerminalOf(...)', function () {
});

async function setup() {
let [deployer, ...addrs] = await ethers.getSigners();
let caller = addrs[1];
let [deployer, projectOwner, ...addrs] = await ethers.getSigners();

let mockJbOperatorStore = await deployMockContract(deployer, jbOperatoreStore.abi);
let mockJbProjects = await deployMockContract(deployer, jbProjects.abi);
Expand All @@ -34,47 +33,57 @@ describe('JBDirectory::primaryTerminalOf(...)', function () {
mockJbProjects.address,
);

let terminal1 = await deployMockContract(caller, jbTerminal.abi);
let terminal2 = await deployMockContract(caller, jbTerminal.abi);
let terminal1 = await deployMockContract(projectOwner, jbTerminal.abi);
let terminal2 = await deployMockContract(projectOwner, jbTerminal.abi);

await mockJbProjects.mock.ownerOf.withArgs(PROJECT_ID).returns(caller.address);
await mockJbProjects.mock.ownerOf.withArgs(PROJECT_ID).returns(projectOwner.address);
await mockJbOperatorStore.mock.hasPermission
.withArgs(caller.address, caller.address, PROJECT_ID, ADD_TERMINALS_PERMISSION_INDEX)
.withArgs(
projectOwner.address,
projectOwner.address,
PROJECT_ID,
ADD_TERMINALS_PERMISSION_INDEX,
)
.returns(true);
await mockJbOperatorStore.mock.hasPermission
.withArgs(caller.address, caller.address, PROJECT_ID, SET_PRIMARY_TERMINAL_PERMISSION_INDEX)
.withArgs(
projectOwner.address,
projectOwner.address,
PROJECT_ID,
SET_PRIMARY_TERMINAL_PERMISSION_INDEX,
)
.returns(true);

// Add a few terminals
await jbDirectory
.connect(caller)
.connect(projectOwner)
.addTerminalsOf(PROJECT_ID, [terminal1.address, terminal2.address]);

return { caller, deployer, addrs, jbDirectory, terminal1, terminal2 };
return { projectOwner, deployer, addrs, jbDirectory, terminal1, terminal2 };
}

it('Returns primary terminal if set', async function () {
const { caller, jbDirectory, terminal1 } = await setup();
const { projectOwner, jbDirectory, terminal1 } = await setup();

let token = ethers.Wallet.createRandom().address;
await terminal1.mock.token.returns(token);

await jbDirectory.connect(caller).setPrimaryTerminalOf(PROJECT_ID, terminal1.address);
await jbDirectory.connect(projectOwner).setPrimaryTerminalOf(PROJECT_ID, terminal1.address);

expect(await jbDirectory.connect(caller).primaryTerminalOf(PROJECT_ID, token)).to.equal(
expect(await jbDirectory.connect(projectOwner).primaryTerminalOf(PROJECT_ID, token)).to.equal(
terminal1.address,
);
});

it('Returns terminal with matching token if set', async function () {
const { caller, jbDirectory, terminal1, terminal2 } = await setup();
const { projectOwner, jbDirectory, terminal1, terminal2 } = await setup();

await terminal1.mock.token.returns(ethers.Wallet.createRandom().address);

let token = ethers.Wallet.createRandom().address;
await terminal2.mock.token.returns(token);

expect(await jbDirectory.connect(caller).primaryTerminalOf(PROJECT_ID, token)).to.equal(
expect(await jbDirectory.connect(projectOwner).primaryTerminalOf(PROJECT_ID, token)).to.equal(
terminal2.address,
);
});
Expand Down
5 changes: 1 addition & 4 deletions test/jb_directory/set_controller_of.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import jbOperatoreStore from '../../artifacts/contracts/JBOperatorStore.sol/JBOp
import jbController from '../../artifacts/contracts/interfaces/IJBController.sol/IJBController.json';
import jbProjects from '../../artifacts/contracts/JBProjects.sol/JBProjects.json';

// TODO(odd-amphora): Access control tests with allowlist.
describe('JBDirectory::setControllerOf(...)', function () {
const PROJECT_ID = 1;

Expand Down Expand Up @@ -119,8 +120,4 @@ describe('JBDirectory::setControllerOf(...)', function () {
await expect(jbDirectory.connect(caller).setControllerOf(PROJECT_ID, controller1.address)).to.be
.reverted;
});

it('TODO', async function () {
// TODO(odd-amphora): Permission override cases.
});
});
24 changes: 14 additions & 10 deletions test/jb_directory/terminals_of.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,7 @@ describe('JBDirectory::terminalsOf(...)', function () {
});

async function setup() {
let [deployer, ...addrs] = await ethers.getSigners();
let caller = addrs[1];
let [deployer, projectOwner, ...addrs] = await ethers.getSigners();

let mockJbOperatorStore = await deployMockContract(deployer, jbOperatoreStore.abi);
let mockJbProjects = await deployMockContract(deployer, jbProjects.abi);
Expand All @@ -32,26 +31,31 @@ describe('JBDirectory::terminalsOf(...)', function () {
mockJbProjects.address,
);

let terminal1 = await deployMockContract(caller, jbTerminal.abi);
let terminal2 = await deployMockContract(caller, jbTerminal.abi);
let terminal1 = await deployMockContract(projectOwner, jbTerminal.abi);
let terminal2 = await deployMockContract(projectOwner, jbTerminal.abi);

await mockJbProjects.mock.ownerOf.withArgs(PROJECT_ID).returns(caller.address);
await mockJbProjects.mock.ownerOf.withArgs(PROJECT_ID).returns(projectOwner.address);
await mockJbOperatorStore.mock.hasPermission
.withArgs(caller.address, caller.address, PROJECT_ID, ADD_TERMINALS_PERMISSION_INDEX)
.withArgs(
projectOwner.address,
projectOwner.address,
PROJECT_ID,
ADD_TERMINALS_PERMISSION_INDEX,
)
.returns(true);

// Add a few terminals
await jbDirectory
.connect(caller)
.connect(projectOwner)
.addTerminalsOf(PROJECT_ID, [terminal1.address, terminal2.address]);

return { caller, deployer, addrs, jbDirectory, terminal1, terminal2 };
return { projectOwner, deployer, addrs, jbDirectory, terminal1, terminal2 };
}

it('Should return terminals belonging to the project', async function () {
const { caller, jbDirectory, terminal1, terminal2 } = await setup();
const { projectOwner, jbDirectory, terminal1, terminal2 } = await setup();

let terminals = [...(await jbDirectory.connect(caller).terminalsOf(PROJECT_ID))];
let terminals = [...(await jbDirectory.connect(projectOwner).terminalsOf(PROJECT_ID))];
terminals.sort();

let expectedTerminals = [terminal1.address, terminal2.address];
Expand Down

0 comments on commit bc6bbc0

Please sign in to comment.