Skip to content

Commit

Permalink
Merge pull request #4 from Hats-Protocol/fix/creation-args
Browse files Browse the repository at this point in the history
Fix/creation-args
  • Loading branch information
spengrah authored Sep 13, 2024
2 parents 8395702 + fa5a0e5 commit 5129e99
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 60 deletions.
30 changes: 15 additions & 15 deletions script/Deploy.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ contract Deploy is Script {

// default values
bool internal _verbose = true;
string internal _version = "0.1.0"; // increment this with each new deployment
string internal _version = "0.1.1"; // increment this with each new deployment
address internal _feeSplitRecipient = 0x58C8854a8E51BdCE9F00726B966905FE2719B4D9;
uint256 internal _feeSplitPercentage = 500; // 5%

Expand Down Expand Up @@ -87,7 +87,6 @@ contract DeployInstance is Script {
uint256 internal _saltNonce = 2;
uint256 internal _hatId = 0x0000020f00010001000000000000000000000000000000000000000000000000;
address internal _unlockFactory = 0x36b34e10295cCE69B652eEB5a8046041074515Da; // sepolia
PublicLockV14Eligibility.LockConfig internal _lockConfig;

// lock config defaults
uint256 internal _expirationDuration = 30 days;
Expand All @@ -103,13 +102,23 @@ contract DeployInstance is Script {
address implementation,
uint256 hatId,
uint256 saltNonce,
PublicLockV14Eligibility.LockConfig memory lockConfig
uint256 expirationDuration,
address tokenAddress,
uint256 keyPrice,
uint256 maxNumberOfKeys,
address lockManager,
string memory lockName
) public {
_verbose = verbose;
_implementation = implementation;
_hatId = hatId;
_saltNonce = saltNonce;
_lockConfig = lockConfig;
_expirationDuration = expirationDuration;
_tokenAddress = tokenAddress;
_keyPrice = keyPrice;
_maxNumberOfKeys = maxNumberOfKeys;
_lockManager = lockManager;
_lockName = lockName;
}

/// @dev Set up the deployer via their private key from the environment
Expand All @@ -129,22 +138,13 @@ contract DeployInstance is Script {
function run() public virtual returns (PublicLockV14Eligibility) {
vm.startBroadcast(deployer());

// use the default values if the prepared lockConfig is empty
if (_lockConfig.expirationDuration == 0) {
_lockConfig.expirationDuration = _expirationDuration;
_lockConfig.tokenAddress = _tokenAddress;
_lockConfig.keyPrice = _keyPrice;
_lockConfig.maxNumberOfKeys = _maxNumberOfKeys;
_lockConfig.lockManager = _lockManager;
_lockConfig.lockName = _lockName;
}

instance = PublicLockV14Eligibility(
factory.createHatsModule(
_implementation,
_hatId,
abi.encodePacked(), // other immutable args
abi.encode(_lockConfig), // init data
abi.encode(_expirationDuration, _tokenAddress, _keyPrice, _maxNumberOfKeys, _lockManager, _lockName), // init
// data
_saltNonce
)
);
Expand Down
43 changes: 22 additions & 21 deletions src/PublicLockV14Eligibility.sol
Original file line number Diff line number Diff line change
Expand Up @@ -38,19 +38,6 @@ contract PublicLockV14Eligibility is HatsEligibilityModule, ILockKeyPurchaseHook
/// @notice Emitted when the referrer fee percentage is set in the implementation contract
event ImplementationReferrerFeePercentageSet(uint256 referrerFeePercentage);

/*//////////////////////////////////////////////////////////////
DATA MODELS
//////////////////////////////////////////////////////////////*/

struct LockConfig {
uint256 expirationDuration;
address tokenAddress;
uint256 keyPrice;
uint256 maxNumberOfKeys;
address lockManager;
string lockName;
}

/*//////////////////////////////////////////////////////////////
CONSTANTS
//////////////////////////////////////////////////////////////*/
Expand Down Expand Up @@ -130,17 +117,24 @@ contract PublicLockV14Eligibility is HatsEligibilityModule, ILockKeyPurchaseHook
/// @inheritdoc HatsModule
function _setUp(bytes calldata _initData) internal override {
// decode init data
LockConfig memory lockConfig = abi.decode(_initData, (LockConfig));
(
uint256 _expirationDuration,
address _tokenAddress,
uint256 _keyPrice,
uint256 _maxNumberOfKeys,
address _lockManager,
string memory _lockName
) = abi.decode(_initData, (uint256, address, uint256, uint256, address, string));

// encode the lock init data
bytes memory lockInitData = abi.encodeWithSignature(
"initialize(address,uint256,address,uint256,uint256,string)",
address(this),
lockConfig.expirationDuration,
lockConfig.tokenAddress,
lockConfig.keyPrice,
lockConfig.maxNumberOfKeys,
lockConfig.lockName
_expirationDuration,
_tokenAddress,
_keyPrice,
_maxNumberOfKeys,
_lockName
);

// create the new lock
Expand All @@ -165,7 +159,7 @@ contract PublicLockV14Eligibility is HatsEligibilityModule, ILockKeyPurchaseHook
lock.setReferrerFee(REFERRER, fee);

// add lock manager role to the configured address
lock.addLockManager(lockConfig.lockManager);
lock.addLockManager(_lockManager);
// revokes itself lock manager
lock.renounceLockManager();
}
Expand Down Expand Up @@ -197,7 +191,7 @@ contract PublicLockV14Eligibility is HatsEligibilityModule, ILockKeyPurchaseHook
address, /* recipient */
address, /* referrer */
bytes calldata /* data */
) external view returns (uint256 minKeyPrice) {
) public view returns (uint256 minKeyPrice) {
// Check if referrer fee is correct. Fail minting if incorrect.
if (lock.referrerFees(REFERRER) != referrerFeePercentage) {
revert InvalidReferrerFee();
Expand Down Expand Up @@ -303,6 +297,13 @@ contract PublicLockV14Eligibility is HatsEligibilityModule, ILockKeyPurchaseHook
return lock.maxNumberOfKeys();
}

/// @notice Convenience function to get the key price from the lock
/// @dev This function wraps the main {keyPurchasePrice} function to enable it to be called without arguments, eg by
/// the Hats Modules SDK
function keyPurchasePrice() external view returns (uint256) {
return this.keyPurchasePrice(address(0), address(0), address(0), bytes(""));
}

/*//////////////////////////////////////////////////////////////
INTERNAL FUNCTIONS
//////////////////////////////////////////////////////////////*/
Expand Down
78 changes: 54 additions & 24 deletions test/PublicLockEligibility.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,12 @@ contract PublicLockV14EligibilityTest is Deploy, Test {
uint256 public targetHat; // should be worn by {wearer}

// lock init data
PublicLockV14Eligibility.LockConfig lockConfig;
uint256 public expirationDuration_;
address public tokenAddress_;
uint256 public keyPrice_;
uint256 public maxNumberOfKeys_;
address public lockManager_;
string public lockName_;

string public MODULE_VERSION;

Expand Down Expand Up @@ -106,14 +111,13 @@ contract WithInstanceTest is PublicLockV14EligibilityTest {
saltNonce = 1;

// set lock init data
lockConfig = PublicLockV14Eligibility.LockConfig({
expirationDuration: 1 days, // 1 day
tokenAddress: address(0), // ETH
keyPrice: 1 ether, // 1 ETH
maxNumberOfKeys: 10, // 10 keys
lockManager: lockManager,
lockName: "Unlock Eligibility Test"
});

expirationDuration_ = 1 days; // 1 day
tokenAddress_ = address(0); // ETH
keyPrice_ = 1 ether; // 1 ETH
maxNumberOfKeys_ = 10; // 10 keys
lockManager_ = lockManager;
lockName_ = "Unlock Eligibility Test";

// set up the hats
tophat = HATS.mintTopHat(org, "test", "test");
Expand All @@ -124,7 +128,18 @@ contract WithInstanceTest is PublicLockV14EligibilityTest {

// deploy the instance using the script; this will also create a new lock
deployInstance = new DeployInstance();
deployInstance.prepare(false, address(implementation), targetHat, saltNonce, lockConfig);
deployInstance.prepare(
false,
address(implementation),
targetHat,
saltNonce,
expirationDuration_,
tokenAddress_,
keyPrice_,
maxNumberOfKeys_,
lockManager_,
lockName_
);
instance = deployInstance.run();

// mint the adminHat to the instance so that it can mint the targetHat
Expand Down Expand Up @@ -218,11 +233,11 @@ contract Deployment is WithInstanceTest {
// lock config
assertTrue(lock.isLockManager(address(lockManager)));
assertFalse(lock.isLockManager(address(instance)));
assertEq(lock.keyPrice(), lockConfig.keyPrice);
assertEq(lock.maxNumberOfKeys(), lockConfig.maxNumberOfKeys);
assertEq(lock.expirationDuration(), lockConfig.expirationDuration);
assertEq(lock.name(), lockConfig.lockName);
assertEq(lock.tokenAddress(), lockConfig.tokenAddress);
assertEq(lock.keyPrice(), keyPrice_);
assertEq(lock.maxNumberOfKeys(), maxNumberOfKeys_);
assertEq(lock.expirationDuration(), expirationDuration_);
assertEq(lock.name(), lockName_);
assertEq(lock.tokenAddress(), tokenAddress_);
assertEq(lock.onKeyPurchaseHook(), address(instance));

// lock version
Expand Down Expand Up @@ -324,7 +339,7 @@ contract DeploymentSepolia is Deployment {
contract KeyPurchasePrice is WithInstanceTest {
function test_happy() public view {
uint256 price = instance.keyPurchasePrice(address(0), address(0), address(0), bytes(""));
assertEq(price, lockConfig.keyPrice);
assertEq(price, keyPrice_);
}

function test_revert_invalidReferrerFee() public {
Expand All @@ -340,6 +355,10 @@ contract KeyPurchasePrice is WithInstanceTest {
vm.expectRevert(PublicLockV14Eligibility.InvalidReferrerFee.selector);
instance.keyPurchasePrice(address(0), address(0), address(0), bytes(""));
}

function test_convenienceFunction() public view {
assertEq(instance.keyPurchasePrice(), instance.keyPurchasePrice(address(0), address(0), address(0), bytes("")));
}
}

contract OnKeyPurchase is WithInstanceTest {
Expand Down Expand Up @@ -495,7 +514,7 @@ contract KeyPurchaseToken is WithInstanceTest {

// update the token address
vm.prank(lockManager);
lock.updateKeyPricing(lockConfig.keyPrice, token);
lock.updateKeyPricing(keyPrice_, token);

// the new token should be returned
assertEq(instance.keyPurchaseToken(), token);
Expand All @@ -506,12 +525,12 @@ contract ExpirationDuration is WithInstanceTest {
function test_happy() public {
lock = _getLock();

assertEq(instance.expirationDuration(), lockConfig.expirationDuration);
assertEq(instance.expirationDuration(), expirationDuration_);

// change the expiration duration
uint256 newDuration = lockConfig.expirationDuration + 1;
uint256 newDuration = expirationDuration_ + 1;
vm.prank(lockManager);
lock.updateLockConfig(newDuration, lockConfig.maxNumberOfKeys, 1);
lock.updateLockConfig(newDuration, maxNumberOfKeys_, 1);

// the new duration should be returned
assertEq(instance.expirationDuration(), newDuration);
Expand All @@ -522,12 +541,12 @@ contract MaxNumberOfKeys is WithInstanceTest {
function test_happy() public {
lock = _getLock();

assertEq(instance.maxNumberOfKeys(), lockConfig.maxNumberOfKeys);
assertEq(instance.maxNumberOfKeys(), maxNumberOfKeys_);

// change the max number of keys
uint256 newMaxNumberOfKeys = lockConfig.maxNumberOfKeys + 1;
uint256 newMaxNumberOfKeys = maxNumberOfKeys_ + 1;
vm.prank(lockManager);
lock.updateLockConfig(lockConfig.expirationDuration, newMaxNumberOfKeys, 1);
lock.updateLockConfig(expirationDuration_, newMaxNumberOfKeys, 1);

// the new max number of keys should be returned
assertEq(instance.maxNumberOfKeys(), newMaxNumberOfKeys);
Expand Down Expand Up @@ -556,7 +575,18 @@ contract SetImplementationReferrerFeePercentage is WithInstanceTest {
assertEq(instance.referrerFeePercentage(), oldFee);

// new instance should have the new referrer fee percentage
deployInstance.prepare(false, address(implementation), targetHat, saltNonce + 1, lockConfig);
deployInstance.prepare(
false,
address(implementation),
targetHat,
saltNonce + 1,
expirationDuration_,
tokenAddress_,
keyPrice_,
maxNumberOfKeys_,
lockManager_,
lockName_
);
PublicLockV14Eligibility newInstance = deployInstance.run();
assertEq(newInstance.referrerFeePercentage(), newFee);
}
Expand Down

0 comments on commit 5129e99

Please sign in to comment.