Loading...
Loading...
Compare original and translation side by side
entryobject::owner()// ✅ CORRECT: Signer verification
public entry fun update_config(admin: &signer, value: u64) acquires Config {
let config = borrow_global<Config>(@my_addr);
assert!(signer::address_of(admin) == config.admin, E_NOT_ADMIN);
// Safe to proceed
}
// ❌ WRONG: No verification
public entry fun update_config(admin: &signer, value: u64) acquires Config {
let config = borrow_global_mut<Config>(@my_addr);
config.value = value; // Anyone can call!
}// ✅ CORRECT: Ownership verification
public entry fun transfer_item(
owner: &signer,
item: Object<Item>,
to: address
) acquires Item {
assert!(object::owner(item) == signer::address_of(owner), E_NOT_OWNER);
// Safe to transfer
}
// ❌ WRONG: No ownership check
public entry fun transfer_item(
owner: &signer,
item: Object<Item>,
to: address
) acquires Item {
// Anyone can transfer any item!
}entryobject::owner()// ✅ CORRECT: Signer verification
public entry fun update_config(admin: &signer, value: u64) acquires Config {
let config = borrow_global<Config>(@my_addr);
assert!(signer::address_of(admin) == config.admin, E_NOT_ADMIN);
// Safe to proceed
}
// ❌ WRONG: No verification
public entry fun update_config(admin: &signer, value: u64) acquires Config {
let config = borrow_global_mut<Config>(@my_addr);
config.value = value; // Anyone can call!
}// ✅ CORRECT: Ownership verification
public entry fun transfer_item(
owner: &signer,
item: Object<Item>,
to: address
) acquires Item {
assert!(object::owner(item) == signer::address_of(owner), E_NOT_OWNER);
// Safe to transfer
}
// ❌ WRONG: No ownership check
public entry fun transfer_item(
owner: &signer,
item: Object<Item>,
to: address
) acquires Item {
// Anyone can transfer any item!
}assert!(amount > 0, E_ZERO_AMOUNT)assert!(amount <= MAX, E_AMOUNT_TOO_HIGH)assert!(vector::length(&v) > 0, E_EMPTY_VECTOR)assert!(string::length(&s) <= MAX_LENGTH, E_NAME_TOO_LONG)assert!(addr != @0x0, E_ZERO_ADDRESS)assert!(type_id < MAX_TYPES, E_INVALID_TYPE)// ✅ CORRECT: Comprehensive validation
public entry fun deposit(user: &signer, amount: u64) acquires Account {
assert!(amount > 0, E_ZERO_AMOUNT);
assert!(amount <= MAX_DEPOSIT_AMOUNT, E_AMOUNT_TOO_HIGH);
let account = borrow_global_mut<Account>(signer::address_of(user));
assert!(account.balance <= MAX_U64 - amount, E_OVERFLOW);
account.balance = account.balance + amount;
}
// ❌ WRONG: No validation
public entry fun deposit(user: &signer, amount: u64) acquires Account {
let account = borrow_global_mut<Account>(signer::address_of(user));
account.balance = account.balance + amount; // Can overflow!
}assert!(amount > 0, E_ZERO_AMOUNT)assert!(amount <= MAX, E_AMOUNT_TOO_HIGH)assert!(vector::length(&v) > 0, E_EMPTY_VECTOR)assert!(string::length(&s) <= MAX_LENGTH, E_NAME_TOO_LONG)assert!(addr != @0x0, E_ZERO_ADDRESS)assert!(type_id < MAX_TYPES, E_INVALID_TYPE)// ✅ CORRECT: Comprehensive validation
public entry fun deposit(user: &signer, amount: u64) acquires Account {
assert!(amount > 0, E_ZERO_AMOUNT);
assert!(amount <= MAX_DEPOSIT_AMOUNT, E_AMOUNT_TOO_HIGH);
let account = borrow_global_mut<Account>(signer::address_of(user));
assert!(account.balance <= MAX_U64 - amount, E_OVERFLOW);
account.balance = account.balance + amount;
}
// ❌ WRONG: No validation
public entry fun deposit(user: &signer, amount: u64) acquires Account {
let account = borrow_global_mut<Account>(signer::address_of(user));
account.balance = account.balance + amount; // Can overflow!
}// ❌ DANGEROUS: Returning ConstructorRef
public fun create_item(): ConstructorRef {
let constructor_ref = object::create_object(@my_addr);
constructor_ref // Caller can destroy object!
}
// ✅ CORRECT: Return Object<T>
public fun create_item(creator: &signer): Object<Item> {
let constructor_ref = object::create_object(signer::address_of(creator));
let transfer_ref = object::generate_transfer_ref(&constructor_ref);
let delete_ref = object::generate_delete_ref(&constructor_ref);
let object_signer = object::generate_signer(&constructor_ref);
move_to(&object_signer, Item { transfer_ref, delete_ref });
object::object_from_constructor_ref<Item>(&constructor_ref)
}// ❌ DANGEROUS: Returning ConstructorRef
public fun create_item(): ConstructorRef {
let constructor_ref = object::create_object(@my_addr);
constructor_ref // Caller can destroy object!
}
// ✅ CORRECT: Return Object<T>
public fun create_item(creator: &signer): Object<Item> {
let constructor_ref = object::create_object(signer::address_of(creator));
let transfer_ref = object::generate_transfer_ref(&constructor_ref);
let delete_ref = object::generate_delete_ref(&constructor_ref);
let object_signer = object::generate_signer(&constructor_ref);
move_to(&object_signer, Item { transfer_ref, delete_ref });
object::object_from_constructor_ref<Item>(&constructor_ref)
}&mutmem::swap// ❌ DANGEROUS: Exposing mutable reference
public fun get_item_mut(item: Object<Item>): &mut Item acquires Item {
borrow_global_mut<Item>(object::object_address(&item))
// Caller can mem::swap fields!
}
// ✅ CORRECT: Controlled mutations
public entry fun update_item_name(
owner: &signer,
item: Object<Item>,
new_name: String
) acquires Item {
assert!(object::owner(item) == signer::address_of(owner), E_NOT_OWNER);
let item_data = borrow_global_mut<Item>(object::object_address(&item));
item_data.name = new_name;
}&mutmem::swap// ❌ DANGEROUS: Exposing mutable reference
public fun get_item_mut(item: Object<Item>): &mut Item acquires Item {
borrow_global_mut<Item>(object::object_address(&item))
// Caller can mem::swap fields!
}
// ✅ CORRECT: Controlled mutations
public entry fun update_item_name(
owner: &signer,
item: Object<Item>,
new_name: String
) acquires Item {
assert!(object::owner(item) == signer::address_of(owner), E_NOT_OWNER);
let item_data = borrow_global_mut<Item>(object::object_address(&item));
item_data.name = new_name;
}// ✅ CORRECT: Overflow protection
public entry fun deposit(user: &signer, amount: u64) acquires Account {
let account = borrow_global_mut<Account>(signer::address_of(user));
// Check overflow BEFORE adding
assert!(account.balance <= MAX_U64 - amount, E_OVERFLOW);
account.balance = account.balance + amount;
}
// ✅ CORRECT: Underflow protection
public entry fun withdraw(user: &signer, amount: u64) acquires Account {
let account = borrow_global_mut<Account>(signer::address_of(user));
// Check underflow BEFORE subtracting
assert!(account.balance >= amount, E_INSUFFICIENT_BALANCE);
account.balance = account.balance - amount;
}
// ❌ WRONG: No overflow check
public entry fun deposit(user: &signer, amount: u64) acquires Account {
let account = borrow_global_mut<Account>(signer::address_of(user));
account.balance = account.balance + amount; // Can overflow!
}// ✅ CORRECT: Overflow protection
public entry fun deposit(user: &signer, amount: u64) acquires Account {
let account = borrow_global_mut<Account>(signer::address_of(user));
// Check overflow BEFORE adding
assert!(account.balance <= MAX_U64 - amount, E_OVERFLOW);
account.balance = account.balance + amount;
}
// ✅ CORRECT: Underflow protection
public entry fun withdraw(user: &signer, amount: u64) acquires Account {
let account = borrow_global_mut<Account>(signer::address_of(user));
// Check underflow BEFORE subtracting
assert!(account.balance >= amount, E_INSUFFICIENT_BALANCE);
account.balance = account.balance - amount;
}
// ❌ WRONG: No overflow check
public entry fun deposit(user: &signer, amount: u64) acquires Account {
let account = borrow_global_mut<Account>(signer::address_of(user));
account.balance = account.balance + amount; // Can overflow!
}struct Vault<phantom CoinType><T: copy + drop>// ✅ CORRECT: Phantom type for safety
struct Vault<phantom CoinType> has key {
balance: u64,
// CoinType only for type safety, not stored
}
public fun deposit<CoinType>(vault: Object<Vault<CoinType>>, amount: u64) {
// Type-safe: can't deposit BTC into USDC vault
}
// ❌ WRONG: No phantom (won't compile if CoinType not in fields)
struct Vault<CoinType> has key {
balance: u64,
}struct Vault<phantom CoinType><T: copy + drop>// ✅ CORRECT: Phantom type for safety
struct Vault<phantom CoinType> has key {
balance: u64,
// CoinType only for type safety, not stored
}
public fun deposit<CoinType>(vault: Object<Vault<CoinType>>, amount: u64) {
// Type-safe: can't deposit BTC into USDC vault
}
// ❌ WRONG: No phantom (won't compile if CoinType not in fields)
struct Vault<CoinType> has key {
balance: u64,
}aptos move test --coverage#[expected_failure]aptos move test --coverage
aptos move coverage source --module <module_name>aptos move test --coverage#[expected_failure]aptos move test --coverage
aptos move coverage source --module <module_name>undefinedundefinedundefinedundefined| Vulnerability | Detection | Impact | Fix |
|---|---|---|---|
| Missing access control | No | Critical - anyone can call | Add signer verification |
| Missing ownership check | No | Critical - anyone can modify any object | Add ownership check |
| Integer overflow | No check before addition | Critical - balance wraps to 0 | Check |
| Integer underflow | No check before subtraction | Critical - balance wraps to MAX | Check |
| Returning ConstructorRef | Function returns ConstructorRef | Critical - caller can destroy object | Return |
| Exposing &mut | Public function returns | High - mem::swap attacks | Expose specific operations only |
| No input validation | Accept any value | Medium - zero amounts, overflow | Validate all inputs |
| Low test coverage | Coverage < 100% | Medium - bugs in production | Write more tests |
| 漏洞类型 | 检测方式 | 影响 | 修复方案 |
|---|---|---|---|
| 缺失访问控制 | entry函数中没有 | 严重 - 任何人都可以调用 | 添加签名者验证 |
| 缺失所有权检查 | 没有 | 严重 - 任何人都可以修改任意对象 | 添加所有权检查 |
| 整数溢出 | 加法前没有检查 | 严重 - 余额归零 | 检查 |
| 整数下溢 | 减法前没有检查 | 严重 - 余额变为最大值 | 检查 |
| 返回ConstructorRef | 函数返回ConstructorRef | 严重 - 调用者可以销毁对象 | 改为返回 |
| 暴露可变引用 | 公共函数返回 | 高危 - 存在mem::swap攻击风险 | 仅暴露特定操作接口 |
| 无输入验证 | 接受任意值 | 中危 - 零金额、溢出等问题 | 校验所有输入 |
| 测试覆盖率低 | 覆盖率<100% | 中危 - 生产环境存在bug | 补充更多测试用例 |
undefinedundefinedundefinedundefinedentry funborrow_global_mutamountlengthaddressConstructorRefcreate_object+-/entry funborrow_global_mutamountlengthaddressConstructorRefcreate_object+-/~/.aptos/config.yaml.env~/.aptos/config.yaml.env../../../patterns/move/SECURITY.md../../../patterns/move/OBJECTS.mdgenerate-testswrite-contractsdeploy-contracts../../../patterns/move/SECURITY.md../../../patterns/move/OBJECTS.mdgenerate-testswrite-contractsdeploy-contracts