Ver código fonte

Enfore the payable attribute on Solana

Functions or constructors not marked payable should abort if value is
transferred to them.

Note that on EVM, the check for value is done very early, to avoid
wasting gas on any work before aborting. Since on Solana this error
is fatal to the transaction anyway, this check can be done later.

Signed-off-by: Sean Young <sean@mess.org>
Sean Young 4 anos atrás
pai
commit
09842bccd5

+ 22 - 13
src/emit/mod.rs

@@ -335,38 +335,47 @@ pub trait TargetRuntime<'a> {
     /// Helper functions which need access to the trait
 
     /// If we receive a value transfer, and we are "payable", abort with revert
-    fn abort_if_value_transfer(&self, bin: &Binary, function: FunctionValue, ns: &ast::Namespace) {
-        let value = self.value_transferred(bin, ns);
+    fn abort_if_value_transfer(
+        &self,
+        binary: &Binary,
+        function: FunctionValue,
+        ns: &ast::Namespace,
+    ) {
+        let value = self.value_transferred(binary, ns);
 
-        let got_value = bin.builder.build_int_compare(
+        let got_value = binary.builder.build_int_compare(
             IntPredicate::NE,
             value,
-            bin.value_type(ns).const_zero(),
+            binary.value_type(ns).const_zero(),
             "is_value_transfer",
         );
 
-        let not_value_transfer = bin
+        let not_value_transfer = binary
             .context
             .append_basic_block(function, "not_value_transfer");
-        let abort_value_transfer = bin
+        let abort_value_transfer = binary
             .context
             .append_basic_block(function, "abort_value_transfer");
 
-        bin.builder
-            .build_conditional_branch(got_value, abort_value_transfer, not_value_transfer);
+        binary.builder.build_conditional_branch(
+            got_value,
+            abort_value_transfer,
+            not_value_transfer,
+        );
 
-        bin.builder.position_at_end(abort_value_transfer);
+        binary.builder.position_at_end(abort_value_transfer);
 
         self.assert_failure(
-            bin,
-            bin.context
+            binary,
+            binary
+                .context
                 .i8_type()
                 .ptr_type(AddressSpace::Generic)
                 .const_null(),
-            bin.context.i32_type().const_zero(),
+            binary.context.i32_type().const_zero(),
         );
 
-        bin.builder.position_at_end(not_value_transfer);
+        binary.builder.position_at_end(not_value_transfer);
     }
 
     /// Recursively load a type from bin storage

+ 9 - 1
src/emit/solana.rs

@@ -511,7 +511,7 @@ impl SolanaTarget {
                 dispatch_function,
                 &contract.functions,
                 None,
-                |_| false,
+                |func| func.nonpayable,
             );
 
             let function_block = binary
@@ -649,6 +649,14 @@ impl SolanaTarget {
                 "",
             );
 
+            // is there a not a payable constructor
+            if !contract.contract.functions.iter().any(|function_no| {
+                let f = &contract.ns.functions[*function_no];
+                f.is_constructor() && f.is_payable()
+            }) {
+                self.abort_if_value_transfer(binary, function, contract.ns);
+            }
+
             // There is only one possible constructor
             let ret = if let Some((constructor_function, params)) = contract.constructor {
                 let mut args = Vec::new();

+ 2 - 2
tests/solana.rs

@@ -1253,12 +1253,12 @@ impl VirtualMachine {
         assert_eq!(res, 0);
     }
 
-    fn constructor(&mut self, name: &str, args: &[Token]) {
+    fn constructor(&mut self, name: &str, args: &[Token], value: u64) {
         let program = &self.stack[0];
 
         println!("constructor for {}", hex::encode(&program.data));
 
-        let mut calldata = VirtualMachine::input(&program.data, &account_new(), 0, name, &[]);
+        let mut calldata = VirtualMachine::input(&program.data, &account_new(), value, name, &[]);
 
         if let Some(constructor) = &program.abi.as_ref().unwrap().constructor {
             calldata.extend(&constructor.encode_input(vec![], args).unwrap());

+ 3 - 3
tests/solana_tests/abi.rs

@@ -35,7 +35,7 @@ fn packed() {
         }"#,
     );
 
-    vm.constructor("bar", &[]);
+    vm.constructor("bar", &[], 0);
 
     vm.function("test", &[], &[], 0);
     vm.function("test2", &[], &[], 0);
@@ -54,7 +54,7 @@ fn inherited() {
         }"#,
     );
 
-    vm.constructor("bar", &[]);
+    vm.constructor("bar", &[], 0);
 
     vm.function("test", &[], &[], 0);
 
@@ -67,7 +67,7 @@ fn inherited() {
             }"#,
     );
 
-    vm.constructor("bar", &[]);
+    vm.constructor("bar", &[], 0);
 
     vm.function("test", &[], &[], 0);
 }

+ 8 - 8
tests/solana_tests/accessor.rs

@@ -10,7 +10,7 @@ fn types() {
         }"#,
     );
 
-    vm.constructor("foo", &[]);
+    vm.constructor("foo", &[], 0);
 
     let returns = vm.function("f1", &[], &[], 0);
 
@@ -23,7 +23,7 @@ fn types() {
         }"#,
     );
 
-    vm.constructor("foo", &[]);
+    vm.constructor("foo", &[], 0);
 
     let returns = vm.function("f1", &[Token::Uint(ethereum_types::U256::from(2))], &[], 0);
 
@@ -43,7 +43,7 @@ fn types() {
         }"#,
     );
 
-    vm.constructor("foo", &[]);
+    vm.constructor("foo", &[], 0);
 
     let returns = vm.function(
         "f1",
@@ -69,7 +69,7 @@ fn types() {
         }"#,
     );
 
-    vm.constructor("foo", &[]);
+    vm.constructor("foo", &[], 0);
 
     let returns = vm.function(
         "f1",
@@ -95,7 +95,7 @@ fn interfaces() {
         "#,
     );
 
-    vm.constructor("foo", &[]);
+    vm.constructor("foo", &[], 0);
 
     let returns = vm.function("f1", &[], &[], 0);
 
@@ -111,7 +111,7 @@ fn constant() {
         }"#,
     );
 
-    vm.constructor("x", &[]);
+    vm.constructor("x", &[], 0);
 
     let returns = vm.function("z", &[], &[], 0);
 
@@ -130,7 +130,7 @@ fn constant() {
         }"#,
     );
 
-    vm.constructor("x", &[]);
+    vm.constructor("x", &[], 0);
 
     let returns = vm.function("z", &[], &[], 0);
 
@@ -149,7 +149,7 @@ fn constant() {
         }"#,
     );
 
-    vm.constructor("x", &[]);
+    vm.constructor("x", &[], 0);
 
     let returns = vm.function("z", &[], &[], 0);
 

+ 11 - 11
tests/solana_tests/arrays.rs

@@ -17,7 +17,7 @@ fn fixed_array() {
         }"#,
     );
 
-    vm.constructor("foo", &[]);
+    vm.constructor("foo", &[], 0);
 
     let returns = vm.function("get", &[], &[], 0);
 
@@ -51,7 +51,7 @@ fn fixed_array() {
         }"#,
     );
 
-    vm.constructor("foo", &[]);
+    vm.constructor("foo", &[], 0);
 
     let returns = vm.function("get", &[], &[], 0);
 
@@ -108,7 +108,7 @@ fn fixed_array() {
         }"#,
     );
 
-    vm.constructor("foo", &[]);
+    vm.constructor("foo", &[], 0);
 
     let returns = vm.function("get", &[], &[], 0);
 
@@ -173,7 +173,7 @@ fn dynamic_array_fixed_elements() {
         }"#,
     );
 
-    vm.constructor("foo", &[]);
+    vm.constructor("foo", &[], 0);
 
     let returns = vm.function(
         "get",
@@ -242,7 +242,7 @@ fn fixed_array_dynamic_elements() {
         }"#,
     );
 
-    vm.constructor("foo", &[]);
+    vm.constructor("foo", &[], 0);
 
     let returns = vm.function(
         "get",
@@ -311,7 +311,7 @@ fn dynamic_array_dynamic_elements() {
         }"#,
     );
 
-    vm.constructor("foo", &[]);
+    vm.constructor("foo", &[], 0);
 
     let returns = vm.function(
         "get",
@@ -377,7 +377,7 @@ fn fixed_array_fixed_elements_storage() {
         }"#,
     );
 
-    vm.constructor("foo", &[]);
+    vm.constructor("foo", &[], 0);
 
     vm.function(
         "set_elem",
@@ -491,7 +491,7 @@ fn fixed_array_dynamic_elements_storage() {
         }"#,
     );
 
-    vm.constructor("foo", &[]);
+    vm.constructor("foo", &[], 0);
 
     vm.function(
         "set_elem",
@@ -618,7 +618,7 @@ fn storage_simple_dynamic_array() {
         }"#,
     );
 
-    vm.constructor("foo", &[]);
+    vm.constructor("foo", &[], 0);
 
     let returns = vm.function("len", &[], &[], 0);
 
@@ -743,7 +743,7 @@ fn storage_pop_running_on_empty() {
         }"#,
     );
 
-    vm.constructor("foo", &[]);
+    vm.constructor("foo", &[], 0);
 
     vm.function("pop", &[], &[], 0);
 }
@@ -800,7 +800,7 @@ fn storage_dynamic_array_of_structs() {
         }"#,
     );
 
-    vm.constructor("foo", &[]);
+    vm.constructor("foo", &[], 0);
 
     let returns = vm.function("len", &[], &[], 0);
 

+ 39 - 1
tests/solana_tests/balance.rs

@@ -12,9 +12,47 @@ fn msg_value() {
         }"#,
     );
 
-    vm.constructor("c", &[]);
+    vm.constructor("c", &[], 0);
 
     let returns = vm.function("test", &[], &[], 102);
 
     assert_eq!(returns[0], Token::Uint(ethereum_types::U256::from(306)));
 }
+
+#[test]
+#[should_panic(expected = "4294967296")]
+fn default_constructor_not_payable() {
+    let mut vm = build_solidity(r#"contract c {}"#);
+
+    vm.constructor("c", &[], 1);
+}
+
+#[test]
+#[should_panic(expected = "4294967296")]
+fn constructor_not_payable() {
+    let mut vm = build_solidity(
+        r#"
+        contract c {
+            constructor () {}
+        }
+    "#,
+    );
+
+    vm.constructor("c", &[], 1);
+}
+
+#[test]
+#[should_panic(expected = "4294967296")]
+fn function_not_payable() {
+    let mut vm = build_solidity(
+        r#"
+        contract c {
+            function test() public {}
+        }
+    "#,
+    );
+
+    vm.constructor("c", &[], 0);
+
+    vm.function("test", &[], &[], 102);
+}

+ 1 - 1
tests/solana_tests/builtin.rs

@@ -18,7 +18,7 @@ fn timestamp() {
         }"#,
     );
 
-    vm.constructor("timestamp", &[]);
+    vm.constructor("timestamp", &[], 0);
 
     let returns = vm.function("mr_now", &[], &[], 0);
 

+ 8 - 8
tests/solana_tests/call.rs

@@ -77,7 +77,7 @@ fn simple_external_call() {
         }"#,
     );
 
-    vm.constructor("bar1", &[]);
+    vm.constructor("bar1", &[], 0);
 
     vm.function("test_bar", &[Token::String(String::from("yo"))], &[], 0);
 
@@ -89,7 +89,7 @@ fn simple_external_call() {
 
     vm.set_program(0);
 
-    vm.constructor("bar0", &[]);
+    vm.constructor("bar0", &[], 0);
 
     vm.function(
         "test_bar",
@@ -129,7 +129,7 @@ fn external_call_with_returns() {
         }"#,
     );
 
-    vm.constructor("bar1", &[]);
+    vm.constructor("bar1", &[], 0);
 
     let res = vm.function(
         "test_bar",
@@ -144,7 +144,7 @@ fn external_call_with_returns() {
 
     vm.set_program(0);
 
-    vm.constructor("bar0", &[]);
+    vm.constructor("bar0", &[], 0);
 
     let res = vm.function(
         "test_other",
@@ -180,7 +180,7 @@ fn external_raw_call_with_returns() {
         }"#,
     );
 
-    vm.constructor("bar1", &[]);
+    vm.constructor("bar1", &[], 0);
 
     let res = vm.function(
         "test_bar",
@@ -195,7 +195,7 @@ fn external_raw_call_with_returns() {
 
     vm.set_program(0);
 
-    vm.constructor("bar0", &[]);
+    vm.constructor("bar0", &[], 0);
 
     let res = vm.function(
         "test_other",
@@ -243,7 +243,7 @@ fn external_call_with_string_returns() {
         }"#,
     );
 
-    vm.constructor("bar1", &[]);
+    vm.constructor("bar1", &[], 0);
 
     let res = vm.function(
         "test_bar",
@@ -258,7 +258,7 @@ fn external_call_with_string_returns() {
 
     vm.set_program(0);
 
-    vm.constructor("bar0", &[]);
+    vm.constructor("bar0", &[], 0);
 
     let bar0_account = vm.stack[0].data;
 

+ 3 - 3
tests/solana_tests/create_contract.rs

@@ -31,7 +31,7 @@ fn simple_create_contract() {
 
     vm.set_program(0);
 
-    vm.constructor("bar0", &[]);
+    vm.constructor("bar0", &[], 0);
 
     let seed = vm.create_empty_account();
 
@@ -84,7 +84,7 @@ fn missing_contract() {
 
     vm.set_program(0);
 
-    vm.constructor("bar0", &[]);
+    vm.constructor("bar0", &[], 0);
 
     let _ = vm.function("test_other", &[], &[], 0);
 }
@@ -111,7 +111,7 @@ fn two_contracts() {
 
     vm.set_program(0);
 
-    vm.constructor("bar0", &[]);
+    vm.constructor("bar0", &[], 0);
 
     let seed1 = vm.create_empty_account();
     let seed2 = vm.create_empty_account();

+ 1 - 1
tests/solana_tests/destructure.rs

@@ -15,7 +15,7 @@ fn conditional_destructure() {
         }"#,
     );
 
-    vm.constructor("foo", &[]);
+    vm.constructor("foo", &[], 0);
 
     let returns = vm.function("f", &[Token::Bool(true), Token::Bool(true)], &[], 0);
 

+ 2 - 2
tests/solana_tests/events.rs

@@ -15,7 +15,7 @@ fn simple_event() {
         }"#,
     );
 
-    vm.constructor("c", &[]);
+    vm.constructor("c", &[], 0);
 
     vm.function("go", &[], &[], 0);
 
@@ -64,7 +64,7 @@ fn less_simple_event() {
         }"#,
     );
 
-    vm.constructor("c", &[]);
+    vm.constructor("c", &[], 0);
 
     vm.function("go", &[], &[], 0);
 

+ 1 - 1
tests/solana_tests/expressions.rs

@@ -33,7 +33,7 @@ fn interfaceid() {
         }"#,
     );
 
-    vm.constructor("foo", &[]);
+    vm.constructor("foo", &[], 0);
 
     let returns = vm.function("get", &[], &[], 0);
 

+ 6 - 6
tests/solana_tests/hash.rs

@@ -15,7 +15,7 @@ fn constants_hash_tests() {
         }"##,
     );
 
-    runtime.constructor("tester", &[]);
+    runtime.constructor("tester", &[], 0);
     runtime.function("test", &[], &[], 0);
 
     let mut runtime = build_solidity(
@@ -29,7 +29,7 @@ fn constants_hash_tests() {
         }"##,
     );
 
-    runtime.constructor("tester", &[]);
+    runtime.constructor("tester", &[], 0);
     runtime.function("test", &[], &[], 0);
 
     let mut runtime = build_solidity(
@@ -43,7 +43,7 @@ fn constants_hash_tests() {
         }"##,
     );
 
-    runtime.constructor("tester", &[]);
+    runtime.constructor("tester", &[], 0);
     runtime.function("test", &[], &[], 0);
 
     // blake2 hash functions are substrate isms. Ensure they don't exist
@@ -95,7 +95,7 @@ fn hash_tests() {
         }"##,
     );
 
-    runtime.constructor("tester", &[]);
+    runtime.constructor("tester", &[], 0);
     let hash = runtime.function("test", &[Token::Bytes(b"Hello, World!".to_vec())], &[], 0);
 
     assert_eq!(
@@ -116,7 +116,7 @@ fn hash_tests() {
         }"##,
     );
 
-    runtime.constructor("tester", &[]);
+    runtime.constructor("tester", &[], 0);
     let hash = runtime.function("test", &[Token::Bytes(b"Hello, World!".to_vec())], &[], 0);
 
     assert_eq!(
@@ -138,7 +138,7 @@ fn hash_tests() {
         }"##,
     );
 
-    runtime.constructor("tester", &[]);
+    runtime.constructor("tester", &[], 0);
     let hash = runtime.function("test", &[Token::Bytes(b"Hello, World!".to_vec())], &[], 0);
 
     assert_eq!(

+ 6 - 6
tests/solana_tests/mappings.rs

@@ -22,7 +22,7 @@ fn simple_mapping() {
         }"#,
     );
 
-    vm.constructor("foo", &[]);
+    vm.constructor("foo", &[], 0);
 
     for i in 0..10 {
         vm.function(
@@ -115,7 +115,7 @@ fn less_simple_mapping() {
         }"#,
     );
 
-    vm.constructor("foo", &[]);
+    vm.constructor("foo", &[], 0);
 
     vm.function(
         "set_string",
@@ -183,7 +183,7 @@ fn string_mapping() {
         }"#,
     );
 
-    vm.constructor("foo", &[]);
+    vm.constructor("foo", &[], 0);
 
     vm.function(
         "set_string",
@@ -227,7 +227,7 @@ fn mapping_in_mapping() {
         }"#,
     );
 
-    vm.constructor("foo", &[]);
+    vm.constructor("foo", &[], 0);
 
     vm.function(
         "set",
@@ -307,7 +307,7 @@ fn sparse_array() {
         }"#,
     );
 
-    vm.constructor("foo", &[]);
+    vm.constructor("foo", &[], 0);
 
     vm.function(
         "set_string",
@@ -373,7 +373,7 @@ fn massive_sparse_array() {
         }"#,
     );
 
-    vm.constructor("foo", &[]);
+    vm.constructor("foo", &[], 0);
 
     vm.function(
         "set_string",

+ 8 - 8
tests/solana_tests/primitives.rs

@@ -23,7 +23,7 @@ fn assert_false() {
         }"#,
     );
 
-    vm.constructor("foo", &[]);
+    vm.constructor("foo", &[], 0);
 
     vm.function("assert_fails", &[], &[], 0);
 }
@@ -40,7 +40,7 @@ fn assert_true() {
         }"#,
     );
 
-    vm.constructor("foo", &[]);
+    vm.constructor("foo", &[], 0);
 
     vm.function("assert_fails", &[], &[], 0);
 }
@@ -72,7 +72,7 @@ fn boolean() {
         }"#,
     );
 
-    vm.constructor("foo", &[]);
+    vm.constructor("foo", &[], 0);
 
     let returns = vm.function("return_true", &[], &[], 0);
 
@@ -106,7 +106,7 @@ fn address() {
         }"#,
     );
 
-    vm.constructor("foo", &[]);
+    vm.constructor("foo", &[], 0);
 
     let returns = vm.function("return_address", &[], &[], 0);
 
@@ -150,7 +150,7 @@ fn test_enum() {
         }"#,
     );
 
-    vm.constructor("foo", &[]);
+    vm.constructor("foo", &[], 0);
 
     let returns = vm.function("return_enum", &[], &[], 0);
 
@@ -206,7 +206,7 @@ fn bytes() {
 
         let mut vm = build_solidity(&src);
 
-        vm.constructor("test", &[]);
+        vm.constructor("test", &[], 0);
 
         let returns = vm.function("return_literal", &[], &[], 0);
 
@@ -393,7 +393,7 @@ fn uint() {
 
         let mut vm = build_solidity(&src);
 
-        vm.constructor("test", &[]);
+        vm.constructor("test", &[], 0);
 
         println!("width:{}", width);
 
@@ -661,7 +661,7 @@ fn int() {
 
         let mut vm = build_solidity(&src);
 
-        vm.constructor("test", &[]);
+        vm.constructor("test", &[], 0);
 
         for _ in 0..10 {
             let mut a_bs = Vec::new();

+ 1 - 1
tests/solana_tests/signature_verify.rs

@@ -42,7 +42,7 @@ fn verify() {
         }"#,
     );
 
-    vm.constructor("foo", &[]);
+    vm.constructor("foo", &[], 0);
 
     let mut csprng = rand::thread_rng();
     let keypair: Keypair = Keypair::generate(&mut csprng);

+ 7 - 6
tests/solana_tests/simple.rs

@@ -15,7 +15,7 @@ fn simple() {
         }"#,
     );
 
-    vm.constructor("foo", &[]);
+    vm.constructor("foo", &[], 0);
 
     assert_eq!(vm.logs, "Hello from constructor");
 
@@ -39,7 +39,7 @@ fn format() {
         }"#,
     );
 
-    vm.constructor("foo", &[]);
+    vm.constructor("foo", &[], 0);
 
     assert_eq!(
         vm.logs,
@@ -64,7 +64,7 @@ fn parameters() {
         }"#,
     );
 
-    vm.constructor("foo", &[]);
+    vm.constructor("foo", &[], 0);
 
     vm.function(
         "test",
@@ -104,7 +104,7 @@ fn returns() {
         }"#,
     );
 
-    vm.constructor("foo", &[]);
+    vm.constructor("foo", &[], 0);
 
     let returns = vm.function(
         "test",
@@ -127,7 +127,7 @@ fn returns() {
         }"#,
     );
 
-    vm.constructor("foo", &[]);
+    vm.constructor("foo", &[], 0);
 
     let returns = vm.function(
         "test",
@@ -171,7 +171,7 @@ fn flipper() {
         }"#,
     );
 
-    vm.constructor("flipper", &[ethabi::Token::Bool(true)]);
+    vm.constructor("flipper", &[ethabi::Token::Bool(true)], 0);
 
     assert_eq!(
         vm.data()[0..17].to_vec(),
@@ -228,6 +228,7 @@ fn incrementer() {
     vm.constructor(
         "incrementer",
         &[ethabi::Token::Uint(ethereum_types::U256::from(5))],
+        0,
     );
 
     let returns = vm.function("get", &[], &[], 0);

+ 11 - 11
tests/solana_tests/storage.rs

@@ -18,7 +18,7 @@ fn string() {
         }"#,
     );
 
-    vm.constructor("foo", &[]);
+    vm.constructor("foo", &[], 0);
 
     assert_eq!(
         vm.data()[0..20].to_vec(),
@@ -104,7 +104,7 @@ fn bytes() {
         }"#,
     );
 
-    vm.constructor("c", &[]);
+    vm.constructor("c", &[], 0);
 
     assert_eq!(
         vm.data()[0..20].to_vec(),
@@ -206,7 +206,7 @@ fn bytes_set_subscript_range() {
         }"#,
     );
 
-    vm.constructor("c", &[]);
+    vm.constructor("c", &[], 0);
 
     vm.function(
         "set_foo_offset",
@@ -245,7 +245,7 @@ fn bytes_get_subscript_range() {
         }"#,
     );
 
-    vm.constructor("c", &[]);
+    vm.constructor("c", &[], 0);
 
     vm.function(
         "set_foo",
@@ -277,7 +277,7 @@ fn storage_alignment() {
         }"#,
     );
 
-    vm.constructor("c", &[]);
+    vm.constructor("c", &[], 0);
 
     assert_eq!(
         vm.data()[0..40].to_vec(),
@@ -309,7 +309,7 @@ fn bytes_push_pop() {
         }"#,
     );
 
-    vm.constructor("c", &[]);
+    vm.constructor("c", &[], 0);
 
     let returns = vm.function("get_bs", &[], &[], 0);
 
@@ -352,7 +352,7 @@ fn bytes_empty_pop() {
         }"#,
     );
 
-    vm.constructor("c", &[]);
+    vm.constructor("c", &[], 0);
 
     vm.function("pop", &[], &[], 0);
 }
@@ -384,7 +384,7 @@ fn simple_struct() {
         }"#,
     );
 
-    vm.constructor("c", &[]);
+    vm.constructor("c", &[], 0);
 
     vm.function("set_s2", &[], &[], 0);
 
@@ -460,7 +460,7 @@ fn struct_in_struct() {
         }"#,
     );
 
-    vm.constructor("c", &[]);
+    vm.constructor("c", &[], 0);
 
     vm.function("set_s2", &[], &[], 0);
 
@@ -544,7 +544,7 @@ fn string_in_struct() {
             }"#,
     );
 
-    vm.constructor("c", &[]);
+    vm.constructor("c", &[], 0);
 
     vm.function("set_s2", &[], &[], 0);
 
@@ -643,7 +643,7 @@ fn complex_struct() {
         }"#,
     );
 
-    vm.constructor("c", &[]);
+    vm.constructor("c", &[], 0);
 
     vm.function("set_s2", &[], &[], 0);
 

+ 1 - 1
tests/solana_tests/unused_variable_elimination.rs

@@ -35,7 +35,7 @@ fn test_returns() {
     "#;
 
     let mut vm = build_solidity(file);
-    vm.constructor("c1", &[]);
+    vm.constructor("c1", &[], 0);
     let _ = vm.function("assign", &[], &[], 0);
     let returns = vm.function("pb1", &[], &[], 0);
 

+ 2 - 2
tests/solana_tests/using.rs

@@ -27,7 +27,7 @@ fn using_for_contracts() {
         }"#,
     );
 
-    runtime.constructor("C", &[]);
+    runtime.constructor("C", &[], 0);
     runtime.function("test", &[], &[], 0);
 
     assert_eq!(runtime.logs, "Hello");
@@ -70,7 +70,7 @@ fn using_for_contracts() {
         }"#,
     );
 
-    runtime.constructor("foo", &[]);
+    runtime.constructor("foo", &[], 0);
     runtime.function("test", &[], &[], 0);
 
     assert_eq!(runtime.logs, "X libX contractx:2");