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

refactor(solecs): use @solidstate Ownable, add OwnableWritable, fix some import formatting #265

Merged
merged 6 commits into from
Jan 10, 2023

Conversation

dk1a
Copy link
Member

@dk1a dk1a commented Nov 25, 2022

Closes #245

  • Use Ownable from @solidstate/contracts to implement IERC173, also use solidstate for IERC165
  • Add IOwnableWritable and OwnableWritable on top of IERC173 and Ownable, to generalize authorization which was previously built into components
  • Add Subsystem, which is a System, but uses OwnableWritable instead of Ownable
  • Fix some import formatting since I was going through the whole package anyways

Edit: removed paragraph about subsystems since they're moved to #268

@cha0sg0d
Copy link
Contributor

cc @Kooshaba, this touches on some of your multiple system contract ideas i think,

@alvrs
Copy link
Member

alvrs commented Nov 26, 2022

  1. What's the benefit of Subsystems over Libraries?
  2. Could you go into some more detail behind the reasoning of introducing diamond storage (+ benefits, implications)?

Also, let's split up the Ownable refactor and the Subsystem changes into two separate PRs

@dk1a
Copy link
Member Author

dk1a commented Nov 26, 2022

Removed Subsystem from this PR, will elaborate on it in its own PR.

Diamond storage:

benefits:

  • Libraries can directly and easily use diamond storage (something like feat(solecs): add deterministic storage location for systems, add storage access util #264). When storage slots are sequential, inheritance can make them unpredictable or difficult to work with.
  • Having it out of namespace removes some ambiguity, like in constructor arguments (but that's just my personal preference).
  • Upgradeability, but it is a very minor concern here, usually it's easier to just register new system/component over old one. And owner alone doesn't solve upgradeability issues anyways.

implications:

  • Some project clutter, since diamond storage requires an extra file.
  • Technically a breaking change (but won't affect most users, directly using _owner wasn't usually necessary, and owner(), transferOwnership() behave the same)
  • Using owner directly in the contract will be fiddly, having to import the storage file (but as with the previous point, that should almost never be needed)

The first benefit applies even more so to the other state vars, especially in System: world, components. But that's for another PR (the 2 drafts I made)

@dk1a
Copy link
Member Author

dk1a commented Nov 26, 2022

Oh also removed the tests, they'll be together with Subsystem since they use it, unless it's rejected changing them back and forth seems unnecessary.

@dk1a dk1a changed the title feat(solecs): refactor access control, add Subsystem, fix some import formatting feat(solecs): refactor access control, fix some import formatting Nov 26, 2022
@dk1a dk1a mentioned this pull request Nov 26, 2022
@dk1a dk1a mentioned this pull request Dec 10, 2022
Copy link
Member

@alvrs alvrs left a comment

Choose a reason for hiding this comment

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

Looking really good, thank you! Just had one minor comment and one question, and need to test locally.

Comment on lines +22 to +24
if (!writeAccess(msg.sender)) {
revert OwnableWritable__NotWriter();
}
Copy link
Member

Choose a reason for hiding this comment

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

curious about your preference of revert over require - could you elaborate?

Copy link
Member Author

@dk1a dk1a Jan 5, 2023

Choose a reason for hiding this comment

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

it's more about my preference of custom errors over error strings. Custom errors just don't support require, unfortunately.
I took the specific semantics (Contract__ErrorName) from solidstate.

  • Unlike strings, custom errors are guaranteed to be devoid of typos, since you can define them in one place, and use (via imports or inheritance) everywhere
  • They allow args (like events), which is the most convenient way to do dynamic errors imo
  • They aren't strings, so they should be more gas-efficient
  • I just don't like the hardcoded nature of error-strings (this is similar to the 1st point, but about personal preference rather than some objective benefit)

imo it'd be great if mud started leaning towards these event-like errors. But if you ultimately prefer require, I can keep that in mind for future PRs

Copy link
Contributor

Choose a reason for hiding this comment

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

Seconding request for use of Custom Errors moving forward!

Copy link
Member

Choose a reason for hiding this comment

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

Thanks for elaborating, I agree custom errors are a better approach!

packages/solecs/src/OwnableWritableStorage.sol Outdated Show resolved Hide resolved
@alvrs alvrs self-assigned this Jan 5, 2023
@alvrs
Copy link
Member

alvrs commented Jan 5, 2023

Seems like @solidstate/contracts removed setOwner from OwnableStorage since v0.0.49: solidstate-network/solidstate-solidity@7378a2c. Should we upgrade to the latest version (0.0.52)?

@dk1a
Copy link
Member Author

dk1a commented Jan 5, 2023

Seems like @solidstate/contracts removed setOwner from OwnableStorage since v0.0.49: solidstate-network/solidstate-solidity@7378a2c. Should we upgrade to the latest version (0.0.52)?

Updated it. I actually prefer the lack of setOwner

Copy link
Member

@alvrs alvrs left a comment

Choose a reason for hiding this comment

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

Looks great! We should make sure to mention the requirement to install @solidstate/contracts in consuming packages in the merge commit. Technically a breaking change, but not worth waiting for this change until the next breaking version imo.

@alvrs alvrs changed the title feat(solecs): refactor access control, fix some import formatting refactor(solecs): use @solidstate Ownable, add OwnableWritable, fix some import formatting Jan 10, 2023
@alvrs alvrs merged commit 4043f3c into latticexyz:main Jan 10, 2023
contract Ownable is SolidStateOwnable {
constructor() {
// Initialize owner (SolidState has no constructors)
OwnableStorage.layout().owner = msg.sender;
Copy link
Member

@holic holic Jan 10, 2023

Choose a reason for hiding this comment

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

ooc why set this manually like this rather than calling _setOwner(msg.sender)?

Copy link
Member Author

Choose a reason for hiding this comment

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

Because it's set in just 1 place and having an explicit method for it seemed unnecessary.
The method also emits an event.
Which is important, because after checking EIP-173, the event should be emitted on creation too.
Since it's merged I'll make a fix PR to use _setOwner, @holic thanks for noticing

Copy link
Member Author

Choose a reason for hiding this comment

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

Because it's set in just 1 place and having an explicit method for it seemed unnecessary.

By that I mean, _setOwner didn't exist in the previous version (I made the PR 2 months ago and recently updated solidstate), and when updating I didn't think to check for a method

Copy link
Member Author

Choose a reason for hiding this comment

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

#265 (comment)

and this comment is about another setOwner which was removed, it didn't emit an event

LPSCRYPT pushed a commit to LPSCRYPT/esp that referenced this pull request Jan 23, 2023
…ome import formatting (latticexyz#265)

* refactor(solecs): use @SolidState Ownable, add OwnableWritable, fix some import formatting (latticexyz#265)

* build(solecs): add peerDependencies to package.json

breaking:
- consumers need to install `@solidstate/contracts` as a new peerDependency of `solecs`.
- internal `_owner` field was removed from `Component`. (Use `owner()` instead.)

Co-authored-by: alvrs <alvarius@lattice.xyz>
@dk1a dk1a deleted the dk1a/access_control branch February 5, 2023 10:40
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.

Use Ownable std implementation for all ownable MUD contracts (Component, System, Set, MapSet))
4 participants