Merge pull request #115 from aave/feat/limit-emergency-admin-unpause

feat: Prevent Emergency Admin from Unpausing
This commit is contained in:
Alan
2022-04-26 12:11:37 +01:00
committed by GitHub
7 changed files with 31 additions and 19 deletions

View File

@@ -90,11 +90,13 @@ contract LensHub is LensNFTBase, VersionedInitializable, LensMultiState, LensHub
/// @inheritdoc ILensHub
function setState(DataTypes.ProtocolState newState) external override {
if (msg.sender == _governance || msg.sender == _emergencyAdmin) {
_setState(newState);
} else {
if (msg.sender == _emergencyAdmin) {
if (newState == DataTypes.ProtocolState.Unpaused)
revert Errors.EmergencyAdminCannotUnpause();
} else if (msg.sender != _governance) {
revert Errors.NotGovernanceOrEmergencyAdmin();
}
_setState(newState);
}
///@inheritdoc ILensHub

View File

@@ -13,6 +13,7 @@ library Errors {
error TokenDoesNotExist();
error NotGovernance();
error NotGovernanceOrEmergencyAdmin();
error EmergencyAdminCannotUnpause();
error CallerNotWhitelistedModule();
error CollectModuleNotWhitelisted();
error FollowModuleNotWhitelisted();

View File

@@ -48,6 +48,8 @@ import {
LensPeriphery__factory,
ProfileFollowModule,
ProfileFollowModule__factory,
FollowNFT,
CollectNFT,
} from '../typechain-types';
import { LensHubLibraryAddresses } from '../typechain-types/factories/LensHub__factory';
import { FAKE_PRIVATEKEY, ZERO_ADDRESS } from './helpers/constants';
@@ -88,8 +90,6 @@ export let userAddress: string;
export let userTwoAddress: string;
export let userThreeAddress: string;
export let governanceAddress: string;
export let followNFTImplAddress: string;
export let collectNFTImplAddress: string;
export let treasuryAddress: string;
export let testWallet: Wallet;
export let lensHubImpl: LensHub;
@@ -102,6 +102,8 @@ export let eventsLib: Events;
export let moduleGlobals: ModuleGlobals;
export let helper: Helper;
export let lensPeriphery: LensPeriphery;
export let followNFTImpl: FollowNFT;
export let collectNFTImpl: CollectNFT;
/* Modules */
@@ -178,8 +180,8 @@ before(async function () {
const hubProxyAddress = computeContractAddress(deployerAddress, nonce + 3); //'0x' + keccak256(RLP.encode([deployerAddress, hubProxyNonce])).substr(26);
const followNFTImpl = await new FollowNFT__factory(deployer).deploy(hubProxyAddress);
const collectNFTImpl = await new CollectNFT__factory(deployer).deploy(hubProxyAddress);
followNFTImpl = await new FollowNFT__factory(deployer).deploy(hubProxyAddress);
collectNFTImpl = await new CollectNFT__factory(deployer).deploy(hubProxyAddress);
lensHubImpl = await new LensHub__factory(hubLibs, deployer).deploy(
followNFTImpl.address,

View File

@@ -9,6 +9,8 @@ export const ERRORS = {
TOKEN_DOES_NOT_EXIST: 'TokenDoesNotExist()',
CALLER_NOT_WHITELSITED_MODULE: 'CallerNotWhitelistedModule()',
NOT_GOVERNANCE: 'NotGovernance()',
NOT_GOVERNANCE_OR_EMERGENCY_ADMIN: 'NotGovernanceOrEmergencyAdmin()',
EMERGENCY_ADMIN_CANNOT_UNPAUSE: 'EmergencyAdminCannotUnpause()',
COLLECT_MODULE_NOT_WHITELISTED: 'CollectModuleNotWhitelisted()',
FOLLOW_MODULE_NOT_WHITELISTED: 'FollowModuleNotWhitelisted()',
REFERENCE_MODULE_NOT_WHITELISTED: 'ReferenceModuleNotWhitelisted()',
@@ -43,7 +45,6 @@ export const ERRORS = {
"Transaction reverted: function selector was not recognized and there's no fallback function",
PAUSED: 'Paused()',
PUBLISHING_PAUSED: 'PublishingPaused()',
NOT_GOVERNANCE_OR_EMERGENCY_ADMIN: 'NotGovernanceOrEmergencyAdmin()',
NO_REASON_ABI_DECODE:
"Transaction reverted and Hardhat couldn't infer the reason. Please report this to help us improve Hardhat.",
};

View File

@@ -50,6 +50,13 @@ makeSuiteCleanRoom('Multi-State Hub', function () {
ERRORS.NOT_GOVERNANCE
);
});
it('Governance should set user as emergency admin, user should fail to set protocol state to unpaused', async function () {
await expect(lensHub.connect(governance).setEmergencyAdmin(userAddress)).to.not.be.reverted;
await expect(lensHub.setState(ProtocolState.Unpaused)).to.be.revertedWith(
ERRORS.EMERGENCY_ADMIN_CANNOT_UNPAUSE
);
});
});
context('Scenarios', function () {
@@ -58,7 +65,6 @@ makeSuiteCleanRoom('Multi-State Hub', function () {
await expect(lensHub.setState(ProtocolState.Paused)).to.not.be.reverted;
await expect(lensHub.setState(ProtocolState.PublishingPaused)).to.not.be.reverted;
await expect(lensHub.setState(ProtocolState.Unpaused)).to.not.be.reverted;
await expect(lensHub.setEmergencyAdmin(ZERO_ADDRESS)).to.be.revertedWith(
ERRORS.NOT_GOVERNANCE
);

View File

@@ -167,16 +167,6 @@ makeSuiteCleanRoom('Events', function () {
ProtocolState.PublishingPaused,
await getTimestamp(),
]);
receipt = await waitForTx(lensHub.connect(user).setState(ProtocolState.Unpaused));
expect(receipt.logs.length).to.eq(1);
matchEvent(receipt, 'StateSet', [
userAddress,
ProtocolState.PublishingPaused,
ProtocolState.Unpaused,
await getTimestamp(),
]);
});
it('Follow module whitelisting functions should emit expected event', async function () {

View File

@@ -43,6 +43,8 @@ import {
userThree,
testWallet,
lensPeriphery,
followNFTImpl,
collectNFTImpl,
} from '../__setup.spec';
/**
@@ -167,6 +169,14 @@ makeSuiteCleanRoom('Misc', function () {
expect(await lensHub.getPubCount(FIRST_PROFILE_ID)).to.eq(expectedCount);
});
it('Follow NFT impl getter should return the correct address', async function () {
expect(await lensHub.getFollowNFTImpl()).to.eq(followNFTImpl.address);
});
it('Collect NFT impl getter should return the correct address', async function () {
expect(await lensHub.getCollectNFTImpl()).to.eq(collectNFTImpl.address);
});
it('Profile tokenURI should return the accurate URI', async function () {
const tokenUri = await lensHub.tokenURI(FIRST_PROFILE_ID);
const metadata = await getMetadataFromBase64TokenUri(tokenUri);