Skip to content

Commit

Permalink
Merge pull request MystenLabs#162 from lxfind/no-transfer-immutable
Browse files Browse the repository at this point in the history
Enforce object mutability in move calls
  • Loading branch information
lxfind authored Jan 12, 2022
2 parents 08254db + cf30200 commit e438a5e
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 3 deletions.
18 changes: 16 additions & 2 deletions fastx_programmability/adapter/src/adapter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -431,7 +431,14 @@ fn resolve_and_type_check(
// check that m.type_ matches the parameter types of the function
match &param_type {
Type::MutableReference(inner_t) => {
// (https://github.com/MystenLabs/fastnft/issues/96): check m.mutability
if m.is_read_only() {
return Err(FastPayError::TypeError {
error: format!(
"Argument {} is expected to be mutable, immutable object found",
idx
),
});
}
type_check_struct(&m.type_, inner_t)?;
mutable_ref_objects.push(object);
}
Expand All @@ -443,7 +450,14 @@ fn resolve_and_type_check(
}
}
Type::Struct { .. } => {
// TODO(https://github.com/MystenLabs/fastnft/issues/96): check m.mutability
if m.is_read_only() {
return Err(FastPayError::TypeError {
error: format!(
"Argument {} is expected to be mutable, immutable object found",
idx
),
});
}
type_check_struct(&m.type_, &param_type)?;
let res = by_value_objects.insert(object.id(), object);
// should always pass due to earlier "no duplicate ID's" check
Expand Down
35 changes: 34 additions & 1 deletion fastx_programmability/adapter/src/unit_tests/adapter_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -521,7 +521,7 @@ fn test_transfer_and_freeze() {
&mut storage,
&native_functions,
"transfer_and_freeze",
gas_object,
gas_object.clone(),
MAX_GAS,
vec![obj1],
pure_args,
Expand All @@ -532,6 +532,39 @@ fn test_transfer_and_freeze() {
let obj1 = storage.read_object(&id1).unwrap();
assert!(obj1.is_read_only());
assert_eq!(obj1.owner, addr2);

// 3. Call transfer again and it should fail.
let pure_args = vec![bcs::to_bytes(&addr1.to_vec()).unwrap()];
let result = call(
&mut storage,
&native_functions,
"transfer",
gas_object.clone(),
MAX_GAS,
vec![obj1],
pure_args,
);
assert!(result
.unwrap_err()
.to_string()
.contains("Argument 0 is expected to be mutable, immutable object found"));

// 4. Call set_value (pass as mutable reference) should fail as well.
let obj1 = storage.read_object(&id1).unwrap();
let pure_args = vec![bcs::to_bytes(&1u64).unwrap()];
let result = call(
&mut storage,
&native_functions,
"set_value",
gas_object.clone(),
MAX_GAS,
vec![obj1],
pure_args,
);
assert!(result
.unwrap_err()
.to_string()
.contains("Argument 0 is expected to be mutable, immutable object found"));
}

// TODO(https://github.com/MystenLabs/fastnft/issues/92): tests that exercise all the error codes of the adapter
4 changes: 4 additions & 0 deletions fastx_programmability/framework/sources/ObjectBasics.move
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ module FastX::ObjectBasics {
Transfer::transfer_and_freeze(o, Address::new(recipient))
}

public fun set_value(o: &mut Object, value: u64, _ctx: &mut TxContext) {
o.value = value;
}

// test that reading o2 and updating o1 works
public fun update(o1: &mut Object, o2: &Object, _ctx: &mut TxContext) {
o1.value = o2.value
Expand Down

0 comments on commit e438a5e

Please sign in to comment.