|
@@ -23,6 +23,7 @@ const {
|
|
|
shouldBehaveLikeNotDelayedAdminOperation,
|
|
|
shouldBehaveLikeRoleAdminOperation,
|
|
|
shouldBehaveLikeAManagedRestrictedOperation,
|
|
|
+ shouldBehaveLikeASelfRestrictedOperation,
|
|
|
} = require('./AccessManager.behavior');
|
|
|
|
|
|
const {
|
|
@@ -48,7 +49,7 @@ async function fixture() {
|
|
|
roles.SOME.members = [member];
|
|
|
roles.PUBLIC.members = [admin, roleAdmin, roleGuardian, member, user, other];
|
|
|
|
|
|
- const manager = await ethers.deployContract('$AccessManager', [admin]);
|
|
|
+ const manager = await ethers.deployContract('$AccessManagerMock', [admin]);
|
|
|
const target = await ethers.deployContract('$AccessManagedTarget', [manager]);
|
|
|
|
|
|
for (const { id: roleId, admin, guardian, members } of Object.values(roles)) {
|
|
@@ -1105,10 +1106,18 @@ describe('AccessManager', function () {
|
|
|
expect(await this.manager.isTargetClosed(this.target)).to.be.false;
|
|
|
});
|
|
|
|
|
|
- it('reverts if closing the manager', async function () {
|
|
|
- await expect(this.manager.connect(this.admin).setTargetClosed(this.manager, true))
|
|
|
- .to.be.revertedWithCustomError(this.manager, 'AccessManagerLockedAccount')
|
|
|
- .withArgs(this.manager);
|
|
|
+ describe('when the target is the manager', async function () {
|
|
|
+ it('closes and opens the manager', async function () {
|
|
|
+ await expect(this.manager.connect(this.admin).setTargetClosed(this.manager, true))
|
|
|
+ .to.emit(this.manager, 'TargetClosed')
|
|
|
+ .withArgs(this.manager, true);
|
|
|
+ expect(await this.manager.isTargetClosed(this.manager)).to.be.true;
|
|
|
+
|
|
|
+ await expect(this.manager.connect(this.admin).setTargetClosed(this.manager, false))
|
|
|
+ .to.emit(this.manager, 'TargetClosed')
|
|
|
+ .withArgs(this.manager, false);
|
|
|
+ expect(await this.manager.isTargetClosed(this.manager)).to.be.false;
|
|
|
+ });
|
|
|
});
|
|
|
});
|
|
|
|
|
@@ -1670,18 +1679,74 @@ describe('AccessManager', function () {
|
|
|
});
|
|
|
});
|
|
|
|
|
|
+ describe('access managed self operations', function () {
|
|
|
+ describe('when calling a restricted target function', function () {
|
|
|
+ const method = 'fnRestricted()';
|
|
|
+
|
|
|
+ beforeEach('set required role', async function () {
|
|
|
+ this.role = { id: 785913n };
|
|
|
+ await this.manager.$_setTargetFunctionRole(
|
|
|
+ this.manager,
|
|
|
+ this.manager[method].getFragment().selector,
|
|
|
+ this.role.id,
|
|
|
+ );
|
|
|
+ });
|
|
|
+
|
|
|
+ describe('restrictions', function () {
|
|
|
+ beforeEach('set method and args', function () {
|
|
|
+ this.caller = this.user;
|
|
|
+ this.calldata = this.manager.interface.encodeFunctionData(method, []);
|
|
|
+ });
|
|
|
+
|
|
|
+ shouldBehaveLikeASelfRestrictedOperation();
|
|
|
+ });
|
|
|
+
|
|
|
+ it('succeeds called by a role member', async function () {
|
|
|
+ await this.manager.$_grantRole(this.role.id, this.user, 0, 0);
|
|
|
+
|
|
|
+ await expect(this.manager.connect(this.user)[method]())
|
|
|
+ .to.emit(this.manager, 'CalledRestricted')
|
|
|
+ .withArgs(this.user);
|
|
|
+ });
|
|
|
+ });
|
|
|
+
|
|
|
+ describe('when calling a non-restricted target function', function () {
|
|
|
+ const method = 'fnUnrestricted()';
|
|
|
+
|
|
|
+ beforeEach('set required role', async function () {
|
|
|
+ this.role = { id: 879435n };
|
|
|
+ await this.manager.$_setTargetFunctionRole(
|
|
|
+ this.manager,
|
|
|
+ this.manager[method].getFragment().selector,
|
|
|
+ this.role.id,
|
|
|
+ );
|
|
|
+ });
|
|
|
+
|
|
|
+ it('succeeds called by anyone', async function () {
|
|
|
+ await expect(this.manager.connect(this.user)[method]())
|
|
|
+ .to.emit(this.manager, 'CalledUnrestricted')
|
|
|
+ .withArgs(this.user);
|
|
|
+ });
|
|
|
+ });
|
|
|
+ });
|
|
|
+
|
|
|
describe('access managed target operations', function () {
|
|
|
describe('when calling a restricted target function', function () {
|
|
|
- beforeEach('set required role', function () {
|
|
|
- this.method = this.target.fnRestricted.getFragment();
|
|
|
+ const method = 'fnRestricted()';
|
|
|
+
|
|
|
+ beforeEach('set required role', async function () {
|
|
|
this.role = { id: 3597243n };
|
|
|
- this.manager.$_setTargetFunctionRole(this.target, this.method.selector, this.role.id);
|
|
|
+ await this.manager.$_setTargetFunctionRole(
|
|
|
+ this.target,
|
|
|
+ this.target[method].getFragment().selector,
|
|
|
+ this.role.id,
|
|
|
+ );
|
|
|
});
|
|
|
|
|
|
describe('restrictions', function () {
|
|
|
beforeEach('set method and args', function () {
|
|
|
- this.calldata = this.target.interface.encodeFunctionData(this.method, []);
|
|
|
this.caller = this.user;
|
|
|
+ this.calldata = this.target.interface.encodeFunctionData(method, []);
|
|
|
});
|
|
|
|
|
|
shouldBehaveLikeAManagedRestrictedOperation();
|
|
@@ -1690,11 +1755,7 @@ describe('AccessManager', function () {
|
|
|
it('succeeds called by a role member', async function () {
|
|
|
await this.manager.$_grantRole(this.role.id, this.user, 0, 0);
|
|
|
|
|
|
- await expect(
|
|
|
- this.target.connect(this.user)[this.method.selector]({
|
|
|
- data: this.calldata,
|
|
|
- }),
|
|
|
- )
|
|
|
+ await expect(this.target.connect(this.user)[method]())
|
|
|
.to.emit(this.target, 'CalledRestricted')
|
|
|
.withArgs(this.user);
|
|
|
});
|
|
@@ -1713,11 +1774,7 @@ describe('AccessManager', function () {
|
|
|
});
|
|
|
|
|
|
it('succeeds called by anyone', async function () {
|
|
|
- await expect(
|
|
|
- this.target.connect(this.user)[method]({
|
|
|
- data: this.calldata,
|
|
|
- }),
|
|
|
- )
|
|
|
+ await expect(this.target.connect(this.user)[method]())
|
|
|
.to.emit(this.target, 'CalledUnrestricted')
|
|
|
.withArgs(this.user);
|
|
|
});
|