Skip to content

Precompile advanced order#2685

Draft
open-junius wants to merge 18 commits into
devnet-readyfrom
precompile-advanced-order
Draft

Precompile advanced order#2685
open-junius wants to merge 18 commits into
devnet-readyfrom
precompile-advanced-order

Conversation

@open-junius

Copy link
Copy Markdown
Contributor

Description

Related Issue(s)

  • Closes #[issue number]

Type of Change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Documentation update
  • Other (please describe):

Breaking Change

If this PR introduces a breaking change, please provide a detailed description of the impact and the migration path for existing applications.

Checklist

  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have run ./scripts/fix_rust.sh to ensure my code is formatted and linted correctly
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes
  • Any dependent changes have been merged and published in downstream modules

Screenshots (if applicable)

Please include any relevant screenshots or GIFs that demonstrate the changes made.

Additional Notes

Please provide any additional information or context that may be helpful for reviewers.

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

AI review — see the sticky summary comment for the verdict and the inline comments below for specific findings.

/// subnet are skipped.
#[pallet::call_index(1)]
#[pallet::weight(T::WeightInfo::execute_batched_orders(orders.len() as u32))]
pub fn execute_batched_orders(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

[HIGH] Batched execution is not atomic after collecting user assets

execute_batched_orders pulls TAO/staked alpha from every order signer into the pallet account via collect_assets, then makes later fallible calls (net_pool_swap, distribution transfers, zero-output checks). Without a transaction boundary, an error after collect_assets can return Err while leaving balances/stake already moved into or through the pallet account and orders not marked fulfilled. A public relayer can trigger this with valid signed orders plus a later slippage/zero-output/distribution failure, locking or misrouting user funds. Wrap the whole batched dispatch in a FRAME transaction so any later error rolls back the asset collection and intermediate transfers.

Suggested change
pub fn execute_batched_orders(
#[frame_support::transactional]
pub fn execute_batched_orders(

Comment on lines +153 to +176
let available =
Self::get_stake_for_hotkey_and_coldkey_on_subnet(from_hotkey, from_coldkey, netuid);
ensure!(available >= amount, Error::<T>::NotEnoughStakeToWithdraw);
Self::decrease_stake_for_hotkey_and_coldkey_on_subnet(
from_hotkey,
from_coldkey,
netuid,
amount,
);
Self::increase_stake_for_hotkey_and_coldkey_on_subnet(
to_hotkey, to_coldkey, netuid, amount,
);
LastColdkeyHotkeyStakeBlock::<T>::insert(
to_coldkey,
to_hotkey,
Self::get_current_block_as_u64(),
);
if validate_receiver {
ensure!(
Self::hotkey_account_exists(to_hotkey),
Error::<T>::HotKeyAccountNotExists
);
Self::set_stake_operation_limit(to_hotkey, to_coldkey, netuid);
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

[HIGH] Stake transfer mutates balances before receiver validation

transfer_staked_alpha decreases the sender stake, increases receiver stake, and writes the rate-limit block before checking hotkey_account_exists(to_hotkey) when validate_receiver is true. In the new batched limit-order distribution path, a buy order with an unregistered destination hotkey can therefore make this helper return Err after stake has already been moved. Validate the receiver before any stake mutation, then set the receiver rate limit after the successful move.

Suggested change
let available =
Self::get_stake_for_hotkey_and_coldkey_on_subnet(from_hotkey, from_coldkey, netuid);
ensure!(available >= amount, Error::<T>::NotEnoughStakeToWithdraw);
Self::decrease_stake_for_hotkey_and_coldkey_on_subnet(
from_hotkey,
from_coldkey,
netuid,
amount,
);
Self::increase_stake_for_hotkey_and_coldkey_on_subnet(
to_hotkey, to_coldkey, netuid, amount,
);
LastColdkeyHotkeyStakeBlock::<T>::insert(
to_coldkey,
to_hotkey,
Self::get_current_block_as_u64(),
);
if validate_receiver {
ensure!(
Self::hotkey_account_exists(to_hotkey),
Error::<T>::HotKeyAccountNotExists
);
Self::set_stake_operation_limit(to_hotkey, to_coldkey, netuid);
}
if validate_receiver {
ensure!(
Self::hotkey_account_exists(to_hotkey),
Error::<T>::HotKeyAccountNotExists
);
}
let available =
Self::get_stake_for_hotkey_and_coldkey_on_subnet(from_hotkey, from_coldkey, netuid);
ensure!(available >= amount, Error::<T>::NotEnoughStakeToWithdraw);
Self::decrease_stake_for_hotkey_and_coldkey_on_subnet(
from_hotkey,
from_coldkey,
netuid,
amount,
);
Self::increase_stake_for_hotkey_and_coldkey_on_subnet(
to_hotkey, to_coldkey, netuid, amount,
);
LastColdkeyHotkeyStakeBlock::<T>::insert(
to_coldkey,
to_hotkey,
Self::get_current_block_as_u64(),
);
if validate_receiver {
Self::set_stake_operation_limit(to_hotkey, to_coldkey, netuid);
}

@github-actions

github-actions Bot commented May 25, 2026

Copy link
Copy Markdown
Contributor

🛡️ AI Review — Skeptic (security review)

VERDICT: VULNERABLE

BASELINE scrutiny: open-junius has repo write permission, an account older than two years, substantial contribution history, and no trusted Gittensor allowlist match; branch is precompile-advanced-order -> devnet-ready.

No trusted review prompt files or .github/copilot-instructions.md are modified in this PR. The added limit-orders precompile delegates execution and cancellation through the existing signed pallet extrinsics; I did not find a direct origin bypass or runtime panic path in that conversion layer.

Findings

Sev File Finding
HIGH contract-tests/package.json:3 Contract test script now skips the existing suite inline

Prior-comment reconciliation

  • 5ea5729b: not addressedcontract-tests/package.json still narrows the persistent test script to test/limitOrders.precompile.test.ts, so the prior test-suite bypass remains present.

Conclusion

The PR appears legitimate, but it still weakens the persistent contract-test CI entrypoint by skipping the existing suite. That is a security-relevant test bypass and should block merge until the full suite is restored.


📜 Previous run (superseded)
Sev File Finding Status
HIGH contract-tests/package.json:3 Contract test script now skips the existing suite ➡️ Carried forward to current findings
contract-tests/package.json still narrows the persistent test script to test/limitOrders.precompile.test.ts, so the prior test-suite bypass remains present.

# 🔍 AI Review — Auditor (domain review) has not yet run on this PR.

@github-actions

Copy link
Copy Markdown
Contributor

🔄 AI review updated — Skeptic: VULNERABLE

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

AI review — see the sticky summary comment for the verdict and the inline comments below for specific findings.

Comment on lines +439 to +441
#[pallet::call_index(1)]
#[pallet::weight(T::WeightInfo::execute_batched_orders(orders.len() as u32))]
pub fn execute_batched_orders(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

[HIGH] Batched execution is not atomic after collecting user assets

execute_batched_orders can transfer TAO/staked alpha into the pallet account in collect_assets, then return Err from net_pool_swap, distribute_alpha_pro_rata, or distribute_tao_pro_rata. Without a transaction boundary on the extrinsic, those earlier balance/stake mutations are not rolled back, so a failing batch can strand or move user assets while the order remains unfulfilled. Wrap the whole batched extrinsic in #[frame_support::transactional] or otherwise make every post-collection failure non-fatal and fully accounted.

Suggested change
#[pallet::call_index(1)]
#[pallet::weight(T::WeightInfo::execute_batched_orders(orders.len() as u32))]
pub fn execute_batched_orders(
#[pallet::call_index(1)]
#[pallet::weight(T::WeightInfo::execute_batched_orders(orders.len() as u32))]
#[frame_support::transactional]
pub fn execute_batched_orders(

Comment on lines +153 to +176
let available =
Self::get_stake_for_hotkey_and_coldkey_on_subnet(from_hotkey, from_coldkey, netuid);
ensure!(available >= amount, Error::<T>::NotEnoughStakeToWithdraw);
Self::decrease_stake_for_hotkey_and_coldkey_on_subnet(
from_hotkey,
from_coldkey,
netuid,
amount,
);
Self::increase_stake_for_hotkey_and_coldkey_on_subnet(
to_hotkey, to_coldkey, netuid, amount,
);
LastColdkeyHotkeyStakeBlock::<T>::insert(
to_coldkey,
to_hotkey,
Self::get_current_block_as_u64(),
);
if validate_receiver {
ensure!(
Self::hotkey_account_exists(to_hotkey),
Error::<T>::HotKeyAccountNotExists
);
Self::set_stake_operation_limit(to_hotkey, to_coldkey, netuid);
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

[HIGH] Stake transfer mutates balances before receiver validation

When validate_receiver is true, this function decreases the sender stake, increases the receiver stake, and writes LastColdkeyHotkeyStakeBlock before checking hotkey_account_exists(to_hotkey). If that receiver check fails, the function returns an error after mutating stake accounting. In the current batched-order path this compounds the missing atomicity issue; the receiver-side validation needs to happen before any stake movement.

Suggested change
let available =
Self::get_stake_for_hotkey_and_coldkey_on_subnet(from_hotkey, from_coldkey, netuid);
ensure!(available >= amount, Error::<T>::NotEnoughStakeToWithdraw);
Self::decrease_stake_for_hotkey_and_coldkey_on_subnet(
from_hotkey,
from_coldkey,
netuid,
amount,
);
Self::increase_stake_for_hotkey_and_coldkey_on_subnet(
to_hotkey, to_coldkey, netuid, amount,
);
LastColdkeyHotkeyStakeBlock::<T>::insert(
to_coldkey,
to_hotkey,
Self::get_current_block_as_u64(),
);
if validate_receiver {
ensure!(
Self::hotkey_account_exists(to_hotkey),
Error::<T>::HotKeyAccountNotExists
);
Self::set_stake_operation_limit(to_hotkey, to_coldkey, netuid);
}
if validate_receiver {
ensure!(
Self::hotkey_account_exists(to_hotkey),
Error::<T>::HotKeyAccountNotExists
);
}
let available =
Self::get_stake_for_hotkey_and_coldkey_on_subnet(from_hotkey, from_coldkey, netuid);
ensure!(available >= amount, Error::<T>::NotEnoughStakeToWithdraw);
Self::decrease_stake_for_hotkey_and_coldkey_on_subnet(
from_hotkey,
from_coldkey,
netuid,
amount,
);
Self::increase_stake_for_hotkey_and_coldkey_on_subnet(
to_hotkey, to_coldkey, netuid, amount,
);
LastColdkeyHotkeyStakeBlock::<T>::insert(
to_coldkey,
to_hotkey,
Self::get_current_block_as_u64(),
);
if validate_receiver {
Self::set_stake_operation_limit(to_hotkey, to_coldkey, netuid);
}

@github-actions

Copy link
Copy Markdown
Contributor

🔄 AI review updated — Skeptic: VULNERABLE

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

AI review — see the sticky summary comment for the verdict and the inline comments below for specific findings.

let pallet_hotkey = T::PalletHotkey::get();

// Pull all input assets into the pallet intermediary before touching the pool.
Self::collect_assets(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

[HIGH] Batched execution is not atomic after collecting user assets

execute_batched_orders still starts by moving every buyer's TAO and seller's staked alpha into the pallet intermediary, then performs the net pool swap, pro-rata distributions, fee forwarding, order-status writes, and event emission as separate fallible steps. There is no outer #[transactional] / with_transaction boundary around the whole batch. If any later transfer or swap fails after this line, earlier collect_assets transfers are not rolled back, so users can lose assets while the extrinsic returns an error and some orders remain unfilled. Wrap the full do_execute_batched_orders asset-collection/swap/distribution/status-write flow in a transaction, or prevalidate every fallible post-collection transfer so no failure is possible after user assets are pulled.

Comment on lines +138 to +152
Self::decrease_stake_for_hotkey_and_coldkey_on_subnet(
from_hotkey,
from_coldkey,
netuid,
amount,
);
Self::increase_stake_for_hotkey_and_coldkey_on_subnet(
to_hotkey, to_coldkey, netuid, amount,
);
LastColdkeyHotkeyStakeBlock::<T>::insert(
to_coldkey,
to_hotkey,
Self::get_current_block_as_u64(),
);
if validate_receiver {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

[HIGH] Stake transfer mutates balances before receiver validation

transfer_staked_alpha decreases the sender's stake, increases the receiver's stake, and writes LastColdkeyHotkeyStakeBlock before checking validate_receiver. The batch distributor calls this with validate_receiver = true for buyers, so a bad buyer hotkey can make the function return HotKeyAccountNotExists after stake has already been moved out of the pallet intermediary. Because this helper is not transactional and the outer batch is not transactional, that failure leaves mutated stake/accounting behind. Validate to_hotkey before lines 138-151, or make this helper transactional so receiver-validation failures roll back the mutations.

Comment on lines +713 to +720
let (amount_in, amount_out) = if order.order_type.is_buy() {
// partial fill validations have passed, it is safe here to do this
let tao_in = TaoBalance::from(signed_order.partial_fill.unwrap_or(order.amount));
// Deduct fee from TAO input before swapping.
let fee_tao = TaoBalance::from(order.fee_rate.mul_floor(tao_in.to_u64()));
let tao_after_fee = tao_in.saturating_sub(fee_tao);

let alpha_out = T::SwapInterface::buy_alpha(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

[MEDIUM] Direct buy execution can fill an order without collecting its fee

For buy orders, the pallet only passes tao_after_fee into buy_alpha, so the subtensor-side balance validation only proves the signer can pay the net swap amount. The fee is then forwarded best-effort from the signer after the swap. A signer with exactly amount - fee free TAO can have the order execute and be marked fulfilled, while forward_fee fails and leaves the fee unpaid. This makes the signed fee field unenforceable in the direct execute_orders path. Require/fund the gross buy amount atomically, or make buy fee transfer a hard precondition before marking the order executed.

@github-actions

Copy link
Copy Markdown
Contributor

🔄 AI review updated — Skeptic: VULNERABLE

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

AI review — see the sticky summary comment for the verdict and the inline comments below for specific findings.

Comment on lines +768 to +769
/// Thin orchestrator for `execute_batched_orders`.
fn do_execute_batched_orders(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

[HIGH] Batched execution is not atomic after collecting user assets

do_execute_batched_orders performs multiple fallible mutations in sequence: it first pulls buyer TAO and seller stake into the pallet account, then swaps, distributes outputs, writes order status, and finally forwards fees. Because the function has no transaction boundary, any failure after an earlier transfer leaves those earlier asset movements committed while the extrinsic returns an error. A malformed batch can therefore strand funds/stake in the pallet intermediary or partially settle only some orders. Wrap the whole batch execution in a FRAME transaction, or otherwise prove every later fallible operation before moving assets.

Suggested change
/// Thin orchestrator for `execute_batched_orders`.
fn do_execute_batched_orders(
/// Thin orchestrator for `execute_batched_orders`.
#[frame_support::transactional]
fn do_execute_batched_orders(

Comment thread pallets/limit-orders/src/lib.rs Outdated
)?;

// Forward the fee TAO to the order's fee recipient.
Self::forward_fee(&order.signer, &order.fee_recipient, fee_tao);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

[MEDIUM] Direct buy execution can fill an order without collecting its fee

The buy path subtracts fee_tao from the signed amount and calls buy_alpha with only tao_after_fee. buy_alpha(..., validate: true) therefore only checks and removes the net amount from the signer. The fee transfer is attempted afterward through forward_fee, which swallows transfer failures, so a signer with enough balance for the net swap but not the fee can still receive alpha and have the order marked fulfilled without paying the signed fee. Collect/escrow the gross TAO up front, or make fee collection a mandatory part of a transaction-wrapped single-order execution.

@github-actions

Copy link
Copy Markdown
Contributor

🔄 AI review updated — Skeptic: VULNERABLE

@open-junius open-junius mentioned this pull request May 27, 2026
19 tasks

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

AI review — see the sticky summary comment for the verdict and the inline comments below for specific findings.

}

/// Thin orchestrator for `execute_batched_orders`.
fn do_execute_batched_orders(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

[HIGH] Batched execution is not atomic after collecting user assets

execute_batched_orders still enters do_execute_batched_orders without a transaction boundary, then debits user TAO/alpha in collect_assets before later fallible ? calls in the pool swap and distribution steps. If any later step fails, prior balance/stake transfers and any pool mutation can persist while the extrinsic returns an error, leaving user assets stranded or partially settled. Wrap the whole orchestrator in a transactional boundary, or move all fallible validation ahead of collection and make the post-collection path infallible.

Suggested change
fn do_execute_batched_orders(
#[frame_support::transactional]
fn do_execute_batched_orders(

Comment thread pallets/limit-orders/src/lib.rs Outdated
)?;

// Forward the fee TAO to the order's fee recipient.
Self::forward_fee(&order.signer, &order.fee_recipient, fee_tao);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

[MEDIUM] Direct buy execution can fill an order without collecting its fee

For buy orders, buy_alpha only debits tao_after_fee; the fee is then attempted with best-effort forward_fee, which emits FeeTransferFailed but does not revert. A signer funded with exactly tao_after_fee can receive the alpha, have the order marked executed, and avoid paying the signed fee. Collect the gross amount atomically, or make fee transfer failure revert before marking the order filled.

@github-actions

Copy link
Copy Markdown
Contributor

🔄 AI review updated — Skeptic: VULNERABLE

@open-junius open-junius added the skip-cargo-audit This PR fails cargo audit but needs to be merged anyway label May 28, 2026
@open-junius open-junius self-assigned this May 28, 2026

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

AI review — see the sticky summary comment for the verdict and the inline comments below for specific findings.

}

/// Thin orchestrator for `execute_batched_orders`.
fn do_execute_batched_orders(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

[HIGH] Batched execution is not atomic after collecting user assets

do_execute_batched_orders performs a multi-step settlement without a #[transactional] boundary. After collect_assets pulls gross TAO/alpha into the pallet account, later fallible calls (net_pool_swap, pro-rata distributions, order-status writes, and collect_fees) can still return Err. FRAME does not automatically roll back prior balance/storage mutations on DispatchError, so a failed batch can leave users debited, the pallet credited, or orders partially settled. Wrap the whole batched settlement in a transaction, or pre-validate every later fallible condition before moving assets.

let fee_tao = TaoBalance::from(order.fee_rate.mul_floor(tao_in.to_u64()));
let tao_after_fee = tao_in.saturating_sub(fee_tao);

let alpha_out = T::SwapInterface::buy_alpha(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

[MEDIUM] Direct buy execution can fill an order without collecting its fee

The buy path spends only tao_after_fee in buy_alpha, then tries to transfer the fee afterward. A signer with enough balance for tao_after_fee but not the fee can get the alpha purchase applied, then make forward_fee fail. In best-effort execute_orders (should_fail = false), that error is swallowed as OrderSkipped, and there is no transactional wrapper around try_execute_order to roll back the already-applied buy. Collect/reserve the gross input before the swap, or make each per-order attempt transactional so skipped failures cannot retain prior side effects.

@github-actions

github-actions Bot commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

🔄 AI review updated — Skeptic: VULNERABLE

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

AI review — see the sticky summary comment for the verdict and the inline comments below for specific findings.

}

/// Thin orchestrator for `execute_batched_orders`.
fn do_execute_batched_orders(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

[HIGH] Batched execution is not atomic after collecting user assets

do_execute_batched_orders collects buyer TAO and seller alpha into the pallet account, then performs several later fallible steps: residual pool swap, pro-rata distributions, order status writes, and fee forwarding. Because this orchestrator is not transactional, any error after collect_assets can return Err while already-moving assets or partially-written settlement state remains committed. This can strand user funds in the pallet intermediary or leave a partially settled batch. Wrap the whole batch orchestrator in a storage transaction so any later failure rolls back the prior transfers and status changes.

Suggested change
fn do_execute_batched_orders(
#[frame_support::transactional]
fn do_execute_batched_orders(


/// Attempt to execute one signed order. Returns an error on any
/// validation or execution failure without panicking.
fn try_execute_order(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

[HIGH] Single-order execution is not atomic after swap side effects

try_execute_order performs the buy/sell swap before later fallible operations such as fee forwarding and status insertion. For a buy order, buy_alpha only validates/removes tao_after_fee; if the signer has enough balance for the net swap but not the fee, the swap succeeds, forward_fee fails, execute_orders treats the order as skipped, and the order remains executable without the fee being paid. The same missing transaction also makes should_fail = true misleading: returning Err does not by itself roll back prior successful order executions. Make this helper transactional so every failed order attempt reverts its own swap/fee/status side effects.

Suggested change
fn try_execute_order(
#[frame_support::transactional]
fn try_execute_order(

@github-actions

github-actions Bot commented Jun 4, 2026

Copy link
Copy Markdown
Contributor

🔄 AI review updated — Skeptic: VULNERABLE

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

AI review — see the sticky summary comment for the verdict and the inline comments below for specific findings.

{
"scripts": {
"test": "TS_NODE_PREFER_TS_EXTS=1 TS_NODE_TRANSPILE_ONLY=1 mocha --timeout 999999 --retries 3 --file src/setup.ts --require ts-node/register --extension ts \"test/**/*.ts\""
"test": "TS_NODE_PREFER_TS_EXTS=1 TS_NODE_TRANSPILE_ONLY=1 mocha --timeout 999999 --file src/setup.ts --require ts-node/register --extension ts \"test/limitOrders.precompile.test.ts\""

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

[HIGH] Contract test script now skips the existing suite

contract-tests/run-ci.sh invokes yarn run test, so changing this script from test/**/*.ts to only test/limitOrders.precompile.test.ts makes the contract-test workflow stop running every existing contract test. That is a persistent CI bypass: future precompile or EVM regressions can merge without exercising the previous suite. Keep the broad glob so the new limit-order test is added to the suite rather than replacing it.

Suggested change
"test": "TS_NODE_PREFER_TS_EXTS=1 TS_NODE_TRANSPILE_ONLY=1 mocha --timeout 999999 --file src/setup.ts --require ts-node/register --extension ts \"test/limitOrders.precompile.test.ts\""
"test": "TS_NODE_PREFER_TS_EXTS=1 TS_NODE_TRANSPILE_ONLY=1 mocha --timeout 999999 --retries 3 --file src/setup.ts --require ts-node/register --extension ts \"test/**/*.ts\""

@github-actions

Copy link
Copy Markdown
Contributor

🔄 AI review updated — Skeptic: VULNERABLE

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

AI review — see the sticky summary comment for the verdict and the inline comments below for specific findings.

{
"scripts": {
"test": "TS_NODE_PREFER_TS_EXTS=1 TS_NODE_TRANSPILE_ONLY=1 mocha --timeout 999999 --retries 3 --file src/setup.ts --require ts-node/register --extension ts \"test/**/*.ts\""
"test": "TS_NODE_PREFER_TS_EXTS=1 TS_NODE_TRANSPILE_ONLY=1 mocha --timeout 999999 --file src/setup.ts --require ts-node/register --extension ts \"test/limitOrders.precompile.test.ts\""

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

[HIGH] Contract test script now skips the existing suite

The persistent test script now runs only test/limitOrders.precompile.test.ts, dropping the previous test/**/*.ts glob and --retries 3. Any CI or reviewer command that relies on this entrypoint will stop exercising the existing EVM contract tests, which makes future vulnerable or hostile changes easier to land unnoticed. Keep the full suite as the default entrypoint; the new limit-orders test is already included by the glob.

Suggested change
"test": "TS_NODE_PREFER_TS_EXTS=1 TS_NODE_TRANSPILE_ONLY=1 mocha --timeout 999999 --file src/setup.ts --require ts-node/register --extension ts \"test/limitOrders.precompile.test.ts\""
"test": "TS_NODE_PREFER_TS_EXTS=1 TS_NODE_TRANSPILE_ONLY=1 mocha --timeout 999999 --retries 3 --file src/setup.ts --require ts-node/register --extension ts \"test/**/*.ts\""

@github-actions

Copy link
Copy Markdown
Contributor

🔄 AI review updated — Skeptic: VULNERABLE

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

AI review — see the sticky summary comment for the verdict and the inline comments below for specific findings.

{
"scripts": {
"test": "TS_NODE_PREFER_TS_EXTS=1 TS_NODE_TRANSPILE_ONLY=1 mocha --timeout 999999 --retries 3 --file src/setup.ts --require ts-node/register --extension ts \"test/**/*.ts\""
"test": "TS_NODE_PREFER_TS_EXTS=1 TS_NODE_TRANSPILE_ONLY=1 mocha --timeout 999999 --file src/setup.ts --require ts-node/register --extension ts \"test/limitOrders.precompile.test.ts\""

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

[HIGH] Contract test script now skips the existing suite

This persistent test entrypoint no longer runs test/**/*.ts; it only runs the new limit-orders precompile test and also drops the prior retry setting. If CI or reviewers rely on yarn test in contract-tests, existing EVM/contract coverage is silently bypassed, which can let regressions in unrelated precompiles or contract flows merge under a green test job. Keep the full suite as the default entrypoint and add a narrower script if this PR needs one.

Suggested change
"test": "TS_NODE_PREFER_TS_EXTS=1 TS_NODE_TRANSPILE_ONLY=1 mocha --timeout 999999 --file src/setup.ts --require ts-node/register --extension ts \"test/limitOrders.precompile.test.ts\""
"test": "TS_NODE_PREFER_TS_EXTS=1 TS_NODE_TRANSPILE_ONLY=1 mocha --timeout 999999 --retries 3 --file src/setup.ts --require ts-node/register --extension ts \"test/**/*.ts\""

@github-actions

Copy link
Copy Markdown
Contributor

🔄 AI review updated — Skeptic: VULNERABLE

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

AI review — see the sticky summary comment for the verdict and the inline comments below for specific findings.

{
"scripts": {
"test": "TS_NODE_PREFER_TS_EXTS=1 TS_NODE_TRANSPILE_ONLY=1 mocha --timeout 999999 --retries 3 --file src/setup.ts --require ts-node/register --extension ts \"test/**/*.ts\""
"test": "TS_NODE_PREFER_TS_EXTS=1 TS_NODE_TRANSPILE_ONLY=1 mocha --timeout 999999 --file src/setup.ts --require ts-node/register --extension ts \"test/limitOrders.precompile.test.ts\""

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

[HIGH] Contract test script now skips the existing suite

contract-tests/run-ci.sh invokes yarn run test, and this change narrows that persistent CI entrypoint to only test/limitOrders.precompile.test.ts. After merge, every future contract-test run would skip the existing test/**/*.ts suite, including other EVM/precompile coverage, so regressions or hostile changes outside this new test file could pass the contract-test job. Restore the original glob and retries while adding the new limit-order test under the existing suite.

Suggested change
"test": "TS_NODE_PREFER_TS_EXTS=1 TS_NODE_TRANSPILE_ONLY=1 mocha --timeout 999999 --file src/setup.ts --require ts-node/register --extension ts \"test/limitOrders.precompile.test.ts\""
"test": "TS_NODE_PREFER_TS_EXTS=1 TS_NODE_TRANSPILE_ONLY=1 mocha --timeout 999999 --retries 3 --file src/setup.ts --require ts-node/register --extension ts \"test/**/*.ts\""

@github-actions

Copy link
Copy Markdown
Contributor

🔄 AI review updated — Skeptic: VULNERABLE

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

AI review — see the sticky summary comment for the verdict and the inline comments below for specific findings.

{
"scripts": {
"test": "TS_NODE_PREFER_TS_EXTS=1 TS_NODE_TRANSPILE_ONLY=1 mocha --timeout 999999 --retries 3 --file src/setup.ts --require ts-node/register --extension ts \"test/**/*.ts\""
"test": "TS_NODE_PREFER_TS_EXTS=1 TS_NODE_TRANSPILE_ONLY=1 mocha --timeout 999999 --file src/setup.ts --require ts-node/register --extension ts \"test/limitOrders.precompile.test.ts\""

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

[HIGH] Contract test script now skips the existing suite

The persistent test script now runs only test/limitOrders.precompile.test.ts and also drops the existing retry setting, so every other contract test under test/**/*.ts is skipped whenever CI or reviewers invoke the standard package test command. A PR should add the new limit-order coverage without narrowing the project-wide test entrypoint; otherwise regressions in the existing precompiles/contracts can merge undetected.

Suggested change
"test": "TS_NODE_PREFER_TS_EXTS=1 TS_NODE_TRANSPILE_ONLY=1 mocha --timeout 999999 --file src/setup.ts --require ts-node/register --extension ts \"test/limitOrders.precompile.test.ts\""
"test": "TS_NODE_PREFER_TS_EXTS=1 TS_NODE_TRANSPILE_ONLY=1 mocha --timeout 999999 --retries 3 --file src/setup.ts --require ts-node/register --extension ts \"test/**/*.ts\""

@github-actions

Copy link
Copy Markdown
Contributor

🔄 AI review updated — Skeptic: VULNERABLE

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

Labels

skip-cargo-audit This PR fails cargo audit but needs to be merged anyway

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants