Skip to content

Commit

Permalink
feat: ReservedUsernameRule fully implemented
Browse files Browse the repository at this point in the history
  • Loading branch information
donosonaumczuk committed Dec 20, 2024
1 parent e581cdc commit 466a516
Showing 1 changed file with 64 additions and 30 deletions.
94 changes: 64 additions & 30 deletions contracts/rules/username/ReservedUsernameRule.sol
Original file line number Diff line number Diff line change
Expand Up @@ -12,55 +12,89 @@ contract ReservedUsernameRule is IUsernameRule {
using AccessControlLib for IAccessControl;
using AccessControlLib for address;

// uint256(keccak256("CREATE_RESERVED_USERNAME"))
uint256 immutable CREATE_RESERVED_USERNAME_PID =
uint256(0xfb95904fa3067a919177cb314539246e6f76089564454716cce76492e210edfc);
// TODO: Think about renaming Username primitive to Namespace or something else
event Lens_ReservedUsernameRule_UsernameReserved(
address indexed usernamePrimitive, bytes32 indexed configSalt, string indexed indexedUsername, string username
);
event Lens_ReservedUsernameRule_UsernameReleased(
address indexed usernamePrimitive, bytes32 indexed configSalt, string indexed indexedUsername, string username
);
event Lens_ReservedUsernameRule_ReservedUsernameCreated(
address indexed usernamePrimitive,
bytes32 indexed configSalt,
string indexed indexedUsername,
string username,
address account,
address createdBy
);

// keccak256("lens.param.key.accessControl");
bytes32 immutable ACCESS_CONTROL_PARAM_KEY = 0x6552dd4db64bdb68f2725e4865ecb072df1c2befcfb455b69e2d2b886a8e185e;
// keccak256("lens.rules.username.CharsetUsernameRule.param.key.CharsetRestrictions.allowNumeric");
bytes32 immutable ALLOW_NUMERIC_PARAM_KEY = 0x99d79d7e6786d3f6700df19cf91a74d5ed8a7432315a6bd2c8e4b2f31d3ac48a;
// keccak256("lens.rules.username.CharsetUsernameRule.param.key.CharsetRestrictions.allowLatinLowercase");
// keccak256("lens.param.key.usernamesToReserve");
bytes32 immutable USERNAMES_TO_RESERVE_PARAM_KEY = 0xe35845d5270ebd172ba5dfaf14a7256cbc847d131e6a9d37dcd9bce7c75e9e77;
// keccak256("lens.param.key.usernamesToRelease");
bytes32 immutable USERNAMES_TO_RELEASE_PARAM_KEY = 0x68f854736312031d89be36bdf38f9d77e90822b1a6417823a39f8721c4db9cb2;

mapping(address => mapping(bytes4 => mapping(bytes32 => Configuration))) internal _configuration;
uint256 constant CREATE_RESERVED_USERNAME_PID = uint256(keccak256("CREATE_RESERVED_USERNAME"));

mapping(address => mapping(bytes32 => address)) internal _accessControl;
mapping(address => mapping(bytes32 => mapping(string => bool))) internal _isUsernameReserved;

constructor() {
emit Events.Lens_PermissionId_Available(SKIP_CHARSET_PID, "SKIP_CHARSET");
emit Events.Lens_PermissionId_Available(CREATE_RESERVED_USERNAME_PID, "CREATE_RESERVED_USERNAME");
}

function configure(
bytes4 ruleSelector,
bytes32 salt,
KeyValue[] calldata ruleConfigurationParams
) external override {
require(ruleSelector == this.processCreation.selector);
Configuration memory configuration = _extractConfigurationFromParams(ruleConfigurationParams);
configuration.accessControl.verifyHasAccessFunction();
_configuration[msg.sender][ruleSelector][salt] = configuration;
function configure(bytes32 configSalt, KeyValue[] calldata ruleParams) external override {
address accessControl;
for (uint256 i = 0; i < ruleParams.length; i++) {
if (ruleParams[i].key == ACCESS_CONTROL_PARAM_KEY) {
accessControl = abi.decode(ruleParams[i].value, (address));
} else if (ruleParams[i].key == USERNAMES_TO_RESERVE_PARAM_KEY) {
string[] memory usernamesToReserve = abi.decode(ruleParams[i].value, (string[]));
for (uint256 j = 0; j < usernamesToReserve.length; j++) {
require(!_isUsernameReserved[msg.sender][configSalt][usernamesToReserve[j]]);
_isUsernameReserved[msg.sender][configSalt][usernamesToReserve[j]] = true;
emit Lens_ReservedUsernameRule_UsernameReserved(
msg.sender, configSalt, usernamesToReserve[j], usernamesToReserve[j]
);
}
} else if (ruleParams[i].key == USERNAMES_TO_RELEASE_PARAM_KEY) {
string[] memory usernamesToRelease = abi.decode(ruleParams[i].value, (string[]));
for (uint256 j = 0; j < usernamesToRelease.length; j++) {
require(_isUsernameReserved[msg.sender][configSalt][usernamesToRelease[j]]);
_isUsernameReserved[msg.sender][configSalt][usernamesToRelease[j]] = false;
emit Lens_ReservedUsernameRule_UsernameReleased(
msg.sender, configSalt, usernamesToRelease[j], usernamesToRelease[j]
);
}
}
}
accessControl.verifyHasAccessFunction();
_accessControl[msg.sender][configSalt] = accessControl;
}

function processCreation(
bytes32 configSalt,
address originalMsgSender,
address, /* account */
address account,
string calldata username,
KeyValue[] calldata, /* primitiveCustomParams */
KeyValue[] calldata /* ruleExecutionParams */
) external view override {
Configuration memory configuration = _configuration[msg.sender][this.processCreation.selector][configSalt];
if (!configuration.accessControl.hasAccess(originalMsgSender, SKIP_CHARSET_PID)) {
_processRestrictions(username, configuration.charsetRestrictions);
KeyValue[] calldata, /* primitiveParams */
KeyValue[] calldata /* ruleParams */
) external override {
if (_isUsernameReserved[msg.sender][configSalt][username]) {
_accessControl[msg.sender][configSalt].requireAccess(originalMsgSender, CREATE_RESERVED_USERNAME_PID);
emit Lens_ReservedUsernameRule_ReservedUsernameCreated(
msg.sender, configSalt, username, username, account, originalMsgSender
);
}
}

function processRemoval(
bytes32, /* configSalt */
address, /* originalMsgSender */
string calldata, /* username */
KeyValue[] calldata, /* primitiveCustomParams */
KeyValue[] calldata /* ruleExecutionParams */
KeyValue[] calldata, /* primitiveParams */
KeyValue[] calldata /* ruleParams */
) external pure override {
revert();
}
Expand All @@ -70,8 +104,8 @@ contract ReservedUsernameRule is IUsernameRule {
address, /* originalMsgSender */
address, /* account */
string calldata, /* username */
KeyValue[] calldata, /* primitiveCustomParams */
KeyValue[] calldata /* ruleExecutionParams */
KeyValue[] calldata, /* primitiveParams */
KeyValue[] calldata /* ruleParams */
) external pure override {
revert();
}
Expand All @@ -81,8 +115,8 @@ contract ReservedUsernameRule is IUsernameRule {
address, /* originalMsgSender */
address, /* account */
string calldata, /* username */
KeyValue[] calldata, /* primitiveCustomParams */
KeyValue[] calldata /* ruleExecutionParams */
KeyValue[] calldata, /* primitiveParams */
KeyValue[] calldata /* ruleParams */
) external pure override {
revert();
}
Expand Down

0 comments on commit 466a516

Please sign in to comment.