Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Non-reentrant DAO executor #355

Merged
merged 114 commits into from
May 17, 2023
Merged

Conversation

heueristik
Copy link
Contributor

@heueristik heueristik commented Apr 17, 2023

Description

This PR add a nonReentrant modifier to the DAO.sol execute function.


Task: OS-358

Type of change

  • Bug fix (non-breaking change which fixes an issue)

Checklist:

  • I have selected the correct base branch.
  • I have performed a self-review of my own code.
  • I have commented my code, particularly in hard-to-understand areas.
  • I have made corresponding changes to the documentation.
  • My changes generate no new warnings.
  • Any dependent changes have been merged and published in downstream modules.
  • I ran all tests with success and extended them if necessary.
  • I have updated the CHANGELOG.md file in the root folder.
  • I have tested my code on the test network.

@heueristik heueristik changed the title feat: protect the DAO executor against reentrancy Non-reentrant DAO executor Apr 17, 2023
@heueristik heueristik marked this pull request as ready for review April 17, 2023 11:00
mathewmeconry
mathewmeconry previously approved these changes Apr 17, 2023
@heueristik heueristik marked this pull request as draft April 17, 2023 15:45
@heueristik heueristik marked this pull request as ready for review April 18, 2023 15:02
@heueristik heueristik force-pushed the feature/OS-358-nonreentrant-executor branch 3 times, most recently from 8d856cc to 630a3c9 Compare April 18, 2023 15:37
@heueristik heueristik force-pushed the feature/OS-358-nonreentrant-executor branch from 630a3c9 to 2ac2262 Compare April 18, 2023 15:38
packages/contracts/src/core/dao/DAO.sol Outdated Show resolved Hide resolved
packages/contracts/src/core/dao/DAO.sol Outdated Show resolved Hide resolved
packages/contracts/src/core/dao/DAO.sol Outdated Show resolved Hide resolved
packages/contracts/src/core/dao/IDAO.sol Outdated Show resolved Hide resolved
packages/contracts/test/core/dao/dao.ts Show resolved Hide resolved
packages/contracts/test/upgrade/dao.ts Outdated Show resolved Hide resolved
Copy link
Contributor

@mathewmeconry mathewmeconry left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what are the files packages/contracts/src/core/dao/previous_versions/DAO_v1_0_0.sol and packages/contracts/src/core/dao/previous_versions/IDAO_v1_0_0.sol for?
If somebody wants to have a previous contract version they should use git to traverse to that version and not us copy pasting code

packages/contracts/test/test-utils/oz-constants.ts Outdated Show resolved Hide resolved
packages/contracts/utils/event.ts Outdated Show resolved Hide resolved
@heueristik
Copy link
Contributor Author

heueristik commented Apr 19, 2023

what are the files packages/contracts/src/core/dao/previous_versions/DAO_v1_0_0.sol and packages/contracts/src/core/dao/previous_versions/IDAO_v1_0_0.sol for? If somebody wants to have a previous contract version they should use git to traverse to that version and not us copy pasting code

I needed it to test that the upgrade actually works and doesn't break the storage (see the test in packages/contracts/test/upgrade/dao.ts).
See also the comment I made here: #355 (comment)
Neither the hardhat-upgrades package can nor the shouldUpgradeCorrectly

export function shouldUpgradeCorrectly(
upgradePermissionId: string,
upgradeRevertPermissionMessage: string
) {
let uupsCompatibleBase: string;
function DaoUnauthorizedRevertArgs(
contract: Contract,
user: SignerWithAddress,
dao: Contract
) {
return [dao.address, contract.address, user.address, upgradePermissionId];
}
function UnauthorizedRevertArgs(dao: Contract, user: SignerWithAddress) {
return [dao.address, user.address, upgradePermissionId];
}
describe('UUPS Upgradeability Test', async () => {
before(async () => {
const factory = await ethers.getContractFactory(
'PluginUUPSUpgradeableV1Mock'
);
uupsCompatibleBase = (await factory.deploy()).address;
});
it('reverts if user without permission tries to upgrade', async function () {
const {user, contract, dao} = this.upgrade;
const connect = contract.connect(user);
const tx1 = connect.upgradeTo(ethers.constants.AddressZero);
const tx2 = connect.upgradeToAndCall(ethers.constants.AddressZero, '0x');
if (upgradeRevertPermissionMessage == 'DaoUnauthorized') {
await expect(tx1)
.to.be.revertedWithCustomError(
contract,
upgradeRevertPermissionMessage
)
.withArgs(...DaoUnauthorizedRevertArgs(contract, user, dao));
await expect(tx2)
.to.be.revertedWithCustomError(
contract,
upgradeRevertPermissionMessage
)
.withArgs(...DaoUnauthorizedRevertArgs(contract, user, dao));
} else {
await expect(tx1)
.to.be.revertedWithCustomError(
contract,
upgradeRevertPermissionMessage
)
.withArgs(...UnauthorizedRevertArgs(dao, user));
await expect(tx2)
.to.be.revertedWithCustomError(
contract,
upgradeRevertPermissionMessage
)
.withArgs(...UnauthorizedRevertArgs(dao, user));
}
});
it('updates correctly to new implementation', async function () {
const {user, contract, dao} = this.upgrade;
await dao.grant(contract.address, user.address, upgradePermissionId);
const connect = contract.connect(user);
await expect(connect.upgradeTo(uupsCompatibleBase))
.to.emit(contract, 'Upgraded')
.withArgs(uupsCompatibleBase);
});
});
}

does check that the storage isn't broken.

Any better way to do it? Testing against the network forks (mainnet) lengthens the tests a lot and we don't have a list of previous versions, only the active ones.

@github-actions github-actions bot removed the subgraph label May 16, 2023
packages/contracts/src/core/dao/DAO.sol Outdated Show resolved Hide resolved
packages/contracts/src/core/dao/DAO.sol Outdated Show resolved Hide resolved
packages/contracts/src/core/dao/DAO.sol Outdated Show resolved Hide resolved
packages/contracts/test/upgrade/dao.ts Show resolved Hide resolved
packages/contracts/test/upgrade/dao.ts Outdated Show resolved Hide resolved
packages/contracts/test/upgrade/dao.ts Show resolved Hide resolved
@heueristik heueristik force-pushed the feature/OS-358-nonreentrant-executor branch from df45432 to 649732b Compare May 16, 2023 11:15
Copy link
Contributor

@Rekard0 Rekard0 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@heueristik heueristik merged commit 7b4e183 into develop May 17, 2023
@heueristik heueristik deleted the feature/OS-358-nonreentrant-executor branch May 17, 2023 15:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants