-
Notifications
You must be signed in to change notification settings - Fork 16
Make Stablecoin and Reservecoin names configurable at deployment, not hardcoded. #44
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: main
Are you sure you want to change the base?
Make Stablecoin and Reservecoin names configurable at deployment, not hardcoded. #44
Conversation
WalkthroughThe constructor of the Djed contract was refactored to accept parameters grouped in a ConstructorParams struct instead of individual arguments. Additionally, hardcoded stablecoin and reservecoin names and symbols are now configurable via the new struct fields. Changes
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes
Poem
Pre-merge checks and finishing touches✅ Passed checks (5 passed)
✨ Finishing touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
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: 3
🧹 Nitpick comments (1)
src/Djed.sol (1)
10-13: Consider makingstableCoin/reserveCoinimmutable(optional gas/clarity win).
They’re assigned once in the constructor and never reassigned.Also applies to: 59-61
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
COPYRIGHT.md(1 hunks)src/Djed.sol(1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: negimox
Repo: DjedAlliance/Djed-Solidity PR: 41
File: src/DjedTefnut.sol:214-217
Timestamp: 2025-12-13T17:46:15.360Z
Learning: In Djed protocol implementations (e.g., DjedTefnut.sol), push payments are used intentionally to maintain consistency with the original Djed protocol architecture, rather than pull payment patterns.
🔇 Additional comments (1)
src/Djed.sol (1)
60-63: No action needed:Coin.decimals()is fixed at 6.The
Coincontract hardcodesdecimals()to return6, so10**stableCoin.decimals()and10**reserveCoin.decimals()are always10**6 = 1,000,000, with no overflow risk. The concern about unbounded decimals does not apply here.
| Copyright © 2025 The Stable Order <br /> | ||
| All rights reserved. | ||
|
|
||
| All works in this repository may be used according to the conditions | ||
| stated in the LICENSE.md file available in this repository. | ||
|
|
||
| These works are WITHOUT ANY WARRANTY, without even the implied warranty of | ||
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
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.
Confirm copyright holder name + avoid HTML in markdown.
If “The Stable Order” isn’t the intended owner for this repo, this file will create legal/branding confusion; also <br /> is unnecessary in .md.
-Copyright © 2025 The Stable Order <br />
+Copyright © 2025 The Stable Order
All rights reserved.(If the holder should be “DjedAlliance”, “IOHK”, “Contributors”, etc., please update accordingly.)
🤖 Prompt for AI Agents
In COPYRIGHT.md around lines 1 to 8, the file uses an HTML <br /> tag and a
possibly incorrect copyright holder name (“The Stable Order”); remove the HTML
tag and replace it with plain Markdown/newline formatting, and confirm and
update the copyright holder to the correct entity (e.g., “DjedAlliance”, “IOHK”,
“Contributors”, or the proper legal owner) so the file reflects the intended
owner; keep the copyright year(s) as-is or update if required and preserve the
warranty disclaimers in plain-text Markdown.
| struct ConstructorParams { | ||
| address oracleAddress; | ||
| uint256 scalingFactor; | ||
| address treasury; | ||
| uint256 initialTreasuryFee; | ||
| uint256 treasuryRevenueTarget; | ||
| uint256 reserveRatioMin; | ||
| uint256 reserveRatioMax; | ||
| uint256 fee; | ||
| uint256 thresholdSupplySC; | ||
| uint256 rcMinPrice; | ||
| uint256 rcInitialPrice; | ||
| uint256 txLimit; | ||
| string stableCoinName; | ||
| string stableCoinSymbol; | ||
| string reserveCoinName; | ||
| string reserveCoinSymbol; | ||
| } |
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.
🧩 Analysis chain
🏁 Script executed:
# First, let's look at the full context of the Djed contract, especially the constructor
head -100 src/Djed.sol | tail -70Repository: DjedAlliance/Djed-Solidity
Length of output: 3005
🏁 Script executed:
# Search for Djed constructor instantiations in Solidity files
rg -n --type solidity -A5 'new\s+Djed\s*\('Repository: DjedAlliance/Djed-Solidity
Length of output: 102
🏁 Script executed:
# Search for deployments in TypeScript/JavaScript files
rg -n --type ts --type js -A5 'Djed|deploy' | head -200Repository: DjedAlliance/Djed-Solidity
Length of output: 218
🏁 Script executed:
# Check the lines 59-80 referenced in the review
sed -n '59,80p' src/Djed.solRepository: DjedAlliance/Djed-Solidity
Length of output: 1008
🏁 Script executed:
# Find all files in the repo to understand structure
find . -type f -name "*.sol" -o -name "*.ts" -o -name "*.js" | grep -E "(test|deploy|spec)" | head -30Repository: DjedAlliance/Djed-Solidity
Length of output: 495
🏁 Script executed:
# Search for any Djed instantiation in .sol files
rg -n "new Djed" --glob "*.sol"Repository: DjedAlliance/Djed-Solidity
Length of output: 492
🏁 Script executed:
# Search for Djed in test/deployment context (TypeScript/JavaScript)
rg -n "Djed" --glob "*.ts" --glob "*.js" -A 3 | head -100Repository: DjedAlliance/Djed-Solidity
Length of output: 218
🏁 Script executed:
# Check if there are any comments or documentation about constructor changes
rg -n "constructor|ConstructorParams" --glob "*.sol" -B2 -A2Repository: DjedAlliance/Djed-Solidity
Length of output: 4358
🏁 Script executed:
# Check the exact constructor calls in test files
sed -n '18,30p' src/test/Djed.t.solRepository: DjedAlliance/Djed-Solidity
Length of output: 495
🏁 Script executed:
# Check Fee test
sed -n '25,40p' src/test/Fee.t.solRepository: DjedAlliance/Djed-Solidity
Length of output: 590
🏁 Script executed:
# Check TransactionLimit test
sed -n '21,35p' src/test/TransactionLimit.t.solRepository: DjedAlliance/Djed-Solidity
Length of output: 548
🏁 Script executed:
# Check deployment script
sed -n '29,50p' scripts/deployDjedContract.s.solRepository: DjedAlliance/Djed-Solidity
Length of output: 659
🏁 Script executed:
# Compare with DjedShu constructor which uses individual params
sed -n '40,60p' src/DjedShu.solRepository: DjedAlliance/Djed-Solidity
Length of output: 1011
Update all Djed constructor calls to use struct parameter format.
The constructor was changed to accept ConstructorParams memory params instead of individual parameters. All instantiations must be updated to pass a struct:
Currently broken in:
src/test/Djed.t.sol:18-30src/test/Fee.t.sol:25-37src/test/TransactionLimit.t.sol:21-34scripts/deployDjedContract.s.sol:29-41
Each call passes positional arguments but must instead create a struct instance. Example fix:
Djed.ConstructorParams({
oracleAddress: address(oracle),
scalingFactor: SCALING_FACTOR,
treasury: TREASURY,
// ... other fields
})🤖 Prompt for AI Agents
In src/Djed.sol around lines 34 to 51 the constructor signature was changed to
accept a single ConstructorParams memory params struct, but tests and deploy
scripts still call the constructor with positional arguments; update all
instantiations in src/test/Djed.t.sol (lines ~18-30), src/test/Fee.t.sol
(25-37), src/test/TransactionLimit.t.sol (21-34) and
scripts/deployDjedContract.s.sol (29-41) to pass a Djed.ConstructorParams struct
literal instead of positional parameters (e.g. Djed.ConstructorParams({
oracleAddress: address(oracle), scalingFactor: SCALING_FACTOR, treasury:
TREASURY, initialTreasuryFee: ..., treasuryRevenueTarget: ..., reserveRatioMin:
..., reserveRatioMax: ..., fee: ..., thresholdSupplySC: ..., rcMinPrice: ...,
rcInitialPrice: ..., txLimit: ..., stableCoinName: "...", stableCoinSymbol:
"...", reserveCoinName: "...", reserveCoinSymbol: "..." })), ensure all fields
are provided with the correct names and types and update imports/qualified name
if needed so the contract compiles.
| constructor(ConstructorParams memory params) payable { | ||
| stableCoin = new Coin(params.stableCoinName, params.stableCoinSymbol); | ||
| reserveCoin = new Coin(params.reserveCoinName, params.reserveCoinSymbol); | ||
| scDecimalScalingFactor = 10**stableCoin.decimals(); | ||
| rcDecimalScalingFactor = 10**reserveCoin.decimals(); | ||
| scalingFactor = _scalingFactor; | ||
| scalingFactor = params.scalingFactor; | ||
|
|
||
| treasury = _treasury; | ||
| initialTreasuryFee = _initialTreasuryFee; | ||
| treasuryRevenueTarget = _treasuryRevenueTarget; | ||
| treasury = params.treasury; | ||
| initialTreasuryFee = params.initialTreasuryFee; | ||
| treasuryRevenueTarget = params.treasuryRevenueTarget; | ||
|
|
||
| reserveRatioMin = _reserveRatioMin; | ||
| reserveRatioMax = _reserveRatioMax; | ||
| fee = _fee; | ||
| thresholdSupplySC = _thresholdSupplySC; | ||
| rcMinPrice = _rcMinPrice; | ||
| rcInitialPrice = _rcInitialPrice; | ||
| txLimit = _txLimit; | ||
| reserveRatioMin = params.reserveRatioMin; | ||
| reserveRatioMax = params.reserveRatioMax; | ||
| fee = params.fee; | ||
| thresholdSupplySC = params.thresholdSupplySC; | ||
| rcMinPrice = params.rcMinPrice; | ||
| rcInitialPrice = params.rcInitialPrice; | ||
| txLimit = params.txLimit; | ||
|
|
||
| oracle = IOracle(oracleAddress); | ||
| oracle = IOracle(params.oracleAddress); | ||
| oracle.acceptTermsOfService(); | ||
| } |
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.
Add constructor parameter validation (prevents div-by-zero + bad deployments).
Right now any of these can silently deploy a broken instance (e.g., treasuryRevenueTarget == 0 makes treasuryFee() divide-by-zero; scalingFactor == 0 breaks fee math; zero addresses burn funds / break oracle).
constructor(ConstructorParams memory params) payable {
+ require(params.oracleAddress != address(0), "ctor: oracle=0");
+ require(params.treasury != address(0), "ctor: treasury=0");
+ require(params.scalingFactor > 0, "ctor: scalingFactor=0");
+ require(params.treasuryRevenueTarget > 0, "ctor: revenueTarget=0");
+ require(params.reserveRatioMin <= params.reserveRatioMax, "ctor: rrMin>rrMax");
+ require(params.txLimit > 0, "ctor: txLimit=0");
+ require(bytes(params.stableCoinName).length != 0, "ctor: scName empty");
+ require(bytes(params.stableCoinSymbol).length != 0, "ctor: scSymbol empty");
+ require(bytes(params.reserveCoinName).length != 0, "ctor: rcName empty");
+ require(bytes(params.reserveCoinSymbol).length != 0, "ctor: rcSymbol empty");
+ require(params.rcMinPrice > 0, "ctor: rcMinPrice=0");
+ require(params.rcInitialPrice > 0, "ctor: rcInitialPrice=0");
+ require(params.rcMinPrice <= params.rcInitialPrice, "ctor: rcMin>rcInit");
stableCoin = new Coin(params.stableCoinName, params.stableCoinSymbol);
reserveCoin = new Coin(params.reserveCoinName, params.reserveCoinSymbol);
scDecimalScalingFactor = 10**stableCoin.decimals();
rcDecimalScalingFactor = 10**reserveCoin.decimals();
scalingFactor = params.scalingFactor;
...
}🤖 Prompt for AI Agents
In src/Djed.sol around lines 59 to 80, add input validation in the constructor
to prevent bad deployments and divide-by-zero: require non-zero addresses for
treasury and oracle (check oracleAddress != address(0) before assigning and
calling acceptTermsOfService), require numeric parameters used as divisors or
scaling factors to be > 0 (treasuryRevenueTarget > 0, scalingFactor > 0,
scDecimalScalingFactor and rcDecimalScalingFactor should be checked or derive
safely), require sensible positive bounds for prices and limits (rcMinPrice > 0,
rcInitialPrice > 0, txLimit > 0), enforce reserveRatioMin/Max consistency (0 <
reserveRatioMin <= reserveRatioMax and reserveRatioMax within expected max), and
validate fee/initialTreasuryFee are within expected ranges; use require(...)
with clear error messages before any state changes or external calls so the
contract cannot deploy with invalid params.
fix #43
Summary
This PR removes hardcoded token names from the Djed contract and makes both the Stablecoin and Reservecoin names and symbols configurable at deployment time.
What changed
Added support for passing Stablecoin and Reservecoin names and symbols via the constructor.
Refactored the constructor to use a parameter struct to avoid Solidity’s stack too deep limitation.
Instantiated Coin contracts using the provided constructor parameters instead of fixed strings
Why this is needed
Hardcoding token names limits the reusability of the Djed contract and makes it difficult for projects to deploy customized instances. This change allows:
Summary by CodeRabbit
Documentation
Refactor
✏️ Tip: You can customize this high-level summary in your review settings.