Repository navigation
Conversation
Keep seize as a direct BANK.transfer after validateSeize. Expose the transient suppression state so Injective Core can read in-flight contract storage before entering the matching permissions hooks. The getter does not alter transfer semantics or storage layout; ordinary EVM and Cosmos transfers continue through compliance.
Extend the real-node Hardhat acceptance test with a restricted issuer wallet. Confirm ordinary EVM and Cosmos transfers remain rejected, then verify partial and full seize operations preserve supply, balances, wallet tracking, and investor counters.
📝 WalkthroughWalkthroughThe token contract now exposes post-transfer hook suppression status. The Injective MTS integration test adds issuer-wallet registration, blocked transfer checks, and partial and full seizure accounting checks. ChangesMTS transfer controls
Estimated code review effort: 2 (Simple) | ~10 minutes 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
test/dstoken-injective-mts.test.ts (1)
263-264: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick winAssert the EVM restriction, not only a revert.
to.be.revertedaccepts any failure. It does not prove that the issuer-wallet restriction caused the EVM transfer to fail. After confirming the compliance error is stable, match it withrevertedWithor the appropriate custom-error matcher. Otherwise, assert that both balances remain unchanged.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@test/dstoken-injective-mts.test.ts` around lines 263 - 264, Update the issuer-wallet transfer assertion in the relevant test to match the specific compliance error using revertedWith or the appropriate custom-error matcher, rather than accepting any revert. Preserve the existing bankSend compliance-error assertion and verify the issuer wallet restriction is the cause of the EVM transfer failure.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@test/dstoken-injective-mts.test.ts`:
- Around line 268-284: Update every numeric expected value in the assertions
surrounding dsToken.totalSupply, balanceOf, balanceOfInvestor, walletCount, and
complianceService.getTotalInvestorsCount to bigint literals by adding the n
suffix, including all 14 values before and after seize.
---
Nitpick comments:
In `@test/dstoken-injective-mts.test.ts`:
- Around line 263-264: Update the issuer-wallet transfer assertion in the
relevant test to match the specific compliance error using revertedWith or the
appropriate custom-error matcher, rather than accepting any revert. Preserve the
existing bankSend compliance-error assertion and verify the issuer wallet
restriction is the cause of the EVM transfer failure.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 4f37c776-26fc-4dd7-9236-d82bed4b5bce
📒 Files selected for processing (2)
contracts/token/DSTokenMTS.soltest/dstoken-injective-mts.test.ts
| expect(await dsToken.totalSupply()).to.equal(500); | ||
| expect(await dsToken.balanceOf(holder.address)).to.equal(275); | ||
| expect(await dsToken.balanceOf(issuerWallet.address)).to.equal(100); | ||
| expect(await dsToken.balanceOfInvestor(INVESTORS.INVESTOR_ID.INVESTOR_ID_1)).to.equal(275); | ||
| expect(await dsToken.walletCount()).to.equal(3); | ||
| expect(await complianceService.getTotalInvestorsCount()).to.equal(2); | ||
|
|
||
| await (await dsToken.seize(holder.address, issuerWallet.address, 275, 'test full seize')).wait(); | ||
|
|
||
| expect(await dsToken.totalSupply()).to.equal(500); | ||
| expect(await dsToken.balanceOf(holder.address)).to.equal(0); | ||
| expect(await dsToken.balanceOf(owner.address)).to.equal(125); | ||
| expect(await dsToken.balanceOf(issuerWallet.address)).to.equal(375); | ||
| expect(await dsToken.balanceOfInvestor(INVESTORS.INVESTOR_ID.INVESTOR_ID_1)).to.equal(0); | ||
| expect(await dsToken.balanceOfInvestor(INVESTORS.INVESTOR_ID.INVESTOR_ID_2)).to.equal(125); | ||
| expect(await dsToken.walletCount()).to.equal(2); | ||
| expect(await complianceService.getTotalInvestorsCount()).to.equal(1); |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/usr/bin/env bash
set -euo pipefail
rg -n '"ethers"\s*:' --glob 'package*.json' --glob '*lock*'
rg -n 'to\.equal\([0-9]+' test/dstoken-injective-mts.test.tsRepository: InjectiveLabs/dstoken
Length of output: 159
🏁 Script executed:
#!/usr/bin/env bash
set -euo pipefail
printf '%s\n' '--- candidate files ---'
git ls-files | rg '(^|/)(package[^/]*\.json|.*lock.*|dstoken-injective-mts\.test\.ts)$' || true
printf '%s\n' '--- test file matches ---'
test_file="$(git ls-files | rg '(^|/)dstoken-injective-mts\.test\.ts$' | head -n 1)"
printf 'test_file=%s\n' "$test_file"
rg -n -C 3 'to\.equal\([0-9]+|totalSupply|walletCount|getTotalInvestorsCount|balanceOfInvestor' "$test_file" || true
printf '%s\n' '--- dependency declarations ---'
while IFS= read -r f; do
printf '\n[%s]\n' "$f"
rg -n -C 2 '"ethers"\s*:' "$f" || true
done < <(git ls-files | rg '(^|/)(package[^/]*\.json|.*lock.*)$')Repository: InjectiveLabs/dstoken
Length of output: 3828
🏁 Script executed:
#!/usr/bin/env bash
set -euo pipefail
printf '%s\n' '--- package.json ethers declaration ---'
rg -n -C 3 '"ethers"\s*:' package.json
printf '%s\n' '--- package-lock ethers entries ---'
rg -n -C 3 '"node_modules/ethers"|"ethers"\s*:' package-lock.json | head -n 80
printf '%s\n' '--- pnpm-lock ethers entries ---'
rg -n -C 3 '(^|/| )ethers(@|:)|ethers:' pnpm-lock.yaml | head -n 80
printf '%s\n' '--- numeric equality assertions in the test ---'
rg -n 'to\.equal\([0-9]+[n]?\)' test/dstoken-injective-mts.test.ts
printf '%s\n' '--- return types for asserted contract methods ---'
rg -n -C 4 'function (totalSupply|balanceOf|balanceOfInvestor|walletCount|getTotalInvestorsCount)|totalSupply\(|balanceOfInvestor\(|walletCount\(|getTotalInvestorsCount\(' contracts interfaces src test | head -n 240Repository: InjectiveLabs/dstoken
Length of output: 28384
🏁 Script executed:
#!/usr/bin/env bash
set -euo pipefail
python3 - <<'PY'
import json
import re
from pathlib import Path
package = json.loads(Path("package.json").read_text())
lock = json.loads(Path("package-lock.json").read_text())
test = Path("test/dstoken-injective-mts.test.ts").read_text()
source = Path("contracts/token/IDSToken.sol").read_text()
declared = package["devDependencies"]["ethers"]
locked = lock["packages"]["node_modules/ethers"]["version"]
block = "\n".join(test.splitlines()[267:284])
assertions = re.findall(r"\.to\.equal\((\d+)\)", block)
uint256_methods = {
name: bool(re.search(
rf"function\s+{name}\b[\s\S]*?returns\s*\(\s*uint256",
source,
))
for name in ("walletCount", "balanceOfInvestor")
}
print({
"declared_ethers": declared,
"locked_ethers": locked,
"bare_numeric_assertions_in_lines_268_284": len(assertions),
"asserted_values": assertions,
"IDSToken_uint256_methods": uint256_methods,
})
assert locked.startswith("6.")
assert len(assertions) == 16
assert all(uint256_methods.values())
PYRepository: InjectiveLabs/dstoken
Length of output: 539
🏁 Script executed:
#!/usr/bin/env bash
set -euo pipefail
printf '%s\n' '--- asserted function declarations ---'
rg -n -U 'function (totalSupply|balanceOf|balanceOfInvestor|walletCount|getTotalInvestorsCount)\b[\s\S]{0,180}?returns\s*\(\s*uint256' contracts
printf '%s\n' '--- corrected read-only invariant check ---'
python3 - <<'PY'
import json
import re
from pathlib import Path
package = json.loads(Path("package.json").read_text())
lock = json.loads(Path("package-lock.json").read_text())
test_lines = Path("test/dstoken-injective-mts.test.ts").read_text().splitlines()
block = "\n".join(test_lines[267:284])
values = re.findall(r"\.to\.equal\((\d+)\)", block)
print("declared ethers:", package["devDependencies"]["ethers"])
print("locked ethers:", lock["packages"]["node_modules/ethers"]["version"])
print("bare numeric assertions at lines 268-284:", len(values))
print("values:", values)
assert lock["packages"]["node_modules/ethers"]["version"].startswith("6.")
assert len(values) == 14
PYRepository: InjectiveLabs/dstoken
Length of output: 2191
Use bigint values in the numeric assertions. Ethers 6 returns these uint256 values as bigint, so update all 14 expected values in lines 268–284 with the n suffix.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@test/dstoken-injective-mts.test.ts` around lines 268 - 284, Update every
numeric expected value in the assertions surrounding dsToken.totalSupply,
balanceOf, balanceOfInvestor, walletCount, and
complianceService.getTotalInvestorsCount to bigint literals by adding the n
suffix, including all 14 values before and after seize.
There was a problem hiding this comment.
Pull request overview
This PR preserves the intended “direct Bank.transfer” semantics for seize in the Injective MTS integration by exposing the in-flight suppression flag to the Bank precompile and expanding the real-node integration test coverage around restricted issuer wallets and seize behavior.
Changes:
- Expose
suppressPostTransferRecordviaisBankTransferHookSuppressed()so the Bank precompile can read the transient suppression state during an authorized in-flight call. - Extend the Injective MTS integration test to validate issuer-wallet restrictions and to assert partial/full seize outcomes across supply, balances, wallet tracking, and investor counters.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
contracts/token/DSTokenMTS.sol |
Adds an external view accessor for the transient suppression flag used during Bank-module transfers (for precompile integration). |
test/dstoken-injective-mts.test.ts |
Adds issuer-wallet restriction checks and partial/full seize assertions in the Injective MTS real-node suite. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Summary
Notes
No burn/mint workaround is included, and there is no storage-layout change. One of the alternative workarounds was to replace transfer with mint+burn but it changes semantics.
Behavior
Ordinary EVM transfers and Cosmos bank sends to the restricted issuer wallet continue to be rejected. Only the contract-originated Bank transfer inside an already-authorized seize observes the transient suppression state; the flag resets before the transaction completes.
Dependency
Requires InjectiveLabs/injective-core#2919 for active-StateDB suppression handling in the Bank precompile and matching permissions hooks.
Verification