Skip to content

Upgrade Djed SDK to Support Advanced Protocol Features and Djed Shu#81

Open
DeveloperAmrit wants to merge 6 commits intoDjedAlliance:mainfrom
DeveloperAmrit:fix-80-new-djed
Open

Upgrade Djed SDK to Support Advanced Protocol Features and Djed Shu#81
DeveloperAmrit wants to merge 6 commits intoDjedAlliance:mainfrom
DeveloperAmrit:fix-80-new-djed

Conversation

@DeveloperAmrit
Copy link
Contributor

@DeveloperAmrit DeveloperAmrit commented Feb 1, 2026

Fixes #80 and #65

Description

This PR significantly upgrades the djed-sdk to align with the latest Djed-Solidity smart contracts. It introduces support for the safety-enhanced Djed Shu version, implements missing core protocol functions like sellBothCoins, and establishes a robust infrastructure for real-time event monitoring.

Key Changes

  1. Djed Shu Compatibility (Price-Band Support)
  • Dynamic Price Method Selection: Implemented getPriceMethod in tradeUtils.js. The SDK now automatically switches between scPrice, scMaxPrice, and scMinPrice based on whether the contract is Djed Shu and what operation (Buy/Sell) is being performed.
  • Version Detection: Added checkIfShu utility to automatically detect the contract version by probing for Shu-specific getters.
  • Ratio Ranges: Updated getCoinDetails to support the dual-ratio system (ratioMin and ratioMax) found in Shu deployments.
  1. New Protocol Functionality: sellBothCoins
  • Atomic Exits: Added sellBothTx and tradeDataPriceSellBoth in a new sellBoth.js module. Users can now exit both StableCoin and ReserveCoin positions in a single atomic transaction.
  1. Improved Parameter Visibility
  • Missing Parameters: Updated getSystemParams to fetch critical protocol values previously missing from the SDK:
    • Treasury details: initialTreasuryFee, treasuryRevenueTarget, treasuryRevenue.
    • Price floor/initials: rcMinPrice, rcInitialPrice.
  • Dynamic Transaction Limits: Refactored isTxLimitReached to use the contract-enforced txLimit instead of a hardcoded constant.
  1. Event Listening Infrastructure
  • Real-time Updates: Introduced listeners.js, providing subscribeToDjedEvents. This allows the UI to react instantly to BoughtStableCoins, SoldBothCoins, etc., without page refreshes.
  • Historical Data: Added getPastDjedEvents for fetching transaction history directly from the blockchain.
  1. ABI Updates
  • Consolidated the DjedABI.json to include all standard and Shu-specific methods, ensuring the SDK can interact with any version of the Djed protocol deployed on-chain.

How to verify

  1. Djed Shu Test: Connect to a Djed Shu contract; verify that getCoinDetails returns the ratio range, and that tradeDataPriceBuySc correctly calls scMaxPrice.
  2. Sell Both Test: Call tradeDataPriceSellBoth with valid amounts; verify it returns the combined BaseCoin (BC) value after fees
  3. Event Test: Use subscribeToDjedEvents and perform a trade; verify the callback receives the expected returnValues.

Summary by CodeRabbit

  • New Features

    • Sell both stable+reserve coins in one transaction (preview + tx builder).
    • Real-time contract event subscriptions and historical event retrieval.
    • Additional transaction builders for alternate contract variants and ERC20 base-asset flows.
    • New oracle connectors for multiple oracle types.
  • Enhancements

    • Dynamic pricing that adapts to newer contract variants (auto-selects appropriate price method).
    • Expanded system parameters exposed (reserve ratio min/max, treasury metrics, tx limits).
    • ERC20 approve/check-allowance helpers and base-asset allowance/approval support.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link

coderabbitai bot commented Feb 1, 2026

📝 Walkthrough

Walkthrough

Adds Isis/Tefnut (Shu) variant support: new ABIs and oracle artifacts, runtime variant detection, dynamic price-method selection, new ERC20-style transaction helpers, sell‑both flow, event listeners, and expanded system/coin parameter outputs.

Changes

Cohort / File(s) Summary
ABI additions
djed-sdk/src/artifacts/DjedABI.json
Appended ABI entries: scMaxPrice, scMinPrice, ratioMax, ratioMin, updateOracleValues.
New Djed variant ABIs
djed-sdk/src/artifacts/DjedIsisABI.json, djed-sdk/src/artifacts/DjedTefnutABI.json
Added full ABI artifacts for Isis and Tefnut Djed variants (large JSON artifacts).
Oracle artifacts
djed-sdk/src/artifacts/API3OracleABI.json, djed-sdk/src/artifacts/ChainlinkOracleABI.json, djed-sdk/src/artifacts/HebeSwapOracleABI.json
Added ABI artifacts for API3, Chainlink, and HebeSwap oracles.
Djed core & exports
djed-sdk/src/djed/djed.js, djed-sdk/src/djed/index.js
Added getDjedIsisContract, getDjedTefnutContract, and checkIfShu (runtime probe via scMaxPrice(0)) and re-exported new helpers/listeners.
Oracle getters
djed-sdk/src/oracle/oracle.js, djed-sdk/src/oracle/index.js
Added getHebeSwapOracleContract, getChainlinkOracleContract, getAPI3OracleContract and corresponding exports.
Event subscriptions & history
djed-sdk/src/djed/listeners.js
New module: subscribeToDjedEvents(djedContract, callbacks) (returns unsubscribe) and getPastDjedEvents(...) for historical queries.
Sell‑both flow
djed-sdk/src/djed/sellBoth.js
New module: tradeDataPriceSellBoth(...) computes combined sell pricing/fees; sellBothTx(...) builds sellBothCoins tx.
ISIS/Tefnut tx helpers
djed-sdk/src/djed/isis.js
New ERC20-style tx builders: buyScIsisTx, sellScIsisTx, buyRcIsisTx, sellRcIsisTx, sellBothIsisTx.
Price resolution & utils
djed-sdk/src/djed/tradeUtils.js, djed-sdk/src/djed/reserveCoin.js, djed-sdk/src/djed/stableCoin.js
Added getPriceMethod(djed, operation) that probes contract version and returns proper price method; isTxLimitReached gains txLimit param; price-call usage updated.
System & coin details
djed-sdk/src/djed/system.js
Integrated checkIfShu, switched to dynamic priceMethod; getCoinDetails now includes isShu, percentReserveRatioMin, percentReserveRatioMax; getSystemParams exposes additional treasury/tx parameters.
Token helpers
djed-sdk/src/djed/token.js
Added approveTx(tokenContract, owner, spender, amount) and checkAllowance(tokenContract, owner, spender).
StablePay integration
stablepay-sdk/src/core/Transaction.js
Constructor accepts optional baseAssetAddress; adds base-asset approval/allowance helpers and switches buy flow to ERC20 path when provided.
Build script
djed-sdk/package.json
Added build script: rollup -c.

Sequence Diagram(s)

sequenceDiagram
    participant Client as SDK Consumer
    participant SDK as Djed SDK
    participant Contract as Djed Contract
    participant Oracle as Oracle Contract

    Client->>SDK: getCoinDetails(djed)
    SDK->>Contract: scMaxPrice(0) (probe via checkIfShu)
    alt probe succeeds (Shu variant)
        SDK->>Contract: ratioMin(), ratioMax()
        Contract-->>SDK: ratios
        SDK->>Contract: scMaxPrice / scMinPrice (per operation via getPriceMethod)
        Contract-->>SDK: prices
        SDK->>Oracle: readData / scalingFactor
        Oracle-->>SDK: oracle price
        SDK-->>Client: coinDetails (isShu=true, min/max ratios, prices)
    else probe fails (non‑Shu)
        SDK->>Contract: scPrice(), ratio()
        Contract-->>SDK: price, ratio
        SDK-->>Client: coinDetails (isShu=false, price, ratio)
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested reviewers

  • Zahnentferner

Poem

🐰 I sniffed the ABI, a joyful hop and cheer,

scMax and scMin have now appeared here.
New oracles hum, events whisper and speak,
Sell‑both bundled tidy — I nibble a leek! 🥕

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title directly and clearly summarizes the main change: upgrading the Djed SDK with support for advanced protocol features and the Djed Shu variant, which aligns with the comprehensive changeset.
Linked Issues check ✅ Passed The PR fulfills all key coding objectives from issue #80: adds DjedIsisABI.json and DjedTefnutABI.json, implements contract accessors (getDjedIsisContract, getDjedTefnutContract), adds oracle support (HebeSwapOracleABI.json, ChainlinkOracleABI.json, API3OracleABI.json with contract getters), and clearly exports new helpers via index.js and listeners.js for StablePay consumption.
Out of Scope Changes check ✅ Passed All changes are in scope: ABI/artifact additions, core SDK module enhancements for Shu/Isis/Tefnut support, oracle integrations, event listeners, token helpers, and stablepay-sdk Transaction.js updates align with the Djed protocol upgrade objectives; no unrelated refactoring or feature drift detected.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a 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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
djed-sdk/src/djed/reserveCoin.js (2)

20-28: ⚠️ Potential issue | 🟠 Major

Unused scMethod variable - incomplete Shu integration.

getPriceMethod(djed, 'buyRC') is called and its result stored in scMethod, but this variable is never used. The tradeDataPriceCore call still uses the hardcoded "rcBuyingPrice" string. This wastes an RPC call and doesn't achieve the intended Shu-aware pricing.

Compare with stableCoin.js where the dynamic method is correctly passed to tradeDataPriceCore. Either remove the unused call or integrate it into the pricing logic.

Proposed fix (if scMethod should be used)
 export const tradeDataPriceBuyRc = async (djed, rcDecimals, amountScaled) => {
   try {
-    const scMethod = await getPriceMethod(djed, 'buyRC');
     const data = await tradeDataPriceCore(
       djed,
       "rcBuyingPrice",
       rcDecimals,
       amountScaled
     );

Or, if the method should influence RC pricing:

 export const tradeDataPriceBuyRc = async (djed, rcDecimals, amountScaled) => {
   try {
-    const scMethod = await getPriceMethod(djed, 'buyRC');
+    // Note: RC uses rcBuyingPrice, not SC price methods
     const data = await tradeDataPriceCore(
       djed,
       "rcBuyingPrice",
       rcDecimals,
       amountScaled
     );

47-55: ⚠️ Potential issue | 🟠 Major

Same issue: unused scMethod in tradeDataPriceSellRc.

Identical problem as above - scMethod is computed but not used, while "rcTargetPrice" is hardcoded.

Proposed fix
 export const tradeDataPriceSellRc = async (djed, rcDecimals, amountScaled) => {
   try {
-    const scMethod = await getPriceMethod(djed, 'sellRC');
     const data = await tradeDataPriceCore(
       djed,
       "rcTargetPrice",
       rcDecimals,
       amountScaled
     );
djed-sdk/src/djed/stableCoin.js (1)

1-11: ⚠️ Potential issue | 🔴 Critical

Missing web3Promise import.

web3Promise is used in calculateFutureScPrice (line 117-119) but is not imported. This will cause a runtime error.

Proposed fix
 import { BC_DECIMALS, TRANSACTION_VALIDITY } from "../constants";
-import { decimalScaling, buildTx } from "../helpers";
+import { decimalScaling, buildTx, web3Promise } from "../helpers";
 import {
   tradeDataPriceCore,
🤖 Fix all issues with AI agents
In `@djed-sdk/src/djed/system.js`:
- Around line 150-165: Remove the duplicated/malformed fragment after the
existing return in getSystemParams: delete the orphaned "};", the dangling
"true", and the partial object literal that re-declares
reserveRatioMax/Min/fee/treasuryFee/thresholdSupplySC (these appear right after
the getSystemParams return). Ensure only the single, complete return inside
getSystemParams remains and do not alter legitimate uses of percentageScale,
reserveRatioMaxUnscaled, reserveRatioMinUnscaled, feeUnscaled or treasuryFee
elsewhere in the module.
- Around line 20-21: getCoinDetails currently hardcodes scMaxPrice for Shu
contracts which is inconsistent with other modules that use getPriceMethod from
tradeUtils.js; update getCoinDetails to call getPriceMethod with an explicit
operation type (e.g., a neutral/“info” operation or a sensible default like
"buy" or "none") or, if you truly want a neutral price, implement and call a new
helper in tradeUtils (e.g., getNeutralPriceMethod) and use that instead; locate
getCoinDetails and replace the hardcoded priceMethod assignment (and references
to checkIfShu if needed) to call getPriceMethod or the new helper so behavior
matches other trade code and is documented via the chosen operation name.

In `@djed-sdk/src/djed/tradeUtils.js`:
- Around line 118-120: The isTxLimitReached helper currently uses the ||
fallback which treats txLimit === 0 as falsy; update the fallback to use nullish
coalescing so an explicit 0 (meaning "no limit") is respected. Modify the
expression inside isTxLimitReached (the BigInt(txLimit || TRANSACTION_USD_LIMIT)
part) to use BigInt(txLimit ?? TRANSACTION_USD_LIMIT) so only null or undefined
fall back to TRANSACTION_USD_LIMIT while preserving 0 as a valid value.
🧹 Nitpick comments (3)
djed-sdk/src/djed/djed.js (1)

31-39: Duplicated Shu detection logic.

This checkIfShu function duplicates the detection logic in tradeUtils.js (getPriceMethod, line 214), which also calls scMaxPrice(0).call() inline. Consider consolidating to avoid redundant RPC calls when both paths are exercised.

One option: have getPriceMethod import and reuse checkIfShu instead of inline detection.

Example consolidation in tradeUtils.js
+import { checkIfShu } from "./djed";
+
 export const getPriceMethod = async (djed, operation) => {
-  const isShu = await djed.methods.scMaxPrice(0).call().then(() => true).catch(() => false);
+  const isShu = await checkIfShu(djed);
   
   if (!isShu) return "scPrice";
   // ...
 };
djed-sdk/src/djed/sellBoth.js (1)

69-71: Consider returning explicit error indicator.

On error, this function logs and returns undefined. While consistent with other SDK functions, callers have no way to distinguish "error occurred" from "successfully computed undefined." Consider throwing or returning an error object.

Optional improvement
   } catch (error) {
     console.error("Error in tradeDataPriceSellBoth:", error);
+    throw error; // Or return { error } for explicit handling
   }
djed-sdk/src/djed/listeners.js (1)

56-72: Consider a safer default for fromBlock.

Defaulting fromBlock to 0 can cause performance issues or timeouts on long-running chains when fetching events from genesis. Consider using a more recent default (e.g., last N blocks) or requiring the caller to specify it explicitly.

Optional: require explicit fromBlock
 export const getPastDjedEvents = async (
   djedContract,
   eventName,
-  filter = {},
-  fromBlock = 0
+  { filter = {}, fromBlock } = {}
 ) => {
+  if (fromBlock === undefined) {
+    throw new Error("fromBlock is required to prevent accidental full-chain scans");
+  }
   try {

Comment on lines +20 to +21
const isShu = await checkIfShu(djed);
const priceMethod = isShu ? "scMaxPrice" : "scPrice";
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Search for getPriceMethod usage
echo "=== Searching for getPriceMethod usage ==="
rg -n 'getPriceMethod' --type js -A 5

echo ""
echo "=== Searching for scMinPrice and scMaxPrice usage patterns ==="
rg -n 'scMinPrice|scMaxPrice' --type js -B 2 -A 2

echo ""
echo "=== Check the system.js file context around price method usage ==="
rg -n 'priceMethod' djed-sdk/src/djed/system.js -B 3 -A 3

Repository: DjedAlliance/StablePay

Length of output: 6288


🏁 Script executed:

#!/bin/bash
# Find getCoinDetails function to understand its purpose and operation type
rg -n 'getCoinDetails' djed-sdk/src/djed/system.js -B 2 -A 20

# Check if there's documentation about what operation type it should use
rg -n 'export.*getCoinDetails' djed-sdk/src/djed/system.js -B 5

Repository: DjedAlliance/StablePay

Length of output: 957


Use getPriceMethod function for consistency with other trade-related code, or document why hardcoding scMaxPrice is appropriate for getCoinDetails.

Currently, getCoinDetails hardcodes scMaxPrice for Shu contracts, but all other modules (stableCoin.js, sellBoth.js, etc.) use the getPriceMethod function from tradeUtils.js, which returns operation-specific prices (e.g., scMinPrice for sell operations). Since getCoinDetails is informational and not operation-specific, clarify whether it should:

  1. Call getPriceMethod with a defined operation type, or
  2. Use its own logic if displaying a neutral price, since hardcoding to scMaxPrice (a worst-case price) may not be appropriate for informational purposes.
🤖 Prompt for AI Agents
In `@djed-sdk/src/djed/system.js` around lines 20 - 21, getCoinDetails currently
hardcodes scMaxPrice for Shu contracts which is inconsistent with other modules
that use getPriceMethod from tradeUtils.js; update getCoinDetails to call
getPriceMethod with an explicit operation type (e.g., a neutral/“info” operation
or a sensible default like "buy" or "none") or, if you truly want a neutral
price, implement and call a new helper in tradeUtils (e.g.,
getNeutralPriceMethod) and use that instead; locate getCoinDetails and replace
the hardcoded priceMethod assignment (and references to checkIfShu if needed) to
call getPriceMethod or the new helper so behavior matches other trade code and
is documented via the chosen operation name.

Comment on lines +118 to 120
export const isTxLimitReached = (amountUSD, totalSCSupply, thresholdSCSupply, txLimit) =>
(BigInt(amountUSD) > BigInt(txLimit || TRANSACTION_USD_LIMIT)) &&
BigInt(totalSCSupply) >= BigInt(thresholdSCSupply);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🌐 Web query:

Djed smart contract transaction limit txLimit meaning zero value

💡 Result:

In the Djed Osiris-family deployments (e.g., the Belus Solidity implementation), txLimit refers to the protocol feature “maximum transaction limits” (a cap on how large a single mint/burn/buy/sell operation is allowed to be). (docs.stability.nexus)

If you read txLimit = 0 on-chain, it almost always means the limit is disabled / unlimited (i.e., “no max per-transaction cap”), because Solidity contracts commonly implement optional limits as “only enforce when limit > 0”. (To be 100% certain for your deployment, you’d need to check the exact contract code or verified source for that address.) (docs.stability.nexus)

Citations:


🏁 Script executed:

# Search for usage of isTxLimitReached in the codebase to understand how it's called
rg "isTxLimitReached" -B 2 -A 2

Repository: DjedAlliance/StablePay

Length of output: 2388


🏁 Script executed:

# Look for any constants or documentation about TRANSACTION_USD_LIMIT and txLimit
rg "TRANSACTION_USD_LIMIT|txLimit" -B 1 -A 1 -t js

Repository: DjedAlliance/StablePay

Length of output: 2749


🏁 Script executed:

# Check if there are any tests or usage examples that show what txLimit values are used
rg "txLimit.*0|txLimit\s*=" -B 2 -A 2 -t js

Repository: DjedAlliance/StablePay

Length of output: 48


🏁 Script executed:

# Search for the TRANSACTION_USD_LIMIT constant definition
rg "TRANSACTION_USD_LIMIT\s*=" -B 1 -A 1 -t js

Repository: DjedAlliance/StablePay

Length of output: 593


Use nullish coalescing (??) instead of || for txLimit fallback.

According to Djed smart contract standards, txLimit = 0 means the limit is disabled/unlimited. The current code txLimit || TRANSACTION_USD_LIMIT incorrectly treats 0 as falsy and applies the fallback limit instead of respecting "no limit". Use ?? to only fall back when txLimit is undefined or null.

Proposed fix
-export const isTxLimitReached = (amountUSD, totalSCSupply, thresholdSCSupply, txLimit) =>
-  (BigInt(amountUSD) > BigInt(txLimit || TRANSACTION_USD_LIMIT)) &&
+export const isTxLimitReached = (amountUSD, totalSCSupply, thresholdSCSupply, txLimit) =>
+  (BigInt(amountUSD) > BigInt(txLimit ?? TRANSACTION_USD_LIMIT)) &&
   BigInt(totalSCSupply) >= BigInt(thresholdSCSupply);
🤖 Prompt for AI Agents
In `@djed-sdk/src/djed/tradeUtils.js` around lines 118 - 120, The isTxLimitReached
helper currently uses the || fallback which treats txLimit === 0 as falsy;
update the fallback to use nullish coalescing so an explicit 0 (meaning "no
limit") is respected. Modify the expression inside isTxLimitReached (the
BigInt(txLimit || TRANSACTION_USD_LIMIT) part) to use BigInt(txLimit ??
TRANSACTION_USD_LIMIT) so only null or undefined fall back to
TRANSACTION_USD_LIMIT while preserving 0 as a valid value.

Copy link

@coderabbitai coderabbitai bot left a 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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
djed-sdk/package.json (1)

14-22: ⚠️ Potential issue | 🟡 Minor

Move web3 from devDependencies to peerDependencies.

web3 is used throughout the SDK for contract interactions, event subscriptions, and transaction helpers in the runtime code (src/), yet it's currently only in devDependencies. This means consumers who install this package won't have web3 automatically installed, causing the SDK to fail at runtime unless they manually install it. By declaring it as a peerDependency, you make this requirement explicit while allowing consumers to use their own web3 version, avoiding duplicate bundling.

♻️ Suggested change
   "devDependencies": {
     "@rollup/plugin-commonjs": "^26.0.1",
     "@rollup/plugin-json": "^6.1.0",
     "@rollup/plugin-node-resolve": "^15.2.3",
     "@rollup/plugin-replace": "^5.0.7",
     "@rollup/plugin-sucrase": "^5.0.2",
-    "rollup": "^4.18.0",
-    "web3": "^1.7.3"
-  }
+    "rollup": "^4.18.0"
+  },
+  "peerDependencies": {
+    "web3": "^1.7.3"
+  }
🤖 Fix all issues with AI agents
In `@stablepay-sdk/src/core/Transaction.js`:
- Around line 140-145: The checkBaseAssetAllowance method currently returns
'Inf' when this.baseAssetContract is falsy which masks the situation where a
baseAssetAddress was provided but init() hasn't run; update
checkBaseAssetAllowance to fail fast: if this.baseAssetAddress is set but
this.baseAssetContract is not initialized, throw a clear error (e.g. indicating
init() must be called or contract must be initialized) instead of returning
'Inf'; keep the original behavior of returning 'Inf' only when there is no
baseAssetAddress at all, and otherwise call
checkAllowance(this.baseAssetContract, owner, this.djedAddress) as before.
- Around line 1-2: The file imports CoinABI via a deep path which will break
when djed-sdk is installed from npm; replace the deep import (CoinABI from
'djed-sdk/src/artifacts/CoinABI.json') with a public import from the djed-sdk
package (e.g., import CoinABI from 'djed-sdk' or import { CoinABI } from
'djed-sdk') or, if the SDK does not currently export the ABI, either add the ABI
export in djed-sdk or embed a local copy of the needed ABI in Transaction.js;
update any references to CoinABI accordingly so Transaction.js only depends on
djed-sdk's public API.
🧹 Nitpick comments (2)
djed-sdk/package.json (1)

2-3: Consider bumping the version for this feature release.

The PR adds significant new functionality (Djed Shu/Isis/Tefnut support, sellBoth module, event listeners, new oracle integrations) but the version remains at 1.0.2. Per semantic versioning, new features typically warrant a minor version bump (e.g., 1.1.0).

If the version bump is planned for a separate commit before release, feel free to disregard.

djed-sdk/src/djed/token.js (1)

3-6: Consider adding a safe-approve helper for ERC-20 allowance-change race conditions.

The ERC-20 standard (SWC-114) documents a race condition when changing a non-zero allowance to another non-zero value: a spender can front-run the transaction to spend the original allowance before your new approve overwrites it, effectively spending both amounts. The standard and OpenZeppelin recommend resetting allowance to 0 before setting a new non-zero amount, or using increaseAllowance/decreaseAllowance patterns instead.

A dedicated safe-approve helper would protect callers without modifying the current approveTx behavior.

♻️ Proposed helper (optional)
 export const approveTx = (tokenContract, owner, spender, amount) => {
   const data = tokenContract.methods.approve(spender, amount).encodeABI();
   return buildTx(owner, tokenContract.options.address, 0, data);
 };
 
+// Optional safer pattern: return 1–2 txs depending on current allowance
+export const safeApproveTx = async (tokenContract, owner, spender, amount) => {
+  const current = await tokenContract.methods.allowance(owner, spender).call();
+  const currentBn = BigInt(current);
+  const nextBn = BigInt(amount);
+
+  if (currentBn !== 0n && nextBn !== 0n) {
+    const resetData = tokenContract.methods.approve(spender, 0).encodeABI();
+    const approveData = tokenContract.methods.approve(spender, amount).encodeABI();
+    return [
+      buildTx(owner, tokenContract.options.address, 0, resetData),
+      buildTx(owner, tokenContract.options.address, 0, approveData),
+    ];
+  }
+
+  const data = tokenContract.methods.approve(spender, amount).encodeABI();
+  return [buildTx(owner, tokenContract.options.address, 0, data)];
+};

Comment on lines +1 to +2
import { getWeb3, getDjedContract, getCoinContracts, getDecimals, getOracleAddress, getOracleContract, tradeDataPriceBuySc, buyScTx, checkAllowance, approveTx, buyScIsisTx } from 'djed-sdk';
import coinArtifact from 'djed-sdk/src/artifacts/CoinABI.json'; // Importing CoinABI from SDK
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

fd "Transaction.js" -t f

Repository: DjedAlliance/StablePay

Length of output: 103


🏁 Script executed:

head -20 stablepay-sdk/src/core/Transaction.js

Repository: DjedAlliance/StablePay

Length of output: 920


🏁 Script executed:

cat package.json | head -30

Repository: DjedAlliance/StablePay

Length of output: 110


🏁 Script executed:

fd "package.json" -t f

Repository: DjedAlliance/StablePay

Length of output: 114


🏁 Script executed:

cat stablepay-sdk/package.json

Repository: DjedAlliance/StablePay

Length of output: 1061


🏁 Script executed:

cat djed-sdk/package.json

Repository: DjedAlliance/StablePay

Length of output: 634


🏁 Script executed:

fd "index.js" djed-sdk -t f

Repository: DjedAlliance/StablePay

Length of output: 197


🏁 Script executed:

cat djed-sdk/src/index.js

Repository: DjedAlliance/StablePay

Length of output: 307


🏁 Script executed:

cat djed-sdk/src/djed/index.js

Repository: DjedAlliance/StablePay

Length of output: 1068


🏁 Script executed:

rg "CoinABI" djed-sdk/src -t js -t json

Repository: DjedAlliance/StablePay

Length of output: 145


🏁 Script executed:

fd "CoinABI.json" djed-sdk -t f

Repository: DjedAlliance/StablePay

Length of output: 101


🏁 Script executed:

cat djed-sdk/src/djed/djed.js | head -50

Repository: DjedAlliance/StablePay

Length of output: 1771


🏁 Script executed:

rg "coinArtifact" stablepay-sdk/src/core/Transaction.js -A 3

Repository: DjedAlliance/StablePay

Length of output: 385


🏁 Script executed:

rg "coinArtifact" stablepay-sdk/src -B 2 -A 2

Repository: DjedAlliance/StablePay

Length of output: 929


🏁 Script executed:

rg "\"files\"" djed-sdk/package.json

Repository: DjedAlliance/StablePay

Length of output: 48


🏁 Script executed:

cat djed-sdk/.npmignore 2>/dev/null || echo "No .npmignore found"

Repository: DjedAlliance/StablePay

Length of output: 84


Avoid deep-importing CoinABI from djed-sdk internals.

Importing djed-sdk/src/artifacts/CoinABI.json directly couples to the dependency's source layout. The djed-sdk package explicitly excludes src/ from published builds (see .npmignore), so this import will break when consumers install djed-sdk from npm. CoinABI must be exported as a public API from djed-sdk for this to work reliably.

Suggested direction (requires djed-sdk to export CoinABI)
-import coinArtifact from 'djed-sdk/src/artifacts/CoinABI.json'; // Importing CoinABI from SDK
+import { CoinABI } from 'djed-sdk'; // Expose CoinABI via package exports
🤖 Prompt for AI Agents
In `@stablepay-sdk/src/core/Transaction.js` around lines 1 - 2, The file imports
CoinABI via a deep path which will break when djed-sdk is installed from npm;
replace the deep import (CoinABI from 'djed-sdk/src/artifacts/CoinABI.json')
with a public import from the djed-sdk package (e.g., import CoinABI from
'djed-sdk' or import { CoinABI } from 'djed-sdk') or, if the SDK does not
currently export the ABI, either add the ABI export in djed-sdk or embed a local
copy of the needed ABI in Transaction.js; update any references to CoinABI
accordingly so Transaction.js only depends on djed-sdk's public API.

Comment on lines +140 to +145
async checkBaseAssetAllowance(owner) {
if (!this.baseAssetContract) {
return 'Inf';
}
return checkAllowance(this.baseAssetContract, owner, this.djedAddress);
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Don’t return 'Inf' when baseAssetAddress is set but the contract isn’t initialized.

If baseAssetAddress is provided and init() hasn’t run, returning 'Inf' can cause callers to skip approval and later hit a revert. Fail fast in that case.

✅ Suggested fix
 async checkBaseAssetAllowance(owner) {
-   if (!this.baseAssetContract) {
-      return 'Inf'; 
-   }
-   return checkAllowance(this.baseAssetContract, owner, this.djedAddress);
+   if (this.baseAssetAddress && !this.baseAssetContract) {
+     throw new Error("Base Asset contract not initialized");
+   }
+   if (!this.baseAssetAddress) {
+     return 'Inf';
+   }
+   return checkAllowance(this.baseAssetContract, owner, this.djedAddress);
 }
🤖 Prompt for AI Agents
In `@stablepay-sdk/src/core/Transaction.js` around lines 140 - 145, The
checkBaseAssetAllowance method currently returns 'Inf' when
this.baseAssetContract is falsy which masks the situation where a
baseAssetAddress was provided but init() hasn't run; update
checkBaseAssetAllowance to fail fast: if this.baseAssetAddress is set but
this.baseAssetContract is not initialized, throw a clear error (e.g. indicating
init() must be called or contract must be initialized) instead of returning
'Inf'; keep the original behavior of returning 'Inf' only when there is no
baseAssetAddress at all, and otherwise call
checkAllowance(this.baseAssetContract, owner, this.djedAddress) as before.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[djed-sdk] Implement support for Djed Isis and Tefnut variants

1 participant