-
Notifications
You must be signed in to change notification settings - Fork 4
Feature: oft adapter step1 - basic upgradeable adapter/minterburner #9
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
base: master
Are you sure you want to change the base?
Conversation
…gic and update dependencies
…ipient configuration
…contracts by removing bridge limits and minting logic, enhancing clarity and maintainability
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.
Hey - I've found 3 issues, and left some high level feedback:
- In
GoodDollarOFTAdapter._credittherequestIdis derived fromkeccak256(..., block.timestamp), which makes it impossible to know and pre-approve viaapproveRequestbefore the message is processed; consider passing a deterministic ID from the source chain or otherwise reworking the approval flow soapprovedRequestsis actually usable. BridgeFees.minFeeandBridgeFees.maxFeeare stored but never used in_takeFeeor elsewhere, so the effective fee logic only depends onfeebps; either wire in min/max bounds enforcement or remove these fields to avoid confusion.- In
GoodDollarMinterBurner, theinitializesignature usesINameServicebut that interface is not defined/imported in this file (while an unusedIIdentityinterface is declared), which will prevent compilation; align the imported/declared interfaces with the types actually used.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- In `GoodDollarOFTAdapter._credit` the `requestId` is derived from `keccak256(..., block.timestamp)`, which makes it impossible to know and pre-approve via `approveRequest` before the message is processed; consider passing a deterministic ID from the source chain or otherwise reworking the approval flow so `approvedRequests` is actually usable.
- `BridgeFees.minFee` and `BridgeFees.maxFee` are stored but never used in `_takeFee` or elsewhere, so the effective fee logic only depends on `fee` bps; either wire in min/max bounds enforcement or remove these fields to avoid confusion.
- In `GoodDollarMinterBurner`, the `initialize` signature uses `INameService` but that interface is not defined/imported in this file (while an unused `IIdentity` interface is declared), which will prevent compilation; align the imported/declared interfaces with the types actually used.
## Individual Comments
### Comment 1
<location> `packages/bridge-contracts/contracts/oft/GoodDollarOFTAdapter.sol:132` </location>
<code_context>
+ function initialize(
+ address _token,
+ IMintableBurnable _minterBurner,
+ address _lzEndpoint,
+ address _owner,
+ address _feeRecipient,
</code_context>
<issue_to_address>
**issue:** The `_lzEndpoint` initializer parameter is unused and may mislead callers about configurability.
In `initialize`, `_lzEndpoint` is accepted but never used. Since the endpoint is already set via `OFTCoreUpgradeable`’s constructor, this parameter has no effect yet suggests per-proxy configurability. Either pass `_lzEndpoint` through to the appropriate parent initializer (if available) or remove it to prevent confusion and misconfiguration.
</issue_to_address>
### Comment 2
<location> `packages/bridge-contracts/contracts/oft/GoodDollarOFTAdapter.sol:348-353` </location>
<code_context>
+
+ // Generate a request ID from the message (using source chain ID and amount as a simple hash)
+ // In a real implementation, you might want to pass this from the LayerZero message
+ uint256 requestId = uint256(keccak256(abi.encode(_srcEid, _to, _amountLD, block.timestamp)));
+
+ // Enforce limits before processing
+ // Note: We track limits by recipient address (_to) since OFT doesn't provide original sender in _credit
+ // For approved requests, call approveRequest() with the requestId before the transfer
+ _enforceLimits(_to, _to, _amountLD, requestId);
+
+ // Calculate fee if fee recipient is set and fee is configured
</code_context>
<issue_to_address>
**issue (bug_risk):** The approval mechanism using `requestId` derived from `block.timestamp` is not practically usable for pre-approvals.
In `_credit`, `requestId` is computed from `_srcEid`, `_to`, `_amountLD`, and `block.timestamp`, while `_enforceLimits` assumes callers can pre-approve via `approveRequest(requestId)`. Since `block.timestamp` is only known at execution, off-chain systems can’t precompute this ID and pre-approval is impractical even on-chain. This makes the `approvedRequests` bypass effectively non-functional. Consider: (a) passing a deterministic request ID from the LayerZero payload, (b) using an explicit override flag controlled by a privileged role on the destination, or (c) removing this approval path to avoid a misleading control surface.
</issue_to_address>
### Comment 3
<location> `packages/bridge-contracts/contracts/oft/GoodDollarOFTAdapter.sol:362-363` </location>
<code_context>
+ }
+
+ // Mint tokens to recipient (amount minus fee)
+ uint256 amountToRecipient = _amountLD - fee;
+ minterBurner.mint(_to, amountToRecipient);
+
+ // Mint fee to fee recipient if fee exists
</code_context>
<issue_to_address>
**issue (bug_risk):** The return value of `minterBurner.mint` is ignored, which can hide mint failures while the bridge flow continues.
In `_credit`, the `bool` returned by `minterBurner.mint(_to, amountToRecipient)` is ignored. If `mint` fails and returns `false`, the bridge will still report success and return `amountToRecipient`, desynchronizing accounting from the actual token supply. This should either revert on failure in `GoodDollarMinterBurner.mint` or explicitly check the return value here and revert with a clear error if it is `false`.
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
packages/bridge-contracts/contracts/oft/GoodDollarOFTAdapter.sol
Outdated
Show resolved
Hide resolved
packages/bridge-contracts/contracts/oft/GoodDollarOFTAdapter.sol
Outdated
Show resolved
Hide resolved
packages/bridge-contracts/contracts/oft/GoodDollarOFTAdapter.sol
Outdated
Show resolved
Hide resolved
Feature: oft adapter step1 - basic upgradeable adapter/minterburner
🚨 Report Summary
For more details view the full report in OpenZeppelin Code Inspector |
…ts, and related logic to enhance clarity and reduce complexity
…cluding Hardhat version upgrades and new remapping file
| * @param _nameService The NameService contract for DAO integration | ||
| */ | ||
| function initialize( | ||
| ISuperGoodDollar _token, |
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.
no need daocontract has nativeToken() method to get the address of the G$ token
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.
Yes I will use nativeToken method
| "@safe-global/safe-core-sdk-types": "^2.3.0", | ||
| "@superfluid-finance/ethereum-contracts": "1.8.1", |
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.
these should not be requried
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.
Yes I will remove them
| "@layerzerolabs/lz-definitions": "^3.0.151", | ||
| "@layerzerolabs/lz-evm-protocol-v2": "^3.0.151", | ||
| "@layerzerolabs/oapp-evm": "^0.4.1", | ||
| "@layerzerolabs/oapp-evm-upgradeable": "^0.1.3", | ||
| "@layerzerolabs/oft-evm": "^4.0.0", | ||
| "@layerzerolabs/oft-evm-upgradeable": "^4.0.2", |
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.
are all these required?
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.
they are all required
| import '@nomicfoundation/hardhat-verify'; | ||
| import '@nomiclabs/hardhat-waffle'; | ||
| import 'hardhat-deploy'; | ||
| // Temporarily disabled due to incompatibility with Hardhat 2.x |
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.
shouldnt be disabled or undo the package upgrade you did
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.
I will uncomment/make it work
…d enhance GoodDollarMinterBurner and GoodDollarOFTAdapter contracts with storage gap for future upgrades
Description
This is the PR for OFT step1 - Write upgradeable GoodDollarMinterBurner and GoodDollarOFTAdapter contracts with basic functionalities
About #7
How Has This Been Tested?
Please describe the tests that you ran to verify your changes.
Checklist: