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

Module Management #15

Merged
merged 35 commits into from
Jan 8, 2024
Merged

Module Management #15

merged 35 commits into from
Jan 8, 2024

Conversation

0xJem
Copy link
Contributor

@0xJem 0xJem commented Jan 3, 2024

Completes #9

Implements:

  • Module keycodes (Keycode) and versioned keycodes (Veecode)
  • Install modules and subsequent versions
  • Sunset modules
  • execOnModule and prohibiting certain functions
  • Continuous integration

@0xJem 0xJem self-assigned this Jan 3, 2024
@0xJem 0xJem linked an issue Jan 3, 2024 that may be closed by this pull request
@0xJem 0xJem requested a review from Oighty January 4, 2024 11:45
Copy link
Contributor

@Oighty Oighty left a comment

Choose a reason for hiding this comment

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

Overall, this looks good. I have a few smallish changes.

@@ -0,0 +1,37 @@
{
Copy link
Contributor

Choose a reason for hiding this comment

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

I was actually hoping to avoid having JS packages in this repo, but it may be unavoidable.

I was planning to use forge fmt instead of prettier for formatting, but there isn't a linter equivalent to replace solhint.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I can shift it over to forge fmt, at least

address module = _getModuleIfInstalled(veecode_);

// Check that the function is not prohibited
bytes4 functionSelector = bytes4(callData_[:4]);
Copy link
Contributor

Choose a reason for hiding this comment

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

I generally like the idea of having the Parent be able to call functions in the course of operations, but restrict them from being called out of scope. I don't know if this is the right pattern though.

There are a few different options.

  1. We could have a function on the Module that returns a list of functions that are callable externally, similar to requestPermissions on Default modules. We could call it governanceFunctions or something. You could then check your calldata against that prior to executing in execOnModule. These could be stored on install or fetched at the beginning of this function.
  2. Having a variable on the Parent contract that is set when the execOnModule function is entered. Modules could have a modifier that checks whether this variable is set on the parent contract. This could be used to separate onlyParent and onlyGovernance functionality. Requires a re-entrant call back to Parent, but probably not an issue.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

#2 seems more simple, as it would just be a modifier attached to the protected functions, e.g.

modifier noGovernance() {
    if (Module(owner).isExecOnModule()) revert NoGovernance();

    _;
}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I've added this - please take a look

Copy link
Contributor Author

Choose a reason for hiding this comment

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

onlyInternal modifier added, along with the infra to support it

Copy link
Contributor

Choose a reason for hiding this comment

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

I think the implementation is close, but not quite there.

I think we only need one execOnModule function, but with the format of execOnModuleInternal. To be more explicit on this:

The idea is that there are standard functions on the Auction, Derivative, etc. modules that are called in the general user flows, such as purchase. We don't want those to be able to be called by governance via execOnModule. They could be if the only access control is onlyParent. However, some functions like setMinDuration should be callable by governance.

Therefore, there are two groups:

  1. Restricted functions only callable by AuctionHouse outside of execOnModule.
  2. Restricted functions that should be accessible by Governance via execOnModule.

I would then propose the following refactor:

  • change isExecOnModuleInternal to isExecOnModule
  • delete execOnModule as currently written and replace with the execOnModuleInternal, renamed to just execOnModule
  • onlyInternal modifier should check if isExecOnModule and fail if it is true.

We would then use onlyInternal for case 1 above and onlyParent for case 2 (Governance type functions).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ok that makes sense! I've pushed the changes.

src/modules/Modules.sol Outdated Show resolved Hide resolved
src/modules/Modules.sol Outdated Show resolved Hide resolved
address module = _getModuleIfInstalled(veecode_);

// Check that the function is not prohibited
bytes4 functionSelector = bytes4(callData_[:4]);
Copy link
Contributor

Choose a reason for hiding this comment

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

I think the implementation is close, but not quite there.

I think we only need one execOnModule function, but with the format of execOnModuleInternal. To be more explicit on this:

The idea is that there are standard functions on the Auction, Derivative, etc. modules that are called in the general user flows, such as purchase. We don't want those to be able to be called by governance via execOnModule. They could be if the only access control is onlyParent. However, some functions like setMinDuration should be callable by governance.

Therefore, there are two groups:

  1. Restricted functions only callable by AuctionHouse outside of execOnModule.
  2. Restricted functions that should be accessible by Governance via execOnModule.

I would then propose the following refactor:

  • change isExecOnModuleInternal to isExecOnModule
  • delete execOnModule as currently written and replace with the execOnModuleInternal, renamed to just execOnModule
  • onlyInternal modifier should check if isExecOnModule and fail if it is true.

We would then use onlyInternal for case 1 above and onlyParent for case 2 (Governance type functions).

Copy link
Contributor

@Oighty Oighty left a comment

Choose a reason for hiding this comment

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

Looks good. Going to merge.

@Oighty Oighty merged commit ddbdc63 into master Jan 8, 2024
1 check passed
@0xJem 0xJem deleted the jem/module-management branch January 9, 2024 06:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Auction House: Module Management
2 participants