-
Notifications
You must be signed in to change notification settings - Fork 0
feat: payment processor #5
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
Conversation
update `feat/payment-processor` branch
Co-Authored-By: hey-ewan <ewanretorokugbe@gmail.com> Co-Authored-By: g4titanx <g4titan1@gmail.com>
WalkthroughThe pull request introduces multiple modifications across the repository. Two new environment variables have been added to extend configuration options. Several dependency versions have been updated, and a new dependency has been added in the package configuration. The main ForgeRegistry contract has been enhanced with additional inheritance, state variables, events, custom errors, updated function signatures, and extended logic for licensing, NFT creation, and payment handling. Moreover, a new abstract ForgeStorage contract has been created, deployment scripts and related tests have been updated, various configuration files have been modified, and a binary target has been removed from a Cargo configuration. Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant ForgeRegistry
participant LicensingModule
participant PaymentHandler
User->>ForgeRegistry: Call register(receiver, IPMetadata, appId, submitter)
Note over ForgeRegistry: Validate addresses and funds
ForgeRegistry->>LicensingModule: Attach licensing terms
ForgeRegistry->>PaymentHandler: Process payment
PaymentHandler-->>ForgeRegistry: Confirm payment
ForgeRegistry-->>User: Emit IPRegistered event
sequenceDiagram
participant Deployer
participant DeployScript
participant Proxy
participant ForgeRegistry
Deployer->>DeployScript: Provide initialisation parameters (incl. licensing, royalty, batcher)
DeployScript->>Proxy: Deploy proxy with initialisation data
Proxy->>ForgeRegistry: Call initialize with extended parameters
ForgeRegistry-->>Proxy: Contract initialised successfully
Poem
🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
🧹 Nitpick comments (6)
execution/contracts/src/ForgeRegistry.sol (3)
16-17: Remove duplicate import.Line 16 and line 17 import the same contract
RoyaltyPolicyLAP. Please remove one of the imports to avoid confusion.- import {RoyaltyPolicyLAP} from "@storyprotocol/core/modules/royalty/policies/LAP/RoyaltyPolicyLAP.sol";
122-126: Minimise repeated ownership initialisation.You are calling
__Ownable_init(owner)and_transferOwnership(owner)in the same function. Typically,__Ownable_init(owner)is sufficient to set up ownership. Re-check if the second call to_transferOwnership(owner)is needed.
281-299: Emitted eventBalanceLockedis confusing duringwithdraw.You emit
BalanceLocked(msg.sender)on line 296 within thewithdraw()function after resettingunlockBlockTime. This may cause confusion, as the user is withdrawing rather than explicitly re-locking funds. Consider using a more specific event name or clarifying the rationale.execution/crates/payment/src/lib.rs (2)
1-5: These public functions currently have no implementation.Consider adding logic or documentation to detail how
deposit_to_forge,check_balance_on_forge, andestimate_feeshould operate. This helps consumers understand the intended usage.
7-10: Basic test module declared.At present, the test module is empty. Add unit tests for these new public functions to ensure correctness once they are implemented.
execution/contracts/package.json (1)
2-8: Updated Dependencies Versions VerificationThe dependency versions for
@openzeppelin/contracts,@openzeppelin/contracts-upgradeable,@story-protocol/protocol-core, and@story-protocol/protocol-peripheryhave been bumped. Please ensure that these new versions are fully compatible with our contract implementations and that no breaking changes have been introduced by these updates.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (2)
execution/Cargo.lockis excluded by!**/*.lockexecution/contracts/pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (6)
.env.example(1 hunks)execution/contracts/package.json(1 hunks)execution/contracts/src/ForgeRegistry.sol(5 hunks)execution/contracts/src/ForgeStorage.sol(1 hunks)execution/crates/payment/Cargo.toml(1 hunks)execution/crates/payment/src/lib.rs(1 hunks)
✅ Files skipped from review due to trivial changes (2)
- .env.example
- execution/crates/payment/Cargo.toml
⏰ Context from checks skipped due to timeout of 90000ms (1)
- GitHub Check: Test
🔇 Additional comments (10)
execution/contracts/src/ForgeRegistry.sol (7)
24-24: Solid usage ofReentrancyGuardUpgradeable.Protecting your contract from re-entrancy attacks in payment and withdrawal operations is prudent.
97-102: Ensure correct initialisation with_batcherWallet.Including
_batcherWalletin the constructor ensures correct usage of theonlyBatchermodifier. Double-check that your deployment script passes the correct wallet address during initialisation.
219-229: Licensing terms integration appears cohesive.Registering the licence terms and attaching them to the IP is logically consistent with your current architecture. Ensure any future updates to
PILicenseTemplateorILicensingModuleremain backward compatible.
255-260: Thereceive()function is straightforward.Funds are credited to the sender’s balance, with the
unlockBlockTimereset. This aligns well with your deposit approach.
262-271: Possible edge case for zero-balance users.Calling
unlock()with a zero balance reverts, which is logical. Confirm there are no scenarios where a user might need to set an unlock time prior to depositing funds.
273-279: Lock function with zero-balance revert.Your logic prevents users from locking zero-balance accounts. While consistent, verify that no workflow requires a user to re-lock after fully withdrawing.
301-312: View functions are neatly structured.Accessors for balances, nonces, and unlock block times are clear and consistent with the
userDatamapping.execution/contracts/src/ForgeStorage.sol (2)
5-9: UserInfo struct covers essential fields.Storing
balance,unlockBlockTime, andnoncecaters to fundamental user fund management. Ensure future additions do not break storage layout.
11-15: Public mapping and batcherWallet variable are clearly defined.
batcherWalletfor theonlyBatcherchecks and theuserDatamapping for user funds tracking are both straightforward. The__GAParray is a sound approach for preserving storage space.execution/contracts/package.json (1)
9-12: DevDependencies ValidationThe
devDependenciesremain unaltered, which is acceptable as there was no need for version changes here. However, please verify that the existing versions ofds-testandforge-stdcontinue to support our testing framework without any issues.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (7)
execution/contracts/src/ForgeRegistry.sol (7)
2-2: Consider using a more flexible pragma version.The current pragma
^0.8.26is very specific. Consider using a more flexible version range like^0.8.0to ease future upgrades while maintaining compatibility with OpenZeppelin contracts.-pragma solidity ^0.8.26; +pragma solidity ^0.8.0;
27-27: Consider making UNLOCK_BLOCK_TIME configurable.The unlock time is hardcoded to 1 hour. Consider making it configurable by the contract owner to allow for adjustments based on business needs.
- uint256 public constant UNLOCK_BLOCK_TIME = 3600 seconds; + uint256 public UNLOCK_BLOCK_TIME;
45-49: Add NatSpec documentation for the Terms struct.The Terms struct lacks documentation explaining the purpose of each field. Consider adding NatSpec comments to improve code maintainability.
+ /// @notice Struct defining the terms of an IP license + /// @param transferable Whether the license can be transferred + /// @param commercial Whether commercial use is allowed + /// @param commercialAttribution Whether attribution is required for commercial use struct Terms { bool transferable; bool commercial; bool commercialAttribution; }
52-63: Consider adding more indexed parameters to events.The PaymentReceived and FundsWithdrawn events could benefit from indexing the amount parameter to allow efficient filtering of high-value transactions.
- event PaymentReceived(address indexed sender, uint256 amount); + event PaymentReceived(address indexed sender, uint256 indexed amount); - event FundsWithdrawn(address indexed recipient, uint256 amount); + event FundsWithdrawn(address indexed recipient, uint256 indexed amount);
93-135: Consider emitting an event after initialization.The initialize function performs critical setup but doesn't emit an event. Consider adding an event to log the initialization parameters for better transparency and auditability.
+ event ForgeRegistryInitialized( + address indexed ipAssetRegistry, + address indexed registrationWorkflows, + address indexed batcherWallet + ); function initialize( // ... parameters ... ) public initializer { // ... existing code ... + emit ForgeRegistryInitialized( + ipAssetRegistryAddress, + registrationWorkflowsAddress, + _batcherWallet + ); }
229-229: Consider making the gas refund multiplier configurable.The gas refund multiplier is hardcoded to 110%. Consider making it configurable by the contract owner to adjust for varying network conditions.
+ uint256 public gasRefundMultiplier = 110; // ... in register function ... - uint256 refundAmount = (gasUsed * tx.gasprice * 110) / 100; + uint256 refundAmount = (gasUsed * tx.gasprice * gasRefundMultiplier) / 100;
259-263: Consider adding a minimum deposit requirement.The receive function accepts any amount. Consider adding a minimum deposit requirement to prevent dust transactions that could lead to higher gas costs relative to the deposit amount.
+ uint256 public minDeposit = 0.01 ether; receive() external payable nonReentrant { + require(msg.value >= minDeposit, "Deposit amount too low"); userData[msg.sender].balance += msg.value; userData[msg.sender].unlockBlockTime = 0; emit PaymentReceived(msg.sender, msg.value); }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
execution/contracts/src/ForgeRegistry.sol(5 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (1)
- GitHub Check: Test
🔇 Additional comments (2)
execution/contracts/src/ForgeRegistry.sol (2)
80-85: LGTM! Well-implemented modifier with custom error.The onlyBatcher modifier effectively restricts access and provides clear error messages.
304-314: LGTM! Well-implemented view functions.The view functions provide clear access to user data without any state modifications.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (4)
execution/contracts/src/ForgeRegistry.sol (4)
19-28: Constant naming consistency.
AlthoughUNLOCK_BLOCK_TIMEclearly states its purpose, you might consider adding further context in a comment to clarify that it equates to one hour, given its value of 3600 seconds. This can aid readability.
45-50: Unused struct detected.
TheTermsstruct currently has no usage in the contract. If you plan to incorporate customisable terms in a future iteration, consider adding a TODO note referencing the relevant ticket or roadmap item. Otherwise, it may be removed to minimise confusion.
66-68: Remove or implementNoSubmittererror.
TheNoSubmittererror is declared but never used in the contract. If you plan to throw this error under specific conditions, please implement it; otherwise, removal is recommended to keep the codebase clean.
183-257: Refund calculation and transfer considerations.
- The partial refund logic calculates
(gasUsed * tx.gasprice * 110) / 100. While this approach is valid, it is approximate and can be influenced by any gas overhead before measuringstartGas. Documenting the 110% premium or making it adjustable might help manage future fee changes.- Using
.transfer()enforces a 2300-gas stipend. This is typically safer but can fail ifmsg.senderis a contract with a complex fallback. If you anticipate calls from contracts that require more gas in fallback, consider using.callwithnonReentrant.- The checks for both contract balance and
userData[submitter].balancelook correct, preventing unintended reverts and freeload transactions.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
execution/contracts/src/ForgeRegistry.sol(5 hunks)execution/crates/payment/src/lib.rs(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- execution/crates/payment/src/lib.rs
⏰ Context from checks skipped due to timeout of 90000ms (1)
- GitHub Check: Test
🔇 Additional comments (4)
execution/contracts/src/ForgeRegistry.sol (4)
7-17: Imports look well-structured and cohesive.
No issues found regarding the addition ofReentrancyGuardUpgradeableand new Story Protocol imports. These imports seem necessary and appropriate for the new licensing and payment logic.
259-264: Safe deposit mechanism.
Using areceive()function withnonReentranteffectively prevents re-entrancy attacks when users send Ether. The immediate assignment touserData[msg.sender].balanceappears logically sound. Consider logging zero-value deposits if they are pertinent to your business logic.
266-283: Lock/unlock workflow is straightforward.
The approach to setunlockBlockTimeonunlock()and reset it to0onlock()is intuitively clear. If users callunlock()repeatedly, they repeatedly push back the unlock time. Ensure this is the desired behaviour for your user experience.
285-302: Withdrawal flow is aligned with user balance checks.
- Verifying
amountagainstsenderData.balanceand ensuring theunlockBlockTimehas passed are strong controls.- Resetting
unlockBlockTimeto0post-withdrawal encourages a fresh lock period before the next withdrawal.- Generally well-structured logic for fund release in an upgradable contract.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
♻️ Duplicate comments (1)
execution/contracts/src/ForgeRegistry.sol (1)
339-342: 🛠️ Refactor suggestionConsider adding contract balance check before withdrawal.
Similar to the contract balance check before refunding, consider adding a check before withdrawal to ensure the contract has sufficient ETH.
senderData.balance -= amount; senderData.unlockBlockTime = 0; + require( + address(this).balance >= amount, + "Insufficient contract balance for withdrawal" + ); payable(msg.sender).transfer(amount); emit FundsWithdrawn(msg.sender, amount);
🧹 Nitpick comments (6)
execution/contracts/src/ForgeRegistry.sol (6)
26-26: Consider making unlock time configurable.The UNLOCK_BLOCK_TIME constant sets a fixed 3600-second (1 hour) lockup period. For flexibility in different environments or after gaining usage insights, consider making this value configurable through owner-controlled functions.
- uint256 public constant UNLOCK_BLOCK_TIME = 3600 seconds; + uint256 public UNLOCK_BLOCK_TIME = 3600 seconds; + + function setUnlockBlockTime(uint256 newUnlockTime) external onlyOwner { + UNLOCK_BLOCK_TIME = newUnlockTime; + emit UnlockTimeUpdated(newUnlockTime); + }
44-49: Address the TODO comment for customisable terms.The TODO comment indicates incomplete functionality. Before deploying to production, implement customisable terms to meet various licensing needs.
Would you like me to provide a design for customisable terms implementation that integrates with the Story Protocol licensing system?
179-180: Consider adding validation in the upgrade authorization.The _authorizeUpgrade function is currently empty except for the onlyOwner modifier. Consider adding validation logic to prevent upgrading to invalid implementations.
function _authorizeUpgrade( address newImplementation ) internal override onlyOwner { + // Ensure the new implementation is a contract + uint256 codeSize; + assembly { + codeSize := extcodesize(newImplementation) + } + require(codeSize > 0, "New implementation must be a contract"); }
318-324: Consider adding an unlock check before locking.The lock function doesn't check if funds are already locked (unlockBlockTime == 0), which would result in an unnecessary state update and event emission.
function lock() external nonReentrant { if (userData[msg.sender].balance == 0) { revert UserHasNoFundsToLock(msg.sender); } + if (userData[msg.sender].unlockBlockTime == 0) { + revert FundsAlreadyLocked(msg.sender); + } userData[msg.sender].unlockBlockTime = 0; emit BalanceLocked(msg.sender); }
332-337: Consider making the unlock time check more explicit.The condition for checking if funds are locked could be more explicit to improve readability and maintenance.
- if ( - senderData.unlockBlockTime == 0 || - senderData.unlockBlockTime > block.timestamp - ) { - revert FundsLocked(senderData.unlockBlockTime, block.timestamp); - } + bool fundsAreLocked = senderData.unlockBlockTime == 0; + bool unlockTimeNotReached = senderData.unlockBlockTime > block.timestamp; + + if (fundsAreLocked || unlockTimeNotReached) { + revert FundsLocked(senderData.unlockBlockTime, block.timestamp); + }
350-352: Ensure nonce purpose is documented.The nonce is incremented during the register function and exposed via this view function. Consider adding documentation about its purpose (likely for replay protection or transaction tracking).
+ /** + * @notice Returns the current nonce for the given account + * @dev Nonces are incremented after each successful registration to prevent transaction replays + * @param account The address to check + * @return The current nonce for the account + */ function user_nonces(address account) public view returns (uint256) { return userData[account].nonce; }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
execution/contracts/pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (9)
execution/contracts/broadcast/ForgeRegistry.s.sol/1315/run-latest.json(3 hunks)execution/contracts/foundry.toml(1 hunks)execution/contracts/package.json(1 hunks)execution/contracts/remappings.txt(1 hunks)execution/contracts/script/ForgeRegistry.s.sol(2 hunks)execution/contracts/src/ForgeRegistry.sol(4 hunks)execution/contracts/test/0_ForgeRegistry.t.sol(1 hunks)execution/contracts/upgrade.sh(2 hunks)execution/crates/irys/Cargo.toml(0 hunks)
💤 Files with no reviewable changes (1)
- execution/crates/irys/Cargo.toml
🧰 Additional context used
🪛 LanguageTool
execution/contracts/remappings.txt
[misspelling] ~7-~7: Hoewel het woord correct kan zijn, is er een grote kans dat het een typefout is van “noden”. Zo niet, dan is het waarschijnlijk een ouderwetse uitdrukking.
Context: ...dules/ds-test/src/ @storyprotocol/test/=node_modules/@story-protocol/protocol-core/t...
(MACHTE)
[misspelling] ~8-~8: Hoewel het woord correct kan zijn, is er een grote kans dat het een typefout is van “noden”. Zo niet, dan is het waarschijnlijk een ouderwetse uitdrukking.
Context: ...ol/protocol-core/test/foundry/ @solady/=node_modules/solady/
(MACHTE)
🔇 Additional comments (29)
execution/contracts/broadcast/ForgeRegistry.s.sol/1315/run-latest.json (11)
4-4: Deployment artifact updated with new transaction hashThis change reflects the updated hash for the new ForgeRegistry contract deployment transaction.
7-7: New ForgeRegistry contract address deployedThe contract address has been updated to reflect the new deployment of the ForgeRegistry contract with payment processing capabilities.
12-12: Increased gas limit for deployment transactionThe gas limit has been increased from 0x1a342d to 0x2f8e46 (approximately from ~1.7M to ~3.1M gas). This significant increase is likely needed to accommodate the additional payment processing functionality being added to the contract.
14-14: Updated contract bytecode with payment functionalityThe deployment bytecode has been completely revised to incorporate the new payment system functionality. This is expected as part of introducing the payment processing feature.
15-15: Transaction nonce updatedThe nonce has been updated from 0x2 to 0x9, indicating that several transactions have occurred from this account between the previous and current deployments.
22-22: Updated upgrade transaction hashThe CALL transaction hash has been updated to reflect the new upgrade transaction.
28-29: Contract upgraded with configuration for payment processingThe upgrade transaction now includes additional parameters in the input data, including multiple Ethereum addresses that likely represent components of the payment system (e.g., wallet addresses, licensing modules, royalty policy addresses).
34-36: Increased gas for upgrade transactionThe gas limit has been increased from 0xc986 to 0x3aed3 (approximately from ~52K to ~241K gas), likely to accommodate the more complex upgrade with payment system initialization.
93-119: New event logs added to upgrade transactionAdditional event logs have been added to the upgrade transaction, including ownership transfer events and initialization events. These logs will make it easier to track the contract's state changes and verify proper initialization of the payment system.
138-138: Updated deployment timestampThe timestamp has been updated to reflect the newer deployment date (1740967734 corresponds to 2025-03-31).
140-140: Updated commit hash referenceThe commit hash has been updated from 6bbcd10 to b4e012a, reflecting the latest code version used for deployment.
execution/contracts/remappings.txt (1)
7-8: Added necessary library remappings for payment system integrationThese new remappings enable access to:
- Story Protocol test utilities via
@storyprotocol/test- Solady library via
@solady- a gas-optimized Solidity utility library that can be valuable for efficient payment processing implementationThese additions are appropriate for supporting the new payment system functionality.
🧰 Tools
🪛 LanguageTool
[misspelling] ~7-~7: Hoewel het woord correct kan zijn, is er een grote kans dat het een typefout is van “noden”. Zo niet, dan is het waarschijnlijk een ouderwetse uitdrukking.
Context: ...dules/ds-test/src/ @storyprotocol/test/=node_modules/@story-protocol/protocol-core/t...(MACHTE)
[misspelling] ~8-~8: Hoewel het woord correct kan zijn, is er een grote kans dat het een typefout is van “noden”. Zo niet, dan is het waarschijnlijk een ouderwetse uitdrukking.
Context: ...ol/protocol-core/test/foundry/ @solady/=node_modules/solady/(MACHTE)
execution/contracts/foundry.toml (2)
8-8: Enabled IR-based compilation for optimized bytecodeThe addition of
via_ir = trueenables Solidity's intermediate representation pipeline during compilation, which can produce more optimized bytecode. This is particularly valuable for complex contracts like payment processors where gas efficiency is critical.Note that while IR-based compilation produces more efficient code, it may increase compilation time.
11-11: Improved security by restricting filesystem permissionsThe change restricts filesystem read access from the entire directory (
./) to only the output directory (./out), while maintaining read-write access to the deployment output directory.This is a security improvement that follows the principle of least privilege, reducing the attack surface by limiting what files the build process can access.
execution/contracts/test/0_ForgeRegistry.t.sol (1)
106-107:❓ Verification inconclusive
Updated function call to match new signature with payment flag
The
mintAndRegisterIpfunction has been updated to include a boolean parameter (set totrue), which likely indicates whether to apply payment processing for the registration operation.This change aligns with the PR's objective of adding payment functionality to the API.
To verify whether this boolean parameter is related to payment processing, I'd suggest checking the implementation of the
mintAndRegisterIpfunction in theRegistrationWorkflowscontract:
🏁 Script executed:
#!/bin/bash # Look for the mintAndRegisterIp function implementation rg -A 10 "function mintAndRegisterIp" --type solidityLength of output: 88
Verify the Payment Parameter in the Mint and Register Process
The updated call to
mintAndRegisterIpinexecution/contracts/test/0_ForgeRegistry.t.solnow includes a boolean set totrue, which appears to indicate that payment processing should occur during the registration operation. However, a preliminary attempt to locate the implementation ofmintAndRegisterIpusing the commandrg -A 10 "function mintAndRegisterIp" --type solidityfailed with an “unrecognised file type: solidity” error. This prevents us from automatically confirming that the new payment flag is being handled correctly in the
RegistrationWorkflowscontract.Action Required:
- Please verify manually (or re-run a more targeted search, e.g. using
rg -A 10 "function\s+mintAndRegisterIp" -g "*.sol") that the implementation ofmintAndRegisterIpin theRegistrationWorkflowscontract correctly utilises the boolean parameter for payment processing.execution/contracts/upgrade.sh (2)
17-22: Appropriate environment variable additions for license and payment functionalities.The new required environment variables properly reflect the added dependencies for the payment processing system integration in the ForgeRegistry contract.
77-82: Verification steps added for the new environment variables.The upgrade log has been appropriately extended to include the newly required addresses, creating a complete record of the deployment configuration for audit and troubleshooting purposes.
execution/contracts/script/ForgeRegistry.s.sol (5)
21-25: Added licensine-related parameters to initialization.The additional parameters properly support the new licensing and royalty functionality being introduced in the ForgeRegistry contract.
30-30: Contract address cast changed to payable.The proxy address is now properly cast to a payable address to support the payment functionality in the ForgeRegistry contract.
43-43: Ensure deployer address is used consistently.The deployer address is now being stored in a variable, which aligns with its usage in the initialization parameters.
50-59: Well-structured reinitializer with all required parameters.The data variable correctly encodes all parameters needed for the ForgeRegistry contract's reinitialize function, maintaining consistency with the initialization function.
63-63: Using structured data for reinitializer call.The upgradeToAndCall function now correctly passes the encoded data instead of an empty string, ensuring proper reinitialization.
execution/contracts/package.json (1)
3-8:❓ Verification inconclusive
Dependencies appropriately updated for new functionality.
The package updates to OpenZeppelin and Story Protocol libraries, along with the addition of Solady (a gas-optimized utility library), align well with the payment processing implementation.
Verify the compatibility of these updated dependencies with your existing codebase.
🌐 Web query:
Are there any breaking changes in OpenZeppelin contracts from version 5.1.0 to 5.2.0?💡 Result:
OpenZeppelin Contracts 5.2.0 introduces minimal breaking changes compared to 5.1.0, with only one notable modification affecting existing implementations:
Breaking Change in Custom Error Handling
TheErrors.FailedCallcustom error identifier was removed fromAddress.sendValue, replaced by direct propagation of revert reasons. Contracts previously catching this specific error throughtry/catchblocks or error signature matching will need to update their error handling logic to account for raw revert messages instead[1][7][9].This minor breaking change aligns with OpenZeppelin's approach in recent versions to simplify error handling while maintaining stability for most users. The 5.2 release primarily focuses on new features like:
- Cross-chain utilities (CAIP identifiers)
- Account abstraction frameworks (ERC-4337/7579 support)
- Enhanced governance tools (overridable voting and extended vote tracking)[1][4][7]
Developers upgrading from 5.1.0 should review any custom error handling around
Addressoperations but can otherwise expect backward compatibility for most use cases. The changes demonstrate OpenZeppelin's continued strategy of introducing breaking changes only when necessary for security or major feature upgrades[6][10].Citations:
- 1: https://blog.openzeppelin.com/introducing-openzeppelin-contracts-5.2-and-openzeppelin-community-contracts
- 2: https://socket.dev/npm/package/@openzeppelin/contracts-upgradeable/versions/5.0.1
- 3: https://docs.openzeppelin.com/contracts/3.x/releases-stability
- 4: https://blog.openzeppelin.com/introducing-openzeppelin-contracts-v5.1
- 5: https://classic.yarnpkg.com/en/package/embark-coverage
- 6: https://www.npmjs.com/package/@openzeppelin/contracts/v/4.5.0?activeTab=versions
- 7: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/CHANGELOG.md?plain=1
- 8: https://docs.soliditylang.org/en/latest/050-breaking-changes.html
- 9: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/CHANGELOG.md
- 10: https://blog.openzeppelin.com/introducing-openzeppelin-contracts-5.0
Action: Verify dependency compatibility update for payment processing
The dependency updates in
execution/contracts/package.jsonare final, and the new versions of OpenZeppelin and Story Protocol libraries—as well as the addition of Solady—support the intended new functionality. However, note that OpenZeppelin Contracts v5.2.0 introduces a minor breaking change: the removal of theErrors.FailedCallcustom error inAddress.sendValue, which is now replaced by direct propagation of revert reasons. If your implementation includes custom error handling (e.g. using try/catch blocks to capture this specific error), please review and update your logic accordingly.
- Confirm that any custom error handling around
Address.sendValueis compatible with the new handling.- Verify overall compatibility of the updated dependencies with the existing codebase.
execution/contracts/src/ForgeRegistry.sol (6)
18-24: Enhanced contract inheritance with security measures.The addition of ReentrancyGuardUpgradeable provides protection against reentrancy attacks, which is crucial for the new payment handling functions. The inheritance from ForgeStorage centralizes data structures and separates concerns.
273-276: Good addition of contract balance check.This balance check properly addresses the previous review comment about ensuring sufficient contract balance before performing a transfer. This change helps prevent transaction failures and provides a clearer error message.
278-284: Proper validation of submitter's balance.The code now correctly checks if the submitter has sufficient balance to cover the refund, with a detailed error that includes the available balance and required amount.
297-297: Potential risk of insufficient contract balance for refund.The refund logic calculates the gas used and transfers the
refundAmountto the batcher. Consider verifying the contract's Ether balance before calling.transfer(), to prevent unintended reverts if the contract's balance is insufficient, even ifuserData[submitter].balancecovers the cost.
301-305: Add event emission for receive function.The receive function properly updates the user's balance and emits an event. This pattern should be maintained for all state-changing functions for proper transparency and auditability.
346-348: Good exposure of user balance information.The view functions for user data provide a clean interface for external contracts and clients to check balance information.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Nitpick comments (1)
execution/crates/registrar/src/lib.rs (1)
47-49: Improved error handling with inspect_errSwitching from
map_errtoinspect_erris a good practice as it logs errors without transforming them, maintaining the original error context.Consider applying the same error handling pattern to other error cases in this file for consistency.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
execution/crates/registrar/src/lib.rs(7 hunks)execution/src/service.rs(1 hunks)execution/src/utils.rs(3 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (1)
- GitHub Check: Test
🔇 Additional comments (8)
execution/src/service.rs (1)
285-285: Required parameter addition for submitterThis change is well-integrated and correctly passes the new
submitterparameter from the content schema to theregister_ipfunction.execution/src/utils.rs (3)
46-46: New field correctly added to ContentSchema structThe addition of the
submitterfield to store the submitter's address is properly typed and implemented.
118-128: Loop refactoring improves readabilityThe change from a
while letloop to aforloop withlines.by_ref()makes the code more idiomatic and easier to understand, while maintaining the same functionality.
309-310: Test data properly updated with new submitter fieldThe test JSON data has been correctly updated to include the new
submitterfield, ensuring the test validates the updated schema.execution/crates/registrar/src/lib.rs (4)
33-33: Function signature correctly updated with submitter parameterThe
register_ipfunction has been properly extended to accept the newsubmitterparameter, aligning with the contract requirements.
91-91: Updated contract call includes the submitter parameterThe call to
registeron the contract correctly passes the new requiredsubmitterparameter.
122-131: Consistent error handling pattern appliedGood to see the same error handling pattern applied to the RPC URL parsing in
get_transaction_datafunction.
200-200:❓ Verification inconclusive
Test correctly provides submitter parameter
The test now correctly passes the address as the submitter parameter.
Is using the same address for both the IP owner and submitter the expected pattern? Let's check if this is addressed in the contract:
🏁 Script executed:
#!/bin/bash # Check if contract has validation for different owner/submitter addresses # Look for validation in the ForgeRegistry contract ast-grep --pattern $'function register($_, $_, $_, address submitter) { $$$ require($_, $_); $$$ }'Length of output: 106
Please verify if using the same address for both the IP owner and submitter is intentional
The test now correctly passes the submitter parameter, as the code at line 200 in
execution/crates/registrar/src/lib.rsshows that the address is passed as the submitter. However, our verification via theast-grepquery against the ForgeRegistry contract did not yield any validations that enforce a difference between the IP owner and the submitter address.
- Verify manually if the design requires distinct addresses for these roles.
- If using the same address is intended behaviour, no further action is needed; otherwise, consider adding the necessary validation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
♻️ Duplicate comments (1)
execution/contracts/src/ForgeRegistry.sol (1)
45-50: 🛠️ Refactor suggestionImplement configurable licensing terms based on past feedback.
The current
Termsstruct is marked with a TODO comment, but previous review comments already suggested making license terms configurable.Consider implementing the suggestion from past reviews to make license terms configurable based on the IP metadata or explicit parameters rather than using hardcoded values. This would enable flexibility in licensing schemes.
🧹 Nitpick comments (4)
execution/contracts/src/ForgeRegistry.sol (4)
26-26: Consider making UNLOCK_BLOCK_TIME configurable.The current hardcoded value of 3600 seconds (1 hour) for the unlock period may not be suitable for all environments (testing, production) or may need to be adjusted in the future.
Consider making this configurable via constructor/initializer or adding an admin function to update it:
- uint256 public constant UNLOCK_BLOCK_TIME = 3600 seconds; + uint256 public UNLOCK_BLOCK_TIME = 3600 seconds;And add a setter function with access control:
function setUnlockBlockTime(uint256 _unlockBlockTime) external onlyOwner { UNLOCK_BLOCK_TIME = _unlockBlockTime; emit UnlockBlockTimeUpdated(_unlockBlockTime); }
34-34: Document the purpose of WIP address constant.The hardcoded WIP address (0x1514000000000000000000000000000000000000) lacks context or documentation. This makes it difficult to understand its purpose or verify its correctness.
Add a comment explaining what this address represents:
- address internal WIP = 0x1514000000000000000000000000000000000000; + // Address of the Work Intellectual Property token contract used for licensing + address internal WIP = 0x1514000000000000000000000000000000000000;
81-86: Consider more descriptive modifier name for better code readability.The
onlyBatchermodifier accurately restricts function access to the batcher wallet, but the name doesn't clearly convey the purpose of this role in the system.Consider renaming to something more descriptive of the role's purpose:
- modifier onlyBatcher() { + modifier onlyAuthorizedBatcher() { if (msg.sender != batcherWallet) { revert OnlyBatcherAllowed(msg.sender); } _; }
138-177: Maintain DRY principle by extracting validation logic.The
reinitializefunction duplicates the validation logic frominitialize, which violates the DRY (Don't Repeat Yourself) principle.Extract the validation logic to a private function:
+ function _validateAddresses( + address ipAssetRegistryAddress, + address registrationWorkflowsAddress, + address piLicenseTemplateAddress, + address royaltyPolicyLAPAddress, + address licensingModuleAddress, + address _batcherWallet + ) private pure { + if (ipAssetRegistryAddress == address(0)) { + revert InvalidAddress("ipAssetRegistryAddress"); + } + if (registrationWorkflowsAddress == address(0)) { + revert InvalidAddress("registrationWorkflowsAddress"); + } + if (piLicenseTemplateAddress == address(0)) { + revert InvalidAddress("piLicenseTemplateAddress"); + } + if (royaltyPolicyLAPAddress == address(0)) { + revert InvalidAddress("royaltyPolicyLAPAddress"); + } + if (licensingModuleAddress == address(0)) { + revert InvalidAddress("licensingModuleAddress"); + } + if (_batcherWallet == address(0)) { + revert InvalidAddress("batcherWallet"); + } + }Then use this function in both
initializeandreinitialize.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
execution/contracts/broadcast/ForgeRegistry.s.sol/1315/run-latest.json(3 hunks)execution/contracts/src/ForgeRegistry.sol(4 hunks)execution/crates/registrar/src/lib.rs(8 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- execution/crates/registrar/src/lib.rs
🔇 Additional comments (14)
execution/contracts/src/ForgeRegistry.sol (10)
7-15: Good security enhancement with reentrancy protection and licensing infrastructure.The addition of ReentrancyGuardUpgradeable and the new licensing-related imports establishes a solid foundation for secure payment processing and intellectual property management. This aligns well with the PR's objective of implementing a payment system.
18-24: Strong inheritance structure provides comprehensive security features.The contract now inherits from multiple security-focused contracts, including ReentrancyGuardUpgradeable and ForgeStorage, which gives you separation of concerns while adding protection against common attack vectors.
67-78: Excellent use of custom errors for gas efficiency and clarity.Using custom errors instead of require statements with string messages is a gas-efficient approach that also provides more meaningful error information for better debugging.
93-136: Well-implemented initialization with comprehensive parameter validation.The
initializefunction properly validates all input addresses to ensure they're not zero addresses, which is crucial for contract security. The initialization of critical components is thorough and follows best practices for upgradeable contracts.
224-244: Properly validate inputs in register function.The validation checks for receiver address, name, and submitter address help ensure data integrity and prevent errors.
271-291: Refund mechanism properly calculates gas and includes safety checks.The gas refund calculation includes a 10% premium and verifies both contract and user balances before proceeding, which addresses previous review comments about insufficient balance checks.
300-301: Good job implementing the balance verification before transfer.The implementation now checks both the user's balance and the contract's balance before attempting the transfer, protecting against unexpected reverts.
303-308: Receive function implementation properly handles deposits.The
receivefunction correctly updates the user's balance and resets the unlock time when they send ETH to the contract. The nonReentrant modifier adds protection against reentrancy attacks.
310-359: Well-designed fund management system with unlock/lock mechanisms.The implementation of unlock/lock/withdraw functions creates a secure system for users to manage their funds with appropriate time-based restrictions. This helps prevent immediate withdrawals that could impact system stability.
260-269:❓ Verification inconclusive
Uncomment and implement licensing functionality.
The licensing code is commented out, which means this important functionality is not currently active.
Is this licensing functionality intentionally disabled or is it a work-in-progress feature? If it's meant to be included, uncomment and test this code. If it's planned for a future phase, consider removing the commented code and tracking it in an issue instead.
🏁 Script executed:
#!/bin/bash # Find other references to licensing in the codebase rg "PILTerms|PIL_TEMPLATE|LICENSING_MODULE" -A 5 -B 5Length of output: 74672
Licensing Functionality: Action Required
The code for licence terms registration remains commented out in ForgeRegistry.sol, even though related variables (such as PIL_TEMPLATE and LICENSING_MODULE) are set up elsewhere (e.g. in deployment and upgrade scripts). Could you please confirm whether this licensing feature should currently be enabled?
- If the functionality is intended for immediate use, please uncomment the code and perform thorough testing.
- If it is planned for a future phase, consider removing the commented code and tracking the implementation in a dedicated issue.
execution/contracts/broadcast/ForgeRegistry.s.sol/1315/run-latest.json (4)
4-8: Deployment configuration updated for new contract implementation.The transaction hash and contract address have been updated to reflect the new deployment with the payment processing functionality.
12-14: Gas limit increase aligns with additional contract functionality.The gas limit increase from 0x1a342d to 0x2a4306 is appropriate given the additional functionality in the contract, including payment processing and the reentrancy guard.
28-29: Verify all parameters in upgrade transaction.The upgrade transaction includes seven address parameters for the ForgeRegistry contract which should be confirmed as correct for your environment.
Please ensure all addresses in the upgrade parameters are pointing to the correct contracts in your environment, particularly checking that:
- PILicenseTemplate
- RoyaltyPolicyLAP
- LicensingModule
are valid and operational.
92-120: New event logs demonstrate successful initialization.The additional logs in the transaction receipt indicate the contract was successfully initialized with the ownership transfer and version update, which is good evidence that the deployment worked properly.
this is the initial version of our payment system designed to add cost coverage of transactions to the api
Summary by CodeRabbit
New Features
Dependency Updates
Upgrade & Deployment
Tests
Chores