From 842f7f64721d72e652325e06a130589c1e7af59d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8r=E2=88=82=C2=A1?= Date: Thu, 30 Nov 2023 16:10:24 +0100 Subject: [PATCH] Conditions testing adapted --- .../src/MemberAccessExecuteCondition.sol | 6 +- .../src/OnlyPluginUpgraderCondition.sol | 6 +- .../member-access-execute-condition.ts | 78 +- .../only-plugin-upgrader-condition.ts | 1647 +++++++++++++---- packages/contracts/utils/helpers.ts | 21 +- 5 files changed, 1362 insertions(+), 396 deletions(-) diff --git a/packages/contracts/src/MemberAccessExecuteCondition.sol b/packages/contracts/src/MemberAccessExecuteCondition.sol index a886246..b1d7815 100644 --- a/packages/contracts/src/MemberAccessExecuteCondition.sol +++ b/packages/contracts/src/MemberAccessExecuteCondition.sol @@ -69,13 +69,13 @@ contract MemberAccessExecuteCondition is PermissionCondition { function decodeGrantRevokeCalldata( bytes memory _data - ) public pure returns (bytes4 sig, address who, address where, bytes32 permissionId) { + ) public pure returns (bytes4 sig, address where, address who, bytes32 permissionId) { // Slicing is only supported for bytes calldata, not bytes memory // Bytes memory requires an assembly block assembly { sig := mload(add(_data, 32)) - who := mload(add(_data, 36)) - where := mload(add(_data, 68)) + where := mload(add(_data, 36)) + who := mload(add(_data, 68)) permissionId := mload(add(_data, 100)) } } diff --git a/packages/contracts/src/OnlyPluginUpgraderCondition.sol b/packages/contracts/src/OnlyPluginUpgraderCondition.sol index a59a846..b4f252d 100644 --- a/packages/contracts/src/OnlyPluginUpgraderCondition.sol +++ b/packages/contracts/src/OnlyPluginUpgraderCondition.sol @@ -88,13 +88,13 @@ contract OnlyPluginUpgraderCondition is PermissionCondition { function decodeGrantRevokeCalldata( bytes memory _data - ) public pure returns (bytes4 selector, address who, address where, bytes32 permissionId) { + ) public pure returns (bytes4 selector, address where, address who, bytes32 permissionId) { // Slicing is only supported for bytes calldata, not bytes memory // Bytes memory requires an assembly block assembly { selector := mload(add(_data, 32)) - who := mload(add(_data, 36)) - where := mload(add(_data, 68)) + where := mload(add(_data, 36)) + who := mload(add(_data, 68)) permissionId := mload(add(_data, 100)) } } diff --git a/packages/contracts/test/unit-testing/member-access-execute-condition.ts b/packages/contracts/test/unit-testing/member-access-execute-condition.ts index 6fb9a8b..33a7825 100644 --- a/packages/contracts/test/unit-testing/member-access-execute-condition.ts +++ b/packages/contracts/test/unit-testing/member-access-execute-condition.ts @@ -5,6 +5,7 @@ import { MemberAccessExecuteCondition, MemberAccessExecuteCondition__factory, } from '../../typechain'; +import {getPluginSetupProcessorAddress} from '../../utils/helpers'; import {deployTestDao} from '../helpers/test-dao'; import { ADDRESS_ONE, @@ -20,13 +21,18 @@ import {hexlify} from '@ethersproject/bytes'; import {SignerWithAddress} from '@nomiclabs/hardhat-ethers/signers'; import {expect} from 'chai'; import {toUtf8Bytes} from 'ethers/lib/utils'; -import {ethers} from 'hardhat'; +import {ethers, network} from 'hardhat'; const SOME_CONTRACT_ADDRESS = '0x' + '1234567890'.repeat(4); const ONE_BYTES32 = '0x0000000000000000000000000000000000000000000000000000000000000001'; +const PLUGIN_ADDR_1 = ADDRESS_ONE; +const PLUGIN_ADDR_2 = ADDRESS_TWO; +const daoInterface = DAO__factory.createInterface(); describe('Member Access Condition', function () { + const pspAddress = getPluginSetupProcessorAddress(network.name, true); + let alice: SignerWithAddress; let bob: SignerWithAddress; let carol: SignerWithAddress; @@ -44,8 +50,6 @@ describe('Member Access Condition', function () { }); describe('Executing grant/revoke MEMBER_PERMISSION_ID on a certain contract', () => { - const daoInterface = DAO__factory.createInterface(); - it('Should only allow executing grant and revoke', async () => { const actions: IDAO.ActionStruct[] = [ {to: dao.address, value: 0, data: '0x'}, @@ -422,4 +426,72 @@ describe('Member Access Condition', function () { ).to.eq(false); }); }); + + describe('Decoders', () => { + it('Should decode getSelector properly', async () => { + const actions: IDAO.ActionStruct[] = [ + { + to: dao.address, + value: 0, + data: daoInterface.encodeFunctionData('grant', [ + PLUGIN_ADDR_1, + pspAddress, + MEMBER_PERMISSION_ID, + ]), + }, + { + to: dao.address, + value: 0, + data: daoInterface.encodeFunctionData('revoke', [ + PLUGIN_ADDR_1, + pspAddress, + MEMBER_PERMISSION_ID, + ]), + }, + ]; + + expect( + await memberAccessExecuteCondition.getSelector(actions[0].data) + ).to.eq((actions[0].data as string).slice(0, 10)); + + expect( + await memberAccessExecuteCondition.getSelector(actions[1].data) + ).to.eq((actions[1].data as string).slice(0, 10)); + }); + + it('Should decode decodeGrantRevokeCalldata properly', async () => { + const calldataList = [ + daoInterface.encodeFunctionData('grant', [ + PLUGIN_ADDR_1, + pspAddress, + MEMBER_PERMISSION_ID, + ]), + daoInterface.encodeFunctionData('revoke', [ + PLUGIN_ADDR_2, + bob.address, + ROOT_PERMISSION_ID, + ]), + ]; + + // 1 + let [selector, where, who, permissionId] = + await memberAccessExecuteCondition.decodeGrantRevokeCalldata( + calldataList[0] + ); + expect(selector).to.eq(calldataList[0].slice(0, 10)); + expect(where).to.eq(PLUGIN_ADDR_1); + expect(who).to.eq(pspAddress); + expect(permissionId).to.eq(MEMBER_PERMISSION_ID); + + // 2 + [selector, where, who, permissionId] = + await memberAccessExecuteCondition.decodeGrantRevokeCalldata( + calldataList[2] + ); + expect(selector).to.eq(calldataList[2].slice(0, 10)); + expect(where).to.eq(PLUGIN_ADDR_2); + expect(who).to.eq(bob.address); + expect(permissionId).to.eq(ROOT_PERMISSION_ID); + }); + }); }); diff --git a/packages/contracts/test/unit-testing/only-plugin-upgrader-condition.ts b/packages/contracts/test/unit-testing/only-plugin-upgrader-condition.ts index 39d8797..97830e1 100644 --- a/packages/contracts/test/unit-testing/only-plugin-upgrader-condition.ts +++ b/packages/contracts/test/unit-testing/only-plugin-upgrader-condition.ts @@ -1,34 +1,44 @@ import { DAO, DAO__factory, - MemberAccessExecuteCondition, - MemberAccessExecuteCondition__factory, + PluginSetupProcessor, + PluginSetupProcessor__factory, + IDAO, + OnlyPluginUpgraderCondition, + OnlyPluginUpgraderCondition__factory, } from '../../typechain'; +import {getPluginSetupProcessorAddress} from '../../utils/helpers'; import {deployTestDao} from '../helpers/test-dao'; import { ADDRESS_ONE, + ADDRESS_THREE, ADDRESS_TWO, ADDRESS_ZERO, - DEPLOYER_PERMISSION_ID, EDITOR_PERMISSION_ID, EXECUTE_PERMISSION_ID, - MEMBER_PERMISSION_ID, ROOT_PERMISSION_ID, + UPGRADE_PLUGIN_PERMISSION_ID, } from './common'; -import {hexlify} from '@ethersproject/bytes'; import {SignerWithAddress} from '@nomiclabs/hardhat-ethers/signers'; import {expect} from 'chai'; -import {toUtf8Bytes} from 'ethers/lib/utils'; -import {ethers} from 'hardhat'; +import {ethers, network} from 'hardhat'; -const SOME_CONTRACT_ADDRESS = '0x' + '1234567890'.repeat(4); +const ONE_BYTES32 = '0x' + '0'.repeat(63) + '1'; +const PLUGIN_ADDR_1 = ADDRESS_ONE; +const PLUGIN_ADDR_2 = ADDRESS_TWO; + +const daoInterface = DAO__factory.createInterface(); +const pspInterface = PluginSetupProcessor__factory.createInterface(); describe('Only Plugin Upgrader Condition', function () { + const pspAddress = getPluginSetupProcessorAddress(network.name, true); + let alice: SignerWithAddress; let bob: SignerWithAddress; let carol: SignerWithAddress; let dao: DAO; - let memberAccessExecuteCondition: MemberAccessExecuteCondition; + let onlyPluginUpgraderCondition: OnlyPluginUpgraderCondition; + let applyUpdateParams: PluginSetupProcessor.ApplyUpdateParamsStruct; before(async () => { [alice, bob, carol] = await ethers.getSigners(); @@ -36,384 +46,1261 @@ describe('Only Plugin Upgrader Condition', function () { }); beforeEach(async () => { - const factory = new MemberAccessExecuteCondition__factory(alice); - memberAccessExecuteCondition = await factory.deploy(SOME_CONTRACT_ADDRESS); - }); + const factory = new OnlyPluginUpgraderCondition__factory(alice); + onlyPluginUpgraderCondition = await factory.deploy( + dao.address, + pspAddress, + [PLUGIN_ADDR_1, PLUGIN_ADDR_2] + ); - it('Should only accept executing grant and revoke', async () => { - // Valid - expect( - await memberAccessExecuteCondition.isGranted( - ADDRESS_ONE, // where (used) - ADDRESS_TWO, // who (used) - EXECUTE_PERMISSION_ID, // permission (used) - DAO__factory.createInterface().encodeFunctionData('grant', [ - // call - SOME_CONTRACT_ADDRESS, - carol.address, - MEMBER_PERMISSION_ID, - ]) - ) - ).to.eq(true); - - expect( - await memberAccessExecuteCondition.isGranted( - ADDRESS_ONE, // where (used) - ADDRESS_TWO, // who (used) - EXECUTE_PERMISSION_ID, // permission (used) - DAO__factory.createInterface().encodeFunctionData('revoke', [ - // call - SOME_CONTRACT_ADDRESS, - carol.address, - MEMBER_PERMISSION_ID, - ]) - ) - ).to.eq(true); - - // Invalid - expect( - await memberAccessExecuteCondition.isGranted( - ADDRESS_ONE, // where (used) - ADDRESS_TWO, // who (used) - EXECUTE_PERMISSION_ID, // permission (used) - DAO__factory.createInterface().encodeFunctionData('setDaoURI', [ - // call - hexlify(toUtf8Bytes('ipfs://')), - ]) - ) - ).to.eq(false); - expect( - await memberAccessExecuteCondition.isGranted( - ADDRESS_ONE, // where (used) - ADDRESS_TWO, // who (used) - EXECUTE_PERMISSION_ID, // permission (used) - DAO__factory.createInterface().encodeFunctionData('setMetadata', [ - // call - hexlify(toUtf8Bytes('ipfs://')), - ]) - ) - ).to.eq(false); - expect( - await memberAccessExecuteCondition.isGranted( - ADDRESS_ONE, // where (used) - ADDRESS_TWO, // who (used) - EXECUTE_PERMISSION_ID, // permission (used) - DAO__factory.createInterface().encodeFunctionData( - 'setSignatureValidator', - [ - // call - ADDRESS_ONE, - ] - ) - ) - ).to.eq(false); + applyUpdateParams = { + plugin: PLUGIN_ADDR_1, + helpersHash: ONE_BYTES32, + initData: '0x', + permissions: [], + pluginSetupRef: { + pluginSetupRepo: ADDRESS_ONE, + versionTag: { + release: 1, + build: 1, + }, + }, + }; }); - it('Should only allow MEMBER_PERMISSION_ID', async () => { - // Valid - expect( - await memberAccessExecuteCondition.isGranted( - ADDRESS_ONE, // where (used) - ADDRESS_TWO, // who (used) - EXECUTE_PERMISSION_ID, // permission (used) - DAO__factory.createInterface().encodeFunctionData('grant', [ - // call - SOME_CONTRACT_ADDRESS, - carol.address, - MEMBER_PERMISSION_ID, - ]) - ) - ).to.eq(true); - expect( - await memberAccessExecuteCondition.isGranted( - ADDRESS_ONE, // where (used) - ADDRESS_TWO, // who (used) - EXECUTE_PERMISSION_ID, // permission (used) - DAO__factory.createInterface().encodeFunctionData('revoke', [ - // call - SOME_CONTRACT_ADDRESS, - carol.address, - MEMBER_PERMISSION_ID, - ]) - ) - ).to.eq(true); - - // Invalid - expect( - await memberAccessExecuteCondition.isGranted( - ADDRESS_ONE, // where (used) - ADDRESS_TWO, // who (used) - EXECUTE_PERMISSION_ID, // permission (used) - DAO__factory.createInterface().encodeFunctionData('grant', [ - // call - SOME_CONTRACT_ADDRESS, - carol.address, - EDITOR_PERMISSION_ID, - ]) - ) - ).to.eq(false); - expect( - await memberAccessExecuteCondition.isGranted( - ADDRESS_ONE, // where (used) - ADDRESS_TWO, // who (used) - EXECUTE_PERMISSION_ID, // permission (used) - DAO__factory.createInterface().encodeFunctionData('revoke', [ - // call - SOME_CONTRACT_ADDRESS, - carol.address, - EDITOR_PERMISSION_ID, - ]) - ) - ).to.eq(false); - expect( - await memberAccessExecuteCondition.isGranted( - ADDRESS_ONE, // where (used) - ADDRESS_TWO, // who (used) - EXECUTE_PERMISSION_ID, // permission (used) - DAO__factory.createInterface().encodeFunctionData('grant', [ - // call - SOME_CONTRACT_ADDRESS, - carol.address, - ROOT_PERMISSION_ID, - ]) - ) - ).to.eq(false); - expect( - await memberAccessExecuteCondition.isGranted( - ADDRESS_ONE, // where (used) - ADDRESS_TWO, // who (used) - EXECUTE_PERMISSION_ID, // permission (used) - DAO__factory.createInterface().encodeFunctionData('revoke', [ - // call - SOME_CONTRACT_ADDRESS, - carol.address, - ROOT_PERMISSION_ID, - ]) - ) - ).to.eq(false); - expect( - await memberAccessExecuteCondition.isGranted( - ADDRESS_ONE, // where (used) - ADDRESS_TWO, // who (used) - EXECUTE_PERMISSION_ID, // permission (used) - DAO__factory.createInterface().encodeFunctionData('grant', [ - // call - SOME_CONTRACT_ADDRESS, - carol.address, - DEPLOYER_PERMISSION_ID, - ]) - ) - ).to.eq(false); - expect( - await memberAccessExecuteCondition.isGranted( - ADDRESS_ONE, // where (used) - ADDRESS_TWO, // who (used) - EXECUTE_PERMISSION_ID, // permission (used) - DAO__factory.createInterface().encodeFunctionData('revoke', [ - // call - SOME_CONTRACT_ADDRESS, - carol.address, - DEPLOYER_PERMISSION_ID, - ]) - ) - ).to.eq(false); - }); + describe('Executing applyUpdate on the PSP', () => { + it('Should allow executing grant, applyUpdate and revoke on the PSP', async () => { + const actions: IDAO.ActionStruct[] = [ + { + to: dao.address, + value: 0, + data: daoInterface.encodeFunctionData('grant', [ + PLUGIN_ADDR_1, + pspAddress, + UPGRADE_PLUGIN_PERMISSION_ID, + ]), + }, + { + to: pspAddress, + value: 0, + data: pspInterface.encodeFunctionData('applyUpdate', [ + dao.address, + applyUpdateParams, + ]), + }, + { + to: dao.address, + value: 0, + data: daoInterface.encodeFunctionData('revoke', [ + PLUGIN_ADDR_1, + pspAddress, + UPGRADE_PLUGIN_PERMISSION_ID, + ]), + }, + ]; + + expect( + await onlyPluginUpgraderCondition.isGranted( + ADDRESS_ZERO, // where + ADDRESS_ZERO, // who + EXECUTE_PERMISSION_ID, // permission + daoInterface.encodeFunctionData('execute', [ONE_BYTES32, actions, 0]) + ) + ).to.eq(true); + expect( + await onlyPluginUpgraderCondition.isGranted( + ADDRESS_ONE, // where + ADDRESS_TWO, // who + EXECUTE_PERMISSION_ID, // permission + daoInterface.encodeFunctionData('execute', [ONE_BYTES32, actions, 0]) + ) + ).to.eq(true); + }); + + it('Should reject calling the methods directly', async () => { + expect( + await onlyPluginUpgraderCondition.isGranted( + ADDRESS_ZERO, // where + ADDRESS_ZERO, // who + EXECUTE_PERMISSION_ID, // permission + daoInterface.encodeFunctionData('grant', [ + PLUGIN_ADDR_1, + pspAddress, + UPGRADE_PLUGIN_PERMISSION_ID, + ]) + ) + ).to.eq(false); + expect( + await onlyPluginUpgraderCondition.isGranted( + ADDRESS_ONE, // where + ADDRESS_TWO, // who + EXECUTE_PERMISSION_ID, // permission + pspInterface.encodeFunctionData('applyUpdate', [ + dao.address, + applyUpdateParams, + ]) + ) + ).to.eq(false); + expect( + await onlyPluginUpgraderCondition.isGranted( + ADDRESS_ONE, // where + ADDRESS_TWO, // who + EXECUTE_PERMISSION_ID, // permission + daoInterface.encodeFunctionData('revoke', [ + PLUGIN_ADDR_1, + pspAddress, + UPGRADE_PLUGIN_PERMISSION_ID, + ]) + ) + ).to.eq(false); + }); + + it('Should reject calling anything other than execute', async () => { + expect( + await onlyPluginUpgraderCondition.isGranted( + ADDRESS_ZERO, // where + ADDRESS_ZERO, // who + EXECUTE_PERMISSION_ID, // permission + daoInterface.encodeFunctionData('setDaoURI', ['ipfs://']) + ) + ).to.eq(false); + expect( + await onlyPluginUpgraderCondition.isGranted( + ADDRESS_ZERO, // where + ADDRESS_ZERO, // who + EXECUTE_PERMISSION_ID, // permission + daoInterface.encodeFunctionData('setMetadata', ['ipfs://']) + ) + ).to.eq(false); + }); - it('Should only allow to target the intended plugin contract', async () => { - // Valid - expect( - await memberAccessExecuteCondition.isGranted( - ADDRESS_ONE, // where (used) - ADDRESS_TWO, // who (used) - EXECUTE_PERMISSION_ID, // permission (used) - DAO__factory.createInterface().encodeFunctionData('grant', [ - // call - SOME_CONTRACT_ADDRESS, - carol.address, - MEMBER_PERMISSION_ID, - ]) - ) - ).to.eq(true); - expect( - await memberAccessExecuteCondition.isGranted( - ADDRESS_ONE, // where (used) - ADDRESS_TWO, // who (used) - EXECUTE_PERMISSION_ID, // permission (used) - DAO__factory.createInterface().encodeFunctionData('revoke', [ - // call - SOME_CONTRACT_ADDRESS, - carol.address, - MEMBER_PERMISSION_ID, - ]) - ) - ).to.eq(true); - - // Invalid - expect( - await memberAccessExecuteCondition.isGranted( - ADDRESS_ONE, // where (used) - ADDRESS_TWO, // who (used) - EXECUTE_PERMISSION_ID, // permission (used) - DAO__factory.createInterface().encodeFunctionData('grant', [ - // call - ADDRESS_TWO, - carol.address, - MEMBER_PERMISSION_ID, - ]) - ) - ).to.eq(false); - expect( - await memberAccessExecuteCondition.isGranted( - ADDRESS_ONE, // where (used) - ADDRESS_TWO, // who (used) - EXECUTE_PERMISSION_ID, // permission (used) - DAO__factory.createInterface().encodeFunctionData('revoke', [ - // call - ADDRESS_TWO, - carol.address, - MEMBER_PERMISSION_ID, - ]) - ) - ).to.eq(false); - - expect( - await memberAccessExecuteCondition.isGranted( - ADDRESS_ONE, // where (used) - ADDRESS_TWO, // who (used) - EXECUTE_PERMISSION_ID, // permission (used) - DAO__factory.createInterface().encodeFunctionData('grant', [ - // call + it('Should reject a proposal with less than 3 actions', async () => { + let actions: IDAO.ActionStruct[] = [ + { + to: dao.address, + value: 0, + data: daoInterface.encodeFunctionData('grant', [ + PLUGIN_ADDR_1, + pspAddress, + UPGRADE_PLUGIN_PERMISSION_ID, + ]), + }, + { + to: pspAddress, + value: 0, + data: pspInterface.encodeFunctionData('applyUpdate', [ + dao.address, + applyUpdateParams, + ]), + }, + ]; + + expect( + await onlyPluginUpgraderCondition.isGranted( + ADDRESS_ZERO, // where + ADDRESS_ZERO, // who + EXECUTE_PERMISSION_ID, // permission + daoInterface.encodeFunctionData('execute', [ONE_BYTES32, actions, 0]) + ) + ).to.eq(false); + expect( + await onlyPluginUpgraderCondition.isGranted( + ADDRESS_ONE, // where + ADDRESS_TWO, // who + EXECUTE_PERMISSION_ID, // permission + daoInterface.encodeFunctionData('execute', [ONE_BYTES32, actions, 0]) + ) + ).to.eq(false); + + // 2 + actions = [ + { + to: pspAddress, + value: 0, + data: pspInterface.encodeFunctionData('applyUpdate', [ + dao.address, + applyUpdateParams, + ]), + }, + { + to: dao.address, + value: 0, + data: daoInterface.encodeFunctionData('revoke', [ + PLUGIN_ADDR_1, + pspAddress, + UPGRADE_PLUGIN_PERMISSION_ID, + ]), + }, + ]; + + expect( + await onlyPluginUpgraderCondition.isGranted( + ADDRESS_ZERO, // where + ADDRESS_ZERO, // who + EXECUTE_PERMISSION_ID, // permission + daoInterface.encodeFunctionData('execute', [ONE_BYTES32, actions, 0]) + ) + ).to.eq(false); + expect( + await onlyPluginUpgraderCondition.isGranted( + ADDRESS_ONE, // where + ADDRESS_TWO, // who + EXECUTE_PERMISSION_ID, // permission + daoInterface.encodeFunctionData('execute', [ONE_BYTES32, actions, 0]) + ) + ).to.eq(false); + }); + + it('Should reject a proposal with more than 3 actions', async () => { + const actions: IDAO.ActionStruct[] = [ + { + to: dao.address, + value: 0, + data: daoInterface.encodeFunctionData('grant', [ + PLUGIN_ADDR_1, + pspAddress, + UPGRADE_PLUGIN_PERMISSION_ID, + ]), + }, + { + to: pspAddress, + value: 0, + data: pspInterface.encodeFunctionData('applyUpdate', [ + dao.address, + applyUpdateParams, + ]), + }, + { + to: dao.address, + value: 0, + data: daoInterface.encodeFunctionData('revoke', [ + PLUGIN_ADDR_1, + pspAddress, + UPGRADE_PLUGIN_PERMISSION_ID, + ]), + }, + {to: dao.address, value: 0, data: '0x'}, + ]; + + expect( + await onlyPluginUpgraderCondition.isGranted( + ADDRESS_ZERO, // where + ADDRESS_ZERO, // who + EXECUTE_PERMISSION_ID, // permission + daoInterface.encodeFunctionData('execute', [ONE_BYTES32, actions, 0]) + ) + ).to.eq(false); + expect( + await onlyPluginUpgraderCondition.isGranted( + ADDRESS_ONE, // where + ADDRESS_TWO, // who + EXECUTE_PERMISSION_ID, // permission + daoInterface.encodeFunctionData('execute', [ONE_BYTES32, actions, 0]) + ) + ).to.eq(false); + + // 2 + actions[3] = actions[2]; + + expect( + await onlyPluginUpgraderCondition.isGranted( + ADDRESS_ZERO, // where + ADDRESS_ZERO, // who + EXECUTE_PERMISSION_ID, // permission + daoInterface.encodeFunctionData('execute', [ONE_BYTES32, actions, 0]) + ) + ).to.eq(false); + expect( + await onlyPluginUpgraderCondition.isGranted( + ADDRESS_ONE, // where + ADDRESS_TWO, // who + EXECUTE_PERMISSION_ID, // permission + daoInterface.encodeFunctionData('execute', [ONE_BYTES32, actions, 0]) + ) + ).to.eq(false); + }); + + // to + + it('Should reject if action 1/3 are not executed on the DAO', async () => { + let actions: IDAO.ActionStruct[] = [ + { + to: bob.address, + value: 0, + data: daoInterface.encodeFunctionData('grant', [ + PLUGIN_ADDR_1, + pspAddress, + UPGRADE_PLUGIN_PERMISSION_ID, + ]), + }, + { + to: pspAddress, + value: 0, + data: pspInterface.encodeFunctionData('applyUpdate', [ + dao.address, + applyUpdateParams, + ]), + }, + { + to: dao.address, + value: 0, + data: daoInterface.encodeFunctionData('revoke', [ + PLUGIN_ADDR_1, + pspAddress, + UPGRADE_PLUGIN_PERMISSION_ID, + ]), + }, + ]; + + expect( + await onlyPluginUpgraderCondition.isGranted( + ADDRESS_ZERO, // where + ADDRESS_ZERO, // who + EXECUTE_PERMISSION_ID, // permission + daoInterface.encodeFunctionData('execute', [ONE_BYTES32, actions, 0]) + ) + ).to.eq(false); + expect( + await onlyPluginUpgraderCondition.isGranted( + ADDRESS_ONE, // where + ADDRESS_TWO, // who + EXECUTE_PERMISSION_ID, // permission + daoInterface.encodeFunctionData('execute', [ONE_BYTES32, actions, 0]) + ) + ).to.eq(false); + + // 2 + actions = [ + { + to: dao.address, + value: 0, + data: daoInterface.encodeFunctionData('grant', [ + PLUGIN_ADDR_1, + pspAddress, + UPGRADE_PLUGIN_PERMISSION_ID, + ]), + }, + { + to: pspAddress, + value: 0, + data: pspInterface.encodeFunctionData('applyUpdate', [ + dao.address, + applyUpdateParams, + ]), + }, + { + to: bob.address, + value: 0, + data: daoInterface.encodeFunctionData('revoke', [ + PLUGIN_ADDR_1, + pspAddress, + UPGRADE_PLUGIN_PERMISSION_ID, + ]), + }, + ]; + + expect( + await onlyPluginUpgraderCondition.isGranted( + ADDRESS_ZERO, // where + ADDRESS_ZERO, // who + EXECUTE_PERMISSION_ID, // permission + daoInterface.encodeFunctionData('execute', [ONE_BYTES32, actions, 0]) + ) + ).to.eq(false); + expect( + await onlyPluginUpgraderCondition.isGranted( + ADDRESS_ONE, // where + ADDRESS_TWO, // who + EXECUTE_PERMISSION_ID, // permission + daoInterface.encodeFunctionData('execute', [ONE_BYTES32, actions, 0]) + ) + ).to.eq(false); + }); + + it('Should reject if action 2 is not executed on the PSP', async () => { + let actions: IDAO.ActionStruct[] = [ + { + to: dao.address, + value: 0, + data: daoInterface.encodeFunctionData('grant', [ + PLUGIN_ADDR_1, + pspAddress, + UPGRADE_PLUGIN_PERMISSION_ID, + ]), + }, + { + to: bob.address, + value: 0, + data: pspInterface.encodeFunctionData('applyUpdate', [ + dao.address, + applyUpdateParams, + ]), + }, + { + to: dao.address, + value: 0, + data: daoInterface.encodeFunctionData('revoke', [ + PLUGIN_ADDR_1, + pspAddress, + UPGRADE_PLUGIN_PERMISSION_ID, + ]), + }, + ]; + + expect( + await onlyPluginUpgraderCondition.isGranted( + ADDRESS_ZERO, // where + ADDRESS_ZERO, // who + EXECUTE_PERMISSION_ID, // permission + daoInterface.encodeFunctionData('execute', [ONE_BYTES32, actions, 0]) + ) + ).to.eq(false); + expect( + await onlyPluginUpgraderCondition.isGranted( + ADDRESS_ONE, // where + ADDRESS_TWO, // who + EXECUTE_PERMISSION_ID, // permission + daoInterface.encodeFunctionData('execute', [ONE_BYTES32, actions, 0]) + ) + ).to.eq(false); + }); + + // grant/revoke calldata + + it('Should reject if actions 1/3 are not grant/revoke respectively', async () => { + let actions: IDAO.ActionStruct[] = [ + { + to: dao.address, + value: 0, + data: daoInterface.encodeFunctionData('revoke', [ + PLUGIN_ADDR_1, + pspAddress, + UPGRADE_PLUGIN_PERMISSION_ID, + ]), + }, + { + to: pspAddress, + value: 0, + data: pspInterface.encodeFunctionData('applyUpdate', [ + dao.address, + applyUpdateParams, + ]), + }, + { + to: dao.address, + value: 0, + data: daoInterface.encodeFunctionData('revoke', [ + PLUGIN_ADDR_1, + pspAddress, + UPGRADE_PLUGIN_PERMISSION_ID, + ]), + }, + ]; + + expect( + await onlyPluginUpgraderCondition.isGranted( + ADDRESS_ZERO, // where + ADDRESS_ZERO, // who + EXECUTE_PERMISSION_ID, // permission + daoInterface.encodeFunctionData('execute', [ONE_BYTES32, actions, 0]) + ) + ).to.eq(false); + expect( + await onlyPluginUpgraderCondition.isGranted( + ADDRESS_ONE, // where + ADDRESS_TWO, // who + EXECUTE_PERMISSION_ID, // permission + daoInterface.encodeFunctionData('execute', [ONE_BYTES32, actions, 0]) + ) + ).to.eq(false); + + // 2 + actions = [ + { + to: dao.address, + value: 0, + data: daoInterface.encodeFunctionData('grant', [ + PLUGIN_ADDR_1, + pspAddress, + UPGRADE_PLUGIN_PERMISSION_ID, + ]), + }, + { + to: pspAddress, + value: 0, + data: pspInterface.encodeFunctionData('applyUpdate', [ + dao.address, + applyUpdateParams, + ]), + }, + { + to: dao.address, + value: 0, + data: daoInterface.encodeFunctionData('grant', [ + PLUGIN_ADDR_1, + pspAddress, + UPGRADE_PLUGIN_PERMISSION_ID, + ]), + }, + ]; + + expect( + await onlyPluginUpgraderCondition.isGranted( + ADDRESS_ZERO, // where + ADDRESS_ZERO, // who + EXECUTE_PERMISSION_ID, // permission + daoInterface.encodeFunctionData('execute', [ONE_BYTES32, actions, 0]) + ) + ).to.eq(false); + expect( + await onlyPluginUpgraderCondition.isGranted( + ADDRESS_ONE, // where + ADDRESS_TWO, // who + EXECUTE_PERMISSION_ID, // permission + daoInterface.encodeFunctionData('execute', [ONE_BYTES32, actions, 0]) + ) + ).to.eq(false); + }); + + it("Should reject if actions 1/3 > who don't target the PSP", async () => { + let actions: IDAO.ActionStruct[] = [ + { + to: dao.address, + value: 0, + data: daoInterface.encodeFunctionData('grant', [ + PLUGIN_ADDR_1, + carol.address, + UPGRADE_PLUGIN_PERMISSION_ID, + ]), + }, + { + to: pspAddress, + value: 0, + data: pspInterface.encodeFunctionData('applyUpdate', [ + dao.address, + applyUpdateParams, + ]), + }, + { + to: dao.address, + value: 0, + data: daoInterface.encodeFunctionData('revoke', [ + PLUGIN_ADDR_1, + pspAddress, + UPGRADE_PLUGIN_PERMISSION_ID, + ]), + }, + ]; + + expect( + await onlyPluginUpgraderCondition.isGranted( + ADDRESS_ZERO, // where + ADDRESS_ZERO, // who + EXECUTE_PERMISSION_ID, // permission + daoInterface.encodeFunctionData('execute', [ONE_BYTES32, actions, 0]) + ) + ).to.eq(false); + expect( + await onlyPluginUpgraderCondition.isGranted( + ADDRESS_ONE, // where + ADDRESS_TWO, // who + EXECUTE_PERMISSION_ID, // permission + daoInterface.encodeFunctionData('execute', [ONE_BYTES32, actions, 0]) + ) + ).to.eq(false); + + // 2 + actions = [ + { + to: dao.address, + value: 0, + data: daoInterface.encodeFunctionData('grant', [ + PLUGIN_ADDR_1, + pspAddress, + UPGRADE_PLUGIN_PERMISSION_ID, + ]), + }, + { + to: pspAddress, + value: 0, + data: pspInterface.encodeFunctionData('applyUpdate', [ + dao.address, + applyUpdateParams, + ]), + }, + { + to: dao.address, + value: 0, + data: daoInterface.encodeFunctionData('revoke', [ + PLUGIN_ADDR_1, + carol.address, + UPGRADE_PLUGIN_PERMISSION_ID, + ]), + }, + ]; + + expect( + await onlyPluginUpgraderCondition.isGranted( + ADDRESS_ZERO, // where + ADDRESS_ZERO, // who + EXECUTE_PERMISSION_ID, // permission + daoInterface.encodeFunctionData('execute', [ONE_BYTES32, actions, 0]) + ) + ).to.eq(false); + expect( + await onlyPluginUpgraderCondition.isGranted( + ADDRESS_ONE, // where + ADDRESS_TWO, // who + EXECUTE_PERMISSION_ID, // permission + daoInterface.encodeFunctionData('execute', [ONE_BYTES32, actions, 0]) + ) + ).to.eq(false); + }); + + it('Should reject if actions 1/3 > permission is not UPGRADE_PLUGIN_PERMISSION_ID', async () => { + let actions: IDAO.ActionStruct[] = [ + { + to: dao.address, + value: 0, + data: daoInterface.encodeFunctionData('grant', [ + PLUGIN_ADDR_1, + pspAddress, + EXECUTE_PERMISSION_ID, + ]), + }, + { + to: pspAddress, + value: 0, + data: pspInterface.encodeFunctionData('applyUpdate', [ + dao.address, + applyUpdateParams, + ]), + }, + { + to: dao.address, + value: 0, + data: daoInterface.encodeFunctionData('revoke', [ + PLUGIN_ADDR_1, + pspAddress, + UPGRADE_PLUGIN_PERMISSION_ID, + ]), + }, + ]; + + expect( + await onlyPluginUpgraderCondition.isGranted( + ADDRESS_ZERO, // where + ADDRESS_ZERO, // who + EXECUTE_PERMISSION_ID, // permission + daoInterface.encodeFunctionData('execute', [ONE_BYTES32, actions, 0]) + ) + ).to.eq(false); + expect( + await onlyPluginUpgraderCondition.isGranted( + ADDRESS_ONE, // where + ADDRESS_TWO, // who + EXECUTE_PERMISSION_ID, // permission + daoInterface.encodeFunctionData('execute', [ONE_BYTES32, actions, 0]) + ) + ).to.eq(false); + + // 2 + actions = [ + { + to: dao.address, + value: 0, + data: daoInterface.encodeFunctionData('grant', [ + PLUGIN_ADDR_1, + pspAddress, + UPGRADE_PLUGIN_PERMISSION_ID, + ]), + }, + { + to: pspAddress, + value: 0, + data: pspInterface.encodeFunctionData('applyUpdate', [ + dao.address, + applyUpdateParams, + ]), + }, + { + to: dao.address, + value: 0, + data: daoInterface.encodeFunctionData('revoke', [ + PLUGIN_ADDR_1, + pspAddress, + EDITOR_PERMISSION_ID, + ]), + }, + ]; + + expect( + await onlyPluginUpgraderCondition.isGranted( + ADDRESS_ZERO, // where + ADDRESS_ZERO, // who + EXECUTE_PERMISSION_ID, // permission + daoInterface.encodeFunctionData('execute', [ONE_BYTES32, actions, 0]) + ) + ).to.eq(false); + expect( + await onlyPluginUpgraderCondition.isGranted( + ADDRESS_ONE, // where + ADDRESS_TWO, // who + EXECUTE_PERMISSION_ID, // permission + daoInterface.encodeFunctionData('execute', [ONE_BYTES32, actions, 0]) + ) + ).to.eq(false); + }); + + it('Should reject if actions 1/3 > where is not a listed plugin', async () => { + let actions: IDAO.ActionStruct[] = [ + { + to: dao.address, + value: 0, + data: daoInterface.encodeFunctionData('grant', [ + carol.address, + pspAddress, + UPGRADE_PLUGIN_PERMISSION_ID, + ]), + }, + { + to: pspAddress, + value: 0, + data: pspInterface.encodeFunctionData('applyUpdate', [ + dao.address, + applyUpdateParams, + ]), + }, + { + to: dao.address, + value: 0, + data: daoInterface.encodeFunctionData('revoke', [ + PLUGIN_ADDR_1, + pspAddress, + UPGRADE_PLUGIN_PERMISSION_ID, + ]), + }, + ]; + + expect( + await onlyPluginUpgraderCondition.isGranted( + ADDRESS_ZERO, // where + ADDRESS_ZERO, // who + EXECUTE_PERMISSION_ID, // permission + daoInterface.encodeFunctionData('execute', [ONE_BYTES32, actions, 0]) + ) + ).to.eq(false); + expect( + await onlyPluginUpgraderCondition.isGranted( + ADDRESS_ONE, // where + ADDRESS_TWO, // who + EXECUTE_PERMISSION_ID, // permission + daoInterface.encodeFunctionData('execute', [ONE_BYTES32, actions, 0]) + ) + ).to.eq(false); + + // 2 + actions = [ + { + to: dao.address, + value: 0, + data: daoInterface.encodeFunctionData('grant', [ + PLUGIN_ADDR_1, + pspAddress, + UPGRADE_PLUGIN_PERMISSION_ID, + ]), + }, + { + to: pspAddress, + value: 0, + data: pspInterface.encodeFunctionData('applyUpdate', [ + dao.address, + applyUpdateParams, + ]), + }, + { + to: dao.address, + value: 0, + data: daoInterface.encodeFunctionData('revoke', [ + bob.address, + pspAddress, + UPGRADE_PLUGIN_PERMISSION_ID, + ]), + }, + ]; + + expect( + await onlyPluginUpgraderCondition.isGranted( + ADDRESS_ZERO, // where + ADDRESS_ZERO, // who + EXECUTE_PERMISSION_ID, // permission + daoInterface.encodeFunctionData('execute', [ONE_BYTES32, actions, 0]) + ) + ).to.eq(false); + expect( + await onlyPluginUpgraderCondition.isGranted( + ADDRESS_ONE, // where + ADDRESS_TWO, // who + EXECUTE_PERMISSION_ID, // permission + daoInterface.encodeFunctionData('execute', [ONE_BYTES32, actions, 0]) + ) + ).to.eq(false); + + // 3 + actions = [ + { + to: dao.address, + value: 0, + data: daoInterface.encodeFunctionData('grant', [ + alice.address, + pspAddress, + UPGRADE_PLUGIN_PERMISSION_ID, + ]), + }, + { + to: pspAddress, + value: 0, + data: pspInterface.encodeFunctionData('applyUpdate', [ + dao.address, + applyUpdateParams, + ]), + }, + { + to: dao.address, + value: 0, + data: daoInterface.encodeFunctionData('revoke', [ + carol.address, + pspAddress, + UPGRADE_PLUGIN_PERMISSION_ID, + ]), + }, + ]; + + expect( + await onlyPluginUpgraderCondition.isGranted( + ADDRESS_ZERO, // where + ADDRESS_ZERO, // who + EXECUTE_PERMISSION_ID, // permission + daoInterface.encodeFunctionData('execute', [ONE_BYTES32, actions, 0]) + ) + ).to.eq(false); + expect( + await onlyPluginUpgraderCondition.isGranted( + ADDRESS_ONE, // where + ADDRESS_TWO, // who + EXECUTE_PERMISSION_ID, // permission + daoInterface.encodeFunctionData('execute', [ONE_BYTES32, actions, 0]) + ) + ).to.eq(false); + }); + + // applyUpdate calldata + + it('Should reject if action 2 is not applyUpdate', async () => { + let actions: IDAO.ActionStruct[] = [ + { + to: dao.address, + value: 0, + data: daoInterface.encodeFunctionData('grant', [ + PLUGIN_ADDR_1, + pspAddress, + UPGRADE_PLUGIN_PERMISSION_ID, + ]), + }, + { + to: pspAddress, + value: 0, + data: pspInterface.encodeFunctionData('applyInstallation', [ + dao.address, + applyUpdateParams, + ]), + }, + { + to: dao.address, + value: 0, + data: daoInterface.encodeFunctionData('revoke', [ + PLUGIN_ADDR_1, + pspAddress, + UPGRADE_PLUGIN_PERMISSION_ID, + ]), + }, + ]; + + expect( + await onlyPluginUpgraderCondition.isGranted( + ADDRESS_ZERO, // where + ADDRESS_ZERO, // who + EXECUTE_PERMISSION_ID, // permission + daoInterface.encodeFunctionData('execute', [ONE_BYTES32, actions, 0]) + ) + ).to.eq(false); + expect( + await onlyPluginUpgraderCondition.isGranted( + ADDRESS_ONE, // where + ADDRESS_TWO, // who + EXECUTE_PERMISSION_ID, // permission + daoInterface.encodeFunctionData('execute', [ONE_BYTES32, actions, 0]) + ) + ).to.eq(false); + + // 2 + actions = [ + { + to: dao.address, + value: 0, + data: daoInterface.encodeFunctionData('grant', [ + PLUGIN_ADDR_1, + pspAddress, + UPGRADE_PLUGIN_PERMISSION_ID, + ]), + }, + { + to: pspAddress, + value: 0, + data: pspInterface.encodeFunctionData('applyUninstallation', [ + dao.address, + applyUpdateParams, + ]), + }, + { + to: dao.address, + value: 0, + data: daoInterface.encodeFunctionData('revoke', [ + PLUGIN_ADDR_1, + pspAddress, + UPGRADE_PLUGIN_PERMISSION_ID, + ]), + }, + ]; + + expect( + await onlyPluginUpgraderCondition.isGranted( + ADDRESS_ZERO, // where + ADDRESS_ZERO, // who + EXECUTE_PERMISSION_ID, // permission + daoInterface.encodeFunctionData('execute', [ONE_BYTES32, actions, 0]) + ) + ).to.eq(false); + expect( + await onlyPluginUpgraderCondition.isGranted( + ADDRESS_ONE, // where + ADDRESS_TWO, // who + EXECUTE_PERMISSION_ID, // permission + daoInterface.encodeFunctionData('execute', [ONE_BYTES32, actions, 0]) + ) + ).to.eq(false); + }); + + it("Should reject if action 2 > dao doesn't match", async () => { + let actions: IDAO.ActionStruct[] = [ + { + to: dao.address, + value: 0, + data: daoInterface.encodeFunctionData('grant', [ + PLUGIN_ADDR_1, + pspAddress, + UPGRADE_PLUGIN_PERMISSION_ID, + ]), + }, + { + to: pspAddress, + value: 0, + data: pspInterface.encodeFunctionData('applyUpdate', [ + alice.address, // bad + applyUpdateParams, + ]), + }, + { + to: dao.address, + value: 0, + data: daoInterface.encodeFunctionData('revoke', [ + PLUGIN_ADDR_1, + pspAddress, + UPGRADE_PLUGIN_PERMISSION_ID, + ]), + }, + ]; + + expect( + await onlyPluginUpgraderCondition.isGranted( + ADDRESS_ZERO, // where + ADDRESS_ZERO, // who + EXECUTE_PERMISSION_ID, // permission + daoInterface.encodeFunctionData('execute', [ONE_BYTES32, actions, 0]) + ) + ).to.eq(false); + expect( + await onlyPluginUpgraderCondition.isGranted( + ADDRESS_ONE, // where + ADDRESS_TWO, // who + EXECUTE_PERMISSION_ID, // permission + daoInterface.encodeFunctionData('execute', [ONE_BYTES32, actions, 0]) + ) + ).to.eq(false); + + // 2 + actions = [ + { + to: dao.address, + value: 0, + data: daoInterface.encodeFunctionData('grant', [ + PLUGIN_ADDR_1, + pspAddress, + UPGRADE_PLUGIN_PERMISSION_ID, + ]), + }, + { + to: pspAddress, + value: 0, + data: pspInterface.encodeFunctionData('applyUpdate', [ + bob.address, // bad + applyUpdateParams, + ]), + }, + { + to: dao.address, + value: 0, + data: daoInterface.encodeFunctionData('revoke', [ + PLUGIN_ADDR_1, + pspAddress, + UPGRADE_PLUGIN_PERMISSION_ID, + ]), + }, + ]; + + expect( + await onlyPluginUpgraderCondition.isGranted( + ADDRESS_ZERO, // where + ADDRESS_ZERO, // who + EXECUTE_PERMISSION_ID, // permission + daoInterface.encodeFunctionData('execute', [ONE_BYTES32, actions, 0]) + ) + ).to.eq(false); + expect( + await onlyPluginUpgraderCondition.isGranted( + ADDRESS_ONE, // where + ADDRESS_TWO, // who + EXECUTE_PERMISSION_ID, // permission + daoInterface.encodeFunctionData('execute', [ONE_BYTES32, actions, 0]) + ) + ).to.eq(false); + }); + + it('Should reject if action 2 targets a non allowed plugin', async () => { + applyUpdateParams.plugin = alice.address; + const actions: IDAO.ActionStruct[] = [ + { + to: dao.address, + value: 0, + data: daoInterface.encodeFunctionData('grant', [ + PLUGIN_ADDR_1, + pspAddress, + UPGRADE_PLUGIN_PERMISSION_ID, + ]), + }, + { + to: pspAddress, + value: 0, + data: pspInterface.encodeFunctionData('applyUpdate', [ + dao.address, + applyUpdateParams, + ]), + }, + { + to: dao.address, + value: 0, + data: daoInterface.encodeFunctionData('revoke', [ + PLUGIN_ADDR_1, + pspAddress, + UPGRADE_PLUGIN_PERMISSION_ID, + ]), + }, + ]; + + expect( + await onlyPluginUpgraderCondition.isGranted( + ADDRESS_ZERO, // where + ADDRESS_ZERO, // who + EXECUTE_PERMISSION_ID, // permission + daoInterface.encodeFunctionData('execute', [ONE_BYTES32, actions, 0]) + ) + ).to.eq(false); + expect( + await onlyPluginUpgraderCondition.isGranted( + ADDRESS_ONE, // where + ADDRESS_TWO, // who + EXECUTE_PERMISSION_ID, // permission + daoInterface.encodeFunctionData('execute', [ONE_BYTES32, actions, 0]) + ) + ).to.eq(false); + + // 2 + applyUpdateParams.plugin = bob.address; + actions[1] = { + to: pspAddress, + value: 0, + data: pspInterface.encodeFunctionData('applyUpdate', [ dao.address, - carol.address, - MEMBER_PERMISSION_ID, - ]) - ) - ).to.eq(false); - expect( - await memberAccessExecuteCondition.isGranted( - ADDRESS_ONE, // where (used) - ADDRESS_TWO, // who (used) - EXECUTE_PERMISSION_ID, // permission (used) - DAO__factory.createInterface().encodeFunctionData('revoke', [ - // call + applyUpdateParams, + ]), + }; + + expect( + await onlyPluginUpgraderCondition.isGranted( + ADDRESS_ZERO, // where + ADDRESS_ZERO, // who + EXECUTE_PERMISSION_ID, // permission + daoInterface.encodeFunctionData('execute', [ONE_BYTES32, actions, 0]) + ) + ).to.eq(false); + expect( + await onlyPluginUpgraderCondition.isGranted( + ADDRESS_ONE, // where + ADDRESS_TWO, // who + EXECUTE_PERMISSION_ID, // permission + daoInterface.encodeFunctionData('execute', [ONE_BYTES32, actions, 0]) + ) + ).to.eq(false); + + // 3 + applyUpdateParams.plugin = ADDRESS_THREE; + actions[1] = { + to: pspAddress, + value: 0, + data: pspInterface.encodeFunctionData('applyUpdate', [ dao.address, - carol.address, - MEMBER_PERMISSION_ID, - ]) - ) - ).to.eq(false); + applyUpdateParams, + ]), + }; + + expect( + await onlyPluginUpgraderCondition.isGranted( + ADDRESS_ZERO, // where + ADDRESS_ZERO, // who + EXECUTE_PERMISSION_ID, // permission + daoInterface.encodeFunctionData('execute', [ONE_BYTES32, actions, 0]) + ) + ).to.eq(false); + expect( + await onlyPluginUpgraderCondition.isGranted( + ADDRESS_ONE, // where + ADDRESS_TWO, // who + EXECUTE_PERMISSION_ID, // permission + daoInterface.encodeFunctionData('execute', [ONE_BYTES32, actions, 0]) + ) + ).to.eq(false); + }); }); - it("Should allow granting to whatever 'who' address", async () => { - expect( - await memberAccessExecuteCondition.isGranted( - ADDRESS_ONE, // where (used) - ADDRESS_TWO, // who (used) - EXECUTE_PERMISSION_ID, // permission (used) - DAO__factory.createInterface().encodeFunctionData('grant', [ - // call - SOME_CONTRACT_ADDRESS, - alice.address, - MEMBER_PERMISSION_ID, - ]) - ) - ).to.eq(true); - expect( - await memberAccessExecuteCondition.isGranted( - ADDRESS_ONE, // where (used) - ADDRESS_TWO, // who (used) - EXECUTE_PERMISSION_ID, // permission (used) - DAO__factory.createInterface().encodeFunctionData('revoke', [ - // call - SOME_CONTRACT_ADDRESS, - alice.address, - MEMBER_PERMISSION_ID, - ]) - ) - ).to.eq(true); - - // Bob - expect( - await memberAccessExecuteCondition.isGranted( - ADDRESS_ONE, // where (used) - ADDRESS_TWO, // who (used) - EXECUTE_PERMISSION_ID, // permission (used) - DAO__factory.createInterface().encodeFunctionData('grant', [ - // call - SOME_CONTRACT_ADDRESS, - bob.address, - MEMBER_PERMISSION_ID, - ]) - ) - ).to.eq(true); - expect( - await memberAccessExecuteCondition.isGranted( - ADDRESS_ONE, // where (used) - ADDRESS_TWO, // who (used) - EXECUTE_PERMISSION_ID, // permission (used) - DAO__factory.createInterface().encodeFunctionData('revoke', [ - // call - SOME_CONTRACT_ADDRESS, - bob.address, - MEMBER_PERMISSION_ID, - ]) - ) - ).to.eq(true); - - // Carol - expect( - await memberAccessExecuteCondition.isGranted( - ADDRESS_ONE, // where (used) - ADDRESS_TWO, // who (used) - EXECUTE_PERMISSION_ID, // permission (used) - DAO__factory.createInterface().encodeFunctionData('grant', [ - // call - SOME_CONTRACT_ADDRESS, - carol.address, - MEMBER_PERMISSION_ID, - ]) - ) - ).to.eq(true); - expect( - await memberAccessExecuteCondition.isGranted( - ADDRESS_ONE, // where (used) - ADDRESS_TWO, // who (used) - EXECUTE_PERMISSION_ID, // permission (used) - DAO__factory.createInterface().encodeFunctionData('revoke', [ - // call - SOME_CONTRACT_ADDRESS, - carol.address, - MEMBER_PERMISSION_ID, - ]) - ) - ).to.eq(true); - - // Any - expect( - await memberAccessExecuteCondition.isGranted( - ADDRESS_ONE, // where (used) - ADDRESS_TWO, // who (used) - EXECUTE_PERMISSION_ID, // permission (used) - DAO__factory.createInterface().encodeFunctionData('grant', [ - // call - SOME_CONTRACT_ADDRESS, - ADDRESS_ZERO, - MEMBER_PERMISSION_ID, - ]) - ) - ).to.eq(true); - expect( - await memberAccessExecuteCondition.isGranted( - ADDRESS_ONE, // where (used) - ADDRESS_TWO, // who (used) - EXECUTE_PERMISSION_ID, // permission (used) - DAO__factory.createInterface().encodeFunctionData('revoke', [ - // call - SOME_CONTRACT_ADDRESS, - ADDRESS_ZERO, - MEMBER_PERMISSION_ID, - ]) - ) - ).to.eq(true); + describe('Decoders', () => { + it('Should decode getSelector properly', async () => { + const actions: IDAO.ActionStruct[] = [ + { + to: dao.address, + value: 0, + data: daoInterface.encodeFunctionData('grant', [ + PLUGIN_ADDR_1, + pspAddress, + UPGRADE_PLUGIN_PERMISSION_ID, + ]), + }, + { + to: pspAddress, + value: 0, + data: pspInterface.encodeFunctionData('applyUpdate', [ + dao.address, + applyUpdateParams, + ]), + }, + { + to: dao.address, + value: 0, + data: daoInterface.encodeFunctionData('revoke', [ + PLUGIN_ADDR_1, + pspAddress, + UPGRADE_PLUGIN_PERMISSION_ID, + ]), + }, + ]; + + expect( + await onlyPluginUpgraderCondition.getSelector(actions[0].data) + ).to.eq((actions[0].data as string).slice(0, 10)); + + expect( + await onlyPluginUpgraderCondition.getSelector(actions[1].data) + ).to.eq((actions[1].data as string).slice(0, 10)); + + expect( + await onlyPluginUpgraderCondition.getSelector(actions[2].data) + ).to.eq((actions[2].data as string).slice(0, 10)); + }); + + it('Should decode decodeGrantRevokeCalldata properly', async () => { + const calldataList = [ + daoInterface.encodeFunctionData('grant', [ + PLUGIN_ADDR_1, + pspAddress, + UPGRADE_PLUGIN_PERMISSION_ID, + ]), + daoInterface.encodeFunctionData('revoke', [ + PLUGIN_ADDR_2, + ADDRESS_THREE, + ROOT_PERMISSION_ID, + ]), + ]; + + // 1 + let [selector, where, who, permissionId] = + await onlyPluginUpgraderCondition.decodeGrantRevokeCalldata( + calldataList[0] + ); + expect(selector).to.eq(calldataList[0].slice(0, 10)); + expect(where).to.eq(PLUGIN_ADDR_1); + expect(who).to.eq(pspAddress); + expect(permissionId).to.eq(UPGRADE_PLUGIN_PERMISSION_ID); + + // 2 + [selector, where, who, permissionId] = + await onlyPluginUpgraderCondition.decodeGrantRevokeCalldata( + calldataList[2] + ); + expect(selector).to.eq(calldataList[2].slice(0, 10)); + expect(where).to.eq(PLUGIN_ADDR_2); + expect(who).to.eq(ADDRESS_THREE); + expect(permissionId).to.eq(ROOT_PERMISSION_ID); + }); + + it('Should decode decodeApplyUpdateCalldata properly', async () => { + applyUpdateParams.plugin = bob.address; + const calldataList = [ + pspInterface.encodeFunctionData('applyUpdate', [ + dao.address, + applyUpdateParams, + ]), + pspInterface.encodeFunctionData('applyUpdate', [ + ADDRESS_THREE, + applyUpdateParams, + ]), + ]; + + // 1 + let [selector, decodedDaoAddress, decodedParams] = + await onlyPluginUpgraderCondition.decodeApplyUpdateCalldata( + calldataList[0] + ); + expect(selector).to.eq(calldataList[0].slice(0, 10)); + expect(decodedDaoAddress).to.eq(dao.address); + expect(decodedParams.plugin).to.eq(bob.address); + + // 2 + [selector, decodedDaoAddress, decodedParams] = + await onlyPluginUpgraderCondition.decodeApplyUpdateCalldata( + calldataList[2] + ); + expect(selector).to.eq(calldataList[2].slice(0, 10)); + expect(decodedDaoAddress).to.eq(ADDRESS_THREE); + expect(decodedParams.plugin).to.eq(bob.address); + }); }); }); diff --git a/packages/contracts/utils/helpers.ts b/packages/contracts/utils/helpers.ts index dd05bf1..1f0a9cd 100644 --- a/packages/contracts/utils/helpers.ts +++ b/packages/contracts/utils/helpers.ts @@ -59,7 +59,10 @@ export function getPluginRepoFactoryAddress(networkName: string): string { return pluginRepoFactoryAddr; } -export function getPluginSetupProcessorAddress(networkName: string): string { +export function getPluginSetupProcessorAddress( + networkName: string, + silent = false +): string { let pluginSetupProcessorAddr: string; if ( @@ -71,16 +74,20 @@ export function getPluginSetupProcessorAddress(networkName: string): string { pluginSetupProcessorAddr = osxContracts[hardhatForkNetwork].PluginSetupProcessor; - console.log( - `Using the "${hardhatForkNetwork}" PluginSetupProcessor address (${pluginSetupProcessorAddr}) for deployment testing on network "${networkName}"` - ); + if (!silent) { + console.log( + `Using the "${hardhatForkNetwork}" PluginSetupProcessor address (${pluginSetupProcessorAddr}) for deployment testing on network "${networkName}"` + ); + } } else { pluginSetupProcessorAddr = osxContracts[networkNameMapping[networkName]].PluginSetupProcessor; - console.log( - `Using the ${networkNameMapping[networkName]} PluginSetupProcessor address (${pluginSetupProcessorAddr}) for deployment...` - ); + if (!silent) { + console.log( + `Using the ${networkNameMapping[networkName]} PluginSetupProcessor address (${pluginSetupProcessorAddr}) for deployment...` + ); + } } return pluginSetupProcessorAddr; }