Movy
State-of-the-art, developer-friendly, open-source move testing framework.
Install / Use
/learn @BitsLabSec/MovyREADME
Movy

Movy is a Move testing framework that offers:
- Modular low-level building bricks for Move language. Specifically, the executor and tracer abstractions and layered database design borrowed from revm that allow you to emulate and inspect an execution.
- Static analysis capabilities inherited from MoveScan, the state-of-the-art static analyzer.
- Cutting-edge fuzzing reimplemented from scratch learned from Belobog that supports both property testing and on-chain fuzzing, in the a flavor similar to foundry by writing invariants in Move language.
- And a lot of more...
Checkout our documentations at here
Movy is still in very early-alpha stage and we are working heavily for new features
Show cases
Trace a Transaction
let mut tracer = TreeTracer::new();
let _ = executor.run_tx_trace(
tx,
epoch,
timestamp_ms,
Some(tracer),
)?;
println!("The trace is:\n{}", trace.take_inner().pprint());
This snippet traces an arbitrary transaction tx, either on-chain or built by yourself.
Invariants Testing
Deploy your Move modules in a single function, even if it requires multiple transactions.
public fun movy_init(
deployer: address,
attacker: address
) {
let mut scenario = ts::begin(deployer);
{
ts::next_tx(&mut scenario, deployer);
counter::create(ts::ctx(&mut scenario));
};
ts::next_tx(&mut scenario, attacker);
{
let mut counter_val = ts::take_shared<Counter>(&scenario);
counter::increment(&mut counter_val, 0);
assert!(counter::value(&counter_val) == 1, 0);
ts::return_shared(counter_val);
};
ts::end(scenario);
}
Write an invariant test for your functions in a Move testing module:
#[test]
public fun movy_pre_increment(
movy: &mut context::MovyContext,
ctr: &mut Counter,
_n: u64
) {
let (ctr_id, val) = extract_counter(ctr);
let state = context::borrow_mut_state(movy);
bag::add(state, ctr_id, val);
}
#[test]
public fun movy_post_increment(
movy: &mut context::MovyContext,
ctr: &mut Counter,
n: u64
) {
let (ctr_id, new_val) = extract_counter(ctr);
let state = context::borrow_state(movy);
let previous_val = bag::borrow<ID, u64>(state, ctr_id);
if (*previous_val + n != new_val) {
crash_because(b"Increment does not correctly inreases internal value.".to_string());
}
}
Call Graph and Type Graph
Generate a type graph for a move package.
Generate a call graph for a move package.
Static Analysis
TODO.
Usage
Use Movy as a Tool
Install dependencies:
apt install -y libssl-dev libclang-dev
Build movy binaries.
git clone https://github.com/BitsLabSec/movy
cd movy
cargo build --release
Note a stable rust toolchain should be present.
Check the usage menu.
./target/release/movy --help
Use Movy as a Library
Add this to your Cargo.toml
movy = {git = "https://github.com/BitsLabSec/movy", branch = "master"}
Unfortunately, both sui and aptos are not on crates.io so we can not publish crates at this moment, unless we fully re-implement the MoveVM for both chains.
Write Invariants
To write invariants for contracts, see the counter sample. Note you need to add the line to your Move.toml. It is test dependency and will be never live on-chain.
[dev-dependencies]
movy = {git = "https://github.com/BitsLabSec/movy", subdir = "move/movy", rev = "master"}
Contritubions
Movy is very open to contributions! We expect your feedbacks and pull requests. See the roadmap or contact us for further information.
Roadmap
At this moment, movy is in very early-alpha state with the folloing features missing:
- Upstream our changes to sui and aptos-core
- Full Aptos support. (We have a private branch for that but still figuring out a good API design.)
- On-chain incidents backtesting.
Credits
Belobog is inspired by several pioneering projects:
Related Skills
node-connect
345.4kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
104.6kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
openai-whisper-api
345.4kTranscribe audio via OpenAI Audio Transcriptions API (Whisper).
qqbot-media
345.4kQQBot 富媒体收发能力。使用 <qqmedia> 标签,系统根据文件扩展名自动识别类型(图片/语音/视频/文件)。
